aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Garrison/Garrison.cpp175
-rw-r--r--src/server/game/Garrison/Garrison.h8
-rw-r--r--src/server/game/Garrison/GarrisonMgr.cpp14
-rw-r--r--src/server/game/Garrison/GarrisonMgr.h2
-rw-r--r--src/server/game/Handlers/GarrisonHandler.cpp9
-rw-r--r--src/server/game/Server/Packets/GarrisonPackets.cpp31
-rw-r--r--src/server/game/Server/Packets/GarrisonPackets.h45
-rw-r--r--src/server/game/Server/Protocol/Opcodes.cpp8
-rw-r--r--src/server/game/Server/WorldSession.h2
9 files changed, 267 insertions, 27 deletions
diff --git a/src/server/game/Garrison/Garrison.cpp b/src/server/game/Garrison/Garrison.cpp
index 15387d9a9b6..35c07e1590c 100644
--- a/src/server/game/Garrison/Garrison.cpp
+++ b/src/server/game/Garrison/Garrison.cpp
@@ -210,6 +210,15 @@ Garrison::Plot* Garrison::GetPlot(uint32 garrPlotInstanceId)
return nullptr;
}
+Garrison::Plot const* Garrison::GetPlot(uint32 garrPlotInstanceId) const
+{
+ auto itr = _plots.find(garrPlotInstanceId);
+ if (itr != _plots.end())
+ return &itr->second;
+
+ return nullptr;
+}
+
void Garrison::LearnBlueprint(uint32 garrBuildingId)
{
WorldPackets::Garrison::GarrisonLearnBlueprintResult learnBlueprintResult;
@@ -253,33 +262,88 @@ void Garrison::PlaceBuilding(uint32 garrPlotInstanceId, uint32 garrBuildingId)
placeBuildingResult.BuildingInfo.TimeBuilt = time(nullptr);
Plot* plot = GetPlot(garrPlotInstanceId);
+ uint32 oldBuildingId = 0;
+ Map* map = FindMap();
+ GarrBuildingEntry const* building = sGarrBuildingStore.AssertEntry(garrBuildingId);
+ if (map)
+ plot->DeleteGameObject(map);
- if (Map* map = FindMap())
+ if (plot->BuildingInfo.PacketInfo)
{
- if (!plot->BuildingInfo.Guid.IsEmpty())
- {
- if (GameObject* oldBuilding = map->GetGameObject(plot->BuildingInfo.Guid))
- oldBuilding->AddObjectToRemoveList();
-
- plot->BuildingInfo.Guid.Clear();
- }
+ oldBuildingId = plot->BuildingInfo.PacketInfo->GarrBuildingID;
+ if (sGarrBuildingStore.AssertEntry(oldBuildingId)->Type != building->Type)
+ plot->ClearBuildingInfo(_owner);
+ }
- plot->BuildingInfo.PacketInfo = placeBuildingResult.BuildingInfo;
+ plot->SetBuildingInfo(placeBuildingResult.BuildingInfo, _owner);
+ if (map)
if (GameObject* go = plot->CreateGameObject(map, GetFaction()))
- {
map->AddToMap(go);
- GarrBuildingEntry const* building = sGarrBuildingStore.AssertEntry(garrBuildingId);
- _owner->ModifyCurrency(building->CostCurrencyID, -building->CostCurrencyAmount, false, true);
- _owner->ModifyMoney(-building->CostMoney, false);
- }
- else
- plot->BuildingInfo.PacketInfo = boost::none;
+
+ _owner->ModifyCurrency(building->CostCurrencyID, -building->CostCurrencyAmount, false, true);
+ _owner->ModifyMoney(-building->CostMoney * GOLD, false);
+
+ if (oldBuildingId)
+ {
+ WorldPackets::Garrison::GarrisonBuildingRemoved buildingRemoved;
+ buildingRemoved.Result = GARRISON_SUCCESS;
+ buildingRemoved.GarrPlotInstanceID = garrPlotInstanceId;
+ buildingRemoved.GarrBuildingID = oldBuildingId;
+ _owner->SendDirectMessage(buildingRemoved.Write());
}
}
_owner->SendDirectMessage(placeBuildingResult.Write());
}
+void Garrison::CancelBuildingConstruction(uint32 garrPlotInstanceId)
+{
+ WorldPackets::Garrison::GarrisonBuildingRemoved buildingRemoved;
+ buildingRemoved.Result = CheckBuildingRemoval(garrPlotInstanceId);
+ if (buildingRemoved.Result == GARRISON_SUCCESS)
+ {
+ Plot* plot = GetPlot(garrPlotInstanceId);
+
+ buildingRemoved.GarrPlotInstanceID = garrPlotInstanceId;
+ buildingRemoved.GarrBuildingID = plot->BuildingInfo.PacketInfo->GarrBuildingID;
+
+ Map* map = FindMap();
+ if (map)
+ plot->DeleteGameObject(map);
+
+ plot->ClearBuildingInfo(_owner);
+ _owner->SendDirectMessage(buildingRemoved.Write());
+
+ GarrBuildingEntry const* constructing = sGarrBuildingStore.AssertEntry(buildingRemoved.GarrBuildingID);
+ // Refund construction/upgrade cost
+ _owner->ModifyCurrency(constructing->CostCurrencyID, constructing->CostCurrencyAmount, false, true);
+ _owner->ModifyMoney(constructing->CostMoney * GOLD, false);
+
+ if (constructing->Level > 1)
+ {
+ // Restore previous level building
+ GarrBuildingEntry const* restored = sGarrisonMgr.GetPreviousLevelBuilding(constructing->Type, constructing->Level);
+ ASSERT(restored);
+
+ WorldPackets::Garrison::GarrisonPlaceBuildingResult placeBuildingResult;
+ placeBuildingResult.Result = GARRISON_SUCCESS;
+ placeBuildingResult.BuildingInfo.GarrPlotInstanceID = garrPlotInstanceId;
+ placeBuildingResult.BuildingInfo.GarrBuildingID = restored->ID;
+ placeBuildingResult.BuildingInfo.TimeBuilt = time(nullptr);
+ placeBuildingResult.BuildingInfo.Active = true;
+
+ plot->SetBuildingInfo(placeBuildingResult.BuildingInfo, _owner);
+ _owner->SendDirectMessage(placeBuildingResult.Write());
+ }
+
+ if (map)
+ if (GameObject* go = plot->CreateGameObject(map, GetFaction()))
+ map->AddToMap(go);
+ }
+ else
+ _owner->SendDirectMessage(buildingRemoved.Write());
+}
+
void Garrison::SendInfo()
{
WorldPackets::Garrison::GetGarrisonInfoResult garrisonInfo;
@@ -347,7 +411,8 @@ Map* Garrison::FindMap() const
GarrisonError Garrison::CheckBuildingPlacement(uint32 garrPlotInstanceId, uint32 garrBuildingId) const
{
GarrPlotInstanceEntry const* plotInstance = sGarrPlotInstanceStore.LookupEntry(garrPlotInstanceId);
- if (!plotInstance || !_plots.count(garrPlotInstanceId))
+ Plot const* plot = GetPlot(garrPlotInstanceId);
+ if (!plotInstance || !plot)
return GARRISON_ERROR_INVALID_PLOT;
GarrBuildingEntry const* building = sGarrBuildingStore.LookupEntry(garrBuildingId);
@@ -357,9 +422,13 @@ GarrisonError Garrison::CheckBuildingPlacement(uint32 garrPlotInstanceId, uint32
if (!sGarrisonMgr.IsPlotMatchingBuilding(plotInstance->GarrPlotID, garrBuildingId))
return GARRISON_ERROR_INVALID_PLOT_BUILDING;
+ // Cannot place buldings of higher level than garrison level
+ if (building->Level > _siteLevel->Level)
+ return GARRISON_ERROR_INVALID_BUILDINGID;
+
if (building->Flags & GARRISON_BUILDING_FLAG_NEEDS_PLAN)
{
- if (_knownBuildings.count(garrBuildingId))
+ if (!_knownBuildings.count(garrBuildingId))
return GARRISON_ERROR_BLUEPRINT_NOT_KNOWN;
}
else // Building is built as a quest reward
@@ -373,7 +442,7 @@ GarrisonError Garrison::CheckBuildingPlacement(uint32 garrPlotInstanceId, uint32
{
existingBuilding = sGarrBuildingStore.AssertEntry(p.second.BuildingInfo.PacketInfo->GarrBuildingID);
if (existingBuilding->Type == building->Type)
- if (p.first != garrPlotInstanceId || existingBuilding->Level != building->Level + 1) // check if its an upgrade in same plot
+ if (p.first != garrPlotInstanceId || existingBuilding->Level + 1 != building->Level) // check if its an upgrade in same plot
return GARRISON_ERROR_BUILDING_EXISTS;
}
}
@@ -381,9 +450,29 @@ GarrisonError Garrison::CheckBuildingPlacement(uint32 garrPlotInstanceId, uint32
if (!_owner->HasCurrency(building->CostCurrencyID, building->CostCurrencyAmount))
return GARRISON_ERROR_NOT_ENOUGH_CURRENCY;
- if (!_owner->HasEnoughMoney(uint64(building->CostMoney)))
+ if (!_owner->HasEnoughMoney(uint64(building->CostMoney * GOLD)))
return GARRISON_ERROR_NOT_ENOUGH_GOLD;
+ // New building cannot replace another building currently under construction
+ if (plot->BuildingInfo.PacketInfo)
+ if (!plot->BuildingInfo.PacketInfo->Active)
+ return GARRISON_ERROR_NO_BUILDING;
+
+ return GARRISON_SUCCESS;
+}
+
+GarrisonError Garrison::CheckBuildingRemoval(uint32 garrPlotInstanceId) const
+{
+ Plot const* plot = GetPlot(garrPlotInstanceId);
+ if (!plot)
+ return GARRISON_ERROR_INVALID_PLOT;
+
+ if (!plot->BuildingInfo.PacketInfo)
+ return GARRISON_ERROR_NO_BUILDING;
+
+ if (plot->BuildingInfo.CanActivate())
+ return GARRISON_ERROR_BUILDING_EXISTS;
+
return GARRISON_SUCCESS;
}
@@ -395,7 +484,7 @@ GameObject* Garrison::Plot::CreateGameObject(Map* map, GarrisonFactionIndex fact
GarrPlotInstanceEntry const* plotInstance = sGarrPlotInstanceStore.AssertEntry(PacketInfo.GarrPlotInstanceID);
GarrPlotEntry const* plot = sGarrPlotStore.AssertEntry(plotInstance->GarrPlotID);
GarrBuildingEntry const* building = sGarrBuildingStore.AssertEntry(BuildingInfo.PacketInfo->GarrBuildingID);
- if (BuildingInfo.PacketInfo->TimeBuilt + building->BuildDuration <= time(nullptr) && BuildingInfo.PacketInfo->Active)
+ if (BuildingInfo.PacketInfo->Active)
entry = faction == GARRISON_FACTION_INDEX_HORDE ? building->HordeGameObjectID : building->AllianceGameObjectID;
else
entry = faction == GARRISON_FACTION_INDEX_HORDE ? plot->HordeConstructionGameObjectID : plot->AllianceConstructionGameObjectID;
@@ -419,3 +508,47 @@ GameObject* Garrison::Plot::CreateGameObject(Map* map, GarrisonFactionIndex fact
BuildingInfo.Guid = go->GetGUID();
return go;
}
+
+void Garrison::Plot::DeleteGameObject(Map* map)
+{
+ if (BuildingInfo.Guid.IsEmpty())
+ return;
+
+ if (GameObject* oldBuilding = map->GetGameObject(BuildingInfo.Guid))
+ oldBuilding->Delete();
+
+ BuildingInfo.Guid.Clear();
+}
+
+void Garrison::Plot::ClearBuildingInfo(Player* owner)
+{
+ WorldPackets::Garrison::GarrisonPlotPlaced plotPlaced;
+ plotPlaced.PlotInfo = &PacketInfo;
+ owner->SendDirectMessage(plotPlaced.Write());
+
+ BuildingInfo.PacketInfo = boost::none;
+}
+
+void Garrison::Plot::SetBuildingInfo(WorldPackets::Garrison::GarrisonBuildingInfo const& buildingInfo, Player* owner)
+{
+ if (!BuildingInfo.PacketInfo)
+ {
+ WorldPackets::Garrison::GarrisonPlotRemoved plotRemoved;
+ plotRemoved.GarrPlotInstanceID = PacketInfo.GarrPlotInstanceID;
+ owner->SendDirectMessage(plotRemoved.Write());
+ }
+
+ BuildingInfo.PacketInfo = buildingInfo;
+}
+
+bool Garrison::Building::CanActivate() const
+{
+ if (PacketInfo)
+ {
+ GarrBuildingEntry const* building = sGarrBuildingStore.AssertEntry(PacketInfo->GarrBuildingID);
+ if (PacketInfo->TimeBuilt + building->BuildDuration <= time(nullptr))
+ return true;
+ }
+
+ return false;
+}
diff --git a/src/server/game/Garrison/Garrison.h b/src/server/game/Garrison/Garrison.h
index 37712386d0b..1b12ac62263 100644
--- a/src/server/game/Garrison/Garrison.h
+++ b/src/server/game/Garrison/Garrison.h
@@ -62,6 +62,8 @@ class Garrison
public:
struct Building
{
+ bool CanActivate() const;
+
ObjectGuid Guid;
Optional<WorldPackets::Garrison::GarrisonBuildingInfo> PacketInfo;
};
@@ -69,6 +71,9 @@ public:
struct Plot
{
GameObject* CreateGameObject(Map* map, GarrisonFactionIndex faction);
+ void DeleteGameObject(Map* map);
+ void ClearBuildingInfo(Player* owner);
+ void SetBuildingInfo(WorldPackets::Garrison::GarrisonBuildingInfo const& buildingInfo, Player* owner);
WorldPackets::Garrison::GarrisonPlotInfo PacketInfo;
uint32 EmptyGameObjectId = 0;
@@ -90,10 +95,12 @@ public:
GarrisonFactionIndex GetFaction() const;
std::vector<Plot*> GetPlots();
Plot* GetPlot(uint32 garrPlotInstanceId);
+ Plot const* GetPlot(uint32 garrPlotInstanceId) const;
void LearnBlueprint(uint32 garrBuildingId);
void UnlearnBlueprint(uint32 garrBuildingId);
void PlaceBuilding(uint32 garrPlotInstanceId, uint32 garrBuildingId);
+ void CancelBuildingConstruction(uint32 garrPlotInstanceId);
void SendInfo();
void SendRemoteInfo() const;
@@ -106,6 +113,7 @@ private:
Map* FindMap() const;
void InitializePlots();
GarrisonError CheckBuildingPlacement(uint32 garrPlotInstanceId, uint32 garrBuildingId) const;
+ GarrisonError CheckBuildingRemoval(uint32 garrPlotInstanceId) const;
Player* _owner;
GarrSiteLevelEntry const* _siteLevel;
uint32 _followerActivationsRemainingToday;
diff --git a/src/server/game/Garrison/GarrisonMgr.cpp b/src/server/game/Garrison/GarrisonMgr.cpp
index 4e7266c0855..f81baa6ddf1 100644
--- a/src/server/game/Garrison/GarrisonMgr.cpp
+++ b/src/server/game/Garrison/GarrisonMgr.cpp
@@ -32,6 +32,9 @@ void GarrisonMgr::Initialize()
for (GarrBuildingPlotInstEntry const* buildingPlotInst : sGarrBuildingPlotInstStore)
_garrisonBuildingPlotInstances[MAKE_PAIR64(buildingPlotInst->GarrBuildingID, buildingPlotInst->GarrSiteLevelPlotInstID)] = buildingPlotInst->ID;
+
+ for (GarrBuildingEntry const* building : sGarrBuildingStore)
+ _garrisonBuildingsByType[building->Type].push_back(building);
}
GarrSiteLevelEntry const* GarrisonMgr::GetGarrSiteLevelEntry(uint32 garrSiteId, uint32 level) const
@@ -82,3 +85,14 @@ uint32 GarrisonMgr::GetGarrBuildingPlotInst(uint32 garrBuildingId, uint32 garrSi
return 0;
}
+
+GarrBuildingEntry const* GarrisonMgr::GetPreviousLevelBuilding(uint32 buildingType, uint32 currentLevel) const
+{
+ auto itr = _garrisonBuildingsByType.find(buildingType);
+ if (itr != _garrisonBuildingsByType.end())
+ for (GarrBuildingEntry const* building : itr->second)
+ if (building->Level == currentLevel - 1)
+ return building;
+
+ return nullptr;
+}
diff --git a/src/server/game/Garrison/GarrisonMgr.h b/src/server/game/Garrison/GarrisonMgr.h
index 1b96f9ca27e..89fd90f25c3 100644
--- a/src/server/game/Garrison/GarrisonMgr.h
+++ b/src/server/game/Garrison/GarrisonMgr.h
@@ -38,12 +38,14 @@ public:
GameObjectsEntry const* GetPlotGameObject(uint32 mapId, uint32 garrPlotInstanceId) const;
bool IsPlotMatchingBuilding(uint32 garrPlotId, uint32 garrBuildingId) const;
uint32 GetGarrBuildingPlotInst(uint32 garrBuildingId, uint32 garrSiteLevelPlotInstId) const;
+ GarrBuildingEntry const* GetPreviousLevelBuilding(uint32 buildingType, uint32 currentLevel) const;
private:
std::unordered_map<uint32 /*garrSiteId*/, std::vector<GarrSiteLevelPlotInstEntry const*>> _garrisonPlotInstBySiteLevel;
std::unordered_map<uint32 /*mapId*/, std::unordered_map<uint32 /*garrPlotId*/, GameObjectsEntry const*>> _garrisonPlots;
std::unordered_map<uint32 /*garrPlotId*/, std::unordered_set<uint32/*garrBuildingId*/>> _garrisonBuildingsByPlot;
std::unordered_map<uint64 /*garrBuildingId | garrSiteLevelPlotInstId << 32*/, uint32 /*garrBuildingPlotInstId*/> _garrisonBuildingPlotInstances;
+ std::unordered_map<uint32 /*buildingType*/, std::vector<GarrBuildingEntry const*>> _garrisonBuildingsByType;
};
#define sGarrisonMgr GarrisonMgr::Instance()
diff --git a/src/server/game/Handlers/GarrisonHandler.cpp b/src/server/game/Handlers/GarrisonHandler.cpp
index 0b45fb0ab57..54c7f4242fd 100644
--- a/src/server/game/Handlers/GarrisonHandler.cpp
+++ b/src/server/game/Handlers/GarrisonHandler.cpp
@@ -34,6 +34,15 @@ void WorldSession::HandleGarrisonPurchaseBuilding(WorldPackets::Garrison::Garris
garrison->PlaceBuilding(garrisonPurchaseBuilding.PlotInstanceID, garrisonPurchaseBuilding.BuildingID);
}
+void WorldSession::HandleGarrisonCancelConstruction(WorldPackets::Garrison::GarrisonCancelConstruction& garrisonCancelConstruction)
+{
+ if (!_player->GetNPCIfCanInteractWith(garrisonCancelConstruction.NpcGUID, UNIT_NPC_FLAG_GARRISON_ARCHITECT))
+ return;
+
+ if (Garrison* garrison = _player->GetGarrison())
+ garrison->CancelBuildingConstruction(garrisonCancelConstruction.PlotInstanceID);
+}
+
void WorldSession::HandleGarrisonRequestBlueprintAndSpecializationData(WorldPackets::Garrison::GarrisonRequestBlueprintAndSpecializationData& /*garrisonRequestBlueprintAndSpecializationData*/)
{
if (Garrison* garrison = _player->GetGarrison())
diff --git a/src/server/game/Server/Packets/GarrisonPackets.cpp b/src/server/game/Server/Packets/GarrisonPackets.cpp
index 09097450486..8dff6ff86d4 100644
--- a/src/server/game/Server/Packets/GarrisonPackets.cpp
+++ b/src/server/game/Server/Packets/GarrisonPackets.cpp
@@ -155,12 +155,27 @@ WorldPacket const* WorldPackets::Garrison::GarrisonPlaceBuildingResult::Write()
{
_worldPacket << uint32(Result);
_worldPacket << BuildingInfo;
- _worldPacket.WriteBit(Active);
+ _worldPacket.WriteBit(PlayActivationCinematic);
_worldPacket.FlushBits();
return &_worldPacket;
}
+void WorldPackets::Garrison::GarrisonCancelConstruction::Read()
+{
+ _worldPacket >> NpcGUID;
+ _worldPacket >> PlotInstanceID;
+}
+
+WorldPacket const* WorldPackets::Garrison::GarrisonBuildingRemoved::Write()
+{
+ _worldPacket << uint32(Result);
+ _worldPacket << uint32(GarrPlotInstanceID);
+ _worldPacket << uint32(GarrBuildingID);
+
+ return &_worldPacket;
+}
+
WorldPacket const* WorldPackets::Garrison::GarrisonLearnBlueprintResult::Write()
{
_worldPacket << uint32(Result);
@@ -208,3 +223,17 @@ WorldPacket const* WorldPackets::Garrison::GarrisonBuildingLandmarks::Write()
return &_worldPacket;
}
+
+WorldPacket const* WorldPackets::Garrison::GarrisonPlotPlaced::Write()
+{
+ _worldPacket << *PlotInfo;
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Garrison::GarrisonPlotRemoved::Write()
+{
+ _worldPacket << uint32(GarrPlotInstanceID);
+
+ return &_worldPacket;
+}
diff --git a/src/server/game/Server/Packets/GarrisonPackets.h b/src/server/game/Server/Packets/GarrisonPackets.h
index c632a5d6103..288074284b5 100644
--- a/src/server/game/Server/Packets/GarrisonPackets.h
+++ b/src/server/game/Server/Packets/GarrisonPackets.h
@@ -154,7 +154,30 @@ namespace WorldPackets
uint32 Result = 0;
GarrisonBuildingInfo BuildingInfo;
- bool Active = false;
+ bool PlayActivationCinematic = false;
+ };
+
+ class GarrisonCancelConstruction final : public ClientPacket
+ {
+ public:
+ GarrisonCancelConstruction(WorldPacket&& packet) : ClientPacket(CMSG_GARRISON_CANCEL_CONSTRUCTION, std::move(packet)) { }
+
+ void Read() override;
+
+ ObjectGuid NpcGUID;
+ uint32 PlotInstanceID = 0;
+ };
+
+ class GarrisonBuildingRemoved final : public ServerPacket
+ {
+ public:
+ GarrisonBuildingRemoved() : ServerPacket(SMSG_GARRISON_BUILDING_REMOVED, 4 + 4 + 4) { }
+
+ WorldPacket const* Write() override;
+
+ uint32 Result = 0;
+ uint32 GarrPlotInstanceID = 0;
+ uint32 GarrBuildingID = 0;
};
class GarrisonLearnBlueprintResult final : public ServerPacket
@@ -224,6 +247,26 @@ namespace WorldPackets
std::vector<GarrisonBuildingLandmark> Landmarks;
};
+
+ class GarrisonPlotPlaced final : public ServerPacket
+ {
+ public:
+ GarrisonPlotPlaced() : ServerPacket(SMSG_GARRISON_PLOT_PLACED) { }
+
+ WorldPacket const* Write() override;
+
+ GarrisonPlotInfo* PlotInfo = nullptr;
+ };
+
+ class GarrisonPlotRemoved final : public ServerPacket
+ {
+ public:
+ GarrisonPlotRemoved() : ServerPacket(SMSG_GARRISON_PLOT_REMOVED, 4) { }
+
+ WorldPacket const* Write() override;
+
+ uint32 GarrPlotInstanceID = 0;
+ };
}
}
diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp
index 6efac892cf9..07632e48b40 100644
--- a/src/server/game/Server/Protocol/Opcodes.cpp
+++ b/src/server/game/Server/Protocol/Opcodes.cpp
@@ -370,7 +370,7 @@ void OpcodeTable::Initialize()
DEFINE_HANDLER(CMSG_GAME_OBJ_REPORT_USE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::GameObject::GameObjReportUse, &WorldSession::HandleGameobjectReportUse);
DEFINE_HANDLER(CMSG_GAME_OBJ_USE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::GameObject::GameObjUse, &WorldSession::HandleGameObjectUseOpcode);
DEFINE_HANDLER(CMSG_GARRISON_ASSIGN_FOLLOWER_TO_BUILDING, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL);
- DEFINE_HANDLER(CMSG_GARRISON_CANCEL_CONSTRUCTION, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL);
+ DEFINE_HANDLER(CMSG_GARRISON_CANCEL_CONSTRUCTION, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Garrison::GarrisonCancelConstruction, &WorldSession::HandleGarrisonCancelConstruction);
DEFINE_HANDLER(CMSG_GARRISON_CHECK_UPGRADEABLE, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL);
DEFINE_HANDLER(CMSG_GARRISON_COMPLETE_MISSION, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL);
DEFINE_HANDLER(CMSG_GARRISON_GENERATE_RECRUITS, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL);
@@ -1114,7 +1114,7 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_GARRISON_ASSIGN_FOLLOWER_TO_BUILDING_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_GARRISON_BUILDING_ACTIVATED, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_GARRISON_BUILDING_LANDMARKS, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GARRISON_BUILDING_REMOVED, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GARRISON_BUILDING_REMOVED, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_GARRISON_BUILDING_SET_ACTIVE_SPECIALIZATION_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_GARRISON_COMPLETE_MISSION_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_GARRISON_CREATE_RESULT, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
@@ -1134,8 +1134,8 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_GARRISON_OPEN_MISSION_NPC, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_GARRISON_OPEN_TRADESKILL_NPC, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_GARRISON_PLACE_BUILDING_RESULT, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GARRISON_PLOT_PLACED, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GARRISON_PLOT_REMOVED, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GARRISON_PLOT_PLACED, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GARRISON_PLOT_REMOVED, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_GARRISON_RECALL_PORTAL_LAST_USED_TIME, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_GARRISON_RECALL_PORTAL_USED, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_GARRISON_RECRUITMENT_FOLLOWERS_GENERATED, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h
index da7cbbe8020..bd4fefdd665 100644
--- a/src/server/game/Server/WorldSession.h
+++ b/src/server/game/Server/WorldSession.h
@@ -218,6 +218,7 @@ namespace WorldPackets
{
class GetGarrisonInfo;
class GarrisonPurchaseBuilding;
+ class GarrisonCancelConstruction;
class GarrisonRequestBlueprintAndSpecializationData;
class GarrisonGetBuildingLandmarks;
}
@@ -1475,6 +1476,7 @@ class WorldSession
// Garrison
void HandleGetGarrisonInfo(WorldPackets::Garrison::GetGarrisonInfo& getGarrisonInfo);
void HandleGarrisonPurchaseBuilding(WorldPackets::Garrison::GarrisonPurchaseBuilding& garrisonPurchaseBuilding);
+ void HandleGarrisonCancelConstruction(WorldPackets::Garrison::GarrisonCancelConstruction& garrisonCancelConstruction);
void HandleGarrisonRequestBlueprintAndSpecializationData(WorldPackets::Garrison::GarrisonRequestBlueprintAndSpecializationData& garrisonRequestBlueprintAndSpecializationData);
void HandleGarrisonGetBuildingLandmarks(WorldPackets::Garrison::GarrisonGetBuildingLandmarks& garrisonGetBuildingLandmarks);