Updated to 7.3.5.25996 (Db2 files not updated)
This commit is contained in:
@@ -282,6 +282,7 @@ namespace Game.Misc
|
||||
text.QuestID = (int)questID;
|
||||
text.QuestType = item.QuestIcon;
|
||||
text.QuestLevel = quest.Level;
|
||||
text.QuestMaxScalingLevel = quest.MaxScalingLevel;
|
||||
text.QuestFlags = (int)quest.Flags;
|
||||
text.QuestFlagsEx = (int)quest.FlagsEx;
|
||||
text.Repeatable = quest.IsRepeatable();
|
||||
@@ -375,6 +376,7 @@ namespace Game.Misc
|
||||
text.QuestID = questID;
|
||||
text.QuestType = questMenuItem.QuestIcon;
|
||||
text.QuestLevel = (uint)quest.Level;
|
||||
text.QuestMaxScalingLevel = (uint)quest.MaxScalingLevel;
|
||||
text.QuestFlags = (uint)quest.Flags;
|
||||
text.QuestFlagsEx = (uint)quest.FlagsEx;
|
||||
text.Repeatable = false; // NYI
|
||||
@@ -497,6 +499,7 @@ namespace Game.Misc
|
||||
packet.Info.QuestID = quest.Id;
|
||||
packet.Info.QuestType = (int)quest.Type;
|
||||
packet.Info.QuestLevel = quest.Level;
|
||||
packet.Info.QuestMaxScalingLevel = quest.MaxScalingLevel;
|
||||
packet.Info.QuestPackageID = quest.PackageID;
|
||||
packet.Info.QuestMinLevel = quest.MinLevel;
|
||||
packet.Info.QuestSortID = quest.QuestSortID;
|
||||
|
||||
@@ -2370,8 +2370,8 @@ namespace Game.Entities
|
||||
SetUInt32Value(UnitFields.Level, result.Read<uint>(6));
|
||||
SetXP(result.Read<uint>(7));
|
||||
|
||||
_LoadIntoDataField(result.Read<string>(65), (int)PlayerFields.ExploredZones1, PlayerConst.ExploredZonesSize);
|
||||
_LoadIntoDataField(result.Read<string>(66), (int)PlayerFields.KnownTitles, PlayerConst.KnowTitlesSize * 2);
|
||||
_LoadIntoDataField(result.Read<string>(66), (int)PlayerFields.ExploredZones1, PlayerConst.ExploredZonesSize);
|
||||
_LoadIntoDataField(result.Read<string>(67), (int)PlayerFields.KnownTitles, PlayerConst.KnowTitlesSize * 2);
|
||||
|
||||
SetObjectScale(1.0f);
|
||||
SetFloatValue(UnitFields.HoverHeight, 1.0f);
|
||||
@@ -2397,12 +2397,13 @@ namespace Game.Entities
|
||||
SetByteValue(PlayerFields.Bytes2, PlayerFieldOffsets.Bytes2OffsetFacialStyle, result.Read<byte>(13));
|
||||
for (byte i = 0; i < PlayerConst.CustomDisplaySize; ++i)
|
||||
SetByteValue(PlayerFields.Bytes2, (byte)(PlayerFieldOffsets.Bytes2OffsetCustomDisplayOption + i), customDisplay[i]);
|
||||
SetBankBagSlotCount(result.Read<byte>(17));
|
||||
SetInventorySlotCount(result.Read<byte>(17));
|
||||
SetBankBagSlotCount(result.Read<byte>(18));
|
||||
SetByteValue(PlayerFields.Bytes3, PlayerFieldOffsets.Bytes3OffsetGender, (byte)gender);
|
||||
SetByteValue(PlayerFields.Bytes3, PlayerFieldOffsets.Bytes3OffsetInebriation, result.Read<byte>(54));
|
||||
SetUInt32Value(PlayerFields.Flags, result.Read<uint>(19));
|
||||
SetUInt32Value(PlayerFields.FlagsEx, result.Read<uint>(20));
|
||||
SetInt32Value(PlayerFields.WatchedFactionIndex, (int)result.Read<uint>(53));
|
||||
SetByteValue(PlayerFields.Bytes3, PlayerFieldOffsets.Bytes3OffsetInebriation, result.Read<byte>(55));
|
||||
SetUInt32Value(PlayerFields.Flags, result.Read<uint>(20));
|
||||
SetUInt32Value(PlayerFields.FlagsEx, result.Read<uint>(21));
|
||||
SetInt32Value(PlayerFields.WatchedFactionIndex, (int)result.Read<uint>(54));
|
||||
|
||||
if (!ValidateAppearance((Race)result.Read<byte>(3), (Class)result.Read<byte>(4), (Gender)gender,
|
||||
GetByteValue(PlayerFields.Bytes, PlayerFieldOffsets.BytesOffsetHairStyleId),
|
||||
@@ -2416,9 +2417,9 @@ namespace Game.Entities
|
||||
}
|
||||
|
||||
// set which actionbars the client has active - DO NOT REMOVE EVER AGAIN (can be changed though, if it does change fieldwise)
|
||||
SetByteValue(PlayerFields.FieldBytes, PlayerFieldOffsets.FieldBytesOffsetActionBarToggles, result.Read<byte>(67));
|
||||
SetByteValue(PlayerFields.FieldBytes, PlayerFieldOffsets.FieldBytesOffsetActionBarToggles, result.Read<byte>(68));
|
||||
|
||||
m_fishingSteps = result.Read<byte>(71);
|
||||
m_fishingSteps = result.Read<byte>(72);
|
||||
|
||||
InitDisplayIds();
|
||||
|
||||
@@ -2442,20 +2443,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>(40);
|
||||
ulong transLowGUID = result.Read<ulong>(41);
|
||||
|
||||
Relocate(result.Read<float>(21), result.Read<float>(22), result.Read<float>(23), result.Read<float>(25));
|
||||
Relocate(result.Read<float>(22), result.Read<float>(23), result.Read<float>(24), result.Read<float>(26));
|
||||
|
||||
uint mapId = result.Read<uint>(24);
|
||||
uint instanceId = result.Read<uint>(62);
|
||||
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>(48)));
|
||||
SetRaidDifficultyID(CheckLoadedRaidDifficultyID((Difficulty)result.Read<byte>(69)));
|
||||
SetLegacyRaidDifficultyID(CheckLoadedLegacyRaidDifficultyID((Difficulty)result.Read<byte>(70)));
|
||||
SetDungeonDifficultyID(CheckLoadedDungeonDifficultyID((Difficulty)result.Read<byte>(49)));
|
||||
SetRaidDifficultyID(CheckLoadedRaidDifficultyID((Difficulty)result.Read<byte>(70)));
|
||||
SetLegacyRaidDifficultyID(CheckLoadedLegacyRaidDifficultyID((Difficulty)result.Read<byte>(71)));
|
||||
|
||||
string taxi_nodes = result.Read<string>(47);
|
||||
string taxi_nodes = result.Read<string>(48);
|
||||
|
||||
_LoadGroup(holder.GetResult(PlayerLoginQueryLoad.Group));
|
||||
|
||||
@@ -2479,9 +2480,9 @@ namespace Game.Entities
|
||||
}
|
||||
|
||||
_LoadCurrency(holder.GetResult(PlayerLoginQueryLoad.Currency));
|
||||
SetUInt32Value(PlayerFields.LifetimeHonorableKills, result.Read<uint>(49));
|
||||
SetUInt16Value(PlayerFields.Kills, 0, result.Read<ushort>(50));
|
||||
SetUInt16Value(PlayerFields.Kills, 1, result.Read<ushort>(51));
|
||||
SetUInt32Value(PlayerFields.LifetimeHonorableKills, result.Read<uint>(50));
|
||||
SetUInt16Value(PlayerFields.Kills, PlayerFieldOffsets.FieldKillsOffsetTodayKills, result.Read<ushort>(51));
|
||||
SetUInt16Value(PlayerFields.Kills, PlayerFieldOffsets.FieldKillsOffsetYesterdayKills, result.Read<ushort>(52));
|
||||
|
||||
_LoadBoundInstances(holder.GetResult(PlayerLoginQueryLoad.BoundInstances));
|
||||
_LoadInstanceTimeRestrictions(holder.GetResult(PlayerLoginQueryLoad.InstanceLockTimes));
|
||||
@@ -2559,10 +2560,10 @@ namespace Game.Entities
|
||||
|
||||
if (transport)
|
||||
{
|
||||
float x = result.Read<float>(36);
|
||||
float y = result.Read<float>(37);
|
||||
float z = result.Read<float>(38);
|
||||
float o = result.Read<float>(39);
|
||||
float x = result.Read<float>(37);
|
||||
float y = result.Read<float>(38);
|
||||
float z = result.Read<float>(39);
|
||||
float o = result.Read<float>(40);
|
||||
m_movementInfo.transport.pos = new Position(x, y, z, o);
|
||||
transport.CalculatePassengerPosition(ref x, ref y, ref z, ref o);
|
||||
|
||||
@@ -2757,7 +2758,7 @@ namespace Game.Entities
|
||||
SaveRecallPosition();
|
||||
|
||||
long now = Time.UnixTime;
|
||||
long logoutTime = result.Read<int>(31);
|
||||
long logoutTime = result.Read<int>(32);
|
||||
|
||||
// since last logout (in seconds)
|
||||
uint time_diff = (uint)(now - logoutTime);
|
||||
@@ -2770,32 +2771,32 @@ namespace Game.Entities
|
||||
|
||||
SetDrunkValue(newDrunkValue);
|
||||
|
||||
m_cinematic = result.Read<byte>(27);
|
||||
m_PlayedTimeTotal = result.Read<uint>(28);
|
||||
m_PlayedTimeLevel = result.Read<uint>(29);
|
||||
m_cinematic = result.Read<byte>(28);
|
||||
m_PlayedTimeTotal = result.Read<uint>(29);
|
||||
m_PlayedTimeLevel = result.Read<uint>(30);
|
||||
|
||||
SetTalentResetCost(result.Read<uint>(33));
|
||||
SetTalentResetTime(result.Read<uint>(34));
|
||||
SetTalentResetCost(result.Read<uint>(34));
|
||||
SetTalentResetTime(result.Read<uint>(35));
|
||||
|
||||
m_taxi.LoadTaxiMask(result.Read<string>(26)); // must be before InitTaxiNodesForLevel
|
||||
m_taxi.LoadTaxiMask(result.Read<string>(27)); // must be before InitTaxiNodesForLevel
|
||||
|
||||
PlayerExtraFlags extraflags = (PlayerExtraFlags)result.Read<uint>(41);
|
||||
PlayerExtraFlags extraflags = (PlayerExtraFlags)result.Read<uint>(42);
|
||||
|
||||
m_stableSlots = result.Read<byte>(42);
|
||||
m_stableSlots = result.Read<byte>(43);
|
||||
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>(43);
|
||||
atLoginFlags = (AtLoginFlags)result.Read<uint>(44);
|
||||
|
||||
// Honor system
|
||||
// Update Honor kills data
|
||||
m_lastHonorUpdateTime = logoutTime;
|
||||
UpdateHonorFields();
|
||||
|
||||
m_deathExpireTime = result.Read<uint>(46);
|
||||
m_deathExpireTime = result.Read<uint>(47);
|
||||
if (m_deathExpireTime > now + PlayerConst.MaxDeathCount * PlayerConst.DeathExpireStep)
|
||||
m_deathExpireTime = now + PlayerConst.MaxDeathCount * PlayerConst.DeathExpireStep - 1;
|
||||
|
||||
@@ -2826,19 +2827,19 @@ namespace Game.Entities
|
||||
InitRunes();
|
||||
|
||||
// rest bonus can only be calculated after InitStatsForLevel()
|
||||
_restMgr.LoadRestBonus(RestTypes.XP, (PlayerRestState)result.Read<byte>(18), result.Read<float>(30));
|
||||
_restMgr.LoadRestBonus(RestTypes.XP, (PlayerRestState)result.Read<byte>(19), result.Read<float>(31));
|
||||
|
||||
// load skills after InitStatsForLevel because it triggering aura apply also
|
||||
_LoadSkills(holder.GetResult(PlayerLoginQueryLoad.Skills));
|
||||
UpdateSkillsForLevel();
|
||||
|
||||
SetPrimarySpecialization(result.Read<uint>(35));
|
||||
SetActiveTalentGroup(result.Read<byte>(63));
|
||||
SetPrimarySpecialization(result.Read<uint>(36));
|
||||
SetActiveTalentGroup(result.Read<byte>(64));
|
||||
ChrSpecializationRecord primarySpec = CliDB.ChrSpecializationStorage.LookupByKey(GetPrimarySpecialization());
|
||||
if (primarySpec == null || primarySpec.ClassID != (byte)GetClass() || GetActiveTalentGroup() >= PlayerConst.MaxSpecializations)
|
||||
ResetTalentSpecialization();
|
||||
|
||||
uint lootSpecId = result.Read<byte>(64);
|
||||
uint lootSpecId = result.Read<byte>(65);
|
||||
ChrSpecializationRecord chrSpec = CliDB.ChrSpecializationStorage.LookupByKey(lootSpecId);
|
||||
if (chrSpec != null)
|
||||
{
|
||||
@@ -2900,7 +2901,7 @@ 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>(52);
|
||||
uint curTitle = result.Read<uint>(53);
|
||||
if (curTitle != 0 && !HasTitle(curTitle))
|
||||
curTitle = 0;
|
||||
|
||||
@@ -2923,7 +2924,7 @@ namespace Game.Entities
|
||||
UpdateAllStats();
|
||||
|
||||
// restore remembered power/health values (but not more max values)
|
||||
uint savedHealth = result.Read<uint>(55);
|
||||
uint savedHealth = result.Read<uint>(56);
|
||||
SetHealth(savedHealth > GetMaxHealth() ? GetMaxHealth() : savedHealth);
|
||||
int loadedPowers = 0;
|
||||
for (PowerType i = 0; i < PowerType.Max; ++i)
|
||||
@@ -3014,7 +3015,7 @@ namespace Game.Entities
|
||||
}
|
||||
|
||||
// RaF stuff.
|
||||
m_grantableLevels = result.Read<byte>(68);
|
||||
m_grantableLevels = result.Read<byte>(69);
|
||||
if (GetSession().IsARecruiter() || (GetSession().GetRecruiterId() != 0))
|
||||
SetFlag(ObjectFields.DynamicFlags, UnitDynFlags.ReferAFriend);
|
||||
|
||||
@@ -3036,9 +3037,9 @@ namespace Game.Entities
|
||||
holder.GetResult(PlayerLoginQueryLoad.GarrisonFollowerAbilities)))
|
||||
_garrison = garrison;
|
||||
|
||||
_InitHonorLevelOnLoadFromDB(result.Read<uint>(72), result.Read<uint>(73), result.Read<uint>(74));
|
||||
_InitHonorLevelOnLoadFromDB(result.Read<uint>(73), result.Read<uint>(74), result.Read<uint>(75));
|
||||
|
||||
_restMgr.LoadRestBonus(RestTypes.Honor, (PlayerRestState)result.Read<byte>(75), result.Read<float>(76));
|
||||
_restMgr.LoadRestBonus(RestTypes.Honor, (PlayerRestState)result.Read<byte>(76), result.Read<float>(77));
|
||||
if (time_diff > 0)
|
||||
{
|
||||
//speed collect rest bonus in offline, in logout, far from tavern, city (section/in hour)
|
||||
@@ -3100,6 +3101,7 @@ namespace Game.Entities
|
||||
stmt.AddValue(index++, GetByteValue(PlayerFields.Bytes2, PlayerFieldOffsets.Bytes2OffsetFacialStyle));
|
||||
for (int i = 0; i < PlayerConst.CustomDisplaySize; ++i)
|
||||
stmt.AddValue(index++, GetByteValue(PlayerFields.Bytes2, (byte)(PlayerFieldOffsets.Bytes2OffsetCustomDisplayOption + i)));
|
||||
stmt.AddValue(index++, GetInventorySlotCount());
|
||||
stmt.AddValue(index++, GetBankBagSlotCount());
|
||||
stmt.AddValue(index++, (byte)GetUInt32Value(PlayerFields.RestInfo + PlayerFieldOffsets.RestStateXp));
|
||||
stmt.AddValue(index++, GetUInt32Value(PlayerFields.Flags));
|
||||
@@ -3211,6 +3213,7 @@ namespace Game.Entities
|
||||
|
||||
stmt.AddValue(index++, GetByteValue(PlayerFields.FieldBytes, PlayerFieldOffsets.FieldBytesOffsetActionBarToggles));
|
||||
stmt.AddValue(index++, m_grantableLevels);
|
||||
stmt.AddValue(index++, Global.WorldMgr.GetRealm().Build);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -3231,6 +3234,7 @@ namespace Game.Entities
|
||||
for (int i = 0; i < PlayerConst.CustomDisplaySize; ++i)
|
||||
stmt.AddValue(index++, GetByteValue(PlayerFields.Bytes2, (byte)(
|
||||
PlayerFieldOffsets.Bytes2OffsetCustomDisplayOption + i)));
|
||||
stmt.AddValue(index++, GetInventorySlotCount());
|
||||
stmt.AddValue(index++, GetBankBagSlotCount());
|
||||
stmt.AddValue(index++, (byte)GetUInt32Value(PlayerFields.RestInfo + PlayerFieldOffsets.RestStateXp));
|
||||
stmt.AddValue(index++, GetUInt32Value(PlayerFields.Flags));
|
||||
@@ -3365,6 +3369,7 @@ namespace Game.Entities
|
||||
stmt.AddValue(index++, GetPrestigeLevel());
|
||||
stmt.AddValue(index++, (byte)GetUInt32Value(PlayerFields.RestInfo + PlayerFieldOffsets.RestStateHonor));
|
||||
stmt.AddValue(index++, _restMgr.GetRestBonus(RestTypes.Honor));
|
||||
stmt.AddValue(index++, Global.WorldMgr.GetRealm().Build);
|
||||
|
||||
// Index
|
||||
stmt.AddValue(index, GetGUID().GetCounter());
|
||||
|
||||
@@ -274,7 +274,8 @@ namespace Game.Entities
|
||||
|
||||
if (inventory)
|
||||
{
|
||||
for (byte i = InventorySlots.ItemStart; i < InventorySlots.ItemEnd; i++)
|
||||
int inventoryEnd = InventorySlots.ItemStart + GetInventorySlotCount();
|
||||
for (byte i = InventorySlots.ItemStart; i < inventoryEnd; i++)
|
||||
{
|
||||
Item pItem = GetItemByPos(InventorySlots.Bag0, i);
|
||||
if (pItem != null)
|
||||
@@ -326,7 +327,8 @@ namespace Game.Entities
|
||||
|
||||
if (inventory)
|
||||
{
|
||||
for (byte i = InventorySlots.ItemStart; i < InventorySlots.ItemEnd; i++)
|
||||
int inventoryEnd = InventorySlots.ItemStart + GetInventorySlotCount();
|
||||
for (byte i = InventorySlots.ItemStart; i < inventoryEnd; i++)
|
||||
{
|
||||
Item pItem = GetItemByPos(InventorySlots.Bag0, i);
|
||||
if (pItem != null)
|
||||
@@ -388,7 +390,8 @@ namespace Game.Entities
|
||||
{
|
||||
uint TotalCost = 0;
|
||||
// equipped, backpack, bags itself
|
||||
for (byte i = EquipmentSlot.Start; i < InventorySlots.ItemEnd; i++)
|
||||
int inventoryEnd = InventorySlots.ItemStart + GetInventorySlotCount();
|
||||
for (byte i = EquipmentSlot.Start; i < inventoryEnd; i++)
|
||||
TotalCost += DurabilityRepair((ushort)((InventorySlots.Bag0 << 8) | i), cost, discountMod, guildBank);
|
||||
|
||||
// items in inventory bags
|
||||
@@ -556,6 +559,7 @@ namespace Game.Entities
|
||||
}
|
||||
|
||||
// not specific slot or have space for partly store only in specific slot
|
||||
byte inventoryEnd = (byte)(InventorySlots.ItemStart + GetInventorySlotCount());
|
||||
|
||||
// in specific bag
|
||||
if (bag != ItemConst.NullBag)
|
||||
@@ -597,7 +601,7 @@ namespace Game.Entities
|
||||
return InventoryResult.ItemMaxCount;
|
||||
}
|
||||
|
||||
res = CanStoreItem_InInventorySlots(InventorySlots.ItemStart, InventorySlots.ItemEnd, dest, pProto, ref count, true, pItem, bag, slot);
|
||||
res = CanStoreItem_InInventorySlots(InventorySlots.ItemStart, inventoryEnd, dest, pProto, ref count, true, pItem, bag, slot);
|
||||
if (res != InventoryResult.Ok)
|
||||
{
|
||||
no_space_count = count + no_similar_count;
|
||||
@@ -678,7 +682,7 @@ namespace Game.Entities
|
||||
}
|
||||
}
|
||||
|
||||
res = CanStoreItem_InInventorySlots(InventorySlots.ItemStart, InventorySlots.ItemEnd, dest, pProto, ref count, false, pItem, bag, slot);
|
||||
res = CanStoreItem_InInventorySlots(InventorySlots.ItemStart, inventoryEnd, dest, pProto, ref count, false, pItem, bag, slot);
|
||||
if (res != InventoryResult.Ok)
|
||||
{
|
||||
no_space_count = count + no_similar_count;
|
||||
@@ -754,7 +758,7 @@ namespace Game.Entities
|
||||
return InventoryResult.ItemMaxCount;
|
||||
}
|
||||
|
||||
res = CanStoreItem_InInventorySlots(InventorySlots.ItemStart, InventorySlots.ItemEnd, dest, pProto, ref count, true, pItem, bag, slot);
|
||||
res = CanStoreItem_InInventorySlots(InventorySlots.ItemStart, inventoryEnd, dest, pProto, ref count, true, pItem, bag, slot);
|
||||
if (res != InventoryResult.Ok)
|
||||
{
|
||||
no_space_count = count + no_similar_count;
|
||||
@@ -917,7 +921,8 @@ namespace Game.Entities
|
||||
uint[] inventoryCounts = new uint[InventorySlots.ItemEnd - InventorySlots.ItemStart];
|
||||
uint[][] bagCounts = new uint[InventorySlots.BagEnd - InventorySlots.BagStart][];
|
||||
|
||||
for (byte i = InventorySlots.ItemStart; i < InventorySlots.ItemEnd; i++)
|
||||
int inventoryEnd = InventorySlots.ItemStart + GetInventorySlotCount();
|
||||
for (byte i = InventorySlots.ItemStart; i < inventoryEnd; i++)
|
||||
{
|
||||
item2 = GetItemByPos(InventorySlots.Bag0, i);
|
||||
if (item2 && !item2.IsInTrade())
|
||||
@@ -974,7 +979,7 @@ namespace Game.Entities
|
||||
// search stack for merge to
|
||||
if (pProto.GetMaxStackSize() != 1)
|
||||
{
|
||||
for (byte t = InventorySlots.ItemStart; t < InventorySlots.ItemEnd; ++t)
|
||||
for (byte t = InventorySlots.ItemStart; t < inventoryEnd; ++t)
|
||||
{
|
||||
item2 = GetItemByPos(InventorySlots.Bag0, t);
|
||||
if (item2 && item2.CanBeMergedPartlyWith(pProto) == InventoryResult.Ok && inventoryCounts[t - InventorySlots.ItemStart] + item.GetCount() <= pProto.GetMaxStackSize())
|
||||
@@ -1043,7 +1048,7 @@ namespace Game.Entities
|
||||
|
||||
// search free slot
|
||||
b_found = false;
|
||||
for (int t = InventorySlots.ItemStart; t < InventorySlots.ItemEnd; ++t)
|
||||
for (int t = InventorySlots.ItemStart; t < inventoryEnd; ++t)
|
||||
{
|
||||
if (inventoryCounts[t - InventorySlots.ItemStart] == 0)
|
||||
{
|
||||
@@ -1538,7 +1543,8 @@ namespace Game.Entities
|
||||
}
|
||||
}
|
||||
|
||||
for (byte i = InventorySlots.ItemStart; i < InventorySlots.ItemEnd; ++i)
|
||||
int inventoryEnd = InventorySlots.ItemStart + GetInventorySlotCount();
|
||||
for (byte i = InventorySlots.ItemStart; i < inventoryEnd; ++i)
|
||||
{
|
||||
Item pItem = GetItemByPos(InventorySlots.Bag0, i);
|
||||
if (pItem != null)
|
||||
@@ -2682,7 +2688,8 @@ namespace Game.Entities
|
||||
}
|
||||
public Item GetItemByGuid(ObjectGuid guid)
|
||||
{
|
||||
for (byte i = EquipmentSlot.Start; i < InventorySlots.ItemEnd; ++i)
|
||||
int inventoryEnd = InventorySlots.ItemStart + GetInventorySlotCount();
|
||||
for (byte i = EquipmentSlot.Start; i < inventoryEnd; ++i)
|
||||
{
|
||||
Item pItem = GetItemByPos(InventorySlots.Bag0, i);
|
||||
if (pItem != null)
|
||||
@@ -2744,7 +2751,8 @@ namespace Game.Entities
|
||||
public uint GetItemCount(uint item, bool inBankAlso = false, Item skipItem = null)
|
||||
{
|
||||
uint count = 0;
|
||||
for (byte i = EquipmentSlot.Start; i < InventorySlots.ItemEnd; i++)
|
||||
int inventoryEnd = InventorySlots.ItemStart + GetInventorySlotCount();
|
||||
for (byte i = EquipmentSlot.Start; i < inventoryEnd; i++)
|
||||
{
|
||||
Item pItem = GetItemByPos(InventorySlots.Bag0, i);
|
||||
if (pItem != null)
|
||||
@@ -2761,7 +2769,7 @@ namespace Game.Entities
|
||||
|
||||
if (skipItem != null && skipItem.GetTemplate().GetGemProperties() != 0)
|
||||
{
|
||||
for (byte i = EquipmentSlot.Start; i < InventorySlots.ItemEnd; ++i)
|
||||
for (byte i = EquipmentSlot.Start; i < inventoryEnd; ++i)
|
||||
{
|
||||
Item pItem = GetItemByPos(InventorySlots.Bag0, i);
|
||||
if (pItem != null)
|
||||
@@ -2874,7 +2882,8 @@ namespace Game.Entities
|
||||
public Item GetItemByEntry(uint entry)
|
||||
{
|
||||
// in inventory
|
||||
for (byte i = InventorySlots.ItemStart; i < InventorySlots.ItemEnd; ++i)
|
||||
int inventoryEnd = InventorySlots.ItemStart + GetInventorySlotCount();
|
||||
for (byte i = InventorySlots.ItemStart; i < inventoryEnd; ++i)
|
||||
{
|
||||
Item pItem = GetItemByPos(InventorySlots.Bag0, i);
|
||||
if (pItem != null)
|
||||
@@ -2919,7 +2928,8 @@ namespace Game.Entities
|
||||
{
|
||||
List<Item> itemList = new List<Item>();
|
||||
|
||||
for (byte i = InventorySlots.ItemStart; i < InventorySlots.ItemEnd; ++i)
|
||||
int inventoryEnd = InventorySlots.ItemStart + GetInventorySlotCount();
|
||||
for (byte i = InventorySlots.ItemStart; i < inventoryEnd; ++i)
|
||||
{
|
||||
Item item = GetItemByPos(InventorySlots.Bag0, i);
|
||||
if (item != null)
|
||||
@@ -2974,7 +2984,8 @@ namespace Game.Entities
|
||||
public bool HasItemCount(uint item, uint count = 1, bool inBankAlso = false)
|
||||
{
|
||||
uint tempcount = 0;
|
||||
for (byte i = EquipmentSlot.Start; i < InventorySlots.ItemEnd; i++)
|
||||
int inventoryEnd = InventorySlots.ItemStart + GetInventorySlotCount();
|
||||
for (byte i = EquipmentSlot.Start; i < inventoryEnd; i++)
|
||||
{
|
||||
Item pItem = GetItemByPos(InventorySlots.Bag0, i);
|
||||
if (pItem != null && pItem.GetEntry() == item && !pItem.IsInTrade())
|
||||
@@ -3083,7 +3094,7 @@ namespace Game.Entities
|
||||
return true;
|
||||
|
||||
// backpack slots
|
||||
if (slot >= InventorySlots.ItemStart && slot < InventorySlots.ItemEnd)
|
||||
if (slot >= InventorySlots.ItemStart && slot < InventorySlots.ItemStart + GetInventorySlotCount())
|
||||
return true;
|
||||
|
||||
// bank main slots
|
||||
@@ -3115,7 +3126,8 @@ namespace Game.Entities
|
||||
|
||||
public Item GetChildItemByGuid(ObjectGuid guid)
|
||||
{
|
||||
for (byte i = EquipmentSlot.Start; i < InventorySlots.ItemEnd; ++i)
|
||||
int inventoryEnd = InventorySlots.ItemStart + GetInventorySlotCount();
|
||||
for (byte i = EquipmentSlot.Start; i < inventoryEnd; ++i)
|
||||
{
|
||||
Item pItem = GetItemByPos(InventorySlots.Bag0, i);
|
||||
if (pItem)
|
||||
@@ -3136,7 +3148,8 @@ namespace Game.Entities
|
||||
uint GetItemCountWithLimitCategory(uint limitCategory, Item skipItem)
|
||||
{
|
||||
uint count = 0;
|
||||
for (byte i = EquipmentSlot.Start; i < InventorySlots.ItemEnd; ++i)
|
||||
int inventoryEnd = InventorySlots.ItemStart + GetInventorySlotCount();
|
||||
for (byte i = EquipmentSlot.Start; i < inventoryEnd; ++i)
|
||||
{
|
||||
Item pItem = GetItemByPos(InventorySlots.Bag0, i);
|
||||
if (pItem)
|
||||
@@ -3220,7 +3233,8 @@ namespace Game.Entities
|
||||
Log.outDebug(LogFilter.Player, "STORAGE: DestroyConjuredItems");
|
||||
|
||||
// in inventory
|
||||
for (byte i = InventorySlots.ItemStart; i < InventorySlots.ItemEnd; i++)
|
||||
int inventoryEnd = InventorySlots.ItemStart + GetInventorySlotCount();
|
||||
for (byte i = InventorySlots.ItemStart; i < inventoryEnd; i++)
|
||||
{
|
||||
Item pItem = GetItemByPos(InventorySlots.Bag0, i);
|
||||
if (pItem)
|
||||
@@ -3260,7 +3274,8 @@ namespace Game.Entities
|
||||
Log.outDebug(LogFilter.Player, "STORAGE: DestroyZoneLimitedItem in map {0} and area {1}", GetMapId(), new_zone);
|
||||
|
||||
// in inventory
|
||||
for (byte i = InventorySlots.ItemStart; i < InventorySlots.ItemEnd; i++)
|
||||
int inventoryEnd = InventorySlots.ItemStart + GetInventorySlotCount();
|
||||
for (byte i = InventorySlots.ItemStart; i < inventoryEnd; i++)
|
||||
{
|
||||
Item pItem = GetItemByPos(InventorySlots.Bag0, i);
|
||||
if (pItem)
|
||||
@@ -3873,7 +3888,8 @@ namespace Game.Entities
|
||||
|
||||
public bool HasItemTotemCategory(uint TotemCategory)
|
||||
{
|
||||
for (byte i = EquipmentSlot.Start; i < EquipmentSlot.End; ++i)
|
||||
int inventoryEnd = InventorySlots.ItemStart + GetInventorySlotCount();
|
||||
for (byte i = EquipmentSlot.Start; i < inventoryEnd; ++i)
|
||||
{
|
||||
Item item = GetUseableItemByPos(InventorySlots.Bag0, i);
|
||||
if (item && Global.DB2Mgr.IsTotemCategoryCompatibleWith(item.GetTemplate().GetTotemCategory(), TotemCategory))
|
||||
@@ -5701,7 +5717,8 @@ namespace Game.Entities
|
||||
uint remcount = 0;
|
||||
|
||||
// in inventory
|
||||
for (byte i = InventorySlots.ItemStart; i < InventorySlots.ItemEnd; ++i)
|
||||
int inventoryEnd = InventorySlots.ItemStart + GetInventorySlotCount();
|
||||
for (byte i = InventorySlots.ItemStart; i < inventoryEnd; ++i)
|
||||
{
|
||||
Item item = GetItemByPos(InventorySlots.Bag0, i);
|
||||
if (item != null)
|
||||
@@ -5973,6 +5990,52 @@ namespace Game.Entities
|
||||
}
|
||||
}
|
||||
|
||||
public byte GetInventorySlotCount() { return GetByteValue(PlayerFields.Bytes2, PlayerFieldOffsets.FieldBytes2OffsetNumBackpackSlots); }
|
||||
public void SetInventorySlotCount(byte slots)
|
||||
{
|
||||
//ASSERT(slots <= (INVENTORY_SLOT_ITEM_END - INVENTORY_SLOT_ITEM_START));
|
||||
|
||||
if (slots < GetInventorySlotCount())
|
||||
{
|
||||
List<Item> unstorableItems = new List<Item>();
|
||||
|
||||
for (byte slot = (byte)(InventorySlots.ItemStart + slots); slot < InventorySlots.ItemEnd; ++slot)
|
||||
{
|
||||
Item unstorableItem = GetItemByPos(InventorySlots.Bag0, slot);
|
||||
if (unstorableItem)
|
||||
unstorableItems.Add(unstorableItem);
|
||||
}
|
||||
|
||||
if (!unstorableItems.Empty())
|
||||
{
|
||||
int fullBatches = unstorableItems.Count / SharedConst.MaxMailItems;
|
||||
int remainder = unstorableItems.Count % SharedConst.MaxMailItems;
|
||||
SQLTransaction trans = new SQLTransaction();
|
||||
|
||||
var sendItemsBatch = new Action<int, int>((batchNumber, batchSize) =>
|
||||
{
|
||||
MailDraft draft = new MailDraft(Global.ObjectMgr.GetCypherString(CypherStrings.NotEquippedItem), "There were problems with equipping item(s).");
|
||||
for (int j = 0; j < batchSize; ++j)
|
||||
draft.AddItem(unstorableItems[batchNumber * SharedConst.MaxMailItems + j]);
|
||||
|
||||
draft.SendMailTo(trans, this, new MailSender(this, MailStationery.Gm), MailCheckMask.Copied);
|
||||
});
|
||||
|
||||
for (int batch = 0; batch < fullBatches; ++batch)
|
||||
sendItemsBatch(batch, SharedConst.MaxMailItems);
|
||||
|
||||
if (remainder != 0)
|
||||
sendItemsBatch(fullBatches, remainder);
|
||||
|
||||
DB.Characters.CommitTransaction(trans);
|
||||
|
||||
SendPacket(new CharacterInventoryOverflowWarning());
|
||||
}
|
||||
}
|
||||
|
||||
SetByteValue(PlayerFields.FieldBytes2, PlayerFieldOffsets.FieldBytes2OffsetNumBackpackSlots, slots);
|
||||
}
|
||||
|
||||
public byte GetBankBagSlotCount() { return GetByteValue(PlayerFields.Bytes3, PlayerFieldOffsets.Bytes3OffsetBankBagSlots); }
|
||||
public void SetBankBagSlotCount(byte count) { SetByteValue(PlayerFields.Bytes3, PlayerFieldOffsets.Bytes3OffsetBankBagSlots, count); }
|
||||
|
||||
|
||||
@@ -211,7 +211,13 @@ namespace Game.Entities
|
||||
return false;
|
||||
}
|
||||
|
||||
public int GetQuestLevel(Quest quest) { return quest != null && (quest.Level > 0) ? quest.Level : (int)getLevel(); }
|
||||
public uint GetQuestLevel(Quest quest)
|
||||
{
|
||||
if (quest == null)
|
||||
return getLevel();
|
||||
|
||||
return (uint)(quest.Level > 0 ? quest.Level : Math.Min((int)getLevel(), quest.MaxScalingLevel));
|
||||
}
|
||||
|
||||
public bool IsQuestRewarded(uint quest_id)
|
||||
{
|
||||
@@ -1372,7 +1378,7 @@ namespace Game.Entities
|
||||
|
||||
public bool SatisfyQuestRace(Quest qInfo, bool msg)
|
||||
{
|
||||
int reqraces = qInfo.AllowableRaces;
|
||||
long reqraces = qInfo.AllowableRaces;
|
||||
if (reqraces == -1)
|
||||
return true;
|
||||
|
||||
|
||||
@@ -224,33 +224,30 @@ namespace Game.Entities
|
||||
return GetUInt16Value(PlayerFields.SkillLineTempBonus + field, offset);
|
||||
}
|
||||
|
||||
public uint GetResurrectionSpellId()
|
||||
void InitializeSelfResurrectionSpells()
|
||||
{
|
||||
// search priceless resurrection possibilities
|
||||
uint prio = 0;
|
||||
uint spell_id = 0;
|
||||
ClearDynamicValue(PlayerDynamicFields.SelfResSpells);
|
||||
|
||||
uint[] spells = new uint[3];
|
||||
|
||||
var dummyAuras = GetAuraEffectsByType(AuraType.Dummy);
|
||||
foreach (var eff in dummyAuras)
|
||||
foreach (var auraEffect in dummyAuras)
|
||||
{
|
||||
// Soulstone Resurrection // prio: 3 (max, non death persistent)
|
||||
if (prio < 2 && eff.GetSpellInfo().SpellFamilyName == SpellFamilyNames.Warlock && eff.GetSpellInfo().SpellFamilyFlags[1].HasAnyFlag(0x1000000u))
|
||||
{
|
||||
spell_id = 3026;
|
||||
prio = 3;
|
||||
}
|
||||
if (auraEffect.GetSpellInfo().SpellFamilyName == SpellFamilyNames.Warlock && auraEffect.GetSpellInfo().SpellFamilyFlags[1].HasAnyFlag(0x1000000u))
|
||||
spells[0] = 3026;
|
||||
// Twisting Nether // prio: 2 (max)
|
||||
else if (eff.GetId() == 23701 && RandomHelper.randChance(10))
|
||||
{
|
||||
prio = 2;
|
||||
spell_id = 23700;
|
||||
}
|
||||
else if (auraEffect.GetId() == 23701 && RandomHelper.randChance(10))
|
||||
spells[1] = 23700;
|
||||
}
|
||||
|
||||
// Reincarnation (passive spell) // prio: 1
|
||||
if (prio < 1 && HasSpell(20608) && !GetSpellHistory().HasCooldown(21169))
|
||||
spell_id = 21169;
|
||||
if (HasSpell(20608) && !GetSpellHistory().HasCooldown(21169))
|
||||
spells[2] = 21169;
|
||||
|
||||
return spell_id;
|
||||
foreach (uint selfResSpell in spells)
|
||||
if (selfResSpell != 0)
|
||||
AddDynamicValue(PlayerDynamicFields.SelfResSpells, selfResSpell);
|
||||
}
|
||||
|
||||
public void PetSpellInitialize()
|
||||
@@ -1027,7 +1024,8 @@ namespace Game.Entities
|
||||
// remove enchants from inventory items
|
||||
// NOTE: no need to remove these from stats, since these aren't equipped
|
||||
// in inventory
|
||||
for (byte i = InventorySlots.ItemStart; i < InventorySlots.ItemEnd; ++i)
|
||||
int inventoryEnd = InventorySlots.ItemStart + GetInventorySlotCount();
|
||||
for (byte i = InventorySlots.ItemStart; i < inventoryEnd; ++i)
|
||||
{
|
||||
Item pItem = GetItemByPos(InventorySlots.Bag0, i);
|
||||
if (pItem)
|
||||
|
||||
@@ -231,6 +231,7 @@ namespace Game.Entities
|
||||
SetUInt32Value(PlayerFields.RestInfo + PlayerFieldOffsets.RestStateHonor, (uint)PlayerRestState.NotRAFLinked);
|
||||
SetByteValue(PlayerFields.Bytes3, PlayerFieldOffsets.Bytes3OffsetGender, (byte)createInfo.Sex);
|
||||
SetByteValue(PlayerFields.Bytes4, PlayerFieldOffsets.Bytes4OffsetArenaFaction, 0);
|
||||
SetInventorySlotCount(InventorySlots.DefaultSize);
|
||||
|
||||
SetGuidValue(ObjectFields.Data, ObjectGuid.Empty);
|
||||
SetUInt32Value(PlayerFields.GuildRank, 0);
|
||||
@@ -409,7 +410,8 @@ namespace Game.Entities
|
||||
|
||||
// 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)
|
||||
for (var i = InventorySlots.ItemStart; i < InventorySlots.ItemEnd; i++)
|
||||
int inventoryEnd = InventorySlots.ItemStart + GetInventorySlotCount();
|
||||
for (byte i = InventorySlots.ItemStart; i < inventoryEnd; i++)
|
||||
{
|
||||
Item pItem = GetItemByPos(InventorySlots.Bag0, i);
|
||||
if (pItem != null)
|
||||
@@ -744,13 +746,11 @@ namespace Game.Entities
|
||||
|
||||
public override void setDeathState(DeathState s)
|
||||
{
|
||||
uint ressSpellId = 0;
|
||||
|
||||
bool cur = IsAlive();
|
||||
bool oldIsAlive = IsAlive();
|
||||
|
||||
if (s == DeathState.JustDied)
|
||||
{
|
||||
if (!cur)
|
||||
if (!oldIsAlive)
|
||||
{
|
||||
Log.outError(LogFilter.Player, "Player.setDeathState: Attempted to kill a dead player '{0}' ({1})", GetName(), GetGUID().ToString());
|
||||
return;
|
||||
@@ -766,12 +766,8 @@ namespace Game.Entities
|
||||
//FIXME: is pet dismissed at dying or releasing spirit? if second, add setDeathState(DEAD) to HandleRepopRequestOpcode and define pet unsummon here with (s == DEAD)
|
||||
RemovePet(null, PetSaveMode.NotInSlot, true);
|
||||
|
||||
// save value before aura remove in Unit::setDeathState
|
||||
ressSpellId = GetUInt32Value(PlayerFields.SelfResSpell);
|
||||
InitializeSelfResurrectionSpells();
|
||||
|
||||
// passive spell
|
||||
if (ressSpellId == 0)
|
||||
ressSpellId = GetResurrectionSpellId();
|
||||
UpdateCriteria(CriteriaTypes.DeathAtMap, 1);
|
||||
UpdateCriteria(CriteriaTypes.Death, 1);
|
||||
UpdateCriteria(CriteriaTypes.DeathInDungeon, 1);
|
||||
@@ -782,13 +778,9 @@ namespace Game.Entities
|
||||
|
||||
base.setDeathState(s);
|
||||
|
||||
// restore resurrection spell id for player after aura remove
|
||||
if (s == DeathState.JustDied && cur && ressSpellId != 0)
|
||||
SetUInt32Value(PlayerFields.SelfResSpell, ressSpellId);
|
||||
|
||||
if (IsAlive() && !cur)
|
||||
if (IsAlive() && !oldIsAlive)
|
||||
//clear aura case after resurrection by another way (spells will be applied before next death)
|
||||
SetUInt32Value(PlayerFields.SelfResSpell, 0);
|
||||
ClearDynamicValue(PlayerDynamicFields.SelfResSpells);
|
||||
}
|
||||
|
||||
public override void DestroyForPlayer(Player target)
|
||||
@@ -1667,15 +1659,15 @@ namespace Game.Entities
|
||||
continue;
|
||||
|
||||
if (quest.IsDaily())
|
||||
rep = CalculateReputationGain(ReputationSource.DailyQuest, (uint)GetQuestLevel(quest), rep, (int)quest.RewardFactionId[i], noQuestBonus);
|
||||
rep = CalculateReputationGain(ReputationSource.DailyQuest, GetQuestLevel(quest), rep, (int)quest.RewardFactionId[i], noQuestBonus);
|
||||
else if (quest.IsWeekly())
|
||||
rep = CalculateReputationGain(ReputationSource.WeeklyQuest, (uint)GetQuestLevel(quest), rep, (int)quest.RewardFactionId[i], noQuestBonus);
|
||||
rep = CalculateReputationGain(ReputationSource.WeeklyQuest, GetQuestLevel(quest), rep, (int)quest.RewardFactionId[i], noQuestBonus);
|
||||
else if (quest.IsMonthly())
|
||||
rep = CalculateReputationGain(ReputationSource.MonthlyQuest, (uint)GetQuestLevel(quest), rep, (int)quest.RewardFactionId[i], noQuestBonus);
|
||||
rep = CalculateReputationGain(ReputationSource.MonthlyQuest, GetQuestLevel(quest), rep, (int)quest.RewardFactionId[i], noQuestBonus);
|
||||
else if (quest.IsRepeatable())
|
||||
rep = CalculateReputationGain(ReputationSource.RepeatableQuest, (uint)GetQuestLevel(quest), rep, (int)quest.RewardFactionId[i], noQuestBonus);
|
||||
rep = CalculateReputationGain(ReputationSource.RepeatableQuest, GetQuestLevel(quest), rep, (int)quest.RewardFactionId[i], noQuestBonus);
|
||||
else
|
||||
rep = CalculateReputationGain(ReputationSource.Quest, (uint)GetQuestLevel(quest), rep, (int)quest.RewardFactionId[i], noQuestBonus);
|
||||
rep = CalculateReputationGain(ReputationSource.Quest, GetQuestLevel(quest), rep, (int)quest.RewardFactionId[i], noQuestBonus);
|
||||
|
||||
bool noSpillover = Convert.ToBoolean(quest.RewardReputationMask & (1 << i));
|
||||
GetReputationMgr().ModifyReputation(factionEntry, rep, noSpillover);
|
||||
@@ -5003,11 +4995,13 @@ namespace Game.Entities
|
||||
DisplayPlayerChoice displayPlayerChoice = new DisplayPlayerChoice();
|
||||
displayPlayerChoice.SenderGUID = sender;
|
||||
displayPlayerChoice.ChoiceID = choiceId;
|
||||
displayPlayerChoice.UiTextureKitID = playerChoice.UiTextureKitId;
|
||||
displayPlayerChoice.Question = playerChoice.Question;
|
||||
if (playerChoiceLocale != null)
|
||||
ObjectManager.GetLocaleString(playerChoiceLocale.Question, locale, ref displayPlayerChoice.Question);
|
||||
|
||||
displayPlayerChoice.CloseChoiceFrame = false;
|
||||
displayPlayerChoice.HideWarboardHeader = playerChoice.HideWarboardHeader;
|
||||
|
||||
for (var i = 0; i < playerChoice.Responses.Count; ++i)
|
||||
{
|
||||
@@ -5900,7 +5894,9 @@ namespace Game.Entities
|
||||
RemoveByteFlag(UnitFields.Bytes2, UnitBytes2Offsets.PvpFlag, (UnitBytes2Flags.FFAPvp | UnitBytes2Flags.Sanctuary));
|
||||
|
||||
// restore if need some important flags
|
||||
SetUInt32Value(PlayerFields.FieldBytes2, 0); // flags empty by default
|
||||
SetByteValue(PlayerFields.FieldBytes2, PlayerFieldOffsets.FieldBytes2OffsetIgnorePowerRegenPredictionMask, 0);
|
||||
SetByteValue(PlayerFields.FieldBytes2, PlayerFieldOffsets.FieldBytes2OffsetAuraVision, 0);
|
||||
SetByteValue(PlayerFields.FieldBytes2, 3, 0);
|
||||
|
||||
if (reapplyMods) // reapply stats values only on .reset stats (level) command
|
||||
_ApplyAllStatBonuses();
|
||||
@@ -6512,7 +6508,7 @@ namespace Game.Entities
|
||||
packet.Reason = victim ? PlayerLogXPReason.Kill : PlayerLogXPReason.NoKill;
|
||||
packet.Amount = (int)xp;
|
||||
packet.GroupBonus = group_rate;
|
||||
packet.ReferAFriend = recruitAFriend;
|
||||
packet.ReferAFriendBonusType = (byte)(recruitAFriend ? 1 : 0);
|
||||
SendPacket(packet);
|
||||
|
||||
uint curXP = GetUInt32Value(PlayerFields.Xp);
|
||||
|
||||
@@ -673,8 +673,10 @@ namespace Game.Entities
|
||||
z = nextFrame.Node.Loc.Z,
|
||||
o = nextFrame.InitialOrientation;
|
||||
|
||||
foreach (var obj in _passengers)
|
||||
for (var i =0; i < _passengers.Count; ++i)
|
||||
{
|
||||
WorldObject obj = _passengers[i];
|
||||
|
||||
float destX, destY, destZ, destO;
|
||||
obj.m_movementInfo.transport.pos.GetPosition(out destX, out destY, out destZ, out destO);
|
||||
TransportPosHelper.CalculatePassengerPosition(ref destX, ref destY, ref destZ, ref destO, x, y, z, o);
|
||||
|
||||
@@ -441,10 +441,10 @@ namespace Game
|
||||
public void LoadRaceAndClassExpansionRequirements()
|
||||
{
|
||||
uint oldMSTime = Time.GetMSTime();
|
||||
_raceExpansionRequirementStorage.Clear();
|
||||
_raceUnlockRequirementStorage.Clear();
|
||||
|
||||
// 0 1
|
||||
SQLResult result = DB.World.Query("SELECT raceID, expansion FROM `race_expansion_requirement`");
|
||||
// 0 1 2
|
||||
SQLResult result = DB.World.Query("SELECT raceID, expansion, achievementId FROM `race_expansion_requirement`");
|
||||
if (!result.IsEmpty())
|
||||
{
|
||||
uint count = 0;
|
||||
@@ -452,21 +452,32 @@ namespace Game
|
||||
{
|
||||
byte raceID = result.Read<byte>(0);
|
||||
byte expansion = result.Read<byte>(1);
|
||||
uint achievementId = result.Read<uint>(2);
|
||||
|
||||
ChrRacesRecord raceEntry = CliDB.ChrRacesStorage.LookupByKey(raceID);
|
||||
if (raceEntry == null)
|
||||
{
|
||||
Log.outError(LogFilter.Sql, "Race {0} defined in `race_expansion_requirement` does not exists, skipped.", raceID);
|
||||
Log.outError(LogFilter.Sql, "Race {0} defined in `race_unlock_requirement` does not exists, skipped.", raceID);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (expansion >= (int)Expansion.Max)
|
||||
if (expansion >= (int)Expansion.MaxAccountExpansions)
|
||||
{
|
||||
Log.outError(LogFilter.Sql, "Race {0} defined in `race_expansion_requirement` has incorrect expansion {1}, skipped.", raceID, expansion);
|
||||
Log.outError(LogFilter.Sql, "Race {0} defined in `race_unlock_requirement` has incorrect expansion {1}, skipped.", raceID, expansion);
|
||||
continue;
|
||||
}
|
||||
|
||||
_raceExpansionRequirementStorage[raceID] = expansion;
|
||||
if (achievementId != 0 && !CliDB.AchievementStorage.ContainsKey(achievementId))
|
||||
{
|
||||
Log.outError(LogFilter.Sql, $"Race {raceID} defined in `race_unlock_requirement` has incorrect achievement {achievementId}, skipped.");
|
||||
continue;
|
||||
}
|
||||
|
||||
RaceUnlockRequirement raceUnlockRequirement = new RaceUnlockRequirement();
|
||||
raceUnlockRequirement.Expansion = expansion;
|
||||
raceUnlockRequirement.AchievementId = achievementId;
|
||||
|
||||
_raceUnlockRequirementStorage[raceID] = raceUnlockRequirement;
|
||||
|
||||
++count;
|
||||
}
|
||||
@@ -573,13 +584,8 @@ namespace Game
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public Dictionary<byte, byte> GetRaceExpansionRequirements() { return _raceExpansionRequirementStorage; }
|
||||
public Expansion GetRaceExpansionRequirement(Race race)
|
||||
{
|
||||
if (_raceExpansionRequirementStorage.ContainsKey((byte)race))
|
||||
return (Expansion)_raceExpansionRequirementStorage[(byte)race];
|
||||
return Expansion.Classic;
|
||||
}
|
||||
public Dictionary<byte, RaceUnlockRequirement> GetRaceUnlockRequirements() { return _raceUnlockRequirementStorage; }
|
||||
public RaceUnlockRequirement GetRaceUnlockRequirement(Race race) { return _raceUnlockRequirementStorage.LookupByKey((byte)race); }
|
||||
public Dictionary<byte, byte> GetClassExpansionRequirements() { return _classExpansionRequirementStorage; }
|
||||
public Expansion GetClassExpansionRequirement(Class class_)
|
||||
{
|
||||
@@ -4854,7 +4860,7 @@ namespace Game
|
||||
if (id == -1)
|
||||
return equip[RandomHelper.IRand(0, equip.Count - 1)].Item2;
|
||||
else
|
||||
return equip.Find(p => p.Item1 == id).Item2;
|
||||
return equip.Find(p => p.Item1 == id)?.Item2;
|
||||
}
|
||||
|
||||
//Maps
|
||||
@@ -6187,35 +6193,35 @@ namespace Game
|
||||
_exclusiveQuestGroups.Clear();
|
||||
|
||||
SQLResult result = DB.World.Query("SELECT " +
|
||||
//0 1 2 3 4 5 6 7 8 9 10
|
||||
"ID, QuestType, QuestLevel, QuestPackageID, MinLevel, QuestSortID, QuestInfoID, SuggestedGroupNum, RewardNextQuest, RewardXPDifficulty, RewardXPMultiplier, " +
|
||||
//11 12 13 14 15 16 17 18 19 20 21
|
||||
//0 1 2 3 4 5 6 7 8 9 10 11
|
||||
"ID, QuestType, QuestLevel, MaxScalingLevel, QuestPackageID, MinLevel, QuestSortID, QuestInfoID, SuggestedGroupNum, RewardNextQuest, RewardXPDifficulty, RewardXPMultiplier, " +
|
||||
//12 13 14 15 16 17 18 19 20 21 22
|
||||
"RewardMoney, RewardMoneyDifficulty, RewardMoneyMultiplier, RewardBonusMoney, RewardDisplaySpell1, RewardDisplaySpell2, RewardDisplaySpell3, RewardSpell, RewardHonor, RewardKillHonor, StartItem, " +
|
||||
//22 23 24 25 26
|
||||
//23 24 25 26 27
|
||||
"RewardArtifactXPDifficulty, RewardArtifactXPMultiplier, RewardArtifactCategoryID, Flags, FlagsEx, " +
|
||||
//27 28 29 30 31 32 33 34
|
||||
//28 29 30 31 32 33 34 35
|
||||
"RewardItem1, RewardAmount1, ItemDrop1, ItemDropQuantity1, RewardItem2, RewardAmount2, ItemDrop2, ItemDropQuantity2, " +
|
||||
//35 36 37 38 39 40 41 42
|
||||
//36 37 38 39 40 41 42 43
|
||||
"RewardItem3, RewardAmount3, ItemDrop3, ItemDropQuantity3, RewardItem4, RewardAmount4, ItemDrop4, ItemDropQuantity4, " +
|
||||
//43 44 45 46 47 48
|
||||
//44 45 46 47 48 49
|
||||
"RewardChoiceItemID1, RewardChoiceItemQuantity1, RewardChoiceItemDisplayID1, RewardChoiceItemID2, RewardChoiceItemQuantity2, RewardChoiceItemDisplayID2, " +
|
||||
//49 50 51 52 53 54
|
||||
//50 51 52 53 54 55
|
||||
"RewardChoiceItemID3, RewardChoiceItemQuantity3, RewardChoiceItemDisplayID3, RewardChoiceItemID4, RewardChoiceItemQuantity4, RewardChoiceItemDisplayID4, " +
|
||||
//55 56 57 58 59 60
|
||||
//56 57 58 59 60 61
|
||||
"RewardChoiceItemID5, RewardChoiceItemQuantity5, RewardChoiceItemDisplayID5, RewardChoiceItemID6, RewardChoiceItemQuantity6, RewardChoiceItemDisplayID6, " +
|
||||
//61 62 63 64 65 66 67 68 69 70
|
||||
//62 63 64 65 66 67 68 69 70 71
|
||||
"POIContinent, POIx, POIy, POIPriority, RewardTitle, RewardArenaPoints, RewardSkillLineID, RewardNumSkillUps, PortraitGiver, PortraitTurnIn, " +
|
||||
//71 72 73 74 75 76 77 78
|
||||
//72 73 74 75 76 77 78 79
|
||||
"RewardFactionID1, RewardFactionValue1, RewardFactionOverride1, RewardFactionCapIn1, RewardFactionID2, RewardFactionValue2, RewardFactionOverride2, RewardFactionCapIn2, " +
|
||||
//79 80 81 82 83 84 85 86
|
||||
//80 81 82 83 84 85 86 87
|
||||
"RewardFactionID3, RewardFactionValue3, RewardFactionOverride3, RewardFactionCapIn3, RewardFactionID4, RewardFactionValue4, RewardFactionOverride4, RewardFactionCapIn4, " +
|
||||
//87 88 89 90 91
|
||||
//88 89 90 91 92
|
||||
"RewardFactionID5, RewardFactionValue5, RewardFactionOverride5, RewardFactionCapIn5, RewardFactionFlags, " +
|
||||
//92 93 94 95 96 97 98 99
|
||||
//93 94 95 96 97 98 99 100
|
||||
"RewardCurrencyID1, RewardCurrencyQty1, RewardCurrencyID2, RewardCurrencyQty2, RewardCurrencyID3, RewardCurrencyQty3, RewardCurrencyID4, RewardCurrencyQty4, " +
|
||||
//100 101 102 103 104 105 106
|
||||
//101 102 103 104 105 106 107
|
||||
"AcceptedSoundKitID, CompleteSoundKitID, AreaGroupID, TimeAllowed, AllowableRaces, QuestRewardID, Expansion, " +
|
||||
//107 108 109 110 111 112 113 114 115
|
||||
//108 109 110 111 112 113 114 115 116
|
||||
"LogTitle, LogDescription, QuestDescription, AreaDescription, PortraitGiverText, PortraitGiverName, PortraitTurnInText, PortraitTurnInName, QuestCompletionLog" +
|
||||
" FROM quest_template");
|
||||
|
||||
@@ -6506,7 +6512,7 @@ namespace Game
|
||||
// AllowableRaces, can be -1/RACEMASK_ALL_PLAYABLE to allow any race
|
||||
if (qinfo.AllowableRaces != -1)
|
||||
{
|
||||
if (!Convert.ToBoolean(qinfo.AllowableRaces & (uint)Race.RaceMaskAllPlayable))
|
||||
if (qinfo.AllowableRaces > 0 && !Convert.ToBoolean(qinfo.AllowableRaces & (long)Race.RaceMaskAllPlayable))
|
||||
{
|
||||
Log.outError(LogFilter.Sql, "Quest {0} does not contain any playable races in `RequiredRaces` ({1}), value set to 0 (all races).", qinfo.Id, qinfo.AllowableRaces);
|
||||
qinfo.AllowableRaces = -1;
|
||||
@@ -7137,8 +7143,8 @@ namespace Game
|
||||
|
||||
uint count = 0;
|
||||
|
||||
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13
|
||||
SQLResult result = DB.World.Query("SELECT QuestID, BlobIndex, Idx1, ObjectiveIndex, QuestObjectiveID, QuestObjectID, MapID, WorldMapAreaId, Floor, Priority, Flags, WorldEffectID, PlayerConditionID, WoDUnk1 FROM quest_poi order by QuestID, Idx1");
|
||||
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
||||
SQLResult result = DB.World.Query("SELECT QuestID, BlobIndex, Idx1, ObjectiveIndex, QuestObjectiveID, QuestObjectID, MapID, WorldMapAreaId, Floor, Priority, Flags, WorldEffectID, PlayerConditionID, WoDUnk1, AlwaysAllowMergingBlobs FROM quest_poi order by QuestID, Idx1");
|
||||
if (result.IsEmpty())
|
||||
{
|
||||
Log.outError(LogFilter.ServerLoading, "Loaded 0 quest POI definitions. DB table `quest_poi` is empty.");
|
||||
@@ -7182,11 +7188,12 @@ namespace Game
|
||||
int WorldEffectID = result.Read<int>(11);
|
||||
int PlayerConditionID = result.Read<int>(12);
|
||||
int WoDUnk1 = result.Read<int>(13);
|
||||
bool AlwaysAllowMergingBlobs = result.Read<bool>(14);
|
||||
|
||||
if (Global.ObjectMgr.GetQuestTemplate(QuestID) == null)
|
||||
Log.outError(LogFilter.Sql, "`quest_poi` quest id ({0}) Idx1 ({1}) does not exist in `quest_template`", QuestID, Idx1);
|
||||
|
||||
QuestPOI POI = new QuestPOI(BlobIndex, ObjectiveIndex, QuestObjectiveID, QuestObjectID, MapID, WorldMapAreaId, Floor, Priority, Flags, WorldEffectID, PlayerConditionID, WoDUnk1);
|
||||
QuestPOI POI = new QuestPOI(BlobIndex, ObjectiveIndex, QuestObjectiveID, QuestObjectID, MapID, WorldMapAreaId, Floor, Priority, Flags, WorldEffectID, PlayerConditionID, WoDUnk1, AlwaysAllowMergingBlobs);
|
||||
if (!POIs.ContainsKey(QuestID) || !POIs[QuestID].ContainsKey(Idx1))
|
||||
{
|
||||
Log.outError(LogFilter.Sql, "Table quest_poi references unknown quest points for quest {0} POI id {1}", QuestID, BlobIndex);
|
||||
@@ -8640,7 +8647,7 @@ namespace Game
|
||||
uint oldMSTime = Time.GetMSTime();
|
||||
_playerChoices.Clear();
|
||||
|
||||
SQLResult choiceResult = DB.World.Query("SELECT ChoiceId, Question FROM playerchoice");
|
||||
SQLResult choiceResult = DB.World.Query("SELECT ChoiceId, UiTextureKitId, Question, HideWarboardHeader FROM playerchoice");
|
||||
if (choiceResult.IsEmpty())
|
||||
{
|
||||
Log.outInfo(LogFilter.ServerLoading, "Loaded 0 player choices. DB table `playerchoice` is empty.");
|
||||
@@ -8655,12 +8662,13 @@ namespace Game
|
||||
|
||||
do
|
||||
{
|
||||
int choiceId = choiceResult.Read<int>(0);
|
||||
|
||||
PlayerChoice choice = new PlayerChoice();
|
||||
choice.ChoiceId = choiceId;
|
||||
choice.Question = choiceResult.Read<string>(1);
|
||||
_playerChoices[choiceId] = choice;
|
||||
choice.ChoiceId = choiceResult.Read<int>(0);
|
||||
choice.UiTextureKitId = choiceResult.Read<int>(1);
|
||||
choice.Question = choiceResult.Read<string>(2);
|
||||
choice.HideWarboardHeader = choiceResult.Read<bool>(3);
|
||||
|
||||
_playerChoices[choice.ChoiceId] = choice;
|
||||
|
||||
} while (choiceResult.NextRow());
|
||||
|
||||
@@ -9466,7 +9474,7 @@ namespace Game
|
||||
List<string> _reservedNamesStorage = new List<string>();
|
||||
Dictionary<uint, SceneTemplate> _sceneTemplateStorage = new Dictionary<uint, SceneTemplate>();
|
||||
|
||||
Dictionary<byte, byte> _raceExpansionRequirementStorage = new Dictionary<byte, byte>();
|
||||
Dictionary<byte, RaceUnlockRequirement> _raceUnlockRequirementStorage = new Dictionary<byte, RaceUnlockRequirement>();
|
||||
Dictionary<byte, byte> _classExpansionRequirementStorage = new Dictionary<byte, byte>();
|
||||
Dictionary<uint, string> _realmNameStorage = new Dictionary<uint, string>();
|
||||
|
||||
@@ -9963,7 +9971,7 @@ namespace Game
|
||||
public class QuestPOI
|
||||
{
|
||||
public QuestPOI(int _BlobIndex, int _ObjectiveIndex, int _QuestObjectiveID, int _QuestObjectID, int _MapID, int _WorldMapAreaID, int _Foor, int _Priority, int _Flags,
|
||||
int _WorldEffectID, int _PlayerConditionID, int _UnkWoD1)
|
||||
int _WorldEffectID, int _PlayerConditionID, int _UnkWoD1, bool _AlwaysAllowMergingBlobs)
|
||||
{
|
||||
BlobIndex = _BlobIndex;
|
||||
ObjectiveIndex = _ObjectiveIndex;
|
||||
@@ -9977,6 +9985,7 @@ namespace Game
|
||||
WorldEffectID = _WorldEffectID;
|
||||
PlayerConditionID = _PlayerConditionID;
|
||||
UnkWoD1 = _UnkWoD1;
|
||||
AlwaysAllowMergingBlobs = _AlwaysAllowMergingBlobs;
|
||||
}
|
||||
|
||||
public int BlobIndex;
|
||||
@@ -9992,6 +10001,7 @@ namespace Game
|
||||
public int PlayerConditionID;
|
||||
public int UnkWoD1;
|
||||
public List<QuestPOIPoint> points = new List<QuestPOIPoint>();
|
||||
public bool AlwaysAllowMergingBlobs;
|
||||
}
|
||||
|
||||
public class QuestPOIPoint
|
||||
@@ -10425,7 +10435,15 @@ namespace Game
|
||||
}
|
||||
|
||||
public int ChoiceId;
|
||||
public int UiTextureKitId;
|
||||
public string Question;
|
||||
public List<PlayerChoiceResponse> Responses = new List<PlayerChoiceResponse>();
|
||||
public bool HideWarboardHeader;
|
||||
}
|
||||
|
||||
public class RaceUnlockRequirement
|
||||
{
|
||||
public byte Expansion;
|
||||
public uint AchievementId;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -462,7 +462,7 @@ namespace Game
|
||||
|
||||
reward.ItemID = result.Read<uint>(0);
|
||||
reward.MinGuildRep = result.Read<byte>(1);
|
||||
reward.RaceMask = result.Read<int>(2);
|
||||
reward.RaceMask = result.Read<ulong>(2);
|
||||
reward.Cost = result.Read<ulong>(3);
|
||||
|
||||
if (Global.ObjectMgr.GetItemTemplate(reward.ItemID) == null)
|
||||
@@ -524,7 +524,7 @@ namespace Game
|
||||
{
|
||||
public uint ItemID;
|
||||
public byte MinGuildRep;
|
||||
public int RaceMask;
|
||||
public ulong RaceMask;
|
||||
public ulong Cost;
|
||||
public List<uint> AchievementsRequired = new List<uint>();
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace Game
|
||||
response.SuccessInfo.HasValue = true;
|
||||
|
||||
response.SuccessInfo.Value = new AuthResponse.AuthSuccessInfo();
|
||||
response.SuccessInfo.Value.AccountExpansionLevel = (byte)GetExpansion();
|
||||
response.SuccessInfo.Value.AccountExpansionLevel = (byte)GetAccountExpansion();
|
||||
response.SuccessInfo.Value.ActiveExpansionLevel = (byte)GetExpansion();
|
||||
response.SuccessInfo.Value.VirtualRealmAddress = Global.WorldMgr.GetVirtualRealmAddress();
|
||||
response.SuccessInfo.Value.Time = (uint)Time.UnixTime;
|
||||
@@ -47,7 +47,6 @@ namespace Game
|
||||
response.SuccessInfo.Value.Templates.Add(templ);
|
||||
|
||||
response.SuccessInfo.Value.AvailableClasses = Global.ObjectMgr.GetClassExpansionRequirements();
|
||||
response.SuccessInfo.Value.AvailableRaces = Global.ObjectMgr.GetRaceExpansionRequirements();
|
||||
}
|
||||
|
||||
if (queued)
|
||||
|
||||
@@ -108,15 +108,23 @@ namespace Game
|
||||
else
|
||||
charResult.HasDemonHunterOnRealm = false;
|
||||
|
||||
if (charInfo.Level >= WorldConfig.GetIntValue(WorldCfg.CharacterCreatingMinLevelForDemonHunter) || canAlwaysCreateDemonHunter)
|
||||
charResult.HasLevel70OnRealm = true;
|
||||
charResult.MaxCharacterLevel = Math.Max(charResult.MaxCharacterLevel, charInfo.Level);
|
||||
|
||||
charResult.Characters.Add(charInfo);
|
||||
}
|
||||
while (result.NextRow());
|
||||
}
|
||||
|
||||
charResult.IsDemonHunterCreationAllowed = (!charResult.HasDemonHunterOnRealm && charResult.HasLevel70OnRealm) || canAlwaysCreateDemonHunter;
|
||||
charResult.IsDemonHunterCreationAllowed = GetAccountExpansion() >= Expansion.Legion || canAlwaysCreateDemonHunter;
|
||||
charResult.IsAlliedRacesCreationAllowed = GetAccountExpansion() >= Expansion.BattleForAzeroth;
|
||||
|
||||
foreach (var requirement in Global.ObjectMgr.GetRaceUnlockRequirements())
|
||||
{
|
||||
EnumCharactersResult.RaceUnlock raceUnlock = new EnumCharactersResult.RaceUnlock();
|
||||
raceUnlock.RaceID = requirement.Key;
|
||||
raceUnlock.HasExpansion = (byte)GetAccountExpansion() >= requirement.Value.Expansion;
|
||||
charResult.RaceUnlockData.Add(raceUnlock);
|
||||
}
|
||||
|
||||
SendPacket(charResult);
|
||||
}
|
||||
@@ -212,19 +220,34 @@ namespace Game
|
||||
}
|
||||
|
||||
// prevent character creating Expansion race without Expansion account
|
||||
var raceExpansionRequirement = Global.ObjectMgr.GetRaceExpansionRequirement(charCreate.CreateInfo.RaceId);
|
||||
if (raceExpansionRequirement > GetExpansion())
|
||||
RaceUnlockRequirement raceExpansionRequirement = Global.ObjectMgr.GetRaceUnlockRequirement(charCreate.CreateInfo.RaceId);
|
||||
if (raceExpansionRequirement == null)
|
||||
{
|
||||
Log.outError(LogFilter.Network, "Expansion {0} account:[{1}] tried to Create character with expansion {2} race ({3})", GetExpansion(), GetAccountId(), raceExpansionRequirement, charCreate.CreateInfo.RaceId);
|
||||
Log.outError(LogFilter.Player, "Account {GetAccountId()} tried to create character with unavailable race {charCreate.CreateInfo.RaceId}");
|
||||
SendCharCreate(ResponseCodes.AccountCreateFailed);
|
||||
return;
|
||||
}
|
||||
|
||||
if (raceExpansionRequirement.Expansion > (byte)GetAccountExpansion())
|
||||
{
|
||||
Log.outError(LogFilter.Player, $"Expansion {GetAccountExpansion()} account:[{GetAccountId()}] tried to Create character with expansion {raceExpansionRequirement.Expansion} race ({charCreate.CreateInfo.RaceId})");
|
||||
SendCharCreate(ResponseCodes.CharCreateExpansion);
|
||||
return;
|
||||
}
|
||||
|
||||
//if (raceExpansionRequirement->AchievementId && !)
|
||||
//{
|
||||
// TC_LOG_ERROR("entities.player.cheat", "Expansion %u account:[%d] tried to Create character without achievement %u race (%u)",
|
||||
// GetAccountExpansion(), GetAccountId(), raceExpansionRequirement->AchievementId, charCreate.CreateInfo->Race);
|
||||
// SendCharCreate(CHAR_CREATE_ALLIED_RACE_ACHIEVEMENT);
|
||||
// return;
|
||||
//}
|
||||
|
||||
// prevent character creating Expansion class without Expansion account
|
||||
var classExpansionRequirement = Global.ObjectMgr.GetClassExpansionRequirement(charCreate.CreateInfo.ClassId);
|
||||
if (classExpansionRequirement > GetExpansion())
|
||||
if (classExpansionRequirement > GetAccountExpansion())
|
||||
{
|
||||
Log.outError(LogFilter.Network, "Expansion {0} account:[{1}] tried to Create character with expansion {2} class ({3})", GetExpansion(), GetAccountId(), classExpansionRequirement, charCreate.CreateInfo.ClassId);
|
||||
Log.outError(LogFilter.Network, $"Expansion {GetAccountExpansion()} account:[{GetAccountId()}] tried to Create character with expansion {classExpansionRequirement} class ({charCreate.CreateInfo.ClassId})");
|
||||
SendCharCreate(ResponseCodes.CharCreateExpansionClass);
|
||||
return;
|
||||
}
|
||||
@@ -409,7 +432,7 @@ namespace Game
|
||||
|
||||
if (checkDemonHunterReqs && !hasDemonHunterReqLevel)
|
||||
{
|
||||
SendCharCreate(ResponseCodes.CharCreateFailed);
|
||||
SendCharCreate(ResponseCodes.CharCreateLevelRequirementDemonHunter);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1818,7 +1841,7 @@ namespace Game
|
||||
var questTemplates = Global.ObjectMgr.GetQuestTemplates();
|
||||
foreach (Quest quest in questTemplates.Values)
|
||||
{
|
||||
uint newRaceMask = (uint)(newTeamId == TeamId.Alliance ? Race.RaceMaskAlliance : Race.RaceMaskHorde);
|
||||
long newRaceMask = (long)(newTeamId == TeamId.Alliance ? Race.RaceMaskAlliance : Race.RaceMaskHorde);
|
||||
if (quest.AllowableRaces != -1 && !Convert.ToBoolean(quest.AllowableRaces & newRaceMask))
|
||||
{
|
||||
stmt = DB.Characters.GetPreparedStatement(CharStatements.UPD_CHAR_QUESTSTATUS_REWARDED_ACTIVE_BY_QUEST);
|
||||
|
||||
@@ -396,6 +396,7 @@ namespace Game
|
||||
questPOIBlobData.WorldEffectID = data.WorldEffectID;
|
||||
questPOIBlobData.PlayerConditionID = data.PlayerConditionID;
|
||||
questPOIBlobData.UnkWoD1 = data.UnkWoD1;
|
||||
questPOIBlobData.AlwaysAllowMergingBlobs = data.AlwaysAllowMergingBlobs;
|
||||
|
||||
foreach (var point in data.points)
|
||||
questPOIBlobData.QuestPOIBlobPointStats.Add(new QuestPOIBlobPoint(point.X, point.Y));
|
||||
|
||||
@@ -445,19 +445,20 @@ namespace Game
|
||||
}
|
||||
|
||||
[WorldPacketHandler(ClientOpcodes.SelfRes)]
|
||||
void HandleSelfRes(SelfRes packet)
|
||||
void HandleSelfRes(SelfRes selfRes)
|
||||
{
|
||||
if (_player.HasAuraType(AuraType.PreventResurrection))
|
||||
return; // silent return, client should display error by itself and not send this opcode
|
||||
|
||||
if (_player.GetUInt32Value(PlayerFields.SelfResSpell) != 0)
|
||||
{
|
||||
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(_player.GetUInt32Value(PlayerFields.SelfResSpell));
|
||||
if (spellInfo != null)
|
||||
_player.CastSpell(_player, spellInfo, false, null);
|
||||
var selfResSpells = _player.GetDynamicValues(PlayerDynamicFields.SelfResSpells);
|
||||
if (!selfResSpells.Contains(selfRes.SpellId))
|
||||
return;
|
||||
|
||||
_player.SetUInt32Value(PlayerFields.SelfResSpell, 0);
|
||||
}
|
||||
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(selfRes.SpellId);
|
||||
if (spellInfo != null)
|
||||
_player.CastSpell(_player, spellInfo, false, null);
|
||||
|
||||
_player.RemoveDynamicValue(PlayerDynamicFields.SelfResSpells, selfRes.SpellId);
|
||||
}
|
||||
|
||||
[WorldPacketHandler(ClientOpcodes.SpellClick)]
|
||||
|
||||
@@ -128,7 +128,8 @@ namespace Game
|
||||
if (bag)
|
||||
freeBagSlots += bag.GetFreeSlots();
|
||||
}
|
||||
for (byte i = InventorySlots.ItemStart; i < InventorySlots.ItemEnd; i++)
|
||||
int inventoryEnd = InventorySlots.ItemStart + _player.GetInventorySlotCount();
|
||||
for (byte i = InventorySlots.ItemStart; i < inventoryEnd; i++)
|
||||
{
|
||||
if (!player.GetItemByPos(InventorySlots.Bag0, i))
|
||||
++freeBagSlots;
|
||||
|
||||
@@ -132,18 +132,11 @@ namespace Game.Network.Packets
|
||||
_worldPacket.WriteUInt8(SuccessInfo.Value.ActiveExpansionLevel);
|
||||
_worldPacket.WriteUInt8(SuccessInfo.Value.AccountExpansionLevel);
|
||||
_worldPacket.WriteUInt32(SuccessInfo.Value.TimeSecondsUntilPCKick);
|
||||
_worldPacket.WriteUInt32(SuccessInfo.Value.AvailableRaces.Count);
|
||||
_worldPacket.WriteUInt32(SuccessInfo.Value.AvailableClasses.Count);
|
||||
_worldPacket.WriteUInt32(SuccessInfo.Value.Templates.Count);
|
||||
_worldPacket.WriteUInt32(SuccessInfo.Value.CurrencyID);
|
||||
_worldPacket.WriteUInt32(SuccessInfo.Value.Time);
|
||||
|
||||
foreach (var race in SuccessInfo.Value.AvailableRaces)
|
||||
{
|
||||
_worldPacket.WriteUInt8(race.Key); /// the current race
|
||||
_worldPacket.WriteUInt8(race.Value); /// the required Expansion
|
||||
}
|
||||
|
||||
foreach (var klass in SuccessInfo.Value.AvailableClasses)
|
||||
{
|
||||
_worldPacket.WriteUInt8(klass.Key); /// the current class
|
||||
@@ -219,7 +212,6 @@ namespace Game.Network.Packets
|
||||
public List<CharacterTemplate> Templates = new List<CharacterTemplate>(); // list of pre-made character templates. @todo implement
|
||||
|
||||
public Dictionary<byte, byte> AvailableClasses; // the minimum AccountExpansion required to select the classes
|
||||
public Dictionary<byte, byte> AvailableRaces; // the minimum AccountExpansion required to select the races
|
||||
|
||||
public bool IsExpansionTrial;
|
||||
public bool ForceCharacterTemplate; // forces the client to always use a character template when creating a new character. @see Templates. @todo implement
|
||||
|
||||
@@ -44,79 +44,35 @@ namespace Game.Network.Packets
|
||||
_worldPacket.WriteBit(IsDeletedCharacters);
|
||||
_worldPacket.WriteBit(IsDemonHunterCreationAllowed);
|
||||
_worldPacket.WriteBit(HasDemonHunterOnRealm);
|
||||
_worldPacket.WriteBit(HasLevel70OnRealm);
|
||||
_worldPacket.WriteBit(Unknown7x);
|
||||
_worldPacket.WriteBit(DisabledClassesMask.HasValue);
|
||||
_worldPacket.WriteBit(IsAlliedRacesCreationAllowed);
|
||||
_worldPacket.WriteUInt32(Characters.Count);
|
||||
_worldPacket.WriteUInt32(FactionChangeRestrictions.Count);
|
||||
_worldPacket.WriteInt32(MaxCharacterLevel);
|
||||
_worldPacket.WriteUInt32(RaceUnlockData.Count);
|
||||
|
||||
if (DisabledClassesMask.HasValue)
|
||||
_worldPacket.WriteUInt32(DisabledClassesMask.Value);
|
||||
|
||||
foreach (RestrictedFactionChangeRuleInfo rule in FactionChangeRestrictions)
|
||||
{
|
||||
_worldPacket.WriteUInt32(rule.Mask);
|
||||
_worldPacket.WriteUInt8(rule.Race);
|
||||
}
|
||||
|
||||
foreach (CharacterInfo charInfo in Characters)
|
||||
{
|
||||
_worldPacket.WritePackedGuid(charInfo.Guid);
|
||||
_worldPacket.WriteUInt8(charInfo.ListPosition);
|
||||
_worldPacket.WriteUInt8(charInfo.RaceId);
|
||||
_worldPacket.WriteUInt8(charInfo.ClassId);
|
||||
_worldPacket.WriteUInt8(charInfo.Sex);
|
||||
_worldPacket.WriteUInt8(charInfo.Skin);
|
||||
_worldPacket.WriteUInt8(charInfo.Face);
|
||||
_worldPacket.WriteUInt8(charInfo.HairStyle);
|
||||
_worldPacket.WriteUInt8(charInfo.HairColor);
|
||||
_worldPacket.WriteUInt8(charInfo.FacialHair);
|
||||
charInfo.CustomDisplay.ForEach(id => _worldPacket.WriteUInt8(id));
|
||||
_worldPacket.WriteUInt8(charInfo.Level);
|
||||
_worldPacket.WriteUInt32(charInfo.ZoneId);
|
||||
_worldPacket.WriteUInt32(charInfo.MapId);
|
||||
_worldPacket.WriteVector3(charInfo.PreLoadPosition);
|
||||
_worldPacket.WritePackedGuid(charInfo.GuildGuid);
|
||||
_worldPacket.WriteUInt32(charInfo.Flags);
|
||||
_worldPacket.WriteUInt32(charInfo.CustomizationFlag);
|
||||
_worldPacket.WriteUInt32(charInfo.Flags3);
|
||||
_worldPacket.WriteUInt32(charInfo.Pet.CreatureDisplayId);
|
||||
_worldPacket.WriteUInt32(charInfo.Pet.Level);
|
||||
_worldPacket.WriteUInt32(charInfo.Pet.CreatureFamily);
|
||||
charInfo.Write(_worldPacket);
|
||||
|
||||
_worldPacket.WriteUInt32(charInfo.ProfessionIds[0]);
|
||||
_worldPacket.WriteUInt32(charInfo.ProfessionIds[1]);
|
||||
|
||||
foreach (var visualItem in charInfo.VisualItems)
|
||||
{
|
||||
_worldPacket.WriteUInt32(visualItem.DisplayId);
|
||||
_worldPacket.WriteUInt32(visualItem.DisplayEnchantId);
|
||||
_worldPacket.WriteUInt8(visualItem.InventoryType);
|
||||
}
|
||||
|
||||
_worldPacket.WriteUInt32(charInfo.LastPlayedTime);
|
||||
_worldPacket.WriteUInt16(charInfo.SpecID);
|
||||
_worldPacket.WriteUInt32(charInfo.Unknown703);
|
||||
_worldPacket.WriteUInt32(charInfo.Flags4);
|
||||
_worldPacket.WriteBits(charInfo.Name.GetByteCount(), 6);
|
||||
_worldPacket.WriteBit(charInfo.FirstLogin);
|
||||
_worldPacket.WriteBit(charInfo.BoostInProgress);
|
||||
_worldPacket.WriteBits(charInfo.unkWod61x, 5);
|
||||
_worldPacket.WriteString(charInfo.Name);
|
||||
}
|
||||
foreach (RaceUnlock raceUnlock in RaceUnlockData)
|
||||
raceUnlock.Write(_worldPacket);
|
||||
}
|
||||
|
||||
public bool Success;
|
||||
public bool IsDeletedCharacters; // used for character undelete list
|
||||
public bool IsDemonHunterCreationAllowed = false; ///< used for demon hunter early access
|
||||
public bool HasDemonHunterOnRealm = false;
|
||||
public bool HasLevel70OnRealm = false;
|
||||
public bool Unknown7x = false;
|
||||
public bool IsAlliedRacesCreationAllowed = false;
|
||||
|
||||
public int MaxCharacterLevel = 1;
|
||||
public Optional<uint> DisabledClassesMask = new Optional<uint>();
|
||||
|
||||
public List<CharacterInfo> Characters = new List<CharacterInfo>(); // all characters on the list
|
||||
public List<RestrictedFactionChangeRuleInfo> FactionChangeRestrictions = new List<RestrictedFactionChangeRuleInfo>(); // @todo: research
|
||||
public List<RaceUnlock> RaceUnlockData = new List<RaceUnlock>(); ///<
|
||||
|
||||
public class CharacterInfo
|
||||
{
|
||||
@@ -130,8 +86,8 @@ namespace Game.Network.Packets
|
||||
// "characters.zone, characters.map, characters.position_x, characters.position_y, characters.position_z, "
|
||||
// 19 20 21 22 23 24 25
|
||||
// "guild_member.guildid, characters.playerFlags, characters.at_login, character_pet.entry, character_pet.modelid, character_pet.level, characters.equipmentCache, "
|
||||
// 26 27 28 29 30
|
||||
// "character_banned.guid, characters.slot, characters.logout_time, characters.activeTalentGroup, character_declinedname.genitive"
|
||||
// 26 27 28 29 30 31
|
||||
// "character_banned.guid, characters.slot, characters.logout_time, characters.activeTalentGroup, characters.lastLoginBuild, character_declinedname.genitive"
|
||||
|
||||
Guid = ObjectGuid.Create(HighGuid.Player, fields.Read<ulong>(0));
|
||||
Name = fields.Read<string>(1);
|
||||
@@ -176,7 +132,7 @@ namespace Game.Network.Packets
|
||||
if (fields.Read<uint>(26) != 0)
|
||||
Flags |= CharacterFlags.LockedByBilling;
|
||||
|
||||
if (WorldConfig.GetBoolValue(WorldCfg.DeclinedNamesUsed) && !string.IsNullOrEmpty(fields.Read<string>(30)))
|
||||
if (WorldConfig.GetBoolValue(WorldCfg.DeclinedNamesUsed) && !string.IsNullOrEmpty(fields.Read<string>(31)))
|
||||
Flags |= CharacterFlags.Declined;
|
||||
|
||||
if (atLoginFlags.HasAnyFlag(AtLoginFlags.Customize))
|
||||
@@ -214,6 +170,8 @@ namespace Game.Network.Packets
|
||||
if (spec != null)
|
||||
SpecID = (ushort)spec.Id;
|
||||
|
||||
LastLoginBuild = fields.Read<uint>(30);
|
||||
|
||||
for (byte slot = 0; slot < InventorySlots.BagEnd; ++slot)
|
||||
{
|
||||
VisualItems[slot].InventoryType = (byte)equipment.NextUInt32();
|
||||
@@ -222,6 +180,53 @@ namespace Game.Network.Packets
|
||||
}
|
||||
}
|
||||
|
||||
public void Write(WorldPacket data)
|
||||
{
|
||||
data.WritePackedGuid(Guid);
|
||||
data.WriteUInt8(ListPosition);
|
||||
data.WriteUInt8(RaceId);
|
||||
data.WriteUInt8(ClassId);
|
||||
data.WriteUInt8(Sex);
|
||||
data.WriteUInt8(Skin);
|
||||
data.WriteUInt8(Face);
|
||||
data.WriteUInt8(HairStyle);
|
||||
data.WriteUInt8(HairColor);
|
||||
data.WriteUInt8(FacialHair);
|
||||
|
||||
foreach (var display in CustomDisplay)
|
||||
data.WriteUInt8(display);
|
||||
|
||||
data.WriteUInt8(Level);
|
||||
data.WriteUInt32(ZoneId);
|
||||
data.WriteUInt32(MapId);
|
||||
data.WriteVector3(PreLoadPosition);
|
||||
data.WritePackedGuid(GuildGuid);
|
||||
data.WriteUInt32(Flags);
|
||||
data.WriteUInt32(CustomizationFlag);
|
||||
data.WriteUInt32(Flags3);
|
||||
data.WriteUInt32(Pet.CreatureDisplayId);
|
||||
data.WriteUInt32(Pet.Level);
|
||||
data.WriteUInt32(Pet.CreatureFamily);
|
||||
|
||||
data.WriteUInt32(ProfessionIds[0]);
|
||||
data.WriteUInt32(ProfessionIds[1]);
|
||||
|
||||
foreach (var visualItem in VisualItems)
|
||||
visualItem.Write(data);
|
||||
|
||||
data.WriteUInt32(LastPlayedTime);
|
||||
data.WriteUInt16(SpecID);
|
||||
data.WriteUInt32(Unknown703);
|
||||
data.WriteUInt32(Flags4);
|
||||
data.WriteBits(Name.GetByteCount(), 6);
|
||||
data.WriteBit(FirstLogin);
|
||||
data.WriteBit(BoostInProgress);
|
||||
data.WriteBits(unkWod61x, 5);
|
||||
data.FlushBits();
|
||||
|
||||
data.WriteString(Name);
|
||||
}
|
||||
|
||||
public ObjectGuid Guid;
|
||||
public string Name;
|
||||
public byte ListPosition; // Order of the characters in list
|
||||
@@ -248,6 +253,7 @@ namespace Game.Network.Packets
|
||||
public uint LastPlayedTime;
|
||||
public ushort SpecID;
|
||||
public uint Unknown703;
|
||||
public uint LastLoginBuild;
|
||||
public PetInfo Pet = new PetInfo();
|
||||
public bool BoostInProgress; // @todo
|
||||
public uint[] ProfessionIds = new uint[2]; // @todo
|
||||
@@ -255,6 +261,13 @@ namespace Game.Network.Packets
|
||||
|
||||
public struct VisualItemInfo
|
||||
{
|
||||
public void Write(WorldPacket data)
|
||||
{
|
||||
data.WriteUInt32(DisplayId);
|
||||
data.WriteUInt32(DisplayEnchantId);
|
||||
data.WriteUInt8(InventoryType);
|
||||
}
|
||||
|
||||
public uint DisplayId;
|
||||
public uint DisplayEnchantId;
|
||||
public byte InventoryType;
|
||||
@@ -267,16 +280,21 @@ namespace Game.Network.Packets
|
||||
}
|
||||
}
|
||||
|
||||
public struct RestrictedFactionChangeRuleInfo
|
||||
public struct RaceUnlock
|
||||
{
|
||||
public RestrictedFactionChangeRuleInfo(uint mask, byte race)
|
||||
public void Write(WorldPacket data)
|
||||
{
|
||||
Mask = mask;
|
||||
Race = race;
|
||||
data.WriteInt32(RaceID);
|
||||
data.WriteBit(HasExpansion);
|
||||
data.WriteBit(HasAchievement);
|
||||
data.WriteBit(HasHeritageArmor);
|
||||
data.FlushBits();
|
||||
}
|
||||
|
||||
public uint Mask;
|
||||
public byte Race;
|
||||
public int RaceID;
|
||||
public bool HasExpansion;
|
||||
public bool HasAchievement;
|
||||
public bool HasHeritageArmor;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -832,8 +850,7 @@ namespace Game.Network.Packets
|
||||
_worldPacket.WriteUInt8(Reason);
|
||||
_worldPacket.WriteInt32(Amount);
|
||||
_worldPacket.WriteFloat(GroupBonus);
|
||||
_worldPacket.WriteBit(ReferAFriend);
|
||||
_worldPacket.FlushBits();
|
||||
_worldPacket.WriteUInt8(ReferAFriendBonusType);
|
||||
}
|
||||
|
||||
public ObjectGuid Victim;
|
||||
@@ -841,7 +858,7 @@ namespace Game.Network.Packets
|
||||
public PlayerLogXPReason Reason;
|
||||
public int Amount;
|
||||
public float GroupBonus;
|
||||
public bool ReferAFriend;
|
||||
public byte ReferAFriendBonusType; // 1 - 300% of normal XP; 2 - 150% of normal XP
|
||||
}
|
||||
|
||||
class TitleEarned : ServerPacket
|
||||
|
||||
@@ -1467,7 +1467,7 @@ namespace Game.Network.Packets
|
||||
data.WriteUInt32(ItemID);
|
||||
data.WriteUInt32(Unk4);
|
||||
data.WriteUInt32(AchievementsRequired.Count);
|
||||
data.WriteUInt32(RaceMask);
|
||||
data.WriteUInt64(RaceMask);
|
||||
data.WriteUInt32(MinGuildLevel);
|
||||
data.WriteUInt32(MinGuildRep);
|
||||
data.WriteUInt64(Cost);
|
||||
@@ -1479,7 +1479,7 @@ namespace Game.Network.Packets
|
||||
public uint ItemID;
|
||||
public uint Unk4;
|
||||
public List<uint> AchievementsRequired = new List<uint>();
|
||||
public uint RaceMask;
|
||||
public ulong RaceMask;
|
||||
public int MinGuildLevel;
|
||||
public int MinGuildRep;
|
||||
public ulong Cost;
|
||||
|
||||
@@ -218,12 +218,15 @@ namespace Game.Network.Packets
|
||||
_worldPacket.WriteUInt32(MaxInCombatResCount);
|
||||
_worldPacket.WriteUInt32(CombatResChargeRecovery);
|
||||
_worldPacket.WriteUInt32(NextCombatResChargeTime);
|
||||
_worldPacket.WriteBit(InProgress);
|
||||
_worldPacket.FlushBits();
|
||||
}
|
||||
|
||||
public uint InCombatResCount; // amount of usable battle ressurections
|
||||
public uint MaxInCombatResCount;
|
||||
public uint CombatResChargeRecovery;
|
||||
public uint NextCombatResChargeTime;
|
||||
public bool InProgress = true;
|
||||
}
|
||||
|
||||
class InstanceEncounterEnd : ServerPacket
|
||||
|
||||
@@ -703,6 +703,13 @@ namespace Game.Network.Packets
|
||||
public ObjectGuid ItemGuid { get; set; }
|
||||
}
|
||||
|
||||
class CharacterInventoryOverflowWarning : ServerPacket
|
||||
{
|
||||
public CharacterInventoryOverflowWarning() : base(ServerOpcodes.CharacterInventoryOverflowWarning) { }
|
||||
|
||||
public override void Write() { }
|
||||
}
|
||||
|
||||
//Structs
|
||||
public class ItemBonusInstanceData
|
||||
{
|
||||
|
||||
@@ -76,6 +76,7 @@ namespace Game.Network.Packets
|
||||
_worldPacket.WriteInt32(text.QuestID);
|
||||
_worldPacket.WriteInt32(text.QuestType);
|
||||
_worldPacket.WriteInt32(text.QuestLevel);
|
||||
_worldPacket.WriteInt32(text.QuestMaxScalingLevel);
|
||||
_worldPacket.WriteInt32(text.QuestFlags);
|
||||
_worldPacket.WriteInt32(text.QuestFlagsEx);
|
||||
|
||||
@@ -308,6 +309,7 @@ namespace Game.Network.Packets
|
||||
public int QuestID;
|
||||
public int QuestType;
|
||||
public int QuestLevel;
|
||||
public int QuestMaxScalingLevel;
|
||||
public bool Repeatable;
|
||||
public string QuestTitle;
|
||||
public int QuestFlags;
|
||||
|
||||
@@ -437,6 +437,9 @@ namespace Game.Network.Packets
|
||||
_worldPacket.WriteInt32(questPOIBlobPoint.X);
|
||||
_worldPacket.WriteInt32(questPOIBlobPoint.Y);
|
||||
}
|
||||
|
||||
_worldPacket.WriteBit(questPOIBlobData.AlwaysAllowMergingBlobs);
|
||||
_worldPacket.FlushBits();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -759,6 +762,7 @@ namespace Game.Network.Packets
|
||||
public int PlayerConditionID;
|
||||
public int UnkWoD1;
|
||||
public List<QuestPOIBlobPoint> QuestPOIBlobPointStats = new List<QuestPOIBlobPoint>();
|
||||
public bool AlwaysAllowMergingBlobs;
|
||||
}
|
||||
|
||||
public class QuestPOIData
|
||||
|
||||
@@ -117,6 +117,7 @@ namespace Game.Network.Packets
|
||||
_worldPacket.WriteInt32(Info.QuestID);
|
||||
_worldPacket.WriteInt32(Info.QuestType);
|
||||
_worldPacket.WriteInt32(Info.QuestLevel);
|
||||
_worldPacket.WriteInt32(Info.QuestMaxScalingLevel);
|
||||
_worldPacket.WriteInt32(Info.QuestPackageID);
|
||||
_worldPacket.WriteInt32(Info.QuestMinLevel);
|
||||
_worldPacket.WriteInt32(Info.QuestSortID);
|
||||
@@ -194,7 +195,7 @@ namespace Game.Network.Packets
|
||||
_worldPacket.WriteInt32(Info.TimeAllowed);
|
||||
|
||||
_worldPacket.WriteUInt32(Info.Objectives.Count);
|
||||
_worldPacket.WriteInt32(Info.AllowableRaces);
|
||||
_worldPacket.WriteInt64(Info.AllowableRaces);
|
||||
_worldPacket.WriteInt32(Info.QuestRewardID);
|
||||
_worldPacket.WriteInt32(Info.Expansion);
|
||||
|
||||
@@ -619,6 +620,7 @@ namespace Game.Network.Packets
|
||||
_worldPacket.WriteUInt32(gossip.QuestID);
|
||||
_worldPacket.WriteUInt32(gossip.QuestType);
|
||||
_worldPacket.WriteUInt32(gossip.QuestLevel);
|
||||
_worldPacket.WriteUInt32(gossip.QuestMaxScalingLevel);
|
||||
_worldPacket.WriteUInt32(gossip.QuestFlags);
|
||||
_worldPacket.WriteUInt32(gossip.QuestFlagsEx);
|
||||
|
||||
@@ -827,8 +829,10 @@ namespace Game.Network.Packets
|
||||
_worldPacket.WriteInt32(ChoiceID);
|
||||
_worldPacket.WriteUInt32(Responses.Count);
|
||||
_worldPacket.WritePackedGuid(SenderGUID);
|
||||
_worldPacket.WriteInt32(UiTextureKitID);
|
||||
_worldPacket.WriteBits(Question.GetByteCount(), 8);
|
||||
_worldPacket.WriteBit(CloseChoiceFrame);
|
||||
_worldPacket.WriteBit(HideWarboardHeader);
|
||||
_worldPacket.FlushBits();
|
||||
|
||||
foreach (PlayerChoiceResponse response in Responses)
|
||||
@@ -839,9 +843,11 @@ namespace Game.Network.Packets
|
||||
|
||||
public ObjectGuid SenderGUID;
|
||||
public int ChoiceID;
|
||||
public int UiTextureKitID;
|
||||
public string Question;
|
||||
public List<PlayerChoiceResponse> Responses = new List<PlayerChoiceResponse>();
|
||||
public bool CloseChoiceFrame;
|
||||
public bool HideWarboardHeader;
|
||||
}
|
||||
|
||||
class ChoiceResponse : ClientPacket
|
||||
@@ -897,6 +903,7 @@ namespace Game.Network.Packets
|
||||
public uint QuestID;
|
||||
public int QuestType; // Accepted values: 0, 1 or 2. 0 == IsAutoComplete() (skip objectives/details)
|
||||
public int QuestLevel; // may be -1, static data, in other cases must be used dynamic level: Player.GetQuestLevel (0 is not known, but assuming this is no longer valid for quest intended for client)
|
||||
public int QuestMaxScalingLevel = 255;
|
||||
public uint QuestPackageID;
|
||||
public int QuestMinLevel;
|
||||
public int QuestSortID; // zone or sort to display in quest log
|
||||
@@ -923,7 +930,7 @@ namespace Game.Network.Packets
|
||||
public float POIx;
|
||||
public float POIy;
|
||||
public uint POIPriority;
|
||||
public int AllowableRaces = -1;
|
||||
public long AllowableRaces = -1;
|
||||
public string LogTitle;
|
||||
public string LogDescription;
|
||||
public string QuestDescription;
|
||||
@@ -1129,11 +1136,12 @@ namespace Game.Network.Packets
|
||||
|
||||
public struct GossipText
|
||||
{
|
||||
public GossipText(uint questID, uint questType, uint questLevel, uint questFlags, uint questFlagsEx, bool repeatable, string questTitle)
|
||||
public GossipText(uint questID, uint questType, uint questLevel, uint questMaxScalingLevel, uint questFlags, uint questFlagsEx, bool repeatable, string questTitle)
|
||||
{
|
||||
QuestID = questID;
|
||||
QuestType = questType;
|
||||
QuestLevel = questLevel;
|
||||
QuestMaxScalingLevel = questMaxScalingLevel;
|
||||
QuestFlags = questFlags;
|
||||
QuestFlagsEx = questFlagsEx;
|
||||
Repeatable = repeatable;
|
||||
@@ -1143,6 +1151,7 @@ namespace Game.Network.Packets
|
||||
public uint QuestID;
|
||||
public uint QuestType;
|
||||
public uint QuestLevel;
|
||||
public uint QuestMaxScalingLevel;
|
||||
public uint QuestFlags;
|
||||
public uint QuestFlagsEx;
|
||||
public bool Repeatable;
|
||||
|
||||
@@ -864,7 +864,12 @@ namespace Game.Network.Packets
|
||||
{
|
||||
public SelfRes(WorldPacket packet) : base(packet) { }
|
||||
|
||||
public override void Read() { }
|
||||
public override void Read()
|
||||
{
|
||||
SpellId = _worldPacket.ReadUInt32();
|
||||
}
|
||||
|
||||
public uint SpellId;
|
||||
}
|
||||
|
||||
class GetMirrorImageData : ClientPacket
|
||||
@@ -1236,7 +1241,7 @@ namespace Game.Network.Packets
|
||||
|
||||
public void Write(WorldPacket data)
|
||||
{
|
||||
data.WriteBits(Type, 3);
|
||||
data.WriteBits(Type, 4);
|
||||
data.WriteInt16(PlayerLevelDelta);
|
||||
data.WriteUInt16(PlayerItemLevel);
|
||||
data.WriteUInt8(TargetLevel);
|
||||
|
||||
@@ -315,6 +315,8 @@ namespace Game.Network.Packets
|
||||
LastTitleAuthorGuid = data.ReadPackedGuid();
|
||||
LastDescriptionAuthorGuid = data.ReadPackedGuid();
|
||||
LastVoiceChatAuthorGuid = data.ReadPackedGuid();
|
||||
ListingCreatorGuid = data.ReadPackedGuid();
|
||||
Unknown735 = data.ReadPackedGuid();
|
||||
|
||||
byte titleLength = data.ReadBits<byte>(8);
|
||||
byte descriptionLength = data.ReadBits<byte>(11);
|
||||
@@ -330,6 +332,8 @@ namespace Game.Network.Packets
|
||||
ObjectGuid LastTitleAuthorGuid;
|
||||
ObjectGuid LastDescriptionAuthorGuid;
|
||||
ObjectGuid LastVoiceChatAuthorGuid;
|
||||
ObjectGuid ListingCreatorGuid;
|
||||
ObjectGuid Unknown735;
|
||||
string Title;
|
||||
string Description;
|
||||
string VoiceChat;
|
||||
|
||||
@@ -101,7 +101,7 @@ namespace Game.Network.Packets
|
||||
{
|
||||
MinLevel = data.ReadInt32();
|
||||
MaxLevel = data.ReadInt32();
|
||||
RaceFilter = data.ReadInt32();
|
||||
RaceFilter = data.ReadInt64();
|
||||
ClassFilter = data.ReadInt32();
|
||||
|
||||
uint nameLength = data.ReadBits<uint>(6);
|
||||
@@ -137,7 +137,7 @@ namespace Game.Network.Packets
|
||||
public string VirtualRealmName;
|
||||
public string Guild;
|
||||
public string GuildVirtualRealmName;
|
||||
public int RaceFilter = -1;
|
||||
public long RaceFilter = 0;
|
||||
public int ClassFilter = -1;
|
||||
public List<string> Words = new List<string>();
|
||||
public bool ShowEnemies;
|
||||
|
||||
@@ -36,9 +36,9 @@ namespace Game.Network
|
||||
static byte[] SessionKeySeed = { 0x58, 0xCB, 0xCF, 0x40, 0xFE, 0x2E, 0xCE, 0xA6, 0x5A, 0x90, 0xB8, 0x01, 0x68, 0x6C, 0x28, 0x0B };
|
||||
static byte[] ContinuedSessionSeed = { 0x16, 0xAD, 0x0C, 0xD4, 0x46, 0xF9, 0x4F, 0xB2, 0xEF, 0x7D, 0xEA, 0x2A, 0x17, 0x66, 0x4D, 0x2F };
|
||||
|
||||
static uint[] ClientTypeSeed_Win = { 0xC34F59FE, 0xFF9A7F5E, 0x8A9DD986, 0x97B24A36 };
|
||||
static uint[] ClientTypeSeed_Wn64 = { 0x4E625212, 0xFAD6CBD8, 0x5D3FD3C7, 0xF335A567 };
|
||||
static uint[] ClientTypeSeed_Mc64 = { 0x95EFC66, 0x266170B8, 0x3145F79, 0xD8C1C808 };
|
||||
static byte[] ClientTypeSeed_Win = { 0x23, 0xC5, 0x9C, 0x59, 0x63, 0xCB, 0xEF, 0x5B, 0x72, 0x8D, 0x13, 0xA5, 0x08, 0x78, 0xDF, 0xCB };
|
||||
static byte[] ClientTypeSeed_Wn64 = { 0xC7, 0xFF, 0x93, 0x2D, 0x6A, 0x21, 0x74, 0xA3, 0xD5, 0x38, 0xCA, 0x72, 0x12, 0x13, 0x6D, 0x2B };
|
||||
static byte[] ClientTypeSeed_Mc64 = { 0x21, 0x0B, 0x97, 0x01, 0x49, 0xD6, 0xF5, 0x6C, 0xAC, 0x9B, 0xAD, 0xF2, 0xAA, 0xC9, 0x1E, 0x8E };
|
||||
|
||||
public WorldSocket(Socket socket) : base(socket)
|
||||
{
|
||||
@@ -383,18 +383,15 @@ namespace Game.Network
|
||||
// For hook purposes, we get Remoteaddress at this point.
|
||||
string address = GetRemoteIpAddress().ToString();
|
||||
|
||||
uint[] clientSeed = ClientTypeSeed_Win;
|
||||
byte[] clientSeed = ClientTypeSeed_Win;
|
||||
if (account.game.OS == "Wn64")
|
||||
clientSeed = ClientTypeSeed_Wn64;
|
||||
else if (account.game.OS == "Mc64")
|
||||
clientSeed = ClientTypeSeed_Mc64;
|
||||
|
||||
byte[] byteArray = new byte[clientSeed.Length * 4];
|
||||
Buffer.BlockCopy(clientSeed, 0, byteArray, 0, clientSeed.Length * 4);
|
||||
|
||||
Sha256 digestKeyHash = new Sha256();
|
||||
digestKeyHash.Process(account.game.SessionKey, account.game.SessionKey.Length);
|
||||
digestKeyHash.Finish(byteArray, byteArray.Length);
|
||||
digestKeyHash.Finish(clientSeed, clientSeed.Length);
|
||||
|
||||
HmacSha256 hmac = new HmacSha256(digestKeyHash.Digest);
|
||||
hmac.Process(authSession.LocalChallenge, authSession.LocalChallenge.Count);
|
||||
@@ -744,10 +741,6 @@ namespace Game.Network
|
||||
game.IsBanned = fields.Read<ulong>(13) != 0;
|
||||
game.IsRectuiter = fields.Read<uint>(14) != 0;
|
||||
|
||||
uint world_expansion = WorldConfig.GetUIntValue(WorldCfg.Expansion);
|
||||
if (game.Expansion > world_expansion)
|
||||
game.Expansion = (byte)world_expansion;
|
||||
|
||||
if (battleNet.Locale >= LocaleConstant.Total)
|
||||
battleNet.Locale = LocaleConstant.enUS;
|
||||
}
|
||||
|
||||
@@ -33,14 +33,6 @@ namespace Game.Network
|
||||
// -1 means use default
|
||||
_socketSendBufferSize = ConfigMgr.GetDefaultValue("Network.OutKBuff", -1);
|
||||
|
||||
m_SockOutUBuff = ConfigMgr.GetDefaultValue("Network.OutUBuff", 65536);
|
||||
|
||||
if (m_SockOutUBuff <= 0)
|
||||
{
|
||||
Log.outError(LogFilter.Network, "Network.OutUBuff is wrong in your config file");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!base.StartNetwork(bindIp, port, threadCount))
|
||||
return false;
|
||||
|
||||
@@ -82,7 +74,6 @@ namespace Game.Network
|
||||
|
||||
AsyncAcceptor _instanceAcceptor;
|
||||
int _socketSendBufferSize;
|
||||
int m_SockOutUBuff;
|
||||
bool _tcpNoDelay;
|
||||
}
|
||||
}
|
||||
|
||||
+65
-63
@@ -33,38 +33,39 @@ namespace Game
|
||||
Id = fields.Read<uint>(0);
|
||||
Type = (QuestType)fields.Read<byte>(1);
|
||||
Level = fields.Read<int>(2);
|
||||
PackageID = fields.Read<uint>(3);
|
||||
MinLevel = fields.Read<int>(4);
|
||||
QuestSortID = fields.Read<short>(5);
|
||||
QuestInfoID = fields.Read<ushort>(6);
|
||||
SuggestedPlayers = fields.Read<uint>(7);
|
||||
NextQuestInChain = fields.Read<uint>(8);
|
||||
RewardXPDifficulty = fields.Read<uint>(9);
|
||||
RewardXPMultiplier = fields.Read<float>(10);
|
||||
RewardMoney = fields.Read<int>(11);
|
||||
RewardMoneyDifficulty = fields.Read<uint>(12);
|
||||
RewardMoneyMultiplier = fields.Read<float>(13);
|
||||
RewardBonusMoney = fields.Read<uint>(14);
|
||||
MaxScalingLevel = fields.Read<int>(3);
|
||||
PackageID = fields.Read<uint>(4);
|
||||
MinLevel = fields.Read<int>(5);
|
||||
QuestSortID = fields.Read<short>(6);
|
||||
QuestInfoID = fields.Read<ushort>(7);
|
||||
SuggestedPlayers = fields.Read<uint>(8);
|
||||
NextQuestInChain = fields.Read<uint>(9);
|
||||
RewardXPDifficulty = fields.Read<uint>(10);
|
||||
RewardXPMultiplier = fields.Read<float>(11);
|
||||
RewardMoney = fields.Read<int>(12);
|
||||
RewardMoneyDifficulty = fields.Read<uint>(13);
|
||||
RewardMoneyMultiplier = fields.Read<float>(14);
|
||||
RewardBonusMoney = fields.Read<uint>(15);
|
||||
|
||||
for (int i = 0; i < SharedConst.QuestRewardDisplaySpellCount; ++i)
|
||||
RewardDisplaySpell[i] = fields.Read<uint>(15 + i);
|
||||
RewardDisplaySpell[i] = fields.Read<uint>(16 + i);
|
||||
|
||||
RewardSpell = fields.Read<uint>(18);
|
||||
RewardHonor = fields.Read<uint>(19);
|
||||
RewardKillHonor = fields.Read<uint>(20);
|
||||
SourceItemId = fields.Read<uint>(21);
|
||||
RewardArtifactXPDifficulty = fields.Read<uint>(22);
|
||||
RewardArtifactXPMultiplier = fields.Read<float>(23);
|
||||
RewardArtifactCategoryID = fields.Read<uint>(24);
|
||||
Flags = (QuestFlags)fields.Read<uint>(25);
|
||||
FlagsEx = (QuestFlagsEx)fields.Read<uint>(26);
|
||||
RewardSpell = fields.Read<uint>(19);
|
||||
RewardHonor = fields.Read<uint>(20);
|
||||
RewardKillHonor = fields.Read<uint>(21);
|
||||
SourceItemId = fields.Read<uint>(22);
|
||||
RewardArtifactXPDifficulty = fields.Read<uint>(23);
|
||||
RewardArtifactXPMultiplier = fields.Read<float>(24);
|
||||
RewardArtifactCategoryID = fields.Read<uint>(25);
|
||||
Flags = (QuestFlags)fields.Read<uint>(26);
|
||||
FlagsEx = (QuestFlagsEx)fields.Read<uint>(27);
|
||||
|
||||
for (int i = 0; i < SharedConst.QuestItemDropCount; ++i)
|
||||
{
|
||||
RewardItemId[i] = fields.Read<uint>(27 + i * 4);
|
||||
RewardItemCount[i] = fields.Read<uint>(28 + i * 4);
|
||||
ItemDrop[i] = fields.Read<uint>(29 + i * 4);
|
||||
ItemDropQuantity[i] = fields.Read<uint>(30 + i * 4);
|
||||
RewardItemId[i] = fields.Read<uint>(28 + i * 4);
|
||||
RewardItemCount[i] = fields.Read<uint>(29 + i * 4);
|
||||
ItemDrop[i] = fields.Read<uint>(30 + i * 4);
|
||||
ItemDropQuantity[i] = fields.Read<uint>(31 + i * 4);
|
||||
|
||||
if (RewardItemId[i] != 0)
|
||||
++_rewItemsCount;
|
||||
@@ -72,63 +73,63 @@ namespace Game
|
||||
|
||||
for (int i = 0; i < SharedConst.QuestRewardChoicesCount; ++i)
|
||||
{
|
||||
RewardChoiceItemId[i] = fields.Read<uint>(43 + i * 3);
|
||||
RewardChoiceItemCount[i] = fields.Read<uint>(44 + i * 3);
|
||||
RewardChoiceItemDisplayId[i] = fields.Read<uint>(45 + i * 3);
|
||||
RewardChoiceItemId[i] = fields.Read<uint>(44 + i * 3);
|
||||
RewardChoiceItemCount[i] = fields.Read<uint>(45 + i * 3);
|
||||
RewardChoiceItemDisplayId[i] = fields.Read<uint>(46 + i * 3);
|
||||
|
||||
if (RewardChoiceItemId[i] != 0)
|
||||
++_rewChoiceItemsCount;
|
||||
}
|
||||
|
||||
POIContinent = fields.Read<uint>(61);
|
||||
POIx = fields.Read<float>(62);
|
||||
POIy = fields.Read<float>(63);
|
||||
POIPriority = fields.Read<uint>(64);
|
||||
POIContinent = fields.Read<uint>(62);
|
||||
POIx = fields.Read<float>(63);
|
||||
POIy = fields.Read<float>(64);
|
||||
POIPriority = fields.Read<uint>(65);
|
||||
|
||||
RewardTitleId = fields.Read<uint>(65);
|
||||
RewardArenaPoints = fields.Read<int>(66);
|
||||
RewardSkillId = fields.Read<uint>(67);
|
||||
RewardSkillPoints = fields.Read<uint>(68);
|
||||
RewardTitleId = fields.Read<uint>(66);
|
||||
RewardArenaPoints = fields.Read<int>(67);
|
||||
RewardSkillId = fields.Read<uint>(68);
|
||||
RewardSkillPoints = fields.Read<uint>(69);
|
||||
|
||||
QuestGiverPortrait = fields.Read<uint>(69);
|
||||
QuestTurnInPortrait = fields.Read<uint>(70);
|
||||
QuestGiverPortrait = fields.Read<uint>(70);
|
||||
QuestTurnInPortrait = fields.Read<uint>(71);
|
||||
|
||||
for (int i = 0; i < SharedConst.QuestRewardReputationsCount; ++i)
|
||||
{
|
||||
RewardFactionId[i] = fields.Read<uint>(71 + i * 4);
|
||||
RewardFactionValue[i] = fields.Read<int>(72 + i * 4);
|
||||
RewardFactionOverride[i] = fields.Read<int>(73 + i * 4);
|
||||
RewardFactionCapIn[i] = fields.Read<uint>(74 + i * 4);
|
||||
RewardFactionId[i] = fields.Read<uint>(72 + i * 4);
|
||||
RewardFactionValue[i] = fields.Read<int>(73 + i * 4);
|
||||
RewardFactionOverride[i] = fields.Read<int>(74 + i * 4);
|
||||
RewardFactionCapIn[i] = fields.Read<uint>(75 + i * 4);
|
||||
}
|
||||
|
||||
RewardReputationMask = fields.Read<uint>(91);
|
||||
RewardReputationMask = fields.Read<uint>(92);
|
||||
|
||||
for (int i = 0; i < SharedConst.QuestRewardCurrencyCount; ++i)
|
||||
{
|
||||
RewardCurrencyId[i] = fields.Read<uint>(92 + i * 2);
|
||||
RewardCurrencyCount[i] = fields.Read<uint>(93 + i * 2);
|
||||
RewardCurrencyId[i] = fields.Read<uint>(93 + i * 2);
|
||||
RewardCurrencyCount[i] = fields.Read<uint>(94 + i * 2);
|
||||
|
||||
if (RewardCurrencyId[i] != 0)
|
||||
++_rewCurrencyCount;
|
||||
}
|
||||
|
||||
SoundAccept = fields.Read<uint>(100);
|
||||
SoundTurnIn = fields.Read<uint>(101);
|
||||
AreaGroupID = fields.Read<uint>(102);
|
||||
LimitTime = fields.Read<uint>(103);
|
||||
AllowableRaces = fields.Read<int>(104);
|
||||
QuestRewardID = fields.Read<uint>(105);
|
||||
Expansion = fields.Read<int>(106);
|
||||
SoundAccept = fields.Read<uint>(101);
|
||||
SoundTurnIn = fields.Read<uint>(102);
|
||||
AreaGroupID = fields.Read<uint>(103);
|
||||
LimitTime = fields.Read<uint>(104);
|
||||
AllowableRaces = fields.Read<int>(105);
|
||||
QuestRewardID = fields.Read<uint>(106);
|
||||
Expansion = fields.Read<int>(107);
|
||||
|
||||
LogTitle = fields.Read<string>(107);
|
||||
LogDescription = fields.Read<string>(108);
|
||||
QuestDescription = fields.Read<string>(109);
|
||||
AreaDescription = fields.Read<string>(110);
|
||||
PortraitGiverText = fields.Read<string>(111);
|
||||
PortraitGiverName = fields.Read<string>(112);
|
||||
PortraitTurnInText = fields.Read<string>(113);
|
||||
PortraitTurnInName = fields.Read<string>(114);
|
||||
QuestCompletionLog = fields.Read<string>(115);
|
||||
LogTitle = fields.Read<string>(108);
|
||||
LogDescription = fields.Read<string>(109);
|
||||
QuestDescription = fields.Read<string>(110);
|
||||
AreaDescription = fields.Read<string>(111);
|
||||
PortraitGiverText = fields.Read<string>(112);
|
||||
PortraitGiverName = fields.Read<string>(113);
|
||||
PortraitTurnInText = fields.Read<string>(114);
|
||||
PortraitTurnInName = fields.Read<string>(115);
|
||||
QuestCompletionLog = fields.Read<string>(116);
|
||||
}
|
||||
|
||||
public void LoadQuestDetails(SQLFields fields)
|
||||
@@ -427,6 +428,7 @@ namespace Game
|
||||
public uint Id;
|
||||
public QuestType Type;
|
||||
public int Level;
|
||||
public int MaxScalingLevel;
|
||||
public uint PackageID;
|
||||
public int MinLevel;
|
||||
public int QuestSortID;
|
||||
@@ -477,7 +479,7 @@ namespace Game
|
||||
public uint SoundTurnIn { get; set; }
|
||||
public uint AreaGroupID;
|
||||
public uint LimitTime;
|
||||
public int AllowableRaces { get; set; }
|
||||
public long AllowableRaces { get; set; }
|
||||
public uint QuestRewardID;
|
||||
public int Expansion;
|
||||
public List<QuestObjective> Objectives = new List<QuestObjective>();
|
||||
|
||||
@@ -46,7 +46,8 @@ namespace Game
|
||||
_accountId = id;
|
||||
_accountName = name;
|
||||
_battlenetAccountId = battlenetAccountId;
|
||||
m_expansion = expansion;
|
||||
m_accountExpansion = expansion;
|
||||
m_expansion = (Expansion)Math.Min((byte)expansion, WorldConfig.GetIntValue(WorldCfg.Expansion));
|
||||
_os = os;
|
||||
m_sessionDbcLocale = Global.WorldMgr.GetAvailableDbcLocale(locale);
|
||||
m_sessionDbLocaleIndex = locale;
|
||||
@@ -602,6 +603,7 @@ namespace Game
|
||||
|
||||
public string GetRemoteAddress() { return m_Address; }
|
||||
|
||||
public Expansion GetAccountExpansion() { return m_accountExpansion; }
|
||||
public Expansion GetExpansion() { return m_expansion; }
|
||||
public string GetOS() { return _os; }
|
||||
public void SetInQueue(bool state) { m_inQueue = state; }
|
||||
@@ -820,6 +822,7 @@ namespace Game
|
||||
uint _accountId;
|
||||
string _accountName;
|
||||
uint _battlenetAccountId;
|
||||
Expansion m_accountExpansion;
|
||||
Expansion m_expansion;
|
||||
string _os;
|
||||
|
||||
|
||||
@@ -1484,7 +1484,7 @@ namespace Game.Spells
|
||||
while (chainTargets != 0)
|
||||
{
|
||||
// try to get unit for next chain jump
|
||||
var found = tempTargets.LastOrDefault();
|
||||
WorldObject found = null;
|
||||
// get unit with highest hp deficit in dist
|
||||
if (isChainHeal)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user