Core: Updated to 11.2.0
Port From (https://github.com/TrinityCore/TrinityCore/commit/5cf0c6c8bb2c4e58a2d66ba5f304af34d18a4782)
This commit is contained in:
@@ -774,10 +774,10 @@ namespace Framework.Constants
|
||||
|
||||
CompleteQuestsCountOnAccount = 257, /*NYI*/
|
||||
|
||||
WarbandBankTabPurchased = 260, /*NYI*/
|
||||
BankTabPurchased = 260, // Bank Tab Purchased in {#BankType}
|
||||
ReachRenownLevel = 261,
|
||||
LearnTaxiNode = 262,
|
||||
Count = 264
|
||||
Count = 270
|
||||
}
|
||||
|
||||
public enum CriteriaDataType
|
||||
|
||||
@@ -46,4 +46,28 @@ namespace Framework.Constants
|
||||
HasCircularMovement = 0x400, // DEPRECATED
|
||||
Unk5 = 0x800,
|
||||
}
|
||||
|
||||
public enum AreaTriggerFieldFlags
|
||||
{
|
||||
None = 0x0000,
|
||||
HeightIgnoresScale = 0x0001,
|
||||
WowLabsCircle = 0x0002,
|
||||
CanLoop = 0x0004,
|
||||
AbsoluteOrientation = 0x0008,
|
||||
DynamicShape = 0x0010,
|
||||
Attached = 0x0020,
|
||||
FaceMovementDir = 0x0040,
|
||||
FollowsTerrain = 0x0080,
|
||||
Unknown1025 = 0x0100,
|
||||
AlwaysExterior = 0x0200,
|
||||
HasPlayers = 0x0400,
|
||||
}
|
||||
|
||||
public enum AreaTriggerPathType
|
||||
{
|
||||
Spline = 0,
|
||||
Orbit = 1,
|
||||
None = 2,
|
||||
MovementScript = 3
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,6 +68,8 @@ namespace Framework.Constants
|
||||
ClientModel = 60,
|
||||
CraftingTable = 61,
|
||||
PerksProgramChest = 62,
|
||||
FuturePatch = 63,
|
||||
AssistAction = 64,
|
||||
|
||||
Max
|
||||
}
|
||||
|
||||
@@ -144,20 +144,14 @@ namespace Framework.Constants
|
||||
public const byte ItemStart = 35;
|
||||
public const byte ItemEnd = 63;
|
||||
|
||||
public const byte BankItemStart = 63;
|
||||
public const byte BankItemEnd = 91;
|
||||
public const byte BankBagStart = 63;
|
||||
public const byte BankBagEnd = 69;
|
||||
|
||||
public const byte BankBagStart = 91;
|
||||
public const byte BankBagEnd = 98;
|
||||
public const byte BuyBackStart = 69;
|
||||
public const byte BuyBackEnd = 81;
|
||||
|
||||
public const byte BuyBackStart = 98;
|
||||
public const byte BuyBackEnd = 110;
|
||||
|
||||
public const byte ReagentStart = 110;
|
||||
public const byte ReagentEnd = 208;
|
||||
|
||||
public const byte ChildEquipmentStart = 208;
|
||||
public const byte ChildEquipmentEnd = 211;
|
||||
public const byte ChildEquipmentStart = 81;
|
||||
public const byte ChildEquipmentEnd = 84;
|
||||
|
||||
public const byte Bag0 = 255;
|
||||
public const byte DefaultSize = 16;
|
||||
@@ -165,22 +159,22 @@ namespace Framework.Constants
|
||||
|
||||
enum EquipableSpellSlots
|
||||
{
|
||||
OffensiveSlot1 = 211,
|
||||
OffensiveSlot2 = 212,
|
||||
OffensiveSlot3 = 213,
|
||||
OffensiveSlot4 = 214,
|
||||
UtilitySlot1 = 215,
|
||||
UtilitySlot2 = 216,
|
||||
UtilitySlot3 = 217,
|
||||
UtilitySlot4 = 218,
|
||||
DefensiveSlot1 = 219,
|
||||
DefensiveSlot2 = 220,
|
||||
DefensiveSlot3 = 221,
|
||||
DefensiveSlot4 = 222,
|
||||
WeaponSlot1 = 223,
|
||||
WeaponSlot2 = 224,
|
||||
WeaponSlot3 = 225,
|
||||
WeaponSlot4 = 226,
|
||||
OffensiveSlot1 = 84,
|
||||
OffensiveSlot2 = 85,
|
||||
OffensiveSlot3 = 86,
|
||||
OffensiveSlot4 = 87,
|
||||
UtilitySlot1 = 88,
|
||||
UtilitySlot2 = 89,
|
||||
UtilitySlot3 = 90,
|
||||
UtilitySlot4 = 91,
|
||||
DefensiveSlot1 = 92,
|
||||
DefensiveSlot2 = 93,
|
||||
DefensiveSlot3 = 94,
|
||||
DefensiveSlot4 = 95,
|
||||
WeaponSlot1 = 96,
|
||||
WeaponSlot2 = 97,
|
||||
WeaponSlot3 = 98,
|
||||
WeaponSlot4 = 99,
|
||||
}
|
||||
|
||||
public struct EquipmentSlot
|
||||
@@ -761,7 +755,7 @@ namespace Framework.Constants
|
||||
BnetAccountUntilEquipped = 9,
|
||||
}
|
||||
|
||||
public enum ItemClass : sbyte
|
||||
public enum ItemClass : int
|
||||
{
|
||||
None = -1,
|
||||
Consumable = 0,
|
||||
@@ -1399,6 +1393,8 @@ namespace Framework.Constants
|
||||
BankNotAccessible = 128,// This Character Does Not Have Access To This Bank.
|
||||
CantTradeAccountItem = 129,// You Can't Trade An Item From The Warband Bank.
|
||||
AccountMoneyLocked = 130,// You cannot withdraw or deposit gold from the warband bank currently; please try again later.
|
||||
CharacterBankNotAccessible = 131,// This character does not have access to this bank.
|
||||
CharacterBankNotConverted = 132,// Your character's bank has not been converted. Please try again later.
|
||||
}
|
||||
|
||||
public enum BankType
|
||||
@@ -1531,6 +1527,9 @@ namespace Framework.Constants
|
||||
PriorityJunk = 0x10,
|
||||
PriorityQuestItems = 0x20,
|
||||
ExcludeJunkSell = 0x40,
|
||||
PriorityReagents = 0x80,
|
||||
ExpansionCurrent = 0x100,
|
||||
ExpansionLegacy = 0x200,
|
||||
}
|
||||
|
||||
public enum LootStoreItemType
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -532,7 +532,10 @@ namespace Framework.Constants
|
||||
AccountSecured = 0x1000, // Script_IsAccountSecured
|
||||
OverrideTransportServerTime = 0x8000,
|
||||
MentorRestricted = 0x20000,
|
||||
WeeklyRewardAvailable = 0x40000
|
||||
HasAccountBankLock = 0x40000,
|
||||
CharacterBankDisabled = 0x80000,
|
||||
CharacterBankConversionFailed = 0x100000,
|
||||
AccountBankDisabled = 0x200000,
|
||||
}
|
||||
|
||||
public enum PlayerFieldByte2Flags
|
||||
@@ -592,14 +595,14 @@ namespace Framework.Constants
|
||||
// first slot for item stored (in any way in player items data)
|
||||
Start = 0,
|
||||
// last+1 slot for item stored (in any way in player items data)
|
||||
End = 232,
|
||||
End = 105,
|
||||
Count = (End - Start)
|
||||
}
|
||||
|
||||
enum AccountBankBagSlots
|
||||
public enum AccountBankBagSlots
|
||||
{
|
||||
Start = 227,
|
||||
End = 232
|
||||
Start = 100,
|
||||
End = 105
|
||||
}
|
||||
|
||||
public enum PlayerTitle : ulong
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -651,6 +651,9 @@ namespace Framework.Constants
|
||||
Unk641 = 641,
|
||||
Unk642 = 642,
|
||||
ModRangedAttackSpeedFlat = 643,
|
||||
Unk644 = 644,
|
||||
Unk645 = 645,
|
||||
|
||||
Total
|
||||
}
|
||||
|
||||
|
||||
@@ -2671,6 +2671,10 @@ namespace Framework.Constants
|
||||
UiAction = 339,
|
||||
Unk340 = 340,
|
||||
LearnWarbanScene = 341,
|
||||
Unk342 = 342,
|
||||
Unk343 = 343,
|
||||
Unk344 = 344, // some kind of teleport
|
||||
AssistAction = 345, // MiscValue[0] = AssistActionType, MiscValue[1] = ID, depends on type
|
||||
|
||||
TotalSpellEffects
|
||||
}
|
||||
|
||||
@@ -37,10 +37,10 @@ namespace Framework.Database
|
||||
fileName = @"/sql/base/characters_database.sql";
|
||||
break;
|
||||
case "WorldDatabase":
|
||||
fileName = @"/sql/TDB_full_world_1115.25051_2025_05_31.sql";
|
||||
fileName = @"/sql/TDB_full_world_1117.25071_2025_07_21.sql";
|
||||
break;
|
||||
case "HotfixDatabase":
|
||||
fileName = @"/sql/TDB_full_hotfixes_1115.25051_2025_05_31.sql";
|
||||
fileName = @"/sql/TDB_full_hotfixes_1117.25071_2025_07_21.sql";
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -73,7 +73,7 @@ namespace Framework.Database
|
||||
PrepareStatement(CharStatements.INS_BATTLEGROUND_RANDOM, "INSERT INTO character_battleground_random (guid) VALUES (?)");
|
||||
|
||||
PrepareStatement(CharStatements.SEL_CHARACTER, "SELECT c.guid, account, name, race, class, gender, level, xp, money, inventorySlots, inventoryBagFlags, bagSlotFlags1, bagSlotFlags2, bagSlotFlags3, bagSlotFlags4, bagSlotFlags5, " +
|
||||
"bankSlots, bankBagFlags, bankBagSlotFlags1, bankBagSlotFlags2, bankBagSlotFlags3, bankBagSlotFlags4, bankBagSlotFlags5, bankBagSlotFlags6, bankBagSlotFlags7, restState, playerFlags, playerFlagsEx, " +
|
||||
"bankSlots, bankTabs, bankBagFlags, restState, playerFlags, playerFlagsEx, " +
|
||||
"position_x, position_y, position_z, map, orientation, taximask, createTime, createMode, cinematic, totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, " +
|
||||
"resettalents_time, primarySpecialization, trans_x, trans_y, trans_z, trans_o, transguid, extra_flags, summonedPetNumber, at_login, zone, online, death_expire_time, taxi_path, dungeonDifficulty, " +
|
||||
"totalKills, todayKills, yesterdayKills, chosenTitle, watchedFaction, drunk, " +
|
||||
@@ -451,14 +451,14 @@ namespace Framework.Database
|
||||
|
||||
// Player saving
|
||||
PrepareStatement(CharStatements.INS_CHARACTER, "INSERT INTO characters (guid, account, name, race, class, gender, level, xp, money, inventorySlots, inventoryBagFlags, bagSlotFlags1, bagSlotFlags2, bagSlotFlags3, bagSlotFlags4, bagSlotFlags5, " +
|
||||
"bankSlots, bankBagFlags, bankBagSlotFlags1, bankBagSlotFlags2, bankBagSlotFlags3, bankBagSlotFlags4, bankBagSlotFlags5, bankBagSlotFlags6, bankBagSlotFlags7, restState, playerFlags, playerFlagsEx, " +
|
||||
"bankSlots, bankTabs, bankBagFlags, restState, playerFlags, playerFlagsEx, " +
|
||||
"map, instance_id, dungeonDifficulty, raidDifficulty, legacyRaidDifficulty, position_x, position_y, position_z, orientation, trans_x, trans_y, trans_z, trans_o, transguid, " +
|
||||
"taximask, createTime, createMode, cinematic, totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, resettalents_time, primarySpecialization, " +
|
||||
"extra_flags, summonedPetNumber, at_login, death_expire_time, taxi_path, totalKills, todayKills, yesterdayKills, chosenTitle, watchedFaction, drunk, health, power1, power2, power3, " +
|
||||
"power4, power5, power6, power7, power8, power9, power10, latency, activeTalentGroup, lootSpecId, exploredZones, equipmentCache, knownTitles, actionBars, lastLoginBuild) VALUES " +
|
||||
"(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)");
|
||||
"(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)");
|
||||
PrepareStatement(CharStatements.UPD_CHARACTER, "UPDATE characters SET name=?,race=?,class=?,gender=?,level=?,xp=?,money=?,inventorySlots=?,inventoryBagFlags=?,bagSlotFlags1=?,bagSlotFlags2=?,bagSlotFlags3=?,bagSlotFlags4=?,bagSlotFlags5=?," +
|
||||
"bankSlots=?,bankBagFlags=?,bankBagSlotFlags1=?,bankBagSlotFlags2=?,bankBagSlotFlags3=?,bankBagSlotFlags4=?,bankBagSlotFlags5=?,bankBagSlotFlags6=?,bankBagSlotFlags7=?,restState=?,playerFlags=?,playerFlagsEx=?," +
|
||||
"bankSlots=?,bankTabs=?,bankBagFlags=?,restState=?,playerFlags=?,playerFlagsEx=?," +
|
||||
"map=?,instance_id=?,dungeonDifficulty=?,raidDifficulty=?,legacyRaidDifficulty=?,position_x=?,position_y=?,position_z=?,orientation=?,trans_x=?,trans_y=?,trans_z=?,trans_o=?,transguid=?,taximask=?,cinematic=?,totaltime=?,leveltime=?,rest_bonus=?," +
|
||||
"logout_time=?,is_logout_resting=?,resettalents_cost=?,resettalents_time=?,numRespecs=?,primarySpecialization=?,extra_flags=?,summonedPetNumber=?,at_login=?,zone=?,death_expire_time=?,taxi_path=?," +
|
||||
"totalKills=?,todayKills=?,yesterdayKills=?,chosenTitle=?," +
|
||||
@@ -654,12 +654,6 @@ namespace Framework.Database
|
||||
PrepareStatement(CharStatements.DEL_CHAR_TRAIT_CONFIGS, "DELETE FROM character_trait_config WHERE guid = ? AND traitConfigId = ?");
|
||||
PrepareStatement(CharStatements.DEL_CHAR_TRAIT_CONFIGS_BY_CHAR, "DELETE FROM character_trait_config WHERE guid = ?");
|
||||
|
||||
// Void Storage
|
||||
PrepareStatement(CharStatements.SEL_CHAR_VOID_STORAGE, "SELECT itemId, itemEntry, slot, creatorGuid, randomBonusListId, fixedScalingLevel, artifactKnowledgeLevel, context, bonusListIDs FROM character_void_storage WHERE playerGuid = ?");
|
||||
PrepareStatement(CharStatements.REP_CHAR_VOID_STORAGE_ITEM, "REPLACE INTO character_void_storage (itemId, playerGuid, itemEntry, slot, creatorGuid, randomBonusListId, fixedScalingLevel, artifactKnowledgeLevel, context, bonusListIDs) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
||||
PrepareStatement(CharStatements.DEL_CHAR_VOID_STORAGE_ITEM_BY_CHAR_GUID, "DELETE FROM character_void_storage WHERE playerGuid = ?");
|
||||
PrepareStatement(CharStatements.DEL_CHAR_VOID_STORAGE_ITEM_BY_SLOT, "DELETE FROM character_void_storage WHERE slot = ? AND playerGuid = ?");
|
||||
|
||||
// CompactUnitFrame profiles
|
||||
PrepareStatement(CharStatements.SEL_CHAR_CUF_PROFILES, "SELECT id, name, frameHeight, frameWidth, sortBy, healthText, boolOptions, topPoint, bottomPoint, leftPoint, topOffset, bottomOffset, leftOffset FROM character_cuf_profiles WHERE guid = ?");
|
||||
PrepareStatement(CharStatements.REP_CHAR_CUF_PROFILES, "REPLACE INTO character_cuf_profiles (guid, id, name, frameHeight, frameWidth, sortBy, healthText, boolOptions, topPoint, bottomPoint, leftPoint, topOffset, bottomOffset, leftOffset) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
||||
@@ -769,11 +763,17 @@ namespace Framework.Database
|
||||
PrepareStatement(CharStatements.INS_INSTANCE, "INSERT INTO instance (instanceId, data, completedEncountersMask, entranceWorldSafeLocId) VALUES (?, ?, ?, ?)");
|
||||
|
||||
PrepareStatement(CharStatements.SEL_PLAYER_DATA_ELEMENTS_CHARACTER, "SELECT playerDataElementCharacterId, floatValue, int64Value FROM character_player_data_element WHERE characterGuid = ?");
|
||||
PrepareStatement(CharStatements.DEL_PLAYER_DATA_ELEMENTS_CHARACTER_BY_GUID, "DELETE FROM character_player_data_element WHERE characterGuid = ?");
|
||||
PrepareStatement(CharStatements.DEL_PLAYER_DATA_ELEMENTS_CHARACTER, "DELETE FROM character_player_data_element WHERE characterGuid = ? AND playerDataElementCharacterId = ?");
|
||||
PrepareStatement(CharStatements.INS_PLAYER_DATA_ELEMENTS_CHARACTER, "INSERT INTO character_player_data_element (characterGuid, playerDataElementCharacterId, floatValue, int64Value) VALUES (?, ?, ?, ?)");
|
||||
PrepareStatement(CharStatements.SEL_PLAYER_DATA_FLAGS_CHARACTER, "SELECT storageIndex, mask FROM character_player_data_flag WHERE characterGuid = ?");
|
||||
PrepareStatement(CharStatements.DEL_PLAYER_DATA_FLAGS_CHARACTER_BY_GUID, "DELETE FROM character_player_data_flag WHERE characterGuid = ?");
|
||||
PrepareStatement(CharStatements.DEL_PLAYER_DATA_FLAGS_CHARACTER, "DELETE FROM character_player_data_flag WHERE characterGuid = ? AND storageIndex = ?");
|
||||
PrepareStatement(CharStatements.INS_PLAYER_DATA_FLAGS_CHARACTER, "INSERT INTO character_player_data_flag (characterGuid, storageIndex, mask) VALUES (?, ?, ?)");
|
||||
|
||||
PrepareStatement(CharStatements.SEL_CHARACTER_BANK_TAB_SETTINGS, "SELECT tabId, name, icon, description, depositFlags FROM character_bank_tab_settings WHERE characterGuid = ?");
|
||||
PrepareStatement(CharStatements.DEL_CHARACTER_BANK_TAB_SETTINGS, "DELETE FROM character_bank_tab_settings WHERE characterGuid = ?");
|
||||
PrepareStatement(CharStatements.INS_CHARACTER_BANK_TAB_SETTINGS, "INSERT INTO character_bank_tab_settings (characterGuid, tabId, name, icon, description, depositFlags) VALUES (?, ?, ?, ?, ?, ?)");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1301,11 +1301,6 @@ namespace Framework.Database
|
||||
DEL_CHAR_TRAIT_CONFIGS,
|
||||
DEL_CHAR_TRAIT_CONFIGS_BY_CHAR,
|
||||
|
||||
SEL_CHAR_VOID_STORAGE,
|
||||
REP_CHAR_VOID_STORAGE_ITEM,
|
||||
DEL_CHAR_VOID_STORAGE_ITEM_BY_CHAR_GUID,
|
||||
DEL_CHAR_VOID_STORAGE_ITEM_BY_SLOT,
|
||||
|
||||
SEL_CHAR_CUF_PROFILES,
|
||||
REP_CHAR_CUF_PROFILES,
|
||||
DEL_CHAR_CUF_PROFILES_BY_ID,
|
||||
@@ -1403,12 +1398,18 @@ namespace Framework.Database
|
||||
INS_INSTANCE,
|
||||
|
||||
SEL_PLAYER_DATA_ELEMENTS_CHARACTER,
|
||||
DEL_PLAYER_DATA_ELEMENTS_CHARACTER_BY_GUID,
|
||||
DEL_PLAYER_DATA_ELEMENTS_CHARACTER,
|
||||
INS_PLAYER_DATA_ELEMENTS_CHARACTER,
|
||||
SEL_PLAYER_DATA_FLAGS_CHARACTER,
|
||||
DEL_PLAYER_DATA_FLAGS_CHARACTER_BY_GUID,
|
||||
DEL_PLAYER_DATA_FLAGS_CHARACTER,
|
||||
INS_PLAYER_DATA_FLAGS_CHARACTER,
|
||||
|
||||
SEL_CHARACTER_BANK_TAB_SETTINGS,
|
||||
DEL_CHARACTER_BANK_TAB_SETTINGS,
|
||||
INS_CHARACTER_BANK_TAB_SETTINGS,
|
||||
|
||||
MAX_CHARACTERDATABASE_STATEMENTS
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,8 +164,9 @@ namespace Framework.Database
|
||||
PrepareStatement(HotfixStatements.SEL_AZERITE_UNLOCK_MAPPING, "SELECT ID, ItemLevel, ItemBonusListHead, ItemBonusListShoulders, ItemBonusListChest, " +
|
||||
"AzeriteUnlockMappingSetID FROM azerite_unlock_mapping WHERE (`VerifiedBuild` > 0) = ?");
|
||||
|
||||
// BankBagSlotPrices.db2
|
||||
PrepareStatement(HotfixStatements.SEL_BANK_BAG_SLOT_PRICES, "SELECT ID, Cost FROM bank_bag_slot_prices WHERE (`VerifiedBuild` > 0) = ?");
|
||||
// BankTab.db2
|
||||
PrepareStatement(HotfixStatements.SEL_BANK_TAB, "SELECT ID, Cost, BankType, OrderIndex, PlayerConditionID, PurchasePromptTitle, PurchasePromptBody, " +
|
||||
"PurchasePromptConfirmation, TabCleanupConfirmation, TabNameEditBoxHeader FROM bank_tab WHERE (`VerifiedBuild` > 0) = ?");
|
||||
|
||||
// BannedAddons.db2
|
||||
PrepareStatement(HotfixStatements.SEL_BANNED_ADDONS, "SELECT ID, Name, Version, Flags FROM banned_addons WHERE (`VerifiedBuild` > 0) = ?");
|
||||
@@ -222,8 +223,8 @@ namespace Framework.Database
|
||||
PrepareStatement(HotfixStatements.SEL_CFG_CATEGORIES_LOCALE, "SELECT ID, Name_lang FROM cfg_categories_locale WHERE (`VerifiedBuild` > 0) = ? AND locale = ?");
|
||||
|
||||
// CfgRegions.db2
|
||||
PrepareStatement(HotfixStatements.SEL_CFG_REGIONS, "SELECT ID, Tag, RegionID, Raidorigin, RegionGroupMask, ChallengeOrigin FROM cfg_regions" +
|
||||
" WHERE (`VerifiedBuild` > 0) = ?");
|
||||
PrepareStatement(HotfixStatements.SEL_CFG_REGIONS, "SELECT ID, Tag, RegionID, Raidorigin, RegionGroupMask, ChallengeOrigin, TimeEventRegionGroupID" +
|
||||
" FROM cfg_regions WHERE (`VerifiedBuild` > 0) = ?");
|
||||
|
||||
// ChallengeModeItemBonusOverride.db2
|
||||
PrepareStatement(HotfixStatements.SEL_CHALLENGE_MODE_ITEM_BONUS_OVERRIDE, "SELECT ID, ItemBonusTreeGroupID, DstItemBonusTreeID, Value, " +
|
||||
@@ -259,12 +260,12 @@ namespace Framework.Database
|
||||
// ChrClasses.db2
|
||||
PrepareStatement(HotfixStatements.SEL_CHR_CLASSES, "SELECT Name, Filename, NameMale, NameFemale, PetNameToken, Description, RoleInfoString, DisabledString, " +
|
||||
"HyphenatedNameMale, HyphenatedNameFemale, CreateScreenFileDataID, SelectScreenFileDataID, IconFileDataID, LowResScreenFileDataID, Flags, " +
|
||||
"SpellTextureBlobFileDataID, ArmorTypeMask, CharStartKitUnknown901, MaleCharacterCreationVisualFallback, " +
|
||||
"StartingLevel, SpellTextureBlobFileDataID, ArmorTypeMask, CharStartKitUnknown901, MaleCharacterCreationVisualFallback, " +
|
||||
"MaleCharacterCreationIdleVisualFallback, FemaleCharacterCreationVisualFallback, FemaleCharacterCreationIdleVisualFallback, " +
|
||||
"CharacterCreationIdleGroundVisualFallback, CharacterCreationGroundVisualFallback, AlteredFormCharacterCreationIdleVisualFallback, " +
|
||||
"CharacterCreationAnimLoopWaitTimeMsFallback, CinematicSequenceID, DefaultSpec, ID, PrimaryStatPriority, DisplayPower, " +
|
||||
"RangedAttackPowerPerAgility, AttackPowerPerAgility, AttackPowerPerStrength, SpellClassSet, ClassColorR, ClassColorG, ClassColorB, RolesMask" +
|
||||
" FROM chr_classes WHERE (`VerifiedBuild` > 0) = ?");
|
||||
"CharacterCreationAnimLoopWaitTimeMsFallback, CinematicSequenceID, DefaultSpec, ID, HasStrengthBonus, PrimaryStatPriority, DisplayPower, " +
|
||||
"RangedAttackPowerPerAgility, AttackPowerPerAgility, AttackPowerPerStrength, SpellClassSet, ClassColorR, ClassColorG, ClassColorB, RolesMask, " +
|
||||
"DamageBonusStat, HasRelicSlot FROM chr_classes WHERE (`VerifiedBuild` > 0) = ?");
|
||||
PrepareStatement(HotfixStatements.SEL_CHR_CLASSES_LOCALE, "SELECT ID, Name_lang, NameMale_lang, NameFemale_lang, Description_lang, RoleInfoString_lang, " +
|
||||
"DisabledString_lang, HyphenatedNameMale_lang, HyphenatedNameFemale_lang FROM chr_classes_locale WHERE (`VerifiedBuild` > 0) = ?" +
|
||||
" AND locale = ?");
|
||||
@@ -391,7 +392,7 @@ namespace Framework.Database
|
||||
|
||||
// CreatureFamily.db2
|
||||
PrepareStatement(HotfixStatements.SEL_CREATURE_FAMILY, "SELECT ID, Name, MinScale, MinScaleLevel, MaxScale, MaxScaleLevel, PetFoodMask, PetTalentType, " +
|
||||
"IconFileID, SkillLine1, SkillLine2 FROM creature_family WHERE (`VerifiedBuild` > 0) = ?");
|
||||
"CategoryEnumID, IconFileID, SkillLine1, SkillLine2 FROM creature_family WHERE (`VerifiedBuild` > 0) = ?");
|
||||
PrepareStatement(HotfixStatements.SEL_CREATURE_FAMILY_LOCALE, "SELECT ID, Name_lang FROM creature_family_locale WHERE (`VerifiedBuild` > 0) = ? AND locale = ?");
|
||||
|
||||
// CreatureLabel.db2
|
||||
@@ -482,7 +483,7 @@ namespace Framework.Database
|
||||
|
||||
// ExpectedStat.db2
|
||||
PrepareStatement(HotfixStatements.SEL_EXPECTED_STAT, "SELECT ID, ExpansionID, CreatureHealth, PlayerHealth, CreatureAutoAttackDps, CreatureArmor, " +
|
||||
"PlayerMana, PlayerPrimaryStat, PlayerSecondaryStat, ArmorConstant, CreatureSpellDamage, Lvl FROM expected_stat" +
|
||||
"PlayerMana, PlayerPrimaryStat, PlayerSecondaryStat, ArmorConstant, CreatureSpellDamage, ContentSetID, Lvl FROM expected_stat" +
|
||||
" WHERE (`VerifiedBuild` > 0) = ?");
|
||||
|
||||
// ExpectedStatMod.db2
|
||||
@@ -818,7 +819,7 @@ namespace Framework.Database
|
||||
PrepareStatement(HotfixStatements.SEL_ITEM_SET_LOCALE, "SELECT ID, Name_lang FROM item_set_locale WHERE (`VerifiedBuild` > 0) = ? AND locale = ?");
|
||||
|
||||
// ItemSetSpell.db2
|
||||
PrepareStatement(HotfixStatements.SEL_ITEM_SET_SPELL, "SELECT ID, ChrSpecID, SpellID, Threshold, ItemSetID FROM item_set_spell" +
|
||||
PrepareStatement(HotfixStatements.SEL_ITEM_SET_SPELL, "SELECT ID, ChrSpecID, SpellID, TraitSubTreeID, Threshold, ItemSetID FROM item_set_spell" +
|
||||
" WHERE (`VerifiedBuild` > 0) = ?");
|
||||
|
||||
// ItemSparse.db2
|
||||
@@ -937,7 +938,9 @@ namespace Framework.Database
|
||||
|
||||
// MapChallengeMode.db2
|
||||
PrepareStatement(HotfixStatements.SEL_MAP_CHALLENGE_MODE, "SELECT Name, ID, MapID, Flags, ExpansionLevel, RequiredWorldStateID, CriteriaCount1, " +
|
||||
"CriteriaCount2, CriteriaCount3 FROM map_challenge_mode WHERE (`VerifiedBuild` > 0) = ?");
|
||||
"CriteriaCount2, CriteriaCount3, FirstRewardQuestID1, FirstRewardQuestID2, FirstRewardQuestID3, FirstRewardQuestID4, FirstRewardQuestID5, " +
|
||||
"FirstRewardQuestID6, RewardQuestID1, RewardQuestID2, RewardQuestID3, RewardQuestID4, RewardQuestID5, RewardQuestID6 FROM map_challenge_mode" +
|
||||
" WHERE (`VerifiedBuild` > 0) = ?");
|
||||
PrepareStatement(HotfixStatements.SEL_MAP_CHALLENGE_MODE_LOCALE, "SELECT ID, Name_lang FROM map_challenge_mode_locale WHERE (`VerifiedBuild` > 0) = ?" +
|
||||
" AND locale = ?");
|
||||
|
||||
@@ -1407,8 +1410,9 @@ namespace Framework.Database
|
||||
" FROM spell_visual_effect_name WHERE (`VerifiedBuild` > 0) = ?");
|
||||
|
||||
// SpellVisualKit.db2
|
||||
PrepareStatement(HotfixStatements.SEL_SPELL_VISUAL_KIT, "SELECT ID, ClutterLevel, FallbackSpellVisualKitId, DelayMin, DelayMax, Flags1, Flags2" +
|
||||
" FROM spell_visual_kit WHERE (`VerifiedBuild` > 0) = ?");
|
||||
PrepareStatement(HotfixStatements.SEL_SPELL_VISUAL_KIT, "SELECT ID, ClutterLevel, FallbackSpellVisualKitId, DelayMin, DelayMax, " +
|
||||
"MinimumSpellVisualDensityFilterType, MinimumSpellVisualDensityFilterParam, ReducedSpellVisualDensityFilterType, " +
|
||||
"ReducedSpellVisualDensityFilterParam, Flags1, Flags2 FROM spell_visual_kit WHERE (`VerifiedBuild` > 0) = ?");
|
||||
|
||||
// SpellVisualMissile.db2
|
||||
PrepareStatement(HotfixStatements.SEL_SPELL_VISUAL_MISSILE, "SELECT CastOffset1, CastOffset2, CastOffset3, ImpactOffset1, ImpactOffset2, ImpactOffset3, ID, " +
|
||||
@@ -1648,11 +1652,10 @@ namespace Framework.Database
|
||||
PrepareStatement(HotfixStatements.SEL_VIGNETTE_LOCALE, "SELECT ID, Name_lang FROM vignette_locale WHERE (`VerifiedBuild` > 0) = ? AND locale = ?");
|
||||
|
||||
// WarbandScene.db2
|
||||
PrepareStatement(HotfixStatements.SEL_WARBAND_SCENE, "SELECT Name, Description, Source, PositionX, PositionY, PositionZ, LookAtX, LookAtY, LookAtZ, ID, " +
|
||||
"MapID, Fov, TimeOfDay, Flags, SoundAmbienceID, Quality, TextureKit, DefaultScenePriority, SourceType FROM warband_scene" +
|
||||
" WHERE (`VerifiedBuild` > 0) = ?");
|
||||
PrepareStatement(HotfixStatements.SEL_WARBAND_SCENE_LOCALE, "SELECT ID, Name_lang, Description_lang, Source_lang FROM warband_scene_locale" +
|
||||
" WHERE (`VerifiedBuild` > 0) = ? AND locale = ?");
|
||||
PrepareStatement(HotfixStatements.SEL_WARBAND_SCENE, "SELECT Name, Description, PositionX, PositionY, PositionZ, LookAtX, LookAtY, LookAtZ, ID, MapID, Fov, " +
|
||||
"TimeOfDay, Flags, SoundAmbienceID, Quality, TextureKit, DefaultScenePriority FROM warband_scene WHERE (`VerifiedBuild` > 0) = ?");
|
||||
PrepareStatement(HotfixStatements.SEL_WARBAND_SCENE_LOCALE, "SELECT ID, Name_lang, Description_lang FROM warband_scene_locale WHERE (`VerifiedBuild` > 0) = ?" +
|
||||
" AND locale = ?");
|
||||
|
||||
// WmoAreaTable.db2
|
||||
PrepareStatement(HotfixStatements.SEL_WMO_AREA_TABLE, "SELECT AreaName, ID, WmoID, NameSetID, WmoGroupID, SoundProviderPref, SoundProviderPrefUnderwater, " +
|
||||
@@ -1759,7 +1762,7 @@ namespace Framework.Database
|
||||
|
||||
SEL_AZERITE_UNLOCK_MAPPING,
|
||||
|
||||
SEL_BANK_BAG_SLOT_PRICES,
|
||||
SEL_BANK_TAB,
|
||||
|
||||
SEL_BANNED_ADDONS,
|
||||
|
||||
|
||||
@@ -379,6 +379,19 @@ namespace Game.Achievements
|
||||
case CriteriaType.GuildAttainedLevel:
|
||||
SetCriteriaProgress(criteria, miscValue1, referencePlayer);
|
||||
break;
|
||||
case CriteriaType.BankTabPurchased:
|
||||
switch ((BankType)criteria.Entry.Asset)
|
||||
{
|
||||
case BankType.Character:
|
||||
SetCriteriaProgress(criteria, referencePlayer.GetCharacterBankTabCount(), referencePlayer);
|
||||
break;
|
||||
case BankType.Account:
|
||||
SetCriteriaProgress(criteria, referencePlayer.GetAccountBankTabCount(), referencePlayer);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
// FIXME: not triggered in code as result, need to implement
|
||||
case CriteriaType.RunInstance:
|
||||
case CriteriaType.EarnTeamArenaRating:
|
||||
@@ -825,6 +838,7 @@ namespace Game.Achievements
|
||||
case CriteriaType.SellItemsToVendors:
|
||||
case CriteriaType.GainLevels:
|
||||
case CriteriaType.ReachRenownLevel:
|
||||
case CriteriaType.BankTabPurchased:
|
||||
case CriteriaType.LearnTaxiNode:
|
||||
return progress.Counter >= requiredAmount;
|
||||
case CriteriaType.EarnAchievement:
|
||||
@@ -1246,6 +1260,10 @@ namespace Game.Achievements
|
||||
if (!referencePlayer.IsMaxLevel())
|
||||
return false;
|
||||
break;
|
||||
case CriteriaType.BankTabPurchased:
|
||||
if (miscValue1 != 0 /*allow any at login*/ && miscValue1 != criteria.Entry.Asset)
|
||||
return false;
|
||||
break;
|
||||
case CriteriaType.LearnTaxiNode:
|
||||
if (miscValue1 != criteria.Entry.Asset)
|
||||
return false;
|
||||
@@ -4180,7 +4198,7 @@ namespace Game.Achievements
|
||||
//CriteriaType.MythicPlusRatingAttained, /*NYI*/
|
||||
//CriteriaType.MythicPlusDisplaySeasonEnded, /*NYI*/
|
||||
//CriteriaType.CompleteTrackingQuest, /*NYI*/
|
||||
//CriteriaType.WarbandBankTabPurchased, /*NYI*/
|
||||
CriteriaType.BankTabPurchased,
|
||||
CriteriaType.LearnTaxiNode,
|
||||
CriteriaType.EarnAchievementPoints,
|
||||
CriteriaType.BattlePetAchievementPointsEarned,
|
||||
|
||||
@@ -126,8 +126,6 @@ namespace Game.Chat.Commands
|
||||
itemPos = "[equipped]";
|
||||
else if (Player.IsInventoryPos((byte)itemBag, itemSlot))
|
||||
itemPos = "[in inventory]";
|
||||
else if (Player.IsReagentBankPos((byte)itemBag, itemSlot))
|
||||
itemPos = "[in reagent bank]";
|
||||
else if (Player.IsBankPos((byte)itemBag, itemSlot))
|
||||
itemPos = "[in bank]";
|
||||
else
|
||||
|
||||
@@ -227,7 +227,7 @@ namespace Game.DataStorage
|
||||
}
|
||||
|
||||
// 0 1 2 3 4 5 6 7 8
|
||||
SQLResult circularMovementInfos = DB.World.Query("SELECT AreaTriggerCreatePropertiesId, IsCustom, StartDelay, CircleRadius, BlendFromRadius, InitialAngle, ZOffset, CounterClockwise, CanLoop FROM `areatrigger_create_properties_orbit`");
|
||||
SQLResult circularMovementInfos = DB.World.Query("SELECT AreaTriggerCreatePropertiesId, IsCustom, ExtraTimeForBlending, CircleRadius, BlendFromRadius, InitialAngle, ZOffset, CounterClockwise, CanLoop FROM `areatrigger_create_properties_orbit`");
|
||||
if (!circularMovementInfos.IsEmpty())
|
||||
{
|
||||
do
|
||||
@@ -243,7 +243,7 @@ namespace Game.DataStorage
|
||||
|
||||
AreaTriggerOrbitInfo orbitInfo = new();
|
||||
|
||||
orbitInfo.StartDelay = circularMovementInfos.Read<uint>(2);
|
||||
orbitInfo.ExtraTimeForBlending = circularMovementInfos.Read<int>(2);
|
||||
|
||||
float ValidateAndSetFloat(float value)
|
||||
{
|
||||
|
||||
@@ -83,7 +83,7 @@ namespace Game.DataStorage
|
||||
AzeriteTierUnlockStorage = ReadDB2<AzeriteTierUnlockRecord>("AzeriteTierUnlock.db2", HotfixStatements.SEL_AZERITE_TIER_UNLOCK);
|
||||
AzeriteTierUnlockSetStorage = ReadDB2<AzeriteTierUnlockSetRecord>("AzeriteTierUnlockSet.db2", HotfixStatements.SEL_AZERITE_TIER_UNLOCK_SET);
|
||||
AzeriteUnlockMappingStorage = ReadDB2<AzeriteUnlockMappingRecord>("AzeriteUnlockMapping.db2", HotfixStatements.SEL_AZERITE_UNLOCK_MAPPING);
|
||||
BankBagSlotPricesStorage = ReadDB2<BankBagSlotPricesRecord>("BankBagSlotPrices.db2", HotfixStatements.SEL_BANK_BAG_SLOT_PRICES);
|
||||
BankTabStorage = ReadDB2<BankTabRecord>("BankTab.db2", HotfixStatements.SEL_BANK_TAB);
|
||||
BannedAddOnsStorage = ReadDB2<BannedAddonsRecord>("BannedAddons.db2", HotfixStatements.SEL_BANNED_ADDONS);
|
||||
BarberShopStyleStorage = ReadDB2<BarberShopStyleRecord>("BarberShopStyle.db2", HotfixStatements.SEL_BARBER_SHOP_STYLE, HotfixStatements.SEL_BARBER_SHOP_STYLE_LOCALE);
|
||||
BattlePetBreedQualityStorage = ReadDB2<BattlePetBreedQualityRecord>("BattlePetBreedQuality.db2", HotfixStatements.SEL_BATTLE_PET_BREED_QUALITY);
|
||||
@@ -403,14 +403,16 @@ namespace Game.DataStorage
|
||||
WorldStateExpressionStorage = ReadDB2<WorldStateExpressionRecord>("WorldStateExpression.db2", HotfixStatements.SEL_WORLD_STATE_EXPRESSION);
|
||||
|
||||
// Check loaded DB2 files proper version
|
||||
if (!AreaTableStorage.ContainsKey(16108) || // last area added in 11.0.7 (58162)
|
||||
!CharTitlesStorage.ContainsKey(876) || // last char title added in 11.0.7 (58162)
|
||||
if (!AreaTableStorage.ContainsKey(16579) || // last area added in 11.2.0 (62213)
|
||||
!CharTitlesStorage.ContainsKey(937) || // last char title added in 11.2.0 (62213)
|
||||
!FlightCapabilityStorage.ContainsKey(1) || // default flight capability (required)
|
||||
!GemPropertiesStorage.ContainsKey(4266) || // last gem property added in 11.0.7 (58162)
|
||||
!ItemStorage.ContainsKey(235551) || // last item added in 11.0.7 (58162)
|
||||
!ItemExtendedCostStorage.ContainsKey(9918) || // last item extended cost added in 11.0.7 (58162)
|
||||
!MapStorage.ContainsKey(2829) || // last map added in 11.0.7 (58162)
|
||||
!SpellNameStorage.ContainsKey(1218101)) // last spell added in 11.0.7 (58162)
|
||||
!GemPropertiesStorage.ContainsKey(4287) || // last gem property added in 11.2.0 (62213)
|
||||
!ItemStorage.ContainsKey(252009) || // last item added in 11.2.0 (62213)
|
||||
!ItemSparseStorage.ContainsKey(208392) ||
|
||||
!ItemSparseStorage.ContainsKey(242709) ||
|
||||
!ItemExtendedCostStorage.ContainsKey(10637) || // last item extended cost added in 11.2.0 (62213)
|
||||
!MapStorage.ContainsKey(2951) || // last map added in 11.2.0 (62213)
|
||||
!SpellNameStorage.ContainsKey(1254022)) // last spell added in 11.2.0 (62213)
|
||||
{
|
||||
Log.outFatal(LogFilter.ServerLoading, "You have _outdated_ DB2 files. Please extract correct versions from current using client.");
|
||||
Environment.Exit(1);
|
||||
@@ -487,7 +489,7 @@ namespace Game.DataStorage
|
||||
public static DB6Storage<AzeriteTierUnlockRecord> AzeriteTierUnlockStorage;
|
||||
public static DB6Storage<AzeriteTierUnlockSetRecord> AzeriteTierUnlockSetStorage;
|
||||
public static DB6Storage<AzeriteUnlockMappingRecord> AzeriteUnlockMappingStorage;
|
||||
public static DB6Storage<BankBagSlotPricesRecord> BankBagSlotPricesStorage;
|
||||
public static DB6Storage<BankTabRecord> BankTabStorage;
|
||||
public static DB6Storage<BannedAddonsRecord> BannedAddOnsStorage;
|
||||
public static DB6Storage<BarberShopStyleRecord> BarberShopStyleStorage;
|
||||
public static DB6Storage<BattlePetBreedQualityRecord> BattlePetBreedQualityStorage;
|
||||
|
||||
@@ -84,7 +84,7 @@ namespace Game.DataStorage
|
||||
{
|
||||
public uint Id;
|
||||
public ushort Fallback;
|
||||
public byte BehaviorTier;
|
||||
public sbyte BehaviorTier;
|
||||
public short BehaviorID;
|
||||
public int[] Flags = new int[2];
|
||||
}
|
||||
|
||||
@@ -5,10 +5,18 @@ using Framework.Constants;
|
||||
|
||||
namespace Game.DataStorage
|
||||
{
|
||||
public sealed class BankBagSlotPricesRecord
|
||||
public sealed class BankTabRecord
|
||||
{
|
||||
public uint Id;
|
||||
public uint Cost;
|
||||
public ulong Cost;
|
||||
public byte BankType;
|
||||
public sbyte OrderIndex;
|
||||
public int PlayerConditionID;
|
||||
public int PurchasePromptTitle;
|
||||
public int PurchasePromptBody;
|
||||
public int PurchasePromptConfirmation;
|
||||
public int TabCleanupConfirmation;
|
||||
public int TabNameEditBoxHeader;
|
||||
}
|
||||
|
||||
public sealed class BannedAddonsRecord
|
||||
@@ -16,7 +24,7 @@ namespace Game.DataStorage
|
||||
public uint Id;
|
||||
public string Name;
|
||||
public string Version;
|
||||
public byte Flags;
|
||||
public int Flags;
|
||||
}
|
||||
|
||||
public sealed class BarberShopStyleRecord
|
||||
@@ -63,7 +71,7 @@ namespace Game.DataStorage
|
||||
public int CovenantID;
|
||||
|
||||
public bool HasFlag(BattlePetSpeciesFlags battlePetSpeciesFlags) { return (Flags & (int)battlePetSpeciesFlags) != 0; }
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class BattlePetSpeciesStateRecord
|
||||
{
|
||||
|
||||
@@ -29,6 +29,7 @@ namespace Game.DataStorage
|
||||
public uint Raidorigin; // Date of first raid reset, all other resets are calculated as this date plus interval
|
||||
public byte RegionGroupMask;
|
||||
public uint ChallengeOrigin;
|
||||
public int TimeEventRegionGroupID;
|
||||
}
|
||||
|
||||
public sealed class ChallengeModeItemBonusOverrideRecord
|
||||
@@ -56,7 +57,7 @@ namespace Game.DataStorage
|
||||
public LocalizedString Name;
|
||||
public LocalizedString Name1;
|
||||
public ushort MaskID;
|
||||
public sbyte Flags;
|
||||
public int Flags;
|
||||
}
|
||||
|
||||
public sealed class CharacterLoadoutRecord
|
||||
@@ -115,6 +116,7 @@ namespace Game.DataStorage
|
||||
public uint IconFileDataID;
|
||||
public uint LowResScreenFileDataID;
|
||||
public int Flags;
|
||||
public int StartingLevel;
|
||||
public uint SpellTextureBlobFileDataID;
|
||||
public uint ArmorTypeMask;
|
||||
public int CharStartKitUnknown901;
|
||||
@@ -129,6 +131,7 @@ namespace Game.DataStorage
|
||||
public ushort CinematicSequenceID;
|
||||
public ushort DefaultSpec;
|
||||
public uint Id;
|
||||
public byte HasStrengthBonus;
|
||||
public sbyte PrimaryStatPriority;
|
||||
public PowerType DisplayPower;
|
||||
public byte RangedAttackPowerPerAgility;
|
||||
@@ -139,6 +142,8 @@ namespace Game.DataStorage
|
||||
public byte ClassColorG;
|
||||
public byte ClassColorB;
|
||||
public byte RolesMask;
|
||||
public byte DamageBonusStat;
|
||||
public byte HasRelicSlot;
|
||||
}
|
||||
|
||||
public sealed class ChrClassesXPowerTypesRecord
|
||||
@@ -506,6 +511,7 @@ namespace Game.DataStorage
|
||||
public sbyte MaxScaleLevel;
|
||||
public ushort PetFoodMask;
|
||||
public sbyte PetTalentType;
|
||||
public int CategoryEnumID;
|
||||
public int IconFileID;
|
||||
public short[] SkillLine = new short[2];
|
||||
}
|
||||
|
||||
@@ -47,6 +47,7 @@ namespace Game.DataStorage
|
||||
public float PlayerSecondaryStat;
|
||||
public float ArmorConstant;
|
||||
public float CreatureSpellDamage;
|
||||
public int ContentSetID;
|
||||
public uint Lvl;
|
||||
}
|
||||
|
||||
|
||||
@@ -349,6 +349,7 @@ namespace Game.DataStorage
|
||||
public uint Id;
|
||||
public ushort ChrSpecID;
|
||||
public uint SpellID;
|
||||
public ushort TraitSubTreeID;
|
||||
public byte Threshold;
|
||||
public uint ItemSetID;
|
||||
}
|
||||
|
||||
@@ -87,6 +87,7 @@ namespace Game.DataStorage
|
||||
case 1643:
|
||||
case 2222:
|
||||
case 2444:
|
||||
case 2601:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
@@ -114,10 +115,12 @@ namespace Game.DataStorage
|
||||
public LocalizedString Name;
|
||||
public uint Id;
|
||||
public ushort MapID;
|
||||
public byte Flags;
|
||||
public int Flags;
|
||||
public uint ExpansionLevel;
|
||||
public int RequiredWorldStateID; // maybe?
|
||||
public short[] CriteriaCount = new short[3];
|
||||
public int[] FirstRewardQuestID = new int[6];
|
||||
public int[] RewardQuestID = new int[6];
|
||||
}
|
||||
|
||||
public sealed class MapDifficultyRecord
|
||||
|
||||
@@ -258,8 +258,8 @@ namespace Game.DataStorage
|
||||
public uint Id;
|
||||
public string Name;
|
||||
public int Flags;
|
||||
public byte UsesPerWeek;
|
||||
public byte MaxCharges;
|
||||
public int UsesPerWeek;
|
||||
public int MaxCharges;
|
||||
public int ChargeRecoveryTime;
|
||||
public int TypeMask;
|
||||
|
||||
@@ -346,7 +346,7 @@ namespace Game.DataStorage
|
||||
{
|
||||
public uint Id;
|
||||
public uint SpellID;
|
||||
public sbyte EquippedItemClass;
|
||||
public int EquippedItemClass;
|
||||
public int EquippedItemInvTypes;
|
||||
public int EquippedItemSubclass;
|
||||
}
|
||||
@@ -658,6 +658,10 @@ namespace Game.DataStorage
|
||||
public int FallbackSpellVisualKitId;
|
||||
public ushort DelayMin;
|
||||
public ushort DelayMax;
|
||||
public int MinimumSpellVisualDensityFilterType;
|
||||
public int MinimumSpellVisualDensityFilterParam;
|
||||
public int ReducedSpellVisualDensityFilterType;
|
||||
public int ReducedSpellVisualDensityFilterParam;
|
||||
public int[] Flags = new int[2];
|
||||
}
|
||||
|
||||
|
||||
@@ -109,7 +109,7 @@ namespace Game.DataStorage
|
||||
public float RegenerationPeace;
|
||||
public float RegenerationCombat;
|
||||
public byte BarType;
|
||||
public ushort Flags;
|
||||
public int Flags;
|
||||
public float StartInset;
|
||||
public float EndInset;
|
||||
public uint[] FileDataID = new uint[6];
|
||||
|
||||
@@ -10,7 +10,6 @@ namespace Game.DataStorage
|
||||
{
|
||||
public LocalizedString Name;
|
||||
public LocalizedString Description;
|
||||
public LocalizedString Source;
|
||||
public Vector3 Position;
|
||||
public Vector3 LookAt;
|
||||
public uint Id;
|
||||
@@ -22,7 +21,6 @@ namespace Game.DataStorage
|
||||
public sbyte Quality;
|
||||
public int TextureKit;
|
||||
public int DefaultScenePriority;
|
||||
public sbyte SourceType;
|
||||
|
||||
public WarbandSceneFlags GetFlags() { return (WarbandSceneFlags)Flags; }
|
||||
}
|
||||
|
||||
@@ -26,7 +26,6 @@ namespace Game.Entities
|
||||
ObjectTypeId = TypeId.AreaTrigger;
|
||||
|
||||
m_updateFlag.Stationary = true;
|
||||
m_updateFlag.AreaTrigger = true;
|
||||
|
||||
m_entityFragments.Add(EntityFragment.Tag_AreaTrigger, false);
|
||||
|
||||
@@ -119,7 +118,7 @@ namespace Game.Entities
|
||||
SetObjectScale(1.0f);
|
||||
SetDuration(duration);
|
||||
|
||||
_shape = GetCreateProperties().Shape;
|
||||
SetShape(GetCreateProperties().Shape);
|
||||
|
||||
var areaTriggerData = m_values.ModifyValue(m_areaTriggerData);
|
||||
if (caster != null)
|
||||
@@ -176,6 +175,35 @@ namespace Game.Entities
|
||||
if (GetCreateProperties() != null && GetCreateProperties().Flags.HasFlag(AreaTriggerCreatePropertiesFlag.VisualAnimIsDecay))
|
||||
SetUpdateFieldValue(visualAnim.ModifyValue(visualAnim.IsDecay), true);
|
||||
|
||||
AreaTriggerFieldFlags fieldFlags()
|
||||
{
|
||||
var flags = GetCreateProperties().Flags;
|
||||
AreaTriggerFieldFlags fieldFlags = AreaTriggerFieldFlags.None;
|
||||
if (flags.HasFlag(AreaTriggerCreatePropertiesFlag.HasAbsoluteOrientation))
|
||||
fieldFlags |= AreaTriggerFieldFlags.AbsoluteOrientation;
|
||||
if (flags.HasFlag(AreaTriggerCreatePropertiesFlag.HasDynamicShape))
|
||||
fieldFlags |= AreaTriggerFieldFlags.DynamicShape;
|
||||
if (flags.HasFlag(AreaTriggerCreatePropertiesFlag.HasAttached))
|
||||
fieldFlags |= AreaTriggerFieldFlags.Attached;
|
||||
if (flags.HasFlag(AreaTriggerCreatePropertiesFlag.HasFaceMovementDir))
|
||||
fieldFlags |= AreaTriggerFieldFlags.FaceMovementDir;
|
||||
if (flags.HasFlag(AreaTriggerCreatePropertiesFlag.HasFollowsTerrain))
|
||||
fieldFlags |= AreaTriggerFieldFlags.FollowsTerrain;
|
||||
if (flags.HasFlag(AreaTriggerCreatePropertiesFlag.AlwaysExterior))
|
||||
fieldFlags |= AreaTriggerFieldFlags.AlwaysExterior;
|
||||
return fieldFlags;
|
||||
}
|
||||
;
|
||||
ReplaceAllAreaTriggerFlags(fieldFlags());
|
||||
|
||||
SetUpdateFieldValue(areaTriggerData.ModifyValue(m_areaTriggerData.MovementStartTime), GameTime.GetGameTimeMS());
|
||||
SetUpdateFieldValue(areaTriggerData.ModifyValue(m_areaTriggerData.CreationTime), GameTime.GetGameTimeMS());
|
||||
|
||||
SetUpdateFieldValue(areaTriggerData.ModifyValue(m_areaTriggerData.ScaleCurveId), GetCreateProperties().ScaleCurveId);
|
||||
SetUpdateFieldValue(areaTriggerData.ModifyValue(m_areaTriggerData.FacingCurveId), GetCreateProperties().FacingCurveId);
|
||||
SetUpdateFieldValue(areaTriggerData.ModifyValue(m_areaTriggerData.MorphCurveId), GetCreateProperties().MorphCurveId);
|
||||
SetUpdateFieldValue(areaTriggerData.ModifyValue(m_areaTriggerData.MoveCurveId), GetCreateProperties().MoveCurveId);
|
||||
|
||||
if (caster != null)
|
||||
PhasingHandler.InheritPhaseShift(this, caster);
|
||||
else if (IsStaticSpawn() && spawnData != null)
|
||||
@@ -184,7 +212,7 @@ namespace Game.Entities
|
||||
PhasingHandler.InitDbPhaseShift(GetPhaseShift(), spawnData.PhaseUseFlags, spawnData.PhaseId, spawnData.PhaseGroup);
|
||||
}
|
||||
|
||||
if (target != null && GetCreateProperties() != null && GetCreateProperties().Flags.HasFlag(AreaTriggerCreatePropertiesFlag.HasAttached))
|
||||
if (target != null && HasAreaTriggerFlag(AreaTriggerFieldFlags.Attached))
|
||||
m_movementInfo.transport.guid = target.GetGUID();
|
||||
|
||||
if (!IsStaticSpawn())
|
||||
@@ -195,7 +223,7 @@ namespace Game.Entities
|
||||
if (GetCreateProperties().OrbitInfo != null)
|
||||
{
|
||||
AreaTriggerOrbitInfo orbit = GetCreateProperties().OrbitInfo;
|
||||
if (target != null && GetCreateProperties() != null && GetCreateProperties().Flags.HasFlag(AreaTriggerCreatePropertiesFlag.HasAttached))
|
||||
if (target != null && HasAreaTriggerFlag(AreaTriggerFieldFlags.Attached))
|
||||
orbit.PathTarget = target.GetGUID();
|
||||
else
|
||||
orbit.Center = new(pos.posX, pos.posY, pos.posZ);
|
||||
@@ -206,6 +234,10 @@ namespace Game.Entities
|
||||
{
|
||||
InitSplineOffsets(GetCreateProperties().SplinePoints);
|
||||
}
|
||||
else
|
||||
SetUpdateFieldValue(areaTriggerData.ModifyValue(m_areaTriggerData.ShapeType), (byte)AreaTriggerPathType.None);
|
||||
|
||||
SetUpdateFieldValue(areaTriggerData.ModifyValue(m_areaTriggerData.Facing), _stationaryPosition.GetOrientation());
|
||||
|
||||
// movement on transport of areatriggers on unit is handled by themself
|
||||
ITransport transport = null;
|
||||
@@ -280,7 +312,6 @@ namespace Game.Entities
|
||||
public override void Update(uint diff)
|
||||
{
|
||||
base.Update(diff);
|
||||
_timeSinceCreated += diff;
|
||||
|
||||
if (!IsStaticSpawn())
|
||||
{
|
||||
@@ -291,19 +322,18 @@ namespace Game.Entities
|
||||
}
|
||||
else if (HasOrbit())
|
||||
{
|
||||
UpdateOrbitPosition(diff);
|
||||
UpdateOrbitPosition();
|
||||
}
|
||||
else if (GetCreateProperties() != null && GetCreateProperties().Flags.HasFlag(AreaTriggerCreatePropertiesFlag.HasAttached))
|
||||
else if (HasAreaTriggerFlag(AreaTriggerFieldFlags.Attached))
|
||||
{
|
||||
Unit target = GetTarget();
|
||||
if (target != null)
|
||||
{
|
||||
float orientation = 0.0f;
|
||||
AreaTriggerCreateProperties createProperties = GetCreateProperties();
|
||||
if (createProperties != null && createProperties.FacingCurveId != 0)
|
||||
orientation = Global.DB2Mgr.GetCurveValueAt(createProperties.FacingCurveId, GetProgress());
|
||||
if (m_areaTriggerData.FacingCurveId != 0)
|
||||
orientation = Global.DB2Mgr.GetCurveValueAt(m_areaTriggerData.FacingCurveId, GetProgress());
|
||||
|
||||
if (GetCreateProperties() == null || !GetCreateProperties().Flags.HasFlag(AreaTriggerCreatePropertiesFlag.HasAbsoluteOrientation))
|
||||
if (!HasAreaTriggerFlag(AreaTriggerFieldFlags.AbsoluteOrientation))
|
||||
orientation += target.GetOrientation();
|
||||
|
||||
GetMap().AreaTriggerRelocation(this, target.GetPositionX(), target.GetPositionY(), target.GetPositionZ(), orientation);
|
||||
@@ -311,16 +341,15 @@ namespace Game.Entities
|
||||
}
|
||||
else if (HasSplines())
|
||||
{
|
||||
UpdateSplinePosition(diff);
|
||||
UpdateSplinePosition(_spline);
|
||||
}
|
||||
else
|
||||
{
|
||||
AreaTriggerCreateProperties createProperties = GetCreateProperties();
|
||||
if (createProperties != null && createProperties.FacingCurveId != 0)
|
||||
if (m_areaTriggerData.FacingCurveId != 0)
|
||||
{
|
||||
float orientation = Global.DB2Mgr.GetCurveValueAt(createProperties.FacingCurveId, GetProgress());
|
||||
if (GetCreateProperties() == null || !GetCreateProperties().Flags.HasFlag(AreaTriggerCreatePropertiesFlag.HasAbsoluteOrientation))
|
||||
orientation += _stationaryPosition.GetOrientation();
|
||||
float orientation = Global.DB2Mgr.GetCurveValueAt(m_areaTriggerData.FacingCurveId, GetProgress());
|
||||
if (!HasAreaTriggerFlag(AreaTriggerFieldFlags.AbsoluteOrientation))
|
||||
orientation += m_areaTriggerData.Facing;
|
||||
|
||||
SetOrientation(orientation);
|
||||
}
|
||||
@@ -351,6 +380,14 @@ namespace Game.Entities
|
||||
AddObjectToRemoveList();
|
||||
}
|
||||
|
||||
uint GetTimeSinceCreated()
|
||||
{
|
||||
uint now = GameTime.GetGameTimeMS();
|
||||
if (now >= m_areaTriggerData.CreationTime)
|
||||
return now - m_areaTriggerData.CreationTime;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SetOverrideScaleCurve(float overrideScale)
|
||||
{
|
||||
SetScaleCurve(m_values.ModifyValue(m_areaTriggerData).ModifyValue(m_areaTriggerData.OverrideScaleCurve), overrideScale);
|
||||
@@ -435,12 +472,8 @@ namespace Game.Entities
|
||||
float scale = 1.0f;
|
||||
if (m_areaTriggerData.OverrideScaleCurve.GetValue().OverrideActive)
|
||||
scale *= Math.Max(GetScaleCurveValue(m_areaTriggerData.OverrideScaleCurve, m_areaTriggerData.TimeToTargetScale), 0.000001f);
|
||||
else
|
||||
{
|
||||
AreaTriggerCreateProperties createProperties = GetCreateProperties();
|
||||
if (createProperties != null && createProperties.ScaleCurveId != 0)
|
||||
scale *= Math.Max(Global.DB2Mgr.GetCurveValueAt(createProperties.ScaleCurveId, GetScaleCurveProgress(m_areaTriggerData.OverrideScaleCurve, m_areaTriggerData.TimeToTargetScale)), 0.000001f);
|
||||
}
|
||||
else if (m_areaTriggerData.ScaleCurveId != 0)
|
||||
scale *= Math.Max(Global.DB2Mgr.GetCurveValueAt(m_areaTriggerData.ScaleCurveId, GetScaleCurveProgress(m_areaTriggerData.OverrideScaleCurve, m_areaTriggerData.TimeToTargetScale)), 0.000001f);
|
||||
|
||||
scale *= Math.Max(GetScaleCurveValue(m_areaTriggerData.ExtraScaleCurve, m_areaTriggerData.TimeToTargetExtraScale), 0.000001f);
|
||||
|
||||
@@ -583,29 +616,21 @@ namespace Game.Entities
|
||||
{
|
||||
List<Unit> targetList = new();
|
||||
|
||||
switch (_shape.TriggerType)
|
||||
m_areaTriggerData.ShapeData.Visit(shape =>
|
||||
{
|
||||
case AreaTriggerShapeType.Sphere:
|
||||
SearchUnitInSphere(targetList);
|
||||
break;
|
||||
case AreaTriggerShapeType.Box:
|
||||
SearchUnitInBox(targetList);
|
||||
break;
|
||||
case AreaTriggerShapeType.Polygon:
|
||||
SearchUnitInPolygon(targetList);
|
||||
break;
|
||||
case AreaTriggerShapeType.Cylinder:
|
||||
SearchUnitInCylinder(targetList);
|
||||
break;
|
||||
case AreaTriggerShapeType.Disk:
|
||||
SearchUnitInDisk(targetList);
|
||||
break;
|
||||
case AreaTriggerShapeType.BoundedPlane:
|
||||
SearchUnitInBoundedPlane(targetList);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (shape is AreaTriggerSphere)
|
||||
SearchUnitInSphere(shape, targetList);
|
||||
else if (shape is AreaTriggerBox)
|
||||
SearchUnitInBox(shape, targetList);
|
||||
else if (shape is AreaTriggerPolygon)
|
||||
SearchUnitInPolygon(shape, targetList);
|
||||
else if (shape is AreaTriggerCylinder)
|
||||
SearchUnitInCylinder(shape, targetList);
|
||||
else if (shape is AreaTriggerDisk)
|
||||
SearchUnitInDisk(shape, targetList);
|
||||
else if (shape is AreaTriggerBoundedPlane)
|
||||
SearchUnitInBoundedPlane(shape, targetList);
|
||||
});
|
||||
|
||||
if (GetTemplate() != null)
|
||||
{
|
||||
@@ -681,32 +706,30 @@ namespace Game.Entities
|
||||
}
|
||||
}
|
||||
|
||||
void SearchUnitInSphere(List<Unit> targetList)
|
||||
void SearchUnitInSphere(AreaTriggerSphere sphere, List<Unit> targetList)
|
||||
{
|
||||
float progress = GetProgress();
|
||||
AreaTriggerCreateProperties createProperties = GetCreateProperties();
|
||||
if (createProperties != null && createProperties.MorphCurveId != 0)
|
||||
progress = Global.DB2Mgr.GetCurveValueAt(createProperties.MorphCurveId, progress);
|
||||
if (m_areaTriggerData.MorphCurveId != 0)
|
||||
progress = Global.DB2Mgr.GetCurveValueAt(m_areaTriggerData.MorphCurveId, progress);
|
||||
|
||||
float scale = CalcCurrentScale();
|
||||
float radius = MathFunctions.Lerp(_shape.SphereDatas.Radius, _shape.SphereDatas.RadiusTarget, progress) * scale;
|
||||
float radius = MathFunctions.Lerp(sphere.Radius, sphere.RadiusTarget, progress) * scale;
|
||||
|
||||
SearchUnits(targetList, radius, true);
|
||||
}
|
||||
|
||||
void SearchUnitInBox(List<Unit> targetList)
|
||||
void SearchUnitInBox(AreaTriggerBox box, List<Unit> targetList)
|
||||
{
|
||||
float progress = GetProgress();
|
||||
AreaTriggerCreateProperties createProperties = GetCreateProperties();
|
||||
if (createProperties != null && createProperties.MorphCurveId != 0)
|
||||
progress = Global.DB2Mgr.GetCurveValueAt(createProperties.MorphCurveId, progress);
|
||||
if (m_areaTriggerData.MorphCurveId != 0)
|
||||
progress = Global.DB2Mgr.GetCurveValueAt(m_areaTriggerData.MorphCurveId, progress);
|
||||
|
||||
unsafe
|
||||
{
|
||||
float scale = CalcCurrentScale();
|
||||
float extentsX = MathFunctions.Lerp(_shape.BoxDatas.Extents[0], _shape.BoxDatas.ExtentsTarget[0], progress) * scale;
|
||||
float extentsY = MathFunctions.Lerp(_shape.BoxDatas.Extents[1], _shape.BoxDatas.ExtentsTarget[1], progress) * scale;
|
||||
float extentsZ = MathFunctions.Lerp(_shape.BoxDatas.Extents[2], _shape.BoxDatas.ExtentsTarget[2], progress) * scale;
|
||||
float extentsX = MathFunctions.Lerp(box.Extents.GetValue().X, box.ExtentsTarget.GetValue().X, progress) * scale;
|
||||
float extentsY = MathFunctions.Lerp(box.Extents.GetValue().Y, box.ExtentsTarget.GetValue().Y, progress) * scale;
|
||||
float extentsZ = MathFunctions.Lerp(box.Extents.GetValue().Z, box.ExtentsTarget.GetValue().Z, progress) * scale;
|
||||
float radius = MathF.Sqrt(extentsX * extentsX + extentsY * extentsY);
|
||||
|
||||
SearchUnits(targetList, radius, false);
|
||||
@@ -716,14 +739,13 @@ namespace Game.Entities
|
||||
}
|
||||
}
|
||||
|
||||
void SearchUnitInPolygon(List<Unit> targetList)
|
||||
void SearchUnitInPolygon(AreaTriggerPolygon polygon, List<Unit> targetList)
|
||||
{
|
||||
float progress = GetProgress();
|
||||
AreaTriggerCreateProperties createProperties = GetCreateProperties();
|
||||
if (createProperties != null && createProperties.MorphCurveId != 0)
|
||||
progress = Global.DB2Mgr.GetCurveValueAt(createProperties.MorphCurveId, progress);
|
||||
if (m_areaTriggerData.MorphCurveId != 0)
|
||||
progress = Global.DB2Mgr.GetCurveValueAt(m_areaTriggerData.MorphCurveId, progress);
|
||||
|
||||
float height = MathFunctions.Lerp(_shape.PolygonDatas.Height, _shape.PolygonDatas.HeightTarget, progress);
|
||||
float height = MathFunctions.Lerp(polygon.Height, polygon.HeightTarget, progress);
|
||||
float minZ = GetPositionZ() - height;
|
||||
float maxZ = GetPositionZ() + height;
|
||||
|
||||
@@ -732,17 +754,16 @@ namespace Game.Entities
|
||||
targetList.RemoveAll(unit => unit.GetPositionZ() < minZ || unit.GetPositionZ() > maxZ || !unit.IsInPolygon2D(this, _polygonVertices));
|
||||
}
|
||||
|
||||
void SearchUnitInCylinder(List<Unit> targetList)
|
||||
void SearchUnitInCylinder(AreaTriggerCylinder cylinder, List<Unit> targetList)
|
||||
{
|
||||
float progress = GetProgress();
|
||||
AreaTriggerCreateProperties createProperties = GetCreateProperties();
|
||||
if (createProperties != null && createProperties.MorphCurveId != 0)
|
||||
progress = Global.DB2Mgr.GetCurveValueAt(createProperties.MorphCurveId, progress);
|
||||
if (m_areaTriggerData.MorphCurveId != 0)
|
||||
progress = Global.DB2Mgr.GetCurveValueAt(m_areaTriggerData.MorphCurveId, progress);
|
||||
|
||||
float scale = CalcCurrentScale();
|
||||
float radius = MathFunctions.Lerp(_shape.CylinderDatas.Radius, _shape.CylinderDatas.RadiusTarget, progress) * scale;
|
||||
float height = MathFunctions.Lerp(_shape.CylinderDatas.Height, _shape.CylinderDatas.HeightTarget, progress);
|
||||
if (!m_areaTriggerData.HeightIgnoresScale)
|
||||
float radius = MathFunctions.Lerp(cylinder.Radius, cylinder.RadiusTarget, progress) * scale;
|
||||
float height = MathFunctions.Lerp(cylinder.Height, cylinder.HeightTarget, progress);
|
||||
if (!HasAreaTriggerFlag(AreaTriggerFieldFlags.HeightIgnoresScale))
|
||||
height *= scale;
|
||||
|
||||
float minZ = GetPositionZ() - height;
|
||||
@@ -753,18 +774,17 @@ namespace Game.Entities
|
||||
targetList.RemoveAll(unit => unit.GetPositionZ() < minZ || unit.GetPositionZ() > maxZ);
|
||||
}
|
||||
|
||||
void SearchUnitInDisk(List<Unit> targetList)
|
||||
void SearchUnitInDisk(AreaTriggerDisk disk, List<Unit> targetList)
|
||||
{
|
||||
float progress = GetProgress();
|
||||
AreaTriggerCreateProperties createProperties = GetCreateProperties();
|
||||
if (createProperties != null && createProperties.MorphCurveId != 0)
|
||||
progress = Global.DB2Mgr.GetCurveValueAt(createProperties.MorphCurveId, progress);
|
||||
if (m_areaTriggerData.MorphCurveId != 0)
|
||||
progress = Global.DB2Mgr.GetCurveValueAt(m_areaTriggerData.MorphCurveId, progress);
|
||||
|
||||
float scale = CalcCurrentScale();
|
||||
float innerRadius = MathFunctions.Lerp(_shape.DiskDatas.InnerRadius, _shape.DiskDatas.InnerRadiusTarget, progress) * scale;
|
||||
float outerRadius = MathFunctions.Lerp(_shape.DiskDatas.OuterRadius, _shape.DiskDatas.OuterRadiusTarget, progress) * scale;
|
||||
float height = MathFunctions.Lerp(_shape.DiskDatas.Height, _shape.DiskDatas.HeightTarget, progress);
|
||||
if (!m_areaTriggerData.HeightIgnoresScale)
|
||||
float innerRadius = MathFunctions.Lerp(disk.InnerRadius, disk.InnerRadiusTarget, progress) * scale;
|
||||
float outerRadius = MathFunctions.Lerp(disk.OuterRadius, disk.OuterRadiusTarget, progress) * scale;
|
||||
float height = MathFunctions.Lerp(disk.Height, disk.HeightTarget, progress);
|
||||
if (!HasAreaTriggerFlag(AreaTriggerFieldFlags.HeightIgnoresScale))
|
||||
height *= scale;
|
||||
|
||||
float minZ = GetPositionZ() - height;
|
||||
@@ -775,18 +795,17 @@ namespace Game.Entities
|
||||
targetList.RemoveAll(unit => unit.IsInDist2d(this, innerRadius) || unit.GetPositionZ() < minZ || unit.GetPositionZ() > maxZ);
|
||||
}
|
||||
|
||||
void SearchUnitInBoundedPlane(List<Unit> targetList)
|
||||
void SearchUnitInBoundedPlane(AreaTriggerBoundedPlane boundedPlane, List<Unit> targetList)
|
||||
{
|
||||
float progress = GetProgress();
|
||||
AreaTriggerCreateProperties createProperties = GetCreateProperties();
|
||||
if (createProperties != null && createProperties.MorphCurveId != 0)
|
||||
progress = Global.DB2Mgr.GetCurveValueAt(createProperties.MorphCurveId, progress);
|
||||
if (m_areaTriggerData.MorphCurveId != 0)
|
||||
progress = Global.DB2Mgr.GetCurveValueAt(m_areaTriggerData.MorphCurveId, progress);
|
||||
|
||||
unsafe
|
||||
{
|
||||
float scale = CalcCurrentScale();
|
||||
float extentsX = MathFunctions.Lerp(_shape.BoundedPlaneDatas.Extents[0], _shape.BoundedPlaneDatas.ExtentsTarget[0], progress) * scale;
|
||||
float extentsY = MathFunctions.Lerp(_shape.BoundedPlaneDatas.Extents[1], _shape.BoundedPlaneDatas.ExtentsTarget[1], progress) * scale;
|
||||
float extentsX = MathFunctions.Lerp(boundedPlane.Extents.GetValue().X, boundedPlane.ExtentsTarget.GetValue().X, progress) * scale;
|
||||
float extentsY = MathFunctions.Lerp(boundedPlane.Extents.GetValue().Y, boundedPlane.ExtentsTarget.GetValue().Y, progress) * scale;
|
||||
float radius = MathF.Sqrt(extentsX * extentsX + extentsY * extentsY);
|
||||
|
||||
SearchUnits(targetList, radius, false);
|
||||
@@ -854,8 +873,10 @@ namespace Game.Entities
|
||||
}
|
||||
}
|
||||
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_areaTriggerData).ModifyValue(m_areaTriggerData.NumUnitsInside), _insideUnits.Count);
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_areaTriggerData).ModifyValue(m_areaTriggerData.NumPlayersInside), _insideUnits.Count(guid => guid.IsPlayer()));
|
||||
if (_insideUnits.Any(guid => guid.IsPlayer()))
|
||||
SetAreaTriggerFlag(AreaTriggerFieldFlags.HasPlayers);
|
||||
else
|
||||
RemoveAreaTriggerFlag(AreaTriggerFieldFlags.HasPlayers);
|
||||
|
||||
if (IsStaticSpawn())
|
||||
SetActive(!_insideUnits.Empty());
|
||||
@@ -902,6 +923,83 @@ namespace Game.Entities
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsafe void SetShape(AreaTriggerShapeInfo shape)
|
||||
{
|
||||
var areaTriggerData = m_values.ModifyValue(m_areaTriggerData);
|
||||
|
||||
switch (shape.TriggerType)
|
||||
{
|
||||
case AreaTriggerShapeType.Sphere:
|
||||
{
|
||||
SetUpdateFieldValue(areaTriggerData.ModifyValue(m_areaTriggerData.ShapeType), (byte)0);
|
||||
var sphere = areaTriggerData.ModifyValue<AreaTriggerSphere>(m_areaTriggerData.ShapeData);
|
||||
SetUpdateFieldValue(sphere.ModifyValue(sphere.Radius), shape.SphereDatas.Radius);
|
||||
SetUpdateFieldValue(sphere.ModifyValue(sphere.RadiusTarget), shape.SphereDatas.RadiusTarget);
|
||||
break;
|
||||
}
|
||||
case AreaTriggerShapeType.Box:
|
||||
{
|
||||
SetUpdateFieldValue(areaTriggerData.ModifyValue(m_areaTriggerData.ShapeType), (byte)1);
|
||||
var box = areaTriggerData.ModifyValue<AreaTriggerBox>(m_areaTriggerData.ShapeData);
|
||||
SetUpdateFieldValue(box.ModifyValue(box.Extents), new Vector3(shape.BoxDatas.Extents[0], shape.BoxDatas.Extents[1], shape.BoxDatas.Extents[2]));
|
||||
SetUpdateFieldValue(box.ModifyValue(box.ExtentsTarget), new Vector3(shape.BoxDatas.ExtentsTarget[0], shape.BoxDatas.ExtentsTarget[1], shape.BoxDatas.ExtentsTarget[2]));
|
||||
break;
|
||||
}
|
||||
case AreaTriggerShapeType.Polygon:
|
||||
{
|
||||
SetUpdateFieldValue(areaTriggerData.ModifyValue(m_areaTriggerData.ShapeType), (byte)3);
|
||||
var polygon = areaTriggerData.ModifyValue<AreaTriggerPolygon>(m_areaTriggerData.ShapeData);
|
||||
var vertices = polygon.ModifyValue(polygon.Vertices);
|
||||
ClearDynamicUpdateFieldValues(vertices);
|
||||
foreach (Vector2 vertex in shape.PolygonVertices)
|
||||
AddDynamicUpdateFieldValue(vertices, vertex);
|
||||
var verticesTarget = polygon.ModifyValue(polygon.VerticesTarget);
|
||||
ClearDynamicUpdateFieldValues(verticesTarget);
|
||||
foreach (Vector2 vertex in shape.PolygonVerticesTarget)
|
||||
AddDynamicUpdateFieldValue(verticesTarget, vertex);
|
||||
SetUpdateFieldValue(polygon.ModifyValue(polygon.Height), shape.PolygonDatas.Height);
|
||||
SetUpdateFieldValue(polygon.ModifyValue(polygon.HeightTarget), shape.PolygonDatas.HeightTarget);
|
||||
break;
|
||||
}
|
||||
case AreaTriggerShapeType.Cylinder:
|
||||
{
|
||||
SetUpdateFieldValue(areaTriggerData.ModifyValue(m_areaTriggerData.ShapeType), (byte)4);
|
||||
var cylinder = areaTriggerData.ModifyValue<AreaTriggerCylinder>(m_areaTriggerData.ShapeData);
|
||||
SetUpdateFieldValue(cylinder.ModifyValue(cylinder.Radius), shape.CylinderDatas.Radius);
|
||||
SetUpdateFieldValue(cylinder.ModifyValue(cylinder.RadiusTarget), shape.CylinderDatas.RadiusTarget);
|
||||
SetUpdateFieldValue(cylinder.ModifyValue(cylinder.Height), shape.CylinderDatas.Height);
|
||||
SetUpdateFieldValue(cylinder.ModifyValue(cylinder.HeightTarget), shape.CylinderDatas.HeightTarget);
|
||||
SetUpdateFieldValue(cylinder.ModifyValue(cylinder.LocationZOffset), shape.CylinderDatas.LocationZOffset);
|
||||
SetUpdateFieldValue(cylinder.ModifyValue(cylinder.LocationZOffsetTarget), shape.CylinderDatas.LocationZOffsetTarget);
|
||||
break;
|
||||
}
|
||||
case AreaTriggerShapeType.Disk:
|
||||
{
|
||||
SetUpdateFieldValue(areaTriggerData.ModifyValue(m_areaTriggerData.ShapeType), (byte)7);
|
||||
var disk = areaTriggerData.ModifyValue<AreaTriggerDisk>(m_areaTriggerData.ShapeData);
|
||||
SetUpdateFieldValue(disk.ModifyValue(disk.InnerRadius), shape.DiskDatas.InnerRadius);
|
||||
SetUpdateFieldValue(disk.ModifyValue(disk.InnerRadiusTarget), shape.DiskDatas.InnerRadiusTarget);
|
||||
SetUpdateFieldValue(disk.ModifyValue(disk.OuterRadius), shape.DiskDatas.OuterRadius);
|
||||
SetUpdateFieldValue(disk.ModifyValue(disk.OuterRadiusTarget), shape.DiskDatas.OuterRadiusTarget);
|
||||
SetUpdateFieldValue(disk.ModifyValue(disk.Height), shape.DiskDatas.Height);
|
||||
SetUpdateFieldValue(disk.ModifyValue(disk.HeightTarget), shape.DiskDatas.HeightTarget);
|
||||
SetUpdateFieldValue(disk.ModifyValue(disk.LocationZOffset), shape.DiskDatas.LocationZOffset);
|
||||
SetUpdateFieldValue(disk.ModifyValue(disk.LocationZOffsetTarget), shape.DiskDatas.LocationZOffsetTarget);
|
||||
break;
|
||||
}
|
||||
case AreaTriggerShapeType.BoundedPlane:
|
||||
{
|
||||
SetUpdateFieldValue(areaTriggerData.ModifyValue(m_areaTriggerData.ShapeType), (byte)8);
|
||||
var boundedPlane = areaTriggerData.ModifyValue<AreaTriggerBoundedPlane>(m_areaTriggerData.ShapeData);
|
||||
SetUpdateFieldValue(boundedPlane.ModifyValue(boundedPlane.Extents), new Vector2(shape.BoundedPlaneDatas.Extents[0], shape.BoundedPlaneDatas.Extents[1]));
|
||||
SetUpdateFieldValue(boundedPlane.ModifyValue(boundedPlane.ExtentsTarget), new Vector2(shape.BoundedPlaneDatas.ExtentsTarget[0], shape.BoundedPlaneDatas.ExtentsTarget[1]));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
float GetMaxSearchRadius()
|
||||
{
|
||||
return m_areaTriggerData.BoundsRadius2D * CalcCurrentScale();
|
||||
@@ -909,26 +1007,25 @@ namespace Game.Entities
|
||||
|
||||
void UpdatePolygonVertices()
|
||||
{
|
||||
AreaTriggerCreateProperties createProperties = GetCreateProperties();
|
||||
AreaTriggerShapeInfo shape = GetShape();
|
||||
AreaTriggerPolygon shape = m_areaTriggerData.ShapeData.Get<AreaTriggerPolygon>();
|
||||
float newOrientation = GetOrientation();
|
||||
|
||||
// No need to recalculate, orientation didn't change
|
||||
if (MathFunctions.fuzzyEq(_verticesUpdatePreviousOrientation, newOrientation) && shape.PolygonVerticesTarget.Empty())
|
||||
if (MathFunctions.fuzzyEq(_verticesUpdatePreviousOrientation, newOrientation) && shape.VerticesTarget.Empty())
|
||||
return;
|
||||
|
||||
_polygonVertices.AddRange(shape.PolygonVertices.Select(p => new Position(p.X, p.Y)));
|
||||
_polygonVertices.AddRange(shape.Vertices._values.Select(p => new Position(p.X, p.Y)));
|
||||
|
||||
if (!shape.PolygonVerticesTarget.Empty())
|
||||
if (!shape.Vertices.Empty())
|
||||
{
|
||||
float progress = GetProgress();
|
||||
if (createProperties.MorphCurveId != 0)
|
||||
progress = Global.DB2Mgr.GetCurveValueAt(createProperties.MorphCurveId, progress);
|
||||
if (m_areaTriggerData.MorphCurveId != 0)
|
||||
progress = Global.DB2Mgr.GetCurveValueAt(m_areaTriggerData.MorphCurveId, progress);
|
||||
|
||||
for (var i = 0; i < _polygonVertices.Count; ++i)
|
||||
{
|
||||
Vector2 vertex = _polygonVertices[i];
|
||||
Vector2 vertexTarget = shape.PolygonVerticesTarget[i];
|
||||
Vector2 vertexTarget = shape.VerticesTarget[i];
|
||||
|
||||
vertex.X = MathFunctions.Lerp(vertex.X, vertexTarget.X, progress);
|
||||
vertex.Y = MathFunctions.Lerp(vertex.Y, vertexTarget.Y, progress);
|
||||
@@ -959,7 +1056,7 @@ namespace Game.Entities
|
||||
|
||||
public void UpdateShape()
|
||||
{
|
||||
if (_shape.IsPolygon())
|
||||
if (m_areaTriggerData.ShapeData.Is<AreaTriggerPolygon>())
|
||||
UpdatePolygonVertices();
|
||||
}
|
||||
|
||||
@@ -1090,8 +1187,6 @@ namespace Game.Entities
|
||||
if (splinePoints.Length < 2)
|
||||
return;
|
||||
|
||||
_movementTime = 0;
|
||||
|
||||
_spline = new Spline<float>();
|
||||
_spline.InitSpline(splinePoints, splinePoints.Length, EvaluationMode.Linear, _stationaryPosition.GetOrientation());
|
||||
_spline.InitLengths();
|
||||
@@ -1101,29 +1196,30 @@ namespace Game.Entities
|
||||
speed = 1.0f;
|
||||
|
||||
uint timeToTarget = _spline.Length() / speed * (float)Time.InMilliseconds;
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_areaTriggerData).ModifyValue(m_areaTriggerData.TimeToTarget), timeToTarget);
|
||||
|
||||
if (IsInWorld)
|
||||
{
|
||||
if (_reachedDestination)
|
||||
{
|
||||
AreaTriggerRePath reshapeDest = new();
|
||||
reshapeDest.TriggerGUID = GetGUID();
|
||||
SendMessageToSet(reshapeDest, true);
|
||||
}
|
||||
var areaTriggerData = m_values.ModifyValue(m_areaTriggerData);
|
||||
SetUpdateFieldValue(areaTriggerData.ModifyValue(m_areaTriggerData.TimeToTarget), timeToTarget);
|
||||
SetUpdateFieldValue(areaTriggerData.ModifyValue(m_areaTriggerData.MovementStartTime), GameTime.GetGameTimeMS());
|
||||
|
||||
AreaTriggerRePath reshape = new();
|
||||
reshape.TriggerGUID = GetGUID();
|
||||
reshape.AreaTriggerSpline = new();
|
||||
reshape.AreaTriggerSpline.ElapsedTimeForMovement = GetElapsedTimeForMovement();
|
||||
reshape.AreaTriggerSpline.TimeToTarget = timeToTarget;
|
||||
reshape.AreaTriggerSpline.Points = _spline;
|
||||
SendMessageToSet(reshape, true);
|
||||
}
|
||||
SetUpdateFieldValue(areaTriggerData.ModifyValue(m_areaTriggerData.PathType), (int)AreaTriggerPathType.Spline);
|
||||
var pathData = areaTriggerData.ModifyValue<AreaTriggerSplineCalculator>(m_areaTriggerData.PathData);
|
||||
SetUpdateFieldValue(pathData.ModifyValue(pathData.Catmullrom), splinePoints.Length >= 4);
|
||||
var points = pathData.ModifyValue(pathData.Points);
|
||||
ClearDynamicUpdateFieldValues(points);
|
||||
foreach (Vector3 point in splinePoints)
|
||||
AddDynamicUpdateFieldValue(points, point);
|
||||
|
||||
_reachedDestination = false;
|
||||
}
|
||||
|
||||
uint GetElapsedTimeForMovement()
|
||||
{
|
||||
uint now = GameTime.GetGameTimeMS();
|
||||
if (now >= m_areaTriggerData.MovementStartTime)
|
||||
return now - m_areaTriggerData.MovementStartTime;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void InitOrbit(AreaTriggerOrbitInfo orbit, float? overrideSpeed = null)
|
||||
{
|
||||
// Circular movement requires either a center position or an attached unit
|
||||
@@ -1135,45 +1231,40 @@ namespace Game.Entities
|
||||
|
||||
uint timeToTarget = (uint)(orbit.Radius * 2.0f * MathF.PI * (float)Time.InMilliseconds / speed);
|
||||
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_areaTriggerData).ModifyValue(m_areaTriggerData.TimeToTarget), timeToTarget);
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_areaTriggerData).ModifyValue(m_areaTriggerData.OrbitPathTarget), orbit.PathTarget.GetValueOrDefault(ObjectGuid.Empty));
|
||||
var areaTriggerData = m_values.ModifyValue(m_areaTriggerData);
|
||||
SetUpdateFieldValue(areaTriggerData.ModifyValue(m_areaTriggerData.TimeToTarget), timeToTarget);
|
||||
SetUpdateFieldValue(areaTriggerData.ModifyValue(m_areaTriggerData.MovementStartTime), GameTime.GetGameTimeMS());
|
||||
SetUpdateFieldValue(areaTriggerData.ModifyValue(m_areaTriggerData.OrbitPathTarget), orbit.PathTarget.GetValueOrDefault(ObjectGuid.Empty));
|
||||
SetUpdateFieldValue(areaTriggerData.ModifyValue(m_areaTriggerData.ZOffset), orbit.ZOffset);
|
||||
if (orbit.CanLoop)
|
||||
SetAreaTriggerFlag(AreaTriggerFieldFlags.CanLoop);
|
||||
else
|
||||
RemoveAreaTriggerFlag(AreaTriggerFieldFlags.CanLoop);
|
||||
|
||||
_orbitInfo = new AreaTriggerOrbitInfo();
|
||||
|
||||
_orbitInfo.TimeToTarget = timeToTarget;
|
||||
_orbitInfo.ElapsedTimeForMovement = 0;
|
||||
|
||||
if (IsInWorld)
|
||||
{
|
||||
AreaTriggerRePath reshape = new();
|
||||
reshape.TriggerGUID = GetGUID();
|
||||
reshape.AreaTriggerOrbit = _orbitInfo;
|
||||
|
||||
SendMessageToSet(reshape, true);
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasOrbit()
|
||||
{
|
||||
return _orbitInfo != null;
|
||||
SetUpdateFieldValue(areaTriggerData.ModifyValue(m_areaTriggerData.PathType), (int)AreaTriggerPathType.Orbit);
|
||||
var pathData = areaTriggerData.ModifyValue<AreaTriggerOrbit>(m_areaTriggerData.PathData);
|
||||
SetUpdateFieldValue(pathData.ModifyValue(pathData.CounterClockwise), orbit.CounterClockwise);
|
||||
SetUpdateFieldValue(pathData.ModifyValue(pathData.Center), orbit.Center.GetValueOrDefault(new Position()));
|
||||
SetUpdateFieldValue(pathData.ModifyValue(pathData.Radius), orbit.Radius);
|
||||
SetUpdateFieldValue(pathData.ModifyValue(pathData.InitialAngle), orbit.InitialAngle);
|
||||
SetUpdateFieldValue(pathData.ModifyValue(pathData.BlendFromRadius), orbit.BlendFromRadius);
|
||||
SetUpdateFieldValue(pathData.ModifyValue(pathData.ExtraTimeForBlending), orbit.ExtraTimeForBlending);
|
||||
}
|
||||
|
||||
Position GetOrbitCenterPosition()
|
||||
{
|
||||
if (!HasOrbit())
|
||||
AreaTriggerOrbit orbit = m_areaTriggerData.PathData.Get<AreaTriggerOrbit>();
|
||||
if (orbit == null)
|
||||
return null;
|
||||
|
||||
if (_orbitInfo.PathTarget.HasValue)
|
||||
if (!m_areaTriggerData.OrbitPathTarget.GetValue().IsEmpty())
|
||||
{
|
||||
WorldObject center = Global.ObjAccessor.GetWorldObject(this, _orbitInfo.PathTarget.Value);
|
||||
WorldObject center = Global.ObjAccessor.GetWorldObject(this, m_areaTriggerData.OrbitPathTarget);
|
||||
if (center != null)
|
||||
return center;
|
||||
}
|
||||
|
||||
if (_orbitInfo.Center.HasValue)
|
||||
return new Position(_orbitInfo.Center.Value);
|
||||
|
||||
return null;
|
||||
return new Position(orbit.Center);
|
||||
}
|
||||
|
||||
Position CalculateOrbitPosition()
|
||||
@@ -1182,26 +1273,24 @@ namespace Game.Entities
|
||||
if (centerPos == null)
|
||||
return GetPosition();
|
||||
|
||||
AreaTriggerCreateProperties createProperties = GetCreateProperties();
|
||||
AreaTriggerOrbitInfo cmi = GetOrbit();
|
||||
AreaTriggerOrbit cmi = m_areaTriggerData.PathData.Get<AreaTriggerOrbit>();
|
||||
|
||||
// AreaTrigger make exactly "Duration / TimeToTarget" loops during his life time
|
||||
float pathProgress = (float)cmi.ElapsedTimeForMovement / cmi.TimeToTarget;
|
||||
if (createProperties != null && createProperties.MoveCurveId != 0)
|
||||
pathProgress = Global.DB2Mgr.GetCurveValueAt(createProperties.MoveCurveId, pathProgress);
|
||||
float pathProgress = (float)(GetElapsedTimeForMovement() + cmi.ExtraTimeForBlending) / (float)GetTimeToTarget();
|
||||
if (m_areaTriggerData.MoveCurveId != 0)
|
||||
pathProgress = Global.DB2Mgr.GetCurveValueAt(m_areaTriggerData.MoveCurveId, pathProgress);
|
||||
|
||||
// We already made one circle and can't loop
|
||||
if (!cmi.CanLoop)
|
||||
if (!HasAreaTriggerFlag(AreaTriggerFieldFlags.CanLoop))
|
||||
pathProgress = Math.Min(1.0f, pathProgress);
|
||||
|
||||
float radius = cmi.Radius;
|
||||
if (MathFunctions.fuzzyNe(cmi.BlendFromRadius, radius))
|
||||
if (pathProgress <= 1.0f && MathFunctions.fuzzyNe(cmi.BlendFromRadius, radius))
|
||||
{
|
||||
float blendCurve = (cmi.BlendFromRadius - radius) / radius;
|
||||
// 4.f Defines four quarters
|
||||
blendCurve = MathFunctions.RoundToInterval(ref blendCurve, 1.0f, 4.0f) / 4.0f;
|
||||
float blendProgress = Math.Min(1.0f, pathProgress / blendCurve);
|
||||
radius = MathFunctions.Lerp(cmi.BlendFromRadius, cmi.Radius, blendProgress);
|
||||
MathFunctions.RoundToInterval(ref blendCurve, 1.0f, 4.0f);
|
||||
float blendProgress = Math.Min(1.0f, pathProgress / blendCurve * 0.63661975f);
|
||||
radius = MathFunctions.Lerp(cmi.BlendFromRadius, radius, blendProgress);
|
||||
}
|
||||
|
||||
// Adapt Path progress depending of circle direction
|
||||
@@ -1211,13 +1300,13 @@ namespace Game.Entities
|
||||
float angle = cmi.InitialAngle + 2.0f * (float)Math.PI * pathProgress;
|
||||
float x = centerPos.GetPositionX() + (radius * (float)Math.Cos(angle));
|
||||
float y = centerPos.GetPositionY() + (radius * (float)Math.Sin(angle));
|
||||
float z = centerPos.GetPositionZ() + cmi.ZOffset;
|
||||
float z = centerPos.GetPositionZ() + m_areaTriggerData.ZOffset;
|
||||
|
||||
float orientation = 0.0f;
|
||||
if (createProperties != null && createProperties.FacingCurveId != 0)
|
||||
orientation = Global.DB2Mgr.GetCurveValueAt(createProperties.FacingCurveId, GetProgress());
|
||||
if (m_areaTriggerData.FacingCurveId != 0)
|
||||
orientation = Global.DB2Mgr.GetCurveValueAt(m_areaTriggerData.FacingCurveId, GetProgress());
|
||||
|
||||
if (GetCreateProperties() == null || !GetCreateProperties().Flags.HasFlag(AreaTriggerCreatePropertiesFlag.HasAbsoluteOrientation))
|
||||
if (!HasAreaTriggerFlag(AreaTriggerFieldFlags.AbsoluteOrientation))
|
||||
{
|
||||
orientation += angle;
|
||||
orientation += cmi.CounterClockwise ? MathFunctions.PiOver4 : -MathFunctions.PiOver4;
|
||||
@@ -1226,13 +1315,8 @@ namespace Game.Entities
|
||||
return new Position(x, y, z, orientation);
|
||||
}
|
||||
|
||||
void UpdateOrbitPosition(uint diff)
|
||||
void UpdateOrbitPosition()
|
||||
{
|
||||
if (_orbitInfo.StartDelay > GetElapsedTimeForMovement())
|
||||
return;
|
||||
|
||||
_orbitInfo.ElapsedTimeForMovement = (int)(GetElapsedTimeForMovement() - _orbitInfo.StartDelay);
|
||||
|
||||
Position pos = CalculateOrbitPosition();
|
||||
|
||||
GetMap().AreaTriggerRelocation(this, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation());
|
||||
@@ -1240,14 +1324,12 @@ namespace Game.Entities
|
||||
DebugVisualizePosition();
|
||||
}
|
||||
|
||||
void UpdateSplinePosition(uint diff)
|
||||
void UpdateSplinePosition(Spline<float> spline)
|
||||
{
|
||||
if (_reachedDestination)
|
||||
return;
|
||||
|
||||
_movementTime += diff;
|
||||
|
||||
if (_movementTime >= GetTimeToTarget())
|
||||
if (GetElapsedTimeForMovement() >= GetTimeToTarget())
|
||||
{
|
||||
_reachedDestination = true;
|
||||
_lastSplineIndex = _spline.Last();
|
||||
@@ -1262,18 +1344,18 @@ namespace Game.Entities
|
||||
return;
|
||||
}
|
||||
|
||||
float currentTimePercent = (float)_movementTime / GetTimeToTarget();
|
||||
float currentTimePercent = (float)GetElapsedTimeForMovement() / GetTimeToTarget();
|
||||
|
||||
if (currentTimePercent <= 0.0f)
|
||||
return;
|
||||
|
||||
AreaTriggerCreateProperties createProperties = GetCreateProperties();
|
||||
if (createProperties != null && createProperties.MoveCurveId != 0)
|
||||
if (m_areaTriggerData.MoveCurveId != 0)
|
||||
{
|
||||
float progress = Global.DB2Mgr.GetCurveValueAt(createProperties.MoveCurveId, currentTimePercent);
|
||||
float progress = Global.DB2Mgr.GetCurveValueAt(m_areaTriggerData.MoveCurveId, currentTimePercent);
|
||||
if (progress < 0.0f || progress > 1.0f)
|
||||
{
|
||||
Log.outError(LogFilter.AreaTrigger, $"AreaTrigger (Id: {GetEntry()}, AreaTriggerCreatePropertiesId: (Id: {createProperties.Id.Id}, IsCustom: {createProperties.Id.IsCustom})) has wrong progress ({progress}) caused by curve calculation (MoveCurveId: {createProperties.MoveCurveId})");
|
||||
AreaTriggerCreateProperties createProperties = GetCreateProperties();
|
||||
Log.outError(LogFilter.AreaTrigger, $"AreaTrigger (Id: {GetEntry()}, AreaTriggerCreatePropertiesId: (Id: {createProperties.Id.Id}, IsCustom: {createProperties.Id.IsCustom})) has wrong progress ({progress}) caused by curve calculation (MoveCurveId: {m_areaTriggerData.MoveCurveId})");
|
||||
}
|
||||
else
|
||||
currentTimePercent = progress;
|
||||
@@ -1287,10 +1369,10 @@ namespace Game.Entities
|
||||
_spline.Evaluate_Percent(lastPositionIndex, percentFromLastPoint, out currentPosition);
|
||||
|
||||
float orientation = _stationaryPosition.GetOrientation();
|
||||
if (createProperties != null && createProperties.FacingCurveId != 0)
|
||||
orientation += Global.DB2Mgr.GetCurveValueAt(createProperties.FacingCurveId, GetProgress());
|
||||
if (m_areaTriggerData.FacingCurveId != 0)
|
||||
orientation += Global.DB2Mgr.GetCurveValueAt(m_areaTriggerData.FacingCurveId, GetProgress());
|
||||
|
||||
if (GetCreateProperties() != null && !GetCreateProperties().Flags.HasFlag(AreaTriggerCreatePropertiesFlag.HasAbsoluteOrientation) && GetCreateProperties().Flags.HasFlag(AreaTriggerCreatePropertiesFlag.HasFaceMovementDir))
|
||||
if (!HasAreaTriggerFlag(AreaTriggerFieldFlags.AbsoluteOrientation) && HasAreaTriggerFlag(AreaTriggerFieldFlags.FaceMovementDir))
|
||||
{
|
||||
_spline.Evaluate_Derivative(lastPositionIndex, percentFromLastPoint, out Vector3 derivative);
|
||||
if (derivative.X != 0.0f || derivative.Y != 0.0f)
|
||||
@@ -1317,11 +1399,11 @@ namespace Game.Entities
|
||||
float z = GetScaleCurveValueAtProgress(m_areaTriggerData.OverrideMoveCurveZ, progress);
|
||||
float orientation = GetOrientation();
|
||||
|
||||
if (GetCreateProperties().FacingCurveId != 0)
|
||||
if (m_areaTriggerData.FacingCurveId != 0)
|
||||
{
|
||||
orientation = Global.DB2Mgr.GetCurveValueAt(GetCreateProperties().FacingCurveId, GetProgress());
|
||||
if (GetCreateProperties() == null || !GetCreateProperties().Flags.HasFlag(AreaTriggerCreatePropertiesFlag.HasAbsoluteOrientation))
|
||||
orientation += _stationaryPosition.GetOrientation();
|
||||
orientation = Global.DB2Mgr.GetCurveValueAt(m_areaTriggerData.FacingCurveId, GetProgress());
|
||||
if (HasAreaTriggerFlag(AreaTriggerFieldFlags.AbsoluteOrientation))
|
||||
orientation += m_areaTriggerData.Facing;
|
||||
}
|
||||
|
||||
GetMap().AreaTriggerRelocation(this, x, y, z, orientation);
|
||||
@@ -1438,9 +1520,15 @@ namespace Game.Entities
|
||||
public bool IsRemoved() { return _isRemoved; }
|
||||
public uint GetSpellId() { return m_areaTriggerData.SpellID; }
|
||||
public AuraEffect GetAuraEffect() { return _aurEff; }
|
||||
public uint GetTimeSinceCreated() { return _timeSinceCreated; }
|
||||
|
||||
public void SetHeightIgnoresScale(bool heightIgnoresScale) { SetUpdateFieldValue(m_values.ModifyValue(m_areaTriggerData).ModifyValue(m_areaTriggerData.HeightIgnoresScale), heightIgnoresScale); }
|
||||
public AreaTriggerFieldFlags GetAreaTriggerFlags() { return (AreaTriggerFieldFlags)m_areaTriggerData.Flags.GetValue(); }
|
||||
public bool HasAreaTriggerFlag(AreaTriggerFieldFlags flag)
|
||||
{
|
||||
return GetAreaTriggerFlags().HasFlag(flag);
|
||||
}
|
||||
public void SetAreaTriggerFlag(AreaTriggerFieldFlags flag) { SetUpdateFieldFlagValue(m_values.ModifyValue(m_areaTriggerData).ModifyValue(m_areaTriggerData.Flags), (uint)flag); }
|
||||
public void RemoveAreaTriggerFlag(AreaTriggerFieldFlags flag) { RemoveUpdateFieldFlagValue(m_values.ModifyValue(m_areaTriggerData).ModifyValue(m_areaTriggerData.Flags), (uint)flag); }
|
||||
public void ReplaceAllAreaTriggerFlags(AreaTriggerFieldFlags flag) { SetUpdateFieldValue(m_values.ModifyValue(m_areaTriggerData).ModifyValue(m_areaTriggerData.Flags), (uint)flag); }
|
||||
|
||||
public uint GetTimeToTarget() { return m_areaTriggerData.TimeToTarget; }
|
||||
public void SetTimeToTarget(uint timeToTarget) { SetUpdateFieldValue(m_values.ModifyValue(m_areaTriggerData).ModifyValue(m_areaTriggerData.TimeToTarget), timeToTarget); }
|
||||
@@ -1467,15 +1555,11 @@ namespace Game.Entities
|
||||
public override ObjectGuid GetOwnerGUID() { return GetCasterGuid(); }
|
||||
public ObjectGuid GetCasterGuid() { return m_areaTriggerData.Caster; }
|
||||
|
||||
public AreaTriggerShapeInfo GetShape() { return _shape; }
|
||||
public Vector3 GetRollPitchYaw() { return _rollPitchYaw; }
|
||||
public Vector3 GetTargetRollPitchYaw() { return _targetRollPitchYaw; }
|
||||
|
||||
public bool HasSplines() { return !_spline.Empty(); }
|
||||
public Spline<float> GetSpline() { return _spline; }
|
||||
public uint GetElapsedTimeForMovement() { return GetTimeSinceCreated(); } // @todo: research the right value, in sniffs both timers are nearly identical
|
||||
|
||||
public AreaTriggerOrbitInfo GetOrbit() { return _orbitInfo; }
|
||||
bool HasOrbit() { return m_areaTriggerData.PathData.Is<AreaTriggerOrbit>(); }
|
||||
public AreaTriggerOrbit GetOrbit() { return m_areaTriggerData.PathData.Get<AreaTriggerOrbit>(); }
|
||||
|
||||
public AreaTriggerFieldData m_areaTriggerData;
|
||||
|
||||
@@ -1486,21 +1570,16 @@ namespace Game.Entities
|
||||
AuraEffect _aurEff;
|
||||
|
||||
Position _stationaryPosition;
|
||||
AreaTriggerShapeInfo _shape;
|
||||
int _duration;
|
||||
int _totalDuration;
|
||||
uint _timeSinceCreated;
|
||||
float _verticesUpdatePreviousOrientation;
|
||||
bool _isRemoved;
|
||||
|
||||
Position _rollPitchYaw;
|
||||
Position _targetRollPitchYaw;
|
||||
List<Position> _polygonVertices;
|
||||
Spline<float> _spline;
|
||||
|
||||
bool _reachedDestination;
|
||||
int _lastSplineIndex;
|
||||
uint _movementTime;
|
||||
|
||||
AreaTriggerOrbitInfo _orbitInfo;
|
||||
|
||||
|
||||
@@ -104,18 +104,6 @@ namespace Game.Entities
|
||||
public AreaTriggerScaleCurvePointsTemplate CurveTemplate;
|
||||
}
|
||||
|
||||
public struct AreaTriggerMovementScriptInfo
|
||||
{
|
||||
public uint SpellScriptID;
|
||||
public Vector3 Center;
|
||||
|
||||
public void Write(WorldPacket data)
|
||||
{
|
||||
data.WriteUInt32(SpellScriptID);
|
||||
data.WriteVector3(Center);
|
||||
}
|
||||
}
|
||||
|
||||
public struct AreaTriggerId
|
||||
{
|
||||
public uint Id;
|
||||
@@ -204,35 +192,11 @@ namespace Game.Entities
|
||||
|
||||
public class AreaTriggerOrbitInfo
|
||||
{
|
||||
public void Write(WorldPacket data)
|
||||
{
|
||||
data.WriteBit(PathTarget.HasValue);
|
||||
data.WriteBit(Center.HasValue);
|
||||
data.WriteBit(CounterClockwise);
|
||||
data.WriteBit(CanLoop);
|
||||
|
||||
data.WriteUInt32(TimeToTarget);
|
||||
data.WriteInt32(ElapsedTimeForMovement);
|
||||
data.WriteUInt32(StartDelay);
|
||||
data.WriteFloat(Radius);
|
||||
data.WriteFloat(BlendFromRadius);
|
||||
data.WriteFloat(InitialAngle);
|
||||
data.WriteFloat(ZOffset);
|
||||
|
||||
if (PathTarget.HasValue)
|
||||
data.WritePackedGuid(PathTarget.Value);
|
||||
|
||||
if (Center.HasValue)
|
||||
data.WriteVector3(Center.Value);
|
||||
}
|
||||
|
||||
public ObjectGuid? PathTarget;
|
||||
public Vector3? Center;
|
||||
public bool CounterClockwise;
|
||||
public bool CanLoop;
|
||||
public uint TimeToTarget;
|
||||
public int ElapsedTimeForMovement;
|
||||
public uint StartDelay;
|
||||
public int ExtraTimeForBlending;
|
||||
public float Radius;
|
||||
public float BlendFromRadius;
|
||||
public float InitialAngle;
|
||||
|
||||
@@ -166,6 +166,7 @@ namespace Game.Entities
|
||||
|
||||
stats.Flags[0] = (uint)creatureDifficulty.TypeFlags;
|
||||
stats.Flags[1] = creatureDifficulty.TypeFlags2;
|
||||
stats.Flags[2] = creatureDifficulty.TypeFlags3;
|
||||
|
||||
stats.CreatureType = (sbyte)CreatureType;
|
||||
stats.CreatureFamily = (int)Family;
|
||||
@@ -436,6 +437,7 @@ namespace Game.Entities
|
||||
public int CreatureDifficultyID;
|
||||
public CreatureTypeFlags TypeFlags;
|
||||
public uint TypeFlags2;
|
||||
public uint TypeFlags3;
|
||||
public uint LootID;
|
||||
public uint PickPocketLootID;
|
||||
public uint SkinLootID;
|
||||
|
||||
@@ -224,6 +224,12 @@ namespace Game.Entities
|
||||
[FieldOffset(80)]
|
||||
public craftingTable CraftingTable;
|
||||
|
||||
[FieldOffset(80)]
|
||||
public futurePatchGameObject FuturePatchGameObject;
|
||||
|
||||
[FieldOffset(80)]
|
||||
public assistAction AssistAction;
|
||||
|
||||
[FieldOffset(80)]
|
||||
public raw Raw;
|
||||
|
||||
@@ -539,6 +545,10 @@ namespace Game.Entities
|
||||
return QuestGiver.gossipID;
|
||||
case GameObjectTypes.Goober:
|
||||
return Goober.gossipID;
|
||||
case GameObjectTypes.SpellFocus:
|
||||
return SpellFocus.gossipID;
|
||||
case GameObjectTypes.AssistAction:
|
||||
return AssistAction.gossipID;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@@ -641,6 +651,8 @@ namespace Game.Entities
|
||||
return Trap.cooldown;
|
||||
case GameObjectTypes.Goober:
|
||||
return Goober.cooldown;
|
||||
case GameObjectTypes.AssistAction:
|
||||
return AssistAction.cooldown;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@@ -1483,7 +1495,7 @@ namespace Game.Entities
|
||||
public uint radius; // 4 radius, int, Min value: 0, Max value: 50, Default value: 10
|
||||
public uint InteractRadiusOverride; // 5 Interact Radius Override (Yards * 100), int, Min value: 0, Max value: 2147483647, Default value: 0
|
||||
public uint ItemInteractionID; // 6 Item Interaction ID, References: UiItemInteraction, NoValue = 0
|
||||
public uint PlayerInteractionType; // 7 Player Interaction Type, enum { None, TradePartner, Item, Gossip, QuestGiver, Merchant, TaxiNode, Trainer, Banker, AlliedRaceDetailsGiver, GuildBanker, Registrar, Vendor, PetitionVendor, GuildTabardVendor, TalentMaster, SpecializationMaster, MailInfo, SpiritHealer, AreaSpiritHealer, Binder, Auctioneer, StableMaster, BattleMaster, Transmogrifier, LFGDungeon, VoidStorageBanker, BlackMarketAuctioneer, AdventureMap, WorldMap, GarrArchitect, GarrTradeskill, GarrMission, ShipmentCrafter, GarrRecruitment, GarrTalent, Trophy, PlayerChoice, ArtifactForge, ObliterumForge, ScrappingMachine, ContributionCollector, AzeriteRespec, IslandQueue, ItemInteraction, ChromieTime, CovenantPreview, AnimaDiversion, LegendaryCrafting, WeeklyRewards, Soulbind, CovenantSanctum, NewPlayerGuide, ItemUpgrade, AdventureJournal, Renown, AzeriteForge, PerksProgramVendor, ProfessionsCraftingOrder, Professions, ProfessionsCustomerOrder, TraitSystem, BarbersChoice, JailersTowerBuffs, MajorFactionRenown, PersonalTabardVendor, ForgeMaster, CharacterBanker, AccountBanker, ProfessionRespec, PlaceholderType71, PlaceholderType72, PlaceholderType73, PlaceholderType74, PlaceholderType75, PlaceholderType76, PlaceholderType77, }; Default: None
|
||||
public uint PlayerInteractionType; // 7 Player Interaction Type, enum { None, TradePartner, Item, Gossip, QuestGiver, Merchant, TaxiNode, Trainer, Banker, AlliedRaceDetailsGiver, GuildBanker, Registrar, Vendor, PetitionVendor, GuildTabardVendor, TalentMaster, SpecializationMaster, MailInfo, SpiritHealer, AreaSpiritHealer, Binder, Auctioneer, StableMaster, BattleMaster, Transmogrifier, LFGDungeon, VoidStorageBanker, BlackMarketAuctioneer, AdventureMap, WorldMap, GarrArchitect, GarrTradeskill, GarrMission, ShipmentCrafter, GarrRecruitment, GarrTalent, Trophy, PlayerChoice, ArtifactForge, ObliterumForge, ScrappingMachine, ContributionCollector, AzeriteRespec, IslandQueue, ItemInteraction, ChromieTime, CovenantPreview, AnimaDiversion, LegendaryCrafting, WeeklyRewards, Soulbind, CovenantSanctum, NewPlayerGuide, ItemUpgrade, AdventureJournal, Renown, AzeriteForge, PerksProgramVendor, ProfessionsCraftingOrder, Professions, ProfessionsCustomerOrder, TraitSystem, BarbersChoice, JailersTowerBuffs, MajorFactionRenown, PersonalTabardVendor, ForgeMaster, CharacterBanker, AccountBanker, ProfessionRespec, PlaceholderType71, PlaceholderType72, PlaceholderType73, PlaceholderType74, PlaceholderType75, PlaceholderType76, GuildRename, PlaceholderType76, }; Default: None
|
||||
}
|
||||
|
||||
public struct keystonereceptacle
|
||||
@@ -1614,6 +1626,19 @@ namespace Game.Entities
|
||||
public uint Script; // 0 Script, References: SpellScript, NoValue = 0
|
||||
public uint autoClose; // 1 autoClose (ms), int, Min value: 0, Max value: 2147483647, Default value: 3000
|
||||
}
|
||||
|
||||
public struct futurePatchGameObject
|
||||
{
|
||||
}
|
||||
|
||||
public struct assistAction
|
||||
{
|
||||
public uint AssistActionType; // 0 Assist Action Type, enum { None, Lounging Player, Grave Marker, Placed VO, Player Guardian, Player Slayer, Captured Buff, }; Default: None
|
||||
public uint cooldown; // 1 cooldown, int, Min value: 0, Max value: 2147483647, Default value: 3000
|
||||
public uint gossipID; // 2 gossipID, References: Gossip, NoValue = 0
|
||||
public uint spell; // 3 spell, References: Spell, NoValue = 0
|
||||
public uint playerCast; // 4 playerCast, enum { false, true, }; Default: false
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
||||
@@ -2551,8 +2551,14 @@ namespace Game.Entities
|
||||
}
|
||||
|
||||
eff.SetBonuses.Add(itemSetSpell);
|
||||
|
||||
// spell cast only if fit form requirement, in other case will cast at form change
|
||||
if (itemSetSpell.ChrSpecID == 0 || (ChrSpecialization)itemSetSpell.ChrSpecID == player.GetPrimarySpecialization())
|
||||
if (itemSetSpell.ChrSpecID != 0 && (ChrSpecialization)itemSetSpell.ChrSpecID != player.GetPrimarySpecialization())
|
||||
continue;
|
||||
|
||||
if (itemSetSpell.TraitSubTreeID != 0 && itemSetSpell.TraitSubTreeID != player.m_playerData.CurrentCombatTraitConfigSubTreeID)
|
||||
continue;
|
||||
|
||||
player.ApplyEquipSpell(spellInfo, null, true);
|
||||
}
|
||||
}
|
||||
@@ -2592,11 +2598,10 @@ namespace Game.Entities
|
||||
if (itemSetSpell.Threshold <= eff.EquippedItems.Count)
|
||||
continue;
|
||||
|
||||
if (!eff.SetBonuses.Contains(itemSetSpell))
|
||||
if (!eff.SetBonuses.Remove(itemSetSpell))
|
||||
continue;
|
||||
|
||||
player.ApplyEquipSpell(Global.SpellMgr.GetSpellInfo(itemSetSpell.SpellID, Difficulty.None), null, false);
|
||||
eff.SetBonuses.Remove(itemSetSpell);
|
||||
}
|
||||
|
||||
if (eff.EquippedItems.Empty()) //all items of a set were removed
|
||||
@@ -2618,7 +2623,8 @@ namespace Game.Entities
|
||||
{
|
||||
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(itemSetSpell.SpellID, Difficulty.None);
|
||||
|
||||
if (itemSetSpell.ChrSpecID != 0 && (ChrSpecialization)itemSetSpell.ChrSpecID != player.GetPrimarySpecialization())
|
||||
if ((itemSetSpell.ChrSpecID != 0 && itemSetSpell.ChrSpecID != (ushort)player.GetPrimarySpecialization())
|
||||
|| (itemSetSpell.TraitSubTreeID != 0 && itemSetSpell.TraitSubTreeID != player.m_playerData.CurrentCombatTraitConfigSubTreeID))
|
||||
player.ApplyEquipSpell(spellInfo, null, false, false); // item set aura is not for current spec
|
||||
else
|
||||
{
|
||||
|
||||
@@ -15,6 +15,12 @@ namespace Game.Entities
|
||||
T GetValue();
|
||||
}
|
||||
|
||||
public interface IHasChangesMask
|
||||
{
|
||||
void ClearChangesMask();
|
||||
UpdateMask GetUpdateMask();
|
||||
}
|
||||
|
||||
public class UpdateFieldString : IUpdateField<string>
|
||||
{
|
||||
public string _value;
|
||||
@@ -347,15 +353,39 @@ namespace Game.Entities
|
||||
}
|
||||
}
|
||||
|
||||
public interface IHasChangesMask
|
||||
public class VariantUpdateField(int blockBit, int bit, params Type[] types)
|
||||
{
|
||||
void ClearChangesMask();
|
||||
UpdateMask GetUpdateMask();
|
||||
public object _value;
|
||||
Type[] _types = types;
|
||||
|
||||
public int BlockBit = blockBit;
|
||||
public int Bit = bit;
|
||||
|
||||
public bool Is<T>() { return _types.Contains(typeof(T)); }
|
||||
|
||||
public T Get<T>() where T : class, new()
|
||||
{
|
||||
if (Is<T>())
|
||||
return _value as T;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void Visit(Action<dynamic> visitor)
|
||||
{
|
||||
visitor(_value);
|
||||
}
|
||||
|
||||
public void ConstructValue<T>() where T : class, new()
|
||||
{
|
||||
_value = new T();
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class HasChangesMask : IHasChangesMask
|
||||
{
|
||||
public int _changeMask;
|
||||
public static int ChangeMaskLength;
|
||||
|
||||
public UpdateMask _changesMask;
|
||||
public int _blockBit;
|
||||
public int Bit;
|
||||
@@ -364,12 +394,13 @@ namespace Game.Entities
|
||||
{
|
||||
_blockBit = blockBit;
|
||||
Bit = (int)bit;
|
||||
ChangeMaskLength = changeMask;
|
||||
_changesMask = new UpdateMask(changeMask);
|
||||
_changeMask = changeMask;
|
||||
}
|
||||
|
||||
public HasChangesMask(int changeMask)
|
||||
{
|
||||
ChangeMaskLength = changeMask;
|
||||
_changesMask = new UpdateMask(changeMask);
|
||||
}
|
||||
|
||||
@@ -433,6 +464,19 @@ namespace Game.Entities
|
||||
}
|
||||
}
|
||||
|
||||
public void ClearChangesMask(VariantUpdateField field)
|
||||
{
|
||||
if (typeof(IHasChangesMask).IsAssignableFrom(field._value.GetType()))
|
||||
((IHasChangesMask)field._value).ClearChangesMask();
|
||||
}
|
||||
|
||||
public dynamic ModifyValueOld(dynamic value, int bit, int blockBit)
|
||||
{
|
||||
_changesMask.Set(blockBit);
|
||||
_changesMask.Set(bit);
|
||||
return value;
|
||||
}
|
||||
|
||||
public UpdateField<U> ModifyValue<U>(UpdateField<U> updateField) where U : new()
|
||||
{
|
||||
MarkChanged(updateField);
|
||||
@@ -504,6 +548,18 @@ namespace Game.Entities
|
||||
return new DynamicUpdateFieldSetter<U>(updateField[index], dynamicIndex);
|
||||
}
|
||||
|
||||
public V ModifyValue<V>(VariantUpdateField field) where V : class, new()
|
||||
{
|
||||
if (!field.Is<V>())
|
||||
field.ConstructValue<V>();
|
||||
|
||||
if (field.BlockBit >= 0)
|
||||
_changesMask.Set(field.BlockBit);
|
||||
|
||||
_changesMask.Set(Bit);
|
||||
return field.Get<V>();
|
||||
}
|
||||
|
||||
public void MarkChanged<U>(UpdateField<U> updateField) where U : new()
|
||||
{
|
||||
_changesMask.Set(updateField.BlockBit);
|
||||
@@ -560,7 +616,7 @@ namespace Game.Entities
|
||||
|
||||
public UpdateMask GetStaticUpdateMask()
|
||||
{
|
||||
return new UpdateMask(_changeMask);
|
||||
return new UpdateMask(ChangeMaskLength);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -299,6 +299,7 @@ namespace Game.Entities
|
||||
data.WriteBit(flags.NoBirthAnim);
|
||||
data.WriteBit(flags.EnablePortals);
|
||||
data.WriteBit(flags.PlayHoverAnim);
|
||||
data.WriteBit(flags.ThisIsYou);
|
||||
data.WriteBit(flags.MovementUpdate);
|
||||
data.WriteBit(flags.MovementTransport);
|
||||
data.WriteBit(flags.Stationary);
|
||||
@@ -307,10 +308,8 @@ namespace Game.Entities
|
||||
data.WriteBit(flags.Vehicle);
|
||||
data.WriteBit(flags.AnimKit);
|
||||
data.WriteBit(flags.Rotation);
|
||||
data.WriteBit(flags.AreaTrigger);
|
||||
data.WriteBit(flags.GameObject);
|
||||
data.WriteBit(flags.SmoothPhasing);
|
||||
data.WriteBit(flags.ThisIsYou);
|
||||
data.WriteBit(flags.SceneObject);
|
||||
data.WriteBit(flags.ActivePlayer);
|
||||
data.WriteBit(flags.Conversation);
|
||||
@@ -461,7 +460,10 @@ namespace Game.Entities
|
||||
}
|
||||
|
||||
if (flags.CombatVictim)
|
||||
data.WritePackedGuid(ToUnit().GetVictim().GetGUID()); // CombatVictim
|
||||
{
|
||||
Unit unit = ToUnit();
|
||||
data.WritePackedGuid(unit.GetVictim().GetGUID()); // CombatVictim
|
||||
}
|
||||
|
||||
if (flags.ServerTime)
|
||||
data.WriteUInt32(GameTime.GetGameTimeMS());
|
||||
@@ -481,7 +483,10 @@ namespace Game.Entities
|
||||
}
|
||||
|
||||
if (flags.Rotation)
|
||||
data.WriteInt64(ToGameObject().GetPackedLocalRotation()); // Rotation
|
||||
{
|
||||
GameObject gameObject = ToGameObject();
|
||||
data.WriteInt64(gameObject.GetPackedLocalRotation()); // Rotation
|
||||
}
|
||||
|
||||
if (PauseTimes != null && !PauseTimes.Empty())
|
||||
foreach (var stopFrame in PauseTimes)
|
||||
@@ -493,138 +498,6 @@ namespace Game.Entities
|
||||
MovementExtensions.WriteTransportInfo(data, self.m_movementInfo.transport);
|
||||
}
|
||||
|
||||
if (flags.AreaTrigger)
|
||||
{
|
||||
AreaTrigger areaTrigger = ToAreaTrigger();
|
||||
AreaTriggerCreateProperties createProperties = areaTrigger.GetCreateProperties();
|
||||
AreaTriggerShapeInfo shape = areaTrigger.GetShape();
|
||||
|
||||
data.WriteUInt32(areaTrigger.GetTimeSinceCreated());
|
||||
|
||||
data.WriteVector3(areaTrigger.GetRollPitchYaw());
|
||||
|
||||
switch (shape.TriggerType)
|
||||
{
|
||||
case AreaTriggerShapeType.Sphere:
|
||||
data.WriteInt8(0);
|
||||
data.WriteFloat(shape.SphereDatas.Radius);
|
||||
data.WriteFloat(shape.SphereDatas.RadiusTarget);
|
||||
break;
|
||||
case AreaTriggerShapeType.Box:
|
||||
data.WriteInt8(1);
|
||||
data.WriteFloat(shape.BoxDatas.Extents[0]);
|
||||
data.WriteFloat(shape.BoxDatas.Extents[1]);
|
||||
data.WriteFloat(shape.BoxDatas.Extents[2]);
|
||||
data.WriteFloat(shape.BoxDatas.ExtentsTarget[0]);
|
||||
data.WriteFloat(shape.BoxDatas.ExtentsTarget[1]);
|
||||
data.WriteFloat(shape.BoxDatas.ExtentsTarget[2]);
|
||||
break;
|
||||
case AreaTriggerShapeType.Polygon:
|
||||
data.WriteInt8(3);
|
||||
data.WriteInt32(shape.PolygonVertices.Count);
|
||||
data.WriteInt32(shape.PolygonVerticesTarget.Count);
|
||||
data.WriteFloat(shape.PolygonDatas.Height);
|
||||
data.WriteFloat(shape.PolygonDatas.HeightTarget);
|
||||
|
||||
foreach (var vertice in shape.PolygonVertices)
|
||||
data.WriteVector2(vertice);
|
||||
|
||||
foreach (var vertice in shape.PolygonVerticesTarget)
|
||||
data.WriteVector2(vertice);
|
||||
break;
|
||||
case AreaTriggerShapeType.Cylinder:
|
||||
data.WriteInt8(4);
|
||||
data.WriteFloat(shape.CylinderDatas.Radius);
|
||||
data.WriteFloat(shape.CylinderDatas.RadiusTarget);
|
||||
data.WriteFloat(shape.CylinderDatas.Height);
|
||||
data.WriteFloat(shape.CylinderDatas.HeightTarget);
|
||||
data.WriteFloat(shape.CylinderDatas.LocationZOffset);
|
||||
data.WriteFloat(shape.CylinderDatas.LocationZOffsetTarget);
|
||||
break;
|
||||
case AreaTriggerShapeType.Disk:
|
||||
data.WriteInt8(7);
|
||||
data.WriteFloat(shape.DiskDatas.InnerRadius);
|
||||
data.WriteFloat(shape.DiskDatas.InnerRadiusTarget);
|
||||
data.WriteFloat(shape.DiskDatas.OuterRadius);
|
||||
data.WriteFloat(shape.DiskDatas.OuterRadiusTarget);
|
||||
data.WriteFloat(shape.DiskDatas.Height);
|
||||
data.WriteFloat(shape.DiskDatas.HeightTarget);
|
||||
data.WriteFloat(shape.DiskDatas.LocationZOffset);
|
||||
data.WriteFloat(shape.DiskDatas.LocationZOffsetTarget);
|
||||
break;
|
||||
case AreaTriggerShapeType.BoundedPlane:
|
||||
data.WriteInt8(8);
|
||||
data.WriteFloat(shape.BoundedPlaneDatas.Extents[0]);
|
||||
data.WriteFloat(shape.BoundedPlaneDatas.Extents[1]);
|
||||
data.WriteFloat(shape.BoundedPlaneDatas.ExtentsTarget[0]);
|
||||
data.WriteFloat(shape.BoundedPlaneDatas.ExtentsTarget[1]);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
bool hasAbsoluteOrientation = createProperties != null && createProperties.Flags.HasFlag(AreaTriggerCreatePropertiesFlag.HasAbsoluteOrientation);
|
||||
bool hasDynamicShape = createProperties != null && createProperties.Flags.HasFlag(AreaTriggerCreatePropertiesFlag.HasDynamicShape);
|
||||
bool hasAttached = createProperties != null && createProperties.Flags.HasFlag(AreaTriggerCreatePropertiesFlag.HasAttached);
|
||||
bool hasFaceMovementDir = createProperties != null && createProperties.Flags.HasFlag(AreaTriggerCreatePropertiesFlag.HasFaceMovementDir);
|
||||
bool hasFollowsTerrain = createProperties != null && createProperties.Flags.HasFlag(AreaTriggerCreatePropertiesFlag.HasFollowsTerrain);
|
||||
bool hasAlwaysExterior = createProperties != null && createProperties.Flags.HasFlag(AreaTriggerCreatePropertiesFlag.AlwaysExterior);
|
||||
bool hasUnknown1025 = false;
|
||||
bool hasTargetRollPitchYaw = createProperties != null && createProperties.Flags.HasFlag(AreaTriggerCreatePropertiesFlag.HasTargetRollPitchYaw);
|
||||
bool hasScaleCurveID = createProperties != null && createProperties.ScaleCurveId != 0;
|
||||
bool hasMorphCurveID = createProperties != null && createProperties.MorphCurveId != 0;
|
||||
bool hasFacingCurveID = createProperties != null && createProperties.FacingCurveId != 0;
|
||||
bool hasMoveCurveID = createProperties != null && createProperties.MoveCurveId != 0;
|
||||
bool hasMovementScript = false;
|
||||
bool hasPositionalSoundKitID = false;
|
||||
|
||||
data.WriteBit(hasAbsoluteOrientation);
|
||||
data.WriteBit(hasDynamicShape);
|
||||
data.WriteBit(hasAttached);
|
||||
data.WriteBit(hasFaceMovementDir);
|
||||
data.WriteBit(hasFollowsTerrain);
|
||||
data.WriteBit(hasAlwaysExterior);
|
||||
data.WriteBit(hasUnknown1025);
|
||||
data.WriteBit(hasTargetRollPitchYaw);
|
||||
data.WriteBit(hasScaleCurveID);
|
||||
data.WriteBit(hasMorphCurveID);
|
||||
data.WriteBit(hasFacingCurveID);
|
||||
data.WriteBit(hasMoveCurveID);
|
||||
data.WriteBit(hasPositionalSoundKitID);
|
||||
data.WriteBit(areaTrigger.HasSplines());
|
||||
data.WriteBit(areaTrigger.HasOrbit());
|
||||
data.WriteBit(hasMovementScript);
|
||||
|
||||
data.FlushBits();
|
||||
|
||||
if (areaTrigger.HasSplines())
|
||||
AreaTriggerSplineInfo.WriteAreaTriggerSpline(data, areaTrigger.GetTimeToTarget(), areaTrigger.GetElapsedTimeForMovement(), areaTrigger.GetSpline());
|
||||
|
||||
if (hasTargetRollPitchYaw)
|
||||
data.WriteVector3(areaTrigger.GetTargetRollPitchYaw());
|
||||
|
||||
if (hasScaleCurveID)
|
||||
data.WriteUInt32(createProperties.ScaleCurveId);
|
||||
|
||||
if (hasMorphCurveID)
|
||||
data.WriteUInt32(createProperties.MorphCurveId);
|
||||
|
||||
if (hasFacingCurveID)
|
||||
data.WriteUInt32(createProperties.FacingCurveId);
|
||||
|
||||
if (hasMoveCurveID)
|
||||
data.WriteUInt32(createProperties.MoveCurveId);
|
||||
|
||||
if (hasPositionalSoundKitID)
|
||||
data.WriteUInt32(0);
|
||||
|
||||
//if (hasMovementScript)
|
||||
// *data << *areaTrigger.GetMovementScript(); // AreaTriggerMovementScriptInfo
|
||||
|
||||
if (areaTrigger.HasOrbit())
|
||||
areaTrigger.GetOrbit().Write(data);
|
||||
}
|
||||
|
||||
if (flags.GameObject)
|
||||
{
|
||||
GameObject gameObject = ToGameObject();
|
||||
@@ -785,7 +658,7 @@ namespace Game.Entities
|
||||
Player player = ToPlayer();
|
||||
|
||||
bool HasSceneInstanceIDs = !player.GetSceneMgr().GetSceneTemplateByInstanceMap().Empty();
|
||||
bool HasRuneState = ToUnit().GetPowerIndex(PowerType.Runes) != (int)PowerType.Max;
|
||||
bool HasRuneState = player.GetPowerIndex(PowerType.Runes) != (int)PowerType.Max;
|
||||
|
||||
data.WriteBit(HasSceneInstanceIDs);
|
||||
data.WriteBit(HasRuneState);
|
||||
@@ -794,8 +667,8 @@ namespace Game.Entities
|
||||
if (HasSceneInstanceIDs)
|
||||
{
|
||||
data.WriteInt32(player.GetSceneMgr().GetSceneTemplateByInstanceMap().Count);
|
||||
foreach (var pair in player.GetSceneMgr().GetSceneTemplateByInstanceMap())
|
||||
data.WriteUInt32(pair.Key);
|
||||
foreach (var (sceneInstanceId, _) in player.GetSceneMgr().GetSceneTemplateByInstanceMap())
|
||||
data.WriteUInt32(sceneInstanceId);
|
||||
}
|
||||
|
||||
if (HasRuneState)
|
||||
@@ -4157,7 +4030,6 @@ namespace Game.Entities
|
||||
public bool Vehicle;
|
||||
public bool AnimKit;
|
||||
public bool Rotation;
|
||||
public bool AreaTrigger;
|
||||
public bool GameObject;
|
||||
public bool SmoothPhasing;
|
||||
public bool ThisIsYou;
|
||||
@@ -4178,7 +4050,6 @@ namespace Game.Entities
|
||||
Vehicle = false;
|
||||
AnimKit = false;
|
||||
Rotation = false;
|
||||
AreaTrigger = false;
|
||||
GameObject = false;
|
||||
SmoothPhasing = false;
|
||||
ThisIsYou = false;
|
||||
|
||||
@@ -725,6 +725,25 @@ namespace Game.Entities
|
||||
}
|
||||
}
|
||||
|
||||
void _LoadCharacterBankTabSettings(SQLResult result)
|
||||
{
|
||||
if (!result.IsEmpty())
|
||||
{
|
||||
do
|
||||
{
|
||||
if (result.Read<byte>(0) >= (InventorySlots.BankBagEnd - InventorySlots.BankBagStart))
|
||||
continue;
|
||||
|
||||
SetCharacterBankTabSettings(result.Read<byte>(0), result.Read<string>(1), result.Read<string>(2),
|
||||
result.Read<string>(3), (BagSlotFlags)result.Read<uint>(4));
|
||||
|
||||
} while (result.NextRow());
|
||||
}
|
||||
|
||||
while (m_activePlayerData.CharacterBankTabSettings.Size() < m_activePlayerData.NumCharacterBankTabs)
|
||||
AddDynamicUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.CharacterBankTabSettings), new BankTabSettings());
|
||||
}
|
||||
|
||||
void _LoadCurrency(SQLResult result)
|
||||
{
|
||||
if (result.IsEmpty())
|
||||
@@ -1272,7 +1291,13 @@ namespace Game.Entities
|
||||
});
|
||||
|
||||
if (activeConfig >= 0)
|
||||
SetActiveCombatTraitConfigID(m_activePlayerData.TraitConfigs[activeConfig].ID);
|
||||
{
|
||||
TraitConfig activeTraitConfig = m_activePlayerData.TraitConfigs[activeConfig];
|
||||
SetActiveCombatTraitConfigID(activeTraitConfig.ID);
|
||||
int activeSubTree = activeTraitConfig.SubTrees.FindIndexIf(subTree => subTree.Active != 0);
|
||||
if (activeSubTree >= 0)
|
||||
SetCurrentCombatTraitConfigSubTreeID(activeTraitConfig.SubTrees[activeSubTree].TraitSubTreeID);
|
||||
}
|
||||
|
||||
foreach (TraitConfig traitConfig in m_activePlayerData.TraitConfigs)
|
||||
{
|
||||
@@ -1340,55 +1365,6 @@ namespace Game.Entities
|
||||
|
||||
RemoveAtLoginFlag(AtLoginFlags.Resurrect);
|
||||
}
|
||||
void _LoadVoidStorage(SQLResult result)
|
||||
{
|
||||
if (result.IsEmpty())
|
||||
return;
|
||||
|
||||
do
|
||||
{
|
||||
// SELECT itemId, itemEntry, slot, creatorGuid, randomBonusListId, fixedScalingLevel, artifactKnowledgeLevel, context, bonusListIDs FROM character_void_storage WHERE playerGuid = ?
|
||||
ulong itemId = result.Read<ulong>(0);
|
||||
uint itemEntry = result.Read<uint>(1);
|
||||
byte slot = result.Read<byte>(2);
|
||||
ObjectGuid creatorGuid = result.Read<ulong>(3) != 0 ? ObjectGuid.Create(HighGuid.Player, result.Read<ulong>(3)) : ObjectGuid.Empty;
|
||||
uint randomBonusListId = result.Read<uint>(4);
|
||||
uint fixedScalingLevel = result.Read<uint>(5);
|
||||
uint artifactKnowledgeLevel = result.Read<uint>(6);
|
||||
ItemContext context = (ItemContext)result.Read<byte>(7);
|
||||
List<uint> bonusListIDs = new();
|
||||
var bonusListIdTokens = new StringArray(result.Read<string>(8), ' ');
|
||||
for (var i = 0; i < bonusListIdTokens.Length; ++i)
|
||||
{
|
||||
if (uint.TryParse(bonusListIdTokens[i], out uint id))
|
||||
bonusListIDs.Add(id);
|
||||
}
|
||||
|
||||
if (itemId == 0)
|
||||
{
|
||||
Log.outError(LogFilter.Player, "Player:_LoadVoidStorage - Player (GUID: {0}, name: {1}) has an item with an invalid id (item id: item id: {2}, entry: {3}).", GetGUID().ToString(), GetName(), itemId, itemEntry);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (Global.ObjectMgr.GetItemTemplate(itemEntry) == null)
|
||||
{
|
||||
Log.outError(LogFilter.Player, "Player:_LoadVoidStorage - Player (GUID: {0}, name: {1}) has an item with an invalid entry (item id: item id: {2}, entry: {3}).", GetGUID().ToString(), GetName(), itemId, itemEntry);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (slot >= SharedConst.VoidStorageMaxSlot)
|
||||
{
|
||||
Log.outError(LogFilter.Player, "Player:_LoadVoidStorage - Player (GUID: {0}, name: {1}) has an item with an invalid slot (item id: item id: {2}, entry: {3}, slot: {4}).", GetGUID().ToString(), GetName(), itemId, itemEntry, slot);
|
||||
continue;
|
||||
}
|
||||
|
||||
_voidStorageItems[slot] = new VoidStorageItem(itemId, itemEntry, creatorGuid, randomBonusListId, fixedScalingLevel, artifactKnowledgeLevel, context, bonusListIDs);
|
||||
|
||||
BonusData bonus = new(new ItemInstance(_voidStorageItems[slot]));
|
||||
GetSession().GetCollectionMgr().AddItemAppearance(itemEntry, bonus.AppearanceModID);
|
||||
}
|
||||
while (result.NextRow());
|
||||
}
|
||||
|
||||
public void _LoadMail(SQLResult mailsResult, SQLResult mailItemsResult, SQLResult artifactResult, SQLResult azeriteItemResult, SQLResult azeriteItemMilestonePowersResult, SQLResult azeriteItemUnlockedEssencesResult, SQLResult azeriteEmpoweredItemResult)
|
||||
{
|
||||
@@ -2762,6 +2738,26 @@ namespace Game.Entities
|
||||
_playerDataFlagsNeedSave.Clear();
|
||||
}
|
||||
|
||||
void _SaveCharacterBankTabSettings(SQLTransaction trans)
|
||||
{
|
||||
PreparedStatement stmt = CharacterDatabase.GetPreparedStatement(CharStatements.DEL_CHARACTER_BANK_TAB_SETTINGS);
|
||||
stmt.AddValue(0, GetGUID().GetCounter());
|
||||
trans.Append(stmt);
|
||||
|
||||
for (int i = 0; i < m_activePlayerData.CharacterBankTabSettings.Size(); ++i)
|
||||
{
|
||||
BankTabSettings tabSetting = m_activePlayerData.CharacterBankTabSettings[i];
|
||||
stmt = CharacterDatabase.GetPreparedStatement(CharStatements.INS_CHARACTER_BANK_TAB_SETTINGS);
|
||||
stmt.AddValue(0, GetGUID().GetCounter());
|
||||
stmt.AddValue(1, i);
|
||||
stmt.AddValue(2, tabSetting.Name);
|
||||
stmt.AddValue(3, tabSetting.Icon);
|
||||
stmt.AddValue(4, tabSetting.Description);
|
||||
stmt.AddValue(5, tabSetting.DepositFlags);
|
||||
trans.Append(stmt);
|
||||
}
|
||||
}
|
||||
|
||||
public void SaveInventoryAndGoldToDB(SQLTransaction trans)
|
||||
{
|
||||
_SaveInventory(trans);
|
||||
@@ -2867,42 +2863,7 @@ namespace Game.Entities
|
||||
}
|
||||
}
|
||||
}
|
||||
void _SaveVoidStorage(SQLTransaction trans)
|
||||
{
|
||||
PreparedStatement stmt;
|
||||
for (byte i = 0; i < SharedConst.VoidStorageMaxSlot; ++i)
|
||||
{
|
||||
if (_voidStorageItems[i] == null) // unused item
|
||||
{
|
||||
// DELETE FROM void_storage WHERE slot = ? AND playerGuid = ?
|
||||
stmt = CharacterDatabase.GetPreparedStatement(CharStatements.DEL_CHAR_VOID_STORAGE_ITEM_BY_SLOT);
|
||||
stmt.AddValue(0, i);
|
||||
stmt.AddValue(1, GetGUID().GetCounter());
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
// REPLACE INTO character_void_storage (itemId, playerGuid, itemEntry, slot, creatorGuid, randomPropertyType, randomProperty, upgradeId, fixedScalingLevel, artifactKnowledgeLevel, bonusListIDs) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
stmt = CharacterDatabase.GetPreparedStatement(CharStatements.REP_CHAR_VOID_STORAGE_ITEM);
|
||||
stmt.AddValue(0, _voidStorageItems[i].ItemId);
|
||||
stmt.AddValue(1, GetGUID().GetCounter());
|
||||
stmt.AddValue(2, _voidStorageItems[i].ItemEntry);
|
||||
stmt.AddValue(3, i);
|
||||
stmt.AddValue(4, _voidStorageItems[i].CreatorGuid.GetCounter());
|
||||
stmt.AddValue(5, (byte)_voidStorageItems[i].RandomBonusListId);
|
||||
stmt.AddValue(6, _voidStorageItems[i].FixedScalingLevel);
|
||||
stmt.AddValue(7, _voidStorageItems[i].ArtifactKnowledgeLevel);
|
||||
stmt.AddValue(8, (byte)_voidStorageItems[i].Context);
|
||||
|
||||
StringBuilder bonusListIDs = new();
|
||||
foreach (uint bonusListID in _voidStorageItems[i].BonusListIDs)
|
||||
bonusListIDs.AppendFormat("{0} ", bonusListID);
|
||||
stmt.AddValue(9, bonusListIDs.ToString());
|
||||
}
|
||||
|
||||
trans.Append(stmt);
|
||||
}
|
||||
}
|
||||
void _SaveCUFProfiles(SQLTransaction trans)
|
||||
{
|
||||
PreparedStatement stmt;
|
||||
@@ -3006,10 +2967,8 @@ namespace Game.Entities
|
||||
bagSlotFlags[i] = (BagSlotFlags)result.Read<uint>(fieldIndex++);
|
||||
|
||||
byte bankSlots = result.Read<byte>(fieldIndex++);
|
||||
BagSlotFlags[] bankBagSlotFlags = new BagSlotFlags[7];
|
||||
byte bankTabs = result.Read<byte>(fieldIndex++);
|
||||
BagSlotFlags bankBagFlags = (BagSlotFlags)result.Read<uint>(fieldIndex++);
|
||||
for (var i = 0; i < bankBagSlotFlags.Length; ++i)
|
||||
bankBagSlotFlags[i] = (BagSlotFlags)result.Read<uint>(fieldIndex++);
|
||||
|
||||
PlayerRestState restState = (PlayerRestState)result.Read<byte>(fieldIndex++);
|
||||
PlayerFlags playerFlags = (PlayerFlags)result.Read<uint>(fieldIndex++);
|
||||
@@ -3179,9 +3138,8 @@ namespace Game.Entities
|
||||
ReplaceAllBagSlotFlags(bagIndex, bagSlotFlags[bagIndex]);
|
||||
|
||||
SetBankBagSlotCount(bankSlots);
|
||||
SetCharacterBankTabCount(bankTabs);
|
||||
SetBankAutoSortDisabled(bankBagFlags.HasFlag(BagSlotFlags.DisableAutoSort));
|
||||
for (int bagIndex = 0; bagIndex < bankBagSlotFlags.Length; ++bagIndex)
|
||||
ReplaceAllBankBagSlotFlags(bagIndex, bankBagSlotFlags[bagIndex]);
|
||||
|
||||
SetNativeGender(gender);
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.Inebriation), drunk);
|
||||
@@ -3608,12 +3566,11 @@ namespace Game.Entities
|
||||
// must be before inventory (some items required reputation check)
|
||||
reputationMgr.LoadFromDB(holder.GetResult(PlayerLoginQueryLoad.Reputation));
|
||||
|
||||
_LoadCharacterBankTabSettings(holder.GetResult(PlayerLoginQueryLoad.BankTabSettings));
|
||||
|
||||
_LoadInventory(holder.GetResult(PlayerLoginQueryLoad.Inventory), holder.GetResult(PlayerLoginQueryLoad.Artifacts), holder.GetResult(PlayerLoginQueryLoad.Azerite),
|
||||
holder.GetResult(PlayerLoginQueryLoad.AzeriteMilestonePowers), holder.GetResult(PlayerLoginQueryLoad.AzeriteUnlockedEssences), holder.GetResult(PlayerLoginQueryLoad.AzeriteEmpowered), time_diff);
|
||||
|
||||
if (IsVoidStorageUnlocked())
|
||||
_LoadVoidStorage(holder.GetResult(PlayerLoginQueryLoad.VoidStorage));
|
||||
|
||||
// update items with duration and realtime
|
||||
UpdateItemDuration(time_diff, true);
|
||||
|
||||
@@ -3884,13 +3841,12 @@ namespace Game.Entities
|
||||
foreach (uint bagSlotFlag in m_activePlayerData.BagSlotFlags)
|
||||
stmt.AddValue(index++, bagSlotFlag);
|
||||
stmt.AddValue(index++, GetBankBagSlotCount());
|
||||
stmt.AddValue(index++, GetCharacterBankTabCount());
|
||||
|
||||
inventoryFlags = BagSlotFlags.None;
|
||||
if (m_activePlayerData.BankAutoSortDisabled)
|
||||
inventoryFlags |= BagSlotFlags.DisableAutoSort;
|
||||
stmt.AddValue(index++, (uint)inventoryFlags);
|
||||
foreach (uint bankBagSlotFlag in m_activePlayerData.BankBagSlotFlags)
|
||||
stmt.AddValue(index++, bankBagSlotFlag);
|
||||
|
||||
stmt.AddValue(index++, m_activePlayerData.RestInfo[(int)RestTypes.XP].StateID);
|
||||
stmt.AddValue(index++, m_playerData.PlayerFlags);
|
||||
@@ -4019,13 +3975,12 @@ namespace Game.Entities
|
||||
foreach (uint bagSlotFlag in m_activePlayerData.BagSlotFlags)
|
||||
stmt.AddValue(index++, bagSlotFlag);
|
||||
stmt.AddValue(index++, GetBankBagSlotCount());
|
||||
stmt.AddValue(index++, GetCharacterBankTabCount());
|
||||
|
||||
inventoryFlags = BagSlotFlags.None;
|
||||
if (m_activePlayerData.BankAutoSortDisabled)
|
||||
inventoryFlags |= BagSlotFlags.DisableAutoSort;
|
||||
stmt.AddValue(index++, (uint)inventoryFlags);
|
||||
foreach (uint bankBagSlotFlag in m_activePlayerData.BankBagSlotFlags)
|
||||
stmt.AddValue(index++, bankBagSlotFlag);
|
||||
|
||||
stmt.AddValue(index++, m_activePlayerData.RestInfo[(int)RestTypes.XP].StateID);
|
||||
stmt.AddValue(index++, m_playerData.PlayerFlags);
|
||||
@@ -4179,7 +4134,6 @@ namespace Game.Entities
|
||||
_SaveCustomizations(characterTransaction);
|
||||
_SaveBGData(characterTransaction);
|
||||
_SaveInventory(characterTransaction);
|
||||
_SaveVoidStorage(characterTransaction);
|
||||
_SaveQuestStatus(characterTransaction);
|
||||
_SaveDailyQuestStatus(characterTransaction);
|
||||
_SaveWeeklyQuestStatus(characterTransaction);
|
||||
@@ -4203,6 +4157,7 @@ namespace Game.Entities
|
||||
_SaveCurrency(characterTransaction);
|
||||
_SaveCUFProfiles(characterTransaction);
|
||||
_SavePlayerData(characterTransaction);
|
||||
_SaveCharacterBankTabSettings(characterTransaction);
|
||||
if (_garrison != null)
|
||||
_garrison.SaveToDB(characterTransaction);
|
||||
|
||||
@@ -4717,10 +4672,6 @@ namespace Game.Entities
|
||||
stmt.AddValue(0, guid);
|
||||
trans.Append(stmt);
|
||||
|
||||
stmt = CharacterDatabase.GetPreparedStatement(CharStatements.DEL_CHAR_VOID_STORAGE_ITEM_BY_CHAR_GUID);
|
||||
stmt.AddValue(0, guid);
|
||||
trans.Append(stmt);
|
||||
|
||||
stmt = CharacterDatabase.GetPreparedStatement(CharStatements.DEL_CHAR_FISHINGSTEPS);
|
||||
stmt.AddValue(0, guid);
|
||||
trans.Append(stmt);
|
||||
@@ -4755,6 +4706,18 @@ namespace Game.Entities
|
||||
stmt.AddValue(0, guid);
|
||||
trans.Append(stmt);
|
||||
|
||||
stmt = CharacterDatabase.GetPreparedStatement(CharStatements.DEL_PLAYER_DATA_ELEMENTS_CHARACTER_BY_GUID);
|
||||
stmt.AddValue(0, guid);
|
||||
trans.Append(stmt);
|
||||
|
||||
stmt = CharacterDatabase.GetPreparedStatement(CharStatements.DEL_PLAYER_DATA_FLAGS_CHARACTER_BY_GUID);
|
||||
stmt.AddValue(0, guid);
|
||||
trans.Append(stmt);
|
||||
|
||||
stmt = CharacterDatabase.GetPreparedStatement(CharStatements.DEL_CHARACTER_BANK_TAB_SETTINGS);
|
||||
stmt.AddValue(0, guid);
|
||||
trans.Append(stmt);
|
||||
|
||||
Global.CharacterCacheStorage.DeleteCharacterCacheEntry(playerGuid, name);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -41,7 +41,6 @@ namespace Game.Entities
|
||||
List<ObjectGuid> m_itemSoulboundTradeable = new();
|
||||
List<ObjectGuid> m_refundableItems = new();
|
||||
public List<Item> ItemUpdateQueue = new();
|
||||
VoidStorageItem[] _voidStorageItems = new VoidStorageItem[SharedConst.VoidStorageMaxSlot];
|
||||
Item[] m_items = new Item[(int)PlayerSlots.Count];
|
||||
uint m_WeaponProficiency;
|
||||
uint m_ArmorProficiency;
|
||||
@@ -490,32 +489,6 @@ namespace Game.Entities
|
||||
public uint leftduration;
|
||||
}
|
||||
|
||||
public class VoidStorageItem
|
||||
{
|
||||
public VoidStorageItem(ulong id, uint entry, ObjectGuid creator, uint randomBonusListId, uint fixedScalingLevel, uint artifactKnowledgeLevel, ItemContext context, List<uint> bonuses)
|
||||
{
|
||||
ItemId = id;
|
||||
ItemEntry = entry;
|
||||
CreatorGuid = creator;
|
||||
RandomBonusListId = randomBonusListId;
|
||||
FixedScalingLevel = fixedScalingLevel;
|
||||
ArtifactKnowledgeLevel = artifactKnowledgeLevel;
|
||||
Context = context;
|
||||
|
||||
foreach (var value in bonuses)
|
||||
BonusListIDs.Add(value);
|
||||
}
|
||||
|
||||
public ulong ItemId;
|
||||
public uint ItemEntry;
|
||||
public ObjectGuid CreatorGuid;
|
||||
public uint RandomBonusListId;
|
||||
public uint FixedScalingLevel;
|
||||
public uint ArtifactKnowledgeLevel;
|
||||
public ItemContext Context;
|
||||
public List<uint> BonusListIDs = new();
|
||||
}
|
||||
|
||||
public class EquipmentSetInfo
|
||||
{
|
||||
public EquipmentSetInfo()
|
||||
|
||||
@@ -1449,7 +1449,7 @@ namespace Game.Entities
|
||||
return res; // return latest error if any
|
||||
}
|
||||
|
||||
Item EquipNewItem(ushort pos, uint item, ItemContext context, bool update)
|
||||
public Item EquipNewItem(ushort pos, uint item, ItemContext context, bool update)
|
||||
{
|
||||
Item pItem = Item.CreateItem(item, 1, context, this);
|
||||
if (pItem != null)
|
||||
@@ -2055,12 +2055,6 @@ namespace Game.Entities
|
||||
}
|
||||
}
|
||||
|
||||
if (IsReagentBankPos(dst) && !IsReagentBankUnlocked())
|
||||
{
|
||||
SendEquipError(InventoryResult.ReagentBankLocked, pSrcItem, pDstItem);
|
||||
return;
|
||||
}
|
||||
|
||||
// NOW this is or item move (swap with empty), or swap with another item (including bags in bag possitions)
|
||||
// or swap empty bag with another empty or not empty bag (with items exchange)
|
||||
|
||||
@@ -2094,7 +2088,6 @@ namespace Game.Entities
|
||||
|
||||
RemoveItem(srcbag, srcslot, true);
|
||||
BankItem(dest, pSrcItem, true);
|
||||
if (!IsReagentBankPos(dst))
|
||||
ItemRemovedQuestCheck(pSrcItem.GetEntry(), pSrcItem.GetCount());
|
||||
}
|
||||
else if (IsEquipmentPos(dst))
|
||||
@@ -2738,18 +2731,10 @@ namespace Game.Entities
|
||||
if (slot >= InventorySlots.ItemStart && slot < InventorySlots.ItemStart + GetInventorySlotCount())
|
||||
return true;
|
||||
|
||||
// bank main slots
|
||||
if (slot >= InventorySlots.BankItemStart && slot < InventorySlots.BankItemEnd)
|
||||
return true;
|
||||
|
||||
// bank bag slots
|
||||
if (slot >= InventorySlots.BankBagStart && slot < InventorySlots.BankBagEnd)
|
||||
return true;
|
||||
|
||||
// reagent bank bag slots
|
||||
if (slot >= InventorySlots.ReagentStart && slot < InventorySlots.ReagentEnd)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -4080,8 +4065,6 @@ namespace Game.Entities
|
||||
return true;
|
||||
if (bag >= InventorySlots.ReagentBagStart && bag < InventorySlots.ReagentBagEnd)
|
||||
return true;
|
||||
if (bag == InventorySlots.Bag0 && (slot >= InventorySlots.ReagentStart && slot < InventorySlots.ReagentEnd))
|
||||
return true;
|
||||
if (bag == InventorySlots.Bag0 && (slot >= InventorySlots.ChildEquipmentStart && slot < InventorySlots.ChildEquipmentEnd))
|
||||
return true;
|
||||
return false;
|
||||
@@ -4168,10 +4151,6 @@ namespace Game.Entities
|
||||
// prevent cheating
|
||||
if ((slot >= InventorySlots.BuyBackStart && slot < InventorySlots.BuyBackEnd) || slot >= (byte)PlayerSlots.End)
|
||||
return InventoryResult.WrongBagType;
|
||||
|
||||
// can't store anything else than crafting reagents in Reagent Bank
|
||||
if (IsReagentBankPos(bag, slot) && (!IsReagentBankUnlocked() || !pProto.IsCraftingReagent()))
|
||||
return InventoryResult.WrongBagType;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -4271,14 +4250,10 @@ namespace Game.Entities
|
||||
|
||||
public static bool IsBankPos(byte bag, byte slot)
|
||||
{
|
||||
if (bag == InventorySlots.Bag0 && (slot >= InventorySlots.BankItemStart && slot < InventorySlots.BankItemEnd))
|
||||
return true;
|
||||
if (bag == InventorySlots.Bag0 && (slot >= InventorySlots.BankBagStart && slot < InventorySlots.BankBagEnd))
|
||||
return true;
|
||||
if (bag >= InventorySlots.BankBagStart && bag < InventorySlots.BankBagEnd)
|
||||
return true;
|
||||
if (bag == InventorySlots.Bag0 && (slot >= InventorySlots.ReagentStart && slot < InventorySlots.ReagentEnd))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -4293,12 +4268,6 @@ namespace Game.Entities
|
||||
Cypher.Assert(bag == ItemConst.NullBag && slot == ItemConst.NullSlot); // when reagentBankOnly is true then bag & slot must be hardcoded constants, not client input
|
||||
}
|
||||
|
||||
if ((IsReagentBankPos(bag, slot) || reagentBankOnly) && !IsReagentBankUnlocked())
|
||||
return InventoryResult.ReagentBankLocked;
|
||||
|
||||
byte slotStart = reagentBankOnly ? InventorySlots.ReagentStart : InventorySlots.BankItemStart;
|
||||
byte slotEnd = reagentBankOnly ? InventorySlots.ReagentEnd : InventorySlots.BankItemEnd;
|
||||
|
||||
uint count = pItem.GetCount();
|
||||
|
||||
Log.outDebug(LogFilter.Player, "STORAGE: CanBankItem bag = {0}, slot = {1}, item = {2}, count = {3}", bag, slot, pItem.GetEntry(), count);
|
||||
@@ -4334,7 +4303,7 @@ namespace Game.Entities
|
||||
if (!pItem.IsBag())
|
||||
return InventoryResult.WrongSlot;
|
||||
|
||||
if (slot - InventorySlots.BagStart >= GetBankBagSlotCount())
|
||||
if (slot - InventorySlots.BagStart >= GetCharacterBankTabCount())
|
||||
return InventoryResult.NoBankSlot;
|
||||
|
||||
res = CanUseItem(pItem, not_loading);
|
||||
@@ -4363,12 +4332,7 @@ namespace Game.Entities
|
||||
{
|
||||
if (bag == InventorySlots.Bag0)
|
||||
{
|
||||
res = CanStoreItem_InInventorySlots(slotStart, slotEnd, dest, pProto, ref count, true, pItem, bag, slot);
|
||||
if (res != InventoryResult.Ok)
|
||||
return res;
|
||||
|
||||
if (count == 0)
|
||||
return InventoryResult.Ok;
|
||||
return InventoryResult.WrongSlot; // TODO: check if INVENTORY_SLOT_BAG_0 condition is neccessary
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -4387,12 +4351,7 @@ namespace Game.Entities
|
||||
// search free slot in bag
|
||||
if (bag == InventorySlots.Bag0)
|
||||
{
|
||||
res = CanStoreItem_InInventorySlots(slotStart, slotEnd, dest, pProto, ref count, false, pItem, bag, slot);
|
||||
if (res != InventoryResult.Ok)
|
||||
return res;
|
||||
|
||||
if (count == 0)
|
||||
return InventoryResult.Ok;
|
||||
return InventoryResult.WrongSlot; // TODO: check if INVENTORY_SLOT_BAG_0 condition is neccessary
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -4413,34 +4372,13 @@ namespace Game.Entities
|
||||
// search stack for merge to
|
||||
if (pProto.GetMaxStackSize() != 1)
|
||||
{
|
||||
// in slots
|
||||
res = CanStoreItem_InInventorySlots(slotStart, slotEnd, dest, pProto, ref count, true, pItem, bag, slot);
|
||||
if (res != InventoryResult.Ok)
|
||||
return res;
|
||||
|
||||
if (count == 0)
|
||||
return InventoryResult.Ok;
|
||||
|
||||
// don't try to store reagents anywhere else than in Reagent Bank if we're on it
|
||||
if (!reagentBankOnly)
|
||||
{
|
||||
// in special bags
|
||||
if (pProto.GetBagFamily() != BagFamilyMask.None)
|
||||
{
|
||||
for (byte i = InventorySlots.BankBagStart; i < InventorySlots.BankBagEnd; i++)
|
||||
{
|
||||
res = CanStoreItem_InBag(i, dest, pProto, ref count, true, false, pItem, bag, slot);
|
||||
if (res != InventoryResult.Ok)
|
||||
continue;
|
||||
|
||||
if (count == 0)
|
||||
return InventoryResult.Ok;
|
||||
}
|
||||
}
|
||||
|
||||
// in regular bags
|
||||
for (byte i = InventorySlots.BankBagStart; i < InventorySlots.BankBagEnd; i++)
|
||||
{
|
||||
// only consider tabs marked as reagents if requested
|
||||
if (reagentBankOnly && (m_activePlayerData.CharacterBankTabSettings[i - InventorySlots.BankBagStart].DepositFlags & (int)BagSlotFlags.PriorityReagents) == 0)
|
||||
continue;
|
||||
|
||||
res = CanStoreItem_InBag(i, dest, pProto, ref count, true, true, pItem, bag, slot);
|
||||
if (res != InventoryResult.Ok)
|
||||
continue;
|
||||
@@ -4449,35 +4387,14 @@ namespace Game.Entities
|
||||
return InventoryResult.Ok;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// search free place in special bag
|
||||
if (!reagentBankOnly && pProto.GetBagFamily() != BagFamilyMask.None)
|
||||
{
|
||||
// search free space in regular bags
|
||||
for (byte i = InventorySlots.BankBagStart; i < InventorySlots.BankBagEnd; i++)
|
||||
{
|
||||
res = CanStoreItem_InBag(i, dest, pProto, ref count, false, false, pItem, bag, slot);
|
||||
if (res != InventoryResult.Ok)
|
||||
// only consider tabs marked as reagents if requested
|
||||
if (reagentBankOnly && (m_activePlayerData.CharacterBankTabSettings[i - InventorySlots.BankBagStart].DepositFlags & (int)BagSlotFlags.PriorityReagents) == 0)
|
||||
continue;
|
||||
|
||||
if (count == 0)
|
||||
return InventoryResult.Ok;
|
||||
}
|
||||
}
|
||||
|
||||
// search free space
|
||||
res = CanStoreItem_InInventorySlots(slotStart, slotEnd, dest, pProto, ref count, false, pItem, bag, slot);
|
||||
if (res != InventoryResult.Ok)
|
||||
return res;
|
||||
|
||||
if (count == 0)
|
||||
return InventoryResult.Ok;
|
||||
|
||||
// search free space in regular bags (don't try to store reagents anywhere else than in Reagent Bank if we're on it)
|
||||
if (!reagentBankOnly)
|
||||
{
|
||||
for (byte i = InventorySlots.BankBagStart; i < InventorySlots.BankBagEnd; i++)
|
||||
{
|
||||
res = CanStoreItem_InBag(i, dest, pProto, ref count, false, true, pItem, bag, slot);
|
||||
if (res != InventoryResult.Ok)
|
||||
continue;
|
||||
@@ -4485,7 +4402,7 @@ namespace Game.Entities
|
||||
if (count == 0)
|
||||
return InventoryResult.Ok;
|
||||
}
|
||||
}
|
||||
|
||||
return reagentBankOnly ? InventoryResult.ReagentBankFull : InventoryResult.BankFull;
|
||||
}
|
||||
|
||||
@@ -4530,10 +4447,6 @@ namespace Game.Entities
|
||||
|
||||
if (location.HasFlag(ItemSearchLocation.Bank))
|
||||
{
|
||||
for (byte i = InventorySlots.BankItemStart; i < InventorySlots.BankItemEnd; ++i)
|
||||
if (GetItemByPos(InventorySlots.Bag0, i) == null)
|
||||
++freeSlotCount;
|
||||
|
||||
for (byte i = InventorySlots.BankBagStart; i < InventorySlots.BankBagEnd; ++i)
|
||||
{
|
||||
Bag bag = GetBagByPos(i);
|
||||
@@ -4556,25 +4469,11 @@ namespace Game.Entities
|
||||
if (bag.GetItemByPos(j) == null)
|
||||
++freeSlotCount;
|
||||
}
|
||||
|
||||
for (byte i = InventorySlots.ReagentStart; i < InventorySlots.ReagentEnd; ++i)
|
||||
if (GetItemByPos(InventorySlots.Bag0, i) == null)
|
||||
++freeSlotCount;
|
||||
}
|
||||
|
||||
return freeSlotCount;
|
||||
}
|
||||
|
||||
//Reagent
|
||||
public static bool IsReagentBankPos(ushort pos) { return IsReagentBankPos((byte)(pos >> 8), (byte)(pos & 255)); }
|
||||
|
||||
public static bool IsReagentBankPos(byte bag, byte slot)
|
||||
{
|
||||
if (bag == InventorySlots.Bag0 && (slot >= InventorySlots.ReagentStart && slot < InventorySlots.ReagentEnd))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
//Bags
|
||||
public Bag GetBagByPos(byte bag)
|
||||
{
|
||||
@@ -4898,7 +4797,7 @@ namespace Game.Entities
|
||||
return ItemConst.NullSlot;
|
||||
}
|
||||
|
||||
InventoryResult CanEquipNewItem(byte slot, out ushort dest, uint item, bool swap)
|
||||
public InventoryResult CanEquipNewItem(byte slot, out ushort dest, uint item, bool swap)
|
||||
{
|
||||
dest = 0;
|
||||
Item pItem = Item.CreateItem(item, 1, ItemContext.None, this);
|
||||
@@ -5253,6 +5152,14 @@ namespace Game.Entities
|
||||
//Child
|
||||
public static bool IsChildEquipmentPos(ushort pos) { return IsChildEquipmentPos((byte)(pos >> 8), (byte)(pos & 255)); }
|
||||
|
||||
public static bool IsAccountBankPos(ushort pos) { return IsBankPos((byte)(pos >> 8), (byte)(pos & 255)); }
|
||||
public static bool IsAccountBankPos(byte bag, byte slot)
|
||||
{
|
||||
if (bag >= (int)AccountBankBagSlots.Start && bag < (int)AccountBankBagSlots.End)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
//Artifact
|
||||
void ApplyArtifactPowers(Item item, bool apply)
|
||||
{
|
||||
@@ -5776,34 +5683,6 @@ namespace Game.Entities
|
||||
}
|
||||
}
|
||||
|
||||
// in bank
|
||||
for (byte i = InventorySlots.BankItemStart; i < InventorySlots.BankItemEnd; i++)
|
||||
{
|
||||
Item item = GetItemByPos(InventorySlots.Bag0, i);
|
||||
if (item != null)
|
||||
{
|
||||
if (item.GetEntry() == itemEntry && !item.IsInTrade())
|
||||
{
|
||||
if (item.GetCount() + remcount <= count)
|
||||
{
|
||||
remcount += item.GetCount();
|
||||
DestroyItem(InventorySlots.Bag0, i, update);
|
||||
if (remcount >= count)
|
||||
return remcount;
|
||||
}
|
||||
else
|
||||
{
|
||||
item.SetCount(item.GetCount() - count + remcount);
|
||||
ItemRemovedQuestCheck(item.GetEntry(), count - remcount);
|
||||
if (IsInWorld && update)
|
||||
item.SendUpdateToPlayer(this);
|
||||
item.SetState(ItemUpdateState.Changed, this);
|
||||
return count;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// in bank bags
|
||||
for (byte i = InventorySlots.BankBagStart; i < InventorySlots.BankBagEnd; i++)
|
||||
{
|
||||
@@ -5872,35 +5751,6 @@ namespace Game.Entities
|
||||
}
|
||||
}
|
||||
|
||||
for (byte i = InventorySlots.ReagentStart; i < InventorySlots.ReagentEnd; ++i)
|
||||
{
|
||||
Item item = GetItemByPos(InventorySlots.Bag0, i);
|
||||
if (item != null)
|
||||
{
|
||||
if (item.GetEntry() == itemEntry && !item.IsInTrade())
|
||||
{
|
||||
if (item.GetCount() + remcount <= count)
|
||||
{
|
||||
// all keys can be unequipped
|
||||
remcount += item.GetCount();
|
||||
DestroyItem(InventorySlots.Bag0, i, update);
|
||||
|
||||
if (remcount >= count)
|
||||
return remcount;
|
||||
}
|
||||
else
|
||||
{
|
||||
item.SetCount(item.GetCount() - count + remcount);
|
||||
ItemRemovedQuestCheck(item.GetEntry(), count - remcount);
|
||||
if (IsInWorld && update)
|
||||
item.SendUpdateToPlayer(this);
|
||||
item.SetState(ItemUpdateState.Changed, this);
|
||||
return count;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (byte i = InventorySlots.ChildEquipmentStart; i < InventorySlots.ChildEquipmentEnd; ++i)
|
||||
{
|
||||
Item item = GetItemByPos(InventorySlots.Bag0, i);
|
||||
@@ -6014,6 +5864,27 @@ namespace Game.Entities
|
||||
|
||||
public byte GetBankBagSlotCount() { return m_activePlayerData.NumBankSlots; }
|
||||
public void SetBankBagSlotCount(byte count) { SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.NumBankSlots), count); }
|
||||
public byte GetCharacterBankTabCount() { return m_activePlayerData.NumCharacterBankTabs; }
|
||||
public void SetCharacterBankTabCount(byte count) { SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.NumCharacterBankTabs), count); }
|
||||
public byte GetAccountBankTabCount() { return m_activePlayerData.NumAccountBankTabs; }
|
||||
public void SetAccountBankTabCount(byte count) { SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.NumAccountBankTabs), count); }
|
||||
public void SetCharacterBankTabSettings(uint tabId, string name, string icon, string description, BagSlotFlags depositFlags)
|
||||
{
|
||||
var setter = m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.CharacterBankTabSettings, (int)tabId);
|
||||
SetBankTabSettings(setter, name, icon, description, depositFlags);
|
||||
}
|
||||
public void SetAccountBankTabSettings(uint tabId, string name, string icon, string description, BagSlotFlags depositFlags)
|
||||
{
|
||||
var setter = m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.AccountBankTabSettings, (int)tabId);
|
||||
SetBankTabSettings(setter, name, icon, description, depositFlags);
|
||||
}
|
||||
public void SetBankTabSettings(BankTabSettings bantTabSettings, string name, string icon, string description, BagSlotFlags depositFlags)
|
||||
{
|
||||
SetUpdateFieldValue(bantTabSettings.ModifyValue(bantTabSettings.Name), name);
|
||||
SetUpdateFieldValue(bantTabSettings.ModifyValue(bantTabSettings.Icon), icon);
|
||||
SetUpdateFieldValue(bantTabSettings.ModifyValue(bantTabSettings.Description), description);
|
||||
SetUpdateFieldValue(bantTabSettings.ModifyValue(bantTabSettings.DepositFlags), (int)depositFlags);
|
||||
}
|
||||
|
||||
public bool IsBackpackAutoSortDisabled() { return m_activePlayerData.BackpackAutoSortDisabled; }
|
||||
public void SetBackpackAutoSortDisabled(bool disabled) { SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.BackpackAutoSortDisabled), disabled); }
|
||||
@@ -6025,10 +5896,6 @@ namespace Game.Entities
|
||||
public void SetBagSlotFlag(int bagIndex, BagSlotFlags flags) { SetUpdateFieldFlagValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.BagSlotFlags, bagIndex), (uint)flags); }
|
||||
public void RemoveBagSlotFlag(int bagIndex, BagSlotFlags flags) { RemoveUpdateFieldFlagValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.BagSlotFlags, bagIndex), (uint)flags); }
|
||||
public void ReplaceAllBagSlotFlags(int bagIndex, BagSlotFlags flags) { SetUpdateFieldValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.BagSlotFlags, bagIndex), (uint)flags); }
|
||||
public BagSlotFlags GetBankBagSlotFlags(int bagIndex) { return (BagSlotFlags)m_activePlayerData.BankBagSlotFlags[bagIndex]; }
|
||||
public void SetBankBagSlotFlag(int bagIndex, BagSlotFlags flags) { SetUpdateFieldFlagValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.BankBagSlotFlags, bagIndex), (uint)flags); }
|
||||
public void RemoveBankBagSlotFlag(int bagIndex, BagSlotFlags flags) { RemoveUpdateFieldFlagValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.BankBagSlotFlags, bagIndex), (uint)flags); }
|
||||
public void ReplaceAllBankBagSlotFlags(int bagIndex, BagSlotFlags flags) { SetUpdateFieldValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.BankBagSlotFlags, bagIndex), (uint)flags); }
|
||||
|
||||
//Loot
|
||||
public ObjectGuid GetLootGUID() { return m_playerData.LootTargetGUID; }
|
||||
@@ -6308,91 +6175,6 @@ namespace Game.Entities
|
||||
}
|
||||
}
|
||||
|
||||
//Void Storage
|
||||
public bool IsVoidStorageUnlocked() { return HasPlayerFlag(PlayerFlags.VoidUnlocked); }
|
||||
public void UnlockVoidStorage() { SetPlayerFlag(PlayerFlags.VoidUnlocked); }
|
||||
public void LockVoidStorage() { RemovePlayerFlag(PlayerFlags.VoidUnlocked); }
|
||||
|
||||
public byte GetNextVoidStorageFreeSlot()
|
||||
{
|
||||
for (byte i = 0; i < SharedConst.VoidStorageMaxSlot; ++i)
|
||||
if (_voidStorageItems[i] == null) // unused item
|
||||
return i;
|
||||
|
||||
return SharedConst.VoidStorageMaxSlot;
|
||||
}
|
||||
|
||||
public byte GetNumOfVoidStorageFreeSlots()
|
||||
{
|
||||
byte count = 0;
|
||||
|
||||
for (byte i = 0; i < SharedConst.VoidStorageMaxSlot; ++i)
|
||||
if (_voidStorageItems[i] == null)
|
||||
count++;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
public byte AddVoidStorageItem(VoidStorageItem item)
|
||||
{
|
||||
byte slot = GetNextVoidStorageFreeSlot();
|
||||
|
||||
if (slot >= SharedConst.VoidStorageMaxSlot)
|
||||
{
|
||||
GetSession().SendVoidStorageTransferResult(VoidTransferError.Full);
|
||||
return 255;
|
||||
}
|
||||
|
||||
_voidStorageItems[slot] = item;
|
||||
return slot;
|
||||
}
|
||||
|
||||
public void DeleteVoidStorageItem(byte slot)
|
||||
{
|
||||
if (slot >= SharedConst.VoidStorageMaxSlot)
|
||||
{
|
||||
GetSession().SendVoidStorageTransferResult(VoidTransferError.InternalError1);
|
||||
return;
|
||||
}
|
||||
|
||||
_voidStorageItems[slot] = null;
|
||||
}
|
||||
|
||||
public bool SwapVoidStorageItem(byte oldSlot, byte newSlot)
|
||||
{
|
||||
if (oldSlot >= SharedConst.VoidStorageMaxSlot || newSlot >= SharedConst.VoidStorageMaxSlot || oldSlot == newSlot)
|
||||
return false;
|
||||
|
||||
_voidStorageItems.Swap(newSlot, oldSlot);
|
||||
return true;
|
||||
}
|
||||
|
||||
public VoidStorageItem GetVoidStorageItem(byte slot)
|
||||
{
|
||||
if (slot >= SharedConst.VoidStorageMaxSlot)
|
||||
{
|
||||
GetSession().SendVoidStorageTransferResult(VoidTransferError.InternalError1);
|
||||
return null;
|
||||
}
|
||||
|
||||
return _voidStorageItems[slot];
|
||||
}
|
||||
|
||||
public VoidStorageItem GetVoidStorageItem(ulong id, out byte slot)
|
||||
{
|
||||
slot = 0;
|
||||
for (byte i = 0; i < SharedConst.VoidStorageMaxSlot; ++i)
|
||||
{
|
||||
if (_voidStorageItems[i] != null && _voidStorageItems[i].ItemId == id)
|
||||
{
|
||||
slot = i;
|
||||
return _voidStorageItems[i];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
//Misc
|
||||
void UpdateItemLevelAreaBasedScaling()
|
||||
{
|
||||
@@ -6469,14 +6251,6 @@ namespace Game.Entities
|
||||
|
||||
if (location.HasAnyFlag(ItemSearchLocation.Bank))
|
||||
{
|
||||
for (byte i = InventorySlots.BankItemStart; i < InventorySlots.BankItemEnd; ++i)
|
||||
{
|
||||
Item item = GetItemByPos(InventorySlots.Bag0, i);
|
||||
if (item != null)
|
||||
if (!callback(item))
|
||||
return false;
|
||||
}
|
||||
|
||||
for (byte i = InventorySlots.BankBagStart; i < InventorySlots.BankBagEnd; ++i)
|
||||
{
|
||||
Bag bag = GetBagByPos(i);
|
||||
@@ -6509,14 +6283,6 @@ namespace Game.Entities
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (byte i = InventorySlots.ReagentStart; i < InventorySlots.ReagentEnd; ++i)
|
||||
{
|
||||
Item item = GetItemByPos(InventorySlots.Bag0, i);
|
||||
if (item != null)
|
||||
if (!callback(item))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -365,9 +365,20 @@ namespace Game.Entities
|
||||
&& ((TraitCombatConfigFlags)(int)traitConfig.CombatConfigFlags & TraitCombatConfigFlags.ActiveForSpec) != TraitCombatConfigFlags.None;
|
||||
});
|
||||
if (specTraitConfigIndex >= 0)
|
||||
SetActiveCombatTraitConfigID(m_activePlayerData.TraitConfigs[specTraitConfigIndex].ID);
|
||||
{
|
||||
TraitConfig activeTraitConfig = m_activePlayerData.TraitConfigs[specTraitConfigIndex];
|
||||
SetActiveCombatTraitConfigID(activeTraitConfig.ID);
|
||||
int activeSubTree = activeTraitConfig.SubTrees.FindIndexIf(subTree => subTree.Active != 0);
|
||||
if (activeSubTree >= 0)
|
||||
SetCurrentCombatTraitConfigSubTreeID(activeTraitConfig.SubTrees[activeSubTree].TraitSubTreeID);
|
||||
else
|
||||
SetCurrentCombatTraitConfigSubTreeID(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetActiveCombatTraitConfigID(0);
|
||||
SetCurrentCombatTraitConfigSubTreeID(0);
|
||||
}
|
||||
|
||||
foreach (var talentInfo in CliDB.TalentStorage.Values)
|
||||
{
|
||||
@@ -1136,6 +1147,17 @@ namespace Game.Entities
|
||||
}
|
||||
}
|
||||
|
||||
if (applyTraits)
|
||||
{
|
||||
int activeSubTree = editedConfig.SubTrees.FindIndexIf(subTree => subTree.Active != 0);
|
||||
if (activeSubTree >= 0)
|
||||
SetCurrentCombatTraitConfigSubTreeID(editedConfig.SubTrees[activeSubTree].TraitSubTreeID);
|
||||
else
|
||||
SetCurrentCombatTraitConfigSubTreeID(0);
|
||||
|
||||
Item.UpdateItemSetAuras(this, false);
|
||||
}
|
||||
|
||||
m_traitConfigStates[editedConfigId] = PlayerSpellState.Changed;
|
||||
}
|
||||
|
||||
|
||||
@@ -143,9 +143,6 @@ namespace Game.Entities
|
||||
|
||||
_cinematicMgr.Dispose();
|
||||
|
||||
for (byte i = 0; i < SharedConst.VoidStorageMaxSlot; ++i)
|
||||
_voidStorageItems[i] = null;
|
||||
|
||||
ClearResurrectRequestData();
|
||||
|
||||
WorldMgr.DecreasePlayerCount();
|
||||
@@ -599,21 +596,8 @@ namespace Game.Entities
|
||||
|
||||
if (target == this)
|
||||
{
|
||||
for (byte i = EquipmentSlot.Start; i < InventorySlots.BankBagEnd; ++i)
|
||||
{
|
||||
if (m_items[i] == null)
|
||||
continue;
|
||||
|
||||
m_items[i].DestroyForPlayer(target);
|
||||
}
|
||||
|
||||
for (byte i = InventorySlots.ReagentStart; i < InventorySlots.ChildEquipmentEnd; ++i)
|
||||
{
|
||||
if (m_items[i] == null)
|
||||
continue;
|
||||
|
||||
m_items[i].DestroyForPlayer(target);
|
||||
}
|
||||
foreach (Item item in m_items)
|
||||
item?.DestroyForPlayer(target);
|
||||
}
|
||||
}
|
||||
public override void CleanupsBeforeDelete(bool finalCleanup = true)
|
||||
@@ -7697,6 +7681,7 @@ namespace Game.Entities
|
||||
}
|
||||
|
||||
void SetActiveCombatTraitConfigID(int traitConfigId) { SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.ActiveCombatTraitConfigID), (uint)traitConfigId); }
|
||||
void SetCurrentCombatTraitConfigSubTreeID(int traitSubTreeId) { SetUpdateFieldValue(m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.CurrentCombatTraitConfigSubTreeID), traitSubTreeId); }
|
||||
|
||||
void InitPrimaryProfessions()
|
||||
{
|
||||
|
||||
@@ -458,6 +458,8 @@ namespace Game.Entities
|
||||
public ObjectGuid castId;
|
||||
public SpellInfo Spell;
|
||||
public SpellCastVisual SpellVisual;
|
||||
public uint StartTimeMs;
|
||||
public uint Duration;
|
||||
public uint damage;
|
||||
public uint originalDamage;
|
||||
public SpellSchoolMask schoolMask;
|
||||
|
||||
@@ -2458,7 +2458,7 @@ namespace Game.Entities
|
||||
{
|
||||
SetAnimTier setAnimTier = new();
|
||||
setAnimTier.Unit = GetGUID();
|
||||
setAnimTier.Tier = (int)animTier;
|
||||
setAnimTier.Tier = (byte)animTier;
|
||||
SendMessageToSet(setAnimTier, true);
|
||||
}
|
||||
}
|
||||
@@ -2486,6 +2486,13 @@ namespace Game.Entities
|
||||
RemoveDynamicUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.ChannelObjects), index);
|
||||
}
|
||||
|
||||
public void SetChannelSpellData(uint startTimeMs, uint durationMs)
|
||||
{
|
||||
UnitChannel channelData = m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.ChannelData);
|
||||
SetUpdateFieldValue(ref channelData.StartTimeMs, startTimeMs);
|
||||
SetUpdateFieldValue(ref channelData.Duration, durationMs);
|
||||
}
|
||||
|
||||
public sbyte GetSpellEmpowerStage() { return m_unitData.SpellEmpowerStage; }
|
||||
|
||||
public void SetSpellEmpowerStage(sbyte stage) { SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.SpellEmpowerStage), stage); }
|
||||
|
||||
@@ -2722,11 +2722,11 @@ namespace Game
|
||||
|
||||
// 0 1 2 3 4 5
|
||||
SQLResult result = DB.World.Query("SELECT Entry, DifficultyID, LevelScalingDeltaMin, LevelScalingDeltaMax, ContentTuningID, HealthScalingExpansion, " +
|
||||
//6 7 8 9 10 11 12
|
||||
"HealthModifier, ManaModifier, ArmorModifier, DamageModifier, CreatureDifficultyID, TypeFlags, TypeFlags2, " +
|
||||
//13 14 15 16 17
|
||||
// 6 7 8 9 10 11 12 13
|
||||
"HealthModifier, ManaModifier, ArmorModifier, DamageModifier, CreatureDifficultyID, TypeFlags, TypeFlags2, TypeFlags3, " +
|
||||
// 14 15 16 17 18
|
||||
"LootID, PickPocketLootID, SkinLootID, GoldMin, GoldMax," +
|
||||
//18 19 20 21 22 23 24 25
|
||||
// 19 20 21 22 23 24 25 26
|
||||
"StaticFlags1, StaticFlags2, StaticFlags3, StaticFlags4, StaticFlags5, StaticFlags6, StaticFlags7, StaticFlags8 " +
|
||||
"FROM creature_template_difficulty ORDER BY Entry");
|
||||
if (result.IsEmpty())
|
||||
@@ -2760,12 +2760,13 @@ namespace Game
|
||||
creatureDifficulty.CreatureDifficultyID = result.Read<int>(10);
|
||||
creatureDifficulty.TypeFlags = (CreatureTypeFlags)result.Read<uint>(11);
|
||||
creatureDifficulty.TypeFlags2 = result.Read<uint>(12);
|
||||
creatureDifficulty.LootID = result.Read<uint>(13);
|
||||
creatureDifficulty.PickPocketLootID = result.Read<uint>(14);
|
||||
creatureDifficulty.SkinLootID = result.Read<uint>(15);
|
||||
creatureDifficulty.GoldMin = result.Read<uint>(16);
|
||||
creatureDifficulty.GoldMax = result.Read<uint>(17);
|
||||
creatureDifficulty.StaticFlags = new(result.Read<uint>(18), result.Read<uint>(19), result.Read<uint>(20), result.Read<uint>(21), result.Read<uint>(22), result.Read<uint>(23), result.Read<uint>(24), result.Read<uint>(25));
|
||||
creatureDifficulty.TypeFlags3 = result.Read<uint>(13);
|
||||
creatureDifficulty.LootID = result.Read<uint>(14);
|
||||
creatureDifficulty.PickPocketLootID = result.Read<uint>(15);
|
||||
creatureDifficulty.SkinLootID = result.Read<uint>(16);
|
||||
creatureDifficulty.GoldMin = result.Read<uint>(17);
|
||||
creatureDifficulty.GoldMax = result.Read<uint>(18);
|
||||
creatureDifficulty.StaticFlags = new(result.Read<uint>(19), result.Read<uint>(20), result.Read<uint>(21), result.Read<uint>(22), result.Read<uint>(23), result.Read<uint>(24), result.Read<uint>(25), result.Read<uint>(26));
|
||||
|
||||
// TODO: Check if this still applies
|
||||
creatureDifficulty.DamageModifier *= Creature.GetDamageMod(template.Classification);
|
||||
@@ -10997,10 +10998,6 @@ namespace Game
|
||||
if (!result.IsEmpty())
|
||||
Global.GuildMgr.SetNextGuildId(result.Read<uint>(0) + 1);
|
||||
|
||||
result = DB.Characters.Query("SELECT MAX(itemId) from character_void_storage");
|
||||
if (!result.IsEmpty())
|
||||
_voidItemId = result.Read<ulong>(0) + 1;
|
||||
|
||||
result = DB.World.Query("SELECT MAX(guid) FROM creature");
|
||||
if (!result.IsEmpty())
|
||||
_creatureSpawnId = result.Read<ulong>(0) + 1;
|
||||
@@ -11036,15 +11033,6 @@ namespace Game
|
||||
}
|
||||
return _mailId++;
|
||||
}
|
||||
public ulong GenerateVoidStorageItemId()
|
||||
{
|
||||
if (_voidItemId >= 0xFFFFFFFFFFFFFFFE)
|
||||
{
|
||||
Log.outError(LogFilter.Misc, "_voidItemId overflow!! Can't continue, shutting down server. ");
|
||||
Global.WorldMgr.StopNow(ShutdownExitCode.Error);
|
||||
}
|
||||
return _voidItemId++;
|
||||
}
|
||||
public ulong GenerateCreatureSpawnId()
|
||||
{
|
||||
if (_creatureSpawnId >= 0xFFFFFFFFFFFFFFFE)
|
||||
@@ -11789,7 +11777,6 @@ namespace Game
|
||||
uint _hiPetNumber;
|
||||
ulong _creatureSpawnId;
|
||||
ulong _gameObjectSpawnId;
|
||||
ulong _voidItemId;
|
||||
uint[] _playerXPperLevel;
|
||||
Dictionary<uint, uint> _baseXPTable = new();
|
||||
#endregion
|
||||
|
||||
@@ -520,7 +520,7 @@ namespace Game.Guilds
|
||||
SQLTransaction trans = new SQLTransaction();
|
||||
|
||||
// Remove money from bank
|
||||
ulong tabCost = GetGuildBankTabPrice(tabId) * MoneyConstants.Gold;
|
||||
ulong tabCost = GetGuildBankTabPrice(tabId);
|
||||
if (tabCost != 0 && !_ModifyBankMoney(trans, tabCost, false)) // Should not happen, this is checked by client
|
||||
return;
|
||||
|
||||
@@ -2538,17 +2538,11 @@ namespace Game.Guilds
|
||||
|
||||
ulong GetGuildBankTabPrice(byte tabId)
|
||||
{
|
||||
// these prices are in gold units, not copper
|
||||
switch (tabId)
|
||||
{
|
||||
case 0: return 100;
|
||||
case 1: return 250;
|
||||
case 2: return 500;
|
||||
case 3: return 1000;
|
||||
case 4: return 2500;
|
||||
case 5: return 5000;
|
||||
default: return 0;
|
||||
}
|
||||
var bankTab = CliDB.BankTabStorage.FirstOrDefault(bankTab => bankTab.Value.BankType == (int)BankType.Guild && bankTab.Value.OrderIndex == tabId).Value;
|
||||
if (bankTab != null)
|
||||
return bankTab.Cost;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static void SendCommandResult(WorldSession session, GuildCommandType type, GuildCommandError errCode, string param = "")
|
||||
|
||||
@@ -90,7 +90,6 @@ namespace Game
|
||||
features.BpayStoreAvailable = false;
|
||||
features.BpayStoreDisabledByParentalControls = false;
|
||||
features.CharUndeleteEnabled = WorldConfig.GetBoolValue(WorldCfg.FeatureSystemCharacterUndeleteEnabled);
|
||||
features.BpayStoreEnabled = WorldConfig.GetBoolValue(WorldCfg.FeatureSystemBpayStoreEnabled);
|
||||
features.MaxCharactersOnThisRealm = WorldConfig.GetIntValue(WorldCfg.CharactersPerRealm);
|
||||
features.MinimumExpansionLevel = (int)Expansion.Classic;
|
||||
features.MaximumExpansionLevel = WorldConfig.GetIntValue(WorldCfg.Expansion);
|
||||
|
||||
@@ -7,6 +7,7 @@ using Game.Entities;
|
||||
using Game.Networking;
|
||||
using Game.Networking.Packets;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Game
|
||||
{
|
||||
@@ -127,65 +128,121 @@ namespace Game
|
||||
}
|
||||
}
|
||||
|
||||
[WorldPacketHandler(ClientOpcodes.BuyBankSlot, Processing = PacketProcessing.Inplace)]
|
||||
void HandleBuyBankSlot(BuyBankSlot packet)
|
||||
[WorldPacketHandler(ClientOpcodes.BuyAccountBankTab)]
|
||||
void HandleBuyBankTab(BuyBankTab buyBankTab)
|
||||
{
|
||||
if (!CanUseBank(packet.Guid))
|
||||
if (!CanUseBank(buyBankTab.Banker))
|
||||
{
|
||||
Log.outDebug(LogFilter.Network, "WORLD: HandleBuyBankSlot - {0} not found or you can't interact with him.", packet.Guid.ToString());
|
||||
Log.outDebug(LogFilter.Network, $"WorldSession::HandleBuyBankTab {_player.GetGUID()} - Banker {buyBankTab.Banker} not found or can't interact with him.");
|
||||
return;
|
||||
}
|
||||
|
||||
uint slot = GetPlayer().GetBankBagSlotCount();
|
||||
if (buyBankTab.BankType != BankType.Character)
|
||||
{
|
||||
Log.outDebug(LogFilter.Network, $"WorldSession::HandleBuyBankTab {_player.GetGUID()} - Bank type {buyBankTab.BankType} is not supported.");
|
||||
return;
|
||||
}
|
||||
|
||||
uint itemId = 0;
|
||||
byte slot = 0;
|
||||
byte inventorySlot = 0;
|
||||
|
||||
switch (buyBankTab.BankType)
|
||||
{
|
||||
case BankType.Character:
|
||||
itemId = 242709;
|
||||
slot = _player.GetCharacterBankTabCount();
|
||||
inventorySlot = InventorySlots.BankBagStart;
|
||||
break;
|
||||
case BankType.Account:
|
||||
itemId = 208392;
|
||||
slot = _player.GetAccountBankTabCount();
|
||||
inventorySlot = (byte)AccountBankBagSlots.Start;
|
||||
break;
|
||||
default:
|
||||
Log.outDebug(LogFilter.Network, $"WorldSession::HandleBuyBankTab {_player.GetGUID()} - Bank type {buyBankTab.BankType} is not supported.");
|
||||
return;
|
||||
}
|
||||
// next slot
|
||||
++slot;
|
||||
|
||||
BankBagSlotPricesRecord slotEntry = CliDB.BankBagSlotPricesStorage.LookupByKey(slot);
|
||||
if (slotEntry == null)
|
||||
var bankTab = CliDB.BankTabStorage.FirstOrDefault(record => record.Value.BankType == (byte)buyBankTab.BankType && record.Value.OrderIndex == slot).Value;
|
||||
if (bankTab == null)
|
||||
return;
|
||||
|
||||
uint price = slotEntry.Cost;
|
||||
if (!GetPlayer().HasEnoughMoney(price))
|
||||
return;
|
||||
|
||||
GetPlayer().SetBankBagSlotCount((byte)slot);
|
||||
GetPlayer().ModifyMoney(-price);
|
||||
GetPlayer().UpdateCriteria(CriteriaType.BankSlotsPurchased);
|
||||
}
|
||||
|
||||
[WorldPacketHandler(ClientOpcodes.BuyReagentBank)]
|
||||
void HandleBuyReagentBank(ReagentBank reagentBank)
|
||||
{
|
||||
if (!CanUseBank(reagentBank.Banker))
|
||||
{
|
||||
Log.outDebug(LogFilter.Network, $"WORLD: HandleBuyReagentBankOpcode - {reagentBank.Banker} not found or you can't interact with him.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (_player.IsReagentBankUnlocked())
|
||||
{
|
||||
Log.outDebug(LogFilter.Network, $"WORLD: HandleBuyReagentBankOpcode - Player ({_player.GetGUID()}, name: {_player.GetName()}) tried to unlock reagent bank a 2nd time.");
|
||||
return;
|
||||
}
|
||||
|
||||
long price = 100 * MoneyConstants.Gold;
|
||||
|
||||
ulong price = bankTab.Cost;
|
||||
if (!_player.HasEnoughMoney(price))
|
||||
return;
|
||||
|
||||
InventoryResult msg = _player.CanEquipNewItem(inventorySlot, out ushort inventoryPos, itemId, false);
|
||||
if (msg != InventoryResult.Ok)
|
||||
{
|
||||
Log.outDebug(LogFilter.Network, $"WORLD: HandleBuyReagentBankOpcode - Player ({_player.GetGUID()}, name: {_player.GetName()}) without enough gold.");
|
||||
_player.SendEquipError(msg, null, null, itemId);
|
||||
return;
|
||||
}
|
||||
|
||||
_player.ModifyMoney(-price);
|
||||
_player.UnlockReagentBank();
|
||||
Item bag = _player.EquipNewItem(inventoryPos, itemId, ItemContext.None, true);
|
||||
if (bag == null)
|
||||
return;
|
||||
|
||||
switch (buyBankTab.BankType)
|
||||
{
|
||||
case BankType.Character:
|
||||
_player.SetCharacterBankTabCount(slot);
|
||||
break;
|
||||
case BankType.Account:
|
||||
_player.SetAccountBankTabCount(slot);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
[WorldPacketHandler(ClientOpcodes.DepositReagentBank)]
|
||||
void HandleReagentBankDeposit(ReagentBank reagentBank)
|
||||
_player.ModifyMoney(-(long)price);
|
||||
|
||||
_player.UpdateCriteria(CriteriaType.BankTabPurchased, (ulong)buyBankTab.BankType);
|
||||
}
|
||||
|
||||
[WorldPacketHandler(ClientOpcodes.UpdateAccountBankTabSettings)]
|
||||
void HandleUpdateBankTabSettings(UpdateBankTabSettings updateBankTabSettings)
|
||||
{
|
||||
if (!CanUseBank(reagentBank.Banker))
|
||||
if (!CanUseBank(updateBankTabSettings.Banker))
|
||||
{
|
||||
Log.outDebug(LogFilter.Network, $"WORLD: HandleReagentBankDepositOpcode - {reagentBank.Banker} not found or you can't interact with him.");
|
||||
Log.outDebug(LogFilter.Network, $"WorldSession::HandleUpdateBankTabSettings {_player.GetGUID()} - Banker {updateBankTabSettings.Banker} not found or can't interact with him.");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (updateBankTabSettings.BankType)
|
||||
{
|
||||
case BankType.Character:
|
||||
if (updateBankTabSettings.Tab >= _player.m_activePlayerData.CharacterBankTabSettings.Size())
|
||||
{
|
||||
Log.outDebug(LogFilter.Network, $"WorldSession::HandleUpdateBankTabSettings {_player.GetGUID()} doesn't have bank tab {updateBankTabSettings.Tab} in bank type {updateBankTabSettings.BankType}.");
|
||||
return;
|
||||
}
|
||||
_player.SetCharacterBankTabSettings(updateBankTabSettings.Tab, updateBankTabSettings.Settings.Name,
|
||||
updateBankTabSettings.Settings.Icon, updateBankTabSettings.Settings.Description, updateBankTabSettings.Settings.DepositFlags);
|
||||
break;
|
||||
case BankType.Account:
|
||||
if (updateBankTabSettings.Tab >= _player.m_activePlayerData.AccountBankTabSettings.Size())
|
||||
{
|
||||
Log.outDebug(LogFilter.Network, $"WorldSession::HandleUpdateBankTabSettings {_player.GetGUID()} doesn't have bank tab {updateBankTabSettings.Tab} in bank type {updateBankTabSettings.BankType}.");
|
||||
return;
|
||||
}
|
||||
_player.SetAccountBankTabSettings(updateBankTabSettings.Tab, updateBankTabSettings.Settings.Name,
|
||||
updateBankTabSettings.Settings.Icon, updateBankTabSettings.Settings.Description, updateBankTabSettings.Settings.DepositFlags);
|
||||
break;
|
||||
default:
|
||||
Log.outDebug(LogFilter.Network, $"WorldSession::HandleUpdateBankTabSettings {_player.GetGUID()} - Bank type {updateBankTabSettings.BankType} is not supported.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
[WorldPacketHandler(ClientOpcodes.AutoDepositCharacterBank)]
|
||||
void HandleAutoDepositCharacterBank(AutoDepositCharacterBank autoDepositCharacterBank)
|
||||
{
|
||||
if (!CanUseBank(autoDepositCharacterBank.Banker))
|
||||
{
|
||||
Log.outDebug(LogFilter.Network, $"WORLD: HandleAutoDepositCharacterBank - {autoDepositCharacterBank.Banker} not found or you can't interact with him.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -204,13 +261,13 @@ namespace Game
|
||||
if (msg != InventoryResult.Ok)
|
||||
{
|
||||
if (msg != InventoryResult.ReagentBankFull || !anyDeposited)
|
||||
_player.SendEquipError(msg, item);
|
||||
_player.SendEquipError(msg, item, null);
|
||||
break;
|
||||
}
|
||||
|
||||
if (dest.Count == 1 && dest[0].pos == item.GetPos())
|
||||
{
|
||||
_player.SendEquipError(InventoryResult.CantSwap, item);
|
||||
_player.SendEquipError(InventoryResult.CantSwap, item, null);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -219,90 +276,7 @@ namespace Game
|
||||
_player.BankItem(dest, item, true);
|
||||
anyDeposited = true;
|
||||
}
|
||||
}
|
||||
|
||||
[WorldPacketHandler(ClientOpcodes.AutobankReagent)]
|
||||
void HandleAutoBankReagent(AutoBankReagent autoBankReagent)
|
||||
{
|
||||
if (!CanUseBank())
|
||||
{
|
||||
Log.outDebug(LogFilter.Network, $"WORLD: HandleAutoBankReagentOpcode - {_player.PlayerTalkClass.GetInteractionData().SourceGuid} not found or you can't interact with him.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_player.IsReagentBankUnlocked())
|
||||
{
|
||||
_player.SendEquipError(InventoryResult.ReagentBankLocked);
|
||||
return;
|
||||
}
|
||||
|
||||
Item item = _player.GetItemByPos(autoBankReagent.PackSlot, autoBankReagent.Slot);
|
||||
if (item == null)
|
||||
return;
|
||||
|
||||
List<ItemPosCount> dest = new();
|
||||
InventoryResult msg = _player.CanBankItem(ItemConst.NullBag, ItemConst.NullSlot, dest, item, false, true, true);
|
||||
if (msg != InventoryResult.Ok)
|
||||
{
|
||||
_player.SendEquipError(msg, item);
|
||||
return;
|
||||
}
|
||||
|
||||
if (dest.Count == 1 && dest[0].pos == item.GetPos())
|
||||
{
|
||||
_player.SendEquipError(InventoryResult.CantSwap, item);
|
||||
return;
|
||||
}
|
||||
|
||||
_player.RemoveItem(autoBankReagent.PackSlot, autoBankReagent.Slot, true);
|
||||
_player.BankItem(dest, item, true);
|
||||
}
|
||||
|
||||
[WorldPacketHandler(ClientOpcodes.AutostoreBankReagent)]
|
||||
void HandleAutoStoreBankReagent(AutoStoreBankReagent autoStoreBankReagent)
|
||||
{
|
||||
if (!CanUseBank())
|
||||
{
|
||||
Log.outDebug(LogFilter.Network, $"WORLD: HandleAutoBankReagentOpcode - {_player.PlayerTalkClass.GetInteractionData().SourceGuid} not found or you can't interact with him.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_player.IsReagentBankUnlocked())
|
||||
{
|
||||
_player.SendEquipError(InventoryResult.ReagentBankLocked);
|
||||
return;
|
||||
}
|
||||
|
||||
Item pItem = _player.GetItemByPos(autoStoreBankReagent.Slot, autoStoreBankReagent.PackSlot);
|
||||
if (pItem == null)
|
||||
return;
|
||||
|
||||
if (Player.IsReagentBankPos(autoStoreBankReagent.Slot, autoStoreBankReagent.PackSlot))
|
||||
{
|
||||
List<ItemPosCount> dest = new();
|
||||
InventoryResult msg = _player.CanStoreItem(ItemConst.NullBag, ItemConst.NullSlot, dest, pItem, false);
|
||||
if (msg != InventoryResult.Ok)
|
||||
{
|
||||
_player.SendEquipError(msg, pItem);
|
||||
return;
|
||||
}
|
||||
|
||||
_player.RemoveItem(autoStoreBankReagent.Slot, autoStoreBankReagent.PackSlot, true);
|
||||
_player.StoreItem(dest, pItem, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
List<ItemPosCount> dest = new();
|
||||
InventoryResult msg = _player.CanBankItem(ItemConst.NullBag, ItemConst.NullSlot, dest, pItem, false, true, true);
|
||||
if (msg != InventoryResult.Ok)
|
||||
{
|
||||
_player.SendEquipError(msg, pItem);
|
||||
return;
|
||||
}
|
||||
|
||||
_player.RemoveItem(autoStoreBankReagent.Slot, autoStoreBankReagent.PackSlot, true);
|
||||
_player.BankItem(dest, pItem, true);
|
||||
}
|
||||
}
|
||||
|
||||
public void SendShowBank(ObjectGuid guid, PlayerInteractionType interactionType)
|
||||
|
||||
@@ -1144,7 +1144,6 @@ namespace Game
|
||||
features.CfgRealmRecID = 0;
|
||||
features.CommercePricePollTimeSeconds = 300;
|
||||
features.VoiceEnabled = false;
|
||||
features.BrowserEnabled = false; // Has to be false, otherwise client will crash if "Customer Support" is opened
|
||||
|
||||
EuropaTicketConfig europaTicketSystemStatus = new();
|
||||
europaTicketSystemStatus.ThrottleState.MaxTries = 10;
|
||||
@@ -1163,7 +1162,6 @@ namespace Game
|
||||
features.EuropaTicketSystemStatus = europaTicketSystemStatus;
|
||||
|
||||
features.CharUndeleteEnabled = WorldConfig.GetBoolValue(WorldCfg.FeatureSystemCharacterUndeleteEnabled);
|
||||
features.BpayStoreEnabled = WorldConfig.GetBoolValue(WorldCfg.FeatureSystemBpayStoreEnabled);
|
||||
features.WarModeEnabled = WorldConfig.GetBoolValue(WorldCfg.FeatureSystemWarModeEnabled);
|
||||
features.IsChatMuted = !CanSpeak();
|
||||
|
||||
@@ -2796,10 +2794,6 @@ namespace Game
|
||||
stmt.AddValue(0, lowGuid);
|
||||
SetQuery(PlayerLoginQueryLoad.AzeriteEmpowered, stmt);
|
||||
|
||||
stmt = CharacterDatabase.GetPreparedStatement(CharStatements.SEL_CHAR_VOID_STORAGE);
|
||||
stmt.AddValue(0, lowGuid);
|
||||
SetQuery(PlayerLoginQueryLoad.VoidStorage, stmt);
|
||||
|
||||
stmt = CharacterDatabase.GetPreparedStatement(CharStatements.SEL_MAIL);
|
||||
stmt.AddValue(0, lowGuid);
|
||||
SetQuery(PlayerLoginQueryLoad.Mails, stmt);
|
||||
@@ -2966,6 +2960,10 @@ namespace Game
|
||||
stmt = CharacterDatabase.GetPreparedStatement(CharStatements.SEL_PLAYER_DATA_FLAGS_CHARACTER);
|
||||
stmt.AddValue(0, lowGuid);
|
||||
SetQuery(PlayerLoginQueryLoad.DataFlags, stmt);
|
||||
|
||||
stmt = CharacterDatabase.GetPreparedStatement(CharStatements.SEL_CHARACTER_BANK_TAB_SETTINGS);
|
||||
stmt.AddValue(0, lowGuid);
|
||||
SetQuery(PlayerLoginQueryLoad.BankTabSettings, stmt);
|
||||
}
|
||||
|
||||
public ObjectGuid GetGuid() { return m_guid; }
|
||||
@@ -3060,7 +3058,6 @@ namespace Game
|
||||
InstanceLockTimes,
|
||||
SeasonalQuestStatus,
|
||||
MonthlyQuestStatus,
|
||||
VoidStorage,
|
||||
Currency,
|
||||
CufProfiles,
|
||||
CorpseLocation,
|
||||
@@ -3074,6 +3071,7 @@ namespace Game
|
||||
TraitConfigs,
|
||||
DataElements,
|
||||
DataFlags,
|
||||
BankTabSettings,
|
||||
Max
|
||||
}
|
||||
|
||||
|
||||
@@ -1097,14 +1097,6 @@ namespace Game
|
||||
SendPacket(new BagCleanupFinished());
|
||||
}
|
||||
|
||||
[WorldPacketHandler(ClientOpcodes.SortReagentBankBags, Processing = PacketProcessing.Inplace)]
|
||||
void HandleSortReagentBankBags(SortReagentBankBags sortReagentBankBags)
|
||||
{
|
||||
// TODO: Implement sorting
|
||||
// Placeholder to prevent completely locking out bags clientside
|
||||
SendPacket(new BagCleanupFinished());
|
||||
}
|
||||
|
||||
[WorldPacketHandler(ClientOpcodes.RemoveNewItem, Processing = PacketProcessing.Inplace)]
|
||||
void HandleRemoveNewItem(RemoveNewItem removeNewItem)
|
||||
{
|
||||
@@ -1134,18 +1126,6 @@ namespace Game
|
||||
_player.RemoveBagSlotFlag(changeBagSlotFlag.BagIndex, changeBagSlotFlag.FlagToChange);
|
||||
}
|
||||
|
||||
[WorldPacketHandler(ClientOpcodes.ChangeBankBagSlotFlag, Processing = PacketProcessing.Inplace)]
|
||||
void HandleChangeBankBagSlotFlag(ChangeBankBagSlotFlag changeBankBagSlotFlag)
|
||||
{
|
||||
if (changeBankBagSlotFlag.BagIndex >= _player.m_activePlayerData.BankBagSlotFlags.GetSize())
|
||||
return;
|
||||
|
||||
if (changeBankBagSlotFlag.On)
|
||||
_player.SetBankBagSlotFlag(changeBankBagSlotFlag.BagIndex, changeBankBagSlotFlag.FlagToChange);
|
||||
else
|
||||
_player.RemoveBankBagSlotFlag(changeBankBagSlotFlag.BagIndex, changeBankBagSlotFlag.FlagToChange);
|
||||
}
|
||||
|
||||
[WorldPacketHandler(ClientOpcodes.SetBackpackAutosortDisabled, Processing = PacketProcessing.Inplace)]
|
||||
void HandleSetBackpackAutosortDisabled(SetBackpackAutosortDisabled setBackpackAutosortDisabled)
|
||||
{
|
||||
|
||||
@@ -301,7 +301,16 @@ namespace Game
|
||||
SendTradeStatus(info);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Player.IsAccountBankPos(item.GetSlot(), item.GetBagSlot()))
|
||||
{
|
||||
info.Status = TradeStatus.Failed;
|
||||
info.BagResult = InventoryResult.CantTradeAccountItem;
|
||||
SendTradeStatus(info);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
item = his_trade.GetItem((TradeSlots)i);
|
||||
if (item != null)
|
||||
{
|
||||
@@ -312,6 +321,14 @@ namespace Game
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (Player.IsAccountBankPos(item.GetSlot(), item.GetBagSlot()))
|
||||
{
|
||||
info.Status = TradeStatus.Failed;
|
||||
info.BagResult = InventoryResult.CantTradeAccountItem;
|
||||
SendTradeStatus(info);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (his_trade.IsAccepted())
|
||||
|
||||
@@ -1,230 +0,0 @@
|
||||
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
|
||||
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
|
||||
|
||||
using Framework.Constants;
|
||||
using Game.Entities;
|
||||
using Game.Networking;
|
||||
using Game.Networking.Packets;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Game
|
||||
{
|
||||
public partial class WorldSession
|
||||
{
|
||||
public void SendVoidStorageTransferResult(VoidTransferError result)
|
||||
{
|
||||
SendPacket(new VoidTransferResult(result));
|
||||
}
|
||||
|
||||
[WorldPacketHandler(ClientOpcodes.UnlockVoidStorage, Processing = PacketProcessing.Inplace)]
|
||||
void HandleVoidStorageUnlock(UnlockVoidStorage unlockVoidStorage)
|
||||
{
|
||||
Creature unit = GetPlayer().GetNPCIfCanInteractWith(unlockVoidStorage.Npc, NPCFlags.VaultKeeper, NPCFlags2.None);
|
||||
if (unit == null)
|
||||
{
|
||||
Log.outDebug(LogFilter.Network, "WORLD: HandleVoidStorageUnlock - {0} not found or player can't interact with it.", unlockVoidStorage.Npc.ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
if (GetPlayer().IsVoidStorageUnlocked())
|
||||
{
|
||||
Log.outDebug(LogFilter.Network, "WORLD: HandleVoidStorageUnlock - Player({0}, name: {1}) tried to unlock void storage a 2nd time.", GetPlayer().GetGUID().ToString(), GetPlayer().GetName());
|
||||
return;
|
||||
}
|
||||
|
||||
GetPlayer().ModifyMoney(-SharedConst.VoidStorageUnlockCost);
|
||||
GetPlayer().UnlockVoidStorage();
|
||||
}
|
||||
|
||||
[WorldPacketHandler(ClientOpcodes.QueryVoidStorage, Processing = PacketProcessing.Inplace)]
|
||||
void HandleVoidStorageQuery(QueryVoidStorage queryVoidStorage)
|
||||
{
|
||||
Player player = GetPlayer();
|
||||
|
||||
Creature unit = player.GetNPCIfCanInteractWith(queryVoidStorage.Npc, NPCFlags.Transmogrifier | NPCFlags.VaultKeeper, NPCFlags2.None);
|
||||
if (unit == null)
|
||||
{
|
||||
Log.outDebug(LogFilter.Network, "WORLD: HandleVoidStorageQuery - {0} not found or player can't interact with it.", queryVoidStorage.Npc.ToString());
|
||||
SendPacket(new VoidStorageFailed());
|
||||
return;
|
||||
}
|
||||
|
||||
if (!GetPlayer().IsVoidStorageUnlocked())
|
||||
{
|
||||
Log.outDebug(LogFilter.Network, "WORLD: HandleVoidStorageQuery - {0} name: {1} queried void storage without unlocking it.", player.GetGUID().ToString(), player.GetName());
|
||||
SendPacket(new VoidStorageFailed());
|
||||
return;
|
||||
}
|
||||
|
||||
VoidStorageContents voidStorageContents = new();
|
||||
for (byte i = 0; i < SharedConst.VoidStorageMaxSlot; ++i)
|
||||
{
|
||||
VoidStorageItem item = player.GetVoidStorageItem(i);
|
||||
if (item == null)
|
||||
continue;
|
||||
|
||||
VoidItem voidItem = new();
|
||||
voidItem.Guid = ObjectGuid.Create(HighGuid.Item, item.ItemId);
|
||||
voidItem.Creator = item.CreatorGuid;
|
||||
voidItem.Slot = i;
|
||||
voidItem.Item = new ItemInstance(item);
|
||||
|
||||
voidStorageContents.Items.Add(voidItem);
|
||||
}
|
||||
|
||||
SendPacket(voidStorageContents);
|
||||
}
|
||||
|
||||
[WorldPacketHandler(ClientOpcodes.VoidStorageTransfer)]
|
||||
void HandleVoidStorageTransfer(VoidStorageTransfer voidStorageTransfer)
|
||||
{
|
||||
Player player = GetPlayer();
|
||||
|
||||
Creature unit = player.GetNPCIfCanInteractWith(voidStorageTransfer.Npc, NPCFlags.VaultKeeper, NPCFlags2.None);
|
||||
if (unit == null)
|
||||
{
|
||||
Log.outDebug(LogFilter.Network, "WORLD: HandleVoidStorageTransfer - {0} not found or player can't interact with it.", voidStorageTransfer.Npc.ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
if (!player.IsVoidStorageUnlocked())
|
||||
{
|
||||
Log.outDebug(LogFilter.Network, "WORLD: HandleVoidStorageTransfer - Player ({0}, name: {1}) queried void storage without unlocking it.", player.GetGUID().ToString(), player.GetName());
|
||||
return;
|
||||
}
|
||||
|
||||
if (voidStorageTransfer.Deposits.Length > player.GetNumOfVoidStorageFreeSlots())
|
||||
{
|
||||
SendVoidStorageTransferResult(VoidTransferError.Full);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!voidStorageTransfer.Withdrawals.Empty() && voidStorageTransfer.Withdrawals.Length > _player.GetFreeInventorySlotCount(ItemSearchLocation.Inventory))
|
||||
{
|
||||
SendVoidStorageTransferResult(VoidTransferError.InventoryFull);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!player.HasEnoughMoney((voidStorageTransfer.Deposits.Length * SharedConst.VoidStorageStoreItemCost)))
|
||||
{
|
||||
SendVoidStorageTransferResult(VoidTransferError.NotEnoughMoney);
|
||||
return;
|
||||
}
|
||||
|
||||
VoidStorageTransferChanges voidStorageTransferChanges = new();
|
||||
|
||||
byte depositCount = 0;
|
||||
for (int i = 0; i < voidStorageTransfer.Deposits.Length; ++i)
|
||||
{
|
||||
Item item = player.GetItemByGuid(voidStorageTransfer.Deposits[i]);
|
||||
if (item == null)
|
||||
{
|
||||
Log.outDebug(LogFilter.Network, "WORLD: HandleVoidStorageTransfer - {0} {1} wants to deposit an invalid item ({2}).", player.GetGUID().ToString(), player.GetName(), voidStorageTransfer.Deposits[i].ToString());
|
||||
continue;
|
||||
}
|
||||
|
||||
VoidStorageItem itemVS = new(Global.ObjectMgr.GenerateVoidStorageItemId(), item.GetEntry(), item.GetCreator(),
|
||||
item.GetItemRandomBonusListId(), item.GetModifier(ItemModifier.TimewalkerLevel), item.GetModifier(ItemModifier.ArtifactKnowledgeLevel),
|
||||
item.GetContext(), item.GetBonusListIDs());
|
||||
|
||||
VoidItem voidItem;
|
||||
voidItem.Guid = ObjectGuid.Create(HighGuid.Item, itemVS.ItemId);
|
||||
voidItem.Creator = item.GetCreator();
|
||||
voidItem.Item = new ItemInstance(itemVS);
|
||||
voidItem.Slot = _player.AddVoidStorageItem(itemVS);
|
||||
|
||||
voidStorageTransferChanges.AddedItems.Add(voidItem);
|
||||
|
||||
player.DestroyItem(item.GetBagSlot(), item.GetSlot(), true);
|
||||
++depositCount;
|
||||
}
|
||||
|
||||
long cost = depositCount * SharedConst.VoidStorageStoreItemCost;
|
||||
|
||||
player.ModifyMoney(-cost);
|
||||
|
||||
for (int i = 0; i < voidStorageTransfer.Withdrawals.Length; ++i)
|
||||
{
|
||||
byte slot;
|
||||
VoidStorageItem itemVS = player.GetVoidStorageItem(voidStorageTransfer.Withdrawals[i].GetCounter(), out slot);
|
||||
if (itemVS == null)
|
||||
{
|
||||
Log.outDebug(LogFilter.Network, "WORLD: HandleVoidStorageTransfer - {0} {1} tried to withdraw an invalid item ({2})", player.GetGUID().ToString(), player.GetName(), voidStorageTransfer.Withdrawals[i].ToString());
|
||||
continue;
|
||||
}
|
||||
|
||||
List<ItemPosCount> dest = new();
|
||||
InventoryResult msg = player.CanStoreNewItem(ItemConst.NullBag, ItemConst.NullSlot, dest, itemVS.ItemEntry, 1);
|
||||
if (msg != InventoryResult.Ok)
|
||||
{
|
||||
SendVoidStorageTransferResult(VoidTransferError.InventoryFull);
|
||||
Log.outDebug(LogFilter.Network, "WORLD: HandleVoidStorageTransfer - {0} {1} couldn't withdraw {2} because inventory was full.", player.GetGUID().ToString(), player.GetName(), voidStorageTransfer.Withdrawals[i].ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
Item item = player.StoreNewItem(dest, itemVS.ItemEntry, true, itemVS.RandomBonusListId, null, itemVS.Context, itemVS.BonusListIDs);
|
||||
if (item != null)
|
||||
{
|
||||
item.SetCreator(itemVS.CreatorGuid);
|
||||
item.SetBinding(true);
|
||||
GetCollectionMgr().AddItemAppearance(item);
|
||||
}
|
||||
|
||||
voidStorageTransferChanges.RemovedItems.Add(ObjectGuid.Create(HighGuid.Item, itemVS.ItemId));
|
||||
|
||||
player.DeleteVoidStorageItem(slot);
|
||||
}
|
||||
|
||||
SendPacket(voidStorageTransferChanges);
|
||||
SendVoidStorageTransferResult(VoidTransferError.Ok);
|
||||
}
|
||||
|
||||
[WorldPacketHandler(ClientOpcodes.SwapVoidItem, Processing = PacketProcessing.Inplace)]
|
||||
void HandleVoidSwapItem(SwapVoidItem swapVoidItem)
|
||||
{
|
||||
Player player = GetPlayer();
|
||||
|
||||
Creature unit = player.GetNPCIfCanInteractWith(swapVoidItem.Npc, NPCFlags.VaultKeeper, NPCFlags2.None);
|
||||
if (unit == null)
|
||||
{
|
||||
Log.outDebug(LogFilter.Network, "WORLD: HandleVoidSwapItem - {0} not found or player can't interact with it.", swapVoidItem.Npc.ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
if (!player.IsVoidStorageUnlocked())
|
||||
{
|
||||
Log.outDebug(LogFilter.Network, "WORLD: HandleVoidSwapItem - Player ({0}, name: {1}) queried void storage without unlocking it.", player.GetGUID().ToString(), player.GetName());
|
||||
return;
|
||||
}
|
||||
|
||||
byte oldSlot;
|
||||
if (player.GetVoidStorageItem(swapVoidItem.VoidItemGuid.GetCounter(), out oldSlot) == null)
|
||||
{
|
||||
Log.outDebug(LogFilter.Network, "WORLD: HandleVoidSwapItem - Player (GUID: {0}, name: {1}) requested swapping an invalid item (slot: {2}, itemid: {3}).", player.GetGUID().ToString(), player.GetName(), swapVoidItem.DstSlot, swapVoidItem.VoidItemGuid.ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
bool usedDestSlot = player.GetVoidStorageItem((byte)swapVoidItem.DstSlot) != null;
|
||||
ObjectGuid itemIdDest = ObjectGuid.Empty;
|
||||
if (usedDestSlot)
|
||||
itemIdDest = ObjectGuid.Create(HighGuid.Item, player.GetVoidStorageItem((byte)swapVoidItem.DstSlot).ItemId);
|
||||
|
||||
if (!player.SwapVoidStorageItem(oldSlot, (byte)swapVoidItem.DstSlot))
|
||||
{
|
||||
SendVoidStorageTransferResult(VoidTransferError.InternalError1);
|
||||
return;
|
||||
}
|
||||
|
||||
VoidItemSwapResponse voidItemSwapResponse = new();
|
||||
voidItemSwapResponse.VoidItemA = swapVoidItem.VoidItemGuid;
|
||||
voidItemSwapResponse.VoidItemSlotA = swapVoidItem.DstSlot;
|
||||
if (usedDestSlot)
|
||||
{
|
||||
voidItemSwapResponse.VoidItemB = itemIdDest;
|
||||
voidItemSwapResponse.VoidItemSlotB = oldSlot;
|
||||
}
|
||||
|
||||
SendPacket(voidItemSwapResponse);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -48,37 +48,6 @@ namespace Game.Networking.Packets
|
||||
public override void Write() { }
|
||||
}
|
||||
|
||||
class AreaTriggerRePath : ServerPacket
|
||||
{
|
||||
public AreaTriggerRePath() : base(ServerOpcodes.AreaTriggerRePath) { }
|
||||
|
||||
public override void Write()
|
||||
{
|
||||
_worldPacket.WritePackedGuid(TriggerGUID);
|
||||
_worldPacket.WritePackedGuid(Unused_1100);
|
||||
|
||||
_worldPacket.WriteBit(AreaTriggerSpline != null);
|
||||
_worldPacket.WriteBit(AreaTriggerOrbit != null);
|
||||
_worldPacket.WriteBit(AreaTriggerMovementScript.HasValue);
|
||||
_worldPacket.FlushBits();
|
||||
|
||||
if (AreaTriggerSpline != null)
|
||||
AreaTriggerSpline.Write(_worldPacket);
|
||||
|
||||
if (AreaTriggerMovementScript.HasValue)
|
||||
AreaTriggerMovementScript.Value.Write(_worldPacket);
|
||||
|
||||
if (AreaTriggerOrbit != null)
|
||||
AreaTriggerOrbit.Write(_worldPacket);
|
||||
}
|
||||
|
||||
public AreaTriggerSplineInfo AreaTriggerSpline;
|
||||
public AreaTriggerOrbitInfo AreaTriggerOrbit;
|
||||
public AreaTriggerMovementScriptInfo? AreaTriggerMovementScript;
|
||||
public ObjectGuid TriggerGUID;
|
||||
public ObjectGuid Unused_1100;
|
||||
}
|
||||
|
||||
class AreaTriggerPlaySpellVisual : ServerPacket
|
||||
{
|
||||
public ObjectGuid AreaTriggerGUID;
|
||||
@@ -108,31 +77,4 @@ namespace Game.Networking.Packets
|
||||
TargetGUID = _worldPacket.ReadPackedGuid();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//Structs
|
||||
class AreaTriggerSplineInfo
|
||||
{
|
||||
public static void WriteAreaTriggerSpline(WorldPacket data, uint timeToTarget, uint elapsedTimeForMovement, Spline<float> areaTriggerSpline)
|
||||
{
|
||||
data.WriteUInt32(timeToTarget);
|
||||
data.WriteUInt32(elapsedTimeForMovement);
|
||||
|
||||
var points = areaTriggerSpline.GetPoints();
|
||||
data.WriteBits(points.Length, 16);
|
||||
data.FlushBits();
|
||||
|
||||
foreach (Vector3 point in points)
|
||||
data.WriteVector3(point);
|
||||
}
|
||||
|
||||
public void Write(WorldPacket data)
|
||||
{
|
||||
WriteAreaTriggerSpline(data, TimeToTarget, ElapsedTimeForMovement, Points);
|
||||
}
|
||||
|
||||
public uint TimeToTarget;
|
||||
public uint ElapsedTimeForMovement;
|
||||
public Spline<float> Points;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,62 +40,30 @@ namespace Game.Networking.Packets
|
||||
}
|
||||
}
|
||||
|
||||
public class BuyBankSlot : ClientPacket
|
||||
public class BuyBankTab : ClientPacket
|
||||
{
|
||||
public BuyBankSlot(WorldPacket packet) : base(packet) { }
|
||||
public ObjectGuid Banker;
|
||||
public BankType BankType;
|
||||
|
||||
public BuyBankTab(WorldPacket packet) : base(packet) { }
|
||||
|
||||
public override void Read()
|
||||
{
|
||||
Guid = _worldPacket.ReadPackedGuid();
|
||||
Banker = _worldPacket.ReadPackedGuid();
|
||||
BankType = (BankType)_worldPacket.ReadInt8();
|
||||
}
|
||||
}
|
||||
|
||||
public ObjectGuid Guid;
|
||||
}
|
||||
|
||||
class AutoBankReagent : ClientPacket
|
||||
class AutoDepositCharacterBank : ClientPacket
|
||||
{
|
||||
public AutoBankReagent(WorldPacket packet) : base(packet) { }
|
||||
public ObjectGuid Banker;
|
||||
|
||||
public override void Read()
|
||||
{
|
||||
Inv = new(_worldPacket);
|
||||
PackSlot = _worldPacket.ReadUInt8();
|
||||
Slot = _worldPacket.ReadUInt8();
|
||||
}
|
||||
|
||||
public InvUpdate Inv;
|
||||
public byte Slot;
|
||||
public byte PackSlot;
|
||||
}
|
||||
|
||||
class AutoStoreBankReagent : ClientPacket
|
||||
{
|
||||
public AutoStoreBankReagent(WorldPacket packet) : base(packet) { }
|
||||
|
||||
public override void Read()
|
||||
{
|
||||
Inv = new(_worldPacket);
|
||||
Slot = _worldPacket.ReadUInt8();
|
||||
PackSlot = _worldPacket.ReadUInt8();
|
||||
}
|
||||
|
||||
public InvUpdate Inv;
|
||||
public byte Slot;
|
||||
public byte PackSlot;
|
||||
}
|
||||
|
||||
// CMSG_BUY_REAGENT_BANK
|
||||
// CMSG_REAGENT_BANK_DEPOSIT
|
||||
class ReagentBank : ClientPacket
|
||||
{
|
||||
public ReagentBank(WorldPacket packet) : base(packet) { }
|
||||
public AutoDepositCharacterBank(WorldPacket packet) : base(packet) { }
|
||||
|
||||
public override void Read()
|
||||
{
|
||||
Banker = _worldPacket.ReadPackedGuid();
|
||||
}
|
||||
|
||||
public ObjectGuid Banker;
|
||||
}
|
||||
|
||||
class BankerActivate : ClientPacket
|
||||
@@ -111,4 +79,43 @@ namespace Game.Networking.Packets
|
||||
InteractionType = (PlayerInteractionType)_worldPacket.ReadInt32();
|
||||
}
|
||||
}
|
||||
|
||||
class UpdateBankTabSettings : ClientPacket
|
||||
{
|
||||
public ObjectGuid Banker;
|
||||
public BankType BankType;
|
||||
public byte Tab;
|
||||
public BankTabSettings Settings;
|
||||
|
||||
public UpdateBankTabSettings(WorldPacket packet) : base(packet) { }
|
||||
|
||||
public override void Read()
|
||||
{
|
||||
Banker = _worldPacket.ReadPackedGuid();
|
||||
BankType = (BankType)_worldPacket.ReadInt8();
|
||||
Tab = _worldPacket.ReadUInt8();
|
||||
Settings.Read(_worldPacket);
|
||||
}
|
||||
}
|
||||
|
||||
public struct BankTabSettings
|
||||
{
|
||||
public string Name;
|
||||
public string Icon;
|
||||
public string Description;
|
||||
public BagSlotFlags DepositFlags;
|
||||
|
||||
public void Read(WorldPacket data)
|
||||
{
|
||||
data.ResetBitPos();
|
||||
var nameLength = data.ReadBits<uint>(7);
|
||||
var iconLength = data.ReadBits<uint>(9);
|
||||
var descriptionLength = data.ReadBits<uint>(14);
|
||||
DepositFlags = (BagSlotFlags)data.ReadInt32();
|
||||
|
||||
Name = data.ReadString(nameLength);
|
||||
Icon = data.ReadString(iconLength);
|
||||
Description = data.ReadString(descriptionLength);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,6 +50,8 @@ namespace Game.Networking.Packets
|
||||
for (int i = 0; i < PvpTalents.Count; ++i)
|
||||
_worldPacket.WriteUInt16(PvpTalents[i]);
|
||||
|
||||
TalentInfo.Write(_worldPacket);
|
||||
|
||||
_worldPacket.WriteBit(GuildData.HasValue);
|
||||
_worldPacket.WriteBit(AzeriteLevel.HasValue);
|
||||
_worldPacket.FlushBits();
|
||||
@@ -79,6 +81,7 @@ namespace Game.Networking.Packets
|
||||
public ushort TodayHK;
|
||||
public ushort YesterdayHK;
|
||||
public byte LifetimeMaxRank;
|
||||
public ClassicTalentInfoUpdate TalentInfo;
|
||||
public TraitInspectInfo TraitsInfo = new();
|
||||
}
|
||||
|
||||
|
||||
@@ -657,13 +657,6 @@ namespace Game.Networking.Packets
|
||||
public override void Read() { }
|
||||
}
|
||||
|
||||
class SortReagentBankBags : ClientPacket
|
||||
{
|
||||
public SortReagentBankBags(WorldPacket packet) : base(packet) { }
|
||||
|
||||
public override void Read() { }
|
||||
}
|
||||
|
||||
class BagCleanupFinished : ServerPacket
|
||||
{
|
||||
public BagCleanupFinished() : base(ServerOpcodes.BagCleanupFinished, ConnectionType.Instance) { }
|
||||
@@ -1006,24 +999,6 @@ namespace Game.Networking.Packets
|
||||
}
|
||||
}
|
||||
|
||||
public ItemInstance(VoidStorageItem voidItem)
|
||||
{
|
||||
ItemID = voidItem.ItemEntry;
|
||||
|
||||
if (voidItem.FixedScalingLevel != 0)
|
||||
Modifications.Values.Add(new ItemMod(voidItem.FixedScalingLevel, ItemModifier.TimewalkerLevel));
|
||||
|
||||
if (voidItem.ArtifactKnowledgeLevel != 0)
|
||||
Modifications.Values.Add(new ItemMod(voidItem.ArtifactKnowledgeLevel, ItemModifier.ArtifactKnowledgeLevel));
|
||||
|
||||
if (!voidItem.BonusListIDs.Empty())
|
||||
{
|
||||
ItemBonus = new();
|
||||
ItemBonus.Context = voidItem.Context;
|
||||
ItemBonus.BonusListIDs = voidItem.BonusListIDs;
|
||||
}
|
||||
}
|
||||
|
||||
public ItemInstance(SocketedGem gem)
|
||||
{
|
||||
ItemID = gem.ItemId;
|
||||
|
||||
@@ -333,9 +333,9 @@ namespace Game.Networking.Packets
|
||||
if (moveSpline.anim_tier != null)
|
||||
{
|
||||
data.WriteUInt32(moveSpline.anim_tier.TierTransitionId);
|
||||
data.WriteUInt8(moveSpline.anim_tier.AnimTier);
|
||||
data.WriteInt32(moveSpline.effect_start_time);
|
||||
data.WriteUInt32(0);
|
||||
data.WriteUInt8(moveSpline.anim_tier.AnimTier);
|
||||
}
|
||||
|
||||
//if (HasUnknown901)
|
||||
@@ -1473,9 +1473,9 @@ namespace Game.Networking.Packets
|
||||
public void Write(WorldPacket data)
|
||||
{
|
||||
data.WriteInt32(TierTransitionID);
|
||||
data.WriteUInt8(AnimTier);
|
||||
data.WriteUInt32(StartTime);
|
||||
data.WriteUInt32(EndTime);
|
||||
data.WriteUInt8(AnimTier);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -782,6 +782,7 @@ namespace Game.Networking.Packets
|
||||
_worldPacket.WriteUInt8(LeaderFactionGroup);
|
||||
_worldPacket.WriteInt32((int)PingRestriction);
|
||||
_worldPacket.WriteInt32(PlayerList.Count);
|
||||
_worldPacket.WriteBit(ChallengeMode.HasValue);
|
||||
_worldPacket.WriteBit(LfgInfos.HasValue);
|
||||
_worldPacket.WriteBit(LootSettings.HasValue);
|
||||
_worldPacket.WriteBit(DifficultySettings.HasValue);
|
||||
@@ -796,6 +797,9 @@ namespace Game.Networking.Packets
|
||||
if (DifficultySettings.HasValue)
|
||||
DifficultySettings.Value.Write(_worldPacket);
|
||||
|
||||
if (ChallengeMode.HasValue)
|
||||
ChallengeMode.Value.Write(_worldPacket);
|
||||
|
||||
if (LfgInfos.HasValue)
|
||||
LfgInfos.Value.Write(_worldPacket);
|
||||
}
|
||||
@@ -815,6 +819,7 @@ namespace Game.Networking.Packets
|
||||
|
||||
public List<PartyPlayerInfo> PlayerList = new();
|
||||
|
||||
public ChallengeModeData? ChallengeMode;
|
||||
public PartyLFGInfo? LfgInfos;
|
||||
public PartyLootSettings? LootSettings;
|
||||
public PartyDifficultySettings? DifficultySettings;
|
||||
@@ -1253,8 +1258,50 @@ namespace Game.Networking.Packets
|
||||
public DungeonScoreSummary DungeonScore = new();
|
||||
}
|
||||
|
||||
public struct LeaverInfo
|
||||
{
|
||||
public ObjectGuid BnetAccountGUID;
|
||||
public float LeaveScore;
|
||||
public uint SeasonID;
|
||||
public uint TotalLeaves;
|
||||
public uint TotalSuccesses;
|
||||
public int ConsecutiveSuccesses;
|
||||
public long LastPenaltyTime;
|
||||
public long LeaverExpirationTime;
|
||||
public int Unknown_1120;
|
||||
public bool LeaverStatus;
|
||||
|
||||
public void Write(WorldPacket data)
|
||||
{
|
||||
data.WritePackedGuid(BnetAccountGUID);
|
||||
data.WriteFloat(LeaveScore);
|
||||
data.WriteUInt32(SeasonID);
|
||||
data.WriteUInt32(TotalLeaves);
|
||||
data.WriteUInt32(TotalSuccesses);
|
||||
data.WriteInt32(ConsecutiveSuccesses);
|
||||
data.WriteInt64(LastPenaltyTime);
|
||||
data.WriteInt64(LeaverExpirationTime);
|
||||
data.WriteInt32(Unknown_1120);
|
||||
data.WriteBits(LeaverStatus, 1);
|
||||
data.FlushBits();
|
||||
}
|
||||
}
|
||||
|
||||
struct PartyPlayerInfo
|
||||
{
|
||||
public ObjectGuid GUID;
|
||||
public string Name;
|
||||
public string VoiceStateID; // same as bgs.protocol.club.v1.MemberVoiceState.id
|
||||
public LeaverInfo Leaver;
|
||||
public byte Class;
|
||||
public byte Subgroup;
|
||||
public byte Flags;
|
||||
public byte RolesAssigned;
|
||||
public byte FactionGroup;
|
||||
public bool FromSocialQueue;
|
||||
public bool VoiceChatSilenced;
|
||||
public bool Connected;
|
||||
|
||||
public void Write(WorldPacket data)
|
||||
{
|
||||
data.WriteBits(Name.GetByteCount(), 6);
|
||||
@@ -1262,6 +1309,7 @@ namespace Game.Networking.Packets
|
||||
data.WriteBit(Connected);
|
||||
data.WriteBit(VoiceChatSilenced);
|
||||
data.WriteBit(FromSocialQueue);
|
||||
Leaver.Write(data);
|
||||
data.WritePackedGuid(GUID);
|
||||
data.WriteUInt8(Subgroup);
|
||||
data.WriteUInt8(Flags);
|
||||
@@ -1272,22 +1320,21 @@ namespace Game.Networking.Packets
|
||||
if (!VoiceStateID.IsEmpty())
|
||||
data.WriteString(VoiceStateID);
|
||||
}
|
||||
|
||||
public ObjectGuid GUID;
|
||||
public string Name;
|
||||
public string VoiceStateID; // same as bgs.protocol.club.v1.MemberVoiceState.id
|
||||
public byte Class;
|
||||
public byte Subgroup;
|
||||
public byte Flags;
|
||||
public byte RolesAssigned;
|
||||
public byte FactionGroup;
|
||||
public bool FromSocialQueue;
|
||||
public bool VoiceChatSilenced;
|
||||
public bool Connected;
|
||||
}
|
||||
|
||||
struct PartyLFGInfo
|
||||
{
|
||||
public uint Slot;
|
||||
public byte MyFlags;
|
||||
public uint MyRandomSlot;
|
||||
public byte MyPartialClear;
|
||||
public float MyGearDiff;
|
||||
public byte MyStrangerCount;
|
||||
public byte MyKickVoteCount;
|
||||
public byte BootCount;
|
||||
public bool Aborted;
|
||||
public bool MyFirstReward;
|
||||
|
||||
public void Write(WorldPacket data)
|
||||
{
|
||||
data.WriteUInt32(Slot);
|
||||
@@ -1302,44 +1349,60 @@ namespace Game.Networking.Packets
|
||||
data.WriteBit(MyFirstReward);
|
||||
data.FlushBits();
|
||||
}
|
||||
|
||||
public uint Slot;
|
||||
public byte MyFlags;
|
||||
public uint MyRandomSlot;
|
||||
public byte MyPartialClear;
|
||||
public float MyGearDiff;
|
||||
public byte MyStrangerCount;
|
||||
public byte MyKickVoteCount;
|
||||
public byte BootCount;
|
||||
public bool Aborted;
|
||||
public bool MyFirstReward;
|
||||
}
|
||||
|
||||
struct PartyLootSettings
|
||||
{
|
||||
public byte Method;
|
||||
public ObjectGuid LootMaster;
|
||||
public byte Threshold;
|
||||
|
||||
public void Write(WorldPacket data)
|
||||
{
|
||||
data.WriteUInt8(Method);
|
||||
data.WritePackedGuid(LootMaster);
|
||||
data.WriteUInt8(Threshold);
|
||||
}
|
||||
|
||||
public byte Method;
|
||||
public ObjectGuid LootMaster;
|
||||
public byte Threshold;
|
||||
}
|
||||
|
||||
struct PartyDifficultySettings
|
||||
{
|
||||
public uint DungeonDifficultyID;
|
||||
public uint RaidDifficultyID;
|
||||
public uint LegacyRaidDifficultyID;
|
||||
|
||||
public void Write(WorldPacket data)
|
||||
{
|
||||
data.WriteUInt32(DungeonDifficultyID);
|
||||
data.WriteUInt32(RaidDifficultyID);
|
||||
data.WriteUInt32(LegacyRaidDifficultyID);
|
||||
}
|
||||
}
|
||||
|
||||
public uint DungeonDifficultyID;
|
||||
public uint RaidDifficultyID;
|
||||
public uint LegacyRaidDifficultyID;
|
||||
struct ChallengeModeData
|
||||
{
|
||||
public int Unknown_1120_1;
|
||||
public int Unknown_1120_2;
|
||||
public ulong Unknown_1120_3;
|
||||
public long Unknown_1120_4;
|
||||
public ObjectGuid KeystoneOwnerGUID;
|
||||
public ObjectGuid LeaverGUID;
|
||||
public bool IsActive;
|
||||
public bool HasRestrictions;
|
||||
public bool CanVoteAbandon;
|
||||
|
||||
public void Write(WorldPacket data)
|
||||
{
|
||||
data.WriteInt32(Unknown_1120_1);
|
||||
data.WriteInt32(Unknown_1120_2);
|
||||
data.WriteUInt64(Unknown_1120_3);
|
||||
data.WriteInt64(Unknown_1120_4);
|
||||
data.WritePackedGuid(KeystoneOwnerGUID);
|
||||
data.WritePackedGuid(LeaverGUID);
|
||||
data.WriteBit(IsActive);
|
||||
data.WriteBit(HasRestrictions);
|
||||
data.WriteBit(CanVoteAbandon);
|
||||
data.FlushBits();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -767,7 +767,7 @@ namespace Game.Networking.Packets
|
||||
public int CreatureDifficultyID;
|
||||
public int WidgetSetID;
|
||||
public int WidgetSetUnitConditionID;
|
||||
public uint[] Flags = new uint[2];
|
||||
public uint[] Flags = new uint[3];
|
||||
public uint[] ProxyCreatureID = new uint[SharedConst.MaxCreatureKillCredit];
|
||||
public StringArray Name = new(SharedConst.MaxCreatureNames);
|
||||
public StringArray NameAlt = new(SharedConst.MaxCreatureNames);
|
||||
|
||||
@@ -29,7 +29,6 @@ namespace Game.Networking.Packets
|
||||
_worldPacket.WriteUInt32(KioskSessionDurationMinutes);
|
||||
_worldPacket.WriteInt64(RedeemForBalanceAmount);
|
||||
|
||||
_worldPacket.WriteUInt32(BpayStorePurchaseTimeout);
|
||||
_worldPacket.WriteUInt32(ClubsPresenceDelay);
|
||||
_worldPacket.WriteUInt32(ClubPresenceUnsubscribeDelay);
|
||||
|
||||
@@ -57,60 +56,58 @@ namespace Game.Networking.Packets
|
||||
|
||||
_worldPacket.WriteBit(VoiceEnabled);
|
||||
_worldPacket.WriteBit(EuropaTicketSystemStatus.HasValue);
|
||||
_worldPacket.WriteBit(BpayStoreEnabled);
|
||||
_worldPacket.WriteBit(BpayStoreAvailable);
|
||||
_worldPacket.WriteBit(BpayStoreDisabledByParentalControls);
|
||||
_worldPacket.WriteBit(ItemRestorationButtonEnabled);
|
||||
_worldPacket.WriteBit(BrowserEnabled);
|
||||
|
||||
_worldPacket.WriteBit(SessionAlert.HasValue);
|
||||
_worldPacket.WriteBit(RAFSystem.Enabled);
|
||||
_worldPacket.WriteBit(RAFSystem.RecruitingEnabled);
|
||||
|
||||
_worldPacket.WriteBit(CharUndeleteEnabled);
|
||||
_worldPacket.WriteBit(RestrictedAccount);
|
||||
_worldPacket.WriteBit(CommerceServerEnabled);
|
||||
_worldPacket.WriteBit(TutorialEnabled);
|
||||
|
||||
_worldPacket.WriteBit(VeteranTokenRedeemWillKick);
|
||||
_worldPacket.WriteBit(WorldTokenRedeemWillKick);
|
||||
_worldPacket.WriteBit(KioskModeEnabled);
|
||||
_worldPacket.WriteBit(CompetitiveModeEnabled);
|
||||
|
||||
_worldPacket.WriteBit(RedeemForBalanceAvailable);
|
||||
_worldPacket.WriteBit(WarModeEnabled);
|
||||
_worldPacket.WriteBit(CommunitiesEnabled);
|
||||
_worldPacket.WriteBit(BnetGroupsEnabled);
|
||||
|
||||
_worldPacket.WriteBit(CharacterCommunitiesEnabled);
|
||||
_worldPacket.WriteBit(ClubPresenceAllowSubscribeAll);
|
||||
_worldPacket.WriteBit(VoiceChatParentalDisabled);
|
||||
_worldPacket.WriteBit(VoiceChatParentalMuted);
|
||||
|
||||
_worldPacket.WriteBit(QuestSessionEnabled);
|
||||
_worldPacket.WriteBit(IsChatMuted);
|
||||
_worldPacket.WriteBit(ClubFinderEnabled);
|
||||
_worldPacket.WriteBit(CommunityFinderEnabled);
|
||||
_worldPacket.WriteBit(BrowserCrashReporterEnabled);
|
||||
_worldPacket.WriteBit(SpeakForMeAllowed);
|
||||
|
||||
_worldPacket.WriteBit(DoesAccountNeedAADCPrompt);
|
||||
_worldPacket.WriteBit(IsAccountOptedInToAADC);
|
||||
|
||||
_worldPacket.WriteBit(LfgRequireAuthenticatorEnabled);
|
||||
_worldPacket.WriteBit(ScriptsDisallowedForBeta);
|
||||
_worldPacket.WriteBit(TimerunningEnabled);
|
||||
_worldPacket.WriteBit(WarGamesEnabled);
|
||||
_worldPacket.WriteBit(IsPlayerContentTrackingEnabled);
|
||||
_worldPacket.WriteBit(SellAllJunkEnabled);
|
||||
|
||||
_worldPacket.WriteBit(GroupFinderEnabled);
|
||||
_worldPacket.WriteBit(IsPremadeGroupEnabled);
|
||||
|
||||
_worldPacket.WriteBit(false); // unused 10.2.7
|
||||
_worldPacket.WriteBit(GuildEventsEditsEnabled);
|
||||
_worldPacket.WriteBit(GuildTradeSkillsEnabled);
|
||||
_worldPacket.WriteBits(Unknown1027.GetByteCount(), 7);
|
||||
_worldPacket.WriteBits(Unknown1027.GetByteCount(), 10);
|
||||
_worldPacket.WriteBit(BNSendWhisperUseV2Services);
|
||||
_worldPacket.WriteBit(BNSendGameDataUseV2Services);
|
||||
_worldPacket.WriteBit(IsAccountCurrencyTransferEnabled);
|
||||
_worldPacket.WriteBit(false); // unused 11.0.7
|
||||
|
||||
_worldPacket.WriteBit(false); // unused 11.0.7
|
||||
_worldPacket.WriteBit(LobbyMatchmakerQueueFromMainlineEnabled);
|
||||
_worldPacket.WriteBit(CanSendLobbyMatchmakerPartyCustomizations);
|
||||
_worldPacket.WriteBit(AddonProfilerEnabled);
|
||||
@@ -139,9 +136,7 @@ namespace Game.Networking.Packets
|
||||
}
|
||||
|
||||
public bool VoiceEnabled;
|
||||
public bool BrowserEnabled;
|
||||
public bool BpayStoreAvailable;
|
||||
public bool BpayStoreEnabled;
|
||||
public SessionAlertConfig? SessionAlert;
|
||||
public EuropaTicketConfig? EuropaTicketSystemStatus;
|
||||
public uint CfgRealmID;
|
||||
@@ -149,7 +144,6 @@ namespace Game.Networking.Packets
|
||||
public int CfgRealmRecID;
|
||||
public uint CommercePricePollTimeSeconds;
|
||||
public long RedeemForBalanceAmount;
|
||||
public uint BpayStorePurchaseTimeout;
|
||||
public uint ClubsPresenceDelay;
|
||||
public uint ClubPresenceUnsubscribeDelay; // Timer for updating club presence when communities ui frame is hidden
|
||||
public uint KioskSessionDurationMinutes;
|
||||
@@ -308,7 +302,6 @@ namespace Game.Networking.Packets
|
||||
|
||||
public override void Write()
|
||||
{
|
||||
_worldPacket.WriteBit(BpayStoreEnabled);
|
||||
_worldPacket.WriteBit(BpayStoreAvailable);
|
||||
_worldPacket.WriteBit(BpayStoreDisabledByParentalControls);
|
||||
_worldPacket.WriteBit(CharUndeleteEnabled);
|
||||
@@ -316,8 +309,8 @@ namespace Game.Networking.Packets
|
||||
_worldPacket.WriteBit(VeteranTokenRedeemWillKick);
|
||||
_worldPacket.WriteBit(WorldTokenRedeemWillKick);
|
||||
_worldPacket.WriteBit(ExpansionPreorderInStore);
|
||||
|
||||
_worldPacket.WriteBit(KioskModeEnabled);
|
||||
|
||||
_worldPacket.WriteBit(CompetitiveModeEnabled);
|
||||
_worldPacket.WriteBit(BoostEnabled);
|
||||
_worldPacket.WriteBit(TrialBoostEnabled);
|
||||
@@ -325,8 +318,8 @@ namespace Game.Networking.Packets
|
||||
_worldPacket.WriteBit(PaidCharacterTransfersBetweenBnetAccountsEnabled);
|
||||
_worldPacket.WriteBit(LiveRegionCharacterListEnabled);
|
||||
_worldPacket.WriteBit(LiveRegionCharacterCopyEnabled);
|
||||
|
||||
_worldPacket.WriteBit(LiveRegionAccountCopyEnabled);
|
||||
|
||||
_worldPacket.WriteBit(LiveRegionKeyBindingsCopyEnabled);
|
||||
_worldPacket.WriteBit(BrowserCrashReporterEnabled);
|
||||
_worldPacket.WriteBit(IsEmployeeAccount);
|
||||
@@ -334,16 +327,16 @@ namespace Game.Networking.Packets
|
||||
_worldPacket.WriteBit(NameReservationOnly);
|
||||
_worldPacket.WriteBit(LaunchDurationETA.HasValue);
|
||||
_worldPacket.WriteBit(TimerunningEnabled);
|
||||
|
||||
_worldPacket.WriteBit(ScriptsDisallowedForBeta);
|
||||
|
||||
_worldPacket.WriteBit(PlayerIdentityOptionsEnabled);
|
||||
_worldPacket.WriteBit(AccountExportEnabled);
|
||||
_worldPacket.WriteBit(AccountLockedPostExport);
|
||||
_worldPacket.WriteBits(RealmHiddenAlert.GetByteCount() + 1, 11);
|
||||
|
||||
_worldPacket.WriteBit(BNSendWhisperUseV2Services);
|
||||
|
||||
_worldPacket.WriteBit(BNSendGameDataUseV2Services);
|
||||
|
||||
_worldPacket.WriteBit(CharacterSelectListModeRealmless);
|
||||
_worldPacket.WriteBit(WowTokenLimitedMode);
|
||||
_worldPacket.WriteBit(false); // unused 11.1.7
|
||||
@@ -360,7 +353,6 @@ namespace Game.Networking.Packets
|
||||
_worldPacket.WriteInt64(RedeemForBalanceAmount);
|
||||
_worldPacket.WriteInt32(MaxCharactersOnThisRealm);
|
||||
_worldPacket.WriteInt32(LiveRegionCharacterCopySourceRegions.Count);
|
||||
_worldPacket.WriteUInt32(BpayStorePurchaseTimeout);
|
||||
_worldPacket.WriteInt32(ActiveBoostType);
|
||||
_worldPacket.WriteInt32(TrialBoostType);
|
||||
_worldPacket.WriteInt32(MinimumExpansionLevel);
|
||||
@@ -395,7 +387,6 @@ namespace Game.Networking.Packets
|
||||
public bool BpayStoreAvailable; // NYI
|
||||
public bool BpayStoreDisabledByParentalControls; // NYI
|
||||
public bool CharUndeleteEnabled;
|
||||
public bool BpayStoreEnabled; // NYI
|
||||
public bool CommerceServerEnabled; // NYI
|
||||
public bool VeteranTokenRedeemWillKick; // NYI
|
||||
public bool WorldTokenRedeemWillKick; // NYI
|
||||
@@ -428,7 +419,6 @@ namespace Game.Networking.Packets
|
||||
public uint CommercePricePollTimeSeconds; // NYI
|
||||
public long RedeemForBalanceAmount; // NYI
|
||||
public int MaxCharactersOnThisRealm;
|
||||
public uint BpayStorePurchaseTimeout; // NYI
|
||||
public int ActiveBoostType; // NYI
|
||||
public int TrialBoostType; // NYI
|
||||
public int MinimumExpansionLevel;
|
||||
|
||||
@@ -22,12 +22,16 @@ namespace Game.Networking.Packets
|
||||
_worldPacket.WriteUInt32(talentGroupInfo.SpecID);
|
||||
_worldPacket.WriteInt32(talentGroupInfo.TalentIDs.Count);
|
||||
_worldPacket.WriteInt32(talentGroupInfo.PvPTalents.Count);
|
||||
_worldPacket.WriteInt32(talentGroupInfo.GlyphIDs.Count);
|
||||
|
||||
foreach (var talentID in talentGroupInfo.TalentIDs)
|
||||
_worldPacket.WriteUInt16(talentID);
|
||||
|
||||
foreach (PvPTalent talent in talentGroupInfo.PvPTalents)
|
||||
talent.Write(_worldPacket);
|
||||
|
||||
foreach (uint talent in talentGroupInfo.GlyphIDs)
|
||||
_worldPacket.WriteUInt16((ushort)talent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,6 +42,7 @@ namespace Game.Networking.Packets
|
||||
public uint SpecID;
|
||||
public List<ushort> TalentIDs = new();
|
||||
public List<PvPTalent> PvPTalents = new();
|
||||
public List<uint> GlyphIDs = new();
|
||||
}
|
||||
|
||||
public class TalentInfoUpdate
|
||||
@@ -183,6 +188,9 @@ namespace Game.Networking.Packets
|
||||
|
||||
struct GlyphBinding
|
||||
{
|
||||
uint SpellID;
|
||||
ushort GlyphID;
|
||||
|
||||
public GlyphBinding(uint spellId, ushort glyphId)
|
||||
{
|
||||
SpellID = spellId;
|
||||
@@ -194,8 +202,66 @@ namespace Game.Networking.Packets
|
||||
data.WriteUInt32(SpellID);
|
||||
data.WriteUInt16(GlyphID);
|
||||
}
|
||||
}
|
||||
|
||||
uint SpellID;
|
||||
ushort GlyphID;
|
||||
public struct ClassicTalentEntry
|
||||
{
|
||||
public int TalentID;
|
||||
public int Rank;
|
||||
|
||||
public void Write(WorldPacket data)
|
||||
{
|
||||
data.WriteInt32(TalentID);
|
||||
data.WriteInt32(Rank);
|
||||
}
|
||||
}
|
||||
|
||||
public class ClassicTalentGroupInfo
|
||||
{
|
||||
public byte NumTalents;
|
||||
public List<ClassicTalentEntry> Talents = new();
|
||||
public byte NumGlyphs;
|
||||
public List<ushort> GlyphIDs = new();
|
||||
public sbyte Role;
|
||||
public int PrimarySpecialization;
|
||||
|
||||
public void Write(WorldPacket data)
|
||||
{
|
||||
data.WriteUInt8(NumTalents);
|
||||
data.WriteInt32(Talents.Count);
|
||||
|
||||
data.WriteUInt8(NumGlyphs);
|
||||
data.WriteInt32(GlyphIDs.Count);
|
||||
|
||||
data.WriteInt8(Role);
|
||||
data.WriteInt32(PrimarySpecialization);
|
||||
|
||||
foreach (ClassicTalentEntry talentEntry in Talents)
|
||||
talentEntry.Write(data);
|
||||
|
||||
foreach (ushort id in GlyphIDs)
|
||||
data.WriteUInt16(id);
|
||||
}
|
||||
}
|
||||
|
||||
public class ClassicTalentInfoUpdate
|
||||
{
|
||||
public int UnspentTalentPoints;
|
||||
public byte ActiveGroup;
|
||||
public bool IsPetTalents;
|
||||
public List<ClassicTalentGroupInfo> Talents = new();
|
||||
|
||||
public void Write(WorldPacket data)
|
||||
{
|
||||
data.WriteInt32(UnspentTalentPoints);
|
||||
data.WriteUInt8(ActiveGroup);
|
||||
data.WriteInt32(Talents.Count);
|
||||
|
||||
foreach (ClassicTalentGroupInfo talents in Talents)
|
||||
talents.Write(data);
|
||||
|
||||
data.WriteBit(IsPetTalents);
|
||||
data.FlushBits();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,6 +121,7 @@ namespace Game.Networking.Packets
|
||||
public int TraitNodeEntryID;
|
||||
public int Rank;
|
||||
public int GrantedRanks;
|
||||
public int BonusRanks;
|
||||
|
||||
public TraitEntryPacket() { }
|
||||
public TraitEntryPacket(TraitEntry ufEntry)
|
||||
@@ -137,6 +138,7 @@ namespace Game.Networking.Packets
|
||||
TraitNodeEntryID = data.ReadInt32();
|
||||
Rank = data.ReadInt32();
|
||||
GrantedRanks = data.ReadInt32();
|
||||
BonusRanks = data.ReadInt32();
|
||||
}
|
||||
|
||||
public void Write(WorldPacket data)
|
||||
@@ -145,6 +147,7 @@ namespace Game.Networking.Packets
|
||||
data.WriteInt32(TraitNodeEntryID);
|
||||
data.WriteInt32(Rank);
|
||||
data.WriteInt32(GrantedRanks);
|
||||
data.WriteInt32(BonusRanks);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,169 +0,0 @@
|
||||
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
|
||||
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
|
||||
|
||||
using Framework.Constants;
|
||||
using Game.Entities;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Game.Networking.Packets
|
||||
{
|
||||
class VoidTransferResult : ServerPacket
|
||||
{
|
||||
public VoidTransferResult(VoidTransferError result) : base(ServerOpcodes.VoidTransferResult, ConnectionType.Instance)
|
||||
{
|
||||
Result = result;
|
||||
}
|
||||
|
||||
public override void Write()
|
||||
{
|
||||
_worldPacket.WriteInt32((int)Result);
|
||||
}
|
||||
|
||||
public VoidTransferError Result;
|
||||
}
|
||||
|
||||
class UnlockVoidStorage : ClientPacket
|
||||
{
|
||||
public UnlockVoidStorage(WorldPacket packet) : base(packet) { }
|
||||
|
||||
public override void Read()
|
||||
{
|
||||
Npc = _worldPacket.ReadPackedGuid();
|
||||
}
|
||||
|
||||
public ObjectGuid Npc;
|
||||
}
|
||||
|
||||
class QueryVoidStorage : ClientPacket
|
||||
{
|
||||
public QueryVoidStorage(WorldPacket packet) : base(packet) { }
|
||||
|
||||
public override void Read()
|
||||
{
|
||||
Npc = _worldPacket.ReadPackedGuid();
|
||||
}
|
||||
|
||||
public ObjectGuid Npc;
|
||||
}
|
||||
|
||||
class VoidStorageFailed : ServerPacket
|
||||
{
|
||||
public VoidStorageFailed() : base(ServerOpcodes.VoidStorageFailed, ConnectionType.Instance) { }
|
||||
|
||||
public override void Write()
|
||||
{
|
||||
_worldPacket.WriteUInt8(Reason);
|
||||
}
|
||||
|
||||
public byte Reason = 0;
|
||||
}
|
||||
|
||||
class VoidStorageContents : ServerPacket
|
||||
{
|
||||
public VoidStorageContents() : base(ServerOpcodes.VoidStorageContents, ConnectionType.Instance) { }
|
||||
|
||||
public override void Write()
|
||||
{
|
||||
_worldPacket.WriteBits(Items.Count, 8);
|
||||
_worldPacket.FlushBits();
|
||||
|
||||
foreach (VoidItem voidItem in Items)
|
||||
voidItem.Write(_worldPacket);
|
||||
}
|
||||
|
||||
public List<VoidItem> Items = new();
|
||||
}
|
||||
|
||||
class VoidStorageTransfer : ClientPacket
|
||||
{
|
||||
public VoidStorageTransfer(WorldPacket packet) : base(packet) { }
|
||||
|
||||
public override void Read()
|
||||
{
|
||||
Npc = _worldPacket.ReadPackedGuid();
|
||||
var DepositCount = _worldPacket.ReadInt32();
|
||||
var WithdrawalCount = _worldPacket.ReadInt32();
|
||||
|
||||
for (uint i = 0; i < DepositCount; ++i)
|
||||
Deposits[i] = _worldPacket.ReadPackedGuid();
|
||||
|
||||
for (uint i = 0; i < WithdrawalCount; ++i)
|
||||
Withdrawals[i] = _worldPacket.ReadPackedGuid();
|
||||
}
|
||||
|
||||
public ObjectGuid[] Withdrawals = new ObjectGuid[(int)SharedConst.VoidStorageMaxWithdraw];
|
||||
public ObjectGuid[] Deposits = new ObjectGuid[(int)SharedConst.VoidStorageMaxDeposit];
|
||||
public ObjectGuid Npc;
|
||||
}
|
||||
|
||||
class VoidStorageTransferChanges : ServerPacket
|
||||
{
|
||||
public VoidStorageTransferChanges() : base(ServerOpcodes.VoidStorageTransferChanges, ConnectionType.Instance) { }
|
||||
|
||||
public override void Write()
|
||||
{
|
||||
_worldPacket.WriteBits(AddedItems.Count, 4);
|
||||
_worldPacket.WriteBits(RemovedItems.Count, 4);
|
||||
_worldPacket.FlushBits();
|
||||
|
||||
foreach (VoidItem addedItem in AddedItems)
|
||||
addedItem.Write(_worldPacket);
|
||||
|
||||
foreach (ObjectGuid removedItem in RemovedItems)
|
||||
_worldPacket.WritePackedGuid(removedItem);
|
||||
}
|
||||
|
||||
public List<ObjectGuid> RemovedItems = new();
|
||||
public List<VoidItem> AddedItems = new();
|
||||
}
|
||||
|
||||
class SwapVoidItem : ClientPacket
|
||||
{
|
||||
public SwapVoidItem(WorldPacket packet) : base(packet) { }
|
||||
|
||||
public override void Read()
|
||||
{
|
||||
Npc = _worldPacket.ReadPackedGuid();
|
||||
VoidItemGuid = _worldPacket.ReadPackedGuid();
|
||||
DstSlot = _worldPacket.ReadUInt32();
|
||||
}
|
||||
|
||||
public ObjectGuid Npc;
|
||||
public ObjectGuid VoidItemGuid;
|
||||
public uint DstSlot;
|
||||
}
|
||||
|
||||
class VoidItemSwapResponse : ServerPacket
|
||||
{
|
||||
public VoidItemSwapResponse() : base(ServerOpcodes.VoidItemSwapResponse, ConnectionType.Instance) { }
|
||||
|
||||
public override void Write()
|
||||
{
|
||||
_worldPacket.WritePackedGuid(VoidItemA);
|
||||
_worldPacket.WriteUInt32(VoidItemSlotA);
|
||||
_worldPacket.WritePackedGuid(VoidItemB);
|
||||
_worldPacket.WriteUInt32(VoidItemSlotB);
|
||||
}
|
||||
|
||||
public ObjectGuid VoidItemA;
|
||||
public ObjectGuid VoidItemB;
|
||||
public uint VoidItemSlotA;
|
||||
public uint VoidItemSlotB;
|
||||
}
|
||||
|
||||
struct VoidItem
|
||||
{
|
||||
public void Write(WorldPacket data)
|
||||
{
|
||||
data .WritePackedGuid(Guid);
|
||||
data .WritePackedGuid(Creator);
|
||||
data .WriteUInt32(Slot);
|
||||
Item.Write(data);
|
||||
}
|
||||
|
||||
public ObjectGuid Guid;
|
||||
public ObjectGuid Creator;
|
||||
public uint Slot;
|
||||
public ItemInstance Item;
|
||||
}
|
||||
}
|
||||
@@ -4471,6 +4471,7 @@ namespace Game.Spells
|
||||
unitCaster.ClearChannelObjects();
|
||||
unitCaster.SetChannelSpellId(0);
|
||||
unitCaster.SetChannelVisual(new SpellCastVisualField());
|
||||
unitCaster.SetChannelSpellData(0, 0);
|
||||
unitCaster.SetSpellEmpowerStage(-1);
|
||||
}
|
||||
|
||||
@@ -4550,6 +4551,7 @@ namespace Game.Spells
|
||||
|
||||
unitCaster.SetChannelSpellId(m_spellInfo.Id);
|
||||
unitCaster.SetChannelVisual(m_SpellVisual);
|
||||
unitCaster.SetChannelSpellData(GameTime.GetGameTimeMS(), duration);
|
||||
|
||||
void setImmunitiesAndHealPrediction(ref SpellChannelStartInterruptImmunities? interruptImmunities, ref SpellTargetedHealPrediction? healPrediction)
|
||||
{
|
||||
|
||||
@@ -992,9 +992,9 @@ namespace Game.Spells
|
||||
if (chargeCategoryEntry == null)
|
||||
return 0;
|
||||
|
||||
uint charges = chargeCategoryEntry.MaxCharges;
|
||||
charges += (uint)_owner.GetTotalAuraModifierByMiscValue(AuraType.ModMaxCharges, (int)chargeCategoryId);
|
||||
return (int)charges;
|
||||
int charges = chargeCategoryEntry.MaxCharges;
|
||||
charges += _owner.GetTotalAuraModifierByMiscValue(AuraType.ModMaxCharges, (int)chargeCategoryId);
|
||||
return charges;
|
||||
}
|
||||
|
||||
public int GetChargeRecoveryTime(uint chargeCategoryId)
|
||||
|
||||
@@ -4898,6 +4898,10 @@ namespace Game.Spells
|
||||
new StaticData(SpellEffectImplicitTargetTypes.None, SpellTargetObjectTypes.None), // 339 SPELL_EFFECT_UI_ACTION
|
||||
new StaticData(SpellEffectImplicitTargetTypes.None, SpellTargetObjectTypes.None), // 340 SPELL_EFFECT_340
|
||||
new StaticData(SpellEffectImplicitTargetTypes.Explicit, SpellTargetObjectTypes.Unit), // 341 SPELL_EFFECT_LEARN_WARBAND_SCENE
|
||||
new StaticData(SpellEffectImplicitTargetTypes.None, SpellTargetObjectTypes.None), // 342 SPELL_EFFECT_342
|
||||
new StaticData(SpellEffectImplicitTargetTypes.None, SpellTargetObjectTypes.None), // 343 SPELL_EFFECT_343
|
||||
new StaticData(SpellEffectImplicitTargetTypes.None, SpellTargetObjectTypes.None), // 344 SPELL_EFFECT_344
|
||||
new StaticData(SpellEffectImplicitTargetTypes.None, SpellTargetObjectTypes.None), // 345 SPELL_EFFECT_ASSIST_ACTION
|
||||
};
|
||||
|
||||
#region Fields
|
||||
|
||||
@@ -3716,6 +3716,15 @@ namespace Game.Entities
|
||||
});
|
||||
});
|
||||
|
||||
// Summon Faol in Tirisfal
|
||||
ApplySpellFix([202112], spellInfo =>
|
||||
{
|
||||
ApplySpellEffectFix(spellInfo, 0, spellEffectInfo =>
|
||||
{
|
||||
spellEffectInfo.TargetA = new SpellImplicitTargetInfo(Targets.DestDb);
|
||||
});
|
||||
});
|
||||
|
||||
//
|
||||
// VIOLET HOLD SPELLS
|
||||
//
|
||||
@@ -4385,7 +4394,7 @@ namespace Game.Entities
|
||||
});
|
||||
|
||||
// Flame Spout
|
||||
ApplySpellFix([ 114685 ], spellInfo =>
|
||||
ApplySpellFix([114685], spellInfo =>
|
||||
{
|
||||
spellInfo.AttributesEx |= SpellAttr1.NoThreat;
|
||||
spellInfo.AttributesEx8 |= SpellAttr8.CanAttackImmunePC;
|
||||
@@ -4692,17 +4701,23 @@ namespace Game.Entities
|
||||
});
|
||||
|
||||
// Keg Smash
|
||||
ApplySpellFix([ 121253 ], spellInfo =>
|
||||
ApplySpellFix([121253], spellInfo =>
|
||||
{
|
||||
spellInfo._LoadSqrtTargetLimit(5, 0, null, 6, null, null);
|
||||
});
|
||||
|
||||
// Odyn's Fury
|
||||
ApplySpellFix([ 385060, 385061, 385062 ], spellInfo =>
|
||||
ApplySpellFix([385060, 385061, 385062], spellInfo =>
|
||||
{
|
||||
spellInfo._LoadSqrtTargetLimit(5, 0, 385059, 5, null, null);
|
||||
});
|
||||
|
||||
// Flamestrike
|
||||
ApplySpellFix([ 2120 ], spellInfo =>
|
||||
{
|
||||
spellInfo._LoadSqrtTargetLimit(8, 0, null, 2, null, null);
|
||||
});
|
||||
|
||||
Log.outInfo(LogFilter.ServerLoading, $"Loaded SpellInfo target caps in {Time.GetMSTimeDiffToNow(oldMSTime)} ms");
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user