/*
* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
*
* 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, see .
*/
#include "OutdoorPvPHP.h"
#include "GameObject.h"
#include "Map.h"
#include "ObjectAccessor.h"
#include "Player.h"
#include "ScriptMgr.h"
#include "WorldStatePackets.h"
uint32 const OutdoorPvPHPBuffZonesNum = 6;
uint32 const OutdoorPvPHPBuffZones[OutdoorPvPHPBuffZonesNum] = { 3483, 3563, 3562, 3713, 3714, 3836 }; // HP, citadel, ramparts, blood furnace, shattered halls, mag's lair
OutdoorPvPHP::OutdoorPvPHP(Map* map) : OutdoorPvP(map)
{
m_TypeId = OUTDOOR_PVP_HP;
m_AllianceTowersControlled = 0;
m_HordeTowersControlled = 0;
ControlZoneHandlers[HP_GO_ENTRY_TOWER_S] = std::make_unique(this);
GetControlZoneTowerSouthHandler().SetFlagArtKitAlliance(65);
GetControlZoneTowerSouthHandler().SetFlagArtKitHorde(64);
GetControlZoneTowerSouthHandler().SetFlagArtKitNeutral(66);
GetControlZoneTowerSouthHandler().SetTextCaptureAlliance(TEXT_BROKEN_HILL_TAKEN_ALLIANCE);
GetControlZoneTowerSouthHandler().SetTextCaptureHorde(TEXT_BROKEN_HILL_TAKEN_HORDE);
GetControlZoneTowerSouthHandler().SetWorldstateAlliance(HP_UI_TOWER_S_A);
GetControlZoneTowerSouthHandler().SetWorldstateHorde(HP_UI_TOWER_S_H);
GetControlZoneTowerSouthHandler().SetWorldstateNeutral(HP_UI_TOWER_S_N);
GetControlZoneTowerSouthHandler().SetKillCredit(HP_KILL_CREDIT_TOWER_S);
ControlZoneHandlers[HP_GO_ENTRY_TOWER_N] = std::make_unique(this);
GetControlZoneTowerNorthHandler().SetFlagArtKitAlliance(62);
GetControlZoneTowerNorthHandler().SetFlagArtKitHorde(61);
GetControlZoneTowerNorthHandler().SetFlagArtKitNeutral(63);
GetControlZoneTowerNorthHandler().SetTextCaptureAlliance(TEXT_OVERLOOK_TAKEN_ALLIANCE);
GetControlZoneTowerNorthHandler().SetTextCaptureHorde(TEXT_OVERLOOK_TAKEN_HORDE);
GetControlZoneTowerNorthHandler().SetWorldstateAlliance(HP_UI_TOWER_N_A);
GetControlZoneTowerNorthHandler().SetWorldstateHorde(HP_UI_TOWER_N_H);
GetControlZoneTowerNorthHandler().SetWorldstateNeutral(HP_UI_TOWER_N_N);
GetControlZoneTowerNorthHandler().SetKillCredit(HP_KILL_CREDIT_TOWER_N);
ControlZoneHandlers[HP_GO_ENTRY_TOWER_W] = std::make_unique(this);
GetControlZoneTowerWestHandler().SetFlagArtKitAlliance(67);
GetControlZoneTowerWestHandler().SetFlagArtKitHorde(68);
GetControlZoneTowerWestHandler().SetFlagArtKitNeutral(69);
GetControlZoneTowerWestHandler().SetTextCaptureAlliance(TEXT_STADIUM_TAKEN_ALLIANCE);
GetControlZoneTowerWestHandler().SetTextCaptureHorde(TEXT_STADIUM_TAKEN_HORDE);
GetControlZoneTowerWestHandler().SetWorldstateAlliance(HP_UI_TOWER_W_A);
GetControlZoneTowerWestHandler().SetWorldstateHorde(HP_UI_TOWER_W_H);
GetControlZoneTowerWestHandler().SetWorldstateNeutral(HP_UI_TOWER_W_N);
GetControlZoneTowerWestHandler().SetKillCredit(HP_KILL_CREDIT_TOWER_W);
}
bool OutdoorPvPHP::SetupOutdoorPvP()
{
m_AllianceTowersControlled = 0;
m_HordeTowersControlled = 0;
// add the zones affected by the pvp buff
for (uint32 i = 0; i < OutdoorPvPHPBuffZonesNum; ++i)
RegisterZone(OutdoorPvPHPBuffZones[i]);
return true;
}
void OutdoorPvPHP::OnGameObjectCreate(GameObject* go)
{
if (go->GetGoType() == GAMEOBJECT_TYPE_CONTROL_ZONE)
_controlZoneGUIDs.insert(go->GetGUID());
switch (go->GetEntry())
{
case 183514:
GetControlZoneTowerSouthHandler().SetFlagGuid(go->GetGUID());
break;
case 182525:
GetControlZoneTowerNorthHandler().SetFlagGuid(go->GetGUID());
break;
case 183515:
GetControlZoneTowerWestHandler().SetFlagGuid(go->GetGUID());
break;
default:
break;
}
OutdoorPvP::OnGameObjectCreate(go);
}
void OutdoorPvPHP::HandlePlayerEnterZone(Player* player, uint32 zone)
{
// add buffs
if (player->GetTeam() == ALLIANCE)
{
if (m_AllianceTowersControlled >=3)
player->CastSpell(player, AllianceBuff, true);
}
else if (player->GetTeam() == HORDE)
{
if (m_HordeTowersControlled >=3)
player->CastSpell(player, HordeBuff, true);
}
OutdoorPvP::HandlePlayerEnterZone(player, zone);
}
void OutdoorPvPHP::HandlePlayerLeaveZone(Player* player, uint32 zone)
{
// remove buffs
if (player->GetTeam() == ALLIANCE)
{
player->RemoveAurasDueToSpell(AllianceBuff);
}
else if (player->GetTeam() == HORDE)
{
player->RemoveAurasDueToSpell(HordeBuff);
}
OutdoorPvP::HandlePlayerLeaveZone(player, zone);
}
void OutdoorPvPHP::Update(uint32 diff)
{
OutdoorPvP::Update(diff);
if (m_AllianceTowersControlled == 3)
TeamApplyBuff(TEAM_ALLIANCE, AllianceBuff, HordeBuff);
else if (m_HordeTowersControlled == 3)
TeamApplyBuff(TEAM_HORDE, HordeBuff, AllianceBuff);
else
{
TeamCastSpell(TEAM_ALLIANCE, -AllianceBuff);
TeamCastSpell(TEAM_HORDE, -HordeBuff);
}
SetWorldState(HP_UI_TOWER_COUNT_A, m_AllianceTowersControlled);
SetWorldState(HP_UI_TOWER_COUNT_H, m_HordeTowersControlled);
}
void OutdoorPvPHP::SendRemoveWorldStates(Player* player)
{
WorldPackets::WorldState::InitWorldStates initWorldStates;
initWorldStates.MapID = player->GetMapId();
initWorldStates.AreaID = player->GetZoneId();
initWorldStates.SubareaID = player->GetAreaId();
initWorldStates.Worldstates.emplace_back(HP_UI_TOWER_DISPLAY_A, 0);
initWorldStates.Worldstates.emplace_back(HP_UI_TOWER_DISPLAY_H, 0);
initWorldStates.Worldstates.emplace_back(HP_UI_TOWER_COUNT_H, 0);
initWorldStates.Worldstates.emplace_back(HP_UI_TOWER_COUNT_A, 0);
for (auto& itr : ControlZoneHandlers)
{
HPControlZoneHandler* handler = static_cast(itr.second.get());
initWorldStates.Worldstates.emplace_back(handler->GetWorldStateNeutral(), 0);
initWorldStates.Worldstates.emplace_back(handler->GetWorldStateHorde(), 0);
initWorldStates.Worldstates.emplace_back(handler->GetWorldStateAlliance(), 0);
}
player->SendDirectMessage(initWorldStates.Write());
}
void OutdoorPvPHP::HandleKillImpl(Player* player, Unit* killed)
{
if (killed->GetTypeId() != TYPEID_PLAYER)
return;
// need to check if player is inside an capture zone
bool isInsideCaptureZone = false;
for (ObjectGuid const& guid : _controlZoneGUIDs)
{
if (GameObject* gameObject = GetMap()->GetGameObject(guid))
{
if (GuidUnorderedSet const* insidePlayerGuids = gameObject->GetInsidePlayers())
{
if (insidePlayerGuids->contains(player->GetGUID()))
{
isInsideCaptureZone = true;
break;
}
}
}
}
if (isInsideCaptureZone)
{
if (player->GetTeam() == ALLIANCE && killed->ToPlayer()->GetTeam() != ALLIANCE)
player->CastSpell(player, AlliancePlayerKillReward, true);
else if (player->GetTeam() == HORDE && killed->ToPlayer()->GetTeam() != HORDE)
player->CastSpell(player, HordePlayerKillReward, true);
}
}
uint32 OutdoorPvPHP::GetAllianceTowersControlled() const
{
return m_AllianceTowersControlled;
}
void OutdoorPvPHP::SetAllianceTowersControlled(uint32 count)
{
m_AllianceTowersControlled = count;
}
uint32 OutdoorPvPHP::GetHordeTowersControlled() const
{
return m_HordeTowersControlled;
}
void OutdoorPvPHP::SetHordeTowersControlled(uint32 count)
{
m_HordeTowersControlled = count;
}
HPControlZoneHandler::HPControlZoneHandler(OutdoorPvPHP* pvp) : OutdoorPvPControlZoneHandler(pvp),
_flagGuid(ObjectGuid::Empty), _textCaptureAlliance(0), _textCaptureHorde(0),
_flagArtKitNeutral(0), _flagArtKitHorde(0), _flagArtKitAlliance(0),
_worldstateNeutral(0), _worldstateHorde(0), _worldstateAlliance(0),
_killCredit(0)
{
}
void HPControlZoneHandler::HandleProgressEventHorde(GameObject* controlZone)
{
ControlZoneHandler::HandleProgressEventHorde(controlZone);
controlZone->SetGoArtKit(1);
controlZone->SendCustomAnim(0);
if (GameObject* flag = controlZone->GetMap()->GetGameObject(_flagGuid))
flag->SetGoArtKit(_flagArtKitHorde);
controlZone->GetMap()->SetWorldStateValue(_worldstateHorde, 1, false);
controlZone->GetMap()->SetWorldStateValue(_worldstateAlliance, 0, false);
controlZone->GetMap()->SetWorldStateValue(_worldstateNeutral, 0, false);
GetOutdoorPvPHP()->SendDefenseMessage(OutdoorPvPHPBuffZones[0], _textCaptureHorde);
if (GuidUnorderedSet const* guidSet = controlZone->GetInsidePlayers())
for (ObjectGuid const& guid : *guidSet)
if (Player* player = ObjectAccessor::GetPlayer(*controlZone, guid))
if (player->GetTeam() == HORDE)
player->KilledMonsterCredit(_killCredit);
}
void HPControlZoneHandler::HandleProgressEventAlliance(GameObject* controlZone)
{
ControlZoneHandler::HandleProgressEventAlliance(controlZone);
controlZone->SetGoArtKit(2);
controlZone->SendCustomAnim(1);
if (GameObject* flag = controlZone->GetMap()->GetGameObject(_flagGuid))
flag->SetGoArtKit(_flagArtKitAlliance);
controlZone->GetMap()->SetWorldStateValue(_worldstateHorde, 0, false);
controlZone->GetMap()->SetWorldStateValue(_worldstateAlliance, 1, false);
controlZone->GetMap()->SetWorldStateValue(_worldstateNeutral, 0, false);
GetOutdoorPvPHP()->SendDefenseMessage(OutdoorPvPHPBuffZones[0], _textCaptureAlliance);
if (GuidUnorderedSet const* guidSet = controlZone->GetInsidePlayers())
for (ObjectGuid const& guid : *guidSet)
if (Player* player = ObjectAccessor::GetPlayer(*controlZone, guid))
if (player->GetTeam() == ALLIANCE)
player->KilledMonsterCredit(_killCredit);
}
void HPControlZoneHandler::HandleNeutralEventHorde(GameObject* controlZone)
{
ControlZoneHandler::HandleNeutralEventHorde(controlZone);
GetOutdoorPvPHP()->SetHordeTowersControlled(GetOutdoorPvPHP()->GetHordeTowersControlled() - 1);
}
void HPControlZoneHandler::HandleNeutralEventAlliance(GameObject* controlZone)
{
ControlZoneHandler::HandleNeutralEventAlliance(controlZone);
GetOutdoorPvPHP()->SetAllianceTowersControlled(GetOutdoorPvPHP()->GetAllianceTowersControlled() - 1);
}
void HPControlZoneHandler::HandleNeutralEvent(GameObject* controlZone)
{
ControlZoneHandler::HandleNeutralEvent(controlZone);
controlZone->SetGoArtKit(21);
controlZone->SendCustomAnim(2);
if (GameObject* flag = controlZone->GetMap()->GetGameObject(_flagGuid))
flag->SetGoArtKit(_flagArtKitNeutral);
controlZone->GetMap()->SetWorldStateValue(_worldstateHorde, 0, false);
controlZone->GetMap()->SetWorldStateValue(_worldstateAlliance, 0, false);
controlZone->GetMap()->SetWorldStateValue(_worldstateNeutral, 1, false);
}
OutdoorPvPHP* HPControlZoneHandler::GetOutdoorPvPHP() const
{
return static_cast(OutdoorPvPControlZoneHandler::GetOutdoorPvP());
}
class OutdoorPvP_hellfire_peninsula : public OutdoorPvPScript
{
public:
OutdoorPvP_hellfire_peninsula() : OutdoorPvPScript("outdoorpvp_hp") { }
OutdoorPvP* GetOutdoorPvP(Map* map) const override
{
return new OutdoorPvPHP(map);
}
};
void AddSC_outdoorpvp_hp()
{
new OutdoorPvP_hellfire_peninsula();
}