From 4de9b2c53e56f59941d2cceec2153d14e06ee714 Mon Sep 17 00:00:00 2001 From: Natedog2012 Date: Fri, 26 Aug 2016 06:34:51 -0700 Subject: [PATCH] Add TiltX and TiltY manipulation to objects (Perl) Translate OP_GroundSpawn for Titanium #perl plugin http://wiki.eqemulator.org/i?Module=Pastebin&Paste=u9IbA6Ql --- common/eq_packet_structs.h | 24 ++-- common/patches/rof.cpp | 4 +- common/patches/rof2.cpp | 4 +- common/patches/titanium.cpp | 40 +++++++ common/patches/titanium_ops.h | 1 + common/patches/uf.cpp | 4 +- common/version.h | 2 +- utils/sql/db_update_manifest.txt | 1 + .../required/2016_08_26_object_size_tilt.sql | 4 + zone/object.cpp | 51 +++++++- zone/object.h | 8 +- zone/perl_object.cpp | 110 +++++++++++++++++- zone/zone.cpp | 8 +- 13 files changed, 232 insertions(+), 29 deletions(-) create mode 100644 utils/sql/git/required/2016_08_26_object_size_tilt.sql diff --git a/common/eq_packet_structs.h b/common/eq_packet_structs.h index a1b614b97..cf411ef72 100644 --- a/common/eq_packet_structs.h +++ b/common/eq_packet_structs.h @@ -2509,23 +2509,25 @@ struct BookRequest_Struct { */ struct Object_Struct { /*00*/ uint32 linked_list_addr[2];// They are, get this, prev and next, ala linked list -/*08*/ uint16 size; // +/*08*/ float size; // /*10*/ uint16 solidtype; // /*12*/ uint32 drop_id; // Unique object id for zone /*16*/ uint16 zone_id; // Redudant, but: Zone the object appears in /*18*/ uint16 zone_instance; // /*20*/ uint32 unknown020; // /*24*/ uint32 unknown024; // -/*28*/ float heading; // heading -/*32*/ float z; // z coord -/*36*/ float x; // x coord -/*40*/ float y; // y coord -/*44*/ char object_name[32]; // Name of object, usually something like IT63_ACTORDEF -/*76*/ uint32 unknown076; // -/*80*/ uint32 object_type; // Type of object, not directly translated to OP_OpenObject -/*84*/ uint32 unknown084; //set to 0xFF -/*88*/ uint32 spawn_id; // Spawn Id of client interacting with object -/*92*/ +/*28*/ float tilt_x; +/*32*/ float tilt_y; +/*36*/ float heading; // heading +/*40*/ float z; // z coord +/*44*/ float x; // x coord +/*76*/ float y; // y coord +/*80*/ char object_name[32]; // Name of object, usually something like IT63_ACTORDEF +/*84*/ uint32 unknown076; // +/*88*/ uint32 object_type; // Type of object, not directly translated to OP_OpenObject +/*92*/ uint32 unknown084; //set to 0xFF + uint32 spawn_id; // Spawn Id of client interacting with object + }; // 01 = generic drop, 02 = armor, 19 = weapon //[13:40] and 0xff seems to be indicative of the tradeskill/openable items that end up returning the old style item type in the OP_OpenObject diff --git a/common/patches/rof.cpp b/common/patches/rof.cpp index 7c5f302cb..8ab38905f 100644 --- a/common/patches/rof.cpp +++ b/common/patches/rof.cpp @@ -987,8 +987,8 @@ namespace RoF VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->drop_id); // Some unique id VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0); // Same for all objects in the zone VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->heading); - VARSTRUCT_ENCODE_TYPE(float, OutBuffer, 0); // X tilt - VARSTRUCT_ENCODE_TYPE(float, OutBuffer, 0); // Y tilt + VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->tilt_x); // X tilt + VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->tilt_y); // Y tilt VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->size != 0 && (float)emu->size < 5000.f ? (float)((float)emu->size / 100.0f) : 1.f ); // This appears to be the size field. Hackish logic because some PEQ DB items were corrupt. VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->y); VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->x); diff --git a/common/patches/rof2.cpp b/common/patches/rof2.cpp index 5bb93f14a..aedd7b592 100644 --- a/common/patches/rof2.cpp +++ b/common/patches/rof2.cpp @@ -1062,8 +1062,8 @@ namespace RoF2 VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->drop_id); // Some unique id VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0); // Same for all objects in the zone VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->heading); - VARSTRUCT_ENCODE_TYPE(float, OutBuffer, 0); // X tilt - VARSTRUCT_ENCODE_TYPE(float, OutBuffer, 0); // Y tilt + VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->tilt_x); // X tilt + VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->tilt_y); // Y tilt VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->size != 0 && (float)emu->size < 5000.f ? (float)((float)emu->size / 100.0f) : 1.f ); // This appears to be the size field. Hackish logic because some PEQ DB items were corrupt. VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->y); VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->x); diff --git a/common/patches/titanium.cpp b/common/patches/titanium.cpp index cc10f6487..9e93051b1 100644 --- a/common/patches/titanium.cpp +++ b/common/patches/titanium.cpp @@ -595,6 +595,46 @@ namespace Titanium dest->FastQueuePacket(&in, ack_req); } + ENCODE(OP_GroundSpawn) + { + // We are not encoding the spawn_id field here, but it doesn't appear to matter. + // + EQApplicationPacket *in = *p; + *p = nullptr; + + //store away the emu struct + unsigned char *__emu_buffer = in->pBuffer; + Object_Struct *emu = (Object_Struct *)__emu_buffer; + + in->size = strlen(emu->object_name) + sizeof(structs::Object_Struct) - 1; + in->pBuffer = new unsigned char[in->size]; + + structs::Object_Struct *eq = (structs::Object_Struct *) in->pBuffer; + + eq->drop_id = emu->drop_id; + eq->heading = emu->heading; + eq->linked_list_addr[0] = 0; + eq->linked_list_addr[1] = 0; + strcpy(eq->object_name, emu->object_name); + eq->object_type = emu->object_type; + eq->spawn_id = 0; + eq->unknown008[0] = 0; + eq->unknown008[1] = 0; + eq->unknown020 = 0; + eq->unknown024 = 0; + eq->unknown076 = 0; + eq->unknown084 = 0xffffffff; + eq->z = emu->z; + eq->x = emu->x; + eq->y = emu->y; + eq->zone_id = emu->zone_id; + eq->zone_instance = emu->zone_instance; + + + delete[] __emu_buffer; + dest->FastQueuePacket(&in, ack_req); + } + ENCODE(OP_GuildMemberList) { //consume the packet diff --git a/common/patches/titanium_ops.h b/common/patches/titanium_ops.h index 9ca0ba770..5e65dd7c0 100644 --- a/common/patches/titanium_ops.h +++ b/common/patches/titanium_ops.h @@ -40,6 +40,7 @@ E(OP_DzLeaderStatus) E(OP_DzMemberList) E(OP_Emote) E(OP_FormattedMessage) +E(OP_GroundSpawn) E(OP_GuildMemberLevelUpdate) E(OP_GuildMemberList) E(OP_Illusion) diff --git a/common/patches/uf.cpp b/common/patches/uf.cpp index af81fea06..ba5bf7622 100644 --- a/common/patches/uf.cpp +++ b/common/patches/uf.cpp @@ -875,8 +875,8 @@ namespace UF // This next field is actually a float. There is a groundspawn in freeportwest (sack of money sitting on some barrels) which requires this // field to be set to (float)255.0 to appear at all, and also the size field below to be 5, to be the correct size. I think SoD has the same // issue. - VARSTRUCT_ENCODE_TYPE(float, OutBuffer, 0); //X tilt - VARSTRUCT_ENCODE_TYPE(float, OutBuffer, 0); //Y tilt + VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->tilt_x); //X tilt + VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->tilt_y); //Y tilt VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->size != 0 && (float)emu->size < 5000.f ? (float)((float)emu->size / 100.0f) : 1.f ); // This appears to be the size field. Hackish logic because some PEQ DB items were corrupt. VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->y); VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->x); diff --git a/common/version.h b/common/version.h index 38731b3ba..f06a68c05 100644 --- a/common/version.h +++ b/common/version.h @@ -30,7 +30,7 @@ Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt */ -#define CURRENT_BINARY_DATABASE_VERSION 9097 +#define CURRENT_BINARY_DATABASE_VERSION 9098 #ifdef BOTS #define CURRENT_BINARY_BOTS_DATABASE_VERSION 9008 #else diff --git a/utils/sql/db_update_manifest.txt b/utils/sql/db_update_manifest.txt index 283500c3b..4030395c3 100644 --- a/utils/sql/db_update_manifest.txt +++ b/utils/sql/db_update_manifest.txt @@ -351,6 +351,7 @@ 9095|2016_01_08_command_find_aliases.sql|SELECT * FROM `command_settings` WHERE `command` LIKE 'findaliases'|empty| 9096|2016_03_05_secondary_recall.sql|SHOW COLUMNS FROM `character_bind` LIKE 'slot'|empty| 9097|2016_07_03_npc_class_as_last_name.sql|SELECT `rule_name` FROM `rule_values` WHERE `rule_name` LIKE 'NPC:UseClassAsLastName'|empty| +9098|2016_08_26_object_size_tilt.sql|SHOW COLUMNS FROM `object` LIKE 'size'|empty| # Upgrade conditions: # This won't be needed after this system is implemented, but it is used database that are not diff --git a/utils/sql/git/required/2016_08_26_object_size_tilt.sql b/utils/sql/git/required/2016_08_26_object_size_tilt.sql new file mode 100644 index 000000000..ded4d841d --- /dev/null +++ b/utils/sql/git/required/2016_08_26_object_size_tilt.sql @@ -0,0 +1,4 @@ +ALTER TABLE `object` + ADD COLUMN `size` FLOAT NOT NULL DEFAULT '100' AFTER `unknown84`, + ADD COLUMN `tilt_x` FLOAT NOT NULL DEFAULT '0' AFTER `size`, + ADD COLUMN `tilt_y` FLOAT NOT NULL DEFAULT '0' AFTER `tilt_x`; \ No newline at end of file diff --git a/zone/object.cpp b/zone/object.cpp index f74d2dd0d..a9672ee4f 100644 --- a/zone/object.cpp +++ b/zone/object.cpp @@ -63,6 +63,9 @@ Object::Object(uint32 id, uint32 type, uint32 icon, const Object_Struct& object, // Set drop_id to zero - it will be set when added to zone with SetID() m_data.drop_id = 0; + m_data.size = object.size; + m_data.tilt_x = object.tilt_x; + m_data.tilt_y = object.tilt_y; } //creating a re-ocurring ground spawn. @@ -653,10 +656,12 @@ void ZoneDatabase::UpdateObject(uint32 id, uint32 type, uint32 icon, const Objec // 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 " + "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, id); + 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()) { @@ -750,6 +755,16 @@ float Object::GetHeadingData() return this->m_data.heading; } +float Object::GetTiltX() +{ + return this->m_data.tilt_x; +} + +float Object::GetTiltY() +{ + return this->m_data.tilt_y; +} + void Object::SetX(float pos) { this->m_data.x = pos; @@ -778,6 +793,34 @@ void Object::SetY(float pos) safe_delete(app2); } +void Object::SetTiltX(float pos) +{ + this->m_data.tilt_x = pos; + + auto app = new EQApplicationPacket(); + auto app2 = new EQApplicationPacket(); + this->CreateDeSpawnPacket(app); + this->CreateSpawnPacket(app2); + entity_list.QueueClients(0, app); + entity_list.QueueClients(0, app2); + safe_delete(app); + safe_delete(app2); +} + +void Object::SetTiltY(float pos) +{ + this->m_data.tilt_y = pos; + + auto app = new EQApplicationPacket(); + auto app2 = new EQApplicationPacket(); + this->CreateDeSpawnPacket(app); + this->CreateSpawnPacket(app2); + entity_list.QueueClients(0, app); + entity_list.QueueClients(0, app2); + safe_delete(app); + safe_delete(app2); +} + void Object::Depop() { auto app = new EQApplicationPacket(); @@ -828,7 +871,7 @@ void Object::SetModelName(const char* modelname) safe_delete(app2); } -void Object::SetSize(uint16 size) +void Object::SetSize(float size) { m_data.size = size; auto app = new EQApplicationPacket(); @@ -854,7 +897,7 @@ void Object::SetSolidType(uint16 solidtype) safe_delete(app2); } -uint16 Object::GetSize() +float Object::GetSize() { return m_data.size; } diff --git a/zone/object.h b/zone/object.h index c7ebdd677..896fc4276 100644 --- a/zone/object.h +++ b/zone/object.h @@ -154,10 +154,14 @@ public: void SetX(float pos); void SetY(float pos); void SetZ(float pos); + void SetTiltX(float pos); + void SetTiltY(float pos); + float GetTiltX(); + float GetTiltY(); void SetModelName(const char* modelname); const char* GetModelName(); - uint16 GetSize(); - void SetSize(uint16 size); + float GetSize(); + void SetSize(float size); uint16 GetSolidType(); void SetSolidType(uint16 size); diff --git a/zone/perl_object.cpp b/zone/perl_object.cpp index be52fef1d..f8fc9a4ee 100644 --- a/zone/perl_object.cpp +++ b/zone/perl_object.cpp @@ -968,7 +968,7 @@ XS(XS_Object_GetSize) Perl_croak(aTHX_ "Usage: Object::GetSize(THIS)"); { Object * THIS; - uint16 RETVAL; + float RETVAL; dXSTARG; if (sv_derived_from(ST(0), "Object")) { @@ -981,7 +981,7 @@ XS(XS_Object_GetSize) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); RETVAL = THIS->GetSize(); - XSprePUSH; PUSHu((UV)RETVAL); + XSprePUSH; PUSHn((double)RETVAL); } XSRETURN(1); } @@ -995,7 +995,7 @@ XS(XS_Object_SetSize) Perl_croak(aTHX_ "Usage: Object::SetSize(THIS, type)"); { Object * THIS; - uint16 size = (uint16)SvUV(ST(1)); + float size = (float)SvNV(ST(1)); if (sv_derived_from(ST(0), "Object")) { IV tmp = SvIV((SV*)SvRV(ST(0))); @@ -1011,6 +1011,106 @@ XS(XS_Object_SetSize) XSRETURN_EMPTY; } +XS(XS_Object_SetTiltX); /* prototype to pass -Wmissing-prototypes */ +XS(XS_Object_SetTiltX) +{ + dXSARGS; + if (items != 2) + Perl_croak(aTHX_ "Usage: Object::SetTiltX(THIS, pos)"); + { + Object * THIS; + float pos = (float)SvNV(ST(1)); + + if (sv_derived_from(ST(0), "Object")) { + IV tmp = SvIV((SV*)SvRV(ST(0))); + THIS = INT2PTR(Object *,tmp); + } + else + Perl_croak(aTHX_ "THIS is not of type Object"); + if(THIS == nullptr) + Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); + + THIS->SetTiltX(pos); + } + XSRETURN_EMPTY; +} + +XS(XS_Object_SetTiltY); /* prototype to pass -Wmissing-prototypes */ +XS(XS_Object_SetTiltY) +{ + dXSARGS; + if (items != 2) + Perl_croak(aTHX_ "Usage: Object::SetTiltY(THIS, pos)"); + { + Object * THIS; + float pos = (float)SvNV(ST(1)); + + if (sv_derived_from(ST(0), "Object")) { + IV tmp = SvIV((SV*)SvRV(ST(0))); + THIS = INT2PTR(Object *,tmp); + } + else + Perl_croak(aTHX_ "THIS is not of type Object"); + if(THIS == nullptr) + Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); + + THIS->SetTiltY(pos); + } + XSRETURN_EMPTY; +} + +XS(XS_Object_GetTiltX); /* prototype to pass -Wmissing-prototypes */ +XS(XS_Object_GetTiltX) +{ + dXSARGS; + if (items != 1) + Perl_croak(aTHX_ "Usage: Object::GetSize(THIS)"); + { + Object * THIS; + float RETVAL; + dXSTARG; + + if (sv_derived_from(ST(0), "Object")) { + IV tmp = SvIV((SV*)SvRV(ST(0))); + THIS = INT2PTR(Object *,tmp); + } + else + Perl_croak(aTHX_ "THIS is not of type Object"); + if(THIS == nullptr) + Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); + + RETVAL = THIS->GetTiltX(); + XSprePUSH; PUSHn((double)RETVAL); + } + XSRETURN(1); +} + +XS(XS_Object_GetTiltY); /* prototype to pass -Wmissing-prototypes */ +XS(XS_Object_GetTiltY) +{ + dXSARGS; + if (items != 1) + Perl_croak(aTHX_ "Usage: Object::GetSize(THIS)"); + { + Object * THIS; + float RETVAL; + dXSTARG; + + if (sv_derived_from(ST(0), "Object")) { + IV tmp = SvIV((SV*)SvRV(ST(0))); + THIS = INT2PTR(Object *,tmp); + } + else + Perl_croak(aTHX_ "THIS is not of type Object"); + if(THIS == nullptr) + Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); + + RETVAL = THIS->GetTiltY(); + XSprePUSH; PUSHn((double)RETVAL); + } + XSRETURN(1); +} + #ifdef __cplusplus extern "C" #endif @@ -1066,6 +1166,10 @@ XS(boot_Object) newXSproto(strcpy(buf, "GetSolidType"),XS_Object_GetSolidType, file, "$"); newXSproto(strcpy(buf, "SetSize"),XS_Object_SetSize, file, "$$"); newXSproto(strcpy(buf, "GetSize"),XS_Object_GetSize, file, "$"); + newXSproto(strcpy(buf, "SetTiltX"),XS_Object_SetTiltX, file, "$$"); + newXSproto(strcpy(buf, "SetTiltY"),XS_Object_SetTiltY, file, "$"); + newXSproto(strcpy(buf, "GetTiltX"),XS_Object_GetTiltX, file, "$$"); + newXSproto(strcpy(buf, "GetTiltY"),XS_Object_GetTiltY, file, "$"); XSRETURN_YES; } #endif //EMBPERL_XS_CLASSES diff --git a/zone/zone.cpp b/zone/zone.cpp index 1165d7e9b..3dd8e55d8 100644 --- a/zone/zone.cpp +++ b/zone/zone.cpp @@ -161,7 +161,8 @@ bool Zone::LoadZoneObjects() { std::string query = StringFormat("SELECT id, zoneid, xpos, ypos, zpos, heading, " "itemid, charges, objectname, type, icon, unknown08, " - "unknown10, unknown20, unknown24, unknown76 fROM object " + "unknown10, unknown20, unknown24, unknown76, size, tilt_x, " + "tilt_y FROM object " "WHERE zoneid = %i AND (version = %u OR version = -1)", zoneid, instanceversion); auto results = database.QueryDatabase(query); @@ -241,11 +242,14 @@ bool Zone::LoadZoneObjects() { data.object_type = type; data.linked_list_addr[0] = 0; data.linked_list_addr[1] = 0; - data.size = (uint32)atoi(row[11]); + data.solidtype = (uint32)atoi(row[12]); data.unknown020 = (uint32)atoi(row[13]); data.unknown024 = (uint32)atoi(row[14]); data.unknown076 = (uint32)atoi(row[15]); + data.size = atof(row[16]); + data.tilt_x = atof(row[17]); + data.tilt_y = atof(row[18]); data.unknown084 = 0; ItemInst* inst = nullptr;