/* * Copyright (C) 2016+ AzerothCore , released under GNU GPL v2 license, you may redistribute it and/or modify it under version 2 of the License, or (at your option), any later version. * Copyright (C) 2008-2016 TrinityCore * Copyright (C) 2005-2009 MaNGOS */ #include "Language.h" #include "MapManager.h" #include "ObjectMgr.h" #include "OutdoorPvP.h" #include "OutdoorPvPHP.h" #include "OutdoorPvPMgr.h" #include "Player.h" #include "ScriptMgr.h" #include "World.h" #include "WorldPacket.h" const uint32 HP_LANG_LOSE_A[HP_TOWER_NUM] = {LANG_OPVP_HP_LOSE_BROKENHILL_A, LANG_OPVP_HP_LOSE_OVERLOOK_A, LANG_OPVP_HP_LOSE_STADIUM_A}; const uint32 HP_LANG_LOSE_H[HP_TOWER_NUM] = {LANG_OPVP_HP_LOSE_BROKENHILL_H, LANG_OPVP_HP_LOSE_OVERLOOK_H, LANG_OPVP_HP_LOSE_STADIUM_H}; const uint32 HP_LANG_CAPTURE_A[HP_TOWER_NUM] = {LANG_OPVP_HP_CAPTURE_BROKENHILL_A, LANG_OPVP_HP_CAPTURE_OVERLOOK_A, LANG_OPVP_HP_CAPTURE_STADIUM_A}; const uint32 HP_LANG_CAPTURE_H[HP_TOWER_NUM] = {LANG_OPVP_HP_CAPTURE_BROKENHILL_H, LANG_OPVP_HP_CAPTURE_OVERLOOK_H, LANG_OPVP_HP_CAPTURE_STADIUM_H}; OPvPCapturePointHP::OPvPCapturePointHP(OutdoorPvP* pvp, OutdoorPvPHPTowerType type) : OPvPCapturePoint(pvp), m_TowerType(type) { SetCapturePointData(HPCapturePoints[type].entry, HPCapturePoints[type].map, HPCapturePoints[type].x, HPCapturePoints[type].y, HPCapturePoints[type].z, HPCapturePoints[type].o, HPCapturePoints[type].rot0, HPCapturePoints[type].rot1, HPCapturePoints[type].rot2, HPCapturePoints[type].rot3); AddObject(type, HPTowerFlags[type].entry, HPTowerFlags[type].map, HPTowerFlags[type].x, HPTowerFlags[type].y, HPTowerFlags[type].z, HPTowerFlags[type].o, HPTowerFlags[type].rot0, HPTowerFlags[type].rot1, HPTowerFlags[type].rot2, HPTowerFlags[type].rot3); } OutdoorPvPHP::OutdoorPvPHP() { m_TypeId = OUTDOOR_PVP_HP; m_AllianceTowersControlled = 0; m_HordeTowersControlled = 0; } bool OutdoorPvPHP::SetupOutdoorPvP() { m_AllianceTowersControlled = 0; m_HordeTowersControlled = 0; // add the zones affected by the pvp buff for (int i = 0; i < OutdoorPvPHPBuffZonesNum; ++i) RegisterZone(OutdoorPvPHPBuffZones[i]); SetMapFromZone(OutdoorPvPHPBuffZones[0]); AddCapturePoint(new OPvPCapturePointHP(this, HP_TOWER_BROKEN_HILL)); AddCapturePoint(new OPvPCapturePointHP(this, HP_TOWER_OVERLOOK)); AddCapturePoint(new OPvPCapturePointHP(this, HP_TOWER_STADIUM)); return true; } void OutdoorPvPHP::HandlePlayerEnterZone(Player* player, uint32 zone) { // add buffs if (player->GetTeamId() == TEAM_ALLIANCE) { if (m_AllianceTowersControlled >= 3) player->CastSpell(player, AllianceBuff, true); } else { if (m_HordeTowersControlled >= 3) player->CastSpell(player, HordeBuff, true); } OutdoorPvP::HandlePlayerEnterZone(player, zone); } void OutdoorPvPHP::HandlePlayerLeaveZone(Player* player, uint32 zone) { // remove buffs if (player->GetTeamId() == TEAM_ALLIANCE) { player->RemoveAurasDueToSpell(AllianceBuff); } else { player->RemoveAurasDueToSpell(HordeBuff); } OutdoorPvP::HandlePlayerLeaveZone(player, zone); } bool OutdoorPvPHP::Update(uint32 diff) { bool changed = OutdoorPvP::Update(diff); if (changed) { 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); } SendUpdateWorldState(HP_UI_TOWER_COUNT_A, m_AllianceTowersControlled); SendUpdateWorldState(HP_UI_TOWER_COUNT_H, m_HordeTowersControlled); } return changed; } void OutdoorPvPHP::SendRemoveWorldStates(Player* player) { player->SendUpdateWorldState(HP_UI_TOWER_DISPLAY_A, 0); player->SendUpdateWorldState(HP_UI_TOWER_DISPLAY_H, 0); player->SendUpdateWorldState(HP_UI_TOWER_COUNT_H, 0); player->SendUpdateWorldState(HP_UI_TOWER_COUNT_A, 0); player->SendUpdateWorldState(HP_UI_TOWER_SLIDER_N, 0); player->SendUpdateWorldState(HP_UI_TOWER_SLIDER_POS, 0); player->SendUpdateWorldState(HP_UI_TOWER_SLIDER_DISPLAY, 0); for (int i = 0; i < HP_TOWER_NUM; ++i) { player->SendUpdateWorldState(HP_MAP_N[i], 0); player->SendUpdateWorldState(HP_MAP_A[i], 0); player->SendUpdateWorldState(HP_MAP_H[i], 0); } } void OutdoorPvPHP::FillInitialWorldStates(WorldPacket& data) { data << uint32(HP_UI_TOWER_DISPLAY_A) << uint32(1); data << uint32(HP_UI_TOWER_DISPLAY_H) << uint32(1); data << uint32(HP_UI_TOWER_COUNT_A) << uint32(m_AllianceTowersControlled); data << uint32(HP_UI_TOWER_COUNT_H) << uint32(m_HordeTowersControlled); data << uint32(HP_UI_TOWER_SLIDER_DISPLAY) << uint32(0); data << uint32(HP_UI_TOWER_SLIDER_POS) << uint32(50); data << uint32(HP_UI_TOWER_SLIDER_N) << uint32(100); for (OPvPCapturePointMap::iterator itr = m_capturePoints.begin(); itr != m_capturePoints.end(); ++itr) { itr->second->FillInitialWorldStates(data); } } void OPvPCapturePointHP::ChangeState() { uint32 field = 0; switch (m_OldState) { case OBJECTIVESTATE_NEUTRAL: field = HP_MAP_N[m_TowerType]; break; case OBJECTIVESTATE_ALLIANCE: field = HP_MAP_A[m_TowerType]; if (uint32 alliance_towers = ((OutdoorPvPHP*)m_PvP)->GetAllianceTowersControlled()) ((OutdoorPvPHP*)m_PvP)->SetAllianceTowersControlled(--alliance_towers); sWorld->SendZoneText(OutdoorPvPHPBuffZones[0], sObjectMgr->GetAcoreStringForDBCLocale(HP_LANG_LOSE_A[m_TowerType])); break; case OBJECTIVESTATE_HORDE: field = HP_MAP_H[m_TowerType]; if (uint32 horde_towers = ((OutdoorPvPHP*)m_PvP)->GetHordeTowersControlled()) ((OutdoorPvPHP*)m_PvP)->SetHordeTowersControlled(--horde_towers); sWorld->SendZoneText(OutdoorPvPHPBuffZones[0], sObjectMgr->GetAcoreStringForDBCLocale(HP_LANG_LOSE_H[m_TowerType])); break; case OBJECTIVESTATE_NEUTRAL_ALLIANCE_CHALLENGE: field = HP_MAP_N[m_TowerType]; break; case OBJECTIVESTATE_NEUTRAL_HORDE_CHALLENGE: field = HP_MAP_N[m_TowerType]; break; case OBJECTIVESTATE_ALLIANCE_HORDE_CHALLENGE: field = HP_MAP_A[m_TowerType]; break; case OBJECTIVESTATE_HORDE_ALLIANCE_CHALLENGE: field = HP_MAP_H[m_TowerType]; break; } // send world state update if (field) { m_PvP->SendUpdateWorldState(field, 0); field = 0; } uint32 artkit = 21; uint32 artkit2 = HP_TowerArtKit_N[m_TowerType]; switch (m_State) { case OBJECTIVESTATE_NEUTRAL: field = HP_MAP_N[m_TowerType]; break; case OBJECTIVESTATE_ALLIANCE: { field = HP_MAP_A[m_TowerType]; artkit = 2; artkit2 = HP_TowerArtKit_A[m_TowerType]; uint32 alliance_towers = ((OutdoorPvPHP*)m_PvP)->GetAllianceTowersControlled(); if (alliance_towers < 3) ((OutdoorPvPHP*)m_PvP)->SetAllianceTowersControlled(++alliance_towers); sWorld->SendZoneText(OutdoorPvPHPBuffZones[0], sObjectMgr->GetAcoreStringForDBCLocale(HP_LANG_CAPTURE_A[m_TowerType])); break; } case OBJECTIVESTATE_HORDE: { field = HP_MAP_H[m_TowerType]; artkit = 1; artkit2 = HP_TowerArtKit_H[m_TowerType]; uint32 horde_towers = ((OutdoorPvPHP*)m_PvP)->GetHordeTowersControlled(); if (horde_towers < 3) ((OutdoorPvPHP*)m_PvP)->SetHordeTowersControlled(++horde_towers); sWorld->SendZoneText(OutdoorPvPHPBuffZones[0], sObjectMgr->GetAcoreStringForDBCLocale(HP_LANG_CAPTURE_H[m_TowerType])); break; } case OBJECTIVESTATE_NEUTRAL_ALLIANCE_CHALLENGE: field = HP_MAP_N[m_TowerType]; break; case OBJECTIVESTATE_NEUTRAL_HORDE_CHALLENGE: field = HP_MAP_N[m_TowerType]; break; case OBJECTIVESTATE_ALLIANCE_HORDE_CHALLENGE: field = HP_MAP_A[m_TowerType]; artkit = 2; artkit2 = HP_TowerArtKit_A[m_TowerType]; break; case OBJECTIVESTATE_HORDE_ALLIANCE_CHALLENGE: field = HP_MAP_H[m_TowerType]; artkit = 1; artkit2 = HP_TowerArtKit_H[m_TowerType]; break; } Map* map = sMapMgr->FindMap(530, 0); auto bounds = map->GetGameObjectBySpawnIdStore().equal_range(m_capturePointSpawnId); for (auto itr = bounds.first; itr != bounds.second; ++itr) itr->second->SetGoArtKit(artkit); bounds = map->GetGameObjectBySpawnIdStore().equal_range(m_Objects[m_TowerType]); for (auto itr = bounds.first; itr != bounds.second; ++itr) itr->second->SetGoArtKit(artkit2); // send world state update if (field) m_PvP->SendUpdateWorldState(field, 1); // complete quest objective if (m_State == OBJECTIVESTATE_ALLIANCE || m_State == OBJECTIVESTATE_HORDE) SendObjectiveComplete(HP_CREDITMARKER[m_TowerType]); } void OPvPCapturePointHP::SendChangePhase() { SendUpdateWorldState(HP_UI_TOWER_SLIDER_N, m_neutralValuePct); // send these updates to only the ones in this objective uint32 phase = (uint32)ceil((m_value + m_maxValue) / (2 * m_maxValue) * 100.0f); SendUpdateWorldState(HP_UI_TOWER_SLIDER_POS, phase); // send this too, sometimes the slider disappears, dunno why :( SendUpdateWorldState(HP_UI_TOWER_SLIDER_DISPLAY, 1); } void OPvPCapturePointHP::FillInitialWorldStates(WorldPacket& data) { switch (m_State) { case OBJECTIVESTATE_ALLIANCE: case OBJECTIVESTATE_ALLIANCE_HORDE_CHALLENGE: data << uint32(HP_MAP_N[m_TowerType]) << uint32(0); data << uint32(HP_MAP_A[m_TowerType]) << uint32(1); data << uint32(HP_MAP_H[m_TowerType]) << uint32(0); break; case OBJECTIVESTATE_HORDE: case OBJECTIVESTATE_HORDE_ALLIANCE_CHALLENGE: data << uint32(HP_MAP_N[m_TowerType]) << uint32(0); data << uint32(HP_MAP_A[m_TowerType]) << uint32(0); data << uint32(HP_MAP_H[m_TowerType]) << uint32(1); break; case OBJECTIVESTATE_NEUTRAL: case OBJECTIVESTATE_NEUTRAL_ALLIANCE_CHALLENGE: case OBJECTIVESTATE_NEUTRAL_HORDE_CHALLENGE: default: data << uint32(HP_MAP_N[m_TowerType]) << uint32(1); data << uint32(HP_MAP_A[m_TowerType]) << uint32(0); data << uint32(HP_MAP_H[m_TowerType]) << uint32(0); break; } } bool OPvPCapturePointHP::HandlePlayerEnter(Player* player) { if (OPvPCapturePoint::HandlePlayerEnter(player)) { player->SendUpdateWorldState(HP_UI_TOWER_SLIDER_DISPLAY, 1); uint32 phase = (uint32)ceil((m_value + m_maxValue) / (2 * m_maxValue) * 100.0f); player->SendUpdateWorldState(HP_UI_TOWER_SLIDER_POS, phase); player->SendUpdateWorldState(HP_UI_TOWER_SLIDER_N, m_neutralValuePct); return true; } return false; } void OPvPCapturePointHP::HandlePlayerLeave(Player* player) { player->SendUpdateWorldState(HP_UI_TOWER_SLIDER_DISPLAY, 0); OPvPCapturePoint::HandlePlayerLeave(player); } void OutdoorPvPHP::HandleKillImpl(Player* player, Unit* killed) { if (killed->GetTypeId() != TYPEID_PLAYER) return; if (player->GetTeamId() == TEAM_ALLIANCE && killed->ToPlayer()->GetTeamId() != TEAM_ALLIANCE) player->CastSpell(player, AlliancePlayerKillReward, true); else if (player->GetTeamId() == TEAM_HORDE && killed->ToPlayer()->GetTeamId() != TEAM_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; } class OutdoorPvP_hellfire_peninsula : public OutdoorPvPScript { public: OutdoorPvP_hellfire_peninsula() : OutdoorPvPScript("outdoorpvp_hp") { } OutdoorPvP* GetOutdoorPvP() const override { return new OutdoorPvPHP(); } }; void AddSC_outdoorpvp_hp() { new OutdoorPvP_hellfire_peninsula(); }