diff options
Diffstat (limited to 'src')
303 files changed, 7247 insertions, 5491 deletions
diff --git a/src/server/game/AI/CoreAI/GameObjectAI.h b/src/server/game/AI/CoreAI/GameObjectAI.h index b9d385ba675..f4555649210 100644 --- a/src/server/game/AI/CoreAI/GameObjectAI.h +++ b/src/server/game/AI/CoreAI/GameObjectAI.h @@ -33,21 +33,24 @@ class GameObjectAI explicit GameObjectAI(GameObject* g) : go(g) {} virtual ~GameObjectAI() {} - virtual void UpdateAI(const uint32 /*diff*/) {} + virtual void UpdateAI(uint32 /*diff*/) {} virtual void InitializeAI() { Reset(); } virtual void Reset() {}; - static int Permissible(const GameObject* go); + static int Permissible(GameObject const* go); - virtual bool GossipHello(Player* /*player*/) {return false;} - virtual bool GossipSelect(Player* /*player*/, uint32 /*sender*/, uint32 /*action*/) {return false;} - virtual bool GossipSelectCode(Player* /*player*/, uint32 /*sender*/, uint32 /*action*/, const char* /*code*/) {return false;} - virtual bool QuestAccept(Player* /*player*/, Quest const* /*quest*/) {return false;} - virtual bool QuestReward(Player* /*player*/, Quest const* /*quest*/, uint32 /*opt*/) {return false;} - virtual uint32 GetDialogStatus(Player* /*player*/) {return 100;} + virtual bool GossipHello(Player* /*player*/) { return false; } + virtual bool GossipSelect(Player* /*player*/, uint32 /*sender*/, uint32 /*action*/) { return false; } + virtual bool GossipSelectCode(Player* /*player*/, uint32 /*sender*/, uint32 /*action*/, char const* /*code*/) { return false; } + virtual bool QuestAccept(Player* /*player*/, Quest const* /*quest*/) { return false; } + virtual bool QuestReward(Player* /*player*/, Quest const* /*quest*/, uint32 /*opt*/) { return false; } + virtual uint32 GetDialogStatus(Player* /*player*/) { return 100; } virtual void Destroyed(Player* /*player*/, uint32 /*eventId*/) {} + virtual uint32 GetData(uint32 /*id*/) { return 0; } + virtual void SetData64(uint32 /*id*/, uint64 /*value*/) {} + virtual uint64 GetData64(uint32 /*id*/) { return 0; } virtual void SetData(uint32 /*id*/, uint32 /*value*/) {} virtual void OnGameEvent(bool /*start*/, uint16 /*eventId*/) {} virtual void OnStateChanged(uint32 /*state*/, Unit* /*unit*/) { } @@ -58,8 +61,8 @@ class NullGameObjectAI : public GameObjectAI public: explicit NullGameObjectAI(GameObject* g); - void UpdateAI(const uint32 /*diff*/) {} + void UpdateAI(uint32 /*diff*/) {} - static int Permissible(const GameObject* /*go*/) { return PERMIT_BASE_IDLE; } + static int Permissible(GameObject const* /*go*/) { return PERMIT_BASE_IDLE; } }; #endif diff --git a/src/server/game/AI/CoreAI/GuardAI.cpp b/src/server/game/AI/CoreAI/GuardAI.cpp index 252bcbabca5..6e2326ca9d5 100755 --- a/src/server/game/AI/CoreAI/GuardAI.cpp +++ b/src/server/game/AI/CoreAI/GuardAI.cpp @@ -23,7 +23,7 @@ #include "World.h" #include "CreatureAIImpl.h" -int GuardAI::Permissible(const Creature* creature) +int GuardAI::Permissible(Creature const* creature) { if (creature->isGuard()) return PERMIT_BASE_SPECIAL; @@ -31,7 +31,7 @@ int GuardAI::Permissible(const Creature* creature) return PERMIT_BASE_NO; } -GuardAI::GuardAI(Creature* creature) : ScriptedAI(creature), i_victimGuid(0), i_state(STATE_NORMAL), i_tracker(TIME_INTERVAL_LOOK) +GuardAI::GuardAI(Creature* creature) : ScriptedAI(creature) { } @@ -40,108 +40,35 @@ bool GuardAI::CanSeeAlways(WorldObject const* obj) if (!obj->isType(TYPEMASK_UNIT)) return false; - std::list<HostileReference*> t_list = me->getThreatManager().getThreatList(); - for (std::list<HostileReference*>::const_iterator itr = t_list.begin(); itr!= t_list.end(); ++itr) - { - if (Unit* unit = Unit::GetUnit(*me, (*itr)->getUnitGuid())) - if (unit == obj) - return true; - } + std::list<HostileReference*> threatList = me->getThreatManager().getThreatList(); + for (std::list<HostileReference*>::const_iterator itr = threatList.begin(); itr != threatList.end(); ++itr) + if ((*itr)->getUnitGuid() == obj->GetGUID()) + return true; return false; } -void GuardAI::MoveInLineOfSight(Unit* unit) -{ - // Ignore Z for flying creatures - if (!me->CanFly() && me->GetDistanceZ(unit) > CREATURE_Z_ATTACK_RANGE) - return; - - if (!me->getVictim() && me->IsValidAttackTarget(unit) && - (unit->IsHostileToPlayers() || me->IsHostileTo(unit)) && - unit->isInAccessiblePlaceFor(me)) - { - float attackRadius = me->GetAttackDistance(unit); - if (me->IsWithinDistInMap(unit, attackRadius)) - { - //Need add code to let guard support player - AttackStart(unit); - //u->RemoveAurasByType(SPELL_AURA_MOD_STEALTH); - } - } -} - void GuardAI::EnterEvadeMode() { if (!me->isAlive()) { - sLog->outStaticDebug("Creature stopped attacking because he is dead [guid=%u]", me->GetGUIDLow()); me->GetMotionMaster()->MoveIdle(); - - i_state = STATE_NORMAL; - - i_victimGuid = 0; me->CombatStop(true); me->DeleteThreatList(); return; } - Unit* victim = ObjectAccessor::GetUnit(*me, i_victimGuid); - - if (!victim) - { - sLog->outStaticDebug("Creature stopped attacking because victim does not exist [guid=%u]", me->GetGUIDLow()); - } - else if (!victim->isAlive()) - { - sLog->outStaticDebug("Creature stopped attacking because victim is dead [guid=%u]", me->GetGUIDLow()); - } - else if (victim->HasStealthAura()) - { - sLog->outStaticDebug("Creature stopped attacking because victim is using stealth [guid=%u]", me->GetGUIDLow()); - } - else if (victim->isInFlight()) - { - sLog->outStaticDebug("Creature stopped attacking because victim is flying away [guid=%u]", me->GetGUIDLow()); - } - else - { - sLog->outStaticDebug("Creature stopped attacking because victim outran him [guid=%u]", me->GetGUIDLow()); - } + sLog->outDebug(LOG_FILTER_UNITS, "Guard entry: %u enters evade mode.", me->GetEntry()); me->RemoveAllAuras(); me->DeleteThreatList(); - i_victimGuid = 0; me->CombatStop(true); - i_state = STATE_NORMAL; // Remove ChaseMovementGenerator from MotionMaster stack list, and add HomeMovementGenerator instead if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == CHASE_MOTION_TYPE) me->GetMotionMaster()->MoveTargetedHome(); } -void GuardAI::UpdateAI(const uint32 /*diff*/) -{ - // update i_victimGuid if me->getVictim() !=0 and changed - if (!UpdateVictim()) - return; - - Unit* const victim = me->getVictim(); - if (!victim) - return; - - i_victimGuid = victim->GetGUID(); - - if (me->isAttackReady()) - { - if (me->IsWithinMeleeRange(victim)) - { - me->AttackerStateUpdate(victim); - me->resetAttackTimer(); - } - } -} - void GuardAI::JustDied(Unit* killer) { if (Player* player = killer->GetCharmerOrOwnerPlayerOrPlayerItself()) diff --git a/src/server/game/AI/CoreAI/GuardAI.h b/src/server/game/AI/CoreAI/GuardAI.h index c80c5a6c343..c8dd9d54921 100755 --- a/src/server/game/AI/CoreAI/GuardAI.h +++ b/src/server/game/AI/CoreAI/GuardAI.h @@ -20,34 +20,19 @@ #define TRINITY_GUARDAI_H #include "ScriptedCreature.h" -#include "Timer.h" class Creature; class GuardAI : public ScriptedAI { - enum GuardState - { - STATE_NORMAL = 1, - STATE_LOOK_AT_VICTIM = 2 - }; - public: + explicit GuardAI(Creature* creature); - explicit GuardAI(Creature* c); - - void MoveInLineOfSight(Unit*); - void EnterEvadeMode(); - void JustDied(Unit*); + static int Permissible(Creature const* creature); bool CanSeeAlways(WorldObject const* obj); - void UpdateAI(const uint32); - static int Permissible(const Creature*); - - private: - uint64 i_victimGuid; - GuardState i_state; - TimeTracker i_tracker; + void EnterEvadeMode(); + void JustDied(Unit* killer); }; #endif diff --git a/src/server/game/AI/CoreAI/PetAI.cpp b/src/server/game/AI/CoreAI/PetAI.cpp index 295768f9d3e..160b406a6ea 100755 --- a/src/server/game/AI/CoreAI/PetAI.cpp +++ b/src/server/game/AI/CoreAI/PetAI.cpp @@ -109,17 +109,25 @@ void PetAI::UpdateAI(const uint32 diff) } else if (owner && me->GetCharmInfo()) //no victim { - Unit* nextTarget = SelectNextTarget(); + // Only aggressive pets do target search every update. + // Defensive pets do target search only in these cases: + // * Owner attacks something - handled by OwnerAttacked() + // * Owner receives damage - handled by OwnerDamagedBy() + // * Pet is in combat and current target dies - handled by KilledUnit() + if (me->HasReactState(REACT_AGGRESSIVE)) + { + Unit* nextTarget = SelectNextTarget(); - if (me->HasReactState(REACT_PASSIVE)) - _stopAttack(); - else if (nextTarget) - AttackStart(nextTarget); + if (nextTarget) + AttackStart(nextTarget); + else + HandleReturnMovement(); + } else HandleReturnMovement(); } else if (owner && !me->HasUnitState(UNIT_STATE_FOLLOW)) // no charm info and no victim - me->GetMotionMaster()->MoveFollow(owner, PET_FOLLOW_DIST, me->GetFollowAngle()); + HandleReturnMovement(); if (!me->GetCharmInfo()) return; @@ -145,40 +153,56 @@ void PetAI::UpdateAI(const uint32 diff) if (spellInfo->IsPositive()) { - // non combat spells allowed - // only pet spells have IsNonCombatSpell and not fit this reqs: - // Consume Shadows, Lesser Invisibility, so ignore checks for its if (spellInfo->CanBeUsedInCombat()) { - // allow only spell without spell cost or with spell cost but not duration limit - int32 duration = spellInfo->GetDuration(); - if ((spellInfo->ManaCost || spellInfo->ManaCostPercentage || spellInfo->ManaPerSecond) && duration > 0) + // check spell cooldown + if (me->HasSpellCooldown(spellInfo->Id)) continue; - // allow only spell without cooldown > duration - int32 cooldown = spellInfo->GetRecoveryTime(); - if (cooldown >= 0 && duration >= 0 && cooldown > duration) + // Check if we're in combat or commanded to attack + if (!me->isInCombat() && !me->GetCharmInfo()->IsCommandAttack()) continue; } Spell* spell = new Spell(me, spellInfo, TRIGGERED_NONE, 0); - bool spellUsed = false; - for (std::set<uint64>::const_iterator tar = m_AllySet.begin(); tar != m_AllySet.end(); ++tar) - { - Unit* target = ObjectAccessor::GetUnit(*me, *tar); - //only buff targets that are in combat, unless the spell can only be cast while out of combat - if (!target) - continue; + // Some spells can target enemy or friendly (DK Ghoul's Leap) + // Check for enemy first (pet then owner) + Unit* target = me->getAttackerForHelper(); + if (!target && owner) + target = owner->getAttackerForHelper(); - if (spell->CanAutoCast(target)) + if (target) + { + if (CanAttack(target) && spell->CanAutoCast(target)) { targetSpellStore.push_back(std::make_pair(target, spell)); spellUsed = true; - break; } } + + // No enemy, check friendly + if (!spellUsed) + { + for (std::set<uint64>::const_iterator tar = m_AllySet.begin(); tar != m_AllySet.end(); ++tar) + { + Unit* ally = ObjectAccessor::GetUnit(*me, *tar); + + //only buff targets that are in combat, unless the spell can only be cast while out of combat + if (!ally) + continue; + + if (spell->CanAutoCast(ally)) + { + targetSpellStore.push_back(std::make_pair(ally, spell)); + spellUsed = true; + break; + } + } + } + + // No valid targets at all if (!spellUsed) delete spell; } @@ -302,6 +326,47 @@ void PetAI::AttackStart(Unit* target) DoAttack(target, true); } +void PetAI::OwnerDamagedBy(Unit* attacker) +{ + // Called when owner takes damage. Allows defensive pets to know + // that their owner might need help + + if (!attacker) + return; + + // Passive pets don't do anything + if (me->HasReactState(REACT_PASSIVE)) + return; + + // Prevent pet from disengaging from current target + if (me->getVictim() && me->getVictim()->isAlive()) + return; + + // Continue to evaluate and attack if necessary + AttackStart(attacker); +} + +void PetAI::OwnerAttacked(Unit* target) +{ + // Called when owner attacks something. Allows defensive pets to know + // that they need to assist + + // Target might be NULL if called from spell with invalid cast targets + if (!target) + return; + + // Passive pets don't do anything + if (me->HasReactState(REACT_PASSIVE)) + return; + + // Prevent pet from disengaging from current target + if (me->getVictim() && me->getVictim()->isAlive()) + return; + + // Continue to evaluate and attack if necessary + AttackStart(target); +} + Unit* PetAI::SelectNextTarget() { // Provides next target selection after current target death diff --git a/src/server/game/AI/CoreAI/PetAI.h b/src/server/game/AI/CoreAI/PetAI.h index 730ab12a3ca..ed3e2305556 100755 --- a/src/server/game/AI/CoreAI/PetAI.h +++ b/src/server/game/AI/CoreAI/PetAI.h @@ -40,6 +40,8 @@ class PetAI : public CreatureAI void KilledUnit(Unit* /*victim*/); void AttackStart(Unit* target); void MovementInform(uint32 moveType, uint32 data); + void OwnerDamagedBy(Unit* attacker); + void OwnerAttacked(Unit* target); private: bool _isVisible(Unit*) const; diff --git a/src/server/game/AI/CoreAI/TotemAI.cpp b/src/server/game/AI/CoreAI/TotemAI.cpp index 0739b62b605..d12d3c098e8 100755 --- a/src/server/game/AI/CoreAI/TotemAI.cpp +++ b/src/server/game/AI/CoreAI/TotemAI.cpp @@ -27,8 +27,7 @@ #include "GridNotifiersImpl.h" #include "CellImpl.h" -int -TotemAI::Permissible(const Creature* creature) +int TotemAI::Permissible(Creature const* creature) { if (creature->isTotem()) return PERMIT_BASE_PROACTIVE; @@ -41,8 +40,7 @@ TotemAI::TotemAI(Creature* c) : CreatureAI(c), i_victimGuid(0) ASSERT(c->isTotem()); } -void -TotemAI::MoveInLineOfSight(Unit*) +void TotemAI::MoveInLineOfSight(Unit* /*who*/) { } @@ -51,10 +49,9 @@ void TotemAI::EnterEvadeMode() me->CombatStop(true); } -void -TotemAI::UpdateAI(const uint32 /*diff*/) +void TotemAI::UpdateAI(uint32 const /*diff*/) { - if (me->ToTotem()->GetTotemType() != TOTEM_ACTIVE) + if (me->ToTotem()->GetTotemType() != TOTEM_ACTIVE) return; if (!me->isAlive() || me->IsNonMeleeSpellCasted(false)) @@ -98,8 +95,7 @@ TotemAI::UpdateAI(const uint32 /*diff*/) i_victimGuid = 0; } -void -TotemAI::AttackStart(Unit*) +void TotemAI::AttackStart(Unit* /*victim*/) { // Sentry totem sends ping on attack if (me->GetEntry() == SENTRY_TOTEM_ENTRY && me->GetOwner()->GetTypeId() == TYPEID_PLAYER) diff --git a/src/server/game/AI/CoreAI/TotemAI.h b/src/server/game/AI/CoreAI/TotemAI.h index 0fa2920888f..f0d705345ef 100755 --- a/src/server/game/AI/CoreAI/TotemAI.h +++ b/src/server/game/AI/CoreAI/TotemAI.h @@ -31,12 +31,12 @@ class TotemAI : public CreatureAI explicit TotemAI(Creature* c); - void MoveInLineOfSight(Unit*); - void AttackStart(Unit*); + void MoveInLineOfSight(Unit* who); + void AttackStart(Unit* victim); void EnterEvadeMode(); - void UpdateAI(const uint32); - static int Permissible(const Creature*); + void UpdateAI(uint32 const diff); + static int Permissible(Creature const* creature); private: uint64 i_victimGuid; diff --git a/src/server/game/AI/CoreAI/UnitAI.h b/src/server/game/AI/CoreAI/UnitAI.h index b871a25835b..593f0d15e18 100755 --- a/src/server/game/AI/CoreAI/UnitAI.h +++ b/src/server/game/AI/CoreAI/UnitAI.h @@ -223,7 +223,7 @@ class UnitAI targetList.reverse(); if (targetType == SELECT_TARGET_RANDOM) - Trinity::RandomResizeList(targetList, maxTargets); + Trinity::Containers::RandomResizeList(targetList, maxTargets); else targetList.resize(maxTargets); } diff --git a/src/server/game/AI/CreatureAI.h b/src/server/game/AI/CreatureAI.h index 423b00291e7..94ac452b9f3 100755 --- a/src/server/game/AI/CreatureAI.h +++ b/src/server/game/AI/CreatureAI.h @@ -138,6 +138,12 @@ class CreatureAI : public UnitAI // Called at text emote receive from player virtual void ReceiveEmote(Player* /*player*/, uint32 /*emoteId*/) {} + // Called when owner takes damage + virtual void OwnerDamagedBy(Unit* /*attacker*/) {} + + // Called when owner attacks something + virtual void OwnerAttacked(Unit* /*target*/) {} + /// == Triggered Actions Requested ================== // Called when creature attack expected (if creature can and no have current victim) diff --git a/src/server/game/AI/CreatureAIImpl.h b/src/server/game/AI/CreatureAIImpl.h index f568da80b49..d097adf38ec 100755 --- a/src/server/game/AI/CreatureAIImpl.h +++ b/src/server/game/AI/CreatureAIImpl.h @@ -326,11 +326,15 @@ class EventMap : private std::map<uint32, uint32> uint32 GetPhaseMask() const { return (_phase >> 24) & 0xFF; } + bool Empty() const { return empty(); } + // Sets event phase, must be in range 1 - 8 void SetPhase(uint32 phase) { if (phase && phase < 8) _phase = (1 << (phase + 24)); + else if (!phase) + _phase = 0; } // Creates new event entry in map with given id, time, group if given (1 - 8) and phase if given (1 - 8) @@ -604,6 +608,7 @@ inline void UnitAI::DoCast(Unit* victim, uint32 spellId, bool triggered) inline void UnitAI::DoCastVictim(uint32 spellId, bool triggered) { + // Why don't we check for casting unit_state and existing target as we do in DoCast(.. ? me->CastSpell(me->getVictim(), spellId, triggered); } diff --git a/src/server/game/AI/CreatureAISelector.cpp b/src/server/game/AI/CreatureAISelector.cpp index f64bb320542..1a0c6652e74 100755 --- a/src/server/game/AI/CreatureAISelector.cpp +++ b/src/server/game/AI/CreatureAISelector.cpp @@ -82,7 +82,7 @@ namespace FactorySelector { const CreatureAICreator* factory = iter->second; const SelectableAI* p = dynamic_cast<const SelectableAI*>(factory); - ASSERT(p != NULL); + ASSERT(p); int val = p->Permit(creature); if (val > best_val) { @@ -102,7 +102,7 @@ namespace FactorySelector MovementGenerator* selectMovementGenerator(Creature* creature) { MovementGeneratorRegistry& mv_registry(*MovementGeneratorRepository::instance()); - ASSERT(creature->GetCreatureTemplate() != NULL); + ASSERT(creature->GetCreatureTemplate()); const MovementGeneratorCreator* mv_factory = mv_registry.GetRegistryItem(creature->GetDefaultMovementType()); /* if (mv_factory == NULL) @@ -133,6 +133,9 @@ namespace FactorySelector const GameObjectAICreator* ai_factory = NULL; GameObjectAIRegistry& ai_registry(*GameObjectAIRepository::instance()); + if (GameObjectAI* scriptedAI = sScriptMgr->GetGameObjectAI(go)) + return scriptedAI; + ai_factory = ai_registry.GetRegistryItem(go->GetAIName()); //future goAI types go here diff --git a/src/server/game/AI/EventAI/CreatureEventAI.cpp b/src/server/game/AI/EventAI/CreatureEventAI.cpp index 7a2b83273c9..835705a0d7c 100755 --- a/src/server/game/AI/EventAI/CreatureEventAI.cpp +++ b/src/server/game/AI/EventAI/CreatureEventAI.cpp @@ -1107,7 +1107,7 @@ void CreatureEventAI::UpdateAI(const uint32 diff) break; case EVENT_T_RANGE: if (me->getVictim()) - if (me->IsInMap(me->getVictim())) + if (me->IsInMap(me->getVictim()) && me->InSamePhase(me->getVictim())) if (me->IsInRange(me->getVictim(), (float)(*i).Event.range.minDist, (float)(*i).Event.range.maxDist)) ProcessEvent(*i); break; diff --git a/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp b/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp index 5c1bbf0ad06..6d27d251579 100644 --- a/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp +++ b/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp @@ -30,18 +30,6 @@ void SummonList::DoZoneInCombat(uint32 entry) } } -void SummonList::DoAction(uint32 entry, int32 info) -{ - for (iterator i = begin(); i != end();) - { - Creature* summon = Unit::GetCreature(*me, *i); - ++i; - if (summon && summon->IsAIEnabled - && (!entry || summon->GetEntry() == entry)) - summon->AI()->DoAction(info); - } -} - void SummonList::DespawnEntry(uint32 entry) { for (iterator i = begin(); i != end();) @@ -126,15 +114,7 @@ void ScriptedAI::UpdateAI(uint32 const /*diff*/) if (!UpdateVictim()) return; - if (me->isAttackReady()) - { - //If we are within range melee the target - if (me->IsWithinMeleeRange(me->getVictim())) - { - me->AttackerStateUpdate(me->getVictim()); - me->resetAttackTimer(); - } - } + DoMeleeAttackIfReady(); } void ScriptedAI::DoStartMovement(Unit* victim, float distance, float angle) @@ -189,11 +169,11 @@ SpellInfo const* ScriptedAI::SelectSpell(Unit* target, uint32 school, uint32 mec { //No target so we can't cast if (!target) - return false; + return NULL; //Silenced so we can't cast if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED)) - return false; + return NULL; //Using the extended script system we first create a list of viable spells SpellInfo const* apSpell[CREATURE_MAX_SPELLS]; @@ -274,7 +254,7 @@ void ScriptedAI::DoResetThreat() for (std::list<HostileReference*>::iterator itr = threatlist.begin(); itr != threatlist.end(); ++itr) { - Unit* unit = Unit::GetUnit((*me), (*itr)->getUnitGuid()); + Unit* unit = Unit::GetUnit(*me, (*itr)->getUnitGuid()); if (unit && DoGetThreat(unit)) DoModifyThreatPercent(unit, -100); @@ -309,14 +289,13 @@ void ScriptedAI::DoTeleportTo(const float position[4]) void ScriptedAI::DoTeleportPlayer(Unit* unit, float x, float y, float z, float o) { - if (!unit || unit->GetTypeId() != TYPEID_PLAYER) - { - if (unit) - sLog->outError("TSCR: Creature " UI64FMTD " (Entry: %u) Tried to teleport non-player unit (Type: %u GUID: " UI64FMTD ") to x: %f y:%f z: %f o: %f. Aborted.", me->GetGUID(), me->GetEntry(), unit->GetTypeId(), unit->GetGUID(), x, y, z, o); + if (!unit) return; - } - CAST_PLR(unit)->TeleportTo(unit->GetMapId(), x, y, z, o, TELE_TO_NOT_LEAVE_COMBAT); + if (Player* player = unit->ToPlayer()) + player->TeleportTo(unit->GetMapId(), x, y, z, o, TELE_TO_NOT_LEAVE_COMBAT); + else + sLog->outError("TSCR: Creature " UI64FMTD " (Entry: %u) Tried to teleport non-player unit (Type: %u GUID: " UI64FMTD ") to x: %f y:%f z: %f o: %f. Aborted.", me->GetGUID(), me->GetEntry(), unit->GetTypeId(), unit->GetGUID(), x, y, z, o); } void ScriptedAI::DoTeleportAll(float x, float y, float z, float o) diff --git a/src/server/game/AI/ScriptedAI/ScriptedCreature.h b/src/server/game/AI/ScriptedAI/ScriptedCreature.h index a01c993cab6..4fac8b3cba5 100644 --- a/src/server/game/AI/ScriptedAI/ScriptedCreature.h +++ b/src/server/game/AI/ScriptedAI/ScriptedCreature.h @@ -38,7 +38,18 @@ class SummonList : public std::list<uint64> void Despawn(Creature* summon) { remove(summon->GetGUID()); } void DespawnEntry(uint32 entry); void DespawnAll(); - void DoAction(uint32 entry, int32 info); + + template <class Predicate> void DoAction(int32 info, Predicate& predicate, uint16 max = 0) + { + Trinity::Containers::RandomResizeList<uint64, Predicate>(*this, predicate, max); + for (iterator i = begin(); i != end(); ) + { + Creature* summon = Unit::GetCreature(*me, *i++); + if (summon && summon->IsAIEnabled) + summon->AI()->DoAction(info); + } + } + void DoZoneInCombat(uint32 entry = 0); void RemoveNotExisting(); bool HasEntry(uint32 entry); @@ -46,6 +57,22 @@ class SummonList : public std::list<uint64> Creature* me; }; +class EntryCheckPredicate +{ + public: + EntryCheckPredicate(uint32 entry) : _entry(entry) {} + bool operator()(uint64 guid) { return GUID_ENPART(guid) == _entry; } + + private: + uint32 _entry; +}; + +class DummyEntryCheckPredicate +{ + public: + bool operator()(uint64) { return true; } +}; + struct ScriptedAI : public CreatureAI { explicit ScriptedAI(Creature* creature); diff --git a/src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp b/src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp index 688d48b41ad..2243734f642 100644 --- a/src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp +++ b/src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp @@ -383,7 +383,7 @@ void npc_escortAI::FillPointMovementListForCreature() if (movePoints.empty()) return; - ScriptPointVector::const_iterator itrEnd = movePoints.end();; + ScriptPointVector::const_iterator itrEnd = movePoints.end(); for (ScriptPointVector::const_iterator itr = movePoints.begin(); itr != itrEnd; ++itr) { Escort_Waypoint point(itr->uiPointId, itr->fX, itr->fY, itr->fZ, itr->uiWaitTime); diff --git a/src/server/game/AI/SmartScripts/SmartAI.cpp b/src/server/game/AI/SmartScripts/SmartAI.cpp index 4eb7f8a7f50..08f1b18ffad 100644 --- a/src/server/game/AI/SmartScripts/SmartAI.cpp +++ b/src/server/game/AI/SmartScripts/SmartAI.cpp @@ -804,12 +804,12 @@ void SmartAI::SetFollow(Unit* target, float dist, float angle, uint32 credit, ui return; SetRun(mRun); mFollowGuid = target->GetGUID(); - mFollowDist = dist ? dist : PET_FOLLOW_DIST; - mFollowAngle = angle ? angle : me->GetFollowAngle(); + mFollowDist = dist >= 0.0f ? dist : PET_FOLLOW_DIST; + mFollowAngle = angle >= 0.0f ? angle : me->GetFollowAngle(); mFollowArrivedTimer = 1000; mFollowCredit = credit; mFollowArrivedEntry = end; - me->GetMotionMaster()->MoveFollow(target, dist, angle); + me->GetMotionMaster()->MoveFollow(target, mFollowDist, mFollowAngle); mFollowCreditType = creditType; } @@ -854,7 +854,7 @@ int SmartGameObjectAI::Permissible(const GameObject* g) return PERMIT_BASE_NO; } -void SmartGameObjectAI::UpdateAI(const uint32 diff) +void SmartGameObjectAI::UpdateAI(uint32 diff) { GetScript()->OnUpdate(diff); } diff --git a/src/server/game/AI/SmartScripts/SmartAI.h b/src/server/game/AI/SmartScripts/SmartAI.h index 94e5e65cf8b..bfd1c7b9d41 100644 --- a/src/server/game/AI/SmartScripts/SmartAI.h +++ b/src/server/game/AI/SmartScripts/SmartAI.h @@ -239,7 +239,7 @@ public: SmartGameObjectAI(GameObject* g) : GameObjectAI(g), go(g) {} ~SmartGameObjectAI() {} - void UpdateAI(const uint32 diff); + void UpdateAI(uint32 diff); void InitializeAI(); void Reset(); SmartScript* GetScript() { return &mScript; } diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index b2c4fd29868..85b117ccd8c 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -108,8 +108,11 @@ void SmartScript::OnReset() ResetBaseObject(); for (SmartAIEventList::iterator i = mEvents.begin(); i != mEvents.end(); ++i) { - InitTimer((*i)); - (*i).runOnce = false; + if (!((*i).event.event_flags & SMART_EVENT_FLAG_DONT_RESET)) + { + InitTimer((*i)); + (*i).runOnce = false; + } } ProcessEventsFor(SMART_EVENT_RESET); mLastInvoker = 0; @@ -1116,12 +1119,13 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u { for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) { - if (!IsUnit(*itr)) - continue; - (*itr)->GetPosition(x, y, z, o); + x += e.target.x; + y += e.target.y; + z += e.target.z; + o += e.target.o; if (Creature* summon = GetBaseObject()->SummonCreature(e.action.summonCreature.creature, x, y, z, o, (TempSummonType)e.action.summonCreature.type, e.action.summonCreature.duration)) - if (unit && e.action.summonCreature.attackInvoker) + if (e.action.summonCreature.attackInvoker) summon->AI()->AttackStart((*itr)->ToUnit()); } @@ -1151,6 +1155,10 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u continue; (*itr)->GetPosition(x, y, z, o); + x += e.target.x; + y += e.target.y; + z += e.target.z; + o += e.target.o; GetBaseObject()->SummonGameObject(e.action.summonGO.entry, x, y, z, o, 0, 0, 0, 0, e.action.summonGO.despawnTime); } @@ -1862,19 +1870,26 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u if (!targets) break; + ObjectList* storedTargets = GetTargetList(e.action.sendTargetToTarget.id); + if (!storedTargets) + { + delete targets; + return; + } + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) { if (IsCreature(*itr)) { if (SmartAI* ai = CAST_AI(SmartAI, (*itr)->ToCreature()->AI())) - ai->GetScript()->StoreTargetList(GetTargetList(e.action.sendTargetToTarget.id), e.action.sendTargetToTarget.id); + ai->GetScript()->StoreTargetList(new ObjectList(*storedTargets), e.action.sendTargetToTarget.id); // store a copy of target list else sLog->outErrorDb("SmartScript: Action target for SMART_ACTION_SEND_TARGET_TO_TARGET is not using SmartAI, skipping"); } else if (IsGameObject(*itr)) { if (SmartGameObjectAI* ai = CAST_AI(SmartGameObjectAI, (*itr)->ToGameObject()->AI())) - ai->GetScript()->StoreTargetList(GetTargetList(e.action.sendTargetToTarget.id), e.action.sendTargetToTarget.id); + ai->GetScript()->StoreTargetList(new ObjectList(*storedTargets), e.action.sendTargetToTarget.id); // store a copy of target list else sLog->outErrorDb("SmartScript: Action target for SMART_ACTION_SEND_TARGET_TO_TARGET is not using SmartGameObjectAI, skipping"); } @@ -1910,7 +1925,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u break; } default: - sLog->outErrorDb("SmartScript::ProcessAction: Unhandled Action type %u", e.GetActionType()); + sLog->outErrorDb("SmartScript::ProcessAction: Entry %d SourceType %u, Event %u, Unhandled Action type %u", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType()); break; } diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp index b0f1fcb8ede..a7149f37480 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp @@ -324,7 +324,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) sLog->outErrorDb("SmartAIMgr: EntryOrGuid %d, event type %u can not be used for Script type %u", e.entryOrGuid, e.GetEventType(), e.GetScriptType()); return false; } - if (e.action.type >= SMART_ACTION_END) + if (e.action.type <= 0 || e.action.type >= SMART_ACTION_END) { sLog->outErrorDb("SmartAIMgr: EntryOrGuid %d using event(%u) has invalid action type (%u), skipped.", e.entryOrGuid, e.event_id, e.GetActionType()); return false; @@ -334,6 +334,11 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) sLog->outErrorDb("SmartAIMgr: EntryOrGuid %d using event(%u) has invalid phase mask (%u), skipped.", e.entryOrGuid, e.event_id, e.event.event_phase_mask); return false; } + if (e.event.event_flags > SMART_EVENT_FLAGS_ALL) + { + sLog->outErrorDb("SmartAIMgr: EntryOrGuid %d using event(%u) has invalid event flags (%u), skipped.", e.entryOrGuid, e.event_id, e.event.event_flags); + return false; + } if (e.GetScriptType() == SMART_SCRIPT_TYPE_TIMED_ACTIONLIST) { e.event.type = SMART_EVENT_UPDATE_OOC;//force default OOC, can change when calling the script! diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h index e2cd75ee62c..bde7768f036 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h @@ -1165,16 +1165,18 @@ const uint32 SmartAIEventMask[SMART_EVENT_END][2] = enum SmartEventFlags { - SMART_EVENT_FLAG_NOT_REPEATABLE = 0x01, //Event can not repeat - SMART_EVENT_FLAG_DIFFICULTY_0 = 0x02, //Event only occurs in instance difficulty 0 - SMART_EVENT_FLAG_DIFFICULTY_1 = 0x04, //Event only occurs in instance difficulty 1 - SMART_EVENT_FLAG_DIFFICULTY_2 = 0x08, //Event only occurs in instance difficulty 2 - SMART_EVENT_FLAG_DIFFICULTY_3 = 0x10, //Event only occurs in instance difficulty 3 - SMART_EVENT_FLAG_RESERVED_5 = 0x20, - SMART_EVENT_FLAG_RESERVED_6 = 0x40, - SMART_EVENT_FLAG_DEBUG_ONLY = 0x80, //Event only occurs in debug build - - SMART_EVENT_FLAG_DIFFICULTY_ALL = (SMART_EVENT_FLAG_DIFFICULTY_0|SMART_EVENT_FLAG_DIFFICULTY_1|SMART_EVENT_FLAG_DIFFICULTY_2|SMART_EVENT_FLAG_DIFFICULTY_3) + SMART_EVENT_FLAG_NOT_REPEATABLE = 0x001, //Event can not repeat + SMART_EVENT_FLAG_DIFFICULTY_0 = 0x002, //Event only occurs in instance difficulty 0 + SMART_EVENT_FLAG_DIFFICULTY_1 = 0x004, //Event only occurs in instance difficulty 1 + SMART_EVENT_FLAG_DIFFICULTY_2 = 0x008, //Event only occurs in instance difficulty 2 + SMART_EVENT_FLAG_DIFFICULTY_3 = 0x010, //Event only occurs in instance difficulty 3 + SMART_EVENT_FLAG_RESERVED_5 = 0x020, + SMART_EVENT_FLAG_RESERVED_6 = 0x040, + SMART_EVENT_FLAG_DEBUG_ONLY = 0x080, //Event only occurs in debug build + SMART_EVENT_FLAG_DONT_RESET = 0x100, //Event will not reset in SmartScript::OnReset() + + SMART_EVENT_FLAG_DIFFICULTY_ALL = (SMART_EVENT_FLAG_DIFFICULTY_0|SMART_EVENT_FLAG_DIFFICULTY_1|SMART_EVENT_FLAG_DIFFICULTY_2|SMART_EVENT_FLAG_DIFFICULTY_3), + SMART_EVENT_FLAGS_ALL = (SMART_EVENT_FLAG_NOT_REPEATABLE|SMART_EVENT_FLAG_DIFFICULTY_ALL|SMART_EVENT_FLAG_RESERVED_5|SMART_EVENT_FLAG_RESERVED_6|SMART_EVENT_FLAG_DEBUG_ONLY|SMART_EVENT_FLAG_DONT_RESET) }; enum SmartCastFlags diff --git a/src/server/game/Accounts/AccountMgr.cpp b/src/server/game/Accounts/AccountMgr.cpp index 9963ade54f9..8076f800356 100755 --- a/src/server/game/Accounts/AccountMgr.cpp +++ b/src/server/game/Accounts/AccountMgr.cpp @@ -91,10 +91,15 @@ AccountOpResult DeleteAccount(uint32 accountId) stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_TUTORIALS); stmt->setUInt32(0, accountId); CharacterDatabase.Execute(stmt); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ACCOUNT_DATA); stmt->setUInt32(0, accountId); CharacterDatabase.Execute(stmt); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHARACTER_BAN); + stmt->setUInt32(0, accountId); + CharacterDatabase.Execute(stmt); + SQLTransaction trans = LoginDatabase.BeginTransaction(); stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_ACCOUNT); @@ -109,6 +114,10 @@ AccountOpResult DeleteAccount(uint32 accountId) stmt->setUInt32(0, accountId); trans->Append(stmt); + stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_ACCOUNT_BANNED); + stmt->setUInt32(0, accountId); + trans->Append(stmt); + LoginDatabase.CommitTransaction(trans); return AOR_OK; diff --git a/src/server/game/Battlegrounds/ArenaTeam.cpp b/src/server/game/Battlegrounds/ArenaTeam.cpp index b4c86f7ef5f..89151b6395c 100755 --- a/src/server/game/Battlegrounds/ArenaTeam.cpp +++ b/src/server/game/Battlegrounds/ArenaTeam.cpp @@ -145,7 +145,7 @@ bool ArenaTeam::AddMember(uint64 playerGuid) uint32 matchMakerRating; if (result) - matchMakerRating = (*result)[0].GetUInt32(); + matchMakerRating = (*result)[0].GetUInt16(); else matchMakerRating = sWorld->getIntConfig(CONFIG_ARENA_START_MATCHMAKER_RATING); @@ -267,7 +267,7 @@ bool ArenaTeam::LoadMembersFromDB(QueryResult result) if (Empty() || !captainPresentInTeam) { // Arena team is empty or captain is not in team, delete from db - sLog->outErrorDb("ArenaTeam %u does not have any members or its captain is not in team, disbanding it...", TeamId); + sLog->outDebug(LOG_FILTER_BATTLEGROUND, "ArenaTeam %u does not have any members or its captain is not in team, disbanding it...", TeamId); return false; } diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp index f3c393eaa36..9d5858e1ca4 100755 --- a/src/server/game/Battlegrounds/Battleground.cpp +++ b/src/server/game/Battlegrounds/Battleground.cpp @@ -144,6 +144,7 @@ Battleground::Battleground() m_Winner = 2; m_StartTime = 0; m_ResetStatTimer = 0; + m_ValidStartPositionTimer = 0; m_Events = 0; m_IsRated = false; m_BuffChange = false; @@ -177,6 +178,8 @@ Battleground::Battleground() m_ArenaTeamIds[BG_TEAM_ALLIANCE] = 0; m_ArenaTeamIds[BG_TEAM_HORDE] = 0; + m_StartMaxDist = 0.0f; + m_ArenaTeamRatingChanges[BG_TEAM_ALLIANCE] = 0; m_ArenaTeamRatingChanges[BG_TEAM_HORDE] = 0; @@ -291,6 +294,7 @@ void Battleground::Update(uint32 diff) // Update start time and reset stats timer m_StartTime += diff; m_ResetStatTimer += diff; + m_ValidStartPositionTimer += diff; PostUpdateImpl(diff); } @@ -422,7 +426,7 @@ inline void Battleground::_ProcessJoin(uint32 diff) // ********************************************************* ModifyStartDelayTime(diff); - if (m_ResetStatTimer <= 5000) + if (m_ResetStatTimer > 5000) { m_ResetStatTimer = 0; for (BattlegroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr) @@ -453,19 +457,19 @@ inline void Battleground::_ProcessJoin(uint32 diff) // First start warning - 2 or 1 minute SendMessageToAll(StartMessageIds[BG_STARTING_EVENT_FIRST], CHAT_MSG_BG_SYSTEM_NEUTRAL); } - // After 1 minute or 30 seconds, warning is signalled + // After 1 minute or 30 seconds, warning is signaled else if (GetStartDelayTime() <= StartDelayTimes[BG_STARTING_EVENT_SECOND] && !(m_Events & BG_STARTING_EVENT_2)) { m_Events |= BG_STARTING_EVENT_2; SendMessageToAll(StartMessageIds[BG_STARTING_EVENT_SECOND], CHAT_MSG_BG_SYSTEM_NEUTRAL); } - // After 30 or 15 seconds, warning is signalled + // After 30 or 15 seconds, warning is signaled else if (GetStartDelayTime() <= StartDelayTimes[BG_STARTING_EVENT_THIRD] && !(m_Events & BG_STARTING_EVENT_3)) { m_Events |= BG_STARTING_EVENT_3; SendMessageToAll(StartMessageIds[BG_STARTING_EVENT_THIRD], CHAT_MSG_BG_SYSTEM_NEUTRAL); } - // Delay expired (atfer 2 or 1 minute) + // Delay expired (after 2 or 1 minute) else if (GetStartDelayTime() <= 0 && !(m_Events & BG_STARTING_EVENT_4)) { m_Events |= BG_STARTING_EVENT_4; @@ -526,6 +530,33 @@ inline void Battleground::_ProcessJoin(uint32 diff) sWorld->SendWorldText(LANG_BG_STARTED_ANNOUNCE_WORLD, GetName(), GetMinLevel(), GetMaxLevel()); } } + + // Find if the player left our start zone; if so, teleport it back + if (m_ValidStartPositionTimer > 1000) + { + m_ValidStartPositionTimer = 0; + float maxDist = GetStartMaxDist(); + if (maxDist > 0.0f) + { + for (BattlegroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr) + { + if (Player *plr = ObjectAccessor::FindPlayer(itr->first)) + { + float x, y, z, o; + uint32 team = plr->GetBGTeam(); + GetTeamStartLoc(team, x, y, z, o); + + float dist = plr->GetDistance(x, y, z); + + if (dist >= maxDist) + { + sLog->outError("BATTLEGROUND: Sending %s back to start location (map: %u) (possible exploit)", plr->GetName(), GetMapId()); + plr->TeleportTo(GetMapId(), x, y, z, o); + } + } + } + } + } } inline void Battleground::_ProcessLeave(uint32 diff) @@ -1459,9 +1490,8 @@ void Battleground::DoorClose(uint32 type) // If doors are open, close it if (obj->getLootState() == GO_ACTIVATED && obj->GetGoState() != GO_STATE_READY) { - // Change state to allow door to be closed obj->SetLootState(GO_READY); - obj->UseDoorOrButton(RESPAWN_ONE_DAY); + obj->SetGoState(GO_STATE_READY); } } else @@ -1473,9 +1503,8 @@ void Battleground::DoorOpen(uint32 type) { if (GameObject* obj = GetBgMap()->GetGameObject(BgObjects[type])) { - // Change state to be sure they will be opened - obj->SetLootState(GO_READY); - obj->UseDoorOrButton(RESPAWN_ONE_DAY); + obj->SetLootState(GO_ACTIVATED); + obj->SetGoState(GO_STATE_ACTIVE); } else sLog->outError("Battleground::DoorOpen: door gameobject (type: %u, GUID: %u) not found for BG (map: %u, instance id: %u)!", diff --git a/src/server/game/Battlegrounds/Battleground.h b/src/server/game/Battlegrounds/Battleground.h index 32f6ebc92de..01dfbb23033 100755 --- a/src/server/game/Battlegrounds/Battleground.h +++ b/src/server/game/Battlegrounds/Battleground.h @@ -443,6 +443,8 @@ class Battleground Z = m_TeamStartLocZ[idx]; O = m_TeamStartLocO[idx]; } + void SetStartMaxDist(float startMaxDist) { m_StartMaxDist = startMaxDist; } + float GetStartMaxDist() const { return m_StartMaxDist; } // Packet Transfer // method that should fill worldpacket with actual world states (not yet implemented for all battlegrounds!) @@ -617,6 +619,7 @@ class Battleground uint32 m_ClientInstanceID; // the instance-id which is sent to the client and without any other internal use uint32 m_StartTime; uint32 m_ResetStatTimer; + uint32 m_ValidStartPositionTimer; int32 m_EndTime; // it is set to 120000 when bg is ending and it decreases itself uint32 m_LastResurrectTime; BattlegroundBracketId m_BracketId; @@ -698,6 +701,7 @@ class Battleground float m_TeamStartLocY[BG_TEAMS_COUNT]; float m_TeamStartLocZ[BG_TEAMS_COUNT]; float m_TeamStartLocO[BG_TEAMS_COUNT]; + float m_StartMaxDist; uint32 ScriptId; }; #endif diff --git a/src/server/game/Battlegrounds/BattlegroundMgr.cpp b/src/server/game/Battlegrounds/BattlegroundMgr.cpp index e1b99cbdcb9..a106f11ae82 100755 --- a/src/server/game/Battlegrounds/BattlegroundMgr.cpp +++ b/src/server/game/Battlegrounds/BattlegroundMgr.cpp @@ -660,6 +660,7 @@ uint32 BattlegroundMgr::CreateBattleground(CreateBattlegroundData& data) bg->SetName(data.BattlegroundName); bg->SetTeamStartLoc(ALLIANCE, data.Team1StartLocX, data.Team1StartLocY, data.Team1StartLocZ, data.Team1StartLocO); bg->SetTeamStartLoc(HORDE, data.Team2StartLocX, data.Team2StartLocY, data.Team2StartLocZ, data.Team2StartLocO); + bg->SetStartMaxDist(data.StartMaxDist); bg->SetLevelRange(data.LevelMin, data.LevelMax); bg->SetScriptId(data.scriptId); @@ -677,8 +678,8 @@ void BattlegroundMgr::CreateInitialBattlegrounds() uint8 selectionWeight; BattlemasterListEntry const* bl; - // 0 1 2 3 4 5 6 7 8 9 10 - QueryResult result = WorldDatabase.Query("SELECT id, MinPlayersPerTeam, MaxPlayersPerTeam, MinLvl, MaxLvl, AllianceStartLoc, AllianceStartO, HordeStartLoc, HordeStartO, Weight, ScriptName FROM battleground_template"); + // 0 1 2 3 4 5 6 7 8 9 10 11 + QueryResult result = WorldDatabase.Query("SELECT id, MinPlayersPerTeam, MaxPlayersPerTeam, MinLvl, MaxLvl, AllianceStartLoc, AllianceStartO, HordeStartLoc, HordeStartO, StartMaxDist, Weight, ScriptName FROM battleground_template"); if (!result) { @@ -712,17 +713,20 @@ void BattlegroundMgr::CreateInitialBattlegrounds() data.MaxPlayersPerTeam = fields[2].GetUInt16(); data.LevelMin = fields[3].GetUInt8(); data.LevelMax = fields[4].GetUInt8(); - //check values from DB - if (data.MaxPlayersPerTeam == 0 || data.MinPlayersPerTeam == 0 || data.MinPlayersPerTeam > data.MaxPlayersPerTeam) + + // check values from DB + if (data.MaxPlayersPerTeam == 0 || data.MinPlayersPerTeam > data.MaxPlayersPerTeam) { - data.MinPlayersPerTeam = 0; // by default now expected strong full bg requirement - data.MaxPlayersPerTeam = 40; + sLog->outErrorDb("Table `battleground_template` for id %u has bad values for MinPlayersPerTeam (%u) and MaxPlayersPerTeam(%u)", + data.bgTypeId, data.MinPlayersPerTeam, data.MaxPlayersPerTeam); + continue; } + if (data.LevelMin == 0 || data.LevelMax == 0 || data.LevelMin > data.LevelMax) { - //TO-DO: FIX ME - data.LevelMin = 0;//bl->minlvl; - data.LevelMax = 80;//bl->maxlvl; + sLog->outErrorDb("Table `battleground_template` for id %u has bad values for LevelMin (%u) and LevelMax(%u)", + data.bgTypeId, data.LevelMin, data.LevelMax); + continue; } startId = fields[5].GetUInt32(); @@ -767,8 +771,10 @@ void BattlegroundMgr::CreateInitialBattlegrounds() continue; } - selectionWeight = fields[9].GetUInt8(); - data.scriptId = sObjectMgr->GetScriptId(fields[10].GetCString()); + data.StartMaxDist = fields[9].GetFloat(); + + selectionWeight = fields[10].GetUInt8(); + data.scriptId = sObjectMgr->GetScriptId(fields[11].GetCString()); data.BattlegroundName = bl->name[sWorld->GetDefaultDbcLocale()]; data.MapID = bl->mapid[0]; diff --git a/src/server/game/Battlegrounds/BattlegroundMgr.h b/src/server/game/Battlegrounds/BattlegroundMgr.h index 88559d07993..7afb83da0a6 100755 --- a/src/server/game/Battlegrounds/BattlegroundMgr.h +++ b/src/server/game/Battlegrounds/BattlegroundMgr.h @@ -50,6 +50,7 @@ struct CreateBattlegroundData float Team2StartLocY; float Team2StartLocZ; float Team2StartLocO; + float StartMaxDist; uint32 scriptId; }; diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp index 52d2cdefd65..d28f5ddfe6a 100755 --- a/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp @@ -290,7 +290,7 @@ int32 BattlegroundAB::_GetNodeNameId(uint8 node) case BG_AB_NODE_LUMBER_MILL:return LANG_BG_AB_NODE_LUMBER_MILL; case BG_AB_NODE_GOLD_MINE: return LANG_BG_AB_NODE_GOLD_MINE; default: - ASSERT(0); + ASSERT(false); } return 0; } diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundDS.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundDS.cpp index 8a11edf85e6..ccc6a2305b4 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundDS.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundDS.cpp @@ -86,11 +86,8 @@ void BattlegroundDS::PostUpdateImpl(uint32 diff) setWaterFallTimer(BG_DS_WATERFALL_WARNING_DURATION); setWaterFallStatus(BG_DS_WATERFALL_STATUS_WARNING); } - else if (getWaterFallStatus() == BG_DS_WATERFALL_STATUS_WARNING) // Active collision and perform knockback + else if (getWaterFallStatus() == BG_DS_WATERFALL_STATUS_WARNING) // Active collision and start knockback timer { - if (Creature* waterSpout = GetBgMap()->GetCreature(BgCreatures[BG_DS_NPC_WATERFALL_KNOCKBACK])) - waterSpout->CastSpell(waterSpout, BG_DS_SPELL_WATER_SPOUT, true); - if (GameObject* gob = GetBgMap()->GetGameObject(BgObjects[BG_DS_OBJECT_WATER_1])) gob->SetGoState(GO_STATE_READY); diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundDS.h b/src/server/game/Battlegrounds/Zones/BattlegroundDS.h index 12ed91fc922..aaf08ba1313 100755 --- a/src/server/game/Battlegrounds/Zones/BattlegroundDS.h +++ b/src/server/game/Battlegrounds/Zones/BattlegroundDS.h @@ -66,9 +66,9 @@ enum BattlegroundDSData { // These values are NOT blizzlike... need the correct data! BG_DS_WATERFALL_TIMER_MIN = 30000, BG_DS_WATERFALL_TIMER_MAX = 60000, - BG_DS_WATERFALL_WARNING_DURATION = 7000, - BG_DS_WATERFALL_DURATION = 10000, - BG_DS_WATERFALL_KNOCKBACK_TIMER = 500, + BG_DS_WATERFALL_WARNING_DURATION = 5000, + BG_DS_WATERFALL_DURATION = 30000, + BG_DS_WATERFALL_KNOCKBACK_TIMER = 1500, BG_DS_PIPE_KNOCKBACK_FIRST_DELAY = 5000, BG_DS_PIPE_KNOCKBACK_DELAY = 3000, @@ -118,7 +118,7 @@ class BattlegroundDS : public Battleground void setWaterFallStatus(uint8 status) { _waterfallStatus = status; }; uint32 getWaterFallTimer() { return _waterfallTimer; }; void setWaterFallTimer(uint32 timer) { _waterfallTimer = timer; }; - uint32 getWaterFallKnockbackTimer() { return _waterfallTimer; }; + uint32 getWaterFallKnockbackTimer() { return _waterfallKnockbackTimer; }; void setWaterFallKnockbackTimer(uint32 timer) { _waterfallKnockbackTimer = timer; }; uint8 getPipeKnockBackCount() { return _pipeKnockBackCount; }; void setPipeKnockBackCount(uint8 count) { _pipeKnockBackCount = count; }; diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp index f3d0f5520f0..ccc9493e234 100755 --- a/src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp @@ -837,6 +837,7 @@ void BattlegroundIC::DestroyGate(Player* player, GameObject* go) { case GO_HORDE_GATE_1: lang_entry = LANG_BG_IC_NORTH_GATE_DESTROYED; + break; case GO_HORDE_GATE_2: case GO_ALLIANCE_GATE_1: lang_entry = LANG_BG_IC_WEST_GATE_DESTROYED; @@ -930,7 +931,7 @@ Transport* BattlegroundIC::CreateTransport(uint32 goEntry, uint32 period) float o = 1; // creates the Gameobject - if (!t->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_MO_TRANSPORT), goEntry, mapid, x, y, z, o, 100, 0)) + if (!t->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_MO_TRANSPORT), goEntry, mapid, x, y, z, o, 255, 0)) { delete t; return NULL; diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp index 6d784488aad..133a0aec560 100755 --- a/src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp @@ -534,16 +534,16 @@ void BattlegroundSA::EventPlayerDamagedGO(Player* /*player*/, GameObject* go, ui if (eventType == go->GetGOInfo()->building.damagedEvent) { - uint32 i = GetGateIDFromDestroyEventID(eventType); + uint32 i = getGateIdFromDamagedOrDestroyEventId(eventType); GateStatus[i] = BG_SA_GATE_DAMAGED; - uint32 uws = GetWorldStateFromGateID(i); + uint32 uws = getWorldStateFromGateId(i); if (uws) UpdateWorldState(uws, GateStatus[i]); } if (eventType == go->GetGOInfo()->building.destroyedEvent) { - if (go->GetGOInfo()->building.destroyedEvent == 19837) + if (go->GetGOInfo()->building.destroyedEvent == BG_SA_EVENT_ANCIENT_GATE_DESTROYED) SendWarningToAll(LANG_BG_SA_CHAMBER_BREACHED); else SendWarningToAll(LANG_BG_SA_WAS_DESTROYED, go->GetGOInfo()->name.c_str()); @@ -603,7 +603,7 @@ void BattlegroundSA::DemolisherStartState(bool start) void BattlegroundSA::DestroyGate(Player* player, GameObject* go) { - uint32 i = GetGateIDFromDestroyEventID(go->GetGOInfo()->building.destroyedEvent); + uint32 i = getGateIdFromDamagedOrDestroyEventId(go->GetGOInfo()->building.destroyedEvent); if (!GateStatus[i]) return; @@ -612,7 +612,7 @@ void BattlegroundSA::DestroyGate(Player* player, GameObject* go) if (g->GetGOValue()->Building.Health == 0) { GateStatus[i] = BG_SA_GATE_DESTROYED; - uint32 uws = GetWorldStateFromGateID(i); + uint32 uws = getWorldStateFromGateId(i); if (uws) UpdateWorldState(uws, GateStatus[i]); bool rewardHonor = true; @@ -720,8 +720,13 @@ void BattlegroundSA::CaptureGraveyard(BG_SA_Graveyards i, Player* Source) DelCreature(BG_SA_MAXNPC + i); GraveyardStatus[i] = Source->GetTeamId(); - WorldSafeLocsEntry const* sg = NULL; - sg = sWorldSafeLocsStore.LookupEntry(BG_SA_GYEntries[i]); + WorldSafeLocsEntry const* sg = sWorldSafeLocsStore.LookupEntry(BG_SA_GYEntries[i]); + if (!sg) + { + sLog->outError("BattlegroundSA::CaptureGraveyard: non-existant GY entry: %u", BG_SA_GYEntries[i]); + return; + } + AddSpiritGuide(i + BG_SA_MAXNPC, sg->x, sg->y, sg->z, BG_SA_GYOrientation[i], (GraveyardStatus[i] == TEAM_ALLIANCE? ALLIANCE : HORDE)); uint32 npc = 0; uint32 flag = 0; @@ -781,7 +786,7 @@ void BattlegroundSA::CaptureGraveyard(BG_SA_Graveyards i, Player* Source) SendWarningToAll(LANG_BG_SA_H_GY_SOUTH); break; default: - ASSERT(0); + ASSERT(false); break; }; } diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundSA.h b/src/server/game/Battlegrounds/Zones/BattlegroundSA.h index 76a772ff978..c18806490f2 100755 --- a/src/server/game/Battlegrounds/Zones/BattlegroundSA.h +++ b/src/server/game/Battlegrounds/Zones/BattlegroundSA.h @@ -30,8 +30,8 @@ class BattlegroundSAScore : public BattlegroundScore uint8 gates_destroyed; }; -#define BG_SA_FLAG_AMOUNT 3 -#define BG_SA_DEMOLISHER_AMOUNT 4 +#define BG_SA_FLAG_AMOUNT 3 +#define BG_SA_DEMOLISHER_AMOUNT 4 enum BG_SA_Status { @@ -45,45 +45,66 @@ enum BG_SA_Status enum BG_SA_GateState { - BG_SA_GATE_OK = 1, - BG_SA_GATE_DAMAGED = 2, - BG_SA_GATE_DESTROYED = 3 + BG_SA_GATE_OK = 1, + BG_SA_GATE_DAMAGED = 2, + BG_SA_GATE_DESTROYED = 3 +}; + +enum BG_SA_EventIdGate +{ + BG_SA_EVENT_BLUE_GATE_DAMAGED = 19040, + BG_SA_EVENT_BLUE_GATE_DESTROYED = 19045, + + BG_SA_EVENT_GREEN_GATE_DAMAGED = 19041, + BG_SA_EVENT_GREEN_GATE_DESTROYED = 19046, + + BG_SA_EVENT_RED_GATE_DAMAGED = 19042, + BG_SA_EVENT_RED_GATE_DESTROYED = 19047, + + BG_SA_EVENT_PURPLE_GATE_DAMAGED = 19043, + BG_SA_EVENT_PURPLE_GATE_DESTROYED = 19048, + + BG_SA_EVENT_YELLOW_GATE_DAMAGED = 19044, + BG_SA_EVENT_YELLOW_GATE_DESTROYED = 19049, + + BG_SA_EVENT_ANCIENT_GATE_DAMAGED = 19836, + BG_SA_EVENT_ANCIENT_GATE_DESTROYED = 19837 }; enum BG_SA_Timers { - BG_SA_BOAT_START = 60*IN_MILLISECONDS, - BG_SA_WARMUPLENGTH = 120*IN_MILLISECONDS, - BG_SA_ROUNDLENGTH = 600*IN_MILLISECONDS + BG_SA_BOAT_START = 60 * IN_MILLISECONDS, + BG_SA_WARMUPLENGTH = 120 * IN_MILLISECONDS, + BG_SA_ROUNDLENGTH = 600 * IN_MILLISECONDS }; enum BG_SA_WorldStates { - BG_SA_TIMER_MINS = 3559, - BG_SA_TIMER_SEC_TENS = 3560, - BG_SA_TIMER_SEC_DECS = 3561, - BG_SA_ALLY_ATTACKS = 4352, - BG_SA_HORDE_ATTACKS = 4353, - BG_SA_PURPLE_GATEWS = 3614, - BG_SA_RED_GATEWS = 3617, - BG_SA_BLUE_GATEWS = 3620, - BG_SA_GREEN_GATEWS = 3623, - BG_SA_YELLOW_GATEWS = 3638, - BG_SA_ANCIENT_GATEWS = 3849, - BG_SA_LEFT_GY_ALLIANCE = 3635, - BG_SA_RIGHT_GY_ALLIANCE = 3636, - BG_SA_CENTER_GY_ALLIANCE = 3637, - BG_SA_RIGHT_ATT_TOKEN_ALL = 3627, - BG_SA_LEFT_ATT_TOKEN_ALL = 3626, - BG_SA_LEFT_ATT_TOKEN_HRD = 3629, - BG_SA_RIGHT_ATT_TOKEN_HRD = 3628, - BG_SA_HORDE_DEFENCE_TOKEN = 3631, - BG_SA_ALLIANCE_DEFENCE_TOKEN = 3630, - BG_SA_RIGHT_GY_HORDE = 3632, - BG_SA_LEFT_GY_HORDE = 3633, - BG_SA_CENTER_GY_HORDE = 3634, - BG_SA_BONUS_TIMER = 0xdf3, - BG_SA_ENABLE_TIMER = 3564, + BG_SA_TIMER_MINS = 3559, + BG_SA_TIMER_SEC_TENS = 3560, + BG_SA_TIMER_SEC_DECS = 3561, + BG_SA_ALLY_ATTACKS = 4352, + BG_SA_HORDE_ATTACKS = 4353, + BG_SA_PURPLE_GATEWS = 3614, + BG_SA_RED_GATEWS = 3617, + BG_SA_BLUE_GATEWS = 3620, + BG_SA_GREEN_GATEWS = 3623, + BG_SA_YELLOW_GATEWS = 3638, + BG_SA_ANCIENT_GATEWS = 3849, + BG_SA_LEFT_GY_ALLIANCE = 3635, + BG_SA_RIGHT_GY_ALLIANCE = 3636, + BG_SA_CENTER_GY_ALLIANCE = 3637, + BG_SA_RIGHT_ATT_TOKEN_ALL = 3627, + BG_SA_LEFT_ATT_TOKEN_ALL = 3626, + BG_SA_LEFT_ATT_TOKEN_HRD = 3629, + BG_SA_RIGHT_ATT_TOKEN_HRD = 3628, + BG_SA_HORDE_DEFENCE_TOKEN = 3631, + BG_SA_ALLIANCE_DEFENCE_TOKEN = 3630, + BG_SA_RIGHT_GY_HORDE = 3632, + BG_SA_LEFT_GY_HORDE = 3633, + BG_SA_CENTER_GY_HORDE = 3634, + BG_SA_BONUS_TIMER = 0xdf3, + BG_SA_ENABLE_TIMER = 3564, }; enum npc @@ -122,14 +143,14 @@ enum BG_SA_NPCs enum BG_SA_Boat { - BG_SA_BOAT_ONE_A =193182, - BG_SA_BOAT_TWO_H =193183, - BG_SA_BOAT_ONE_H =193184, - BG_SA_BOAT_TWO_A =193185, + BG_SA_BOAT_ONE_A = 193182, + BG_SA_BOAT_TWO_H = 193183, + BG_SA_BOAT_ONE_H = 193184, + BG_SA_BOAT_TWO_A = 193185, }; -const uint32 BG_SA_NpcEntries[BG_SA_MAXNPC] = - { +uint32 const BG_SA_NpcEntries[BG_SA_MAXNPC] = +{ NPC_ANTI_PERSONNAL_CANNON, NPC_ANTI_PERSONNAL_CANNON, NPC_ANTI_PERSONNAL_CANNON, @@ -140,25 +161,25 @@ const uint32 BG_SA_NpcEntries[BG_SA_MAXNPC] = NPC_ANTI_PERSONNAL_CANNON, NPC_ANTI_PERSONNAL_CANNON, NPC_ANTI_PERSONNAL_CANNON, - //4 beach demolishers + // 4 beach demolishers NPC_DEMOLISHER_SA, NPC_DEMOLISHER_SA, NPC_DEMOLISHER_SA, NPC_DEMOLISHER_SA, - //Triggers + // Triggers 23472, 23472, 23472, 23472, 23472, - //Used Demolisher Salesman + // Used Demolisher Salesman NPC_RIGGER_SPARKLIGHT, NPC_GORGRIL_RIGSPARK - }; +}; -const float BG_SA_NpcSpawnlocs[BG_SA_MAXNPC + BG_SA_DEMOLISHER_AMOUNT][4] = +float const BG_SA_NpcSpawnlocs[BG_SA_MAXNPC + BG_SA_DEMOLISHER_AMOUNT][4] = { - //Cannons + // Cannons { 1436.429f, 110.05f, 41.407f, 5.4f }, { 1404.9023f, 84.758f, 41.183f, 5.46f }, { 1068.693f, -86.951f, 93.81f, 0.02f }, @@ -169,21 +190,21 @@ const float BG_SA_NpcSpawnlocs[BG_SA_MAXNPC + BG_SA_DEMOLISHER_AMOUNT][4] = { 1249.634f, -224.189f, 66.72f, 0.635f }, { 1236.213f, 92.287f, 64.965f, 5.751f }, { 1215.11f, 57.772f, 64.739f, 5.78f }, - //Demolishers + // Demolishers { 1611.597656f, -117.270073f, 8.719355f, 2.513274f}, { 1575.562500f, -158.421875f, 5.024450f, 2.129302f}, { 1618.047729f, 61.424641f, 7.248210f, 3.979351f}, { 1575.103149f, 98.873344f, 2.830360f, 3.752458f}, - //trigger + // Triggers { 1453.49f, -250.453f, 30.896f, 4.2883f}, { 1377.05f, 97.036f, 30.8605f, 2.46539f}, { 1186.05f, 58.8048f, 56.5491f, 2.75992f}, { 1042.83f, -72.839f, 84.8145f, 3.58615f}, { 1233.62f, -250.49f, 55.4036f, 3.7016f}, - //Npcs + // Npcs { 1348.644165f, -298.786469f, 31.080130f, 1.710423f}, { 1358.191040f, 195.527786f, 31.018187f, 4.171337f}, - //Demolishers2 + // Demolishers 2 { 1371.055786f, -317.071136f, 35.007359f, 1.947460f}, { 1424.034912f, -260.195190f, 31.084425f, 2.820013f}, { 1353.139893f, 223.745438f, 35.265411f, 4.343684f}, @@ -221,7 +242,7 @@ enum BG_SA_Objects BG_SA_MAXOBJ = BG_SA_BOMB+68 }; -const float BG_SA_ObjSpawnlocs[BG_SA_MAXOBJ][4] = +float const BG_SA_ObjSpawnlocs[BG_SA_MAXOBJ][4] = { { 1411.57f, 108.163f, 28.692f, 5.441f }, { 1055.452f, -108.1f, 82.134f, 0.034f }, @@ -230,30 +251,30 @@ const float BG_SA_ObjSpawnlocs[BG_SA_MAXOBJ][4] = { 1214.681f, 81.21f, 53.413f, 5.745f }, { 878.555f, -108.2f, 117.845f, 0.0f }, { 836.5f, -108.8f, 120.219f, 0.0f }, - //Ships + // Ships { 2679.696777f, -826.891235f, 3.712860f, 5.78367f}, //rot2 1 rot3 0.0002f { 2574.003662f, 981.261475f, 2.603424f, 0.807696f}, - //Sigils + // Sigils { 1414.054f, 106.72f, 41.442f, 5.441f }, { 1060.63f, -107.8f, 94.7f, 0.034f }, { 1433.383f, -216.4f, 43.642f, 0.9736f }, { 1230.75f, -210.724f, 67.611f, 0.5023f }, { 1217.8f, 79.532f, 66.58f, 5.745f }, - //Flagpoles + // Flagpoles { 1215.114258f, -65.711861f, 70.084267f, -3.124123f}, {1338.863892f, -153.336533f, 30.895121f, -2.530723f}, {1309.124268f, 9.410645f, 30.893402f, -1.623156f}, - //Flags + // Flags { 1215.108032f, -65.715767f, 70.084267f, -3.124123f}, { 1338.859253f, -153.327316f, 30.895077f, -2.530723f}, { 1309.192017f, 9.416233f, 30.893402f, 1.518436f}, - //Portal + // Portal {1468.380005f, -225.798996f, 30.896200f, 0.0f}, //blue {1394.270020f, 72.551399f, 31.054300f, 0.0f}, //green {1065.260010f, -89.79501f, 81.073402f, 0.0f}, //yellow {1216.069946f, 47.904301f, 54.278198f, 0.0f}, //purple {1255.569946f, -233.548996f, 56.43699f, 0.0f}, //red - //Bombs + // Bombs {1333.45f, 211.354f, 31.0538f, 5.03666f}, {1334.29f, 209.582f, 31.0532f, 1.28088f}, {1332.72f, 210.049f, 31.0532f, 1.28088f}, @@ -337,7 +358,7 @@ const float BG_SA_ObjSpawnlocs[BG_SA_MAXOBJ][4] = * to get horde ones. */ -const uint32 BG_SA_ObjEntries[BG_SA_MAXOBJ + BG_SA_FLAG_AMOUNT] = +uint32 const BG_SA_ObjEntries[BG_SA_MAXOBJ + BG_SA_FLAG_AMOUNT] = { 190722, 190727, @@ -367,7 +388,7 @@ const uint32 BG_SA_ObjEntries[BG_SA_MAXOBJ + BG_SA_FLAG_AMOUNT] = 190753 }; -const uint32 BG_SA_Factions[2] = +uint32 const BG_SA_Factions[2] = { 1732, 1735, @@ -392,13 +413,13 @@ const uint32 BG_SA_GYEntries[BG_SA_MAX_GY] = 1348, }; -const float BG_SA_GYOrientation[BG_SA_MAX_GY] = +float const BG_SA_GYOrientation[BG_SA_MAX_GY] = { 6.202f, - 1.926f, //right capturable GY - 3.917f, //left capturable GY - 3.104f, //center, capturable - 6.148f, //defender last GY + 1.926f, // right capturable GY + 3.917f, // left capturable GY + 3.104f, // center, capturable + 6.148f, // defender last GY }; struct BG_SA_RoundScore @@ -443,34 +464,60 @@ class BattlegroundSA : public Battleground /// Called when a player use a gamobject (relic) virtual void EventPlayerUsedGO(Player* Source, GameObject* object); /// Return gate id, relative to bg data, according to gameobject id - uint32 GetGateIDFromDestroyEventID(uint32 id) + uint32 getGateIdFromDamagedOrDestroyEventId(uint32 id) { - uint32 i = 0; switch (id) { - case 19046: i = BG_SA_GREEN_GATE; break; //Green gate destroyed - case 19045: i = BG_SA_BLUE_GATE; break; //blue gate - case 19047: i = BG_SA_RED_GATE; break; //red gate - case 19048: i = BG_SA_PURPLE_GATE; break; //purple gate - case 19049: i = BG_SA_YELLOW_GATE; break; //yellow gate - case 19837: i = BG_SA_ANCIENT_GATE; break; //ancient gate + // Green gate + case BG_SA_EVENT_GREEN_GATE_DAMAGED: + case BG_SA_EVENT_GREEN_GATE_DESTROYED: + return BG_SA_GREEN_GATE; + // Blue gate + case BG_SA_EVENT_BLUE_GATE_DAMAGED: + case BG_SA_EVENT_BLUE_GATE_DESTROYED: + return BG_SA_BLUE_GATE; + // Red gate + case BG_SA_EVENT_RED_GATE_DAMAGED: + case BG_SA_EVENT_RED_GATE_DESTROYED: + return BG_SA_RED_GATE; + // Purple gate + case BG_SA_EVENT_PURPLE_GATE_DAMAGED: + case BG_SA_EVENT_PURPLE_GATE_DESTROYED: + return BG_SA_PURPLE_GATE; + // Yellow gate + case BG_SA_EVENT_YELLOW_GATE_DAMAGED: + case BG_SA_EVENT_YELLOW_GATE_DESTROYED: + return BG_SA_YELLOW_GATE; + // Ancient gate + case BG_SA_EVENT_ANCIENT_GATE_DAMAGED: + case BG_SA_EVENT_ANCIENT_GATE_DESTROYED: + return BG_SA_ANCIENT_GATE; + default: + break; } - return i; + return 0; } /// Return worldstate id, according to door id - uint32 GetWorldStateFromGateID(uint32 id) + uint32 getWorldStateFromGateId(uint32 id) { - uint32 uws = 0; switch (id) { - case BG_SA_GREEN_GATE: uws = BG_SA_GREEN_GATEWS; break; - case BG_SA_YELLOW_GATE: uws = BG_SA_YELLOW_GATEWS; break; - case BG_SA_BLUE_GATE: uws = BG_SA_BLUE_GATEWS; break; - case BG_SA_RED_GATE: uws = BG_SA_RED_GATEWS; break; - case BG_SA_PURPLE_GATE: uws = BG_SA_PURPLE_GATEWS; break; - case BG_SA_ANCIENT_GATE: uws = BG_SA_ANCIENT_GATEWS; break; + case BG_SA_GREEN_GATE: + return BG_SA_GREEN_GATEWS; + case BG_SA_YELLOW_GATE: + return BG_SA_YELLOW_GATEWS; + case BG_SA_BLUE_GATE: + return BG_SA_BLUE_GATEWS; + case BG_SA_RED_GATE: + return BG_SA_RED_GATEWS; + case BG_SA_PURPLE_GATE: + return BG_SA_PURPLE_GATEWS; + case BG_SA_ANCIENT_GATE: + return BG_SA_ANCIENT_GATEWS; + default: + break; } - return uws; + return 0; } /// Called on battleground ending diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp index 86ad749b8b7..d100dc645a2 100755 --- a/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp @@ -179,20 +179,20 @@ void BattlegroundWS::StartingEventCloseDoors() void BattlegroundWS::StartingEventOpenDoors() { - for (uint32 i = BG_WS_OBJECT_DOOR_A_1; i <= BG_WS_OBJECT_DOOR_A_4; ++i) + for (uint32 i = BG_WS_OBJECT_DOOR_A_1; i <= BG_WS_OBJECT_DOOR_A_6; ++i) DoorOpen(i); - for (uint32 i = BG_WS_OBJECT_DOOR_H_1; i <= BG_WS_OBJECT_DOOR_H_2; ++i) + for (uint32 i = BG_WS_OBJECT_DOOR_H_1; i <= BG_WS_OBJECT_DOOR_H_4; ++i) DoorOpen(i); + for (uint32 i = BG_WS_OBJECT_A_FLAG; i <= BG_WS_OBJECT_BERSERKBUFF_2; ++i) + SpawnBGObject(i, RESPAWN_IMMEDIATELY); + SpawnBGObject(BG_WS_OBJECT_DOOR_A_5, RESPAWN_ONE_DAY); SpawnBGObject(BG_WS_OBJECT_DOOR_A_6, RESPAWN_ONE_DAY); SpawnBGObject(BG_WS_OBJECT_DOOR_H_3, RESPAWN_ONE_DAY); SpawnBGObject(BG_WS_OBJECT_DOOR_H_4, RESPAWN_ONE_DAY); - for (uint32 i = BG_WS_OBJECT_A_FLAG; i <= BG_WS_OBJECT_BERSERKBUFF_2; ++i) - SpawnBGObject(i, RESPAWN_IMMEDIATELY); - - // players joining later are not egible + // players joining later are not eligibles StartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, WS_EVENT_START_BATTLE); } @@ -476,7 +476,7 @@ void BattlegroundWS::EventPlayerClickedOnFlag(Player* Source, GameObject* target } //Alliance flag on ground(not in base) (returned or picked up again from ground!) - if (GetFlagState(ALLIANCE) == BG_WS_FLAG_STATE_ON_GROUND && Source->IsWithinDistInMap(target_obj, 10) && BgObjects[BG_WS_OBJECT_A_FLAG] == target_obj->GetGUID()) + if (GetFlagState(ALLIANCE) == BG_WS_FLAG_STATE_ON_GROUND && Source->IsWithinDistInMap(target_obj, 10) && target_obj->GetGOInfo()->entry == BG_OBJECT_A_FLAG_GROUND_WS_ENTRY) { if (Source->GetTeam() == ALLIANCE) { @@ -510,7 +510,7 @@ void BattlegroundWS::EventPlayerClickedOnFlag(Player* Source, GameObject* target } //Horde flag on ground(not in base) (returned or picked up again) - if (GetFlagState(HORDE) == BG_WS_FLAG_STATE_ON_GROUND && Source->IsWithinDistInMap(target_obj, 10) && BgObjects[BG_WS_OBJECT_H_FLAG] == target_obj->GetGUID()) + if (GetFlagState(HORDE) == BG_WS_FLAG_STATE_ON_GROUND && Source->IsWithinDistInMap(target_obj, 10) && target_obj->GetGOInfo()->entry == BG_OBJECT_H_FLAG_GROUND_WS_ENTRY) { if (Source->GetTeam() == HORDE) { diff --git a/src/server/game/CMakeLists.txt b/src/server/game/CMakeLists.txt index 1f680f6e9b0..8b81a48c33b 100644 --- a/src/server/game/CMakeLists.txt +++ b/src/server/game/CMakeLists.txt @@ -107,7 +107,6 @@ set(game_STAT_SRCS include_directories( ${CMAKE_BINARY_DIR} ${CMAKE_SOURCE_DIR}/dep/g3dlite/include - ${CMAKE_SOURCE_DIR}/dep/mersennetwister ${CMAKE_SOURCE_DIR}/dep/SFMT ${CMAKE_SOURCE_DIR}/dep/zlib ${CMAKE_SOURCE_DIR}/src/server/collision diff --git a/src/server/game/Calendar/CalendarMgr.cpp b/src/server/game/Calendar/CalendarMgr.cpp index cef68891890..62bc0ab3205 100644 --- a/src/server/game/Calendar/CalendarMgr.cpp +++ b/src/server/game/Calendar/CalendarMgr.cpp @@ -95,9 +95,9 @@ CalendarEventIdList const& CalendarMgr::GetPlayerEvents(uint64 guid) CalendarInvite* CalendarMgr::GetInvite(uint64 inviteId) { - CalendarInviteMap::iterator it = _invites.find(inviteId); - if (it != _invites.end()) - return &(it->second); + CalendarInviteMap::iterator itr = _invites.find(inviteId); + if (itr != _invites.end()) + return &(itr->second); sLog->outError("CalendarMgr::GetInvite: [" UI64FMTD "] not found!", inviteId); return NULL; @@ -105,9 +105,9 @@ CalendarInvite* CalendarMgr::GetInvite(uint64 inviteId) CalendarEvent* CalendarMgr::GetEvent(uint64 eventId) { - CalendarEventMap::iterator it = _events.find(eventId); - if (it != _events.end()) - return &(it->second); + CalendarEventMap::iterator itr = _events.find(eventId); + if (itr != _events.end()) + return &(itr->second); sLog->outError("CalendarMgr::GetEvent: [" UI64FMTD "] not found!", eventId); return NULL; @@ -316,11 +316,6 @@ void CalendarMgr::AddAction(CalendarAction const& action) if (!calendarEvent) return; - CalendarInviteIdList const& inviteIds = calendarEvent->GetInviteIdList(); - for (CalendarInviteIdList::const_iterator it = inviteIds.begin(); it != inviteIds.end(); ++it) - if (uint64 invitee = RemoveInvite(*it)) - SendCalendarEventRemovedAlert(invitee, *calendarEvent); - RemoveEvent(eventId); break; } @@ -464,8 +459,6 @@ bool CalendarMgr::RemoveEvent(uint64 eventId) return false; } - _events.erase(itr); - bool val = true; CalendarInviteIdList const& invites = itr->second.GetInviteIdList(); @@ -474,8 +467,13 @@ bool CalendarMgr::RemoveEvent(uint64 eventId) CalendarInvite* invite = GetInvite(*itrInvites); if (!invite || !RemovePlayerEvent(invite->GetInvitee(), eventId)) val = false; + + if (uint64 invitee = RemoveInvite(*itrInvites)) + SendCalendarEventRemovedAlert(invitee, itr->second); } + _events.erase(itr); + return val; } diff --git a/src/server/game/Chat/Channels/Channel.cpp b/src/server/game/Chat/Channels/Channel.cpp index 92cf4d750a8..0e89601e987 100755 --- a/src/server/game/Chat/Channels/Channel.cpp +++ b/src/server/game/Chat/Channels/Channel.cpp @@ -49,7 +49,6 @@ Channel::Channel(const std::string& name, uint32 channel_id, uint32 Team) } else // it's custom channel { - channel_id = 0; m_flags |= CHANNEL_FLAG_CUSTOM; // If storing custom channels in the db is enabled either load or save the channel diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp index 9992721a6dd..cc64a8e22dd 100755 --- a/src/server/game/Chat/Chat.cpp +++ b/src/server/game/Chat/Chat.cpp @@ -359,7 +359,6 @@ ChatCommand* ChatHandler::getCommandTable() { "summon", SEC_MODERATOR, false, OldHandler<&ChatHandler::HandleSummonCommand>, "", NULL }, { "groupsummon", SEC_MODERATOR, false, OldHandler<&ChatHandler::HandleGroupSummonCommand>, "", NULL }, { "commands", SEC_PLAYER, true, OldHandler<&ChatHandler::HandleCommandsCommand>, "", NULL }, - { "demorph", SEC_GAMEMASTER, false, OldHandler<&ChatHandler::HandleDeMorphCommand>, "", NULL }, { "die", SEC_ADMINISTRATOR, false, OldHandler<&ChatHandler::HandleDieCommand>, "", NULL }, { "revive", SEC_ADMINISTRATOR, true, OldHandler<&ChatHandler::HandleReviveCommand>, "", NULL }, { "dismount", SEC_PLAYER, false, OldHandler<&ChatHandler::HandleDismountCommand>, "", NULL }, @@ -382,7 +381,6 @@ ChatCommand* ChatHandler::getCommandTable() { "linkgrave", SEC_ADMINISTRATOR, false, OldHandler<&ChatHandler::HandleLinkGraveCommand>, "", NULL }, { "neargrave", SEC_ADMINISTRATOR, false, OldHandler<&ChatHandler::HandleNearGraveCommand>, "", NULL }, { "explorecheat", SEC_ADMINISTRATOR, false, OldHandler<&ChatHandler::HandleExploreCheatCommand>, "", NULL }, - { "hover", SEC_ADMINISTRATOR, false, OldHandler<&ChatHandler::HandleHoverCommand>, "", NULL }, { "levelup", SEC_ADMINISTRATOR, false, OldHandler<&ChatHandler::HandleLevelUpCommand>, "", NULL }, { "showarea", SEC_ADMINISTRATOR, false, OldHandler<&ChatHandler::HandleShowAreaCommand>, "", NULL }, { "hidearea", SEC_ADMINISTRATOR, false, OldHandler<&ChatHandler::HandleHideAreaCommand>, "", NULL }, @@ -401,7 +399,7 @@ ChatCommand* ChatHandler::getCommandTable() { "movegens", SEC_ADMINISTRATOR, false, OldHandler<&ChatHandler::HandleMovegensCommand>, "", NULL }, { "cometome", SEC_ADMINISTRATOR, false, OldHandler<&ChatHandler::HandleComeToMeCommand>, "", NULL }, { "damage", SEC_ADMINISTRATOR, false, OldHandler<&ChatHandler::HandleDamageCommand>, "", NULL }, - { "combatstop", SEC_GAMEMASTER, false, OldHandler<&ChatHandler::HandleCombatStopCommand>, "", NULL }, + { "combatstop", SEC_GAMEMASTER, true, OldHandler<&ChatHandler::HandleCombatStopCommand>, "", NULL }, { "flusharenapoints", SEC_ADMINISTRATOR, false, OldHandler<&ChatHandler::HandleFlushArenaPointsCommand>, "", NULL }, { "repairitems", SEC_GAMEMASTER, true, OldHandler<&ChatHandler::HandleRepairitemsCommand>, "", NULL }, { "waterwalk", SEC_GAMEMASTER, false, OldHandler<&ChatHandler::HandleWaterwalkCommand>, "", NULL }, @@ -1335,7 +1333,7 @@ GameTele const* ChatHandler::extractGameTeleFromLink(char* text) // id, or string, or [name] Shift-click form |color|Htele:id|h[name]|h|r char* cId = extractKeyFromLink(text, "Htele"); if (!cId) - return false; + return NULL; // id case (explicit or from shift link) if (cId[0] >= '0' || cId[0] >= '9') @@ -1507,7 +1505,7 @@ char* ChatHandler::extractQuotedArg(char* args) { char* space = strtok(args, "\""); if (!space) - return false; + return NULL; return strtok(NULL, "\""); } } diff --git a/src/server/game/Chat/Chat.h b/src/server/game/Chat/Chat.h index 0a39eb43ddb..e88914a2daf 100755 --- a/src/server/game/Chat/Chat.h +++ b/src/server/game/Chat/Chat.h @@ -286,7 +286,6 @@ class ChatHandler bool HandleActivateObjectCommand(const char* args); bool HandleSpawnTransportCommand(const char* args); bool HandleExploreCheatCommand(const char* args); - bool HandleHoverCommand(const char* args); bool HandleWaterwalkCommand(const char* args); bool HandleLevelUpCommand(const char* args); bool HandleShowAreaCommand(const char* args); diff --git a/src/server/game/Chat/Commands/Level2.cpp b/src/server/game/Chat/Commands/Level2.cpp index cc7c9020d38..52bdcd15163 100755 --- a/src/server/game/Chat/Commands/Level2.cpp +++ b/src/server/game/Chat/Commands/Level2.cpp @@ -205,22 +205,6 @@ bool ChatHandler::HandleItemMoveCommand(const char* args) return true; } -//demorph player or unit -bool ChatHandler::HandleDeMorphCommand(const char* /*args*/) -{ - Unit* target = getSelectedUnit(); - if (!target) - target = m_session->GetPlayer(); - - // check online security - else if (target->GetTypeId() == TYPEID_PLAYER && HasLowerSecurity((Player*)target, 0)) - return false; - - target->DeMorph(); - - return true; -} - //kick player bool ChatHandler::HandleKickPlayerCommand(const char *args) { @@ -713,9 +697,22 @@ bool ChatHandler::HandleLookupEventCommand(const char* args) bool ChatHandler::HandleCombatStopCommand(const char* args) { - Player* target; - if (!extractPlayerTarget((char*)args, &target)) - return false; + Player* target = NULL; + + if (args && strlen(args) > 0) + { + target = sObjectAccessor->FindPlayerByName(args); + if (!target) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + } + + if (!target) + if (!extractPlayerTarget((char*)args, &target)) + return false; // check online security if (HasLowerSecurity(target, 0)) diff --git a/src/server/game/Chat/Commands/Level3.cpp b/src/server/game/Chat/Commands/Level3.cpp index d3417705867..30562bb9662 100755 --- a/src/server/game/Chat/Commands/Level3.cpp +++ b/src/server/game/Chat/Commands/Level3.cpp @@ -441,7 +441,7 @@ bool ChatHandler::HandleListItemCommand(const char *args) Field* fields = result->Fetch(); uint32 item_guid = fields[0].GetUInt32(); uint32 item_bag = fields[1].GetUInt32(); - uint32 item_slot = fields[2].GetUInt32(); + uint8 item_slot = fields[2].GetUInt8(); uint32 owner_guid = fields[3].GetUInt32(); uint32 owner_acc = fields[4].GetUInt32(); std::string owner_name = fields[5].GetString(); @@ -638,7 +638,7 @@ bool ChatHandler::HandleListObjectCommand(const char *args) uint32 obj_count = 0; result = WorldDatabase.PQuery("SELECT COUNT(guid) FROM gameobject WHERE id='%u'", go_id); if (result) - obj_count = (*result)[0].GetUInt32(); + obj_count = (*result)[0].GetUInt64(); if (m_session) { @@ -710,7 +710,7 @@ bool ChatHandler::HandleListCreatureCommand(const char *args) uint32 cr_count = 0; result = WorldDatabase.PQuery("SELECT COUNT(guid) FROM creature WHERE id='%u'", cr_id); if (result) - cr_count = (*result)[0].GetUInt32(); + cr_count = (*result)[0].GetUInt64(); if (m_session) { @@ -2158,25 +2158,6 @@ bool ChatHandler::HandleExploreCheatCommand(const char *args) return true; } -bool ChatHandler::HandleHoverCommand(const char *args) -{ - char* px = strtok((char*)args, " "); - uint32 flag; - if (!px) - flag = 1; - else - flag = atoi(px); - - m_session->GetPlayer()->SetHover(flag); - - if (flag) - SendSysMessage(LANG_HOVER_ENABLED); - else - SendSysMessage(LANG_HOVER_DISABLED); - - return true; -} - void ChatHandler::HandleCharacterLevel(Player* player, uint64 playerGuid, uint32 oldLevel, uint32 newLevel) { if (player) @@ -4593,40 +4574,38 @@ bool ChatHandler::HandleUnFreezeCommand(const char *args) { std::string name; Player* player; - char *TargetName = strtok((char*)args, " "); //get entered name - if (!TargetName) //if no name entered use target - { - player = getSelectedPlayer(); - if (player) //prevent crash with creature as target - name = player->GetName(); - } + char* targetName = strtok((char*)args, " "); // Get entered name - else // if name entered + if (targetName) { - name = TargetName; + name = targetName; normalizePlayerName(name); player = sObjectAccessor->FindPlayerByName(name.c_str()); } + else // If no name was entered - use target + { + player = getSelectedPlayer(); + if (player) + name = player->GetName(); + } - //effect if (player) { PSendSysMessage(LANG_COMMAND_UNFREEZE, name.c_str()); - //Reset player faction + allow combat + allow duels + // Reset player faction + allow combat + allow duels player->setFactionForRace(player->getRace()); player->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - //allow movement and spells + // Remove Freeze spell (allowing movement and spells) player->RemoveAurasDueToSpell(9454); - //save player + // Save player player->SaveToDB(); } - - if (!player) + else { - if (TargetName) + if (targetName) { // Check for offline players PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_GUID_BY_NAME); @@ -4638,12 +4617,13 @@ bool ChatHandler::HandleUnFreezeCommand(const char *args) SendSysMessage(LANG_COMMAND_FREEZE_WRONG); return true; } - //if player found: delete his freeze aura - Field* fields=result->Fetch(); - uint64 pguid = fields[0].GetUInt64(); + + // If player found: delete his freeze aura + Field* fields = result->Fetch(); + uint32 lowGuid = fields[0].GetUInt32(); stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_AURA_FROZEN); - stmt->setUInt32(0, pguid); + stmt->setUInt32(0, lowGuid); CharacterDatabase.Execute(stmt); PSendSysMessage(LANG_COMMAND_UNFREEZE, name.c_str()); diff --git a/src/server/game/Combat/ThreatManager.cpp b/src/server/game/Combat/ThreatManager.cpp index d82e43ba83b..9737d4584ea 100755 --- a/src/server/game/Combat/ThreatManager.cpp +++ b/src/server/game/Combat/ThreatManager.cpp @@ -75,7 +75,7 @@ bool ThreatCalcHelper::isValidProcess(Unit* hatedUnit, Unit* hatingUnit, SpellIn return false; // not in same map or phase - if (!hatedUnit->IsInMap(hatingUnit)) + if (!hatedUnit->IsInMap(hatingUnit) || !hatedUnit->InSamePhase(hatingUnit)) return false; // spell not causing threat @@ -182,6 +182,7 @@ void HostileReference::updateOnlineStatus() && (getTarget()->GetTypeId() != TYPEID_PLAYER || !getTarget()->ToPlayer()->isGameMaster()) && !getTarget()->HasUnitState(UNIT_STATE_IN_FLIGHT) && getTarget()->IsInMap(getSourceUnit()) + && getTarget()->InSamePhase(getSourceUnit()) ) { Creature* creature = getSourceUnit()->ToCreature(); @@ -534,6 +535,7 @@ void ThreatManager::processThreatEvent(ThreatRefStatusChangeEvent* threatRefStat setCurrentVictim(NULL); setDirty(true); } + iOwner->SendRemoveFromThreatListOpcode(hostilRef); iThreatContainer.remove(hostilRef); iThreatOfflineContainer.addReference(hostilRef); } diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp index 3fcabea4c74..4176d9f605b 100755 --- a/src/server/game/Conditions/ConditionMgr.cpp +++ b/src/server/game/Conditions/ConditionMgr.cpp @@ -190,7 +190,7 @@ bool Condition::Meets(ConditionSourceInfo& sourceInfo) } case CONDITION_OBJECT_ENTRY: { - if (object->GetTypeId() == ConditionValue1) + if (uint32(object->GetTypeId()) == ConditionValue1) condMeets = (!ConditionValue2) || (object->GetEntry() == ConditionValue2); break; } @@ -274,6 +274,12 @@ bool Condition::Meets(ConditionSourceInfo& sourceInfo) condMeets = object->GetPhaseMask() & ConditionValue1; break; } + case CONDITION_TITLE: + { + if (Player* player = object->ToPlayer()) + condMeets = player->HasTitle(ConditionValue1); + break; + } default: condMeets = false; break; @@ -422,6 +428,9 @@ uint32 Condition::GetSearcherTypeMaskForCondition() case CONDITION_PHASEMASK: mask |= GRID_MAP_TYPE_MASK_ALL; break; + case CONDITION_TITLE: + mask |= GRID_MAP_TYPE_MASK_PLAYER; + break; default: ASSERT(false && "Condition::GetSearcherTypeMaskForCondition - missing condition handling!"); break; @@ -1826,9 +1835,16 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond) sLog->outErrorDb("Phasemask condition has useless data in value3 (%u)!", cond->ConditionValue3); break; } - case CONDITION_UNUSED_18: - sLog->outErrorDb("Found ConditionTypeOrReference = CONDITION_UNUSED_18 in `conditions` table - ignoring"); - return false; + case CONDITION_TITLE: + { + CharTitlesEntry const* titleEntry = sCharTitlesStore.LookupEntry(cond->ConditionValue1); + if (!titleEntry) + { + sLog->outErrorDb("Title condition has non existing title in value1 (%u), skipped", cond->ConditionValue1); + return false; + } + break; + } case CONDITION_UNUSED_19: sLog->outErrorDb("Found ConditionTypeOrReference = CONDITION_UNUSED_19 in `conditions` table - ignoring"); return false; diff --git a/src/server/game/Conditions/ConditionMgr.h b/src/server/game/Conditions/ConditionMgr.h index 2df79eab088..130a23a0cb0 100755 --- a/src/server/game/Conditions/ConditionMgr.h +++ b/src/server/game/Conditions/ConditionMgr.h @@ -48,7 +48,7 @@ enum ConditionTypes CONDITION_CLASS = 15, // class 0 0 true if player's class is equal to class CONDITION_RACE = 16, // race 0 0 true if player's race is equal to race CONDITION_ACHIEVEMENT = 17, // achievement_id 0 0 true if achievement is complete - CONDITION_UNUSED_18 = 18, // + CONDITION_TITLE = 18, // title id 0 0 true if player has title CONDITION_UNUSED_19 = 19, // CONDITION_UNUSED_20 = 20, // CONDITION_UNUSED_21 = 21, // diff --git a/src/server/game/DataStores/DBCEnums.h b/src/server/game/DataStores/DBCEnums.h index 80949effa0c..23578a55816 100755 --- a/src/server/game/DataStores/DBCEnums.h +++ b/src/server/game/DataStores/DBCEnums.h @@ -245,7 +245,7 @@ enum AreaFlags AREA_FLAG_CITY = 0x00000200, // only for one zone named "City" (where it located?) AREA_FLAG_OUTLAND = 0x00000400, // expansion zones? (only Eye of the Storm not have this flag, but have 0x00004000 flag) AREA_FLAG_SANCTUARY = 0x00000800, // sanctuary area (PvP disabled) - AREA_FLAG_NEED_FLY = 0x00001000, // Unknown + AREA_FLAG_NEED_FLY = 0x00001000, // Respawn alive at the graveyard without corpse AREA_FLAG_UNUSED1 = 0x00002000, // Unused in 3.3.5a AREA_FLAG_OUTLAND2 = 0x00004000, // expansion zones? (only Circle of Blood Arena not have this flag, but have 0x00000400 flag) AREA_FLAG_OUTDOOR_PVP = 0x00008000, // pvp objective area? (Death's Door also has this flag although it's no pvp object area) @@ -260,7 +260,7 @@ enum AreaFlags AREA_FLAG_WINTERGRASP = 0x01000000, // Wintergrasp and it's subzones AREA_FLAG_INSIDE = 0x02000000, // used for determinating spell related inside/outside questions in Map::IsOutdoors AREA_FLAG_OUTSIDE = 0x04000000, // used for determinating spell related inside/outside questions in Map::IsOutdoors - AREA_FLAG_WINTERGRASP_2 = 0x08000000, // Same as AREA_FLAG_WINTERGRASP except for The Sunken Ring and Western Bridge. + AREA_FLAG_WINTERGRASP_2 = 0x08000000, // Can Hearth And Resurrect From Area AREA_FLAG_NO_FLY_ZONE = 0x20000000 // Marks zones where you cannot fly }; diff --git a/src/server/game/DataStores/DBCStructure.h b/src/server/game/DataStores/DBCStructure.h index 38e8c957681..15792fd57da 100755 --- a/src/server/game/DataStores/DBCStructure.h +++ b/src/server/game/DataStores/DBCStructure.h @@ -1292,6 +1292,7 @@ struct MapEntry bool IsBattleground() const { return map_type == MAP_BATTLEGROUND; } bool IsBattleArena() const { return map_type == MAP_ARENA; } bool IsBattlegroundOrArena() const { return map_type == MAP_BATTLEGROUND || map_type == MAP_ARENA; } + bool IsWorldMap() const { return map_type == MAP_COMMON; } bool GetEntrancePos(int32 &mapid, float &x, float &y) const { diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp index b936d32e13f..47c298d7467 100755 --- a/src/server/game/DungeonFinding/LFGMgr.cpp +++ b/src/server/game/DungeonFinding/LFGMgr.cpp @@ -1023,7 +1023,7 @@ bool LFGMgr::CheckCompatibility(LfgGuidList check, LfgProposal*& pProposal) // Select a random dungeon from the compatible list // TODO - Select the dungeon based on group item Level, not just random // Create a new proposal - pProposal = new LfgProposal(SelectRandomContainerElement(compatibleDungeons)); + pProposal = new LfgProposal(Trinity::Containers::SelectRandomContainerElement(compatibleDungeons)); pProposal->cancelTime = time_t(time(NULL)) + LFG_TIME_PROPOSAL; pProposal->state = LFG_PROPOSAL_INITIATING; pProposal->queues = check; diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index 6a8ae07291a..6506a113ae1 100755 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -135,7 +135,7 @@ CreatureBaseStats const* CreatureBaseStats::GetBaseStats(uint8 level, uint8 unit bool ForcedDespawnDelayEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/) { - m_owner.ForcedDespawn(); + m_owner.DespawnOrUnsummon(); // since we are here, we are not TempSummon as object type cannot change during runtime return true; } @@ -357,8 +357,9 @@ bool Creature::UpdateEntry(uint32 Entry, uint32 team, const CreatureData* data) m_regenHealth = cInfo->RegenHealth; - // creatures always have melee weapon ready if any - SetSheath(SHEATH_STATE_MELEE); + // creatures always have melee weapon ready if any unless specified otherwise + if (!GetCreatureAddon()) + SetSheath(SHEATH_STATE_MELEE); SelectLevel(GetCreatureTemplate()); if (team == HORDE) @@ -467,9 +468,9 @@ void Creature::Update(uint32 diff) switch (m_deathState) { - case JUST_ALIVED: - // Must not be called, see Creature::setDeathState JUST_ALIVED -> ALIVE promoting. - sLog->outError("Creature (GUID: %u Entry: %u) in wrong state: JUST_ALIVED (4)", GetGUIDLow(), GetEntry()); + case JUST_RESPAWNED: + // Must not be called, see Creature::setDeathState JUST_RESPAWNED -> ALIVE promoting. + sLog->outError("Creature (GUID: %u Entry: %u) in wrong state: JUST_RESPAWNED (4)", GetGUIDLow(), GetEntry()); break; case JUST_DIED: // Must not be called, see Creature::setDeathState JUST_DIED -> CORPSE promoting. @@ -795,10 +796,12 @@ bool Creature::Create(uint32 guidlow, Map* map, uint32 phaseMask, uint32 Entry, //! Need to be called after LoadCreaturesAddon - MOVEMENTFLAG_HOVER is set there if (HasUnitMovementFlag(MOVEMENTFLAG_HOVER)) + { z += GetFloatValue(UNIT_FIELD_HOVERHEIGHT); - //! Relocate again with updated Z coord - Relocate(x, y, z, ang); + //! Relocate again with updated Z coord + Relocate(x, y, z, ang); + } uint32 displayID = GetNativeDisplayId(); CreatureModelInfo const* minfo = sObjectMgr->GetCreatureModelRandomGender(&displayID); @@ -1125,7 +1128,7 @@ void Creature::SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask) stmt->setUInt8(index++, uint8(GetDefaultMovementType())); stmt->setUInt32(index++, npcflag); stmt->setUInt32(index++, unit_flags); - stmt->setUInt32(index, dynamicflags); + stmt->setUInt32(index++, dynamicflags); trans->Append(stmt); WorldDatabase.CommitTransaction(trans); @@ -1552,7 +1555,7 @@ void Creature::setDeathState(DeathState s) Unit::setDeathState(CORPSE); } - else if (s == JUST_ALIVED) + else if (s == JUST_RESPAWNED) { //if (isPet()) // setActive(true); @@ -1608,7 +1611,7 @@ void Creature::Respawn(bool force) CreatureTemplate const* cinfo = GetCreatureTemplate(); SelectLevel(cinfo); - setDeathState(JUST_ALIVED); + setDeathState(JUST_RESPAWNED); uint32 displayID = GetNativeDisplayId(); CreatureModelInfo const* minfo = sObjectMgr->GetCreatureModelRandomGender(&displayID); @@ -1665,8 +1668,8 @@ bool Creature::IsImmunedToSpell(SpellInfo const* spellInfo) if (!spellInfo) return false; - // Spells that don't have effectMechanics. - if (!spellInfo->HasAnyEffectMechanic() && GetCreatureTemplate()->MechanicImmuneMask & (1 << (spellInfo->Mechanic - 1))) + // Creature is immune to main mechanic of the spell + if (GetCreatureTemplate()->MechanicImmuneMask & (1 << (spellInfo->Mechanic - 1))) return true; // This check must be done instead of 'if (GetCreatureTemplate()->MechanicImmuneMask & (1 << (spellInfo->Mechanic - 1)))' for not break diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h index f100d391698..f6021a7d7ec 100755 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -266,7 +266,6 @@ struct CreatureData // `creature_addon` table struct CreatureAddon { - uint32 guidOrEntry; uint32 path_id; uint32 mount; uint32 bytes1; @@ -508,7 +507,7 @@ class Creature : public Unit, public GridObject<Creature>, public MapCreature if (isPet()) return false; - return GetCreatureTemplate()->rank == CREATURE_ELITE_WORLDBOSS; + return GetCreatureTemplate()->type_flags & CREATURE_TYPEFLAGS_BOSS; } bool IsDungeonBoss() const; @@ -636,7 +635,6 @@ class Creature : public Unit, public GridObject<Creature>, public MapCreature void RemoveCorpse(bool setSpawnTime = true); - void ForcedDespawn(uint32 timeMSToDespawn = 0); void DespawnOrUnsummon(uint32 msTimeToDespawn = 0); time_t const& GetRespawnTime() const { return m_respawnTime; } @@ -764,6 +762,8 @@ class Creature : public Unit, public GridObject<Creature>, public MapCreature bool IsInvisibleDueToDespawn() const; bool CanAlwaysSee(WorldObject const* obj) const; private: + void ForcedDespawn(uint32 timeMSToDespawn = 0); + //WaypointMovementGenerator vars uint32 m_waypointID; uint32 m_path_id; diff --git a/src/server/game/Entities/Creature/GossipDef.cpp b/src/server/game/Entities/Creature/GossipDef.cpp index a39bd8eddf7..836fbe8c7bf 100755 --- a/src/server/game/Entities/Creature/GossipDef.cpp +++ b/src/server/game/Entities/Creature/GossipDef.cpp @@ -47,10 +47,7 @@ void GossipMenu::AddMenuItem(int32 menuItemId, uint8 icon, std::string const& me for (GossipMenuItemContainer::const_iterator itr = _menuItems.begin(); itr != _menuItems.end(); ++itr) { if (int32(itr->first) > menuItemId) - { - menuItemId = menuItemId; break; - } menuItemId = itr->first + 1; } diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index 1fe83023976..10136c5fbd7 100755 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -135,10 +135,10 @@ void GameObject::AddToWorld() sObjectAccessor->AddObject(this); bool startOpen = (GetGoType() == GAMEOBJECT_TYPE_DOOR || GetGoType() == GAMEOBJECT_TYPE_BUTTON ? GetGOInfo()->door.startOpen : false); // The state can be changed after GameObject::Create but before GameObject::AddToWorld - bool toggledState = GetGoState() == GO_STATE_READY; + bool toggledState = GetGOData() ? GetGOData()->go_state == GO_STATE_READY : false; if (m_model) GetMap()->Insert(*m_model); - if ((startOpen && !toggledState) || (!startOpen && toggledState)) + if (startOpen ^ toggledState) EnableCollision(false); WorldObject::AddToWorld(); @@ -222,9 +222,7 @@ bool GameObject::Create(uint32 guidlow, uint32 name_id, Map* map, uint32 phaseMa // GAMEOBJECT_BYTES_1, index at 0, 1, 2 and 3 SetGoType(GameobjectTypes(goinfo->type)); SetGoState(go_state); - - SetGoArtKit(0); // unknown what this is - SetByteValue(GAMEOBJECT_BYTES_1, 2, artKit); + SetGoArtKit(artKit); switch (goinfo->type) { @@ -1432,7 +1430,7 @@ void GameObject::Use(Unit* user) if (info->summoningRitual.casterTargetSpell && info->summoningRitual.casterTargetSpell != 1) // No idea why this field is a bool in some cases for (uint32 i = 0; i < info->summoningRitual.casterTargetSpellTargets; i++) // m_unique_users can contain only player GUIDs - if (Player* target = ObjectAccessor::GetPlayer(*this, SelectRandomContainerElement(m_unique_users))) + if (Player* target = ObjectAccessor::GetPlayer(*this, Trinity::Containers::SelectRandomContainerElement(m_unique_users))) spellCaster->CastSpell(target, info->summoningRitual.casterTargetSpell, true); // finish owners spell @@ -1825,6 +1823,7 @@ void GameObject::SetDestructibleState(GameObjectDestructibleState state, Player* m_goValue->Building.Health = m_goValue->Building.MaxHealth; SetGoAnimProgress(255); } + EnableCollision(true); break; case GO_DESTRUCTIBLE_DAMAGED: { @@ -1881,6 +1880,7 @@ void GameObject::SetDestructibleState(GameObjectDestructibleState state, Player* m_goValue->Building.Health = 0; SetGoAnimProgress(0); } + EnableCollision(false); break; } case GO_DESTRUCTIBLE_REBUILDING: @@ -1900,6 +1900,7 @@ void GameObject::SetDestructibleState(GameObjectDestructibleState state, Player* m_goValue->Building.Health = m_goValue->Building.MaxHealth; SetGoAnimProgress(255); } + EnableCollision(true); break; } } @@ -1909,6 +1910,7 @@ void GameObject::SetLootState(LootState state, Unit* unit) { m_lootState = state; AI()->OnStateChanged(state, unit); + sScriptMgr->OnGameObjectLootStateChanged(this, state, unit); if (m_model) { // startOpen determines whether we are going to add or remove the LoS on activation @@ -1928,6 +1930,7 @@ void GameObject::SetLootState(LootState state, Unit* unit) void GameObject::SetGoState(GOState state) { SetByteValue(GAMEOBJECT_BYTES_1, 0, state); + sScriptMgr->OnGameObjectStateChanged(this, state); if (m_model) { if (!IsInWorld()) diff --git a/src/server/game/Entities/Item/Item.cpp b/src/server/game/Entities/Item/Item.cpp index fe2e8f38e62..f2b893896dc 100755 --- a/src/server/game/Entities/Item/Item.cpp +++ b/src/server/game/Entities/Item/Item.cpp @@ -343,8 +343,8 @@ void Item::SaveToDB(SQLTransaction& trans) } stmt->setString(++index, ssEnchants.str()); - stmt->setInt32 (++index, GetItemRandomPropertyId()); - stmt->setUInt32(++index, GetUInt32Value(ITEM_FIELD_DURABILITY)); + stmt->setInt16 (++index, GetItemRandomPropertyId()); + stmt->setUInt16(++index, GetUInt32Value(ITEM_FIELD_DURABILITY)); stmt->setUInt32(++index, GetUInt32Value(ITEM_FIELD_CREATE_PLAYED_TIME)); stmt->setString(++index, m_text); stmt->setUInt32(++index, guid); @@ -486,7 +486,7 @@ void Item::DeleteFromDB(SQLTransaction& trans) /*static*/ void Item::DeleteFromInventoryDB(SQLTransaction& trans, uint32 itemGuid) { - PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_INVENTORY_ITEM); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_INVENTORY_BY_ITEM); stmt->setUInt32(0, itemGuid); trans->Append(stmt); } @@ -1089,9 +1089,9 @@ void Item::SaveRefundDataToDB() stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_ITEM_REFUND_INSTANCE); stmt->setUInt32(0, GetGUIDLow()); - stmt->setUInt32(0, GetRefundRecipient()); - stmt->setUInt32(0, GetPaidMoney()); - stmt->setUInt16(0, uint16(GetPaidExtendedCost())); + stmt->setUInt32(1, GetRefundRecipient()); + stmt->setUInt32(2, GetPaidMoney()); + stmt->setUInt16(3, uint16(GetPaidExtendedCost())); trans->Append(stmt); CharacterDatabase.CommitTransaction(trans); diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index 69effaa016e..fc1b56c4b8c 100755 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -627,6 +627,11 @@ void Object::_BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask* dynamicFlags &= ~UNIT_DYNFLAG_LOOTABLE; } + // unit UNIT_DYNFLAG_TRACK_UNIT should only be sent to caster of SPELL_AURA_MOD_STALKED auras + if (Unit const* unit = ToUnit()) + if (dynamicFlags & UNIT_DYNFLAG_TRACK_UNIT) + if (!unit->HasAuraTypeWithCaster(SPELL_AURA_MOD_STALKED, target->GetGUID())) + dynamicFlags &= ~UNIT_DYNFLAG_TRACK_UNIT; *data << dynamicFlags; } // FG: pretend that OTHER players in own group are friendly ("blue") @@ -1630,7 +1635,7 @@ void WorldObject::UpdateAllowedPositionZ(float x, float y, float &z) const default: { float ground_z = GetBaseMap()->GetHeight(GetPhaseMask(), x, y, z, true); - if(ground_z > INVALID_HEIGHT) + if (ground_z > INVALID_HEIGHT) z = ground_z; break; } @@ -2741,6 +2746,14 @@ void WorldObject::MovePositionToFirstCollision(Position &pos, float dist, float pos.m_positionZ += 2.0f; destx = pos.m_positionX + dist * cos(angle); desty = pos.m_positionY + dist * sin(angle); + + // Prevent invalid coordinates here, position is unchanged + if (!Trinity::IsValidMapCoord(destx, desty)) + { + sLog->outCrash("WorldObject::MovePositionToFirstCollision invalid coordinates X: %f and Y: %f were passed!", destx, desty); + return; + } + ground = GetMap()->GetHeight(GetPhaseMask(), destx, desty, MAX_HEIGHT, true); floor = GetMap()->GetHeight(GetPhaseMask(), destx, desty, pos.m_positionZ, true); destz = fabs(ground - pos.m_positionZ) <= fabs(floor - pos.m_positionZ) ? ground : floor; diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index 6c77bf69a68..3693f683b24 100755 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -685,7 +685,7 @@ class WorldObject : public Object, public WorldLocation bool IsInMap(const WorldObject* obj) const { if (obj) - return IsInWorld() && obj->IsInWorld() && (GetMap() == obj->GetMap()) && InSamePhase(obj); + return IsInWorld() && obj->IsInWorld() && (GetMap() == obj->GetMap()); return false; } bool IsWithinDist3d(float x, float y, float z, float dist) const @@ -703,7 +703,7 @@ class WorldObject : public Object, public WorldLocation } bool IsWithinDistInMap(WorldObject const* obj, float dist2compare, bool is3D = true) const { - return obj && IsInMap(obj) && _IsWithinDist(obj, dist2compare, is3D); + return obj && IsInMap(obj) && InSamePhase(obj) && _IsWithinDist(obj, dist2compare, is3D); } bool IsWithinLOS(float x, float y, float z) const; bool IsWithinLOSInMap(const WorldObject* obj) const; @@ -878,20 +878,6 @@ class WorldObject : public Object, public WorldLocation namespace Trinity { - template<class T> - void RandomResizeList(std::list<T> &_list, uint32 _size) - { - size_t list_size = _list.size(); - - while (list_size > _size) - { - typename std::list<T>::iterator itr = _list.begin(); - std::advance(itr, urand(0, list_size - 1)); - _list.erase(itr); - --list_size; - } - } - // Binary predicate to sort WorldObjects based on the distance to a reference WorldObject class ObjectDistanceOrderPred { diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp index 0ee8381d54f..f3a736daceb 100755 --- a/src/server/game/Entities/Pet/Pet.cpp +++ b/src/server/game/Entities/Pet/Pet.cpp @@ -940,14 +940,14 @@ bool Guardian::InitStatsForLevel(uint8 petlevel) { case 510: // mage Water Elemental { - SetBonusDamage(int32(m_owner->SpellBaseDamageBonus(SPELL_SCHOOL_MASK_FROST) * 0.33f)); + SetBonusDamage(int32(m_owner->SpellBaseDamageBonusDone(SPELL_SCHOOL_MASK_FROST) * 0.33f)); break; } case 1964: //force of nature { if (!pInfo) SetCreateHealth(30 + 30*petlevel); - float bonusDmg = m_owner->SpellBaseDamageBonus(SPELL_SCHOOL_MASK_NATURE) * 0.15f; + float bonusDmg = m_owner->SpellBaseDamageBonusDone(SPELL_SCHOOL_MASK_NATURE) * 0.15f; SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(petlevel * 2.5f - (petlevel / 2) + bonusDmg)); SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float(petlevel * 2.5f + (petlevel / 2) + bonusDmg)); break; @@ -967,7 +967,7 @@ bool Guardian::InitStatsForLevel(uint8 petlevel) SetCreateHealth(40*petlevel); SetCreateMana(28 + 10*petlevel); } - SetBonusDamage(int32(m_owner->SpellBaseDamageBonus(SPELL_SCHOOL_MASK_FIRE) * 0.5f)); + SetBonusDamage(int32(m_owner->SpellBaseDamageBonusDone(SPELL_SCHOOL_MASK_FIRE) * 0.5f)); SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(petlevel * 4 - petlevel)); SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float(petlevel * 4 + petlevel)); break; @@ -979,7 +979,7 @@ bool Guardian::InitStatsForLevel(uint8 petlevel) SetCreateMana(28 + 10*petlevel); SetCreateHealth(28 + 30*petlevel); } - int32 bonus_dmg = (int32(m_owner->SpellBaseDamageBonus(SPELL_SCHOOL_MASK_SHADOW)* 0.3f)); + int32 bonus_dmg = (int32(m_owner->SpellBaseDamageBonusDone(SPELL_SCHOOL_MASK_SHADOW)* 0.3f)); SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float((petlevel * 4 - petlevel) + bonus_dmg)); SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float((petlevel * 4 + petlevel) + bonus_dmg)); @@ -1020,7 +1020,7 @@ bool Guardian::InitStatsForLevel(uint8 petlevel) } case 31216: // Mirror Image { - SetBonusDamage(int32(m_owner->SpellBaseDamageBonus(SPELL_SCHOOL_MASK_FROST) * 0.33f)); + SetBonusDamage(int32(m_owner->SpellBaseDamageBonusDone(SPELL_SCHOOL_MASK_FROST) * 0.33f)); SetDisplayId(m_owner->GetDisplayId()); if (!pInfo) { @@ -1041,6 +1041,13 @@ bool Guardian::InitStatsForLevel(uint8 petlevel) SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float(petlevel + (petlevel / 4))); break; } + case 28017: // Bloodworms + { + SetCreateHealth(4 * petlevel); + SetBonusDamage(int32(m_owner->GetTotalAttackPowerValue(BASE_ATTACK) * 0.006f)); + SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(petlevel - 30 - (petlevel / 4))); + SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float(petlevel - 30 + (petlevel / 4))); + } } break; } @@ -1745,7 +1752,7 @@ void Pet::resetTalentsForAllPetsOf(Player* owner, Pet* online_pet /*= NULL*/) stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PET_SPELL_LIST); stmt->setUInt32(0, owner->GetGUIDLow()); - stmt->setUInt32(0, except_petnumber); + stmt->setUInt32(1, except_petnumber); PreparedQueryResult result = CharacterDatabase.Query(stmt); if (!result) diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index f4a5cbb5572..41c95ac3d04 100755 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -724,7 +724,6 @@ Player::Player(WorldSession* session): Unit(true), m_achievementMgr(this), m_rep for (uint8 i=0; i<MAX_TIMERS; i++) m_MirrorTimer[i] = DISABLED_MIRROR_TIMER; - _lastLiquid = NULL; m_MirrorTimerFlags = UNDERWATER_NONE; m_MirrorTimerFlagsLast = UNDERWATER_NONE; m_isInWater = false; @@ -932,7 +931,8 @@ bool Player::Create(uint32 guidlow, CharacterCreateInfo* createInfo) PlayerInfo const* info = sObjectMgr->GetPlayerInfo(createInfo->Race, createInfo->Class); if (!info) { - sLog->outError("Player (Name %s) has incorrect race/class pair. Can't be loaded.", m_name.c_str()); + sLog->outError("Player::Create: Possible hacking-attempt: Account %u tried creating a character named '%s' with an invalid race/class pair (%u/%u) - refusing to do so.", + GetSession()->GetAccountId(), m_name.c_str(), createInfo->Race, createInfo->Class); return false; } @@ -944,7 +944,8 @@ bool Player::Create(uint32 guidlow, CharacterCreateInfo* createInfo) ChrClassesEntry const* cEntry = sChrClassesStore.LookupEntry(createInfo->Class); if (!cEntry) { - sLog->outError("Class %u not found in DBC (Wrong DBC files?)", createInfo->Class); + sLog->outError("Player::Create: Possible hacking-attempt: Account %u tried creating a character named '%s' with an invalid character class (%u) - refusing to do so (wrong DBC-files?)", + GetSession()->GetAccountId(), m_name.c_str(), createInfo->Class); return false; } @@ -959,7 +960,8 @@ bool Player::Create(uint32 guidlow, CharacterCreateInfo* createInfo) if (!IsValidGender(createInfo->Gender)) { - sLog->outError("Player has invalid gender (%hu), can't be loaded.", createInfo->Gender); + sLog->outError("Player::Create: Possible hacking-attempt: Account %u tried creating a character named '%s' with an invalid gender (%hu) - refusing to do so", + GetSession()->GetAccountId(), m_name.c_str(), createInfo->Gender); return false; } @@ -2134,7 +2136,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati if (duel && GetMapId() != mapid && GetMap()->GetGameObject(GetUInt64Value(PLAYER_DUEL_ARBITER))) DuelComplete(DUEL_FLED); - if ((GetMapId() == mapid && !m_transport) || (GetTransport() && GetMapId() == 628)) + if (GetMapId() == mapid) { //lets reset far teleport flag if it wasn't reset during chained teleports SetSemaphoreTeleportFar(false); @@ -2936,7 +2938,7 @@ void Player::GiveXP(uint32 xp, Unit* victim, float group_rate) if (xp < 1) return; - if (!isAlive()) + if (!isAlive() && !GetBattlegroundId()) return; if (HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_NO_XP_GAIN)) @@ -4819,16 +4821,16 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC { do { - Field* fields = resultMail->Fetch(); + Field* mailFields = resultMail->Fetch(); - uint32 mail_id = fields[0].GetUInt32(); - uint16 mailType = fields[1].GetUInt16(); - uint16 mailTemplateId= fields[2].GetUInt16(); - uint32 sender = fields[3].GetUInt32(); - std::string subject = fields[4].GetString(); - std::string body = fields[5].GetString(); - uint32 money = fields[6].GetUInt32(); - bool has_items = fields[7].GetBool(); + uint32 mail_id = mailFields[0].GetUInt32(); + uint8 mailType = mailFields[1].GetUInt8(); + uint16 mailTemplateId= mailFields[2].GetUInt16(); + uint32 sender = mailFields[3].GetUInt32(); + std::string subject = mailFields[4].GetString(); + std::string body = mailFields[5].GetString(); + uint32 money = mailFields[6].GetUInt32(); + bool has_items = mailFields[7].GetBool(); // We can return mail now // So firstly delete the old one @@ -4862,9 +4864,9 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC { do { - Field* fields2 = resultItems->Fetch(); - uint32 item_guidlow = fields2[11].GetUInt32(); - uint32 item_template = fields2[12].GetUInt32(); + Field* itemFields = resultItems->Fetch(); + uint32 item_guidlow = itemFields[11].GetUInt32(); + uint32 item_template = itemFields[12].GetUInt32(); ItemTemplate const* itemProto = sObjectMgr->GetItemTemplate(item_template); if (!itemProto) @@ -4876,7 +4878,7 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC } Item* pItem = NewItemOrBag(itemProto); - if (!pItem->LoadFromDB(item_guidlow, MAKE_NEW_GUID(guid, 0, HIGHGUID_PLAYER), fields, item_template)) + if (!pItem->LoadFromDB(item_guidlow, MAKE_NEW_GUID(guid, 0, HIGHGUID_PLAYER), itemFields, item_template)) { pItem->FSetState(ITEM_REMOVED); pItem->SaveToDB(trans); // it also deletes item object! @@ -6827,11 +6829,6 @@ bool Player::UpdatePosition(float x, float y, float z, float orientation, bool t if (GetGroup()) SetGroupUpdateFlag(GROUP_UPDATE_FLAG_POSITION); - // code block for underwater state update - // Unit::UpdatePosition() checks for validity and updates our coordinates - // so we re-fetch them instead of using "raw" coordinates from function params - UpdateUnderwaterState(GetMap(), GetPositionX(), GetPositionY(), GetPositionZ()); - if (GetTrader() && !IsWithinDistInMap(GetTrader(), INTERACTION_DISTANCE)) GetSession()->SendCancelTrade(); @@ -8196,6 +8193,10 @@ void Player::_ApplyWeaponDependentAuraMods(Item* item, WeaponAttackType attackTy void Player::_ApplyWeaponDependentAuraCritMod(Item* item, WeaponAttackType attackType, AuraEffect const* aura, bool apply) { + // don't apply mod if item is broken or cannot be used + if (item->IsBroken() || !CanUseAttackType(attackType)) + return; + // generic not weapon specific case processes in aura code if (aura->GetSpellInfo()->EquippedItemClass == -1) return; @@ -8209,13 +8210,13 @@ void Player::_ApplyWeaponDependentAuraCritMod(Item* item, WeaponAttackType attac default: return; } - if (!item->IsBroken()&&item->IsFitToSpellRequirements(aura->GetSpellInfo())) + if (item->IsFitToSpellRequirements(aura->GetSpellInfo())) HandleBaseModValue(mod, FLAT_MOD, float (aura->GetAmount()), apply); } void Player::_ApplyWeaponDependentAuraDamageMod(Item* item, WeaponAttackType attackType, AuraEffect const* aura, bool apply) { - //don't apply mod if item is broken + // don't apply mod if item is broken or cannot be used if (item->IsBroken() || !CanUseAttackType(attackType)) return; @@ -9216,6 +9217,9 @@ void Player::SendInitWorldStates(uint32 zoneid, uint32 areaid) case 4100: // The Culling of Stratholme NumberOfFields = 13; break; + case 4273: // Ulduar + NumberOfFields = 10; + break; default: NumberOfFields = 12; break; @@ -9760,6 +9764,16 @@ void Player::SendInitWorldStates(uint32 zoneid, uint32 areaid) data << uint32(3932) << uint32(0); // 13 WORLDSTATE_TIME_GUARDIAN_SHOW } break; + // Ulduar + case 4273: + if (instance && mapid == 603) + instance->FillInitialWorldStates(data); + else + { + data << uint32(4132) << uint32(0); // 9 WORLDSTATE_SHOW_CRATES + data << uint32(4131) << uint32(0); // 10 WORLDSTATE_CRATES_REVEALED + } + break; default: data << uint32(0x914) << uint32(0x0); // 7 data << uint32(0x913) << uint32(0x0); // 8 @@ -10143,7 +10157,8 @@ uint32 Player::GetItemCount(uint32 item, bool inBankAlso, Item* skipItem) const if (inBankAlso) { - for (uint8 i = BANK_SLOT_ITEM_START; i < BANK_SLOT_ITEM_END; ++i) + // checking every item from 39 to 74 (including bank bags) + for (uint8 i = BANK_SLOT_ITEM_START; i < BANK_SLOT_BAG_END; ++i) if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) if (pItem != skipItem && pItem->GetEntry() == item) count += pItem->GetCount(); @@ -10183,7 +10198,7 @@ uint32 Player::GetItemCountWithLimitCategory(uint32 limitCategory, Item* skipIte if (Bag* pBag = GetBagByPos(i)) count += pBag->GetItemCountWithLimitCategory(limitCategory, skipItem); - for (int i = BANK_SLOT_ITEM_START; i < BANK_SLOT_ITEM_END; ++i) + for (int i = BANK_SLOT_ITEM_START; i < BANK_SLOT_BAG_END; ++i) if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) if (pItem != skipItem) if (ItemTemplate const* pProto = pItem->GetTemplate()) @@ -10209,7 +10224,7 @@ Item* Player::GetItemByGuid(uint64 guid) const if (pItem->GetGUID() == guid) return pItem; - for (int i = BANK_SLOT_ITEM_START; i < BANK_SLOT_ITEM_END; ++i) + for (int i = BANK_SLOT_ITEM_START; i < BANK_SLOT_BAG_END; ++i) if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) if (pItem->GetGUID() == guid) return pItem; @@ -12005,7 +12020,7 @@ InventoryResult Player::CanRollForItemInLFG(ItemTemplate const* proto, WorldObje Map const* map = lootedObject->GetMap(); if (uint32 dungeonId = sLFGMgr->GetDungeon(GetGroup()->GetGUID(), true)) if (LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(dungeonId)) - if (uint32(dungeon->map) == map->GetId() && dungeon->difficulty == map->GetDifficulty()) + if (uint32(dungeon->map) == map->GetId() && dungeon->difficulty == uint32(map->GetDifficulty())) lootedObjectInDungeon = true; if (!lootedObjectInDungeon) @@ -12166,11 +12181,6 @@ Item* Player::StoreNewItem(ItemPosCountVec const& dest, uint32 item, bool update pItem->SetItemRandomProperties(randomPropertyId); pItem = StoreItem(dest, pItem, update); - const ItemTemplate* proto = pItem->GetTemplate(); - for (uint8 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i) - if (proto->Spells[i].SpellTrigger == ITEM_SPELLTRIGGER_ON_NO_DELAY_USE && proto->Spells[i].SpellId > 0) // On obtain trigger - CastSpell(this, proto->Spells[i].SpellId, true, pItem); - if (allowedLooters.size() > 1 && pItem->GetTemplate()->GetMaxStackSize() == 1 && pItem->IsSoulBound()) { pItem->SetSoulboundTradeable(allowedLooters); @@ -12276,6 +12286,14 @@ Item* Player::_StoreItem(uint16 pos, Item* pItem, uint32 count, bool clone, bool AddEnchantmentDurations(pItem); AddItemDurations(pItem); + + const ItemTemplate* proto = pItem->GetTemplate(); + for (uint8 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i) + if (proto->Spells[i].SpellTrigger == ITEM_SPELLTRIGGER_ON_NO_DELAY_USE && proto->Spells[i].SpellId > 0) // On obtain trigger + if (bag == INVENTORY_SLOT_BAG_0 || (bag >= INVENTORY_SLOT_BAG_START && bag < INVENTORY_SLOT_BAG_END)) + if (!HasAura(proto->Spells[i].SpellId)) + CastSpell(this, proto->Spells[i].SpellId, true, pItem); + return pItem; } else @@ -12312,6 +12330,13 @@ Item* Player::_StoreItem(uint16 pos, Item* pItem, uint32 count, bool clone, bool pItem2->SetState(ITEM_CHANGED, this); + const ItemTemplate* proto = pItem2->GetTemplate(); + for (uint8 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i) + if (proto->Spells[i].SpellTrigger == ITEM_SPELLTRIGGER_ON_NO_DELAY_USE && proto->Spells[i].SpellId > 0) // On obtain trigger + if (bag == INVENTORY_SLOT_BAG_0 || (bag >= INVENTORY_SLOT_BAG_START && bag < INVENTORY_SLOT_BAG_END)) + if (!HasAura(proto->Spells[i].SpellId)) + CastSpell(this, proto->Spells[i].SpellId, true, pItem2); + return pItem2; } } @@ -17592,6 +17617,7 @@ void Player::_LoadInventory(PreparedQueryResult result, uint32 timeDiff) uint32 zoneId = GetZoneId(); std::map<uint64, Bag*> bagMap; // fast guid lookup for bags + std::map<uint64, Item*> invalidBagMap; // fast guid lookup for bags std::list<Item*> problematicItems; SQLTransaction trans = CharacterDatabase.BeginTransaction(); @@ -17636,9 +17662,15 @@ void Player::_LoadInventory(PreparedQueryResult result, uint32 timeDiff) // Remember bags that may contain items in them if (err == EQUIP_ERR_OK) + { if (IsBagPos(item->GetPos())) if (Bag* pBag = item->ToBag()) bagMap[item->GetGUIDLow()] = pBag; + } + else + if (IsBagPos(item->GetPos())) + if (item->IsBag()) + invalidBagMap[item->GetGUIDLow()] = item; } else { @@ -17650,8 +17682,23 @@ void Player::_LoadInventory(PreparedQueryResult result, uint32 timeDiff) ItemPosCountVec dest; err = CanStoreItem(itr->second->GetSlot(), slot, dest, item); if (err == EQUIP_ERR_OK) - itr->second->StoreItem(slot, item, true); + item = StoreItem(dest, item, true); } + else if (invalidBagMap.find(bagGuid) != invalidBagMap.end()) + { + std::map<uint64, Item*>::iterator itr = invalidBagMap.find(bagGuid); + if (std::find(problematicItems.begin(),problematicItems.end(),itr->second) != problematicItems.end()) + err = EQUIP_ERR_INT_BAG_ERROR; + } + else + { + sLog->outError("Player::_LoadInventory: player (GUID: %u, name: '%s') has item (GUID: %u, entry: %u) which doesnt have a valid bag (Bag GUID: %u, slot: %u). Possible cheat?", + GetGUIDLow(), GetName(), item->GetGUIDLow(), item->GetEntry(), bagGuid, slot); + item->DeleteFromInventoryDB(trans); + delete item; + continue; + } + } // Item's state may have changed after storing @@ -17775,7 +17822,7 @@ Item* Player::_LoadItem(SQLTransaction& trans, uint32 zoneId, uint32 timeDiff, F GameEventMgr::ActiveEvents const& activeEventsList = sGameEventMgr->GetActiveEventList(); for (GameEventMgr::ActiveEvents::const_iterator itr = activeEventsList.begin(); itr != activeEventsList.end(); ++itr) { - if (events[*itr].holiday_id == proto->HolidayId) + if (uint32(events[*itr].holiday_id) == proto->HolidayId) { remove = false; break; @@ -18311,10 +18358,10 @@ void Player::UnbindInstance(BoundInstancesMap::iterator &itr, Difficulty difficu CharacterDatabase.Execute(stmt); } - itr->second.save->RemovePlayer(this); // save can become invalid if (itr->second.perm) GetSession()->SendCalendarRaidLockout(itr->second.save, false); + itr->second.save->RemovePlayer(this); // save can become invalid m_boundInstances[difficulty].erase(itr++); } } @@ -18984,7 +19031,7 @@ void Player::_SaveActions(SQLTransaction& trans) void Player::_SaveAuras(SQLTransaction& trans) { - PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_AURA); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_AURA); stmt->setUInt32(0, GetGUIDLow()); trans->Append(stmt); @@ -19147,7 +19194,7 @@ void Player::_SaveInventory(SQLTransaction& trans) trans->Append(stmt); break; case ITEM_REMOVED: - stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_INVENTORY_ITEM); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_INVENTORY_BY_ITEM); stmt->setUInt32(0, item->GetGUIDLow()); trans->Append(stmt); case ITEM_UNCHANGED: @@ -19776,7 +19823,11 @@ void Player::SendResetInstanceSuccess(uint32 MapId) void Player::SendResetInstanceFailed(uint32 reason, uint32 MapId) { - // TODO: find what other fail reasons there are besides players in the instance + /*reasons for instance reset failure: + // 0: There are players inside the instance. + // 1: There are players offline in your party. + // 2>: There are players in your party attempting to zone into an instance. + */ WorldPacket data(SMSG_INSTANCE_RESET_FAILED, 4); data << uint32(reason); data << uint32(MapId); @@ -21144,10 +21195,10 @@ bool Player::BuyItemFromVendorSlot(uint64 vendorguid, uint32 vendorslot, uint32 } uint32 price = 0; - if(crItem->IsGoldRequired(pProto) && pProto->BuyPrice > 0) //Assume price cannot be negative (do not know why it is int32) + if (crItem->IsGoldRequired(pProto) && pProto->BuyPrice > 0) //Assume price cannot be negative (do not know why it is int32) { uint32 maxCount = MAX_MONEY_AMOUNT / pProto->BuyPrice; - if((uint32)count > maxCount) + if ((uint32)count > maxCount) { sLog->outError("Player %s tried to buy %u item id %u, causing overflow", GetName(), (uint32)count, pProto->ItemId); count = (uint8)maxCount; @@ -25546,3 +25597,27 @@ void Player::SendMovementSetCanTransitionBetweenSwimAndFly(bool apply) data << uint32(0); //! movement counter SendDirectMessage(&data); } + +void Player::SendMovementSetHover(bool apply) +{ + WorldPacket data(apply ? SMSG_MOVE_SET_HOVER : SMSG_MOVE_UNSET_HOVER, 12); + data.append(GetPackGUID()); + data << uint32(0); //! movement counter + SendDirectMessage(&data); +} + +void Player::SendMovementSetWaterWalking(bool apply) +{ + WorldPacket data(apply ? SMSG_MOVE_WATER_WALK : SMSG_MOVE_LAND_WALK, 12); + data.append(GetPackGUID()); + data << uint32(0); //! movement counter + SendDirectMessage(&data); +} + +void Player::SendMovementSetFeatherFall(bool apply) +{ + WorldPacket data(apply ? SMSG_MOVE_FEATHER_FALL : SMSG_MOVE_NORMAL_FALL, 12); + data.append(GetPackGUID()); + data << uint32(0); //! movement counter + SendDirectMessage(&data); +} diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 53b848a89b0..ed887994bca 100755 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -2486,6 +2486,9 @@ class Player : public Unit, public GridObject<Player> */ void SendMovementSetCanFly(bool apply); void SendMovementSetCanTransitionBetweenSwimAndFly(bool apply); + void SendMovementSetHover(bool apply); + void SendMovementSetWaterWalking(bool apply); + void SendMovementSetFeatherFall(bool apply); bool CanFly() const { return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_CAN_FLY); } @@ -2822,7 +2825,6 @@ class Player : public Unit, public GridObject<Player> uint32 m_lastFallTime; float m_lastFallZ; - LiquidTypeEntry const* _lastLiquid; int32 m_MirrorTimer[MAX_TIMERS]; uint8 m_MirrorTimerFlags; uint8 m_MirrorTimerFlagsLast; diff --git a/src/server/game/Entities/Transport/Transport.cpp b/src/server/game/Entities/Transport/Transport.cpp index 81a505b7acc..9578605ac6f 100755 --- a/src/server/game/Entities/Transport/Transport.cpp +++ b/src/server/game/Entities/Transport/Transport.cpp @@ -52,7 +52,7 @@ void MapManager::LoadTransports() uint32 period = fields[3].GetUInt32(); uint32 scriptId = sObjectMgr->GetScriptId(fields[4].GetCString()); - const GameObjectTemplate* goinfo = sObjectMgr->GetGameObjectTemplate(entry); + GameObjectTemplate const* goinfo = sObjectMgr->GetGameObjectTemplate(entry); if (!goinfo) { @@ -86,7 +86,7 @@ void MapManager::LoadTransports() float o = 1.0f; // creates the Gameobject - if (!t->Create(lowguid, entry, mapid, x, y, z, o, 100, 0)) + if (!t->Create(lowguid, entry, mapid, x, y, z, o, 255, 0)) { delete t; continue; @@ -217,8 +217,7 @@ bool Transport::Create(uint32 guidlow, uint32 entry, uint32 mapid, float x, floa SetFloatValue(OBJECT_FIELD_SCALE_X, goinfo->size); SetUInt32Value(GAMEOBJECT_FACTION, goinfo->faction); - //SetUInt32Value(GAMEOBJECT_FLAGS, goinfo->flags); - SetUInt32Value(GAMEOBJECT_FLAGS, MAKE_PAIR32(0x28, 0x64)); + SetUInt32Value(GAMEOBJECT_FLAGS, goinfo->flags); SetUInt32Value(GAMEOBJECT_LEVEL, m_period); SetEntry(goinfo->entry); diff --git a/src/server/game/Entities/Unit/StatSystem.cpp b/src/server/game/Entities/Unit/StatSystem.cpp index 69771129ac9..5cec0cf4375 100755 --- a/src/server/game/Entities/Unit/StatSystem.cpp +++ b/src/server/game/Entities/Unit/StatSystem.cpp @@ -142,13 +142,13 @@ void Player::ApplySpellPowerBonus(int32 amount, bool apply) void Player::UpdateSpellDamageAndHealingBonus() { - // Magic damage modifiers implemented in Unit::SpellDamageBonus + // Magic damage modifiers implemented in Unit::SpellDamageBonusDone // This information for client side use only // Get healing bonus for all schools - SetStatInt32Value(PLAYER_FIELD_MOD_HEALING_DONE_POS, SpellBaseHealingBonus(SPELL_SCHOOL_MASK_ALL)); + SetStatInt32Value(PLAYER_FIELD_MOD_HEALING_DONE_POS, SpellBaseHealingBonusDone(SPELL_SCHOOL_MASK_ALL)); // Get damage bonus for all schools for (int i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i) - SetStatInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS+i, SpellBaseDamageBonus(SpellSchoolMask(1 << i))); + SetStatInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS+i, SpellBaseDamageBonusDone(SpellSchoolMask(1 << i))); } bool Player::UpdateAllStats() @@ -1068,6 +1068,7 @@ void Creature::UpdateDamagePhysical(WeaponAttackType attType) #define ENTRY_TREANT 1964 #define ENTRY_FIRE_ELEMENTAL 15438 #define ENTRY_GHOUL 26125 +#define ENTRY_BLOODWORM 28017 bool Guardian::UpdateStats(Stats stat) { @@ -1229,6 +1230,7 @@ void Guardian::UpdateMaxHealth() case ENTRY_SUCCUBUS: multiplicator = 9.1f; break; case ENTRY_FELHUNTER: multiplicator = 9.5f; break; case ENTRY_FELGUARD: multiplicator = 11.0f; break; + case ENTRY_BLOODWORM: multiplicator = 1.0f; break; default: multiplicator = 10.0f; break; } diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 8d02db9d515..71977bf469c 100755 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -252,6 +252,7 @@ m_HostileRefManager(this) _focusSpell = NULL; _targetLocked = false; + _lastLiquid = NULL; } //////////////////////////////////////////////////////////// @@ -459,7 +460,7 @@ void Unit::resetAttackTimer(WeaponAttackType type) bool Unit::IsWithinCombatRange(const Unit* obj, float dist2compare) const { - if (!obj || !IsInMap(obj)) + if (!obj || !IsInMap(obj) || !InSamePhase(obj)) return false; float dx = GetPositionX() - obj->GetPositionX(); @@ -475,7 +476,7 @@ bool Unit::IsWithinCombatRange(const Unit* obj, float dist2compare) const bool Unit::IsWithinMeleeRange(const Unit* obj, float dist) const { - if (!obj || !IsInMap(obj)) + if (!obj || !IsInMap(obj) || !InSamePhase(obj)) return false; float dx = GetPositionX() - obj->GetPositionX(); @@ -572,6 +573,15 @@ uint32 Unit::DealDamage(Unit* victim, uint32 damage, CleanDamage const* cleanDam if (IsAIEnabled) GetAI()->DamageDealt(victim, damage, damagetype); + // Signal to pets that their owner was attacked + if (victim->GetTypeId() == TYPEID_PLAYER) + { + Pet* pet = victim->ToPlayer()->GetPet(); + + if (pet && pet->isAlive()) + pet->AI()->OwnerDamagedBy(this); + } + if (damagetype != NODAMAGE) { // interrupting auras with AURA_INTERRUPT_FLAG_DAMAGE before checking !damage (absorbed damage breaks that type of auras) @@ -943,7 +953,9 @@ uint32 Unit::SpellNonMeleeDamageLog(Unit* victim, uint32 spellID, uint32 damage) { SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellID); SpellNonMeleeDamage damageInfo(this, victim, spellInfo->Id, spellInfo->SchoolMask); - damage = SpellDamageBonus(victim, spellInfo, damage, SPELL_DIRECT_DAMAGE); + damage = SpellDamageBonusDone(victim, spellInfo, damage, SPELL_DIRECT_DAMAGE); + damage = victim->SpellDamageBonusTaken(this, spellInfo, damage, SPELL_DIRECT_DAMAGE); + CalculateSpellDamageTaken(&damageInfo, damage, spellInfo); DealDamageMods(damageInfo.target, damageInfo.damage, &damageInfo.absorb); SendSpellNonMeleeDamageLog(&damageInfo); @@ -1138,7 +1150,8 @@ void Unit::CalculateMeleeDamage(Unit* victim, uint32 damage, CalcDamageInfo* dam damage += CalculateDamage(damageInfo->attackType, false, true); // Add melee damage bonus - MeleeDamageBonus(damageInfo->target, &damage, damageInfo->attackType); + damage = MeleeDamageBonusDone(damageInfo->target, damage, damageInfo->attackType); + damage = damageInfo->target->MeleeDamageBonusTaken(this, damage, damageInfo->attackType); // Calculate armor reduction if (IsDamageReducedByArmor((SpellSchoolMask)(damageInfo->damageSchoolMask))) @@ -1390,7 +1403,10 @@ void Unit::DealMeleeDamage(CalcDamageInfo* damageInfo, bool durabilityLoss) uint32 damage = (*dmgShieldItr)->GetAmount(); if (Unit* caster = (*dmgShieldItr)->GetCaster()) - damage = caster->SpellDamageBonus(this, i_spellProto, damage, SPELL_DIRECT_DAMAGE); + { + damage = caster->SpellDamageBonusDone(this, i_spellProto, damage, SPELL_DIRECT_DAMAGE); + damage = this->SpellDamageBonusTaken(caster, i_spellProto, damage, SPELL_DIRECT_DAMAGE); + } // No Unit::CalcAbsorbResist here - opcode doesn't send that data - this damage is probably not affected by that victim->DealDamageMods(this, damage, NULL); @@ -1485,7 +1501,7 @@ uint32 Unit::CalcArmorReducedDamage(Unit* victim, const uint32 damage, SpellInfo } else { - if (ToPlayer() && ToPlayer()->HasItemFitToSpellRequirements((*itr)->GetSpellInfo())) + if (ToPlayer()->HasItemFitToSpellRequirements((*itr)->GetSpellInfo())) bonusPct += (*itr)->GetAmount(); } } @@ -1495,6 +1511,7 @@ uint32 Unit::CalcArmorReducedDamage(Unit* victim, const uint32 damage, SpellInfo maxArmorPen = float(400 + 85 * victim->getLevel()); else maxArmorPen = 400 + 85 * victim->getLevel() + 4.5f * 85 * (victim->getLevel() - 59); + // Cap armor penetration to this number maxArmorPen = std::min((armor + maxArmorPen) / 3, armor); // Figure out how much armor do we ignore @@ -1531,7 +1548,8 @@ void Unit::CalcAbsorbResist(Unit* victim, SpellSchoolMask schoolMask, DamageEffe DamageInfo dmgInfo = DamageInfo(this, victim, damage, spellInfo, schoolMask, damagetype); // Magic damage, check for resists - if ((schoolMask & SPELL_SCHOOL_MASK_NORMAL) == 0) + // Ignore spells that cant be resisted + if ((schoolMask & SPELL_SCHOOL_MASK_NORMAL) == 0 && (!spellInfo || (spellInfo->AttributesEx4 & SPELL_ATTR4_IGNORE_RESISTANCES) == 0)) { float victimResistance = float(victim->GetResistance(schoolMask)); victimResistance += float(GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_TARGET_RESISTANCE, schoolMask)); @@ -3078,6 +3096,48 @@ bool Unit::IsUnderWater() const return GetBaseMap()->IsUnderWater(GetPositionX(), GetPositionY(), GetPositionZ()); } +void Unit::UpdateUnderwaterState(Map* m, float x, float y, float z) +{ + if (!isPet() && !IsVehicle()) + return; + + LiquidData liquid_status; + ZLiquidStatus res = m->getLiquidStatus(x, y, z, MAP_ALL_LIQUIDS, &liquid_status); + if (!res) + { + if (_lastLiquid && _lastLiquid->SpellId) + RemoveAurasDueToSpell(_lastLiquid->SpellId); + + RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_NOT_UNDERWATER); + _lastLiquid = NULL; + return; + } + + if (uint32 liqEntry = liquid_status.entry) + { + LiquidTypeEntry const* liquid = sLiquidTypeStore.LookupEntry(liqEntry); + if (_lastLiquid && _lastLiquid->SpellId && _lastLiquid->Id != liqEntry) + RemoveAurasDueToSpell(_lastLiquid->SpellId); + + if (liquid && liquid->SpellId) + { + if (res & (LIQUID_MAP_UNDER_WATER | LIQUID_MAP_IN_WATER)) + CastSpell(this, liquid->SpellId, true); + else + RemoveAurasDueToSpell(liquid->SpellId); + } + + RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_NOT_ABOVEWATER); + _lastLiquid = liquid; + } + else if (_lastLiquid && _lastLiquid->SpellId) + { + RemoveAurasDueToSpell(_lastLiquid->SpellId); + RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_NOT_UNDERWATER); + _lastLiquid = NULL; + } +} + void Unit::DeMorph() { SetDisplayId(GetNativeDisplayId()); @@ -3597,8 +3657,12 @@ void Unit::RemoveAurasDueToSpellByDispel(uint32 spellId, uint32 dispellerSpellId { // final heal int32 healAmount = aurEff->GetAmount(); - int32 stack = dispelInfo.GetRemovedCharges(); - CastCustomSpell(this, 33778, &healAmount, &stack, NULL, true, NULL, NULL, aura->GetCasterGUID()); + if (Unit* caster = aura->GetCaster()) + { + healAmount = caster->SpellHealingBonusDone(this, aura->GetSpellInfo(), healAmount, HEAL, dispelInfo.GetRemovedCharges()); + healAmount = this->SpellHealingBonusTaken(caster, aura->GetSpellInfo(), healAmount, HEAL, dispelInfo.GetRemovedCharges()); + } + CastCustomSpell(this, 33778, &healAmount, NULL, NULL, true, NULL, NULL, aura->GetCasterGUID()); // mana if (Unit* caster = aura->GetCaster()) @@ -4424,9 +4488,7 @@ float Unit::GetTotalAuraMultiplierByMiscMask(AuraType auratype, uint32 misc_mask } // Add the highest of the Same Effect Stack Rule SpellGroups to the multiplier for (std::map<SpellGroup, int32>::const_iterator itr = SameEffectSpellGroup.begin(); itr != SameEffectSpellGroup.end(); ++itr) - { AddPctN(multiplier, itr->second); - } return multiplier; } @@ -4461,27 +4523,39 @@ int32 Unit::GetMaxNegativeAuraModifierByMiscMask(AuraType auratype, uint32 misc_ int32 Unit::GetTotalAuraModifierByMiscValue(AuraType auratype, int32 misc_value) const { + std::map<SpellGroup, int32> SameEffectSpellGroup; int32 modifier = 0; AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype); for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i) { if ((*i)->GetMiscValue() == misc_value) - modifier += (*i)->GetAmount(); + if (!sSpellMgr->AddSameEffectStackRuleSpellGroups((*i)->GetSpellInfo(), (*i)->GetAmount(), SameEffectSpellGroup)) + modifier += (*i)->GetAmount(); } + + for (std::map<SpellGroup, int32>::const_iterator itr = SameEffectSpellGroup.begin(); itr != SameEffectSpellGroup.end(); ++itr) + modifier += itr->second; + return modifier; } float Unit::GetTotalAuraMultiplierByMiscValue(AuraType auratype, int32 misc_value) const { + std::map<SpellGroup, int32> SameEffectSpellGroup; float multiplier = 1.0f; AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype); for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i) { if ((*i)->GetMiscValue() == misc_value) - AddPctN(multiplier, (*i)->GetAmount()); + if (!sSpellMgr->AddSameEffectStackRuleSpellGroups((*i)->GetSpellInfo(), (*i)->GetAmount(), SameEffectSpellGroup)) + AddPctN(multiplier, (*i)->GetAmount()); } + + for (std::map<SpellGroup, int32>::const_iterator itr = SameEffectSpellGroup.begin(); itr != SameEffectSpellGroup.end(); ++itr) + AddPctN(multiplier, itr->second); + return multiplier; } @@ -4515,27 +4589,39 @@ int32 Unit::GetMaxNegativeAuraModifierByMiscValue(AuraType auratype, int32 misc_ int32 Unit::GetTotalAuraModifierByAffectMask(AuraType auratype, SpellInfo const* affectedSpell) const { + std::map<SpellGroup, int32> SameEffectSpellGroup; int32 modifier = 0; AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype); for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i) { if ((*i)->IsAffectedOnSpell(affectedSpell)) - modifier += (*i)->GetAmount(); + if (!sSpellMgr->AddSameEffectStackRuleSpellGroups((*i)->GetSpellInfo(), (*i)->GetAmount(), SameEffectSpellGroup)) + modifier += (*i)->GetAmount(); } + + for (std::map<SpellGroup, int32>::const_iterator itr = SameEffectSpellGroup.begin(); itr != SameEffectSpellGroup.end(); ++itr) + modifier += itr->second; + return modifier; } float Unit::GetTotalAuraMultiplierByAffectMask(AuraType auratype, SpellInfo const* affectedSpell) const { + std::map<SpellGroup, int32> SameEffectSpellGroup; float multiplier = 1.0f; AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype); for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i) { if ((*i)->IsAffectedOnSpell(affectedSpell)) - AddPctN(multiplier, (*i)->GetAmount()); + if (!sSpellMgr->AddSameEffectStackRuleSpellGroups((*i)->GetSpellInfo(), (*i)->GetAmount(), SameEffectSpellGroup)) + AddPctN(multiplier, (*i)->GetAmount()); } + + for (std::map<SpellGroup, int32>::const_iterator itr = SameEffectSpellGroup.begin(); itr != SameEffectSpellGroup.end(); ++itr) + AddPctN(multiplier, itr->second); + return multiplier; } @@ -5719,7 +5805,7 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere // Glyph of Polymorph case 56375: { - if(!target) + if (!target) return false; target->RemoveAurasByType(SPELL_AURA_PERIODIC_DAMAGE, 0, target->GetAura(32409)); // SW:D shall not be removed. target->RemoveAurasByType(SPELL_AURA_PERIODIC_DAMAGE_PERCENT); @@ -5778,13 +5864,13 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere // Blessing of Ancient Kings (Val'anyr, Hammer of Ancient Kings) case 64411: { - if(!victim) + if (!victim) return false; basepoints0 = int32(CalculatePctN(damage, 15)); if (AuraEffect* aurEff = victim->GetAuraEffect(64413, 0, GetGUID())) { // The shield can grow to a maximum size of 20, 000 damage absorbtion - aurEff->SetAmount(std::max<int32>(aurEff->GetAmount() + basepoints0, 20000)); + aurEff->SetAmount(std::min<int32>(aurEff->GetAmount() + basepoints0, 20000)); // Refresh and return to prevent replacing the aura aurEff->GetBase()->RefreshDuration(); @@ -5966,6 +6052,8 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere // Siphon Life case 63108: { + if (!damage) + break; // Glyph of Siphon Life if (HasAura(56216)) triggerAmount += triggerAmount / 4; @@ -6089,7 +6177,7 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere // Divine Aegis if (dummySpell->SpellIconID == 2820) { - if(!target) + if (!target) return false; // Multiple effects stack, so let's try to find this aura. @@ -6259,7 +6347,7 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere // Glyph of Shred case 54815: { - if(!target) + if (!target) return false; // try to find spell Rip on the target @@ -6565,7 +6653,7 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere // Explosive Shot if (procSpell->SpellFamilyFlags[2] & 0x200) { - if(!victim) + if (!victim) return false; if (AuraEffect const* pEff = victim->GetAuraEffect(SPELL_AURA_PERIODIC_DUMMY, SPELLFAMILY_HUNTER, 0x0, 0x80000000, 0x0, GetGUID())) basepoints0 = pEff->GetSpellInfo()->CalcPowerCost(this, SpellSchoolMask(pEff->GetSpellInfo()->SchoolMask)) * 4/10/3; @@ -6645,8 +6733,8 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere return false; triggered_spell_id = 25742; float ap = GetTotalAttackPowerValue(BASE_ATTACK); - int32 holy = SpellBaseDamageBonus(SPELL_SCHOOL_MASK_HOLY) + - SpellBaseDamageBonusForVictim(SPELL_SCHOOL_MASK_HOLY, victim); + int32 holy = SpellBaseDamageBonusDone(SPELL_SCHOOL_MASK_HOLY) + + victim->SpellBaseDamageBonusTaken(SPELL_SCHOOL_MASK_HOLY); basepoints0 = (int32)GetAttackTime(BASE_ATTACK) * int32(ap * 0.022f + 0.044f * holy) / 1000; break; } @@ -7278,30 +7366,16 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere if (procSpell->SpellIconID != 2019) return false; - AuraEffect* aurEffA = NULL; - AuraEffectList const& auras = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_DONE); - for (AuraEffectList::const_iterator i = auras.begin(); i != auras.end(); ++i) + if (Creature* totem = GetMap()->GetCreature(m_SummonSlot[1])) // Fire totem summon slot { - SpellInfo const* spell = (*i)->GetSpellInfo(); - if (spell->SpellFamilyName == uint32(SPELLFAMILY_SHAMAN) && spell->SpellFamilyFlags.HasFlag(0, 0x02000000, 0)) + if (SpellInfo const* totemSpell = sSpellMgr->GetSpellInfo(totem->m_spells[0])) { - if ((*i)->GetCasterGUID() != GetGUID()) - continue; - if (spell->Id == 63283) - continue; - aurEffA = (*i); - break; + int32 bp0 = CalculatePctN(totemSpell->Effects[EFFECT_0].CalcValue(), triggerAmount); + int32 bp1 = CalculatePctN(totemSpell->Effects[EFFECT_1].CalcValue(), triggerAmount); + CastCustomSpell(this, 63283, &bp0, &bp1, NULL, true); + return true; } } - if (aurEffA) - { - int32 bp0 = 0, bp1 = 0; - bp0 = CalculatePctN(triggerAmount, aurEffA->GetAmount()); - if (AuraEffect* aurEffB = aurEffA->GetBase()->GetEffect(EFFECT_1)) - bp1 = CalculatePctN(triggerAmount, aurEffB->GetAmount()); - CastCustomSpell(this, 63283, &bp0, &bp1, NULL, true, NULL, triggeredByAura); - return true; - } return false; } break; @@ -7320,20 +7394,6 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere triggered_spell_id = 63685; break; } - // Storm, Earth and Fire - if (dummySpell->SpellIconID == 3063) - { - // Earthbind Totem summon only - if (procSpell->Id != 2484) - return false; - - float chance = (float)triggerAmount; - if (!roll_chance_f(chance)) - return false; - - triggered_spell_id = 64695; - break; - } // Ancestral Awakening if (dummySpell->SpellIconID == 3065) { @@ -7362,8 +7422,7 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere if (GetTypeId() != TYPEID_PLAYER || !victim || !victim->isAlive() || !castItem || !castItem->IsEquipped()) return false; - Player* player = ToPlayer(); - WeaponAttackType attType = WeaponAttackType(player->GetAttackBySlot(castItem->GetSlot())); + WeaponAttackType attType = WeaponAttackType(Player::GetAttackBySlot(castItem->GetSlot())); if ((attType != BASE_ATTACK && attType != OFF_ATTACK) || (attType == BASE_ATTACK && procFlag & PROC_FLAG_DONE_OFFHAND_ATTACK) || (attType == OFF_ATTACK && procFlag & PROC_FLAG_DONE_MAINHAND_ATTACK)) @@ -7371,8 +7430,8 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere float fire_onhit = float(CalculatePctF(dummySpell->Effects[EFFECT_0]. CalcValue(), 1.0f)); - float add_spellpower = (float)(SpellBaseDamageBonus(SPELL_SCHOOL_MASK_FIRE) - + SpellBaseDamageBonusForVictim(SPELL_SCHOOL_MASK_FIRE, victim)); + float add_spellpower = (float)(SpellBaseDamageBonusDone(SPELL_SCHOOL_MASK_FIRE) + + victim->SpellBaseDamageBonusTaken(SPELL_SCHOOL_MASK_FIRE)); // 1.3speed = 5%, 2.6speed = 10%, 4.0 speed = 15%, so, 1.0speed = 3.84% ApplyPctF(add_spellpower, 3.84f); @@ -7713,17 +7772,6 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere } } } - // Item - Death Knight T10 Melee 4P Bonus - if (dummySpell->Id == 70656) - { - Player* player = ToPlayer(); - if (!player) - return false; - - for (uint32 i = 0; i < MAX_RUNES; ++i) - if (player->GetRuneCooldown(i) == 0) - return false; - } break; } case SPELLFAMILY_POTION: @@ -7951,11 +7999,7 @@ bool Unit::HandleAuraProc(Unit* victim, uint32 damage, Aura* triggeredByAura, Sp for (uint8 i = 1; i < stack; ++i) dmg += mod * stack; if (Unit* caster = triggeredByAura->GetCaster()) - { caster->CastCustomSpell(70701, SPELLVALUE_BASE_POINT0, dmg); - if (Creature* creature = caster->ToCreature()) - creature->DespawnOrUnsummon(1); - } break; } // Ball of Flames Proc @@ -7995,7 +8039,7 @@ bool Unit::HandleAuraProc(Unit* victim, uint32 damage, Aura* triggeredByAura, Sp *handled = true; if (victim && victim->HasAura(53601)) { - int32 bp0 = CalculatePctN(int32(damage / 12), dummySpell->Effects[EFFECT_2]. CalcValue()); + int32 bp0 = CalculatePctN(int32(damage / 12), dummySpell->Effects[EFFECT_2].CalcValue()); // Item - Paladin T9 Holy 4P Bonus if (AuraEffect const* aurEff = GetAuraEffect(67191, 0)) AddPctN(bp0, aurEff->GetAmount()); @@ -8166,6 +8210,16 @@ bool Unit::HandleAuraProc(Unit* victim, uint32 damage, Aura* triggeredByAura, Sp CastCustomSpell(this, 70845, &basepoints0, NULL, NULL, true); break; } + // Recklessness + case 1719: + { + //! Possible hack alert + //! Don't drop charges on proc, they will be dropped on SpellMod removal + //! Before this change, it was dropping two charges per attack, one in ProcDamageAndSpellFor, and one in RemoveSpellMods. + //! The reason of this behaviour is Recklessness having three auras, 2 of them can not proc (isTriggeredAura array) but the other one can, making the whole spell proc. + *handled = true; + break; + } default: break; } @@ -8289,6 +8343,12 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg RemoveAuraFromStack(auraSpellInfo->Id); return false; } + if (auraSpellInfo->Id == 50720) + { + target = triggeredByAura->GetCaster(); + if (!target) + return false; + } break; case SPELLFAMILY_WARLOCK: { @@ -8639,6 +8699,36 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg trigger_spell_id = 50475; basepoints0 = CalculatePctN(int32(damage), triggerAmount); } + // Item - Death Knight T10 Melee 4P Bonus + else if (auraSpellInfo->Id == 70656) + { + if (GetTypeId() != TYPEID_PLAYER || getClass() != CLASS_DEATH_KNIGHT) + return false; + + for (uint8 i = 0; i < MAX_RUNES; ++i) + if (ToPlayer()->GetRuneCooldown(i) == 0) + return false; + } + break; + } + case SPELLFAMILY_ROGUE: + { + switch (auraSpellInfo->Id) + { + // Rogue T10 2P bonus, should only proc on caster + case 70805: + { + if (victim != this) + return false; + break; + } + // Rogue T10 4P bonus, should proc on victim + case 70803: + { + target = victim; + break; + } + } break; } default: @@ -8805,7 +8895,7 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg } // Blade Barrier - if (auraSpellInfo->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT && auraSpellInfo->SpellIconID == 85) + if (auraSpellInfo->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT && auraSpellInfo->SpellIconID == 85 && procSpell) { Player* player = ToPlayer(); if (!player || player->getClass() != CLASS_DEATH_KNIGHT) @@ -8911,7 +9001,7 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg { if (AuraEffect* aurEff = owner->GetDummyAuraEffect(SPELLFAMILY_WARLOCK, 3220, 0)) { - basepoints0 = int32((aurEff->GetAmount() * owner->SpellBaseDamageBonus(SpellSchoolMask(SPELL_SCHOOL_MASK_MAGIC)) + 100.0f) / 100.0f); // TODO: Is it right? + basepoints0 = int32((aurEff->GetAmount() * owner->SpellBaseDamageBonusDone(SpellSchoolMask(SPELL_SCHOOL_MASK_MAGIC)) + 100.0f) / 100.0f); // TODO: Is it right? CastCustomSpell(this, trigger_spell_id, &basepoints0, &basepoints0, NULL, true, castItem, triggeredByAura); return true; } @@ -9493,6 +9583,16 @@ bool Unit::Attack(Unit* victim, bool meleeAttack) if (meleeAttack) SendMeleeAttackStart(victim); + // Let the pet know we've started attacking someting. Handles melee attacks only + // Spells such as auto-shot and others handled in WorldSession::HandleCastSpellOpcode + if (this->GetTypeId() == TYPEID_PLAYER) + { + Pet* playerPet = this->ToPlayer()->GetPet(); + + if (playerPet && playerPet->isAlive()) + playerPet->AI()->OwnerAttacked(victim); + } + return true; } @@ -10091,7 +10191,7 @@ Unit* Unit::GetFirstControlled() const // Sequence: charmed, pet, other guardians Unit* unit = GetCharm(); if (!unit) - if (uint64 guid = GetUInt64Value(UNIT_FIELD_SUMMON)) + if (uint64 guid = GetMinionGUID()) unit = ObjectAccessor::GetUnit(*this, guid); return unit; @@ -10268,7 +10368,7 @@ void Unit::EnergizeBySpell(Unit* victim, uint32 spellID, uint32 damage, Powers p victim->getHostileRefManager().threatAssist(this, float(damage) * 0.5f, spellInfo); } -uint32 Unit::SpellDamageBonus(Unit* victim, SpellInfo const* spellProto, uint32 pdamage, DamageEffectType damagetype, uint32 stack) +uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uint32 pdamage, DamageEffectType damagetype, uint32 stack) { if (!spellProto || !victim || damagetype == DIRECT_DAMAGE) return pdamage; @@ -10281,33 +10381,35 @@ uint32 Unit::SpellDamageBonus(Unit* victim, SpellInfo const* spellProto, uint32 // For totems get damage bonus from owner if (GetTypeId() == TYPEID_UNIT && ToCreature()->isTotem()) if (Unit* owner = GetOwner()) - return owner->SpellDamageBonus(victim, spellProto, pdamage, damagetype); + return owner->SpellDamageBonusDone(victim, spellProto, pdamage, damagetype); - // Taken/Done total percent damage auras + // Done total percent damage auras float DoneTotalMod = 1.0f; float ApCoeffMod = 1.0f; int32 DoneTotal = 0; - int32 TakenTotal = 0; - // ..done // Pet damage? if (GetTypeId() == TYPEID_UNIT && !ToCreature()->isPet()) DoneTotalMod *= ToCreature()->GetSpellDamageMod(ToCreature()->GetCreatureTemplate()->rank); - AuraEffectList const& mModDamagePercentDone = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_PERCENT_DONE); - for (AuraEffectList::const_iterator i = mModDamagePercentDone.begin(); i != mModDamagePercentDone.end(); ++i) + // Some spells don't benefit from pct done mods + if (!(spellProto->AttributesEx6 & SPELL_ATTR6_NO_DONE_PCT_DAMAGE_MODS) && !spellProto->IsRankOf(sSpellMgr->GetSpellInfo(12162))) { - if (spellProto->EquippedItemClass == -1 && (*i)->GetSpellInfo()->EquippedItemClass != -1) //prevent apply mods from weapon specific case to non weapon specific spells (Example: thunder clap and two-handed weapon specialization) - continue; - - if ((*i)->GetMiscValue() & spellProto->GetSchoolMask()) + AuraEffectList const& mModDamagePercentDone = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_PERCENT_DONE); + for (AuraEffectList::const_iterator i = mModDamagePercentDone.begin(); i != mModDamagePercentDone.end(); ++i) { - if ((*i)->GetSpellInfo()->EquippedItemClass == -1) - AddPctN(DoneTotalMod, (*i)->GetAmount()); - else if (!((*i)->GetSpellInfo()->AttributesEx5 & SPELL_ATTR5_SPECIAL_ITEM_CLASS_CHECK) && ((*i)->GetSpellInfo()->EquippedItemSubClassMask == 0)) - AddPctN(DoneTotalMod, (*i)->GetAmount()); - else if (ToPlayer() && ToPlayer()->HasItemFitToSpellRequirements((*i)->GetSpellInfo())) - AddPctN(DoneTotalMod, (*i)->GetAmount()); + if (spellProto->EquippedItemClass == -1 && (*i)->GetSpellInfo()->EquippedItemClass != -1) //prevent apply mods from weapon specific case to non weapon specific spells (Example: thunder clap and two-handed weapon specialization) + continue; + + if ((*i)->GetMiscValue() & spellProto->GetSchoolMask()) + { + if ((*i)->GetSpellInfo()->EquippedItemClass == -1) + AddPctN(DoneTotalMod, (*i)->GetAmount()); + else if (!((*i)->GetSpellInfo()->AttributesEx5 & SPELL_ATTR5_SPECIAL_ITEM_CLASS_CHECK) && ((*i)->GetSpellInfo()->EquippedItemSubClassMask == 0)) + AddPctN(DoneTotalMod, (*i)->GetAmount()); + else if (ToPlayer() && ToPlayer()->HasItemFitToSpellRequirements((*i)->GetSpellInfo())) + AddPctN(DoneTotalMod, (*i)->GetAmount()); + } } } @@ -10487,7 +10589,7 @@ uint32 Unit::SpellDamageBonus(Unit* victim, SpellInfo const* spellProto, uint32 break; } } - break; + break; case SPELLFAMILY_PRIEST: // Mind Flay if (spellProto->SpellFamilyFlags[0] & 0x800000) @@ -10520,7 +10622,7 @@ uint32 Unit::SpellDamageBonus(Unit* victim, SpellInfo const* spellProto, uint32 if (victim->HasAuraState(AURA_STATE_HEALTHLESS_35_PERCENT)) AddPctN(DoneTotalMod, aurEff->GetAmount()); } - break; + break; case SPELLFAMILY_PALADIN: // Judgement of Vengeance/Judgement of Corruption if ((spellProto->SpellFamilyFlags[1] & 0x400000) && spellProto->SpellIconID == 2292) @@ -10538,7 +10640,7 @@ uint32 Unit::SpellDamageBonus(Unit* victim, SpellInfo const* spellProto, uint32 if (stacks) AddPctU(DoneTotalMod, 10 * stacks); } - break; + break; case SPELLFAMILY_DRUID: // Thorns if (spellProto->SpellFamilyFlags[0] & 0x100) @@ -10547,7 +10649,7 @@ uint32 Unit::SpellDamageBonus(Unit* victim, SpellInfo const* spellProto, uint32 if (AuraEffect* aurEff = GetAuraEffectOfRankedSpell(16836, 0)) AddPctN(DoneTotalMod, aurEff->GetAmount()); } - break; + break; case SPELLFAMILY_WARLOCK: // Fire and Brimstone if (spellProto->SpellFamilyFlags[1] & 0x00020040) @@ -10569,14 +10671,14 @@ uint32 Unit::SpellDamageBonus(Unit* victim, SpellInfo const* spellProto, uint32 if (spellProto->SpellFamilyFlags[1] & 0x00400000 && isPet()) if (uint8 count = victim->GetDoTsByCaster(GetOwnerGUID())) AddPctN(DoneTotalMod, 15 * count); - break; + break; case SPELLFAMILY_HUNTER: // Steady Shot if (spellProto->SpellFamilyFlags[1] & 0x1) if (AuraEffect* aurEff = GetAuraEffect(56826, 0)) // Glyph of Steady Shot if (victim->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_HUNTER, 0x00004000, 0, 0, GetGUID())) AddPctN(DoneTotalMod, aurEff->GetAmount()); - break; + break; case SPELLFAMILY_DEATHKNIGHT: // Improved Icy Touch if (spellProto->SpellFamilyFlags[0] & 0x2) @@ -10617,53 +10719,11 @@ uint32 Unit::SpellDamageBonus(Unit* victim, SpellInfo const* spellProto, uint32 } } } - break; - } - - // ..taken - float TakenTotalMod = 1.0f; - - // from positive and negative SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN - // multiplicative bonus, for example Dispersion + Shadowform (0.10*0.85=0.085) - TakenTotalMod *= victim->GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, spellProto->GetSchoolMask()); - - // .. taken pct: dummy auras - AuraEffectList const& mDummyAuras = victim->GetAuraEffectsByType(SPELL_AURA_DUMMY); - for (AuraEffectList::const_iterator i = mDummyAuras.begin(); i != mDummyAuras.end(); ++i) - { - switch ((*i)->GetSpellInfo()->SpellIconID) - { - // Cheat Death - case 2109: - if ((*i)->GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL) - { - if (victim->GetTypeId() != TYPEID_PLAYER) - continue; - float mod = victim->ToPlayer()->GetRatingBonusValue(CR_CRIT_TAKEN_MELEE) * (-8.0f); - AddPctF(TakenTotalMod, std::max(mod, float((*i)->GetAmount()))); - } - break; - } - } - - // From caster spells - AuraEffectList const& mOwnerTaken = victim->GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_FROM_CASTER); - for (AuraEffectList::const_iterator i = mOwnerTaken.begin(); i != mOwnerTaken.end(); ++i) - if ((*i)->GetCasterGUID() == GetGUID() && (*i)->IsAffectedOnSpell(spellProto)) - AddPctN(TakenTotalMod, (*i)->GetAmount()); - - // Mod damage from spell mechanic - if (uint32 mechanicMask = spellProto->GetAllEffectsMechanicMask()) - { - AuraEffectList const& mDamageDoneMechanic = victim->GetAuraEffectsByType(SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT); - for (AuraEffectList::const_iterator i = mDamageDoneMechanic.begin(); i != mDamageDoneMechanic.end(); ++i) - if (mechanicMask & uint32(1<<((*i)->GetMiscValue()))) - AddPctN(TakenTotalMod, (*i)->GetAmount()); + break; } - // Taken/Done fixed damage bonus auras - int32 DoneAdvertisedBenefit = SpellBaseDamageBonus(spellProto->GetSchoolMask()); - int32 TakenAdvertisedBenefit = SpellBaseDamageBonusForVictim(spellProto->GetSchoolMask(), victim); + // Done fixed damage bonus auras + int32 DoneAdvertisedBenefit = SpellBaseDamageBonusDone(spellProto->GetSchoolMask()); // Pets just add their bonus damage to their spell damage // note that their spell damage is just gain of their own auras if (HasUnitTypeMask(UNIT_MASK_GUARDIAN)) @@ -10680,7 +10740,7 @@ uint32 Unit::SpellDamageBonus(Unit* victim, SpellInfo const* spellProto, uint32 if (bonus->ap_dot_bonus > 0) { WeaponAttackType attType = (spellProto->IsRangedWeaponSpell() && spellProto->DmgClass != SPELL_DAMAGE_CLASS_MELEE) ? RANGED_ATTACK : BASE_ATTACK; - float APbonus = (float) victim->GetTotalAuraModifier(attType == BASE_ATTACK ? SPELL_AURA_MELEE_ATTACK_POWER_ATTACKER_BONUS : SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS); + float APbonus = float(victim->GetTotalAuraModifier(attType == BASE_ATTACK ? SPELL_AURA_MELEE_ATTACK_POWER_ATTACKER_BONUS : SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS)); APbonus += GetTotalAttackPowerValue(attType); DoneTotal += int32(bonus->ap_dot_bonus * stack * ApCoeffMod * APbonus); } @@ -10691,74 +10751,20 @@ uint32 Unit::SpellDamageBonus(Unit* victim, SpellInfo const* spellProto, uint32 if (bonus->ap_bonus > 0) { WeaponAttackType attType = (spellProto->IsRangedWeaponSpell() && spellProto->DmgClass != SPELL_DAMAGE_CLASS_MELEE) ? RANGED_ATTACK : BASE_ATTACK; - float APbonus = (float) victim->GetTotalAuraModifier(attType == BASE_ATTACK ? SPELL_AURA_MELEE_ATTACK_POWER_ATTACKER_BONUS : SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS); + float APbonus = float(victim->GetTotalAuraModifier(attType == BASE_ATTACK ? SPELL_AURA_MELEE_ATTACK_POWER_ATTACKER_BONUS : SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS)); APbonus += GetTotalAttackPowerValue(attType); DoneTotal += int32(bonus->ap_bonus * stack * ApCoeffMod * APbonus); } } } // Default calculation - if (DoneAdvertisedBenefit || TakenAdvertisedBenefit) + if (DoneAdvertisedBenefit) { if (!bonus || coeff < 0) - { - // Damage Done from spell damage bonus - int32 CastingTime = spellProto->IsChanneled() ? spellProto->GetDuration() : spellProto->CalcCastTime(); - // Damage over Time spells bonus calculation - float DotFactor = 1.0f; - if (damagetype == DOT) - { - int32 DotDuration = spellProto->GetDuration(); - // 200% limit - if (DotDuration > 0) - { - if (DotDuration > 30000) - DotDuration = 30000; - if (!spellProto->IsChanneled()) - DotFactor = DotDuration / 15000.0f; - uint8 x = 0; - for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j) - { - if (spellProto->Effects[j].Effect == SPELL_EFFECT_APPLY_AURA && ( - spellProto->Effects[j].ApplyAuraName == SPELL_AURA_PERIODIC_DAMAGE || - spellProto->Effects[j].ApplyAuraName == SPELL_AURA_PERIODIC_LEECH)) - { - x = j; - break; - } - } - int32 DotTicks = 6; - if (spellProto->Effects[x].Amplitude != 0) - DotTicks = DotDuration / spellProto->Effects[x].Amplitude; - if (DotTicks) - { - DoneAdvertisedBenefit /= DotTicks; - TakenAdvertisedBenefit /= DotTicks; - } - } - } - // Distribute Damage over multiple effects, reduce by AoE - CastingTime = GetCastingTimeForBonus(spellProto, damagetype, CastingTime); - - // 50% for damage and healing spells for leech spells from damage bonus and 0% from healing - for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j) - { - if (spellProto->Effects[j].Effect == SPELL_EFFECT_HEALTH_LEECH || - (spellProto->Effects[j].Effect == SPELL_EFFECT_APPLY_AURA && spellProto->Effects[j].ApplyAuraName == SPELL_AURA_PERIODIC_LEECH)) - { - CastingTime /= 2; - break; - } - } - if (spellProto->SchoolMask != SPELL_SCHOOL_MASK_NORMAL) - coeff = (CastingTime / 3500.0f) * DotFactor; - else - coeff = DotFactor; - } + coeff = CalculateDefaultCoefficient(spellProto, damagetype) * int32(stack); float factorMod = CalculateLevelPenalty(spellProto) * stack; - // level penalty still applied on Taken bonus - is it blizzlike? - TakenTotal+= int32(TakenAdvertisedBenefit * factorMod); + if (Player* modOwner = GetSpellModOwner()) { coeff *= 100.0f; @@ -10775,27 +10781,94 @@ uint32 Unit::SpellDamageBonus(Unit* victim, SpellInfo const* spellProto, uint32 DoneTotalMod = 1.0f; } - // Some spells don't benefit from pct done mods - // maybe should be implemented like SPELL_ATTR3_NO_DONE_BONUS, - // but then it may break spell power coeffs work on spell 31117 - if (spellProto->AttributesEx6 & SPELL_ATTR6_NO_DONE_PCT_DAMAGE_MODS) - DoneTotalMod = 1.0f; - float tmpDamage = (int32(pdamage) + DoneTotal) * DoneTotalMod; // apply spellmod to Done damage (flat and pct) if (Player* modOwner = GetSpellModOwner()) modOwner->ApplySpellMod(spellProto->Id, damagetype == DOT ? SPELLMOD_DOT : SPELLMOD_DAMAGE, tmpDamage); - tmpDamage = (tmpDamage + TakenTotal) * TakenTotalMod; + return uint32(std::max(tmpDamage, 0.0f)); +} + +uint32 Unit::SpellDamageBonusTaken(Unit* caster, SpellInfo const* spellProto, uint32 pdamage, DamageEffectType damagetype, uint32 stack) +{ + if (!spellProto || damagetype == DIRECT_DAMAGE) + return pdamage; + + int32 TakenTotal = 0; + float TakenTotalMod = 1.0f; + + // from positive and negative SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN + // multiplicative bonus, for example Dispersion + Shadowform (0.10*0.85=0.085) + TakenTotalMod *= GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, spellProto->GetSchoolMask()); + + //.. taken pct: dummy auras + AuraEffectList const& mDummyAuras = GetAuraEffectsByType(SPELL_AURA_DUMMY); + for (AuraEffectList::const_iterator i = mDummyAuras.begin(); i != mDummyAuras.end(); ++i) + { + switch ((*i)->GetSpellInfo()->SpellIconID) + { + // Cheat Death + case 2109: + if ((*i)->GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL) + { + if (GetTypeId() != TYPEID_PLAYER) + continue; + float mod = ToPlayer()->GetRatingBonusValue(CR_CRIT_TAKEN_MELEE) * (-8.0f); + AddPctF(TakenTotalMod, std::max(mod, float((*i)->GetAmount()))); + } + break; + } + } + + // From caster spells + AuraEffectList const& mOwnerTaken = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_FROM_CASTER); + for (AuraEffectList::const_iterator i = mOwnerTaken.begin(); i != mOwnerTaken.end(); ++i) + if ((*i)->GetCasterGUID() == caster->GetGUID() && (*i)->IsAffectedOnSpell(spellProto)) + AddPctN(TakenTotalMod, (*i)->GetAmount()); + + // Mod damage from spell mechanic + if (uint32 mechanicMask = spellProto->GetAllEffectsMechanicMask()) + { + AuraEffectList const& mDamageDoneMechanic = GetAuraEffectsByType(SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT); + for (AuraEffectList::const_iterator i = mDamageDoneMechanic.begin(); i != mDamageDoneMechanic.end(); ++i) + if (mechanicMask & uint32(1<<((*i)->GetMiscValue()))) + AddPctN(TakenTotalMod, (*i)->GetAmount()); + } + + int32 TakenAdvertisedBenefit = SpellBaseDamageBonusTaken(spellProto->GetSchoolMask()); + + // Check for table values + float coeff = 0; + SpellBonusEntry const* bonus = sSpellMgr->GetSpellBonusData(spellProto->Id); + if (bonus) + coeff = (damagetype == DOT) ? bonus->dot_damage : bonus->direct_damage; + + // Default calculation + if (TakenAdvertisedBenefit) + { + if (!bonus || coeff < 0) + coeff = CalculateDefaultCoefficient(spellProto, damagetype) * int32(stack); + + float factorMod = CalculateLevelPenalty(spellProto) * stack; + // level penalty still applied on Taken bonus - is it blizzlike? + if (Player* modOwner = GetSpellModOwner()) + { + coeff *= 100.0f; + modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_BONUS_MULTIPLIER, coeff); + coeff /= 100.0f; + } + TakenTotal+= int32(TakenAdvertisedBenefit * coeff * factorMod); + } + + float tmpDamage = (float(pdamage) + TakenTotal) * TakenTotalMod; return uint32(std::max(tmpDamage, 0.0f)); } -int32 Unit::SpellBaseDamageBonus(SpellSchoolMask schoolMask) +int32 Unit::SpellBaseDamageBonusDone(SpellSchoolMask schoolMask) { int32 DoneAdvertisedBenefit = 0; - // ..done AuraEffectList const& mDamageDone = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_DONE); for (AuraEffectList::const_iterator i = mDamageDone.begin(); i != mDamageDone.end(); ++i) if (((*i)->GetMiscValue() & schoolMask) != 0 && @@ -10828,27 +10901,19 @@ int32 Unit::SpellBaseDamageBonus(SpellSchoolMask schoolMask) DoneAdvertisedBenefit += int32(CalculatePctN(GetTotalAttackPowerValue(BASE_ATTACK), (*i)->GetAmount())); } - return DoneAdvertisedBenefit > 0 ? DoneAdvertisedBenefit : 0; + return DoneAdvertisedBenefit; } -int32 Unit::SpellBaseDamageBonusForVictim(SpellSchoolMask schoolMask, Unit* victim) +int32 Unit::SpellBaseDamageBonusTaken(SpellSchoolMask schoolMask) { - uint32 creatureTypeMask = victim->GetCreatureTypeMask(); - int32 TakenAdvertisedBenefit = 0; - // ..done (for creature type by mask) in taken - AuraEffectList const& mDamageDoneCreature = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_DONE_CREATURE); - for (AuraEffectList::const_iterator i = mDamageDoneCreature.begin(); i != mDamageDoneCreature.end(); ++i) - if (creatureTypeMask & uint32((*i)->GetMiscValue())) - TakenAdvertisedBenefit += (*i)->GetAmount(); - // ..taken - AuraEffectList const& mDamageTaken = victim->GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_TAKEN); + AuraEffectList const& mDamageTaken = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_TAKEN); for (AuraEffectList::const_iterator i = mDamageTaken.begin(); i != mDamageTaken.end(); ++i) if (((*i)->GetMiscValue() & schoolMask) != 0) TakenAdvertisedBenefit += (*i)->GetAmount(); - return TakenAdvertisedBenefit > 0 ? TakenAdvertisedBenefit : 0; + return TakenAdvertisedBenefit; } bool Unit::isSpellCrit(Unit* victim, SpellInfo const* spellProto, SpellSchoolMask schoolMask, WeaponAttackType attackType) const @@ -11112,23 +11177,19 @@ uint32 Unit::SpellCriticalHealingBonus(SpellInfo const* spellProto, uint32 damag return damage; } -uint32 Unit::SpellHealingBonus(Unit* victim, SpellInfo const* spellProto, uint32 healamount, DamageEffectType damagetype, uint32 stack) +uint32 Unit::SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, uint32 healamount, DamageEffectType damagetype, uint32 stack) { // For totems get healing bonus from owner (statue isn't totem in fact) - if (GetTypeId() == TYPEID_UNIT && ToCreature()->isTotem()) + if (GetTypeId() == TYPEID_UNIT && isTotem()) if (Unit* owner = GetOwner()) - return owner->SpellHealingBonus(victim, spellProto, healamount, damagetype, stack); + return owner->SpellHealingBonusDone(victim, spellProto, healamount, damagetype, stack); - // no bonus for heal potions/bandages + // No bonus healing for potion spells if (spellProto->SpellFamilyName == SPELLFAMILY_POTION) return healamount; - // Healing Done - // Taken/Done total percent damage auras - float DoneTotalMod = 1.0f; - float TakenTotalMod = 1.0f; - int32 DoneTotal = 0; - int32 TakenTotal = 0; + float DoneTotalMod = 1.0f; + int32 DoneTotal = 0; // Healing done percent AuraEffectList const& mHealingDonePct = GetAuraEffectsByType(SPELL_AURA_MOD_HEALING_DONE_PERCENT); @@ -11191,28 +11252,11 @@ uint32 Unit::SpellHealingBonus(Unit* victim, SpellInfo const* spellProto, uint32 } } - // Taken/Done fixed damage bonus auras - int32 DoneAdvertisedBenefit = SpellBaseHealingBonus(spellProto->GetSchoolMask()); - int32 TakenAdvertisedBenefit = SpellBaseHealingBonusForVictim(spellProto->GetSchoolMask(), victim); - - bool scripted = false; - - for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) - { - switch (spellProto->Effects[i].ApplyAuraName) - { - // These auras do not use healing coeff - case SPELL_AURA_PERIODIC_LEECH: - case SPELL_AURA_PERIODIC_HEALTH_FUNNEL: - scripted = true; - break; - } - if (spellProto->Effects[i].Effect == SPELL_EFFECT_HEALTH_LEECH) - scripted = true; - } + // Done fixed damage bonus auras + int32 DoneAdvertisedBenefit = SpellBaseHealingBonusDone(spellProto->GetSchoolMask()); // Check for table values - SpellBonusEntry const* bonus = !scripted ? sSpellMgr->GetSpellBonusData(spellProto->Id) : NULL; + SpellBonusEntry const* bonus = sSpellMgr->GetSpellBonusData(spellProto->Id); float coeff = 0; float factorMod = 1.0f; if (bonus) @@ -11222,159 +11266,184 @@ uint32 Unit::SpellHealingBonus(Unit* victim, SpellInfo const* spellProto, uint32 coeff = bonus->dot_damage; if (bonus->ap_dot_bonus > 0) DoneTotal += int32(bonus->ap_dot_bonus * stack * GetTotalAttackPowerValue( - (spellProto->IsRangedWeaponSpell() && spellProto->DmgClass !=SPELL_DAMAGE_CLASS_MELEE)? RANGED_ATTACK : BASE_ATTACK)); + (spellProto->IsRangedWeaponSpell() && spellProto->DmgClass !=SPELL_DAMAGE_CLASS_MELEE) ? RANGED_ATTACK : BASE_ATTACK)); } else { coeff = bonus->direct_damage; if (bonus->ap_bonus > 0) DoneTotal += int32(bonus->ap_bonus * stack * GetTotalAttackPowerValue( - (spellProto->IsRangedWeaponSpell() && spellProto->DmgClass !=SPELL_DAMAGE_CLASS_MELEE)? RANGED_ATTACK : BASE_ATTACK)); + (spellProto->IsRangedWeaponSpell() && spellProto->DmgClass !=SPELL_DAMAGE_CLASS_MELEE) ? RANGED_ATTACK : BASE_ATTACK)); } } - else // scripted bonus + else { - // Gift of the Naaru - if (spellProto->SpellFamilyFlags[2] & 0x80000000 && spellProto->SpellIconID == 329) - { - scripted = true; - int32 apBonus = int32(std::max(GetTotalAttackPowerValue(BASE_ATTACK), GetTotalAttackPowerValue(RANGED_ATTACK))); - if (apBonus > DoneAdvertisedBenefit) - DoneTotal += int32(apBonus * 0.22f); // 22% of AP per tick - else - DoneTotal += int32(DoneAdvertisedBenefit * 0.377f); // 37.7% of BH per tick - } - // Earthliving - 0.45% of normal hot coeff - else if (spellProto->SpellFamilyName == SPELLFAMILY_SHAMAN && spellProto->SpellFamilyFlags[1] & 0x80000) - factorMod *= 0.45f; - // Already set to scripted? so not uses healing bonus coefficient - // No heal coeff for SPELL_DAMAGE_CLASS_NONE class spells by default - else if (scripted || spellProto->DmgClass == SPELL_DAMAGE_CLASS_NONE) - { - scripted = true; - coeff = 0.0f; - } + // No bonus healing for SPELL_DAMAGE_CLASS_NONE class spells by default + if (spellProto->DmgClass == SPELL_DAMAGE_CLASS_NONE) + return healamount; } // Default calculation - if (DoneAdvertisedBenefit || TakenAdvertisedBenefit) + if (DoneAdvertisedBenefit) { - if ((!bonus && !scripted) || coeff < 0) - { - // Damage Done from spell damage bonus - int32 CastingTime = !spellProto->IsChanneled() ? spellProto->CalcCastTime() : spellProto->GetDuration(); - // Damage over Time spells bonus calculation - float DotFactor = 1.0f; - if (damagetype == DOT) - { - int32 DotDuration = spellProto->GetDuration(); - // 200% limit - if (DotDuration > 0) - { - if (DotDuration > 30000) DotDuration = 30000; - if (!spellProto->IsChanneled()) DotFactor = DotDuration / 15000.0f; - uint32 x = 0; - for (uint8 j = 0; j < MAX_SPELL_EFFECTS; j++) - { - if (spellProto->Effects[j].Effect == SPELL_EFFECT_APPLY_AURA && ( - spellProto->Effects[j].ApplyAuraName == SPELL_AURA_PERIODIC_DAMAGE || - spellProto->Effects[j].ApplyAuraName == SPELL_AURA_PERIODIC_LEECH)) - { - x = j; - break; - } - } - int32 DotTicks = 6; - if (spellProto->Effects[x].Amplitude != 0) - DotTicks = DotDuration / spellProto->Effects[x].Amplitude; - if (DotTicks) - { - DoneAdvertisedBenefit = DoneAdvertisedBenefit * int32(stack) / DotTicks; - TakenAdvertisedBenefit = TakenAdvertisedBenefit * int32(stack) / DotTicks; - } - } - } - // Distribute Damage over multiple effects, reduce by AoE - CastingTime = GetCastingTimeForBonus(spellProto, damagetype, CastingTime); - // 50% for damage and healing spells for leech spells from damage bonus and 0% from healing - for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j) - { - if (spellProto->Effects[j].Effect == SPELL_EFFECT_HEALTH_LEECH || - (spellProto->Effects[j].Effect == SPELL_EFFECT_APPLY_AURA && spellProto->Effects[j].ApplyAuraName == SPELL_AURA_PERIODIC_LEECH)) - { - CastingTime /= 2; - break; - } - } - // As wowwiki says: C = (Cast Time / 3.5) * 1.88 (for healing spells) - coeff = (CastingTime / 3500.0f) * DotFactor * 1.88f; - } + if (!bonus || coeff < 0) + coeff = CalculateDefaultCoefficient(spellProto, damagetype) * int32(stack) * 1.88f; // As wowwiki says: C = (Cast Time / 3.5) * 1.88 (for healing spells) factorMod *= CalculateLevelPenalty(spellProto) * stack; - // level penalty still applied on Taken bonus - is it blizzlike? - TakenTotal += int32(TakenAdvertisedBenefit * factorMod); + if (Player* modOwner = GetSpellModOwner()) { coeff *= 100.0f; modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_BONUS_MULTIPLIER, coeff); coeff /= 100.0f; } + + // Earthliving - 0.45% of normal hot coeff + if (spellProto->SpellFamilyName == SPELLFAMILY_SHAMAN && spellProto->SpellFamilyFlags[1] & 0x80000) + factorMod *= 0.45f; + DoneTotal += int32(DoneAdvertisedBenefit * coeff * factorMod); } + // Gift of the Naaru + if (spellProto->SpellFamilyFlags[2] & 0x80000000 && spellProto->SpellIconID == 329) + { + int32 apBonus = int32(std::max(GetTotalAttackPowerValue(BASE_ATTACK), GetTotalAttackPowerValue(RANGED_ATTACK))); + if (apBonus > DoneAdvertisedBenefit) + DoneTotal += int32(apBonus * 0.22f); // 22% of AP per tick + else + DoneTotal += int32(DoneAdvertisedBenefit * 0.377f); // 37.7% of BH per tick + } + + for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) + { + switch (spellProto->Effects[i].ApplyAuraName) + { + // Bonus healing does not apply to these spells + case SPELL_AURA_PERIODIC_LEECH: + case SPELL_AURA_PERIODIC_HEALTH_FUNNEL: + DoneTotal = 0; + break; + } + if (spellProto->Effects[i].Effect == SPELL_EFFECT_HEALTH_LEECH) + DoneTotal = 0; + } + // use float as more appropriate for negative values and percent applying - float heal = (int32(healamount) + DoneTotal) * DoneTotalMod; + float heal = float(int32(healamount) + DoneTotal) * DoneTotalMod; // apply spellmod to Done amount if (Player* modOwner = GetSpellModOwner()) modOwner->ApplySpellMod(spellProto->Id, damagetype == DOT ? SPELLMOD_DOT : SPELLMOD_DAMAGE, heal); - // Nourish cast - if (spellProto->SpellFamilyName == SPELLFAMILY_DRUID && spellProto->SpellFamilyFlags[1] & 0x2000000) - { - // Rejuvenation, Regrowth, Lifebloom, or Wild Growth - if (victim->GetAuraEffect(SPELL_AURA_PERIODIC_HEAL, SPELLFAMILY_DRUID, 0x50, 0x4000010, 0)) - // increase healing by 20% - TakenTotalMod *= 1.2f; - } - - // Taken mods + return uint32(std::max(heal, 0.0f)); +} - // Tenacity increase healing % taken - if (AuraEffect const* Tenacity = victim->GetAuraEffect(58549, 0)) - AddPctN(TakenTotalMod, Tenacity->GetAmount()); +uint32 Unit::SpellHealingBonusTaken(Unit* caster, SpellInfo const* spellProto, uint32 healamount, DamageEffectType damagetype, uint32 stack) +{ + float TakenTotalMod = 1.0f; // Healing taken percent - float minval = (float)victim->GetMaxNegativeAuraModifier(SPELL_AURA_MOD_HEALING_PCT); + float minval = float(GetMaxNegativeAuraModifier(SPELL_AURA_MOD_HEALING_PCT)); if (minval) AddPctF(TakenTotalMod, minval); - float maxval = (float)victim->GetMaxPositiveAuraModifier(SPELL_AURA_MOD_HEALING_PCT); + float maxval = float(GetMaxPositiveAuraModifier(SPELL_AURA_MOD_HEALING_PCT)); if (maxval) AddPctF(TakenTotalMod, maxval); + // Tenacity increase healing % taken + if (AuraEffect const* Tenacity = GetAuraEffect(58549, 0)) + AddPctN(TakenTotalMod, Tenacity->GetAmount()); + + // Healing Done + int32 TakenTotal = 0; + + // Taken fixed damage bonus auras + int32 TakenAdvertisedBenefit = SpellBaseHealingBonusTaken(spellProto->GetSchoolMask()); + + // Nourish cast + if (spellProto->SpellFamilyName == SPELLFAMILY_DRUID && spellProto->SpellFamilyFlags[1] & 0x2000000) + { + // Rejuvenation, Regrowth, Lifebloom, or Wild Growth + if (GetAuraEffect(SPELL_AURA_PERIODIC_HEAL, SPELLFAMILY_DRUID, 0x50, 0x4000010, 0)) + // increase healing by 20% + TakenTotalMod *= 1.2f; + } + if (damagetype == DOT) { // Healing over time taken percent - float minval_hot = (float)victim->GetMaxNegativeAuraModifier(SPELL_AURA_MOD_HOT_PCT); + float minval_hot = float(GetMaxNegativeAuraModifier(SPELL_AURA_MOD_HOT_PCT)); if (minval_hot) AddPctF(TakenTotalMod, minval_hot); - float maxval_hot = (float)victim->GetMaxPositiveAuraModifier(SPELL_AURA_MOD_HOT_PCT); + float maxval_hot = float(GetMaxPositiveAuraModifier(SPELL_AURA_MOD_HOT_PCT)); if (maxval_hot) AddPctF(TakenTotalMod, maxval_hot); } - AuraEffectList const& mHealingGet= victim->GetAuraEffectsByType(SPELL_AURA_MOD_HEALING_RECEIVED); + // Check for table values + SpellBonusEntry const* bonus = sSpellMgr->GetSpellBonusData(spellProto->Id); + float coeff = 0; + float factorMod = 1.0f; + if (bonus) + coeff = (damagetype == DOT) ? bonus->dot_damage : bonus->direct_damage; + else + { + // No bonus healing for SPELL_DAMAGE_CLASS_NONE class spells by default + if (spellProto->DmgClass == SPELL_DAMAGE_CLASS_NONE) + { + healamount = uint32(std::max((float(healamount) * TakenTotalMod), 0.0f)); + return healamount; + } + } + + // Default calculation + if (TakenAdvertisedBenefit) + { + if (!bonus || coeff < 0) + coeff = CalculateDefaultCoefficient(spellProto, damagetype) * int32(stack) * 1.88f; // As wowwiki says: C = (Cast Time / 3.5) * 1.88 (for healing spells) + + factorMod *= CalculateLevelPenalty(spellProto) * int32(stack); + if (Player* modOwner = GetSpellModOwner()) + { + coeff *= 100.0f; + modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_BONUS_MULTIPLIER, coeff); + coeff /= 100.0f; + } + + // Earthliving - 0.45% of normal hot coeff + if (spellProto->SpellFamilyName == SPELLFAMILY_SHAMAN && spellProto->SpellFamilyFlags[1] & 0x80000) + factorMod *= 0.45f; + + TakenTotal += int32(TakenAdvertisedBenefit * coeff * factorMod); + } + + AuraEffectList const& mHealingGet= GetAuraEffectsByType(SPELL_AURA_MOD_HEALING_RECEIVED); for (AuraEffectList::const_iterator i = mHealingGet.begin(); i != mHealingGet.end(); ++i) - if (GetGUID() == (*i)->GetCasterGUID() && (*i)->IsAffectedOnSpell(spellProto)) + if (caster->GetGUID() == (*i)->GetCasterGUID() && (*i)->IsAffectedOnSpell(spellProto)) AddPctN(TakenTotalMod, (*i)->GetAmount()); - heal = (int32(heal) + TakenTotal) * TakenTotalMod; + for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) + { + switch (spellProto->Effects[i].ApplyAuraName) + { + // Bonus healing does not apply to these spells + case SPELL_AURA_PERIODIC_LEECH: + case SPELL_AURA_PERIODIC_HEALTH_FUNNEL: + TakenTotal = 0; + break; + } + if (spellProto->Effects[i].Effect == SPELL_EFFECT_HEALTH_LEECH) + TakenTotal = 0; + } + + float heal = float(int32(healamount) + TakenTotal) * TakenTotalMod; return uint32(std::max(heal, 0.0f)); } -int32 Unit::SpellBaseHealingBonus(SpellSchoolMask schoolMask) +int32 Unit::SpellBaseHealingBonusDone(SpellSchoolMask schoolMask) { int32 AdvertisedBenefit = 0; @@ -11407,13 +11476,15 @@ int32 Unit::SpellBaseHealingBonus(SpellSchoolMask schoolMask) return AdvertisedBenefit; } -int32 Unit::SpellBaseHealingBonusForVictim(SpellSchoolMask schoolMask, Unit* victim) +int32 Unit::SpellBaseHealingBonusTaken(SpellSchoolMask schoolMask) { int32 AdvertisedBenefit = 0; - AuraEffectList const& mDamageTaken = victim->GetAuraEffectsByType(SPELL_AURA_MOD_HEALING); + + AuraEffectList const& mDamageTaken = GetAuraEffectsByType(SPELL_AURA_MOD_HEALING); for (AuraEffectList::const_iterator i = mDamageTaken.begin(); i != mDamageTaken.end(); ++i) if (((*i)->GetMiscValue() & schoolMask) != 0) AdvertisedBenefit += (*i)->GetAmount(); + return AdvertisedBenefit; } @@ -11440,7 +11511,7 @@ bool Unit::IsImmunedToDamage(SpellInfo const* spellInfo) return false; uint32 shoolMask = spellInfo->GetSchoolMask(); - if (spellInfo->Id != 42292 && spellInfo->Id !=59752) + if (spellInfo->Id != 42292 && spellInfo->Id != 59752) { // If m_immuneToSchool type contain this school type, IMMUNE damage. SpellImmuneList const& schoolList = m_spellImmune[IMMUNITY_SCHOOL]; @@ -11481,7 +11552,7 @@ bool Unit::IsImmunedToSpell(SpellInfo const* spellInfo) } // Spells that don't have effectMechanics. - if (!spellInfo->HasAnyEffectMechanic() && spellInfo->Mechanic) + if (spellInfo->Mechanic) { SpellImmuneList const& mechanicList = m_spellImmune[IMMUNITY_MECHANIC]; for (SpellImmuneList::const_iterator itr = mechanicList.begin(); itr != mechanicList.end(); ++itr) @@ -11494,16 +11565,17 @@ bool Unit::IsImmunedToSpell(SpellInfo const* spellInfo) { // State/effect immunities applied by aura expect full spell immunity // Ignore effects with mechanic, they are supposed to be checked separately - if (spellInfo->Effects[i].Mechanic || !IsImmunedToSpellEffect(spellInfo, i)) + if (!IsImmunedToSpellEffect(spellInfo, i)) { immuneToAllEffects = false; break; } } + if (immuneToAllEffects) //Return immune only if the target is immune to all spell effects. return true; - if (spellInfo->Id != 42292 && spellInfo->Id !=59752) + if (spellInfo->Id != 42292 && spellInfo->Id != 59752) { SpellImmuneList const& schoolList = m_spellImmune[IMMUNITY_SCHOOL]; for (SpellImmuneList::const_iterator itr = schoolList.begin(); itr != schoolList.end(); ++itr) @@ -11521,8 +11593,9 @@ bool Unit::IsImmunedToSpell(SpellInfo const* spellInfo) bool Unit::IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index) const { - if (!spellInfo) + if (!spellInfo || !spellInfo->Effects[index].IsEffect()) return false; + // If m_immuneToEffect type contain this effect type, IMMUNE effect. uint32 effect = spellInfo->Effects[index].Effect; SpellImmuneList const& effectList = m_spellImmune[IMMUNITY_EFFECT]; @@ -11556,21 +11629,17 @@ bool Unit::IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index) cons return false; } -void Unit::MeleeDamageBonus(Unit* victim, uint32 *pdamage, WeaponAttackType attType, SpellInfo const* spellProto) +uint32 Unit::MeleeDamageBonusDone(Unit* victim, uint32 pdamage, WeaponAttackType attType, SpellInfo const* spellProto) { - if (!victim) - return; - - if (*pdamage == 0) - return; + if (!victim || pdamage == 0) + return 0; uint32 creatureTypeMask = victim->GetCreatureTypeMask(); - // Taken/Done fixed damage bonus auras + // Done fixed damage bonus auras int32 DoneFlatBenefit = 0; - int32 TakenFlatBenefit = 0; - // ..done (for creature type by mask) in taken + // ..done AuraEffectList const& mDamageDoneCreature = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_DONE_CREATURE); for (AuraEffectList::const_iterator i = mDamageDoneCreature.begin(); i != mDamageDoneCreature.end(); ++i) if (creatureTypeMask & uint32((*i)->GetMiscValue())) @@ -11616,38 +11685,27 @@ void Unit::MeleeDamageBonus(Unit* victim, uint32 *pdamage, WeaponAttackType attT DoneFlatBenefit += int32(APbonus/14.0f * GetAPMultiplier(attType, normalized)); } - // ..taken - AuraEffectList const& mDamageTaken = victim->GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_TAKEN); - for (AuraEffectList::const_iterator i = mDamageTaken.begin(); i != mDamageTaken.end(); ++i) - if ((*i)->GetMiscValue() & GetMeleeDamageSchoolMask()) - TakenFlatBenefit += (*i)->GetAmount(); - - if (attType != RANGED_ATTACK) - TakenFlatBenefit += victim->GetTotalAuraModifier(SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN); - else - TakenFlatBenefit += victim->GetTotalAuraModifier(SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN); - - // Done/Taken total percent damage auras + // Done total percent damage auras float DoneTotalMod = 1.0f; - float TakenTotalMod = 1.0f; - // ..done - AuraEffectList const& mModDamagePercentDone = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_PERCENT_DONE); - for (AuraEffectList::const_iterator i = mModDamagePercentDone.begin(); i != mModDamagePercentDone.end(); ++i) - { - if (spellProto) + // Some spells don't benefit from pct done mods + if (spellProto) + if (!(spellProto->AttributesEx6 & SPELL_ATTR6_NO_DONE_PCT_DAMAGE_MODS) && !spellProto->IsRankOf(sSpellMgr->GetSpellInfo(12162))) { - if ((*i)->GetMiscValue() & spellProto->GetSchoolMask() && !(spellProto->GetSchoolMask() & SPELL_SCHOOL_MASK_NORMAL)) + AuraEffectList const& mModDamagePercentDone = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_PERCENT_DONE); + for (AuraEffectList::const_iterator i = mModDamagePercentDone.begin(); i != mModDamagePercentDone.end(); ++i) { - if ((*i)->GetSpellInfo()->EquippedItemClass == -1) - AddPctN(DoneTotalMod, (*i)->GetAmount()); - else if (!((*i)->GetSpellInfo()->AttributesEx5 & SPELL_ATTR5_SPECIAL_ITEM_CLASS_CHECK) && ((*i)->GetSpellInfo()->EquippedItemSubClassMask == 0)) - AddPctN(DoneTotalMod, (*i)->GetAmount()); - else if (ToPlayer() && ToPlayer()->HasItemFitToSpellRequirements((*i)->GetSpellInfo())) - AddPctN(DoneTotalMod, (*i)->GetAmount()); + if ((*i)->GetMiscValue() & spellProto->GetSchoolMask() && !(spellProto->GetSchoolMask() & SPELL_SCHOOL_MASK_NORMAL)) + { + if ((*i)->GetSpellInfo()->EquippedItemClass == -1) + AddPctN(DoneTotalMod, (*i)->GetAmount()); + else if (!((*i)->GetSpellInfo()->AttributesEx5 & SPELL_ATTR5_SPECIAL_ITEM_CLASS_CHECK) && ((*i)->GetSpellInfo()->EquippedItemSubClassMask == 0)) + AddPctN(DoneTotalMod, (*i)->GetAmount()); + else if (ToPlayer() && ToPlayer()->HasItemFitToSpellRequirements((*i)->GetSpellInfo())) + AddPctN(DoneTotalMod, (*i)->GetAmount()); + } } } - } AuraEffectList const& mDamageDoneVersus = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_DONE_VERSUS); for (AuraEffectList::const_iterator i = mDamageDoneVersus.begin(); i != mDamageDoneVersus.end(); ++i) @@ -11735,18 +11793,50 @@ void Unit::MeleeDamageBonus(Unit* victim, uint32 *pdamage, WeaponAttackType attT break; } + float tmpDamage = float(int32(pdamage) + DoneFlatBenefit) * DoneTotalMod; + + // apply spellmod to Done damage + if (spellProto) + if (Player* modOwner = GetSpellModOwner()) + modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_DAMAGE, tmpDamage); + + // bonus result can be negative + return uint32(std::max(tmpDamage, 0.0f)); +} + +uint32 Unit::MeleeDamageBonusTaken(Unit* attacker, uint32 pdamage, WeaponAttackType attType, SpellInfo const* spellProto) +{ + if (pdamage == 0) + return 0; + + int32 TakenFlatBenefit = 0; + // ..taken - TakenTotalMod *= victim->GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, GetMeleeDamageSchoolMask()); + AuraEffectList const& mDamageTaken = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_TAKEN); + for (AuraEffectList::const_iterator i = mDamageTaken.begin(); i != mDamageTaken.end(); ++i) + if ((*i)->GetMiscValue() & GetMeleeDamageSchoolMask()) + TakenFlatBenefit += (*i)->GetAmount(); - // From caster spells - AuraEffectList const& mOwnerTaken = victim->GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_FROM_CASTER); - for (AuraEffectList::const_iterator i = mOwnerTaken.begin(); i != mOwnerTaken.end(); ++i) - if ((*i)->GetCasterGUID() == GetGUID() && (*i)->IsAffectedOnSpell(spellProto)) - AddPctN(TakenTotalMod, (*i)->GetAmount()); + if (attType != RANGED_ATTACK) + TakenFlatBenefit += GetTotalAuraModifier(SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN); + else + TakenFlatBenefit += GetTotalAuraModifier(SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN); + + // Taken total percent damage auras + float TakenTotalMod = 1.0f; + + // ..taken + TakenTotalMod *= GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, GetMeleeDamageSchoolMask()); // .. taken pct (special attacks) if (spellProto) { + // From caster spells + AuraEffectList const& mOwnerTaken = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_FROM_CASTER); + for (AuraEffectList::const_iterator i = mOwnerTaken.begin(); i != mOwnerTaken.end(); ++i) + if ((*i)->GetCasterGUID() == attacker->GetGUID() && (*i)->IsAffectedOnSpell(spellProto)) + AddPctN(TakenTotalMod, (*i)->GetAmount()); + // Mod damage from spell mechanic uint32 mechanicMask = spellProto->GetAllEffectsMechanicMask(); @@ -11756,7 +11846,7 @@ void Unit::MeleeDamageBonus(Unit* victim, uint32 *pdamage, WeaponAttackType attT if (mechanicMask) { - AuraEffectList const& mDamageDoneMechanic = victim->GetAuraEffectsByType(SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT); + AuraEffectList const& mDamageDoneMechanic = GetAuraEffectsByType(SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT); for (AuraEffectList::const_iterator i = mDamageDoneMechanic.begin(); i != mDamageDoneMechanic.end(); ++i) if (mechanicMask & uint32(1<<((*i)->GetMiscValue()))) AddPctN(TakenTotalMod, (*i)->GetAmount()); @@ -11764,7 +11854,7 @@ void Unit::MeleeDamageBonus(Unit* victim, uint32 *pdamage, WeaponAttackType attT } // .. taken pct: dummy auras - AuraEffectList const& mDummyAuras = victim->GetAuraEffectsByType(SPELL_AURA_DUMMY); + AuraEffectList const& mDummyAuras = GetAuraEffectsByType(SPELL_AURA_DUMMY); for (AuraEffectList::const_iterator i = mDummyAuras.begin(); i != mDummyAuras.end(); ++i) { switch ((*i)->GetSpellInfo()->SpellIconID) @@ -11773,9 +11863,9 @@ void Unit::MeleeDamageBonus(Unit* victim, uint32 *pdamage, WeaponAttackType attT case 2109: if ((*i)->GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL) { - if (victim->GetTypeId() != TYPEID_PLAYER) + if (GetTypeId() != TYPEID_PLAYER) continue; - float mod = victim->ToPlayer()->GetRatingBonusValue(CR_CRIT_TAKEN_MELEE) * (-8.0f); + float mod = ToPlayer()->GetRatingBonusValue(CR_CRIT_TAKEN_MELEE) * (-8.0f); AddPctF(TakenTotalMod, std::max(mod, float((*i)->GetAmount()))); } break; @@ -11783,38 +11873,31 @@ void Unit::MeleeDamageBonus(Unit* victim, uint32 *pdamage, WeaponAttackType attT } // .. taken pct: class scripts - /*AuraEffectList const& mclassScritAuras = GetAuraEffectsByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS); - for (AuraEffectList::const_iterator i = mclassScritAuras.begin(); i != mclassScritAuras.end(); ++i) - { - switch ((*i)->GetMiscValue()) - { - } - }*/ + //*AuraEffectList const& mclassScritAuras = GetAuraEffectsByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS); + //for (AuraEffectList::const_iterator i = mclassScritAuras.begin(); i != mclassScritAuras.end(); ++i) + //{ + // switch ((*i)->GetMiscValue()) + // { + // } + //}*/ if (attType != RANGED_ATTACK) { - AuraEffectList const& mModMeleeDamageTakenPercent = victim->GetAuraEffectsByType(SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN_PCT); + AuraEffectList const& mModMeleeDamageTakenPercent = GetAuraEffectsByType(SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN_PCT); for (AuraEffectList::const_iterator i = mModMeleeDamageTakenPercent.begin(); i != mModMeleeDamageTakenPercent.end(); ++i) AddPctN(TakenTotalMod, (*i)->GetAmount()); } else { - AuraEffectList const& mModRangedDamageTakenPercent = victim->GetAuraEffectsByType(SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN_PCT); + AuraEffectList const& mModRangedDamageTakenPercent = GetAuraEffectsByType(SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN_PCT); for (AuraEffectList::const_iterator i = mModRangedDamageTakenPercent.begin(); i != mModRangedDamageTakenPercent.end(); ++i) AddPctN(TakenTotalMod, (*i)->GetAmount()); } - float tmpDamage = float(int32(*pdamage) + DoneFlatBenefit) * DoneTotalMod; - - // apply spellmod to Done damage - if (spellProto) - if (Player* modOwner = GetSpellModOwner()) - modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_DAMAGE, tmpDamage); - - tmpDamage = (tmpDamage + TakenFlatBenefit) * TakenTotalMod; + float tmpDamage = (float(pdamage) + TakenFlatBenefit) * TakenTotalMod; // bonus result can be negative - *pdamage = uint32(std::max(tmpDamage, 0.0f)); + return uint32(std::max(tmpDamage, 0.0f)); } void Unit::ApplySpellImmune(uint32 spellId, uint32 op, uint32 type, bool apply) @@ -12154,7 +12237,7 @@ bool Unit::IsValidAttackTarget(Unit const* target) const } // function based on function Unit::CanAttack from 13850 client -bool Unit::_IsValidAttackTarget(Unit const* target, SpellInfo const* bySpell) const +bool Unit::_IsValidAttackTarget(Unit const* target, SpellInfo const* bySpell, WorldObject const* obj) const { ASSERT(target); @@ -12172,8 +12255,8 @@ bool Unit::_IsValidAttackTarget(Unit const* target, SpellInfo const* bySpell) co if (IsOnVehicle(target) || m_vehicle->GetBase()->IsOnVehicle(target)) return false; - // can't attack invisible (ignore stealth for aoe spells) - if ((!bySpell || !(bySpell->AttributesEx6 & SPELL_ATTR6_CAN_TARGET_INVISIBLE)) && !canSeeOrDetect(target, bySpell && bySpell->IsAffectingArea())) + // can't attack invisible (ignore stealth for aoe spells) also if the area being looked at is from a spell use the dynamic object created instead of the casting unit. + if ((!bySpell || !(bySpell->AttributesEx6 & SPELL_ATTR6_CAN_TARGET_INVISIBLE)) && (obj ? !obj->canSeeOrDetect(target, bySpell && bySpell->IsAffectingArea()) : !canSeeOrDetect(target, bySpell && bySpell->IsAffectingArea()))) return false; // can't attack dead @@ -12465,6 +12548,12 @@ bool Unit::IsAlwaysVisibleFor(WorldObject const* seer) const if (seer->GetGUID() == guid) return true; + if (Player const* seerPlayer = seer->ToPlayer()) + if (Unit* owner = GetOwner()) + if (Player* ownerPlayer = owner->ToPlayer()) + if (ownerPlayer->IsGroupVisibleFor(seerPlayer)) + return true; + return false; } @@ -12728,11 +12817,7 @@ void Unit::SetSpeed(UnitMoveType mtype, float rate, bool forced) void Unit::setDeathState(DeathState s) { - // death state needs to be updated before RemoveAllAurasOnDeath() calls HandleChannelDeathItem(..) so that - // it can be used to check creation of death items (such as soul shards). - m_deathState = s; - - if (s != ALIVE && s != JUST_ALIVED) + if (s != ALIVE && s != JUST_RESPAWNED) { CombatStop(); DeleteThreatList(); @@ -12754,8 +12839,16 @@ void Unit::setDeathState(DeathState s) // remove aurastates allowing special moves ClearAllReactives(); ClearDiminishings(); - GetMotionMaster()->Clear(false); - GetMotionMaster()->MoveIdle(); + if (IsInWorld()) + { + // Only clear MotionMaster for entities that exists in world + // Avoids crashes in the following conditions : + // * Using 'call pet' on dead pets + // * Using 'call stabled pet' + // * Logging in with dead pets + GetMotionMaster()->Clear(false); + GetMotionMaster()->MoveIdle(); + } StopMoving(); DisableSpline(); // without this when removing IncreaseMaxHealth aura player may stuck with 1 hp @@ -12767,8 +12860,10 @@ void Unit::setDeathState(DeathState s) if (ZoneScript* zoneScript = GetZoneScript() ? GetZoneScript() : (ZoneScript*)GetInstanceScript()) zoneScript->OnUnitDeath(this); } - else if (s == JUST_ALIVED) - RemoveFlag (UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE); // clear skinnable for creature and player (at battleground) + else if (s == JUST_RESPAWNED) + RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE); // clear skinnable for creature and player (at battleground) + + m_deathState = s; } /*######################################## @@ -14381,7 +14476,8 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: doing %u damage from spell id %u (triggered by %s aura of spell %u)", triggeredByAura->GetAmount(), spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId()); SpellNonMeleeDamage damageInfo(this, target, spellInfo->Id, spellInfo->SchoolMask); - uint32 newDamage = SpellDamageBonus(target, spellInfo, triggeredByAura->GetAmount(), SPELL_DIRECT_DAMAGE); + uint32 newDamage = SpellDamageBonusDone(target, spellInfo, triggeredByAura->GetAmount(), SPELL_DIRECT_DAMAGE); + newDamage = target->SpellDamageBonusTaken(this, spellInfo, newDamage, SPELL_DIRECT_DAMAGE); CalculateSpellDamageTaken(&damageInfo, newDamage, spellInfo); DealDamageMods(damageInfo.target, damageInfo.damage, &damageInfo.absorb); SendSpellNonMeleeDamageLog(&damageInfo); @@ -14881,7 +14977,7 @@ Unit* Unit::SelectNearbyTarget(Unit* exclude, float dist) const return NULL; // select random - return SelectRandomContainerElement(targets); + return Trinity::Containers::SelectRandomContainerElement(targets); } void Unit::ApplyAttackTimePercentMod(WeaponAttackType att, float val, bool apply) @@ -14908,7 +15004,7 @@ void Unit::ApplyCastTimePercentMod(float val, bool apply) ApplyPercentModFloatValue(UNIT_MOD_CAST_SPEED, -val, apply); } -uint32 Unit::GetCastingTimeForBonus(SpellInfo const* spellProto, DamageEffectType damagetype, uint32 CastingTime) +uint32 Unit::GetCastingTimeForBonus(SpellInfo const* spellProto, DamageEffectType damagetype, uint32 CastingTime) const { // Not apply this to creature casted spells with casttime == 0 if (CastingTime == 0 && GetTypeId() == TYPEID_UNIT && !ToCreature()->isPet()) @@ -14981,20 +15077,21 @@ uint32 Unit::GetCastingTimeForBonus(SpellInfo const* spellProto, DamageEffectTyp if (AreaEffect) CastingTime /= 2; - // -5% of total per any additional effect - for (uint8 i = 0; i < effects; ++i) + // 50% for damage and healing spells for leech spells from damage bonus and 0% from healing + for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j) { - if (CastingTime > 175) - { - CastingTime -= 175; - } - else + if (spellProto->Effects[j].Effect == SPELL_EFFECT_HEALTH_LEECH || + (spellProto->Effects[j].Effect == SPELL_EFFECT_APPLY_AURA && spellProto->Effects[j].ApplyAuraName == SPELL_AURA_PERIODIC_LEECH)) { - CastingTime = 0; + CastingTime /= 2; break; } } + // -5% of total per any additional effect + for (uint8 i = 0; i < effects; ++i) + CastingTime *= 0.95f; + return CastingTime; } @@ -15025,6 +15122,29 @@ void Unit::UpdateAuraForGroup(uint8 slot) } } +float Unit::CalculateDefaultCoefficient(SpellInfo const *spellInfo, DamageEffectType damagetype) const +{ + // Damage over Time spells bonus calculation + float DotFactor = 1.0f; + if (damagetype == DOT) + { + + int32 DotDuration = spellInfo->GetDuration(); + if (!spellInfo->IsChanneled() && DotDuration > 0) + DotFactor = DotDuration / 15000.0f; + + if (uint32 DotTicks = spellInfo->GetMaxTicks()) + DotFactor /= DotTicks; + } + + int32 CastingTime = spellInfo->IsChanneled() ? spellInfo->GetDuration() : spellInfo->CalcCastTime(); + // Distribute Damage over multiple effects, reduce by AoE + CastingTime = GetCastingTimeForBonus(spellInfo, damagetype, CastingTime); + + // As wowwiki says: C = (Cast Time / 3.5) + return (CastingTime / 3500.0f) * DotFactor; +} + float Unit::GetAPMultiplier(WeaponAttackType attType, bool normalized) { if (!normalized || GetTypeId() != TYPEID_PLAYER) @@ -16898,7 +17018,7 @@ bool Unit::HandleSpellClick(Unit* clicker, int8 seatId) } if (IsInMap(caster)) - caster->CastCustomSpell(itr->second.spellId, SpellValueMod(SPELLVALUE_BASE_POINT0+i), seatId+1, target, true, NULL, NULL, origCasterGUID); + caster->CastCustomSpell(itr->second.spellId, SpellValueMod(SPELLVALUE_BASE_POINT0+i), seatId+1, target, false, NULL, NULL, origCasterGUID); else // This can happen during Player::_LoadAuras { int32 bp0 = seatId; @@ -16908,7 +17028,7 @@ bool Unit::HandleSpellClick(Unit* clicker, int8 seatId) else { if (IsInMap(caster)) - caster->CastSpell(target, spellEntry, true, NULL, NULL, origCasterGUID); + caster->CastSpell(target, spellEntry, false, NULL, NULL, origCasterGUID); else Aura::TryRefreshStackOrCreate(spellEntry, MAX_EFFECT_MASK, this, clicker, NULL, NULL, origCasterGUID); } @@ -17178,6 +17298,9 @@ bool Unit::UpdatePosition(float x, float y, float z, float orientation, bool tel else if (turn) UpdateOrientation(orientation); + // code block for underwater state update + UpdateUnderwaterState(GetMap(), x, y, z); + return (relocated || turn); } @@ -17482,7 +17605,7 @@ bool Unit::SetWalk(bool enable) return true; } -bool Unit::SetDisableGravity(bool disable) +bool Unit::SetDisableGravity(bool disable, bool /*packetOnly = false*/) { if (disable == IsLevitating()) return false; @@ -17523,26 +17646,35 @@ bool Unit::SetHover(bool enable) void Unit::SendMovementHover() { + if (GetTypeId() == TYPEID_PLAYER) + ToPlayer()->SendMovementSetHover(HasUnitMovementFlag(MOVEMENTFLAG_HOVER)); + WorldPacket data(MSG_MOVE_HOVER, 64); data.append(GetPackGUID()); BuildMovementPacket(&data); - SendMessageToSet(&data, true); + SendMessageToSet(&data, false); } void Unit::SendMovementWaterWalking() { + if (GetTypeId() == TYPEID_PLAYER) + ToPlayer()->SendMovementSetWaterWalking(HasUnitMovementFlag(MOVEMENTFLAG_WATERWALKING)); + WorldPacket data(MSG_MOVE_WATER_WALK, 64); data.append(GetPackGUID()); BuildMovementPacket(&data); - SendMessageToSet(&data, true); + SendMessageToSet(&data, false); } void Unit::SendMovementFeatherFall() { + if (GetTypeId() == TYPEID_PLAYER) + ToPlayer()->SendMovementSetFeatherFall(HasUnitMovementFlag(MOVEMENTFLAG_FALLING_SLOW)); + WorldPacket data(MSG_MOVE_FEATHER_FALL, 64); data.append(GetPackGUID()); BuildMovementPacket(&data); - SendMessageToSet(&data, true); + SendMessageToSet(&data, false); } void Unit::SendMovementGravityChange() @@ -17550,7 +17682,7 @@ void Unit::SendMovementGravityChange() WorldPacket data(MSG_MOVE_GRAVITY_CHNG, 64); data.append(GetPackGUID()); BuildMovementPacket(&data); - SendMessageToSet(&data, true); + SendMessageToSet(&data, false); } void Unit::SendMovementCanFlyChange() @@ -17575,5 +17707,5 @@ void Unit::SendMovementCanFlyChange() WorldPacket data(MSG_MOVE_UPDATE_CAN_FLY, 64); data.append(GetPackGUID()); BuildMovementPacket(&data); - SendMessageToSet(&data, true); + SendMessageToSet(&data, false); } diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index fcbe1afa389..f246f595dec 100755 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -465,7 +465,7 @@ enum DeathState JUST_DIED = 1, CORPSE = 2, DEAD = 3, - JUST_ALIVED = 4, + JUST_RESPAWNED = 4, }; enum UnitState @@ -707,6 +707,9 @@ enum MovementFlags MOVEMENTFLAG_MASK_TURNING = MOVEMENTFLAG_LEFT | MOVEMENTFLAG_RIGHT, + MOVEMENTFLAG_MASK_MOVING_FLY = + MOVEMENTFLAG_FLYING | MOVEMENTFLAG_ASCENDING | MOVEMENTFLAG_DESCENDING, + //! TODO if needed: add more flags to this masks that are exclusive to players MOVEMENTFLAG_MASK_PLAYER_ONLY = MOVEMENTFLAG_FLYING, @@ -1570,13 +1573,14 @@ class Unit : public WorldObject bool isTargetableForAttack(bool checkFakeDeath = true) const; bool IsValidAttackTarget(Unit const* target) const; - bool _IsValidAttackTarget(Unit const* target, SpellInfo const* bySpell) const; + bool _IsValidAttackTarget(Unit const* target, SpellInfo const* bySpell, WorldObject const* obj = NULL) const; bool IsValidAssistTarget(Unit const* target) const; bool _IsValidAssistTarget(Unit const* target, SpellInfo const* bySpell) const; virtual bool IsInWater() const; virtual bool IsUnderWater() const; + virtual void UpdateUnderwaterState(Map* m, float x, float y, float z); bool isInAccessiblePlaceFor(Creature const* c) const; void SendHealSpellLog(Unit* victim, uint32 SpellID, uint32 Damage, uint32 OverHeal, uint32 Absorb, bool critical = false); @@ -1644,7 +1648,7 @@ class Unit : public WorldObject bool IsLevitating() const { return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY);} bool IsWalking() const { return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_WALKING);} virtual bool SetWalk(bool enable); - virtual bool SetDisableGravity(bool disable); + virtual bool SetDisableGravity(bool disable, bool packetOnly = false); bool SetHover(bool enable); void SetInFront(Unit const* target); @@ -2030,12 +2034,20 @@ class Unit : public WorldObject void UnsummonAllTotems(); Unit* GetMagicHitRedirectTarget(Unit* victim, SpellInfo const* spellInfo); Unit* GetMeleeHitRedirectTarget(Unit* victim, SpellInfo const* spellInfo = NULL); - int32 SpellBaseDamageBonus(SpellSchoolMask schoolMask); - int32 SpellBaseHealingBonus(SpellSchoolMask schoolMask); - int32 SpellBaseDamageBonusForVictim(SpellSchoolMask schoolMask, Unit* victim); - int32 SpellBaseHealingBonusForVictim(SpellSchoolMask schoolMask, Unit* victim); - uint32 SpellDamageBonus(Unit* victim, SpellInfo const* spellProto, uint32 damage, DamageEffectType damagetype, uint32 stack = 1); - uint32 SpellHealingBonus(Unit* victim, SpellInfo const* spellProto, uint32 healamount, DamageEffectType damagetype, uint32 stack = 1); + + int32 SpellBaseDamageBonusDone(SpellSchoolMask schoolMask); + int32 SpellBaseDamageBonusTaken(SpellSchoolMask schoolMask); + uint32 SpellDamageBonusDone(Unit* victim, SpellInfo const *spellProto, uint32 pdamage, DamageEffectType damagetype, uint32 stack = 1); + uint32 SpellDamageBonusTaken(Unit* caster, SpellInfo const *spellProto, uint32 pdamage, DamageEffectType damagetype, uint32 stack = 1); + int32 SpellBaseHealingBonusDone(SpellSchoolMask schoolMask); + int32 SpellBaseHealingBonusTaken(SpellSchoolMask schoolMask); + uint32 SpellHealingBonusDone(Unit* victim, SpellInfo const *spellProto, uint32 healamount, DamageEffectType damagetype, uint32 stack = 1); + uint32 SpellHealingBonusTaken(Unit* caster, SpellInfo const *spellProto, uint32 healamount, DamageEffectType damagetype, uint32 stack = 1); + + uint32 MeleeDamageBonusDone(Unit *pVictim, uint32 damage, WeaponAttackType attType, SpellInfo const *spellProto = NULL); + uint32 MeleeDamageBonusTaken(Unit* attacker, uint32 pdamage,WeaponAttackType attType, SpellInfo const *spellProto = NULL); + + bool isSpellBlocked(Unit* victim, SpellInfo const* spellProto, WeaponAttackType attackType = BASE_ATTACK); bool isBlockCritical(); bool isSpellCrit(Unit* victim, SpellInfo const* spellProto, SpellSchoolMask schoolMask, WeaponAttackType attackType = BASE_ATTACK) const; @@ -2047,8 +2059,8 @@ class Unit : public WorldObject void SetContestedPvP(Player* attackedPlayer = NULL); - void MeleeDamageBonus(Unit* victim, uint32 *damage, WeaponAttackType attType, SpellInfo const* spellProto = NULL); - uint32 GetCastingTimeForBonus(SpellInfo const* spellProto, DamageEffectType damagetype, uint32 CastingTime); + uint32 GetCastingTimeForBonus(SpellInfo const* spellProto, DamageEffectType damagetype, uint32 CastingTime) const; + float CalculateDefaultCoefficient(SpellInfo const *spellInfo, DamageEffectType damagetype) const; uint32 GetRemainingPeriodicAmount(uint64 caster, uint32 spellId, AuraType auraType, uint8 effectIndex = 0) const; @@ -2316,6 +2328,7 @@ class Unit : public WorldObject Vehicle* m_vehicleKit; uint32 m_unitTypeMask; + LiquidTypeEntry const* _lastLiquid; bool IsAlwaysVisibleFor(WorldObject const* seer) const; bool IsAlwaysDetectableFor(WorldObject const* seer) const; diff --git a/src/server/game/Entities/Vehicle/Vehicle.cpp b/src/server/game/Entities/Vehicle/Vehicle.cpp index f3d6e8abc79..c297ce1e792 100755 --- a/src/server/game/Entities/Vehicle/Vehicle.cpp +++ b/src/server/game/Entities/Vehicle/Vehicle.cpp @@ -285,9 +285,6 @@ void Vehicle::InstallAccessory(uint32 entry, int8 seatId, bool minion, uint8 typ // return; // Something went wrong in the spellsystem //} - // This is not good, we have to send update twice - accessory->SendMovementFlagUpdate(); - if (GetBase()->GetTypeId() == TYPEID_UNIT) sScriptMgr->OnInstallAccessory(this, accessory); } @@ -352,6 +349,7 @@ bool Vehicle::AddPassenger(Unit* unit, int8 seatId) unit->m_movementInfo.t_pos.m_orientation = 0; unit->m_movementInfo.t_time = 0; // 1 for player unit->m_movementInfo.t_seat = seat->first; + unit->m_movementInfo.t_guid = _me->GetGUID(); if (_me->GetTypeId() == TYPEID_UNIT && unit->GetTypeId() == TYPEID_PLAYER @@ -453,11 +451,12 @@ void Vehicle::RelocatePassengers(float x, float y, float z, float ang) void Vehicle::Dismiss() { + if (GetBase()->GetTypeId() != TYPEID_UNIT) + return; + sLog->outDebug(LOG_FILTER_VEHICLES, "Vehicle::Dismiss Entry: %u, GuidLow %u", _creatureEntry, _me->GetGUIDLow()); Uninstall(); - _me->DestroyForNearbyPlayers(); - _me->CombatStop(); - _me->AddObjectToRemoveList(); + GetBase()->ToCreature()->DespawnOrUnsummon(); } void Vehicle::InitMovementInfoForBase() diff --git a/src/server/game/Events/GameEventMgr.cpp b/src/server/game/Events/GameEventMgr.cpp index a8492726e75..d5e85d2cf2f 100755 --- a/src/server/game/Events/GameEventMgr.cpp +++ b/src/server/game/Events/GameEventMgr.cpp @@ -1124,8 +1124,6 @@ void GameEventMgr::UnApplyEvent(uint16 event_id) UpdateEventNPCVendor(event_id, false); // update bg holiday UpdateBattlegroundSettings(); - // check for seasonal quest reset. - sWorld->ResetEventSeasonalQuests(event_id); } void GameEventMgr::ApplyNewEvent(uint16 event_id) @@ -1160,6 +1158,8 @@ void GameEventMgr::ApplyNewEvent(uint16 event_id) UpdateEventNPCVendor(event_id, true); // update bg holiday UpdateBattlegroundSettings(); + // check for seasonal quest reset. + sWorld->ResetEventSeasonalQuests(event_id); } void GameEventMgr::UpdateEventNPCFlags(uint16 event_id) diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index bf647fa5c31..1e36b4c732b 100755 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -5337,15 +5337,15 @@ void ObjectMgr::ReturnOrDeleteOldMails(bool serverUp) { Field* fields = result->Fetch(); Mail* m = new Mail; - m->messageID = fields[0].GetUInt32(); - m->messageType = fields[1].GetUInt8(); - m->sender = fields[2].GetUInt32(); - m->receiver = fields[3].GetUInt32(); - bool has_items = fields[4].GetBool(); - m->expire_time = time_t(fields[5].GetUInt32()); - m->deliver_time = 0; - m->COD = fields[6].GetUInt32(); - m->checked = fields[7].GetUInt32(); + m->messageID = fields[0].GetUInt32(); + m->messageType = fields[1].GetUInt8(); + m->sender = fields[2].GetUInt32(); + m->receiver = fields[3].GetUInt32(); + bool has_items = fields[4].GetBool(); + m->expire_time = time_t(fields[5].GetUInt32()); + m->deliver_time = 0; + m->COD = fields[6].GetUInt32(); + m->checked = fields[7].GetUInt8(); m->mailTemplateId = fields[8].GetInt16(); Player* player = NULL; @@ -5382,8 +5382,8 @@ void ObjectMgr::ReturnOrDeleteOldMails(bool serverUp) stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_MAIL_RETURNED); stmt->setUInt32(0, m->receiver); stmt->setUInt32(1, m->sender); - stmt->setUInt64(2, basetime + 30 * DAY); - stmt->setUInt64(3, basetime); + stmt->setUInt32(2, basetime + 30 * DAY); + stmt->setUInt32(3, basetime); stmt->setUInt8 (4, uint8(MAIL_CHECK_MASK_RETURNED)); stmt->setUInt32(5, m->messageID); CharacterDatabase.Execute(stmt); @@ -6247,74 +6247,54 @@ uint32 ObjectMgr::GenerateLowGuid(HighGuid guidhigh) switch (guidhigh) { case HIGHGUID_ITEM: - if (_hiItemGuid >= 0xFFFFFFFE) - { - sLog->outError("Item guid overflow!! Can't continue, shutting down server. "); - World::StopNow(ERROR_EXIT_CODE); - } + { + ASSERT(_hiItemGuid < 0xFFFFFFFE && "Item guid overflow!"); return _hiItemGuid++; + } case HIGHGUID_UNIT: - if (_hiCreatureGuid >= 0x00FFFFFE) - { - sLog->outError("Creature guid overflow!! Can't continue, shutting down server. "); - World::StopNow(ERROR_EXIT_CODE); - } + { + ASSERT(_hiCreatureGuid < 0x00FFFFFE && "Creature guid overflow!"); return _hiCreatureGuid++; + } case HIGHGUID_PET: - if (_hiPetGuid >= 0x00FFFFFE) - { - sLog->outError("Pet guid overflow!! Can't continue, shutting down server. "); - World::StopNow(ERROR_EXIT_CODE); - } + { + ASSERT(_hiPetGuid < 0x00FFFFFE && "Pet guid overflow!"); return _hiPetGuid++; + } case HIGHGUID_VEHICLE: - if (_hiVehicleGuid >= 0x00FFFFFF) - { - sLog->outError("Vehicle guid overflow!! Can't continue, shutting down server. "); - World::StopNow(ERROR_EXIT_CODE); - } + { + ASSERT(_hiVehicleGuid < 0x00FFFFFF && "Vehicle guid overflow!"); return _hiVehicleGuid++; + } case HIGHGUID_PLAYER: - if (_hiCharGuid >= 0xFFFFFFFE) - { - sLog->outError("Players guid overflow!! Can't continue, shutting down server. "); - World::StopNow(ERROR_EXIT_CODE); - } + { + ASSERT(_hiCharGuid < 0xFFFFFFFE && "Player guid overflow!"); return _hiCharGuid++; + } case HIGHGUID_GAMEOBJECT: - if (_hiGoGuid >= 0x00FFFFFE) - { - sLog->outError("Gameobject guid overflow!! Can't continue, shutting down server. "); - World::StopNow(ERROR_EXIT_CODE); - } + { + ASSERT(_hiGoGuid < 0x00FFFFFE && "Gameobject guid overflow!"); return _hiGoGuid++; + } case HIGHGUID_CORPSE: - if (_hiCorpseGuid >= 0xFFFFFFFE) - { - sLog->outError("Corpse guid overflow!! Can't continue, shutting down server. "); - World::StopNow(ERROR_EXIT_CODE); - } + { + ASSERT(_hiCorpseGuid < 0xFFFFFFFE && "Corpse guid overflow!"); return _hiCorpseGuid++; + } case HIGHGUID_DYNAMICOBJECT: - if (_hiDoGuid >= 0xFFFFFFFE) - { - sLog->outError("DynamicObject guid overflow!! Can't continue, shutting down server. "); - World::StopNow(ERROR_EXIT_CODE); - } + { + ASSERT(_hiDoGuid < 0xFFFFFFFE && "DynamicObject guid overflow!"); return _hiDoGuid++; + } case HIGHGUID_MO_TRANSPORT: - if (_hiMoTransGuid >= 0xFFFFFFFE) - { - sLog->outError("MO Transport guid overflow!! Can't continue, shutting down server. "); - World::StopNow(ERROR_EXIT_CODE); - } + { + ASSERT(_hiMoTransGuid < 0xFFFFFFFE && "MO Transport guid overflow!"); return _hiMoTransGuid++; + } default: - ASSERT(0); + ASSERT(false && "ObjectMgr::GenerateLowGuid - Unknown HIGHGUID type"); + return 0; } - - ASSERT(0); - return 0; } void ObjectMgr::LoadGameObjectLocales() @@ -7203,7 +7183,7 @@ void ObjectMgr::SaveCreatureRespawnTime(uint32 loguid, uint32 instance, time_t t PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_CREATURE_RESPAWN); stmt->setUInt32(0, loguid); - stmt->setUInt64(1, uint64(t)); + stmt->setUInt32(1, uint32(t)); stmt->setUInt32(2, instance); CharacterDatabase.Execute(stmt); } @@ -7217,7 +7197,7 @@ void ObjectMgr::RemoveCreatureRespawnTime(uint32 loguid, uint32 instance) _creatureRespawnTimesMutex.release(); } - PreparedStatement *stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CREATURE_RESPAWN); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CREATURE_RESPAWN); stmt->setUInt32(0, loguid); stmt->setUInt32(1, instance); CharacterDatabase.Execute(stmt); diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index 0f2b2382007..f81e7f1f074 100755 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -1025,15 +1025,6 @@ class ObjectMgr return &itr->second; } - bool IsGoOfSpecificEntrySpawned(uint32 entry) const - { - for (GameObjectDataContainer::const_iterator it = _gameObjectDataStore.begin(); it != _gameObjectDataStore.end(); ++it) - if (it->second.id == entry) - return true; - - return false; - } - GameObjectData const* GetGOData(uint32 guid) const { GameObjectDataContainer::const_iterator itr = _gameObjectDataStore.find(guid); diff --git a/src/server/game/Grids/GridStates.h b/src/server/game/Grids/GridStates.h index 08b66f6bb35..cf649f8d896 100755 --- a/src/server/game/Grids/GridStates.h +++ b/src/server/game/Grids/GridStates.h @@ -40,6 +40,7 @@ class GridState void setMagic() { i_Magic = MAGIC_TESTVAL; } unsigned int i_Magic; #endif + virtual ~GridState() {}; virtual void Update(Map &, NGridType&, GridInfo &, const uint32 t_diff) const = 0; }; diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.h b/src/server/game/Grids/Notifiers/GridNotifiers.h index bb2a9c5130b..7bb4492f99c 100755 --- a/src/server/game/Grids/Notifiers/GridNotifiers.h +++ b/src/server/game/Grids/Notifiers/GridNotifiers.h @@ -797,7 +797,7 @@ namespace Trinity if (u->GetTypeId() == TYPEID_UNIT && ((Creature*)u)->isTotem()) return false; - if(!u->isTargetableForAttack(false)) + if (!u->isTargetableForAttack(false)) return false; return i_obj->IsWithinDistInMap(u, i_range) && !i_funit->IsFriendlyTo(u); @@ -943,7 +943,7 @@ namespace Trinity if (u->GetTypeId() == TYPEID_UNIT && ((Creature*)u)->isTotem()) return false; - if (i_funit->_IsValidAttackTarget(u, _spellInfo) && i_obj->IsWithinDistInMap(u, i_range)) + if (i_funit->_IsValidAttackTarget(u, _spellInfo,i_obj->GetTypeId() == TYPEID_DYNAMICOBJECT ? i_obj : NULL) && i_obj->IsWithinDistInMap(u, i_range)) return true; return false; @@ -972,7 +972,7 @@ namespace Trinity return; // too far - if (!u->IsWithinDistInMap(i_enemy, i_range)) + if (!u->IsWithinDistInMap(i_funit, i_range)) return; // only if see assisted creature's enemy @@ -1287,7 +1287,7 @@ namespace Trinity AllWorldObjectsInRange(const WorldObject* object, float maxRange) : m_pObject(object), m_fRange(maxRange) {} bool operator() (WorldObject* go) { - return m_pObject->IsWithinDist(go, m_fRange, false); + return m_pObject->IsWithinDist(go, m_fRange, false) && m_pObject->InSamePhase(go); } private: const WorldObject* m_pObject; diff --git a/src/server/game/Grids/Notifiers/GridNotifiersImpl.h b/src/server/game/Grids/Notifiers/GridNotifiersImpl.h index 40b3863679b..e3cda4dd76d 100755 --- a/src/server/game/Grids/Notifiers/GridNotifiersImpl.h +++ b/src/server/game/Grids/Notifiers/GridNotifiersImpl.h @@ -251,9 +251,8 @@ void Trinity::WorldObjectListSearcher<Check>::Visit(PlayerMapType &m) return; for (PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr) - if (itr->getSource()->InSamePhase(i_phaseMask)) - if (i_check(itr->getSource())) - i_objects.push_back(itr->getSource()); + if (i_check(itr->getSource())) + i_objects.push_back(itr->getSource()); } template<class Check> @@ -263,9 +262,8 @@ void Trinity::WorldObjectListSearcher<Check>::Visit(CreatureMapType &m) return; for (CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr) - if (itr->getSource()->InSamePhase(i_phaseMask)) - if (i_check(itr->getSource())) - i_objects.push_back(itr->getSource()); + if (i_check(itr->getSource())) + i_objects.push_back(itr->getSource()); } template<class Check> @@ -275,9 +273,8 @@ void Trinity::WorldObjectListSearcher<Check>::Visit(CorpseMapType &m) return; for (CorpseMapType::iterator itr=m.begin(); itr != m.end(); ++itr) - if (itr->getSource()->InSamePhase(i_phaseMask)) - if (i_check(itr->getSource())) - i_objects.push_back(itr->getSource()); + if (i_check(itr->getSource())) + i_objects.push_back(itr->getSource()); } template<class Check> @@ -287,9 +284,8 @@ void Trinity::WorldObjectListSearcher<Check>::Visit(GameObjectMapType &m) return; for (GameObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr) - if (itr->getSource()->InSamePhase(i_phaseMask)) - if (i_check(itr->getSource())) - i_objects.push_back(itr->getSource()); + if (i_check(itr->getSource())) + i_objects.push_back(itr->getSource()); } template<class Check> @@ -299,9 +295,8 @@ void Trinity::WorldObjectListSearcher<Check>::Visit(DynamicObjectMapType &m) return; for (DynamicObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr) - if (itr->getSource()->InSamePhase(i_phaseMask)) - if (i_check(itr->getSource())) - i_objects.push_back(itr->getSource()); + if (i_check(itr->getSource())) + i_objects.push_back(itr->getSource()); } // Gameobject searchers diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp index 768531b0aea..c7648bf1ccc 100755 --- a/src/server/game/Groups/Group.cpp +++ b/src/server/game/Groups/Group.cpp @@ -2136,7 +2136,7 @@ void Group::SetGroupMemberFlag(uint64 guid, bool apply, GroupMemberFlags flag) PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GROUP_MEMBER_FLAG); stmt->setUInt8(0, slot->flags); - stmt->setUInt32(0, GUID_LOPART(guid)); + stmt->setUInt32(1, GUID_LOPART(guid)); CharacterDatabase.Execute(stmt); diff --git a/src/server/game/Handlers/CalendarHandler.cpp b/src/server/game/Handlers/CalendarHandler.cpp index d1277d154cc..298c742fc3a 100755 --- a/src/server/game/Handlers/CalendarHandler.cpp +++ b/src/server/game/Handlers/CalendarHandler.cpp @@ -20,7 +20,7 @@ ----- Opcodes Not Used yet ----- SMSG_CALENDAR_CLEAR_PENDING_ACTION SendCalendarClearPendingAction() -SMSG_CALENDAR_RAID_LOCKOUT_UPDATED SendCalendarRaidLockoutUpdated(InstanceSave const* save) <--- Structure unknown, using LOCKOUT_ADDED +SMSG_CALENDAR_RAID_LOCKOUT_UPDATED SendCalendarRaidLockoutUpdated(InstanceSave const* save) ----- Opcodes without Sniffs ----- SMSG_CALENDAR_FILTER_GUILD [ for (... uint32(count) { packguid(???), uint8(???) } ] @@ -74,7 +74,11 @@ void WorldSession::HandleCalendarGetCalendar(WorldPacket& /*recvData*/) else { sLog->outError("SMSG_CALENDAR_SEND_CALENDAR: No Invite found with id [" UI64FMTD "]", *it); - data << uint64(0) << uint64(0) << uint8(0) << uint8(0); + data << uint64(0); + data << uint64(0); + data << uint8(0); + data << uint8(0); + data << uint8(0); data.appendPackGUID(0); } } @@ -96,8 +100,12 @@ void WorldSession::HandleCalendarGetCalendar(WorldPacket& /*recvData*/) else { sLog->outError("SMSG_CALENDAR_SEND_CALENDAR: No Event found with id [" UI64FMTD "]", *it); - data << uint64(0) << uint8(0) << uint32(0) - << uint32(0) << uint32(0) << uint32(0); + data << uint64(0); + data << uint8(0); + data << uint32(0); + data << uint32(0); + data << uint32(0); + data << uint32(0); data.appendPackGUID(0); } } @@ -835,26 +843,6 @@ void WorldSession::SendCalendarClearPendingAction() SendPacket(&data); } -void WorldSession::SendCalendarRaidLockoutUpdated(InstanceSave const* save) -{ - if (!save) - return; - - uint64 guid = _player->GetGUID(); - sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_CALENDAR_RAID_LOCKOUT_UPDATED [" UI64FMTD - "] Map: %u, Difficulty %u", guid, save->GetMapId(), save->GetDifficulty()); - - time_t cur_time = time_t(time(NULL)); - - WorldPacket data(SMSG_CALENDAR_RAID_LOCKOUT_UPDATED, 4 + 4 + 4 + 4 + 8); - data << secsToTimeBitFields(cur_time); - data << uint32(save->GetMapId()); - data << uint32(save->GetDifficulty()); - data << uint32(save->GetResetTime() - cur_time); - data << uint64(save->GetInstanceId()); - SendPacket(&data); -} - void WorldSession::SendCalendarCommandResult(CalendarError err, char const* param /*= NULL*/) { uint64 guid = _player->GetGUID(); @@ -898,3 +886,23 @@ void WorldSession::SendCalendarRaidLockout(InstanceSave const* save, bool add) data << uint64(save->GetInstanceId()); SendPacket(&data); } + +void WorldSession::SendCalendarRaidLockoutUpdated(InstanceSave const* save) +{ + if (!save) + return; + + uint64 guid = _player->GetGUID(); + sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_CALENDAR_RAID_LOCKOUT_UPDATED [" UI64FMTD + "] Map: %u, Difficulty %u", guid, save->GetMapId(), save->GetDifficulty()); + + time_t cur_time = time_t(time(NULL)); + + WorldPacket data(SMSG_CALENDAR_RAID_LOCKOUT_UPDATED, 4 + 4 + 4 + 4 + 8); + data << secsToTimeBitFields(cur_time); + data << uint32(save->GetMapId()); + data << uint32(save->GetDifficulty()); + data << uint32(0); // Amount of seconds that has changed to the reset time + data << uint32(save->GetResetTime() - cur_time); + SendPacket(&data); +} diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index 1e54bbe6995..2d70efd3305 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -461,7 +461,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte if (result) { Field* fields = result->Fetch(); - createInfo->CharCount = fields[0].GetUInt8(); + createInfo->CharCount = uint8(fields[0].GetUInt64()); // SQL's COUNT() returns uint64 but it will always be less than uint8.Max if (createInfo->CharCount >= sWorld->getIntConfig(CONFIG_CHARACTERS_PER_REALM)) { @@ -653,8 +653,6 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte LoginDatabase.CommitTransaction(trans); - newChar.CleanupsBeforeDelete(); - WorldPacket data(SMSG_CHAR_CREATE, 1); data << uint8(CHAR_CREATE_SUCCESS); SendPacket(&data); @@ -665,6 +663,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte sScriptMgr->OnPlayerCreate(&newChar); sWorld->AddCharacterNameData(newChar.GetGUIDLow(), std::string(newChar.GetName()), newChar.getGender(), newChar.getRace(), newChar.getClass()); + newChar.CleanupsBeforeDelete(); delete createInfo; _charCreateCallback.Reset(); } diff --git a/src/server/game/Handlers/ItemHandler.cpp b/src/server/game/Handlers/ItemHandler.cpp index 85694dba630..d537fc5b4aa 100755 --- a/src/server/game/Handlers/ItemHandler.cpp +++ b/src/server/game/Handlers/ItemHandler.cpp @@ -1127,9 +1127,9 @@ void WorldSession::HandleWrapItemOpcode(WorldPacket& recv_data) PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_GIFT); stmt->setUInt32(0, GUID_LOPART(item->GetOwnerGUID())); - stmt->setUInt32(0, item->GetGUIDLow()); - stmt->setUInt32(0, item->GetEntry()); - stmt->setUInt32(0, item->GetUInt32Value(ITEM_FIELD_FLAGS)); + stmt->setUInt32(1, item->GetGUIDLow()); + stmt->setUInt32(2, item->GetEntry()); + stmt->setUInt32(3, item->GetUInt32Value(ITEM_FIELD_FLAGS)); trans->Append(stmt); item->SetEntry(gift->GetEntry()); diff --git a/src/server/game/Handlers/LFGHandler.cpp b/src/server/game/Handlers/LFGHandler.cpp index aea7499aaa9..aa6d208ad3a 100755 --- a/src/server/game/Handlers/LFGHandler.cpp +++ b/src/server/game/Handlers/LFGHandler.cpp @@ -525,9 +525,9 @@ void WorldSession::SendLfgBootPlayer(const LfgPlayerBoot* pBoot) ++agreeNum; } } - sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_LFG_BOOT_PLAYER [" UI64FMTD "] inProgress: %u - didVote: %u - agree: %u - victim: [" UI64FMTD "] votes: %u - agrees: %u - left: %u - needed: %u - reason %s", + sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_LFG_BOOT_PROPOSAL_UPDATE [" UI64FMTD "] inProgress: %u - didVote: %u - agree: %u - victim: [" UI64FMTD "] votes: %u - agrees: %u - left: %u - needed: %u - reason %s", guid, uint8(pBoot->inProgress), uint8(playerVote != LFG_ANSWER_PENDING), uint8(playerVote == LFG_ANSWER_AGREE), pBoot->victim, votesNum, agreeNum, secsleft, pBoot->votedNeeded, pBoot->reason.c_str()); - WorldPacket data(SMSG_LFG_BOOT_PLAYER, 1 + 1 + 1 + 8 + 4 + 4 + 4 + 4 + pBoot->reason.length()); + WorldPacket data(SMSG_LFG_BOOT_PROPOSAL_UPDATE, 1 + 1 + 1 + 8 + 4 + 4 + 4 + 4 + pBoot->reason.length()); data << uint8(pBoot->inProgress); // Vote in progress data << uint8(playerVote != LFG_ANSWER_PENDING); // Did Vote data << uint8(playerVote == LFG_ANSWER_AGREE); // Agree diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index 35872f8c63f..a280bc30b7c 100755 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -51,6 +51,7 @@ #include "GameObjectAI.h" #include "Group.h" #include "AccountMgr.h" +#include "Spell.h" void WorldSession::HandleRepopRequestOpcode(WorldPacket & recv_data) { @@ -1714,3 +1715,47 @@ void WorldSession::HandleInstanceLockResponse(WorldPacket& recvPacket) _player->SetPendingBind(0, 0); } + +void WorldSession::HandleUpdateMissileTrajectory(WorldPacket& recvPacket) +{ + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_UPDATE_MISSILE_TRAJECTORY"); + + uint64 guid; + uint32 spellId; + float elevation, speed; + float curX, curY, curZ; + float targetX, targetY, targetZ; + uint8 moveStop; + + recvPacket >> guid >> spellId >> elevation >> speed; + recvPacket >> curX >> curY >> curZ; + recvPacket >> targetX >> targetY >> targetZ; + recvPacket >> moveStop; + + Unit* caster = ObjectAccessor::GetUnit(*_player, guid); + Spell* spell = caster ? caster->GetCurrentSpell(CURRENT_GENERIC_SPELL) : NULL; + if (!spell || spell->m_spellInfo->Id != spellId || !spell->m_targets.HasDst() || !spell->m_targets.HasSrc()) + { + recvPacket.rfinish(); + return; + } + + Position pos = *spell->m_targets.GetSrcPos(); + pos.Relocate(curX, curY, curZ); + spell->m_targets.ModSrc(pos); + + pos = *spell->m_targets.GetDstPos(); + pos.Relocate(targetX, targetY, targetZ); + spell->m_targets.ModDst(pos); + + spell->m_targets.SetElevation(elevation); + spell->m_targets.SetSpeed(speed); + + if (moveStop) + { + uint32 opcode; + recvPacket >> opcode; + recvPacket.SetOpcode(opcode); + HandleMovementOpcodes(recvPacket); + } +} diff --git a/src/server/game/Handlers/MovementHandler.cpp b/src/server/game/Handlers/MovementHandler.cpp index f1217e58b3f..c271a43462a 100755 --- a/src/server/game/Handlers/MovementHandler.cpp +++ b/src/server/game/Handlers/MovementHandler.cpp @@ -46,7 +46,7 @@ void WorldSession::HandleMoveWorldportAckOpcode() GetPlayer()->SetSemaphoreTeleportFar(false); // get the teleport destination - WorldLocation &loc = GetPlayer()->GetTeleportDest(); + WorldLocation const loc = GetPlayer()->GetTeleportDest(); // possible errors in the coordinate validity check if (!MapManager::IsValidMapCoord(loc)) @@ -64,10 +64,9 @@ void WorldSession::HandleMoveWorldportAckOpcode() GetPlayer()->m_InstanceValid = true; Map* oldMap = GetPlayer()->GetMap(); - ASSERT(oldMap); if (GetPlayer()->IsInWorld()) { - sLog->outCrash("Player (Name %s) is still in world when teleported from map %u to new map %u", GetPlayer()->GetName(), oldMap->GetId(), loc.GetMapId()); + sLog->outError("Player (Name %s) is still in world when teleported from map %u to new map %u", GetPlayer()->GetName(), oldMap->GetId(), loc.GetMapId()); oldMap->RemovePlayerFromMap(GetPlayer(), false); } @@ -200,8 +199,7 @@ void WorldSession::HandleMoveTeleportAck(WorldPacket& recv_data) sLog->outStaticDebug("Guid " UI64FMTD, guid); sLog->outStaticDebug("Flags %u, time %u", flags, time/IN_MILLISECONDS); - Unit* mover = _player->m_mover; - Player* plMover = mover->GetTypeId() == TYPEID_PLAYER ? (Player*)mover : NULL; + Player* plMover = _player->m_mover->ToPlayer(); if (!plMover || !plMover->IsBeingTeleportedNear()) return; @@ -240,33 +238,33 @@ void WorldSession::HandleMoveTeleportAck(WorldPacket& recv_data) GetPlayer()->ProcessDelayedOperations(); } -void WorldSession::HandleMovementOpcodes(WorldPacket & recv_data) +void WorldSession::HandleMovementOpcodes(WorldPacket & recvData) { - uint16 opcode = recv_data.GetOpcode(); + uint16 opcode = recvData.GetOpcode(); Unit* mover = _player->m_mover; - ASSERT(mover != NULL); // there must always be a mover + ASSERT(mover != NULL); // there must always be a mover - Player* plMover = mover->GetTypeId() == TYPEID_PLAYER ? (Player*)mover : NULL; + Player* plrMover = mover->ToPlayer(); // ignore, waiting processing in WorldSession::HandleMoveWorldportAckOpcode and WorldSession::HandleMoveTeleportAck - if (plMover && plMover->IsBeingTeleported()) + if (plrMover && plrMover->IsBeingTeleported()) { - recv_data.rfinish(); // prevent warnings spam + recvData.rfinish(); // prevent warnings spam return; } /* extract packet */ uint64 guid; - recv_data.readPackGUID(guid); + recvData.readPackGUID(guid); MovementInfo movementInfo; movementInfo.guid = guid; - ReadMovementInfo(recv_data, &movementInfo); + ReadMovementInfo(recvData, &movementInfo); - recv_data.rfinish(); // prevent warnings spam + recvData.rfinish(); // prevent warnings spam // prevent tampered movement data if (guid != mover->GetGUID()) @@ -274,7 +272,7 @@ void WorldSession::HandleMovementOpcodes(WorldPacket & recv_data) if (!movementInfo.pos.IsPositionValid()) { - recv_data.rfinish(); // prevent warnings spam + recvData.rfinish(); // prevent warnings spam return; } @@ -285,27 +283,27 @@ void WorldSession::HandleMovementOpcodes(WorldPacket & recv_data) // (also received at zeppelin leave by some reason with t_* as absolute in continent coordinates, can be safely skipped) if (movementInfo.t_pos.GetPositionX() > 50 || movementInfo.t_pos.GetPositionY() > 50 || movementInfo.t_pos.GetPositionZ() > 50) { - recv_data.rfinish(); // prevent warnings spam + recvData.rfinish(); // prevent warnings spam return; } if (!Trinity::IsValidMapCoord(movementInfo.pos.GetPositionX() + movementInfo.t_pos.GetPositionX(), movementInfo.pos.GetPositionY() + movementInfo.t_pos.GetPositionY(), movementInfo.pos.GetPositionZ() + movementInfo.t_pos.GetPositionZ(), movementInfo.pos.GetOrientation() + movementInfo.t_pos.GetOrientation())) { - recv_data.rfinish(); // prevent warnings spam + recvData.rfinish(); // prevent warnings spam return; } // if we boarded a transport, add us to it - if (plMover && !plMover->GetTransport()) + if (plrMover && !plrMover->GetTransport()) { // elevators also cause the client to send MOVEMENTFLAG_ONTRANSPORT - just dismount if the guid can be found in the transport list for (MapManager::TransportSet::const_iterator iter = sMapMgr->m_Transports.begin(); iter != sMapMgr->m_Transports.end(); ++iter) { if ((*iter)->GetGUID() == movementInfo.t_guid) { - plMover->m_transport = (*iter); - (*iter)->AddPassenger(plMover); + plrMover->m_transport = (*iter); + (*iter)->AddPassenger(plrMover); break; } } @@ -318,29 +316,29 @@ void WorldSession::HandleMovementOpcodes(WorldPacket & recv_data) movementInfo.flags &= ~MOVEMENTFLAG_ONTRANSPORT; } } - else if (plMover && plMover->GetTransport()) // if we were on a transport, leave + else if (plrMover && plrMover->GetTransport()) // if we were on a transport, leave { - plMover->m_transport->RemovePassenger(plMover); - plMover->m_transport = NULL; + plrMover->m_transport->RemovePassenger(plrMover); + plrMover->m_transport = NULL; movementInfo.t_pos.Relocate(0.0f, 0.0f, 0.0f, 0.0f); movementInfo.t_time = 0; movementInfo.t_seat = -1; } // fall damage generation (ignore in flight case that can be triggered also at lags in moment teleportation to another map). - if (opcode == MSG_MOVE_FALL_LAND && plMover && !plMover->isInFlight()) - plMover->HandleFall(movementInfo); + if (opcode == MSG_MOVE_FALL_LAND && plrMover && !plrMover->isInFlight()) + plrMover->HandleFall(movementInfo); - if (plMover && ((movementInfo.flags & MOVEMENTFLAG_SWIMMING) != 0) != plMover->IsInWater()) + if (plrMover && ((movementInfo.flags & MOVEMENTFLAG_SWIMMING) != 0) != plrMover->IsInWater()) { // now client not include swimming flag in case jumping under water - plMover->SetInWater(!plMover->IsInWater() || plMover->GetBaseMap()->IsUnderWater(movementInfo.pos.GetPositionX(), movementInfo.pos.GetPositionY(), movementInfo.pos.GetPositionZ())); + plrMover->SetInWater(!plrMover->IsInWater() || plrMover->GetBaseMap()->IsUnderWater(movementInfo.pos.GetPositionX(), movementInfo.pos.GetPositionY(), movementInfo.pos.GetPositionZ())); } /*----------------------*/ /* process position-change */ - WorldPacket data(opcode, recv_data.size()); + WorldPacket data(opcode, recvData.size()); movementInfo.time = getMSTime(); movementInfo.guid = mover->GetGUID(); WriteMovementInfo(&data, &movementInfo); @@ -357,27 +355,25 @@ void WorldSession::HandleMovementOpcodes(WorldPacket & recv_data) mover->UpdatePosition(movementInfo.pos); - if (plMover) // nothing is charmed, or player charmed + if (plrMover) // nothing is charmed, or player charmed { - plMover->UpdateFallInformationIfNeed(movementInfo, opcode); + plrMover->UpdateFallInformationIfNeed(movementInfo, opcode); if (movementInfo.pos.GetPositionZ() < -500.0f) { - if (!(plMover->InBattleground() - && plMover->GetBattleground() - && plMover->GetBattleground()->HandlePlayerUnderMap(_player))) + if (!(plrMover->GetBattleground() && plrMover->GetBattleground()->HandlePlayerUnderMap(_player))) { // NOTE: this is actually called many times while falling // even after the player has been teleported away // TODO: discard movement packets after the player is rooted - if (plMover->isAlive()) + if (plrMover->isAlive()) { - plMover->EnvironmentalDamage(DAMAGE_FALL_TO_VOID, GetPlayer()->GetMaxHealth()); + plrMover->EnvironmentalDamage(DAMAGE_FALL_TO_VOID, GetPlayer()->GetMaxHealth()); // player can be alive if GM/etc // change the death state to CORPSE to prevent the death timer from // starting in the next player update - if (!plMover->isAlive()) - plMover->KillPlayer(); + if (!plrMover->isAlive()) + plrMover->KillPlayer(); } } } diff --git a/src/server/game/Handlers/PetHandler.cpp b/src/server/game/Handlers/PetHandler.cpp index 1fa6d9fc0ed..e54bee96b8b 100755 --- a/src/server/game/Handlers/PetHandler.cpp +++ b/src/server/game/Handlers/PetHandler.cpp @@ -153,8 +153,6 @@ void WorldSession::HandlePetActionHelper(Unit* pet, uint64 guid1, uint16 spellid switch (spellid) { case COMMAND_STAY: //flat=1792 //STAY - pet->AttackStop(); - pet->InterruptNonMeleeSpells(false); pet->StopMoving(); pet->GetMotionMaster()->Clear(false); pet->GetMotionMaster()->MoveIdle(); diff --git a/src/server/game/Handlers/PetitionsHandler.cpp b/src/server/game/Handlers/PetitionsHandler.cpp index 7a3964b9469..cb3bac0e443 100755 --- a/src/server/game/Handlers/PetitionsHandler.cpp +++ b/src/server/game/Handlers/PetitionsHandler.cpp @@ -300,9 +300,9 @@ void WorldSession::HandlePetitionShowSignOpcode(WorldPacket& recv_data) for (uint8 i = 1; i <= signs; ++i) { Field* fields2 = result->Fetch(); - uint64 plguid = fields2[0].GetUInt64(); + uint32 lowGuid = fields2[0].GetUInt32(); - data << uint64(plguid); // Player GUID + data << uint64(MAKE_NEW_GUID(lowGuid, 0, HIGHGUID_PLAYER)); // Player GUID data << uint32(0); // there 0 ... result->NextRow(); @@ -485,7 +485,7 @@ void WorldSession::HandlePetitionSignOpcode(WorldPacket & recv_data) fields = result->Fetch(); uint64 ownerGuid = MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER); - uint8 signs = fields[1].GetUInt8(); + uint64 signs = fields[1].GetUInt64(); uint8 type = fields[2].GetUInt8(); uint32 playerGuid = _player->GetGUIDLow(); @@ -727,9 +727,7 @@ void WorldSession::HandleOfferPetitionOpcode(WorldPacket & recv_data) for (uint8 i = 1; i <= signs; ++i) { Field* fields2 = result->Fetch(); - plguid = fields2[0].GetUInt64(); - - data << uint64(plguid); // Player GUID + data << uint64(MAKE_NEW_GUID(fields2[0].GetUInt32(), 0, HIGHGUID_PLAYER)); // Player GUID data << uint32(0); // there 0 ... result->NextRow(); diff --git a/src/server/game/Handlers/QueryHandler.cpp b/src/server/game/Handlers/QueryHandler.cpp index 5061331b8de..628cdbbdd5e 100755 --- a/src/server/game/Handlers/QueryHandler.cpp +++ b/src/server/game/Handlers/QueryHandler.cpp @@ -38,15 +38,9 @@ void WorldSession::SendNameQueryOpcode(uint64 guid) WorldPacket data(SMSG_NAME_QUERY_RESPONSE, (8+1+1+1+1+1+10)); data.appendPackGUID(guid); - if (!player) - { - data << uint8(1); // player unknown - SendPacket(&data); - return; - } if (!nameData) { - data << uint8(2); // name unknown + data << uint8(1); // name unknown SendPacket(&data); return; } @@ -58,7 +52,7 @@ void WorldSession::SendNameQueryOpcode(uint64 guid) data << uint8(nameData->m_gender); data << uint8(nameData->m_class); - if (DeclinedName const* names = player->GetDeclinedNames()) + if (DeclinedName const* names = (player ? player->GetDeclinedNames() : NULL)) { data << uint8(1); // Name is declined for (uint8 i = 0; i < MAX_DECLINED_NAME_CASES; ++i) diff --git a/src/server/game/Handlers/TicketHandler.cpp b/src/server/game/Handlers/TicketHandler.cpp index 9c4eba67426..d6675188f6e 100755 --- a/src/server/game/Handlers/TicketHandler.cpp +++ b/src/server/game/Handlers/TicketHandler.cpp @@ -176,6 +176,8 @@ void WorldSession::HandleReportLag(WorldPacket& recv_data) stmt->setFloat (3, x); stmt->setFloat (4, y); stmt->setFloat (5, z); + stmt->setUInt32(6, GetLatency()); + stmt->setUInt32(7, time(NULL)); CharacterDatabase.Execute(stmt); } diff --git a/src/server/game/Instances/InstanceSaveMgr.cpp b/src/server/game/Instances/InstanceSaveMgr.cpp index c17c7edbf0d..8078a91d082 100755 --- a/src/server/game/Instances/InstanceSaveMgr.cpp +++ b/src/server/game/Instances/InstanceSaveMgr.cpp @@ -581,17 +581,17 @@ void InstanceSaveManager::_ResetOrWarnAll(uint32 mapid, Difficulty difficulty, b PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_INSTANCE_BY_MAP_DIFF); stmt->setUInt16(0, uint16(mapid)); - stmt->setUInt8(0, uint8(difficulty)); + stmt->setUInt8(1, uint8(difficulty)); trans->Append(stmt); stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GROUP_INSTANCE_BY_MAP_DIFF); stmt->setUInt16(0, uint16(mapid)); - stmt->setUInt8(0, uint8(difficulty)); + stmt->setUInt8(1, uint8(difficulty)); trans->Append(stmt); stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_INSTANCE_BY_MAP_DIFF); stmt->setUInt16(0, uint16(mapid)); - stmt->setUInt8(0, uint8(difficulty)); + stmt->setUInt8(1, uint8(difficulty)); trans->Append(stmt); CharacterDatabase.CommitTransaction(trans); diff --git a/src/server/game/Loot/LootMgr.cpp b/src/server/game/Loot/LootMgr.cpp index 1b349b11156..75065158ef6 100755 --- a/src/server/game/Loot/LootMgr.cpp +++ b/src/server/game/Loot/LootMgr.cpp @@ -1526,7 +1526,7 @@ void LoadLootTemplates_Gameobject() { if (uint32 lootid = itr->second.GetLootId()) { - if (sObjectMgr->IsGoOfSpecificEntrySpawned(itr->second.entry) && lootIdSet.find(lootid) == lootIdSet.end()) + if (lootIdSet.find(lootid) == lootIdSet.end()) LootTemplates_Gameobject.ReportNotExistedId(lootid); else lootIdSetUsed.insert(lootid); diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index f60a8f20c1c..162dd12d121 100755 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -787,20 +787,20 @@ void Map::RemoveCreatureFromMoveList(Creature* c) void Map::MoveAllCreaturesInMoveList() { _creatureToMoveLock = true; - for(std::vector<Creature*>::iterator itr = _creaturesToMove.begin(); itr != _creaturesToMove.end(); ++itr) + for (std::vector<Creature*>::iterator itr = _creaturesToMove.begin(); itr != _creaturesToMove.end(); ++itr) { Creature* c = *itr; - if(c->FindMap() != this) //pet is teleported to another map + if (c->FindMap() != this) //pet is teleported to another map continue; - if(c->_moveState != CREATURE_CELL_MOVE_ACTIVE) + if (c->_moveState != CREATURE_CELL_MOVE_ACTIVE) { c->_moveState = CREATURE_CELL_MOVE_NONE; continue; } c->_moveState = CREATURE_CELL_MOVE_NONE; - if(!c->IsInWorld()) + if (!c->IsInWorld()) continue; // do move or do move to respawn or remove creature if previous all fail @@ -2470,7 +2470,7 @@ bool InstanceMap::AddPlayerToMap(Player* player) if (uint32 dungeonId = sLFGMgr->GetDungeon(group->GetGUID(), true)) if (LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(dungeonId)) if (LFGDungeonEntry const* randomDungeon = sLFGDungeonStore.LookupEntry(*(sLFGMgr->GetSelectedDungeons(player->GetGUID()).begin()))) - if (uint32(dungeon->map) == GetId() && dungeon->difficulty == GetDifficulty() && randomDungeon->type == LFG_TYPE_RANDOM) + if (uint32(dungeon->map) == GetId() && dungeon->difficulty == uint32(GetDifficulty()) && randomDungeon->type == uint32(LFG_TYPE_RANDOM)) player->CastSpell(player, LFG_SPELL_LUCK_OF_THE_DRAW, true); } diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h index 766e3d23f93..6ba08646f25 100755 --- a/src/server/game/Maps/Map.h +++ b/src/server/game/Maps/Map.h @@ -228,7 +228,7 @@ enum LevelRequirementVsMode #define MAX_HEIGHT 100000.0f // can be use for find ground height at surface #define INVALID_HEIGHT -100000.0f // for check, must be equal to VMAP_INVALID_HEIGHT, real value for unknown height is VMAP_INVALID_HEIGHT_VALUE #define MAX_FALL_DISTANCE 250000.0f // "unlimited fall" to find VMap ground if it is available, just larger than MAX_HEIGHT - INVALID_HEIGHT -#define DEFAULT_HEIGHT_SEARCH 10.0f // default search distance to find height at nearby locations +#define DEFAULT_HEIGHT_SEARCH 50.0f // default search distance to find height at nearby locations #define MIN_UNLOAD_DELAY 1 // immediate unload typedef std::map<uint32/*leaderDBGUID*/, CreatureGroup*> CreatureGroupHolderType; diff --git a/src/server/game/Maps/MapManager.cpp b/src/server/game/Maps/MapManager.cpp index 0fb28008c1e..eb09538721d 100755 --- a/src/server/game/Maps/MapManager.cpp +++ b/src/server/game/Maps/MapManager.cpp @@ -96,32 +96,32 @@ void MapManager::checkAndCorrectGridStatesArray() Map* MapManager::CreateBaseMap(uint32 id) { - Map* m = FindBaseMap(id); + Map* map = FindBaseMap(id); - if (m == NULL) + if (map == NULL) { TRINITY_GUARD(ACE_Thread_Mutex, Lock); const MapEntry* entry = sMapStore.LookupEntry(id); if (entry && entry->Instanceable()) { - m = new MapInstanced(id, i_gridCleanUpDelay); + map = new MapInstanced(id, i_gridCleanUpDelay); } else { - m = new Map(id, i_gridCleanUpDelay, 0, REGULAR_DIFFICULTY); + map = new Map(id, i_gridCleanUpDelay, 0, REGULAR_DIFFICULTY); } - i_maps[id] = m; + i_maps[id] = map; } - ASSERT(m != NULL); - return m; + ASSERT(map); + return map; } Map* MapManager::FindBaseNonInstanceMap(uint32 mapId) const { Map* map = FindBaseMap(mapId); - if(map && map->Instanceable()) + if (map && map->Instanceable()) return NULL; return map; } diff --git a/src/server/game/Miscellaneous/Language.h b/src/server/game/Miscellaneous/Language.h index 547f1679b61..aec72835d86 100755 --- a/src/server/game/Miscellaneous/Language.h +++ b/src/server/game/Miscellaneous/Language.h @@ -522,8 +522,11 @@ enum TrinityStrings LANG_YOURS_EXPLORE_SET_ALL = 553, LANG_YOURS_EXPLORE_SET_NOTHING = 554, - LANG_HOVER_ENABLED = 555, - LANG_HOVER_DISABLED = 556, + LANG_NPC_SETDATA = 555, + + //! Old ones now free: + // LANG_HOVER_DISABLED = 556, + LANG_YOURS_LEVEL_UP = 557, LANG_YOURS_LEVEL_DOWN = 558, LANG_YOURS_LEVEL_PROGRESS_RESET = 559, diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index bca896df38f..06aca10879d 100755 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -269,7 +269,7 @@ enum SpellAttr0 SPELL_ATTR0_UNK0 = 0x00000001, // 0 SPELL_ATTR0_REQ_AMMO = 0x00000002, // 1 on next ranged SPELL_ATTR0_ON_NEXT_SWING = 0x00000004, // 2 - SPELL_ATTR0_UNK3 = 0x00000008, // 3 not set in 3.0.3 + SPELL_ATTR0_IS_REPLENISHMENT = 0x00000008, // 3 not set in 3.0.3 SPELL_ATTR0_ABILITY = 0x00000010, // 4 client puts 'ability' instead of 'spell' in game strings for these spells SPELL_ATTR0_TRADESPELL = 0x00000020, // 5 trade spells (recipes), will be added by client to a sublist of profession spell SPELL_ATTR0_PASSIVE = 0x00000040, // 6 Passive spell @@ -314,7 +314,7 @@ enum SpellAttr1 SPELL_ATTR1_MELEE_COMBAT_START = 0x00000200, // 9 player starts melee combat after this spell is cast SPELL_ATTR1_NO_THREAT = 0x00000400, // 10 no generates threat on cast 100% (old NO_INITIAL_AGGRO) SPELL_ATTR1_UNK11 = 0x00000800, // 11 aura - SPELL_ATTR1_UNK12 = 0x00001000, // 12 pickpoket + SPELL_ATTR1_IS_PICKPOCKET = 0x00001000, // 12 Pickpocket SPELL_ATTR1_FARSIGHT = 0x00002000, // 13 Client removes farsight on aura loss SPELL_ATTR1_CHANNEL_TRACK_TARGET = 0x00004000, // 14 Client automatically forces player to face target when channeling SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY = 0x00008000, // 15 remove auras on immunity @@ -326,7 +326,7 @@ enum SpellAttr1 SPELL_ATTR1_UNK21 = 0x00200000, // 21 SPELL_ATTR1_REQ_COMBO_POINTS2 = 0x00400000, // 22 Req combo points on target SPELL_ATTR1_UNK23 = 0x00800000, // 23 - SPELL_ATTR1_UNK24 = 0x01000000, // 24 only fishing spells + SPELL_ATTR1_IS_FISHING = 0x01000000, // 24 only fishing spells SPELL_ATTR1_UNK25 = 0x02000000, // 25 SPELL_ATTR1_UNK26 = 0x04000000, // 26 works correctly with [target=focus] and [target=mouseover] macros? SPELL_ATTR1_UNK27 = 0x08000000, // 27 melee spell? @@ -351,17 +351,17 @@ enum SpellAttr2 SPELL_ATTR2_UNK10 = 0x00000400, // 10 related to tame SPELL_ATTR2_HEALTH_FUNNEL = 0x00000800, // 11 SPELL_ATTR2_UNK12 = 0x00001000, // 12 Cleave, Heart Strike, Maul, Sunder Armor, Swipe - SPELL_ATTR2_UNK13 = 0x00002000, // 13 Items enchanted by spells with this flag preserve the enchant to arenas + SPELL_ATTR2_PRESERVE_ENCHANT_IN_ARENA = 0x00002000, // 13 Items enchanted by spells with this flag preserve the enchant to arenas SPELL_ATTR2_UNK14 = 0x00004000, // 14 SPELL_ATTR2_UNK15 = 0x00008000, // 15 not set in 3.0.3 SPELL_ATTR2_TAME_BEAST = 0x00010000, // 16 SPELL_ATTR2_NOT_RESET_AUTO_ACTIONS = 0x00020000, // 17 don't reset timers for melee autoattacks (swings) or ranged autoattacks (autoshoots) - SPELL_ATTR2_UNK18 = 0x00040000, // 18 Only Revive pet - possible req dead pet + SPELL_ATTR2_REQ_DEAD_PET = 0x00040000, // 18 Only Revive pet and Heart of the Pheonix SPELL_ATTR2_NOT_NEED_SHAPESHIFT = 0x00080000, // 19 does not necessarly need shapeshift SPELL_ATTR2_UNK20 = 0x00100000, // 20 SPELL_ATTR2_DAMAGE_REDUCED_SHIELD = 0x00200000, // 21 for ice blocks, pala immunity buffs, priest absorb shields, but used also for other spells -> not sure! SPELL_ATTR2_UNK22 = 0x00400000, // 22 Ambush, Backstab, Cheap Shot, Death Grip, Garrote, Judgements, Mutilate, Pounce, Ravage, Shiv, Shred - SPELL_ATTR2_UNK23 = 0x00800000, // 23 Only mage Arcane Concentration have this flag + SPELL_ATTR2_IS_ARCANE_CONCENTRATION = 0x00800000, // 23 Only mage Arcane Concentration have this flag SPELL_ATTR2_UNK24 = 0x01000000, // 24 SPELL_ATTR2_UNK25 = 0x02000000, // 25 SPELL_ATTR2_UNK26 = 0x04000000, // 26 unaffected by school immunity @@ -388,7 +388,7 @@ enum SpellAttr3 SPELL_ATTR3_BATTLEGROUND = 0x00000800, // 11 Can casted only on battleground SPELL_ATTR3_ONLY_TARGET_GHOSTS = 0x00001000, // 12 SPELL_ATTR3_UNK13 = 0x00002000, // 13 - SPELL_ATTR3_UNK14 = 0x00004000, // 14 "Honorless Target" only this spells have this flag + SPELL_ATTR3_IS_HONORLESS_TARGET = 0x00004000, // 14 "Honorless Target" only this spells have this flag SPELL_ATTR3_UNK15 = 0x00008000, // 15 Auto Shoot, Shoot, Throw, - this is autoshot flag SPELL_ATTR3_CANT_TRIGGER_PROC = 0x00010000, // 16 confirmed with many patchnotes SPELL_ATTR3_NO_INITIAL_AGGRO = 0x00020000, // 17 Soothe Animal, 39758, Mind Soothe @@ -410,8 +410,8 @@ enum SpellAttr3 enum SpellAttr4 { - SPELL_ATTR4_UNK0 = 0x00000001, // 0 - SPELL_ATTR4_PROC_ONLY_ON_DUMMY = 0x00000002, // 1 proc only on SPELL_EFFECT_DUMMY? + SPELL_ATTR4_IGNORE_RESISTANCES = 0x00000001, // 0 spells with this attribute will completely ignore the target's resistance (these spells can't be resisted) + SPELL_ATTR4_PROC_ONLY_ON_CASTER = 0x00000002, // 1 proc only on effects with TARGET_UNIT_CASTER? SPELL_ATTR4_UNK2 = 0x00000004, // 2 SPELL_ATTR4_UNK3 = 0x00000008, // 3 SPELL_ATTR4_UNK4 = 0x00000010, // 4 This will no longer cause guards to attack on use?? @@ -432,16 +432,16 @@ enum SpellAttr4 SPELL_ATTR4_UNK19 = 0x00080000, // 19 proc dalayed, after damage or don't proc on absorb? SPELL_ATTR4_NOT_CHECK_SELFCAST_POWER = 0x00100000, // 20 supersedes message "More powerful spell applied" for self casts. SPELL_ATTR4_UNK21 = 0x00200000, // 21 Pally aura, dk presence, dudu form, warrior stance, shadowform, hunter track - SPELL_ATTR4_UNK22 = 0x00400000, // 22 + SPELL_ATTR4_UNK22 = 0x00400000, // 22 Seal of Command (42058,57770) and Gymer's Smash 55426 SPELL_ATTR4_UNK23 = 0x00800000, // 23 SPELL_ATTR4_UNK24 = 0x01000000, // 24 some shoot spell - SPELL_ATTR4_UNK25 = 0x02000000, // 25 pet scaling auras + SPELL_ATTR4_IS_PET_SCALING = 0x02000000, // 25 pet scaling auras SPELL_ATTR4_CAST_ONLY_IN_OUTLAND = 0x04000000, // 26 Can only be used in Outland. SPELL_ATTR4_UNK27 = 0x08000000, // 27 SPELL_ATTR4_UNK28 = 0x10000000, // 28 Aimed Shot SPELL_ATTR4_UNK29 = 0x20000000, // 29 SPELL_ATTR4_UNK30 = 0x40000000, // 30 - SPELL_ATTR4_UNK31 = 0x80000000 // 31 + SPELL_ATTR4_UNK31 = 0x80000000 // 31 Polymorph (chicken) 228 and Sonic Boom (38052,38488) }; enum SpellAttr5 @@ -461,7 +461,7 @@ enum SpellAttr5 SPELL_ATTR5_UNK12 = 0x00001000, // 12 Cleave related? SPELL_ATTR5_HASTE_AFFECT_DURATION = 0x00002000, // 13 haste effects decrease duration of this SPELL_ATTR5_UNK14 = 0x00004000, // 14 - SPELL_ATTR5_UNK15 = 0x00008000, // 15 + SPELL_ATTR5_UNK15 = 0x00008000, // 15 Inflits on multiple targets? SPELL_ATTR5_SPECIAL_ITEM_CLASS_CHECK = 0x00010000, // 16 this allows spells with EquippedItemClass to affect spells from other items if the required item is equipped SPELL_ATTR5_USABLE_WHILE_FEARED = 0x00020000, // 17 usable while feared SPELL_ATTR5_USABLE_WHILE_CONFUSED = 0x00040000, // 18 usable while confused @@ -2566,7 +2566,7 @@ enum CreatureTypeFlags { CREATURE_TYPEFLAGS_TAMEABLE = 0x00000001, // Tameable by any hunter CREATURE_TYPEFLAGS_GHOST = 0x00000002, // Creature are also visible for not alive player. Allow gossip interaction if npcflag allow? - CREATURE_TYPEFLAGS_UNK2 = 0x00000004, + CREATURE_TYPEFLAGS_BOSS = 0x00000004, CREATURE_TYPEFLAGS_UNK3 = 0x00000008, CREATURE_TYPEFLAGS_UNK4 = 0x00000010, CREATURE_TYPEFLAGS_UNK5 = 0x00000020, @@ -3294,20 +3294,20 @@ enum BanReturn // indexes of BattlemasterList.dbc enum BattlegroundTypeId { - BATTLEGROUND_TYPE_NONE = 0, - BATTLEGROUND_AV = 1, - BATTLEGROUND_WS = 2, - BATTLEGROUND_AB = 3, - BATTLEGROUND_NA = 4, - BATTLEGROUND_BE = 5, - BATTLEGROUND_AA = 6, - BATTLEGROUND_EY = 7, - BATTLEGROUND_RL = 8, - BATTLEGROUND_SA = 9, - BATTLEGROUND_DS = 10, - BATTLEGROUND_RV = 11, - BATTLEGROUND_IC = 30, - BATTLEGROUND_RB = 32 + BATTLEGROUND_TYPE_NONE = 0, // None + BATTLEGROUND_AV = 1, // Alterac Valley + BATTLEGROUND_WS = 2, // Warsong Gulch + BATTLEGROUND_AB = 3, // Arathi Basin + BATTLEGROUND_NA = 4, // Nagrand Arena + BATTLEGROUND_BE = 5, // Blade's Edge Arena + BATTLEGROUND_AA = 6, // All Arenas + BATTLEGROUND_EY = 7, // Eye of the Storm + BATTLEGROUND_RL = 8, // Ruins of Lordaernon + BATTLEGROUND_SA = 9, // Strand of the Ancients + BATTLEGROUND_DS = 10, // Dalaran Sewers + BATTLEGROUND_RV = 11, // Ring of Valor + BATTLEGROUND_IC = 30, // Isle of Conquest + BATTLEGROUND_RB = 32 // Random Battleground }; #define MAX_BATTLEGROUND_TYPE_ID 33 diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp index b8a7ee848ed..c0e1eb842ae 100755 --- a/src/server/game/Movement/MotionMaster.cpp +++ b/src/server/game/Movement/MotionMaster.cpp @@ -114,6 +114,9 @@ void MotionMaster::UpdateMotion(uint32 diff) _cleanFlag &= ~MMCF_RESET; } + + // probably not the best place to pu this but im not really sure where else to put it. + _owner->UpdateUnderwaterState(_owner->GetMap(), _owner->GetPositionX(), _owner->GetPositionY(), _owner->GetPositionZ()); } void MotionMaster::DirectClean(bool reset) @@ -383,6 +386,12 @@ void MotionMaster::MoveFall(uint32 id/*=0*/) if (fabs(_owner->GetPositionZ() - tz) < 0.1f) return; + if (_owner->GetTypeId() == TYPEID_PLAYER) + { + _owner->AddUnitMovementFlag(MOVEMENTFLAG_FALLING); + _owner->m_movementInfo.SetFallTime(0); + } + Movement::MoveSplineInit init(*_owner); init.MoveTo(_owner->GetPositionX(), _owner->GetPositionY(), tz); init.SetFall(); diff --git a/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp index da830a9a49b..54a68f92c66 100755 --- a/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp @@ -32,11 +32,10 @@ template<class T> void ConfusedMovementGenerator<T>::Initialize(T &unit) { - const float wander_distance=4; - float x,y,z; - x = unit.GetPositionX(); - y = unit.GetPositionY(); - z = unit.GetPositionZ(); + float const wander_distance = 4; + float x = unit.GetPositionX(); + float y = unit.GetPositionY(); + float z = unit.GetPositionZ(); Map const* map = unit.GetBaseMap(); @@ -47,31 +46,42 @@ void ConfusedMovementGenerator<T>::Initialize(T &unit) for (uint8 idx = 0; idx < MAX_CONF_WAYPOINTS + 1; ++idx) { - const float wanderX=wander_distance*(float)rand_norm() - wander_distance/2; - const float wanderY=wander_distance*(float)rand_norm() - wander_distance/2; - - i_waypoints[idx][0] = x + wanderX; - i_waypoints[idx][1] = y + wanderY; + float wanderX = x + (wander_distance * (float)rand_norm() - wander_distance/2); + float wanderY = y + (wander_distance * (float)rand_norm() - wander_distance/2); // prevent invalid coordinates generation - Trinity::NormalizeMapCoord(i_waypoints[idx][0]); - Trinity::NormalizeMapCoord(i_waypoints[idx][1]); + Trinity::NormalizeMapCoord(wanderX); + Trinity::NormalizeMapCoord(wanderY); - bool is_water = map->IsInWater(i_waypoints[idx][0],i_waypoints[idx][1],z); - // if generated wrong path just ignore - if ((is_water && !is_water_ok) || (!is_water && !is_land_ok)) + if (unit.IsWithinLOS(wanderX, wanderY, z)) + { + bool is_water = map->IsInWater(wanderX, wanderY, z); + + if ((is_water && !is_water_ok) || (!is_water && !is_land_ok)) + { + //! Cannot use coordinates outside our InhabitType. Use the current or previous position. + wanderX = idx > 0 ? i_waypoints[idx-1][0] : x; + wanderY = idx > 0 ? i_waypoints[idx-1][1] : y; + } + } + else { - i_waypoints[idx][0] = idx > 0 ? i_waypoints[idx-1][0] : x; - i_waypoints[idx][1] = idx > 0 ? i_waypoints[idx-1][1] : y; + //! Trying to access path outside line of sight. Skip this by using the current or previous position. + wanderX = idx > 0 ? i_waypoints[idx-1][0] : x; + wanderY = idx > 0 ? i_waypoints[idx-1][1] : y; } - unit.UpdateAllowedPositionZ(i_waypoints[idx][0], i_waypoints[idx][1], z); + unit.UpdateAllowedPositionZ(wanderX, wanderY, z); + + //! Positions are fine - apply them to this waypoint + i_waypoints[idx][0] = wanderX; + i_waypoints[idx][1] = wanderY; i_waypoints[idx][2] = z; } unit.StopMoving(); unit.SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_CONFUSED); - unit.AddUnitState(UNIT_STATE_CONFUSED|UNIT_STATE_CONFUSED_MOVE); + unit.AddUnitState(UNIT_STATE_CONFUSED | UNIT_STATE_CONFUSED_MOVE); } template<> @@ -94,7 +104,7 @@ void ConfusedMovementGenerator<T>::Reset(T &unit) i_nextMove = 1; i_nextMoveTime.Reset(0); unit.StopMoving(); - unit.AddUnitState(UNIT_STATE_CONFUSED|UNIT_STATE_CONFUSED_MOVE); + unit.AddUnitState(UNIT_STATE_CONFUSED | UNIT_STATE_CONFUSED_MOVE); } template<class T> @@ -110,8 +120,8 @@ bool ConfusedMovementGenerator<T>::Update(T &unit, const uint32 &diff) if (unit.movespline->Finalized()) { - i_nextMove = urand(1,MAX_CONF_WAYPOINTS); - i_nextMoveTime.Reset(urand(0, 1500-1)); // TODO: check the minimum reset time, should be probably higher + i_nextMove = urand(1, MAX_CONF_WAYPOINTS); + i_nextMoveTime.Reset(urand(500, 1200)); // Guessed } } else @@ -123,7 +133,7 @@ bool ConfusedMovementGenerator<T>::Update(T &unit, const uint32 &diff) // start moving unit.AddUnitState(UNIT_STATE_CONFUSED_MOVE); - ASSERT( i_nextMove <= MAX_CONF_WAYPOINTS ); + ASSERT(i_nextMove <= MAX_CONF_WAYPOINTS); float x = i_waypoints[i_nextMove][0]; float y = i_waypoints[i_nextMove][1]; float z = i_waypoints[i_nextMove][2]; @@ -141,14 +151,14 @@ template<> void ConfusedMovementGenerator<Player>::Finalize(Player &unit) { unit.RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_CONFUSED); - unit.ClearUnitState(UNIT_STATE_CONFUSED|UNIT_STATE_CONFUSED_MOVE); + unit.ClearUnitState(UNIT_STATE_CONFUSED | UNIT_STATE_CONFUSED_MOVE); } template<> void ConfusedMovementGenerator<Creature>::Finalize(Creature &unit) { unit.RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_CONFUSED); - unit.ClearUnitState(UNIT_STATE_CONFUSED|UNIT_STATE_CONFUSED_MOVE); + unit.ClearUnitState(UNIT_STATE_CONFUSED | UNIT_STATE_CONFUSED_MOVE); if (unit.getVictim()) unit.SetTarget(unit.getVictim()->GetGUID()); } diff --git a/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.h b/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.h index b9f96bb785d..7f2226ea069 100755 --- a/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.h @@ -22,11 +22,10 @@ #include "MovementGenerator.h" #include "Timer.h" -#define MAX_CONF_WAYPOINTS 24 +#define MAX_CONF_WAYPOINTS 24 //! Allows a twelve second confusion if i_nextMove always is the absolute minimum timer. template<class T> -class ConfusedMovementGenerator -: public MovementGeneratorMedium< T, ConfusedMovementGenerator<T> > +class ConfusedMovementGenerator : public MovementGeneratorMedium< T, ConfusedMovementGenerator<T> > { public: explicit ConfusedMovementGenerator() : i_nextMoveTime(0) {} diff --git a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp index 7de5f1095c4..08e27abf050 100755 --- a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp @@ -28,8 +28,7 @@ #define MAX_QUIET_DISTANCE 43.0f template<class T> -void -FleeingMovementGenerator<T>::_setTargetLocation(T &owner) +void FleeingMovementGenerator<T>::_setTargetLocation(T &owner) { if (!&owner) return; @@ -53,8 +52,7 @@ FleeingMovementGenerator<T>::_setTargetLocation(T &owner) } template<class T> -bool -FleeingMovementGenerator<T>::_getPoint(T &owner, float &x, float &y, float &z) +bool FleeingMovementGenerator<T>::_getPoint(T &owner, float &x, float &y, float &z) { if (!&owner) return false; @@ -65,8 +63,8 @@ FleeingMovementGenerator<T>::_getPoint(T &owner, float &x, float &y, float &z) float temp_x, temp_y, angle; const Map* _map = owner.GetBaseMap(); - //primitive path-finding - for(uint8 i = 0; i < 18; ++i) + // primitive path-finding + for (uint8 i = 0; i < 18; ++i) { if (i_only_forward && i > 2) break; @@ -187,8 +185,7 @@ FleeingMovementGenerator<T>::_getPoint(T &owner, float &x, float &y, float &z) } template<class T> -bool -FleeingMovementGenerator<T>::_setMoveData(T &owner) +bool FleeingMovementGenerator<T>::_setMoveData(T &owner) { float cur_dist_xyz = owner.GetDistance(i_caster_x, i_caster_y, i_caster_z); @@ -280,8 +277,7 @@ FleeingMovementGenerator<T>::_setMoveData(T &owner) } template<class T> -void -FleeingMovementGenerator<T>::Initialize(T &owner) +void FleeingMovementGenerator<T>::Initialize(T &owner) { if (!&owner) return; @@ -312,8 +308,7 @@ FleeingMovementGenerator<T>::Initialize(T &owner) } template<> -void -FleeingMovementGenerator<Creature>::_Init(Creature &owner) +void FleeingMovementGenerator<Creature>::_Init(Creature &owner) { if (!&owner) return; @@ -324,8 +319,7 @@ FleeingMovementGenerator<Creature>::_Init(Creature &owner) } template<> -void -FleeingMovementGenerator<Player>::_Init(Player &) +void FleeingMovementGenerator<Player>::_Init(Player &) { is_water_ok = true; is_land_ok = true; @@ -354,8 +348,7 @@ void FleeingMovementGenerator<T>::Reset(T &owner) } template<class T> -bool -FleeingMovementGenerator<T>::Update(T &owner, const uint32 &time_diff) +bool FleeingMovementGenerator<T>::Update(T &owner, const uint32 &time_diff) { if (!&owner || !owner.isAlive()) return false; diff --git a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.h b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.h index f795a002821..aec93ad3375 100755 --- a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.h @@ -22,8 +22,7 @@ #include "MovementGenerator.h" template<class T> -class FleeingMovementGenerator -: public MovementGeneratorMedium< T, FleeingMovementGenerator<T> > +class FleeingMovementGenerator : public MovementGeneratorMedium< T, FleeingMovementGenerator<T> > { public: FleeingMovementGenerator(uint64 fright) : i_frightGUID(fright), i_nextCheckTime(0) {} @@ -55,8 +54,7 @@ class FleeingMovementGenerator TimeTracker i_nextCheckTime; }; -class TimedFleeingMovementGenerator -: public FleeingMovementGenerator<Creature> +class TimedFleeingMovementGenerator : public FleeingMovementGenerator<Creature> { public: TimedFleeingMovementGenerator(uint64 fright, uint32 time) : diff --git a/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.cpp index 311b69c06b7..a8bdb698432 100755 --- a/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.cpp @@ -25,7 +25,6 @@ void HomeMovementGenerator<Creature>::Initialize(Creature & owner) { - owner.AddUnitState(UNIT_STATE_EVADE); _setTargetLocation(owner); } diff --git a/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.h b/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.h index c724edc91ff..95eb05f281c 100755 --- a/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.h @@ -27,8 +27,7 @@ template < class T > class HomeMovementGenerator; template <> -class HomeMovementGenerator<Creature> -: public MovementGeneratorMedium< Creature, HomeMovementGenerator<Creature> > +class HomeMovementGenerator<Creature> : public MovementGeneratorMedium< Creature, HomeMovementGenerator<Creature> > { public: diff --git a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp index 91b50344ccb..a922c937b5f 100755 --- a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp @@ -46,7 +46,7 @@ bool PointMovementGenerator<T>::Update(T &unit, const uint32 & /*diff*/) if (!&unit) return false; - if(unit.HasUnitState(UNIT_STATE_ROOT | UNIT_STATE_STUNNED)) + if (unit.HasUnitState(UNIT_STATE_ROOT | UNIT_STATE_STUNNED)) { unit.ClearUnitState(UNIT_STATE_ROAMING_MOVE); return true; diff --git a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h index 82578da5f9b..13be9fee77b 100755 --- a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h @@ -23,8 +23,7 @@ #include "FollowerReference.h" template<class T> -class PointMovementGenerator -: public MovementGeneratorMedium< T, PointMovementGenerator<T> > +class PointMovementGenerator : public MovementGeneratorMedium< T, PointMovementGenerator<T> > { public: PointMovementGenerator(uint32 _id, float _x, float _y, float _z, float _speed = 0.0f) : id(_id), @@ -46,8 +45,7 @@ class PointMovementGenerator float speed; }; -class AssistanceMovementGenerator -: public PointMovementGenerator<Creature> +class AssistanceMovementGenerator : public PointMovementGenerator<Creature> { public: AssistanceMovementGenerator(float _x, float _y, float _z) : diff --git a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp index e520253eb46..84cd9e88295 100755 --- a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp @@ -127,8 +127,7 @@ void RandomMovementGenerator<Creature>::Initialize(Creature &creature) } template<> -void -RandomMovementGenerator<Creature>::Reset(Creature &creature) +void RandomMovementGenerator<Creature>::Reset(Creature &creature) { Initialize(creature); } @@ -141,8 +140,7 @@ void RandomMovementGenerator<Creature>::Finalize(Creature &creature) } template<> -bool -RandomMovementGenerator<Creature>::Update(Creature &creature, const uint32 diff) +bool RandomMovementGenerator<Creature>::Update(Creature &creature, const uint32 diff) { if (creature.HasUnitState(UNIT_STATE_ROOT | UNIT_STATE_STUNNED | UNIT_STATE_DISTRACTED)) { diff --git a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.h b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.h index 67161b6fc29..07ec3647052 100755 --- a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.h @@ -22,8 +22,7 @@ #include "MovementGenerator.h" template<class T> -class RandomMovementGenerator -: public MovementGeneratorMedium< T, RandomMovementGenerator<T> > +class RandomMovementGenerator : public MovementGeneratorMedium< T, RandomMovementGenerator<T> > { public: RandomMovementGenerator(float spawn_dist = 0.0f) : i_nextMoveTime(0), wander_distance(spawn_dist) {} diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp index 6d507a3b694..fdff5a92564 100755 --- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp @@ -78,7 +78,7 @@ void TargetedMovementGeneratorMedium<T,D>::_setTargetLocation(T &owner) //We don't update Mob Movement, if the difference between New destination and last destination is < BothObjectSize float bothObjectSize = i_target->GetObjectBoundingRadius() + owner.GetObjectBoundingRadius() + CONTACT_DISTANCE; - if( i_destinationHolder.HasDestination() && i_destinationHolder.GetDestinationDiff(x,y,z) < bothObjectSize ) + if ( i_destinationHolder.HasDestination() && i_destinationHolder.GetDestinationDiff(x,y,z) < bothObjectSize ) return; */ @@ -135,7 +135,7 @@ bool TargetedMovementGeneratorMedium<T,D>::Update(T &owner, const uint32 & time_ } // prevent movement while casting spells with cast time or channel time - if (owner.IsNonMeleeSpellCasted(false, false, true)) + if (owner.HasUnitState(UNIT_STATE_CASTING)) { if (!owner.IsStopped()) owner.StopMoving(); diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h index b851dbc0e05..29fd73624e1 100755 --- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h @@ -34,8 +34,7 @@ class TargetedMovementGeneratorBase }; template<class T, typename D> -class TargetedMovementGeneratorMedium -: public MovementGeneratorMedium< T, D >, public TargetedMovementGeneratorBase +class TargetedMovementGeneratorMedium : public MovementGeneratorMedium< T, D >, public TargetedMovementGeneratorBase { protected: TargetedMovementGeneratorMedium(Unit &target, float offset, float angle) : diff --git a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp index 81fe1606ede..25730f92161 100755 --- a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp @@ -107,7 +107,7 @@ bool WaypointMovementGenerator<Creature>::StartMove(Creature &creature) i_currentNode = (i_currentNode+1) % i_path->size(); } - const WaypointData *node = i_path->at(i_currentNode); + WaypointData const* node = i_path->at(i_currentNode); m_isArrivalDone = false; @@ -116,7 +116,8 @@ bool WaypointMovementGenerator<Creature>::StartMove(Creature &creature) Movement::MoveSplineInit init(creature); init.MoveTo(node->x, node->y, node->z); - if (node->orientation != 100 && node->delay != 0) + //! Accepts angles such as 0.00001 and -0.00001, 0 must be ignored, default value in waypoint table + if (node->orientation && node->delay) init.SetFacing(node->orientation); init.SetWalk(!node->run); diff --git a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h index b5b43fcae64..0d8f047c83a 100755 --- a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h @@ -58,9 +58,8 @@ template<class T> class WaypointMovementGenerator; template<> -class WaypointMovementGenerator<Creature> -: public MovementGeneratorMedium< Creature, WaypointMovementGenerator<Creature> >, -public PathMovementBase<Creature, WaypointPath const*> +class WaypointMovementGenerator<Creature> : public MovementGeneratorMedium< Creature, WaypointMovementGenerator<Creature> >, + public PathMovementBase<Creature, WaypointPath const*> { public: WaypointMovementGenerator(uint32 _path_id = 0, bool _repeating = true) @@ -110,9 +109,8 @@ public PathMovementBase<Creature, WaypointPath const*> /** FlightPathMovementGenerator generates movement of the player for the paths * and hence generates ground and activities for the player. */ -class FlightPathMovementGenerator -: public MovementGeneratorMedium< Player, FlightPathMovementGenerator >, -public PathMovementBase<Player, TaxiPathNodeList const*> +class FlightPathMovementGenerator : public MovementGeneratorMedium< Player, FlightPathMovementGenerator >, + public PathMovementBase<Player, TaxiPathNodeList const*> { public: explicit FlightPathMovementGenerator(TaxiPathNodeList const& pathnodes, uint32 startNode = 0) diff --git a/src/server/game/Movement/Spline/MoveSpline.cpp b/src/server/game/Movement/Spline/MoveSpline.cpp index 5d0344f9769..91b4ff08250 100644 --- a/src/server/game/Movement/Spline/MoveSpline.cpp +++ b/src/server/game/Movement/Spline/MoveSpline.cpp @@ -288,7 +288,7 @@ std::string MoveSpline::ToString() const str << "facing angle: " << facing.angle; else if (splineflags.final_target) str << "facing target: " << facing.target; - else if(splineflags.final_point) + else if (splineflags.final_point) str << "facing point: " << facing.f.x << " " << facing.f.y << " " << facing.f.z; str << std::endl; str << "time passed: " << time_passed << std::endl; diff --git a/src/server/game/Movement/Spline/MovementPacketBuilder.cpp b/src/server/game/Movement/Spline/MovementPacketBuilder.cpp index e9031f95486..0260767dbe2 100644 --- a/src/server/game/Movement/Spline/MovementPacketBuilder.cpp +++ b/src/server/game/Movement/Spline/MovementPacketBuilder.cpp @@ -111,7 +111,7 @@ namespace Movement Vector3 middle = (real_path[0] + real_path[last_idx]) / 2.f; Vector3 offset; // first and last points already appended - for(uint32 i = 1; i < last_idx; ++i) + for (uint32 i = 1; i < last_idx; ++i) { offset = middle - real_path[i]; data.appendPackXYZ(offset.x, offset.y, offset.z); @@ -169,7 +169,7 @@ namespace Movement { data << move_spline.facing.target; } - else if(splineFlags.final_point) + else if (splineFlags.final_point) { data << move_spline.facing.f.x << move_spline.facing.f.y << move_spline.facing.f.z; } diff --git a/src/server/game/Pools/PoolMgr.cpp b/src/server/game/Pools/PoolMgr.cpp index 5ebf78e484c..d8548b552d3 100755 --- a/src/server/game/Pools/PoolMgr.cpp +++ b/src/server/game/Pools/PoolMgr.cpp @@ -479,7 +479,7 @@ void PoolGroup<Quest>::SpawnObject(ActivePoolData& spawns, uint32 limit, uint32 { do { - uint32 questId = SelectRandomContainerElement(currentQuests); + uint32 questId = Trinity::Containers::SelectRandomContainerElement(currentQuests); newQuests.insert(questId); currentQuests.erase(questId); } while (newQuests.size() < limit && !currentQuests.empty()); // failsafe @@ -491,7 +491,7 @@ void PoolGroup<Quest>::SpawnObject(ActivePoolData& spawns, uint32 limit, uint32 // activate <limit> random quests do { - uint32 questId = SelectRandomContainerElement(newQuests); + uint32 questId = Trinity::Containers::SelectRandomContainerElement(newQuests); spawns.ActivateObject<Quest>(questId, poolId); PoolObject tempObj(questId, 0.0f); Spawn1Object(&tempObj); diff --git a/src/server/game/Reputation/ReputationMgr.h b/src/server/game/Reputation/ReputationMgr.h index 401503783b9..a073845ea73 100755 --- a/src/server/game/Reputation/ReputationMgr.h +++ b/src/server/game/Reputation/ReputationMgr.h @@ -132,6 +132,9 @@ class ReputationMgr void ApplyForceReaction(uint32 faction_id, ReputationRank rank, bool apply); + //! Public for chat command needs + bool SetOneFactionReputation(FactionEntry const* factionEntry, int32 standing, bool incremental); + public: // senders void SendInitialReputations(); void SendForceReactions(); @@ -142,7 +145,6 @@ class ReputationMgr void Initialize(); uint32 GetDefaultStateFlags(FactionEntry const* factionEntry) const; bool SetReputation(FactionEntry const* factionEntry, int32 standing, bool incremental); - bool SetOneFactionReputation(FactionEntry const* factionEntry, int32 standing, bool incremental); void SetVisible(FactionState* faction); void SetAtWar(FactionState* faction, bool atWar) const; void SetInactive(FactionState* faction, bool inactive) const; diff --git a/src/server/game/Scripting/ScriptLoader.cpp b/src/server/game/Scripting/ScriptLoader.cpp index 76c3f1c073c..f64d0953e86 100755 --- a/src/server/game/Scripting/ScriptLoader.cpp +++ b/src/server/game/Scripting/ScriptLoader.cpp @@ -61,7 +61,6 @@ void AddSC_reload_commandscript(); void AddSC_tele_commandscript(); void AddSC_titles_commandscript(); void AddSC_wp_commandscript(); -void AddSC_gps_commandscript(); #ifdef SCRIPTS //world @@ -425,6 +424,7 @@ void AddSC_ulduar_teleporter(); void AddSC_boss_mimiron(); void AddSC_boss_hodir(); void AddSC_boss_freya(); +void AddSC_boss_algalon_the_observer(); void AddSC_instance_ulduar(); void AddSC_boss_keleseth(); //Utgarde Keep void AddSC_boss_skarvald_dalronn(); @@ -663,7 +663,6 @@ void AddCommandScripts() AddSC_tele_commandscript(); AddSC_titles_commandscript(); AddSC_wp_commandscript(); - AddSC_gps_commandscript(); } void AddWorldScripts() @@ -1129,6 +1128,7 @@ void AddNorthrendScripts() AddSC_boss_mimiron(); AddSC_boss_hodir(); AddSC_boss_freya(); + AddSC_boss_algalon_the_observer(); AddSC_instance_ulduar(); AddSC_boss_keleseth(); //Utgarde Keep AddSC_boss_skarvald_dalronn(); diff --git a/src/server/game/Scripting/ScriptMgr.cpp b/src/server/game/Scripting/ScriptMgr.cpp index 012910210a5..23d18e12097 100755 --- a/src/server/game/Scripting/ScriptMgr.cpp +++ b/src/server/game/Scripting/ScriptMgr.cpp @@ -582,7 +582,7 @@ void ScriptMgr::OnCreateMap(Map* map) { ASSERT(map); - SCR_MAP_BGN(WorldMapScript, map, itr, end, entry, IsContinent); + SCR_MAP_BGN(WorldMapScript, map, itr, end, entry, IsWorldMap); itr->second->OnCreate(map); SCR_MAP_END; @@ -599,7 +599,7 @@ void ScriptMgr::OnDestroyMap(Map* map) { ASSERT(map); - SCR_MAP_BGN(WorldMapScript, map, itr, end, entry, IsContinent); + SCR_MAP_BGN(WorldMapScript, map, itr, end, entry, IsWorldMap); itr->second->OnDestroy(map); SCR_MAP_END; @@ -617,7 +617,7 @@ void ScriptMgr::OnLoadGridMap(Map* map, GridMap* gmap, uint32 gx, uint32 gy) ASSERT(map); ASSERT(gmap); - SCR_MAP_BGN(WorldMapScript, map, itr, end, entry, IsContinent); + SCR_MAP_BGN(WorldMapScript, map, itr, end, entry, IsWorldMap); itr->second->OnLoadGridMap(map, gmap, gx, gy); SCR_MAP_END; @@ -635,7 +635,7 @@ void ScriptMgr::OnUnloadGridMap(Map* map, GridMap* gmap, uint32 gx, uint32 gy) ASSERT(map); ASSERT(gmap); - SCR_MAP_BGN(WorldMapScript, map, itr, end, entry, IsContinent); + SCR_MAP_BGN(WorldMapScript, map, itr, end, entry, IsWorldMap); itr->second->OnUnloadGridMap(map, gmap, gx, gy); SCR_MAP_END; @@ -653,7 +653,7 @@ void ScriptMgr::OnPlayerEnterMap(Map* map, Player* player) ASSERT(map); ASSERT(player); - SCR_MAP_BGN(WorldMapScript, map, itr, end, entry, IsContinent); + SCR_MAP_BGN(WorldMapScript, map, itr, end, entry, IsWorldMap); itr->second->OnPlayerEnter(map, player); SCR_MAP_END; @@ -671,7 +671,7 @@ void ScriptMgr::OnPlayerLeaveMap(Map* map, Player* player) ASSERT(map); ASSERT(player); - SCR_MAP_BGN(WorldMapScript, map, itr, end, entry, IsContinent); + SCR_MAP_BGN(WorldMapScript, map, itr, end, entry, IsWorldMap); itr->second->OnPlayerLeave(map, player); SCR_MAP_END; @@ -688,7 +688,7 @@ void ScriptMgr::OnMapUpdate(Map* map, uint32 diff) { ASSERT(map); - SCR_MAP_BGN(WorldMapScript, map, itr, end, entry, IsContinent); + SCR_MAP_BGN(WorldMapScript, map, itr, end, entry, IsWorldMap); itr->second->OnUpdate(map, diff); SCR_MAP_END; @@ -937,6 +937,22 @@ void ScriptMgr::OnGameObjectDamaged(GameObject* go, Player* player) tmpscript->OnDamaged(go, player); } +void ScriptMgr::OnGameObjectLootStateChanged(GameObject* go, uint32 state, Unit* unit) +{ + ASSERT(go); + + GET_SCRIPT(GameObjectScript, go->GetScriptId(), tmpscript); + tmpscript->OnLootStateChanged(go, state, unit); +} + +void ScriptMgr::OnGameObjectStateChanged(GameObject* go, uint32 state) +{ + ASSERT(go); + + GET_SCRIPT(GameObjectScript, go->GetScriptId(), tmpscript); + tmpscript->OnGameObjectStateChanged(go, state); +} + void ScriptMgr::OnGameObjectUpdate(GameObject* go, uint32 diff) { ASSERT(go); @@ -954,6 +970,14 @@ bool ScriptMgr::OnDummyEffect(Unit* caster, uint32 spellId, SpellEffIndex effInd return tmpscript->OnDummyEffect(caster, spellId, effIndex, target); } +GameObjectAI* ScriptMgr::GetGameObjectAI(GameObject* go) +{ + ASSERT(go); + + GET_SCRIPT_RET(GameObjectScript, go->GetScriptId(), tmpscript, NULL); + return tmpscript->GetAI(go); +} + bool ScriptMgr::OnAreaTrigger(Player* player, AreaTriggerEntry const* trigger) { ASSERT(player); @@ -1415,7 +1439,7 @@ FormulaScript::FormulaScript(const char* name) WorldMapScript::WorldMapScript(const char* name, uint32 mapId) : ScriptObject(name), MapScript<Map>(mapId) { - if (GetEntry() && !GetEntry()->IsContinent()) + if (GetEntry() && !GetEntry()->IsWorldMap()) sLog->outError("WorldMapScript for map %u is invalid.", mapId); ScriptRegistry<WorldMapScript>::AddScript(this); diff --git a/src/server/game/Scripting/ScriptMgr.h b/src/server/game/Scripting/ScriptMgr.h index 3b65a5cf256..b3d445af0c6 100755 --- a/src/server/game/Scripting/ScriptMgr.h +++ b/src/server/game/Scripting/ScriptMgr.h @@ -39,6 +39,7 @@ class Creature; class CreatureAI; class DynamicObject; class GameObject; +class GameObjectAI; class Guild; class GridMap; class Group; @@ -471,6 +472,15 @@ class GameObjectScript : public ScriptObject, public UpdatableScript<GameObject> // Called when the game object is damaged (destructible buildings only). virtual void OnDamaged(GameObject* /*go*/, Player* /*player*/) { } + + // Called when the game object loot state is changed. + virtual void OnLootStateChanged(GameObject* /*go*/, uint32 /*state*/, Unit* /*unit*/) { } + + // Called when the game object state is changed. + virtual void OnGameObjectStateChanged(GameObject* /*go*/, uint32 /*state*/) { } + + // Called when a GameObjectAI object is needed for the gameobject. + virtual GameObjectAI* GetAI(GameObject* /*go*/) const { return NULL; } }; class AreaTriggerScript : public ScriptObject @@ -910,7 +920,10 @@ class ScriptMgr uint32 GetDialogStatus(Player* player, GameObject* go); void OnGameObjectDestroyed(GameObject* go, Player* player); void OnGameObjectDamaged(GameObject* go, Player* player); + void OnGameObjectLootStateChanged(GameObject* go, uint32 state, Unit* unit); + void OnGameObjectStateChanged(GameObject* go, uint32 state); void OnGameObjectUpdate(GameObject* go, uint32 diff); + GameObjectAI* GetGameObjectAI(GameObject* go); public: /* AreaTriggerScript */ diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp index c6ccfaa8004..bd9c75c251d 100755 --- a/src/server/game/Server/Protocol/Opcodes.cpp +++ b/src/server/game/Server/Protocol/Opcodes.cpp @@ -76,7 +76,7 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] = /*0x02F*/ { "SMSG_DEBUG_AISTATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, /*0x030*/ { "CMSG_DISABLE_PVP_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, /*0x031*/ { "CMSG_ADVANCE_SPAWN_TIME", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x032*/ { "SMSG_DESTRUCTIBLE_BUILDING_DAMAGE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, + /*0x032*/ { "SMSG_DESTRUCTIBLE_BUILDING_DAMAGE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, /*0x033*/ { "CMSG_AUTH_SRP6_BEGIN", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, /*0x034*/ { "CMSG_AUTH_SRP6_PROOF", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, /*0x035*/ { "CMSG_AUTH_SRP6_RECODE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, @@ -270,8 +270,8 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] = /*0x0F1*/ { "MSG_MOVE_KNOCK_BACK", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, /*0x0F2*/ { "SMSG_MOVE_FEATHER_FALL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, /*0x0F3*/ { "SMSG_MOVE_NORMAL_FALL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x0F4*/ { "SMSG_MOVE_SET_HOVER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x0F5*/ { "SMSG_MOVE_UNSET_HOVER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, + /*0x0F4*/ { "SMSG_MOVE_SET_HOVER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, + /*0x0F5*/ { "SMSG_MOVE_UNSET_HOVER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, /*0x0F6*/ { "CMSG_MOVE_HOVER_ACK", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMoveHoverAck }, /*0x0F7*/ { "MSG_MOVE_HOVER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, /*0x0F8*/ { "CMSG_TRIGGER_CINEMATIC_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, @@ -558,7 +558,7 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] = /*0x211*/ { "CMSG_GMTICKET_GETTICKET", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGMTicketGetTicketOpcode }, /*0x212*/ { "SMSG_GMTICKET_GETTICKET", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, /*0x213*/ { "CMSG_UNLEARN_TALENTS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x214*/ { "SMSG_GAMEOBJECT_SPAWN_ANIM_OBSOLETE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, + /*0x214*/ { "SMSG_UPDATE_INSTANCE_ENCOUNTER_UNIT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, /*0x215*/ { "SMSG_GAMEOBJECT_DESPAWN_ANIM", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, /*0x216*/ { "MSG_CORPSE_QUERY", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCorpseQueryOpcode }, /*0x217*/ { "CMSG_GMTICKET_DELETETICKET", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGMTicketDeleteOpcode }, @@ -970,7 +970,7 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] = /*0x3AD*/ { "MSG_MOVE_UPDATE_CAN_FLY", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, /*0x3AE*/ { "MSG_RAID_READY_CHECK_CONFIRM", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, /*0x3AF*/ { "CMSG_VOICE_SESSION_ENABLE", STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleVoiceSessionEnableOpcode }, - /*0x3B0*/ { "SMSG_VOICE_SESSION_ENABLE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, + /*0x3B0*/ { "SMSG_VOICE_SESSION_ENABLE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, /*0x3B1*/ { "SMSG_VOICE_PARENTAL_CONTROLS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, /*0x3B2*/ { "CMSG_GM_WHISPER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, /*0x3B3*/ { "SMSG_GM_MESSAGECHAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, @@ -1023,7 +1023,7 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] = /*0x3E2*/ { "SMSG_COMSAT_CONNECT_FAIL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, /*0x3E3*/ { "SMSG_VOICE_CHAT_STATUS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, /*0x3E4*/ { "CMSG_REPORT_PVP_AFK", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleReportPvPAFK }, - /*0x3E5*/ { "SMSG_REPORT_PVP_AFK_RESULT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, + /*0x3E5*/ { "SMSG_REPORT_PVP_AFK_RESULT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, /*0x3E6*/ { "CMSG_GUILD_BANKER_ACTIVATE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildBankerActivate }, /*0x3E7*/ { "CMSG_GUILD_BANK_QUERY_TAB", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildBankQueryTab }, /*0x3E8*/ { "SMSG_GUILD_BANK_LIST", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, @@ -1148,7 +1148,7 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] = /*0x45F*/ { "CMSG_CALENDAR_EVENT_INVITE_NOTES", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, /*0x460*/ { "SMSG_CALENDAR_EVENT_INVITE_NOTES", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, /*0x461*/ { "SMSG_CALENDAR_EVENT_INVITE_NOTES_ALERT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x462*/ { "CMSG_UPDATE_MISSILE_TRAJECTORY", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, + /*0x462*/ { "CMSG_UPDATE_MISSILE_TRAJECTORY", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleUpdateMissileTrajectory }, /*0x463*/ { "SMSG_UPDATE_ACCOUNT_DATA_COMPLETE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, /*0x464*/ { "SMSG_TRIGGER_MOVIE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, /*0x465*/ { "CMSG_COMPLETE_MOVIE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, diff --git a/src/server/game/Server/Protocol/Opcodes.h b/src/server/game/Server/Protocol/Opcodes.h index ab6ba7e7796..3c77ced6741 100755 --- a/src/server/game/Server/Protocol/Opcodes.h +++ b/src/server/game/Server/Protocol/Opcodes.h @@ -911,7 +911,7 @@ enum Opcodes CMSG_LFG_SET_ROLES = 0x36A, CMSG_LFG_SET_NEEDS = 0x36B, CMSG_LFG_SET_BOOT_VOTE = 0x36C, - SMSG_LFG_BOOT_PLAYER = 0x36D, // uint8, uint8, uint8, uint64, uint32, uint32, uint32, uint32 + SMSG_LFG_BOOT_PROPOSAL_UPDATE = 0x36D, // uint8, uint8, uint8, uint64, uint32, uint32, uint32, uint32 CMSG_LFD_PLAYER_LOCK_INFO_REQUEST = 0x36E, SMSG_LFG_PLAYER_INFO = 0x36F, // uint8, for (uint8) { uint32, uint8, uint32, uint32, uint32, uint32, uint8, for (uint8) {uint32, uint32, uint32}}, uint32, for (uint32) {uint32, uint32} CMSG_LFG_TELEPORT = 0x370, diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index be6561c2633..88248b7bc55 100755 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -831,8 +831,8 @@ void WorldSession::ReadMovementInfo(WorldPacket &data, MovementInfo* mi) in conjunction with any of the moving movement flags such as MOVEMENTFLAG_FORWARD. It will freeze clients that receive this player's movement info. */ - REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_ROOT) && mi->HasMovementFlag(MOVEMENTFLAG_MASK_MOVING), - MOVEMENTFLAG_MASK_MOVING); + REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_ROOT), + MOVEMENTFLAG_ROOT); //! Cannot hover without SPELL_AURA_HOVER REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_HOVER) && !GetPlayer()->HasAuraType(SPELL_AURA_HOVER), diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index 0fce0a372ff..6d8a9e3ff38 100755 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -395,7 +395,7 @@ class WorldSession public: // opcodes handlers void Handle_NULL(WorldPacket& recvPacket); // not used - void Handle_EarlyProccess(WorldPacket& recvPacket);// just mark packets processed in WorldSocket::OnRead + void Handle_EarlyProccess(WorldPacket& recvPacket); // just mark packets processed in WorldSocket::OnRead void Handle_ServerSide(WorldPacket& recvPacket); // sever side only, can't be accepted from client void Handle_Deprecated(WorldPacket& recvPacket); // never used anymore by client @@ -785,6 +785,7 @@ class WorldSession void HandleResetInstancesOpcode(WorldPacket& recv_data); void HandleHearthAndResurrect(WorldPacket& recv_data); void HandleInstanceLockResponse(WorldPacket& recvPacket); + void HandleUpdateMissileTrajectory(WorldPacket& recvPacket); // Looking for Dungeon/Raid void HandleLfgSetCommentOpcode(WorldPacket& recv_data); diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index 6383c7ff3ef..d28ba9e1e19 100755 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -490,7 +490,7 @@ int32 AuraEffect::CalculateAmount(Unit* caster) if (GetSpellInfo()->SpellFamilyFlags[1] & 0x1 && GetSpellInfo()->SpellFamilyFlags[2] & 0x8) { // +80.68% from sp bonus - DoneActualBenefit += caster->SpellBaseDamageBonus(m_spellInfo->GetSchoolMask()) * 0.8068f; + DoneActualBenefit += caster->SpellBaseDamageBonusDone(m_spellInfo->GetSchoolMask()) * 0.8068f; // Glyph of Ice Barrier: its weird having a SPELLMOD_ALL_EFFECTS here but its blizzards doing :) // Glyph of Ice Barrier is only applied at the spell damage bonus because it was already applied to the base value in CalculateSpellDamage DoneActualBenefit = caster->ApplyEffectModifiers(GetSpellInfo(), m_effIndex, DoneActualBenefit); @@ -499,13 +499,13 @@ int32 AuraEffect::CalculateAmount(Unit* caster) else if (GetSpellInfo()->SpellFamilyFlags[0] & 0x8 && GetSpellInfo()->SpellFamilyFlags[2] & 0x8) { // +80.68% from sp bonus - DoneActualBenefit += caster->SpellBaseDamageBonus(m_spellInfo->GetSchoolMask()) * 0.8068f; + DoneActualBenefit += caster->SpellBaseDamageBonusDone(m_spellInfo->GetSchoolMask()) * 0.8068f; } // Frost Ward else if (GetSpellInfo()->SpellFamilyFlags[0] & 0x100 && GetSpellInfo()->SpellFamilyFlags[2] & 0x8) { // +80.68% from sp bonus - DoneActualBenefit += caster->SpellBaseDamageBonus(m_spellInfo->GetSchoolMask()) * 0.8068f; + DoneActualBenefit += caster->SpellBaseDamageBonusDone(m_spellInfo->GetSchoolMask()) * 0.8068f; } break; case SPELLFAMILY_WARLOCK: @@ -513,7 +513,7 @@ int32 AuraEffect::CalculateAmount(Unit* caster) if (m_spellInfo->SpellFamilyFlags[2] & 0x40) { // +80.68% from sp bonus - DoneActualBenefit += caster->SpellBaseDamageBonus(m_spellInfo->GetSchoolMask()) * 0.8068f; + DoneActualBenefit += caster->SpellBaseDamageBonusDone(m_spellInfo->GetSchoolMask()) * 0.8068f; } break; case SPELLFAMILY_PRIEST: @@ -527,7 +527,7 @@ int32 AuraEffect::CalculateAmount(Unit* caster) if (AuraEffect const* pAurEff = caster->GetDummyAuraEffect(SPELLFAMILY_PRIEST, 2899, 1)) bonus += CalculatePctN(1.0f, pAurEff->GetAmount()); - DoneActualBenefit += caster->SpellBaseHealingBonus(m_spellInfo->GetSchoolMask()) * bonus; + DoneActualBenefit += caster->SpellBaseHealingBonusDone(m_spellInfo->GetSchoolMask()) * bonus; // Improved PW: Shield: its weird having a SPELLMOD_ALL_EFFECTS here but its blizzards doing :) // Improved PW: Shield is only applied at the spell healing bonus because it was already applied to the base value in CalculateSpellDamage DoneActualBenefit = caster->ApplyEffectModifiers(GetSpellInfo(), m_effIndex, DoneActualBenefit); @@ -555,7 +555,7 @@ int32 AuraEffect::CalculateAmount(Unit* caster) //+75.00% from sp bonus float bonus = 0.75f; - DoneActualBenefit += caster->SpellBaseHealingBonus(m_spellInfo->GetSchoolMask()) * bonus; + DoneActualBenefit += caster->SpellBaseHealingBonusDone(m_spellInfo->GetSchoolMask()) * bonus; // Divine Guardian is only applied at the spell healing bonus because it was already applied to the base value in CalculateSpellDamage DoneActualBenefit = caster->ApplyEffectModifiers(GetSpellInfo(), m_effIndex, DoneActualBenefit); DoneActualBenefit *= caster->CalculateLevelPenalty(GetSpellInfo()); @@ -584,7 +584,7 @@ int32 AuraEffect::CalculateAmount(Unit* caster) if (GetSpellInfo()->SpellFamilyName == SPELLFAMILY_MAGE && GetSpellInfo()->SpellFamilyFlags[0] & 0x8000 && m_spellInfo->SpellFamilyFlags[2] & 0x8) { // +80.53% from +spd bonus - DoneActualBenefit += caster->SpellBaseDamageBonus(m_spellInfo->GetSchoolMask()) * 0.8053f;; + DoneActualBenefit += caster->SpellBaseDamageBonusDone(m_spellInfo->GetSchoolMask()) * 0.8053f; } break; case SPELL_AURA_DUMMY: @@ -592,7 +592,10 @@ int32 AuraEffect::CalculateAmount(Unit* caster) break; // Earth Shield if (GetSpellInfo()->SpellFamilyName == SPELLFAMILY_SHAMAN && m_spellInfo->SpellFamilyFlags[1] & 0x400) - amount = caster->SpellHealingBonus(GetBase()->GetUnitOwner(), GetSpellInfo(), amount, SPELL_DIRECT_DAMAGE); + { + amount = caster->SpellHealingBonusDone(GetBase()->GetUnitOwner(), GetSpellInfo(), amount, SPELL_DIRECT_DAMAGE); + amount = GetBase()->GetUnitOwner()->SpellHealingBonusTaken(caster, GetSpellInfo(), amount, SPELL_DIRECT_DAMAGE); + } break; case SPELL_AURA_PERIODIC_DAMAGE: if (!caster) @@ -933,6 +936,7 @@ void AuraEffect::ChangeAmount(int32 newAmount, bool mark, bool onStackOrReapply) handleMask |= AURA_EFFECT_HANDLE_CHANGE_AMOUNT; if (onStackOrReapply) handleMask |= AURA_EFFECT_HANDLE_REAPPLY; + if (!handleMask) return; @@ -1231,12 +1235,11 @@ bool AuraEffect::IsPeriodicTickCrit(Unit* target, Unit const* caster) const if ((*itr)->IsAffectedOnSpell(m_spellInfo) && caster->isSpellCrit(target, m_spellInfo, m_spellInfo->GetSchoolMask())) return true; } + // Rupture - since 3.3.3 can crit - if (target->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_ROGUE, 0x100000, 0x0, 0x0, caster->GetGUID())) - { - if (caster->isSpellCrit(target, m_spellInfo, m_spellInfo->GetSchoolMask())) - return true; - } + if (m_spellInfo->SpellIconID == 500 && m_spellInfo->SpellFamilyName == SPELLFAMILY_ROGUE) + return caster->isSpellCrit(target, m_spellInfo, m_spellInfo->GetSchoolMask()); + return false; } @@ -1475,6 +1478,23 @@ void AuraEffect::HandleShapeshiftBoosts(Unit* target, bool apply) const if (spellInfo->Stances & (1<<(GetMiscValue()-1))) target->CastSpell(target, itr->first, true, NULL, this); } + + // Also do it for Glyphs + for (uint32 i = 0; i < MAX_GLYPH_SLOT_INDEX; ++i) + { + if (uint32 glyphId = target->ToPlayer()->GetGlyph(i)) + { + if (GlyphPropertiesEntry const* glyph = sGlyphPropertiesStore.LookupEntry(glyphId)) + { + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(glyph->SpellId); + if (!spellInfo || !(spellInfo->Attributes & (SPELL_ATTR0_PASSIVE | SPELL_ATTR0_HIDDEN_CLIENTSIDE))) + continue; + if (spellInfo->Stances & (1<<(GetMiscValue()-1))) + target->CastSpell(target, glyph->SpellId, true, NULL, this); + } + } + } + // Leader of the Pack if (target->ToPlayer()->HasSpell(17007)) { @@ -1584,10 +1604,25 @@ void AuraEffect::HandleShapeshiftBoosts(Unit* target, bool apply) const } } + const Unit::AuraEffectList& shapeshifts = target->GetAuraEffectsByType(SPELL_AURA_MOD_SHAPESHIFT); + AuraEffect* newAura = NULL; + // Iterate through all the shapeshift auras that the target has, if there is another aura with SPELL_AURA_MOD_SHAPESHIFT, then this aura is being removed due to that one being applied + for (Unit::AuraEffectList::const_iterator itr = shapeshifts.begin(); itr != shapeshifts.end(); ++itr) + { + if ((*itr) != this) + { + newAura = *itr; + break; + } + } Unit::AuraApplicationMap& tAuras = target->GetAppliedAuras(); for (Unit::AuraApplicationMap::iterator itr = tAuras.begin(); itr != tAuras.end();) { - if (itr->second->GetBase()->IsRemovedOnShapeLost(target)) + // Use the new aura to see on what stance the target will be + uint32 newStance = (1<<((newAura ? newAura->GetMiscValue() : 0)-1)); + + // If the stances are not compatible with the spell, remove it + if (itr->second->GetBase()->IsRemovedOnShapeLost(target) && !(itr->second->GetBase()->GetSpellInfo()->Stances & newStance)) target->RemoveAura(itr); else ++itr; @@ -2856,9 +2891,8 @@ void AuraEffect::HandleAuraAllowFlight(AuraApplication const* aurApp, uint8 mode target->SetCanFly(apply); if (!apply) { - target->RemoveUnitMovementFlag(MOVEMENTFLAG_FLYING); - target->AddUnitMovementFlag(MOVEMENTFLAG_FALLING); - target->m_movementInfo.SetFallTime(0); + target->RemoveUnitMovementFlag(MOVEMENTFLAG_MASK_MOVING_FLY); + target->GetMotionMaster()->MoveFall(); } Player* player = target->ToPlayer(); @@ -2889,10 +2923,7 @@ void AuraEffect::HandleAuraWaterWalk(AuraApplication const* aurApp, uint8 mode, if (apply) target->AddUnitMovementFlag(MOVEMENTFLAG_WATERWALKING); else - { target->RemoveUnitMovementFlag(MOVEMENTFLAG_WATERWALKING); - target->AddUnitMovementFlag(MOVEMENTFLAG_FALLING); - } target->SendMovementWaterWalking(); } @@ -4768,11 +4799,6 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool if (target->GetTypeId() == TYPEID_PLAYER) target->ToPlayer()->RemoveAmmo(); // not use ammo and not allow use break; - case 49028: - if (caster) - if (AuraEffect* aurEff = caster->GetAuraEffect(63330, 0)) // glyph of Dancing Rune Weapon - GetBase()->SetDuration(GetBase()->GetDuration() + aurEff->GetAmount()); - break; case 52916: // Honor Among Thieves if (target->GetTypeId() == TYPEID_PLAYER) if (Unit* spellTarget = ObjectAccessor::GetUnit(*target, target->ToPlayer()->GetComboTarget())) @@ -4938,7 +4964,13 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool // final heal int32 stack = GetBase()->GetStackAmount(); - target->CastCustomSpell(target, 33778, &m_amount, &stack, NULL, true, NULL, this, GetCasterGUID()); + int32 heal = m_amount; + if (caster) + { + heal = caster->SpellHealingBonusDone(target, GetSpellInfo(), heal, HEAL, stack); + heal = target->SpellHealingBonusTaken(caster, GetSpellInfo(), heal, HEAL, stack); + } + target->CastCustomSpell(target, 33778, &heal, &stack, NULL, true, NULL, this, GetCasterGUID()); // restore mana if (caster) @@ -5240,66 +5272,63 @@ void AuraEffect::HandleChannelDeathItem(AuraApplication const* aurApp, uint8 mod if (!(mode & AURA_EFFECT_HANDLE_REAL)) return; - if (!apply) - { - Unit* caster = GetCaster(); + if (apply || aurApp->GetRemoveMode() != AURA_REMOVE_BY_DEATH) + return; - if (!caster || caster->GetTypeId() != TYPEID_PLAYER) - return; + Unit* caster = GetCaster(); - Player* plCaster = caster->ToPlayer(); - Unit* target = aurApp->GetTarget(); + if (!caster || caster->GetTypeId() != TYPEID_PLAYER) + return; - if (target->getDeathState() != JUST_DIED) - return; + Player* plCaster = caster->ToPlayer(); + Unit* target = aurApp->GetTarget(); - // Item amount - if (GetAmount() <= 0) - return; + // Item amount + if (GetAmount() <= 0) + return; + + if (GetSpellInfo()->Effects[m_effIndex].ItemType == 0) + return; - if (GetSpellInfo()->Effects[m_effIndex].ItemType == 0) + // Soul Shard + if (GetSpellInfo()->Effects[m_effIndex].ItemType == 6265) + { + // Soul Shard only from units that grant XP or honor + if (!plCaster->isHonorOrXPTarget(target) || + (target->GetTypeId() == TYPEID_UNIT && !target->ToCreature()->isTappedBy(plCaster))) return; - // Soul Shard - if (GetSpellInfo()->Effects[m_effIndex].ItemType == 6265) + // If this is Drain Soul, check for Glyph of Drain Soul + if (GetSpellInfo()->SpellFamilyName == SPELLFAMILY_WARLOCK && (GetSpellInfo()->SpellFamilyFlags[0] & 0x00004000)) { - // Soul Shard only from units that grant XP or honor - if (!plCaster->isHonorOrXPTarget(target) || - (target->GetTypeId() == TYPEID_UNIT && !target->ToCreature()->isTappedBy(plCaster))) - return; - - // If this is Drain Soul, check for Glyph of Drain Soul - if (GetSpellInfo()->SpellFamilyName == SPELLFAMILY_WARLOCK && (GetSpellInfo()->SpellFamilyFlags[0] & 0x00004000)) - { - // Glyph of Drain Soul - chance to create an additional Soul Shard - if (AuraEffect* aur = caster->GetAuraEffect(58070, 0)) - if (roll_chance_i(aur->GetMiscValue())) - caster->CastSpell(caster, 58068, true, 0, aur); // We _could_ simply do ++count here, but Blizz does it this way :) - } + // Glyph of Drain Soul - chance to create an additional Soul Shard + if (AuraEffect* aur = caster->GetAuraEffect(58070, 0)) + if (roll_chance_i(aur->GetMiscValue())) + caster->CastSpell(caster, 58068, true, 0, aur); // We _could_ simply do ++count here, but Blizz does it this way :) } + } - //Adding items - uint32 noSpaceForCount = 0; - uint32 count = m_amount; + //Adding items + uint32 noSpaceForCount = 0; + uint32 count = m_amount; - ItemPosCountVec dest; - InventoryResult msg = plCaster->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, GetSpellInfo()->Effects[m_effIndex].ItemType, count, &noSpaceForCount); - if (msg != EQUIP_ERR_OK) - { - count-=noSpaceForCount; - plCaster->SendEquipError(msg, NULL, NULL, GetSpellInfo()->Effects[m_effIndex].ItemType); - if (count == 0) - return; - } - - Item* newitem = plCaster->StoreNewItem(dest, GetSpellInfo()->Effects[m_effIndex].ItemType, true); - if (!newitem) - { - plCaster->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL); + ItemPosCountVec dest; + InventoryResult msg = plCaster->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, GetSpellInfo()->Effects[m_effIndex].ItemType, count, &noSpaceForCount); + if (msg != EQUIP_ERR_OK) + { + count-=noSpaceForCount; + plCaster->SendEquipError(msg, NULL, NULL, GetSpellInfo()->Effects[m_effIndex].ItemType); + if (count == 0) return; - } - plCaster->SendNewItem(newitem, count, true, true); } + + Item* newitem = plCaster->StoreNewItem(dest, GetSpellInfo()->Effects[m_effIndex].ItemType, true); + if (!newitem) + { + plCaster->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL); + return; + } + plCaster->SendNewItem(newitem, count, true, true); } void AuraEffect::HandleBindSight(AuraApplication const* aurApp, uint8 mode, bool apply) const @@ -5623,21 +5652,6 @@ void AuraEffect::HandlePeriodicDummyAuraTick(Unit* target, Unit* caster) const caster->CastCustomSpell(66153, SPELLVALUE_MAX_TARGETS, urand(1, 6), target, true); break; } - case 54798: // FLAMING Arrow Triggered Effect - { - if (!caster || !target || !target->ToCreature() || !caster->GetVehicle() || target->HasAura(54683)) - break; - - target->CastSpell(target, 54683, true); - - // Credit Frostworgs - if (target->GetEntry() == 29358) - caster->CastSpell(caster, 54896, true); - // Credit Frost Giants - else if (target->GetEntry() == 29351) - caster->CastSpell(caster, 54893, true); - break; - } case 62292: // Blaze (Pool of Tar) // should we use custom damage? target->CastSpell((Unit*)NULL, m_spellInfo->Effects[m_effIndex].TriggerSpell, true); @@ -5726,7 +5740,7 @@ void AuraEffect::HandlePeriodicDummyAuraTick(Unit* target, Unit* caster) const if (targets.empty()) return; - Unit* spellTarget = SelectRandomContainerElement(targets); + Unit* spellTarget = Trinity::Containers::SelectRandomContainerElement(targets); target->CastSpell(spellTarget, 57840, true); target->CastSpell(spellTarget, 57841, true); @@ -6180,7 +6194,8 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const if (GetAuraType() == SPELL_AURA_PERIODIC_DAMAGE) { - damage = caster->SpellDamageBonus(target, GetSpellInfo(), damage, DOT, GetBase()->GetStackAmount()); + damage = caster->SpellDamageBonusDone(target, GetSpellInfo(), damage, DOT, GetBase()->GetStackAmount()); + damage = target->SpellDamageBonusTaken(caster, GetSpellInfo(), damage, DOT, GetBase()->GetStackAmount()); // Calculate armor mitigation if (Unit::IsDamageReducedByArmor(GetSpellInfo()->GetSchoolMask(), GetSpellInfo(), GetEffIndex())) @@ -6272,7 +6287,7 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) const { - if (!caster || !caster->isAlive() || !target->isAlive()) + if (!caster || !target->isAlive()) return; if (target->HasUnitState(UNIT_STATE_ISOLATED) || target->IsImmunedToDamage(GetSpellInfo())) @@ -6290,7 +6305,9 @@ void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) c CleanDamage cleanDamage = CleanDamage(0, 0, BASE_ATTACK, MELEE_HIT_NORMAL); uint32 damage = std::max(GetAmount(), 0); - damage = caster->SpellDamageBonus(target, GetSpellInfo(), damage, DOT, GetBase()->GetStackAmount()); + + damage = caster->SpellDamageBonusDone(target, GetSpellInfo(), damage, DOT, GetBase()->GetStackAmount()); + damage = target->SpellDamageBonusTaken(caster, GetSpellInfo(), damage, DOT, GetBase()->GetStackAmount()); bool crit = IsPeriodicTickCrit(target, caster); if (crit) @@ -6325,15 +6342,19 @@ void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) c damage = (damage <= absorb+resist) ? 0 : (damage-absorb-resist); if (damage) procVictim |= PROC_FLAG_TAKEN_DAMAGE; - caster->ProcDamageAndSpell(target, procAttacker, procVictim, procEx, damage, BASE_ATTACK, GetSpellInfo()); + if (caster->isAlive()) + caster->ProcDamageAndSpell(target, procAttacker, procVictim, procEx, damage, BASE_ATTACK, GetSpellInfo()); int32 new_damage = caster->DealDamage(target, damage, &cleanDamage, DOT, GetSpellInfo()->GetSchoolMask(), GetSpellInfo(), false); + if (caster->isAlive()) + { + float gainMultiplier = GetSpellInfo()->Effects[GetEffIndex()].CalcValueMultiplier(caster); - float gainMultiplier = GetSpellInfo()->Effects[GetEffIndex()].CalcValueMultiplier(caster); - - uint32 heal = uint32(caster->SpellHealingBonus(caster, GetSpellInfo(), uint32(new_damage * gainMultiplier), DOT, GetBase()->GetStackAmount())); + uint32 heal = uint32(caster->SpellHealingBonusDone(caster, GetSpellInfo(), uint32(new_damage * gainMultiplier), DOT, GetBase()->GetStackAmount())); + heal = uint32(caster->SpellHealingBonusTaken(caster, GetSpellInfo(), heal, DOT, GetBase()->GetStackAmount())); - int32 gain = caster->HealBySpell(caster, GetSpellInfo(), heal); - caster->getHostileRefManager().threatAssist(caster, gain * 0.5f, GetSpellInfo()); + int32 gain = caster->HealBySpell(caster, GetSpellInfo(), heal); + caster->getHostileRefManager().threatAssist(caster, gain * 0.5f, GetSpellInfo()); + } } void AuraEffect::HandlePeriodicHealthFunnelAuraTick(Unit* target, Unit* caster) const @@ -6433,7 +6454,8 @@ void AuraEffect::HandlePeriodicHealAurasTick(Unit* target, Unit* caster) const damage += addition; } - damage = caster->SpellHealingBonus(target, GetSpellInfo(), damage, DOT, GetBase()->GetStackAmount()); + damage = caster->SpellHealingBonusDone(target, GetSpellInfo(), damage, DOT, GetBase()->GetStackAmount()); + damage = target->SpellHealingBonusTaken(caster, GetSpellInfo(), damage, DOT, GetBase()->GetStackAmount()); } bool crit = IsPeriodicTickCrit(target, caster); @@ -6459,7 +6481,7 @@ void AuraEffect::HandlePeriodicHealAurasTick(Unit* target, Unit* caster) const // damage caster for heal amount if (target != caster && GetSpellInfo()->AttributesEx2 & SPELL_ATTR2_HEALTH_FUNNEL) { - uint32 funnelDamage = GetSpellInfo()->Effects[EFFECT_0].CalcValue(); // damage is not affected by spell power + uint32 funnelDamage = GetSpellInfo()->ManaPerSecond; // damage is not affected by spell power if ((int32)funnelDamage > gain) funnelDamage = gain; uint32 funnelAbsorb = 0; @@ -6723,7 +6745,8 @@ void AuraEffect::HandleProcTriggerDamageAuraProc(AuraApplication* aurApp, ProcEv Unit* target = aurApp->GetTarget(); Unit* triggerTarget = eventInfo.GetProcTarget(); SpellNonMeleeDamage damageInfo(target, triggerTarget, GetId(), GetSpellInfo()->SchoolMask); - uint32 damage = target->SpellDamageBonus(triggerTarget, GetSpellInfo(), GetAmount(), SPELL_DIRECT_DAMAGE); + uint32 damage = target->SpellDamageBonusDone(triggerTarget, GetSpellInfo(), GetAmount(), SPELL_DIRECT_DAMAGE); + damage = triggerTarget->SpellDamageBonusTaken(target, GetSpellInfo(), damage, SPELL_DIRECT_DAMAGE); target->CalculateSpellDamageTaken(&damageInfo, damage, GetSpellInfo()); target->DealDamageMods(damageInfo.target, damageInfo.damage, &damageInfo.absorb); target->SendSpellNonMeleeDamageLog(&damageInfo); diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp index b6cdc006d2d..4dda1c731a7 100755 --- a/src/server/game/Spells/Auras/SpellAuras.cpp +++ b/src/server/game/Spells/Auras/SpellAuras.cpp @@ -1212,8 +1212,11 @@ void Aura::HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, b // Improved Devouring Plague if (AuraEffect const* aurEff = caster->GetDummyAuraEffect(SPELLFAMILY_PRIEST, 3790, 1)) { - int32 basepoints0 = aurEff->GetAmount() * GetEffect(0)->GetTotalTicks() * caster->SpellDamageBonus(target, GetSpellInfo(), GetEffect(0)->GetAmount(), DOT) / 100; + uint32 damage = caster->SpellDamageBonusDone(target, GetSpellInfo(), GetEffect(0)->GetAmount(), DOT); + damage = target->SpellDamageBonusTaken(caster, GetSpellInfo(), damage, DOT); + int32 basepoints0 = aurEff->GetAmount() * GetEffect(0)->GetTotalTicks() * int32(damage) / 100; int32 heal = int32(CalculatePctN(basepoints0, 15)); + caster->CastCustomSpell(target, 63675, &basepoints0, NULL, NULL, true, NULL, GetEffect(0)); caster->CastCustomSpell(caster, 75999, &heal, NULL, NULL, true, NULL, GetEffect(0)); } @@ -1224,7 +1227,10 @@ void Aura::HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, b // Empowered Renew if (AuraEffect const* aurEff = caster->GetDummyAuraEffect(SPELLFAMILY_PRIEST, 3021, 1)) { - int32 basepoints0 = aurEff->GetAmount() * GetEffect(0)->GetTotalTicks() * caster->SpellHealingBonus(target, GetSpellInfo(), GetEffect(0)->GetAmount(), HEAL) / 100; + uint32 damage = caster->SpellHealingBonusDone(target, GetSpellInfo(), GetEffect(0)->GetAmount(), HEAL); + damage = target->SpellHealingBonusTaken(caster, GetSpellInfo(), damage, HEAL); + + int32 basepoints0 = aurEff->GetAmount() * GetEffect(0)->GetTotalTicks() * int32(damage) / 100; caster->CastCustomSpell(target, 63544, &basepoints0, NULL, NULL, true, NULL, GetEffect(0)); } } @@ -2243,7 +2249,7 @@ void Aura::CallScriptEffectCalcSpellModHandlers(AuraEffect const* aurEff, SpellM } } -void Aura::CallScriptEffectAbsorbHandlers(AuraEffect* aurEff, AuraApplication const* aurApp, DamageInfo & dmgInfo, uint32 & absorbAmount, bool & /*defaultPrevented*/) +void Aura::CallScriptEffectAbsorbHandlers(AuraEffect* aurEff, AuraApplication const* aurApp, DamageInfo & dmgInfo, uint32 & absorbAmount, bool& defaultPrevented) { for (std::list<AuraScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr) { @@ -2254,6 +2260,7 @@ void Aura::CallScriptEffectAbsorbHandlers(AuraEffect* aurEff, AuraApplication co if ((*effItr).IsEffectAffected(m_spellInfo, aurEff->GetEffIndex())) (*effItr).Call(*scritr, aurEff, dmgInfo, absorbAmount); } + defaultPrevented = (*scritr)->_IsDefaultActionPrevented(); (*scritr)->_FinishScriptCall(); } } diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 942f9dc7e86..de432229e2c 100755 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -1008,7 +1008,7 @@ void Spell::SelectImplicitNearbyTargets(SpellEffIndex effIndex, SpellImplicitTar { case TARGET_OBJECT_TYPE_UNIT: if (Unit* unitTarget = target->ToUnit()) - AddUnitTarget(unitTarget, effMask, false); + AddUnitTarget(unitTarget, effMask, true, false); break; case TARGET_OBJECT_TYPE_GOBJ: if (GameObject* gobjTarget = target->ToGameObject()) @@ -1055,7 +1055,7 @@ void Spell::SelectImplicitConeTargets(SpellEffIndex effIndex, SpellImplicitTarge if ((*j)->IsAffectedOnSpell(m_spellInfo)) maxTargets += (*j)->GetAmount(); - Trinity::RandomResizeList(targets, maxTargets); + Trinity::Containers::RandomResizeList(targets, maxTargets); } // for compability with older code - add only unit and go targets @@ -1350,7 +1350,7 @@ void Spell::SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTarge if (m_spellInfo->Id == 5246) //Intimidating Shout unitTargets.remove(m_targets.GetUnitTarget()); - Trinity::RandomResizeList(unitTargets, maxTargets); + Trinity::Containers::RandomResizeList(unitTargets, maxTargets); } CallScriptAfterUnitTargetSelectHandlers(unitTargets, effIndex); @@ -1368,7 +1368,7 @@ void Spell::SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTarge if ((*j)->IsAffectedOnSpell(m_spellInfo)) maxTargets += (*j)->GetAmount(); - Trinity::RandomResizeList(gObjTargets, maxTargets); + Trinity::Containers::RandomResizeList(gObjTargets, maxTargets); } for (std::list<GameObject*>::iterator itr = gObjTargets.begin(); itr != gObjTargets.end(); ++itr) AddGOTarget(*itr, effMask); @@ -1544,7 +1544,7 @@ void Spell::SelectImplicitTargetObjectTargets(SpellEffIndex effIndex, SpellImpli { ASSERT((m_targets.GetObjectTarget() || m_targets.GetItemTarget()) && "Spell::SelectImplicitTargetObjectTargets - no explicit object or item target available!"); if (Unit* unit = m_targets.GetUnitTarget()) - AddUnitTarget(unit, 1 << effIndex); + AddUnitTarget(unit, 1 << effIndex, true, false); else if (GameObject* gobj = m_targets.GetGOTarget()) AddGOTarget(gobj, 1 << effIndex); else @@ -2077,7 +2077,7 @@ void Spell::CleanupTargetList() m_delayMoment = 0; } -void Spell::AddUnitTarget(Unit* target, uint32 effectMask, bool checkIfValid /*= true*/) +void Spell::AddUnitTarget(Unit* target, uint32 effectMask, bool checkIfValid /*= true*/, bool implicit /*= true*/) { for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex) if (!m_spellInfo->Effects[effIndex].IsEffect() || !CheckEffectTarget(target, effIndex)) @@ -2088,7 +2088,7 @@ void Spell::AddUnitTarget(Unit* target, uint32 effectMask, bool checkIfValid /*= return; if (checkIfValid) - if (m_spellInfo->CheckTarget(m_caster, target, true) != SPELL_CAST_OK) + if (m_spellInfo->CheckTarget(m_caster, target, implicit) != SPELL_CAST_OK) return; // Check for effect immune skip if immuned @@ -2442,13 +2442,13 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target) else procEx |= PROC_EX_NORMAL_HIT; - // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge) - if (canEffectTrigger && missInfo != SPELL_MISS_REFLECT) - caster->ProcDamageAndSpell(unitTarget, procAttacker, procVictim, procEx, addhealth, m_attackType, m_spellInfo, m_triggeredByAuraSpell); - int32 gain = caster->HealBySpell(unitTarget, m_spellInfo, addhealth, crit); unitTarget->getHostileRefManager().threatAssist(caster, float(gain) * 0.5f, m_spellInfo); m_healing = gain; + + // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge) + if (canEffectTrigger && missInfo != SPELL_MISS_REFLECT) + caster->ProcDamageAndSpell(unitTarget, procAttacker, procVictim, procEx, addhealth, m_attackType, m_spellInfo, m_triggeredByAuraSpell); } // Do damage and triggers else if (m_damage > 0) @@ -2475,15 +2475,16 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target) caster->ToPlayer()->CastItemCombatSpell(unitTarget, m_attackType, procVictim, procEx); } - caster->DealSpellDamage(&damageInfo, true); - // Haunt if (m_spellInfo->SpellFamilyName == SPELLFAMILY_WARLOCK && m_spellInfo->SpellFamilyFlags[1] & 0x40000 && m_spellAura && m_spellAura->GetEffect(1)) { AuraEffect* aurEff = m_spellAura->GetEffect(1); aurEff->SetAmount(CalculatePctU(aurEff->GetAmount(), damageInfo.damage)); } + m_damage = damageInfo.damage; + + caster->DealSpellDamage(&damageInfo, true); } // Passive spell hits/misses or active spells only misses (only triggers) else @@ -2504,7 +2505,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target) } } - if (missInfo != SPELL_MISS_EVADE && m_caster && !m_caster->IsFriendlyTo(unit) && !m_spellInfo->IsPositive()) + if (missInfo != SPELL_MISS_EVADE && m_caster && !m_caster->IsFriendlyTo(unit) && (!m_spellInfo->IsPositive() || m_spellInfo->HasEffect(SPELL_EFFECT_DISPEL))) { m_caster->CombatStart(unit, !(m_spellInfo->AttributesEx3 & SPELL_ATTR3_NO_INITIAL_AGGRO)); @@ -2745,18 +2746,18 @@ void Spell::DoTriggersOnSpellHit(Unit* unit, uint8 effMask) if (!m_hitTriggerSpells.empty()) { int _duration = 0; - for (HitTriggerSpells::const_iterator i = m_hitTriggerSpells.begin(); i != m_hitTriggerSpells.end(); ++i) + for (HitTriggerSpellList::const_iterator i = m_hitTriggerSpells.begin(); i != m_hitTriggerSpells.end(); ++i) { - if (CanExecuteTriggersOnHit(effMask, i->first) && roll_chance_i(i->second)) + if (CanExecuteTriggersOnHit(effMask, i->triggeredByAura) && roll_chance_i(i->chance)) { - m_caster->CastSpell(unit, i->first, true); - sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "Spell %d triggered spell %d by SPELL_AURA_ADD_TARGET_TRIGGER aura", m_spellInfo->Id, i->first->Id); + m_caster->CastSpell(unit, i->triggeredSpell, true); + sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "Spell %d triggered spell %d by SPELL_AURA_ADD_TARGET_TRIGGER aura", m_spellInfo->Id, i->triggeredSpell->Id); // SPELL_AURA_ADD_TARGET_TRIGGER auras shouldn't trigger auras without duration // set duration of current aura to the triggered spell - if (i->first->GetDuration() == -1) + if (i->triggeredSpell->GetDuration() == -1) { - if (Aura* triggeredAur = unit->GetAura(i->first->Id, m_caster->GetGUID())) + if (Aura* triggeredAur = unit->GetAura(i->triggeredSpell->Id, m_caster->GetGUID())) { // get duration from aura-only once if (!_duration) @@ -3101,11 +3102,20 @@ void Spell::cast(bool skipCheck) return; } - // now that we've done the basic check, now run the scripts - // should be done before the spell is actually executed if (Player* playerCaster = m_caster->ToPlayer()) + { + // now that we've done the basic check, now run the scripts + // should be done before the spell is actually executed sScriptMgr->OnPlayerSpellCast(playerCaster, this, skipCheck); + // As of 3.0.2 pets begin attacking their owner's target immediately + // Let any pets know we've attacked something. Check DmgClass for harmful spells only + // This prevents spells such as Hunter's Mark from triggering pet attack + if (this->GetSpellInfo()->DmgClass != SPELL_DAMAGE_CLASS_NONE) + if (Pet* playerPet = playerCaster->GetPet()) + if (playerPet->isAlive() && playerPet->isControlled() && (m_targets.GetTargetMask() & TARGET_FLAG_UNIT)) + playerPet->AI()->OwnerAttacked(m_targets.GetObjectTarget()->ToUnit()); + } SetExecutedCurrently(true); if (m_caster->GetTypeId() != TYPEID_PLAYER && m_targets.GetUnitTarget() && m_targets.GetUnitTarget() != m_caster) @@ -3423,29 +3433,13 @@ void Spell::_handle_immediate_phase() return; // Handle procs on cast // TODO: finish new proc system:P - if (m_UniqueTargetInfo.empty()) + if (m_UniqueTargetInfo.empty() && m_targets.HasDst()) { uint32 procAttacker = m_procAttacker; if (!procAttacker) - { - bool positive = m_spellInfo->IsPositive(); - switch (m_spellInfo->DmgClass) - { - case SPELL_DAMAGE_CLASS_MAGIC: - if (positive) - procAttacker |= PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS; - else - procAttacker |= PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG; - break; - case SPELL_DAMAGE_CLASS_NONE: - if (positive) - procAttacker |= PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS; - else - procAttacker |= PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG; - break; - } - } - // Proc damage for spells which have only dest targets (2484 should proc 51486 for example) + procAttacker |= PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS; + + // Proc the spells that have DEST target m_originalCaster->ProcDamageAndSpell(NULL, procAttacker, 0, m_procEx | PROC_EX_NORMAL_HIT, 0, BASE_ATTACK, m_spellInfo, m_triggeredByAuraSpell); } } @@ -4331,10 +4325,9 @@ void Spell::TakePower() for (std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit) if (ihit->targetGUID == targetGUID) { - if (ihit->missCondition != SPELL_MISS_NONE && ihit->missCondition != SPELL_MISS_MISS/* && ihit->targetGUID != m_caster->GetGUID()*/) - hit = false; if (ihit->missCondition != SPELL_MISS_NONE) { + hit = false; //lower spell cost on fail (by talent aura) if (Player* modOwner = m_caster->ToPlayer()->GetSpellModOwner()) modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_SPELL_COST_REFUND_ON_FAIL, m_powerCost); @@ -4994,35 +4987,12 @@ SpellCastResult Spell::CheckCast(bool strict) { case SPELL_EFFECT_DUMMY: { - if (m_spellInfo->Id == 51582) // Rocket Boots Engaged - { - if (m_caster->IsInWater()) - return SPELL_FAILED_ONLY_ABOVEWATER; - } - else if (m_spellInfo->SpellIconID == 156) // Holy Shock - { - // spell different for friends and enemies - // hurt version required facing - if (m_targets.GetUnitTarget() && !m_caster->IsFriendlyTo(m_targets.GetUnitTarget()) && !m_caster->HasInArc(static_cast<float>(M_PI), m_targets.GetUnitTarget())) - return SPELL_FAILED_UNIT_NOT_INFRONT; - } - else if (m_spellInfo->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT && m_spellInfo->SpellFamilyFlags[0] == 0x2000) // Death Coil (DeathKnight) - { - Unit* target = m_targets.GetUnitTarget(); - if (!target || (target->IsFriendlyTo(m_caster) && target->GetCreatureType() != CREATURE_TYPE_UNDEAD)) - return SPELL_FAILED_BAD_TARGETS; - } - else if (m_spellInfo->Id == 19938) // Awaken Peon + if (m_spellInfo->Id == 19938) // Awaken Peon { Unit* unit = m_targets.GetUnitTarget(); if (!unit || !unit->HasAura(17743)) return SPELL_FAILED_BAD_TARGETS; } - else if (m_spellInfo->Id == 52264) // Deliver Stolen Horse - { - if (!m_caster->FindNearestCreature(28653, 5)) - return SPELL_FAILED_OUT_OF_RANGE; - } else if (m_spellInfo->Id == 31789) // Righteous Defense { if (m_caster->GetTypeId() != TYPEID_PLAYER) @@ -5230,10 +5200,8 @@ SpellCastResult Spell::CheckCast(bool strict) case SPELL_EFFECT_SUMMON_DEAD_PET: { Creature* pet = m_caster->GetGuardianPet(); - if (!pet) - return SPELL_FAILED_NO_PET; - if (pet->isAlive()) + if (pet && pet->isAlive()) return SPELL_FAILED_ALREADY_HAVE_SUMMON; break; @@ -5283,7 +5251,6 @@ SpellCastResult Spell::CheckCast(bool strict) if (m_caster->GetCharmGUID()) return SPELL_FAILED_ALREADY_HAVE_CHARM; - break; } case SPELL_EFFECT_SUMMON_PLAYER: @@ -5358,8 +5325,7 @@ SpellCastResult Spell::CheckCast(bool strict) if (m_caster->GetTypeId() == TYPEID_PLAYER && m_spellInfo->Id == 781 && !m_caster->isInCombat()) return SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW; - Unit* target = m_targets.GetUnitTarget(); - if (m_caster == target && m_caster->HasUnitState(UNIT_STATE_ROOT)) + if (m_caster->HasUnitState(UNIT_STATE_ROOT)) { if (m_caster->GetTypeId() == TYPEID_PLAYER) return SPELL_FAILED_ROOTED; @@ -7171,14 +7137,13 @@ void Spell::CallScriptAfterUnitTargetSelectHandlers(std::list<Unit*>& unitTarget } } -bool Spell::CanExecuteTriggersOnHit(uint8 effMask, SpellInfo const* spellInfo) const +bool Spell::CanExecuteTriggersOnHit(uint8 effMask, SpellInfo const* triggeredByAura) const { - bool only_on_dummy = (spellInfo && (spellInfo->AttributesEx4 & SPELL_ATTR4_PROC_ONLY_ON_DUMMY)); - // If triggered spell has SPELL_ATTR4_PROC_ONLY_ON_DUMMY then it can only proc on a casted spell with SPELL_EFFECT_DUMMY - // If triggered spell doesn't have SPELL_ATTR4_PROC_ONLY_ON_DUMMY then it can NOT proc on SPELL_EFFECT_DUMMY (needs confirmation) + bool only_on_caster = (triggeredByAura && (triggeredByAura->AttributesEx4 & SPELL_ATTR4_PROC_ONLY_ON_CASTER)); + // If triggeredByAura has SPELL_ATTR4_PROC_ONLY_ON_CASTER then it can only proc on a casted spell with TARGET_UNIT_CASTER for (uint8 i = 0;i < MAX_SPELL_EFFECTS; ++i) { - if ((effMask & (1 << i)) && (only_on_dummy == (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_DUMMY))) + if ((effMask & (1 << i)) && (!only_on_caster || (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_UNIT_CASTER))) return true; } return false; @@ -7230,9 +7195,14 @@ void Spell::PrepareTriggersExecutedOnHit() // calculate the chance using spell base amount, because aura amount is not updated on combo-points change // this possibly needs fixing int32 auraBaseAmount = (*i)->GetBaseAmount(); - int32 chance = m_caster->CalculateSpellDamage(NULL, auraSpellInfo, auraSpellIdx, &auraBaseAmount); // proc chance is stored in effect amount - m_hitTriggerSpells.push_back(std::make_pair(spellInfo, chance * (*i)->GetBase()->GetStackAmount())); + int32 chance = m_caster->CalculateSpellDamage(NULL, auraSpellInfo, auraSpellIdx, &auraBaseAmount); + // build trigger and add to the list + HitTriggerSpell spellTriggerInfo; + spellTriggerInfo.triggeredSpell = spellInfo; + spellTriggerInfo.triggeredByAura = auraSpellInfo; + spellTriggerInfo.chance = chance * (*i)->GetBase()->GetStackAmount(); + m_hitTriggerSpells.push_back(spellTriggerInfo); } } } diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h index 37842433eb3..8f43b9b2290 100755 --- a/src/server/game/Spells/Spell.h +++ b/src/server/game/Spells/Spell.h @@ -596,7 +596,7 @@ class Spell SpellDestination m_destTargets[MAX_SPELL_EFFECTS]; - void AddUnitTarget(Unit* target, uint32 effectMask, bool checkIfValid = true); + void AddUnitTarget(Unit* target, uint32 effectMask, bool checkIfValid = true, bool implicit = true); void AddGOTarget(GameObject* target, uint32 effectMask); void AddItemTarget(Item* item, uint32 effectMask); void AddDestTarget(SpellDestination const& dest, uint32 effIndex); @@ -633,10 +633,18 @@ class Spell void CallScriptAfterUnitTargetSelectHandlers(std::list<Unit*>& unitTargets, SpellEffIndex effIndex); std::list<SpellScript*> m_loadedScripts; - bool CanExecuteTriggersOnHit(uint8 effMask, SpellInfo const* spellInfo = NULL) const; + struct HitTriggerSpell + { + SpellInfo const* triggeredSpell; + SpellInfo const* triggeredByAura; + // uint8 triggeredByEffIdx This might be needed at a later stage - No need known for now + int32 chance; + }; + + bool CanExecuteTriggersOnHit(uint8 effMask, SpellInfo const* triggeredByAura = NULL) const; void PrepareTriggersExecutedOnHit(); - typedef std::list< std::pair<SpellInfo const*, int32> > HitTriggerSpells; - HitTriggerSpells m_hitTriggerSpells; + typedef std::list<HitTriggerSpell> HitTriggerSpellList; + HitTriggerSpellList m_hitTriggerSpells; // effect helpers void SummonGuardian(uint32 i, uint32 entry, SummonPropertiesEntry const* properties, uint32 numSummons); diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index ce64c2e9560..07bea5f980c 100755 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -390,23 +390,6 @@ void Spell::EffectSchoolDMG(SpellEffIndex effIndex) if (!unitTarget->HasAura(27825)) return; break; - // Cataclysmic Bolt - case 38441: - { - damage = unitTarget->CountPctFromMaxHealth(50); - break; - } - case 20625: // Ritual of Doom Sacrifice - case 29142: // Eyesore Blaster - case 35139: // Throw Boom's Doom - case 42393: // Brewfest - Attack Keg - case 55269: // Deathly Stare - case 56578: // Rapid-Fire Harpoon - case 62775: // Tympanic Tantrum - { - damage = unitTarget->CountPctFromMaxHealth(damage); - break; - } // Gargoyle Strike case 51963: { @@ -484,7 +467,8 @@ void Spell::EffectSchoolDMG(SpellEffIndex effIndex) if (aura) { uint32 pdamage = uint32(std::max(aura->GetAmount(), 0)); - pdamage = m_caster->SpellDamageBonus(unitTarget, aura->GetSpellInfo(), pdamage, DOT, aura->GetBase()->GetStackAmount()); + pdamage = m_caster->SpellDamageBonusDone(unitTarget, aura->GetSpellInfo(), pdamage, DOT, aura->GetBase()->GetStackAmount()); + pdamage = unitTarget->SpellDamageBonusTaken(m_caster, aura->GetSpellInfo(), pdamage, DOT, aura->GetBase()->GetStackAmount()); uint32 pct_dir = m_caster->CalculateSpellDamage(unitTarget, m_spellInfo, (effIndex + 1)); uint8 baseTotalTicks = uint8(m_caster->CalcSpellDuration(aura->GetSpellInfo()) / aura->GetSpellInfo()->Effects[EFFECT_0].Amplitude); damage += int32(CalculatePctU(pdamage * baseTotalTicks, pct_dir)); @@ -522,7 +506,8 @@ void Spell::EffectSchoolDMG(SpellEffIndex effIndex) // Shadow Word: Death - deals damage equal to damage done to caster if (m_spellInfo->SpellFamilyFlags[1] & 0x2) { - int32 back_damage = m_caster->SpellDamageBonus(unitTarget, m_spellInfo, (uint32)damage, SPELL_DIRECT_DAMAGE); + int32 back_damage = m_caster->SpellDamageBonusDone(unitTarget, m_spellInfo, (uint32)damage, SPELL_DIRECT_DAMAGE); + back_damage = unitTarget->SpellDamageBonusTaken(m_caster, m_spellInfo, (uint32)back_damage, SPELL_DIRECT_DAMAGE); // Pain and Suffering reduces damage if (AuraEffect* aurEff = m_caster->GetDummyAuraEffect(SPELLFAMILY_PRIEST, 2874, 0)) AddPctN(back_damage, -aurEff->GetAmount()); @@ -666,19 +651,19 @@ void Spell::EffectSchoolDMG(SpellEffIndex effIndex) if (found) damage += m_spellInfo->Effects[EFFECT_1].CalcValue(); - if (m_caster->GetTypeId() == TYPEID_PLAYER) + if (Player* caster = m_caster->ToPlayer()) { // Add Ammo and Weapon damage plus RAP * 0.1 - Item* item = m_caster->ToPlayer()->GetWeaponForAttack(RANGED_ATTACK); - if (item) + if (Item* item = caster->GetWeaponForAttack(RANGED_ATTACK)) { - float dmg_min = item->GetTemplate()->Damage->DamageMin; - float dmg_max = item->GetTemplate()->Damage->DamageMax; + ItemTemplate const* weaponTemplate = item->GetTemplate(); + float dmg_min = weaponTemplate->Damage[0].DamageMin; + float dmg_max = weaponTemplate->Damage[0].DamageMax; if (dmg_max == 0.0f && dmg_min > dmg_max) damage += int32(dmg_min); else damage += irand(int32(dmg_min), int32(dmg_max)); - damage += int32(m_caster->ToPlayer()->GetAmmoDPS()*item->GetTemplate()->Delay*0.001f); + damage += int32(caster->GetAmmoDPS() * weaponTemplate->Delay * 0.001f); } } } @@ -729,7 +714,10 @@ void Spell::EffectSchoolDMG(SpellEffIndex effIndex) } if (m_originalCaster && damage > 0 && apply_direct_bonus) - damage = m_originalCaster->SpellDamageBonus(unitTarget, m_spellInfo, (uint32)damage, SPELL_DIRECT_DAMAGE); + { + damage = m_originalCaster->SpellDamageBonusDone(unitTarget, m_spellInfo, (uint32)damage, SPELL_DIRECT_DAMAGE); + damage = unitTarget->SpellDamageBonusTaken(m_originalCaster, m_spellInfo, (uint32)damage, SPELL_DIRECT_DAMAGE); + } m_damage += damage; } @@ -774,7 +762,7 @@ void Spell::EffectDummy(SpellEffIndex effIndex) uint32 maxTargets = std::min<uint32>(3, attackers.size()); for (uint32 i = 0; i < maxTargets; ++i) { - Unit* attacker = SelectRandomContainerElement(attackers); + Unit* attacker = Trinity::Containers::SelectRandomContainerElement(attackers); AddUnitTarget(attacker, 1 << 1); attackers.erase(attacker); } @@ -1102,10 +1090,6 @@ void Spell::EffectForceCast(SpellEffIndex effIndex) case 52349: // Overtake unitTarget->CastCustomSpell(unitTarget, spellInfo->Id, &damage, NULL, NULL, true, NULL, NULL, m_originalCasterGUID); return; - case 72378: // Blood Nova - case 73058: // Blood Nova - m_caster->CastSpell(unitTarget, damage, true); // additional spell cast - break; } } @@ -1412,7 +1396,8 @@ void Spell::EffectPowerDrain(SpellEffIndex effIndex) return; // add spell damage bonus - damage = m_caster->SpellDamageBonus(unitTarget, m_spellInfo, uint32(damage), SPELL_DIRECT_DAMAGE); + damage = m_caster->SpellDamageBonusDone(unitTarget, m_spellInfo, uint32(damage), SPELL_DIRECT_DAMAGE); + damage = unitTarget->SpellDamageBonusTaken(m_caster, m_spellInfo, uint32(damage), SPELL_DIRECT_DAMAGE); // resilience reduce mana draining effect at spell crit damage reduction (added in 2.4) int32 power = damage; @@ -1575,7 +1560,7 @@ void Spell::EffectHeal(SpellEffIndex /*effIndex*/) int32 tickheal = targetAura->GetAmount(); if (Unit* auraCaster = targetAura->GetCaster()) - tickheal = auraCaster->SpellHealingBonus(unitTarget, targetAura->GetSpellInfo(), tickheal, DOT); + tickheal = auraCaster->SpellHealingBonusDone(unitTarget, targetAura->GetSpellInfo(), tickheal, DOT); //int32 tickheal = targetAura->GetSpellInfo()->EffectBasePoints[idx] + 1; //It is said that talent bonus should not be included @@ -1596,11 +1581,12 @@ void Spell::EffectHeal(SpellEffIndex /*effIndex*/) //addhealth += tickheal * tickcount; //addhealth = caster->SpellHealingBonus(m_spellInfo, addhealth, HEAL, unitTarget); } - // Glyph of Nourish + // Nourish else if (m_spellInfo->SpellFamilyName == SPELLFAMILY_DRUID && m_spellInfo->SpellFamilyFlags[1] & 0x2000000) { - addhealth = caster->SpellHealingBonus(unitTarget, m_spellInfo, addhealth, HEAL); + addhealth = caster->SpellHealingBonusDone(unitTarget, m_spellInfo, addhealth, HEAL); + // Glyph of Nourish if (AuraEffect const* aurEff = m_caster->GetAuraEffect(62971, 0)) { Unit::AuraEffectList const& Periodic = unitTarget->GetAuraEffectsByType(SPELL_AURA_PERIODIC_HEAL); @@ -1611,25 +1597,13 @@ void Spell::EffectHeal(SpellEffIndex /*effIndex*/) } } } - // Lifebloom - final heal coef multiplied by original DoT stack - else if (m_spellInfo->Id == 33778) - addhealth = caster->SpellHealingBonus(unitTarget, m_spellInfo, addhealth, HEAL, m_spellValue->EffectBasePoints[1]); - // Riptide - increase healing done by Chain Heal - else if (m_spellInfo->SpellFamilyName == SPELLFAMILY_SHAMAN && m_spellInfo->SpellFamilyFlags[0] & 0x100) - { - addhealth = caster->SpellHealingBonus(unitTarget, m_spellInfo, addhealth, HEAL); - if (AuraEffect* aurEff = unitTarget->GetAuraEffect(SPELL_AURA_PERIODIC_HEAL, SPELLFAMILY_SHAMAN, 0, 0, 0x10, m_originalCasterGUID)) - { - addhealth = int32(addhealth * 1.25f); - // consume aura - unitTarget->RemoveAura(aurEff->GetBase()); - } - } // Death Pact - return pct of max health to caster else if (m_spellInfo->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT && m_spellInfo->SpellFamilyFlags[0] & 0x00080000) - addhealth = caster->SpellHealingBonus(unitTarget, m_spellInfo, int32(caster->CountPctFromMaxHealth(damage)), HEAL); + addhealth = caster->SpellHealingBonusDone(unitTarget, m_spellInfo, int32(caster->CountPctFromMaxHealth(damage)), HEAL); else - addhealth = caster->SpellHealingBonus(unitTarget, m_spellInfo, addhealth, HEAL); + addhealth = caster->SpellHealingBonusDone(unitTarget, m_spellInfo, addhealth, HEAL); + + addhealth = unitTarget->SpellHealingBonusTaken(caster, m_spellInfo, addhealth, HEAL); // Remove Grievious bite if fully healed if (unitTarget->HasAura(48920) && (unitTarget->GetHealth() + addhealth >= unitTarget->GetMaxHealth())) @@ -1655,7 +1629,10 @@ void Spell::EffectHealPct(SpellEffIndex /*effIndex*/) if (m_spellInfo->Id == 59754 && unitTarget == m_caster) return; - m_healing += m_originalCaster->SpellHealingBonus(unitTarget, m_spellInfo, unitTarget->CountPctFromMaxHealth(damage), HEAL); + uint32 heal = m_originalCaster->SpellHealingBonusDone(unitTarget, m_spellInfo, unitTarget->CountPctFromMaxHealth(damage), HEAL); + heal = unitTarget->SpellHealingBonusTaken(m_originalCaster, m_spellInfo, heal, HEAL); + + m_healing += heal; } void Spell::EffectHealMechanical(SpellEffIndex /*effIndex*/) @@ -1670,7 +1647,9 @@ void Spell::EffectHealMechanical(SpellEffIndex /*effIndex*/) if (!m_originalCaster) return; - m_healing += m_originalCaster->SpellHealingBonus(unitTarget, m_spellInfo, uint32(damage), HEAL); + uint32 heal = m_originalCaster->SpellHealingBonusDone(unitTarget, m_spellInfo, uint32(damage), HEAL); + + m_healing += unitTarget->SpellHealingBonusTaken(m_originalCaster, m_spellInfo, heal, HEAL); } void Spell::EffectHealthLeech(SpellEffIndex effIndex) @@ -1681,7 +1660,8 @@ void Spell::EffectHealthLeech(SpellEffIndex effIndex) if (!unitTarget || !unitTarget->isAlive() || damage < 0) return; - damage = m_caster->SpellDamageBonus(unitTarget, m_spellInfo, uint32(damage), SPELL_DIRECT_DAMAGE); + damage = m_caster->SpellDamageBonusDone(unitTarget, m_spellInfo, uint32(damage), SPELL_DIRECT_DAMAGE); + damage = unitTarget->SpellDamageBonusTaken(m_caster, m_spellInfo, uint32(damage), SPELL_DIRECT_DAMAGE); sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "HealthLeech :%i", damage); @@ -1693,7 +1673,9 @@ void Spell::EffectHealthLeech(SpellEffIndex effIndex) if (m_caster->isAlive()) { - healthGain = m_caster->SpellHealingBonus(m_caster, m_spellInfo, healthGain, HEAL); + healthGain = m_caster->SpellHealingBonusDone(m_caster, m_spellInfo, healthGain, HEAL); + healthGain = m_caster->SpellHealingBonusTaken(m_caster, m_spellInfo, healthGain, HEAL); + m_caster->HealBySpell(m_caster, m_spellInfo, uint32(healthGain)); } } @@ -2008,7 +1990,7 @@ void Spell::EffectEnergize(SpellEffIndex effIndex) if (!avalibleElixirs.empty()) { // cast random elixir on target - m_caster->CastSpell(unitTarget, SelectRandomContainerElement(avalibleElixirs), true, m_CastItem); + m_caster->CastSpell(unitTarget, Trinity::Containers::SelectRandomContainerElement(avalibleElixirs), true, m_CastItem); } } } @@ -3387,7 +3369,7 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex) if (m_spellInfo->Id == 20467) { spell_bonus += int32(0.08f * m_caster->GetTotalAttackPowerValue(BASE_ATTACK)); - spell_bonus += int32(0.13f * m_caster->SpellBaseDamageBonus(m_spellInfo->GetSchoolMask())); + spell_bonus += int32(0.13f * m_caster->SpellBaseDamageBonusDone(m_spellInfo->GetSchoolMask())); } break; } @@ -3556,8 +3538,9 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex) uint32 eff_damage(std::max(weaponDamage, 0)); // Add melee damage bonuses (also check for negative) - m_caster->MeleeDamageBonus(unitTarget, &eff_damage, m_attackType, m_spellInfo); - m_damage += eff_damage; + uint32 damage = m_caster->MeleeDamageBonusDone(unitTarget, eff_damage, m_attackType, m_spellInfo); + + m_damage += unitTarget->MeleeDamageBonusTaken(m_caster, damage, m_attackType, m_spellInfo); } void Spell::EffectThreat(SpellEffIndex /*effIndex*/) @@ -3600,7 +3583,10 @@ void Spell::EffectHealMaxHealth(SpellEffIndex /*effIndex*/) addhealth = unitTarget->GetMaxHealth() - unitTarget->GetHealth(); if (m_originalCaster) - m_healing += m_originalCaster->SpellHealingBonus(unitTarget, m_spellInfo, addhealth, HEAL); + { + uint32 heal = m_originalCaster->SpellHealingBonusDone(unitTarget, m_spellInfo, addhealth, HEAL); + m_healing += unitTarget->SpellHealingBonusTaken(m_originalCaster, m_spellInfo, heal, HEAL); + } } void Spell::EffectInterruptCast(SpellEffIndex effIndex) @@ -5726,7 +5712,7 @@ void Spell::EffectSummonDeadPet(SpellEffIndex /*effIndex*/) return; Pet* pet = player->GetPet(); - if (!pet || pet->isAlive()) + if (pet && pet->isAlive()) return; if (damage < 0) @@ -5734,6 +5720,14 @@ void Spell::EffectSummonDeadPet(SpellEffIndex /*effIndex*/) float x, y, z; player->GetPosition(x, y, z); + if (!pet) + { + player->SummonPet(0, x, y, z, player->GetOrientation(), SUMMON_PET, 0); + pet = player->GetPet(); + } + if (!pet) + return; + player->GetMap()->CreatureRelocation(pet, x, y, z, player->GetOrientation()); pet->SetUInt32Value(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_NONE); diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index b95ee766f38..a931f759163 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -351,7 +351,7 @@ bool SpellEffectInfo::IsEffect() const bool SpellEffectInfo::IsEffect(SpellEffects effectName) const { - return Effect == effectName; + return Effect == uint32(effectName); } bool SpellEffectInfo::IsAura() const @@ -1972,6 +1972,33 @@ uint32 SpellInfo::CalcCastTime(Unit* caster, Spell* spell) const return (castTime > 0) ? uint32(castTime) : 0; } +uint32 SpellInfo::GetMaxTicks() const +{ + int32 DotDuration = GetDuration(); + if (DotDuration == 0) + return 1; + + // 200% limit + if (DotDuration > 30000) + DotDuration = 30000; + + for (uint8 x = 0; x < MAX_SPELL_EFFECTS; x++) + { + if (Effects[x].Effect == SPELL_EFFECT_APPLY_AURA) + switch (Effects[x].ApplyAuraName) + { + case SPELL_AURA_PERIODIC_DAMAGE: + case SPELL_AURA_PERIODIC_HEAL: + case SPELL_AURA_PERIODIC_LEECH: + if (Effects[x].Amplitude != 0) + return DotDuration / Effects[x].Amplitude; + break; + } + } + + return 6; +} + uint32 SpellInfo::GetRecoveryTime() const { return RecoveryTime > CategoryRecoveryTime ? RecoveryTime : CategoryRecoveryTime; @@ -2177,12 +2204,12 @@ bool SpellInfo::_IsPositiveEffect(uint8 effIndex, bool deep) const switch (Id) { case 34700: // Allergic Reaction - case 61716: // Rabbit Costume - case 61734: // Noblegarden Bunny case 61987: // Avenging Wrath Marker case 61988: // Divine Shield exclude aura case 62532: // Conservator's Grip return false; + case 61716: // Rabbit Costume + case 61734: // Noblegarden Bunny case 30877: // Tag Murloc case 62344: // Fists of Stone return true; diff --git a/src/server/game/Spells/SpellInfo.h b/src/server/game/Spells/SpellInfo.h index b82f7dbd61d..54430cd7116 100644 --- a/src/server/game/Spells/SpellInfo.h +++ b/src/server/game/Spells/SpellInfo.h @@ -440,6 +440,8 @@ public: int32 GetDuration() const; int32 GetMaxDuration() const; + uint32 GetMaxTicks() const; + uint32 CalcCastTime(Unit* caster = NULL, Spell* spell = NULL) const; uint32 GetRecoveryTime() const; diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index 895dc9ab4b7..06e4978eb58 100755 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -1602,7 +1602,7 @@ void SpellMgr::LoadSpellGroups() uint32 group_id = fields[0].GetUInt32(); if (group_id <= SPELL_GROUP_DB_RANGE_MIN && group_id >= SPELL_GROUP_CORE_RANGE_MAX) { - sLog->outErrorDb("SpellGroup id %u listed in `spell_groups` is in core range, but is not defined in core!", group_id); + sLog->outErrorDb("SpellGroup id %u listed in `spell_group` is in core range, but is not defined in core!", group_id); continue; } int32 spell_id = fields[1].GetInt32(); @@ -1618,7 +1618,7 @@ void SpellMgr::LoadSpellGroups() { if (groups.find(abs(itr->second)) == groups.end()) { - sLog->outErrorDb("SpellGroup id %u listed in `spell_groups` does not exist", abs(itr->second)); + sLog->outErrorDb("SpellGroup id %u listed in `spell_group` does not exist", abs(itr->second)); mSpellGroupSpell.erase(itr++); } else @@ -2094,7 +2094,7 @@ void SpellMgr::LoadEnchantCustomAttr() continue; // TODO: find a better check - if (!(spellInfo->AttributesEx2 & SPELL_ATTR2_UNK13) || !(spellInfo->Attributes & SPELL_ATTR0_NOT_SHAPESHIFT)) + if (!(spellInfo->AttributesEx2 & SPELL_ATTR2_PRESERVE_ENCHANT_IN_ARENA) || !(spellInfo->Attributes & SPELL_ATTR0_NOT_SHAPESHIFT)) continue; for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j) @@ -3238,6 +3238,10 @@ void SpellMgr::LoadDbcDataCorrections() spellInfo->EffectDieSides[0] = 0; // was 1, that should probably mean seat 0, but instead it's treated as spell 1 spellInfo->EffectBasePoints[0] = 52391; // Ride Vehicle (forces seat 0) break; + case 64745: // Item - Death Knight T8 Tank 4P Bonus + case 64936: // Item - Warrior T8 Protection 4P Bonus + spellInfo->EffectBasePoints[0] = 100; // 100% chance of procc'ing, not -10% (chance calculated in PrepareTriggersExecutedOnHit) + break; case 19970: // Entangling Roots (Rank 6) -- Nature's Grasp Proc case 19971: // Entangling Roots (Rank 5) -- Nature's Grasp Proc case 19972: // Entangling Roots (Rank 4) -- Nature's Grasp Proc @@ -3294,6 +3298,19 @@ void SpellMgr::LoadDbcDataCorrections() spellInfo->EffectImplicitTargetB[1] = TARGET_UNIT_NEARBY_ENTRY; spellInfo->EffectImplicitTargetB[2] = TARGET_UNIT_NEARBY_ENTRY; break; + case 62301: // Cosmic Smash (Algalon the Observer) + spellInfo->MaxAffectedTargets = 1; + break; + case 64598: // Cosmic Smash (Algalon the Observer) + spellInfo->MaxAffectedTargets = 3; + break; + case 62293: // Cosmic Smash (Algalon the Observer) + spellInfo->EffectImplicitTargetB[0] = TARGET_DEST_CASTER; + break; + case 62311: // Cosmic Smash (Algalon the Observer) + case 64596: // Cosmic Smash (Algalon the Observer) + spellInfo->rangeIndex = 6; // 100yd + break; // ENDOF ULDUAR SPELLS // // TRIAL OF THE CRUSADER SPELLS @@ -3329,13 +3346,22 @@ void SpellMgr::LoadDbcDataCorrections() case 70835: // Bone Storm (Lord Marrowgar) case 70836: // Bone Storm (Lord Marrowgar) case 72864: // Death Plague (Rotting Frost Giant) - case 72378: // Blood Nova (Deathbringer Saurfang) - case 73058: // Blood Nova (Deathbringer Saurfang) case 71160: // Plague Stench (Stinky) case 71161: // Plague Stench (Stinky) case 71123: // Decimate (Stinky & Precious) spellInfo->EffectRadiusIndex[0] = EFFECT_RADIUS_100_YARDS; // 100yd break; + case 72378: // Blood Nova (Deathbringer Saurfang) + case 73058: // Blood Nova (Deathbringer Saurfang) + spellInfo->EffectRadiusIndex[0] = EFFECT_RADIUS_200_YARDS; + spellInfo->EffectRadiusIndex[1] = EFFECT_RADIUS_200_YARDS; + break; + case 72769: // Scent of Blood (Deathbringer Saurfang) + spellInfo->EffectRadiusIndex[0] = EFFECT_RADIUS_200_YARDS; + // no break + case 72771: // Scent of Blood (Deathbringer Saurfang) + spellInfo->EffectRadiusIndex[1] = EFFECT_RADIUS_200_YARDS; + break; case 72723: // Resistant Skin (Deathbringer Saurfang adds) // this spell initially granted Shadow damage immunity, however it was removed but the data was left in client spellInfo->Effect[2] = 0; @@ -3343,9 +3369,9 @@ void SpellMgr::LoadDbcDataCorrections() case 70460: // Coldflame Jets (Traps after Saurfang) spellInfo->DurationIndex = 1; // 10 seconds break; - case 71413: // Green Ooze Summon (Professor Putricide) - case 71414: // Orange Ooze Summon (Professor Putricide) - spellInfo->EffectImplicitTargetA[0] = TARGET_DEST_DEST; + case 71412: // Green Ooze Summon (Professor Putricide) + case 71415: // Orange Ooze Summon (Professor Putricide) + spellInfo->EffectImplicitTargetA[0] = TARGET_UNIT_TARGET_ANY; break; case 71159: // Awaken Plagued Zombies spellInfo->DurationIndex = 21; @@ -3406,10 +3432,7 @@ void SpellMgr::LoadDbcDataCorrections() spellInfo->EffectImplicitTargetA[0] = TARGET_DEST_CASTER; break; case 69846: // Frost Bomb - spellInfo->speed = 10; - spellInfo->EffectImplicitTargetA[0] = TARGET_DEST_TARGET_ANY; - spellInfo->EffectImplicitTargetB[0] = TARGET_UNIT_TARGET_ANY; - spellInfo->Effect[1] = 0; + spellInfo->speed = 0.0f; // This spell's summon happens instantly break; case 71614: // Ice Lock spellInfo->Mechanic = MECHANIC_STUN; @@ -3505,6 +3528,11 @@ void SpellMgr::LoadDbcDataCorrections() case 40166: // Introspection case 40167: // Introspection spellInfo->Attributes |= SPELL_ATTR0_NEGATIVE_1; + break; + case 2378: // Minor Fortitude + spellInfo->manaCost = 0; + spellInfo->manaPerSecond = 0; + break; default: break; } diff --git a/src/server/game/Spells/SpellScript.cpp b/src/server/game/Spells/SpellScript.cpp index 81f8bbd78c5..e6ce80c20f0 100755 --- a/src/server/game/Spells/SpellScript.cpp +++ b/src/server/game/Spells/SpellScript.cpp @@ -320,29 +320,34 @@ SpellInfo const* SpellScript::GetSpellInfo() return m_spell->GetSpellInfo(); } -WorldLocation const* SpellScript::GetTargetDest() +WorldLocation const* SpellScript::GetExplTargetDest() { if (m_spell->m_targets.HasDst()) return m_spell->m_targets.GetDstPos(); return NULL; } -void SpellScript::SetTargetDest(WorldLocation& loc) +void SpellScript::SetExplTargetDest(WorldLocation& loc) { m_spell->m_targets.SetDst(loc); } -Unit* SpellScript::GetTargetUnit() +WorldObject* SpellScript::GetExplTargetWorldObject() +{ + return m_spell->m_targets.GetObjectTarget(); +} + +Unit* SpellScript::GetExplTargetUnit() { return m_spell->m_targets.GetUnitTarget(); } -GameObject* SpellScript::GetTargetGObj() +GameObject* SpellScript::GetExplTargetGObj() { return m_spell->m_targets.GetGOTarget(); } -Item* SpellScript::GetTargetItem() +Item* SpellScript::GetExplTargetItem() { return m_spell->m_targets.GetItemTarget(); } @@ -403,7 +408,7 @@ GameObject* SpellScript::GetHitGObj() return m_spell->gameObjTarget; } -WorldLocation const* SpellScript::GetHitDest() +WorldLocation* SpellScript::GetHitDest() { if (!IsInEffectHook()) { @@ -773,6 +778,7 @@ bool AuraScript::_IsDefaultActionPrevented() case AURA_SCRIPT_HOOK_EFFECT_APPLY: case AURA_SCRIPT_HOOK_EFFECT_REMOVE: case AURA_SCRIPT_HOOK_EFFECT_PERIODIC: + case AURA_SCRIPT_HOOK_EFFECT_ABSORB: return m_defaultActionPrevented; default: ASSERT(false && "AuraScript::_IsDefaultActionPrevented is called in a wrong place"); @@ -787,6 +793,7 @@ void AuraScript::PreventDefaultAction() case AURA_SCRIPT_HOOK_EFFECT_APPLY: case AURA_SCRIPT_HOOK_EFFECT_REMOVE: case AURA_SCRIPT_HOOK_EFFECT_PERIODIC: + case AURA_SCRIPT_HOOK_EFFECT_ABSORB: m_defaultActionPrevented = true; break; default: diff --git a/src/server/game/Spells/SpellScript.h b/src/server/game/Spells/SpellScript.h index e84a56c8dbb..7b194b7827f 100755 --- a/src/server/game/Spells/SpellScript.h +++ b/src/server/game/Spells/SpellScript.h @@ -295,25 +295,35 @@ class SpellScript : public _SpellScript SpellInfo const* GetSpellInfo(); SpellValue const* GetSpellValue(); - // methods useable after spell targets are set - // accessors to the "focus" targets of the spell - // note: do not confuse these with spell hit targets + // methods useable after spell is prepared + // accessors to the explicit targets of the spell + // explicit target - target selected by caster (player, game client, or script - DoCast(explicitTarget, ...), required for spell to be cast + // examples: + // -shadowstep - explicit target is the unit you want to go behind of + // -chain heal - explicit target is the unit to be healed first + // -holy nova/arcane explosion - explicit target = NULL because target you are selecting doesn't affect how spell targets are selected + // you can determine if spell requires explicit targets by dbc columns: + // - Targets - mask of explicit target types + // - ImplicitTargetXX set to TARGET_XXX_TARGET_YYY, _TARGET_ here means that explicit target is used by the effect, so spell needs one too + // returns: WorldLocation which was selected as a spell destination or NULL - WorldLocation const* GetTargetDest(); + WorldLocation const* GetExplTargetDest(); - void SetTargetDest(WorldLocation& loc); + void SetExplTargetDest(WorldLocation& loc); - // returns: Unit which was selected as a spell target or NULL - Unit* GetTargetUnit(); + // returns: WorldObject which was selected as an explicit spell target or NULL if there's no target + WorldObject* GetExplTargetWorldObject(); - // returns: GameObject which was selected as a spell target or NULL - GameObject* GetTargetGObj(); + // returns: Unit which was selected as an explicit spell target or NULL if there's no target + Unit* GetExplTargetUnit(); - // returns: Item which was selected as a spell target or NULL - Item* GetTargetItem(); + // returns: GameObject which was selected as an explicit spell target or NULL if there's no target + GameObject* GetExplTargetGObj(); - // methods useable only during spell hit on target, or during spell launch on target: + // returns: Item which was selected as an explicit spell target or NULL if there's no target + Item* GetExplTargetItem(); + // methods useable only during spell hit on target, or during spell launch on target: // returns: target of current effect if it was Unit otherwise NULL Unit* GetHitUnit(); // returns: target of current effect if it was Creature otherwise NULL @@ -325,7 +335,7 @@ class SpellScript : public _SpellScript // returns: target of current effect if it was GameObject otherwise NULL GameObject* GetHitGObj(); // returns: destination of current effect - WorldLocation const* GetHitDest(); + WorldLocation* GetHitDest(); // setter/getter for for damage done by spell to target of spell hit // returns damage calculated before hit, and real dmg done after hit int32 GetHitDamage(); diff --git a/src/server/game/Tickets/TicketMgr.cpp b/src/server/game/Tickets/TicketMgr.cpp index 68e28014319..f82c01adf31 100755 --- a/src/server/game/Tickets/TicketMgr.cpp +++ b/src/server/game/Tickets/TicketMgr.cpp @@ -37,7 +37,10 @@ GmTicket::GmTicket(Player* player, WorldPacket& recv_data) : _createTime(time(NU _playerName = player->GetName(); _playerGuid = player->GetGUID(); - recv_data >> _mapId; + uint32 mapId; + recv_data >> mapId; // Map is sent as UInt32! + _mapId = mapId; + recv_data >> _posX; recv_data >> _posY; recv_data >> _posZ; diff --git a/src/server/game/Tools/PlayerDump.cpp b/src/server/game/Tools/PlayerDump.cpp index 8d5d16d22b9..476a19b6885 100644 --- a/src/server/game/Tools/PlayerDump.cpp +++ b/src/server/game/Tools/PlayerDump.cpp @@ -306,22 +306,28 @@ bool PlayerDumpWriter::DumpTable(std::string& dump, uint32 guid, char const*tabl switch (type) { case DTT_INVENTORY: - StoreGUID(result, 3, items); break; // item guid collection (character_inventory.item) + StoreGUID(result, 3, items); // item guid collection (character_inventory.item) + break; case DTT_PET: - StoreGUID(result, 0, pets); break; // pet petnumber collection (character_pet.id) + StoreGUID(result, 0, pets); // pet petnumber collection (character_pet.id) + break; case DTT_MAIL: - StoreGUID(result, 0, mails); // mail id collection (mail.id) + StoreGUID(result, 0, mails); // mail id collection (mail.id) + break; case DTT_MAIL_ITEM: - StoreGUID(result, 1, items); break; // item guid collection (mail_items.item_guid) + StoreGUID(result, 1, items); // item guid collection (mail_items.item_guid) + break; case DTT_CHARACTER: { - if (result->GetFieldCount() <= 67) // avoid crashes on next check - return true; - if (result->Fetch()[67].GetUInt32()) // characters.deleteInfos_Account - if filled error + if (result->GetFieldCount() <= 68) // avoid crashes on next check + sLog->outCrash("PlayerDumpWriter::DumpTable - Trying to access non-existing or wrong positioned field (`deleteInfos_Account`) in `characters` table."); + + if (result->Fetch()[68].GetUInt32()) // characters.deleteInfos_Account - if filled error return false; break; } - default: break; + default: + break; } dump += CreateDumpString(tableTo, result); diff --git a/src/server/game/Warden/Warden.cpp b/src/server/game/Warden/Warden.cpp index fa30adde72a..0734e0a0f63 100644 --- a/src/server/game/Warden/Warden.cpp +++ b/src/server/game/Warden/Warden.cpp @@ -187,7 +187,9 @@ std::string Warden::Penalty(WardenCheck* check /*= NULL*/) duration << sWorld->getIntConfig(CONFIG_WARDEN_CLIENT_BAN_DURATION) << "s"; std::string accountName; AccountMgr::GetName(_session->GetAccountId(), accountName); - sWorld->BanAccount(BAN_ACCOUNT, accountName, duration.str(), "Warden Anticheat violation","Server"); + std::stringstream banReason; + banReason << "Warden Anticheat Violation: " << check->Comment << " (CheckId: " << check->CheckId << ")"; + sWorld->BanAccount(BAN_ACCOUNT, accountName, duration.str(), banReason.str(),"Server"); return "Ban"; break; diff --git a/src/server/game/Warden/Warden.h b/src/server/game/Warden/Warden.h index e06ea7dca25..d16890b31b9 100644 --- a/src/server/game/Warden/Warden.h +++ b/src/server/game/Warden/Warden.h @@ -107,7 +107,7 @@ class Warden public: Warden(); - ~Warden(); + virtual ~Warden(); virtual void Init(WorldSession* session, BigNumber* k) = 0; virtual ClientWardenModule* GetModuleForClient() = 0; diff --git a/src/server/game/Warden/WardenCheckMgr.cpp b/src/server/game/Warden/WardenCheckMgr.cpp index 90d1cfc0140..f4c7a5069cf 100644 --- a/src/server/game/Warden/WardenCheckMgr.cpp +++ b/src/server/game/Warden/WardenCheckMgr.cpp @@ -63,8 +63,8 @@ void WardenCheckMgr::LoadWardenChecks() CheckStore.resize(maxCheckId + 1); - // 0 1 2 3 4 5 6 - result = WorldDatabase.Query("SELECT id, type, data, result, address, length, str FROM warden_checks ORDER BY id ASC"); + // 0 1 2 3 4 5 6 7 + result = WorldDatabase.Query("SELECT id, type, data, result, address, length, str, comment FROM warden_checks ORDER BY id ASC"); uint32 count = 0; do @@ -78,9 +78,11 @@ void WardenCheckMgr::LoadWardenChecks() uint32 address = fields[4].GetUInt32(); uint8 length = fields[5].GetUInt8(); std::string str = fields[6].GetString(); + std::string comment = fields[7].GetString(); WardenCheck* wardenCheck = new WardenCheck(); wardenCheck->Type = checkType; + wardenCheck->CheckId = id; // Initialize action with default action from config wardenCheck->Action = WardenActions(sWorld->getIntConfig(CONFIG_WARDEN_CLIENT_FAIL_ACTION)); @@ -134,6 +136,11 @@ void WardenCheckMgr::LoadWardenChecks() CheckResultStore[id] = wr; } + if (comment.empty()) + wardenCheck->Comment = "Undocumented Check"; + else + wardenCheck->Comment = comment; + ++count; } while (result->NextRow()); diff --git a/src/server/game/Warden/WardenCheckMgr.h b/src/server/game/Warden/WardenCheckMgr.h index 45de18081c2..7a83d8f0c6d 100644 --- a/src/server/game/Warden/WardenCheckMgr.h +++ b/src/server/game/Warden/WardenCheckMgr.h @@ -36,6 +36,8 @@ struct WardenCheck uint32 Address; // PROC_CHECK, MEM_CHECK, PAGE_CHECK uint8 Length; // PROC_CHECK, MEM_CHECK, PAGE_CHECK std::string Str; // LUA, MPQ, DRIVER + std::string Comment; + uint16 CheckId; enum WardenActions Action; }; diff --git a/src/server/game/Warden/WardenMac.cpp b/src/server/game/Warden/WardenMac.cpp index f62aa11a339..a60ae765013 100644 --- a/src/server/game/Warden/WardenMac.cpp +++ b/src/server/game/Warden/WardenMac.cpp @@ -122,7 +122,7 @@ void WardenMac::HandleHashResult(ByteBuffer &buff) uint8 mod_seed[16] = { 0x4D, 0x80, 0x8D, 0x2C, 0x77, 0xD9, 0x05, 0xC4, 0x1A, 0x63, 0x80, 0xEC, 0x08, 0x58, 0x6A, 0xFE }; - for(int i = 0; i < 4; ++i) + for (int i = 0; i < 4; ++i) { keyIn[i] = *(int*)(&mod_seed[0] + i * 4); } diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 1a9905edd12..6e32d33a7bb 100755 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1200,7 +1200,9 @@ void World::LoadConfigSettings(bool reload) m_bool_configs[CONFIG_PDUMP_NO_PATHS] = ConfigMgr::GetBoolDefault("PlayerDump.DisallowPaths", true); m_bool_configs[CONFIG_PDUMP_NO_OVERWRITE] = ConfigMgr::GetBoolDefault("PlayerDump.DisallowOverwrite", true); - sScriptMgr->OnConfigLoad(reload); + // call ScriptMgr if we're reloading the configuration + if (reload) + sScriptMgr->OnConfigLoad(reload); } extern void LoadGameObjectModelList(); @@ -1653,6 +1655,7 @@ void World::SetInitialWorldSettings() sLog->outString("Initializing Scripts..."); sScriptMgr->Initialize(); + sScriptMgr->OnConfigLoad(false); // must be done after the ScriptMgr has been properly initialized sLog->outString("Validating spell scripts..."); sObjectMgr->ValidateSpellScripts(); @@ -2599,7 +2602,7 @@ void World::SendAutoBroadcast() std::string msg; - msg = SelectRandomContainerElement(m_Autobroadcasts); + msg = Trinity::Containers::SelectRandomContainerElement(m_Autobroadcasts); uint32 abcenter = sWorld->getIntConfig(CONFIG_AUTOBROADCAST_CENTER); @@ -2639,7 +2642,7 @@ void World::_UpdateRealmCharCount(PreparedQueryResult resultCharCount) { Field* fields = resultCharCount->Fetch(); uint32 accountId = fields[0].GetUInt32(); - uint32 charCount = fields[1].GetUInt32(); + uint8 charCount = uint8(fields[1].GetUInt64()); PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_REALM_CHARACTERS_BY_REALM); stmt->setUInt32(0, accountId); @@ -2647,7 +2650,7 @@ void World::_UpdateRealmCharCount(PreparedQueryResult resultCharCount) LoginDatabase.Execute(stmt); stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_REALM_CHARACTERS); - stmt->setUInt32(0, charCount); + stmt->setUInt8(0, charCount); stmt->setUInt32(1, accountId); stmt->setUInt32(2, realmID); LoginDatabase.Execute(stmt); @@ -2923,7 +2926,7 @@ void World::LoadCharacterNameData() { sLog->outString("Loading character name data"); - QueryResult result = CharacterDatabase.Query("SELECT guid, name, race, gender, class FROM characters"); + QueryResult result = CharacterDatabase.Query("SELECT guid, name, race, gender, class FROM characters WHERE deleteDate IS NULL"); if (!result) { sLog->outError("No character name data loaded, empty query"); diff --git a/src/server/scripts/CMakeLists.txt b/src/server/scripts/CMakeLists.txt index 728d95a0851..792fdeb3e7b 100644 --- a/src/server/scripts/CMakeLists.txt +++ b/src/server/scripts/CMakeLists.txt @@ -53,7 +53,6 @@ include_directories( ${CMAKE_BINARY_DIR} ${CMAKE_SOURCE_DIR}/dep/g3dlite/include ${CMAKE_SOURCE_DIR}/dep/SFMT - ${CMAKE_SOURCE_DIR}/dep/mersennetwister ${CMAKE_SOURCE_DIR}/dep/zlib ${CMAKE_SOURCE_DIR}/src/server/shared ${CMAKE_SOURCE_DIR}/src/server/shared/Configuration @@ -120,6 +119,7 @@ include_directories( ${CMAKE_SOURCE_DIR}/src/server/game/Maps ${CMAKE_SOURCE_DIR}/src/server/game/Movement ${CMAKE_SOURCE_DIR}/src/server/game/Movement/MovementGenerators + ${CMAKE_SOURCE_DIR}/src/server/game/Movement/Spline ${CMAKE_SOURCE_DIR}/src/server/game/Movement/Waypoints ${CMAKE_SOURCE_DIR}/src/server/game/Opcodes ${CMAKE_SOURCE_DIR}/src/server/game/OutdoorPvP diff --git a/src/server/scripts/Commands/CMakeLists.txt b/src/server/scripts/Commands/CMakeLists.txt index d14e71aac4a..86fe984e197 100644 --- a/src/server/scripts/Commands/CMakeLists.txt +++ b/src/server/scripts/Commands/CMakeLists.txt @@ -17,7 +17,6 @@ set(scripts_STAT_SRCS Commands/cs_gm.cpp Commands/cs_go.cpp Commands/cs_gobject.cpp - Commands/cs_gps.cpp Commands/cs_honor.cpp Commands/cs_learn.cpp Commands/cs_misc.cpp diff --git a/src/server/scripts/Commands/cs_debug.cpp b/src/server/scripts/Commands/cs_debug.cpp index 679bb450800..c7bcde01e9b 100644 --- a/src/server/scripts/Commands/cs_debug.cpp +++ b/src/server/scripts/Commands/cs_debug.cpp @@ -95,6 +95,7 @@ public: static ChatCommand commandTable[] = { { "debug", SEC_MODERATOR, true, NULL, "", debugCommandTable }, + { "wpgps", SEC_ADMINISTRATOR, false, &HandleWPGPSCommand, "", NULL }, { NULL, SEC_PLAYER, false, NULL, "", NULL } }; return commandTable; @@ -1319,6 +1320,16 @@ public: return true; } + + static bool HandleWPGPSCommand(ChatHandler* handler, char const* /*args*/) + { + Player* player = handler->GetSession()->GetPlayer(); + + sLog->outSQLDev("(@PATH, XX, %.3f, %.3f, %.5f, 0,0, 0,100, 0),", player->GetPositionX(), player->GetPositionY(), player->GetPositionZ()); + + handler->PSendSysMessage("Waypoint SQL written to SQL Developer log"); + return true; + } }; void AddSC_debug_commandscript() diff --git a/src/server/scripts/Commands/cs_gps.cpp b/src/server/scripts/Commands/cs_gps.cpp deleted file mode 100644 index 59e2ec90905..00000000000 --- a/src/server/scripts/Commands/cs_gps.cpp +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -/* ScriptData -Name: gps_commandscript -%Complete: 100 -Comment: GPS/WPGPS commands -Category: commandscripts -EndScriptData */ - -#include "ObjectAccessor.h" -#include "ScriptMgr.h" -#include "Chat.h" -#include "CellImpl.h" - -class gps_commandscript : public CommandScript -{ -public: - gps_commandscript() : CommandScript("gps_commandscript") { } - - ChatCommand* GetCommands() const - { - static ChatCommand commandTable[] = - { - { "gps", SEC_ADMINISTRATOR, false, &HandleGPSCommand, "", NULL }, - { "wpgps", SEC_ADMINISTRATOR, false, &HandleWPGPSCommand, "", NULL }, - { NULL, 0, false, NULL, "", NULL } - }; - return commandTable; - } - - static bool HandleGPSCommand(ChatHandler* handler, char const* args) - { - WorldObject* object = NULL; - if (*args) - { - uint64 guid = handler->extractGuidFromLink((char*)args); - if (guid) - object = (WorldObject*)ObjectAccessor::GetObjectByTypeMask(*handler->GetSession()->GetPlayer(), guid, TYPEMASK_UNIT | TYPEMASK_GAMEOBJECT); - - if (!object) - { - handler->SendSysMessage(LANG_PLAYER_NOT_FOUND); - handler->SetSentErrorMessage(true); - return false; - } - } - else - { - object = handler->getSelectedUnit(); - - if (!object) - { - handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); - handler->SetSentErrorMessage(true); - return false; - } - } - - CellCoord cellCoord = Trinity::ComputeCellCoord(object->GetPositionX(), object->GetPositionY()); - Cell cell(cellCoord); - - uint32 zoneId, areaId; - object->GetZoneAndAreaId(zoneId, areaId); - - MapEntry const* mapEntry = sMapStore.LookupEntry(object->GetMapId()); - AreaTableEntry const* zoneEntry = GetAreaEntryByAreaID(zoneId); - AreaTableEntry const* areaEntry = GetAreaEntryByAreaID(areaId); - - float zoneX = object->GetPositionX(); - float zoneY = object->GetPositionY(); - - Map2ZoneCoordinates(zoneX, zoneY, zoneId); - - Map const* map = object->GetMap(); - float groundZ = map->GetHeight(object->GetPhaseMask(), object->GetPositionX(), object->GetPositionY(), MAX_HEIGHT); - float floorZ = map->GetHeight(object->GetPhaseMask(), object->GetPositionX(), object->GetPositionY(), object->GetPositionZ()); - - GridCoord gridCoord = Trinity::ComputeGridCoord(object->GetPositionX(), object->GetPositionY()); - - // 63? WHY? - int gridX = 63 - gridCoord.x_coord; - int gridY = 63 - gridCoord.y_coord; - - uint32 haveMap = Map::ExistMap(object->GetMapId(), gridX, gridY) ? 1 : 0; - uint32 haveVMap = Map::ExistVMap(object->GetMapId(), gridX, gridY) ? 1 : 0; - - if (haveVMap) - { - if (map->IsOutdoors(object->GetPositionX(), object->GetPositionY(), object->GetPositionZ())) - handler->PSendSysMessage("You are outdoors"); - else - handler->PSendSysMessage("You are indoors"); - } - else - handler->PSendSysMessage("no VMAP available for area info"); - - handler->PSendSysMessage(LANG_MAP_POSITION, - object->GetMapId(), (mapEntry ? mapEntry->name[handler->GetSessionDbcLocale()] : "<unknown>"), - zoneId, (zoneEntry ? zoneEntry->area_name[handler->GetSessionDbcLocale()] : "<unknown>"), - areaId, (areaEntry ? areaEntry->area_name[handler->GetSessionDbcLocale()] : "<unknown>"), - object->GetPhaseMask(), - object->GetPositionX(), object->GetPositionY(), object->GetPositionZ(), object->GetOrientation(), - cell.GridX(), cell.GridY(), cell.CellX(), cell.CellY(), object->GetInstanceId(), - zoneX, zoneY, groundZ, floorZ, haveMap, haveVMap); - - LiquidData liquidStatus; - ZLiquidStatus status = map->getLiquidStatus(object->GetPositionX(), object->GetPositionY(), object->GetPositionZ(), MAP_ALL_LIQUIDS, &liquidStatus); - - if (status) - handler->PSendSysMessage(LANG_LIQUID_STATUS, liquidStatus.level, liquidStatus.depth_level, liquidStatus.entry, liquidStatus.type_flags, status); - - return true; - } - - static bool HandleWPGPSCommand(ChatHandler* handler, char const* /*args*/) - { - Player* player = handler->GetSession()->GetPlayer(); - - sLog->outSQLDev("(@PATH, XX, %.3f, %.3f, %.5f, 0,0, 0,100, 0),", player->GetPositionX(), player->GetPositionY(), player->GetPositionZ()); - - handler->PSendSysMessage("Waypoint SQL written to SQL Developer log"); - return true; - } -}; - -void AddSC_gps_commandscript() -{ - new gps_commandscript(); -} diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index 5f0434e5c55..7c431566f52 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -17,6 +17,9 @@ #include "ScriptPCH.h"
#include "Chat.h"
+#include "ObjectAccessor.h"
+#include "ScriptMgr.h"
+#include "CellImpl.h"
class misc_commandscript : public CommandScript
{
@@ -27,7 +30,8 @@ public: {
static ChatCommand commandTable[] =
{
- { "dev", SEC_ADMINISTRATOR, false, &HandleDevCommand, "", NULL },
+ { "dev", SEC_ADMINISTRATOR, false, &HandleDevCommand, "", NULL },
+ { "gps", SEC_ADMINISTRATOR, false, &HandleGPSCommand, "", NULL },
{ NULL, 0, false, NULL, "", NULL }
};
return commandTable;
@@ -64,6 +68,90 @@ public: handler->SetSentErrorMessage(true);
return false;
}
+
+ static bool HandleGPSCommand(ChatHandler* handler, char const* args)
+ {
+ WorldObject* object = NULL;
+ if (*args)
+ {
+ uint64 guid = handler->extractGuidFromLink((char*)args);
+ if (guid)
+ object = (WorldObject*)ObjectAccessor::GetObjectByTypeMask(*handler->GetSession()->GetPlayer(), guid, TYPEMASK_UNIT | TYPEMASK_GAMEOBJECT);
+
+ if (!object)
+ {
+ handler->SendSysMessage(LANG_PLAYER_NOT_FOUND);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+ }
+ else
+ {
+ object = handler->getSelectedUnit();
+
+ if (!object)
+ {
+ handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+ }
+
+ CellCoord cellCoord = Trinity::ComputeCellCoord(object->GetPositionX(), object->GetPositionY());
+ Cell cell(cellCoord);
+
+ uint32 zoneId, areaId;
+ object->GetZoneAndAreaId(zoneId, areaId);
+
+ MapEntry const* mapEntry = sMapStore.LookupEntry(object->GetMapId());
+ AreaTableEntry const* zoneEntry = GetAreaEntryByAreaID(zoneId);
+ AreaTableEntry const* areaEntry = GetAreaEntryByAreaID(areaId);
+
+ float zoneX = object->GetPositionX();
+ float zoneY = object->GetPositionY();
+
+ Map2ZoneCoordinates(zoneX, zoneY, zoneId);
+
+ Map const* map = object->GetMap();
+ float groundZ = map->GetHeight(object->GetPhaseMask(), object->GetPositionX(), object->GetPositionY(), MAX_HEIGHT);
+ float floorZ = map->GetHeight(object->GetPhaseMask(), object->GetPositionX(), object->GetPositionY(), object->GetPositionZ());
+
+ GridCoord gridCoord = Trinity::ComputeGridCoord(object->GetPositionX(), object->GetPositionY());
+
+ // 63? WHY?
+ int gridX = 63 - gridCoord.x_coord;
+ int gridY = 63 - gridCoord.y_coord;
+
+ uint32 haveMap = Map::ExistMap(object->GetMapId(), gridX, gridY) ? 1 : 0;
+ uint32 haveVMap = Map::ExistVMap(object->GetMapId(), gridX, gridY) ? 1 : 0;
+
+ if (haveVMap)
+ {
+ if (map->IsOutdoors(object->GetPositionX(), object->GetPositionY(), object->GetPositionZ()))
+ handler->PSendSysMessage("You are outdoors");
+ else
+ handler->PSendSysMessage("You are indoors");
+ }
+ else
+ handler->PSendSysMessage("no VMAP available for area info");
+
+ handler->PSendSysMessage(LANG_MAP_POSITION,
+ object->GetMapId(), (mapEntry ? mapEntry->name[handler->GetSessionDbcLocale()] : "<unknown>"),
+ zoneId, (zoneEntry ? zoneEntry->area_name[handler->GetSessionDbcLocale()] : "<unknown>"),
+ areaId, (areaEntry ? areaEntry->area_name[handler->GetSessionDbcLocale()] : "<unknown>"),
+ object->GetPhaseMask(),
+ object->GetPositionX(), object->GetPositionY(), object->GetPositionZ(), object->GetOrientation(),
+ cell.GridX(), cell.GridY(), cell.CellX(), cell.CellY(), object->GetInstanceId(),
+ zoneX, zoneY, groundZ, floorZ, haveMap, haveVMap);
+
+ LiquidData liquidStatus;
+ ZLiquidStatus status = map->getLiquidStatus(object->GetPositionX(), object->GetPositionY(), object->GetPositionZ(), MAP_ALL_LIQUIDS, &liquidStatus);
+
+ if (status)
+ handler->PSendSysMessage(LANG_LIQUID_STATUS, liquidStatus.level, liquidStatus.depth_level, liquidStatus.entry, liquidStatus.type_flags, status);
+
+ return true;
+ }
};
void AddSC_misc_commandscript()
diff --git a/src/server/scripts/Commands/cs_modify.cpp b/src/server/scripts/Commands/cs_modify.cpp index 32ee96dacfe..b6feccc10c6 100644 --- a/src/server/scripts/Commands/cs_modify.cpp +++ b/src/server/scripts/Commands/cs_modify.cpp @@ -33,6 +33,16 @@ public: ChatCommand* GetCommands() const { + static ChatCommand modifyspeedCommandTable[] = + { + { "fly", SEC_MODERATOR, false, &HandleModifyFlyCommand, "", NULL }, + { "all", SEC_MODERATOR, false, &HandleModifyASpeedCommand, "", NULL }, + { "walk", SEC_MODERATOR, false, &HandleModifySpeedCommand, "", NULL }, + { "backwalk", SEC_MODERATOR, false, &HandleModifyBWalkCommand, "", NULL }, + { "swim", SEC_MODERATOR, false, &HandleModifySwimCommand, "", NULL }, + { "", SEC_MODERATOR, false, &HandleModifyASpeedCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } + }; static ChatCommand modifyCommandTable[] = { { "hp", SEC_MODERATOR, false, &HandleModifyHPCommand, "", NULL }, @@ -41,29 +51,26 @@ public: { "runicpower", SEC_MODERATOR, false, &HandleModifyRunicPowerCommand, "", NULL }, { "energy", SEC_MODERATOR, false, &HandleModifyEnergyCommand, "", NULL }, { "money", SEC_MODERATOR, false, &HandleModifyMoneyCommand, "", NULL }, - { "speed", SEC_MODERATOR, false, &HandleModifySpeedCommand, "", NULL }, - { "swim", SEC_MODERATOR, false, &HandleModifySwimCommand, "", NULL }, { "scale", SEC_MODERATOR, false, &HandleModifyScaleCommand, "", NULL }, { "bit", SEC_MODERATOR, false, &HandleModifyBitCommand, "", NULL }, - { "bwalk", SEC_MODERATOR, false, &HandleModifyBWalkCommand, "", NULL }, - { "fly", SEC_MODERATOR, false, &HandleModifyFlyCommand, "", NULL }, - { "aspeed", SEC_MODERATOR, false, &HandleModifyASpeedCommand, "", NULL }, { "faction", SEC_MODERATOR, false, &HandleModifyFactionCommand, "", NULL }, { "spell", SEC_MODERATOR, false, &HandleModifySpellCommand, "", NULL }, - { "tp", SEC_MODERATOR, false, &HandleModifyTalentCommand, "", NULL }, + { "talentpoints", SEC_MODERATOR, false, &HandleModifyTalentCommand, "", NULL }, { "mount", SEC_MODERATOR, false, &HandleModifyMountCommand, "", NULL }, { "honor", SEC_MODERATOR, false, &HandleModifyHonorCommand, "", NULL }, - { "rep", SEC_GAMEMASTER, false, &HandleModifyRepCommand, "", NULL }, - { "arena", SEC_MODERATOR, false, &HandleModifyArenaCommand, "", NULL }, + { "reputation", SEC_GAMEMASTER, false, &HandleModifyRepCommand, "", NULL }, + { "arenapoints", SEC_MODERATOR, false, &HandleModifyArenaCommand, "", NULL }, { "drunk", SEC_MODERATOR, false, &HandleModifyDrunkCommand, "", NULL }, { "standstate", SEC_GAMEMASTER, false, &HandleModifyStandStateCommand, "", NULL }, - { "morph", SEC_GAMEMASTER, false, &HandleModifyMorphCommand, "", NULL }, { "phase", SEC_ADMINISTRATOR, false, &HandleModifyPhaseCommand, "", NULL }, { "gender", SEC_GAMEMASTER, false, &HandleModifyGenderCommand, "", NULL }, + { "speed", SEC_MODERATOR, false, NULL, "", modifyspeedCommandTable }, { NULL, 0, false, NULL, "", NULL } }; static ChatCommand commandTable[] = { + { "morph", SEC_GAMEMASTER, false, &HandleModifyMorphCommand, "", NULL }, + { "demorph", SEC_GAMEMASTER, false, &HandleDeMorphCommand, "", NULL }, { "modify", SEC_MODERATOR, false, NULL, "", modifyCommandTable }, { NULL, 0, false, NULL, "", NULL } }; @@ -1234,7 +1241,7 @@ public: return false; } - target->GetReputationMgr().SetReputation(factionEntry, amount); + target->GetReputationMgr().SetOneFactionReputation(factionEntry, amount, false); handler->PSendSysMessage(LANG_COMMAND_MODIFY_REP, factionEntry->name[handler->GetSessionDbcLocale()], factionId, handler->GetNameLink(target).c_str(), target->GetReputationMgr().GetReputation(factionEntry)); return true; @@ -1376,6 +1383,21 @@ public: return true; } +//demorph player or unit + static bool HandleDeMorphCommand(ChatHandler* handler, const char* /*args*/) + { + Unit* target = handler->getSelectedUnit(); + if (!target) + target = handler->GetSession()->GetPlayer(); + + // check online security + else if (target->GetTypeId() == TYPEID_PLAYER && handler->HasLowerSecurity(target->ToPlayer(), 0)) + return false; + + target->DeMorph(); + + return true; + } }; void AddSC_modify_commandscript() diff --git a/src/server/scripts/Commands/cs_npc.cpp b/src/server/scripts/Commands/cs_npc.cpp index a9959c60201..832f7958fc8 100644 --- a/src/server/scripts/Commands/cs_npc.cpp +++ b/src/server/scripts/Commands/cs_npc.cpp @@ -28,6 +28,7 @@ EndScriptData */ #include "Transport.h" #include "CreatureGroups.h" #include "TargetedMovementGenerator.h" // for HandleNpcUnFollowCommand +#include "CreatureAI.h" class npc_commandscript : public CommandScript { @@ -73,6 +74,7 @@ public: { "phase", SEC_GAMEMASTER, false, &HandleNpcSetPhaseCommand, "", NULL }, { "spawndist", SEC_GAMEMASTER, false, &HandleNpcSetSpawnDistCommand, "", NULL }, { "spawntime", SEC_GAMEMASTER, false, &HandleNpcSetSpawnTimeCommand, "", NULL }, + { "data", SEC_ADMINISTRATOR, false, &HandleNpcSetDataCommand, "", NULL }, //{ TODO: fix or remove these commands { "name", SEC_GAMEMASTER, false, &HandleNpcSetNameCommand, "", NULL }, { "subname", SEC_GAMEMASTER, false, &HandleNpcSetSubNameCommand, "", NULL }, @@ -524,6 +526,39 @@ public: return true; } + //set data of creature for testing scripting + static bool HandleNpcSetDataCommand(ChatHandler* handler, const char* args) + { + if (!*args) + return false; + + char* arg1 = strtok((char*)args, " "); + char* arg2 = strtok((char*)NULL, ""); + + if (!arg1 || !arg2) + return false; + + uint32 data_1 = (uint32)atoi(arg1); + uint32 data_2 = (uint32)atoi(arg2); + + if (!data_1 || !data_2) + return false; + + Creature* creature = handler->getSelectedCreature(); + + if (!creature) + { + handler->SendSysMessage(LANG_SELECT_CREATURE); + handler->SetSentErrorMessage(true); + return false; + } + + creature->AI()->SetData(data_1, data_2); + std::string AIorScript = creature->GetAIName() != "" ? "AI type: " + creature->GetAIName() : (creature->GetScriptName() != "" ? "Script Name: " + creature->GetScriptName() : "No AI or Script Name Set"); + handler->PSendSysMessage(LANG_NPC_SETDATA, creature->GetGUID(), creature->GetEntry(), creature->GetName(), data_1, data_2, AIorScript.c_str()); + return true; + } + //npc follow handling static bool HandleNpcFollowCommand(ChatHandler* handler, const char* /*args*/) { diff --git a/src/server/scripts/Commands/cs_reload.cpp b/src/server/scripts/Commands/cs_reload.cpp index 5f192ffceee..1c119fdef4c 100644 --- a/src/server/scripts/Commands/cs_reload.cpp +++ b/src/server/scripts/Commands/cs_reload.cpp @@ -424,7 +424,7 @@ public: continue; } - CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(entry); + CreatureTemplate* cInfo = const_cast<CreatureTemplate*>(sObjectMgr->GetCreatureTemplate(entry)); if (!cInfo) { handler->PSendSysMessage(LANG_COMMAND_CREATURESTORAGE_NOTFOUND, entry); @@ -435,90 +435,88 @@ public: Field* fields = result->Fetch(); - const_cast<CreatureTemplate*>(cInfo)->DifficultyEntry[0] = fields[0].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->DifficultyEntry[1] = fields[1].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->DifficultyEntry[2] = fields[2].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->KillCredit[0] = fields[3].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->KillCredit[1] = fields[4].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->Modelid1 = fields[5].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->Modelid2 = fields[6].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->Modelid3 = fields[7].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->Modelid4 = fields[8].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->Name = fields[9].GetString(); - const_cast<CreatureTemplate*>(cInfo)->SubName = fields[10].GetString(); - const_cast<CreatureTemplate*>(cInfo)->IconName = fields[11].GetString(); - const_cast<CreatureTemplate*>(cInfo)->GossipMenuId = fields[12].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->minlevel = fields[13].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->maxlevel = fields[14].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->expansion = fields[15].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->faction_A = fields[16].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->faction_H = fields[17].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->npcflag = fields[18].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->speed_walk = fields[19].GetFloat(); - const_cast<CreatureTemplate*>(cInfo)->speed_run = fields[20].GetFloat(); - const_cast<CreatureTemplate*>(cInfo)->scale = fields[21].GetFloat(); - const_cast<CreatureTemplate*>(cInfo)->rank = fields[22].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->mindmg = fields[23].GetFloat(); - const_cast<CreatureTemplate*>(cInfo)->maxdmg = fields[24].GetFloat(); - const_cast<CreatureTemplate*>(cInfo)->dmgschool = fields[25].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->attackpower = fields[26].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->dmg_multiplier = fields[27].GetFloat(); - const_cast<CreatureTemplate*>(cInfo)->baseattacktime = fields[28].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->rangeattacktime = fields[29].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->unit_class = fields[30].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->unit_flags = fields[31].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->dynamicflags = fields[32].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->family = fields[33].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->trainer_type = fields[34].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->trainer_spell = fields[35].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->trainer_class = fields[36].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->trainer_race = fields[37].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->minrangedmg = fields[38].GetFloat(); - const_cast<CreatureTemplate*>(cInfo)->maxrangedmg = fields[39].GetFloat(); - const_cast<CreatureTemplate*>(cInfo)->rangedattackpower = fields[40].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->type = fields[41].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->type_flags = fields[42].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->lootid = fields[43].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->pickpocketLootId = fields[44].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->SkinLootId = fields[45].GetUInt32(); + cInfo->DifficultyEntry[0] = fields[0].GetUInt32(); + cInfo->DifficultyEntry[1] = fields[1].GetUInt32(); + cInfo->DifficultyEntry[2] = fields[2].GetUInt32(); + cInfo->KillCredit[0] = fields[3].GetUInt32(); + cInfo->KillCredit[1] = fields[4].GetUInt32(); + cInfo->Modelid1 = fields[5].GetUInt32(); + cInfo->Modelid2 = fields[6].GetUInt32(); + cInfo->Modelid3 = fields[7].GetUInt32(); + cInfo->Modelid4 = fields[8].GetUInt32(); + cInfo->Name = fields[9].GetString(); + cInfo->SubName = fields[10].GetString(); + cInfo->IconName = fields[11].GetString(); + cInfo->GossipMenuId = fields[12].GetUInt32(); + cInfo->minlevel = fields[13].GetUInt8(); + cInfo->maxlevel = fields[14].GetUInt8(); + cInfo->expansion = fields[15].GetUInt16(); + cInfo->faction_A = fields[16].GetUInt16(); + cInfo->faction_H = fields[17].GetUInt16(); + cInfo->npcflag = fields[18].GetUInt32(); + cInfo->speed_walk = fields[19].GetFloat(); + cInfo->speed_run = fields[20].GetFloat(); + cInfo->scale = fields[21].GetFloat(); + cInfo->rank = fields[22].GetUInt8(); + cInfo->mindmg = fields[23].GetFloat(); + cInfo->maxdmg = fields[24].GetFloat(); + cInfo->dmgschool = fields[25].GetUInt8(); + cInfo->attackpower = fields[26].GetUInt32(); + cInfo->dmg_multiplier = fields[27].GetFloat(); + cInfo->baseattacktime = fields[28].GetUInt32(); + cInfo->rangeattacktime = fields[29].GetUInt32(); + cInfo->unit_class = fields[30].GetUInt8(); + cInfo->unit_flags = fields[31].GetUInt32(); + cInfo->dynamicflags = fields[32].GetUInt32(); + cInfo->family = fields[33].GetUInt8(); + cInfo->trainer_type = fields[34].GetUInt8(); + cInfo->trainer_spell = fields[35].GetUInt32(); + cInfo->trainer_class = fields[36].GetUInt8(); + cInfo->trainer_race = fields[37].GetUInt8(); + cInfo->minrangedmg = fields[38].GetFloat(); + cInfo->maxrangedmg = fields[39].GetFloat(); + cInfo->rangedattackpower = fields[40].GetUInt16(); + cInfo->type = fields[41].GetUInt8(); + cInfo->type_flags = fields[42].GetUInt32(); + cInfo->lootid = fields[43].GetUInt32(); + cInfo->pickpocketLootId = fields[44].GetUInt32(); + cInfo->SkinLootId = fields[45].GetUInt32(); for (uint8 i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i) - { - const_cast<CreatureTemplate*>(cInfo)->resistance[i] = fields[46 + i -1].GetUInt32(); - } - - const_cast<CreatureTemplate*>(cInfo)->spells[0] = fields[52].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->spells[1] = fields[53].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->spells[2] = fields[54].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->spells[3] = fields[55].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->spells[4] = fields[56].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->spells[5] = fields[57].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->spells[6] = fields[58].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->spells[7] = fields[59].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->PetSpellDataId = fields[60].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->VehicleId = fields[61].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->mingold = fields[62].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->maxgold = fields[63].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->AIName = fields[64].GetString(); - const_cast<CreatureTemplate*>(cInfo)->MovementType = fields[65].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->InhabitType = fields[66].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->HoverHeight = fields[67].GetFloat(); - const_cast<CreatureTemplate*>(cInfo)->ModHealth = fields[68].GetFloat(); - const_cast<CreatureTemplate*>(cInfo)->ModMana = fields[69].GetFloat(); - const_cast<CreatureTemplate*>(cInfo)->ModArmor = fields[70].GetFloat(); - const_cast<CreatureTemplate*>(cInfo)->RacialLeader = fields[71].GetBool(); - const_cast<CreatureTemplate*>(cInfo)->questItems[0] = fields[72].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->questItems[1] = fields[73].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->questItems[2] = fields[74].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->questItems[3] = fields[75].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->questItems[4] = fields[76].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->questItems[5] = fields[77].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->movementId = fields[78].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->RegenHealth = fields[79].GetBool(); - const_cast<CreatureTemplate*>(cInfo)->equipmentId = fields[80].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->MechanicImmuneMask = fields[81].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->flags_extra = fields[82].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->ScriptID = sObjectMgr->GetScriptId(fields[83].GetCString()); + cInfo->resistance[i] = fields[46 + i -1].GetUInt16(); + + cInfo->spells[0] = fields[52].GetUInt32(); + cInfo->spells[1] = fields[53].GetUInt32(); + cInfo->spells[2] = fields[54].GetUInt32(); + cInfo->spells[3] = fields[55].GetUInt32(); + cInfo->spells[4] = fields[56].GetUInt32(); + cInfo->spells[5] = fields[57].GetUInt32(); + cInfo->spells[6] = fields[58].GetUInt32(); + cInfo->spells[7] = fields[59].GetUInt32(); + cInfo->PetSpellDataId = fields[60].GetUInt32(); + cInfo->VehicleId = fields[61].GetUInt32(); + cInfo->mingold = fields[62].GetUInt32(); + cInfo->maxgold = fields[63].GetUInt32(); + cInfo->AIName = fields[64].GetString(); + cInfo->MovementType = fields[65].GetUInt8(); + cInfo->InhabitType = fields[66].GetUInt8(); + cInfo->HoverHeight = fields[67].GetFloat(); + cInfo->ModHealth = fields[68].GetFloat(); + cInfo->ModMana = fields[69].GetFloat(); + cInfo->ModArmor = fields[70].GetFloat(); + cInfo->RacialLeader = fields[71].GetBool(); + cInfo->questItems[0] = fields[72].GetUInt32(); + cInfo->questItems[1] = fields[73].GetUInt32(); + cInfo->questItems[2] = fields[74].GetUInt32(); + cInfo->questItems[3] = fields[75].GetUInt32(); + cInfo->questItems[4] = fields[76].GetUInt32(); + cInfo->questItems[5] = fields[77].GetUInt32(); + cInfo->movementId = fields[78].GetUInt32(); + cInfo->RegenHealth = fields[79].GetBool(); + cInfo->equipmentId = fields[80].GetUInt32(); + cInfo->MechanicImmuneMask = fields[81].GetUInt32(); + cInfo->flags_extra = fields[82].GetUInt32(); + cInfo->ScriptID = sObjectMgr->GetScriptId(fields[83].GetCString()); sObjectMgr->CheckCreatureTemplate(cInfo); } diff --git a/src/server/scripts/Commands/cs_tele.cpp b/src/server/scripts/Commands/cs_tele.cpp index 89646c23ea0..ca7c3af7fde 100644 --- a/src/server/scripts/Commands/cs_tele.cpp +++ b/src/server/scripts/Commands/cs_tele.cpp @@ -138,8 +138,8 @@ public: if (resultDB) { Field* fieldsDB = resultDB->Fetch(); - uint32 mapId = fieldsDB[0].GetUInt32(); - uint32 zoneId = fieldsDB[1].GetUInt32(); + uint32 mapId = fieldsDB[0].GetUInt16(); + uint32 zoneId = fieldsDB[1].GetUInt16(); float posX = fieldsDB[2].GetFloat(); float posY = fieldsDB[3].GetFloat(); float posZ = fieldsDB[4].GetFloat(); diff --git a/src/server/scripts/EasternKingdoms/BlackrockSpire/blackrock_spire.h b/src/server/scripts/EasternKingdoms/BlackrockSpire/blackrock_spire.h index e51c6b9130d..beef71ea857 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockSpire/blackrock_spire.h +++ b/src/server/scripts/EasternKingdoms/BlackrockSpire/blackrock_spire.h @@ -57,11 +57,39 @@ enum AdditionalData { SPELL_SUMMON_ROOKERY_WHELP = 15745, MAX_ENCOUNTER = 14, + MAX_DRAGONSPIRE_HALL_RUNES = 7, }; enum GameObjects { - GO_WHELP_SPAWNER = 175622, //trap spawned by go id 175124 + GO_WHELP_SPAWNER = 175622, // trap spawned by go id 175124 + + // Doors + GO_EMBERSEER_IN = 175244, // First door to Pyroguard Emberseer + GO_DOORS = 175705, // Second door to Pyroguard Emberseer + GO_EMBERSEER_OUT = 175153, // Door after Pyroguard Emberseer event + GO_GYTH_ENTRY_DOOR = 164726, + GO_GYTH_COMBAT_DOOR = 175185, + GO_GYTH_EXIT_DOOR = 175186, + GO_DRAKKISATH_DOOR_1 = 175946, + GO_DRAKKISATH_DOOR_2 = 175947, + + // Runes + GO_ROOM_1_RUNE = 175197, + GO_ROOM_2_RUNE = 175199, + GO_ROOM_3_RUNE = 175195, + GO_ROOM_4_RUNE = 175200, + GO_ROOM_5_RUNE = 175198, + GO_ROOM_6_RUNE = 175196, + GO_ROOM_7_RUNE = 175194, + + GO_EMBERSEER_RUNE_1 = 175266, + GO_EMBERSEER_RUNE_2 = 175267, + GO_EMBERSEER_RUNE_3 = 175268, + GO_EMBERSEER_RUNE_4 = 175269, + GO_EMBERSEER_RUNE_5 = 175270, + GO_EMBERSEER_RUNE_6 = 175271, + GO_EMBERSEER_RUNE_7 = 175272, }; #endif diff --git a/src/server/scripts/EasternKingdoms/BlackrockSpire/instance_blackrock_spire.cpp b/src/server/scripts/EasternKingdoms/BlackrockSpire/instance_blackrock_spire.cpp index ff97984fa09..b5b1b34a593 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockSpire/instance_blackrock_spire.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockSpire/instance_blackrock_spire.cpp @@ -247,7 +247,30 @@ public: }; +uint8 ActivatedRunes = 0; + +class go_dragonspire_hall_rune : public GameObjectScript +{ +public: + go_dragonspire_hall_rune() : GameObjectScript("go_dragonspire_hall_rune") { } + + void OnGameObjectStateChanged(GameObject* go, uint32 state) + { + if (state == GO_STATE_READY) + { + if (++ActivatedRunes == MAX_DRAGONSPIRE_HALL_RUNES) + { + if (GameObject* door1 = GetClosestGameObjectWithEntry(go, GO_EMBERSEER_IN, 150.0f)) + door1->SetGoState(GO_STATE_ACTIVE); + if (GameObject* door2 = GetClosestGameObjectWithEntry(go, GO_DOORS, 150.0f)) + door2->SetGoState(GO_STATE_ACTIVE); + } + } + } +}; + void AddSC_instance_blackrock_spire() { new instance_blackrock_spire(); + new go_dragonspire_hall_rune; } diff --git a/src/server/scripts/EasternKingdoms/BlackwingLair/boss_chromaggus.cpp b/src/server/scripts/EasternKingdoms/BlackwingLair/boss_chromaggus.cpp index 818dcace078..a3eb0cea5ad 100644 --- a/src/server/scripts/EasternKingdoms/BlackwingLair/boss_chromaggus.cpp +++ b/src/server/scripts/EasternKingdoms/BlackwingLair/boss_chromaggus.cpp @@ -245,7 +245,7 @@ public: Unit* unit; if ((*i) && (*i)->getSource()) { - unit = Unit::GetUnit((*me), (*i)->getUnitGuid()); + unit = Unit::GetUnit(*me, (*i)->getUnitGuid()); if (unit) { //Cast affliction diff --git a/src/server/scripts/EasternKingdoms/BlackwingLair/boss_vaelastrasz.cpp b/src/server/scripts/EasternKingdoms/BlackwingLair/boss_vaelastrasz.cpp index 5bcb6d051bb..eaa8c118f19 100644 --- a/src/server/scripts/EasternKingdoms/BlackwingLair/boss_vaelastrasz.cpp +++ b/src/server/scripts/EasternKingdoms/BlackwingLair/boss_vaelastrasz.cpp @@ -176,9 +176,9 @@ public: break; case 2: me->setFaction(103); - if (PlayerGUID && Unit::GetUnit((*me), PlayerGUID)) + if (PlayerGUID && Unit::GetUnit(*me, PlayerGUID)) { - AttackStart(Unit::GetUnit((*me), PlayerGUID)); + AttackStart(Unit::GetUnit(*me, PlayerGUID)); DoCast(me, SPELL_ESSENCEOFTHERED); } SpeechTimer = 0; diff --git a/src/server/scripts/EasternKingdoms/Deadmines/boss_mr_smite.cpp b/src/server/scripts/EasternKingdoms/Deadmines/boss_mr_smite.cpp index aa62e1277f8..4885d8620b0 100644 --- a/src/server/scripts/EasternKingdoms/Deadmines/boss_mr_smite.cpp +++ b/src/server/scripts/EasternKingdoms/Deadmines/boss_mr_smite.cpp @@ -127,7 +127,7 @@ public: DoCastAOE(SPELL_SMITE_STOMP, false); SetCombatMovement(false); if (instance) - if (GameObject* go = GameObject::GetGameObject((*me), instance->GetData64(DATA_SMITE_CHEST))) + if (GameObject* go = GameObject::GetGameObject(*me, instance->GetData64(DATA_SMITE_CHEST))) { me->GetMotionMaster()->Clear(); me->GetMotionMaster()->MovePoint(1, go->GetPositionX() - 3.0f, go->GetPositionY(), go->GetPositionZ()); diff --git a/src/server/scripts/EasternKingdoms/Gnomeregan/gnomeregan.cpp b/src/server/scripts/EasternKingdoms/Gnomeregan/gnomeregan.cpp index 6aa4c9d1a7a..b5a7984d945 100644 --- a/src/server/scripts/EasternKingdoms/Gnomeregan/gnomeregan.cpp +++ b/src/server/scripts/EasternKingdoms/Gnomeregan/gnomeregan.cpp @@ -189,11 +189,11 @@ public: if (bBool) { if (instance) - if (GameObject* go = GameObject::GetGameObject((*me), instance->GetData64(DATA_GO_CAVE_IN_RIGHT))) + if (GameObject* go = GameObject::GetGameObject(*me, instance->GetData64(DATA_GO_CAVE_IN_RIGHT))) instance->HandleGameObject(0, false, go); }else if (instance) - if (GameObject* go = GameObject::GetGameObject((*me), instance->GetData64(DATA_GO_CAVE_IN_LEFT))) + if (GameObject* go = GameObject::GetGameObject(*me, instance->GetData64(DATA_GO_CAVE_IN_LEFT))) instance->HandleGameObject(0, false, go); } @@ -204,10 +204,10 @@ public: if (bBool) { - if (GameObject* go = GameObject::GetGameObject((*me), instance->GetData64(DATA_GO_CAVE_IN_RIGHT))) + if (GameObject* go = GameObject::GetGameObject(*me, instance->GetData64(DATA_GO_CAVE_IN_RIGHT))) me->SetFacingToObject(go); }else - if (GameObject* go = GameObject::GetGameObject((*me), instance->GetData64(DATA_GO_CAVE_IN_LEFT))) + if (GameObject* go = GameObject::GetGameObject(*me, instance->GetData64(DATA_GO_CAVE_IN_LEFT))) me->SetFacingToObject(go); } @@ -216,10 +216,10 @@ public: if (!instance) return; - if (GameObject* go = GameObject::GetGameObject((*me), instance->GetData64(DATA_GO_CAVE_IN_RIGHT))) + if (GameObject* go = GameObject::GetGameObject(*me, instance->GetData64(DATA_GO_CAVE_IN_RIGHT))) instance->HandleGameObject(0, false, go); - if (GameObject* go = GameObject::GetGameObject((*me), instance->GetData64(DATA_GO_CAVE_IN_LEFT))) + if (GameObject* go = GameObject::GetGameObject(*me, instance->GetData64(DATA_GO_CAVE_IN_LEFT))) instance->HandleGameObject(0, false, go); if (!GoSummonList.empty()) @@ -445,7 +445,7 @@ public: DoScriptText(SAY_BLASTMASTER_5, me); Summon(1); if (instance) - if (GameObject* go = GameObject::GetGameObject((*me), instance->GetData64(DATA_GO_CAVE_IN_RIGHT))) + if (GameObject* go = GameObject::GetGameObject(*me, instance->GetData64(DATA_GO_CAVE_IN_RIGHT))) instance->HandleGameObject(0, true, go); NextStep(3000, true); break; @@ -491,7 +491,7 @@ public: DoScriptText(SAY_BLASTMASTER_23, me); SetInFace(false); if (instance) - if (GameObject* go = GameObject::GetGameObject((*me), instance->GetData64(DATA_GO_CAVE_IN_LEFT))) + if (GameObject* go = GameObject::GetGameObject(*me, instance->GetData64(DATA_GO_CAVE_IN_LEFT))) instance->HandleGameObject(0, true, go); NextStep(2000, true); break; diff --git a/src/server/scripts/EasternKingdoms/Karazhan/boss_midnight.cpp b/src/server/scripts/EasternKingdoms/Karazhan/boss_midnight.cpp index bbf87ac3e73..783ac6baad1 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/boss_midnight.cpp +++ b/src/server/scripts/EasternKingdoms/Karazhan/boss_midnight.cpp @@ -244,8 +244,8 @@ void boss_attumen::boss_attumenAI::UpdateAI(const uint32 diff) Midnight = 0; me->SetVisible(false); me->Kill(me); - } - } else ResetTimer -= diff; + } else ResetTimer -= diff; + } //Return since we have no target if (!UpdateVictim()) diff --git a/src/server/scripts/EasternKingdoms/Karazhan/boss_moroes.cpp b/src/server/scripts/EasternKingdoms/Karazhan/boss_moroes.cpp index 90fdb165384..f69cecdb4c3 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/boss_moroes.cpp +++ b/src/server/scripts/EasternKingdoms/Karazhan/boss_moroes.cpp @@ -358,7 +358,7 @@ struct boss_moroes_guestAI : public ScriptedAI uint64 TempGUID = GuestGUID[rand()%4]; if (TempGUID) { - Unit* unit = Unit::GetUnit((*me), TempGUID); + Unit* unit = Unit::GetUnit(*me, TempGUID); if (unit && unit->isAlive()) return unit; } diff --git a/src/server/scripts/EasternKingdoms/Karazhan/boss_terestian_illhoof.cpp b/src/server/scripts/EasternKingdoms/Karazhan/boss_terestian_illhoof.cpp index f2def74011d..2f19d2c7fc1 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/boss_terestian_illhoof.cpp +++ b/src/server/scripts/EasternKingdoms/Karazhan/boss_terestian_illhoof.cpp @@ -101,7 +101,7 @@ public: uint64 TerestianGUID = instance->GetData64(DATA_TERESTIAN); if (TerestianGUID) { - Unit* Terestian = Unit::GetUnit((*me), TerestianGUID); + Unit* Terestian = Unit::GetUnit(*me, TerestianGUID); if (Terestian && Terestian->isAlive()) DoCast(Terestian, SPELL_BROKEN_PACT, true); } @@ -157,7 +157,7 @@ public: { if (SacrificeGUID) { - Unit* Sacrifice = Unit::GetUnit((*me), SacrificeGUID); + Unit* Sacrifice = Unit::GetUnit(*me, SacrificeGUID); if (Sacrifice) Sacrifice->RemoveAurasDueToSpell(SPELL_SACRIFICE); } diff --git a/src/server/scripts/EasternKingdoms/Karazhan/bosses_opera.cpp b/src/server/scripts/EasternKingdoms/Karazhan/bosses_opera.cpp index c2aeedbd1d3..6f8121ef5b6 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/bosses_opera.cpp +++ b/src/server/scripts/EasternKingdoms/Karazhan/bosses_opera.cpp @@ -886,7 +886,7 @@ public: { IsChasing = false; - if (Unit* target = Unit::GetUnit((*me), HoodGUID)) + if (Unit* target = Unit::GetUnit(*me, HoodGUID)) { HoodGUID = 0; if (DoGetThreat(target)) diff --git a/src/server/scripts/EasternKingdoms/Karazhan/karazhan.cpp b/src/server/scripts/EasternKingdoms/Karazhan/karazhan.cpp index 89c3e371de7..b37f6913b8d 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/karazhan.cpp +++ b/src/server/scripts/EasternKingdoms/Karazhan/karazhan.cpp @@ -536,7 +536,7 @@ public: uint32 NextStep(uint32 Step) { - Unit* arca = Unit::GetUnit((*me), ArcanagosGUID); + Unit* arca = Unit::GetUnit(*me, ArcanagosGUID); Map* map = me->GetMap(); switch (Step) { @@ -625,7 +625,7 @@ public: if (Step >= 7 && Step <= 12) { - Unit* arca = Unit::GetUnit((*me), ArcanagosGUID); + Unit* arca = Unit::GetUnit(*me, ArcanagosGUID); if (FireArcanagosTimer <= diff) { diff --git a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp index 6bcec6c6db5..4a75370f0e8 100644 --- a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp +++ b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp @@ -197,7 +197,7 @@ public: std::list<HostileReference*>::const_iterator i = m_threatlist.begin(); for (i = m_threatlist.begin(); i != m_threatlist.end(); ++i) { - Unit* unit = Unit::GetUnit((*me), (*i)->getUnitGuid()); + Unit* unit = Unit::GetUnit(*me, (*i)->getUnitGuid()); if (unit && unit->isAlive()) { float threat = me->getThreatManager().getThreat(unit); @@ -215,7 +215,7 @@ public: std::list<HostileReference*>::const_iterator i = me->getThreatManager().getThreatList().begin(); for (i = me->getThreatManager().getThreatList().begin(); i!= me->getThreatManager().getThreatList().end(); ++i) { - Unit* unit = Unit::GetUnit((*me), (*i)->getUnitGuid()); + Unit* unit = Unit::GetUnit(*me, (*i)->getUnitGuid()); if (unit && (unit->GetTypeId() == TYPEID_PLAYER)) unit->CastSpell(unit, SPELL_TELEPORT_CENTER, true); } @@ -227,7 +227,7 @@ public: std::list<HostileReference*>::const_iterator i = me->getThreatManager().getThreatList().begin(); for (i = me->getThreatManager().getThreatList().begin(); i!= me->getThreatManager().getThreatList().end(); ++i) { - Unit* unit = Unit::GetUnit((*me), (*i)->getUnitGuid()); + Unit* unit = Unit::GetUnit(*me, (*i)->getUnitGuid()); if (unit && (unit->GetTypeId() == TYPEID_PLAYER)) // Knockback into the air unit->CastSpell(unit, SPELL_GRAVITY_LAPSE_DOT, true, 0, 0, me->GetGUID()); @@ -239,7 +239,7 @@ public: std::list<HostileReference*>::const_iterator i = me->getThreatManager().getThreatList().begin(); for (i = me->getThreatManager().getThreatList().begin(); i!= me->getThreatManager().getThreatList().end(); ++i) { - Unit* unit = Unit::GetUnit((*me), (*i)->getUnitGuid()); + Unit* unit = Unit::GetUnit(*me, (*i)->getUnitGuid()); if (unit && (unit->GetTypeId() == TYPEID_PLAYER)) { // Also needs an exception in spell system. @@ -259,7 +259,7 @@ public: std::list<HostileReference*>::const_iterator i = me->getThreatManager().getThreatList().begin(); for (i = me->getThreatManager().getThreatList().begin(); i!= me->getThreatManager().getThreatList().end(); ++i) { - Unit* unit = Unit::GetUnit((*me), (*i)->getUnitGuid()); + Unit* unit = Unit::GetUnit(*me, (*i)->getUnitGuid()); if (unit && (unit->GetTypeId() == TYPEID_PLAYER)) { unit->RemoveAurasDueToSpell(SPELL_GRAVITY_LAPSE_FLY); diff --git a/src/server/scripts/EasternKingdoms/MoltenCore/boss_sulfuron_harbinger.cpp b/src/server/scripts/EasternKingdoms/MoltenCore/boss_sulfuron_harbinger.cpp index 9f511c1394a..343298d29fe 100644 --- a/src/server/scripts/EasternKingdoms/MoltenCore/boss_sulfuron_harbinger.cpp +++ b/src/server/scripts/EasternKingdoms/MoltenCore/boss_sulfuron_harbinger.cpp @@ -103,7 +103,7 @@ class boss_sulfuron : public CreatureScript { std::list<Creature*> healers = DoFindFriendlyMissingBuff(45.0f, SPELL_INSPIRE); if (!healers.empty()) - DoCast(SelectRandomContainerElement(healers), SPELL_INSPIRE); + DoCast(Trinity::Containers::SelectRandomContainerElement(healers), SPELL_INSPIRE); DoCast(me, SPELL_INSPIRE); events.ScheduleEvent(EVENT_INSPIRE, urand(20000, 26000)); diff --git a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp index ceab845f0a2..bf887bec164 100644 --- a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp +++ b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp @@ -664,7 +664,7 @@ public: { CAST_PLR(charmer)->GroupEventHappens(12687, me); charmer->RemoveAurasDueToSpell(SPELL_EFFECT_OVERTAKE); - CAST_CRE(who)->ForcedDespawn(); + CAST_CRE(who)->DespawnOrUnsummon(); //CAST_CRE(who)->Respawn(true); } @@ -767,7 +767,7 @@ public: //Todo: Creatures must not be removed, but, must instead // stand next to Gothik and be commanded into the pit // and dig into the ground. - CAST_CRE(who)->ForcedDespawn(); + CAST_CRE(who)->DespawnOrUnsummon(); if (CAST_PLR(owner)->GetQuestStatus(12698) == QUEST_STATUS_COMPLETE) owner->RemoveAllMinionsByEntry(GHOULS); @@ -809,11 +809,11 @@ public: { for (std::list<Creature*>::const_iterator itr = MinionList.begin(); itr != MinionList.end(); ++itr) { - if (CAST_CRE(*itr)->GetOwner()->GetGUID() == me->GetOwner()->GetGUID()) + if ((*itr)->GetOwner()->GetGUID() == me->GetOwner()->GetGUID()) { - if (CAST_CRE(*itr)->isInCombat() && CAST_CRE(*itr)->getAttackerForHelper()) + if ((*itr)->isInCombat() && (*itr)->getAttackerForHelper()) { - AttackStart(CAST_CRE(*itr)->getAttackerForHelper()); + AttackStart((*itr)->getAttackerForHelper()); } } } @@ -826,10 +826,11 @@ public: { if (Unit* owner = me->GetOwner()) { - if (owner->GetTypeId() == TYPEID_PLAYER && CAST_PLR(owner)->isInCombat()) + Player* plrOwner = owner->ToPlayer(); + if (plrOwner && plrOwner->isInCombat()) { - if (CAST_PLR(owner)->getAttackerForHelper() && CAST_PLR(owner)->getAttackerForHelper()->GetEntry() == GHOSTS) - AttackStart(CAST_PLR(owner)->getAttackerForHelper()); + if (plrOwner->getAttackerForHelper() && plrOwner->getAttackerForHelper()->GetEntry() == GHOSTS) + AttackStart(plrOwner->getAttackerForHelper()); else FindMinions(owner); } diff --git a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter2.cpp b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter2.cpp index 2b9dbdd248d..1c17e6afa9b 100644 --- a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter2.cpp +++ b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter2.cpp @@ -627,48 +627,48 @@ public: me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); } - bool MeetQuestCondition(Unit* player) + bool MeetQuestCondition(Player* player) { switch (me->GetEntry()) { case 29061: // Ellen Stanbridge - if (CAST_PLR(player)->GetQuestStatus(12742) == QUEST_STATUS_INCOMPLETE) + if (player->GetQuestStatus(12742) == QUEST_STATUS_INCOMPLETE) return true; break; case 29072: // Kug Ironjaw - if (CAST_PLR(player)->GetQuestStatus(12748) == QUEST_STATUS_INCOMPLETE) + if (player->GetQuestStatus(12748) == QUEST_STATUS_INCOMPLETE) return true; break; case 29067: // Donovan Pulfrost - if (CAST_PLR(player)->GetQuestStatus(12744) == QUEST_STATUS_INCOMPLETE) + if (player->GetQuestStatus(12744) == QUEST_STATUS_INCOMPLETE) return true; break; case 29065: // Yazmina Oakenthorn - if (CAST_PLR(player)->GetQuestStatus(12743) == QUEST_STATUS_INCOMPLETE) + if (player->GetQuestStatus(12743) == QUEST_STATUS_INCOMPLETE) return true; break; case 29071: // Antoine Brack - if (CAST_PLR(player)->GetQuestStatus(12750) == QUEST_STATUS_INCOMPLETE) + if (player->GetQuestStatus(12750) == QUEST_STATUS_INCOMPLETE) return true; break; case 29032: // Malar Bravehorn - if (CAST_PLR(player)->GetQuestStatus(12739) == QUEST_STATUS_INCOMPLETE) + if (player->GetQuestStatus(12739) == QUEST_STATUS_INCOMPLETE) return true; break; case 29068: // Goby Blastenheimer - if (CAST_PLR(player)->GetQuestStatus(12745) == QUEST_STATUS_INCOMPLETE) + if (player->GetQuestStatus(12745) == QUEST_STATUS_INCOMPLETE) return true; break; case 29073: // Iggy Darktusk - if (CAST_PLR(player)->GetQuestStatus(12749) == QUEST_STATUS_INCOMPLETE) + if (player->GetQuestStatus(12749) == QUEST_STATUS_INCOMPLETE) return true; break; case 29074: // Lady Eonys - if (CAST_PLR(player)->GetQuestStatus(12747) == QUEST_STATUS_INCOMPLETE) + if (player->GetQuestStatus(12747) == QUEST_STATUS_INCOMPLETE) return true; break; case 29070: // Valok the Righteous - if (CAST_PLR(player)->GetQuestStatus(12746) == QUEST_STATUS_INCOMPLETE) + if (player->GetQuestStatus(12746) == QUEST_STATUS_INCOMPLETE) return true; break; } @@ -681,7 +681,7 @@ public: if (PlayerGUID || who->GetTypeId() != TYPEID_PLAYER || !who->IsWithinDist(me, INTERACTION_DISTANCE)) return; - if (MeetQuestCondition(who)) + if (MeetQuestCondition(who->ToPlayer())) PlayerGUID = who->GetGUID(); } diff --git a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp index 31dc23d24af..813c43288d0 100644 --- a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp +++ b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp @@ -348,7 +348,7 @@ public: if (wait <= diff) { die = false; - if (Unit* body = Unit::GetUnit((*me), bodyGUID)) + if (Unit* body = Unit::GetUnit(*me, bodyGUID)) body->Kill(body); me->Kill(me); } @@ -475,7 +475,7 @@ public: wp_reached = false; me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); SaySound(SAY_ENTRANCE); - if (Unit* player = Unit::GetUnit((*me), PlayerGUID)) + if (Unit* player = Unit::GetUnit(*me, PlayerGUID)) DoStartMovement(player); break; } @@ -586,7 +586,7 @@ public: std::list<HostileReference*>::const_iterator itr; for (itr = caster->getThreatManager().getThreatList().begin(); itr != caster->getThreatManager().getThreatList().end(); ++itr) { - Unit* unit = Unit::GetUnit((*me), (*itr)->getUnitGuid()); + Unit* unit = Unit::GetUnit(*me, (*itr)->getUnitGuid()); if (unit && unit->isAlive() && unit != caster) me->AddThreat(unit, caster->getThreatManager().getThreat(unit)); } @@ -606,7 +606,7 @@ public: if (!headGUID) headGUID = DoSpawnCreature(HEAD, float(rand()%6), float(rand()%6), 0, 0, TEMPSUMMON_DEAD_DESPAWN, 0)->GetGUID(); - Unit* Head = Unit::GetUnit((*me), headGUID); + Unit* Head = Unit::GetUnit(*me, headGUID); if (Head && Head->isAlive()) { Head->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); @@ -817,7 +817,7 @@ public: if (!debuffGUID) return; - Unit* debuff = Unit::GetUnit((*me), debuffGUID); + Unit* debuff = Unit::GetUnit(*me, debuffGUID); if (debuff) { debuff->SetVisible(false); diff --git a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_high_inquisitor_fairbanks.cpp b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_high_inquisitor_fairbanks.cpp index a64636a4223..1989c318c84 100644 --- a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_high_inquisitor_fairbanks.cpp +++ b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_high_inquisitor_fairbanks.cpp @@ -66,9 +66,15 @@ public: Sleep_Timer = 30000; Dispel_Timer = 20000; PowerWordShield = false; + me->SetStandState(UNIT_STAND_STATE_DEAD); + me->SetUInt32Value(UNIT_FIELD_BYTES_1, 7); } - void EnterCombat(Unit* /*who*/) {} + void EnterCombat(Unit* /*who*/) + { + me->SetStandState(UNIT_STAND_STATE_STAND); + me->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); + } void UpdateAI(const uint32 diff) { diff --git a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_mograine_and_whitemane.cpp b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_mograine_and_whitemane.cpp index ec6ac34b0bb..8d813bfe502 100644 --- a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_mograine_and_whitemane.cpp +++ b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_mograine_and_whitemane.cpp @@ -132,7 +132,7 @@ public: return; //On first death, fake death and open door, as well as initiate whitemane if exist - if (Unit* Whitemane = Unit::GetUnit((*me), instance->GetData64(DATA_WHITEMANE))) + if (Unit* Whitemane = Unit::GetUnit(*me, instance->GetData64(DATA_WHITEMANE))) { instance->SetData(TYPE_MOGRAINE_AND_WHITE_EVENT, IN_PROGRESS); @@ -181,7 +181,7 @@ public: if (_bHasDied && !_bHeal && instance && instance->GetData(TYPE_MOGRAINE_AND_WHITE_EVENT) == SPECIAL) { //On ressurection, stop fake death and heal whitemane and resume fight - if (Unit* Whitemane = Unit::GetUnit((*me), instance->GetData64(DATA_WHITEMANE))) + if (Unit* Whitemane = Unit::GetUnit(*me, instance->GetData64(DATA_WHITEMANE))) { me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); me->SetStandState(UNIT_STAND_STATE_STAND); @@ -292,7 +292,7 @@ public: //When casting resuruction make sure to delay so on rez when reinstate battle deepsleep runs out if (instance && Wait_Timer <= diff) { - if (Unit* Mograine = Unit::GetUnit((*me), instance->GetData64(DATA_MOGRAINE))) + if (Unit* Mograine = Unit::GetUnit(*me, instance->GetData64(DATA_MOGRAINE))) { DoCast(Mograine, SPELL_SCARLETRESURRECTION); DoScriptText(SAY_WH_RESSURECT, me); diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_eredar_twins.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_eredar_twins.cpp index c3398799f17..03486a644a2 100644 --- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_eredar_twins.cpp +++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_eredar_twins.cpp @@ -120,7 +120,7 @@ public: if (instance) { - Unit* Temp = Unit::GetUnit((*me), instance->GetData64(DATA_ALYTHESS)); + Unit* Temp = Unit::GetUnit(*me, instance->GetData64(DATA_ALYTHESS)); if (Temp) { if (Temp->isDead()) @@ -152,7 +152,7 @@ public: if (instance) { - Unit* Temp = Unit::GetUnit((*me), instance->GetData64(DATA_ALYTHESS)); + Unit* Temp = Unit::GetUnit(*me, instance->GetData64(DATA_ALYTHESS)); if (Temp && Temp->isAlive() && !(Temp->getVictim())) CAST_CRE(Temp)->AI()->AttackStart(who); } @@ -231,7 +231,7 @@ public: if (instance) { Unit* Temp = NULL; - Temp = Unit::GetUnit((*me), instance->GetData64(DATA_ALYTHESS)); + Temp = Unit::GetUnit(*me, instance->GetData64(DATA_ALYTHESS)); if (Temp && Temp->isDead()) { DoScriptText(YELL_SISTER_ALYTHESS_DEAD, me); @@ -382,7 +382,7 @@ public: if (instance) { - Unit* Temp = Unit::GetUnit((*me), instance->GetData64(DATA_SACROLASH)); + Unit* Temp = Unit::GetUnit(*me, instance->GetData64(DATA_SACROLASH)); if (Temp) { if (Temp->isDead()) @@ -415,7 +415,7 @@ public: if (instance) { - Unit* Temp = Unit::GetUnit((*me), instance->GetData64(DATA_SACROLASH)); + Unit* Temp = Unit::GetUnit(*me, instance->GetData64(DATA_SACROLASH)); if (Temp && Temp->isAlive() && !(Temp->getVictim())) CAST_CRE(Temp)->AI()->AttackStart(who); } @@ -567,7 +567,7 @@ public: if (instance) { Unit* Temp = NULL; - Temp = Unit::GetUnit((*me), instance->GetData64(DATA_SACROLASH)); + Temp = Unit::GetUnit(*me, instance->GetData64(DATA_SACROLASH)); if (Temp && Temp->isDead()) { DoScriptText(YELL_SISTER_SACROLASH_DEAD, me); diff --git a/src/server/scripts/EasternKingdoms/ZulAman/boss_hexlord.cpp b/src/server/scripts/EasternKingdoms/ZulAman/boss_hexlord.cpp index f63ebe77a1b..b5698d851f8 100644 --- a/src/server/scripts/EasternKingdoms/ZulAman/boss_hexlord.cpp +++ b/src/server/scripts/EasternKingdoms/ZulAman/boss_hexlord.cpp @@ -267,7 +267,7 @@ class boss_hexlord_malacrass : public CreatureScript for (uint8 i = 0; i < 4; ++i) { - Unit* Temp = Unit::GetUnit((*me), AddGUID[i]); + Unit* Temp = Unit::GetUnit(*me, AddGUID[i]); if (Temp && Temp->isAlive()) CAST_CRE(Temp)->AI()->AttackStart(me->getVictim()); else @@ -303,7 +303,7 @@ class boss_hexlord_malacrass : public CreatureScript for (uint8 i = 0; i < 4; ++i) { - Unit* Temp = Unit::GetUnit((*me), AddGUID[i]); + Unit* Temp = Unit::GetUnit(*me, AddGUID[i]); if (Temp && Temp->isAlive()) Temp->DealDamage(Temp, Temp->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); } diff --git a/src/server/scripts/EasternKingdoms/ZulAman/boss_janalai.cpp b/src/server/scripts/EasternKingdoms/ZulAman/boss_janalai.cpp index f9161fb4223..a2125c45689 100644 --- a/src/server/scripts/EasternKingdoms/ZulAman/boss_janalai.cpp +++ b/src/server/scripts/EasternKingdoms/ZulAman/boss_janalai.cpp @@ -289,7 +289,7 @@ class boss_janalai : public CreatureScript { if (BombCount < 40) { - if (Unit* FireBomb = Unit::GetUnit((*me), FireBombGUIDs[BombCount])) + if (Unit* FireBomb = Unit::GetUnit(*me, FireBombGUIDs[BombCount])) { FireBomb->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); DoCast(FireBomb, SPELL_FIRE_BOMB_THROW, true); diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_gahzranka.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_gahzranka.cpp index 84e3de71b1d..ce2fd0848f9 100644 --- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_gahzranka.cpp +++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_gahzranka.cpp @@ -32,15 +32,11 @@ EndScriptData */ class boss_gahzranka : public CreatureScript { public: - - boss_gahzranka() - : CreatureScript("boss_gahzranka") - { - } + boss_gahzranka() : CreatureScript("boss_gahzranka") { } struct boss_gahzrankaAI : public ScriptedAI { - boss_gahzrankaAI(Creature* creature) : ScriptedAI(creature) {} + boss_gahzrankaAI(Creature* creature) : ScriptedAI(creature) { } uint32 Frostbreath_Timer; uint32 MassiveGeyser_Timer; uint32 Slam_Timer; diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_grilek.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_grilek.cpp index 19d0a04b9a6..cdd45a3fa0d 100644 --- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_grilek.cpp +++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_grilek.cpp @@ -32,15 +32,11 @@ EndScriptData */ class boss_grilek : public CreatureScript { public: - - boss_grilek() - : CreatureScript("boss_grilek") - { - } + boss_grilek() : CreatureScript("boss_grilek") { } struct boss_grilekAI : public ScriptedAI { - boss_grilekAI(Creature* creature) : ScriptedAI(creature) {} + boss_grilekAI(Creature* creature) : ScriptedAI(creature) { } uint32 Avartar_Timer; uint32 GroundTremor_Timer; diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_jindo.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_jindo.cpp index d7901d663f3..f4a17da56fb 100644 --- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_jindo.cpp +++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_jindo.cpp @@ -212,7 +212,7 @@ class mob_healing_ward : public CreatureScript { if (instance) { - Unit* pJindo = Unit::GetUnit((*me), instance->GetData64(DATA_JINDO)); + Unit* pJindo = Unit::GetUnit(*me, instance->GetData64(DATA_JINDO)); if (pJindo) DoCast(pJindo, SPELL_HEAL); } diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_thekal.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_thekal.cpp index d85f99b0295..ce6b3b37ef8 100644 --- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_thekal.cpp +++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_thekal.cpp @@ -134,7 +134,7 @@ class boss_thekal : public CreatureScript if (instance->GetData(DATA_LORKHAN) == SPECIAL) { //Resurrect LorKhan - if (Unit* pLorKhan = Unit::GetUnit((*me), instance->GetData64(DATA_LORKHAN))) + if (Unit* pLorKhan = Unit::GetUnit(*me, instance->GetData64(DATA_LORKHAN))) { pLorKhan->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); pLorKhan->setFaction(14); @@ -148,7 +148,7 @@ class boss_thekal : public CreatureScript if (instance->GetData(DATA_ZATH) == SPECIAL) { //Resurrect Zath - Unit* pZath = Unit::GetUnit((*me), instance->GetData64(DATA_ZATH)); + Unit* pZath = Unit::GetUnit(*me, instance->GetData64(DATA_ZATH)); if (pZath) { pZath->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); @@ -337,8 +337,8 @@ class mob_zealot_lorkhan : public CreatureScript { if (instance) { - Unit* pThekal = Unit::GetUnit((*me), instance->GetData64(DATA_THEKAL)); - Unit* pZath = Unit::GetUnit((*me), instance->GetData64(DATA_ZATH)); + Unit* pThekal = Unit::GetUnit(*me, instance->GetData64(DATA_THEKAL)); + Unit* pZath = Unit::GetUnit(*me, instance->GetData64(DATA_ZATH)); if (!pThekal || !pZath) return; @@ -374,7 +374,7 @@ class mob_zealot_lorkhan : public CreatureScript if (instance->GetData(DATA_THEKAL) == SPECIAL) { //Resurrect Thekal - if (Unit* pThekal = Unit::GetUnit((*me), instance->GetData64(DATA_THEKAL))) + if (Unit* pThekal = Unit::GetUnit(*me, instance->GetData64(DATA_THEKAL))) { pThekal->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); pThekal->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); @@ -386,7 +386,7 @@ class mob_zealot_lorkhan : public CreatureScript if (instance->GetData(DATA_ZATH) == SPECIAL) { //Resurrect Zath - if (Unit* pZath = Unit::GetUnit((*me), instance->GetData64(DATA_ZATH))) + if (Unit* pZath = Unit::GetUnit(*me, instance->GetData64(DATA_ZATH))) { pZath->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); pZath->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); @@ -527,7 +527,7 @@ class mob_zealot_zath : public CreatureScript if (instance->GetData(DATA_LORKHAN) == SPECIAL) { //Resurrect LorKhan - if (Unit* pLorKhan = Unit::GetUnit((*me), instance->GetData64(DATA_LORKHAN))) + if (Unit* pLorKhan = Unit::GetUnit(*me, instance->GetData64(DATA_LORKHAN))) { pLorKhan->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); pLorKhan->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); @@ -539,7 +539,7 @@ class mob_zealot_zath : public CreatureScript if (instance->GetData(DATA_THEKAL) == SPECIAL) { //Resurrect Thekal - if (Unit* pThekal = Unit::GetUnit((*me), instance->GetData64(DATA_THEKAL))) + if (Unit* pThekal = Unit::GetUnit(*me, instance->GetData64(DATA_THEKAL))) { pThekal->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); pThekal->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); diff --git a/src/server/scripts/EasternKingdoms/eastern_plaguelands.cpp b/src/server/scripts/EasternKingdoms/eastern_plaguelands.cpp index 731067a774f..0519ce94b32 100644 --- a/src/server/scripts/EasternKingdoms/eastern_plaguelands.cpp +++ b/src/server/scripts/EasternKingdoms/eastern_plaguelands.cpp @@ -32,23 +32,14 @@ EndContentData */ #include "ScriptPCH.h" -//id8530 - cannibal ghoul -//id8531 - gibbering ghoul -//id8532 - diseased flayer - class mobs_ghoul_flayer : public CreatureScript { public: mobs_ghoul_flayer() : CreatureScript("mobs_ghoul_flayer") { } - CreatureAI* GetAI(Creature* creature) const - { - return new mobs_ghoul_flayerAI (creature); - } - struct mobs_ghoul_flayerAI : public ScriptedAI { - mobs_ghoul_flayerAI(Creature* creature) : ScriptedAI(creature) {} + mobs_ghoul_flayerAI(Creature* creature) : ScriptedAI(creature) { } void Reset() {} @@ -56,10 +47,15 @@ public: void JustDied(Unit* killer) { - if (Player* player = killer->ToPlayer()) + if (killer->GetTypeId() == TYPEID_PLAYER) me->SummonCreature(11064, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 60000); } }; + + CreatureAI* GetAI(Creature* creature) const + { + return new mobs_ghoul_flayerAI (creature); + } }; /*###### diff --git a/src/server/scripts/EasternKingdoms/eversong_woods.cpp b/src/server/scripts/EasternKingdoms/eversong_woods.cpp index 016dd60b39c..8ae72e142c8 100644 --- a/src/server/scripts/EasternKingdoms/eversong_woods.cpp +++ b/src/server/scripts/EasternKingdoms/eversong_woods.cpp @@ -490,14 +490,14 @@ public: { if (PlayerGUID) if (Player* player = Unit::GetPlayer(*me, PlayerGUID)) - CAST_PLR(player)->FailQuest(QUEST_UNEXPECTED_RESULT); + player->FailQuest(QUEST_UNEXPECTED_RESULT); } void UpdateAI(const uint32 /*diff*/) { if (KillCount >= 3 && PlayerGUID) if (Player* player = Unit::GetPlayer(*me, PlayerGUID)) - CAST_PLR(player)->CompleteQuest(QUEST_UNEXPECTED_RESULT); + player->CompleteQuest(QUEST_UNEXPECTED_RESULT); if (Summon) { diff --git a/src/server/scripts/EasternKingdoms/isle_of_queldanas.cpp b/src/server/scripts/EasternKingdoms/isle_of_queldanas.cpp index 98ac2ff4cc1..27d8ea3e51c 100644 --- a/src/server/scripts/EasternKingdoms/isle_of_queldanas.cpp +++ b/src/server/scripts/EasternKingdoms/isle_of_queldanas.cpp @@ -129,8 +129,8 @@ public: PlayerGUID = caster->GetGUID(); if (PlayerGUID) { - Unit* player = Unit::GetUnit((*me), PlayerGUID); - if (player && CAST_PLR(player)->GetQuestStatus(QUESTG) == QUEST_STATUS_INCOMPLETE) + Player* player = Unit::GetPlayer(*me, PlayerGUID); + if (player && player->GetQuestStatus(QUESTG) == QUEST_STATUS_INCOMPLETE) DoCast(player, 45110, true); } DoCast(me, ENRAGE); diff --git a/src/server/scripts/EasternKingdoms/stormwind_city.cpp b/src/server/scripts/EasternKingdoms/stormwind_city.cpp index 7e5e9e3cf89..96ad1da725d 100644 --- a/src/server/scripts/EasternKingdoms/stormwind_city.cpp +++ b/src/server/scripts/EasternKingdoms/stormwind_city.cpp @@ -403,7 +403,7 @@ public: { if (Unit* summoner = me->ToTempSummon()->GetSummoner()) { - if (summoner && summoner->GetTypeId() == TYPEID_UNIT && summoner->isAlive() && !summoner->isInCombat()) + if (summoner->GetTypeId() == TYPEID_UNIT && summoner->isAlive() && !summoner->isInCombat()) summoner->ToCreature()->AI()->AttackStart(who); } } @@ -417,7 +417,7 @@ public: { if (Unit* summoner = me->ToTempSummon()->GetSummoner()) { - if (summoner && summoner->GetTypeId() == TYPEID_UNIT && summoner->isAlive()) + if (summoner->GetTypeId() == TYPEID_UNIT && summoner->isAlive()) summoner->ToCreature()->DisappearAndDie(); } } diff --git a/src/server/scripts/EasternKingdoms/undercity.cpp b/src/server/scripts/EasternKingdoms/undercity.cpp index 0522e214012..a9b627ded34 100644 --- a/src/server/scripts/EasternKingdoms/undercity.cpp +++ b/src/server/scripts/EasternKingdoms/undercity.cpp @@ -47,7 +47,15 @@ enum Sylvanas SPELL_HIGHBORNE_AURA = 37090, SPELL_SYLVANAS_CAST = 36568, - SPELL_RIBBON_OF_SOULS = 34432, //the real one to use might be 37099 + SPELL_RIBBON_OF_SOULS = 34432, // the real one to use might be 37099 + + // Combat spells + SPELL_BLACK_ARROW = 59712, + SPELL_FADE = 20672, + SPELL_FADE_BLINK = 29211, + SPELL_MULTI_SHOT = 59713, + SPELL_SHOT = 59710, + SPELL_SUMMON_SKELETON = 59711 }; float HighborneLoc[4][3]= @@ -90,15 +98,27 @@ public: { npc_lady_sylvanas_windrunnerAI(Creature* creature) : ScriptedAI(creature) {} - uint32 LamentEvent_Timer; + uint32 LamentEventTimer; bool LamentEvent; uint64 targetGUID; + uint32 FadeTimer; + uint32 SummonSkeletonTimer; + uint32 BlackArrowTimer; + uint32 ShotTimer; + uint32 MultiShotTimer; + void Reset() { - LamentEvent_Timer = 5000; + LamentEventTimer = 5000; LamentEvent = false; targetGUID = 0; + + FadeTimer = 30000; + SummonSkeletonTimer = 20000; + BlackArrowTimer = 15000; + ShotTimer = 8000; + MultiShotTimer = 10000; } void EnterCombat(Unit* /*who*/) {} @@ -123,23 +143,70 @@ public: { if (LamentEvent) { - if (LamentEvent_Timer <= diff) + if (LamentEventTimer <= diff) { DoSummon(ENTRY_HIGHBORNE_BUNNY, me, 10.0f, 3000, TEMPSUMMON_TIMED_DESPAWN); - LamentEvent_Timer = 2000; + LamentEventTimer = 2000; if (!me->HasAura(SPELL_SYLVANAS_CAST)) { DoScriptText(SAY_LAMENT_END, me); DoScriptText(EMOTE_LAMENT_END, me); LamentEvent = false; } - } else LamentEvent_Timer -= diff; + } else LamentEventTimer -= diff; } if (!UpdateVictim()) return; + // Combat spells + + if (FadeTimer <= diff) + { + DoCast(me, SPELL_FADE); + // add a blink to simulate a stealthed movement and reappearing elsewhere + DoCast(me, SPELL_FADE_BLINK); + FadeTimer = 30000 + rand()%5000; + // if the victim is out of melee range she cast multi shot + if (Unit* victim = me->getVictim()) + if (me->GetDistance(victim) > 10.0f) + DoCast(victim, SPELL_MULTI_SHOT); + } else FadeTimer -= diff; + + if (SummonSkeletonTimer <= diff) + { + DoCast(me, SPELL_SUMMON_SKELETON); + SummonSkeletonTimer = 20000 + rand()%10000; + } else SummonSkeletonTimer -= diff; + + if (BlackArrowTimer <= diff) + { + if (Unit* victim = me->getVictim()) + { + DoCast(victim, SPELL_BLACK_ARROW); + BlackArrowTimer = 15000 + rand()%5000; + } + } else BlackArrowTimer -= diff; + + if (ShotTimer <= diff) + { + if (Unit* victim = me->getVictim()) + { + DoCast(victim, SPELL_SHOT); + ShotTimer = 8000 + rand()%2000; + } + } else ShotTimer -= diff; + + if (MultiShotTimer <= diff) + { + if (Unit* victim = me->getVictim()) + { + DoCast(victim, SPELL_MULTI_SHOT); + MultiShotTimer = 10000 + rand()%3000; + } + } else MultiShotTimer -= diff; + DoMeleeAttackIfReady(); } }; @@ -163,15 +230,15 @@ public: { npc_highborne_lamenterAI(Creature* creature) : ScriptedAI(creature) {} - uint32 EventMove_Timer; - uint32 EventCast_Timer; + uint32 EventMoveTimer; + uint32 EventCastTimer; bool EventMove; bool EventCast; void Reset() { - EventMove_Timer = 10000; - EventCast_Timer = 17500; + EventMoveTimer = 10000; + EventCastTimer = 17500; EventMove = true; EventCast = true; } @@ -182,21 +249,21 @@ public: { if (EventMove) { - if (EventMove_Timer <= diff) + if (EventMoveTimer <= diff) { me->SetDisableGravity(true); me->MonsterMoveWithSpeed(me->GetPositionX(), me->GetPositionY(), HIGHBORNE_LOC_Y_NEW, me->GetDistance(me->GetPositionX(), me->GetPositionY(), HIGHBORNE_LOC_Y_NEW) / (5000 * 0.001f)); me->SetPosition(me->GetPositionX(), me->GetPositionY(), HIGHBORNE_LOC_Y_NEW, me->GetOrientation()); EventMove = false; - } else EventMove_Timer -= diff; + } else EventMoveTimer -= diff; } if (EventCast) { - if (EventCast_Timer <= diff) + if (EventCastTimer <= diff) { DoCast(me, SPELL_HIGHBORNE_AURA); EventCast = false; - } else EventCast_Timer -= diff; + } else EventCastTimer -= diff; } } }; diff --git a/src/server/scripts/Examples/example_spell.cpp b/src/server/scripts/Examples/example_spell.cpp index 8c721c141af..70d7f43135c 100644 --- a/src/server/scripts/Examples/example_spell.cpp +++ b/src/server/scripts/Examples/example_spell.cpp @@ -102,7 +102,7 @@ class spell_ex_5581 : public SpellScriptLoader { // in this hook you can add additional requirements for spell caster (and throw a client error if reqs're not passed) // in this case we're disallowing to select non-player as a target of the spell - //if (!GetTargetUnit() || GetTargetUnit()->ToPlayer()) + //if (!GetExplTargetUnit() || GetExplTargetUnit()->ToPlayer()) //return SPELL_FAILED_BAD_TARGETS; return SPELL_CAST_OK; } diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_anetheron.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_anetheron.cpp index e0a0ff1dc59..85f82c62079 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_anetheron.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_anetheron.cpp @@ -119,7 +119,7 @@ public: { if (waypointId == 7 && instance) { - Unit* target = Unit::GetUnit((*me), instance->GetData64(DATA_JAINAPROUDMOORE)); + Unit* target = Unit::GetUnit(*me, instance->GetData64(DATA_JAINAPROUDMOORE)); if (target && target->isAlive()) me->AddThreat(target, 0.0f); } diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp index e22dbd972e5..f07aaaa1f2a 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp @@ -117,7 +117,7 @@ public: { if (CheckTimer <= diff) { - if (Unit* Archimonde = Unit::GetUnit((*me), ArchimondeGUID)) + if (Unit* Archimonde = Unit::GetUnit(*me, ArchimondeGUID)) { if (Archimonde->HealthBelowPct(2) || !Archimonde->isAlive()) DoCast(me, SPELL_DENOUEMENT_WISP); @@ -367,7 +367,7 @@ public: std::list<HostileReference*>::const_iterator itr = m_threatlist.begin(); for (; itr != m_threatlist.end(); ++itr) { - Unit* unit = Unit::GetUnit((*me), (*itr)->getUnitGuid()); + Unit* unit = Unit::GetUnit(*me, (*itr)->getUnitGuid()); if (unit && unit->isAlive()) targets.push_back(unit); } diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_azgalor.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_azgalor.cpp index 24fe1b5957b..a9e0c866ab9 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_azgalor.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_azgalor.cpp @@ -115,7 +115,7 @@ public: { if (waypointId == 7 && instance) { - Unit* target = Unit::GetUnit((*me), instance->GetData64(DATA_THRALL)); + Unit* target = Unit::GetUnit(*me, instance->GetData64(DATA_THRALL)); if (target && target->isAlive()) me->AddThreat(target, 0.0f); } diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_kazrogal.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_kazrogal.cpp index de8759b3968..407faa19eaa 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_kazrogal.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_kazrogal.cpp @@ -107,7 +107,7 @@ public: { if (waypointId == 7 && instance) { - Unit* target = Unit::GetUnit((*me), instance->GetData64(DATA_THRALL)); + Unit* target = Unit::GetUnit(*me, instance->GetData64(DATA_THRALL)); if (target && target->isAlive()) me->AddThreat(target, 0.0f); } diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_rage_winterchill.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_rage_winterchill.cpp index f328b55f766..5d7ee1fe194 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_rage_winterchill.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_rage_winterchill.cpp @@ -109,7 +109,7 @@ public: { if (waypointId == 7 && instance) { - Unit* target = Unit::GetUnit((*me), instance->GetData64(DATA_JAINAPROUDMOORE)); + Unit* target = Unit::GetUnit(*me, instance->GetData64(DATA_JAINAPROUDMOORE)); if (target && target->isAlive()) me->AddThreat(target, 0.0f); } diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.cpp index 28457b3b461..22307468f14 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.cpp @@ -226,7 +226,6 @@ public: player->SendNewItem(item, 1, true, false, true); } player->SEND_GOSSIP_MENU(907, creature->GetGUID()); - CAST_AI(hyjalAI, creature->AI()); } return true; } diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.cpp index 115aa3b6445..2f6bbb7edb5 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.cpp @@ -855,7 +855,7 @@ void hyjalAI::UpdateAI(const uint32 diff) { if (BossGUID[i]) { - Unit* unit = Unit::GetUnit((*me), BossGUID[i]); + Unit* unit = Unit::GetUnit(*me, BossGUID[i]); if (unit && (!unit->isAlive())) { if (BossGUID[i] == BossGUID[0]) @@ -991,7 +991,7 @@ void hyjalAI::WaypointReached(uint32 waypointId) DoCast(me, SPELL_MASS_TELEPORT, false); if (me->GetEntry() == THRALL && DummyGuid) { - Unit* Dummy = Unit::GetUnit((*me), DummyGuid); + Unit* Dummy = Unit::GetUnit(*me, DummyGuid); if (Dummy) { CAST_AI(hyjalAI, CAST_CRE(Dummy)->AI())->DoMassTeleport = true; diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp index e63b33faf70..840aa5de081 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp @@ -432,7 +432,7 @@ public: { if (instance->GetData(DATA_ALLIANCE_RETREAT))//2.alliance boss down, attack thrall { - Unit* target = Unit::GetUnit((*me), instance->GetData64(DATA_THRALL)); + Unit* target = Unit::GetUnit(*me, instance->GetData64(DATA_THRALL)); if (target && target->isAlive()) me->AddThreat(target, 0.0f); } @@ -473,7 +473,7 @@ public: { if (instance->GetData(DATA_ALLIANCE_RETREAT) && !instance->GetData(DATA_HORDE_RETREAT)) { - Unit* target = Unit::GetUnit((*me), instance->GetData64(DATA_THRALL)); + Unit* target = Unit::GetUnit(*me, instance->GetData64(DATA_THRALL)); if (target && target->isAlive()) me->AddThreat(target, 0.0f); } else if (instance->GetData(DATA_ALLIANCE_RETREAT) && instance->GetData(DATA_HORDE_RETREAT)){ @@ -557,13 +557,13 @@ public: { if (instance->GetData(DATA_ALLIANCE_RETREAT))//2.alliance boss down, attack thrall { - Unit* target = Unit::GetUnit((*me), instance->GetData64(DATA_THRALL)); + Unit* target = Unit::GetUnit(*me, instance->GetData64(DATA_THRALL)); if (target && target->isAlive()) me->AddThreat(target, 0.0f); } else { - Unit* target = Unit::GetUnit((*me), instance->GetData64(DATA_JAINAPROUDMOORE)); + Unit* target = Unit::GetUnit(*me, instance->GetData64(DATA_JAINAPROUDMOORE)); if (target && target->isAlive()) me->AddThreat(target, 0.0f); } @@ -661,13 +661,13 @@ public: { if (instance->GetData(DATA_ALLIANCE_RETREAT))//2.alliance boss down, attack thrall { - Unit* target = Unit::GetUnit((*me), instance->GetData64(DATA_THRALL)); + Unit* target = Unit::GetUnit(*me, instance->GetData64(DATA_THRALL)); if (target && target->isAlive()) me->AddThreat(target, 0.0f); } else { - Unit* target = Unit::GetUnit((*me), instance->GetData64(DATA_JAINAPROUDMOORE)); + Unit* target = Unit::GetUnit(*me, instance->GetData64(DATA_JAINAPROUDMOORE)); if (target && target->isAlive()) me->AddThreat(target, 0.0f); } @@ -780,13 +780,13 @@ public: { if (instance->GetData(DATA_ALLIANCE_RETREAT))//2.alliance boss down, attack thrall { - Unit* target = Unit::GetUnit((*me), instance->GetData64(DATA_THRALL)); + Unit* target = Unit::GetUnit(*me, instance->GetData64(DATA_THRALL)); if (target && target->isAlive()) me->AddThreat(target, 0.0f); } else { - Unit* target = Unit::GetUnit((*me), instance->GetData64(DATA_JAINAPROUDMOORE)); + Unit* target = Unit::GetUnit(*me, instance->GetData64(DATA_JAINAPROUDMOORE)); if (target && target->isAlive()) me->AddThreat(target, 0.0f); } @@ -900,13 +900,13 @@ public: { if (instance->GetData(DATA_ALLIANCE_RETREAT))//2.alliance boss down, attack thrall { - Unit* target = Unit::GetUnit((*me), instance->GetData64(DATA_THRALL)); + Unit* target = Unit::GetUnit(*me, instance->GetData64(DATA_THRALL)); if (target && target->isAlive()) me->AddThreat(target, 0.0f); } else { - Unit* target = Unit::GetUnit((*me), instance->GetData64(DATA_JAINAPROUDMOORE)); + Unit* target = Unit::GetUnit(*me, instance->GetData64(DATA_JAINAPROUDMOORE)); if (target && target->isAlive()) me->AddThreat(target, 0.0f); } @@ -1001,13 +1001,13 @@ public: { if (instance->GetData(DATA_ALLIANCE_RETREAT))//2.alliance boss down, attack thrall { - Unit* target = Unit::GetUnit((*me), instance->GetData64(DATA_THRALL)); + Unit* target = Unit::GetUnit(*me, instance->GetData64(DATA_THRALL)); if (target && target->isAlive()) me->AddThreat(target, 0.0f); } else { - Unit* target = Unit::GetUnit((*me), instance->GetData64(DATA_JAINAPROUDMOORE)); + Unit* target = Unit::GetUnit(*me, instance->GetData64(DATA_JAINAPROUDMOORE)); if (target && target->isAlive()) me->AddThreat(target, 0.0f); } @@ -1093,13 +1093,13 @@ public: { if (instance->GetData(DATA_ALLIANCE_RETREAT))//2.alliance boss down, attack thrall { - Unit* target = Unit::GetUnit((*me), instance->GetData64(DATA_THRALL)); + Unit* target = Unit::GetUnit(*me, instance->GetData64(DATA_THRALL)); if (target && target->isAlive()) me->AddThreat(target, 0.0f); } else { - Unit* target = Unit::GetUnit((*me), instance->GetData64(DATA_JAINAPROUDMOORE)); + Unit* target = Unit::GetUnit(*me, instance->GetData64(DATA_JAINAPROUDMOORE)); if (target && target->isAlive()) me->AddThreat(target, 0.0f); } @@ -1186,7 +1186,7 @@ public: { if (waypointId == 2 && instance && !IsOverrun) { - Unit* target = Unit::GetUnit((*me), instance->GetData64(DATA_THRALL)); + Unit* target = Unit::GetUnit(*me, instance->GetData64(DATA_THRALL)); if (target && target->isAlive()) { me->AddThreat(target, 0.0f); @@ -1305,7 +1305,7 @@ public: { if (waypointId == 2 && instance && !IsOverrun) { - Unit* target = Unit::GetUnit((*me), instance->GetData64(DATA_THRALL)); + Unit* target = Unit::GetUnit(*me, instance->GetData64(DATA_THRALL)); if (target && target->isAlive()) { me->AddThreat(target, 0.0f); diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/DarkPortal/instance_dark_portal.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/DarkPortal/instance_dark_portal.cpp index dabf3db13cb..2c8cd096644 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/DarkPortal/instance_dark_portal.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/DarkPortal/instance_dark_portal.cpp @@ -116,9 +116,9 @@ public: DoUpdateWorldState(WORLD_STATE_BM_RIFT, 0); } - bool IsEncounterInProgress() + bool IsEncounterInProgress() const { - if (GetData(TYPE_MEDIVH) == IN_PROGRESS) + if (const_cast<instance_dark_portal_InstanceMapScript*>(this)->GetData(TYPE_MEDIVH) == IN_PROGRESS) return true; return false; diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.cpp index d9cdccf2291..7d9da6771dc 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.cpp @@ -413,7 +413,7 @@ public: case 94: if (uint64 TarethaGUID = instance->GetData64(DATA_TARETHA)) { - if (Unit* Taretha = Unit::GetUnit((*me), TarethaGUID)) + if (Unit* Taretha = Unit::GetUnit(*me, TarethaGUID)) DoScriptText(SAY_TA_ESCAPED, Taretha, me); } break; diff --git a/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_moam.cpp b/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_moam.cpp index a290b07e60f..18a77519ba2 100644 --- a/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_moam.cpp +++ b/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_moam.cpp @@ -147,7 +147,7 @@ class boss_moam : public CreatureScript targetList.push_back((*itr)->getTarget()); } - Trinity::RandomResizeList(targetList, 5); + Trinity::Containers::RandomResizeList(targetList, 5); for (std::list<Unit*>::iterator itr = targetList.begin(); itr != targetList.end(); ++itr) DoCast(*itr, SPELL_DRAIN_MANA); diff --git a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_bug_trio.cpp b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_bug_trio.cpp index ce73c7ceb69..36b1871c96e 100644 --- a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_bug_trio.cpp +++ b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_bug_trio.cpp @@ -303,8 +303,8 @@ public: { if (instance) { - Unit* pKri = Unit::GetUnit((*me), instance->GetData64(DATA_KRI)); - Unit* pVem = Unit::GetUnit((*me), instance->GetData64(DATA_VEM)); + Unit* pKri = Unit::GetUnit(*me, instance->GetData64(DATA_KRI)); + Unit* pVem = Unit::GetUnit(*me, instance->GetData64(DATA_VEM)); switch (urand(0, 2)) { diff --git a/src/server/scripts/Kalimdor/ashenvale.cpp b/src/server/scripts/Kalimdor/ashenvale.cpp index ff4f90672fc..e28665c038e 100644 --- a/src/server/scripts/Kalimdor/ashenvale.cpp +++ b/src/server/scripts/Kalimdor/ashenvale.cpp @@ -28,7 +28,8 @@ npc_torek npc_ruul_snowhoof EndContentData */ -#include "ScriptPCH.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" #include "ScriptedEscortAI.h" /*#### @@ -78,32 +79,31 @@ class npc_torek : public CreatureScript void WaypointReached(uint32 waypointId) { - Player* player = GetPlayerForEscort(); - if (!player) - return; - - switch (waypointId) + if (Player* player = GetPlayerForEscort()) { - case 1: - Talk(SAY_MOVE, player->GetGUID()); - break; - case 8: - Talk(SAY_PREPARE, player->GetGUID()); - break; - case 19: - //TODO: verify location and creatures amount. - me->SummonCreature(ENTRY_DURIEL, 1776.73f, -2049.06f, 109.83f, 1.54f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); - me->SummonCreature(ENTRY_SILVERWING_SENTINEL, 1774.64f, -2049.41f, 109.83f, 1.40f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); - me->SummonCreature(ENTRY_SILVERWING_WARRIOR, 1778.73f, -2049.50f, 109.83f, 1.67f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); - break; - case 20: - DoScriptText(SAY_WIN, me, player); - Completed = true; - player->GroupEventHappens(QUEST_TOREK_ASSULT, me); - break; - case 21: - Talk(SAY_END, player->GetGUID()); - break; + switch (waypointId) + { + case 1: + Talk(SAY_MOVE, player->GetGUID()); + break; + case 8: + Talk(SAY_PREPARE, player->GetGUID()); + break; + case 19: + //TODO: verify location and creatures amount. + me->SummonCreature(ENTRY_DURIEL, 1776.73f, -2049.06f, 109.83f, 1.54f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); + me->SummonCreature(ENTRY_SILVERWING_SENTINEL, 1774.64f, -2049.41f, 109.83f, 1.40f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); + me->SummonCreature(ENTRY_SILVERWING_WARRIOR, 1778.73f, -2049.50f, 109.83f, 1.67f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); + break; + case 20: + DoScriptText(SAY_WIN, me, player); + Completed = true; + player->GroupEventHappens(QUEST_TOREK_ASSULT, me); + break; + case 21: + Talk(SAY_END, player->GetGUID()); + break; + } } } @@ -169,8 +169,26 @@ class npc_torek : public CreatureScript # npc_ruul_snowhoof ####*/ -#define QUEST_FREEDOM_TO_RUUL 6482 -#define GO_CAGE 178147 +enum RuulSnowhoof +{ + NPC_THISTLEFUR_URSA = 3921, + NPC_THISTLEFUR_TOTEMIC = 3922, + NPC_THISTLEFUR_PATHFINDER = 3926, + + QUEST_FREEDOM_TO_RUUL = 6482, + + GO_CAGE = 178147 +}; + +Position const RuulSnowhoofSummonsCoord[6] = +{ + {3449.218018f, -587.825073f, 174.978867f, 4.714445f}, + {3446.384521f, -587.830872f, 175.186279f, 4.714445f}, + {3444.218994f, -587.835327f, 175.380600f, 4.714445f}, + {3508.344482f, -492.024261f, 186.929031f, 4.145029f}, + {3506.265625f, -490.531006f, 186.740128f, 4.239277f}, + {3503.682373f, -489.393799f, 186.629684f, 4.349232f} +}; class npc_ruul_snowhoof : public CreatureScript { @@ -195,14 +213,14 @@ class npc_ruul_snowhoof : public CreatureScript Cage->SetGoState(GO_STATE_ACTIVE); break; case 13: - me->SummonCreature(3922, 3449.218018f, -587.825073f, 174.978867f, 4.714445f, TEMPSUMMON_DEAD_DESPAWN, 60000); - me->SummonCreature(3921, 3446.384521f, -587.830872f, 175.186279f, 4.714445f, TEMPSUMMON_DEAD_DESPAWN, 60000); - me->SummonCreature(3926, 3444.218994f, -587.835327f, 175.380600f, 4.714445f, TEMPSUMMON_DEAD_DESPAWN, 60000); + me->SummonCreature(NPC_THISTLEFUR_TOTEMIC, RuulSnowhoofSummonsCoord[0], TEMPSUMMON_DEAD_DESPAWN, 60000); + me->SummonCreature(NPC_THISTLEFUR_URSA, RuulSnowhoofSummonsCoord[1], TEMPSUMMON_DEAD_DESPAWN, 60000); + me->SummonCreature(NPC_THISTLEFUR_PATHFINDER, RuulSnowhoofSummonsCoord[2], TEMPSUMMON_DEAD_DESPAWN, 60000); break; case 19: - me->SummonCreature(3922, 3508.344482f, -492.024261f, 186.929031f, 4.145029f, TEMPSUMMON_DEAD_DESPAWN, 60000); - me->SummonCreature(3921, 3506.265625f, -490.531006f, 186.740128f, 4.239277f, TEMPSUMMON_DEAD_DESPAWN, 60000); - me->SummonCreature(3926, 3503.682373f, -489.393799f, 186.629684f, 4.349232f, TEMPSUMMON_DEAD_DESPAWN, 60000); + me->SummonCreature(NPC_THISTLEFUR_TOTEMIC, RuulSnowhoofSummonsCoord[3], TEMPSUMMON_DEAD_DESPAWN, 60000); + me->SummonCreature(NPC_THISTLEFUR_URSA, RuulSnowhoofSummonsCoord[4], TEMPSUMMON_DEAD_DESPAWN, 60000); + me->SummonCreature(NPC_THISTLEFUR_PATHFINDER, RuulSnowhoofSummonsCoord[5], TEMPSUMMON_DEAD_DESPAWN, 60000); break; case 21: player->GroupEventHappens(QUEST_FREEDOM_TO_RUUL, me); @@ -214,8 +232,7 @@ class npc_ruul_snowhoof : public CreatureScript void Reset() { - GameObject* Cage = me->FindNearestGameObject(GO_CAGE, 20); - if (Cage) + if (GameObject* Cage = me->FindNearestGameObject(GO_CAGE, 20)) Cage->SetGoState(GO_STATE_READY); } @@ -249,7 +266,7 @@ class npc_ruul_snowhoof : public CreatureScript } }; -enum eEnums +enum Muglash { SAY_MUG_START1 = -1800054, SAY_MUG_START2 = -1800055, @@ -278,21 +295,21 @@ enum eEnums NPC_MUGLASH = 12717 }; -static float m_afFirstNagaCoord[3][3]= +Position const FirstNagaCoord[3] = { - {3603.504150f, 1122.631104f, 1.635f}, // rider - {3589.293945f, 1148.664063f, 5.565f}, // sorceress - {3609.925537f, 1168.759521f, -1.168f} // razortail + {3603.504150f, 1122.631104f, 1.635f, 0.0f}, // rider + {3589.293945f, 1148.664063f, 5.565f, 0.0f}, // sorceress + {3609.925537f, 1168.759521f, -1.168f, 0.0f} // razortail }; -static float m_afSecondNagaCoord[3][3]= +Position const SecondNagaCoord[3] = { - {3609.925537f, 1168.759521f, -1.168f}, // witch - {3645.652100f, 1139.425415f, 1.322f}, // priest - {3583.602051f, 1128.405762f, 2.347f} // myrmidon + {3609.925537f, 1168.759521f, -1.168f, 0.0f}, // witch + {3645.652100f, 1139.425415f, 1.322f, 0.0f}, // priest + {3583.602051f, 1128.405762f, 2.347f, 0.0f} // myrmidon }; -static float m_fVorshaCoord[]={3633.056885f, 1172.924072f, -5.388f}; +Position const VorshaCoord = {3633.056885f, 1172.924072f, -5.388f, 0.0f}; class npc_muglash : public CreatureScript { @@ -303,9 +320,9 @@ class npc_muglash : public CreatureScript { npc_muglashAI(Creature* creature) : npc_escortAI(creature) { } - uint32 m_uiWaveId; - uint32 m_uiEventTimer; - bool m_bIsBrazierExtinguished; + uint8 WaveId; + uint32 EventTimer; + bool IsBrazierExtinguished; void JustSummoned(Creature* summoned) { @@ -314,34 +331,33 @@ class npc_muglash : public CreatureScript void WaypointReached(uint32 waypointId) { - Player* player = GetPlayerForEscort(); - - switch (waypointId) + if (Player* player = GetPlayerForEscort()) { - case 0: - if (player) + switch (waypointId) + { + case 0: DoScriptText(SAY_MUG_START2, me, player); - break; - case 24: - if (player) + break; + case 24: DoScriptText(SAY_MUG_BRAZIER, me, player); - if (GameObject* go = GetClosestGameObjectWithEntry(me, GO_NAGA_BRAZIER, INTERACTION_DISTANCE*2)) - { - go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); - SetEscortPaused(true); - } - break; - case 25: - DoScriptText(SAY_MUG_GRATITUDE, me); - player->GroupEventHappens(QUEST_VORSHA, me); - break; - case 26: - DoScriptText(SAY_MUG_PATROL, me); - break; - case 27: - DoScriptText(SAY_MUG_RETURN, me); - break; + if (GameObject* go = GetClosestGameObjectWithEntry(me, GO_NAGA_BRAZIER, INTERACTION_DISTANCE*2)) + { + go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); + SetEscortPaused(true); + } + break; + case 25: + DoScriptText(SAY_MUG_GRATITUDE, me); + player->GroupEventHappens(QUEST_VORSHA, me); + break; + case 26: + DoScriptText(SAY_MUG_PATROL, me); + break; + case 27: + DoScriptText(SAY_MUG_RETURN, me); + break; + } } } @@ -358,9 +374,9 @@ class npc_muglash : public CreatureScript void Reset() { - m_uiEventTimer = 10000; - m_uiWaveId = 0; - m_bIsBrazierExtinguished = false; + EventTimer = 10000; + WaveId = 0; + IsBrazierExtinguished = false; } void JustDied(Unit* /*killer*/) @@ -372,20 +388,20 @@ class npc_muglash : public CreatureScript void DoWaveSummon() { - switch (m_uiWaveId) + switch (WaveId) { case 1: - me->SummonCreature(NPC_WRATH_RIDER, m_afFirstNagaCoord[0][0], m_afFirstNagaCoord[0][1], m_afFirstNagaCoord[0][2], 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); - me->SummonCreature(NPC_WRATH_SORCERESS, m_afFirstNagaCoord[1][0], m_afFirstNagaCoord[1][1], m_afFirstNagaCoord[1][2], 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); - me->SummonCreature(NPC_WRATH_RAZORTAIL, m_afFirstNagaCoord[2][0], m_afFirstNagaCoord[2][1], m_afFirstNagaCoord[2][2], 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); + me->SummonCreature(NPC_WRATH_RIDER, FirstNagaCoord[0], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); + me->SummonCreature(NPC_WRATH_SORCERESS, FirstNagaCoord[1], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); + me->SummonCreature(NPC_WRATH_RAZORTAIL, FirstNagaCoord[2], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); break; case 2: - me->SummonCreature(NPC_WRATH_PRIESTESS, m_afSecondNagaCoord[0][0], m_afSecondNagaCoord[0][1], m_afSecondNagaCoord[0][2], 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); - me->SummonCreature(NPC_WRATH_MYRMIDON, m_afSecondNagaCoord[1][0], m_afSecondNagaCoord[1][1], m_afSecondNagaCoord[1][2], 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); - me->SummonCreature(NPC_WRATH_SEAWITCH, m_afSecondNagaCoord[2][0], m_afSecondNagaCoord[2][1], m_afSecondNagaCoord[2][2], 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); + me->SummonCreature(NPC_WRATH_PRIESTESS, SecondNagaCoord[0], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); + me->SummonCreature(NPC_WRATH_MYRMIDON, SecondNagaCoord[1], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); + me->SummonCreature(NPC_WRATH_SEAWITCH, SecondNagaCoord[2], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); break; case 3: - me->SummonCreature(NPC_VORSHA, m_fVorshaCoord[0], m_fVorshaCoord[1], m_fVorshaCoord[2], 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); + me->SummonCreature(NPC_VORSHA, VorshaCoord, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); break; case 4: SetEscortPaused(false); @@ -400,16 +416,16 @@ class npc_muglash : public CreatureScript if (!me->getVictim()) { - if (HasEscortState(STATE_ESCORT_PAUSED) && m_bIsBrazierExtinguished) + if (HasEscortState(STATE_ESCORT_PAUSED) && IsBrazierExtinguished) { - if (m_uiEventTimer < uiDiff) + if (EventTimer < uiDiff) { - ++m_uiWaveId; + ++WaveId; DoWaveSummon(); - m_uiEventTimer = 10000; + EventTimer = 10000; } else - m_uiEventTimer -= uiDiff; + EventTimer -= uiDiff; } return; } @@ -441,11 +457,7 @@ class npc_muglash : public CreatureScript class go_naga_brazier : public GameObjectScript { public: - - go_naga_brazier() - : GameObjectScript("go_naga_brazier") - { - } + go_naga_brazier() : GameObjectScript("go_naga_brazier") { } bool OnGossipHello(Player* /*player*/, GameObject* go) { @@ -455,7 +467,7 @@ class go_naga_brazier : public GameObjectScript { DoScriptText(SAY_MUG_BRAZIER_WAIT, creature); - pEscortAI->m_bIsBrazierExtinguished = true; + pEscortAI->IsBrazierExtinguished = true; return false; } } diff --git a/src/server/scripts/Kalimdor/azshara.cpp b/src/server/scripts/Kalimdor/azshara.cpp index 2e7b0a684c1..eae5baa8db2 100644 --- a/src/server/scripts/Kalimdor/azshara.cpp +++ b/src/server/scripts/Kalimdor/azshara.cpp @@ -30,9 +30,9 @@ mob_rizzle_sprysprocket mob_depth_charge EndContentData */ -#include "ScriptPCH.h" -#include "World.h" -#include "WorldPacket.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedGossip.h" /*###### ## mobs_spitelashes @@ -179,9 +179,12 @@ public: # mob_rizzle_sprysprocket ####*/ -enum eRizzleSprysprocketData +enum RizzleSprysprocketData { + QUEST_CHASING_THE_MOONSTONE = 10994, + MOB_DEPTH_CHARGE = 23025, + SPELL_RIZZLE_BLACKJACK = 39865, SPELL_RIZZLE_ESCAPE = 39871, SPELL_RIZZLE_FROST_GRENADE = 40525, @@ -199,67 +202,66 @@ enum eRizzleSprysprocketData #define GOSSIP_GET_MOONSTONE "Hand over the Southfury moonstone and I'll let you go." -float WPs[58][4] = +Position const WPs[58] = { -//pos_x pos_y pos_z orien -{3691.97f, -3962.41f, 35.9118f, 3.67f}, -{3675.02f, -3960.49f, 35.9118f, 3.67f}, -{3653.19f, -3958.33f, 33.9118f, 3.59f}, -{3621.12f, -3958.51f, 29.9118f, 3.48f}, -{3604.86f, -3963, 29.9118f, 3.48f}, -{3569.94f, -3970.25f, 29.9118f, 3.44f}, -{3541.03f, -3975.64f, 29.9118f, 3.41f}, -{3510.84f, -3978.71f, 29.9118f, 3.41f}, -{3472.7f, -3997.07f, 29.9118f, 3.35f}, -{3439.15f, -4014.55f, 29.9118f, 3.29f}, -{3412.8f, -4025.87f, 29.9118f, 3.25f}, -{3384.95f, -4038.04f, 29.9118f, 3.24f}, -{3346.77f, -4052.93f, 29.9118f, 3.22f}, -{3299.56f, -4071.59f, 29.9118f, 3.20f}, -{3261.22f, -4080.38f, 30.9118f, 3.19f}, -{3220.68f, -4083.09f, 31.9118f, 3.18f}, -{3187.11f, -4070.45f, 33.9118f, 3.16f}, -{3162.78f, -4062.75f, 33.9118f, 3.15f}, -{3136.09f, -4050.32f, 33.9118f, 3.07f}, -{3119.47f, -4044.51f, 36.0363f, 3.07f}, -{3098.95f, -4019.8f, 33.9118f, 3.07f}, -{3073.07f, -4011.42f, 33.9118f, 3.07f}, -{3051.71f, -3993.37f, 33.9118f, 3.02f}, -{3027.52f, -3978.6f, 33.9118f, 3.00f}, -{3003.78f, -3960.14f, 33.9118f, 2.98f}, -{2977.99f, -3941.98f, 31.9118f, 2.96f}, -{2964.57f, -3932.07f, 30.9118f, 2.96f}, -{2947.9f, -3921.31f, 29.9118f, 2.96f}, -{2924.91f, -3910.8f, 29.9118f, 2.94f}, -{2903.04f, -3896.42f, 29.9118f, 2.93f}, -{2884.75f, -3874.03f, 29.9118f, 2.90f}, -{2868.19f, -3851.48f, 29.9118f, 2.82f}, -{2854.62f, -3819.72f, 29.9118f, 2.80f}, -{2825.53f, -3790.4f, 29.9118f, 2.744f}, -{2804.31f, -3773.05f, 29.9118f, 2.71f}, -{2769.78f, -3763.57f, 29.9118f, 2.70f}, -{2727.23f, -3745.92f, 30.9118f, 2.69f}, -{2680.12f, -3737.49f, 30.9118f, 2.67f}, -{2647.62f, -3739.94f, 30.9118f, 2.66f}, -{2616.6f, -3745.75f, 30.9118f, 2.64f}, -{2589.38f, -3731.97f, 30.9118f, 2.61f}, -{2562.94f, -3722.35f, 31.9118f, 2.56f}, -{2521.05f, -3716.6f, 31.9118f, 2.55f}, -{2485.26f, -3706.67f, 31.9118f, 2.51f}, -{2458.93f, -3696.67f, 31.9118f, 2.51f}, -{2432, -3692.03f, 31.9118f, 2.46f}, -{2399.59f, -3681.97f, 31.9118f, 2.45f}, -{2357.75f, -3666.6f, 31.9118f, 2.44f}, -{2311.99f, -3656.88f, 31.9118f, 2.94f}, -{2263.41f, -3649.55f, 31.9118f, 3.02f}, -{2209.05f, -3641.76f, 31.9118f, 2.99f}, -{2164.83f, -3637.64f, 31.9118f, 3.15f}, -{2122.42f, -3639, 31.9118f, 3.21f}, -{2075.73f, -3643.59f, 31.9118f, 3.22f}, -{2033.59f, -3649.52f, 31.9118f, 3.42f}, -{1985.22f, -3662.99f, 31.9118f, 3.42f}, -{1927.09f, -3679.56f, 33.9118f, 3.42f}, -{1873.57f, -3695.32f, 33.9118f, 3.44f} + {3691.97f, -3962.41f, 35.9118f, 3.67f}, + {3675.02f, -3960.49f, 35.9118f, 3.67f}, + {3653.19f, -3958.33f, 33.9118f, 3.59f}, + {3621.12f, -3958.51f, 29.9118f, 3.48f}, + {3604.86f, -3963, 29.9118f, 3.48f}, + {3569.94f, -3970.25f, 29.9118f, 3.44f}, + {3541.03f, -3975.64f, 29.9118f, 3.41f}, + {3510.84f, -3978.71f, 29.9118f, 3.41f}, + {3472.7f, -3997.07f, 29.9118f, 3.35f}, + {3439.15f, -4014.55f, 29.9118f, 3.29f}, + {3412.8f, -4025.87f, 29.9118f, 3.25f}, + {3384.95f, -4038.04f, 29.9118f, 3.24f}, + {3346.77f, -4052.93f, 29.9118f, 3.22f}, + {3299.56f, -4071.59f, 29.9118f, 3.20f}, + {3261.22f, -4080.38f, 30.9118f, 3.19f}, + {3220.68f, -4083.09f, 31.9118f, 3.18f}, + {3187.11f, -4070.45f, 33.9118f, 3.16f}, + {3162.78f, -4062.75f, 33.9118f, 3.15f}, + {3136.09f, -4050.32f, 33.9118f, 3.07f}, + {3119.47f, -4044.51f, 36.0363f, 3.07f}, + {3098.95f, -4019.8f, 33.9118f, 3.07f}, + {3073.07f, -4011.42f, 33.9118f, 3.07f}, + {3051.71f, -3993.37f, 33.9118f, 3.02f}, + {3027.52f, -3978.6f, 33.9118f, 3.00f}, + {3003.78f, -3960.14f, 33.9118f, 2.98f}, + {2977.99f, -3941.98f, 31.9118f, 2.96f}, + {2964.57f, -3932.07f, 30.9118f, 2.96f}, + {2947.9f, -3921.31f, 29.9118f, 2.96f}, + {2924.91f, -3910.8f, 29.9118f, 2.94f}, + {2903.04f, -3896.42f, 29.9118f, 2.93f}, + {2884.75f, -3874.03f, 29.9118f, 2.90f}, + {2868.19f, -3851.48f, 29.9118f, 2.82f}, + {2854.62f, -3819.72f, 29.9118f, 2.80f}, + {2825.53f, -3790.4f, 29.9118f, 2.744f}, + {2804.31f, -3773.05f, 29.9118f, 2.71f}, + {2769.78f, -3763.57f, 29.9118f, 2.70f}, + {2727.23f, -3745.92f, 30.9118f, 2.69f}, + {2680.12f, -3737.49f, 30.9118f, 2.67f}, + {2647.62f, -3739.94f, 30.9118f, 2.66f}, + {2616.6f, -3745.75f, 30.9118f, 2.64f}, + {2589.38f, -3731.97f, 30.9118f, 2.61f}, + {2562.94f, -3722.35f, 31.9118f, 2.56f}, + {2521.05f, -3716.6f, 31.9118f, 2.55f}, + {2485.26f, -3706.67f, 31.9118f, 2.51f}, + {2458.93f, -3696.67f, 31.9118f, 2.51f}, + {2432, -3692.03f, 31.9118f, 2.46f}, + {2399.59f, -3681.97f, 31.9118f, 2.45f}, + {2357.75f, -3666.6f, 31.9118f, 2.44f}, + {2311.99f, -3656.88f, 31.9118f, 2.94f}, + {2263.41f, -3649.55f, 31.9118f, 3.02f}, + {2209.05f, -3641.76f, 31.9118f, 2.99f}, + {2164.83f, -3637.64f, 31.9118f, 3.15f}, + {2122.42f, -3639, 31.9118f, 3.21f}, + {2075.73f, -3643.59f, 31.9118f, 3.22f}, + {2033.59f, -3649.52f, 31.9118f, 3.42f}, + {1985.22f, -3662.99f, 31.9118f, 3.42f}, + {1927.09f, -3679.56f, 33.9118f, 3.42f}, + {1873.57f, -3695.32f, 33.9118f, 3.44f} }; class mob_rizzle_sprysprocket : public CreatureScript @@ -270,19 +272,19 @@ public: bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) { player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_ACTION_INFO_DEF + 1 && player->GetQuestStatus(10994) == QUEST_STATUS_INCOMPLETE) + if (action == GOSSIP_ACTION_INFO_DEF + 1 && player->GetQuestStatus(QUEST_CHASING_THE_MOONSTONE) == QUEST_STATUS_INCOMPLETE) { player->CLOSE_GOSSIP_MENU(); creature->CastSpell(player, SPELL_GIVE_SOUTHFURY_MOONSTONE, true); - CAST_AI(mob_rizzle_sprysprocket::mob_rizzle_sprysprocketAI, creature->AI())->Must_Die_Timer = 3000; - CAST_AI(mob_rizzle_sprysprocket::mob_rizzle_sprysprocketAI, creature->AI())->Must_Die = true; + CAST_AI(mob_rizzle_sprysprocket::mob_rizzle_sprysprocketAI, creature->AI())->MustDieTimer = 3000; + CAST_AI(mob_rizzle_sprysprocket::mob_rizzle_sprysprocketAI, creature->AI())->MustDie = true; } return true; } bool OnGossipHello(Player* player, Creature* creature) { - if (player->GetQuestStatus(10994) != QUEST_STATUS_INCOMPLETE) + if (player->GetQuestStatus(QUEST_CHASING_THE_MOONSTONE) != QUEST_STATUS_INCOMPLETE) return true; player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_GET_MOONSTONE, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); player->SEND_GOSSIP_MENU(10811, creature->GetGUID()); @@ -298,32 +300,32 @@ public: { mob_rizzle_sprysprocketAI(Creature* creature) : ScriptedAI(creature) {} - uint32 spellEscape_Timer; - uint32 Teleport_Timer; - uint32 Check_Timer; - uint32 Grenade_Timer; - uint32 Must_Die_Timer; + uint32 SpellEscapeTimer; + uint32 TeleportTimer; + uint32 CheckTimer; + uint32 GrenadeTimer; + uint32 MustDieTimer; uint32 CurrWP; uint64 PlayerGUID; - bool Must_Die; + bool MustDie; bool Escape; bool ContinueWP; bool Reached; void Reset() { - spellEscape_Timer = 1300; - Teleport_Timer = 3500; - Check_Timer = 10000; - Grenade_Timer = 30000; - Must_Die_Timer = 3000; + SpellEscapeTimer = 1300; + TeleportTimer = 3500; + CheckTimer = 10000; + GrenadeTimer = 30000; + MustDieTimer = 3000; CurrWP = 0; PlayerGUID = 0; - Must_Die = false; + MustDie = false; Escape = false; ContinueWP = false; Reached = false; @@ -331,13 +333,13 @@ public: void UpdateAI(const uint32 diff) { - if (Must_Die) + if (MustDie) { - if (Must_Die_Timer <= diff) + if (MustDieTimer <= diff) { me->DespawnOrUnsummon(); return; - } else Must_Die_Timer -= diff; + } else MustDieTimer -= diff; } if (!Escape) @@ -345,17 +347,16 @@ public: if (!PlayerGUID) return; - if (spellEscape_Timer <= diff) + if (SpellEscapeTimer <= diff) { DoCast(me, SPELL_RIZZLE_ESCAPE, false); - spellEscape_Timer = 10000; - } else spellEscape_Timer -= diff; + SpellEscapeTimer = 10000; + } else SpellEscapeTimer -= diff; - if (Teleport_Timer <= diff) + if (TeleportTimer <= diff) { //temp solution - unit can't be teleported by core using spelleffect 5, only players - Map* map = me->GetMap(); - if (map) + if (me->GetMap()) { me->SetPosition(3706.39f, -3969.15f, 35.9118f, 0); me->AI_SendMoveToPacket(3706.39f, -3969.15f, 35.9118f, 0, 0, 0); @@ -367,20 +368,20 @@ public: me->SetUnitMovementFlags(MOVEMENTFLAG_HOVER | MOVEMENTFLAG_SWIMMING); me->SetSpeed(MOVE_RUN, 0.85f, true); me->GetMotionMaster()->MovementExpired(); - me->GetMotionMaster()->MovePoint(CurrWP, WPs[CurrWP][0], WPs[CurrWP][1], WPs[CurrWP][2]); + me->GetMotionMaster()->MovePoint(CurrWP, WPs[CurrWP]); Escape = true; - } else Teleport_Timer -= diff; + } else TeleportTimer -= diff; return; } if (ContinueWP) { - me->GetMotionMaster()->MovePoint(CurrWP, WPs[CurrWP][0], WPs[CurrWP][1], WPs[CurrWP][2]); + me->GetMotionMaster()->MovePoint(CurrWP, WPs[CurrWP]); ContinueWP = false; } - if (Grenade_Timer <= diff) + if (GrenadeTimer <= diff) { Player* player = Unit::GetPlayer(*me, PlayerGUID); if (player) @@ -388,10 +389,10 @@ public: DoScriptText(SAY_RIZZLE_GRENADE, me, player); DoCast(player, SPELL_RIZZLE_FROST_GRENADE, true); } - Grenade_Timer = 30000; - } else Grenade_Timer -= diff; + GrenadeTimer = 30000; + } else GrenadeTimer -= diff; - if (Check_Timer <= diff) + if (CheckTimer <= diff) { Player* player = Unit::GetPlayer(*me, PlayerGUID); if (!player) @@ -410,8 +411,8 @@ public: Reached = true; } - Check_Timer = 1000; - } else Check_Timer -= diff; + CheckTimer = 1000; + } else CheckTimer -= diff; } @@ -427,7 +428,7 @@ public: if (!who || PlayerGUID) return; - if (who->GetTypeId() == TYPEID_PLAYER && CAST_PLR(who)->GetQuestStatus(10994) == QUEST_STATUS_INCOMPLETE) + if (who->GetTypeId() == TYPEID_PLAYER && CAST_PLR(who)->GetQuestStatus(QUEST_CHASING_THE_MOONSTONE) == QUEST_STATUS_INCOMPLETE) { PlayerGUID = who->GetGUID(); DoScriptText(SAY_RIZZLE_START, me); @@ -472,25 +473,25 @@ public: { mob_depth_chargeAI(Creature* creature) : ScriptedAI(creature) {} - bool we_must_die; - uint32 must_die_timer; + bool WeMustDie; + uint32 WeMustDieTimer; void Reset() { me->SetUnitMovementFlags(MOVEMENTFLAG_HOVER | MOVEMENTFLAG_SWIMMING); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - we_must_die = false; - must_die_timer = 1000; + WeMustDie = false; + WeMustDieTimer = 1000; } void UpdateAI(const uint32 diff) { - if (we_must_die) + if (WeMustDie) { - if (must_die_timer <= diff) - { + if (WeMustDieTimer <= diff) me->DespawnOrUnsummon(); - } else must_die_timer -= diff; + else + WeMustDieTimer -= diff; } return; } @@ -503,18 +504,14 @@ public: if (who->GetTypeId() == TYPEID_PLAYER && me->IsWithinDistInMap(who, 5)) { DoCast(who, SPELL_DEPTH_CHARGE_TRAP); - we_must_die = true; + WeMustDie = true; return; } } - void AttackStart(Unit* /*who*/) - { - } + void AttackStart(Unit* /*who*/) {} - void EnterCombat(Unit* /*who*/) - { - } + void EnterCombat(Unit* /*who*/) {} }; }; diff --git a/src/server/scripts/Kalimdor/azuremyst_isle.cpp b/src/server/scripts/Kalimdor/azuremyst_isle.cpp index dfb1f3b0bdf..608117ca9af 100644 --- a/src/server/scripts/Kalimdor/azuremyst_isle.cpp +++ b/src/server/scripts/Kalimdor/azuremyst_isle.cpp @@ -33,15 +33,19 @@ go_ravager_cage npc_death_ravager EndContentData */ -#include "ScriptPCH.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" #include "ScriptedEscortAI.h" -#include <cmath> +#include "ScriptedGossip.h" +#include "Cell.h" +#include "CellImpl.h" +#include "GridNotifiers.h" /*###### ## npc_draenei_survivor ######*/ -enum eEnums +enum draeneiSurvivor { SAY_HEAL1 = -1000176, SAY_HEAL2 = -1000177, @@ -175,7 +179,7 @@ public: ## npc_engineer_spark_overgrind ######*/ -enum eOvergrind +enum Overgrind { SAY_TEXT = -1000184, SAY_EMOTE = -1000185, @@ -235,15 +239,15 @@ public: uint32 NormFaction; uint32 NpcFlags; - uint32 Dynamite_Timer; - uint32 Emote_Timer; + uint32 DynamiteTimer; + uint32 EmoteTimer; bool IsTreeEvent; void Reset() { - Dynamite_Timer = 8000; - Emote_Timer = urand(120000, 150000); + DynamiteTimer = 8000; + EmoteTimer = urand(120000, 150000); me->setFaction(NormFaction); me->SetUInt32Value(UNIT_NPC_FLAGS, NpcFlags); @@ -260,12 +264,12 @@ public: { if (!me->isInCombat() && !IsTreeEvent) { - if (Emote_Timer <= diff) + if (EmoteTimer <= diff) { DoScriptText(SAY_TEXT, me); DoScriptText(SAY_EMOTE, me); - Emote_Timer = urand(120000, 150000); - } else Emote_Timer -= diff; + EmoteTimer = urand(120000, 150000); + } else EmoteTimer -= diff; } else if (IsTreeEvent) return; @@ -273,11 +277,11 @@ public: if (!UpdateVictim()) return; - if (Dynamite_Timer <= diff) + if (DynamiteTimer <= diff) { DoCast(me->getVictim(), SPELL_DYNAMITE); - Dynamite_Timer = 8000; - } else Dynamite_Timer -= diff; + DynamiteTimer = 8000; + } else DynamiteTimer -= diff; DoMeleeAttackIfReady(); } @@ -307,7 +311,7 @@ public: { me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT); me->SetHealth(me->CountPctFromMaxHealth(15)); - switch (rand()%2) + switch (urand(0, 1)) { case 0: me->SetStandState(UNIT_STAND_STATE_SIT); @@ -321,14 +325,9 @@ public: void EnterCombat(Unit* /*who*/) {} - void MoveInLineOfSight(Unit* /*who*/) - { - } - - void UpdateAI(const uint32 /*diff*/) - { - } + void MoveInLineOfSight(Unit* /*who*/) {} + void UpdateAI(const uint32 /*diff*/) {} }; }; @@ -337,7 +336,7 @@ public: ## npc_magwin ######*/ -enum eMagwin +enum Magwin { SAY_START = -1000111, SAY_AGGRO = -1000112, @@ -376,26 +375,25 @@ public: void WaypointReached(uint32 waypointId) { - Player* player = GetPlayerForEscort(); - if (!player) - return; - - switch (waypointId) + if (Player* player = GetPlayerForEscort()) { - case 0: - DoScriptText(SAY_START, me, player); - break; - case 17: - DoScriptText(SAY_PROGRESS, me, player); - break; - case 28: - DoScriptText(SAY_END1, me, player); - break; - case 29: - DoScriptText(EMOTE_HUG, me, player); - DoScriptText(SAY_END2, me, player); - player->GroupEventHappens(QUEST_A_CRY_FOR_SAY_HELP, me); - break; + switch (waypointId) + { + case 0: + DoScriptText(SAY_START, me, player); + break; + case 17: + DoScriptText(SAY_PROGRESS, me, player); + break; + case 28: + DoScriptText(SAY_END1, me, player); + break; + case 29: + DoScriptText(EMOTE_HUG, me, player); + DoScriptText(SAY_END2, me, player); + player->GroupEventHappens(QUEST_A_CRY_FOR_SAY_HELP, me); + break; + } } } @@ -404,7 +402,7 @@ public: DoScriptText(SAY_AGGRO, me, who); } - void Reset() { } + void Reset() {} }; }; @@ -413,7 +411,7 @@ public: ## npc_geezle ######*/ -enum eGeezle +enum Geezle { QUEST_TREES_COMPANY = 9531, @@ -433,7 +431,7 @@ enum eGeezle GO_NAGA_FLAG = 181694 }; -static float SparkPos[3] = {-5029.91f, -11291.79f, 8.096f}; +Position const SparkPos = {-5029.91f, -11291.79f, 8.096f, 0.0f}; class npc_geezle : public CreatureScript { @@ -451,7 +449,7 @@ public: uint64 SparkGUID; - uint32 Step; + uint8 Step; uint32 SayTimer; bool EventStarted; @@ -469,8 +467,7 @@ public: { Step = 0; EventStarted = true; - Creature* Spark = me->SummonCreature(MOB_SPARK, SparkPos[0], SparkPos[1], SparkPos[2], 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 1000); - if (Spark) + if (Creature* Spark = me->SummonCreature(MOB_SPARK, SparkPos, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 1000)) { SparkGUID = Spark->GetGUID(); Spark->setActive(true); @@ -479,47 +476,47 @@ public: SayTimer = 8000; } - uint32 NextStep(uint32 Step) + uint32 NextStep(uint8 Step) { Creature* Spark = Unit::GetCreature(*me, SparkGUID); switch (Step) { - case 0: - if (Spark) - Spark->GetMotionMaster()->MovePoint(0, -5080.70f, -11253.61f, 0.56f); - me->GetMotionMaster()->MovePoint(0, -5092.26f, -11252, 0.71f); - return 9000; // NPCs are walking up to fire - case 1: - DespawnNagaFlag(true); - DoScriptText(EMOTE_SPARK, Spark); - return 1000; - case 2: - DoScriptText(GEEZLE_SAY_1, me, Spark); - if (Spark) - { - Spark->SetInFront(me); - me->SetInFront(Spark); - } - return 5000; - case 3: DoScriptText(SPARK_SAY_2, Spark); return 7000; - case 4: DoScriptText(SPARK_SAY_3, Spark); return 8000; - case 5: DoScriptText(GEEZLE_SAY_4, me, Spark); return 8000; - case 6: DoScriptText(SPARK_SAY_5, Spark); return 9000; - case 7: DoScriptText(SPARK_SAY_6, Spark); return 8000; - case 8: DoScriptText(GEEZLE_SAY_7, me, Spark); return 2000; - case 9: - me->GetMotionMaster()->MoveTargetedHome(); - if (Spark) - Spark->GetMotionMaster()->MovePoint(0, SparkPos[0], SparkPos[1], SparkPos[2]); - CompleteQuest(); - return 9000; - case 10: - if (Spark) - Spark->DisappearAndDie(); - DespawnNagaFlag(false); - me->DisappearAndDie(); - default: return 99999999; + case 0: + if (Spark) + Spark->GetMotionMaster()->MovePoint(0, -5080.70f, -11253.61f, 0.56f); + me->GetMotionMaster()->MovePoint(0, -5092.26f, -11252, 0.71f); + return 9000; // NPCs are walking up to fire + case 1: + DespawnNagaFlag(true); + DoScriptText(EMOTE_SPARK, Spark); + return 1000; + case 2: + DoScriptText(GEEZLE_SAY_1, me, Spark); + if (Spark) + { + Spark->SetInFront(me); + me->SetInFront(Spark); + } + return 5000; + case 3: DoScriptText(SPARK_SAY_2, Spark); return 7000; + case 4: DoScriptText(SPARK_SAY_3, Spark); return 8000; + case 5: DoScriptText(GEEZLE_SAY_4, me, Spark); return 8000; + case 6: DoScriptText(SPARK_SAY_5, Spark); return 9000; + case 7: DoScriptText(SPARK_SAY_6, Spark); return 8000; + case 8: DoScriptText(GEEZLE_SAY_7, me, Spark); return 2000; + case 9: + me->GetMotionMaster()->MoveTargetedHome(); + if (Spark) + Spark->GetMotionMaster()->MovePoint(0, SparkPos); + CompleteQuest(); + return 9000; + case 10: + if (Spark) + Spark->DisappearAndDie(); + DespawnNagaFlag(false); + me->DisappearAndDie(); + default: return 99999999; } } @@ -533,13 +530,8 @@ public: me->VisitNearbyWorldObject(radius, searcher); for (std::list<Player*>::const_iterator itr = players.begin(); itr != players.end(); ++itr) - { - if ((*itr)->GetQuestStatus(QUEST_TREES_COMPANY) == QUEST_STATUS_INCOMPLETE - &&(*itr)->HasAura(SPELL_TREE_DISGUISE)) - { + if ((*itr)->GetQuestStatus(QUEST_TREES_COMPANY) == QUEST_STATUS_INCOMPLETE && (*itr)->HasAura(SPELL_TREE_DISGUISE)) (*itr)->KilledMonsterCredit(MOB_SPARK, 0); - } - } } void DespawnNagaFlag(bool despawn) @@ -552,13 +544,13 @@ public: for (std::list<GameObject*>::const_iterator itr = FlagList.begin(); itr != FlagList.end(); ++itr) { if (despawn) - { (*itr)->SetLootState(GO_JUST_DEACTIVATED); - } else (*itr)->Respawn(); } - } else sLog->outError("SD2 ERROR: FlagList is empty!"); + } + else + sLog->outError("SD2 ERROR: FlagList is empty!"); } void UpdateAI(const uint32 diff) @@ -566,16 +558,16 @@ public: if (SayTimer <= diff) { if (EventStarted) - { SayTimer = NextStep(Step++); - } - } else SayTimer -= diff; + } + else + SayTimer -= diff; } }; }; -enum eRavegerCage +enum RavegerCage { NPC_DEATH_RAVAGER = 17556, diff --git a/src/server/scripts/Kalimdor/bloodmyst_isle.cpp b/src/server/scripts/Kalimdor/bloodmyst_isle.cpp index ffc2fb3fb61..3883b740d02 100644 --- a/src/server/scripts/Kalimdor/bloodmyst_isle.cpp +++ b/src/server/scripts/Kalimdor/bloodmyst_isle.cpp @@ -28,14 +28,16 @@ mob_webbed_creature npc_captured_sunhawk_agent EndContentData */ -#include "ScriptPCH.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedGossip.h" /*###### ## mob_webbed_creature ######*/ //possible creatures to be spawned -const uint32 possibleSpawns[32] = {17322, 17661, 17496, 17522, 17340, 17352, 17333, 17524, 17654, 17348, 17339, 17345, 17359, 17353, 17336, 17550, 17330, 17701, 17321, 17680, 17325, 17320, 17683, 17342, 17715, 17334, 17341, 17338, 17337, 17346, 17344, 17327}; +uint32 const possibleSpawns[32] = {17322, 17661, 17496, 17522, 17340, 17352, 17333, 17524, 17654, 17348, 17339, 17345, 17359, 17353, 17336, 17550, 17330, 17701, 17321, 17680, 17325, 17320, 17683, 17342, 17715, 17334, 17341, 17338, 17337, 17346, 17344, 17327}; class mob_webbed_creature : public CreatureScript { @@ -51,13 +53,9 @@ public: { mob_webbed_creatureAI(Creature* creature) : ScriptedAI(creature) {} - void Reset() - { - } + void Reset() {} - void EnterCombat(Unit* /*who*/) - { - } + void EnterCombat(Unit* /*who*/) {} void JustDied(Unit* killer) { @@ -153,7 +151,7 @@ public: ## Quest 9667: Saving Princess Stillpine ######*/ -enum eStillpine +enum Stillpine { QUEST_SAVING_PRINCESS_STILLPINE = 9667, NPC_PRINCESS_STILLPINE = 17682, @@ -193,7 +191,7 @@ public: if (type == POINT_MOTION_TYPE && id == 1) { DoScriptText(SAY_DIRECTION, me); - me->ForcedDespawn(); + me->DespawnOrUnsummon(); } } }; diff --git a/src/server/scripts/Kalimdor/boss_azuregos.cpp b/src/server/scripts/Kalimdor/boss_azuregos.cpp index 37d3753377b..ec098951c03 100644 --- a/src/server/scripts/Kalimdor/boss_azuregos.cpp +++ b/src/server/scripts/Kalimdor/boss_azuregos.cpp @@ -23,17 +23,24 @@ SDComment: Teleport not included, spell reflect not effecting dots (Core problem SDCategory: Azshara EndScriptData */ -#include "ScriptPCH.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" -#define SAY_TELEPORT -1000100 +enum Say +{ + SAY_TELEPORT = -1000100 +}; -#define SPELL_MARKOFFROST 23182 -#define SPELL_MANASTORM 21097 -#define SPELL_CHILL 21098 -#define SPELL_FROSTBREATH 21099 -#define SPELL_REFLECT 22067 -#define SPELL_CLEAVE 8255 //Perhaps not right ID -#define SPELL_ENRAGE 23537 +enum Spells +{ + SPELL_MARKOFFROST = 23182, + SPELL_MANASTORM = 21097, + SPELL_CHILL = 21098, + SPELL_FROSTBREATH = 21099, + SPELL_REFLECT = 22067, + SPELL_CLEAVE = 8255, //Perhaps not right ID + SPELL_ENRAGE = 23537 +}; class boss_azuregos : public CreatureScript { @@ -49,26 +56,26 @@ public: { boss_azuregosAI(Creature* creature) : ScriptedAI(creature) {} - uint32 MarkOfFrost_Timer; - uint32 ManaStorm_Timer; - uint32 Chill_Timer; - uint32 Breath_Timer; - uint32 Teleport_Timer; - uint32 Reflect_Timer; - uint32 Cleave_Timer; - uint32 Enrage_Timer; + uint32 MarkOfFrostTimer; + uint32 ManaStormTimer; + uint32 ChillTimer; + uint32 BreathTimer; + uint32 TeleportTimer; + uint32 ReflectTimer; + uint32 CleaveTimer; + uint32 EnrageTimer; bool Enraged; void Reset() { - MarkOfFrost_Timer = 35000; - ManaStorm_Timer = urand(5000, 17000); - Chill_Timer = urand(10000, 30000); - Breath_Timer = urand(2000, 8000); - Teleport_Timer = 30000; - Reflect_Timer = urand(15000, 30000); - Cleave_Timer = 7000; - Enrage_Timer = 0; + MarkOfFrostTimer = 35000; + ManaStormTimer = urand(5000, 17000); + ChillTimer = urand(10000, 30000); + BreathTimer = urand(2000, 8000); + TeleportTimer = 30000; + ReflectTimer = urand(15000, 30000); + CleaveTimer = 7000; + EnrageTimer = 0; Enraged = false; } @@ -80,14 +87,14 @@ public: if (!UpdateVictim()) return; - if (Teleport_Timer <= diff) + if (TeleportTimer <= diff) { DoScriptText(SAY_TELEPORT, me); - std::list<HostileReference*>& m_threatlist = me->getThreatManager().getThreatList(); - std::list<HostileReference*>::const_iterator i = m_threatlist.begin(); - for (i = m_threatlist.begin(); i!= m_threatlist.end(); ++i) + std::list<HostileReference*>& threatlist = me->getThreatManager().getThreatList(); + std::list<HostileReference*>::const_iterator i = threatlist.begin(); + for (i = threatlist.begin(); i!= threatlist.end(); ++i) { - Unit* unit = Unit::GetUnit((*me), (*i)->getUnitGuid()); + Unit* unit = Unit::GetUnit(*me, (*i)->getUnitGuid()); if (unit && (unit->GetTypeId() == TYPEID_PLAYER)) { DoTeleportPlayer(unit, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()+3, unit->GetOrientation()); @@ -95,53 +102,53 @@ public: } DoResetThreat(); - Teleport_Timer = 30000; - } else Teleport_Timer -= diff; + TeleportTimer = 30000; + } else TeleportTimer -= diff; - // //MarkOfFrost_Timer - // if (MarkOfFrost_Timer <= diff) + // //MarkOfFrostTimer + // if (MarkOfFrostTimer <= diff) // { // DoCast(me->getVictim(), SPELL_MARKOFFROST); - // MarkOfFrost_Timer = 25000; - // } else MarkOfFrost_Timer -= diff; + // MarkOfFrostTimer = 25000; + // } else MarkOfFrostTimer -= diff; - //Chill_Timer - if (Chill_Timer <= diff) + //ChillTimer + if (ChillTimer <= diff) { DoCast(me->getVictim(), SPELL_CHILL); - Chill_Timer = urand(13000, 25000); - } else Chill_Timer -= diff; + ChillTimer = urand(13000, 25000); + } else ChillTimer -= diff; - //Breath_Timer - if (Breath_Timer <= diff) + //BreathTimer + if (BreathTimer <= diff) { DoCast(me->getVictim(), SPELL_FROSTBREATH); - Breath_Timer = urand(10000, 15000); - } else Breath_Timer -= diff; + BreathTimer = urand(10000, 15000); + } else BreathTimer -= diff; - //ManaStorm_Timer - if (ManaStorm_Timer <= diff) + //ManaStormTimer + if (ManaStormTimer <= diff) { if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) DoCast(target, SPELL_MANASTORM); - ManaStorm_Timer = urand(7500, 12500); - } else ManaStorm_Timer -= diff; + ManaStormTimer = urand(7500, 12500); + } else ManaStormTimer -= diff; - //Reflect_Timer - if (Reflect_Timer <= diff) + //ReflectTimer + if (ReflectTimer <= diff) { DoCast(me, SPELL_REFLECT); - Reflect_Timer = urand(20000, 35000); - } else Reflect_Timer -= diff; + ReflectTimer = urand(20000, 35000); + } else ReflectTimer -= diff; - //Cleave_Timer - if (Cleave_Timer <= diff) + //CleaveTimer + if (CleaveTimer <= diff) { DoCast(me->getVictim(), SPELL_CLEAVE); - Cleave_Timer = 7000; - } else Cleave_Timer -= diff; + CleaveTimer = 7000; + } else CleaveTimer -= diff; - //Enrage_Timer + //EnrageTimer if (HealthBelowPct(26) && !Enraged) { DoCast(me, SPELL_ENRAGE); diff --git a/src/server/scripts/Kalimdor/darkshore.cpp b/src/server/scripts/Kalimdor/darkshore.cpp index 1de04db61c4..0e02a77169e 100644 --- a/src/server/scripts/Kalimdor/darkshore.cpp +++ b/src/server/scripts/Kalimdor/darkshore.cpp @@ -29,7 +29,9 @@ npc_prospector_remtravel npc_threshwackonator EndContentData */ -#include "ScriptPCH.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedGossip.h" #include "ScriptedEscortAI.h" #include "ScriptedFollowerAI.h" @@ -37,7 +39,7 @@ EndContentData */ # npc_kerlonian ####*/ -enum eKerlonian +enum Kerlonian { SAY_KER_START = -1000434, @@ -94,11 +96,11 @@ public: { npc_kerlonianAI(Creature* creature) : FollowerAI(creature) { } - uint32 m_uiFallAsleepTimer; + uint32 FallAsleepTimer; void Reset() { - m_uiFallAsleepTimer = urand(10000, 45000); + FallAsleepTimer = urand(10000, 45000); } void MoveInLineOfSight(Unit* who) @@ -150,7 +152,7 @@ public: SetFollowPaused(false); } - void UpdateFollowerAI(const uint32 uiDiff) + void UpdateFollowerAI(const uint32 Diff) { if (!UpdateVictim()) { @@ -159,13 +161,13 @@ public: if (!HasFollowState(STATE_FOLLOW_PAUSED)) { - if (m_uiFallAsleepTimer <= uiDiff) + if (FallAsleepTimer <= Diff) { SetSleeping(); - m_uiFallAsleepTimer = urand(25000, 90000); + FallAsleepTimer = urand(25000, 90000); } else - m_uiFallAsleepTimer -= uiDiff; + FallAsleepTimer -= Diff; } return; @@ -181,7 +183,7 @@ public: # npc_prospector_remtravel ####*/ -enum eRemtravel +enum Remtravel { SAY_REM_START = -1000327, SAY_REM_AGGRO = -1000328, @@ -233,63 +235,62 @@ public: void WaypointReached(uint32 waypointId) { - Player* player = GetPlayerForEscort(); - if (!player) - return; - - switch (waypointId) + if (Player* player = GetPlayerForEscort()) { - case 0: - DoScriptText(SAY_REM_START, me, player); - break; - case 5: - DoScriptText(SAY_REM_RAMP1_1, me, player); - break; - case 6: - DoSpawnCreature(NPC_GRAVEL_SCOUT, -10.0f, 5.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); - DoSpawnCreature(NPC_GRAVEL_BONE, -10.0f, 7.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); - break; - case 9: - DoScriptText(SAY_REM_RAMP1_2, me, player); - break; - case 14: - //depend quest rewarded? - DoScriptText(SAY_REM_BOOK, me, player); - break; - case 15: - DoScriptText(SAY_REM_TENT1_1, me, player); - break; - case 16: - DoSpawnCreature(NPC_GRAVEL_SCOUT, -10.0f, 5.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); - DoSpawnCreature(NPC_GRAVEL_BONE, -10.0f, 7.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); - break; - case 17: - DoScriptText(SAY_REM_TENT1_2, me, player); - break; - case 26: - DoScriptText(SAY_REM_MOSS, me, player); - break; - case 27: - DoScriptText(EMOTE_REM_MOSS, me, player); - break; - case 28: - DoScriptText(SAY_REM_MOSS_PROGRESS, me, player); - break; - case 29: - DoSpawnCreature(NPC_GRAVEL_SCOUT, -15.0f, 3.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); - DoSpawnCreature(NPC_GRAVEL_BONE, -15.0f, 5.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); - DoSpawnCreature(NPC_GRAVEL_GEO, -15.0f, 7.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); - break; - case 31: - DoScriptText(SAY_REM_PROGRESS, me, player); - break; - case 41: - DoScriptText(SAY_REM_REMEMBER, me, player); - break; - case 42: - DoScriptText(EMOTE_REM_END, me, player); - player->GroupEventHappens(QUEST_ABSENT_MINDED_PT2, me); - break; + switch (waypointId) + { + case 0: + DoScriptText(SAY_REM_START, me, player); + break; + case 5: + DoScriptText(SAY_REM_RAMP1_1, me, player); + break; + case 6: + DoSpawnCreature(NPC_GRAVEL_SCOUT, -10.0f, 5.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); + DoSpawnCreature(NPC_GRAVEL_BONE, -10.0f, 7.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); + break; + case 9: + DoScriptText(SAY_REM_RAMP1_2, me, player); + break; + case 14: + //depend quest rewarded? + DoScriptText(SAY_REM_BOOK, me, player); + break; + case 15: + DoScriptText(SAY_REM_TENT1_1, me, player); + break; + case 16: + DoSpawnCreature(NPC_GRAVEL_SCOUT, -10.0f, 5.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); + DoSpawnCreature(NPC_GRAVEL_BONE, -10.0f, 7.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); + break; + case 17: + DoScriptText(SAY_REM_TENT1_2, me, player); + break; + case 26: + DoScriptText(SAY_REM_MOSS, me, player); + break; + case 27: + DoScriptText(EMOTE_REM_MOSS, me, player); + break; + case 28: + DoScriptText(SAY_REM_MOSS_PROGRESS, me, player); + break; + case 29: + DoSpawnCreature(NPC_GRAVEL_SCOUT, -15.0f, 3.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); + DoSpawnCreature(NPC_GRAVEL_BONE, -15.0f, 5.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); + DoSpawnCreature(NPC_GRAVEL_GEO, -15.0f, 7.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); + break; + case 31: + DoScriptText(SAY_REM_PROGRESS, me, player); + break; + case 41: + DoScriptText(SAY_REM_REMEMBER, me, player); + break; + case 42: + DoScriptText(EMOTE_REM_END, me, player); + player->GroupEventHappens(QUEST_ABSENT_MINDED_PT2, me); + break; + } } } @@ -297,7 +298,7 @@ public: void EnterCombat(Unit* who) { - if (rand()%2) + if (urand(0, 1)) DoScriptText(SAY_REM_AGGRO, me, who); } @@ -314,7 +315,7 @@ public: # npc_threshwackonator ####*/ -enum eThreshwackonator +enum Threshwackonator { EMOTE_START = -1000325, //signed for 4966 SAY_AT_CLOSE = -1000326, //signed for 4966 diff --git a/src/server/scripts/Kalimdor/desolace.cpp b/src/server/scripts/Kalimdor/desolace.cpp index f295d7626ac..e196c71f681 100644 --- a/src/server/scripts/Kalimdor/desolace.cpp +++ b/src/server/scripts/Kalimdor/desolace.cpp @@ -30,10 +30,12 @@ npc_dalinda_malem go_demon_portal EndContentData */ -#include "ScriptPCH.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedGossip.h" #include "ScriptedEscortAI.h" -enum eDyingKodo +enum DyingKodo { // signed for 9999 SAY_SMEED_HOME_1 = -1000348, @@ -114,11 +116,11 @@ public: { npc_aged_dying_ancient_kodoAI(Creature* creature) : ScriptedAI(creature) { Reset(); } - uint32 m_uiDespawnTimer; + uint32 DespawnTimer; void Reset() { - m_uiDespawnTimer = 0; + DespawnTimer = 0; } void MoveInLineOfSight(Unit* who) @@ -143,14 +145,14 @@ public: if (pSpell->Id == SPELL_KODO_KOMBO_GOSSIP) { me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); - m_uiDespawnTimer = 60000; + DespawnTimer = 60000; } } void UpdateAI(const uint32 diff) { //timer should always be == 0 unless we already updated entry of creature. Then not expect this updated to ever be in combat. - if (m_uiDespawnTimer && m_uiDespawnTimer <= diff) + if (DespawnTimer && DespawnTimer <= diff) { if (!me->getVictim() && me->isAlive()) { @@ -159,7 +161,7 @@ public: me->Respawn(); return; } - } else m_uiDespawnTimer -= diff; + } else DespawnTimer -= diff; if (!UpdateVictim()) return; @@ -175,7 +177,7 @@ public: ## Hand of Iruxos ######*/ -enum +enum Iruxos { QUEST_HAND_IRUXOS = 5381, NPC_DEMON_SPIRIT = 11876, @@ -199,7 +201,10 @@ class go_iruxos : public GameObjectScript ## npc_dalinda_malem. Quest 1440 ######*/ -#define QUEST_RETURN_TO_VAHLARRIEL 1440 +enum Dalinda +{ + QUEST_RETURN_TO_VAHLARRIEL = 1440 +}; class npc_dalinda : public CreatureScript { @@ -255,9 +260,9 @@ public: return; } - void UpdateAI(const uint32 uiDiff) + void UpdateAI(const uint32 Diff) { - npc_escortAI::UpdateAI(uiDiff); + npc_escortAI::UpdateAI(Diff); if (!UpdateVictim()) return; DoMeleeAttackIfReady(); diff --git a/src/server/scripts/Kalimdor/durotar.cpp b/src/server/scripts/Kalimdor/durotar.cpp index 88bc3352ea1..ec06a542b6f 100644 --- a/src/server/scripts/Kalimdor/durotar.cpp +++ b/src/server/scripts/Kalimdor/durotar.cpp @@ -15,8 +15,10 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "ScriptPCH.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" #include "Vehicle.h" +#include "SpellScript.h" /*###### ##Quest 5441: Lazy Peons @@ -50,15 +52,15 @@ public: { npc_lazy_peonAI(Creature* creature) : ScriptedAI(creature) {} - uint64 uiPlayerGUID; + uint64 PlayerGUID; - uint32 m_uiRebuffTimer; + uint32 RebuffTimer; bool work; void Reset() { - uiPlayerGUID = 0; - m_uiRebuffTimer = 0; + PlayerGUID = 0; + RebuffTimer = 0; work = false; } @@ -81,17 +83,17 @@ public: } } - void UpdateAI(const uint32 uiDiff) + void UpdateAI(const uint32 Diff) { if (work == true) me->HandleEmoteCommand(EMOTE_ONESHOT_WORK_CHOPWOOD); - if (m_uiRebuffTimer <= uiDiff) + if (RebuffTimer <= Diff) { DoCast(me, SPELL_BUFF_SLEEP); - m_uiRebuffTimer = 300000; //Rebuff agian in 5 minutes + RebuffTimer = 300000; //Rebuff agian in 5 minutes } else - m_uiRebuffTimer -= uiDiff; + RebuffTimer -= Diff; if (!UpdateVictim()) return; DoMeleeAttackIfReady(); @@ -264,7 +266,7 @@ class npc_tiger_matriarch : public CreatureScript vehSummoner->RemoveAurasDueToSpell(SPELL_SPIRIT_OF_THE_TIGER_RIDER); vehSummoner->RemoveAurasDueToSpell(SPELL_SUMMON_ZENTABRA_TRIGGER); } - me->ForcedDespawn(); + me->DespawnOrUnsummon(); } void DamageTaken(Unit* attacker, uint32& damage) @@ -287,7 +289,7 @@ class npc_tiger_matriarch : public CreatureScript vehSummoner->RemoveAurasDueToSpell(SPELL_SUMMON_ZENTABRA_TRIGGER); } - me->ForcedDespawn(); + me->DespawnOrUnsummon(); } } diff --git a/src/server/scripts/Kalimdor/dustwallow_marsh.cpp b/src/server/scripts/Kalimdor/dustwallow_marsh.cpp index 4a1b67ba477..45e1c1808c1 100644 --- a/src/server/scripts/Kalimdor/dustwallow_marsh.cpp +++ b/src/server/scripts/Kalimdor/dustwallow_marsh.cpp @@ -32,8 +32,11 @@ npc_private_hendel npc_cassa_crimsonwing - handled by npc_taxi EndContentData */ -#include "ScriptPCH.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" #include "ScriptedEscortAI.h" +#include "ScriptedGossip.h" +#include "SpellScript.h" /*###### ## mobs_risen_husk_spirit @@ -132,7 +135,7 @@ class mobs_risen_husk_spirit : public CreatureScript ## npc_deserter_agitator ######*/ -enum eDeserter +enum Deserter { QUEST_TRAITORS_AMONG_US = 11126, NPC_THERAMORE_DESERTER = 23602, @@ -203,12 +206,12 @@ public: me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); } - void MovementInform(uint32 uiType, uint32 uiId) + void MovementInform(uint32 Type, uint32 Id) { - if (uiType != POINT_MOTION_TYPE) + if (Type != POINT_MOTION_TYPE) return; - if (uiId == 1) + if (Id == 1) me->DisappearAndDie(); } }; @@ -218,7 +221,7 @@ public: ## npc_deserter_agitator ######*/ -enum eTheramoreGuard +enum TheramoreGuard { SAY_QUEST1 = -1000641, SAY_QUEST2 = -1000642, @@ -266,7 +269,7 @@ public: DoScriptText(SAY_QUEST1, creature); creature->CastSpell(creature, SPELL_DOCTORED_LEAFLET, false); creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); - CAST_AI(npc_theramore_guard::npc_theramore_guardAI, creature->AI())->uiYellTimer = 4000; + CAST_AI(npc_theramore_guard::npc_theramore_guardAI, creature->AI())->YellTimer = 4000; CAST_AI(npc_theramore_guard::npc_theramore_guardAI, creature->AI())->bYellTimer = true; } @@ -282,40 +285,40 @@ public: { npc_theramore_guardAI(Creature* creature) : ScriptedAI(creature) { } - uint32 uiYellTimer; - uint32 uiStep; + uint32 YellTimer; + uint32 Step; bool bYellTimer; void Reset() { bYellTimer = false; - uiStep = 0; + Step = 0; } - void UpdateAI(const uint32 uiDiff) + void UpdateAI(const uint32 Diff) { if (!me->HasAura(SPELL_PROPAGANDIZED)) me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); - if (bYellTimer && uiYellTimer <= uiDiff) + if (bYellTimer && YellTimer <= Diff) { - switch (uiStep) + switch (Step) { case 0: DoScriptText(RAND(SAY_QUEST2, SAY_QUEST3, SAY_QUEST4, SAY_QUEST5, SAY_QUEST6), me); - uiYellTimer = 3000; - ++uiStep; + YellTimer = 3000; + ++Step; break; case 1: DoScriptText(RAND(SAY_QUEST7, SAY_QUEST8, SAY_QUEST9), me); me->HandleEmoteCommand(EMOTE_ONESHOT_LAUGH); - uiStep = 0; + Step = 0; bYellTimer = false; break; } } else - uiYellTimer -= uiDiff; + YellTimer -= Diff; } }; }; @@ -324,7 +327,7 @@ public: ## npc_lady_jaina_proudmoore ######*/ -enum eLadyJaina +enum LadyJaina { QUEST_JAINAS_AUTOGRAPH = 558, SPELL_JAINAS_AUTOGRAPH = 23122 @@ -367,7 +370,7 @@ public: ## npc_nat_pagle ######*/ -enum eNatPagle +enum NatPagle { QUEST_NATS_MEASURING_TAPE = 8227 }; @@ -408,7 +411,7 @@ public: ## npc_private_hendel ######*/ -enum eHendel +enum Hendel { // looks like all this text ids are wrong. SAY_PROGRESS_1_TER = -1000411, // signed for 3568 @@ -464,11 +467,11 @@ public: AttackStart(pAttacker); } - void DamageTaken(Unit* pDoneBy, uint32 &uiDamage) + void DamageTaken(Unit* pDoneBy, uint32 &Damage) { - if (uiDamage > me->GetHealth() || me->HealthBelowPctDamaged(20, uiDamage)) + if (Damage > me->GetHealth() || me->HealthBelowPctDamaged(20, Damage)) { - uiDamage = 0; + Damage = 0; if (Player* player = pDoneBy->GetCharmerOrOwnerPlayerOrPlayerItself()) player->GroupEventHappens(QUEST_MISSING_DIPLO_PT16, me); @@ -485,9 +488,9 @@ public: ## npc_zelfrax ######*/ -const Position MovePosition = {-2967.030f, -3872.1799f, 35.620f, 0.0f}; +Position const MovePosition = {-2967.030f, -3872.1799f, 35.620f, 0.0f}; -enum eZelfrax +enum Zelfrax { SAY_ZELFRAX = -1000472, SAY_ZELFRAX_2 = -1000473 @@ -525,9 +528,9 @@ public: } } - void MovementInform(uint32 uiType, uint32 /*uiId*/) + void MovementInform(uint32 Type, uint32 /*Id*/) { - if (uiType != POINT_MOTION_TYPE) + if (Type != POINT_MOTION_TYPE) return; me->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation()); @@ -547,7 +550,7 @@ public: DoScriptText(SAY_ZELFRAX_2, me); } - void UpdateAI(uint32 const /*uiDiff*/) + void UpdateAI(uint32 const /*Diff*/) { if (!UpdateVictim()) return; @@ -562,7 +565,7 @@ public: ## npc_stinky ######*/ -enum eStinky +enum Stinky { QUEST_STINKYS_ESCAPE_H = 1270, QUEST_STINKYS_ESCAPE_A = 1222, @@ -713,7 +716,7 @@ class spell_ooze_zap : public SpellScriptLoader if (!GetCaster()->HasAura(GetSpellInfo()->Effects[EFFECT_1].CalcValue())) return SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW; // This is actually correct - if (!GetTargetUnit()) + if (!GetExplTargetUnit()) return SPELL_FAILED_BAD_TARGETS; return SPELL_CAST_OK; @@ -847,7 +850,7 @@ public: player->KilledMonsterCredit(NPC_THERAMORE_PRISONER, 0); prisoner->AI()->Talk(SAY_FREE); // We also emote cry here (handled in creature_text.emote) - prisoner->ForcedDespawn(6000); + prisoner->DespawnOrUnsummon(6000); } return true; } diff --git a/src/server/scripts/Kalimdor/felwood.cpp b/src/server/scripts/Kalimdor/felwood.cpp index e1f59ec26be..9243ea0017e 100644 --- a/src/server/scripts/Kalimdor/felwood.cpp +++ b/src/server/scripts/Kalimdor/felwood.cpp @@ -27,7 +27,9 @@ EndScriptData */ npcs_riverbreeze_and_silversky EndContentData */ -#include "ScriptPCH.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedGossip.h" /*###### ## npcs_riverbreeze_and_silversky @@ -35,6 +37,17 @@ EndContentData */ #define GOSSIP_ITEM_BEACON "Please make me a Cenarion Beacon" +enum RiverbreezeAndSilversky +{ + SPELL_CENARION_BEACON = 15120, + + NPC_ARATHANDRIS_SILVERSKY = 9528, + NPC_MAYBESS_RIVERBREEZE = 9529, + + QUEST_CLEASING_FELWOOD_A = 4101, + QUEST_CLEASING_FELWOOD_H = 4102 +}; + class npcs_riverbreeze_and_silversky : public CreatureScript { public: @@ -46,7 +59,7 @@ public: if (action == GOSSIP_ACTION_INFO_DEF+1) { player->CLOSE_GOSSIP_MENU(); - creature->CastSpell(player, 15120, false); + creature->CastSpell(player, SPELL_CENARION_BEACON, false); } return true; } @@ -58,9 +71,9 @@ public: uint32 creatureId = creature->GetEntry(); - if (creatureId == 9528) + if (creatureId == NPC_ARATHANDRIS_SILVERSKY) { - if (player->GetQuestRewardStatus(4101)) + if (player->GetQuestRewardStatus(QUEST_CLEASING_FELWOOD_A)) { player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_BEACON, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); player->SEND_GOSSIP_MENU(2848, creature->GetGUID()); @@ -70,9 +83,9 @@ public: player->SEND_GOSSIP_MENU(2844, creature->GetGUID()); } - if (creatureId == 9529) + if (creatureId == NPC_MAYBESS_RIVERBREEZE) { - if (player->GetQuestRewardStatus(4102)) + if (player->GetQuestRewardStatus(QUEST_CLEASING_FELWOOD_H)) { player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_BEACON, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); player->SEND_GOSSIP_MENU(2849, creature->GetGUID()); diff --git a/src/server/scripts/Kalimdor/feralas.cpp b/src/server/scripts/Kalimdor/feralas.cpp index 480b94d6767..4fcd20951c9 100644 --- a/src/server/scripts/Kalimdor/feralas.cpp +++ b/src/server/scripts/Kalimdor/feralas.cpp @@ -23,8 +23,10 @@ SDComment: Quest support: 3520, 2767, Special vendor Gregan Brewspewer SDCategory: Feralas EndScriptData */ -#include "ScriptPCH.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" #include "ScriptedEscortAI.h" +#include "ScriptedGossip.h" /*###### ## npc_gregan_brewspewer @@ -68,7 +70,7 @@ public: ## npc_oox22fe ######*/ -enum eOOX +enum OOX { //signed for 7806 SAY_OOX_START = -1000287, diff --git a/src/server/scripts/Kalimdor/moonglade.cpp b/src/server/scripts/Kalimdor/moonglade.cpp index 08f5b2aa592..9df208d2578 100644 --- a/src/server/scripts/Kalimdor/moonglade.cpp +++ b/src/server/scripts/Kalimdor/moonglade.cpp @@ -31,14 +31,16 @@ npc_clintar_spirit npc_clintar_dreamwalker EndContentData */ -#include "ScriptPCH.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" #include "ScriptedEscortAI.h" +#include "ScriptedGossip.h" /*###### ## npc_bunthen_plainswind ######*/ -enum eBunthen +enum Bunthen { QUEST_SEA_LION_HORDE = 30, QUEST_SEA_LION_ALLY = 272, @@ -218,70 +220,68 @@ public: ## npc_clintar_spirit ######*/ -float Clintar_spirit_WP[41][5] = +float const Clintar_spirit_WP[41][5] = { - //pos_x pos_y pos_z orien waitTime -{7465.28f, -3115.46f, 439.327f, 0.83f, 4000}, -{7476.49f, -3101, 443.457f, 0.89f, 0}, -{7486.57f, -3085.59f, 439.478f, 1.07f, 0}, -{7472.19f, -3085.06f, 443.142f, 3.07f, 0}, -{7456.92f, -3085.91f, 438.862f, 3.24f, 0}, -{7446.68f, -3083.43f, 438.245f, 2.40f, 0}, -{7446.17f, -3080.21f, 439.826f, 1.10f, 6000}, -{7452.41f, -3085.8f, 438.984f, 5.78f, 0}, -{7469.11f, -3084.94f, 443.048f, 6.25f, 0}, -{7483.79f, -3085.44f, 439.607f, 6.25f, 0}, -{7491.14f, -3090.96f, 439.983f, 5.44f, 0}, -{7497.62f, -3098.22f, 436.854f, 5.44f, 0}, -{7498.72f, -3113.41f, 434.596f, 4.84f, 0}, -{7500.06f, -3122.51f, 434.749f, 5.17f, 0}, -{7504.96f, -3131.53f, 434.475f, 4.74f, 0}, -{7504.31f, -3133.53f, 435.693f, 3.84f, 6000}, -{7504.55f, -3133.27f, 435.476f, 0.68f, 15000}, -{7501.99f, -3126.01f, 434.93f, 1.83f, 0}, -{7490.76f, -3114.97f, 434.431f, 2.51f, 0}, -{7479.64f, -3105.51f, 431.123f, 1.83f, 0}, -{7474.63f, -3086.59f, 428.994f, 1.83f, 2000}, -{7472.96f, -3074.18f, 427.566f, 1.57f, 0}, -{7472.25f, -3063, 428.268f, 1.55f, 0}, -{7473.46f, -3054.22f, 427.588f, 0.36f, 0}, -{7475.08f, -3053.6f, 428.653f, 0.36f, 6000}, -{7474.66f, -3053.56f, 428.433f, 3.19f, 4000}, -{7471.81f, -3058.84f, 427.073f, 4.29f, 0}, -{7472.16f, -3064.91f, 427.772f, 4.95f, 0}, -{7471.56f, -3085.36f, 428.924f, 4.72f, 0}, -{7473.56f, -3093.48f, 429.294f, 5.04f, 0}, -{7478.94f, -3104.29f, 430.638f, 5.23f, 0}, -{7484.46f, -3109.61f, 432.769f, 5.79f, 0}, -{7490.23f, -3111.08f, 434.431f, 0.02f, 0}, -{7496.29f, -3108, 434.783f, 1.15f, 0}, -{7497.46f, -3100.66f, 436.191f, 1.50f, 0}, -{7495.64f, -3093.39f, 438.349f, 2.10f, 0}, -{7492.44f, -3086.01f, 440.267f, 1.38f, 0}, -{7498.26f, -3076.44f, 440.808f, 0.71f, 0}, -{7506.4f, -3067.35f, 443.64f, 0.77f, 0}, -{7518.37f, -3057.42f, 445.584f, 0.74f, 0}, -{7517.51f, -3056.3f, 444.568f, 2.49f, 4500} + //pos_x pos_y pos_z orien waitTime + {7465.28f, -3115.46f, 439.327f, 0.83f, 4000}, + {7476.49f, -3101, 443.457f, 0.89f, 0}, + {7486.57f, -3085.59f, 439.478f, 1.07f, 0}, + {7472.19f, -3085.06f, 443.142f, 3.07f, 0}, + {7456.92f, -3085.91f, 438.862f, 3.24f, 0}, + {7446.68f, -3083.43f, 438.245f, 2.40f, 0}, + {7446.17f, -3080.21f, 439.826f, 1.10f, 6000}, + {7452.41f, -3085.8f, 438.984f, 5.78f, 0}, + {7469.11f, -3084.94f, 443.048f, 6.25f, 0}, + {7483.79f, -3085.44f, 439.607f, 6.25f, 0}, + {7491.14f, -3090.96f, 439.983f, 5.44f, 0}, + {7497.62f, -3098.22f, 436.854f, 5.44f, 0}, + {7498.72f, -3113.41f, 434.596f, 4.84f, 0}, + {7500.06f, -3122.51f, 434.749f, 5.17f, 0}, + {7504.96f, -3131.53f, 434.475f, 4.74f, 0}, + {7504.31f, -3133.53f, 435.693f, 3.84f, 6000}, + {7504.55f, -3133.27f, 435.476f, 0.68f, 15000}, + {7501.99f, -3126.01f, 434.93f, 1.83f, 0}, + {7490.76f, -3114.97f, 434.431f, 2.51f, 0}, + {7479.64f, -3105.51f, 431.123f, 1.83f, 0}, + {7474.63f, -3086.59f, 428.994f, 1.83f, 2000}, + {7472.96f, -3074.18f, 427.566f, 1.57f, 0}, + {7472.25f, -3063, 428.268f, 1.55f, 0}, + {7473.46f, -3054.22f, 427.588f, 0.36f, 0}, + {7475.08f, -3053.6f, 428.653f, 0.36f, 6000}, + {7474.66f, -3053.56f, 428.433f, 3.19f, 4000}, + {7471.81f, -3058.84f, 427.073f, 4.29f, 0}, + {7472.16f, -3064.91f, 427.772f, 4.95f, 0}, + {7471.56f, -3085.36f, 428.924f, 4.72f, 0}, + {7473.56f, -3093.48f, 429.294f, 5.04f, 0}, + {7478.94f, -3104.29f, 430.638f, 5.23f, 0}, + {7484.46f, -3109.61f, 432.769f, 5.79f, 0}, + {7490.23f, -3111.08f, 434.431f, 0.02f, 0}, + {7496.29f, -3108, 434.783f, 1.15f, 0}, + {7497.46f, -3100.66f, 436.191f, 1.50f, 0}, + {7495.64f, -3093.39f, 438.349f, 2.10f, 0}, + {7492.44f, -3086.01f, 440.267f, 1.38f, 0}, + {7498.26f, -3076.44f, 440.808f, 0.71f, 0}, + {7506.4f, -3067.35f, 443.64f, 0.77f, 0}, + {7518.37f, -3057.42f, 445.584f, 0.74f, 0}, + {7517.51f, -3056.3f, 444.568f, 2.49f, 4500} }; -#define ASPECT_RAVEN 22915 - -#define ASPECT_RAVEN_SUMMON_X 7472.96f -#define ASPECT_RAVEN_SUMMON_Y -3074.18f -#define ASPECT_RAVEN_SUMMON_Z 427.566f -#define CLINTAR_SPIRIT_SUMMON_X 7459.2275f -#define CLINTAR_SPIRIT_SUMMON_Y -3122.5632f -#define CLINTAR_SPIRIT_SUMMON_Z 438.9842f -#define CLINTAR_SPIRIT_SUMMON_O 0.8594f - -//from -1000292 to -1000287 are signed for 7806. but all this texts ids wrong. -#define CLINTAR_SPIRIT_SAY_START -1000286 -#define CLINTAR_SPIRIT_SAY_UNDER_ATTACK_1 -1000287 -#define CLINTAR_SPIRIT_SAY_UNDER_ATTACK_2 -1000288 -#define CLINTAR_SPIRIT_SAY_GET_ONE -1000289 -#define CLINTAR_SPIRIT_SAY_GET_TWO -1000290 -#define CLINTAR_SPIRIT_SAY_GET_THREE -1000291 -#define CLINTAR_SPIRIT_SAY_GET_FINAL -1000292 +Position const AspectRavenSummon = {7472.96f, -3074.18f, 427.566f, 0.0f}; +Position const ClintarSpiritSummon = {7459.2275f, -3122.5632f, 438.9842f, 0.8594f}; + +enum ClintarSpirit +{ + ASPECT_RAVEN = 22915, + + //from -1000292 to -1000287 are signed for 7806. but all this texts ids wrong. + CLINTAR_SPIRIT_SAY_START = -1000286, + CLINTAR_SPIRIT_SAY_UNDER_ATTACK_1 = -1000287, + CLINTAR_SPIRIT_SAY_UNDER_ATTACK_2 = -1000288, + CLINTAR_SPIRIT_SAY_GET_ONE = -1000289, + CLINTAR_SPIRIT_SAY_GET_TWO = -1000290, + CLINTAR_SPIRIT_SAY_GET_THREE = -1000291, + CLINTAR_SPIRIT_SAY_GET_FINAL = -1000292 +}; class npc_clintar_spirit : public CreatureScript { @@ -298,14 +298,14 @@ public: public: npc_clintar_spiritAI(Creature* creature) : npc_escortAI(creature) {} - uint32 Step; + uint8 Step; uint32 CurrWP; - uint32 Event_Timer; - uint32 checkPlayer_Timer; + uint32 EventTimer; + uint32 checkPlayerTimer; uint64 PlayerGUID; - bool Event_onWait; + bool EventOnWait; void Reset() { @@ -313,10 +313,10 @@ public: { Step = 0; CurrWP = 0; - Event_Timer = 0; + EventTimer = 0; PlayerGUID = 0; - checkPlayer_Timer = 1000; - Event_onWait = false; + checkPlayerTimer = 1000; + EventOnWait = false; } } @@ -347,8 +347,7 @@ public: void EnterCombat(Unit* who) { - uint32 rnd = rand()%2; - switch (rnd) + switch (urand(0, 1)) { case 0: DoScriptText(CLINTAR_SPIRIT_SAY_UNDER_ATTACK_1, me, who); break; case 1: DoScriptText(CLINTAR_SPIRIT_SAY_UNDER_ATTACK_2, me, who); break; @@ -357,9 +356,7 @@ public: void StartEvent(Player* player) { - if (!player) - return; - if (player->GetQuestStatus(10965) == QUEST_STATUS_INCOMPLETE) + if (player && player->GetQuestStatus(10965) == QUEST_STATUS_INCOMPLETE) { for (uint8 i = 0; i < 41; ++i) { @@ -381,18 +378,18 @@ public: return; } - if (!me->isInCombat() && !Event_onWait) + if (!me->isInCombat() && !EventOnWait) { - if (checkPlayer_Timer <= diff) + if (checkPlayerTimer <= diff) { Player* player = Unit::GetPlayer(*me, PlayerGUID); if (player && player->isInCombat() && player->getAttackerForHelper()) AttackStart(player->getAttackerForHelper()); - checkPlayer_Timer = 1000; - } else checkPlayer_Timer -= diff; + checkPlayerTimer = 1000; + } else checkPlayerTimer -= diff; } - if (Event_onWait && Event_Timer <= diff) + if (EventOnWait && EventTimer <= diff) { Player* player = Unit::GetPlayer(*me, PlayerGUID); @@ -409,11 +406,11 @@ public: { case 0: me->Say(CLINTAR_SPIRIT_SAY_START, 0, PlayerGUID); - Event_Timer = 8000; + EventTimer = 8000; Step = 1; break; case 1: - Event_onWait = false; + EventOnWait = false; break; } break; @@ -422,13 +419,13 @@ public: { case 0: me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 133); - Event_Timer = 5000; + EventTimer = 5000; Step = 1; break; case 1: me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 0); DoScriptText(CLINTAR_SPIRIT_SAY_GET_ONE, me, player); - Event_onWait = false; + EventOnWait = false; break; } break; @@ -437,12 +434,12 @@ public: { case 0: me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 133); - Event_Timer = 5000; + EventTimer = 5000; Step = 1; break; case 1: me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 0); - Event_onWait = false; + EventOnWait = false; break; } break; @@ -451,11 +448,11 @@ public: { case 0: DoScriptText(CLINTAR_SPIRIT_SAY_GET_TWO, me, player); - Event_Timer = 15000; + EventTimer = 15000; Step = 1; break; case 1: - Event_onWait = false; + EventOnWait = false; break; } break; @@ -463,19 +460,16 @@ public: switch (Step) { case 0: - { - Creature* mob = me->SummonCreature(ASPECT_RAVEN, ASPECT_RAVEN_SUMMON_X, ASPECT_RAVEN_SUMMON_Y, ASPECT_RAVEN_SUMMON_Z, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 2000); - if (mob) + if (Creature* mob = me->SummonCreature(ASPECT_RAVEN, AspectRavenSummon, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 2000)) { mob->AddThreat(me, 10000.0f); mob->AI()->AttackStart(me); } - Event_Timer = 2000; + EventTimer = 2000; Step = 1; break; - } case 1: - Event_onWait = false; + EventOnWait = false; break; } break; @@ -484,12 +478,12 @@ public: { case 0: me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 133); - Event_Timer = 5000; + EventTimer = 5000; Step = 1; break; case 1: me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 0); - Event_onWait = false; + EventOnWait = false; break; } break; @@ -498,11 +492,11 @@ public: { case 0: DoScriptText(CLINTAR_SPIRIT_SAY_GET_THREE, me, player); - Event_Timer = 4000; + EventTimer = 4000; Step = 1; break; case 1: - Event_onWait = false; + EventOnWait = false; break; } break; @@ -513,12 +507,12 @@ public: me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 2); DoScriptText(CLINTAR_SPIRIT_SAY_GET_FINAL, me, player); player->CompleteQuest(10965); - Event_Timer = 1500; + EventTimer = 1500; Step = 1; break; case 1: me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 0); - Event_Timer = 3000; + EventTimer = 3000; Step = 2; break; case 2: @@ -530,19 +524,19 @@ public: } break; default: - Event_onWait = false; + EventOnWait = false; break; } - } else if (Event_onWait) Event_Timer -= diff; + } else if (EventOnWait) EventTimer -= diff; } void WaypointReached(uint32 waypointId) { CurrWP = waypointId; - Event_Timer = 0; + EventTimer = 0; Step = 0; - Event_onWait = true; + EventOnWait = true; } }; @@ -552,7 +546,10 @@ public: # npc_clintar_dreamwalker ####*/ -#define CLINTAR_SPIRIT 22916 +enum Clintar +{ + CLINTAR_SPIRIT = 22916 +}; class npc_clintar_dreamwalker : public CreatureScript { @@ -562,11 +559,8 @@ public: bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) { if (quest->GetQuestId() == 10965) - { - Creature* clintar_spirit = creature->SummonCreature(CLINTAR_SPIRIT, CLINTAR_SPIRIT_SUMMON_X, CLINTAR_SPIRIT_SUMMON_Y, CLINTAR_SPIRIT_SUMMON_Z, CLINTAR_SPIRIT_SUMMON_O, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 100000); - if (clintar_spirit) + if (Creature* clintar_spirit = creature->SummonCreature(CLINTAR_SPIRIT, ClintarSpiritSummon, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 100000)) CAST_AI(npc_clintar_spirit::npc_clintar_spiritAI, clintar_spirit->AI())->StartEvent(player); - } return true; } diff --git a/src/server/scripts/Kalimdor/mulgore.cpp b/src/server/scripts/Kalimdor/mulgore.cpp index bd4cf55b7b2..5b35688c2b8 100644 --- a/src/server/scripts/Kalimdor/mulgore.cpp +++ b/src/server/scripts/Kalimdor/mulgore.cpp @@ -29,8 +29,9 @@ npc_kyle_frenzied npc_plains_vision EndContentData */ -#include "ScriptPCH.h" -#include "ScriptedEscortAI.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedGossip.h" /*###### # npc_skorn_whitecloud @@ -71,7 +72,7 @@ public: # npc_kyle_frenzied ######*/ -enum eKyleFrenzied +enum KyleFrenzied { //emote signed for 7780 but propably thats wrong id. EMOTE_SEE_LUNCH = -1000340, @@ -98,30 +99,30 @@ public: { npc_kyle_frenziedAI(Creature* creature) : ScriptedAI(creature) {} - bool bEvent; - bool m_bIsMovingToLunch; - uint64 uiPlayerGUID; - uint32 uiEventTimer; - uint8 uiEventPhase; + bool EventActive; + bool IsMovingToLunch; + uint64 PlayerGUID; + uint32 EventTimer; + uint8 EventPhase; void Reset() { - bEvent = false; - m_bIsMovingToLunch = false; - uiPlayerGUID = 0; - uiEventTimer = 5000; - uiEventPhase = 0; + EventActive = false; + IsMovingToLunch = false; + PlayerGUID = 0; + EventTimer = 5000; + EventPhase = 0; if (me->GetEntry() == NPC_KYLE_FRIENDLY) me->UpdateEntry(NPC_KYLE_FRENZIED); } - void SpellHit(Unit* pCaster, SpellInfo const* pSpell) + void SpellHit(Unit* Caster, SpellInfo const* Spell) { - if (!me->getVictim() && !bEvent && pSpell->Id == SPELL_LUNCH) + if (!me->getVictim() && !EventActive && Spell->Id == SPELL_LUNCH) { - if (pCaster->GetTypeId() == TYPEID_PLAYER) - uiPlayerGUID = pCaster->GetGUID(); + if (Caster->GetTypeId() == TYPEID_PLAYER) + PlayerGUID = Caster->GetGUID(); if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == WAYPOINT_MOTION_TYPE) { @@ -130,41 +131,41 @@ public: me->StopMoving(); } - bEvent = true; + EventActive = true; DoScriptText(EMOTE_SEE_LUNCH, me); me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_CREATURE_SPECIAL); } } - void MovementInform(uint32 uiType, uint32 uiPointId) + void MovementInform(uint32 Type, uint32 PointId) { - if (uiType != POINT_MOTION_TYPE || !bEvent) + if (Type != POINT_MOTION_TYPE || !EventActive) return; - if (uiPointId == POINT_ID) - m_bIsMovingToLunch = false; + if (PointId == POINT_ID) + IsMovingToLunch = false; } void UpdateAI(const uint32 diff) { - if (bEvent) + if (EventActive) { - if (m_bIsMovingToLunch) + if (IsMovingToLunch) return; - if (uiEventTimer <= diff) + if (EventTimer <= diff) { - uiEventTimer = 5000; - ++uiEventPhase; + EventTimer = 5000; + ++EventPhase; - switch (uiEventPhase) + switch (EventPhase) { case 1: - if (Unit* unit = Unit::GetUnit(*me, uiPlayerGUID)) + if (Unit* unit = Unit::GetUnit(*me, PlayerGUID)) { if (GameObject* go = unit->GetGameObject(SPELL_LUNCH)) { - m_bIsMovingToLunch = true; + IsMovingToLunch = true; me->GetMotionMaster()->MovePoint(POINT_ID, go->GetPositionX(), go->GetPositionY(), go->GetPositionZ()); } } @@ -174,13 +175,13 @@ public: me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_USE_STANDING); break; case 3: - if (Player* unit = Unit::GetPlayer(*me, uiPlayerGUID)) + if (Player* unit = Unit::GetPlayer(*me, PlayerGUID)) unit->TalkedToCreature(me->GetEntry(), me->GetGUID()); me->UpdateEntry(NPC_KYLE_FRIENDLY); break; case 4: - uiEventTimer = 30000; + EventTimer = 30000; DoScriptText(EMOTE_DANCE, me); me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_DANCESPECIAL); break; @@ -192,7 +193,7 @@ public: } } else - uiEventTimer -= diff; + EventTimer -= diff; } } }; @@ -203,58 +204,58 @@ public: # npc_plains_vision ######*/ -float wp_plain_vision[50][3] = +Position const wpPlainVision[50] = { - {-2226.32f, -408.095f, -9.36235f}, - {-2203.04f, -437.212f, -5.72498f}, - {-2163.91f, -457.851f, -7.09049f}, - {-2123.87f, -448.137f, -9.29591f}, - {-2104.66f, -427.166f, -6.49513f}, - {-2101.48f, -422.826f, -5.3567f}, - {-2097.56f, -417.083f, -7.16716f}, - {-2084.87f, -398.626f, -9.88973f}, - {-2072.71f, -382.324f, -10.2488f}, - {-2054.05f, -356.728f, -6.22468f}, - {-2051.8f, -353.645f, -5.35791f}, - {-2049.08f, -349.912f, -6.15723f}, - {-2030.6f, -310.724f, -9.59302f}, - {-2002.15f, -249.308f, -10.8124f}, - {-1972.85f, -195.811f, -10.6316f}, - {-1940.93f, -147.652f, -11.7055f}, - {-1888.06f, -81.943f, -11.4404f}, - {-1837.05f, -34.0109f, -12.258f}, - {-1796.12f, -14.6462f, -10.3581f}, - {-1732.61f, -4.27746f, -10.0213f}, - {-1688.94f, -0.829945f, -11.7103f}, - {-1681.32f, 13.0313f, -9.48056f}, - {-1677.04f, 36.8349f, -7.10318f}, - {-1675.2f, 68.559f, -8.95384f}, - {-1676.57f, 89.023f, -9.65104f}, - {-1678.16f, 110.939f, -10.1782f}, - {-1677.86f, 128.681f, -5.73869f}, - {-1675.27f, 144.324f, -3.47916f}, - {-1671.7f, 163.169f, -1.23098f}, - {-1666.61f, 181.584f, 5.26145f}, - {-1661.51f, 196.154f, 8.95252f}, - {-1655.47f, 210.811f, 8.38727f}, - {-1647.07f, 226.947f, 5.27755f}, - {-1621.65f, 232.91f, 2.69579f}, - {-1600.23f, 237.641f, 2.98539f}, - {-1576.07f, 242.546f, 4.66541f}, - {-1554.57f, 248.494f, 6.60377f}, - {-1547.53f, 259.302f, 10.6741f}, - {-1541.7f, 269.847f, 16.4418f}, - {-1539.83f, 278.989f, 21.0597f}, - {-1540.16f, 290.219f, 27.8247f}, - {-1538.99f, 298.983f, 34.0032f}, - {-1540.38f, 307.337f, 41.3557f}, - {-1536.61f, 314.884f, 48.0179f}, - {-1532.42f, 323.277f, 55.6667f}, - {-1528.77f, 329.774f, 61.1525f}, - {-1525.65f, 333.18f, 63.2161f}, - {-1517.01f, 350.713f, 62.4286f}, - {-1511.39f, 362.537f, 62.4539f}, - {-1508.68f, 366.822f, 62.733f} + {-2226.32f, -408.095f, -9.36235f, 0.0f}, + {-2203.04f, -437.212f, -5.72498f, 0.0f}, + {-2163.91f, -457.851f, -7.09049f, 0.0f}, + {-2123.87f, -448.137f, -9.29591f, 0.0f}, + {-2104.66f, -427.166f, -6.49513f, 0.0f}, + {-2101.48f, -422.826f, -5.3567f, 0.0f}, + {-2097.56f, -417.083f, -7.16716f, 0.0f}, + {-2084.87f, -398.626f, -9.88973f, 0.0f}, + {-2072.71f, -382.324f, -10.2488f, 0.0f}, + {-2054.05f, -356.728f, -6.22468f, 0.0f}, + {-2051.8f, -353.645f, -5.35791f, 0.0f}, + {-2049.08f, -349.912f, -6.15723f, 0.0f}, + {-2030.6f, -310.724f, -9.59302f, 0.0f}, + {-2002.15f, -249.308f, -10.8124f, 0.0f}, + {-1972.85f, -195.811f, -10.6316f, 0.0f}, + {-1940.93f, -147.652f, -11.7055f, 0.0f}, + {-1888.06f, -81.943f, -11.4404f, 0.0f}, + {-1837.05f, -34.0109f, -12.258f, 0.0f}, + {-1796.12f, -14.6462f, -10.3581f, 0.0f}, + {-1732.61f, -4.27746f, -10.0213f, 0.0f}, + {-1688.94f, -0.829945f, -11.7103f, 0.0f}, + {-1681.32f, 13.0313f, -9.48056f, 0.0f}, + {-1677.04f, 36.8349f, -7.10318f, 0.0f}, + {-1675.2f, 68.559f, -8.95384f, 0.0f}, + {-1676.57f, 89.023f, -9.65104f, 0.0f}, + {-1678.16f, 110.939f, -10.1782f, 0.0f}, + {-1677.86f, 128.681f, -5.73869f, 0.0f}, + {-1675.27f, 144.324f, -3.47916f, 0.0f}, + {-1671.7f, 163.169f, -1.23098f, 0.0f}, + {-1666.61f, 181.584f, 5.26145f, 0.0f}, + {-1661.51f, 196.154f, 8.95252f, 0.0f}, + {-1655.47f, 210.811f, 8.38727f, 0.0f}, + {-1647.07f, 226.947f, 5.27755f, 0.0f}, + {-1621.65f, 232.91f, 2.69579f, 0.0f}, + {-1600.23f, 237.641f, 2.98539f, 0.0f}, + {-1576.07f, 242.546f, 4.66541f, 0.0f}, + {-1554.57f, 248.494f, 6.60377f, 0.0f}, + {-1547.53f, 259.302f, 10.6741f, 0.0f}, + {-1541.7f, 269.847f, 16.4418f, 0.0f}, + {-1539.83f, 278.989f, 21.0597f, 0.0f}, + {-1540.16f, 290.219f, 27.8247f, 0.0f}, + {-1538.99f, 298.983f, 34.0032f, 0.0f}, + {-1540.38f, 307.337f, 41.3557f, 0.0f}, + {-1536.61f, 314.884f, 48.0179f, 0.0f}, + {-1532.42f, 323.277f, 55.6667f, 0.0f}, + {-1528.77f, 329.774f, 61.1525f, 0.0f}, + {-1525.65f, 333.18f, 63.2161f, 0.0f}, + {-1517.01f, 350.713f, 62.4286f, 0.0f}, + {-1511.39f, 362.537f, 62.4539f, 0.0f}, + {-1508.68f, 366.822f, 62.733f, 0.0f} }; class npc_plains_vision : public CreatureScript @@ -305,7 +306,7 @@ public: { if (newWaypoint) { - me->GetMotionMaster()->MovePoint(WayPointId, wp_plain_vision[WayPointId][0], wp_plain_vision[WayPointId][1], wp_plain_vision[WayPointId][2]); + me->GetMotionMaster()->MovePoint(WayPointId, wpPlainVision[WayPointId]); newWaypoint = false; } } diff --git a/src/server/scripts/Kalimdor/orgrimmar.cpp b/src/server/scripts/Kalimdor/orgrimmar.cpp index 2ff2d28768a..fca8d0f5fc5 100644 --- a/src/server/scripts/Kalimdor/orgrimmar.cpp +++ b/src/server/scripts/Kalimdor/orgrimmar.cpp @@ -28,13 +28,15 @@ npc_shenthul npc_thrall_warchief EndContentData */ -#include "ScriptPCH.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedGossip.h" /*###### ## npc_shenthul ######*/ -enum eShenthul +enum Shenthul { QUEST_SHATTERED_SALUTE = 2460 }; @@ -65,16 +67,16 @@ public: bool CanTalk; bool CanEmote; - uint32 Salute_Timer; - uint32 Reset_Timer; + uint32 SaluteTimer; + uint32 ResetTimer; uint64 PlayerGUID; void Reset() { CanTalk = false; CanEmote = false; - Salute_Timer = 6000; - Reset_Timer = 0; + SaluteTimer = 6000; + ResetTimer = 0; PlayerGUID = 0; } @@ -84,7 +86,7 @@ public: { if (CanEmote) { - if (Reset_Timer <= diff) + if (ResetTimer <= diff) { if (Player* player = Unit::GetPlayer(*me, PlayerGUID)) { @@ -92,17 +94,17 @@ public: player->FailQuest(QUEST_SHATTERED_SALUTE); } Reset(); - } else Reset_Timer -= diff; + } else ResetTimer -= diff; } if (CanTalk && !CanEmote) { - if (Salute_Timer <= diff) + if (SaluteTimer <= diff) { me->HandleEmoteCommand(EMOTE_ONESHOT_SALUTE); CanEmote = true; - Reset_Timer = 60000; - } else Salute_Timer -= diff; + ResetTimer = 60000; + } else SaluteTimer -= diff; } if (!UpdateVictim()) @@ -130,10 +132,13 @@ public: ## npc_thrall_warchief ######*/ -#define QUEST_6566 6566 +enum ThrallWarchief +{ + QUEST_6566 = 6566, -#define SPELL_CHAIN_LIGHTNING 16033 -#define SPELL_SHOCK 16034 + SPELL_CHAIN_LIGHTNING = 16033, + SPELL_SHOCK = 16034 +}; #define GOSSIP_HTW "Please share your wisdom with me, Warchief." #define GOSSIP_STW1 "What discoveries?" @@ -207,13 +212,13 @@ public: { npc_thrall_warchiefAI(Creature* creature) : ScriptedAI(creature) {} - uint32 ChainLightning_Timer; - uint32 Shock_Timer; + uint32 ChainLightningTimer; + uint32 ShockTimer; void Reset() { - ChainLightning_Timer = 2000; - Shock_Timer = 8000; + ChainLightningTimer = 2000; + ShockTimer = 8000; } void EnterCombat(Unit* /*who*/) {} @@ -223,17 +228,17 @@ public: if (!UpdateVictim()) return; - if (ChainLightning_Timer <= diff) + if (ChainLightningTimer <= diff) { DoCast(me->getVictim(), SPELL_CHAIN_LIGHTNING); - ChainLightning_Timer = 9000; - } else ChainLightning_Timer -= diff; + ChainLightningTimer = 9000; + } else ChainLightningTimer -= diff; - if (Shock_Timer <= diff) + if (ShockTimer <= diff) { DoCast(me->getVictim(), SPELL_SHOCK); - Shock_Timer = 15000; - } else Shock_Timer -= diff; + ShockTimer = 15000; + } else ShockTimer -= diff; DoMeleeAttackIfReady(); } diff --git a/src/server/scripts/Kalimdor/silithus.cpp b/src/server/scripts/Kalimdor/silithus.cpp index 66986ebd5ae..639de3dc3b2 100644 --- a/src/server/scripts/Kalimdor/silithus.cpp +++ b/src/server/scripts/Kalimdor/silithus.cpp @@ -29,7 +29,9 @@ npcs_rutgar_and_frankal quest_a_pawn_on_the_eternal_pawn EndContentData */ -#include "ScriptPCH.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedGossip.h" #include "Group.h" /*### @@ -125,9 +127,11 @@ public: #define GOSSIP_ITEM14 "I should ask the monkey about this" #define GOSSIP_ITEM15 "Then what..." -//trigger creatures to kill -#define TRIGGER_RUTGAR 15222 -#define TRIGGER_FRANKAL 15221 +enum RutgarAndFrankal //trigger creatures to kill +{ + TRIGGER_FRANKAL = 15221, + TRIGGER_RUTGAR = 15222 +}; class npcs_rutgar_and_frankal : public CreatureScript { @@ -223,7 +227,7 @@ public: /*#### # quest_a_pawn_on_the_eternal_board (Defines) ####*/ -enum eEternalBoard +enum EternalBoard { QUEST_A_PAWN_ON_THE_ETERNAL_BOARD = 8519, @@ -290,7 +294,6 @@ TO DO: get correct spell IDs and timings for spells cast upon dragon transformat TO DO: Dragons should use the HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF) after transformation, but for some unknown reason it doesnt work. EndContentData */ -#define QUEST_A_PAWN_ON_THE_ETERNAL_BOARD 8519 #define EVENT_AREA_RADIUS 65 //65yds #define EVENT_COOLDOWN 500000 //in ms. appear after event completed or failed (should be = Adds despawn time) @@ -374,7 +377,7 @@ static QuestCinematic EventAnim[]= }; //Cordinates for Spawns -static const Position SpawnLocation[]= +Position const SpawnLocation[] = { {-8085.0f, 1528.0f, 2.61f, 3.141592f}, //Kaldorei Infantry {-8080.0f, 1526.0f, 2.61f, 3.141592f}, //Kaldorei Infantry @@ -455,7 +458,7 @@ struct WaveData int32 WaveTextId; }; -static WaveData WavesInfo[] = +static WaveData WavesInfo[5] = { {30, 0, 15423, 0, 0, 24000, 0}, // Kaldorei Soldier { 3, 35, 15424, 0, 0, 24000, 0}, // Anubisath Conqueror @@ -470,7 +473,7 @@ struct SpawnSpells uint32 Timer1, Timer2, SpellId; }; -static SpawnSpells SpawnCast[]=// +static SpawnSpells SpawnCast[4] = { {100000, 2000, 33652}, // Stop Time {38500, 300000, 28528}, // Poison Cloud @@ -485,9 +488,9 @@ class npc_anachronos_the_ancient : public CreatureScript public: npc_anachronos_the_ancient() : CreatureScript("npc_anachronos_the_ancient") { } - CreatureAI* GetAI(Creature* c) const + CreatureAI* GetAI(Creature* creature) const { - return new npc_anachronos_the_ancientAI(c); + return new npc_anachronos_the_ancientAI(creature); } struct npc_anachronos_the_ancientAI : public ScriptedAI @@ -813,9 +816,9 @@ class mob_qiraj_war_spawn : public CreatureScript public: mob_qiraj_war_spawn() : CreatureScript("mob_qiraj_war_spawn") { } - CreatureAI* GetAI(Creature* c) const + CreatureAI* GetAI(Creature* creature) const { - return new mob_qiraj_war_spawnAI(c); + return new mob_qiraj_war_spawnAI(creature); } struct mob_qiraj_war_spawnAI : public ScriptedAI @@ -928,9 +931,9 @@ class npc_anachronos_quest_trigger : public CreatureScript public: npc_anachronos_quest_trigger() : CreatureScript("npc_anachronos_quest_trigger") { } - CreatureAI* GetAI(Creature* c) const + CreatureAI* GetAI(Creature* creature) const { - return new npc_anachronos_quest_triggerAI(c); + return new npc_anachronos_quest_triggerAI(creature); } struct npc_anachronos_quest_triggerAI : public ScriptedAI @@ -967,16 +970,15 @@ public: void SummonNextWave() { - //uint8 count = WavesInfo[WaveCount].SpawnCount; uint8 locIndex = WavesInfo[WaveCount].UsedSpawnPoint; - //uint8 KaldoreiSoldierCount = 0; - //uint8 AnubisathConquerorCount = 0; - //uint8 QirajiWaspCount = 0; - for (uint8 i = 0; i < 67; ++i) + uint8 count = locIndex + WavesInfo[WaveCount].SpawnCount; + + for (uint8 i = locIndex; i <= count; ++i) { - if (Creature* spawn = me->SummonCreature(WavesInfo[WaveCount].CreatureId, SpawnLocation[locIndex + i], TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, WavesInfo[WaveCount].DespTimer)) + uint32 desptimer = WavesInfo[WaveCount].DespTimer; + + if (Creature* spawn = me->SummonCreature(WavesInfo[WaveCount].CreatureId, SpawnLocation[i], TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, desptimer)) { - spawn->LoadCreaturesAddon(); if (spawn->GetEntry() == 15423) spawn->SetUInt32Value(UNIT_FIELD_DISPLAYID, 15427+rand()%4); if (i >= 30) WaveCount = 1; @@ -986,12 +988,15 @@ public: if (WaveCount < 5) //1-4 Wave { - mob_qiraj_war_spawn::mob_qiraj_war_spawnAI* spawnAI = CAST_AI(mob_qiraj_war_spawn::mob_qiraj_war_spawnAI, spawn->AI()); - spawnAI->MobGUID = me->GetGUID(); - spawnAI->PlayerGUID = PlayerGUID; + if (mob_qiraj_war_spawn::mob_qiraj_war_spawnAI* spawnAI = CAST_AI(mob_qiraj_war_spawn::mob_qiraj_war_spawnAI, spawn->AI())) + { + spawnAI->MobGUID = me->GetGUID(); + spawnAI->PlayerGUID = PlayerGUID; + } } } } + WaveTimer = WavesInfo[WaveCount].SpawnTimer; AnnounceTimer = WavesInfo[WaveCount].YellTimer; } @@ -1005,27 +1010,27 @@ public: if (Group* EventGroup = player->GetGroup()) { - Player* GroupMember; + Player* groupMember; uint8 GroupMemberCount = 0; uint8 DeadMemberCount = 0; uint8 FailedMemberCount = 0; - const Group::MemberSlotList members = EventGroup->GetMemberSlots(); + Group::MemberSlotList const members = EventGroup->GetMemberSlots(); for (Group::member_citerator itr = members.begin(); itr!= members.end(); ++itr) { - GroupMember = (Unit::GetPlayer(*me, itr->guid)); - if (!GroupMember) + groupMember = (Unit::GetPlayer(*me, itr->guid)); + if (!groupMember) continue; - if (!GroupMember->IsWithinDistInMap(me, EVENT_AREA_RADIUS) && GroupMember->GetQuestStatus(QUEST_A_PAWN_ON_THE_ETERNAL_BOARD) == QUEST_STATUS_INCOMPLETE) + if (!groupMember->IsWithinDistInMap(me, EVENT_AREA_RADIUS) && groupMember->GetQuestStatus(QUEST_A_PAWN_ON_THE_ETERNAL_BOARD) == QUEST_STATUS_INCOMPLETE) { - GroupMember->FailQuest(QUEST_A_PAWN_ON_THE_ETERNAL_BOARD); + groupMember->FailQuest(QUEST_A_PAWN_ON_THE_ETERNAL_BOARD); ++FailedMemberCount; } ++GroupMemberCount; - if (GroupMember->isDead()) + if (groupMember->isDead()) ++DeadMemberCount; } @@ -1069,8 +1074,13 @@ public: void mob_qiraj_war_spawn::mob_qiraj_war_spawnAI::JustDied(Unit* /*slayer*/) { me->RemoveCorpse(); - if (Creature* Mob = (Unit::GetCreature(*me, MobGUID))) - CAST_AI(npc_anachronos_quest_trigger::npc_anachronos_quest_triggerAI, Mob->AI())->LiveCounter(); + + if (!MobGUID) + return; + + if (Creature* mob = Unit::GetCreature(*me, MobGUID)) + if (npc_anachronos_quest_trigger::npc_anachronos_quest_triggerAI* triggerAI = CAST_AI(npc_anachronos_quest_trigger::npc_anachronos_quest_triggerAI, mob->AI())) + triggerAI->LiveCounter(); }; @@ -1087,15 +1097,13 @@ public: { if (quest->GetQuestId() == QUEST_A_PAWN_ON_THE_ETERNAL_BOARD) { - - if (Unit* Anachronos_Quest_Trigger = go->FindNearestCreature(15454, 100, player)) + if (Creature* trigger = go->FindNearestCreature(15454, 100, player)) { - - Unit* Merithra = Anachronos_Quest_Trigger->SummonCreature(15378, -8034.535f, 1535.14f, 2.61f, 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 220000); - Unit* Caelestrasz = Anachronos_Quest_Trigger->SummonCreature(15379, -8032.767f, 1533.148f, 2.61f, 1.5f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 220000); - Unit* Arygos = Anachronos_Quest_Trigger->SummonCreature(15380, -8034.52f, 1537.843f, 2.61f, 5.7f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 220000); - /* Unit* Fandral = */ Anachronos_Quest_Trigger->SummonCreature(15382, -8028.462f, 1535.843f, 2.61f, 3.141592f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 220000); - Creature* Anachronos = Anachronos_Quest_Trigger->SummonCreature(15381, -8028.75f, 1538.795f, 2.61f, 4, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 220000); + Unit* Merithra = trigger->SummonCreature(15378, -8034.535f, 1535.14f, 2.61f, 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 220000); + Unit* Caelestrasz = trigger->SummonCreature(15379, -8032.767f, 1533.148f, 2.61f, 1.5f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 220000); + Unit* Arygos = trigger->SummonCreature(15380, -8034.52f, 1537.843f, 2.61f, 5.7f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 220000); + /* Unit* Fandral = */ trigger->SummonCreature(15382, -8028.462f, 1535.843f, 2.61f, 3.141592f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 220000); + Creature* Anachronos = trigger->SummonCreature(15381, -8028.75f, 1538.795f, 2.61f, 4, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 220000); if (Merithra) { @@ -1123,11 +1131,16 @@ public: if (Anachronos) { - CAST_AI(npc_anachronos_the_ancient::npc_anachronos_the_ancientAI, Anachronos->AI())->PlayerGUID = player->GetGUID(); - CAST_AI(npc_anachronos_quest_trigger::npc_anachronos_quest_triggerAI, CAST_CRE(Anachronos_Quest_Trigger)->AI())->Failed=false; - CAST_AI(npc_anachronos_quest_trigger::npc_anachronos_quest_triggerAI, CAST_CRE(Anachronos_Quest_Trigger)->AI())->PlayerGUID = player->GetGUID(); - CAST_AI(npc_anachronos_quest_trigger::npc_anachronos_quest_triggerAI, CAST_CRE(Anachronos_Quest_Trigger)->AI())->EventStarted=true; - CAST_AI(npc_anachronos_quest_trigger::npc_anachronos_quest_triggerAI, CAST_CRE(Anachronos_Quest_Trigger)->AI())->Announced=true; + if (npc_anachronos_the_ancient::npc_anachronos_the_ancientAI* anachronosAI = CAST_AI(npc_anachronos_the_ancient::npc_anachronos_the_ancientAI, Anachronos->AI())) + anachronosAI->PlayerGUID = player->GetGUID(); + + if (npc_anachronos_quest_trigger::npc_anachronos_quest_triggerAI* triggerAI = CAST_AI(npc_anachronos_quest_trigger::npc_anachronos_quest_triggerAI, trigger->AI())) + { + triggerAI->Failed = false; + triggerAI->PlayerGUID = player->GetGUID(); + triggerAI->EventStarted = true; + triggerAI->Announced = true; + } } } } diff --git a/src/server/scripts/Kalimdor/stonetalon_mountains.cpp b/src/server/scripts/Kalimdor/stonetalon_mountains.cpp index 635bb50509e..d38395c7b37 100644 --- a/src/server/scripts/Kalimdor/stonetalon_mountains.cpp +++ b/src/server/scripts/Kalimdor/stonetalon_mountains.cpp @@ -28,7 +28,9 @@ npc_braug_dimspirit npc_kaya_flathoof EndContentData */ -#include "ScriptPCH.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedGossip.h" #include "ScriptedEscortAI.h" /*###### @@ -90,7 +92,7 @@ public: ## npc_kaya_flathoof ######*/ -enum eKaya +enum Kaya { FACTION_ESCORTEE_H = 775, diff --git a/src/server/scripts/Kalimdor/tanaris.cpp b/src/server/scripts/Kalimdor/tanaris.cpp index da0e0e738cf..9b742b495bb 100644 --- a/src/server/scripts/Kalimdor/tanaris.cpp +++ b/src/server/scripts/Kalimdor/tanaris.cpp @@ -33,7 +33,9 @@ npc_OOX17 npc_tooga EndContentData */ -#include "ScriptPCH.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedGossip.h" #include "ScriptedEscortAI.h" #include "ScriptedFollowerAI.h" @@ -41,10 +43,13 @@ EndContentData */ ## mob_aquementas ######*/ -#define AGGRO_YELL_AQUE -1000350 +enum Aquementas +{ + AGGRO_YELL_AQUE = -1000350, -#define SPELL_AQUA_JET 13586 -#define SPELL_FROST_SHOCK 15089 + SPELL_AQUA_JET = 13586, + SPELL_FROST_SHOCK = 15089 +}; class mob_aquementas : public CreatureScript { @@ -60,22 +65,22 @@ public: { mob_aquementasAI(Creature* creature) : ScriptedAI(creature) {} - uint32 SendItem_Timer; - uint32 SwitchFaction_Timer; + uint32 SendItemTimer; + uint32 SwitchFactionTimer; bool isFriendly; - uint32 FrostShock_Timer; - uint32 AquaJet_Timer; + uint32 FrostShockTimer; + uint32 AquaJetTimer; void Reset() { - SendItem_Timer = 0; - SwitchFaction_Timer = 10000; + SendItemTimer = 0; + SwitchFactionTimer = 10000; me->setFaction(35); isFriendly = true; - AquaJet_Timer = 5000; - FrostShock_Timer = 1000; + AquaJetTimer = 5000; + FrostShockTimer = 1000; } void SendItem(Unit* receiver) @@ -101,11 +106,11 @@ public: { if (isFriendly) { - if (SwitchFaction_Timer <= diff) + if (SwitchFactionTimer <= diff) { me->setFaction(91); isFriendly = false; - } else SwitchFaction_Timer -= diff; + } else SwitchFactionTimer -= diff; } if (!UpdateVictim()) @@ -113,25 +118,25 @@ public: if (!isFriendly) { - if (SendItem_Timer <= diff) + if (SendItemTimer <= diff) { if (me->getVictim()->GetTypeId() == TYPEID_PLAYER) SendItem(me->getVictim()); - SendItem_Timer = 5000; - } else SendItem_Timer -= diff; + SendItemTimer = 5000; + } else SendItemTimer -= diff; } - if (FrostShock_Timer <= diff) + if (FrostShockTimer <= diff) { DoCast(me->getVictim(), SPELL_FROST_SHOCK); - FrostShock_Timer = 15000; - } else FrostShock_Timer -= diff; + FrostShockTimer = 15000; + } else FrostShockTimer -= diff; - if (AquaJet_Timer <= diff) + if (AquaJetTimer <= diff) { DoCast(me, SPELL_AQUA_JET); - AquaJet_Timer = 15000; - } else AquaJet_Timer -= diff; + AquaJetTimer = 15000; + } else AquaJetTimer -= diff; DoMeleeAttackIfReady(); } @@ -143,20 +148,23 @@ public: ## npc_custodian_of_time ######*/ -#define WHISPER_CUSTODIAN_1 -1000217 -#define WHISPER_CUSTODIAN_2 -1000218 -#define WHISPER_CUSTODIAN_3 -1000219 -#define WHISPER_CUSTODIAN_4 -1000220 -#define WHISPER_CUSTODIAN_5 -1000221 -#define WHISPER_CUSTODIAN_6 -1000222 -#define WHISPER_CUSTODIAN_7 -1000223 -#define WHISPER_CUSTODIAN_8 -1000224 -#define WHISPER_CUSTODIAN_9 -1000225 -#define WHISPER_CUSTODIAN_10 -1000226 -#define WHISPER_CUSTODIAN_11 -1000227 -#define WHISPER_CUSTODIAN_12 -1000228 -#define WHISPER_CUSTODIAN_13 -1000229 -#define WHISPER_CUSTODIAN_14 -1000230 +enum CustodianOfTime +{ + WHISPER_CUSTODIAN_1 = -1000217, + WHISPER_CUSTODIAN_2 = -1000218, + WHISPER_CUSTODIAN_3 = -1000219, + WHISPER_CUSTODIAN_4 = -1000220, + WHISPER_CUSTODIAN_5 = -1000221, + WHISPER_CUSTODIAN_6 = -1000222, + WHISPER_CUSTODIAN_7 = -1000223, + WHISPER_CUSTODIAN_8 = -1000224, + WHISPER_CUSTODIAN_9 = -1000225, + WHISPER_CUSTODIAN_10 = -1000226, + WHISPER_CUSTODIAN_11 = -1000227, + WHISPER_CUSTODIAN_12 = -1000228, + WHISPER_CUSTODIAN_13 = -1000229, + WHISPER_CUSTODIAN_14 = -1000230 +}; class npc_custodian_of_time : public CreatureScript { @@ -174,69 +182,68 @@ public: void WaypointReached(uint32 waypointId) { - Player* player = GetPlayerForEscort(); - if (!player) - return; - - switch (waypointId) + if (Player* player = GetPlayerForEscort()) { - case 0: - DoScriptText(WHISPER_CUSTODIAN_1, me, player); - break; - case 1: - DoScriptText(WHISPER_CUSTODIAN_2, me, player); - break; - case 2: - DoScriptText(WHISPER_CUSTODIAN_3, me, player); - break; - case 3: - DoScriptText(WHISPER_CUSTODIAN_4, me, player); - break; - case 5: - DoScriptText(WHISPER_CUSTODIAN_5, me, player); - break; - case 6: - DoScriptText(WHISPER_CUSTODIAN_6, me, player); - break; - case 7: - DoScriptText(WHISPER_CUSTODIAN_7, me, player); - break; - case 8: - DoScriptText(WHISPER_CUSTODIAN_8, me, player); - break; - case 9: - DoScriptText(WHISPER_CUSTODIAN_9, me, player); - break; - case 10: - DoScriptText(WHISPER_CUSTODIAN_4, me, player); - break; - case 13: - DoScriptText(WHISPER_CUSTODIAN_10, me, player); - break; - case 14: - DoScriptText(WHISPER_CUSTODIAN_4, me, player); - break; - case 16: - DoScriptText(WHISPER_CUSTODIAN_11, me, player); - break; - case 17: - DoScriptText(WHISPER_CUSTODIAN_12, me, player); - break; - case 18: - DoScriptText(WHISPER_CUSTODIAN_4, me, player); - break; - case 22: - DoScriptText(WHISPER_CUSTODIAN_13, me, player); - break; - case 23: - DoScriptText(WHISPER_CUSTODIAN_4, me, player); - break; - case 24: - DoScriptText(WHISPER_CUSTODIAN_14, me, player); - DoCast(player, 34883); - // below here is temporary workaround, to be removed when spell works properly - player->AreaExploredOrEventHappens(10277); - break; + switch (waypointId) + { + case 0: + DoScriptText(WHISPER_CUSTODIAN_1, me, player); + break; + case 1: + DoScriptText(WHISPER_CUSTODIAN_2, me, player); + break; + case 2: + DoScriptText(WHISPER_CUSTODIAN_3, me, player); + break; + case 3: + DoScriptText(WHISPER_CUSTODIAN_4, me, player); + break; + case 5: + DoScriptText(WHISPER_CUSTODIAN_5, me, player); + break; + case 6: + DoScriptText(WHISPER_CUSTODIAN_6, me, player); + break; + case 7: + DoScriptText(WHISPER_CUSTODIAN_7, me, player); + break; + case 8: + DoScriptText(WHISPER_CUSTODIAN_8, me, player); + break; + case 9: + DoScriptText(WHISPER_CUSTODIAN_9, me, player); + break; + case 10: + DoScriptText(WHISPER_CUSTODIAN_4, me, player); + break; + case 13: + DoScriptText(WHISPER_CUSTODIAN_10, me, player); + break; + case 14: + DoScriptText(WHISPER_CUSTODIAN_4, me, player); + break; + case 16: + DoScriptText(WHISPER_CUSTODIAN_11, me, player); + break; + case 17: + DoScriptText(WHISPER_CUSTODIAN_12, me, player); + break; + case 18: + DoScriptText(WHISPER_CUSTODIAN_4, me, player); + break; + case 22: + DoScriptText(WHISPER_CUSTODIAN_13, me, player); + break; + case 23: + DoScriptText(WHISPER_CUSTODIAN_4, me, player); + break; + case 24: + DoScriptText(WHISPER_CUSTODIAN_14, me, player); + DoCast(player, 34883); + // below here is temporary workaround, to be removed when spell works properly + player->AreaExploredOrEventHappens(10277); + break; + } } } @@ -259,7 +266,7 @@ public: } void EnterCombat(Unit* /*who*/) {} - void Reset() { } + void Reset() {} void UpdateAI(const uint32 diff) { @@ -416,7 +423,7 @@ public: ## npc_OOX17 ######*/ -enum e00X17 +enum Npc00X17 { //texts are signed for 7806 SAY_OOX_START = -1000287, @@ -464,30 +471,29 @@ public: void WaypointReached(uint32 waypointId) { - Player* player = GetPlayerForEscort(); - if (!player) - return; - - switch (waypointId) + if (Player* player = GetPlayerForEscort()) { - case 23: - me->SummonCreature(SPAWN_FIRST, -8350.96f, -4445.79f, 10.10f, 6.20f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); - me->SummonCreature(SPAWN_FIRST, -8355.96f, -4447.79f, 10.10f, 6.27f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); - me->SummonCreature(SPAWN_FIRST, -8353.96f, -4442.79f, 10.10f, 6.08f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); - DoScriptText(SAY_OOX_AMBUSH, me); - break; - case 56: - me->SummonCreature(SPAWN_SECOND_1, -7510.07f, -4795.50f, 9.35f, 6.06f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); - me->SummonCreature(SPAWN_SECOND_2, -7515.07f, -4797.50f, 9.35f, 6.22f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); - me->SummonCreature(SPAWN_SECOND_2, -7518.07f, -4792.50f, 9.35f, 6.22f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); - DoScriptText(SAY_OOX_AMBUSH, me); - if (Unit* scoff = me->FindNearestCreature(SPAWN_SECOND_2, 30)) - DoScriptText(SAY_OOX17_AMBUSH_REPLY, scoff); - break; - case 86: - DoScriptText(SAY_OOX_END, me); - player->GroupEventHappens(Q_OOX17, me); - break; + switch (waypointId) + { + case 23: + me->SummonCreature(SPAWN_FIRST, -8350.96f, -4445.79f, 10.10f, 6.20f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); + me->SummonCreature(SPAWN_FIRST, -8355.96f, -4447.79f, 10.10f, 6.27f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); + me->SummonCreature(SPAWN_FIRST, -8353.96f, -4442.79f, 10.10f, 6.08f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); + DoScriptText(SAY_OOX_AMBUSH, me); + break; + case 56: + me->SummonCreature(SPAWN_SECOND_1, -7510.07f, -4795.50f, 9.35f, 6.06f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); + me->SummonCreature(SPAWN_SECOND_2, -7515.07f, -4797.50f, 9.35f, 6.22f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); + me->SummonCreature(SPAWN_SECOND_2, -7518.07f, -4792.50f, 9.35f, 6.22f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); + DoScriptText(SAY_OOX_AMBUSH, me); + if (Unit* scoff = me->FindNearestCreature(SPAWN_SECOND_2, 30)) + DoScriptText(SAY_OOX17_AMBUSH_REPLY, scoff); + break; + case 86: + DoScriptText(SAY_OOX_END, me); + player->GroupEventHappens(Q_OOX17, me); + break; + } } } @@ -509,7 +515,7 @@ public: # npc_tooga ####*/ -enum eTooga +enum Tooga { SAY_TOOG_THIRST = -1000391, SAY_TOOG_WORRIED = -1000392, @@ -527,7 +533,7 @@ enum eTooga FACTION_TOOG_ESCORTEE = 113 }; -const float m_afToWaterLoc[] = {-7032.664551f, -4906.199219f, -1.606446f}; +Position const ToWaterLoc = {-7032.664551f, -4906.199219f, -1.606446f, 0.0f}; class npc_tooga : public CreatureScript { @@ -554,17 +560,17 @@ public: { npc_toogaAI(Creature* creature) : FollowerAI(creature) { } - uint32 m_uiCheckSpeechTimer; - uint32 m_uiPostEventTimer; - uint32 m_uiPhasePostEvent; + uint32 CheckSpeechTimer; + uint32 PostEventTimer; + uint32 PhasePostEvent; uint64 TortaGUID; void Reset() { - m_uiCheckSpeechTimer = 2500; - m_uiPostEventTimer = 1000; - m_uiPhasePostEvent = 0; + CheckSpeechTimer = 2500; + PostEventTimer = 1000; + PhasePostEvent = 0; TortaGUID = 0; } @@ -577,11 +583,9 @@ public: { if (me->IsWithinDistInMap(who, INTERACTION_DISTANCE)) { - if (Player* player = GetLeaderForFollower()) - { - if (player->GetQuestStatus(QUEST_TOOGA) == QUEST_STATUS_INCOMPLETE) - player->GroupEventHappens(QUEST_TOOGA, me); - } + Player* player = GetLeaderForFollower(); + if (player && player->GetQuestStatus(QUEST_TOOGA) == QUEST_STATUS_INCOMPLETE) + player->GroupEventHappens(QUEST_TOOGA, me); TortaGUID = who->GetGUID(); SetFollowComplete(true); @@ -589,27 +593,27 @@ public: } } - void MovementInform(uint32 uiMotionType, uint32 uiPointId) + void MovementInform(uint32 MotionType, uint32 PointId) { - FollowerAI::MovementInform(uiMotionType, uiPointId); + FollowerAI::MovementInform(MotionType, PointId); - if (uiMotionType != POINT_MOTION_TYPE) + if (MotionType != POINT_MOTION_TYPE) return; - if (uiPointId == POINT_ID_TO_WATER) + if (PointId == POINT_ID_TO_WATER) SetFollowComplete(); } - void UpdateFollowerAI(const uint32 uiDiff) + void UpdateFollowerAI(const uint32 Diff) { if (!UpdateVictim()) { //we are doing the post-event, or... if (HasFollowState(STATE_FOLLOW_POSTEVENT)) { - if (m_uiPostEventTimer <= uiDiff) + if (PostEventTimer <= Diff) { - m_uiPostEventTimer = 5000; + PostEventTimer = 5000; Unit* pTorta = Unit::GetUnit(*me, TortaGUID); if (!pTorta || !pTorta->isAlive()) @@ -619,7 +623,7 @@ public: return; } - switch (m_uiPhasePostEvent) + switch (PhasePostEvent) { case 1: DoScriptText(SAY_TOOG_POST_1, me); @@ -638,27 +642,27 @@ public: break; case 6: DoScriptText(SAY_TORT_POST_6, pTorta); - me->GetMotionMaster()->MovePoint(POINT_ID_TO_WATER, m_afToWaterLoc[0], m_afToWaterLoc[1], m_afToWaterLoc[2]); + me->GetMotionMaster()->MovePoint(POINT_ID_TO_WATER, ToWaterLoc); break; } - ++m_uiPhasePostEvent; + ++PhasePostEvent; } else - m_uiPostEventTimer -= uiDiff; + PostEventTimer -= Diff; } //...we are doing regular speech check else if (HasFollowState(STATE_FOLLOW_INPROGRESS)) { - if (m_uiCheckSpeechTimer <= uiDiff) + if (CheckSpeechTimer <= Diff) { - m_uiCheckSpeechTimer = 5000; + CheckSpeechTimer = 5000; if (urand(0, 9) > 8) DoScriptText(RAND(SAY_TOOG_THIRST, SAY_TOOG_WORRIED), me); } else - m_uiCheckSpeechTimer -= uiDiff; + CheckSpeechTimer -= Diff; } return; diff --git a/src/server/scripts/Kalimdor/teldrassil.cpp b/src/server/scripts/Kalimdor/teldrassil.cpp index d7cac99c374..7f2b2fc7f05 100644 --- a/src/server/scripts/Kalimdor/teldrassil.cpp +++ b/src/server/scripts/Kalimdor/teldrassil.cpp @@ -27,14 +27,15 @@ EndScriptData */ npc_mist EndContentData */ -#include "ScriptPCH.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" #include "ScriptedFollowerAI.h" /*#### # npc_mist ####*/ -enum eMist +enum Mist { SAY_AT_HOME = -1000323, EMOTE_AT_HOME = -1000324, @@ -51,10 +52,8 @@ public: bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) { if (quest->GetQuestId() == QUEST_MIST) - { if (npc_mistAI* pMistAI = CAST_AI(npc_mist::npc_mistAI, creature->AI())) pMistAI->StartFollow(player, FACTION_DARNASSUS, quest); - } return true; } @@ -88,18 +87,16 @@ public: { DoScriptText(EMOTE_AT_HOME, me); - if (Player* player = GetLeaderForFollower()) - { - if (player->GetQuestStatus(QUEST_MIST) == QUEST_STATUS_INCOMPLETE) - player->GroupEventHappens(QUEST_MIST, me); - } + Player* player = GetLeaderForFollower(); + if (player && player->GetQuestStatus(QUEST_MIST) == QUEST_STATUS_INCOMPLETE) + player->GroupEventHappens(QUEST_MIST, me); //The follow is over (and for later development, run off to the woods before really end) SetFollowComplete(); } //call not needed here, no known abilities - /*void UpdateFollowerAI(const uint32 uiDiff) + /*void UpdateFollowerAI(const uint32 Diff) { if (!UpdateVictim()) return; diff --git a/src/server/scripts/Kalimdor/the_barrens.cpp b/src/server/scripts/Kalimdor/the_barrens.cpp index c56991e2553..f4983558b67 100644 --- a/src/server/scripts/Kalimdor/the_barrens.cpp +++ b/src/server/scripts/Kalimdor/the_barrens.cpp @@ -32,7 +32,9 @@ npc_twiggy_flathead npc_wizzlecrank_shredder EndContentData */ -#include "ScriptPCH.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedGossip.h" #include "ScriptedEscortAI.h" /*###### @@ -41,7 +43,7 @@ EndContentData */ #define GOSSIP_CORPSE "Examine corpse in detail..." -enum eQuests +enum BeatenCorpse { QUEST_LOST_IN_BATTLE = 4921 }; @@ -77,7 +79,7 @@ public: # npc_gilthares ######*/ -enum eGilthares +enum Gilthares { SAY_GIL_START = -1000370, SAY_GIL_AT_LAST = -1000371, @@ -214,7 +216,7 @@ public: ## npc_taskmaster_fizzule ######*/ -enum eEnums +enum TaskmasterFizzule { FACTION_FRIENDLY_F = 35, SPELL_FLARE = 10113, @@ -240,13 +242,13 @@ public: uint32 factionNorm; bool IsFriend; - uint32 Reset_Timer; + uint32 ResetTimer; uint8 FlareCount; void Reset() { IsFriend = false; - Reset_Timer = 120000; + ResetTimer = 120000; FlareCount = 0; me->setFaction(factionNorm); } @@ -281,11 +283,11 @@ public: { if (IsFriend) { - if (Reset_Timer <= diff) + if (ResetTimer <= diff) { EnterEvadeMode(); return; - } else Reset_Timer -= diff; + } else ResetTimer -= diff; } if (!UpdateVictim()) @@ -315,7 +317,7 @@ public: ## npc_twiggy_flathead #####*/ -enum eTwiggyFlathead +enum TwiggyFlathead { NPC_BIG_WILL = 6238, NPC_AFFRAY_CHALLENGER = 6240, @@ -327,7 +329,7 @@ enum eTwiggyFlathead SAY_TWIGGY_FLATHEAD_OVER = -1000127, }; -float AffrayChallengerLoc[6][4]= +Position const AffrayChallengerLoc[6] = { {-1683.0f, -4326.0f, 2.79f, 0.0f}, {-1682.0f, -4329.0f, 2.79f, 0.0f}, @@ -354,10 +356,10 @@ public: bool EventInProgress; bool EventGrate; bool EventBigWill; - bool Challenger_down[6]; - uint32 Wave; - uint32 Wave_Timer; - uint32 Challenger_checker; + bool ChallengerDown[6]; + uint8 Wave; + uint32 WaveTimer; + uint32 ChallengerChecker; uint64 PlayerGUID; uint64 AffrayChallenger[6]; uint64 BigWill; @@ -367,15 +369,15 @@ public: EventInProgress = false; EventGrate = false; EventBigWill = false; - Wave_Timer = 600000; - Challenger_checker = 0; + WaveTimer = 600000; + ChallengerChecker = 0; Wave = 0; PlayerGUID = 0; for (uint8 i = 0; i < 6; ++i) { AffrayChallenger[i] = 0; - Challenger_down[i] = false; + ChallengerDown[i] = false; } BigWill = 0; } @@ -408,42 +410,26 @@ public: return; if (!pWarrior->isAlive() && pWarrior->GetQuestStatus(1719) == QUEST_STATUS_INCOMPLETE) { - EventInProgress = false; DoScriptText(SAY_TWIGGY_FLATHEAD_DOWN, me); pWarrior->FailQuest(1719); - for (uint8 i = 0; i < 6; ++i) + for (uint8 i = 0; i < 6; ++i) // unsummon challengers { if (AffrayChallenger[i]) { Creature* creature = Unit::GetCreature((*me), AffrayChallenger[i]); - if (creature) { - if (creature->isAlive()) - { - creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT); - creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - creature->setDeathState(JUST_DIED); - } - } + if (creature && creature->isAlive()) + creature->DisappearAndDie(); } - AffrayChallenger[i] = 0; - Challenger_down[i] = false; } - if (BigWill) + if (BigWill) // unsummon bigWill { Creature* creature = Unit::GetCreature((*me), BigWill); - if (creature) - { - if (creature->isAlive()) - { - creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT); - creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - creature->setDeathState(JUST_DIED); - } - } + if (creature && creature->isAlive()) + creature->DisappearAndDie(); } - BigWill = 0; + Reset(); } if (!EventGrate && EventInProgress) @@ -453,11 +439,11 @@ public: if (x >= -1684 && x <= -1674 && y >= -4334 && y <= -4324) { pWarrior->AreaExploredOrEventHappens(1719); - DoScriptText(SAY_TWIGGY_FLATHEAD_BEGIN, me); + DoScriptText(SAY_TWIGGY_FLATHEAD_BEGIN, me, pWarrior); for (uint8 i = 0; i < 6; ++i) { - Creature* creature = me->SummonCreature(NPC_AFFRAY_CHALLENGER, AffrayChallengerLoc[i][0], AffrayChallengerLoc[i][1], AffrayChallengerLoc[i][2], AffrayChallengerLoc[i][3], TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 600000); + Creature* creature = me->SummonCreature(NPC_AFFRAY_CHALLENGER, AffrayChallengerLoc[i], TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 600000); if (!creature) continue; creature->setFaction(35); @@ -466,31 +452,31 @@ public: creature->HandleEmoteCommand(EMOTE_ONESHOT_ROAR); AffrayChallenger[i] = creature->GetGUID(); } - Wave_Timer = 5000; - Challenger_checker = 1000; + WaveTimer = 5000; + ChallengerChecker = 1000; EventGrate = true; } } else if (EventInProgress) { - if (Challenger_checker <= diff) + if (ChallengerChecker <= diff) { for (uint8 i = 0; i < 6; ++i) { if (AffrayChallenger[i]) { Creature* creature = Unit::GetCreature((*me), AffrayChallenger[i]); - if ((!creature || (!creature->isAlive())) && !Challenger_down[i]) + if ((!creature || (!creature->isAlive())) && !ChallengerDown[i]) { DoScriptText(SAY_TWIGGY_FLATHEAD_DOWN, me); - Challenger_down[i] = true; + ChallengerDown[i] = true; } } } - Challenger_checker = 1000; - } else Challenger_checker -= diff; + ChallengerChecker = 1000; + } else ChallengerChecker -= diff; - if (Wave_Timer <= diff) + if (WaveTimer <= diff) { if (Wave < 6 && AffrayChallenger[Wave] && !EventBigWill) { @@ -504,7 +490,7 @@ public: creature->setFaction(14); creature->AI()->AttackStart(pWarrior); ++Wave; - Wave_Timer = 20000; + WaveTimer = 20000; } } else if (Wave >= 6 && !EventBigWill) { @@ -516,7 +502,7 @@ public: creature->GetMotionMaster()->MovePoint(2, -1682, -4329, 2.79f); creature->HandleEmoteCommand(EMOTE_STATE_READY_UNARMED); EventBigWill = true; - Wave_Timer = 1000; + WaveTimer = 1000; } } else if (Wave >= 6 && EventBigWill && BigWill) @@ -525,14 +511,10 @@ public: if (!creature || !creature->isAlive()) { DoScriptText(SAY_TWIGGY_FLATHEAD_OVER, me); - EventInProgress = false; - EventBigWill = false; - EventGrate = false; - PlayerGUID = 0; - Wave = 0; + Reset(); } } - } else Wave_Timer -= diff; + } else WaveTimer -= diff; } } } @@ -544,7 +526,7 @@ public: ## npc_wizzlecrank_shredder #####*/ -enum eEnums_Wizzlecrank +enum Wizzlecrank { SAY_START = -1000298, SAY_STARTUP1 = -1000299, @@ -570,14 +552,14 @@ public: { npc_wizzlecrank_shredderAI(Creature* creature) : npc_escortAI(creature) { - m_bIsPostEvent = false; - m_uiPostEventTimer = 1000; - m_uiPostEventCount = 0; + IsPostEvent = false; + PostEventTimer = 1000; + PostEventCount = 0; } - bool m_bIsPostEvent; - uint32 m_uiPostEventTimer; - uint32 m_uiPostEventCount; + bool IsPostEvent; + uint32 PostEventTimer; + uint32 PostEventCount; void Reset() { @@ -586,9 +568,9 @@ public: if (me->getStandState() == UNIT_STAND_STATE_DEAD) me->SetStandState(UNIT_STAND_STATE_STAND); - m_bIsPostEvent = false; - m_uiPostEventTimer = 1000; - m_uiPostEventCount = 0; + IsPostEvent = false; + PostEventTimer = 1000; + PostEventCount = 0; } } @@ -610,19 +592,19 @@ public: } break; case 24: - m_bIsPostEvent = true; + IsPostEvent = true; break; } } - void WaypointStart(uint32 uiPointId) + void WaypointStart(uint32 PointId) { Player* player = GetPlayerForEscort(); if (!player) return; - switch (uiPointId) + switch (PointId) { case 9: DoScriptText(SAY_STARTUP2, me, player); @@ -643,15 +625,15 @@ public: summoned->AI()->AttackStart(me); } - void UpdateEscortAI(const uint32 uiDiff) + void UpdateEscortAI(const uint32 Diff) { if (!UpdateVictim()) { - if (m_bIsPostEvent) + if (IsPostEvent) { - if (m_uiPostEventTimer <= uiDiff) + if (PostEventTimer <= Diff) { - switch (m_uiPostEventCount) + switch (PostEventCount) { case 0: DoScriptText(SAY_PROGRESS_2, me); @@ -671,11 +653,11 @@ public: break; } - ++m_uiPostEventCount; - m_uiPostEventTimer = 5000; + ++PostEventCount; + PostEventTimer = 5000; } else - m_uiPostEventTimer -= uiDiff; + PostEventTimer -= Diff; } return; diff --git a/src/server/scripts/Kalimdor/thousand_needles.cpp b/src/server/scripts/Kalimdor/thousand_needles.cpp index 5b77b8dc2c0..b9ae356ddf1 100644 --- a/src/server/scripts/Kalimdor/thousand_needles.cpp +++ b/src/server/scripts/Kalimdor/thousand_needles.cpp @@ -32,14 +32,16 @@ npc_enraged_panther go_panther_cage EndContentData */ -#include "ScriptPCH.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedGossip.h" #include "ScriptedEscortAI.h" /*##### # npc_kanati ######*/ -enum eKanati +enum Kanati { SAY_KAN_START = -1000410, @@ -47,7 +49,7 @@ enum eKanati NPC_GALAK_ASS = 10720 }; -const float m_afGalakLoc[]= {-4867.387695f, -1357.353760f, -48.226f }; +Position const GalakLoc = {-4867.387695f, -1357.353760f, -48.226f, 0.0f}; class npc_kanati : public CreatureScript { @@ -57,10 +59,9 @@ public: bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest) { if (quest->GetQuestId() == QUEST_PROTECT_KANATI) - { if (npc_kanatiAI* pEscortAI = CAST_AI(npc_kanati::npc_kanatiAI, creature->AI())) pEscortAI->Start(false, false, player->GetGUID(), quest, true); - } + return true; } @@ -73,7 +74,7 @@ public: { npc_kanatiAI(Creature* creature) : npc_escortAI(creature) { } - void Reset() { } + void Reset() {} void WaypointReached(uint32 waypointId) { @@ -93,9 +94,7 @@ public: void DoSpawnGalak() { for (int i = 0; i < 3; ++i) - me->SummonCreature(NPC_GALAK_ASS, - m_afGalakLoc[0], m_afGalakLoc[1], m_afGalakLoc[2], 0.0f, - TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); + me->SummonCreature(NPC_GALAK_ASS, GalakLoc, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); } void JustSummoned(Creature* summoned) @@ -110,7 +109,7 @@ public: # npc_lakota_windsong ######*/ -enum eLakota +enum Lakota { SAY_LAKO_START = -1000365, SAY_LAKO_LOOK_OUT = -1000366, @@ -127,14 +126,14 @@ enum eLakota ID_AMBUSH_3 = 4 }; -float m_afBanditLoc[6][6]= +Position const BanditLoc[6] = { - {-4905.479492f, -2062.732666f, 84.352f}, - {-4915.201172f, -2073.528320f, 84.733f}, - {-4878.883301f, -1986.947876f, 91.966f}, - {-4877.503906f, -1966.113403f, 91.859f}, - {-4767.985352f, -1873.169189f, 90.192f}, - {-4788.861328f, -1888.007813f, 89.888f} + {-4905.479492f, -2062.732666f, 84.352f, 0.0f}, + {-4915.201172f, -2073.528320f, 84.733f, 0.0f}, + {-4878.883301f, -1986.947876f, 91.966f, 0.0f}, + {-4877.503906f, -1966.113403f, 91.859f, 0.0f}, + {-4767.985352f, -1873.169189f, 90.192f, 0.0f}, + {-4788.861328f, -1888.007813f, 89.888f, 0.0f} }; class npc_lakota_windsong : public CreatureScript @@ -164,7 +163,7 @@ public: { npc_lakota_windsongAI(Creature* creature) : npc_escortAI(creature) { } - void Reset() { } + void Reset() {} void WaypointReached(uint32 waypointId) { @@ -189,12 +188,10 @@ public: } } - void DoSpawnBandits(int uiAmbushId) + void DoSpawnBandits(int AmbushId) { for (int i = 0; i < 2; ++i) - me->SummonCreature(NPC_GRIM_BANDIT, - m_afBanditLoc[i+uiAmbushId][0], m_afBanditLoc[i+uiAmbushId][1], m_afBanditLoc[i+uiAmbushId][2], 0.0f, - TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 60000); + me->SummonCreature(NPC_GRIM_BANDIT, BanditLoc[i+AmbushId], TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 60000); } }; @@ -204,7 +201,7 @@ public: # npc_paoka_swiftmountain ######*/ -enum ePacka +enum Packa { SAY_START = -1000362, SAY_WYVERN = -1000363, @@ -215,11 +212,11 @@ enum ePacka FACTION_ESCORTEE = 232 //guessed }; -float m_afWyvernLoc[3][3]= +Position const WyvernLoc[3] = { - {-4990.606f, -906.057f, -5.343f}, - {-4970.241f, -927.378f, -4.951f}, - {-4985.364f, -952.528f, -5.199f} + {-4990.606f, -906.057f, -5.343f, 0.0f}, + {-4970.241f, -927.378f, -4.951f, 0.0f}, + {-4985.364f, -952.528f, -5.199f, 0.0f} }; class npc_paoka_swiftmountain : public CreatureScript @@ -249,7 +246,7 @@ public: { npc_paoka_swiftmountainAI(Creature* creature) : npc_escortAI(creature) { } - void Reset() { } + void Reset() {} void WaypointReached(uint32 waypointId) { @@ -272,9 +269,7 @@ public: void DoSpawnWyvern() { for (int i = 0; i < 3; ++i) - me->SummonCreature(NPC_WYVERN, - m_afWyvernLoc[i][0], m_afWyvernLoc[i][1], m_afWyvernLoc[i][2], 0.0f, - TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 60000); + me->SummonCreature(NPC_WYVERN, WyvernLoc[i], TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 60000); } }; }; @@ -285,7 +280,7 @@ public: #define GOSSIP_P "Please tell me the Phrase.." -enum ePlucky +enum Plucky { FACTION_FRIENDLY = 35, QUEST_SCOOP = 1950, @@ -328,17 +323,17 @@ public: struct npc_pluckyAI : public ScriptedAI { - npc_pluckyAI(Creature* creature) : ScriptedAI(creature) { m_uiNormFaction = creature->getFaction(); } + npc_pluckyAI(Creature* creature) : ScriptedAI(creature) { NormFaction = creature->getFaction(); } - uint32 m_uiNormFaction; - uint32 m_uiResetTimer; + uint32 NormFaction; + uint32 ResetTimer; void Reset() { - m_uiResetTimer = 120000; + ResetTimer = 120000; - if (me->getFaction() != m_uiNormFaction) - me->setFaction(m_uiNormFaction); + if (me->getFaction() != NormFaction) + me->setFaction(NormFaction); if (me->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP)) me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); @@ -346,11 +341,11 @@ public: DoCast(me, SPELL_PLUCKY_CHICKEN, false); } - void ReceiveEmote(Player* player, uint32 uiTextEmote) + void ReceiveEmote(Player* player, uint32 TextEmote) { if (player->GetQuestStatus(QUEST_SCOOP) == QUEST_STATUS_INCOMPLETE) { - if (uiTextEmote == TEXT_EMOTE_BECKON) + if (TextEmote == TEXT_EMOTE_BECKON) { me->setFaction(FACTION_FRIENDLY); me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); @@ -358,7 +353,7 @@ public: } } - if (uiTextEmote == TEXT_EMOTE_CHICKEN) + if (TextEmote == TEXT_EMOTE_CHICKEN) { if (me->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP)) return; @@ -372,11 +367,11 @@ public: } } - void UpdateAI(const uint32 uiDiff) + void UpdateAI(const uint32 Diff) { if (me->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP)) { - if (m_uiResetTimer <= uiDiff) + if (ResetTimer <= Diff) { if (!me->getVictim()) EnterEvadeMode(); @@ -386,7 +381,7 @@ public: return; } else - m_uiResetTimer -= uiDiff; + ResetTimer -= Diff; } if (!UpdateVictim()) @@ -398,7 +393,7 @@ public: }; -enum ePantherCage +enum PantherCage { ENRAGED_PANTHER = 10992 }; diff --git a/src/server/scripts/Kalimdor/thunder_bluff.cpp b/src/server/scripts/Kalimdor/thunder_bluff.cpp index 5aa55ddea66..b8b05b9692f 100644 --- a/src/server/scripts/Kalimdor/thunder_bluff.cpp +++ b/src/server/scripts/Kalimdor/thunder_bluff.cpp @@ -23,17 +23,22 @@ SDComment: Quest support: 925 SDCategory: Thunder Bluff EndScriptData */ -#include "ScriptPCH.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedGossip.h" /*##### # npc_cairne_bloodhoof ######*/ -#define SPELL_BERSERKER_CHARGE 16636 -#define SPELL_CLEAVE 16044 -#define SPELL_MORTAL_STRIKE 16856 -#define SPELL_THUNDERCLAP 23931 -#define SPELL_UPPERCUT 22916 +enum CairneBloodhoof +{ + SPELL_BERSERKER_CHARGE = 16636, + SPELL_CLEAVE = 16044, + SPELL_MORTAL_STRIKE = 16856, + SPELL_THUNDERCLAP = 23931, + SPELL_UPPERCUT = 22916 +}; #define GOSSIP_HCB "I know this is rather silly but a young ward who is a bit shy would like your hoofprint." //TODO: verify abilities/timers @@ -75,19 +80,19 @@ public: { npc_cairne_bloodhoofAI(Creature* creature) : ScriptedAI(creature) {} - uint32 BerserkerCharge_Timer; - uint32 Cleave_Timer; - uint32 MortalStrike_Timer; - uint32 Thunderclap_Timer; - uint32 Uppercut_Timer; + uint32 BerserkerChargeTimer; + uint32 CleaveTimer; + uint32 MortalStrikeTimer; + uint32 ThunderclapTimer; + uint32 UppercutTimer; void Reset() { - BerserkerCharge_Timer = 30000; - Cleave_Timer = 5000; - MortalStrike_Timer = 10000; - Thunderclap_Timer = 15000; - Uppercut_Timer = 10000; + BerserkerChargeTimer = 30000; + CleaveTimer = 5000; + MortalStrikeTimer = 10000; + ThunderclapTimer = 15000; + UppercutTimer = 10000; } void EnterCombat(Unit* /*who*/) {} @@ -97,37 +102,37 @@ public: if (!UpdateVictim()) return; - if (BerserkerCharge_Timer <= diff) + if (BerserkerChargeTimer <= diff) { Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0); if (target) DoCast(target, SPELL_BERSERKER_CHARGE); - BerserkerCharge_Timer = 25000; - } else BerserkerCharge_Timer -= diff; + BerserkerChargeTimer = 25000; + } else BerserkerChargeTimer -= diff; - if (Uppercut_Timer <= diff) + if (UppercutTimer <= diff) { DoCast(me->getVictim(), SPELL_UPPERCUT); - Uppercut_Timer = 20000; - } else Uppercut_Timer -= diff; + UppercutTimer = 20000; + } else UppercutTimer -= diff; - if (Thunderclap_Timer <= diff) + if (ThunderclapTimer <= diff) { DoCast(me->getVictim(), SPELL_THUNDERCLAP); - Thunderclap_Timer = 15000; - } else Thunderclap_Timer -= diff; + ThunderclapTimer = 15000; + } else ThunderclapTimer -= diff; - if (MortalStrike_Timer <= diff) + if (MortalStrikeTimer <= diff) { DoCast(me->getVictim(), SPELL_MORTAL_STRIKE); - MortalStrike_Timer = 15000; - } else MortalStrike_Timer -= diff; + MortalStrikeTimer = 15000; + } else MortalStrikeTimer -= diff; - if (Cleave_Timer <= diff) + if (CleaveTimer <= diff) { DoCast(me->getVictim(), SPELL_CLEAVE); - Cleave_Timer = 7000; - } else Cleave_Timer -= diff; + CleaveTimer = 7000; + } else CleaveTimer -= diff; DoMeleeAttackIfReady(); } diff --git a/src/server/scripts/Kalimdor/ungoro_crater.cpp b/src/server/scripts/Kalimdor/ungoro_crater.cpp index 232dba404e0..786d2fc0cd3 100644 --- a/src/server/scripts/Kalimdor/ungoro_crater.cpp +++ b/src/server/scripts/Kalimdor/ungoro_crater.cpp @@ -28,11 +28,12 @@ npc_a-me npc_ringo EndContentData */ -#include "ScriptPCH.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" #include "ScriptedEscortAI.h" #include "ScriptedFollowerAI.h" -enum eAMeData +enum AmeData { SAY_READY = -1000517, SAY_AGGRO1 = -1000518, @@ -76,41 +77,40 @@ public: { npc_ameAI(Creature* creature) : npc_escortAI(creature) {} - uint32 DEMORALIZINGSHOUT_Timer; + uint32 DemoralizingShoutTimer; void WaypointReached(uint32 waypointId) { - Player* player = GetPlayerForEscort(); - if (!player) - return; - - switch (waypointId) + if (Player* player = GetPlayerForEscort()) { - case 19: - me->SummonCreature(ENTRY_STOMPER, -6391.69f, -1730.49f, -272.83f, 4.96f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); - DoScriptText(SAY_AGGRO1, me, player); - break; - case 28: - DoScriptText(SAY_SEARCH, me, player); - break; - case 38: - me->SummonCreature(ENTRY_TARLORD, -6370.75f, -1382.84f, -270.51f, 6.06f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); - DoScriptText(SAY_AGGRO2, me, player); - break; - case 49: - me->SummonCreature(ENTRY_TARLORD1, -6324.44f, -1181.05f, -270.17f, 4.34f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); - DoScriptText(SAY_AGGRO3, me, player); - break; - case 55: - DoScriptText(SAY_FINISH, me, player); - player->GroupEventHappens(QUEST_CHASING_AME, me); - break; + switch (waypointId) + { + case 19: + me->SummonCreature(ENTRY_STOMPER, -6391.69f, -1730.49f, -272.83f, 4.96f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); + DoScriptText(SAY_AGGRO1, me, player); + break; + case 28: + DoScriptText(SAY_SEARCH, me, player); + break; + case 38: + me->SummonCreature(ENTRY_TARLORD, -6370.75f, -1382.84f, -270.51f, 6.06f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); + DoScriptText(SAY_AGGRO2, me, player); + break; + case 49: + me->SummonCreature(ENTRY_TARLORD1, -6324.44f, -1181.05f, -270.17f, 4.34f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); + DoScriptText(SAY_AGGRO3, me, player); + break; + case 55: + DoScriptText(SAY_FINISH, me, player); + player->GroupEventHappens(QUEST_CHASING_AME, me); + break; + } } } void Reset() { - DEMORALIZINGSHOUT_Timer = 5000; + DemoralizingShoutTimer = 5000; } void JustSummoned(Creature* summoned) @@ -130,11 +130,11 @@ public: if (!UpdateVictim()) return; - if (DEMORALIZINGSHOUT_Timer <= diff) + if (DemoralizingShoutTimer <= diff) { DoCast(me->getVictim(), SPELL_DEMORALIZINGSHOUT); - DEMORALIZINGSHOUT_Timer = 70000; - } else DEMORALIZINGSHOUT_Timer -= diff; + DemoralizingShoutTimer = 70000; + } else DemoralizingShoutTimer -= diff; } }; }; @@ -143,7 +143,7 @@ public: # npc_ringo ####*/ -enum eRingo +enum Ringo { SAY_RIN_START_1 = -1000416, SAY_RIN_START_2 = -1000417, @@ -201,17 +201,17 @@ public: { npc_ringoAI(Creature* creature) : FollowerAI(creature) { } - uint32 m_uiFaintTimer; - uint32 m_uiEndEventProgress; - uint32 m_uiEndEventTimer; + uint32 FaintTimer; + uint32 EndEventProgress; + uint32 EndEventTimer; uint64 SpraggleGUID; void Reset() { - m_uiFaintTimer = urand(30000, 60000); - m_uiEndEventProgress = 0; - m_uiEndEventTimer = 1000; + FaintTimer = urand(30000, 60000); + EndEventProgress = 0; + EndEventTimer = 1000; SpraggleGUID = 0; } @@ -266,13 +266,13 @@ public: SetFollowPaused(false); } - void UpdateFollowerAI(const uint32 uiDiff) + void UpdateFollowerAI(const uint32 Diff) { if (!UpdateVictim()) { if (HasFollowState(STATE_FOLLOW_POSTEVENT)) { - if (m_uiEndEventTimer <= uiDiff) + if (EndEventTimer <= Diff) { Unit* pSpraggle = Unit::GetUnit(*me, SpraggleGUID); if (!pSpraggle || !pSpraggle->isAlive()) @@ -281,64 +281,61 @@ public: return; } - switch (m_uiEndEventProgress) + switch (EndEventProgress) { case 1: DoScriptText(SAY_RIN_END_1, me); - m_uiEndEventTimer = 3000; + EndEventTimer = 3000; break; case 2: DoScriptText(SAY_SPR_END_2, pSpraggle); - m_uiEndEventTimer = 5000; + EndEventTimer = 5000; break; case 3: DoScriptText(SAY_RIN_END_3, me); - m_uiEndEventTimer = 1000; + EndEventTimer = 1000; break; case 4: DoScriptText(EMOTE_RIN_END_4, me); SetFaint(); - m_uiEndEventTimer = 9000; + EndEventTimer = 9000; break; case 5: DoScriptText(EMOTE_RIN_END_5, me); ClearFaint(); - m_uiEndEventTimer = 1000; + EndEventTimer = 1000; break; case 6: DoScriptText(SAY_RIN_END_6, me); - m_uiEndEventTimer = 3000; + EndEventTimer = 3000; break; case 7: DoScriptText(SAY_SPR_END_7, pSpraggle); - m_uiEndEventTimer = 10000; + EndEventTimer = 10000; break; case 8: DoScriptText(EMOTE_RIN_END_8, me); - m_uiEndEventTimer = 5000; + EndEventTimer = 5000; break; case 9: SetFollowComplete(); break; } - ++m_uiEndEventProgress; + ++EndEventProgress; } else - m_uiEndEventTimer -= uiDiff; + EndEventTimer -= Diff; } - else if (HasFollowState(STATE_FOLLOW_INPROGRESS)) + else if (HasFollowState(STATE_FOLLOW_INPROGRESS) && !HasFollowState(STATE_FOLLOW_PAUSED)) { - if (!HasFollowState(STATE_FOLLOW_PAUSED)) + if (FaintTimer <= Diff) { - if (m_uiFaintTimer <= uiDiff) - { - SetFaint(); - m_uiFaintTimer = urand(60000, 120000); - } - else - m_uiFaintTimer -= uiDiff; + SetFaint(); + FaintTimer = urand(60000, 120000); } + else + FaintTimer -= Diff; } return; diff --git a/src/server/scripts/Kalimdor/winterspring.cpp b/src/server/scripts/Kalimdor/winterspring.cpp index ab5e4c4023a..a02156ee110 100644 --- a/src/server/scripts/Kalimdor/winterspring.cpp +++ b/src/server/scripts/Kalimdor/winterspring.cpp @@ -29,7 +29,9 @@ npc_rivern_frostwind npc_witch_doctor_mauari EndContentData */ -#include "ScriptPCH.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedGossip.h" /*###### ## npc_lorax diff --git a/src/server/scripts/Northrend/CMakeLists.txt b/src/server/scripts/Northrend/CMakeLists.txt index 31aa924365d..3502e7fb104 100644 --- a/src/server/scripts/Northrend/CMakeLists.txt +++ b/src/server/scripts/Northrend/CMakeLists.txt @@ -22,7 +22,7 @@ set(scripts_STAT_SRCS Northrend/Ulduar/Ulduar/ulduar_teleporter.cpp Northrend/Ulduar/Ulduar/boss_thorim.cpp Northrend/Ulduar/Ulduar/boss_ignis.cpp - Northrend/Ulduar/Ulduar/boss_algalon.cpp + Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp Northrend/Ulduar/Ulduar/instance_ulduar.cpp Northrend/Ulduar/Ulduar/boss_auriaya.cpp Northrend/Ulduar/Ulduar/boss_yoggsaron.cpp diff --git a/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/boss_sartharion.cpp b/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/boss_sartharion.cpp index eeba4a8717d..b115a4ee827 100644 --- a/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/boss_sartharion.cpp +++ b/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/boss_sartharion.cpp @@ -951,7 +951,7 @@ struct dummy_dragonAI : public ScriptedAI return; // Twilight Revenge to main boss - if (Unit* pSartharion = Unit::GetUnit((*me), instance->GetData64(DATA_SARTHARION))) + if (Unit* pSartharion = Unit::GetUnit(*me, instance->GetData64(DATA_SARTHARION))) if (pSartharion->isAlive()) { pSartharion->RemoveAurasDueToSpell(uiSpellId); diff --git a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_saviana_ragefire.cpp b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_saviana_ragefire.cpp index 3407b42b2a7..4e5e01cc745 100644 --- a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_saviana_ragefire.cpp +++ b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_saviana_ragefire.cpp @@ -206,7 +206,7 @@ class spell_saviana_conflagration_init : public SpellScriptLoader unitList.remove_if (ConflagrationTargetSelector()); uint8 maxSize = uint8(GetCaster()->GetMap()->GetSpawnMode() & 1 ? 6 : 3); if (unitList.size() > maxSize) - Trinity::RandomResizeList(unitList, maxSize); + Trinity::Containers::RandomResizeList(unitList, maxSize); } void HandleDummy(SpellEffIndex effIndex) diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_argent_challenge.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_argent_challenge.cpp index d4d1d8c8b4b..305266ee628 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_argent_challenge.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_argent_challenge.cpp @@ -414,8 +414,8 @@ public: void JustDied(Unit* /*killer*/) { - if (me->isSummon()) - if (Unit* summoner = me->ToTempSummon()->GetSummoner()) + if (TempSummon* summ = me->ToTempSummon()) + if (Unit* summoner = summ->GetSummoner()) if (summoner->isAlive()) summoner->GetAI()->SetData(1, 0); } diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp index 37516e5e0df..f329b940e1f 100755 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp @@ -104,7 +104,7 @@ enum BossSpells SPELL_SPIKE_TELE = 66170, }; -#define SPELL_PERMAFROST_HELPER RAID_MODE<uint32>(66193, 67856, 67855, 67857) +#define SPELL_PERMAFROST_HELPER RAID_MODE<uint32>(66193, 67855, 67856, 67857) enum SummonActions { @@ -263,7 +263,8 @@ public: if (instance) instance->SetData(TYPE_ANUBARAK, IN_PROGRESS); //Despawn Scarab Swarms neutral - Summons.DoAction(NPC_SCARAB, ACTION_SCARAB_SUBMERGE); + EntryCheckPredicate pred(NPC_SCARAB); + Summons.DoAction(ACTION_SCARAB_SUBMERGE, pred); //Spawn Burrow for (int i=0; i < 4; i++) me->SummonCreature(NPC_BURROW, AnubarakLoc[i+2]); @@ -304,7 +305,8 @@ public: if (IsHeroic() && m_uiNerubianShadowStrikeTimer <= uiDiff) { - Summons.DoAction(NPC_BURROWER, ACTION_SHADOW_STRIKE); + EntryCheckPredicate pred(NPC_BURROWER); + Summons.DoAction(ACTION_SHADOW_STRIKE, pred); m_uiNerubianShadowStrikeTimer = 30*IN_MILLISECONDS; } else m_uiNerubianShadowStrikeTimer -= uiDiff; diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_faction_champions.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_faction_champions.cpp index d232be4577a..79bbb470edf 100755 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_faction_champions.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_faction_champions.cpp @@ -292,7 +292,7 @@ struct boss_faction_championsAI : public ScriptedAI std::list<HostileReference*> const& tList = me->getThreatManager().getThreatList(); for (std::list<HostileReference*>::const_iterator itr = tList.begin(); itr != tList.end(); ++itr) { - Unit* unit = Unit::GetUnit((*me), (*itr)->getUnitGuid()); + Unit* unit = Unit::GetUnit(*me, (*itr)->getUnitGuid()); if (unit && me->getThreatManager().getThreat(unit)) { if (unit->GetTypeId()==TYPEID_PLAYER) @@ -384,7 +384,7 @@ struct boss_faction_championsAI : public ScriptedAI Unit* target; for (iter = tList.begin(); iter!=tList.end(); ++iter) { - target = Unit::GetUnit((*me), (*iter)->getUnitGuid()); + target = Unit::GetUnit(*me, (*iter)->getUnitGuid()); if (target && target->getPowerType() == POWER_MANA) return target; } @@ -399,7 +399,7 @@ struct boss_faction_championsAI : public ScriptedAI Unit* target; for (iter = tList.begin(); iter!=tList.end(); ++iter) { - target = Unit::GetUnit((*me), (*iter)->getUnitGuid()); + target = Unit::GetUnit(*me, (*iter)->getUnitGuid()); if (target && me->GetDistance2d(target) < distance) ++count; } diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp index 74b9c038482..cf84abb482f 100755 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp @@ -759,7 +759,7 @@ class spell_powering_up : public SpellScriptLoader uint32 spellId; - bool Validate(SpellEntry const* /*spellEntry*/) + bool Load() { spellId = sSpellMgr->GetSpellIdForDifficulty(SPELL_SURGE_OF_SPEED, GetCaster()); if (!sSpellMgr->GetSpellInfo(spellId)) @@ -769,7 +769,7 @@ class spell_powering_up : public SpellScriptLoader void HandleScriptEffect(SpellEffIndex /*effIndex*/) { - if (Unit* target = GetTargetUnit()) + if (Unit* target = GetExplTargetUnit()) if (urand(0, 99) < 15) target->CastSpell(target, spellId, true); } diff --git a/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/forge_of_souls.cpp b/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/forge_of_souls.cpp index 3158d58716f..1469e26fd20 100644 --- a/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/forge_of_souls.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/forge_of_souls.cpp @@ -18,53 +18,6 @@ #include "ScriptPCH.h" #include "forge_of_souls.h" -enum Spells -{ - //Spiteful Apparition - SPELL_SPITE = 68895, - H_SPELL_SPITE = 70212, - - //Spectral Warden - SPELL_VEIL_OF_SHADOWS = 69633, - SPELL_WAIL_OF_SOULS = 69148, - H_SPELL_WAIL_OF_SOULS = 70210, - - //Soulguard Watchman - SPELL_SHROUD_OF_RUNES = 69056, - SPELL_UNHOLY_RAGE = 69053, - - //Soulguard Reaper - SPELL_FROST_NOVA = 69060, - H_SPELL_FROST_NOVA = 70209, - SPELL_SHADOW_LANCE = 69058, - - //Soulguard Bonecaster - SPELL_BONE_VOLLEY = 69080, - H_SPELL_BONE_VOLLEY = 70206, - SPELL_RAISE_DEAD = 69562, - SPELL_SHIELD_OF_BONES = 69069, - H_SPELL_SHIELD_OF_BONES = 70207, - - //Soulguard Animator - // Raise dead 69562 - SPELL_SHADOW_BOLT = 69068, - H_SPELL_SHADOW_BOLT = 70208, - SPELL_SOUL_SICKNESS = 69131, - SPELL_SOUL_SIPHON = 69128, - - //Soulguard Adept - //Raise dead 69562 - //Shadow Bolt 69068/70208 - SPELL_DRAIN_LIFE = 69066, - H_SPELL_DRAIN_LIFE = 70213, - SPELL_SHADOW_MEND = 69564, - H_SPELL_SHADOW_MEND = 70205, - - //Soul Horror - SPELL_SOUL_STRIKE = 69088, - H_SPELL_SOUL_STRIKE = 70211, -}; - enum Events { EVENT_NONE, @@ -78,38 +31,6 @@ enum Events EVENT_INTRO_6, EVENT_INTRO_7, EVENT_INTRO_8, - - //Spiteful Apparition - EVENT_SPITE, - - //Spectral Warden - EVENT_VEIL_OF_SHADOWS, - EVENT_WAIL_OF_SOULS, - - //Soulguard Watchman - EVENT_SHROUD_OF_RUNES, - EVENT_UNHOLY_RAGE, - - //Soulguard Reaper - EVENT_FROST_NOVA, - EVENT_SHADOW_LANCE, - - //Soulguard Bonecaster - EVENT_BONE_VOLLEY, - EVENT_RAISE_DEAD, - EVENT_SHIELD_OF_BONES, - - //Soulguard Animator - EVENT_SHADOW_BOLT, - EVENT_SOUL_SICKNESS, - EVENT_SOUL_SIPHON, - - //Soulguard Adept - EVENT_DRAIN_LIFE, - EVENT_SHADOW_MEND, - - //Soul Horror - EVENT_SOUL_STRIKE, }; /****************************************SYLVANAS************************************/ @@ -410,508 +331,8 @@ public: } }; -class mob_spiteful_apparition : public CreatureScript -{ -public: - mob_spiteful_apparition() : CreatureScript("mob_spiteful_apparition") { } - - struct mob_spiteful_apparitionAI: public ScriptedAI - { - mob_spiteful_apparitionAI(Creature* creature) : ScriptedAI(creature) - { - } - - EventMap events; - - void Reset() - { - events.Reset(); - } - - void EnterCombat(Unit* /*who*/) - { - events.ScheduleEvent(EVENT_SPITE, 8000); - } - - void UpdateAI(const uint32 diff) - { - //Return since we have no target - if (!UpdateVictim()) - return; - - events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - while (uint32 eventId = events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_SPITE: - DoCastVictim(SPELL_SPITE); - events.RescheduleEvent(EVENT_SPITE, 8000); - return; - } - } - - DoMeleeAttackIfReady(); - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new mob_spiteful_apparitionAI(creature); - } -}; - -class mob_spectral_warden : public CreatureScript -{ -public: - mob_spectral_warden() : CreatureScript("mob_spectral_warden") { } - - struct mob_spectral_wardenAI: public ScriptedAI - { - mob_spectral_wardenAI(Creature* creature) : ScriptedAI(creature) - { - } - - EventMap events; - - void Reset() - { - events.Reset(); - } - - void EnterCombat(Unit* /*who*/) - { - events.ScheduleEvent(EVENT_VEIL_OF_SHADOWS, 5000); - events.ScheduleEvent(EVENT_WAIL_OF_SOULS, 10000); - } - - void UpdateAI(const uint32 diff) - { - //Return since we have no target - if (!UpdateVictim()) - return; - - events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - while (uint32 eventId = events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_VEIL_OF_SHADOWS: - DoCastVictim(SPELL_VEIL_OF_SHADOWS); - events.RescheduleEvent(EVENT_VEIL_OF_SHADOWS, 10000); - return; - case EVENT_WAIL_OF_SOULS: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - DoCast(target, SPELL_WAIL_OF_SOULS); - events.RescheduleEvent(EVENT_WAIL_OF_SOULS, 5000); - return; - } - } - DoMeleeAttackIfReady(); - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new mob_spectral_wardenAI(creature); - } -}; - -class mob_soulguard_watchman : public CreatureScript -{ -public: - mob_soulguard_watchman() : CreatureScript("mob_soulguard_watchman") { } - - struct mob_soulguard_watchmanAI: public ScriptedAI - { - mob_soulguard_watchmanAI(Creature* creature) : ScriptedAI(creature) { } - - EventMap events; - - void Reset() - { - events.Reset(); - } - - void EnterCombat(Unit* /*who*/) - { - events.ScheduleEvent(EVENT_SHROUD_OF_RUNES, 1000); - events.ScheduleEvent(EVENT_UNHOLY_RAGE, 1000); - } - - void UpdateAI(const uint32 diff) - { - //Return since we have no target - if (!UpdateVictim()) - return; - - events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - while (uint32 eventId = events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_SHROUD_OF_RUNES: - DoCast(me, SPELL_SHROUD_OF_RUNES); - events.RescheduleEvent(EVENT_SHROUD_OF_RUNES, 5000); - return; - case EVENT_UNHOLY_RAGE: - DoCast(me, SPELL_UNHOLY_RAGE); - events.RescheduleEvent(EVENT_UNHOLY_RAGE, 99999); - return; - } - } - DoMeleeAttackIfReady(); - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new mob_soulguard_watchmanAI(creature); - } -}; - -class mob_soulguard_reaper : public CreatureScript -{ -public: - mob_soulguard_reaper() : CreatureScript("mob_soulguard_reaper") { } - - struct mob_soulguard_reaperAI: public ScriptedAI - { - mob_soulguard_reaperAI(Creature* creature) : ScriptedAI(creature) { } - - EventMap events; - - void Reset() - { - events.Reset(); - } - - void EnterCombat(Unit* /*who*/) - { - events.ScheduleEvent(EVENT_FROST_NOVA, 8000); - events.ScheduleEvent(EVENT_SHADOW_LANCE, 5000); - } - - void UpdateAI(const uint32 diff) - { - //Return since we have no target - if (!UpdateVictim()) - return; - - events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - while (uint32 eventId = events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_FROST_NOVA: - DoCast(me, SPELL_FROST_NOVA); - events.RescheduleEvent(EVENT_FROST_NOVA, 9600); - return; - case EVENT_SHADOW_LANCE: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - DoCast(target, SPELL_SHADOW_LANCE); - events.RescheduleEvent(EVENT_SHADOW_LANCE, 8000); - return; - } - } - - DoMeleeAttackIfReady(); - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new mob_soulguard_reaperAI(creature); - } -}; - -class mob_soulguard_bonecaster : public CreatureScript -{ -public: - mob_soulguard_bonecaster() : CreatureScript("mob_soulguard_bonecaster") { } - - struct mob_soulguard_bonecasterAI: public ScriptedAI - { - mob_soulguard_bonecasterAI(Creature* creature) : ScriptedAI(creature) { } - - EventMap events; - - void Reset() - { - events.Reset(); - } - - void EnterCombat(Unit* /*who*/) - { - events.ScheduleEvent(EVENT_BONE_VOLLEY, 6000); - events.ScheduleEvent(EVENT_RAISE_DEAD, 25000); - events.ScheduleEvent(EVENT_SHIELD_OF_BONES, 6000); - } - - void UpdateAI(const uint32 diff) - { - //Return since we have no target - if (!UpdateVictim()) - return; - - events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - while (uint32 eventId = events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_BONE_VOLLEY: - DoCastAOE(SPELL_BONE_VOLLEY); - events.RescheduleEvent(EVENT_BONE_VOLLEY, 7000); - return; - case EVENT_RAISE_DEAD: - DoCast(me, SPELL_RAISE_DEAD); - events.RescheduleEvent(EVENT_RAISE_DEAD, 25000); - return; - case EVENT_SHIELD_OF_BONES: - DoCast(me, SPELL_SHIELD_OF_BONES); - events.RescheduleEvent(EVENT_SHIELD_OF_BONES, 8000); - return; - } - } - - DoMeleeAttackIfReady(); - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new mob_soulguard_bonecasterAI(creature); - } -}; - -class mob_soulguard_animator : public CreatureScript -{ -public: - mob_soulguard_animator() : CreatureScript("mob_soulguard_animator") { } - - struct mob_soulguard_animatorAI : public ScriptedAI - { - mob_soulguard_animatorAI(Creature* creature) : ScriptedAI(creature) - { - } - - EventMap events; - - void Reset() - { - events.Reset(); - } - - void EnterCombat(Unit* /*who*/) - { - events.ScheduleEvent(EVENT_RAISE_DEAD, 25000); - events.ScheduleEvent(EVENT_SHADOW_BOLT, 5000); - events.ScheduleEvent(EVENT_SOUL_SICKNESS, 8000); - events.ScheduleEvent(EVENT_SOUL_SIPHON, 10000); - } - - void UpdateAI(const uint32 diff) - { - //Return since we have no target - if (!UpdateVictim()) - return; - - events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - while (uint32 eventId = events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_RAISE_DEAD: - DoCast(me, SPELL_RAISE_DEAD); - events.RescheduleEvent(EVENT_RAISE_DEAD, 25000); - return; - case EVENT_SHADOW_BOLT: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - DoCast(target, SPELL_SHADOW_BOLT); - events.RescheduleEvent(EVENT_SHADOW_BOLT, 5000); - return; - case EVENT_SOUL_SICKNESS: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - DoCast(target, SPELL_SOUL_SICKNESS); - events.RescheduleEvent(EVENT_SOUL_SICKNESS, 10000); - return; - case EVENT_SOUL_SIPHON: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - DoCast(target, SPELL_SOUL_SIPHON); - events.RescheduleEvent(EVENT_SOUL_SIPHON, 8000); - return; - } - } - - DoMeleeAttackIfReady(); - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new mob_soulguard_animatorAI(creature); - } -}; - -class mob_soulguard_adept : public CreatureScript -{ -public: - mob_soulguard_adept() : CreatureScript("mob_soulguard_adept") { } - - struct mob_soulguard_adeptAI: public ScriptedAI - { - mob_soulguard_adeptAI(Creature* creature) : ScriptedAI(creature) - { - } - - EventMap events; - - void Reset() - { - events.Reset(); - } - - void EnterCombat(Unit* /*who*/) - { - events.ScheduleEvent(EVENT_RAISE_DEAD, 25000); - events.ScheduleEvent(EVENT_SHADOW_BOLT, 8000); - events.ScheduleEvent(EVENT_DRAIN_LIFE, 7000); - events.ScheduleEvent(EVENT_SHADOW_MEND, 35000); - } - - void UpdateAI(const uint32 diff) - { - //Return since we have no target - if (!UpdateVictim()) - return; - - events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - while (uint32 eventId = events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_RAISE_DEAD: - DoCast(me, SPELL_RAISE_DEAD); - events.RescheduleEvent(EVENT_RAISE_DEAD, 25000); - return; - case EVENT_SHADOW_BOLT: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - DoCast(target, SPELL_SHADOW_BOLT); - events.RescheduleEvent(EVENT_SHADOW_BOLT, 4000); - return; - case EVENT_DRAIN_LIFE: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - DoCast(target, SPELL_DRAIN_LIFE); - events.RescheduleEvent(EVENT_DRAIN_LIFE, 9000); - return; - case EVENT_SHADOW_MEND: - DoCast(me, SPELL_SHADOW_MEND); - events.RescheduleEvent(EVENT_SHADOW_MEND, 20000); - return; - } - } - - DoMeleeAttackIfReady(); - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new mob_soulguard_adeptAI(creature); - } -}; - -class mob_soul_horror : public CreatureScript -{ -public: - mob_soul_horror() : CreatureScript("mob_soul_horror") { } - - struct mob_soul_horrorAI : public ScriptedAI - { - mob_soul_horrorAI(Creature* creature) : ScriptedAI(creature) { } - - EventMap events; - - void Reset() - { - events.Reset(); - } - - void EnterCombat(Unit* /*who*/) - { - events.ScheduleEvent(EVENT_SOUL_STRIKE, 6000); - } - - void UpdateAI(const uint32 diff) - { - //Return since we have no target - if (!UpdateVictim()) - return; - - events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - while (uint32 eventId = events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_SOUL_STRIKE: - DoCast(me->getVictim(), SPELL_SOUL_STRIKE); - events.RescheduleEvent(EVENT_SOUL_STRIKE, 8000); - return; - } - } - - DoMeleeAttackIfReady(); - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new mob_soul_horrorAI(creature); - } -}; - void AddSC_forge_of_souls() { new npc_sylvanas_fos(); new npc_jaina_fos(); - new mob_spiteful_apparition(); - new mob_spectral_warden(); - new mob_soulguard_watchman(); - new mob_soulguard_reaper(); - new mob_soulguard_bonecaster(); - new mob_soulguard_animator(); - new mob_soulguard_adept(); - new mob_soul_horror(); } diff --git a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_forgemaster_garfrost.cpp b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_forgemaster_garfrost.cpp index 64609efd7ff..a3b8c5df4e7 100644 --- a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_forgemaster_garfrost.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_forgemaster_garfrost.cpp @@ -20,14 +20,15 @@ enum Yells { - SAY_AGGRO = -1658001, - SAY_SLAY_1 = -1658002, - SAY_SLAY_2 = -1658003, - SAY_DEATH = -1658004, - SAY_PHASE2 = -1658005, - SAY_PHASE3 = -1658006, - - SAY_TYRANNUS_DEATH = -1658007, + SAY_AGGRO = 0, + SAY_PHASE2 = 1, + SAY_PHASE3 = 2, + SAY_DEATH = 3, + SAY_SLAY = 4, + SAY_THROW_SARONITE = 5, + SAY_CAST_DEEP_FREEZE = 6, + + SAY_TYRANNUS_DEATH = -1658007, // todo }; enum Spells @@ -107,8 +108,9 @@ class boss_garfrost : public CreatureScript void EnterCombat(Unit* /*who*/) { - DoScriptText(SAY_AGGRO, me); + Talk(SAY_AGGRO); DoCast(me, SPELL_PERMAFROST); + me->CallForHelp(70.0f); events.ScheduleEvent(EVENT_THROW_SARONITE, 7000); instance->SetBossState(DATA_GARFROST, IN_PROGRESS); @@ -117,12 +119,13 @@ class boss_garfrost : public CreatureScript void KilledUnit(Unit* victim) { if (victim->GetTypeId() == TYPEID_PLAYER) - DoScriptText(RAND(SAY_SLAY_1, SAY_SLAY_2), me); + Talk(SAY_SLAY); } void JustDied(Unit* /*killer*/) { - DoScriptText(SAY_DEATH, me); + Talk(SAY_DEATH); + if (Creature* tyrannus = me->GetCreature(*me, instance->GetData64(DATA_TYRANNUS))) DoScriptText(SAY_TYRANNUS_DEATH, tyrannus); @@ -134,6 +137,7 @@ class boss_garfrost : public CreatureScript if (events.GetPhaseMask() & PHASE_ONE_MASK && !HealthAbovePct(66)) { events.SetPhase(PHASE_TWO); + Talk(SAY_PHASE2); events.DelayEvents(8000); DoCast(me, SPELL_THUNDERING_STOMP); events.ScheduleEvent(EVENT_JUMP, 1500); @@ -143,6 +147,7 @@ class boss_garfrost : public CreatureScript if (events.GetPhaseMask() & PHASE_TWO_MASK && !HealthAbovePct(33)) { events.SetPhase(PHASE_THREE); + Talk(SAY_PHASE3); events.DelayEvents(8000); DoCast(me, SPELL_THUNDERING_STOMP); events.ScheduleEvent(EVENT_JUMP, 1500); @@ -199,7 +204,10 @@ class boss_garfrost : public CreatureScript { case EVENT_THROW_SARONITE: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) + { + Talk(SAY_THROW_SARONITE); DoCast(target, SPELL_THROW_SARONITE); + } events.ScheduleEvent(EVENT_THROW_SARONITE, urand(12500, 20000)); break; case EVENT_CHILLING_WAVE: @@ -208,7 +216,10 @@ class boss_garfrost : public CreatureScript break; case EVENT_DEEP_FREEZE: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) + { + Talk(SAY_CAST_DEEP_FREEZE); DoCast(target, SPELL_DEEP_FREEZE); + } events.ScheduleEvent(EVENT_DEEP_FREEZE, 35000, 0, PHASE_THREE); break; case EVENT_JUMP: diff --git a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_scourgelord_tyrannus.cpp b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_scourgelord_tyrannus.cpp index 88e9bedcd07..8d015adf4a4 100644 --- a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_scourgelord_tyrannus.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_scourgelord_tyrannus.cpp @@ -387,8 +387,7 @@ class player_overlord_brandAI : public PlayerAI void SetGUID(uint64 guid, int32 /*type*/) { tyrannus = ObjectAccessor::GetCreature(*me, guid); - if (!tyrannus) - me->IsAIEnabled = false; + me->IsAIEnabled = tyrannus != NULL; } void DamageDealt(Unit* /*victim*/, uint32& damage, DamageEffectType /*damageType*/) @@ -423,10 +422,9 @@ class spell_tyrannus_overlord_brand : public SpellScriptLoader return; oldAI = GetTarget()->GetAI(); + oldAIState = GetTarget()->IsAIEnabled; GetTarget()->SetAI(new player_overlord_brandAI(GetTarget()->ToPlayer())); GetTarget()->GetAI()->SetGUID(GetCasterGUID()); - oldAIState = GetTarget()->IsAIEnabled; - GetTarget()->IsAIEnabled = true; } void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) diff --git a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/instance_pit_of_saron.cpp b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/instance_pit_of_saron.cpp index 24529801564..1301acf4c99 100644 --- a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/instance_pit_of_saron.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/instance_pit_of_saron.cpp @@ -23,6 +23,13 @@ Position const SlaveLeaderPos = {689.7158f, -104.8736f, 513.7360f, 0.0f}; // position for Jaina and Sylvanas Position const EventLeaderPos2 = {1054.368f, 107.14620f, 628.4467f, 0.0f}; +DoorData const Doors[] = +{ + {GO_ICE_WALL, DATA_GARFROST, DOOR_TYPE_PASSAGE, BOUNDARY_NONE}, + {GO_ICE_WALL, DATA_ICK, DOOR_TYPE_PASSAGE, BOUNDARY_NONE}, + {GO_HALLS_OF_REFLECTION_PORTCULLIS, DATA_TYRANNUS, DOOR_TYPE_PASSAGE, BOUNDARY_NONE}, +}; + class instance_pit_of_saron : public InstanceMapScript { public: @@ -33,6 +40,7 @@ class instance_pit_of_saron : public InstanceMapScript instance_pit_of_saron_InstanceScript(Map* map) : InstanceScript(map) { SetBossNumber(MAX_ENCOUNTER); + LoadDoorData(Doors); _garfrostGUID = 0; _krickGUID = 0; _ickGUID = 0; @@ -154,6 +162,28 @@ class instance_pit_of_saron : public InstanceMapScript } } + void OnGameObjectCreate(GameObject* go) + { + switch (go->GetEntry()) + { + case GO_ICE_WALL: + case GO_HALLS_OF_REFLECTION_PORTCULLIS: + AddDoor(go, true); + break; + } + } + + void OnGameObjectRemove(GameObject* go) + { + switch (go->GetEntry()) + { + case GO_ICE_WALL: + case GO_HALLS_OF_REFLECTION_PORTCULLIS: + AddDoor(go, false); + break; + } + } + bool SetBossState(uint32 type, EncounterState state) { if (!InstanceScript::SetBossState(type, state)) diff --git a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/pit_of_saron.cpp b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/pit_of_saron.cpp index a91951ca25e..b6c821ef66a 100644 --- a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/pit_of_saron.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/pit_of_saron.cpp @@ -25,9 +25,6 @@ enum eSpells SPELL_HELLFIRE = 69586, SPELL_TACTICAL_BLINK = 69584, SPELL_FROST_BREATH = 69527, //Iceborn Proto-Drake - SPELL_BLINDING_DIRT = 70302, //Wrathbone Laborer - SPELL_PUNCTURE_WOUND = 70278, - SPELL_SHOVELLED = 69572, SPELL_LEAPING_FACE_MAUL = 69504, // Geist Ambusher }; @@ -36,11 +33,6 @@ enum eEvents // Ymirjar Flamebearer EVENT_FIREBALL = 1, EVENT_TACTICAL_BLINK = 2, - - //Wrathbone Laborer - EVENT_BLINDING_DIRT = 3, - EVENT_PUNCTURE_WOUND = 4, - EVENT_SHOVELLED = 5, }; class mob_ymirjar_flamebearer : public CreatureScript @@ -157,73 +149,6 @@ class mob_iceborn_protodrake : public CreatureScript } }; -class mob_wrathbone_laborer : public CreatureScript -{ - public: - mob_wrathbone_laborer() : CreatureScript("mob_wrathbone_laborer") { } - - struct mob_wrathbone_laborerAI: public ScriptedAI - { - mob_wrathbone_laborerAI(Creature* creature) : ScriptedAI(creature) - { - } - - void Reset() - { - _events.Reset(); - } - - void EnterCombat(Unit* /*who*/) - { - _events.ScheduleEvent(EVENT_BLINDING_DIRT, 8000); - _events.ScheduleEvent(EVENT_PUNCTURE_WOUND, 9000); - _events.ScheduleEvent(EVENT_SHOVELLED, 5000); - } - - void UpdateAI(const uint32 diff) - { - if (!UpdateVictim()) - return; - - _events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - while (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_BLINDING_DIRT: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 10.0f, true)) - DoCast(target, SPELL_BLINDING_DIRT); - _events.RescheduleEvent(EVENT_BLINDING_DIRT, 10000); - return; - case EVENT_PUNCTURE_WOUND: - DoCastVictim(SPELL_PUNCTURE_WOUND); - _events.RescheduleEvent(EVENT_PUNCTURE_WOUND, 9000); - return; - case EVENT_SHOVELLED: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, -5.0f)) - DoCast(target, SPELL_SHOVELLED); - _events.RescheduleEvent(EVENT_SHOVELLED, 7000); - return; - } - } - - DoMeleeAttackIfReady(); - } - - private: - EventMap _events; - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new mob_wrathbone_laborerAI(creature); - } -}; - class mob_geist_ambusher : public CreatureScript { public: @@ -240,12 +165,13 @@ class mob_geist_ambusher : public CreatureScript _leapingFaceMaulCooldown = 9000; } - void MoveInLineOfSight(Unit* who) + void EnterCombat(Unit* who) { if (who->GetTypeId() != TYPEID_PLAYER) return; - if (me->IsWithinDistInMap(who, 30.0f)) + // the max range is determined by aggro range + if (me->GetDistance(who) > 5.0f) DoCast(who, SPELL_LEAPING_FACE_MAUL); } @@ -309,7 +235,6 @@ class spell_trash_mob_glacial_strike : public SpellScriptLoader void AddSC_pit_of_saron() { new mob_ymirjar_flamebearer(); - new mob_wrathbone_laborer(); new mob_iceborn_protodrake(); new mob_geist_ambusher(); new spell_trash_mob_glacial_strike(); diff --git a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/pit_of_saron.h b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/pit_of_saron.h index 728e0ccd955..768c3ba40ec 100644 --- a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/pit_of_saron.h +++ b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/pit_of_saron.h @@ -90,6 +90,8 @@ enum CreatureIds enum GameObjectIds { GO_SARONITE_ROCK = 196485, + GO_ICE_WALL = 201885, + GO_HALLS_OF_REFLECTION_PORTCULLIS = 201848, }; #endif diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp index de104a78e43..d091a87dbfe 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp @@ -103,6 +103,7 @@ enum Spells SPELL_UNSTABLE = 72059, SPELL_KINETIC_BOMB_VISUAL = 72054, SPELL_KINETIC_BOMB_EXPLOSION = 72052, + SPELL_KINETIC_BOMB_KNOCKBACK = 72087, // Shock Vortex SPELL_SHOCK_VORTEX_PERIODIC = 71945, @@ -443,20 +444,12 @@ class boss_prince_keleseth_icc : public CreatureScript { summons.Summon(summon); Position pos; - pos.Relocate(summon); + me->GetPosition(&pos); float maxRange = me->GetDistance2d(summon); float angle = me->GetAngle(summon); - // prevent spawning outside of room - while (!me->IsWithinLOS(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ())) - { - maxRange -= 5.0f; - if (maxRange < 5.0f) - break; - - summon->MovePosition(pos, float(rand_norm() * maxRange), angle); - } - + me->MovePositionToFirstCollision(pos, maxRange, angle); summon->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation()); + summon->ToTempSummon()->SetTempSummonType(TEMPSUMMON_CORPSE_DESPAWN); } void DamageDealt(Unit* /*target*/, uint32& damage, DamageEffectType damageType) @@ -894,6 +887,7 @@ class boss_prince_valanar_icc : public CreatureScript summon->GetPosition(x, y, z); float ground_Z = summon->GetMap()->GetHeight(summon->GetPhaseMask(), x, y, z, true, 500.0f); summon->GetMotionMaster()->MovePoint(POINT_KINETIC_BOMB_IMPACT, x, y, ground_Z); + summon->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); break; } case NPC_SHOCK_VORTEX: @@ -1073,7 +1067,7 @@ class npc_blood_queen_lana_thel : public CreatureScript if (_introDone) return; - if (!me->IsWithinDistInMap(who, 35.0f)) + if (!me->IsWithinDistInMap(who, 35.0f, false)) return; _introDone = true; @@ -1232,12 +1226,12 @@ class npc_kinetic_bomb : public CreatureScript void Reset() { _events.Reset(); - me->SetDisplayId(DISPLAY_KINETIC_BOMB); + me->SetWalk(true); me->CastSpell(me, SPELL_UNSTABLE, true); me->CastSpell(me, SPELL_KINETIC_BOMB_VISUAL, true); me->SetReactState(REACT_PASSIVE); - me->SetSpeed(MOVE_FLIGHT, IsHeroic() ? 0.3f : 0.15f, true); me->GetPosition(_x, _y, _groundZ); + me->DespawnOrUnsummon(60000); _groundZ = me->GetMap()->GetHeight(me->GetPhaseMask(), _x, _y, _groundZ, true, 500.0f); } @@ -1247,9 +1241,9 @@ class npc_kinetic_bomb : public CreatureScript _events.ScheduleEvent(EVENT_BOMB_DESPAWN, 1000); else if (action == ACTION_KINETIC_BOMB_JUMP) { - me->GetMotionMaster()->Clear(); - me->GetMotionMaster()->MoveJump(_x, _y, me->GetPositionZ() + 7.0f, 1.0f, 7.0f); - _events.ScheduleEvent(EVENT_CONTINUE_FALLING, 700); + if (!me->HasAura(SPELL_KINETIC_BOMB_KNOCKBACK)) + me->GetMotionMaster()->MoveCharge(_x, _y, me->GetPositionZ() + 100.0f, me->GetSpeed(MOVE_RUN), 0); + _events.RescheduleEvent(EVENT_CONTINUE_FALLING, 3000); } } @@ -1263,10 +1257,10 @@ class npc_kinetic_bomb : public CreatureScript { case EVENT_BOMB_DESPAWN: me->SetVisible(false); + me->DespawnOrUnsummon(5000); break; case EVENT_CONTINUE_FALLING: - me->GetMotionMaster()->Clear(); - me->GetMotionMaster()->MovePoint(POINT_KINETIC_BOMB_IMPACT, _x, _y, _groundZ); + me->GetMotionMaster()->MoveCharge(_x, _y, _groundZ, me->GetSpeed(MOVE_WALK), POINT_KINETIC_BOMB_IMPACT); break; default: break; @@ -1329,17 +1323,16 @@ class npc_dark_nucleus : public CreatureScript void DamageTaken(Unit* attacker, uint32& /*damage*/) { - if (attacker == me) + if (attacker == me || attacker == me->getVictim()) return; - if (!_lockedTarget) - if (me->getVictim() == attacker) - _lockedTarget = true; + me->DeleteThreatList(); + me->AddThreat(attacker, 500000000.0f); } - void UpdateAI(const uint32 diff) + void UpdateAI(uint32 const diff) { - if (!me->isInCombat()) + if (!UpdateVictim()) return; if (_targetAuraCheck <= diff) @@ -1355,23 +1348,6 @@ class npc_dark_nucleus : public CreatureScript } else _targetAuraCheck -= diff; - - if (!_lockedTarget) - { - if (Unit* victim = me->SelectVictim()) - { - if (me->getVictim() && me->getVictim() != victim) - { - me->getVictim()->RemoveAurasDueToSpell(SPELL_SHADOW_RESONANCE_RESIST, me->GetGUID()); - _lockedTarget = true; - } - - _lockedTarget = true; - AttackStart(victim); - DoCast(victim, SPELL_SHADOW_RESONANCE_RESIST); - me->ClearUnitState(UNIT_STATE_CASTING); - } - } } private: @@ -1521,10 +1497,11 @@ class spell_valanar_kinetic_bomb : public SpellScriptLoader void ChangeSummonPos(SpellEffIndex /*effIndex*/) { - WorldLocation summonPos = *GetTargetDest(); + WorldLocation summonPos = *GetExplTargetDest(); Position offset = {0.0f, 0.0f, 20.0f, 0.0f}; summonPos.RelocateOffset(offset); - SetTargetDest(summonPos); + SetExplTargetDest(summonPos); + GetHitDest()->RelocateOffset(offset); } void Register() @@ -1586,7 +1563,7 @@ class spell_valanar_kinetic_bomb_knockback : public SpellScriptLoader void Register() { - AfterHit += SpellHitFn(spell_valanar_kinetic_bomb_knockback_SpellScript::KnockIntoAir); + BeforeHit += SpellHitFn(spell_valanar_kinetic_bomb_knockback_SpellScript::KnockIntoAir); } }; @@ -1663,7 +1640,7 @@ class spell_blood_council_shadow_prison_damage : public SpellScriptLoader void AddExtraDamage() { if (Aura* aur = GetHitUnit()->GetAura(GetSpellInfo()->Id)) - if (AuraEffect const* eff = aur->GetEffect(1)) + if (AuraEffect const* eff = aur->GetEffect(EFFECT_1)) SetHitDamage(GetHitDamage() + eff->GetAmount()); } diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp index 784cda8f595..f086e8dc9cf 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp @@ -386,7 +386,7 @@ class boss_blood_queen_lana_thel : public CreatureScript ++targetCount; if (Is25ManRaid()) ++targetCount; - Trinity::RandomResizeList<Player*>(targets, targetCount); + Trinity::Containers::RandomResizeList<Player*>(targets, targetCount); if (targets.size() > 1) { Talk(SAY_PACT_OF_THE_DARKFALLEN); @@ -409,7 +409,7 @@ class boss_blood_queen_lana_thel : public CreatureScript { std::list<Player*> targets; SelectRandomTarget(false, &targets); - Trinity::RandomResizeList<Player*>(targets, uint32(Is25ManRaid() ? 4 : 2)); + Trinity::Containers::RandomResizeList<Player*>(targets, uint32(Is25ManRaid() ? 4 : 2)); for (std::list<Player*>::iterator itr = targets.begin(); itr != targets.end(); ++itr) DoCast(*itr, SPELL_TWILIGHT_BLOODBOLT); DoCast(me, SPELL_TWILIGHT_BLOODBOLT_TARGET); @@ -481,7 +481,7 @@ class boss_blood_queen_lana_thel : public CreatureScript return tempTargets.front(); } - return SelectRandomContainerElement(tempTargets); + return Trinity::Containers::SelectRandomContainerElement(tempTargets); } std::set<uint64> _vampires; @@ -522,7 +522,7 @@ class spell_blood_queen_vampiric_bite : public SpellScriptLoader SpellCastResult CheckTarget() { - if (IsVampire(GetTargetUnit())) + if (IsVampire(GetExplTargetUnit())) { SetCustomCastResultMessage(SPELL_CUSTOM_ERROR_CANT_TARGET_VAMPIRES); return SPELL_FAILED_CUSTOM_ERROR; @@ -658,7 +658,7 @@ class spell_blood_queen_bloodbolt : public SpellScriptLoader { uint32 targetCount = (targets.size() + 2) / 3; targets.remove_if (BloodboltHitCheck(static_cast<LanaThelAI*>(GetCaster()->GetAI()))); - Trinity::RandomResizeList(targets, targetCount); + Trinity::Containers::RandomResizeList(targets, targetCount); // mark targets now, effect hook has missile travel time delay (might cast next in that time) for (std::list<Unit*>::const_iterator itr = targets.begin(); itr != targets.end(); ++itr) GetCaster()->GetAI()->SetGUID((*itr)->GetGUID(), GUID_BLOODBOLT); diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp index 3ce62d939d3..afc7c503bee 100755 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp @@ -39,6 +39,7 @@ enum ScriptTexts SAY_FRENZY = 11, SAY_BERSERK = 12, SAY_DEATH = 13, + EMOTE_SCENT_OF_BLOOD = 14, // High Overlord Saurfang SAY_INTRO_HORDE_1 = 0, @@ -145,6 +146,7 @@ enum EventTypes EVENT_BOILING_BLOOD = 20, EVENT_BLOOD_NOVA = 21, EVENT_RUNE_OF_BLOOD = 22, + EVENT_SCENT_OF_BLOOD = 52, EVENT_OUTRO_ALLIANCE_1 = 23, EVENT_OUTRO_ALLIANCE_2 = 24, @@ -297,7 +299,7 @@ class boss_deathbringer_saurfang : public CreatureScript Talk(SAY_AGGRO); events.ScheduleEvent(EVENT_SUMMON_BLOOD_BEAST, 30000, 0, PHASE_COMBAT); - events.ScheduleEvent(EVENT_BERSERK, 480000, 0, PHASE_COMBAT); + events.ScheduleEvent(EVENT_BERSERK, IsHeroic() ? 360000 : 480000, 0, PHASE_COMBAT); events.ScheduleEvent(EVENT_BOILING_BLOOD, 15500, 0, PHASE_COMBAT); events.ScheduleEvent(EVENT_BLOOD_NOVA, 17000, 0, PHASE_COMBAT); events.ScheduleEvent(EVENT_RUNE_OF_BLOOD, 20000, 0, PHASE_COMBAT); @@ -374,16 +376,13 @@ class boss_deathbringer_saurfang : public CreatureScript if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true)) summon->AI()->AttackStart(target); - if (IsHeroic()) - DoCast(summon, SPELL_SCENT_OF_BLOOD); - - summon->AI()->DoCast(summon, SPELL_BLOOD_LINK_BEAST, true); - summon->AI()->DoCast(summon, SPELL_RESISTANT_SKIN, true); + summon->CastSpell(summon, SPELL_BLOOD_LINK_BEAST, true); + summon->CastSpell(summon, SPELL_RESISTANT_SKIN, true); summons.Summon(summon); DoZoneInCombat(summon); } - void SummonedCreatureDespawn(Creature* summon) + void SummonedCreatureDies(Creature* summon, Unit* /*killer*/) { summons.Despawn(summon); } @@ -463,18 +462,13 @@ class boss_deathbringer_saurfang : public CreatureScript DoCast(me, SPELL_SUMMON_BLOOD_BEAST_25_MAN+i25); Talk(SAY_BLOOD_BEASTS); events.ScheduleEvent(EVENT_SUMMON_BLOOD_BEAST, 40000, 0, PHASE_COMBAT); + if (IsHeroic()) + events.ScheduleEvent(EVENT_SCENT_OF_BLOOD, 10000, 0, PHASE_COMBAT); break; case EVENT_BLOOD_NOVA: - { - // select at range only - Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, -10.0f, true); - if (!target) - target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true); // noone? select melee - if (target) - DoCast(target, SPELL_BLOOD_NOVA_TRIGGER); + DoCastAOE(SPELL_BLOOD_NOVA_TRIGGER); events.ScheduleEvent(EVENT_BLOOD_NOVA, urand(20000, 25000), 0, PHASE_COMBAT); break; - } case EVENT_RUNE_OF_BLOOD: DoCastVictim(SPELL_RUNE_OF_BLOOD); events.ScheduleEvent(EVENT_RUNE_OF_BLOOD, urand(20000, 25000), 0, PHASE_COMBAT); @@ -487,6 +481,13 @@ class boss_deathbringer_saurfang : public CreatureScript DoCast(me, SPELL_BERSERK); Talk(SAY_BERSERK); break; + case EVENT_SCENT_OF_BLOOD: + if (!summons.empty()) + { + Talk(EMOTE_SCENT_OF_BLOOD); + DoCastAOE(SPELL_SCENT_OF_BLOOD); + } + break; default: break; } @@ -1237,10 +1238,16 @@ class spell_deathbringer_blood_nova_targeting : public SpellScriptLoader unitList.push_back(target); } + void HandleForceCast(SpellEffIndex /*effIndex*/) + { + GetCaster()->CastSpell(GetHitUnit(), uint32(GetEffectValue()), TRIGGERED_FULL_MASK); + } + void Register() { OnUnitTargetSelect += SpellUnitTargetFn(spell_deathbringer_blood_nova_targeting_SpellScript::FilterTargetsInitial, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); OnUnitTargetSelect += SpellUnitTargetFn(spell_deathbringer_blood_nova_targeting_SpellScript::FilterTargetsSubsequent, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY); + OnEffectHitTarget += SpellEffectFn(spell_deathbringer_blood_nova_targeting_SpellScript::HandleForceCast, EFFECT_0, SPELL_EFFECT_FORCE_CAST); } Unit* target; @@ -1272,7 +1279,7 @@ class spell_deathbringer_boiling_blood : public SpellScriptLoader if (unitList.empty()) return; - Unit* target = SelectRandomContainerElement(unitList); + Unit* target = Trinity::Containers::SelectRandomContainerElement(unitList); unitList.clear(); unitList.push_back(target); } diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp index ea2f73e788f..e2f9faf6a97 100755 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp @@ -605,7 +605,7 @@ class boss_lady_deathwhisper : public CreatureScript return; // select random cultist - Creature* cultist = SelectRandomContainerElement(temp); + Creature* cultist = Trinity::Containers::SelectRandomContainerElement(temp); DoCast(cultist, cultist->GetEntry() == NPC_CULT_FANATIC ? SPELL_DARK_TRANSFORMATION_T : SPELL_DARK_EMPOWERMENT_T, true); Talk(uint8(cultist->GetEntry() == NPC_CULT_FANATIC ? SAY_DARK_TRANSFORMATION : SAY_DARK_EMPOWERMENT)); } diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp index 44bc40d08bd..a0fca522f61 100755 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp @@ -64,6 +64,9 @@ enum Spells SPELL_MALLEABLE_GOO = 70852, SPELL_UNSTABLE_EXPERIMENT = 70351, SPELL_TEAR_GAS = 71617, // phase transition + SPELL_TEAR_GAS_CREATURE = 71618, + SPELL_TEAR_GAS_CANCEL = 71620, + SPELL_TEAR_GAS_PERIODIC_TRIGGER = 73170, SPELL_CREATE_CONCOCTION = 71621, SPELL_GUZZLE_POTIONS = 71893, SPELL_OOZE_TANK_PROTECTION = 71770, // protects the tank @@ -86,6 +89,7 @@ enum Spells SPELL_GASEOUS_BLOAT_PROC = 70215, SPELL_GASEOUS_BLOAT = 70672, SPELL_GASEOUS_BLOAT_PROTECTION = 70812, + SPELL_EXPUNGED_GAS = 70701, // Volatile Ooze SPELL_OOZE_ERUPTION = 70492, @@ -167,6 +171,33 @@ enum PutricideData #define EXPERIMENT_STATE_OOZE false #define EXPERIMENT_STATE_GAS true +class AbominationDespawner +{ + public: + explicit AbominationDespawner(Unit* owner) : _owner(owner) { } + + bool operator()(uint64 guid) + { + if (Unit* summon = ObjectAccessor::GetUnit(*_owner, guid)) + { + if (summon->GetEntry() == NPC_MUTATED_ABOMINATION_10 || summon->GetEntry() == NPC_MUTATED_ABOMINATION_25) + { + if (Vehicle* veh = summon->GetVehicleKit()) + veh->RemoveAllPassengers(); // also despawns the vehicle + + return true; + } + + return false; + } + + return true; + } + + private: + Unit* _owner; +}; + class boss_professor_putricide : public CreatureScript { public: @@ -477,8 +508,7 @@ class boss_professor_putricide : public CreatureScript SetPhase(PHASE_COMBAT_3); events.ScheduleEvent(EVENT_MUTATED_PLAGUE, 25000); events.CancelEvent(EVENT_UNSTABLE_EXPERIMENT); - summons.DespawnEntry(NPC_MUTATED_ABOMINATION_10); - summons.DespawnEntry(NPC_MUTATED_ABOMINATION_25); + summons.remove_if(AbominationDespawner(me)); break; default: break; @@ -514,7 +544,7 @@ class boss_professor_putricide : public CreatureScript void UpdateAI(uint32 const diff) { - if ((!UpdateVictim() && !(events.GetPhaseMask() & PHASE_MASK_NOT_SELF)) || !CheckInRoom()) + if ((!(events.GetPhaseMask() & PHASE_MASK_NOT_SELF) && !UpdateVictim()) || !CheckInRoom()) return; events.Update(diff); @@ -569,13 +599,15 @@ class boss_professor_putricide : public CreatureScript break; case EVENT_TEAR_GAS: me->GetMotionMaster()->MovePoint(POINT_TABLE, tablePos); + DoCast(me, SPELL_TEAR_GAS_PERIODIC_TRIGGER, true); break; case EVENT_RESUME_ATTACK: me->SetReactState(REACT_DEFENSIVE); AttackStart(me->getVictim()); // remove Tear Gas + me->RemoveAurasDueToSpell(SPELL_TEAR_GAS_PERIODIC_TRIGGER); instance->DoRemoveAurasDueToSpellOnPlayers(71615); - instance->DoRemoveAurasDueToSpellOnPlayers(71618); + DoCastAOE(SPELL_TEAR_GAS_CANCEL); instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_GAS_VARIABLE); instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_OOZE_VARIABLE); break; @@ -673,27 +705,36 @@ class npc_volatile_ooze : public CreatureScript public: npc_volatile_ooze() : CreatureScript("npc_volatile_ooze") { } - struct npc_volatile_oozeAI : public ScriptedAI + struct npc_putricide_oozeAI : public ScriptedAI { - npc_volatile_oozeAI(Creature* creature) : ScriptedAI(creature) + npc_putricide_oozeAI(Creature* creature) : ScriptedAI(creature) { _newTargetSelectTimer = 0; } void SpellHitTarget(Unit* /*target*/, SpellInfo const* spell) { - if (!_newTargetSelectTimer && sSpellMgr->GetSpellDifficultyId(spell->Id) == sSpellMgr->GetSpellDifficultyId(SPELL_OOZE_ERUPTION)) + if (!_newTargetSelectTimer && spell->Id == sSpellMgr->GetSpellIdForDifficulty(SPELL_OOZE_ERUPTION, me)) + _newTargetSelectTimer = 1000; + } + + void SpellHit(Unit* /*caster*/, SpellInfo const* spell) + { + if (spell->Id == SPELL_TEAR_GAS_CREATURE) _newTargetSelectTimer = 1000; } void UpdateAI(uint32 const diff) { - if (!UpdateVictim()) + if (!UpdateVictim() && !_newTargetSelectTimer) return; if (!_newTargetSelectTimer) return; + if (me->HasAura(SPELL_TEAR_GAS_CREATURE)) + return; + if (_newTargetSelectTimer <= diff) { _newTargetSelectTimer = 0; @@ -704,13 +745,68 @@ class npc_volatile_ooze : public CreatureScript } private: - // no need to use EventMap for just one event uint32 _newTargetSelectTimer; }; CreatureAI* GetAI(Creature* creature) const { - return GetIcecrownCitadelAI<npc_volatile_oozeAI>(creature); + return GetIcecrownCitadelAI<npc_putricide_oozeAI>(creature); + } +}; + +class npc_gas_cloud : public CreatureScript +{ + public: + npc_gas_cloud() : CreatureScript("npc_gas_cloud") { } + + struct npc_gas_cloudAI : public ScriptedAI + { + npc_gas_cloudAI(Creature* creature) : ScriptedAI(creature) + { + _newTargetSelectTimer = 0; + } + + void SpellHitTarget(Unit* /*target*/, SpellInfo const* spell) + { + if (!_newTargetSelectTimer && spell->Id == sSpellMgr->GetSpellIdForDifficulty(SPELL_EXPUNGED_GAS, me)) + _newTargetSelectTimer = 1000; + } + + void SpellHit(Unit* /*caster*/, SpellInfo const* spell) + { + if (spell->Id == SPELL_TEAR_GAS_CREATURE) + _newTargetSelectTimer = 1000; + } + + void UpdateAI(uint32 const diff) + { + if (!UpdateVictim() && !_newTargetSelectTimer) + return; + + DoMeleeAttackIfReady(); + + if (!_newTargetSelectTimer) + return; + + if (me->HasAura(SPELL_TEAR_GAS_CREATURE)) + return; + + if (_newTargetSelectTimer <= diff) + { + _newTargetSelectTimer = 0; + me->CastCustomSpell(SPELL_GASEOUS_BLOAT, SPELLVALUE_AURA_STACK, 10, me, false); + } + else + _newTargetSelectTimer -= diff; + } + + private: + uint32 _newTargetSelectTimer; + }; + + CreatureAI* GetAI(Creature* creature) const + { + return GetIcecrownCitadelAI<npc_gas_cloudAI>(creature); } }; @@ -729,8 +825,8 @@ class spell_putricide_gaseous_bloat : public SpellScriptLoader if (Unit* caster = GetCaster()) { target->RemoveAuraFromStack(GetSpellInfo()->Id, GetCasterGUID()); - if (!target->HasAura(GetId())&& caster->GetTypeId() == TYPEID_UNIT) - caster->ToCreature()->DespawnOrUnsummon(); + if (!target->HasAura(GetId())) + caster->CastCustomSpell(SPELL_GASEOUS_BLOAT, SPELLVALUE_AURA_STACK, 10, caster, false); } } @@ -781,7 +877,7 @@ class spell_putricide_ooze_channel : public SpellScriptLoader return; } - Unit* target = SelectRandomContainerElement(targetList); + Unit* target = Trinity::Containers::SelectRandomContainerElement(targetList); targetList.clear(); targetList.push_back(target); _target = target; @@ -797,7 +893,19 @@ class spell_putricide_ooze_channel : public SpellScriptLoader void StartAttack() { GetCaster()->ClearUnitState(UNIT_STATE_CASTING); + GetCaster()->DeleteThreatList(); GetCaster()->ToCreature()->AI()->AttackStart(GetHitUnit()); + GetCaster()->AddThreat(GetHitUnit(), 500000000.0f); // value seen in sniff + } + + // temporary, until SelectTarget are not called on empty lists + void CheckTarget() + { + if (_target) + return; + + FinishCast(SPELL_FAILED_NO_VALID_TARGETS); + GetCaster()->ToCreature()->DespawnOrUnsummon(1); // despawn next update } void Register() @@ -806,6 +914,7 @@ class spell_putricide_ooze_channel : public SpellScriptLoader OnUnitTargetSelect += SpellUnitTargetFn(spell_putricide_ooze_channel_SpellScript::SetTarget, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY); OnUnitTargetSelect += SpellUnitTargetFn(spell_putricide_ooze_channel_SpellScript::SetTarget, EFFECT_2, TARGET_UNIT_SRC_AREA_ENEMY); AfterHit += SpellHitFn(spell_putricide_ooze_channel_SpellScript::StartAttack); + OnCast += SpellCastFn(spell_putricide_ooze_channel_SpellScript::CheckTarget); } Unit* _target; @@ -905,13 +1014,13 @@ class spell_putricide_unstable_experiment : public SpellScriptLoader uint32 stage = GetCaster()->ToCreature()->AI()->GetData(DATA_EXPERIMENT_STAGE); Creature* target = NULL; std::list<Creature*> creList; - GetCreatureListWithEntryInGrid(creList, GetCaster(), NPC_ABOMINATION_WING_MAD_SCIENTIST_STALKER, 100.0f); + GetCreatureListWithEntryInGrid(creList, GetCaster(), NPC_ABOMINATION_WING_MAD_SCIENTIST_STALKER, 200.0f); // 2 of them are spawned at green place - weird trick blizz for (std::list<Creature*>::iterator itr = creList.begin(); itr != creList.end(); ++itr) { target = *itr; std::list<Creature*> tmp; - GetCreatureListWithEntryInGrid(tmp, target, NPC_ABOMINATION_WING_MAD_SCIENTIST_STALKER, 1.0f); + GetCreatureListWithEntryInGrid(tmp, target, NPC_ABOMINATION_WING_MAD_SCIENTIST_STALKER, 10.0f); if ((!stage && tmp.size() > 1) || (stage && tmp.size() == 1)) break; } @@ -931,42 +1040,6 @@ class spell_putricide_unstable_experiment : public SpellScriptLoader } }; -class spell_putricide_ooze_summon : public SpellScriptLoader -{ - public: - spell_putricide_ooze_summon() : SpellScriptLoader("spell_putricide_ooze_summon") { } - - class spell_putricide_ooze_summon_AuraScript : public AuraScript - { - PrepareAuraScript(spell_putricide_ooze_summon_AuraScript); - - void HandleTriggerSpell(AuraEffect const* aurEff) - { - PreventDefaultAction(); - if (Unit* caster = GetCaster()) - { - uint32 triggerSpellId = GetSpellInfo()->Effects[aurEff->GetEffIndex()].TriggerSpell; - float x, y, z; - GetTarget()->GetPosition(x, y, z); - z = GetTarget()->GetMap()->GetHeight(GetTarget()->GetPhaseMask(), x, y, z, true, 25.0f); - x += 10.0f * cosf(caster->GetOrientation()); - y += 10.0f * sinf(caster->GetOrientation()); - caster->CastSpell(x, y, z, triggerSpellId, true, NULL, NULL, GetCasterGUID()); - } - } - - void Register() - { - OnEffectPeriodic += AuraEffectPeriodicFn(spell_putricide_ooze_summon_AuraScript::HandleTriggerSpell, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); - } - }; - - AuraScript* GetAuraScript() const - { - return new spell_putricide_ooze_summon_AuraScript(); - } -}; - class spell_putricide_ooze_eruption_searcher : public SpellScriptLoader { public: @@ -1207,11 +1280,11 @@ class spell_putricide_mutation_init : public SpellScriptLoader SpellCastResult CheckRequirementInternal(SpellCustomErrors& extendedError) { - InstanceScript* instance = GetTargetUnit()->GetInstanceScript(); + InstanceScript* instance = GetExplTargetUnit()->GetInstanceScript(); if (!instance) return SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW; - Creature* professor = ObjectAccessor::GetCreature(*GetTargetUnit(), instance->GetData64(DATA_PROFESSOR_PUTRICIDE)); + Creature* professor = ObjectAccessor::GetCreature(*GetExplTargetUnit(), instance->GetData64(DATA_PROFESSOR_PUTRICIDE)); if (!professor) return SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW; @@ -1232,17 +1305,17 @@ class spell_putricide_mutation_init : public SpellScriptLoader SpellCastResult CheckRequirement() { - if (!GetTargetUnit()) + if (!GetExplTargetUnit()) return SPELL_FAILED_BAD_TARGETS; - if (GetTargetUnit()->GetTypeId() != TYPEID_PLAYER) + if (GetExplTargetUnit()->GetTypeId() != TYPEID_PLAYER) return SPELL_FAILED_TARGET_NOT_PLAYER; SpellCustomErrors extension = SPELL_CUSTOM_ERROR_NONE; SpellCastResult result = CheckRequirementInternal(extension); if (result != SPELL_CAST_OK) { - Spell::SendCastResult(GetTargetUnit()->ToPlayer(), GetSpellInfo(), 0, result, extension); + Spell::SendCastResult(GetExplTargetUnit()->ToPlayer(), GetSpellInfo(), 0, result, extension); return result; } @@ -1429,14 +1502,15 @@ class spell_putricide_regurgitated_ooze : public SpellScriptLoader } }; -class spell_putricide_clear_mutated_plague : public SpellScriptLoader +// Removes aura with id stored in effect value +class spell_putricide_clear_aura_effect_value : public SpellScriptLoader { public: - spell_putricide_clear_mutated_plague() : SpellScriptLoader("spell_putricide_clear_mutated_plague") { } + spell_putricide_clear_aura_effect_value() : SpellScriptLoader("spell_putricide_clear_aura_effect_value") { } - class spell_putricide_clear_mutated_plague_SpellScript : public SpellScript + class spell_putricide_clear_aura_effect_value_SpellScript : public SpellScript { - PrepareSpellScript(spell_putricide_clear_mutated_plague_SpellScript); + PrepareSpellScript(spell_putricide_clear_aura_effect_value_SpellScript); void HandleScript(SpellEffIndex effIndex) { @@ -1447,13 +1521,13 @@ class spell_putricide_clear_mutated_plague : public SpellScriptLoader void Register() { - OnEffectHitTarget += SpellEffectFn(spell_putricide_clear_mutated_plague_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHitTarget += SpellEffectFn(spell_putricide_clear_aura_effect_value_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); } }; SpellScript* GetSpellScript() const { - return new spell_putricide_clear_mutated_plague_SpellScript(); + return new spell_putricide_clear_aura_effect_value_SpellScript(); } }; @@ -1492,12 +1566,12 @@ void AddSC_boss_professor_putricide() { new boss_professor_putricide(); new npc_volatile_ooze(); + new npc_gas_cloud(); new spell_putricide_gaseous_bloat(); new spell_putricide_ooze_channel(); new spell_putricide_slime_puddle(); new spell_putricide_slime_puddle_aura(); new spell_putricide_unstable_experiment(); - new spell_putricide_ooze_summon(); new spell_putricide_ooze_eruption_searcher(); new spell_putricide_choking_gas_bomb(); new spell_putricide_unbound_plague(); @@ -1508,6 +1582,6 @@ void AddSC_boss_professor_putricide() new spell_putricide_mutated_transformation(); new spell_putricide_mutated_transformation_dmg(); new spell_putricide_regurgitated_ooze(); - new spell_putricide_clear_mutated_plague(); + new spell_putricide_clear_aura_effect_value(); new spell_stinky_precious_decimate(); } diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp index 09707b2d9ab..a4ab13f6ada 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp @@ -498,7 +498,7 @@ class spell_rotface_mutated_infection : public SpellScriptLoader if (targets.empty()) return; - Unit* target = SelectRandomContainerElement(targets); + Unit* target = Trinity::Containers::SelectRandomContainerElement(targets); targets.clear(); targets.push_back(target); _target = target; @@ -716,13 +716,13 @@ class spell_rotface_unstable_ooze_explosion : public SpellScriptLoader void CheckTarget(SpellEffIndex effIndex) { PreventHitDefaultEffect(EFFECT_0); - if (!GetTargetDest()) + if (!GetExplTargetDest()) return; uint32 triggered_spell_id = GetSpellInfo()->Effects[effIndex].TriggerSpell; float x, y, z; - GetTargetDest()->GetPosition(x, y, z); + GetExplTargetDest()->GetPosition(x, y, z); // let Rotface handle the cast - caster dies before this executes if (InstanceScript* script = GetCaster()->GetInstanceScript()) if (Creature* rotface = script->instance->GetCreature(script->GetData64(DATA_ROTFACE))) diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp index c88b3aa8b37..6039ace44ab 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp @@ -61,6 +61,7 @@ enum Spells SPELL_ASPHYXIATION = 71665, SPELL_FROST_BOMB_TRIGGER = 69846, SPELL_FROST_BOMB_VISUAL = 70022, + SPELL_BIRTH_NO_VISUAL = 40031, SPELL_FROST_BOMB = 69845, SPELL_MYSTIC_BUFFET = 70128, @@ -98,6 +99,8 @@ enum Events EVENT_LAND = 12, EVENT_AIR_MOVEMENT = 21, EVENT_THIRD_PHASE_CHECK = 22, + EVENT_AIR_MOVEMENT_FAR = 23, + EVENT_LAND_GROUND = 24, // Spinestalker EVENT_BELLOWING_ROAR = 13, @@ -133,6 +136,8 @@ enum MovementPoints POINT_AIR_PHASE = 3, POINT_TAKEOFF = 4, POINT_LAND = 5, + POINT_AIR_PHASE_FAR = 6, + POINT_LAND_GROUND = 7, }; enum Shadowmourne @@ -152,6 +157,8 @@ Position const SindragosaSpawnPos = {4818.700f, 2483.710f, 287.0650f, 3.089233f Position const SindragosaFlyPos = {4475.190f, 2484.570f, 234.8510f, 3.141593f}; Position const SindragosaLandPos = {4419.190f, 2484.570f, 203.3848f, 3.141593f}; Position const SindragosaAirPos = {4475.990f, 2484.430f, 247.9340f, 3.141593f}; +Position const SindragosaAirPosFar = {4525.600f, 2485.150f, 245.0820f, 3.141593f}; +Position const SindragosaFlyInPos = {4419.190f, 2484.360f, 232.5150f, 3.141593f}; class FrostwyrmLandEvent : public BasicEvent { @@ -169,6 +176,23 @@ class FrostwyrmLandEvent : public BasicEvent Position const& _dest; }; +class FrostBombExplosion : public BasicEvent +{ + public: + FrostBombExplosion(Creature* owner, uint64 sindragosaGUID) : _owner(owner), _sindragosaGUID(sindragosaGUID) { } + + bool Execute(uint64 /*eventTime*/, uint32 /*updateTime*/) + { + _owner->CastSpell((Unit*)NULL, SPELL_FROST_BOMB, true, NULL, NULL, _sindragosaGUID); + _owner->RemoveAurasDueToSpell(SPELL_FROST_BOMB_VISUAL); + return true; + } + + private: + Creature* _owner; + uint64 _sindragosaGUID; +}; + class boss_sindragosa : public CreatureScript { public: @@ -293,20 +317,31 @@ class boss_sindragosa : public CreatureScript break; case POINT_AIR_PHASE: me->CastCustomSpell(SPELL_ICE_TOMB_TARGET, SPELLVALUE_MAX_TARGETS, RAID_MODE<int32>(2, 5, 2, 6), NULL); - events.ScheduleEvent(EVENT_FROST_BOMB, 8000); + me->SetFacingTo(float(M_PI)); + events.ScheduleEvent(EVENT_AIR_MOVEMENT_FAR, 1); + events.ScheduleEvent(EVENT_FROST_BOMB, 9000); + break; + case POINT_AIR_PHASE_FAR: + me->SetFacingTo(float(M_PI)); + events.ScheduleEvent(EVENT_LAND, 30000); break; case POINT_LAND: + events.ScheduleEvent(EVENT_LAND_GROUND, 1); + break; + case POINT_LAND_GROUND: + { me->SetCanFly(false); me->SetDisableGravity(false); me->RemoveByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_HOVER); me->SetReactState(REACT_DEFENSIVE); if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == POINT_MOTION_TYPE) me->GetMotionMaster()->MovementExpired(); - DoStartMovement(me->getVictim()); _isInAirPhase = false; // trigger Asphyxiation - summons.DoAction(NPC_ICE_TOMB, ACTION_TRIGGER_ASPHYXIATION); + EntryCheckPredicate pred(NPC_ICE_TOMB); + summons.DoAction(ACTION_TRIGGER_ASPHYXIATION, pred); break; + } default: break; } @@ -325,6 +360,12 @@ class boss_sindragosa : public CreatureScript void JustSummoned(Creature* summon) { summons.Summon(summon); + if (summon->GetEntry() == NPC_FROST_BOMB) + { + summon->CastSpell(summon, SPELL_FROST_BOMB_VISUAL, true); + summon->CastSpell(summon, SPELL_BIRTH_NO_VISUAL, true); + summon->m_Events.AddEvent(new FrostBombExplosion(summon, me->GetGUID()), summon->m_Events.CalculateTime(5500)); + } } void SummonedCreatureDespawn(Creature* summon) @@ -337,18 +378,25 @@ class boss_sindragosa : public CreatureScript void SpellHitTarget(Unit* target, SpellInfo const* spell) { if (uint32 spellId = sSpellMgr->GetSpellIdForDifficulty(70127, me)) + { if (spellId == spell->Id) + { if (Aura const* mysticBuffet = target->GetAura(spell->Id)) _mysticBuffetStack = std::max<uint8>(_mysticBuffetStack, mysticBuffet->GetStackAmount()); + return; + } + } + // Frost Infusion if (Player* player = target->ToPlayer()) { if (uint32 spellId = sSpellMgr->GetSpellIdForDifficulty(_isThirdPhase ? SPELL_FROST_BREATH_P2 : SPELL_FROST_BREATH_P1, me)) { - if (player->GetQuestStatus(QUEST_FROST_INFUSION) == QUEST_STATUS_INCOMPLETE && spellId == spell->Id) + if (spellId == spell->Id) { - if (Item* shadowsEdge = player->GetWeaponForAttack(BASE_ATTACK, true)) + Item* shadowsEdge = player->GetWeaponForAttack(BASE_ATTACK, true); + if (player->GetQuestStatus(QUEST_FROST_INFUSION) == QUEST_STATUS_INCOMPLETE && shadowsEdge) { if (!player->HasAura(SPELL_FROST_IMBUED_BLADE) && shadowsEdge->GetEntry() == ITEM_SHADOW_S_EDGE) { @@ -366,15 +414,11 @@ class boss_sindragosa : public CreatureScript player->CastSpell(player, SPELL_FROST_INFUSION, true); } } + + return; } } } - - if (spell->Id == SPELL_FROST_BOMB_TRIGGER) - { - target->CastSpell(target, SPELL_FROST_BOMB, true); - target->RemoveAurasDueToSpell(SPELL_FROST_BOMB_VISUAL); - } } void UpdateAI(uint32 const diff) @@ -415,7 +459,6 @@ class boss_sindragosa : public CreatureScript break; case EVENT_ICY_GRIP: DoCast(me, SPELL_ICY_GRIP); - events.ScheduleEvent(EVENT_ICY_GRIP, urand(70000, 75000), EVENT_GROUP_LAND_PHASE); events.ScheduleEvent(EVENT_BLISTERING_COLD, 1000, EVENT_GROUP_LAND_PHASE); break; case EVENT_BLISTERING_COLD: @@ -434,19 +477,21 @@ class boss_sindragosa : public CreatureScript me->SetDisableGravity(true); me->SetByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_HOVER); me->SetReactState(REACT_PASSIVE); + me->AttackStop(); Position pos; pos.Relocate(me); pos.m_positionZ += 17.0f; me->GetMotionMaster()->MoveTakeoff(POINT_TAKEOFF, pos, 8.30078125f); - events.DelayEvents(45000, EVENT_GROUP_LAND_PHASE); + events.CancelEventGroup(EVENT_GROUP_LAND_PHASE); events.ScheduleEvent(EVENT_AIR_PHASE, 110000); - events.RescheduleEvent(EVENT_UNCHAINED_MAGIC, urand(55000, 60000), EVENT_GROUP_LAND_PHASE); - events.ScheduleEvent(EVENT_LAND, 45000); break; } case EVENT_AIR_MOVEMENT: me->GetMotionMaster()->MovePoint(POINT_AIR_PHASE, SindragosaAirPos); break; + case EVENT_AIR_MOVEMENT_FAR: + me->GetMotionMaster()->MovePoint(POINT_AIR_PHASE_FAR, SindragosaAirPosFar); + break; case EVENT_ICE_TOMB: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true, -SPELL_ICE_TOMB_UNTARGETABLE)) { @@ -458,30 +503,28 @@ class boss_sindragosa : public CreatureScript case EVENT_FROST_BOMB: { float destX, destY, destZ; - destX = float(rand_norm()) * 117.25f + 4339.25f; - if (destX > 4371.5f && destX < 4432.0f) - destY = float(rand_norm()) * 111.0f + 2429.0f; - else - destY = float(rand_norm()) * 31.23f + 2454.64f; + destX = float(rand_norm()) * 75.0f + 4350.0f; + destY = float(rand_norm()) * 75.0f + 2450.0f; destZ = 205.0f; // random number close to ground, get exact in next call me->UpdateGroundPositionZ(destX, destY, destZ); - Position pos; - pos.Relocate(destX, destY, destZ, 0.0f); - if (TempSummon* summ = me->SummonCreature(NPC_FROST_BOMB, pos, TEMPSUMMON_TIMED_DESPAWN, 40000)) - { - summ->CastSpell(summ, SPELL_FROST_BOMB_VISUAL, true); - DoCast(summ, SPELL_FROST_BOMB_TRIGGER); - //me->CastSpell(destX, destY, destZ, SPELL_FROST_BOMB_TRIGGER, false); - } - events.ScheduleEvent(EVENT_FROST_BOMB, urand(5000, 10000)); + me->CastSpell(destX, destY, destZ, SPELL_FROST_BOMB_TRIGGER, false); + events.ScheduleEvent(EVENT_FROST_BOMB, urand(6000, 8000)); break; } case EVENT_LAND: { events.CancelEvent(EVENT_FROST_BOMB); - me->GetMotionMaster()->MovePoint(POINT_LAND, SindragosaLandPos); + me->GetMotionMaster()->MovePoint(POINT_LAND, SindragosaFlyInPos); break; } + case EVENT_LAND_GROUND: + events.ScheduleEvent(EVENT_CLEAVE, urand(13000, 15000), EVENT_GROUP_LAND_PHASE); + events.ScheduleEvent(EVENT_TAIL_SMASH, urand(19000, 23000), EVENT_GROUP_LAND_PHASE); + events.ScheduleEvent(EVENT_FROST_BREATH, urand(10000, 15000), EVENT_GROUP_LAND_PHASE); + events.ScheduleEvent(EVENT_UNCHAINED_MAGIC, urand(12000, 17000), EVENT_GROUP_LAND_PHASE); + events.ScheduleEvent(EVENT_ICY_GRIP, urand(35000, 40000), EVENT_GROUP_LAND_PHASE); + me->GetMotionMaster()->MoveLand(POINT_LAND_GROUND, SindragosaLandPos, 0.0f); + break; case EVENT_THIRD_PHASE_CHECK: { if (!_isInAirPhase) @@ -670,6 +713,7 @@ class npc_spinestalker : public CreatureScript me->SetDisableGravity(false); me->RemoveByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_HOVER); me->SetHomePosition(SpinestalkerLandPos); + me->SetFacingTo(SpinestalkerLandPos.GetOrientation()); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); } @@ -796,6 +840,7 @@ class npc_rimefang : public CreatureScript me->SetDisableGravity(false); me->RemoveByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_HOVER); me->SetHomePosition(RimefangLandPos); + me->SetFacingTo(RimefangLandPos.GetOrientation()); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); } @@ -1054,10 +1099,10 @@ class spell_sindragosa_unchained_magic : public SpellScriptLoader void FilterTargets(std::list<Unit*>& unitList) { - unitList.remove_if (UnchainedMagicTargetSelector()); - uint32 maxSize = uint32(GetCaster()->GetMap()->GetSpawnMode() & 1 ? 5 : 2); + unitList.remove_if(UnchainedMagicTargetSelector()); + uint32 maxSize = uint32(GetCaster()->GetMap()->GetSpawnMode() & 1 ? 6 : 2); if (unitList.size() > maxSize) - Trinity::RandomResizeList(unitList, maxSize); + Trinity::Containers::RandomResizeList(unitList, maxSize); } void Register() @@ -1240,6 +1285,46 @@ class spell_sindragosa_icy_grip : public SpellScriptLoader } }; +class MysticBuffetTargetFilter +{ + public: + explicit MysticBuffetTargetFilter(Unit* caster) : _caster(caster) { } + + bool operator()(Unit* unit) + { + return !unit->IsWithinLOSInMap(_caster); + } + + private: + Unit* _caster; +}; + +class spell_sindragosa_mystic_buffet : public SpellScriptLoader +{ + public: + spell_sindragosa_mystic_buffet() : SpellScriptLoader("spell_sindragosa_mystic_buffet") { } + + class spell_sindragosa_mystic_buffet_SpellScript : public SpellScript + { + PrepareSpellScript(spell_sindragosa_mystic_buffet_SpellScript); + + void FilterTargets(std::list<Unit*>& unitList) + { + unitList.remove_if(MysticBuffetTargetFilter(GetCaster())); + } + + void Register() + { + OnUnitTargetSelect += SpellUnitTargetFn(spell_sindragosa_mystic_buffet_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_sindragosa_mystic_buffet_SpellScript(); + } +}; + class spell_rimefang_icy_blast : public SpellScriptLoader { public: @@ -1259,7 +1344,7 @@ class spell_rimefang_icy_blast : public SpellScriptLoader void HandleTriggerMissile(SpellEffIndex effIndex) { PreventHitDefaultEffect(effIndex); - if (Position const* pos = GetTargetDest()) + if (Position const* pos = GetExplTargetDest()) if (TempSummon* summon = GetCaster()->SummonCreature(NPC_ICY_BLAST, *pos, TEMPSUMMON_TIMED_DESPAWN, 40000)) summon->CastSpell(summon, SPELL_ICY_BLAST_AREA, true); } @@ -1321,7 +1406,7 @@ class spell_frostwarden_handler_order_whelp : public SpellScriptLoader if (unitList.empty()) return; - Unit* target = SelectRandomContainerElement(unitList); + Unit* target = Trinity::Containers::SelectRandomContainerElement(unitList); unitList.clear(); unitList.push_back(target); } @@ -1338,7 +1423,7 @@ class spell_frostwarden_handler_order_whelp : public SpellScriptLoader if (unitList.empty()) return; - SelectRandomContainerElement(unitList)->CastSpell(GetHitUnit(), uint32(GetEffectValue()), true); + Trinity::Containers::SelectRandomContainerElement(unitList)->CastSpell(GetHitUnit(), uint32(GetEffectValue()), true); } void Register() @@ -1465,6 +1550,7 @@ void AddSC_boss_sindragosa() new spell_sindragosa_frost_beacon(); new spell_sindragosa_ice_tomb(); new spell_sindragosa_icy_grip(); + new spell_sindragosa_mystic_buffet(); new spell_rimefang_icy_blast(); new spell_frostwarden_handler_order_whelp(); new spell_frostwarden_handler_focus_fire(); diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp index 90ee6e1af71..4dab215d1da 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp @@ -554,7 +554,8 @@ class boss_the_lich_king : public CreatureScript if (Creature* tirion = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_HIGHLORD_TIRION_FORDRING))) tirion->AI()->EnterEvadeMode(); DoCastAOE(SPELL_KILL_FROSTMOURNE_PLAYERS); - summons.DoAction(NPC_STRANGULATE_VEHICLE, ACTION_TELEPORT_BACK); + EntryCheckPredicate pred(NPC_STRANGULATE_VEHICLE); + summons.DoAction(ACTION_TELEPORT_BACK, pred); } void KilledUnit(Unit* victim) @@ -595,12 +596,15 @@ class boss_the_lich_king : public CreatureScript events.ScheduleEvent(EVENT_OUTRO_TALK_8, 17000, 0, PHASE_OUTRO); break; case ACTION_TELEPORT_BACK: - summons.DoAction(NPC_STRANGULATE_VEHICLE, ACTION_TELEPORT_BACK); + { + EntryCheckPredicate pred(NPC_STRANGULATE_VEHICLE); + summons.DoAction(ACTION_TELEPORT_BACK, pred); if (!IsHeroic()) Talk(SAY_LK_FROSTMOURNE_ESCAPE); else DoCastAOE(SPELL_TRIGGER_VILE_SPIRIT_HEROIC); break; + } default: break; } @@ -2466,7 +2470,7 @@ class spell_the_lich_king_summon_into_air : public SpellScriptLoader void ModDestHeight(SpellEffIndex effIndex) { static Position const offset = {0.0f, 0.0f, 15.0f, 0.0f}; - WorldLocation* dest = const_cast<WorldLocation*>(GetTargetDest()); + WorldLocation* dest = const_cast<WorldLocation*>(GetExplTargetDest()); dest->RelocateOffset(offset); // spirit bombs get higher if (GetSpellInfo()->Effects[effIndex].MiscValue == NPC_SPIRIT_BOMB) @@ -2550,7 +2554,7 @@ class spell_the_lich_king_valkyr_target_search : public SpellScriptLoader if (unitList.empty()) return; - _target = SelectRandomContainerElement(unitList); + _target = Trinity::Containers::SelectRandomContainerElement(unitList); unitList.clear(); unitList.push_back(_target); GetCaster()->GetAI()->SetGUID(_target->GetGUID()); @@ -2723,7 +2727,7 @@ class spell_the_lich_king_vile_spirits_visual : public SpellScriptLoader void ModDestHeight(SpellEffIndex /*effIndex*/) { Position offset = {0.0f, 0.0f, 15.0f, 0.0f}; - const_cast<WorldLocation*>(GetTargetDest())->RelocateOffset(offset); + const_cast<WorldLocation*>(GetExplTargetDest())->RelocateOffset(offset); } void Register() @@ -2758,7 +2762,7 @@ class spell_the_lich_king_vile_spirit_move_target_search : public SpellScriptLoa if (targets.empty()) return; - _target = SelectRandomContainerElement(targets); + _target = Trinity::Containers::SelectRandomContainerElement(targets); } void HandleScript(SpellEffIndex effIndex) diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp index af2eb57b7c3..c40a521c794 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp @@ -262,7 +262,7 @@ class ValithriaDespawner : public BasicEvent if (CreatureData const* data = creature->GetCreatureData()) creature->SetPosition(data->posX, data->posY, data->posZ, data->orientation); - creature->ForcedDespawn(); + creature->DespawnOrUnsummon(); creature->SetCorpseDelay(corpseDelay); creature->SetRespawnDelay(respawnDelay); @@ -1087,7 +1087,7 @@ class npc_dream_cloud : public CreatureScript me->GetMotionMaster()->MoveIdle(); // must use originalCaster the same for all clouds to allow stacking me->CastSpell(me, EMERALD_VIGOR, false, NULL, NULL, _instance->GetData64(DATA_VALITHRIA_DREAMWALKER)); - me->ForcedDespawn(100); + me->DespawnOrUnsummon(100); break; default: break; @@ -1196,7 +1196,7 @@ class spell_dreamwalker_summoner : public SpellScriptLoader if (targets.empty()) return; - Unit* target = SelectRandomContainerElement(targets); + Unit* target = Trinity::Containers::SelectRandomContainerElement(targets); targets.clear(); targets.push_back(target); } @@ -1242,7 +1242,7 @@ class spell_dreamwalker_summon_suppresser : public SpellScriptLoader std::list<Creature*> summoners; GetCreatureListWithEntryInGrid(summoners, caster, NPC_WORLD_TRIGGER, 100.0f); summoners.remove_if (Trinity::UnitAuraCheck(true, SPELL_RECENTLY_SPAWNED)); - Trinity::RandomResizeList(summoners, 2); + Trinity::Containers::RandomResizeList(summoners, 2); if (summoners.empty()) return; diff --git a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp index 5720ce0e423..fab9a5f0740 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp @@ -346,7 +346,7 @@ class FrostwingGauntletRespawner if (CreatureData const* data = creature->GetCreatureData()) creature->SetPosition(data->posX, data->posY, data->posZ, data->orientation); - creature->ForcedDespawn(); + creature->DespawnOrUnsummon(); creature->SetCorpseDelay(corpseDelay); creature->SetRespawnDelay(respawnDelay); @@ -796,7 +796,8 @@ class boss_sister_svalna : public CreatureScript { _JustReachedHome(); me->SetReactState(REACT_PASSIVE); - me->SetCanFly(false); + me->SetDisableGravity(false); + me->SetHover(false); } void DoAction(int32 const action) @@ -838,13 +839,14 @@ class boss_sister_svalna : public CreatureScript void MovementInform(uint32 type, uint32 id) { - if (type != POINT_MOTION_TYPE || id != POINT_LAND) + if (type != EFFECT_MOTION_TYPE || id != POINT_LAND) return; _isEventInProgress = false; me->setActive(false); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC); - me->SetCanFly(false); + me->SetDisableGravity(false); + me->SetHover(false); } void SpellHitTarget(Unit* target, SpellInfo const* spell) @@ -1288,7 +1290,7 @@ struct npc_argent_captainAI : public ScriptedAI if (spell->Id == SPELL_REVIVE_CHAMPION && !IsUndead) { IsUndead = true; - me->setDeathState(JUST_ALIVED); + me->setDeathState(JUST_RESPAWNED); uint32 newEntry = 0; switch (me->GetEntry()) { @@ -1368,7 +1370,7 @@ class npc_captain_arnath : public CreatureScript case EVENT_ARNATH_PW_SHIELD: { std::list<Creature*> targets = DoFindFriendlyMissingBuff(40.0f, SPELL_POWER_WORD_SHIELD); - DoCast(SelectRandomContainerElement(targets), SPELL_POWER_WORD_SHIELD); + DoCast(Trinity::Containers::SelectRandomContainerElement(targets), SPELL_POWER_WORD_SHIELD); Events.ScheduleEvent(EVENT_ARNATH_PW_SHIELD, urand(15000, 20000)); break; } @@ -1822,7 +1824,7 @@ class spell_frost_giant_death_plague : public SpellScriptLoader unitList.remove_if (DeathPlagueTargetSelector(GetCaster())); if (!unitList.empty()) { - Unit* target = SelectRandomContainerElement(unitList); + Unit* target = Trinity::Containers::SelectRandomContainerElement(unitList); unitList.clear(); unitList.push_back(target); } @@ -1909,7 +1911,7 @@ class spell_svalna_revive_champion : public SpellScriptLoader void RemoveAliveTarget(std::list<Unit*>& unitList) { unitList.remove_if(AliveCheck()); - Trinity::RandomResizeList(unitList, 2); + Trinity::Containers::RandomResizeList(unitList, 2); } void Land(SpellEffIndex /*effIndex*/) @@ -1921,10 +1923,10 @@ class spell_svalna_revive_champion : public SpellScriptLoader Position pos; caster->GetPosition(&pos); caster->GetNearPosition(pos, 5.0f, 0.0f); - pos.m_positionZ = caster->GetBaseMap()->GetHeight(caster->GetPhaseMask(), pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), true, 20.0f); - pos.m_positionZ += 0.05f; + //pos.m_positionZ = caster->GetBaseMap()->GetHeight(caster->GetPhaseMask(), pos.GetPositionX(), pos.GetPositionY(), caster->GetPositionZ(), true, 50.0f); + //pos.m_positionZ += 0.05f; caster->SetHomePosition(pos); - caster->GetMotionMaster()->MovePoint(POINT_LAND, pos); + caster->GetMotionMaster()->MoveLand(POINT_LAND, pos, caster->GetSpeed(MOVE_FLIGHT)); } void Register() diff --git a/src/server/scripts/Northrend/Naxxramas/boss_four_horsemen.cpp b/src/server/scripts/Northrend/Naxxramas/boss_four_horsemen.cpp index d2f36efc06a..17ed6a79c76 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_four_horsemen.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_four_horsemen.cpp @@ -136,10 +136,10 @@ public: if (!instance) return false; - Creature* Thane = CAST_CRE(Unit::GetUnit(*me, instance->GetData64(DATA_THANE))); - Creature* Lady = CAST_CRE(Unit::GetUnit(*me, instance->GetData64(DATA_LADY))); - Creature* Baron = CAST_CRE(Unit::GetUnit(*me, instance->GetData64(DATA_BARON))); - Creature* Sir = CAST_CRE(Unit::GetUnit(*me, instance->GetData64(DATA_SIR))); + Creature* Thane = Unit::GetCreature(*me, instance->GetData64(DATA_THANE)); + Creature* Lady = Unit::GetCreature(*me, instance->GetData64(DATA_LADY)); + Creature* Baron = Unit::GetCreature(*me, instance->GetData64(DATA_BARON)); + Creature* Sir = Unit::GetCreature(*me, instance->GetData64(DATA_SIR)); if (Thane && Lady && Baron && Sir) { diff --git a/src/server/scripts/Northrend/Naxxramas/boss_gothik.cpp b/src/server/scripts/Northrend/Naxxramas/boss_gothik.cpp index 132ecdafa5a..8d23de5427c 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_gothik.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_gothik.cpp @@ -424,7 +424,8 @@ class boss_gothik : public CreatureScript { if (instance) instance->SetData(DATA_GOTHIK_GATE, GO_STATE_ACTIVE); - summons.DoAction(0, 0); + DummyEntryCheckPredicate pred; + summons.DoAction(0, pred); //! Magic numbers fail summons.DoZoneInCombat(); mergedSides = true; } @@ -447,7 +448,8 @@ class boss_gothik : public CreatureScript DoScriptText(SAY_TELEPORT, me); DoTeleportTo(PosGroundLiveSide); me->SetReactState(REACT_AGGRESSIVE); - summons.DoAction(0, 0); + DummyEntryCheckPredicate pred; + summons.DoAction(0, pred); //! Magic numbers fail summons.DoZoneInCombat(); events.ScheduleEvent(EVENT_BOLT, 1000); events.ScheduleEvent(EVENT_HARVEST, urand(3000, 15000)); diff --git a/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp b/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp index 98cbb95f10d..4d6bfc578ff 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp @@ -667,7 +667,7 @@ public: if (!instance || instance->IsEncounterInProgress() || instance->GetBossState(BOSS_KELTHUZAD) == DONE) return false; - Creature* pKelthuzad = CAST_CRE(Unit::GetUnit(*player, instance->GetData64(DATA_KELTHUZAD))); + Creature* pKelthuzad = Unit::GetCreature(*player, instance->GetData64(DATA_KELTHUZAD)); if (!pKelthuzad) return false; @@ -714,7 +714,6 @@ public: return true; } - }; class npc_kelthuzad_abomination : public CreatureScript @@ -726,16 +725,13 @@ class npc_kelthuzad_abomination : public CreatureScript { npc_kelthuzad_abominationAI(Creature* creature) : ScriptedAI(creature) { - instance = me->GetInstanceScript(); + _instance = creature->GetInstanceScript(); } - InstanceScript* instance; - EventMap events; - void Reset() { - events.Reset(); - events.ScheduleEvent(EVENT_MORTAL_WOUND, urand(2000, 5000)); + _events.Reset(); + _events.ScheduleEvent(EVENT_MORTAL_WOUND, urand(2000, 5000)); DoCast(me, SPELL_FRENZY, true); } @@ -744,15 +740,15 @@ class npc_kelthuzad_abomination : public CreatureScript if (!UpdateVictim()) return; - events.Update(diff); + _events.Update(diff); - while (uint32 eventId = events.ExecuteEvent()) + while (uint32 eventId = _events.ExecuteEvent()) { switch (eventId) { case EVENT_MORTAL_WOUND: DoCastVictim(SPELL_MORTAL_WOUND, true); - events.ScheduleEvent(EVENT_MORTAL_WOUND, urand(10000, 15000)); + _events.ScheduleEvent(EVENT_MORTAL_WOUND, urand(10000, 15000)); break; default: break; @@ -762,9 +758,13 @@ class npc_kelthuzad_abomination : public CreatureScript void JustDied(Unit* /*killer*/) { - if (instance) - instance->SetData(DATA_ABOMINATION_KILLED, instance->GetData(DATA_ABOMINATION_KILLED) + 1); + if (_instance) + _instance->SetData(DATA_ABOMINATION_KILLED, _instance->GetData(DATA_ABOMINATION_KILLED) + 1); } + + private: + InstanceScript* _instance; + EventMap _events; }; CreatureAI* GetAI(Creature* creature) const @@ -776,9 +776,7 @@ class npc_kelthuzad_abomination : public CreatureScript class achievement_just_cant_get_enough : public AchievementCriteriaScript { public: - achievement_just_cant_get_enough() : AchievementCriteriaScript("achievement_just_cant_get_enough") - { - } + achievement_just_cant_get_enough() : AchievementCriteriaScript("achievement_just_cant_get_enough") { } bool OnCheck(Player* /*player*/, Unit* target) { diff --git a/src/server/scripts/Northrend/Nexus/Nexus/boss_ormorok.cpp b/src/server/scripts/Northrend/Nexus/Nexus/boss_ormorok.cpp index 577bc3cc822..c70db7d4ebc 100644 --- a/src/server/scripts/Northrend/Nexus/Nexus/boss_ormorok.cpp +++ b/src/server/scripts/Northrend/Nexus/Nexus/boss_ormorok.cpp @@ -195,7 +195,7 @@ public: std::list<HostileReference*>::const_iterator i = me->getThreatManager().getThreatList().begin(); for (; i != me->getThreatManager().getThreatList().end(); ++i) { - Unit* temp = Unit::GetUnit((*me), (*i)->getUnitGuid()); + Unit* temp = Unit::GetUnit(*me, (*i)->getUnitGuid()); if (temp && temp->GetTypeId() == TYPEID_PLAYER && temp->getClass() == Healer) { target = temp; diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon.cpp deleted file mode 100644 index 2dd13e7ce07..00000000000 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon.cpp +++ /dev/null @@ -1,376 +0,0 @@ -/* - * Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ulduar.h" - -#define GAMEOBJECT_GIVE_OF_THE_OBSERVER 194821 - -enum Spells -{ - SPELL_ASCEND = 64487, - SPELL_BERSERK = 47008, - SPELL_BIG_BANG = 64443, - H_SPELL_BIG_BANG = 64584, - SPELL_COSMIC_SMASH = 62301, - H_SPELL_COSMIC_SMASH = 64598, - SPELL_PHASE_PUNCH = 64412, - SPELL_QUANTUM_STRIKE = 64395, - H_SPELL_QUANTUM_STRIKE = 64592, - SPELL_BLACK_HOLE_EXPLOSION = 64122, - SPELL_ARCANE_BARAGE = 64599, - H_SPELL_ARCANE_BARAGE = 64607 -}; - -enum Creatures -{ - CREATURE_COLLAPSING_STAR = 32955, - CREATURE_BLACK_HOLE = 32953, - CREATURE_LIVING_CONSTELLATION = 33052, - CREATURE_DARK_MATTER = 33089 -}; - -enum Yells -{ - SAY_AGGRO = -1603000, - SAY_SLAY_1 = -1603001, - SAY_SLAY_2 = -1603002, - SAY_ENGADED_FOR_FIRTS_TIME = -1603003, - SAY_PHASE_2 = -1603004, - SAY_SUMMON_COLLAPSING_STAR = -1603005, - SAY_DEATH_1 = -1603006, - SAY_DEATH_2 = -1603007, - SAY_DEATH_3 = -1603008, - SAY_DEATH_4 = -1603009, - SAY_DEATH_5 = -1603010, - SAY_BERSERK = -1603011, - SAY_BIG_BANG_1 = -1603012, - SAY_BIG_BANG_2 = -1603013, - SAY_TIMER_1 = -1603014, - SAY_TIMER_2 = -1603015, - SAY_TIMER_3 = -1603016, - SAY_SUMMON_1 = -1603017, - SAY_SUMMON_2 = -1603018, - SAY_SUMMON_3 = -1603019, -}; - -class boss_algalon : public CreatureScript -{ -public: - boss_algalon() : CreatureScript("boss_algalon") { } - - CreatureAI* GetAI(Creature* creature) const - { - return GetUlduarAI<boss_algalonAI>(creature); - } - - struct boss_algalonAI : public ScriptedAI - { - boss_algalonAI(Creature* creature) : ScriptedAI(creature) - { - instance = creature->GetInstanceScript(); - Summon = false; // not in reset. intro speech done only once. - } - - InstanceScript* instance; - - std::list<uint64> m_lCollapsingStarGUIDList; - - uint32 Phase; - uint32 Ascend_Timer; - uint32 Berserk_Timer; - uint32 BigBang_Timer; - uint32 CosmicSmash_Timer; - uint32 PhasePunch_Timer; - uint32 QuantumStrike_Timer; - uint32 CollapsingStar_Timer; - uint32 uiPhase_timer; - uint32 uiStep; - - uint64 BlackHoleGUID; - - bool Enrage; - bool Summon; - - void EnterCombat(Unit* who) - { - if (Summon) - { - DoScriptText(SAY_AGGRO, me); - me->InterruptSpell(CURRENT_CHANNELED_SPELL); - DoZoneInCombat(who->ToCreature()); - } - else - { - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - me->SetReactState(REACT_PASSIVE); - uiStep = 1; - } - - if (instance) - instance->SetData(BOSS_ALGALON, IN_PROGRESS); - } - - void KilledUnit(Unit* /*victim*/) - { - DoScriptText(RAND(SAY_SLAY_1, SAY_SLAY_2), me); - } - - void Reset() - { - Phase = 1; - - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - if (instance) - instance->SetData(BOSS_ALGALON, NOT_STARTED); - - BlackHoleGUID = 0; - - uiPhase_timer = 0; - Ascend_Timer = 480000; //8 minutes - QuantumStrike_Timer = urand(4000, 14000); - Berserk_Timer = 360000; //6 minutes - CollapsingStar_Timer = urand(15000, 20000); //Spawns between 15 to 20 seconds - BigBang_Timer = 90000; - PhasePunch_Timer = 8000; - CosmicSmash_Timer = urand(30000, 60000); - Enrage = false; - } - - void JumpToNextStep(uint32 uiTimer) - { - uiPhase_timer = uiTimer; - ++uiStep; - } - - void DespawnCollapsingStar() - { - if (m_lCollapsingStarGUIDList.empty()) - return; - - for (std::list<uint64>::const_iterator itr = m_lCollapsingStarGUIDList.begin(); itr != m_lCollapsingStarGUIDList.end(); ++itr) - { - if (Creature* temp = Unit::GetCreature(*me, *itr)) - { - if (temp->isAlive()) - temp->DespawnOrUnsummon(); - } - } - m_lCollapsingStarGUIDList.clear(); - } - - void JustSummoned(Creature* summoned) - { - if (summoned->GetEntry() == CREATURE_COLLAPSING_STAR) - { - Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0); - if (me->getVictim()) - summoned->AI()->AttackStart(target ? target : me->getVictim()); - m_lCollapsingStarGUIDList.push_back(summoned->GetGUID()); - } - } - - void SummonCollapsingStar(Unit* target) - { - DoScriptText(SAY_SUMMON_COLLAPSING_STAR, me); - me->SummonCreature(CREATURE_COLLAPSING_STAR, target->GetPositionX()+15.0f, target->GetPositionY()+15.0f, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 100000); - me->SummonCreature(CREATURE_BLACK_HOLE, target->GetPositionX()+15.0f, target->GetPositionY()+15.0f, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 27000); - } - - void UpdateAI(const uint32 diff) - { - //Return since we have no target - if (!UpdateVictim()) - return; - - if (Phase == 1 && HealthBelowPct(20)) - { - Phase = 2; - DoScriptText(SAY_PHASE_2, me); - } - - if (HealthBelowPct(2)) - { - me->SummonGameObject(GAMEOBJECT_GIVE_OF_THE_OBSERVER, 1634.258667f, -295.101166f, 417.321381f, 0, 0, 0, 0, 0, 0); - - // All of them. or random? - DoScriptText(SAY_DEATH_1, me); - DoScriptText(SAY_DEATH_2, me); - DoScriptText(SAY_DEATH_3, me); - DoScriptText(SAY_DEATH_4, me); - DoScriptText(SAY_DEATH_5, me); - - me->DisappearAndDie(); - - if (instance) - instance->SetData(BOSS_ALGALON, DONE); - - return; - } - - if (Phase == 1) - { - if (!Summon) - { - if (uiPhase_timer <= diff) - { - switch (uiStep) - { - case 1: - DoScriptText(SAY_SUMMON_1, me); - JumpToNextStep(3000); - break; - case 2: - DoScriptText(SAY_SUMMON_2, me); - JumpToNextStep(3000); - break; - case 3: - DoScriptText(SAY_SUMMON_3, me); - JumpToNextStep(3000); - break; - case 4: - DoScriptText(SAY_ENGADED_FOR_FIRTS_TIME, me); - JumpToNextStep(3000); - break; - case 5: - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - me->SetReactState(REACT_AGGRESSIVE); - Summon = true; - break; - } - } else uiPhase_timer -= diff; - - return; - } - - if (QuantumStrike_Timer <= diff) - { - DoCast(me->getVictim(), RAID_MODE(SPELL_QUANTUM_STRIKE, H_SPELL_QUANTUM_STRIKE), true); - - QuantumStrike_Timer = urand(4000, 14000); - } else QuantumStrike_Timer -= diff; - - if (BigBang_Timer <= diff) - { - DoScriptText(RAND(SAY_BIG_BANG_1, SAY_BIG_BANG_2), me); - DoCast(me->getVictim(), RAID_MODE(SPELL_BIG_BANG, H_SPELL_BIG_BANG), true); - - BigBang_Timer = 90000; - } else BigBang_Timer -= diff; - - if (Ascend_Timer <= diff) - { - DoCast(me->getVictim(), SPELL_ASCEND, true); - - Ascend_Timer = 480000; - } else Ascend_Timer -= diff; - - if (PhasePunch_Timer <= diff) - { - DoCast(me->getVictim(), SPELL_PHASE_PUNCH, true); - - PhasePunch_Timer = 8000; - } else PhasePunch_Timer -= diff; - - if (CosmicSmash_Timer <= diff) - { - DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0), RAID_MODE(SPELL_COSMIC_SMASH, H_SPELL_COSMIC_SMASH), true); - - CosmicSmash_Timer = urand(30000, 60000); - } else CosmicSmash_Timer -= diff; - - if (Berserk_Timer <= diff) - { - DoScriptText(SAY_BERSERK, me); - DoCast(me->getVictim(), SPELL_BERSERK, true); - - Berserk_Timer = 360000; - } else Berserk_Timer -= diff; - - DoMeleeAttackIfReady(); - - EnterEvadeIfOutOfCombatArea(diff); - } - - if (Phase == 2) - { - if (Enrage) - { - if (Ascend_Timer <= diff) - { - DoCast(me, SPELL_ASCEND); - DoScriptText(SAY_BERSERK, me); - Ascend_Timer = urand(360000, 365000); - Enrage = false; - } else Ascend_Timer -= diff; - } - } - - DoMeleeAttackIfReady(); - } - }; - -}; - -//Collapsing Star -class mob_collapsing_star : public CreatureScript -{ -public: - mob_collapsing_star() : CreatureScript("mob_collapsing_star") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new mob_collapsing_starAI(creature); - } - - struct mob_collapsing_starAI : public ScriptedAI - { - mob_collapsing_starAI(Creature* creature) : ScriptedAI(creature) - { - instance = creature->GetInstanceScript(); - } - - InstanceScript* instance; - - uint32 BlackHoleExplosion_Timer; - - void Reset() - { - BlackHoleExplosion_Timer = 0; - } - - void UpdateAI(const uint32 diff) - { - if (!UpdateVictim()) - return; - - if (BlackHoleExplosion_Timer <= diff) - { - me->CastSpell(me, SPELL_BLACK_HOLE_EXPLOSION, false); - BlackHoleExplosion_Timer = 0; - } else BlackHoleExplosion_Timer -= diff; - } - }; - -}; - -void AddSC_boss_Algalon() -{ - new boss_algalon(); - new mob_collapsing_star(); -} diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp new file mode 100644 index 00000000000..2af73389ecb --- /dev/null +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp @@ -0,0 +1,1374 @@ +/* + * Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "ObjectMgr.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "SpellScript.h" +#include "PassiveAI.h" +#include "GameObjectAI.h" +#include "MapManager.h" +#include "MoveSplineInit.h" +#include "ulduar.h" + +enum Texts +{ + SAY_BRANN_ALGALON_INTRO_1 = 0, + SAY_BRANN_ALGALON_INTRO_2 = 1, + SAY_BRANN_ALGALON_OUTRO = 2, + + SAY_ALGALON_INTRO_1 = 0, + SAY_ALGALON_INTRO_2 = 1, + SAY_ALGALON_INTRO_3 = 2, + SAY_ALGALON_START_TIMER = 3, + SAY_ALGALON_AGGRO = 4, + SAY_ALGALON_COLLAPSING_STAR = 5, + EMOTE_ALGALON_COLLAPSING_STAR = 6, + SAY_ALGALON_BIG_BANG = 7, + EMOTE_ALGALON_BIG_BANG = 8, + SAY_ALGALON_ASCEND = 9, + EMOTE_ALGALON_COSMIC_SMASH = 10, + SAY_ALGALON_PHASE_TWO = 11, + SAY_ALGALON_OUTRO_1 = 12, + SAY_ALGALON_OUTRO_2 = 13, + SAY_ALGALON_OUTRO_3 = 14, + SAY_ALGALON_OUTRO_4 = 15, + SAY_ALGALON_OUTRO_5 = 16, + SAY_ALGALON_DESPAWN_1 = 17, + SAY_ALGALON_DESPAWN_2 = 18, + SAY_ALGALON_DESPAWN_3 = 19, + SAY_ALGALON_KILL = 20, +}; + +enum Spells +{ + // Algalon the Observer + SPELL_ARRIVAL = 64997, + SPELL_RIDE_THE_LIGHTNING = 64986, + SPELL_SUMMON_AZEROTH = 64994, + SPELL_REORIGINATION = 64996, + SPELL_SUPERMASSIVE_FAIL = 65311, + SPELL_QUANTUM_STRIKE = 64395, + SPELL_PHASE_PUNCH = 64412, + SPELL_BIG_BANG = 64443, + SPELL_ASCEND_TO_THE_HEAVENS = 64487, + SPELL_COSMIC_SMASH = 62301, + SPELL_COSMIC_SMASH_TRIGGERED = 62304, + SPELL_COSMIC_SMASH_VISUAL_STATE = 62300, + SPELL_SELF_STUN = 65256, + SPELL_KILL_CREDIT = 65184, + SPELL_TELEPORT = 62940, + + // Algalon Stalker + SPELL_TRIGGER_3_ADDS = 62266, // Triggers Living Constellation + + // Living Constellation + SPELL_ARCANE_BARRAGE = 64599, + + // Collapsing Star + SPELL_COLLAPSE = 62018, + SPELL_BLACK_HOLE_SPAWN_VISUAL = 62003, + SPELL_SUMMON_BLACK_HOLE = 62189, + + // Black Hole + SPELL_BLACK_HOLE_TRIGGER = 62185, + SPELL_CONSTELLATION_PHASE_TRIGGER = 65508, + SPELL_CONSTELLATION_PHASE_EFFECT = 65509, + SPELL_BLACK_HOLE_EXPLOSION = 64122, + SPELL_SUMMON_VOID_ZONE_VISUAL = 64470, + SPELL_VOID_ZONE_VISUAL = 64469, + SPELL_BLACK_HOLE_CREDIT = 65312, + + // Worm Hole + SPELL_WORM_HOLE_TRIGGER = 65251, + SPELL_SUMMON_UNLEASHED_DARK_MATTER = 64450, +}; + +uint32 const PhasePunchAlphaId[5] = {64435, 64434, 64428, 64421, 64417}; + +enum Events +{ + // Celestial Planetarium Access + EVENT_DESPAWN_CONSOLE = 1, + + // Brann Bronzebeard + EVENT_BRANN_MOVE_INTRO = 2, + EVENT_SUMMON_ALGALON = 3, + EVENT_BRANN_OUTRO_1 = 4, + EVENT_BRANN_OUTRO_2 = 5, + + // Algalon the Observer + EVENT_INTRO_1 = 6, + EVENT_INTRO_2 = 7, + EVENT_INTRO_3 = 8, + EVENT_INTRO_FINISH = 9, + EVENT_START_COMBAT = 10, + EVENT_INTRO_TIMER_DONE = 11, + EVENT_QUANTUM_STRIKE = 12, + EVENT_PHASE_PUNCH = 13, + EVENT_SUMMON_COLLAPSING_STAR = 14, + EVENT_BIG_BANG = 15, + EVENT_RESUME_UPDATING = 16, + EVENT_ASCEND_TO_THE_HEAVENS = 17, + EVENT_EVADE = 18, + EVENT_COSMIC_SMASH = 19, + EVENT_UNLOCK_YELL = 20, + EVENT_OUTRO_START = 21, + EVENT_OUTRO_1 = 22, + EVENT_OUTRO_2 = 23, + EVENT_OUTRO_3 = 24, + EVENT_OUTRO_4 = 25, + EVENT_OUTRO_5 = 26, + EVENT_OUTRO_6 = 27, + EVENT_OUTRO_7 = 28, + EVENT_OUTRO_8 = 29, + EVENT_OUTRO_9 = 30, + EVENT_OUTRO_10 = 31, + EVENT_OUTRO_11 = 32, + EVENT_OUTRO_12 = 33, + EVENT_OUTRO_13 = 34, + EVENT_OUTRO_14 = 35, + EVENT_DESPAWN_ALGALON_1 = 36, + EVENT_DESPAWN_ALGALON_2 = 37, + EVENT_DESPAWN_ALGALON_3 = 38, + + // Living Constellation + EVENT_ARCANE_BARRAGE = 39, +}; + +enum Actions +{ + ACTION_START_INTRO = 0, + ACTION_FINISH_INTRO = 1, + ACTION_ACTIVATE_STAR = 2, + ACTION_BIG_BANG = 3, + ACTION_ASCEND = 4, + ACTION_OUTRO = 5, +}; + +enum Points +{ + POINT_BRANN_INTRO = 0, + MAX_BRANN_WAYPOINTS_INTRO = 10, + POINT_BRANN_OUTRO = 10, + POINT_BRANN_OUTRO_END = 11, + + POINT_ALGALON_LAND = 1, + POINT_ALGALON_OUTRO = 2, +}; + +enum EncounterPhases +{ + PHASE_NORMAL = 0, + PHASE_ROLE_PLAY = 1, + PHASE_BIG_BANG = 2, + + PHASE_MASK_NO_UPDATE = (1 << PHASE_ROLE_PLAY) | (1 << PHASE_BIG_BANG), + PHASE_MASK_NO_CAST_CHECK = 1 << PHASE_ROLE_PLAY, +}; + +enum AchievmentInfo +{ + EVENT_ID_SUPERMASSIVE_START = 21697, + DATA_HAS_FED_ON_TEARS = 30043005, +}; + + +Position const BrannIntroSpawnPos = {1676.277f, -162.5308f, 427.3326f, 3.235537f}; +Position const BrannIntroWaypoint[MAX_BRANN_WAYPOINTS_INTRO] = +{ + {1642.482f, -164.0812f, 427.2602f, 0.0f}, + {1635.000f, -169.5145f, 427.2523f, 0.0f}, + {1632.814f, -173.9334f, 427.2621f, 0.0f}, + {1632.676f, -190.5927f, 425.8831f, 0.0f}, + {1631.497f, -214.2221f, 418.1152f, 0.0f}, + {1624.717f, -224.6876f, 418.1152f, 0.0f}, + {1631.497f, -214.2221f, 418.1152f, 0.0f}, + {1632.676f, -190.5927f, 425.8831f, 0.0f}, + {1632.814f, -173.9334f, 427.2621f, 0.0f}, + {1635.000f, -169.5145f, 427.2523f, 0.0f}, +}; +Position const AlgalonSummonPos = {1632.531f, -304.8516f, 450.1123f, 1.530165f}; +Position const AlgalonLandPos = {1632.668f, -302.7656f, 417.3211f, 1.530165f}; + +#define LIVING_CONSTELLATION_COUNT 11 +Position const ConstellationPos[LIVING_CONSTELLATION_COUNT] = +{ + {1625.208f, -267.2771f, 446.4296f, 5.044002f}, + {1658.279f, -262.5490f, 441.9073f, 4.188790f}, + {1678.677f, -276.3280f, 427.7531f, 3.979351f}, + {1593.389f, -299.4325f, 432.4636f, 6.073746f}, + {1685.613f, -300.1219f, 443.2366f, 3.385939f}, + {1591.706f, -263.8201f, 441.4153f, 5.253441f}, + {1668.317f, -324.7676f, 457.9394f, 3.211406f}, + {1592.242f, -325.5323f, 446.9508f, 0.226893f}, + {1635.821f, -363.3442f, 424.3459f, 1.466077f}, + {1672.188f, -357.2484f, 436.7337f, 2.338741f}, + {1615.800f, -348.0065f, 442.9586f, 1.134464f}, +}; + +#define COLLAPSING_STAR_COUNT 4 +Position const CollapsingStarPos[COLLAPSING_STAR_COUNT] = +{ + {1649.438f, -319.8127f, 418.3941f, 1.082104f}, + {1647.005f, -288.6790f, 417.3955f, 3.490659f}, + {1622.451f, -321.1563f, 417.6188f, 4.677482f}, + {1615.060f, -291.6816f, 417.7796f, 3.490659f}, +}; +Position const AlgalonOutroPos = {1633.64f, -317.78f, 417.3211f, 0.0f}; +Position const BrannOutroPos[3] = +{ + {1632.023f, -243.7434f, 417.9118f, 0.0f}, + {1631.986f, -297.7831f, 417.3210f, 0.0f}, + {1633.832f, -216.2948f, 417.0463f, 0.0f}, +}; + +class ActivateLivingConstellation : public BasicEvent +{ + public: + ActivateLivingConstellation(Unit* owner) : _owner(owner), _instance(owner->GetInstanceScript()) + { + } + + bool Execute(uint64 execTime, uint32 /*diff*/) + { + if (!_instance || _instance->GetBossState(BOSS_ALGALON) != IN_PROGRESS) + return true; // delete event + + _owner->CastSpell((Unit*)NULL, SPELL_TRIGGER_3_ADDS, TRIGGERED_FULL_MASK); + _owner->m_Events.AddEvent(this, execTime + urand(45000, 50000)); + return false; + } + + private: + Unit* _owner; + InstanceScript* _instance; +}; + +class CosmicSmashDamageEvent : public BasicEvent +{ + public: + CosmicSmashDamageEvent(Unit* caster) : _caster(caster) + { + } + + bool Execute(uint64 /*execTime*/, uint32 /*diff*/) + { + _caster->CastSpell((Unit*)NULL, SPELL_COSMIC_SMASH_TRIGGERED, TRIGGERED_FULL_MASK); + return true; + } + + private: + Unit* _caster; +}; + +class SummonUnleashedDarkMatter : public BasicEvent +{ + public: + SummonUnleashedDarkMatter(Unit* caster) : _caster(caster) + { + } + + bool Execute(uint64 execTime, uint32 /*diff*/) + { + _caster->CastSpell((Unit*)NULL, SPELL_SUMMON_UNLEASHED_DARK_MATTER, TRIGGERED_FULL_MASK); + _caster->m_Events.AddEvent(this, execTime + 30000); + return false; + } + + private: + Unit* _caster; +}; + +class boss_algalon_the_observer : public CreatureScript +{ + public: + boss_algalon_the_observer() : CreatureScript("boss_algalon_the_observer") {} + + struct boss_algalon_the_observerAI : public BossAI + { + boss_algalon_the_observerAI(Creature* creature) : BossAI(creature, BOSS_ALGALON) + { + _firstPull = true; + _fedOnTears = false; + } + + void Reset() + { + _Reset(); + me->SetReactState(REACT_PASSIVE); + _phaseTwo = false; + _fightWon = false; + _hasYelled = false; + } + + void KilledUnit(Unit* victim) + { + if (victim->GetTypeId() == TYPEID_UNIT) + { + _fedOnTears = true; + if (!_hasYelled) + { + _hasYelled = true; + events.ScheduleEvent(EVENT_UNLOCK_YELL, 1000); + Talk(SAY_ALGALON_KILL); + } + } + } + + void DoAction(int32 const action) + { + switch (action) + { + case ACTION_START_INTRO: + { + me->SetFlag(UNIT_FIELD_FLAGS_2, 0x20); + me->SetDisableGravity(true); + DoCast(me, SPELL_ARRIVAL, true); + DoCast(me, SPELL_RIDE_THE_LIGHTNING, true); + me->GetMotionMaster()->MovePoint(POINT_ALGALON_LAND, AlgalonLandPos); + me->SetHomePosition(AlgalonLandPos); + Movement::MoveSplineInit init(*me); + init.MoveTo(AlgalonLandPos.GetPositionX(), AlgalonLandPos.GetPositionY(), AlgalonLandPos.GetPositionZ()); + init.SetOrientationFixed(true); + init.Launch(); + events.Reset(); + events.SetPhase(PHASE_ROLE_PLAY); + events.ScheduleEvent(EVENT_INTRO_1, 5000, 0, PHASE_ROLE_PLAY); + events.ScheduleEvent(EVENT_INTRO_2, 15000, 0, PHASE_ROLE_PLAY); + events.ScheduleEvent(EVENT_INTRO_3, 23000, 0, PHASE_ROLE_PLAY); + events.ScheduleEvent(EVENT_INTRO_FINISH, 36000, 0, PHASE_ROLE_PLAY); + break; + } + case ACTION_ASCEND: + events.SetPhase(PHASE_BIG_BANG); + events.CancelEvent(EVENT_RESUME_UPDATING); + events.ScheduleEvent(EVENT_ASCEND_TO_THE_HEAVENS, 1500); + break; + case EVENT_DESPAWN_ALGALON: + events.Reset(); + events.SetPhase(PHASE_ROLE_PLAY); + if (me->isInCombat()) + events.ScheduleEvent(EVENT_ASCEND_TO_THE_HEAVENS, 1); + events.ScheduleEvent(EVENT_DESPAWN_ALGALON_1, 5000); + events.ScheduleEvent(EVENT_DESPAWN_ALGALON_2, 17000); + events.ScheduleEvent(EVENT_DESPAWN_ALGALON_3, 26000); + me->DespawnOrUnsummon(34000); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_IMMUNE_TO_NPC); + break; + case ACTION_INIT_ALGALON: + _firstPull = false; + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); + break;; + } + } + + uint32 GetData(uint32 type) + { + return type == DATA_HAS_FED_ON_TEARS ? _fedOnTears : 1; + } + + void EnterCombat(Unit* /*target*/) + { + uint32 introDelay = 0; + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_IMMUNE_TO_NPC); + events.Reset(); + events.SetPhase(PHASE_ROLE_PLAY); + + if (!_firstPull) + { + Talk(SAY_ALGALON_AGGRO); + _EnterCombat(); + introDelay = 8000; + } + else + { + _firstPull = false; + Talk(SAY_ALGALON_START_TIMER); + if (Creature* brann = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_BRANN_BRONZEBEARD_ALG))) + brann->AI()->DoAction(ACTION_FINISH_INTRO); + + me->setActive(true); + DoZoneInCombat(); + introDelay = 26000; + summons.DespawnEntry(NPC_AZEROTH); + instance->SetData(EVENT_DESPAWN_ALGALON, 0); + events.ScheduleEvent(EVENT_START_COMBAT, 18000); + } + + events.ScheduleEvent(EVENT_INTRO_TIMER_DONE, introDelay); + events.ScheduleEvent(EVENT_QUANTUM_STRIKE, 3500 + introDelay); + events.ScheduleEvent(EVENT_PHASE_PUNCH, 15500 + introDelay); + events.ScheduleEvent(EVENT_SUMMON_COLLAPSING_STAR, 18000 + introDelay); + events.ScheduleEvent(EVENT_BIG_BANG, 90000 + introDelay); + events.ScheduleEvent(EVENT_ASCEND_TO_THE_HEAVENS, 360000 + introDelay); + events.ScheduleEvent(EVENT_COSMIC_SMASH, 25000 + introDelay); + + std::list<Creature*> stalkers; + me->GetCreatureListWithEntryInGrid(stalkers, NPC_ALGALON_STALKER, 200.0f); + for (std::list<Creature*>::iterator itr = stalkers.begin(); itr != stalkers.end(); ++itr) + (*itr)->m_Events.KillAllEvents(true); + } + + void MovementInform(uint32 movementType, uint32 pointId) + { + if (movementType != POINT_MOTION_TYPE) + return; + + if (pointId == POINT_ALGALON_LAND) + me->SetDisableGravity(false); + else if (pointId == POINT_ALGALON_OUTRO) + { + me->SetFacingTo(1.605703f); + events.ScheduleEvent(EVENT_OUTRO_3, 1200); + events.ScheduleEvent(EVENT_OUTRO_4, 2400); + events.ScheduleEvent(EVENT_OUTRO_5, 8500); + events.ScheduleEvent(EVENT_OUTRO_6, 15500); + events.ScheduleEvent(EVENT_OUTRO_7, 55500); + events.ScheduleEvent(EVENT_OUTRO_8, 73500); + events.ScheduleEvent(EVENT_OUTRO_9, 85500); + events.ScheduleEvent(EVENT_OUTRO_10, 108500); + events.ScheduleEvent(EVENT_OUTRO_11, 123500); + } + } + + void JustSummoned(Creature* summon) + { + summons.Summon(summon); + switch (summon->GetEntry()) + { + case NPC_AZEROTH: + DoCastAOE(SPELL_REORIGINATION, true); + break; + case NPC_COLLAPSING_STAR: + summon->SetReactState(REACT_PASSIVE); + summon->GetMotionMaster()->MoveRandom(20.0f); + summon->CastSpell(summon, SPELL_COLLAPSE, TRIGGERED_FULL_MASK); + break; + case NPC_BLACK_HOLE: + summon->SetReactState(REACT_PASSIVE); + summon->CastSpell((Unit*)NULL, SPELL_BLACK_HOLE_TRIGGER, TRIGGERED_FULL_MASK); + summon->CastSpell(summon, SPELL_CONSTELLATION_PHASE_TRIGGER, TRIGGERED_FULL_MASK); + summon->CastSpell((Unit*)NULL, SPELL_BLACK_HOLE_EXPLOSION); + summon->CastSpell(summon, SPELL_SUMMON_VOID_ZONE_VISUAL, TRIGGERED_FULL_MASK); + break; + case NPC_ALGALON_VOID_ZONE_VISUAL_STALKER: + summon->CastSpell(summon, SPELL_VOID_ZONE_VISUAL, TRIGGERED_FULL_MASK); + break; + case NPC_ALGALON_STALKER_ASTEROID_TARGET_01: + summon->CastSpell(summon, SPELL_COSMIC_SMASH_VISUAL_STATE, TRIGGERED_FULL_MASK); + break; + case NPC_ALGALON_STALKER_ASTEROID_TARGET_02: + summon->m_Events.AddEvent(new CosmicSmashDamageEvent(summon), summon->m_Events.CalculateTime(3250)); + break; + case NPC_WORM_HOLE: + summon->SetReactState(REACT_PASSIVE); + summon->CastSpell(summon, SPELL_WORM_HOLE_TRIGGER, TRIGGERED_FULL_MASK); + summon->CastSpell(summon, SPELL_SUMMON_VOID_ZONE_VISUAL, TRIGGERED_FULL_MASK); + break; + case NPC_UNLEASHED_DARK_MATTER: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, NonTankTargetSelector(me))) + if (summon->Attack(target, true)) + summon->GetMotionMaster()->MoveChase(target); + break; + } + } + + void EnterEvadeMode() + { + instance->SetBossState(BOSS_ALGALON, FAIL); + BossAI::EnterEvadeMode(); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); + me->SetSheath(SHEATH_STATE_UNARMED); + } + + void DamageTaken(Unit* /*attacker*/, uint32& damage) + { + if (_fightWon) + { + damage = 0; + return; + } + + if (!_phaseTwo && me->HealthBelowPctDamaged(20, damage)) + { + _phaseTwo = true; + Talk(SAY_ALGALON_PHASE_TWO); + summons.DespawnEntry(NPC_LIVING_CONSTELLATION); + summons.DespawnEntry(NPC_COLLAPSING_STAR); + summons.DespawnEntry(NPC_BLACK_HOLE); + summons.DespawnEntry(NPC_ALGALON_VOID_ZONE_VISUAL_STALKER); + events.CancelEvent(EVENT_SUMMON_COLLAPSING_STAR); + std::list<Creature*> stalkers; + me->GetCreatureListWithEntryInGrid(stalkers, NPC_ALGALON_STALKER, 200.0f); + for (std::list<Creature*>::iterator itr = stalkers.begin(); itr != stalkers.end(); ++itr) + (*itr)->m_Events.KillAllEvents(true); + for (uint32 i = 0; i < COLLAPSING_STAR_COUNT; ++i) + if (Creature* wormHole = DoSummon(NPC_WORM_HOLE, CollapsingStarPos[i], TEMPSUMMON_MANUAL_DESPAWN)) + wormHole->m_Events.AddEvent(new SummonUnleashedDarkMatter(wormHole), wormHole->m_Events.CalculateTime(i >= 2 ? 8000 : 6000)); + } + else if ((int32(me->GetHealth()) - int32(damage)) < CalculatePctF<int32>(int32(me->GetMaxHealth()), 2.5f) && !_fightWon) + { + _fightWon = true; + damage = 0; + me->SetReactState(REACT_PASSIVE); + me->AttackStop(); + me->setFaction(35); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + DoCast(me, SPELL_SELF_STUN); + events.Reset(); + summons.DespawnAll(); + events.SetPhase(PHASE_ROLE_PLAY); + events.ScheduleEvent(EVENT_OUTRO_START, 1500); + events.ScheduleEvent(EVENT_OUTRO_1, 7200); + events.ScheduleEvent(EVENT_OUTRO_2, 8700); + } + } + + void UpdateAI(uint32 const diff) + { + if ((!(events.GetPhaseMask() & PHASE_MASK_NO_UPDATE) && !UpdateVictim()) || !CheckInRoom()) + return; + + events.Update(diff); + + if (!(events.GetPhaseMask() & PHASE_MASK_NO_CAST_CHECK)) + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_INTRO_1: + me->RemoveAurasDueToSpell(SPELL_RIDE_THE_LIGHTNING); + Talk(SAY_ALGALON_INTRO_1); + break; + case EVENT_INTRO_2: + DoCastAOE(SPELL_SUMMON_AZEROTH, true); + Talk(SAY_ALGALON_INTRO_2); + break; + case EVENT_INTRO_3: + Talk(SAY_ALGALON_INTRO_3); + break; + case EVENT_INTRO_FINISH: + events.Reset(); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); + break; + case EVENT_START_COMBAT: + instance->SetBossState(BOSS_ALGALON, IN_PROGRESS); + break; + case EVENT_INTRO_TIMER_DONE: + { + events.SetPhase(PHASE_NORMAL); + me->SetSheath(SHEATH_STATE_MELEE); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_IMMUNE_TO_NPC); + me->SetReactState(REACT_DEFENSIVE); + DoCastAOE(SPELL_SUPERMASSIVE_FAIL, true); + //! Workaround for Creature::_IsTargetAcceptable returning false + //! for creatures that start combat in REACT_PASSIVE and UNIT_FLAG_NOT_SELECTABLE + //! causing them to immediately evade + if (!me->getThreatManager().isThreatListEmpty()) + AttackStart(me->getThreatManager().getHostilTarget()); + for (uint32 i = 0; i < LIVING_CONSTELLATION_COUNT; ++i) + if (Creature* summon = DoSummon(NPC_LIVING_CONSTELLATION, ConstellationPos[i], 0, TEMPSUMMON_DEAD_DESPAWN)) + summon->SetReactState(REACT_PASSIVE); + + std::list<Creature*> stalkers; + me->GetCreatureListWithEntryInGrid(stalkers, NPC_ALGALON_STALKER, 200.0f); + if (!stalkers.empty()) + { + Unit* stalker = Trinity::Containers::SelectRandomContainerElement(stalkers); + stalker->m_Events.AddEvent(new ActivateLivingConstellation(stalker), stalker->m_Events.CalculateTime(urand(45000, 50000))); + } + break; + } + case EVENT_QUANTUM_STRIKE: + DoCastVictim(SPELL_QUANTUM_STRIKE); + events.ScheduleEvent(EVENT_QUANTUM_STRIKE, urand(3000, 5000)); + break; + case EVENT_PHASE_PUNCH: + DoCastVictim(SPELL_PHASE_PUNCH); + events.ScheduleEvent(EVENT_PHASE_PUNCH, 15500); + break; + case EVENT_SUMMON_COLLAPSING_STAR: + Talk(SAY_ALGALON_COLLAPSING_STAR); + Talk(EMOTE_ALGALON_COLLAPSING_STAR); + for (uint32 i = 0; i < COLLAPSING_STAR_COUNT; ++i) + me->SummonCreature(NPC_COLLAPSING_STAR, CollapsingStarPos[i], TEMPSUMMON_CORPSE_DESPAWN); + events.ScheduleEvent(EVENT_SUMMON_COLLAPSING_STAR, 60000); + break; + case EVENT_BIG_BANG: + { + Talk(SAY_ALGALON_BIG_BANG); + Talk(EMOTE_ALGALON_BIG_BANG); + events.SetPhase(PHASE_BIG_BANG); + std::list<Creature*> constellations; + me->GetCreatureListWithEntryInGrid(constellations, NPC_LIVING_CONSTELLATION, 200.0f); + for (std::list<Creature*>::iterator itr = constellations.begin(); itr != constellations.end(); ++itr) + (*itr)->AI()->DoAction(ACTION_BIG_BANG); + DoCastAOE(SPELL_BIG_BANG); + events.ScheduleEvent(EVENT_BIG_BANG, 90500); + events.ScheduleEvent(EVENT_RESUME_UPDATING, 9500); + break; + } + case EVENT_RESUME_UPDATING: + events.SetPhase(0); + break; + case EVENT_ASCEND_TO_THE_HEAVENS: + Talk(SAY_ALGALON_ASCEND); + DoCastAOE(SPELL_ASCEND_TO_THE_HEAVENS); + events.ScheduleEvent(EVENT_EVADE, 2500); + break; + case EVENT_EVADE: + EnterEvadeMode(); + break; + case EVENT_COSMIC_SMASH: + Talk(EMOTE_ALGALON_COSMIC_SMASH); + DoCastAOE(SPELL_COSMIC_SMASH); + events.ScheduleEvent(EVENT_COSMIC_SMASH, 25500); + break; + case EVENT_UNLOCK_YELL: + _hasYelled = false; + break; + case EVENT_OUTRO_START: + instance->SetBossState(BOSS_ALGALON, DONE); + break; + case EVENT_OUTRO_1: + me->RemoveAllAuras(); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_RENAME); + break; + case EVENT_OUTRO_2: + _EnterEvadeMode(); + me->AddUnitState(UNIT_STATE_EVADE); + me->GetMotionMaster()->MovePoint(POINT_ALGALON_OUTRO, AlgalonOutroPos); + break; + case EVENT_OUTRO_3: + DoCastAOE(SPELL_KILL_CREDIT); + break; + case EVENT_OUTRO_4: + DoCastAOE(SPELL_SUPERMASSIVE_FAIL); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + break; + case EVENT_OUTRO_5: + if (Creature* brann = DoSummon(NPC_BRANN_BRONZBEARD_ALG, BrannOutroPos[0], 131500, TEMPSUMMON_TIMED_DESPAWN)) + brann->AI()->DoAction(ACTION_OUTRO); + break; + case EVENT_OUTRO_6: + Talk(SAY_ALGALON_OUTRO_1); + me->SetStandState(UNIT_STAND_STATE_KNEEL); + break; + case EVENT_OUTRO_7: + Talk(SAY_ALGALON_OUTRO_2); + break; + case EVENT_OUTRO_8: + Talk(SAY_ALGALON_OUTRO_3); + break; + case EVENT_OUTRO_9: + Talk(SAY_ALGALON_OUTRO_4); + break; + case EVENT_OUTRO_10: + Talk(SAY_ALGALON_OUTRO_5); + break; + case EVENT_OUTRO_11: + me->SetStandState(UNIT_STAND_STATE_STAND); + DoCast(me, SPELL_TELEPORT); + me->DespawnOrUnsummon(1500); + break; + } + } + + DoMeleeAttackIfReady(); + } + + private: + bool _firstPull; + bool _fedOnTears; + bool _phaseTwo; + bool _fightWon; + bool _hasYelled; + }; + + CreatureAI* GetAI(Creature* creature) const + { + return GetUlduarAI<boss_algalon_the_observerAI>(creature); + } +}; + +class npc_living_constellation : public CreatureScript +{ + public: + npc_living_constellation() : CreatureScript("npc_living_constellation") { } + + struct npc_living_constellationAI : public CreatureAI + { + npc_living_constellationAI(Creature* creature) : CreatureAI(creature) + { + } + + void Reset() + { + _events.Reset(); + _events.ScheduleEvent(EVENT_ARCANE_BARRAGE, 2500); + _isActive = false; + } + + uint32 GetData(uint32 /*type*/) + { + return _isActive ? 1 : 0; + } + + void DoAction(int32 const action) + { + switch (action) + { + case ACTION_ACTIVATE_STAR: + if (Creature* algalon = me->FindNearestCreature(NPC_ALGALON, 200.0f)) + { + if (Unit* target = algalon->AI()->SelectTarget(SELECT_TARGET_RANDOM, 0, NonTankTargetSelector(algalon))) + { + me->SetReactState(REACT_AGGRESSIVE); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + AttackStart(target); + DoZoneInCombat(); + _isActive = true; + } + } + break; + case ACTION_BIG_BANG: + _events.SetPhase(PHASE_BIG_BANG); + _events.DelayEvents(9500); + _events.ScheduleEvent(EVENT_RESUME_UPDATING, 9500); + break; + } + } + + void SpellHit(Unit* caster, SpellInfo const* spell) + { + if (spell->Id != SPELL_CONSTELLATION_PHASE_EFFECT || caster->GetTypeId() != TYPEID_UNIT) + return; + + me->DespawnOrUnsummon(1); + if (InstanceScript* instance = me->GetInstanceScript()) + instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, EVENT_ID_SUPERMASSIVE_START); + caster->CastSpell((Unit*)NULL, SPELL_BLACK_HOLE_CREDIT, TRIGGERED_FULL_MASK); + caster->ToCreature()->DespawnOrUnsummon(1); + } + + void UpdateAI(uint32 const diff) + { + if (!(_events.GetPhaseMask() & PHASE_MASK_NO_UPDATE) && !UpdateVictim()) + return; + + _events.Update(diff); + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_ARCANE_BARRAGE: + DoCastAOE(SPELL_ARCANE_BARRAGE); + _events.ScheduleEvent(EVENT_ARCANE_BARRAGE, 2500); + break; + case EVENT_RESUME_UPDATING: + _events.SetPhase(0); + break; + } + } + } + + private: + EventMap _events; + bool _isActive; + }; + + CreatureAI* GetAI(Creature* creature) const + { + return GetUlduarAI<npc_living_constellationAI>(creature); + } +}; + +class npc_collapsing_star : public CreatureScript +{ + public: + npc_collapsing_star() : CreatureScript("npc_collapsing_star") { } + + struct npc_collapsing_starAI : public PassiveAI + { + npc_collapsing_starAI(Creature* creature) : PassiveAI(creature) + { + _dying = false; + } + + void JustSummoned(Creature* summon) + { + if (summon->GetEntry() != NPC_BLACK_HOLE) + return; + + if (TempSummon* summ = me->ToTempSummon()) + if (Creature* algalon = ObjectAccessor::GetCreature(*me, summ->GetSummonerGUID())) + algalon->AI()->JustSummoned(summon); + + me->DespawnOrUnsummon(1); + } + + void DamageTaken(Unit* /*attacker*/, uint32& damage) + { + if (_dying) + { + damage = 0; + return; + } + + if (damage >= me->GetHealth()) + { + _dying = true; + damage = 0; + DoCast(me, SPELL_BLACK_HOLE_SPAWN_VISUAL, true); + DoCast(me, SPELL_SUMMON_BLACK_HOLE, true); + } + } + + bool _dying; + }; + + CreatureAI* GetAI(Creature* creature) const + { + return GetUlduarAI<npc_collapsing_starAI>(creature); + } +}; + +class npc_brann_bronzebeard_algalon : public CreatureScript +{ + public: + npc_brann_bronzebeard_algalon() : CreatureScript("npc_brann_bronzebeard_algalon") { } + + struct npc_brann_bronzebeard_algalonAI : public CreatureAI + { + npc_brann_bronzebeard_algalonAI(Creature* creature) : CreatureAI(creature) + { + } + + void DoAction(int32 const action) + { + switch (action) + { + case ACTION_START_INTRO: + _currentPoint = 0; + _events.Reset(); + me->SetWalk(false); + _events.ScheduleEvent(EVENT_BRANN_MOVE_INTRO, 1); + break; + case ACTION_FINISH_INTRO: + Talk(SAY_BRANN_ALGALON_INTRO_2); + _events.ScheduleEvent(EVENT_BRANN_MOVE_INTRO, 1); + break; + case ACTION_OUTRO: + me->GetMotionMaster()->MovePoint(POINT_BRANN_OUTRO, BrannOutroPos[1]); + _events.ScheduleEvent(EVENT_BRANN_OUTRO_1, 89500); + _events.ScheduleEvent(EVENT_BRANN_OUTRO_2, 116500); + break; + } + } + + void MovementInform(uint32 movementType, uint32 pointId) + { + if (movementType != POINT_MOTION_TYPE) + return; + + uint32 delay = 1; + _currentPoint = pointId + 1; + switch (pointId) + { + case 2: + delay = 8000; + me->SetWalk(true); + break; + case 5: + me->SetWalk(false); + Talk(SAY_BRANN_ALGALON_INTRO_1); + _events.ScheduleEvent(EVENT_SUMMON_ALGALON, 7500); + return; + case 9: + me->DespawnOrUnsummon(1); + return; + case POINT_BRANN_OUTRO: + case POINT_BRANN_OUTRO_END: + return; + } + + _events.ScheduleEvent(EVENT_BRANN_MOVE_INTRO, delay); + } + + void UpdateAI(uint32 const diff) + { + UpdateVictim(); + + if (_events.Empty()) + return; + + _events.Update(diff); + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_BRANN_MOVE_INTRO: + if (_currentPoint < MAX_BRANN_WAYPOINTS_INTRO) + me->GetMotionMaster()->MovePoint(_currentPoint, BrannIntroWaypoint[_currentPoint]); + break; + case EVENT_SUMMON_ALGALON: + if (Creature* algalon = me->GetMap()->SummonCreature(NPC_ALGALON, AlgalonSummonPos)) + algalon->AI()->DoAction(ACTION_START_INTRO); + break; + case EVENT_BRANN_OUTRO_1: + Talk(SAY_BRANN_ALGALON_OUTRO); + break; + case EVENT_BRANN_OUTRO_2: + me->GetMotionMaster()->MovePoint(POINT_BRANN_OUTRO_END, BrannOutroPos[2]); + break; + } + } + } + + private: + EventMap _events; + uint32 _currentPoint; + }; + + CreatureAI* GetAI(Creature* creature) const + { + return GetUlduarAI<npc_brann_bronzebeard_algalonAI>(creature); + } +}; + +class go_celestial_planetarium_access : public GameObjectScript +{ + public: + go_celestial_planetarium_access() : GameObjectScript("go_celestial_planetarium_access") {} + + struct go_celestial_planetarium_accessAI : public GameObjectAI + { + go_celestial_planetarium_accessAI(GameObject* go) : GameObjectAI(go) + { + } + + bool GossipHello(Player* player) + { + bool hasKey = true; + if (LockEntry const* lock = sLockStore.LookupEntry(go->GetGOInfo()->goober.lockId)) + { + hasKey = false; + for (uint32 i = 0; i < MAX_LOCK_CASE; ++i) + { + if (!lock->Index[i]) + continue; + + if (player->HasItemCount(lock->Index[i], 1)) + { + hasKey = true; + break; + } + } + } + + if (!hasKey) + return false; + + // Start Algalon event + go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_IN_USE); + _events.ScheduleEvent(EVENT_DESPAWN_CONSOLE, 5000); + if (Creature* brann = go->SummonCreature(NPC_BRANN_BRONZBEARD_ALG, BrannIntroSpawnPos)) + brann->AI()->DoAction(ACTION_START_INTRO); + + if (InstanceScript* instance = go->GetInstanceScript()) + { + instance->SetData(DATA_ALGALON_SUMMON_STATE, 1); + if (GameObject* sigil = ObjectAccessor::GetGameObject(*go, instance->GetData64(DATA_SIGILDOOR_01))) + sigil->SetGoState(GO_STATE_ACTIVE); + + if (GameObject* sigil = ObjectAccessor::GetGameObject(*go, instance->GetData64(DATA_SIGILDOOR_02))) + sigil->SetGoState(GO_STATE_ACTIVE); + } + + return false; + } + + void UpdateAI(uint32 diff) + { + if (_events.Empty()) + return; + + _events.Update(diff); + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_DESPAWN_CONSOLE: + go->Delete(); + break; + } + } + } + + EventMap _events; + }; + + GameObjectAI* GetAI(GameObject* go) const + { + return GetUlduarAI<go_celestial_planetarium_accessAI>(go); + } +}; + +class spell_algalon_phase_punch : public SpellScriptLoader +{ + public: + spell_algalon_phase_punch() : SpellScriptLoader("spell_algalon_phase_punch") { } + + class spell_algalon_phase_punch_AuraScript : public AuraScript + { + PrepareAuraScript(spell_algalon_phase_punch_AuraScript); + + void HandlePeriodic(AuraEffect const* /*aurEff*/) + { + PreventDefaultAction(); + if (GetStackAmount() != 1) + GetTarget()->RemoveAurasDueToSpell(PhasePunchAlphaId[GetStackAmount() - 2]); + GetTarget()->CastSpell(GetTarget(), PhasePunchAlphaId[GetStackAmount() - 1], TRIGGERED_FULL_MASK); + if (GetStackAmount() == 5) + Remove(AURA_REMOVE_BY_DEFAULT); + } + + void OnRemove(AuraEffect const*, AuraEffectHandleModes) + { + if (GetStackAmount() != 5) + GetTarget()->RemoveAurasDueToSpell(PhasePunchAlphaId[GetStackAmount() - 1]); + } + + void Register() + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_algalon_phase_punch_AuraScript::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); + OnEffectRemove += AuraEffectRemoveFn(spell_algalon_phase_punch_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_algalon_phase_punch_AuraScript(); + } +}; + +class NotVictimFilter +{ + public: + NotVictimFilter(Unit* caster) : _victim(caster->getVictim()) + { + } + + bool operator()(Unit* target) + { + return target != _victim; + } + + private: + Unit* _victim; +}; + +class spell_algalon_arcane_barrage : public SpellScriptLoader +{ + public: + spell_algalon_arcane_barrage() : SpellScriptLoader("spell_algalon_arcane_barrage") { } + + class spell_algalon_arcane_barrage_SpellScript : public SpellScript + { + PrepareSpellScript(spell_algalon_arcane_barrage_SpellScript); + + void SelectTarget(std::list<Unit*>& targets) + { + targets.remove_if(NotVictimFilter(GetCaster())); + } + + void Register() + { + OnUnitTargetSelect += SpellUnitTargetFn(spell_algalon_arcane_barrage_SpellScript::SelectTarget, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_algalon_arcane_barrage_SpellScript(); + } +}; + +class ActiveConstellationFilter +{ + public: + bool operator()(Unit* target) const + { + return target->GetAI()->GetData(0); + } +}; + +class spell_algalon_trigger_3_adds : public SpellScriptLoader +{ + public: + spell_algalon_trigger_3_adds() : SpellScriptLoader("spell_algalon_trigger_3_adds") { } + + class spell_algalon_trigger_3_adds_SpellScript : public SpellScript + { + PrepareSpellScript(spell_algalon_trigger_3_adds_SpellScript); + + void SelectTarget(std::list<Unit*>& targets) + { + targets.remove_if(ActiveConstellationFilter()); + } + + void HandleDummy(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + Creature* target = GetHitCreature(); + if (!target) + return; + + target->AI()->DoAction(ACTION_ACTIVATE_STAR); + } + + void Register() + { + OnUnitTargetSelect += SpellUnitTargetFn(spell_algalon_trigger_3_adds_SpellScript::SelectTarget, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_algalon_trigger_3_adds_SpellScript(); + } +}; + +class spell_algalon_collapse : public SpellScriptLoader +{ + public: + spell_algalon_collapse() : SpellScriptLoader("spell_algalon_collapse") { } + + class spell_algalon_collapse_AuraScript : public AuraScript + { + PrepareAuraScript(spell_algalon_collapse_AuraScript); + + void HandlePeriodic(AuraEffect const* /*aurEff*/) + { + PreventDefaultAction(); + GetTarget()->DealDamage(GetTarget(), GetTarget()->CountPctFromMaxHealth(1), NULL, NODAMAGE); + } + + void Register() + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_algalon_collapse_AuraScript::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_algalon_collapse_AuraScript(); + } +}; + +class spell_algalon_big_bang : public SpellScriptLoader +{ + public: + spell_algalon_big_bang() : SpellScriptLoader("spell_algalon_big_bang") { } + + class spell_algalon_big_bang_SpellScript : public SpellScript + { + PrepareSpellScript(spell_algalon_big_bang_SpellScript); + + bool Load() + { + _targetCount = 0; + return true; + } + + void CountTargets(std::list<Unit*>& targets) + { + _targetCount = targets.size(); + } + + void CheckTargets() + { + if (!_targetCount) + GetCaster()->GetAI()->DoAction(ACTION_ASCEND); + } + + void Register() + { + OnUnitTargetSelect += SpellUnitTargetFn(spell_algalon_big_bang_SpellScript::CountTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); + AfterCast += SpellCastFn(spell_algalon_big_bang_SpellScript::CheckTargets); + } + + uint32 _targetCount; + }; + + SpellScript* GetSpellScript() const + { + return new spell_algalon_big_bang_SpellScript(); + } +}; + +class spell_algalon_remove_phase : public SpellScriptLoader +{ + public: + spell_algalon_remove_phase() : SpellScriptLoader("spell_algalon_remove_phase") { } + + class spell_algalon_remove_phase_AuraScript : public AuraScript + { + PrepareAuraScript(spell_algalon_remove_phase_AuraScript); + + void HandlePeriodic(AuraEffect const* /*aurEff*/) + { + PreventDefaultAction(); + GetTarget()->RemoveAurasByType(SPELL_AURA_PHASE); + } + + void Register() + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_algalon_remove_phase_AuraScript::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_algalon_remove_phase_AuraScript(); + } +}; + +class spell_algalon_cosmic_smash : public SpellScriptLoader +{ + public: + spell_algalon_cosmic_smash() : SpellScriptLoader("spell_algalon_cosmic_smash") { } + + class spell_algalon_cosmic_smash_SpellScript : public SpellScript + { + PrepareSpellScript(spell_algalon_cosmic_smash_SpellScript); + + void ModDestHeight(SpellEffIndex /*effIndex*/) + { + Position offset = {0.0f, 0.0f, 65.0f, 0.0f}; + const_cast<WorldLocation*>(GetExplTargetDest())->RelocateOffset(offset); + GetHitDest()->RelocateOffset(offset); + } + + void Register() + { + OnEffectLaunch += SpellEffectFn(spell_algalon_cosmic_smash_SpellScript::ModDestHeight, EFFECT_0, SPELL_EFFECT_SUMMON); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_algalon_cosmic_smash_SpellScript(); + } +}; + +class spell_algalon_cosmic_smash_damage : public SpellScriptLoader +{ + public: + spell_algalon_cosmic_smash_damage() : SpellScriptLoader("spell_algalon_cosmic_smash_damage") { } + + class spell_algalon_cosmic_smash_damage_SpellScript : public SpellScript + { + PrepareSpellScript(spell_algalon_cosmic_smash_damage_SpellScript); + + void RecalculateDamage() + { + if (!GetExplTargetDest() || !GetHitUnit()) + return; + + float distance = GetHitUnit()->GetDistance2d(GetExplTargetDest()->GetPositionX(), GetExplTargetDest()->GetPositionY()); + if (distance > 6.0f) + SetHitDamage(int32(float(GetHitDamage()) / distance) * 2); + } + + void Register() + { + OnHit += SpellHitFn(spell_algalon_cosmic_smash_damage_SpellScript::RecalculateDamage); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_algalon_cosmic_smash_damage_SpellScript(); + } +}; + +class spell_algalon_supermassive_fail : public SpellScriptLoader +{ + public: + spell_algalon_supermassive_fail() : SpellScriptLoader("spell_algalon_supermassive_fail") { } + + class spell_algalon_supermassive_fail_SpellScript : public SpellScript + { + PrepareSpellScript(spell_algalon_supermassive_fail_SpellScript); + + void RecalculateDamage() + { + if (!GetHitPlayer()) + return; + + GetHitPlayer()->GetAchievementMgr().ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, ACHIEVEMENT_CRITERIA_CONDITION_NO_SPELL_HIT, GetSpellInfo()->Id, true); + } + + void Register() + { + OnHit += SpellHitFn(spell_algalon_supermassive_fail_SpellScript::RecalculateDamage); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_algalon_supermassive_fail_SpellScript(); + } +}; + +class achievement_he_feeds_on_your_tears : public AchievementCriteriaScript +{ + public: + achievement_he_feeds_on_your_tears() : AchievementCriteriaScript("achievement_he_feeds_on_your_tears") { } + + bool OnCheck(Player* /*source*/, Unit* target) + { + return !target->GetAI()->GetData(DATA_HAS_FED_ON_TEARS); + } +}; + +void AddSC_boss_algalon_the_observer() +{ + new boss_algalon_the_observer(); + new npc_living_constellation(); + new npc_collapsing_star(); + new npc_brann_bronzebeard_algalon(); + new go_celestial_planetarium_access(); + new spell_algalon_phase_punch(); + new spell_algalon_arcane_barrage(); + new spell_algalon_trigger_3_adds(); + new spell_algalon_collapse(); + new spell_algalon_big_bang(); + new spell_algalon_remove_phase(); + new spell_algalon_cosmic_smash(); + new spell_algalon_cosmic_smash_damage(); + new spell_algalon_supermassive_fail(); + new achievement_he_feeds_on_your_tears(); +} diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_auriaya.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_auriaya.cpp index 6c2c08f07a0..472ff153d73 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_auriaya.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_auriaya.cpp @@ -298,14 +298,14 @@ class npc_auriaya_seeping_trigger : public CreatureScript void Reset() { - me->ForcedDespawn(600000); + me->DespawnOrUnsummon(600000); DoCast(me, SPELL_SEEPING_ESSENCE); } void UpdateAI(uint32 const /*diff*/) { if (instance->GetBossState(BOSS_AURIAYA) != IN_PROGRESS) - me->ForcedDespawn(); + me->DespawnOrUnsummon(); } private: diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp index 5d68da4e75a..0e453eceaa1 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp @@ -1273,7 +1273,7 @@ class go_ulduar_tower : public GameObjectScript public: go_ulduar_tower() : GameObjectScript("go_ulduar_tower") { } - void OnDestroyed(GameObject* go, Player* /*player*/, uint32 /*value*/) + void OnDestroyed(GameObject* go, Player* /*player*/) { InstanceScript* instance = go->GetInstanceScript(); if (!instance) @@ -1678,7 +1678,7 @@ class spell_pursue : public SpellScriptLoader else { //! In the end, only one target should be selected - _target = SelectRandomContainerElement(targets); + _target = Trinity::Containers::SelectRandomContainerElement(targets); FilterTargetsSubsequently(targets); } } @@ -1743,7 +1743,7 @@ class spell_vehicle_throw_passenger : public SpellScriptLoader { // use 99 because it is 3d search std::list<WorldObject*> targetList; - Trinity::WorldObjectSpellAreaTargetCheck check(99, GetTargetDest(), GetCaster(), GetCaster(), GetSpellInfo(), TARGET_CHECK_DEFAULT, NULL); + Trinity::WorldObjectSpellAreaTargetCheck check(99, GetExplTargetDest(), GetCaster(), GetCaster(), GetSpellInfo(), TARGET_CHECK_DEFAULT, NULL); Trinity::WorldObjectListSearcher<Trinity::WorldObjectSpellAreaTargetCheck> searcher(GetCaster(), targetList, check); GetCaster()->GetMap()->VisitAll(GetCaster()->m_positionX, GetCaster()->m_positionY, 99, searcher); float minDist = 99 * 99; diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp index 4ea38a7642d..a3c9cb847e5 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp @@ -507,7 +507,7 @@ class boss_freya : public CreatureScript for (uint8 n = 0; n < 3; ++n) { summons.remove(Elemental[n][i]->GetGUID()); - Elemental[n][i]->ForcedDespawn(5000); + Elemental[n][i]->DespawnOrUnsummon(5000); trioDefeated[i] = true; Elemental[n][i]->CastSpell(me, SPELL_REMOVE_10STACK, true); } @@ -664,12 +664,12 @@ class boss_freya : public CreatureScript case NPC_DETONATING_LASHER: summoned->CastSpell(me, SPELL_REMOVE_2STACK, true); summoned->CastSpell(who, SPELL_DETONATE, true); - summoned->ForcedDespawn(5000); + summoned->DespawnOrUnsummon(5000); summons.remove(summoned->GetGUID()); break; case NPC_ANCIENT_CONSERVATOR: summoned->CastSpell(me, SPELL_REMOVE_25STACK, true); - summoned->ForcedDespawn(5000); + summoned->DespawnOrUnsummon(5000); summons.remove(summoned->GetGUID()); break; } @@ -1385,7 +1385,7 @@ class npc_healthy_spore : public CreatureScript if (lifeTimer <= diff) { me->RemoveAurasDueToSpell(SPELL_GROW); - me->ForcedDespawn(2200); + me->DespawnOrUnsummon(2200); lifeTimer = urand(22000, 30000); } else @@ -1423,7 +1423,7 @@ class npc_eonars_gift : public CreatureScript { me->RemoveAurasDueToSpell(SPELL_GROW); DoCast(SPELL_LIFEBINDERS_GIFT); - me->ForcedDespawn(2500); + me->DespawnOrUnsummon(2500); lifeBindersGiftTimer = 12000; } else diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_general_vezax.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_general_vezax.cpp index 61f82d898b9..3556bf188de 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_general_vezax.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_general_vezax.cpp @@ -290,7 +290,7 @@ class boss_general_vezax : public CreatureScript if (size < playersMin) return NULL; - return SelectRandomContainerElement(PlayerList); + return Trinity::Containers::SelectRandomContainerElement(PlayerList); } return NULL; diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_ignis.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_ignis.cpp index 5a7afc34f13..540876f421b 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_ignis.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_ignis.cpp @@ -371,15 +371,15 @@ class npc_scorch_ground : public CreatureScript creature->SetDisplayId(16925); //model 2 in db cannot overwrite wdb fields } - void MoveInLineOfSight(Unit* unit) + void MoveInLineOfSight(Unit* who) { if (!_heat) { - if (unit->GetEntry() == NPC_IRON_CONSTRUCT) + if (who->GetEntry() == NPC_IRON_CONSTRUCT) { - if (!unit->HasAura(SPELL_HEAT) || !unit->HasAura(SPELL_MOLTEN)) + if (!who->HasAura(SPELL_HEAT) || !who->HasAura(SPELL_MOLTEN)) { - _constructGUID = unit->GetGUID(); + _constructGUID = who->GetGUID(); _heat = true; } } diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp index a1323b07899..e8e938dc06b 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp @@ -1006,7 +1006,7 @@ class spell_razorscale_devouring_flame : public SpellScriptLoader PreventHitDefaultEffect(effIndex); Unit* caster = GetCaster(); uint32 entry = uint32(GetSpellInfo()->Effects[effIndex].MiscValue); - WorldLocation const* summonLocation = GetTargetDest(); + WorldLocation const* summonLocation = GetExplTargetDest(); if (!caster || !summonLocation) return; diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp index 727f40aef81..c7091b42c5a 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp @@ -947,13 +947,19 @@ class spell_xt002_tympanic_tantrum : public SpellScriptLoader void FilterTargets(std::list<Unit*>& unitList) { - unitList.remove_if (PlayerOrPetCheck()); + unitList.remove_if(PlayerOrPetCheck()); + } + + void RecalculateDamage() + { + SetHitDamage(GetHitUnit()->CountPctFromMaxHealth(GetHitDamage())); } void Register() { OnUnitTargetSelect += SpellUnitTargetFn(spell_xt002_tympanic_tantrum_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); OnUnitTargetSelect += SpellUnitTargetFn(spell_xt002_tympanic_tantrum_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY); + OnHit += SpellHitFn(spell_xt002_tympanic_tantrum_SpellScript::RecalculateDamage); } }; diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yoggsaron.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yoggsaron.cpp index 3f01f21b189..58ba125b994 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yoggsaron.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yoggsaron.cpp @@ -18,18 +18,27 @@ #include "ScriptMgr.h" #include "ulduar.h" -enum Sara_Yells +enum Sara { - SAY_SARA_PREFIGHT_1 = -1603310, - SAY_SARA_PREFIGHT_2 = -1603311, - SAY_SARA_AGGRO_1 = -1603312, - SAY_SARA_AGGRO_2 = -1603313, - SAY_SARA_AGGRO_3 = -1603314, - SAY_SARA_SLAY_1 = -1603315, - SAY_SARA_SLAY_2 = -1603316, - WHISP_SARA_INSANITY = -1603317, - SAY_SARA_PHASE2_1 = -1603318, - SAY_SARA_PHASE2_2 = -1603319, + // text + YELL_SARA_PREFIGHT = 0, + YELL_COMBAT_PHASE_1 = 1, + YELL_COMBAT_PHASE_2 = 2, + YELL_SLAY = 3, + + // Phase 1 spells + SPELL_SARAS_ANGER_1 = 63147, // Target Entry 33136 + SPELL_SARAS_ANGER_2 = 63744, // Target Entry 33136 + SPELL_SARAS_FEVOR_1 = 63138, // Target Player + SPELL_SARAS_FEVOR_2 = 63747, // Target Player + SPELL_SARAS_BLESSING_1 = 63134, // Target Player + SPELL_SARAS_BLESSING_2 = 63745, // Target Self + + // Phase 2 spells + SPELL_PHYCHOSIS = 63795, // Target Self + SPELL_MALADY_OF_THE_MIND = 63830, // Target Self + SPELL_DEATH_RAY = 63891, // Target Self + SPELL_BRAIN_LINK = 63802, // Target Self }; enum YoggSaron_Yells diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp index e12393f047f..654d763ddbc 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp @@ -22,9 +22,14 @@ static DoorData const doorData[] = { - { GO_LEVIATHAN_DOOR, BOSS_LEVIATHAN, DOOR_TYPE_ROOM, BOUNDARY_S }, - { GO_XT_002_DOOR, BOSS_XT002, DOOR_TYPE_ROOM, BOUNDARY_S }, - { 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE }, + {GO_LEVIATHAN_DOOR, BOSS_LEVIATHAN, DOOR_TYPE_ROOM, BOUNDARY_S }, + {GO_XT_002_DOOR, BOSS_XT002, DOOR_TYPE_ROOM, BOUNDARY_S }, + {GO_DOODAD_UL_SIGILDOOR_03, BOSS_ALGALON, DOOR_TYPE_ROOM, BOUNDARY_W }, + {GO_DOODAD_UL_UNIVERSEFLOOR_01, BOSS_ALGALON, DOOR_TYPE_ROOM, BOUNDARY_NONE }, + {GO_DOODAD_UL_UNIVERSEFLOOR_02, BOSS_ALGALON, DOOR_TYPE_SPAWN_HOLE, BOUNDARY_NONE }, + {GO_DOODAD_UL_UNIVERSEGLOBE01, BOSS_ALGALON, DOOR_TYPE_SPAWN_HOLE, BOUNDARY_NONE }, + {GO_DOODAD_UL_ULDUAR_TRAPDOOR_03, BOSS_ALGALON, DOOR_TYPE_SPAWN_HOLE, BOUNDARY_NONE }, + {0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE }, }; class instance_ulduar : public InstanceMapScript @@ -36,7 +41,6 @@ class instance_ulduar : public InstanceMapScript { instance_ulduar_InstanceMapScript(InstanceMap* map) : InstanceScript(map) { } - uint32 Encounter[MAX_ENCOUNTER]; std::string m_strInstData; // Creatures @@ -72,6 +76,12 @@ class instance_ulduar : public InstanceMapScript uint64 HodirDoorGUID; uint64 HodirIceDoorGUID; uint64 ArchivumDoorGUID; + uint64 AlgalonSigilDoorGUID[3]; + uint64 AlgalonFloorGUID[2]; + uint64 AlgalonUniverseGUID; + uint64 AlgalonTrapdoorGUID; + uint64 BrannBronzebeardAlgGUID; + uint64 GiftOfTheObserverGUID; // Miscellaneous uint32 TeamInInstance; @@ -111,35 +121,49 @@ class instance_ulduar : public InstanceMapScript HodirDoorGUID = 0; HodirIceDoorGUID = 0; ArchivumDoorGUID = 0; + AlgalonUniverseGUID = 0; + AlgalonTrapdoorGUID = 0; + BrannBronzebeardAlgGUID = 0; + GiftOfTheObserverGUID = 0; + _algalonTimer = 61; + _maxArmorItemLevel = 0; + _maxWeaponItemLevel = 0; TeamInInstance = 0; HodirRareCacheData = 0; ColossusData = 0; elderCount = 0; conSpeedAtory = false; Unbroken = true; + _summonAlgalon = false; - memset(Encounter, 0, sizeof(Encounter)); + memset(AlgalonSigilDoorGUID, 0, sizeof(AlgalonSigilDoorGUID)); + memset(AlgalonFloorGUID, 0, sizeof(AlgalonFloorGUID)); memset(XTToyPileGUIDs, 0, sizeof(XTToyPileGUIDs)); memset(AssemblyGUIDs, 0, sizeof(AssemblyGUIDs)); memset(RazorHarpoonGUIDs, 0, sizeof(RazorHarpoonGUIDs)); memset(KeeperGUIDs, 0, sizeof(KeeperGUIDs)); } - bool IsEncounterInProgress() const + void FillInitialWorldStates(WorldPacket& packet) { - for (uint8 i = 0; i < MAX_ENCOUNTER; ++i) - { - if (Encounter[i] == IN_PROGRESS) - return true; - } - - return false; + packet << uint32(WORLD_STATE_ALGALON_TIMER_ENABLED) << uint32(_algalonTimer && _algalonTimer <= 60); + packet << uint32(WORLD_STATE_ALGALON_DESPAWN_TIMER) << uint32(std::min<uint32>(_algalonTimer, 60)); } void OnPlayerEnter(Player* player) { if (!TeamInInstance) TeamInInstance = player->GetTeam(); + + if (_summonAlgalon) + { + _summonAlgalon = false; + TempSummon* algalon = instance->SummonCreature(NPC_ALGALON, AlgalonLandPos); + if (_algalonTimer && _algalonTimer <= 60) + algalon->AI()->DoAction(ACTION_INIT_ALGALON); + else + algalon->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); + } } void OnCreatureCreate(Creature* creature) @@ -234,7 +258,6 @@ class instance_ulduar : public InstanceMapScript case NPC_ALGALON: AlgalonGUID = creature->GetGUID(); break; - // Hodir's Helper NPCs case NPC_EIVI_NIGHTFEATHER: if (TeamInInstance == HORDE) @@ -268,9 +291,32 @@ class instance_ulduar : public InstanceMapScript if (TeamInInstance == HORDE) creature->UpdateEntry(NPC_BATTLE_PRIEST_GINA, HORDE); break; + case NPC_BRANN_BRONZBEARD_ALG: + BrannBronzebeardAlgGUID = creature->GetGUID(); + break; + //! These creatures are summoned by something else than Algalon + //! but need to be controlled/despawned by him - so they need to be + //! registered in his summon list + case NPC_ALGALON_VOID_ZONE_VISUAL_STALKER: + case NPC_ALGALON_STALKER_ASTEROID_TARGET_01: + case NPC_ALGALON_STALKER_ASTEROID_TARGET_02: + case NPC_UNLEASHED_DARK_MATTER: + if (Creature* algalon = instance->GetCreature(AlgalonGUID)) + algalon->AI()->JustSummoned(creature); + break; } + } - } + void OnCreatureRemove(Creature* creature) + { + switch (creature->GetEntry()) + { + case NPC_BRANN_BRONZBEARD_ALG: + if (BrannBronzebeardAlgGUID == creature->GetGUID()) + BrannBronzebeardAlgGUID = 0; + break; + } + } void OnGameObjectCreate(GameObject* gameObject) { @@ -341,6 +387,45 @@ class instance_ulduar : public InstanceMapScript if (GetBossState(BOSS_ASSEMBLY_OF_IRON) != DONE) HandleGameObject(ArchivumDoorGUID, false); break; + case GO_CELESTIAL_PLANETARIUM_ACCESS_10: + case GO_CELESTIAL_PLANETARIUM_ACCESS_25: + if (_algalonSummoned) + gameObject->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_IN_USE); + break; + case GO_DOODAD_UL_SIGILDOOR_01: + AlgalonSigilDoorGUID[0] = gameObject->GetGUID(); + if (_algalonSummoned) + gameObject->SetGoState(GO_STATE_ACTIVE); + break; + case GO_DOODAD_UL_SIGILDOOR_02: + AlgalonSigilDoorGUID[1] = gameObject->GetGUID(); + if (_algalonSummoned) + gameObject->SetGoState(GO_STATE_ACTIVE); + break; + case GO_DOODAD_UL_SIGILDOOR_03: + AlgalonSigilDoorGUID[2] = gameObject->GetGUID(); + AddDoor(gameObject, true); + break; + case GO_DOODAD_UL_UNIVERSEFLOOR_01: + AlgalonFloorGUID[0] = gameObject->GetGUID(); + AddDoor(gameObject, true); + break; + case GO_DOODAD_UL_UNIVERSEFLOOR_02: + AlgalonFloorGUID[1] = gameObject->GetGUID(); + AddDoor(gameObject, true); + break; + case GO_DOODAD_UL_UNIVERSEGLOBE01: + AlgalonUniverseGUID = gameObject->GetGUID(); + AddDoor(gameObject, true); + break; + case GO_DOODAD_UL_ULDUAR_TRAPDOOR_03: + AlgalonTrapdoorGUID = gameObject->GetGUID(); + AddDoor(gameObject, true); + break; + case GO_GIFT_OF_THE_OBSERVER_10: + case GO_GIFT_OF_THE_OBSERVER_25: + GiftOfTheObserverGUID = gameObject->GetGUID(); + break; } } @@ -349,10 +434,14 @@ class instance_ulduar : public InstanceMapScript switch (gameObject->GetEntry()) { case GO_LEVIATHAN_DOOR: - AddDoor(gameObject, false); - break; case GO_XT_002_DOOR: + case GO_DOODAD_UL_SIGILDOOR_03: + case GO_DOODAD_UL_UNIVERSEFLOOR_01: + case GO_DOODAD_UL_UNIVERSEFLOOR_02: + case GO_DOODAD_UL_UNIVERSEGLOBE01: + case GO_DOODAD_UL_ULDUAR_TRAPDOOR_03: AddDoor(gameObject, false); + break; default: break; } @@ -390,6 +479,7 @@ class instance_ulduar : public InstanceMapScript // Flame Leviathan's Tower Event triggers Creature* FlameLeviathan = instance->GetCreature(LeviathanGUID); if (FlameLeviathan && FlameLeviathan->isAlive()) // No leviathan, no event triggering ;) + { switch (eventId) { case EVENT_TOWER_OF_STORM_DESTROYED: @@ -405,6 +495,7 @@ class instance_ulduar : public InstanceMapScript FlameLeviathan->AI()->DoAction(ACTION_TOWER_OF_LIFE_DESTROYED); break; } + } } @@ -465,6 +556,52 @@ class instance_ulduar : public InstanceMapScript if (GameObject* gameObject = instance->GetGameObject(ThorimChestGUID)) gameObject->SetRespawnTime(gameObject->GetRespawnDelay()); break; + case BOSS_ALGALON: + if (state == DONE) + { + _events.CancelEvent(EVENT_UPDATE_ALGALON_TIMER); + _events.CancelEvent(EVENT_DESPAWN_ALGALON); + DoUpdateWorldState(WORLD_STATE_ALGALON_TIMER_ENABLED, 0); + _algalonTimer = 61; + if (GameObject* gameObject = instance->GetGameObject(GiftOfTheObserverGUID)) + gameObject->SetRespawnTime(gameObject->GetRespawnDelay()); + // get item level (recheck weapons) + Map::PlayerList const& players = instance->GetPlayers(); + for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) + if (Player* player = itr->getSource()) + for (uint8 slot = EQUIPMENT_SLOT_MAINHAND; slot <= EQUIPMENT_SLOT_RANGED; ++slot) + if (Item* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot)) + if (item->GetTemplate()->ItemLevel > _maxWeaponItemLevel) + _maxWeaponItemLevel = item->GetTemplate()->ItemLevel; + } + else if (state == IN_PROGRESS) + { + // get item level (armor cannot be swapped in combat) + Map::PlayerList const& players = instance->GetPlayers(); + for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) + { + if (Player* player = itr->getSource()) + { + for (uint8 slot = EQUIPMENT_SLOT_START; slot < EQUIPMENT_SLOT_END; ++slot) + { + if (slot == EQUIPMENT_SLOT_TABARD || slot == EQUIPMENT_SLOT_BODY) + continue; + + if (Item* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot)) + { + if (slot >= EQUIPMENT_SLOT_MAINHAND && slot <= EQUIPMENT_SLOT_RANGED) + { + if (item->GetTemplate()->ItemLevel > _maxWeaponItemLevel) + _maxWeaponItemLevel = item->GetTemplate()->ItemLevel; + } + else if (item->GetTemplate()->ItemLevel > _maxArmorItemLevel) + _maxArmorItemLevel = item->GetTemplate()->ItemLevel; + } + } + } + } + } + break; } return true; @@ -497,6 +634,16 @@ class instance_ulduar : public InstanceMapScript case DATA_UNBROKEN: Unbroken = bool(data); break; + case EVENT_DESPAWN_ALGALON: + DoUpdateWorldState(WORLD_STATE_ALGALON_TIMER_ENABLED, 1); + DoUpdateWorldState(WORLD_STATE_ALGALON_DESPAWN_TIMER, 60); + _algalonTimer = 60; + _events.ScheduleEvent(EVENT_DESPAWN_ALGALON, 3600000); + _events.ScheduleEvent(EVENT_UPDATE_ALGALON_TIMER, 60000); + break; + case DATA_ALGALON_SUMMON_STATE: + _algalonSummoned = true; + break; default: break; } @@ -571,6 +718,22 @@ class instance_ulduar : public InstanceMapScript return KeeperGUIDs[1]; case BOSS_STONEBARK: return KeeperGUIDs[2]; + case DATA_SIGILDOOR_01: + return AlgalonSigilDoorGUID[0]; + case DATA_SIGILDOOR_02: + return AlgalonSigilDoorGUID[1]; + case DATA_SIGILDOOR_03: + return AlgalonSigilDoorGUID[2]; + case DATA_UNIVERSE_FLOOR_01: + return AlgalonFloorGUID[0]; + case DATA_UNIVERSE_FLOOR_02: + return AlgalonFloorGUID[1]; + case DATA_UNIVERSE_GLOBE: + return AlgalonUniverseGUID; + case DATA_ALGALON_TRAPDOOR: + return AlgalonTrapdoorGUID; + case DATA_BRANN_BRONZEBEARD_ALG: + return BrannBronzebeardAlgGUID; } return 0; @@ -593,12 +756,23 @@ class instance_ulduar : public InstanceMapScript return 0; } + bool CheckAchievementCriteriaMeet(uint32 criteriaId, Player const* , Unit const* /* = NULL */, uint32 /* = 0 */) + { + switch (criteriaId) + { + case CRITERIA_HERALD_OF_TITANS: + return _maxArmorItemLevel <= MAX_HERALD_ARMOR_ITEMLEVEL && _maxWeaponItemLevel <= MAX_HERALD_WEAPON_ITEMLEVEL; + } + + return false; + } + std::string GetSaveData() { OUT_SAVE_INST_DATA; std::ostringstream saveStream; - saveStream << "U U " << GetBossSaveData() << GetData(DATA_COLOSSUS); + saveStream << "U U " << GetBossSaveData() << GetData(DATA_COLOSSUS) << ' ' << _algalonTimer << ' ' << (_algalonSummoned ? 1 : 0); OUT_SAVE_INST_DATA_COMPLETE; return saveStream.str(); @@ -628,15 +802,68 @@ class instance_ulduar : public InstanceMapScript if (tmpState == IN_PROGRESS || tmpState > SPECIAL) tmpState = NOT_STARTED; - if (i == DATA_COLOSSUS) - SetData(i, tmpState); - else - SetBossState(i, EncounterState(tmpState)); + SetBossState(i, EncounterState(tmpState)); + } + + uint32 tempState; + loadStream >> tempState; + if (tempState == IN_PROGRESS || tempState > SPECIAL) + tempState = NOT_STARTED; + SetData(DATA_COLOSSUS, tempState); + + loadStream >> _algalonTimer; + loadStream >> tempState; + _algalonSummoned = tempState != 0; + if (_algalonSummoned && GetBossState(BOSS_ALGALON) != DONE) + { + _summonAlgalon = true; + if (_algalonTimer && _algalonTimer <= 60) + { + _events.ScheduleEvent(EVENT_UPDATE_ALGALON_TIMER, 60000); + DoUpdateWorldState(WORLD_STATE_ALGALON_TIMER_ENABLED, 1); + DoUpdateWorldState(WORLD_STATE_ALGALON_DESPAWN_TIMER, _algalonTimer); + } } } OUT_LOAD_INST_DATA_COMPLETE; } + + void Update(uint32 diff) + { + if (_events.Empty()) + return; + + _events.Update(diff); + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_UPDATE_ALGALON_TIMER: + SaveToDB(); + DoUpdateWorldState(WORLD_STATE_ALGALON_DESPAWN_TIMER, --_algalonTimer); + if (_algalonTimer) + _events.ScheduleEvent(EVENT_UPDATE_ALGALON_TIMER, 60000); + else + { + DoUpdateWorldState(WORLD_STATE_ALGALON_TIMER_ENABLED, 0); + _events.CancelEvent(EVENT_UPDATE_ALGALON_TIMER); + if (Creature* algalon = instance->GetCreature(AlgalonGUID)) + algalon->AI()->DoAction(EVENT_DESPAWN_ALGALON); + } + break; + } + } + } + + private: + EventMap _events; + uint32 _algalonTimer; + bool _summonAlgalon; + bool _algalonSummoned; + uint32 _maxArmorItemLevel; + uint32 _maxWeaponItemLevel; }; InstanceScript* GetInstanceScript(InstanceMap* map) const diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h b/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h index a31954b8a16..d35f0559080 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h @@ -21,6 +21,8 @@ #include "ObjectMgr.h" #define UlduarScriptName "instance_ulduar" +extern Position const AlgalonLandPos; + enum UlduarBosses { MAX_ENCOUNTER = 20, @@ -50,98 +52,124 @@ enum UlduarBosses enum UlduarNPCs { // General - NPC_LEVIATHAN = 33113, - NPC_SALVAGED_DEMOLISHER = 33109, - NPC_SALVAGED_SIEGE_ENGINE = 33060, - NPC_IGNIS = 33118, - NPC_RAZORSCALE = 33186, - NPC_RAZORSCALE_CONTROLLER = 33233, - NPC_STEELFORGED_DEFFENDER = 33236, - NPC_EXPEDITION_COMMANDER = 33210, - NPC_XT002 = 33293, - NPC_XT_TOY_PILE = 33337, - NPC_STEELBREAKER = 32867, - NPC_MOLGEIM = 32927, - NPC_BRUNDIR = 32857, - NPC_KOLOGARN = 32930, - NPC_FOCUSED_EYEBEAM = 33632, - NPC_FOCUSED_EYEBEAM_RIGHT = 33802, - NPC_LEFT_ARM = 32933, - NPC_RIGHT_ARM = 32934, - NPC_RUBBLE = 33768, - NPC_AURIAYA = 33515, - NPC_MIMIRON = 33350, - NPC_HODIR = 32845, - NPC_THORIM = 32865, - NPC_FREYA = 32906, - NPC_VEZAX = 33271, - NPC_YOGGSARON = 33288, - NPC_ALGALON = 32871, + NPC_LEVIATHAN = 33113, + NPC_SALVAGED_DEMOLISHER = 33109, + NPC_SALVAGED_SIEGE_ENGINE = 33060, + NPC_IGNIS = 33118, + NPC_RAZORSCALE = 33186, + NPC_RAZORSCALE_CONTROLLER = 33233, + NPC_STEELFORGED_DEFFENDER = 33236, + NPC_EXPEDITION_COMMANDER = 33210, + NPC_XT002 = 33293, + NPC_XT_TOY_PILE = 33337, + NPC_STEELBREAKER = 32867, + NPC_MOLGEIM = 32927, + NPC_BRUNDIR = 32857, + NPC_KOLOGARN = 32930, + NPC_FOCUSED_EYEBEAM = 33632, + NPC_FOCUSED_EYEBEAM_RIGHT = 33802, + NPC_LEFT_ARM = 32933, + NPC_RIGHT_ARM = 32934, + NPC_RUBBLE = 33768, + NPC_AURIAYA = 33515, + NPC_MIMIRON = 33350, + NPC_HODIR = 32845, + NPC_THORIM = 32865, + NPC_FREYA = 32906, + NPC_VEZAX = 33271, + NPC_YOGGSARON = 33288, + NPC_ALGALON = 32871, // Mimiron - NPC_LEVIATHAN_MKII = 33432, - NPC_VX_001 = 33651, - NPC_AERIAL_COMMAND_UNIT = 33670, + NPC_LEVIATHAN_MKII = 33432, + NPC_VX_001 = 33651, + NPC_AERIAL_COMMAND_UNIT = 33670, // Freya's Keepers - NPC_IRONBRANCH = 32913, - NPC_BRIGHTLEAF = 32915, - NPC_STONEBARK = 32914, + NPC_IRONBRANCH = 32913, + NPC_BRIGHTLEAF = 32915, + NPC_STONEBARK = 32914, // Hodir's Helper NPCs - NPC_TOR_GREYCLOUD = 32941, - NPC_KAR_GREYCLOUD = 33333, - NPC_EIVI_NIGHTFEATHER = 33325, - NPC_ELLIE_NIGHTFEATHER = 32901, - NPC_SPIRITWALKER_TARA = 33332, - NPC_SPIRITWALKER_YONA = 32950, - NPC_ELEMENTALIST_MAHFUUN = 33328, - NPC_ELEMENTALIST_AVUUN = 32900, - NPC_AMIRA_BLAZEWEAVER = 33331, - NPC_VEESHA_BLAZEWEAVER = 32946, - NPC_MISSY_FLAMECUFFS = 32893, - NPC_SISSY_FLAMECUFFS = 33327, - NPC_BATTLE_PRIEST_ELIZA = 32948, - NPC_BATTLE_PRIEST_GINA = 33330, - NPC_FIELD_MEDIC_PENNY = 32897, - NPC_FIELD_MEDIC_JESSI = 33326, + NPC_TOR_GREYCLOUD = 32941, + NPC_KAR_GREYCLOUD = 33333, + NPC_EIVI_NIGHTFEATHER = 33325, + NPC_ELLIE_NIGHTFEATHER = 32901, + NPC_SPIRITWALKER_TARA = 33332, + NPC_SPIRITWALKER_YONA = 32950, + NPC_ELEMENTALIST_MAHFUUN = 33328, + NPC_ELEMENTALIST_AVUUN = 32900, + NPC_AMIRA_BLAZEWEAVER = 33331, + NPC_VEESHA_BLAZEWEAVER = 32946, + NPC_MISSY_FLAMECUFFS = 32893, + NPC_SISSY_FLAMECUFFS = 33327, + NPC_BATTLE_PRIEST_ELIZA = 32948, + NPC_BATTLE_PRIEST_GINA = 33330, + NPC_FIELD_MEDIC_PENNY = 32897, + NPC_FIELD_MEDIC_JESSI = 33326, // Freya's trash NPCs - NPC_CORRUPTED_SERVITOR = 33354, - NPC_MISGUIDED_NYMPH = 33355, - NPC_GUARDIAN_LASHER = 33430, - NPC_FOREST_SWARMER = 33431, - NPC_MANGROVE_ENT = 33525, - NPC_IRONROOT_LASHER = 33526, - NPC_NATURES_BLADE = 33527, - NPC_GUARDIAN_OF_LIFE = 33528, + NPC_CORRUPTED_SERVITOR = 33354, + NPC_MISGUIDED_NYMPH = 33355, + NPC_GUARDIAN_LASHER = 33430, + NPC_FOREST_SWARMER = 33431, + NPC_MANGROVE_ENT = 33525, + NPC_IRONROOT_LASHER = 33526, + NPC_NATURES_BLADE = 33527, + NPC_GUARDIAN_OF_LIFE = 33528, + + // Algalon the Observer + NPC_BRANN_BRONZBEARD_ALG = 34064, + NPC_AZEROTH = 34246, + NPC_LIVING_CONSTELLATION = 33052, + NPC_ALGALON_STALKER = 33086, + NPC_COLLAPSING_STAR = 32955, + NPC_BLACK_HOLE = 32953, + NPC_WORM_HOLE = 34099, + NPC_ALGALON_VOID_ZONE_VISUAL_STALKER = 34100, + NPC_ALGALON_STALKER_ASTEROID_TARGET_01 = 33104, + NPC_ALGALON_STALKER_ASTEROID_TARGET_02 = 33105, + NPC_UNLEASHED_DARK_MATTER = 34097, }; enum UlduarGameObjects { - GO_KOLOGARN_CHEST_HERO = 195047, - GO_KOLOGARN_CHEST = 195046, - GO_KOLOGARN_BRIDGE = 194232, - GO_KOLOGARN_DOOR = 194553, - GO_THORIM_CHEST_HERO = 194315, - GO_THORIM_CHEST = 194314, - GO_HODIR_RARE_CACHE_OF_WINTER = 194200, - GO_HODIR_RARE_CACHE_OF_WINTER_HERO = 194201, - GO_HODIR_CHEST_HERO = 194308, - GO_HODIR_CHEST = 194307, - GO_LEVIATHAN_DOOR = 194905, - GO_LEVIATHAN_GATE = 194630, - GO_XT_002_DOOR = 194631, - GO_VEZAX_DOOR = 194750, - GO_MOLE_MACHINE = 194316, - GO_RAZOR_HARPOON_1 = 194542, - GO_RAZOR_HARPOON_2 = 194541, - GO_RAZOR_HARPOON_3 = 194543, - GO_RAZOR_HARPOON_4 = 194519, - GO_RAZOR_BROKEN_HARPOON = 194565, - GO_HODIR_DOOR = 194634, - GO_HODIR_ICE_DOOR = 194441, - GO_ARCHIVUM_DOOR = 194556, + GO_KOLOGARN_CHEST_HERO = 195047, + GO_KOLOGARN_CHEST = 195046, + GO_KOLOGARN_BRIDGE = 194232, + GO_KOLOGARN_DOOR = 194553, + GO_THORIM_CHEST_HERO = 194315, + GO_THORIM_CHEST = 194314, + GO_HODIR_RARE_CACHE_OF_WINTER = 194200, + GO_HODIR_RARE_CACHE_OF_WINTER_HERO = 194201, + GO_HODIR_CHEST_HERO = 194308, + GO_HODIR_CHEST = 194307, + GO_LEVIATHAN_DOOR = 194905, + GO_LEVIATHAN_GATE = 194630, + GO_XT_002_DOOR = 194631, + GO_VEZAX_DOOR = 194750, + GO_MOLE_MACHINE = 194316, + GO_RAZOR_HARPOON_1 = 194542, + GO_RAZOR_HARPOON_2 = 194541, + GO_RAZOR_HARPOON_3 = 194543, + GO_RAZOR_HARPOON_4 = 194519, + GO_RAZOR_BROKEN_HARPOON = 194565, + GO_HODIR_DOOR = 194634, + GO_HODIR_ICE_DOOR = 194441, + GO_ARCHIVUM_DOOR = 194556, + + // Algalon the Observer + GO_CELESTIAL_PLANETARIUM_ACCESS_10 = 194628, + GO_CELESTIAL_PLANETARIUM_ACCESS_25 = 194752, + GO_DOODAD_UL_SIGILDOOR_01 = 194767, + GO_DOODAD_UL_SIGILDOOR_02 = 194911, + GO_DOODAD_UL_SIGILDOOR_03 = 194910, + GO_DOODAD_UL_UNIVERSEFLOOR_01 = 194715, + GO_DOODAD_UL_UNIVERSEFLOOR_02 = 194716, + GO_DOODAD_UL_UNIVERSEGLOBE01 = 194148, + GO_DOODAD_UL_ULDUAR_TRAPDOOR_03 = 194253, + GO_GIFT_OF_THE_OBSERVER_10 = 194821, + GO_GIFT_OF_THE_OBSERVER_25 = 194822, }; enum LeviathanData @@ -161,6 +189,7 @@ enum UlduarAchievementCriteriaIds { CRITERIA_CON_SPEED_ATORY = 21597, CRITERIA_DISARMED = 21687, + CRITERIA_HERALD_OF_TITANS = 10678, }; enum UlduarData @@ -180,12 +209,38 @@ enum UlduarData // Hodir DATA_HODIR_RARE_CACHE, + + // Algalon the Observer + DATA_ALGALON_SUMMON_STATE, + DATA_SIGILDOOR_01, + DATA_SIGILDOOR_02, + DATA_SIGILDOOR_03, + DATA_UNIVERSE_FLOOR_01, + DATA_UNIVERSE_FLOOR_02, + DATA_UNIVERSE_GLOBE, + DATA_ALGALON_TRAPDOOR, + DATA_BRANN_BRONZEBEARD_ALG, +}; + +enum UlduarWorldStates +{ + WORLD_STATE_ALGALON_DESPAWN_TIMER = 4131, + WORLD_STATE_ALGALON_TIMER_ENABLED = 4132, }; enum UlduarAchievementData { // FL Achievement boolean DATA_UNBROKEN = 29052906, // 2905, 2906 are achievement IDs, + MAX_HERALD_ARMOR_ITEMLEVEL = 226, + MAX_HERALD_WEAPON_ITEMLEVEL = 232, +}; + +enum UlduarEvents +{ + EVENT_DESPAWN_ALGALON = 1, + EVENT_UPDATE_ALGALON_TIMER = 2, + ACTION_INIT_ALGALON = 6, }; template<class AI> @@ -199,6 +254,17 @@ CreatureAI* GetUlduarAI(Creature* creature) return NULL; } +template<class AI> +GameObjectAI* GetUlduarAI(GameObject* go) +{ + if (InstanceMap* instance = go->GetMap()->ToInstanceMap()) + if (instance->GetInstanceScript()) + if (instance->GetScriptId() == sObjectMgr->GetScriptId(UlduarScriptName)) + return new AI(go); + + return NULL; +} + class PlayerOrPetCheck { public: diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp index 26ac516f209..a7853a07e22 100644 --- a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp +++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp @@ -344,7 +344,7 @@ public: { if (type != POINT_MOTION_TYPE) return; - Unit* ingvar = Unit::GetUnit((*me), instance ? instance->GetData64(DATA_INGVAR) : 0); + Unit* ingvar = Unit::GetUnit(*me, instance ? instance->GetData64(DATA_INGVAR) : 0); if (ingvar) { switch (id) diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_skarvald_dalronn.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_skarvald_dalronn.cpp index 3db9a785f74..915d1c71bb2 100644 --- a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_skarvald_dalronn.cpp +++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_skarvald_dalronn.cpp @@ -93,7 +93,7 @@ public: ghost = (me->GetEntry() == MOB_SKARVALD_GHOST); if (!ghost && instance) { - Unit* dalronn = Unit::GetUnit((*me), instance->GetData64(DATA_DALRONN)); + Unit* dalronn = Unit::GetUnit(*me, instance->GetData64(DATA_DALRONN)); if (dalronn && dalronn->isDead()) CAST_CRE(dalronn)->Respawn(); @@ -107,7 +107,7 @@ public: { DoScriptText(YELL_SKARVALD_AGGRO, me); - Unit* dalronn = Unit::GetUnit((*me), instance->GetData64(DATA_DALRONN)); + Unit* dalronn = Unit::GetUnit(*me, instance->GetData64(DATA_DALRONN)); if (dalronn && dalronn->isAlive() && !dalronn->getVictim()) dalronn->getThreatManager().addThreat(who, 0.0f); @@ -119,7 +119,7 @@ public: { if (!ghost && instance) { - Unit* dalronn = Unit::GetUnit((*me), instance->GetData64(DATA_DALRONN)); + Unit* dalronn = Unit::GetUnit(*me, instance->GetData64(DATA_DALRONN)); if (dalronn) { if (dalronn->isDead()) @@ -250,7 +250,7 @@ public: ghost = me->GetEntry() == MOB_DALRONN_GHOST; if (!ghost && instance) { - Unit* skarvald = Unit::GetUnit((*me), instance->GetData64(DATA_SKARVALD)); + Unit* skarvald = Unit::GetUnit(*me, instance->GetData64(DATA_SKARVALD)); if (skarvald && skarvald->isDead()) CAST_CRE(skarvald)->Respawn(); @@ -262,7 +262,7 @@ public: { if (!ghost && instance) { - Unit* skarvald = Unit::GetUnit((*me), instance->GetData64(DATA_SKARVALD)); + Unit* skarvald = Unit::GetUnit(*me, instance->GetData64(DATA_SKARVALD)); if (skarvald && skarvald->isAlive() && !skarvald->getVictim()) skarvald->getThreatManager().addThreat(who, 0.0f); @@ -277,7 +277,7 @@ public: { if (!ghost && instance) { - Unit* skarvald = Unit::GetUnit((*me), instance->GetData64(DATA_SKARVALD)); + Unit* skarvald = Unit::GetUnit(*me, instance->GetData64(DATA_SKARVALD)); if (skarvald) { if (skarvald->isDead()) diff --git a/src/server/scripts/Northrend/VaultOfArchavon/boss_emalon.cpp b/src/server/scripts/Northrend/VaultOfArchavon/boss_emalon.cpp index dc58e51a5a1..4980ed36ec3 100644 --- a/src/server/scripts/Northrend/VaultOfArchavon/boss_emalon.cpp +++ b/src/server/scripts/Northrend/VaultOfArchavon/boss_emalon.cpp @@ -139,7 +139,7 @@ class boss_emalon : public CreatureScript case EVENT_OVERCHARGE: if (!summons.empty()) { - Creature* minion = Unit::GetCreature(*me, SelectRandomContainerElement(summons)); + Creature* minion = Unit::GetCreature(*me, Trinity::Containers::SelectRandomContainerElement(summons)); if (minion && minion->isAlive()) { minion->CastSpell(me, SPELL_OVERCHARGED, true); diff --git a/src/server/scripts/Northrend/VioletHold/instance_violet_hold.cpp b/src/server/scripts/Northrend/VioletHold/instance_violet_hold.cpp index 79c54880430..37a13388b5f 100644 --- a/src/server/scripts/Northrend/VioletHold/instance_violet_hold.cpp +++ b/src/server/scripts/Northrend/VioletHold/instance_violet_hold.cpp @@ -690,7 +690,8 @@ public: { AddWave(); bActive = false; - uiActivationTimer = 5000; + // 1 minute waiting time after each boss fight + uiActivationTimer = (uiWaveCount == 6 || uiWaveCount == 12) ? 60000 : 5000; } else uiActivationTimer -= diff; } diff --git a/src/server/scripts/Northrend/borean_tundra.cpp b/src/server/scripts/Northrend/borean_tundra.cpp index f83538b344c..8b51618eedd 100644 --- a/src/server/scripts/Northrend/borean_tundra.cpp +++ b/src/server/scripts/Northrend/borean_tundra.cpp @@ -186,7 +186,7 @@ public: if (owner->GetTypeId() == TYPEID_PLAYER) { owner->CastSpell(owner, 46231, true); - CAST_CRE(who)->ForcedDespawn(); + CAST_CRE(who)->DespawnOrUnsummon(); } } } diff --git a/src/server/scripts/Northrend/sholazar_basin.cpp b/src/server/scripts/Northrend/sholazar_basin.cpp index 37c0e9fc976..93d0182ea08 100644 --- a/src/server/scripts/Northrend/sholazar_basin.cpp +++ b/src/server/scripts/Northrend/sholazar_basin.cpp @@ -306,10 +306,9 @@ public: if (me->isDead()) return; - if (me->isSummon()) - if (Unit* summoner = me->ToTempSummon()->GetSummoner()) - if (summoner) - me->GetMotionMaster()->MovePoint(0, summoner->GetPositionX(), summoner->GetPositionY(), summoner->GetPositionZ()); + if (TempSummon* summ = me->ToTempSummon()) + if (Unit* summoner = summ->GetSummoner()) + me->GetMotionMaster()->MovePoint(0, summoner->GetPositionX(), summoner->GetPositionY(), summoner->GetPositionZ()); Reset(); } diff --git a/src/server/scripts/Northrend/storm_peaks.cpp b/src/server/scripts/Northrend/storm_peaks.cpp index 3560774ce0d..15239e9f836 100644 --- a/src/server/scripts/Northrend/storm_peaks.cpp +++ b/src/server/scripts/Northrend/storm_peaks.cpp @@ -550,7 +550,7 @@ public: // drake unsummoned, passengers dropped if (!me->IsOnVehicle(drake) && !hasEmptySeats) - me->ForcedDespawn(3000); + me->DespawnOrUnsummon(3000); if (enter_timer <= 0) return; @@ -567,9 +567,9 @@ public: enter_timer -= diff; } - void MoveInLineOfSight(Unit* unit) + void MoveInLineOfSight(Unit* who) { - if (!unit || !drakeGUID) + if (!who || !drakeGUID) return; Creature* drake = Unit::GetCreature(*me, drakeGUID); @@ -581,21 +581,21 @@ public: if (!me->IsOnVehicle(drake) && !me->HasAura(SPELL_ICE_PRISON)) { - if (unit->IsVehicle() && me->IsWithinDist(unit, 25.0f, true) && unit->ToCreature() && unit->ToCreature()->GetEntry() == 29709) + if (who->IsVehicle() && me->IsWithinDist(who, 25.0f, true) && who->ToCreature() && who->ToCreature()->GetEntry() == 29709) { - uint8 seat = unit->GetVehicleKit()->GetNextEmptySeat(0, true); + uint8 seat = who->GetVehicleKit()->GetNextEmptySeat(0, true); if (seat <= 0) return; - me->EnterVehicle(unit, seat); + me->EnterVehicle(who, seat); me->SendMovementFlagUpdate(); hasEmptySeats = false; } } - if (unit->ToCreature() && me->IsOnVehicle(drake)) + if (who->ToCreature() && me->IsOnVehicle(drake)) { - if (unit->ToCreature()->GetEntry() == NPC_QUEST_GIVER && me->IsWithinDist(unit, 15.0f, false)) + if (who->ToCreature()->GetEntry() == NPC_QUEST_GIVER && me->IsWithinDist(who, 15.0f, false)) { Unit* rider = drake->GetVehicleKit()->GetPassenger(0); if (!rider) @@ -605,7 +605,7 @@ public: me->ExitVehicle(); me->CastSpell(me, SPELL_SUMMON_LIBERATED, true); - me->ForcedDespawn(500); + me->DespawnOrUnsummon(500); // drake is empty now, deliver credit for drake and despawn him if (drake->GetVehicleKit()->HasEmptySeat(1) && @@ -616,7 +616,7 @@ public: if (rider->ToPlayer()) rider->ToPlayer()->KilledMonsterCredit(29709, 0); - drake->ToCreature()->ForcedDespawn(0); + drake->DespawnOrUnsummon(0); } } } @@ -748,14 +748,14 @@ class npc_hyldsmeet_protodrake : public CreatureScript void AddSC_storm_peaks() { - new npc_agnetta_tyrsdottar; - new npc_frostborn_scout; - new npc_thorim; - new npc_victorious_challenger; - new npc_loklira_crone; - new npc_injured_goblin; - new npc_roxi_ramrocket; - new npc_brunnhildar_prisoner; - new npc_icefang; - new npc_hyldsmeet_protodrake; + new npc_agnetta_tyrsdottar(); + new npc_frostborn_scout(); + new npc_thorim(); + new npc_victorious_challenger(); + new npc_loklira_crone(); + new npc_injured_goblin(); + new npc_roxi_ramrocket(); + new npc_brunnhildar_prisoner(); + new npc_icefang(); + new npc_hyldsmeet_protodrake(); } diff --git a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_grandmaster_vorpil.cpp b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_grandmaster_vorpil.cpp index e47810c74f7..8d971c37559 100644 --- a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_grandmaster_vorpil.cpp +++ b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_grandmaster_vorpil.cpp @@ -201,7 +201,7 @@ public: { for (uint8 i = 0; i < 5; ++i) { - Unit* Portal = Unit::GetUnit((*me), PortalsGuid[i]); + Unit* Portal = Unit::GetUnit(*me, PortalsGuid[i]); if (Portal && Portal->isAlive()) Portal->DealDamage(Portal, Portal->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); PortalsGuid[i] = 0; diff --git a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_murmur.cpp b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_murmur.cpp index be4f3107d05..99661d8818c 100644 --- a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_murmur.cpp +++ b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_murmur.cpp @@ -166,7 +166,7 @@ public: { std::list<HostileReference*>& m_threatlist = me->getThreatManager().getThreatList(); for (std::list<HostileReference*>::const_iterator i = m_threatlist.begin(); i != m_threatlist.end(); ++i) - if (Unit* target = Unit::GetUnit((*me), (*i)->getUnitGuid())) + if (Unit* target = Unit::GetUnit(*me, (*i)->getUnitGuid())) if (target->isAlive() && !me->IsWithinDist(target, 35, false)) DoCast(target, SPELL_THUNDERING_STORM, true); ThunderingStorm_Timer = 15000; @@ -189,7 +189,7 @@ public: { std::list<HostileReference*>& m_threatlist = me->getThreatManager().getThreatList(); for (std::list<HostileReference*>::const_iterator i = m_threatlist.begin(); i != m_threatlist.end(); ++i) - if (Unit* target = Unit::GetUnit((*me), (*i)->getUnitGuid())) + if (Unit* target = Unit::GetUnit(*me, (*i)->getUnitGuid())) if (target->isAlive() && me->IsWithinMeleeRange(target)) { me->TauntApply(target); diff --git a/src/server/scripts/Outland/BlackTemple/boss_bloodboil.cpp b/src/server/scripts/Outland/BlackTemple/boss_bloodboil.cpp index 7ae09e925a5..caac89da765 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_bloodboil.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_bloodboil.cpp @@ -186,7 +186,7 @@ public: void RevertThreatOnTarget(uint64 guid) { Unit* unit = NULL; - unit = Unit::GetUnit((*me), guid); + unit = Unit::GetUnit(*me, guid); if (unit) { if (DoGetThreat(unit)) diff --git a/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp b/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp index 8925f2899f5..1926929c97c 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp @@ -865,7 +865,7 @@ public: { if (GlaiveGUID[i]) { - Unit* Glaive = Unit::GetUnit((*me), GlaiveGUID[i]); + Unit* Glaive = Unit::GetUnit(*me, GlaiveGUID[i]); if (Glaive) { Glaive->CastSpell(me, SPELL_GLAIVE_RETURNS, false); // Make it look like the Glaive flies back up to us @@ -1492,7 +1492,7 @@ public: std::vector<Unit*> eliteList; for (std::list<HostileReference*>::const_iterator itr = threatList.begin(); itr != threatList.end(); ++itr) { - Unit* unit = Unit::GetUnit((*me), (*itr)->getUnitGuid()); + Unit* unit = Unit::GetUnit(*me, (*itr)->getUnitGuid()); if (unit && unit->GetEntry() == ILLIDARI_ELITE) eliteList.push_back(unit); } @@ -1649,9 +1649,9 @@ public: Unit* Channel = NULL, *Spirit[2] = { NULL, NULL }; if (ChannelCount <= 5) { - Channel = Unit::GetUnit((*me), ChannelGUID); - Spirit[0] = Unit::GetUnit((*me), SpiritGUID[0]); - Spirit[1] = Unit::GetUnit((*me), SpiritGUID[1]); + Channel = Unit::GetUnit(*me, ChannelGUID); + Spirit[0] = Unit::GetUnit(*me, SpiritGUID[0]); + Spirit[1] = Unit::GetUnit(*me, SpiritGUID[1]); if (!Channel || !Spirit[0] || !Spirit[1]) return; } @@ -2145,7 +2145,7 @@ public: void JustDied(Unit* /*killer*/) { - if (Unit* target = Unit::GetUnit((*me), TargetGUID)) + if (Unit* target = Unit::GetUnit(*me, TargetGUID)) target->RemoveAurasDueToSpell(SPELL_PARALYZE); } diff --git a/src/server/scripts/Outland/BlackTemple/boss_mother_shahraz.cpp b/src/server/scripts/Outland/BlackTemple/boss_mother_shahraz.cpp index f5b2e3efa92..4e4607a7d44 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_mother_shahraz.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_mother_shahraz.cpp @@ -250,7 +250,7 @@ public: Unit* unit = NULL; if (TargetGUID[i]) { - unit = Unit::GetUnit((*me), TargetGUID[i]); + unit = Unit::GetUnit(*me, TargetGUID[i]); if (unit) unit->CastSpell(unit, SPELL_ATTRACTION, true); TargetGUID[i] = 0; diff --git a/src/server/scripts/Outland/BlackTemple/boss_reliquary_of_souls.cpp b/src/server/scripts/Outland/BlackTemple/boss_reliquary_of_souls.cpp index 70f27d6caf9..c5e78f2fa7b 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_reliquary_of_souls.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_reliquary_of_souls.cpp @@ -219,7 +219,7 @@ public: std::list<HostileReference*>::const_iterator itr = m_threatlist.begin(); for (; itr != m_threatlist.end(); ++itr) { - Unit* unit = Unit::GetUnit((*me), (*itr)->getUnitGuid()); + Unit* unit = Unit::GetUnit(*me, (*itr)->getUnitGuid()); if (unit) { DoModifyThreatPercent(unit, -100); @@ -441,7 +441,7 @@ public: std::list<HostileReference*>::const_iterator itr = m_threatlist.begin(); for (; itr != m_threatlist.end(); ++itr) { - Unit* unit = Unit::GetUnit((*me), (*itr)->getUnitGuid()); + Unit* unit = Unit::GetUnit(*me, (*itr)->getUnitGuid()); if (unit && unit->isAlive() && (unit->GetTypeId() == TYPEID_PLAYER)) // Only alive players targets.push_back(unit); } diff --git a/src/server/scripts/Outland/BlackTemple/boss_supremus.cpp b/src/server/scripts/Outland/BlackTemple/boss_supremus.cpp index cd804ad0d03..ce1732433c8 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_supremus.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_supremus.cpp @@ -134,7 +134,8 @@ public: if (!phase || phase == PHASE_CHASE) { phase = PHASE_STRIKE; - summons.DoAction(EVENT_VOLCANO, 0); + DummyEntryCheckPredicate pred; + summons.DoAction(EVENT_VOLCANO, pred); events.ScheduleEvent(EVENT_HATEFUL_STRIKE, 5000, GCD_CAST, PHASE_STRIKE); me->SetSpeed(MOVE_RUN, 1.2f); me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, false); @@ -184,7 +185,7 @@ public: std::list<HostileReference*>::const_iterator i = m_threatlist.begin(); for (i = m_threatlist.begin(); i!= m_threatlist.end(); ++i) { - Unit* unit = Unit::GetUnit((*me), (*i)->getUnitGuid()); + Unit* unit = Unit::GetUnit(*me, (*i)->getUnitGuid()); if (unit && me->IsWithinMeleeRange(unit)) { if (unit->GetHealth() > health) diff --git a/src/server/scripts/Outland/BlackTemple/boss_teron_gorefiend.cpp b/src/server/scripts/Outland/BlackTemple/boss_teron_gorefiend.cpp index 4edd8b23a47..bc12a6c1c6c 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_teron_gorefiend.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_teron_gorefiend.cpp @@ -175,7 +175,7 @@ public: std::list<Unit*> targets; for (; itr != m_threatlist.end(); ++itr) { - Unit* unit = Unit::GetUnit((*me), (*itr)->getUnitGuid()); + Unit* unit = Unit::GetUnit(*me, (*itr)->getUnitGuid()); if (unit && unit->isAlive()) targets.push_back(unit); } @@ -325,7 +325,7 @@ public: std::list<HostileReference*>::const_iterator i = m_threatlist.begin(); for (i = m_threatlist.begin(); i != m_threatlist.end(); ++i) { - Unit* unit = Unit::GetUnit((*me), (*i)->getUnitGuid()); + Unit* unit = Unit::GetUnit(*me, (*i)->getUnitGuid()); if (unit && unit->isAlive()) { float threat = DoGetThreat(unit); @@ -345,7 +345,7 @@ public: Unit* Ghost = NULL; if (GhostGUID) - Ghost = Unit::GetUnit((*me), GhostGUID); + Ghost = Unit::GetUnit(*me, GhostGUID); if (Ghost && Ghost->isAlive() && Ghost->HasAura(SPELL_SHADOW_OF_DEATH)) { /*float x, y, z; @@ -392,7 +392,7 @@ public: Done = true; if (AggroTargetGUID) { - Unit* unit = Unit::GetUnit((*me), AggroTargetGUID); + Unit* unit = Unit::GetUnit(*me, AggroTargetGUID); if (unit) AttackStart(unit); diff --git a/src/server/scripts/Outland/BlackTemple/illidari_council.cpp b/src/server/scripts/Outland/BlackTemple/illidari_council.cpp index a0e85e1b334..0742f174ccf 100644 --- a/src/server/scripts/Outland/BlackTemple/illidari_council.cpp +++ b/src/server/scripts/Outland/BlackTemple/illidari_council.cpp @@ -299,7 +299,7 @@ public: Unit* Member = NULL; if (Council[i]) { - Member = Unit::GetUnit((*me), Council[i]); + Member = Unit::GetUnit(*me, Council[i]); if (Member && Member->isAlive()) CAST_CRE(Member)->AI()->AttackStart(target); } @@ -512,7 +512,7 @@ public: member = urand(1, 3); if (member != 2) // No need to create another pointer to us using Unit::GetUnit - unit = Unit::GetUnit((*me), Council[member]); + unit = Unit::GetUnit(*me, Council[member]); return unit; } @@ -526,7 +526,7 @@ public: } for (uint8 i = 0; i < 4; ++i) { - Unit* unit = Unit::GetUnit((*me), Council[i]); + Unit* unit = Unit::GetUnit(*me, Council[i]); if (unit) unit->CastSpell(unit, spellid, true, 0, 0, me->GetGUID()); } diff --git a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_fathomlord_karathress.cpp b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_fathomlord_karathress.cpp index 9af79de7426..206ba3d9455 100644 --- a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_fathomlord_karathress.cpp +++ b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_fathomlord_karathress.cpp @@ -225,7 +225,7 @@ public: //Only if not incombat check if the event is started if (!me->isInCombat() && instance && instance->GetData(DATA_KARATHRESSEVENT)) { - Unit* target = Unit::GetUnit((*me), instance->GetData64(DATA_KARATHRESSEVENT_STARTER)); + Unit* target = Unit::GetUnit(*me, instance->GetData64(DATA_KARATHRESSEVENT_STARTER)); if (target) { @@ -381,7 +381,7 @@ public: //Only if not incombat check if the event is started if (!me->isInCombat() && instance && instance->GetData(DATA_KARATHRESSEVENT)) { - Unit* target = Unit::GetUnit((*me), instance->GetData64(DATA_KARATHRESSEVENT_STARTER)); + Unit* target = Unit::GetUnit(*me, instance->GetData64(DATA_KARATHRESSEVENT_STARTER)); if (target) { @@ -522,7 +522,7 @@ public: //Only if not incombat check if the event is started if (!me->isInCombat() && instance && instance->GetData(DATA_KARATHRESSEVENT)) { - Unit* target = Unit::GetUnit((*me), instance->GetData64(DATA_KARATHRESSEVENT_STARTER)); + Unit* target = Unit::GetUnit(*me, instance->GetData64(DATA_KARATHRESSEVENT_STARTER)); if (target) { @@ -648,7 +648,7 @@ public: //Only if not incombat check if the event is started if (!me->isInCombat() && instance && instance->GetData(DATA_KARATHRESSEVENT)) { - Unit* target = Unit::GetUnit((*me), instance->GetData64(DATA_KARATHRESSEVENT_STARTER)); + Unit* target = Unit::GetUnit(*me, instance->GetData64(DATA_KARATHRESSEVENT_STARTER)); if (target) { @@ -730,13 +730,13 @@ public: switch (rand()%4) { case 0: - unit = Unit::GetUnit((*me), instance->GetData64(DATA_KARATHRESS)); + unit = Unit::GetUnit(*me, instance->GetData64(DATA_KARATHRESS)); break; case 1: - unit = Unit::GetUnit((*me), instance->GetData64(DATA_SHARKKIS)); + unit = Unit::GetUnit(*me, instance->GetData64(DATA_SHARKKIS)); break; case 2: - unit = Unit::GetUnit((*me), instance->GetData64(DATA_TIDALVESS)); + unit = Unit::GetUnit(*me, instance->GetData64(DATA_TIDALVESS)); break; case 3: unit = me; diff --git a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lady_vashj.cpp b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lady_vashj.cpp index b614a5afa3a..18d8b2b5a1e 100644 --- a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lady_vashj.cpp +++ b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lady_vashj.cpp @@ -783,7 +783,7 @@ public: if (instance) { // check if vashj is death - Unit* Vashj = Unit::GetUnit((*me), instance->GetData64(DATA_LADYVASHJ)); + Unit* Vashj = Unit::GetUnit(*me, instance->GetData64(DATA_LADYVASHJ)); if (!Vashj || (Vashj && !Vashj->isAlive()) || (Vashj && CAST_AI(boss_lady_vashj::boss_lady_vashjAI, CAST_CRE(Vashj)->AI())->Phase != 3)) { // remove @@ -839,7 +839,7 @@ public: if (CheckTimer <= diff) { - Unit* vashj = Unit::GetUnit((*me), instance->GetData64(DATA_LADYVASHJ)); + Unit* vashj = Unit::GetUnit(*me, instance->GetData64(DATA_LADYVASHJ)); if (vashj && vashj->isAlive()) { diff --git a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_leotheras_the_blind.cpp b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_leotheras_the_blind.cpp index 35d5ab7793b..4876410890c 100644 --- a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_leotheras_the_blind.cpp +++ b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_leotheras_the_blind.cpp @@ -111,7 +111,7 @@ public: void JustDied(Unit* /*killer*/) { - Unit* unit = Unit::GetUnit((*me), victimGUID); + Unit* unit = Unit::GetUnit(*me, victimGUID); if (unit && unit->HasAura(SPELL_INSIDIOUS_WHISPER)) unit->RemoveAurasDueToSpell(SPELL_INSIDIOUS_WHISPER); } @@ -140,7 +140,7 @@ public: if (me->getVictim()->GetGUID() != victimGUID) { DoModifyThreatPercent(me->getVictim(), -100); - Unit* owner = Unit::GetUnit((*me), victimGUID); + Unit* owner = Unit::GetUnit(*me, victimGUID); if (owner && owner->isAlive()) { me->AddThreat(owner, 999999); diff --git a/src/server/scripts/Outland/CoilfangReservoir/SteamVault/boss_mekgineer_steamrigger.cpp b/src/server/scripts/Outland/CoilfangReservoir/SteamVault/boss_mekgineer_steamrigger.cpp index 77f521e5094..739168863f4 100644 --- a/src/server/scripts/Outland/CoilfangReservoir/SteamVault/boss_mekgineer_steamrigger.cpp +++ b/src/server/scripts/Outland/CoilfangReservoir/SteamVault/boss_mekgineer_steamrigger.cpp @@ -231,7 +231,7 @@ public: { if (instance && instance->GetData64(DATA_MEKGINEERSTEAMRIGGER) && instance->GetData(TYPE_MEKGINEER_STEAMRIGGER) == IN_PROGRESS) { - if (Unit* pMekgineer = Unit::GetUnit((*me), instance->GetData64(DATA_MEKGINEERSTEAMRIGGER))) + if (Unit* pMekgineer = Unit::GetUnit(*me, instance->GetData64(DATA_MEKGINEERSTEAMRIGGER))) { if (me->IsWithinDistInMap(pMekgineer, MAX_REPAIR_RANGE)) { diff --git a/src/server/scripts/Outland/GruulsLair/boss_high_king_maulgar.cpp b/src/server/scripts/Outland/GruulsLair/boss_high_king_maulgar.cpp index de4b23d5f6d..0f42b1b7e53 100644 --- a/src/server/scripts/Outland/GruulsLair/boss_high_king_maulgar.cpp +++ b/src/server/scripts/Outland/GruulsLair/boss_high_king_maulgar.cpp @@ -223,7 +223,7 @@ public: //Only if not incombat check if the event is started if (!me->isInCombat() && instance && instance->GetData(DATA_MAULGAREVENT)) { - Unit* target = Unit::GetUnit((*me), instance->GetData64(DATA_MAULGAREVENT_TANK)); + Unit* target = Unit::GetUnit(*me, instance->GetData64(DATA_MAULGAREVENT_TANK)); if (target) { @@ -383,7 +383,7 @@ public: //Only if not incombat check if the event is started if (!me->isInCombat() && instance && instance->GetData(DATA_MAULGAREVENT)) { - Unit* target = Unit::GetUnit((*me), instance->GetData64(DATA_MAULGAREVENT_TANK)); + Unit* target = Unit::GetUnit(*me, instance->GetData64(DATA_MAULGAREVENT_TANK)); if (target) { @@ -498,7 +498,7 @@ public: //Only if not incombat check if the event is started if (!me->isInCombat() && instance && instance->GetData(DATA_MAULGAREVENT)) { - Unit* target = Unit::GetUnit((*me), instance->GetData64(DATA_MAULGAREVENT_TANK)); + Unit* target = Unit::GetUnit(*me, instance->GetData64(DATA_MAULGAREVENT_TANK)); if (target) { @@ -618,7 +618,7 @@ public: //Only if not incombat check if the event is started if (!me->isInCombat() && instance && instance->GetData(DATA_MAULGAREVENT)) { - Unit* target = Unit::GetUnit((*me), instance->GetData64(DATA_MAULGAREVENT_TANK)); + Unit* target = Unit::GetUnit(*me, instance->GetData64(DATA_MAULGAREVENT_TANK)); if (target) { @@ -728,7 +728,7 @@ public: //Only if not incombat check if the event is started if (!me->isInCombat() && instance && instance->GetData(DATA_MAULGAREVENT)) { - Unit* target = Unit::GetUnit((*me), instance->GetData64(DATA_MAULGAREVENT_TANK)); + Unit* target = Unit::GetUnit(*me, instance->GetData64(DATA_MAULGAREVENT_TANK)); if (target) { diff --git a/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_warchief_kargath_bladefist.cpp b/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_warchief_kargath_bladefist.cpp index f92a163f553..c1489671292 100644 --- a/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_warchief_kargath_bladefist.cpp +++ b/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_warchief_kargath_bladefist.cpp @@ -166,7 +166,7 @@ class boss_warchief_kargath_bladefist : public CreatureScript { for (std::vector<uint64>::const_iterator itr = adds.begin(); itr!= adds.end(); ++itr) { - Unit* temp = Unit::GetUnit((*me), *itr); + Unit* temp = Unit::GetUnit(*me, *itr); if (temp && temp->isAlive()) { (*temp).GetMotionMaster()->Clear(true); @@ -178,7 +178,7 @@ class boss_warchief_kargath_bladefist : public CreatureScript for (std::vector<uint64>::const_iterator itr = assassins.begin(); itr!= assassins.end(); ++itr) { - Unit* temp = Unit::GetUnit((*me), *itr); + Unit* temp = Unit::GetUnit(*me, *itr); if (temp && temp->isAlive()) { (*temp).GetMotionMaster()->Clear(true); diff --git a/src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp b/src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp index 074ce08ca33..77c07f5fe4d 100644 --- a/src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp +++ b/src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp @@ -500,7 +500,7 @@ class mob_ember_of_alar : public CreatureScript me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); if (instance && instance->GetData(DATA_ALAREVENT) == 2) { - if (Unit* Alar = Unit::GetUnit((*me), instance->GetData64(DATA_ALAR))) + if (Unit* Alar = Unit::GetUnit(*me, instance->GetData64(DATA_ALAR))) { int32 AlarHealth = int32(Alar->GetHealth()) - int32(Alar->CountPctFromMaxHealth(3)); if (AlarHealth > 0) diff --git a/src/server/scripts/Outland/TempestKeep/Eye/boss_astromancer.cpp b/src/server/scripts/Outland/TempestKeep/Eye/boss_astromancer.cpp index 010b741caef..c0203150789 100644 --- a/src/server/scripts/Outland/TempestKeep/Eye/boss_astromancer.cpp +++ b/src/server/scripts/Outland/TempestKeep/Eye/boss_astromancer.cpp @@ -454,7 +454,7 @@ class mob_solarium_priest : public CreatureScript { case 0: if (instance) - target = Unit::GetUnit((*me), instance->GetData64(DATA_ASTROMANCER)); + target = Unit::GetUnit(*me, instance->GetData64(DATA_ASTROMANCER)); break; case 1: target = me; diff --git a/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp b/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp index 318d9c629b9..1d8c7e71bef 100644 --- a/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp +++ b/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp @@ -253,7 +253,7 @@ struct advisorbase_ai : public ScriptedAI DelayRes_Timer = 0; FakeDeath = false; - Unit* Target = Unit::GetUnit((*me), DelayRes_Target); + Unit* Target = Unit::GetUnit(*me, DelayRes_Target); if (!Target) Target = me->getVictim(); @@ -464,7 +464,7 @@ class boss_kaelthas : public CreatureScript for (uint8 i = 0; i < MAX_ADVISORS; ++i) { - if (Unit* pAdvisor = Unit::GetUnit((*me), m_auiAdvisorGuid[i])) + if (Unit* pAdvisor = Unit::GetUnit(*me, m_auiAdvisorGuid[i])) pAdvisor->Kill(pAdvisor); } } @@ -895,7 +895,7 @@ class boss_kaelthas : public CreatureScript // 1) Kael'thas will portal the whole raid right into his body for (i = me->getThreatManager().getThreatList().begin(); i!= me->getThreatManager().getThreatList().end(); ++i) { - Unit* unit = Unit::GetUnit((*me), (*i)->getUnitGuid()); + Unit* unit = Unit::GetUnit(*me, (*i)->getUnitGuid()); if (unit && (unit->GetTypeId() == TYPEID_PLAYER)) { //Use work around packet to prevent player from being dropped from combat @@ -916,7 +916,7 @@ class boss_kaelthas : public CreatureScript // 2) At that point he will put a Gravity Lapse debuff on everyone for (i = me->getThreatManager().getThreatList().begin(); i != me->getThreatManager().getThreatList().end(); ++i) { - if (Unit* unit = Unit::GetUnit((*me), (*i)->getUnitGuid())) + if (Unit* unit = Unit::GetUnit(*me, (*i)->getUnitGuid())) { DoCast(unit, SPELL_KNOCKBACK, true); //Gravity lapse - needs an exception in Spell system to work @@ -949,7 +949,7 @@ class boss_kaelthas : public CreatureScript //Remove flight for (i = me->getThreatManager().getThreatList().begin(); i!= me->getThreatManager().getThreatList().end(); ++i) { - if (Unit* unit = Unit::GetUnit((*me), (*i)->getUnitGuid())) + if (Unit* unit = Unit::GetUnit(*me, (*i)->getUnitGuid())) { //Using packet workaround WorldPacket data(12); @@ -1289,7 +1289,7 @@ class boss_grand_astromancer_capernian : public CreatureScript std::list<HostileReference*>& m_threatlist = me->getThreatManager().getThreatList(); for (std::list<HostileReference*>::const_iterator i = m_threatlist.begin(); i!= m_threatlist.end(); ++i) { - Unit* unit = Unit::GetUnit((*me), (*i)->getUnitGuid()); + Unit* unit = Unit::GetUnit(*me, (*i)->getUnitGuid()); //if in melee range if (unit && unit->IsWithinDistInMap(me, 5)) { diff --git a/src/server/scripts/Outland/blades_edge_mountains.cpp b/src/server/scripts/Outland/blades_edge_mountains.cpp index 7a371170d7d..cf0955ed89c 100644 --- a/src/server/scripts/Outland/blades_edge_mountains.cpp +++ b/src/server/scripts/Outland/blades_edge_mountains.cpp @@ -855,7 +855,7 @@ class npc_simon_bunny : public CreatureScript if (GameObject* relic = me->FindNearestGameObject(large ? GO_APEXIS_MONUMENT : GO_APEXIS_RELIC, searchDistance)) relic->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); - me->ForcedDespawn(1000); + me->DespawnOrUnsummon(1000); } /* diff --git a/src/server/scripts/Outland/boss_doomlord_kazzak.cpp b/src/server/scripts/Outland/boss_doomlord_kazzak.cpp index 147d2d60359..a213713ae1a 100644 --- a/src/server/scripts/Outland/boss_doomlord_kazzak.cpp +++ b/src/server/scripts/Outland/boss_doomlord_kazzak.cpp @@ -31,15 +31,15 @@ enum Texts enum Spells { - SPELL_SHADOWVOLLEY = 32963, + SPELL_SHADOW_VOLLEY = 32963, SPELL_CLEAVE = 31779, SPELL_THUNDERCLAP = 36706, - SPELL_VOIDBOLT = 39329, - SPELL_MARKOFKAZZAK = 32960, - SPELL_MARKOFKAZZAK_DAMAGE = 32961, + SPELL_VOID_BOLT = 39329, + SPELL_MARK_OF_KAZZAK = 32960, SPELL_ENRAGE = 32964, - SPELL_CAPTURESOUL = 32966, - SPELL_TWISTEDREFLECTION = 21063 + SPELL_CAPTURE_SOUL = 32966, + SPELL_TWISTED_REFLECTION = 21063, + SPELL_BERSERK = 32965, }; enum Events @@ -47,10 +47,11 @@ enum Events EVENT_SHADOW_VOLLEY = 1, EVENT_CLEAVE = 2, EVENT_THUNDERCLAP = 3, - EVENT_VOIDBOLT = 4, + EVENT_VOID_BOLT = 4, EVENT_MARK_OF_KAZZAK = 5, EVENT_ENRAGE = 6, - EVENT_TWISTED_REFLECTION = 7 + EVENT_TWISTED_REFLECTION = 7, + EVENT_BERSERK = 8 }; class boss_doomlord_kazzak : public CreatureScript @@ -70,10 +71,11 @@ class boss_doomlord_kazzak : public CreatureScript _events.ScheduleEvent(EVENT_SHADOW_VOLLEY, urand(6000, 10000)); _events.ScheduleEvent(EVENT_CLEAVE, 7000); _events.ScheduleEvent(EVENT_THUNDERCLAP, urand(14000, 18000)); - _events.ScheduleEvent(EVENT_VOIDBOLT, 30000); + _events.ScheduleEvent(EVENT_VOID_BOLT, 30000); _events.ScheduleEvent(EVENT_MARK_OF_KAZZAK, 25000); _events.ScheduleEvent(EVENT_ENRAGE, 60000); _events.ScheduleEvent(EVENT_TWISTED_REFLECTION, 33000); + _events.ScheduleEvent(EVENT_BERSERK, 180000); } void JustRespawned() @@ -92,7 +94,7 @@ class boss_doomlord_kazzak : public CreatureScript if (victim->GetTypeId() != TYPEID_PLAYER) return; - DoCast(me, SPELL_CAPTURESOUL); + DoCast(me, SPELL_CAPTURE_SOUL); Talk(SAY_KILL); } @@ -118,7 +120,7 @@ class boss_doomlord_kazzak : public CreatureScript switch (eventId) { case EVENT_SHADOW_VOLLEY: - DoCastVictim(SPELL_SHADOWVOLLEY); + DoCastVictim(SPELL_SHADOW_VOLLEY); _events.ScheduleEvent(EVENT_SHADOW_VOLLEY, urand(4000, 6000)); break; case EVENT_CLEAVE: @@ -129,13 +131,13 @@ class boss_doomlord_kazzak : public CreatureScript DoCastVictim(SPELL_THUNDERCLAP); _events.ScheduleEvent(EVENT_THUNDERCLAP, urand(10000, 14000)); break; - case EVENT_VOIDBOLT: - DoCastVictim(SPELL_VOIDBOLT); - _events.ScheduleEvent(EVENT_VOIDBOLT, urand(15000, 18000)); + case EVENT_VOID_BOLT: + DoCastVictim(SPELL_VOID_BOLT); + _events.ScheduleEvent(EVENT_VOID_BOLT, urand(15000, 18000)); break; case EVENT_MARK_OF_KAZZAK: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true)) - DoCast(target, SPELL_MARKOFKAZZAK); + DoCast(target, SPELL_MARK_OF_KAZZAK); _events.ScheduleEvent(EVENT_MARK_OF_KAZZAK, 20000); break; case EVENT_ENRAGE: @@ -145,9 +147,12 @@ class boss_doomlord_kazzak : public CreatureScript break; case EVENT_TWISTED_REFLECTION: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true)) - DoCast(target, SPELL_TWISTEDREFLECTION); + DoCast(target, SPELL_TWISTED_REFLECTION); _events.ScheduleEvent(EVENT_TWISTED_REFLECTION, 15000); break; + case EVENT_BERSERK: + DoCast(me, SPELL_BERSERK); + break; default: break; } diff --git a/src/server/scripts/Outland/nagrand.cpp b/src/server/scripts/Outland/nagrand.cpp index 8080a1402af..871a2f200bb 100644 --- a/src/server/scripts/Outland/nagrand.cpp +++ b/src/server/scripts/Outland/nagrand.cpp @@ -450,7 +450,7 @@ public: { if (Say_Timer <= diff) { - me->ForcedDespawn(); + me->DespawnOrUnsummon(); ReleasedFromCage = false; } else @@ -689,7 +689,7 @@ class go_warmaul_prison : public GameObjectScript player->KilledMonsterCredit(NPC_MAGHAR_PRISONER, 0); prisoner->AI()->Talk(SAY_FREE, player->GetGUID()); - prisoner->ForcedDespawn(6000); + prisoner->DespawnOrUnsummon(6000); } return true; } diff --git a/src/server/scripts/Outland/netherstorm.cpp b/src/server/scripts/Outland/netherstorm.cpp index 17b9ec23f3d..afc18c71b92 100644 --- a/src/server/scripts/Outland/netherstorm.cpp +++ b/src/server/scripts/Outland/netherstorm.cpp @@ -115,7 +115,7 @@ public: if (someplayer) { - Unit* p = Unit::GetUnit((*me), someplayer); + Unit* p = Unit::GetUnit(*me, someplayer); if (p && p->GetTypeId() == TYPEID_PLAYER) { switch (me->GetEntry()) @@ -142,7 +142,7 @@ public: if (goConsole) { - if (GameObject* go = GameObject::GetGameObject((*me), goConsole)) + if (GameObject* go = GameObject::GetGameObject(*me, goConsole)) go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_IN_USE); } } @@ -243,7 +243,7 @@ public: case 1: if (someplayer) { - Unit* u = Unit::GetUnit((*me), someplayer); + Unit* u = Unit::GetUnit(*me, someplayer); if (u && u->GetTypeId() == TYPEID_PLAYER) DoScriptText(EMOTE_START, me, u); } Event_Timer = 60000; @@ -271,14 +271,14 @@ public: DoScriptText(EMOTE_COMPLETE, me); if (someplayer) { - Unit* u = Unit::GetUnit((*me), someplayer); + Unit* u = Unit::GetUnit(*me, someplayer); if (u && u->GetTypeId() == TYPEID_PLAYER) CAST_PLR(u)->KilledMonsterCredit(me->GetEntry(), me->GetGUID()); DoCast(me, SPELL_DISABLE_VISUAL); } if (goConsole) { - if (GameObject* go = GameObject::GetGameObject((*me), goConsole)) + if (GameObject* go = GameObject::GetGameObject(*me, goConsole)) go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_IN_USE); } ++Phase; @@ -812,7 +812,7 @@ public: } if (!UnitsWithMana.empty()) { - DoCast(SelectRandomContainerElement(UnitsWithMana), SPELL_MANA_BURN); + DoCast(Trinity::Containers::SelectRandomContainerElement(UnitsWithMana), SPELL_MANA_BURN); ManaBurnTimer = 8000 + (rand() % 10 * 1000); // 8-18 sec cd } else @@ -1057,7 +1057,7 @@ class go_captain_tyralius_prison : public GameObjectScript player->KilledMonsterCredit(NPC_CAPTAIN_TYRALIUS, 0); tyralius->AI()->Talk(SAY_FREE); - tyralius->ForcedDespawn(8000); + tyralius->DespawnOrUnsummon(8000); } return true; } diff --git a/src/server/scripts/Outland/shadowmoon_valley.cpp b/src/server/scripts/Outland/shadowmoon_valley.cpp index 46257f32ee2..340049ba4fa 100644 --- a/src/server/scripts/Outland/shadowmoon_valley.cpp +++ b/src/server/scripts/Outland/shadowmoon_valley.cpp @@ -262,7 +262,7 @@ public: { if (PlayerGUID) { - Unit* player = Unit::GetUnit((*me), PlayerGUID); + Unit* player = Unit::GetUnit(*me, PlayerGUID); if (player) DoCast(player, SPELL_FORCE_OF_NELTHARAKU, true); @@ -758,8 +758,8 @@ public: uint32 NextStep(uint32 Step) { - Unit* player = Unit::GetUnit((*me), PlayerGUID); - Unit* Illi = Unit::GetUnit((*me), IllidanGUID); + Player* player = Unit::GetPlayer(*me, PlayerGUID); + Unit* Illi = Unit::GetUnit(*me, IllidanGUID); if (!player || !Illi) { @@ -769,213 +769,178 @@ public: switch (Step) { - case 0: - return 0; - break; - - case 1: - me->GetMotionMaster()->MovePoint(0, -5104.41f, 595.297f, 85.6838f); - return 9000; - break; - - case 2: - DoScriptText(OVERLORD_YELL_1, me, player); - return 4500; - break; - - case 3: - me->SetInFront(player); - return 3200; - break; - - case 4: - DoScriptText(OVERLORD_SAY_2, me, player); - return 2000; - break; - - case 5: - Illi->SetVisible(true); - Illi->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - return 350; - break; - - case 6: - Illi->CastSpell(Illi, SPELL_ONE, true); - Illi->SetTarget(me->GetGUID()); - me->SetTarget(IllidanGUID); - return 2000; - break; - - case 7: - DoScriptText(OVERLORD_YELL_2, me); - return 4500; - break; - - case 8: - me->SetUInt32Value(UNIT_FIELD_BYTES_1, 8); - return 2500; - break; - - case 9: - DoScriptText(OVERLORD_SAY_3, me); - return 6500; - break; - - case 10: - DoScriptText(LORD_ILLIDAN_SAY_1, Illi); - return 5000; - break; - - case 11: - DoScriptText(OVERLORD_SAY_4, me, player); - return 6000; - break; - - case 12: - DoScriptText(LORD_ILLIDAN_SAY_2, Illi); - return 5500; - break; - - case 13: - DoScriptText(LORD_ILLIDAN_SAY_3, Illi); - return 4000; - break; - - case 14: - Illi->SetTarget(PlayerGUID); - return 1500; - break; - - case 15: - DoScriptText(LORD_ILLIDAN_SAY_4, Illi); - return 1500; - break; - - case 16: - if (player) - { - Illi->CastSpell(player, SPELL_TWO, true); - player->RemoveAurasDueToSpell(SPELL_THREE); - player->RemoveAurasDueToSpell(SPELL_FOUR); + case 0: + return 0; + break; + case 1: + me->GetMotionMaster()->MovePoint(0, -5104.41f, 595.297f, 85.6838f); + return 9000; + break; + case 2: + DoScriptText(OVERLORD_YELL_1, me, player); + return 4500; + break; + case 3: + me->SetInFront(player); + return 3200; + break; + case 4: + DoScriptText(OVERLORD_SAY_2, me, player); + return 2000; + break; + case 5: + Illi->SetVisible(true); + Illi->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + return 350; + break; + case 6: + Illi->CastSpell(Illi, SPELL_ONE, true); + Illi->SetTarget(me->GetGUID()); + me->SetTarget(IllidanGUID); + return 2000; + break; + case 7: + DoScriptText(OVERLORD_YELL_2, me); + return 4500; + break; + case 8: + me->SetUInt32Value(UNIT_FIELD_BYTES_1, 8); + return 2500; + break; + case 9: + DoScriptText(OVERLORD_SAY_3, me); + return 6500; + break; + case 10: + DoScriptText(LORD_ILLIDAN_SAY_1, Illi); return 5000; - } - else - { - CAST_PLR(player)->FailQuest(QUEST_LORD_ILLIDAN_STORMRAGE); - Step = 30; - return 100; - } - break; - - case 17: - DoScriptText(LORD_ILLIDAN_SAY_5, Illi); - return 5000; - break; - - case 18: - DoScriptText(LORD_ILLIDAN_SAY_6, Illi); - return 5000; - break; - - case 19: - DoScriptText(LORD_ILLIDAN_SAY_7, Illi); - return 5000; - break; - - case 20: - Illi->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF); - Illi->SetDisableGravity(true); - return 500; - break; - - case 21: - DoScriptText(OVERLORD_SAY_5, me); - return 500; - break; - - case 22: - Illi->SetVisible(false); - Illi->setDeathState(JUST_DIED); - return 1000; - break; - - case 23: - me->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); - return 2000; - break; - - case 24: - me->SetTarget(PlayerGUID); - return 5000; - break; - - case 25: - DoScriptText(OVERLORD_SAY_6, me); - return 2000; - break; - - case 26: - if (player) - CAST_PLR(player)->GroupEventHappens(QUEST_LORD_ILLIDAN_STORMRAGE, me); - return 6000; - break; - - case 27: - { - Unit* Yarzill = me->FindNearestCreature(C_YARZILL, 50); - if (Yarzill) - Yarzill->SetTarget(PlayerGUID); - return 500; - } - break; - - case 28: - player->RemoveAurasDueToSpell(SPELL_TWO); - player->RemoveAurasDueToSpell(41519); - player->CastSpell(player, SPELL_THREE, true); - player->CastSpell(player, SPELL_FOUR, true); - return 1000; - break; - - case 29: - { - Unit* Yarzill = me->FindNearestCreature(C_YARZILL, 50); - if (Yarzill) - DoScriptText(YARZILL_THE_MERC_SAY, Yarzill, player); + break; + case 11: + DoScriptText(OVERLORD_SAY_4, me, player); + return 6000; + break; + case 12: + DoScriptText(LORD_ILLIDAN_SAY_2, Illi); + return 5500; + break; + case 13: + DoScriptText(LORD_ILLIDAN_SAY_3, Illi); + return 4000; + break; + case 14: + Illi->SetTarget(PlayerGUID); + return 1500; + break; + case 15: + DoScriptText(LORD_ILLIDAN_SAY_4, Illi); + return 1500; + break; + case 16: + if (player) + { + Illi->CastSpell(player, SPELL_TWO, true); + player->RemoveAurasDueToSpell(SPELL_THREE); + player->RemoveAurasDueToSpell(SPELL_FOUR); + return 5000; + } + else + { + player->FailQuest(QUEST_LORD_ILLIDAN_STORMRAGE); + Step = 30; + return 100; + } + break; + case 17: + DoScriptText(LORD_ILLIDAN_SAY_5, Illi); return 5000; - } - break; - - case 30: - { - Unit* Yarzill = me->FindNearestCreature(C_YARZILL, 50); - if (Yarzill) - Yarzill->SetTarget(0); + break; + case 18: + DoScriptText(LORD_ILLIDAN_SAY_6, Illi); return 5000; - } - break; - - case 31: - { - Unit* Yarzill = me->FindNearestCreature(C_YARZILL, 50); - if (Yarzill) - Yarzill->CastSpell(player, 41540, true); + break; + case 19: + DoScriptText(LORD_ILLIDAN_SAY_7, Illi); + return 5000; + break; + case 20: + Illi->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF); + Illi->SetDisableGravity(true); + return 500; + break; + case 21: + DoScriptText(OVERLORD_SAY_5, me); + return 500; + break; + case 22: + Illi->SetVisible(false); + Illi->setDeathState(JUST_DIED); return 1000; - } - break; - - case 32: - me->GetMotionMaster()->MovePoint(0, -5085.77f, 577.231f, 86.6719f); return 5000; - break; - - case 33: - Reset(); - return 100; - break; - - default : - return 0; - break; + break; + case 23: + me->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); + return 2000; + break; + case 24: + me->SetTarget(PlayerGUID); + return 5000; + break; + case 25: + DoScriptText(OVERLORD_SAY_6, me); + return 2000; + break; + case 26: + player->GroupEventHappens(QUEST_LORD_ILLIDAN_STORMRAGE, me); + return 6000; + break; + case 27: + { + Unit* Yarzill = me->FindNearestCreature(C_YARZILL, 50); + if (Yarzill) + Yarzill->SetTarget(PlayerGUID); + return 500; + } + break; + case 28: + player->RemoveAurasDueToSpell(SPELL_TWO); + player->RemoveAurasDueToSpell(41519); + player->CastSpell(player, SPELL_THREE, true); + player->CastSpell(player, SPELL_FOUR, true); + return 1000; + break; + case 29: + { + Unit* Yarzill = me->FindNearestCreature(C_YARZILL, 50); + if (Yarzill) + DoScriptText(YARZILL_THE_MERC_SAY, Yarzill, player); + return 5000; + } + break; + case 30: + { + Unit* Yarzill = me->FindNearestCreature(C_YARZILL, 50); + if (Yarzill) + Yarzill->SetTarget(0); + return 5000; + } + break; + case 31: + { + Unit* Yarzill = me->FindNearestCreature(C_YARZILL, 50); + if (Yarzill) + Yarzill->CastSpell(player, 41540, true); + return 1000; + } + break; + case 32: + me->GetMotionMaster()->MovePoint(0, -5085.77f, 577.231f, 86.6719f); return 5000; + break; + case 33: + Reset(); + return 100; + break; + default : + return 0; + break; } } diff --git a/src/server/scripts/Spells/spell_dk.cpp b/src/server/scripts/Spells/spell_dk.cpp index 5d874faf411..36dcb53ad00 100644 --- a/src/server/scripts/Spells/spell_dk.cpp +++ b/src/server/scripts/Spells/spell_dk.cpp @@ -750,8 +750,26 @@ class spell_dk_death_coil : public SpellScriptLoader } } + SpellCastResult CheckCast() + { + Unit* caster = GetCaster(); + if (Unit* target = GetExplTargetUnit()) + { + if (!caster->IsFriendlyTo(target) && !caster->isInFront(target)) + return SPELL_FAILED_UNIT_NOT_INFRONT; + + if (target->IsFriendlyTo(caster) && target->GetCreatureType() != CREATURE_TYPE_UNDEAD) + return SPELL_FAILED_BAD_TARGETS; + } + else + return SPELL_FAILED_BAD_TARGETS; + + return SPELL_CAST_OK; + } + void Register() { + OnCheckCast += SpellCheckCastFn(spell_dk_death_coil_SpellScript::CheckCast); OnEffectHitTarget += SpellEffectFn(spell_dk_death_coil_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } @@ -775,7 +793,7 @@ class spell_dk_death_grip : public SpellScriptLoader void HandleDummy(SpellEffIndex /*effIndex*/) { int32 damage = GetEffectValue(); - Position const* pos = GetTargetDest(); + Position const* pos = GetExplTargetDest(); if (Unit* target = GetHitUnit()) { if (!target->HasAuraType(SPELL_AURA_DEFLECT_SPELLS)) // Deterrence diff --git a/src/server/scripts/Spells/spell_druid.cpp b/src/server/scripts/Spells/spell_druid.cpp index 4c440f18bd9..898350dbd71 100644 --- a/src/server/scripts/Spells/spell_druid.cpp +++ b/src/server/scripts/Spells/spell_druid.cpp @@ -237,7 +237,7 @@ class spell_dru_t10_restoration_4p_bonus : public SpellScriptLoader } else { - unitList.remove(GetTargetUnit()); + unitList.remove(GetExplTargetUnit()); std::list<Unit*> tempTargets; for (std::list<Unit*>::const_iterator itr = unitList.begin(); itr != unitList.end(); ++itr) if ((*itr)->GetTypeId() == TYPEID_PLAYER && GetCaster()->IsInRaidWith(*itr)) @@ -250,7 +250,7 @@ class spell_dru_t10_restoration_4p_bonus : public SpellScriptLoader return; } - Unit* target = SelectRandomContainerElement(tempTargets); + Unit* target = Trinity::Containers::SelectRandomContainerElement(tempTargets); unitList.clear(); unitList.push_back(target); } @@ -279,7 +279,7 @@ class spell_dru_starfall_aoe : public SpellScriptLoader void FilterTargets(std::list<Unit*>& unitList) { - unitList.remove(GetTargetUnit()); + unitList.remove(GetExplTargetUnit()); } void Register() diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp index 929206dec05..0c879cfb029 100644 --- a/src/server/scripts/Spells/spell_generic.cpp +++ b/src/server/scripts/Spells/spell_generic.cpp @@ -169,7 +169,7 @@ class spell_gen_burn_brutallus : public SpellScriptLoader } }; -enum eCannibalizeSpells +enum CannibalizeSpells { SPELL_CANNIBALIZE_TRIGGERED = 20578, }; @@ -224,7 +224,7 @@ class spell_gen_cannibalize : public SpellScriptLoader }; // 45472 Parachute -enum eParachuteSpells +enum ParachuteSpells { SPELL_PARACHUTE = 45472, SPELL_PARACHUTE_BUFF = 44795, @@ -365,7 +365,7 @@ class spell_gen_remove_flight_auras : public SpellScriptLoader }; // 66118 Leeching Swarm -enum eLeechingSwarmSpells +enum LeechingSwarmSpells { SPELL_LEECHING_SWARM_DMG = 66240, SPELL_LEECHING_SWARM_HEAL = 66125, @@ -481,7 +481,7 @@ class spell_gen_elune_candle : public SpellScriptLoader }; // 24750 Trick -enum eTrickSpells +enum TrickSpells { SPELL_PIRATE_COSTUME_MALE = 24708, SPELL_PIRATE_COSTUME_FEMALE = 24709, @@ -557,7 +557,7 @@ class spell_gen_trick : public SpellScriptLoader }; // 24751 Trick or Treat -enum eTrickOrTreatSpells +enum TrickOrTreatSpells { SPELL_TRICK = 24714, SPELL_TREAT = 24715, @@ -1234,30 +1234,30 @@ class spell_gen_magic_rooster : public SpellScriptLoader class spell_gen_allow_cast_from_item_only : public SpellScriptLoader { -public: - spell_gen_allow_cast_from_item_only() : SpellScriptLoader("spell_gen_allow_cast_from_item_only") { } - - class spell_gen_allow_cast_from_item_only_SpellScript : public SpellScript - { - PrepareSpellScript(spell_gen_allow_cast_from_item_only_SpellScript); + public: + spell_gen_allow_cast_from_item_only() : SpellScriptLoader("spell_gen_allow_cast_from_item_only") { } - SpellCastResult CheckRequirement() + class spell_gen_allow_cast_from_item_only_SpellScript : public SpellScript { - if (!GetCastItem()) - return SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW; - return SPELL_CAST_OK; - } + PrepareSpellScript(spell_gen_allow_cast_from_item_only_SpellScript); - void Register() + SpellCastResult CheckRequirement() + { + if (!GetCastItem()) + return SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW; + return SPELL_CAST_OK; + } + + void Register() + { + OnCheckCast += SpellCheckCastFn(spell_gen_allow_cast_from_item_only_SpellScript::CheckRequirement); + } + }; + + SpellScript* GetSpellScript() const { - OnCheckCast += SpellCheckCastFn(spell_gen_allow_cast_from_item_only_SpellScript::CheckRequirement); + return new spell_gen_allow_cast_from_item_only_SpellScript(); } - }; - - SpellScript* GetSpellScript() const - { - return new spell_gen_allow_cast_from_item_only_SpellScript(); - } }; enum Launch @@ -1282,7 +1282,7 @@ class spell_gen_launch : public SpellScriptLoader void Launch() { - WorldLocation const* const position = GetTargetDest(); + WorldLocation const* const position = GetExplTargetDest(); if (Player* player = GetHitPlayer()) { @@ -1513,7 +1513,7 @@ class spell_gen_luck_of_the_draw : public SpellScriptLoader if (group->isLFGGroup()) if (uint32 dungeonId = sLFGMgr->GetDungeon(group->GetGUID(), true)) if (LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(dungeonId)) - if (uint32(dungeon->map) == map->GetId() && dungeon->difficulty == map->GetDifficulty()) + if (uint32(dungeon->map) == map->GetId() && dungeon->difficulty == uint32(map->GetDifficulty())) if (randomDungeon && randomDungeon->type == LFG_TYPE_RANDOM) return; // in correct dungeon @@ -2590,6 +2590,104 @@ class spell_gen_ds_flush_knockback : public SpellScriptLoader } }; +class spell_gen_wg_water : public SpellScriptLoader +{ + public: + spell_gen_wg_water() : SpellScriptLoader("spell_gen_wg_water") {} + + class spell_gen_wg_water_SpellScript : public SpellScript + { + PrepareSpellScript(spell_gen_wg_water_SpellScript); + + SpellCastResult CheckCast() + { + if (!GetSpellInfo()->CheckTargetCreatureType(GetCaster())) + return SPELL_FAILED_DONT_REPORT; + return SPELL_CAST_OK; + } + + void Register() + { + OnCheckCast += SpellCheckCastFn(spell_gen_wg_water_SpellScript::CheckCast); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_gen_wg_water_SpellScript(); + } +}; + +class spell_gen_count_pct_from_max_hp : public SpellScriptLoader +{ + public: + spell_gen_count_pct_from_max_hp(char const* name, int32 damagePct = 0) : SpellScriptLoader(name), _damagePct(damagePct) { } + + class spell_gen_count_pct_from_max_hp_SpellScript : public SpellScript + { + PrepareSpellScript(spell_gen_count_pct_from_max_hp_SpellScript) + + public: + spell_gen_count_pct_from_max_hp_SpellScript(int32 damagePct) : SpellScript(), _damagePct(damagePct) { } + + void RecalculateDamage() + { + if (!_damagePct) + _damagePct = GetHitDamage(); + + SetHitDamage(GetHitUnit()->CountPctFromMaxHealth(_damagePct)); + } + + void Register() + { + OnHit += SpellHitFn(spell_gen_count_pct_from_max_hp_SpellScript::RecalculateDamage); + } + + private: + int32 _damagePct; + }; + + SpellScript* GetSpellScript() const + { + return new spell_gen_count_pct_from_max_hp_SpellScript(_damagePct); + } + + private: + int32 _damagePct; +}; + +class spell_gen_despawn_self : public SpellScriptLoader +{ +public: + spell_gen_despawn_self() : SpellScriptLoader("spell_gen_despawn_self") { } + + class spell_gen_despawn_self_SpellScript : public SpellScript + { + PrepareSpellScript(spell_gen_despawn_self_SpellScript); + + bool Load() + { + return GetCaster()->GetTypeId() == TYPEID_UNIT; + } + + void HandleDummy(SpellEffIndex effIndex) + { + if (GetSpellInfo()->Effects[effIndex].Effect == SPELL_EFFECT_DUMMY || GetSpellInfo()->Effects[effIndex].Effect == SPELL_EFFECT_SCRIPT_EFFECT) + GetCaster()->ToCreature()->DespawnOrUnsummon(); + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_gen_despawn_self_SpellScript::HandleDummy, EFFECT_ALL, SPELL_EFFECT_ANY); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_gen_despawn_self_SpellScript(); + } +}; + void AddSC_generic_spell_scripts() { new spell_gen_absorb0_hitlimit1(); @@ -2640,4 +2738,8 @@ void AddSC_generic_spell_scripts() new spell_gen_tournament_pennant(); new spell_gen_chaos_blast(); new spell_gen_ds_flush_knockback(); + new spell_gen_wg_water(); + new spell_gen_count_pct_from_max_hp("spell_gen_default_count_pct_from_max_hp"); + new spell_gen_count_pct_from_max_hp("spell_gen_50pct_count_pct_from_max_hp", 50); + new spell_gen_despawn_self(); } diff --git a/src/server/scripts/Spells/spell_hunter.cpp b/src/server/scripts/Spells/spell_hunter.cpp index 5d8e8f84e6a..896ed331bde 100644 --- a/src/server/scripts/Spells/spell_hunter.cpp +++ b/src/server/scripts/Spells/spell_hunter.cpp @@ -137,8 +137,9 @@ class spell_hun_chimera_shot : public SpellScriptLoader { int32 TickCount = aurEff->GetTotalTicks(); spellId = HUNTER_SPELL_CHIMERA_SHOT_SERPENT; - basePoint = caster->SpellDamageBonus(unitTarget, aura->GetSpellInfo(), aurEff->GetAmount(), DOT, aura->GetStackAmount()); + basePoint = caster->SpellDamageBonusDone(unitTarget, aura->GetSpellInfo(), aurEff->GetAmount(), DOT, aura->GetStackAmount()); ApplyPctN(basePoint, TickCount * 40); + basePoint = unitTarget->SpellDamageBonusTaken(caster, aura->GetSpellInfo(), basePoint, DOT, aura->GetStackAmount()); } // Viper Sting - Instantly restores mana to you equal to 60% of the total amount drained by your Viper Sting. else if (familyFlag[1] & 0x00000080) @@ -286,8 +287,8 @@ class spell_hun_masters_call : public SpellScriptLoader target->CastSpell(target, HUNTER_SPELL_MASTERS_CALL_TRIGGERED, castMask); // there is a possibility that this effect should access effect 0 (dummy) target, but i dubt that // it's more likely that on on retail it's possible to call target selector based on dbc values - // anyways, we're using GetTargetUnit() here and it's ok - if (Unit* ally = GetTargetUnit()) + // anyways, we're using GetExplTargetUnit() here and it's ok + if (Unit* ally = GetExplTargetUnit()) { target->CastSpell(ally, GetEffectValue(), castMask); target->CastSpell(ally, GetSpellInfo()->Effects[EFFECT_0].CalcValue(), castMask); diff --git a/src/server/scripts/Spells/spell_item.cpp b/src/server/scripts/Spells/spell_item.cpp index 80520f44c3e..4e2eb633662 100644 --- a/src/server/scripts/Spells/spell_item.cpp +++ b/src/server/scripts/Spells/spell_item.cpp @@ -1095,7 +1095,7 @@ class spell_item_shimmering_vessel : public SpellScriptLoader void HandleDummy(SpellEffIndex /* effIndex */) { if (Creature* target = GetHitCreature()) - target->setDeathState(JUST_ALIVED); + target->setDeathState(JUST_RESPAWNED); } void Register() @@ -1744,11 +1744,20 @@ class spell_item_rocket_boots : public SpellScriptLoader if (Battleground* bg = caster->GetBattleground()) bg->EventPlayerDroppedFlag(caster); + caster->RemoveSpellCooldown(SPELL_ROCKET_BOOTS_PROC); caster->CastSpell(caster, SPELL_ROCKET_BOOTS_PROC, true, NULL); } + SpellCastResult CheckCast() + { + if (GetCaster()->IsInWater()) + return SPELL_FAILED_ONLY_ABOVEWATER; + return SPELL_CAST_OK; + } + void Register() { + OnCheckCast += SpellCheckCastFn(spell_item_rocket_boots_SpellScript::CheckCast); OnEffectHitTarget += SpellEffectFn(spell_item_rocket_boots_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; @@ -2005,7 +2014,7 @@ class spell_item_muisek_vessel : public SpellScriptLoader { if (Creature* target = GetHitCreature()) if (target->isDead()) - target->ForcedDespawn(); + target->DespawnOrUnsummon(); } void Register() @@ -2020,6 +2029,37 @@ class spell_item_muisek_vessel : public SpellScriptLoader } }; +enum GreatmothersSoulcather +{ + SPELL_FORCE_CAST_SUMMON_GNOME_SOUL = 46486, +}; +class spell_item_greatmothers_soulcatcher : public SpellScriptLoader +{ +public: + spell_item_greatmothers_soulcatcher() : SpellScriptLoader("spell_item_greatmothers_soulcatcher") { } + + class spell_item_greatmothers_soulcatcher_SpellScript : public SpellScript + { + PrepareSpellScript(spell_item_greatmothers_soulcatcher_SpellScript); + + void HandleDummy(SpellEffIndex /*effIndex*/) + { + if (GetHitUnit()) + GetCaster()->CastSpell(GetCaster(),SPELL_FORCE_CAST_SUMMON_GNOME_SOUL); + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_item_greatmothers_soulcatcher_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_item_greatmothers_soulcatcher_SpellScript(); + } +}; + void AddSC_item_spell_scripts() { // 23074 Arcanite Dragonling @@ -2072,4 +2112,5 @@ void AddSC_item_spell_scripts() new spell_item_uded(); new spell_item_chicken_cover(); new spell_item_muisek_vessel(); + new spell_item_greatmothers_soulcatcher(); } diff --git a/src/server/scripts/Spells/spell_mage.cpp b/src/server/scripts/Spells/spell_mage.cpp index b746c37a090..050741ffaba 100644 --- a/src/server/scripts/Spells/spell_mage.cpp +++ b/src/server/scripts/Spells/spell_mage.cpp @@ -250,9 +250,11 @@ class spell_mage_frost_warding_trigger : public SpellScriptLoader if (roll_chance_i(chance)) { - absorbAmount = dmgInfo.GetDamage(); - int32 bp = absorbAmount; + int32 bp = dmgInfo.GetDamage(); + dmgInfo.AbsorbDamage(bp); target->CastCustomSpell(target, SPELL_MAGE_FROST_WARDING_TRIGGERED, &bp, NULL, NULL, true, NULL, aurEff); + absorbAmount = 0; + PreventDefaultAction(); } } } diff --git a/src/server/scripts/Spells/spell_paladin.cpp b/src/server/scripts/Spells/spell_paladin.cpp index d823c629d4b..4baa1eb3735 100644 --- a/src/server/scripts/Spells/spell_paladin.cpp +++ b/src/server/scripts/Spells/spell_paladin.cpp @@ -285,9 +285,29 @@ class spell_pal_holy_shock : public SpellScriptLoader } } + SpellCastResult CheckCast() + { + Player* caster = GetCaster()->ToPlayer(); + if (Unit* target = GetExplTargetUnit()) + { + if (!caster->IsFriendlyTo(target)) + { + if (!caster->IsValidAttackTarget(target)) + return SPELL_FAILED_BAD_TARGETS; + + if (!caster->isInFront(target)) + return SPELL_FAILED_UNIT_NOT_INFRONT; + } + } + else + return SPELL_FAILED_BAD_TARGETS; + return SPELL_CAST_OK; + } + void Register() { // add dummy effect spell handler to Holy Shock + OnCheckCast += SpellCheckCastFn(spell_pal_holy_shock_SpellScript::CheckCast); OnEffectHitTarget += SpellEffectFn(spell_pal_holy_shock_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; diff --git a/src/server/scripts/Spells/spell_priest.cpp b/src/server/scripts/Spells/spell_priest.cpp index d2bba2b8bc3..8088004c9d1 100644 --- a/src/server/scripts/Spells/spell_priest.cpp +++ b/src/server/scripts/Spells/spell_priest.cpp @@ -227,10 +227,9 @@ class spell_pri_penance : public SpellScriptLoader SpellCastResult CheckCast() { Player* caster = GetCaster()->ToPlayer(); - if (GetTargetUnit()) - if (Player* target = GetTargetUnit()->ToPlayer()) - if (caster->GetTeam() != target->GetTeam() && !caster->IsValidAttackTarget(target)) - return SPELL_FAILED_BAD_TARGETS; + if (Unit* target = GetExplTargetUnit()) + if (!caster->IsFriendlyTo(target) && !caster->IsValidAttackTarget(target)) + return SPELL_FAILED_BAD_TARGETS; return SPELL_CAST_OK; } @@ -291,12 +290,53 @@ class spell_pri_reflective_shield_trigger : public SpellScriptLoader } }; +enum PrayerOfMending +{ + SPELL_T9_HEALING_2_PIECE = 67201, +}; +// Prayer of Mending Heal +class spell_pri_prayer_of_mending_heal : public SpellScriptLoader +{ +public: + spell_pri_prayer_of_mending_heal() : SpellScriptLoader("spell_pri_prayer_of_mending_heal") { } + + class spell_pri_prayer_of_mending_heal_SpellScript : public SpellScript + { + PrepareSpellScript(spell_pri_prayer_of_mending_heal_SpellScript); + + void HandleHeal(SpellEffIndex /*effIndex*/) + { + if (Unit* caster = GetOriginalCaster()) + { + if (AuraEffect* aurEff = caster->GetAuraEffect(SPELL_T9_HEALING_2_PIECE,EFFECT_0)) + { + int32 heal = GetHitHeal(); + AddPctN(heal, aurEff->GetAmount()); + SetHitHeal(heal); + } + } + + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_pri_prayer_of_mending_heal_SpellScript::HandleHeal, EFFECT_0, SPELL_EFFECT_HEAL); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_pri_prayer_of_mending_heal_SpellScript(); + } +}; + void AddSC_priest_spell_scripts() { new spell_pri_guardian_spirit(); - new spell_pri_mana_burn; - new spell_pri_pain_and_suffering_proc; - new spell_pri_penance; + new spell_pri_mana_burn(); + new spell_pri_pain_and_suffering_proc(); + new spell_pri_penance(); new spell_pri_reflective_shield_trigger(); new spell_pri_mind_sear(); + new spell_pri_prayer_of_mending_heal(); } diff --git a/src/server/scripts/Spells/spell_quest.cpp b/src/server/scripts/Spells/spell_quest.cpp index 278abcc0c0b..810cc20e04b 100644 --- a/src/server/scripts/Spells/spell_quest.cpp +++ b/src/server/scripts/Spells/spell_quest.cpp @@ -275,7 +275,7 @@ class spell_q11396_11399_scourging_crystal_controller : public SpellScriptLoader void HandleDummy(SpellEffIndex /*effIndex*/) { - if (Unit* target = GetTargetUnit()) + if (Unit* target = GetExplTargetUnit()) if (target->GetTypeId() == TYPEID_UNIT && target->HasAura(SPELL_FORCE_SHIELD_ARCANE_PURPLE_X3)) // Make sure nobody else is channeling the same target if (!target->HasAura(SPELL_SCOURGING_CRYSTAL_CONTROLLER)) @@ -636,6 +636,10 @@ class spell_q12851_going_bearback : public SpellScriptLoader if (Unit* caster = GetCaster()) { Unit* target = GetTarget(); + // Already in fire + if (target->HasAura(SPELL_ABLAZE)) + return; + if (Player* player = caster->GetCharmerOrOwnerPlayerOrPlayerItself()) { switch (target->GetEntry()) @@ -833,7 +837,7 @@ class spell_q12659_ahunaes_knife : public SpellScriptLoader Player* caster = GetCaster()->ToPlayer(); if (Creature* target = GetHitCreature()) { - target->ForcedDespawn(); + target->DespawnOrUnsummon(); caster->KilledMonsterCredit(NPC_SCALPS_KC_BUNNY, 0); } } @@ -1101,6 +1105,63 @@ public: } }; +enum LeaveNothingToChance +{ + NPC_UPPER_MINE_SHAFT = 27436, + NPC_LOWER_MINE_SHAFT = 27437, + + SPELL_UPPER_MINE_SHAFT_CREDIT = 48744, + SPELL_LOWER_MINE_SHAFT_CREDIT = 48745, +}; + +class spell_q12277_wintergarde_mine_explosion : public SpellScriptLoader +{ + public: + spell_q12277_wintergarde_mine_explosion() : SpellScriptLoader("spell_q12277_wintergarde_mine_explosion") { } + + class spell_q12277_wintergarde_mine_explosion_SpellScript : public SpellScript + { + PrepareSpellScript(spell_q12277_wintergarde_mine_explosion_SpellScript); + + void HandleDummy(SpellEffIndex /*effIndex*/) + { + if (Creature* unitTarget = GetHitCreature()) + { + if (Unit* caster = GetCaster()) + { + if (caster->GetTypeId() == TYPEID_UNIT) + { + if (Unit* owner = caster->GetOwner()) + { + switch (unitTarget->GetEntry()) + { + case NPC_UPPER_MINE_SHAFT: + caster->CastSpell(owner, SPELL_UPPER_MINE_SHAFT_CREDIT, true); + break; + case NPC_LOWER_MINE_SHAFT: + caster->CastSpell(owner, SPELL_LOWER_MINE_SHAFT_CREDIT, true); + break; + default: + break; + } + } + } + } + } + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_q12277_wintergarde_mine_explosion_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_q12277_wintergarde_mine_explosion_SpellScript(); + } +}; + void AddSC_quest_spell_scripts() { new spell_q55_sacred_cleansing(); @@ -1127,4 +1188,5 @@ void AddSC_quest_spell_scripts() new spell_q14112_14145_chum_the_water(); new spell_q9452_cast_net(); new spell_q12987_read_pronouncement(); + new spell_q12277_wintergarde_mine_explosion(); } diff --git a/src/server/scripts/Spells/spell_shaman.cpp b/src/server/scripts/Spells/spell_shaman.cpp index 96ee7a18429..c9c036d5329 100644 --- a/src/server/scripts/Spells/spell_shaman.cpp +++ b/src/server/scripts/Spells/spell_shaman.cpp @@ -35,6 +35,9 @@ enum ShamanSpells SHAMAN_SPELL_FIRE_NOVA_TRIGGERED_R1 = 8349, SHAMAN_SPELL_SATED = 57724, SHAMAN_SPELL_EXHAUSTION = 57723, + + SHAMAN_SPELL_STORM_EARTH_AND_FIRE = 51483, + EARTHBIND_TOTEM_SPELL_EARTHGRAB = 64695, // For Earthen Power SHAMAN_TOTEM_SPELL_EARTHBIND_TOTEM = 6474, @@ -210,20 +213,35 @@ class spell_sha_earthbind_totem : public SpellScriptLoader return true; } - void HandleEffectPeriodic(AuraEffect const* aurEff) + void HandleEffectPeriodic(AuraEffect const* /*aurEff*/) { - if (Unit* target = GetTarget()) - if (Unit* caster = aurEff->GetBase()->GetCaster()) - if (TempSummon* summon = caster->ToTempSummon()) - if (Unit* owner = summon->GetOwner()) - if (AuraEffect* aur = owner->GetDummyAuraEffect(SPELLFAMILY_SHAMAN, 2289, 0)) - if (roll_chance_i(aur->GetBaseAmount()) && target->HasAuraWithMechanic(1 << MECHANIC_SNARE)) - caster->CastSpell(caster, SHAMAN_TOTEM_SPELL_EARTHEN_POWER, true, NULL, aurEff); + if (!GetCaster()) + return; + if (Player* owner = GetCaster()->GetCharmerOrOwnerPlayerOrPlayerItself()) + if (AuraEffect* aur = owner->GetDummyAuraEffect(SPELLFAMILY_SHAMAN, 2289, 0)) + if (roll_chance_i(aur->GetBaseAmount())) + GetTarget()->CastSpell((Unit*)NULL, SHAMAN_TOTEM_SPELL_EARTHEN_POWER, true); + } + + void Apply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (!GetCaster()) + return; + Player* owner = GetCaster()->GetCharmerOrOwnerPlayerOrPlayerItself(); + if (!owner) + return; + // Storm, Earth and Fire + if (AuraEffect* aurEff = owner->GetAuraEffectOfRankedSpell(SHAMAN_SPELL_STORM_EARTH_AND_FIRE, EFFECT_1)) + { + if (roll_chance_i(aurEff->GetAmount())) + GetCaster()->CastSpell(GetCaster(), EARTHBIND_TOTEM_SPELL_EARTHGRAB, false); + } } void Register() { OnEffectPeriodic += AuraEffectPeriodicFn(spell_sha_earthbind_totem_AuraScript::HandleEffectPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + OnEffectApply += AuraEffectApplyFn(spell_sha_earthbind_totem_AuraScript::Apply, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL); } }; @@ -233,6 +251,46 @@ class spell_sha_earthbind_totem : public SpellScriptLoader } }; +class EarthenPowerTargetSelector +{ + public: + EarthenPowerTargetSelector() { } + + bool operator() (Unit* target) + { + if (!target->HasAuraWithMechanic(1 << MECHANIC_SNARE)) + return true; + + return false; + } +}; + +class spell_sha_earthen_power : public SpellScriptLoader +{ + public: + spell_sha_earthen_power() : SpellScriptLoader("spell_sha_earthen_power") { } + + class spell_sha_earthen_power_SpellScript : public SpellScript + { + PrepareSpellScript(spell_sha_earthen_power_SpellScript); + + void FilterTargets(std::list<Unit*>& unitList) + { + unitList.remove_if(EarthenPowerTargetSelector()); + } + + void Register() + { + OnUnitTargetSelect += SpellUnitTargetFn(spell_sha_earthen_power_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_sha_earthen_power_SpellScript(); + } +}; + class spell_sha_bloodlust : public SpellScriptLoader { public: @@ -251,7 +309,7 @@ class spell_sha_bloodlust : public SpellScriptLoader void RemoveInvalidTargets(std::list<Unit*>& targets) { - targets.remove_if (Trinity::UnitAuraCheck(true, SHAMAN_SPELL_SATED)); + targets.remove_if(Trinity::UnitAuraCheck(true, SHAMAN_SPELL_SATED)); } void ApplyDebuff() @@ -430,7 +488,7 @@ class spell_sha_healing_stream_totem : public SpellScriptLoader if (Unit* owner = caster->GetOwner()) { if (triggeringSpell) - damage = int32(owner->SpellHealingBonus(target, triggeringSpell, damage, HEAL)); + damage = int32(owner->SpellHealingBonusDone(target, triggeringSpell, damage, HEAL)); // Restorative Totems if (AuraEffect* dummy = owner->GetAuraEffect(SPELL_AURA_DUMMY, SPELLFAMILY_SHAMAN, ICON_ID_RESTORATIVE_TOTEMS, 1)) @@ -439,6 +497,8 @@ class spell_sha_healing_stream_totem : public SpellScriptLoader // Glyph of Healing Stream Totem if (AuraEffect const* aurEff = owner->GetAuraEffect(SPELL_GLYPH_OF_HEALING_STREAM_TOTEM, EFFECT_0)) AddPctN(damage, aurEff->GetAmount()); + + damage = int32(target->SpellHealingBonusTaken(owner, triggeringSpell, damage, HEAL)); } caster->CastCustomSpell(target, SPELL_HEALING_STREAM_TOTEM_HEAL, &damage, 0, 0, true, 0, 0, GetOriginalCaster()->GetGUID()); } @@ -542,6 +602,55 @@ class spell_sha_lava_lash : public SpellScriptLoader } }; +// 1064 Chain Heal +class spell_sha_chain_heal : public SpellScriptLoader +{ + public: + spell_sha_chain_heal() : SpellScriptLoader("spell_sha_chain_heal") { } + + class spell_sha_chain_heal_SpellScript : public SpellScript + { + PrepareSpellScript(spell_sha_chain_heal_SpellScript); + + bool Load() + { + firstHeal = true; + riptide = false; + return true; + } + + void HandleHeal(SpellEffIndex /*effIndex*/) + { + if (firstHeal) + { + // Check if the target has Riptide + if (AuraEffect* aurEff = GetHitUnit()->GetAuraEffect(SPELL_AURA_PERIODIC_HEAL, SPELLFAMILY_SHAMAN, 0, 0, 0x10, GetCaster()->GetGUID())) + { + riptide = true; + // Consume it + GetHitUnit()->RemoveAura(aurEff->GetBase()); + } + firstHeal = false; + } + // Riptide increases the Chain Heal effect by 25% + if (riptide) + SetHitHeal(GetHitHeal() * 1.25f); + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_sha_chain_heal_SpellScript::HandleHeal, EFFECT_0, SPELL_EFFECT_HEAL); + } + + bool firstHeal; + bool riptide; + }; + + SpellScript* GetSpellScript() const + { + return new spell_sha_chain_heal_SpellScript(); + } +}; void AddSC_shaman_spell_scripts() { @@ -549,6 +658,7 @@ void AddSC_shaman_spell_scripts() new spell_sha_fire_nova(); new spell_sha_mana_tide_totem(); new spell_sha_earthbind_totem(); + new spell_sha_earthen_power(); new spell_sha_bloodlust(); new spell_sha_heroism(); new spell_sha_ancestral_awakening_proc(); @@ -556,4 +666,5 @@ void AddSC_shaman_spell_scripts() new spell_sha_healing_stream_totem(); new spell_sha_mana_spring_totem(); new spell_sha_lava_lash(); + new spell_sha_chain_heal(); } diff --git a/src/server/scripts/Spells/spell_warlock.cpp b/src/server/scripts/Spells/spell_warlock.cpp index 29a52406279..838b9e4f932 100644 --- a/src/server/scripts/Spells/spell_warlock.cpp +++ b/src/server/scripts/Spells/spell_warlock.cpp @@ -172,6 +172,19 @@ class spell_warl_create_healthstone : public SpellScriptLoader return true; } + SpellCastResult CheckCast() + { + if (Player* caster = GetCaster()->ToPlayer()) + { + uint8 spellRank = sSpellMgr->GetSpellRank(GetSpellInfo()->Id); + ItemPosCountVec dest; + InventoryResult msg = caster->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, iTypes[spellRank - 1][0], 1, NULL); + if (msg != EQUIP_ERR_OK) + return SPELL_FAILED_TOO_MANY_OF_ITEM; + } + return SPELL_CAST_OK; + } + void HandleScriptEffect(SpellEffIndex effIndex) { if (Unit* unitTarget = GetHitUnit()) @@ -198,6 +211,7 @@ class spell_warl_create_healthstone : public SpellScriptLoader void Register() { OnEffectHitTarget += SpellEffectFn(spell_warl_create_healthstone_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + OnCheckCast += SpellCheckCastFn(spell_warl_create_healthstone_SpellScript::CheckCast); } }; @@ -287,8 +301,8 @@ class spell_warl_seed_of_corruption : public SpellScriptLoader void FilterTargets(std::list<Unit*>& unitList) { - if (GetTargetUnit()) - unitList.remove(GetTargetUnit()); + if (GetExplTargetUnit()) + unitList.remove(GetExplTargetUnit()); } void Register() diff --git a/src/server/scripts/Spells/spell_warrior.cpp b/src/server/scripts/Spells/spell_warrior.cpp index 1084398c37d..0ba5c866d63 100644 --- a/src/server/scripts/Spells/spell_warrior.cpp +++ b/src/server/scripts/Spells/spell_warrior.cpp @@ -177,24 +177,27 @@ class spell_warr_deep_wounds : public SpellScriptLoader void HandleDummy(SpellEffIndex /* effIndex */) { int32 damage = GetEffectValue(); + Unit* caster = GetCaster(); if (Unit* target = GetHitUnit()) - if (Unit* caster = GetCaster()) - { - // apply percent damage mods - damage = caster->SpellDamageBonus(target, GetSpellInfo(), damage, SPELL_DIRECT_DAMAGE); + { + // apply percent damage mods + damage = caster->SpellDamageBonusDone(target, GetSpellInfo(), damage, SPELL_DIRECT_DAMAGE); - ApplyPctN(damage, 16 * sSpellMgr->GetSpellRank(GetSpellInfo()->Id)); + ApplyPctN(damage, 16 * sSpellMgr->GetSpellRank(GetSpellInfo()->Id)); + + damage = target->SpellDamageBonusTaken(caster, GetSpellInfo(), damage, SPELL_DIRECT_DAMAGE); + + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(SPELL_DEEP_WOUNDS_RANK_PERIODIC); + uint32 ticks = spellInfo->GetDuration() / spellInfo->Effects[EFFECT_0].Amplitude; - SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(SPELL_DEEP_WOUNDS_RANK_PERIODIC); - uint32 ticks = spellInfo->GetDuration() / spellInfo->Effects[EFFECT_0].Amplitude; + // Add remaining ticks to damage done + if (AuraEffect const* aurEff = target->GetAuraEffect(SPELL_DEEP_WOUNDS_RANK_PERIODIC, EFFECT_0, caster->GetGUID())) + damage += aurEff->GetAmount() * (ticks - aurEff->GetTickNumber()); - // Add remaining ticks to damage done - if (AuraEffect const* aurEff = target->GetAuraEffect(SPELL_DEEP_WOUNDS_RANK_PERIODIC, EFFECT_0, caster->GetGUID())) - damage += aurEff->GetAmount() * (ticks - aurEff->GetTickNumber()); + damage = damage / ticks; - damage = damage / ticks; - caster->CastCustomSpell(target, SPELL_DEEP_WOUNDS_RANK_PERIODIC, &damage, NULL, NULL, true); - } + caster->CastCustomSpell(target, SPELL_DEEP_WOUNDS_RANK_PERIODIC, &damage, NULL, NULL, true); + } } void Register() @@ -365,7 +368,7 @@ class spell_warr_concussion_blow : public SpellScriptLoader void HandleDummy(SpellEffIndex /* effIndex */) { - SetHitDamage(GetHitDamage() + CalculatePctF(GetHitDamage(),GetCaster()->GetTotalAttackPowerValue(BASE_ATTACK))); + SetHitDamage(CalculatePctN(GetCaster()->GetTotalAttackPowerValue(BASE_ATTACK), GetEffectValue())); } void Register() @@ -397,8 +400,7 @@ class spell_warr_bloodthirst : public SpellScriptLoader void HandleDummy(SpellEffIndex /* effIndex */) { int32 damage = GetEffectValue(); - if (GetHitUnit()) - GetCaster()->CastCustomSpell(GetHitUnit(), SPELL_BLOODTHIRST, &damage, NULL, NULL, true, NULL); + GetCaster()->CastCustomSpell(GetCaster(), SPELL_BLOODTHIRST, &damage, NULL, NULL, true, NULL); } void Register() @@ -413,6 +415,51 @@ class spell_warr_bloodthirst : public SpellScriptLoader } }; +enum Overpower +{ + SPELL_UNRELENTING_ASSAULT_RANK_1 = 46859, + SPELL_UNRELENTING_ASSAULT_RANK_2 = 46860, + SPELL_UNRELENTING_ASSAULT_TRIGGER_1 = 64849, + SPELL_UNRELENTING_ASSAULT_TRIGGER_2 = 64850, +}; + +class spell_warr_overpower : public SpellScriptLoader +{ +public: + spell_warr_overpower() : SpellScriptLoader("spell_warr_overpower") { } + + class spell_warr_overpower_SpellScript : public SpellScript + { + PrepareSpellScript(spell_warr_overpower_SpellScript); + + void HandleEffect(SpellEffIndex /* effIndex */) + { + uint32 spellId = 0; + if (GetCaster()->HasAura(SPELL_UNRELENTING_ASSAULT_RANK_1)) + spellId = SPELL_UNRELENTING_ASSAULT_TRIGGER_1; + else if (GetCaster()->HasAura(SPELL_UNRELENTING_ASSAULT_RANK_2)) + spellId = SPELL_UNRELENTING_ASSAULT_TRIGGER_2; + + if (!spellId) + return; + + if (Player* target = GetHitPlayer()) + if (target->HasUnitState(UNIT_STATE_CASTING)) + target->CastSpell(target, spellId, true); + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_warr_overpower_SpellScript::HandleEffect, EFFECT_0, SPELL_EFFECT_ANY); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_warr_overpower_SpellScript(); + } +}; + void AddSC_warrior_spell_scripts() { new spell_warr_last_stand(); @@ -424,4 +471,5 @@ void AddSC_warrior_spell_scripts() new spell_warr_execute(); new spell_warr_concussion_blow(); new spell_warr_bloodthirst(); + new spell_warr_overpower(); } diff --git a/src/server/scripts/World/go_scripts.cpp b/src/server/scripts/World/go_scripts.cpp index 60ddf8990a7..790a9d0f814 100644 --- a/src/server/scripts/World/go_scripts.cpp +++ b/src/server/scripts/World/go_scripts.cpp @@ -1174,7 +1174,7 @@ class go_gjalerbron_cage : public GameObjectScript player->KilledMonsterCredit(NPC_GJALERBRON_PRISONER, 0); prisoner->AI()->Talk(SAY_FREE); - prisoner->ForcedDespawn(6000); + prisoner->DespawnOrUnsummon(6000); } } return true; @@ -1201,7 +1201,7 @@ class go_large_gjalerbron_cage : public GameObjectScript { go->UseDoorOrButton(); player->KilledMonsterCredit(NPC_GJALERBRON_PRISONER, (*itr)->GetGUID()); - (*itr)->ForcedDespawn(6000); + (*itr)->DespawnOrUnsummon(6000); (*itr)->AI()->Talk(SAY_FREE); } } @@ -1235,7 +1235,7 @@ class go_veil_skith_cage : public GameObjectScript { go->UseDoorOrButton(); player->KilledMonsterCredit(NPC_CAPTIVE_CHILD, (*itr)->GetGUID()); - (*itr)->ForcedDespawn(5000); + (*itr)->DespawnOrUnsummon(5000); (*itr)->GetMotionMaster()->MovePoint(1, go->GetPositionX()+5, go->GetPositionY(), go->GetPositionZ()); (*itr)->AI()->Talk(SAY_FREE_0); (*itr)->GetMotionMaster()->Clear(); diff --git a/src/server/scripts/World/npcs_special.cpp b/src/server/scripts/World/npcs_special.cpp index d3dc577175d..ecd1a439a58 100644 --- a/src/server/scripts/World/npcs_special.cpp +++ b/src/server/scripts/World/npcs_special.cpp @@ -1975,33 +1975,31 @@ public: class npc_lightwell : public CreatureScript { -public: - npc_lightwell() : CreatureScript("npc_lightwell") { } - - struct npc_lightwellAI : public PassiveAI - { - npc_lightwellAI(Creature* creature) : PassiveAI(creature) {} + public: + npc_lightwell() : CreatureScript("npc_lightwell") { } - void Reset() + struct npc_lightwellAI : public PassiveAI { - DoCast(me, 59907, false); // Spell for Lightwell Charges - } + npc_lightwellAI(Creature* creature) : PassiveAI(creature) + { + DoCast(me, 59907, false); + } - void EnterEvadeMode() - { - if (!me->isAlive()) - return; + void EnterEvadeMode() + { + if (!me->isAlive()) + return; - me->DeleteThreatList(); - me->CombatStop(true); - me->ResetPlayerDamageReq(); - } - }; + me->DeleteThreatList(); + me->CombatStop(true); + me->ResetPlayerDamageReq(); + } + }; - CreatureAI* GetAI(Creature* creature) const - { - return new npc_lightwellAI(creature); - } + CreatureAI* GetAI(Creature* creature) const + { + return new npc_lightwellAI(creature); + } }; enum eTrainingDummy @@ -2099,34 +2097,26 @@ public: class npc_shadowfiend : public CreatureScript { -public: - npc_shadowfiend() : CreatureScript("npc_shadowfiend") { } - - struct npc_shadowfiendAI : public ScriptedAI - { - npc_shadowfiendAI(Creature* creature) : ScriptedAI(creature) {} + public: + npc_shadowfiend() : CreatureScript("npc_shadowfiend") { } - void DamageTaken(Unit* /*killer*/, uint32& damage) + struct npc_shadowfiendAI : public ScriptedAI { - if (me->isSummon()) - if (Unit* owner = me->ToTempSummon()->GetSummoner()) - if (owner->HasAura(GLYPH_OF_SHADOWFIEND) && damage >= me->GetHealth()) - owner->CastSpell(owner, GLYPH_OF_SHADOWFIEND_MANA, true); - } + npc_shadowfiendAI(Creature* creature) : ScriptedAI(creature) {} - void UpdateAI(uint32 const /*diff*/) - { - if (!UpdateVictim()) - return; + void DamageTaken(Unit* /*killer*/, uint32& damage) + { + if (me->isSummon()) + if (Unit* owner = me->ToTempSummon()->GetSummoner()) + if (owner->HasAura(GLYPH_OF_SHADOWFIEND) && damage >= me->GetHealth()) + owner->CastSpell(owner, GLYPH_OF_SHADOWFIEND_MANA, true); + } + }; - DoMeleeAttackIfReady(); + CreatureAI* GetAI(Creature* creature) const + { + return new npc_shadowfiendAI(creature); } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_shadowfiendAI(creature); - } }; /*###### @@ -2193,7 +2183,7 @@ public: } }; - CreatureAI *GetAI(Creature* creature) const + CreatureAI* GetAI(Creature* creature) const { return new npc_fire_elementalAI(creature); } @@ -2238,7 +2228,7 @@ public: } }; - CreatureAI *GetAI(Creature* creature) const + CreatureAI* GetAI(Creature* creature) const { return new npc_earth_elementalAI(creature); } @@ -2248,78 +2238,111 @@ public: # npc_wormhole ######*/ -#define GOSSIP_ENGINEERING1 "Borean Tundra." -#define GOSSIP_ENGINEERING2 "Howling Fjord." -#define GOSSIP_ENGINEERING3 "Sholazar Basin." -#define GOSSIP_ENGINEERING4 "Icecrown." -#define GOSSIP_ENGINEERING5 "Storm Peaks." +#define GOSSIP_ENGINEERING1 "Borean Tundra" +#define GOSSIP_ENGINEERING2 "Howling Fjord" +#define GOSSIP_ENGINEERING3 "Sholazar Basin" +#define GOSSIP_ENGINEERING4 "Icecrown" +#define GOSSIP_ENGINEERING5 "Storm Peaks" +#define GOSSIP_ENGINEERING6 "Underground..." -enum eWormhole +enum WormholeSpells { - SPELL_HOWLING_FJORD = 67838, + SPELL_BOREAN_TUNDRA = 67834, SPELL_SHOLAZAR_BASIN = 67835, SPELL_ICECROWN = 67836, SPELL_STORM_PEAKS = 67837, + SPELL_HOWLING_FJORD = 67838, + SPELL_UNDERGROUND = 68081, + + TEXT_WORMHOLE = 907, - TEXT_WORMHOLE = 907 + DATA_SHOW_UNDERGROUND = 1, }; class npc_wormhole : public CreatureScript { -public: - npc_wormhole() : CreatureScript("npc_wormhole") { } + public: + npc_wormhole() : CreatureScript("npc_wormhole") {} - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isSummon()) + struct npc_wormholeAI : public PassiveAI + { + npc_wormholeAI(Creature* creature) : PassiveAI(creature) {} + + void InitializeAI() + { + _showUnderground = urand(0, 100) == 0; // Guessed value, it is really rare though + } + + uint32 GetData(uint32 type) + { + return (type == DATA_SHOW_UNDERGROUND && _showUnderground) ? 1 : 0; + } + + private: + bool _showUnderground; + }; + + bool OnGossipHello(Player* player, Creature* creature) { - if (player == creature->ToTempSummon()->GetSummoner()) + if (creature->isSummon()) { - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ENGINEERING1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ENGINEERING2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ENGINEERING3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ENGINEERING4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 4); - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ENGINEERING5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 5); + if (player == creature->ToTempSummon()->GetSummoner()) + { + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ENGINEERING1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ENGINEERING2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ENGINEERING3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ENGINEERING4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 4); + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ENGINEERING5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 5); - player->PlayerTalkClass->SendGossipMenu(TEXT_WORMHOLE, creature->GetGUID()); + if (creature->AI()->GetData(DATA_SHOW_UNDERGROUND)) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ENGINEERING6, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 6); + + player->PlayerTalkClass->SendGossipMenu(TEXT_WORMHOLE, creature->GetGUID()); + } } + + return true; } - return true; - } - bool OnGossipSelect(Player* player, Creature* /*creature*/, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - bool roll = urand(0, 1); + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); - switch (action) + switch (action) + { + case GOSSIP_ACTION_INFO_DEF + 1: // Borean Tundra + player->CLOSE_GOSSIP_MENU(); + creature->CastSpell(player, SPELL_BOREAN_TUNDRA, false); + break; + case GOSSIP_ACTION_INFO_DEF + 2: // Howling Fjord + player->CLOSE_GOSSIP_MENU(); + creature->CastSpell(player, SPELL_HOWLING_FJORD, false); + break; + case GOSSIP_ACTION_INFO_DEF + 3: // Sholazar Basin + player->CLOSE_GOSSIP_MENU(); + creature->CastSpell(player, SPELL_SHOLAZAR_BASIN, false); + break; + case GOSSIP_ACTION_INFO_DEF + 4: // Icecrown + player->CLOSE_GOSSIP_MENU(); + creature->CastSpell(player, SPELL_ICECROWN, false); + break; + case GOSSIP_ACTION_INFO_DEF + 5: // Storm peaks + player->CLOSE_GOSSIP_MENU(); + creature->CastSpell(player, SPELL_STORM_PEAKS, false); + break; + case GOSSIP_ACTION_INFO_DEF + 6: // Underground + player->CLOSE_GOSSIP_MENU(); + creature->CastSpell(player, SPELL_UNDERGROUND, false); + break; + } + + return true; + } + + CreatureAI* GetAI(Creature* creature) const { - case GOSSIP_ACTION_INFO_DEF + 1: //Borean Tundra - player->CLOSE_GOSSIP_MENU(); - if (roll) //At the moment we don't have chance on spell_target_position table so we hack this - player->TeleportTo(571, 4305.505859f, 5450.839844f, 63.005806f, 0.627286f); - else - player->TeleportTo(571, 3201.936279f, 5630.123535f, 133.658798f, 3.855272f); - break; - case GOSSIP_ACTION_INFO_DEF + 2: //Howling Fjord - player->CLOSE_GOSSIP_MENU(); - player->CastSpell(player, SPELL_HOWLING_FJORD, true); - break; - case GOSSIP_ACTION_INFO_DEF + 3: //Sholazar Basin - player->CLOSE_GOSSIP_MENU(); - player->CastSpell(player, SPELL_SHOLAZAR_BASIN, true); - break; - case GOSSIP_ACTION_INFO_DEF + 4: //Icecrown - player->CLOSE_GOSSIP_MENU(); - player->CastSpell(player, SPELL_ICECROWN, true); - break; - case GOSSIP_ACTION_INFO_DEF + 5: //Storm peaks - player->CLOSE_GOSSIP_MENU(); - player->CastSpell(player, SPELL_STORM_PEAKS, true); - break; + return new npc_wormholeAI(creature); } - return true; - } }; /*###### @@ -2400,6 +2423,9 @@ enum eLockSmith QUEST_HOTTER_THAN_HELL_H = 10764, QUEST_RETURN_TO_KHAGDAR = 9837, QUEST_CONTAINMENT = 13159, + QUEST_ETERNAL_VIGILANCE = 11011, + QUEST_KEY_TO_THE_FOCUSING_IRIS = 13372, + QUEST_HC_KEY_TO_THE_FOCUSING_IRIS = 13375, ITEM_ARCATRAZ_KEY = 31084, ITEM_SHADOWFORGE_KEY = 11000, @@ -2407,21 +2433,28 @@ enum eLockSmith ITEM_SHATTERED_HALLS_KEY = 28395, ITEM_THE_MASTERS_KEY = 24490, ITEM_VIOLET_HOLD_KEY = 42482, + ITEM_ESSENCE_INFUSED_MOONSTONE = 32449, + ITEM_KEY_TO_THE_FOCUSING_IRIS = 44582, + ITEM_HC_KEY_TO_THE_FOCUSING_IRIS = 44581, SPELL_ARCATRAZ_KEY = 54881, SPELL_SHADOWFORGE_KEY = 54882, SPELL_SKELETON_KEY = 54883, SPELL_SHATTERED_HALLS_KEY = 54884, SPELL_THE_MASTERS_KEY = 54885, - SPELL_VIOLET_HOLD_KEY = 67253 + SPELL_VIOLET_HOLD_KEY = 67253, + SPELL_ESSENCE_INFUSED_MOONSTONE = 40173, }; -#define GOSSIP_LOST_ARCATRAZ_KEY "I've lost my key to the Arcatraz." -#define GOSSIP_LOST_SHADOWFORGE_KEY "I've lost my key to the Blackrock Depths." -#define GOSSIP_LOST_SKELETON_KEY "I've lost my key to the Scholomance." -#define GOSSIP_LOST_SHATTERED_HALLS_KEY "I've lost my key to the Shattered Halls." -#define GOSSIP_LOST_THE_MASTERS_KEY "I've lost my key to the Karazhan." -#define GOSSIP_LOST_VIOLET_HOLD_KEY "I've lost my key to the Violet Hold." +#define GOSSIP_LOST_ARCATRAZ_KEY "I've lost my key to the Arcatraz." +#define GOSSIP_LOST_SHADOWFORGE_KEY "I've lost my key to the Blackrock Depths." +#define GOSSIP_LOST_SKELETON_KEY "I've lost my key to the Scholomance." +#define GOSSIP_LOST_SHATTERED_HALLS_KEY "I've lost my key to the Shattered Halls." +#define GOSSIP_LOST_THE_MASTERS_KEY "I've lost my key to the Karazhan." +#define GOSSIP_LOST_VIOLET_HOLD_KEY "I've lost my key to the Violet Hold." +#define GOSSIP_LOST_ESSENCE_INFUSED_MOONSTONE "I've lost my Essence-Infused Moonstone." +#define GOSSIP_LOST_KEY_TO_THE_FOCUSING_IRIS "I've lost my Key to the Focusing Iris." +#define GOSSIP_LOST_HC_KEY_TO_THE_FOCUSING_IRIS "I've lost my Heroic Key to the Focusing Iris." class npc_locksmith : public CreatureScript { @@ -2456,6 +2489,18 @@ public: if (player->GetQuestRewardStatus(QUEST_CONTAINMENT) && !player->HasItemCount(ITEM_VIOLET_HOLD_KEY, 1, true)) player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LOST_VIOLET_HOLD_KEY, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 6); + // Essence-Infused Moonstone + if (player->GetQuestRewardStatus(QUEST_ETERNAL_VIGILANCE) && !player->HasItemCount(ITEM_ESSENCE_INFUSED_MOONSTONE, 1, true)) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LOST_ESSENCE_INFUSED_MOONSTONE, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 7); + + // Key to the Focusing Iris + if (player->GetQuestRewardStatus(QUEST_KEY_TO_THE_FOCUSING_IRIS) && !player->HasItemCount(ITEM_KEY_TO_THE_FOCUSING_IRIS, 1, true)) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LOST_KEY_TO_THE_FOCUSING_IRIS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 8); + + // Heroic Key to the Focusing Iris + if (player->GetQuestRewardStatus(QUEST_HC_KEY_TO_THE_FOCUSING_IRIS) && !player->HasItemCount(ITEM_HC_KEY_TO_THE_FOCUSING_IRIS, 1, true)) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LOST_HC_KEY_TO_THE_FOCUSING_IRIS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 9); + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); return true; @@ -2490,171 +2535,17 @@ public: player->CLOSE_GOSSIP_MENU(); player->CastSpell(player, SPELL_VIOLET_HOLD_KEY, false); break; - } - return true; - } -}; - -/*###### -## npc_tabard_vendor -######*/ - -enum -{ - QUEST_TRUE_MASTERS_OF_LIGHT = 9737, - QUEST_THE_UNWRITTEN_PROPHECY = 9762, - QUEST_INTO_THE_BREACH = 10259, - QUEST_BATTLE_OF_THE_CRIMSON_WATCH = 10781, - QUEST_SHARDS_OF_AHUNE = 11972, - - ACHIEVEMENT_EXPLORE_NORTHREND = 45, - ACHIEVEMENT_TWENTYFIVE_TABARDS = 1021, - ACHIEVEMENT_THE_LOREMASTER_A = 1681, - ACHIEVEMENT_THE_LOREMASTER_H = 1682, - - ITEM_TABARD_OF_THE_HAND = 24344, - ITEM_TABARD_OF_THE_BLOOD_KNIGHT = 25549, - ITEM_TABARD_OF_THE_PROTECTOR = 28788, - ITEM_OFFERING_OF_THE_SHATAR = 31408, - ITEM_GREEN_TROPHY_TABARD_OF_THE_ILLIDARI = 31404, - ITEM_PURPLE_TROPHY_TABARD_OF_THE_ILLIDARI = 31405, - ITEM_TABARD_OF_THE_SUMMER_SKIES = 35279, - ITEM_TABARD_OF_THE_SUMMER_FLAMES = 35280, - ITEM_TABARD_OF_THE_ACHIEVER = 40643, - ITEM_LOREMASTERS_COLORS = 43300, - ITEM_TABARD_OF_THE_EXPLORER = 43348, - - SPELL_TABARD_OF_THE_BLOOD_KNIGHT = 54974, - SPELL_TABARD_OF_THE_HAND = 54976, - SPELL_GREEN_TROPHY_TABARD_OF_THE_ILLIDARI = 54977, - SPELL_PURPLE_TROPHY_TABARD_OF_THE_ILLIDARI = 54982, - SPELL_TABARD_OF_THE_ACHIEVER = 55006, - SPELL_TABARD_OF_THE_PROTECTOR = 55008, - SPELL_LOREMASTERS_COLORS = 58194, - SPELL_TABARD_OF_THE_EXPLORER = 58224, - SPELL_TABARD_OF_SUMMER_SKIES = 62768, - SPELL_TABARD_OF_SUMMER_FLAMES = 62769 -}; - -#define GOSSIP_LOST_TABARD_OF_BLOOD_KNIGHT "I've lost my Tabard of Blood Knight." -#define GOSSIP_LOST_TABARD_OF_THE_HAND "I've lost my Tabard of the Hand." -#define GOSSIP_LOST_TABARD_OF_THE_PROTECTOR "I've lost my Tabard of the Protector." -#define GOSSIP_LOST_GREEN_TROPHY_TABARD_OF_THE_ILLIDARI "I've lost my Green Trophy Tabard of the Illidari." -#define GOSSIP_LOST_PURPLE_TROPHY_TABARD_OF_THE_ILLIDARI "I've lost my Purple Trophy Tabard of the Illidari." -#define GOSSIP_LOST_TABARD_OF_SUMMER_SKIES "I've lost my Tabard of Summer Skies." -#define GOSSIP_LOST_TABARD_OF_SUMMER_FLAMES "I've lost my Tabard of Summer Flames." -#define GOSSIP_LOST_LOREMASTERS_COLORS "I've lost my Loremaster's Colors." -#define GOSSIP_LOST_TABARD_OF_THE_EXPLORER "I've lost my Tabard of the Explorer." -#define GOSSIP_LOST_TABARD_OF_THE_ACHIEVER "I've lost my Tabard of the Achiever." - -class npc_tabard_vendor : public CreatureScript -{ -public: - npc_tabard_vendor() : CreatureScript("npc_tabard_vendor") { } - - bool OnGossipHello(Player* player, Creature* creature) - { - bool lostBloodKnight = false; - bool lostHand = false; - bool lostProtector = false; - bool lostIllidari = false; - bool lostSummer = false; - - //Tabard of the Blood Knight - if (player->GetQuestRewardStatus(QUEST_TRUE_MASTERS_OF_LIGHT) && !player->HasItemCount(ITEM_TABARD_OF_THE_BLOOD_KNIGHT, 1, true)) - lostBloodKnight = true; - - //Tabard of the Hand - if (player->GetQuestRewardStatus(QUEST_THE_UNWRITTEN_PROPHECY) && !player->HasItemCount(ITEM_TABARD_OF_THE_HAND, 1, true)) - lostHand = true; - - //Tabard of the Protector - if (player->GetQuestRewardStatus(QUEST_INTO_THE_BREACH) && !player->HasItemCount(ITEM_TABARD_OF_THE_PROTECTOR, 1, true)) - lostProtector = true; - - //Green Trophy Tabard of the Illidari - //Purple Trophy Tabard of the Illidari - if (player->GetQuestRewardStatus(QUEST_BATTLE_OF_THE_CRIMSON_WATCH) && - (!player->HasItemCount(ITEM_GREEN_TROPHY_TABARD_OF_THE_ILLIDARI, 1, true) && - !player->HasItemCount(ITEM_PURPLE_TROPHY_TABARD_OF_THE_ILLIDARI, 1, true) && - !player->HasItemCount(ITEM_OFFERING_OF_THE_SHATAR, 1, true))) - lostIllidari = true; - - //Tabard of Summer Skies - //Tabard of Summer Flames - if (player->GetQuestRewardStatus(QUEST_SHARDS_OF_AHUNE) && - !player->HasItemCount(ITEM_TABARD_OF_THE_SUMMER_SKIES, 1, true) && - !player->HasItemCount(ITEM_TABARD_OF_THE_SUMMER_FLAMES, 1, true)) - lostSummer = true; - - if (lostBloodKnight || lostHand || lostProtector || lostIllidari || lostSummer) - { - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE); - - if (lostBloodKnight) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LOST_TABARD_OF_BLOOD_KNIGHT, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); - - if (lostHand) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LOST_TABARD_OF_THE_HAND, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); - - if (lostProtector) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LOST_TABARD_OF_THE_PROTECTOR, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); - - if (lostIllidari) - { - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LOST_GREEN_TROPHY_TABARD_OF_THE_ILLIDARI, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 4); - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LOST_PURPLE_TROPHY_TABARD_OF_THE_ILLIDARI, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 5); - } - - if (lostSummer) - { - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LOST_TABARD_OF_SUMMER_SKIES, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 6); - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LOST_TABARD_OF_SUMMER_FLAMES, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 7); - } - - player->SEND_GOSSIP_MENU(13583, creature->GetGUID()); - } - else - player->GetSession()->SendListInventory(creature->GetGUID()); - - return true; - } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - switch (action) - { - case GOSSIP_ACTION_TRADE: - player->GetSession()->SendListInventory(creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF + 1: - player->CLOSE_GOSSIP_MENU(); - player->CastSpell(player, SPELL_TABARD_OF_THE_BLOOD_KNIGHT, false); - break; - case GOSSIP_ACTION_INFO_DEF + 2: - player->CLOSE_GOSSIP_MENU(); - player->CastSpell(player, SPELL_TABARD_OF_THE_HAND, false); - break; - case GOSSIP_ACTION_INFO_DEF + 3: - player->CLOSE_GOSSIP_MENU(); - player->CastSpell(player, SPELL_TABARD_OF_THE_PROTECTOR, false); - break; - case GOSSIP_ACTION_INFO_DEF + 4: - player->CLOSE_GOSSIP_MENU(); - player->CastSpell(player, SPELL_GREEN_TROPHY_TABARD_OF_THE_ILLIDARI, false); - break; - case GOSSIP_ACTION_INFO_DEF + 5: + case GOSSIP_ACTION_INFO_DEF + 7: player->CLOSE_GOSSIP_MENU(); - player->CastSpell(player, SPELL_PURPLE_TROPHY_TABARD_OF_THE_ILLIDARI, false); + player->CastSpell(player, SPELL_ESSENCE_INFUSED_MOONSTONE, false); break; - case GOSSIP_ACTION_INFO_DEF + 6: + case GOSSIP_ACTION_INFO_DEF + 8: player->CLOSE_GOSSIP_MENU(); - player->CastSpell(player, SPELL_TABARD_OF_SUMMER_SKIES, false); + player->AddItem(ITEM_KEY_TO_THE_FOCUSING_IRIS,1); break; - case GOSSIP_ACTION_INFO_DEF + 7: + case GOSSIP_ACTION_INFO_DEF + 9: player->CLOSE_GOSSIP_MENU(); - player->CastSpell(player, SPELL_TABARD_OF_SUMMER_FLAMES, false); + player->AddItem(ITEM_HC_KEY_TO_THE_FOCUSING_IRIS,1); break; } return true; @@ -2997,7 +2888,7 @@ public: } }; - CreatureAI *GetAI(Creature* creature) const + CreatureAI* GetAI(Creature* creature) const { return new npc_fireworkAI(creature); } @@ -3099,35 +2990,34 @@ public: void AddSC_npcs_special() { - new npc_air_force_bots; - new npc_lunaclaw_spirit; - new npc_chicken_cluck; - new npc_dancing_flames; - new npc_doctor; - new npc_injured_patient; - new npc_garments_of_quests; - new npc_guardian; - new npc_mount_vendor; - new npc_rogue_trainer; - new npc_sayge; - new npc_steam_tonk; - new npc_tonk_mine; - new npc_winter_reveler; - new npc_brewfest_reveler; - new npc_snake_trap; - new npc_mirror_image; - new npc_ebon_gargoyle; - new npc_lightwell; - new mob_mojo; - new npc_training_dummy; - new npc_shadowfiend; - new npc_wormhole; - new npc_pet_trainer; - new npc_locksmith; - new npc_tabard_vendor; - new npc_experience; - new npc_fire_elemental; - new npc_earth_elemental; - new npc_firework; + new npc_air_force_bots(); + new npc_lunaclaw_spirit(); + new npc_chicken_cluck(); + new npc_dancing_flames(); + new npc_doctor(); + new npc_injured_patient(); + new npc_garments_of_quests(); + new npc_guardian(); + new npc_mount_vendor(); + new npc_rogue_trainer(); + new npc_sayge(); + new npc_steam_tonk(); + new npc_tonk_mine(); + new npc_winter_reveler(); + new npc_brewfest_reveler(); + new npc_snake_trap(); + new npc_mirror_image(); + new npc_ebon_gargoyle(); + new npc_lightwell(); + new mob_mojo(); + new npc_training_dummy(); + new npc_shadowfiend(); + new npc_wormhole(); + new npc_pet_trainer(); + new npc_locksmith(); + new npc_experience(); + new npc_fire_elemental(); + new npc_earth_elemental(); + new npc_firework(); new npc_spring_rabbit(); } diff --git a/src/server/shared/CMakeLists.txt b/src/server/shared/CMakeLists.txt index 3ec35b5394a..de998442419 100644 --- a/src/server/shared/CMakeLists.txt +++ b/src/server/shared/CMakeLists.txt @@ -53,7 +53,6 @@ set(shared_STAT_SRCS include_directories( ${CMAKE_BINARY_DIR} ${CMAKE_SOURCE_DIR}/dep/SFMT - ${CMAKE_SOURCE_DIR}/dep/mersennetwister ${CMAKE_SOURCE_DIR}/dep/sockets/include ${CMAKE_SOURCE_DIR}/dep/utf8cpp ${CMAKE_SOURCE_DIR}/src/server diff --git a/src/server/shared/Containers.h b/src/server/shared/Containers.h new file mode 100644 index 00000000000..f0242cbff0e --- /dev/null +++ b/src/server/shared/Containers.h @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef TRINITY_CONTAINERS_H +#define TRINITY_CONTAINERS_H + +#include <list> + +//! Because circular includes are bad +extern uint32 urand(uint32 min, uint32 max); + +namespace Trinity +{ + namespace Containers + { + template<class T> + void RandomResizeList(std::list<T> &list, uint32 size) + { + size_t list_size = list.size(); + + while (list_size > size) + { + typename std::list<T>::iterator itr = list.begin(); + std::advance(itr, urand(0, list_size - 1)); + list.erase(itr); + --list_size; + } + } + + template<class T, class Predicate> + void RandomResizeList(std::list<T> &list, Predicate& predicate, uint32 size) + { + //! First use predicate filter + std::list<T> listCopy; + for (typename std::list<T>::iterator itr = list.begin(); itr != list.end(); ++itr) + if (predicate(*itr)) + listCopy.push_back(*itr); + + if (size) + RandomResizeList(listCopy, size); + + list = listCopy; + } + + /* Select a random element from a container. Note: make sure you explicitly empty check the container */ + template <class C> typename C::value_type const& SelectRandomContainerElement(C const& container) + { + typename C::const_iterator it = container.begin(); + std::advance(it, urand(0, container.size() - 1)); + return *it; + } + }; + //! namespace Containers +}; +//! namespace Trinity + +#endif //! #ifdef TRINITY_CONTAINERS_H
\ No newline at end of file diff --git a/src/server/shared/Database/DatabaseWorkerPool.h b/src/server/shared/Database/DatabaseWorkerPool.h index 5fe31006bb2..314d196cc06 100755 --- a/src/server/shared/Database/DatabaseWorkerPool.h +++ b/src/server/shared/Database/DatabaseWorkerPool.h @@ -102,7 +102,7 @@ class DatabaseWorkerPool //! Shuts down delaythreads for this connection pool by underlying deactivate(). //! The next dequeue attempt in the worker thread tasks will result in an error, - //! ultimately ending the worker thread task. + //! ultimately ending the worker thread task. _queue->queue()->close(); for (uint8 i = 0; i < _connectionCount[IDX_ASYNC]; ++i) @@ -114,7 +114,7 @@ class DatabaseWorkerPool t->Close(); //! Closes the actualy MySQL connection. } - sLog->outSQLDriver("Asynchronous connections on DatabasePool '%s' terminated. Proceeding with synchronous connections.", + sLog->outSQLDriver("Asynchronous connections on DatabasePool '%s' terminated. Proceeding with synchronous connections.", GetDatabaseName()); //! Shut down the synchronous connections @@ -239,7 +239,7 @@ class DatabaseWorkerPool va_list ap; char szQuery[MAX_QUERY_LEN]; - va_start(ap, sql); + va_start(ap, conn); vsnprintf(szQuery, MAX_QUERY_LEN, sql, ap); va_end(ap); diff --git a/src/server/shared/Database/Field.h b/src/server/shared/Database/Field.h index 2c5e7d47ca4..bfa42dbe574 100755 --- a/src/server/shared/Database/Field.h +++ b/src/server/shared/Database/Field.h @@ -43,11 +43,11 @@ class Field #ifdef TRINITY_DEBUG if (!IsType(MYSQL_TYPE_TINY)) { - sLog->outSQLDriver("Warning: GetUInt8() on non-tinyint field."); + sLog->outSQLDriver("Warning: GetUInt8() on non-tinyint field. Using type: %s.", FieldTypeToString(data.type)); return 0; } - #endif + if (data.raw) return *reinterpret_cast<uint8*>(data.value); return static_cast<uint8>(atol((char*)data.value)); @@ -61,7 +61,7 @@ class Field #ifdef TRINITY_DEBUG if (!IsType(MYSQL_TYPE_TINY)) { - sLog->outSQLDriver("Warning: GetInt8() on non-tinyint field."); + sLog->outSQLDriver("Warning: GetInt8() on non-tinyint field. Using type: %s.", FieldTypeToString(data.type)); return 0; } #endif @@ -79,7 +79,7 @@ class Field #ifdef TRINITY_DEBUG if (!IsType(MYSQL_TYPE_SHORT) && !IsType(MYSQL_TYPE_YEAR)) { - sLog->outSQLDriver("Warning: GetUInt16() on non-smallint field."); + sLog->outSQLDriver("Warning: GetUInt16() on non-smallint field. Using type: %s.", FieldTypeToString(data.type)); return 0; } #endif @@ -97,7 +97,7 @@ class Field #ifdef TRINITY_DEBUG if (!IsType(MYSQL_TYPE_SHORT) && !IsType(MYSQL_TYPE_YEAR)) { - sLog->outSQLDriver("Warning: GetInt16() on non-smallint field."); + sLog->outSQLDriver("Warning: GetInt16() on non-smallint field. Using type: %s.", FieldTypeToString(data.type)); return 0; } #endif @@ -115,7 +115,7 @@ class Field #ifdef TRINITY_DEBUG if (!IsType(MYSQL_TYPE_INT24) && !IsType(MYSQL_TYPE_LONG)) { - sLog->outSQLDriver("Warning: GetUInt32() on non-(medium)int field."); + sLog->outSQLDriver("Warning: GetUInt32() on non-(medium)int field. Using type: %s.", FieldTypeToString(data.type)); return 0; } #endif @@ -133,7 +133,7 @@ class Field #ifdef TRINITY_DEBUG if (!IsType(MYSQL_TYPE_INT24) && !IsType(MYSQL_TYPE_LONG)) { - sLog->outSQLDriver("Warning: GetInt32() on non-(medium)int field."); + sLog->outSQLDriver("Warning: GetInt32() on non-(medium)int field. Using type: %s.", FieldTypeToString(data.type)); return 0; } #endif @@ -151,7 +151,7 @@ class Field #ifdef TRINITY_DEBUG if (!IsType(MYSQL_TYPE_LONGLONG) && !IsType(MYSQL_TYPE_BIT)) { - sLog->outSQLDriver("Warning: GetUInt64() on non-bigint field."); + sLog->outSQLDriver("Warning: GetUInt64() on non-bigint field. Using type: %s.", FieldTypeToString(data.type)); return 0; } #endif @@ -169,7 +169,7 @@ class Field #ifdef TRINITY_DEBUG if (!IsType(MYSQL_TYPE_LONGLONG) && !IsType(MYSQL_TYPE_BIT)) { - sLog->outSQLDriver("Warning: GetInt64() on non-bigint field."); + sLog->outSQLDriver("Warning: GetInt64() on non-bigint field. Using type: %s.", FieldTypeToString(data.type)); return 0; } #endif @@ -187,7 +187,7 @@ class Field #ifdef TRINITY_DEBUG if (!IsType(MYSQL_TYPE_FLOAT)) { - sLog->outSQLDriver("Warning: GetFloat() on non-float field."); + sLog->outSQLDriver("Warning: GetFloat() on non-float field. Using type: %s.", FieldTypeToString(data.type)); return 0.0f; } #endif @@ -205,7 +205,7 @@ class Field #ifdef TRINITY_DEBUG if (!IsType(MYSQL_TYPE_DOUBLE)) { - sLog->outSQLDriver("Warning: GetDouble() on non-double field."); + sLog->outSQLDriver("Warning: GetDouble() on non-double field. Using type: %s.", FieldTypeToString(data.type)); return 0.0f; } #endif @@ -215,7 +215,7 @@ class Field return static_cast<double>(atof((char*)data.value)); } - const char* GetCString() const + char const* GetCString() const { if (!data.value) return NULL; @@ -223,11 +223,12 @@ class Field #ifdef TRINITY_DEBUG if (IsNumeric()) { - sLog->outSQLDriver("Error: GetCString() on numeric field."); + sLog->outSQLDriver("Error: GetCString() on numeric field. Using type: %s.", FieldTypeToString(data.type)); return NULL; } #endif - return static_cast<const char*>(data.value); + return static_cast<char const*>(data.value); + } std::string GetString() const @@ -237,7 +238,7 @@ class Field if (data.raw) { - const char* string = GetCString(); + char const* string = GetCString(); if (!string) string = ""; return std::string(string, data.length); @@ -267,7 +268,7 @@ class Field #pragma pack(pop) #endif - void SetByteValue(const void* newValue, const size_t newSize, enum_field_types newType, uint32 length); + void SetByteValue(void const* newValue, size_t const newSize, enum_field_types newType, uint32 length); void SetStructuredValue(char* newValue, enum_field_types newType); void CleanUp() @@ -341,6 +342,43 @@ class Field data.type == MYSQL_TYPE_DOUBLE || data.type == MYSQL_TYPE_LONGLONG ); } + + private: + #ifdef TRINITY_DEBUG + static char const* FieldTypeToString(enum_field_types type) + { + switch (type) + { + case MYSQL_TYPE_BIT: return "BIT"; + case MYSQL_TYPE_BLOB: return "BLOB"; + case MYSQL_TYPE_DATE: return "DATE"; + case MYSQL_TYPE_DATETIME: return "DATETIME"; + case MYSQL_TYPE_NEWDECIMAL: return "NEWDECIMAL"; + case MYSQL_TYPE_DECIMAL: return "DECIMAL"; + case MYSQL_TYPE_DOUBLE: return "DOUBLE"; + case MYSQL_TYPE_ENUM: return "ENUM"; + case MYSQL_TYPE_FLOAT: return "FLOAT"; + case MYSQL_TYPE_GEOMETRY: return "GEOMETRY"; + case MYSQL_TYPE_INT24: return "INT24"; + case MYSQL_TYPE_LONG: return "LONG"; + case MYSQL_TYPE_LONGLONG: return "LONGLONG"; + case MYSQL_TYPE_LONG_BLOB: return "LONG_BLOB"; + case MYSQL_TYPE_MEDIUM_BLOB: return "MEDIUM_BLOB"; + case MYSQL_TYPE_NEWDATE: return "NEWDATE"; + case MYSQL_TYPE_NULL: return "NULL"; + case MYSQL_TYPE_SET: return "SET"; + case MYSQL_TYPE_SHORT: return "SHORT"; + case MYSQL_TYPE_STRING: return "STRING"; + case MYSQL_TYPE_TIME: return "TIME"; + case MYSQL_TYPE_TIMESTAMP: return "TIMESTAMP"; + case MYSQL_TYPE_TINY: return "TINY"; + case MYSQL_TYPE_TINY_BLOB: return "TINY_BLOB"; + case MYSQL_TYPE_VAR_STRING: return "VAR_STRING"; + case MYSQL_TYPE_YEAR: return "YEAR"; + default: return "-Unknown-"; + } + } + #endif }; #endif diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.cpp b/src/server/shared/Database/Implementation/CharacterDatabase.cpp index 22de70b993b..d315c6417ea 100644 --- a/src/server/shared/Database/Implementation/CharacterDatabase.cpp +++ b/src/server/shared/Database/Implementation/CharacterDatabase.cpp @@ -27,12 +27,13 @@ void CharacterDatabaseConnection::DoPrepareStatements() PREPARE_STATEMENT(CHAR_DEL_NONEXISTENT_GUILD_BANK_ITEM, "DELETE FROM guild_bank_item WHERE guildid = ? AND TabId = ? AND SlotId = ?", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_DEL_EXPIRED_BANS, "UPDATE character_banned SET active = 0 WHERE unbandate <= UNIX_TIMESTAMP() AND unbandate <> bandate", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_SEL_GUID_BY_NAME, "SELECT guid FROM characters WHERE name = ?", CONNECTION_BOTH); - PREPARE_STATEMENT(CHAR_SEL_CHECK_NAME, "SELECT 1 FROM characters WHERE name = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_SEL_CHECK_NAME, "SELECT 1 FROM characters WHERE name = ?", CONNECTION_BOTH); PREPARE_STATEMENT(CHAR_SEL_CHECK_GUID, "SELECT 1 FROM characters WHERE guid = ?", CONNECTION_SYNCH); - PREPARE_STATEMENT(CHAR_SEL_SUM_CHARS, "SELECT COUNT(guid) FROM characters WHERE account = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_SEL_SUM_CHARS, "SELECT COUNT(guid) FROM characters WHERE account = ?", CONNECTION_BOTH); PREPARE_STATEMENT(CHAR_SEL_CHAR_CREATE_INFO, "SELECT level, race, class FROM characters WHERE account = ? LIMIT 0, ?", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_INS_CHARACTER_BAN, "INSERT INTO character_banned VALUES (?, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()+?, ?, ?, 1)", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_UPD_CHARACTER_BAN, "UPDATE character_banned SET active = 0 WHERE guid = ? AND active != 0", CONNECTION_ASYNC) + PREPARE_STATEMENT(CHAR_DEL_CHARACTER_BAN, "DELETE cb FROM character_banned cb INNER JOIN characters c ON c.guid = cb.guid WHERE c.account = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_SEL_BANINFO, "SELECT FROM_UNIXTIME(bandate), unbandate-bandate, active, unbandate, banreason, bannedby FROM character_banned WHERE guid = ? ORDER BY bandate ASC", CONNECTION_SYNCH) PREPARE_STATEMENT(CHAR_SEL_GUID_BY_NAME_FILTER, "SELECT guid, name FROM characters WHERE name LIKE CONCAT('%%', ?, '%%')", CONNECTION_SYNCH) PREPARE_STATEMENT(CHAR_SEL_BANINFO_LIST, "SELECT bandate, unbandate, bannedby, banreason FROM character_banned WHERE guid = ? ORDER BY unbandate", CONNECTION_SYNCH) @@ -48,6 +49,7 @@ void CharacterDatabaseConnection::DoPrepareStatements() PREPARE_STATEMENT(CHAR_SEL_CHAR_RACE, "SELECT race FROM characters WHERE guid = ?", CONNECTION_SYNCH); PREPARE_STATEMENT(CHAR_SEL_CHAR_LEVEL, "SELECT level FROM characters WHERE guid = ?", CONNECTION_SYNCH); PREPARE_STATEMENT(CHAR_SEL_CHAR_ZONE, "SELECT zone FROM characters WHERE guid = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_SEL_CHARACTER_NAME_DATA, "SELECT race, class, gender FROM characters WHERE guid = ?", CONNECTION_SYNCH); PREPARE_STATEMENT(CHAR_SEL_CHAR_POSITION_XYZ, "SELECT map, position_x, position_y, position_z FROM characters WHERE guid = ?", CONNECTION_SYNCH); PREPARE_STATEMENT(CHAR_SEL_CHAR_POSITION, "SELECT position_x, position_y, position_z, orientation, map, taxi_path FROM characters WHERE guid = ?", CONNECTION_SYNCH); PREPARE_STATEMENT(CHAR_DEL_QUEST_STATUS_DAILY, "DELETE FROM character_queststatus_daily", CONNECTION_ASYNC); @@ -129,7 +131,6 @@ void CharacterDatabaseConnection::DoPrepareStatements() PREPARE_STATEMENT(CHAR_DEL_ITEM_BOP_TRADE, "DELETE FROM item_soulbound_trade_data WHERE itemGuid = ? LIMIT 1", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_INS_ITEM_BOP_TRADE, "INSERT INTO item_soulbound_trade_data VALUES (?, ?)", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_REP_INVENTORY_ITEM, "REPLACE INTO character_inventory (guid, bag, slot, item) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC) - PREPARE_STATEMENT(CHAR_DEL_INVENTORY_ITEM, "DELETE FROM character_inventory WHERE item = ?", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_REP_ITEM_INSTANCE, "REPLACE INTO item_instance (itemEntry, owner_guid, creatorGuid, giftCreatorGuid, count, duration, charges, flags, enchantments, randomPropertyId, durability, playedTime, text, guid) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_UPD_ITEM_INSTANCE, "UPDATE item_instance SET itemEntry = ?, owner_guid = ?, creatorGuid = ?, giftCreatorGuid = ?, count = ?, duration = ?, charges = ?, flags = ?, enchantments = ?, randomPropertyId = ?, durability = ?, playedTime = ?, text = ? WHERE guid = ?", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_UPD_ITEM_INSTANCE_ON_LOAD, "UPDATE item_instance SET duration = ?, flags = ?, durability = ? WHERE guid = ?", CONNECTION_ASYNC) @@ -239,7 +240,6 @@ void CharacterDatabaseConnection::DoPrepareStatements() PREPARE_STATEMENT(CHAR_DEL_EQUIP_SET, "DELETE FROM character_equipmentsets WHERE setguid=?", CONNECTION_ASYNC) // Auras - PREPARE_STATEMENT(CHAR_DEL_AURA, "DELETE FROM character_aura WHERE guid = ?", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_INS_AURA, "INSERT INTO character_aura (guid, caster_guid, item_guid, spell, effect_mask, recalculate_mask, stackcount, amount0, amount1, amount2, base_amount0, base_amount1, base_amount2, maxduration, remaintime, remaincharges) " "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC) @@ -336,7 +336,7 @@ void CharacterDatabaseConnection::DoPrepareStatements() // GM Survey/subsurvey/lag report PREPARE_STATEMENT(CHAR_INS_GM_SURVEY, "INSERT INTO gm_surveys (guid, surveyId, mainSurvey, overallComment, createTime) VALUES (?, ?, ?, ?, UNIX_TIMESTAMP(NOW()))", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_INS_GM_SUBSURVEY, "INSERT INTO gm_subsurveys (surveyId, subsurveyId, rank, comment) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC) - PREPARE_STATEMENT(CHAR_INS_LAG_REPORT, "INSERT INTO lag_reports (guid, lagType, mapId, posX, posY, posZ) VALUES (?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC) + PREPARE_STATEMENT(CHAR_INS_LAG_REPORT, "INSERT INTO lag_reports (guid, lagType, mapId, posX, posY, posZ, latency, createTime) VALUES (?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC) // For loading and deleting expired auctions at startup PREPARE_STATEMENT(CHAR_SEL_EXPIRED_AUCTIONS, "SELECT id, auctioneerguid, itemguid, itemEntry, itemowner, buyoutprice, time, buyguid, lastbid, startbid, deposit FROM auctionhouse ah INNER JOIN item_instance ii ON ii.guid = ah.itemguid WHERE ah.time <= ?", CONNECTION_SYNCH) @@ -436,8 +436,8 @@ void CharacterDatabaseConnection::DoPrepareStatements() PREPARE_STATEMENT(CHAR_SEL_PET_SPELL, "SELECT spell, active FROM pet_spell WHERE guid = ?", CONNECTION_SYNCH); PREPARE_STATEMENT(CHAR_SEL_PET_SPELL_COOLDOWN, "SELECT spell, time FROM pet_spell_cooldown WHERE guid = ?", CONNECTION_SYNCH); PREPARE_STATEMENT(CHAR_SEL_PET_DECLINED_NAME, "SELECT genitive, dative, accusative, instrumental, prepositional FROM character_pet_declinedname WHERE owner = ? AND id = ?", CONNECTION_SYNCH); - PREPARE_STATEMENT(CHAR_SEL_CHAR_GUID_BY_NAME, "SELECT characters.guid FROM characters WHERE characters.name = ?", CONNECTION_SYNCH); - PREPARE_STATEMENT(CHAR_DEL_CHAR_AURA_FROZEN, "DELETE FROM character_aura WHERE character_aura.spell = 9454 AND character_aura.guid = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_SEL_CHAR_GUID_BY_NAME, "SELECT guid FROM characters WHERE name = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_DEL_CHAR_AURA_FROZEN, "DELETE FROM character_aura WHERE spell = 9454 AND guid = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_SEL_CHAR_INVENTORY_COUNT_ITEM, "SELECT COUNT(itemEntry) FROM character_inventory ci INNER JOIN item_instance ii ON ii.guid = ci.item WHERE itemEntry = ?", CONNECTION_SYNCH); PREPARE_STATEMENT(CHAR_SEL_MAIL_COUNT_ITEM, "SELECT COUNT(itemEntry) FROM mail_items mi INNER JOIN item_instance ii ON ii.guid = mi.item_guid WHERE itemEntry = ?", CONNECTION_SYNCH); PREPARE_STATEMENT(CHAR_SEL_AUCTIONHOUSE_COUNT_ITEM,"SELECT COUNT(itemEntry) FROM auctionhouse ah INNER JOIN item_instance ii ON ii.guid = ah.itemguid WHERE itemEntry = ?", CONNECTION_SYNCH); diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.h b/src/server/shared/Database/Implementation/CharacterDatabase.h index 4d8433c74b2..cf6bbd7bdfa 100644 --- a/src/server/shared/Database/Implementation/CharacterDatabase.h +++ b/src/server/shared/Database/Implementation/CharacterDatabase.h @@ -53,6 +53,7 @@ enum CharacterDatabaseStatements CHAR_SEL_CHAR_CREATE_INFO, CHAR_INS_CHARACTER_BAN, CHAR_UPD_CHARACTER_BAN, + CHAR_DEL_CHARACTER_BAN, CHAR_SEL_BANINFO, CHAR_SEL_GUID_BY_NAME_FILTER, CHAR_SEL_BANINFO_LIST, @@ -68,6 +69,7 @@ enum CharacterDatabaseStatements CHAR_SEL_CHAR_RACE, CHAR_SEL_CHAR_LEVEL, CHAR_SEL_CHAR_ZONE, + CHAR_SEL_CHARACTER_NAME_DATA, CHAR_SEL_CHAR_POSITION_XYZ, CHAR_SEL_CHAR_POSITION, CHAR_DEL_QUEST_STATUS_DAILY, @@ -138,7 +140,6 @@ enum CharacterDatabaseStatements CHAR_DEL_ITEM_BOP_TRADE, CHAR_INS_ITEM_BOP_TRADE, CHAR_REP_INVENTORY_ITEM, - CHAR_DEL_INVENTORY_ITEM, CHAR_REP_ITEM_INSTANCE, CHAR_UPD_ITEM_INSTANCE, CHAR_UPD_ITEM_INSTANCE_ON_LOAD, @@ -231,7 +232,6 @@ enum CharacterDatabaseStatements CHAR_INS_EQUIP_SET, CHAR_DEL_EQUIP_SET, - CHAR_DEL_AURA, CHAR_INS_AURA, CHAR_SEL_ACCOUNT_DATA, diff --git a/src/server/shared/Database/Implementation/LoginDatabase.cpp b/src/server/shared/Database/Implementation/LoginDatabase.cpp index 70d874be31d..028d927a720 100755 --- a/src/server/shared/Database/Implementation/LoginDatabase.cpp +++ b/src/server/shared/Database/Implementation/LoginDatabase.cpp @@ -33,6 +33,7 @@ void LoginDatabaseConnection::DoPrepareStatements() PREPARE_STATEMENT(LOGIN_SEL_ACCOUNT_BANNED_ALL, "SELECT account.id, username FROM account, account_banned WHERE account.id = account_banned.id AND active = 1 GROUP BY account.id", CONNECTION_SYNCH); PREPARE_STATEMENT(LOGIN_SEL_ACCOUNT_BANNED_BY_USERNAME, "SELECT account.id, username FROM account, account_banned WHERE account.id = account_banned.id AND active = 1 AND username LIKE CONCAT('%%', ?, '%%') GROUP BY account.id", CONNECTION_SYNCH); PREPARE_STATEMENT(LOGIN_INS_ACCOUNT_AUTO_BANNED, "INSERT INTO account_banned VALUES (?, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()+?, 'Trinity realmd', 'Failed login autoban', 1)", CONNECTION_ASYNC) + PREPARE_STATEMENT(LOGIN_DEL_ACCOUNT_BANNED, "DELETE FROM account_banned WHERE id = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(LOGIN_SEL_SESSIONKEY, "SELECT a.sessionkey, a.id, aa.gmlevel FROM account a LEFT JOIN account_access aa ON (a.id = aa.id) WHERE username = ?", CONNECTION_SYNCH) PREPARE_STATEMENT(LOGIN_UPD_VS, "UPDATE account SET v = ?, s = ? WHERE username = ?", CONNECTION_ASYNC) PREPARE_STATEMENT(LOGIN_UPD_LOGONPROOF, "UPDATE account SET sessionkey = ?, last_ip = ?, last_login = NOW(), locale = ?, failed_logins = 0, os = ? WHERE username = ?", CONNECTION_ASYNC) @@ -86,5 +87,4 @@ void LoginDatabaseConnection::DoPrepareStatements() PREPARE_STATEMENT(LOGIN_SEL_ACCOUNT_WHOIS, "SELECT username, email, last_ip FROM account WHERE id = ?", CONNECTION_SYNCH); PREPARE_STATEMENT(LOGIN_SEL_REALMLIST_SECURITY_LEVEL, "SELECT allowedSecurityLevel from realmlist WHERE id = ?", CONNECTION_SYNCH); PREPARE_STATEMENT(LOGIN_DEL_ACCOUNT, "DELETE FROM account WHERE id = ?", CONNECTION_ASYNC); - } diff --git a/src/server/shared/Database/Implementation/LoginDatabase.h b/src/server/shared/Database/Implementation/LoginDatabase.h index 2b9d94cbceb..7c2a94eec94 100755 --- a/src/server/shared/Database/Implementation/LoginDatabase.h +++ b/src/server/shared/Database/Implementation/LoginDatabase.h @@ -51,6 +51,7 @@ enum LoginDatabaseStatements LOGIN_SEL_ACCOUNT_BANNED_ALL, LOGIN_SEL_ACCOUNT_BANNED_BY_USERNAME, LOGIN_INS_ACCOUNT_AUTO_BANNED, + LOGIN_DEL_ACCOUNT_BANNED, LOGIN_SEL_SESSIONKEY, LOGIN_UPD_VS, LOGIN_UPD_LOGONPROOF, diff --git a/src/server/shared/Debugging/Errors.h b/src/server/shared/Debugging/Errors.h index 6927fdb483f..48a8bda32ed 100755 --- a/src/server/shared/Debugging/Errors.h +++ b/src/server/shared/Debugging/Errors.h @@ -24,10 +24,10 @@ #include <ace/Stack_Trace.h> #include <ace/OS_NS_unistd.h> -#define WPAssert( assertion ) { if (!(assertion)) { ACE_Stack_Trace st; sLog->outError( "\n%s:%i in %s ASSERTION FAILED:\n %s\n%s\n", __FILE__, __LINE__, __FUNCTION__, #assertion, st.c_str()); assert( #assertion &&0 ); ((void(*)())NULL)();} } -#define WPError( assertion, errmsg ) if ( ! (assertion) ) { sLog->outError( "%\n%s:%i in %s ERROR:\n %s\n", __FILE__, __LINE__, __FUNCTION__, (char *)errmsg ); assert( false ); } -#define WPWarning( assertion, errmsg ) if ( ! (assertion) ) { sLog->outError( "\n%s:%i in %s WARNING:\n %s\n", __FILE__, __LINE__, __FUNCTION__, (char *)errmsg ); } -#define WPFatal( assertion, errmsg ) if ( ! (assertion) ) { sLog->outError( "\n%s:%i in %s FATAL ERROR:\n %s\n", __FILE__, __LINE__, __FUNCTION__, (char *)errmsg ); ACE_OS::sleep(10); assert( #assertion &&0 ); abort(); } +#define WPAssert(assertion) { if (!(assertion)) { ACE_Stack_Trace st; sLog->outError("\n%s:%i in %s ASSERTION FAILED:\n %s\n%s\n", __FILE__, __LINE__, __FUNCTION__, #assertion, st.c_str()); *((volatile int*)NULL) = 0; } } +#define WPError(assertion, errmsg) { if (!(assertion)) { sLog->outError("%\n%s:%i in %s ERROR:\n %s\n", __FILE__, __LINE__, __FUNCTION__, (char *)errmsg); *((volatile int*)NULL) = 0; } } +#define WPWarning(assertion, errmsg) { if (!(assertion)) { sLog->outError("\n%s:%i in %s WARNING:\n %s\n", __FILE__, __LINE__, __FUNCTION__, (char *)errmsg); } } +#define WPFatal(assertion, errmsg) { if (!(assertion)) { sLog->outError("\n%s:%i in %s FATAL ERROR:\n %s\n", __FILE__, __LINE__, __FUNCTION__, (char *)errmsg); ACE_OS::sleep(10); *((volatile int*)NULL) = 0; } } #define ASSERT WPAssert #endif diff --git a/src/server/shared/Debugging/WheatyExceptionReport.cpp b/src/server/shared/Debugging/WheatyExceptionReport.cpp index 63648f66e29..febc5ef3573 100644 --- a/src/server/shared/Debugging/WheatyExceptionReport.cpp +++ b/src/server/shared/Debugging/WheatyExceptionReport.cpp @@ -195,7 +195,23 @@ BOOL WheatyExceptionReport::_GetWindowsVersion(TCHAR* szVersion, DWORD cntMax) case VER_PLATFORM_WIN32_NT: // Test for the specific product family. if (osvi.dwMajorVersion == 6) - _tcsncat(szVersion, _T("Windows Vista or Windows Server 2008 "), cntMax); + { + #if WINVER < 0x0500 + if (osvi.wReserved[1] == VER_NT_WORKSTATION) + #else + if (osvi.wProductType == VER_NT_WORKSTATION) + #endif // WINVER < 0x0500 + { + if (osvi.dwMinorVersion == 1) + _tcsncat(szVersion, _T("Windows 7 "), cntMax); + else + _tcsncat(szVersion, _T("Windows Vista "), cntMax); + } + else if (osvi.dwMinorVersion == 1) + _tcsncat(szVersion, _T("Windows Server 2008 R2 "), cntMax); + else + _tcsncat(szVersion, _T("Windows Server 2008 "), cntMax); + } if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2) _tcsncat(szVersion, _T("Microsoft Windows Server 2003 "), cntMax); if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1) diff --git a/src/server/shared/Dynamic/TypeContainerFunctionsPtr.h b/src/server/shared/Dynamic/TypeContainerFunctionsPtr.h deleted file mode 100755 index 2c065d96d4a..00000000000 --- a/src/server/shared/Dynamic/TypeContainerFunctionsPtr.h +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/> - * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef TYPECONTAINER_FUNCTIONS_PTR_H -#define TYPECONTAINER_FUNCTIONS_PTR_H - -/* - * Here you'll find a list of helper functions to make - * the TypeContainer usefull. Without it, its hard - * to access or mutate the container. - */ - -#include "Platform/Define.h" -#include "Utilities/TypeList.h" -#include <map> - -namespace Trinity -{ - /* ContainerMapList Helpers */ - // count functions - // template<class SPECIFIC_TYPE> size_t Count(const ContainerMapList<SPECIFIC_TYPE> &elements, CountedPtr<SPECIFIC_TYPE>* /*fake*/) - // { - // return elements._element.size(); - // }; - // - // template<class SPECIFIC_TYPE> size_t Count(const ContainerMapList<TypeNull> &elements, CountedPtr<SPECIFIC_TYPE>* /*fake*/) - // { - // return 0; - // } - // - // template<class SPECIFIC_TYPE, class T> size_t Count(const ContainerMapList<T> &elements, CountedPtr<SPECIFIC_TYPE>* /*fake*/) - // { - // return 0; - // } - // - // template<class SPECIFIC_TYPE, class T> size_t Count(const ContainerMapList<TypeList<SPECIFIC_TYPE, T> >&elements, SPECIFIC_TYPE* fake) - // { - // return Count(elements._elements, fake); - // } - // - // template<class SPECIFIC_TYPE, class H, class T> size_t Count(const ContainerMapList<TypeList<H, T> >&elements, SPECIFIC_TYPE* fake) - // { - // return Count(elements._TailElements, fake); - // } - - // non-const find functions - template<class SPECIFIC_TYPE> CountedPtr<SPECIFIC_TYPE>& Find(ContainerMapList<SPECIFIC_TYPE> &elements, OBJECT_HANDLE hdl, CountedPtr<SPECIFIC_TYPE>* /*fake*/) - { - typename std::map<OBJECT_HANDLE, CountedPtr<SPECIFIC_TYPE> >::iterator iter = elements._element.find(hdl); - return (iter == elements._element.end() ? NullPtr<SPECIFIC_TYPE>((SPECIFIC_TYPE*)NULL) : iter->second); - }; - - template<class SPECIFIC_TYPE> CountedPtr<SPECIFIC_TYPE>& Find(ContainerMapList<TypeNull> &elements, OBJECT_HANDLE hdl, CountedPtr<SPECIFIC_TYPE>* /*fake*/) - { - return NullPtr<SPECIFIC_TYPE>((SPECIFIC_TYPE*)NULL);// terminate recursion - } - - template<class SPECIFIC_TYPE, class T> CountedPtr<SPECIFIC_TYPE>& Find(ContainerMapList<T> &elements, OBJECT_HANDLE hdl, CountedPtr<SPECIFIC_TYPE>* /*fake*/) - { - return NullPtr<SPECIFIC_TYPE>((SPECIFIC_TYPE*)NULL);// this is a missed - } - - template<class SPECIFIC_TYPE, class H, class T> CountedPtr<SPECIFIC_TYPE>& Find(ContainerMapList<TypeList<H, T> >&elements, OBJECT_HANDLE hdl, CountedPtr<SPECIFIC_TYPE>* fake) - { - CountedPtr<SPECIFIC_TYPE> &t = Find(elements._elements, hdl, fake); - return (!t ? Find(elements._TailElements, hdl, fake) : t); - } - - // const find functions - template<class SPECIFIC_TYPE> const CountedPtr<SPECIFIC_TYPE>& Find(const ContainerMapList<SPECIFIC_TYPE> &elements, OBJECT_HANDLE hdl, CountedPtr<SPECIFIC_TYPE>* /*fake*/) - { - typename CountedPtr<SPECIFIC_TYPE>::iterator iter = elements._element.find(hdl); - return (iter == elements._element.end() ? NullPtr<SPECIFIC_TYPE>((SPECIFIC_TYPE*)NULL) : iter->second); - }; - - template<class SPECIFIC_TYPE> const CountedPtr<SPECIFIC_TYPE>& Find(const ContainerMapList<TypeNull> &elements, OBJECT_HANDLE hdl, CountedPtr<SPECIFIC_TYPE>* /*fake*/) - { - return NullPtr<SPECIFIC_TYPE>((SPECIFIC_TYPE*)NULL); - } - - template<class SPECIFIC_TYPE, class T> const CountedPtr<SPECIFIC_TYPE>& Find(const ContainerMapList<T> &elements, OBJECT_HANDLE hdl, CountedPtr<SPECIFIC_TYPE>* /*fake*/) - { - return NullPtr<SPECIFIC_TYPE>((SPECIFIC_TYPE*)NULL); - } - - template<class SPECIFIC_TYPE, class H, class T> CountedPtr<SPECIFIC_TYPE>& Find(const ContainerMapList<TypeList<H, T> >&elements, OBJECT_HANDLE hdl, CountedPtr<SPECIFIC_TYPE>* fake) - { - CountedPtr<SPECIFIC_TYPE> &t = Find(elements._elements, hdl, fake); - if (!t) - t = Find(elements._TailElement, hdl, fake); - - return t; - } - - // non-const insert functions - template<class SPECIFIC_TYPE> CountedPtr<SPECIFIC_TYPE>& Insert(ContainerMapList<SPECIFIC_TYPE> &elements, CountedPtr<SPECIFIC_TYPE> &obj, OBJECT_HANDLE hdl) - { - elements._element[hdl] = obj; - return obj; - }; - - template<class SPECIFIC_TYPE> CountedPtr<SPECIFIC_TYPE>& Insert(ContainerMapList<TypeNull> &elements, CountedPtr<SPECIFIC_TYPE> &obj, OBJECT_HANDLE hdl) - { - return NullPtr<SPECIFIC_TYPE>((SPECIFIC_TYPE*)NULL); - } - - // this is a missed - template<class SPECIFIC_TYPE, class T> CountedPtr<SPECIFIC_TYPE>& Insert(ContainerMapList<T> &elements, CountedPtr<SPECIFIC_TYPE> &obj, OBJECT_HANDLE hdl) - { - return NullPtr<SPECIFIC_TYPE>((SPECIFIC_TYPE*)NULL);// a missed - } - - // Recursion - template<class SPECIFIC_TYPE, class H, class T> CountedPtr<SPECIFIC_TYPE>& Insert(ContainerMapList<TypeList<H, T> >&elements, CountedPtr<SPECIFIC_TYPE> &obj, OBJECT_HANDLE hdl) - { - CountedPtr<SPECIFIC_TYPE> &t= Insert(elements._elements, obj, hdl); - return (!t ? Insert(elements._TailElements, obj, hdl) : t); - } - - // non-const remove method - template<class SPECIFIC_TYPE> bool Remove(ContainerMapList<SPECIFIC_TYPE> &elements, CountedPtr<SPECIFIC_TYPE> &obj, OBJECT_HANDLE hdl) - { - typename std::map<OBJECT_HANDLE, CountedPtr<SPECIFIC_TYPE> >::iterator iter = elements._element.find(hdl); - if ( iter != elements._element.end() ) - { - elements._element.erase(iter); - return true; - } - - return false; // found... terminate the search - } - - template<class SPECIFIC_TYPE> bool Remove(ContainerMapList<TypeNull> &elements, CountedPtr<SPECIFIC_TYPE> &obj, OBJECT_HANDLE hdl) - { - return false; - } - - // this is a missed - template<class SPECIFIC_TYPE, class T> bool Remove(ContainerMapList<T> &elements, CountedPtr<SPECIFIC_TYPE> &obj, OBJECT_HANDLE hdl) - { - return false; - } - - template<class SPECIFIC_TYPE, class T, class H> bool Remove(ContainerMapList<TypeList<H, T> > &elements, CountedPtr<SPECIFIC_TYPE> &obj, OBJECT_HANDLE hdl) - { - // The head element is bad - bool t = Remove(elements._elements, obj, hdl); - return ( !t ? Remove(elements._TailElements, obj, hdl) : t ); - } - -} -#endif - diff --git a/src/server/shared/Utilities/Util.h b/src/server/shared/Utilities/Util.h index 4c2c1936993..196882dc2a0 100755 --- a/src/server/shared/Utilities/Util.h +++ b/src/server/shared/Utilities/Util.h @@ -20,7 +20,7 @@ #define _UTIL_H #include "Common.h" - +#include "Containers.h" #include <string> #include <vector> @@ -73,7 +73,7 @@ inline uint32 secsToTimeBitFields(time_t secs) double rand_norm(void); /* Return a random double from 0.0 to 99.9999999999999. Floats support only 7 valid decimal digits. - * A double supports up to 15 valid decimal digits and is used internaly (RAND32_MAX has 10 digits). + * A double supports up to 15 valid decimal digits and is used internally (RAND32_MAX has 10 digits). * With an FPU, there is usually no difference in performance between float and double. */ double rand_chance(void); @@ -653,12 +653,4 @@ public: }; }; -/* Select a random element from a container. Note: make sure you explicitly empty check the container */ -template <class C> typename C::value_type const& SelectRandomContainerElement(C const& container) -{ - typename C::const_iterator it = container.begin(); - std::advance(it, urand(0, container.size() - 1)); - return *it; -} - #endif diff --git a/src/server/worldserver/CMakeLists.txt b/src/server/worldserver/CMakeLists.txt index d1419cb0fcb..0d51f30449e 100644 --- a/src/server/worldserver/CMakeLists.txt +++ b/src/server/worldserver/CMakeLists.txt @@ -48,7 +48,6 @@ include_directories( ${CMAKE_SOURCE_DIR}/dep/gsoap ${CMAKE_SOURCE_DIR}/dep/sockets/include ${CMAKE_SOURCE_DIR}/dep/SFMT - ${CMAKE_SOURCE_DIR}/dep/mersennetwister ${CMAKE_SOURCE_DIR}/src/server/collision ${CMAKE_SOURCE_DIR}/src/server/collision/Management ${CMAKE_SOURCE_DIR}/src/server/collision/Models diff --git a/src/server/worldserver/CommandLine/CliRunnable.cpp b/src/server/worldserver/CommandLine/CliRunnable.cpp index 0721515ea73..e85a3e1870d 100755 --- a/src/server/worldserver/CommandLine/CliRunnable.cpp +++ b/src/server/worldserver/CommandLine/CliRunnable.cpp @@ -314,6 +314,11 @@ void ChatHandler::HandleCharacterDeletedRestoreHelper(DeletedInfo const& delInfo stmt->setUInt32(2, delInfo.lowguid); CharacterDatabase.Execute(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_NAME_DATA); + stmt->setUInt32(0, delInfo.lowguid); + if (PreparedQueryResult result = CharacterDatabase.Query(stmt)) + sWorld->AddCharacterNameData(delInfo.lowguid, delInfo.name, (*result)[2].GetUInt8(), (*result)[0].GetUInt8(), (*result)[1].GetUInt8()); } /** diff --git a/src/tools/map_extractor/System.cpp b/src/tools/map_extractor/System.cpp index bbde9f4675e..1505f2c2cee 100644 --- a/src/tools/map_extractor/System.cpp +++ b/src/tools/map_extractor/System.cpp @@ -71,7 +71,7 @@ float CONF_flat_height_delta_limit = 0.005f; // If max - min less this value - s float CONF_flat_liquid_delta_limit = 0.001f; // If max - min less this value - liquid surface is flat // List MPQ for extract from -char *CONF_mpq_list[]={ +const char *CONF_mpq_list[]={ "common.MPQ", "common-2.MPQ", "lichking.MPQ", @@ -83,7 +83,7 @@ char *CONF_mpq_list[]={ "patch-5.MPQ", }; -static char* const langs[] = {"enGB", "enUS", "deDE", "esES", "frFR", "koKR", "zhCN", "zhTW", "enCN", "enTW", "esMX", "ruRU" }; +static const char* const langs[] = {"enGB", "enUS", "deDE", "esES", "frFR", "koKR", "zhCN", "zhTW", "enCN", "enTW", "esMX", "ruRU" }; #define LANG_COUNT 12 void CreateDir( const std::string& Path ) @@ -259,15 +259,15 @@ void ReadLiquidTypeTableDBC() exit(1); } - size_t LiqType_count = dbc.getRecordCount(); - size_t LiqType_maxid = dbc.getMaxId(); - LiqType = new uint16[LiqType_maxid + 1]; - memset(LiqType, 0xff, (LiqType_maxid + 1) * sizeof(uint16)); + size_t liqTypeCount = dbc.getRecordCount(); + size_t liqTypeMaxId = dbc.getMaxId(); + LiqType = new uint16[liqTypeMaxId + 1]; + memset(LiqType, 0xff, (liqTypeMaxId + 1) * sizeof(uint16)); - for(uint32 x = 0; x < LiqType_count; ++x) + for(uint32 x = 0; x < liqTypeCount; ++x) LiqType[dbc.getRecord(x).getUInt(0)] = dbc.getRecord(x).getUInt(3); - printf("Done! (%u LiqTypes loaded)\n", LiqType_count); + printf("Done! (%u LiqTypes loaded)\n", liqTypeCount); } // @@ -364,7 +364,7 @@ uint8 liquid_flags[ADT_CELLS_PER_GRID][ADT_CELLS_PER_GRID]; bool liquid_show[ADT_GRID_SIZE][ADT_GRID_SIZE]; float liquid_height[ADT_GRID_SIZE+1][ADT_GRID_SIZE+1]; -bool ConvertADT(char *filename, char *filename2, int cell_y, int cell_x, uint32 build) +bool ConvertADT(char *filename, char *filename2, int /*cell_y*/, int /*cell_x*/, uint32 build) { ADT_file adt; diff --git a/src/tools/map_extractor/mpq_libmpq04.h b/src/tools/map_extractor/mpq_libmpq04.h index 1f3b259bbfc..89f715e9e87 100644 --- a/src/tools/map_extractor/mpq_libmpq04.h +++ b/src/tools/map_extractor/mpq_libmpq04.h @@ -60,8 +60,8 @@ class MPQFile libmpq__off_t pointer,size; // disable copying - MPQFile(const MPQFile &f) {} - void operator=(const MPQFile &f) {} + MPQFile(const MPQFile& /*f*/) {} + void operator=(const MPQFile& /*f*/) {} public: MPQFile(const char* filename); // filenames are not case sensitive |
