diff --git a/zone/command.cpp b/zone/command.cpp index ab18d63ac..884d43330 100755 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -11708,8 +11708,6 @@ void command_object(Client *c, const Seperator *sep) Object *o = nullptr; Object_Struct od; - Door door; - Doors *doors; Door_Struct *ds; uint32 id = 0; uint32 itemid = 0; @@ -12531,32 +12529,34 @@ void command_object(Client *c, const Seperator *sep) entity_list.RemoveObject(o->GetID()); - memset(&door, 0, sizeof(door)); + auto door = DoorsRepository::NewEntity(); - strn0cpy(door.zone_name, zone->GetShortName(), sizeof(door.zone_name)); + door.zone = zone->GetShortName(); - door.db_id = 1000000000 + id; // Out of range of normal use for doors.id - door.door_id = -1; // Client doesn't care if these are all the same door_id - door.pos_x = od.x; // xpos - door.pos_y = od.y; // ypos - door.pos_z = od.z; // zpos - door.heading = od.heading; // heading + door.id = 1000000000 + id; // Out of range of normal use for doors.id + door.doorid = -1; // Client doesn't care if these are all the same door_id + door.pos_x = od.x; + door.pos_y = od.y; + door.pos_z = od.z; + door.heading = od.heading; - strn0cpy(door.door_name, od.object_name, sizeof(door.door_name)); // objectname + door.name = od.object_name; // Strip trailing "_ACTORDEF" if present. Client won't accept it for doors. - uint32 len = strlen(door.door_name); - if ((len > 9) && (memcmp(&door.door_name[len - 9], "_ACTORDEF", 10) == 0)) - door.door_name[len - 9] = '\0'; + int pos = door.name.size() - strlen("_ACTORDEF"); + if (pos > 0 && door.name.compare(pos, std::string::npos, "_ACTORDEF") == 0) + { + door.name.erase(pos); + } - memcpy(door.dest_zone, "NONE", 5); + door.dest_zone = "NONE"; if ((door.size = od.size) == 0) // unknown08 = optional size percentage door.size = 100; - switch ( - door.opentype = - od.solidtype) // unknown10 = optional request_nonsolid (0 or 1 or experimental number) + door.opentype = od.solidtype; + + switch (door.opentype) // unknown10 = optional request_nonsolid (0 or 1 or experimental number) { case 0: door.opentype = 31; @@ -12570,21 +12570,22 @@ void command_object(Client *c, const Seperator *sep) door.incline = od.unknown020; // unknown20 = optional incline value door.client_version_mask = 0xFFFFFFFF; - doors = new Doors(&door); + Doors* doors = new Doors(door); + entity_list.AddDoor(doors); app = new EQApplicationPacket(OP_SpawnDoor, sizeof(Door_Struct)); ds = (Door_Struct *)app->pBuffer; memset(ds, 0, sizeof(Door_Struct)); - memcpy(ds->name, door.door_name, 32); + memcpy(ds->name, door.name.c_str(), 32); ds->xPos = door.pos_x; ds->yPos = door.pos_y; ds->zPos = door.pos_z; ds->heading = door.heading; ds->incline = door.incline; ds->size = door.size; - ds->doorId = door.door_id; + ds->doorId = door.doorid; ds->opentype = door.opentype; ds->unknown0052[9] = 1; // *ptr-1 and *ptr-3 from EntityList::MakeDoorSpawnPacket() ds->unknown0052[11] = 1; diff --git a/zone/doors.cpp b/zone/doors.cpp index 2458e7f69..83f8dcb8a 100644 --- a/zone/doors.cpp +++ b/zone/doors.cpp @@ -42,38 +42,38 @@ extern EntityList entity_list; extern WorldServer worldserver; -Doors::Doors(const Door *door) : +Doors::Doors(const DoorsRepository::Doors& door) : close_timer(5000), - m_Position(door->pos_x, door->pos_y, door->pos_z, door->heading), - m_Destination(door->dest_x, door->dest_y, door->dest_z, door->dest_heading) { + m_Position(door.pos_x, door.pos_y, door.pos_z, door.heading), + m_Destination(door.dest_x, door.dest_y, door.dest_z, door.dest_heading) +{ + strn0cpy(zone_name, door.zone.c_str(), sizeof(zone_name)); + strn0cpy(door_name, door.name.c_str(), sizeof(door_name)); + strn0cpy(destination_zone_name, door.dest_zone.c_str(), sizeof(destination_zone_name)); - strn0cpy(zone_name, door->zone_name, 32); - strn0cpy(door_name, door->door_name, 32); - strn0cpy(destination_zone_name, door->dest_zone, 16); - - this->database_id = door->db_id; - this->door_id = door->door_id; - this->incline = door->incline; - this->open_type = door->opentype; - this->guild_id = door->guild_id; - this->lockpick = door->lock_pick; - this->key_item_id = door->keyitem; - this->no_key_ring = door->nokeyring; - this->trigger_door = door->trigger_door; - this->trigger_type = door->trigger_type; - this->triggered = false; - this->door_param = door->door_param; - this->size = door->size; - this->invert_state = door->invert_state; - this->destination_instance_id = door->dest_instance_id; - this->is_ldon_door = door->is_ldon_door; - this->client_version_mask = door->client_version_mask; + database_id = door.id; + door_id = door.doorid; + incline = door.incline; + open_type = door.opentype; + guild_id = door.guild; + lockpick = door.lockpick; + key_item_id = door.keyitem; + no_key_ring = door.nokeyring; + trigger_door = door.triggerdoor; + trigger_type = door.triggertype; + triggered = false; + door_param = door.door_param; + size = door.size; + invert_state = door.invert_state; + destination_instance_id = door.dest_instance; + is_ldon_door = door.is_ldon_door; + client_version_mask = door.client_version_mask; SetOpenState(false); close_timer.Disable(); - disable_timer = (door->disable_timer == 1 ? true : false); + disable_timer = (door.disable_timer == 1 ? true : false); } Doors::Doors(const char *model, const glm::vec4 &position, uint8 open_type, uint16 size) : @@ -682,106 +682,19 @@ int32 ZoneDatabase::GetDoorsDBCountPlusOne(const char *zone_name, int16 version) return atoi(row[0]) + 1; } -bool ZoneDatabase::LoadDoors(int32 door_count, Door *into, const char *zone_name, int16 version) { +std::vector ZoneDatabase::LoadDoors(const std::string& zone_name, int16 version) +{ LogInfo("Loading Doors from database"); - std::string query = StringFormat( - " SELECT " - " id, " - " doorid, " - " zone, " - " NAME, " - " pos_x, " - " pos_y, " - " pos_z, " - " heading, " - " opentype, " - " guild, " - " lockpick, " - " keyitem, " - " nokeyring, " - " triggerdoor, " - " triggertype, " - " dest_zone, " - " dest_instance, " - " dest_x, " - " dest_y, " - " dest_z, " - " dest_heading, " - " door_param, " - " invert_state, " - " incline, " - " size, " - " is_ldon_door, " - " client_version_mask, " - " disable_timer " - " FROM " - " doors " - " WHERE " - " zone = '%s' " - " AND ( version = % u OR version = - 1 ) " - " %s " - " ORDER BY " - " doorid ASC ", - zone_name, - version, - ContentFilterCriteria::apply().c_str() - ); - auto results = QueryDatabase(query); - if (!results.Success()) { - return false; - } + auto door_entries = DoorsRepository::GetWhere(*this, fmt::format( + "zone = '{}' AND (version = {} OR version = -1) {} ORDER BY doorid ASC", + zone_name, version, ContentFilterCriteria::apply())); - int32 row_index = 0; - for (auto row = results.begin(); row != results.end(); ++row, ++row_index) { - if (row_index >= door_count) { - std::cerr << "Error, Door Count of " << door_count << " exceeded." << std::endl; - break; - } + LogDoors("Loaded [{}] doors for [{}] version [{}]", door_entries.size(), zone_name, version); - memset(&into[row_index], 0, sizeof(Door)); - - strn0cpy(into[row_index].zone_name, row[2], 32); - strn0cpy(into[row_index].door_name, row[3], 32); - strn0cpy(into[row_index].dest_zone, row[15], 32); - - into[row_index].db_id = static_cast(atoi(row[0])); - into[row_index].door_id = static_cast(atoi(row[1])); - into[row_index].pos_x = (float) atof(row[4]); - into[row_index].pos_y = (float) atof(row[5]); - into[row_index].pos_z = (float) atof(row[6]); - into[row_index].heading = (float) atof(row[7]); - into[row_index].opentype = static_cast(atoi(row[8])); - into[row_index].guild_id = static_cast(atoi(row[9])); - into[row_index].lock_pick = static_cast(atoi(row[10])); - into[row_index].keyitem = static_cast(atoi(row[11])); - into[row_index].nokeyring = static_cast(atoi(row[12])); - into[row_index].trigger_door = static_cast(atoi(row[13])); - into[row_index].trigger_type = static_cast(atoi(row[14])); - into[row_index].dest_instance_id = static_cast(atoi(row[16])); - into[row_index].dest_x = (float) atof(row[17]); - into[row_index].dest_y = (float) atof(row[18]); - into[row_index].dest_z = (float) atof(row[19]); - into[row_index].dest_heading = (float) atof(row[20]); - into[row_index].door_param = static_cast(atoi(row[21])); - into[row_index].invert_state = atoi(row[22]); - into[row_index].incline = atoi(row[23]); - into[row_index].size = static_cast(atoi(row[24])); - into[row_index].is_ldon_door = static_cast(atoi(row[25])); - into[row_index].client_version_mask = (uint32) strtoul(row[26], nullptr, 10); - into[row_index].disable_timer = static_cast(atoi(row[27])); - - Log(Logs::Detail, Logs::Doors, "Door Load: db id: %u, door_id %u disable_timer: %i", - into[row_index].db_id, - into[row_index].door_id, - into[row_index].disable_timer - ); - } - - return true; + return door_entries; } - void Doors::SetLocation(float x, float y, float z) { entity_list.DespawnAllDoors(); diff --git a/zone/doors.h b/zone/doors.h index 455dfd03f..009041805 100644 --- a/zone/doors.h +++ b/zone/doors.h @@ -1,6 +1,7 @@ #ifndef DOORS_H #define DOORS_H +#include "../common/repositories/doors_repository.h" #include "../common/emu_opcodes.h" #include "../common/eq_packet_structs.h" #include "../common/linked_list.h" @@ -19,7 +20,7 @@ public: ~Doors(); Doors(const char *model, const glm::vec4& position, uint8 open_type = 58, uint16 size = 100); - Doors(const Door* door); + Doors(const DoorsRepository::Doors& door); bool GetDisableTimer() { return disable_timer; } bool IsDoor() const { return true; } diff --git a/zone/zone.cpp b/zone/zone.cpp index e5b810a1f..a5be7d140 100755 --- a/zone/zone.cpp +++ b/zone/zone.cpp @@ -197,24 +197,27 @@ bool Zone::LoadZoneObjects() if (!shortname) continue; - Door d; - memset(&d, 0, sizeof(d)); + // todo: clean up duplicate code with command_object + auto d = DoorsRepository::NewEntity(); - strn0cpy(d.zone_name, shortname, sizeof(d.zone_name)); - d.db_id = 1000000000 + atoi(row[0]); // Out of range of normal use for doors.id - d.door_id = -1; // Client doesn't care if these are all the same door_id + d.zone = shortname; + d.id = 1000000000 + atoi(row[0]); // Out of range of normal use for doors.id + d.doorid = -1; // Client doesn't care if these are all the same door_id d.pos_x = atof(row[2]); // xpos d.pos_y = atof(row[3]); // ypos d.pos_z = atof(row[4]); // zpos d.heading = atof(row[5]); // heading - strn0cpy(d.door_name, row[8], sizeof(d.door_name)); // objectname - // Strip trailing "_ACTORDEF" if present. Client won't accept it for doors. - int len = strlen(d.door_name); - if ((len > 9) && (memcmp(&d.door_name[len - 9], "_ACTORDEF", 10) == 0)) - d.door_name[len - 9] = '\0'; + d.name = row[8]; // objectname - memcpy(d.dest_zone, "NONE", 5); + // Strip trailing "_ACTORDEF" if present. Client won't accept it for doors. + int pos = d.name.size() - strlen("_ACTORDEF"); + if (pos > 0 && d.name.compare(pos, std::string::npos, "_ACTORDEF") == 0) + { + d.name.erase(pos); + } + + d.dest_zone = "NONE"; if ((d.size = atoi(row[11])) == 0) // unknown08 = optional size percentage d.size = 100; @@ -232,7 +235,7 @@ bool Zone::LoadZoneObjects() d.incline = atoi(row[13]); // unknown20 = optional model incline value d.client_version_mask = 0xFFFFFFFF; // We should load the mask from the zone. - auto door = new Doors(&d); + auto door = new Doors(d); entity_list.AddDoor(door); } @@ -911,29 +914,19 @@ void Zone::LoadZoneDoors(const char* zone, int16 version) { LogInfo("Loading doors for [{}] ", zone); - uint32 maxid; - int32 count = content_db.GetDoorsCount(&maxid, zone, version); - if(count < 1) { + auto door_entries = content_db.LoadDoors(zone, version); + if (door_entries.empty()) + { LogInfo("No doors loaded"); return; } - auto dlist = new Door[count]; - - if(!content_db.LoadDoors(count, dlist, zone, version)) { - LogError("Failed to load doors"); - delete[] dlist; - return; - } - - int r; - Door *d = dlist; - for(r = 0; r < count; r++, d++) { - auto newdoor = new Doors(d); + for (const auto& entry : door_entries) + { + auto newdoor = new Doors(entry); entity_list.AddDoor(newdoor); - Log(Logs::Detail, Logs::Doors, "Door Add to Entity List, index: %u db id: %u, door_id %u", r, dlist[r].db_id, dlist[r].door_id); + LogDoorsDetail("Door added to entity list, db id: [{}], door_id: [{}]", entry.id, entry.doorid); } - delete[] dlist; } Zone::Zone(uint32 in_zoneid, uint32 in_instanceid, const char* in_short_name) diff --git a/zone/zonedb.h b/zone/zonedb.h index 61eb97ae1..03e69c242 100644 --- a/zone/zonedb.h +++ b/zone/zonedb.h @@ -10,6 +10,7 @@ #include "../common/eqemu_logsys.h" #include "aa_ability.h" #include "event_codes.h" +#include "../common/repositories/doors_repository.h" #ifdef BOTS #include "bot_database.h" @@ -526,7 +527,7 @@ public: /* Doors */ bool DoorIsOpen(uint8 door_id,const char* zone_name); void SetDoorPlace(uint8 value,uint8 door_id,const char* zone_name); - bool LoadDoors(int32 door_count, Door *into, const char *zone_name, int16 version); + std::vector LoadDoors(const std::string& zone_name, int16 version); uint32 GetGuildEQID(uint32 guilddbid); void UpdateDoorGuildID(int doorid, int guild_id); int32 GetDoorsCount(uint32* oMaxID, const char *zone_name, int16 version); diff --git a/zone/zonedump.h b/zone/zonedump.h index 09f11b65b..4bbdf47c8 100644 --- a/zone/zonedump.h +++ b/zone/zonedump.h @@ -201,37 +201,6 @@ struct PlayerCorpse_Struct { //std::list items; }; -struct Door { - uint32 db_id; - uint8 door_id; - char zone_name[32]; - char door_name[32]; - float pos_x; - float pos_y; - float pos_z; - float heading; - int incline; - uint8 opentype; - uint32 guild_id; - uint16 lock_pick; - uint32 keyitem; - uint8 nokeyring; - uint8 trigger_door; - uint8 trigger_type; - uint8 disable_timer; - uint32 door_param; - int invert_state; - uint16 size; - char dest_zone[16]; - uint32 dest_instance_id; - float dest_x; - float dest_y; - float dest_z; - float dest_heading; - uint8 is_ldon_door; - uint32 client_version_mask; -}; - #pragma pack() #endif