Core/DataStores: Updated db2 structures to 9.0.2
Port From (https://github.com/TrinityCore/TrinityCore/commit/b82a3a557a7bf13d48342ea189325550059b622d)
This commit is contained in:
@@ -1832,6 +1832,38 @@ namespace Game.Entities
|
||||
pair.Value.state = PlayerCurrencyState.Unchanged;
|
||||
}
|
||||
}
|
||||
|
||||
public static void SavePlayerCustomizations(SQLTransaction trans, ulong guid, List<ChrCustomizationChoice> customizations)
|
||||
{
|
||||
PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.DEL_CHARACTER_CUSTOMIZATIONS);
|
||||
stmt.AddValue(0, guid);
|
||||
trans.Append(stmt);
|
||||
|
||||
foreach (var customization in customizations)
|
||||
{
|
||||
stmt = DB.Characters.GetPreparedStatement(CharStatements.INS_CHARACTER_CUSTOMIZATION);
|
||||
stmt.AddValue(0, guid);
|
||||
stmt.AddValue(1, customization.ChrCustomizationOptionID);
|
||||
stmt.AddValue(2, customization.ChrCustomizationChoiceID);
|
||||
trans.Append(stmt);
|
||||
}
|
||||
}
|
||||
|
||||
public static void SaveCustomizations(SQLTransaction trans, ulong guid, List<ChrCustomizationChoice> customizations)
|
||||
{
|
||||
SavePlayerCustomizations(trans, guid, customizations);
|
||||
}
|
||||
|
||||
void _SaveCustomizations(SQLTransaction trans)
|
||||
{
|
||||
if (!m_customizationsChanged)
|
||||
return;
|
||||
|
||||
m_customizationsChanged = false;
|
||||
|
||||
SavePlayerCustomizations(trans, GetGUID().GetCounter(), m_playerData.Customizations);
|
||||
}
|
||||
|
||||
void _SaveActions(SQLTransaction trans)
|
||||
{
|
||||
PreparedStatement stmt = null;
|
||||
@@ -2418,19 +2450,86 @@ namespace Game.Entities
|
||||
SQLResult result = holder.GetResult(PlayerLoginQueryLoad.From);
|
||||
if (result.IsEmpty())
|
||||
{
|
||||
string name;
|
||||
Global.CharacterCacheStorage.GetCharacterNameByGuid(guid, out name);
|
||||
Log.outError(LogFilter.Player, "Player {0} {1} not found in table `characters`, can't load. ", name, guid.ToString());
|
||||
Global.CharacterCacheStorage.GetCharacterNameByGuid(guid, out string cacheName);
|
||||
Log.outError(LogFilter.Player, "Player {0} {1} not found in table `characters`, can't load. ", cacheName, guid.ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
uint dbAccountId = result.Read<uint>(1);
|
||||
int fieldIndex = 1;
|
||||
uint accountId = result.Read<uint>(fieldIndex++);
|
||||
string name = result.Read<string>(fieldIndex++);
|
||||
Race race = (Race)result.Read<byte>(fieldIndex++);
|
||||
Class class_ = (Class)result.Read<byte>(fieldIndex++);
|
||||
Gender gender = (Gender)result.Read<byte>(fieldIndex++);
|
||||
byte level = result.Read<byte>(fieldIndex++);
|
||||
uint xp = result.Read<uint>(fieldIndex++);
|
||||
ulong money = result.Read<ulong>(fieldIndex++);
|
||||
byte inventorySlots = result.Read<byte>(fieldIndex++);
|
||||
byte bankSlots = result.Read<byte>(fieldIndex++);
|
||||
PlayerRestState restState = (PlayerRestState)result.Read<byte>(fieldIndex++);
|
||||
PlayerFlags playerFlags = (PlayerFlags)result.Read<uint>(fieldIndex++);
|
||||
PlayerFlagsEx playerFlagsEx = (PlayerFlagsEx)result.Read<uint>(fieldIndex++);
|
||||
float position_x = result.Read<float>(fieldIndex++);
|
||||
float position_y = result.Read<float>(fieldIndex++);
|
||||
float position_z = result.Read<float>(fieldIndex++);
|
||||
uint mapId = result.Read<ushort>(fieldIndex++);
|
||||
float orientation = result.Read<float>(fieldIndex++);
|
||||
string taximask = result.Read<string>(fieldIndex++);
|
||||
byte cinematic = result.Read<byte>(fieldIndex++);
|
||||
uint totaltime = result.Read<uint> (fieldIndex++);
|
||||
uint leveltime = result.Read<uint>(fieldIndex++);
|
||||
float rest_bonus = result.Read<float>(fieldIndex++);
|
||||
uint logout_time = result.Read<uint>(fieldIndex++);
|
||||
byte is_logout_resting = result.Read<byte>(fieldIndex++);
|
||||
uint resettalents_cost = result.Read<uint>(fieldIndex++);
|
||||
uint resettalents_time = result.Read<uint>(fieldIndex++);
|
||||
uint primarySpecialization = result.Read<uint>(fieldIndex++);
|
||||
float trans_x = result.Read<float>(fieldIndex++);
|
||||
float trans_y = result.Read<float>(fieldIndex++);
|
||||
float trans_z = result.Read<float>(fieldIndex++);
|
||||
float trans_o = result.Read<float>(fieldIndex++);
|
||||
ulong transguid = result.Read<ulong>(fieldIndex++);
|
||||
PlayerExtraFlags extra_flags = (PlayerExtraFlags)result.Read<ushort>(fieldIndex++);
|
||||
byte stable_slots = result.Read<byte>(fieldIndex++);
|
||||
ushort at_login = result.Read<ushort>(fieldIndex++);
|
||||
ushort zone = result.Read<ushort>(fieldIndex++);
|
||||
byte online = result.Read<byte>(fieldIndex++);
|
||||
uint death_expire_time = result.Read<uint>(fieldIndex++);
|
||||
string taxi_path = result.Read<string>(fieldIndex++);
|
||||
Difficulty dungeonDifficulty = (Difficulty)result.Read<byte>(fieldIndex++);
|
||||
uint totalKills = result.Read<uint>(fieldIndex++);
|
||||
ushort todayKills = result.Read<ushort>(fieldIndex++);
|
||||
ushort yesterdayKills = result.Read<ushort>(fieldIndex++);
|
||||
uint chosenTitle = result.Read<uint>(fieldIndex++);
|
||||
uint watchedFaction = result.Read<uint>(fieldIndex++);
|
||||
byte drunk = result.Read<byte>(fieldIndex++);
|
||||
uint health = result.Read<uint>(fieldIndex++);
|
||||
|
||||
uint[] powers = new uint[(int)PowerType.MaxPerClass];
|
||||
for (var i = 0; fieldIndex < powers.Length; ++i)
|
||||
powers[i] = result.Read<uint>(fieldIndex++);
|
||||
|
||||
uint instance_id = result.Read<uint>(fieldIndex++);
|
||||
byte activeTalentGroup = result.Read<byte>(fieldIndex++);
|
||||
uint lootSpecId = result.Read<uint>(fieldIndex++);
|
||||
string exploredZones = result.Read<string>(fieldIndex++);
|
||||
string knownTitles = result.Read<string>(fieldIndex++);
|
||||
byte actionBars = result.Read<byte>(fieldIndex++);
|
||||
Difficulty raidDifficulty = (Difficulty)result.Read<byte>(fieldIndex++);
|
||||
Difficulty legacyRaidDifficulty = (Difficulty)result.Read<byte>(fieldIndex++);
|
||||
byte fishingSteps = result.Read<byte>(fieldIndex++);
|
||||
uint honor = result.Read<uint>(fieldIndex++);
|
||||
uint honorLevel = result.Read<uint>(fieldIndex++);
|
||||
PlayerRestState honorRestState = (PlayerRestState)result.Read<byte>(fieldIndex++);
|
||||
float honorRestBonus = result.Read<float>(fieldIndex++);
|
||||
byte numRespecs = result.Read<byte>(fieldIndex++);
|
||||
|
||||
|
||||
// check if the character's account in the db and the logged in account match.
|
||||
// player should be able to load/delete character only with correct account!
|
||||
if (dbAccountId != GetSession().GetAccountId())
|
||||
if (accountId != GetSession().GetAccountId())
|
||||
{
|
||||
Log.outError(LogFilter.Player, "Player (GUID: {0}) loading from wrong account (is: {1}, should be: {2})", GetGUID().ToString(), GetSession().GetAccountId(), dbAccountId);
|
||||
Log.outError(LogFilter.Player, "Player (GUID: {0}) loading from wrong account (is: {1}, should be: {2})", GetGUID().ToString(), GetSession().GetAccountId(), accountId);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -2443,7 +2542,7 @@ namespace Game.Entities
|
||||
|
||||
_Create(guid);
|
||||
|
||||
SetName(result.Read<string>(2));
|
||||
SetName(name);
|
||||
|
||||
// check name limitations
|
||||
if (ObjectManager.CheckPlayerName(GetName(), GetSession().GetSessionDbcLocale()) != ResponseCodes.CharNameSuccess ||
|
||||
@@ -2456,18 +2555,18 @@ namespace Game.Entities
|
||||
return false;
|
||||
}
|
||||
|
||||
// overwrite possible wrong/corrupted guid
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.WowAccount), GetSession().GetAccountGUID());
|
||||
|
||||
Gender gender = (Gender)result.Read<byte>(5);
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.WowAccount), GetSession().GetAccountGUID());
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.BnetAccount), GetSession().GetBattlenetAccountGUID());
|
||||
|
||||
if (gender >= Gender.None)
|
||||
{
|
||||
Log.outError(LogFilter.Player, "Player {0} has wrong gender ({1}), can't be loaded.", guid.ToString(), gender);
|
||||
return false;
|
||||
}
|
||||
|
||||
SetRace((Race)result.Read<byte>(3));
|
||||
SetClass((Class)result.Read<byte>(4));
|
||||
SetRace(race);
|
||||
SetClass(class_);
|
||||
SetGender(gender);
|
||||
|
||||
// check if race/class combination is valid
|
||||
@@ -2478,19 +2577,19 @@ namespace Game.Entities
|
||||
return false;
|
||||
}
|
||||
|
||||
SetLevel(result.Read<uint>(6));
|
||||
SetXP(result.Read<uint>(7));
|
||||
SetLevel(level);
|
||||
SetXP(xp);
|
||||
|
||||
StringArray exploredZones = new StringArray(result.Read<string>(66), ' ');
|
||||
if (exploredZones.Length == PlayerConst.ExploredZonesSize * 2)
|
||||
for (int i = 0; i < exploredZones.Length; ++i)
|
||||
SetUpdateFieldFlagValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.ExploredZones, i / 2), (ulong)((long.Parse(exploredZones[i])) << (32 * (i % 2))));
|
||||
StringArray exploredZonesStrings = new StringArray(exploredZones, ' ');
|
||||
if (exploredZonesStrings.Length == PlayerConst.ExploredZonesSize * 2)
|
||||
for (int i = 0; i < exploredZonesStrings.Length; ++i)
|
||||
SetUpdateFieldFlagValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.ExploredZones, i / 2), (ulong)((long.Parse(exploredZonesStrings[i])) << (32 * (i % 2))));
|
||||
|
||||
StringArray knownTitles = new StringArray(result.Read<string>(67), ' ');
|
||||
if ((knownTitles.Length % 2) == 0)
|
||||
StringArray knownTitlesStrings = new StringArray(knownTitles, ' ');
|
||||
if ((knownTitlesStrings.Length % 2) == 0)
|
||||
{
|
||||
for (int i = 0; i < knownTitles.Length; ++i)
|
||||
SetUpdateFieldFlagValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.KnownTitles, i / 2), (ulong)((long.Parse(knownTitles[i])) << (32 * (i % 2))));
|
||||
for (int i = 0; i < knownTitlesStrings.Length; ++i)
|
||||
SetUpdateFieldFlagValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.KnownTitles, i / 2), (ulong)((long.Parse(knownTitlesStrings[i])) << (32 * (i % 2))));
|
||||
}
|
||||
|
||||
SetObjectScale(1.0f);
|
||||
@@ -2500,42 +2599,42 @@ namespace Game.Entities
|
||||
m_achievementSys.LoadFromDB(holder.GetResult(PlayerLoginQueryLoad.Achievements), holder.GetResult(PlayerLoginQueryLoad.CriteriaProgress));
|
||||
m_questObjectiveCriteriaMgr.LoadFromDB(holder.GetResult(PlayerLoginQueryLoad.QuestStatusObjectivesCriteria), holder.GetResult(PlayerLoginQueryLoad.QuestStatusObjectivesCriteriaProgress));
|
||||
|
||||
ulong money = result.Read<ulong>(8);
|
||||
if (money > PlayerConst.MaxMoneyAmount)
|
||||
money = PlayerConst.MaxMoneyAmount;
|
||||
SetMoney(money);
|
||||
SetMoney(Math.Min(money, PlayerConst.MaxMoneyAmount));
|
||||
|
||||
Array<byte> customDisplay = new Array<byte>(PlayerConst.CustomDisplaySize);
|
||||
customDisplay[0] = result.Read<byte>(14);
|
||||
customDisplay[1] = result.Read<byte>(15);
|
||||
customDisplay[2] = result.Read<byte>(16);
|
||||
List<ChrCustomizationChoice> customizations = new List<ChrCustomizationChoice>();
|
||||
SQLResult customizationsResult = holder.GetResult(PlayerLoginQueryLoad.Customizations);
|
||||
if (!customizationsResult.IsEmpty())
|
||||
{
|
||||
do
|
||||
{
|
||||
|
||||
SetSkinId(result.Read<byte>(9));
|
||||
SetFaceId(result.Read<byte>(10));
|
||||
SetHairStyleId(result.Read<byte>(11));
|
||||
SetHairColorId(result.Read<byte>(12));
|
||||
SetFacialHairStyleId(result.Read<byte>(13));
|
||||
for (byte i = 0; i < PlayerConst.CustomDisplaySize; ++i)
|
||||
SetCustomDisplayOption(i, customDisplay[i]);
|
||||
SetInventorySlotCount(result.Read<byte>(17));
|
||||
SetBankBagSlotCount(result.Read<byte>(18));
|
||||
ChrCustomizationChoice choice;
|
||||
choice.ChrCustomizationOptionID = customizationsResult.Read<uint>(0);
|
||||
choice.ChrCustomizationChoiceID = customizationsResult.Read<uint>(1);
|
||||
customizations.Add(choice);
|
||||
|
||||
} while (customizationsResult.NextRow());
|
||||
}
|
||||
|
||||
SetCustomizations(customizations, false);
|
||||
SetInventorySlotCount(inventorySlots);
|
||||
SetBankBagSlotCount(bankSlots);
|
||||
SetNativeSex(gender);
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.Inebriation), result.Read<byte>(55));
|
||||
SetPlayerFlags((PlayerFlags)result.Read<uint>(20));
|
||||
SetPlayerFlagsEx((PlayerFlagsEx)result.Read<uint>(21));
|
||||
SetWatchedFactionIndex(result.Read<uint>(54));
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.Inebriation), drunk);
|
||||
SetPlayerFlags(playerFlags);
|
||||
SetPlayerFlagsEx(playerFlagsEx);
|
||||
SetWatchedFactionIndex(watchedFaction);
|
||||
|
||||
if (!ValidateAppearance((Race)result.Read<byte>(3), (Class)result.Read<byte>(4), (Gender)gender,
|
||||
m_playerData.HairStyleID, m_playerData.HairColorID, m_playerData.FaceID, m_playerData.FacialHairStyleID, m_playerData.SkinID, customDisplay))
|
||||
if (!GetSession().ValidateAppearance(GetRace(), GetClass(), gender, customizations))
|
||||
{
|
||||
Log.outError(LogFilter.Player, "Player {0} has wrong Appearance values (Hair/Skin/Color), can't be loaded.", guid.ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
// set which actionbars the client has active - DO NOT REMOVE EVER AGAIN (can be changed though, if it does change fieldwise)
|
||||
SetMultiActionBars(result.Read<byte>(68));
|
||||
SetMultiActionBars(actionBars);
|
||||
|
||||
m_fishingSteps = result.Read<byte>(71);
|
||||
m_fishingSteps = fishingSteps;
|
||||
|
||||
InitDisplayIds();
|
||||
|
||||
@@ -2560,27 +2659,20 @@ namespace Game.Entities
|
||||
InitPrimaryProfessions(); // to max set before any spell loaded
|
||||
|
||||
// init saved position, and fix it later if problematic
|
||||
ulong transLowGUID = result.Read<ulong>(41);
|
||||
Relocate(position_x, position_y, position_z, orientation);
|
||||
|
||||
Relocate(result.Read<float>(22), result.Read<float>(23), result.Read<float>(24), result.Read<float>(26));
|
||||
SetDungeonDifficultyID(CheckLoadedDungeonDifficultyID(dungeonDifficulty));
|
||||
SetRaidDifficultyID(CheckLoadedRaidDifficultyID(raidDifficulty));
|
||||
SetLegacyRaidDifficultyID(CheckLoadedLegacyRaidDifficultyID(legacyRaidDifficulty));
|
||||
|
||||
uint mapId = result.Read<uint>(25);
|
||||
uint instanceId = result.Read<uint>(63);
|
||||
|
||||
var RelocateToHomebind = new Action(() => { mapId = homebind.GetMapId(); instanceId = 0; Relocate(homebind); });
|
||||
|
||||
SetDungeonDifficultyID(CheckLoadedDungeonDifficultyID((Difficulty)result.Read<byte>(49)));
|
||||
SetRaidDifficultyID(CheckLoadedRaidDifficultyID((Difficulty)result.Read<byte>(69)));
|
||||
SetLegacyRaidDifficultyID(CheckLoadedLegacyRaidDifficultyID((Difficulty)result.Read<byte>(70)));
|
||||
|
||||
string taxi_nodes = result.Read<string>(48);
|
||||
var RelocateToHomebind = new Action(() => { mapId = (ushort)homebind.GetMapId(); instance_id = 0; Relocate(homebind); });
|
||||
|
||||
_LoadGroup(holder.GetResult(PlayerLoginQueryLoad.Group));
|
||||
|
||||
_LoadCurrency(holder.GetResult(PlayerLoginQueryLoad.Currency));
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.LifetimeHonorableKills), result.Read<uint>(50));
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.TodayHonorableKills), result.Read<ushort>(51));
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.YesterdayHonorableKills), result.Read<ushort>(52));
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.LifetimeHonorableKills), totalKills);
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.TodayHonorableKills), todayKills);
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.YesterdayHonorableKills), yesterdayKills);
|
||||
|
||||
_LoadBoundInstances(holder.GetResult(PlayerLoginQueryLoad.BoundInstances));
|
||||
_LoadInstanceTimeRestrictions(holder.GetResult(PlayerLoginQueryLoad.InstanceLockTimes));
|
||||
@@ -2632,7 +2724,7 @@ namespace Game.Entities
|
||||
// Do not look for instance if bg not found
|
||||
WorldLocation _loc = GetBattlegroundEntryPoint();
|
||||
mapId = _loc.GetMapId();
|
||||
instanceId = 0;
|
||||
instance_id = 0;
|
||||
|
||||
if (mapId == 0xFFFFFFFF) // BattlegroundEntry Point not found (???)
|
||||
{
|
||||
@@ -2647,9 +2739,9 @@ namespace Game.Entities
|
||||
}
|
||||
}
|
||||
// currently we do not support transport in bg
|
||||
else if (transLowGUID != 0)
|
||||
else if (transguid != 0)
|
||||
{
|
||||
ObjectGuid transGUID = ObjectGuid.Create(HighGuid.Transport, transLowGUID);
|
||||
ObjectGuid transGUID = ObjectGuid.Create(HighGuid.Transport, transguid);
|
||||
|
||||
Transport transport = null;
|
||||
Transport go = Global.ObjAccessor.FindTransport(transGUID);
|
||||
@@ -2658,10 +2750,11 @@ namespace Game.Entities
|
||||
|
||||
if (transport)
|
||||
{
|
||||
float x = result.Read<float>(37);
|
||||
float y = result.Read<float>(38);
|
||||
float z = result.Read<float>(39);
|
||||
float o = result.Read<float>(40);
|
||||
float x = trans_x;
|
||||
float y = trans_y;
|
||||
float z = trans_z;
|
||||
float o = trans_o;
|
||||
|
||||
m_movementInfo.transport.pos = new Position(x, y, z, o);
|
||||
transport.CalculatePassengerPosition(ref x, ref y, ref z, ref o);
|
||||
|
||||
@@ -2671,8 +2764,7 @@ namespace Game.Entities
|
||||
Math.Abs(m_movementInfo.transport.pos.posY) > 250.0f ||
|
||||
Math.Abs(m_movementInfo.transport.pos.posZ) > 250.0f)
|
||||
{
|
||||
Log.outError(LogFilter.Player, "Player (guidlow {0}) have invalid transport coordinates (X: {1} Y: {2} Z: {3} O: {4}). Teleport to bind location.",
|
||||
guid.ToString(), x, y, z, o);
|
||||
Log.outError(LogFilter.Player, "Player (guidlow {0}) have invalid transport coordinates (X: {1} Y: {2} Z: {3} O: {4}). Teleport to bind location.", guid.ToString(), x, y, z, o);
|
||||
|
||||
m_movementInfo.transport.Reset();
|
||||
RelocateToHomebind();
|
||||
@@ -2687,16 +2779,15 @@ namespace Game.Entities
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.outError(LogFilter.Player, "Player (guidlow {0}) have problems with transport guid ({1}). Teleport to bind location.",
|
||||
guid.ToString(), transLowGUID);
|
||||
Log.outError(LogFilter.Player, "Player (guidlow {0}) have problems with transport guid ({1}). Teleport to bind location.", guid.ToString(), transguid);
|
||||
|
||||
RelocateToHomebind();
|
||||
}
|
||||
}
|
||||
// currently we do not support taxi in instance
|
||||
else if (!string.IsNullOrEmpty(taxi_nodes))
|
||||
else if (!taxi_path.IsEmpty())
|
||||
{
|
||||
instanceId = 0;
|
||||
instance_id = 0;
|
||||
|
||||
// Not finish taxi flight path
|
||||
if (m_bgData.HasTaxiPath())
|
||||
@@ -2704,7 +2795,7 @@ namespace Game.Entities
|
||||
for (int i = 0; i < 2; ++i)
|
||||
m_taxi.AddTaxiDestination(m_bgData.taxiPath[i]);
|
||||
}
|
||||
if (!m_taxi.LoadTaxiDestinationsFromString(taxi_nodes, GetTeam()))
|
||||
if (!m_taxi.LoadTaxiDestinationsFromString(taxi_path, GetTeam()))
|
||||
{
|
||||
// problems with taxi path loading
|
||||
TaxiNodesRecord nodeEntry = null;
|
||||
@@ -2753,19 +2844,20 @@ namespace Game.Entities
|
||||
}
|
||||
|
||||
// fix crash (because of if (Map* map = _FindMap(instanceId)) in MapInstanced.CreateInstance)
|
||||
if (instanceId != 0)
|
||||
if (instance_id != 0)
|
||||
{
|
||||
InstanceSave save = GetInstanceSave(mapId);
|
||||
if (save != null)
|
||||
if (save.GetInstanceId() != instanceId)
|
||||
instanceId = 0;
|
||||
if (save.GetInstanceId() != instance_id)
|
||||
instance_id = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// NOW player must have valid map
|
||||
// load the player's map here if it's not already loaded
|
||||
if (!map)
|
||||
map = Global.MapMgr.CreateMap(mapId, this, instanceId);
|
||||
map = Global.MapMgr.CreateMap(mapId, this, instance_id);
|
||||
|
||||
AreaTriggerStruct areaTrigger = null;
|
||||
bool check = false;
|
||||
|
||||
@@ -2802,7 +2894,7 @@ namespace Game.Entities
|
||||
areaTrigger = Global.ObjectMgr.GetGoBackTrigger(mapId);
|
||||
check = true;
|
||||
}
|
||||
else if (instanceId != 0 && Global.InstanceSaveMgr.GetInstanceSave(instanceId) == null) // ... and instance is reseted then look for entrance.
|
||||
else if (instance_id != 0 && Global.InstanceSaveMgr.GetInstanceSave(instance_id) == null) // ... and instance is reseted then look for entrance.
|
||||
{
|
||||
areaTrigger = Global.ObjectMgr.GetMapEntranceTrigger(mapId);
|
||||
check = true;
|
||||
@@ -2857,7 +2949,7 @@ namespace Game.Entities
|
||||
SaveRecallPosition();
|
||||
|
||||
long now = Time.UnixTime;
|
||||
long logoutTime = result.Read<int>(32);
|
||||
long logoutTime = logout_time;
|
||||
|
||||
// since last logout (in seconds)
|
||||
uint time_diff = (uint)(now - logoutTime);
|
||||
@@ -2870,32 +2962,30 @@ namespace Game.Entities
|
||||
|
||||
SetDrunkValue(newDrunkValue);
|
||||
|
||||
m_cinematic = result.Read<byte>(28);
|
||||
m_PlayedTimeTotal = result.Read<uint>(29);
|
||||
m_PlayedTimeLevel = result.Read<uint>(30);
|
||||
m_cinematic = cinematic;
|
||||
m_PlayedTimeTotal = totaltime;
|
||||
m_PlayedTimeLevel = leveltime;
|
||||
|
||||
SetTalentResetCost(result.Read<uint>(34));
|
||||
SetTalentResetTime(result.Read<uint>(35));
|
||||
SetTalentResetCost(resettalents_cost);
|
||||
SetTalentResetTime(resettalents_time);
|
||||
|
||||
m_taxi.LoadTaxiMask(result.Read<string>(27)); // must be before InitTaxiNodesForLevel
|
||||
m_taxi.LoadTaxiMask(taximask); // must be before InitTaxiNodesForLevel
|
||||
|
||||
PlayerExtraFlags extraflags = (PlayerExtraFlags)result.Read<uint>(42);
|
||||
|
||||
m_stableSlots = result.Read<byte>(43);
|
||||
m_stableSlots = stable_slots;
|
||||
if (m_stableSlots > 4)
|
||||
{
|
||||
Log.outError(LogFilter.Player, "Player can have not more {0} stable slots, but have in DB {1}", 4, m_stableSlots);
|
||||
m_stableSlots = 4;
|
||||
}
|
||||
|
||||
atLoginFlags = (AtLoginFlags)result.Read<uint>(44);
|
||||
atLoginFlags = (AtLoginFlags)at_login;
|
||||
|
||||
// Honor system
|
||||
// Update Honor kills data
|
||||
m_lastHonorUpdateTime = logoutTime;
|
||||
UpdateHonorFields();
|
||||
|
||||
m_deathExpireTime = result.Read<uint>(47);
|
||||
m_deathExpireTime = death_expire_time;
|
||||
if (m_deathExpireTime > now + PlayerConst.MaxDeathCount * PlayerConst.DeathExpireStep)
|
||||
m_deathExpireTime = now + PlayerConst.MaxDeathCount * PlayerConst.DeathExpireStep - 1;
|
||||
|
||||
@@ -2910,20 +3000,19 @@ namespace Game.Entities
|
||||
InitRunes();
|
||||
|
||||
// rest bonus can only be calculated after InitStatsForLevel()
|
||||
_restMgr.LoadRestBonus(RestTypes.XP, (PlayerRestState)result.Read<byte>(19), result.Read<float>(31));
|
||||
_restMgr.LoadRestBonus(RestTypes.XP, restState, rest_bonus);
|
||||
|
||||
// load skills after InitStatsForLevel because it triggering aura apply also
|
||||
_LoadSkills(holder.GetResult(PlayerLoginQueryLoad.Skills));
|
||||
UpdateSkillsForLevel();
|
||||
|
||||
SetNumRespecs(result.Read<byte>(76));
|
||||
SetPrimarySpecialization(result.Read<uint>(36));
|
||||
SetActiveTalentGroup(result.Read<byte>(64));
|
||||
SetNumRespecs(numRespecs);
|
||||
SetPrimarySpecialization(primarySpecialization);
|
||||
SetActiveTalentGroup(activeTalentGroup);
|
||||
ChrSpecializationRecord primarySpec = CliDB.ChrSpecializationStorage.LookupByKey(GetPrimarySpecialization());
|
||||
if (primarySpec == null || primarySpec.ClassID != (byte)GetClass() || GetActiveTalentGroup() >= PlayerConst.MaxSpecializations)
|
||||
ResetTalentSpecialization();
|
||||
|
||||
uint lootSpecId = result.Read<byte>(65);
|
||||
ChrSpecializationRecord chrSpec = CliDB.ChrSpecializationStorage.LookupByKey(lootSpecId);
|
||||
if (chrSpec != null)
|
||||
{
|
||||
@@ -2986,11 +3075,10 @@ namespace Game.Entities
|
||||
|
||||
// check PLAYER_CHOSEN_TITLE compatibility with PLAYER__FIELD_KNOWN_TITLES
|
||||
// note: PLAYER__FIELD_KNOWN_TITLES updated at quest status loaded
|
||||
uint curTitle = result.Read<uint>(53);
|
||||
if (curTitle != 0 && !HasTitle(curTitle))
|
||||
curTitle = 0;
|
||||
if (chosenTitle != 0 && !HasTitle(chosenTitle))
|
||||
chosenTitle = 0;
|
||||
|
||||
SetChosenTitle(curTitle);
|
||||
SetChosenTitle(chosenTitle);
|
||||
|
||||
// has to be called after last Relocate() in Player.LoadFromDB
|
||||
SetFallInformation(0, GetPositionZ());
|
||||
@@ -3009,14 +3097,13 @@ namespace Game.Entities
|
||||
UpdateAllStats();
|
||||
|
||||
// restore remembered power/health values (but not more max values)
|
||||
uint savedHealth = result.Read<uint>(56);
|
||||
SetHealth(savedHealth > GetMaxHealth() ? GetMaxHealth() : savedHealth);
|
||||
SetHealth(health > GetMaxHealth() ? GetMaxHealth() : health);
|
||||
int loadedPowers = 0;
|
||||
for (PowerType i = 0; i < PowerType.Max; ++i)
|
||||
{
|
||||
if (Global.DB2Mgr.GetPowerIndexByClass(i, GetClass()) != (int)PowerType.Max)
|
||||
{
|
||||
uint savedPower = result.Read<uint>(56 + loadedPowers);
|
||||
uint savedPower = powers[loadedPowers];
|
||||
uint maxPower = m_unitData.MaxPower[loadedPowers];
|
||||
SetPower(i, (int)(savedPower > maxPower ? maxPower : savedPower));
|
||||
if (++loadedPowers >= (int)PowerType.MaxPerClass)
|
||||
@@ -3025,7 +3112,7 @@ namespace Game.Entities
|
||||
}
|
||||
|
||||
for (; loadedPowers < (int)PowerType.MaxPerClass; ++loadedPowers)
|
||||
SetUpdateFieldValue(ref m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.Power, (int)loadedPowers), 0);
|
||||
SetUpdateFieldValue(ref m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.Power, loadedPowers), 0);
|
||||
|
||||
SetPower(PowerType.LunarPower, 0);
|
||||
// Init rune recharge
|
||||
@@ -3054,7 +3141,7 @@ namespace Game.Entities
|
||||
case 1: SetGameMaster(true);
|
||||
break; // enable
|
||||
case 2: // save state
|
||||
if (extraflags.HasAnyFlag(PlayerExtraFlags.GMOn))
|
||||
if (extra_flags.HasAnyFlag(PlayerExtraFlags.GMOn))
|
||||
SetGameMaster(true);
|
||||
break;
|
||||
}
|
||||
@@ -3067,7 +3154,7 @@ namespace Game.Entities
|
||||
case 1:
|
||||
break; // visible
|
||||
case 2: // save state
|
||||
if (extraflags.HasAnyFlag(PlayerExtraFlags.GMInvisible))
|
||||
if (extra_flags.HasAnyFlag(PlayerExtraFlags.GMInvisible))
|
||||
SetGMVisible(false);
|
||||
break;
|
||||
}
|
||||
@@ -3080,7 +3167,7 @@ namespace Game.Entities
|
||||
case 1: SetGMChat(true);
|
||||
break; // enable
|
||||
case 2: // save state
|
||||
if (extraflags.HasAnyFlag(PlayerExtraFlags.GMChat))
|
||||
if (extra_flags.HasAnyFlag(PlayerExtraFlags.GMChat))
|
||||
SetGMChat(true);
|
||||
break;
|
||||
}
|
||||
@@ -3093,7 +3180,7 @@ namespace Game.Entities
|
||||
case 1: SetAcceptWhispers(true);
|
||||
break; // enable
|
||||
case 2: // save state
|
||||
if (extraflags.HasAnyFlag(PlayerExtraFlags.AcceptWhispers))
|
||||
if (extra_flags.HasAnyFlag(PlayerExtraFlags.AcceptWhispers))
|
||||
SetAcceptWhispers(true);
|
||||
break;
|
||||
}
|
||||
@@ -3118,16 +3205,16 @@ namespace Game.Entities
|
||||
holder.GetResult(PlayerLoginQueryLoad.GarrisonFollowerAbilities)))
|
||||
_garrison = garrison;
|
||||
|
||||
_InitHonorLevelOnLoadFromDB(result.Read<uint>(72), result.Read<uint>(73));
|
||||
_InitHonorLevelOnLoadFromDB(honor, honorLevel);
|
||||
|
||||
_restMgr.LoadRestBonus(RestTypes.Honor, (PlayerRestState)result.Read<byte>(74), result.Read<float>(75));
|
||||
_restMgr.LoadRestBonus(RestTypes.Honor, honorRestState, honorRestBonus);
|
||||
if (time_diff > 0)
|
||||
{
|
||||
//speed collect rest bonus in offline, in logout, far from tavern, city (section/in hour)
|
||||
float bubble0 = 0.031f;
|
||||
//speed collect rest bonus in offline, in logout, in tavern, city (section/in hour)
|
||||
float bubble1 = 0.125f;
|
||||
float bubble = result.Read<byte>(33) > 0
|
||||
float bubble = is_logout_resting > 0
|
||||
? bubble1 * WorldConfig.GetFloatValue(WorldCfg.RateRestOfflineInTavernOrCity)
|
||||
: bubble0 * WorldConfig.GetFloatValue(WorldCfg.RateRestOfflineInWilderness);
|
||||
|
||||
@@ -3191,15 +3278,8 @@ namespace Game.Entities
|
||||
stmt.AddValue(index++, (byte)GetClass());
|
||||
stmt.AddValue(index++, (byte)m_playerData.NativeSex); // save gender from PLAYER_BYTES_3, UNIT_BYTES_0 changes with every transform effect
|
||||
stmt.AddValue(index++, GetLevel());
|
||||
stmt.AddValue(index++, (uint)m_activePlayerData.XP);
|
||||
stmt.AddValue(index++, (uint)GetNativeSex());
|
||||
stmt.AddValue(index++, GetMoney());
|
||||
stmt.AddValue(index++, (byte)m_playerData.SkinID);
|
||||
stmt.AddValue(index++, (byte)m_playerData.FaceID);
|
||||
stmt.AddValue(index++, (byte)m_playerData.HairStyleID);
|
||||
stmt.AddValue(index++, (byte)m_playerData.HairColorID);
|
||||
stmt.AddValue(index++, (byte)m_playerData.FacialHairStyleID);
|
||||
for (int i = 0; i < PlayerConst.CustomDisplaySize; ++i)
|
||||
stmt.AddValue(index++, m_playerData.CustomDisplayOption[i]);
|
||||
stmt.AddValue(index++, GetInventorySlotCount());
|
||||
stmt.AddValue(index++, GetBankBagSlotCount());
|
||||
stmt.AddValue(index++, (byte)m_activePlayerData.RestInfo[(int)RestTypes.XP].StateID);
|
||||
@@ -3321,17 +3401,8 @@ namespace Game.Entities
|
||||
stmt.AddValue(index++, (byte)GetClass());
|
||||
stmt.AddValue(index++, (byte)m_playerData.NativeSex); // save gender from PLAYER_BYTES_3, UNIT_BYTES_0 changes with every transform effect
|
||||
stmt.AddValue(index++, GetLevel());
|
||||
stmt.AddValue(index++, (uint)m_activePlayerData.XP);
|
||||
stmt.AddValue(index++, (uint)GetNativeSex());
|
||||
stmt.AddValue(index++, GetMoney());
|
||||
stmt.AddValue(index++, (byte)m_playerData.SkinID);
|
||||
stmt.AddValue(index++, (byte)m_playerData.FaceID);
|
||||
stmt.AddValue(index++, (byte)m_playerData.HairStyleID);
|
||||
stmt.AddValue(index++, (byte)m_playerData.HairColorID);
|
||||
stmt.AddValue(index++, (byte)m_playerData.FacialHairStyleID);
|
||||
|
||||
for (int i = 0; i < PlayerConst.CustomDisplaySize; ++i)
|
||||
stmt.AddValue(index++, m_playerData.CustomDisplayOption[i]);
|
||||
|
||||
stmt.AddValue(index++, GetInventorySlotCount());
|
||||
stmt.AddValue(index++, GetBankBagSlotCount());
|
||||
stmt.AddValue(index++, (byte)m_activePlayerData.RestInfo[(int)RestTypes.XP].StateID);
|
||||
@@ -3485,6 +3556,7 @@ namespace Game.Entities
|
||||
if (m_mailsUpdated) //save mails only when needed
|
||||
_SaveMail(characterTransaction);
|
||||
|
||||
_SaveCustomizations(characterTransaction);
|
||||
_SaveBGData(characterTransaction);
|
||||
_SaveInventory(characterTransaction);
|
||||
_SaveVoidStorage(characterTransaction);
|
||||
@@ -3807,6 +3879,10 @@ namespace Game.Entities
|
||||
stmt.AddValue(0, guid);
|
||||
trans.Append(stmt);
|
||||
|
||||
stmt = DB.Characters.GetPreparedStatement(CharStatements.DEL_CHARACTER_CUSTOMIZATIONS);
|
||||
stmt.AddValue(0, guid);
|
||||
trans.Append(stmt);
|
||||
|
||||
stmt = DB.Characters.GetPreparedStatement(CharStatements.DEL_PLAYER_ACCOUNT_DATA);
|
||||
stmt.AddValue(0, guid);
|
||||
trans.Append(stmt);
|
||||
|
||||
@@ -196,6 +196,7 @@ namespace Game.Entities
|
||||
byte m_cinematic;
|
||||
|
||||
uint m_movie;
|
||||
bool m_customizationsChanged;
|
||||
|
||||
SpecializationInfo _specializationInfo;
|
||||
public List<ObjectGuid> m_clientGUIDs = new List<ObjectGuid>();
|
||||
|
||||
@@ -32,6 +32,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Game.BattleFields;
|
||||
using Framework.Dynamic;
|
||||
|
||||
namespace Game.Entities
|
||||
{
|
||||
@@ -3848,6 +3849,8 @@ namespace Game.Entities
|
||||
if (guild != null)
|
||||
guild.AddGuildNews(GuildNews.ItemPurchased, GetGUID(), 0, item);
|
||||
}
|
||||
|
||||
UpdateCriteria(CriteriaTypes.BoughtItemFromVendor, 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -5186,9 +5189,12 @@ namespace Game.Entities
|
||||
return InventoryResult.ClientLockedOut;
|
||||
}
|
||||
|
||||
ScalingStatDistributionRecord ssd = CliDB.ScalingStatDistributionStorage.LookupByKey(pItem.GetScalingStatDistribution());
|
||||
ContentTuningLevels? requiredLevels = null;
|
||||
// check allowed level (extend range to upper values if MaxLevel more or equal max player level, this let GM set high level with 1...max range items)
|
||||
if (ssd != null && ssd.MaxLevel < WorldConfig.GetIntValue(WorldCfg.MaxPlayerLevel) && ssd.MaxLevel < GetLevel() && Global.DB2Mgr.GetHeirloomByItemId(pProto.GetId()) == null)
|
||||
if (pItem.GetQuality() == ItemQuality.Heirloom)
|
||||
requiredLevels = Global.DB2Mgr.GetContentTuningData(pItem.GetScalingContentTuningId(), 0, true);
|
||||
|
||||
if (requiredLevels.HasValue && requiredLevels.Value.MaxLevel < SharedConst.DefaultMaxLevel && requiredLevels.Value.MaxLevel < GetLevel() && Global.DB2Mgr.GetHeirloomByItemId(pProto.GetId()) == null)
|
||||
return InventoryResult.NotEquippable;
|
||||
|
||||
byte eslot = FindEquipSlot(pProto, slot, swap);
|
||||
|
||||
@@ -144,6 +144,8 @@ namespace Game.Entities
|
||||
_restMgr.SetRestFlag(RestFlag.FactionArea);
|
||||
else
|
||||
_restMgr.RemoveRestFlag(RestFlag.FactionArea);
|
||||
|
||||
UpdateCriteria(CriteriaTypes.TravelledToArea, newArea);
|
||||
}
|
||||
|
||||
public void UpdateZone(uint newZone, uint newArea)
|
||||
|
||||
@@ -49,14 +49,18 @@ namespace Game.Entities
|
||||
|
||||
public int GetQuestMinLevel(Quest quest)
|
||||
{
|
||||
if (quest.Level == -1 && quest.ScalingFactionGroup != 0)
|
||||
var questLevels = Global.DB2Mgr.GetContentTuningData(quest.ContentTuningId, m_playerData.CtrOptions.GetValue().ContentTuningConditionMask);
|
||||
if (questLevels.HasValue)
|
||||
{
|
||||
ChrRacesRecord race = CliDB.ChrRacesStorage.LookupByKey(GetRace());
|
||||
FactionTemplateRecord raceFaction = CliDB.FactionTemplateStorage.LookupByKey(race.FactionID);
|
||||
if (raceFaction == null || raceFaction.FactionGroup != quest.ScalingFactionGroup)
|
||||
return quest.MaxScalingLevel;
|
||||
if (raceFaction == null || raceFaction.FactionGroup != CliDB.ContentTuningStorage.LookupByKey(quest.ContentTuningId).GetScalingFactionGroup())
|
||||
return questLevels.Value.MaxLevel;
|
||||
|
||||
return questLevels.Value.MinLevelWithDelta;
|
||||
}
|
||||
return quest.MinLevel;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int GetQuestLevel(Quest quest)
|
||||
@@ -64,16 +68,18 @@ namespace Game.Entities
|
||||
if (quest == null)
|
||||
return 0;
|
||||
|
||||
if (quest.Level == -1)
|
||||
var questLevels = Global.DB2Mgr.GetContentTuningData(quest.ContentTuningId, m_playerData.CtrOptions.GetValue().ContentTuningConditionMask);
|
||||
if (questLevels.HasValue)
|
||||
{
|
||||
int minLevel = GetQuestMinLevel(quest);
|
||||
int maxLevel = quest.MaxScalingLevel;
|
||||
int maxLevel = questLevels.Value.MaxLevel;
|
||||
int level = (int)GetLevel();
|
||||
if (level >= minLevel)
|
||||
return Math.Min(level, maxLevel);
|
||||
return minLevel;
|
||||
}
|
||||
return quest.Level;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int GetRewardedQuestCount() { return m_RewardedQuests.Count; }
|
||||
@@ -1153,6 +1159,7 @@ namespace Game.Entities
|
||||
|
||||
UpdateCriteria(CriteriaTypes.CompleteQuestCount);
|
||||
UpdateCriteria(CriteriaTypes.CompleteQuest, quest.Id);
|
||||
UpdateCriteria(CriteriaTypes.CompleteQuestAccumulate, 1);
|
||||
|
||||
// make full db save
|
||||
SaveToDB(false);
|
||||
|
||||
@@ -59,6 +59,7 @@ namespace Game.Entities
|
||||
|
||||
m_zoneUpdateId = 0xffffffff;
|
||||
m_nextSave = WorldConfig.GetUIntValue(WorldCfg.IntervalSave);
|
||||
m_customizationsChanged = false;
|
||||
|
||||
SetGroupInvite(null);
|
||||
|
||||
@@ -184,7 +185,7 @@ namespace Game.Entities
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ValidateAppearance(createInfo.RaceId, createInfo.ClassId, createInfo.Sex, createInfo.HairStyle, createInfo.HairColor, createInfo.Face, createInfo.FacialHairStyle, createInfo.Skin, createInfo.CustomDisplay, true))
|
||||
if (!GetSession().ValidateAppearance(createInfo.RaceId, createInfo.ClassId, createInfo.Sex, createInfo.Customizations))
|
||||
{
|
||||
Log.outError(LogFilter.Player, "Player.Create: Possible hacking-attempt: Account {0} tried creating a character named '{1}' with invalid appearance attributes - refusing to do so",
|
||||
GetSession().GetAccountId(), GetName());
|
||||
@@ -223,14 +224,7 @@ namespace Game.Entities
|
||||
|
||||
SetWatchedFactionIndex(0xFFFFFFFF);
|
||||
|
||||
SetSkinId(createInfo.Skin);
|
||||
SetFaceId(createInfo.Face);
|
||||
SetHairStyleId(createInfo.HairStyle);
|
||||
SetHairColorId(createInfo.HairColor);
|
||||
SetFacialHairStyleId(createInfo.FacialHairStyle);
|
||||
for (byte i = 0; i < PlayerConst.CustomDisplaySize; ++i)
|
||||
SetCustomDisplayOption(i, createInfo.CustomDisplay[i]);
|
||||
|
||||
SetCustomizations(createInfo.Customizations);
|
||||
SetRestState(RestTypes.XP, ((GetSession().IsARecruiter() || GetSession().GetRecruiterId() != 0) ? PlayerRestState.RAFLinked : PlayerRestState.NotRAFLinked));
|
||||
SetRestState(RestTypes.Honor, PlayerRestState.NotRAFLinked);
|
||||
SetNativeSex(createInfo.Sex);
|
||||
@@ -308,46 +302,8 @@ namespace Game.Entities
|
||||
}
|
||||
|
||||
// original items
|
||||
CharStartOutfitRecord oEntry = Global.DB2Mgr.GetCharStartOutfitEntry((byte)createInfo.RaceId, (byte)createInfo.ClassId, (byte)createInfo.Sex);
|
||||
if (oEntry != null)
|
||||
{
|
||||
for (int j = 0; j < ItemConst.MaxOutfitItems - 1; ++j)
|
||||
{
|
||||
if (oEntry.ItemID[j] <= 0)
|
||||
continue;
|
||||
|
||||
uint itemId = (uint)oEntry.ItemID[j];
|
||||
|
||||
ItemTemplate iProto = Global.ObjectMgr.GetItemTemplate(itemId);
|
||||
if (iProto == null)
|
||||
continue;
|
||||
|
||||
// BuyCount by default
|
||||
uint count = iProto.GetBuyCount();
|
||||
|
||||
// special amount for food/drink
|
||||
if (iProto.GetClass() == ItemClass.Consumable && iProto.GetSubClass() == (uint)ItemSubClassConsumable.FoodDrink)
|
||||
{
|
||||
if (!iProto.Effects.Empty())
|
||||
{
|
||||
switch (iProto.Effects[0].SpellCategoryID)
|
||||
{
|
||||
case 11: // food
|
||||
count = (uint)(GetClass() == Class.Deathknight ? 10 : 4);
|
||||
break;
|
||||
case 59: // drink
|
||||
count = 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (iProto.GetMaxStackSize() < count)
|
||||
count = iProto.GetMaxStackSize();
|
||||
}
|
||||
StoreNewItemInBestSlots(itemId, count);
|
||||
}
|
||||
}
|
||||
foreach (var item in info.item)
|
||||
StoreNewItemInBestSlots(item.item_id, item.item_amount);
|
||||
foreach (PlayerCreateInfoItem initialItem in info.item)
|
||||
StoreNewItemInBestSlots(initialItem.item_id, initialItem.item_amount);
|
||||
|
||||
// bags and main-hand weapon must equipped at this moment
|
||||
// now second pass for not equipped (offhand weapon/shield if it attempt equipped before main-hand weapon)
|
||||
@@ -1193,7 +1149,7 @@ namespace Game.Entities
|
||||
FactionRecord factionEntry = CliDB.FactionStorage.LookupByKey(currency.FactionID);
|
||||
if (factionEntry != null)
|
||||
{
|
||||
if (currency.Flags.HasAnyFlag((uint)CurrencyFlags.HighPrecision))
|
||||
if (currency.Flags[0].HasAnyFlag((int)CurrencyFlags.HighPrecision))
|
||||
count /= 100;
|
||||
GetReputationMgr().ModifyReputation(factionEntry, count, false, true);
|
||||
return;
|
||||
@@ -1582,8 +1538,12 @@ namespace Game.Entities
|
||||
{
|
||||
LFGDungeonsRecord dungeon = Global.DB2Mgr.GetLfgDungeon(map.GetId(), map.GetDifficultyID());
|
||||
if (dungeon != null)
|
||||
if (dungeon.TargetLevel == 80)
|
||||
ChampioningFaction = GetChampioningFaction();
|
||||
{
|
||||
var dungeonLevels = Global.DB2Mgr.GetContentTuningData(dungeon.ContentTuningID, m_playerData.CtrOptions.GetValue().ContentTuningConditionMask);
|
||||
if (dungeonLevels.HasValue)
|
||||
if (dungeonLevels.Value.TargetLevelMax == Global.ObjectMgr.GetMaxLevelForExpansion(Expansion.WrathOfTheLichKing))
|
||||
ChampioningFaction = GetChampioningFaction();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2613,6 +2573,9 @@ namespace Game.Entities
|
||||
if (channel.Flags.HasAnyFlag(ChannelDBCFlags.GuildReq) && GetGuildId() != 0)
|
||||
return false;
|
||||
|
||||
if (channel.Flags.HasAnyFlag(ChannelDBCFlags.NoClientJoin))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
public void JoinedChannel(Channel c)
|
||||
@@ -2658,6 +2621,9 @@ namespace Game.Entities
|
||||
|
||||
foreach (var channelEntry in CliDB.ChatChannelsStorage.Values)
|
||||
{
|
||||
if (!channelEntry.Flags.HasAnyFlag(ChannelDBCFlags.Initial))
|
||||
continue;
|
||||
|
||||
Channel usedChannel = null;
|
||||
foreach (var channel in m_channels)
|
||||
{
|
||||
@@ -3467,51 +3433,27 @@ namespace Game.Entities
|
||||
SendBattlefieldWorldStates();
|
||||
}
|
||||
|
||||
public uint GetBarberShopCost(BarberShopStyleRecord newHairStyle, uint newHairColor, BarberShopStyleRecord newFacialHair, BarberShopStyleRecord newSkin, BarberShopStyleRecord newFace, Array<BarberShopStyleRecord> newCustomDisplay)
|
||||
public long GetBarberShopCost(List<ChrCustomizationChoice> newCustomizations)
|
||||
{
|
||||
byte hairstyle = m_playerData.HairStyleID;
|
||||
byte haircolor = m_playerData.HairColorID;
|
||||
byte facialhair = m_playerData.FacialHairStyleID;
|
||||
byte skincolor = m_playerData.SkinID;
|
||||
byte face = m_playerData.FaceID;
|
||||
|
||||
Array<byte> customDisplay = new Array<byte>(PlayerConst.CustomDisplaySize);
|
||||
for (int i = 0; i < PlayerConst.CustomDisplaySize; ++i)
|
||||
customDisplay[i] = m_playerData.CustomDisplayOption[i];
|
||||
|
||||
if ((hairstyle == newHairStyle.Data) &&
|
||||
(haircolor == newHairColor) &&
|
||||
(facialhair == newFacialHair.Data) &&
|
||||
(newSkin == null || (newSkin.Data == skincolor)) &&
|
||||
(newFace == null || (newFace.Data == face)) &&
|
||||
(newCustomDisplay[0] == null || (newCustomDisplay[0].Data == customDisplay[0])) &&
|
||||
(newCustomDisplay[1] == null || (newCustomDisplay[1].Data == customDisplay[1])) &&
|
||||
(newCustomDisplay[2] == null || (newCustomDisplay[2].Data == customDisplay[2])))
|
||||
return 0;
|
||||
|
||||
GtBarberShopCostBaseRecord bsc = CliDB.BarberShopCostBaseGameTable.GetRow(GetLevel());
|
||||
if (bsc == null) // shouldn't happen
|
||||
return 0xFFFFFFFF;
|
||||
return 0;
|
||||
|
||||
uint cost = 0;
|
||||
if (hairstyle != newHairStyle.Data)
|
||||
cost += (uint)(bsc.Cost * newHairStyle.CostModifier);
|
||||
long cost = 0;
|
||||
foreach (ChrCustomizationChoice newChoice in newCustomizations)
|
||||
{
|
||||
int currentCustomizationIndex = m_playerData.Customizations.FindIndexIf(currentCustomization =>
|
||||
{
|
||||
return currentCustomization.ChrCustomizationOptionID == newChoice.ChrCustomizationOptionID;
|
||||
});
|
||||
|
||||
if ((haircolor != newHairColor) && (hairstyle == newHairStyle.Data))
|
||||
cost += (uint)(bsc.Cost * 0.5f); // +1/2 of price
|
||||
|
||||
if (facialhair != newFacialHair.Data)
|
||||
cost += (uint)(bsc.Cost * newFacialHair.CostModifier);
|
||||
|
||||
if (newSkin != null && skincolor != newSkin.Data)
|
||||
cost += (uint)(bsc.Cost * newSkin.CostModifier);
|
||||
|
||||
if (newFace != null && face != newFace.Data)
|
||||
cost += (uint)(bsc.Cost * newFace.CostModifier);
|
||||
|
||||
for (int i = 0; i < PlayerConst.CustomDisplaySize; ++i)
|
||||
if (newCustomDisplay[i] != null && customDisplay[i] != newCustomDisplay[i].Data)
|
||||
cost += (uint)(bsc.Cost * newCustomDisplay[i].CostModifier);
|
||||
if (currentCustomizationIndex == -1 || m_playerData.Customizations[currentCustomizationIndex].ChrCustomizationChoiceID != newChoice.ChrCustomizationChoiceID)
|
||||
{
|
||||
ChrCustomizationOptionRecord customizationOption = CliDB.ChrCustomizationOptionStorage.LookupByKey(newChoice.ChrCustomizationOptionID);
|
||||
if (customizationOption != null)
|
||||
cost += (long)(bsc.Cost * customizationOption.BarberShopCostModifier);
|
||||
}
|
||||
}
|
||||
|
||||
return cost;
|
||||
}
|
||||
@@ -3950,139 +3892,10 @@ namespace Game.Entities
|
||||
return null;
|
||||
}
|
||||
|
||||
static uint GetSelectionFromContext(uint context, Class playerClass)
|
||||
{
|
||||
switch (context)
|
||||
{
|
||||
case 1:
|
||||
if (playerClass == Class.Deathknight)
|
||||
return 1;
|
||||
if (playerClass == Class.DemonHunter)
|
||||
return 3;
|
||||
return 0;
|
||||
case 2:
|
||||
if (playerClass == Class.Deathknight)
|
||||
return 5;
|
||||
if (playerClass == Class.DemonHunter)
|
||||
return 6;
|
||||
return 4;
|
||||
case 3:
|
||||
return 7;
|
||||
case 4:
|
||||
if (playerClass == Class.Deathknight)
|
||||
return 9;
|
||||
if (playerClass == Class.DemonHunter)
|
||||
return 10;
|
||||
return 8;
|
||||
default:
|
||||
if (playerClass == Class.Deathknight)
|
||||
return 1;
|
||||
if (playerClass == Class.DemonHunter)
|
||||
return 2;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static bool ComponentFlagsMatch(CharSectionsRecord entry, uint selection)
|
||||
{
|
||||
switch (selection)
|
||||
{
|
||||
case 0:
|
||||
if (!entry.Flags.HasAnyFlag((short)1))
|
||||
return false;
|
||||
return !entry.Flags.HasAnyFlag((short)0x2C);
|
||||
case 1:
|
||||
if (!entry.Flags.HasAnyFlag((short)1))
|
||||
return false;
|
||||
if (!entry.Flags.HasAnyFlag((short)0x94))
|
||||
return false;
|
||||
return !entry.Flags.HasAnyFlag((short)8);
|
||||
case 2:
|
||||
if (!entry.Flags.HasAnyFlag((short)1))
|
||||
return false;
|
||||
if (!entry.Flags.HasAnyFlag((short)0x70))
|
||||
return false;
|
||||
return !entry.Flags.HasAnyFlag((short)8);
|
||||
case 3:
|
||||
if (!entry.Flags.HasAnyFlag((short)1))
|
||||
return false;
|
||||
if (!entry.Flags.HasAnyFlag((short)0x20))
|
||||
return false;
|
||||
return !entry.Flags.HasAnyFlag((short)8);
|
||||
case 4:
|
||||
case 8:
|
||||
if (!entry.Flags.HasAnyFlag((short)3))
|
||||
return false;
|
||||
return !entry.Flags.HasAnyFlag((short)0x2C);
|
||||
case 5:
|
||||
case 9:
|
||||
if (!entry.Flags.HasAnyFlag((short)3))
|
||||
return false;
|
||||
if (!entry.Flags.HasAnyFlag((short)0x94))
|
||||
return false;
|
||||
return !entry.Flags.HasAnyFlag((short)8);
|
||||
case 6:
|
||||
case 10:
|
||||
if (!entry.Flags.HasAnyFlag((short)3))
|
||||
return false;
|
||||
if (!entry.Flags.HasAnyFlag((short)0x70))
|
||||
return false;
|
||||
return !entry.Flags.HasAnyFlag((short)8);
|
||||
case 7:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool IsSectionFlagValid(CharSectionsRecord entry, Class class_, bool create)
|
||||
{
|
||||
if (create)
|
||||
return ComponentFlagsMatch(entry, GetSelectionFromContext(0, class_));
|
||||
|
||||
return ComponentFlagsMatch(entry, GetSelectionFromContext(2, class_));
|
||||
}
|
||||
static bool IsSectionValid(Race race, Class class_, Gender gender, CharBaseSectionVariation variation, byte variationIndex, byte colorIndex, bool create)
|
||||
{
|
||||
CharSectionsRecord section = Global.DB2Mgr.GetCharSectionEntry(race, gender, variation, variationIndex, colorIndex);
|
||||
if (section != null)
|
||||
return IsSectionFlagValid(section, class_, create);
|
||||
|
||||
return false;
|
||||
}
|
||||
public static bool IsValidGender(Gender _gender) { return _gender <= Gender.Female; }
|
||||
public static bool IsValidClass(Class _class) { return Convert.ToBoolean((1 << ((int)_class - 1)) & (int)Class.ClassMaskAllPlayable); }
|
||||
public static bool IsValidRace(Race _race) { return Convert.ToBoolean((1 << ((int)_race - 1)) & (int)Race.RaceMaskAllPlayable); }
|
||||
|
||||
public static bool ValidateAppearance(Race race, Class class_, Gender gender, byte hairID, byte hairColor, byte faceID, byte facialHairId, byte skinColor, Array<byte> customDisplay, bool create = false)
|
||||
{
|
||||
if (!IsSectionValid(race, class_, gender, CharBaseSectionVariation.Skin, 0, skinColor, create))
|
||||
return false;
|
||||
|
||||
if (!IsSectionValid(race, class_, gender, CharBaseSectionVariation.Face, faceID, skinColor, create))
|
||||
return false;
|
||||
|
||||
if (!IsSectionValid(race, class_, gender, CharBaseSectionVariation.Hair, hairID, hairColor, create))
|
||||
return false;
|
||||
|
||||
if (!IsSectionValid(race, class_, gender, CharBaseSectionVariation.FacialHair, facialHairId, hairColor, create))
|
||||
if (Global.DB2Mgr.HasCharSections(race, gender, CharBaseSectionVariation.FacialHair) || !Global.DB2Mgr.HasCharacterFacialHairStyle(race, gender, facialHairId))
|
||||
return false;
|
||||
|
||||
if (!IsSectionValid(race, class_, gender, CharBaseSectionVariation.CustomDisplay1, customDisplay[0], 0, create))
|
||||
return false;
|
||||
|
||||
if (!IsSectionValid(race, class_, gender, CharBaseSectionVariation.CustomDisplay2, customDisplay[1], 0, create))
|
||||
return false;
|
||||
|
||||
if (!IsSectionValid(race, class_, gender, CharBaseSectionVariation.CustomDisplay3, customDisplay[2], 0, create))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void OnCombatExit()
|
||||
{
|
||||
UpdatePotionCooldown();
|
||||
@@ -4594,12 +4407,8 @@ namespace Game.Entities
|
||||
flags |= CorpseFlags.FFAPvP;
|
||||
|
||||
corpse.SetRace(GetRace());
|
||||
corpse.SetSex((Gender)(byte)m_playerData.NativeSex);
|
||||
corpse.SetSkin(m_playerData.SkinID);
|
||||
corpse.SetFace(m_playerData.FaceID);
|
||||
corpse.SetHairStyle(m_playerData.HairStyleID);
|
||||
corpse.SetHairColor(m_playerData.HairColorID);
|
||||
corpse.SetFacialHairStyle(m_playerData.FacialHairStyleID);
|
||||
corpse.SetSex(GetNativeSex());
|
||||
corpse.SetCustomizations(m_playerData.Customizations);
|
||||
corpse.SetFlags(flags);
|
||||
corpse.SetDisplayId(GetNativeDisplayId());
|
||||
corpse.SetFactionTemplate(CliDB.ChrRacesStorage.LookupByKey(GetRace()).FactionID);
|
||||
@@ -5475,8 +5284,7 @@ namespace Game.Entities
|
||||
return;
|
||||
}
|
||||
|
||||
byte gender = m_playerData.NativeSex;
|
||||
switch ((Gender)gender)
|
||||
switch (GetNativeSex())
|
||||
{
|
||||
case Gender.Female:
|
||||
SetDisplayId(info.DisplayId_f);
|
||||
@@ -5487,7 +5295,7 @@ namespace Game.Entities
|
||||
SetNativeDisplayId(info.DisplayId_m);
|
||||
break;
|
||||
default:
|
||||
Log.outError(LogFilter.Player, "Player {0} ({1}) has invalid gender {2}", GetName(), GetGUID().ToString(), (Gender)gender);
|
||||
Log.outError(LogFilter.Player, "Player {0} ({1}) has invalid gender {2}", GetName(), GetGUID().ToString(), GetNativeSex());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -5883,13 +5691,13 @@ namespace Game.Entities
|
||||
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.ModHealingDonePos), 0);
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.ModHealingPercent), 1.0f);
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.ModHealingDonePercent), 1.0f);
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.ModPeriodicHealingDonePercent), 1.0f);
|
||||
for (byte i = 0; i < 7; ++i)
|
||||
for (byte i = 0; i < (int)SpellSchools.Max; ++i)
|
||||
{
|
||||
SetUpdateFieldValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.ModDamageDoneNeg, i), 0);
|
||||
SetUpdateFieldValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.ModDamageDonePos, i), 0);
|
||||
SetUpdateFieldValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.ModDamageDonePercent, i), 1.0f);
|
||||
SetUpdateFieldValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.ModHealingDonePercent, i), 1.0f);
|
||||
}
|
||||
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.ModSpellPowerPercent), 1.0f);
|
||||
@@ -6324,7 +6132,8 @@ namespace Game.Entities
|
||||
|
||||
UpdateCriteria(CriteriaTypes.ExploreArea, GetAreaId());
|
||||
|
||||
if (areaEntry.ExplorationLevel > 0)
|
||||
var areaLevels = Global.DB2Mgr.GetContentTuningData(areaEntry.ContentTuningID, m_playerData.CtrOptions.GetValue().ContentTuningConditionMask);
|
||||
if (areaLevels.HasValue)
|
||||
{
|
||||
if (GetLevel() >= WorldConfig.GetIntValue(WorldCfg.MaxPlayerLevel))
|
||||
{
|
||||
@@ -6332,7 +6141,8 @@ namespace Game.Entities
|
||||
}
|
||||
else
|
||||
{
|
||||
int diff = (int)(GetLevel() - areaEntry.ExplorationLevel);
|
||||
ushort areaLevel = (ushort)Math.Min(Math.Max((ushort)GetLevel(), areaLevels.Value.MinLevel), areaLevels.Value.MaxLevel);
|
||||
int diff = (int)(GetLevel()) - areaLevel;
|
||||
uint XP = 0;
|
||||
if (diff < -5)
|
||||
{
|
||||
@@ -6344,11 +6154,11 @@ namespace Game.Entities
|
||||
if (exploration_percent < 0)
|
||||
exploration_percent = 0;
|
||||
|
||||
XP = (uint)(Global.ObjectMgr.GetBaseXP((byte)areaEntry.ExplorationLevel) * exploration_percent / 100 * WorldConfig.GetFloatValue(WorldCfg.RateXpExplore));
|
||||
XP = (uint)(Global.ObjectMgr.GetBaseXP(areaLevel) * exploration_percent / 100 * WorldConfig.GetFloatValue(WorldCfg.RateXpExplore));
|
||||
}
|
||||
else
|
||||
{
|
||||
XP = (uint)(Global.ObjectMgr.GetBaseXP((byte)areaEntry.ExplorationLevel) * WorldConfig.GetFloatValue(WorldCfg.RateXpExplore));
|
||||
XP = (uint)(Global.ObjectMgr.GetBaseXP(areaLevel) * WorldConfig.GetFloatValue(WorldCfg.RateXpExplore));
|
||||
}
|
||||
|
||||
GiveXP(XP, null);
|
||||
@@ -7477,17 +7287,40 @@ namespace Game.Entities
|
||||
public void RemovePlayerFlagEx(PlayerFlagsEx flags) { RemoveUpdateFieldFlagValue(m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.PlayerFlagsEx), (uint)flags); }
|
||||
public void SetPlayerFlagsEx(PlayerFlagsEx flags) { SetUpdateFieldValue(m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.PlayerFlagsEx), (uint)flags); }
|
||||
|
||||
public void SetSkinId(byte skinId) { SetUpdateFieldValue(m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.SkinID), skinId); }
|
||||
public void SetFaceId(byte faceId) { SetUpdateFieldValue(m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.FaceID), faceId); }
|
||||
public void SetHairStyleId(byte hairStyleId) { SetUpdateFieldValue(m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.HairStyleID), hairStyleId); }
|
||||
public void SetHairColorId(byte hairColorId) { SetUpdateFieldValue(m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.HairColorID), hairColorId); }
|
||||
public void SetFacialHairStyleId(byte facialHairStyleId) { SetUpdateFieldValue(m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.FacialHairStyleID), facialHairStyleId); }
|
||||
public uint GetCustomizationChoice(uint chrCustomizationOptionId)
|
||||
{
|
||||
int choiceIndex = m_playerData.Customizations.FindIndexIf(choice =>
|
||||
{
|
||||
return choice.ChrCustomizationOptionID == chrCustomizationOptionId;
|
||||
});
|
||||
|
||||
if (choiceIndex >= 0)
|
||||
return m_playerData.Customizations[choiceIndex].ChrCustomizationChoiceID;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void SetCustomizations(List<ChrCustomizationChoice> customizations, bool markChanged = true)
|
||||
{
|
||||
if (markChanged)
|
||||
m_customizationsChanged = true;
|
||||
|
||||
ClearDynamicUpdateFieldValues(m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.Customizations));
|
||||
foreach (var customization in customizations)
|
||||
{
|
||||
ChrCustomizationChoice newChoice = new ChrCustomizationChoice();
|
||||
newChoice.ChrCustomizationOptionID = customization.ChrCustomizationOptionID;
|
||||
newChoice.ChrCustomizationChoiceID = customization.ChrCustomizationChoiceID;
|
||||
AddDynamicUpdateFieldValue(m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.Customizations), newChoice);
|
||||
}
|
||||
}
|
||||
|
||||
public Gender GetNativeSex() { return (Gender)(byte)m_playerData.NativeSex; }
|
||||
public void SetNativeSex(Gender sex) { SetUpdateFieldValue(m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.NativeSex), (byte)sex); }
|
||||
public void SetPvpTitle(byte pvpTitle) { SetUpdateFieldValue(m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.PvpTitle), pvpTitle); }
|
||||
public void SetArenaFaction(byte arenaFaction) { SetUpdateFieldValue(m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.ArenaFaction), arenaFaction); }
|
||||
public void ApplyModFakeInebriation(int mod, bool apply) { ApplyModUpdateFieldValue(m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.FakeInebriation), mod, apply); }
|
||||
public void SetVirtualPlayerRealm(uint virtualRealmAddress) { SetUpdateFieldValue(m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.VirtualPlayerRealm), virtualRealmAddress); }
|
||||
public void SetCustomDisplayOption(int slot, byte customDisplayOption) { SetUpdateFieldValue(ref m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.CustomDisplayOption, slot), customDisplayOption); }
|
||||
|
||||
public void AddHeirloom(uint itemId, uint flags)
|
||||
{
|
||||
@@ -7537,9 +7370,9 @@ namespace Game.Entities
|
||||
public void ApplyModOverrideAPBySpellPowerPercent(float mod, bool apply) { ApplyModUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.OverrideAPBySpellPowerPercent), mod, apply); }
|
||||
|
||||
public bool HasPlayerLocalFlag(PlayerLocalFlags flags) { return (m_activePlayerData.LocalFlags & (int)flags) != 0; }
|
||||
public void AddPlayerLocalFlag(PlayerLocalFlags flags) { SetUpdateFieldFlagValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.LocalFlags), (int)flags); }
|
||||
public void RemovePlayerLocalFlag(PlayerLocalFlags flags) { RemoveUpdateFieldFlagValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.LocalFlags), (int)flags); }
|
||||
public void SetPlayerLocalFlags(PlayerLocalFlags flags) { SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.LocalFlags), (int)flags); }
|
||||
public void AddPlayerLocalFlag(PlayerLocalFlags flags) { SetUpdateFieldFlagValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.LocalFlags), (uint)flags); }
|
||||
public void RemovePlayerLocalFlag(PlayerLocalFlags flags) { RemoveUpdateFieldFlagValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.LocalFlags), (uint)flags); }
|
||||
public void SetPlayerLocalFlags(PlayerLocalFlags flags) { SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.LocalFlags), (uint)flags); }
|
||||
|
||||
public byte GetNumRespecs() { return m_activePlayerData.NumRespecs; }
|
||||
public void SetNumRespecs(byte numRespecs) { SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.NumRespecs), numRespecs); }
|
||||
|
||||
@@ -114,7 +114,11 @@ namespace Game.Entities
|
||||
if (rested_bonus > xp) // max rested_bonus == xp or (r+x) = 200% xp
|
||||
rested_bonus = xp;
|
||||
|
||||
SetRestBonus(restType, GetRestBonus(restType) - rested_bonus);
|
||||
uint rested_loss = rested_bonus;
|
||||
if (restType == RestTypes.XP)
|
||||
MathFunctions.AddPct(ref rested_loss, _player.GetTotalAuraModifier(AuraType.ModRestedXpConsumption));
|
||||
|
||||
SetRestBonus(restType, GetRestBonus(restType) - rested_loss);
|
||||
|
||||
Log.outDebug(LogFilter.Player, "RestMgr.GetRestBonus: Player '{0}' ({1}) gain {2} xp (+{3} Rested Bonus). Rested points={4}",
|
||||
_player.GetGUID().ToString(), _player.GetName(), xp + rested_bonus, rested_bonus, GetRestBonus(restType));
|
||||
|
||||
Reference in New Issue
Block a user