mirror of
https://github.com/SapphireServer/Sapphire.git
synced 2025-05-01 16:37: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:
parent
c82be40934
commit
14860047b6
22 changed files with 373 additions and 44 deletions
|
@ -78,6 +78,60 @@ namespace Sapphire::Common
|
|||
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
|
||||
{
|
||||
None = 0x00,
|
||||
|
@ -649,6 +703,7 @@ namespace Sapphire::Common
|
|||
* @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
|
||||
*/
|
||||
Provoke = 24,
|
||||
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.
|
||||
Knockback = 33,
|
||||
|
@ -893,6 +948,7 @@ namespace Sapphire::Common
|
|||
{
|
||||
Normal = 0x1,
|
||||
ItemAction = 0x2,
|
||||
EventItem = 0x3,
|
||||
MountSkill = 0xD,
|
||||
};
|
||||
|
||||
|
|
|
@ -382,7 +382,7 @@ namespace Sapphire::Network::ActorControl
|
|||
AllotAttribute = 0x135,
|
||||
|
||||
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
|
||||
HuntingLogDetails = 0x194,
|
||||
|
||||
|
|
|
@ -452,7 +452,7 @@ struct FFXIVIpcEventYieldHandler :
|
|||
uint32_t eventId;
|
||||
uint16_t scene;
|
||||
uint16_t padding;
|
||||
uint64_t unknown;
|
||||
uint32_t params[2];
|
||||
};
|
||||
|
||||
struct FFXIVIpcEventYield16Handler :
|
||||
|
@ -468,7 +468,7 @@ struct FFXIVIpcCFCommenceHandler :
|
|||
FFXIVIpcBasePacket< CFCommenceHandler >
|
||||
{
|
||||
uint8_t param;
|
||||
uint8_t dummy[7];
|
||||
uint8_t padding[7];
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -753,8 +753,8 @@ namespace Sapphire::Network::Packets::Server
|
|||
uint16_t unknown1;
|
||||
uint16_t unknown2;
|
||||
uint16_t modelChara;
|
||||
uint16_t currentMount;
|
||||
uint16_t rotation;
|
||||
uint16_t currentMount;
|
||||
uint16_t activeMinion;
|
||||
uint8_t spawnIndex;
|
||||
uint8_t state;
|
||||
|
@ -2230,10 +2230,12 @@ namespace Sapphire::Network::Packets::Server
|
|||
uint8_t classId;
|
||||
uint8_t u5;
|
||||
uint8_t level;
|
||||
uint8_t otherData[368];
|
||||
uint8_t isLevelSync;
|
||||
uint8_t unknown[7];
|
||||
Common::StatusEffect effect[30];
|
||||
} member[8];
|
||||
uint64_t someContentId1;
|
||||
uint64_t someContentId2;
|
||||
uint64_t partyId;
|
||||
uint64_t channelId;
|
||||
uint8_t leaderIndex;
|
||||
uint8_t partySize;
|
||||
uint16_t padding1;
|
||||
|
|
|
@ -123,7 +123,7 @@ private:
|
|||
{
|
||||
if( result.param2 == 1 )
|
||||
{
|
||||
if( player.giveQuestRewards( getId(), 0 ) )
|
||||
if( player.giveQuestRewards( getId(), result.param3 ) )
|
||||
{
|
||||
player.setQuestUI8BH( getId(), result.param3 );
|
||||
player.finishQuest( getId() );
|
||||
|
|
70
src/world/Action/EventItemAction.cpp
Normal file
70
src/world/Action/EventItemAction.cpp
Normal 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();
|
||||
}
|
34
src/world/Action/EventItemAction.h
Normal file
34
src/world/Action/EventItemAction.h
Normal 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;
|
||||
};
|
||||
}
|
|
@ -732,6 +732,7 @@ void Sapphire::Entity::BNpc::calculateStats()
|
|||
m_baseStats.pie = static_cast< uint32_t >( base );
|
||||
m_baseStats.skillSpeed = 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.critHitRate = static_cast< uint32_t >( paramGrowthInfo->baseSpeed );
|
||||
m_baseStats.attackPotMagic = static_cast< uint32_t >( paramGrowthInfo->baseSpeed );
|
||||
|
|
|
@ -529,8 +529,8 @@ void Sapphire::Entity::Chara::addStatusEffect( StatusEffect::StatusEffectPtr pEf
|
|||
if( nextSlot == -1 )
|
||||
return;
|
||||
|
||||
pEffect->applyStatus();
|
||||
m_statusEffectMap[ nextSlot ] = pEffect;
|
||||
pEffect->applyStatus();
|
||||
|
||||
auto statusEffectAdd = makeZonePacket< FFXIVIpcEffectResult >( getId() );
|
||||
|
||||
|
@ -867,6 +867,12 @@ uint32_t Sapphire::Entity::Chara::getStatValue( Sapphire::Common::BaseParam base
|
|||
break;
|
||||
}
|
||||
|
||||
case Common::BaseParam::Haste:
|
||||
{
|
||||
value = m_baseStats.haste;
|
||||
break;
|
||||
}
|
||||
|
||||
case Common::BaseParam::CriticalHit:
|
||||
{
|
||||
value = m_baseStats.critHitRate;
|
||||
|
|
|
@ -48,6 +48,7 @@ namespace Sapphire::Entity
|
|||
uint32_t healingPotMagic = 0;
|
||||
uint32_t determination = 0;
|
||||
uint32_t skillSpeed = 0;
|
||||
uint32_t haste = 0;
|
||||
|
||||
uint32_t resistSlow = 0;
|
||||
uint32_t resistSilence = 0;
|
||||
|
|
|
@ -287,6 +287,7 @@ void Sapphire::Entity::Player::calculateStats()
|
|||
m_baseStats.pie = static_cast< uint32_t >( base );
|
||||
m_baseStats.skillSpeed = paramGrowthInfo->baseSpeed;
|
||||
m_baseStats.spellSpeed = paramGrowthInfo->baseSpeed;
|
||||
m_baseStats.haste = 100;
|
||||
m_baseStats.accuracy = paramGrowthInfo->baseSpeed;
|
||||
m_baseStats.critHitRate = 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().skillSpeed = getStatValue( Common::BaseParam::SkillSpeed );
|
||||
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().defense = getStatValue( Common::BaseParam::Defense );
|
||||
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 )
|
||||
{
|
||||
|
||||
if( ( tickCount - m_lastAttack ) > mainWeap->getDelay() )
|
||||
if( ( tickCount - m_lastAttack ) > ( static_cast< float >( mainWeap->getDelay() ) * ( getStatValue( Common::BaseParam::Haste ) / 100.0f ) ) )
|
||||
{
|
||||
m_lastAttack = tickCount;
|
||||
autoAttack( actor->getAsChara() );
|
||||
|
|
|
@ -704,7 +704,14 @@ Sapphire::ItemPtr Sapphire::Entity::Player::addItem( uint32_t catalogId, uint32_
|
|||
{
|
||||
if( catalogId == 0 )
|
||||
return nullptr;
|
||||
if( catalogId > 1000000 )
|
||||
{
|
||||
catalogId -= 1000000;
|
||||
isHq = true;
|
||||
}
|
||||
auto item = createTempItem( catalogId, quantity );
|
||||
if( !item )
|
||||
return false;
|
||||
item->setHq( isHq );
|
||||
return addItem( item, silent, canMerge, sendLootMessage );
|
||||
}
|
||||
|
|
|
@ -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 )
|
||||
{
|
||||
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 );
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -87,6 +87,7 @@ namespace World::Action
|
|||
TYPE_FORWARD( Action );
|
||||
TYPE_FORWARD( EventAction );
|
||||
TYPE_FORWARD( ItemAction );
|
||||
TYPE_FORWARD( EventItemAction );
|
||||
TYPE_FORWARD( MountAction );
|
||||
TYPE_FORWARD( EffectBuilder );
|
||||
TYPE_FORWARD( EffectResult );
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "Action/Action.h"
|
||||
#include "Action/ItemAction.h"
|
||||
#include "Action/EventItemAction.h"
|
||||
#include "Action/MountAction.h"
|
||||
#include "Script/ScriptMgr.h"
|
||||
#include "Actor/Player.h"
|
||||
|
@ -72,6 +73,20 @@ void World::Manager::ActionMgr::handleItemAction( Sapphire::Entity::Player& play
|
|||
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,
|
||||
Data::ActionPtr actionData, uint64_t targetId,
|
||||
uint16_t sequence )
|
||||
|
@ -94,6 +109,7 @@ void World::Manager::ActionMgr::bootstrapAction( Entity::Player& player,
|
|||
{
|
||||
if( !currentAction->preCheck() )
|
||||
{
|
||||
player.sendDebug( "preCheck failed" );
|
||||
// forcefully interrupt the action and reset the cooldown
|
||||
currentAction->interrupt();
|
||||
return;
|
||||
|
|
|
@ -10,6 +10,9 @@ namespace Sapphire::Data
|
|||
|
||||
struct ItemAction;
|
||||
using ItemActionPtr = std::shared_ptr< ItemAction >;
|
||||
|
||||
struct EventItem;
|
||||
using EventItemPtr = std::shared_ptr< EventItem >;
|
||||
}
|
||||
|
||||
namespace Sapphire::World::Manager
|
||||
|
@ -28,6 +31,8 @@ namespace Sapphire::World::Manager
|
|||
void handleItemAction( Entity::Player& player, uint32_t itemId, Data::ItemActionPtr itemActionData,
|
||||
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,
|
||||
Data::ActionPtr actionData, uint64_t targetId, uint16_t sequence );
|
||||
|
||||
|
|
|
@ -16,6 +16,9 @@
|
|||
#include "DebugCommand/DebugCommand.h"
|
||||
#include "DebugCommandMgr.h"
|
||||
|
||||
#include <datReader/DatCategories/bg/LgbTypes.h>
|
||||
#include <datReader/DatCategories/bg/lgb.h>
|
||||
|
||||
#include "Network/PacketWrappers/ServerNoticePacket.h"
|
||||
#include "Network/PacketWrappers/ActorControlPacket.h"
|
||||
#include "Network/PacketWrappers/ActorControlSelfPacket.h"
|
||||
|
@ -33,6 +36,7 @@
|
|||
#include "Territory/InstanceContent.h"
|
||||
#include "Territory/QuestBattle.h"
|
||||
#include "Territory/PublicContent.h"
|
||||
#include "Territory/InstanceObjectCache.h"
|
||||
#include "Manager/TerritoryMgr.h"
|
||||
#include "Event/EventDefs.h"
|
||||
|
||||
|
@ -304,6 +308,76 @@ void Sapphire::World::Manager::DebugCommandMgr::set( char* data, Entity::Player&
|
|||
{
|
||||
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" )
|
||||
{
|
||||
uint16_t questId;
|
||||
|
@ -604,6 +678,18 @@ void Sapphire::World::Manager::DebugCommandMgr::get( char* data, Entity::Player&
|
|||
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
|
||||
{
|
||||
player.sendUrgent( "{0} is not a valid GET command.", subCommand );
|
||||
|
|
|
@ -112,7 +112,13 @@ bool Sapphire::World::Manager::TerritoryMgr::isInstanceContentTerritory( uint32_
|
|||
intendedUse == TerritoryIntendedUse::RaidFights ||
|
||||
intendedUse == TerritoryIntendedUse::Raids ||
|
||||
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
|
||||
|
@ -148,8 +154,11 @@ bool Sapphire::World::Manager::TerritoryMgr::isDefaultTerritory( uint32_t territ
|
|||
return pTeri->territoryIntendedUse == TerritoryIntendedUse::Inn ||
|
||||
pTeri->territoryIntendedUse == TerritoryIntendedUse::Town ||
|
||||
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
|
||||
|
@ -327,8 +336,8 @@ Sapphire::TerritoryPtr Sapphire::World::Manager::TerritoryMgr::createQuestBattle
|
|||
if( !pQuestInfo )
|
||||
return nullptr;
|
||||
|
||||
if( !isInstanceContentTerritory( pContentFinderCondition->territoryType ) )
|
||||
return nullptr;
|
||||
//if( !isInstanceContentTerritory( pContentFinderCondition->territoryType ) )
|
||||
// return nullptr;
|
||||
|
||||
auto pTeri = getTerritoryDetail( pContentFinderCondition->territoryType );
|
||||
|
||||
|
@ -361,8 +370,8 @@ Sapphire::TerritoryPtr Sapphire::World::Manager::TerritoryMgr::createInstanceCon
|
|||
if( !pInstanceContent )
|
||||
return nullptr;
|
||||
|
||||
if( !isInstanceContentTerritory( pContentFinderCondition->territoryType ) )
|
||||
return nullptr;
|
||||
//if( !isInstanceContentTerritory( pContentFinderCondition->territoryType ) )
|
||||
// return nullptr;
|
||||
|
||||
auto pTeri = getTerritoryDetail( pContentFinderCondition->territoryType );
|
||||
|
||||
|
|
|
@ -48,8 +48,10 @@ namespace Sapphire::World::Manager
|
|||
MSQPrivateArea = 15,
|
||||
Raids = 16,
|
||||
RaidFights = 17,
|
||||
ChocoboSquare = 19,
|
||||
ChocoboTutorial = 21,
|
||||
Wedding = 22,
|
||||
GoldSaucer = 23,
|
||||
DiademV1 = 26,
|
||||
BeginnerTutorial = 27,
|
||||
PvPTheFeast = 28,
|
||||
|
|
|
@ -67,6 +67,14 @@ void Sapphire::Network::GameConnection::actionHandler( const Packets::FFXIVARR_P
|
|||
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:
|
||||
{
|
||||
auto action = exdData.get< Data::Action >( 4 );
|
||||
|
|
|
@ -109,7 +109,9 @@ void Sapphire::Network::GameConnection::clientTriggerHandler( const Packets::FFX
|
|||
else
|
||||
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;
|
||||
}
|
||||
|
@ -523,6 +525,18 @@ void Sapphire::Network::GameConnection::clientTriggerHandler( const Packets::FFX
|
|||
}
|
||||
break;
|
||||
}
|
||||
case ClientTriggerType::CameraMode:
|
||||
{
|
||||
if( param11 == 1 )
|
||||
{
|
||||
player.setOnlineStatusMask( player.getOnlineStatusMask() | 0x0000000000040000 );
|
||||
}
|
||||
else
|
||||
{
|
||||
player.setOnlineStatusMask( player.getOnlineStatusMask() & 0xFFFFFFFFFFFBFFFF );
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
Logger::debug( "[{0}] Unhandled action: {1:04X}", m_pSession->getId(), commandId );
|
||||
|
|
|
@ -298,17 +298,20 @@ void Sapphire::Network::GameConnection::eventYieldHandler( const Packets::FFXIVA
|
|||
auto pParam = reinterpret_cast< const uint32_t* >( &inPacket.data[ 0x10 + 8 ] );
|
||||
|
||||
std::vector< uint32_t > param;
|
||||
auto paramSize = 0;
|
||||
|
||||
switch( opcode )
|
||||
{
|
||||
case EventYield2Handler:
|
||||
paramSize = 2;
|
||||
break;
|
||||
case EventYield16Handler:
|
||||
{
|
||||
for( int i = 0; i < 16; i++ )
|
||||
{
|
||||
param.push_back( pParam[ i ] );
|
||||
}
|
||||
paramSize = 16;
|
||||
break;
|
||||
}
|
||||
for( int i = 0; i < paramSize; i++ )
|
||||
{
|
||||
param.push_back( pParam[ i ] );
|
||||
}
|
||||
|
||||
std::string eventName = "onEventYield";
|
||||
|
|
Loading…
Add table
Reference in a new issue