1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-05-02 00:47:45 +00:00

First batch of 5.58 updates:

- Common defs, ActorControls and packet updates (more to come later).
  - Haste added to chara base stats for later use.
  - Acquiring HQ items support (HQ status not yet saved to db, need table modification).
  - Event item support.
  - Load more default zones.
  - Quest related debug commands.
This commit is contained in:
collett 2023-02-05 19:37:17 +09:00
parent c82be40934
commit 14860047b6
22 changed files with 373 additions and 44 deletions

View file

@ -78,6 +78,60 @@ namespace Sapphire::Common
Enemy = 4, Enemy = 4,
}; };
enum ActorKind : int32_t
{
ACTOR_KIND_PC = 0x0,
ACTOR_KIND_NPC = 0x1,
ACTOR_KIND_RETAINER = 0x2,
ACTOR_KIND_BATTLE = 0x3,
ACTOR_KIND_BATTLE_FRIEND = 0x4,
ACTOR_KIND_OBJECT = 0x5,
ACTOR_KIND_TREASURE = 0x6,
ACTOR_KIND_GATHERING = 0x7,
ACTOR_KIND_MAX = 0x8,
};
enum ObjectType : int32_t
{
OBJECT_TYPE_CAMERA = 0x0,
OBJECT_TYPE_CAMERA_MAYA = 0x1,
OBJECT_TYPE_LIGHT = 0x2,
OBJECT_TYPE_PLAYER = 0x3,
OBJECT_TYPE_WEAPON = 0x4,
OBJECT_TYPE_MONSTER = 0x5,
OBJECT_TYPE_TERRAIN = 0x6,
OBJECT_TYPE_BG_OBJECT = 0x7,
OBJECT_TYPE_ENV_LOCATION = 0x8,
OBJECT_TYPE_ENV_SPACE = 0x9,
OBJECT_TYPE_VFX_OBJECT = 0xA,
OBJECT_TYPE_COUNT_MAX = 0xB,
};
enum WarpType : uint8_t
{
WARP_TYPE_NON = 0x0,
WARP_TYPE_NORMAL = 0x1,
WARP_TYPE_NORMAL_POS = 0x2,
WARP_TYPE_EXIT_RANGE = 0x3,
WARP_TYPE_TELEPO = 0x4,
WARP_TYPE_REISE = 0x5,
WARP_TYPE_ = 0x6,
WARP_TYPE_DESION = 0x7,
WARP_TYPE_HOME_POINT = 0x8,
WARP_TYPE_RENTAL_CHOCOBO = 0x9,
WARP_TYPE_CHOCOBO_TAXI = 0xA,
WARP_TYPE_INSTANCE_CONTENT = 0xB,
WARP_TYPE_REJECT = 0xC,
WARP_TYPE_CONTENT_END_RETURN = 0xD,
WARP_TYPE_TOWN_TRANSLATE = 0xE,
WARP_TYPE_GM = 0xF,
WARP_TYPE_LOGIN = 0x10,
WARP_TYPE_LAYER_SET = 0x11,
WARP_TYPE_EMOTE = 0x12,
WARP_TYPE_HOUSING_TELEPO = 0x13,
WARP_TYPE_DEBUG = 0x14,
};
enum ObjKind : uint8_t enum ObjKind : uint8_t
{ {
None = 0x00, None = 0x00,
@ -649,6 +703,7 @@ namespace Sapphire::Common
* @param flags Required to be 128, doesn't show combo rings on hotbars otherwise * @param flags Required to be 128, doesn't show combo rings on hotbars otherwise
* @param value The actionid that starts/continues the combo. eg, 3617 will start a spinning slash and/or syphon strike combo * @param value The actionid that starts/continues the combo. eg, 3617 will start a spinning slash and/or syphon strike combo
*/ */
Provoke = 24,
StartActionCombo = 27, // shifted one up from 5.18 StartActionCombo = 27, // shifted one up from 5.18
ComboSucceed = 28, // shifted one up from 5.18, on retail this is not seen anymore, still working though. ComboSucceed = 28, // shifted one up from 5.18, on retail this is not seen anymore, still working though.
Knockback = 33, Knockback = 33,
@ -893,6 +948,7 @@ namespace Sapphire::Common
{ {
Normal = 0x1, Normal = 0x1,
ItemAction = 0x2, ItemAction = 0x2,
EventItem = 0x3,
MountSkill = 0xD, MountSkill = 0xD,
}; };

View file

@ -382,7 +382,7 @@ namespace Sapphire::Network::ActorControl
AllotAttribute = 0x135, AllotAttribute = 0x135,
ClearFieldMarkers = 0x13A, ClearFieldMarkers = 0x13A,
CameraMode = 0x13B, // param12, 1 = camera mode enable, 0 = disable CameraMode = 0x13B, // param11, 1 = enable, 0 = disable
CharaNameReq = 0x13D, // requests character name by content id CharaNameReq = 0x13D, // requests character name by content id
HuntingLogDetails = 0x194, HuntingLogDetails = 0x194,

View file

@ -452,7 +452,7 @@ struct FFXIVIpcEventYieldHandler :
uint32_t eventId; uint32_t eventId;
uint16_t scene; uint16_t scene;
uint16_t padding; uint16_t padding;
uint64_t unknown; uint32_t params[2];
}; };
struct FFXIVIpcEventYield16Handler : struct FFXIVIpcEventYield16Handler :
@ -468,7 +468,7 @@ struct FFXIVIpcCFCommenceHandler :
FFXIVIpcBasePacket< CFCommenceHandler > FFXIVIpcBasePacket< CFCommenceHandler >
{ {
uint8_t param; uint8_t param;
uint8_t dummy[7]; uint8_t padding[7];
}; };
} }

View file

@ -753,8 +753,8 @@ namespace Sapphire::Network::Packets::Server
uint16_t unknown1; uint16_t unknown1;
uint16_t unknown2; uint16_t unknown2;
uint16_t modelChara; uint16_t modelChara;
uint16_t currentMount;
uint16_t rotation; uint16_t rotation;
uint16_t currentMount;
uint16_t activeMinion; uint16_t activeMinion;
uint8_t spawnIndex; uint8_t spawnIndex;
uint8_t state; uint8_t state;
@ -2230,10 +2230,12 @@ namespace Sapphire::Network::Packets::Server
uint8_t classId; uint8_t classId;
uint8_t u5; uint8_t u5;
uint8_t level; uint8_t level;
uint8_t otherData[368]; uint8_t isLevelSync;
uint8_t unknown[7];
Common::StatusEffect effect[30];
} member[8]; } member[8];
uint64_t someContentId1; uint64_t partyId;
uint64_t someContentId2; uint64_t channelId;
uint8_t leaderIndex; uint8_t leaderIndex;
uint8_t partySize; uint8_t partySize;
uint16_t padding1; uint16_t padding1;

View file

@ -123,7 +123,7 @@ private:
{ {
if( result.param2 == 1 ) if( result.param2 == 1 )
{ {
if( player.giveQuestRewards( getId(), 0 ) ) if( player.giveQuestRewards( getId(), result.param3 ) )
{ {
player.setQuestUI8BH( getId(), result.param3 ); player.setQuestUI8BH( getId(), result.param3 );
player.finishQuest( getId() ); player.finishQuest( getId() );

View file

@ -0,0 +1,70 @@
#include "EventItemAction.h"
#include <Actor/Player.h>
#include <Network/PacketWrappers/EffectPacket.h>
#include "Manager/PlayerMgr.h"
#include "Manager/EventMgr.h"
#include "Script/ScriptMgr.h"
#include <Service.h>
#include <Network/CommonActorControl.h>
#include "Network/PacketWrappers/ActorControlPacket.h"
#include "Network/PacketWrappers/ActorControlSelfPacket.h"
#include "Network/PacketWrappers/ActorControlTargetPacket.h"
#include <Util/UtilMath.h>
#include <Common.h>
using namespace Sapphire;
using namespace Sapphire::Common;
using namespace Sapphire::Network;
using namespace Sapphire::Network::Packets;
using namespace Sapphire::Network::Packets::Server;
using namespace Sapphire::Network::ActorControl;
using namespace Sapphire::World;
using namespace Sapphire::World::Action;
EventItemAction::EventItemAction( Sapphire::Entity::CharaPtr source, uint32_t eventItemId,
Data::EventItemPtr eventItemActionData,
uint32_t sequence, uint64_t targetId ) :
m_eventItemAction( std::move( eventItemActionData ) )
{
m_id = eventItemId;
m_eventItem = eventItemId;
m_pSource = std::move( source );
m_sequence = sequence;
m_targetId = targetId;
m_interruptType = Common::ActionInterruptType::None;
//m_actionKind = Common::SkillType::EventItem;
}
bool EventItemAction::init()
{
auto& exdData = Common::Service< Data::ExdDataGenerated >::ref();
auto actionInfoPtr = exdData.get< Data::Action >( m_eventItemAction->action );
m_castTimeMs = static_cast< uint32_t >( m_eventItemAction->castTime * 1000 );
m_recastTimeMs = static_cast< uint32_t >( actionInfoPtr->recast100ms * 100 );
m_cooldownGroup = actionInfoPtr->cooldownGroup;
m_id = m_eventItemAction->action;
return true;
}
void EventItemAction::execute()
{
auto player = getSourceChara()->getAsPlayer();
if( !player )
return;
auto& scriptMgr = Common::Service< Scripting::ScriptMgr >::ref();
auto& eventMgr = Common::Service< World::Manager::EventMgr >::ref();
player->eventStart( m_targetId, m_eventItemAction->quest, Event::EventHandler::ActionResult, 0, 0 );
scriptMgr.onEventItem( *player, m_eventItem, m_eventItemAction->quest, m_castTimeMs, m_targetId );
player->checkEvent( m_eventItemAction->quest );
}
void EventItemAction::start()
{
m_startTime = Common::Util::getTimeMs();
}

View file

@ -0,0 +1,34 @@
#pragma once
#include "Action.h"
#include <Exd/ExdDataGenerated.h>
namespace Sapphire::Data
{
struct EventItem;
using EventItemPtr = std::shared_ptr< EventItem >;
}
namespace Sapphire::World::Action
{
class EventItemAction : public Action
{
public:
EventItemAction( Entity::CharaPtr source, uint32_t eventItemId, Data::EventItemPtr itemActionData,
uint32_t sequence, uint64_t targetId );
virtual ~EventItemAction() = default;
bool init();
void execute() override;
void start() override;
private:
Data::EventItemPtr m_eventItemAction;
uint32_t m_eventItem;
uint32_t m_sequence;
};
}

View file

@ -732,6 +732,7 @@ void Sapphire::Entity::BNpc::calculateStats()
m_baseStats.pie = static_cast< uint32_t >( base ); m_baseStats.pie = static_cast< uint32_t >( base );
m_baseStats.skillSpeed = static_cast< uint32_t >( paramGrowthInfo->baseSpeed ); m_baseStats.skillSpeed = static_cast< uint32_t >( paramGrowthInfo->baseSpeed );
m_baseStats.spellSpeed = static_cast< uint32_t >( paramGrowthInfo->baseSpeed ); m_baseStats.spellSpeed = static_cast< uint32_t >( paramGrowthInfo->baseSpeed );
m_baseStats.haste = 100;
m_baseStats.accuracy = static_cast< uint32_t >( paramGrowthInfo->baseSpeed ); m_baseStats.accuracy = static_cast< uint32_t >( paramGrowthInfo->baseSpeed );
m_baseStats.critHitRate = static_cast< uint32_t >( paramGrowthInfo->baseSpeed ); m_baseStats.critHitRate = static_cast< uint32_t >( paramGrowthInfo->baseSpeed );
m_baseStats.attackPotMagic = static_cast< uint32_t >( paramGrowthInfo->baseSpeed ); m_baseStats.attackPotMagic = static_cast< uint32_t >( paramGrowthInfo->baseSpeed );

View file

@ -529,8 +529,8 @@ void Sapphire::Entity::Chara::addStatusEffect( StatusEffect::StatusEffectPtr pEf
if( nextSlot == -1 ) if( nextSlot == -1 )
return; return;
pEffect->applyStatus();
m_statusEffectMap[ nextSlot ] = pEffect; m_statusEffectMap[ nextSlot ] = pEffect;
pEffect->applyStatus();
auto statusEffectAdd = makeZonePacket< FFXIVIpcEffectResult >( getId() ); auto statusEffectAdd = makeZonePacket< FFXIVIpcEffectResult >( getId() );
@ -867,6 +867,12 @@ uint32_t Sapphire::Entity::Chara::getStatValue( Sapphire::Common::BaseParam base
break; break;
} }
case Common::BaseParam::Haste:
{
value = m_baseStats.haste;
break;
}
case Common::BaseParam::CriticalHit: case Common::BaseParam::CriticalHit:
{ {
value = m_baseStats.critHitRate; value = m_baseStats.critHitRate;

View file

@ -48,6 +48,7 @@ namespace Sapphire::Entity
uint32_t healingPotMagic = 0; uint32_t healingPotMagic = 0;
uint32_t determination = 0; uint32_t determination = 0;
uint32_t skillSpeed = 0; uint32_t skillSpeed = 0;
uint32_t haste = 0;
uint32_t resistSlow = 0; uint32_t resistSlow = 0;
uint32_t resistSilence = 0; uint32_t resistSilence = 0;

View file

@ -287,6 +287,7 @@ void Sapphire::Entity::Player::calculateStats()
m_baseStats.pie = static_cast< uint32_t >( base ); m_baseStats.pie = static_cast< uint32_t >( base );
m_baseStats.skillSpeed = paramGrowthInfo->baseSpeed; m_baseStats.skillSpeed = paramGrowthInfo->baseSpeed;
m_baseStats.spellSpeed = paramGrowthInfo->baseSpeed; m_baseStats.spellSpeed = paramGrowthInfo->baseSpeed;
m_baseStats.haste = 100;
m_baseStats.accuracy = paramGrowthInfo->baseSpeed; m_baseStats.accuracy = paramGrowthInfo->baseSpeed;
m_baseStats.critHitRate = paramGrowthInfo->baseSpeed; m_baseStats.critHitRate = paramGrowthInfo->baseSpeed;
m_baseStats.attackPotMagic = paramGrowthInfo->baseSpeed; m_baseStats.attackPotMagic = paramGrowthInfo->baseSpeed;
@ -339,7 +340,7 @@ void Sapphire::Entity::Player::sendStats()
statPacket->data().healingMagicPotency = getStatValue( Common::BaseParam::HealingMagicPotency ); statPacket->data().healingMagicPotency = getStatValue( Common::BaseParam::HealingMagicPotency );
statPacket->data().skillSpeed = getStatValue( Common::BaseParam::SkillSpeed ); statPacket->data().skillSpeed = getStatValue( Common::BaseParam::SkillSpeed );
statPacket->data().spellSpeed = getStatValue( Common::BaseParam::SpellSpeed ); statPacket->data().spellSpeed = getStatValue( Common::BaseParam::SpellSpeed );
statPacket->data().haste = 100; statPacket->data().haste = getStatValue( Common::BaseParam::Haste );
statPacket->data().criticalHit = getStatValue( Common::BaseParam::CriticalHit ); statPacket->data().criticalHit = getStatValue( Common::BaseParam::CriticalHit );
statPacket->data().defense = getStatValue( Common::BaseParam::Defense ); statPacket->data().defense = getStatValue( Common::BaseParam::Defense );
statPacket->data().magicDefense = getStatValue( Common::BaseParam::MagicDefense ); statPacket->data().magicDefense = getStatValue( Common::BaseParam::MagicDefense );
@ -1183,7 +1184,7 @@ void Sapphire::Entity::Player::update( uint64_t tickCount )
actor->getPos().x, actor->getPos().y, actor->getPos().z ) <= range ) actor->getPos().x, actor->getPos().y, actor->getPos().z ) <= range )
{ {
if( ( tickCount - m_lastAttack ) > mainWeap->getDelay() ) if( ( tickCount - m_lastAttack ) > ( static_cast< float >( mainWeap->getDelay() ) * ( getStatValue( Common::BaseParam::Haste ) / 100.0f ) ) )
{ {
m_lastAttack = tickCount; m_lastAttack = tickCount;
autoAttack( actor->getAsChara() ); autoAttack( actor->getAsChara() );

View file

@ -704,7 +704,14 @@ Sapphire::ItemPtr Sapphire::Entity::Player::addItem( uint32_t catalogId, uint32_
{ {
if( catalogId == 0 ) if( catalogId == 0 )
return nullptr; return nullptr;
if( catalogId > 1000000 )
{
catalogId -= 1000000;
isHq = true;
}
auto item = createTempItem( catalogId, quantity ); auto item = createTempItem( catalogId, quantity );
if( !item )
return false;
item->setHq( isHq ); item->setHq( isHq );
return addItem( item, silent, canMerge, sendLootMessage ); return addItem( item, silent, canMerge, sendLootMessage );
} }

View file

@ -1091,6 +1091,13 @@ bool Sapphire::Entity::Player::giveQuestRewards( uint32_t questId, uint32_t opti
} }
} }
auto isHq = false;
if( optionalChoice > 1000000 )
{
optionalChoice -= 1000000;
isHq = true;
}
if( optionalItemCount > 0 ) if( optionalItemCount > 0 )
{ {
for( uint32_t i = 0; i < optionalItemCount; i++ ) for( uint32_t i = 0; i < optionalItemCount; i++ )
@ -1098,7 +1105,7 @@ bool Sapphire::Entity::Player::giveQuestRewards( uint32_t questId, uint32_t opti
auto itemId = questInfo->itemReward1.at( i ); auto itemId = questInfo->itemReward1.at( i );
if( itemId > 0 && itemId == optionalChoice ) if( itemId > 0 && itemId == optionalChoice )
{ {
addItem( itemId, questInfo->itemCountReward1.at( i ), false, false, true, true ); addItem( itemId, questInfo->itemCountReward1.at( i ), isHq, false, true, true );
break; break;
} }
} }

View file

@ -87,6 +87,7 @@ namespace World::Action
TYPE_FORWARD( Action ); TYPE_FORWARD( Action );
TYPE_FORWARD( EventAction ); TYPE_FORWARD( EventAction );
TYPE_FORWARD( ItemAction ); TYPE_FORWARD( ItemAction );
TYPE_FORWARD( EventItemAction );
TYPE_FORWARD( MountAction ); TYPE_FORWARD( MountAction );
TYPE_FORWARD( EffectBuilder ); TYPE_FORWARD( EffectBuilder );
TYPE_FORWARD( EffectResult ); TYPE_FORWARD( EffectResult );

View file

@ -2,6 +2,7 @@
#include "Action/Action.h" #include "Action/Action.h"
#include "Action/ItemAction.h" #include "Action/ItemAction.h"
#include "Action/EventItemAction.h"
#include "Action/MountAction.h" #include "Action/MountAction.h"
#include "Script/ScriptMgr.h" #include "Script/ScriptMgr.h"
#include "Actor/Player.h" #include "Actor/Player.h"
@ -72,6 +73,20 @@ void World::Manager::ActionMgr::handleItemAction( Sapphire::Entity::Player& play
action->start(); action->start();
} }
void World::Manager::ActionMgr::handleEventItemAction( Sapphire::Entity::Player& player, uint32_t itemId, Data::EventItemPtr itemActionData, uint32_t sequence, uint64_t targetId )
{
auto action = Action::make_EventItemAction( player.getAsChara(), itemId, itemActionData, sequence, targetId );
if( !action->init() )
return;
if( itemActionData->castTime )
{
player.setCurrentAction( action );
}
action->start();
}
void World::Manager::ActionMgr::handleMountAction( Entity::Player& player, uint16_t mountId, void World::Manager::ActionMgr::handleMountAction( Entity::Player& player, uint16_t mountId,
Data::ActionPtr actionData, uint64_t targetId, Data::ActionPtr actionData, uint64_t targetId,
uint16_t sequence ) uint16_t sequence )
@ -94,6 +109,7 @@ void World::Manager::ActionMgr::bootstrapAction( Entity::Player& player,
{ {
if( !currentAction->preCheck() ) if( !currentAction->preCheck() )
{ {
player.sendDebug( "preCheck failed" );
// forcefully interrupt the action and reset the cooldown // forcefully interrupt the action and reset the cooldown
currentAction->interrupt(); currentAction->interrupt();
return; return;

View file

@ -10,6 +10,9 @@ namespace Sapphire::Data
struct ItemAction; struct ItemAction;
using ItemActionPtr = std::shared_ptr< ItemAction >; using ItemActionPtr = std::shared_ptr< ItemAction >;
struct EventItem;
using EventItemPtr = std::shared_ptr< EventItem >;
} }
namespace Sapphire::World::Manager namespace Sapphire::World::Manager
@ -28,6 +31,8 @@ namespace Sapphire::World::Manager
void handleItemAction( Entity::Player& player, uint32_t itemId, Data::ItemActionPtr itemActionData, void handleItemAction( Entity::Player& player, uint32_t itemId, Data::ItemActionPtr itemActionData,
uint16_t itemSourceSlot, uint16_t itemSourceContainer ); uint16_t itemSourceSlot, uint16_t itemSourceContainer );
void handleEventItemAction( Entity::Player& player, uint32_t itemId, Data::EventItemPtr itemActionData, uint32_t sequence, uint64_t targetId );
void handleMountAction( Entity::Player& player, uint16_t mountId, void handleMountAction( Entity::Player& player, uint16_t mountId,
Data::ActionPtr actionData, uint64_t targetId, uint16_t sequence ); Data::ActionPtr actionData, uint64_t targetId, uint16_t sequence );

View file

@ -16,6 +16,9 @@
#include "DebugCommand/DebugCommand.h" #include "DebugCommand/DebugCommand.h"
#include "DebugCommandMgr.h" #include "DebugCommandMgr.h"
#include <datReader/DatCategories/bg/LgbTypes.h>
#include <datReader/DatCategories/bg/lgb.h>
#include "Network/PacketWrappers/ServerNoticePacket.h" #include "Network/PacketWrappers/ServerNoticePacket.h"
#include "Network/PacketWrappers/ActorControlPacket.h" #include "Network/PacketWrappers/ActorControlPacket.h"
#include "Network/PacketWrappers/ActorControlSelfPacket.h" #include "Network/PacketWrappers/ActorControlSelfPacket.h"
@ -33,6 +36,7 @@
#include "Territory/InstanceContent.h" #include "Territory/InstanceContent.h"
#include "Territory/QuestBattle.h" #include "Territory/QuestBattle.h"
#include "Territory/PublicContent.h" #include "Territory/PublicContent.h"
#include "Territory/InstanceObjectCache.h"
#include "Manager/TerritoryMgr.h" #include "Manager/TerritoryMgr.h"
#include "Event/EventDefs.h" #include "Event/EventDefs.h"
@ -304,6 +308,76 @@ void Sapphire::World::Manager::DebugCommandMgr::set( char* data, Entity::Player&
{ {
terriMgr.disableCurrentFestival(); terriMgr.disableCurrentFestival();
} }
else if( subCommand == "QuestVar" )
{
uint16_t questId;
uint8_t index;
uint8_t value;
sscanf( params.c_str(), "%hu %hhu %hhu", &questId, &index, &value );
switch( index )
{
case 1:
{
player.setQuestUI8AH( questId, value );
break;
}
case 2:
{
player.setQuestUI8AL( questId, value );
break;
}
case 3:
{
player.setQuestUI8BH( questId, value );
break;
}
case 4:
{
player.setQuestUI8BL( questId, value );
break;
}
case 5:
{
player.setQuestUI8CH( questId, value );
break;
}
case 6:
{
player.setQuestUI8CL( questId, value );
break;
}
case 7:
{
player.setQuestUI8DH( questId, value );
break;
}
case 8:
{
player.setQuestUI8DL( questId, value );
break;
}
case 9:
{
player.setQuestUI8EH( questId, value );
break;
}
case 10:
{
player.setQuestUI8EL( questId, value );
break;
}
case 11:
{
player.setQuestUI8FH( questId, value );
break;
}
case 12:
{
player.setQuestUI8FL( questId, value );
break;
}
}
}
else if( subCommand == "BitFlag" ) else if( subCommand == "BitFlag" )
{ {
uint16_t questId; uint16_t questId;
@ -604,6 +678,18 @@ void Sapphire::World::Manager::DebugCommandMgr::get( char* data, Entity::Player&
instance->getBranch() ); instance->getBranch() );
} }
} }
else if( ( subCommand == "poprange" ) )
{
uint32_t id, param;
sscanf( params.c_str(), "%u", &id );
auto& instanceObjectCache = Common::Service< InstanceObjectCache >::ref();
auto pPopRange = instanceObjectCache.getPopRange( player.getCurrentTerritory()->getTerritoryTypeId(), id );
if( pPopRange )
{
player.sendNotice( "x:{}, y:{}, z:{}", pPopRange->header.transform.translation.x, pPopRange->header.transform.translation.y, pPopRange->header.transform.translation.z );
}
}
else else
{ {
player.sendUrgent( "{0} is not a valid GET command.", subCommand ); player.sendUrgent( "{0} is not a valid GET command.", subCommand );

View file

@ -112,7 +112,13 @@ bool Sapphire::World::Manager::TerritoryMgr::isInstanceContentTerritory( uint32_
intendedUse == TerritoryIntendedUse::RaidFights || intendedUse == TerritoryIntendedUse::RaidFights ||
intendedUse == TerritoryIntendedUse::Raids || intendedUse == TerritoryIntendedUse::Raids ||
intendedUse == TerritoryIntendedUse::TreasureMapInstance || intendedUse == TerritoryIntendedUse::TreasureMapInstance ||
intendedUse == TerritoryIntendedUse::EventTrial; intendedUse == TerritoryIntendedUse::EventTrial ||
intendedUse == TerritoryIntendedUse::DiademV1 ||
intendedUse == TerritoryIntendedUse::DiademV2 ||
intendedUse == TerritoryIntendedUse::DiademV3 ||
intendedUse == TerritoryIntendedUse::Eureka ||
intendedUse == TerritoryIntendedUse::Bozja ||
intendedUse == TerritoryIntendedUse::Wedding;
} }
bool Sapphire::World::Manager::TerritoryMgr::isPrivateTerritory( uint32_t territoryTypeId ) const bool Sapphire::World::Manager::TerritoryMgr::isPrivateTerritory( uint32_t territoryTypeId ) const
@ -148,8 +154,11 @@ bool Sapphire::World::Manager::TerritoryMgr::isDefaultTerritory( uint32_t territ
return pTeri->territoryIntendedUse == TerritoryIntendedUse::Inn || return pTeri->territoryIntendedUse == TerritoryIntendedUse::Inn ||
pTeri->territoryIntendedUse == TerritoryIntendedUse::Town || pTeri->territoryIntendedUse == TerritoryIntendedUse::Town ||
pTeri->territoryIntendedUse == TerritoryIntendedUse::OpenWorld || pTeri->territoryIntendedUse == TerritoryIntendedUse::OpenWorld ||
pTeri->territoryIntendedUse == TerritoryIntendedUse::OpeningArea; pTeri->territoryIntendedUse == TerritoryIntendedUse::OpeningArea ||
pTeri->territoryIntendedUse == TerritoryIntendedUse::GoldSaucer ||
pTeri->territoryIntendedUse == TerritoryIntendedUse::ChocoboSquare ||
pTeri->territoryIntendedUse == TerritoryIntendedUse::MSQPrivateArea ||
pTeri->territoryIntendedUse == TerritoryIntendedUse::BeforeTrialDung;
} }
bool Sapphire::World::Manager::TerritoryMgr::isHousingTerritory( uint32_t territoryTypeId ) const bool Sapphire::World::Manager::TerritoryMgr::isHousingTerritory( uint32_t territoryTypeId ) const
@ -327,8 +336,8 @@ Sapphire::TerritoryPtr Sapphire::World::Manager::TerritoryMgr::createQuestBattle
if( !pQuestInfo ) if( !pQuestInfo )
return nullptr; return nullptr;
if( !isInstanceContentTerritory( pContentFinderCondition->territoryType ) ) //if( !isInstanceContentTerritory( pContentFinderCondition->territoryType ) )
return nullptr; // return nullptr;
auto pTeri = getTerritoryDetail( pContentFinderCondition->territoryType ); auto pTeri = getTerritoryDetail( pContentFinderCondition->territoryType );
@ -361,8 +370,8 @@ Sapphire::TerritoryPtr Sapphire::World::Manager::TerritoryMgr::createInstanceCon
if( !pInstanceContent ) if( !pInstanceContent )
return nullptr; return nullptr;
if( !isInstanceContentTerritory( pContentFinderCondition->territoryType ) ) //if( !isInstanceContentTerritory( pContentFinderCondition->territoryType ) )
return nullptr; // return nullptr;
auto pTeri = getTerritoryDetail( pContentFinderCondition->territoryType ); auto pTeri = getTerritoryDetail( pContentFinderCondition->territoryType );

View file

@ -48,8 +48,10 @@ namespace Sapphire::World::Manager
MSQPrivateArea = 15, MSQPrivateArea = 15,
Raids = 16, Raids = 16,
RaidFights = 17, RaidFights = 17,
ChocoboSquare = 19,
ChocoboTutorial = 21, ChocoboTutorial = 21,
Wedding = 22, Wedding = 22,
GoldSaucer = 23,
DiademV1 = 26, DiademV1 = 26,
BeginnerTutorial = 27, BeginnerTutorial = 27,
PvPTheFeast = 28, PvPTheFeast = 28,

View file

@ -67,6 +67,14 @@ void Sapphire::Network::GameConnection::actionHandler( const Packets::FFXIVARR_P
break; break;
} }
case Common::SkillType::EventItem:
{
auto action = exdData.get< Data::EventItem >( actionId );
assert( action );
actionMgr.handleEventItemAction( player, actionId, action, sequence, targetId );
break;
}
case Common::SkillType::MountSkill: case Common::SkillType::MountSkill:
{ {
auto action = exdData.get< Data::Action >( 4 ); auto action = exdData.get< Data::Action >( 4 );

View file

@ -109,7 +109,9 @@ void Sapphire::Network::GameConnection::clientTriggerHandler( const Packets::FFX
else else
player.setAutoattack( false ); player.setAutoattack( false );
player.sendToInRangeSet( makeActorControl( player.getId(), 1, param11, 1 ) ); // the client seems to ignore source actor of this packet and always set auto-attack on itself. causing everyone on screen take their weapons out
player.queuePacket( makeActorControl( player.getId(), 1, param11, 1 ) );
//player.sendToInRangeSet( makeActorControl( player.getId(), 1, param11, 1 ) );
break; break;
} }
@ -523,6 +525,18 @@ void Sapphire::Network::GameConnection::clientTriggerHandler( const Packets::FFX
} }
break; break;
} }
case ClientTriggerType::CameraMode:
{
if( param11 == 1 )
{
player.setOnlineStatusMask( player.getOnlineStatusMask() | 0x0000000000040000 );
}
else
{
player.setOnlineStatusMask( player.getOnlineStatusMask() & 0xFFFFFFFFFFFBFFFF );
}
break;
}
default: default:
{ {
Logger::debug( "[{0}] Unhandled action: {1:04X}", m_pSession->getId(), commandId ); Logger::debug( "[{0}] Unhandled action: {1:04X}", m_pSession->getId(), commandId );

View file

@ -298,17 +298,20 @@ void Sapphire::Network::GameConnection::eventYieldHandler( const Packets::FFXIVA
auto pParam = reinterpret_cast< const uint32_t* >( &inPacket.data[ 0x10 + 8 ] ); auto pParam = reinterpret_cast< const uint32_t* >( &inPacket.data[ 0x10 + 8 ] );
std::vector< uint32_t > param; std::vector< uint32_t > param;
auto paramSize = 0;
switch( opcode ) switch( opcode )
{ {
case EventYield2Handler:
paramSize = 2;
break;
case EventYield16Handler: case EventYield16Handler:
{ paramSize = 16;
for( int i = 0; i < 16; i++ )
{
param.push_back( pParam[ i ] );
}
break; break;
} }
for( int i = 0; i < paramSize; i++ )
{
param.push_back( pParam[ i ] );
} }
std::string eventName = "onEventYield"; std::string eventName = "onEventYield";