[Traps] Convert Load/Set of Traps to Repositories (#3994)

# Notes
- Convert `LoadTraps()` and `SetTrapData()` to repositories.
This commit is contained in:
Alex King 2024-01-28 23:38:21 -05:00 committed by GitHub
parent a38fd8f986
commit 1cb72642ac
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 96 additions and 91 deletions

View File

@ -24,6 +24,7 @@
#include "mob.h" #include "mob.h"
#include "trap.h" #include "trap.h"
#include "../common/repositories/criteria/content_filter_criteria.h" #include "../common/repositories/criteria/content_filter_criteria.h"
#include "../common/repositories/traps_repository.h"
/* /*
@ -439,59 +440,63 @@ void EntityList::ClearTrapPointers()
} }
bool ZoneDatabase::LoadTraps(const char* zonename, int16 version) {
std::string query = StringFormat(
"SELECT id, x, y, z, effect, effectvalue, effectvalue2, skill, " bool ZoneDatabase::LoadTraps(const std::string& zone_short_name, int16 instance_version)
"maxzdiff, radius, chance, message, respawn_time, respawn_var, level, " {
"`group`, triggered_number, despawn_when_triggered, undetectable FROM traps WHERE zone='%s' AND version=%u %s", const auto& l = TrapsRepository::GetWhere(
zonename, *this,
version, fmt::format(
ContentFilterCriteria::apply().c_str() "`zone` = '{}' AND `version` = {} {}",
Strings::Escape(zone_short_name),
instance_version,
ContentFilterCriteria::apply()
)
); );
auto results = QueryDatabase(query); if (l.empty()) {
if (!results.Success()) {
return false; return false;
} }
for (auto row = results.begin(); row != results.end(); ++row) { for (const auto& e : l) {
uint32 tid = Strings::ToInt(row[0]); if (e.group) {
uint8 grp = Strings::ToInt(row[15]); if (entity_list.IsTrapGroupSpawned(e.id, e.group)) {
if (grp > 0)
{
// If a member of our group is already spawned skip loading this trap. // If a member of our group is already spawned skip loading this trap.
if (entity_list.IsTrapGroupSpawned(tid, grp))
{
continue; continue;
} }
} }
auto trap = new Trap();
trap->trap_id = tid; auto t = new Trap();
trap->db_id = tid;
trap->m_Position = glm::vec3(Strings::ToFloat(row[1]), Strings::ToFloat(row[2]), Strings::ToFloat(row[3])); t->trap_id = e.id;
trap->effect = Strings::ToInt(row[4]); t->db_id = e.id;
trap->effectvalue = Strings::ToInt(row[5]); t->m_Position = glm::vec3(e.x, e.y, e.z);
trap->effectvalue2 = Strings::ToInt(row[6]); t->effect = e.effect;
trap->skill = Strings::ToInt(row[7]); t->effectvalue = e.effectvalue;
trap->maxzdiff = Strings::ToFloat(row[8]); t->effectvalue2 = e.effectvalue2;
trap->radius = Strings::ToFloat(row[9]); t->skill = e.skill;
trap->chance = Strings::ToInt(row[10]); t->maxzdiff = e.maxzdiff;
trap->message = row[11]; t->radius = e.radius;
trap->respawn_time = Strings::ToInt(row[12]); t->chance = e.chance;
trap->respawn_var = Strings::ToInt(row[13]); t->message = e.message;
trap->level = Strings::ToInt(row[14]); t->respawn_time = e.respawn_time;
trap->group = grp; t->respawn_var = e.respawn_var;
trap->triggered_number = Strings::ToInt(row[16]); t->level = e.level;
trap->despawn_when_triggered = atobool(row[17]); t->group = e.group;
trap->undetectable = atobool(row[18]); t->triggered_number = e.triggered_number;
entity_list.AddTrap(trap); t->despawn_when_triggered = e.despawn_when_triggered;
trap->CreateHiddenTrigger(); t->undetectable = e.undetectable;
Log(Logs::General, Logs::Traps, "Trap %d successfully loaded.", trap->trap_id);
entity_list.AddTrap(t);
t->CreateHiddenTrigger();
} }
LogInfo("Loaded [{}] trap(s)", Strings::Commify(results.RowCount())); LogInfo(
"Loaded [{}] Trap{}",
Strings::Commify(l.size()),
l.size() != 1 ? "s" : ""
);
return true; return true;
} }
@ -525,61 +530,61 @@ void Trap::CreateHiddenTrigger()
SetHiddenTrigger(npca); SetHiddenTrigger(npca);
} }
bool ZoneDatabase::SetTrapData(Trap* trap, bool repopnow) { bool ZoneDatabase::SetTrapData(Trap* t, bool repop)
{
const auto& l = TrapsRepository::GetWhere(
*this,
fmt::format(
"`zone` = '{}' AND `id` = {}{}",
zone->GetShortName(),
t->db_id,
(
t->group ?
fmt::format(
" AND `group` = {} ORDER BY RAND() LIMIT 1",
t->group
) :
""
)
)
);
uint32 dbid = trap->db_id; if (l.empty()) {
std::string query;
if (trap->group > 0)
{
query = StringFormat("SELECT id, x, y, z, effect, effectvalue, effectvalue2, skill, "
"maxzdiff, radius, chance, message, respawn_time, respawn_var, level, "
"triggered_number, despawn_when_triggered, undetectable FROM traps WHERE zone='%s' AND `group`=%d AND id != %d ORDER BY RAND() LIMIT 1", zone->GetShortName(), trap->group, dbid);
}
else
{
// We could just use the existing data here, but querying the DB is not expensive, and allows content developers to change traps without rebooting.
query = StringFormat("SELECT id, x, y, z, effect, effectvalue, effectvalue2, skill, "
"maxzdiff, radius, chance, message, respawn_time, respawn_var, level, "
"triggered_number, despawn_when_triggered, undetectable FROM traps WHERE zone='%s' AND id = %d", zone->GetShortName(), dbid);
}
auto results = QueryDatabase(query);
if (!results.Success()) {
return false; return false;
} }
for (auto row = results.begin(); row != results.end(); ++row) { const uint32 before_id = t->db_id;
trap->db_id = Strings::ToInt(row[0]); for (const auto& e : l) {
trap->m_Position = glm::vec3(Strings::ToFloat(row[1]), Strings::ToFloat(row[2]), Strings::ToFloat(row[3])); t->db_id = e.id;
trap->effect = Strings::ToInt(row[4]); t->m_Position = glm::vec3(e.x, e.y, e.z);
trap->effectvalue = Strings::ToInt(row[5]); t->effect = e.effect;
trap->effectvalue2 = Strings::ToInt(row[6]); t->effectvalue = e.effectvalue;
trap->skill = Strings::ToInt(row[7]); t->effectvalue2 = e.effectvalue2;
trap->maxzdiff = Strings::ToFloat(row[8]); t->skill = e.skill;
trap->radius = Strings::ToFloat(row[9]); t->maxzdiff = e.maxzdiff;
trap->chance = Strings::ToInt(row[10]); t->radius = e.radius;
trap->message = row[11]; t->chance = e.chance;
trap->respawn_time = Strings::ToInt(row[12]); t->message = e.message;
trap->respawn_var = Strings::ToInt(row[13]); t->respawn_var = e.respawn_var;
trap->level = Strings::ToInt(row[14]); t->level = e.level;
trap->triggered_number = Strings::ToInt(row[15]); t->triggered_number = e.triggered_number;
trap->despawn_when_triggered = atobool(row[16]); t->despawn_when_triggered = e.despawn_when_triggered;
trap->undetectable = atobool(row[17]); t->undetectable = e.undetectable;
trap->CreateHiddenTrigger(); t->respawn_time = e.respawn_time;
if (repopnow) t->CreateHiddenTrigger();
{
trap->chkarea_timer.Enable();
} if (repop) {
else t->chkarea_timer.Enable();
{ } else {
trap->respawn_timer.Start((trap->respawn_time + zone->random.Int(0, trap->respawn_var)) * 1000); t->respawn_timer.Start((t->respawn_time + zone->random.Int(0, t->respawn_var)) * 1000);
} }
if (trap->trap_id != trap->db_id) if (t->trap_id != t->db_id) {
Log(Logs::General, Logs::Traps, "Trap (%d) DBID has changed from %d to %d", trap->trap_id, dbid, trap->db_id); LogTraps("Trap ({}) DBID has changed from {} to {}.", t->trap_id, before_id, t->db_id);
}
return true; return true;
} }

View File

@ -623,8 +623,8 @@ public:
bool LoadBlockedSpells(int64 blocked_spells_count, ZoneSpellsBlocked* into, uint32 zone_id); bool LoadBlockedSpells(int64 blocked_spells_count, ZoneSpellsBlocked* into, uint32 zone_id);
/* Traps */ /* Traps */
bool LoadTraps(const char* zonename, int16 version); bool LoadTraps(const std::string& zone_short_name, int16 instance_version);
bool SetTrapData(Trap* trap, bool repopnow = false); bool SetTrapData(Trap* t, bool repop = false);
/* Time */ /* Time */
uint32 GetZoneTimezone(uint32 zoneid, uint32 version); uint32 GetZoneTimezone(uint32 zoneid, uint32 version);