diff --git a/zone/gm_commands/object_manipulation.cpp b/zone/gm_commands/object_manipulation.cpp index 9f9063298..27214cf27 100644 --- a/zone/gm_commands/object_manipulation.cpp +++ b/zone/gm_commands/object_manipulation.cpp @@ -132,9 +132,22 @@ void ObjectManipulation::CommandHandler(Client *c, const Seperator *sep) ) ); - const bool object_found = l.empty(); + for (const auto& e : l) { + c->Message( + Chat::White, + fmt::format( + "ID: {} Name: {} XYZ: {:.2f}, {:.2f}, {:.2f} Heading: {:.2f}", + e.id, + e.objectname, + e.xpos, + e.ypos, + e.zpos, + e.heading + ).c_str() + ); + } - if (object_found) { + if (!l.empty()) { c->Message(Chat::White, "An object already exists at this location."); return; } @@ -189,66 +202,18 @@ void ObjectManipulation::CommandHandler(Client *c, const Seperator *sep) Object *o = entity_list.GetObjectByID(c->GetObjectToolEntityId()); + if (!o) { + c->Message(Chat::White, "You do not have a valid selected object."); + return; + } + const uint32 object_id = o->GetDBID(); - if (o) { - auto app = new EQApplicationPacket(); - o->CreateDeSpawnPacket(app); - entity_list.QueueClients(nullptr, app); - entity_list.RemoveObject(o->GetID()); - safe_delete(app); - - const int deleted_object = ObjectRepository::DeleteWhere( - content_db, - fmt::format( - "id = {} AND zoneid = {} AND version = {}", - object_id, - zone->GetZoneID(), - zone->GetInstanceVersion() - ) - ); - - if (deleted_object) { - c->Message( - Chat::White, - fmt::format( - "Successfully deleted Object ID {}.", - object_id - ).c_str() - ); - } else { - c->Message( - Chat::White, - fmt::format( - "Failed to delete Object ID {}.", - object_id - ).c_str() - ); - } - - return; - } - - const auto &e = ObjectRepository::GetWhere( - content_db, - fmt::format( - "id = {} AND zoneid = {} AND version = {} LIMIT 1", - object_id, - zone->GetZoneID(), - zone->GetInstanceVersion() - ) - ); - - if (e[0].type == ObjectTypes::Temporary) { - c->Message( - Chat::White, - fmt::format( - "Object ID {} is a temporarily spawned ground spawn or dropped item, which is not supported with #object. See the 'ground_spawns' table in the database.", - object_id - ).c_str() - ); - return; - } + auto app = new EQApplicationPacket(); + o->CreateDeSpawnPacket(app); + entity_list.QueueClients(nullptr, app); + entity_list.RemoveObject(o->GetID()); + safe_delete(app); const int deleted_object = ObjectRepository::DeleteWhere( content_db, diff --git a/zone/object.cpp b/zone/object.cpp index ef0a24ec5..31120e765 100644 --- a/zone/object.cpp +++ b/zone/object.cpp @@ -30,6 +30,7 @@ #include "../common/repositories/criteria/content_filter_criteria.h" #include "../common/events/player_event_logs.h" #include "../common/repositories/ground_spawns_repository.h" +#include "../common/repositories/object_repository.h" const char DEFAULT_OBJECT_NAME[] = "IT63_ACTORDEF"; @@ -669,50 +670,57 @@ bool Object::HandleClick(Client* sender, const ClickObject_Struct* click_object) return true; } -// Add new Zone Object (theoretically only called for items dropped to ground) -uint32 ZoneDatabase::AddObject(uint32 type, uint32 icon, const Object_Struct& object, const EQ::ItemInstance* inst) +uint32 ZoneDatabase::AddObject( + uint32 type, + uint32 icon, + const Object_Struct& o, + const EQ::ItemInstance* inst +) { - uint32 database_id = 0; uint32 item_id = 0; - int16 charges = 0; + int16 charges = 0; if (inst && inst->GetItem()) { item_id = inst->GetItem()->ID; charges = inst->GetCharges(); } - // SQL Escape object_name - uint32 len = strlen(object.object_name) * 2 + 1; - auto object_name = new char[len]; - DoEscapeString(object_name, object.object_name, strlen(object.object_name)); + auto e = ObjectRepository::NewEntity(); - // Save new record for object - std::string query = StringFormat("INSERT INTO object " - "(zoneid, xpos, ypos, zpos, heading, " - "itemid, charges, objectname, type, icon) " - "values (%i, %f, %f, %f, %f, %i, %i, '%s', %i, %i)", - object.zone_id, object.x, object.y, object.z, object.heading, - item_id, charges, object_name, type, icon); - safe_delete_array(object_name); - auto results = QueryDatabase(query); - if (!results.Success()) { - LogError("Unable to insert object: [{}]", results.ErrorMessage().c_str()); + e.zoneid = o.zone_id; + e.xpos = o.x; + e.ypos = o.y; + e.zpos = o.z; + e.heading = o.heading; + e.itemid = item_id; + e.charges = charges; + e.objectname = o.object_name; + e.type = type; + e.icon = icon; + + e = ObjectRepository::InsertOne(*this, e); + + if (!e.id) { return 0; } - // Save container contents, if container if (inst && inst->IsType(EQ::item::ItemClassBag)) { - SaveWorldContainer(object.zone_id, database_id, inst); + SaveWorldContainer(o.zone_id, e.id, inst); } - return database_id; + return e.id; } -// Update information about existing object in database -void ZoneDatabase::UpdateObject(uint32 id, uint32 type, uint32 icon, const Object_Struct& object, const EQ::ItemInstance* inst) +void ZoneDatabase::UpdateObject( + uint32 object_id, + uint32 type, + uint32 icon, + const Object_Struct& o, + const EQ::ItemInstance* inst +) { uint32 item_id = 0; - int16 charges = 0; + int16 charges = 0; if (inst && inst->GetItem()) { item_id = inst->GetItem()->ID; @@ -720,32 +728,31 @@ void ZoneDatabase::UpdateObject(uint32 id, uint32 type, uint32 icon, const Objec } if (inst && !inst->IsType(EQ::item::ItemClassBag)) { - uint32 len = strlen(object.object_name) * 2 + 1; - auto object_name = new char[len]; - DoEscapeString(object_name, object.object_name, strlen(object.object_name)); + auto e = ObjectRepository::FindOne(*this, object_id); - // Save new record for object - std::string query = StringFormat( - "UPDATE object SET " - "zoneid = %i, xpos = %f, ypos = %f, zpos = %f, heading = %f, " - "itemid = %i, charges = %i, objectname = '%s', type = %i, icon = %i, " - "size = %f, tilt_x = %f, tilt_y = %f " - "WHERE id = %i", - object.zone_id, object.x, object.y, object.z, object.heading, - item_id, charges, object_name, type, icon, - object.size, object.tilt_x, object.tilt_y, id - ); - safe_delete_array(object_name); - auto results = QueryDatabase(query); - if (!results.Success()) { - LogError("Unable to update object: [{}]", results.ErrorMessage().c_str()); + e.zoneid = o.zone_id; + e.xpos = o.x; + e.ypos = o.y; + e.zpos = o.z; + e.heading = o.heading; + e.itemid = item_id; + e.charges = charges; + e.objectname = o.object_name; + e.type = type; + e.icon = icon; + e.size = o.size; + e.tilt_x = o.tilt_x; + e.tilt_y = o.tilt_y; + + const int updated = ObjectRepository::UpdateOne(*this, e); + + if (!updated) { return; } } - // Save container contents, if container if (inst && inst->IsType(EQ::item::ItemClassBag)) { - SaveWorldContainer(object.zone_id, id, inst); + SaveWorldContainer(o.zone_id, object_id, inst); } } @@ -790,17 +797,13 @@ GroundSpawns* ZoneDatabase::LoadGroundSpawns( return gs; } -void ZoneDatabase::DeleteObject(uint32 id) +void ZoneDatabase::DeleteObject(uint32 object_id) { - if (id == 0) { + if (!object_id) { return; } - std::string query = StringFormat("DELETE FROM object WHERE id = %i", id); - auto results = QueryDatabase(query); - if (!results.Success()) { - LogError("Unable to delete object: [{}]", results.ErrorMessage().c_str()); - } + ObjectRepository::DeleteOne(*this, object_id); } uint32 Object::GetDBID() diff --git a/zone/zonedb.h b/zone/zonedb.h index 09487b4b1..9ebd7b9e1 100644 --- a/zone/zonedb.h +++ b/zone/zonedb.h @@ -379,8 +379,8 @@ public: void SaveWorldContainer(uint32 zone_id, uint32 parent_id, const EQ::ItemInstance* container); void DeleteWorldContainer(uint32 parent_id,uint32 zone_id); uint32 AddObject(uint32 type, uint32 icon, const Object_Struct& object, const EQ::ItemInstance* inst); - void UpdateObject(uint32 id, uint32 type, uint32 icon, const Object_Struct& object, const EQ::ItemInstance* inst); - void DeleteObject(uint32 id); + void UpdateObject(uint32 object_id, uint32 type, uint32 icon, const Object_Struct& object, const EQ::ItemInstance* inst); + void DeleteObject(uint32 object_id); GroundSpawns* LoadGroundSpawns(uint32 zone_id, int16 instance_version, GroundSpawns* gs); /* Traders */