From d2002538c67ad8864c4844e745139f11440b3e59 Mon Sep 17 00:00:00 2001 From: Bemvaras <169070864+Barathos@users.noreply.github.com> Date: Tue, 17 Jun 2025 15:14:46 -0600 Subject: [PATCH] Add target_version to zone_points --- common/database/database_update_manifest.cpp | 29 ++-- .../base/base_zone_points_repository.h | 146 ++++++++++-------- .../2025_06_01_zonepoints_target_version.sql | 1 + zone/client.cpp | 41 +++-- zone/client.h | 3 +- zone/zone.cpp | 24 +-- zone/zone.h | 5 +- zone/zoning.cpp | 34 ++-- 8 files changed, 166 insertions(+), 117 deletions(-) create mode 100644 utils/sql/git/required/2025_06_01_zonepoints_target_version.sql diff --git a/common/database/database_update_manifest.cpp b/common/database/database_update_manifest.cpp index 1b2f7bc61b..8ac6fae3a2 100644 --- a/common/database/database_update_manifest.cpp +++ b/common/database/database_update_manifest.cpp @@ -7099,19 +7099,30 @@ ALTER TABLE `npc_types` )", .content_schema_update = true }, - ManifestEntry{ - .version = 9323, - .description = "2025_04_16_character_data_first_login.sql", - .check = "SHOW COLUMNS FROM `character_data` LIKE 'first_login'", - .condition = "empty", - .match = "", - .sql = R"( + ManifestEntry{ + .version = 9323, + .description = "2025_04_16_character_data_first_login.sql", + .check = "SHOW COLUMNS FROM `character_data` LIKE 'first_login'", + .condition = "empty", + .match = "", + .sql = R"( ALTER TABLE `character_data` CHANGE COLUMN `firstlogon` `ingame` tinyint(1) UNSIGNED NOT NULL DEFAULT 0 AFTER `xtargets`, ADD COLUMN `first_login` int(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `xtargets`; )", - .content_schema_update = false - }, + .content_schema_update = false + }, + ManifestEntry{ + .version = 9324, + .description = "2025_06_01_zonepoints_target_version.sql", + .check = "SHOW COLUMNS FROM `zone_points` LIKE 'target_version'", + .condition = "empty", + .match = "", + .sql = R"( +ALTER TABLE `zone_points` ADD COLUMN `target_version` INT NOT NULL DEFAULT 0 AFTER `target_zone_id`; +)", + .content_schema_update = false + }, // -- template; copy/paste this when you need to create a new entry // ManifestEntry{ // .version = 9228, diff --git a/common/repositories/base/base_zone_points_repository.h b/common/repositories/base/base_zone_points_repository.h index b4e91c20de..5045aef85e 100644 --- a/common/repositories/base/base_zone_points_repository.h +++ b/common/repositories/base/base_zone_points_repository.h @@ -32,8 +32,9 @@ class BaseZonePointsRepository { float target_z; float target_heading; uint16_t zoneinst; - uint32_t target_zone_id; - uint32_t target_instance; + uint32_t target_zone_id; + int32_t target_version; + uint32_t target_instance; float buffer; uint32_t client_version_mask; int8_t min_expansion; @@ -65,9 +66,10 @@ class BaseZonePointsRepository { "target_x", "target_z", "target_heading", - "zoneinst", - "target_zone_id", - "target_instance", + "zoneinst", + "target_zone_id", + "target_version", + "target_instance", "buffer", "client_version_mask", "min_expansion", @@ -95,9 +97,10 @@ class BaseZonePointsRepository { "target_x", "target_z", "target_heading", - "zoneinst", - "target_zone_id", - "target_instance", + "zoneinst", + "target_zone_id", + "target_version", + "target_instance", "buffer", "client_version_mask", "min_expansion", @@ -160,8 +163,9 @@ class BaseZonePointsRepository { e.target_z = 0; e.target_heading = 0; e.zoneinst = 0; - e.target_zone_id = 0; - e.target_instance = 0; + e.target_zone_id = 0; + e.target_version = 0; + e.target_instance = 0; e.buffer = 0; e.client_version_mask = 4294967295; e.min_expansion = -1; @@ -220,17 +224,18 @@ class BaseZonePointsRepository { e.target_z = row[10] ? strtof(row[10], nullptr) : 0; e.target_heading = row[11] ? strtof(row[11], nullptr) : 0; e.zoneinst = row[12] ? static_cast(strtoul(row[12], nullptr, 10)) : 0; - e.target_zone_id = row[13] ? static_cast(strtoul(row[13], nullptr, 10)) : 0; - e.target_instance = row[14] ? static_cast(strtoul(row[14], nullptr, 10)) : 0; - e.buffer = row[15] ? strtof(row[15], nullptr) : 0; - e.client_version_mask = row[16] ? static_cast(strtoul(row[16], nullptr, 10)) : 4294967295; - e.min_expansion = row[17] ? static_cast(atoi(row[17])) : -1; - e.max_expansion = row[18] ? static_cast(atoi(row[18])) : -1; - e.content_flags = row[19] ? row[19] : ""; - e.content_flags_disabled = row[20] ? row[20] : ""; - e.is_virtual = row[21] ? static_cast(atoi(row[21])) : 0; - e.height = row[22] ? static_cast(atoi(row[22])) : 0; - e.width = row[23] ? static_cast(atoi(row[23])) : 0; + e.target_zone_id = row[13] ? static_cast(strtoul(row[13], nullptr, 10)) : 0; + e.target_version = row[14] ? static_cast(atoi(row[14])) : 0; + e.target_instance = row[15] ? static_cast(strtoul(row[15], nullptr, 10)) : 0; + e.buffer = row[16] ? strtof(row[16], nullptr) : 0; + e.client_version_mask = row[17] ? static_cast(strtoul(row[17], nullptr, 10)) : 4294967295; + e.min_expansion = row[18] ? static_cast(atoi(row[18])) : -1; + e.max_expansion = row[19] ? static_cast(atoi(row[19])) : -1; + e.content_flags = row[20] ? row[20] : ""; + e.content_flags_disabled = row[21] ? row[21] : ""; + e.is_virtual = row[22] ? static_cast(atoi(row[22])) : 0; + e.height = row[23] ? static_cast(atoi(row[23])) : 0; + e.width = row[24] ? static_cast(atoi(row[24])) : 0; return e; } @@ -275,18 +280,19 @@ class BaseZonePointsRepository { v.push_back(columns[9] + " = " + std::to_string(e.target_x)); v.push_back(columns[10] + " = " + std::to_string(e.target_z)); v.push_back(columns[11] + " = " + std::to_string(e.target_heading)); - v.push_back(columns[12] + " = " + std::to_string(e.zoneinst)); - v.push_back(columns[13] + " = " + std::to_string(e.target_zone_id)); - v.push_back(columns[14] + " = " + std::to_string(e.target_instance)); - v.push_back(columns[15] + " = " + std::to_string(e.buffer)); - v.push_back(columns[16] + " = " + std::to_string(e.client_version_mask)); - v.push_back(columns[17] + " = " + std::to_string(e.min_expansion)); - v.push_back(columns[18] + " = " + std::to_string(e.max_expansion)); - v.push_back(columns[19] + " = '" + Strings::Escape(e.content_flags) + "'"); - v.push_back(columns[20] + " = '" + Strings::Escape(e.content_flags_disabled) + "'"); - v.push_back(columns[21] + " = " + std::to_string(e.is_virtual)); - v.push_back(columns[22] + " = " + std::to_string(e.height)); - v.push_back(columns[23] + " = " + std::to_string(e.width)); + v.push_back(columns[12] + " = " + std::to_string(e.zoneinst)); + v.push_back(columns[13] + " = " + std::to_string(e.target_zone_id)); + v.push_back(columns[14] + " = " + std::to_string(e.target_version)); + v.push_back(columns[15] + " = " + std::to_string(e.target_instance)); + v.push_back(columns[16] + " = " + std::to_string(e.buffer)); + v.push_back(columns[17] + " = " + std::to_string(e.client_version_mask)); + v.push_back(columns[18] + " = " + std::to_string(e.min_expansion)); + v.push_back(columns[19] + " = " + std::to_string(e.max_expansion)); + v.push_back(columns[20] + " = '" + Strings::Escape(e.content_flags) + "'"); + v.push_back(columns[21] + " = '" + Strings::Escape(e.content_flags_disabled) + "'"); + v.push_back(columns[22] + " = " + std::to_string(e.is_virtual)); + v.push_back(columns[23] + " = " + std::to_string(e.height)); + v.push_back(columns[24] + " = " + std::to_string(e.width)); auto results = db.QueryDatabase( fmt::format( @@ -320,9 +326,10 @@ class BaseZonePointsRepository { v.push_back(std::to_string(e.target_x)); v.push_back(std::to_string(e.target_z)); v.push_back(std::to_string(e.target_heading)); - v.push_back(std::to_string(e.zoneinst)); - v.push_back(std::to_string(e.target_zone_id)); - v.push_back(std::to_string(e.target_instance)); + v.push_back(std::to_string(e.zoneinst)); + v.push_back(std::to_string(e.target_zone_id)); + v.push_back(std::to_string(e.target_version)); + v.push_back(std::to_string(e.target_instance)); v.push_back(std::to_string(e.buffer)); v.push_back(std::to_string(e.client_version_mask)); v.push_back(std::to_string(e.min_expansion)); @@ -373,9 +380,10 @@ class BaseZonePointsRepository { v.push_back(std::to_string(e.target_x)); v.push_back(std::to_string(e.target_z)); v.push_back(std::to_string(e.target_heading)); - v.push_back(std::to_string(e.zoneinst)); - v.push_back(std::to_string(e.target_zone_id)); - v.push_back(std::to_string(e.target_instance)); + v.push_back(std::to_string(e.zoneinst)); + v.push_back(std::to_string(e.target_zone_id)); + v.push_back(std::to_string(e.target_version)); + v.push_back(std::to_string(e.target_instance)); v.push_back(std::to_string(e.buffer)); v.push_back(std::to_string(e.client_version_mask)); v.push_back(std::to_string(e.min_expansion)); @@ -431,17 +439,18 @@ class BaseZonePointsRepository { e.target_z = row[10] ? strtof(row[10], nullptr) : 0; e.target_heading = row[11] ? strtof(row[11], nullptr) : 0; e.zoneinst = row[12] ? static_cast(strtoul(row[12], nullptr, 10)) : 0; - e.target_zone_id = row[13] ? static_cast(strtoul(row[13], nullptr, 10)) : 0; - e.target_instance = row[14] ? static_cast(strtoul(row[14], nullptr, 10)) : 0; - e.buffer = row[15] ? strtof(row[15], nullptr) : 0; - e.client_version_mask = row[16] ? static_cast(strtoul(row[16], nullptr, 10)) : 4294967295; - e.min_expansion = row[17] ? static_cast(atoi(row[17])) : -1; - e.max_expansion = row[18] ? static_cast(atoi(row[18])) : -1; - e.content_flags = row[19] ? row[19] : ""; - e.content_flags_disabled = row[20] ? row[20] : ""; - e.is_virtual = row[21] ? static_cast(atoi(row[21])) : 0; - e.height = row[22] ? static_cast(atoi(row[22])) : 0; - e.width = row[23] ? static_cast(atoi(row[23])) : 0; + e.target_zone_id = row[13] ? static_cast(strtoul(row[13], nullptr, 10)) : 0; + e.target_version = row[14] ? static_cast(atoi(row[14])) : 0; + e.target_instance = row[15] ? static_cast(strtoul(row[15], nullptr, 10)) : 0; + e.buffer = row[16] ? strtof(row[16], nullptr) : 0; + e.client_version_mask = row[17] ? static_cast(strtoul(row[17], nullptr, 10)) : 4294967295; + e.min_expansion = row[18] ? static_cast(atoi(row[18])) : -1; + e.max_expansion = row[19] ? static_cast(atoi(row[19])) : -1; + e.content_flags = row[20] ? row[20] : ""; + e.content_flags_disabled = row[21] ? row[21] : ""; + e.is_virtual = row[22] ? static_cast(atoi(row[22])) : 0; + e.height = row[23] ? static_cast(atoi(row[23])) : 0; + e.width = row[24] ? static_cast(atoi(row[24])) : 0; all_entries.push_back(e); } @@ -479,17 +488,18 @@ class BaseZonePointsRepository { e.target_z = row[10] ? strtof(row[10], nullptr) : 0; e.target_heading = row[11] ? strtof(row[11], nullptr) : 0; e.zoneinst = row[12] ? static_cast(strtoul(row[12], nullptr, 10)) : 0; - e.target_zone_id = row[13] ? static_cast(strtoul(row[13], nullptr, 10)) : 0; - e.target_instance = row[14] ? static_cast(strtoul(row[14], nullptr, 10)) : 0; - e.buffer = row[15] ? strtof(row[15], nullptr) : 0; - e.client_version_mask = row[16] ? static_cast(strtoul(row[16], nullptr, 10)) : 4294967295; - e.min_expansion = row[17] ? static_cast(atoi(row[17])) : -1; - e.max_expansion = row[18] ? static_cast(atoi(row[18])) : -1; - e.content_flags = row[19] ? row[19] : ""; - e.content_flags_disabled = row[20] ? row[20] : ""; - e.is_virtual = row[21] ? static_cast(atoi(row[21])) : 0; - e.height = row[22] ? static_cast(atoi(row[22])) : 0; - e.width = row[23] ? static_cast(atoi(row[23])) : 0; + e.target_zone_id = row[13] ? static_cast(strtoul(row[13], nullptr, 10)) : 0; + e.target_version = row[14] ? static_cast(atoi(row[14])) : 0; + e.target_instance = row[15] ? static_cast(strtoul(row[15], nullptr, 10)) : 0; + e.buffer = row[16] ? strtof(row[16], nullptr) : 0; + e.client_version_mask = row[17] ? static_cast(strtoul(row[17], nullptr, 10)) : 4294967295; + e.min_expansion = row[18] ? static_cast(atoi(row[18])) : -1; + e.max_expansion = row[19] ? static_cast(atoi(row[19])) : -1; + e.content_flags = row[20] ? row[20] : ""; + e.content_flags_disabled = row[21] ? row[21] : ""; + e.is_virtual = row[22] ? static_cast(atoi(row[22])) : 0; + e.height = row[23] ? static_cast(atoi(row[23])) : 0; + e.width = row[24] ? static_cast(atoi(row[24])) : 0; all_entries.push_back(e); } @@ -576,9 +586,10 @@ class BaseZonePointsRepository { v.push_back(std::to_string(e.target_x)); v.push_back(std::to_string(e.target_z)); v.push_back(std::to_string(e.target_heading)); - v.push_back(std::to_string(e.zoneinst)); - v.push_back(std::to_string(e.target_zone_id)); - v.push_back(std::to_string(e.target_instance)); + v.push_back(std::to_string(e.zoneinst)); + v.push_back(std::to_string(e.target_zone_id)); + v.push_back(std::to_string(e.target_version)); + v.push_back(std::to_string(e.target_instance)); v.push_back(std::to_string(e.buffer)); v.push_back(std::to_string(e.client_version_mask)); v.push_back(std::to_string(e.min_expansion)); @@ -622,9 +633,10 @@ class BaseZonePointsRepository { v.push_back(std::to_string(e.target_x)); v.push_back(std::to_string(e.target_z)); v.push_back(std::to_string(e.target_heading)); - v.push_back(std::to_string(e.zoneinst)); - v.push_back(std::to_string(e.target_zone_id)); - v.push_back(std::to_string(e.target_instance)); + v.push_back(std::to_string(e.zoneinst)); + v.push_back(std::to_string(e.target_zone_id)); + v.push_back(std::to_string(e.target_version)); + v.push_back(std::to_string(e.target_instance)); v.push_back(std::to_string(e.buffer)); v.push_back(std::to_string(e.client_version_mask)); v.push_back(std::to_string(e.min_expansion)); diff --git a/utils/sql/git/required/2025_06_01_zonepoints_target_version.sql b/utils/sql/git/required/2025_06_01_zonepoints_target_version.sql new file mode 100644 index 0000000000..79ae9614d5 --- /dev/null +++ b/utils/sql/git/required/2025_06_01_zonepoints_target_version.sql @@ -0,0 +1 @@ +ALTER TABLE zone_points ADD COLUMN target_version INT NOT NULL DEFAULT 0 AFTER target_zone_id; diff --git a/zone/client.cpp b/zone/client.cpp index 4b18ab6b87..ca4b092cc4 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -6988,12 +6988,14 @@ void Client::SendZonePoints() // if we don't use the same instance_id that the client was sent, the client will forcefully // issue a zone change request when they should be simply moving to a different point in the same zone // because the client will think the zone point target is different from the current instance - auto target_instance = data->target_zone_instance; - if (data->target_zone_id == zone->GetZoneID() && data->target_zone_instance == 0) { - target_instance = zone->GetInstanceID(); - } - - zp->zpe[i].zoneinstance = target_instance; + auto target_instance = data->target_zone_instance; + if (data->target_zone_id == zone->GetZoneID() && data->target_zone_instance == 0 && data->target_version == 0) { + target_instance = zone->GetInstanceID(); + } else if (data->target_zone_instance == 0 && data->target_version != 0) { + target_instance = data->target_version; + } + + zp->zpe[i].zoneinstance = target_instance; i++; } iterator.Advance(); @@ -9872,14 +9874,25 @@ void Client::CheckVirtualZoneLines() GetZ() < (virtual_zone_point.z + (float) virtual_zone_point.height) ) { - MovePC( - virtual_zone_point.target_zone_id, - virtual_zone_point.target_instance, - virtual_zone_point.target_x, - virtual_zone_point.target_y, - virtual_zone_point.target_z, - virtual_zone_point.target_heading - ); + if (virtual_zone_point.target_instance == 0 && virtual_zone_point.target_version != 0) { + MovePC( + virtual_zone_point.target_zone_id, + virtual_zone_point.target_version, + virtual_zone_point.target_x, + virtual_zone_point.target_y, + virtual_zone_point.target_z, + virtual_zone_point.target_heading + ); + } else { + MovePC( + virtual_zone_point.target_zone_id, + virtual_zone_point.target_instance, + virtual_zone_point.target_x, + virtual_zone_point.target_y, + virtual_zone_point.target_z, + virtual_zone_point.target_heading + ); + } LogZonePoints( "Virtual Zone Box Sending player [{}] to [{}]", diff --git a/zone/client.h b/zone/client.h index 9f96ba235d..3ff1eda320 100644 --- a/zone/client.h +++ b/zone/client.h @@ -800,7 +800,8 @@ class Client : public Mob void MovePC(const char* zonename, float x, float y, float z, float heading, uint8 ignorerestrictions = 0, ZoneMode zm = ZoneSolicited); void MovePC(uint32 zoneID, float x, float y, float z, float heading, uint8 ignorerestrictions = 0, ZoneMode zm = ZoneSolicited); void MovePC(float x, float y, float z, float heading, uint8 ignorerestrictions = 0, ZoneMode zm = ZoneSolicited); - void MovePC(uint32 zoneID, uint32 instanceID, float x, float y, float z, float heading, uint8 ignorerestrictions = 0, ZoneMode zm = ZoneSolicited); + void MovePC(uint32 zoneID, uint32 instanceID, float x, float y, float z, float heading, uint8 ignorerestrictions = 0, ZoneMode zm = ZoneSolicited); + void MovePC(uint32 zoneID, int16 version, float x, float y, float z, float heading, uint8 ignorerestrictions = 0, ZoneMode zm = ZoneSolicited); void MoveZone(const char *zone_short_name, const glm::vec4& location = glm::vec4(0.f)); void MoveZoneGroup(const char *zone_short_name, const glm::vec4& location = glm::vec4(0.f)); void MoveZoneRaid(const char *zone_short_name, const glm::vec4& location = glm::vec4(0.f)); diff --git a/zone/zone.cpp b/zone/zone.cpp index 6f00f805e1..7289f149c9 100644 --- a/zone/zone.cpp +++ b/zone/zone.cpp @@ -2151,8 +2151,9 @@ bool ZoneDatabase::LoadStaticZonePoints(LinkedList *zone_point_list zp->target_x = zone_point.target_x; zp->target_y = zone_point.target_y; zp->target_z = zone_point.target_z; - zp->target_zone_id = zone_point.target_zone_id; - zp->heading = zone_point.heading; + zp->target_zone_id = zone_point.target_zone_id; + zp->target_version = zone_point.target_version; + zp->heading = zone_point.heading; zp->target_heading = zone_point.target_heading; zp->number = zone_point.number; zp->target_zone_instance = zone_point.target_instance; @@ -2161,8 +2162,8 @@ bool ZoneDatabase::LoadStaticZonePoints(LinkedList *zone_point_list zp->height = zone_point.height; zp->width = zone_point.width; - LogZonePoints( - "Loading ZP x [{}] y [{}] z [{}] heading [{}] target x y z zone_id instance_id [{}] [{}] [{}] [{}] [{}] number [{}] is_virtual [{}] height [{}] width [{}]", + LogZonePoints( + "Loading ZP x [{}] y [{}] z [{}] heading [{}] target x y z zone_id version instance_id [{}] [{}] [{}] [{}] [{}] [{}] number [{}] is_virtual [{}] height [{}] width [{}]", zp->x, zp->y, zp->z, @@ -2170,13 +2171,14 @@ bool ZoneDatabase::LoadStaticZonePoints(LinkedList *zone_point_list zp->target_x, zp->target_y, zp->target_z, - zp->target_zone_id, - zp->target_zone_instance, - zp->number, - zp->is_virtual ? "true" : "false", - zp->height, - zp->width - ); + zp->target_zone_id, + zp->target_version, + zp->target_zone_instance, + zp->number, + zp->is_virtual ? "true" : "false", + zp->height, + zp->width + ); if (zone_point.is_virtual) { zone->virtual_zone_point_list.emplace_back(zone_point); diff --git a/zone/zone.h b/zone/zone.h index 29a2980fd3..07c25f8351 100755 --- a/zone/zone.h +++ b/zone/zone.h @@ -69,8 +69,9 @@ struct ZonePoint { float target_y; float target_z; float target_heading; - uint16 target_zone_id; - int32 target_zone_instance; + uint16 target_zone_id; + int16 target_version; + int32 target_zone_instance; uint32 client_version_mask; bool is_virtual; int height; diff --git a/zone/zoning.cpp b/zone/zoning.cpp index 1f84ff6e36..ee7c394af6 100644 --- a/zone/zoning.cpp +++ b/zone/zoning.cpp @@ -74,9 +74,10 @@ void Client::Handle_OP_ZoneChange(const EQApplicationPacket *app) { content_service.HandleZoneRoutingMiddleware(zc); - uint16 target_zone_id = 0; - auto target_instance_id = zc->instanceID; - ZonePoint* zone_point = nullptr; + uint16 target_zone_id = 0; + auto target_instance_id = zc->instanceID; + int16 target_version = 0; + ZonePoint* zone_point = nullptr; //figure out where they are going. if (zc->zoneID == 0) { @@ -102,11 +103,12 @@ void Client::Handle_OP_ZoneChange(const EQApplicationPacket *app) { break; case ZoneUnsolicited: //client came up with this on its own. zone_point = zone->GetClosestZonePointWithoutZone(GetX(), GetY(), GetZ(), this, ZONEPOINT_NOZONE_RANGE); - if (zone_point) { - //we found a zone point, which is a reasonable distance away - //assume that is the one were going with. - target_zone_id = zone_point->target_zone_id; - target_instance_id = zone_point->target_zone_instance; + if (zone_point) { + //we found a zone point, which is a reasonable distance away + //assume that is the one were going with. + target_zone_id = zone_point->target_zone_id; + target_instance_id = zone_point->target_zone_instance; + target_version = zone_point->target_version; } else { //unable to find a zone point... is there anything else //that can be a valid un-zolicited zone request? @@ -199,7 +201,7 @@ void Client::Handle_OP_ZoneChange(const EQApplicationPacket *app) { return; } - auto target_instance_version = database.GetInstanceVersion(target_instance_id); + auto target_instance_version = target_instance_id ? database.GetInstanceVersion(target_instance_id) : target_version; auto zone_data = GetZoneVersionWithFallback( ZoneID(target_zone_name), target_instance_version @@ -375,9 +377,10 @@ void Client::Handle_OP_ZoneChange(const EQApplicationPacket *app) { Message(Chat::White, "Your GM flag allows you to bypass zone expansion checks."); } - if (zoning_message == ZoningMessage::ZoneSuccess) { - DoZoneSuccess(zc, target_zone_id, target_instance_id, target_x, target_y, target_z, target_heading, ignore_restrictions); - } else { + if (zoning_message == ZoningMessage::ZoneSuccess) { + uint32 send_instance = target_instance_id ? target_instance_id : target_version; + DoZoneSuccess(zc, target_zone_id, send_instance, target_x, target_y, target_z, target_heading, ignore_restrictions); + } else { LogError("Zoning [{}]: Rules prevent this char from zoning into [{}]", GetName(), target_zone_name); SendZoneError(zc, zoning_message); } @@ -590,7 +593,12 @@ void Client::MovePC(uint32 zoneID, float x, float y, float z, float heading, uin } void Client::MovePC(uint32 zoneID, uint32 instanceID, float x, float y, float z, float heading, uint8 ignorerestrictions, ZoneMode zm){ - ProcessMovePC(zoneID, instanceID, x, y, z, heading, ignorerestrictions, zm); + ProcessMovePC(zoneID, instanceID, x, y, z, heading, ignorerestrictions, zm); +} + +void Client::MovePC(uint32 zoneID, int16 version, float x, float y, float z, float heading, uint8 ignorerestrictions, ZoneMode zm) +{ + ProcessMovePC(zoneID, version, x, y, z, heading, ignorerestrictions, zm); } void Client::MoveZone(const char *zone_short_name, const glm::vec4 &location) {