From 36a74cf8735f316ac6cb1e0be6a830261270eb4d Mon Sep 17 00:00:00 2001 From: hondacrx Date: Wed, 6 Sep 2017 12:00:21 -0400 Subject: [PATCH] Misc fixes --- Framework/Constants/ItemConst.cs | 6 +- Framework/Constants/Spells/SpellConst.cs | 4 +- Game/AI/SmartScripts/SmartAI.cs | 6 +- Game/AI/SmartScripts/SmartScript.cs | 21 +-- Game/BattleFields/Zones/WinterGrasp.cs | 150 ++++---------------- Game/BattleFields/Zones/WinterGraspConst.cs | 96 +------------ Game/Entities/Creature/Creature.cs | 21 ++- Game/Entities/Player/Player.Items.cs | 26 +++- Game/Entities/StatSystem.cs | 13 +- Game/Entities/Unit/Unit.Spells.cs | 12 +- Game/Loot/Loot.cs | 4 - Game/Maps/GridNotifiers.cs | 25 ++-- Game/Movement/Generators/HomeMovement.cs | 2 +- Game/Spells/Auras/Aura.cs | 6 +- Game/Spells/Auras/AuraEffect.cs | 58 ++++---- Game/Spells/SpellManager.cs | 13 +- Scripts/Spells/Items.cs | 2 + Scripts/World/GameObjects.cs | 8 +- 18 files changed, 161 insertions(+), 312 deletions(-) diff --git a/Framework/Constants/ItemConst.cs b/Framework/Constants/ItemConst.cs index 53ccfe55b..6a63c55fd 100644 --- a/Framework/Constants/ItemConst.cs +++ b/Framework/Constants/ItemConst.cs @@ -772,7 +772,7 @@ namespace Framework.Constants HeroicTooltip = 0x08, // Makes Green "Heroic" Text Appear On Item Deprecated = 0x10, // Cannot Equip Or Use NoUserDestroy = 0x20, // Item Can Not Be Destroyed, Except By Using Spell (Item Can Be Reagent For Spell) - Playercast = 0x40, + Playercast = 0x40, // Item's spells are castable by players NoEquipCooldown = 0x80, // No Default 30 Seconds Cooldown When Equipped MultiLootQuest = 0x100, IsWrapper = 0x200, // Item Can Wrap Other Items @@ -780,7 +780,7 @@ namespace Framework.Constants MultiDrop = 0x800, // Looting This Item Does Not Remove It From Available Loot ItemPurchaseRecord = 0x1000, // Item Can Be Returned To Vendor For Its Original Cost (Extended Cost) Petition = 0x2000, // Item Is Guild Or Arena Charter - HasText = 0x4000, + HasText = 0x4000, // Only readable items have this (but not all) NoDisenchant = 0x8000, RealDuration = 0x10000, NoCreator = 0x20000, @@ -788,7 +788,7 @@ namespace Framework.Constants UniqueEquippable = 0x80000, // You Can Only Equip One Of These IgnoreForAuras = 0x100000, IgnoreDefaultArenaRestrictions = 0x200000, // Item Can Be Used During Arena Match - NoDurabilityLoss = 0x400000, + NoDurabilityLoss = 0x400000, // Some Thrown weapons have it (and only Thrown) but not all UseWhenShapeshifted = 0x800000, // Item Can Be Used In Shapeshift Forms HasQuestGlow = 0x1000000, HideUnusableRecipe = 0x2000000, // Profession Recipes: Can Only Be Looted If You Meet Requirements And Don'T Already Know It diff --git a/Framework/Constants/Spells/SpellConst.cs b/Framework/Constants/Spells/SpellConst.cs index 33c4d2e12..324c7705a 100644 --- a/Framework/Constants/Spells/SpellConst.cs +++ b/Framework/Constants/Spells/SpellConst.cs @@ -2097,11 +2097,11 @@ namespace Framework.Constants RangedMask = DoneRangedAutoAttack | TakenRangedAutoAttack | DoneSpellRangedDmgClass | TakenSpellRangedDmgClass, - SpellMask = DoneSpellMeleeDmgClass | TakenSpellMeleeDmgClass | DoneSpellRangedDmgClass | TakenSpellRangedDmgClass + SpellMask = DoneSpellMeleeDmgClass | TakenSpellMeleeDmgClass | DoneRangedAutoAttack | TakenRangedAutoAttack| DoneSpellRangedDmgClass | TakenSpellRangedDmgClass | DoneSpellNoneDmgClassPos | TakenSpellNoneDmgClassPos | DoneSpellNoneDmgClassNeg | TakenSpellNoneDmgClassNeg | DoneSpellMagicDmgClassPos | TakenSpellMagicDmgClassPos | DoneSpellMagicDmgClassNeg | TakenSpellMagicDmgClassNeg, - SpellCastMask = SpellMask | DoneTrapActivation | RangedMask, + SpellCastMask = SpellMask | DoneTrapActivation, PeriodicMask = DonePeriodic | TakenPeriodic, diff --git a/Game/AI/SmartScripts/SmartAI.cs b/Game/AI/SmartScripts/SmartAI.cs index e47bb35d8..3964e43aa 100644 --- a/Game/AI/SmartScripts/SmartAI.cs +++ b/Game/AI/SmartScripts/SmartAI.cs @@ -74,11 +74,7 @@ namespace Game.AI bool IsAIControlled() { - if (me.IsControlledByPlayer()) - return false; - if (mIsCharmed) - return false; - return true; + return !mIsCharmed; } void UpdateDespawn(uint diff) diff --git a/Game/AI/SmartScripts/SmartScript.cs b/Game/AI/SmartScripts/SmartScript.cs index 71ab5a06f..b24efa0d5 100644 --- a/Game/AI/SmartScripts/SmartScript.cs +++ b/Game/AI/SmartScripts/SmartScript.cs @@ -54,7 +54,6 @@ namespace Game.AI public void OnReset() { - SetPhase(0); ResetBaseObject(); foreach (var holder in mEvents) { @@ -87,8 +86,7 @@ namespace Game.AI //calc random if (e.GetEventType() != SmartEvents.Link && e.Event.event_chance < 100 && e.Event.event_chance != 0) { - uint rnd = RandomHelper.URand(1, 100); - if (e.Event.event_chance <= rnd) + if (RandomHelper.randChance(e.Event.event_chance)) return; } e.runOnce = true;//used for repeat check @@ -1190,7 +1188,7 @@ namespace Game.AI if (!IsCreature(obj)) continue; - if (!e.Event.event_flags.HasAnyFlag(SmartEventFlags.WhileCharmed) && !IsCreatureInControlOfSelf(obj)) + if (!e.Event.event_flags.HasAnyFlag(SmartEventFlags.WhileCharmed) && IsCharmedCreature(obj)) continue; Position pos = obj.GetPosition(); @@ -2887,7 +2885,7 @@ namespace Game.AI if ((e.Event.event_phase_mask != 0 && !IsInPhase(e.Event.event_phase_mask)) || (e.Event.event_flags.HasAnyFlag(SmartEventFlags.NotRepeatable) && e.runOnce)) return; - if (!e.Event.event_flags.HasAnyFlag(SmartEventFlags.WhileCharmed) && IsCreature(me) && !IsCreatureInControlOfSelf(me)) + if (!e.Event.event_flags.HasAnyFlag(SmartEventFlags.WhileCharmed) && IsCharmedCreature(me)) return; switch (e.GetEventType()) @@ -3924,13 +3922,16 @@ namespace Game.AI bool IsUnit(WorldObject obj) { return obj != null && (obj.IsTypeId(TypeId.Unit) || obj.IsTypeId(TypeId.Player)); } public bool IsPlayer(WorldObject obj) { return obj != null && obj.IsTypeId(TypeId.Player); } bool IsCreature(WorldObject obj) { return obj != null && obj.IsTypeId(TypeId.Unit); } - static bool IsCreatureInControlOfSelf(WorldObject obj) + static bool IsCharmedCreature(WorldObject obj) { - Creature creatureObj = obj?.ToCreature(); - if (creatureObj) - return !creatureObj.IsCharmed() && !creatureObj.IsControlledByPlayer(); - else + if (!obj) return false; + + Creature creatureObj = obj.ToCreature(); + if (creatureObj) + return creatureObj.IsCharmed(); + + return false; } bool IsGameObject(WorldObject obj) { return obj != null && obj.IsTypeId(TypeId.GameObject); } diff --git a/Game/BattleFields/Zones/WinterGrasp.cs b/Game/BattleFields/Zones/WinterGrasp.cs index ccfc8c5cf..cd85e44ed 100644 --- a/Game/BattleFields/Zones/WinterGrasp.cs +++ b/Game/BattleFields/Zones/WinterGrasp.cs @@ -54,8 +54,6 @@ namespace Game.BattleFields for (var team = 0; team < SharedConst.BGTeamsCount; ++team) { - KeepCreature[team] = new List(); - OutsideCreature[team] = new List(); DefenderPortalList[team] = new List(); m_vehicles[team] = new List(); } @@ -104,7 +102,7 @@ namespace Game.BattleFields for (byte i = 0; i < WGConst.MaxWorkshops; i++) { WGWorkshop workshop = new WGWorkshop(this, i); - if (i < WGWorkshopIds.KeepWest) + if (i < WGWorkshopIds.Ne) workshop.GiveControlTo(GetAttackerTeam(), true); else workshop.GiveControlTo(GetDefenderTeam(), true); @@ -113,53 +111,6 @@ namespace Game.BattleFields Workshops.Add(workshop); } - // Spawn NPCs in the defender's keep, both Horde and Alliance - foreach (var npc in WGConst.WGKeepNPC) - { - // Horde npc - Creature creature = SpawnCreature(npc.HordeEntry, npc.Pos); - if (creature) - KeepCreature[TeamId.Horde].Add(creature.GetGUID()); - // Alliance npc - creature = SpawnCreature(npc.AllianceEntry, npc.Pos); - if (creature) - KeepCreature[TeamId.Alliance].Add(creature.GetGUID()); - } - - // Hide NPCs from the Attacker's team in the keep - foreach (var guid in KeepCreature[GetAttackerTeam()]) - { - Creature creature = GetCreature(guid); - if (creature) - HideNpc(creature); - } - - // Spawn Horde NPCs outside the keep - for (var i = 0; i < WGConst.OutsideAllianceNpc; i++) - { - var npc = WGConst.WGOutsideNPC[i]; - Creature creature = SpawnCreature(npc.HordeEntry, npc.Pos); - if (creature) - OutsideCreature[TeamId.Horde].Add(creature.GetGUID()); - } - - // Spawn Alliance NPCs outside the keep - for (var i = WGConst.OutsideAllianceNpc; i < WGConst.MaxOutsideNpcs; i++) - { - var npc = WGConst.WGOutsideNPC[i]; - Creature creature = SpawnCreature(npc.AllianceEntry, npc.Pos); - if (creature) - OutsideCreature[TeamId.Alliance].Add(creature.GetGUID()); - } - - // Hide units outside the keep that are defenders - foreach (var guid in OutsideCreature[GetDefenderTeam()]) - { - Creature creature = GetCreature(guid); - if (creature) - HideNpc(creature); - } - // Spawn turrets and hide them per default foreach (var turret in WGConst.WGTurret) { @@ -349,39 +300,6 @@ namespace Game.BattleFields } } - if (!endByTimer) // One player triggered the relic - { - // Change all npc in keep - foreach (var guid in KeepCreature[GetAttackerTeam()]) - { - Creature creature = GetCreature(guid); - if (creature) - HideNpc(creature); - } - - foreach (var guid in KeepCreature[GetDefenderTeam()]) - { - Creature creature = GetCreature(guid); - if (creature) - ShowNpc(creature, true); - } - - // Change all npc out of keep - foreach (var guid in OutsideCreature[GetDefenderTeam()]) - { - Creature creature = GetCreature(guid); - if (creature) - HideNpc(creature); - } - - foreach (var guid in OutsideCreature[GetAttackerTeam()]) - { - Creature creature = GetCreature(guid); - if (creature) - ShowNpc(creature, true); - }; - } - // Update all graveyard, control is to defender when no wartime for (byte i = 0; i < WGGraveyardId.Horde; i++) { @@ -648,38 +566,9 @@ namespace Game.BattleFields if (killer == victim) return; - bool again = false; - int killerTeam = killer.GetTeamId(); if (victim.IsTypeId(TypeId.Player)) - { - foreach (var guid in m_PlayersInWar[killerTeam]) - { - Player player = Global.ObjAccessor.FindPlayer(guid); - if (player) - if (player.GetDistance2d(killer) < 40) - PromotePlayer(player); - } - return; - } + HandlePromotion(killer, victim); - foreach (var guid in KeepCreature[GetOtherTeam(killerTeam)]) - { - Creature creature = GetCreature(guid); - if (creature) - { - if (victim.GetEntry() == creature.GetEntry() && !again) - { - again = true; - foreach (var guid2 in m_PlayersInWar[killerTeam]) - { - Player player = Global.ObjAccessor.FindPlayer(guid2); - if (player) - if (player.GetDistance2d(killer) < 40.0f) - PromotePlayer(player); - } - } - } - } // @todo Recent PvP activity worldstate } @@ -708,6 +597,19 @@ namespace Game.BattleFields UpdateVehicleCountWG(); } + void HandlePromotion(Player playerKiller, Unit unitKilled) + { + int teamId = playerKiller.GetTeamId(); + + foreach (var guid in m_PlayersInWar[teamId]) + { + Player player = Global.ObjAccessor.FindPlayer(guid); + if (player) + if (player.GetDistance2d(unitKilled) < 40.0f) + PromotePlayer(player); + } + } + // Update rank for player void PromotePlayer(Player killer) { @@ -898,7 +800,19 @@ namespace Game.BattleFields } } - public void BrokenWallOrTower(uint team) { } + public void BrokenWallOrTower(uint team, BfWGGameObjectBuilding building) + { + if (team == GetDefenderTeam()) + { + foreach (var guid in m_PlayersInWar[GetAttackerTeam()]) + { + Player player = Global.ObjAccessor.FindPlayer(guid); + if (player) + if (player.GetDistance2d(GetGameObject(building.GetGUID())) < 50.0f) + player.KilledMonsterCredit(WintergraspQuests.CreditDefendSiege); + } + } + } // Called when a tower is broke public void UpdatedDestroyedTowerCount(uint team) @@ -1120,8 +1034,6 @@ namespace Game.BattleFields List[] m_vehicles = new List[SharedConst.BGTeamsCount]; List CanonList = new List(); - List[] KeepCreature = new List[SharedConst.BGTeamsCount]; - List[] OutsideCreature = new List[SharedConst.BGTeamsCount]; uint m_tenacityStack; uint m_saveTimer; @@ -1253,7 +1165,7 @@ namespace Game.BattleFields break; } - _wg.BrokenWallOrTower(_teamControl); + _wg.BrokenWallOrTower(_teamControl, this); } public void Init(GameObject go) @@ -1641,8 +1553,8 @@ namespace Game.BattleFields public void UpdateGraveyardAndWorkshop() { - if (_staticInfo.WorkshopId < WGWorkshopIds.KeepWest) - _wg.GetGraveyardById(_staticInfo.WorkshopId).GiveControlTo(_teamControl); + if (_staticInfo.WorkshopId < WGWorkshopIds.Ne) + GiveControlTo(_wg.GetAttackerTeam(), true); else GiveControlTo(_wg.GetDefenderTeam(), true); } diff --git a/Game/BattleFields/Zones/WinterGraspConst.cs b/Game/BattleFields/Zones/WinterGraspConst.cs index 05b3367e8..50ebdc469 100644 --- a/Game/BattleFields/Zones/WinterGraspConst.cs +++ b/Game/BattleFields/Zones/WinterGraspConst.cs @@ -129,73 +129,6 @@ namespace Game.BattleFields new Position(5147.98f, 2861.93f, 421.63f, 3.18792f), }; - // Here there is all npc keeper spawn point - public static WintergraspObjectPositionData[] WGKeepNPC = - { - // North East - new WintergraspObjectPositionData(5326.203125f, 2660.026367f, 409.100891f, 2.543383f, WGNpcs.GuardH, WGNpcs.GuardA), // Roaming Guard - new WintergraspObjectPositionData(5298.430176f, 2738.760010f, 409.316010f, 3.971740f, WGNpcs.VieronBlazefeather, WGNpcs.BowyerRandolph), // Vieron Blazefeather - new WintergraspObjectPositionData(5335.310059f, 2764.110107f, 409.274994f, 4.834560f, WGNpcs.GuardH, WGNpcs.GuardA), // Standing Guard - new WintergraspObjectPositionData(5349.810059f, 2763.629883f, 409.333008f, 4.660030f, WGNpcs.GuardH, WGNpcs.GuardA), // Standing Guard - // North - new WintergraspObjectPositionData(5373.470215f, 2789.060059f, 409.322998f, 2.600540f, WGNpcs.StoneGuardMukar, WGNpcs.KnightDameron), // Stone Guard Mukar - new WintergraspObjectPositionData(5296.560059f, 2789.870117f, 409.274994f, 0.733038f, WGNpcs.HoodooMasterFuJin, WGNpcs.SorceressKaylana), // Voodoo Master Fu'jin - new WintergraspObjectPositionData(5372.670000f, 2786.740000f, 409.442000f, 2.809980f, WGNpcs.ChampionRosSlai, WGNpcs.MarshalMagruder), // Wintergrasp Quartermaster - new WintergraspObjectPositionData(5368.709961f, 2856.360107f, 409.322998f, 2.949610f, WGNpcs.GuardH, WGNpcs.GuardA), // Standing Guard - new WintergraspObjectPositionData(5367.910156f, 2826.520020f, 409.322998f, 3.333580f, WGNpcs.GuardH, WGNpcs.GuardA), // Standing Guard - new WintergraspObjectPositionData(5389.270020f, 2847.370117f, 418.759003f, 3.106690f, WGNpcs.GuardH, WGNpcs.GuardA), // Standing Guard - new WintergraspObjectPositionData(5388.560059f, 2834.770020f, 418.759003f, 3.071780f, WGNpcs.GuardH, WGNpcs.GuardA), // Standing Guard - new WintergraspObjectPositionData(5359.129883f, 2837.989990f, 409.364014f, 4.698930f, WGNpcs.CommanderDardosh, WGNpcs.CommanderZanneth), // Commander Dardosh - new WintergraspObjectPositionData(5366.129883f, 2833.399902f, 409.322998f, 3.141590f, WGNpcs.TacticalOfficerKilrath, WGNpcs.TacticalOfficerAhbramis), // Tactical Officer Kilrath - // North West - new WintergraspObjectPositionData(5350.680176f, 2917.010010f, 409.274994f, 1.466080f, WGNpcs.GuardH, WGNpcs.GuardA), // Standing Guard - new WintergraspObjectPositionData(5335.120117f, 2916.800049f, 409.444000f, 1.500980f, WGNpcs.GuardH, WGNpcs.GuardA), // Standing Guard - new WintergraspObjectPositionData(5295.560059f, 2926.669922f, 409.274994f, 0.872665f, WGNpcs.SiegesmithStronghoof, WGNpcs.SiegeMasterStouthandle), // Stronghoof - new WintergraspObjectPositionData(5371.399902f, 3026.510010f, 409.205994f, 3.250030f, WGNpcs.PrimalistMulfort, WGNpcs.AnchoriteTessa), // Primalist Mulfort - new WintergraspObjectPositionData(5392.123535f, 3031.110352f, 409.187683f, 3.677212f, WGNpcs.GuardH, WGNpcs.GuardA), // Roaming Guard - // South - new WintergraspObjectPositionData(5270.060059f, 2847.550049f, 409.274994f, 3.071780f, WGNpcs.GuardH, WGNpcs.GuardA), // Standing Guard - new WintergraspObjectPositionData(5270.160156f, 2833.479980f, 409.274994f, 3.124140f, WGNpcs.GuardH, WGNpcs.GuardA), // Standing Guard - new WintergraspObjectPositionData(5179.109863f, 2837.129883f, 409.274994f, 3.211410f, WGNpcs.GuardH, WGNpcs.GuardA), // Standing Guard - new WintergraspObjectPositionData(5179.669922f, 2846.600098f, 409.274994f, 3.089230f, WGNpcs.GuardH, WGNpcs.GuardA), // Standing Guard - new WintergraspObjectPositionData(5234.970215f, 2883.399902f, 409.274994f, 4.293510f, WGNpcs.LieutenantMurp, WGNpcs.SeniorDemolitionistLegoso), // Lieutenant Murp - // Portal guards (from around the fortress) - new WintergraspObjectPositionData(5319.209473f, 3055.947754f, 409.176636f, 1.020201f, WGNpcs.GuardH, WGNpcs.GuardA), // Standing Guard - new WintergraspObjectPositionData(5311.612305f, 3061.207275f, 408.734161f, 0.965223f, WGNpcs.GuardH, WGNpcs.GuardA), // Standing Guard - new WintergraspObjectPositionData(5264.713379f, 3017.283447f, 408.479706f, 3.482424f, WGNpcs.GuardH, WGNpcs.GuardA), // Standing Guard - new WintergraspObjectPositionData(5269.096191f, 3008.315918f, 408.826294f, 3.843706f, WGNpcs.GuardH, WGNpcs.GuardA), // Standing Guard - new WintergraspObjectPositionData(5201.414551f, 2945.096924f, 409.190735f, 0.945592f, WGNpcs.GuardH, WGNpcs.GuardA), // Standing Guard - new WintergraspObjectPositionData(5193.386230f, 2949.617188f, 409.190735f, 1.145859f, WGNpcs.GuardH, WGNpcs.GuardA), // Standing Guard - new WintergraspObjectPositionData(5148.116211f, 2904.761963f, 409.193756f, 3.368532f, WGNpcs.GuardH, WGNpcs.GuardA), // Standing Guard - new WintergraspObjectPositionData(5153.355957f, 2895.501465f, 409.199310f, 3.549174f, WGNpcs.GuardH, WGNpcs.GuardA), // Standing Guard - new WintergraspObjectPositionData(5154.353027f, 2787.349365f, 409.250183f, 2.555644f, WGNpcs.GuardH, WGNpcs.GuardA), // Standing Guard - new WintergraspObjectPositionData(5150.066406f, 2777.876953f, 409.343903f, 2.708797f, WGNpcs.GuardH, WGNpcs.GuardA), // Standing Guard - new WintergraspObjectPositionData(5193.706543f, 2732.882812f, 409.189514f, 4.845073f, WGNpcs.GuardH, WGNpcs.GuardA), // Standing Guard - new WintergraspObjectPositionData(5202.126953f, 2737.570557f, 409.189514f, 5.375215f, WGNpcs.GuardH, WGNpcs.GuardA), // Standing Guard - new WintergraspObjectPositionData(5269.181152f, 2671.174072f, 409.098999f, 2.457459f, WGNpcs.GuardH, WGNpcs.GuardA), // Standing Guard - new WintergraspObjectPositionData(5264.960938f, 2662.332520f, 409.098999f, 2.598828f, WGNpcs.GuardH, WGNpcs.GuardA), // Standing Guard - new WintergraspObjectPositionData(5307.111816f, 2616.006836f, 409.095734f, 5.355575f, WGNpcs.GuardH, WGNpcs.GuardA), // Standing Guard - new WintergraspObjectPositionData(5316.770996f, 2619.430176f, 409.027740f, 5.363431f, WGNpcs.GuardH, WGNpcs.GuardA) // Standing Guard - }; - - public static WintergraspObjectPositionData[] WGOutsideNPC = - { - new WintergraspObjectPositionData(5032.04f, 3681.79f, 362.980f, 4.210f, WGNpcs.VieronBlazefeather, 0), - new WintergraspObjectPositionData(5020.71f, 3626.19f, 360.150f, 4.640f, WGNpcs.HoodooMasterFuJin, 0), - new WintergraspObjectPositionData(4994.85f, 3660.51f, 359.150f, 2.260f, WGNpcs.CommanderDardosh, 0), - new WintergraspObjectPositionData(5015.46f, 3677.11f, 362.970f, 6.009f, WGNpcs.TacticalOfficerKilrath, 0), - new WintergraspObjectPositionData(5031.12f, 3663.77f, 363.500f, 3.110f, WGNpcs.SiegesmithStronghoof, 0), - new WintergraspObjectPositionData(5042.74f, 3675.82f, 363.060f, 3.358f, WGNpcs.PrimalistMulfort, 0), - new WintergraspObjectPositionData(5014.45f, 3640.87f, 361.390f, 3.280f, WGNpcs.LieutenantMurp, 0), - new WintergraspObjectPositionData(5100.07f, 2168.89f, 365.779f, 1.972f, 0, WGNpcs.BowyerRandolph), - new WintergraspObjectPositionData(5081.70f, 2173.73f, 365.878f, 0.855f, 0, WGNpcs.SorceressKaylana), - new WintergraspObjectPositionData(5078.28f, 2183.70f, 365.029f, 1.466f, 0, WGNpcs.CommanderZanneth), - new WintergraspObjectPositionData(5088.49f, 2188.18f, 365.647f, 5.253f, 0, WGNpcs.TacticalOfficerAhbramis), - new WintergraspObjectPositionData(5095.67f, 2193.28f, 365.924f, 4.939f, 0, WGNpcs.SiegeMasterStouthandle), - new WintergraspObjectPositionData(5088.61f, 2167.66f, 365.689f, 0.680f, 0, WGNpcs.AnchoriteTessa), - new WintergraspObjectPositionData(5080.40f, 2199.00f, 359.489f, 2.967f, 0, WGNpcs.SeniorDemolitionistLegoso), - }; - public static WintergraspGameObjectData[] WGPortalDefenderData = { // Player teleporter @@ -514,26 +447,6 @@ namespace Game.BattleFields public const uint GuardA = 30740; public const uint Stalker = 15214; - public const uint VieronBlazefeather = 31102; - public const uint StoneGuardMukar = 32296; // - public const uint HoodooMasterFuJin = 31101; // - public const uint ChampionRosSlai = 39173; // - public const uint CommanderDardosh = 31091; - public const uint TacticalOfficerKilrath = 31151; - public const uint SiegesmithStronghoof = 31106; - public const uint PrimalistMulfort = 31053; - public const uint LieutenantMurp = 31107; - - public const uint BowyerRandolph = 31052; - public const uint KnightDameron = 32294; // - public const uint SorceressKaylana = 31051; // - public const uint MarshalMagruder = 39172; // - public const uint CommanderZanneth = 31036; - public const uint TacticalOfficerAhbramis = 31153; - public const uint SiegeMasterStouthandle = 31108; - public const uint AnchoriteTessa = 31054; - public const uint SeniorDemolitionistLegoso = 31109; - public const uint TaunkaSpiritGuide = 31841; // Horde Spirit Guide For Wintergrasp public const uint DwarvenSpiritGuide = 31842; // Alliance Spirit Guide For Wintergrasp @@ -581,10 +494,10 @@ namespace Game.BattleFields struct WGWorkshopIds { - public const byte Ne = 0; - public const byte Nw = 1; - public const byte Se = 2; - public const byte Sw = 3; + public const byte Se = 0; + public const byte Sw = 1; + public const byte Ne = 2; + public const byte Nw = 3; public const byte KeepWest = 4; public const byte KeepEast = 5; } @@ -651,6 +564,7 @@ namespace Game.BattleFields public const uint VictoryAlliance = 13181; public const uint VictoryHorde = 13183; public const uint CreditTowersDestroyed = 35074; + public const uint CreditDefendSiege = 31284; } struct WintergraspText diff --git a/Game/Entities/Creature/Creature.cs b/Game/Entities/Creature/Creature.cs index d473e6453..1e00b8a6a 100644 --- a/Game/Entities/Creature/Creature.cs +++ b/Game/Entities/Creature/Creature.cs @@ -1389,23 +1389,22 @@ namespace Game.Entities public void SetSpawnHealth() { + if (m_creatureData == null) + return; + ulong curhealth; if (!m_regenHealth) { - if (m_creatureData != null) + curhealth = m_creatureData.curhealth; + if (curhealth != 0) { - curhealth = m_creatureData.curhealth; - if (curhealth != 0) - { - curhealth = (uint)(curhealth * _GetHealthMod(GetCreatureTemplate().Rank)); - if (curhealth < 1) - curhealth = 1; - } - SetPower(PowerType.Mana, (int)m_creatureData.curmana); + curhealth = (uint)(curhealth * _GetHealthMod(GetCreatureTemplate().Rank)); + if (curhealth < 1) + curhealth = 1; } - else - curhealth = GetHealth(); + + SetPower(PowerType.Mana, (int)m_creatureData.curmana); } else { diff --git a/Game/Entities/Player/Player.Items.cs b/Game/Entities/Player/Player.Items.cs index 1b1518339..3c45012d0 100644 --- a/Game/Entities/Player/Player.Items.cs +++ b/Game/Entities/Player/Player.Items.cs @@ -5315,7 +5315,9 @@ namespace Game.Entities return InventoryResult.ItemMaxLimitCategoryEquippedExceededIs; // there is an equip limit on this item - if (HasItemOrGemWithLimitCategoryEquipped(itemProto.GetItemLimitCategory(), limitEntry.Quantity - limit_count + 1, except_slot)) + if (HasItemWithLimitCategoryEquipped(itemProto.GetItemLimitCategory(), limitEntry.Quantity - limit_count + 1, except_slot)) + return InventoryResult.ItemMaxLimitCategoryEquippedExceededIs; + else if (HasGemWithLimitCategoryEquipped(itemProto.GetItemLimitCategory(), limitEntry.Quantity - limit_count + 1, except_slot)) return InventoryResult.ItemMaxCountEquippedSocketed; } @@ -5484,7 +5486,7 @@ namespace Game.Entities return false; } - bool HasItemOrGemWithLimitCategoryEquipped(uint limitCategory, uint count, byte except_slot) + bool HasItemWithLimitCategoryEquipped(uint limitCategory, uint count, byte except_slot) { uint tempcount = 0; for (byte i = EquipmentSlot.Start; i < EquipmentSlot.End; ++i) @@ -5506,6 +5508,26 @@ namespace Game.Entities if (tempcount >= count) return true; } + } + + return false; + } + + bool HasGemWithLimitCategoryEquipped(uint limitCategory, uint count, byte except_slot) + { + uint tempcount = 0; + for (byte i = EquipmentSlot.Start; i < EquipmentSlot.End; ++i) + { + if (i == except_slot) + continue; + + Item pItem = GetItemByPos(InventorySlots.Bag0, i); + if (!pItem) + continue; + + ItemTemplate pProto = pItem.GetTemplate(); + if (pProto == null) + continue; if (pItem.GetSocketColor(0) != 0 || pItem.GetEnchantmentId(EnchantmentSlot.Prismatic) != 0) { diff --git a/Game/Entities/StatSystem.cs b/Game/Entities/StatSystem.cs index 899bd2d9e..d509b8c17 100644 --- a/Game/Entities/StatSystem.cs +++ b/Game/Entities/StatSystem.cs @@ -755,13 +755,16 @@ namespace Game.Entities chance = playerVictim.GetFloatValue(PlayerFields.ParryPercentage); } } - else if (victim.IsTypeId(TypeId.Unit) && !(victim.ToCreature().GetCreatureTemplate().FlagsExtra.HasAnyFlag(CreatureFlagsExtra.NoParry))) + else { - chance = 6.0f; - chance += victim.GetTotalAuraModifier(AuraType.ModParryPercent); + if (!victim.IsTotem() && !victim.ToCreature().GetCreatureTemplate().FlagsExtra.HasAnyFlag(CreatureFlagsExtra.NoParry)) + { + chance = 6.0f; + chance += victim.GetTotalAuraModifier(AuraType.ModParryPercent); - if (levelDiff > 0) - levelBonus = 1.5f * levelDiff; + if (levelDiff > 0) + levelBonus = 1.5f * levelDiff; + } } chance += levelBonus; diff --git a/Game/Entities/Unit/Unit.Spells.cs b/Game/Entities/Unit/Unit.Spells.cs index d250cbb95..01e29acdd 100644 --- a/Game/Entities/Unit/Unit.Spells.cs +++ b/Game/Entities/Unit/Unit.Spells.cs @@ -894,7 +894,7 @@ namespace Game.Entities canDodge = false; // only if in front - if (victim.HasInArc(MathFunctions.PI, this) || victim.HasAuraType(AuraType.IgnoreHitDirection)) + if (!victim.HasUnitState(UnitState.Controlled) && (victim.HasInArc(MathFunctions.PI, this) || victim.HasAuraType(AuraType.IgnoreHitDirection))) { int deflect_chance = victim.GetTotalAuraModifier(AuraType.DeflectSpells) * 100; tmp += deflect_chance; @@ -1043,8 +1043,7 @@ namespace Game.Entities int tmp = 10000 - HitChance; - int rand = RandomHelper.IRand(0, 10000); - + int rand = RandomHelper.IRand(0, 9999); if (rand < tmp) return SpellMissInfo.Miss; @@ -2157,13 +2156,8 @@ namespace Game.Entities if (victim.HasAuraType(AuraType.IgnoreHitDirection) || victim.HasInArc(MathFunctions.PI, this)) { - // Check creatures flags_extra for disable block - if (victim.IsTypeId(TypeId.Unit) && - victim.ToCreature().GetCreatureTemplate().FlagsExtra.HasAnyFlag(CreatureFlagsExtra.NoBlock)) - return false; - float blockChance = GetUnitBlockChance(attackType, victim); - if (RandomHelper.randChance(blockChance)) + if (blockChance != 0 && RandomHelper.randChance(blockChance)) return true; } return false; diff --git a/Game/Loot/Loot.cs b/Game/Loot/Loot.cs index 9fd6bb757..3d04f10f5 100644 --- a/Game/Loot/Loot.cs +++ b/Game/Loot/Loot.cs @@ -77,10 +77,6 @@ namespace Game.Loots && ((needs_quest || (pProto.GetStartQuest() != 0 && player.GetQuestStatus(pProto.GetStartQuest()) != QuestStatus.None)) && !player.HasQuestForItem(itemid))) return false; - // Don't show bind-when-picked-up unique items if player already has the maximum allowed quantity. - if (pProto.GetBonding() == ItemBondingType.OnAcquire && pProto.GetMaxCount() != 0 && player.GetItemCount(itemid, true) >= pProto.GetMaxCount()) - return false; - return true; } diff --git a/Game/Maps/GridNotifiers.cs b/Game/Maps/GridNotifiers.cs index 856d1230d..fa9d596fa 100644 --- a/Game/Maps/GridNotifiers.cs +++ b/Game/Maps/GridNotifiers.cs @@ -1515,16 +1515,20 @@ namespace Game.Maps public class AnyGroupedUnitInObjectRangeCheck : ICheck { - public AnyGroupedUnitInObjectRangeCheck(WorldObject obj, Unit funit, float range, bool raid) + public AnyGroupedUnitInObjectRangeCheck(WorldObject obj, Unit funit, float range, bool raid, bool playerOnly = false) { _source = obj; _refUnit = funit; _range = range; _raid = raid; + _playerOnly = playerOnly; } public bool Invoke(Unit u) { + if (_playerOnly && !u.IsPlayer()) + return false; + if (_raid) { if (!_refUnit.IsInRaidWith(u)) @@ -1540,6 +1544,7 @@ namespace Game.Maps Unit _refUnit; float _range; bool _raid; + bool _playerOnly; } public class AnyUnitInObjectRangeCheck : ICheck @@ -1593,19 +1598,14 @@ namespace Game.Maps public class AnyAoETargetUnitInObjectRangeCheck : ICheck { - public AnyAoETargetUnitInObjectRangeCheck(WorldObject obj, Unit funit, float range) + public AnyAoETargetUnitInObjectRangeCheck(WorldObject obj, Unit funit, float range, SpellInfo spellInfo = null) { i_obj = obj; i_funit = funit; - _spellInfo = null; + _spellInfo = spellInfo; i_range = range; - Unit check = i_funit; - Unit owner = i_funit.GetOwner(); - if (owner) - check = owner; - i_targetForPlayer = (check.IsTypeId(TypeId.Player)); - if (i_obj.IsTypeId(TypeId.DynamicObject)) + if (_spellInfo == null) _spellInfo = i_obj.ToDynamicObject().GetSpellInfo(); } @@ -1615,13 +1615,12 @@ namespace Game.Maps if (u.IsTypeId(TypeId.Unit) && u.IsTotem()) return false; - if (i_funit._IsValidAttackTarget(u, _spellInfo, i_obj.IsTypeId(TypeId.DynamicObject) ? i_obj : null) && i_obj.IsWithinDistInMap(u, i_range)) - return true; + if (_spellInfo != null && _spellInfo.HasAttribute(SpellAttr3.OnlyTargetPlayers) && !u.IsPlayer()) + return false; - return false; + return i_funit._IsValidAttackTarget(u, _spellInfo, i_obj.IsTypeId(TypeId.DynamicObject) ? i_obj : null) && i_obj.IsWithinDistInMap(u, i_range); } - bool i_targetForPlayer; WorldObject i_obj; Unit i_funit; SpellInfo _spellInfo; diff --git a/Game/Movement/Generators/HomeMovement.cs b/Game/Movement/Generators/HomeMovement.cs index a716a095a..8b9acd6a0 100644 --- a/Game/Movement/Generators/HomeMovement.cs +++ b/Game/Movement/Generators/HomeMovement.cs @@ -35,8 +35,8 @@ namespace Game.AI owner.ClearUnitState(UnitState.Evade); owner.SetWalk(true); owner.LoadCreaturesAddon(); - owner.SetSpawnHealth(); owner.GetAI().JustReachedHome(); + owner.SetSpawnHealth(); } } diff --git a/Game/Spells/Auras/Aura.cs b/Game/Spells/Auras/Aura.cs index 1c2222cda..c70cdfd6b 100644 --- a/Game/Spells/Auras/Aura.cs +++ b/Game/Spells/Auras/Aura.cs @@ -1711,8 +1711,8 @@ namespace Game.Spells if (!Global.SpellMgr.CanSpellTriggerProcOnEvent(procEntry, eventInfo)) return 0; - // check if aura can proc when spell is triggered - if (!procEntry.AttributesMask.HasAnyFlag(ProcAttributes.TriggeredCanProc)) + // check if aura can proc when spell is triggered (exception for hunter auto shot & wands) + if (!procEntry.AttributesMask.HasAnyFlag(ProcAttributes.TriggeredCanProc) && !eventInfo.GetTypeMask().HasAnyFlag(ProcFlags.AutoAttackMask)) { Spell spell = eventInfo.GetProcSpell(); if (spell) @@ -2665,7 +2665,7 @@ namespace Game.Spells List targetList = new List(); if (effect.TargetB.GetTarget() == Targets.DestDynobjAlly || effect.TargetB.GetTarget() == Targets.UnitDestAreaAlly) { - var u_check = new AnyFriendlyUnitInObjectRangeCheck(GetDynobjOwner(), dynObjOwnerCaster, radius); + var u_check = new AnyFriendlyUnitInObjectRangeCheck(GetDynobjOwner(), dynObjOwnerCaster, radius, GetSpellInfo().HasAttribute(SpellAttr3.OnlyTargetPlayers)); var searcher = new UnitListSearcher(GetDynobjOwner(), targetList, u_check); Cell.VisitAllObjects(GetDynobjOwner(), searcher, radius); } diff --git a/Game/Spells/Auras/AuraEffect.cs b/Game/Spells/Auras/AuraEffect.cs index c67cfd0bc..b52c5e074 100644 --- a/Game/Spells/Auras/AuraEffect.cs +++ b/Game/Spells/Auras/AuraEffect.cs @@ -663,21 +663,44 @@ namespace Game.Spells SpellInfo spellInfo = eventInfo.GetSpellInfo(); switch (GetAuraType()) { + case AuraType.ModConfuse: + case AuraType.ModFear: + case AuraType.ModStun: + case AuraType.ModRoot: + case AuraType.Transform: + { + DamageInfo damageInfo = eventInfo.GetDamageInfo(); + if (damageInfo == null || damageInfo.GetDamage() == 0) + return false; + + // Spell own damage at apply won't break CC + if (spellInfo != null) + { + if (spellInfo == GetSpellInfo()) + { + Aura aura = GetBase(); + // called from spellcast, should not have ticked yet + if (aura.GetDuration() == aura.GetMaxDuration()) + return false; + } + } + break; + } case AuraType.MechanicImmunity: case AuraType.ModMechanicResistance: // compare mechanic if (spellInfo == null || !Convert.ToBoolean(spellInfo.GetAllEffectsMechanicMask() & (1 << GetMiscValue()))) - result = false; + return false; break; case AuraType.ModCastingSpeedNotStack: // skip melee hits and instant cast spells if (!eventInfo.GetProcSpell() || eventInfo.GetProcSpell().GetCastTime() == 0) - result = false; + return false; break; case AuraType.ModSpellDamageFromCaster: // Compare casters if (GetCasterGUID() != eventInfo.GetActor().GetGUID()) - result = false; + return false; break; case AuraType.ModPowerCostSchool: case AuraType.ModPowerCostSchoolPct: @@ -685,22 +708,19 @@ namespace Game.Spells // Skip melee hits and spells with wrong school or zero cost if (spellInfo == null || !Convert.ToBoolean((int)spellInfo.GetSchoolMask() & GetMiscValue()) // School Check || !eventInfo.GetProcSpell()) - { - result = false; - break; - } + return false; // Costs Check var costs = eventInfo.GetProcSpell().GetPowerCost(); var m = costs.Find(cost => { return cost.Amount > 0; }); if (m == null) - result = false; + return false; break; } case AuraType.ReflectSpellsSchool: // Skip melee hits and spells with wrong school if (spellInfo == null || !Convert.ToBoolean((int)spellInfo.GetSchoolMask() & GetMiscValue())) - result = false; + return false; break; case AuraType.ProcTriggerSpell: case AuraType.ProcTriggerSpellWithValue: @@ -710,7 +730,7 @@ namespace Game.Spells SpellInfo triggeredSpellInfo = Global.SpellMgr.GetSpellInfo(triggerSpellId); if (triggeredSpellInfo != null) if (aurApp.GetTarget().m_extraAttacks != 0 && triggeredSpellInfo.HasEffect(SpellEffectName.AddExtraAttacks)) - result = false; + return false; break; } default: @@ -6007,24 +6027,12 @@ namespace Game.Spells void HandleBreakableCCAuraProc(AuraApplication aurApp, ProcEventInfo eventInfo) { - DamageInfo damageInfo = eventInfo.GetDamageInfo(); - if (damageInfo == null) - return; + int damageLeft = (int)(GetAmount() - eventInfo.GetDamageInfo().GetDamage()); - // aura own damage at apply won't break CC - if (eventInfo.GetSpellPhaseMask().HasAnyFlag(ProcFlagsSpellPhase.Cast)) - { - SpellInfo spellInfo = eventInfo.GetSpellInfo(); - if (spellInfo != null) - if (spellInfo == GetSpellInfo()) - return; - } - - int damageLeft = GetAmount(); - if (damageLeft < damageInfo.GetDamage()) + if (damageLeft <= 0) aurApp.GetTarget().RemoveAura(aurApp); else - ChangeAmount((int)(damageLeft - damageInfo.GetDamage())); + ChangeAmount(damageLeft); } void HandleProcTriggerSpellAuraProc(AuraApplication aurApp, ProcEventInfo eventInfo) diff --git a/Game/Spells/SpellManager.cs b/Game/Spells/SpellManager.cs index dfb5d693c..c2a850944 100644 --- a/Game/Spells/SpellManager.cs +++ b/Game/Spells/SpellManager.cs @@ -481,8 +481,8 @@ namespace Game.Entities if ((eventInfo.GetTypeMask() & (ProcFlags.Killed | ProcFlags.Kill | ProcFlags.Death)) != 0) return true; - // do triggered cast checks - if (!procEntry.AttributesMask.HasAnyFlag(ProcAttributes.TriggeredCanProc)) + // Do not consider autoattacks as triggered spells + if (!procEntry.AttributesMask.HasAnyFlag(ProcAttributes.TriggeredCanProc) && !eventInfo.GetTypeMask().HasAnyFlag(ProcFlags.AutoAttackMask)) { Spell spell = eventInfo.GetProcSpell(); if (spell) @@ -1686,12 +1686,15 @@ namespace Game.Entities SpellProcEntry procEntry = new SpellProcEntry(); procEntry.SchoolMask = 0; - procEntry.SpellFamilyName = spellInfo.SpellFamilyName; procEntry.ProcFlags = spellInfo.ProcFlags; + procEntry.SpellFamilyName = 0; foreach (SpellEffectInfo effect in spellInfo.GetEffectsForDifficulty(Difficulty.None)) if (effect != null && effect.IsEffect() && isTriggerAura(effect.ApplyAuraName)) procEntry.SpellFamilyMask |= effect.SpellClassMask; + if (procEntry.SpellFamilyMask) + procEntry.SpellFamilyName = spellInfo.SpellFamilyName; + procEntry.SpellTypeMask = ProcFlagsSpellType.MaskAll; procEntry.SpellPhaseMask = ProcFlagsSpellPhase.Hit; procEntry.HitMask = ProcFlagsHit.None; // uses default proc @see SpellMgr::CanSpellTriggerProcOnEvent @@ -2793,6 +2796,10 @@ namespace Game.Entities case 42793: // Burn Body spellInfo.GetEffect(2).MiscValue = 24008; // Fallen Combatant break; + case 59544:// Gift of the Naaru (priest and monk variants) + case 121093: + spellInfo.SpellFamilyFlags[2] = 0x80000000; + break; // VIOLET HOLD SPELLS // case 54258: // Water Globule (Ichoron) diff --git a/Scripts/Spells/Items.cs b/Scripts/Spells/Items.cs index b5f0cfd22..5e44df3e2 100644 --- a/Scripts/Spells/Items.cs +++ b/Scripts/Spells/Items.cs @@ -1657,6 +1657,8 @@ namespace Scripts.Spells.Items { void HandleProc(ProcEventInfo procInfo) { + PreventDefaultAction(); + Unit caster = procInfo.GetActor(); Unit target = GetCaster(); if (!caster || !target) diff --git a/Scripts/World/GameObjects.cs b/Scripts/World/GameObjects.cs index a3ee5b648..35f47f689 100644 --- a/Scripts/World/GameObjects.cs +++ b/Scripts/World/GameObjects.cs @@ -1105,17 +1105,13 @@ namespace Scripts.World if (!Global.GameEventMgr.IsHolidayActive(HolidayIds.FireFestival)) return; - var players = go.GetMap().GetPlayers(); - foreach (var player in players) + var playersNearby = go.GetPlayerListInGrid(go.GetMap().GetVisibilityRange()); + foreach (var player in playersNearby) { if (player.GetTeam() == Team.Horde) - { go.PlayDirectMusic(12325, player); - } else - { go.PlayDirectMusic(12319, player); - } } task.Repeat(TimeSpan.FromSeconds(5)); // Every 5 second's SMSG_PLAY_MUSIC packet (PlayDirectMusic) is pushed to the client (sniffed value)