1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-04-30 08:07:46 +00:00

Another approach at event improvements

This commit is contained in:
Mordred 2018-01-09 23:50:54 +01:00
parent 7720bb6d68
commit bd5fe6f699
14 changed files with 5542 additions and 3855 deletions

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,102 @@
#ifndef _FORWARDS_H
#define _FORWARDS_H
#include <boost/shared_ptr.hpp>
namespace Core
{
class Cell;
class Zone;
class Item;
class ItemContainer;
class Inventory;
class Session;
class XMLConfig;
class ZonePosition;
typedef boost::shared_ptr<Zone> ZonePtr;
typedef boost::shared_ptr<Item> ItemPtr;
typedef boost::shared_ptr<ItemContainer> ItemContainerPtr;
typedef boost::shared_ptr<Inventory> InventoryPtr;
typedef boost::shared_ptr<Session> SessionPtr;
typedef boost::shared_ptr<XMLConfig> XMLConfigPtr;
typedef boost::shared_ptr<ZonePosition> ZonePositionPtr;
namespace StatusEffect
{
class StatusEffect;
class StatusEffectContainer;
typedef boost::shared_ptr<StatusEffect> StatusEffectPtr;
typedef boost::shared_ptr<StatusEffectContainer> StatusEffectContainerPtr;
}
namespace Entity
{
class Actor;
class Player;
class BattleNpc;
typedef boost::shared_ptr<Actor> ActorPtr;
typedef boost::shared_ptr<Player> PlayerPtr;
typedef boost::shared_ptr<BattleNpc> BattleNpcPtr;
}
namespace Event
{
class EventHandler;
typedef boost::shared_ptr<EventHandler> EventPtr;
}
namespace Action
{
class Action;
class ActionTeleport;
class EventAction;
typedef boost::shared_ptr<Action> ActionPtr;
typedef boost::shared_ptr<ActionTeleport> ActionTeleportPtr;
typedef boost::shared_ptr<EventAction> EventActionPtr;
}
namespace Network
{
class Hive;
class Acceptor;
class Connection;
class WorldConnection;
class SessionConnection;
class ZoneConnection;
typedef boost::shared_ptr<Hive> HivePtr;
typedef boost::shared_ptr<Acceptor> AcceptorPtr;
typedef boost::shared_ptr<Connection> ConnectionPtr;
typedef boost::shared_ptr<WorldConnection> WorldConnectionPtr;
typedef boost::shared_ptr<ZoneConnection> ZoneConnectionPtr;
typedef boost::shared_ptr<SessionConnection> SessionConnectionPtr;
namespace Packets
{
class GamePacket;
typedef boost::shared_ptr<GamePacket> GamePacketPtr;
}
}
namespace Scripting
{
typedef std::function< void( Entity::Player&, uint32_t, uint16_t, uint16_t, uint16_t, uint16_t ) > EventReturnCallback;
}
typedef std::function< void( Entity::Player&, uint32_t, uint64_t ) > ActionCallback;
}
#endif

View file

@ -0,0 +1,138 @@
#include <common/Util/Util.h>
#include <common/Logging/Logger.h>
#include <common/Exd/ExdData.h>
#include "EventAction.h"
#include "Network/PacketWrappers/ActorControlPacket142.h"
#include "Network/PacketWrappers/ActorControlPacket143.h"
#include "Actor/Player.h"
#include "Event/EventHandler.h"
extern Core::Logger g_log;
extern Core::Data::ExdData g_exdData;
using namespace Core::Common;
using namespace Core::Network;
using namespace Core::Network::Packets;
using namespace Core::Network::Packets::Server;
Core::Action::EventAction::EventAction()
{
m_handleActionType = HandleActionType::Event;
}
Core::Action::EventAction::EventAction( Entity::ActorPtr pActor, uint32_t eventId, uint16_t action,
ActionCallback finishRef, ActionCallback interruptRef, uint64_t additional )
{
m_additional = additional;
m_handleActionType = HandleActionType::Event;
m_eventId = eventId;
m_id = action;
m_castTime = g_exdData.m_EventActionInfoMap[action].castTime; // TODO: Add security checks.
m_onActionFinishClb = finishRef;
m_onActionInterruptClb = interruptRef;
m_pSource = pActor;
m_bInterrupt = false;
}
Core::Action::EventAction::~EventAction()
{
}
void Core::Action::EventAction::onStart()
{
if( !m_pSource )
return;
m_startTime = Util::getTimeMs();
auto control = ActorControlPacket142( m_pSource->getId(), Common::ActorControlType::CastStart,
1, m_id, 0x4000004E );
if( m_pSource->isPlayer() )
{
m_pSource->sendToInRangeSet( control, true );
m_pSource->getAsPlayer()->setStateFlag( PlayerStateFlag::SomeFlag );
m_pSource->getAsPlayer()->sendStateFlags();
}
else
m_pSource->sendToInRangeSet( control );
}
void Core::Action::EventAction::onFinish()
{
if( !m_pSource )
return;
try
{
auto pEvent = m_pSource->getAsPlayer()->getEvent( m_eventId );
pEvent->setPlayedScene( false );
if( m_onActionFinishClb )
m_onActionFinishClb( *m_pSource->getAsPlayer(), m_eventId, m_additional );
auto control = ActorControlPacket142( m_pSource->getId(), Common::ActorControlType::CastStart, 0, m_id );
if( !pEvent->hasPlayedScene() )
m_pSource->getAsPlayer()->eventFinish( m_eventId, 1 );
else
pEvent->setPlayedScene( false );
if( m_pSource->isPlayer() )
{
m_pSource->getAsPlayer()->unsetStateFlag( PlayerStateFlag::SomeFlag );
m_pSource->getAsPlayer()->sendStateFlags();
m_pSource->sendToInRangeSet( control, true );
}
else
m_pSource->sendToInRangeSet( control );
}
catch( std::exception& e )
{
g_log.error( e.what() );
}
}
void Core::Action::EventAction::onInterrupt()
{
if( !m_pSource )
return;
try
{
auto control = ActorControlPacket142( m_pSource->getId(), ActorControlType::CastInterrupt,
0x219, 0x04, m_id );
if( m_pSource->isPlayer() )
{
auto control1 = ActorControlPacket143( m_pSource->getId(), ActorControlType::FreeEventPos, m_eventId );
m_pSource->getAsPlayer()->unsetStateFlag( PlayerStateFlag::NoCombat );
m_pSource->getAsPlayer()->unsetStateFlag( PlayerStateFlag::Occupied1 );
m_pSource->getAsPlayer()->sendStateFlags();
m_pSource->sendToInRangeSet( control );
m_pSource->sendToInRangeSet( control1 );
m_pSource->getAsPlayer()->queuePacket( control1 );
m_pSource->getAsPlayer()->queuePacket( control );
m_pSource->getAsPlayer()->eventFinish( m_eventId, 1 );
}
else
m_pSource->sendToInRangeSet( control );
if( m_onActionInterruptClb )
m_onActionInterruptClb( *m_pSource->getAsPlayer(), m_eventId, m_additional );
}
catch( std::exception& e )
{
g_log.error( e.what() );
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,652 @@
#ifndef _PLAYER_H
#define _PLAYER_H
#include "Forwards.h"
#include <common/Common.h>
#include "Actor.h"
#include "Inventory/Inventory.h"
#include "Event/EventHandler.h"
#include <map>
#include <queue>
namespace Core {
namespace Entity {
struct QueuedZoning
{
uint16_t m_targetZone;
Common::FFXIVARR_POSITION3 m_targetPosition;
float m_targetRotation;
uint64_t m_queueTime;
QueuedZoning( uint16_t targetZone, const Common::FFXIVARR_POSITION3& targetPosition, uint64_t queuedTime, float targetRotation )
: m_targetZone( targetZone )
, m_targetPosition( targetPosition )
, m_queueTime( queuedTime )
, m_targetRotation( targetRotation ) {}
};
/** Class representing the Player
* Inheriting from Actor
*
*/
class Player : public Actor
{
public:
/*! Contructor */
Player();
/*! Destructor */
~Player();
void autoAttack( ActorPtr pTarget ) override;
// EventHandlers
//////////////////////////////////////////////////////////////////////////////////////////////////////
/*! start an event action */
void eventActionStart( uint32_t eventId, uint32_t action, ActionCallback finishCallback, ActionCallback interruptCallback, uint64_t additional );
/*! start an event item action */
void eventItemActionStart( uint32_t eventId, uint32_t action, ActionCallback finishCallback, ActionCallback interruptCallback, uint64_t additional );
/*! start/register a normal event */
void eventStart( uint64_t actorId, uint32_t eventId, Event::EventHandler::EventType eventParam, uint8_t eventParam1, uint32_t eventParam2 );
/*! play a subevent */
void eventPlay( uint32_t eventId, uint32_t scene, uint32_t flags, uint32_t eventParam2, uint32_t eventParam3 );
/*! play a subevent */
void eventPlay( uint32_t eventId, uint32_t scene, uint32_t flags,
uint32_t eventParam2, uint32_t eventParam3, Event::EventHandler::SceneReturnCallback eventReturnCallback );
/*! play a subevent */
void eventPlay( uint32_t eventId, uint32_t scene, uint32_t flags,
uint32_t eventParam2, uint32_t eventParam3, uint32_t eventParam4,
Event::EventHandler::SceneReturnCallback eventReturnCallback );
/*! play a subevent */
void eventPlay( uint32_t eventId, uint32_t scene, uint32_t flags,
Event::EventHandler::SceneReturnCallback eventReturnCallback );
/*! play a subevent */
void eventPlay( uint32_t eventId, uint32_t scene, uint32_t flags );
/*! finish / unregister an event */
void eventFinish( uint32_t eventId, uint32_t freePlayer );
/*! add an event to the event array */
void addEvent( Event::EventHandlerPtr pEvent );
/*! retrieve an event from the event array */
Event::EventHandlerPtr getEvent( uint32_t eventId );
/*! get number of active events */
size_t getEventCount();
/*! remove an event from the event array */
void removeEvent( uint32_t eventId );
/*! return the eventlist */
std::map< uint32_t, Event::EventHandlerPtr >& eventList();
void checkEvent( uint32_t eventId );
// Events
//////////////////////////////////////////////////////////////////////////////////////////////////////
/*! Event to be called when zoning process gets triggered */
void onZoneStart();
/*! Event to be called when zoning process is finished */
void onZoneDone();
/*! Event to be called on login */
void onLogin();
/*! Event to be called on update tick */
void onTick() override;
/*! Event to be called upon player death */
void onDeath() override;
/*! Event called on every session iteration */
void update( int64_t currTime ) override;
/*! Event to be called upon Bnpc kill */
void onMobKill( uint16_t nameId );
// Quest
//////////////////////////////////////////////////////////////////////////////////////////////////////
/*! load data for currently active quests */
bool loadActiveQuests();
/*! update quest ( register it as active quest if new ) */
void updateQuest( uint16_t questId, uint8_t sequence );
/*! return true if quest is currently active */
bool hasQuest( uint16_t questId );
/*! return the current quest sequence */
uint8_t getQuestSeq( uint16_t questId );
/*! send the quest tracker packet */
void sendQuestTracker();
/*! set quest tracker flag for a specified slot */
void setQuestTracker( uint16_t index, int16_t flag );
/*! return the index of a given quest in the players quest list */
int8_t getQuestIndex( uint16_t questId );
/*! finish a given quest */
void finishQuest( uint16_t questId );
/*! finish a given quest */
void unfinishQuest( uint16_t questId );
/*! remove a given quest */
void removeQuest( uint16_t questId );
/*! add a quest to the completed quests mask */
void updateQuestsCompleted( uint32_t questId );
/*! remove a quest from the completed quest mask */
void removeQuestsCompleted( uint32_t questId );
/*! get the curent opening sequence */
uint8_t getOpeningSequence() const;
/*! set te current opening sequence */
void setOpeningSequence( uint8_t seq );
bool giveQuestRewards( uint32_t questId, uint32_t optionalChoice );
boost::shared_ptr< Common::QuestActive > getQuestActive( uint16_t index );
uint8_t getQuestUI8A( uint16_t questId );
uint8_t getQuestUI8B( uint16_t questId );
uint8_t getQuestUI8C( uint16_t questId );
uint8_t getQuestUI8D( uint16_t questId );
uint8_t getQuestUI8E( uint16_t questId );
uint8_t getQuestUI8F( uint16_t questId );
uint8_t getQuestUI8AH( uint16_t questId );
uint8_t getQuestUI8BH( uint16_t questId );
uint8_t getQuestUI8CH( uint16_t questId );
uint8_t getQuestUI8DH( uint16_t questId );
uint8_t getQuestUI8EH( uint16_t questId );
uint8_t getQuestUI8FH( uint16_t questId );
uint8_t getQuestUI8AL( uint16_t questId );
uint8_t getQuestUI8BL( uint16_t questId );
uint8_t getQuestUI8CL( uint16_t questId );
uint8_t getQuestUI8DL( uint16_t questId );
uint8_t getQuestUI8EL( uint16_t questId );
uint8_t getQuestUI8FL( uint16_t questId );
uint16_t getQuestUI16A( uint16_t questId );
uint16_t getQuestUI16B( uint16_t questId );
uint16_t getQuestUI16C( uint16_t questId );
uint32_t getQuestUI32A( uint16_t questId );
uint8_t getQuestBitFlag8( uint16_t questId );
uint8_t getQuestBitFlag16( uint16_t questId );
uint8_t getQuestBitFlag24( uint16_t questId );
uint8_t getQuestBitFlag32( uint16_t questId );
uint8_t getQuestBitFlag40( uint16_t questId );
uint8_t getQuestBitFlag48( uint16_t questId );
void setQuestUI8A( uint16_t questId, uint8_t val );
void setQuestUI8B( uint16_t questId, uint8_t val );
void setQuestUI8C( uint16_t questId, uint8_t val );
void setQuestUI8D( uint16_t questId, uint8_t val );
void setQuestUI8E( uint16_t questId, uint8_t val );
void setQuestUI8F( uint16_t questId, uint8_t val );
void setQuestUI8AH( uint16_t questId, uint8_t val );
void setQuestUI8BH( uint16_t questId, uint8_t val );
void setQuestUI8CH( uint16_t questId, uint8_t val );
void setQuestUI8DH( uint16_t questId, uint8_t val );
void setQuestUI8EH( uint16_t questId, uint8_t val );
void setQuestUI8FH( uint16_t questId, uint8_t val );
void setQuestUI8AL( uint16_t questId, uint8_t val );
void setQuestUI8BL( uint16_t questId, uint8_t val );
void setQuestUI8CL( uint16_t questId, uint8_t val );
void setQuestUI8DL( uint16_t questId, uint8_t val );
void setQuestUI8EL( uint16_t questId, uint8_t val );
void setQuestUI8FL( uint16_t questId, uint8_t val );
void setQuestUI16A( uint16_t questId, uint16_t val );
void setQuestUI16B( uint16_t questId, uint16_t val );
void setQuestUI16C( uint16_t questId, uint16_t val );
void setQuestUI32A( uint16_t questId, uint32_t val );
void setQuestBitFlag8( uint16_t questId, uint8_t val );
void setQuestBitFlag16( uint16_t questId, uint8_t val );
void setQuestBitFlag24( uint16_t questId, uint8_t val );
void setQuestBitFlag32( uint16_t questId, uint8_t val );
void setQuestBitFlag40( uint16_t questId, uint8_t val );
void setQuestBitFlag48( uint16_t questId, uint8_t val );
// Inventory / Item / Currency
//////////////////////////////////////////////////////////////////////////////////////////////////////
/*! add an item to the first free slot in one of the 4 main containers */
bool tryAddItem( uint16_t catalogId, uint32_t quantity );
/*! add an item to a given container */
bool addItem( uint16_t containerId, uint16_t catalogId, uint32_t quantity );
/*! equip an item to a specified slot */
void equipItem( Inventory::EquipSlot equipSlotId, ItemPtr pItem, bool sendModel );
/*! remove an item from an equipment slot */
void unequipItem( Inventory::EquipSlot equipSlotId, ItemPtr pItem );
/*! equip a weapon, possibly forcing a job change */
void equipWeapon( ItemPtr pItem );
/*! get player ilvl */
uint16_t getItemLevel() const;
/*! send player ilvl */
void sendItemLevel();
/*! get a const pointer to the inventory object */
InventoryPtr getInventory() const;
/*! get the current main hand model */
uint64_t getModelMainWeapon() const;
/*! get the current off hand model */
uint64_t getModelSubWeapon() const;
/*! get the current system hand model */
uint64_t getModelSystemWeapon() const;
/*! return a const pointer to the model array */
const uint32_t* getModelArray() const;
/*! return the equipment model in a specified equipment slot */
uint32_t getModelForSlot( Inventory::EquipSlot slot );
/*! set the equipment model in a specified equipment slot */
void setModelForSlot( Inventory::EquipSlot slot, uint32_t val );
/*! return the current amount of currency of type */
uint32_t getCurrency( uint8_t type ) const;
/*! add amount to the currency of type */
void addCurrency( uint8_t type, uint32_t amount );
/*! remove amount from the currency of type */
void removeCurrency( uint8_t type, uint32_t amount );
/*! return the current amount of crystals of type */
uint32_t getCrystal( uint8_t type ) const;
/*! add amount to the crystals of type */
void addCrystal( uint8_t type, uint32_t amount );
/*! remove amount from the crystals of type */
void removeCrystal( uint8_t type, uint32_t amount );
// Class / Job / Exp
//////////////////////////////////////////////////////////////////////////////////////////////////////
/*! returns the level of the currently active class / job */
uint8_t getLevel() const override;
/*! returns the level of the provided class / job */
uint8_t getLevelForClass( Common::ClassJob pClass ) const;
/*! returns the exp of the currently active class / job */
uint32_t getExp() const;
/*! sets the exp of the currently active class / job */
void setExp( uint32_t amount );
/*! adds exp to the currently active class / job */
void gainExp( uint32_t amount );
/*! gain a level on the currently active class / job */
void gainLevel();
/*! set level on the currently active class / job to given level */
void setLevel( uint8_t level );
/*! set level on the provided class / job to given level */
void setLevelForClass( uint8_t level, Common::ClassJob classjob );
/*! change class or job to given class / job */
void setClassJob( Common::ClassJob classJob );
/*! returns a pointer to the class array */
uint16_t* getClassArray();
/*! returns a const pointer to the class array */
const uint16_t* getClassArray() const;
/*! returns a pointer to the exp array */
uint32_t* getExpArray();
/*! returns a const pointer to the exp array */
const uint32_t* getExpArray() const;
// Base Look / Stats / Params
//////////////////////////////////////////////////////////////////////////////////////////////////////
/*! return the birth day */
uint8_t getBirthDay() const;
/*! return the birth month */
uint8_t getBirthMonth() const;
/*! return the guardian diety Id */
uint8_t getGuardianDeity() const;
/*! get look at specified index */
uint8_t getLookAt( uint8_t index ) const;
/*! return the race */
uint8_t getRace() const;
/*! return gender 0 male, 1 female */
uint8_t getGender() const;
/*! return the id of the home town */
uint8_t getStartTown() const;
/*! return the voice id */
uint8_t getVoiceId() const;
/*! return the grand company */
uint8_t getGc() const;
/*! return the grand company rank */
const uint8_t* getGcRankArray() const;
/*! set look at index */
void setLookAt( uint8_t index, uint8_t value );
/*! set the voice Id */
void setVoiceId( uint8_t voiceId );
/*! set the grand company */
void setGc( uint8_t gc );
/*! set the grand company rank */
void setGcRankAt( uint8_t index, uint8_t rank );
/*! return a const pointer to the look array */
const uint8_t* getLookArray() const;
/*! returns true if the player is currently in combat */
bool isInCombat() const;
/*! sets players combat state */
void setInCombat( bool mode );
/*! return current online status depending on current state / activity */
Common::OnlineStatus getOnlineStatus();
/*! sets the players zone, initiating a zoning process */
void setZone( uint32_t zoneId );
void forceZoneing( uint32_t zoneId );
/*! return player to preset homepoint */
void returnToHomepoint();
/*! change position, sends update too */
void changePosition( float x, float y, float z, float o );
/*! return the contentId */
uint64_t getContentId() const;
/*! return max hp */
uint32_t getMaxHp();
/*! return max mp */
uint32_t getMaxMp();
/*! return a players total play time */
uint32_t getPlayTime() const;
/*! return true if the player has "new adventurere" status */
bool isNewAdventurer() const;
/*! change the players "new adventurere" status */
void setNewAdventurer( bool state );
/*! sets the list of current online status */
void setOnlineStatusMask( uint64_t status );
/*! returns the current online status */
uint64_t getOnlineStatusMask() const;
/*! perform a teleport of a specified type ( teleport,return,aethernet ) */
void teleport( uint16_t aetheryteId, uint8_t type = 1 );
/*! prepares zoning / fades out the screen */
void prepareZoning( uint16_t targetZone, bool fadeOut, uint8_t fadoutTime = 0, uint16_t animation = 0 );
/*! get player's title list (available titles) */
uint8_t* getTitleList();
/*! get player's active title */
uint16_t getTitle() const;
/*! add title to player title list */
void addTitle( uint16_t titleId );
/*! change player's active title */
void setTitle( uint16_t titleId );
/*! change gear param state */
void setEquipDisplayFlags( uint8_t state );
/*! get gear param state */
uint8_t getEquipDisplayFlags() const;
/*! mount the specified mount and send the packets */
void mount( uint32_t id );
/*! dismount the current mount and send the packets */
void dismount();
/*! get the current mount */
uint8_t getCurrentMount() const;
void calculateStats() override;
void sendStats();
// Aetheryte / Action / Attribute bitmasks
//////////////////////////////////////////////////////////////////////////////////////////////////////
/*! register aetheryte aetheryteId and send update */
void registerAetheryte( uint8_t aetheryteId );
/*! check if aetheryte is already registered */
bool isAetheryteRegistered( uint8_t aetheryteId ) const;
/*! return a const pointer to the aetheryte unlock bitmask array */
int8_t getAetheryteMaskAt( uint8_t index ) const;
/*! return a pointer to the aetheryte unlock bitmask array */
uint8_t* getAetheryteArray();
/*! set homepoint */
void setHomepoint( uint8_t aetheryteId );
/*! get homepoint */
uint8_t getHomepoint() const;
/*! discover subarea subid fo map map_id, also send udpate packet */
void discover( int16_t map_id, int16_t sub_id );
/*! return a pointer to the discovery bitmask array */
uint8_t* getDiscoveryBitmask();
/*! helper/debug function to reset all discovered areas */
void resetDiscovery();
/*! get a pointer to the howto bitmask array */
uint8_t* getHowToArray();
/*! get a const pointer to the howto bitmask array */
const uint8_t* getHowToArray() const;
/*! update bitmask for how-to's seen */
void updateHowtosSeen( uint32_t howToId );
/*! learn an action / update the unlock bitmask. */
void learnAction( uint8_t actionId );
/*! learn a song / update the unlock bitmask. */
void learnSong( uint8_t songId, uint32_t itemId );
/*! check if an action is already unlocked in the bitmask. */
bool isActionLearned( uint8_t actionId ) const;
/*! return a const pointer to the unlock bitmask array */
const uint8_t* getUnlockBitmask() const;
/*! return a const pointer to the orchestrion bitmask array */
const uint8_t* getOrchestrionBitmask() const;
/*! return a const pointer to the mount guide bitmask array */
const uint8_t* getMountGuideBitmask() const;
// Spawn handling
//////////////////////////////////////////////////////////////////////////////////////////////////////
/*! initialize the spawnId queue */
void initSpawnIdQueue();
/*! get the spawn id mapped to a specific actorId */
uint8_t getSpawnIdForActorId( uint32_t actorId );
/*! assigns the given spawnId to the actor */
void assignSpawnIdToPlayerId( uint32_t actorId, uint8_t spawnId );
/*! frees the spawnId assigned to the given actor */
void freePlayerSpawnId( uint32_t actorId );
/*! send spawn packets to pTarget */
void spawn( PlayerPtr pTarget ) override;
/*! send despawn packets to pTarget */
void despawn( ActorPtr pTarget ) override;
// Player State Handling
//////////////////////////////////////////////////////////////////////////////////////////////////////
/* return a const pointer to the state flag array */
const uint8_t* getStateFlags() const;
/* set a specified state flag */
void setStateFlag( Common::PlayerStateFlag flag );
/* set a specified state flag */
void setStateFlags( std::vector< Common::PlayerStateFlag > flags );
/* check if a specified flag is set */
bool hasStateFlag( Common::PlayerStateFlag flag ) const;
/* reset a specified flag */
void unsetStateFlag( Common::PlayerStateFlag flag );
/* helper function, send an empty state flag update */
void unlock();
// Player Session Handling
//////////////////////////////////////////////////////////////////////////////////////////////////////
/*! return the userlevel */
uint8_t getUserLevel() const;
/*! set timestamp for last received ping */
void setLastPing( uint32_t ping );
/*! get timestamp of last received ping */
uint32_t getLastPing() const;
// Player Database Handling
//////////////////////////////////////////////////////////////////////////////////////////////////////
/*! generate the update sql based on update flags */
void updateSql();
/*! load player from db, by id */
bool load( uint32_t charId, SessionPtr pSession );
/*! load active class data */
bool loadClassData();
/*! load search info */
bool loadSearchInfo();
// Player Network Handling
//////////////////////////////////////////////////////////////////////////////////////////////////////
/*! send current models ( equipment ) */
void sendModel();
/*! send active state flags */
void sendStateFlags();
/*! send status update */
void sendStatusUpdate( bool toSelf = true ) override;
/*! send the entire inventory sequence */
void sendInventory() const;
/*! send active quest list */
void sendQuestInfo();
/*! send a quest specific message */
void sendQuestMessage( uint32_t questId, int8_t msgId, uint8_t type, uint32_t var1, uint32_t var2 );
/*! queue a packet for the player */
void queuePacket( Network::Packets::GamePacketPtr pPacket );
/*! queue a char connection packet for the player */
void queueChatPacket( Network::Packets::GamePacketPtr pPacket );
/*! returns true if loading is complete ( 0x69 has been received ) */
bool isLoadingComplete() const;
/*! set the loading complete bool */
void setLoadingComplete( bool bComplete );
/*! mark this player for zoning, notify worldserver */
void performZoning(uint16_t zoneId, const Common::FFXIVARR_POSITION3& pos, float rotation);
/*! return true if the player is marked for zoning */
bool isMarkedForZoning() const;
Common::ZoneingType getZoningType() const;
void setZoningType( Common::ZoneingType zoneingType );
void setSearchInfo( uint8_t selectRegion, uint8_t selectClass, const char* searchMessage );
const char* getSearchMessage() const;
uint8_t getSearchSelectRegion() const;
uint8_t getSearchSelectClass() const;
void sendNotice( const std::string& message );
void sendUrgent( const std::string& message );
void sendDebug( const std::string& message );
// Player Battle Handling
//////////////////////////////////////////////////////////////////////////////////////////////////////
void onMobAggro( BattleNpcPtr pBNpc );
void onMobDeaggro( BattleNpcPtr pBNpc );
void initHateSlotQueue();
void hateListAdd( BattleNpcPtr pBNpc );
void hateListRemove( BattleNpcPtr pBNpc );
bool hateListHasMob( BattleNpcPtr pBNpc );
void sendHateList();
bool actionHasCastTime( uint32_t actionId );
Core::Entity::ActorPtr lookupTargetById( uint64_t targetId );
bool isLogin() const;
void setIsLogin( bool bIsLogin );
uint16_t getZoneId() const;
uint8_t getGmRank() const;
void setGmRank( uint8_t rank );
uint8_t getMode() const;
void setMode( uint8_t mode );
void setAutoattack( bool mode );
bool isAutoattackOn() const;
// Content Finder handling
//////////////////////////////////////////////////////////////////////////////////////////////////////
/*! Get an unix time when the player can register into content finder again. */
uint32_t getCFPenaltyTimestamp() const;
/*! Set an unix time when the player can register into content finder again. */
void setCFPenaltyTimestamp( uint32_t timestamp );
uint32_t getCFPenaltyMinutes() const;
void setCFPenaltyMinutes( uint32_t minutes );
void setEorzeaTimeOffset( uint64_t timestamp );
// Database
void updateDbAllQuests() const;
void deleteQuest( uint16_t questId ) const;
void insertQuest( uint16_t questId, uint8_t index, uint8_t seq ) const;
void updateDbSearchInfo() const;
void updateDbClass() const;
void insertDbClass( const uint8_t classJobIndex ) const;
void setMarkedForRemoval();
bool isMarkedForRemoval() const;
private:
uint32_t m_lastWrite;
uint32_t m_lastPing;
bool m_bIsLogin;
uint64_t m_contentId; // This id will be the name of the folder for character settings in "My Games"
uint8_t m_mode;
bool m_markedForRemoval;
private:
uint8_t m_voice;
uint64_t m_modelMainWeapon;
uint64_t m_modelSubWeapon;
uint64_t m_modelSystemWeapon;
uint32_t m_modelEquip[10];
bool m_bNewGame;
uint8_t m_guardianDeity;
uint8_t m_birthDay;
uint8_t m_birthMonth;
struct RetainerInfo
{
uint32_t retainerId;
char retainerName[32];
uint32_t createUnixTime;
bool isActive;
bool isRename;
uint8_t status;
} m_retainerInfo[8];
uint16_t m_activeTitle;
uint8_t m_titleList[48];
uint8_t m_howTo[33];
uint8_t m_minions[35];
uint8_t m_mountGuide[14];
uint8_t m_homePoint;
uint8_t m_startTown;
uint16_t m_townWarpFstFlags;
uint8_t m_questCompleteFlags[200];
uint8_t m_discovery[420];
uint32_t m_playTime;
uint16_t m_classArray[25];
uint32_t m_expArray[25];
uint8_t m_aetheryte[16];
uint8_t m_unlocks[64];
uint8_t m_orchestrion[40];
uint8_t m_openingSequence;
uint16_t m_itemLevel;
InventoryPtr m_pInventory;
std::map< uint32_t, Event::EventHandlerPtr > m_eventMap;
std::map< uint32_t, uint8_t > m_playerIdToSpawnIdMap; // maps player to spawn id
std::queue< uint8_t > m_freeSpawnIdQueue; // queue with spawn ids free to be assigned
std::queue< uint8_t > m_freeHateSlotQueue; // queue with "hate slots" free to be assigned
std::map< uint32_t, uint8_t > m_actorIdTohateSlotMap;
std::map< uint32_t, uint8_t > m_questIdToQuestIdx; // quest mapping, quest id to quest container index
std::map< uint8_t, uint32_t > m_questIdxToQuestId; // quest mapping, quest container index to questId
boost::shared_ptr< Common::QuestActive > m_activeQuests[30];
int16_t m_questTracking[5];
uint8_t m_stateFlags[7];
uint8_t m_gmRank;
uint16_t zoneId;
uint8_t m_equipDisplayFlags;
bool m_bInCombat;
bool m_bLoadingComplete;
bool m_bAutoattack;
Common::ZoneingType m_zoningType;
bool m_bMarkedForZoning;
bool m_bNewAdventurer;
uint64_t m_onlineStatus;
boost::shared_ptr< QueuedZoning > m_queuedZoneing;
// search info
char m_searchMessage[193]; // searchmessage to show in profile
uint8_t m_searchSelectRegion; // regions selected to show up in profile
uint8_t m_searchSelectClass; // class selected to show up in profile
// gc info
uint8_t m_gc;
uint8_t m_gcRank[3];
// content finder info
uint32_t m_cfPenaltyUntil; // unix time
uint8_t m_mount;
};
}
}
#endif

View file

@ -0,0 +1,361 @@
#include <common/Common.h>
#include <common/Network/GamePacket.h>
#include <common/Logging/Logger.h>
#include <common/Network/PacketContainer.h>
#include <common/Config/XMLConfig.h>
#include "Player.h"
#include "Zone/Zone.h"
#include "Forwards.h"
#include "Network/GameConnection.h"
#include "Network/PacketWrappers/ActorControlPacket142.h"
#include "Network/PacketWrappers/InitUIPacket.h"
#include "Network/PacketWrappers/ServerNoticePacket.h"
#include "Network/PacketWrappers/EventStartPacket.h"
#include "Network/PacketWrappers/EventPlayPacket.h"
#include "Network/PacketWrappers/EventFinishPacket.h"
#include "Action/EventAction.h"
#include "Action/EventItemAction.h"
#include "Event/EventHandler.h"
#include "Event/EventHandler.h"
#include "ServerZone.h"
extern Core::Logger g_log;
extern Core::ServerZone g_serverZone;
using namespace Core::Common;
using namespace Core::Network::Packets;
using namespace Core::Network::Packets::Server;
void Core::Entity::Player::addEvent( Event::EventHandlerPtr pEvent )
{
m_eventMap[pEvent->getId()] = pEvent;
}
std::map< uint32_t, Core::Event::EventHandlerPtr >& Core::Entity::Player::eventList()
{
return m_eventMap;
}
Core::Event::EventHandlerPtr Core::Entity::Player::getEvent( uint32_t eventId )
{
auto it = m_eventMap.find( eventId );
if( it != m_eventMap.end() )
return it->second;
return Event::EventHandlerPtr( nullptr );
}
size_t Core::Entity::Player::getEventCount()
{
return m_eventMap.size();
}
void Core::Entity::Player::removeEvent( uint32_t eventId )
{
auto it = m_eventMap.find( eventId );
if( it != m_eventMap.end() )
{
auto tmpEvent = it->second;
m_eventMap.erase( it );
}
}
void Core::Entity::Player::checkEvent( uint32_t eventId )
{
auto pEvent = getEvent( eventId );
if( pEvent && !pEvent->hasPlayedScene() )
eventFinish( eventId, 1 );
}
void Core::Entity::Player::eventStart( uint64_t actorId, uint32_t eventId,
Event::EventHandler::EventType eventType, uint8_t eventParam1,
uint32_t eventParam2 )
{
Event::EventHandlerPtr newEvent( new Event::EventHandler( actorId, eventId, eventType, eventParam2 ) );
addEvent( newEvent );
setStateFlag( PlayerStateFlag::Occupied2 );
sendStateFlags();
EventStartPacket eventStart( getId(), actorId, eventId, eventType, eventParam1, eventParam2 );
queuePacket( eventStart );
}
void Core::Entity::Player::eventPlay( uint32_t eventId, uint32_t scene,
uint32_t flags, uint32_t eventParam2,
uint32_t eventParam3 )
{
eventPlay( eventId, scene, flags, eventParam2, eventParam3, nullptr );
}
void Core::Entity::Player::eventPlay( uint32_t eventId, uint32_t scene,
uint32_t flags, Event::EventHandler::SceneReturnCallback eventCallback )
{
eventPlay( eventId, scene, flags, 0, 0, eventCallback );
}
void Core::Entity::Player::eventPlay( uint32_t eventId, uint32_t scene, uint32_t flags )
{
eventPlay( eventId, scene, flags, 0, 0, nullptr );
}
void Core::Entity::Player::eventPlay( uint32_t eventId, uint32_t scene,
uint32_t flags, uint32_t eventParam2,
uint32_t eventParam3, Event::EventHandler::SceneReturnCallback eventCallback )
{
if( flags & 0x02 )
{
setStateFlag( PlayerStateFlag::WatchingCutscene );
sendToInRangeSet( ActorControlPacket142( getId(), SetStatusIcon,
static_cast< uint8_t >( getOnlineStatus() ) ), true );
}
auto pEvent = getEvent( eventId );
if( !pEvent && getEventCount() )
{
// We're trying to play a nested event, need to start it first.
eventStart( getId(), eventId, Event::EventHandler::Nest, 0, 0 );
pEvent = getEvent( eventId );
}
else if( !pEvent )
{
g_log.error( "Could not find event " + std::to_string( eventId ) + ", event has not been started!" );
return;
}
pEvent->setPlayedScene( true );
pEvent->setEventReturnCallback( eventCallback );
EventPlayPacket eventPlay( getId(), pEvent->getActorId(), pEvent->getId(),
scene, flags, eventParam2, eventParam3 );
queuePacket( eventPlay );
}
void Core::Entity::Player::eventPlay( uint32_t eventId, uint32_t scene,
uint32_t flags, uint32_t eventParam2,
uint32_t eventParam3, uint32_t eventParam4, Event::EventHandler::SceneReturnCallback eventCallback )
{
if( flags & 0x02 )
{
setStateFlag( PlayerStateFlag::WatchingCutscene );
sendToInRangeSet( ActorControlPacket142( getId(), SetStatusIcon,
static_cast< uint8_t >( getOnlineStatus() ) ), true );
}
auto pEvent = getEvent( eventId );
if( !pEvent && getEventCount() )
{
// We're trying to play a nested event, need to start it first.
eventStart( getId(), eventId, Event::EventHandler::Nest, 0, 0 );
pEvent = getEvent( eventId );
}
else if( !pEvent )
{
g_log.error( "Could not find event " + std::to_string( eventId ) + ", event has not been started!" );
return;
}
pEvent->setPlayedScene( true );
pEvent->setEventReturnCallback( eventCallback );
EventPlayPacket eventPlay( getId(), pEvent->getActorId(), pEvent->getId(),
scene, flags, eventParam2, eventParam3, eventParam4 );
queuePacket( eventPlay );
}
void Core::Entity::Player::eventFinish( uint32_t eventId, uint32_t freePlayer )
{
auto pEvent = getEvent( eventId );
if( !pEvent )
{
g_log.error( "Could not find event " + std::to_string( eventId ) + ", event has not been started!" );
return;
}
if( getEventCount() > 1 && pEvent->getEventType() != Event::EventHandler::Nest )
{
// this is the parent of a nested event, we can't finish it until the parent finishes
return;
}
switch( pEvent->getEventType() )
{
case Event::EventHandler::Nest:
{
queuePacket( EventFinishPacket( getId(), pEvent->getId(), pEvent->getEventType(), pEvent->getEventParam3() ) );
removeEvent( pEvent->getId() );
auto events = eventList();
for( auto it : events )
{
if( it.second->hasPlayedScene() == false )
{
// TODO: not happy with this, this is also prone to break wit more than one remaining event in there
queuePacket( EventFinishPacket( getId(), it.second->getId(), it.second->getEventType(), it.second->getEventParam3() ) );
removeEvent( it.second->getId() );
}
}
break;
}
default:
{
queuePacket( EventFinishPacket( getId(), pEvent->getId(), pEvent->getEventType(), pEvent->getEventParam3() ) );
break;
}
}
if( hasStateFlag( PlayerStateFlag::WatchingCutscene ) )
{
unsetStateFlag( PlayerStateFlag::WatchingCutscene );
sendToInRangeSet( ActorControlPacket142( getId(), SetStatusIcon,
static_cast< uint8_t >( getOnlineStatus() ) ), true );
}
removeEvent( pEvent->getId() );
if( freePlayer == 1 )
{
unsetStateFlag( PlayerStateFlag::Occupied2 );
sendStateFlags();
}
}
void Core::Entity::Player::eventActionStart( uint32_t eventId,
uint32_t action,
ActionCallback finishCallback,
ActionCallback interruptCallback,
uint64_t additional )
{
Action::ActionPtr pEventAction( new Action::EventAction( shared_from_this(), eventId, action,
finishCallback, interruptCallback, additional ) );
setCurrentAction( pEventAction );
auto pEvent = getEvent( eventId );
if( !pEvent && getEventCount() )
{
// We're trying to play a nested event, need to start it first.
eventStart( getId(), eventId, Event::EventHandler::Nest, 0, 0 );
pEvent = getEvent( eventId );
}
else if( !pEvent )
{
g_log.error( "Could not find event " + std::to_string( eventId ) + ", event has not been started!" );
return;
}
if( pEvent )
pEvent->setPlayedScene( true );
pEventAction->onStart();
}
void Core::Entity::Player::eventItemActionStart( uint32_t eventId,
uint32_t action,
ActionCallback finishCallback,
ActionCallback interruptCallback,
uint64_t additional )
{
Action::ActionPtr pEventItemAction( new Action::EventItemAction( shared_from_this(), eventId, action,
finishCallback, interruptCallback, additional ) );
setCurrentAction( pEventItemAction );
pEventItemAction->onStart();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Core::Entity::Player::onLogin()
{
for( auto& child : g_serverZone.getConfig()->getChild( "Settings.Parameters.MotDArray" ) )
{
sendNotice( child.second.data() );
}
}
void Core::Entity::Player::onZoneStart()
{
}
void Core::Entity::Player::onZoneDone()
{
}
void Core::Entity::Player::onDeath()
{
}
// TODO: slightly ugly here and way too static. Needs too be done properly
void Core::Entity::Player::onTick()
{
bool sendUpdate = false;
if( !isAlive() || !isLoadingComplete() )
return;
uint32_t addHp = static_cast< uint32_t >( getMaxHp() * 0.1f + 1 );
uint32_t addMp = static_cast< uint32_t >( getMaxMp() * 0.06f + 1 );
uint32_t addTp = 100;
if( !m_actorIdTohateSlotMap.empty() )
{
addHp = static_cast< uint32_t >( getMaxHp() * 0.01f + 1 );
addMp = static_cast< uint32_t >( getMaxMp() * 0.02f + 1 );
addTp = 60;
}
if( m_hp < getMaxHp() )
{
if( m_hp + addHp < getMaxHp() )
m_hp += addHp;
else
m_hp = getMaxHp();
sendUpdate = true;
}
if( m_mp < getMaxMp() )
{
if( m_mp + addMp < getMaxMp() )
m_mp += addMp;
else
m_mp = getMaxMp();
sendUpdate = true;
}
if( m_tp < 1000 )
{
if( m_tp + addTp < 1000 )
m_tp += addTp;
else
m_tp = 1000;
sendUpdate = true;
}
if( sendUpdate )
sendStatusUpdate();
}

View file

@ -0,0 +1,72 @@
#include "EventHelper.h"
#include "EventHandler.h"
#include <common/Common.h>
#include <common/Exd/ExdData.h>
extern Core::Data::ExdData g_exdData;
using namespace Core::Common;
std::string Core::Event::getEventName( uint32_t eventId )
{
uint16_t eventType = eventId >> 16;
auto unknown = std::string{ "unknown" };
switch( eventType )
{
case EventType::Quest:
{
auto questInfo = g_exdData.getQuestInfo( eventId );
if( !questInfo )
return unknown + "Quest";
std::string name = questInfo->name_intern;
std::size_t pos = name.find_first_of( "_" );
return questInfo->name_intern.substr( 0, pos );
}
case EventType::CustomTalk:
{
auto customTalkInfo = g_exdData.getCustomTalkInfo( eventId );
if( !customTalkInfo )
return unknown + "CustomTalk";
std::string name = customTalkInfo->name_intern;
std::size_t pos = name.find_first_of( "_" );
return customTalkInfo->name_intern.substr( 0, pos );
}
case EventType::Opening:
{
auto openingInfo = g_exdData.getOpeningInfo( eventId );
if( openingInfo )
return openingInfo->name;
return unknown + "Opening";
}
case EventType::Aetheryte:
{
auto aetherInfo = g_exdData.getAetheryteInfo( eventId & 0xFFFF );
if( aetherInfo->isAetheryte )
return "Aetheryte";
return "Aethernet";
}
case EventType::Warp:
{
return "ChocoboTaxi";
}
default:
{
return unknown;
}
}
}
uint32_t Core::Event::mapEventActorToRealActor( uint32_t eventActorId )
{
auto levelInfo = g_exdData.getLevelInfo( eventActorId );
if( levelInfo )
return levelInfo->actor_id;
return 0;
}

View file

@ -0,0 +1,81 @@
#ifndef _FORWARDS_H
#define _FORWARDS_H
#include <boost/shared_ptr.hpp>
#include <vector>
#define TYPE_FORWARD( x ) \
class x; \
typedef boost::shared_ptr< x > x ## Ptr; \
typedef std::vector< x > x ## PtrList;
namespace Core
{
TYPE_FORWARD( Cell );
TYPE_FORWARD( Zone );
TYPE_FORWARD( Item );
TYPE_FORWARD( ItemContainer );
TYPE_FORWARD( Inventory );
TYPE_FORWARD( Session );
TYPE_FORWARD( XMLConfig );
TYPE_FORWARD( ZonePosition )
namespace StatusEffect
{
TYPE_FORWARD( StatusEffect );
TYPE_FORWARD( StatusEffectContainer );
}
namespace Entity
{
TYPE_FORWARD( Actor );
TYPE_FORWARD( Player );
TYPE_FORWARD( BattleNpc );
TYPE_FORWARD( BattleNpcTemplate );
}
namespace Event
{
TYPE_FORWARD( EventHandler );
}
namespace Action
{
TYPE_FORWARD( Action );
TYPE_FORWARD( ActionTeleport );
TYPE_FORWARD( ActionCast );
TYPE_FORWARD( ActionMount );
TYPE_FORWARD( EventAction );
}
namespace Network
{
TYPE_FORWARD( Hive );
TYPE_FORWARD( Acceptor );
TYPE_FORWARD( Connection );
TYPE_FORWARD( GameConnection );
TYPE_FORWARD( SessionConnection );
TYPE_FORWARD( CustomMsgClientConnection );
namespace Packets
{
TYPE_FORWARD( GamePacket );
}
}
namespace ContentFinder
{
TYPE_FORWARD( ContentFinder );
}
namespace Scripting
{
class NativeScriptManager;
}
typedef std::function< void( Entity::Player&, uint32_t, uint64_t ) > ActionCallback;
}
#endif

View file

@ -0,0 +1,483 @@
#include <common/Logging/Logger.h>
#include <common/Exd/ExdData.h>
#include <common/Config/XMLConfig.h>
#include "NativeScriptManager.h"
#include "Zone/Zone.h"
#include "Actor/Player.h"
#include "Actor/BattleNpc.h"
#include "ServerZone.h"
#include "Event/EventHandler.h"
#include "Event/EventHelper.h"
#include "StatusEffect/StatusEffect.h"
#include "Network/PacketWrappers/ServerNoticePacket.h"
#include "Script/ScriptManager.h"
#include <boost/lexical_cast.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
#include <boost/format.hpp>
#include <boost/foreach.hpp>
// enable the ambiguity fix for every platform to avoid #define nonsense
#define WIN_AMBIGUITY_FIX
#include <libraries/external/watchdog/Watchdog.h>
extern Core::Logger g_log;
extern Core::Data::ExdData g_exdData;
extern Core::ServerZone g_serverZone;
Core::Scripting::ScriptManager::ScriptManager() :
m_firstScriptChangeNotificiation( false )
{
m_nativeScriptManager = createNativeScriptMgr();
}
Core::Scripting::ScriptManager::~ScriptManager()
{
Watchdog::unwatchAll();
}
void Core::Scripting::ScriptManager::update()
{
m_nativeScriptManager->processLoadQueue();
}
bool Core::Scripting::ScriptManager::init()
{
std::set< std::string > files;
loadDir( g_serverZone.getConfig()->getValue< std::string >( "Settings.General.Scripts.Path", "./compiledscripts/" ),
files, m_nativeScriptManager->getModuleExtension() );
uint32_t scriptsFound = 0;
uint32_t scriptsLoaded = 0;
for( auto itr = files.begin(); itr != files.end(); ++itr )
{
auto& path = *itr;
scriptsFound++;
if( m_nativeScriptManager->loadScript( path ) )
scriptsLoaded++;
}
g_log.info( "ScriptManager: Loaded " + std::to_string( scriptsLoaded ) + "/" + std::to_string( scriptsFound ) + " scripts successfully" );
watchDirectories();
return true;
}
void Core::Scripting::ScriptManager::watchDirectories()
{
Watchdog::watchMany( g_serverZone.getConfig()->getValue< std::string >( "Settings.General.Scripts.Path", "./compiledscripts/" ) + "*" + m_nativeScriptManager->getModuleExtension(),
[ this ]( const std::vector< ci::fs::path >& paths )
{
if( !m_firstScriptChangeNotificiation )
{
// for whatever reason, the first time this runs, it detects every file as changed
// so we're always going to ignore the first notification
m_firstScriptChangeNotificiation = true;
return;
}
for( auto path : paths )
{
if( m_nativeScriptManager->isModuleLoaded( path.stem().string() ) )
{
g_log.debug( "Reloading changed script: " + path.stem().string() );
m_nativeScriptManager->queueScriptReload( path.stem( ).string( ));
}
else
{
g_log.debug( "Loading new script: " + path.stem().string() );
m_nativeScriptManager->loadScript( path.string() );
}
}
});
}
void Core::Scripting::ScriptManager::loadDir( const std::string& dirname, std::set<std::string> &files, const std::string& ext )
{
g_log.info( "ScriptEngine: loading scripts from " + dirname );
boost::filesystem::path targetDir( dirname );
boost::filesystem::directory_iterator iter( targetDir );
boost::filesystem::directory_iterator eod;
BOOST_FOREACH( boost::filesystem::path const& i, make_pair( iter, eod ) )
{
if( is_regular_file( i ) && boost::filesystem::extension( i.string() ) == ext )
{
files.insert( i.string() );
}
}
}
void Core::Scripting::ScriptManager::onPlayerFirstEnterWorld( Entity::Player& player )
{
// try
// {
// std::string test = m_onFirstEnterWorld( player );
// }
// catch( const std::exception &e )
// {
// std::string what = e.what();
// g_log.Log( LoggingSeverity::error, what );
// }
}
bool Core::Scripting::ScriptManager::registerBnpcTemplate( std::string templateName, uint32_t bnpcBaseId,
uint32_t bnpcNameId, uint32_t modelId, std::string aiName )
{
return g_serverZone.registerBnpcTemplate( templateName, bnpcBaseId, bnpcNameId, modelId, aiName );
}
bool Core::Scripting::ScriptManager::onTalk( Entity::Player& player, uint64_t actorId, uint32_t eventId )
{
std::string eventName = "onTalk";
std::string objName = Event::getEventName( eventId );
player.sendDebug( "Actor: " +
std::to_string( actorId ) + " -> " +
std::to_string( Event::mapEventActorToRealActor( static_cast< uint32_t >( actorId ) ) ) +
" \neventId: " +
std::to_string( eventId ) +
" (0x" + boost::str( boost::format( "%|08X|" )
% static_cast< uint64_t >( eventId & 0xFFFFFFF ) ) + ")" );
uint16_t eventType = eventId >> 16;
uint32_t scriptId = eventId;
// aethernet/aetherytes need to be handled separately
if( eventType == Common::EventType::Aetheryte )
{
auto aetherInfo = g_exdData.getAetheryteInfo( eventId & 0xFFFF );
scriptId = EVENTSCRIPT_AETHERYTE_ID;
if( !aetherInfo->isAetheryte )
scriptId = EVENTSCRIPT_AETHERNET_ID;
}
auto script = m_nativeScriptManager->getScript< EventScript >( ScriptType::ScriptedEvent, scriptId );
if( script )
{
player.sendDebug( "Calling: " + objName + "." + eventName );
player.eventStart( actorId, eventId, Event::EventHandler::Talk, 0, 0 );
script->onTalk( eventId, player, actorId );
player.checkEvent( eventId );
}
else
{
if ( eventType == Common::EventType::Quest )
{
auto questInfo = g_exdData.getQuestInfo( eventId );
if ( questInfo )
{
player.sendUrgent( "Quest not implemented: " + questInfo->name + " (" + questInfo->name_intern + ")" );
}
}
return false;
}
return true;
}
bool Core::Scripting::ScriptManager::onEnterTerritory( Entity::Player& player, uint32_t eventId,
uint16_t param1, uint16_t param2 )
{
std::string eventName = "onEnterTerritory";
std::string objName = Event::getEventName( eventId );
player.sendDebug( "Calling: " + objName + "." + eventName + " - " + std::to_string( eventId ) );
auto script = m_nativeScriptManager->getScript< EventScript >( ScriptType::ScriptedEvent, eventId );
if( script )
{
player.eventStart( player.getId(), eventId, Event::EventHandler::EnterTerritory, 0, player.getZoneId() );
script->onEnterZone( player, eventId, param1, param2 );
player.checkEvent( eventId );
return true;
}
return false;
}
bool Core::Scripting::ScriptManager::onWithinRange( Entity::Player& player, uint32_t eventId, uint32_t param1,
float x, float y, float z )
{
std::string eventName = "onWithinRange";
std::string objName = Event::getEventName( eventId );
player.sendDebug( "Calling: " + objName + "." + eventName + " - " + std::to_string( eventId ) + " p1: " + std::to_string( param1 ) );
auto script = m_nativeScriptManager->getScript< EventScript >( ScriptType::ScriptedEvent, eventId );
if( script )
{
player.eventStart( player.getId(), eventId, Event::EventHandler::WithinRange, 1, param1 );
script->onWithinRange( player, eventId, param1, x, y, z );
player.checkEvent( eventId );
return true;
}
return false;
}
bool Core::Scripting::ScriptManager::onOutsideRange( Entity::Player& player, uint32_t eventId, uint32_t param1,
float x, float y, float z )
{
std::string eventName = "onOutsideRange";
std::string objName = Event::getEventName( eventId );
player.sendDebug( "Calling: " + objName + "." + eventName + " - " + std::to_string( eventId ) );
auto script = m_nativeScriptManager->getScript< EventScript >( ScriptType::ScriptedEvent, eventId );
if( script )
{
player.eventStart( player.getId(), eventId, Event::EventHandler::WithinRange, 1, param1 );
script->onOutsideRange( player, eventId, param1, x, y, z );
player.checkEvent( eventId );
return true;
}
return false;
}
bool Core::Scripting::ScriptManager::onEmote( Entity::Player& player, uint64_t actorId,
uint32_t eventId, uint8_t emoteId )
{
std::string eventName = "onEmote";
std::string objName = Event::getEventName( eventId );
auto script = m_nativeScriptManager->getScript< EventScript >( ScriptType::ScriptedEvent, eventId );
if( script )
{
player.sendDebug( "Calling: " + objName + "." + eventName );
player.eventStart( actorId, eventId, Event::EventHandler::Emote, 0, emoteId );
script->onEmote( actorId, eventId, emoteId, player );
player.checkEvent( eventId );
}
else
{
uint16_t eventType = eventId >> 16;
if( eventType == Common::EventType::Quest )
{
auto questInfo = g_exdData.getQuestInfo( eventId );
if( questInfo )
{
player.sendUrgent( "Quest not implemented: " + questInfo->name );
return false;
}
}
return false;
}
return true;
}
bool Core::Scripting::ScriptManager::onEventHandlerReturn( Entity::Player& player, uint32_t eventId,
uint16_t subEvent, uint16_t param1, uint16_t param2,
uint16_t param3 )
{
player.sendDebug( "eventId: " +
std::to_string( eventId ) +
" ( 0x" + boost::str( boost::format( "%|08X|" ) % ( uint64_t ) ( eventId & 0xFFFFFFF ) ) + " ) " +
" scene: " + std::to_string( subEvent ) +
" p1: " + std::to_string( param1 ) +
" p2: " + std::to_string( param2 ) +
" p3: " + std::to_string( param3 ) );
try
{
auto pEvent = player.getEvent( eventId );
if( pEvent )
{
pEvent->setPlayedScene( false );
// try to retrieve a stored callback
auto eventCallback = pEvent->getEventReturnCallback();
// if there is one, proceed to call it
if( eventCallback )
{
eventCallback( player, eventId, param1, param2, param3 );
if( !pEvent->hasPlayedScene() )
player.eventFinish( eventId, 1 );
else
pEvent->setPlayedScene( false );
}
// else, finish the event.
else
player.eventFinish( eventId, 1 );
}
}
catch( std::exception& e )
{
player.sendNotice( e.what() );
return false;
}
return true;
}
bool Core::Scripting::ScriptManager::onEventHandlerTradeReturn( Entity::Player& player, uint32_t eventId,
uint16_t subEvent, uint16_t param, uint32_t catalogId )
{
auto script = m_nativeScriptManager->getScript< EventScript >( ScriptType::ScriptedEvent, eventId );
if( script )
{
script->onEventHandlerTradeReturn( player, eventId, subEvent, param, catalogId );
return true;
}
return false;
}
bool Core::Scripting::ScriptManager::onEventItem( Entity::Player& player, uint32_t eventItemId,
uint32_t eventId, uint32_t castTime, uint64_t targetId )
{
std::string eventName = "onEventItem";
std::string objName = Event::getEventName( eventId );
player.sendDebug( "Calling: " + objName + "." + eventName + " - " + std::to_string( eventId ) );
auto script = m_nativeScriptManager->getScript< EventScript >( ScriptType::ScriptedEvent, eventId );
if( script )
{
player.eventStart( targetId, eventId, Event::EventHandler::Item, 0, 0 );
script->onEventItem( player, eventItemId, eventId, castTime, targetId );
return true;
}
return false;
}
bool Core::Scripting::ScriptManager::onMobKill( Entity::Player& player, uint16_t nameId )
{
std::string eventName = "onBnpcKill_" + std::to_string( nameId );
// loop through all active quests and try to call available onMobKill callbacks
for( size_t i = 0; i < 30; i++ )
{
auto activeQuests = player.getQuestActive( static_cast< uint16_t >( i ) );
if( !activeQuests )
continue;
uint16_t questId = activeQuests->c.questId;
auto script = m_nativeScriptManager->getScript< EventScript >( ScriptType::ScriptedEvent, questId );
if( script )
{
std::string objName = Event::getEventName( 0x00010000 | questId );
player.sendDebug("Calling: " + objName + "." + eventName);
script->onNpcKill( nameId, player );
}
}
return true;
}
bool Core::Scripting::ScriptManager::onCastFinish( Entity::Player& player, Entity::ActorPtr pTarget, uint32_t actionId )
{
auto script = m_nativeScriptManager->getScript< ActionScript >( ScriptType::ScriptedAction, actionId );
if( script )
script->onCastFinish( player, *pTarget );
return true;
}
bool Core::Scripting::ScriptManager::onStatusReceive( Entity::ActorPtr pActor, uint32_t effectId )
{
auto script = m_nativeScriptManager->getScript< StatusEffectScript >( ScriptType::ScriptedStatusEffect, effectId );
if( script )
{
if( pActor->isPlayer() )
pActor->getAsPlayer()->sendDebug( "Calling status receive for statusid: " + std::to_string( effectId ) );
script->onApply( *pActor );
return true;
}
return false;
}
bool Core::Scripting::ScriptManager::onStatusTick( Entity::ActorPtr pActor, Core::StatusEffect::StatusEffect& effect )
{
auto script = m_nativeScriptManager->getScript< StatusEffectScript >( ScriptType::ScriptedStatusEffect, effect.getId() );
if( script )
{
if( pActor->isPlayer() )
pActor->getAsPlayer()->sendDebug( "Calling status tick for statusid: " + std::to_string( effect.getId() ) );
script->onTick( *pActor );
return true;
}
return false;
}
bool Core::Scripting::ScriptManager::onStatusTimeOut( Entity::ActorPtr pActor, uint32_t effectId )
{
auto script = m_nativeScriptManager->getScript< StatusEffectScript >( ScriptType::ScriptedStatusEffect, effectId );
if( script )
{
if( pActor->isPlayer() )
pActor->getAsPlayer()->sendDebug( "Calling status timeout for statusid: " + std::to_string( effectId ) );
script->onExpire( *pActor );
return true;
}
return false;
}
bool Core::Scripting::ScriptManager::onZoneInit( ZonePtr pZone )
{
auto script = m_nativeScriptManager->getScript< ZoneScript >( ScriptType::ScriptedZone, pZone->getId() );
if( script )
{
script->onZoneInit();
return true;
}
return false;
}
Scripting::NativeScriptManager& Core::Scripting::ScriptManager::getNativeScriptHandler()
{
return *m_nativeScriptManager;
}

View file

@ -1,197 +1 @@
#include "Director.h" #include "Director.h"
#include <Network/PacketDef/Ipcs.h>
#include <Network/PacketDef/Zone/ServerZoneDef.h>
#include <Network/CommonActorControl.h>
#include "Actor/Player.h"
#include "Network/PacketWrappers/ActorControlPacket.h"
#include "Network/PacketWrappers/ActorControlSelfPacket.h"
#include <Logging/Logger.h>
using namespace Sapphire::Common;
using namespace Sapphire::Network::Packets;
using namespace Sapphire::Network::Packets::Server;
using namespace Sapphire::Network::ActorControl;
Sapphire::Event::Director::Director( Sapphire::Event::Director::DirectorType type, uint16_t contentId ) :
m_contentId( contentId ),
m_type( type ),
m_directorId( ( static_cast< uint32_t >( type ) << 16 ) | contentId ),
m_sequence( 1 ),
m_branch( 0 ),
m_elapsedTime( 0 )
{
memset( m_unionData.arrData, 0, sizeof( m_unionData ) );
}
uint32_t Sapphire::Event::Director::getDirectorId() const
{
return m_directorId;
}
uint16_t Sapphire::Event::Director::getContentId() const
{
return m_contentId;
}
uint8_t Sapphire::Event::Director::getSequence() const
{
return m_sequence;
}
void Sapphire::Event::Director::sendDirectorClear( Sapphire::Entity::Player& player ) const
{
player.queuePacket( makeActorControlSelf( player.getId(), DirectorClear, m_directorId ) );
}
void Sapphire::Event::Director::sendDirectorVars( Sapphire::Entity::Player& player ) const
{
auto varPacket = makeZonePacket< FFXIVIpcDirectorVars >( player.getId() );
varPacket->data().m_directorId = getDirectorId();
varPacket->data().m_sequence = getSequence();
varPacket->data().m_branch = 0;
memcpy( varPacket->data().m_unionData, m_unionData.arrData, sizeof( varPacket->data().m_unionData ) );
player.queuePacket( varPacket );
}
void Sapphire::Event::Director::sendDirectorInit( Sapphire::Entity::Player& player ) const
{
Logger::debug( "DirectorID#{}, QuestBattleID#{}", m_directorId, m_contentId );
player.queuePacket( makeActorControlSelf( player.getId(), DirectorInit, m_directorId, m_contentId ) );
}
Sapphire::Event::Director::DirectorType Sapphire::Event::Director::getType() const
{
return m_type;
}
uint8_t Sapphire::Event::Director::getBranch() const
{
return m_branch;
}
void Sapphire::Event::Director::setDirectorUI8AL( uint8_t value )
{
m_unionData.ui8lh.UI8AL = value;
}
void Sapphire::Event::Director::setDirectorUI8AH( uint8_t value )
{
m_unionData.ui8lh.UI8AH = value;
}
void Sapphire::Event::Director::setDirectorUI8BL( uint8_t value )
{
m_unionData.ui8lh.UI8BL = value;
}
void Sapphire::Event::Director::setDirectorUI8BH( uint8_t value )
{
m_unionData.ui8lh.UI8BH = value;
}
void Sapphire::Event::Director::setDirectorUI8CL( uint8_t value )
{
m_unionData.ui8lh.UI8CL = value;
}
void Sapphire::Event::Director::setDirectorUI8CH( uint8_t value )
{
m_unionData.ui8lh.UI8CH = value;
}
void Sapphire::Event::Director::setDirectorUI8DL( uint8_t value )
{
m_unionData.ui8lh.UI8DL = value;
}
void Sapphire::Event::Director::setDirectorUI8DH( uint8_t value )
{
m_unionData.ui8lh.UI8DH = value;
}
void Sapphire::Event::Director::setDirectorUI8EL( uint8_t value )
{
m_unionData.ui8lh.UI8EL = value;
}
void Sapphire::Event::Director::setDirectorUI8EH( uint8_t value )
{
m_unionData.ui8lh.UI8EH = value;
}
void Sapphire::Event::Director::setDirectorUI8FL( uint8_t value )
{
m_unionData.ui8lh.UI8FL = value;
}
void Sapphire::Event::Director::setDirectorUI8FH( uint8_t value )
{
m_unionData.ui8lh.UI8FH = value;
}
void Sapphire::Event::Director::setDirectorUI8GL( uint8_t value )
{
m_unionData.ui8lh.UI8GL = value;
}
void Sapphire::Event::Director::setDirectorUI8GH( uint8_t value )
{
m_unionData.ui8lh.UI8GH = value;
}
void Sapphire::Event::Director::setDirectorUI8HL( uint8_t value )
{
m_unionData.ui8lh.UI8HL = value;
}
void Sapphire::Event::Director::setDirectorUI8HH( uint8_t value )
{
m_unionData.ui8lh.UI8HH = value;
}
void Sapphire::Event::Director::setDirectorUI8IL( uint8_t value )
{
m_unionData.ui8lh.UI8IL = value;
}
void Sapphire::Event::Director::setDirectorUI8IH( uint8_t value )
{
m_unionData.ui8lh.UI8IH = value;
}
void Sapphire::Event::Director::setDirectorUI8JL( uint8_t value )
{
m_unionData.ui8lh.UI8JL = value;
}
void Sapphire::Event::Director::setDirectorUI8JH( uint8_t value )
{
m_unionData.ui8lh.UI8JH = value;
}
void Sapphire::Event::Director::setDirectorBranch( uint8_t value )
{
m_branch = value;
}
void Sapphire::Event::Director::setDirectorSequence( uint8_t value )
{
m_sequence = value;
}
void Sapphire::Event::Director::setCustomVar( uint32_t varId, uint32_t value )
{
m_customVarMap[ varId ] = value;
}
uint32_t Sapphire::Event::Director::getCustomVar( uint32_t varId )
{
auto it = m_customVarMap.find( varId );
if( it != m_customVarMap.end() )
return it->second;
return 0;
}

View file

@ -1,192 +1,45 @@
#ifndef SAPPHIRE_DIRECTOR_H #ifndef SAPPHIRE_DIRECTOR_H
#define SAPPHIRE_DIRECTOR_H #define SAPPHIRE_DIRECTOR_H
#include <Common.h> #include <common/Common.h>
#include "ForwardsZone.h" #include "Forwards.h"
namespace Sapphire::Event namespace Core {
namespace Event {
/*!
\class Director
\brief Base class for all Directors implements sequence and variables
\author Mordred
*/
class Director
{ {
private:
/*! Id of the director */
uint32_t m_id;
/*! /*! currect sequence */
\class Director uint8_t m_sequence;
\brief Base class for all Directors implements sequence and variables
*/ /*! current branch */
uint8_t m_branch;
class Director /*! raw storage for flags/vars */
{ uint8_t m_unionData[10];
public: public:
enum DirectorType uint8_t getId() const;
{ uint8_t getSequence() const;
BattleLeve = 0x8001,
GatheringLeve = 0x8002,
InstanceContent = 0x8003, // used for dungeons/raids
PublicContent = 0x8004,
QuestBattle = 0x8006,
CompanyLeve = 0x8007,
TreasureHunt = 0x8009,
GoldSaucer = 0x800A,
CompanyCraftDirector = 0x800B,
DpsChallange = 0x800D,
Fate = 0x801A
};
enum DirectorState };
{
Created,
DutyReset,
DutyInProgress,
DutyFinished,
DutyFailed
};
Director( DirectorType type, uint16_t contentId );
uint32_t getDirectorId() const;
uint16_t getContentId() const;
DirectorType getType() const;
uint8_t getSequence() const;
uint8_t getBranch() const;
void sendDirectorInit( Entity::Player& player ) const;
void sendDirectorClear( Entity::Player& player ) const;
void sendDirectorVars( Entity::Player& player ) const;
void setDirectorUI8AL( uint8_t value );
void setDirectorUI8AH( uint8_t value );
void setDirectorUI8BL( uint8_t value );
void setDirectorUI8BH( uint8_t value );
void setDirectorUI8CL( uint8_t value );
void setDirectorUI8CH( uint8_t value );
void setDirectorUI8DL( uint8_t value );
void setDirectorUI8DH( uint8_t value );
void setDirectorUI8EL( uint8_t value );
void setDirectorUI8EH( uint8_t value );
void setDirectorUI8FL( uint8_t value );
void setDirectorUI8FH( uint8_t value );
void setDirectorUI8GL( uint8_t value );
void setDirectorUI8GH( uint8_t value );
void setDirectorUI8HL( uint8_t value );
void setDirectorUI8HH( uint8_t value );
void setDirectorUI8IL( uint8_t value );
void setDirectorUI8IH( uint8_t value );
void setDirectorUI8JL( uint8_t value );
void setDirectorUI8JH( uint8_t value );
void setDirectorSequence( uint8_t value );
void setDirectorBranch( uint8_t value );
void setCustomVar( uint32_t varId, uint32_t value );
uint32_t getCustomVar( uint32_t varId );
private:
/*! Id of the content of the director */
uint16_t m_contentId;
/*! DirectorType | ContentId */
uint32_t m_directorId;
/*! currect sequence */
uint8_t m_sequence;
/*! current branch */
uint8_t m_branch;
union
{
struct UI8LH
{
uint8_t UI8AL : 4;
uint8_t UI8AH : 4;
uint8_t UI8BL : 4;
uint8_t UI8BH : 4;
uint8_t UI8CL : 4;
uint8_t UI8CH : 4;
uint8_t UI8DL : 4;
uint8_t UI8DH : 4;
uint8_t UI8EL : 4;
uint8_t UI8EH : 4;
uint8_t UI8FL : 4;
uint8_t UI8FH : 4;
uint8_t UI8GL : 4;
uint8_t UI8GH : 4;
uint8_t UI8HL : 4;
uint8_t UI8HH : 4;
uint8_t UI8IL : 4;
uint8_t UI8IH : 4;
uint8_t UI8JL : 4;
uint8_t UI8JH : 4;
} ui8lh;
struct UI8
{
uint8_t UI8A;
uint8_t UI8B;
uint8_t UI8C;
uint8_t UI8D;
uint8_t UI8E;
uint8_t UI8F;
uint8_t UI8G;
uint8_t UI8H;
uint8_t UI8I;
uint8_t UI8J;
} ui8;
struct FLAGS
{
uint8_t flags80;
uint8_t flags72;
uint8_t flags64;
uint8_t flags56;
uint8_t flags48;
uint8_t flags40;
uint8_t flags32;
uint8_t flags24;
uint8_t flags16;
uint8_t flags8;
} flags;
/*! raw storage for flags/vars */
uint8_t arrData[10];
} m_unionData;
/*! type of the director */
DirectorType m_type;
uint32_t m_elapsedTime;
std::unordered_map< uint32_t, uint32_t > m_customVarMap;
};
} }
}
#endif //SAPPHIRE_DIRECTOR_H #endif //SAPPHIRE_DIRECTOR_H

View file

@ -1,95 +1,65 @@
#include "EventHandler.h" #include "EventHandler.h"
Sapphire::Event::EventHandler::EventHandler( uint64_t actorId, uint32_t eventId, Core::Event::EventHandler::EventHandler( uint64_t actorId, uint32_t eventId, EventType eventType, uint32_t eventParam3 ) :
EventType eventType, uint32_t eventParam ) : m_actorId( actorId ),
m_actorId( actorId ), m_eventId( eventId ),
m_eventId( eventId ), m_eventType( eventType ),
m_eventType( eventType ), m_playedScene( false )
m_playedScene( false )
{ {
m_entryId = static_cast< uint16_t >( eventId ); m_entryId = static_cast< uint16_t >( eventId );
m_type = static_cast< uint16_t >( eventId >> 16 ); m_type = static_cast< uint16_t >( eventId >> 16 );
m_eventParam = eventParam;
m_returnCallback = nullptr; m_eventParam3 = eventParam3;
m_callback = nullptr;
} }
uint64_t Sapphire::Event::EventHandler::getActorId() const uint64_t Core::Event::EventHandler::getActorId() const
{ {
return m_actorId; return m_actorId;
} }
uint32_t Sapphire::Event::EventHandler::getId() const uint32_t Core::Event::EventHandler::getId() const
{ {
return m_eventId; return m_eventId;
} }
uint8_t Sapphire::Event::EventHandler::getEventType() const uint8_t Core::Event::EventHandler::getEventType() const
{ {
return m_eventType; return m_eventType;
} }
uint16_t Sapphire::Event::EventHandler::getType() const uint16_t Core::Event::EventHandler::getType() const
{ {
return m_type; return m_type;
} }
uint16_t Sapphire::Event::EventHandler::getEntryId() const uint16_t Core::Event::EventHandler::getEntryId() const
{ {
return m_entryId; return m_entryId;
} }
uint32_t Sapphire::Event::EventHandler::getEventParam() const uint32_t Core::Event::EventHandler::getEventParam3() const
{ {
return m_eventParam; return m_eventParam3;
} }
Sapphire::Event::EventHandler::SceneReturnCallback Sapphire::Event::EventHandler::getEventReturnCallback() const Core::Event::EventHandler::SceneReturnCallback Core::Event::EventHandler::getEventReturnCallback() const
{ {
return m_returnCallback; return m_callback;
} }
void Sapphire::Event::EventHandler::setEventReturnCallback( SceneReturnCallback callback ) void Core::Event::EventHandler::setEventReturnCallback( SceneReturnCallback callback )
{ {
m_returnCallback = callback; m_callback = callback;
} }
Sapphire::Event::EventHandler::SceneChainCallback Sapphire::Event::EventHandler::getSceneChainCallback() const bool Core::Event::EventHandler::hasPlayedScene() const
{ {
return m_chainCallback; return m_playedScene;
} }
void Sapphire::Event::EventHandler::setSceneChainCallback( Sapphire::Event::EventHandler::SceneChainCallback callback ) void Core::Event::EventHandler::setPlayedScene( bool playedScene )
{ {
m_chainCallback = callback; m_playedScene = playedScene;
} }
Sapphire::Event::EventHandler::EventFinishCallback Sapphire::Event::EventHandler::getEventFinishCallback() const
{
return m_finishCallback;
}
void Sapphire::Event::EventHandler::setEventFinishCallback( EventFinishCallback callback )
{
m_finishCallback = callback;
}
bool Sapphire::Event::EventHandler::hasPlayedScene() const
{
return m_playedScene;
}
void Sapphire::Event::EventHandler::setPlayedScene( bool playedScene )
{
m_playedScene = playedScene;
}
bool Sapphire::Event::EventHandler::hasNestedEvent() const
{
return m_pNestedEvent != nullptr;
}
void Sapphire::Event::EventHandler::removeNestedEvent()
{
m_pNestedEvent.reset();
}

View file

@ -1,142 +1,106 @@
#ifndef _EVENT_H #ifndef _EVENT_H
#define _EVENT_H #define _EVENT_H
#include "ForwardsZone.h" #include "../Forwards.h"
namespace Sapphire::Event namespace Core {
{ namespace Event {
struct SceneResult class EventHandler
{ {
uint64_t actorId; public:
uint32_t eventId; enum EventType : uint8_t
uint16_t param1; {
uint16_t param2; Talk = 1,
uint16_t param3; Emote = 2,
uint16_t param4; DistanceBelow = 3,
}; DistanceOver = 4,
BattleReward = 5,
Craft = 6,
Nest = 7,
Item = 8,
Drop = 9,
WithinRange = 10,
OutsideRange = 11,
GameStart = 12,
GameProgress = 13,
EnterTerritory = 15,
GameComeBack = 17,
ActionResult = 18,
MateriaCraft = 19,
Fishing = 20,
UI = 21,
Housing = 22,
Say = 23,
TableGame = 24,
};
class EventHandler enum EventHandlerType : uint16_t
{ {
public: Quest = 0x0001,
enum EventType : uint8_t Warp = 0x0002,
{ Shop = 0x0004,
Talk = 1, Aetheryte = 0x0005,
Emote = 2, GuildLeveAssignment = 0x0006,
DistanceBelow = 3, DefaultTalk = 0x0009,
DistanceOver = 4, CustomTalk = 0x000B,
BattleReward = 5, CompanyLeveOfficer = 0x000C,
Craft = 6, CraftLeve = 0x000E,
Nest = 7, GimmickAccessor = 0x000F,
Item = 8, GimmickBill = 0x0010,
Drop = 9, GimmickRect = 0x0011,
WithinRange = 10, ChocoboTaxiStand = 0x0012,
OutsideRange = 11, Opening = 0x0013,
GameStart = 12, ExitRange = 0x0014,
GameProgress = 13, GCShop = 0x0016,
EnterTerritory = 15, GuildOrderGuide = 0x0017,
GameComeBack = 17, GuildOrderOfficer = 0x0018,
ActionResult = 18, ContentNpc = 0x0019,
MateriaCraft = 19, Story = 0x001A,
Fishing = 20, SpecialShop = 0x001B,
UI = 21, BahamutGuide = 0x001C,
Housing = 22, FcTalk = 0x001F,
Say = 23, };
TableGame = 24,
};
enum class EventHandlerType : uint16_t using SceneReturnCallback = std::function< void( Entity::Player&, uint32_t, uint16_t, uint16_t, uint16_t ) > ;
{
Quest = 0x0001,
Warp = 0x0002,
GatheringPoint = 0x0003, // Came up in the client with "Begin" unsure that means
Shop = 0x0004,
Aetheryte = 0x0005,
GuildLeveAssignment = 0x0006,
DefaultTalk = 0x0009,
Craft = 0x000A,
CustomTalk = 0x000B,
CompanyLeveOfficer = 0x000C,
Array = 0x000D,
CraftLeve = 0x000E,
GimmickAccessor = 0x000F,
GimmickBill = 0x0010,
GimmickRect = 0x0011,
ChocoboTaxiStand = 0x0012,
Opening = 0x0013,
ExitRange = 0x0014,
Fishing = 0x0015,
GCShop = 0x0016,
GuildOrderGuide = 0x0017,
GuildOrderOfficer = 0x0018,
ContentNpc = 0x0019,
Story = 0x001A,
SpecialShop = 0x001B,
BahamutGuide = 0x001C,
InstanceContentGuide = 0x001D,
HousingAethernet = 0x001E,
FcTalk = 0x001F,
Adventure = 0x0021,
DailyQuestSupply = 0x0022,
ICDirector = 0x8003,
QuestBattleDirector = 0x8006,
};
using SceneReturnCallback = std::function< void( Entity::Player&, const SceneResult& ) >; EventHandler( uint64_t actorId, uint32_t eventId, EventType eventType, uint32_t eventParam3 );
using SceneChainCallback = std::function< void( Entity::Player& ) >;
using EventFinishCallback = std::function< void( Entity::Player&, uint64_t ) >;
EventHandler( uint64_t actorId, uint32_t eventId, EventType eventType, uint32_t eventParam ); ~EventHandler() {}
~EventHandler() uint64_t getActorId() const;
{
}
uint64_t getActorId() const; uint32_t getId() const;
uint32_t getId() const; uint16_t getType() const;
uint16_t getType() const; uint16_t getEntryId() const;
uint16_t getEntryId() const; uint8_t getEventType() const;
uint8_t getEventType() const; uint32_t getEventParam3() const;
uint32_t getEventParam() const; bool hasPlayedScene() const;
bool hasPlayedScene() const; void setPlayedScene( bool playedScene );
void setPlayedScene( bool playedScene ); SceneReturnCallback getEventReturnCallback() const;
SceneReturnCallback getEventReturnCallback() const; void setEventReturnCallback( SceneReturnCallback callback );
void setEventReturnCallback( SceneReturnCallback callback );
SceneChainCallback getSceneChainCallback() const;
void setSceneChainCallback( SceneChainCallback callback ); protected:
uint64_t m_actorId;
EventFinishCallback getEventFinishCallback() const; uint32_t m_eventId;
uint16_t m_entryId;
void setEventFinishCallback( EventFinishCallback callback ); uint16_t m_type;
uint8_t m_eventType;
bool hasNestedEvent() const; uint32_t m_eventParam3;
bool m_playedScene;
void removeNestedEvent(); SceneReturnCallback m_callback;
};
protected:
uint64_t m_actorId;
uint32_t m_eventId;
uint16_t m_entryId;
uint16_t m_type;
uint8_t m_eventType;
uint32_t m_eventParam;
EventHandlerPtr m_pNestedEvent;
bool m_playedScene;
SceneReturnCallback m_returnCallback;
SceneChainCallback m_chainCallback;
EventFinishCallback m_finishCallback;
};
}
} }
#endif #endif