fix(CORE/OPvP): Halaa Mechanics not working properly (#15634)

This commit is contained in:
Pedro Antonio
2024-01-14 18:00:53 +01:00
committed by GitHub
parent e30d904ae7
commit 2c7c3b6832
4 changed files with 602 additions and 157 deletions

View File

@@ -17,6 +17,8 @@
#include "OutdoorPvPNA.h"
#include "CreatureScript.h"
#include "GridNotifiers.h"
#include "ScriptedCreature.h"
#include "GameGraveyard.h"
#include "Language.h"
#include "MapMgr.h"
@@ -33,6 +35,43 @@ OutdoorPvPNA::OutdoorPvPNA()
m_obj = nullptr;
}
// SpawnIds from creatures
HalaaNPCS halaaNPCHorde;
HalaaNPCS halaaNPCAlly;
void OutdoorPvPNA::HandleKill(Player* killer, Unit* killed)
{
if (Group* group = killer->GetGroup())
{
for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
{
Player* groupGuy = itr->GetSource();
if (!groupGuy)
continue;
// skip if too far away
if (!groupGuy->IsAtGroupRewardDistance(killed) && killer != groupGuy)
continue;
// creature kills must be notified, even if not inside objective / not outdoor pvp active
// player kills only count if active and inside objective
if ((groupGuy->IsOutdoorPvPActive() && groupGuy->GetAreaId() == NA_HALAA_ZONE_ID) || killed->GetTypeId() == TYPEID_UNIT)
{
HandleKillImpl(groupGuy, killed);
}
}
}
else
{
// creature kills must be notified, even if not inside objective / not outdoor pvp active
if (killer && ((killer->IsOutdoorPvPActive() && killer->ToPlayer()->GetAreaId() == NA_HALAA_ZONE_ID) || killed->GetTypeId() == TYPEID_UNIT))
{
HandleKillImpl(killer, killed);
}
}
}
void OutdoorPvPNA::HandleKillImpl(Player* player, Unit* killed)
{
if (killed->GetTypeId() == TYPEID_PLAYER && player->GetTeamId() != killed->ToPlayer()->GetTeamId())
@@ -42,40 +81,36 @@ void OutdoorPvPNA::HandleKillImpl(Player* player, Unit* killed)
}
}
uint32 OPvPCapturePointNA::GetAliveGuardsCount()
void UpdateCreatureHalaa(ObjectGuid::LowType spawnId, Map* map, float x, float y)
{
uint32 cnt = 0;
for (auto itr = _creatures.begin(); itr != _creatures.end(); ++itr)
CreatureData& data = sObjectMgr->NewOrExistCreatureData(spawnId);
sObjectMgr->AddCreatureToGrid(spawnId, &data);
// Spawn if necessary (loaded grids only)
if (!map->Instanceable() && !map->IsRemovalGrid(x, y))
{
switch (itr->first)
Creature* creature = new Creature();
if (!creature->LoadCreatureFromDB(spawnId, map, true, false, true))
{
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:
{
auto bounds = _pvp->GetMap()->GetCreatureBySpawnIdStore().equal_range(itr->second);
for (auto itr2 = bounds.first; itr2 != bounds.second; ++itr2)
if (itr2->second->IsAlive())
++cnt;
break;
}
default:
break;
LOG_ERROR("sql.sql", "AddCreature: Cannot add creature spawnId {} to map", spawnId);
delete creature;
return;
}
}
return cnt;
}
uint32 OPvPCapturePointNA::GetAliveGuardsCount()
{
uint32 count = 0;
for (auto itr = _creatures.begin(); itr != _creatures.end(); ++itr)
{
auto bounds = _pvp->GetMap()->GetCreatureBySpawnIdStore().equal_range(itr->second);
for (auto itr2 = bounds.first; itr2 != bounds.second; ++itr2)
if (itr2->second->IsAlive() && (itr2->second->GetEntry() == NA_HALAANI_GUARD_A || itr2->second->GetEntry() == NA_HALAANI_GUARD_H))
++count;
}
return count;
}
TeamId OPvPCapturePointNA::GetControllingFaction() const
@@ -83,23 +118,41 @@ TeamId OPvPCapturePointNA::GetControllingFaction() const
return m_ControllingFaction;
}
void OPvPCapturePointNA::SpawnNPCsForTeam(TeamId teamId)
void OPvPCapturePointNA::DespawnCreatures(HalaaNPCS teamNPC)
{
const creature_type* creatures = nullptr;
if (teamId == TEAM_ALLIANCE)
creatures = AllianceControlNPCs;
else if (teamId == TEAM_HORDE)
creatures = HordeControlNPCs;
else
return;
for (int i = 0; i < NA_CONTROL_NPC_NUM; ++i)
AddCreature(i, creatures[i].entry, creatures[i].map, creatures[i].x, creatures[i].y, creatures[i].z, creatures[i].o, 1000000);
for (int i = 0; i < NA_HALAA_CREATURE_TEAM_SPAWN; i++)
{
ObjectGuid::LowType spawnId = teamNPC[i];
auto bounds = _pvp->GetMap()->GetCreatureBySpawnIdStore().equal_range(spawnId);
CreatureData const* data = sObjectMgr->GetCreatureData(spawnId);
for (auto itr = bounds.first; itr != bounds.second;)
{
// can happen when closing the core
Creature* c = itr->second;
if (c)
{
++itr;
c->AddObjectToRemoveList();
sObjectMgr->RemoveCreatureFromGrid(spawnId, data);
_creatures[i] = 0;
_creatureTypes[_creatures[i]] = 0;
}
}
}
}
void OPvPCapturePointNA::DeSpawnNPCs()
void OPvPCapturePointNA::SpawnNPCsForTeam(HalaaNPCS teamNPC)
{
for (int i = 0; i < NA_CONTROL_NPC_NUM; ++i)
DelCreature(i);
for (int i = 0; i < NA_HALAA_CREATURE_TEAM_SPAWN; i++)
{
ObjectGuid::LowType spawnId = teamNPC[i];
const CreatureData* data = sObjectMgr->GetCreatureData(spawnId);
if (data) {
UpdateCreatureHalaa(spawnId, _pvp->GetMap(), data->posX, data->posY);
_creatures[i] = spawnId;
_creatureTypes[_creatures[i]] = i;
}
}
}
void OPvPCapturePointNA::SpawnGOsForTeam(TeamId teamId)
@@ -126,7 +179,7 @@ void OPvPCapturePointNA::SpawnGOsForTeam(TeamId teamId)
}
}
void OPvPCapturePointNA::DeSpawnGOs()
void OPvPCapturePointNA::DespawnGOs()
{
for (int i = 0; i < NA_CONTROL_GO_NUM; ++i)
{
@@ -142,16 +195,16 @@ void OPvPCapturePointNA::FactionTakeOver(TeamId teamId)
sWorld->SendZoneText(NA_HALAA_GRAVEYARD_ZONE, sObjectMgr->GetAcoreStringForDBCLocale(LANG_OPVP_NA_LOSE_A));
else if (m_ControllingFaction == TEAM_HORDE)
sWorld->SendZoneText(NA_HALAA_GRAVEYARD_ZONE, sObjectMgr->GetAcoreStringForDBCLocale(LANG_OPVP_NA_LOSE_H));
DespawnCreatures(GetControllingFaction() == TEAM_HORDE ? halaaNPCHorde : halaaNPCAlly);
m_ControllingFaction = teamId;
if (m_ControllingFaction != TEAM_NEUTRAL)
sGraveyard->AddGraveyardLink(NA_HALAA_GRAVEYARD, NA_HALAA_GRAVEYARD_ZONE, m_ControllingFaction, false);
DeSpawnGOs();
DeSpawnNPCs();
DespawnGOs();
SpawnGOsForTeam(teamId);
SpawnNPCsForTeam(teamId);
SpawnNPCsForTeam(GetControllingFaction() == TEAM_HORDE ? halaaNPCHorde : halaaNPCAlly);
m_GuardsAlive = NA_GUARDS_MAX;
m_capturable = false;
m_canRecap = false;
this->UpdateHalaaWorldState();
if (teamId == TEAM_ALLIANCE)
{
@@ -205,7 +258,7 @@ void OPvPCapturePointNA::HandlePlayerLeave(Player* player)
OPvPCapturePointNA::OPvPCapturePointNA(OutdoorPvP* pvp) :
OPvPCapturePoint(pvp), m_capturable(true), m_GuardsAlive(0), m_ControllingFaction(TEAM_NEUTRAL),
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)
m_HalaaState(HALAA_N), m_RespawnTimer(NA_RESPAWN_TIME), m_GuardCheckTimer(NA_GUARD_CHECK_TIME), m_canRecap(true)
{
SetCapturePointData(182210, 530, -1572.57f, 7945.3f, -22.475f, 2.05949f, 0.0f, 0.0f, 0.857167f, 0.515038f);
}
@@ -223,6 +276,10 @@ bool OutdoorPvPNA::SetupOutdoorPvP()
return false;
AddCapturePoint(m_obj);
//Remove linked graveyard at the server start to avoid players spawning in halaa
sGraveyard->RemoveGraveyardLink(NA_HALAA_GRAVEYARD, NA_HALAA_GRAVEYARD_ZONE, TEAM_ALLIANCE, false);
sGraveyard->RemoveGraveyardLink(NA_HALAA_GRAVEYARD, NA_HALAA_GRAVEYARD_ZONE, TEAM_HORDE, false);
return true;
}
@@ -335,6 +392,12 @@ bool OutdoorPvPNA::Update(uint32 diff)
return m_obj->Update(diff);
}
void FlagPlayerPvP(Player* player)
{
player->SetPlayerFlag(PLAYER_FLAGS_IN_PVP);
player->UpdatePvP(true, true);
}
bool OPvPCapturePointNA::HandleCustomSpell(Player* player, uint32 spellId, GameObject* /*go*/)
{
std::vector<uint32> nodes;
@@ -346,32 +409,28 @@ bool OPvPCapturePointNA::HandleCustomSpell(Player* player, uint32 spellId, GameO
nodes[0] = FlightPathStartNodes[NA_ROOST_N];
nodes[1] = FlightPathEndNodes[NA_ROOST_N];
player->ActivateTaxiPathTo(nodes);
player->SetPlayerFlag(PLAYER_FLAGS_IN_PVP);
player->UpdatePvP(true, true);
FlagPlayerPvP(player);
retval = true;
break;
case NA_SPELL_FLY_SOUTH:
nodes[0] = FlightPathStartNodes[NA_ROOST_S];
nodes[1] = FlightPathEndNodes[NA_ROOST_S];
player->ActivateTaxiPathTo(nodes);
player->SetPlayerFlag(PLAYER_FLAGS_IN_PVP);
player->UpdatePvP(true, true);
FlagPlayerPvP(player);
retval = true;
break;
case NA_SPELL_FLY_WEST:
nodes[0] = FlightPathStartNodes[NA_ROOST_W];
nodes[1] = FlightPathEndNodes[NA_ROOST_W];
player->ActivateTaxiPathTo(nodes);
player->SetPlayerFlag(PLAYER_FLAGS_IN_PVP);
player->UpdatePvP(true, true);
FlagPlayerPvP(player);
retval = true;
break;
case NA_SPELL_FLY_EAST:
nodes[0] = FlightPathStartNodes[NA_ROOST_E];
nodes[1] = FlightPathEndNodes[NA_ROOST_E];
player->ActivateTaxiPathTo(nodes);
player->SetPlayerFlag(PLAYER_FLAGS_IN_PVP);
player->UpdatePvP(true, true);
FlagPlayerPvP(player);
retval = true;
break;
default:
@@ -387,9 +446,8 @@ bool OPvPCapturePointNA::HandleCustomSpell(Player* player, uint32 spellId, GameO
ItemPosCountVec dest;
int32 count = 10;
uint32 itemid = 24538;
// bomb id count
InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, itemid, count, &noSpaceForCount);
InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, NA_HALAA_BOMB, count, &noSpaceForCount);
if (msg != EQUIP_ERR_OK) // convert to possible store amount
count -= noSpaceForCount;
@@ -398,7 +456,7 @@ bool OPvPCapturePointNA::HandleCustomSpell(Player* player, uint32 spellId, GameO
return true;
}
Item* item = player->StoreNewItem(dest, itemid, true);
Item* item = player->StoreNewItem(dest, NA_HALAA_BOMB, true);
if (count > 0 && item)
{
@@ -439,6 +497,7 @@ int32 OPvPCapturePointNA::HandleOpenGo(Player* player, GameObject* go)
else
m_WyvernStateSouth = WYVERN_HORDE;
UpdateWyvernRoostWorldState(NA_ROOST_S);
FlagPlayerPvP(player);
break;
case NA_DESTROYED_ROOST_N:
del = NA_DESTROYED_ROOST_N;
@@ -449,6 +508,7 @@ int32 OPvPCapturePointNA::HandleOpenGo(Player* player, GameObject* go)
else
m_WyvernStateNorth = WYVERN_HORDE;
UpdateWyvernRoostWorldState(NA_ROOST_N);
FlagPlayerPvP(player);
break;
case NA_DESTROYED_ROOST_W:
del = NA_DESTROYED_ROOST_W;
@@ -459,6 +519,7 @@ int32 OPvPCapturePointNA::HandleOpenGo(Player* player, GameObject* go)
else
m_WyvernStateWest = WYVERN_HORDE;
UpdateWyvernRoostWorldState(NA_ROOST_W);
FlagPlayerPvP(player);
break;
case NA_DESTROYED_ROOST_E:
del = NA_DESTROYED_ROOST_E;
@@ -469,6 +530,7 @@ int32 OPvPCapturePointNA::HandleOpenGo(Player* player, GameObject* go)
else
m_WyvernStateEast = WYVERN_HORDE;
UpdateWyvernRoostWorldState(NA_ROOST_E);
FlagPlayerPvP(player);
break;
case NA_BOMB_WAGON_S:
del = NA_BOMB_WAGON_S;
@@ -479,6 +541,7 @@ int32 OPvPCapturePointNA::HandleOpenGo(Player* player, GameObject* go)
else
m_WyvernStateSouth = WYVERN_NEU_HORDE;
UpdateWyvernRoostWorldState(NA_ROOST_S);
FlagPlayerPvP(player);
break;
case NA_BOMB_WAGON_N:
del = NA_BOMB_WAGON_N;
@@ -489,6 +552,7 @@ int32 OPvPCapturePointNA::HandleOpenGo(Player* player, GameObject* go)
else
m_WyvernStateNorth = WYVERN_NEU_HORDE;
UpdateWyvernRoostWorldState(NA_ROOST_N);
FlagPlayerPvP(player);
break;
case NA_BOMB_WAGON_W:
del = NA_BOMB_WAGON_W;
@@ -499,6 +563,7 @@ int32 OPvPCapturePointNA::HandleOpenGo(Player* player, GameObject* go)
else
m_WyvernStateWest = WYVERN_NEU_HORDE;
UpdateWyvernRoostWorldState(NA_ROOST_W);
FlagPlayerPvP(player);
break;
case NA_BOMB_WAGON_E:
del = NA_BOMB_WAGON_E;
@@ -509,6 +574,7 @@ int32 OPvPCapturePointNA::HandleOpenGo(Player* player, GameObject* go)
else
m_WyvernStateEast = WYVERN_NEU_HORDE;
UpdateWyvernRoostWorldState(NA_ROOST_E);
FlagPlayerPvP(player);
break;
default:
return -1;
@@ -534,12 +600,34 @@ int32 OPvPCapturePointNA::HandleOpenGo(Player* player, GameObject* go)
bool OPvPCapturePointNA::Update(uint32 diff)
{
// let the controlling faction advance in phase
bool capturable = false;
if (m_ControllingFaction == TEAM_ALLIANCE && _activePlayers[0].size() > _activePlayers[1].size())
capturable = true;
else if (m_ControllingFaction == TEAM_HORDE && _activePlayers[0].size() < _activePlayers[1].size())
capturable = true;
if (!_capturePoint)
return false;
float radius = ((float)_capturePoint->GetGOInfo()->capturePoint.radius);
for (PlayerSet playerSet : _activePlayers)
{
for (ObjectGuid playerGuid : playerSet)
{
if (Player* player = ObjectAccessor::FindPlayer(playerGuid))
if (!_capturePoint->IsWithinDistInMap(player, radius) || !player->IsOutdoorPvPActive())
HandlePlayerLeave(player);
}
}
std::list<Player*> players;
Acore::AnyPlayerInObjectRangeCheck checker(_capturePoint, radius);
Acore::PlayerListSearcher<Acore::AnyPlayerInObjectRangeCheck> searcher(_capturePoint, players, checker);
Cell::VisitWorldObjects(_capturePoint, searcher, radius);
for (Player* player : players)
{
if (player->IsOutdoorPvPActive())
{
if (_activePlayers[player->GetTeamId()].insert(player->GetGUID()).second)
HandlePlayerEnter(player);
}
}
if (m_GuardCheckTimer < diff)
{
@@ -549,26 +637,148 @@ bool OPvPCapturePointNA::Update(uint32 diff)
{
m_GuardsAlive = cnt;
if (m_GuardsAlive == 0)
{
m_capturable = true;
m_RespawnTimer = NA_RESPAWN_TIME;
sWorld->SendZoneText(NA_HALAA_GRAVEYARD_ZONE, sObjectMgr->GetAcoreStringForDBCLocale(LANG_OPVP_NA_DEFENSELESS));
}
else
m_capturable = false;
// update the guard count for the players in zone
_pvp->SendUpdateWorldState(NA_UI_GUARDS_LEFT, m_GuardsAlive);
}
}
else m_GuardCheckTimer -= diff;
if (m_capturable || capturable)
{
if (m_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;
if (GetControllingFaction() == TEAM_ALLIANCE) {
_state = OBJECTIVESTATE_ALLIANCE;
_value = _maxValue;
}
else
{
_state = OBJECTIVESTATE_HORDE;
_value = -_maxValue;
}
// we reset again the artkit, map icons, sliders and respawn Halaa for controller team
SendChangePhase();
ChangeState();
FactionTakeOver(GetControllingFaction());
return true;
}
else if (GetControllingFaction() != TEAM_NEUTRAL) // Don't decrease the respawn timer if the team is not HORDE or ALLIANCE
m_RespawnTimer -= diff;
// get the difference of numbers
float factDiff = ((float)_activePlayers[0].size() - (float)_activePlayers[1].size()) * diff / OUTDOORPVP_OBJECTIVE_UPDATE_INTERVAL;
if (!factDiff)
return false;
float maxDiff = _maxSpeed * diff;
if (factDiff < 0)
{
// horde is in majority, but it's already horde-controlled -> no change
if (_state == OBJECTIVESTATE_HORDE && _value <= -_maxValue)
return false;
if (factDiff < -maxDiff)
factDiff = -maxDiff;
}
else
{
// ally is in majority, but it's already ally-controlled -> no change
if (_state == OBJECTIVESTATE_ALLIANCE && _value >= _maxValue)
return false;
if (factDiff > maxDiff)
factDiff = maxDiff;
}
float oldValue = _value;
TeamId oldTeam = _team;
_oldState = _state;
_value += factDiff;
if (_value < -_minValue) // red
{
if (_value < -_maxValue) //check if the m_value is lower than max, that means horde capped point
{
_value = -_maxValue;
_state = OBJECTIVESTATE_HORDE;
_team = TEAM_HORDE;
}
else //then point is still in battle between teams
{
if (_oldState == OBJECTIVESTATE_NEUTRAL || _oldState == OBJECTIVESTATE_NEUTRAL_HORDE_CHALLENGE || _oldState == OBJECTIVESTATE_NEUTRAL_ALLIANCE_CHALLENGE)
{
_state = OBJECTIVESTATE_NEUTRAL_HORDE_CHALLENGE;
}
else
{
_state = OBJECTIVESTATE_HORDE_ALLIANCE_CHALLENGE;
}
}
if (GetControllingFaction() == TEAM_ALLIANCE && !m_canRecap)
{
//When the point goes through neutral, the same faction can recapture again to respawn the guards, still need check blizzlike
m_canRecap = true;
DespawnGOs();
DespawnCreatures(GetControllingFaction() == TEAM_HORDE ? halaaNPCHorde : halaaNPCAlly);
}
}
else //blue
{
if (_value > _maxValue) //check if the m_value is bigger than max, that means alliance capped point
{
_value = _maxValue;
_state = OBJECTIVESTATE_ALLIANCE;
_team = TEAM_ALLIANCE;
}
else //then point is still in battle between teams
{
if (_oldState == OBJECTIVESTATE_NEUTRAL || _oldState == OBJECTIVESTATE_NEUTRAL_HORDE_CHALLENGE || _oldState == OBJECTIVESTATE_NEUTRAL_ALLIANCE_CHALLENGE)
{
_state = OBJECTIVESTATE_NEUTRAL_ALLIANCE_CHALLENGE;
}
else
{
_state = OBJECTIVESTATE_ALLIANCE_HORDE_CHALLENGE;
}
}
if (GetControllingFaction() == TEAM_HORDE && !m_canRecap)
{
//When the point goes through neutral, the same faction can recapture again to respawn the guards, still need check blizzlike
m_canRecap = true;
DespawnGOs();
DespawnCreatures(GetControllingFaction() == TEAM_HORDE ? halaaNPCHorde : halaaNPCAlly);
}
}
if (_value != oldValue)
{
SendChangePhase();
}
if (_oldState != _state)
{
if (oldTeam != _team)
{
ChangeTeam(oldTeam);
}
ChangeState();
return true;
}
else m_RespawnTimer -= diff;
}
return OPvPCapturePoint::Update(diff);
else
SendUpdateWorldState(NA_UI_TOWER_SLIDER_DISPLAY, 0); //Point is not capturable so we hide the slider
return false;
}
void OPvPCapturePointNA::ChangeState()
@@ -581,12 +791,14 @@ void OPvPCapturePointNA::ChangeState()
break;
case OBJECTIVESTATE_ALLIANCE:
m_HalaaState = HALAA_A;
FactionTakeOver(TEAM_ALLIANCE);
if(m_canRecap)
FactionTakeOver(TEAM_ALLIANCE);
artkit = 2;
break;
case OBJECTIVESTATE_HORDE:
m_HalaaState = HALAA_H;
FactionTakeOver(TEAM_HORDE);
if (m_canRecap)
FactionTakeOver(TEAM_HORDE);
artkit = 1;
break;
case OBJECTIVESTATE_NEUTRAL_ALLIANCE_CHALLENGE:
@@ -665,10 +877,7 @@ void OPvPCapturePointNA::UpdateWyvernRoostWorldState(uint32 roost)
class OutdoorPvP_nagrand : public OutdoorPvPScript
{
public:
OutdoorPvP_nagrand()
: OutdoorPvPScript("outdoorpvp_na")
{
}
OutdoorPvP_nagrand() : OutdoorPvPScript("outdoorpvp_na") { }
OutdoorPvP* GetOutdoorPvP() const override
{
@@ -676,8 +885,47 @@ public:
}
};
struct outdoorpvp_na_halaa_creatures : public ScriptedAI
{
outdoorpvp_na_halaa_creatures(Creature* creature) : ScriptedAI(creature) { }
void UpdateAI(uint32 /*diff*/) override
{
if (halaaNPCHorde.size() != NA_HALAA_CREATURE_TEAM_SPAWN && halaaNPCAlly.size() != NA_HALAA_CREATURE_TEAM_SPAWN)
{
std::list<Creature*> creatures;
uint32 entry = 0;
for (int i = 0; i < NA_HALAA_CREATURES; i++)
{
me->GetCreatureListWithEntryInGrid(creatures, PatrolCreatureEntry[i].idPatrol, 250);
}
if (creatures.size() == NA_HALAA_MAX_CREATURE_SPAWN)
{
for (std::list<Creature*>::iterator itr = creatures.begin(); itr != creatures.end(); ++itr)
{
Creature* const c = *itr;
if (entry < NA_HALAA_CREATURE_TEAM_SPAWN)
{
halaaNPCHorde[entry] = c->GetSpawnId();
}
else
{
halaaNPCAlly[entry - NA_HALAA_CREATURE_TEAM_SPAWN] = c->GetSpawnId();
}
c->AddObjectToRemoveList();
entry++;
sObjectMgr->RemoveCreatureFromGrid(c->GetSpawnId(), c->GetCreatureData());
}
}
}
DoMeleeAttackIfReady();
}
};
void AddSC_outdoorpvp_na()
{
new OutdoorPvP_nagrand();
RegisterCreatureAI(outdoorpvp_na_halaa_creatures);
}

View File

@@ -40,10 +40,14 @@ const uint32 NA_HALAA_GRAVEYARD = 993;
const uint32 NA_HALAA_GRAVEYARD_ZONE = 3518; // need to add zone id, not area id
uint32 const NA_HALAA_ZONE_ID = 3628; // halaa zone id
const uint32 NA_RESPAWN_TIME = 3600000; // one hour to capture after defeating all guards
const uint32 NA_GUARD_CHECK_TIME = 500; // every half second
const uint32 NA_HALAA_BOMB = 24538; // Item id Bomb throwed in Halaa
enum OutdoorPvPNAWorldStates
{
NA_UI_HORDE_GUARDS_SHOW = 2503,
@@ -116,6 +120,20 @@ enum FlightSpellsNA
NA_SPELL_FLY_EAST = 32081
};
//Npc ids from Halaa guards, Ally and Horde
enum HalaaGuardsNA
{
NA_HALAANI_GUARD_A = 18256,
NA_HALAANI_GUARD_H = 18192
};
enum HalaaCreaturesSpawn
{
NA_HALAA_CREATURES = 12, //Quantity of creatures_templates contains HALAA
NA_HALAA_CREATURE_TEAM_SPAWN = 20, //Number of creatures by team
NA_HALAA_MAX_CREATURE_SPAWN = 40 //Number of creatures by both teams
};
// spawned when the alliance is attacking, horde is in control
const go_type HordeControlGOs[NA_CONTROL_GO_NUM] =
{
@@ -125,9 +143,9 @@ const go_type HordeControlGOs[NA_CONTROL_GO_NUM] =
{182282, 530, -1650.11f, 7732.56f, -15.4505f, -2.80998f, 0.0f, 0.0f, 0.986286f, -0.165048f}, //ALLY_ROOST_EAST
{182222, 530, -1825.4022f, 8039.2602f, -26.08f, -2.89725f, 0.0f, 0.0f, 0.992546f, -0.121869f}, //HORDE_BOMB_WAGON_SOUTH
{182272, 530, -1515.37f, 8136.91f, -20.42f, -1.3439f, 0.0f, 0.0f, 0.622515f, -0.782608f}, //HORDE_BOMB_WAGON_WEST
{182273, 530, -1377.95f, 7773.44f, -10.31f, -0.575959f, 0.0f, 0.0f, 0.284015f, -0.95882f}, //HORDE_BOMB_WAGON_NORTH
{182274, 530, -1659.87f, 7733.15f, -15.75f, -2.80998f, 0.0f, 0.0f, 0.986286f, -0.165048f}, //HORDE_BOMB_WAGON_EAST
{182272, 530, -1517.44f, 8140.24f, -20.17f, -2.8099f, 0.0f, 0.0f, 0.622515f, -0.782608f}, //HORDE_BOMB_WAGON_WEST
{182273, 530, -1389.53f, 7782.50f, -11.62f, -1.5184f, 0.0f, 0.0f, 0.284015f, -0.95882f}, //HORDE_BOMB_WAGON_NORTH
{182274, 530, -1662.28f, 7735.00f, -15.96f, 1.8845f, 0.0f, 0.0f, 0.986286f, -0.165048f}, //HORDE_BOMB_WAGON_EAST
{182266, 530, -1815.8f, 8036.51f, -26.2354f, -2.89725f, 0.0f, 0.0f, 0.992546f, -0.121869f}, //DESTROYED_ALLY_ROOST_SOUTH
{182275, 530, -1507.95f, 8132.1f, -19.5585f, -1.3439f, 0.0f, 0.0f, 0.622515f, -0.782608f}, //DESTROYED_ALLY_ROOST_WEST
@@ -144,9 +162,9 @@ const go_type AllianceControlGOs[NA_CONTROL_GO_NUM] =
{182304, 530, -1650.11f, 7732.56f, -15.4505f, -2.80998f, 0.0f, 0.0f, 0.986286f, -0.165048f}, //HORDE_ROOST_EAST
{182305, 530, -1825.4022f, 8039.2602f, -26.08f, -2.89725f, 0.0f, 0.0f, 0.992546f, -0.121869f}, //ALLY_BOMB_WAGON_SOUTH
{182306, 530, -1515.37f, 8136.91f, -20.42f, -1.3439f, 0.0f, 0.0f, 0.622515f, -0.782608f}, //ALLY_BOMB_WAGON_WEST
{182307, 530, -1377.95f, 7773.44f, -10.31f, -0.575959f, 0.0f, 0.0f, 0.284015f, -0.95882f}, //ALLY_BOMB_WAGON_NORTH
{182308, 530, -1659.87f, 7733.15f, -15.75f, -2.80998f, 0.0f, 0.0f, 0.986286f, -0.165048f}, //ALLY_BOMB_WAGON_EAST
{182306, 530, -1517.44f, 8140.24f, -20.17f, -2.8099f, 0.0f, 0.0f, 0.622515f, -0.782608f}, //ALLY_BOMB_WAGON_WEST
{182307, 530, -1389.53f, 7782.50f, -11.62f, -1.5184f, 0.0f, 0.0f, 0.284015f, -0.95882f}, //ALLY_BOMB_WAGON_NORTH
{182308, 530, -1662.28f, 7735.00f, -15.96f, 1.8845f, 0.0f, 0.0f, 0.986286f, -0.165048f}, //ALLY_BOMB_WAGON_EAST
{182297, 530, -1815.8f, 8036.51f, -26.2354f, -2.89725f, 0.0f, 0.0f, 0.992546f, -0.121869f}, //DESTROYED_HORDE_ROOST_SOUTH
{182298, 530, -1507.95f, 8132.1f, -19.5585f, -1.3439f, 0.0f, 0.0f, 0.622515f, -0.782608f}, //DESTROYED_HORDE_ROOST_WEST
@@ -154,79 +172,27 @@ const go_type AllianceControlGOs[NA_CONTROL_GO_NUM] =
{182300, 530, -1650.11f, 7732.56f, -15.4505f, -2.80998f, 0.0f, 0.0f, 0.986286f, -0.165048f} //DESTROYED_HORDE_ROOST_EAST
};
enum ControlNPCTypes
struct HalaaIds
{
NA_NPC_RESEARCHER = 0,
NA_NPC_QUARTERMASTER,
NA_NPC_BLADE_MERCHANT,
NA_NPC_FOOD_MERCHANT,
NA_NPC_AMMO,
NA_NPC_GUARD_01,
NA_NPC_GUARD_02,
NA_NPC_GUARD_03,
NA_NPC_GUARD_04,
NA_NPC_GUARD_05,
NA_NPC_GUARD_06,
NA_NPC_GUARD_07,
NA_NPC_GUARD_08,
NA_NPC_GUARD_09,
NA_NPC_GUARD_10,
NA_NPC_GUARD_11,
NA_NPC_GUARD_12,
NA_NPC_GUARD_13,
NA_NPC_GUARD_14,
NA_NPC_GUARD_15,
NA_CONTROL_NPC_NUM
uint32 idPatrol;
};
const creature_type HordeControlNPCs[NA_CONTROL_NPC_NUM] =
const HalaaIds PatrolCreatureEntry[NA_HALAA_CREATURES] =
{
{18816, 530, -1523.92f, 7951.76f, -17.6942f, 3.51172f},
{18821, 530, -1527.75f, 7952.46f, -17.6948f, 3.99317f},
{21474, 530, -1520.14f, 7927.11f, -20.2527f, 3.39389f},
{21484, 530, -1524.84f, 7930.34f, -20.182f, 3.6405f},
{21483, 530, -1570.01f, 7993.8f, -22.4505f, 5.02655f},
{18192, 530, -1654.06f, 8000.46f, -26.59f, 3.37f},
{18192, 530, -1487.18f, 7899.1f, -19.53f, 0.954f},
{18192, 530, -1480.88f, 7908.79f, -19.19f, 4.485f},
{18192, 530, -1540.56f, 7995.44f, -20.45f, 0.947f},
{18192, 530, -1546.95f, 8000.85f, -20.72f, 6.035f},
{18192, 530, -1595.31f, 7860.53f, -21.51f, 3.747f},
{18192, 530, -1642.31f, 7995.59f, -25.8f, 3.317f},
{18192, 530, -1545.46f, 7995.35f, -20.63f, 1.094f},
{18192, 530, -1487.58f, 7907.99f, -19.27f, 5.567f},
{18192, 530, -1651.54f, 7988.56f, -26.5289f, 2.98451f},
{18192, 530, -1602.46f, 7866.43f, -22.1177f, 4.74729f},
{18192, 530, -1591.22f, 7875.29f, -22.3536f, 4.34587f},
{18192, 530, -1550.6f, 7944.45f, -21.63f, 3.559f},
{18192, 530, -1545.57f, 7935.83f, -21.13f, 3.448f},
{18192, 530, -1550.86f, 7937.56f, -21.7f, 3.801f}
};
const creature_type AllianceControlNPCs[NA_CONTROL_NPC_NUM] =
{
{18817, 530, -1591.18f, 8020.39f, -22.2042f, 4.59022f},
{18822, 530, -1588.0f, 8019.0f, -22.2042f, 4.06662f},
{21485, 530, -1521.93f, 7927.37f, -20.2299f, 3.24631f},
{21487, 530, -1540.33f, 7971.95f, -20.7186f, 3.07178f},
{21488, 530, -1570.01f, 7993.8f, -22.4505f, 5.02655f},
{18256, 530, -1654.06f, 8000.46f, -26.59f, 3.37f},
{18256, 530, -1487.18f, 7899.1f, -19.53f, 0.954f},
{18256, 530, -1480.88f, 7908.79f, -19.19f, 4.485f},
{18256, 530, -1540.56f, 7995.44f, -20.45f, 0.947f},
{18256, 530, -1546.95f, 8000.85f, -20.72f, 6.035f},
{18256, 530, -1595.31f, 7860.53f, -21.51f, 3.747f},
{18256, 530, -1642.31f, 7995.59f, -25.8f, 3.317f},
{18256, 530, -1545.46f, 7995.35f, -20.63f, 1.094f},
{18256, 530, -1487.58f, 7907.99f, -19.27f, 5.567f},
{18256, 530, -1651.54f, 7988.56f, -26.5289f, 2.98451f},
{18256, 530, -1602.46f, 7866.43f, -22.1177f, 4.74729f},
{18256, 530, -1591.22f, 7875.29f, -22.3536f, 4.34587f},
{18256, 530, -1603.75f, 8000.36f, -24.18f, 4.516f},
{18256, 530, -1585.73f, 7994.68f, -23.29f, 4.439f},
{18256, 530, -1595.5f, 7991.27f, -23.53f, 4.738f}
// Horde
{18192},
{18816},
{18821},
{21474},
{21484},
{21483},
// Ally
{18256},
{18817},
{18822},
{21485},
{21487},
{21488}
};
enum WyvernStates
@@ -246,6 +212,8 @@ enum HalaaStates
HALAA_H = 16
};
typedef std::map<uint32, ObjectGuid::LowType> HalaaNPCS;
class Unit;
class Creature;
class OutdoorPvPNA;
@@ -278,15 +246,14 @@ protected:
// called when a faction takes control
void FactionTakeOver(TeamId teamId);
void DeSpawnNPCs();
void DeSpawnGOs();
void DespawnGOs();
void DespawnCreatures(HalaaNPCS teamNPC);
void SpawnNPCsForTeam(TeamId teamId);
void SpawnNPCsForTeam(HalaaNPCS teamNPC);
void SpawnGOsForTeam(TeamId teamId);
void UpdateWyvernRoostWorldState(uint32 roost);
void UpdateHalaaWorldState();
private:
bool m_capturable;
@@ -304,6 +271,8 @@ private:
uint32 m_RespawnTimer;
uint32 m_GuardCheckTimer;
bool m_canRecap;
};
class OutdoorPvPNA : public OutdoorPvP
@@ -322,6 +291,8 @@ public:
void SendRemoveWorldStates(Player* player) override;
void HandleKill(Player* killer, Unit* killed) override;
void HandleKillImpl(Player* player, Unit* killed) override;
OPvPCapturePointNA* GetCapturePoint() { return m_obj; }