aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/updates/world/master/2025_06_15_08_world.sql19
-rw-r--r--src/server/game/Entities/AreaTrigger/AreaTrigger.cpp31
-rw-r--r--src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.h3
-rw-r--r--src/server/game/Entities/Player/Player.cpp25
-rw-r--r--src/server/game/Entities/Player/RestMgr.cpp2
-rw-r--r--src/server/game/Entities/Player/RestMgr.h13
-rw-r--r--src/server/game/Handlers/MiscHandler.cpp7
7 files changed, 87 insertions, 13 deletions
diff --git a/sql/updates/world/master/2025_06_15_08_world.sql b/sql/updates/world/master/2025_06_15_08_world.sql
new file mode 100644
index 00000000000..8e43adbd4ab
--- /dev/null
+++ b/sql/updates/world/master/2025_06_15_08_world.sql
@@ -0,0 +1,19 @@
+SET @ATID := 137;
+SET @ATCREATEID := 132;
+SET @ATSPAWNID := 231;
+
+DELETE FROM `areatrigger_template` WHERE `Id` BETWEEN @ATID+0 AND @ATID+26;
+INSERT INTO `areatrigger_template` (`Id`, `IsCustom`, `Flags`, `ActionSetId`, `ActionSetFlags`, `VerifiedBuild`) VALUES
+(@ATID+0, 1, 1, 0, 0x0, 0);
+
+DELETE FROM `areatrigger_create_properties` WHERE `Id` BETWEEN @ATCREATEID+0 AND @ATCREATEID+26;
+INSERT INTO `areatrigger_create_properties` (`Id`, `IsCustom`, `AreaTriggerId`, `IsAreatriggerCustom`, `Flags`, `MoveCurveId`, `ScaleCurveId`, `MorphCurveId`, `FacingCurveId`, `AnimId`, `AnimKitId`, `DecalPropertiesId`, `SpellForVisuals`, `TimeToTargetScale`, `Speed`, `Shape`, `ShapeData0`, `ShapeData1`, `ShapeData2`, `ShapeData3`, `ShapeData4`, `ShapeData5`, `ShapeData6`, `ShapeData7`, `ScriptName`, `VerifiedBuild`) VALUES
+(@ATCREATEID+0, 1, @ATID+0, 1, 0, 0, 0, 0, 0, -1, 0, 0, NULL, 0, 0, 4, 15, 15, 25, 25, 0, 0, 0, 0, '', 0);
+
+DELETE FROM `areatrigger` WHERE `SpawnId` BETWEEN @ATSPAWNID+0 AND @ATSPAWNID+26;
+INSERT INTO `areatrigger` (`SpawnId`, `AreaTriggerCreatePropertiesId`, `IsCustom`, `MapId`, `SpawnDifficulties`, `PosX`, `PosY`, `PosZ`, `Orientation`, `PhaseUseFlags`, `Comment`) VALUES
+(@ATSPAWNID+0, @ATCREATEID+0, 1, 1220, '0', -62.13, 7000.73, 19.81, 4.45, 0, 'Illidari Stand - Tavern');
+
+DELETE FROM `areatrigger_template_actions` WHERE `AreaTriggerId` BETWEEN @ATID+0 AND @ATID+26;
+INSERT INTO `areatrigger_template_actions` (`AreaTriggerId`, `IsCustom`, `ActionType`, `ActionParam`, `TargetType`) VALUES
+(@ATID+0, 1, 3, 0, 5);
diff --git a/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp b/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp
index 2181840580e..868ad6fbbc1 100644
--- a/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp
+++ b/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp
@@ -33,6 +33,7 @@
#include "ObjectMgr.h"
#include "PhasingHandler.h"
#include "Player.h"
+#include "RestMgr.h"
#include "ScriptMgr.h"
#include "SpellInfo.h"
#include "SpellMgr.h"
@@ -887,6 +888,9 @@ void AreaTrigger::HandleUnitEnterExit(std::vector<Unit*> const& newTargetList)
SetUpdateFieldValue(m_values.ModifyValue(&AreaTrigger::m_areaTriggerData).ModifyValue(&UF::AreaTriggerData::NumUnitsInside), _insideUnits.size());
SetUpdateFieldValue(m_values.ModifyValue(&AreaTrigger::m_areaTriggerData).ModifyValue(&UF::AreaTriggerData::NumPlayersInside),
std::ranges::count_if(_insideUnits, [](ObjectGuid const& guid) { return guid.IsPlayer(); }));
+
+ if (IsStaticSpawn())
+ setActive(!_insideUnits.empty());
}
uint32 AreaTrigger::GetScriptId() const
@@ -1050,6 +1054,13 @@ void AreaTrigger::DoActions(Unit* unit)
}
break;
}
+ case AREATRIGGER_ACTION_TAVERN:
+ if (Player* player = caster->ToPlayer())
+ {
+ player->GetRestMgr().SetInnTrigger(InnAreaTrigger{ .IsDBC = false });
+ player->GetRestMgr().SetRestFlag(REST_FLAG_IN_TAVERN);
+ }
+ break;
default:
break;
}
@@ -1061,9 +1072,25 @@ void AreaTrigger::DoActions(Unit* unit)
void AreaTrigger::UndoActions(Unit* unit)
{
if (GetTemplate())
+ {
for (AreaTriggerAction const& action : GetTemplate()->Actions)
- if (action.ActionType == AREATRIGGER_ACTION_CAST || action.ActionType == AREATRIGGER_ACTION_ADDAURA)
- unit->RemoveAurasDueToSpell(action.Param, GetCasterGuid());
+ {
+ switch (action.ActionType)
+ {
+ case AREATRIGGER_ACTION_CAST:
+ [[fallthrough]];
+ case AREATRIGGER_ACTION_ADDAURA:
+ unit->RemoveAurasDueToSpell(action.Param, GetCasterGuid());
+ break;
+ case AREATRIGGER_ACTION_TAVERN:
+ if (Player* player = unit->ToPlayer())
+ player->GetRestMgr().SetInnTrigger(std::nullopt);
+ break;
+ default:
+ break;
+ }
+ }
+ }
}
void AreaTrigger::InitSplineOffsets(std::vector<Position> const& offsets, Optional<float> overrideSpeed)
diff --git a/src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.h b/src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.h
index a5846beb78c..5dba3e6b499 100644
--- a/src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.h
+++ b/src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.h
@@ -42,7 +42,8 @@ enum AreaTriggerActionTypes
AREATRIGGER_ACTION_CAST = 0,
AREATRIGGER_ACTION_ADDAURA = 1,
AREATRIGGER_ACTION_TELEPORT = 2,
- AREATRIGGER_ACTION_MAX = 3
+ AREATRIGGER_ACTION_TAVERN = 3,
+ AREATRIGGER_ACTION_MAX = 4
};
enum AreaTriggerActionUserTypes
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index f48bb73995e..fd8408873b7 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -6432,12 +6432,27 @@ void Player::UpdateIndoorsOutdoorsAuras()
void Player::UpdateTavernRestingState()
{
- AreaTriggerEntry const* atEntry = sAreaTriggerStore.LookupEntry(_restMgr->GetInnTriggerID());
+ Optional<InnAreaTrigger> innTrigger = _restMgr->GetInnTrigger();
+ if (!innTrigger)
+ {
+ if (_restMgr->HasRestFlag(REST_FLAG_IN_TAVERN))
+ _restMgr->RemoveRestFlag(REST_FLAG_IN_TAVERN);
- if (_restMgr->HasRestFlag(REST_FLAG_IN_TAVERN) && (!atEntry || !IsInAreaTrigger(atEntry)))
- _restMgr->RemoveRestFlag(REST_FLAG_IN_TAVERN);
- else if (!_restMgr->HasRestFlag(REST_FLAG_IN_TAVERN) && IsInAreaTrigger(atEntry))
- _restMgr->SetRestFlag(REST_FLAG_IN_TAVERN);
+ return;
+ }
+
+ if (innTrigger->IsDBC)
+ {
+ AreaTriggerEntry const* atEntry = sAreaTriggerStore.LookupEntry(innTrigger->AreaTriggerEntryId);
+
+ if (_restMgr->HasRestFlag(REST_FLAG_IN_TAVERN) && (!atEntry || !IsInAreaTrigger(atEntry)))
+ {
+ _restMgr->RemoveRestFlag(REST_FLAG_IN_TAVERN);
+ _restMgr->SetInnTrigger(std::nullopt);
+ }
+ else if (!_restMgr->HasRestFlag(REST_FLAG_IN_TAVERN) && IsInAreaTrigger(atEntry))
+ _restMgr->SetRestFlag(REST_FLAG_IN_TAVERN);
+ }
}
Team Player::TeamForRace(uint8 race)
diff --git a/src/server/game/Entities/Player/RestMgr.cpp b/src/server/game/Entities/Player/RestMgr.cpp
index ef978b5056f..6fae5b98f29 100644
--- a/src/server/game/Entities/Player/RestMgr.cpp
+++ b/src/server/game/Entities/Player/RestMgr.cpp
@@ -23,7 +23,7 @@
#include "World.h"
#include "WorldSession.h"
-RestMgr::RestMgr(Player* player) : _player(player), _restTime(0), _innAreaTriggerId(0), _restFlagMask(0)
+RestMgr::RestMgr(Player* player) : _player(player), _restTime(0), _restFlagMask(0)
{
for (uint8 i = REST_TYPE_XP; i < REST_TYPE_MAX; i++)
_restBonus[i] = 0;
diff --git a/src/server/game/Entities/Player/RestMgr.h b/src/server/game/Entities/Player/RestMgr.h
index becde78ec24..b3d991a1677 100644
--- a/src/server/game/Entities/Player/RestMgr.h
+++ b/src/server/game/Entities/Player/RestMgr.h
@@ -19,6 +19,7 @@
#define RestMgr_h__
#include "Define.h"
+#include "Optional.h"
#include <ctime>
class Player;
@@ -55,6 +56,12 @@ enum RestFlag : uint32
REST_FLAG_IN_FACTION_AREA = 0x4 // used with AREA_FLAG_REST_ZONE_*
};
+struct InnAreaTrigger
+{
+ bool IsDBC = true;
+ uint32 AreaTriggerEntryId = 0;
+};
+
class TC_GAME_API RestMgr
{
friend class Player;
@@ -72,8 +79,8 @@ public:
void RemoveRestFlag(RestFlag restFlag);
uint32 GetRestBonusFor(RestTypes restType, uint32 xp);
- uint32 GetInnTriggerID() const { return _innAreaTriggerId; }
- void SetInnTriggerID(uint32 id) { _innAreaTriggerId = id; }
+ Optional<InnAreaTrigger> GetInnTrigger() const { return _innAreaTrigger; }
+ void SetInnTrigger(Optional<InnAreaTrigger> trigger) { _innAreaTrigger = trigger; }
void Update(time_t now);
@@ -85,7 +92,7 @@ protected:
private:
Player* _player;
time_t _restTime;
- uint32 _innAreaTriggerId;
+ Optional<InnAreaTrigger> _innAreaTrigger;
float _restBonus[REST_TYPE_MAX];
uint32 _restFlagMask;
};
diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp
index facda1a71c2..c60ba89ab6a 100644
--- a/src/server/game/Handlers/MiscHandler.cpp
+++ b/src/server/game/Handlers/MiscHandler.cpp
@@ -567,9 +567,14 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPackets::AreaTrigger::AreaTrigge
{
// set resting flag we are in the inn
if (packet.Entered)
- player->GetRestMgr().SetInnTriggerID(atEntry->ID);
+ {
+ player->GetRestMgr().SetInnTrigger(InnAreaTrigger{ .IsDBC = true, .AreaTriggerEntryId = atEntry->ID });
+ }
else
+ {
player->GetRestMgr().RemoveRestFlag(REST_FLAG_IN_TAVERN);
+ player->GetRestMgr().SetInnTrigger(std::nullopt);
+ }
if (sWorld->IsFFAPvPRealm())
{