diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp index ada63891f..fff9e87c5 100644 --- a/src/game/Creature.cpp +++ b/src/game/Creature.cpp @@ -40,6 +40,7 @@ #include "InstanceData.h" #include "MapPersistentStateMgr.h" #include "BattleGroundMgr.h" +#include "OutdoorPvP/OutdoorPvP.h" #include "Spell.h" #include "Util.h" #include "GridNotifiers.h" @@ -755,6 +756,10 @@ bool Creature::Create(uint32 guidlow, CreatureCreatePos& cPos, CreatureInfo cons if (InstanceData* iData = GetMap()->GetInstanceData()) iData->OnCreatureCreate(this); + // Notify the outdoor pvp script + if (OutdoorPvP* outdoorPvP = sOutdoorPvPMgr.GetScript(GetZoneId())) + outdoorPvP->HandleCreatureCreate(this); + switch (GetCreatureInfo()->rank) { case CREATURE_ELITE_RARE: diff --git a/src/game/GameObject.cpp b/src/game/GameObject.cpp index dc778b4c8..ca73f7fa2 100644 --- a/src/game/GameObject.cpp +++ b/src/game/GameObject.cpp @@ -172,6 +172,10 @@ bool GameObject::Create(uint32 guidlow, uint32 name_id, Map* map, uint32 phaseMa if (InstanceData* iData = map->GetInstanceData()) iData->OnObjectCreate(this); + // Notify the outdoor pvp script + if (OutdoorPvP* outdoorPvP = sOutdoorPvPMgr.GetScript(GetZoneId())) + outdoorPvP->HandleGameObjectCreate(this); + return true; } @@ -1152,6 +1156,15 @@ void GameObject::Use(Unit* user) } case GAMEOBJECT_TYPE_GOOBER: // 10 { + // Handle OutdoorPvP use cases + // Note: this may be also handled by DB spell scripts in the future, when the world state manager is implemented + if (user->GetTypeId() == TYPEID_PLAYER) + { + Player* player = (Player*)user; + if (OutdoorPvP* outdoorPvP = sOutdoorPvPMgr.GetScript(player->GetCachedZoneId())) + outdoorPvP->HandleGameObjectUse(player, this); + } + GameObjectInfo const* info = GetGOInfo(); TriggerLinkedGameObject(user); @@ -2092,7 +2105,10 @@ void GameObject::TickCapturePoint() { eventId = info->capturePoint.progressEventID1; - // TODO handle objective complete + // handle objective complete + if (m_captureState == CAPTURE_STATE_NEUTRAL) + if (OutdoorPvP* outdoorPvP = sOutdoorPvPMgr.GetScript((*capturingPlayers.begin())->GetCachedZoneId())) + outdoorPvP->HandleObjectiveComplete(eventId, capturingPlayers, progressFaction); // set capture state to alliance m_captureState = CAPTURE_STATE_PROGRESS_ALLIANCE; @@ -2102,7 +2118,10 @@ void GameObject::TickCapturePoint() { eventId = info->capturePoint.progressEventID2; - // TODO handle objective complete + // handle objective complete + if (m_captureState == CAPTURE_STATE_NEUTRAL) + if (OutdoorPvP* outdoorPvP = sOutdoorPvPMgr.GetScript((*capturingPlayers.begin())->GetCachedZoneId())) + outdoorPvP->HandleObjectiveComplete(eventId, capturingPlayers, progressFaction); // set capture state to horde m_captureState = CAPTURE_STATE_PROGRESS_HORDE; @@ -2138,6 +2157,14 @@ void GameObject::TickCapturePoint() if (eventId) { + // Notify the outdoor pvp script + if (OutdoorPvP* outdoorPvP = sOutdoorPvPMgr.GetScript((*capturingPlayers.begin())->GetCachedZoneId())) + { + // Allow only certain events to be handled by other script engines + if (outdoorPvP->HandleEvent(eventId, this)) + return; + } + // Send script event to SD2 and database as well - this can be used for summoning creatures, casting specific spells or spawning GOs if (!sScriptMgr.OnProcessEvent(eventId, this, this, true)) GetMap()->ScriptsStart(sEventScripts, eventId, this, this); diff --git a/src/game/MiscHandler.cpp b/src/game/MiscHandler.cpp index 8151defc1..755067fbf 100644 --- a/src/game/MiscHandler.cpp +++ b/src/game/MiscHandler.cpp @@ -38,6 +38,7 @@ #include "ObjectAccessor.h" #include "Object.h" #include "BattleGround.h" +#include "OutdoorPvP/OutdoorPvP.h" #include "Pet.h" #include "SocialMgr.h" #include "DBCEnums.h" @@ -741,6 +742,12 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPacket& recv_data) return; } + if (OutdoorPvP* outdoorPvP = sOutdoorPvPMgr.GetScript(pl->GetCachedZoneId())) + { + if (outdoorPvP->HandleAreaTrigger(pl, Trigger_ID)) + return; + } + // NULL if all values default (non teleport trigger) AreaTrigger const* at = sObjectMgr.GetAreaTrigger(Trigger_ID); if (!at) diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 2b997299b..c2835d48c 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -52,6 +52,7 @@ #include "BattleGround.h" #include "BattleGroundAV.h" #include "BattleGroundMgr.h" +#include "OutdoorPvP/OutdoorPvP.h" #include "ArenaTeam.h" #include "Chat.h" #include "Database/DatabaseImpl.h" @@ -621,6 +622,10 @@ void Player::CleanupsBeforeDelete() TradeCancel(false); DuelComplete(DUEL_INTERUPTED); } + + // notify zone scripts for player logout + sOutdoorPvPMgr.HandlePlayerLeaveZone(this, m_zoneUpdateId); + Unit::CleanupsBeforeDelete(); } @@ -6870,6 +6875,10 @@ void Player::UpdateZone(uint32 newZone, uint32 newArea) if (m_zoneUpdateId != newZone) { + // handle outdoor pvp zones + sOutdoorPvPMgr.HandlePlayerLeaveZone(this, m_zoneUpdateId); + sOutdoorPvPMgr.HandlePlayerEnterZone(this, newZone); + SendInitWorldStates(newZone, newArea); // only if really enters to new zone, not just area change, works strange... if (sWorld.getConfig(CONFIG_BOOL_WEATHER)) diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 9ef658fa5..331676ab9 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -38,6 +38,7 @@ #include "Creature.h" #include "Formulas.h" #include "BattleGround.h" +#include "OutdoorPvP/OutdoorPvP.h" #include "CreatureAI.h" #include "ScriptMgr.h" #include "Util.h" @@ -5194,8 +5195,11 @@ void Aura::HandleAuraModEffectImmunity(bool apply, bool /*Real*/) if( !apply && target->GetTypeId() == TYPEID_PLAYER && (GetSpellProto()->GetAuraInterruptFlags() & AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION) ) { - if (BattleGround* bg = ((Player*)target)->GetBattleGround()) - bg->EventPlayerDroppedFlag(((Player*)target)); + Player* player = (Player*)target; + if (BattleGround* bg = player->GetBattleGround()) + bg->EventPlayerDroppedFlag(player); + else if (OutdoorPvP* outdoorPvP = sOutdoorPvPMgr.GetScript(player->GetCachedZoneId())) + outdoorPvP->HandleDropFlag(player, GetSpellProto()->Id); } target->ApplySpellImmune(GetId(), IMMUNITY_EFFECT, m_modifier.m_miscvalue, apply); diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 58a5c8738..8435b62f8 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -42,6 +42,7 @@ #include "Vehicle.h" #include "BattleGround.h" #include "InstanceData.h" +#include "OutdoorPvP/OutdoorPvP.h" #include "MapPersistentStateMgr.h" #include "GridNotifiersImpl.h" #include "CellImpl.h" @@ -1097,6 +1098,13 @@ uint32 Unit::DealDamage(Unit* pVictim, uint32 damage, CleanDamage const* cleanDa he->DuelComplete(DUEL_INTERUPTED); } + // handle player kill in outdoor pvp + if (player_tap && pVictim->GetTypeId() == TYPEID_PLAYER && pVictim != this) + { + if (OutdoorPvP* outdoorPvP = sOutdoorPvPMgr.GetScript(player_tap->GetCachedZoneId())) + outdoorPvP->HandlePlayerKill(player_tap, pVictim); + } + // battleground things (do this at the end, so the death state flag will be properly set to handle in the bg->handlekill) if (pVictim->GetTypeId() == TYPEID_PLAYER && ((Player*)pVictim)->InBattleGround()) { @@ -1328,6 +1336,10 @@ void Unit::JustKilledCreature(Creature* victim) if (InstanceData* mapInstance = victim->GetInstanceData()) mapInstance->OnCreatureDeath(victim); + // Notify the outdoor pvp script + if (OutdoorPvP* outdoorPvP = sOutdoorPvPMgr.GetScript(GetZoneId())) + outdoorPvP->HandleCreatureDeath(victim); + if (victim->IsLinkingEventTrigger()) victim->GetMap()->GetCreatureLinkingHolder()->DoCreatureLinkingEvent(LINKING_EVENT_DIE, victim);