mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-16 18:40:28 +00:00
fix(CORE/OPvP): Halaa Mechanics not working properly (#15634)
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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; }
|
||||
|
||||
Reference in New Issue
Block a user