From c77683afbb57b0d081fe5d2a72df650fd6c99515 Mon Sep 17 00:00:00 2001 From: balrok Date: Wed, 2 Sep 2009 20:39:01 +0000 Subject: [PATCH] event-handling functions in battleground-class i added a map m_ActiveEvents which will track all current active events it's allways key:event1 -> value:event2 so it's like a one dimensional array which contains current active event2.. i only need one event2 in this list, cause i only want to allow one event2 at the same time if other event2 are also active right now - i would just despawn it (for example (numbers not real) arathi basin stables are event1=3 and have 5 states (alliance assault, horde assault, neutral...) so every state has an event2 index and only one state at a time is possible (so if we spawn horde-contested gameobjects/creatures, we will despawn everything else) OnObjectDBLoad - generic implementation for this function: will automaticly spawn or not spawn.. open (doors) or not open gameobjects/creatures doors: i use event1=254 and event2=0 IsDoor(event1,event2) - just a check if this event could be a door (mostly not needed for bg-subclasses) OpenDoorEvent(event1,event2) - opens the door (used in bg subclass cause some doors also must be despawned) SpawnEvent(event1, event2, bool spawn) spawn=true says all related gameobjects/creatures getting spawned, else despawned will despawn all event2 in event1 which are not equal to the event2-parameter also this function will set the right values in m_ActiveEvents IsActiveEvent(event1,event2) - returns true if event is active --- src/game/BattleGround.cpp | 87 +++++++++++++++++++++++++++++++++++++++ src/game/BattleGround.h | 41 +++++++++++++++++- 2 files changed, 127 insertions(+), 1 deletion(-) diff --git a/src/game/BattleGround.cpp b/src/game/BattleGround.cpp index 86e380e3d..245c3a696 100644 --- a/src/game/BattleGround.cpp +++ b/src/game/BattleGround.cpp @@ -1083,6 +1083,9 @@ void BattleGround::Reset() m_Events = 0; + // door-event2 is always 0 + m_ActiveEvents[BG_EVENT_DOOR] = 0; + if (m_InvitedAlliance > 0 || m_InvitedHorde > 0) sLog.outError("BattleGround system: bad counter, m_InvitedAlliance: %d, m_InvitedHorde: %d", m_InvitedAlliance, m_InvitedHorde); @@ -1447,6 +1450,90 @@ void BattleGround::DoorOpen(uint64 const& guid) } } +void BattleGround::OnObjectDBLoad(Creature* creature) +{ + BattleGroundEventIdx eventId = sBattleGroundMgr.GetCreatureEventIndex(creature->GetDBTableGUIDLow()); + if (eventId.event1 == BG_EVENT_NONE) + return; + m_EventObjects[MAKE_PAIR32(eventId.event1, eventId.event2)].creatures.push_back(creature->GetGUID()); + if (!IsActiveEvent(eventId.event1, eventId.event2)) + SpawnBGCreature(creature->GetGUID(), RESPAWN_ONE_DAY); +} + + +void BattleGround::OnObjectDBLoad(GameObject* obj) +{ + BattleGroundEventIdx eventId = sBattleGroundMgr.GetGameObjectEventIndex(obj->GetDBTableGUIDLow()); + if (eventId.event1 == BG_EVENT_NONE) + return; + m_EventObjects[MAKE_PAIR32(eventId.event1, eventId.event2)].gameobjects.push_back(obj->GetGUID()); + if (!IsActiveEvent(eventId.event1, eventId.event2)) + { + SpawnBGObject(obj->GetGUID(), RESPAWN_ONE_DAY); + } + else + { + // it's possible, that doors aren't spawned anymore (wsg) + if (GetStatus() >= STATUS_IN_PROGRESS && IsDoor(eventId.event1, eventId.event2)) + DoorOpen(obj->GetGUID()); + } +} + +bool BattleGround::IsDoor(uint8 event1, uint8 event2) +{ + if (event1 == BG_EVENT_DOOR) + { + if (event2 > 0) + { + sLog.outError("BattleGround too high event2 for event1:%i", event1); + return false; + } + return true; + } + return false; +} + +void BattleGround::OpenDoorEvent(uint8 event1, uint8 event2 /*=0*/) +{ + if (!IsDoor(event1, event2)) + { + sLog.outError("BattleGround:OpenDoorEvent this is no door event1:%u event2:%u", event1, event2); + return; + } + if (!IsActiveEvent(event1, event2)) // maybe already despawned (eye) + { + sLog.outError("BattleGround:OpenDoorEvent this event isn't active event1:%u event2:%u", event1, event2); + return; + } + BGObjects::const_iterator itr = m_EventObjects[MAKE_PAIR32(event1, event2)].gameobjects.begin(); + for(; itr != m_EventObjects[MAKE_PAIR32(event1, event2)].gameobjects.end(); ++itr) + DoorOpen(*itr); +} + +void BattleGround::SpawnEvent(uint8 event1, uint8 event2, bool spawn) +{ + // stop if we want to spawn something which was already spawned + // or despawn something which was already despawned + if (event2 == BG_EVENT_NONE || (spawn && m_ActiveEvents[event1] == event2) + || (!spawn && m_ActiveEvents[event1] != event2)) + return; + + if (spawn) + { + // if event gets spawned, the current active event mus get despawned + SpawnEvent(event1, m_ActiveEvents[event1], false); + m_ActiveEvents[event1] = event2; // set this event to active + } + else + m_ActiveEvents[event1] = BG_EVENT_NONE; // no event active if event2 gets despawned + + BGCreatures::const_iterator itr = m_EventObjects[MAKE_PAIR32(event1, event2)].creatures.begin(); + for(; itr != m_EventObjects[MAKE_PAIR32(event1, event2)].creatures.end(); ++itr) + SpawnBGCreature(*itr, (spawn) ? RESPAWN_IMMEDIATELY : RESPAWN_ONE_DAY); + BGObjects::const_iterator itr2 = m_EventObjects[MAKE_PAIR32(event1, event2)].gameobjects.begin(); + for(; itr2 != m_EventObjects[MAKE_PAIR32(event1, event2)].gameobjects.end(); ++itr2) + SpawnBGObject(*itr2, (spawn) ? RESPAWN_IMMEDIATELY : RESPAWN_ONE_DAY); +} void BattleGround::SpawnBGObject(uint64 const& guid, uint32 respawntime) { diff --git a/src/game/BattleGround.h b/src/game/BattleGround.h index 688c8fbc6..a16d4243e 100644 --- a/src/game/BattleGround.h +++ b/src/game/BattleGround.h @@ -22,7 +22,12 @@ #include "Common.h" #include "SharedDefines.h" +// magic event-numbers #define BG_EVENT_NONE 255 +// those generic events should get a high event id +#define BG_EVENT_DOOR 254 + + class Creature; class GameObject; class Group; @@ -484,14 +489,30 @@ class BattleGround virtual void RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPacket); // can be extended in in BG subclass + /* event related */ + // generic implementation in BattleGround-class + // called when a creature gets added to map (NOTE: only triggered if + // a player activates the cell of the creature) virtual void OnObjectDBLoad(Creature* /*creature*/); virtual void OnObjectDBLoad(GameObject* /*obj*/); + // (de-)spawns creatures and gameobjects from an event + void SpawnEvent(uint8 event1, uint8 event2, bool spawn); + bool IsActiveEvent(uint8 event1, uint8 event2) + { + if (m_ActiveEvents.find(event1) == m_ActiveEvents.end()) + return false; + return m_ActiveEvents[event1] == event2; + } + void OpenDoorEvent(uint8 event1, uint8 event2 = 0); + bool IsDoor(uint8 event1, uint8 event2); + /* other things */ void HandleTriggerBuff(uint64 const& go_guid); // TODO: make this protected: typedef std::vector BGObjects; typedef std::vector BGCreatures; + // TODO drop m_BGObjects BGObjects m_BgObjects; BGCreatures m_BgCreatures; void SpawnBGObject(uint64 const& guid, uint32 respawntime); @@ -517,13 +538,31 @@ class BattleGround /* virtual score-array - get's used in bg-subclasses */ int32 m_TeamScores[BG_TEAMS_COUNT]; + struct EventObjects + { + BGObjects gameobjects; + BGCreatures creatures; + }; + + //typedef std::map> BGObjectMap; + //typedef std::map> BGEventMap; + // cause we create it dynamicly i use a map - to avoid resizing when + // using vector - also it contains 2*events concatenated with PAIR32 + // this is needed to avoid overhead of a 2dimensional std::map + std::map m_EventObjects; + // this must be filled first in BattleGroundXY::Reset().. else + // creatures will get added wrong + // door-events are automaticly added - but _ALL_ other must be in this vector + std::map m_ActiveEvents; + + protected: //this method is called, when BG cannot spawn its own spirit guide, or something is wrong, It correctly ends BattleGround void EndNow(); void PlayerAddedToBGCheckIfBGIsRunning(Player* plr); /* Scorekeeping */ - + BattleGroundScoreMap m_PlayerScores; // Player scores // must be implemented in BG subclass virtual void RemovePlayer(Player * /*player*/, uint64 /*guid*/) {}