diff options
Diffstat (limited to 'src/server')
29 files changed, 1291 insertions, 421 deletions
diff --git a/src/server/game/Accounts/RBAC.h b/src/server/game/Accounts/RBAC.h index fc22f76e949..ded2a58d7f1 100644 --- a/src/server/game/Accounts/RBAC.h +++ b/src/server/game/Accounts/RBAC.h @@ -535,7 +535,7 @@ enum RBACPermissions      RBAC_PERM_COMMAND_RELOAD_CONDITIONS                      = 629,      RBAC_PERM_COMMAND_RELOAD_CONFIG                          = 630,      RBAC_PERM_COMMAND_RELOAD_BATTLEGROUND_TEMPLATE           = 631, -    RBAC_PERM_UNUSED_632                                     = 632, // unused +    RBAC_PERM_COMMAND_MUTEHISTORY                            = 632,      RBAC_PERM_COMMAND_RELOAD_CREATURE_LINKED_RESPAWN         = 633,      RBAC_PERM_COMMAND_RELOAD_CREATURE_LOOT_TEMPLATE          = 634,      RBAC_PERM_COMMAND_RELOAD_CREATURE_ONKILL_REPUTATION      = 635, @@ -698,6 +698,8 @@ enum RBACPermissions      RBAC_PERM_COMMAND_AHBOT_RELOAD                           = 792,      RBAC_PERM_COMMAND_AHBOT_STATUS                           = 793,      RBAC_PERM_COMMAND_GUILD_INFO                             = 794, +    RBAC_PERM_COMMAND_INSTANCE_SET_BOSS_STATE                = 795, +    RBAC_PERM_COMMAND_INSTANCE_GET_BOSS_STATE                = 796,      // custom permissions 1000+      RBAC_PERM_MAX diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp index 52843b97a51..73951a5b35e 100644 --- a/src/server/game/Battlegrounds/Battleground.cpp +++ b/src/server/game/Battlegrounds/Battleground.cpp @@ -37,6 +37,7 @@  #include "SpellAuras.h"  #include "Util.h"  #include "WorldPacket.h" +#include "Transport.h"  namespace Trinity  { @@ -1407,7 +1408,7 @@ void Battleground::RelocateDeadPlayers(ObjectGuid guideGuid)      }  } -bool Battleground::AddObject(uint32 type, uint32 entry, float x, float y, float z, float o, float rotation0, float rotation1, float rotation2, float rotation3, uint32 /*respawnTime*/) +bool Battleground::AddObject(uint32 type, uint32 entry, float x, float y, float z, float o, float rotation0, float rotation1, float rotation2, float rotation3, uint32 /*respawnTime*/, GOState goState)  {      // If the assert is called, means that BgObjects must be resized!      ASSERT(type < BgObjects.size()); @@ -1420,7 +1421,7 @@ bool Battleground::AddObject(uint32 type, uint32 entry, float x, float y, float      // So we must create it specific for this instance      GameObject* go = new GameObject;      if (!go->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_GAMEOBJECT), entry, GetBgMap(), -        PHASEMASK_NORMAL, x, y, z, o, rotation0, rotation1, rotation2, rotation3, 100, GO_STATE_READY)) +        PHASEMASK_NORMAL, x, y, z, o, rotation0, rotation1, rotation2, rotation3, 100, goState))      {          TC_LOG_ERROR("bg.battleground", "Battleground::AddObject: cannot create gameobject (entry: %u) for BG (map: %u, instance id: %u)!",                  entry, m_MapId, m_InstanceID); @@ -1460,9 +1461,9 @@ bool Battleground::AddObject(uint32 type, uint32 entry, float x, float y, float      return true;  } -bool Battleground::AddObject(uint32 type, uint32 entry, Position const& pos, float rotation0, float rotation1, float rotation2, float rotation3, uint32 respawnTime /*= 0*/) +bool Battleground::AddObject(uint32 type, uint32 entry, Position const& pos, float rotation0, float rotation1, float rotation2, float rotation3, uint32 respawnTime /*= 0*/, GOState goState /*= GO_STATE_READY*/)  { -    return AddObject(type, entry, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), rotation0, rotation1, rotation2, rotation3, respawnTime); +    return AddObject(type, entry, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), rotation0, rotation1, rotation2, rotation3, respawnTime, goState);  }  // Some doors aren't despawned so we cannot handle their closing in gameobject::update() @@ -1541,7 +1542,7 @@ void Battleground::SpawnBGObject(uint32 type, uint32 respawntime)          }  } -Creature* Battleground::AddCreature(uint32 entry, uint32 type, float x, float y, float z, float o, TeamId /*teamId = TEAM_NEUTRAL*/, uint32 respawntime /*= 0*/) +Creature* Battleground::AddCreature(uint32 entry, uint32 type, float x, float y, float z, float o, TeamId /*teamId = TEAM_NEUTRAL*/, uint32 respawntime /*= 0*/, Transport* transport)  {      // If the assert is called, means that BgCreatures must be resized!      ASSERT(type < BgCreatures.size()); @@ -1550,7 +1551,19 @@ Creature* Battleground::AddCreature(uint32 entry, uint32 type, float x, float y,      if (!map)          return NULL; +    if (transport) +    { +        if (Creature* creature = transport->SummonPassenger(entry, { x, y, z, o }, TEMPSUMMON_MANUAL_DESPAWN)) +        { +            BgCreatures[type] = creature->GetGUID(); +            return creature; +        } + +        return NULL; +    } +      Creature* creature = new Creature(); +      if (!creature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, PHASEMASK_NORMAL, entry, x, y, z, o))      {          TC_LOG_ERROR("bg.battleground", "Battleground::AddCreature: cannot create creature (entry: %u) for BG (map: %u, instance id: %u)!", @@ -1584,9 +1597,9 @@ Creature* Battleground::AddCreature(uint32 entry, uint32 type, float x, float y,      return creature;  } -Creature* Battleground::AddCreature(uint32 entry, uint32 type, Position const& pos, TeamId teamId /*= TEAM_NEUTRAL*/, uint32 respawntime /*= 0*/) +Creature* Battleground::AddCreature(uint32 entry, uint32 type, Position const& pos, TeamId teamId /*= TEAM_NEUTRAL*/, uint32 respawntime /*= 0*/, Transport* transport)  { -    return AddCreature(entry, type, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), teamId, respawntime); +    return AddCreature(entry, type, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), teamId, respawntime, transport);  }  bool Battleground::DelCreature(uint32 type) diff --git a/src/server/game/Battlegrounds/Battleground.h b/src/server/game/Battlegrounds/Battleground.h index 1c4b3de4f76..851a191927c 100644 --- a/src/server/game/Battlegrounds/Battleground.h +++ b/src/server/game/Battlegrounds/Battleground.h @@ -25,6 +25,7 @@  #include "DBCEnums.h"  #include "WorldPacket.h"  #include "Object.h" +#include "GameObject.h"  class Creature;  class GameObject; @@ -435,10 +436,10 @@ class Battleground          GuidVector BgObjects;          GuidVector BgCreatures;          void SpawnBGObject(uint32 type, uint32 respawntime); -        virtual bool AddObject(uint32 type, uint32 entry, float x, float y, float z, float o, float rotation0, float rotation1, float rotation2, float rotation3, uint32 respawnTime = 0); -        bool AddObject(uint32 type, uint32 entry, Position const& pos, float rotation0, float rotation1, float rotation2, float rotation3, uint32 respawnTime = 0); -        virtual Creature* AddCreature(uint32 entry, uint32 type, float x, float y, float z, float o, TeamId teamId = TEAM_NEUTRAL, uint32 respawntime = 0); -        Creature* AddCreature(uint32 entry, uint32 type, Position const& pos, TeamId teamId = TEAM_NEUTRAL, uint32 respawntime = 0); +        virtual bool AddObject(uint32 type, uint32 entry, float x, float y, float z, float o, float rotation0, float rotation1, float rotation2, float rotation3, uint32 respawnTime = 0, GOState goState = GO_STATE_READY); +        bool AddObject(uint32 type, uint32 entry, Position const& pos, float rotation0, float rotation1, float rotation2, float rotation3, uint32 respawnTime = 0, GOState goState = GO_STATE_READY); +        virtual Creature* AddCreature(uint32 entry, uint32 type, float x, float y, float z, float o, TeamId teamId = TEAM_NEUTRAL, uint32 respawntime = 0, Transport* transport = NULL); +        Creature* AddCreature(uint32 entry, uint32 type, Position const& pos, TeamId teamId = TEAM_NEUTRAL, uint32 respawntime = 0, Transport* transport = NULL);          bool DelCreature(uint32 type);          bool DelObject(uint32 type);          virtual bool AddSpiritGuide(uint32 type, float x, float y, float z, float o, TeamId teamId = TEAM_NEUTRAL); diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp index 4e0bdd17162..bd3ef91daac 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp @@ -26,11 +26,12 @@  #include "Vehicle.h"  #include "Transport.h"  #include "WorldSession.h" +#include "ScriptedCreature.h"  BattlegroundIC::BattlegroundIC()  { -    BgObjects.resize(MAX_NORMAL_GAMEOBJECTS_SPAWNS + MAX_AIRSHIPS_SPAWNS + MAX_HANGAR_TELEPORTERS_SPAWNS + MAX_FORTRESS_TELEPORTERS_SPAWNS); -    BgCreatures.resize(MAX_NORMAL_NPCS_SPAWNS + MAX_WORKSHOP_SPAWNS + MAX_DOCKS_SPAWNS + MAX_SPIRIT_GUIDES_SPAWNS); +    BgObjects.resize(MAX_NORMAL_GAMEOBJECTS_SPAWNS + MAX_AIRSHIPS_SPAWNS + MAX_HANGAR_TELEPORTERS_SPAWNS + MAX_FORTRESS_TELEPORTERS_SPAWNS + MAX_HANGAR_TELEPORTER_EFFECTS_SPAWNS + MAX_FORTRESS_TELEPORTER_EFFECTS_SPAWNS); +    BgCreatures.resize(MAX_NORMAL_NPCS_SPAWNS + MAX_WORKSHOP_SPAWNS + MAX_DOCKS_SPAWNS + MAX_SPIRIT_GUIDES_SPAWNS + MAX_HANGAR_NPCS_SPAWNS);      StartMessageIds[BG_STARTING_EVENT_FIRST]  = LANG_BG_IC_START_TWO_MINUTES;      StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_BG_IC_START_ONE_MINUTE; @@ -68,38 +69,8 @@ void BattlegroundIC::HandlePlayerResurrect(Player* player)          player->CastSpell(player, SPELL_OIL_REFINERY, true);  } -void BattlegroundIC::DoAction(uint32 action, ObjectGuid var) -{ -    if (action != ACTION_TELEPORT_PLAYER_TO_TRANSPORT) -        return; - -    if (!gunshipAlliance || !gunshipHorde) -        return; - -    Player* player = ObjectAccessor::FindPlayer(var); -    if (!player) -        return; - -    (player->GetTeamId() == TEAM_ALLIANCE ? gunshipAlliance : gunshipHorde)->AddPassenger(player); - -    player->m_movementInfo.transport.pos.m_positionX = TransportMovementInfo.GetPositionX(); -    player->m_movementInfo.transport.pos.m_positionY = TransportMovementInfo.GetPositionY(); -    player->m_movementInfo.transport.pos.m_positionZ = TransportMovementInfo.GetPositionZ(); - -    if (player->TeleportTo(GetMapId(), TeleportToTransportPosition.GetPositionX(), -                        TeleportToTransportPosition.GetPositionY(), -                        TeleportToTransportPosition.GetPositionZ(), -                        TeleportToTransportPosition.GetOrientation(), -                        TELE_TO_NOT_LEAVE_TRANSPORT)) -    { -        player->CastSpell(player, SPELL_PARACHUTE, true); // this must be changed, there is a trigger in each transport that casts the spell. -        player->CastSpell(player, SPELL_SLOW_FALL, true); -    } -} -  void BattlegroundIC::PostUpdateImpl(uint32 diff)  { -      if (GetStatus() != STATUS_IN_PROGRESS)          return; @@ -109,9 +80,17 @@ void BattlegroundIC::PostUpdateImpl(uint32 diff)          {              GetBGObject(BG_IC_GO_DOODAD_ND_HUMAN_GATE_CLOSEDFX_DOOR01)->RemoveFromWorld();              GetBGObject(BG_IC_GO_DOODAD_ND_WINTERORC_WALL_GATEFX_DOOR01)->RemoveFromWorld(); - -            GetBGObject(BG_IC_GO_ALLIANCE_GATE_3)->SetDestructibleState(GO_DESTRUCTIBLE_DAMAGED); // Alliance door -            GetBGObject(BG_IC_GO_HORDE_GATE_1)->SetDestructibleState(GO_DESTRUCTIBLE_DAMAGED); // Horde door +            GetBGObject(BG_IC_GO_DOODAD_ND_HUMAN_GATE_CLOSEDFX_DOOR02)->RemoveFromWorld(); +            GetBGObject(BG_IC_GO_DOODAD_ND_WINTERORC_WALL_GATEFX_DOOR02)->RemoveFromWorld(); +            GetBGObject(BG_IC_GO_DOODAD_ND_HUMAN_GATE_CLOSEDFX_DOOR03)->RemoveFromWorld(); +            GetBGObject(BG_IC_GO_DOODAD_ND_WINTERORC_WALL_GATEFX_DOOR03)->RemoveFromWorld(); + +            GetBGObject(BG_IC_GO_ALLIANCE_GATE_1)->SetDestructibleState(GO_DESTRUCTIBLE_DAMAGED); +            GetBGObject(BG_IC_GO_HORDE_GATE_1)->SetDestructibleState(GO_DESTRUCTIBLE_DAMAGED); +            GetBGObject(BG_IC_GO_ALLIANCE_GATE_2)->SetDestructibleState(GO_DESTRUCTIBLE_DAMAGED); +            GetBGObject(BG_IC_GO_HORDE_GATE_2)->SetDestructibleState(GO_DESTRUCTIBLE_DAMAGED); +            GetBGObject(BG_IC_GO_ALLIANCE_GATE_3)->SetDestructibleState(GO_DESTRUCTIBLE_DAMAGED); +            GetBGObject(BG_IC_GO_HORDE_GATE_3)->SetDestructibleState(GO_DESTRUCTIBLE_DAMAGED);              doorsClosed = true;          } else closeFortressDoorsTimer -= diff; @@ -240,11 +219,6 @@ void BattlegroundIC::PostUpdateImpl(uint32 diff)  void BattlegroundIC::StartingEventCloseDoors()  { -    // Show Full Gate Displays -    GetBGObject(BG_IC_GO_ALLIANCE_GATE_1)->SetDestructibleState(GO_DESTRUCTIBLE_DAMAGED); -    GetBGObject(BG_IC_GO_ALLIANCE_GATE_2)->SetDestructibleState(GO_DESTRUCTIBLE_DAMAGED); -    GetBGObject(BG_IC_GO_HORDE_GATE_2)->SetDestructibleState(GO_DESTRUCTIBLE_DAMAGED); -    GetBGObject(BG_IC_GO_HORDE_GATE_3)->SetDestructibleState(GO_DESTRUCTIBLE_DAMAGED);  }  void BattlegroundIC::StartingEventOpenDoors() @@ -252,6 +226,10 @@ void BattlegroundIC::StartingEventOpenDoors()      //after 20 seconds they should be despawned      DoorOpen(BG_IC_GO_DOODAD_ND_HUMAN_GATE_CLOSEDFX_DOOR01);      DoorOpen(BG_IC_GO_DOODAD_ND_WINTERORC_WALL_GATEFX_DOOR01); +    DoorOpen(BG_IC_GO_DOODAD_ND_HUMAN_GATE_CLOSEDFX_DOOR02); +    DoorOpen(BG_IC_GO_DOODAD_ND_WINTERORC_WALL_GATEFX_DOOR02); +    DoorOpen(BG_IC_GO_DOODAD_ND_HUMAN_GATE_CLOSEDFX_DOOR03); +    DoorOpen(BG_IC_GO_DOODAD_ND_WINTERORC_WALL_GATEFX_DOOR03);      DoorOpen(BG_IC_GO_DOODAD_HU_PORTCULLIS01_1);      DoorOpen(BG_IC_GO_DOODAD_HU_PORTCULLIS01_2); @@ -259,15 +237,10 @@ void BattlegroundIC::StartingEventOpenDoors()      DoorOpen(BG_IC_GO_DOODAD_VR_PORTCULLIS01_2);      for (uint8 i = 0; i < MAX_FORTRESS_TELEPORTERS_SPAWNS; ++i) -    { -        if (!AddObject(BG_IC_Teleporters[i].type, BG_IC_Teleporters[i].entry, -                       BG_IC_Teleporters[i].x, BG_IC_Teleporters[i].y, -                       BG_IC_Teleporters[i].z, BG_IC_Teleporters[i].o, -                       0, 0, 0, 0, RESPAWN_ONE_DAY)) -        { -            TC_LOG_ERROR("bg.battleground", "Isle of Conquest | Starting Event Open Doors: There was an error spawning gameobject %u", BG_IC_Teleporters[i].entry); -        } -    } +        GetBGObject(BG_IC_Teleporters[i].type)->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); + +    for (uint8 i = 0; i < MAX_FORTRESS_TELEPORTER_EFFECTS_SPAWNS; ++i) +        GetBGObject(BG_IC_TeleporterEffects[i].type)->SetGoState(GO_STATE_ACTIVE);  }  void BattlegroundIC::AddPlayer(Player* player) @@ -335,32 +308,44 @@ bool BattlegroundIC::SetupBattleground()  {      for (uint8 i = 0; i < MAX_NORMAL_GAMEOBJECTS_SPAWNS; ++i)      { -        if (!AddObject(BG_IC_ObjSpawnlocs[i].type, BG_IC_ObjSpawnlocs[i].entry, -            BG_IC_ObjSpawnlocs[i].x, BG_IC_ObjSpawnlocs[i].y, -            BG_IC_ObjSpawnlocs[i].z, BG_IC_ObjSpawnlocs[i].o, -            0, 0, 0, 0, RESPAWN_ONE_DAY)) +        if (!AddObject(BG_IC_ObjSpawnlocs[i].type, BG_IC_ObjSpawnlocs[i].entry, BG_IC_ObjSpawnlocs[i].x, BG_IC_ObjSpawnlocs[i].y, BG_IC_ObjSpawnlocs[i].z, BG_IC_ObjSpawnlocs[i].o, 0, 0, 0, 0, RESPAWN_ONE_DAY))          {              TC_LOG_ERROR("bg.battleground", "Isle of Conquest: There was an error spawning gameobject %u", BG_IC_ObjSpawnlocs[i].entry);              return false;          }      } +    for (uint8 i = 0; i < MAX_FORTRESS_TELEPORTERS_SPAWNS; ++i) +    { +        if (!AddObject(BG_IC_Teleporters[i].type, BG_IC_Teleporters[i].entry, BG_IC_Teleporters[i].x, BG_IC_Teleporters[i].y, BG_IC_Teleporters[i].z, BG_IC_Teleporters[i].o, 0, 0, 0, 0, RESPAWN_ONE_DAY)) +        { +            TC_LOG_ERROR("bg.battleground", "Isle of Conquest | Starting Event Open Doors: There was an error spawning gameobject %u", BG_IC_Teleporters[i].entry); +            return false; +        } +    } + +    for (uint8 i = 0; i < MAX_FORTRESS_TELEPORTER_EFFECTS_SPAWNS; ++i) +    { +        if (!AddObject(BG_IC_TeleporterEffects[i].type, BG_IC_TeleporterEffects[i].entry, BG_IC_TeleporterEffects[i].x, BG_IC_TeleporterEffects[i].y, BG_IC_TeleporterEffects[i].z, BG_IC_TeleporterEffects[i].o, 0, 0, 0, 0, RESPAWN_ONE_DAY)) +        { +            TC_LOG_ERROR("bg.battleground", "Isle of Conquest | Starting Event Open Doors: There was an error spawning gameobject %u", BG_IC_Teleporters[i].entry); +            return false; +        } +    } +      for (uint8 i = 2; i < MAX_NORMAL_NPCS_SPAWNS; ++i)      { -        if (!AddCreature(BG_IC_NpcSpawnlocs[i].entry, BG_IC_NpcSpawnlocs[i].type, -            BG_IC_NpcSpawnlocs[i].x, BG_IC_NpcSpawnlocs[i].y, -            BG_IC_NpcSpawnlocs[i].z, BG_IC_NpcSpawnlocs[i].o, -            BG_IC_NpcSpawnlocs[i].team, RESPAWN_ONE_DAY)) +        if (!AddCreature(BG_IC_NpcSpawnlocs[i].entry, BG_IC_NpcSpawnlocs[i].type, BG_IC_NpcSpawnlocs[i].x, BG_IC_NpcSpawnlocs[i].y, BG_IC_NpcSpawnlocs[i].z, BG_IC_NpcSpawnlocs[i].o, BG_IC_NpcSpawnlocs[i].team, RESPAWN_ONE_DAY))          {              TC_LOG_ERROR("bg.battleground", "Isle of Conquest: There was an error spawning creature %u", BG_IC_NpcSpawnlocs[i].entry);              return false;          }      } -    if (!AddSpiritGuide(BG_IC_NPC_SPIRIT_GUIDE_1+5, BG_IC_SpiritGuidePos[5], TEAM_ALLIANCE) -        || !AddSpiritGuide(BG_IC_NPC_SPIRIT_GUIDE_1+6, BG_IC_SpiritGuidePos[6], TEAM_HORDE) -        || !AddSpiritGuide(BG_IC_NPC_SPIRIT_GUIDE_1+3, BG_IC_SpiritGuidePos[7], TEAM_ALLIANCE) -        || !AddSpiritGuide(BG_IC_NPC_SPIRIT_GUIDE_1+4, BG_IC_SpiritGuidePos[8], TEAM_HORDE)) +    if (!AddSpiritGuide(BG_IC_NPC_SPIRIT_GUIDE_1+3, BG_IC_SpiritGuidePos[5], TEAM_ALLIANCE) +        || !AddSpiritGuide(BG_IC_NPC_SPIRIT_GUIDE_1+4, BG_IC_SpiritGuidePos[6], TEAM_HORDE) +        || !AddSpiritGuide(BG_IC_NPC_SPIRIT_GUIDE_1+5, BG_IC_SpiritGuidePos[7], TEAM_ALLIANCE) +        || !AddSpiritGuide(BG_IC_NPC_SPIRIT_GUIDE_1+6, BG_IC_SpiritGuidePos[8], TEAM_HORDE))      {          TC_LOG_ERROR("bg.battleground", "Isle of Conquest: Failed to spawn initial spirit guide!");          return false; @@ -379,9 +364,9 @@ bool BattlegroundIC::SetupBattleground()      gunshipAlliance->EnableMovement(false);      // setting correct factions for Keep Cannons -    for (uint8 i = BG_IC_NPC_KEEP_CANNON_1; i < BG_IC_NPC_KEEP_CANNON_12; ++i) +    for (uint8 i = BG_IC_NPC_KEEP_CANNON_1; i <= BG_IC_NPC_KEEP_CANNON_12; ++i)          GetBGCreature(i)->setFaction(BG_IC_Factions[0]); -    for (uint8 i = BG_IC_NPC_KEEP_CANNON_13; i < BG_IC_NPC_KEEP_CANNON_25; ++i) +    for (uint8 i = BG_IC_NPC_KEEP_CANNON_13; i <= BG_IC_NPC_KEEP_CANNON_25; ++i)          GetBGCreature(i)->setFaction(BG_IC_Factions[1]);      // correcting spawn time for keeps bombs @@ -459,8 +444,7 @@ void BattlegroundIC::EventPlayerClickedOnFlag(Player* player, GameObject* target              nodePoint[i].gameobject_entry = nextBanner;              // this is just needed if the next banner is grey -            if (nodePoint[i].banners[BANNER_A_CONTESTED] == nextBanner || -                nodePoint[i].banners[BANNER_H_CONTESTED] == nextBanner) +            if (nodePoint[i].banners[BANNER_A_CONTESTED] == nextBanner || nodePoint[i].banners[BANNER_H_CONTESTED] == nextBanner)              {                  nodePoint[i].timer = BANNER_STATE_CHANGE_TIME; // 1 minute for last change (real faction banner)                  nodePoint[i].needChange = true; @@ -478,9 +462,8 @@ void BattlegroundIC::EventPlayerClickedOnFlag(Player* player, GameObject* target                  SendMessage2ToAll(LANG_BG_IC_TEAM_ASSAULTED_NODE_1, CHAT_MSG_BG_SYSTEM_NEUTRAL, player, nodePoint[i].string);                  SendMessage2ToAll(LANG_BG_IC_TEAM_ASSAULTED_NODE_2, CHAT_MSG_BG_SYSTEM_NEUTRAL, player, nodePoint[i].string, (player->GetTeamId() == TEAM_ALLIANCE ? LANG_BG_IC_ALLIANCE : LANG_BG_IC_HORDE));                  HandleContestedNodes(&nodePoint[i]); -            } else if (nextBanner == nodePoint[i].banners[BANNER_A_CONTROLLED] || -                       nextBanner == nodePoint[i].banners[BANNER_H_CONTROLLED]) -                       // if we are going to spawn the definitve faction banner, we dont need the timer anymore +            } +            else if (nextBanner == nodePoint[i].banners[BANNER_A_CONTROLLED] || nextBanner == nodePoint[i].banners[BANNER_H_CONTROLLED]) // if we are going to spawn the definitve faction banner, we dont need the timer anymore              {                  nodePoint[i].timer = BANNER_STATE_CHANGE_TIME;                  nodePoint[i].needChange = false; @@ -505,12 +488,6 @@ void BattlegroundIC::EventPlayerClickedOnFlag(Player* player, GameObject* target              GetBGObject(nodePoint[i].gameobject_type)->SetUInt32Value(GAMEOBJECT_FACTION, nodePoint[i].faction == TEAM_ALLIANCE ? BG_IC_Factions[1] : BG_IC_Factions[0]); -            if (nodePoint[i].nodeType == NODE_TYPE_WORKSHOP) -            { -                DelObject(BG_IC_GO_SEAFORIUM_BOMBS_1); -                DelObject(BG_IC_GO_SEAFORIUM_BOMBS_2); -            } -              UpdateNodeWorldState(&nodePoint[i]);              // we dont need iterating if we are here              // If the needChange bool was set true, we will handle the rest in the Update Map function. @@ -573,11 +550,39 @@ void BattlegroundIC::HandleContestedNodes(ICNodePoint* nodePoint)  {      if (nodePoint->nodeType == NODE_TYPE_HANGAR)      { -         if (gunshipAlliance && gunshipHorde) -             (nodePoint->faction == TEAM_ALLIANCE ? gunshipHorde : gunshipAlliance)->EnableMovement(false); +        if (gunshipAlliance && gunshipHorde) +            (nodePoint->faction == TEAM_ALLIANCE ? gunshipHorde : gunshipAlliance)->EnableMovement(false); + +        for (uint8 u = BG_IC_GO_HANGAR_TELEPORTER_1; u <= BG_IC_GO_HANGAR_TELEPORTER_3; ++u) +            DelObject(u); -        for (uint8 u = BG_IC_GO_HANGAR_TELEPORTER_1; u < BG_IC_GO_HANGAR_TELEPORTER_3; ++u) +        for (uint8 u = BG_IC_GO_HANGAR_TELEPORTER_EFFECT_1; u <= BG_IC_GO_HANGAR_TELEPORTER_EFFECT_3; ++u)              DelObject(u); + +        DelCreature(BG_IC_NPC_WORLD_TRIGGER_NOT_FLOATING); + +        for (uint8 u = 0; u < MAX_CAPTAIN_SPAWNS_PER_FACTION; ++u) +        { +            uint8 type = BG_IC_NPC_GUNSHIP_CAPTAIN_1 + u; +            DelCreature(type); +        } + +        std::list<Creature*> cannons; +        if (nodePoint->faction == TEAM_HORDE) +            gunshipAlliance->GetCreatureListWithEntryInGrid(cannons, NPC_ALLIANCE_GUNSHIP_CANNON, 150.0f); +        else +            gunshipHorde->GetCreatureListWithEntryInGrid(cannons, NPC_HORDE_GUNSHIP_CANNON, 150.0f); + +        for (Creature* cannon : cannons) +        { +            cannon->GetVehicleKit()->RemoveAllPassengers(); +            cannon->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); +        } +    } +    else if (nodePoint->nodeType == NODE_TYPE_WORKSHOP) +    { +        DelObject(BG_IC_GO_SEAFORIUM_BOMBS_1); +        DelObject(BG_IC_GO_SEAFORIUM_BOMBS_2);      }  } @@ -592,26 +597,55 @@ void BattlegroundIC::HandleCapturedNodes(ICNodePoint* nodePoint, bool recapture)      switch (nodePoint->gameobject_type)      {          case BG_IC_GO_HANGAR_BANNER: -            // all the players on the stopped transport should be teleported out -            if (!gunshipAlliance || !gunshipHorde) -                break; - -            for (uint8 u = 0; u < MAX_HANGAR_TELEPORTERS_SPAWNS; ++u)              { -                uint8 type = BG_IC_GO_HANGAR_TELEPORTER_1+u; -                if (!AddObject(type, (nodePoint->faction == TEAM_ALLIANCE ? GO_ALLIANCE_GUNSHIP_PORTAL : GO_HORDE_GUNSHIP_PORTAL), -                    BG_IC_HangarTeleporters[u], 0, 0, 0, 0, RESPAWN_ONE_DAY)) +                if (!gunshipAlliance || !gunshipHorde) +                    break; + +                std::list<Creature*> cannons; +                if (nodePoint->faction == TEAM_ALLIANCE) +                    gunshipAlliance->GetCreatureListWithEntryInGrid(cannons, NPC_ALLIANCE_GUNSHIP_CANNON, 150.0f); +                else +                    gunshipHorde->GetCreatureListWithEntryInGrid(cannons, NPC_HORDE_GUNSHIP_CANNON, 150.0f); + +                for (Creature* cannon : cannons) +                    cannon->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + +                for (uint8 u = 0; u < MAX_HANGAR_TELEPORTERS_SPAWNS; ++u)                  { -                    TC_LOG_ERROR("bg.battleground", "Isle of Conquest: There was an error spawning a gunship portal. Type: %u", BG_IC_GO_HANGAR_TELEPORTER_1+u); +                    uint8 type = BG_IC_GO_HANGAR_TELEPORTER_1 + u; +                    if (!AddObject(type, (nodePoint->faction == TEAM_ALLIANCE ? GO_ALLIANCE_GUNSHIP_PORTAL : GO_HORDE_GUNSHIP_PORTAL), BG_IC_HangarTeleporters[u], 0, 0, 0, 0, RESPAWN_ONE_DAY)) +                        TC_LOG_ERROR("bg.battleground", "Isle of Conquest: There was an error spawning a gunship portal. Type: %u", BG_IC_GO_HANGAR_TELEPORTER_1 + u); +                } + +                for (uint8 u = 0; u < MAX_HANGAR_TELEPORTER_EFFECTS_SPAWNS; ++u) +                { +                    uint8 type = BG_IC_GO_HANGAR_TELEPORTER_EFFECT_1 + u; +                    if (!AddObject(type, (nodePoint->faction == TEAM_ALLIANCE ? GO_ALLIANCE_GUNSHIP_PORTAL_EFFECTS : GO_HORDE_GUNSHIP_PORTAL_EFFECTS), BG_IC_HangarTeleporterEffects[u], 0, 0, 0, 0, RESPAWN_ONE_DAY, GO_STATE_ACTIVE)) +                        TC_LOG_ERROR("bg.battleground", "Isle of Conquest: There was an error spawning a gunship portal effects. Type: %u", BG_IC_GO_HANGAR_TELEPORTER_1 + u);                  } -            } -            //TC_LOG_ERROR("bg.battleground", "BG_IC_GO_HANGAR_BANNER CAPTURED Faction: %u", nodePoint->faction); +                for (uint8 u = 0; u < MAX_TRIGGER_SPAWNS_PER_FACTION; ++u) +                { +                    if (!AddCreature(NPC_WORLD_TRIGGER_NOT_FLOATING, BG_IC_NPC_WORLD_TRIGGER_NOT_FLOATING, BG_IC_HangarTrigger[nodePoint->faction], nodePoint->faction, RESPAWN_ONE_DAY, nodePoint->faction == TEAM_ALLIANCE ? gunshipAlliance : gunshipHorde)) +                        TC_LOG_ERROR("bg.battleground", "Isle of Conquest: There was an error spawning a world trigger. Type: %u", BG_IC_NPC_WORLD_TRIGGER_NOT_FLOATING); +                } -            (nodePoint->faction == TEAM_ALLIANCE ? gunshipAlliance : gunshipHorde)->EnableMovement(true); -            (nodePoint->faction == TEAM_ALLIANCE ? gunshipHorde : gunshipAlliance)->EnableMovement(false); -            // we should spawn teleporters -            break; +                for (uint8 u = 0; u < MAX_CAPTAIN_SPAWNS_PER_FACTION; ++u) +                { +                    uint8 type = BG_IC_NPC_GUNSHIP_CAPTAIN_1 + u; + +                    if (type == BG_IC_NPC_GUNSHIP_CAPTAIN_1) +                        if (AddCreature(nodePoint->faction == TEAM_ALLIANCE ? NPC_ALLIANCE_GUNSHIP_CAPTAIN : NPC_HORDE_GUNSHIP_CAPTAIN, type, BG_IC_HangarCaptains[nodePoint->faction == TEAM_ALLIANCE ? 2 : 0], nodePoint->faction, RESPAWN_ONE_DAY)) +                            GetBGCreature(BG_IC_NPC_GUNSHIP_CAPTAIN_1)->GetAI()->DoAction(ACTION_GUNSHIP_READY); + +                    if (type == BG_IC_NPC_GUNSHIP_CAPTAIN_2) +                        if (!AddCreature(nodePoint->faction == TEAM_ALLIANCE ? NPC_ALLIANCE_GUNSHIP_CAPTAIN : NPC_HORDE_GUNSHIP_CAPTAIN, type, BG_IC_HangarCaptains[nodePoint->faction == TEAM_ALLIANCE ? 3 : 1], nodePoint->faction, RESPAWN_ONE_DAY, nodePoint->faction == TEAM_ALLIANCE ? gunshipAlliance : gunshipHorde)) +                            TC_LOG_ERROR("bg.battleground", "Isle of Conquest: There was an error spawning a world trigger. Type: %u", BG_IC_NPC_GUNSHIP_CAPTAIN_2); +                } + +                (nodePoint->faction == TEAM_ALLIANCE ? gunshipAlliance : gunshipHorde)->EnableMovement(true); +                break; +            }          case BG_IC_GO_QUARRY_BANNER:              RemoveAuraOnTeam(SPELL_QUARRY, (nodePoint->faction == TEAM_ALLIANCE ? HORDE : ALLIANCE));              CastSpellOnTeam(SPELL_QUARRY, (nodePoint->faction == TEAM_ALLIANCE ? ALLIANCE : HORDE)); @@ -621,7 +655,6 @@ void BattlegroundIC::HandleCapturedNodes(ICNodePoint* nodePoint, bool recapture)              CastSpellOnTeam(SPELL_OIL_REFINERY, (nodePoint->faction == TEAM_ALLIANCE ? ALLIANCE : HORDE));              break;          case BG_IC_GO_DOCKS_BANNER: -              if (recapture)                  break; @@ -661,8 +694,7 @@ void BattlegroundIC::HandleCapturedNodes(ICNodePoint* nodePoint, bool recapture)                  if (GetBGCreature(type, false) && GetBGCreature(type)->IsAlive())                      continue; -                if (AddCreature(nodePoint->faction == TEAM_ALLIANCE ? NPC_GLAIVE_THROWER_A : NPC_GLAIVE_THROWER_H, type, -                        BG_IC_DocksVehiclesGlaives[i], nodePoint->faction, RESPAWN_ONE_DAY)) +                if (AddCreature(nodePoint->faction == TEAM_ALLIANCE ? NPC_GLAIVE_THROWER_A : NPC_GLAIVE_THROWER_H, type, BG_IC_DocksVehiclesGlaives[i], nodePoint->faction, RESPAWN_ONE_DAY))                      GetBGCreature(type)->setFaction(BG_IC_Factions[(nodePoint->faction == TEAM_ALLIANCE ? 0 : 1)]);              } @@ -767,7 +799,16 @@ void BattlegroundIC::DestroyGate(Player* player, GameObject* go)          UpdateWorldState(uws_close, 0);          UpdateWorldState(uws_open, 1);      } -    DoorOpen((player->GetTeamId() == TEAM_ALLIANCE ? BG_IC_GO_HORDE_KEEP_PORTCULLIS : BG_IC_GO_DOODAD_PORTCULLISACTIVE02)); +    if (player->GetTeamId() == TEAM_ALLIANCE) +    { +        DoorOpen(BG_IC_GO_HORDE_KEEP_PORTCULLIS); +        GetBGObject(BG_IC_GO_HORDE_BANNER)->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); +    } +    else +    { +        DoorOpen(BG_IC_GO_DOODAD_PORTCULLISACTIVE02); +        GetBGObject(BG_IC_GO_ALLIANCE_BANNER)->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); +    }      uint32 lang_entry = 0; @@ -787,8 +828,8 @@ void BattlegroundIC::DestroyGate(Player* player, GameObject* go)          case GO_ALLIANCE_GATE_3:              lang_entry = LANG_BG_IC_SOUTH_GATE_DESTROYED;              break; -    default: -        break; +        default: +            break;      }      if (go->GetEntry() == GO_HORDE_GATE_1 || go->GetEntry() == GO_HORDE_GATE_2 || go->GetEntry() == GO_HORDE_GATE_3) diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundIC.h b/src/server/game/Battlegrounds/Zones/BattlegroundIC.h index 64186faf9ea..52fda127ecf 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundIC.h +++ b/src/server/game/Battlegrounds/Zones/BattlegroundIC.h @@ -32,156 +32,160 @@ const uint32 BG_IC_Factions[2] =  enum creaturesIC  { -    NPC_HIGH_COMMANDER_HALFORD_WYRMBANE = 34924, // Alliance Boss -    NPC_OVERLORD_AGMAR = 34922, // Horde Boss -    NPC_KOR_KRON_GUARD = 34918, // horde guard -    NPC_SEVEN_TH_LEGION_INFANTRY = 34919, // alliance guard -    NPC_KEEP_CANNON  = 34944, -    NPC_DEMOLISHER = 34775, -    NPC_SIEGE_ENGINE_H = 35069, -    NPC_SIEGE_ENGINE_A = 34776, -    NPC_GLAIVE_THROWER_A = 34802, -    NPC_GLAIVE_THROWER_H = 35273, -    NPC_CATAPULT = 34793, -    NPC_HORDE_GUNSHIP_CANNON = 34935, -    NPC_ALLIANCE_GUNSHIP_CANNON = 34929 +    NPC_HIGH_COMMANDER_HALFORD_WYRMBANE     = 34924, // Alliance Boss +    NPC_OVERLORD_AGMAR                      = 34922, // Horde Boss +    NPC_KOR_KRON_GUARD                      = 34918, // horde guard +    NPC_SEVEN_TH_LEGION_INFANTRY            = 34919, // alliance guard +    NPC_KEEP_CANNON                         = 34944, +    NPC_DEMOLISHER                          = 34775, +    NPC_SIEGE_ENGINE_H                      = 35069, +    NPC_SIEGE_ENGINE_A                      = 34776, +    NPC_GLAIVE_THROWER_A                    = 34802, +    NPC_GLAIVE_THROWER_H                    = 35273, +    NPC_CATAPULT                            = 34793, +    NPC_HORDE_GUNSHIP_CANNON                = 34935, +    NPC_ALLIANCE_GUNSHIP_CANNON             = 34929, +    NPC_HORDE_GUNSHIP_CAPTAIN               = 35003, +    NPC_ALLIANCE_GUNSHIP_CAPTAIN            = 34960, +    NPC_WORLD_TRIGGER_NOT_FLOATING          = 34984, +    NPC_WORLD_TRIGGER_ALLIANCE_FRIENDLY     = 20213, +    NPC_WORLD_TRIGGER_HORDE_FRIENDLY        = 20212  };  enum gameobjectsIC  { -    GO_ALLIANCE_BANNER = 195396, +    GO_ALLIANCE_BANNER                          = 195396, -    GO_ALLIANCE_GATE_1 = 195699, -    GO_ALLIANCE_GATE_2 = 195698, -    GO_ALLIANCE_GATE_3 = 195700, +    GO_ALLIANCE_GATE_1                          = 195699, +    GO_ALLIANCE_GATE_2                          = 195698, +    GO_ALLIANCE_GATE_3                          = 195700, -    GO_ALLIANCE_GUNSHIP_PORTAL = 195320, +    GO_ALLIANCE_GUNSHIP_PORTAL                  = 195320, -    GO_ALLIANCE_GUNSHIP_PORTAL_EFFECTS = 195705, +    GO_ALLIANCE_GUNSHIP_PORTAL_EFFECTS          = 195705, -    GO_BENCH_1 = 186896, -    GO_BENCH_2 = 186922, -    GO_BENCH_3 = 186899, -    GO_BENCH_4 = 186904, -    GO_BENCH_5 = 186897, +    GO_BENCH_1                                  = 186896, +    GO_BENCH_2                                  = 186922, +    GO_BENCH_3                                  = 186899, +    GO_BENCH_4                                  = 186904, +    GO_BENCH_5                                  = 186897, -    GO_BONFIRE_1 = 195376, -    GO_BONFIRE_2 = 195208, -    GO_BONFIRE_3 = 195210, -    GO_BONFIRE_4 = 195207, -    GO_BONFIRE_5 = 195209, -    GO_BONFIRE_6 = 195377, +    GO_BONFIRE_1                                = 195376, +    GO_BONFIRE_2                                = 195208, +    GO_BONFIRE_3                                = 195210, +    GO_BONFIRE_4                                = 195207, +    GO_BONFIRE_5                                = 195209, +    GO_BONFIRE_6                                = 195377, -    GO_DOCKS_BANNER = 195157, +    GO_DOCKS_BANNER                             = 195157, -    GO_DOODAD_HU_PORTCULLIS01 = 195436, +    GO_DOODAD_HU_PORTCULLIS01                   = 195436, -    GO_DOODAD_ND_HUMAN_GATE_CLOSEDFX_DOOR01 = 195703, +    GO_DOODAD_ND_HUMAN_GATE_CLOSEDFX_DOOR01     = 195703, -    GO_DOODAD_PORTCULLISACTIVE01 = 195451, +    GO_DOODAD_PORTCULLISACTIVE01                = 195451, -    GO_DOODAD_PORTCULLISACTIVE02 = 195452, +    GO_DOODAD_PORTCULLISACTIVE02                = 195452, -    GO_DOODAD_VR_PORTCULLIS01 = 195437, +    GO_DOODAD_VR_PORTCULLIS01                   = 195437, -    GO_CHAIR_1 = 195410, -    GO_CHAIR_2 = 195414, -    GO_CHAIR_3 = 160415, -    GO_CHAIR_4 = 195418, -    GO_CHAIR_5 = 195416, -    GO_CHAIR_6 = 160410, -    GO_CHAIR_7 = 160418, -    GO_CHAIR_8 = 160416, -    GO_CHAIR_9 = 160419, +    GO_CHAIR_1                                  = 195410, +    GO_CHAIR_2                                  = 195414, +    GO_CHAIR_3                                  = 160415, +    GO_CHAIR_4                                  = 195418, +    GO_CHAIR_5                                  = 195416, +    GO_CHAIR_6                                  = 160410, +    GO_CHAIR_7                                  = 160418, +    GO_CHAIR_8                                  = 160416, +    GO_CHAIR_9                                  = 160419, -    GO_FLAGPOLE_1 = 195131, -    GO_FLAGPOLE_2 = 195439, +    GO_FLAGPOLE_1                               = 195131, +    GO_FLAGPOLE_2                               = 195439, -    GO_GUNSHIP_PORTAL_1 = 195371, -    GO_GUNSHIP_PORTAL_2 = 196413, +    GO_GUNSHIP_PORTAL_1                         = 195371, +    GO_GUNSHIP_PORTAL_2                         = 196413, -    GO_HANGAR_BANNER = 195158, +    GO_HANGAR_BANNER                            = 195158, -    GO_HORDE_BANNER = 195393, +    GO_HORDE_BANNER                             = 195393, -    GO_HORDE_GATE_1 = 195494, -    GO_HORDE_GATE_2 = 195496, -    GO_HORDE_GATE_3 = 195495, +    GO_HORDE_GATE_1                             = 195494, +    GO_HORDE_GATE_2                             = 195496, +    GO_HORDE_GATE_3                             = 195495, -    GO_HORDE_GUNSHIP_PORTAL = 195326, +    GO_HORDE_GUNSHIP_PORTAL                     = 195326, -    GO_HORDE_GUNSHIP_PORTAL_EFFECTS = 195706, +    GO_HORDE_GUNSHIP_PORTAL_EFFECTS             = 195706, -    GO_HORDE_KEEP_PORTCULLIS = 195223, +    GO_HORDE_KEEP_PORTCULLIS                    = 195223, -    GO_HUGE_SEAFORIUM_BOMB_A = 195332, -    GO_HUGE_SEAFORIUM_BOMB_H = 195333, +    GO_HUGE_SEAFORIUM_BOMB_A                    = 195332, +    GO_HUGE_SEAFORIUM_BOMB_H                    = 195333, -    GO_QUARRY_BANNER = 195338, -    GO_REFRESHMENT_PORTAL = 186811, -    GO_SEAFORIUM_BOMBS = 195237, +    GO_QUARRY_BANNER                            = 195338, +    GO_REFRESHMENT_PORTAL                       = 186811, +    GO_SEAFORIUM_BOMBS                          = 195237, -    GO_STOVE_1 = 174863, -    GO_STOVE_2 = 160411, +    GO_STOVE_1                                  = 174863, +    GO_STOVE_2                                  = 160411, -    GO_TELEPORTER_1 = 195314, // 195314 H-OUT 66549 -    GO_TELEPORTER_2 = 195313, // 195313 H-IN 66548 +    GO_TELEPORTER_1                             = 195314, // 195314 H-OUT 66549 +    GO_TELEPORTER_2                             = 195313, // 195313 H-IN 66548 -    GO_TELEPORTER_3 = 195315, // 195315 A-OUT 66549 -    GO_TELEPORTER_4 = 195316, // 195316 A-IN 66548 +    GO_TELEPORTER_3                             = 195315, // 195315 A-OUT 66549 +    GO_TELEPORTER_4                             = 195316, // 195316 A-IN 66548 -    GO_TELEPORTER_EFFECTS_A = 195701, +    GO_TELEPORTER_EFFECTS_A                     = 195701, +    GO_TELEPORTER_EFFECTS_H                     = 195702, -    GO_TELEPORTER_EFFECTS_H = 195702, +    GO_WORKSHOP_BANNER                          = 195133, -    GO_WORKSHOP_BANNER = 195133, +    GO_BRAZIER_1                                = 195402, +    GO_BRAZIER_2                                = 195403, +    GO_BRAZIER_3                                = 195425, +    GO_BRAZIER_4                                = 195424, -    GO_BRAZIER_1 = 195402, -    GO_BRAZIER_2 = 195403, -    GO_BRAZIER_3 = 195425, -    GO_BRAZIER_4 = 195424, +    GO_REFINERY_BANNER                          = 195343, -    GO_REFINERY_BANNER = 195343, +    GO_DOODAD_ND_WINTERORC_WALL_GATEFX_DOOR01   = 195491, -    GO_DOODAD_ND_WINTERORC_WALL_GATEFX_DOOR01 = 195491, +    GO_ALLIANCE_BANNER_DOCK                     = 195153, +    GO_ALLIANCE_BANNER_DOCK_CONT                = 195154, +    GO_HORDE_BANNER_DOCK                        = 195155, +    GO_HORDE_BANNER_DOCK_CONT                   = 195156, -    GO_ALLIANCE_BANNER_DOCK = 195153, -    GO_ALLIANCE_BANNER_DOCK_CONT = 195154, -    GO_HORDE_BANNER_DOCK = 195155, -    GO_HORDE_BANNER_DOCK_CONT = 195156, +    GO_HORDE_BANNER_HANGAR                      = 195130, +    GO_HORDE_BANNER_HANGAR_CONT                 = 195145, +    GO_ALLIANCE_BANNER_HANGAR                   = 195132, +    GO_ALLIANCE_BANNER_HANGAR_CONT              = 195144, -    GO_HORDE_BANNER_HANGAR = 195130, -    GO_HORDE_BANNER_HANGAR_CONT = 195145, -    GO_ALLIANCE_BANNER_HANGAR = 195132, -    GO_ALLIANCE_BANNER_HANGAR_CONT= 195144, +    GO_ALLIANCE_BANNER_QUARRY                   = 195334, +    GO_ALLIANCE_BANNER_QUARRY_CONT              = 195335, +    GO_HORDE_BANNER_QUARRY                      = 195336, +    GO_HORDE_BANNER_QUARRY_CONT                 = 195337, -    GO_ALLIANCE_BANNER_QUARRY = 195334, -    GO_ALLIANCE_BANNER_QUARRY_CONT = 195335, -    GO_HORDE_BANNER_QUARRY = 195336, -    GO_HORDE_BANNER_QUARRY_CONT = 195337, +    GO_ALLIANCE_BANNER_REFINERY                 = 195339, +    GO_ALLIANCE_BANNER_REFINERY_CONT            = 195340, +    GO_HORDE_BANNER_REFINERY                    = 195341, +    GO_HORDE_BANNER_REFINERY_CONT               = 195342, -    GO_ALLIANCE_BANNER_REFINERY = 195339, -    GO_ALLIANCE_BANNER_REFINERY_CONT = 195340, -    GO_HORDE_BANNER_REFINERY = 195341, -    GO_HORDE_BANNER_REFINERY_CONT = 195342, +    GO_ALLIANCE_BANNER_WORKSHOP                 = 195149, +    GO_ALLIANCE_BANNER_WORKSHOP_CONT            = 195150, +    GO_HORDE_BANNER_WORKSHOP                    = 195151, +    GO_HORDE_BANNER_WORKSHOP_CONT               = 195152, -    GO_ALLIANCE_BANNER_WORKSHOP = 195149, -    GO_ALLIANCE_BANNER_WORKSHOP_CONT = 195150, -    GO_HORDE_BANNER_WORKSHOP = 195151, -    GO_HORDE_BANNER_WORKSHOP_CONT = 195152, +    GO_ALLIANCE_BANNER_GRAVEYARD_A              = 195396, +    GO_ALLIANCE_BANNER_GRAVEYARD_A_CONT         = 195397, +    GO_HORDE_BANNER_GRAVEYARD_A                 = 195398, +    GO_HORDE_BANNER_GRAVEYARD_A_CONT            = 195399, -    GO_ALLIANCE_BANNER_GRAVEYARD_A = 195396, -    GO_ALLIANCE_BANNER_GRAVEYARD_A_CONT = 195397, -    GO_HORDE_BANNER_GRAVEYARD_A = 195398, -    GO_HORDE_BANNER_GRAVEYARD_A_CONT = 195399, +    GO_ALLIANCE_BANNER_GRAVEYARD_H              = 195391, +    GO_ALLIANCE_BANNER_GRAVEYARD_H_CONT         = 195392, +    GO_HORDE_BANNER_GRAVEYARD_H                 = 195393, +    GO_HORDE_BANNER_GRAVEYARD_H_CONT            = 195394, -    GO_ALLIANCE_BANNER_GRAVEYARD_H = 195391, -    GO_ALLIANCE_BANNER_GRAVEYARD_H_CONT = 195392, -    GO_HORDE_BANNER_GRAVEYARD_H = 195393, -    GO_HORDE_BANNER_GRAVEYARD_H_CONT = 195394, - -    GO_HORDE_GUNSHIP = 195276, -    GO_ALLIANCE_GUNSHIP = 195121 +    GO_HORDE_GUNSHIP                            = 195276, +    GO_ALLIANCE_GUNSHIP                         = 195121  };  #define MAX_REINFORCEMENTS 300 @@ -198,7 +202,7 @@ enum Times  enum Actions  { -    ACTION_TELEPORT_PLAYER_TO_TRANSPORT = 1 +    ACTION_GUNSHIP_READY = 1  };  struct ICNpc @@ -257,6 +261,8 @@ enum BG_IC_GOs      BG_IC_GO_DOODAD_HU_PORTCULLIS01_2,      BG_IC_GO_DOODAD_ND_HUMAN_GATE_CLOSEDFX_DOOR01, +    BG_IC_GO_DOODAD_ND_HUMAN_GATE_CLOSEDFX_DOOR02, +    BG_IC_GO_DOODAD_ND_HUMAN_GATE_CLOSEDFX_DOOR03,      BG_IC_GO_DOODAD_PORTCULLISACTIVE01, @@ -306,6 +312,8 @@ enum BG_IC_GOs      BG_IC_GO_HUGE_SEAFORIUM_BOMBS_H_4,      BG_IC_GO_DOODAD_ND_WINTERORC_WALL_GATEFX_DOOR01, +    BG_IC_GO_DOODAD_ND_WINTERORC_WALL_GATEFX_DOOR02, +    BG_IC_GO_DOODAD_ND_WINTERORC_WALL_GATEFX_DOOR03,      BG_IC_GO_SEAFORIUM_BOMBS_1,      BG_IC_GO_SEAFORIUM_BOMBS_2, @@ -314,6 +322,10 @@ enum BG_IC_GOs      BG_IC_GO_HANGAR_TELEPORTER_2,      BG_IC_GO_HANGAR_TELEPORTER_3, +    BG_IC_GO_HANGAR_TELEPORTER_EFFECT_1, +    BG_IC_GO_HANGAR_TELEPORTER_EFFECT_2, +    BG_IC_GO_HANGAR_TELEPORTER_EFFECT_3, +      BG_IC_GO_TELEPORTER_1_1,      BG_IC_GO_TELEPORTER_1_2,      BG_IC_GO_TELEPORTER_2_1, @@ -408,6 +420,10 @@ enum BG_IC_NPCs      BG_IC_NPC_CATAPULT_3_H,      BG_IC_NPC_CATAPULT_4_H, +    BG_IC_NPC_WORLD_TRIGGER_NOT_FLOATING, +    BG_IC_NPC_GUNSHIP_CAPTAIN_1, +    BG_IC_NPC_GUNSHIP_CAPTAIN_2, +      BG_IC_NPC_SPIRIT_GUIDE_1,      BG_IC_NPC_SPIRIT_GUIDE_2,      BG_IC_NPC_SPIRIT_GUIDE_3, @@ -427,26 +443,33 @@ enum BannersTypes  enum BG_IC_MaxSpawns  { -    MAX_NORMAL_GAMEOBJECTS_SPAWNS = BG_IC_GO_DOODAD_ND_WINTERORC_WALL_GATEFX_DOOR01+1, -    MAX_NORMAL_NPCS_SPAWNS = BG_IC_NPC_KEEP_CANNON_25+1, -    MAX_WORKSHOP_SPAWNS = 10, -    MAX_DOCKS_SPAWNS = 12, -    MAX_SPIRIT_GUIDES_SPAWNS = 7, -    MAX_HANGAR_TELEPORTERS_SPAWNS = 3, -    MAX_AIRSHIPS_SPAWNS = 2, -    MAX_FORTRESS_GATES_SPAWNS = 6, -    MAX_FORTRESS_TELEPORTERS_SPAWNS = 24, +    MAX_NORMAL_GAMEOBJECTS_SPAWNS                       = BG_IC_GO_DOODAD_ND_WINTERORC_WALL_GATEFX_DOOR03+1, +    MAX_NORMAL_NPCS_SPAWNS                              = BG_IC_NPC_KEEP_CANNON_25+1, +    MAX_WORKSHOP_SPAWNS                                 = 10, +    MAX_DOCKS_SPAWNS                                    = 12, +    MAX_SPIRIT_GUIDES_SPAWNS                            = 7, +    MAX_HANGAR_TELEPORTERS_SPAWNS                       = 3, +    MAX_HANGAR_TELEPORTER_EFFECTS_SPAWNS                = 3, +    MAX_AIRSHIPS_SPAWNS                                 = 2, +    MAX_FORTRESS_GATES_SPAWNS                           = 6, +    MAX_FORTRESS_TELEPORTERS_SPAWNS                     = 12, +    MAX_FORTRESS_TELEPORTER_EFFECTS_SPAWNS              = 12, +    MAX_HANGAR_NPCS_SPAWNS                              = 3,      // docks -    MAX_GLAIVE_THROWERS_SPAWNS_PER_FACTION = 2, -    MAX_CATAPULTS_SPAWNS_PER_FACTION = 4, +    MAX_GLAIVE_THROWERS_SPAWNS_PER_FACTION              = 2, +    MAX_CATAPULTS_SPAWNS_PER_FACTION                    = 4,      // workshop -    MAX_DEMOLISHERS_SPAWNS_PER_FACTION = 4, -    MAX_WORKSHOP_BOMBS_SPAWNS_PER_FACTION = 2 +    MAX_DEMOLISHERS_SPAWNS_PER_FACTION                  = 4, +    MAX_WORKSHOP_BOMBS_SPAWNS_PER_FACTION               = 2, + +    // Hangar +    MAX_TRIGGER_SPAWNS_PER_FACTION                      = 1, +    MAX_CAPTAIN_SPAWNS_PER_FACTION                      = 2,  }; -const ICNpc BG_IC_NpcSpawnlocs[MAX_NORMAL_NPCS_SPAWNS]= +const ICNpc BG_IC_NpcSpawnlocs[MAX_NORMAL_NPCS_SPAWNS] =  {      {BG_IC_NPC_OVERLORD_AGMAR, NPC_OVERLORD_AGMAR, TEAM_HORDE, 1295.44f, -765.733f, 70.0541f, 0.0f}, //Overlord Agmar 1      {BG_IC_NPC_HIGH_COMMANDER_HALFORD_WYRMBANE, NPC_HIGH_COMMANDER_HALFORD_WYRMBANE, TEAM_ALLIANCE, 224.983f, -831.573f, 60.9034f, 0.0f}, //High Commander Halford Wyrmbane 2 @@ -485,7 +508,7 @@ const ICNpc BG_IC_NpcSpawnlocs[MAX_NORMAL_NPCS_SPAWNS]=      {BG_IC_NPC_KEEP_CANNON_22, NPC_KEEP_CANNON, TEAM_HORDE, 1144.33f, -833.309f, 87.9268f, 2.14675f}, // 32      {BG_IC_NPC_KEEP_CANNON_23, NPC_KEEP_CANNON, TEAM_HORDE, 1135.29f, -840.878f, 88.0252f, 2.30383f}, // 33      {BG_IC_NPC_KEEP_CANNON_24, NPC_KEEP_CANNON, TEAM_HORDE, 1142.59f, -691.946f, 87.9756f, 3.9619f}, // 34 -    {BG_IC_NPC_KEEP_CANNON_25, NPC_KEEP_CANNON, TEAM_HORDE, 1166.13f, -858.391f, 87.9653f, 5.63741f}, // 35 +    {BG_IC_NPC_KEEP_CANNON_25, NPC_KEEP_CANNON, TEAM_HORDE, 1166.13f, -858.391f, 87.9653f, 5.63741f} // 35  };  const Position BG_IC_WorkshopVehicles[5] = @@ -499,8 +522,8 @@ const Position BG_IC_WorkshopVehicles[5] =  const Position BG_IC_DocksVehiclesGlaives[2] =  { -    { 779.3125f, -342.972229f, 12.2104874f, 4.712389f }, // Glaive Throwers -    { 790.029541f, -342.899323f, 12.2128582f, 4.71238f }, // Glaive Throwers +    {779.3125f, -342.972229f, 12.2104874f, 4.712389f}, // Glaive Throwers +    {790.029541f, -342.899323f, 12.2128582f, 4.71238f} // Glaive Throwers  };  const Position BG_IC_DocksVehiclesCatapults[4] = @@ -508,14 +531,35 @@ const Position BG_IC_DocksVehiclesCatapults[4] =      {757.283f, -341.7795f, 12.2113762f, 4.729842f}, // Catapults      {766.947937f, -342.053833f, 12.2009945f, 4.694f}, // Catapults      {800.3785f, -342.607635f, 12.1669979f, 4.6774f}, // Catapults -    {810.7257f, -342.083344f, 12.1675768f, 4.6600f}, // Catapults +    {810.7257f, -342.083344f, 12.1675768f, 4.6600f} // Catapults  };  const Position BG_IC_HangarTeleporters[3] =  { -    {827.958f, -994.467f, 134.071f, 0.0f}, // Gunship Portal -    {738.613f, -1106.58f, 134.745f, 2.54818f}, // Gunship Portal -    {672.283f, -1156.99f, 133.706f, 1.37881f}, // Gunship Portal +    {827.9219f, -993.3249f, 134.1972f, 3.141593f}, // Gunship Portal +    {739.0226f, -1106.661f, 134.7551f, 2.426008f}, // Gunship Portal +    {672.0799f, -1156.776f, 133.7057f, 1.832595f} // Gunship Portal +}; + +const Position BG_IC_HangarTeleporterEffects[3] = +{ +    {827.9236f, -993.2986f, 134.2002f, 3.141593f}, // Gunship Portal Effect +    {739.0139f, -1106.661f, 134.7548f, 3.141593f}, // Gunship Portal Effect +    {672.0868f, -1156.786f, 133.7057f, 3.141593f} // Gunship Portal Effect +}; + +const Position BG_IC_HangarTrigger[2] = +{ +    {11.69965f, 0.034146f, 20.62076f, 3.211406f}, +    {7.305609f, -0.095246f, 34.51022f, 3.159046f} +}; + +const Position BG_IC_HangarCaptains[4] = +{ +    {825.6667f, -994.00520f, 134.3569f, 3.403392f}, +    {53.65112f, -0.1139221f, 30.09546f, 3.106686f}, +    {826.2205f, -994.40280f, 134.2812f, 3.351032f}, +    {10.89952f, 4.88029700f, 20.49038f, 4.840575f}  };  struct ICGo @@ -541,8 +585,11 @@ const ICGo BG_IC_Teleporters[MAX_FORTRESS_TELEPORTERS_SPAWNS] =      {BG_IC_GO_TELEPORTER_4_2, GO_TELEPORTER_4, 323.54f, -888.361f, 48.9197f, 0.0349063f}, // Teleporter      {BG_IC_GO_TELEPORTER_4_3, GO_TELEPORTER_4, 326.285f, -777.366f, 49.0208f, 3.12412f}, // Teleporter      {BG_IC_GO_TELEPORTER_1_3, GO_TELEPORTER_1, 1235.09f, -857.898f, 48.9163f, 3.07177f}, // Teleporter -    {BG_IC_GO_TELEPORTER_2_3, GO_TELEPORTER_2, 1158.76f, -746.182f, 48.6277f, -1.51844f}, // Teleporter +    {BG_IC_GO_TELEPORTER_2_3, GO_TELEPORTER_2, 1158.76f, -746.182f, 48.6277f, -1.51844f} // Teleporter +}; +const ICGo BG_IC_TeleporterEffects[MAX_FORTRESS_TELEPORTER_EFFECTS_SPAWNS] = +{      {BG_IC_GO_TELEPORTER_EFFECTS_A_1, GO_TELEPORTER_EFFECTS_A, 425.686f, -857.092f, 48.51f, -1.62316f}, // Teleporter Effects (Alliance)      {BG_IC_GO_TELEPORTER_EFFECTS_A_2, GO_TELEPORTER_EFFECTS_A, 324.634f, -749.148f, 49.359f, 0.0174525f}, // Teleporter Effects (Alliance)      {BG_IC_GO_TELEPORTER_EFFECTS_A_3, GO_TELEPORTER_EFFECTS_A, 311.911f, -913.986f, 48.8157f, 3.08918f}, // Teleporter Effects (Alliance) @@ -555,7 +602,7 @@ const ICGo BG_IC_Teleporters[MAX_FORTRESS_TELEPORTERS_SPAWNS] =      {BG_IC_GO_TELEPORTER_EFFECTS_H_3, GO_TELEPORTER_EFFECTS_H, 1233.25f, -844.573f, 48.8836f, 0.0174525f}, // Teleporter Effects (Horde)      {BG_IC_GO_TELEPORTER_EFFECTS_H_4, GO_TELEPORTER_EFFECTS_H, 1235.07f, -857.957f, 48.9163f, 3.05433f}, // Teleporter Effects (Horde)      {BG_IC_GO_TELEPORTER_EFFECTS_H_5, GO_TELEPORTER_EFFECTS_H, 1236.46f, -669.344f, 48.2684f, 0.087266f}, // Teleporter Effects (Horde) -    {BG_IC_GO_TELEPORTER_EFFECTS_H_6, GO_TELEPORTER_EFFECTS_H, 1235.6f, -683.806f, 49.3028f, -3.07177f}, // Teleporter Effects (Horde) +    {BG_IC_GO_TELEPORTER_EFFECTS_H_6, GO_TELEPORTER_EFFECTS_H, 1235.6f, -683.806f, 49.3028f, -3.07177f} // Teleporter Effects (Horde)  };  const ICGo BG_IC_ObjSpawnlocs[MAX_NORMAL_GAMEOBJECTS_SPAWNS] = @@ -612,6 +659,8 @@ const ICGo BG_IC_ObjSpawnlocs[MAX_NORMAL_GAMEOBJECTS_SPAWNS] =      {BG_IC_GO_DOODAD_HU_PORTCULLIS01_2, GO_DOODAD_HU_PORTCULLIS01, 399.802f, -885.208f, 50.1939f, 2.516f}, // Doodad_HU_Portcullis01      {BG_IC_GO_DOODAD_ND_HUMAN_GATE_CLOSEDFX_DOOR01, GO_DOODAD_ND_HUMAN_GATE_CLOSEDFX_DOOR01, 413.479f, -833.95f, 48.5238f, 3.14159f}, // Doodad_ND_Human_Gate_ClosedFX_Door01 +    {BG_IC_GO_DOODAD_ND_HUMAN_GATE_CLOSEDFX_DOOR02, GO_DOODAD_ND_HUMAN_GATE_CLOSEDFX_DOOR01, 351.615f, -762.75f, 48.91625f, 4.71292f}, // Doodad_ND_Human_Gate_ClosedFX_Door01 +    {BG_IC_GO_DOODAD_ND_HUMAN_GATE_CLOSEDFX_DOOR03, GO_DOODAD_ND_HUMAN_GATE_CLOSEDFX_DOOR01, 351.024f, -903.33f, 48.92472f, 1.570796f}, // Doodad_ND_Human_Gate_ClosedFX_Door01      {BG_IC_GO_DOODAD_PORTCULLISACTIVE01, GO_DOODAD_PORTCULLISACTIVE01, -832.595f, 51.4109f, -0.0261791f, 0.0f}, // Doodad_PortcullisActive01 @@ -646,7 +695,9 @@ const ICGo BG_IC_ObjSpawnlocs[MAX_NORMAL_GAMEOBJECTS_SPAWNS] =      {BG_IC_GO_HUGE_SEAFORIUM_BOMBS_H_3, GO_HUGE_SEAFORIUM_BOMB_H, 1273.066f, -786.572937f, 48.9419174f, -0.94247663f},      {BG_IC_GO_HUGE_SEAFORIUM_BOMBS_H_4, GO_HUGE_SEAFORIUM_BOMB_H, 1273.849f, -796.2778f, 48.9364281f, -2.75761318f}, -    {BG_IC_GO_DOODAD_ND_WINTERORC_WALL_GATEFX_DOOR01, GO_DOODAD_ND_WINTERORC_WALL_GATEFX_DOOR01, 1150.9f, -762.606f, 47.0f, 3.14159f} // Doodad_ND_WinterOrc_Wall_GateFX_Door01 -> this was not sniffed because I only had alliance sniffs +    {BG_IC_GO_DOODAD_ND_WINTERORC_WALL_GATEFX_DOOR01, GO_DOODAD_ND_WINTERORC_WALL_GATEFX_DOOR01, 1150.903f, -762.6059f, 47.50768f, 3.141593f}, +    {BG_IC_GO_DOODAD_ND_WINTERORC_WALL_GATEFX_DOOR02, GO_DOODAD_ND_WINTERORC_WALL_GATEFX_DOOR01, 1217.899f, -676.9479f, 47.63408f, 1.570796f}, +    {BG_IC_GO_DOODAD_ND_WINTERORC_WALL_GATEFX_DOOR03, GO_DOODAD_ND_WINTERORC_WALL_GATEFX_DOOR01, 1218.743f, -851.1545f, 48.25328f, 4.712392f}  };  const Position workshopBombs[2] = @@ -657,16 +708,20 @@ const Position workshopBombs[2] =  enum Spells  { -    SPELL_OIL_REFINERY                     = 68719, -    SPELL_QUARRY                           = 68720, -    SPELL_PARACHUTE                        = 66656, -    SPELL_SLOW_FALL                        = 12438, -    SPELL_DESTROYED_VEHICLE_ACHIEVEMENT    = 68357, -    SPELL_BACK_DOOR_JOB_ACHIEVEMENT        = 68502, -    SPELL_DRIVING_CREDIT_DEMOLISHER        = 68365, -    SPELL_DRIVING_CREDIT_GLAIVE            = 68363, -    SPELL_DRIVING_CREDIT_SIEGE             = 68364, -    SPELL_DRIVING_CREDIT_CATAPULT          = 68362, +    SPELL_OIL_REFINERY                      = 68719, +    SPELL_QUARRY                            = 68720, +    SPELL_PARACHUTE                         = 66656, +    SPELL_SLOW_FALL                         = 12438, +    SPELL_DESTROYED_VEHICLE_ACHIEVEMENT     = 68357, +    SPELL_BACK_DOOR_JOB_ACHIEVEMENT         = 68502, +    SPELL_DRIVING_CREDIT_DEMOLISHER         = 68365, +    SPELL_DRIVING_CREDIT_GLAIVE             = 68363, +    SPELL_DRIVING_CREDIT_SIEGE              = 68364, +    SPELL_DRIVING_CREDIT_CATAPULT           = 68362, +    SPELL_SIMPLE_TELEPORT                   = 12980, +    SPELL_TELEPORT_VISUAL_ONLY              = 51347, +    SPELL_PARACHUTE_IC                      = 66657, +    SPELL_LAUNCH_NO_FALLING_DAMAGE          = 66251  };  enum BG_IC_Objectives @@ -677,71 +732,71 @@ enum BG_IC_Objectives  enum ICWorldStates  { -    BG_IC_ALLIANCE_RENFORT_SET      = 4221, -    BG_IC_HORDE_RENFORT_SET         = 4222, -    BG_IC_ALLIANCE_RENFORT          = 4226, -    BG_IC_HORDE_RENFORT             = 4227, -    BG_IC_GATE_FRONT_H_WS_CLOSED    = 4317, -    BG_IC_GATE_WEST_H_WS_CLOSED     = 4318, -    BG_IC_GATE_EAST_H_WS_CLOSED     = 4319, -    BG_IC_GATE_FRONT_A_WS_CLOSED    = 4328, -    BG_IC_GATE_WEST_A_WS_CLOSED     = 4327, -    BG_IC_GATE_EAST_A_WS_CLOSED     = 4326, -    BG_IC_GATE_FRONT_H_WS_OPEN      = 4322, -    BG_IC_GATE_WEST_H_WS_OPEN       = 4321, -    BG_IC_GATE_EAST_H_WS_OPEN       = 4320, -    BG_IC_GATE_FRONT_A_WS_OPEN      = 4323, -    BG_IC_GATE_WEST_A_WS_OPEN       = 4324, -    BG_IC_GATE_EAST_A_WS_OPEN       = 4325, - -    BG_IC_DOCKS_UNCONTROLLED = 4301, -    BG_IC_DOCKS_CONFLICT_A = 4305, -    BG_IC_DOCKS_CONFLICT_H = 4302, -    BG_IC_DOCKS_CONTROLLED_A = 4304, -    BG_IC_DOCKS_CONTROLLED_H = 4303, - -    BG_IC_HANGAR_UNCONTROLLED = 4296, -    BG_IC_HANGAR_CONFLICT_A = 4300, -    BG_IC_HANGAR_CONFLICT_H = 4297, -    BG_IC_HANGAR_CONTROLLED_A = 4299, -    BG_IC_HANGAR_CONTROLLED_H = 4298, - -    BG_IC_QUARRY_UNCONTROLLED = 4306, -    BG_IC_QUARRY_CONFLICT_A = 4310, -    BG_IC_QUARRY_CONFLICT_H = 4307, -    BG_IC_QUARRY_CONTROLLED_A = 4309, -    BG_IC_QUARRY_CONTROLLED_H = 4308, - -    BG_IC_REFINERY_UNCONTROLLED = 4311, -    BG_IC_REFINERY_CONFLICT_A = 4315, -    BG_IC_REFINERY_CONFLICT_H = 4312, -    BG_IC_REFINERY_CONTROLLED_A = 4314, -    BG_IC_REFINERY_CONTROLLED_H = 4313, - -    BG_IC_WORKSHOP_UNCONTROLLED = 4294, -    BG_IC_WORKSHOP_CONFLICT_A = 4228, -    BG_IC_WORKSHOP_CONFLICT_H = 4293, -    BG_IC_WORKSHOP_CONTROLLED_A = 4229, -    BG_IC_WORKSHOP_CONTROLLED_H = 4230, - -    BG_IC_ALLIANCE_KEEP_UNCONTROLLED = 4341, -    BG_IC_ALLIANCE_KEEP_CONFLICT_A = 4342, -    BG_IC_ALLIANCE_KEEP_CONFLICT_H = 4343, -    BG_IC_ALLIANCE_KEEP_CONTROLLED_A = 4339, -    BG_IC_ALLIANCE_KEEP_CONTROLLED_H = 4340, - -    BG_IC_HORDE_KEEP_UNCONTROLLED = 4346, -    BG_IC_HORDE_KEEP_CONFLICT_A = 4347, -    BG_IC_HORDE_KEEP_CONFLICT_H = 4348, -    BG_IC_HORDE_KEEP_CONTROLLED_A = 4344, -    BG_IC_HORDE_KEEP_CONTROLLED_H = 4345 +    BG_IC_ALLIANCE_RENFORT_SET          = 4221, +    BG_IC_HORDE_RENFORT_SET             = 4222, +    BG_IC_ALLIANCE_RENFORT              = 4226, +    BG_IC_HORDE_RENFORT                 = 4227, +    BG_IC_GATE_FRONT_H_WS_CLOSED        = 4317, +    BG_IC_GATE_WEST_H_WS_CLOSED         = 4318, +    BG_IC_GATE_EAST_H_WS_CLOSED         = 4319, +    BG_IC_GATE_FRONT_A_WS_CLOSED        = 4328, +    BG_IC_GATE_WEST_A_WS_CLOSED         = 4327, +    BG_IC_GATE_EAST_A_WS_CLOSED         = 4326, +    BG_IC_GATE_FRONT_H_WS_OPEN          = 4322, +    BG_IC_GATE_WEST_H_WS_OPEN           = 4321, +    BG_IC_GATE_EAST_H_WS_OPEN           = 4320, +    BG_IC_GATE_FRONT_A_WS_OPEN          = 4323, +    BG_IC_GATE_WEST_A_WS_OPEN           = 4324, +    BG_IC_GATE_EAST_A_WS_OPEN           = 4325, + +    BG_IC_DOCKS_UNCONTROLLED            = 4301, +    BG_IC_DOCKS_CONFLICT_A              = 4305, +    BG_IC_DOCKS_CONFLICT_H              = 4302, +    BG_IC_DOCKS_CONTROLLED_A            = 4304, +    BG_IC_DOCKS_CONTROLLED_H            = 4303, + +    BG_IC_HANGAR_UNCONTROLLED           = 4296, +    BG_IC_HANGAR_CONFLICT_A             = 4300, +    BG_IC_HANGAR_CONFLICT_H             = 4297, +    BG_IC_HANGAR_CONTROLLED_A           = 4299, +    BG_IC_HANGAR_CONTROLLED_H           = 4298, + +    BG_IC_QUARRY_UNCONTROLLED           = 4306, +    BG_IC_QUARRY_CONFLICT_A             = 4310, +    BG_IC_QUARRY_CONFLICT_H             = 4307, +    BG_IC_QUARRY_CONTROLLED_A           = 4309, +    BG_IC_QUARRY_CONTROLLED_H           = 4308, + +    BG_IC_REFINERY_UNCONTROLLED         = 4311, +    BG_IC_REFINERY_CONFLICT_A           = 4315, +    BG_IC_REFINERY_CONFLICT_H           = 4312, +    BG_IC_REFINERY_CONTROLLED_A         = 4314, +    BG_IC_REFINERY_CONTROLLED_H         = 4313, + +    BG_IC_WORKSHOP_UNCONTROLLED         = 4294, +    BG_IC_WORKSHOP_CONFLICT_A           = 4228, +    BG_IC_WORKSHOP_CONFLICT_H           = 4293, +    BG_IC_WORKSHOP_CONTROLLED_A         = 4229, +    BG_IC_WORKSHOP_CONTROLLED_H         = 4230, + +    BG_IC_ALLIANCE_KEEP_UNCONTROLLED    = 4341, +    BG_IC_ALLIANCE_KEEP_CONFLICT_A      = 4342, +    BG_IC_ALLIANCE_KEEP_CONFLICT_H      = 4343, +    BG_IC_ALLIANCE_KEEP_CONTROLLED_A    = 4339, +    BG_IC_ALLIANCE_KEEP_CONTROLLED_H    = 4340, + +    BG_IC_HORDE_KEEP_UNCONTROLLED       = 4346, +    BG_IC_HORDE_KEEP_CONFLICT_A         = 4347, +    BG_IC_HORDE_KEEP_CONFLICT_H         = 4348, +    BG_IC_HORDE_KEEP_CONTROLLED_A       = 4344, +    BG_IC_HORDE_KEEP_CONTROLLED_H       = 4345  };  enum BG_IC_GateState  { -    BG_IC_GATE_OK = 1, -    BG_IC_GATE_DAMAGED = 2, -    BG_IC_GATE_DESTROYED = 3 +    BG_IC_GATE_OK           = 1, +    BG_IC_GATE_DAMAGED      = 2, +    BG_IC_GATE_DESTROYED    = 3  };  enum ICDoorList @@ -781,9 +836,6 @@ enum ICNodeState  const uint32 BG_IC_GraveyardIds[MAX_NODE_TYPES+2] = {0, 0, 1480, 1481, 1482, 1485, 1486, 1483, 1484}; -const Position TransportMovementInfo = {7.305609f, -0.095246f, 34.51022f, 0.0f}; -const Position TeleportToTransportPosition = {661.0f, -1244.0f, 288.0f, 0.0f}; -  Position const BG_IC_SpiritGuidePos[MAX_NODE_TYPES+2] =  {      {0.0f, 0.0f, 0.0f, 0.0f},                     // no grave @@ -797,24 +849,6 @@ Position const BG_IC_SpiritGuidePos[MAX_NODE_TYPES+2] =      {1148.65f, -1250.98f, 16.60f, 1.74f},         // last resort horde  }; -const Position hordeGunshipPassengers[5] = -{ -    {-21.401f, -31.343f, 34.173f, 4.62057f}, -    {-12.1064f, -31.9697f, 34.3807f, 4.62057f}, -    {-2.4877f, -31.9885f, 34.8384f, 4.62057f}, -    {10.2664f, -32.0713f, 35.7357f, 4.62057f}, -    {19.4636f, -30.794f, 36.2254f, 4.83106f} -}; - -const Position allianceGunshipPassengers[5] = -{ -    {-41.7122f, 23.1838f, 22.5605f, 1.60659f}, -    {-31.0354f, 25.1286f, 21.6921f, 1.60659f}, -    {-21.4492f, 25.8326f, 21.6309f, 1.60659f}, -    {-12.4734f, 26.321f, 21.6237f, 1.60659f}, -    {-2.81125f, 26.2077f, 21.6566f, 1.60659f} -}; -  // I.E: Hangar, Quarry, Graveyards .. etc  struct ICNodePoint  { @@ -839,13 +873,13 @@ const ICNodePoint nodePointInitial[7] =      {BG_IC_GO_HANGAR_BANNER, GO_HANGAR_BANNER, TEAM_NEUTRAL, NODE_TYPE_HANGAR, {GO_ALLIANCE_BANNER_HANGAR, GO_ALLIANCE_BANNER_HANGAR_CONT, GO_HORDE_BANNER_HANGAR, GO_HORDE_BANNER_HANGAR_CONT}, false, 0, 0, {BG_IC_HANGAR_UNCONTROLLED, BG_IC_HANGAR_CONFLICT_A, BG_IC_HANGAR_CONFLICT_H, BG_IC_HANGAR_CONTROLLED_A, BG_IC_HANGAR_CONTROLLED_H}, NODE_STATE_UNCONTROLLED, LANG_BG_IC_HANGAR},      {BG_IC_GO_WORKSHOP_BANNER, GO_WORKSHOP_BANNER, TEAM_NEUTRAL, NODE_TYPE_WORKSHOP, {GO_ALLIANCE_BANNER_WORKSHOP, GO_ALLIANCE_BANNER_WORKSHOP_CONT, GO_HORDE_BANNER_WORKSHOP, GO_HORDE_BANNER_WORKSHOP_CONT}, false, 0, 0, {BG_IC_WORKSHOP_UNCONTROLLED, BG_IC_WORKSHOP_CONFLICT_A, BG_IC_WORKSHOP_CONFLICT_H, BG_IC_WORKSHOP_CONTROLLED_A, BG_IC_WORKSHOP_CONTROLLED_H}, NODE_STATE_UNCONTROLLED, LANG_BG_IC_WORKSHOP},      {BG_IC_GO_ALLIANCE_BANNER, GO_ALLIANCE_BANNER, TEAM_ALLIANCE, NODE_TYPE_GRAVEYARD_A, {GO_ALLIANCE_BANNER_GRAVEYARD_A, GO_ALLIANCE_BANNER_GRAVEYARD_A_CONT, GO_HORDE_BANNER_GRAVEYARD_A, GO_HORDE_BANNER_GRAVEYARD_A_CONT}, false, 0, 0, {BG_IC_ALLIANCE_KEEP_UNCONTROLLED, BG_IC_ALLIANCE_KEEP_CONFLICT_A, BG_IC_ALLIANCE_KEEP_CONFLICT_H, BG_IC_ALLIANCE_KEEP_CONTROLLED_A, BG_IC_ALLIANCE_KEEP_CONTROLLED_H}, NODE_STATE_CONTROLLED_A, LANG_BG_IC_ALLIANCE_KEEP}, -    {BG_IC_GO_HORDE_BANNER, GO_HORDE_BANNER, TEAM_HORDE, NODE_TYPE_GRAVEYARD_H, {GO_ALLIANCE_BANNER_GRAVEYARD_H, GO_ALLIANCE_BANNER_GRAVEYARD_H_CONT, GO_HORDE_BANNER_GRAVEYARD_H, GO_HORDE_BANNER_GRAVEYARD_H_CONT}, false, 0, 0, {BG_IC_HORDE_KEEP_UNCONTROLLED, BG_IC_HORDE_KEEP_CONFLICT_A, BG_IC_HORDE_KEEP_CONFLICT_H, BG_IC_HORDE_KEEP_CONTROLLED_A, BG_IC_HORDE_KEEP_CONTROLLED_H}, NODE_STATE_CONTROLLED_H, LANG_BG_IC_HORDE_KEEP}, +    {BG_IC_GO_HORDE_BANNER, GO_HORDE_BANNER, TEAM_HORDE, NODE_TYPE_GRAVEYARD_H, {GO_ALLIANCE_BANNER_GRAVEYARD_H, GO_ALLIANCE_BANNER_GRAVEYARD_H_CONT, GO_HORDE_BANNER_GRAVEYARD_H, GO_HORDE_BANNER_GRAVEYARD_H_CONT}, false, 0, 0, {BG_IC_HORDE_KEEP_UNCONTROLLED, BG_IC_HORDE_KEEP_CONFLICT_A, BG_IC_HORDE_KEEP_CONFLICT_H, BG_IC_HORDE_KEEP_CONTROLLED_A, BG_IC_HORDE_KEEP_CONTROLLED_H}, NODE_STATE_CONTROLLED_H, LANG_BG_IC_HORDE_KEEP}  };  enum HonorRewards  { -    RESOURCE_HONOR_AMOUNT = 12, -    WINNER_HONOR_AMOUNT = 500 +    RESOURCE_HONOR_AMOUNT   = 12, +    WINNER_HONOR_AMOUNT     = 500  };  struct BattlegroundICScore final : public BattlegroundScore @@ -913,8 +947,6 @@ class BattlegroundIC : public Battleground          /* Scorekeeping */          void FillInitialWorldStates(WorldPacket& data) override; -        void DoAction(uint32 action, ObjectGuid var) override; -          void HandlePlayerResurrect(Player* player) override;          uint32 GetNodeState(uint8 nodeType) const { return (uint8)nodePoint[nodeType].nodeState; } diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 14ca3a645d7..9b74797e703 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -62,6 +62,7 @@  #include "Pet.h"  #include "QuestDef.h"  #include "ReputationMgr.h" +#include "revision.h"  #include "SkillDiscovery.h"  #include "SocialMgr.h"  #include "Spell.h" @@ -15262,6 +15263,19 @@ void Player::AddQuest(Quest const* quest, Object* questGiver)      StartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_QUEST, quest_id);      SendQuestUpdate(quest_id); + +    if (sWorld->getBoolConfig(CONFIG_QUEST_ENABLE_QUEST_TRACKER)) // check if Quest Tracker is enabled +    { +        // prepare Quest Tracker datas +        PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_QUEST_TRACK); +        stmt->setUInt32(0, quest_id); +        stmt->setUInt32(1, GetGUIDLow()); +        stmt->setString(2, _HASH); +        stmt->setString(3, _DATE); + +        // add to Quest Tracker +        CharacterDatabase.Execute(stmt); +    }  }  void Player::CompleteQuest(uint32 quest_id) @@ -15282,6 +15296,17 @@ void Player::CompleteQuest(uint32 quest_id)                  SendQuestComplete(qInfo);          }      } + +    if (sWorld->getBoolConfig(CONFIG_QUEST_ENABLE_QUEST_TRACKER)) // check if Quest Tracker is enabled +    { +        // prepare Quest Tracker datas +        PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_QUEST_TRACK_COMPLETE_TIME); +        stmt->setUInt32(0, quest_id); +        stmt->setUInt32(1, GetGUIDLow()); + +        // add to Quest Tracker +        CharacterDatabase.Execute(stmt); +    }  }  void Player::IncompleteQuest(uint32 quest_id) diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index bca95e155d4..30a22f4d193 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -3239,7 +3239,7 @@ void Unit::_UnapplyAura(AuraApplicationMap::iterator &i, AuraRemoveMode removeMo      ASSERT(!aurApp->GetEffectMask());      // Remove totem at next update if totem loses its aura -    if (aurApp->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE && GetTypeId() == TYPEID_UNIT && ToCreature()->IsTotem()&& ToTotem()->GetSummonerGUID() == aura->GetCasterGUID()) +    if (aurApp->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE && GetTypeId() == TYPEID_UNIT && ToCreature()->IsTotem())      {          if (ToTotem()->GetSpell() == aura->GetId() && ToTotem()->GetTotemType() == TOTEM_PASSIVE)              ToTotem()->setDeathState(JUST_DIED); @@ -7123,6 +7123,10 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg      if (cooldown && GetTypeId() == TYPEID_PLAYER && ToPlayer()->HasSpellCooldown(trigger_spell_id))          return false; +    // extra attack should hit same target +    if (triggerEntry->HasEffect(SPELL_EFFECT_ADD_EXTRA_ATTACKS)) +        target = victim; +      // try detect target manually if not set      if (target == NULL)          target = !(procFlags & (PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS | PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS)) && triggerEntry && triggerEntry->IsPositive() ? this : victim; @@ -8153,6 +8157,15 @@ int32 Unit::DealHeal(Unit* victim, uint32 addhealth)      return gain;  } +bool Unit::IsMagnet() const +{ +    // Grounding Totem  +    if (GetUInt32Value(UNIT_CREATED_BY_SPELL) == 8177) /// @todo: find a more generic solution +        return true; + +    return false; +} +  Unit* Unit::GetMagicHitRedirectTarget(Unit* victim, SpellInfo const* spellInfo)  {      // Patch 1.2 notes: Spell Reflection no longer reflects abilities @@ -8168,7 +8181,16 @@ Unit* Unit::GetMagicHitRedirectTarget(Unit* victim, SpellInfo const* spellInfo)                  && _IsValidAttackTarget(magnet, spellInfo))              {                  /// @todo handle this charge drop by proc in cast phase on explicit target -                (*itr)->GetBase()->DropCharge(AURA_REMOVE_BY_EXPIRE); +                if (victim && spellInfo->Speed > 0.0f) +                { +                    // Set up missile speed based delay +                    uint32 delay = uint32(std::floor(std::max<float>(victim->GetDistance(this), 5.0f) / spellInfo->Speed * 1000.0f)); +                    // Schedule charge drop +                    (*itr)->GetBase()->DropChargeDelayed(delay,AURA_REMOVE_BY_EXPIRE); +                } +                else +                    (*itr)->GetBase()->DropCharge(AURA_REMOVE_BY_EXPIRE); +                  return magnet;              }      } diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index fd986083bcb..4d6bb4cd6f1 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -1988,6 +1988,7 @@ class Unit : public WorldObject          uint32 BuildAuraStateUpdateForTarget(Unit* target) const;          bool HasAuraState(AuraStateType flag, SpellInfo const* spellProto = NULL, Unit const* Caster = NULL) const;          void UnsummonAllTotems(); +        bool IsMagnet() const;          Unit* GetMagicHitRedirectTarget(Unit* victim, SpellInfo const* spellInfo);          Unit* GetMeleeHitRedirectTarget(Unit* victim, SpellInfo const* spellInfo = NULL); diff --git a/src/server/game/Entities/Vehicle/Vehicle.cpp b/src/server/game/Entities/Vehicle/Vehicle.cpp index 1e7779065d2..3eefc7d9209 100644 --- a/src/server/game/Entities/Vehicle/Vehicle.cpp +++ b/src/server/game/Entities/Vehicle/Vehicle.cpp @@ -203,6 +203,8 @@ void Vehicle::ApplyAllImmunities()          case 160: // Strand of the Ancients          case 244: // Wintergrasp          case 510: // Isle of Conquest +        case 452: // Isle of Conquest +        case 543: // Isle of Conquest              _me->SetControlled(true, UNIT_STATE_ROOT);              // why we need to apply this? we can simple add immunities to slow mechanic in DB              _me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_DECREASE_SPEED, true); diff --git a/src/server/game/Handlers/QuestHandler.cpp b/src/server/game/Handlers/QuestHandler.cpp index 331256c7edd..8eade08b32c 100644 --- a/src/server/game/Handlers/QuestHandler.cpp +++ b/src/server/game/Handlers/QuestHandler.cpp @@ -427,6 +427,17 @@ void WorldSession::HandleQuestLogRemoveQuest(WorldPacket& recvData)              _player->RemoveTimedAchievement(ACHIEVEMENT_TIMED_TYPE_QUEST, questId);              TC_LOG_INFO("network", "Player %u abandoned quest %u", _player->GetGUIDLow(), questId); + +            if (sWorld->getBoolConfig(CONFIG_QUEST_ENABLE_QUEST_TRACKER)) // check if Quest Tracker is enabled +            { +                // prepare Quest Tracker datas +                PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_QUEST_TRACK_ABANDON_TIME); +                stmt->setUInt32(0, questId); +                stmt->setUInt32(1, _player->GetGUIDLow()); + +                // add to Quest Tracker +                CharacterDatabase.Execute(stmt); +            }          }          _player->SetQuestSlot(slot, 0); diff --git a/src/server/game/Instances/InstanceScript.h b/src/server/game/Instances/InstanceScript.h index 24a0296491c..ccc98de0de7 100644 --- a/src/server/game/Instances/InstanceScript.h +++ b/src/server/game/Instances/InstanceScript.h @@ -247,6 +247,8 @@ class InstanceScript : public ZoneScript          // ReCheck PhaseTemplate related conditions          void UpdatePhasing(); +        uint32 GetEncounterCount() const { return bosses.size(); } +      protected:          void SetHeaders(std::string const& dataHeaders);          void SetBossNumber(uint32 number) { bosses.resize(number); } diff --git a/src/server/game/Miscellaneous/Language.h b/src/server/game/Miscellaneous/Language.h index fe38c0dff62..41654f80dd4 100644 --- a/src/server/game/Miscellaneous/Language.h +++ b/src/server/game/Miscellaneous/Language.h @@ -1118,8 +1118,15 @@ enum TrinityStrings      LANG_COMMAND_INST_STAT_GROUPSBOUND  = 5054,      LANG_NOT_DUNGEON                    = 5055, // Map is not a dungeon.      LANG_NO_INSTANCE_DATA               = 5056, // Map has no instance data. +    LANG_COMMAND_INST_SET_BOSS_STATE    = 5057, +    LANG_COMMAND_INST_GET_BOSS_STATE    = 5058, -    // Room for more Trinity strings      5057-9999 +    // Mutehistory commands +    LANG_COMMAND_MUTEHISTORY            = 5059, +    LANG_COMMAND_MUTEHISTORY_EMPTY      = 5060, +    LANG_COMMAND_MUTEHISTORY_OUTPUT     = 5061, + +    // Room for more Trinity strings      5062-9999      // Level requirement notifications      LANG_SAY_REQ                        = 6604, diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 3d0955f5d97..81b7198b2e8 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -113,8 +113,6 @@ SpellCastTargets::SpellCastTargets() : m_elevation(0), m_speed(0), m_strTarget()      m_objectTarget = NULL;      m_itemTarget = NULL; -    m_objectTargetGUID.Clear(); -    m_itemTargetGUID.Clear();      m_itemTargetEntry  = 0;      m_targetMask = 0; @@ -212,6 +210,28 @@ void SpellCastTargets::Write(ByteBuffer& data)          data << m_strTarget;  } +ObjectGuid SpellCastTargets::GetOrigUnitTargetGUID() const +{ +    switch (m_origObjectTargetGUID.GetHigh()) +    { +        case HIGHGUID_PLAYER: +        case HIGHGUID_VEHICLE: +        case HIGHGUID_UNIT: +        case HIGHGUID_PET: +            return m_origObjectTargetGUID; +        default: +            return ObjectGuid(); +    } +} + +void SpellCastTargets::SetOrigUnitTarget(Unit* target) +{ +    if (!target) +        return; + +    m_origObjectTargetGUID = target->GetGUID(); +} +  ObjectGuid SpellCastTargets::GetUnitTargetGUID() const  {      if (m_objectTargetGUID.IsUnit()) @@ -638,6 +658,7 @@ Spell::~Spell()  void Spell::InitExplicitTargets(SpellCastTargets const& targets)  {      m_targets = targets; +    m_targets.SetOrigUnitTarget(m_targets.GetUnitTarget());      // this function tries to correct spell explicit targets for spell      // client doesn't send explicit targets correctly sometimes - we need to fix such spells serverside      // this also makes sure that we correctly send explicit targets to client (removes redundant data) @@ -3411,8 +3432,13 @@ void Spell::_handle_finish_phase()             HandleHolyPower(m_caster->m_movedPlayer);      } -    if (m_caster->m_extraAttacks && GetSpellInfo()->HasEffect(SPELL_EFFECT_ADD_EXTRA_ATTACKS)) -        m_caster->HandleProcExtraAttackFor(m_caster->GetVictim()); +    if (m_caster->m_extraAttacks && m_spellInfo->HasEffect(SPELL_EFFECT_ADD_EXTRA_ATTACKS)) +    { +        if (Unit* victim = ObjectAccessor::FindUnit(m_targets.GetOrigUnitTargetGUID())) +            m_caster->HandleProcExtraAttackFor(victim); +        else +            m_caster->m_extraAttacks = 0; +    }      /// @todo trigger proc phase finish here  } diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h index 9fc3deaef99..65fe51b37e3 100644 --- a/src/server/game/Spells/Spell.h +++ b/src/server/game/Spells/Spell.h @@ -109,6 +109,9 @@ class SpellCastTargets          void SetTargetFlag(SpellCastTargetFlags flag) { m_targetMask |= flag; } +        ObjectGuid GetOrigUnitTargetGUID() const; +        void SetOrigUnitTarget(Unit* target); +          ObjectGuid GetUnitTargetGUID() const;          Unit* GetUnitTarget() const;          void SetUnitTarget(Unit* target); @@ -174,6 +177,7 @@ class SpellCastTargets          Item* m_itemTarget;          // object GUID/etc, can be used always +        ObjectGuid m_origObjectTargetGUID;          ObjectGuid m_objectTargetGUID;          ObjectGuid m_itemTargetGUID;          uint32 m_itemTargetEntry; diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index b68b6dfbc04..6f800c4ed13 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -4276,7 +4276,7 @@ void Spell::EffectAddExtraAttacks(SpellEffIndex effIndex)      if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)          return; -    if (!unitTarget || !unitTarget->IsAlive() || !unitTarget->GetVictim()) +    if (!unitTarget || !unitTarget->IsAlive())          return;      if (unitTarget->m_extraAttacks) @@ -4284,7 +4284,7 @@ void Spell::EffectAddExtraAttacks(SpellEffIndex effIndex)      unitTarget->m_extraAttacks = damage; -    ExecuteLogEffectExtraAttacks(effIndex, unitTarget->GetVictim(), damage); +    ExecuteLogEffectExtraAttacks(effIndex, unitTarget, damage);  }  void Spell::EffectParry(SpellEffIndex /*effIndex*/) diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index 49e84d26d60..62d5763d6e2 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -1911,6 +1911,11 @@ bool SpellInfo::CheckTargetCreatureType(Unit const* target) const          else              return true;      } + +    // if target is magnet (i.e Grounding Totem) the check is skipped +    if (target->IsMagnet()) +        return true; +      uint32 creatureType = target->GetCreatureTypeMask();      return !TargetCreatureType || !creatureType || (creatureType & TargetCreatureType);  } diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index d3d06d0ee8a..a43baed9ae0 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -996,6 +996,8 @@ void World::LoadConfigSettings(bool reload)      m_int_configs[CONFIG_WORLD_BOSS_LEVEL_DIFF] = sConfigMgr->GetIntDefault("WorldBossLevelDiff", 3); +    m_bool_configs[CONFIG_QUEST_ENABLE_QUEST_TRACKER] = sConfigMgr->GetBoolDefault("Quests.EnableQuestTracker", false); +      // note: disable value (-1) will assigned as 0xFFFFFFF, to prevent overflow at calculations limit it to max possible player level MAX_LEVEL(100)      m_int_configs[CONFIG_QUEST_LOW_LEVEL_HIDE_DIFF] = sConfigMgr->GetIntDefault("Quests.LowLevelHideDiff", 4);      if (m_int_configs[CONFIG_QUEST_LOW_LEVEL_HIDE_DIFF] > MAX_LEVEL) diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h index 2c74e3929fe..ae07a5434f1 100644 --- a/src/server/game/World/World.h +++ b/src/server/game/World/World.h @@ -157,6 +157,7 @@ enum WorldBoolConfigs      CONFIG_PDUMP_NO_OVERWRITE,      CONFIG_QUEST_IGNORE_AUTO_ACCEPT,      CONFIG_QUEST_IGNORE_AUTO_COMPLETE, +    CONFIG_QUEST_ENABLE_QUEST_TRACKER,      CONFIG_WARDEN_ENABLED,      CONFIG_ENABLE_MMAPS,      CONFIG_WINTERGRASP_ENABLE, diff --git a/src/server/scripts/Commands/cs_instance.cpp b/src/server/scripts/Commands/cs_instance.cpp index a426c49a5f7..d2cec87e08f 100644 --- a/src/server/scripts/Commands/cs_instance.cpp +++ b/src/server/scripts/Commands/cs_instance.cpp @@ -40,11 +40,13 @@ public:      {          static ChatCommand instanceCommandTable[] =          { -            { "listbinds", rbac::RBAC_PERM_COMMAND_INSTANCE_LISTBINDS, false, &HandleInstanceListBindsCommand,    "", NULL }, -            { "unbind",    rbac::RBAC_PERM_COMMAND_INSTANCE_UNBIND,    false, &HandleInstanceUnbindCommand,       "", NULL }, -            { "stats",     rbac::RBAC_PERM_COMMAND_INSTANCE_STATS,      true, &HandleInstanceStatsCommand,        "", NULL }, -            { "savedata",  rbac::RBAC_PERM_COMMAND_INSTANCE_SAVEDATA,  false, &HandleInstanceSaveDataCommand,     "", NULL }, -            { NULL,        0,                                    false, NULL,                               "", NULL } +            { "listbinds",    rbac::RBAC_PERM_COMMAND_INSTANCE_LISTBINDS,     false, &HandleInstanceListBindsCommand,    "", NULL }, +            { "unbind",       rbac::RBAC_PERM_COMMAND_INSTANCE_UNBIND,        false, &HandleInstanceUnbindCommand,       "", NULL }, +            { "stats",        rbac::RBAC_PERM_COMMAND_INSTANCE_STATS,          true, &HandleInstanceStatsCommand,        "", NULL }, +            { "savedata",     rbac::RBAC_PERM_COMMAND_INSTANCE_SAVEDATA,      false, &HandleInstanceSaveDataCommand,     "", NULL }, +            { "setbossstate", rbac::RBAC_PERM_COMMAND_INSTANCE_SET_BOSS_STATE, true, &HandleInstanceSetBossStateCommand, "", NULL }, +            { "getbossstate", rbac::RBAC_PERM_COMMAND_INSTANCE_GET_BOSS_STATE, true, &HandleInstanceGetBossStateCommand, "", NULL }, +            { NULL,           0,                                              false, NULL,                               "", NULL }          };          static ChatCommand commandTable[] = @@ -187,6 +189,138 @@ public:          return true;      } + +    static bool HandleInstanceSetBossStateCommand(ChatHandler* handler, char const* args) +    { +        if (!*args) +            return false; + +        char* param1 = strtok((char*)args, " "); +        char* param2 = strtok(nullptr, " "); +        char* param3 = strtok(nullptr, " "); +        uint32 encounterId = 0; +        int32 state = 0; +        Player* player = nullptr; +        std::string playerName; + +        // Character name must be provided when using this from console. +        if (!param2 || (!param3 && !handler->GetSession())) +        { +            handler->PSendSysMessage(LANG_CMD_SYNTAX); +            handler->SetSentErrorMessage(true); +            return false; +        } + +        if (!param3) +            player = handler->GetSession()->GetPlayer(); +        else +        { +            playerName = param3; +            if (normalizePlayerName(playerName)) +                player = sObjectAccessor->FindPlayerByName(playerName); +        } + +        if (!player) +        { +            handler->PSendSysMessage(LANG_PLAYER_NOT_FOUND); +            handler->SetSentErrorMessage(true); +            return false; +        } + +        Map* map = player->GetMap(); +        if (!map->IsDungeon()) +        { +            handler->PSendSysMessage(LANG_NOT_DUNGEON); +            handler->SetSentErrorMessage(true); +            return false; +        } + +        if (!map->ToInstanceMap()->GetInstanceScript()) +        { +            handler->PSendSysMessage(LANG_NO_INSTANCE_DATA); +            handler->SetSentErrorMessage(true); +            return false; +        } + +        encounterId = atoi(param1); +        state = atoi(param2); + +        // Reject improper values. +        if (state > TO_BE_DECIDED || encounterId > map->ToInstanceMap()->GetInstanceScript()->GetEncounterCount()) +        { +            handler->PSendSysMessage(LANG_BAD_VALUE); +            handler->SetSentErrorMessage(true); +            return false; +        } + +        map->ToInstanceMap()->GetInstanceScript()->SetBossState(encounterId, (EncounterState)state); +        handler->PSendSysMessage(LANG_COMMAND_INST_SET_BOSS_STATE, encounterId, state); +        return true; +    } + +    static bool HandleInstanceGetBossStateCommand(ChatHandler* handler, char const* args) +    { +        if (!*args) +            return false; + +        char* param1 = strtok((char*)args, " "); +        char* param2 = strtok(nullptr, " "); +        uint32 encounterId = 0; +        Player* player = nullptr; +        std::string playerName; + +        // Character name must be provided when using this from console. +        if (!param1 || (!param2 && !handler->GetSession())) +        { +            handler->PSendSysMessage(LANG_CMD_SYNTAX); +            handler->SetSentErrorMessage(true); +            return false; +        } + +        if (!param2) +            player = handler->GetSession()->GetPlayer(); +        else +        { +            playerName = param2; +            if (normalizePlayerName(playerName)) +                player = sObjectAccessor->FindPlayerByName(playerName); +        } + +        if (!player) +        { +            handler->PSendSysMessage(LANG_PLAYER_NOT_FOUND); +            handler->SetSentErrorMessage(true); +            return false; +        } + +        Map* map = player->GetMap(); +        if (!map->IsDungeon()) +        { +            handler->PSendSysMessage(LANG_NOT_DUNGEON); +            handler->SetSentErrorMessage(true); +            return false; +        } + +        if (!map->ToInstanceMap()->GetInstanceScript()) +        { +            handler->PSendSysMessage(LANG_NO_INSTANCE_DATA); +            handler->SetSentErrorMessage(true); +            return false; +        } + +        if (encounterId > map->ToInstanceMap()->GetInstanceScript()->GetEncounterCount()) +        { +            handler->PSendSysMessage(LANG_BAD_VALUE); +            handler->SetSentErrorMessage(true); +            return false; +        } + +        encounterId = atoi(param1); + +        uint8 state = map->ToInstanceMap()->GetInstanceScript()->GetBossState(encounterId); +        handler->PSendSysMessage(LANG_COMMAND_INST_GET_BOSS_STATE, encounterId, state); +        return true; +    }  };  void AddSC_instance_commandscript() diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index 75dbf975857..706f98c0009 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -73,6 +73,7 @@ public:              { "maxskill",         rbac::RBAC_PERM_COMMAND_MAXSKILL,         false, &HandleMaxSkillCommand,         "", NULL },              { "movegens",         rbac::RBAC_PERM_COMMAND_MOVEGENS,         false, &HandleMovegensCommand,         "", NULL },              { "mute",             rbac::RBAC_PERM_COMMAND_MUTE,              true, &HandleMuteCommand,             "", NULL }, +            { "mutehistory",      rbac::RBAC_PERM_COMMAND_MUTEHISTORY,       true, &HandleMuteInfoCommand,         "", NULL },              { "neargrave",        rbac::RBAC_PERM_COMMAND_NEARGRAVE,        false, &HandleNearGraveCommand,        "", NULL },              { "pinfo",            rbac::RBAC_PERM_COMMAND_PINFO,             true, &HandlePInfoCommand,            "", NULL },              { "playall",          rbac::RBAC_PERM_COMMAND_PLAYALL,          false, &HandlePlayAllCommand,          "", NULL }, @@ -1850,6 +1851,12 @@ public:          stmt->setString(2, muteBy.c_str());          stmt->setUInt32(3, accountId);          LoginDatabase.Execute(stmt); +        stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_ACCOUNT_MUTE); +        stmt->setUInt32(0, accountId); +        stmt->setUInt32(1, notSpeakTime); +        stmt->setString(2, muteBy.c_str()); +        stmt->setString(3, muteReasonStr.c_str()); +        LoginDatabase.Execute(stmt);          std::string nameLink = handler->playerLink(targetName);          if (sWorld->getBoolConfig(CONFIG_SHOW_MUTE_IN_WORLD) && !target) @@ -1909,6 +1916,65 @@ public:          return true;      } +    // mutehistory command +    static bool HandleMuteInfoCommand(ChatHandler* handler, char const* args) +    { +        if (!*args) +            return false; + +        char *nameStr = strtok((char*)args, ""); +        if (!nameStr) +            return false; + +        std::string accountName = nameStr; +        if (!AccountMgr::normalizeString(accountName)) +        { +            handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, accountName.c_str()); +            handler->SetSentErrorMessage(true); +            return false; +        } + +        uint32 accountId = AccountMgr::GetId(accountName); +        if (!accountId) +        { +            handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, accountName.c_str()); +            return false; +        } + +        return HandleMuteInfoHelper(accountId, accountName.c_str(), handler); +    } + +    // helper for mutehistory +    static bool HandleMuteInfoHelper(uint32 accountId, char const* accountName, ChatHandler *handler) +    { +        PreparedStatement *stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_MUTE_INFO); +        stmt->setUInt16(0, accountId); +        PreparedQueryResult result = LoginDatabase.Query(stmt); +         +        if (!result) +        { +            handler->PSendSysMessage(LANG_COMMAND_MUTEHISTORY_EMPTY, accountName); +            return true; +        } + +        handler->PSendSysMessage(LANG_COMMAND_MUTEHISTORY, accountName); +        do +        { +            Field* fields = result->Fetch(); +             +            // we have to manually set the string for mutedate +            time_t sqlTime = fields[0].GetUInt32(); +            struct tm* timeinfo; +            char buffer[80]; +             +            // set it to string +            timeinfo = localtime_r(&sqlTime); +            strftime(buffer, sizeof(buffer),"%Y-%m-%d %I:%M%p", timeinfo); +             +            handler->PSendSysMessage(LANG_COMMAND_MUTEHISTORY_OUTPUT, buffer, fields[1].GetUInt32(), fields[2].GetCString(), fields[3].GetCString()); +        } while (result->NextRow()); +        return true; +    }      static bool HandleMovegensCommand(ChatHandler* handler, char const* /*args*/)      { diff --git a/src/server/scripts/Commands/cs_quest.cpp b/src/server/scripts/Commands/cs_quest.cpp index dc75e0aedab..fb486128049 100644 --- a/src/server/scripts/Commands/cs_quest.cpp +++ b/src/server/scripts/Commands/cs_quest.cpp @@ -238,6 +238,17 @@ public:          if (ReqOrRewMoney < 0)              player->ModifyMoney(-ReqOrRewMoney); +        if (sWorld->getBoolConfig(CONFIG_QUEST_ENABLE_QUEST_TRACKER)) // check if Quest Tracker is enabled +        { +            // prepare Quest Tracker datas +            PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_QUEST_TRACK_GM_COMPLETE); +            stmt->setUInt32(0, quest->GetQuestId()); +            stmt->setUInt32(1, player->GetGUIDLow()); + +            // add to Quest Tracker +            CharacterDatabase.Execute(stmt); +        } +          player->CompleteQuest(entry);          return true;      } diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_shazzrah.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_shazzrah.cpp index fcabf3d1b18..44c41a6be0f 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_shazzrah.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_shazzrah.cpp @@ -1,6 +1,5 @@  /*   * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> - * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>   *   * This program is free software; you can redistribute it and/or modify it   * under the terms of the GNU General Public License as published by the @@ -16,33 +15,29 @@   * with this program. If not, see <http://www.gnu.org/licenses/>.   */ -/* ScriptData -SDName: Boss_Shazzrah -SD%Complete: 75 -SDComment: Teleport NYI -SDCategory: Molten Core -EndScriptData */ - -#include "ObjectMgr.h"  #include "ScriptMgr.h"  #include "ScriptedCreature.h" +#include "SpellScript.h"  #include "molten_core.h"  enum Spells  { -    SPELL_ARCANE_EXPLOSION  = 19712, -    SPELL_SHAZZRAH_CURSE    = 19713, -    SPELL_MAGIC_GROUNDING   = 19714, -    SPELL_COUNTERSPELL      = 19715, +    SPELL_ARCANE_EXPLOSION      = 19712, +    SPELL_SHAZZRAH_CURSE        = 19713, +    SPELL_MAGIC_GROUNDING       = 19714, +    SPELL_COUNTERSPELL          = 19715, +    SPELL_SHAZZRAH_GATE_DUMMY   = 23138, // Teleports to and attacks a random target. +    SPELL_SHAZZRAH_GATE         = 23139,  };  enum Events  { -    EVENT_ARCANE_EXPLOSION  = 1, -    EVENT_SHAZZRAH_CURSE    = 2, -    EVENT_MAGIC_GROUNDING   = 3, -    EVENT_COUNTERSPELL      = 4, -    EVENT_BLINK             = 5, +    EVENT_ARCANE_EXPLOSION              = 1, +    EVENT_ARCANE_EXPLOSION_TRIGGERED    = 2, +    EVENT_SHAZZRAH_CURSE                = 3, +    EVENT_MAGIC_GROUNDING               = 4, +    EVENT_COUNTERSPELL                  = 5, +    EVENT_SHAZZRAH_GATE                 = 6,  };  class boss_shazzrah : public CreatureScript @@ -52,9 +47,7 @@ class boss_shazzrah : public CreatureScript          struct boss_shazzrahAI : public BossAI          { -            boss_shazzrahAI(Creature* creature) : BossAI(creature, BOSS_SHAZZRAH) -            { -            } +            boss_shazzrahAI(Creature* creature) : BossAI(creature, BOSS_SHAZZRAH) { }              void EnterCombat(Unit* target) override              { @@ -63,7 +56,7 @@ class boss_shazzrah : public CreatureScript                  events.ScheduleEvent(EVENT_SHAZZRAH_CURSE, 10000);                  events.ScheduleEvent(EVENT_MAGIC_GROUNDING, 24000);                  events.ScheduleEvent(EVENT_COUNTERSPELL, 15000); -                events.ScheduleEvent(EVENT_BLINK, 30000); +                events.ScheduleEvent(EVENT_SHAZZRAH_GATE, 45000);              }              void UpdateAI(uint32 diff) override @@ -82,10 +75,14 @@ class boss_shazzrah : public CreatureScript                      {                          case EVENT_ARCANE_EXPLOSION:                              DoCastVictim(SPELL_ARCANE_EXPLOSION); -                            events.ScheduleEvent(EVENT_ARCANE_EXPLOSION, urand(5000, 9000)); +                            events.ScheduleEvent(EVENT_ARCANE_EXPLOSION, urand(4000, 7000)); +                            break; +                        // Triggered subsequent to using "Gate of Shazzrah". +                        case EVENT_ARCANE_EXPLOSION_TRIGGERED: +                            DoCastVictim(SPELL_ARCANE_EXPLOSION);                              break;                          case EVENT_SHAZZRAH_CURSE: -                            if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true, -EVENT_SHAZZRAH_CURSE)) +                            if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true, -SPELL_SHAZZRAH_CURSE))                                  DoCast(target, SPELL_SHAZZRAH_CURSE);                              events.ScheduleEvent(EVENT_SHAZZRAH_CURSE, urand(25000, 30000));                              break; @@ -97,16 +94,12 @@ class boss_shazzrah : public CreatureScript                              DoCastVictim(SPELL_COUNTERSPELL);                              events.ScheduleEvent(EVENT_COUNTERSPELL, urand(16000, 20000));                              break; -                        case EVENT_BLINK: -                            // Teleporting him to a random player and casting Arcane Explosion after that. -                            // Blink is not working cause of LoS System we need to do this hardcoded. -                            if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 100.0f, true)) -                            { -                                DoTeleportTo(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ()); -                                DoCast(target, SPELL_ARCANE_EXPLOSION); -                                DoResetThreat(); -                            } -                            events.ScheduleEvent(EVENT_BLINK, 45000); +                        case EVENT_SHAZZRAH_GATE: +                            DoResetThreat(); +                            DoCastAOE(SPELL_SHAZZRAH_GATE_DUMMY); +                            events.ScheduleEvent(EVENT_ARCANE_EXPLOSION_TRIGGERED, 2000); +                            events.RescheduleEvent(EVENT_ARCANE_EXPLOSION, urand(3000, 6000)); +                            events.ScheduleEvent(EVENT_SHAZZRAH_GATE, 45000);                              break;                          default:                              break; @@ -123,7 +116,58 @@ class boss_shazzrah : public CreatureScript          }  }; +// 23138 - Gate of Shazzrah +class spell_shazzrah_gate_dummy : public SpellScriptLoader +{ +    public: +        spell_shazzrah_gate_dummy() : SpellScriptLoader("spell_shazzrah_gate_dummy") { } + +        class spell_shazzrah_gate_dummy_SpellScript : public SpellScript +        { +            PrepareSpellScript(spell_shazzrah_gate_dummy_SpellScript); + +            bool Validate(SpellInfo const* /*spellInfo*/) override +            { +                if (!sSpellMgr->GetSpellInfo(SPELL_SHAZZRAH_GATE)) +                    return false; +                return true; +            } + +            void FilterTargets(std::list<WorldObject*>& targets) +            { +                if (targets.empty()) +                    return; + +                WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets); +                targets.clear(); +                targets.push_back(target); +            } + +            void HandleScript(SpellEffIndex /*effIndex*/) +            { +                if (Unit* target = GetHitUnit()) +                { +                    target->CastSpell(GetCaster(), SPELL_SHAZZRAH_GATE, true); +                    if (Creature* creature = GetCaster()->ToCreature()) +                        creature->AI()->AttackStart(target); // Attack the target which caster will teleport to. +                } +            } + +            void Register() override +            { +                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_shazzrah_gate_dummy_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); +                OnEffectHitTarget += SpellEffectFn(spell_shazzrah_gate_dummy_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY); +            } +        }; + +        SpellScript* GetSpellScript() const override +        { +            return new spell_shazzrah_gate_dummy_SpellScript(); +        } +}; +  void AddSC_boss_shazzrah()  {      new boss_shazzrah(); +    new spell_shazzrah_gate_dummy();  } diff --git a/src/server/scripts/Northrend/isle_of_conquest.cpp b/src/server/scripts/Northrend/isle_of_conquest.cpp index 84541eb7b99..7d4c396f29e 100644 --- a/src/server/scripts/Northrend/isle_of_conquest.cpp +++ b/src/server/scripts/Northrend/isle_of_conquest.cpp @@ -73,6 +73,68 @@ class npc_four_car_garage : public CreatureScript          }  }; +enum Events +{ +    EVENT_TALK  = 1, +    EVENT_DESPAWN +}; + +enum Texts +{ +    SAY_ONBOARD = 0 +}; + +class npc_ioc_gunship_captain : public CreatureScript +{ +    public: +        npc_ioc_gunship_captain() : CreatureScript("npc_ioc_gunship_captain") { } + +        struct npc_ioc_gunship_captainAI : public ScriptedAI +        { +            npc_ioc_gunship_captainAI(Creature* creature) : ScriptedAI(creature) { } + +            void DoAction(int32 action) override +            { +                if (action == ACTION_GUNSHIP_READY) +                { +                    DoCast(me, SPELL_SIMPLE_TELEPORT); +                    _events.ScheduleEvent(EVENT_TALK, 3000); +                } +            } + +            void UpdateAI(uint32 diff) override +            { +                _events.Update(diff); +                while (uint32 eventId = _events.ExecuteEvent()) +                { +                    switch (eventId) +                    { +                        case EVENT_TALK: +                            _events.ScheduleEvent(EVENT_DESPAWN, 1000); +                            Talk(SAY_ONBOARD); +                            DoCast(me, SPELL_TELEPORT_VISUAL_ONLY); +                            break; +                        case EVENT_DESPAWN: +                            if (me->GetMap()->ToBattlegroundMap()) +                                if (Battleground* bgIoC = me->GetMap()->ToBattlegroundMap()->GetBG()) +                                    bgIoC->DelCreature(BG_IC_NPC_GUNSHIP_CAPTAIN_1); +                            break; +                        default: +                            break; +                    } +                } +            } + +        private: +            EventMap _events; +        }; + +        CreatureAI* GetAI(Creature* creature) const override +        { +            return new npc_ioc_gunship_captainAI(creature); +        } +}; +  class spell_ioc_gunship_portal : public SpellScriptLoader  {      public: @@ -90,9 +152,28 @@ class spell_ioc_gunship_portal : public SpellScriptLoader              void HandleScript(SpellEffIndex /*effIndex*/)              {                  Player* caster = GetCaster()->ToPlayer(); -                if (Battleground* bg = caster->GetBattleground()) -                    if (bg->GetTypeID(true) == BATTLEGROUND_IC) -                        bg->DoAction(1, caster->GetGUID()); +                /* +                 * HACK: GetWorldLocation() returns real position and not transportposition. +                 * ServertoClient: SMSG_MOVE_TELEPORT (0x0B39) +                 * counter: 45 +                 * Tranpsort Guid: Full: xxxx Type: MOTransport Low: xxx +                 * Transport Position X: 0 Y: 0 Z: 0 O: 0 +                 * Position: X: 7.305609 Y: -0.095246 Z: 34.51022 O: 0 +                 */ +                caster->TeleportTo(GetHitCreature()->GetWorldLocation(), TELE_TO_NOT_LEAVE_TRANSPORT); +                /* +                 * HACK: This aura should be added by 20212 and 20213 but can't find any SMSG_SPELL_GO. Could't find their position. +                 * ServerToClient: SMSG_AURA_UPDATE (0x0072) +                 * [0] CasterGUID: Full: xxxxx Type: Unit Entry: 20212 Low: xxx +                 * [0] Flags: None (0) +                 * [0] Caster Level: 60 +                 * [0] Spell ID: 66656 +                 * [0] Charges: 0 +                 * [0] Effect Mask: 1 +                 * [0] Slot: 37 +                 * Guid: Full: xxxxx Type: Player2 Low: xxxxx +                 */ +                caster->AddAura(SPELL_PARACHUTE, caster);              }              void Register() override @@ -107,11 +188,6 @@ class spell_ioc_gunship_portal : public SpellScriptLoader          }  }; -enum ParachuteIC -{ -    SPELL_PARACHUTE_IC      = 66657 -}; -  class spell_ioc_parachute_ic : public SpellScriptLoader  {      public: @@ -124,7 +200,7 @@ class spell_ioc_parachute_ic : public SpellScriptLoader              void HandleTriggerSpell(AuraEffect const* /*aurEff*/)              {                  if (Player* target = GetTarget()->ToPlayer()) -                    if (target->m_movementInfo.GetFallTime() > 2000) +                    if (target->m_movementInfo.GetFallTime() > 2000 && !target->GetTransport())                          target->CastSpell(target, SPELL_PARACHUTE_IC, true);              } @@ -140,9 +216,31 @@ class spell_ioc_parachute_ic : public SpellScriptLoader          }  }; -enum Launch +class StartLaunchEvent : public BasicEvent  { -    SPELL_LAUNCH_NO_FALLING_DAMAGE  = 66251 +    public: +        StartLaunchEvent(float x, float y, float z, uint32 lowGuid) : _x(x), _y(y), _z(z), _lowGuid(lowGuid) +        { +        } + +        bool Execute(uint64 /*time*/, uint32 /*diff*/) +        { +            Player* player = sObjectMgr->GetPlayerByLowGUID(_lowGuid); +            if (!player || !player->GetVehicle()) +                return true; + +            player->AddAura(SPELL_LAUNCH_NO_FALLING_DAMAGE, player); // prevents falling damage +            float speedZ = 10.0f; +            float dist = player->GetExactDist2d(_x, _y); + +            player->ExitVehicle(); +            player->GetMotionMaster()->MoveJump(_x, _y, _z, dist, speedZ); +            return true; +        } + +    private: +        float _x, _y, _z; +        uint32 _lowGuid;  };  class spell_ioc_launch : public SpellScriptLoader @@ -154,34 +252,20 @@ class spell_ioc_launch : public SpellScriptLoader          {              PrepareSpellScript(spell_ioc_launch_SpellScript); -            void HandleScript(SpellEffIndex /*effIndex*/) -            { -                if (Player* player = GetHitPlayer()) -                    player->AddAura(SPELL_LAUNCH_NO_FALLING_DAMAGE, player); // prevents falling damage -            } -              void Launch()              { -                WorldLocation const* const position = GetExplTargetDest(); - -                if (Player* player = GetHitPlayer()) -                { -                    player->ExitVehicle(); - -                    // A better research is needed -                    // There is no spell for this, the following calculation was based on void Spell::CalculateJumpSpeeds - -                    float speedZ = 10.0f; -                    float dist = position->GetExactDist2d(player->GetPositionX(), player->GetPositionY()); -                    float speedXY = dist; - -                    player->GetMotionMaster()->MoveJump(position->GetPositionX(), position->GetPositionY(), position->GetPositionZ(), speedXY, speedZ); -                } +                if (!GetCaster()->ToCreature() || !GetExplTargetDest()) +                    return; + +                float x, y, z; +                x = GetExplTargetDest()->GetPositionX(); +                y = GetExplTargetDest()->GetPositionY(); +                z = GetExplTargetDest()->GetPositionZ(); +                GetCaster()->ToCreature()->m_Events.AddEvent(new StartLaunchEvent(x, y, z, GetHitPlayer()->GetGUIDLow()), GetCaster()->ToCreature()->m_Events.CalculateTime(2500));              }              void Register() override              { -                OnEffectHitTarget += SpellEffectFn(spell_ioc_launch_SpellScript::HandleScript, EFFECT_1, SPELL_EFFECT_FORCE_CAST);                  AfterHit += SpellHitFn(spell_ioc_launch_SpellScript::Launch);              }          }; @@ -195,6 +279,7 @@ class spell_ioc_launch : public SpellScriptLoader  void AddSC_isle_of_conquest()  {      new npc_four_car_garage(); +    new npc_ioc_gunship_captain();      new spell_ioc_gunship_portal();      new spell_ioc_parachute_ic();      new spell_ioc_launch(); diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp index 225920aa2dc..a774a8a7db7 100644 --- a/src/server/scripts/Spells/spell_generic.cpp +++ b/src/server/scripts/Spells/spell_generic.cpp @@ -3721,6 +3721,314 @@ public:      }  }; +enum RequiredMixologySpells +{ +    SPELL_MIXOLOGY                      = 53042, +    // Flasks +    SPELL_FLASK_OF_THE_FROST_WYRM       = 53755, +    SPELL_FLASK_OF_STONEBLOOD           = 53758, +    SPELL_FLASK_OF_ENDLESS_RAGE         = 53760, +    SPELL_FLASK_OF_PURE_MOJO            = 54212, +    SPELL_LESSER_FLASK_OF_RESISTANCE    = 62380, +    SPELL_LESSER_FLASK_OF_TOUGHNESS     = 53752, +    SPELL_FLASK_OF_BLINDING_LIGHT       = 28521, +    SPELL_FLASK_OF_CHROMATIC_WONDER     = 42735, +    SPELL_FLASK_OF_FORTIFICATION        = 28518, +    SPELL_FLASK_OF_MIGHTY_RESTORATION   = 28519, +    SPELL_FLASK_OF_PURE_DEATH           = 28540, +    SPELL_FLASK_OF_RELENTLESS_ASSAULT   = 28520, +    SPELL_FLASK_OF_CHROMATIC_RESISTANCE = 17629, +    SPELL_FLASK_OF_DISTILLED_WISDOM     = 17627, +    SPELL_FLASK_OF_SUPREME_POWER        = 17628, +    SPELL_FLASK_OF_THE_TITANS           = 17626, +    // Elixirs +    SPELL_ELIXIR_OF_MIGHTY_AGILITY      = 28497, +    SPELL_ELIXIR_OF_ACCURACY            = 60340, +    SPELL_ELIXIR_OF_DEADLY_STRIKES      = 60341, +    SPELL_ELIXIR_OF_MIGHTY_DEFENSE      = 60343, +    SPELL_ELIXIR_OF_EXPERTISE           = 60344, +    SPELL_ELIXIR_OF_ARMOR_PIERCING      = 60345, +    SPELL_ELIXIR_OF_LIGHTNING_SPEED     = 60346, +    SPELL_ELIXIR_OF_MIGHTY_FORTITUDE    = 53751, +    SPELL_ELIXIR_OF_MIGHTY_MAGEBLOOD    = 53764, +    SPELL_ELIXIR_OF_MIGHTY_STRENGTH     = 53748, +    SPELL_ELIXIR_OF_MIGHTY_TOUGHTS      = 60347, +    SPELL_ELIXIR_OF_PROTECTION          = 53763, +    SPELL_ELIXIR_OF_SPIRIT              = 53747, +    SPELL_GURUS_ELIXIR                  = 53749, +    SPELL_SHADOWPOWER_ELIXIR            = 33721, +    SPELL_WRATH_ELIXIR                  = 53746, +    SPELL_ELIXIR_OF_EMPOWERMENT         = 28514, +    SPELL_ELIXIR_OF_MAJOR_MAGEBLOOD     = 28509, +    SPELL_ELIXIR_OF_MAJOR_SHADOW_POWER  = 28503, +    SPELL_ELIXIR_OF_MAJOR_DEFENSE       = 28502, +    SPELL_FEL_STRENGTH_ELIXIR           = 38954, +    SPELL_ELIXIR_OF_IRONSKIN            = 39628, +    SPELL_ELIXIR_OF_MAJOR_AGILITY       = 54494, +    SPELL_ELIXIR_OF_DRAENIC_WISDOM      = 39627, +    SPELL_ELIXIR_OF_MAJOR_FIREPOWER     = 28501, +    SPELL_ELIXIR_OF_MAJOR_FROST_POWER   = 28493, +    SPELL_EARTHEN_ELIXIR                = 39626, +    SPELL_ELIXIR_OF_MASTERY             = 33726, +    SPELL_ELIXIR_OF_HEALING_POWER       = 28491, +    SPELL_ELIXIR_OF_MAJOR_FORTITUDE     = 39625, +    SPELL_ELIXIR_OF_MAJOR_STRENGTH      = 28490, +    SPELL_ADEPTS_ELIXIR                 = 54452, +    SPELL_ONSLAUGHT_ELIXIR              = 33720, +    SPELL_MIGHTY_TROLLS_BLOOD_ELIXIR    = 24361, +    SPELL_GREATER_ARCANE_ELIXIR         = 17539, +    SPELL_ELIXIR_OF_THE_MONGOOSE        = 17538, +    SPELL_ELIXIR_OF_BRUTE_FORCE         = 17537, +    SPELL_ELIXIR_OF_SAGES               = 17535, +    SPELL_ELIXIR_OF_SUPERIOR_DEFENSE    = 11348, +    SPELL_ELIXIR_OF_DEMONSLAYING        = 11406, +    SPELL_ELIXIR_OF_GREATER_FIREPOWER   = 26276, +    SPELL_ELIXIR_OF_SHADOW_POWER        = 11474, +    SPELL_MAGEBLOOD_ELIXIR              = 24363, +    SPELL_ELIXIR_OF_GIANTS              = 11405, +    SPELL_ELIXIR_OF_GREATER_AGILITY     = 11334, +    SPELL_ARCANE_ELIXIR                 = 11390, +    SPELL_ELIXIR_OF_GREATER_INTELLECT   = 11396, +    SPELL_ELIXIR_OF_GREATER_DEFENSE     = 11349, +    SPELL_ELIXIR_OF_FROST_POWER         = 21920, +    SPELL_ELIXIR_OF_AGILITY             = 11328, +    SPELL_MAJOR_TROLLS_BLLOOD_ELIXIR    =  3223, +    SPELL_ELIXIR_OF_FORTITUDE           =  3593, +    SPELL_ELIXIR_OF_OGRES_STRENGTH      =  3164, +    SPELL_ELIXIR_OF_FIREPOWER           =  7844, +    SPELL_ELIXIR_OF_LESSER_AGILITY      =  3160, +    SPELL_ELIXIR_OF_DEFENSE             =  3220, +    SPELL_STRONG_TROLLS_BLOOD_ELIXIR    =  3222, +    SPELL_ELIXIR_OF_MINOR_ACCURACY      = 63729, +    SPELL_ELIXIR_OF_WISDOM              =  3166, +    SPELL_ELIXIR_OF_GIANTH_GROWTH       =  8212, +    SPELL_ELIXIR_OF_MINOR_AGILITY       =  2374, +    SPELL_ELIXIR_OF_MINOR_FORTITUDE     =  2378, +    SPELL_WEAK_TROLLS_BLOOD_ELIXIR      =  3219, +    SPELL_ELIXIR_OF_LIONS_STRENGTH      =  2367, +    SPELL_ELIXIR_OF_MINOR_DEFENSE       =   673 +}; + +class spell_gen_mixology_bonus : public SpellScriptLoader +{ +public: +    spell_gen_mixology_bonus() : SpellScriptLoader("spell_gen_mixology_bonus") { } + +    class spell_gen_mixology_bonus_AuraScript : public AuraScript +    { +        PrepareAuraScript(spell_gen_mixology_bonus_AuraScript); + +    public: +        spell_gen_mixology_bonus_AuraScript() +        { +            bonus = 0; +        } + +    private: +        bool Validate(SpellInfo const* /*spellInfo*/) override +        { +            if (!sSpellMgr->GetSpellInfo(SPELL_MIXOLOGY)) +                return false; +            return true; +        } + +        bool Load() override +        { +            return GetCaster() && GetCaster()->GetTypeId() == TYPEID_PLAYER; +        } + +        void SetBonusValueForEffect(SpellEffIndex effIndex, int32 value, AuraEffect const* aurEff) +        { +            if (aurEff->GetEffIndex() == uint32(effIndex)) +                bonus = value; +        } + +        void CalculateAmount(AuraEffect const* aurEff, int32& amount, bool& /*canBeRecalculated*/) +        { +            if (GetCaster()->HasAura(SPELL_MIXOLOGY) && GetCaster()->HasSpell(GetSpellInfo()->Effects[EFFECT_0].TriggerSpell)) +            { +                switch (GetId()) +                { +                    case SPELL_WEAK_TROLLS_BLOOD_ELIXIR: +                    case SPELL_MAGEBLOOD_ELIXIR: +                        bonus = amount; +                        break; +                    case SPELL_ELIXIR_OF_FROST_POWER: +                    case SPELL_LESSER_FLASK_OF_TOUGHNESS: +                    case SPELL_LESSER_FLASK_OF_RESISTANCE: +                        bonus = CalculatePct(amount, 80); +                        break; +                    case SPELL_ELIXIR_OF_MINOR_DEFENSE: +                    case SPELL_ELIXIR_OF_LIONS_STRENGTH: +                    case SPELL_ELIXIR_OF_MINOR_AGILITY: +                    case SPELL_MAJOR_TROLLS_BLLOOD_ELIXIR: +                    case SPELL_ELIXIR_OF_SHADOW_POWER: +                    case SPELL_ELIXIR_OF_BRUTE_FORCE: +                    case SPELL_MIGHTY_TROLLS_BLOOD_ELIXIR: +                    case SPELL_ELIXIR_OF_GREATER_FIREPOWER: +                    case SPELL_ONSLAUGHT_ELIXIR: +                    case SPELL_EARTHEN_ELIXIR: +                    case SPELL_ELIXIR_OF_MAJOR_AGILITY: +                    case SPELL_FLASK_OF_THE_TITANS: +                    case SPELL_FLASK_OF_RELENTLESS_ASSAULT: +                    case SPELL_FLASK_OF_STONEBLOOD: +                    case SPELL_ELIXIR_OF_MINOR_ACCURACY: +                        bonus = CalculatePct(amount, 50); +                        break; +                    case SPELL_ELIXIR_OF_PROTECTION: +                        bonus = 280; +                        break; +                    case SPELL_ELIXIR_OF_MAJOR_DEFENSE: +                        bonus = 200; +                        break; +                    case SPELL_ELIXIR_OF_GREATER_DEFENSE: +                    case SPELL_ELIXIR_OF_SUPERIOR_DEFENSE: +                        bonus = 140; +                        break; +                    case SPELL_ELIXIR_OF_FORTITUDE: +                        bonus = 100; +                        break; +                    case SPELL_FLASK_OF_ENDLESS_RAGE: +                        bonus = 82; +                        break; +                    case SPELL_ELIXIR_OF_DEFENSE: +                        bonus = 70; +                        break; +                    case SPELL_ELIXIR_OF_DEMONSLAYING: +                        bonus = 50; +                        break; +                    case SPELL_FLASK_OF_THE_FROST_WYRM: +                        bonus = 47; +                        break; +                    case SPELL_WRATH_ELIXIR: +                        bonus = 32; +                        break; +                    case SPELL_ELIXIR_OF_MAJOR_FROST_POWER: +                    case SPELL_ELIXIR_OF_MAJOR_FIREPOWER: +                    case SPELL_ELIXIR_OF_MAJOR_SHADOW_POWER: +                        bonus = 29; +                        break; +                    case SPELL_ELIXIR_OF_MIGHTY_TOUGHTS: +                        bonus = 27; +                        break; +                    case SPELL_FLASK_OF_SUPREME_POWER: +                    case SPELL_FLASK_OF_BLINDING_LIGHT: +                    case SPELL_FLASK_OF_PURE_DEATH: +                    case SPELL_SHADOWPOWER_ELIXIR: +                        bonus = 23; +                        break; +                    case SPELL_ELIXIR_OF_MIGHTY_AGILITY: +                    case SPELL_FLASK_OF_DISTILLED_WISDOM: +                    case SPELL_ELIXIR_OF_SPIRIT: +                    case SPELL_ELIXIR_OF_MIGHTY_STRENGTH: +                    case SPELL_FLASK_OF_PURE_MOJO: +                    case SPELL_ELIXIR_OF_ACCURACY: +                    case SPELL_ELIXIR_OF_DEADLY_STRIKES: +                    case SPELL_ELIXIR_OF_MIGHTY_DEFENSE: +                    case SPELL_ELIXIR_OF_EXPERTISE: +                    case SPELL_ELIXIR_OF_ARMOR_PIERCING: +                    case SPELL_ELIXIR_OF_LIGHTNING_SPEED: +                        bonus = 20; +                        break; +                    case SPELL_FLASK_OF_CHROMATIC_RESISTANCE: +                        bonus = 17; +                        break; +                    case SPELL_ELIXIR_OF_MINOR_FORTITUDE: +                    case SPELL_ELIXIR_OF_MAJOR_STRENGTH: +                        bonus = 15; +                        break; +                    case SPELL_FLASK_OF_MIGHTY_RESTORATION: +                        bonus = 13; +                        break; +                    case SPELL_ARCANE_ELIXIR: +                        bonus = 12; +                        break; +                    case SPELL_ELIXIR_OF_GREATER_AGILITY: +                    case SPELL_ELIXIR_OF_GIANTS: +                        bonus = 11; +                        break; +                    case SPELL_ELIXIR_OF_AGILITY: +                    case SPELL_ELIXIR_OF_GREATER_INTELLECT: +                    case SPELL_ELIXIR_OF_SAGES: +                    case SPELL_ELIXIR_OF_IRONSKIN: +                    case SPELL_ELIXIR_OF_MIGHTY_MAGEBLOOD: +                        bonus = 10; +                        break; +                    case SPELL_ELIXIR_OF_HEALING_POWER: +                        bonus = 9; +                        break; +                    case SPELL_ELIXIR_OF_DRAENIC_WISDOM: +                    case SPELL_GURUS_ELIXIR: +                        bonus = 8; +                        break; +                    case SPELL_ELIXIR_OF_FIREPOWER: +                    case SPELL_ELIXIR_OF_MAJOR_MAGEBLOOD: +                    case SPELL_ELIXIR_OF_MASTERY: +                        bonus = 6; +                        break; +                    case SPELL_ELIXIR_OF_LESSER_AGILITY: +                    case SPELL_ELIXIR_OF_OGRES_STRENGTH: +                    case SPELL_ELIXIR_OF_WISDOM: +                    case SPELL_ELIXIR_OF_THE_MONGOOSE: +                        bonus = 5; +                        break; +                    case SPELL_STRONG_TROLLS_BLOOD_ELIXIR: +                    case SPELL_FLASK_OF_CHROMATIC_WONDER: +                        bonus = 4; +                        break; +                    case SPELL_ELIXIR_OF_EMPOWERMENT: +                        bonus = -10; +                        break; +                    case SPELL_ADEPTS_ELIXIR: +                        SetBonusValueForEffect(EFFECT_0, 13, aurEff); +                        SetBonusValueForEffect(EFFECT_1, 13, aurEff); +                        SetBonusValueForEffect(EFFECT_2, 8, aurEff); +                        break; +                    case SPELL_ELIXIR_OF_MIGHTY_FORTITUDE: +                        SetBonusValueForEffect(EFFECT_0, 160, aurEff); +                        break; +                    case SPELL_ELIXIR_OF_MAJOR_FORTITUDE: +                        SetBonusValueForEffect(EFFECT_0, 116, aurEff); +                        SetBonusValueForEffect(EFFECT_1, 6, aurEff); +                        break; +                    case SPELL_FEL_STRENGTH_ELIXIR: +                        SetBonusValueForEffect(EFFECT_0, 40, aurEff); +                        SetBonusValueForEffect(EFFECT_1, 40, aurEff); +                        break; +                    case SPELL_FLASK_OF_FORTIFICATION: +                        SetBonusValueForEffect(EFFECT_0, 210, aurEff); +                        SetBonusValueForEffect(EFFECT_1, 5, aurEff); +                        break; +                    case SPELL_GREATER_ARCANE_ELIXIR: +                        SetBonusValueForEffect(EFFECT_0, 19, aurEff); +                        SetBonusValueForEffect(EFFECT_1, 19, aurEff); +                        SetBonusValueForEffect(EFFECT_2, 5, aurEff); +                        break; +                    case SPELL_ELIXIR_OF_GIANTH_GROWTH: +                        SetBonusValueForEffect(EFFECT_0, 5, aurEff); +                        break; +                    default: +                        TC_LOG_ERROR("spells", "SpellId %u couldn't be processed in spell_gen_mixology_bonus", GetId()); +                        break; +                } +                amount += bonus; +            } +        } + +        int32 bonus; + +        void Register() override +        { +            DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_mixology_bonus_AuraScript::CalculateAmount, EFFECT_ALL, SPELL_AURA_ANY); +        } +    }; + +    AuraScript* GetAuraScript() const override +    { +        return new spell_gen_mixology_bonus_AuraScript(); +    } +}; +  void AddSC_generic_spell_scripts()  {      new spell_gen_absorb0_hitlimit1(); @@ -3805,4 +4113,5 @@ void AddSC_generic_spell_scripts()      new spell_gen_eject_all_passengers();      new spell_gen_gm_freeze();      new spell_gen_stand(); +    new spell_gen_mixology_bonus();  } diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.cpp b/src/server/shared/Database/Implementation/CharacterDatabase.cpp index a0fb6e74a39..0c62ea19f99 100644 --- a/src/server/shared/Database/Implementation/CharacterDatabase.cpp +++ b/src/server/shared/Database/Implementation/CharacterDatabase.cpp @@ -635,4 +635,9 @@ void CharacterDatabaseConnection::DoPrepareStatements()      PrepareStatement(CHAR_INS_PVPSTATS_BATTLEGROUND, "INSERT INTO pvpstats_battlegrounds (id, winner_faction, bracket_id, type, date) VALUES (?, ?, ?, ?, NOW())", CONNECTION_ASYNC);      PrepareStatement(CHAR_INS_PVPSTATS_PLAYER, "INSERT INTO pvpstats_players (battleground_id, character_guid, score_killing_blows, score_deaths, score_honorable_kills, score_bonus_honor, score_damage_done, score_healing_done, attr_1, attr_2, attr_3, attr_4, attr_5) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); +    // QuestTracker +    PrepareStatement(CHAR_INS_QUEST_TRACK, "INSERT INTO quest_tracker (id, character_guid, quest_accept_time, core_hash, core_revision) VALUES (?, ?, NOW(), ?, ?)", CONNECTION_ASYNC); +    PrepareStatement(CHAR_UPD_QUEST_TRACK_GM_COMPLETE, "UPDATE quest_tracker SET completed_by_gm = 1 WHERE id = ? AND character_guid = ? ORDER BY quest_accept_time DESC LIMIT 1", CONNECTION_ASYNC); +    PrepareStatement(CHAR_UPD_QUEST_TRACK_COMPLETE_TIME, "UPDATE quest_tracker SET quest_complete_time = NOW() WHERE id = ? AND character_guid = ? ORDER BY quest_accept_time DESC LIMIT 1", CONNECTION_ASYNC); +    PrepareStatement(CHAR_UPD_QUEST_TRACK_ABANDON_TIME, "UPDATE quest_tracker SET quest_abandon_time = NOW() WHERE id = ? AND character_guid = ? ORDER BY quest_accept_time DESC LIMIT 1", CONNECTION_ASYNC);  } diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.h b/src/server/shared/Database/Implementation/CharacterDatabase.h index 4764d653f17..18eb2e09c5d 100644 --- a/src/server/shared/Database/Implementation/CharacterDatabase.h +++ b/src/server/shared/Database/Implementation/CharacterDatabase.h @@ -563,6 +563,11 @@ enum CharacterDatabaseStatements      CHAR_INS_PVPSTATS_BATTLEGROUND,      CHAR_INS_PVPSTATS_PLAYER, +    CHAR_INS_QUEST_TRACK, +    CHAR_UPD_QUEST_TRACK_GM_COMPLETE, +    CHAR_UPD_QUEST_TRACK_COMPLETE_TIME, +    CHAR_UPD_QUEST_TRACK_ABANDON_TIME, +      MAX_CHARACTERDATABASE_STATEMENTS  }; diff --git a/src/server/shared/Database/Implementation/LoginDatabase.cpp b/src/server/shared/Database/Implementation/LoginDatabase.cpp index 2bdbc70933d..4aa8adac764 100644 --- a/src/server/shared/Database/Implementation/LoginDatabase.cpp +++ b/src/server/shared/Database/Implementation/LoginDatabase.cpp @@ -112,6 +112,9 @@ void LoginDatabaseConnection::DoPrepareStatements()      PrepareStatement(LOGIN_INS_RBAC_ACCOUNT_PERMISSION, "INSERT INTO rbac_account_permissions (accountId, permissionId, granted, realmId) VALUES (?, ?, ?, ?) ON DUPLICATE KEY UPDATE granted = VALUES(granted)", CONNECTION_ASYNC);      PrepareStatement(LOGIN_DEL_RBAC_ACCOUNT_PERMISSION, "DELETE FROM rbac_account_permissions WHERE accountId = ? AND permissionId = ? AND (realmId = ? OR realmId = -1)", CONNECTION_ASYNC); +    PrepareStatement(LOGIN_INS_ACCOUNT_MUTE, "INSERT INTO account_muted VALUES (?, UNIX_TIMESTAMP(), ?, ?, ?)", CONNECTION_ASYNC); +    PrepareStatement(LOGIN_SEL_ACCOUNT_MUTE_INFO, "SELECT mutedate, mutetime, mutereason, mutedby FROM account_muted WHERE guid = ? ORDER BY mutedate ASC", CONNECTION_SYNCH); +      PrepareStatement(LOGIN_SEL_BNET_ACCOUNT_INFO, "SELECT sha_pass_hash, id, locked, lock_country, last_ip, v, s FROM battlenet_accounts WHERE email = ?", CONNECTION_SYNCH);      PrepareStatement(LOGIN_DEL_BNET_EXPIRED_BANS, "UPDATE battlenet_account_bans SET active = 0 WHERE active = 1 AND unbandate <> bandate AND unbandate <= UNIX_TIMESTAMP()", CONNECTION_SYNCH);      PrepareStatement(LOGIN_SEL_BNET_ACTIVE_ACCOUNT_BAN, "SELECT bandate, unbandate FROM battlenet_account_bans WHERE id = ? AND active = 1", CONNECTION_SYNCH); diff --git a/src/server/shared/Database/Implementation/LoginDatabase.h b/src/server/shared/Database/Implementation/LoginDatabase.h index c1816784f07..bfbbc9023e2 100644 --- a/src/server/shared/Database/Implementation/LoginDatabase.h +++ b/src/server/shared/Database/Implementation/LoginDatabase.h @@ -128,6 +128,9 @@ enum LoginDatabaseStatements      LOGIN_INS_RBAC_ACCOUNT_PERMISSION,      LOGIN_DEL_RBAC_ACCOUNT_PERMISSION, +    LOGIN_INS_ACCOUNT_MUTE, +    LOGIN_SEL_ACCOUNT_MUTE_INFO +      LOGIN_SEL_BNET_ACCOUNT_INFO,      LOGIN_DEL_BNET_EXPIRED_BANS,      LOGIN_SEL_BNET_ACTIVE_ACCOUNT_BAN, diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist index 57d97756d70..de62005642b 100644 --- a/src/server/worldserver/worldserver.conf.dist +++ b/src/server/worldserver/worldserver.conf.dist @@ -821,6 +821,14 @@ Instance.UnloadDelay = 1800000  InstancesResetAnnounce = false  # +#    Quests.EnableQuestTracker +#        Description: Store datas in the database about quest completion and abandonment to help finding out bugged quests. +#        Default:     0  - (Disabled) +#                     1  - (Enabled) + +Quests.EnableQuestTracker = 0 + +#  #    Quests.LowLevelHideDiff  #        Description: Level difference between player and quest level at which quests are  #                     considered low-level and are not shown via exclamation mark (!) at quest  | 
