diff options
Diffstat (limited to 'src')
17 files changed, 292 insertions, 228 deletions
diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index 2d6046cbddf..f94a3e79066 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -731,7 +731,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u me->AI()->EnterEvadeMode(); TC_LOG_DEBUG(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_EVADE: Creature %u EnterEvadeMode", me->GetGUIDLow()); - return; + break; } case SMART_ACTION_FLEE_FOR_ASSIST: { @@ -854,7 +854,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u } case SMART_ACTION_CALL_KILLEDMONSTER: { - if (e.target.type == SMART_TARGET_NONE) // Loot recipient and his group members + if (e.target.type == SMART_TARGET_NONE || e.target.type == SMART_TARGET_SELF) // Loot recipient and his group members { if (!me) break; @@ -1340,15 +1340,18 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u if (!me) break; - ObjectList* targets = GetTargets(e, unit); if (e.GetTargetType() == SMART_TARGET_SELF) me->SetFacingTo(me->GetHomePosition().GetOrientation()); else if (e.GetTargetType() == SMART_TARGET_POSITION) me->SetFacingTo(e.target.o); - else if (targets && !targets->empty()) - me->SetFacingToObject(*targets->begin()); + else if (ObjectList* targets = GetTargets(e, unit)) + { + if (!targets->empty()) + me->SetFacingToObject(*targets->begin()); + + delete targets; + } - delete targets; break; } case SMART_ACTION_PLAYMOVIE: @@ -1445,7 +1448,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u { TC_LOG_ERROR(LOG_FILTER_SQL, "SmartScript: SMART_ACTION_EQUIP uses non-existent equipment info id %u for creature %u", equipId, npc->GetEntry()); delete targets; - return; + break; } npc->SetCurrentEquipmentId(equipId); @@ -1879,11 +1882,13 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u break; for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + { if (Creature* creature = (*itr)->ToCreature()) { creature->GetMotionMaster()->Clear(); creature->GetMotionMaster()->MoveJump(e.target.x, e.target.y, e.target.z, (float)e.action.jump.speedxy, (float)e.action.jump.speedz); } + } /// @todo Resume path when reached jump location delete targets; @@ -1913,7 +1918,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u if (!storedTargets) { delete targets; - return; + break; } for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) @@ -1950,6 +1955,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u break; for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + { if (Player* player = (*itr)->ToPlayer()) { if (e.action.sendGossipMenu.gossipMenuId) @@ -1959,6 +1965,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u player->SEND_GOSSIP_MENU(e.action.sendGossipMenu.gossipNpcTextId, GetBaseObject()->GetGUID()); } + } delete targets; break; @@ -1970,15 +1977,32 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u break; for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + { if (IsCreature(*itr)) { if (e.GetTargetType() == SMART_TARGET_SELF) (*itr)->ToCreature()->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation()); else if (e.GetTargetType() == SMART_TARGET_POSITION) (*itr)->ToCreature()->SetHomePosition(e.target.x, e.target.y, e.target.z, e.target.o); + else if (e.GetTargetType() == SMART_TARGET_CREATURE_RANGE || e.GetTargetType() == SMART_TARGET_CREATURE_GUID || + e.GetTargetType() == SMART_TARGET_CREATURE_DISTANCE || e.GetTargetType() == SMART_TARGET_GAMEOBJECT_RANGE || + e.GetTargetType() == SMART_TARGET_GAMEOBJECT_GUID || e.GetTargetType() == SMART_TARGET_GAMEOBJECT_DISTANCE || + e.GetTargetType() == SMART_TARGET_CLOSEST_CREATURE || e.GetTargetType() == SMART_TARGET_CLOSEST_GAMEOBJECT || + e.GetTargetType() == SMART_TARGET_OWNER_OR_SUMMONER || e.GetTargetType() == SMART_TARGET_ACTION_INVOKER || + e.GetTargetType() == SMART_TARGET_CLOSEST_ENEMY || e.GetTargetType() == SMART_TARGET_CLOSEST_FRIENDLY) + { + if (ObjectList* targets = GetTargets(e, unit)) + { + if (WorldObject* target = targets->front()) + (*itr)->ToCreature()->SetHomePosition(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), target->GetOrientation()); + + delete targets; + } + } else - TC_LOG_ERROR(LOG_FILTER_SQL, "SmartScript: Action target for SMART_ACTION_SET_HOME_POS is not using SMART_TARGET_SELF or SMART_TARGET_POSITION, skipping"); + TC_LOG_ERROR(LOG_FILTER_SQL, "SmartScript: Action target for SMART_ACTION_SET_HOME_POS is invalid, skipping"); } + } delete targets; break; @@ -2101,7 +2125,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u if (!sGameEventMgr->IsActiveEvent(eventId)) { TC_LOG_ERROR(LOG_FILTER_SQL, "SmartScript::ProcessAction: At case SMART_ACTION_GAME_EVENT_STOP, inactive event (id: %u)", eventId); - return; + break; } sGameEventMgr->StopEvent(eventId, true); break; @@ -2112,7 +2136,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u if (sGameEventMgr->IsActiveEvent(eventId)) { TC_LOG_ERROR(LOG_FILTER_SQL, "SmartScript::ProcessAction: At case SMART_ACTION_GAME_EVENT_START, already activated event (id: %u)", eventId); - return; + break; } sGameEventMgr->StartEvent(eventId, true); break; @@ -2621,10 +2645,20 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui } case SMART_EVENT_TARGET_CASTING: { - if (!me || !me->IsInCombat() || !me->GetVictim() || !me->GetVictim()->IsNonMeleeSpellCasted(false, false, true)) + if (!me || !me->IsInCombat()) return; - ProcessTimedAction(e, e.event.minMaxRepeat.repeatMin, e.event.minMaxRepeat.repeatMax, me->GetVictim()); + Unit* victim = me->GetVictim(); + + if (!victim || !victim->IsNonMeleeSpellCasted(false, false, true)) + return; + + if (e.event.targetCasting.spellId > 0) + if (Spell* currSpell = victim->GetCurrentSpell(CURRENT_GENERIC_SPELL)) + if (currSpell->m_spellInfo->Id != e.event.targetCasting.spellId) + return; + + ProcessTimedAction(e, e.event.targetCasting.repeatMin, e.event.targetCasting.repeatMax, me->GetVictim()); break; } case SMART_EVENT_FRIENDLY_HEALTH: @@ -2632,10 +2666,10 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui if (!me || !me->IsInCombat()) return; - Unit* target = DoSelectLowestHpFriendly((float)e.event.friendlyHealt.radius, e.event.friendlyHealt.hpDeficit); + Unit* target = DoSelectLowestHpFriendly((float)e.event.friendlyHealth.radius, e.event.friendlyHealth.hpDeficit); if (!target || !target->IsInCombat()) return; - ProcessTimedAction(e, e.event.friendlyHealt.repeatMin, e.event.friendlyHealt.repeatMax, target); + ProcessTimedAction(e, e.event.friendlyHealth.repeatMin, e.event.friendlyHealth.repeatMax, target); break; } case SMART_EVENT_FRIENDLY_IS_CC: @@ -2983,7 +3017,7 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui { uint32 healthPct = uint32((*itr)->ToUnit()->GetHealthPct()); - if (healthPct > e.event.friendlyHealtPct.maxHpPct || healthPct < e.event.friendlyHealtPct.minHpPct) + if (healthPct > e.event.friendlyHealthPct.maxHpPct || healthPct < e.event.friendlyHealthPct.minHpPct) continue; target = (*itr)->ToUnit(); @@ -2996,7 +3030,7 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui if (!target) return; - ProcessTimedAction(e, e.event.friendlyHealtPct.repeatMin, e.event.friendlyHealtPct.repeatMax, target); + ProcessTimedAction(e, e.event.friendlyHealthPct.repeatMin, e.event.friendlyHealthPct.repeatMax, target); break; } default: diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp index 081599c322e..ae87d7122d4 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp @@ -407,10 +407,10 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) } break; case SMART_EVENT_FRIENDLY_HEALTH: - if (!NotNULL(e, e.event.friendlyHealt.radius)) + if (!NotNULL(e, e.event.friendlyHealth.radius)) return false; - if (!IsMinMaxValid(e, e.event.friendlyHealt.repeatMin, e.event.friendlyHealt.repeatMax)) + if (!IsMinMaxValid(e, e.event.friendlyHealth.repeatMin, e.event.friendlyHealth.repeatMax)) return false; break; case SMART_EVENT_FRIENDLY_IS_CC: @@ -437,6 +437,15 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) return false; break; case SMART_EVENT_TARGET_CASTING: + if (e.event.targetCasting.spellId > 0 && !sSpellMgr->GetSpellInfo(e.event.targetCasting.spellId)) + { + sLog->outError(LOG_FILTER_SQL, "SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses non-existent Spell entry %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.event.spellHit.spell); + return false; + } + + if (!IsMinMaxValid(e, e.event.targetCasting.repeatMin, e.event.targetCasting.repeatMax)) + return false; + break; case SMART_EVENT_PASSENGER_BOARDED: case SMART_EVENT_PASSENGER_REMOVED: if (!IsMinMaxValid(e, e.event.minMax.repeatMin, e.event.minMax.repeatMax)) @@ -546,10 +555,10 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) break; } case SMART_EVENT_FRIENDLY_HEALTH_PCT: - if (!IsMinMaxValid(e, e.event.friendlyHealtPct.repeatMin, e.event.friendlyHealtPct.repeatMax)) + if (!IsMinMaxValid(e, e.event.friendlyHealthPct.repeatMin, e.event.friendlyHealthPct.repeatMax)) return false; - if (e.event.friendlyHealtPct.maxHpPct > 100 || e.event.friendlyHealtPct.minHpPct > 100) + if (e.event.friendlyHealthPct.maxHpPct > 100 || e.event.friendlyHealthPct.minHpPct > 100) { TC_LOG_ERROR(LOG_FILTER_SQL, "SmartAIMgr: Entry %d SourceType %u Event %u Action %u has pct value above 100, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType()); return false; diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h index 0138d2b07a3..6f0dd31e11f 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h @@ -95,7 +95,7 @@ enum SMART_EVENT SMART_EVENT_OOC_LOS = 10, // NoHostile, MaxRnage, CooldownMin, CooldownMax SMART_EVENT_RESPAWN = 11, // type, MapId, ZoneId SMART_EVENT_TARGET_HEALTH_PCT = 12, // HPMin%, HPMax%, RepeatMin, RepeatMax - SMART_EVENT_TARGET_CASTING = 13, // RepeatMin, RepeatMax + SMART_EVENT_TARGET_CASTING = 13, // RepeatMin, RepeatMax, spellid SMART_EVENT_FRIENDLY_HEALTH = 14, // HPDeficit, Radius, RepeatMin, RepeatMax SMART_EVENT_FRIENDLY_IS_CC = 15, // Radius, RepeatMin, RepeatMax SMART_EVENT_FRIENDLY_MISSING_BUFF = 16, // SpellId, Radius, RepeatMin, RepeatMax @@ -216,11 +216,18 @@ struct SmartEvent struct { + uint32 repeatMin; + uint32 repeatMax; + uint32 spellId; + } targetCasting; + + struct + { uint32 hpDeficit; uint32 radius; uint32 repeatMin; uint32 repeatMax; - } friendlyHealt; + } friendlyHealth; struct { @@ -369,7 +376,7 @@ struct SmartEvent uint32 maxHpPct; uint32 repeatMin; uint32 repeatMax; - } friendlyHealtPct; + } friendlyHealthPct; struct { diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index 27ca1d7df89..e7f7be356a6 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -55,7 +55,7 @@ enum TypeMask TYPEMASK_DYNAMICOBJECT = 0x0040, TYPEMASK_CORPSE = 0x0080, TYPEMASK_AREATRIGGER = 0x0100, - TYPEMASK_SEER = TYPEMASK_UNIT | TYPEMASK_DYNAMICOBJECT + TYPEMASK_SEER = TYPEMASK_PLAYER | TYPEMASK_UNIT | TYPEMASK_DYNAMICOBJECT }; enum TypeID diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 81a07e2620d..b7321b7c51d 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -586,6 +586,10 @@ void ObjectMgr::LoadCreatureTemplateAddons() TC_LOG_ERROR(LOG_FILTER_SQL, "Creature (Entry: %u) has wrong spell %u defined in `auras` field in `creature_template_addon`.", entry, uint32(atol(*itr))); continue; } + + if (AdditionalSpellInfo->HasAura(SPELL_AURA_CONTROL_VEHICLE)) + TC_LOG_ERROR(LOG_FILTER_SQL, "Creature (Entry: %u) has SPELL_AURA_CONTROL_VEHICLE aura %u defined in `auras` field in `creature_template_addon`.", entry, uint32(atol(*itr))); + creatureAddon.auras[i++] = uint32(atol(*itr)); } @@ -600,7 +604,7 @@ void ObjectMgr::LoadCreatureTemplateAddons() if (!sEmotesStore.LookupEntry(creatureAddon.emote)) { - TC_LOG_ERROR(LOG_FILTER_SQL, "Creature (Entry: %u) has invalid emote (%u) defined in `creature_addon`.", entry, creatureAddon.emote); + TC_LOG_ERROR(LOG_FILTER_SQL, "Creature (Entry: %u) has invalid emote (%u) defined in `creature_template_addon`.", entry, creatureAddon.emote); creatureAddon.emote = 0; } @@ -959,6 +963,10 @@ void ObjectMgr::LoadCreatureAddons() TC_LOG_ERROR(LOG_FILTER_SQL, "Creature (GUID: %u) has wrong spell %u defined in `auras` field in `creature_addon`.", guid, uint32(atol(*itr))); continue; } + + if (AdditionalSpellInfo->HasAura(SPELL_AURA_CONTROL_VEHICLE)) + TC_LOG_ERROR(LOG_FILTER_SQL, "Creature (GUID: %u) has SPELL_AURA_CONTROL_VEHICLE aura %u defined in `auras` field in `creature_addon`.", guid, uint32(atol(*itr))); + creatureAddon.auras[i++] = uint32(atol(*itr)); } diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index 2fe882d0c8a..275349c83cb 100644 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -317,107 +317,102 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater) _recvQueue.next(packet, updater)) { if (!AntiDOS.EvaluateOpcode(*packet)) - { - delete packet; - packet = NULL; KickPlayer(); - } - if (packet) + OpcodeHandler const* opHandle = opcodeTable[packet->GetOpcode()]; + try { - OpcodeHandler const* opHandle = opcodeTable[packet->GetOpcode()]; - try + switch (opHandle->Status) { - switch (opHandle->Status) - { - case STATUS_LOGGEDIN: - if (!_player) - { - // skip STATUS_LOGGEDIN opcode unexpected errors if player logout sometime ago - this can be network lag delayed packets - //! If player didn't log out a while ago, it means packets are being sent while the server does not recognize - //! the client to be in world yet. We will re-add the packets to the bottom of the queue and process them later. - if (!m_playerRecentlyLogout) - { - //! Prevent infinite loop - if (!firstDelayedPacket) - firstDelayedPacket = packet; - //! Because checking a bool is faster than reallocating memory - deletePacket = false; - QueuePacket(packet); - //! Log - TC_LOG_DEBUG(LOG_FILTER_NETWORKIO, "Re-enqueueing packet with opcode %s with with status STATUS_LOGGEDIN. " - "Player is currently not in world yet.", GetOpcodeNameForLogging(packet->GetOpcode()).c_str()); - } - } - else if (_player->IsInWorld()) - { - sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet)); - (this->*opHandle->Handler)(*packet); - LogUnprocessedTail(packet); - } - // lag can cause STATUS_LOGGEDIN opcodes to arrive after the player started a transfer - break; - case STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT: - if (!_player && !m_playerRecentlyLogout && !m_playerLogout) // There's a short delay between _player = null and m_playerRecentlyLogout = true during logout - LogUnexpectedOpcode(packet, "STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT", - "the player has not logged in yet and not recently logout"); - else + case STATUS_LOGGEDIN: + if (!_player) + { + // skip STATUS_LOGGEDIN opcode unexpected errors if player logout sometime ago - this can be network lag delayed packets + //! If player didn't log out a while ago, it means packets are being sent while the server does not recognize + //! the client to be in world yet. We will re-add the packets to the bottom of the queue and process them later. + if (!m_playerRecentlyLogout) { - // not expected _player or must checked in packet hanlder - sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet)); - (this->*opHandle->Handler)(*packet); - LogUnprocessedTail(packet); + //! Prevent infinite loop + if (!firstDelayedPacket) + firstDelayedPacket = packet; + //! Because checking a bool is faster than reallocating memory + deletePacket = false; + QueuePacket(packet); + //! Log + TC_LOG_DEBUG(LOG_FILTER_NETWORKIO, "Re-enqueueing packet with opcode %s with with status STATUS_LOGGEDIN. " + "Player is currently not in world yet.", GetOpcodeNameForLogging(packet->GetOpcode()).c_str()); } - break; - case STATUS_TRANSFER: - if (!_player) - LogUnexpectedOpcode(packet, "STATUS_TRANSFER", "the player has not logged in yet"); - else if (_player->IsInWorld()) - LogUnexpectedOpcode(packet, "STATUS_TRANSFER", "the player is still in world"); - else - { - sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet)); - (this->*opHandle->Handler)(*packet); - LogUnprocessedTail(packet); - } - break; - case STATUS_AUTHED: - // prevent cheating with skip queue wait - if (m_inQueue) - { - LogUnexpectedOpcode(packet, "STATUS_AUTHED", "the player not pass queue yet"); - break; - } - - // some auth opcodes can be recieved before STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT opcodes - // however when we recieve CMSG_CHAR_ENUM we are surely no longer during the logout process. - if (packet->GetOpcode() == CMSG_CHAR_ENUM) - m_playerRecentlyLogout = false; - + } + else if (_player->IsInWorld()) + { sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet)); (this->*opHandle->Handler)(*packet); LogUnprocessedTail(packet); + } + // lag can cause STATUS_LOGGEDIN opcodes to arrive after the player started a transfer + break; + case STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT: + if (!_player && !m_playerRecentlyLogout && !m_playerLogout) // There's a short delay between _player = null and m_playerRecentlyLogout = true during logout + LogUnexpectedOpcode(packet, "STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT", + "the player has not logged in yet and not recently logout"); + else + { + // not expected _player or must checked in packet hanlder + sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet)); + (this->*opHandle->Handler)(*packet); + LogUnprocessedTail(packet); + } + break; + case STATUS_TRANSFER: + if (!_player) + LogUnexpectedOpcode(packet, "STATUS_TRANSFER", "the player has not logged in yet"); + else if (_player->IsInWorld()) + LogUnexpectedOpcode(packet, "STATUS_TRANSFER", "the player is still in world"); + else + { + sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet)); + (this->*opHandle->Handler)(*packet); + LogUnprocessedTail(packet); + } + break; + case STATUS_AUTHED: + // prevent cheating with skip queue wait + if (m_inQueue) + { + LogUnexpectedOpcode(packet, "STATUS_AUTHED", "the player not pass queue yet"); break; - case STATUS_NEVER: - TC_LOG_ERROR(LOG_FILTER_OPCODES, "Received not allowed opcode %s from %s", GetOpcodeNameForLogging(packet->GetOpcode()).c_str() - , GetPlayerInfo().c_str()); - break; - case STATUS_UNHANDLED: - TC_LOG_ERROR(LOG_FILTER_OPCODES, "Received not handled opcode %s from %s", GetOpcodeNameForLogging(packet->GetOpcode()).c_str() - , GetPlayerInfo().c_str()); - break; - } + } + + // some auth opcodes can be recieved before STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT opcodes + // however when we recieve CMSG_CHAR_ENUM we are surely no longer during the logout process. + if (packet->GetOpcode() == CMSG_CHAR_ENUM) + m_playerRecentlyLogout = false; + + sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet)); + (this->*opHandle->Handler)(*packet); + LogUnprocessedTail(packet); + break; + case STATUS_NEVER: + TC_LOG_ERROR(LOG_FILTER_OPCODES, "Received not allowed opcode %s from %s", GetOpcodeNameForLogging(packet->GetOpcode()).c_str() + , GetPlayerInfo().c_str()); + break; + case STATUS_UNHANDLED: + TC_LOG_ERROR(LOG_FILTER_OPCODES, "Received not handled opcode %s from %s", GetOpcodeNameForLogging(packet->GetOpcode()).c_str() + , GetPlayerInfo().c_str()); + break; } - catch(ByteBufferException &) - { - TC_LOG_ERROR(LOG_FILTER_NETWORKIO, "WorldSession::Update ByteBufferException occured while parsing a packet (opcode: %u) from client %s, accountid=%i. Skipped packet.", - packet->GetOpcode(), GetRemoteAddress().c_str(), GetAccountId()); - packet->hexlike(); - } - - if (deletePacket) - delete packet; } + catch (ByteBufferException const&) + { + TC_LOG_ERROR(LOG_FILTER_NETWORKIO, "WorldSession::Update ByteBufferException occured while parsing a packet (opcode: %u) from client %s, accountid=%i. Skipped packet.", + packet->GetOpcode(), GetRemoteAddress().c_str(), GetAccountId()); + packet->hexlike(); + } + + if (deletePacket) + delete packet; + + deletePacket = true; } if (m_Socket && !m_Socket->IsClosed() && _warden) diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 5fdc499403a..7ec30c49d3c 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -84,7 +84,7 @@ ACE_Atomic_Op<ACE_Thread_Mutex, bool> World::m_stopEvent = false; uint8 World::m_ExitCode = SHUTDOWN_EXIT_CODE; -volatile uint32 World::m_worldLoopCounter = 0; +ACE_Atomic_Op<ACE_Thread_Mutex, uint32> World::m_worldLoopCounter = 0; float World::m_MaxVisibleDistanceOnContinents = DEFAULT_VISIBILITY_DISTANCE; float World::m_MaxVisibleDistanceInInstances = DEFAULT_VISIBILITY_INSTANCE; diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h index 0ba76ff3ce2..8de393ee54b 100644 --- a/src/server/game/World/World.h +++ b/src/server/game/World/World.h @@ -534,7 +534,7 @@ struct CharacterNameData class World { public: - static volatile uint32 m_worldLoopCounter; + static ACE_Atomic_Op<ACE_Thread_Mutex, uint32> m_worldLoopCounter; World(); ~World(); diff --git a/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_devourer_of_souls.cpp b/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_devourer_of_souls.cpp index b1ecdc5904e..7d923e7686f 100644 --- a/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_devourer_of_souls.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_devourer_of_souls.cpp @@ -403,21 +403,19 @@ class spell_devourer_of_souls_mirrored_soul_proc : public SpellScriptLoader bool Load() OVERRIDE { - _procTarget = NULL; return true; } bool CheckProc(ProcEventInfo& /*eventInfo*/) { - _procTarget = GetCaster(); - return _procTarget && _procTarget->IsAlive(); + return GetCaster() && GetCaster()->IsAlive(); } void HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo) { PreventDefaultAction(); int32 damage = int32(CalculatePct(eventInfo.GetDamageInfo()->GetDamage(), 45)); - GetTarget()->CastCustomSpell(SPELL_MIRRORED_SOUL_DAMAGE, SPELLVALUE_BASE_POINT0, damage, _procTarget, true); + GetTarget()->CastCustomSpell(SPELL_MIRRORED_SOUL_DAMAGE, SPELLVALUE_BASE_POINT0, damage, GetCaster(), true); } void Register() OVERRIDE @@ -425,9 +423,6 @@ class spell_devourer_of_souls_mirrored_soul_proc : public SpellScriptLoader DoCheckProc += AuraCheckProcFn(spell_devourer_of_souls_mirrored_soul_proc_AuraScript::CheckProc); OnEffectProc += AuraEffectProcFn(spell_devourer_of_souls_mirrored_soul_proc_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); } - - private: - Unit* _procTarget; }; AuraScript* GetAuraScript() const OVERRIDE diff --git a/src/server/scripts/Northrend/Gundrak/boss_slad_ran.cpp b/src/server/scripts/Northrend/Gundrak/boss_slad_ran.cpp index afd0e8a4342..0097fe8c4d7 100644 --- a/src/server/scripts/Northrend/Gundrak/boss_slad_ran.cpp +++ b/src/server/scripts/Northrend/Gundrak/boss_slad_ran.cpp @@ -256,8 +256,6 @@ public: } } else uiGripOfSladRanTimer -= diff; } - - InstanceScript* instance; }; }; @@ -278,8 +276,6 @@ public: uint32 uiVenomousBiteTimer; - InstanceScript* instance; - void Reset() OVERRIDE { uiVenomousBiteTimer = 2*IN_MILLISECONDS; 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 38864effe9f..46776ae9b96 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_general_vezax.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_general_vezax.cpp @@ -39,7 +39,7 @@ enum VezaxEmotes EMOTE_SURGE_OF_DARKNESS = 8, // Saronite Vapor - EMOTE_VAPORS = 9 + EMOTE_VAPORS = 0 }; enum VezaxSpells @@ -443,14 +443,21 @@ class npc_saronite_vapors : public CreatureScript } }; -class spell_mark_of_the_faceless : public SpellScriptLoader +class spell_general_vezax_mark_of_the_faceless : public SpellScriptLoader { public: - spell_mark_of_the_faceless() : SpellScriptLoader("spell_mark_of_the_faceless") { } + spell_general_vezax_mark_of_the_faceless() : SpellScriptLoader("spell_general_vezax_mark_of_the_faceless") { } - class spell_mark_of_the_faceless_AuraScript : public AuraScript + class spell_general_vezax_mark_of_the_faceless_AuraScript : public AuraScript { - PrepareAuraScript(spell_mark_of_the_faceless_AuraScript); + PrepareAuraScript(spell_general_vezax_mark_of_the_faceless_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_MARK_OF_THE_FACELESS_DAMAGE)) + return false; + return true; + } void HandleEffectPeriodic(AuraEffect const* aurEff) { @@ -460,13 +467,42 @@ class spell_mark_of_the_faceless : public SpellScriptLoader void Register() OVERRIDE { - OnEffectPeriodic += AuraEffectPeriodicFn(spell_mark_of_the_faceless_AuraScript::HandleEffectPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); + OnEffectPeriodic += AuraEffectPeriodicFn(spell_general_vezax_mark_of_the_faceless_AuraScript::HandleEffectPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); } }; AuraScript* GetAuraScript() const OVERRIDE { - return new spell_mark_of_the_faceless_AuraScript(); + return new spell_general_vezax_mark_of_the_faceless_AuraScript(); + } +}; + +class spell_general_vezax_mark_of_the_faceless_leech : public SpellScriptLoader +{ + public: + spell_general_vezax_mark_of_the_faceless_leech() : SpellScriptLoader("spell_general_vezax_mark_of_the_faceless_leech") { } + + class spell_general_vezax_mark_of_the_faceless_leech_SpellScript : public SpellScript + { + PrepareSpellScript(spell_general_vezax_mark_of_the_faceless_leech_SpellScript); + + void FilterTargets(std::list<WorldObject*>& targets) + { + targets.remove(GetExplTargetWorldObject()); + + if (targets.empty()) + FinishCast(SPELL_FAILED_NO_VALID_TARGETS); + } + + void Register() + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_general_vezax_mark_of_the_faceless_leech_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_DEST_AREA_ENEMY); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_general_vezax_mark_of_the_faceless_leech_SpellScript(); } }; @@ -554,7 +590,8 @@ void AddSC_boss_general_vezax() new boss_general_vezax(); new boss_saronite_animus(); new npc_saronite_vapors(); - new spell_mark_of_the_faceless(); + new spell_general_vezax_mark_of_the_faceless(); + new spell_general_vezax_mark_of_the_faceless_leech(); new spell_general_vezax_saronite_vapors(); new achievement_shadowdodger(); new achievement_smell_saronite(); diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp index 56fd4b310ee..6783d8cd428 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp @@ -16,6 +16,7 @@ */ #include "ScriptMgr.h" +#include "ScriptedCreature.h" #include "SpellScript.h" #include "ulduar.h" diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp index 8691f9769fa..d0cb7108c09 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp @@ -24,15 +24,21 @@ 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 }, - {GO_YOGG_SARON_DOOR, BOSS_YOGG_SARON, 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 }, + { GO_LEVIATHAN_DOOR, BOSS_LEVIATHAN, DOOR_TYPE_ROOM, BOUNDARY_S }, + { GO_XT_002_DOOR, BOSS_XT002, DOOR_TYPE_ROOM, BOUNDARY_S }, + { GO_IRON_COUNCIL_DOOR, BOSS_ASSEMBLY_OF_IRON, DOOR_TYPE_ROOM, BOUNDARY_N }, + { GO_ARCHIVUM_DOOR, BOSS_ASSEMBLY_OF_IRON, DOOR_TYPE_PASSAGE, BOUNDARY_S }, + { GO_HODIR_ENTRANCE, BOSS_HODIR, DOOR_TYPE_ROOM, BOUNDARY_E }, + { GO_HODIR_DOOR, BOSS_HODIR, DOOR_TYPE_PASSAGE, BOUNDARY_NONE }, + { GO_HODIR_ICE_DOOR, BOSS_HODIR, DOOR_TYPE_PASSAGE, BOUNDARY_W }, + { GO_VEZAX_DOOR, BOSS_VEZAX, DOOR_TYPE_PASSAGE, BOUNDARY_E }, + { GO_YOGG_SARON_DOOR, BOSS_YOGG_SARON, 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 }, }; MinionData const minionData[] = @@ -46,7 +52,7 @@ MinionData const minionData[] = class instance_ulduar : public InstanceMapScript { public: - instance_ulduar() : InstanceMapScript("instance_ulduar", 603) { } + instance_ulduar() : InstanceMapScript(UlduarScriptName, 603) { } struct instance_ulduar_InstanceMapScript : public InstanceScript { @@ -73,6 +79,7 @@ class instance_ulduar : public InstanceMapScript uint64 VoiceOfYoggSaronGUID; uint64 SaraGUID; uint64 BrainOfYoggSaronGUID; + uint64 KeeperGUIDs[4]; uint64 AlgalonGUID; uint64 BrannBronzebeardAlgGUID; @@ -81,16 +88,10 @@ class instance_ulduar : public InstanceMapScript uint64 RazorHarpoonGUIDs[4]; uint64 KologarnChestGUID; uint64 KologarnBridgeGUID; - uint64 KologarnDoorGUID; uint64 ThorimChestGUID; uint64 HodirRareCacheGUID; uint64 HodirChestGUID; - uint64 HodirDoorGUID; - uint64 HodirIceDoorGUID; - uint64 ArchivumDoorGUID; - uint64 VezaxDoorGUID; uint64 BrainRoomDoorGUIDs[3]; - uint64 KeeperGUIDs[4]; uint64 AlgalonSigilDoorGUID[3]; uint64 AlgalonFloorGUID[2]; uint64 AlgalonUniverseGUID; @@ -138,10 +139,6 @@ class instance_ulduar : public InstanceMapScript HodirRareCacheGUID = 0; HodirChestGUID = 0; LeviathanGateGUID = 0; - VezaxDoorGUID = 0; - HodirDoorGUID = 0; - HodirIceDoorGUID = 0; - ArchivumDoorGUID = 0; AlgalonUniverseGUID = 0; AlgalonTrapdoorGUID = 0; BrannBronzebeardAlgGUID = 0; @@ -458,9 +455,6 @@ class instance_ulduar : public InstanceMapScript if (GetBossState(BOSS_KOLOGARN) == DONE) HandleGameObject(0, false, gameObject); break; - case GO_KOLOGARN_DOOR: - KologarnDoorGUID = gameObject->GetGUID(); - break; case GO_THORIM_CHEST_HERO: case GO_THORIM_CHEST: ThorimChestGUID = gameObject->GetGUID(); @@ -473,20 +467,21 @@ class instance_ulduar : public InstanceMapScript case GO_HODIR_CHEST: HodirChestGUID = gameObject->GetGUID(); break; - case GO_LEVIATHAN_DOOR: - AddDoor(gameObject, true); - break; case GO_LEVIATHAN_GATE: LeviathanGateGUID = gameObject->GetGUID(); if (GetBossState(BOSS_LEVIATHAN) == DONE) gameObject->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE); break; + case GO_LEVIATHAN_DOOR: case GO_XT_002_DOOR: - AddDoor(gameObject, true); - break; + case GO_IRON_COUNCIL_DOOR: + case GO_ARCHIVUM_DOOR: + case GO_HODIR_ENTRANCE: + case GO_HODIR_DOOR: + case GO_HODIR_ICE_DOOR: case GO_VEZAX_DOOR: - VezaxDoorGUID = gameObject->GetGUID(); - HandleGameObject(0, false, gameObject); + case GO_YOGG_SARON_DOOR: + AddDoor(gameObject, true); break; case GO_RAZOR_HARPOON_1: RazorHarpoonGUIDs[0] = gameObject->GetGUID(); @@ -504,20 +499,6 @@ class instance_ulduar : public InstanceMapScript if (GetBossState(BOSS_RAZORSCALE) == IN_PROGRESS) gameObject->SetGoState(GO_STATE_ACTIVE); break; - case GO_HODIR_DOOR: - HodirDoorGUID = gameObject->GetGUID(); - break; - case GO_HODIR_ICE_DOOR: - HodirIceDoorGUID = gameObject->GetGUID(); - break; - case GO_ARCHIVUM_DOOR: - ArchivumDoorGUID = gameObject->GetGUID(); - if (GetBossState(BOSS_ASSEMBLY_OF_IRON) != DONE) - HandleGameObject(ArchivumDoorGUID, false); - break; - case GO_YOGG_SARON_DOOR: - AddDoor(gameObject, true); - break; case GO_BRAIN_ROOM_DOOR_1: BrainRoomDoorGUIDs[0] = gameObject->GetGUID(); break; @@ -566,6 +547,8 @@ class instance_ulduar : public InstanceMapScript case GO_GIFT_OF_THE_OBSERVER_25: GiftOfTheObserverGUID = gameObject->GetGUID(); break; + default: + break; } } @@ -575,6 +558,13 @@ class instance_ulduar : public InstanceMapScript { case GO_LEVIATHAN_DOOR: case GO_XT_002_DOOR: + case GO_IRON_COUNCIL_DOOR: + case GO_ARCHIVUM_DOOR: + case GO_HODIR_ENTRANCE: + case GO_HODIR_DOOR: + case GO_HODIR_ICE_DOOR: + case GO_VEZAX_DOOR: + case GO_YOGG_SARON_DOOR: case GO_DOODAD_UL_SIGILDOOR_03: case GO_DOODAD_UL_UNIVERSEFLOOR_01: case GO_DOODAD_UL_UNIVERSEFLOOR_02: @@ -659,7 +649,10 @@ class instance_ulduar : public InstanceMapScript case BOSS_IGNIS: case BOSS_RAZORSCALE: case BOSS_XT002: + case BOSS_ASSEMBLY_OF_IRON: case BOSS_AURIAYA: + case BOSS_VEZAX: + case BOSS_YOGG_SARON: break; case BOSS_MIMIRON: if (state == DONE) @@ -669,16 +662,6 @@ class instance_ulduar : public InstanceMapScript if (state == DONE) instance->SummonCreature(NPC_FREYA_OBSERVATION_RING, ObservationRingKeepersPos[0]); break; - case BOSS_ASSEMBLY_OF_IRON: - if (state == DONE) - HandleGameObject(ArchivumDoorGUID, true); - break; - case BOSS_VEZAX: - if (state == DONE) - HandleGameObject(VezaxDoorGUID, true); - break; - case BOSS_YOGG_SARON: - break; case BOSS_KOLOGARN: if (state == DONE) { @@ -698,8 +681,6 @@ class instance_ulduar : public InstanceMapScript HodirRareCache->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); if (GameObject* HodirChest = instance->GetGameObject(HodirChestGUID)) HodirChest->SetRespawnTime(HodirChest->GetRespawnDelay()); - HandleGameObject(HodirDoorGUID, true); - HandleGameObject(HodirIceDoorGUID, true); instance->SummonCreature(NPC_HODIR_OBSERVATION_RING, ObservationRingKeepersPos[1]); } diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h b/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h index 35d11522580..45134cd9ff6 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h @@ -166,29 +166,46 @@ enum UlduarNPCs 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, + // Leviathan GO_LEVIATHAN_DOOR = 194905, GO_LEVIATHAN_GATE = 194630, - GO_XT_002_DOOR = 194631, - GO_VEZAX_DOOR = 194750, + + // Razorscale 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, + + // XT-002 + GO_XT_002_DOOR = 194631, + + // Assembly of Iron + GO_IRON_COUNCIL_DOOR = 194554, + GO_ARCHIVUM_DOOR = 194556, + + // Kologarn + GO_KOLOGARN_CHEST_HERO = 195047, + GO_KOLOGARN_CHEST = 195046, + GO_KOLOGARN_BRIDGE = 194232, + GO_KOLOGARN_DOOR = 194553, + + // Hodir + GO_HODIR_ENTRANCE = 194442, GO_HODIR_DOOR = 194634, GO_HODIR_ICE_DOOR = 194441, - GO_ARCHIVUM_DOOR = 194556, + GO_HODIR_RARE_CACHE_OF_WINTER = 194200, + GO_HODIR_RARE_CACHE_OF_WINTER_HERO = 194201, + GO_HODIR_CHEST_HERO = 194308, + GO_HODIR_CHEST = 194307, + + // Thorim + GO_THORIM_CHEST_HERO = 194315, + GO_THORIM_CHEST = 194314, + + // Vezax + GO_VEZAX_DOOR = 194750, // Yogg-Saron GO_YOGG_SARON_DOOR = 194773, @@ -327,26 +344,10 @@ enum YoggSaronIllusions STORMWIND_ILLUSION = 2, }; -template<class AI> -CreatureAI* GetUlduarAI(Creature* creature) +template<class AI, class T> +AI* GetUlduarAI(T* obj) { - if (InstanceMap* instance = creature->GetMap()->ToInstanceMap()) - if (instance->GetInstanceScript()) - if (instance->GetScriptId() == sObjectMgr->GetScriptId(UlduarScriptName)) - return new AI(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; + return GetInstanceAI<AI, T>(obj, UlduarScriptName); } class PlayerOrPetCheck diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar_teleporter.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar_teleporter.cpp index 054a32a75d2..0daa9ea16c6 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar_teleporter.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar_teleporter.cpp @@ -18,9 +18,9 @@ #include "ScriptMgr.h" #include "ScriptedGossip.h" -#include "ulduar.h" #include "InstanceScript.h" #include "Player.h" +#include "ulduar.h" /* The teleporter appears to be active and stable. diff --git a/src/server/scripts/Outland/zone_netherstorm.cpp b/src/server/scripts/Outland/zone_netherstorm.cpp index 74257c95cf3..7c328f57e78 100644 --- a/src/server/scripts/Outland/zone_netherstorm.cpp +++ b/src/server/scripts/Outland/zone_netherstorm.cpp @@ -753,7 +753,6 @@ public: bool Drained; uint8 WeakPercent; - Player* player; uint64 PlayerGUID; uint32 ManaBurnTimer; diff --git a/src/server/worldserver/Master.cpp b/src/server/worldserver/Master.cpp index b2a6b60ac4f..d9b97cfd3f5 100644 --- a/src/server/worldserver/Master.cpp +++ b/src/server/worldserver/Master.cpp @@ -103,10 +103,11 @@ public: ACE_Based::Thread::Sleep(1000); uint32 curtime = getMSTime(); // normal work - if (_loops != World::m_worldLoopCounter) + uint32 worldLoopCounter = World::m_worldLoopCounter.value(); + if (_loops != worldLoopCounter) { _lastChange = curtime; - _loops = World::m_worldLoopCounter; + _loops = worldLoopCounter; } // possible freeze else if (getMSTimeDiff(_lastChange, curtime) > _delaytime) |