/* * Copyright (C) 2005-2008 MaNGOS * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * 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 "ObjectMgr.h" #include "MapManager.h" #include "Language.h" #include BattleGroundAV::BattleGroundAV() { } BattleGroundAV::~BattleGroundAV() { } void BattleGroundAV::HandleKillPlayer(Player *player, Player *killer) { if(GetStatus() != STATUS_IN_PROGRESS) return; uint8 teamIndex = GetTeamIndexByTeamId(player->GetTeam()); if(teamIndex==0) AScore--; else HScore--; UpdateScore(); } void BattleGroundAV::HandleKillUnit(Unit *unit, Player *killer) { if(GetStatus() != STATUS_IN_PROGRESS) return; uint32 ressources = 0; uint32 reputation = 0; uint32 honor = 0; uint16 teamIndex = 0; if(GetTeamIndexByTeamId(killer->GetTeam()) == BG_TEAM_ALLIANCE) teamIndex = HORDE; else teamIndex = ALLIANCE; //check for general/captain mobs, generals end battleground and captains decrease tickets by 100 switch(unit->GetEntry()) { case 11948: reputation = 389; honor = 80; EndBattleGround(HORDE); break; case 11946: reputation = 389; honor = 80; EndBattleGround(ALLIANCE); break; case 11949: reputation = 125; honor = 60; rew.m_CaptainsAlive[BG_TEAM_ALLIANCE]--; rew.m_CaptainsKilled[BG_TEAM_HORDE]++; ressources = 100; break; case 11947: reputation = 125; honor = 60; rew.m_CaptainsAlive[BG_TEAM_HORDE]--; rew.m_CaptainsKilled[BG_TEAM_ALLIANCE]++; ressources = 100; break; case 13557: /* todo: CaptureMine(killer->GetTeam()); */ reputation = 125; break; case 13539: /*todo: CaptureMine(killer->GetTeam()); */ reputation = 125; break; default: ressources = 0; honor = 0; break; } uint32 faction = 0; if(teamIndex==0) HScore -= ressources; else AScore -= ressources; if(killer->GetTeam() == ALLIANCE) faction = 730; else faction = 729; if(reputation) RewardReputation(faction,reputation, killer->GetTeam(),killer); if(honor) RewardHonor(honor,killer->GetTeam(),killer); UpdateScore(); } void BattleGroundAV::UpdateScore() { uint32 TAScore = (AScore<0)?0:AScore; uint32 THScore = (HScore<0)?0:HScore; UpdateWorldState(AV_Alliance_Score, TAScore); UpdateWorldState(AV_Horde_Score, THScore); } void BattleGroundAV::InitWorldStates() { UpdateWorldState(AV_Alliance_Score, AScore); UpdateWorldState(AV_Horde_Score, HScore); UpdateWorldState(AV_SHOW_H_SCORE, 1); UpdateWorldState(AV_SHOW_A_SCORE, 1); } void BattleGroundAV::Update(time_t diff) { BattleGround::Update(diff); //BG is in preparation! if (GetStatus() == STATUS_WAIT_JOIN && GetPlayersSize()) { ModifyStartDelayTime(diff); InitWorldStates(); if (!(m_Events & 0x01)) { m_Events |= 0x01; sLog.outDebug("Alterac Valley: entering state STATUS_WAIT_JOIN ..."); // Starting doors MapManager::Instance().GetMap(GetMapId(), m_bgobjects[BG_AV_OBJECT_GATE_A])->Add(m_bgobjects[BG_AV_OBJECT_GATE_A]); MapManager::Instance().GetMap(GetMapId(), m_bgobjects[BG_AV_OBJECT_GATE_H])->Add(m_bgobjects[BG_AV_OBJECT_GATE_H]); SetStartDelayTime(START_DELAY0); } // After 1 minute, warning is signalled else if (GetStartDelayTime() <= START_DELAY1 && !(m_Events & 0x04)) { m_Events |= 0x04; SendMessageToAll(LANG_BG_AV_ONEMINTOSTART); } // After 1,5 minute, warning is signalled else if (GetStartDelayTime() <= START_DELAY2 && !(m_Events & 0x08)) { m_Events |= 0x08; SendMessageToAll(LANG_BG_AV_HALFMINTOSTART); } // After 2 minutes, gates OPEN ! x) else if (GetStartDelayTime() <= 0 && !(m_Events & 0x10)) { m_Events |= 0x10; SendMessageToAll(LANG_BG_AV_STARTED); m_bgobjects[BG_AV_OBJECT_GATE_A]->SetUInt32Value(GAMEOBJECT_FLAGS,33); m_bgobjects[BG_AV_OBJECT_GATE_A]->SetUInt32Value(GAMEOBJECT_STATE,0); m_bgobjects[BG_AV_OBJECT_GATE_H]->SetUInt32Value(GAMEOBJECT_FLAGS,33); m_bgobjects[BG_AV_OBJECT_GATE_H]->SetUInt32Value(GAMEOBJECT_STATE,0); // Create banners for nodes 0-14 for(uint32 i=BG_AV_OBJECT_FIRSTAID_STATION; i<(BG_AV_OBJECT_FIRSTAID_STATION+15); i++) { _CreateBanner(i); _ShowBanner(i); // set status of graveyards+mines if(!BG_AV_Nodes[i]._IsTower) { //alliance graveyards if(i<7) m_Nodestatus[i]=3; //horde graveyards else if(i>7) m_Nodestatus[i]=4; //neutral graveyards else if(i=7) m_Nodestatus[i]=0; _UpdateGYNode(i); } } PlaySoundToAll(SOUND_BG_START); SetStatus(STATUS_IN_PROGRESS); //set neutral graveyard to wasneutral=true ??? why! we got Nodestatus[7]=0; which is the same BG_AV_Nodes[7]._WasNeutral=true; } } //bg started/doors opened starting to spawn nodes/graveyards else if(GetStatus() == STATUS_IN_PROGRESS) { // Test win condition if (HScore <= 0) EndBattleGround(ALLIANCE); if (AScore <= 0) EndBattleGround(HORDE); // Towers/Nodes 0-14 capture check(time to capture remaining) for(uint32 i=BG_AV_OBJECT_FIRSTAID_STATION; idiff) { BG_AV_Nodes[i].RespawnTimer-=diff; } else { BG_AV_Nodes[i].RespawnTimer=0; _ShowBanner(i); } } // if it is attacked calculate time to destroy if(BG_AV_Nodes[i].StateTimer) if(BG_AV_Nodes[i].StateTimer>diff) { BG_AV_Nodes[i].StateTimer-=diff; } //node will be destroyed else { BG_AV_Nodes[i].StateTimer=0; //_DeleteBanner(i); UpdateWorldState(BG_AV_Nodes[i].WStates[BG_AV_Nodes[i].State],0); // set from attacked(ally/horde: 3/4) to under control/destroyed(ally/horde: 1/2) BG_AV_Nodes[i].State-=2; // set attacker dependant from nodestate(ally/horde: 0/1) uint8 teamIndex = BG_AV_Nodes[i].State-1; char buf[256]; uint8 type = (teamIndex == 0) ? CHAT_MSG_BG_SYSTEM_ALLIANCE : CHAT_MSG_BG_SYSTEM_HORDE; //if node=tower take ressources/set rewards if(BG_AV_Nodes[i]._IsTower) { //Node has been destoryed sprintf(buf, LANG_BG_AV_TOWER_TAKEN, _GetNodeName(i)); BG_AV_Nodes[i]._WasNeutral=false; if(teamIndex == 0) { HScore-=BG_AV_SCORE_TOWER_LOST; rew.m_TowersControlled[BG_TEAM_HORDE]--; rew.m_TowersDestroyed[BG_TEAM_ALLIANCE]++; } else { rew.m_TowersControlled[BG_TEAM_ALLIANCE]--; rew.m_TowersDestroyed[BG_TEAM_HORDE]++; AScore-=BG_AV_SCORE_TOWER_LOST; } _DeleteBanner(i); } //if node=mine/graveyard else if(!BG_AV_Nodes[i]._IsMine && !BG_AV_Nodes[i]._IsTower) { _DeleteBanner(i); BG_AV_Nodes[i]._WasNeutral=false; _CreateBanner(i); //going into repop BG_AV_Nodes[i].RespawnTimer=BG_AV_BANNER_RESPAWN_TIMER; //who attacked node? -> (ally/horde: 3/4) m_Nodestatus[i]=teamIndex+3; _UpdateGYNode(i); sprintf(buf, LANG_BG_AV_GRAVE_TAKEN, _GetNodeName(i), (teamIndex == 0) ? LANG_BG_AB_ALLY : LANG_BG_AB_HORDE); } UpdateWorldState(BG_AV_Nodes[i].WStates[BG_AV_Nodes[i].State],1); WorldPacket data; ChatHandler::FillMessageData(&data, NULL, type, LANG_UNIVERSAL, NULL, 0, buf, NULL); SendPacketToAll(&data); UpdateScore(); } } } } void BattleGroundAV::_CreateBanner(uint32 node) { //if not already spawned: do spawn! if(!m_bgobjects[node]) { m_bgobjects[node]= new GameObject(NULL); m_bgobjects[node+BG_AV_AURA]= new GameObject(NULL); sLog.outDebug("Alterac Valley: CREATE => node=%u id=%u state=%u",node,BG_AV_Nodes[node].GO_ids[BG_AV_Nodes[node].State],BG_AV_Nodes[node].State); if(!m_bgobjects[node]->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), BG_AV_Nodes[node].GO_ids[BG_AV_Nodes[node].State] , GetMapId(), BG_AV_Nodes[node].x, BG_AV_Nodes[node].y, BG_AV_Nodes[node].z, BG_AV_Nodes[node].a, BG_AV_Nodes[node].r0, BG_AV_Nodes[node].r1, BG_AV_Nodes[node].r2, BG_AV_Nodes[node].r3, 100, 1)) sLog.outError("Could not create banner on node: %u",node); uint32 banneraura = BG_AV_State_Auras[BG_AV_Nodes[node].State]; // set banneraura for towers if(BG_AV_Nodes[node]._IsTower) banneraura = BG_AV_State_Auras_Small[BG_AV_Nodes[node].State]; //apply banneraura if(!m_bgobjects[node+BG_AV_AURA]->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), banneraura , GetMapId(), BG_AV_Nodes[node].x, BG_AV_Nodes[node].y, BG_AV_Nodes[node].z, BG_AV_Nodes[node].a, BG_AV_Nodes[node].r0, BG_AV_Nodes[node].r1, BG_AV_Nodes[node].r2, BG_AV_Nodes[node].r3, 0, 0)) sLog.outError("Could not create banner aura on node: %u",node); } else { sLog.outError("Alterac Valley: Bad node => %u OBJECT IS THERE",node); } } //repop banner! void BattleGroundAV::_ShowBanner(uint32 node) { if(!m_bgobjects[node]) return; sLog.outDebug("Alterac Valley: SHOW => node=%u",node); MapManager::Instance().GetMap(GetMapId(), m_bgobjects[node])->Add(m_bgobjects[node]); MapManager::Instance().GetMap(GetMapId(), m_bgobjects[node+BG_AV_AURA])->Add(m_bgobjects[node+BG_AV_AURA]); } //remove banner void BattleGroundAV::_DeleteBanner(uint32 node) { sLog.outDebug("Alterac Valley: DELETE => node=%u",node); m_bgobjects[node]->Delete(); m_bgobjects[node]=NULL; m_bgobjects[node+BG_AV_AURA]->Delete(); m_bgobjects[node+BG_AV_AURA]=NULL; //only for towers if(BG_AV_Nodes[node]._IsTower && !BG_AV_Nodes[node]._WasNeutral) { m_bgobjects[node+BG_AV_FIRES]= new GameObject(NULL); if(!m_bgobjects[node+BG_AV_FIRES]->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), BG_AB_OBJECTID_FIRE , GetMapId(), BG_AV_Nodes[node].x, BG_AV_Nodes[node].y, BG_AV_Nodes[node].z, BG_AV_Nodes[node].a, BG_AV_Nodes[node].r0, BG_AV_Nodes[node].r1, BG_AV_Nodes[node].r2, BG_AV_Nodes[node].r3, 0, 0)) sLog.outError("Could not create fire aura on node: %u",node); } } 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; } void BattleGroundAV::RemovePlayer(Player *plr,uint64 guid) { if(GetPlayersSize()==0) { sLog.outDebug("Alterac Valley: BG ended, objects despawning..."); // delete everything (for times, when BG will instanced) for(uint32 i=BG_AV_OBJECT_FIRSTAID_STATION; i<(BG_AV_OBJECT_FIRSTAID_STATION+15); i++) if(BG_AV_Nodes[i].RespawnTimer) { BG_AV_Nodes[i].RespawnTimer=0; _ShowBanner(i); //if object is created but not spawned - may generate error } for(uint32 i = 0; i < BG_AV_OBJECT_MAX; i++) if (m_bgobjects[i]) { m_bgobjects[i]->Delete(); m_bgobjects[i] = NULL; } for(uint32 i = 0; i < BG_AV_SPIRITHEALER_COUNT; i++) if(m_spiritGuides[i]) { m_spiritGuides[i]->CleanupsBeforeDelete(); ObjectAccessor::Instance().AddObjectToRemoveList(m_spiritGuides[i]); m_spiritGuides[i] = NULL; m_Nodestatus[i]=0; } for(uint32 i = 0; i < BG_AV_CREATURE_COUNT; i++) if(m_bgcreatures[i]) { m_bgcreatures[i]->CleanupsBeforeDelete(); } Reset(); SetupBattleGround(); } } void BattleGroundAV::HandleAreaTrigger(Player *Source, uint32 Trigger) { // this is wrong way to implement these things. On official it done by gameobject spell cast. if(GetStatus() != STATUS_IN_PROGRESS) return; uint32 SpellId = 0; switch(Trigger) { case 95: 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->GetSession()->SendAreaTriggerMessage("Warning: Unhandled AreaTrigger in Battleground: %u", Trigger); //Source->Unmount(); break; default: sLog.outError("WARNING: Unhandled AreaTrigger in Battleground: %u", Trigger); Source->GetSession()->SendAreaTriggerMessage("Warning: Unhandled AreaTrigger in Battleground: %u", Trigger); break; } if(SpellId) Source->CastSpell(Source, SpellId, true); } void BattleGroundAV::UpdatePlayerScore(Player* Source, uint32 type, uint32 value) { std::map::iterator itr = m_PlayerScores.find(Source->GetGUID()); if(itr == m_PlayerScores.end()) // player not found... return; switch(type) { case SCORE_GRAVEYARDS_ASSAULTED: ((BattleGroundAVScore*)itr->second)->GraveyardsAssaulted += value; break; case SCORE_GRAVEYARDS_DEFENDED: ((BattleGroundAVScore*)itr->second)->GraveyardsDefended += value; break; case SCORE_TOWERS_ASSAULTED: ((BattleGroundAVScore*)itr->second)->TowersAssaulted += value; break; case SCORE_TOWERS_DEFENDED: ((BattleGroundAVScore*)itr->second)->TowersDefended += value; break; case SCORE_MINES_CAPTURED: ((BattleGroundAVScore*)itr->second)->MinesCaptured += value; break; case SCORE_LEADERS_KILLED: ((BattleGroundAVScore*)itr->second)->LeadersKilled += value; break; case SCORE_SECONDARY_OBJECTIVES: ((BattleGroundAVScore*)itr->second)->SecondaryObjectives += value; break; default: BattleGround::UpdatePlayerScore(Source,type,value); break; } } /* Invoked if a player used a banner as a gameobject */ void BattleGroundAV::EventPlayerCapturedBanner(Player *source) { if(GetStatus() != STATUS_IN_PROGRESS) return; uint8 node = BG_AV_OBJECT_FIRSTAID_STATION; while (node < BG_AV_OBJECT_IRONDEEP_MINE) { if(m_bgobjects[node]) if((source->IsWithinDistInMap(m_bgobjects[node], 10))) // player and nodes distance break; ++node; } if (node == (BG_AV_OBJECT_FIRSTAID_STATION+15)) { // this means our player isn't close to any of banners - maybe cheater ?? return; } _DeleteBanner(node); uint8 teamIndex = GetTeamIndexByTeamId(source->GetTeam()); char buf[256]; uint8 type = (teamIndex == 0) ? CHAT_MSG_BG_SYSTEM_ALLIANCE : CHAT_MSG_BG_SYSTEM_HORDE; BG_AV_Nodes[node].RespawnTimer = BG_AV_BANNER_RESPAWN_TIMER; BG_AV_Nodes[node].StateTimer = BG_AV_CAPTIME; UpdateWorldState(BG_AV_Nodes[node].WStates[BG_AV_Nodes[node].State],0); if(BG_AV_Nodes[node].State == 0) // if node is neutral BG_AV_Nodes[node].State=teamIndex+3; // set state to: alliance=3, horde =4 else BG_AV_Nodes[node].State=5-BG_AV_Nodes[node].State; // if node already captured: alliance=4, horde=3 // neutral graveyard if(BG_AV_Nodes[node]._WasNeutral) // node is neutral BG_AV_Nodes[node].State=teamIndex+3; // set state to: alliance=3, horde=4 // if node=tower if(BG_AV_Nodes[node]._IsTower) { // if node is attacked (ally/horde: 3/4 - 4/3) if(BG_AV_Nodes[node].State>2) { UpdatePlayerScore(source,SCORE_TOWERS_ASSAULTED,1); sprintf(buf, LANG_BG_AV_TOWER_ASSAULTED, _GetNodeName(node), (teamIndex == 0) ? LANG_BG_AV_ALLY : LANG_BG_AV_HORDE); } else { UpdatePlayerScore(source,SCORE_TOWERS_DEFENDED,1); sprintf(buf, LANG_BG_AV_GRAVE_DEFENDED, _GetNodeName(node)); } } // graveyards else { // neutral graveyard if(BG_AV_Nodes[node]._WasNeutral) { sprintf(buf, LANG_BG_AV_GRAVE_ASSAULTED, _GetNodeName(node), (teamIndex == 0) ? LANG_BG_AV_ALLY : LANG_BG_AV_HORDE); UpdatePlayerScore(source,SCORE_GRAVEYARDS_ASSAULTED,1); } else // graveyard already occupied now: under change! { // its attacked if(BG_AV_Nodes[node].State>2) { UpdatePlayerScore(source,SCORE_GRAVEYARDS_ASSAULTED,1); sprintf(buf, LANG_BG_AV_GRAVE_ASSAULTED, _GetNodeName(node), (teamIndex == 0) ? LANG_BG_AB_ALLY : LANG_BG_AB_HORDE); m_Nodestatus[node]=teamIndex+1; _UpdateGYNode(node); } // its defended else { UpdatePlayerScore(source,SCORE_GRAVEYARDS_DEFENDED,1); sprintf(buf, LANG_BG_AV_GRAVE_DEFENDED, _GetNodeName(node)); m_Nodestatus[node]=teamIndex+3; _UpdateGYNode(node); } } } UpdateWorldState(BG_AV_Nodes[node].WStates[BG_AV_Nodes[node].State],1); WorldPacket data; ChatHandler::FillMessageData(&data, source->GetSession(), type, LANG_UNIVERSAL, NULL, source->GetGUID(), buf, NULL); SendPacketToAll(&data); UpdateScore(); _CreateBanner(node); } void BattleGroundAV::_UpdateGYNode(uint32 GYid) { if(GYid>BG_AV_OBJECT_GATE_H) { sLog.outError("There is no such node: %u",GYid); return; } std::cout << "GYid: " << GYid << std::endl; // 0=neutral 1= ally 2= horde uint32 gystate=m_Nodestatus[GYid]; sLog.outDebug("Alterac Valley: GY %u UPDATE = %u",GYid,gystate); std::cout << "gystate: " << gystate << std::endl; if(gystate>0) //to prevent double freeing { if(gystate<3) { //changing from owned to free std::cout << "gystate: " << gystate << std::endl; sLog.outDebug("Alterac Valley: GY %u FREE",GYid); // Those who are waiting to resurrect at this node are taken to the closest own node's graveyard std::vector ghost_list = m_ReviveQueue[m_spiritGuides[GYid]->GetGUID()]; std::cout << "ghost_list initialized" << std::endl; if (!ghost_list.empty()) { std::cout << "ghostlist NOT empty! sending players to different grave" << std::endl; WorldSafeLocsEntry const *ClosestGrave = NULL; Player *plr; for (std::vector::iterator itr = ghost_list.begin(); itr != ghost_list.end(); ++itr) { std::cout << "we are within gy list" << std::endl; plr = objmgr.GetPlayer(*ghost_list.begin()); if (!plr) continue; if (!ClosestGrave) { std::cout << "sending player to different grave" << std::endl; ClosestGrave = SelectGraveYard(plr); std::cout << "searching new closestrave " << std::endl; } if(ClosestGrave) { std::cout << "found new closestgrave: " << ClosestGrave->ID << "teleporting player" << std::endl; plr->TeleportTo(GetMapId(), ClosestGrave->x, ClosestGrave->y, ClosestGrave->z, plr->GetOrientation()); } else sLog.outError("No graveyard found for player %u, faction %s",plr->GetGUIDLow(),(plr->GetTeam()==BG_TEAM_ALLIANCE) ? LANG_BG_AV_ALLY : LANG_BG_AV_HORDE); } } std::cout << "ghost-listing done" << std::endl; m_spiritGuides[GYid]->CleanupsBeforeDelete(); std::cout << "Cleanup done, adding spiritguide to removelist" << std::endl; ObjectAccessor::Instance().AddObjectToRemoveList(m_spiritGuides[GYid]); std::cout << "its on removelist" << std::endl; m_spiritGuides[GYid] = NULL; m_Nodestatus[GYid]=0; std::cout << "everything is done: node is neutral" << std::endl; } else { //changing from free to owned std::cout << "node is now owned by different faction" << std::endl; if (m_spiritGuides[GYid]) return; std::cout << "currently no spiritguide here" << std::endl; m_spiritGuides[GYid] = new Creature(NULL); sLog.outDebug("Alterac Valley: GY %u NEW SG",GYid); //get graveyardid for current node WorldSafeLocsEntry const* entry = sWorldSafeLocsStore.LookupEntry( BG_AV_GraveyardIds[GYid] ); std::cout << "found graveyard id: " << GYid << std::endl; // create spiritguide if (!m_spiritGuides[GYid]->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), entry->map_id, entry->x, entry->y, entry->z, 1, BG_AV_SpiritGuideId[gystate-3],BG_AV_SpiritGuideTeamId[gystate-3] )) sLog.outError("Alterac Valley: Spiritguide could not be spawned for graveyard: %u", BG_AV_GraveyardIds[GYid]); m_spiritGuides[GYid]->setDeathState(DEAD); m_spiritGuides[GYid]->AIM_Initialize(); sLog.outDebug("Alterac Valley: GY %u ADD = %u",GYid,m_spiritGuides[GYid]->GetEntry()); // add to map MapManager::Instance().GetMap(GetMapId(), m_spiritGuides[GYid])->Add(m_spiritGuides[GYid]); m_spiritGuides[GYid]->CastSpell(m_spiritGuides[GYid], SPELL_SPIRIT_HEAL_CHANNEL, true); sLog.outDebug("Alterac Valley: GY %u DONE",GYid); } } } WorldSafeLocsEntry const* BattleGroundAV::SelectGraveYard(Player* player) { uint8 teamIndex = GetTeamIndexByTeamId(player->GetTeam()); // Are there any occupied nodes for this team? std::vector nodes; for (uint8 i = 0; i < BG_AV_SPIRITHEALER_COUNT; ++i) if (m_Nodestatus[i] == teamIndex+3) nodes.push_back(i); WorldSafeLocsEntry const* good_entry = NULL; // If so, select the closest node to send ghost to if (!nodes.empty()) { float x = player->GetPositionX(); float y = player->GetPositionY(); // dont mind about z coordinate float mindist = 999999.0f; for (uint8 i = 0; i < nodes.size(); ++i) { WorldSafeLocsEntry const*entry = sWorldSafeLocsStore.LookupEntry( BG_AV_GraveyardIds[nodes[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; } } nodes.clear(); } // If not, send ghost to starting location if(!good_entry) good_entry = sWorldSafeLocsStore.LookupEntry( BG_AV_GraveyardIds[teamIndex+8] ); return good_entry; } bool BattleGroundAV::SetupBattleGround() { // Initialize objects table for (int i = 0; i < BG_AV_OBJECT_MAX; ++i) m_bgobjects[i] = NULL; for (int i = 0; i < BG_AV_SPIRITHEALER_COUNT; ++i) m_spiritGuides[i] = NULL; for (int i = 0; i < BG_AV_CREATURE_COUNT; i++) m_bgcreatures[i] = NULL; //for (int i = BG_AV_AURA; i < BG_AV_AURA+15; ++i) // m_bgobjects[i]= new GameObject(NULL); AScore=BG_AV_SCORE_INITIAL_POINTS; HScore=BG_AV_SCORE_INITIAL_POINTS; //Alliance stats for(uint8 i=0; i<2; i++) { rew.m_CaptainsAlive[i] = 2; rew.m_CaptainsKilled[i] = 0; rew.m_TowersControlled[i] = 8; rew.m_TowersDestroyed[i] = 0; rew.m_MinesControlled[i] = 0; rew.m_GraveYardsControlled[i] = 3; } // Create starting objects // Starting gates m_bgobjects[BG_AV_OBJECT_GATE_A] = new GameObject(NULL); if(!m_bgobjects[BG_AV_OBJECT_GATE_A]->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), BG_AV_OBJECTID_GATE_A, GetMapId(), BG_AV_DoorPositions[0][0], BG_AV_DoorPositions[0][1], BG_AV_DoorPositions[0][2], BG_AV_DoorPositions[0][3], BG_AV_DoorPositions[0][4], BG_AV_DoorPositions[0][5], BG_AV_DoorPositions[0][6], BG_AV_DoorPositions[0][7], 100, 1)) return false; m_bgobjects[BG_AV_OBJECT_GATE_H] = new GameObject(NULL); if(!m_bgobjects[BG_AV_OBJECT_GATE_H]->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), BG_AV_OBJECTID_GATE_H, GetMapId(), BG_AV_DoorPositions[1][0], BG_AV_DoorPositions[1][1], BG_AV_DoorPositions[1][2], BG_AV_DoorPositions[1][3], BG_AV_DoorPositions[1][4], BG_AV_DoorPositions[1][5], BG_AV_DoorPositions[1][6], BG_AV_DoorPositions[1][7], 100, 1)) return false; WorldSafeLocsEntry const *sg = NULL; for(uint8 i=BG_AV_OBJECT_FIRSTAID_STATION; i7)BG_AV_Nodes[i].State=2; // horde node BG_AV_Nodes[i].x=BG_AV_NodePositions[i][0]; BG_AV_Nodes[i].y=BG_AV_NodePositions[i][1]; BG_AV_Nodes[i].z=BG_AV_NodePositions[i][2]; BG_AV_Nodes[i].a=BG_AV_NodePositions[i][3]; BG_AV_Nodes[i].r0=BG_AV_NodePositions[i][4]; BG_AV_Nodes[i].r1=BG_AV_NodePositions[i][5]; BG_AV_Nodes[i].r2=BG_AV_NodePositions[i][6]; BG_AV_Nodes[i].r3=BG_AV_NodePositions[i][7]; for(uint8 k=0;k<5;k++) BG_AV_Nodes[i].GO_ids[k]=BG_AV_Node_GO[i][k]; for(uint8 k=0;k<5;k++) BG_AV_Nodes[i].WStates[k]=BG_AV_Node_StateIcons[i][k]; } return true; } void BattleGroundAV::AtEndBG(uint32 winner,Player* plr) { uint32 faction = 0; uint32 rep = 0; rep = rew.m_CaptainsAlive[plr->GetTeam()] * 125; rep += rew.m_CaptainsKilled[plr->GetTeam()] * 36; rep += rew.m_GraveYardsControlled[plr->GetTeam()] * 12; rep += rew.m_MinesControlled[plr->GetTeam()] * 12; rep += rew.m_TowersControlled[plr->GetTeam()] * 12; rep += rew.m_TowersDestroyed[plr->GetTeam()] * 24; faction = (plr->GetTeam() == ALLIANCE) ? faction=730 : faction=729; plr->ModifyFactionReputation(faction,rep); } const char* BattleGroundAV::_GetNodeName(uint8 node) { switch (node) { case BG_AV_OBJECT_FIRSTAID_STATION: return "Stormpike Aid Station"; case BG_AV_OBJECT_DUNBALDAR_SHOUTH: return "The Dun Baldar South Bunker"; case BG_AV_OBJECT_DUNBALDAR_NORTH: return "The Dun Baldar North Bunker"; case BG_AV_OBJECT_STORMPIKE_GRAVE: return "Stormpike Graveyard"; case BG_AV_OBJECT_ICEWING_BUNKER: return "The Icewing Bunker"; case BG_AV_OBJECT_STONEHEART_GRAVE: return "Stonehearth Graveyard"; case BG_AV_OBJECT_STONEHEART_BUNKER: return "The Stonehearth Bunker"; case BG_AV_OBJECT_SNOWFALL_GRAVE: return "Snowfall Graveyard"; case BG_AV_OBJECT_ICEBLOOD_TOWER: return "Iceblood Tower"; case BG_AV_OBJECT_ICEBLOOD_GRAVE: return "Iceblood Graveyard"; case BG_AV_OBJECT_TOWER_POINT: return "Tower Point"; case BG_AV_OBJECT_FROSTWOLF_GRAVE: return "Frostwolf Graveyard"; case BG_AV_OBJECT_FROSTWOLF_ETOWER: return "The East Frostwolf Tower"; case BG_AV_OBJECT_FROSTWOLF_WTOWER: return "The West Frostwolf Tower"; case BG_AV_OBJECT_FROSTWOLF_HUT: return "Frostwolf Relief Hut"; case BG_AV_OBJECT_IRONDEEP_MINE: return "Irondeep Mine"; case BG_AV_OBJECT_COLDTOOTH_MINE: return "Coldtooth Mine"; default: return "Unknown Node"; } return ""; } void BattleGroundAV::ResetBGSubclass() { AScore=BG_AV_SCORE_INITIAL_POINTS; HScore=BG_AV_SCORE_INITIAL_POINTS; }