/*
* 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;
}