diff options
author | megamage <none@none> | 2008-11-21 19:45:49 -0600 |
---|---|---|
committer | megamage <none@none> | 2008-11-21 19:45:49 -0600 |
commit | fa667cf4507e5635d597b878119ce20f2836cc8c (patch) | |
tree | 34a1b3a70db2d8ba86be680bb341f1e499b0d672 /src | |
parent | b2ba78e57a7c1895d1bacf950a3705eedd01c256 (diff) |
*Alterac Valley. By Bogie and Balrok. Note: some core contents are modified. Will fix them later. Some sql are disabled because of possible conflict with offical DB. Use them at your own risk.
--HG--
branch : trunk
Diffstat (limited to 'src')
-rw-r--r-- | src/game/BattleGround.cpp | 57 | ||||
-rw-r--r-- | src/game/BattleGround.h | 5 | ||||
-rw-r--r-- | src/game/BattleGroundAV.cpp | 1339 | ||||
-rw-r--r-- | src/game/BattleGroundAV.h | 1526 | ||||
-rw-r--r-- | src/game/Creature.cpp | 2 | ||||
-rw-r--r-- | src/game/Creature.h | 2 | ||||
-rw-r--r-- | src/game/GameObject.cpp | 11 | ||||
-rw-r--r-- | src/game/Language.h | 40 | ||||
-rw-r--r-- | src/game/LootHandler.cpp | 10 | ||||
-rw-r--r-- | src/game/Player.cpp | 302 | ||||
-rw-r--r-- | src/game/QuestHandler.cpp | 8 | ||||
-rw-r--r-- | src/game/SpellEffects.cpp | 24 | ||||
-rw-r--r-- | src/game/Unit.cpp | 19 |
13 files changed, 3166 insertions, 179 deletions
diff --git a/src/game/BattleGround.cpp b/src/game/BattleGround.cpp index 67261b6ff20..772368841d1 100644 --- a/src/game/BattleGround.cpp +++ b/src/game/BattleGround.cpp @@ -362,6 +362,23 @@ void BattleGround::CastSpellOnTeam(uint32 SpellID, uint32 TeamID) } } +void BattleGround::YellToAll(Creature* creature, const char* text, uint32 language) +{ + for(std::map<uint64, BattleGroundPlayer>::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) + { + WorldPacket data(SMSG_MESSAGECHAT, 200); + Player *plr = objmgr.GetPlayer(itr->first); + if(!plr) + { + sLog.outError("BattleGround: Player " I64FMTD " not found!", itr->first); + continue; + } + creature->BuildMonsterChat(&data,CHAT_MSG_MONSTER_YELL,text,language,creature->GetName(),itr->first); + plr->GetSession()->SendPacket(&data); + } +} + + void BattleGround::RewardHonorToTeam(uint32 Honor, uint32 TeamID) { for(std::map<uint64, BattleGroundPlayer>::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) @@ -1218,6 +1235,22 @@ void BattleGround::DoorOpen(uint32 type) } } +GameObject* BattleGround::GetBGObject(uint32 type) +{ + GameObject *obj = HashMapHolder<GameObject>::Find(m_BgObjects[type]); + if(!obj) + sLog.outError("couldn't get gameobject %i",type); + return obj; +} + +Creature* BattleGround::GetBGCreature(uint32 type) +{ + Creature *creature = HashMapHolder<Creature>::Find(m_BgCreatures[type]); + if(!creature) + sLog.outError("couldn't get creature %i",type); + return creature; +} + void BattleGround::SpawnBGObject(uint32 type, uint32 respawntime) { Map * map = MapManager::Instance().FindMap(GetMapId(),GetInstanceID()); @@ -1269,6 +1302,16 @@ Creature* BattleGround::AddCreature(uint32 entry, uint32 type, uint32 teamval, f return NULL; } + CreatureData &data = objmgr.NewOrExistCreatureData(pCreature->GetDBTableGUIDLow()); + + data.id = entry; +// data.mapid = GetMapId(); + data.posX = x; + data.posY = y; + data.posZ = z; + data.orientation = o; + data.spawndist = 15; + pCreature->AIM_Initialize(); //pCreature->SetDungeonDifficulty(0); @@ -1287,6 +1330,7 @@ bool BattleGround::DelCreature(uint32 type) sLog.outError("Can't find creature guid: %u",GUID_LOPART(m_BgCreatures[type])); return false; } + //TODO: only delete creature after not in combat cr->CleanupsBeforeDelete(); cr->AddObjectToRemoveList(); m_BgCreatures[type] = 0; @@ -1474,3 +1518,16 @@ void BattleGround::SetHoliday(bool is_holiday) else m_HonorMode = BG_NORMAL; } + +int32 BattleGround::GetObjectType(uint64 guid) +{ + for(uint32 i = 0;i <= m_BgObjects.size(); i++) + if(m_BgObjects[i] == guid) + return i; + sLog.outError("BattleGround: cheating? a player used a gameobject which isnt supposed to be a usable object!"); + return -1; +} + +void BattleGround::HandleKillUnit(Creature *creature, Player *killer) +{ +} diff --git a/src/game/BattleGround.h b/src/game/BattleGround.h index e53ed1d21e6..c151a207124 100644 --- a/src/game/BattleGround.h +++ b/src/game/BattleGround.h @@ -354,6 +354,8 @@ class BattleGround void StartBattleGround(); + GameObject* GetBGObject(uint32 type); + Creature* GetBGCreature(uint32 type); /* Location */ void SetMapId(uint32 MapID) { m_MapId = MapID; } uint32 GetMapId() const { return m_MapId; } @@ -373,6 +375,7 @@ class BattleGround virtual void FillInitialWorldStates(WorldPacket& /*data*/) {} void SendPacketToTeam(uint32 TeamID, WorldPacket *packet, Player *sender = NULL, bool self = true); void SendPacketToAll(WorldPacket *packet); + void YellToAll(Creature* creature, const char* text, uint32 language); void PlaySoundToTeam(uint32 SoundID, uint32 TeamID); void PlaySoundToAll(uint32 SoundID); void CastSpellOnTeam(uint32 SpellID, uint32 TeamID); @@ -423,6 +426,7 @@ class BattleGround virtual void HandleAreaTrigger(Player* /*Source*/, uint32 /*Trigger*/) {} // must be implemented in BG subclass if need AND call base class generic code virtual void HandleKillPlayer(Player *player, Player *killer); + virtual void HandleKillUnit(Creature* /*unit*/, Player* /*killer*/); /* Battleground events */ /* these functions will return true event is possible, but false if player is bugger */ @@ -452,6 +456,7 @@ class BattleGround bool DelCreature(uint32 type); bool DelObject(uint32 type); bool AddSpiritGuide(uint32 type, float x, float y, float z, float o, uint32 team); + int32 GetObjectType(uint64 guid); void DoorOpen(uint32 type); void DoorClose(uint32 type); diff --git a/src/game/BattleGroundAV.cpp b/src/game/BattleGroundAV.cpp index 1feccaeae38..832a442ce59 100644 --- a/src/game/BattleGroundAV.cpp +++ b/src/game/BattleGroundAV.cpp @@ -18,27 +18,453 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "Object.h" #include "Player.h" #include "BattleGround.h" #include "BattleGroundAV.h" #include "Creature.h" +#include "Chat.h" +#include "Object.h" +#include "ObjectMgr.h" +#include "ObjectAccessor.h" #include "MapManager.h" #include "Language.h" +#include "SpellAuras.h" +#include "Formulas.h" BattleGroundAV::BattleGroundAV() { + m_BgObjects.resize(BG_AV_OBJECT_MAX); + m_BgCreatures.resize(AV_CPLACE_MAX+AV_STATICCPLACE_MAX); } BattleGroundAV::~BattleGroundAV() { +} + +const uint16 BattleGroundAV::GetBonusHonor(uint8 kills) //TODO: move this function to Battleground.cpp (needs to find a way to get m_MaxLevel) +{ + return Trinity::Honor::hk_honor_at_level(m_MaxLevel, kills); +} + +void BattleGroundAV::HandleKillPlayer(Player *player, Player *killer) +{ + if(GetStatus() != STATUS_IN_PROGRESS) + return; + BattleGround::HandleKillPlayer(player, killer); + UpdateScore(player->GetTeam(),-1); +} + +void BattleGroundAV::HandleKillUnit(Creature *unit, Player *killer) +{ + sLog.outDebug("bg_av HandleKillUnit %i",unit->GetEntry()); + if(GetStatus() != STATUS_IN_PROGRESS) + return; + uint32 entry = unit->GetEntry(); + if(entry == BG_AV_CreatureInfo[AV_NPC_A_BOSS][0]) + { + CastSpellOnTeam(23658,HORDE); //this is a spell which finishes a quest where a player has to kill the boss + RewardReputationToTeam(729,BG_AV_REP_BOSS,HORDE); + RewardHonorToTeam(GetBonusHonor(BG_AV_KILL_BOSS),HORDE); + EndBattleGround(HORDE); + } + else if ( entry == BG_AV_CreatureInfo[AV_NPC_H_BOSS][0] ) + { + CastSpellOnTeam(23658,ALLIANCE); //this is a spell which finishes a quest where a player has to kill the boss + RewardReputationToTeam(730,BG_AV_REP_BOSS,ALLIANCE); + RewardHonorToTeam(GetBonusHonor(BG_AV_KILL_BOSS),ALLIANCE); + EndBattleGround(ALLIANCE); + } + else if(entry == BG_AV_CreatureInfo[AV_NPC_A_CAPTAIN][0]) + { + if(!m_CaptainAlive[0]) + { + sLog.outError("Killed a Captain twice, please report this bug, if you haven't done \".respawn\""); + return; + } + m_CaptainAlive[0]=false; + RewardReputationToTeam(729,BG_AV_REP_CAPTAIN,HORDE); + RewardHonorToTeam(GetBonusHonor(BG_AV_KILL_CAPTAIN),HORDE); + UpdateScore(ALLIANCE,(-1)*BG_AV_RES_CAPTAIN); + //spawn destroyed aura + for(uint8 i=0; i<=9; i++) + SpawnBGObject(BG_AV_OBJECT_BURN_BUILDING_ALLIANCE+i,RESPAWN_IMMEDIATELY); + Creature* creature = GetBGCreature(AV_CPLACE_HERALD); + if(creature) + YellToAll(creature,GetTrinityString(LANG_BG_AV_A_CAPTAIN_DEAD),LANG_UNIVERSAL); + + } + else if ( entry == BG_AV_CreatureInfo[AV_NPC_H_CAPTAIN][0] ) + { + if(!m_CaptainAlive[1]) + { + sLog.outError("Killed a Captain twice, please report this bug, if you haven't done \".respawn\""); + return; + } + m_CaptainAlive[1]=false; + RewardReputationToTeam(730,BG_AV_REP_CAPTAIN,ALLIANCE); + RewardHonorToTeam(GetBonusHonor(BG_AV_KILL_CAPTAIN),ALLIANCE); + UpdateScore(HORDE,(-1)*BG_AV_RES_CAPTAIN); + //spawn destroyed aura + for(uint8 i=0; i<=9; i++) + SpawnBGObject(BG_AV_OBJECT_BURN_BUILDING_HORDE+i,RESPAWN_IMMEDIATELY); + Creature* creature = GetBGCreature(AV_CPLACE_HERALD); + if(creature) + YellToAll(creature,GetTrinityString(LANG_BG_AV_H_CAPTAIN_DEAD),LANG_UNIVERSAL); + } + else if ( entry == BG_AV_CreatureInfo[AV_NPC_N_MINE_N_4][0] || entry == BG_AV_CreatureInfo[AV_NPC_N_MINE_A_4][0] || entry == BG_AV_CreatureInfo[AV_NPC_N_MINE_H_4][0]) + ChangeMineOwner(AV_NORTH_MINE,killer->GetTeam()); + else if ( entry == BG_AV_CreatureInfo[AV_NPC_S_MINE_N_4][0] || entry == BG_AV_CreatureInfo[AV_NPC_S_MINE_A_4][0] || entry == BG_AV_CreatureInfo[AV_NPC_S_MINE_H_4][0]) + ChangeMineOwner(AV_SOUTH_MINE,killer->GetTeam()); +} + +void BattleGroundAV::HandleQuestComplete(uint32 questid, Player *player) +{ + if (GetStatus() != STATUS_IN_PROGRESS) + return;//maybe we should log this, cause this must be a cheater or a big bug + uint8 team = GetTeamIndexByTeamId(player->GetTeam()); + //TODO add reputation, events (including quest not available anymore, next quest availabe, go/npc de/spawning)and maybe honor + sLog.outError("BG_AV Quest %i completed",questid); + switch(questid) + { + case AV_QUEST_A_SCRAPS1: + case AV_QUEST_A_SCRAPS2: + case AV_QUEST_H_SCRAPS1: + case AV_QUEST_H_SCRAPS2: + m_Team_QuestStatus[team][0]+=20; + if(m_Team_QuestStatus[team][0] == 500 || m_Team_QuestStatus[team][0] == 1000 || m_Team_QuestStatus[team][0] == 1500) //25,50,75 turn ins + { + sLog.outDebug("BG_AV Quest %i completed starting with unit upgrading..",questid); + for (BG_AV_Nodes i = BG_AV_NODES_FIRSTAID_STATION; i <= BG_AV_NODES_FROSTWOLF_HUT; ++i) + if (m_Nodes[i].Owner == player->GetTeam() && m_Nodes[i].State == POINT_CONTROLED) + { + DePopulateNode(i); + PopulateNode(i); + //maybe this is bad, because it will instantly respawn all creatures on every grave.. + } + } + break; + case AV_QUEST_A_COMMANDER1: + case AV_QUEST_H_COMMANDER1: + m_Team_QuestStatus[team][1]++; + RewardReputationToTeam(team,1,player->GetTeam()); + if(m_Team_QuestStatus[team][1] == 30) + sLog.outDebug("BG_AV Quest %i completed (need to implement some events here",questid); + break; + case AV_QUEST_A_COMMANDER2: + case AV_QUEST_H_COMMANDER2: + m_Team_QuestStatus[team][2]++; + RewardReputationToTeam(team,1,player->GetTeam()); + if(m_Team_QuestStatus[team][2] == 60) + sLog.outDebug("BG_AV Quest %i completed (need to implement some events here",questid); + break; + case AV_QUEST_A_COMMANDER3: + case AV_QUEST_H_COMMANDER3: + m_Team_QuestStatus[team][3]++; + RewardReputationToTeam(team,1,player->GetTeam()); + if(m_Team_QuestStatus[team][1] == 120) + sLog.outDebug("BG_AV Quest %i completed (need to implement some events here",questid); + break; + case AV_QUEST_A_BOSS1: + case AV_QUEST_H_BOSS1: + m_Team_QuestStatus[team][4] += 9; //you can turn in 10 or 1 item.. + case AV_QUEST_A_BOSS2: + case AV_QUEST_H_BOSS2: + m_Team_QuestStatus[team][4]++; + if(m_Team_QuestStatus[team][4] >= 200) + sLog.outDebug("BG_AV Quest %i completed (need to implement some events here",questid); + break; + case AV_QUEST_A_NEAR_MINE: + case AV_QUEST_H_NEAR_MINE: + m_Team_QuestStatus[team][5]++; + if(m_Team_QuestStatus[team][5] == 28) + { + sLog.outDebug("BG_AV Quest %i completed (need to implement some events here",questid); + if(m_Team_QuestStatus[team][6] == 7) + sLog.outDebug("BG_AV Quest %i completed (need to implement some events here - ground assault ready",questid); + } + break; + case AV_QUEST_A_OTHER_MINE: + case AV_QUEST_H_OTHER_MINE: + m_Team_QuestStatus[team][6]++; + if(m_Team_QuestStatus[team][6] == 7) + { + sLog.outDebug("BG_AV Quest %i completed (need to implement some events here",questid); + if(m_Team_QuestStatus[team][5] == 20) + sLog.outDebug("BG_AV Quest %i completed (need to implement some events here - ground assault ready",questid); + } + break; + case AV_QUEST_A_RIDER_HIDE: + case AV_QUEST_H_RIDER_HIDE: + m_Team_QuestStatus[team][7]++; + if(m_Team_QuestStatus[team][7] == 25) + { + sLog.outDebug("BG_AV Quest %i completed (need to implement some events here",questid); + if(m_Team_QuestStatus[team][8] == 25) + sLog.outDebug("BG_AV Quest %i completed (need to implement some events here - rider assault ready",questid); + } + break; + case AV_QUEST_A_RIDER_TAME: + case AV_QUEST_H_RIDER_TAME: + m_Team_QuestStatus[team][8]++; + if(m_Team_QuestStatus[team][8] == 25) + { + sLog.outDebug("BG_AV Quest %i completed (need to implement some events here",questid); + if(m_Team_QuestStatus[team][7] == 25) + sLog.outDebug("BG_AV Quest %i completed (need to implement some events here - rider assault ready",questid); + } + break; + default: + sLog.outDebug("BG_AV Quest %i completed but is not interesting at all",questid); + return; //was no interesting quest at all + break; + } +} + + +void BattleGroundAV::UpdateScore(uint16 team, int16 points ) +{ //note: to remove reinforcementpoints points must be negative, for adding reinforcements points must be positive + assert( team == ALLIANCE || team == HORDE); + uint8 teamindex = GetTeamIndexByTeamId(team); //0=ally 1=horde + m_Team_Scores[teamindex] += points; + + UpdateWorldState(((teamindex==BG_TEAM_HORDE)?AV_Horde_Score:AV_Alliance_Score), m_Team_Scores[teamindex]); + if( points < 0) + { + if( m_Team_Scores[teamindex] < 1) + { + m_Team_Scores[teamindex]=0; + EndBattleGround(((teamindex==BG_TEAM_HORDE)?ALLIANCE:HORDE)); + } + else if(!m_IsInformedNearVictory[teamindex] && m_Team_Scores[teamindex] < SEND_MSG_NEAR_LOSE) + { + SendMessageToAll(GetTrinityString((teamindex==BG_TEAM_HORDE)?LANG_BG_AV_H_NEAR_LOSE:LANG_BG_AV_A_NEAR_LOSE)); + PlaySoundToAll(AV_SOUND_NEAR_VICTORY); + m_IsInformedNearVictory[teamindex] = true; + } + } +} + +Creature* BattleGroundAV::AddAVCreature(uint16 cinfoid, uint16 type ) +{ + uint32 level; + bool isStatic=false; + Creature* creature = NULL; + assert(type <= AV_CPLACE_MAX + AV_STATICCPLACE_MAX); + if(type>=AV_CPLACE_MAX) //static + { + type-=AV_CPLACE_MAX; + cinfoid=int(BG_AV_StaticCreaturePos[type][4]); + creature = AddCreature(BG_AV_StaticCreatureInfo[cinfoid][0],(type+AV_CPLACE_MAX),BG_AV_StaticCreatureInfo[cinfoid][1],BG_AV_StaticCreaturePos[type][0],BG_AV_StaticCreaturePos[type][1],BG_AV_StaticCreaturePos[type][2],BG_AV_StaticCreaturePos[type][3]); + level = ( BG_AV_StaticCreatureInfo[cinfoid][2] == BG_AV_StaticCreatureInfo[cinfoid][3] ) ? BG_AV_StaticCreatureInfo[cinfoid][2] : urand(BG_AV_StaticCreatureInfo[cinfoid][2],BG_AV_StaticCreatureInfo[cinfoid][3]); + isStatic=true; + } + else + { + creature = AddCreature(BG_AV_CreatureInfo[cinfoid][0],type,BG_AV_CreatureInfo[cinfoid][1],BG_AV_CreaturePos[type][0],BG_AV_CreaturePos[type][1],BG_AV_CreaturePos[type][2],BG_AV_CreaturePos[type][3]); + level = ( BG_AV_CreatureInfo[cinfoid][2] == BG_AV_CreatureInfo[cinfoid][3] ) ? BG_AV_CreatureInfo[cinfoid][2] : urand(BG_AV_CreatureInfo[cinfoid][2],BG_AV_CreatureInfo[cinfoid][3]); + } + if(!creature) + return NULL; + if(creature->GetEntry() == BG_AV_CreatureInfo[AV_NPC_A_CAPTAIN][0] || creature->GetEntry() == BG_AV_CreatureInfo[AV_NPC_H_CAPTAIN][0]) + creature->SetRespawnDelay(RESPAWN_ONE_DAY); // TODO: look if this can be done by database + also add this for the wingcommanders + + if((isStatic && cinfoid>=10 && cinfoid<=14) || (!isStatic && ((cinfoid >= AV_NPC_A_GRAVEDEFENSE0 && cinfoid<=AV_NPC_A_GRAVEDEFENSE3) || + (cinfoid>=AV_NPC_H_GRAVEDEFENSE0 && cinfoid<=AV_NPC_H_GRAVEDEFENSE3)))) + { + if(!isStatic && ((cinfoid>=AV_NPC_A_GRAVEDEFENSE0 && cinfoid<=AV_NPC_A_GRAVEDEFENSE3) + || (cinfoid>=AV_NPC_H_GRAVEDEFENSE0 && cinfoid<=AV_NPC_H_GRAVEDEFENSE3))) + { + CreatureData &data = objmgr.NewOrExistCreatureData(creature->GetDBTableGUIDLow()); + data.spawndist = 5; + } + //else spawndist will be 15, so creatures move maximum=10 + creature->SetDefaultMovementType(RANDOM_MOTION_TYPE); + creature->GetMotionMaster()->Initialize(); + creature->setDeathState(JUST_DIED); + creature->Respawn(); + //TODO: find a way to add a motionmaster without killing the creature (i + //just copied this code from a gm-command + } + + if(level != 0) + level += m_MaxLevel-60; //maybe we can do this more generic for custom level-range.. actually it's blizzlike + creature->SetLevel(level); + return creature; } void BattleGroundAV::Update(time_t diff) { BattleGround::Update(diff); + if (GetStatus() == STATUS_WAIT_JOIN && GetPlayersSize()) + { + ModifyStartDelayTime(diff); + + if (!(m_Events & 0x01)) + { + m_Events |= 0x01; + +#ifdef ARENA_PATCH + if(!SetupBattleGround()) + { + EndNow(); + return; + } +#endif + + uint16 i; + sLog.outDebug("Alterac Valley: entering state STATUS_WAIT_JOIN ..."); + // Initial Nodes + for(i = 0; i < BG_AV_OBJECT_MAX; i++) + SpawnBGObject(i, RESPAWN_ONE_DAY); + for(i = BG_AV_OBJECT_FLAG_A_FIRSTAID_STATION; i <= BG_AV_OBJECT_FLAG_A_STONEHEART_GRAVE ; i++){ + SpawnBGObject(BG_AV_OBJECT_AURA_A_FIRSTAID_STATION+3*i,RESPAWN_IMMEDIATELY); + SpawnBGObject(i, RESPAWN_IMMEDIATELY); + } + for(i = BG_AV_OBJECT_FLAG_A_DUNBALDAR_SOUTH; i <= BG_AV_OBJECT_FLAG_A_STONEHEART_BUNKER ; i++) + SpawnBGObject(i, RESPAWN_IMMEDIATELY); + for(i = BG_AV_OBJECT_FLAG_H_ICEBLOOD_GRAVE; i <= BG_AV_OBJECT_FLAG_H_FROSTWOLF_WTOWER ; i++){ + SpawnBGObject(i, RESPAWN_IMMEDIATELY); + if(i<=BG_AV_OBJECT_FLAG_H_FROSTWOLF_HUT) + SpawnBGObject(BG_AV_OBJECT_AURA_H_FIRSTAID_STATION+3*GetNodeThroughObject(i),RESPAWN_IMMEDIATELY); + } + for(i = BG_AV_OBJECT_TFLAG_A_DUNBALDAR_SOUTH; i <= BG_AV_OBJECT_TFLAG_A_STONEHEART_BUNKER; i+=2) + { + SpawnBGObject(i, RESPAWN_IMMEDIATELY); //flag + SpawnBGObject(i+16, RESPAWN_IMMEDIATELY); //aura + } + for(i = BG_AV_OBJECT_TFLAG_H_ICEBLOOD_TOWER; i <= BG_AV_OBJECT_TFLAG_H_FROSTWOLF_WTOWER; i+=2) + { + SpawnBGObject(i, RESPAWN_IMMEDIATELY); //flag + SpawnBGObject(i+16, RESPAWN_IMMEDIATELY); //aura + } + //snowfall and the doors + for(i = BG_AV_OBJECT_FLAG_N_SNOWFALL_GRAVE; i <= BG_AV_OBJECT_DOOR_A; i++) + SpawnBGObject(i, RESPAWN_IMMEDIATELY); + SpawnBGObject(BG_AV_OBJECT_AURA_N_SNOWFALL_GRAVE,RESPAWN_IMMEDIATELY); + + //creatures + sLog.outDebug("BG_AV start poputlating nodes"); + for(BG_AV_Nodes i= BG_AV_NODES_FIRSTAID_STATION; i < BG_AV_NODES_MAX; ++i ) + { + if(m_Nodes[i].Owner) + PopulateNode(i); + } + //all creatures which don't get despawned through the script are static + sLog.outDebug("BG_AV: start spawning static creatures"); + for(i=0; i < AV_STATICCPLACE_MAX; i++ ) + AddAVCreature(0,i+AV_CPLACE_MAX); + //mainspiritguides: + sLog.outDebug("BG_AV: start spawning spiritguides creatures"); + AddSpiritGuide(7, BG_AV_CreaturePos[7][0], BG_AV_CreaturePos[7][1], BG_AV_CreaturePos[7][2], BG_AV_CreaturePos[7][3], ALLIANCE); + AddSpiritGuide(8, BG_AV_CreaturePos[8][0], BG_AV_CreaturePos[8][1], BG_AV_CreaturePos[8][2], BG_AV_CreaturePos[8][3], HORDE); + //spawn the marshals (those who get deleted, if a tower gets destroyed) + sLog.outDebug("BG_AV: start spawning marshal creatures"); + for(i=AV_NPC_A_MARSHAL_SOUTH; i<= AV_NPC_H_MARSHAL_WTOWER; i++) + AddAVCreature(i,AV_CPLACE_A_MARSHAL_SOUTH+(i-AV_NPC_A_MARSHAL_SOUTH)); + + AddAVCreature(AV_NPC_HERALD,AV_CPLACE_HERALD); + DoorClose(BG_AV_OBJECT_DOOR_A); + DoorClose(BG_AV_OBJECT_DOOR_H); + + SetStartDelayTime(START_DELAY0); + } + // After 1 minute, warning is signalled + else if (GetStartDelayTime() <= START_DELAY1 && !(m_Events & 0x04)) + { + m_Events |= 0x04; + SendMessageToAll(GetTrinityString(LANG_BG_AV_ONEMINTOSTART)); + } + // After 1,5 minute, warning is signalled + else if (GetStartDelayTime() <= START_DELAY2 && !(m_Events & 0x08)) + { + m_Events |= 0x08; + SendMessageToAll(GetTrinityString(LANG_BG_AV_HALFMINTOSTART)); + } + // After 2 minutes, gates OPEN ! x) + else if (GetStartDelayTime() <= 0 && !(m_Events & 0x10)) + { + UpdateWorldState(AV_SHOW_H_SCORE, 1); + UpdateWorldState(AV_SHOW_A_SCORE, 1); + m_Events |= 0x10; + + SendMessageToAll(GetTrinityString(LANG_BG_AV_STARTED)); + PlaySoundToAll(SOUND_BG_START); + SetStatus(STATUS_IN_PROGRESS); + + sLog.outDebug("BG_AV: start spawning mine stuff"); + for(uint16 i= BG_AV_OBJECT_MINE_SUPPLY_N_MIN; i<=BG_AV_OBJECT_MINE_SUPPLY_N_MAX;i++) + SpawnBGObject(i,RESPAWN_IMMEDIATELY); + for(uint16 i= BG_AV_OBJECT_MINE_SUPPLY_S_MIN; i<=BG_AV_OBJECT_MINE_SUPPLY_S_MAX;i++) + SpawnBGObject(i,RESPAWN_IMMEDIATELY); + for(uint8 mine = AV_NORTH_MINE; mine <= AV_SOUTH_MINE; mine++) //mine population + ChangeMineOwner(mine, AV_NEUTRAL_TEAM,true); + DoorOpen(BG_AV_OBJECT_DOOR_H); + DoorOpen(BG_AV_OBJECT_DOOR_A); + + + for(BattleGroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr) + if(Player* plr = objmgr.GetPlayer(itr->first)) + plr->RemoveAurasDueToSpell(SPELL_PREPARATION); + } + } + else if(GetStatus() == STATUS_IN_PROGRESS) + { + for(uint8 i=0; i<=1;i++)//0=alliance, 1=horde + { + if(!m_CaptainAlive[i]) + continue; + if(m_CaptainBuffTimer[i] > diff) + m_CaptainBuffTimer[i] -= diff; + else + { + if(i==0) + { + CastSpellOnTeam(AV_BUFF_A_CAPTAIN,ALLIANCE); + Creature* creature = GetBGCreature(AV_CPLACE_MAX + 61); + if(creature) + YellToAll(creature,LANG_BG_AV_A_CAPTAIN_BUFF,LANG_COMMON); + } + else + { + CastSpellOnTeam(AV_BUFF_H_CAPTAIN,HORDE); + Creature* creature = GetBGCreature(AV_CPLACE_MAX + 59); //TODO: make the captains a dynamic creature + if(creature) + YellToAll(creature,LANG_BG_AV_H_CAPTAIN_BUFF,LANG_ORCISH); + } + m_CaptainBuffTimer[i] = 120000 + urand(0,4)* 60000; //as far as i could see, the buff is randomly so i make 2minutes (thats the duration of the buff itself) + 0-4minutes TODO get the right times + } + } + //add points from mine owning, and look if he neutral team wanrts to reclaim the mine + m_Mine_Timer -=diff; + for(uint8 mine=0; mine <2; mine++) + { + if(m_Mine_Owner[mine] == ALLIANCE || m_Mine_Owner[mine] == HORDE) + { + if( m_Mine_Timer <= 0) + UpdateScore(m_Mine_Owner[mine],1); + + if(m_Mine_Reclaim_Timer[mine] > diff) + m_Mine_Reclaim_Timer[mine] -= diff; + else{ //we don't need to set this timer to 0 cause this codepart wont get called when this thing is 0 + ChangeMineOwner(mine,AV_NEUTRAL_TEAM); + } + } + } + if( m_Mine_Timer <= 0) + m_Mine_Timer=AV_MINE_TICK_TIMER; //this is at the end, cause we need to update both mines + + //looks for all timers of the nodes and destroy the building (for graveyards the building wont get destroyed, it goes just to the other team + for(BG_AV_Nodes i = BG_AV_NODES_FIRSTAID_STATION; i < BG_AV_NODES_MAX; ++i) + if(m_Nodes[i].State == POINT_ASSAULTED) //maybe remove this + { + if(m_Nodes[i].Timer > diff) + m_Nodes[i].Timer -= diff; + else + EventPlayerDestroyedPoint( i); + } + } } void BattleGroundAV::AddPlayer(Player *plr) @@ -46,15 +472,66 @@ void BattleGroundAV::AddPlayer(Player *plr) BattleGround::AddPlayer(plr); //create score and add it to map, default values are set in constructor BattleGroundAVScore* sc = new BattleGroundAVScore; - m_PlayerScores[plr->GetGUID()] = sc; + if(m_MaxLevel==0) + m_MaxLevel=(plr->getLevel()%10 == 0)? plr->getLevel() : (plr->getLevel()-(plr->getLevel()%10))+10; //TODO: just look at the code \^_^/ --but queue-info should provide this information.. + } -void BattleGroundAV::RemovePlayer(Player* /*plr*/,uint64 /*guid*/) +void BattleGroundAV::EndBattleGround(uint32 winner) { + //calculate bonuskills for both teams: + //first towers: + uint8 kills[2]={0,0}; //0=ally 1=horde + uint8 rep[2]={0,0}; //0=ally 1=horde + for(BG_AV_Nodes i = BG_AV_NODES_DUNBALDAR_SOUTH; i <= BG_AV_NODES_FROSTWOLF_WTOWER; ++i) + { + if(m_Nodes[i].State == POINT_CONTROLED) + { + if(m_Nodes[i].Owner == ALLIANCE) + { + rep[0] += BG_AV_REP_SURVIVING_TOWER; + kills[0] += BG_AV_KILL_SURVIVING_TOWER; + } + else + { + rep[0] += BG_AV_KILL_SURVIVING_TOWER; + kills[1] += BG_AV_KILL_SURVIVING_TOWER; + } + } + } + for(int i=0; i<=1; i++) //0=ally 1=horde + { + if(m_CaptainAlive[i]) + { + kills[i] += BG_AV_KILL_SURVIVING_CAPTAIN; + rep[i] += BG_AV_REP_SURVIVING_CAPTAIN; + } + if(rep[i] != 0) + RewardReputationToTeam((i == 0)?730:729,rep[i],(i == 0)?ALLIANCE:HORDE); + if(kills[i] != 0) + RewardHonorToTeam(GetBonusHonor(kills[i]),(i == 0)?ALLIANCE:HORDE); + } + + //TODO add enterevademode for all attacking creatures + BattleGround::EndBattleGround(winner); +} + +void BattleGroundAV::RemovePlayer(Player* plr,uint64 /*guid*/) +{ + if(!plr) + { + sLog.outError("bg_AV no player at remove"); + return; + } + //TODO search more buffs + plr->RemoveAurasDueToSpell(AV_BUFF_ARMOR); + plr->RemoveAurasDueToSpell(AV_BUFF_A_CAPTAIN); + plr->RemoveAurasDueToSpell(AV_BUFF_H_CAPTAIN); } + void BattleGroundAV::HandleAreaTrigger(Player *Source, uint32 Trigger) { // this is wrong way to implement these things. On official it done by gameobject spell cast. @@ -65,18 +542,29 @@ void BattleGroundAV::HandleAreaTrigger(Player *Source, uint32 Trigger) switch(Trigger) { case 95: - case 2606: case 2608: + if(Source->GetTeam() != ALLIANCE) + Source->GetSession()->SendAreaTriggerMessage("Only The Alliance can use that portal"); + else + Source->LeaveBattleground(); + break; + case 2606: + if(Source->GetTeam() != HORDE) + Source->GetSession()->SendAreaTriggerMessage("Only The Horde can use that portal"); + else + Source->LeaveBattleground(); + break; case 3326: case 3327: case 3328: case 3329: case 3330: case 3331: + //Source->Unmount(); break; default: - sLog.outError("WARNING: Unhandled AreaTrigger in Battleground: %u", Trigger); - Source->GetSession()->SendAreaTriggerMessage("Warning: Unhandled AreaTrigger in Battleground: %u", Trigger); + sLog.outDebug("WARNING: Unhandled AreaTrigger in Battleground: %u", Trigger); +// Source->GetSession()->SendAreaTriggerMessage("Warning: Unhandled AreaTrigger in Battleground: %u", Trigger); break; } @@ -120,3 +608,842 @@ void BattleGroundAV::UpdatePlayerScore(Player* Source, uint32 type, uint32 value break; } } + + + +void BattleGroundAV::EventPlayerDestroyedPoint(BG_AV_Nodes node) +{ + + uint32 object = GetObjectThroughNode(node); + sLog.outDebug("bg_av: player destroyed point node %i object %i",node,object); + + //despawn banner + SpawnBGObject(object, RESPAWN_ONE_DAY); + DestroyNode(node); + UpdateNodeWorldState(node); + + uint32 owner = m_Nodes[node].Owner; + if( IsTower(node) ) + { + uint8 tmp = node-BG_AV_NODES_DUNBALDAR_SOUTH; + //despawn marshal + if(m_BgCreatures[AV_CPLACE_A_MARSHAL_SOUTH + tmp]) + DelCreature(AV_CPLACE_A_MARSHAL_SOUTH + tmp); + else + sLog.outError("BG_AV: playerdestroyedpoint: marshal %i doesn't exist",AV_CPLACE_A_MARSHAL_SOUTH + tmp); + //spawn destroyed aura + for(uint8 i=0; i<=9; i++) + SpawnBGObject(BG_AV_OBJECT_BURN_DUNBALDAR_SOUTH + i + (tmp * 10),RESPAWN_IMMEDIATELY); + + UpdateScore((owner == ALLIANCE) ? HORDE : ALLIANCE, (-1)*BG_AV_RES_TOWER); + RewardReputationToTeam((owner == ALLIANCE)?730:729,BG_AV_REP_TOWER,owner); + RewardHonorToTeam(GetBonusHonor(BG_AV_KILL_TOWER),owner); + + SpawnBGObject(BG_AV_OBJECT_TAURA_A_DUNBALDAR_SOUTH+GetTeamIndexByTeamId(owner)+(2*tmp),RESPAWN_ONE_DAY); + SpawnBGObject(BG_AV_OBJECT_TFLAG_A_DUNBALDAR_SOUTH+GetTeamIndexByTeamId(owner)+(2*tmp),RESPAWN_ONE_DAY); + } + else + { + if( owner == ALLIANCE ) + SpawnBGObject(object-11, RESPAWN_IMMEDIATELY); + else + SpawnBGObject(object+11, RESPAWN_IMMEDIATELY); + SpawnBGObject(BG_AV_OBJECT_AURA_N_FIRSTAID_STATION+3*node,RESPAWN_ONE_DAY); + SpawnBGObject(BG_AV_OBJECT_AURA_A_FIRSTAID_STATION+GetTeamIndexByTeamId(owner)+3*node,RESPAWN_IMMEDIATELY); + PopulateNode(node); + if(node == BG_AV_NODES_SNOWFALL_GRAVE) //snowfall eyecandy + { + for(uint8 i = 0; i < 4; i++) + { + SpawnBGObject(((owner==ALLIANCE)?BG_AV_OBJECT_SNOW_EYECANDY_PA : BG_AV_OBJECT_SNOW_EYECANDY_PH)+i,RESPAWN_ONE_DAY); + SpawnBGObject(((owner==ALLIANCE)?BG_AV_OBJECT_SNOW_EYECANDY_A : BG_AV_OBJECT_SNOW_EYECANDY_H )+i,RESPAWN_IMMEDIATELY); + } + } + } + //send a nice message to all :) + char buf[256]; + if(IsTower(node)) + sprintf(buf, GetTrinityString(LANG_BG_AV_TOWER_TAKEN) , GetNodeName(node),( owner == ALLIANCE ) ? GetTrinityString(LANG_BG_AV_ALLY) : GetTrinityString(LANG_BG_AV_HORDE) ); + else + sprintf(buf, GetTrinityString(LANG_BG_AV_GRAVE_TAKEN) , GetNodeName(node),( owner == ALLIANCE ) ? GetTrinityString(LANG_BG_AV_ALLY) :GetTrinityString(LANG_BG_AV_HORDE) ); + + Creature* creature = GetBGCreature(AV_CPLACE_HERALD); + if(creature) + YellToAll(creature,buf,LANG_UNIVERSAL); +} + +void BattleGroundAV::ChangeMineOwner(uint8 mine, uint32 team, bool initial) +{ //mine=0 northmine mine=1 southmin +//changing the owner results in setting respawntim to infinite for current creatures, spawning new mine owners creatures and changing the chest-objects so that the current owning team can use them + assert(mine == AV_NORTH_MINE || mine == AV_SOUTH_MINE); + if(team != ALLIANCE && team != HORDE) + team = AV_NEUTRAL_TEAM; + else + PlaySoundToAll((team==ALLIANCE)?AV_SOUND_ALLIANCE_GOOD:AV_SOUND_HORDE_GOOD); + + if(m_Mine_Owner[mine] == team && !initial) + return; + m_Mine_PrevOwner[mine] = m_Mine_Owner[mine]; + m_Mine_Owner[mine] = team; + + if(!initial) + { + sLog.outDebug("bg_av depopulating mine %i (0=north,1=south)",mine); + if(mine==AV_SOUTH_MINE) + for(uint16 i=AV_CPLACE_MINE_S_S_MIN; i <= AV_CPLACE_MINE_S_S_MAX; i++) + if( m_BgCreatures[i] ) + DelCreature(i); //TODO just set the respawntime to 999999 + for(uint16 i=((mine==AV_NORTH_MINE)?AV_CPLACE_MINE_N_1_MIN:AV_CPLACE_MINE_S_1_MIN); i <= ((mine==AV_NORTH_MINE)?AV_CPLACE_MINE_N_3:AV_CPLACE_MINE_S_3); i++) + if( m_BgCreatures[i] ) + DelCreature(i); //TODO here also + } + SendMineWorldStates(mine); + + sLog.outDebug("bg_av populating mine %i (0=north,1=south)",mine); + uint16 miner; + //also neutral team exists.. after a big time, the neutral team tries to conquer the mine + if(mine==AV_NORTH_MINE) + { + if(team == ALLIANCE) + miner = AV_NPC_N_MINE_A_1; + else if (team == HORDE) + miner = AV_NPC_N_MINE_H_1; + else + miner = AV_NPC_N_MINE_N_1; + } + else + { + uint16 cinfo; + if(team == ALLIANCE) + miner = AV_NPC_S_MINE_A_1; + else if (team == HORDE) + miner = AV_NPC_S_MINE_H_1; + else + miner = AV_NPC_S_MINE_N_1; + //vermin + sLog.outDebug("spawning vermin"); + if(team == ALLIANCE) + cinfo = AV_NPC_S_MINE_A_3; + else if (team == HORDE) + cinfo = AV_NPC_S_MINE_H_3; + else + cinfo = AV_NPC_S_MINE_N_S; + for(uint16 i=AV_CPLACE_MINE_S_S_MIN; i <= AV_CPLACE_MINE_S_S_MAX; i++) + AddAVCreature(cinfo,i); + } + for(uint16 i=( (mine==AV_NORTH_MINE)?AV_CPLACE_MINE_N_1_MIN:AV_CPLACE_MINE_S_1_MIN ); i <= ((mine==AV_NORTH_MINE)?AV_CPLACE_MINE_N_1_MAX:AV_CPLACE_MINE_S_1_MAX); i++) + AddAVCreature(miner,i); + //the next chooses randomly between 2 cretures + for(uint16 i=((mine==AV_NORTH_MINE)?AV_CPLACE_MINE_N_2_MIN:AV_CPLACE_MINE_S_2_MIN); i <= ((mine==AV_NORTH_MINE)?AV_CPLACE_MINE_N_2_MAX:AV_CPLACE_MINE_S_2_MAX); i++) + AddAVCreature(miner+(urand(1,2)),i); + AddAVCreature(miner+3,(mine==AV_NORTH_MINE)?AV_CPLACE_MINE_N_3:AV_CPLACE_MINE_S_3); + //because the gameobjects in this mine have changed, update all surrounding players: +// for(uint16 i = ((mine==AV_NORTH_MINE)?BG_AV_OBJECT_MINE_SUPPLY_N_MIN:BG_AV_OBJECT_MINE_SUPPLY_N_MIN); i <= ((mine==AV_NORTH_MINE)?BG_AV_OBJECT_MINE_SUPPLY_N_MAX:BG_AV_OBJECT_MINE_SUPPLY_N_MAX); i++) +// { + //TODO: add gameobject-update code +// } + if(team == ALLIANCE || team == HORDE) + { + m_Mine_Reclaim_Timer[mine]=AV_MINE_RECLAIM_TIMER; + char buf[256]; + sprintf(buf, GetTrinityString(LANG_BG_AV_MINE_TAKEN), GetTrinityString(( mine == AV_NORTH_MINE ) ? LANG_BG_AV_MINE_NORTH : LANG_BG_AV_MINE_SOUTH), ( team == ALLIANCE ) ? GetTrinityString(LANG_BG_AV_ALLY) : GetTrinityString(LANG_BG_AV_HORDE)); + Creature* creature = GetBGCreature(AV_CPLACE_HERALD); + if(creature) + YellToAll(creature,buf,LANG_UNIVERSAL); + } + else + { + if(mine==AV_SOUTH_MINE) //i think this gets called all the time + { + Creature* creature = GetBGCreature(AV_CPLACE_MINE_S_3); + YellToAll(creature,LANG_BG_AV_S_MINE_BOSS_CLAIMS,LANG_UNIVERSAL); + } + } + return; +} + +bool BattleGroundAV::PlayerCanDoMineQuest(int32 GOId,uint32 team) +{ + if(GOId == BG_AV_OBJECTID_MINE_N) + return (m_Mine_Owner[AV_NORTH_MINE]==team); + if(GOId == BG_AV_OBJECTID_MINE_S) + return (m_Mine_Owner[AV_SOUTH_MINE]==team); + return true; //cause it's no mine'object it is ok if this is true +} + +void BattleGroundAV::PopulateNode(BG_AV_Nodes node) +{ + uint32 owner = m_Nodes[node].Owner; + assert(owner); + + uint32 c_place = AV_CPLACE_DEFENSE_STORM_AID + ( 4 * node ); + uint32 creatureid; + if(IsTower(node)) + creatureid=(owner==ALLIANCE)?AV_NPC_A_TOWERDEFENSE:AV_NPC_H_TOWERDEFENSE; + else + { + uint8 team2 = GetTeamIndexByTeamId(owner); + if (m_Team_QuestStatus[team2][0] < 500 ) + creatureid = ( owner == ALLIANCE )? AV_NPC_A_GRAVEDEFENSE0 : AV_NPC_H_GRAVEDEFENSE0; + else if ( m_Team_QuestStatus[team2][0] < 1000 ) + creatureid = ( owner == ALLIANCE )? AV_NPC_A_GRAVEDEFENSE1 : AV_NPC_H_GRAVEDEFENSE1; + else if ( m_Team_QuestStatus[team2][0] < 1500 ) + creatureid = ( owner == ALLIANCE )? AV_NPC_A_GRAVEDEFENSE2 : AV_NPC_H_GRAVEDEFENSE2; + else + creatureid = ( owner == ALLIANCE )? AV_NPC_A_GRAVEDEFENSE3 : AV_NPC_H_GRAVEDEFENSE3; + //spiritguide + if( m_BgCreatures[node] ) + DelCreature(node); + if( !AddSpiritGuide(node, BG_AV_CreaturePos[node][0], BG_AV_CreaturePos[node][1], BG_AV_CreaturePos[node][2], BG_AV_CreaturePos[node][3], owner)) + sLog.outError("AV: couldn't spawn spiritguide at node %i",node); + + } + for(uint8 i=0; i<4; i++) + { + Creature* cr = AddAVCreature(creatureid,c_place+i); + } +} +void BattleGroundAV::DePopulateNode(BG_AV_Nodes node) +{ + uint32 c_place = AV_CPLACE_DEFENSE_STORM_AID + ( 4 * node ); + for(uint8 i=0; i<4; i++) + if( m_BgCreatures[c_place+i] ) + DelCreature(c_place+i); + //spiritguide + if( !IsTower(node) && m_BgCreatures[node] ) + DelCreature(node); +} + + +const BG_AV_Nodes BattleGroundAV::GetNodeThroughObject(uint32 object) +{ + sLog.outDebug("bg_AV getnodethroughobject %i",object); + if( object <= BG_AV_OBJECT_FLAG_A_STONEHEART_BUNKER ) + return BG_AV_Nodes(object); + if( object <= BG_AV_OBJECT_FLAG_C_A_FROSTWOLF_HUT ) + return BG_AV_Nodes(object - 11); + if( object <= BG_AV_OBJECT_FLAG_C_A_FROSTWOLF_WTOWER ) + return BG_AV_Nodes(object - 7); + if( object <= BG_AV_OBJECT_FLAG_C_H_STONEHEART_BUNKER ) + return BG_AV_Nodes(object -22); + if( object <= BG_AV_OBJECT_FLAG_H_FROSTWOLF_HUT ) + return BG_AV_Nodes(object - 33); + if( object <= BG_AV_OBJECT_FLAG_H_FROSTWOLF_WTOWER ) + return BG_AV_Nodes(object - 29); + if( object == BG_AV_OBJECT_FLAG_N_SNOWFALL_GRAVE ) + return BG_AV_NODES_SNOWFALL_GRAVE; + sLog.outError("BattleGroundAV: ERROR! GetPlace got a wrong object :("); + assert(false); + return BG_AV_Nodes(0); +} + +const uint32 BattleGroundAV::GetObjectThroughNode(BG_AV_Nodes node) +{ //this function is the counterpart to GetNodeThroughObject() + sLog.outDebug("bg_AV GetObjectThroughNode %i",node); + if( m_Nodes[node].Owner == ALLIANCE ) + { + if( m_Nodes[node].State == POINT_ASSAULTED ) + { + if( node <= BG_AV_NODES_FROSTWOLF_HUT ) + return node+11; + if( node >= BG_AV_NODES_ICEBLOOD_TOWER && node <= BG_AV_NODES_FROSTWOLF_WTOWER) + return node+7; + } + else if ( m_Nodes[node].State == POINT_CONTROLED ) + if( node <= BG_AV_NODES_STONEHEART_BUNKER ) + return node; + } + else if ( m_Nodes[node].Owner == HORDE ) + { + if( m_Nodes[node].State == POINT_ASSAULTED ) + if( node <= BG_AV_NODES_STONEHEART_BUNKER ) + return node+22; + else if ( m_Nodes[node].State == POINT_CONTROLED ) + { + if( node <= BG_AV_NODES_FROSTWOLF_HUT ) + return node+33; + if( node >= BG_AV_NODES_ICEBLOOD_TOWER && node <= BG_AV_NODES_FROSTWOLF_WTOWER) + return node+29; + } + } + else if ( m_Nodes[node].Owner == AV_NEUTRAL_TEAM ) + return BG_AV_OBJECT_FLAG_N_SNOWFALL_GRAVE; + sLog.outError("BattleGroundAV: Error! GetPlaceNode couldn't resolve node %i",node); + assert(false); + return 0; +} + + +//called when using banner + +void BattleGroundAV::EventPlayerClickedOnFlag(Player *source, GameObject* target_obj) +{ + if(GetStatus() != STATUS_IN_PROGRESS) + return; + int32 object = GetObjectType(target_obj->GetGUID()); + sLog.outDebug("BG_AV using gameobject %i with type %i",target_obj->GetEntry(),object); + if(object < 0) + return; + switch(target_obj->GetEntry()) + { + case BG_AV_OBJECTID_BANNER_A: + case BG_AV_OBJECTID_BANNER_A_B: + case BG_AV_OBJECTID_BANNER_H: + case BG_AV_OBJECTID_BANNER_H_B: + case BG_AV_OBJECTID_BANNER_SNOWFALL_N: + EventPlayerAssaultsPoint(source, object); + break; + case BG_AV_OBJECTID_BANNER_CONT_A: + case BG_AV_OBJECTID_BANNER_CONT_A_B: + case BG_AV_OBJECTID_BANNER_CONT_H: + case BG_AV_OBJECTID_BANNER_CONT_H_B: + EventPlayerDefendsPoint(source, object); + break; + default: + break; + } +} + +void BattleGroundAV::EventPlayerDefendsPoint(Player* player, uint32 object) +{ + assert(GetStatus() == STATUS_IN_PROGRESS); + BG_AV_Nodes node = GetNodeThroughObject(object); + + uint32 owner = m_Nodes[node].Owner; //maybe should name it prevowner + uint32 team = player->GetTeam(); + + if(owner == player->GetTeam() || m_Nodes[node].State != POINT_ASSAULTED) + return; + if(m_Nodes[node].TotalOwner == AV_NEUTRAL_TEAM) + { //until snowfall doesn't belong to anyone it is better handled in assault-code + assert(node == BG_AV_NODES_SNOWFALL_GRAVE); //currently the only neutral grave + EventPlayerAssaultsPoint(player,object); + return; + } + sLog.outDebug("player defends point object: %i node: %i",object,node); + if(m_Nodes[node].PrevOwner != team) + { + sLog.outError("BG_AV: player defends point which doesn't belong to his team %i",node); + return; + } + + + //spawn new go :) + if(m_Nodes[node].Owner == ALLIANCE) + SpawnBGObject(object+22, RESPAWN_IMMEDIATELY); //spawn horde banner + else + SpawnBGObject(object-22, RESPAWN_IMMEDIATELY); //spawn alliance banner + + if(!IsTower(node)) + { + SpawnBGObject(BG_AV_OBJECT_AURA_N_FIRSTAID_STATION+3*node,RESPAWN_ONE_DAY); + SpawnBGObject(BG_AV_OBJECT_AURA_A_FIRSTAID_STATION+GetTeamIndexByTeamId(team)+3*node,RESPAWN_IMMEDIATELY); + } + // despawn old go + SpawnBGObject(object, RESPAWN_ONE_DAY); + + DefendNode(node,team); + PopulateNode(node); + UpdateNodeWorldState(node); + + if(IsTower(node)) + { + //spawn big flag+aura on top of tower + SpawnBGObject(BG_AV_OBJECT_TAURA_A_DUNBALDAR_SOUTH+(2*(node-BG_AV_NODES_DUNBALDAR_SOUTH)),(team == ALLIANCE)? RESPAWN_IMMEDIATELY : RESPAWN_ONE_DAY); + SpawnBGObject(BG_AV_OBJECT_TAURA_H_DUNBALDAR_SOUTH+(2*(node-BG_AV_NODES_DUNBALDAR_SOUTH)),(team == HORDE)? RESPAWN_IMMEDIATELY : RESPAWN_ONE_DAY); + SpawnBGObject(BG_AV_OBJECT_TFLAG_A_DUNBALDAR_SOUTH+(2*(node-BG_AV_NODES_DUNBALDAR_SOUTH)),(team == ALLIANCE)? RESPAWN_IMMEDIATELY : RESPAWN_ONE_DAY); + SpawnBGObject(BG_AV_OBJECT_TFLAG_H_DUNBALDAR_SOUTH+(2*(node-BG_AV_NODES_DUNBALDAR_SOUTH)),(team == HORDE)? RESPAWN_IMMEDIATELY : RESPAWN_ONE_DAY); + } + else if(node == BG_AV_NODES_SNOWFALL_GRAVE) //snowfall eyecandy + { + for(uint8 i = 0; i < 4; i++) + { + SpawnBGObject(((owner==ALLIANCE)?BG_AV_OBJECT_SNOW_EYECANDY_PA : BG_AV_OBJECT_SNOW_EYECANDY_PH)+i,RESPAWN_ONE_DAY); + SpawnBGObject(((team==ALLIANCE)?BG_AV_OBJECT_SNOW_EYECANDY_A : BG_AV_OBJECT_SNOW_EYECANDY_H)+i,RESPAWN_IMMEDIATELY); + } + } + //send a nice message to all :) + char buf[256]; + sprintf(buf, GetTrinityString(( IsTower(node) ) ? LANG_BG_AV_TOWER_DEFENDED : LANG_BG_AV_GRAVE_DEFENDED), GetNodeName(node),( team == ALLIANCE ) ? GetTrinityString(LANG_BG_AV_ALLY) : GetTrinityString(LANG_BG_AV_HORDE)); + Creature* creature = GetBGCreature(AV_CPLACE_HERALD); + if(creature) + YellToAll(creature,buf,LANG_UNIVERSAL); + //update the statistic for the defending player + UpdatePlayerScore(player, ( IsTower(node) ) ? SCORE_TOWERS_DEFENDED : SCORE_GRAVEYARDS_DEFENDED, 1); + if(IsTower(node)) + PlaySoundToAll(AV_SOUND_BOTH_TOWER_DEFEND); + else + PlaySoundToAll((team==ALLIANCE)?AV_SOUND_ALLIANCE_GOOD:AV_SOUND_HORDE_GOOD); +} + +void BattleGroundAV::EventPlayerAssaultsPoint(Player* player, uint32 object) +{ + assert(GetStatus() == STATUS_IN_PROGRESS); + + BG_AV_Nodes node = GetNodeThroughObject(object); + uint32 owner = m_Nodes[node].Owner; //maybe name it prevowner + uint32 team = player->GetTeam(); + sLog.outDebug("bg_av: player assaults point object %i node %i",object,node); + if(owner == team || team == m_Nodes[node].TotalOwner) + return; //surely a gm used this object + + + if(node == BG_AV_NODES_SNOWFALL_GRAVE) //snowfall is a bit special in capping + it gets eyecandy stuff + { + if(object == BG_AV_OBJECT_FLAG_N_SNOWFALL_GRAVE) //initial capping + { + assert(owner == AV_NEUTRAL_TEAM && m_Nodes[node].TotalOwner == AV_NEUTRAL_TEAM); + if( team == ALLIANCE ) + SpawnBGObject(BG_AV_OBJECT_FLAG_C_A_SNOWFALL_GRAVE, RESPAWN_IMMEDIATELY); + else + SpawnBGObject(BG_AV_OBJECT_FLAG_C_H_SNOWFALL_GRAVE, RESPAWN_IMMEDIATELY); + SpawnBGObject(BG_AV_OBJECT_AURA_N_FIRSTAID_STATION+3*node,RESPAWN_IMMEDIATELY); //neutral aura spawn + } + else if(m_Nodes[node].TotalOwner == AV_NEUTRAL_TEAM) //recapping, when no team owns this node realy + { + assert(m_Nodes[node].State != POINT_CONTROLED); + if(team == ALLIANCE) + SpawnBGObject(object-11, RESPAWN_IMMEDIATELY); + else + SpawnBGObject(object+11, RESPAWN_IMMEDIATELY); + } + //eyecandy + uint32 spawn,despawn; + if(team == ALLIANCE) + { + despawn = ( m_Nodes[node].State == POINT_ASSAULTED )?BG_AV_OBJECT_SNOW_EYECANDY_PH : BG_AV_OBJECT_SNOW_EYECANDY_H; + spawn = BG_AV_OBJECT_SNOW_EYECANDY_PA; + } + else + { + despawn = ( m_Nodes[node].State == POINT_ASSAULTED )?BG_AV_OBJECT_SNOW_EYECANDY_PA : BG_AV_OBJECT_SNOW_EYECANDY_A; + spawn = BG_AV_OBJECT_SNOW_EYECANDY_PH; + } + for(uint8 i = 0; i < 4; i++) + { + SpawnBGObject(despawn+i,RESPAWN_ONE_DAY); + SpawnBGObject(spawn+i,RESPAWN_IMMEDIATELY); + } + } + + //if snowfall gots capped it can be handled like all other graveyards + if( m_Nodes[node].TotalOwner != AV_NEUTRAL_TEAM) + { + assert(m_Nodes[node].Owner != AV_NEUTRAL_TEAM); + if(team == ALLIANCE) + SpawnBGObject(object-22, RESPAWN_IMMEDIATELY); + else + SpawnBGObject(object+22, RESPAWN_IMMEDIATELY); + if(IsTower(node)) + { //spawning/despawning of bigflag+aura + SpawnBGObject(BG_AV_OBJECT_TAURA_A_DUNBALDAR_SOUTH+(2*(node-BG_AV_NODES_DUNBALDAR_SOUTH)),(team==ALLIANCE)? RESPAWN_IMMEDIATELY : RESPAWN_ONE_DAY); + SpawnBGObject(BG_AV_OBJECT_TAURA_H_DUNBALDAR_SOUTH+(2*(node-BG_AV_NODES_DUNBALDAR_SOUTH)),(team==HORDE)? RESPAWN_IMMEDIATELY : RESPAWN_ONE_DAY); + SpawnBGObject(BG_AV_OBJECT_TFLAG_A_DUNBALDAR_SOUTH+(2*(node-BG_AV_NODES_DUNBALDAR_SOUTH)),(team==ALLIANCE)? RESPAWN_IMMEDIATELY : RESPAWN_ONE_DAY); + SpawnBGObject(BG_AV_OBJECT_TFLAG_H_DUNBALDAR_SOUTH+(2*(node-BG_AV_NODES_DUNBALDAR_SOUTH)),(team==HORDE)? RESPAWN_IMMEDIATELY : RESPAWN_ONE_DAY); + } + else + { + //spawning/despawning of aura + SpawnBGObject(BG_AV_OBJECT_AURA_N_FIRSTAID_STATION+3*node,RESPAWN_IMMEDIATELY); //neutral aura spawn + SpawnBGObject(BG_AV_OBJECT_AURA_A_FIRSTAID_STATION+GetTeamIndexByTeamId(owner)+3*node,RESPAWN_ONE_DAY); //teeamaura despawn + // Those who are waiting to resurrect at this object are taken to the closest own object's graveyard + std::vector<uint64> ghost_list = m_ReviveQueue[m_BgCreatures[node]]; + if( !ghost_list.empty() ) + { + Player *plr; + WorldSafeLocsEntry const *ClosestGrave = NULL; + for (std::vector<uint64>::iterator itr = ghost_list.begin(); itr != ghost_list.end(); ++itr) + { + plr = objmgr.GetPlayer(*ghost_list.begin()); + if( !plr ) + continue; + if(!ClosestGrave) + ClosestGrave = GetClosestGraveYard(plr->GetPositionX(), plr->GetPositionY(), plr->GetPositionZ(), team); + else + plr->TeleportTo(GetMapId(), ClosestGrave->x, ClosestGrave->y, ClosestGrave->z, plr->GetOrientation()); + } + m_ReviveQueue[m_BgCreatures[node]].clear(); + } + } + DePopulateNode(node); + } + + SpawnBGObject(object, RESPAWN_ONE_DAY); //delete old banner + AssaultNode(node,team); + UpdateNodeWorldState(node); + + //send a nice message to all :) + char buf[256]; + sprintf(buf, ( IsTower(node) ) ? GetTrinityString(LANG_BG_AV_TOWER_ASSAULTED) : GetTrinityString(LANG_BG_AV_GRAVE_ASSAULTED), GetNodeName(node), ( team == ALLIANCE ) ? GetTrinityString(LANG_BG_AV_ALLY) : GetTrinityString(LANG_BG_AV_HORDE )); + Creature* creature = GetBGCreature(AV_CPLACE_HERALD); + if(creature) + YellToAll(creature,buf,LANG_UNIVERSAL); + //update the statistic for the assaulting player + UpdatePlayerScore(player, ( IsTower(node) ) ? SCORE_TOWERS_ASSAULTED : SCORE_GRAVEYARDS_ASSAULTED, 1); + PlaySoundToAll((team==ALLIANCE)?AV_SOUND_ALLIANCE_ASSAULTS:AV_SOUND_HORDE_ASSAULTS); +} + +void BattleGroundAV::FillInitialWorldStates(WorldPacket& data) +{ + bool stateok; + //graveyards + for (uint8 i = BG_AV_NODES_FIRSTAID_STATION; i <= BG_AV_NODES_FROSTWOLF_HUT; i++) + { + for (uint8 j =1; j <= 3; j+=2) + {//j=1=assaulted j=3=controled + stateok = (m_Nodes[i].State == j); + data << uint32(BG_AV_NodeWorldStates[i][GetWorldStateType(j,ALLIANCE)]) << uint32((m_Nodes[i].Owner == ALLIANCE && stateok)?1:0); + data << uint32(BG_AV_NodeWorldStates[i][GetWorldStateType(j,HORDE)]) << uint32((m_Nodes[i].Owner == HORDE && stateok)?1:0); + } + } + + //towers + for (uint8 i = BG_AV_NODES_DUNBALDAR_SOUTH; i <= BG_AV_NODES_MAX; i++) + for (uint8 j =1; j <= 3; j+=2) + {//j=1=assaulted j=3=controled //i dont have j=2=destroyed cause destroyed is the same like enemy-team controll + stateok = (m_Nodes[i].State == j || (m_Nodes[i].State == POINT_DESTROYED && j==3)); + data << uint32(BG_AV_NodeWorldStates[i][GetWorldStateType(j,ALLIANCE)]) << uint32((m_Nodes[i].Owner == ALLIANCE && stateok)?1:0); + data << uint32(BG_AV_NodeWorldStates[i][GetWorldStateType(j,HORDE)]) << uint32((m_Nodes[i].Owner == HORDE && stateok)?1:0); + } + if(m_Nodes[BG_AV_NODES_SNOWFALL_GRAVE].Owner == AV_NEUTRAL_TEAM) //cause neutral teams aren't handled generic + data << uint32(AV_SNOWFALL_N) << uint32(1); + data << uint32(AV_Alliance_Score) << uint32(m_Team_Scores[0]); + data << uint32(AV_Horde_Score) << uint32(m_Team_Scores[1]); + if(GetStatus() == STATUS_IN_PROGRESS){ //only if game started the teamscores are displayed + data << uint32(AV_SHOW_A_SCORE) << uint32(1); + data << uint32(AV_SHOW_H_SCORE) << uint32(1); + } + else + { + data << uint32(AV_SHOW_A_SCORE) << uint32(0); + data << uint32(AV_SHOW_H_SCORE) << uint32(0); + } + SendMineWorldStates(AV_NORTH_MINE); + SendMineWorldStates(AV_SOUTH_MINE); +} + +const uint8 BattleGroundAV::GetWorldStateType(uint8 state, uint16 team) //this is used for node worldstates and returns values which fit good into the worldstatesarray +{ + //neutral stuff cant get handled (currently its only snowfall) + assert(team != AV_NEUTRAL_TEAM); +//a_c a_a h_c h_a the positions in worldstate-array + if(team == ALLIANCE) + { + if(state==POINT_CONTROLED || state==POINT_DESTROYED) + return 0; + if(state==POINT_ASSAULTED) + return 1; + } + if(team == HORDE) + { + if(state==POINT_DESTROYED || state==POINT_CONTROLED) + return 2; + if(state==POINT_ASSAULTED) + return 3; + } + sLog.outError("BG_AV: should update a strange worldstate state:%i team:%i",state,team); + return 5; //this will crash the game, but i want to know if something is wrong here +} + +void BattleGroundAV::UpdateNodeWorldState(BG_AV_Nodes node) +{ + UpdateWorldState(BG_AV_NodeWorldStates[node][GetWorldStateType(m_Nodes[node].State,m_Nodes[node].Owner)],1); + if(m_Nodes[node].PrevOwner == AV_NEUTRAL_TEAM) //currently only snowfall is supported as neutral node (i don't want to make an extra row (neutral states) in worldstatesarray just for one node + UpdateWorldState(AV_SNOWFALL_N,0); + else + UpdateWorldState(BG_AV_NodeWorldStates[node][GetWorldStateType(m_Nodes[node].PrevState,m_Nodes[node].PrevOwner)],0); +} + +void BattleGroundAV::SendMineWorldStates(uint32 mine) +{ + assert(mine == AV_NORTH_MINE || mine==AV_SOUTH_MINE); +// currently i'm sure, that this works (: +// assert(m_Mine_PrevOwner[mine] == ALLIANCE || m_Mine_PrevOwner[mine] == HORDE || m_Mine_PrevOwner[mine] == AV_NEUTRAL_TEAM); +// assert(m_Mine_Owner[mine] == ALLIANCE || m_Mine_Owner[mine] == HORDE || m_Mine_Owner[mine] == AV_NEUTRAL_TEAM); + + uint8 owner,prevowner,mine2; //those variables are needed to access the right worldstate in the BG_AV_MineWorldStates array + mine2 = (mine==AV_NORTH_MINE)?0:1; + if(m_Mine_PrevOwner[mine] == ALLIANCE) + prevowner = 0; + else if(m_Mine_PrevOwner[mine] == HORDE) + prevowner = 2; + else + prevowner = 1; + if(m_Mine_Owner[mine] == ALLIANCE) + owner = 0; + else if(m_Mine_Owner[mine] == HORDE) + owner = 2; + else + owner = 1; + + UpdateWorldState(BG_AV_MineWorldStates[mine2][owner],1); + if( prevowner != owner) + UpdateWorldState(BG_AV_MineWorldStates[mine2][prevowner],0); +} + + +WorldSafeLocsEntry const* BattleGroundAV::GetClosestGraveYard(float x, float y, float z, uint32 team) +{ + WorldSafeLocsEntry const* good_entry = NULL; + if( GetStatus() == STATUS_IN_PROGRESS) + { + // Is there any occupied node for this team? + float mindist = 9999999.0f; + for (uint8 i = BG_AV_NODES_FIRSTAID_STATION; i <= BG_AV_NODES_FROSTWOLF_HUT; ++i) + { + if (m_Nodes[i].Owner != team || m_Nodes[i].State != POINT_CONTROLED) + continue; + WorldSafeLocsEntry const*entry = sWorldSafeLocsStore.LookupEntry( BG_AV_GraveyardIds[i] ); + if( !entry ) + continue; + float dist = (entry->x - x)*(entry->x - x)+(entry->y - y)*(entry->y - y); + if( mindist > dist ) + { + mindist = dist; + good_entry = entry; + } + } + } + // If not, place ghost on starting location + if( !good_entry ) + good_entry = sWorldSafeLocsStore.LookupEntry( BG_AV_GraveyardIds[GetTeamIndexByTeamId(team)+7] ); + + return good_entry; +} + + +bool BattleGroundAV::SetupBattleGround() +{ + // Create starting objects + if( + // alliance gates + !AddObject(BG_AV_OBJECT_DOOR_A, BG_AV_OBJECTID_GATE_A, BG_AV_DoorPositons[0][0],BG_AV_DoorPositons[0][1],BG_AV_DoorPositons[0][2],BG_AV_DoorPositons[0][3],0,0,sin(BG_AV_DoorPositons[0][3]/2),cos(BG_AV_DoorPositons[0][3]/2),RESPAWN_IMMEDIATELY) + // horde gates + || !AddObject(BG_AV_OBJECT_DOOR_H, BG_AV_OBJECTID_GATE_H, BG_AV_DoorPositons[1][0],BG_AV_DoorPositons[1][1],BG_AV_DoorPositons[1][2],BG_AV_DoorPositons[1][3],0,0,sin(BG_AV_DoorPositons[1][3]/2),cos(BG_AV_DoorPositons[1][3]/2),RESPAWN_IMMEDIATELY)) + { + sLog.outErrorDb("BatteGroundAV: Failed to spawn some object BattleGround not created!1"); + return false; + } + +//spawn node-objects + for (uint8 i = BG_AV_NODES_FIRSTAID_STATION ; i < BG_AV_NODES_MAX; ++i) + { + if( i <= BG_AV_NODES_FROSTWOLF_HUT ) + { + if( !AddObject(i,BG_AV_OBJECTID_BANNER_A_B,BG_AV_ObjectPos[i][0],BG_AV_ObjectPos[i][1],BG_AV_ObjectPos[i][2],BG_AV_ObjectPos[i][3], 0, 0, sin(BG_AV_ObjectPos[i][3]/2), cos(BG_AV_ObjectPos[i][3]/2),RESPAWN_ONE_DAY) + || !AddObject(i+11,BG_AV_OBJECTID_BANNER_CONT_A_B,BG_AV_ObjectPos[i][0],BG_AV_ObjectPos[i][1],BG_AV_ObjectPos[i][2],BG_AV_ObjectPos[i][3], 0, 0, sin(BG_AV_ObjectPos[i][3]/2), cos(BG_AV_ObjectPos[i][3]/2),RESPAWN_ONE_DAY) + || !AddObject(i+33,BG_AV_OBJECTID_BANNER_H_B,BG_AV_ObjectPos[i][0],BG_AV_ObjectPos[i][1],BG_AV_ObjectPos[i][2],BG_AV_ObjectPos[i][3], 0, 0, sin(BG_AV_ObjectPos[i][3]/2), cos(BG_AV_ObjectPos[i][3]/2),RESPAWN_ONE_DAY) + || !AddObject(i+22,BG_AV_OBJECTID_BANNER_CONT_H_B,BG_AV_ObjectPos[i][0],BG_AV_ObjectPos[i][1],BG_AV_ObjectPos[i][2],BG_AV_ObjectPos[i][3], 0, 0, sin(BG_AV_ObjectPos[i][3]/2), cos(BG_AV_ObjectPos[i][3]/2),RESPAWN_ONE_DAY) + //aura + || !AddObject(BG_AV_OBJECT_AURA_N_FIRSTAID_STATION+i*3,BG_AV_OBJECTID_AURA_N,BG_AV_ObjectPos[i][0],BG_AV_ObjectPos[i][1],BG_AV_ObjectPos[i][2],BG_AV_ObjectPos[i][3], 0, 0, sin(BG_AV_ObjectPos[i][3]/2), cos(BG_AV_ObjectPos[i][3]/2),RESPAWN_ONE_DAY) + || !AddObject(BG_AV_OBJECT_AURA_A_FIRSTAID_STATION+i*3,BG_AV_OBJECTID_AURA_A,BG_AV_ObjectPos[i][0],BG_AV_ObjectPos[i][1],BG_AV_ObjectPos[i][2],BG_AV_ObjectPos[i][3], 0, 0, sin(BG_AV_ObjectPos[i][3]/2), cos(BG_AV_ObjectPos[i][3]/2),RESPAWN_ONE_DAY) + || !AddObject(BG_AV_OBJECT_AURA_H_FIRSTAID_STATION+i*3,BG_AV_OBJECTID_AURA_H,BG_AV_ObjectPos[i][0],BG_AV_ObjectPos[i][1],BG_AV_ObjectPos[i][2],BG_AV_ObjectPos[i][3], 0, 0, sin(BG_AV_ObjectPos[i][3]/2), cos(BG_AV_ObjectPos[i][3]/2),RESPAWN_ONE_DAY)) + { + sLog.outError("BatteGroundAV: Failed to spawn some object BattleGround not created!2"); + return false; + } + } + else //towers + { + if( i <= BG_AV_NODES_STONEHEART_BUNKER ) //alliance towers + { + if( !AddObject(i,BG_AV_OBJECTID_BANNER_A,BG_AV_ObjectPos[i][0],BG_AV_ObjectPos[i][1],BG_AV_ObjectPos[i][2],BG_AV_ObjectPos[i][3], 0, 0, sin(BG_AV_ObjectPos[i][3]/2), cos(BG_AV_ObjectPos[i][3]/2),RESPAWN_ONE_DAY) + || !AddObject(i+22,BG_AV_OBJECTID_BANNER_CONT_H,BG_AV_ObjectPos[i][0],BG_AV_ObjectPos[i][1],BG_AV_ObjectPos[i][2],BG_AV_ObjectPos[i][3], 0, 0, sin(BG_AV_ObjectPos[i][3]/2), cos(BG_AV_ObjectPos[i][3]/2),RESPAWN_ONE_DAY) + || !AddObject(BG_AV_OBJECT_TAURA_A_DUNBALDAR_SOUTH+(2*(i-BG_AV_NODES_DUNBALDAR_SOUTH)),BG_AV_OBJECTID_AURA_A,BG_AV_ObjectPos[i+8][0],BG_AV_ObjectPos[i+8][1],BG_AV_ObjectPos[i+8][2],BG_AV_ObjectPos[i+8][3], 0, 0, sin(BG_AV_ObjectPos[i+8][3]/2), cos(BG_AV_ObjectPos[i+8][3]/2),RESPAWN_ONE_DAY) + || !AddObject(BG_AV_OBJECT_TAURA_H_DUNBALDAR_SOUTH+(2*(i-BG_AV_NODES_DUNBALDAR_SOUTH)),BG_AV_OBJECTID_AURA_N,BG_AV_ObjectPos[i+8][0],BG_AV_ObjectPos[i+8][1],BG_AV_ObjectPos[i+8][2],BG_AV_ObjectPos[i+8][3], 0, 0, sin(BG_AV_ObjectPos[i+8][3]/2), cos(BG_AV_ObjectPos[i+8][3]/2),RESPAWN_ONE_DAY) + || !AddObject(BG_AV_OBJECT_TFLAG_A_DUNBALDAR_SOUTH+(2*(i-BG_AV_NODES_DUNBALDAR_SOUTH)),BG_AV_OBJECTID_TOWER_BANNER_A,BG_AV_ObjectPos[i+8][0],BG_AV_ObjectPos[i+8][1],BG_AV_ObjectPos[i+8][2],BG_AV_ObjectPos[i+8][3], 0, 0, sin(BG_AV_ObjectPos[i+8][3]/2), cos(BG_AV_ObjectPos[i+8][3]/2),RESPAWN_ONE_DAY) + || !AddObject(BG_AV_OBJECT_TFLAG_H_DUNBALDAR_SOUTH+(2*(i-BG_AV_NODES_DUNBALDAR_SOUTH)),BG_AV_OBJECTID_TOWER_BANNER_PH,BG_AV_ObjectPos[i+8][0],BG_AV_ObjectPos[i+8][1],BG_AV_ObjectPos[i+8][2],BG_AV_ObjectPos[i+8][3], 0, 0, sin(BG_AV_ObjectPos[i+8][3]/2), cos(BG_AV_ObjectPos[i+8][3]/2),RESPAWN_ONE_DAY)) + { + sLog.outError("BatteGroundAV: Failed to spawn some object BattleGround not created!3"); + return false; + } + } + else //horde towers + { + if( !AddObject(i+7,BG_AV_OBJECTID_BANNER_CONT_A,BG_AV_ObjectPos[i][0],BG_AV_ObjectPos[i][1],BG_AV_ObjectPos[i][2],BG_AV_ObjectPos[i][3], 0, 0, sin(BG_AV_ObjectPos[i][3]/2), cos(BG_AV_ObjectPos[i][3]/2),RESPAWN_ONE_DAY) + || !AddObject(i+29,BG_AV_OBJECTID_BANNER_H,BG_AV_ObjectPos[i][0],BG_AV_ObjectPos[i][1],BG_AV_ObjectPos[i][2],BG_AV_ObjectPos[i][3], 0, 0, sin(BG_AV_ObjectPos[i][3]/2), cos(BG_AV_ObjectPos[i][3]/2),RESPAWN_ONE_DAY) + || !AddObject(BG_AV_OBJECT_TAURA_A_DUNBALDAR_SOUTH+(2*(i-BG_AV_NODES_DUNBALDAR_SOUTH)),BG_AV_OBJECTID_AURA_N,BG_AV_ObjectPos[i+8][0],BG_AV_ObjectPos[i+8][1],BG_AV_ObjectPos[i+8][2],BG_AV_ObjectPos[i+8][3], 0, 0, sin(BG_AV_ObjectPos[i+8][3]/2), cos(BG_AV_ObjectPos[i+8][3]/2),RESPAWN_ONE_DAY) + || !AddObject(BG_AV_OBJECT_TAURA_H_DUNBALDAR_SOUTH+(2*(i-BG_AV_NODES_DUNBALDAR_SOUTH)),BG_AV_OBJECTID_AURA_H,BG_AV_ObjectPos[i+8][0],BG_AV_ObjectPos[i+8][1],BG_AV_ObjectPos[i+8][2],BG_AV_ObjectPos[i+8][3], 0, 0, sin(BG_AV_ObjectPos[i+8][3]/2), cos(BG_AV_ObjectPos[i+8][3]/2),RESPAWN_ONE_DAY) + || !AddObject(BG_AV_OBJECT_TFLAG_A_DUNBALDAR_SOUTH+(2*(i-BG_AV_NODES_DUNBALDAR_SOUTH)),BG_AV_OBJECTID_TOWER_BANNER_PA,BG_AV_ObjectPos[i+8][0],BG_AV_ObjectPos[i+8][1],BG_AV_ObjectPos[i+8][2],BG_AV_ObjectPos[i+8][3], 0, 0, sin(BG_AV_ObjectPos[i+8][3]/2), cos(BG_AV_ObjectPos[i+8][3]/2),RESPAWN_ONE_DAY) + || !AddObject(BG_AV_OBJECT_TFLAG_H_DUNBALDAR_SOUTH+(2*(i-BG_AV_NODES_DUNBALDAR_SOUTH)),BG_AV_OBJECTID_TOWER_BANNER_H,BG_AV_ObjectPos[i+8][0],BG_AV_ObjectPos[i+8][1],BG_AV_ObjectPos[i+8][2],BG_AV_ObjectPos[i+8][3], 0, 0, sin(BG_AV_ObjectPos[i+8][3]/2), cos(BG_AV_ObjectPos[i+8][3]/2),RESPAWN_ONE_DAY)) + { + sLog.outError("BatteGroundAV: Failed to spawn some object BattleGround not created!4"); + return false; + } + } + for(uint8 j=0; j<=9; j++) //burning aura + { + if(!AddObject(BG_AV_OBJECT_BURN_DUNBALDAR_SOUTH+((i-BG_AV_NODES_DUNBALDAR_SOUTH)*10)+j,BG_AV_OBJECTID_FIRE,BG_AV_ObjectPos[AV_OPLACE_BURN_DUNBALDAR_SOUTH+((i-BG_AV_NODES_DUNBALDAR_SOUTH)*10)+j][0],BG_AV_ObjectPos[AV_OPLACE_BURN_DUNBALDAR_SOUTH+((i-BG_AV_NODES_DUNBALDAR_SOUTH)*10)+j][1],BG_AV_ObjectPos[AV_OPLACE_BURN_DUNBALDAR_SOUTH+((i-BG_AV_NODES_DUNBALDAR_SOUTH)*10)+j][2],BG_AV_ObjectPos[AV_OPLACE_BURN_DUNBALDAR_SOUTH+((i-BG_AV_NODES_DUNBALDAR_SOUTH)*10)+j][3], 0, 0, sin(BG_AV_ObjectPos[AV_OPLACE_BURN_DUNBALDAR_SOUTH+((i-BG_AV_NODES_DUNBALDAR_SOUTH)*10)+j][3]/2), cos(BG_AV_ObjectPos[AV_OPLACE_BURN_DUNBALDAR_SOUTH+((i-BG_AV_NODES_DUNBALDAR_SOUTH)*10)+j][3]/2),RESPAWN_ONE_DAY)) + { + sLog.outError("BatteGroundAV: Failed to spawn some object BattleGround not created!5.%i",i); + return false; + } + } + } + } + for(uint8 i=0;i<2;i++) //burning aura for buildings + { + for(uint8 j=0; j<=9; j++) + { + if(j<5) + { + if(!AddObject(BG_AV_OBJECT_BURN_BUILDING_ALLIANCE+(i*10)+j,BG_AV_OBJECTID_SMOKE,BG_AV_ObjectPos[AV_OPLACE_BURN_BUILDING_A+(i*10)+j][0],BG_AV_ObjectPos[AV_OPLACE_BURN_BUILDING_A+(i*10)+j][1],BG_AV_ObjectPos[AV_OPLACE_BURN_BUILDING_A+(i*10)+j][2],BG_AV_ObjectPos[AV_OPLACE_BURN_BUILDING_A+(i*10)+j][3], 0, 0, sin(BG_AV_ObjectPos[AV_OPLACE_BURN_BUILDING_A+(i*10)+j][3]/2), cos(BG_AV_ObjectPos[AV_OPLACE_BURN_BUILDING_A+(i*10)+j][3]/2),RESPAWN_ONE_DAY)) + { + sLog.outError("BatteGroundAV: Failed to spawn some object BattleGround not created!6.%i",i); + return false; + } + } + else + { + if(!AddObject(BG_AV_OBJECT_BURN_BUILDING_ALLIANCE+(i*10)+j,BG_AV_OBJECTID_FIRE,BG_AV_ObjectPos[AV_OPLACE_BURN_BUILDING_A+(i*10)+j][0],BG_AV_ObjectPos[AV_OPLACE_BURN_BUILDING_A+(i*10)+j][1],BG_AV_ObjectPos[AV_OPLACE_BURN_BUILDING_A+(i*10)+j][2],BG_AV_ObjectPos[AV_OPLACE_BURN_BUILDING_A+(i*10)+j][3], 0, 0, sin(BG_AV_ObjectPos[AV_OPLACE_BURN_BUILDING_A+(i*10)+j][3]/2), cos(BG_AV_ObjectPos[AV_OPLACE_BURN_BUILDING_A+(i*10)+j][3]/2),RESPAWN_ONE_DAY)) + { + sLog.outError("BatteGroundAV: Failed to spawn some object BattleGround not created!7.%i",i); + return false; + } + } + } + } + for(uint16 i= 0; i<=(BG_AV_OBJECT_MINE_SUPPLY_N_MAX-BG_AV_OBJECT_MINE_SUPPLY_N_MIN);i++) + { + if(!AddObject(BG_AV_OBJECT_MINE_SUPPLY_N_MIN+i,BG_AV_OBJECTID_MINE_N,BG_AV_ObjectPos[AV_OPLACE_MINE_SUPPLY_N_MIN+i][0],BG_AV_ObjectPos[AV_OPLACE_MINE_SUPPLY_N_MIN+i][1],BG_AV_ObjectPos[AV_OPLACE_MINE_SUPPLY_N_MIN+i][2],BG_AV_ObjectPos[AV_OPLACE_MINE_SUPPLY_N_MIN+i][3], 0, 0, sin(BG_AV_ObjectPos[AV_OPLACE_MINE_SUPPLY_N_MIN+i][3]/2), cos(BG_AV_ObjectPos[AV_OPLACE_MINE_SUPPLY_N_MIN+i][3]/2),RESPAWN_ONE_DAY)) + { + sLog.outError("BatteGroundAV: Failed to spawn some mine supplies BattleGround not created!7.5.%i",i); + return false; + } + } + for(uint16 i= 0 ; i<=(BG_AV_OBJECT_MINE_SUPPLY_S_MAX-BG_AV_OBJECT_MINE_SUPPLY_S_MIN);i++) + { + if(!AddObject(BG_AV_OBJECT_MINE_SUPPLY_S_MIN+i,BG_AV_OBJECTID_MINE_S,BG_AV_ObjectPos[AV_OPLACE_MINE_SUPPLY_S_MIN+i][0],BG_AV_ObjectPos[AV_OPLACE_MINE_SUPPLY_S_MIN+i][1],BG_AV_ObjectPos[AV_OPLACE_MINE_SUPPLY_S_MIN+i][2],BG_AV_ObjectPos[AV_OPLACE_MINE_SUPPLY_S_MIN+i][3], 0, 0, sin(BG_AV_ObjectPos[AV_OPLACE_MINE_SUPPLY_S_MIN+i][3]/2), cos(BG_AV_ObjectPos[AV_OPLACE_MINE_SUPPLY_S_MIN+i][3]/2),RESPAWN_ONE_DAY)) + { + sLog.outError("BatteGroundAV: Failed to spawn some mine supplies BattleGround not created!7.6.%i",i); + return false; + } + } + + if(!AddObject(BG_AV_OBJECT_FLAG_N_SNOWFALL_GRAVE, BG_AV_OBJECTID_BANNER_SNOWFALL_N ,BG_AV_ObjectPos[BG_AV_NODES_SNOWFALL_GRAVE][0],BG_AV_ObjectPos[BG_AV_NODES_SNOWFALL_GRAVE][1],BG_AV_ObjectPos[BG_AV_NODES_SNOWFALL_GRAVE][2],BG_AV_ObjectPos[BG_AV_NODES_SNOWFALL_GRAVE][3],0,0,sin(BG_AV_ObjectPos[BG_AV_NODES_SNOWFALL_GRAVE][3]/2), cos(BG_AV_ObjectPos[BG_AV_NODES_SNOWFALL_GRAVE][3]/2), RESPAWN_ONE_DAY)) + { + sLog.outError("BatteGroundAV: Failed to spawn some object BattleGround not created!8"); + return false; + } + for(uint8 i = 0; i < 4; i++) + { + if(!AddObject(BG_AV_OBJECT_SNOW_EYECANDY_A+i, BG_AV_OBJECTID_SNOWFALL_CANDY_A ,BG_AV_ObjectPos[AV_OPLACE_SNOW_1+i][0],BG_AV_ObjectPos[AV_OPLACE_SNOW_1+i][1],BG_AV_ObjectPos[AV_OPLACE_SNOW_1+i][2],BG_AV_ObjectPos[AV_OPLACE_SNOW_1+i][3],0,0,sin(BG_AV_ObjectPos[AV_OPLACE_SNOW_1+i][3]/2), cos(BG_AV_ObjectPos[AV_OPLACE_SNOW_1+i][3]/2), RESPAWN_ONE_DAY) + || !AddObject(BG_AV_OBJECT_SNOW_EYECANDY_PA+i, BG_AV_OBJECTID_SNOWFALL_CANDY_PA ,BG_AV_ObjectPos[AV_OPLACE_SNOW_1+i][0],BG_AV_ObjectPos[AV_OPLACE_SNOW_1+i][1],BG_AV_ObjectPos[AV_OPLACE_SNOW_1+i][2],BG_AV_ObjectPos[AV_OPLACE_SNOW_1+i][3],0,0,sin(BG_AV_ObjectPos[AV_OPLACE_SNOW_1+i][3]/2), cos(BG_AV_ObjectPos[AV_OPLACE_SNOW_1+i][3]/2), RESPAWN_ONE_DAY) + || !AddObject(BG_AV_OBJECT_SNOW_EYECANDY_H+i, BG_AV_OBJECTID_SNOWFALL_CANDY_H ,BG_AV_ObjectPos[AV_OPLACE_SNOW_1+i][0],BG_AV_ObjectPos[AV_OPLACE_SNOW_1+i][1],BG_AV_ObjectPos[AV_OPLACE_SNOW_1+i][2],BG_AV_ObjectPos[AV_OPLACE_SNOW_1+i][3],0,0,sin(BG_AV_ObjectPos[AV_OPLACE_SNOW_1+i][3]/2), cos(BG_AV_ObjectPos[AV_OPLACE_SNOW_1+i][3]/2), RESPAWN_ONE_DAY) + || !AddObject(BG_AV_OBJECT_SNOW_EYECANDY_PH+i, BG_AV_OBJECTID_SNOWFALL_CANDY_PH ,BG_AV_ObjectPos[AV_OPLACE_SNOW_1+i][0],BG_AV_ObjectPos[AV_OPLACE_SNOW_1+i][1],BG_AV_ObjectPos[AV_OPLACE_SNOW_1+i][2],BG_AV_ObjectPos[AV_OPLACE_SNOW_1+i][3],0,0,sin(BG_AV_ObjectPos[AV_OPLACE_SNOW_1+i][3]/2), cos(BG_AV_ObjectPos[AV_OPLACE_SNOW_1+i][3]/2), RESPAWN_ONE_DAY)) + { + sLog.outError("BatteGroundAV: Failed to spawn some object BattleGround not created!9.%i",i); + return false; + } + } + return true; +} + +const char* BattleGroundAV::GetNodeName(BG_AV_Nodes node) +{ + switch (node) + { + case BG_AV_NODES_FIRSTAID_STATION: return GetTrinityString(LANG_BG_AV_NODE_GRAVE_STORM_AID); + case BG_AV_NODES_DUNBALDAR_SOUTH: return GetTrinityString(LANG_BG_AV_NODE_TOWER_DUN_S); + case BG_AV_NODES_DUNBALDAR_NORTH: return GetTrinityString(LANG_BG_AV_NODE_TOWER_DUN_N); + case BG_AV_NODES_STORMPIKE_GRAVE: return GetTrinityString(LANG_BG_AV_NODE_GRAVE_STORMPIKE); + case BG_AV_NODES_ICEWING_BUNKER: return GetTrinityString(LANG_BG_AV_NODE_TOWER_ICEWING); + case BG_AV_NODES_STONEHEART_GRAVE: return GetTrinityString(LANG_BG_AV_NODE_GRAVE_STONE); + case BG_AV_NODES_STONEHEART_BUNKER: return GetTrinityString(LANG_BG_AV_NODE_TOWER_STONE); + case BG_AV_NODES_SNOWFALL_GRAVE: return GetTrinityString(LANG_BG_AV_NODE_GRAVE_SNOW); + case BG_AV_NODES_ICEBLOOD_TOWER: return GetTrinityString(LANG_BG_AV_NODE_TOWER_ICE); + case BG_AV_NODES_ICEBLOOD_GRAVE: return GetTrinityString(LANG_BG_AV_NODE_GRAVE_ICE); + case BG_AV_NODES_TOWER_POINT: return GetTrinityString(LANG_BG_AV_NODE_TOWER_POINT); + case BG_AV_NODES_FROSTWOLF_GRAVE: return GetTrinityString(LANG_BG_AV_NODE_GRAVE_FROST); + case BG_AV_NODES_FROSTWOLF_ETOWER: return GetTrinityString(LANG_BG_AV_NODE_TOWER_FROST_E); + case BG_AV_NODES_FROSTWOLF_WTOWER: return GetTrinityString(LANG_BG_AV_NODE_TOWER_FROST_W); + case BG_AV_NODES_FROSTWOLF_HUT: return GetTrinityString(LANG_BG_AV_NODE_GRAVE_FROST_HUT); + default: + { + sLog.outError("tried to get name for node %u%",node); + return "Unknown"; + break; + } + } +} + +void BattleGroundAV::AssaultNode(BG_AV_Nodes node, uint16 team) +{ + assert(m_Nodes[node].TotalOwner != team); + assert(m_Nodes[node].Owner != team); + assert(m_Nodes[node].State != POINT_DESTROYED); + assert(m_Nodes[node].State != POINT_ASSAULTED || !m_Nodes[node].TotalOwner ); //only assault an assaulted node if no totalowner exists + //the timer gets another time, if the previous owner was 0==Neutral + m_Nodes[node].Timer = (m_Nodes[node].PrevOwner)? BG_AV_CAPTIME : BG_AV_SNOWFALL_FIRSTCAP; + m_Nodes[node].PrevOwner = m_Nodes[node].Owner; + m_Nodes[node].Owner = team; + m_Nodes[node].PrevState = m_Nodes[node].State; + m_Nodes[node].State = POINT_ASSAULTED; +} + +void BattleGroundAV::DestroyNode(BG_AV_Nodes node) +{ + assert(m_Nodes[node].State == POINT_ASSAULTED); + + m_Nodes[node].TotalOwner = m_Nodes[node].Owner; + m_Nodes[node].PrevOwner = m_Nodes[node].Owner; + m_Nodes[node].PrevState = m_Nodes[node].State; + m_Nodes[node].State = (m_Nodes[node].Tower)? POINT_DESTROYED : POINT_CONTROLED; + m_Nodes[node].Timer = 0; +} + +void BattleGroundAV::InitNode(BG_AV_Nodes node, uint16 team, bool tower) +{ + m_Nodes[node].TotalOwner = team; + m_Nodes[node].Owner = team; + m_Nodes[node].PrevOwner = 0; + m_Nodes[node].State = POINT_CONTROLED; + m_Nodes[node].PrevState = m_Nodes[node].State; + m_Nodes[node].State = POINT_CONTROLED; + m_Nodes[node].Timer = 0; + m_Nodes[node].Tower = tower; +} + +void BattleGroundAV::DefendNode(BG_AV_Nodes node, uint16 team) +{ + assert(m_Nodes[node].TotalOwner == team); + assert(m_Nodes[node].Owner != team); + assert(m_Nodes[node].State != POINT_CONTROLED && m_Nodes[node].State != POINT_DESTROYED); + m_Nodes[node].PrevOwner = m_Nodes[node].Owner; + m_Nodes[node].Owner = team; + m_Nodes[node].PrevState = m_Nodes[node].State; + m_Nodes[node].State = POINT_CONTROLED; + m_Nodes[node].Timer = 0; +} + +void BattleGroundAV::ResetBGSubclass() +{ + m_MaxLevel=0; + for(uint8 i=0; i<2; i++) //forloop for both teams (it just make 0==alliance and 1==horde also for both mines 0=north 1=south + { + for(uint8 j=0; j<9; j++) + m_Team_QuestStatus[i][j]=0; + m_Team_Scores[i]=BG_AV_SCORE_INITIAL_POINTS; + m_IsInformedNearVictory[i]=false; + m_CaptainAlive[i] = true; + m_CaptainBuffTimer[i] = 120000 + urand(0,4)* 60; //as far as i could see, the buff is randomly so i make 2minutes (thats the duration of the buff itself) + 0-4minutes TODO get the right times + m_Mine_Owner[i] = AV_NEUTRAL_TEAM; + m_Mine_PrevOwner[i] = m_Mine_Owner[i]; + } + for(BG_AV_Nodes i = BG_AV_NODES_FIRSTAID_STATION; i <= BG_AV_NODES_STONEHEART_GRAVE; ++i) //alliance graves + InitNode(i,ALLIANCE,false); + for(BG_AV_Nodes i = BG_AV_NODES_DUNBALDAR_SOUTH; i <= BG_AV_NODES_STONEHEART_BUNKER; ++i) //alliance towers + InitNode(i,ALLIANCE,true); + for(BG_AV_Nodes i = BG_AV_NODES_ICEBLOOD_GRAVE; i <= BG_AV_NODES_FROSTWOLF_HUT; ++i) //horde graves + InitNode(i,HORDE,false); + for(BG_AV_Nodes i = BG_AV_NODES_ICEBLOOD_TOWER; i <= BG_AV_NODES_FROSTWOLF_WTOWER; ++i) //horde towers + InitNode(i,HORDE,true); + InitNode(BG_AV_NODES_SNOWFALL_GRAVE,AV_NEUTRAL_TEAM,false); //give snowfall neutral owner + + m_Mine_Timer=AV_MINE_TICK_TIMER; + for(uint16 i = 0; i < AV_CPLACE_MAX+AV_STATICCPLACE_MAX; i++) + if(m_BgCreatures[i]) + DelCreature(i); + +} + diff --git a/src/game/BattleGroundAV.h b/src/game/BattleGroundAV.h index 5b69af9458b..e80ad47d869 100644 --- a/src/game/BattleGroundAV.h +++ b/src/game/BattleGroundAV.h @@ -23,6 +23,1462 @@ class BattleGround; +#define LANG_BG_AV_A_CAPTAIN_BUFF "Begone. Uncouth scum! The Alliance shall prevail in Alterac Valley!" +#define LANG_BG_AV_H_CAPTAIN_BUFF "Now is the time to attack! For the Horde!" +#define LANG_BG_AV_S_MINE_BOSS_CLAIMS "Snivvle is here! Snivvle claims the Coldtooth Mine!" + +#define BG_AV_CAPTIME 240000 //4:00 +#define BG_AV_SNOWFALL_FIRSTCAP 300000 //5:00 but i also have seen 4:05 + +#define BG_AV_SCORE_INITIAL_POINTS 600 +#define SEND_MSG_NEAR_LOSE 120 + +#define BG_AV_KILL_BOSS 4 +#define BG_AV_REP_BOSS 350 + +#define BG_AV_KILL_CAPTAIN 3 +#define BG_AV_REP_CAPTAIN 125 +#define BG_AV_RES_CAPTAIN 100 + +#define BG_AV_KILL_TOWER 3 +#define BG_AV_REP_TOWER 12 +#define BG_AV_RES_TOWER 75 + +#define BG_AV_GET_COMMANDER 1 //for a safely returned wingcommander +//bonushonor at the end +#define BG_AV_KILL_SURVIVING_TOWER 2 +#define BG_AV_REP_SURVIVING_TOWER 12 + +#define BG_AV_KILL_SURVIVING_CAPTAIN 2 +#define BG_AV_REP_SURVIVING_CAPTAIN 125 + +enum BG_AV_Sounds +{ //TODO: get out if there comes a sound when neutral team captures mine + +/* +8212: + alliance grave assault + alliance tower assault + drek "mlanzenabschaum! In meiner Burg?! Toetet sie all" - nicht immer der sound +8333: + galv "sterbt fuer euch ist kein platz hier" + +8332: + bal "Verschwinde, dreckiger Abschaum! Die Allianz wird im Alteractal " +8174: + horde tower assault + horde grave assault + van "es Sturmlanzenklans, euer General wird angegriffen! Ich fordere Unterst" +8173: + ally grave capture/defend + tower destroy + mine capture + ally wins +8192: + ally tower destroy(only iceblood - found a bug^^) + ally tower defend + horde tower defend +8213 +horde: + grave defend/capture + tower destroy + mine capture + horde wins + */ + + AV_SOUND_NEAR_VICTORY = 8456, //not confirmed yet + + AV_SOUND_ALLIANCE_ASSAULTS = 8212, //tower,grave + enemy boss if someone tries to attack him + AV_SOUND_HORDE_ASSAULTS = 8174, + AV_SOUND_ALLIANCE_GOOD = 8173, //if something good happens for the team: wins(maybe only through killing the boss), captures mine or grave, destroys tower and defends grave + AV_SOUND_HORDE_GOOD = 8213, + AV_SOUND_BOTH_TOWER_DEFEND = 8192, + + AV_SOUND_ALLIANCE_CAPTAIN = 8232, //gets called when someone attacks them and at the beginning after 3min+rand(x)*10sec (maybe buff) + AV_SOUND_HORDE_CAPTAIN = 8333, + + +}; + +enum BG_AV_OTHER_VALUES +{ + AV_STATICCPLACE_MAX = 123, + AV_NORTH_MINE = 0, + AV_SOUTH_MINE = 1, + AV_MINE_TICK_TIMER = 45000, + AV_MINE_RECLAIM_TIMER = 1200000, //TODO: get the right value.. this is currently 20 minutes + AV_NEUTRAL_TEAM = 0 //this is the neutral owner of snowfall +}; +enum BG_AV_ObjectIds +{ + //cause the mangos-system is a bit different, we don't use the right go-ids for every node.. if we want to be 100% like another big server, we must take one object for every node + //snowfall 4flags as eyecandy 179424 (alliance neutral) + //Banners - stolen from battleground_AB.h ;-) + BG_AV_OBJECTID_BANNER_A = 178925, // can only be used by horde + BG_AV_OBJECTID_BANNER_H = 178943, // can only be used by alliance + BG_AV_OBJECTID_BANNER_CONT_A = 178940, // can only be used by horde + BG_AV_OBJECTID_BANNER_CONT_H = 179435, // can only be used by alliance + + BG_AV_OBJECTID_BANNER_A_B = 178365, + BG_AV_OBJECTID_BANNER_H_B = 178364, + BG_AV_OBJECTID_BANNER_CONT_A_B = 179286, + BG_AV_OBJECTID_BANNER_CONT_H_B = 179287, + BG_AV_OBJECTID_BANNER_SNOWFALL_N = 180418, + + //snowfall eyecandy banner: + BG_AV_OBJECTID_SNOWFALL_CANDY_A = 179044, + BG_AV_OBJECTID_SNOWFALL_CANDY_PA = 179424, + BG_AV_OBJECTID_SNOWFALL_CANDY_H = 179064, + BG_AV_OBJECTID_SNOWFALL_CANDY_PH = 179425, + + //banners on top of towers: + BG_AV_OBJECTID_TOWER_BANNER_A = 178927, //[PH] Alliance A1 Tower Banner BIG + BG_AV_OBJECTID_TOWER_BANNER_H = 178955, //[PH] Horde H1 Tower Banner BIG + BG_AV_OBJECTID_TOWER_BANNER_PA = 179446, //[PH] Alliance H1 Tower Pre-Banner BIG + BG_AV_OBJECTID_TOWER_BANNER_PH = 179436, //[PH] Horde A1 Tower Pre-Banner BIG + + //Auras + BG_AV_OBJECTID_AURA_A = 180421, + BG_AV_OBJECTID_AURA_H = 180422, + BG_AV_OBJECTID_AURA_N = 180423, + BG_AV_OBJECTID_AURA_A_S = 180100, + BG_AV_OBJECTID_AURA_H_S = 180101, + BG_AV_OBJECTID_AURA_N_S = 180102, + + BG_AV_OBJECTID_GATE_A = 180424, + BG_AV_OBJECTID_GATE_H = 180424, + + //mine supplies + BG_AV_OBJECTID_MINE_N = 178785, + BG_AV_OBJECTID_MINE_S = 178784, + + BG_AV_OBJECTID_FIRE = 179065, + BG_AV_OBJECTID_SMOKE = 179066 +}; + +enum BG_AV_Nodes +{ + BG_AV_NODES_FIRSTAID_STATION = 0, + BG_AV_NODES_STORMPIKE_GRAVE = 1, + BG_AV_NODES_STONEHEART_GRAVE = 2, + BG_AV_NODES_SNOWFALL_GRAVE = 3, + BG_AV_NODES_ICEBLOOD_GRAVE = 4, + BG_AV_NODES_FROSTWOLF_GRAVE = 5, + BG_AV_NODES_FROSTWOLF_HUT = 6, + BG_AV_NODES_DUNBALDAR_SOUTH = 7, + BG_AV_NODES_DUNBALDAR_NORTH = 8, + BG_AV_NODES_ICEWING_BUNKER = 9, + BG_AV_NODES_STONEHEART_BUNKER = 10, + BG_AV_NODES_ICEBLOOD_TOWER = 11, + BG_AV_NODES_TOWER_POINT = 12, + BG_AV_NODES_FROSTWOLF_ETOWER = 13, + BG_AV_NODES_FROSTWOLF_WTOWER = 14, + + BG_AV_NODES_MAX = 15 +}; + +enum BG_AV_ObjectTypes +{ + BG_AV_OBJECT_FLAG_A_FIRSTAID_STATION = 0, + BG_AV_OBJECT_FLAG_A_STORMPIKE_GRAVE = 1, + BG_AV_OBJECT_FLAG_A_STONEHEART_GRAVE = 2, + BG_AV_OBJECT_FLAG_A_SNOWFALL_GRAVE = 3, + BG_AV_OBJECT_FLAG_A_ICEBLOOD_GRAVE = 4, + BG_AV_OBJECT_FLAG_A_FROSTWOLF_GRAVE = 5, + BG_AV_OBJECT_FLAG_A_FROSTWOLF_HUT = 6, + BG_AV_OBJECT_FLAG_A_DUNBALDAR_SOUTH = 7, + BG_AV_OBJECT_FLAG_A_DUNBALDAR_NORTH = 8, + BG_AV_OBJECT_FLAG_A_ICEWING_BUNKER = 9, + BG_AV_OBJECT_FLAG_A_STONEHEART_BUNKER = 10, + + BG_AV_OBJECT_FLAG_C_A_FIRSTAID_STATION = 11, + BG_AV_OBJECT_FLAG_C_A_STORMPIKE_GRAVE = 12, + BG_AV_OBJECT_FLAG_C_A_STONEHEART_GRAVE = 13, + BG_AV_OBJECT_FLAG_C_A_SNOWFALL_GRAVE = 14, + BG_AV_OBJECT_FLAG_C_A_ICEBLOOD_GRAVE = 15, + BG_AV_OBJECT_FLAG_C_A_FROSTWOLF_GRAVE = 16, + BG_AV_OBJECT_FLAG_C_A_FROSTWOLF_HUT = 17, + BG_AV_OBJECT_FLAG_C_A_ICEBLOOD_TOWER = 18, + BG_AV_OBJECT_FLAG_C_A_TOWER_POINT = 19, + BG_AV_OBJECT_FLAG_C_A_FROSTWOLF_ETOWER = 20, + BG_AV_OBJECT_FLAG_C_A_FROSTWOLF_WTOWER = 21, + + BG_AV_OBJECT_FLAG_C_H_FIRSTAID_STATION = 22, + BG_AV_OBJECT_FLAG_C_H_STORMPIKE_GRAVE = 23, + BG_AV_OBJECT_FLAG_C_H_STONEHEART_GRAVE = 24, + BG_AV_OBJECT_FLAG_C_H_SNOWFALL_GRAVE = 25, + BG_AV_OBJECT_FLAG_C_H_ICEBLOOD_GRAVE = 26, + BG_AV_OBJECT_FLAG_C_H_FROSTWOLF_GRAVE = 27, + BG_AV_OBJECT_FLAG_C_H_FROSTWOLF_HUT = 28, + BG_AV_OBJECT_FLAG_C_H_DUNBALDAR_SOUTH = 29, + BG_AV_OBJECT_FLAG_C_H_DUNBALDAR_NORTH = 30, + BG_AV_OBJECT_FLAG_C_H_ICEWING_BUNKER = 31, + BG_AV_OBJECT_FLAG_C_H_STONEHEART_BUNKER = 32, + + BG_AV_OBJECT_FLAG_H_FIRSTAID_STATION = 33, + BG_AV_OBJECT_FLAG_H_STORMPIKE_GRAVE = 34, + BG_AV_OBJECT_FLAG_H_STONEHEART_GRAVE = 35, + BG_AV_OBJECT_FLAG_H_SNOWFALL_GRAVE = 36, + BG_AV_OBJECT_FLAG_H_ICEBLOOD_GRAVE = 37, + BG_AV_OBJECT_FLAG_H_FROSTWOLF_GRAVE = 38, + BG_AV_OBJECT_FLAG_H_FROSTWOLF_HUT = 39, + BG_AV_OBJECT_FLAG_H_ICEBLOOD_TOWER = 40, + BG_AV_OBJECT_FLAG_H_TOWER_POINT = 41, + BG_AV_OBJECT_FLAG_H_FROSTWOLF_ETOWER = 42, + BG_AV_OBJECT_FLAG_H_FROSTWOLF_WTOWER = 43, + + BG_AV_OBJECT_FLAG_N_SNOWFALL_GRAVE = 44, + + BG_AV_OBJECT_DOOR_H = 45, + BG_AV_OBJECT_DOOR_A = 46, +//auras for graveyards (3auras per graveyard neutral,alliance,horde) + BG_AV_OBJECT_AURA_N_FIRSTAID_STATION = 47, + BG_AV_OBJECT_AURA_A_FIRSTAID_STATION = 48, + BG_AV_OBJECT_AURA_H_FIRSTAID_STATION = 49, + BG_AV_OBJECT_AURA_N_STORMPIKE_GRAVE = 50, + BG_AV_OBJECT_AURA_A_STORMPIKE_GRAVE = 51, + BG_AV_OBJECT_AURA_H_STORMPIKE_GRAVE = 52, + BG_AV_OBJECT_AURA_N_STONEHEART_GRAVE = 53, + BG_AV_OBJECT_AURA_A_STONEHEART_GRAVE = 54, + BG_AV_OBJECT_AURA_H_STONEHEART_GRAVE = 55, + BG_AV_OBJECT_AURA_N_SNOWFALL_GRAVE = 56, + BG_AV_OBJECT_AURA_A_SNOWFALL_GRAVE = 57, + BG_AV_OBJECT_AURA_H_SNOWFALL_GRAVE = 58, + BG_AV_OBJECT_AURA_N_ICEBLOOD_GRAVE = 59, + BG_AV_OBJECT_AURA_A_ICEBLOOD_GRAVE = 60, + BG_AV_OBJECT_AURA_H_ICEBLOOD_GRAVE = 61, + BG_AV_OBJECT_AURA_N_FROSTWOLF_GRAVE = 62, + BG_AV_OBJECT_AURA_A_FROSTWOLF_GRAVE = 63, + BG_AV_OBJECT_AURA_H_FROSTWOLF_GRAVE = 64, + BG_AV_OBJECT_AURA_N_FROSTWOLF_HUT = 65, + BG_AV_OBJECT_AURA_A_FROSTWOLF_HUT = 66, + BG_AV_OBJECT_AURA_H_FROSTWOLF_HUT = 67, + + //big flags on top of towers 2 flags on each (contested,(alliance | horde)) + 2 auras + BG_AV_OBJECT_TFLAG_A_DUNBALDAR_SOUTH = 67, + BG_AV_OBJECT_TFLAG_H_DUNBALDAR_SOUTH = 68, + BG_AV_OBJECT_TFLAG_A_DUNBALDAR_NORTH = 69, + BG_AV_OBJECT_TFLAG_H_DUNBALDAR_NORTH = 70, + BG_AV_OBJECT_TFLAG_A_ICEWING_BUNKER = 71, + BG_AV_OBJECT_TFLAG_H_ICEWING_BUNKER = 72, + BG_AV_OBJECT_TFLAG_A_STONEHEART_BUNKER = 73, + BG_AV_OBJECT_TFLAG_H_STONEHEART_BUNKER = 74, + BG_AV_OBJECT_TFLAG_A_ICEBLOOD_TOWER = 75, + BG_AV_OBJECT_TFLAG_H_ICEBLOOD_TOWER = 76, + BG_AV_OBJECT_TFLAG_A_TOWER_POINT = 77, + BG_AV_OBJECT_TFLAG_H_TOWER_POINT = 78, + BG_AV_OBJECT_TFLAG_A_FROSTWOLF_ETOWER = 79, + BG_AV_OBJECT_TFLAG_H_FROSTWOLF_ETOWER = 80, + BG_AV_OBJECT_TFLAG_A_FROSTWOLF_WTOWER = 81, + BG_AV_OBJECT_TFLAG_H_FROSTWOLF_WTOWER = 82, + BG_AV_OBJECT_TAURA_A_DUNBALDAR_SOUTH = 83, + BG_AV_OBJECT_TAURA_H_DUNBALDAR_SOUTH = 84, + BG_AV_OBJECT_TAURA_A_DUNBALDAR_NORTH = 85, + BG_AV_OBJECT_TAURA_H_DUNBALDAR_NORTH = 86, + BG_AV_OBJECT_TAURA_A_ICEWING_BUNKER = 87, + BG_AV_OBJECT_TAURA_H_ICEWING_BUNKER = 88, + BG_AV_OBJECT_TAURA_A_STONEHEART_BUNKER = 89, + BG_AV_OBJECT_TAURA_H_STONEHEART_BUNKER = 90, + BG_AV_OBJECT_TAURA_A_ICEBLOOD_TOWER = 91, + BG_AV_OBJECT_TAURA_H_ICEBLOOD_TOWER = 92, + BG_AV_OBJECT_TAURA_A_TOWER_POINT = 93, + BG_AV_OBJECT_TAURA_H_TOWER_POINT = 94, + BG_AV_OBJECT_TAURA_A_FROSTWOLF_ETOWER = 95, + BG_AV_OBJECT_TAURA_H_FROSTWOLF_ETOWER = 96, + BG_AV_OBJECT_TAURA_A_FROSTWOLF_WTOWER = 97, + BG_AV_OBJECT_TAURA_H_FROSTWOLF_WTOWER = 98, + + BG_AV_OBJECT_BURN_DUNBALDAR_SOUTH = 99, + BG_AV_OBJECT_BURN_DUNBALDAR_NORTH = 109, + BG_AV_OBJECT_BURN_ICEWING_BUNKER = 119, + BG_AV_OBJECT_BURN_STONEHEART_BUNKER = 129, + BG_AV_OBJECT_BURN_ICEBLOOD_TOWER = 139, + BG_AV_OBJECT_BURN_TOWER_POINT = 149, + BG_AV_OBJECT_BURN_FROSTWOLF_ETWOER = 159, + BG_AV_OBJECT_BURN_FROSTWOLF_WTOWER = 169, + BG_AV_OBJECT_BURN_BUILDING_ALLIANCE = 179, + BG_AV_OBJECT_BURN_BUILDING_HORDE = 189, + BG_AV_OBJECT_SNOW_EYECANDY_A = 199, + BG_AV_OBJECT_SNOW_EYECANDY_PA = 203, + BG_AV_OBJECT_SNOW_EYECANDY_H = 207, + BG_AV_OBJECT_SNOW_EYECANDY_PH = 211, + BG_AV_OBJECT_MINE_SUPPLY_N_MIN = 215, + BG_AV_OBJECT_MINE_SUPPLY_N_MAX = 224, + BG_AV_OBJECT_MINE_SUPPLY_S_MIN = 225, + BG_AV_OBJECT_MINE_SUPPLY_S_MAX = 236, + + BG_AV_OBJECT_MAX = 237 +}; + + + +enum BG_AV_OBJECTS +{ + AV_OPLACE_FIRSTAID_STATION = 0, + AV_OPLACE_STORMPIKE_GRAVE = 1, + AV_OPLACE_STONEHEART_GRAVE = 2, + AV_OPLACE_SNOWFALL_GRAVE = 3, + AV_OPLACE_ICEBLOOD_GRAVE = 4, + AV_OPLACE_FROSTWOLF_GRAVE = 5, + AV_OPLACE_FROSTWOLF_HUT = 6, + AV_OPLACE_DUNBALDAR_SOUTH = 7, + AV_OPLACE_DUNBALDAR_NORTH = 8, + AV_OPLACE_ICEWING_BUNKER = 9, + AV_OPLACE_STONEHEART_BUNKER = 10, + AV_OPLACE_ICEBLOOD_TOWER = 11, + AV_OPLACE_TOWER_POINT = 12, + AV_OPLACE_FROSTWOLF_ETOWER = 13, + AV_OPLACE_FROSTWOLF_WTOWER = 14, + AV_OPLACE_BIGBANNER_DUNBALDAR_SOUTH = 15, + AV_OPLACE_BIGBANNER_DUNBALDAR_NORTH = 16, + AV_OPLACE_BIGBANNER_ICEWING_BUNKER = 17, + AV_OPLACE_BIGBANNER_STONEHEART_BUNKER = 18, + AV_OPLACE_BIGBANNER_ICEBLOOD_TOWER = 19, + AV_OPLACE_BIGBANNER_TOWER_POINT = 20, + AV_OPLACE_BIGBANNER_FROSTWOLF_ETOWER = 21, + AV_OPLACE_BIGBANNER_FROSTWOLF_WTOWER = 22, + + AV_OPLACE_BURN_DUNBALDAR_SOUTH = 23, + AV_OPLACE_BURN_DUNBALDAR_NORTH = 33, + AV_OPLACE_BURN_ICEWING_BUNKER = 43, + AV_OPLACE_BURN_STONEHEART_BUNKER = 53, + AV_OPLACE_BURN_ICEBLOOD_TOWER = 63, + AV_OPLACE_BURN_TOWER_POINT = 73, + AV_OPLACE_BURN_FROSTWOLF_ETOWER = 83, + AV_OPLACE_BURN_FROSTWOLF_WTOWER = 93, + AV_OPLACE_BURN_BUILDING_A = 103, + AV_OPLACE_BURN_BUILDING_H = 113, + AV_OPLACE_SNOW_1 = 123, + AV_OPLACE_SNOW_2 = 124, + AV_OPLACE_SNOW_3 = 125, + AV_OPLACE_SNOW_4 = 126, + AV_OPLACE_MINE_SUPPLY_N_MIN = 127, + AV_OPLACE_MINE_SUPPLY_N_MAX = 136, + AV_OPLACE_MINE_SUPPLY_S_MIN = 137, + AV_OPLACE_MINE_SUPPLY_S_MAX = 148, + + AV_OPLACE_MAX = 149 +}; +const float BG_AV_ObjectPos[AV_OPLACE_MAX][4] = { + {638.592f,-32.422f,46.0608f,-1.62316f },//firstaid station + {669.007f,-294.078f,30.2909f,2.77507f },//stormpike + {77.8013f,-404.7f,46.7549f,-0.872665f },//stone grave + {-202.581f,-112.73f,78.4876f,-0.715585f },//snowfall + {-611.962f,-396.17f,60.8351f,2.53682f}, //iceblood grave + {-1082.45f,-346.823f,54.9219f,-1.53589f },//frostwolf grave + {-1402.21f,-307.431f,89.4424f,0.191986f },//frostwolf hut + {553.779f,-78.6566f,51.9378f,-1.22173f }, //dunnbaldar south + {674.001f,-143.125f,63.6615f,0.994838f }, //dunbaldar north + {203.281f,-360.366f,56.3869f,-0.925024f }, //icew + {-152.437f,-441.758f,40.3982f,-1.95477f }, //stone + {-571.88f,-262.777f,75.0087f,-0.802851f }, //ice tower + {-768.907f,-363.71f,90.8949f,1.07991f}, //tower point + {-1302.9f,-316.981f,113.867f,2.00713f }, //frostwolf etower + {-1297.5f,-266.767f,114.15f,3.31044f}, //frostwolf wtower + //bigbanner: + {555.848f,-84.4151f,64.4397f,3.12414f }, //duns + {679.339f,-136.468f,73.9626f,-2.16421f }, //dunn + {208.973f,-365.971f,66.7409f,-0.244346f }, //icew + {-155.832f,-449.401f,52.7306f,0.610865f }, //stone + {-572.329f,-262.476f,88.6496f,-0.575959f }, //icetower + {-768.199f,-363.105f,104.537f,0.10472f }, //towerp + {-1302.84f,-316.582f,127.516f,0.122173f }, //etower + {-1297.87f,-266.762f,127.796f,0.0698132f }, //wtower + //burning auras towers have 9*179065 captain-buildings have 5*179066+5*179065 + //dunns + {562.632f,-88.1815f,61.993f,0.383972f }, + {562.523f,-74.5028f,37.9474f,-0.0523599f }, + {558.097f,-70.9842f,52.4876f,0.820305f }, + {578.167f,-71.8191f,38.1514f,2.72271f }, + {556.028f,-94.9242f,44.8191f,3.05433f }, + {572.451f,-94.3655f,37.9443f,-1.72788f }, + {549.263f,-79.3645f,44.8191f,0.436332f }, + {543.513f,-94.4006f,52.4819f,0.0349066f }, + {572.149f,-93.7862f,52.5726f,0.541052f }, + {582.162f,-81.2375f,37.9216f,0.0872665f }, + //dunn + {664.797f,-143.65f,64.1784f,-0.453786f}, + {664.505f,-139.452f,49.6696f,-0.0349067f}, + {676.067f,-124.319f,49.6726f,-1.01229f}, + {693.004f,-144.025f,64.1755f,2.44346f}, + {661.175f,-117.691f,49.645f,1.91986f}, + {684.423f,-146.582f,63.6662f,0.994838f}, + {682.791f,-127.769f,62.4155f,1.09956f}, + {674.576f,-147.101f,56.5425f,-1.6057f}, + {655.719f,-126.673f,49.8138f,2.80998f}, + {0,0,0,0}, + //icew + {231.503f,-356.688f,42.3704f,0.296706f}, + {224.989f,-348.175f,42.5607f,1.50098f}, + {205.782f,-351.335f,56.8998f,1.01229f}, + {196.605f,-369.187f,56.3914f,2.46091f}, + {210.619f,-376.938f,49.2677f,2.86234f}, + {209.647f,-352.632f,42.3959f,-0.698132f}, + {220.65f,-368.132f,42.3978f,-0.2618f}, + {224.682f,-374.031f,57.0679f,0.541052f}, + {200.26f,-359.968f,49.2677f,-2.89725f}, + {196.619f,-378.016f,56.9131f,1.01229f}, + //stone + {-155.488f,-437.356f,33.2796f,2.60054f}, + {-163.441f,-454.188f,33.2796f,1.93732f}, + {-143.977f,-445.148f,26.4097f,-1.8675f}, + {-135.764f,-464.708f,26.3823f,2.25147f}, + {-154.076f,-466.929f,41.0636f,-1.8675f}, + {-149.908f,-460.332f,26.4083f,-2.09439f}, + {-151.638f,-439.521f,40.3797f,0.436332f}, + {-131.301f,-454.905f,26.5771f,2.93215f}, + {-171.291f,-444.684f,40.9211f,2.30383f}, + {-143.591f,-439.75f,40.9275f,-1.72788f}, + //iceblood + {-572.667f,-267.923f,56.8542f,2.35619f}, + {-561.021f,-262.689f,68.4589f,1.37881f}, + {-572.538f,-262.649f,88.6197f,1.8326f}, + {-574.77f,-251.45f,74.9422f,-1.18682f}, + {-578.625f,-267.571f,68.4696f,0.506145f}, + {-571.476f,-257.234f,63.3223f,3.10669f}, + {-566.035f,-273.907f,52.9582f,-0.890118f}, + {-580.948f,-259.77f,68.4696f,1.46608f}, + {-568.318f,-267.1f,75.0008f,1.01229f}, + {-559.621f,-268.597f,52.8986f,0.0523599f}, + //towerp + {-776.072f,-368.046f,84.3558f,2.63545f}, + {-777.564f,-368.521f,90.6701f,1.72788f}, + {-765.461f,-357.711f,90.888f,0.314159f}, + {-768.763f,-362.735f,104.612f,1.81514f}, + {-760.356f,-358.896f,84.3558f,2.1293f}, + {-771.967f,-352.838f,84.3484f,1.74533f}, + {-773.333f,-364.653f,79.2351f,-1.64061f}, + {-764.109f,-366.069f,70.0934f,0.383972f}, + {-767.103f,-350.737f,68.7933f,2.80998f}, + {-760.115f,-353.845f,68.8633f,1.79769f}, + //froste + {-1304.87f,-304.525f,91.8366f,-0.680679f}, + {-1301.77f,-310.974f,95.8252f,0.907571f}, + {-1305.58f,-320.625f,102.166f,-0.558505f}, + {-1294.27f,-323.468f,113.893f,-1.67552f}, + {-1302.65f,-317.192f,127.487f,2.30383f}, + {-1293.89f,-313.478f,107.328f,1.6057f}, + {-1312.41f,-312.999f,107.328f,1.5708f}, + {-1311.57f,-308.08f,91.7666f,-1.85005f}, + {-1314.7f,-322.131f,107.36f,0.645772f}, + {-1304.6f,-310.754f,113.859f,-0.401426f}, + //frostw + {-1308.24f,-273.26f,92.0514f,-0.139626f}, + {-1302.26f,-262.858f,95.9269f,0.418879f}, + {-1297.28f,-267.773f,126.756f,2.23402f}, + {-1299.08f,-256.89f,114.108f,-2.44346f}, + {-1303.41f,-268.237f,114.151f,-1.23918f}, + {-1304.43f,-273.682f,107.612f,0.244346f}, + {-1309.53f,-265.951f,92.1418f,-2.49582f}, + {-1295.55f,-263.865f,105.033f,0.925024f}, + {-1294.71f,-281.466f,107.664f,-1.50098f}, + {-1289.69f,-259.521f,107.612f,-2.19912f}, + + //the two buildings of the captains + //alliance + {-64.4987f,-289.33f,33.4616f,-2.82743f}, + {-5.98025f,-326.144f,38.8538f,0}, + {-2.67893f,-306.998f,33.4165f,0}, + {-60.25f,-309.232f,50.2408f,-1.46608f}, + {-48.7941f,-266.533f,47.7916f,2.44346f}, + {-3.40929f,-306.288f,33.34f,0}, + {-48.619f,-266.917f,47.8168f,0}, + {-62.9474f,-286.212f,66.7288f,0}, + {-5.05132f,-325.323f,38.8536f,0}, + {-64.2677f,-289.412f,33.469f,0}, +//horde + {-524.276f,-199.6f,82.8733f,-1.46608f}, + {-518.196f,-173.085f,102.43f,0}, + {-500.732f,-145.358f,88.5337f,2.44346f}, + {-501.084f,-150.784f,80.8506f,0}, + {-518.309f,-163.963f,102.521f,2.96706f}, + {-517.053f,-200.429f,80.759f,0}, + {-514.361f,-163.864f,104.163f,0}, + {-568.04f,-188.707f,81.55f,0}, + {-501.775f,-151.581f,81.2027f,0}, + {-509.975f,-191.652f,83.2978f,0}, + +//snowfall eyecandy + {-191.153f,-129.868f,78.5595f,-1.25664f }, + {-201.282f,-134.319f,78.6753f,-0.942478f }, + {-215.981f,-91.4101f,80.8702f,-1.74533f }, + {-200.465f,-96.418f,79.7587f,1.36136f }, + //mine supplies + //irondeep + {870.899f,-388.434f,61.6406f,-1.22173f}, + {825.214f,-320.174f,63.712f,-2.82743f}, + {837.117f,-452.556f,47.2331f,-3.12414f}, + {869.755f,-448.867f,52.5448f,-0.855212f}, + {949.877f,-458.198f,56.4874f,0.314159f}, + {900.35f,-479.024f,58.3553f,0.122173f}, + {854.449f,-442.255f,50.6589f,0.401426f}, + {886.685f,-442.358f,54.6962f,-1.22173f}, + {817.509f,-457.331f,48.4666f,2.07694f}, + {793.411f,-326.281f,63.1117f,-2.79253f}, + //coldtooth + {-934.212f,-57.3517f,80.277f,-0.0174535f}, + {-916.281f,-36.8579f,77.0227f,0.122173f}, + {-902.73f,-103.868f,75.4378f,-1.58825f}, + {-900.514f,-143.527f,75.9686f,1.8675f}, + {-862.882f,-0.353299f,72.1526f,-2.51327f}, + {-854.932f,-85.9184f,68.6056f,-2.04204f}, + {-851.833f,-118.959f,63.8672f,-0.0698131f}, + {-849.832f,-20.8421f,70.4672f,-1.81514f}, + {-844.25f,-60.0374f,72.1031f,-2.19912f}, + {-820.644f,-136.043f,63.1977f,2.40855f}, + {-947.642f,-208.807f,77.0101f,1.36136f}, + {-951.394f,-193.695f,67.634f,0.802851f} +}; + +const float BG_AV_DoorPositons[2][4] = { + {780.487f, -493.024f, 99.9553f, 3.0976f}, //alliance + {-1375.193f, -538.981f, 55.2824f, 0.72178f} //horde +}; + + +//creaturestuff starts here +//is related to BG_AV_CreaturePos +enum BG_AV_CreaturePlace +{ + AV_CPLACE_SPIRIT_STORM_AID = 0, + AV_CPLACE_SPIRIT_STORM_GRAVE = 1, + AV_CPLACE_SPIRIT_STONE_GRAVE = 2, + AV_CPLACE_SPIRIT_SNOWFALL = 3, + AV_CPLACE_SPIRIT_ICE_GRAVE = 4, + AV_CPLACE_SPIRIT_FROSTWOLF = 5, + AV_CPLACE_SPIRIT_FROST_HUT = 6, + AV_CPLACE_SPIRIT_MAIN_ALLIANCE = 7, + AV_CPLACE_SPIRIT_MAIN_HORDE = 8, +//i don't will add for all 4 positions a variable.. i think one is enough to compute the rest + AV_CPLACE_DEFENSE_STORM_AID = 9, + AV_CPLACE_DEFEMSE_STORM_GRAVE = 13, + AV_CPLACE_DEFENSE_STONE_GRAVE = 17, + AV_CPLACE_DEFENSE_SNOWFALL = 21, + AV_CPLACE_DEFENSE_FROSTWOLF = 25, + AV_CPLACE_DEFENSE_ICE_GRAVE = 29, + AV_CPLACE_DEFENSE_FROST_HUT = 33, + + AV_CPLACE_DEFENSE_DUN_S = 37, + AV_CPLACE_DEFENSE_DUN_N = 41, + AV_CPLACE_DEFENSE_ICEWING = 45, + AV_CPLACE_DEFENSE_STONE_TOWER = 49, + AV_CPLACE_DEFENSE_ICE_TOWER = 53, + AV_CPLACE_DEFENSE_TOWERPOINT = 57, + AV_CPLACE_DEFENSE_FROST_E = 61, + AV_CPLACE_DEFENSE_FROST_t = 65, + + AV_CPLACE_A_MARSHAL_SOUTH = 69, + AV_CPLACE_A_MARSHAL_NORTH = 70, + AV_CPLACE_A_MARSHAL_ICE = 71, + AV_CPLACE_A_MARSHAL_STONE = 72, + AV_CPLACE_H_MARSHAL_ICE = 73, + AV_CPLACE_H_MARSHAL_TOWER = 74, + AV_CPLACE_H_MARSHAL_ETOWER = 75, + AV_CPLACE_H_MARSHAL_WTOWER = 76, + //irondeep + //miner: + AV_CPLACE_MINE_N_1_MIN = 77, + AV_CPLACE_MINE_N_1_MAX = 136, + //special types + AV_CPLACE_MINE_N_2_MIN = 137, + AV_CPLACE_MINE_N_2_MAX = 192, + //boss + AV_CPLACE_MINE_N_3 = 193, + //coldtooth + //miner: + AV_CPLACE_MINE_S_1_MIN = 194, + AV_CPLACE_MINE_S_1_MAX = 250, + //special types + AV_CPLACE_MINE_S_2_MIN = 251, + AV_CPLACE_MINE_S_2_MAX = 289, + //vermin + AV_CPLACE_MINE_S_S_MIN = 290, + AV_CPLACE_MINE_S_S_MAX = 299, + //boss + AV_CPLACE_MINE_S_3 = 300, + + //herald + AV_CPLACE_HERALD = 301, + + AV_CPLACE_MAX = 302 +}; + +//x, y, z, o +const float BG_AV_CreaturePos[AV_CPLACE_MAX][4] = { + //spiritguides + {643.000000f,44.000000f,69.740196f,-0.001854f}, + {676.000000f,-374.000000f,30.000000f,-0.001854f}, + {73.417755f,-496.433105f,48.731918f,-0.001854f}, + {-157.409195f,31.206272f,77.050598f,-0.001854f}, + {-531.217834f,-405.231384f,49.551376f,-0.001854f}, + {-1090.476807f,-253.308670f,57.672371f,-0.001854f}, + {-1496.065063f,-333.338409f,101.134804f,-0.001854f}, + {873.001770f,-491.283630f,96.541931f,-0.001854f}, + {-1437.670044f,-610.088989f,51.161900f,-0.001854f}, + //grave + //firstaid + {635.17f,-29.5594f,46.5056f,4.81711f}, + {642.488f,-32.9437f,46.365f,4.67748f}, + {642.326f,-27.9442f,46.9211f,4.59022f}, + {635.945f,-33.6171f,45.7164f,4.97419f}, + //stormpike + {669.272f,-297.304f,30.291f,4.66604f}, + {674.08f,-292.328f,30.4817f,0.0918785f}, + {667.01f,-288.532f,29.8809f,1.81583f}, + {664.153f,-294.042f,30.2851f,3.28531f}, + //stone + {81.7027f,-406.135f,47.7843f,0.598464f}, + {78.1431f,-409.215f,48.0401f,5.05953f}, + {73.4135f,-407.035f,46.7527f,3.34736f}, + {78.2258f,-401.859f,46.4202f,2.05852f}, + //snowfall + {-207.412f,-110.616f,78.7959f,2.43251f}, + {-197.95f,-112.205f,78.5686f,6.22441f}, + {-202.709f,-116.829f,78.4358f,5.13742f}, + {-202.059f,-108.314f,78.5783f,5.91968f}, + //ice + {-615.501f,-393.802f,60.4299f,3.06147f}, + {-608.513f,-392.717f,62.5724f,2.06323f}, + {-609.769f,-400.072f,60.7174f,5.22367f}, + {-616.093f,-398.293f,60.5628f,3.73613f}, + //frost + {-1077.7f,-340.21f,55.4682f,6.25569f}, + {-1082.74f,-333.821f,54.7962f,2.05459f}, + {-1090.66f,-341.267f,54.6768f,3.27746f}, + {-1081.58f,-344.63f,55.256f,4.75636f}, + //frost hut + {-1408.95f,-311.69f,89.2536f,4.49954f}, + {-1407.15f,-305.323f,89.1993f,2.86827f}, + {-1400.64f,-304.3f,89.7008f,1.0595f}, + {-1400.4f,-311.35f,89.3028f,4.99434f}, + //towers + //dun south - OK + {569.395f,-101.064f,52.8296f,2.34974f}, + {574.85f,-92.9842f,52.5869f,3.09325f}, + {575.411f,-83.597f,52.3626f,6.26573f}, + {571.352f,-75.6582f,52.479f,0.523599f}, + //dun north - OK + {668.60f,-122.53f,64.12f,2.34f}, //not 100% ok + {662.253f,-129.105f,64.1794f,2.77507f}, + {661.209f,-138.877f,64.2251f,3.38594f}, + {665.481f,-146.857f,64.1271f,3.75246f}, + //icewing - OK + {225.228f,-368.909f,56.9983f,6.23806f}, + {191.36f,-369.899f,57.1524f,3.24631f}, + {215.518f,-384.019f,56.9889f,5.09636f}, + {199.625f,-382.177f,56.8691f,4.08407f}, + //stone + {-172.851f,-452.366f,40.8725f,3.31829f}, + {-147.147f,-435.053f,40.8022f,0.599238f}, + {-169.456f,-440.325f,40.985f,2.59101f}, + {-163.494f,-434.904f,41.0725f,1.84174f}, + //ice - OK + {-573.522f,-271.854f,75.0078f,3.9619f}, + {-565.616f,-269.051f,74.9952f,5.02655f}, + {-562.825f,-261.087f,74.9898f,5.95157f}, + {-569.176f,-254.446f,74.8771f,0.820305f}, + //towerpoint + {-763.04f,-371.032f,90.7933f,5.25979f}, + {-759.764f,-358.264f,90.8681f,0.289795f}, + {-768.808f,-353.056f,90.8811f,1.52601f}, + {-775.944f,-362.639f,90.8949f,2.59573f}, + //frost etower + {-1294.13f,-313.045f,107.328f,0.270162f}, + {-1306.5f,-308.105f,113.767f,1.78755f}, + {-1294.78f,-319.966f,113.79f,5.94545f}, + {-1294.83f,-312.241f,113.799f,0.295293f}, + //frost wtower + {-1300.96f,-275.111f,114.058f,4.12804f}, + {-1302.41f,-259.256f,114.065f,1.67602f}, + {-1287.97f,-262.087f,114.165f,6.18264f}, + {-1291.59f,-271.166f,114.151f,5.28257f}, + + //alliance marshall + {721.104f,-7.64155f,50.7046f,3.45575f},// south + {723.058f,-14.1548f,50.7046f,3.40339f},// north + {715.691f,-4.72233f,50.2187f,3.47321f},// icewing + {720.046f,-19.9413f,50.2187f,3.36849f},// stone +//horde (coords not 100% ok) + {-1363.99f,-221.99f,98.4053f,4.93012f}, + {-1370.96f,-223.532f,98.4266f,4.93012f}, + {-1378.37f,-228.614f,99.3546f,5.38565f}, + {-1358.02f,-228.998f,98.868f,3.87768f}, + + //irondeep mine + //Irondeep Trogg + {971.671f,-442.657f,57.6951f,3.1765f}, + {969.979f,-457.148f,58.1119f,4.5204f}, + {958.692f,-333.477f,63.2276f,5.77704f}, + {957.113f,-325.92f,61.7589f,1.13446f}, + {948.25f,-448.268f,56.9009f,5.60251f}, + {934.727f,-385.802f,63.0344f,3.75246f}, + {931.751f,-403.458f,59.6737f,5.63741f}, + {931.146f,-359.666f,66.0294f,3.9619f}, + {929.702f,-412.401f,56.8776f,5.89921f}, + {926.849f,-379.074f,63.5286f,2.0944f}, + {921.972f,-358.597f,66.4313f,2.93215f}, + {921.449f,-341.981f,67.1264f,3.4383f}, + {921.1f,-395.812f,60.4615f,2.71695f}, + {919.274f,-394.986f,60.3478f,2.71696f}, + {916.852f,-393.891f,60.1726f,2.71695f}, + {914.568f,-326.21f,66.1733f,2.25147f}, + {913.064f,-395.773f,60.1364f,4.41568f}, + {909.246f,-474.576f,58.2067f,0.226893f}, + {909.246f,-474.576f,58.2901f,0.226893f}, + {907.209f,-428.267f,59.8065f,1.8675f}, + {905.973f,-459.528f,58.7594f,1.37189f}, + {905.067f,-396.074f,60.2085f,5.07891f}, + {901.809f,-457.709f,59.0116f,3.52557f}, + {900.962f,-427.44f,59.0842f,1.50098f}, + {897.929f,-471.742f,59.7729f,2.54818f}, + {893.376f,-343.171f,68.1499f,5.35816f}, + {890.584f,-406.049f,61.1925f,5.67232f}, + {888.208f,-332.564f,68.148f,1.93732f}, + {887.647f,-391.537f,61.8734f,1.37881f}, + {885.109f,-343.338f,67.0867f,3.78979f}, + {881.618f,-419.948f,53.5228f,0.593412f}, + {878.675f,-345.36f,66.1052f,3.45651f}, + {877.127f,-351.8f,66.5296f,5.74213f}, + {876.778f,-345.97f,65.7724f,3.45262f}, + {874.577f,-414.786f,52.7817f,1.67552f}, + {868.247f,-343.136f,64.9894f,1.6057f}, + {859.03f,-367.231f,47.4655f,0.0174533f}, + {857.513f,-351.817f,65.1867f,4.39823f}, + {852.632f,-372.416f,48.1657f,3.66519f}, + {849.86f,-340.944f,66.2447f,0.401426f}, + {847.99f,-386.287f,60.9277f,2.32374f}, + {847.601f,-423.072f,50.0852f,4.57276f}, + {847.135f,-411.307f,50.2106f,1.5708f}, + {835.077f,-379.418f,48.2755f,5.93412f}, + {834.87f,-453.304f,47.9075f,0.226893f}, + {834.634f,-365.981f,62.8801f,1.32645f}, + {834.354f,-355.526f,48.1491f,6.07375f}, + {833.702f,-327.506f,65.0439f,0.331613f}, + {833.151f,-374.228f,63.0938f,3.66519f}, + {831.711f,-346.785f,47.2975f,0.226893f}, + {827.874f,-413.624f,48.5818f,1.49241f}, + {827.728f,-415.483f,48.5593f,1.49238f}, + {827.016f,-424.543f,48.2856f,1.49236f}, + {823.222f,-334.283f,65.6306f,4.88692f}, + {821.892f,-464.723f,48.9451f,4.66003f}, + {821.006f,-387.635f,49.0728f,3.15905f}, + {817.26f,-447.432f,49.4308f,2.18166f}, + {805.399f,-320.146f,52.7712f,0.296706f}, + {801.405f,-328.055f,53.0195f,4.31096f}, + //irondeep skullthumber irondeep shaman + {955.812f,-440.302f,55.3411f,3.19395f}, + {937.378f,-377.816f,65.3919f,3.56047f}, + {925.059f,-331.347f,65.7564f,3.66519f}, + {922.918f,-396.634f,60.3942f,2.71695f}, + {909.99f,-462.154f,59.0811f,3.7001f}, + {907.893f,-388.787f,61.7923f,5.74213f}, + {898.801f,-437.105f,58.5266f,0.959931f}, + {884.237f,-407.597f,61.566f,0.820305f}, + {880.744f,-344.683f,66.4086f,3.4644f}, + {876.047f,-341.857f,65.8743f,4.45059f}, + {874.674f,-402.077f,61.7573f,0.26341f}, + {871.914f,-404.209f,62.1269f,6.06163f}, + {871.606f,-403.665f,62.0795f,0.765774f}, + {871.561f,-404.114f,62.1297f,0.00981727f}, + {871.528f,-404.248f,62.1455f,0.498032f}, + {871.493f,-404.122f,62.1331f,5.65727f}, + {871.282f,-403.843f,62.1108f,0.788382f}, + {868.294f,-392.395f,61.4772f,4.38685f}, + {868.256f,-392.363f,61.4803f,0.732738f}, + {867.804f,-392.51f,61.5089f,2.30167f}, + {867.612f,-392.371f,61.524f,2.86149f}, + {858.593f,-439.614f,50.2184f,0.872665f}, + {851.471f,-362.52f,47.314f,4.06662f}, + {846.939f,-347.279f,66.2876f,0.942478f}, + {842.08f,-421.775f,48.2659f,1.0821f}, + {838.358f,-371.212f,63.3299f,4.04916f}, + {827.57f,-417.483f,48.4538f,1.49237f}, + {827.012f,-457.397f,48.9331f,2.35619f}, + {825.535f,-322.373f,63.9357f,4.76475f}, + {867.635f,-443.605f,51.3347f,1.38626f}, + {957.293f,-455.039f,56.7395f,5.79449f}, + {950.077f,-326.672f,61.6552f,5.48033f}, + {936.692f,-356.78f,65.9835f,2.75762f}, + {926.475f,-419.345f,56.1833f,2.0944f}, + {924.729f,-397.453f,60.213f,2.71695f}, + {902.195f,-475.891f,58.312f,1.39626f}, + {897.464f,-338.758f,68.1715f,2.94961f}, + {884.237f,-407.597f,61.566f,0.820305f}, + {882.517f,-344.111f,66.7887f,3.46962f}, + {881.437f,-400.254f,61.2028f,0.263427f}, + {880.156f,-400.678f,61.3113f,3.41373f}, + {877.989f,-418.051f,52.9753f,4.46804f}, + {871.212f,-404.12f,62.1433f,3.6554f}, + {871.036f,-404.119f,62.2237f,4.50295f}, + {857.396f,-395.766f,61.263f,4.78684f}, + {857.276f,-395.395f,61.2418f,0.0845553f}, + {857.231f,-394.577f,61.2174f,1.96817f}, + {857.108f,-395.682f,61.2317f,4.87022f}, + {856.709f,-395.28f,61.1814f,2.54913f}, + {850.922f,-390.399f,60.8771f,2.85405f}, + {847.556f,-388.228f,60.9438f,2.56872f}, + {842.031f,-384.663f,61.6028f,2.56871f}, + {832.035f,-389.301f,47.5567f,2.11185f}, + {827.415f,-419.468f,48.3322f,1.49232f}, + {826.402f,-349.454f,47.2722f,1.51844f}, + {817.83f,-455.715f,48.4207f,0.925025f}, + {808.953f,-325.964f,52.4043f,3.01942f}, + // Morloch + {865.554f,-438.735f,50.7333f,2.12431f}, + //coldtooth mine + //miner/digger + {-917.648f,-46.8922f,77.0872f,5.27089f}, + {-912.689f,-45.4494f,76.2277f,4.60767f}, + {-905.455f,-84.5179f,75.3642f,3.29867f}, + {-904.332f,-111.509f,75.5925f,2.47837f}, + {-904.27f,-160.419f,61.9876f,3.61192f}, + {-904.023f,-90.4558f,75.3706f,3.40339f}, + {-978.678f,-37.3136f,75.8364f,2.84489f}, + {-973.076f,-36.5013f,77.5047f,1.0821f}, + {-963.951f,-87.734f,81.5555f,0.575959f}, + {-961.941f,-90.7252f,81.6629f,0.820305f}, + {-957.623f,-186.582f,66.6021f,1.95477f}, + {-952.476f,-179.778f,78.6771f,4.5204f}, + {-950.427f,-115.007f,79.6127f,3.68264f}, + {-950.25f,-151.95f,79.4598f,-1.81423f}, + {-950.169f,-188.099f,66.6184f,5.55015f}, + {-949.944f,-142.977f,80.5382f,2.70526f}, + {-947.854f,-170.5f,79.7618f,0.942478f}, + {-946.738f,-139.567f,80.0904f,2.3911f}, + {-945.503f,-65.0654f,79.7907f,5.02655f}, + {-943.678f,-110.986f,80.2557f,0.959931f}, + {-942.993f,-56.9881f,79.8915f,5.65487f}, + {-938.197f,-155.838f,61.3111f,1.65806f}, + {-930.488f,-214.524f,72.1431f,2.1236f}, + {-929.947f,-154.449f,61.5084f,1.67552f}, + {-927.412f,-135.313f,61.1987f,3.29867f}, + {-920.677f,-156.859f,62.8033f,3.15306f}, + {-916.75f,-136.094f,62.2357f,0.0698132f}, + {-915.319f,-132.718f,62.562f,1.16984f}, + {-913.589f,-146.794f,76.9366f,1.8675f}, + {-907.572f,-148.937f,76.6898f,4.76475f}, + {-902.02f,-64.6174f,73.9707f,1.19169f}, + {-899.489f,-61.7252f,73.2498f,5.09636f}, + {-894.792f,-127.141f,75.3834f,6.14356f}, + {-892.408f,-162.525f,64.1212f,2.69884f}, + {-892.326f,-123.158f,76.0318f,5.5676f}, + {-888.468f,-148.462f,61.8012f,1.65806f}, + {-883.268f,-159.738f,63.5311f,5.20108f}, + {-877.76f,-118.07f,65.215f,2.94961f}, + {-876.792f,-128.646f,64.1045f,3.40339f}, + {-874.901f,-36.6579f,69.4246f,2.00713f}, + {-874.856f,-151.351f,62.7537f,3.57875f}, + {-872.135f,-150.08f,62.7513f,3.57201f}, + {-870.288f,-149.217f,62.5413f,3.56624f}, + {-870.03f,-6.27443f,70.3867f,2.3911f}, + {-869.023f,-82.2118f,69.5848f,3.22886f}, + {-866.354f,-40.2455f,70.842f,0.0698132f}, + {-865.305f,-152.302f,63.5044f,4.86947f}, + {-861.926f,-79.0519f,71.4178f,0.20944f}, + {-857.292f,-152.277f,63.2114f,4.18879f}, + {-853.357f,-0.696194f,72.0655f,0.994838f}, + {-850.685f,-14.2596f,70.2298f,0.20944f}, + {-839.987f,-67.7695f,72.7916f,4.93928f}, + {-839.199f,-57.0558f,73.4891f,1.67552f}, + {-836.963f,-153.224f,63.3821f,4.46804f}, + {-832.721f,-67.7555f,72.9062f,4.99164f}, + {-821.496f,-143.095f,63.1292f,0.541052f}, + {-818.829f,-153.004f,62.1757f,6.12611f}, + //special + {-954.622f,-110.958f,80.7911f,6.24828f}, + {-951.477f,-53.9647f,80.0235f,5.32325f}, + {-946.812f,-126.04f,78.8601f,5.15265f}, + {-940.689f,-140.707f,79.9225f,2.79253f}, + {-933.954f,-159.632f,60.778f,2.56563f}, + {-922.537f,-130.291f,61.3756f,4.95674f}, + {-915.862f,-151.74f,76.9427f,0.942478f}, + {-888.321f,-159.831f,62.5303f,1.20428f}, + {-874.361f,-42.4751f,69.4316f,0.785398f}, + {-873.19f,-50.4899f,70.0568f,-2.41288f}, + {-868.511f,-148.386f,62.3547f,3.57875f}, + {-868.44f,-121.649f,64.5056f,3.33358f}, + {-868.324f,-77.7196f,71.4768f,5.41052f}, + {-859.846f,-19.6549f,70.7304f,1.97222f}, + {-828.05f,-150.508f,62.2019f,2.14675f}, + {-826.254f,-58.6911f,72.0041f,3.68264f}, + {-976.086f,-44.1775f,76.029f,1.46608f}, + {-971.864f,-87.4223f,81.4954f,5.8294f}, + {-966.551f,-74.1111f,80.0243f,4.2129f}, + {-958.509f,-173.652f,77.9013f,6.24828f}, + {-951.511f,-181.242f,65.529f,4.39823f}, + {-940.967f,-186.243f,77.698f,1.28164f}, + {-930.004f,-65.0898f,79.077f,0.0581657f}, + {-920.864f,-40.2009f,78.256f,5.16617f}, + {-919.089f,-148.021f,62.0317f,2.59327f}, + {-901.516f,-116.329f,75.6876f,0.471239f}, + {-897.864f,-84.4348f,74.083f,3.00197f}, + {-897.617f,-52.0457f,71.9503f,4.36332f}, + {-894.891f,-153.951f,61.6827f,3.23569f}, + {-893.933f,-111.625f,75.6591f,4.22536f}, + {-883.265f,-152.854f,61.8384f,0.0941087f}, + {-868.293f,-147.243f,62.1097f,3.2056f}, + {-867.501f,-11.8709f,70.018f,6.14356f}, + {-866.699f,-147.54f,62.1646f,3.57878f}, + {-866.566f,-91.1916f,67.4414f,4.56707f}, + {-857.272f,-141.142f,61.7356f,4.17134f}, + {-847.446f,-98.0061f,68.5131f,3.24631f}, + {-837.026f,-140.729f,62.5141f,5.51524f}, + {-824.204f,-65.053f,72.3381f,3.01942f}, + //vermin (s.th special for this mine) + {-951.955f,-197.5f,77.212f,5.63741f}, + {-944.837f,-199.608f,77.0737f,4.97419f}, + {-933.494f,-209.063f,73.7803f,5.88176f}, + {-929.666f,-201.308f,73.7032f,5.02655f}, + {-978.997f,-249.356f,65.4345f,5.05464f}, + {-974.565f,-224.828f,69.5858f,4.88846f}, + {-946.514f,-259.239f,66.0874f,3.78132f}, + {-918.402f,-250.439f,69.5271f,2.21352f}, + {-910.14f,-229.959f,72.9279f,0.27677f}, + {-851.563f,-88.6527f,68.5983f,3.61896f}, + //boss + {-848.902f,-92.931f,68.6325f,3.33350}, + //herald + {-48.459f,-288.802f,55.47f,1.0} + +}; + + +enum BG_AV_CreatureIds +{ + + AV_NPC_A_GRAVEDEFENSE0 = 0, // stormpike Defender + AV_NPC_A_GRAVEDEFENSE1 = 1, // seasoned defender + AV_NPC_A_GRAVEDEFENSE2 = 2, // veteran defender + AV_NPC_A_GRAVEDEFENSE3 = 3, // champion defender + AV_NPC_A_TOWERDEFENSE = 4, // stormpike bowman + AV_NPC_A_CAPTAIN = 5, // balinda + AV_NPC_A_BOSS = 6, // vanndar + + AV_NPC_H_GRAVEDEFENSE0 = 7, // frostwolf guardian + AV_NPC_H_GRAVEDEFENSE1 = 8, // seasoned guardian + AV_NPC_H_GRAVEDEFENSE2 = 9, // veteran guardian + AV_NPC_H_GRAVEDEFENSE3 = 10, // champion guardian + AV_NPC_H_TOWERDEFENSE = 11, // frostwolf bowman + AV_NPC_H_CAPTAIN = 12, // galvangar + AV_NPC_H_BOSS = 13, // drek thar + + AV_NPC_A_MARSHAL_SOUTH = 14, + AV_NPC_MARSHAL_NORTH = 15, + AV_NPC_A_MARSHAL_ICE = 16, + AV_NPC_A_MARSHAL_STONE = 17, + AV_NPC_H_MARSHAL_ICE = 18, + AV_NPC_H_MARSHAL_TOWER = 19, + AV_NPC_MARSHAL_ETOWER = 20, + AV_NPC_H_MARSHAL_WTOWER= 21, + AV_NPC_N_MINE_N_1 = 22, + AV_NPC_N_MINE_N_2 = 23, + AV_NPC_N_MINE_N_3 = 24, + AV_NPC_N_MINE_N_4 = 25, + AV_NPC_N_MINE_A_1 = 26, + AV_NPC_N_MINE_A_2 = 27, + AV_NPC_N_MINE_A_3 = 28, + AV_NPC_N_MINE_A_4 = 29, + AV_NPC_N_MINE_H_1 = 30, + AV_NPC_N_MINE_H_2 = 31, + AV_NPC_N_MINE_H_3 = 32, + AV_NPC_N_MINE_H_4 = 33, + AV_NPC_S_MINE_N_1 = 34, + AV_NPC_S_MINE_N_2 = 35, + AV_NPC_S_MINE_N_3 = 36, + AV_NPC_S_MINE_N_4 = 37, + AV_NPC_S_MINE_N_S = 38, + AV_NPC_S_MINE_A_1 = 39, + AV_NPC_S_MINE_A_2 = 40, + AV_NPC_S_MINE_A_3 = 41, + AV_NPC_S_MINE_A_4 = 42, + AV_NPC_S_MINE_H_1 = 43, + AV_NPC_S_MINE_H_2 = 44, + AV_NPC_S_MINE_H_3 = 45, + AV_NPC_S_MINE_H_4 = 46, + AV_NPC_HERALD = 47, + AV_NPC_INFO_MAX = 48 + +}; + +//entry, team, minlevel, maxlevel +//TODO this array should be removed, the only needed things are the entrys (for spawning(?) and handlekillunit) +const uint32 BG_AV_CreatureInfo[AV_NPC_INFO_MAX][4] = { + { 12050, 1216, 58, 58 }, //Stormpike Defender + { 13326, 1216, 59, 59 }, //Seasoned Defender + { 13331, 1216, 60, 60 }, //Veteran Defender + { 13422, 1216, 61, 61 }, //Champion Defender + { 13358, 1216, 59, 60 }, //Stormpike Bowman //i think its 60,61 and 69,70.. but this is until now not possible TODO look if this is ok + { 11949,469,0,0},//not spawned with this data, but used for handlekillunit + { 11948,469,0,0},//not spawned with this data, but used for handlekillunit + { 12053, 1214, 58, 58 }, //Frostwolf Guardian + { 13328, 1214, 59, 59 }, //Seasoned Guardian + { 13332, 1214, 60, 60 }, //Veteran Guardian + { 13421, 1214, 61, 61 }, //Champion Guardian + { 13359, 1214, 59, 60 }, //Frostwolf Bowman + { 11947,67,0,0}, //not spawned with this data, but used for handlekillunit + { 11946,67,0,0}, //not spawned with this data, but used for handlekillunit + { 14763, 1534, 60, 60 }, //Dun Baldar South Marshal + { 14762, 1534, 60, 60 }, //Dun Baldar North Marshal + { 14764, 1534, 60, 60 }, //Icewing Marshal + { 14765, 1534, 60, 60 }, //Stonehearth Marshal + + { 14773, 1214, 60, 60 }, //Iceblood Warmaster + { 14776, 1214, 60, 60 }, //Tower Point Warmaster + { 14772, 1214, 60, 60 }, //East Frostwolf Warmaster + { 14777, 1214, 60, 60 }, //West Frostwolf Warmaster + + { 10987, 59, 52, 53 }, //Irondeep Trogg + { 11600, 59, 53, 54 }, //Irondeep Shaman + { 11602, 59, 54, 55 }, //Irondeep Skullthumper + { 11657, 59, 58, 58 }, //Morloch + + {13396,469,52,53}, //irondeep alliance TODO: get the right ids + {13080,469,53,54}, + {13098,469,54,55}, + {13078,469,58,58}, + + {13397,67,52,53}, //irondeep horde + {13099,67,53,54}, + {13081,67,54,55}, + {13079,67,58,58}, + + { 11603, 59, 52, 53 }, //south mine neutral + { 11604, 59, 53, 54 }, + { 11605, 59, 54, 55 }, + { 11677, 59, 58, 58 }, + { 10982, 59, 52, 53 }, //vermin + + {13317,469,52,53}, //alliance + {13096,469,54,55}, //explorer + {13087,469,54,55}, //invader + {13086,469,58,58}, + + {13316,67,52,53}, //horde + {13097,67,54,55}, //surveypr + {13089,67,54,55}, //guard + {13088,67,58,58}, + {14848,67,58,58} //Herald + +}; + +//x,y,z,o,static_creature_info-id +const float BG_AV_StaticCreaturePos[AV_STATICCPLACE_MAX][5] = { //static creatures + {-1235.31f,-340.777f,60.5088f,3.31613f,0 },//2225 - Zora Guthrek + {-1244.02f,-323.795f,61.0485f,5.21853f,1 },//3343 - Grelkor + {-1235.16f,-332.302f,60.2985f,2.96706f,2 },//3625 - Rarck + {587.303f,-42.8257f,37.5615f,5.23599f,3 },//4255 - Brogus Thunderbrew + {643.635f,-58.3987f,41.7405f,4.72984f,4 },//4257 - Lana Thunderbrew + {591.464f,-44.452f,37.6166f,5.65487f,5 },//5134 - Jonivera Farmountain + {608.515f,-33.3935f,42.0003f,5.41052f,6 },//5135 - Svalbrad Farmountain + {617.656f,-32.0701f,42.7168f,4.06662f,7 },//5139 - Kurdrum Barleybeard + {-1183.76f,-268.295f,72.8233f,3.28122f,8 },//10364 - Yaelika Farclaw + {-1187.86f,-275.31f,73.0481f,3.63028f,9 },//10367 - Shrye Ragefist + {-1008.42f,-368.006f,55.3426f,5.95647f,10 },//10981 - Frostwolf + {-1091.92f,-424.28f,53.0139f,2.93958f,10 },//10981 - Frostwolf + {-558.455f,-198.768f,58.1755f,4.97946f,10 },//10981 - Frostwolf + {-861.247f,-312.51f,55.1427f,3.35382f,10 },//10981 - Frostwolf + {-1003.81f,-395.913f,50.4736f,2.85631f,10 },//10981 - Frostwolf + {-904.5f,-289.815f,65.1222f,5.7847f,10 },//10981 - Frostwolf + {-1064.41f,-438.839f,51.3614f,1.88857f,10 },//10981 - Frostwolf + {258.814f,76.2017f,18.6468f,6.19052f,11 },//10986 - Snowblind Harpy + {265.838f,-315.846f,-16.5429f,3.15917f,11 },//10986 - Snowblind Harpy + {426.485f,-51.1927f,-5.66286f,1.60347f,11 },//10986 - Snowblind Harpy + {452.044f,-33.9594f,-0.044651f,2.72815f,11 },//10986 - Snowblind Harpy + {266.032f,-315.639f,-16.5429f,4.67962f,11 },//10986 - Snowblind Harpy + {532.64f,-54.5863f,20.7024f,2.93215f,11 },//10986 - Snowblind Harpy + {295.183f,-299.908f,-34.6123f,0.135851f,12 },//10990 - Alterac Ram + {421.08f,-225.006f,-23.73f,0.166754f,12 },//10990 - Alterac Ram + {-55.7766f,-192.498f,20.4352f,6.12221f,12 },//10990 - Alterac Ram + {527.887f,-477.223f,62.3559f,0.170935f,12 },//10990 - Alterac Ram + {389.144f,-346.508f,-30.334f,4.14117f,12 },//10990 - Alterac Ram + {108.121f,-322.248f,37.5655f,4.46788f,12 },//10990 - Alterac Ram + {507.479f,-67.9403f,10.3571f,3.26304f,12 },//10990 - Alterac Ram + {329.071f,-185.016f,-29.1542f,0.356943f,12 },//10990 - Alterac Ram + {252.449f,-422.313f,35.1404f,4.53771f,12 },//10990 - Alterac Ram + {358.882f,-118.061f,-24.9119f,2.29257f,12 },//10990 - Alterac Ram + {487.151f,-174.229f,14.7558f,4.73192f,12 },//10990 - Alterac Ram + {449.652f,-123.561f,6.14273f,6.12029f,12 },//10990 - Alterac Ram + {272.419f,-261.802f,-41.8835f,3.66559f,12 },//10990 - Alterac Ram + {359.021f,-210.954f,-29.3483f,4.31339f,12 },//10990 - Alterac Ram + {450.598f,-318.048f,-37.7548f,0.655219f,12 },//10990 - Alterac Ram + {509.333f,-218.2f,3.05439f,3.66292f,12 },//10990 - Alterac Ram + {485.771f,-223.613f,-1.53f,2.04862f,12 },//10990 - Alterac Ram + {486.636f,-452.172f,39.6592f,2.3341f,12 },//10990 - Alterac Ram + {702.783f,-257.494f,25.9777f,1.68329f,12 },//10990 - Alterac Ram + {460.942f,-199.263f,-6.0149f,0.380506f,12 },//10990 - Alterac Ram + {483.108f,-115.307f,10.1056f,3.69701f,12 },//10990 - Alterac Ram + {471.601f,-154.174f,14.0702f,5.5807f,12 },//10990 - Alterac Ram + {213.938f,-420.793f,41.2549f,5.71394f,12 },//10990 - Alterac Ram + {289.387f,-294.685f,-33.9073f,0.555494f,12 },//10990 - Alterac Ram + {155.649f,-402.891f,43.3915f,5.94838f,12 },//10990 - Alterac Ram + {517.184f,-295.105f,-9.78195f,6.05668f,12 },//10990 - Alterac Ram + {102.334f,-332.165f,38.9812f,3.31445f,12 },//10990 - Alterac Ram + {320.244f,-107.793f,-42.6357f,-1.00311f,12 },//10990 - Alterac Ram + {217.976f,110.774f,15.7603f,4.56793f,13 },//11675 - Snowblind Windcaller + {269.872f,6.66684f,20.7592f,0.381212f,13 },//11675 - Snowblind Windcaller + {313.528f,-319.041f,-27.2373f,0.554098f,13 },//11675 - Snowblind Windcaller + {435.441f,-39.9289f,-0.169651f,0.549454f,13 },//11675 - Snowblind Windcaller + {315.115f,-317.62f,-29.1123f,0.90111f,13 },//11675 - Snowblind Windcaller + {428.091f,-122.731f,3.40332f,6.05901f,14 },//11678 - Snowblind Ambusher + {235.05f,85.5705f,18.3079f,-0.914255f,14 },//11678 - Snowblind Ambusher + {-1553.04f,-344.342f,64.4163f,6.09933f,15 },//11839 - Wildpaw Brute + {-545.23f,-165.35f,57.7886f,3.01145f,16 },//11947 - Captain Galvangar + {722.43f,-10.9982f,50.7046f,3.42085f,17 },//11948 - Vanndar Stormpike + {-57.7891f,-286.597f,15.6479f,6.02139f,18 },//11949 - Captain Balinda Stonehearth + {930.498f,-520.755f,93.7334f,1.8326f,19 },//11997 - Stormpike Herald + {-776.092f,-345.161f,67.4092f,1.89257f,20 },//12051 - Frostwolf Legionnaire + {-1224.63f,-308.144f,65.0087f,4.01139f,20 },//12051 - Frostwolf Legionnaire + {-713.039f,-442.515f,82.8638f,0.68724f,20 },//12051 - Frostwolf Legionnaire + {-711.783f,-444.061f,82.7039f,0.683494f,20 },//12051 - Frostwolf Legionnaire + {587.633f,-45.9816f,37.5438f,5.81195f,21 },//12096 - Stormpike Quartermaster + {-1293.79f,-194.407f,72.4398f,5.84685f,22 },//12097 - Frostwolf Quartermaster + {446.163f,-377.119f,-1.12725f,0.209526f,23 },//12127 - Stormpike Guardsman + {549.348f,-399.254f,53.3537f,3.24729f,23 },//12127 - Stormpike Guardsman + {549.801f,-401.217f,53.8305f,3.24729f,23 },//12127 - Stormpike Guardsman + {192.704f,-406.874f,42.9183f,6.10696f,23 },//12127 - Stormpike Guardsman + {441.305f,-435.765f,28.2385f,2.14472f,23 },//12127 - Stormpike Guardsman + {192.982f,-404.891f,43.0132f,6.1061f,23 },//12127 - Stormpike Guardsman + {355.342f,-391.989f,-0.486707f,3.00643f,23 },//12127 - Stormpike Guardsman + {446.035f,-375.104f,-1.12725f,0.21033f,23 },//12127 - Stormpike Guardsman + {697.864f,-433.238f,62.7914f,1.65776f,23 },//12127 - Stormpike Guardsman + {610.74f,-331.585f,30.8021f,5.14253f,23 },//12127 - Stormpike Guardsman + {609.815f,-329.775f,30.9271f,-2.38829f,23 },//12127 - Stormpike Guardsman + {695.874f,-433.434f,62.8543f,1.65776f,23 },//12127 - Stormpike Guardsman + {443.337f,-435.283f,28.6842f,2.13768f,23 },//12127 - Stormpike Guardsman + {-1251.5f,-316.327f,62.6565f,5.02655f,24 },//13176 - Smith Regzar + {-1332.0f,-331.243f,91.2631f,1.50098f,25 },//13179 - Wing Commander Guse + {569.983f,-94.9992f,38.0325f,1.39626f,26 },//13216 - Gaelden Hammersmith + {-1244.92f,-308.916f,63.2525f,1.62316f,27 },//13218 - Grunnda Wolfheart + {-1319.56f,-342.675f,60.3404f,1.20428f,28 },//13236 - Primalist Thurloga + {647.61f,-61.1548f,41.7405f,4.24115f,29 },//13257 - Murgot Deepforge + {-1321.64f,-343.73f,60.4833f,1.01229f,30 },//13284 - Frostwolf Shaman + {-1317.61f,-342.853f,60.3726f,2.47837f,30 },//13284 - Frostwolf Shaman + {-1319.31f,-344.475f,60.3825f,1.72788f,30 },//13284 - Frostwolf Shaman + {569.963f,-42.0218f,37.7581f,4.27606f,31 },//13438 - Wing Commander Slidore + {729.2f,-78.812f,51.6335f,3.97935f,32 },//13442 - Arch Druid Renferal + {729.118f,-82.8713f,51.6335f,2.53073f,33 },//13443 - Druid of the Grove + {725.554f,-79.4973f,51.6335f,5.27089f,33 },//13443 - Druid of the Grove + {724.768f,-84.1642f,51.6335f,0.733038f,33 },//13443 - Druid of the Grove + {596.68f,-83.0633f,39.0051f,6.24828f,34 },//13447 - Corporal Noreg Stormpike + {600.032f,-2.92475f,42.0788f,5.00909f,35 },//13577 - Stormpike Ram Rider Commander + {610.239f,-21.8454f,43.272f,4.90438f,36 },//13617 - Stormpike Stable Master + {613.422f,-150.764f,33.4517f,5.55015f,37 },//13797 - Mountaineer Boombellow + {-1213.91f,-370.619f,56.4455f,0.837758f,38 },//13798 - Jotek + {704.35f,-22.9071f,50.2187f,0.785398f,39 },//13816 - Prospector Stonehewer + {-1271.24f,-335.766f,62.3971f,5.75959f,40 },//14185 - Najak Hexxen + {-1268.64f,-332.688f,62.6171f,5.28835f,41 },//14186 - Ravak Grimtotem + {648.363f,-65.2233f,41.7405f,3.12414f,42 },//14187 - Athramanis + {648.238f,-67.8931f,41.7405f,2.60054f,43 },//14188 - Dirk Swindle + {-1223.44f,-309.833f,64.9331f,4.0131f,44 },//14282 - Frostwolf Bloodhound + {-1226.4f,-307.136f,64.9706f,4.0145f,44 },//14282 - Frostwolf Bloodhound + {356.001f,-389.969f,-0.438796f,3.0334f,45 },//14283 - Stormpike Owl + {355.835f,-394.005f,-0.60149f,3.02498f,45 },//14283 - Stormpike Owl + {882.266f,-496.378f,96.7707f,4.83248f,45 },//14283 - Stormpike Owl + {878.649f,-495.917f,96.6171f,4.67693f,45 },//14283 - Stormpike Owl + {932.851f,-511.017f,93.6748f,3.61004f,45 },//14283 - Stormpike Owl + {935.806f,-513.983f,93.7436f,3.61788f,45 },//14283 - Stormpike Owl + {947.412f,-509.982f,95.1098f,2.82743f,46 },//14284 - Stormpike Battleguard + {934.557f,-512.395f,93.662f,3.61004f,46 },//14284 - Stormpike Battleguard + {939.42f,-502.777f,94.5887f,5.14872f,46 },//14284 - Stormpike Battleguard + {854.276f,-494.241f,96.8017f,5.44543f,46 },//14284 - Stormpike Battleguard + {776.621f,-487.775f,99.4049f,3.50811f,46 },//14284 - Stormpike Battleguard + {880.169f,-495.699f,96.6204f,4.8325f,46 },//14284 - Stormpike Battleguard + {773.651f,-497.482f,99.0408f,2.11185f,46 },//14284 - Stormpike Battleguard + {949.1f,-506.913f,95.4237f,3.31613f,46 },//14284 - Stormpike Battleguard + {-1370.9f,-219.793f,98.4258f,5.04381f,47}, //drek thar + +}; + +const uint32 BG_AV_StaticCreatureInfo[51][4] = { + { 2225, 1215, 55, 55 }, //Zora Guthrek + { 3343, 1215, 55, 55 }, //Grelkor + { 3625, 1215, 55, 55 }, //Rarck + { 4255, 1217, 55, 55 }, //Brogus Thunderbrew + { 4257, 1217, 55, 55 }, //Lana Thunderbrew + { 5134, 1217, 55, 55 }, //Jonivera Farmountain + { 5135, 1217, 55, 55 }, //Svalbrad Farmountain + { 5139, 1217, 55, 55 }, //Kurdrum Barleybeard + { 10364, 1215, 55, 55 }, //Yaelika Farclaw + { 10367, 1215, 55, 55 }, //Shrye Ragefist + { 10981, 38, 50, 51 }, //Frostwolf + { 10986, 514, 52, 53 }, //Snowblind Harpy + { 10990, 1274, 50, 51 }, //Alterac Ram + { 11675, 514, 53, 53 }, //Snowblind Windcaller + { 11678, 14, 52, 53 }, //Snowblind Ambusher + { 11839, 39, 56, 56 }, //Wildpaw Brute + { 11947, 1214, 61, 61 }, //Captain Galvangar --TODO: doubled + { 11948, 1216, 63, 63 }, //Vanndar Stormpike + { 11949, 1216, 61, 61 }, //Captain Balinda Stonehearth + { 11997, 1334, 60, 60 }, //Stormpike Herald + { 12051, 1214, 57, 57 }, //Frostwolf Legionnaire + { 12096, 1217, 55, 55 }, //Stormpike Quartermaster + { 12097, 1215, 55, 55 }, //Frostwolf Quartermaster + { 12127, 1216, 57, 57 }, //Stormpike Guardsman + { 13176, 1215, 60, 60 }, //Smith Regzar + { 13179, 1215, 59, 59 }, //Wing Commander Guse + { 13216, 1217, 58, 58 }, //Gaelden Hammersmith + { 13218, 1215, 58, 58 }, //Grunnda Wolfheart + { 13236, 1214, 60, 60 }, //Primalist Thurloga + { 13257, 1216, 60, 60 }, //Murgot Deepforge + { 13284, 1214, 58, 58 }, //Frostwolf Shaman + { 13438, 1217, 58, 58 }, //Wing Commander Slidore + { 13442, 1216, 60, 60 }, //Arch Druid Renferal + { 13443, 1216, 60, 60 }, //Druid of the Grove + { 13447, 1216, 58, 58 }, //Corporal Noreg Stormpike + { 13577, 1216, 60, 60 }, //Stormpike Ram Rider Commander + { 13617, 1216, 60, 60 }, //Stormpike Stable Master + { 13797, 32, 60, 61 }, //Mountaineer Boombellow + { 13798, 1214, 60, 61 }, //Jotek + { 13816, 1216, 61, 61 }, //Prospector Stonehewer + { 14185, 877, 59, 59 }, //Najak Hexxen + { 14186, 105, 60, 60 }, //Ravak Grimtotem + { 14187, 1594, 60, 60 }, //Athramanis + { 14188, 57, 59, 59 }, //Dirk Swindle + { 14282, 1214, 53, 54 }, //Frostwolf Bloodhound + { 14283, 1216, 53, 54 }, //Stormpike Owl + { 14284, 1216, 61, 61 }, //Stormpike Battleguard + { 11946, 1214, 63, 63 }, //Drek'Thar //TODO: make the levels right (boss=0 maybe) + { 11948, 1216, 63, 63 }, //Vanndar Stormpike + { 11947, 1214, 61, 61 }, //Captain Galvangar + { 11949, 1216, 61, 61 } //Captain Balinda Stonehearth +}; + +enum BG_AV_Graveyards +{ + AV_GRAVE_STORM_AID = 751, + AV_GRAVE_STORM_GRAVE = 689, + AV_GRAVE_STONE_GRAVE = 729, + AV_GRAVE_SNOWFALL = 169, + AV_GRAVE_ICE_GRAVE = 749, + AV_GRAVE_FROSTWOLF = 690, + AV_GRAVE_FROST_HUT = 750, + AV_GRAVE_MAIN_ALLIANCE = 611, + AV_GRAVE_MAIN_HORDE = 610 +}; + + + +const uint32 BG_AV_GraveyardIds[9]= { + AV_GRAVE_STORM_AID, + AV_GRAVE_STORM_GRAVE, + AV_GRAVE_STONE_GRAVE, + AV_GRAVE_SNOWFALL, + AV_GRAVE_ICE_GRAVE, + AV_GRAVE_FROSTWOLF, + AV_GRAVE_FROST_HUT, + AV_GRAVE_MAIN_ALLIANCE, + AV_GRAVE_MAIN_HORDE +}; + +enum BG_AV_BUFF +{ //TODO add all other buffs here + AV_BUFF_ARMOR = 21163, + AV_BUFF_A_CAPTAIN = 23693, //the buff which the alliance captain does + AV_BUFF_H_CAPTAIN = 22751 //the buff which the horde captain does +}; +enum BG_AV_States +{ + POINT_NEUTRAL = 0, + POINT_ASSAULTED = 1, + POINT_DESTROYED = 2, + POINT_CONTROLED = 3 +}; + +enum BG_AV_WorldStates +{ + AV_Alliance_Score = 3127, + AV_Horde_Score = 3128, + AV_SHOW_H_SCORE = 3133, + AV_SHOW_A_SCORE = 3134, + +/* + //the comments behind the state shows which icon overlaps the other.. but is, until now, unused and maybe not a good solution (but give few performance (: ) + +// Graves + + // Alliance + //Stormpike first aid station + AV_AID_A_C = 1325, + AV_AID_A_A = 1326, + AV_AID_H_C = 1327, + AV_AID_H_A = 1328, + //Stormpike Graveyard + AV_PIKEGRAVE_A_C = 1333, + AV_PIKEGRAVE_A_A = 1335, + AV_PIKEGRAVE_H_C = 1334, + AV_PIKEGRAVE_H_A = 1336, + //Stoneheart Grave + AV_STONEHEART_A_C = 1302, + AV_STONEHEART_A_A = 1304, //over hc + AV_STONEHEART_H_C = 1301, //over ac + AV_STONEHEART_H_A = 1303, //over aa + //Neutral + //Snowfall Grave +*/ + AV_SNOWFALL_N = 1966, //over aa +/* + AV_SNOWFALL_A_C = 1341, //over hc + AV_SNOWFALL_A_A = 1343, //over ha + AV_SNOWFALL_H_C = 1342, + AV_SNOWFALL_H_A = 1344, //over ac + //Horde + //Iceblood grave + AV_ICEBLOOD_A_C = 1346, //over hc + AV_ICEBLOOD_A_A = 1348, //over ac + AV_ICEBLOOD_H_C = 1347, + AV_ICEBLOOD_H_A = 1349, //over aa + //Frostwolf Grave + AV_FROSTWOLF_A_C = 1337, //over hc + AV_FROSTWOLF_A_A = 1339, //over ac + AV_FROSTWOLF_H_C = 1338, + AV_FROSTWOLF_H_A = 1340, //over aa + //Frostwolf Hut + AV_FROSTWOLFHUT_A_C = 1329, //over hc + AV_FROSTWOLFHUT_A_A = 1331, //over ha + AV_FROSTWOLFHUT_H_C = 1330, + AV_FROSTWOLFHUT_H_A = 1332, //over ac + + +//Towers + //Alliance + //Dunbaldar South Bunker + AV_DUNS_CONTROLLED = 1361, + AV_DUNS_DESTROYED = 1370, + AV_DUNS_ASSAULTED = 1378, + //Dunbaldar North Bunker + AV_DUNN_CONTROLLED = 1362, + AV_DUNN_DESTROYED = 1371, + AV_DUNN_ASSAULTED = 1379, + //Icewing Bunker + AV_ICEWING_CONTROLLED = 1363, + AV_ICEWING_DESTROYED = 1372, + AV_ICEWING_ASSAULTED = 1380, + //Stoneheart Bunker + AV_STONEH_CONTROLLED = 1364, + AV_STONEH_DESTROYED = 1373, + AV_STONEH_ASSAULTED = 1381, + //Horde + //Iceblood Tower + AV_ICEBLOOD_CONTROLLED = 1385, + AV_ICEBLOOD_DESTROYED = 1368, + AV_ICEBLOOD_ASSAULTED = 1390, + //Tower Point + AV_TOWERPOINT_CONTROLLED = 1384, + AV_TOWERPOINT_DESTROYED = 1367, //goes over controlled + AV_TOWERPOINT_ASSAULTED = 1389, //goes over destroyed + //Frostwolf West + AV_FROSTWOLFW_CONTROLLED = 1382, + AV_FROSTWOLFW_DESTROYED = 1365, //over controlled + AV_FROSTWOLFW_ASSAULTED = 1387, //over destroyed + //Frostwolf East + AV_FROSTWOLFE_CONTROLLED = 1383, + AV_FROSTWOLFE_DESTROYED = 1366, + AV_FROSTWOLFE_ASSAULTED = 1388, + +//mines + + AV_N_MINE_N = 1360, + AV_N_MINE_A = 1358, + AV_N_MINE_H = 1359, + + AV_S_MINE_N = 1357, + AV_S_MINE_A = 1355, + AV_S_MINE_H = 1356, + +//towers assaulted by own team (unused) + AV_STONEH_UNUSED = 1377, + AV_ICEWING_UNUSED = 1376, + AV_DUNS_UNUSED = 1375, + AV_DUNN_UNUSED = 1374, + + AV_ICEBLOOD_UNUSED = 1395, + AV_TOWERPOINT_UNUSED = 1394, + AV_FROSTWOLFE_UNUSED = 1393, + AV_FROSTWOLFW_UNUSED = 1392 +*/ + +}; + +//alliance_control neutral_control horde_control +const uint32 BG_AV_MineWorldStates[2][3] = { + {1358, 1360,1359}, + {1355, 1357,1356} +}; + + +//alliance_control alliance_assault h_control h_assault +const uint32 BG_AV_NodeWorldStates[16][4] = { + //Stormpike first aid station + {1325, 1326,1327,1328}, + //Stormpike Graveyard + {1333,1335,1334,1336}, + //Stoneheart Grave + {1302,1304,1301,1303}, + //Snowfall Grave + {1341,1343,1342,1344}, + //Iceblood grave + {1346,1348,1347,1349}, + //Frostwolf Grave + {1337,1339,1338,1340}, + //Frostwolf Hut + {1329,1331,1330,1332}, + //Dunbaldar South Bunker + {1361,1375,1370,1378}, + //Dunbaldar North Bunker + {1362,1374,1371,1379}, + //Icewing Bunker + {1363,1376,1372,1380}, + //Stoneheart Bunker + {1364,1377,1373,1381}, + //Iceblood Tower + {1368,1390,1385,1395}, + //Tower Point + {1367,1389,1384,1394}, + //Frostwolf East + {1366,1388,1383,1393}, + //Frostwolf West + {1365,1387,1382,1392}, +}; + +enum BG_AV_QuestIds +{ + AV_QUEST_A_SCRAPS1 = 7223, + AV_QUEST_A_SCRAPS2 = 6781, + AV_QUEST_H_SCRAPS1 = 7224, + AV_QUEST_H_SCRAPS2 = 6741, + AV_QUEST_A_COMMANDER1 = 6942, //soldier + AV_QUEST_H_COMMANDER1 = 6825, + AV_QUEST_A_COMMANDER2 = 6941, //leutnant + AV_QUEST_H_COMMANDER2 = 6826, + AV_QUEST_A_COMMANDER3 = 6943, //commander + AV_QUEST_H_COMMANDER3 = 6827, + AV_QUEST_A_BOSS1 = 7386, // 5 cristal/blood + AV_QUEST_H_BOSS1 = 7385, + AV_QUEST_A_BOSS2 = 6881, // 1 + AV_QUEST_H_BOSS2 = 6801, + AV_QUEST_A_NEAR_MINE = 5892, //the mine near start location of team + AV_QUEST_H_NEAR_MINE = 5893, + AV_QUEST_A_OTHER_MINE = 6982, //the other mine ;) + AV_QUEST_H_OTHER_MINE = 6985, + AV_QUEST_A_RIDER_HIDE = 7026, + AV_QUEST_H_RIDER_HIDE = 7002, + AV_QUEST_A_RIDER_TAME = 7027, + AV_QUEST_H_RIDER_TAME = 7001 +}; + +struct BG_AV_NodeInfo +{ + uint16 TotalOwner; + uint16 Owner; + uint16 PrevOwner; + BG_AV_States State; + BG_AV_States PrevState; + int Timer; + bool Tower; +}; + +inline BG_AV_Nodes &operator++(BG_AV_Nodes &i){ return i = BG_AV_Nodes(i + 1); } + class BattleGroundAVScore : public BattleGroundScore { public: @@ -51,11 +1507,75 @@ class BattleGroundAV : public BattleGround void RemovePlayer(Player *plr,uint64 guid); void HandleAreaTrigger(Player *Source, uint32 Trigger); - //bool SetupBattleGround(); + bool SetupBattleGround(); + virtual void ResetBGSubclass(); - /* Scorekeeping */ - void UpdatePlayerScore(Player *Source, uint32 type, uint32 value); + /*general stuff*/ + void UpdateScore(uint16 team, int16 points); + void UpdatePlayerScore(Player *Source, uint32 type, uint32 value); + + /*handlestuff*/ //these are functions which get called from extern + virtual void EventPlayerClickedOnFlag(Player *source, GameObject* target_obj); + void HandleKillPlayer(Player* player, Player *killer); + void HandleKillUnit(Creature *unit, Player *killer); + void HandleQuestComplete(uint32 questid, Player *player); + bool PlayerCanDoMineQuest(int32 GOId,uint32 team); + + + void EndBattleGround(uint32 winner); + + virtual WorldSafeLocsEntry const* GetClosestGraveYard(float x, float y, float z, uint32 team); private: + /* Nodes occupying */ + void EventPlayerAssaultsPoint(Player* player, uint32 object); + void EventPlayerDefendsPoint(Player* player, uint32 object); + void EventPlayerDestroyedPoint(BG_AV_Nodes node); + + void AssaultNode(BG_AV_Nodes node,uint16 team); + void DestroyNode(BG_AV_Nodes node); + void InitNode(BG_AV_Nodes node, uint16 team, bool tower); + void DefendNode(BG_AV_Nodes node, uint16 team); + + void PopulateNode(BG_AV_Nodes node); + void DePopulateNode(BG_AV_Nodes node); + + const BG_AV_Nodes GetNodeThroughObject(uint32 object); + const uint32 GetObjectThroughNode(BG_AV_Nodes node); + const char* GetNodeName(BG_AV_Nodes node); + const bool IsTower(BG_AV_Nodes node) { return m_Nodes[node].Tower; } + + + /*mine*/ + void ChangeMineOwner(uint8 mine, uint32 team, bool initial=false); + + /*worldstates*/ + void FillInitialWorldStates(WorldPacket& data); + const uint8 GetWorldStateType(uint8 state, uint16 team); + void SendMineWorldStates(uint32 mine); + void UpdateNodeWorldState(BG_AV_Nodes node); + + /*general */ + Creature* AddAVCreature(uint16 cinfoid, uint16 type); + const uint16 GetBonusHonor(uint8 kills); //TODO remove this when mangos handles this right + + /*variables */ + int32 m_Team_Scores[2]; + uint32 m_Team_QuestStatus[2][9]; //[x][y] x=team y=questcounter + + BG_AV_NodeInfo m_Nodes[BG_AV_NODES_MAX]; + + uint32 m_Mine_Owner[2]; + uint32 m_Mine_PrevOwner[2]; //only for worldstates needed + int32 m_Mine_Timer; //ticks for both teams + uint32 m_Mine_Reclaim_Timer[2]; + uint32 m_CaptainBuffTimer[2]; + bool m_CaptainAlive[2]; + + uint8 m_MaxLevel; //TODO remove this when battleground-getmaxlevel() returns something usefull + bool m_IsInformedNearVictory[2]; + + }; + #endif diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp index 91eb04b07f5..24b4f4e141b 100644 --- a/src/game/Creature.cpp +++ b/src/game/Creature.cpp @@ -577,6 +577,7 @@ bool Creature::Create (uint32 guidlow, Map *map, uint32 Entry, uint32 team, cons { SetMapId(map->GetId()); SetInstanceId(map->GetInstanceId()); + m_DBTableGuid = guidlow; //oX = x; oY = y; dX = x; dY = y; m_moveTime = 0; m_startMove = 0; const bool bResult = CreateFromProto(guidlow, Entry, team, data); @@ -603,7 +604,6 @@ bool Creature::Create (uint32 guidlow, Map *map, uint32 Entry, uint32 team, cons } LoadCreaturesAddon(); } - return bResult; } diff --git a/src/game/Creature.h b/src/game/Creature.h index 5d0ca5b5946..5f2d6e249f7 100644 --- a/src/game/Creature.h +++ b/src/game/Creature.h @@ -611,7 +611,6 @@ class TRINITY_DLL_SPEC Creature : public Unit void GetCombatStartPosition(float &x, float &y, float &z) { x = CombatStartX; y = CombatStartY; z = CombatStartZ; } uint32 GetGlobalCooldown() const { return m_GlobalCooldown; } - protected: bool CreateFromProto(uint32 guidlow,uint32 Entry,uint32 team, const CreatureData *data = NULL); bool InitEntry(uint32 entry, uint32 team=ALLIANCE, const CreatureData* data=NULL); @@ -660,6 +659,7 @@ class TRINITY_DLL_SPEC Creature : public Unit float CombatStartX; float CombatStartY; float CombatStartZ; + private: GridReference<Creature> m_gridRef; CreatureInfo const* m_creatureInfo; // in heroic mode can different from ObjMgr::GetCreatureTemplate(GetEntry()) diff --git a/src/game/GameObject.cpp b/src/game/GameObject.cpp index f6f89f482e5..3a11bf95c35 100644 --- a/src/game/GameObject.cpp +++ b/src/game/GameObject.cpp @@ -37,8 +37,9 @@ #include "CellImpl.h" #include "InstanceData.h" #include "BattleGround.h" -#include "OutdoorPvPMgr.h" #include "Util.h" +#include "OutdoorPvPMgr.h" +#include "BattleGroundAV.h" GameObject::GameObject() : WorldObject() { @@ -754,7 +755,15 @@ bool GameObject::ActivateToQuest( Player *pTarget)const case GAMEOBJECT_TYPE_CHEST: { if(LootTemplates_Gameobject.HaveQuestLootForPlayer(GetLootId(), pTarget)) + { + //TODO: fix this hack + //look for battlegroundAV for some objects which are only activated after mine gots captured by own team + if(GetEntry() == BG_AV_OBJECTID_MINE_N || GetEntry() == BG_AV_OBJECTID_MINE_S) + if(BattleGround *bg = pTarget->GetBattleGround()) + if(bg->GetTypeID() == BATTLEGROUND_AV && !(((BattleGroundAV*)bg)->PlayerCanDoMineQuest(GetEntry(),pTarget->GetTeam()))) + return false; return true; + } break; } case GAMEOBJECT_TYPE_GOOBER: diff --git a/src/game/Language.h b/src/game/Language.h index fb44f37dda5..fc20f1725fd 100644 --- a/src/game/Language.h +++ b/src/game/Language.h @@ -644,7 +644,45 @@ enum TrinityStrings LANG_HIS_ARENA_LEVEL_REQ_ERROR = 714, LANG_YOUR_BG_LEVEL_REQ_ERROR = 715, LANG_YOUR_ARENA_TEAM_FULL = 716, - // Room for BG/ARENA 717-799 not used + + LANG_BG_AV_ALLY = 717, + LANG_BG_AV_HORDE = 718, + LANG_BG_AV_TOWER_TAKEN = 719, + LANG_BG_AV_TOWER_ASSAULTED = 720, + LANG_BG_AV_TOWER_DEFENDED = 721, + LANG_BG_AV_GRAVE_TAKEN = 722, + LANG_BG_AV_GRAVE_DEFENDED = 723, + LANG_BG_AV_GRAVE_ASSAULTED = 724, + + LANG_BG_AV_MINE_TAKEN = 725, + LANG_BG_AV_MINE_NORTH = 726, + LANG_BG_AV_MINE_SOUTH = 727, + + LANG_BG_AV_NODE_GRAVE_STORM_AID = 728, + LANG_BG_AV_NODE_TOWER_DUN_S = 729, + LANG_BG_AV_NODE_TOWER_DUN_N = 730, + LANG_BG_AV_NODE_GRAVE_STORMPIKE = 731, + LANG_BG_AV_NODE_TOWER_ICEWING = 732, + LANG_BG_AV_NODE_GRAVE_STONE = 733, + LANG_BG_AV_NODE_TOWER_STONE = 734, + LANG_BG_AV_NODE_GRAVE_SNOW = 735, + LANG_BG_AV_NODE_TOWER_ICE = 736, + LANG_BG_AV_NODE_GRAVE_ICE = 737, + LANG_BG_AV_NODE_TOWER_POINT = 738, + LANG_BG_AV_NODE_GRAVE_FROST = 739, + LANG_BG_AV_NODE_TOWER_FROST_E = 740, + LANG_BG_AV_NODE_TOWER_FROST_W = 741, + LANG_BG_AV_NODE_GRAVE_FROST_HUT = 742, + + LANG_BG_AV_ONEMINTOSTART = 743, + LANG_BG_AV_HALFMINTOSTART = 744, + LANG_BG_AV_STARTED = 745, + LANG_BG_AV_A_NEAR_LOSE = 746, + LANG_BG_AV_H_NEAR_LOSE = 747, + LANG_BG_AV_H_CAPTAIN_DEAD = 748, + LANG_BG_AV_A_CAPTAIN_DEAD = 749, + + // Room for BG/ARENA 750-799 not used LANG_ARENA_YOUR_TEAM_ONLY = 730, LANG_ARENA_NOT_ENOUGH_PLAYERS = 731, diff --git a/src/game/LootHandler.cpp b/src/game/LootHandler.cpp index 4894b3aabeb..a4a8a7a1f01 100644 --- a/src/game/LootHandler.cpp +++ b/src/game/LootHandler.cpp @@ -70,6 +70,16 @@ void WorldSession::HandleAutostoreLootItemOpcode( WorldPacket & recv_data ) loot = &pItem->loot; } + else if (IS_CORPSE_GUID(lguid)) + { + Corpse *bones = ObjectAccessor::GetCorpse(*player, lguid); + if (!bones) + { + player->SendLootRelease(lguid); + return; + } + loot = &bones->loot; + } else { Creature* pCreature = diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 11ffba972a3..13f37a50b05 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -54,6 +54,7 @@ #include "Transports.h" #include "Weather.h" #include "BattleGround.h" +#include "BattleGroundAV.h" #include "BattleGroundMgr.h" #include "OutdoorPvP.h" #include "OutdoorPvPMgr.h" @@ -4160,7 +4161,7 @@ void Player::RepopAtGraveyard() // Special handle for battleground maps BattleGround *bg = sBattleGroundMgr.GetBattleGround(GetBattleGroundId()); - if(bg && (bg->GetTypeID() == BATTLEGROUND_AB || bg->GetTypeID() == BATTLEGROUND_EY)) + if(bg && (bg->GetTypeID() == BATTLEGROUND_AB || bg->GetTypeID() == BATTLEGROUND_EY || bg->GetTypeID() == BATTLEGROUND_AV)) ClosestGrave = bg->GetClosestGraveYard(GetPositionX(), GetPositionY(), GetPositionZ(), GetTeam()); else ClosestGrave = objmgr.GetClosestGraveYard( GetPositionX(), GetPositionY(), GetPositionZ(), GetMapId(), GetTeam() ); @@ -7215,6 +7216,16 @@ void Player::SendLoot(uint64 guid, LootType loot_type) { uint32 lootid = go->GetLootId(); + //TODO: fix this big hack + if((go->GetEntry() == BG_AV_OBJECTID_MINE_N || go->GetEntry() == BG_AV_OBJECTID_MINE_S)) + if( BattleGround *bg = GetBattleGround()) + if(bg->GetTypeID() == BATTLEGROUND_AV) + if(!(((BattleGroundAV*)bg)->PlayerCanDoMineQuest(go->GetEntry(),GetTeam()))) + { + SendLootRelease(guid); + return; + } + if(lootid) { sLog.outDebug(" if(lootid)"); @@ -7291,6 +7302,8 @@ void Player::SendLoot(uint64 guid, LootType loot_type) bones->lootForBody = true; uint32 pLevel = bones->loot.gold; bones->loot.clear(); + if(GetBattleGround()->GetTypeID() == BATTLEGROUND_AV) + loot->FillLoot(1, LootTemplates_Creature, this); // It may need a better formula // Now it works like this: lvl10: ~6copper, lvl70: ~9silver bones->loot.gold = (uint32)( urand(50, 150) * 0.016f * pow( ((float)pLevel)/5.76f, 2.5f) * sWorld.getRate(RATE_DROP_MONEY) ); @@ -7664,81 +7677,86 @@ void Player::SendInitWorldStates(bool forceZone, uint32 forceZoneId) } break; case 2597: // AV - data << uint32(0x7ae) << uint32(0x1); // 7 - data << uint32(0x532) << uint32(0x1); // 8 - data << uint32(0x531) << uint32(0x0); // 9 - data << uint32(0x52e) << uint32(0x0); // 10 - data << uint32(0x571) << uint32(0x0); // 11 - data << uint32(0x570) << uint32(0x0); // 12 - data << uint32(0x567) << uint32(0x1); // 13 - data << uint32(0x566) << uint32(0x1); // 14 - data << uint32(0x550) << uint32(0x1); // 15 - data << uint32(0x544) << uint32(0x0); // 16 - data << uint32(0x536) << uint32(0x0); // 17 - data << uint32(0x535) << uint32(0x1); // 18 - data << uint32(0x518) << uint32(0x0); // 19 - data << uint32(0x517) << uint32(0x0); // 20 - data << uint32(0x574) << uint32(0x0); // 21 - data << uint32(0x573) << uint32(0x0); // 22 - data << uint32(0x572) << uint32(0x0); // 23 - data << uint32(0x56f) << uint32(0x0); // 24 - data << uint32(0x56e) << uint32(0x0); // 25 - data << uint32(0x56d) << uint32(0x0); // 26 - data << uint32(0x56c) << uint32(0x0); // 27 - data << uint32(0x56b) << uint32(0x0); // 28 - data << uint32(0x56a) << uint32(0x1); // 29 - data << uint32(0x569) << uint32(0x1); // 30 - data << uint32(0x568) << uint32(0x1); // 13 - data << uint32(0x565) << uint32(0x0); // 32 - data << uint32(0x564) << uint32(0x0); // 33 - data << uint32(0x563) << uint32(0x0); // 34 - data << uint32(0x562) << uint32(0x0); // 35 - data << uint32(0x561) << uint32(0x0); // 36 - data << uint32(0x560) << uint32(0x0); // 37 - data << uint32(0x55f) << uint32(0x0); // 38 - data << uint32(0x55e) << uint32(0x0); // 39 - data << uint32(0x55d) << uint32(0x0); // 40 - data << uint32(0x3c6) << uint32(0x4); // 41 - data << uint32(0x3c4) << uint32(0x6); // 42 - data << uint32(0x3c2) << uint32(0x4); // 43 - data << uint32(0x516) << uint32(0x1); // 44 - data << uint32(0x515) << uint32(0x0); // 45 - data << uint32(0x3b6) << uint32(0x6); // 46 - data << uint32(0x55c) << uint32(0x0); // 47 - data << uint32(0x55b) << uint32(0x0); // 48 - data << uint32(0x55a) << uint32(0x0); // 49 - data << uint32(0x559) << uint32(0x0); // 50 - data << uint32(0x558) << uint32(0x0); // 51 - data << uint32(0x557) << uint32(0x0); // 52 - data << uint32(0x556) << uint32(0x0); // 53 - data << uint32(0x555) << uint32(0x0); // 54 - data << uint32(0x554) << uint32(0x1); // 55 - data << uint32(0x553) << uint32(0x1); // 56 - data << uint32(0x552) << uint32(0x1); // 57 - data << uint32(0x551) << uint32(0x1); // 58 - data << uint32(0x54f) << uint32(0x0); // 59 - data << uint32(0x54e) << uint32(0x0); // 60 - data << uint32(0x54d) << uint32(0x1); // 61 - data << uint32(0x54c) << uint32(0x0); // 62 - data << uint32(0x54b) << uint32(0x0); // 63 - data << uint32(0x545) << uint32(0x0); // 64 - data << uint32(0x543) << uint32(0x1); // 65 - data << uint32(0x542) << uint32(0x0); // 66 - data << uint32(0x540) << uint32(0x0); // 67 - data << uint32(0x53f) << uint32(0x0); // 68 - data << uint32(0x53e) << uint32(0x0); // 69 - data << uint32(0x53d) << uint32(0x0); // 70 - data << uint32(0x53c) << uint32(0x0); // 71 - data << uint32(0x53b) << uint32(0x0); // 72 - data << uint32(0x53a) << uint32(0x1); // 73 - data << uint32(0x539) << uint32(0x0); // 74 - data << uint32(0x538) << uint32(0x0); // 75 - data << uint32(0x537) << uint32(0x0); // 76 - data << uint32(0x534) << uint32(0x0); // 77 - data << uint32(0x533) << uint32(0x0); // 78 - data << uint32(0x530) << uint32(0x0); // 79 - data << uint32(0x52f) << uint32(0x0); // 80 - data << uint32(0x52d) << uint32(0x1); // 81 + if (bg && bg->GetTypeID() == BATTLEGROUND_AV) + bg->FillInitialWorldStates(data); + else + { + data << uint32(0x7ae) << uint32(0x1); // 7 snowfall n + data << uint32(0x532) << uint32(0x1); // 8 frostwolfhut hc + data << uint32(0x531) << uint32(0x0); // 9 frostwolfhut ac + data << uint32(0x52e) << uint32(0x0); // 10 stormpike firstaid a_a + data << uint32(0x571) << uint32(0x0); // 11 east frostwolf tower horde assaulted -unused + data << uint32(0x570) << uint32(0x0); // 12 west frostwolf tower horde assaulted - unused + data << uint32(0x567) << uint32(0x1); // 13 frostwolfe c + data << uint32(0x566) << uint32(0x1); // 14 frostwolfw c + data << uint32(0x550) << uint32(0x1); // 15 irondeep (N) ally + data << uint32(0x544) << uint32(0x0); // 16 ice grave a_a + data << uint32(0x536) << uint32(0x0); // 17 stormpike grave h_c + data << uint32(0x535) << uint32(0x1); // 18 stormpike grave a_c + data << uint32(0x518) << uint32(0x0); // 19 stoneheart grave a_a + data << uint32(0x517) << uint32(0x0); // 20 stoneheart grave h_a + data << uint32(0x574) << uint32(0x0); // 21 1396 unk + data << uint32(0x573) << uint32(0x0); // 22 iceblood tower horde assaulted -unused + data << uint32(0x572) << uint32(0x0); // 23 towerpoint horde assaulted - unused + data << uint32(0x56f) << uint32(0x0); // 24 1391 unk + data << uint32(0x56e) << uint32(0x0); // 25 iceblood a + data << uint32(0x56d) << uint32(0x0); // 26 towerp a + data << uint32(0x56c) << uint32(0x0); // 27 frostwolfe a + data << uint32(0x56b) << uint32(0x0); // 28 froswolfw a + data << uint32(0x56a) << uint32(0x1); // 29 1386 unk + data << uint32(0x569) << uint32(0x1); // 30 iceblood c + data << uint32(0x568) << uint32(0x1); // 31 towerp c + data << uint32(0x565) << uint32(0x0); // 32 stoneh tower a + data << uint32(0x564) << uint32(0x0); // 33 icewing tower a + data << uint32(0x563) << uint32(0x0); // 34 dunn a + data << uint32(0x562) << uint32(0x0); // 35 duns a + data << uint32(0x561) << uint32(0x0); // 36 stoneheart bunker alliance assaulted - unused + data << uint32(0x560) << uint32(0x0); // 37 icewing bunker alliance assaulted - unused + data << uint32(0x55f) << uint32(0x0); // 38 dunbaldar south alliance assaulted - unused + data << uint32(0x55e) << uint32(0x0); // 39 dunbaldar north alliance assaulted - unused + data << uint32(0x55d) << uint32(0x0); // 40 stone tower d + data << uint32(0x3c6) << uint32(0x0); // 41 966 unk + data << uint32(0x3c4) << uint32(0x0); // 42 964 unk + data << uint32(0x3c2) << uint32(0x0); // 43 962 unk + data << uint32(0x516) << uint32(0x1); // 44 stoneheart grave a_c + data << uint32(0x515) << uint32(0x0); // 45 stonheart grave h_c + data << uint32(0x3b6) << uint32(0x0); // 46 950 unk + data << uint32(0x55c) << uint32(0x0); // 47 icewing tower d + data << uint32(0x55b) << uint32(0x0); // 48 dunn d + data << uint32(0x55a) << uint32(0x0); // 49 duns d + data << uint32(0x559) << uint32(0x0); // 50 1369 unk + data << uint32(0x558) << uint32(0x0); // 51 iceblood d + data << uint32(0x557) << uint32(0x0); // 52 towerp d + data << uint32(0x556) << uint32(0x0); // 53 frostwolfe d + data << uint32(0x555) << uint32(0x0); // 54 frostwolfw d + data << uint32(0x554) << uint32(0x1); // 55 stoneh tower c + data << uint32(0x553) << uint32(0x1); // 56 icewing tower c + data << uint32(0x552) << uint32(0x1); // 57 dunn c + data << uint32(0x551) << uint32(0x1); // 58 duns c + data << uint32(0x54f) << uint32(0x0); // 59 irondeep (N) horde + data << uint32(0x54e) << uint32(0x0); // 60 irondeep (N) ally + data << uint32(0x54d) << uint32(0x1); // 61 mine (S) neutral + data << uint32(0x54c) << uint32(0x0); // 62 mine (S) horde + data << uint32(0x54b) << uint32(0x0); // 63 mine (S) ally + data << uint32(0x545) << uint32(0x0); // 64 iceblood h_a + data << uint32(0x543) << uint32(0x1); // 65 iceblod h_c + data << uint32(0x542) << uint32(0x0); // 66 iceblood a_c + data << uint32(0x540) << uint32(0x0); // 67 snowfall h_a + data << uint32(0x53f) << uint32(0x0); // 68 snowfall a_a + data << uint32(0x53e) << uint32(0x0); // 69 snowfall h_c + data << uint32(0x53d) << uint32(0x0); // 70 snowfall a_c + data << uint32(0x53c) << uint32(0x0); // 71 frostwolf g h_a + data << uint32(0x53b) << uint32(0x0); // 72 frostwolf g a_a + data << uint32(0x53a) << uint32(0x1); // 73 frostwolf g h_c + data << uint32(0x539) << uint32(0x0); // 74 frostwolf g a_c + data << uint32(0x538) << uint32(0x0); // 75 stormpike grave h_a + data << uint32(0x537) << uint32(0x0); // 76 stormpike grave a_a + data << uint32(0x534) << uint32(0x0); // 77 frostwolf hut h_a + data << uint32(0x533) << uint32(0x0); // 78 frostwolf hut a_a + data << uint32(0x530) << uint32(0x0); // 79 stormpike first aid h_a + data << uint32(0x52f) << uint32(0x0); // 80 stormpike first aid h_c + data << uint32(0x52d) << uint32(0x1); // 81 stormpike first aid a_c + } break; case 3277: // WS if (bg && bg->GetTypeID() == BATTLEGROUND_WS) @@ -13350,7 +13368,8 @@ bool Player::HasQuestForItem( uint32 itemid ) const // hide quest if player is in raid-group and quest is no raid quest if(GetGroup() && GetGroup()->isRaidGroup() && qinfo->GetType() != QUEST_TYPE_RAID) - continue; + if(!InBattleGround()) //there are two ways.. we can make every bg-quest a raidquest, or add this code here.. i don't know if this can be exploited by other quests, but i think all other quests depend on a specific area.. but keep this in mind, if something strange happens later + continue; // There should be no mixed ReqItem/ReqSource drop // This part for ReqItem drop @@ -18045,6 +18064,7 @@ uint32 Player::GetMaxLevelForBattleGroundQueueId(uint32 queue_id) return 10*(queue_id+2)-1; } +//TODO make this more generic - current implementation is wrong uint32 Player::GetBattleGroundQueueIdFromLevel() const { uint32 level = getLevel(); @@ -18700,70 +18720,70 @@ bool ItemPosCount::isContainedIn(ItemPosCountVec const& vec) const //-------------TRINITY--------------- //*********************************** -void Player::HandleFallDamage(MovementInfo& movementInfo)
-{
- //Players with Feather Fall or low fall time, or physical immunity (charges used) are ignored
- if (!isInFlight() && movementInfo.fallTime > 1100 && !isDead() && !isGameMaster() &&
- !HasAuraType(SPELL_AURA_HOVER) && !HasAuraType(SPELL_AURA_FEATHER_FALL) &&
- !HasAuraType(SPELL_AURA_FLY) && !IsImmunedToDamage(SPELL_SCHOOL_MASK_NORMAL,true) )
- {
- //Safe fall, fall time reduction
- int32 safe_fall = GetTotalAuraModifier(SPELL_AURA_SAFE_FALL);
- uint32 fall_time = (movementInfo.fallTime > (safe_fall*10)) ? movementInfo.fallTime - (safe_fall*10) : 0;
-
- if(fall_time > 1100) //Prevent damage if fall time < 1100
- {
- //Fall Damage calculation
- float fallperc = float(fall_time)/1100;
- uint32 damage = (uint32)(((fallperc*fallperc -1) / 9 * GetMaxHealth())*sWorld.getRate(RATE_DAMAGE_FALL));
-
- float height = movementInfo.z;
- UpdateGroundPositionZ(movementInfo.x,movementInfo.y,height);
-
- if (damage > 0)
- {
- //Prevent fall damage from being more than the player maximum health
- if (damage > GetMaxHealth())
- damage = GetMaxHealth();
-
- // Gust of Wind
- if (GetDummyAura(43621))
- damage = GetMaxHealth()/2;
-
- EnvironmentalDamage(GetGUID(), DAMAGE_FALL, damage);
- }
-
- //Z given by moveinfo, LastZ, FallTime, WaterZ, MapZ, Damage, Safefall reduction
- DEBUG_LOG("FALLDAMAGE z=%f sz=%f pZ=%f FallTime=%d mZ=%f damage=%d SF=%d" , movementInfo.z, height, GetPositionZ(), movementInfo.fallTime, height, damage, safe_fall);
- }
- }
-}
-
-void Player::HandleFallUnderMap()
-{
- if(InBattleGround() && GetBattleGround()
- && GetBattleGround()->HandlePlayerUnderMap(this))
- {
- // do nothing, the handle already did if returned true
- }
- else
- {
- // 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(isAlive())
- {
- EnvironmentalDamage(GetGUID(),DAMAGE_FALL_TO_VOID, GetMaxHealth());
- // change the death state to CORPSE to prevent the death timer from
- // starting in the next player update
- KillPlayer();
- BuildPlayerRepop();
- }
-
- // cancel the death timer here if started
- RepopAtGraveyard();
- }
-}
+void Player::HandleFallDamage(MovementInfo& movementInfo) +{ + //Players with Feather Fall or low fall time, or physical immunity (charges used) are ignored + if (!isInFlight() && movementInfo.fallTime > 1100 && !isDead() && !isGameMaster() && + !HasAuraType(SPELL_AURA_HOVER) && !HasAuraType(SPELL_AURA_FEATHER_FALL) && + !HasAuraType(SPELL_AURA_FLY) && !IsImmunedToDamage(SPELL_SCHOOL_MASK_NORMAL,true) ) + { + //Safe fall, fall time reduction + int32 safe_fall = GetTotalAuraModifier(SPELL_AURA_SAFE_FALL); + uint32 fall_time = (movementInfo.fallTime > (safe_fall*10)) ? movementInfo.fallTime - (safe_fall*10) : 0; + + if(fall_time > 1100) //Prevent damage if fall time < 1100 + { + //Fall Damage calculation + float fallperc = float(fall_time)/1100; + uint32 damage = (uint32)(((fallperc*fallperc -1) / 9 * GetMaxHealth())*sWorld.getRate(RATE_DAMAGE_FALL)); + + float height = movementInfo.z; + UpdateGroundPositionZ(movementInfo.x,movementInfo.y,height); + + if (damage > 0) + { + //Prevent fall damage from being more than the player maximum health + if (damage > GetMaxHealth()) + damage = GetMaxHealth(); + + // Gust of Wind + if (GetDummyAura(43621)) + damage = GetMaxHealth()/2; + + EnvironmentalDamage(GetGUID(), DAMAGE_FALL, damage); + } + + //Z given by moveinfo, LastZ, FallTime, WaterZ, MapZ, Damage, Safefall reduction + DEBUG_LOG("FALLDAMAGE z=%f sz=%f pZ=%f FallTime=%d mZ=%f damage=%d SF=%d" , movementInfo.z, height, GetPositionZ(), movementInfo.fallTime, height, damage, safe_fall); + } + } +} + +void Player::HandleFallUnderMap() +{ + if(InBattleGround() && GetBattleGround() + && GetBattleGround()->HandlePlayerUnderMap(this)) + { + // do nothing, the handle already did if returned true + } + else + { + // 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(isAlive()) + { + EnvironmentalDamage(GetGUID(),DAMAGE_FALL_TO_VOID, GetMaxHealth()); + // change the death state to CORPSE to prevent the death timer from + // starting in the next player update + KillPlayer(); + BuildPlayerRepop(); + } + + // cancel the death timer here if started + RepopAtGraveyard(); + } +} void Player::Possess(Unit *target) { diff --git a/src/game/QuestHandler.cpp b/src/game/QuestHandler.cpp index 1dbb8e92b38..abb285e6dbb 100644 --- a/src/game/QuestHandler.cpp +++ b/src/game/QuestHandler.cpp @@ -31,6 +31,8 @@ #include "ObjectAccessor.h" #include "ScriptCalls.h" #include "Group.h" +#include "BattleGround.h" +#include "BattleGroundAV.h" void WorldSession::HandleQuestgiverStatusQueryOpcode( WorldPacket & recv_data ) { @@ -401,6 +403,12 @@ void WorldSession::HandleQuestComplete(WorldPacket& recv_data) Quest const *pQuest = objmgr.GetQuestTemplate(quest); if( pQuest ) { + // TODO: need a virtual function + if(GetPlayer()->InBattleGround()) + if(BattleGround* bg = GetPlayer()->GetBattleGround()) + if(bg->GetTypeID() == BATTLEGROUND_AV) + ((BattleGroundAV*)bg)->HandleQuestComplete(quest, GetPlayer()); + if( _player->GetQuestStatus( quest ) != QUEST_STATUS_COMPLETE ) { if( pQuest->IsRepeatable() ) diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index a492e06f5b1..0cbd727ac9d 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -341,17 +341,17 @@ void Spell::EffectSchoolDMG(uint32 effect_idx) return; break; } - // gruul's shatter
- case 33671:
- {
- // don't damage self and only players
- if(unitTarget->GetGUID() == m_caster->GetGUID() || unitTarget->GetTypeId() != TYPEID_PLAYER)
- return;
-
- float radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[0]));
- if(!radius) return;
- float distance = m_caster->GetDistance2d(unitTarget);
- damage = (distance > radius ) ? 0 : (int32)(m_spellInfo->EffectBasePoints[0]*((radius - distance)/radius));
+ // gruul's shatter + case 33671: + { + // don't damage self and only players + if(unitTarget->GetGUID() == m_caster->GetGUID() || unitTarget->GetTypeId() != TYPEID_PLAYER) + return; + + float radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[0])); + if(!radius) return; + float distance = m_caster->GetDistance2d(unitTarget); + damage = (distance > radius ) ? 0 : (int32)(m_spellInfo->EffectBasePoints[0]*((radius - distance)/radius)); }break; } break; @@ -2886,7 +2886,7 @@ void Spell::EffectOpenLock(uint32 /*i*/) if(BattleGround *bg = player->GetBattleGround()) { // check if it's correct bg - if(bg && bg->GetTypeID() == BATTLEGROUND_AB) + if(bg->GetTypeID() == BATTLEGROUND_AB || bg->GetTypeID() == BATTLEGROUND_AV) bg->EventPlayerClickedOnFlag(player, gameObjTarget); return; } diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 94f647cdd46..73dce3e043a 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -829,22 +829,15 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa } // 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())) + if(player && player->InBattleGround()) { - Player *killed = ((Player*)pVictim); - Player *killer = NULL; - if(GetTypeId() == TYPEID_PLAYER) - killer = ((Player*)this); - else if(GetTypeId() == TYPEID_UNIT && ((Creature*)this)->isPet()) + if(BattleGround *bg = player->GetBattleGround()) { - Unit *owner = GetOwner(); - if(owner && owner->GetTypeId() == TYPEID_PLAYER) - killer = ((Player*)owner); + if(pVictim->GetTypeId() == TYPEID_PLAYER) + bg->HandleKillPlayer((Player*)pVictim, player); + else + bg->HandleKillUnit((Creature*)pVictim, player); } - - if(killer) - if(BattleGround *bg = killed->GetBattleGround()) - bg->HandleKillPlayer(killed, killer); // drop flags and etc } } else // if (health <= damage) |