mirror of
https://github.com/araxiaonline/TrinityCore.git
synced 2026-06-24 15:40:28 -04:00
81a3c135a7
The script references BattlefieldWG, which is not exported in dynamic builds.
Move the script, so it is in the same library.
(cherry picked from commit c40b897d36)
1902 lines
75 KiB
C++
1902 lines
75 KiB
C++
/*
|
|
* 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 <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
/// @todo Implement proper support for vehicle+player teleportation
|
|
/// @todo Use spell victory/defeat in wg instead of RewardMarkOfHonor() && RewardHonor
|
|
/// @todo Add proper implement of achievement
|
|
|
|
#include "BattlefieldWG.h"
|
|
#include "AchievementMgr.h"
|
|
#include "BattlefieldMgr.h"
|
|
#include "Battleground.h"
|
|
#include "CreatureTextMgr.h"
|
|
#include "GameObject.h"
|
|
#include "GameTime.h"
|
|
#include "DB2Stores.h"
|
|
#include "Log.h"
|
|
#include "MapManager.h"
|
|
#include "ObjectAccessor.h"
|
|
#include "Player.h"
|
|
#include "Random.h"
|
|
#include "ScriptedCreature.h"
|
|
#include "ScriptMgr.h"
|
|
#include "SpellAuras.h"
|
|
#include "TemporarySummon.h"
|
|
#include "World.h"
|
|
#include "WorldSession.h"
|
|
#include "WorldStatePackets.h"
|
|
|
|
struct BfWGCoordGY
|
|
{
|
|
Position Pos;
|
|
uint32 GraveyardID;
|
|
uint32 TextID; // for gossip menu
|
|
TeamId StartControl;
|
|
};
|
|
|
|
// 7 in sql, 7 in header
|
|
BfWGCoordGY const WGGraveyard[BATTLEFIELD_WG_GRAVEYARD_MAX] =
|
|
{
|
|
{ { 5104.750f, 2300.940f, 368.579f, 0.733038f }, 1329, BATTLEFIELD_WG_GOSSIPTEXT_GY_NE, TEAM_NEUTRAL },
|
|
{ { 5099.120f, 3466.036f, 368.484f, 5.317802f }, 1330, BATTLEFIELD_WG_GOSSIPTEXT_GY_NW, TEAM_NEUTRAL },
|
|
{ { 4314.648f, 2408.522f, 392.642f, 6.268125f }, 1333, BATTLEFIELD_WG_GOSSIPTEXT_GY_SE, TEAM_NEUTRAL },
|
|
{ { 4331.716f, 3235.695f, 390.251f, 0.008500f }, 1334, BATTLEFIELD_WG_GOSSIPTEXT_GY_SW, TEAM_NEUTRAL },
|
|
{ { 5537.986f, 2897.493f, 517.057f, 4.819249f }, 1285, BATTLEFIELD_WG_GOSSIPTEXT_GY_KEEP, TEAM_NEUTRAL },
|
|
{ { 5032.454f, 3711.382f, 372.468f, 3.971623f }, 1331, BATTLEFIELD_WG_GOSSIPTEXT_GY_HORDE, TEAM_HORDE },
|
|
{ { 5140.790f, 2179.120f, 390.950f, 1.972220f }, 1332, BATTLEFIELD_WG_GOSSIPTEXT_GY_ALLIANCE, TEAM_ALLIANCE },
|
|
};
|
|
|
|
uint32 const ClockWorldState[] = { WS_BATTLEFIELD_WG_TIME_BATTLE_END, WS_BATTLEFIELD_WG_TIME_NEXT_BATTLE };
|
|
uint32 const WintergraspFaction[] = { FACTION_ALLIANCE_GENERIC_WG, FACTION_HORDE_GENERIC_WG, FACTION_FRIENDLY };
|
|
|
|
Position const WintergraspStalkerPos = { 4948.985f, 2937.789f, 550.5172f, 1.815142f };
|
|
|
|
Position const WintergraspRelicPos = { 5440.379f, 2840.493f, 430.2816f, -1.832595f };
|
|
QuaternionData const WintergraspRelicRot = { 0.f, 0.f, -0.7933531f, 0.6087617f };
|
|
|
|
uint8 const WG_MAX_OBJ = 32;
|
|
uint8 const WG_MAX_TURRET = 15;
|
|
uint8 const WG_MAX_TELEPORTER = 12;
|
|
uint8 const WG_MAX_WORKSHOP = 6;
|
|
uint8 const WG_MAX_TOWER = 7;
|
|
|
|
// *****************************************************
|
|
// ************ Destructible (Wall, Tower..) ***********
|
|
// *****************************************************
|
|
|
|
struct WintergraspBuildingSpawnData
|
|
{
|
|
uint32 entry;
|
|
uint32 WorldState;
|
|
Position pos;
|
|
QuaternionData rot;
|
|
WintergraspGameObjectBuildingType type;
|
|
};
|
|
|
|
WintergraspBuildingSpawnData const WGGameObjectBuilding[WG_MAX_OBJ] =
|
|
{
|
|
// Wall (Not spawned in db)
|
|
// Entry WS X Y Z O rX rY rZ rW Type
|
|
{ 190219, 3749, { 5371.457f, 3047.472f, 407.5710f, 3.14159300f }, { 0.f, 0.f, -1.000000000f, 0.00000000f }, BATTLEFIELD_WG_OBJECTTYPE_WALL },
|
|
{ 190220, 3750, { 5331.264f, 3047.105f, 407.9228f, 0.05235888f }, { 0.f, 0.f, 0.026176450f, 0.99965730f }, BATTLEFIELD_WG_OBJECTTYPE_WALL },
|
|
{ 191795, 3764, { 5385.841f, 2909.490f, 409.7127f, 0.00872424f }, { 0.f, 0.f, 0.004362106f, 0.99999050f }, BATTLEFIELD_WG_OBJECTTYPE_WALL },
|
|
{ 191796, 3772, { 5384.452f, 2771.835f, 410.2704f, 3.14159300f }, { 0.f, 0.f, -1.000000000f, 0.00000000f }, BATTLEFIELD_WG_OBJECTTYPE_WALL },
|
|
{ 191799, 3762, { 5371.436f, 2630.610f, 408.8163f, 3.13285800f }, { 0.f, 0.f, 0.999990500f, 0.00436732f }, BATTLEFIELD_WG_OBJECTTYPE_WALL },
|
|
{ 191800, 3766, { 5301.838f, 2909.089f, 409.8661f, 0.00872424f }, { 0.f, 0.f, 0.004362106f, 0.99999050f }, BATTLEFIELD_WG_OBJECTTYPE_WALL },
|
|
{ 191801, 3770, { 5301.063f, 2771.411f, 409.9014f, 3.14159300f }, { 0.f, 0.f, -1.000000000f, 0.00000000f }, BATTLEFIELD_WG_OBJECTTYPE_WALL },
|
|
{ 191802, 3751, { 5280.197f, 2995.583f, 408.8249f, 1.61442800f }, { 0.f, 0.f, 0.722363500f, 0.69151360f }, BATTLEFIELD_WG_OBJECTTYPE_WALL },
|
|
{ 191803, 3752, { 5279.136f, 2956.023f, 408.6041f, 1.57079600f }, { 0.f, 0.f, 0.707106600f, 0.70710690f }, BATTLEFIELD_WG_OBJECTTYPE_WALL },
|
|
{ 191804, 3767, { 5278.685f, 2882.513f, 409.5388f, 1.57079600f }, { 0.f, 0.f, 0.707106600f, 0.70710690f }, BATTLEFIELD_WG_OBJECTTYPE_WALL },
|
|
{ 191806, 3769, { 5279.502f, 2798.945f, 409.9983f, 1.57079600f }, { 0.f, 0.f, 0.707106600f, 0.70710690f }, BATTLEFIELD_WG_OBJECTTYPE_WALL },
|
|
{ 191807, 3759, { 5279.937f, 2724.766f, 409.9452f, 1.56207000f }, { 0.f, 0.f, 0.704014800f, 0.71018530f }, BATTLEFIELD_WG_OBJECTTYPE_WALL },
|
|
{ 191808, 3760, { 5279.601f, 2683.786f, 409.8488f, 1.55334100f }, { 0.f, 0.f, 0.700908700f, 0.71325110f }, BATTLEFIELD_WG_OBJECTTYPE_WALL },
|
|
{ 191809, 3761, { 5330.955f, 2630.777f, 409.2826f, 3.13285800f }, { 0.f, 0.f, 0.999990500f, 0.00436732f }, BATTLEFIELD_WG_OBJECTTYPE_WALL },
|
|
{ 190369, 3753, { 5256.085f, 2933.963f, 409.3571f, 3.13285800f }, { 0.f, 0.f, 0.999990500f, 0.00436732f }, BATTLEFIELD_WG_OBJECTTYPE_WALL },
|
|
{ 190370, 3758, { 5257.463f, 2747.327f, 409.7427f, -3.13285800f }, { 0.f, 0.f, -0.999990500f, 0.00436732f }, BATTLEFIELD_WG_OBJECTTYPE_WALL },
|
|
{ 190371, 3754, { 5214.960f, 2934.089f, 409.1905f, -0.00872424f }, { 0.f, 0.f, -0.004362106f, 0.99999050f }, BATTLEFIELD_WG_OBJECTTYPE_WALL },
|
|
{ 190372, 3757, { 5215.821f, 2747.566f, 409.1884f, -3.13285800f }, { 0.f, 0.f, -0.999990500f, 0.00436732f }, BATTLEFIELD_WG_OBJECTTYPE_WALL },
|
|
{ 190374, 3755, { 5162.273f, 2883.043f, 410.2556f, 1.57952200f }, { 0.f, 0.f, 0.710185100f, 0.70401500f }, BATTLEFIELD_WG_OBJECTTYPE_WALL },
|
|
{ 190376, 3756, { 5163.724f, 2799.838f, 409.2270f, 1.57952200f }, { 0.f, 0.f, 0.710185100f, 0.70401500f }, BATTLEFIELD_WG_OBJECTTYPE_WALL },
|
|
|
|
// Tower of keep (Not spawned in db)
|
|
{ 190221, 3711, { 5281.154f, 3044.588f, 407.8434f, 3.115388f }, { 0.f, 0.f, 0.9999142f, 0.013101960f }, BATTLEFIELD_WG_OBJECTTYPE_KEEP_TOWER }, // NW
|
|
{ 190373, 3713, { 5163.757f, 2932.228f, 409.1904f, 3.124123f }, { 0.f, 0.f, 0.9999619f, 0.008734641f }, BATTLEFIELD_WG_OBJECTTYPE_KEEP_TOWER }, // SW
|
|
{ 190377, 3714, { 5166.397f, 2748.368f, 409.1884f, -1.570796f }, { 0.f, 0.f, -0.7071066f, 0.707106900f }, BATTLEFIELD_WG_OBJECTTYPE_KEEP_TOWER }, // SE
|
|
{ 190378, 3712, { 5281.192f, 2632.479f, 409.0985f, -1.588246f }, { 0.f, 0.f, -0.7132492f, 0.700910500f }, BATTLEFIELD_WG_OBJECTTYPE_KEEP_TOWER }, // NE
|
|
|
|
// Wall (with passage) (Not spawned in db)
|
|
{ 191797, 3765, { 5343.290f, 2908.860f, 409.5757f, 0.00872424f }, { 0.f, 0.f, 0.004362106f, 0.9999905f }, BATTLEFIELD_WG_OBJECTTYPE_WALL },
|
|
{ 191798, 3771, { 5342.719f, 2771.386f, 409.6249f, 3.14159300f }, { 0.f, 0.f, -1.000000000f, 0.0000000f }, BATTLEFIELD_WG_OBJECTTYPE_WALL },
|
|
{ 191805, 3768, { 5279.126f, 2840.797f, 409.7826f, 1.57952200f }, { 0.f, 0.f, 0.710185100f, 0.7040150f }, BATTLEFIELD_WG_OBJECTTYPE_WALL },
|
|
|
|
// South tower (Not spawned in db)
|
|
{ 190356, 3704, { 4557.173f, 3623.943f, 395.8828f, 1.675516f }, { 0.f, 0.f, 0.7431450f, 0.669130400f }, BATTLEFIELD_WG_OBJECTTYPE_TOWER }, // W
|
|
{ 190357, 3705, { 4398.172f, 2822.497f, 405.6270f, -3.124123f }, { 0.f, 0.f, -0.9999619f, 0.008734641f }, BATTLEFIELD_WG_OBJECTTYPE_TOWER }, // S
|
|
{ 190358, 3706, { 4459.105f, 1944.326f, 434.9912f, -2.002762f }, { 0.f, 0.f, -0.8422165f, 0.539139500f }, BATTLEFIELD_WG_OBJECTTYPE_TOWER }, // E
|
|
|
|
// Door of forteress (Not spawned in db)
|
|
{ GO_WINTERGRASP_FORTRESS_GATE, 3763, { 5162.991f, 2841.232f, 410.1892f, -3.132858f }, { 0.f, 0.f, -0.9999905f, 0.00436732f }, BATTLEFIELD_WG_OBJECTTYPE_DOOR },
|
|
|
|
// Last door (Not spawned in db)
|
|
{ GO_WINTERGRASP_VAULT_GATE, 3773, { 5397.108f, 2841.54f, 425.9014f, 3.141593f }, { 0.f, 0.f, -1.f, 0.f }, BATTLEFIELD_WG_OBJECTTYPE_DOOR_LAST },
|
|
};
|
|
|
|
struct StaticWintergraspTowerInfo
|
|
{
|
|
uint8 TowerId;
|
|
|
|
struct
|
|
{
|
|
uint8 Damaged;
|
|
uint8 Destroyed;
|
|
} TextIds;
|
|
};
|
|
|
|
StaticWintergraspTowerInfo const TowerData[WG_MAX_TOWER] =
|
|
{
|
|
{ BATTLEFIELD_WG_TOWER_FORTRESS_NW, { BATTLEFIELD_WG_TEXT_NW_KEEPTOWER_DAMAGE, BATTLEFIELD_WG_TEXT_NW_KEEPTOWER_DESTROY } },
|
|
{ BATTLEFIELD_WG_TOWER_FORTRESS_SW, { BATTLEFIELD_WG_TEXT_SW_KEEPTOWER_DAMAGE, BATTLEFIELD_WG_TEXT_SW_KEEPTOWER_DESTROY } },
|
|
{ BATTLEFIELD_WG_TOWER_FORTRESS_SE, { BATTLEFIELD_WG_TEXT_SE_KEEPTOWER_DAMAGE, BATTLEFIELD_WG_TEXT_SE_KEEPTOWER_DESTROY } },
|
|
{ BATTLEFIELD_WG_TOWER_FORTRESS_NE, { BATTLEFIELD_WG_TEXT_NE_KEEPTOWER_DAMAGE, BATTLEFIELD_WG_TEXT_NE_KEEPTOWER_DESTROY } },
|
|
{ BATTLEFIELD_WG_TOWER_SHADOWSIGHT, { BATTLEFIELD_WG_TEXT_WESTERN_TOWER_DAMAGE, BATTLEFIELD_WG_TEXT_WESTERN_TOWER_DESTROY } },
|
|
{ BATTLEFIELD_WG_TOWER_WINTER_S_EDGE, { BATTLEFIELD_WG_TEXT_SOUTHERN_TOWER_DAMAGE, BATTLEFIELD_WG_TEXT_SOUTHERN_TOWER_DESTROY } },
|
|
{ BATTLEFIELD_WG_TOWER_FLAMEWATCH, { BATTLEFIELD_WG_TEXT_EASTERN_TOWER_DAMAGE, BATTLEFIELD_WG_TEXT_EASTERN_TOWER_DESTROY } }
|
|
};
|
|
|
|
Position const WGTurret[WG_MAX_TURRET] =
|
|
{
|
|
{ 5391.19f, 3060.8f, 419.616f, 1.69557f },
|
|
{ 5266.75f, 2976.5f, 421.067f, 3.20354f },
|
|
{ 5234.86f, 2948.8f, 420.88f, 1.61311f },
|
|
{ 5323.05f, 2923.7f, 421.645f, 1.5817f },
|
|
{ 5363.82f, 2923.87f, 421.709f, 1.60527f },
|
|
{ 5264.04f, 2861.34f, 421.587f, 3.21142f },
|
|
{ 5264.68f, 2819.78f, 421.656f, 3.15645f },
|
|
{ 5322.16f, 2756.69f, 421.646f, 4.69978f },
|
|
{ 5363.78f, 2756.77f, 421.629f, 4.78226f },
|
|
{ 5236.2f, 2732.68f, 421.649f, 4.72336f },
|
|
{ 5265.02f, 2704.63f, 421.7f, 3.12507f },
|
|
{ 5350.87f, 2616.03f, 421.243f, 4.72729f },
|
|
{ 5390.95f, 2615.5f, 421.126f, 4.6409f },
|
|
{ 5148.8f, 2820.24f, 421.621f, 3.16043f },
|
|
{ 5147.98f, 2861.93f, 421.63f, 3.18792f },
|
|
};
|
|
|
|
struct WintergraspObjectPositionData
|
|
{
|
|
Position Pos;
|
|
uint32 HordeEntry;
|
|
uint32 AllianceEntry;
|
|
};
|
|
|
|
struct WintergraspGameObjectData
|
|
{
|
|
Position Pos;
|
|
QuaternionData Rot;
|
|
uint32 HordeEntry;
|
|
uint32 AllianceEntry;
|
|
};
|
|
|
|
WintergraspGameObjectData const WGPortalDefenderData[WG_MAX_TELEPORTER] =
|
|
{
|
|
// Player teleporter
|
|
{ { 5153.408f, 2901.349f, 409.1913f, -0.06981169f }, { 0.f, 0.f, -0.03489876f, 0.9993908f }, 190763, 191575 },
|
|
{ { 5268.698f, 2666.421f, 409.0985f, -0.71558490f }, { 0.f, 0.f, -0.35020730f, 0.9366722f }, 190763, 191575 },
|
|
{ { 5197.050f, 2944.814f, 409.1913f, 2.33874000f }, { 0.f, 0.f, 0.92050460f, 0.3907318f }, 190763, 191575 },
|
|
{ { 5196.671f, 2737.345f, 409.1892f, -2.93213900f }, { 0.f, 0.f, -0.99452110f, 0.1045355f }, 190763, 191575 },
|
|
{ { 5314.580f, 3055.852f, 408.8620f, 0.54105060f }, { 0.f, 0.f, 0.26723770f, 0.9636307f }, 190763, 191575 },
|
|
{ { 5391.277f, 2828.094f, 418.6752f, -2.16420600f }, { 0.f, 0.f, -0.88294700f, 0.4694727f }, 190763, 191575 },
|
|
{ { 5153.931f, 2781.671f, 409.2455f, 1.65806200f }, { 0.f, 0.f, 0.73727700f, 0.6755905f }, 190763, 191575 },
|
|
{ { 5311.445f, 2618.931f, 409.0916f, -2.37364400f }, { 0.f, 0.f, -0.92718320f, 0.3746083f }, 190763, 191575 },
|
|
{ { 5269.208f, 3013.838f, 408.8276f, -1.76278200f }, { 0.f, 0.f, -0.77162460f, 0.6360782f }, 190763, 191575 },
|
|
|
|
{ { 5401.634f, 2853.667f, 418.6748f, 2.63544400f }, { 0.f, 0.f, 0.96814730f, 0.2503814f }, 192819, 192819 }, // return portal inside fortress, neutral
|
|
// Vehicle teleporter
|
|
{ { 5314.515f, 2703.687f, 408.5502f, -0.89011660f }, { 0.f, 0.f, -0.43051050f, 0.9025856f }, 192951, 192951 },
|
|
{ { 5316.252f, 2977.042f, 408.5385f, -0.82030330f }, { 0.f, 0.f, -0.39874840f, 0.9170604f }, 192951, 192951 }
|
|
};
|
|
|
|
// *********************************************************
|
|
// **********Tower Element(GameObject, Creature)************
|
|
// *********************************************************
|
|
|
|
struct WintergraspTowerData
|
|
{
|
|
uint32 towerEntry; // Gameobject id of tower
|
|
std::vector<WintergraspGameObjectData> GameObject; // Gameobject position and entry (Horde/Alliance)
|
|
|
|
// Creature: Turrets and Guard /// @todo: Killed on Tower destruction ? Tower damage ? Requires confirming
|
|
std::vector<WintergraspObjectPositionData> CreatureBottom;
|
|
};
|
|
|
|
uint8 const WG_MAX_ATTACKTOWERS = 3;
|
|
// 192414 : 0 in sql, 1 in header
|
|
// 192278 : 0 in sql, 3 in header
|
|
WintergraspTowerData const AttackTowers[WG_MAX_ATTACKTOWERS] =
|
|
{
|
|
// West tower
|
|
{
|
|
190356,
|
|
{
|
|
{ { 4559.113f, 3606.216f, 419.9992f, 4.799657f }, { 0.f, 0.f, -0.67558960f, 0.73727790f }, 192488, 192501 }, // Flag on tower
|
|
{ { 4539.420f, 3622.490f, 420.0342f, 3.211419f }, { 0.f, 0.f, -0.99939060f, 0.03490613f }, 192488, 192501 }, // Flag on tower
|
|
{ { 4555.258f, 3641.648f, 419.9740f, 1.675514f }, { 0.f, 0.f, 0.74314400f, 0.66913150f }, 192488, 192501 }, // Flag on tower
|
|
{ { 4574.872f, 3625.911f, 420.0792f, 0.087266f }, { 0.f, 0.f, 0.04361916f, 0.99904820f }, 192488, 192501 }, // Flag on tower
|
|
{ { 4433.899f, 3534.142f, 360.2750f, 4.433136f }, { 0.f, 0.f, -0.79863550f, 0.60181500f }, 192269, 192278 }, // Flag near workshop
|
|
{ { 4572.933f, 3475.519f, 363.0090f, 1.422443f }, { 0.f, 0.f, 0.65275960f, 0.75756520f }, 192269, 192277 } // Flag near bridge
|
|
},
|
|
{
|
|
{ { 4418.688477f, 3506.251709f, 358.975494f, 4.293305f }, BATTLEFIELD_WG_NPC_GUARD_H, BATTLEFIELD_WG_NPC_GUARD_A } // Roaming Guard
|
|
}
|
|
},
|
|
// South Tower
|
|
{
|
|
190357,
|
|
{
|
|
{ { 4416.004f, 2822.666f, 429.8512f, 6.2657330f }, { 0.f, 0.f, -0.00872612f, 0.99996190f }, 192488, 192501 }, // Flag on tower
|
|
{ { 4398.819f, 2804.698f, 429.7920f, 4.6949370f }, { 0.f, 0.f, -0.71325020f, 0.70090960f }, 192488, 192501 }, // Flag on tower
|
|
{ { 4387.622f, 2719.566f, 389.9351f, 4.7385700f }, { 0.f, 0.f, -0.69779010f, 0.71630230f }, 192366, 192414 }, // Flag near tower
|
|
{ { 4464.124f, 2855.453f, 406.1106f, 0.8290324f }, { 0.f, 0.f, 0.40274720f, 0.91531130f }, 192366, 192429 }, // Flag near tower
|
|
{ { 4526.457f, 2810.181f, 391.1997f, 3.2899610f }, { 0.f, 0.f, -0.99724960f, 0.07411628f }, 192269, 192278 } // Flag near bridge
|
|
},
|
|
{
|
|
{ { 4452.859863f, 2808.870117f, 402.604004f, 6.056290f }, BATTLEFIELD_WG_NPC_GUARD_H, BATTLEFIELD_WG_NPC_GUARD_A }, // Standing Guard
|
|
{ { 4455.899902f, 2835.958008f, 401.122559f, 0.034907f }, BATTLEFIELD_WG_NPC_GUARD_H, BATTLEFIELD_WG_NPC_GUARD_A }, // Standing Guard
|
|
{ { 4412.649414f, 2953.792236f, 374.799957f, 0.980838f }, BATTLEFIELD_WG_NPC_GUARD_H, BATTLEFIELD_WG_NPC_GUARD_A }, // Roaming Guard
|
|
{ { 4362.089844f, 2811.510010f, 407.337006f, 3.193950f }, BATTLEFIELD_WG_NPC_GUARD_H, BATTLEFIELD_WG_NPC_GUARD_A }, // Standing Guard
|
|
{ { 4412.290039f, 2753.790039f, 401.015015f, 5.829400f }, BATTLEFIELD_WG_NPC_GUARD_H, BATTLEFIELD_WG_NPC_GUARD_A }, // Standing Guard
|
|
{ { 4421.939941f, 2773.189941f, 400.894989f, 5.707230f }, BATTLEFIELD_WG_NPC_GUARD_H, BATTLEFIELD_WG_NPC_GUARD_A } // Standing Guard
|
|
}
|
|
},
|
|
// East Tower
|
|
{
|
|
190358,
|
|
{
|
|
{ { 4466.793f, 1960.418f, 459.1437f, 1.151916f }, { 0.f, 0.f, 0.5446386f, 0.8386708f }, 192488, 192501 }, // Flag on tower
|
|
{ { 4475.351f, 1937.031f, 459.0702f, 5.846854f }, { 0.f, 0.f, -0.2164392f, 0.9762961f }, 192488, 192501 }, // Flag on tower
|
|
{ { 4451.758f, 1928.104f, 459.0759f, 4.276057f }, { 0.f, 0.f, -0.8433914f, 0.5372996f }, 192488, 192501 }, // Flag on tower
|
|
{ { 4442.987f, 1951.898f, 459.0930f, 2.740162f }, { 0.f, 0.f, 0.9799242f, 0.1993704f }, 192488, 192501 } // Flag on tower
|
|
},
|
|
{
|
|
{ { 4501.060059f, 1990.280029f, 431.157013f, 1.029740f }, BATTLEFIELD_WG_NPC_GUARD_H, BATTLEFIELD_WG_NPC_GUARD_A }, // Standing Guard
|
|
{ { 4463.830078f, 2015.180054f, 430.299988f, 1.431170f }, BATTLEFIELD_WG_NPC_GUARD_H, BATTLEFIELD_WG_NPC_GUARD_A }, // Standing Guard
|
|
{ { 4494.580078f, 1943.760010f, 435.627014f, 6.195920f }, BATTLEFIELD_WG_NPC_GUARD_H, BATTLEFIELD_WG_NPC_GUARD_A }, // Standing Guard
|
|
{ { 4450.149902f, 1897.579956f, 435.045013f, 4.398230f }, BATTLEFIELD_WG_NPC_GUARD_H, BATTLEFIELD_WG_NPC_GUARD_A }, // Standing Guard
|
|
{ { 4428.870117f, 1906.869995f, 432.648010f, 3.996800f }, BATTLEFIELD_WG_NPC_GUARD_H, BATTLEFIELD_WG_NPC_GUARD_A } // Standing Guard
|
|
}
|
|
}
|
|
};
|
|
|
|
struct WintergraspTowerCannonData
|
|
{
|
|
uint32 towerEntry;
|
|
std::vector<Position> TowerCannonBottom;
|
|
std::vector<Position> TurretTop;
|
|
};
|
|
|
|
uint8 const WG_MAX_TOWER_CANNON = 7;
|
|
|
|
WintergraspTowerCannonData const TowerCannon[WG_MAX_TOWER_CANNON] =
|
|
{
|
|
{
|
|
190221,
|
|
{
|
|
// no cannons at bottom
|
|
},
|
|
{
|
|
{ 5255.88f, 3047.63f, 438.499f, 3.13677f },
|
|
{ 5280.90f, 3071.32f, 438.499f, 1.62879f }
|
|
}
|
|
},
|
|
{
|
|
190373,
|
|
{
|
|
// no cannons at bottom
|
|
},
|
|
{
|
|
{ 5138.59f, 2935.16f, 439.845f, 3.11723f },
|
|
{ 5163.06f, 2959.52f, 439.846f, 1.47258f }
|
|
}
|
|
},
|
|
{
|
|
190377,
|
|
{
|
|
// no cannons at bottom
|
|
},
|
|
{
|
|
{ 5163.84f, 2723.74f, 439.844f, 1.39940f },
|
|
{ 5139.69f, 2747.40f, 439.844f, 3.17221f }
|
|
}
|
|
},
|
|
{
|
|
190378,
|
|
{
|
|
// no cannons at bottom
|
|
},
|
|
{
|
|
{ 5278.21f, 2607.23f, 439.755f, 4.71944f },
|
|
{ 5255.01f, 2631.98f, 439.755f, 3.15257f }
|
|
}
|
|
},
|
|
{
|
|
190356,
|
|
{
|
|
{ 4537.380371f, 3599.531738f, 402.886993f, 3.998462f },
|
|
{ 4581.497559f, 3604.087158f, 402.886963f, 5.651723f }
|
|
},
|
|
{
|
|
{ 4469.448242f, 1966.623779f, 465.647217f, 1.153573f },
|
|
{ 4581.895996f, 3626.438477f, 426.539062f, 0.117806f }
|
|
}
|
|
},
|
|
{
|
|
190357,
|
|
{
|
|
{ 4421.640137f, 2799.935791f, 412.630920f, 5.459298f },
|
|
{ 4420.263184f, 2845.340332f, 412.630951f, 0.742197f }
|
|
},
|
|
{
|
|
{ 4423.430664f, 2822.762939f, 436.283142f, 6.223487f },
|
|
{ 4397.825684f, 2847.629639f, 436.283325f, 1.579430f },
|
|
{ 4398.814941f, 2797.266357f, 436.283051f, 4.703747f }
|
|
}
|
|
},
|
|
{
|
|
190358,
|
|
{
|
|
{ 4448.138184f, 1974.998779f, 441.995911f, 1.967238f },
|
|
{ 4448.713379f, 1955.148682f, 441.995178f, 0.380733f }
|
|
},
|
|
{
|
|
{ 4469.448242f, 1966.623779f, 465.647217f, 1.153573f },
|
|
{ 4481.996582f, 1933.658325f, 465.647186f, 5.873029f }
|
|
}
|
|
}
|
|
};
|
|
|
|
// *********************************************************
|
|
// *****************WorkShop Data & Element*****************
|
|
// *********************************************************
|
|
|
|
struct StaticWintergraspWorkshopInfo
|
|
{
|
|
uint8 WorkshopId;
|
|
uint32 WorldStateId;
|
|
|
|
struct
|
|
{
|
|
uint8 AllianceCapture;
|
|
uint8 AllianceAttack;
|
|
uint8 HordeCapture;
|
|
uint8 HordeAttack;
|
|
} TextIds;
|
|
};
|
|
|
|
StaticWintergraspWorkshopInfo const WorkshopData[WG_MAX_WORKSHOP] =
|
|
{
|
|
{ BATTLEFIELD_WG_WORKSHOP_NE, WS_BATTLEFIELD_WG_WORKSHOP_NE, { BATTLEFIELD_WG_TEXT_SUNKEN_RING_CAPTURE_ALLIANCE, BATTLEFIELD_WG_TEXT_SUNKEN_RING_ATTACK_ALLIANCE, BATTLEFIELD_WG_TEXT_SUNKEN_RING_CAPTURE_HORDE, BATTLEFIELD_WG_TEXT_SUNKEN_RING_ATTACK_HORDE } },
|
|
{ BATTLEFIELD_WG_WORKSHOP_NW, WS_BATTLEFIELD_WG_WORKSHOP_NW, { BATTLEFIELD_WG_TEXT_BROKEN_TEMPLE_CAPTURE_ALLIANCE, BATTLEFIELD_WG_TEXT_BROKEN_TEMPLE_ATTACK_ALLIANCE, BATTLEFIELD_WG_TEXT_BROKEN_TEMPLE_CAPTURE_HORDE, BATTLEFIELD_WG_TEXT_BROKEN_TEMPLE_ATTACK_HORDE } },
|
|
{ BATTLEFIELD_WG_WORKSHOP_SE, WS_BATTLEFIELD_WG_WORKSHOP_SE, { BATTLEFIELD_WG_TEXT_EASTSPARK_CAPTURE_ALLIANCE, BATTLEFIELD_WG_TEXT_EASTSPARK_ATTACK_ALLIANCE, BATTLEFIELD_WG_TEXT_EASTSPARK_CAPTURE_HORDE, BATTLEFIELD_WG_TEXT_EASTSPARK_ATTACK_HORDE } },
|
|
{ BATTLEFIELD_WG_WORKSHOP_SW, WS_BATTLEFIELD_WG_WORKSHOP_SW, { BATTLEFIELD_WG_TEXT_WESTSPARK_CAPTURE_ALLIANCE, BATTLEFIELD_WG_TEXT_WESTSPARK_ATTACK_ALLIANCE, BATTLEFIELD_WG_TEXT_WESTSPARK_CAPTURE_HORDE, BATTLEFIELD_WG_TEXT_WESTSPARK_ATTACK_HORDE } },
|
|
// KEEP WORKSHOPS - It can't be taken, so it doesn't have a textids
|
|
{ BATTLEFIELD_WG_WORKSHOP_KEEP_WEST, WS_BATTLEFIELD_WG_WORKSHOP_K_W, { 0, 0, 0, 0 } },
|
|
{ BATTLEFIELD_WG_WORKSHOP_KEEP_EAST, WS_BATTLEFIELD_WG_WORKSHOP_K_E, { 0, 0, 0, 0 } }
|
|
};
|
|
|
|
BattlefieldWG::~BattlefieldWG()
|
|
{
|
|
for (WintergraspWorkshop* workshop : Workshops)
|
|
delete workshop;
|
|
|
|
for (BfWGGameObjectBuilding* building : BuildingsInZone)
|
|
delete building;
|
|
}
|
|
|
|
bool BattlefieldWG::SetupBattlefield()
|
|
{
|
|
m_TypeId = BATTLEFIELD_WG; // See enum BattlefieldTypes
|
|
m_BattleId = BATTLEFIELD_BATTLEID_WG;
|
|
m_ZoneId = AREA_WINTERGRASP;
|
|
m_MapId = BATTLEFIELD_WG_MAPID;
|
|
m_Map = sMapMgr->CreateBaseMap(m_MapId);
|
|
|
|
InitStalker(BATTLEFIELD_WG_NPC_STALKER, WintergraspStalkerPos);
|
|
|
|
m_MaxPlayer = sWorld->getIntConfig(CONFIG_WINTERGRASP_PLR_MAX);
|
|
m_IsEnabled = sWorld->getBoolConfig(CONFIG_WINTERGRASP_ENABLE);
|
|
m_MinPlayer = sWorld->getIntConfig(CONFIG_WINTERGRASP_PLR_MIN);
|
|
m_MinLevel = sWorld->getIntConfig(CONFIG_WINTERGRASP_PLR_MIN_LVL);
|
|
m_BattleTime = sWorld->getIntConfig(CONFIG_WINTERGRASP_BATTLETIME) * MINUTE * IN_MILLISECONDS;
|
|
m_NoWarBattleTime = sWorld->getIntConfig(CONFIG_WINTERGRASP_NOBATTLETIME) * MINUTE * IN_MILLISECONDS;
|
|
m_RestartAfterCrash = sWorld->getIntConfig(CONFIG_WINTERGRASP_RESTART_AFTER_CRASH) * MINUTE * IN_MILLISECONDS;
|
|
|
|
m_TimeForAcceptInvite = 20;
|
|
m_StartGroupingTimer = 15 * MINUTE * IN_MILLISECONDS;
|
|
m_StartGrouping = false;
|
|
|
|
m_tenacityTeam = TEAM_NEUTRAL;
|
|
m_tenacityStack = 0;
|
|
|
|
KickPosition.Relocate(5728.117f, 2714.346f, 697.733f, 0);
|
|
KickPosition.m_mapId = m_MapId;
|
|
|
|
RegisterZone(m_ZoneId);
|
|
|
|
m_Data32.resize(BATTLEFIELD_WG_DATA_MAX);
|
|
|
|
m_saveTimer = 60000;
|
|
|
|
// Init Graveyards
|
|
SetGraveyardNumber(BATTLEFIELD_WG_GRAVEYARD_MAX);
|
|
|
|
// Load from db
|
|
if ((sWorld->getWorldState(WS_BATTLEFIELD_WG_ACTIVE) == 0) && (sWorld->getWorldState(WS_BATTLEFIELD_WG_DEFENDER) == 0)
|
|
&& (sWorld->getWorldState(ClockWorldState[0]) == 0))
|
|
{
|
|
sWorld->setWorldState(WS_BATTLEFIELD_WG_ACTIVE, uint64(false));
|
|
sWorld->setWorldState(WS_BATTLEFIELD_WG_DEFENDER, uint64(urand(0, 1)));
|
|
sWorld->setWorldState(ClockWorldState[0], uint64(m_NoWarBattleTime));
|
|
}
|
|
|
|
m_isActive = sWorld->getWorldState(WS_BATTLEFIELD_WG_ACTIVE) != 0;
|
|
m_DefenderTeam = TeamId(sWorld->getWorldState(WS_BATTLEFIELD_WG_DEFENDER));
|
|
|
|
m_Timer = sWorld->getWorldState(ClockWorldState[0]);
|
|
if (m_isActive)
|
|
{
|
|
m_isActive = false;
|
|
m_Timer = m_RestartAfterCrash;
|
|
}
|
|
|
|
SetData(BATTLEFIELD_WG_DATA_WON_A, uint32(sWorld->getWorldState(WS_BATTLEFIELD_WG_ATTACKED_A)));
|
|
SetData(BATTLEFIELD_WG_DATA_DEF_A, uint32(sWorld->getWorldState(WS_BATTLEFIELD_WG_DEFENDED_A)));
|
|
SetData(BATTLEFIELD_WG_DATA_WON_H, uint32(sWorld->getWorldState(WS_BATTLEFIELD_WG_ATTACKED_H)));
|
|
SetData(BATTLEFIELD_WG_DATA_DEF_H, uint32(sWorld->getWorldState(WS_BATTLEFIELD_WG_DEFENDED_H)));
|
|
|
|
for (uint8 i = 0; i < BATTLEFIELD_WG_GRAVEYARD_MAX; i++)
|
|
{
|
|
BfGraveyardWG* graveyard = new BfGraveyardWG(this);
|
|
|
|
// When between games, the graveyard is controlled by the defending team
|
|
if (WGGraveyard[i].StartControl == TEAM_NEUTRAL)
|
|
graveyard->Initialize(m_DefenderTeam, WGGraveyard[i].GraveyardID);
|
|
else
|
|
graveyard->Initialize(WGGraveyard[i].StartControl, WGGraveyard[i].GraveyardID);
|
|
|
|
graveyard->SetTextId(WGGraveyard[i].TextID);
|
|
m_GraveyardList[i] = graveyard;
|
|
}
|
|
|
|
|
|
Workshops.resize(WG_MAX_WORKSHOP);
|
|
// Spawn workshop creatures and gameobjects
|
|
for (uint8 i = 0; i < WG_MAX_WORKSHOP; i++)
|
|
{
|
|
WintergraspWorkshop* workshop = new WintergraspWorkshop(this, i);
|
|
if (i < BATTLEFIELD_WG_WORKSHOP_NE)
|
|
workshop->GiveControlTo(GetAttackerTeam(), true);
|
|
else
|
|
workshop->GiveControlTo(GetDefenderTeam(), true);
|
|
|
|
// Note: Capture point is added once the gameobject is created.
|
|
Workshops[i] = workshop;
|
|
}
|
|
|
|
// Spawn turrets and hide them per default
|
|
for (uint8 i = 0; i < WG_MAX_TURRET; i++)
|
|
{
|
|
Position towerCannonPos = WGTurret[i].GetPosition();
|
|
if (Creature* creature = SpawnCreature(NPC_WINTERGRASP_TOWER_CANNON, towerCannonPos))
|
|
{
|
|
CanonList.push_back(creature->GetGUID());
|
|
HideNpc(creature);
|
|
}
|
|
}
|
|
|
|
BuildingsInZone.resize(WG_MAX_OBJ);
|
|
// Spawn all gameobjects
|
|
for (uint8 i = 0; i < WG_MAX_OBJ; i++)
|
|
{
|
|
if (GameObject* go = SpawnGameObject(WGGameObjectBuilding[i].entry, WGGameObjectBuilding[i].pos, WGGameObjectBuilding[i].rot))
|
|
{
|
|
BfWGGameObjectBuilding* b = new BfWGGameObjectBuilding(this, WGGameObjectBuilding[i].type, WGGameObjectBuilding[i].WorldState);
|
|
b->Init(go);
|
|
if (!IsEnabled() && go->GetEntry() == GO_WINTERGRASP_VAULT_GATE)
|
|
go->SetDestructibleState(GO_DESTRUCTIBLE_DESTROYED);
|
|
|
|
BuildingsInZone[i] = b;
|
|
}
|
|
}
|
|
|
|
// Spawning portal defender
|
|
for (uint8 i = 0; i < WG_MAX_TELEPORTER; ++i)
|
|
{
|
|
WintergraspGameObjectData const& teleporter = WGPortalDefenderData[i];
|
|
if (GameObject* go = SpawnGameObject(teleporter.AllianceEntry, teleporter.Pos, teleporter.Rot))
|
|
{
|
|
DefenderPortalList[TEAM_ALLIANCE].push_back(go->GetGUID());
|
|
go->SetRespawnTime(GetDefenderTeam() == TEAM_ALLIANCE ? RESPAWN_IMMEDIATELY : RESPAWN_ONE_DAY);
|
|
}
|
|
|
|
if (GameObject* go = SpawnGameObject(teleporter.HordeEntry, teleporter.Pos, teleporter.Rot))
|
|
{
|
|
DefenderPortalList[TEAM_HORDE].push_back(go->GetGUID());
|
|
go->SetRespawnTime(GetDefenderTeam() == TEAM_HORDE ? RESPAWN_IMMEDIATELY : RESPAWN_ONE_DAY);
|
|
}
|
|
}
|
|
|
|
UpdateCounterVehicle(true);
|
|
return true;
|
|
}
|
|
|
|
bool BattlefieldWG::Update(uint32 diff)
|
|
{
|
|
bool m_return = Battlefield::Update(diff);
|
|
if (m_saveTimer <= diff)
|
|
{
|
|
sWorld->setWorldState(WS_BATTLEFIELD_WG_ACTIVE, m_isActive);
|
|
sWorld->setWorldState(WS_BATTLEFIELD_WG_DEFENDER, m_DefenderTeam);
|
|
sWorld->setWorldState(ClockWorldState[0], m_Timer);
|
|
sWorld->setWorldState(WS_BATTLEFIELD_WG_ATTACKED_A, GetData(BATTLEFIELD_WG_DATA_WON_A));
|
|
sWorld->setWorldState(WS_BATTLEFIELD_WG_DEFENDED_A, GetData(BATTLEFIELD_WG_DATA_DEF_A));
|
|
sWorld->setWorldState(WS_BATTLEFIELD_WG_ATTACKED_H, GetData(BATTLEFIELD_WG_DATA_WON_H));
|
|
sWorld->setWorldState(WS_BATTLEFIELD_WG_DEFENDED_H, GetData(BATTLEFIELD_WG_DATA_DEF_H));
|
|
m_saveTimer = 60 * IN_MILLISECONDS;
|
|
}
|
|
else
|
|
m_saveTimer -= diff;
|
|
|
|
return m_return;
|
|
}
|
|
|
|
void BattlefieldWG::OnBattleStart()
|
|
{
|
|
// Spawn titan relic
|
|
if (GameObject* relic = SpawnGameObject(GO_WINTERGRASP_TITAN_S_RELIC, WintergraspRelicPos, WintergraspRelicRot))
|
|
{
|
|
// Update faction of relic, only attacker can click on
|
|
relic->SetFaction(WintergraspFaction[GetAttackerTeam()]);
|
|
// Set in use (not allow to click on before last door is broken)
|
|
relic->AddFlag(GameObjectFlags(GO_FLAG_IN_USE | GO_FLAG_NOT_SELECTABLE));
|
|
m_titansRelicGUID = relic->GetGUID();
|
|
}
|
|
else
|
|
TC_LOG_ERROR("bg.battlefield", "WG: Failed to spawn titan relic.");
|
|
|
|
|
|
// Update tower visibility and update faction
|
|
for (auto itr = CanonList.begin(); itr != CanonList.end(); ++itr)
|
|
{
|
|
if (Creature* creature = GetCreature(*itr))
|
|
{
|
|
ShowNpc(creature, true);
|
|
creature->SetFaction(WintergraspFaction[GetDefenderTeam()]);
|
|
}
|
|
}
|
|
|
|
// Rebuild all wall
|
|
for (BfWGGameObjectBuilding* building : BuildingsInZone)
|
|
{
|
|
building->Rebuild();
|
|
building->UpdateTurretAttack(false);
|
|
}
|
|
|
|
SetData(BATTLEFIELD_WG_DATA_BROKEN_TOWER_ATT, 0);
|
|
SetData(BATTLEFIELD_WG_DATA_BROKEN_TOWER_DEF, 0);
|
|
SetData(BATTLEFIELD_WG_DATA_DAMAGED_TOWER_ATT, 0);
|
|
SetData(BATTLEFIELD_WG_DATA_DAMAGED_TOWER_DEF, 0);
|
|
|
|
// Update graveyard (in no war time all graveyard is to deffender, in war time, depend of base)
|
|
for (WintergraspWorkshop* workshop : Workshops)
|
|
workshop->UpdateGraveyardAndWorkshop();
|
|
|
|
for (uint8 team = 0; team < PVP_TEAMS_COUNT; ++team)
|
|
{
|
|
for (auto itr = m_players[team].begin(); itr != m_players[team].end(); ++itr)
|
|
{
|
|
// Kick player in orb room, TODO: offline player ?
|
|
if (Player* player = ObjectAccessor::FindPlayer(*itr))
|
|
{
|
|
float x, y, z;
|
|
player->GetPosition(x, y, z);
|
|
if (5500 > x && x > 5392 && y < 2880 && y > 2800 && z < 480)
|
|
player->TeleportTo(571, 5349.8686f, 2838.481f, 409.240f, 0.046328f);
|
|
SendInitWorldStatesTo(player);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Initialize vehicle counter
|
|
UpdateCounterVehicle(true);
|
|
// Send start warning to all players
|
|
SendWarning(BATTLEFIELD_WG_TEXT_START_BATTLE);
|
|
}
|
|
|
|
void BattlefieldWG::UpdateCounterVehicle(bool init)
|
|
{
|
|
if (init)
|
|
{
|
|
SetData(BATTLEFIELD_WG_DATA_VEHICLE_H, 0);
|
|
SetData(BATTLEFIELD_WG_DATA_VEHICLE_A, 0);
|
|
}
|
|
SetData(BATTLEFIELD_WG_DATA_MAX_VEHICLE_H, 0);
|
|
SetData(BATTLEFIELD_WG_DATA_MAX_VEHICLE_A, 0);
|
|
|
|
for (WintergraspWorkshop* workshop : Workshops)
|
|
{
|
|
if (workshop->GetTeamControl() == TEAM_ALLIANCE)
|
|
UpdateData(BATTLEFIELD_WG_DATA_MAX_VEHICLE_A, 4);
|
|
else if (workshop->GetTeamControl() == TEAM_HORDE)
|
|
UpdateData(BATTLEFIELD_WG_DATA_MAX_VEHICLE_H, 4);
|
|
}
|
|
|
|
UpdateVehicleCountWG();
|
|
}
|
|
|
|
void BattlefieldWG::OnBattleEnd(bool endByTimer)
|
|
{
|
|
// Remove relic
|
|
if (!m_titansRelicGUID.IsEmpty())
|
|
if (GameObject* relic = GetGameObject(m_titansRelicGUID))
|
|
relic->RemoveFromWorld();
|
|
m_titansRelicGUID.Clear();
|
|
|
|
// change collision wall state closed
|
|
for (BfWGGameObjectBuilding* building : BuildingsInZone)
|
|
{
|
|
building->RebuildGate();
|
|
}
|
|
|
|
// successful defense
|
|
if (endByTimer)
|
|
UpdateData(GetDefenderTeam() == TEAM_HORDE ? BATTLEFIELD_WG_DATA_DEF_H : BATTLEFIELD_WG_DATA_DEF_A, 1);
|
|
// successful attack (note that teams have already been swapped, so defender team is the one who won)
|
|
else
|
|
UpdateData(GetDefenderTeam() == TEAM_HORDE ? BATTLEFIELD_WG_DATA_WON_H : BATTLEFIELD_WG_DATA_WON_A, 1);
|
|
|
|
// Remove turret
|
|
for (auto itr = CanonList.begin(); itr != CanonList.end(); ++itr)
|
|
{
|
|
if (Creature* creature = GetCreature(*itr))
|
|
{
|
|
if (!endByTimer)
|
|
creature->SetFaction(WintergraspFaction[GetDefenderTeam()]);
|
|
HideNpc(creature);
|
|
}
|
|
}
|
|
|
|
// Update all graveyard, control is to defender when no wartime
|
|
for (uint8 i = 0; i < BATTLEFIELD_WG_GY_HORDE; i++)
|
|
if (BfGraveyard* graveyard = GetGraveyardById(i))
|
|
graveyard->GiveControlTo(GetDefenderTeam());
|
|
|
|
// Update portals
|
|
for (auto itr = DefenderPortalList[GetDefenderTeam()].begin(); itr != DefenderPortalList[GetDefenderTeam()].end(); ++itr)
|
|
if (GameObject* portal = GetGameObject(*itr))
|
|
portal->SetRespawnTime(RESPAWN_IMMEDIATELY);
|
|
|
|
for (auto itr = DefenderPortalList[GetAttackerTeam()].begin(); itr != DefenderPortalList[GetAttackerTeam()].end(); ++itr)
|
|
if (GameObject* portal = GetGameObject(*itr))
|
|
portal->SetRespawnTime(RESPAWN_ONE_DAY);
|
|
|
|
// Saving data
|
|
for (BfWGGameObjectBuilding* building : BuildingsInZone)
|
|
building->Save();
|
|
|
|
for (WintergraspWorkshop* workshop : Workshops)
|
|
workshop->Save();
|
|
|
|
for (auto itr = m_PlayersInWar[GetDefenderTeam()].begin(); itr != m_PlayersInWar[GetDefenderTeam()].end(); ++itr)
|
|
{
|
|
if (Player* player = ObjectAccessor::FindPlayer(*itr))
|
|
{
|
|
player->CastSpell(player, SPELL_ESSENCE_OF_WINTERGRASP, true);
|
|
player->CastSpell(player, SPELL_VICTORY_REWARD, true);
|
|
// Complete victory quests
|
|
player->AreaExploredOrEventHappens(QUEST_VICTORY_WINTERGRASP_A);
|
|
player->AreaExploredOrEventHappens(QUEST_VICTORY_WINTERGRASP_H);
|
|
// Send Wintergrasp victory achievement
|
|
DoCompleteOrIncrementAchievement(ACHIEVEMENTS_WIN_WG, player);
|
|
// Award achievement for succeeding in Wintergrasp in 10 minutes or less
|
|
if (!endByTimer && GetTimer() <= 10000)
|
|
DoCompleteOrIncrementAchievement(ACHIEVEMENTS_WIN_WG_TIMER_10, player);
|
|
}
|
|
}
|
|
|
|
for (auto itr = m_PlayersInWar[GetAttackerTeam()].begin(); itr != m_PlayersInWar[GetAttackerTeam()].end(); ++itr)
|
|
if (Player* player = ObjectAccessor::FindPlayer(*itr))
|
|
player->CastSpell(player, SPELL_DEFEAT_REWARD, true);
|
|
|
|
for (uint8 team = 0; team < PVP_TEAMS_COUNT; ++team)
|
|
{
|
|
for (auto itr = m_PlayersInWar[team].begin(); itr != m_PlayersInWar[team].end(); ++itr)
|
|
if (Player* player = ObjectAccessor::FindPlayer(*itr))
|
|
RemoveAurasFromPlayer(player);
|
|
|
|
m_PlayersInWar[team].clear();
|
|
|
|
for (auto itr = m_vehicles[team].begin(); itr != m_vehicles[team].end(); ++itr)
|
|
if (Creature* creature = GetCreature(*itr))
|
|
if (creature->IsVehicle())
|
|
creature->DespawnOrUnsummon();
|
|
|
|
m_vehicles[team].clear();
|
|
}
|
|
|
|
if (!endByTimer)
|
|
{
|
|
for (uint8 team = 0; team < PVP_TEAMS_COUNT; ++team)
|
|
{
|
|
for (auto itr = m_players[team].begin(); itr != m_players[team].end(); ++itr)
|
|
{
|
|
if (Player* player = ObjectAccessor::FindPlayer(*itr))
|
|
{
|
|
player->RemoveAurasDueToSpell(m_DefenderTeam == TEAM_ALLIANCE ? SPELL_HORDE_CONTROL_PHASE_SHIFT : SPELL_ALLIANCE_CONTROL_PHASE_SHIFT, player->GetGUID());
|
|
player->AddAura(m_DefenderTeam == TEAM_HORDE ? SPELL_HORDE_CONTROL_PHASE_SHIFT : SPELL_ALLIANCE_CONTROL_PHASE_SHIFT, player);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!endByTimer) // win alli/horde
|
|
SendWarning(GetDefenderTeam() == TEAM_ALLIANCE ? BATTLEFIELD_WG_TEXT_FORTRESS_CAPTURE_ALLIANCE : BATTLEFIELD_WG_TEXT_FORTRESS_CAPTURE_HORDE);
|
|
else // defend alli/horde
|
|
SendWarning(GetDefenderTeam() == TEAM_ALLIANCE ? BATTLEFIELD_WG_TEXT_FORTRESS_DEFEND_ALLIANCE : BATTLEFIELD_WG_TEXT_FORTRESS_DEFEND_HORDE);
|
|
}
|
|
|
|
// *******************************************************
|
|
// ******************* Reward System *********************
|
|
// *******************************************************
|
|
void BattlefieldWG::DoCompleteOrIncrementAchievement(uint32 achievement, Player* player, uint8 /*incrementNumber*/)
|
|
{
|
|
AchievementEntry const* achievementEntry = sAchievementStore.LookupEntry(achievement);
|
|
|
|
if (!achievementEntry)
|
|
return;
|
|
|
|
switch (achievement)
|
|
{
|
|
case ACHIEVEMENTS_WIN_WG_100:
|
|
{
|
|
// player->UpdateCriteria();
|
|
}
|
|
default:
|
|
{
|
|
if (player)
|
|
player->CompletedAchievement(achievementEntry);
|
|
break;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
void BattlefieldWG::OnStartGrouping()
|
|
{
|
|
SendWarning(BATTLEFIELD_WG_TEXT_START_GROUPING);
|
|
}
|
|
|
|
uint8 BattlefieldWG::GetSpiritGraveyardId(uint32 areaId) const
|
|
{
|
|
switch (areaId)
|
|
{
|
|
case AREA_WINTERGRASP_FORTRESS:
|
|
return BATTLEFIELD_WG_GY_KEEP;
|
|
case AREA_THE_SUNKEN_RING:
|
|
return BATTLEFIELD_WG_GY_WORKSHOP_NE;
|
|
case AREA_THE_BROKEN_TEMPLATE:
|
|
return BATTLEFIELD_WG_GY_WORKSHOP_NW;
|
|
case AREA_WESTPARK_WORKSHOP:
|
|
return BATTLEFIELD_WG_GY_WORKSHOP_SW;
|
|
case AREA_EASTPARK_WORKSHOP:
|
|
return BATTLEFIELD_WG_GY_WORKSHOP_SE;
|
|
case AREA_WINTERGRASP:
|
|
return BATTLEFIELD_WG_GY_ALLIANCE;
|
|
case AREA_THE_CHILLED_QUAGMIRE:
|
|
return BATTLEFIELD_WG_GY_HORDE;
|
|
default:
|
|
TC_LOG_ERROR("bg.battlefield", "BattlefieldWG::GetSpiritGraveyardId: Unexpected Area Id %u", areaId);
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void BattlefieldWG::OnCreatureCreate(Creature* creature)
|
|
{
|
|
// Accessing to db spawned creatures
|
|
switch (creature->GetEntry())
|
|
{
|
|
case NPC_DWARVEN_SPIRIT_GUIDE:
|
|
case NPC_TAUNKA_SPIRIT_GUIDE:
|
|
{
|
|
TeamId teamId = (creature->GetEntry() == NPC_DWARVEN_SPIRIT_GUIDE ? TEAM_ALLIANCE : TEAM_HORDE);
|
|
uint8 graveyardId = GetSpiritGraveyardId(creature->GetAreaId());
|
|
if (m_GraveyardList[graveyardId])
|
|
m_GraveyardList[graveyardId]->SetSpirit(creature, teamId);
|
|
break;
|
|
}
|
|
}
|
|
|
|
// untested code - not sure if it is valid.
|
|
if (IsWarTime())
|
|
{
|
|
switch (creature->GetEntry())
|
|
{
|
|
case NPC_WINTERGRASP_SIEGE_ENGINE_ALLIANCE:
|
|
case NPC_WINTERGRASP_SIEGE_ENGINE_HORDE:
|
|
case NPC_WINTERGRASP_CATAPULT:
|
|
case NPC_WINTERGRASP_DEMOLISHER:
|
|
{
|
|
if (!creature->ToTempSummon() || !creature->ToTempSummon()->GetSummonerGUID() || !ObjectAccessor::FindPlayer(creature->ToTempSummon()->GetSummonerGUID()))
|
|
{
|
|
creature->DespawnOrUnsummon();
|
|
return;
|
|
}
|
|
|
|
Player* creator = ObjectAccessor::FindPlayer(creature->ToTempSummon()->GetSummonerGUID());
|
|
TeamId team = creator->GetTeamId();
|
|
|
|
if (team == TEAM_HORDE)
|
|
{
|
|
if (GetData(BATTLEFIELD_WG_DATA_VEHICLE_H) < GetData(BATTLEFIELD_WG_DATA_MAX_VEHICLE_H))
|
|
{
|
|
UpdateData(BATTLEFIELD_WG_DATA_VEHICLE_H, 1);
|
|
creature->AddAura(SPELL_HORDE_FLAG, creature);
|
|
m_vehicles[team].insert(creature->GetGUID());
|
|
UpdateVehicleCountWG();
|
|
}
|
|
else
|
|
{
|
|
creature->DespawnOrUnsummon();
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (GetData(BATTLEFIELD_WG_DATA_VEHICLE_A) < GetData(BATTLEFIELD_WG_DATA_MAX_VEHICLE_A))
|
|
{
|
|
UpdateData(BATTLEFIELD_WG_DATA_VEHICLE_A, 1);
|
|
creature->AddAura(SPELL_ALLIANCE_FLAG, creature);
|
|
m_vehicles[team].insert(creature->GetGUID());
|
|
UpdateVehicleCountWG();
|
|
}
|
|
else
|
|
{
|
|
creature->DespawnOrUnsummon();
|
|
return;
|
|
}
|
|
}
|
|
|
|
creature->CastSpell(creator, SPELL_GRAB_PASSENGER, true);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void BattlefieldWG::OnCreatureRemove(Creature* /*creature*/)
|
|
{
|
|
/* possibly can be used later
|
|
if (IsWarTime())
|
|
{
|
|
switch (creature->GetEntry())
|
|
{
|
|
case NPC_WINTERGRASP_SIEGE_ENGINE_ALLIANCE:
|
|
case NPC_WINTERGRASP_SIEGE_ENGINE_HORDE:
|
|
case NPC_WINTERGRASP_CATAPULT:
|
|
case NPC_WINTERGRASP_DEMOLISHER:
|
|
{
|
|
uint8 team;
|
|
if (creature->GetFaction() == WintergraspFaction[TEAM_ALLIANCE])
|
|
team = TEAM_ALLIANCE;
|
|
else if (creature->GetFaction() == WintergraspFaction[TEAM_HORDE])
|
|
team = TEAM_HORDE;
|
|
else
|
|
return;
|
|
|
|
m_vehicles[team].erase(creature->GetGUID());
|
|
if (team == TEAM_HORDE)
|
|
UpdateData(BATTLEFIELD_WG_DATA_VEHICLE_H, -1);
|
|
else
|
|
UpdateData(BATTLEFIELD_WG_DATA_VEHICLE_A, -1);
|
|
UpdateVehicleCountWG();
|
|
|
|
break;
|
|
}
|
|
}
|
|
}*/
|
|
}
|
|
|
|
void BattlefieldWG::OnGameObjectCreate(GameObject* go)
|
|
{
|
|
uint8 workshopId = 0;
|
|
|
|
switch (go->GetEntry())
|
|
{
|
|
case GO_WINTERGRASP_FACTORY_BANNER_NE:
|
|
workshopId = BATTLEFIELD_WG_WORKSHOP_NE;
|
|
break;
|
|
case GO_WINTERGRASP_FACTORY_BANNER_NW:
|
|
workshopId = BATTLEFIELD_WG_WORKSHOP_NW;
|
|
break;
|
|
case GO_WINTERGRASP_FACTORY_BANNER_SE:
|
|
workshopId = BATTLEFIELD_WG_WORKSHOP_SE;
|
|
break;
|
|
case GO_WINTERGRASP_FACTORY_BANNER_SW:
|
|
workshopId = BATTLEFIELD_WG_WORKSHOP_SW;
|
|
break;
|
|
default:
|
|
return;
|
|
}
|
|
|
|
for (WintergraspWorkshop* workshop : Workshops)
|
|
{
|
|
if (workshop->GetId() == workshopId)
|
|
{
|
|
WintergraspCapturePoint* capturePoint = new WintergraspCapturePoint(this, GetAttackerTeam());
|
|
|
|
capturePoint->SetCapturePointData(go);
|
|
capturePoint->LinkToWorkshop(workshop);
|
|
AddCapturePoint(capturePoint);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Called when player kill a unit in wg zone
|
|
void BattlefieldWG::HandleKill(Player* killer, Unit* victim)
|
|
{
|
|
if (killer == victim)
|
|
return;
|
|
|
|
if (victim->GetTypeId() == TYPEID_PLAYER)
|
|
{
|
|
HandlePromotion(killer, victim);
|
|
|
|
// Allow to Skin non-released corpse
|
|
victim->AddUnitFlag(UNIT_FLAG_SKINNABLE);
|
|
}
|
|
|
|
/// @todoRecent PvP activity worldstate
|
|
}
|
|
|
|
bool BattlefieldWG::FindAndRemoveVehicleFromList(Unit* vehicle)
|
|
{
|
|
for (uint32 team = 0; team < PVP_TEAMS_COUNT; ++team)
|
|
{
|
|
auto itr = m_vehicles[team].find(vehicle->GetGUID());
|
|
if (itr != m_vehicles[team].end())
|
|
{
|
|
m_vehicles[team].erase(itr);
|
|
|
|
if (team == TEAM_HORDE)
|
|
UpdateData(BATTLEFIELD_WG_DATA_VEHICLE_H, -1);
|
|
else
|
|
UpdateData(BATTLEFIELD_WG_DATA_VEHICLE_A, -1);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void BattlefieldWG::OnUnitDeath(Unit* unit)
|
|
{
|
|
if (IsWarTime())
|
|
if (unit->IsVehicle())
|
|
if (FindAndRemoveVehicleFromList(unit))
|
|
UpdateVehicleCountWG();
|
|
}
|
|
|
|
void BattlefieldWG::HandlePromotion(Player* playerKiller, Unit* unitKilled)
|
|
{
|
|
uint32 teamId = playerKiller->GetTeamId();
|
|
|
|
for (auto iter = m_PlayersInWar[teamId].begin(); iter != m_PlayersInWar[teamId].end(); ++iter)
|
|
if (Player* player = ObjectAccessor::FindPlayer(*iter))
|
|
if (player->GetDistance2d(unitKilled) < 40.0f)
|
|
PromotePlayer(player);
|
|
}
|
|
|
|
// Update rank for player
|
|
void BattlefieldWG::PromotePlayer(Player* killer)
|
|
{
|
|
if (!m_isActive)
|
|
return;
|
|
// Updating rank of player
|
|
if (Aura* auraRecruit = killer->GetAura(SPELL_RECRUIT))
|
|
{
|
|
if (auraRecruit->GetStackAmount() >= 5)
|
|
{
|
|
killer->RemoveAura(SPELL_RECRUIT);
|
|
killer->CastSpell(killer, SPELL_CORPORAL, true);
|
|
if (Creature* stalker = GetCreature(StalkerGuid))
|
|
sCreatureTextMgr->SendChat(stalker, BATTLEFIELD_WG_TEXT_RANK_CORPORAL, killer, CHAT_MSG_ADDON, LANG_ADDON, TEXT_RANGE_NORMAL, 0, SoundKitPlayType::Normal, TEAM_OTHER, false, killer);
|
|
}
|
|
else
|
|
killer->CastSpell(killer, SPELL_RECRUIT, true);
|
|
}
|
|
else if (Aura* auraCorporal = killer->GetAura(SPELL_CORPORAL))
|
|
{
|
|
if (auraCorporal->GetStackAmount() >= 5)
|
|
{
|
|
killer->RemoveAura(SPELL_CORPORAL);
|
|
killer->CastSpell(killer, SPELL_LIEUTENANT, true);
|
|
if (Creature* stalker = GetCreature(StalkerGuid))
|
|
sCreatureTextMgr->SendChat(stalker, BATTLEFIELD_WG_TEXT_RANK_FIRST_LIEUTENANT, killer, CHAT_MSG_ADDON, LANG_ADDON, TEXT_RANGE_NORMAL, 0, SoundKitPlayType::Normal, TEAM_OTHER, false, killer);
|
|
}
|
|
else
|
|
killer->CastSpell(killer, SPELL_CORPORAL, true);
|
|
}
|
|
}
|
|
|
|
void BattlefieldWG::RemoveAurasFromPlayer(Player* player)
|
|
{
|
|
player->RemoveAurasDueToSpell(SPELL_RECRUIT);
|
|
player->RemoveAurasDueToSpell(SPELL_CORPORAL);
|
|
player->RemoveAurasDueToSpell(SPELL_LIEUTENANT);
|
|
player->RemoveAurasDueToSpell(SPELL_TOWER_CONTROL);
|
|
player->RemoveAurasDueToSpell(SPELL_SPIRITUAL_IMMUNITY);
|
|
player->RemoveAurasDueToSpell(SPELL_TENACITY);
|
|
player->RemoveAurasDueToSpell(SPELL_ESSENCE_OF_WINTERGRASP);
|
|
player->RemoveAurasDueToSpell(SPELL_WINTERGRASP_RESTRICTED_FLIGHT_AREA);
|
|
}
|
|
|
|
void BattlefieldWG::OnPlayerJoinWar(Player* player)
|
|
{
|
|
RemoveAurasFromPlayer(player);
|
|
|
|
player->CastSpell(player, SPELL_RECRUIT, true);
|
|
|
|
if (player->GetZoneId() != m_ZoneId)
|
|
{
|
|
if (player->GetTeamId() == GetDefenderTeam())
|
|
player->TeleportTo(571, 5345, 2842, 410, 3.14f);
|
|
else
|
|
{
|
|
if (player->GetTeamId() == TEAM_HORDE)
|
|
player->TeleportTo(571, 5025.857422f, 3674.628906f, 362.737122f, 4.135169f);
|
|
else
|
|
player->TeleportTo(571, 5101.284f, 2186.564f, 373.549f, 3.812f);
|
|
}
|
|
}
|
|
|
|
UpdateTenacity();
|
|
|
|
if (player->GetTeamId() == GetAttackerTeam())
|
|
{
|
|
if (GetData(BATTLEFIELD_WG_DATA_BROKEN_TOWER_ATT) < 3)
|
|
player->SetAuraStack(SPELL_TOWER_CONTROL, player, 3 - GetData(BATTLEFIELD_WG_DATA_BROKEN_TOWER_ATT));
|
|
}
|
|
else
|
|
{
|
|
if (GetData(BATTLEFIELD_WG_DATA_BROKEN_TOWER_ATT) > 0)
|
|
player->SetAuraStack(SPELL_TOWER_CONTROL, player, GetData(BATTLEFIELD_WG_DATA_BROKEN_TOWER_ATT));
|
|
}
|
|
SendInitWorldStatesTo(player);
|
|
}
|
|
|
|
void BattlefieldWG::OnPlayerLeaveWar(Player* player)
|
|
{
|
|
// Remove all aura from WG /// @todo false we can go out of this zone on retail and keep Rank buff, remove on end of WG
|
|
if (!player->GetSession()->PlayerLogout())
|
|
{
|
|
if (Creature* vehicle = player->GetVehicleCreatureBase()) // Remove vehicle of player if he go out.
|
|
vehicle->DespawnOrUnsummon();
|
|
|
|
RemoveAurasFromPlayer(player);
|
|
}
|
|
|
|
player->RemoveAurasDueToSpell(SPELL_HORDE_CONTROLS_FACTORY_PHASE_SHIFT);
|
|
player->RemoveAurasDueToSpell(SPELL_ALLIANCE_CONTROLS_FACTORY_PHASE_SHIFT);
|
|
player->RemoveAurasDueToSpell(SPELL_HORDE_CONTROL_PHASE_SHIFT);
|
|
player->RemoveAurasDueToSpell(SPELL_ALLIANCE_CONTROL_PHASE_SHIFT);
|
|
UpdateTenacity();
|
|
}
|
|
|
|
void BattlefieldWG::OnPlayerLeaveZone(Player* player)
|
|
{
|
|
if (!m_isActive)
|
|
RemoveAurasFromPlayer(player);
|
|
|
|
player->RemoveAurasDueToSpell(SPELL_HORDE_CONTROLS_FACTORY_PHASE_SHIFT);
|
|
player->RemoveAurasDueToSpell(SPELL_ALLIANCE_CONTROLS_FACTORY_PHASE_SHIFT);
|
|
player->RemoveAurasDueToSpell(SPELL_HORDE_CONTROL_PHASE_SHIFT);
|
|
player->RemoveAurasDueToSpell(SPELL_ALLIANCE_CONTROL_PHASE_SHIFT);
|
|
}
|
|
|
|
void BattlefieldWG::OnPlayerEnterZone(Player* player)
|
|
{
|
|
if (!m_isActive)
|
|
RemoveAurasFromPlayer(player);
|
|
|
|
player->AddAura(m_DefenderTeam == TEAM_HORDE ? SPELL_HORDE_CONTROL_PHASE_SHIFT : SPELL_ALLIANCE_CONTROL_PHASE_SHIFT, player);
|
|
// Send worldstate to player
|
|
SendInitWorldStatesTo(player);
|
|
}
|
|
|
|
uint32 BattlefieldWG::GetData(uint32 data) const
|
|
{
|
|
switch (data)
|
|
{
|
|
// Used to determine when the phasing spells must be cast
|
|
// See: SpellArea::IsFitToRequirements
|
|
case AREA_THE_SUNKEN_RING:
|
|
case AREA_THE_BROKEN_TEMPLATE:
|
|
case AREA_WESTPARK_WORKSHOP:
|
|
case AREA_EASTPARK_WORKSHOP:
|
|
// Graveyards and Workshops are controlled by the same team.
|
|
if (BfGraveyard const* graveyard = GetGraveyardById(GetSpiritGraveyardId(data)))
|
|
return graveyard->GetControlTeamId();
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return Battlefield::GetData(data);
|
|
}
|
|
|
|
|
|
void BattlefieldWG::FillInitialWorldStates(WorldPackets::WorldState::InitWorldStates& packet)
|
|
{
|
|
packet.Worldstates.emplace_back(WS_BATTLEFIELD_WG_DEFENDED_A, GetData(BATTLEFIELD_WG_DATA_DEF_A));
|
|
packet.Worldstates.emplace_back(WS_BATTLEFIELD_WG_DEFENDED_H, GetData(BATTLEFIELD_WG_DATA_DEF_H));
|
|
packet.Worldstates.emplace_back(WS_BATTLEFIELD_WG_ATTACKED_A, GetData(BATTLEFIELD_WG_DATA_WON_A));
|
|
packet.Worldstates.emplace_back(WS_BATTLEFIELD_WG_ATTACKED_H, GetData(BATTLEFIELD_WG_DATA_WON_H));
|
|
packet.Worldstates.emplace_back(WS_BATTLEFIELD_WG_ATTACKER, GetAttackerTeam());
|
|
packet.Worldstates.emplace_back(WS_BATTLEFIELD_WG_DEFENDER, GetDefenderTeam());
|
|
|
|
// Note: cleanup these two, their names look awkward
|
|
packet.Worldstates.emplace_back(WS_BATTLEFIELD_WG_ACTIVE, IsWarTime() ? 0 : 1);
|
|
packet.Worldstates.emplace_back(WS_BATTLEFIELD_WG_SHOW_WORLDSTATE, IsWarTime() ? 1 : 0);
|
|
|
|
for (uint32 itr = 0; itr < 2; ++itr)
|
|
packet.Worldstates.emplace_back(ClockWorldState[itr], int32(GameTime::GetGameTime()) + int32(m_Timer) / int32(1000));
|
|
|
|
packet.Worldstates.emplace_back(WS_BATTLEFIELD_WG_VEHICLE_H, GetData(BATTLEFIELD_WG_DATA_VEHICLE_H));
|
|
packet.Worldstates.emplace_back(WS_BATTLEFIELD_WG_MAX_VEHICLE_H, GetData(BATTLEFIELD_WG_DATA_MAX_VEHICLE_H));
|
|
packet.Worldstates.emplace_back(WS_BATTLEFIELD_WG_VEHICLE_A, GetData(BATTLEFIELD_WG_DATA_VEHICLE_A));
|
|
packet.Worldstates.emplace_back(WS_BATTLEFIELD_WG_MAX_VEHICLE_A, GetData(BATTLEFIELD_WG_DATA_MAX_VEHICLE_A));
|
|
|
|
for (BfWGGameObjectBuilding* building : BuildingsInZone)
|
|
building->FillInitialWorldStates(packet);
|
|
|
|
for (WintergraspWorkshop* workshop : Workshops)
|
|
workshop->FillInitialWorldStates(packet);
|
|
}
|
|
|
|
void BattlefieldWG::SendInitWorldStatesTo(Player* player)
|
|
{
|
|
WorldPackets::WorldState::InitWorldStates packet;
|
|
packet.MapID = m_MapId;
|
|
packet.AreaID = m_ZoneId;
|
|
packet.SubareaID = player->GetAreaId();
|
|
FillInitialWorldStates(packet);
|
|
|
|
player->SendDirectMessage(packet.Write());
|
|
}
|
|
|
|
void BattlefieldWG::SendInitWorldStatesToAll()
|
|
{
|
|
for (uint8 team = 0; team < PVP_TEAMS_COUNT; ++team)
|
|
for (auto itr = m_players[team].begin(); itr != m_players[team].end(); ++itr)
|
|
if (Player* player = ObjectAccessor::FindPlayer(*itr))
|
|
SendInitWorldStatesTo(player);
|
|
}
|
|
|
|
void BattlefieldWG::BrokenWallOrTower(TeamId team, BfWGGameObjectBuilding* building)
|
|
{
|
|
if (team == GetDefenderTeam())
|
|
{
|
|
for (auto itr = m_PlayersInWar[GetAttackerTeam()].begin(); itr != m_PlayersInWar[GetAttackerTeam()].end(); ++itr)
|
|
{
|
|
if (Player* player = ObjectAccessor::FindPlayer(*itr))
|
|
if (player->GetDistance2d(ASSERT_NOTNULL(GetGameObject(building->GetGUID()))) < 50.0f)
|
|
player->KilledMonsterCredit(QUEST_CREDIT_DEFEND_SIEGE);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Called when a tower is broke
|
|
void BattlefieldWG::UpdatedDestroyedTowerCount(TeamId team)
|
|
{
|
|
// Southern tower
|
|
if (team == GetAttackerTeam())
|
|
{
|
|
// Update counter
|
|
UpdateData(BATTLEFIELD_WG_DATA_DAMAGED_TOWER_ATT, -1);
|
|
UpdateData(BATTLEFIELD_WG_DATA_BROKEN_TOWER_ATT, 1);
|
|
|
|
// Remove buff stack on attackers
|
|
for (auto itr = m_PlayersInWar[GetAttackerTeam()].begin(); itr != m_PlayersInWar[GetAttackerTeam()].end(); ++itr)
|
|
if (Player* player = ObjectAccessor::FindPlayer(*itr))
|
|
player->RemoveAuraFromStack(SPELL_TOWER_CONTROL);
|
|
|
|
// Add buff stack to defenders and give achievement/quest credit
|
|
for (auto itr = m_PlayersInWar[GetDefenderTeam()].begin(); itr != m_PlayersInWar[GetDefenderTeam()].end(); ++itr)
|
|
{
|
|
if (Player* player = ObjectAccessor::FindPlayer(*itr))
|
|
{
|
|
player->CastSpell(player, SPELL_TOWER_CONTROL, true);
|
|
player->KilledMonsterCredit(QUEST_CREDIT_TOWERS_DESTROYED);
|
|
DoCompleteOrIncrementAchievement(ACHIEVEMENTS_WG_TOWER_DESTROY, player);
|
|
}
|
|
}
|
|
|
|
// If all three south towers are destroyed (ie. all attack towers), remove ten minutes from battle time
|
|
if (GetData(BATTLEFIELD_WG_DATA_BROKEN_TOWER_ATT) == 3)
|
|
{
|
|
if (int32(m_Timer - 600000) < 0)
|
|
m_Timer = 0;
|
|
else
|
|
m_Timer -= 600000;
|
|
SendInitWorldStatesToAll();
|
|
}
|
|
}
|
|
else // Keep tower
|
|
{
|
|
UpdateData(BATTLEFIELD_WG_DATA_DAMAGED_TOWER_DEF, -1);
|
|
UpdateData(BATTLEFIELD_WG_DATA_BROKEN_TOWER_DEF, 1);
|
|
}
|
|
}
|
|
|
|
void BattlefieldWG::ProcessEvent(WorldObject* obj, uint32 eventId, WorldObject* /*invoker*/)
|
|
{
|
|
if (!obj || !IsWarTime())
|
|
return;
|
|
|
|
// We handle only gameobjects here
|
|
GameObject* go = obj->ToGameObject();
|
|
if (!go)
|
|
return;
|
|
|
|
// On click on titan relic
|
|
if (go->GetEntry() == GO_WINTERGRASP_TITAN_S_RELIC)
|
|
{
|
|
if (CanInteractWithRelic())
|
|
EndBattle(false);
|
|
else if (GameObject* relic = GetRelic())
|
|
relic->SetRespawnTime(RESPAWN_IMMEDIATELY);
|
|
}
|
|
|
|
// if destroy or damage event, search the wall/tower and update worldstate/send warning message
|
|
for (BfWGGameObjectBuilding* building : BuildingsInZone)
|
|
{
|
|
if (go->GetGUID() == building->GetGUID())
|
|
{
|
|
if (GameObject* buildingGo = GetGameObject(building->GetGUID()))
|
|
{
|
|
if (buildingGo->GetGOInfo()->destructibleBuilding.DamagedEvent == eventId)
|
|
building->Damaged();
|
|
else if (buildingGo->GetGOInfo()->destructibleBuilding.DestroyedEvent == eventId)
|
|
building->Destroyed();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Called when a tower is damaged, used for honor reward calcul
|
|
void BattlefieldWG::UpdateDamagedTowerCount(TeamId team)
|
|
{
|
|
if (team == GetAttackerTeam())
|
|
UpdateData(BATTLEFIELD_WG_DATA_DAMAGED_TOWER_ATT, 1);
|
|
else
|
|
UpdateData(BATTLEFIELD_WG_DATA_DAMAGED_TOWER_DEF, 1);
|
|
}
|
|
|
|
// Update vehicle count WorldState to player
|
|
void BattlefieldWG::UpdateVehicleCountWG()
|
|
{
|
|
SendUpdateWorldState(WS_BATTLEFIELD_WG_VEHICLE_H, GetData(BATTLEFIELD_WG_DATA_VEHICLE_H));
|
|
SendUpdateWorldState(WS_BATTLEFIELD_WG_MAX_VEHICLE_H, GetData(BATTLEFIELD_WG_DATA_MAX_VEHICLE_H));
|
|
SendUpdateWorldState(WS_BATTLEFIELD_WG_VEHICLE_A, GetData(BATTLEFIELD_WG_DATA_VEHICLE_A));
|
|
SendUpdateWorldState(WS_BATTLEFIELD_WG_MAX_VEHICLE_A, GetData(BATTLEFIELD_WG_DATA_MAX_VEHICLE_A));
|
|
}
|
|
|
|
void BattlefieldWG::UpdateTenacity()
|
|
{
|
|
uint32 alliancePlayers = m_PlayersInWar[TEAM_ALLIANCE].size();
|
|
uint32 hordePlayers = m_PlayersInWar[TEAM_HORDE].size();
|
|
int32 newStack = 0;
|
|
|
|
if (alliancePlayers && hordePlayers)
|
|
{
|
|
if (alliancePlayers < hordePlayers)
|
|
newStack = int32((float(hordePlayers / alliancePlayers) - 1) * 4); // positive, should cast on alliance
|
|
else if (alliancePlayers > hordePlayers)
|
|
newStack = int32((1 - float(alliancePlayers / hordePlayers)) * 4); // negative, should cast on horde
|
|
}
|
|
|
|
if (newStack == int32(m_tenacityStack))
|
|
return;
|
|
|
|
m_tenacityStack = newStack;
|
|
// Remove old buff
|
|
if (m_tenacityTeam != TEAM_NEUTRAL)
|
|
{
|
|
for (auto itr = m_players[m_tenacityTeam].begin(); itr != m_players[m_tenacityTeam].end(); ++itr)
|
|
if (Player* player = ObjectAccessor::FindPlayer(*itr))
|
|
if (player->GetLevel() >= m_MinLevel)
|
|
player->RemoveAurasDueToSpell(SPELL_TENACITY);
|
|
|
|
for (auto itr = m_vehicles[m_tenacityTeam].begin(); itr != m_vehicles[m_tenacityTeam].end(); ++itr)
|
|
if (Creature* creature = GetCreature(*itr))
|
|
creature->RemoveAurasDueToSpell(SPELL_TENACITY_VEHICLE);
|
|
}
|
|
|
|
// Apply new buff
|
|
if (newStack)
|
|
{
|
|
m_tenacityTeam = newStack > 0 ? TEAM_ALLIANCE : TEAM_HORDE;
|
|
|
|
if (newStack < 0)
|
|
newStack = -newStack;
|
|
if (newStack > 20)
|
|
newStack = 20;
|
|
|
|
uint32 buff_honor = SPELL_GREATEST_HONOR;
|
|
if (newStack < 15)
|
|
buff_honor = SPELL_GREATER_HONOR;
|
|
if (newStack < 10)
|
|
buff_honor = SPELL_GREAT_HONOR;
|
|
if (newStack < 5)
|
|
buff_honor = 0;
|
|
|
|
for (auto itr = m_PlayersInWar[m_tenacityTeam].begin(); itr != m_PlayersInWar[m_tenacityTeam].end(); ++itr)
|
|
if (Player* player = ObjectAccessor::FindPlayer(*itr))
|
|
player->SetAuraStack(SPELL_TENACITY, player, newStack);
|
|
|
|
for (auto itr = m_vehicles[m_tenacityTeam].begin(); itr != m_vehicles[m_tenacityTeam].end(); ++itr)
|
|
if (Creature* creature = GetCreature(*itr))
|
|
creature->SetAuraStack(SPELL_TENACITY_VEHICLE, creature, newStack);
|
|
|
|
if (buff_honor != 0)
|
|
{
|
|
for (auto itr = m_PlayersInWar[m_tenacityTeam].begin(); itr != m_PlayersInWar[m_tenacityTeam].end(); ++itr)
|
|
if (Player* player = ObjectAccessor::FindPlayer(*itr))
|
|
player->CastSpell(player, buff_honor, true);
|
|
|
|
for (auto itr = m_vehicles[m_tenacityTeam].begin(); itr != m_vehicles[m_tenacityTeam].end(); ++itr)
|
|
if (Creature* creature = GetCreature(*itr))
|
|
creature->CastSpell(creature, buff_honor, true);
|
|
}
|
|
}
|
|
else
|
|
m_tenacityTeam = TEAM_NEUTRAL;
|
|
}
|
|
|
|
WintergraspCapturePoint::WintergraspCapturePoint(BattlefieldWG* battlefield, TeamId teamInControl) : BfCapturePoint(battlefield)
|
|
{
|
|
m_Bf = battlefield;
|
|
m_team = teamInControl;
|
|
m_Workshop = nullptr;
|
|
}
|
|
|
|
void WintergraspCapturePoint::ChangeTeam(TeamId /*oldTeam*/)
|
|
{
|
|
ASSERT(m_Workshop);
|
|
m_Workshop->GiveControlTo(m_team);
|
|
}
|
|
|
|
BfGraveyardWG::BfGraveyardWG(BattlefieldWG* battlefield) : BfGraveyard(battlefield)
|
|
{
|
|
m_Bf = battlefield;
|
|
m_GossipTextId = 0;
|
|
}
|
|
|
|
BfWGGameObjectBuilding::BfWGGameObjectBuilding(BattlefieldWG* wg, WintergraspGameObjectBuildingType type, uint32 worldState)
|
|
{
|
|
ASSERT(wg);
|
|
|
|
_wg = wg;
|
|
_teamControl = TEAM_NEUTRAL;
|
|
_type = type;
|
|
_worldState = worldState;
|
|
_state = BATTLEFIELD_WG_OBJECTSTATE_NONE;
|
|
_staticTowerInfo = nullptr;
|
|
}
|
|
|
|
void BfWGGameObjectBuilding::Rebuild()
|
|
{
|
|
switch (_type)
|
|
{
|
|
case BATTLEFIELD_WG_OBJECTTYPE_KEEP_TOWER:
|
|
case BATTLEFIELD_WG_OBJECTTYPE_DOOR_LAST:
|
|
case BATTLEFIELD_WG_OBJECTTYPE_DOOR:
|
|
case BATTLEFIELD_WG_OBJECTTYPE_WALL:
|
|
_teamControl = _wg->GetDefenderTeam(); // Objects that are part of the keep should be the defender's
|
|
break;
|
|
case BATTLEFIELD_WG_OBJECTTYPE_TOWER:
|
|
_teamControl = _wg->GetAttackerTeam(); // The towers in the south should be the attacker's
|
|
break;
|
|
default:
|
|
_teamControl = TEAM_NEUTRAL;
|
|
break;
|
|
}
|
|
|
|
if (GameObject* build = _wg->GetGameObject(_buildGUID))
|
|
{
|
|
// Rebuild gameobject
|
|
if (build->IsDestructibleBuilding())
|
|
{
|
|
build->SetDestructibleState(GO_DESTRUCTIBLE_REBUILDING, nullptr, true);
|
|
if (build->GetEntry() == GO_WINTERGRASP_VAULT_GATE)
|
|
if (GameObject* go = build->FindNearestGameObject(GO_WINTERGRASP_KEEP_COLLISION_WALL, 50.0f))
|
|
go->SetGoState(GO_STATE_ACTIVE);
|
|
|
|
// Update worldstate
|
|
_state = WintergraspGameObjectState(BATTLEFIELD_WG_OBJECTSTATE_ALLIANCE_INTACT - (_teamControl * 3));
|
|
_wg->SendUpdateWorldState(_worldState, _state);
|
|
}
|
|
UpdateCreatureAndGo();
|
|
build->SetFaction(WintergraspFaction[_teamControl]);
|
|
}
|
|
}
|
|
|
|
void BfWGGameObjectBuilding::RebuildGate()
|
|
{
|
|
if (GameObject* build = _wg->GetGameObject(_buildGUID))
|
|
{
|
|
if (build->IsDestructibleBuilding() && build->GetEntry() == GO_WINTERGRASP_VAULT_GATE)
|
|
{
|
|
if (GameObject* go = build->FindNearestGameObject(GO_WINTERGRASP_KEEP_COLLISION_WALL, 50.0f))
|
|
go->SetGoState(GO_STATE_READY); //not GO_STATE_ACTIVE
|
|
}
|
|
}
|
|
}
|
|
|
|
void BfWGGameObjectBuilding::Damaged()
|
|
{
|
|
// Update worldstate
|
|
_state = WintergraspGameObjectState(BATTLEFIELD_WG_OBJECTSTATE_ALLIANCE_DAMAGE - (_teamControl * 3));
|
|
_wg->SendUpdateWorldState(_worldState, _state);
|
|
|
|
// Send warning message
|
|
if (_staticTowerInfo)
|
|
_wg->SendWarning(_staticTowerInfo->TextIds.Damaged);
|
|
|
|
for (ObjectGuid guid : m_CreatureTopList[_wg->GetAttackerTeam()])
|
|
if (Creature* creature = _wg->GetCreature(guid))
|
|
_wg->HideNpc(creature);
|
|
|
|
for (ObjectGuid guid : m_TurretTopList)
|
|
if (Creature* creature = _wg->GetCreature(guid))
|
|
_wg->HideNpc(creature);
|
|
|
|
if (_type == BATTLEFIELD_WG_OBJECTTYPE_KEEP_TOWER)
|
|
_wg->UpdateDamagedTowerCount(_wg->GetDefenderTeam());
|
|
else if (_type == BATTLEFIELD_WG_OBJECTTYPE_TOWER)
|
|
_wg->UpdateDamagedTowerCount(_wg->GetAttackerTeam());
|
|
}
|
|
|
|
void BfWGGameObjectBuilding::Destroyed()
|
|
{
|
|
// Update worldstate
|
|
_state = WintergraspGameObjectState(BATTLEFIELD_WG_OBJECTSTATE_ALLIANCE_DESTROY - (_teamControl * 3));
|
|
_wg->SendUpdateWorldState(_worldState, _state);
|
|
|
|
// Warn players
|
|
if (_staticTowerInfo)
|
|
_wg->SendWarning(_staticTowerInfo->TextIds.Destroyed);
|
|
|
|
switch (_type)
|
|
{
|
|
// Inform the global wintergrasp script of the destruction of this object
|
|
case BATTLEFIELD_WG_OBJECTTYPE_TOWER:
|
|
case BATTLEFIELD_WG_OBJECTTYPE_KEEP_TOWER:
|
|
_wg->UpdatedDestroyedTowerCount(_teamControl);
|
|
break;
|
|
case BATTLEFIELD_WG_OBJECTTYPE_DOOR_LAST:
|
|
if (GameObject* build = _wg->GetGameObject(_buildGUID))
|
|
if (GameObject* go = build->FindNearestGameObject(GO_WINTERGRASP_KEEP_COLLISION_WALL, 50.0f))
|
|
go->SetGoState(GO_STATE_ACTIVE);
|
|
_wg->SetRelicInteractible(true);
|
|
if (_wg->GetRelic())
|
|
_wg->GetRelic()->RemoveFlag(GameObjectFlags(GO_FLAG_IN_USE | GO_FLAG_NOT_SELECTABLE));
|
|
else
|
|
TC_LOG_ERROR("bg.battlefield.wg", "Titan Relic not found.");
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
_wg->BrokenWallOrTower(_teamControl, this);
|
|
}
|
|
|
|
void BfWGGameObjectBuilding::Init(GameObject* go)
|
|
{
|
|
if (!go)
|
|
return;
|
|
|
|
// GameObject associated to object
|
|
_buildGUID = go->GetGUID();
|
|
|
|
switch (_type)
|
|
{
|
|
case BATTLEFIELD_WG_OBJECTTYPE_KEEP_TOWER:
|
|
case BATTLEFIELD_WG_OBJECTTYPE_DOOR_LAST:
|
|
case BATTLEFIELD_WG_OBJECTTYPE_DOOR:
|
|
case BATTLEFIELD_WG_OBJECTTYPE_WALL:
|
|
_teamControl = _wg->GetDefenderTeam(); // Objects that are part of the keep should be the defender's
|
|
break;
|
|
case BATTLEFIELD_WG_OBJECTTYPE_TOWER:
|
|
_teamControl = _wg->GetAttackerTeam(); // The towers in the south should be the attacker's
|
|
break;
|
|
default:
|
|
_teamControl = TEAM_NEUTRAL;
|
|
break;
|
|
}
|
|
|
|
_state = WintergraspGameObjectState(sWorld->getWorldState(_worldState));
|
|
switch (_state)
|
|
{
|
|
case BATTLEFIELD_WG_OBJECTSTATE_NEUTRAL_INTACT:
|
|
case BATTLEFIELD_WG_OBJECTSTATE_ALLIANCE_INTACT:
|
|
case BATTLEFIELD_WG_OBJECTSTATE_HORDE_INTACT:
|
|
go->SetDestructibleState(GO_DESTRUCTIBLE_REBUILDING, nullptr, true);
|
|
break;
|
|
case BATTLEFIELD_WG_OBJECTSTATE_NEUTRAL_DESTROY:
|
|
case BATTLEFIELD_WG_OBJECTSTATE_ALLIANCE_DESTROY:
|
|
case BATTLEFIELD_WG_OBJECTSTATE_HORDE_DESTROY:
|
|
go->SetDestructibleState(GO_DESTRUCTIBLE_DESTROYED);
|
|
break;
|
|
case BATTLEFIELD_WG_OBJECTSTATE_NEUTRAL_DAMAGE:
|
|
case BATTLEFIELD_WG_OBJECTSTATE_ALLIANCE_DAMAGE:
|
|
case BATTLEFIELD_WG_OBJECTSTATE_HORDE_DAMAGE:
|
|
go->SetDestructibleState(GO_DESTRUCTIBLE_DAMAGED);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
int32 towerId = -1;
|
|
switch (go->GetEntry())
|
|
{
|
|
case GO_WINTERGRASP_FORTRESS_TOWER_1:
|
|
towerId = BATTLEFIELD_WG_TOWER_FORTRESS_NW;
|
|
break;
|
|
case GO_WINTERGRASP_FORTRESS_TOWER_2:
|
|
towerId = BATTLEFIELD_WG_TOWER_FORTRESS_SW;
|
|
break;
|
|
case GO_WINTERGRASP_FORTRESS_TOWER_3:
|
|
towerId = BATTLEFIELD_WG_TOWER_FORTRESS_SE;
|
|
break;
|
|
case GO_WINTERGRASP_FORTRESS_TOWER_4:
|
|
towerId = BATTLEFIELD_WG_TOWER_FORTRESS_NE;
|
|
break;
|
|
case GO_WINTERGRASP_SHADOWSIGHT_TOWER:
|
|
towerId = BATTLEFIELD_WG_TOWER_SHADOWSIGHT;
|
|
break;
|
|
case GO_WINTERGRASP_WINTER_S_EDGE_TOWER:
|
|
towerId = BATTLEFIELD_WG_TOWER_WINTER_S_EDGE;
|
|
break;
|
|
case GO_WINTERGRASP_FLAMEWATCH_TOWER:
|
|
towerId = BATTLEFIELD_WG_TOWER_FLAMEWATCH;
|
|
break;
|
|
}
|
|
|
|
if (towerId >= BATTLEFIELD_WG_TOWER_SHADOWSIGHT) // Attacker towers
|
|
{
|
|
// Spawn associate gameobjects
|
|
for (WintergraspGameObjectData const& gobData : AttackTowers[towerId - 4].GameObject)
|
|
{
|
|
if (GameObject* goHorde = _wg->SpawnGameObject(gobData.HordeEntry, gobData.Pos, gobData.Rot))
|
|
m_GameObjectList[TEAM_HORDE].push_back(goHorde->GetGUID());
|
|
|
|
if (GameObject* goAlliance = _wg->SpawnGameObject(gobData.AllianceEntry, gobData.Pos, gobData.Rot))
|
|
m_GameObjectList[TEAM_ALLIANCE].push_back(goAlliance->GetGUID());
|
|
}
|
|
|
|
// Spawn associate npc bottom
|
|
for (WintergraspObjectPositionData const& creatureData : AttackTowers[towerId - 4].CreatureBottom)
|
|
{
|
|
if (Creature* creature = _wg->SpawnCreature(creatureData.HordeEntry, creatureData.Pos))
|
|
m_CreatureBottomList[TEAM_HORDE].push_back(creature->GetGUID());
|
|
|
|
if (Creature* creature = _wg->SpawnCreature(creatureData.AllianceEntry, creatureData.Pos))
|
|
m_CreatureBottomList[TEAM_ALLIANCE].push_back(creature->GetGUID());
|
|
}
|
|
}
|
|
|
|
if (towerId >= 0)
|
|
{
|
|
ASSERT(towerId < WG_MAX_TOWER);
|
|
_staticTowerInfo = &TowerData[towerId];
|
|
|
|
// Spawn Turret bottom
|
|
for (Position const& turretPos : TowerCannon[towerId].TowerCannonBottom)
|
|
{
|
|
if (Creature* turret = _wg->SpawnCreature(NPC_WINTERGRASP_TOWER_CANNON, turretPos))
|
|
{
|
|
m_TowerCannonBottomList.push_back(turret->GetGUID());
|
|
switch (go->GetEntry())
|
|
{
|
|
case GO_WINTERGRASP_FORTRESS_TOWER_1:
|
|
case GO_WINTERGRASP_FORTRESS_TOWER_2:
|
|
case GO_WINTERGRASP_FORTRESS_TOWER_3:
|
|
case GO_WINTERGRASP_FORTRESS_TOWER_4:
|
|
turret->SetFaction(WintergraspFaction[_wg->GetDefenderTeam()]);
|
|
break;
|
|
case GO_WINTERGRASP_SHADOWSIGHT_TOWER:
|
|
case GO_WINTERGRASP_WINTER_S_EDGE_TOWER:
|
|
case GO_WINTERGRASP_FLAMEWATCH_TOWER:
|
|
turret->SetFaction(WintergraspFaction[_wg->GetAttackerTeam()]);
|
|
break;
|
|
}
|
|
|
|
_wg->HideNpc(turret);
|
|
}
|
|
}
|
|
|
|
// Spawn Turret top
|
|
for (Position const& towerCannonPos : TowerCannon[towerId].TurretTop)
|
|
{
|
|
if (Creature* turret = _wg->SpawnCreature(NPC_WINTERGRASP_TOWER_CANNON, towerCannonPos))
|
|
{
|
|
m_TurretTopList.push_back(turret->GetGUID());
|
|
switch (go->GetEntry())
|
|
{
|
|
case GO_WINTERGRASP_FORTRESS_TOWER_1:
|
|
case GO_WINTERGRASP_FORTRESS_TOWER_2:
|
|
case GO_WINTERGRASP_FORTRESS_TOWER_3:
|
|
case GO_WINTERGRASP_FORTRESS_TOWER_4:
|
|
turret->SetFaction(WintergraspFaction[_wg->GetDefenderTeam()]);
|
|
break;
|
|
case GO_WINTERGRASP_SHADOWSIGHT_TOWER:
|
|
case GO_WINTERGRASP_WINTER_S_EDGE_TOWER:
|
|
case GO_WINTERGRASP_FLAMEWATCH_TOWER:
|
|
turret->SetFaction(WintergraspFaction[_wg->GetAttackerTeam()]);
|
|
break;
|
|
}
|
|
_wg->HideNpc(turret);
|
|
}
|
|
}
|
|
UpdateCreatureAndGo();
|
|
}
|
|
}
|
|
|
|
void BfWGGameObjectBuilding::UpdateCreatureAndGo()
|
|
{
|
|
for (ObjectGuid guid : m_CreatureTopList[_wg->GetDefenderTeam()])
|
|
if (Creature* creature = _wg->GetCreature(guid))
|
|
_wg->HideNpc(creature);
|
|
|
|
for (ObjectGuid guid : m_CreatureTopList[_wg->GetAttackerTeam()])
|
|
if (Creature* creature = _wg->GetCreature(guid))
|
|
_wg->ShowNpc(creature, true);
|
|
|
|
for (ObjectGuid guid : m_CreatureBottomList[_wg->GetDefenderTeam()])
|
|
if (Creature* creature = _wg->GetCreature(guid))
|
|
_wg->HideNpc(creature);
|
|
|
|
for (ObjectGuid guid : m_CreatureBottomList[_wg->GetAttackerTeam()])
|
|
if (Creature* creature = _wg->GetCreature(guid))
|
|
_wg->ShowNpc(creature, true);
|
|
|
|
for (ObjectGuid guid : m_GameObjectList[_wg->GetDefenderTeam()])
|
|
if (GameObject* go = _wg->GetGameObject(guid))
|
|
go->SetRespawnTime(RESPAWN_ONE_DAY);
|
|
|
|
for (ObjectGuid guid : m_GameObjectList[_wg->GetAttackerTeam()])
|
|
if (GameObject* go = _wg->GetGameObject(guid))
|
|
go->SetRespawnTime(RESPAWN_IMMEDIATELY);
|
|
}
|
|
|
|
void BfWGGameObjectBuilding::UpdateTurretAttack(bool disable)
|
|
{
|
|
for (ObjectGuid guid : m_TowerCannonBottomList)
|
|
{
|
|
if (Creature* creature = _wg->GetCreature(guid))
|
|
{
|
|
if (disable)
|
|
_wg->HideNpc(creature);
|
|
else
|
|
_wg->ShowNpc(creature, true);
|
|
|
|
switch (_buildGUID.GetEntry())
|
|
{
|
|
case GO_WINTERGRASP_FORTRESS_TOWER_1:
|
|
case GO_WINTERGRASP_FORTRESS_TOWER_2:
|
|
case GO_WINTERGRASP_FORTRESS_TOWER_3:
|
|
case GO_WINTERGRASP_FORTRESS_TOWER_4:
|
|
{
|
|
creature->SetFaction(WintergraspFaction[_wg->GetDefenderTeam()]);
|
|
break;
|
|
}
|
|
case GO_WINTERGRASP_SHADOWSIGHT_TOWER:
|
|
case GO_WINTERGRASP_WINTER_S_EDGE_TOWER:
|
|
case GO_WINTERGRASP_FLAMEWATCH_TOWER:
|
|
{
|
|
creature->SetFaction(WintergraspFaction[_wg->GetAttackerTeam()]);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
for (ObjectGuid guid : m_TurretTopList)
|
|
{
|
|
if (Creature* creature = _wg->GetCreature(guid))
|
|
{
|
|
if (disable)
|
|
_wg->HideNpc(creature);
|
|
else
|
|
_wg->ShowNpc(creature, true);
|
|
|
|
switch (_buildGUID.GetEntry())
|
|
{
|
|
case GO_WINTERGRASP_FORTRESS_TOWER_1:
|
|
case GO_WINTERGRASP_FORTRESS_TOWER_2:
|
|
case GO_WINTERGRASP_FORTRESS_TOWER_3:
|
|
case GO_WINTERGRASP_FORTRESS_TOWER_4:
|
|
{
|
|
creature->SetFaction(WintergraspFaction[_wg->GetDefenderTeam()]);
|
|
break;
|
|
}
|
|
case GO_WINTERGRASP_SHADOWSIGHT_TOWER:
|
|
case GO_WINTERGRASP_WINTER_S_EDGE_TOWER:
|
|
case GO_WINTERGRASP_FLAMEWATCH_TOWER:
|
|
{
|
|
creature->SetFaction(WintergraspFaction[_wg->GetAttackerTeam()]);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void BfWGGameObjectBuilding::FillInitialWorldStates(WorldPackets::WorldState::InitWorldStates& packet)
|
|
{
|
|
packet.Worldstates.emplace_back(_worldState, _state);
|
|
}
|
|
|
|
void BfWGGameObjectBuilding::Save()
|
|
{
|
|
sWorld->setWorldState(_worldState, _state);
|
|
}
|
|
|
|
WintergraspWorkshop::WintergraspWorkshop(BattlefieldWG* wg, uint8 type)
|
|
{
|
|
ASSERT(wg && type < WG_MAX_WORKSHOP);
|
|
|
|
_wg = wg;
|
|
_state = BATTLEFIELD_WG_OBJECTSTATE_NONE;
|
|
_teamControl = TEAM_NEUTRAL;
|
|
_staticInfo = &WorkshopData[type];
|
|
}
|
|
|
|
uint8 WintergraspWorkshop::GetId() const
|
|
{
|
|
return _staticInfo->WorkshopId;
|
|
}
|
|
|
|
void WintergraspWorkshop::GiveControlTo(TeamId teamId, bool init /*= false*/)
|
|
{
|
|
switch (teamId)
|
|
{
|
|
case TEAM_NEUTRAL:
|
|
{
|
|
// Send warning message to all player for inform a faction attack a workshop
|
|
// alliance / horde attacking workshop
|
|
_wg->SendWarning(_teamControl == TEAM_ALLIANCE ? _staticInfo->TextIds.HordeAttack : _staticInfo->TextIds.AllianceAttack);
|
|
break;
|
|
}
|
|
case TEAM_ALLIANCE:
|
|
{
|
|
// Updating worldstate
|
|
_state = BATTLEFIELD_WG_OBJECTSTATE_ALLIANCE_INTACT;
|
|
_wg->SendUpdateWorldState(_staticInfo->WorldStateId, _state);
|
|
|
|
// Warning message
|
|
if (!init)
|
|
_wg->SendWarning(_staticInfo->TextIds.AllianceCapture); // workshop taken - alliance
|
|
|
|
// Found associate graveyard and update it
|
|
if (_staticInfo->WorkshopId < BATTLEFIELD_WG_WORKSHOP_KEEP_WEST)
|
|
if (BfGraveyard* gy = _wg->GetGraveyardById(_staticInfo->WorkshopId))
|
|
gy->GiveControlTo(TEAM_ALLIANCE);
|
|
|
|
_teamControl = teamId;
|
|
break;
|
|
}
|
|
case TEAM_HORDE:
|
|
{
|
|
// Update worldstate
|
|
_state = BATTLEFIELD_WG_OBJECTSTATE_HORDE_INTACT;
|
|
_wg->SendUpdateWorldState(_staticInfo->WorldStateId, _state);
|
|
|
|
// Warning message
|
|
if (!init)
|
|
_wg->SendWarning(_staticInfo->TextIds.HordeCapture); // workshop taken - horde
|
|
|
|
// Update graveyard control
|
|
if (_staticInfo->WorkshopId < BATTLEFIELD_WG_WORKSHOP_KEEP_WEST)
|
|
if (BfGraveyard* gy = _wg->GetGraveyardById(_staticInfo->WorkshopId))
|
|
gy->GiveControlTo(TEAM_HORDE);
|
|
|
|
_teamControl = teamId;
|
|
break;
|
|
}
|
|
}
|
|
if (!init)
|
|
_wg->UpdateCounterVehicle(false);
|
|
}
|
|
|
|
void WintergraspWorkshop::UpdateGraveyardAndWorkshop()
|
|
{
|
|
if (_staticInfo->WorkshopId < BATTLEFIELD_WG_WORKSHOP_NE)
|
|
GiveControlTo(_wg->GetAttackerTeam(), true);
|
|
else
|
|
GiveControlTo(_wg->GetDefenderTeam(), true);
|
|
}
|
|
|
|
void WintergraspWorkshop::FillInitialWorldStates(WorldPackets::WorldState::InitWorldStates& packet)
|
|
{
|
|
packet.Worldstates.emplace_back(_staticInfo->WorldStateId, _state);
|
|
}
|
|
|
|
void WintergraspWorkshop::Save()
|
|
{
|
|
sWorld->setWorldState(_staticInfo->WorldStateId, _state);
|
|
}
|
|
|
|
class Battlefield_wintergrasp : public BattlefieldScript
|
|
{
|
|
public:
|
|
Battlefield_wintergrasp() : BattlefieldScript("battlefield_wg") { }
|
|
|
|
Battlefield* GetBattlefield() const override
|
|
{
|
|
return new BattlefieldWG();
|
|
}
|
|
};
|
|
|
|
class npc_wg_give_promotion_credit : public CreatureScript
|
|
{
|
|
public:
|
|
npc_wg_give_promotion_credit() : CreatureScript("npc_wg_give_promotion_credit") { }
|
|
|
|
struct npc_wg_give_promotion_creditAI : public ScriptedAI
|
|
{
|
|
npc_wg_give_promotion_creditAI(Creature* creature) : ScriptedAI(creature) { }
|
|
|
|
void JustDied(Unit* killer) override
|
|
{
|
|
if (!killer || killer->GetTypeId() != TYPEID_PLAYER)
|
|
return;
|
|
|
|
BattlefieldWG* wintergrasp = static_cast<BattlefieldWG*>(sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG));
|
|
if (!wintergrasp)
|
|
return;
|
|
|
|
wintergrasp->HandlePromotion(killer->ToPlayer(), me);
|
|
}
|
|
};
|
|
|
|
CreatureAI* GetAI(Creature* creature) const override
|
|
{
|
|
return new npc_wg_give_promotion_creditAI(creature);
|
|
}
|
|
};
|
|
|
|
void AddSC_BF_wintergrasp()
|
|
{
|
|
new Battlefield_wintergrasp();
|
|
new npc_wg_give_promotion_credit();
|
|
}
|