Skip to content

Commit

Permalink
[s2480] SpawnGroup: Implement spawn_group_squad and respawn override
Browse files Browse the repository at this point in the history
  • Loading branch information
killerwife committed Dec 26, 2024
1 parent 07a6e4b commit 2967066
Show file tree
Hide file tree
Showing 12 changed files with 281 additions and 121 deletions.
17 changes: 16 additions & 1 deletion sql/base/mangos.sql
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ DROP TABLE IF EXISTS `db_version`;
CREATE TABLE `db_version` (
`version` varchar(120) DEFAULT NULL,
`creature_ai_version` varchar(120) DEFAULT NULL,
`required_s2479_01_mangos_displayid_probability` bit(1) DEFAULT NULL
`required_s2480_01_mangos_spawn_group_squad` bit(1) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Used DB version notes';

--
Expand Down Expand Up @@ -12891,6 +12891,8 @@ CREATE TABLE `spawn_group` (
`WorldStateExpression` int(11) NOT NULL DEFAULT 0 COMMENT 'Worldstate expression Id',
`Flags` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'Flags for various behaviour',
`StringId` INT(11) UNSIGNED NOT NULL DEFAULT '0',
`RespawnOverrideMin` INT UNSIGNED COMMENT 'Respawn time override' DEFAULT NULL,
`RespawnOverrideMax` INT UNSIGNED COMMENT 'Respawn time override' DEFAULT NULL,
PRIMARY KEY (`Id`)
);

Expand Down Expand Up @@ -12944,6 +12946,19 @@ CREATE TABLE `spawn_group_linked_group` (
PRIMARY KEY (`Id`, `LinkedId`)
);

-- ----------------------------
-- Table structure for spawn_group_squad
-- ----------------------------

DROP TABLE IF EXISTS spawn_group_squad;
CREATE TABLE spawn_group_squad(
Id INT NOT NULL COMMENT 'Spawn Group ID',
SquadId INT NOT NULL COMMENT 'Squad Id within Spawn Group',
Guid INT NOT NULL COMMENT 'Guid of creature or GO',
Entry INT NOT NULL COMMENT 'Entry of creature or GO',
PRIMARY KEY(Id, SquadId, Guid)
);

--
-- Table structure for table `spam_records`
--
Expand Down
15 changes: 15 additions & 0 deletions sql/updates/mangos/s2480_01_mangos_spawn_group_squad.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
ALTER TABLE db_version CHANGE COLUMN required_s2479_01_mangos_displayid_probability required_s2480_01_mangos_spawn_group_squad bit;

DROP TABLE IF EXISTS spawn_group_squad;
CREATE TABLE spawn_group_squad(
Id INT NOT NULL COMMENT 'Spawn Group ID',
SquadId INT NOT NULL COMMENT 'Squad Id within Spawn Group',
Guid INT NOT NULL COMMENT 'Guid of creature or GO',
Entry INT NOT NULL COMMENT 'Entry of creature or GO',
PRIMARY KEY(Id, SquadId, Guid)
);

ALTER TABLE spawn_group ADD COLUMN `RespawnOverrideMin` INT UNSIGNED COMMENT 'Respawn time override' DEFAULT NULL AFTER `StringId`;
ALTER TABLE spawn_group ADD COLUMN `RespawnOverrideMax` INT UNSIGNED COMMENT 'Respawn time override' DEFAULT NULL AFTER `RespawnOverrideMin`;


4 changes: 3 additions & 1 deletion src/game/Entities/Creature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1870,7 +1870,9 @@ void Creature::SetDeathState(DeathState s)
{
if (!m_respawnOverriden)
{
if (CreatureData const* data = sObjectMgr.GetCreatureData(GetDbGuid()))
if (GetCreatureGroup() && GetCreatureGroup()->IsRespawnOverriden())
m_respawnDelay = GetCreatureGroup()->GetRandomRespawnTime();
else if (CreatureData const* data = sObjectMgr.GetCreatureData(GetDbGuid()))
m_respawnDelay = data->GetRandomRespawnTime();
}
else if (m_respawnOverrideOnce)
Expand Down
2 changes: 1 addition & 1 deletion src/game/Entities/Creature.h
Original file line number Diff line number Diff line change
Expand Up @@ -769,7 +769,7 @@ class Creature : public Unit
void Respawn();
void SaveRespawnTime() override;

uint32 GetRespawnDelay() const { return m_respawnDelay; }
uint32 GetRespawnDelay() const override { return m_respawnDelay; }
void SetRespawnDelay(uint32 delay, bool once = false) { m_respawnDelay = delay; m_respawnOverriden = true; m_respawnOverrideOnce = once; } // in seconds
void SetRespawnDelay(std::chrono::seconds delay, bool once = false) { SetRespawnDelay(delay.count(), once); }

Expand Down
6 changes: 5 additions & 1 deletion src/game/Entities/GameObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -692,8 +692,12 @@ void GameObject::Update(const uint32 diff)
{
// since pool system can fail to roll unspawned object, this one can remain spawned, so must set respawn nevertheless
if (IsSpawnedByDefault())
if (GameObjectData const* data = sObjectMgr.GetGOData(GetDbGuid()))
{
if (GetGameObjectGroup() && GetGameObjectGroup()->IsRespawnOverriden())
m_respawnDelay = GetGameObjectGroup()->GetRandomRespawnTime();
else if (GameObjectData const* data = sObjectMgr.GetGOData(GetDbGuid()))
m_respawnDelay = data->GetRandomRespawnTime();
}
}
else if (m_respawnOverrideOnce)
m_respawnOverriden = false;
Expand Down
2 changes: 1 addition & 1 deletion src/game/Entities/GameObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -789,7 +789,7 @@ class GameObject : public WorldObject
(m_respawnTime == 0 && m_spawnedByDefault);
}
bool IsSpawnedByDefault() const { return m_spawnedByDefault; }
uint32 GetRespawnDelay() const { return m_respawnDelay; }
uint32 GetRespawnDelay() const override { return m_respawnDelay; }
void SetRespawnDelay(uint32 delay, bool once = false) { m_respawnDelay = delay; m_respawnOverriden = true; m_respawnOverrideOnce = once; }
void SetForcedDespawn() { m_forcedDespawn = true; };
void SetChestDespawn();
Expand Down
2 changes: 2 additions & 0 deletions src/game/Entities/Object.h
Original file line number Diff line number Diff line change
Expand Up @@ -1212,6 +1212,8 @@ class WorldObject : public Object
bool HasStringId(uint32 stringId) const; // not to be used in sd2
void SetStringId(uint32 stringId, bool apply); // not to be used outside of scriptmgr

virtual uint32 GetRespawnDelay() const { return 0; }

protected:
explicit WorldObject();

Expand Down
46 changes: 45 additions & 1 deletion src/game/Globals/ObjectMgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1198,7 +1198,7 @@ void ObjectMgr::LoadSpawnGroups()
std::shared_ptr<SpawnGroupEntryContainer> newContainer = std::make_shared<SpawnGroupEntryContainer>();
uint32 count = 0;

std::unique_ptr<QueryResult> result(WorldDatabase.Query("SELECT Id, Name, Type, MaxCount, WorldState, WorldStateExpression, Flags, StringId FROM spawn_group"));
std::unique_ptr<QueryResult> result(WorldDatabase.Query("SELECT Id, Name, Type, MaxCount, WorldState, WorldStateExpression, Flags, StringId, RespawnOverrideMin, RespawnOverrideMax FROM spawn_group"));
if (result)
{
do
Expand Down Expand Up @@ -1257,6 +1257,10 @@ void ObjectMgr::LoadSpawnGroups()
entry.EnabledByDefault = true;
entry.Formation = nullptr;
entry.HasChancedSpawns = false;
if (!fields[8].IsNULL())
entry.RespawnOverrideMin = fields[8].GetUInt32();
if (!fields[9].IsNULL())
entry.RespawnOverrideMax = fields[9].GetUInt32();
newContainer->spawnGroupMap.emplace(entry.Id, std::move(entry));
} while (result->NextRow());
}
Expand Down Expand Up @@ -1495,6 +1499,46 @@ void ObjectMgr::LoadSpawnGroups()
} while (result->NextRow());
}

result = WorldDatabase.Query("SELECT Id, SquadId, Guid, Entry FROM spawn_group_squad");
if (result)
{
do
{
Field* fields = result->Fetch();
uint32 Id = fields[0].GetUInt32();

uint32 squadId = fields[1].GetUInt32();
uint32 dbGuid = fields[2].GetUInt32();
uint32 entry = fields[3].GetUInt32();

auto itr = newContainer->spawnGroupMap.find(Id);
if (itr == newContainer->spawnGroupMap.end())
{
sLog.outErrorDb("LoadSpawnGroups: Invalid spawn_group_squad Id %u. Skipping.", Id);
continue;
}

auto& spawnGroup = itr->second;
if (!spawnGroup.RandomEntries.empty())
sLog.outErrorDb("LoadSpawnGroups: spawn_group_squad Id %u has spawn_group_entry. Will be overriden by squad", Id);

auto squadItr = std::find_if(spawnGroup.Squads.begin(), spawnGroup.Squads.end(), [squadId](const SpawnGroupSquad& obj) -> bool { return obj.SquadId == squadId; });

if (squadItr == spawnGroup.Squads.end())
{
SpawnGroupSquad squad;
squad.SquadId = squadId;
squad.GuidToEntry.emplace(dbGuid, entry);
spawnGroup.Squads.push_back(std::move(squad));
}
else
{
squadItr->GuidToEntry.emplace(dbGuid, entry);
}
}
while (result->NextRow());
}

for (auto& data : newContainer->spawnGroupMap)
{
SpawnGroupEntry& entry = data.second;
Expand Down
Loading

0 comments on commit 2967066

Please sign in to comment.