diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/game/OutdoorPvPWG.cpp | 1829 | ||||
-rw-r--r-- | src/game/OutdoorPvPWG.h | 325 |
2 files changed, 0 insertions, 2154 deletions
diff --git a/src/game/OutdoorPvPWG.cpp b/src/game/OutdoorPvPWG.cpp deleted file mode 100644 index a5047e3a5ff..00000000000 --- a/src/game/OutdoorPvPWG.cpp +++ /dev/null @@ -1,1829 +0,0 @@ -/* - * 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 "OutdoorPvPWG.h" -#include "SpellAuras.h" -#include "Vehicle.h" -#include "ObjectMgr.h" -#include "World.h" -#include "Chat.h" -#include "MapManager.h" - -void _LoadTeamPair(TeamPairMap &pairMap, const TeamPair *pair) -{ - while((*pair)[0]) - { - pairMap[(*pair)[0]] = (*pair)[1]; - pairMap[(*pair)[1]] = (*pair)[0]; - ++pair; - } -} - -void _RespawnCreatureIfNeeded(Creature *cr, uint32 entry) -{ - if (cr) - { - cr->SetOriginalEntry(entry); - if (entry != cr->GetEntry() || !cr->isAlive()) - cr->Respawn(true); - cr->SetVisibility(VISIBILITY_ON); - } -} - -OutdoorPvPWG::OutdoorPvPWG() -{ - m_TypeId = OUTDOOR_PVP_WG; - - m_LastResurrectTime = 0; // Temporal copy of BG system till 3.2 -} - -bool OutdoorPvPWG::SetupOutdoorPvP() -{ - if (!sWorld.getConfig(CONFIG_OUTDOORPVP_WINTERGRASP_ENABLED)) - { - sWorld.setState(WORLDSTATE_WINTERGRASP_CONTROLING_FACTION, TEAM_NEUTRAL); - return false; - } - - m_defender = TeamId(rand()%2); - sWorld.setState(WORLDSTATE_WINTERGRASP_CONTROLING_FACTION, getDefenderTeam()); - m_changeDefender = false; - m_workshopCount[TEAM_ALLIANCE] = 0; - m_workshopCount[TEAM_HORDE] = 0; - m_tenacityStack = 0; - m_gate = NULL; - - std::list<uint32> engGuids; - std::list<uint32> spiritGuids; - - // Store Eng, spirit guide guids and questgiver for later use - QueryResult *result = WorldDatabase.PQuery("SELECT guid, id FROM creature WHERE creature.map=571" - " AND creature.id IN (%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u);", - CRE_ENG_A, CRE_ENG_H, CRE_SPI_A, CRE_SPI_H, 31101, 31051, 31102, 31052, - 31107, 31109, 31151, 31153, 31106, 31108, 31053, 31054, 31091, 31036); - if (!result) - sLog.outError("Cannot find siege workshop master or spirit guides in creature!"); - else - { - do - { - Position posHorde, posAlli; - Field *fields = result->Fetch(); - switch(fields[1].GetUInt32()) - { - case CRE_ENG_A: - case CRE_ENG_H: - engGuids.push_back(fields[0].GetUInt32()); - break; - case CRE_SPI_A: - case CRE_SPI_H: - spiritGuids.push_back(fields[0].GetUInt32()); - break; - case 31051: - posHorde.Relocate(5081.7, 2173.73, 365.878, 0.855211); - posAlli.Relocate(5296.56, 2789.87, 409.275, 0.733038); - LoadQuestGiverMap(fields[0].GetUInt32(), posHorde, posAlli); - break; - case 31101: - posHorde.Relocate(5296.56, 2789.87, 409.275, 0.733038); - posAlli.Relocate(5016.57, 3677.53, 362.982, 5.7525); - LoadQuestGiverMap(fields[0].GetUInt32(), posHorde, posAlli); - break; - case 31052: - posHorde.Relocate(5100.07, 2168.89, 365.779, 1.97222); - posAlli.Relocate(5298.43, 2738.76, 409.316, 3.97174); - LoadQuestGiverMap(fields[0].GetUInt32(), posHorde, posAlli); - break; - case 31102: - posHorde.Relocate(5298.43, 2738.76, 409.316, 3.97174); - posAlli.Relocate(5030.44, 3659.82, 363.194, 1.83336); - LoadQuestGiverMap(fields[0].GetUInt32(), posHorde, posAlli); - break; - case 31109: - posHorde.Relocate(5080.4, 2199, 359.489, 2.96706); - posAlli.Relocate(5234.97, 2883.4, 409.275, 4.29351); - LoadQuestGiverMap(fields[0].GetUInt32(), posHorde, posAlli); - break; - case 31107: - posHorde.Relocate(5234.97, 2883.4, 409.275, 4.29351); - posAlli.Relocate(5008.64, 3659.91, 361.07, 4.0796); - LoadQuestGiverMap(fields[0].GetUInt32(), posHorde, posAlli); - break; - case 31153: - posHorde.Relocate(5088.49, 2188.18, 365.647, 5.25344); - posAlli.Relocate(5366.13, 2833.4, 409.323, 3.14159); - LoadQuestGiverMap(fields[0].GetUInt32(), posHorde, posAlli); - break; - case 31151: - posHorde.Relocate(5366.13, 2833.4, 409.323, 3.14159); - posAlli.Relocate(5032.33, 3680.7, 363.018, 3.43167); - LoadQuestGiverMap(fields[0].GetUInt32(), posHorde, posAlli); - break; - case 31108: - posHorde.Relocate(5095.67, 2193.28, 365.924, 4.93928); - posAlli.Relocate(5295.56, 2926.67, 409.275, 0.872665); - LoadQuestGiverMap(fields[0].GetUInt32(), posHorde, posAlli); - break; - case 31106: - posHorde.Relocate(5295.56, 2926.67, 409.275, 0.872665); - posAlli.Relocate(5032.66, 3674.28, 363.053, 2.9447); - LoadQuestGiverMap(fields[0].GetUInt32(), posHorde, posAlli); - break; - case 31054: - posHorde.Relocate(5088.61, 2167.66, 365.689, 0.680678); - posAlli.Relocate(5371.4, 3026.51, 409.206, 3.25003); - LoadQuestGiverMap(fields[0].GetUInt32(), posHorde, posAlli); - break; - case 31053: - posHorde.Relocate(5371.4, 3026.51, 409.206, 3.25003); - posAlli.Relocate(5032.44, 3668.66, 363.11, 2.87402); - LoadQuestGiverMap(fields[0].GetUInt32(), posHorde, posAlli); - break; - case 31036: - posHorde.Relocate(5078.28, 2183.7, 365.029, 1.46608); - posAlli.Relocate(5359.13, 2837.99, 409.364, 4.69893); - LoadQuestGiverMap(fields[0].GetUInt32(), posHorde, posAlli); - break; - case 31091: - posHorde.Relocate(5359.13, 2837.99, 409.364, 4.69893); - posAlli.Relocate(5022.43, 3659.91, 361.61, 1.35426); - LoadQuestGiverMap(fields[0].GetUInt32(), posHorde, posAlli); - break; - default: - break; - } - }while(result->NextRow()); - delete result; - } - - // Select POI - AreaPOIList areaPOIs; - float minX = 9999, minY = 9999, maxX = -9999, maxY = -9999; - for (uint32 i = 0; i < sAreaPOIStore.GetNumRows(); ++i) - { - const AreaPOIEntry * poiInfo = sAreaPOIStore.LookupEntry(i); - if (poiInfo && poiInfo->zoneId == ZONE_WINTERGRASP) - { - areaPOIs.push_back(poiInfo); - if (minX > poiInfo->x) minX = poiInfo->x; - if (minY > poiInfo->y) minY = poiInfo->y; - if (maxX < poiInfo->x) maxX = poiInfo->x; - if (maxY < poiInfo->y) maxY = poiInfo->y; - } - } - minX -= 20; minY -= 20; maxX += 20; maxY += 20; - - // Coords: 4290.330078, 1790.359985 - 5558.379883, 4048.889893 - result = WorldDatabase.PQuery("SELECT guid FROM gameobject,gameobject_template" - " WHERE gameobject.map=571" - " AND gameobject.position_x>%f AND gameobject.position_y>%f" - " AND gameobject.position_x<%f AND gameobject.position_y<%f" - " AND gameobject_template.type=33" - " AND gameobject.id=gameobject_template.entry", - minX, minY, maxX, maxY); - if (!result) - return false; - - do - { - Field *fields = result->Fetch(); - - uint32 guid = fields[0].GetUInt32(); - GameObjectData const * goData = objmgr.GetGOData(guid); - if (!goData) // this should not happen - continue; - - float x = goData->posX, y = goData->posY; - float minDist = 100; - AreaPOIList::iterator poi = areaPOIs.end(); - for (AreaPOIList::iterator itr = areaPOIs.begin(); itr != areaPOIs.end(); ++itr) - { - if (!(*itr)->icon[1]) // note: may for other use - continue; - - float dist = (abs((*itr)->x - x) + abs((*itr)->y - y)); - if (minDist > dist) - { - minDist = dist; - poi = itr; - } - } - - if (poi == areaPOIs.end()) - continue; - - // add building to the list - TeamId teamId = x > POS_X_CENTER ? getDefenderTeam() : getAttackerTeam(); - m_buildingStates[guid] = new BuildingState((*poi)->worldState, teamId, getDefenderTeam() != TEAM_ALLIANCE); - if ((*poi)->id == 2246) - m_gate = m_buildingStates[guid]; - areaPOIs.erase(poi); - - // add capture point - uint32 capturePointEntry = 0; - - switch(goData->id) - { - case 192028: // NW - case 192030: // W - case 192032: // SW - capturePointEntry = 190475; - break; - case 192029: // NE - case 192031: // E - case 192033: // SE - capturePointEntry = 190487; - break; - } - - if (capturePointEntry) - { - uint32 engGuid = 0; - uint32 spiritGuid = 0; - // Find closest Eng to Workshop - float minDist = 100; - for (std::list<uint32>::iterator itr = engGuids.begin(); itr != engGuids.end(); ++itr) - { - const CreatureData *creData = objmgr.GetCreatureData(*itr); - if (!creData) - continue; - - float dist = (abs(creData->posX - x) + abs(creData->posY - y)); - if (minDist > dist) - { - minDist = dist; - engGuid = *itr; - } - } - - if (!engGuid) - { - sLog.outError("Cannot find nearby siege workshop master!"); - continue; - } - else - engGuids.remove(engGuid); - // Find closest Spirit Guide to Workshop - minDist = 255; - for (std::list<uint32>::iterator itr = spiritGuids.begin(); itr != spiritGuids.end(); ++itr) - { - const CreatureData *creData = objmgr.GetCreatureData(*itr); - if (!creData) - continue; - - float dist = (abs(creData->posX - x) + abs(creData->posY - y)); - if (minDist > dist) - { - minDist = dist; - spiritGuid = *itr; - } - } - - // Inside fortress won't be capturable - OPvPCapturePointWG *workshop = new OPvPCapturePointWG(this, m_buildingStates[guid]); - if (goData->posX < POS_X_CENTER && !workshop->SetCapturePointData(capturePointEntry, goData->mapid, goData->posX + 40 * cos(goData->orientation + M_PI / 2), goData->posY + 40 * sin(goData->orientation + M_PI / 2), goData->posZ)) - { - delete workshop; - sLog.outError("Cannot add capture point!"); - continue; - } - - const CreatureData *creData = objmgr.GetCreatureData(engGuid); - if (!creData) - continue; - - workshop->m_engEntry = const_cast<uint32*>(&creData->id); - const_cast<CreatureData*>(creData)->displayid = 0; - workshop->m_engGuid = engGuid; - - // Back spirit is linked to one of the inside workshops, 1 workshop wont have spirit - if (spiritGuid) - { - spiritGuids.remove(spiritGuid); - - const CreatureData *spiritData = objmgr.GetCreatureData(spiritGuid); - if (!spiritData) - continue; - - workshop->m_spiEntry = const_cast<uint32*>(&spiritData->id); - const_cast<CreatureData*>(spiritData)->displayid = 0; - workshop->m_spiGuid = spiritGuid; - } - else - workshop->m_spiGuid = 0; - workshop->m_workshopGuid = guid; - AddCapturePoint(workshop); - m_buildingStates[guid]->type = BUILDING_WORKSHOP; - workshop->SetTeamByBuildingState(); - } - }while(result->NextRow()); - delete result; - - engGuids.clear(); - spiritGuids.clear(); - - if (!m_gate) - { - sLog.outError("Cannot find wintergrasp fortress gate!"); - return false; - } - - // Load Graveyard - GraveYardMap::const_iterator graveLow = objmgr.mGraveYardMap.lower_bound(ZONE_WINTERGRASP); - GraveYardMap::const_iterator graveUp = objmgr.mGraveYardMap.upper_bound(ZONE_WINTERGRASP); - for (AreaPOIList::iterator itr = areaPOIs.begin(); itr != areaPOIs.end();) - { - if ((*itr)->icon[1] == 8) - { - // find or create grave yard - const WorldSafeLocsEntry *loc = objmgr.GetClosestGraveYard((*itr)->x, (*itr)->y, (*itr)->z, (*itr)->mapId, 0); - if (!loc) - { - ++itr; - continue; - } - - GraveYardMap::const_iterator graveItr; - for (graveItr = graveLow; graveItr != graveUp; ++graveItr) - if (graveItr->second.safeLocId == loc->ID) - break; - if (graveItr == graveUp) - { - GraveYardData graveData; - graveData.safeLocId = loc->ID; - graveData.team = 0; - graveItr = objmgr.mGraveYardMap.insert(std::make_pair(ZONE_WINTERGRASP, graveData)); - } - - for (BuildingStateMap::iterator stateItr = m_buildingStates.begin(); stateItr != m_buildingStates.end(); ++stateItr) - { - if (stateItr->second->worldState == (*itr)->worldState) - { - stateItr->second->graveTeam = const_cast<uint32*>(&graveItr->second.team); - break; - } - } - areaPOIs.erase(itr++); - } - else - ++itr; - } - - //Titan Relic - objmgr.AddGOData(192829, 571, 5440, 2840.8, 420.43 + 10, 0); - - _LoadTeamPair(m_goDisplayPair, OutdoorPvPWGGODisplayPair); - _LoadTeamPair(m_creEntryPair, OutdoorPvPWGCreEntryPair); - - m_wartime = false; - m_timer = sWorld.getConfig(CONFIG_OUTDOORPVP_WINTERGRASP_START_TIME) * MINUTE * IN_MILISECONDS; - - m_towerDamagedCount[TEAM_ALLIANCE] = 0; - m_towerDestroyedCount[TEAM_ALLIANCE] = 0; - m_towerDamagedCount[TEAM_HORDE] = 0; - m_towerDestroyedCount[TEAM_HORDE] = 0; - - RemoveOfflinePlayerWGAuras(); - - RegisterZone(ZONE_WINTERGRASP); - return true; -} - -void OutdoorPvPWG::ProcessEvent(GameObject *obj, uint32 eventId) -{ - if (obj->GetEntry() == 192829) // Titan Relic - { - if (obj->GetGOInfo()->goober.eventId == eventId && isWarTime() && m_gate && m_gate->damageState == DAMAGE_DESTROYED) - { - m_changeDefender = true; - m_timer = 0; - } - } - else if (obj->GetGoType() == GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING) - { - BuildingStateMap::const_iterator itr = m_buildingStates.find(obj->GetDBTableGUIDLow()); - if (itr == m_buildingStates.end()) - return; - - std::string msgStr; - switch(eventId) - { // TODO - Localized msgs of GO names - case 19672: case 19675: // Flamewatch Tower - msgStr = "Flamewatch"; - break; - case 18553: case 19677: // Shadowsight Tower - msgStr = "Shadowsight"; - break; - case 19673: case 19676: // Winter's Edge Tower - msgStr = "Winter's Edge"; - break; - case 19776: case 19778: // E Workshop damaged - msgStr = "Sunken Ring"; - break; - case 19777: case 19779: // W Workshop damaged - msgStr = "Broken Temple"; - break; - case 19782: case 19786: // NW Workshop damaged - msgStr = "north-western"; - break; - case 19783: case 19787: // NE Workshop damaged - msgStr = "north-eastern"; - break; - case 19784: case 19788: // SW Workshop damaged - msgStr = "Westpark"; - break; - case 19785: case 19789: // SE Workshop damaged - msgStr = "Eastpark"; - break; - case 19657: case 19661: // NW Wintergrasp Keep Tower damaged - msgStr = "north-western"; - break; - case 19658: case 19663: // NE Wintergrasp Keep Tower damaged - msgStr = "north-eastern"; - break; - case 19659: case 19662: // SW Wintergrasp Keep Tower damaged - msgStr = "south-western"; - break; - case 19660: case 19664: // SE Wintergrasp Keep Tower damaged - msgStr = "south-eastern"; - break; - default: - msgStr = ""; - } - - BuildingState *state = itr->second; - if (eventId == obj->GetGOInfo()->building.damagedEvent) - { - state->damageState = DAMAGE_DAMAGED; - switch(state->type) - { - case BUILDING_WORKSHOP: - msgStr = fmtstring(objmgr.GetTrinityStringForDBCLocale(LANG_BG_WG_WORKSHOP_DAMAGED), msgStr.c_str(), objmgr.GetTrinityStringForDBCLocale(getDefenderTeam() == TEAM_ALLIANCE ? LANG_BG_AB_ALLY : LANG_BG_AB_HORDE)); - sWorld.SendZoneText(ZONE_WINTERGRASP, msgStr.c_str()); - break; - case BUILDING_WALL: - sWorld.SendZoneText(ZONE_WINTERGRASP, objmgr.GetTrinityStringForDBCLocale(LANG_BG_WG_FORTRESS_UNDER_ATTACK)); - break; - case BUILDING_TOWER: - ++m_towerDamagedCount[state->GetTeam()]; - msgStr = fmtstring(objmgr.GetTrinityStringForDBCLocale(LANG_BG_WG_TOWER_DAMAGED), msgStr.c_str()); - sWorld.SendZoneText(ZONE_WINTERGRASP, msgStr.c_str()); - break; - } - } - else if (eventId == obj->GetGOInfo()->building.destroyedEvent) - { - state->damageState = DAMAGE_DESTROYED; - - switch(state->type) - { - case BUILDING_WORKSHOP: - ModifyWorkshopCount(state->GetTeam(), false); - msgStr = fmtstring(objmgr.GetTrinityStringForDBCLocale(LANG_BG_WG_WORKSHOP_DESTROYED), msgStr.c_str(), objmgr.GetTrinityStringForDBCLocale(getDefenderTeam() == TEAM_ALLIANCE ? LANG_BG_AB_ALLY : LANG_BG_AB_HORDE)); - sWorld.SendZoneText(ZONE_WINTERGRASP, msgStr.c_str()); - break; - case BUILDING_WALL: - sWorld.SendZoneText(ZONE_WINTERGRASP, objmgr.GetTrinityStringForDBCLocale(LANG_BG_WG_FORTRESS_UNDER_ATTACK)); - break; - case BUILDING_TOWER: - --m_towerDamagedCount[state->GetTeam()]; - ++m_towerDestroyedCount[state->GetTeam()]; - if (state->GetTeam() == getAttackerTeam()) - { - TeamCastSpell(getAttackerTeam(), -SPELL_TOWER_CONTROL); - TeamCastSpell(getDefenderTeam(), -SPELL_TOWER_CONTROL); - uint32 attStack = 3 - m_towerDestroyedCount[getAttackerTeam()]; - - if (m_towerDestroyedCount[getAttackerTeam()]) - { - for (PlayerSet::iterator itr = m_players[getDefenderTeam()].begin(); itr != m_players[getDefenderTeam()].end(); ++itr) - if ((*itr)->getLevel() > 69) - (*itr)->SetAuraStack(SPELL_TOWER_CONTROL, (*itr), m_towerDestroyedCount[getAttackerTeam()]); - } - - if (attStack) - { - for (PlayerSet::iterator itr = m_players[getAttackerTeam()].begin(); itr != m_players[getAttackerTeam()].end(); ++itr) - if ((*itr)->getLevel() > 69) - (*itr)->SetAuraStack(SPELL_TOWER_CONTROL, (*itr), attStack); - } - else - { - if (m_timer < 600000) - m_timer = 0; - else - m_timer = m_timer - 600000; // - 10 mins - } - } - msgStr = fmtstring(objmgr.GetTrinityStringForDBCLocale(LANG_BG_WG_TOWER_DESTROYED), msgStr.c_str()); - sWorld.SendZoneText(ZONE_WINTERGRASP, msgStr.c_str()); - break; - } - BroadcastStateChange(state); - } - } -} - -void OutdoorPvPWG::RemoveOfflinePlayerWGAuras() -{ - // if server crashed while in battle there could be players with rank or tenacity - CharacterDatabase.PExecute("DELETE FROM character_aura WHERE spell IN (%u, %u, %u, %u, %u)", - SPELL_RECRUIT, SPELL_CORPORAL, SPELL_LIEUTENANT, SPELL_TENACITY, SPELL_TOWER_CONTROL); -} - -void OutdoorPvPWG::ModifyWorkshopCount(TeamId team, bool add) -{ - if (team == TEAM_NEUTRAL) - return; - - if (add) - ++m_workshopCount[team]; - else if (m_workshopCount[team]) - --m_workshopCount[team]; - else - sLog.outError("OutdoorPvPWG::ModifyWorkshopCount: negative workshop count!"); - - SendUpdateWorldState(MaxVehNumWorldState[team], m_workshopCount[team] * MAX_VEHICLE_PER_WORKSHOP); -} - -uint32 OutdoorPvPWG::GetCreatureEntry(uint32 guidlow, const CreatureData *data) -{ - if (getDefenderTeam() == TEAM_ALLIANCE) - { - TeamPairMap::const_iterator itr = m_creEntryPair.find(data->id); - if (itr != m_creEntryPair.end()) - { - const_cast<CreatureData*>(data)->displayid = 0; - return itr->second; - } - } - return data->id; -} - -OutdoorPvPWGCreType OutdoorPvPWG::GetCreatureType(uint32 entry) const -{ - // VEHICLES, GUARDS and TURRETS gives kill credit - // OTHER Not in wartime - // TURRET Only during wartime - // SPECIAL like "OTHER" but no despawn conditions - // Entries like Case A: Case: B have their own despawn function - switch(entry) - { - case 27881: // Catapult - case 28094: // Demolisher - case 28312: // Alliance Siege Engine - case 32627: // Horde Siege Engine - case 28319: // Siege turret - case 32629: // Siege turret - return CREATURE_SIEGE_VEHICLE; - case 28366: // Wintergrasp Tower cannon - return CREATURE_TURRET; - case CRE_ENG_A: // Alliance Engineer - case CRE_ENG_H: // Horde Engineer - return CREATURE_ENGINEER; - case 30739:case 30740: // Champions - case 32307:case 32308: // Guards - return CREATURE_GUARD; - case CRE_SPI_A: // Dwarven Spirit Guide - case CRE_SPI_H: // Taunka Spirit Guide - return CREATURE_SPIRIT_GUIDE; - case 6491: // Spirit Healers - return CREATURE_SPIRIT_HEALER; - case 31101:case 31051: // Hoodoo Master & Sorceress - case 31102:case 31052: // Vieron Blazefeather & Bowyer - case 31107:case 31109: // Lieutenant & Senior Demolitionist - case 31151:case 31153: // Tactical Officer - case 31106:case 31108: // Siegesmith & Siege Master - case 31053:case 31054: // Primalist & Anchorite - case 31091:case 31036: // Commander - return CREATURE_QUESTGIVER; - case 32615:case 32626: // Warbringer && Brigadier General - case 32296:case 32294: // Quartermaster - case 30870:case 30869: // Flight Masters - return CREATURE_SPECIAL; - default: - return CREATURE_OTHER; // Revenants, Elementals, etc - } -} - -void OutdoorPvPWG::OnCreatureCreate(Creature *creature, bool add) -{ - uint32 entry = creature->GetEntry(); - switch(GetCreatureType(entry)) - { - case CREATURE_SIEGE_VEHICLE: - { - if (!creature->isSummon()) - return; - - TeamId team; - if (add) - { - if (creature->getFaction() == WintergraspFaction[TEAM_ALLIANCE]) - team = TEAM_ALLIANCE; - else if (creature->getFaction() == WintergraspFaction[TEAM_HORDE]) - team = TEAM_HORDE; - else - return; - - if (uint32 engLowguid = GUID_LOPART(creature->ToTempSummon()->GetSummonerGUID())) - { - if (OPvPCapturePointWG *workshop = GetWorkshopByEngGuid(engLowguid)) - { - if (CanBuildVehicle(workshop)) - { - m_vehicles[team].insert(creature); - //workshop->m_vehicles.insert(creature); - } - else - { - creature->setDeathState(DEAD); - creature->SetRespawnTime(DAY); - return; - } - } - } - - if (m_tenacityStack > 0 && team == TEAM_ALLIANCE) - creature->SetAuraStack(SPELL_TENACITY_VEHICLE, creature, m_tenacityStack); - else if (m_tenacityStack < 0 && team == TEAM_HORDE) - creature->SetAuraStack(SPELL_TENACITY_VEHICLE, creature, -m_tenacityStack); - } - else // the faction may be changed in uncharm - { - // TODO: now you have to wait until the corpse of vehicle disappear to build a new one - if (m_vehicles[TEAM_ALLIANCE].erase(creature)) - team = TEAM_ALLIANCE; - else if (m_vehicles[TEAM_HORDE].erase(creature)) - team = TEAM_HORDE; - else - return; - } - SendUpdateWorldState(VehNumWorldState[team], m_vehicles[team].size()); - break; - } - case CREATURE_QUESTGIVER: - if (add) - m_questgivers[creature->GetDBTableGUIDLow()] = creature; - else - m_questgivers.erase(creature->GetDBTableGUIDLow()); - break; - case CREATURE_ENGINEER: - for (OutdoorPvP::OPvPCapturePointMap::iterator itr = m_capturePoints.begin(); itr != m_capturePoints.end(); ++itr) - { - if (OPvPCapturePointWG *workshop = dynamic_cast<OPvPCapturePointWG*>(itr->second)) - if (workshop->m_engGuid == creature->GetDBTableGUIDLow()) - { - workshop->m_engineer = add ? creature : NULL; - break; - } - } - break; - case CREATURE_SPIRIT_GUIDE: - for (OutdoorPvP::OPvPCapturePointMap::iterator itr = m_capturePoints.begin(); itr != m_capturePoints.end(); ++itr) - { - if (OPvPCapturePointWG *workshop = dynamic_cast<OPvPCapturePointWG*>(itr->second)) - if (workshop->m_spiGuid == creature->GetDBTableGUIDLow()) - { - workshop->m_spiritguide = add ? creature : NULL; - break; - } - } - creature->CastSpell(creature, SPELL_SPIRITUAL_IMMUNITY, true); - case CREATURE_SPIRIT_HEALER: - case CREATURE_TURRET: - case CREATURE_OTHER: - if (add) - UpdateCreatureInfo(creature); - default: - if (add) - m_creatures.insert(creature); - else - m_creatures.erase(creature); - break; - } -} - -void OutdoorPvPWG::OnGameObjectCreate(GameObject *go, bool add) -{ - OutdoorPvP::OnGameObjectCreate(go, add); - - if (UpdateGameObjectInfo(go)) - { - if (add) m_gobjects.insert(go); - else m_gobjects.erase(go); - } - //do we need to store building? - else if (go->GetGoType() == GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING) - { - BuildingStateMap::const_iterator itr = m_buildingStates.find(go->GetDBTableGUIDLow()); - if (itr != m_buildingStates.end()) - { - itr->second->building = add ? go : NULL; - if (go->GetGOInfo()->displayId == 7878 || go->GetGOInfo()->displayId == 7900) - itr->second->type = BUILDING_TOWER; - if (!add || itr->second->damageState == DAMAGE_INTACT && !itr->second->health) - itr->second->health = go->GetGOValue()->building.health; - else - { - go->GetGOValue()->building.health = itr->second->health; - if (itr->second->damageState == DAMAGE_DAMAGED) - go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_DAMAGED); - else if (itr->second->damageState == DAMAGE_DESTROYED) - go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_DESTROYED); - } - } - } -} - -void OutdoorPvPWG::UpdateAllWorldObject() -{ - // update cre and go factions - for (GameObjectSet::iterator itr = m_gobjects.begin(); itr != m_gobjects.end(); ++itr) - UpdateGameObjectInfo(*itr); - for (CreatureSet::iterator itr = m_creatures.begin(); itr != m_creatures.end(); ++itr) - UpdateCreatureInfo(*itr); - for (QuestGiverMap::iterator itr = m_questgivers.begin(); itr != m_questgivers.end(); ++itr) - UpdateQuestGiverPosition((*itr).first, (*itr).second); - - // rebuild and update building states - RebuildAllBuildings(); - - // update capture points - for (OPvPCapturePointMap::iterator itr = m_capturePoints.begin(); itr != m_capturePoints.end(); ++itr) - if (OPvPCapturePointWG *workshop = dynamic_cast<OPvPCapturePointWG*>(itr->second)) - workshop->SetTeamByBuildingState(); -} - -void OutdoorPvPWG::RebuildAllBuildings() -{ - for (BuildingStateMap::const_iterator itr = m_buildingStates.begin(); itr != m_buildingStates.end(); ++itr) - { - if (itr->second->building) - { - UpdateGameObjectInfo(itr->second->building); - itr->second->building->Rebuild(); - itr->second->health = itr->second->building->GetGOValue()->building.health; - } - else - itr->second->health = 0; - - if (itr->second->damageState == DAMAGE_DESTROYED) - { - if (itr->second->type == BUILDING_WORKSHOP) - ModifyWorkshopCount(itr->second->GetTeam(), true); - } - - itr->second->damageState = DAMAGE_INTACT; - itr->second->SetTeam(getDefenderTeam() == TEAM_ALLIANCE ? OTHER_TEAM(itr->second->defaultTeam) : itr->second->defaultTeam); - } - m_towerDamagedCount[TEAM_ALLIANCE] = 0; - m_towerDestroyedCount[TEAM_ALLIANCE] = 0; - m_towerDamagedCount[TEAM_HORDE] = 0; - m_towerDestroyedCount[TEAM_HORDE] = 0; -} - -void OutdoorPvPWG::SendInitWorldStatesTo(Player *player) const -{ - WorldPacket data(SMSG_INIT_WORLD_STATES, (4+4+4+2+(m_buildingStates.size()*8))); - data << uint32(571); - data << uint32(ZONE_WINTERGRASP); - data << uint32(0); - data << uint16(4+2+4+m_buildingStates.size()); - - data << uint32(3803) << uint32(getDefenderTeam() == TEAM_ALLIANCE ? 1 : 0); - data << uint32(3802) << uint32(getDefenderTeam() != TEAM_ALLIANCE ? 1 : 0); - data << uint32(3801) << uint32(isWarTime() ? 0 : 1); - data << uint32(3710) << uint32(isWarTime() ? 1 : 0); - - for (uint32 i = 0; i < 2; ++i) - data << ClockWorldState[i] << m_clock[i]; - - data << uint32(3490) << uint32(m_vehicles[TEAM_HORDE].size()); - data << uint32(3491) << m_workshopCount[TEAM_HORDE] * MAX_VEHICLE_PER_WORKSHOP; - data << uint32(3680) << uint32(m_vehicles[TEAM_ALLIANCE].size()); - data << uint32(3681) << m_workshopCount[TEAM_ALLIANCE] * MAX_VEHICLE_PER_WORKSHOP; - - for (BuildingStateMap::const_iterator itr = m_buildingStates.begin(); itr != m_buildingStates.end(); ++itr) - itr->second->FillData(data); - - if (player) - player->GetSession()->SendPacket(&data); - else - BroadcastPacket(data); -} - -void OutdoorPvPWG::BroadcastStateChange(BuildingState *state) const -{ - if (m_sendUpdate) - for (uint32 team = 0; team < 2; ++team) - for (PlayerSet::const_iterator p_itr = m_players[team].begin(); p_itr != m_players[team].end(); ++p_itr) - state->SendUpdate(*p_itr); -} - -// Called at Start and Battle End -bool OutdoorPvPWG::UpdateCreatureInfo(Creature *creature) -{ - if (!creature) - return false; - uint32 entry = creature->GetEntry(); - switch(GetCreatureType(entry)) - { - case CREATURE_TURRET: - if (isWarTime()) - { - if (!creature->isAlive()) - creature->Respawn(true); - creature->setFaction(WintergraspFaction[getDefenderTeam()]); - creature->SetVisibility(VISIBILITY_ON); - } - else - { - if (creature->IsVehicle() && creature->GetVehicleKit()) - creature->GetVehicleKit()->RemoveAllPassengers(); - creature->SetVisibility(VISIBILITY_OFF); - creature->setFaction(35); - } - return false; - case CREATURE_OTHER: - if (isWarTime()) - { - creature->SetVisibility(VISIBILITY_OFF); - creature->setFaction(35); - } - else - { - creature->RestoreFaction(); - creature->SetVisibility(VISIBILITY_ON); - } - return false; - case CREATURE_SPIRIT_GUIDE: - if (isWarTime()) - { - creature->SetVisibility(VISIBILITY_ON); - //creature->setDeathState(ALIVE); - } - else - { - creature->SetVisibility(VISIBILITY_OFF); - //creature->setDeathState(DEAD); - } - return false; - case CREATURE_SPIRIT_HEALER: - creature->SetVisibility(isWarTime() ? VISIBILITY_OFF : VISIBILITY_ON); - return false; - case CREATURE_ENGINEER: - return false; - case CREATURE_SIEGE_VEHICLE: - //creature->DisappearAndDie(); - return false; - case CREATURE_GUARD: - case CREATURE_SPECIAL: - { - TeamPairMap::const_iterator itr = m_creEntryPair.find(creature->GetCreatureData()->id); - if (itr != m_creEntryPair.end()) - { - entry = getDefenderTeam() == TEAM_ALLIANCE ? itr->second : itr->first; - _RespawnCreatureIfNeeded(creature, entry); - } - return false; - } - default: - return false; - } -} - -bool OutdoorPvPWG::UpdateQuestGiverPosition(uint32 guid, Creature *creature) -{ - assert(guid); - Position pos = m_qgPosMap[std::pair<uint32, bool>(guid, getDefenderTeam() == TEAM_HORDE)]; - - if (creature && creature->IsInWorld()) - { - // if not questgiver or position is the same, do nothing - if (creature->GetPositionX() == pos.GetPositionX() && - creature->GetPositionY() == pos.GetPositionY() && - creature->GetPositionZ() == pos.GetPositionZ()) - return false; - - if (creature->isAlive() && creature->isInCombat()) - { - creature->CombatStop(true); - creature->getHostileRefManager().deleteReferences(); - } - creature->SetHomePosition(pos); - creature->DestroyForNearbyPlayers(); - if (!creature->GetMap()->IsLoaded(pos.GetPositionX(), pos.GetPositionY())) - creature->GetMap()->LoadGrid(pos.GetPositionX(), pos.GetPositionY()); - creature->GetMap()->CreatureRelocation(creature, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation()); - if (!creature->isAlive()) - creature->Respawn(true); - } - else - objmgr.MoveCreData(guid, 571, pos); - - return true; -} - -// Return false = Need to rebuild at battle End/Start -// true = no need to rebuild (ie: Banners or teleporters) -bool OutdoorPvPWG::UpdateGameObjectInfo(GameObject *go) const -{ - uint32 attFaction = 35; - uint32 defFaction = 35; - - if (isWarTime()) - { - attFaction = WintergraspFaction[getAttackerTeam()]; - defFaction = WintergraspFaction[getDefenderTeam()]; - } - - switch(go->GetGOInfo()->displayId) - { - case 8244: // Defender's Portal - Vehicle Teleporter - go->SetUInt32Value(GAMEOBJECT_FACTION, WintergraspFaction[getDefenderTeam()]); - return true; - case 7967: // Titan relic - go->SetUInt32Value(GAMEOBJECT_FACTION, WintergraspFaction[getAttackerTeam()]); - return true; - - case 8165: // Wintergrasp Keep Door - case 7877: // Wintergrasp Fortress Wall - case 7878: // Wintergrasp Keep Tower - case 7906: // Wintergrasp Fortress Gate - case 7909: // Wintergrasp Wall - go->SetUInt32Value(GAMEOBJECT_FACTION, defFaction); - return false; - case 7900: // Flamewatch Tower - Shadowsight Tower - Winter's Edge Tower - go->SetUInt32Value(GAMEOBJECT_FACTION, attFaction); - return false; - case 8208: // Goblin Workshop - OPvPCapturePointWG *workshop = GetWorkshopByGOGuid(go->GetGUID()); - if (workshop) - go->SetUInt32Value(GAMEOBJECT_FACTION, WintergraspFaction[workshop->m_buildingState->GetTeam()]); - return false; - } - - // Note: this is only for test, still need db support - TeamPairMap::const_iterator itr = m_goDisplayPair.find(go->GetGOInfo()->displayId); - if (itr != m_goDisplayPair.end()) - { - go->SetUInt32Value(GAMEOBJECT_DISPLAYID, getDefenderTeam() == TEAM_ALLIANCE ? - itr->second : itr->first); - return true; - } - return false; -} - -void OutdoorPvPWG::HandlePlayerEnterZone(Player * plr, uint32 zone) -{ - if (!sWorld.getConfig(CONFIG_OUTDOORPVP_WINTERGRASP_ENABLED)) - return; - - if (isWarTime()) - { - if (plr->getLevel() > 69) - { - if (!plr->HasAura(SPELL_RECRUIT) && !plr->HasAura(SPELL_CORPORAL) - && !plr->HasAura(SPELL_LIEUTENANT)) - plr->CastSpell(plr, SPELL_RECRUIT, true); - if (plr->GetTeamId() == getAttackerTeam()) - { - if (m_towerDestroyedCount[getAttackerTeam()] < 3) - plr->SetAuraStack(SPELL_TOWER_CONTROL, plr, 3 - m_towerDestroyedCount[getAttackerTeam()]); - } - else - { - if (m_towerDestroyedCount[getAttackerTeam()]) - plr->SetAuraStack(SPELL_TOWER_CONTROL, plr, m_towerDestroyedCount[getAttackerTeam()]); - } - } - } - - SendInitWorldStatesTo(plr); - OutdoorPvP::HandlePlayerEnterZone(plr, zone); - UpdateTenacityStack(); -} - -// Reapply Auras if needed -void OutdoorPvPWG::HandlePlayerResurrects(Player * plr, uint32 zone) -{ - if (!sWorld.getConfig(CONFIG_OUTDOORPVP_WINTERGRASP_ENABLED)) - return; - - if (isWarTime()) - { - if (plr->getLevel() > 69) - { - // Tenacity - if (plr->GetTeamId() == TEAM_ALLIANCE && m_tenacityStack > 0 || - plr->GetTeamId() == TEAM_HORDE && m_tenacityStack < 0) - { - if (plr->HasAura(SPELL_TENACITY)) - plr->RemoveAurasDueToSpell(SPELL_TENACITY); - - int32 newStack = m_tenacityStack < 0 ? -m_tenacityStack : m_tenacityStack; - if (newStack > 20) - newStack = 20; - plr->SetAuraStack(SPELL_TENACITY, plr, newStack); - } - - // Tower Control - if (plr->GetTeamId() == getAttackerTeam()) - { - if (m_towerDestroyedCount[getAttackerTeam()] < 3) - plr->SetAuraStack(SPELL_TOWER_CONTROL, plr, 3 - m_towerDestroyedCount[getAttackerTeam()]); - } - else - { - if (m_towerDestroyedCount[getAttackerTeam()]) - plr->SetAuraStack(SPELL_TOWER_CONTROL, plr, m_towerDestroyedCount[getAttackerTeam()]); - } - } - } - OutdoorPvP::HandlePlayerResurrects(plr, zone); -} - -void OutdoorPvPWG::HandlePlayerLeaveZone(Player * plr, uint32 zone) -{ - if (!sWorld.getConfig(CONFIG_OUTDOORPVP_WINTERGRASP_ENABLED)) - return; - - if (!plr->GetSession()->PlayerLogout()) - { - if (plr->GetVehicle()) // dismiss in change zone case - plr->GetVehicle()->Dismiss(); - plr->RemoveAurasDueToSpell(SPELL_RECRUIT); - plr->RemoveAurasDueToSpell(SPELL_CORPORAL); - plr->RemoveAurasDueToSpell(SPELL_LIEUTENANT); - plr->RemoveAurasDueToSpell(SPELL_TOWER_CONTROL); - plr->RemoveAurasDueToSpell(SPELL_SPIRITUAL_IMMUNITY); - } - plr->RemoveAurasDueToSpell(SPELL_TENACITY); - OutdoorPvP::HandlePlayerLeaveZone(plr, zone); - UpdateTenacityStack(); -} - -void OutdoorPvPWG::PromotePlayer(Player *killer) const -{ - Aura * aur; - if (aur = killer->GetAura(SPELL_RECRUIT)) - { - if (aur->GetStackAmount() >= 5) - { - killer->RemoveAura(SPELL_RECRUIT); - killer->CastSpell(killer, SPELL_CORPORAL, true); - ChatHandler(killer).PSendSysMessage(LANG_BG_WG_RANK1); - } - else - killer->CastSpell(killer, SPELL_RECRUIT, true); - } - else if (aur = killer->GetAura(SPELL_CORPORAL)) - { - if (aur->GetStackAmount() >= 5) - { - killer->RemoveAura(SPELL_CORPORAL); - killer->CastSpell(killer, SPELL_LIEUTENANT, true); - ChatHandler(killer).PSendSysMessage(LANG_BG_WG_RANK2); - } - else - killer->CastSpell(killer, SPELL_CORPORAL, true); - } -} - -void OutdoorPvPWG::HandleKill(Player *killer, Unit *victim) -{ - if (!sWorld.getConfig(CONFIG_OUTDOORPVP_WINTERGRASP_ENABLED) || !isWarTime()) - return; - - bool ok = false; - if (victim->GetTypeId() == TYPEID_PLAYER) - { - if (victim->getLevel() >= 70) - ok = true; - killer->RewardPlayerAndGroupAtEvent(CRE_PVP_KILL, victim); - } - else - { - switch(GetCreatureType(victim->GetEntry())) - { - case CREATURE_SIEGE_VEHICLE: - killer->RewardPlayerAndGroupAtEvent(CRE_PVP_KILL_V, victim); - ok = true; - break; - case CREATURE_GUARD: - killer->RewardPlayerAndGroupAtEvent(CRE_PVP_KILL, victim); - ok = true; - break; - case CREATURE_TURRET: - ok = true; - break; - } - } - - if (ok) - { - if (Group *pGroup = killer->GetGroup()) - { - for (GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next()) - if (itr->getSource()->IsAtGroupRewardDistance(killer) && itr->getSource()->getLevel() > 69) - PromotePlayer(itr->getSource()); - } - else if (killer->getLevel() > 69) - PromotePlayer(killer); - } -} - -// Recalculates Tenacity and applies it to Players / Vehicles -void OutdoorPvPWG::UpdateTenacityStack() -{ - if (!isWarTime()) - return; - - TeamId team = TEAM_NEUTRAL; - uint32 allianceNum = 0; - uint32 hordeNum = 0; - int32 newStack = 0; - - for (PlayerSet::iterator itr = m_players[TEAM_ALLIANCE].begin(); itr != m_players[TEAM_ALLIANCE].end(); ++itr) - if ((*itr)->getLevel() > 69) - ++allianceNum; - - for (PlayerSet::iterator itr = m_players[TEAM_HORDE].begin(); itr != m_players[TEAM_HORDE].end(); ++itr) - if ((*itr)->getLevel() > 69) - ++hordeNum; - - if (allianceNum && hordeNum) - { - if (allianceNum < hordeNum) - newStack = int32((float(hordeNum) / float(allianceNum) - 1)*4); // positive, should cast on alliance - else if (allianceNum > hordeNum) - newStack = int32((1 - float(allianceNum) / float(hordeNum))*4); // negative, should cast on horde - } - - if (newStack == m_tenacityStack) - return; - - if (m_tenacityStack > 0 && newStack <= 0) // old buff was on alliance - team = TEAM_ALLIANCE; - else if (m_tenacityStack < 0 && newStack >= 0) // old buff was on horde - team = TEAM_HORDE; - - m_tenacityStack = newStack; - - // Remove old buff - if (team != TEAM_NEUTRAL) - { - for (PlayerSet::const_iterator itr = m_players[team].begin(); itr != m_players[team].end(); ++itr) - if ((*itr)->getLevel() > 69) - (*itr)->RemoveAurasDueToSpell(SPELL_TENACITY); - - for (CreatureSet::const_iterator itr = m_vehicles[team].begin(); itr != m_vehicles[team].end(); ++itr) - (*itr)->RemoveAurasDueToSpell(SPELL_TENACITY_VEHICLE); - } - - // Apply new buff - if (newStack) - { - team = newStack > 0 ? TEAM_ALLIANCE : TEAM_HORDE; - if (newStack < 0) - newStack = -newStack; - if (newStack > 20) - newStack = 20; - - for (PlayerSet::const_iterator itr = m_players[team].begin(); itr != m_players[team].end(); ++itr) - if ((*itr)->getLevel() > 69) - (*itr)->SetAuraStack(SPELL_TENACITY, (*itr), newStack); - - for (CreatureSet::const_iterator itr = m_vehicles[team].begin(); itr != m_vehicles[team].end(); ++itr) - (*itr)->SetAuraStack(SPELL_TENACITY_VEHICLE, (*itr), newStack); - } -} - -void OutdoorPvPWG::UpdateClockDigit(uint32 &timer, uint32 digit, uint32 mod) -{ - uint32 value = timer%mod; - if (m_clock[digit] != value) - { - m_clock[digit] = value; - SendUpdateWorldState(ClockWorldState[digit], (timer + time(NULL))); - sWorld.SetWintergrapsTimer(timer + time(NULL), digit); - } -} - -void OutdoorPvPWG::UpdateClock() -{ - uint32 timer = m_timer / 1000; - if (!isWarTime()) - UpdateClockDigit(timer, 1, 10); - else - UpdateClockDigit(timer, 0, 10); -} - -bool OutdoorPvPWG::Update(uint32 diff) -{ - if (!sWorld.getConfig(CONFIG_OUTDOORPVP_WINTERGRASP_ENABLED)) - return false; - - if (m_timer > diff) - { - m_timer -= diff; - - if (isWarTime()) - { - OutdoorPvP::Update(diff); // update capture points - - /*********************************************************/ - /*** BATTLEGROUND RESSURECTION SYSTEM ***/ - /*********************************************************/ - - //this should be handled by spell system - m_LastResurrectTime += diff; - if (m_LastResurrectTime >= RESURRECTION_INTERVAL) - { - if (GetReviveQueueSize()) - { - for (std::map<uint64, std::vector<uint64> >::iterator itr = m_ReviveQueue.begin(); itr != m_ReviveQueue.end(); ++itr) - { - Creature *sh = NULL; - for (std::vector<uint64>::const_iterator itr2 = (itr->second).begin(); itr2 != (itr->second).end(); ++itr2) - { - Player *plr = objmgr.GetPlayer(*itr2); - if (!plr) - continue; - - if (!sh && plr->IsInWorld()) - { - sh = plr->GetMap()->GetCreature(itr->first); - // only for visual effect - if (sh) - // Spirit Heal, effect 117 - sh->CastSpell(sh, SPELL_SPIRIT_HEAL, true); - } - - // Resurrection visual - plr->CastSpell(plr, SPELL_RESURRECTION_VISUAL, true); - m_ResurrectQueue.push_back(*itr2); - } - (itr->second).clear(); - } - - m_ReviveQueue.clear(); - m_LastResurrectTime = 0; - } - else - // queue is clear and time passed, just update last resurrection time - m_LastResurrectTime = 0; - } - else if (m_LastResurrectTime > 500) // Resurrect players only half a second later, to see spirit heal effect on NPC - { - for (std::vector<uint64>::const_iterator itr = m_ResurrectQueue.begin(); itr != m_ResurrectQueue.end(); ++itr) - { - Player *plr = objmgr.GetPlayer(*itr); - if (!plr) - continue; - plr->ResurrectPlayer(1.0f); - plr->CastSpell(plr, 6962, true); - plr->CastSpell(plr, SPELL_SPIRIT_HEAL_MANA, true); - ObjectAccessor::Instance().ConvertCorpseForPlayer(*itr); - } - m_ResurrectQueue.clear(); - } - } - UpdateClock(); - } - else - { - m_sendUpdate = false; - int32 entry = LANG_BG_WG_DEFENDED; - - if (m_changeDefender) - { - m_changeDefender = false; - m_defender = getAttackerTeam(); - entry = LANG_BG_WG_CAPTURED; - } - - if (isWarTime()) - { - if (m_timer != 1) // 1 = forceStopBattle - sWorld.SendZoneText(ZONE_WINTERGRASP, fmtstring(objmgr.GetTrinityStringForDBCLocale(entry), objmgr.GetTrinityStringForDBCLocale(getDefenderTeam() == TEAM_ALLIANCE ? LANG_BG_AB_ALLY : LANG_BG_AB_HORDE))); - EndBattle(); - } - else - { - if (m_timer != 1) // 1 = forceStartBattle - sWorld.SendZoneText(ZONE_WINTERGRASP, objmgr.GetTrinityStringForDBCLocale(LANG_BG_WG_BATTLE_STARTS)); - StartBattle(); - } - - UpdateAllWorldObject(); - UpdateClock(); - - SendInitWorldStatesTo(); - m_sendUpdate = true; - } - - return false; -} - -void OutdoorPvPWG::forceStartBattle() -{ // Uptime will do all the work - m_wartime = false; - - if (m_timer != 1) - { - m_timer = 1; - sWorld.SendZoneText(ZONE_WINTERGRASP, objmgr.GetTrinityStringForDBCLocale(LANG_BG_WG_BATTLE_FORCE_START)); - } -} - -void OutdoorPvPWG::forceStopBattle() -{ // Uptime will do all the work. - - if (!isWarTime()) - m_wartime = true; - - if (m_timer != 1) - { - m_timer = 1; - sWorld.SendZoneText(ZONE_WINTERGRASP, objmgr.GetTrinityStringForDBCLocale(LANG_BG_WG_BATTLE_FORCE_STOP)); - } -} - -void OutdoorPvPWG::forceChangeTeam() -{ - m_changeDefender = true; - m_timer = 1; - sWorld.SendZoneText(ZONE_WINTERGRASP, fmtstring(objmgr.GetTrinityStringForDBCLocale(LANG_BG_WG_SWITCH_FACTION), objmgr.GetTrinityStringForDBCLocale(getAttackerTeam() == TEAM_ALLIANCE ? LANG_BG_AB_ALLY : LANG_BG_AB_HORDE))); - if (isWarTime()) - forceStartBattle(); - else - forceStopBattle(); -} - -// Can be forced by gm's while in battle so have to reset in case it was wartime -void OutdoorPvPWG::StartBattle() -{ - m_wartime = true; - m_timer = sWorld.getConfig(CONFIG_OUTDOORPVP_WINTERGRASP_BATTLE_TIME) * MINUTE * IN_MILISECONDS; - - // Remove Essence of Wintergrasp to all players - sWorld.setState(WORLDSTATE_WINTERGRASP_CONTROLING_FACTION, TEAM_NEUTRAL); - sWorld.UpdateAreaDependentAuras(); - - // destroyed all vehicles - for (uint32 team = 0; team < 2; ++team) - { - while(!m_vehicles[team].empty()) - { - Creature *veh = *m_vehicles[team].begin(); - m_vehicles[team].erase(m_vehicles[team].begin()); - veh->setDeathState(JUST_DIED); - } - } - - // Remove All Wintergrasp auras. Add Recruit rank and Tower Control - for (PlayerSet::iterator itr = m_players[getAttackerTeam()].begin(); itr != m_players[getAttackerTeam()].end(); ++itr) - { - (*itr)->RemoveAurasDueToSpell(SPELL_RECRUIT); - (*itr)->RemoveAurasDueToSpell(SPELL_CORPORAL); - (*itr)->RemoveAurasDueToSpell(SPELL_LIEUTENANT); - (*itr)->RemoveAurasDueToSpell(SPELL_TOWER_CONTROL); - (*itr)->RemoveAurasDueToSpell(SPELL_SPIRITUAL_IMMUNITY); - if ((*itr)->getLevel() > 69) - { - (*itr)->SetAuraStack(SPELL_TOWER_CONTROL, (*itr), 3); - (*itr)->CastSpell(*itr, SPELL_RECRUIT, true); - } - } - - // Remove All Wintergrasp auras. Add Recruit rank - for (PlayerSet::iterator itr = m_players[getDefenderTeam()].begin(); itr != m_players[getDefenderTeam()].end(); ++itr) - { - (*itr)->RemoveAurasDueToSpell(SPELL_RECRUIT); - (*itr)->RemoveAurasDueToSpell(SPELL_CORPORAL); - (*itr)->RemoveAurasDueToSpell(SPELL_LIEUTENANT); - (*itr)->RemoveAurasDueToSpell(SPELL_TOWER_CONTROL); - (*itr)->RemoveAurasDueToSpell(SPELL_SPIRITUAL_IMMUNITY); - if ((*itr)->getLevel() > 69) - (*itr)->CastSpell(*itr, SPELL_RECRUIT, true); - } - UpdateTenacityStack(); -} - -void OutdoorPvPWG::EndBattle() -{ - // Cast Essence of Wintergrasp to all players (CheckCast will determine who to cast) - sWorld.setState(WORLDSTATE_WINTERGRASP_CONTROLING_FACTION, getDefenderTeam()); - sWorld.UpdateAreaDependentAuras(); - - for (uint32 team = 0; team < 2; ++team) - { - // destroyed all vehicles - while(!m_vehicles[team].empty()) - { - Creature *veh = *m_vehicles[team].begin(); - m_vehicles[team].erase(m_vehicles[team].begin()); - veh->setDeathState(JUST_DIED); - } - - if (m_players[team].empty()) - continue; - - for (PlayerSet::iterator itr = m_players[team].begin(); itr != m_players[team].end(); ++itr) - { - // When WG ends the zone is cleaned including corpses, revive all players if dead - if ((*itr)->isDead()) - { - (*itr)->ResurrectPlayer(1.0f); - ObjectAccessor::Instance().ConvertCorpseForPlayer((*itr)->GetGUID()); - } - (*itr)->RemoveAurasDueToSpell(SPELL_TENACITY); - (*itr)->CombatStop(true); - (*itr)->getHostileRefManager().deleteReferences(); - } - - if (m_timer == 1) // Battle End was forced so no reward. - { - for (PlayerSet::iterator itr = m_players[team].begin(); itr != m_players[team].end(); ++itr) - { - (*itr)->RemoveAurasDueToSpell(SPELL_RECRUIT); - (*itr)->RemoveAurasDueToSpell(SPELL_CORPORAL); - (*itr)->RemoveAurasDueToSpell(SPELL_LIEUTENANT); - (*itr)->RemoveAurasDueToSpell(SPELL_TOWER_CONTROL); - (*itr)->RemoveAurasDueToSpell(SPELL_SPIRITUAL_IMMUNITY); - } - continue; - } - - // calculate rewards - uint32 intactNum = 0; - uint32 damagedNum = 0; - for (OutdoorPvP::OPvPCapturePointMap::const_iterator itr = m_capturePoints.begin(); itr != m_capturePoints.end(); ++itr) - if (OPvPCapturePointWG *workshop = dynamic_cast<OPvPCapturePointWG*>(itr->second)) - if (workshop->m_buildingState->GetTeam() == team) - if (workshop->m_buildingState->damageState == DAMAGE_DAMAGED) - ++damagedNum; - else if (workshop->m_buildingState->damageState == DAMAGE_INTACT) - ++intactNum; - - uint32 spellRewardId = team == getDefenderTeam() ? SPELL_VICTORY_REWARD : SPELL_DEFEAT_REWARD; - uint32 baseHonor = 0; - uint32 marks = 0; - uint32 playersWithRankNum = 0; - uint32 honor = 0; - - if (sWorld.getConfig(CONFIG_OUTDOORPVP_WINTERGRASP_CUSTOM_HONOR)) - { - // Calculate Level 70+ with Corporal or Lieutenant rank - for (PlayerSet::iterator itr = m_players[team].begin(); itr != m_players[team].end(); ++itr) - if ((*itr)->getLevel() > 69 && ((*itr)->HasAura(SPELL_LIEUTENANT) || (*itr)->HasAura(SPELL_CORPORAL))) - ++playersWithRankNum; - - baseHonor = team == getDefenderTeam() ? sWorld.getConfig(CONFIG_OUTDOORPVP_WINTERGRASP_WIN_BATTLE) : sWorld.getConfig(CONFIG_OUTDOORPVP_WINTERGRASP_LOSE_BATTLE); - baseHonor += (sWorld.getConfig(CONFIG_OUTDOORPVP_WINTERGRASP_DAMAGED_TOWER) * m_towerDamagedCount[OTHER_TEAM(team)]); - baseHonor += (sWorld.getConfig(CONFIG_OUTDOORPVP_WINTERGRASP_DESTROYED_TOWER) * m_towerDestroyedCount[OTHER_TEAM(team)]); - baseHonor += (sWorld.getConfig(CONFIG_OUTDOORPVP_WINTERGRASP_INTACT_BUILDING) * intactNum); - baseHonor += (sWorld.getConfig(CONFIG_OUTDOORPVP_WINTERGRASP_DAMAGED_BUILDING) * damagedNum); - if (playersWithRankNum) - baseHonor /= playersWithRankNum; - } - - for (PlayerSet::iterator itr = m_players[team].begin(); itr != m_players[team].end(); ++itr) - { - - if ((*itr)->getLevel() < 70) - continue; // No rewards for level <70 - - // give rewards - if (sWorld.getConfig(CONFIG_OUTDOORPVP_WINTERGRASP_CUSTOM_HONOR)) - { - if (team == getDefenderTeam()) - { - if ((*itr)->HasAura(SPELL_LIEUTENANT)) - { - marks = 3; - honor = baseHonor; - } - else if ((*itr)->HasAura(SPELL_CORPORAL)) - { - marks = 2; - honor = baseHonor; - } - else - { - marks = 1; - honor = 0; - } - } - else - { - if ((*itr)->HasAura(SPELL_LIEUTENANT)) - { - marks = 1; - honor = baseHonor; - } - else if ((*itr)->HasAura(SPELL_CORPORAL)) - { - marks = 1; - honor = baseHonor; - } - else - { - marks = 0; - honor = 0; - } - } - (*itr)->RewardHonor(NULL, 1, honor); - RewardMarkOfHonor(*itr, marks); - (*itr)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, spellRewardId); - } - else - { - if ((*itr)->HasAura(SPELL_LIEUTENANT) || (*itr)->HasAura(SPELL_CORPORAL)) - { - // TODO - Honor from SpellReward should be shared by team players - // TODO - Marks should be given depending on Rank but 3 are given - // each time so Won't give any to recruits - (*itr)->CastSpell(*itr, spellRewardId, true); - for (uint32 i = 0; i < intactNum; ++i) - (*itr)->CastSpell(*itr, SPELL_INTACT_BUILDING, true); - for (uint32 i = 0; i < damagedNum; ++i) - (*itr)->CastSpell(*itr, SPELL_DAMAGED_BUILDING, true); - for (uint32 i = 0; i < m_towerDamagedCount[OTHER_TEAM(team)]; ++i) - (*itr)->CastSpell(*itr, SPELL_DAMAGED_TOWER, true); - for (uint32 i = 0; i < m_towerDestroyedCount[OTHER_TEAM(team)]; ++i) - (*itr)->CastSpell(*itr, SPELL_DESTROYED_TOWER, true); - } - } - if (team == getDefenderTeam()) - { - if ((*itr)->HasAura(SPELL_LIEUTENANT) || (*itr)->HasAura(SPELL_CORPORAL)) - { - (*itr)->AreaExploredOrEventHappens(A_VICTORY_IN_WG); - (*itr)->AreaExploredOrEventHappens(H_VICTORY_IN_WG); - } - } - (*itr)->RemoveAurasDueToSpell(SPELL_RECRUIT); - (*itr)->RemoveAurasDueToSpell(SPELL_CORPORAL); - (*itr)->RemoveAurasDueToSpell(SPELL_LIEUTENANT); - (*itr)->RemoveAurasDueToSpell(SPELL_TOWER_CONTROL); - (*itr)->RemoveAurasDueToSpell(SPELL_SPIRITUAL_IMMUNITY); - } - } - - m_wartime = false; - m_timer = sWorld.getConfig(CONFIG_OUTDOORPVP_WINTERGRASP_INTERVAL) * MINUTE * IN_MILISECONDS; - //3.2.0: TeamCastSpell(getAttackerTeam(), SPELL_TELEPORT_DALARAN); - RemoveOfflinePlayerWGAuras(); -} - -bool OutdoorPvPWG::CanBuildVehicle(OPvPCapturePointWG *workshop) const -{ - TeamId team = workshop->m_buildingState->GetTeam(); - if (team == TEAM_NEUTRAL) - return false; - - return isWarTime() - && workshop->m_buildingState->damageState != DAMAGE_DESTROYED - && m_vehicles[team].size() < m_workshopCount[team] * MAX_VEHICLE_PER_WORKSHOP; -} - -uint32 OutdoorPvPWG::GetData(uint32 id) -{ - // if can build more vehicles - if (OPvPCapturePointWG *workshop = GetWorkshopByEngGuid(id)) - return CanBuildVehicle(workshop) ? 1 : 0; - - return 0; -} - -void OutdoorPvPWG::RewardMarkOfHonor(Player *plr, uint32 count) -{ - // 'Inactive' this aura prevents the player from gaining honor points and battleground tokens - if (plr->HasAura(SPELL_AURA_PLAYER_INACTIVE)) - return; - if (count == 0) - return; - - ItemPosCountVec dest; - uint32 no_space_count = 0; - uint8 msg = plr->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, WG_MARK_OF_HONOR, count, &no_space_count); - - if (msg == EQUIP_ERR_ITEM_NOT_FOUND) - { - sLog.outErrorDb("Wintergrasp reward item (Entry %u) not exist in `item_template`.", WG_MARK_OF_HONOR); - return; - } - - if (msg != EQUIP_ERR_OK) // convert to possible store amount - count -= no_space_count; - - if (count != 0 && !dest.empty()) // can add some - if (Item* item = plr->StoreNewItem(dest, WG_MARK_OF_HONOR, true, 0)) - plr->SendNewItem(item, count, true, false); -} - -void OutdoorPvPWG::LoadQuestGiverMap(uint32 guid, Position posHorde, Position posAlli) -{ - m_qgPosMap[std::pair<uint32, bool>(guid, true)] = posHorde, - m_qgPosMap[std::pair<uint32, bool>(guid, false)] = posAlli, - m_questgivers[guid] = NULL; - if (getDefenderTeam() == TEAM_ALLIANCE) - objmgr.MoveCreData(guid, 571, posAlli); -} - -OPvPCapturePointWG *OutdoorPvPWG::GetWorkshop(uint32 lowguid) const -{ - if (OPvPCapturePoint *cp = GetCapturePoint(lowguid)) - return dynamic_cast<OPvPCapturePointWG*>(cp); - return NULL; -} - -OPvPCapturePointWG *OutdoorPvPWG::GetWorkshopByEngGuid(uint32 lowguid) const -{ - for (OutdoorPvP::OPvPCapturePointMap::const_iterator itr = m_capturePoints.begin(); itr != m_capturePoints.end(); ++itr) - if (OPvPCapturePointWG *workshop = dynamic_cast<OPvPCapturePointWG*>(itr->second)) - if (workshop->m_engGuid == lowguid) - return workshop; - return NULL; -} - -OPvPCapturePointWG *OutdoorPvPWG::GetWorkshopByGOGuid(uint32 lowguid) const -{ - for (OutdoorPvP::OPvPCapturePointMap::const_iterator itr = m_capturePoints.begin(); itr != m_capturePoints.end(); ++itr) - if (OPvPCapturePointWG *workshop = dynamic_cast<OPvPCapturePointWG*>(itr->second)) - if (workshop->m_workshopGuid == lowguid) - return workshop; - return NULL; -} - -/*######################################################## - * Copy of Battleground system to make Spirit Guides Work - *#######################################################*/ -void OutdoorPvPWG::SendAreaSpiritHealerQueryOpcode(Player *pl, const uint64& guid) -{ - WorldPacket data(SMSG_AREA_SPIRIT_HEALER_TIME, 12); - uint32 time_ = 30000 - GetLastResurrectTime(); // resurrect every 30 seconds - if (time_ == uint32(-1)) - time_ = 0; - data << guid << time_; - pl->GetSession()->SendPacket(&data); -} - -void OutdoorPvPWG::AddPlayerToResurrectQueue(uint64 npc_guid, uint64 player_guid) -{ - m_ReviveQueue[npc_guid].push_back(player_guid); - - Player *plr = objmgr.GetPlayer(player_guid); - if (!plr) - return; - - plr->CastSpell(plr, SPELL_WAITING_FOR_RESURRECT, true); -} - -void OutdoorPvPWG::RemovePlayerFromResurrectQueue(uint64 player_guid) -{ - for (std::map<uint64, std::vector<uint64> >::iterator itr = m_ReviveQueue.begin(); itr != m_ReviveQueue.end(); ++itr) - { - for (std::vector<uint64>::iterator itr2 =(itr->second).begin(); itr2 != (itr->second).end(); ++itr2) - { - if (*itr2 == player_guid) - { - (itr->second).erase(itr2); - - Player *plr = objmgr.GetPlayer(player_guid); - if (!plr) - return; - - plr->RemoveAurasDueToSpell(SPELL_WAITING_FOR_RESURRECT); - - return; - } - } - } -} - -void OutdoorPvPWG::RelocateDeadPlayers(Creature *cr) -{ - if (!cr || GetCreatureType(cr->GetEntry()) != CREATURE_SPIRIT_GUIDE) - return; - - // Those who are waiting to resurrect at this node are taken to the closest own node's graveyard - std::vector<uint64> ghost_list = m_ReviveQueue[cr->GetGUID()]; - if (!ghost_list.empty()) - { - WorldSafeLocsEntry const *ClosestGrave = NULL; - for (std::vector<uint64>::const_iterator itr = ghost_list.begin(); itr != ghost_list.end(); ++itr) - { - Player* plr = objmgr.GetPlayer(*itr); - if (!plr) - continue; - - if (!ClosestGrave) - ClosestGrave = objmgr.GetClosestGraveYard(plr->GetPositionX(), plr->GetPositionY(), plr->GetPositionZ(), plr->GetMapId(), plr->GetTeam()); - - if (ClosestGrave) - plr->TeleportTo(plr->GetMapId(), ClosestGrave->x, ClosestGrave->y, ClosestGrave->z, plr->GetOrientation()); - } - } -} - -/*###### -##OPvPCapturePointWG -######*/ - -OPvPCapturePointWG::OPvPCapturePointWG(OutdoorPvPWG *opvp, BuildingState *state) -: OPvPCapturePoint(opvp), m_buildingState(state), m_wintergrasp(opvp) -, m_engineer(NULL), m_engGuid(0), m_spiritguide(NULL), m_spiGuid(0) -{ -} - -void OPvPCapturePointWG::SetTeamByBuildingState() -{ - if (m_buildingState->GetTeam() == TEAM_ALLIANCE) - { - m_value = m_maxValue; - m_State = OBJECTIVESTATE_ALLIANCE; - } - else if (m_buildingState->GetTeam() == TEAM_HORDE) - { - m_value = -m_maxValue; - m_State = OBJECTIVESTATE_HORDE; - } - else - { - m_value = 0; - m_State = OBJECTIVESTATE_NEUTRAL; - } - - if (m_team != m_buildingState->GetTeam()) - { - TeamId oldTeam = m_team; - m_team = m_buildingState->GetTeam(); - ChangeTeam(oldTeam); - } - - SendChangePhase(); -} - -void OPvPCapturePointWG::ChangeTeam(TeamId oldTeam) -{ - uint32 entry = 0; - uint32 guide_entry = 0; - - if (oldTeam != TEAM_NEUTRAL) - m_wintergrasp->ModifyWorkshopCount(oldTeam, false); - - if (m_team != TEAM_NEUTRAL) - { - entry = m_team == TEAM_ALLIANCE ? CRE_ENG_A : CRE_ENG_H; - guide_entry = m_team == TEAM_ALLIANCE ? CRE_SPI_A : CRE_SPI_H; - m_wintergrasp->ModifyWorkshopCount(m_team, true); - } - - if (m_capturePoint) - GameObject::SetGoArtKit(CapturePointArtKit[m_team], m_capturePoint, m_capturePointGUID); - - m_buildingState->SetTeam(m_team); - // TODO: this may be sent twice - m_wintergrasp->BroadcastStateChange(m_buildingState); - - if (m_buildingState->building) - m_buildingState->building->SetUInt32Value(GAMEOBJECT_FACTION, WintergraspFaction[m_team]); - - if (entry) - { - if (m_engGuid) - { - *m_engEntry = entry; - _RespawnCreatureIfNeeded(m_engineer, entry); - } - if (m_spiGuid) - { - *m_spiEntry = guide_entry; - _RespawnCreatureIfNeeded(m_spiritguide, guide_entry); - m_wintergrasp->RelocateDeadPlayers(m_spiritguide); - } - } - else if (m_engineer) - m_engineer->SetVisibility(VISIBILITY_OFF); - - sLog.outDebug("Wintergrasp workshop now belongs to %u.", (uint32)m_buildingState->GetTeam()); -} diff --git a/src/game/OutdoorPvPWG.h b/src/game/OutdoorPvPWG.h deleted file mode 100644 index 78a489aca55..00000000000 --- a/src/game/OutdoorPvPWG.h +++ /dev/null @@ -1,325 +0,0 @@ -/* - * 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 - */ - -#ifndef OUTDOOR_PVP_WG_ -#define OUTDOOR_PVP_WG_ - -#include "OutdoorPvPImpl.h" - -#define ZONE_WINTERGRASP 4197 -#define POS_X_CENTER 5100 -#define MAX_VEHICLE_PER_WORKSHOP 4 - -const uint32 WintergraspFaction[3] = {1732, 1735, 35}; -const uint32 WG_MARK_OF_HONOR = 43589; -const uint32 VehNumWorldState[2] = {3680,3490}; -const uint32 MaxVehNumWorldState[2] = {3681,3491}; -const uint32 ClockWorldState[2] = {3781,4354}; - -enum OutdoorPvPWGSpell -{ - // Wartime auras - SPELL_RECRUIT = 37795, - SPELL_CORPORAL = 33280, - SPELL_LIEUTENANT = 55629, - SPELL_TENACITY = 58549, - SPELL_TENACITY_VEHICLE = 59911, - SPELL_TOWER_CONTROL = 62064, - SPELL_SPIRITUAL_IMMUNITY = 58729, - - // Reward spells - SPELL_VICTORY_REWARD = 56902, - SPELL_DEFEAT_REWARD = 58494, - SPELL_DAMAGED_TOWER = 59135, - SPELL_DESTROYED_TOWER = 59136, - SPELL_DAMAGED_BUILDING = 59201, - SPELL_INTACT_BUILDING = 59203, - -// SPELL_TELEPORT_DALARAN = 53360, -// SPELL_VICTORY_AURA = 60044, -}; - -/* Not used / Not implemented - -const uint16 GameEventWintergraspDefender[2] = {50, 51}; - -enum OutdoorPvP_WG_Sounds -{ - OutdoorPvP_WG_SOUND_KEEP_CLAIMED = 8192, - OutdoorPvP_WG_SOUND_KEEP_CAPTURED_ALLIANCE = 8173, - OutdoorPvP_WG_SOUND_KEEP_CAPTURED_HORDE = 8213, - OutdoorPvP_WG_SOUND_KEEP_ASSAULTED_ALLIANCE = 8212, - OutdoorPvP_WG_SOUND_KEEP_ASSAULTED_HORDE = 8174, - OutdoorPvP_WG_SOUND_NEAR_VICTORY = 8456 -}; - -enum DataId -{ - DATA_ENGINEER_DIE, -}; - -enum OutdoorPvP_WG_KeepStatus -{ - OutdoorPvP_WG_KEEP_TYPE_NEUTRAL = 0, - OutdoorPvP_WG_KEEP_TYPE_CONTESTED = 1, - OutdoorPvP_WG_KEEP_STATUS_ALLY_CONTESTED = 1, - OutdoorPvP_WG_KEEP_STATUS_HORDE_CONTESTED = 2, - OutdoorPvP_WG_KEEP_TYPE_OCCUPIED = 3, - OutdoorPvP_WG_KEEP_STATUS_ALLY_OCCUPIED = 3, - OutdoorPvP_WG_KEEP_STATUS_HORDE_OCCUPIED = 4 -}; -*/ - -enum OutdoorPvPWGCreType -{ - CREATURE_OTHER, - CREATURE_SIEGE_VEHICLE, - CREATURE_TURRET, - CREATURE_ENGINEER, - CREATURE_GUARD, - CREATURE_SPECIAL, - CREATURE_SPIRIT_GUIDE, - CREATURE_SPIRIT_HEALER, - CREATURE_QUESTGIVER, -}; - -enum OutdoorPvPWGBuildingType -{ - BUILDING_WALL, - BUILDING_WORKSHOP, - BUILDING_TOWER, -}; - -enum OutdoorPvPWGDamageState -{ // Do not change order - DAMAGE_INTACT, - DAMAGE_DAMAGED, - DAMAGE_DESTROYED, -}; - -typedef uint32 TeamPair[2]; - -enum OutdoorPvPWGQuest -{ - A_VICTORY_IN_WG = 13181, - H_VICTORY_IN_WG = 13183, - CRE_PVP_KILL = 31086, //Quest Objective - Fixme: this should be handled by DB - CRE_PVP_KILL_V = 31093, //Quest Objective - Fixme: this should be handled by DB -}; - -enum OutdoorPvPWGCreEntry -{ - CRE_ENG_A = 30499, - CRE_ENG_H = 30400, - CRE_SPI_A = 31842, - CRE_SPI_H = 31841, -}; - -const TeamPair OutdoorPvPWGCreEntryPair[] = -{ - {32307, 32308}, // Guards - {30739, 30740}, // Champions - {32296, 32294}, // Quartermaster - {32615, 32626}, // Warbringer & Brigadier General - {0,0} // Do not delete Used in LoadTeamPair -}; - -const TeamPair OutdoorPvPWGGODisplayPair[] = -{ - {5651, 5652}, - {8256, 8257}, - {0,0} // Do not delete Used in LoadTeamPair -}; - -const uint32 AreaPOIIconId[3][3] = {{7,8,9},{4,5,6},{1,2,3}}; -typedef std::list<const AreaPOIEntry *> AreaPOIList; - -struct BuildingState -{ - explicit BuildingState(uint32 _worldState, TeamId _team, bool asDefault) - : worldState(_worldState), health(0) - , defaultTeam(asDefault ? _team : OTHER_TEAM(_team)), team(_team), damageState(DAMAGE_INTACT) - , building(NULL), type(BUILDING_WALL), graveTeam(NULL) - {} - uint32 worldState; - uint32 health; - TeamId defaultTeam; - OutdoorPvPWGDamageState damageState; - GameObject *building; - uint32 *graveTeam; - OutdoorPvPWGBuildingType type; - - void SendUpdate(Player *player) const - { - player->SendUpdateWorldState(worldState, AreaPOIIconId[team][damageState]); - } - - void FillData(WorldPacket &data) const - { - data << worldState << AreaPOIIconId[team][damageState]; - } - - TeamId GetTeam() const { return team; } - void SetTeam(TeamId t) - { - team = t; - if(graveTeam) - if (uint32 newTeam = TeamId2Team[t]) - *graveTeam = newTeam; - } - -private: - TeamId team; -}; - -typedef std::map<uint32, uint32> TeamPairMap; - -class OPvPCapturePointWG; - -class OutdoorPvPWG : public OutdoorPvP -{ - protected: - typedef std::map<uint32, BuildingState *> BuildingStateMap; - typedef std::set<Creature*> CreatureSet; - typedef std::set<GameObject*> GameObjectSet; - typedef std::map<std::pair<uint32, bool>, Position> QuestGiverPositionMap; - typedef std::map<uint32, Creature*> QuestGiverMap; - public: - OutdoorPvPWG(); - bool SetupOutdoorPvP(); - - uint32 GetCreatureEntry(uint32 guidlow, const CreatureData *data); - - void OnCreatureCreate(Creature *creature, bool add); - void OnGameObjectCreate(GameObject *go, bool add); - - void ProcessEvent(GameObject *obj, uint32 eventId); - - void HandlePlayerEnterZone(Player *plr, uint32 zone); - void HandlePlayerLeaveZone(Player *plr, uint32 zone); - void HandlePlayerResurrects(Player * plr, uint32 zone); - void HandleKill(Player *killer, Unit *victim); - - bool Update(uint32 diff); - - void BroadcastStateChange(BuildingState *state) const; - - uint32 GetData(uint32 id); - void SetData(uint32 id, uint32 value) {}; - - void ModifyWorkshopCount(TeamId team, bool add); - uint32 GetTimer() const { return m_timer / 1000; }; - bool isWarTime() const { return m_wartime; }; - void setTimer(uint32 timer) { if (timer >= 0) m_timer = timer; }; - uint32 GetNumPlayersA() const { return m_players[TEAM_ALLIANCE].size(); }; - uint32 GetNumPlayersH() const { return m_players[TEAM_HORDE].size(); }; - TeamId getDefenderTeam() const { return m_defender; }; - TeamId getAttackerTeam() const { return OTHER_TEAM(m_defender); }; - void forceChangeTeam(); - void forceStopBattle(); - void forceStartBattle(); - - // Temporal BG specific till 3.2 - void SendAreaSpiritHealerQueryOpcode(Player *pl, const uint64& guid); - void AddPlayerToResurrectQueue(uint64 npc_guid, uint64 player_guid); - void RemovePlayerFromResurrectQueue(uint64 player_guid); - void RelocateDeadPlayers(Creature *cr); - // BG end - protected: - // Temporal BG specific till 3.2 - std::vector<uint64> m_ResurrectQueue; // Player GUID - uint32 m_LastResurrectTime; - // Spirit Guide guid + Player list GUIDS - std::map<uint64, std::vector<uint64> > m_ReviveQueue; - - uint32 GetLastResurrectTime() const { return m_LastResurrectTime; } - uint32 GetReviveQueueSize() const { return m_ReviveQueue.size(); } - // BG end - - TeamId m_defender; - int32 m_tenacityStack; - - BuildingStateMap m_buildingStates; - BuildingState *m_gate; - - CreatureSet m_creatures; - CreatureSet m_vehicles[2]; - GameObjectSet m_gobjects; - QuestGiverMap m_questgivers; - - TeamPairMap m_creEntryPair, m_goDisplayPair; - QuestGiverPositionMap m_qgPosMap; - - bool m_wartime; - bool m_changeDefender; - uint32 m_timer; - uint32 m_clock[2]; - uint32 m_workshopCount[2]; - uint32 m_towerDestroyedCount[2]; - uint32 m_towerDamagedCount[2]; - - OPvPCapturePointWG *GetWorkshop(uint32 lowguid) const; - OPvPCapturePointWG *GetWorkshopByEngGuid(uint32 lowguid) const; - OPvPCapturePointWG *GetWorkshopByGOGuid(uint32 lowguid) const; - - void StartBattle(); - void EndBattle(); - - void UpdateClock(); - void UpdateClockDigit(uint32 &timer, uint32 digit, uint32 mod); - void PromotePlayer(Player *player) const; - void UpdateTenacityStack(); - void UpdateAllWorldObject(); - bool UpdateCreatureInfo(Creature *creature); - bool UpdateGameObjectInfo(GameObject *go) const; - - bool CanBuildVehicle(OPvPCapturePointWG *workshop) const; - OutdoorPvPWGCreType GetCreatureType(uint32 entry) const; - - void RebuildAllBuildings(); - - void SendInitWorldStatesTo(Player *player = NULL) const; - void RemoveOfflinePlayerWGAuras(); - void RewardMarkOfHonor(Player *player, uint32 count); - void MoveQuestGiver(uint32 guid); - void LoadQuestGiverMap(uint32 guid, Position posHorde, Position posAlli); - bool UpdateQuestGiverPosition(uint32 guid, Creature *creature); -}; - -class OPvPCapturePointWG : public OPvPCapturePoint -{ - public: - explicit OPvPCapturePointWG(OutdoorPvPWG *opvp, BuildingState *state); - void SetTeamByBuildingState(); - void ChangeState() {} - void ChangeTeam(TeamId oldteam); - - uint32 *m_spiEntry; - uint32 m_spiGuid; - Creature *m_spiritguide; - - uint32 *m_engEntry; - uint32 m_engGuid; - Creature *m_engineer; - uint32 m_workshopGuid; - BuildingState *m_buildingState; - protected: - OutdoorPvPWG *m_wintergrasp; -}; - -#endif |