From 6b22386ef6331dc7fb44c87d1939fbc722c9ce28 Mon Sep 17 00:00:00 2001 From: Emagi Date: Fri, 20 Jun 2025 09:17:25 -0400 Subject: [PATCH] #37 Fix north qeynos temple of life, ForceZone transport_type added to transporters table see comment for table updates. ALTER TABLE transporters MODIFY COLUMN transport_type ENUM('Zone', 'Location', 'Generic Transport', 'Flight', 'ForceZone') NOT NULL DEFAULT 'Zone'; This provides the north qeynos teleporters for Temple of Life to work as zone points (with code update): update transporters set transport_type='ForceZone' where id=43; update transporters set transport_type='ForceZone' where id=44; --- source/WorldServer/World.h | 2 + source/WorldServer/WorldDatabase.cpp | 4 +- source/WorldServer/client.cpp | 91 ++++++++++++++++++---------- source/WorldServer/client.h | 2 + source/WorldServer/zoneserver.cpp | 26 +++++--- source/WorldServer/zoneserver.h | 2 +- 6 files changed, 81 insertions(+), 46 deletions(-) diff --git a/source/WorldServer/World.h b/source/WorldServer/World.h index 3f1986b..3936d1b 100644 --- a/source/WorldServer/World.h +++ b/source/WorldServer/World.h @@ -158,6 +158,7 @@ struct LocationTransportDestination{ int32 cost; int32 faction_id; int32 faction_value; + bool force_zone; }; struct LottoPlayer { @@ -348,6 +349,7 @@ struct GlobalLoot { #define TRANSPORT_TYPE_ZONE 1 #define TRANSPORT_TYPE_GENERIC 2 #define TRANSPORT_TYPE_FLIGHT 3 +#define TRANSPORT_TYPE_FORCEZONE 4 // structs MUST start with class_id and race_id, in that order as int8's diff --git a/source/WorldServer/WorldDatabase.cpp b/source/WorldServer/WorldDatabase.cpp index 9828bd3..0ad3817 100644 --- a/source/WorldServer/WorldDatabase.cpp +++ b/source/WorldServer/WorldDatabase.cpp @@ -5615,8 +5615,8 @@ void WorldDatabase::LoadTransporters(ZoneServer* zone){ zone->AddTransporter(atoul(row[0]), TRANSPORT_TYPE_ZONE, name, message, atoul(row[4]), atof(row[5]), atof(row[6]), atof(row[7]), atof(row[8]), atoul(row[14]), atoul(row[15]), atoi(row[16]), atoi(row[17]), atoul(row[18]), atoi(row[19]), atoul(row[20]), atoul(row[21]), atoul(row[22]), atoul(row[23]), atoul(row[24]), atoul(row[25]), atoul(row[26]), atoul(row[27]), atoul(row[28]), atoul(row[29]), atoul(row[30]), atoul(row[31])); else if (row[1] && strcmp(row[1], "Flight") == 0) zone->AddTransporter(atoul(row[0]), TRANSPORT_TYPE_FLIGHT, name, message, atoul(row[4]), atof(row[5]), atof(row[6]), atof(row[7]), atof(row[8]), atoul(row[14]), atoul(row[15]), atoi(row[16]), atoi(row[17]), atoul(row[18]), atoi(row[19]), atoul(row[20]), atoul(row[21]), atoul(row[22]), atoul(row[23]), atoul(row[24]), atoul(row[25]), atoul(row[26]), atoul(row[27]), atoul(row[28]), atoul(row[29]), atoul(row[30]), atoul(row[31])); - else if(row[1] && strcmp(row[1], "Location") == 0) - zone->AddLocationTransporter(atoul(row[9]), message, atof(row[10]), atof(row[11]), atof(row[12]), atof(row[13]), atoul(row[4]), atof(row[5]), atof(row[6]), atof(row[7]), atof(row[8]), atoul(row[14]), atoul(row[15])); + else if(row[1] && (strcmp(row[1], "Location") == 0 || strcmp(row[1], "ForceZone") == 0)) + zone->AddLocationTransporter(atoul(row[9]), message, atof(row[10]), atof(row[11]), atof(row[12]), atof(row[13]), atoul(row[4]), atof(row[5]), atof(row[6]), atof(row[7]), atof(row[8]), atoul(row[14]), atoul(row[15]), (strcmp(row[1], "ForceZone") == 0) ? true : false); else zone->AddTransporter(atoul(row[0]), TRANSPORT_TYPE_GENERIC, "", message, atoul(row[4]), atof(row[5]), atof(row[6]), atof(row[7]), atof(row[8]), atoul(row[14]), atoul(row[15]), atoi(row[16]), atoi(row[17]), atoul(row[18]), atoi(row[19]), atoul(row[20]), atoul(row[21]), atoul(row[22]), atoul(row[23]), atoul(row[24]), atoul(row[25]), atoul(row[26]), atoul(row[27]), atoul(row[28]), atoul(row[29]), atoul(row[30]), atoul(row[31])); total++; diff --git a/source/WorldServer/client.cpp b/source/WorldServer/client.cpp index ac41069..8e59062 100644 --- a/source/WorldServer/client.cpp +++ b/source/WorldServer/client.cpp @@ -4891,6 +4891,22 @@ bool Client::GotoSpawn(const char* search_name, bool forceTarget) { return true; } +void Client::MoveInZone(float x, float y, float z, float h) { + SetReloadingZone(true); + + SetZoningCoords(x,y,z,h); + + PacketStruct* packet = configReader.getStruct("WS_TeleportWithinZone", GetVersion()); + if (packet) + { + packet->setDataByName("x", x); + packet->setDataByName("y", y); + packet->setDataByName("z", z); + QueuePacket(packet->serialize()); + safe_delete(packet); + } +} + bool Client::CheckZoneAccess(const char* zoneName) { LogWrite(CCLIENT__DEBUG, 0, "Client", "Zone access check for %s (%u), client: %u", zoneName, database.GetZoneID(zoneName), GetVersion()); @@ -10154,7 +10170,7 @@ void Client::ProcessTeleport(Spawn* spawn, vector* destin transport_list.push_back(destination); } if (transport_list.size() == 0 && destination) { - if (destination->destination_zone_id == 0 || destination->destination_zone_id == GetCurrentZone()->GetZoneID()) { + if (destination->destination_zone_id == 0 || (destination->destination_zone_id == GetCurrentZone()->GetZoneID() && destination->type != TRANSPORT_TYPE_FORCEZONE)) { if (destination->type == TRANSPORT_TYPE_FLIGHT) SendFlightAutoMount(destination->flight_path_id, destination->mount_id, destination->mount_red_color, destination->mount_green_color, destination->mount_blue_color); @@ -10166,20 +10182,14 @@ void Client::ProcessTeleport(Spawn* spawn, vector* destin } } else { - - // determine if this is an instanced zone that already exists - ZoneChangeDetails zone_details; - bool foundZone = world.GetGroupManager()->IdentifyMemberInGroupOrRaid(&zone_details, this, destination->destination_zone_id); - if (foundZone) { - GetPlayer()->SetX(destination->destination_x); - GetPlayer()->SetY(destination->destination_y); - GetPlayer()->SetZ(destination->destination_z); - GetPlayer()->SetHeading(destination->destination_heading); - Zone(&zone_details, (ZoneServer*)zone_details.zonePtr, false, is_spell); + if (destination->destination_zone_id == GetCurrentZone()->GetZoneID() && destination->type == TRANSPORT_TYPE_FORCEZONE) { + MoveInZone(destination->destination_x, destination->destination_y, destination->destination_z, destination->destination_heading); } else { - bool isZone = zone_list.GetZone(&zone_details, destination->destination_zone_id); - if (isZone) { + // determine if this is an instanced zone that already exists + ZoneChangeDetails zone_details; + bool foundZone = world.GetGroupManager()->IdentifyMemberInGroupOrRaid(&zone_details, this, destination->destination_zone_id); + if (foundZone) { GetPlayer()->SetX(destination->destination_x); GetPlayer()->SetY(destination->destination_y); GetPlayer()->SetZ(destination->destination_z); @@ -10187,7 +10197,17 @@ void Client::ProcessTeleport(Spawn* spawn, vector* destin Zone(&zone_details, (ZoneServer*)zone_details.zonePtr, false, is_spell); } else { - SimpleMessage(CHANNEL_COLOR_RED, "Error establishing a zone destination"); + bool isZone = zone_list.GetZone(&zone_details, destination->destination_zone_id); + if (isZone) { + GetPlayer()->SetX(destination->destination_x); + GetPlayer()->SetY(destination->destination_y); + GetPlayer()->SetZ(destination->destination_z); + GetPlayer()->SetHeading(destination->destination_heading); + Zone(&zone_details, (ZoneServer*)zone_details.zonePtr, false, is_spell); + } + else { + SimpleMessage(CHANNEL_COLOR_RED, "Error establishing a zone destination"); + } } } } @@ -10317,7 +10337,7 @@ void Client::ProcessTeleportLocation(EQApplicationPacket* app) { SimpleMessage(CHANNEL_COLOR_RED, "Error processing transport."); else { if (cost == 0 || player->RemoveCoins(cost)) { - if (destination->destination_zone_id == 0 || destination->destination_zone_id == GetCurrentZone()->GetZoneID()) { + if (destination->destination_zone_id == 0 || (destination->destination_zone_id == GetCurrentZone()->GetZoneID() && destination->type != TRANSPORT_TYPE_FORCEZONE)) { if (destination->type == TRANSPORT_TYPE_FLIGHT) SendFlightAutoMount(destination->flight_path_id, destination->mount_id, destination->mount_red_color, destination->mount_green_color, destination->mount_blue_color); @@ -10329,25 +10349,30 @@ void Client::ProcessTeleportLocation(EQApplicationPacket* app) { } } else { - GetPlayer()->SetX(destination->destination_x); - GetPlayer()->SetY(destination->destination_y); - GetPlayer()->SetZ(destination->destination_z); - GetPlayer()->SetHeading(destination->destination_heading); + if((destination->destination_zone_id == GetCurrentZone()->GetZoneID() && destination->type == TRANSPORT_TYPE_FORCEZONE)) { + MoveInZone(destination->destination_x, destination->destination_y, destination->destination_z, destination->destination_heading); + } + else { + GetPlayer()->SetX(destination->destination_x); + GetPlayer()->SetY(destination->destination_y); + GetPlayer()->SetZ(destination->destination_z); + GetPlayer()->SetHeading(destination->destination_heading); - // Test if where we're going is an Instanced zone - if (!TryZoneInstance(destination->destination_zone_id, false)) { - LogWrite(INSTANCE__DEBUG, 0, "Instance", "Attempting to zone normally"); - ZoneChangeDetails zone_details; - bool foundDupeZone = false; - duplicate_zoning_id = 0; - int32 additional_zones = zone_list.GetHighestDuplicateID("", destination->destination_zone_id, false); - if(additional_zones) { - if(foundDupeZone = zone_list.GetDuplicateZoneDetails(&zone_details, "", destination->destination_zone_id, duplicateId)) - duplicate_zoning_id = duplicateId; - } - - if (foundDupeZone || zone_list.GetZone(&zone_details, destination->destination_zone_id)) { - Zone(&zone_details, (ZoneServer*)zone_details.zonePtr, false); + // Test if where we're going is an Instanced zone + if (!TryZoneInstance(destination->destination_zone_id, false)) { + LogWrite(INSTANCE__DEBUG, 0, "Instance", "Attempting to zone normally"); + ZoneChangeDetails zone_details; + bool foundDupeZone = false; + duplicate_zoning_id = 0; + int32 additional_zones = zone_list.GetHighestDuplicateID("", destination->destination_zone_id, false); + if(additional_zones) { + if(foundDupeZone = zone_list.GetDuplicateZoneDetails(&zone_details, "", destination->destination_zone_id, duplicateId)) + duplicate_zoning_id = duplicateId; + } + + if (foundDupeZone || zone_list.GetZone(&zone_details, destination->destination_zone_id)) { + Zone(&zone_details, (ZoneServer*)zone_details.zonePtr, false); + } } } } diff --git a/source/WorldServer/client.h b/source/WorldServer/client.h index 32a1ccc..66095f9 100644 --- a/source/WorldServer/client.h +++ b/source/WorldServer/client.h @@ -292,6 +292,8 @@ public: bool IdentifyInstance(ZoneChangeDetails* zone_details, int32 zoneID); bool TryZoneInstance(int32 zoneID, bool zone_coords_valid = false); bool GotoSpawn(const char* search_name, bool forceTarget = false); + void MoveInZone(float x, float y, float z, float h); + void DisplayDeadWindow(); void HandlePlayerRevive(int32 point_id); void Bank(Spawn* banker, bool cancel = false); diff --git a/source/WorldServer/zoneserver.cpp b/source/WorldServer/zoneserver.cpp index 2b7c817..165fa30 100644 --- a/source/WorldServer/zoneserver.cpp +++ b/source/WorldServer/zoneserver.cpp @@ -3389,20 +3389,25 @@ void ZoneServer::CheckTransporters(Client* client) { for (itr = transporter_locations.begin(); itr != transporter_locations.end(); itr++) { loc = *itr; if(client->GetPlayer()->GetDistance(loc->trigger_x, loc->trigger_y, loc->trigger_z) <= loc->trigger_radius){ - if(loc->destination_zone_id == 0 || loc->destination_zone_id == GetZoneID()){ + if(loc->destination_zone_id == 0 || (loc->destination_zone_id == GetZoneID() && !loc->force_zone)){ EQ2Packet* packet = client->GetPlayer()->Move(loc->destination_x, loc->destination_y, loc->destination_z, client->GetVersion()); if(packet) client->QueuePacket(packet); } else{ - ZoneChangeDetails zone_details; - bool foundZone = zone_list.GetZone(&zone_details, loc->destination_zone_id); - if(foundZone){ - client->GetPlayer()->SetX(loc->destination_x); - client->GetPlayer()->SetY(loc->destination_y); - client->GetPlayer()->SetZ(loc->destination_z); - client->GetPlayer()->SetHeading(loc->destination_heading); - client->Zone(&zone_details, (ZoneServer*)zone_details.zonePtr); + if(loc->force_zone && loc->destination_zone_id == GetZoneID()) { + client->MoveInZone(loc->destination_x, loc->destination_y, loc->destination_z, loc->destination_heading); + } + else { + ZoneChangeDetails zone_details; + bool foundZone = zone_list.GetZone(&zone_details, loc->destination_zone_id); + if(foundZone){ + client->GetPlayer()->SetX(loc->destination_x); + client->GetPlayer()->SetY(loc->destination_y); + client->GetPlayer()->SetZ(loc->destination_z); + client->GetPlayer()->SetHeading(loc->destination_heading); + client->Zone(&zone_details, (ZoneServer*)zone_details.zonePtr); + } } } break; @@ -8574,7 +8579,7 @@ LootTable* ZoneServer::GetLootTable(int32 table_id){ return loot_tables[table_id]; } -void ZoneServer::AddLocationTransporter(int32 zone_id, string message, float trigger_x, float trigger_y, float trigger_z, float trigger_radius, int32 destination_zone_id, float destination_x, float destination_y, float destination_z, float destination_heading, int32 cost, int32 unique_id){ +void ZoneServer::AddLocationTransporter(int32 zone_id, string message, float trigger_x, float trigger_y, float trigger_z, float trigger_radius, int32 destination_zone_id, float destination_x, float destination_y, float destination_z, float destination_heading, int32 cost, int32 unique_id, bool force_zone){ LocationTransportDestination* loc = new LocationTransportDestination; loc->message = message; loc->trigger_x = trigger_x; @@ -8588,6 +8593,7 @@ void ZoneServer::AddLocationTransporter(int32 zone_id, string message, float tri loc->destination_heading = destination_heading; loc->cost = cost; loc->unique_id = unique_id; + loc->force_zone = force_zone; MTransporters.lock(); if(location_transporters.count(zone_id) == 0) location_transporters[zone_id] = new MutexList(); diff --git a/source/WorldServer/zoneserver.h b/source/WorldServer/zoneserver.h index 5b395fa..e5cb23f 100644 --- a/source/WorldServer/zoneserver.h +++ b/source/WorldServer/zoneserver.h @@ -1149,7 +1149,7 @@ public: LootTable* GetLootTable(int32 table_id); /* Transporters */ - void AddLocationTransporter(int32 zone_id, string message, float trigger_x, float trigger_y, float trigger_z, float trigger_radius, int32 destination_zone_id, float destination_x, float destination_y, float destination_z, float destination_heading, int32 cost, int32 unique_id); + void AddLocationTransporter(int32 zone_id, string message, float trigger_x, float trigger_y, float trigger_z, float trigger_radius, int32 destination_zone_id, float destination_x, float destination_y, float destination_z, float destination_heading, int32 cost, int32 unique_id, bool force_zone); void AddTransporter(int32 transport_id, int8 type, string name, string message, int32 destination_zone_id, float destination_x, float destination_y, float destination_z, float destination_heading, int32 cost, int32 unique_id, int8 min_level, int8 max_level, int32 quest_req, int16 quest_step_req, int32 quest_complete, int32 map_x, int32 map_y, int32 expansion_flag, int32 holiday_flag, int32 min_client_version, int32 max_client_version, int32 flight_path_id, int16 mount_id, int8 mount_red_color, int8 mount_green_color, int8 mount_blue_color);