text: /*
   * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
   *
   * 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 "OutdoorPvPNA.h"
  #include "Player.h"
  #include "ObjectMgr.h"
  #include "OutdoorPvPMgr.h"
  #include "WorldPacket.h"
  #include "Language.h"
  #include "World.h"
  #include "ScriptPCH.h"
  
  OutdoorPvPNA::OutdoorPvPNA() {
  	m_TypeId = OUTDOOR_PVP_NA;
  }
  
  void OutdoorPvPNA::HandleKillImpl(Player *plr, Unit * killed) {
  	if (killed->GetTypeId() == TYPEID_PLAYER
  			&& plr->GetTeam() != killed->ToPlayer()->GetTeam()) {
  		plr->KilledMonsterCredit(NA_CREDIT_MARKER, 0); // 0 guid, btw it isn't even used in killedmonster function :S
  		if (plr->GetTeam() == ALLIANCE)
  			plr->CastSpell(plr, NA_KILL_TOKEN_ALLIANCE, true);
  		else
  			plr->CastSpell(plr, NA_KILL_TOKEN_HORDE, true);
  	}
  }
  
  uint32 OPvPCapturePointNA::GetAliveGuardsCount() {
  	uint32 cnt = 0;
  	for (std::map<uint32, uint64>::iterator itr = m_Creatures.begin();
  			itr != m_Creatures.end(); ++itr) {
  		switch (itr->first) {
  		case NA_NPC_GUARD_01:
  		case NA_NPC_GUARD_02:
  		case NA_NPC_GUARD_03:
  		case NA_NPC_GUARD_04:
  		case NA_NPC_GUARD_05:
  		case NA_NPC_GUARD_06:
  		case NA_NPC_GUARD_07:
  		case NA_NPC_GUARD_08:
  		case NA_NPC_GUARD_09:
  		case NA_NPC_GUARD_10:
  		case NA_NPC_GUARD_11:
  		case NA_NPC_GUARD_12:
  		case NA_NPC_GUARD_13:
  		case NA_NPC_GUARD_14:
  		case NA_NPC_GUARD_15: {
  			if (Creature * cr = HashMapHolder<Creature>::Find(itr->second)) {
  				if (cr->isAlive())
  					++cnt;
  			} else if (CreatureData const * cd = sObjectMgr->GetCreatureData(GUID_LOPART(itr->second))) {
  				if (!cd->is_dead)
  					++cnt;
  			}
  		}
  			break;
  		default:
  			break;
  		}
  	}
  	return cnt;
  }
  
  void OPvPCapturePointNA::SpawnNPCsForTeam(uint32 team) {
  	const creature_type * creatures = NULL;
  	if (team == ALLIANCE)
  		creatures = AllianceControlNPCs;
  	else if (team == HORDE)
  		creatures = HordeControlNPCs;
  	else
  		return;
  	for (int i = 0; i < NA_CONTROL_NPC_NUM; ++i)
  		AddCreature(i, creatures[i].entry, creatures[i].teamval,
  				creatures[i].map, creatures[i].x, creatures[i].y,
  				creatures[i].z, creatures[i].o, 1000000);
  }
  
  void OPvPCapturePointNA::DeSpawnNPCs() {
  	for (int i = 0; i < NA_CONTROL_NPC_NUM; ++i)
  		DelCreature(i);
  }
  
  void OPvPCapturePointNA::SpawnGOsForTeam(uint32 team) {
  	const go_type * gos = NULL;
  	if (team == ALLIANCE)
  		gos = AllianceControlGOs;
  	else if (team == HORDE)
  		gos = HordeControlGOs;
  	else
  		return;
  	for (int i = 0; i < NA_CONTROL_GO_NUM; ++i) {
  		if (i == NA_ROOST_S || i == NA_ROOST_W || i == NA_ROOST_N
  				|| i == NA_ROOST_E || i == NA_BOMB_WAGON_S
  				|| i == NA_BOMB_WAGON_W || i == NA_BOMB_WAGON_N
  				|| i == NA_BOMB_WAGON_E)
  			continue; // roosts and bomb wagons are spawned when someone uses the matching destroyed roost
  		AddObject(i, gos[i].entry, gos[i].map, gos[i].x, gos[i].y, gos[i].z,
  				gos[i].o, gos[i].rot0, gos[i].rot1, gos[i].rot2, gos[i].rot3);
  	}
  }
  
  void OPvPCapturePointNA::DeSpawnGOs() {
  	for (int i = 0; i < NA_CONTROL_GO_NUM; ++i) {
  		DelObject(i);
  	}
  }
  
  void OPvPCapturePointNA::FactionTakeOver(uint32 team) {
  	if (m_ControllingFaction)
  		sObjectMgr->RemoveGraveYardLink(NA_HALAA_GRAVEYARD,
  				NA_HALAA_GRAVEYARD_ZONE, m_ControllingFaction, false);
  	if (m_ControllingFaction == ALLIANCE)
  		sWorld->SendZoneText(NA_HALAA_GRAVEYARD_ZONE,
  				sObjectMgr->GetFrenchCOREStringForDBCLocale(LANG_OPVP_NA_LOOSE_A));
  	else if (m_ControllingFaction == HORDE)
  		sWorld->SendZoneText(NA_HALAA_GRAVEYARD_ZONE,
  				sObjectMgr->GetFrenchCOREStringForDBCLocale(LANG_OPVP_NA_LOOSE_H));
  
  	m_ControllingFaction = team;
  	if (m_ControllingFaction)
  		sObjectMgr->AddGraveYardLink(NA_HALAA_GRAVEYARD,
  				NA_HALAA_GRAVEYARD_ZONE, m_ControllingFaction, false);
  	DeSpawnGOs();
  	DeSpawnNPCs();
  	SpawnGOsForTeam(team);
  	SpawnNPCsForTeam(team);
  	m_GuardsAlive = NA_GUARDS_MAX;
  	m_capturable = false;
  	this->UpdateHalaaWorldState();
  	if (team == ALLIANCE) {
  		m_WyvernStateSouth = WYVERN_NEU_HORDE;
  		m_WyvernStateNorth = WYVERN_NEU_HORDE;
  		m_WyvernStateEast = WYVERN_NEU_HORDE;
  		m_WyvernStateWest = WYVERN_NEU_HORDE;
  		m_PvP->TeamApplyBuff(TEAM_ALLIANCE, NA_CAPTURE_BUFF);
  		m_PvP->SendUpdateWorldState(NA_UI_HORDE_GUARDS_SHOW, 0);
  		m_PvP->SendUpdateWorldState(NA_UI_ALLIANCE_GUARDS_SHOW, 1);
  		m_PvP->SendUpdateWorldState(NA_UI_GUARDS_LEFT, m_GuardsAlive);
  		sWorld->SendZoneText(
  				NA_HALAA_GRAVEYARD_ZONE,
  				sObjectMgr->GetFrenchCOREStringForDBCLocale(
  						LANG_OPVP_NA_CAPTURE_A));
  	} else {
  		m_WyvernStateSouth = WYVERN_NEU_ALLIANCE;
  		m_WyvernStateNorth = WYVERN_NEU_ALLIANCE;
  		m_WyvernStateEast = WYVERN_NEU_ALLIANCE;
  		m_WyvernStateWest = WYVERN_NEU_ALLIANCE;
  		m_PvP->TeamApplyBuff(TEAM_HORDE, NA_CAPTURE_BUFF);
  		m_PvP->SendUpdateWorldState(NA_UI_HORDE_GUARDS_SHOW, 1);
  		m_PvP->SendUpdateWorldState(NA_UI_ALLIANCE_GUARDS_SHOW, 0);
  		m_PvP->SendUpdateWorldState(NA_UI_GUARDS_LEFT, m_GuardsAlive);
  		sWorld->SendZoneText(
  				NA_HALAA_GRAVEYARD_ZONE,
  				sObjectMgr->GetFrenchCOREStringForDBCLocale(
  						LANG_OPVP_NA_CAPTURE_H));
  	}
  	UpdateWyvernRoostWorldState(NA_ROOST_S);
  	UpdateWyvernRoostWorldState(NA_ROOST_N);
  	UpdateWyvernRoostWorldState(NA_ROOST_W);
  	UpdateWyvernRoostWorldState(NA_ROOST_E);
  }
  
  bool OPvPCapturePointNA::HandlePlayerEnter(Player *plr) {
  	if (OPvPCapturePoint::HandlePlayerEnter(plr)) {
  		plr->SendUpdateWorldState(NA_UI_TOWER_SLIDER_DISPLAY, 1);
  		uint32 phase = (uint32) ceil(
  				(m_value + m_maxValue) / (2 * m_maxValue) * 100.0f);
  		plr->SendUpdateWorldState(NA_UI_TOWER_SLIDER_POS, phase);
  		plr->SendUpdateWorldState(NA_UI_TOWER_SLIDER_N, m_neutralValuePct);
  		return true;
  	}
  	return false;
  }
  
  void OPvPCapturePointNA::HandlePlayerLeave(Player *plr) {
  	plr->SendUpdateWorldState(NA_UI_TOWER_SLIDER_DISPLAY, 0);
  	OPvPCapturePoint::HandlePlayerLeave(plr);
  }
  
  OPvPCapturePointNA::OPvPCapturePointNA(OutdoorPvP *pvp) :
  		OPvPCapturePoint(pvp), m_capturable(true), m_GuardsAlive(0), m_ControllingFaction(
  				0), m_WyvernStateNorth(0), m_WyvernStateSouth(0), m_WyvernStateEast(
  				0), m_WyvernStateWest(0), m_HalaaState(HALAA_N), m_RespawnTimer(
  				NA_RESPAWN_TIME), m_GuardCheckTimer(NA_GUARD_CHECK_TIME) {
  	SetCapturePointData(182210, 530, -1572.57f, 7945.3f, -22.475f, 2.05949f,
  			0.0f, 0.0f, 0.857167f, 0.515038f);
  }
  
  bool OutdoorPvPNA::SetupOutdoorPvP() {
  //    m_TypeId = OUTDOOR_PVP_NA; _MUST_ be set in ctor, because of spawns cleanup
  	// add the zones affected by the pvp buff
  	RegisterZone(NA_BUFF_ZONE);
  
  	// halaa
  	m_obj = new OPvPCapturePointNA(this);
  	if (!m_obj)
  		return false;
  	AddCapturePoint(m_obj);
  
  	return true;
  }
  
  void OutdoorPvPNA::HandlePlayerEnterZone(Player * plr, uint32 zone) {
  	// add buffs
  	if (plr->GetTeam() == m_obj->m_ControllingFaction)
  		plr->CastSpell(plr, NA_CAPTURE_BUFF, true);
  	OutdoorPvP::HandlePlayerEnterZone(plr, zone);
  }
  
  void OutdoorPvPNA::HandlePlayerLeaveZone(Player * plr, uint32 zone) {
  	// remove buffs
  	plr->RemoveAurasDueToSpell(NA_CAPTURE_BUFF);
  	OutdoorPvP::HandlePlayerLeaveZone(plr, zone);
  }
  
  void OutdoorPvPNA::FillInitialWorldStates(WorldPacket &data) {
  	m_obj->FillInitialWorldStates(data);
  }
  
  void OPvPCapturePointNA::FillInitialWorldStates(WorldPacket &data) {
  	if (m_ControllingFaction == ALLIANCE) {
  		data << NA_UI_HORDE_GUARDS_SHOW << uint32(0);
  		data << NA_UI_ALLIANCE_GUARDS_SHOW << uint32(1);
  	} else if (m_ControllingFaction == HORDE) {
  		data << NA_UI_HORDE_GUARDS_SHOW << uint32(1);
  		data << NA_UI_ALLIANCE_GUARDS_SHOW << uint32(0);
  	} else {
  		data << NA_UI_HORDE_GUARDS_SHOW << uint32(0);
  		data << NA_UI_ALLIANCE_GUARDS_SHOW << uint32(0);
  	}
  
  	data << NA_UI_GUARDS_MAX << NA_GUARDS_MAX;
  	data << NA_UI_GUARDS_LEFT << uint32(m_GuardsAlive);
  
  	data << NA_UI_TOWER_SLIDER_DISPLAY << uint32(0);
  	data << NA_UI_TOWER_SLIDER_POS << uint32(50);
  	data << NA_UI_TOWER_SLIDER_N << uint32(100);
  
  	data << NA_MAP_WYVERN_NORTH_NEU_H
  			<< uint32(bool(m_WyvernStateNorth & WYVERN_NEU_HORDE));
  	data << NA_MAP_WYVERN_NORTH_NEU_A
  			<< uint32(bool(m_WyvernStateNorth & WYVERN_NEU_ALLIANCE));
  	data << NA_MAP_WYVERN_NORTH_H
  			<< uint32(bool(m_WyvernStateNorth & WYVERN_HORDE));
  	data << NA_MAP_WYVERN_NORTH_A
  			<< uint32(bool(m_WyvernStateNorth & WYVERN_ALLIANCE));
  
  	data << NA_MAP_WYVERN_SOUTH_NEU_H
  			<< uint32(bool(m_WyvernStateSouth & WYVERN_NEU_HORDE));
  	data << NA_MAP_WYVERN_SOUTH_NEU_A
  			<< uint32(bool(m_WyvernStateSouth & WYVERN_NEU_ALLIANCE));
  	data << NA_MAP_WYVERN_SOUTH_H
  			<< uint32(bool(m_WyvernStateSouth & WYVERN_HORDE));
  	data << NA_MAP_WYVERN_SOUTH_A
  			<< uint32(bool(m_WyvernStateSouth & WYVERN_ALLIANCE));
  
  	data << NA_MAP_WYVERN_WEST_NEU_H
  			<< uint32(bool(m_WyvernStateWest & WYVERN_NEU_HORDE));
  	data << NA_MAP_WYVERN_WEST_NEU_A
  			<< uint32(bool(m_WyvernStateWest & WYVERN_NEU_ALLIANCE));
  	data << NA_MAP_WYVERN_WEST_H
  			<< uint32(bool(m_WyvernStateWest & WYVERN_HORDE));
  	data << NA_MAP_WYVERN_WEST_A
  			<< uint32(bool(m_WyvernStateWest & WYVERN_ALLIANCE));
  
  	data << NA_MAP_WYVERN_EAST_NEU_H
  			<< uint32(bool(m_WyvernStateEast & WYVERN_NEU_HORDE));
  	data << NA_MAP_WYVERN_EAST_NEU_A
  			<< uint32(bool(m_WyvernStateEast & WYVERN_NEU_ALLIANCE));
  	data << NA_MAP_WYVERN_EAST_H
  			<< uint32(bool(m_WyvernStateEast & WYVERN_HORDE));
  	data << NA_MAP_WYVERN_EAST_A
  			<< uint32(bool(m_WyvernStateEast & WYVERN_ALLIANCE));
  
  	data << NA_MAP_HALAA_NEUTRAL << uint32(bool(m_HalaaState & HALAA_N));
  	data << NA_MAP_HALAA_NEU_A << uint32(bool(m_HalaaState & HALAA_N_A));
  	data << NA_MAP_HALAA_NEU_H << uint32(bool(m_HalaaState & HALAA_N_H));
  	data << NA_MAP_HALAA_HORDE << uint32(bool(m_HalaaState & HALAA_H));
  	data << NA_MAP_HALAA_ALLIANCE << uint32(bool(m_HalaaState & HALAA_A));
  }
  
  void OutdoorPvPNA::SendRemoveWorldStates(Player *plr) {
  	plr->SendUpdateWorldState(NA_UI_HORDE_GUARDS_SHOW, 0);
  	plr->SendUpdateWorldState(NA_UI_ALLIANCE_GUARDS_SHOW, 0);
  	plr->SendUpdateWorldState(NA_UI_GUARDS_MAX, 0);
  	plr->SendUpdateWorldState(NA_UI_GUARDS_LEFT, 0);
  	plr->SendUpdateWorldState(NA_UI_TOWER_SLIDER_DISPLAY, 0);
  	plr->SendUpdateWorldState(NA_UI_TOWER_SLIDER_POS, 0);
  	plr->SendUpdateWorldState(NA_UI_TOWER_SLIDER_N, 0);
  	plr->SendUpdateWorldState(NA_MAP_WYVERN_NORTH_NEU_H, 0);
  	plr->SendUpdateWorldState(NA_MAP_WYVERN_NORTH_NEU_A, 0);
  	plr->SendUpdateWorldState(NA_MAP_WYVERN_NORTH_H, 0);
  	plr->SendUpdateWorldState(NA_MAP_WYVERN_NORTH_A, 0);
  	plr->SendUpdateWorldState(NA_MAP_WYVERN_SOUTH_NEU_H, 0);
  	plr->SendUpdateWorldState(NA_MAP_WYVERN_SOUTH_NEU_A, 0);
  	plr->SendUpdateWorldState(NA_MAP_WYVERN_SOUTH_H, 0);
  	plr->SendUpdateWorldState(NA_MAP_WYVERN_SOUTH_A, 0);
  	plr->SendUpdateWorldState(NA_MAP_WYVERN_WEST_NEU_H, 0);
  	plr->SendUpdateWorldState(NA_MAP_WYVERN_WEST_NEU_A, 0);
  	plr->SendUpdateWorldState(NA_MAP_WYVERN_WEST_H, 0);
  	plr->SendUpdateWorldState(NA_MAP_WYVERN_WEST_A, 0);
  	plr->SendUpdateWorldState(NA_MAP_WYVERN_EAST_NEU_H, 0);
  	plr->SendUpdateWorldState(NA_MAP_WYVERN_EAST_NEU_A, 0);
  	plr->SendUpdateWorldState(NA_MAP_WYVERN_EAST_H, 0);
  	plr->SendUpdateWorldState(NA_MAP_WYVERN_EAST_A, 0);
  	plr->SendUpdateWorldState(NA_MAP_HALAA_NEUTRAL, 0);
  	plr->SendUpdateWorldState(NA_MAP_HALAA_NEU_A, 0);
  	plr->SendUpdateWorldState(NA_MAP_HALAA_NEU_H, 0);
  	plr->SendUpdateWorldState(NA_MAP_HALAA_HORDE, 0);
  	plr->SendUpdateWorldState(NA_MAP_HALAA_ALLIANCE, 0);
  }
  
  bool OutdoorPvPNA::Update(uint32 diff) {
  	return m_obj->Update(diff);
  }
  
  bool OPvPCapturePointNA::HandleCustomSpell(Player * plr, uint32 spellId,
  		GameObject * /*go*/) {
  	std::vector<uint32> nodes;
  	nodes.resize(2);
  	bool retval = false;
  	switch (spellId) {
  	case NA_SPELL_FLY_NORTH:
  		nodes[0] = FlightPathStartNodes[NA_ROOST_N];
  		nodes[1] = FlightPathEndNodes[NA_ROOST_N];
  		plr->ActivateTaxiPathTo(nodes);
  		plr->SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP);
  		plr->UpdatePvP(true, true);
  		retval = true;
  		break;
  	case NA_SPELL_FLY_SOUTH:
  		nodes[0] = FlightPathStartNodes[NA_ROOST_S];
  		nodes[1] = FlightPathEndNodes[NA_ROOST_S];
  		plr->ActivateTaxiPathTo(nodes);
  		plr->SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP);
  		plr->UpdatePvP(true, true);
  		retval = true;
  		break;
  	case NA_SPELL_FLY_WEST:
  		nodes[0] = FlightPathStartNodes[NA_ROOST_W];
  		nodes[1] = FlightPathEndNodes[NA_ROOST_W];
  		plr->ActivateTaxiPathTo(nodes);
  		plr->SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP);
  		plr->UpdatePvP(true, true);
  		retval = true;
  		break;
  	case NA_SPELL_FLY_EAST:
  		nodes[0] = FlightPathStartNodes[NA_ROOST_E];
  		nodes[1] = FlightPathEndNodes[NA_ROOST_E];
  		plr->ActivateTaxiPathTo(nodes);
  		plr->SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP);
  		plr->UpdatePvP(true, true);
  		retval = true;
  		break;
  	default:
  		break;
  	}
  
  	if (retval) {
  		//Adding items
  		uint32 noSpaceForCount = 0;
  
  		// check space and find places
  		ItemPosCountVec dest;
  
  		int32 count = 10;
  		uint32 itemid = 24538;
  		// bomb id count
  		uint8 msg = plr->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, itemid,
  				count, &noSpaceForCount);
  		if (msg != EQUIP_ERR_OK) // convert to possible store amount
  			count -= noSpaceForCount;
  
  		if (count == 0 || dest.empty()) // can't add any
  				{
  			return true;
  		}
  
  		Item* item = plr->StoreNewItem(dest, itemid, true);
  
  		if (count > 0 && item) {
  			plr->SendNewItem(item, count, true, false);
  		}
  
  		return true;
  	}
  	return false;
  }
  
  int32 OPvPCapturePointNA::HandleOpenGo(Player *plr, uint64 guid) {
  	int32 retval = OPvPCapturePoint::HandleOpenGo(plr, guid);
  	if (retval >= 0) {
  		const go_type * gos = NULL;
  		if (m_ControllingFaction == ALLIANCE)
  			gos = AllianceControlGOs;
  		else if (m_ControllingFaction == HORDE)
  			gos = HordeControlGOs;
  		else
  			return -1;
  
  		int32 del = -1;
  		int32 del2 = -1;
  		int32 add = -1;
  		int32 add2 = -1;
  
  		switch (retval) {
  		case NA_DESTROYED_ROOST_S:
  			del = NA_DESTROYED_ROOST_S;
  			add = NA_ROOST_S;
  			add2 = NA_BOMB_WAGON_S;
  			if (m_ControllingFaction == HORDE)
  				m_WyvernStateSouth = WYVERN_ALLIANCE;
  			else
  				m_WyvernStateSouth = WYVERN_HORDE;
  			UpdateWyvernRoostWorldState(NA_ROOST_S);
  			break;
  		case NA_DESTROYED_ROOST_N:
  			del = NA_DESTROYED_ROOST_N;
  			add = NA_ROOST_N;
  			add2 = NA_BOMB_WAGON_N;
  			if (m_ControllingFaction == HORDE)
  				m_WyvernStateNorth = WYVERN_ALLIANCE;
  			else
  				m_WyvernStateNorth = WYVERN_HORDE;
  			UpdateWyvernRoostWorldState(NA_ROOST_N);
  			break;
  		case NA_DESTROYED_ROOST_W:
  			del = NA_DESTROYED_ROOST_W;
  			add = NA_ROOST_W;
  			add2 = NA_BOMB_WAGON_W;
  			if (m_ControllingFaction == HORDE)
  				m_WyvernStateWest = WYVERN_ALLIANCE;
  			else
  				m_WyvernStateWest = WYVERN_HORDE;
  			UpdateWyvernRoostWorldState(NA_ROOST_W);
  			break;
  		case NA_DESTROYED_ROOST_E:
  			del = NA_DESTROYED_ROOST_E;
  			add = NA_ROOST_E;
  			add2 = NA_BOMB_WAGON_E;
  			if (m_ControllingFaction == HORDE)
  				m_WyvernStateEast = WYVERN_ALLIANCE;
  			else
  				m_WyvernStateEast = WYVERN_HORDE;
  			UpdateWyvernRoostWorldState(NA_ROOST_E);
  			break;
  		case NA_BOMB_WAGON_S:
  			del = NA_BOMB_WAGON_S;
  			del2 = NA_ROOST_S;
  			add = NA_DESTROYED_ROOST_S;
  			if (m_ControllingFaction == HORDE)
  				m_WyvernStateSouth = WYVERN_NEU_ALLIANCE;
  			else
  				m_WyvernStateSouth = WYVERN_NEU_HORDE;
  			UpdateWyvernRoostWorldState(NA_ROOST_S);
  			break;
  		case NA_BOMB_WAGON_N:
  			del = NA_BOMB_WAGON_N;
  			del2 = NA_ROOST_N;
  			add = NA_DESTROYED_ROOST_N;
  			if (m_ControllingFaction == HORDE)
  				m_WyvernStateNorth = WYVERN_NEU_ALLIANCE;
  			else
  				m_WyvernStateNorth = WYVERN_NEU_HORDE;
  			UpdateWyvernRoostWorldState(NA_ROOST_N);
  			break;
  		case NA_BOMB_WAGON_W:
  			del = NA_BOMB_WAGON_W;
  			del2 = NA_ROOST_W;
  			add = NA_DESTROYED_ROOST_W;
  			if (m_ControllingFaction == HORDE)
  				m_WyvernStateWest = WYVERN_NEU_ALLIANCE;
  			else
  				m_WyvernStateWest = WYVERN_NEU_HORDE;
  			UpdateWyvernRoostWorldState(NA_ROOST_W);
  			break;
  		case NA_BOMB_WAGON_E:
  			del = NA_BOMB_WAGON_E;
  			del2 = NA_ROOST_E;
  			add = NA_DESTROYED_ROOST_E;
  			if (m_ControllingFaction == HORDE)
  				m_WyvernStateEast = WYVERN_NEU_ALLIANCE;
  			else
  				m_WyvernStateEast = WYVERN_NEU_HORDE;
  			UpdateWyvernRoostWorldState(NA_ROOST_E);
  			break;
  		default:
  			return -1;
  			break;
  		}
  
  		if (del > -1)
  			DelObject(del);
  
  		if (del2 > -1)
  			DelObject(del2);
  
  		if (add > -1)
  			AddObject(add, gos[add].entry, gos[add].map, gos[add].x, gos[add].y,
  					gos[add].z, gos[add].o, gos[add].rot0, gos[add].rot1,
  					gos[add].rot2, gos[add].rot3);
  
  		if (add2 > -1)
  			AddObject(add2, gos[add2].entry, gos[add2].map, gos[add2].x,
  					gos[add2].y, gos[add2].z, gos[add2].o, gos[add2].rot0,
  					gos[add2].rot1, gos[add2].rot2, gos[add2].rot3);
  
  		return retval;
  	}
  	return -1;
  }
  
  bool OPvPCapturePointNA::Update(uint32 diff) {
  	// let the controlling faction advance in phase
  	bool capturable = false;
  	if (m_ControllingFaction == ALLIANCE
  			&& m_activePlayers[0].size() > m_activePlayers[1].size())
  		capturable = true;
  	else if (m_ControllingFaction == HORDE
  			&& m_activePlayers[0].size() < m_activePlayers[1].size())
  		capturable = true;
  
  	if (m_GuardCheckTimer < diff) {
  		m_GuardCheckTimer = NA_GUARD_CHECK_TIME;
  		uint32 cnt = GetAliveGuardsCount();
  		if (cnt != m_GuardsAlive) {
  			m_GuardsAlive = cnt;
  			if (m_GuardsAlive == 0)
  				m_capturable = true;
  			// update the guard count for the players in zone
  			m_PvP->SendUpdateWorldState(NA_UI_GUARDS_LEFT, m_GuardsAlive);
  		}
  	} else
  		m_GuardCheckTimer -= diff;
  
  	if (m_capturable || capturable) {
  		if (m_RespawnTimer < diff) {
  			// if the guards have been killed, then the challenger has one hour to take over halaa.
  			// in case they fail to do it, the guards are respawned, and they have to start again.
  			if (m_ControllingFaction)
  				FactionTakeOver(m_ControllingFaction);
  			m_RespawnTimer = NA_RESPAWN_TIME;
  		} else
  			m_RespawnTimer -= diff;
  
  		return OPvPCapturePoint::Update(diff);
  	}
  	return false;
  }
  
  void OPvPCapturePointNA::ChangeState() {
  	uint32 artkit = 21;
  	switch (m_State) {
  	case OBJECTIVESTATE_NEUTRAL:
  		m_HalaaState = HALAA_N;
  		break;
  	case OBJECTIVESTATE_ALLIANCE:
  		m_HalaaState = HALAA_A;
  		FactionTakeOver(ALLIANCE);
  		artkit = 2;
  		break;
  	case OBJECTIVESTATE_HORDE:
  		m_HalaaState = HALAA_H;
  		FactionTakeOver(HORDE);
  		artkit = 1;
  		break;
  	case OBJECTIVESTATE_NEUTRAL_ALLIANCE_CHALLENGE:
  		m_HalaaState = HALAA_N_A;
  		break;
  	case OBJECTIVESTATE_NEUTRAL_HORDE_CHALLENGE:
  		m_HalaaState = HALAA_N_H;
  		break;
  	case OBJECTIVESTATE_ALLIANCE_HORDE_CHALLENGE:
  		m_HalaaState = HALAA_N_A;
  		artkit = 2;
  		break;
  	case OBJECTIVESTATE_HORDE_ALLIANCE_CHALLENGE:
  		m_HalaaState = HALAA_N_H;
  		artkit = 1;
  		break;
  	}
  
  	GameObject* flag = HashMapHolder<GameObject>::Find(m_capturePointGUID);
  	if (flag) {
  		flag->SetGoArtKit(artkit);
  	}
  
  	UpdateHalaaWorldState();
  }
  
  void OPvPCapturePointNA::SendChangePhase() {
  	// send this too, sometimes the slider disappears, dunno why :(
  	SendUpdateWorldState(NA_UI_TOWER_SLIDER_DISPLAY, 1);
  	// send these updates to only the ones in this objective
  	uint32 phase = (uint32) ceil(
  			(m_value + m_maxValue) / (2 * m_maxValue) * 100.0f);
  	SendUpdateWorldState(NA_UI_TOWER_SLIDER_POS, phase);
  	SendUpdateWorldState(NA_UI_TOWER_SLIDER_N, m_neutralValuePct);
  }
  
  void OPvPCapturePointNA::UpdateHalaaWorldState() {
  	m_PvP->SendUpdateWorldState(NA_MAP_HALAA_NEUTRAL,
  			uint32(bool(m_HalaaState & HALAA_N)));
  	m_PvP->SendUpdateWorldState(NA_MAP_HALAA_NEU_A,
  			uint32(bool(m_HalaaState & HALAA_N_A)));
  	m_PvP->SendUpdateWorldState(NA_MAP_HALAA_NEU_H,
  			uint32(bool(m_HalaaState & HALAA_N_H)));
  	m_PvP->SendUpdateWorldState(NA_MAP_HALAA_HORDE,
  			uint32(bool(m_HalaaState & HALAA_H)));
  	m_PvP->SendUpdateWorldState(NA_MAP_HALAA_ALLIANCE,
  			uint32(bool(m_HalaaState & HALAA_A)));
  }
  
  void OPvPCapturePointNA::UpdateWyvernRoostWorldState(uint32 roost) {
  	switch (roost) {
  	case NA_ROOST_S:
  		m_PvP->SendUpdateWorldState(NA_MAP_WYVERN_SOUTH_NEU_H,
  				uint32(bool(m_WyvernStateSouth & WYVERN_NEU_HORDE)));
  		m_PvP->SendUpdateWorldState(NA_MAP_WYVERN_SOUTH_NEU_A,
  				uint32(bool(m_WyvernStateSouth & WYVERN_NEU_ALLIANCE)));
  		m_PvP->SendUpdateWorldState(NA_MAP_WYVERN_SOUTH_H,
  				uint32(bool(m_WyvernStateSouth & WYVERN_HORDE)));
  		m_PvP->SendUpdateWorldState(NA_MAP_WYVERN_SOUTH_A,
  				uint32(bool(m_WyvernStateSouth & WYVERN_ALLIANCE)));
  		break;
  	case NA_ROOST_N:
  		m_PvP->SendUpdateWorldState(NA_MAP_WYVERN_NORTH_NEU_H,
  				uint32(bool(m_WyvernStateNorth & WYVERN_NEU_HORDE)));
  		m_PvP->SendUpdateWorldState(NA_MAP_WYVERN_NORTH_NEU_A,
  				uint32(bool(m_WyvernStateNorth & WYVERN_NEU_ALLIANCE)));
  		m_PvP->SendUpdateWorldState(NA_MAP_WYVERN_NORTH_H,
  				uint32(bool(m_WyvernStateNorth & WYVERN_HORDE)));
  		m_PvP->SendUpdateWorldState(NA_MAP_WYVERN_NORTH_A,
  				uint32(bool(m_WyvernStateNorth & WYVERN_ALLIANCE)));
  		break;
  	case NA_ROOST_W:
  		m_PvP->SendUpdateWorldState(NA_MAP_WYVERN_WEST_NEU_H,
  				uint32(bool(m_WyvernStateWest & WYVERN_NEU_HORDE)));
  		m_PvP->SendUpdateWorldState(NA_MAP_WYVERN_WEST_NEU_A,
  				uint32(bool(m_WyvernStateWest & WYVERN_NEU_ALLIANCE)));
  		m_PvP->SendUpdateWorldState(NA_MAP_WYVERN_WEST_H,
  				uint32(bool(m_WyvernStateWest & WYVERN_HORDE)));
  		m_PvP->SendUpdateWorldState(NA_MAP_WYVERN_WEST_A,
  				uint32(bool(m_WyvernStateWest & WYVERN_ALLIANCE)));
  		break;
  	case NA_ROOST_E:
  		m_PvP->SendUpdateWorldState(NA_MAP_WYVERN_EAST_NEU_H,
  				uint32(bool(m_WyvernStateEast & WYVERN_NEU_HORDE)));
  		m_PvP->SendUpdateWorldState(NA_MAP_WYVERN_EAST_NEU_A,
  				uint32(bool(m_WyvernStateEast & WYVERN_NEU_ALLIANCE)));
  		m_PvP->SendUpdateWorldState(NA_MAP_WYVERN_EAST_H,
  				uint32(bool(m_WyvernStateEast & WYVERN_HORDE)));
  		m_PvP->SendUpdateWorldState(NA_MAP_WYVERN_EAST_A,
  				uint32(bool(m_WyvernStateEast & WYVERN_ALLIANCE)));
  		break;
  	}
  }
  
  class OutdoorPvP_nagrand: public OutdoorPvPScript {
  public:
  
  	OutdoorPvP_nagrand() :
  			OutdoorPvPScript("outdoorpvp_na") {
  	}
  
  	OutdoorPvP* GetOutdoorPvP() const {
  		return new OutdoorPvPNA();
  	}
  };
  
  void AddSC_outdoorpvp_na() {
  	new OutdoorPvP_nagrand();
  }
  