From 66707a02c238798aa4a20f56c29e2d26043f5054 Mon Sep 17 00:00:00 2001 From: Pinapelz Date: Fri, 17 May 2024 16:44:44 -0700 Subject: [PATCH 1/3] implement teleportation via aetheryte ticket --- src/common/Common.h | 1 + src/scripts/action/common/ActionTeleport5.cpp | 1 + src/world/Actor/Player.cpp | 10 ++++++---- src/world/Actor/Player.h | 2 +- src/world/Network/Handlers/PacketCommandHandler.cpp | 5 +++-- 5 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/common/Common.h b/src/common/Common.h index 06883139..27b2c065 100644 --- a/src/common/Common.h +++ b/src/common/Common.h @@ -1790,6 +1790,7 @@ namespace Sapphire::Common { uint16_t targetAetheryte; uint16_t cost; + bool useAetheryteTicket{ false }; }; enum EventSceneError : uint8_t diff --git a/src/scripts/action/common/ActionTeleport5.cpp b/src/scripts/action/common/ActionTeleport5.cpp index 954ab746..cbd52078 100644 --- a/src/scripts/action/common/ActionTeleport5.cpp +++ b/src/scripts/action/common/ActionTeleport5.cpp @@ -22,6 +22,7 @@ public: auto teleportQuery = pPlayer->getTeleportQuery(); if( pPlayer->getCurrency( Common::CurrencyType::Gil ) < teleportQuery.cost || + teleportQuery.useAetheryteTicket && !pPlayer->removeItem( 7569 ) || teleportQuery.targetAetheryte == 0 ) { action.interrupt(); diff --git a/src/world/Actor/Player.cpp b/src/world/Actor/Player.cpp index 08cac924..08f3dbd5 100644 --- a/src/world/Actor/Player.cpp +++ b/src/world/Actor/Player.cpp @@ -1367,7 +1367,7 @@ bool Player::isDirectorInitialized() const return m_directorInitialized; } -void Player::teleportQuery( uint16_t aetheryteId ) +void Player::teleportQuery( uint16_t aetheryteId, bool useAetheryteTicket ) { auto& exdData = Common::Service< Data::ExdData >::ref(); // TODO: only register this action if enough gil is in possession @@ -1378,10 +1378,11 @@ void Player::teleportQuery( uint16_t aetheryteId ) auto fromAetheryte = exdData.getRow< Excel::Aetheryte >( exdData.getRow< Excel::TerritoryType >( getTerritoryTypeId() )->data().Aetheryte ); - // calculate cost - does not apply for favorite points or homepoints neither checks for aether tickets - auto cost = static_cast< uint16_t > ( + // calculate cost - does not apply for favorite points or homepoints + // if using aetheryte ticket, cost is 0 + auto cost = useAetheryteTicket ? 0 : static_cast( ( std::sqrt( std::pow( fromAetheryte->data().CostPosX - targetAetheryte->data().CostPosX, 2 ) + - std::pow( fromAetheryte->data().CostPosY - targetAetheryte->data().CostPosY, 2 ) ) / 2 ) + 100 ); + std::pow( fromAetheryte->data().CostPosY - targetAetheryte->data().CostPosY, 2 )) / 2 ) + 100 ); // cap at 999 gil cost = std::min< uint16_t >( 999, cost ); @@ -1393,6 +1394,7 @@ void Player::teleportQuery( uint16_t aetheryteId ) { m_teleportQuery.targetAetheryte = aetheryteId; m_teleportQuery.cost = cost; + m_teleportQuery.useAetheryteTicket = useAetheryteTicket; } else { diff --git a/src/world/Actor/Player.h b/src/world/Actor/Player.h index a30770ff..759ed8df 100644 --- a/src/world/Actor/Player.h +++ b/src/world/Actor/Player.h @@ -339,7 +339,7 @@ namespace Sapphire::Entity uint64_t getFullOnlineStatusMask() const; /*! query teleport of a specified type */ - void teleportQuery( uint16_t aetheryteId ); + void teleportQuery( uint16_t aetheryteId, bool useAetheryteTicket ); Common::PlayerTeleportQuery getTeleportQuery() const; diff --git a/src/world/Network/Handlers/PacketCommandHandler.cpp b/src/world/Network/Handlers/PacketCommandHandler.cpp index 6cb822e9..931ae94e 100644 --- a/src/world/Network/Handlers/PacketCommandHandler.cpp +++ b/src/world/Network/Handlers/PacketCommandHandler.cpp @@ -607,8 +607,9 @@ void Sapphire::Network::GameConnection::commandHandler( const Packets::FFXIVARR_ } case PacketCommand::TELEPO_INQUIRY: // Teleport { - - player.teleportQuery( static_cast< uint16_t >( data.Arg0 ) ); + // data.Arg0 = aetheryte id + // data.Arg1 = confirm or cancel if using aetheryte ticket + player.teleportQuery( static_cast< uint16_t >( data.Arg0 ), data.Arg1 == 1 ); break; } case PacketCommand::DYE_ITEM: // Dye item From 825f07accc46e288e254452075a0649f8a3185c7 Mon Sep 17 00:00:00 2001 From: Pinapelz Date: Fri, 17 May 2024 18:44:14 -0700 Subject: [PATCH 2/3] fix: seperate set homepoint and housing options from aetheryte menu --- src/scripts/common/aethernet/Aetheryte.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/scripts/common/aethernet/Aetheryte.cpp b/src/scripts/common/aethernet/Aetheryte.cpp index 2af4abef..b02dbe77 100644 --- a/src/scripts/common/aethernet/Aetheryte.cpp +++ b/src/scripts/common/aethernet/Aetheryte.cpp @@ -62,10 +62,18 @@ public: // eventParam4 (or params[1] if using EventPlay8, which is actually used on retail) anything bigger than 1 will show select instance menu item eventMgr().playScene( player, eventId, 0, 1, { 1, 2 }, [ this ]( Entity::Player& player, const Event::SceneResult& result ) { - if( result.numOfResults == 1 ) // set homepoint + if( result.numOfResults == 1 ) { - player.setHomepoint( result.eventId & 0xFFFF ); - eventMgr().sendEventNotice( player, result.eventId, 2, 0xEA, 0, 0 ); + auto cmd = result.getResult( 0 ); + if( cmd == 1 ) // set homepoint + { + player.setHomepoint( result.eventId & 0xFFFF ); + eventMgr().sendEventNotice( player, result.eventId, 2, 0xEA, 0, 0 ); + } + else if( cmd == 5 ) + { + //TODO: Housing teleport selection + } } else if( result.numOfResults == 2 ) // aethernet access { From 2ef9df61f816ee40e343f9fedb1a1ad80b5dc6bd Mon Sep 17 00:00:00 2001 From: Pinapelz Date: Sat, 18 May 2024 11:37:32 -0700 Subject: [PATCH 3/3] fix styling --- src/world/Actor/Player.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/world/Actor/Player.cpp b/src/world/Actor/Player.cpp index 08f3dbd5..83315972 100644 --- a/src/world/Actor/Player.cpp +++ b/src/world/Actor/Player.cpp @@ -1380,9 +1380,9 @@ void Player::teleportQuery( uint16_t aetheryteId, bool useAetheryteTicket ) // calculate cost - does not apply for favorite points or homepoints // if using aetheryte ticket, cost is 0 - auto cost = useAetheryteTicket ? 0 : static_cast( + auto cost = useAetheryteTicket ? 0 : static_cast< uint16_t > ( ( std::sqrt( std::pow( fromAetheryte->data().CostPosX - targetAetheryte->data().CostPosX, 2 ) + - std::pow( fromAetheryte->data().CostPosY - targetAetheryte->data().CostPosY, 2 )) / 2 ) + 100 ); + std::pow( fromAetheryte->data().CostPosY - targetAetheryte->data().CostPosY, 2 ) ) / 2 ) + 100 ); // cap at 999 gil cost = std::min< uint16_t >( 999, cost );