Core/Battlegrounds: Move to scripts And a lot of misc commits i couldn't recover.

Port From (https://github.com/TrinityCore/TrinityCore/commit/d0d5d309bb5877dc2fcb27f6cb123707a31ec1e8)
This commit is contained in:
Hondacrx
2024-08-04 15:18:22 -04:00
parent bca02a24b0
commit e9b21a91be
139 changed files with 8322 additions and 8700 deletions
@@ -0,0 +1,250 @@
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
using Framework.Constants;
using Game;
using Game.AI;
using Game.DataStorage;
using Game.Entities;
using Game.Maps;
using Game.Scripting;
using System;
namespace Scripts.Battlegrounds.AlteracValley
{
struct SpellIds
{
public const uint Charge = 22911;
public const uint Cleave = 40504;
public const uint DemoralizingShout = 23511;
public const uint Enrage = 8599;
public const uint Whirlwind = 13736;
public const uint NorthMarshal = 45828;
public const uint SouthMarshal = 45829;
public const uint StonehearthMarshal = 45830;
public const uint IcewingMarshal = 45831;
public const uint IcebloodWarmaster = 45822;
public const uint TowerPointWarmaster = 45823;
public const uint WestFrostwolfWarmaster = 45824;
public const uint EastFrostwolfWarmaster = 45826;
}
enum CreatureIds
{
NorthMarshal = 14762,
SouthMarshal = 14763,
IcewingMarshal = 14764,
StonehearthMarshal = 14765,
EastFrostwolfWarmaster = 14772,
IcebloodWarmaster = 14773,
TowerPointWarmaster = 14776,
WestFrostwolfWarmaster = 14777,
Vanndar = 11948,
Drekthar = 11946,
Balinda = 11949,
Galvangar = 11947,
Morloch = 11657,
UmiThorson = 13078,
Keetar = 13079,
TaskmasterSnivvle = 11677,
AgiRumblestomp = 13086,
MashaSwiftcut = 13088,
Herald = 14848,
StormpikeDefender = 12050,
FrostwolfGuardian = 12053,
SeasonedDefender = 13326,
SeasonedGuardian = 13328,
VeteranDefender = 13331,
VeteranGuardian = 13332,
ChampionDefender = 13422,
ChampionGuardian = 13421
}
enum SharedActions
{
BuffYell = -30001,
InteractCapturableObject = 1,
CaptureCapturableObject = 2,
TurnInScraps = 3,
TurnInCommander1 = 4,
TurnInCommander2 = 5,
TurnInCommander3 = 6,
TurnInBoss1,
TurnInBoss2,
TurnInNearMine,
TurnInOtherMine,
TurnInRiderHide,
TurnInRiderTame
}
[Script]
class npc_av_marshal_or_warmaster : ScriptedAI
{
public npc_av_marshal_or_warmaster(Creature creature) : base(creature) { }
public override void Reset()
{
_scheduler.CancelAll();
_scheduler.Schedule(TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(12), task =>
{
DoCastVictim(SpellIds.Charge);
task.Repeat(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(25));
});
_scheduler.Schedule(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(11), task =>
{
DoCastVictim(SpellIds.Cleave);
task.Repeat(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(16));
});
_scheduler.Schedule(TimeSpan.FromSeconds(2), task =>
{
DoCast(me, SpellIds.DemoralizingShout);
task.Repeat(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(15));
});
_scheduler.Schedule(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(20), task =>
{
DoCast(me, SpellIds.Whirlwind);
task.Repeat(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(25));
});
_scheduler.Schedule(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(20), task =>
{
DoCast(me, SpellIds.Enrage);
task.Repeat(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(30));
});
_scheduler.Schedule(TimeSpan.FromSeconds(5), task =>
{
Position _homePosition = me.GetHomePosition();
if (me.GetDistance2d(_homePosition.GetPositionX(), _homePosition.GetPositionY()) > 50.0f)
{
EnterEvadeMode();
return;
}
task.Repeat(TimeSpan.FromSeconds(5));
});
}
public override void JustAppeared()
{
Reset();
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
_scheduler.Update(diff);
}
}
[Script]
class go_av_capturable_object : GameObjectAI
{
public go_av_capturable_object(GameObject go) : base(go) { }
public override void Reset()
{
me.SetActive(true);
}
public override bool OnGossipHello(Player player)
{
if (me.GetGoState() != GameObjectState.Ready)
return true;
ZoneScript zonescript = me.GetZoneScript();
if (zonescript != null)
{
zonescript.DoAction(1, player, me);
return false;
}
return true;
}
}
[Script]
class go_av_contested_object : GameObjectAI
{
public go_av_contested_object(GameObject go) : base(go) { }
public override void Reset()
{
me.SetActive(true);
_scheduler.Schedule(TimeSpan.FromMinutes(4), _ =>
{
ZoneScript zonescript = me.GetZoneScript();
if (zonescript != null)
zonescript.DoAction(2, me, me);
});
}
public override bool OnGossipHello(Player player)
{
if (me.GetGoState() != GameObjectState.Ready)
return true;
ZoneScript zonescript = me.GetZoneScript();
if (zonescript != null)
{
zonescript.DoAction(1, player, me);
return false;
}
return true;
}
public override void UpdateAI(uint diff)
{
_scheduler.Update(diff);
}
}
[Script]
class at_av_exploit : AreaTriggerScript
{
public at_av_exploit() : base("at_av_exploit") { }
public override bool OnTrigger(Player player, AreaTriggerRecord trigger)
{
var battleground = player.GetBattleground();
if (battleground != null && battleground.GetStatus() == BattlegroundStatus.WaitJoin)
battleground.TeleportPlayerToExploitLocation(player);
return true;
}
}
[Script("quest_alterac_valley_armor_scraps", SharedActions.TurnInScraps)]
[Script("quest_alterac_valley_call_of_air_slidore_guse", SharedActions.TurnInCommander1)]
[Script("quest_alterac_valley_call_of_air_vipore_jeztor", SharedActions.TurnInCommander2)]
[Script("quest_alterac_valley_call_of_air_ichman_mulverick", SharedActions.TurnInCommander3)]
[Script("quest_alterac_valley_boss_5", SharedActions.TurnInBoss1)]
[Script("quest_alterac_valley_boss_1", SharedActions.TurnInBoss2)]
[Script("quest_alterac_valley_near_mine", SharedActions.TurnInNearMine)]
[Script("quest_alterac_valley_other_mine", SharedActions.TurnInOtherMine)]
[Script("quest_alterac_valley_ram_harnesses", SharedActions.TurnInRiderHide)]
[Script("quest_alterac_valley_empty_stables", SharedActions.TurnInRiderTame)]
class quest_alterac_valley : QuestScript
{
uint _actionId;
public quest_alterac_valley(string scriptName, SharedActions actionId) : base(scriptName)
{
_actionId = (uint)actionId;
}
public override void OnQuestStatusChange(Player player, Quest quest, QuestStatus oldStatus, QuestStatus newStatus)
{
if (newStatus != QuestStatus.Rewarded)
return;
ZoneScript zoneScript = player.FindZoneScript();
if (zoneScript != null)
zoneScript.DoAction(_actionId, player, player);
}
}
}
@@ -0,0 +1,147 @@
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
using Framework.Constants;
using Game.AI;
using Game.Entities;
using Game.Scripting;
using Game.Spells;
using System;
using System.Collections.Generic;
namespace Scripts.Battlegrounds.AlteracValley.Balinda
{
struct SpellIds
{
public const uint ArcaneExplosion = 46608;
public const uint ConeOfCold = 38384;
public const uint Fireball = 46988;
public const uint Frostbolt = 46987;
public const uint SummonWaterElemental = 45067;
public const uint Iceblock = 46604;
}
struct TextIds
{
public const uint SayAggro = 0;
public const uint SayEvade = 1;
public const uint SaySalvation = 2;
}
struct ActionIds
{
public const int BuffYell = -30001; // shared from Battleground
}
[Script]
class boss_balinda : ScriptedAI
{
SummonList summons;
ObjectGuid WaterElementalGUID;
bool HasCastIceblock;
public boss_balinda(Creature creature) : base(creature)
{
summons = new(me);
Initialize();
}
void Initialize()
{
WaterElementalGUID.Clear();
HasCastIceblock = false;
}
public override void Reset()
{
Initialize();
_scheduler.CancelAll();
summons.DespawnAll();
}
public override void JustEngagedWith(Unit who)
{
Talk(TextIds.SayAggro);
_scheduler.Schedule(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(15), task =>
{
DoCastVictim(SpellIds.ArcaneExplosion);
task.Repeat();
});
_scheduler.Schedule(TimeSpan.FromSeconds(8), task =>
{
DoCastVictim(SpellIds.ConeOfCold);
task.Repeat(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(20));
});
_scheduler.Schedule(TimeSpan.FromSeconds(1), task =>
{
DoCastVictim(SpellIds.Fireball);
task.Repeat(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(9));
});
_scheduler.Schedule(TimeSpan.FromSeconds(4), task =>
{
DoCastVictim(SpellIds.Frostbolt);
task.Repeat(TimeSpan.FromSeconds(4), TimeSpan.FromSeconds(12));
});
_scheduler.Schedule(TimeSpan.FromSeconds(3), task =>
{
if (summons.Empty())
DoCast(SpellIds.SummonWaterElemental);
task.Repeat(TimeSpan.FromSeconds(50));
});
_scheduler.Schedule(TimeSpan.FromSeconds(5), task =>
{
if (me.GetDistance2d(me.GetHomePosition().GetPositionX(), me.GetHomePosition().GetPositionY()) > 50)
{
EnterEvadeMode();
Talk(TextIds.SayEvade);
}
Creature elemental = ObjectAccessor.GetCreature(me, WaterElementalGUID);
if (elemental != null)
if (elemental.GetDistance2d(me.GetHomePosition().GetPositionX(), me.GetHomePosition().GetPositionY()) > 50)
elemental.GetAI().EnterEvadeMode();
task.Repeat();
});
}
public override void JustSummoned(Creature summoned)
{
summoned.GetAI().AttackStart(SelectTarget(SelectTargetMethod.Random, 0, 50, true));
summoned.SetFaction(me.GetFaction());
WaterElementalGUID = summoned.GetGUID();
summons.Summon(summoned);
}
public override void SummonedCreatureDespawn(Creature summoned)
{
summons.Despawn(summoned);
}
public override void JustDied(Unit killer)
{
summons.DespawnAll();
}
public override void DoAction(int actionId)
{
if (actionId == ActionIds.BuffYell)
Talk(TextIds.SayAggro);
}
public override void DamageTaken(Unit attacker, ref uint damage, DamageEffectType damageType, SpellInfo spellInfo = null)
{
if (me.HealthBelowPctDamaged(40, damage) && !HasCastIceblock)
{
DoCast(SpellIds.Iceblock);
HasCastIceblock = true;
}
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
_scheduler.Update(diff);
}
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,97 @@
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
using Game.AI;
using Game.Entities;
using Game.Scripting;
using System;
namespace Scripts.Battlegrounds.AlteracValley.Drekthar
{
struct SpellIds
{
public const uint Whirlwind = 15589;
public const uint Whirlwind2 = 13736;
public const uint Knockdown = 19128;
public const uint Frenzy = 8269;
public const uint SweepingStrikes = 18765; // not sure
public const uint Cleave = 20677; // not sure
public const uint Windfury = 35886; // not sure
public const uint Stormpike = 51876; // not sure
}
struct TextIds
{
public const uint SayAggro = 0;
public const uint SayEvade = 1;
public const uint SayRespawn = 2;
public const uint SayRandom = 3;
}
[Script]
class boss_drekthar : ScriptedAI
{
public boss_drekthar(Creature creature) : base(creature) { }
public override void Reset()
{
_scheduler.CancelAll();
}
public override void JustEngagedWith(Unit who)
{
Talk(TextIds.SayAggro);
_scheduler.Schedule(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(20), task =>
{
DoCastVictim(SpellIds.Whirlwind);
task.Repeat(TimeSpan.FromSeconds(8), TimeSpan.FromSeconds(18));
});
_scheduler.Schedule(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(20), task =>
{
DoCastVictim(SpellIds.Whirlwind2);
task.Repeat(TimeSpan.FromSeconds(7), TimeSpan.FromSeconds(25));
});
_scheduler.Schedule(TimeSpan.FromSeconds(12), task =>
{
DoCastVictim(SpellIds.Knockdown);
task.Repeat(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(15));
});
_scheduler.Schedule(TimeSpan.FromSeconds(6), task =>
{
DoCastVictim(SpellIds.Frenzy);
task.Repeat(TimeSpan.FromSeconds(20), TimeSpan.FromSeconds(30));
});
_scheduler.Schedule(TimeSpan.FromSeconds(20), TimeSpan.FromSeconds(30), task =>
{
Talk(TextIds.SayRandom);
task.Repeat();
});
}
public override void JustAppeared()
{
Reset();
Talk(TextIds.SayRespawn);
}
public override bool CheckInRoom()
{
if (me.GetDistance2d(me.GetHomePosition().GetPositionX(), me.GetHomePosition().GetPositionY()) > 50)
{
EnterEvadeMode();
Talk(TextIds.SayEvade);
return false;
}
return true;
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim() || !CheckInRoom())
return;
_scheduler.Update(diff);
}
}
}
@@ -0,0 +1,98 @@
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
using Game.AI;
using Game.Entities;
using Game.Scripting;
using System;
namespace Scripts.Battlegrounds.AlteracValley.Galvangar
{
struct SpellIds
{
public const uint Cleave = 15284;
public const uint FrighteningShout = 19134;
public const uint Whirlwind1 = 15589;
public const uint Whirlwind2 = 13736;
public const uint MortalStrike = 16856;
}
struct TextIds
{
public const uint SayAggro = 0;
public const uint SayEvade = 1;
public const uint SayBuff = 2;
}
struct ActionIds
{
public const int BuffYell = -30001; // shared from Battleground
}
[Script]
class boss_galvangar : ScriptedAI
{
public boss_galvangar(Creature creature) : base(creature) { }
public override void Reset()
{
_scheduler.CancelAll();
}
public override void JustEngagedWith(Unit who)
{
Talk(TextIds.SayAggro);
_scheduler.Schedule(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(9), task =>
{
DoCastVictim(SpellIds.Cleave);
task.Repeat(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(16));
});
_scheduler.Schedule(TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(19), task =>
{
DoCastVictim(SpellIds.FrighteningShout);
task.Repeat(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(15));
});
_scheduler.Schedule(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(13), task =>
{
DoCastVictim(SpellIds.Whirlwind1);
task.Repeat(TimeSpan.FromSeconds(6), TimeSpan.FromSeconds(10));
});
_scheduler.Schedule(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(20), task =>
{
DoCastVictim(SpellIds.Whirlwind2);
task.Repeat(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(25));
});
_scheduler.Schedule(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(20), task =>
{
DoCastVictim(SpellIds.MortalStrike);
task.Repeat(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(30));
});
}
public override void DoAction(int actionId)
{
if (actionId == ActionIds.BuffYell)
Talk(TextIds.SayBuff);
}
public override bool CheckInRoom()
{
if (me.GetDistance2d(me.GetHomePosition().GetPositionX(), me.GetHomePosition().GetPositionY()) > 50)
{
EnterEvadeMode();
Talk(TextIds.SayEvade);
return false;
}
return true;
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim() || !CheckInRoom())
return;
_scheduler.Update(diff);
}
}
}
@@ -0,0 +1,81 @@
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
using Game.AI;
using Game.Entities;
using Game.Scripting;
using System;
namespace Scripts.Battlegrounds.AlteracValley.Vanndar
{
struct SpellIds
{
public const uint Avatar = 19135;
public const uint Thunderclap = 15588;
public const uint Stormbolt = 20685; // not sure
}
struct TextIds
{
public const uint YellAggro = 0;
public const uint YellEvade = 1;
//public const uint YellRespawn1 = -1810010; // Missing in database
//public const uint YellRespawn2 = -1810011; // Missing in database
public const uint YellRandom = 2;
public const uint YellSpell = 3;
}
[Script]
class boss_vanndar : ScriptedAI
{
public boss_vanndar(Creature creature) : base(creature) { }
public override void Reset()
{
_scheduler.CancelAll();
}
public override void JustEngagedWith(Unit who)
{
_scheduler.Schedule(TimeSpan.FromSeconds(3), task =>
{
DoCastVictim(SpellIds.Avatar);
task.Repeat(TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(20));
});
_scheduler.Schedule(TimeSpan.FromSeconds(4), task =>
{
DoCastVictim(SpellIds.Thunderclap);
task.Repeat(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(15));
});
_scheduler.Schedule(TimeSpan.FromSeconds(6), task =>
{
DoCastVictim(SpellIds.Stormbolt);
task.Repeat(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(25));
});
_scheduler.Schedule(TimeSpan.FromSeconds(20), TimeSpan.FromSeconds(30), task =>
{
Talk(TextIds.YellRandom);
task.Repeat(TimeSpan.FromSeconds(20), TimeSpan.FromSeconds(30));
});
_scheduler.Schedule(TimeSpan.FromSeconds(5), task =>
{
if (me.GetDistance2d(me.GetHomePosition().GetPositionX(), me.GetHomePosition().GetPositionY()) > 50)
{
EnterEvadeMode();
Talk(TextIds.YellEvade);
}
task.Repeat();
});
Talk(TextIds.YellAggro);
}
public override void UpdateAI(uint diff)
{
if (!UpdateVictim())
return;
_scheduler.Update(diff);
}
}
}
@@ -0,0 +1,66 @@
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
using Framework.Constants;
using Game.AI;
using Game.Entities;
using Game.Scripting;
using Game.Spells;
using System;
using System.Collections.Generic;
namespace Scripts.Battlegrounds.ArthiBasin
{
[Script]
[Script("npc_bg_ab_arathor_gryphon_rider_leader", PathGryphonRiderLeader)]
[Script("npc_bg_ab_defiler_bat_rider_leader", PathBatRiderLeader)]
class npc_bg_ab_gryphon_bat_rider_leader : ScriptedAI
{
const uint PathGryphonRiderLeader = 800000059;
const uint PathBatRiderLeader = 800000058;
uint _pathId;
public npc_bg_ab_gryphon_bat_rider_leader(Creature creature, uint pathId) : base(creature)
{
_pathId = pathId;
}
public override void WaypointPathEnded(uint nodeId, uint pathId)
{
if (pathId != _pathId)
return;
// despawn formation group
List<Creature> followers = me.GetCreatureListWithEntryInGrid(me.GetEntry());
foreach (Creature follower in followers)
follower.DespawnOrUnsummon(TimeSpan.FromMilliseconds(500));
me.DespawnOrUnsummon(TimeSpan.FromMilliseconds(500));
}
}
[Script] // 261985 - Blacksmith Working
class spell_bg_ab_blacksmith_working : AuraScript
{
const uint ItemBlacksmithHammer = 5956;
void OnApply(AuraEffect aurEff, AuraEffectHandleModes mode)
{
GetTarget().SetVirtualItem(0, ItemBlacksmithHammer);
}
void OnRemove(AuraEffect aurEff, AuraEffectHandleModes mode)
{
Creature creature = GetTarget().ToCreature();
if (creature != null)
creature.LoadEquipment(creature.GetOriginalEquipmentId());
}
public override void Register()
{
AfterEffectApply.Add(new(OnApply, 0, AuraType.Dummy, AuraEffectHandleModes.Real));
AfterEffectRemove.Add(new(OnRemove, 0, AuraType.Dummy, AuraEffectHandleModes.Real));
}
}
}
@@ -0,0 +1,597 @@
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
using Framework.Constants;
using Game.BattleGrounds;
using Game.Entities;
using Game.Maps;
using Game.Scripting;
using System;
using System.Collections.Generic;
namespace Scripts.Battlegrounds.ArthiBasin
{
enum PvpStats
{
BasesAssaulted = 926,
BasesDefended = 927,
}
enum EventIds
{
StartBattle = 9158, // Achievement: Let's Get This Done
ContestedStablesHorde = 28523,
CaptureStablesHorde = 28527,
DefendedStablesHorde = 28525,
ContestedStablesAlliance = 28522,
CaptureStablesAlliance = 28526,
DefendedStablesAlliance = 28524,
ContestedBlacksmithHorde = 8876,
CaptureBlacksmithHorde = 8773,
DefendedBlacksmithHorde = 8770,
ContestedBlacksmithAlliance = 8874,
CaptureBlacksmithAlliance = 8769,
DefendedBlacksmithAlliance = 8774,
ContestedFarmHorde = 39398,
CaptureFarmHorde = 39399,
DefendedFarmHorde = 39400,
ContestedFarmAlliance = 39401,
CaptureFarmAlliance = 39402,
DefendedFarmAlliance = 39403,
ContestedGoldMineHorde = 39404,
CaptureGoldMineHorde = 39405,
DefendedGoldMineHorde = 39406,
ContestedGoldMineAlliance = 39407,
CaptureGoldMineAlliance = 39408,
DefendedGoldMineAlliance = 39409,
ContestedLumberMillHorde = 39387,
CaptureLumberMillHorde = 39388,
DefendedLumberMillHorde = 39389,
ContestedLumberMillAlliance = 39390,
CaptureLumberMillAlliance = 39391,
DefendedLumberMillAlliance = 39392
}
enum SoundIds
{
NodeClaimed = 8192,
NodeCapturedAlliance = 8173,
NodeCapturedHorde = 8213,
NodeAssaultedAlliance = 8212,
NodeAssaultedHorde = 8174,
NearVictoryAlliance = 8456,
NearVictoryHorde = 8457
}
enum BroadcastTexts
{
AllianceNearVictory = 10598,
HordeNearVictory = 10599,
}
enum CreatureIds
{
TheBlackBride = 150501,
RadulfLeder = 150505
}
enum GameObjectIds
{
CapturePointStables = 227420,
CapturePointBlacksmith = 227522,
CapturePointFarm = 227536,
CapturePointGoldMine = 227538,
CapturePointLumberMill = 227544,
GhostGate = 180322,
AllianceDoor = 322273,
HordeDoor = 322274
}
enum WorldStateIds
{
OccupiedBasesHorde = 1778,
OccupiedBasesAlly = 1779,
ResourcesAlly = 1776,
ResourcesHorde = 1777,
ResourcesMax = 1780,
ResourcesWarning = 1955,
StableIcon = 1842, // Stable Map Icon (None)
StableStateAlience = 1767, // Stable Map State (Alience)
StableStateHorde = 1768, // Stable Map State (Horde)
StableStateConAli = 1769, // Stable Map State (Con Alience)
StableStateConHor = 1770, // Stable Map State (Con Horde)
FarmIcon = 1845, // Farm Map Icon (None)
FarmStateAlience = 1772, // Farm State (Alience)
FarmStateHorde = 1773, // Farm State (Horde)
FarmStateConAli = 1774, // Farm State (Con Alience)
FarmStateConHor = 1775, // Farm State (Con Horde)
BlacksmithIcon = 1846, // Blacksmith Map Icon (None)
BlacksmithStateAlience = 1782, // Blacksmith Map State (Alience)
BlacksmithStateHorde = 1783, // Blacksmith Map State (Horde)
BlacksmithStateConAli = 1784, // Blacksmith Map State (Con Alience)
BlacksmithStateConHor = 1785, // Blacksmith Map State (Con Horde)
LumbermillIcon = 1844, // Lumber Mill Map Icon (None)
LumbermillStateAlience = 1792, // Lumber Mill Map State (Alience)
LumbermillStateHorde = 1793, // Lumber Mill Map State (Horde)
LumbermillStateConAli = 1794, // Lumber Mill Map State (Con Alience)
LumbermillStateConHor = 1795, // Lumber Mill Map State (Con Horde)
GoldmineIcon = 1843, // Gold Mine Map Icon (None)
GoldmineStateAlience = 1787, // Gold Mine Map State (Alience)
GoldmineStateHorde = 1788, // Gold Mine Map State (Horde)
GoldmineStateConAli = 1789, // Gold Mine Map State (Con Alience
GoldmineStateConHor = 1790, // Gold Mine Map State (Con Horde)
Had500DisadvantageAlliance = 3644,
Had500DisadvantageHorde = 3645,
FarmIconNew = 8808, // Farm Map Icon
LumberMillIconNew = 8805, // Lumber Mill Map Icon
BlacksmithIconNew = 8799, // Blacksmith Map Icon
GoldMineIconNew = 8809, // Gold Mine Map Icon
StablesIconNew = 5834, // Stable Map Icon
FarmHordeControlState = 17328,
FarmAllianceControlState = 17325,
LumberMillHordeControlState = 17330,
LumberMillAllianceControlState = 17326,
BlacksmithHordeControlState = 17327,
BlacksmithAllianceControlState = 17324,
GoldMineHordeControlState = 17329,
GoldMineAllianceControlState = 17323,
StablesHordeControlState = 17331,
StablesAllianceControlState = 17322,
}
struct Misc
{
public const int WarningNearVictoryScore = 1200;
public const int MaxTeamScore = 1500;
// Tick intervals and given points: case 0, 1, 2, 3, 4, 5 captured nodes
public static uint TickInterval = 2000;
public static uint[] TickPoints = { 0, 2, 3, 4, 7, 60 };
public static uint NormalHonorTicks = 160;
public static uint WeekendHonorTicks = 260;
public static uint NormalReputationTicks = 120;
public static uint WeekendReputationTicks = 160;
}
[Script(nameof(battleground_arathi_basin), 2107)]
class battleground_arathi_basin : BattlegroundScript
{
uint _lastTick;
uint[] _honorScoreTics = new uint[SharedConst.PvpTeamsCount];
uint[] _reputationScoreTics = new uint[SharedConst.PvpTeamsCount];
bool _isInformedNearVictory;
uint _honorTics;
uint _reputationTics;
List<ObjectGuid> _gameobjectsToRemoveOnMatchStart = new();
List<ObjectGuid> _creaturesToRemoveOnMatchStart = new();
List<ObjectGuid> _doors = new();
List<ObjectGuid> _capturePoints = new();
public battleground_arathi_basin(BattlegroundMap map) : base(map)
{
bool isBGWeekend = Global.BattlegroundMgr.IsBGWeekend(battleground.GetTypeID());
_honorTics = isBGWeekend ? Misc.WeekendHonorTicks : Misc.NormalHonorTicks;
_reputationTics = isBGWeekend ? Misc.WeekendReputationTicks : Misc.NormalReputationTicks;
_honorScoreTics = [0, 0];
_reputationScoreTics = [0, 0];
}
public override void OnInit()
{
base.OnInit();
UpdateWorldState((int)WorldStateIds.ResourcesMax, Misc.MaxTeamScore);
UpdateWorldState((int)WorldStateIds.ResourcesWarning, Misc.WarningNearVictoryScore);
}
public override void OnUpdate(uint diff)
{
if (battleground.GetStatus() != BattlegroundStatus.InProgress)
return;
// Accumulate points
_lastTick += diff;
if (_lastTick > Misc.TickInterval)
{
_lastTick -= Misc.TickInterval;
_CalculateTeamNodes(out byte ally, out byte horde);
byte[] points = { ally, horde };
for (byte team = 0; team < SharedConst.PvpTeamsCount; ++team)
{
if (points[team] == 0)
continue;
battleground.AddPoint(team == BattleGroundTeamId.Horde ? Team.Horde : Team.Alliance, Misc.TickPoints[points[team]]);
_honorScoreTics[team] += Misc.TickPoints[points[team]];
_reputationScoreTics[team] += Misc.TickPoints[points[team]];
if (_reputationScoreTics[team] >= _reputationTics)
{
if (team == BattleGroundTeamId.Alliance)
battleground.RewardReputationToTeam(509, 10, Team.Alliance);
else
battleground.RewardReputationToTeam(510, 10, Team.Horde);
_reputationScoreTics[team] -= _reputationTics;
}
if (_honorScoreTics[team] >= _honorTics)
{
battleground.RewardHonorToTeam(battleground.GetBonusHonorFromKill(1), (team == BattleGroundTeamId.Alliance) ? Team.Alliance : Team.Horde);
_honorScoreTics[team] -= _honorTics;
}
uint teamScore = battleground.GetTeamScore(team);
if (!_isInformedNearVictory && teamScore > Misc.WarningNearVictoryScore)
{
if (team == BattleGroundTeamId.Alliance)
{
battleground.SendBroadcastText((uint)BroadcastTexts.AllianceNearVictory, ChatMsg.BgSystemNeutral);
battleground.PlaySoundToAll((uint)SoundIds.NearVictoryAlliance);
}
else
{
battleground.SendBroadcastText((uint)BroadcastTexts.HordeNearVictory, ChatMsg.BgSystemNeutral);
battleground.PlaySoundToAll((uint)SoundIds.NearVictoryHorde);
}
_isInformedNearVictory = true;
}
if (teamScore > Misc.MaxTeamScore)
battleground.SetTeamPoint(team == BattleGroundTeamId.Horde ? Team.Horde : Team.Alliance, Misc.MaxTeamScore);
if (team == BattleGroundTeamId.Alliance)
UpdateWorldState((int)WorldStateIds.ResourcesAlly, (int)teamScore);
else
UpdateWorldState((int)WorldStateIds.ResourcesHorde, (int)teamScore);
// update achievement flags
// we increased m_TeamScores[team] so we just need to check if it is 500 more than other teams resources
int otherTeam = (team + 1) % SharedConst.PvpTeamsCount;
if (teamScore > battleground.GetTeamScore(otherTeam) + 500)
{
if (team == BattleGroundTeamId.Alliance)
UpdateWorldState((int)WorldStateIds.Had500DisadvantageHorde, 1);
else
UpdateWorldState((int)WorldStateIds.Had500DisadvantageAlliance, 1);
}
}
UpdateWorldState((int)WorldStateIds.OccupiedBasesAlly, ally);
UpdateWorldState((int)WorldStateIds.OccupiedBasesHorde, horde);
}
// Test win condition
if (battleground.GetTeamScore(BattleGroundTeamId.Alliance) >= Misc.MaxTeamScore && battleground.GetTeamScore(BattleGroundTeamId.Horde) >= Misc.MaxTeamScore)
battleground.EndBattleground(Team.Other); // draw
else if (battleground.GetTeamScore(BattleGroundTeamId.Alliance) >= Misc.MaxTeamScore)
battleground.EndBattleground(Team.Alliance);
else if (battleground.GetTeamScore(BattleGroundTeamId.Horde) >= Misc.MaxTeamScore)
battleground.EndBattleground(Team.Horde);
}
public override void OnStart()
{
// Achievement: Let's Get This Done
TriggerGameEvent((uint)EventIds.StartBattle);
}
void _CalculateTeamNodes(out byte alliance, out byte horde)
{
alliance = 0;
horde = 0;
foreach (ObjectGuid guid in _capturePoints)
{
GameObject capturePoint = battlegroundMap.GetGameObject(guid);
if (capturePoint != null)
{
int wsValue = battlegroundMap.GetWorldStateValue((int)capturePoint.GetGoInfo().CapturePoint.worldState1);
switch ((BattlegroundCapturePointState)wsValue)
{
case BattlegroundCapturePointState.AllianceCaptured:
++alliance;
break;
case BattlegroundCapturePointState.HordeCaptured:
++horde;
break;
default:
break;
}
}
}
}
public override Team GetPrematureWinner()
{
// How many bases each team owns
_CalculateTeamNodes(out byte ally, out byte horde);
if (ally > horde)
return Team.Alliance;
if (horde > ally)
return Team.Horde;
// If the values are equal, fall back to the original result (based on number of players on each team)
return base.GetPrematureWinner();
}
public override void ProcessEvent(WorldObject source, uint eventId, WorldObject invoker)
{
Player player = invoker.ToPlayer();
switch ((EventIds)eventId)
{
case EventIds.StartBattle:
{
foreach (ObjectGuid guid in _creaturesToRemoveOnMatchStart)
{
Creature creature = battlegroundMap.GetCreature(guid);
if (creature != null)
creature.DespawnOrUnsummon();
}
foreach (ObjectGuid guid in _gameobjectsToRemoveOnMatchStart)
{
GameObject gameObject = battlegroundMap.GetGameObject(guid);
if (gameObject != null)
gameObject.DespawnOrUnsummon();
}
foreach (ObjectGuid guid in _doors)
{
GameObject gameObject = battlegroundMap.GetGameObject(guid);
if (gameObject != null)
{
gameObject.UseDoorOrButton();
gameObject.DespawnOrUnsummon(TimeSpan.FromSeconds(3));
}
}
break;
}
case EventIds.ContestedBlacksmithAlliance:
UpdateWorldState((int)WorldStateIds.BlacksmithAllianceControlState, 1);
UpdateWorldState((int)WorldStateIds.BlacksmithHordeControlState, 0);
battleground.PlaySoundToAll((uint)SoundIds.NodeAssaultedAlliance);
if (player != null)
battleground.UpdatePvpStat(player, (uint)PvpStats.BasesAssaulted, 1);
break;
case EventIds.DefendedBlacksmithAlliance:
UpdateWorldState((int)WorldStateIds.BlacksmithAllianceControlState, 2);
UpdateWorldState((int)WorldStateIds.BlacksmithHordeControlState, 0);
battleground.PlaySoundToAll((uint)SoundIds.NodeCapturedAlliance);
if (player != null)
battleground.UpdatePvpStat(player, (uint)PvpStats.BasesDefended, 1);
break;
case EventIds.CaptureBlacksmithAlliance:
UpdateWorldState((int)WorldStateIds.BlacksmithAllianceControlState, 2);
battleground.PlaySoundToAll((uint)SoundIds.NodeCapturedAlliance);
break;
case EventIds.ContestedBlacksmithHorde:
UpdateWorldState((int)WorldStateIds.BlacksmithAllianceControlState, 0);
UpdateWorldState((int)WorldStateIds.BlacksmithHordeControlState, 1);
battleground.PlaySoundToAll((uint)SoundIds.NodeAssaultedHorde);
if (player != null)
battleground.UpdatePvpStat(player, (uint)PvpStats.BasesAssaulted, 1);
break;
case EventIds.DefendedBlacksmithHorde:
UpdateWorldState((int)WorldStateIds.BlacksmithAllianceControlState, 0);
UpdateWorldState((int)WorldStateIds.BlacksmithHordeControlState, 2);
battleground.PlaySoundToAll((uint)SoundIds.NodeCapturedHorde);
if (player != null)
battleground.UpdatePvpStat(player, (uint)PvpStats.BasesDefended, 1);
break;
case EventIds.CaptureBlacksmithHorde:
UpdateWorldState((int)WorldStateIds.BlacksmithHordeControlState, 2);
battleground.PlaySoundToAll((uint)SoundIds.NodeCapturedHorde);
break;
case EventIds.ContestedFarmAlliance:
UpdateWorldState((int)WorldStateIds.FarmAllianceControlState, 1);
UpdateWorldState((int)WorldStateIds.FarmHordeControlState, 0);
battleground.PlaySoundToAll((uint)SoundIds.NodeAssaultedAlliance);
if (player != null)
battleground.UpdatePvpStat(player, (uint)PvpStats.BasesAssaulted, 1);
break;
case EventIds.DefendedFarmAlliance:
UpdateWorldState((int)WorldStateIds.FarmAllianceControlState, 2);
UpdateWorldState((int)WorldStateIds.FarmHordeControlState, 0);
battleground.PlaySoundToAll((uint)SoundIds.NodeCapturedAlliance);
if (player != null)
battleground.UpdatePvpStat(player, (uint)PvpStats.BasesDefended, 1);
break;
case EventIds.CaptureFarmAlliance:
UpdateWorldState((int)WorldStateIds.FarmAllianceControlState, 2);
battleground.PlaySoundToAll((uint)SoundIds.NodeCapturedAlliance);
break;
case EventIds.ContestedFarmHorde:
UpdateWorldState((int)WorldStateIds.FarmAllianceControlState, 0);
UpdateWorldState((int)WorldStateIds.FarmHordeControlState, 1);
battleground.PlaySoundToAll((uint)SoundIds.NodeAssaultedHorde);
if (player != null)
battleground.UpdatePvpStat(player, (uint)PvpStats.BasesAssaulted, 1);
break;
case EventIds.DefendedFarmHorde:
UpdateWorldState((int)WorldStateIds.FarmAllianceControlState, 0);
UpdateWorldState((int)WorldStateIds.FarmHordeControlState, 2);
battleground.PlaySoundToAll((uint)SoundIds.NodeCapturedHorde);
if (player != null)
battleground.UpdatePvpStat(player, (uint)PvpStats.BasesDefended, 1);
break;
case EventIds.CaptureFarmHorde:
UpdateWorldState((int)WorldStateIds.FarmHordeControlState, 2);
battleground.PlaySoundToAll((uint)SoundIds.NodeCapturedHorde);
break;
case EventIds.ContestedGoldMineAlliance:
UpdateWorldState((int)WorldStateIds.GoldMineAllianceControlState, 1);
UpdateWorldState((int)WorldStateIds.GoldMineHordeControlState, 0);
battleground.PlaySoundToAll((uint)SoundIds.NodeAssaultedAlliance);
if (player != null)
battleground.UpdatePvpStat(player, (uint)PvpStats.BasesAssaulted, 1);
break;
case EventIds.DefendedGoldMineAlliance:
UpdateWorldState((int)WorldStateIds.GoldMineAllianceControlState, 2);
UpdateWorldState((int)WorldStateIds.GoldMineHordeControlState, 0);
battleground.PlaySoundToAll((uint)SoundIds.NodeCapturedAlliance);
if (player != null)
battleground.UpdatePvpStat(player, (uint)PvpStats.BasesDefended, 1);
break;
case EventIds.CaptureGoldMineAlliance:
UpdateWorldState((int)WorldStateIds.GoldMineAllianceControlState, 2);
battleground.PlaySoundToAll((uint)SoundIds.NodeCapturedAlliance);
break;
case EventIds.ContestedGoldMineHorde:
UpdateWorldState((int)WorldStateIds.GoldMineAllianceControlState, 0);
UpdateWorldState((int)WorldStateIds.GoldMineHordeControlState, 1);
battleground.PlaySoundToAll((uint)SoundIds.NodeAssaultedHorde);
if (player != null)
battleground.UpdatePvpStat(player, (uint)PvpStats.BasesAssaulted, 1);
break;
case EventIds.DefendedGoldMineHorde:
UpdateWorldState((int)WorldStateIds.GoldMineAllianceControlState, 0);
UpdateWorldState((int)WorldStateIds.GoldMineHordeControlState, 2);
battleground.PlaySoundToAll((uint)SoundIds.NodeCapturedHorde);
if (player != null)
battleground.UpdatePvpStat(player, (uint)PvpStats.BasesDefended, 1);
break;
case EventIds.CaptureGoldMineHorde:
UpdateWorldState((int)WorldStateIds.GoldMineHordeControlState, 2);
battleground.PlaySoundToAll((uint)SoundIds.NodeCapturedHorde);
break;
case EventIds.ContestedLumberMillAlliance:
UpdateWorldState((int)WorldStateIds.LumberMillAllianceControlState, 1);
UpdateWorldState((int)WorldStateIds.LumberMillHordeControlState, 0);
battleground.PlaySoundToAll((uint)SoundIds.NodeAssaultedAlliance);
if (player != null)
battleground.UpdatePvpStat(player, (uint)PvpStats.BasesAssaulted, 1);
break;
case EventIds.DefendedLumberMillAlliance:
UpdateWorldState((int)WorldStateIds.LumberMillAllianceControlState, 2);
UpdateWorldState((int)WorldStateIds.LumberMillHordeControlState, 0);
battleground.PlaySoundToAll((uint)SoundIds.NodeCapturedAlliance);
if (player != null)
battleground.UpdatePvpStat(player, (uint)PvpStats.BasesDefended, 1);
break;
case EventIds.CaptureLumberMillAlliance:
UpdateWorldState((int)WorldStateIds.LumberMillAllianceControlState, 2);
battleground.PlaySoundToAll((uint)SoundIds.NodeCapturedAlliance);
break;
case EventIds.ContestedLumberMillHorde:
UpdateWorldState((int)WorldStateIds.LumberMillAllianceControlState, 0);
UpdateWorldState((int)WorldStateIds.LumberMillHordeControlState, 1);
battleground.PlaySoundToAll((uint)SoundIds.NodeAssaultedHorde);
if (player != null)
battleground.UpdatePvpStat(player, (uint)PvpStats.BasesAssaulted, 1);
break;
case EventIds.DefendedLumberMillHorde:
UpdateWorldState((int)WorldStateIds.LumberMillAllianceControlState, 0);
UpdateWorldState((int)WorldStateIds.LumberMillHordeControlState, 2);
battleground.PlaySoundToAll((uint)SoundIds.NodeCapturedHorde);
if (player != null)
battleground.UpdatePvpStat(player, (uint)PvpStats.BasesDefended, 1);
break;
case EventIds.CaptureLumberMillHorde:
UpdateWorldState((int)WorldStateIds.LumberMillHordeControlState, 2);
battleground.PlaySoundToAll((uint)SoundIds.NodeCapturedHorde);
break;
case EventIds.ContestedStablesAlliance:
UpdateWorldState((int)WorldStateIds.StablesAllianceControlState, 1);
UpdateWorldState((int)WorldStateIds.StablesHordeControlState, 0);
battleground.PlaySoundToAll((uint)SoundIds.NodeAssaultedAlliance);
if (player != null)
battleground.UpdatePvpStat(player, (uint)PvpStats.BasesAssaulted, 1);
break;
case EventIds.DefendedStablesAlliance:
UpdateWorldState((int)WorldStateIds.StablesAllianceControlState, 2);
UpdateWorldState((int)WorldStateIds.StablesHordeControlState, 0);
battleground.PlaySoundToAll((uint)SoundIds.NodeCapturedAlliance);
if (player != null)
battleground.UpdatePvpStat(player, (uint)PvpStats.BasesDefended, 1);
break;
case EventIds.CaptureStablesAlliance:
UpdateWorldState((int)WorldStateIds.StablesAllianceControlState, 2);
battleground.PlaySoundToAll((uint)SoundIds.NodeCapturedAlliance);
break;
case EventIds.ContestedStablesHorde:
UpdateWorldState((int)WorldStateIds.StablesAllianceControlState, 0);
UpdateWorldState((int)WorldStateIds.StablesHordeControlState, 1);
battleground.PlaySoundToAll((uint)SoundIds.NodeAssaultedHorde);
if (player != null)
battleground.UpdatePvpStat(player, (uint)PvpStats.BasesAssaulted, 1);
break;
case EventIds.DefendedStablesHorde:
UpdateWorldState((int)WorldStateIds.StablesAllianceControlState, 0);
UpdateWorldState((int)WorldStateIds.StablesHordeControlState, 2);
battleground.PlaySoundToAll((uint)SoundIds.NodeCapturedHorde);
if (player != null)
battleground.UpdatePvpStat(player, (uint)PvpStats.BasesDefended, 1);
break;
case EventIds.CaptureStablesHorde:
UpdateWorldState((int)WorldStateIds.StablesHordeControlState, 2);
battleground.PlaySoundToAll((uint)SoundIds.NodeCapturedHorde);
break;
default:
Log.outWarn(LogFilter.Battleground, $"BattlegroundAB::ProcessEvent: Unhandled event {eventId}.");
break;
}
}
public override void OnCreatureCreate(Creature creature)
{
switch ((CreatureIds)creature.GetEntry())
{
case CreatureIds.TheBlackBride:
case CreatureIds.RadulfLeder:
_creaturesToRemoveOnMatchStart.Add(creature.GetGUID());
break;
default:
break;
}
}
public override void OnGameObjectCreate(GameObject gameObject)
{
if (gameObject.GetGoInfo().type == GameObjectTypes.CapturePoint)
_capturePoints.Add(gameObject.GetGUID());
switch ((GameObjectIds)gameObject.GetEntry())
{
case GameObjectIds.GhostGate:
_gameobjectsToRemoveOnMatchStart.Add(gameObject.GetGUID());
break;
case GameObjectIds.AllianceDoor:
case GameObjectIds.HordeDoor:
_doors.Add(gameObject.GetGUID());
break;
default:
break;
}
}
public override void OnEnd(Team winner)
{
base.OnEnd(winner);
// Win reward
if (winner == Team.Alliance)
battleground.RewardHonorToTeam(battleground.GetBonusHonorFromKill(1), Team.Alliance);
if (winner == Team.Horde)
battleground.RewardHonorToTeam(battleground.GetBonusHonorFromKill(1), Team.Horde);
// Complete map_end rewards (even if no team wins)
battleground.RewardHonorToTeam(battleground.GetBonusHonorFromKill(1), Team.Horde);
battleground.RewardHonorToTeam(battleground.GetBonusHonorFromKill(1), Team.Alliance);
}
}
}
@@ -0,0 +1,15 @@
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
using Game.BattleGrounds;
using Game.Maps;
using Game.Scripting;
namespace Scripts.Battlegrounds.BattleForGilneas
{
[Script(nameof(battleground_battle_for_gilneas), 761)]
class battleground_battle_for_gilneas : BattlegroundScript
{
public battleground_battle_for_gilneas(BattlegroundMap map) : base(map) { }
}
}
@@ -0,0 +1,71 @@
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
using Framework.Constants;
using Framework.Dynamic;
using Game.BattleGrounds;
using Game.Entities;
using Game.Maps;
using Game.Scripting;
using System;
using System.Collections.Generic;
namespace Scripts.Battlegrounds.BladesEdge
{
enum GameObjectIds
{
Door1 = 183971,
Door2 = 183973,
Door3 = 183970,
Door4 = 183972,
Buff1 = 184663,
Buff2 = 184664
}
[Script(nameof(arena_blades_edge), 1672)]
class arena_blades_edge : ArenaScript
{
List<ObjectGuid> _doorGUIDs = new();
public arena_blades_edge(BattlegroundMap map) : base(map) { }
public override void OnUpdate(uint diff)
{
_scheduler.Update(diff);
}
public override void OnInit()
{
AddDoor(GameObjectIds.Door1, 6287.277f, 282.1877f, 3.810925f, -2.260201f, 0, 0, 0.9044551f, -0.4265689f);
AddDoor(GameObjectIds.Door2, 6189.546f, 241.7099f, 3.101481f, 0.8813917f, 0, 0, 0.4265689f, 0.9044551f);
AddDoor(GameObjectIds.Door3, 6299.116f, 296.5494f, 3.308032f, 0.8813917f, 0, 0, 0.4265689f, 0.9044551f);
AddDoor(GameObjectIds.Door4, 6177.708f, 227.3481f, 3.604374f, -2.260201f, 0, 0, 0.9044551f, -0.4265689f);
}
public override void OnStart()
{
foreach (ObjectGuid guid in _doorGUIDs)
{
GameObject door = battlegroundMap.GetGameObject(guid);
if (door != null)
{
door.UseDoorOrButton();
door.DespawnOrUnsummon(TimeSpan.FromSeconds(5));
}
}
_scheduler.Schedule(TimeSpan.FromMinutes(1), _ =>
{
CreateObject((uint)GameObjectIds.Buff1, 6249.042f, 275.3239f, 11.22033f, -1.448624f, 0, 0, 0.6626201f, -0.7489557f);
CreateObject((uint)GameObjectIds.Buff2, 6228.26f, 249.566f, 11.21812f, -0.06981307f, 0, 0, 0.03489945f, -0.9993908f);
});
}
void AddDoor(GameObjectIds entry, float x, float y, float z, float o, float rotation0, float rotation1, float rotation2, float rotation3, GameObjectState goState = GameObjectState.Ready)
{
GameObject go = CreateObject((uint)entry, x, y, z, o, rotation0, rotation1, rotation2, rotation3, goState);
if (go != null)
_doorGUIDs.Add(go.GetGUID());
}
}
}
@@ -0,0 +1,278 @@
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
using Framework.Constants;
using Game.BattleGrounds;
using Game.DataStorage;
using Game.Entities;
using Game.Maps;
using Game.Scripting;
using System;
using System.Collections.Generic;
namespace Scripts.Battlegrounds.DalaranSewers
{
enum GameObjectIds
{
Door1 = 192642,
Door2 = 192643,
Water1 = 194395, // Collision
Water2 = 191877,
Buff1 = 184663,
Buff2 = 184664
}
enum EventIds
{
WaterfallWarning = 1, // Water Starting To Fall, But No Los Blocking Nor Movement Blocking
WaterfallOn = 2, // Los And Movement Blocking Active
WaterfallOff = 3,
WaterfallKnockback = 4,
PipeKnockback = 5
}
enum CreatureIds
{
WaterSpout = 28567
}
enum SpellIds
{
Flush = 57405, // Visual And Target Selector For The Starting Knockback From The Pipe
FlushKnockback = 61698, // Knockback Effect For Previous Spell (Triggered, Not Needed To Be Cast)
WaterSpout = 58873, // Knockback Effect Of The Central Waterfall
WarlDemonicCircle = 48018 // Demonic Circle Summon
}
struct Misc
{
// These values are NOT blizzlike... need the correct data!
public const uint PipeKnockbackFirstDelay = 5000;
public const uint PipeKnockbackDelay = 3000;
public static TimeSpan WaterfallTimerMin = TimeSpan.FromSeconds(30);
public static TimeSpan WaterfallTimerMax = TimeSpan.FromSeconds(60);
public static TimeSpan WaterfallWarningDuration = TimeSpan.FromSeconds(5);
public static TimeSpan WaterfallDuration = TimeSpan.FromSeconds(30);
public static TimeSpan WaterfallKnockbackTimer = TimeSpan.FromSeconds(1.5);
public const uint DataPipeKnockbackCount = 1;
public const uint PipeKnockbackTotalCount = 2;
}
[Script(nameof(arena_dalaran_sewers), 617)]
class arena_dalaran_sewers : ArenaScript
{
List<ObjectGuid> _doorGUIDs = new();
ObjectGuid _water1GUID;
ObjectGuid _water2GUID;
ObjectGuid _waterfallCreatureGUID;
List<ObjectGuid> _pipeCreatureGUIDs = new();
uint _pipeKnockBackTimer;
uint _pipeKnockBackCount;
public arena_dalaran_sewers(BattlegroundMap map) : base(map)
{
_pipeKnockBackTimer = Misc.PipeKnockbackFirstDelay;
}
public override void OnUpdate(uint diff)
{
if (battleground.GetStatus() != BattlegroundStatus.InProgress)
return;
_events.Update(diff);
_scheduler.Update(diff);
_events.ExecuteEvents(eventId =>
{
switch ((EventIds)eventId)
{
case EventIds.WaterfallWarning:
{
// Add the water
GameObject go = battlegroundMap.GetGameObject(_water2GUID);
if (go != null)
go.ResetDoorOrButton();
_events.ScheduleEvent((uint)EventIds.WaterfallOn, Misc.WaterfallWarningDuration);
break;
}
case EventIds.WaterfallOn:
{
// Active collision and start knockback timer
GameObject go = battlegroundMap.GetGameObject(_water1GUID);
if (go != null)
go.ResetDoorOrButton();
_events.ScheduleEvent((uint)EventIds.WaterfallOff, Misc.WaterfallDuration);
_events.ScheduleEvent((uint)EventIds.WaterfallKnockback, Misc.WaterfallKnockbackTimer);
break;
}
case EventIds.WaterfallOff:
{
// Remove collision and water
GameObject go = battlegroundMap.GetGameObject(_water1GUID);
if (go != null)
go.UseDoorOrButton();
go = battlegroundMap.GetGameObject(_water2GUID);
if (go != null)
go.UseDoorOrButton();
_events.CancelEvent((uint)EventIds.WaterfallKnockback);
_events.ScheduleEvent((uint)EventIds.WaterfallWarning, Misc.WaterfallTimerMin, Misc.WaterfallTimerMax);
break;
}
case EventIds.WaterfallKnockback:
{
// Repeat knockback while the waterfall still active
Creature waterSpout = battlegroundMap.GetCreature(_waterfallCreatureGUID);
if (waterSpout != null)
waterSpout.CastSpell(waterSpout, (uint)SpellIds.WaterSpout, true);
_events.ScheduleEvent(eventId, Misc.WaterfallKnockbackTimer);
break;
}
case EventIds.PipeKnockback:
{
foreach (ObjectGuid guid in _pipeCreatureGUIDs)
{
Creature waterSpout = battlegroundMap.GetCreature(guid);
if (waterSpout != null)
waterSpout.CastSpell(waterSpout, (uint)SpellIds.Flush, true);
}
break;
}
default:
break;
}
});
if (_pipeKnockBackCount < Misc.PipeKnockbackTotalCount)
{
if (_pipeKnockBackTimer < diff)
{
foreach (ObjectGuid guid in _pipeCreatureGUIDs)
{
Creature waterSpout = battlegroundMap.GetCreature(guid);
if (waterSpout != null)
waterSpout.CastSpell(waterSpout, (uint)SpellIds.Flush, true);
}
++_pipeKnockBackCount;
_pipeKnockBackTimer = Misc.PipeKnockbackDelay;
}
else
_pipeKnockBackTimer -= diff;
}
}
public override void OnInit()
{
AddObject((uint)GameObjectIds.Door1, 1350.95f, 817.2f, 20.8096f, 3.15f, 0, 0, 0.99627f, 0.0862864f, GameObjectState.Ready, _doorGUIDs);
AddObject((uint)GameObjectIds.Door2, 1232.65f, 764.913f, 20.0729f, 6.3f, 0, 0, 0.0310211f, -0.999519f, GameObjectState.Ready, _doorGUIDs);
GameObject go = CreateObject((uint)GameObjectIds.Water1, 1291.56f, 790.837f, 7.1f, 3.14238f, 0, 0, 0.694215f, -0.719768f, GameObjectState.Ready);
if (go != null)
_water1GUID = go.GetGUID();
go = CreateObject((uint)GameObjectIds.Water2, 1291.56f, 790.837f, 7.1f, 3.14238f, 0, 0, 0.694215f, -0.719768f, GameObjectState.Ready);
if (go != null)
_water2GUID = go.GetGUID();
}
public override void OnStart()
{
foreach (ObjectGuid guid in _doorGUIDs)
{
GameObject door = battlegroundMap.GetGameObject(guid);
if (door != null)
{
door.UseDoorOrButton();
door.DespawnOrUnsummon(TimeSpan.FromSeconds(5));
}
}
_scheduler.Schedule(TimeSpan.FromMinutes(1), _ =>
{
CreateObject((uint)GameObjectIds.Buff1, 1291.7f, 813.424f, 7.11472f, 4.64562f, 0, 0, 0.730314f, -0.683111f);
CreateObject((uint)GameObjectIds.Buff2, 1291.7f, 768.911f, 7.11472f, 1.55194f, 0, 0, 0.700409f, 0.713742f);
});
_events.ScheduleEvent((uint)EventIds.WaterfallWarning, Misc.WaterfallTimerMin, Misc.WaterfallTimerMax);
_pipeKnockBackTimer = Misc.PipeKnockbackFirstDelay;
// Remove collision and water
GameObject go = battlegroundMap.GetGameObject(_water1GUID);
if (go != null)
go.UseDoorOrButton();
go = battlegroundMap.GetGameObject(_water2GUID);
if (go != null)
go.UseDoorOrButton();
foreach (var (playerGuid, _) in battleground.GetPlayers())
{
Player player = Global.ObjAccessor.FindPlayer(playerGuid);
if (player != null)
player.RemoveAurasDueToSpell((uint)SpellIds.WarlDemonicCircle);
}
}
void AddObject(uint entry, float x, float y, float z, float o, float rotation0, float rotation1, float rotation2, float rotation3, GameObjectState goState, List<ObjectGuid> guidList)
{
GameObject go = CreateObject(entry, x, y, z, o, rotation0, rotation1, rotation2, rotation3, goState);
if (go != null)
guidList.Add(go.GetGUID());
}
public override void SetData(uint dataId, uint value)
{
base.SetData(dataId, value);
if (dataId == Misc.DataPipeKnockbackCount)
_pipeKnockBackCount = value;
}
public override uint GetData(uint dataId)
{
if (dataId == Misc.DataPipeKnockbackCount)
return _pipeKnockBackCount;
return base.GetData(dataId);
}
}
[Script]
class at_ds_pipe_knockback : AreaTriggerScript
{
public at_ds_pipe_knockback() : base("at_ds_pipe_knockback") { }
void Trigger(Player player)
{
Battleground battleground = player.GetBattleground();
if (battleground != null)
{
if (battleground.GetStatus() != BattlegroundStatus.InProgress)
return;
// Remove effects of Demonic Circle Summon
player.RemoveAurasDueToSpell((uint)SpellIds.WarlDemonicCircle);
// Someone has get back into the pipes and the knockback has already been performed,
// so we reset the knockback count for kicking the player again into the arena.
if (battleground.GetBgMap().GetBattlegroundScript().GetData(Misc.DataPipeKnockbackCount) >= Misc.PipeKnockbackTotalCount)
battleground.GetBgMap().GetBattlegroundScript().SetData(Misc.DataPipeKnockbackCount, 0);
}
}
public override bool OnTrigger(Player player, AreaTriggerRecord trigger)
{
Trigger(player);
return true;
}
public override bool OnExit(Player player, AreaTriggerRecord trigger)
{
Trigger(player);
return true;
}
}
}
@@ -0,0 +1,647 @@
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
using Framework.Constants;
using Game.BattleGrounds;
using Game.Entities;
using Game.Maps;
using Game.Scripting;
using Game.Spells;
using System;
using System.Collections.Generic;
namespace Scripts.Battlegrounds.EyeOfTheStorm
{
enum WorldStateIds
{
AllianceResources = 1776,
HordeResources = 1777,
MaxResources = 1780,
AllianceBase = 2752,
HordeBase = 2753,
DraeneiRuinsHordeControl = 2733,
DraeneiRuinsAllianceControl = 2732,
DraeneiRuinsUncontrol = 2731,
MageTowerAllianceControl = 2730,
MageTowerHordeControl = 2729,
MageTowerUncontrol = 2728,
FelReaverHordeControl = 2727,
FelReaverAllianceControl = 2726,
FelReaverUncontrol = 2725,
BloodElfHordeControl = 2724,
BloodElfAllianceControl = 2723,
BloodElfUncontrol = 2722,
ProgressBarPercentGrey = 2720, //100 = Empty (Only Grey), 0 = Blue|Red (No Grey)
ProgressBarStatus = 2719, //50 Init!, 48 ... Hordak Bere .. 33 .. 0 = Full 100% Hordacky, 100 = Full Alliance
ProgressBarShow = 2718, //1 Init, 0 Druhy Send - Bez Messagu, 1 = Controlled Aliance
NetherstormFlag = 8863,
//Set To 2 When Flag Is Picked Up, And To 1 If It Is Dropped
NetherstormFlagStateAlliance = 9808,
NetherstormFlagStateHorde = 9809,
DraeneiRuinsHordeControlState = 17362,
DraeneiRuinsAllianceControlState = 17366,
MageTowerHordeControlState = 17361,
MageTowerAllianceControlState = 17368,
FelReaverHordeControlState = 17364,
FelReaverAllianceControlState = 17367,
BloodElfHordeControlState = 17363,
BloodElfAllianceControlState = 17365,
}
enum SoundIds
{
//strange ids, but sure about them
FlagPickedUpAlliance = 8212,
FlagCapturedHorde = 8213,
FlagPickedUpHorde = 8174,
FlagCapturedAlliance = 8173,
FlagReset = 8192
}
enum SpellIds
{
NetherstormFlag = 34976,
PlayerDroppedFlag = 34991,
// Focused/Brutal Assault
FocusedAssault = 46392,
BrutalAssault = 46393
}
enum GameObjectIds
{
ADoorEyEntry = 184719, //Alliance Door
HDoorEyEntry = 184720, //Horde Door
Flag2EyEntry = 208977, //Netherstorm Flag (Flagstand)
BeTowerCapEyEntry = 184080, //Be Tower Cap Pt
FrTowerCapEyEntry = 184081, //Fel Reaver Cap Pt
HuTowerCapEyEntry = 184082, //Human Tower Cap Pt
DrTowerCapEyEntry = 184083, //Draenei Tower Cap Pt
}
enum Points
{
FelReaver = 0,
BloodElf = 1,
DraeneiRuins = 2,
MageTower = 3,
PlayersOutOfPoints = 4,
Max = 4
}
enum EOSFlagState
{
OnBase = 0,
WaitRespawn = 1,
OnPlayer = 2,
OnGround = 3
}
enum PointState
{
NoOwner = 0,
StateUncontrolled = 0,
UnderControl = 3
}
enum BroadcastTextIds
{
AllianceTakenFelReaverRuins = 17828,
HordeTakenFelReaverRuins = 17829,
AllianceLostFelReaverRuins = 91961,
HordeLostFelReaverRuins = 91962,
AllianceTakenBloodElfTower = 17819,
HordeTakenBloodElfTower = 17823,
AllianceLostBloodElfTower = 91957,
HordeLostBloodElfTower = 91958,
AllianceTakenDraeneiRuins = 17827,
HordeTakenDraeneiRuins = 91917,
AllianceLostDraeneiRuins = 91959,
HordeLostDraeneiRuins = 91960,
AllianceTakenMageTower = 17824,
HordeTakenMageTower = 17825,
AllianceLostMageTower = 91963,
HordeLostMageTower = 91964,
TakenFlag = 18359,
FlagDropped = 18361,
FlagReset = 18364,
AllianceCapturedFlag = 18375,
HordeCapturedFlag = 18384,
}
struct Misc
{
public const uint AreatriggerCaptureFlag = 33;
public const uint WarningNearVictoryScore = 1200;
public const uint MaxTeamScore = 1500;
public const uint NotEYWeekendHonorTicks = 260;
public const uint EYWeekendHonorTicks = 160;
public const uint PvpStaFlagCaptures = 183;
public static TimeSpan PointsTickTime = TimeSpan.FromSeconds(2);
public static TimeSpan FlagAssaultTimer = TimeSpan.FromSeconds(30);
public const ushort FlagBrutalAssaultStackCount = 5;
public const uint EventStartBattle = 13180;
public static byte[] TickPoints = { 1, 2, 5, 10 };
public static uint[] FlagPoints = { 75, 85, 100, 500 };
public const uint ExploitTeleportLocationAlliance = 3773;
public const uint ExploitTeleportLocationHorde = 3772;
public static EyeOfTheStormPointIconsStruct[] m_PointsIconStruct =
{
new(WorldStateIds.FelReaverUncontrol, WorldStateIds.FelReaverAllianceControl, WorldStateIds.FelReaverHordeControl, WorldStateIds.FelReaverAllianceControlState, WorldStateIds.FelReaverHordeControlState),
new(WorldStateIds.BloodElfUncontrol, WorldStateIds.BloodElfAllianceControl, WorldStateIds.BloodElfHordeControl, WorldStateIds.BloodElfAllianceControlState, WorldStateIds.BloodElfHordeControlState),
new(WorldStateIds.DraeneiRuinsUncontrol, WorldStateIds.DraeneiRuinsAllianceControl, WorldStateIds.DraeneiRuinsHordeControl, WorldStateIds.DraeneiRuinsAllianceControlState, WorldStateIds.DraeneiRuinsHordeControlState),
new(WorldStateIds.MageTowerUncontrol, WorldStateIds.MageTowerAllianceControl, WorldStateIds.MageTowerHordeControl, WorldStateIds.MageTowerAllianceControlState, WorldStateIds.MageTowerHordeControlState)
};
public static EyeOfTheStormTextIdStruct[] m_LosingPointTypes =
{
new(BroadcastTextIds.AllianceLostFelReaverRuins, BroadcastTextIds.HordeLostFelReaverRuins),
new(BroadcastTextIds.AllianceLostBloodElfTower, BroadcastTextIds.HordeLostBloodElfTower),
new(BroadcastTextIds.AllianceLostDraeneiRuins, BroadcastTextIds.HordeLostDraeneiRuins),
new(BroadcastTextIds.AllianceLostMageTower, BroadcastTextIds.HordeLostMageTower)
};
public static EyeOfTheStormTextIdStruct[] m_CapturingPointTypes =
{
new(BroadcastTextIds.AllianceTakenFelReaverRuins, BroadcastTextIds.HordeTakenFelReaverRuins),
new(BroadcastTextIds.AllianceTakenBloodElfTower, BroadcastTextIds.HordeTakenBloodElfTower),
new(BroadcastTextIds.AllianceTakenDraeneiRuins, BroadcastTextIds.HordeTakenDraeneiRuins),
new(BroadcastTextIds.AllianceTakenMageTower, BroadcastTextIds.HordeTakenMageTower)
};
}
struct EyeOfTheStormPointIconsStruct
{
public int WorldStateControlIndex;
public int WorldStateAllianceControlledIndex;
public int WorldStateHordeControlledIndex;
public int WorldStateAllianceStatusBarIcon;
public int WorldStateHordeStatusBarIcon;
public EyeOfTheStormPointIconsStruct(WorldStateIds worldStateControlIndex, WorldStateIds worldStateAllianceControlledIndex, WorldStateIds worldStateHordeControlledIndex, WorldStateIds worldStateAllianceStatusBarIcon, WorldStateIds worldStateHordeStatusBarIcon)
{
WorldStateControlIndex = (int)worldStateControlIndex;
WorldStateAllianceControlledIndex = (int)worldStateAllianceControlledIndex;
WorldStateHordeControlledIndex = (int)worldStateHordeControlledIndex;
WorldStateAllianceStatusBarIcon = (int)worldStateAllianceStatusBarIcon;
WorldStateHordeStatusBarIcon = (int)worldStateHordeStatusBarIcon;
}
}
struct EyeOfTheStormTextIdStruct
{
public uint MessageIdAlliance;
public uint MessageIdHorde;
public EyeOfTheStormTextIdStruct(BroadcastTextIds messageIdAlliance, BroadcastTextIds messageIdHorde)
{
MessageIdAlliance = (uint)messageIdAlliance;
MessageIdHorde = (uint)messageIdHorde;
}
}
class BattlegroundEYControlZoneHandler : ControlZoneHandler
{
uint _point;
public BattlegroundEYControlZoneHandler(Points point)
{
_point = (uint)point;
}
public uint GetPoint() { return _point; }
}
[Script(nameof(battleground_eye_of_the_storm), 566)]
class battleground_eye_of_the_storm : BattlegroundScript
{
uint[] _honorScoreTics = new uint[SharedConst.PvpTeamsCount];
TimeTracker _pointsTimer = new();
uint _honorTics;
Dictionary<uint, BattlegroundEYControlZoneHandler> _controlZoneHandlers = new();
List<ObjectGuid> _doorGUIDs = new();
ObjectGuid _flagGUID;
// Focused/Brutal Assault
bool _assaultEnabled;
TimeTracker _flagAssaultTimer;
byte _assaultStackCount;
public battleground_eye_of_the_storm(BattlegroundMap map) : base(map)
{
_honorTics = 0;
_pointsTimer = new(Misc.PointsTickTime);
_assaultEnabled = false;
_assaultStackCount = 0;
_flagAssaultTimer = new(Misc.FlagAssaultTimer);
_controlZoneHandlers[(int)GameObjectIds.FrTowerCapEyEntry] = new(Points.FelReaver);
_controlZoneHandlers[(int)GameObjectIds.BeTowerCapEyEntry] = new(Points.BloodElf);
_controlZoneHandlers[(int)GameObjectIds.DrTowerCapEyEntry] = new(Points.DraeneiRuins);
_controlZoneHandlers[(int)GameObjectIds.HuTowerCapEyEntry] = new(Points.MageTower);
bool isBGWeekend = Global.BattlegroundMgr.IsBGWeekend(battleground.GetTypeID());
_honorTics = (isBGWeekend) ? Misc.EYWeekendHonorTicks : Misc.NotEYWeekendHonorTicks;
}
public override void OnInit()
{
UpdateWorldState((int)WorldStateIds.MaxResources, (int)Misc.MaxTeamScore);
}
public override void OnUpdate(uint diff)
{
if (battleground.GetStatus() != BattlegroundStatus.InProgress)
return;
_pointsTimer.Update(diff);
if (_pointsTimer.Passed())
{
_pointsTimer.Reset(Misc.PointsTickTime);
byte baseCountAlliance = GetControlledBaseCount(BattleGroundTeamId.Alliance);
byte baseCountHorde = GetControlledBaseCount(BattleGroundTeamId.Horde);
if (baseCountAlliance > 0)
AddPoint(Team.Alliance, Misc.TickPoints[baseCountAlliance - 1]);
if (baseCountHorde > 0)
AddPoint(Team.Horde, Misc.TickPoints[baseCountHorde - 1]);
}
if (_assaultEnabled)
{
_flagAssaultTimer.Update(diff);
if (_flagAssaultTimer.Passed())
{
_flagAssaultTimer.Reset(Misc.FlagAssaultTimer);
if (_assaultStackCount < byte.MaxValue)
{
_assaultStackCount++;
// update assault debuff stacks
DoForFlagKeepers(ApplyAssaultDebuffToPlayer);
}
}
}
}
public override void OnStart()
{
foreach (ObjectGuid door in _doorGUIDs)
{
GameObject gameObject = battlegroundMap.GetGameObject(door);
if (gameObject != null)
{
gameObject.UseDoorOrButton();
gameObject.DespawnOrUnsummon(TimeSpan.FromSeconds(3));
}
}
// Achievement: Flurry
TriggerGameEvent(Misc.EventStartBattle);
}
void AddPoint(Team team, uint points)
{
battleground.AddPoint(team, points);
int team_index = Battleground.GetTeamIndexByTeamId(team);
_honorScoreTics[team_index] += points;
if (_honorScoreTics[team_index] >= _honorTics)
{
battleground.RewardHonorToTeam(battleground.GetBonusHonorFromKill(1), team);
_honorScoreTics[team_index] -= _honorTics;
}
UpdateTeamScore(team_index);
}
byte GetControlledBaseCount(int teamId)
{
byte baseCount = 0;
foreach (var (_, controlZoneHandler) in _controlZoneHandlers)
{
uint point = controlZoneHandler.GetPoint();
switch (teamId)
{
case BattleGroundTeamId.Alliance:
if (battlegroundMap.GetWorldStateValue(Misc.m_PointsIconStruct[point].WorldStateAllianceControlledIndex) == 1)
baseCount++;
break;
case BattleGroundTeamId.Horde:
if (battlegroundMap.GetWorldStateValue(Misc.m_PointsIconStruct[point].WorldStateHordeControlledIndex) == 1)
baseCount++;
break;
default:
break;
}
}
return baseCount;
}
void DoForFlagKeepers(Action<Player> action)
{
GameObject flag = battlegroundMap.GetGameObject(_flagGUID);
if (flag != null)
{
Player carrier = Global.ObjAccessor.FindPlayer(flag.GetFlagCarrierGUID());
if (carrier != null)
action(carrier);
}
}
void ResetAssaultDebuff()
{
_assaultEnabled = false;
_assaultStackCount = 0;
_flagAssaultTimer.Reset(Misc.FlagAssaultTimer);
DoForFlagKeepers(RemoveAssaultDebuffFromPlayer);
}
void ApplyAssaultDebuffToPlayer(Player player)
{
if (_assaultStackCount == 0)
return;
uint spellId = (uint)SpellIds.FocusedAssault;
if (_assaultStackCount >= Misc.FlagBrutalAssaultStackCount)
{
player.RemoveAurasDueToSpell((uint)SpellIds.FocusedAssault);
spellId = (uint)SpellIds.BrutalAssault;
}
Aura aura = player.GetAura(spellId);
if (aura == null)
{
player.CastSpell(player, spellId, true);
aura = player.GetAura(spellId);
}
if (aura != null)
aura.SetStackAmount(_assaultStackCount);
}
void RemoveAssaultDebuffFromPlayer(Player player)
{
player.RemoveAurasDueToSpell((uint)SpellIds.FocusedAssault);
player.RemoveAurasDueToSpell((uint)SpellIds.BrutalAssault);
}
void UpdateTeamScore(int team)
{
uint score = battleground.GetTeamScore(team);
if (score >= Misc.MaxTeamScore)
{
score = Misc.MaxTeamScore;
if (team == BattleGroundTeamId.Alliance)
battleground.EndBattleground(Team.Alliance);
else
battleground.EndBattleground(Team.Horde);
}
if (team == BattleGroundTeamId.Alliance)
UpdateWorldState((int)WorldStateIds.AllianceResources, (int)score);
else
UpdateWorldState((int)WorldStateIds.HordeResources, (int)score);
}
public override void OnEnd(Team winner)
{
base.OnEnd(winner);
// Win reward
if (winner == Team.Alliance)
battleground.RewardHonorToTeam(battleground.GetBonusHonorFromKill(1), Team.Alliance);
if (winner == Team.Horde)
battleground.RewardHonorToTeam(battleground.GetBonusHonorFromKill(1), Team.Horde);
// Complete map reward
battleground.RewardHonorToTeam(battleground.GetBonusHonorFromKill(1), Team.Alliance);
battleground.RewardHonorToTeam(battleground.GetBonusHonorFromKill(1), Team.Horde);
}
void UpdatePointsCount(int teamId)
{
if (teamId == BattleGroundTeamId.Alliance)
UpdateWorldState((int)WorldStateIds.AllianceBase, GetControlledBaseCount(BattleGroundTeamId.Alliance));
else
UpdateWorldState((int)WorldStateIds.HordeBase, GetControlledBaseCount(BattleGroundTeamId.Horde));
}
public override void OnGameObjectCreate(GameObject gameObject)
{
switch ((GameObjectIds)gameObject.GetEntry())
{
case GameObjectIds.ADoorEyEntry:
case GameObjectIds.HDoorEyEntry:
_doorGUIDs.Add(gameObject.GetGUID());
break;
case GameObjectIds.Flag2EyEntry:
_flagGUID = gameObject.GetGUID();
break;
default:
break;
}
}
public override bool CanCaptureFlag(AreaTrigger areaTrigger, Player player)
{
if (areaTrigger.GetEntry() != Misc.AreatriggerCaptureFlag)
return false;
GameObject flag = battlegroundMap.GetGameObject(_flagGUID);
if (flag != null)
{
if (flag.GetFlagCarrierGUID() != player.GetGUID())
return false;
}
GameObject controlzone = player.FindNearestGameObjectWithOptions(40.0f, new() { StringId = "bg_eye_of_the_storm_control_zone" });
if (controlzone != null)
{
uint point = _controlZoneHandlers[controlzone.GetEntry()].GetPoint();
switch (battleground.GetPlayerTeam(player.GetGUID()))
{
case Team.Alliance:
return battlegroundMap.GetWorldStateValue(Misc.m_PointsIconStruct[point].WorldStateAllianceControlledIndex) == 1;
case Team.Horde:
return battlegroundMap.GetWorldStateValue(Misc.m_PointsIconStruct[point].WorldStateHordeControlledIndex) == 1;
default:
return false;
}
}
return false;
}
public override void OnCaptureFlag(AreaTrigger areaTrigger, Player player)
{
if (areaTrigger.GetEntry() != Misc.AreatriggerCaptureFlag)
return;
uint baseCount = GetControlledBaseCount(Battleground.GetTeamIndexByTeamId(battleground.GetPlayerTeam(player.GetGUID())));
GameObject gameObject = battlegroundMap.GetGameObject(_flagGUID);
if (gameObject != null)
gameObject.HandleCustomTypeCommand(new Game.Entities.GameObjectType.SetNewFlagState(FlagState.Respawning, player));
Team team = battleground.GetPlayerTeam(player.GetGUID());
if (team == Team.Alliance)
{
battleground.SendBroadcastText((uint)BroadcastTextIds.AllianceCapturedFlag, ChatMsg.BgSystemAlliance, player);
battleground.PlaySoundToAll((uint)SoundIds.FlagCapturedAlliance);
}
else
{
battleground.SendBroadcastText((uint)BroadcastTextIds.HordeCapturedFlag, ChatMsg.BgSystemHorde, player);
battleground.PlaySoundToAll((uint)SoundIds.FlagCapturedHorde);
}
if (baseCount > 0)
AddPoint(team, Misc.FlagPoints[baseCount - 1]);
UpdateWorldState((int)WorldStateIds.NetherstormFlagStateHorde, (int)EOSFlagState.OnBase);
UpdateWorldState((int)WorldStateIds.NetherstormFlagStateAlliance, (int)EOSFlagState.OnBase);
battleground.UpdatePvpStat(player, Misc.PvpStaFlagCaptures, 1);
ResetAssaultDebuff();
player.RemoveAurasDueToSpell((uint)SpellIds.NetherstormFlag);
player.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.PvPActive);
}
public override void OnFlagStateChange(GameObject flagInBase, FlagState oldValue, FlagState newValue, Player player)
{
switch (newValue)
{
case FlagState.InBase:
ResetAssaultDebuff();
break;
case FlagState.Dropped:
player.CastSpell(player, BattlegroundConst.SpellRecentlyDroppedNeutralFlag, true);
RemoveAssaultDebuffFromPlayer(player);
UpdateWorldState((int)WorldStateIds.NetherstormFlagStateHorde, (int)EOSFlagState.WaitRespawn);
UpdateWorldState((int)WorldStateIds.NetherstormFlagStateAlliance, (int)EOSFlagState.WaitRespawn);
if (battleground.GetPlayerTeam(player.GetGUID()) == Team.Alliance)
battleground.SendBroadcastText((uint)BroadcastTextIds.FlagDropped, ChatMsg.BgSystemAlliance);
else
battleground.SendBroadcastText((uint)BroadcastTextIds.FlagDropped, ChatMsg.BgSystemHorde);
break;
case FlagState.Taken:
if (battleground.GetPlayerTeam(player.GetGUID()) == Team.Alliance)
{
UpdateWorldState((int)WorldStateIds.NetherstormFlagStateAlliance, (int)EOSFlagState.OnPlayer);
battleground.PlaySoundToAll((uint)SoundIds.FlagPickedUpAlliance);
battleground.SendBroadcastText((uint)BroadcastTextIds.TakenFlag, ChatMsg.BgSystemAlliance, player);
}
else
{
UpdateWorldState((int)WorldStateIds.NetherstormFlagStateHorde, (int)EOSFlagState.OnPlayer);
battleground.PlaySoundToAll((uint)SoundIds.FlagPickedUpHorde);
battleground.SendBroadcastText((uint)BroadcastTextIds.TakenFlag, ChatMsg.BgSystemHorde, player);
}
ApplyAssaultDebuffToPlayer(player);
_assaultEnabled = true;
player.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.PvPActive);
break;
case FlagState.Respawning:
ResetAssaultDebuff();
break;
default:
break;
}
UpdateWorldState((int)WorldStateIds.NetherstormFlag, (int)newValue);
}
void EventTeamLostPoint(int teamId, uint point, GameObject controlZone)
{
if (teamId == BattleGroundTeamId.Alliance)
{
battleground.SendBroadcastText(Misc.m_LosingPointTypes[point].MessageIdAlliance, ChatMsg.BgSystemAlliance, controlZone);
UpdateWorldState(Misc.m_PointsIconStruct[point].WorldStateAllianceControlledIndex, 0);
}
else if (teamId == BattleGroundTeamId.Horde)
{
battleground.SendBroadcastText(Misc.m_LosingPointTypes[point].MessageIdHorde, ChatMsg.BgSystemHorde, controlZone);
UpdateWorldState(Misc.m_PointsIconStruct[point].WorldStateHordeControlledIndex, 0);
}
UpdateWorldState(Misc.m_PointsIconStruct[point].WorldStateControlIndex, 1);
UpdatePointsCount(teamId);
}
void EventTeamCapturedPoint(int teamId, uint point, GameObject controlZone)
{
if (teamId == BattleGroundTeamId.Alliance)
{
battleground.SendBroadcastText(Misc.m_CapturingPointTypes[point].MessageIdAlliance, ChatMsg.BgSystemAlliance, controlZone);
UpdateWorldState(Misc.m_PointsIconStruct[point].WorldStateAllianceControlledIndex, 1);
}
else if (teamId == BattleGroundTeamId.Horde)
{
battleground.SendBroadcastText(Misc.m_CapturingPointTypes[point].MessageIdHorde, ChatMsg.BgSystemHorde, controlZone);
UpdateWorldState(Misc.m_PointsIconStruct[point].WorldStateHordeControlledIndex, 1);
}
UpdateWorldState(Misc.m_PointsIconStruct[point].WorldStateControlIndex, 0);
UpdatePointsCount(teamId);
}
public override Team GetPrematureWinner()
{
if (battleground.GetTeamScore(BattleGroundTeamId.Alliance) > battleground.GetTeamScore(BattleGroundTeamId.Horde))
return Team.Alliance;
if (battleground.GetTeamScore(BattleGroundTeamId.Horde) > battleground.GetTeamScore(BattleGroundTeamId.Alliance))
return Team.Horde;
return base.GetPrematureWinner();
}
public override void ProcessEvent(WorldObject obj, uint eventId, WorldObject invoker)
{
base.ProcessEvent(obj, eventId, invoker);
if (invoker != null)
{
GameObject gameobject = invoker.ToGameObject();
if (gameobject != null)
{
if (gameobject.GetGoType() == GameObjectTypes.ControlZone)
{
if (!_controlZoneHandlers.ContainsKey(gameobject.GetEntry()))
return;
var controlzone = gameobject.GetGoInfo().ControlZone;
BattlegroundEYControlZoneHandler handler = _controlZoneHandlers[invoker.GetEntry()];
if (eventId == controlzone.NeutralEventAlliance)
EventTeamLostPoint(BattleGroundTeamId.Alliance, handler.GetPoint(), gameobject);
else if (eventId == controlzone.NeutralEventHorde)
EventTeamLostPoint(BattleGroundTeamId.Horde, handler.GetPoint(), gameobject);
else if (eventId == controlzone.ProgressEventAlliance)
EventTeamCapturedPoint(BattleGroundTeamId.Alliance, handler.GetPoint(), gameobject);
else if (eventId == controlzone.ProgressEventHorde)
EventTeamCapturedPoint(BattleGroundTeamId.Horde, handler.GetPoint(), gameobject);
}
}
}
}
}
}
@@ -0,0 +1,974 @@
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
using Framework.Constants;
using Framework.Dynamic;
using Game.BattleGrounds;
using Game.Entities;
using Game.Maps;
using Game.Scripting;
using System;
using System.Collections.Generic;
namespace Scripts.Battlegrounds.IsleOfConquest
{
enum BannersTypes
{
AControlled,
AContested,
HControlled,
HContested
}
enum ExploitTeleportLocations
{
Alliance = 3986,
Horde = 3983
}
enum GateState
{
Ok = 1,
Damaged = 2,
Destroyed = 3
}
enum DoorList
{
HFront,
HWest,
HEast,
AFront,
AWest,
AEast,
Maxdoor
}
enum NodePointType
{
Refinery,
Quarry,
Docks,
Hangar,
Workshop,
// Graveyards
GraveyardA,
GraveyardH,
MaxNodeTypes
}
enum NodeState
{
Neutral,
ConflictA,
ConflictH,
ControlledA,
ControlledH
}
enum BroadcastTextIds
{
FrontGateHordeDestroyed = 35409,
FrontGateAllianceDestroyed = 35410,
WestGateHordeDestroyed = 35411,
WestGateAllianceDestroyed = 35412,
EastGateHordeDestroyed = 35413,
EastGateAllianceDestroyed = 35414
}
enum Actions
{
GunshipReady = 1,
InteractCapturableObject = 2,
CaptureCapturableObject = 3
}
enum HonorRewards
{
ResourceAmount = 12,
WinnerAmount = 500
}
enum PvpStats
{
BasesAssaulted = 245,
BasesDefended = 246
}
enum GameObjectIds
{
Teleporter1 = 195314, // 195314 H-Out 66549
Teleporter2 = 195313, // 195313 H-In 66548
Teleporter3 = 195315, // 195315 A-Out 66549
Teleporter4 = 195316, // 195316 A-In 66548
TeleporterEffectsA = 195701,
TeleporterEffectsH = 195702,
DoodadHuPortcullis01 = 195436,
DoodadNdHumanGateClosedfxDoor01 = 195703,
DoodadPortcullisactive02 = 195452,
DoodadVrPortcullis01 = 195437,
HordeGate1 = 195494,
HordeGate2 = 195495,
HordeGate3 = 195496,
AllianceGate1 = 195699,
AllianceGate2 = 195700,
AllianceGate3 = 195698,
DoodadNdWinterorcWallGatefxDoor01 = 195491,
// Banners
BannerWorkshopControlledH = 195130,
BannerWorkshopControlledA = 195132,
BannerWorkshopControlledN = 195133,
BannerWorkshopContestedA = 195144,
BannerWorkshopContestedH = 195145,
BannerDocksControlledA = 195149,
BannerDocksContestedA = 195150,
BannerDocksControlledH = 195151,
BannerDocksContestedH = 195152,
BannerDocksControlledN = 195157,
BannerHangarControlledA = 195153,
BannerHangarContestedA = 195154,
BannerHangarControlledH = 195155,
BannerHangarContestedH = 195156,
BannerHangarControlledN = 195158,
BannerQuarryControlledA = 195334,
BannerQuarryControlledH = 195336,
BannerQuarryContestedA = 195335,
BannerQuarryContestedH = 195337,
BannerQuarryControlledN = 195338,
BannerRefineryControlledA = 195339,
BannerRefineryControlledH = 195341,
BannerRefineryContestedA = 195340,
BannerRefineryContestedH = 195342,
BannerRefineryControlledN = 195343,
BannerHordeKeepControlledA = 195391,
BannerHordeKeepControlledH = 195393,
BannerHordeKeepContestedA = 195392,
BannerHordeKeepContestedH = 195394,
BannerAllianceKeepControlledA = 195396,
BannerAllianceKeepControlledH = 195398,
BannerAllianceKeepContestedA = 195397,
BannerAllianceKeepContestedH = 195399,
KeepGateH = 195223,
KeepGateA = 195451,
KeepGate2A = 195452,
HordeGunship = 195276,
AllianceGunship = 195121
}
enum WorldStateIds
{
AllianceReinforcementsSet = 4221,
HordeReinforcementsSet = 4222,
AllianceReinforcements = 4226,
HordeReinforcements = 4227,
MaxReinforcements = 17377,
GateFrontHWsClosed = 4317,
GateWestHWsClosed = 4318,
GateEastHWsClosed = 4319,
GateFrontAWsClosed = 4328,
GateWestAWsClosed = 4327,
GateEastAWsClosed = 4326,
GateFrontHWsOpen = 4322,
GateWestHWsOpen = 4321,
GateEastHWsOpen = 4320,
GateFrontAWsOpen = 4323,
GateWestAWsOpen = 4324,
GateEastAWsOpen = 4325,
DocksUncontrolled = 4301,
DocksConflictA = 4305,
DocksConflictH = 4302,
DocksControlledA = 4304,
DocksControlledH = 4303,
HangarUncontrolled = 4296,
HangarConflictA = 4300,
HangarConflictH = 4297,
HangarControlledA = 4299,
HangarControlledH = 4298,
QuarryUncontrolled = 4306,
QuarryConflictA = 4310,
QuarryConflictH = 4307,
QuarryControlledA = 4309,
QuarryControlledH = 4308,
RefineryUncontrolled = 4311,
RefineryConflictA = 4315,
RefineryConflictH = 4312,
RefineryControlledA = 4314,
RefineryControlledH = 4313,
WorkshopUncontrolled = 4294,
WorkshopConflictA = 4228,
WorkshopConflictH = 4293,
WorkshopControlledA = 4229,
WorkshopControlledH = 4230,
AllianceKeepUncontrolled = 4341,
AllianceKeepConflictA = 4342,
AllianceKeepConflictH = 4343,
AllianceKeepControlledA = 4339,
AllianceKeepControlledH = 4340,
HordeKeepUncontrolled = 4346,
HordeKeepConflictA = 4347,
HordeKeepConflictH = 4348,
HordeKeepControlledA = 4344,
HordeKeepControlledH = 4345
}
struct Misc
{
public const ushort MAX_REINFORCEMENTS = 400;
public static TimeSpan IOC_RESOURCE_TIMER = TimeSpan.FromSeconds(45);
public static Position[] GunshipTeleportTriggerPosition =
{
new(11.69964981079101562f, 0.034145999699831008f, 20.62075996398925781f, 3.211405754089355468f),
new(7.30560922622680664f, -0.09524600207805633f, 34.51021575927734375f, 3.159045934677124023f)
};
public static IoCStaticNodeInfo[] nodePointInitial =
{
new(NodePointType.Refinery, 35377, 35378, 35379, 35380, WorldStateIds.RefineryUncontrolled, WorldStateIds.RefineryConflictA, WorldStateIds.RefineryConflictH, WorldStateIds.RefineryControlledA, WorldStateIds.RefineryControlledH),
new(NodePointType.Quarry, 35373, 35374, 35375, 35376, WorldStateIds.QuarryUncontrolled, WorldStateIds.QuarryConflictA, WorldStateIds.QuarryConflictH, WorldStateIds.QuarryControlledA, WorldStateIds.QuarryControlledH),
new(NodePointType.Docks, 35365, 35366, 35367, 35368, WorldStateIds.DocksUncontrolled, WorldStateIds.DocksConflictA, WorldStateIds.DocksConflictH, WorldStateIds.DocksControlledA, WorldStateIds.DocksControlledH),
new(NodePointType.Hangar, 35369, 35370, 35371, 35372, WorldStateIds.HangarUncontrolled, WorldStateIds.HangarConflictA, WorldStateIds.HangarConflictH, WorldStateIds.HangarControlledA, WorldStateIds.HangarControlledH),
new(NodePointType.Workshop, 35278, 35286, 35279, 35280, WorldStateIds.WorkshopUncontrolled, WorldStateIds.WorkshopConflictA, WorldStateIds.WorkshopConflictH, WorldStateIds.WorkshopControlledA, WorldStateIds.WorkshopControlledH),
new(NodePointType.GraveyardA, 35461, 35459, 35463, 35466, WorldStateIds.AllianceKeepUncontrolled, WorldStateIds.AllianceKeepConflictA, WorldStateIds.AllianceKeepConflictH, WorldStateIds.AllianceKeepControlledA, WorldStateIds.AllianceKeepControlledH),
new(NodePointType.GraveyardH, 35462, 35460, 35464, 35465, WorldStateIds.HordeKeepUncontrolled, WorldStateIds.HordeKeepConflictA, WorldStateIds.HordeKeepConflictH, WorldStateIds.HordeKeepControlledA, WorldStateIds.HordeKeepControlledH)
};
}
// I.E: Hangar, Quarry, Graveyards .. etc
struct IoCStaticNodeInfo
{
public NodePointType NodeType;
public uint AssaultedTextId;
public uint DefendedTextId;
public uint AllianceTakenTextId;
public uint HordeTakenTextId;
public int UncontrolledWorldState;
public int ConflictAWorldState;
public int ConflictHWorldState;
public int ControlledAWorldState;
public int ControlledHWorldState;
public IoCStaticNodeInfo(NodePointType nodeType, uint assaultedTextId, uint defendedTextId, uint allianceTakenTextId, uint hordeTakenTextId, WorldStateIds uncontrolledWorldState, WorldStateIds conflictAWorldState, WorldStateIds conflictHWorldState, WorldStateIds controlledAWorldState, WorldStateIds controlledHWorldState)
{
NodeType = nodeType;
AssaultedTextId = assaultedTextId;
DefendedTextId = defendedTextId;
AllianceTakenTextId = allianceTakenTextId;
HordeTakenTextId = hordeTakenTextId;
UncontrolledWorldState = (int)uncontrolledWorldState;
ConflictAWorldState = (int)conflictAWorldState;
ConflictHWorldState = (int)conflictHWorldState;
ControlledAWorldState = (int)controlledAWorldState;
ControlledHWorldState = (int)controlledHWorldState;
}
}
class ICNodePoint
{
NodeState _state;
int _lastControlled;
IoCStaticNodeInfo _nodeInfo;
public ICNodePoint(NodeState state, IoCStaticNodeInfo nodeInfo)
{
_state = state;
_nodeInfo = nodeInfo;
switch (state)
{
case NodeState.ControlledH:
_lastControlled = BattleGroundTeamId.Horde;
break;
case NodeState.ControlledA:
_lastControlled = BattleGroundTeamId.Alliance;
break;
case NodeState.ConflictA:
case NodeState.ConflictH:
case NodeState.Neutral:
_lastControlled = BattleGroundTeamId.Neutral;
break;
}
}
public NodeState GetState() { return _state; }
public bool IsContested()
{
return _state == NodeState.ConflictA || _state == NodeState.ConflictH;
}
public int GetLastControlledTeam() { return _lastControlled; }
public IoCStaticNodeInfo GetNodeInfo() { return _nodeInfo; }
public void UpdateState(NodeState state)
{
switch (state)
{
case NodeState.ControlledA:
_lastControlled = BattleGroundTeamId.Alliance;
break;
case NodeState.ControlledH:
_lastControlled = BattleGroundTeamId.Horde;
break;
case NodeState.Neutral:
_lastControlled = BattleGroundTeamId.Neutral;
break;
case NodeState.ConflictA:
case NodeState.ConflictH:
break;
}
_state = state;
}
}
[Script(nameof(battleground_isle_of_conquest), 628)]
class battleground_isle_of_conquest : BattlegroundScript
{
ushort[] _factionReinforcements = new ushort[SharedConst.PvpTeamsCount];
GateState[] _gateStatus = new GateState[6];
ICNodePoint[] _nodePoints = new ICNodePoint[7];
ObjectGuid[] _gunshipGUIDs = new ObjectGuid[SharedConst.PvpTeamsCount];
List<ObjectGuid> _teleporterGUIDs = new();
List<ObjectGuid> _teleporterEffectGUIDs = new();
List<ObjectGuid> _mainGateDoorGUIDs = new();
List<ObjectGuid> _portcullisGUIDs = new();
List<ObjectGuid> _wallGUIDs = new();
List<ObjectGuid>[] _cannonGUIDs = new List<ObjectGuid>[SharedConst.PvpTeamsCount];
List<ObjectGuid>[] _keepGateGUIDs = new List<ObjectGuid>[SharedConst.PvpTeamsCount];
ObjectGuid[] _keepBannerGUIDs = new ObjectGuid[SharedConst.PvpTeamsCount];
ObjectGuid _gunshipTeleportTarget;
TimeTracker _resourceTimer;
public battleground_isle_of_conquest(BattlegroundMap map) : base(map)
{
_factionReinforcements = [Misc.MAX_REINFORCEMENTS, Misc.MAX_REINFORCEMENTS];
_gateStatus = [GateState.Ok, GateState.Ok, GateState.Ok, GateState.Ok, GateState.Ok, GateState.Ok];
for (var i = 0; i < SharedConst.PvpTeamsCount; i++)
{
_cannonGUIDs[i] = new List<ObjectGuid>();
_keepGateGUIDs[i] = new List<ObjectGuid>();
}
_nodePoints[(int)NodePointType.Refinery] = new(NodeState.Neutral, Misc.nodePointInitial[(int)NodePointType.Refinery]);
_nodePoints[(int)NodePointType.Quarry] = new(NodeState.Neutral, Misc.nodePointInitial[(int)NodePointType.Quarry]);
_nodePoints[(int)NodePointType.Docks] = new(NodeState.Neutral, Misc.nodePointInitial[(int)NodePointType.Docks]);
_nodePoints[(int)NodePointType.Hangar] = new(NodeState.Neutral, Misc.nodePointInitial[(int)NodePointType.Hangar]);
_nodePoints[(int)NodePointType.Workshop] = new(NodeState.Neutral, Misc.nodePointInitial[(int)NodePointType.Workshop]);
_nodePoints[(int)NodePointType.GraveyardA] = new(NodeState.ControlledA, Misc.nodePointInitial[(int)NodePointType.GraveyardA]);
_nodePoints[(int)NodePointType.GraveyardH] = new(NodeState.ControlledH, Misc.nodePointInitial[(int)NodePointType.GraveyardH]);
_resourceTimer.Reset(Misc.IOC_RESOURCE_TIMER);
}
public override void OnUpdate(uint diff)
{
base.OnUpdate(diff);
if (battleground.GetStatus() != BattlegroundStatus.InProgress)
return;
_scheduler.Update(diff);
_resourceTimer.Update(diff);
if (_resourceTimer.Passed())
{
for (byte i = 0; i < (int)NodePointType.Docks; ++i)
{
if (_nodePoints[i].GetLastControlledTeam() != BattleGroundTeamId.Neutral && !_nodePoints[i].IsContested())
{
_factionReinforcements[_nodePoints[i].GetLastControlledTeam()] += 1;
battleground.RewardHonorToTeam((uint)HonorRewards.ResourceAmount, _nodePoints[i].GetLastControlledTeam() == BattleGroundTeamId.Alliance ? Team.Alliance : Team.Horde);
UpdateWorldState((int)(_nodePoints[i].GetLastControlledTeam() == BattleGroundTeamId.Alliance ? WorldStateIds.AllianceReinforcements : WorldStateIds.HordeReinforcements), _factionReinforcements[_nodePoints[i].GetLastControlledTeam()]);;
}
}
_resourceTimer.Reset(Misc.IOC_RESOURCE_TIMER);
}
}
public override void OnStart()
{
base.OnStart();
void gameobjectAction(List<ObjectGuid> guids, Action<GameObject> action)
{
foreach (ObjectGuid guid in guids)
{
GameObject gameObject = battlegroundMap.GetGameObject(guid);
if (gameObject != null)
action(gameObject);
}
}
gameobjectAction(_mainGateDoorGUIDs, gameobject =>
{
gameobject.UseDoorOrButton();
gameobject.DespawnOrUnsummon(TimeSpan.FromSeconds(20));
});
gameobjectAction(_portcullisGUIDs, gameobject => gameobject.UseDoorOrButton());
gameobjectAction(_teleporterGUIDs, gameobject => gameobject.RemoveFlag(GameObjectFlags.NotSelectable));
gameobjectAction(_teleporterEffectGUIDs, gameobject => gameobject.SetGoState(GameObjectState.Active));
_scheduler.Schedule(TimeSpan.FromSeconds(20), _ =>
{
foreach (ObjectGuid guid in _wallGUIDs)
{
GameObject gameobject = battlegroundMap.GetGameObject(guid);
if (gameobject != null)
gameobject.SetDestructibleState(GameObjectDestructibleState.Damaged);
}
});
}
public override void OnUnitKilled(Creature unit, Unit killer)
{
base.OnUnitKilled(unit, killer);
if (battleground.GetStatus() != BattlegroundStatus.InProgress)
return;
switch ((CreatureIds)unit.GetEntry())
{
case CreatureIds.HighCommanderHalfordWyrmbane:
battleground.RewardHonorToTeam((uint)HonorRewards.WinnerAmount, Team.Horde);
battleground.EndBattleground(Team.Horde);
break;
case CreatureIds.OverlordAgmar:
battleground.RewardHonorToTeam((uint)HonorRewards.WinnerAmount, Team.Alliance);
battleground.EndBattleground(Team.Alliance);
break;
}
//Achievement Mowed Down
// TO-DO: This should be done on the script of each vehicle of the BG.
if (unit.IsVehicle())
{
Player killerPlayer = killer.GetCharmerOrOwnerPlayerOrPlayerItself();
if (killerPlayer != null)
killerPlayer.CastSpell(killerPlayer, (uint)SpellIds.DestroyedVehicleAchievement, true);
}
}
public override void OnPlayerKilled(Player player, Player killer)
{
base.OnPlayerKilled(player, killer);
if (battleground.GetStatus() != BattlegroundStatus.InProgress)
return;
int victimTeamId = Battleground.GetTeamIndexByTeamId(battleground.GetPlayerTeam(player.GetGUID()));
_factionReinforcements[victimTeamId] -= 1;
UpdateWorldState((int)(battleground.GetPlayerTeam(player.GetGUID()) == Team.Alliance ? WorldStateIds.AllianceReinforcements : WorldStateIds.HordeReinforcements), _factionReinforcements[victimTeamId]);
// we must end the battleground
if (_factionReinforcements[victimTeamId] < 1)
battleground.EndBattleground(battleground.GetPlayerTeam(killer.GetGUID()));
}
static uint GetGateIDFromEntry(uint id)
{
switch ((GameObjectIds)id)
{
case GameObjectIds.HordeGate1:
return (uint)DoorList.HFront;
case GameObjectIds.HordeGate2:
return (uint)DoorList.HWest;
case GameObjectIds.HordeGate3:
return (uint)DoorList.HEast;
case GameObjectIds.AllianceGate3:
return (uint)DoorList.AFront;
case GameObjectIds.AllianceGate1:
return (uint)DoorList.AWest;
case GameObjectIds.AllianceGate2:
return (uint)DoorList.AEast;
default:
return 0;
}
}
static int GetWorldStateFromGateEntry(uint id, bool open)
{
WorldStateIds uws = 0;
switch ((GameObjectIds)id)
{
case GameObjectIds.HordeGate1:
uws = (open ? WorldStateIds.GateFrontHWsOpen : WorldStateIds.GateFrontHWsClosed);
break;
case GameObjectIds.HordeGate2:
uws = (open ? WorldStateIds.GateWestHWsOpen : WorldStateIds.GateWestHWsClosed);
break;
case GameObjectIds.HordeGate3:
uws = (open ? WorldStateIds.GateEastHWsOpen : WorldStateIds.GateEastHWsClosed);
break;
case GameObjectIds.AllianceGate3:
uws = (open ? WorldStateIds.GateFrontAWsOpen : WorldStateIds.GateFrontAWsOpen);
break;
case GameObjectIds.AllianceGate1:
uws = (open ? WorldStateIds.GateWestAWsOpen : WorldStateIds.GateWestAWsClosed);
break;
case GameObjectIds.AllianceGate2:
uws = (open ? WorldStateIds.GateEastAWsOpen : WorldStateIds.GateEastAWsClosed);
break;
default:
break;
}
return (int)uws;
}
void UpdateNodeWorldState(ICNodePoint node)
{
UpdateWorldState(node.GetNodeInfo().ConflictAWorldState, node.GetState() == NodeState.ConflictA);
UpdateWorldState(node.GetNodeInfo().ConflictHWorldState, node.GetState() == NodeState.ConflictH);
UpdateWorldState(node.GetNodeInfo().ControlledAWorldState, node.GetState() == NodeState.ControlledA);
UpdateWorldState(node.GetNodeInfo().ControlledHWorldState, node.GetState() == NodeState.ControlledH);
UpdateWorldState(node.GetNodeInfo().UncontrolledWorldState, node.GetState() == NodeState.Neutral);
}
static NodePointType BannerToNodeType(uint bannerId)
{
switch ((GameObjectIds)bannerId)
{
case GameObjectIds.BannerAllianceKeepContestedA:
case GameObjectIds.BannerAllianceKeepContestedH:
case GameObjectIds.BannerAllianceKeepControlledA:
case GameObjectIds.BannerAllianceKeepControlledH:
return NodePointType.GraveyardA;
case GameObjectIds.BannerHordeKeepContestedA:
case GameObjectIds.BannerHordeKeepContestedH:
case GameObjectIds.BannerHordeKeepControlledA:
case GameObjectIds.BannerHordeKeepControlledH:
return NodePointType.GraveyardH;
case GameObjectIds.BannerDocksContestedA:
case GameObjectIds.BannerDocksContestedH:
case GameObjectIds.BannerDocksControlledA:
case GameObjectIds.BannerDocksControlledH:
case GameObjectIds.BannerDocksControlledN:
return NodePointType.Docks;
case GameObjectIds.BannerHangarContestedA:
case GameObjectIds.BannerHangarContestedH:
case GameObjectIds.BannerHangarControlledA:
case GameObjectIds.BannerHangarControlledH:
case GameObjectIds.BannerHangarControlledN:
return NodePointType.Hangar;
case GameObjectIds.BannerWorkshopContestedA:
case GameObjectIds.BannerWorkshopContestedH:
case GameObjectIds.BannerWorkshopControlledA:
case GameObjectIds.BannerWorkshopControlledH:
case GameObjectIds.BannerWorkshopControlledN:
return NodePointType.Workshop;
case GameObjectIds.BannerQuarryContestedA:
case GameObjectIds.BannerQuarryContestedH:
case GameObjectIds.BannerQuarryControlledA:
case GameObjectIds.BannerQuarryControlledH:
case GameObjectIds.BannerQuarryControlledN:
return NodePointType.Quarry;
case GameObjectIds.BannerRefineryContestedA:
case GameObjectIds.BannerRefineryContestedH:
case GameObjectIds.BannerRefineryControlledA:
case GameObjectIds.BannerRefineryControlledH:
case GameObjectIds.BannerRefineryControlledN:
return NodePointType.Refinery;
default:
break;
}
return NodePointType.MaxNodeTypes;
}
void HandleCapturedNodes(ICNodePoint node)
{
if (node.GetLastControlledTeam() == BattleGroundTeamId.Neutral)
return;
switch (node.GetNodeInfo().NodeType)
{
case NodePointType.Quarry:
case NodePointType.Refinery:
battlegroundMap.UpdateAreaDependentAuras();
break;
case NodePointType.Hangar:
Transport transport = battlegroundMap.GetTransport(_gunshipGUIDs[node.GetLastControlledTeam()]);
if (transport != null)
{
// Can't have this in spawngroup, creature is on a transport
TempSummon trigger = transport.SummonPassenger((uint)CreatureIds.WorldTriggerNotFloating, Misc.GunshipTeleportTriggerPosition[node.GetLastControlledTeam()], TempSummonType.ManualDespawn);
if (trigger != null)
_gunshipTeleportTarget = trigger.GetGUID();
transport.EnableMovement(true);
}
foreach (ObjectGuid guid in _cannonGUIDs[node.GetLastControlledTeam()])
{
Creature cannon = battlegroundMap.GetCreature(guid);
if (cannon != null)
cannon.SetUninteractible(false);
}
break;
default:
break;
}
}
public override void OnCreatureCreate(Creature creature)
{
base.OnCreatureCreate(creature);
if (creature.HasStringId("bg_ioc_faction_1735"))
creature.SetFaction(FactionTemplates.HordeGenericWg);
else if (creature.HasStringId("bg_ioc_faction_1732"))
creature.SetFaction(FactionTemplates.AllianceGenericWg);
switch ((CreatureIds)creature.GetEntry())
{
case CreatureIds.AllianceGunshipCannon:
_cannonGUIDs[BattleGroundTeamId.Alliance].Add(creature.GetGUID());
creature.SetUninteractible(true);
creature.SetControlled(true, UnitState.Root);
break;
case CreatureIds.HordeGunshipCannon:
_cannonGUIDs[BattleGroundTeamId.Horde].Add(creature.GetGUID());
creature.SetUninteractible(true);
creature.SetControlled(true, UnitState.Root);
break;
default:
break;
}
}
public override void OnGameObjectCreate(GameObject gameobject)
{
base.OnGameObjectCreate(gameobject);
if (gameobject.IsDestructibleBuilding())
_wallGUIDs.Add(gameobject.GetGUID());
if (gameobject.HasStringId("bg_ioc_faction_1735"))
gameobject.SetFaction(FactionTemplates.HordeGenericWg);
else if (gameobject.HasStringId("bg_ioc_faction_1732"))
gameobject.SetFaction(FactionTemplates.AllianceGenericWg);
switch ((GameObjectIds)gameobject.GetEntry())
{
case GameObjectIds.Teleporter1:
case GameObjectIds.Teleporter2:
case GameObjectIds.Teleporter3:
case GameObjectIds.Teleporter4:
_teleporterGUIDs.Add(gameobject.GetGUID());
break;
case GameObjectIds.TeleporterEffectsA:
case GameObjectIds.TeleporterEffectsH:
_teleporterEffectGUIDs.Add(gameobject.GetGUID());
break;
case GameObjectIds.DoodadNdHumanGateClosedfxDoor01:
case GameObjectIds.DoodadNdWinterorcWallGatefxDoor01:
_mainGateDoorGUIDs.Add(gameobject.GetGUID());
break;
case GameObjectIds.DoodadHuPortcullis01:
case GameObjectIds.DoodadVrPortcullis01:
_portcullisGUIDs.Add(gameobject.GetGUID());
break;
case GameObjectIds.KeepGateH:
_keepGateGUIDs[BattleGroundTeamId.Horde].Add(gameobject.GetGUID());
break;
case GameObjectIds.KeepGateA:
case GameObjectIds.KeepGate2A:
_keepGateGUIDs[BattleGroundTeamId.Alliance].Add(gameobject.GetGUID());
break;
case GameObjectIds.BannerAllianceKeepControlledA:
_keepBannerGUIDs[BattleGroundTeamId.Alliance] = gameobject.GetGUID();
break;
case GameObjectIds.BannerAllianceKeepControlledH:
_keepBannerGUIDs[BattleGroundTeamId.Horde] = gameobject.GetGUID();
break;
default:
break;
}
}
public override void OnInit()
{
base.OnInit();
Transport transport = Global.TransportMgr.CreateTransport((uint)GameObjectIds.HordeGunship, battlegroundMap);
if (transport != null)
{
_gunshipGUIDs[BattleGroundTeamId.Horde] = transport.GetGUID();
transport.EnableMovement(false);
}
transport = Global.TransportMgr.CreateTransport((uint)GameObjectIds.AllianceGunship, battlegroundMap);
if (transport != null)
{
_gunshipGUIDs[BattleGroundTeamId.Alliance] = transport.GetGUID();
transport.EnableMovement(false);
}
}
public override void DoAction(uint actionId, WorldObject source, WorldObject target)
{
base.DoAction(actionId, source, target);
switch ((Actions)actionId)
{
case Actions.InteractCapturableObject:
OnPlayerInteractWithBanner(source?.ToPlayer(), target?.ToGameObject());
break;
case Actions.CaptureCapturableObject:
HandleCaptureNodeAction(target?.ToGameObject());
break;
default:
break;
}
}
void OnPlayerInteractWithBanner(Player player, GameObject banner)
{
if (player == null || banner == null)
return;
Team playerTeam = battleground.GetPlayerTeam(player.GetGUID());
int playerTeamId = Battleground.GetTeamIndexByTeamId(playerTeam);
NodePointType nodeType = BannerToNodeType(banner.GetEntry());
if (nodeType == NodePointType.MaxNodeTypes)
return;
ICNodePoint node = _nodePoints[(int)nodeType];
bool assault = false;
bool defend = false;
switch (node.GetState())
{
case NodeState.Neutral:
assault = true;
break;
case NodeState.ControlledH:
assault = playerTeamId != BattleGroundTeamId.Horde;
break;
case NodeState.ControlledA:
assault = playerTeamId != BattleGroundTeamId.Alliance;
break;
case NodeState.ConflictA:
defend = playerTeamId == node.GetLastControlledTeam();
assault = !defend && playerTeamId == BattleGroundTeamId.Horde;
break;
case NodeState.ConflictH:
defend = playerTeamId == node.GetLastControlledTeam();
assault = !defend && playerTeamId == BattleGroundTeamId.Alliance;
break;
}
if (assault)
OnPlayerAssaultNode(player, node);
else if (defend)
OnPlayerDefendNode(player, node);
battlegroundMap.UpdateSpawnGroupConditions();
}
void OnPlayerAssaultNode(Player player, ICNodePoint node)
{
if (player == null)
return;
Team playerTeam = battleground.GetPlayerTeam(player.GetGUID());
int playerTeamId = Battleground.GetTeamIndexByTeamId(playerTeam);
NodeState newState = playerTeamId == BattleGroundTeamId.Horde ? NodeState.ConflictH : NodeState.ConflictA;
node.UpdateState(newState);
battleground.UpdatePvpStat(player, (uint)PvpStats.BasesAssaulted, 1);
ChatMsg messageType = playerTeamId == BattleGroundTeamId.Alliance ? ChatMsg.BgSystemAlliance : ChatMsg.BgSystemHorde;
battleground.SendBroadcastText(node.GetNodeInfo().AssaultedTextId, messageType, player);
UpdateNodeWorldState(node);
// apply side effects of each node, only if it wasn't neutral before
if (node.GetLastControlledTeam() == BattleGroundTeamId.Neutral)
return;
switch (node.GetNodeInfo().NodeType)
{
case NodePointType.Hangar:
Transport transport = battlegroundMap.GetTransport(_gunshipGUIDs[node.GetLastControlledTeam()]);
if (transport != null)
transport.EnableMovement(false);
foreach (ObjectGuid guid in _cannonGUIDs[node.GetLastControlledTeam()])
{
Creature cannon = battlegroundMap.GetCreature(guid);
if (cannon != null)
{
cannon.GetVehicleKit().RemoveAllPassengers();
cannon.SetUninteractible(true);
}
}
// Despawn teleport trigger target
Creature creature = battlegroundMap.GetCreature(_gunshipTeleportTarget);
if (creature != null)
creature.DespawnOrUnsummon();
break;
default:
break;
}
}
void OnPlayerDefendNode(Player player, ICNodePoint node)
{
if (player == null)
return;
Team playerTeam = battleground.GetPlayerTeam(player.GetGUID());
int playerTeamId = Battleground.GetTeamIndexByTeamId(playerTeam);
node.UpdateState(playerTeamId == BattleGroundTeamId.Horde ? NodeState.ControlledH : NodeState.ControlledA);
HandleCapturedNodes(node);
battleground.UpdatePvpStat(player, (uint)PvpStats.BasesDefended, 1);
ChatMsg messageType = playerTeamId == BattleGroundTeamId.Alliance ? ChatMsg.BgSystemAlliance : ChatMsg.BgSystemHorde;
battleground.SendBroadcastText(node.GetNodeInfo().DefendedTextId, messageType, player);
UpdateNodeWorldState(node);
}
public override void ProcessEvent(WorldObject target, uint eventId, WorldObject invoker)
{
base.ProcessEvent(target, eventId, invoker);
GameObject obj = target?.ToGameObject();
if (obj != null && obj.GetGoType() == GameObjectTypes.DestructibleBuilding)
if (obj.GetGoInfo().DestructibleBuilding.DestroyedEvent == eventId)
OnGateDestroyed(obj, invoker);
}
void HandleCaptureNodeAction(GameObject banner)
{
if (banner == null)
return;
NodePointType nodeType = BannerToNodeType(banner.GetEntry());
if (nodeType == NodePointType.MaxNodeTypes)
return;
ICNodePoint node = _nodePoints[(int)nodeType];
if (node.GetState() == NodeState.ConflictH)
node.UpdateState(NodeState.ControlledH);
else if (node.GetState() == NodeState.ConflictA)
node.UpdateState(NodeState.ControlledA);
HandleCapturedNodes(node);
ChatMsg messageType = node.GetLastControlledTeam() == BattleGroundTeamId.Alliance ? ChatMsg.BgSystemAlliance : ChatMsg.BgSystemHorde;
uint textId = node.GetLastControlledTeam() == BattleGroundTeamId.Alliance ? node.GetNodeInfo().AllianceTakenTextId : node.GetNodeInfo().HordeTakenTextId;
battleground.SendBroadcastText(textId, messageType);
UpdateNodeWorldState(node);
}
void OnGateDestroyed(GameObject gate, WorldObject destroyer)
{
_gateStatus[GetGateIDFromEntry(gate.GetEntry())] = GateState.Destroyed;
int wsGateOpen = GetWorldStateFromGateEntry(gate.GetEntry(), true);
int wsGateClosed = GetWorldStateFromGateEntry(gate.GetEntry(), false);
if (wsGateOpen != 0)
{
UpdateWorldState(wsGateClosed, 0);
UpdateWorldState(wsGateOpen, 1);
}
int teamId;
BroadcastTextIds textId;
ChatMsg msgType;
switch ((GameObjectIds)gate.GetEntry())
{
case GameObjectIds.HordeGate1:
textId = BroadcastTextIds.FrontGateHordeDestroyed;
msgType = ChatMsg.BgSystemAlliance;
teamId = BattleGroundTeamId.Horde;
break;
case GameObjectIds.HordeGate2:
textId = BroadcastTextIds.WestGateHordeDestroyed;
msgType = ChatMsg.BgSystemAlliance;
teamId = BattleGroundTeamId.Horde;
break;
case GameObjectIds.HordeGate3:
textId = BroadcastTextIds.EastGateHordeDestroyed;
msgType = ChatMsg.BgSystemAlliance;
teamId = BattleGroundTeamId.Horde;
break;
case GameObjectIds.AllianceGate1:
textId = BroadcastTextIds.WestGateAllianceDestroyed;
msgType = ChatMsg.BgSystemHorde;
teamId = BattleGroundTeamId.Alliance;
break;
case GameObjectIds.AllianceGate2:
textId = BroadcastTextIds.EastGateAllianceDestroyed;
msgType = ChatMsg.BgSystemHorde;
teamId = BattleGroundTeamId.Alliance;
break;
case GameObjectIds.AllianceGate3:
textId = BroadcastTextIds.FrontGateAllianceDestroyed;
msgType = ChatMsg.BgSystemHorde;
teamId = BattleGroundTeamId.Alliance;
break;
default:
return;
}
if (teamId != BattleGroundTeamId.Neutral)
{
var keepGates = _keepGateGUIDs[teamId];
ObjectGuid bannerGuid = _keepBannerGUIDs[teamId];
foreach (ObjectGuid guid in keepGates)
{
GameObject keepGate = battlegroundMap.GetGameObject(guid);
if (keepGate != null)
keepGate.UseDoorOrButton();
}
GameObject banner = battlegroundMap.GetGameObject(bannerGuid);
if (banner != null)
banner.RemoveFlag(GameObjectFlags.NotSelectable);
}
battleground.SendBroadcastText((uint)textId, msgType, destroyer);
}
}
}
@@ -0,0 +1,45 @@
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
namespace Scripts.Battlegrounds.IsleOfConquest
{
enum CreatureIds
{
HighCommanderHalfordWyrmbane = 34924, // Alliance Boss
OverlordAgmar = 34922, // Horde Boss
KorKronGuard = 34918, // Horde Guard
SevenThLegionInfantry = 34919, // Alliance Guard
KeepCannon = 34944,
Demolisher = 34775,
SiegeEngineH = 35069,
SiegeEngineA = 34776,
GlaiveThrowerA = 34802,
GlaiveThrowerH = 35273,
Catapult = 34793,
HordeGunshipCannon = 34935,
AllianceGunshipCannon = 34929,
HordeGunshipCaptain = 35003,
AllianceGunshipCaptain = 34960,
WorldTriggerNotFloating = 34984,
WorldTriggerAllianceFriendly = 20213,
WorldTriggerHordeFriendly = 20212
}
enum SpellIds
{
OilRefinery = 68719,
Quarry = 68720,
Parachute = 66656,
SlowFall = 12438,
DestroyedVehicleAchievement = 68357,
BackDoorJobAchievement = 68502,
DrivingCreditDemolisher = 68365,
DrivingCreditGlaive = 68363,
DrivingCreditSiege = 68364,
DrivingCreditCatapult = 68362,
SimpleTeleport = 12980,
TeleportVisualOnly = 51347,
ParachuteIc = 66657,
LaunchNoFallingDamage = 66251
}
}
@@ -0,0 +1,70 @@
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
using Framework.Constants;
using Game.BattleGrounds;
using Game.Entities;
using Game.Maps;
using Game.Scripting;
using System;
using System.Collections.Generic;
namespace Scripts.Battlegrounds.NagrandArena
{
enum GameObjectIds
{
Door1 = 183978,
Door2 = 183980,
Door3 = 183977,
Door4 = 183979,
Buff1 = 184663,
Buff2 = 184664
}
[Script(nameof(arena_nagrand), 1505)]
class arena_nagrand : ArenaScript
{
List<ObjectGuid> _doorGUIDs = new();
public arena_nagrand(BattlegroundMap map) : base(map) { }
public override void OnUpdate(uint diff)
{
_scheduler.Update(diff);
}
public override void OnInit()
{
AddDoor(GameObjectIds.Door1, 4031.854f, 2966.833f, 12.6462f, -2.648788f, 0, 0, 0.9697962f, -0.2439165f);
AddDoor(GameObjectIds.Door2, 4081.179f, 2874.97f, 12.39171f, 0.4928045f, 0, 0, 0.2439165f, 0.9697962f);
AddDoor(GameObjectIds.Door3, 4023.709f, 2981.777f, 10.70117f, -2.648788f, 0, 0, 0.9697962f, -0.2439165f);
AddDoor(GameObjectIds.Door4, 4090.064f, 2858.438f, 10.23631f, 0.4928045f, 0, 0, 0.2439165f, 0.9697962f);
}
public override void OnStart()
{
foreach (ObjectGuid guid in _doorGUIDs)
{
GameObject door = battlegroundMap.GetGameObject(guid);
if (door != null)
{
door.UseDoorOrButton();
door.DespawnOrUnsummon(TimeSpan.FromMinutes(5));
}
}
_scheduler.Schedule(TimeSpan.FromMinutes(1), _ =>
{
CreateObject((uint)GameObjectIds.Buff1, 4009.189941f, 2895.250000f, 13.052700f, -1.448624f, 0, 0, 0.6626201f, -0.7489557f);
CreateObject((uint)GameObjectIds.Buff2, 4103.330078f, 2946.350098f, 13.051300f, -0.06981307f, 0, 0, 0.03489945f, -0.9993908f);
});
}
void AddDoor(GameObjectIds entry, float x, float y, float z, float o, float rotation0, float rotation1, float rotation2, float rotation3, GameObjectState goState = GameObjectState.Ready)
{
GameObject go = CreateObject((uint)entry, x, y, z, o, rotation0, rotation1, rotation2, rotation3, goState);
if (go != null)
_doorGUIDs.Add(go.GetGUID());
}
}
}
@@ -0,0 +1,293 @@
using Game.Entities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Framework.Dynamic;
using Game.Scripting;
using Game.BattleGrounds;
using Game.Maps;
using Framework.Constants;
namespace Scripts.Battlegrounds.RingOfValor
{
enum GameObjectIds
{
Buff1 = 184663,
Buff2 = 184664,
Fire1 = 192704,
Fire2 = 192705,
Firedoor2 = 192387,
Firedoor1 = 192388,
Pulley1 = 192389,
Pulley2 = 192390,
Gear1 = 192393,
Gear2 = 192394,
Elevator1 = 194582,
Elevator2 = 194586,
PilarCollision1 = 194580, // Axe
PilarCollision2 = 194579, // Arena // Big
PilarCollision3 = 194581, // Lightning
PilarCollision4 = 194578, // Ivory // Big
Pilar1 = 194583, // Axe
Pilar2 = 194584, // Arena
Pilar3 = 194585, // Lightning
Pilar4 = 194587 // Ivory
}
enum Data
{
StateOpenFences,
StateSwitchPillars,
StateCloseFire,
PillarSwitchTimer = 25000,
FireToPillarTimer = 20000,
CloseFireTimer = 5000,
FirstTimer = 20133,
}
[Script(nameof(arena_ring_of_valor), 618)]
class arena_ring_of_valor : ArenaScript
{
List<ObjectGuid> _elevatorGUIDs = new();
List<ObjectGuid> _gearGUIDs = new();
List<ObjectGuid> _fireGUIDs = new();
List<ObjectGuid> _firedoorGUIDs = new();
List<ObjectGuid> _pillarSmallCollisionGUIDs = new();
List<ObjectGuid> _pillarBigCollisionGUIDs = new();
List<ObjectGuid> _pillarSmallGUIDs = new();
List<ObjectGuid> _pillarBigGUIDs = new();
List<ObjectGuid> _pulleyGUIDs = new();
uint _timer;
uint _state;
bool _pillarCollision;
public arena_ring_of_valor(BattlegroundMap map) : base(map) { }
public override void OnUpdate(uint diff)
{
if (battleground.GetStatus() != BattlegroundStatus.InProgress)
return;
_scheduler.Update(diff);
if (_timer < diff)
{
switch (_state)
{
case (uint)Data.StateOpenFences:
// Open fire (only at game start)
foreach (ObjectGuid guid in _fireGUIDs)
{
GameObject go = battlegroundMap.GetGameObject(guid);
if (go != null)
go.UseDoorOrButton();
}
foreach (ObjectGuid guid in _firedoorGUIDs)
{
GameObject go = battlegroundMap.GetGameObject(guid);
if (go != null)
go.UseDoorOrButton();
}
_timer = (uint)Data.CloseFireTimer;
_state = (uint)Data.StateCloseFire;
break;
case (uint)Data.StateCloseFire:
foreach (ObjectGuid guid in _fireGUIDs)
{
GameObject go = battlegroundMap.GetGameObject(guid);
if (go != null)
go.ResetDoorOrButton();
}
foreach (ObjectGuid guid in _firedoorGUIDs)
{
GameObject go = battlegroundMap.GetGameObject(guid);
if (go != null)
go.ResetDoorOrButton();
}
// Fire got closed after five seconds, leaves twenty seconds before toggling pillars
_timer = (uint)Data.FireToPillarTimer;
_state = (uint)Data.StateSwitchPillars;
break;
case (uint)Data.StateSwitchPillars:
TogglePillarCollision();
_timer = (uint)Data.PillarSwitchTimer;
break;
default:
break;
}
}
else
_timer -= diff;
}
public override void OnInit()
{
CreateObject((uint)GameObjectIds.Elevator1, 763.536377f, -294.535767f, 0.505383f, 3.141593f, 0.0f, 0.0f, 0.0f, 0.0f);
CreateObject((uint)GameObjectIds.Elevator2, 763.506348f, -273.873352f, 0.505383f, 0.000000f, 0.0f, 0.0f, 0.0f, 0.0f);
CreateObject((uint)GameObjectIds.Fire1, 743.543457f, -283.799469f, 28.286655f, 3.141593f, 0.0f, 0.0f, 0.0f, 0.0f);
CreateObject((uint)GameObjectIds.Fire2, 782.971802f, -283.799469f, 28.286655f, 3.141593f, 0.0f, 0.0f, 0.0f, 0.0f);
CreateObject((uint)GameObjectIds.Firedoor1, 743.711060f, -284.099609f, 27.542587f, 3.141593f, 0.0f, 0.0f, 0.0f, 0.0f);
CreateObject((uint)GameObjectIds.Firedoor2, 783.221252f, -284.133362f, 27.535686f, 0.000000f, 0.0f, 0.0f, 0.0f, 0.0f);
CreateObject((uint)GameObjectIds.Gear1, 763.664551f, -261.872986f, 26.686588f, 0.000000f, 0.0f, 0.0f, 0.0f, 0.0f);
CreateObject((uint)GameObjectIds.Gear2, 763.578979f, -306.146149f, 26.665222f, 3.141593f, 0.0f, 0.0f, 0.0f, 0.0f);
CreateObject((uint)GameObjectIds.Pulley1, 700.722290f, -283.990662f, 39.517582f, 3.141593f, 0.0f, 0.0f, 0.0f, 0.0f);
CreateObject((uint)GameObjectIds.Pulley2, 826.303833f, -283.996429f, 39.517582f, 0.000000f, 0.0f, 0.0f, 0.0f, 0.0f);
CreateObject((uint)GameObjectIds.Pilar1, 763.632385f, -306.162384f, 25.909504f, 3.141593f, 0.0f, 0.0f, 0.0f, 0.0f);
CreateObject((uint)GameObjectIds.Pilar2, 723.644287f, -284.493256f, 24.648525f, 3.141593f, 0.0f, 0.0f, 0.0f, 0.0f);
CreateObject((uint)GameObjectIds.Pilar3, 763.611145f, -261.856750f, 25.909504f, 0.000000f, 0.0f, 0.0f, 0.0f, 0.0f);
CreateObject((uint)GameObjectIds.Pilar4, 802.211609f, -284.493256f, 24.648525f, 0.000000f, 0.0f, 0.0f, 0.0f, 0.0f);
CreateObject((uint)GameObjectIds.PilarCollision1, 763.632385f, -306.162384f, 30.639660f, 3.141593f, 0.0f, 0.0f, 0.0f, 0.0f);
CreateObject((uint)GameObjectIds.PilarCollision2, 723.644287f, -284.493256f, 32.382710f, 0.000000f, 0.0f, 0.0f, 0.0f, 0.0f);
CreateObject((uint)GameObjectIds.PilarCollision3, 763.611145f, -261.856750f, 30.639660f, 0.000000f, 0.0f, 0.0f, 0.0f, 0.0f);
CreateObject((uint)GameObjectIds.PilarCollision4, 802.211609f, -284.493256f, 32.382710f, 3.141593f, 0.0f, 0.0f, 0.0f, 0.0f);
}
public override void OnStart()
{
foreach (ObjectGuid guid in _elevatorGUIDs)
{
GameObject door = battlegroundMap.GetGameObject(guid);
if (door != null)
{
door.UseDoorOrButton();
door.DespawnOrUnsummon(TimeSpan.FromSeconds(5));
}
}
_state = (uint)Data.StateOpenFences;
_timer = (uint)Data.FirstTimer;
// Should be false at first, TogglePillarCollision will do it.
_pillarCollision = true;
TogglePillarCollision();
_scheduler.Schedule(TimeSpan.FromMinutes(1), _ =>
{
CreateObject((uint)GameObjectIds.Buff1, 735.551819f, -284.794678f, 28.276682f, 0.034906f, 0.0f, 0.0f, 0.0f, 0.0f);
CreateObject((uint)GameObjectIds.Buff2, 791.224487f, -284.794464f, 28.276682f, 2.600535f, 0.0f, 0.0f, 0.0f, 0.0f);
});
}
void TogglePillarCollision()
{
// Toggle visual pillars, pulley, gear, and collision based on previous state
List<ObjectGuid> smallPillarGuids = [.. _pillarSmallGUIDs, .. _gearGUIDs];
foreach (ObjectGuid guid in smallPillarGuids)
{
GameObject go = battlegroundMap.GetGameObject(guid);
if (go != null)
{
if (_pillarCollision)
go.UseDoorOrButton();
else
go.ResetDoorOrButton();
}
}
List<ObjectGuid> bigPillarGuids = [.. _pillarBigGUIDs, .. _pulleyGUIDs];
foreach (ObjectGuid guid in bigPillarGuids)
{
GameObject go = battlegroundMap.GetGameObject(guid);
if (go != null)
{
if (_pillarCollision)
go.ResetDoorOrButton();
else
go.UseDoorOrButton();
}
}
List<ObjectGuid> allObjects = [.. smallPillarGuids, .. bigPillarGuids, .. _pillarSmallCollisionGUIDs, .. _pillarBigCollisionGUIDs];
foreach (ObjectGuid guid in allObjects)
{
GameObject go = battlegroundMap.GetGameObject(guid);
if (go != null)
{
bool isCollision = false;
switch ((GameObjectIds)go.GetEntry())
{
case GameObjectIds.PilarCollision1:
case GameObjectIds.PilarCollision2:
case GameObjectIds.PilarCollision3:
case GameObjectIds.PilarCollision4:
isCollision = true;
break;
default:
break;
}
if (isCollision)
{
GameObjectState state = ((go.GetGoInfo().Door.startOpen != 0) == _pillarCollision) ? GameObjectState.Active : GameObjectState.Ready;
go.SetGoState(state);
}
foreach (var (playerGuid, _) in battleground.GetPlayers())
{
Player player = Global.ObjAccessor.FindPlayer(playerGuid);
if (player != null)
go.SendUpdateToPlayer(player);
}
}
}
_pillarCollision = !_pillarCollision;
}
public override void OnGameObjectCreate(GameObject gameobject)
{
base.OnGameObjectCreate(gameobject);
switch ((GameObjectIds)gameobject.GetEntry())
{
case GameObjectIds.Elevator1:
case GameObjectIds.Elevator2:
_elevatorGUIDs.Add(gameobject.GetGUID());
break;
case GameObjectIds.Fire1:
case GameObjectIds.Fire2:
_fireGUIDs.Add(gameobject.GetGUID());
break;
case GameObjectIds.Firedoor1:
case GameObjectIds.Firedoor2:
_firedoorGUIDs.Add(gameobject.GetGUID());
break;
case GameObjectIds.Gear1:
case GameObjectIds.Gear2:
_gearGUIDs.Add(gameobject.GetGUID());
break;
case GameObjectIds.Pilar1:
case GameObjectIds.Pilar3:
_pillarSmallGUIDs.Add(gameobject.GetGUID());
break;
case GameObjectIds.Pilar2:
case GameObjectIds.Pilar4:
_pillarBigGUIDs.Add(gameobject.GetGUID());
break;
case GameObjectIds.PilarCollision1:
case GameObjectIds.PilarCollision3:
_pillarSmallCollisionGUIDs.Add(gameobject.GetGUID());
break;
case GameObjectIds.PilarCollision2:
case GameObjectIds.PilarCollision4:
_pillarBigCollisionGUIDs.Add(gameobject.GetGUID());
break;
case GameObjectIds.Pulley1:
case GameObjectIds.Pulley2:
_pulleyGUIDs.Add(gameobject.GetGUID());
break;
default:
break;
}
}
}
}
@@ -0,0 +1,66 @@
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
using Framework.Constants;
using Game.BattleGrounds;
using Game.Entities;
using Game.Maps;
using Game.Scripting;
using System;
using System.Collections.Generic;
namespace Scripts.Battlegrounds.RuinsOfLordaeron
{
enum GameObjectIds
{
Door1 = 185918,
Door2 = 185917,
Buff1 = 184663,
Buff2 = 184664
}
[Script(nameof(arena_ruins_of_lordaeron), 572)]
class arena_ruins_of_lordaeron : ArenaScript
{
List<ObjectGuid> _doorGUIDs = new();
public arena_ruins_of_lordaeron(BattlegroundMap map) : base(map) { }
public override void OnUpdate(uint diff)
{
_scheduler.Update(diff);
}
public override void OnInit()
{
AddDoor((uint)GameObjectIds.Door1, 1293.561f, 1601.938f, 31.60557f, -1.457349f, 0, 0, -0.6658813f, 0.7460576f);
AddDoor((uint)GameObjectIds.Door2, 1278.648f, 1730.557f, 31.60557f, 1.684245f, 0, 0, 0.7460582f, 0.6658807f);
}
public override void OnStart()
{
foreach (ObjectGuid guid in _doorGUIDs)
{
GameObject door = battlegroundMap.GetGameObject(guid);
if (door != null)
{
door.UseDoorOrButton();
door.DespawnOrUnsummon(TimeSpan.FromSeconds(5));
}
}
_scheduler.Schedule(TimeSpan.FromMinutes(1), _ =>
{
CreateObject((uint)GameObjectIds.Buff1, 1328.719971f, 1632.719971f, 36.730400f, -1.448624f, 0, 0, 0.6626201f, -0.7489557f);
CreateObject((uint)GameObjectIds.Buff2, 1243.300049f, 1699.170044f, 34.872601f, -0.06981307f, 0, 0, 0.03489945f, -0.9993908f);
});
}
void AddDoor(uint entry, float x, float y, float z, float o, float rotation0, float rotation1, float rotation2, float rotation3, GameObjectState goState = GameObjectState.Ready)
{
GameObject go = CreateObject(entry, x, y, z, o, rotation0, rotation1, rotation2, rotation3, goState);
if (go != null)
_doorGUIDs.Add(go.GetGUID());
}
}
}
@@ -0,0 +1,21 @@
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
using Game.BattleGrounds;
using Game.Maps;
using Game.Scripting;
namespace Scripts.Battlegrounds.TwinPeaks
{
[Script(nameof(battleground_twin_peaks), 726)]
class battleground_twin_peaks : BattlegroundScript
{
enum PvpStats : uint
{
BG_TP_FLAG_CAPTURES = 290,
BG_TP_FLAG_RETURNS = 291
}
public battleground_twin_peaks(BattlegroundMap map) : base(map) { }
}
}
@@ -0,0 +1,583 @@
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
using Framework.Constants;
using Game.BattleGrounds;
using Game.Entities;
using Game.Maps;
using Game.Scripting;
using Game.Spells;
using System;
using System.Collections.Generic;
namespace Scripts.Battlegrounds.WarsongGulch
{
enum SpellIds
{
FocusedAssault = 46392,
BrutalAssault = 46393,
CapturedAllianceCosmeticFx = 262508,
CapturedHordeCosmeticFx = 262512,
WarsongFlag = 23333,
WarsongFlagDropped = 23334,
SilverwingFlag = 23335,
SilverwingFlagDropped = 23336,
QuickCapTimer = 183317,
}
enum AreaTriggerIds
{
CapturePointAlliance = 30,
CapturePointHorde = 31
}
enum PvpStats
{
FlagCaptures = 928,
FlagReturns = 929
}
enum WorldStateIds
{
FlagStateAlliance = 1545,
FlagStateHorde = 1546,
FlagStateNeutral = 1547,
HordeFlagCountPickedUp = 17712,
AllianceFlagCountPickedUp = 17713,
FlagCapturesAlliance = 1581,
FlagCapturesHorde = 1582,
FlagCapturesMax = 1601,
FlagCapturesMaxNew = 17303,
FlagControlHorde = 2338,
FlagControlAlliance = 2339,
StateTimer = 4248,
StateTimerActive = 4247
}
enum TextIds
{
StartOneMinute = 10015,
StartHalfMinute = 10016,
BattleHasBegun = 10014,
CapturedHordeFlag = 9801,
CapturedAllianceFlag = 9802,
FlagsPlaced = 9803,
AllianceFlagPickedUp = 9804,
AllianceFlagDropped = 9805,
HordeFlagPickedUp = 9807,
HordeFlagDropped = 9806,
AllianceFlagReturned = 9808,
HordeFlagReturned = 9809
}
enum SoundIds
{
FlagCapturedAlliance = 8173,
FlagCapturedHorde = 8213,
FlagPlaced = 8232,
FlagReturned = 8192,
HordeFlagPickedUp = 8212,
AllianceFlagPickedUp = 8174,
FlagsRespawned = 8232
}
enum GameObjectIds
{
AllianceDoor = 309704,
Portcullis009 = 309705,
Portcullis002 = 309883,
CollisionPcSize = 242273,
HordeGate1 = 352709,
HordeGate2 = 352710,
AllianceFlagInBase = 227741,
HordeFlagInBase = 227740
}
struct Misc
{
public const uint MaxTeamScore = 3;
public const uint FlagBrutalAssaultStackCount = 5;
public const uint EventStartBattle = 35912;
public static TimeSpan FlagAssaultTimer = TimeSpan.FromSeconds(30);
public static uint[][] HonorRewards = [[20, 40, 40], [60, 40, 80]];
}
[Script(nameof(battleground_warsong_gulch), 2106)]
class battleground_warsong_gulch : BattlegroundScript
{
Team _lastFlagCaptureTeam;
bool _bothFlagsKept;
List<ObjectGuid> _doors = new();
ObjectGuid[] _flags = new ObjectGuid[SharedConst.PvpTeamsCount];
TimeTracker _flagAssaultTimer;
byte _assaultStackCount;
ObjectGuid[] _capturePointAreaTriggers = new ObjectGuid[SharedConst.PvpTeamsCount];
uint _honorWinKills;
uint _honorEndKills;
uint _reputationCapture;
public battleground_warsong_gulch(BattlegroundMap map) : base(map)
{
_lastFlagCaptureTeam = Team.Other;
_flagAssaultTimer.Reset(Misc.FlagAssaultTimer);
if (Global.BattlegroundMgr.IsBGWeekend(battleground.GetTypeID()))
{
_reputationCapture = 45;
_honorWinKills = 3;
_honorEndKills = 4;
}
else
{
_reputationCapture = 35;
_honorWinKills = 1;
_honorEndKills = 2;
}
}
public override void OnUpdate(uint diff)
{
base.OnUpdate(diff);
if (battleground.GetStatus() == BattlegroundStatus.InProgress)
{
if (battleground.GetElapsedTime() >= 17 * Time.Minute * Time.InMilliseconds)
{
if (battleground.GetTeamScore(BattleGroundTeamId.Alliance) == 0)
{
if (battleground.GetTeamScore(BattleGroundTeamId.Horde) == 0) // No one scored - result is tie
battleground.EndBattleground(Team.Other);
else // Horde has more points and thus wins
battleground.EndBattleground(Team.Horde);
}
else if (battleground.GetTeamScore(BattleGroundTeamId.Horde) == 0) // Alliance has > 0, Horde has 0, alliance wins
battleground.EndBattleground(Team.Alliance);
else if (battleground.GetTeamScore(BattleGroundTeamId.Horde) == battleground.GetTeamScore(BattleGroundTeamId.Alliance)) // Team score equal, winner is team that scored the last flag
battleground.EndBattleground(_lastFlagCaptureTeam);
else if (battleground.GetTeamScore(BattleGroundTeamId.Horde) > battleground.GetTeamScore(BattleGroundTeamId.Alliance)) // Last but not least, check who has the higher score
battleground.EndBattleground(Team.Horde);
else
battleground.EndBattleground(Team.Alliance);
}
}
if (_bothFlagsKept)
{
_flagAssaultTimer.Update(diff);
if (_flagAssaultTimer.Passed())
{
_flagAssaultTimer.Reset(Misc.FlagAssaultTimer);
if (_assaultStackCount < byte.MaxValue)
{
_assaultStackCount++;
// update assault debuff stacks
DoForFlagKeepers(ApplyAssaultDebuffToPlayer);
}
}
}
}
public override void OnStart()
{
base.OnStart();
foreach (ObjectGuid door in _doors)
{
GameObject gameObject = battlegroundMap.GetGameObject(door);
if (gameObject != null)
{
gameObject.UseDoorOrButton();
gameObject.DespawnOrUnsummon(TimeSpan.FromSeconds(3));
}
}
UpdateWorldState((int)WorldStateIds.StateTimerActive, 1);
UpdateWorldState((int)WorldStateIds.StateTimer, (int)Time.DateTimeToUnixTime(GameTime.GetSystemTime() + TimeSpan.FromMinutes(15)));
// players joining later are not eligibles
TriggerGameEvent(Misc.EventStartBattle);
}
public override void OnEnd(Team winner)
{
base.OnEnd(winner);
// Win reward
if (winner == Team.Alliance)
battleground.RewardHonorToTeam(battleground.GetBonusHonorFromKill(_honorWinKills), Team.Alliance);
if (winner == Team.Horde)
battleground.RewardHonorToTeam(battleground.GetBonusHonorFromKill(_honorWinKills), Team.Horde);
// Complete map_end rewards (even if no team wins)
battleground.RewardHonorToTeam(battleground.GetBonusHonorFromKill(_honorEndKills), Team.Alliance);
battleground.RewardHonorToTeam(battleground.GetBonusHonorFromKill(_honorEndKills), Team.Horde);
}
void DoForFlagKeepers(Action<Player> action)
{
foreach (ObjectGuid flagGUID in _flags)
{
GameObject flag = battlegroundMap.GetGameObject(flagGUID);
if (flag != null)
{
Player carrier = Global.ObjAccessor.FindPlayer(flag.GetFlagCarrierGUID());
if (carrier != null)
action(carrier);
}
}
}
void ResetAssaultDebuff()
{
_bothFlagsKept = false;
_assaultStackCount = 0;
_flagAssaultTimer.Reset(Misc.FlagAssaultTimer);
DoForFlagKeepers(RemoveAssaultDebuffFromPlayer);
}
void ApplyAssaultDebuffToPlayer(Player player)
{
if (_assaultStackCount == 0)
return;
uint spellId = (uint)SpellIds.FocusedAssault;
if (_assaultStackCount >= Misc.FlagBrutalAssaultStackCount)
{
player.RemoveAurasDueToSpell((uint)SpellIds.FocusedAssault);
spellId = (uint)SpellIds.BrutalAssault;
}
Aura aura = player.GetAura(spellId);
if (aura == null)
{
player.CastSpell(player, spellId, true);
aura = player.GetAura(spellId);
}
if (aura != null)
aura.SetStackAmount(_assaultStackCount);
}
void RemoveAssaultDebuffFromPlayer(Player player)
{
player.RemoveAurasDueToSpell((uint)SpellIds.FocusedAssault);
player.RemoveAurasDueToSpell((uint)SpellIds.BrutalAssault);
}
FlagState GetFlagState(int team)
{
GameObject flag = battlegroundMap.GetGameObject(_flags[team]);
if (flag != null)
return flag.GetFlagState();
return 0;
}
ObjectGuid GetFlagCarrierGUID(int team)
{
GameObject flag = battlegroundMap.GetGameObject(_flags[team]);
if (flag != null)
return flag.GetFlagCarrierGUID();
return ObjectGuid.Empty;
}
void HandleFlagRoomCapturePoint()
{
DoForFlagKeepers(player =>
{
int team = Battleground.GetTeamIndexByTeamId(battleground.GetPlayerTeam(player.GetGUID()));
AreaTrigger trigger = battlegroundMap.GetAreaTrigger(_capturePointAreaTriggers[team]);
if (trigger != null && trigger.GetInsideUnits().Contains(player.GetGUID()))
if (CanCaptureFlag(trigger, player))
OnCaptureFlag(trigger, player);
});
}
void UpdateFlagState(Team team, FlagState value)
{
static int transformValueToOtherTeamControlWorldState(FlagState state) => state switch
{
FlagState.InBase or FlagState.Dropped or FlagState.Respawning => 1,
FlagState.Taken => 2,
_ => 0
};
if (team == Team.Alliance)
{
UpdateWorldState((int)WorldStateIds.FlagStateAlliance, (int)value);
UpdateWorldState((int)WorldStateIds.FlagControlHorde, transformValueToOtherTeamControlWorldState(value));
}
else
{
UpdateWorldState((int)WorldStateIds.FlagStateHorde, (int)value);
UpdateWorldState((int)WorldStateIds.FlagControlAlliance, transformValueToOtherTeamControlWorldState(value));
}
}
void UpdateTeamScore(int team)
{
if (team == BattleGroundTeamId.Alliance)
UpdateWorldState((int)WorldStateIds.FlagCapturesAlliance, (int)battleground.GetTeamScore(team));
else
UpdateWorldState((int)WorldStateIds.FlagCapturesHorde, (int)battleground.GetTeamScore(team));
}
public override void OnGameObjectCreate(GameObject gameObject)
{
base.OnGameObjectCreate(gameObject);
switch ((GameObjectIds)gameObject.GetEntry())
{
case GameObjectIds.AllianceDoor:
case GameObjectIds.Portcullis009:
case GameObjectIds.Portcullis002:
case GameObjectIds.CollisionPcSize:
case GameObjectIds.HordeGate1:
case GameObjectIds.HordeGate2:
_doors.Add(gameObject.GetGUID());
break;
case GameObjectIds.AllianceFlagInBase:
_flags[BattleGroundTeamId.Alliance] = gameObject.GetGUID();
break;
case GameObjectIds.HordeFlagInBase:
_flags[BattleGroundTeamId.Horde] = gameObject.GetGUID();
break;
default:
break;
}
}
public override void OnAreaTriggerCreate(AreaTrigger areaTrigger)
{
base.OnAreaTriggerCreate(areaTrigger);
if (!areaTrigger.IsStaticSpawn())
return;
switch ((AreaTriggerIds)areaTrigger.GetEntry())
{
case AreaTriggerIds.CapturePointAlliance:
_capturePointAreaTriggers[BattleGroundTeamId.Alliance] = areaTrigger.GetGUID();
break;
case AreaTriggerIds.CapturePointHorde:
_capturePointAreaTriggers[BattleGroundTeamId.Horde] = areaTrigger.GetGUID();
break;
default:
break;
}
}
public override void OnFlagStateChange(GameObject flagInBase, FlagState oldValue, FlagState newValue, Player player)
{
base.OnFlagStateChange(flagInBase, oldValue, newValue, player);
Team team = flagInBase.GetEntry() == (uint)GameObjectIds.HordeFlagInBase ? Team.Horde : Team.Alliance;
int otherTeamId = Battleground.GetTeamIndexByTeamId(SharedConst.GetOtherTeam(team));
UpdateFlagState(team, newValue);
switch (newValue)
{
case FlagState.InBase:
{
if (battleground.GetStatus() == BattlegroundStatus.InProgress)
{
ResetAssaultDebuff();
if (player != null)
{
// flag got returned to base by player interaction
battleground.UpdatePvpStat(player, (uint)PvpStats.FlagReturns, 1); // +1 flag returns
if (team == Team.Alliance)
{
battleground.SendBroadcastText((uint)TextIds.AllianceFlagReturned, ChatMsg.BgSystemAlliance, player);
battleground.PlaySoundToAll((uint)SoundIds.FlagReturned);
}
else
{
battleground.SendBroadcastText((uint)TextIds.HordeFlagReturned, ChatMsg.BgSystemHorde, player);
battleground.PlaySoundToAll((uint)SoundIds.FlagReturned);
}
}
// Flag respawned due to timeout/capture
else if (GetFlagState(otherTeamId) != FlagState.Respawning)
{
// if other flag is respawning, we will let that one handle the message and sound to prevent double message/sound.
battleground.SendBroadcastText((uint)TextIds.FlagsPlaced, ChatMsg.BgSystemNeutral);
battleground.PlaySoundToAll((uint)SoundIds.FlagsRespawned);
}
HandleFlagRoomCapturePoint();
}
break;
}
case FlagState.Dropped:
{
player.RemoveAurasDueToSpell((uint)SpellIds.QuickCapTimer);
RemoveAssaultDebuffFromPlayer(player);
uint recentlyDroppedSpellId = BattlegroundConst.SpellRecentlyDroppedHordeFlag;
if (team == Team.Alliance)
{
recentlyDroppedSpellId = BattlegroundConst.SpellRecentlyDroppedAllianceFlag;
battleground.SendBroadcastText((uint)TextIds.AllianceFlagDropped, ChatMsg.BgSystemAlliance, player);
}
else
battleground.SendBroadcastText((uint)TextIds.HordeFlagDropped, ChatMsg.BgSystemHorde, player);
player.CastSpell(player, recentlyDroppedSpellId, true);
break;
}
case FlagState.Taken:
{
if (team == Team.Horde)
{
battleground.SendBroadcastText((uint)TextIds.HordeFlagPickedUp, ChatMsg.BgSystemHorde, player);
battleground.PlaySoundToAll((uint)SoundIds.HordeFlagPickedUp);
}
else
{
battleground.SendBroadcastText((uint)TextIds.AllianceFlagPickedUp, ChatMsg.BgSystemAlliance, player);
battleground.PlaySoundToAll((uint)SoundIds.AllianceFlagPickedUp);
}
if (GetFlagState(otherTeamId) == FlagState.Taken)
_bothFlagsKept = true;
ApplyAssaultDebuffToPlayer(player);
flagInBase.CastSpell(player, (uint)SpellIds.QuickCapTimer, true);
player.StartCriteria(CriteriaStartEvent.BeSpellTarget, (uint)SpellIds.QuickCapTimer, TimeSpan.FromSeconds(GameTime.GetGameTime() - flagInBase.GetFlagTakenFromBaseTime()));
break;
}
case FlagState.Respawning:
ResetAssaultDebuff();
break;
default:
break;
}
}
public override bool CanCaptureFlag(AreaTrigger areaTrigger, Player player)
{
if (battleground.GetStatus() != BattlegroundStatus.InProgress)
return false;
Team team = battleground.GetPlayerTeam(player.GetGUID());
int teamId = Battleground.GetTeamIndexByTeamId(team);
int otherTeamId = Battleground.GetTeamIndexByTeamId(SharedConst.GetOtherTeam(team));
if (areaTrigger.GetGUID() != _capturePointAreaTriggers[teamId])
return false;
// check if enemy flag's carrier is this player
if (GetFlagCarrierGUID(otherTeamId) != player.GetGUID())
return false;
// check that team's flag is in base
return GetFlagState(teamId) == FlagState.InBase;
}
public override void OnCaptureFlag(AreaTrigger areaTrigger, Player player)
{
base.OnCaptureFlag(areaTrigger, player);
Team winner = Team.Other;
Team team = battleground.GetPlayerTeam(player.GetGUID());
int teamId = Battleground.GetTeamIndexByTeamId(team);
int otherTeamId = Battleground.GetTeamIndexByTeamId(SharedConst.GetOtherTeam(team));
/*
1. Update flag states & score world states
2. update points
3. chat message & sound
4. update criterias & achievements
5. remove all related auras
?. Reward honor & reputation
*/
// 1. update the flag states
foreach (ObjectGuid flagGuid in _flags)
{
GameObject flag1 = battlegroundMap.GetGameObject(flagGuid);
if (flag1 != null)
flag1.HandleCustomTypeCommand(new Game.Entities.GameObjectType.SetNewFlagState(FlagState.Respawning, player));
}
// 2. update points
if (battleground.GetTeamScore(teamId) < Misc.MaxTeamScore)
battleground.AddPoint(team, 1);
UpdateTeamScore(teamId);
// 3. chat message & sound
if (team == Team.Alliance)
{
battleground.SendBroadcastText((uint)TextIds.CapturedHordeFlag, ChatMsg.BgSystemHorde, player);
battleground.PlaySoundToAll((uint)SoundIds.FlagCapturedAlliance);
battleground.RewardReputationToTeam(890, _reputationCapture, Team.Alliance);
player.CastSpell(player, (uint)SpellIds.CapturedAllianceCosmeticFx);
}
else
{
battleground.SendBroadcastText((uint)TextIds.CapturedAllianceFlag, ChatMsg.BgSystemAlliance, player);
battleground.PlaySoundToAll((uint)SoundIds.FlagCapturedHorde);
battleground.RewardReputationToTeam(889, _reputationCapture, Team.Horde);
player.CastSpell(player, (uint)SpellIds.CapturedHordeCosmeticFx);
}
// 4. update criteria's for achievement, player score etc.
battleground.UpdatePvpStat(player, (uint)PvpStats.FlagCaptures, 1); // +1 flag captures
// 5. Remove all related auras
RemoveAssaultDebuffFromPlayer(player);
GameObject flag = battlegroundMap.GetGameObject(_flags[otherTeamId]);
if (flag != null)
player.RemoveAurasDueToSpell(flag.GetGoInfo().NewFlag.pickupSpell, flag.GetGUID());
player.RemoveAurasDueToSpell((uint)SpellIds.QuickCapTimer);
player.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.PvPActive);
battleground.RewardHonorToTeam(battleground.GetBonusHonorFromKill(2), team);
// update last flag capture to be used if teamscore is equal
SetLastFlagCapture(team);
if (battleground.GetTeamScore(teamId) == Misc.MaxTeamScore)
winner = team;
if (winner != 0)
{
UpdateWorldState((int)WorldStateIds.FlagStateAlliance, 1);
UpdateWorldState((int)WorldStateIds.FlagStateHorde, 1);
UpdateWorldState((int)WorldStateIds.StateTimerActive, 0);
battleground.RewardHonorToTeam(Misc.HonorRewards[Global.BattlegroundMgr.IsBGWeekend(battleground.GetTypeID()) ? 1 : 0][0], winner);
battleground.EndBattleground(winner);
}
}
public override Team GetPrematureWinner()
{
if (battleground.GetTeamScore(BattleGroundTeamId.Alliance) > battleground.GetTeamScore(BattleGroundTeamId.Horde))
return Team.Alliance;
if (battleground.GetTeamScore(BattleGroundTeamId.Horde) > battleground.GetTeamScore(BattleGroundTeamId.Alliance))
return Team.Horde;
return base.GetPrematureWinner();
}
void SetLastFlagCapture(Team team)
{
_lastFlagCaptureTeam = team;
}
}
}