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

Merge pull request #524 from NotAdam/action_rewrite

WIP action rewrite
This commit is contained in:
Mordred 2019-03-08 00:08:10 +01:00 committed by GitHub
commit b4f1f3afe4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
57 changed files with 1180 additions and 2080 deletions

3
.gitignore vendored
View file

@ -23,8 +23,9 @@ src/tools/[Bb]in/exd_struct_gen
# decompiled scripts
src/tools/bin/generated/*
# Build Directory
# Build Directories
build/
build-*/
cmake-build-*/
# Prerequisites

View file

@ -525,8 +525,7 @@ namespace Sapphire::Common
};
enum struct ActionAspect :
uint8_t
enum struct ActionAspect : uint8_t
{
None = 0, // Doesn't imply unaspected
Fire = 1,
@ -538,6 +537,21 @@ namespace Sapphire::Common
Unaspected = 7 // Doesn't imply magical unaspected damage - could be unaspected physical
};
enum class ActionPrimaryCostType : uint8_t
{
None = 0, // ?
MagicPoints = 3,
TacticsPoints = 5,
// WARGauge = 22,
// DRKGauge = 25,
// AetherflowStack = 30,
// Status = 32,
// PLDGauge = 41,
// RDMGaugeBoth = 74,
//// RDMGaugeBlack = 75, // not right?
// DRGGauge3Eyes = 76,
};
enum class ActionType : int8_t
{
WeaponOverride = -1, // Needs more investigation (takes the damage type of the equipped weapon)?
@ -584,6 +598,11 @@ namespace Sapphire::Common
CritDirectHitDamage = 3
};
enum ItemActionType : uint16_t
{
ItemActionVFX = 944,
};
enum ActionEffectDisplayType : uint8_t
{
HideActionName = 0,
@ -591,6 +610,22 @@ namespace Sapphire::Common
ShowItemName = 2,
};
struct EffectEntry
{
Common::ActionEffectType effectType;
Common::ActionHitSeverityType hitSeverity;
uint8_t param;
/*!
* @brief Shows an additional percentage in the battle log
*
* Has no effect on what is shown and stored in value
*/
int8_t bonusPercent;
uint8_t valueMultiplier; // This multiplies whatever value is in the 'value' param by 10. Possibly a workaround for big numbers
uint8_t flags;
int16_t value;
};
enum class ActionCollisionType : uint8_t
{
None,
@ -604,6 +639,13 @@ namespace Sapphire::Common
Unknown3
};
enum class ActionInterruptType : uint8_t
{
None,
RegularInterrupt,
DamageInterrupt,
};
enum HandleActionType : uint8_t
{
Event,
@ -889,6 +931,12 @@ namespace Sapphire::Common
IsFreeCompanyEstate = 16,
};
struct PlayerTeleportQuery
{
uint16_t targetAetheryte;
uint16_t cost;
};
using PlayerStateFlagList = std::vector< PlayerStateFlag >;
}

View file

@ -35,6 +35,13 @@ enum ActorControlType : uint16_t
DeathAnimation = 0x0E,
CastInterrupt = 0x0F,
/*!
* @brief Sent when a player uses an action
*
* param1 Seems to be always 1 from what I've seen, needs more research
* param2 The actionid
* param3 The action cooldown in ms / 10
*/
ActionStart = 0x11,
StatusEffectGain = 0x14,

View file

@ -304,6 +304,7 @@ namespace Sapphire::Network::Packets
SkillHandler = 0x013B, // updated 4.5
GMCommand1 = 0x013C, // updated 4.5
GMCommand2 = 0x013D, // updated 4.5
AoESkillHandler = 0x13E, // updated 4.5
UpdatePositionHandler = 0x013F, // updated 4.5
UpdatePositionInstance = 0x0183, // updated 4.3

View file

@ -63,13 +63,29 @@ struct FFXIVIpcUpdatePosition :
struct FFXIVIpcSkillHandler :
FFXIVIpcBasePacket< SkillHandler >
{
/* 0000 */ char pad_0000[1];
/* 0000 */ uint8_t pad_0000;
/* 0001 */ uint8_t type;
/* 0002 */ char pad_0002[2];
/* 0002 */ uint8_t pad_0002[2];
/* 0004 */ uint32_t actionId;
/* 0008 */ uint32_t useCount;
/* 000C */ char pad_000C[4];
/* 0008 */ uint16_t sequence;
/* 000A */ uint8_t pad_000C[6];
/* 0010 */ uint64_t targetId;
/* 0018 */ uint16_t itemSourceSlot;
/* 001A */ uint16_t itemSourceContainer;
/* 001C */ uint32_t unknown;
};
struct FFXIVIpcAoESkillHandler :
FFXIVIpcBasePacket< AoESkillHandler >
{
/* 0000 */ uint8_t pad_0000;
/* 0001 */ uint8_t type;
/* 0002 */ uint8_t pad_0002[2];
/* 0004 */ uint32_t actionId;
/* 0008 */ uint16_t sequence;
/* 000A */ uint8_t pad_000C[6];
/* 0010 */ Common::FFXIVARR_POSITION3 pos;
/* 001C */ uint32_t unknown; // could almost be rotation + 16 bits more padding?
};
struct FFXIVIpcZoneLineHandler :
@ -91,9 +107,9 @@ struct FFXIVIpcEventHandlerReturn :
/* 0004 */ uint16_t scene;
/* 0006 */ uint16_t param1;
/* 0008 */ uint16_t param2;
/* 000A */ char pad_000A[2];
/* 000A */ uint8_t pad_000A[2];
/* 000C */ uint16_t param3;
/* 000E */ char pad_000E[2];
/* 000E */ uint8_t pad_000E[2];
/* 0010 */ uint16_t param4;
};
@ -155,7 +171,7 @@ struct FFXIVIpcSetSearchInfo :
};
};
/* 0008 */ char pad_0008[9];
/* 0008 */ uint8_t pad_0008[9];
/* 0011 */ Common::ClientLanguage language;
/* 0012 */ char searchComment[193];
};
@ -175,9 +191,9 @@ struct FFXIVIpcTellHandler : FFXIVIpcBasePacket< TellReq >
struct FFXIVIpcChatHandler :
FFXIVIpcBasePacket< ChatHandler >
{
/* 0000 */ char pad_0000[4];
/* 0000 */ uint8_t pad_0000[4];
/* 0004 */ uint32_t sourceId;
/* 0008 */ char pad_0008[16];
/* 0008 */ uint8_t pad_0008[16];
/* 0018 */ Common::ChatType chatType;
/* 001A */ char message[1012];
};
@ -194,7 +210,7 @@ struct FFXIVIpcLinkshellEventHandler :
{
/* 0000 */ uint32_t eventId;
/* 0004 */ uint16_t scene;
/* 0006 */ char pad_0006[1];
/* 0006 */ uint8_t pad_0006[1];
/* 0007 */ char lsName[21];
};
@ -203,13 +219,13 @@ struct FFXIVIpcInventoryModifyHandler :
{
/* 0000 */ uint32_t seq;
/* 0004 */ Common::InventoryOperation action;
/* 0005 */ char pad_0005[7];
/* 0005 */ uint8_t pad_0005[7];
/* 000C */ uint16_t fromContainer;
/* 000E */ char pad_000E[2];
/* 000E */ uint8_t pad_000E[2];
/* 0010 */ uint8_t fromSlot;
/* 0011 */ char pad_0011[15];
/* 0011 */ uint8_t pad_0011[15];
/* 0020 */ uint16_t toContainer;
/* 0022 */ char pad_0022[2];
/* 0022 */ uint8_t pad_0022[2];
/* 0024 */ uint8_t toSlot;
/* 0025 */ uint8_t pad_0025[3];
/* 0028 */ uint32_t splitCount;
@ -245,11 +261,11 @@ struct FFXIVIpcSetSharedEstateSettings :
/* 0008 */ uint64_t char2ContentId;
/* 0010 */ uint64_t char3ContentId;
/* 0018 */ uint8_t char1Permissions;
/* 0019 */ char padding1[0x7];
/* 0019 */ uint8_t padding1[0x7];
/* 0020 */ uint8_t char2Permissions;
/* 0021 */ char padding2[0x7];
/* 0021 */ uint8_t padding2[0x7];
/* 0028 */ uint8_t char3Permissions;
/* 0029 */ char padding3[0x7];
/* 0029 */ uint8_t padding3[0x7];
};
struct FFXIVIpcMarketBoardRequestItemListings :

View file

@ -388,17 +388,6 @@ struct FFXIVIpcUpdateHpMpTp :
* Structural representation of the packet sent by the server
* for battle actions
*/
struct EffectEntry
{
Common::ActionEffectType effectType;
Common::ActionHitSeverityType hitSeverity;
uint8_t param;
int8_t bonusPercent; // shows an additional percentage in the battle log, will not change the damage number sent & shown
uint8_t valueMultiplier; // This multiplies whatever value is in the 'value' param by 10. Possibly a workaround for big numbers
uint8_t flags;
int16_t value;
};
struct EffectHeader
{
uint64_t animationTargetId; // who the animation targets
@ -426,7 +415,7 @@ struct FFXIVIpcEffect : FFXIVIpcBasePacket< Effect >
uint64_t animationTargetId; // who the animation targets
uint32_t actionId; // what the casting player casts, shown in battle log/ui
uint32_t globalEffectCounter; // seems to only increment on retail?
uint32_t sequence; // seems to only increment on retail?
float animationLockTime; // maybe? doesn't seem to do anything
uint32_t someTargetId; // always 00 00 00 E0, 0x0E000000 is the internal def for INVALID TARGET ID
@ -458,7 +447,7 @@ struct FFXIVIpcAoeEffect
{
EffectHeader header;
EffectEntry effects[size];
Common::EffectEntry effects[size];
uint16_t padding_6A[3];
@ -1154,15 +1143,15 @@ struct FFXIVIpcCurrencyCrystalInfo :
struct FFXIVIpcInventoryTransactionFinish :
FFXIVIpcBasePacket< InventoryTransactionFinish >
{
uint32_t transactionId;
uint32_t transactionId1;
uint32_t sequenceId;
uint32_t sequenceId1;
uint64_t padding;
};
struct FFXIVIpcInventoryTransaction :
FFXIVIpcBasePacket< InventoryTransaction >
{
uint32_t transactionId;
uint32_t sequence;
uint8_t type;
uint8_t padding;
uint16_t padding1;

View file

@ -1,19 +0,0 @@
#include <ScriptObject.h>
#include <Actor/Player.h>
class ActionSprint3 :
public Sapphire::ScriptAPI::ActionScript
{
public:
ActionSprint3() :
Sapphire::ScriptAPI::ActionScript( 3 )
{
}
void onCastFinish( Sapphire::Entity::Player& player, Sapphire::Entity::Chara& targetActor ) override
{
player.addStatusEffectByIdIfNotExist( 50, 20000, player, 30 );
}
};
EXPOSE_SCRIPT( ActionSprint3 );

View file

@ -1,17 +0,0 @@
#include <Script/NativeScriptApi.h>
extern Sapphire::ScriptAPI::ScriptObject* makeScriptActionReturn6();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptActionSprint3();
const Sapphire::ScriptAPI::ScriptObject* ptrs[] =
{
makeScriptActionReturn6(),
makeScriptActionSprint3(),
nullptr
};
extern "C" EXPORT const Sapphire::ScriptAPI::ScriptObject** getScripts()
{
return ptrs;
}

View file

@ -1,6 +1,7 @@
#include <Script/NativeScriptApi.h>
#include "../ScriptObject.h"
#include <ScriptObject.h>
#include <Actor/Player.h>
#include <Action/Action.h>
class ActionReturn6 :
public Sapphire::ScriptAPI::ActionScript
@ -11,9 +12,12 @@ public:
{
}
void onCastFinish( Sapphire::Entity::Player& player, Sapphire::Entity::Chara& targetActor ) override
void onExecute( Sapphire::Action::Action& action ) override
{
player.returnToHomepoint();
if( !action.getSourceChara()->isPlayer() )
return;
action.getSourceChara()->getAsPlayer()->returnToHomepoint();
}
};

View file

@ -0,0 +1,25 @@
#include <ScriptObject.h>
#include <Actor/Player.h>
#include <Action/Action.h>
class ActionSprint3 :
public Sapphire::ScriptAPI::ActionScript
{
public:
ActionSprint3() :
Sapphire::ScriptAPI::ActionScript( 3 )
{
}
void onExecute( Sapphire::Action::Action& action ) override
{
auto sourceChara = action.getSourceChara();
if( !sourceChara->isPlayer() )
return;
sourceChara->getAsPlayer()->addStatusEffectByIdIfNotExist( 50, 20000, *sourceChara, 30 );
}
};
EXPOSE_SCRIPT( ActionSprint3 );

View file

@ -0,0 +1,42 @@
#include <Script/NativeScriptApi.h>
#include <ScriptObject.h>
#include <Actor/Player.h>
#include <Action/Action.h>
using namespace Sapphire;
class ActionTeleport5 :
public Sapphire::ScriptAPI::ActionScript
{
public:
ActionTeleport5() :
Sapphire::ScriptAPI::ActionScript( 5 )
{
}
void onExecute( Sapphire::Action::Action& action ) override
{
auto player = action.getSourceChara()->getAsPlayer();
if( !player )
return;
auto teleportQuery = player->getTeleportQuery();
if( player->getCurrency( Common::CurrencyType::Gil ) < teleportQuery.cost ||
teleportQuery.targetAetheryte == 0 )
{
action.interrupt();
return;
}
player->removeCurrency( Common::CurrencyType::Gil, teleportQuery.cost );
player->setZoningType( Common::ZoneingType::Teleport );
player->teleport( teleportQuery.targetAetheryte );
player->clearTeleportQuery();
}
};
EXPOSE_SCRIPT( ActionTeleport5 );

View file

@ -0,0 +1,23 @@
#include <Script/NativeScriptApi.h>
#include <ScriptObject.h>
#include <Actor/Player.h>
#include <Action/Action.h>
class ActionHeavyShot97 :
public Sapphire::ScriptAPI::ActionScript
{
public:
ActionHeavyShot97() :
Sapphire::ScriptAPI::ActionScript( 97 )
{
}
void onExecute( Sapphire::Action::Action& action ) override
{
if( auto player = action.getSourceChara()->getAsPlayer() )
player->sendDebug( "Imagine you just hit an enemy for 150 potency. Incredible, right?" );
}
};
EXPOSE_SCRIPT( ActionHeavyShot97 );

View file

@ -0,0 +1,22 @@
#include <Script/NativeScriptApi.h>
#include <ScriptObject.h>
#include <Actor/Player.h>
#include <Action/Action.h>
class ActionCure120 :
public Sapphire::ScriptAPI::ActionScript
{
public:
ActionCure120() :
Sapphire::ScriptAPI::ActionScript( 120 )
{
}
void onExecute( Sapphire::Action::Action& action ) override
{
}
};
EXPOSE_SCRIPT( ActionCure120 );

View file

@ -0,0 +1,22 @@
#include <Script/NativeScriptApi.h>
#include <ScriptObject.h>
#include <Actor/Player.h>
#include <Action/Action.h>
class ActionAsylum3569 :
public Sapphire::ScriptAPI::ActionScript
{
public:
ActionAsylum3569() :
Sapphire::ScriptAPI::ActionScript( 3569 )
{
}
void onExecute( Sapphire::Action::Action& action ) override
{
}
};
EXPOSE_SCRIPT( ActionAsylum3569 );

View file

@ -1,47 +0,0 @@
#include <Script/NativeScriptApi.h>
extern Sapphire::ScriptAPI::ScriptObject* makeScriptCmnDefCutSceneReplay();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptCmnDefInnBed();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptCmnDefLinkShell();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptCmnDefMarketBoardGridania();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptCmnDefMogLetter();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptCmnDefNpcRepair();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptCmnDefWeatherForeCast();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptComDefMobHuntBoard();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptGilShop();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptHouFurOrchestrion();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptAetheryte();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptHousingAethernet();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptHousingEstateEntrance();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptCmnDefHousingPersonalRoomEntrance();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptCmnDefHousingSignboard();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptHousingWarpTaxiExitEstate();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptWarpTaxi();
const Sapphire::ScriptAPI::ScriptObject* ptrs[] =
{
makeScriptCmnDefCutSceneReplay(),
makeScriptCmnDefInnBed(),
makeScriptCmnDefLinkShell(),
makeScriptCmnDefMarketBoardGridania(),
makeScriptCmnDefMogLetter(),
makeScriptCmnDefNpcRepair(),
makeScriptCmnDefWeatherForeCast(),
makeScriptComDefMobHuntBoard(),
makeScriptGilShop(),
makeScriptHouFurOrchestrion(),
makeScriptAetheryte(),
makeScriptHousingAethernet(),
makeScriptHousingEstateEntrance(),
makeScriptCmnDefHousingPersonalRoomEntrance(),
makeScriptCmnDefHousingSignboard(),
makeScriptHousingWarpTaxiExitEstate(),
makeScriptWarpTaxi(),
nullptr
};
extern "C" EXPORT const Sapphire::ScriptAPI::ScriptObject** getScripts()
{
return ptrs;
}

View file

@ -1,681 +0,0 @@
#include <Script/NativeScriptApi.h>
extern Sapphire::ScriptAPI::ScriptObject* makeScriptHeavenonHighFloors110();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptHeavenonHighFloors1120();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptHeavenonHighFloors2130();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptHeavenonHighFloors3140();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptHeavenonHighFloors4150();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptHeavenonHighFloors5160();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptHeavenonHighFloors6170();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptHeavenonHighFloors7180();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptHeavenonHighFloors8190();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptHeavenonHighFloors91100();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptThePalaceoftheDeadFloors101110();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptThePalaceoftheDeadFloors110();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptThePalaceoftheDeadFloors111120();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptThePalaceoftheDeadFloors1120();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptThePalaceoftheDeadFloors121130();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptThePalaceoftheDeadFloors131140();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptThePalaceoftheDeadFloors141150();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptThePalaceoftheDeadFloors151160();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptThePalaceoftheDeadFloors161170();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptThePalaceoftheDeadFloors171180();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptThePalaceoftheDeadFloors181190();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptThePalaceoftheDeadFloors191200();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptThePalaceoftheDeadFloors2130();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptThePalaceoftheDeadFloors3140();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptThePalaceoftheDeadFloors4150();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptThePalaceoftheDeadFloors5160();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptThePalaceoftheDeadFloors6170();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptThePalaceoftheDeadFloors7180();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptThePalaceoftheDeadFloors8190();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptThePalaceoftheDeadFloors91100();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptAlaMhigo();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptAmdaporKeep();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptAmdaporKeepHard();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptBaelsarsWall();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptBardamsMettle();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptBrayfloxsLongstop();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptBrayfloxsLongstopHard();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptCastrumAbania();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptCastrumMeridianum();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptCopperbellMines();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptCopperbellMinesHard();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptCuttersCry();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptDomaCastle();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptDzemaelDarkhold();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptHalatali();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptHalataliHard();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptHaukkeManor();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptHaukkeManorHard();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptHellsLid();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptHullbreakerIsle();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptHullbreakerIsleHard();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptKuganeCastle();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptNeverreap();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptPharosSirius();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptPharosSiriusHard();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptSaintMociannesArboretum();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptSaintMociannesArboretumHard();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptSastasha();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptSastashaHard();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptShisuioftheVioletTides();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptSnowcloak();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptSohmAl();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptSohmAlHard();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptSohrKhai();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheAery();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheAetherochemicalResearchFacility();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheAntitower();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheAurumVale();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheBurn();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheDrownedCityofSkalla();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheDuskVigil();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheFractalContinuum();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheFractalContinuumHard();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheGhimlytDark();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheGreatGubalLibrary();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheGreatGubalLibraryHard();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheKeeperoftheLake();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheLostCityofAmdapor();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheLostCityofAmdaporHard();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptThePraetorium();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheSirensongSea();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheStoneVigil();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheStoneVigilHard();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheSunkenTempleofQarn();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheSunkenTempleofQarnHard();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheSwallowsCompass();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheTamTaraDeepcroft();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheTamTaraDeepcroftHard();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheTempleoftheFist();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheThousandMawsofTotoRak();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheVault();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheWanderersPalace();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheWanderersPalaceHard();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptXelphatol();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheHauntedManor();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheValentionesCeremony();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptAirForceOne();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptAdvancedMahjongRanked();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptFourplayerMahjongKuitanDisabled();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptFourplayerMahjongKuitanEnabled();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptNoviceMahjongRanked();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptAllsWellthatEndsintheWell();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptAnnoytheVoid();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptBasicTrainingEnemyParties();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptBasicTrainingEnemyStrongholds();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptFlickingSticksandTakingNames();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptHeroontheHalfShell();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptLongLivetheQueen();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptMorethanaFeeler();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptPullingPoisonPosies();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptShadowandClaw();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptSolemnTrinity();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptStingingBack();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptUndertheArmor();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptWardUp();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptAccrueEnmityfromMultipleTargets();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptAssistAlliesinDefeatingaTarget();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptAvoidAreaofEffectAttacks();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptAvoidEngagedTargets();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptDefeatanOccupiedTarget();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptEngageEnemyReinforcements();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptEngageMultipleTargets();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptExecuteaComboinBattle();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptExecuteaCombotoIncreaseEnmity();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptExecuteaRangedAttacktoIncreaseEnmity();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptFinalExercise();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptHealMultipleAllies();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptHealanAlly();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptInteractwiththeBattlefield();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptAChorusSlime();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptALittleKnightMusic();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptAllsWellThatStartsWell();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptAmazingTechnicolorPitFiends();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptBeautyandaBeast();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptBehemothsandBroomsticks();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptBlobsintheWoods();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptBombedyofErrors();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptChimeraonaHotTinRoof();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptDirtyRottenAzulmagia();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptEyeSociety();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptGentlemenPreferSwords();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptHereComestheBoom();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptMidsummerNightsExplosion();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptMissTyphon();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptMuchAdoAboutPudding();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptOnaClearDayYouCanSmellForever();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptSomeLikeItExcruciatinglyHot();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptSunsetBullevard();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheMeNobodyNodes();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptThePlantomoftheOpera();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheSwordofMusic();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheThreepennyTurtles();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptToKillaMockingslime();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptWaitingforGolem();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptSealRockSeize();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheBorderlandRuinsSecure();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheFieldsofGloryShatter();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptAstragalos();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptHiddenGorge();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheFeast4on4Ranked();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheFeast4on4Training();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheFeastCustomMatchCrystalTower();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheFeastCustomMatchFeastingGrounds();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheFeastCustomMatchLichenweed();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheFeastRanked();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheFeastTeamCustomMatchCrystalTower();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheFeastTeamRanked();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheFeastTraining();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptABloodyReunion();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptASpectaclefortheAges();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptBloodDragoon();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptBloodontheDeck();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptCuriousGorgeMeetsHisMatch();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptDarkwingDragon();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptEmissaryoftheDawn();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptInThalsName();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptInterdimensionalRift();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptItsProbablyaTrap();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptMatsubaMayhem();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptNaadam();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptOneLifeforOneWorld();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptOurCompromise();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptOurUnsungHeroes();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptRaisingtheSword();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptReturnoftheBull();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheBattleonBekko();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheCarteneauFlatsHeliodrome();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheFaceofTrueEvil();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheHeartoftheProblem();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheOrphansandtheBrokenBlade();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheResonant();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheWilloftheMoon();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptWhenClansCollide();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptWithHeartandSteel();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptAlexanderTheArmoftheFather();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptAlexanderTheArmoftheFatherSavage();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptAlexanderTheArmoftheSon();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptAlexanderTheArmoftheSonSavage();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptAlexanderTheBreathoftheCreator();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptAlexanderTheBreathoftheCreatorSavage();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptAlexanderTheBurdenoftheFather();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptAlexanderTheBurdenoftheFatherSavage();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptAlexanderTheBurdenoftheSon();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptAlexanderTheBurdenoftheSonSavage();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptAlexanderTheCuffoftheFather();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptAlexanderTheCuffoftheFatherSavage();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptAlexanderTheCuffoftheSon();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptAlexanderTheCuffoftheSonSavage();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptAlexanderTheEyesoftheCreator();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptAlexanderTheEyesoftheCreatorSavage();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptAlexanderTheFistoftheFather();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptAlexanderTheFistoftheFatherSavage();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptAlexanderTheFistoftheSon();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptAlexanderTheFistoftheSonSavage();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptAlexanderTheHeartoftheCreator();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptAlexanderTheHeartoftheCreatorSavage();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptAlexanderTheSouloftheCreator();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptAlexanderTheSouloftheCreatorSavage();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptAlphascapeV10();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptAlphascapeV10Savage();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptAlphascapeV20();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptAlphascapeV20Savage();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptAlphascapeV30();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptAlphascapeV30Savage();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptAlphascapeV40();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptAlphascapeV40Savage();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptDeltascapeV10();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptDeltascapeV10Savage();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptDeltascapeV20();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptDeltascapeV20Savage();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptDeltascapeV30();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptDeltascapeV30Savage();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptDeltascapeV40();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptDeltascapeV40Savage();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptDunScaith();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptSigmascapeV10();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptSigmascapeV10Savage();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptSigmascapeV20();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptSigmascapeV20Savage();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptSigmascapeV30();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptSigmascapeV30Savage();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptSigmascapeV40();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptSigmascapeV40Savage();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptSyrcusTower();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheBindingCoilofBahamutTurn1();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheBindingCoilofBahamutTurn2();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheBindingCoilofBahamutTurn3();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheBindingCoilofBahamutTurn4();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheBindingCoilofBahamutTurn5();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheFinalCoilofBahamutTurn1();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheFinalCoilofBahamutTurn2();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheFinalCoilofBahamutTurn3();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheFinalCoilofBahamutTurn4();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheLabyrinthoftheAncients();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheOrbonneMonastery();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheRidoranaLighthouse();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheRoyalCityofRabanastre();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheSecondCoilofBahamutSavageTurn1();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheSecondCoilofBahamutSavageTurn2();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheSecondCoilofBahamutSavageTurn3();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheSecondCoilofBahamutSavageTurn4();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheSecondCoilofBahamutTurn1();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheSecondCoilofBahamutTurn2();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheSecondCoilofBahamutTurn3();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheSecondCoilofBahamutTurn4();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheUnendingCoilofBahamutUltimate();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheVoidArk();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheWeaponsRefrainUltimate();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheWeepingCityofMhach();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheWorldofDarkness();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheAquapolis();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheHiddenCanalsofUznair();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheLostCanalsofUznair();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheShiftingAltarsofUznair();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptARelicReborntheChimera();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptARelicReborntheHydra();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptAkhAfahAmphitheatreExtreme();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptAkhAfahAmphitheatreHard();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptBattleintheBigKeep();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptBattleontheBigBridge();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptCapeWestwind();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptCastrumFluminis();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptContainmentBayP1T6();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptContainmentBayP1T6Extreme();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptContainmentBayS1T7();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptContainmentBayS1T7Extreme();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptContainmentBayZ1T9();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptContainmentBayZ1T9Extreme();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptEmanation();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptEmanationExtreme();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptHellsKier();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptHellsKierExtreme();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptSpecialEventI();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptSpecialEventII();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptSpecialEventIII();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheBowlofEmbers();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheBowlofEmbersExtreme();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheBowlofEmbersHard();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheChrysalis();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheDragonsNeck();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheFinalStepsofFaith();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheGreatHunt();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheGreatHuntExtreme();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheHowlingEye();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheHowlingEyeExtreme();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheHowlingEyeHard();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheJadeStoa();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheJadeStoaExtreme();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheLimitlessBlueExtreme();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheLimitlessBlueHard();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheMinstrelsBalladNidhoggsRage();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheMinstrelsBalladShinryusDomain();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheMinstrelsBalladThordansReign();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheMinstrelsBalladTsukuyomisPain();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheMinstrelsBalladUltimasBane();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheNavel();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheNavelExtreme();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheNavelHard();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptThePoolofTribute();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptThePoolofTributeExtreme();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheRoyalMenagerie();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheSingularityReactor();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheStepsofFaith();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheStrikingTreeExtreme();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheStrikingTreeHard();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheWhorleaterExtreme();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheWhorleaterHard();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheWreathofSnakes();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptTheWreathofSnakesExtreme();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptThokastThokExtreme();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptThokastThokHard();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptThornmarchExtreme();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptThornmarchHard();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptUrthsFount();
const Sapphire::ScriptAPI::ScriptObject* ptrs[] =
{
makeScriptHeavenonHighFloors110(),
makeScriptHeavenonHighFloors1120(),
makeScriptHeavenonHighFloors2130(),
makeScriptHeavenonHighFloors3140(),
makeScriptHeavenonHighFloors4150(),
makeScriptHeavenonHighFloors5160(),
makeScriptHeavenonHighFloors6170(),
makeScriptHeavenonHighFloors7180(),
makeScriptHeavenonHighFloors8190(),
makeScriptHeavenonHighFloors91100(),
makeScriptThePalaceoftheDeadFloors101110(),
makeScriptThePalaceoftheDeadFloors110(),
makeScriptThePalaceoftheDeadFloors111120(),
makeScriptThePalaceoftheDeadFloors1120(),
makeScriptThePalaceoftheDeadFloors121130(),
makeScriptThePalaceoftheDeadFloors131140(),
makeScriptThePalaceoftheDeadFloors141150(),
makeScriptThePalaceoftheDeadFloors151160(),
makeScriptThePalaceoftheDeadFloors161170(),
makeScriptThePalaceoftheDeadFloors171180(),
makeScriptThePalaceoftheDeadFloors181190(),
makeScriptThePalaceoftheDeadFloors191200(),
makeScriptThePalaceoftheDeadFloors2130(),
makeScriptThePalaceoftheDeadFloors3140(),
makeScriptThePalaceoftheDeadFloors4150(),
makeScriptThePalaceoftheDeadFloors5160(),
makeScriptThePalaceoftheDeadFloors6170(),
makeScriptThePalaceoftheDeadFloors7180(),
makeScriptThePalaceoftheDeadFloors8190(),
makeScriptThePalaceoftheDeadFloors91100(),
makeScriptAlaMhigo(),
makeScriptAmdaporKeep(),
makeScriptAmdaporKeepHard(),
makeScriptBaelsarsWall(),
makeScriptBardamsMettle(),
makeScriptBrayfloxsLongstop(),
makeScriptBrayfloxsLongstopHard(),
makeScriptCastrumAbania(),
makeScriptCastrumMeridianum(),
makeScriptCopperbellMines(),
makeScriptCopperbellMinesHard(),
makeScriptCuttersCry(),
makeScriptDomaCastle(),
makeScriptDzemaelDarkhold(),
makeScriptHalatali(),
makeScriptHalataliHard(),
makeScriptHaukkeManor(),
makeScriptHaukkeManorHard(),
makeScriptHellsLid(),
makeScriptHullbreakerIsle(),
makeScriptHullbreakerIsleHard(),
makeScriptKuganeCastle(),
makeScriptNeverreap(),
makeScriptPharosSirius(),
makeScriptPharosSiriusHard(),
makeScriptSaintMociannesArboretum(),
makeScriptSaintMociannesArboretumHard(),
makeScriptSastasha(),
makeScriptSastashaHard(),
makeScriptShisuioftheVioletTides(),
makeScriptSnowcloak(),
makeScriptSohmAl(),
makeScriptSohmAlHard(),
makeScriptSohrKhai(),
makeScriptTheAery(),
makeScriptTheAetherochemicalResearchFacility(),
makeScriptTheAntitower(),
makeScriptTheAurumVale(),
makeScriptTheBurn(),
makeScriptTheDrownedCityofSkalla(),
makeScriptTheDuskVigil(),
makeScriptTheFractalContinuum(),
makeScriptTheFractalContinuumHard(),
makeScriptTheGhimlytDark(),
makeScriptTheGreatGubalLibrary(),
makeScriptTheGreatGubalLibraryHard(),
makeScriptTheKeeperoftheLake(),
makeScriptTheLostCityofAmdapor(),
makeScriptTheLostCityofAmdaporHard(),
makeScriptThePraetorium(),
makeScriptTheSirensongSea(),
makeScriptTheStoneVigil(),
makeScriptTheStoneVigilHard(),
makeScriptTheSunkenTempleofQarn(),
makeScriptTheSunkenTempleofQarnHard(),
makeScriptTheSwallowsCompass(),
makeScriptTheTamTaraDeepcroft(),
makeScriptTheTamTaraDeepcroftHard(),
makeScriptTheTempleoftheFist(),
makeScriptTheThousandMawsofTotoRak(),
makeScriptTheVault(),
makeScriptTheWanderersPalace(),
makeScriptTheWanderersPalaceHard(),
makeScriptXelphatol(),
makeScriptTheHauntedManor(),
makeScriptTheValentionesCeremony(),
makeScriptAirForceOne(),
makeScriptAdvancedMahjongRanked(),
makeScriptFourplayerMahjongKuitanDisabled(),
makeScriptFourplayerMahjongKuitanEnabled(),
makeScriptNoviceMahjongRanked(),
makeScriptAllsWellthatEndsintheWell(),
makeScriptAnnoytheVoid(),
makeScriptBasicTrainingEnemyParties(),
makeScriptBasicTrainingEnemyStrongholds(),
makeScriptFlickingSticksandTakingNames(),
makeScriptHeroontheHalfShell(),
makeScriptLongLivetheQueen(),
makeScriptMorethanaFeeler(),
makeScriptPullingPoisonPosies(),
makeScriptShadowandClaw(),
makeScriptSolemnTrinity(),
makeScriptStingingBack(),
makeScriptUndertheArmor(),
makeScriptWardUp(),
makeScriptAccrueEnmityfromMultipleTargets(),
makeScriptAssistAlliesinDefeatingaTarget(),
makeScriptAvoidAreaofEffectAttacks(),
makeScriptAvoidEngagedTargets(),
makeScriptDefeatanOccupiedTarget(),
makeScriptEngageEnemyReinforcements(),
makeScriptEngageMultipleTargets(),
makeScriptExecuteaComboinBattle(),
makeScriptExecuteaCombotoIncreaseEnmity(),
makeScriptExecuteaRangedAttacktoIncreaseEnmity(),
makeScriptFinalExercise(),
makeScriptHealMultipleAllies(),
makeScriptHealanAlly(),
makeScriptInteractwiththeBattlefield(),
makeScriptAChorusSlime(),
makeScriptALittleKnightMusic(),
makeScriptAllsWellThatStartsWell(),
makeScriptAmazingTechnicolorPitFiends(),
makeScriptBeautyandaBeast(),
makeScriptBehemothsandBroomsticks(),
makeScriptBlobsintheWoods(),
makeScriptBombedyofErrors(),
makeScriptChimeraonaHotTinRoof(),
makeScriptDirtyRottenAzulmagia(),
makeScriptEyeSociety(),
makeScriptGentlemenPreferSwords(),
makeScriptHereComestheBoom(),
makeScriptMidsummerNightsExplosion(),
makeScriptMissTyphon(),
makeScriptMuchAdoAboutPudding(),
makeScriptOnaClearDayYouCanSmellForever(),
makeScriptSomeLikeItExcruciatinglyHot(),
makeScriptSunsetBullevard(),
makeScriptTheMeNobodyNodes(),
makeScriptThePlantomoftheOpera(),
makeScriptTheSwordofMusic(),
makeScriptTheThreepennyTurtles(),
makeScriptToKillaMockingslime(),
makeScriptWaitingforGolem(),
makeScriptSealRockSeize(),
makeScriptTheBorderlandRuinsSecure(),
makeScriptTheFieldsofGloryShatter(),
makeScriptAstragalos(),
makeScriptHiddenGorge(),
makeScriptTheFeast4on4Ranked(),
makeScriptTheFeast4on4Training(),
makeScriptTheFeastCustomMatchCrystalTower(),
makeScriptTheFeastCustomMatchFeastingGrounds(),
makeScriptTheFeastCustomMatchLichenweed(),
makeScriptTheFeastRanked(),
makeScriptTheFeastTeamCustomMatchCrystalTower(),
makeScriptTheFeastTeamRanked(),
makeScriptTheFeastTraining(),
makeScriptABloodyReunion(),
makeScriptASpectaclefortheAges(),
makeScriptBloodDragoon(),
makeScriptBloodontheDeck(),
makeScriptCuriousGorgeMeetsHisMatch(),
makeScriptDarkwingDragon(),
makeScriptEmissaryoftheDawn(),
makeScriptInThalsName(),
makeScriptInterdimensionalRift(),
makeScriptItsProbablyaTrap(),
makeScriptMatsubaMayhem(),
makeScriptNaadam(),
makeScriptOneLifeforOneWorld(),
makeScriptOurCompromise(),
makeScriptOurUnsungHeroes(),
makeScriptRaisingtheSword(),
makeScriptReturnoftheBull(),
makeScriptTheBattleonBekko(),
makeScriptTheCarteneauFlatsHeliodrome(),
makeScriptTheFaceofTrueEvil(),
makeScriptTheHeartoftheProblem(),
makeScriptTheOrphansandtheBrokenBlade(),
makeScriptTheResonant(),
makeScriptTheWilloftheMoon(),
makeScriptWhenClansCollide(),
makeScriptWithHeartandSteel(),
makeScriptAlexanderTheArmoftheFather(),
makeScriptAlexanderTheArmoftheFatherSavage(),
makeScriptAlexanderTheArmoftheSon(),
makeScriptAlexanderTheArmoftheSonSavage(),
makeScriptAlexanderTheBreathoftheCreator(),
makeScriptAlexanderTheBreathoftheCreatorSavage(),
makeScriptAlexanderTheBurdenoftheFather(),
makeScriptAlexanderTheBurdenoftheFatherSavage(),
makeScriptAlexanderTheBurdenoftheSon(),
makeScriptAlexanderTheBurdenoftheSonSavage(),
makeScriptAlexanderTheCuffoftheFather(),
makeScriptAlexanderTheCuffoftheFatherSavage(),
makeScriptAlexanderTheCuffoftheSon(),
makeScriptAlexanderTheCuffoftheSonSavage(),
makeScriptAlexanderTheEyesoftheCreator(),
makeScriptAlexanderTheEyesoftheCreatorSavage(),
makeScriptAlexanderTheFistoftheFather(),
makeScriptAlexanderTheFistoftheFatherSavage(),
makeScriptAlexanderTheFistoftheSon(),
makeScriptAlexanderTheFistoftheSonSavage(),
makeScriptAlexanderTheHeartoftheCreator(),
makeScriptAlexanderTheHeartoftheCreatorSavage(),
makeScriptAlexanderTheSouloftheCreator(),
makeScriptAlexanderTheSouloftheCreatorSavage(),
makeScriptAlphascapeV10(),
makeScriptAlphascapeV10Savage(),
makeScriptAlphascapeV20(),
makeScriptAlphascapeV20Savage(),
makeScriptAlphascapeV30(),
makeScriptAlphascapeV30Savage(),
makeScriptAlphascapeV40(),
makeScriptAlphascapeV40Savage(),
makeScriptDeltascapeV10(),
makeScriptDeltascapeV10Savage(),
makeScriptDeltascapeV20(),
makeScriptDeltascapeV20Savage(),
makeScriptDeltascapeV30(),
makeScriptDeltascapeV30Savage(),
makeScriptDeltascapeV40(),
makeScriptDeltascapeV40Savage(),
makeScriptDunScaith(),
makeScriptSigmascapeV10(),
makeScriptSigmascapeV10Savage(),
makeScriptSigmascapeV20(),
makeScriptSigmascapeV20Savage(),
makeScriptSigmascapeV30(),
makeScriptSigmascapeV30Savage(),
makeScriptSigmascapeV40(),
makeScriptSigmascapeV40Savage(),
makeScriptSyrcusTower(),
makeScriptTheBindingCoilofBahamutTurn1(),
makeScriptTheBindingCoilofBahamutTurn2(),
makeScriptTheBindingCoilofBahamutTurn3(),
makeScriptTheBindingCoilofBahamutTurn4(),
makeScriptTheBindingCoilofBahamutTurn5(),
makeScriptTheFinalCoilofBahamutTurn1(),
makeScriptTheFinalCoilofBahamutTurn2(),
makeScriptTheFinalCoilofBahamutTurn3(),
makeScriptTheFinalCoilofBahamutTurn4(),
makeScriptTheLabyrinthoftheAncients(),
makeScriptTheOrbonneMonastery(),
makeScriptTheRidoranaLighthouse(),
makeScriptTheRoyalCityofRabanastre(),
makeScriptTheSecondCoilofBahamutSavageTurn1(),
makeScriptTheSecondCoilofBahamutSavageTurn2(),
makeScriptTheSecondCoilofBahamutSavageTurn3(),
makeScriptTheSecondCoilofBahamutSavageTurn4(),
makeScriptTheSecondCoilofBahamutTurn1(),
makeScriptTheSecondCoilofBahamutTurn2(),
makeScriptTheSecondCoilofBahamutTurn3(),
makeScriptTheSecondCoilofBahamutTurn4(),
makeScriptTheUnendingCoilofBahamutUltimate(),
makeScriptTheVoidArk(),
makeScriptTheWeaponsRefrainUltimate(),
makeScriptTheWeepingCityofMhach(),
makeScriptTheWorldofDarkness(),
makeScriptTheAquapolis(),
makeScriptTheHiddenCanalsofUznair(),
makeScriptTheLostCanalsofUznair(),
makeScriptTheShiftingAltarsofUznair(),
makeScriptARelicReborntheChimera(),
makeScriptARelicReborntheHydra(),
makeScriptAkhAfahAmphitheatreExtreme(),
makeScriptAkhAfahAmphitheatreHard(),
makeScriptBattleintheBigKeep(),
makeScriptBattleontheBigBridge(),
makeScriptCapeWestwind(),
makeScriptCastrumFluminis(),
makeScriptContainmentBayP1T6(),
makeScriptContainmentBayP1T6Extreme(),
makeScriptContainmentBayS1T7(),
makeScriptContainmentBayS1T7Extreme(),
makeScriptContainmentBayZ1T9(),
makeScriptContainmentBayZ1T9Extreme(),
makeScriptEmanation(),
makeScriptEmanationExtreme(),
makeScriptHellsKier(),
makeScriptHellsKierExtreme(),
makeScriptSpecialEventI(),
makeScriptSpecialEventII(),
makeScriptSpecialEventIII(),
makeScriptTheBowlofEmbers(),
makeScriptTheBowlofEmbersExtreme(),
makeScriptTheBowlofEmbersHard(),
makeScriptTheChrysalis(),
makeScriptTheDragonsNeck(),
makeScriptTheFinalStepsofFaith(),
makeScriptTheGreatHunt(),
makeScriptTheGreatHuntExtreme(),
makeScriptTheHowlingEye(),
makeScriptTheHowlingEyeExtreme(),
makeScriptTheHowlingEyeHard(),
makeScriptTheJadeStoa(),
makeScriptTheJadeStoaExtreme(),
makeScriptTheLimitlessBlueExtreme(),
makeScriptTheLimitlessBlueHard(),
makeScriptTheMinstrelsBalladNidhoggsRage(),
makeScriptTheMinstrelsBalladShinryusDomain(),
makeScriptTheMinstrelsBalladThordansReign(),
makeScriptTheMinstrelsBalladTsukuyomisPain(),
makeScriptTheMinstrelsBalladUltimasBane(),
makeScriptTheNavel(),
makeScriptTheNavelExtreme(),
makeScriptTheNavelHard(),
makeScriptThePoolofTribute(),
makeScriptThePoolofTributeExtreme(),
makeScriptTheRoyalMenagerie(),
makeScriptTheSingularityReactor(),
makeScriptTheStepsofFaith(),
makeScriptTheStrikingTreeExtreme(),
makeScriptTheStrikingTreeHard(),
makeScriptTheWhorleaterExtreme(),
makeScriptTheWhorleaterHard(),
makeScriptTheWreathofSnakes(),
makeScriptTheWreathofSnakesExtreme(),
makeScriptThokastThokExtreme(),
makeScriptThokastThokHard(),
makeScriptThornmarchExtreme(),
makeScriptThornmarchHard(),
makeScriptUrthsFount(),
nullptr
};
extern "C" EXPORT const Sapphire::ScriptAPI::ScriptObject** getScripts()
{
return ptrs;
}

View file

@ -1,19 +0,0 @@
#include <Script/NativeScriptApi.h>
extern Sapphire::ScriptAPI::ScriptObject* makeScriptOpeningGridania();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptOpeningLimsa();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptOpeningUldah();
const Sapphire::ScriptAPI::ScriptObject* ptrs[] =
{
makeScriptOpeningGridania(),
makeScriptOpeningLimsa(),
makeScriptOpeningUldah(),
nullptr
};
extern "C" EXPORT const Sapphire::ScriptAPI::ScriptObject** getScripts()
{
return ptrs;
}

View file

@ -1,101 +0,0 @@
#include <Script/NativeScriptApi.h>
extern Sapphire::ScriptAPI::ScriptObject* makeScriptManFst001();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptManFst002();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptManFst003();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptManFst004();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptManSea001();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptManSea002();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptManSea003();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptManWil001();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptManWil002();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptManWil003();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptManWil004();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptSubFst001();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptSubFst002();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptSubFst003();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptSubFst004();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptSubFst005();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptSubFst008();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptSubFst009();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptSubFst010();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptSubFst011();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptSubFst013();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptSubFst014();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptSubFst015();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptSubFst019();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptSubFst026();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptSubFst029();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptSubFst030();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptSubFst041();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptSubFst045();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptSubSea001();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptSubSea012();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptSubWil000();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptSubWil001();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptSubWil002();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptSubWil004();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptSubWil006();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptSubWil007();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptSubWil018();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptSubWil019();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptSubWil021();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptSubWil022();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptSubWil027();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptSubWil028();
extern Sapphire::ScriptAPI::ScriptObject* makeScriptSubWil029();
const Sapphire::ScriptAPI::ScriptObject* ptrs[] =
{
makeScriptManFst001(),
makeScriptManFst002(),
makeScriptManFst003(),
makeScriptManFst004(),
makeScriptManSea001(),
makeScriptManSea002(),
makeScriptManSea003(),
makeScriptManWil001(),
makeScriptManWil002(),
makeScriptManWil003(),
makeScriptManWil004(),
makeScriptSubFst001(),
makeScriptSubFst002(),
makeScriptSubFst003(),
makeScriptSubFst004(),
makeScriptSubFst005(),
makeScriptSubFst008(),
makeScriptSubFst009(),
makeScriptSubFst010(),
makeScriptSubFst011(),
makeScriptSubFst013(),
makeScriptSubFst014(),
makeScriptSubFst015(),
makeScriptSubFst019(),
makeScriptSubFst026(),
makeScriptSubFst029(),
makeScriptSubFst030(),
makeScriptSubFst041(),
makeScriptSubFst045(),
makeScriptSubSea001(),
makeScriptSubSea012(),
makeScriptSubWil000(),
makeScriptSubWil001(),
makeScriptSubWil002(),
makeScriptSubWil004(),
makeScriptSubWil006(),
makeScriptSubWil007(),
makeScriptSubWil018(),
makeScriptSubWil019(),
makeScriptSubWil021(),
makeScriptSubWil022(),
makeScriptSubWil027(),
makeScriptSubWil028(),
makeScriptSubWil029(),
nullptr
};
extern "C" EXPORT const Sapphire::ScriptAPI::ScriptObject** getScripts()
{
return ptrs;
}

View file

@ -1,63 +1,148 @@
#include "Action.h"
#include <Exd/ExdDataGenerated.h>
#include <Util/Util.h>
#include "Framework.h"
#include "Script/ScriptMgr.h"
#include "Actor/Player.h"
#include "Actor/BNpc.h"
#include "Territory/Zone.h"
#include <Network/CommonActorControl.h>
#include "Network/PacketWrappers/ActorControlPacket142.h"
#include "Network/PacketWrappers/ActorControlPacket143.h"
#include "Network/PacketWrappers/ActorControlPacket144.h"
#include <Network/PacketWrappers/EffectPacket.h>
using namespace Sapphire::Common;
using namespace Sapphire::Network;
using namespace Sapphire::Network::Packets;
using namespace Sapphire::Network::Packets::Server;
using namespace Sapphire::Network::ActorControl;
Sapphire::Action::Action::Action()
Sapphire::Action::Action::Action() = default;
Sapphire::Action::Action::~Action() = default;
Sapphire::Action::Action::Action( Entity::CharaPtr caster, uint32_t actionId, FrameworkPtr fw ) :
Action( std::move( caster ), actionId, nullptr, std::move( fw ) )
{
}
Sapphire::Action::Action::~Action()
Sapphire::Action::Action::Action( Entity::CharaPtr caster, uint32_t actionId,
Data::ActionPtr actionData, FrameworkPtr fw ) :
m_pSource( std::move( caster ) ),
m_pFw( std::move( fw ) ),
m_actionData( std::move( actionData ) ),
m_id( actionId ),
m_targetId( 0 ),
m_startTime( 0 ),
m_interruptType( Common::ActionInterruptType::None )
{
}
uint16_t Sapphire::Action::Action::getId() const
uint32_t Sapphire::Action::Action::getId() const
{
return m_id;
}
Sapphire::Common::HandleActionType Sapphire::Action::Action::getHandleActionType() const
bool Sapphire::Action::Action::init()
{
return m_handleActionType;
if( !m_actionData )
{
// need to get actionData
auto exdData = m_pFw->get< Data::ExdDataGenerated >();
assert( exdData );
auto actionData = exdData->get< Data::Action >( m_id );
assert( actionData );
m_actionData = actionData;
}
Sapphire::Entity::CharaPtr Sapphire::Action::Action::getTargetChara() const
m_castTimeMs = static_cast< uint32_t >( m_actionData->cast100ms * 100 );
m_recastTimeMs = static_cast< uint32_t >( m_actionData->recast100ms * 100 );
m_cooldownGroup = m_actionData->cooldownGroup;
m_range = m_actionData->range;
m_effectRange = m_actionData->effectRange;
m_aspect = static_cast< Common::ActionAspect >( m_actionData->aspect );
// a default range is set by the game for the class/job
if( m_range == -1 )
{
return m_pTarget;
switch( static_cast< Common::ClassJob >( m_actionData->classJob ) )
{
case Common::ClassJob::Bard:
case Common::ClassJob::Archer:
m_range = 25;
// anything that isnt ranged
default:
m_range = 3;
}
}
m_primaryCostType = static_cast< Common::ActionPrimaryCostType >( m_actionData->costType );
m_primaryCost = m_actionData->cost;
// todo: add missing rows for secondaryCostType/secondaryCostType and rename the current rows to primaryCostX
return true;
}
void Sapphire::Action::Action::setPos( Sapphire::Common::FFXIVARR_POSITION3 pos )
{
m_pos = pos;
}
Sapphire::Common::FFXIVARR_POSITION3 Sapphire::Action::Action::getPos() const
{
return m_pos;
}
void Sapphire::Action::Action::setTargetId( uint64_t targetId )
{
m_targetId = targetId;
}
uint64_t Sapphire::Action::Action::getTargetId() const
{
return m_targetId;
}
bool Sapphire::Action::Action::hasClientsideTarget() const
{
return m_targetId > 0xFFFFFFFF;
}
bool Sapphire::Action::Action::isInterrupted() const
{
return m_bInterrupt;
return m_interruptType != Common::ActionInterruptType::None;
}
void Sapphire::Action::Action::setInterrupted()
void Sapphire::Action::Action::setInterrupted( Common::ActionInterruptType type )
{
m_bInterrupt = true;
}
uint64_t Sapphire::Action::Action::getStartTime() const
{
return m_startTime;
}
void Sapphire::Action::Action::setStartTime( uint64_t startTime )
{
m_startTime = startTime;
m_interruptType = type;
}
uint32_t Sapphire::Action::Action::getCastTime() const
{
return m_castTime;
return m_castTimeMs;
}
void Sapphire::Action::Action::setCastTime( uint32_t castTime )
{
m_castTime = castTime;
m_castTimeMs = castTime;
}
Sapphire::Entity::CharaPtr Sapphire::Action::Action::getActionSource() const
bool Sapphire::Action::Action::hasCastTime() const
{
return m_castTimeMs > 0;
}
Sapphire::Entity::CharaPtr Sapphire::Action::Action::getSourceChara() const
{
return m_pSource;
}
@ -68,18 +153,329 @@ bool Sapphire::Action::Action::update()
if( m_startTime == 0 )
return false;
if( m_bInterrupt )
if( isInterrupted() )
{
onInterrupt();
interrupt();
return true;
}
if( !hasClientsideTarget() )
{
// todo: check if the target is still in range
}
uint64_t currTime = Util::getTimeMs();
if( ( currTime - m_startTime ) > m_castTime )
if( !hasCastTime() || std::difftime( currTime, m_startTime ) > m_castTimeMs )
{
onFinish();
execute();
return true;
}
return false;
}
void Sapphire::Action::Action::start()
{
assert( m_pSource );
m_startTime = Util::getTimeMs();
auto player = m_pSource->getAsPlayer();
if( hasCastTime() )
{
auto castPacket = makeZonePacket< Server::FFXIVIpcActorCast >( getId() );
castPacket->data().action_id = static_cast< uint16_t >( m_id );
castPacket->data().skillType = Common::SkillType::Normal;
castPacket->data().unknown_1 = m_id;
// This is used for the cast bar above the target bar of the caster.
castPacket->data().cast_time = m_castTimeMs / 1000.f;
castPacket->data().target_id = static_cast< uint32_t >( m_targetId );
m_pSource->sendToInRangeSet( castPacket, true );
if( player )
{
player->setStateFlag( PlayerStateFlag::Casting );
}
}
// todo: m_recastTimeMs needs to be adjusted for player sks/sps
auto actionStartPkt = makeActorControl143( m_pSource->getId(), ActorControlType::ActionStart, 1, getId(), m_recastTimeMs / 10 );
player->queuePacket( actionStartPkt );
auto pScriptMgr = m_pFw->get< Scripting::ScriptMgr >();
if( !pScriptMgr->onStart( *this ) )
{
// script not implemented
interrupt();
if( player )
{
player->sendUrgent( "Action not implemented, missing script for action#{0}", getId() );
player->setCurrentAction( nullptr );
}
return;
}
// instantly finish cast if there's no cast time
if( !hasCastTime() )
execute();
}
void Sapphire::Action::Action::interrupt()
{
assert( m_pSource );
// things that aren't players don't care about cooldowns and state flags
if( m_pSource->isPlayer() )
{
auto player = m_pSource->getAsPlayer();
// todo: reset cooldown for actual player
// reset state flag
//player->unsetStateFlag( PlayerStateFlag::Occupied1 );
player->unsetStateFlag( PlayerStateFlag::Casting );
}
if( hasCastTime() )
{
uint8_t interruptEffect = 0;
if( m_interruptType == ActionInterruptType::DamageInterrupt )
interruptEffect = 1;
// Note: When cast interrupt from taking too much damage, set the last value to 1.
// This enables the cast interrupt effect.
auto control = makeActorControl142( m_pSource->getId(), ActorControlType::CastInterrupt,
0x219, 1, m_id, interruptEffect );
m_pSource->sendToInRangeSet( control, true );
}
auto pScriptMgr = m_pFw->get< Scripting::ScriptMgr >();
pScriptMgr->onInterrupt( *this );
}
void Sapphire::Action::Action::execute()
{
assert( m_pSource );
auto pScriptMgr = m_pFw->get< Scripting::ScriptMgr >();
if( hasCastTime() )
{
// todo: what's this?
/*auto control = ActorControlPacket143( m_pTarget->getId(), ActorControlType::Unk7,
0x219, m_id, m_id, m_id, m_id );
m_pSource->sendToInRangeSet( control, true );*/
if( auto player = m_pSource->getAsPlayer() )
{
player->unsetStateFlag( PlayerStateFlag::Casting );
}
}
if( !hasClientsideTarget() )
{
pScriptMgr->onExecute( *this );
}
else if( auto player = m_pSource->getAsPlayer() )
{
pScriptMgr->onEObjHit( *player, m_targetId );
return;
}
}
void Sapphire::Action::Action::calculateActionCost()
{
// todo: just a test handler for now to get MP output for each cast, not sure where we should put this
// check primary cost
switch( m_primaryCostType )
{
case ActionPrimaryCostType::None:
{
break;
}
case ActionPrimaryCostType::MagicPoints:
{
calculateMPCost( m_primaryCost );
break;
}
case ActionPrimaryCostType::TacticsPoints:
{
break;
}
default:
{
if( auto player = m_pSource->getAsPlayer() )
{
player->sendDebug( "action#{0} is missing a handler for cost type: {1}",
m_id, static_cast< uint8_t >( m_primaryCostType ) );
}
break;
}
}
// todo: secondary cost type needs to be handled
}
// todo: this shouldn't be in action and instead be in some general stat calc util
void Sapphire::Action::Action::calculateMPCost( uint16_t baseCost )
{
auto level = m_pSource->getLevel();
// each level range is 1-10, 11-20, 21-30, ... therefore:
// level 50 should be in the 4th group, not the 5th
// dividing by 10 on the border will break this unless we subtract 1
auto levelGroup = std::max< uint8_t >( level - 1, 1 ) / 10;
float cost = baseCost;
// thanks to andrew for helping me figure this shit out, should be pretty accurate
switch( levelGroup )
{
// level 1-10
case 0:
{
// r^2 = 0.9999
cost = 0.0952f * level + 0.9467f;
break;
}
// level 11-20
case 1:
{
// r^2 = 1
cost = 0.19f * level;
break;
}
// level 21-30
case 2:
{
// r^2 = 1
cost = 0.38f * level - 3.8f;
break;
}
// level 31-40
case 3:
{
// r^2 = 1
cost = 0.6652f * level - 12.358f;
break;
}
// level 41-50
case 4:
{
// r^2 = 1
cost = 1.2352f * level - 35.159f;
break;
}
// level 51-60
case 5:
{
// r^2 = 1
cost = 0.0654f * std::exp( 0.1201f * level );
break;
}
// level 61-70
case 6:
{
// r^2 = 0.9998
cost = 0.2313f * ( level * level ) - 26.98f * level + 875.21f;
break;
}
default:
return;
}
// m_primaryCost is the base cost, cost is the multiplier for the current player level
m_primaryCost = static_cast< uint16_t >( std::round( cost * baseCost ) );
if( auto player = m_pSource->getAsPlayer() )
player->sendDebug( "calculated mp cost: {0}", m_primaryCost );
}
bool Sapphire::Action::Action::precheck()
{
if( auto player = m_pSource->getAsPlayer() )
{
if( !playerPrecheck( *player ) )
return false;
}
return true;
}
bool Sapphire::Action::Action::playerPrecheck( Entity::Player& player )
{
// lol
if( !player.isAlive() )
return false;
// npc actions/non player actions
if( m_actionData->classJob == -1 )
return false;
if( player.getLevel() < m_actionData->classJobLevel )
return false;
auto currentClass = player.getClass();
auto actionClass = static_cast< Common::ClassJob >( m_actionData->classJob );
if( actionClass != Common::ClassJob::Adventurer && currentClass != actionClass )
{
// check if not a base class action
auto exdData = m_pFw->get< Data::ExdDataGenerated >();
assert( exdData );
auto classJob = exdData->get< Data::ClassJob >( static_cast< uint8_t >( currentClass ) );
if( !classJob )
return false;
if( classJob->classJobParent != m_actionData->classJob )
return false;
}
// reset target on actions that can only be casted on yourself while having a target set
// todo: check what actions send when targeting an enemy
// if( m_actionData->canTargetSelf &&
// !m_actionData->canTargetFriendly &&
// !m_actionData->canTargetHostile &&
// !m_actionData->canTargetParty )
// {
// setTargetId( getSourceChara() );
// }
// todo: party/enemy validation
// validate range
// todo: validate costs/conditionals here
calculateActionCost();
return true;
}
uint32_t Sapphire::Action::Action::getAdditionalData() const
{
return m_additionalData;
}
void Sapphire::Action::Action::setAdditionalData( uint32_t data )
{
m_additionalData = data;
}

View file

@ -3,6 +3,13 @@
#include <Common.h>
#include "ForwardsZone.h"
#include <array>
namespace Sapphire::Data
{
struct Action;
using ActionPtr = std::shared_ptr< Action >;
}
namespace Sapphire::Action
{
@ -11,59 +18,106 @@ namespace Sapphire::Action
{
public:
Action();
Action( Entity::CharaPtr caster, uint32_t actionId, FrameworkPtr fw );
Action( Entity::CharaPtr caster, uint32_t actionId, Data::ActionPtr actionData, FrameworkPtr fw );
virtual ~Action();
uint16_t getId() const;
uint32_t getId() const;
Common::HandleActionType getHandleActionType() const;
bool init();
Entity::CharaPtr getTargetChara() const;
void setPos( Common::FFXIVARR_POSITION3 pos );
Common::FFXIVARR_POSITION3 getPos() const;
void setTargetId( uint64_t targetId );
uint64_t getTargetId() const;
Entity::CharaPtr getSourceChara() const;
bool isInterrupted() const;
void setInterrupted();
uint64_t getStartTime() const;
void setStartTime( uint64_t startTime );
void setInterrupted( Common::ActionInterruptType type );
uint32_t getCastTime() const;
void setCastTime( uint32_t castTime );
Entity::CharaPtr getActionSource() const;
uint32_t getAdditionalData() const;
void setAdditionalData( uint32_t data );
virtual void onStart()
{
};
/*!
* @brief Checks if the action *may* target a resident instead of an actor
* @return true if the target *may* be a resident and not an actor, otherwise false.
*/
bool hasClientsideTarget() const;
virtual void onFinish()
{
};
/*!
* @brief Tests whether the action is instantly usable or has a cast assoc'd with it
* @return true if action has a cast time
*/
bool hasCastTime() const;
virtual void onInterrupt()
{
};
/*!
* @brief Tests if an action is castable by the current source chara
* @return true if castable, false if the caster doesn't meet the requirements
*/
bool precheck();
// update action, if returns true, action is done and has to be removed from the actor
/*!
* @brief Starts the cast. Finishes it immediately if there is no cast time (weaponskills).
*/
virtual void start();
/*!
* @brief Finishes the cast, effected targets are calculated here.
*/
virtual void execute();
/*!
* @brief Called when a cast is interrupted for any reason
*
* m_interruptType will have the reason why the action was interrupted (eg. damage, movement, ...)
*/
virtual void interrupt();
/*!
* @brief Called on each player update tick
* @return true if a cast has finished and should be removed from the owning chara
*/
virtual bool update();
protected:
uint16_t m_id;
Common::HandleActionType m_handleActionType;
void calculateActionCost();
void calculateMPCost( uint16_t baseCost );
bool playerPrecheck( Entity::Player& player );
uint32_t m_id;
Common::ActionPrimaryCostType m_primaryCostType;
uint16_t m_primaryCost;
uint64_t m_startTime;
uint32_t m_castTime;
uint32_t m_castTimeMs;
uint32_t m_recastTimeMs;
uint8_t m_cooldownGroup;
int8_t m_range;
uint8_t m_effectRange;
Common::ActionAspect m_aspect;
uint32_t m_additionalData;
Entity::CharaPtr m_pSource;
Entity::CharaPtr m_pTarget;
uint64_t m_targetId;
bool m_bInterrupt;
Common::ActionInterruptType m_interruptType;
FrameworkPtr m_pFw;
Data::ActionPtr m_actionData;
Common::FFXIVARR_POSITION3 m_pos;
};
}

View file

@ -1,102 +0,0 @@
#include <Common.h>
#include <Util/Util.h>
#include <Util/UtilMath.h>
#include <Logging/Logger.h>
#include <Exd/ExdDataGenerated.h>
#include <Network/CommonActorControl.h>
#include "Network/PacketWrappers/ActorControlPacket142.h"
#include "Network/PacketWrappers/ActorControlPacket143.h"
#include "Network/PacketWrappers/ActorControlPacket144.h"
#include "Actor/Player.h"
#include "Script/ScriptMgr.h"
#include "ActionCast.h"
#include "Framework.h"
using namespace Sapphire::Common;
using namespace Sapphire::Network;
using namespace Sapphire::Network::Packets;
using namespace Sapphire::Network::Packets::Server;
using namespace Sapphire::Network::ActorControl;
Sapphire::Action::ActionCast::ActionCast()
{
m_handleActionType = Common::HandleActionType::Event;
}
Sapphire::Action::ActionCast::ActionCast( Entity::CharaPtr pActor, Entity::CharaPtr pTarget,
uint16_t actionId, FrameworkPtr pFw )
{
m_pFw = pFw;
auto pExdData = m_pFw->get< Data::ExdDataGenerated >();
m_startTime = 0;
m_id = actionId;
m_handleActionType = HandleActionType::Spell;
m_castTime = pExdData->get< Sapphire::Data::Action >( actionId )->cast100ms * 100; // TODO: Add security checks.
m_pSource = pActor;
m_pTarget = pTarget;
m_bInterrupt = false;
}
Sapphire::Action::ActionCast::~ActionCast() = default;
void Sapphire::Action::ActionCast::onStart()
{
if( !m_pSource )
return;
m_pSource->getAsPlayer()->sendDebug( "onStart()" );
m_startTime = Util::getTimeMs();
auto castPacket = makeZonePacket< FFXIVIpcActorCast >( getId() );
castPacket->data().action_id = m_id;
castPacket->data().skillType = Common::SkillType::Normal;
castPacket->data().unknown_1 = m_id;
// This is used for the cast bar above the target bar of the caster.
castPacket->data().cast_time = static_cast< float >( m_castTime / 1000 );
castPacket->data().target_id = m_pTarget->getId();
m_pSource->sendToInRangeSet( castPacket, true );
m_pSource->getAsPlayer()->setStateFlag( PlayerStateFlag::Casting );
}
void Sapphire::Action::ActionCast::onFinish()
{
if( !m_pSource )
return;
auto pScriptMgr = m_pFw->get< Scripting::ScriptMgr >();
auto pPlayer = m_pSource->getAsPlayer();
pPlayer->sendDebug( "onFinish()" );
pPlayer->unsetStateFlag( PlayerStateFlag::Casting );
/*auto control = ActorControlPacket143( m_pTarget->getId(), ActorControlType::Unk7,
0x219, m_id, m_id, m_id, m_id );
m_pSource->sendToInRangeSet( control, true );*/
pScriptMgr->onCastFinish( *pPlayer, m_pTarget, m_id );
}
void Sapphire::Action::ActionCast::onInterrupt()
{
if( !m_pSource )
return;
//m_pSource->getAsPlayer()->unsetStateFlag( PlayerStateFlag::Occupied1 );
m_pSource->getAsPlayer()->unsetStateFlag( PlayerStateFlag::Casting );
auto control = makeActorControl142( m_pSource->getId(), ActorControlType::CastInterrupt, 0x219, 1, m_id, 0 );
// Note: When cast interrupt from taking too much damage, set the last value to 1. This enables the cast interrupt effect. Example:
// auto control = ActorControlPacket142( m_pSource->getId(), ActorControlType::CastInterrupt, 0x219, 1, m_id, 0 );
m_pSource->sendToInRangeSet( control, true );
}

View file

@ -1,31 +0,0 @@
#ifndef _ACTIONCAST_H_
#define _ACTIONCAST_H_
#include "ForwardsZone.h"
#include "Action.h"
namespace Sapphire::Action
{
class ActionCast : public Action
{
private:
public:
ActionCast();
~ActionCast();
ActionCast( Entity::CharaPtr pActor, Entity::CharaPtr pTarget, uint16_t actionId, FrameworkPtr pFw );
void onStart() override;
void onFinish() override;
void onInterrupt() override;
};
}
#endif

View file

@ -1,143 +0,0 @@
#include <Util/Util.h>
#include <Util/UtilMath.h>
#include <Exd/ExdDataGenerated.h>
#include "ActionCollision.h"
#include "Actor/Actor.h"
#include "Actor/Chara.h"
#include "Actor/Player.h"
#include <cmath>
#include <cassert>
using namespace Sapphire::Entity;
using namespace Sapphire::Common;
// todo: add AoE actor limits (16, 32)
bool ActionCollision::isActorApplicable( Actor& actor, TargetFilter targetFilter )
{
bool actorApplicable = false;
switch( targetFilter )
{
case TargetFilter::All:
{
actorApplicable = true;
break;
}
case TargetFilter::Players:
{
actorApplicable = actor.isPlayer();
break;
}
case TargetFilter::Allies:
{
// todo: implement ally NPCs
// actorApplicable = !chara.isBattleNpc();
break;
}
case TargetFilter::Party:
{
// todo: implement party
actorApplicable = actor.isPlayer();
break;
}
case TargetFilter::Enemies:
{
//actorApplicable = chara.isBattleNpc();
break;
}
}
return ( actorApplicable && actor.getAsChara()->isAlive() );
}
std::set< Sapphire::Entity::ActorPtr > ActionCollision::getActorsHitFromAction( FFXIVARR_POSITION3 aoePosition,
std::set< ActorPtr > actorsInRange,
std::shared_ptr< Sapphire::Data::Action > actionInfo,
TargetFilter targetFilter )
{
std::set< ActorPtr > actorsCollided;
switch( static_cast< ActionCollisionType >( actionInfo->castType ) )
{
case ActionCollisionType::None:
case ActionCollisionType::SingleTarget:
{
// This is actually needed. There is "splash damage" in actions marked as single target.
// Notice how we're using aoe_width. How collision works for SingleTarget is unknown as of now.
for( auto pActor : actorsInRange )
{
// Make sure actor exists. If it doesn't we done goofed.
assert( pActor );
// Don't bother wasting on collision if actor doesn't apply for it
if( !isActorApplicable( *pActor, targetFilter ) )
continue;
// Test our collision from actor with the area generated by the action from the AoE data
if( radiusCollision( pActor->getPos(), aoePosition, actionInfo->effectRange ) )
{
// Add it to the actors collided with the area
actorsCollided.insert( pActor );
}
}
break;
}
case ActionCollisionType::Circle:
{
for( auto pActor : actorsInRange )
{
assert( pActor );
if( !isActorApplicable( *pActor, targetFilter ) )
continue;
if( radiusCollision( pActor->getPos(), aoePosition, actionInfo->effectRange ) )
actorsCollided.insert( pActor );
}
break;
}
case ActionCollisionType::Box:
{
for( auto pActor : actorsInRange )
{
assert( pActor );
if( !isActorApplicable( *pActor, targetFilter ) )
continue;
if( boxCollision( pActor->getPos(), aoePosition, actionInfo->xAxisModifier, actionInfo->effectRange ) )
{
// todo: does this actually work?
actorsCollided.insert( pActor );
}
}
break;
}
default:
{
break;
}
}
return actorsCollided;
}
bool
ActionCollision::radiusCollision( FFXIVARR_POSITION3 actorPosition, FFXIVARR_POSITION3 aoePosition, uint16_t radius )
{
return Sapphire::Util::distance( actorPosition.x, actorPosition.y, actorPosition.z,
aoePosition.x, aoePosition.y, aoePosition.z ) <= radius;
}
bool ActionCollision::boxCollision( FFXIVARR_POSITION3 actorPosition, FFXIVARR_POSITION3 aoePosition, uint16_t width,
uint16_t height )
{
return actorPosition.x < aoePosition.x + width &&
actorPosition.x > aoePosition.x &&
actorPosition.y < aoePosition.y + height &&
actorPosition.y > aoePosition.y;
}

View file

@ -1,46 +0,0 @@
#ifndef _ACTIONCOLLISION_H
#define _ACTIONCOLLISION_H
#include <Common.h>
#include "ForwardsZone.h"
namespace Sapphire::Data
{
struct Action;
}
namespace Sapphire::Entity
{
enum class TargetFilter
{
All, // All actors in the AoE are applicable for collision
Players, // Only players
Allies, // Only allies (players, ally NPCs)
Party, // Only party members
Enemies // Only enemies
};
class ActionCollision
{
public:
static bool isActorApplicable( Actor& actor, TargetFilter targetFilter );
static std::set< ActorPtr > getActorsHitFromAction( Common::FFXIVARR_POSITION3 aoePosition,
std::set< ActorPtr > actorsInRange,
std::shared_ptr< Data::Action > actionInfo,
TargetFilter targetFilter );
private:
static bool radiusCollision( Common::FFXIVARR_POSITION3 actorPosition, Common::FFXIVARR_POSITION3 aoePosition,
uint16_t radius );
static bool boxCollision( Common::FFXIVARR_POSITION3 actorPosition, Common::FFXIVARR_POSITION3 aoePosition,
uint16_t width, uint16_t height );
};
}
#endif

View file

@ -1,107 +0,0 @@
#include <Common.h>
#include <Util/Util.h>
#include <Util/UtilMath.h>
#include <Logging/Logger.h>
#include <Network/CommonActorControl.h>
#include "Network/PacketWrappers/ActorControlPacket142.h"
#include "Network/PacketWrappers/ActorControlPacket143.h"
#include "Network/PacketWrappers/ActorControlPacket144.h"
#include "Network/PacketWrappers/EffectPacket.h"
#include "Actor/Player.h"
#include "Script/ScriptMgr.h"
#include "ActionMount.h"
#include "Framework.h"
using namespace Sapphire::Common;
using namespace Sapphire::Network;
using namespace Sapphire::Network::Packets;
using namespace Sapphire::Network::Packets::Server;
using namespace Sapphire::Network::ActorControl;
extern Sapphire::Framework g_framework;
Sapphire::Action::ActionMount::ActionMount()
{
m_handleActionType = HandleActionType::Event;
}
Sapphire::Action::ActionMount::ActionMount( Entity::CharaPtr pActor, uint16_t mountId )
{
m_startTime = 0;
m_id = mountId;
m_handleActionType = HandleActionType::Spell;
m_castTime = 1000;
m_pSource = pActor;
m_bInterrupt = false;
}
Sapphire::Action::ActionMount::~ActionMount()
{
}
void Sapphire::Action::ActionMount::onStart()
{
if( !m_pSource )
return;
m_pSource->getAsPlayer()->sendDebug( "ActionMount::onStart()" );
m_startTime = Util::getTimeMs();
auto castPacket = makeZonePacket< FFXIVIpcActorCast >( getId() );
castPacket->data().action_id = m_id;
castPacket->data().skillType = Common::SkillType::MountSkill;
castPacket->data().unknown_1 = m_id;
// This is used for the cast bar above the target bar of the caster.
castPacket->data().cast_time = static_cast< float >( m_castTime / 1000 );
castPacket->data().target_id = m_pSource->getAsPlayer()->getId();
m_pSource->sendToInRangeSet( castPacket, true );
m_pSource->getAsPlayer()->setStateFlag( PlayerStateFlag::Casting );
}
void Sapphire::Action::ActionMount::onFinish()
{
if( !m_pSource )
return;
auto pPlayer = m_pSource->getAsPlayer();
pPlayer->sendDebug( "ActionMount::onFinish()" );
pPlayer->unsetStateFlag( PlayerStateFlag::Casting );
auto effectPacket = std::make_shared< Server::EffectPacket >( getId(), pPlayer->getId(), 4 );
effectPacket->setRotation( Util::floatToUInt16Rot( pPlayer->getRot() ) );
Server::EffectEntry effectEntry{};
effectEntry.effectType = ActionEffectType::Mount;
effectEntry.hitSeverity = ActionHitSeverityType::CritDamage;
effectEntry.value = m_id;
effectPacket->addEffect( effectEntry );
pPlayer->sendToInRangeSet( effectPacket, true );
pPlayer->mount( m_id );
}
void Sapphire::Action::ActionMount::onInterrupt()
{
if( !m_pSource )
return;
//m_pSource->getAsPlayer()->unsetStateFlag( PlayerStateFlag::Occupied1 );
m_pSource->getAsPlayer()->unsetStateFlag( PlayerStateFlag::Casting );
auto control = makeActorControl142( m_pSource->getId(), ActorControlType::CastInterrupt, 0x219, 1, m_id, 0 );
// Note: When cast interrupt from taking too much damage, set the last value to 1. This enables the cast interrupt effect. Example:
// auto control = ActorControlPacket142( m_pSource->getId(), ActorControlType::CastInterrupt, 0x219, 1, m_id, 0 );
m_pSource->sendToInRangeSet( control, true );
}

View file

@ -1,31 +0,0 @@
#ifndef _ACTIONMOUNT_H_
#define _ACTIONMOUNT_H_
#include "ForwardsZone.h"
#include "Action.h"
namespace Sapphire::Action
{
class ActionMount : public Action
{
private:
public:
ActionMount();
~ActionMount();
ActionMount( Entity::CharaPtr pActor, uint16_t mountId );
void onStart() override;
void onFinish() override;
void onInterrupt() override;
};
}
#endif

View file

@ -1,105 +0,0 @@
#include <Util/Util.h>
#include <Exd/ExdDataGenerated.h>
#include <Logging/Logger.h>
#include <Network/CommonActorControl.h>
#include <Util/UtilMath.h>
#include "Network/PacketWrappers/ActorControlPacket142.h"
#include "Network/PacketWrappers/ActorControlPacket143.h"
#include "Network/PacketWrappers/EffectPacket.h"
#include "Actor/Player.h"
#include "ActionTeleport.h"
#include "Framework.h"
using namespace Sapphire::Common;
using namespace Sapphire::Network;
using namespace Sapphire::Network::Packets;
using namespace Sapphire::Network::Packets::Server;
using namespace Sapphire::Network::ActorControl;
Sapphire::Action::ActionTeleport::ActionTeleport()
{
m_handleActionType = HandleActionType::Event;
}
Sapphire::Action::ActionTeleport::ActionTeleport( Entity::CharaPtr pActor, uint16_t targetZone, uint16_t cost, FrameworkPtr pFw )
{
auto pExdData = pFw->get< Data::ExdDataGenerated >();
m_startTime = 0;
m_id = 5;
m_handleActionType = HandleActionType::Teleport;
m_castTime = pExdData->get< Sapphire::Data::Action >( 5 )->cast100ms * 100; // TODO: Add security checks.
m_pSource = pActor;
m_bInterrupt = false;
m_targetAetheryte = targetZone;
m_cost = cost;
}
Sapphire::Action::ActionTeleport::~ActionTeleport()
{
}
void Sapphire::Action::ActionTeleport::onStart()
{
if( !m_pSource )
return;
m_startTime = Util::getTimeMs();
auto castPacket = makeZonePacket< FFXIVIpcActorCast >( getId() );
castPacket->data().action_id = 5;
castPacket->data().unknown = 1;
castPacket->data().cast_time = 5.0f;
castPacket->data().target_id = m_pSource->getId();
m_pSource->sendToInRangeSet( castPacket, true );
m_pSource->getAsPlayer()->setStateFlag( PlayerStateFlag::Casting );
}
void Sapphire::Action::ActionTeleport::onFinish()
{
if( !m_pSource )
return;
auto pPlayer = m_pSource->getAsPlayer();
// check we can finish teleporting
if( pPlayer->getCurrency( Common::CurrencyType::Gil ) < m_cost )
{
onInterrupt();
return;
}
pPlayer->removeCurrency( Common::CurrencyType::Gil, m_cost );
pPlayer->unsetStateFlag( PlayerStateFlag::Casting );
// TODO: not sure if this ever gets sent
//auto control = makeActorControl142( m_pSource->getId(), Common::ActorControlType::TeleportDone );
//m_pSource->sendToInRangeSet( control, false );
pPlayer->setZoningType( ZoneingType::Teleport );
auto effectPacket = std::make_shared< Server::EffectPacket >( getId(), pPlayer->getId(), 5 );
effectPacket->setRotation( Util::floatToUInt16Rot( pPlayer->getRot() ) );
pPlayer->sendToInRangeSet( effectPacket, true );
pPlayer->teleport( m_targetAetheryte );
}
void Sapphire::Action::ActionTeleport::onInterrupt()
{
if( !m_pSource )
return;
m_pSource->getAsPlayer()->unsetStateFlag( PlayerStateFlag::Casting );
auto control = makeActorControl142( m_pSource->getId(), ActorControlType::CastInterrupt, 0x219, 0x04, m_id, 0 );
m_pSource->sendToInRangeSet( control, true );
}

View file

@ -1,33 +0,0 @@
#ifndef _ACTIONTELEPORT_H_
#define _ACTIONTELEPORT_H_
#include "ForwardsZone.h"
#include "Action.h"
namespace Sapphire::Action
{
class ActionTeleport : public Action
{
private:
uint16_t m_targetAetheryte;
uint16_t m_cost;
public:
ActionTeleport();
~ActionTeleport();
ActionTeleport( Entity::CharaPtr pActor, uint16_t action, uint16_t cost, FrameworkPtr pFw );
void onStart() override;
void onFinish() override;
void onInterrupt() override;
};
}
#endif

View file

@ -17,34 +17,25 @@ using namespace Sapphire::Network::Packets;
using namespace Sapphire::Network::Packets::Server;
using namespace Sapphire::Network::ActorControl;
Sapphire::Action::EventAction::EventAction()
{
m_handleActionType = HandleActionType::Event;
}
Sapphire::Action::EventAction::EventAction( Entity::CharaPtr pActor, uint32_t eventId, uint16_t action,
ActionCallback finishRef, ActionCallback interruptRef, uint64_t additional,
FrameworkPtr pFw )
{
m_additional = additional;
m_handleActionType = HandleActionType::Event;
m_eventId = eventId;
m_id = action;
m_pFw = pFw;
auto pExdData = pFw->get< Data::ExdDataGenerated >();
m_castTime = pExdData->get< Sapphire::Data::EventAction >( action )->castTime * 1000; // TODO: Add security checks.
m_onActionFinishClb = finishRef;
m_onActionInterruptClb = interruptRef;
m_pSource = pActor;
m_bInterrupt = false;
m_castTimeMs = pExdData->get< Sapphire::Data::EventAction >( action )->castTime * 1000; // TODO: Add security checks.
m_onActionFinishClb = std::move( finishRef );
m_onActionInterruptClb = std::move( interruptRef );
m_pSource = std::move( pActor );
m_interruptType = Common::ActionInterruptType::None;
}
Sapphire::Action::EventAction::~EventAction()
{
Sapphire::Action::EventAction::~EventAction() = default;
}
void Sapphire::Action::EventAction::onStart()
void Sapphire::Action::EventAction::start()
{
if( !m_pSource )
return;
@ -63,7 +54,7 @@ void Sapphire::Action::EventAction::onStart()
m_pSource->sendToInRangeSet( control );
}
void Sapphire::Action::EventAction::onFinish()
void Sapphire::Action::EventAction::execute()
{
if( !m_pSource )
return;
@ -99,7 +90,7 @@ void Sapphire::Action::EventAction::onFinish()
}
void Sapphire::Action::EventAction::onInterrupt()
void Sapphire::Action::EventAction::interrupt()
{
if( !m_pSource )
return;

View file

@ -13,18 +13,16 @@ namespace Sapphire::Action
{
public:
EventAction();
~EventAction();
virtual ~EventAction();
EventAction( Entity::CharaPtr pActor, uint32_t eventId, uint16_t action,
ActionCallback finishRef, ActionCallback interruptRef, uint64_t additional, FrameworkPtr pFw );
void onStart() override;
void start() override;
void onFinish() override;
void execute() override;
void onInterrupt() override;
void interrupt() override;
private:
uint32_t m_eventId;

View file

@ -1,115 +0,0 @@
#include <string.h>
#include <Util/Util.h>
#include <Util/UtilMath.h>
#include <Logging/Logger.h>
#include <Network/CommonActorControl.h>
#include "Network/PacketWrappers/ActorControlPacket142.h"
#include "Network/PacketWrappers/ActorControlPacket143.h"
#include "Network/PacketWrappers/EffectPacket.h"
#include "Actor/Player.h"
#include "EventItemAction.h"
#include "Framework.h"
using namespace Sapphire::Common;
using namespace Sapphire::Network;
using namespace Sapphire::Network::Packets;
using namespace Sapphire::Network::Packets::Server;
using namespace Sapphire::Network::ActorControl;
Sapphire::Action::EventItemAction::EventItemAction()
{
m_handleActionType = HandleActionType::Event;
}
Sapphire::Action::EventItemAction::EventItemAction( Entity::CharaPtr 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;
// TODO: read the cast time from the action itself
m_castTime = 3000;
m_onActionFinishClb = finishRef;
m_onActionInterruptClb = interruptRef;
m_pSource = pActor;
m_bInterrupt = false;
}
Sapphire::Action::EventItemAction::~EventItemAction() = default;
void Sapphire::Action::EventItemAction::onStart()
{
if( !m_pSource )
return;
m_startTime = Util::getTimeMs();
auto castPacket = makeZonePacket< FFXIVIpcActorCast >( m_pSource->getId() );
castPacket->data().action_id = 1;
castPacket->data().unknown = 3;
castPacket->data().unknown_1 = m_id;
castPacket->data().cast_time = 3.0f;
castPacket->data().target_id = m_pSource->getId();
m_pSource->sendToInRangeSet( castPacket, true );
m_pSource->getAsPlayer()->setStateFlag( PlayerStateFlag::Casting );
}
void Sapphire::Action::EventItemAction::onFinish()
{
if( !m_pSource )
return;
try
{
auto effectPacket = std::make_shared< Server::EffectPacket >( m_pSource->getId(), m_additional, m_id );
effectPacket->setAnimationId( 1 );
effectPacket->setRotation( Util::floatToUInt16Rot( m_pSource->getRot() ) );
m_pSource->getAsPlayer()->unsetStateFlag( Common::PlayerStateFlag::Casting );
m_pSource->sendToInRangeSet( effectPacket, true );
if( m_onActionFinishClb )
m_onActionFinishClb( *m_pSource->getAsPlayer(), m_eventId, m_additional );
}
catch( std::exception& e )
{
Logger::error( e.what() );
}
}
void Sapphire::Action::EventItemAction::onInterrupt()
{
if( !m_pSource )
return;
try
{
auto control = makeActorControl142( m_pSource->getId(), ActorControlType::CastInterrupt, 0x219, 0x04, m_id );
if( m_pSource->isPlayer() )
{
m_pSource->getAsPlayer()->unsetStateFlag( PlayerStateFlag::Casting );
m_pSource->sendToInRangeSet( control, true );
}
else
m_pSource->sendToInRangeSet( control );
if( m_onActionInterruptClb )
m_onActionInterruptClb( *m_pSource->getAsPlayer(), m_eventId, m_additional );
}
catch( std::exception& e )
{
Logger::error( e.what() );
}
}

View file

@ -1,38 +0,0 @@
#ifndef _EVENTITEMACTION_H_
#define _EVENTITEMACTION_H_
#include "ForwardsZone.h"
#include "Action.h"
namespace Sapphire::Action
{
class EventItemAction : public Action
{
public:
EventItemAction();
~EventItemAction();
EventItemAction( Entity::CharaPtr pActor, uint32_t eventId, uint16_t action,
ActionCallback finishRef, ActionCallback interruptRef, uint64_t additional );
void onStart() override;
void onFinish() override;
void onInterrupt() override;
private:
uint32_t m_eventId;
uint64_t m_additional;
ActionCallback m_onActionFinishClb;
ActionCallback m_onActionInterruptClb;
};
}
#endif

View file

@ -6,9 +6,6 @@
#include <Util/UtilMath.h>
#include <utility>
#include "Action/Action.h"
#include "Action/ActionCollision.h"
#include "Territory/Zone.h"
#include "Network/GameConnection.h"

View file

@ -23,7 +23,6 @@
#include "Navi/NaviProvider.h"
#include "StatusEffect/StatusEffect.h"
#include "Action/ActionCollision.h"
#include "ServerMgr.h"
#include "Session.h"
#include "Math/CalcBattle.h"

View file

@ -7,7 +7,6 @@
#include "Forwards.h"
#include "Action/Action.h"
#include "Territory/Zone.h"
@ -19,7 +18,7 @@
#include "Network/PacketWrappers/EffectPacket.h"
#include "StatusEffect/StatusEffect.h"
#include "Action/ActionCollision.h"
#include "Action/Action.h"
#include "ServerMgr.h"
#include "Session.h"
#include "Math/CalcBattle.h"
@ -109,12 +108,6 @@ Sapphire::Common::ClassJob Sapphire::Entity::Chara::getClass() const
return m_class;
}
/*! \return current class or job as int32_t ( this feels pointless ) */
uint8_t Sapphire::Entity::Chara::getClassAsInt() const
{
return static_cast< uint8_t >( m_class );
}
/*! \param ClassJob to set */
void Sapphire::Entity::Chara::setClass( Common::ClassJob classJob )
{
@ -418,7 +411,7 @@ void Sapphire::Entity::Chara::autoAttack( CharaPtr pTarget )
auto effectPacket = std::make_shared< Server::EffectPacket >( getId(), pTarget->getId(), 7 );
effectPacket->setRotation( Util::floatToUInt16Rot( getRot() ) );
Server::EffectEntry effectEntry{};
Common::EffectEntry effectEntry{};
effectEntry.value = damage;
effectEntry.effectType = ActionEffectType::Damage;
effectEntry.hitSeverity = ActionHitSeverityType::NormalDamage;
@ -431,145 +424,6 @@ void Sapphire::Entity::Chara::autoAttack( CharaPtr pTarget )
}
}
/*!
Skill Handler.
\param GamePacketPtr to send
\param bool should be send to self?
*/
void Sapphire::Entity::Chara::handleScriptSkill( uint32_t type, uint16_t actionId, uint64_t param1,
uint64_t param2, Entity::Chara& target )
{
auto pExdData = m_pFw->get< Data::ExdDataGenerated >();
if( isPlayer() )
{
getAsPlayer()->sendDebug( "{0}", target.getId() );
getAsPlayer()->sendDebug( "Handle script skill type: {0}", type );
}
auto actionInfoPtr = pExdData->get< Sapphire::Data::Action >( actionId );
// Todo: Effect packet generator. 90% of this is basically setting params and it's basically unreadable.
// Prepare packet. This is seemingly common for all packets in the action handler.
auto effectPacket = std::make_shared< Server::EffectPacket >( getId(), target.getId(), actionId );
effectPacket->setRotation( Util::floatToUInt16Rot( getRot() ) );
// Todo: for each actor, calculate how much damage the calculated value should deal to them - 2-step damage calc. we only have 1-step
switch( type )
{
case ActionEffectType::Damage:
{
Server::EffectEntry effectEntry{};
effectEntry.value = static_cast< uint16_t >( param1 );
effectEntry.effectType = ActionEffectType::Damage;
effectEntry.hitSeverity = ActionHitSeverityType::NormalDamage;
effectPacket->addEffect( effectEntry );
if( ( actionInfoPtr->castType == 1 && actionInfoPtr->effectRange != 0 ) ||
( actionInfoPtr->castType != 1 ) )
{
// If action on this specific target is valid...
if( isPlayer() && !ActionCollision::isActorApplicable( target, TargetFilter::Enemies ) )
break;
sendToInRangeSet( effectPacket, true );
if( target.isAlive() )
target.onActionHostile( getAsChara() );
target.takeDamage( static_cast< uint32_t >( param1 ) );
}
else
{
auto actorsCollided = ActionCollision::getActorsHitFromAction( target.getPos(), getInRangeActors( true ),
actionInfoPtr, TargetFilter::Enemies );
for( const auto& pHitActor : actorsCollided )
{
effectPacket->setTargetActor( pHitActor->getId() );
// todo: send to range of what? ourselves? when mob script hits this is going to be lacking
sendToInRangeSet( effectPacket, true );
if( pHitActor->getAsChara()->isAlive() )
pHitActor->getAsChara()->onActionHostile( getAsChara() );
pHitActor->getAsChara()->takeDamage( static_cast< uint32_t >( param1 ) );
// Debug
if( isPlayer() )
{
if( pHitActor->isPlayer() )
getAsPlayer()->sendDebug( "AoE hit actor#{0} ({1})", pHitActor->getId(), pHitActor->getAsChara()->getName() );
else
getAsPlayer()->sendDebug( "AoE hit actor#{0}", pHitActor->getId() );
}
}
}
break;
}
case ActionEffectType::Heal:
{
uint32_t calculatedHeal = Math::CalcBattle::calculateHealValue( getAsPlayer(),
static_cast< uint32_t >( param1 ),
m_pFw );
Server::EffectEntry effectEntry{};
effectEntry.value = calculatedHeal;
effectEntry.effectType = ActionEffectType::Heal;
effectEntry.hitSeverity = ActionHitSeverityType::NormalHeal;
effectPacket->addEffect( effectEntry );
if( ( actionInfoPtr->castType == 1 && actionInfoPtr->effectRange != 0 ) || actionInfoPtr->castType != 1 )
{
if( isPlayer() && !ActionCollision::isActorApplicable( target, TargetFilter::Allies ) )
break;
sendToInRangeSet( effectPacket, true );
target.heal( calculatedHeal );
}
else
{
// todo: get proper packets: the following was just kind of thrown together from what we know.
// atm buggy (packets look "delayed" from client)
auto actorsCollided = ActionCollision::getActorsHitFromAction( target.getPos(), getInRangeActors( true ),
actionInfoPtr, TargetFilter::Allies );
for( const auto& pHitActor : actorsCollided )
{
effectPacket->setTargetActor( pHitActor->getId() );
sendToInRangeSet( effectPacket, true );
pHitActor->getAsChara()->heal( calculatedHeal );
// Debug
if( isPlayer() )
{
if( pHitActor->isPlayer() )
getAsPlayer()->sendDebug( "AoE hit actor#{0} ({1})", pHitActor->getId(), pHitActor->getAsChara()->getName() );
else
getAsPlayer()->sendDebug( "AoE hit actor#{0}", pHitActor->getId() );
}
}
}
break;
}
default:
break;
}
}
/*! \param StatusEffectPtr to be applied to the actor */
void Sapphire::Entity::Chara::addStatusEffect( StatusEffect::StatusEffectPtr pEffect )
{

View file

@ -180,8 +180,6 @@ namespace Sapphire::Entity
Common::ClassJob getClass() const;
uint8_t getClassAsInt() const;
void setClass( Common::ClassJob classJob );
void setTargetId( uint64_t targetId );
@ -212,9 +210,6 @@ namespace Sapphire::Entity
void setStatus( Common::ActorStatus status );
void
handleScriptSkill( uint32_t type, uint16_t actionId, uint64_t param1, uint64_t param2, Entity::Chara& target );
virtual void autoAttack( CharaPtr pTarget );
virtual void onDeath() {};

View file

@ -18,8 +18,6 @@
#include "Network/PacketWrappers/UpdateHpMpTpPacket.h"
#include "Network/PacketWrappers/EffectPacket.h"
#include "StatusEffect/StatusEffect.h"
#include "Action/ActionCollision.h"
#include "ServerMgr.h"
#include "Session.h"
#include "Math/CalcBattle.h"

View file

@ -35,9 +35,6 @@
#include "Script/ScriptMgr.h"
#include "Action/Action.h"
#include "Action/ActionTeleport.h"
#include "Action/EventAction.h"
#include "Action/EventItemAction.h"
#include "Math/CalcStats.h"
#include "Math/CalcBattle.h"
@ -1555,7 +1552,7 @@ void Sapphire::Entity::Player::autoAttack( CharaPtr pTarget )
auto effectPacket = std::make_shared< Server::EffectPacket >( getId(), pTarget->getId(), 8 );
effectPacket->setRotation( Util::floatToUInt16Rot( getRot() ) );
Server::EffectEntry entry{};
Common::EffectEntry entry{};
entry.value = damage;
entry.effectType = Common::ActionEffectType::Damage;
entry.hitSeverity = Common::ActionHitSeverityType::NormalDamage;
@ -1569,7 +1566,7 @@ void Sapphire::Entity::Player::autoAttack( CharaPtr pTarget )
auto effectPacket = std::make_shared< Server::EffectPacket >( getId(), pTarget->getId(), 7 );
effectPacket->setRotation( Util::floatToUInt16Rot( getRot() ) );
Server::EffectEntry entry{};
Common::EffectEntry entry{};
entry.value = damage;
entry.effectType = Common::ActionEffectType::Damage;
entry.hitSeverity = Common::ActionHitSeverityType::NormalDamage;
@ -1833,9 +1830,9 @@ void Sapphire::Entity::Player::emoteInterrupt()
sendToInRangeSet( makeActorControl142( getId(), ActorControlType::EmoteInterrupt ) );
}
void Sapphire::Entity::Player::teleportQuery( uint16_t aetheryteId, FrameworkPtr pFw )
void Sapphire::Entity::Player::teleportQuery( uint16_t aetheryteId )
{
auto pExdData = pFw->get< Data::ExdDataGenerated >();
auto pExdData = m_pFw->get< Data::ExdDataGenerated >();
// TODO: only register this action if enough gil is in possession
auto targetAetheryte = pExdData->get< Sapphire::Data::Aetheryte >( aetheryteId );
@ -1850,7 +1847,7 @@ void Sapphire::Entity::Player::teleportQuery( uint16_t aetheryteId, FrameworkPtr
std::pow( fromAetheryte->aetherstreamY - targetAetheryte->aetherstreamY, 2 ) ) / 2 ) + 100 );
// cap at 999 gil
cost = cost > uint16_t{ 999 } ? uint16_t{ 999 } : cost;
cost = std::min< uint16_t >( 999, cost );
bool insufficientGil = getCurrency( Common::CurrencyType::Gil ) < cost;
// TODO: figure out what param1 really does
@ -1858,13 +1855,26 @@ void Sapphire::Entity::Player::teleportQuery( uint16_t aetheryteId, FrameworkPtr
if( !insufficientGil )
{
Action::ActionPtr pActionTeleport;
pActionTeleport = Action::make_ActionTeleport( getAsPlayer(), aetheryteId, cost, pFw );
setCurrentAction( pActionTeleport );
m_teleportQuery.targetAetheryte = aetheryteId;
m_teleportQuery.cost = cost;
}
else
{
clearTeleportQuery();
}
}
}
Sapphire::Common::PlayerTeleportQuery Sapphire::Entity::Player::getTeleportQuery() const
{
return m_teleportQuery;
}
void Sapphire::Entity::Player::clearTeleportQuery()
{
memset( &m_teleportQuery, 0x0, sizeof( Common::PlayerTeleportQuery ) );
}
uint8_t Sapphire::Entity::Player::getNextObjSpawnIndexForActorId( uint32_t actorId )
{
auto index = m_objSpawnIndexAllocator.getNextFreeSpawnIndex( actorId );

View file

@ -52,12 +52,12 @@ namespace Sapphire::Entity
// EventHandlers
//////////////////////////////////////////////////////////////////////////////////////////////////////
/*! start an event action */
void eventActionStart( uint32_t eventId, uint32_t action, ActionCallback finishCallback,
ActionCallback interruptCallback, uint64_t additional );
void eventActionStart( uint32_t eventId, uint32_t action, Action::ActionCallback finishCallback,
Action::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 );
void eventItemActionStart( uint32_t eventId, uint32_t action, Action::ActionCallback finishCallback,
Action::ActionCallback interruptCallback, uint64_t additional );
/*! start/register a normal event */
void
@ -531,7 +531,11 @@ namespace Sapphire::Entity
void teleport( uint16_t aetheryteId, uint8_t type = 1 );
/*! query teleport of a specified type */
void teleportQuery( uint16_t aetheryteId, FrameworkPtr pFw );
void teleportQuery( uint16_t aetheryteId );
Common::PlayerTeleportQuery getTeleportQuery() const;
void clearTeleportQuery();
/*! prepares zoning / fades out the screen */
void prepareZoning( uint16_t targetZone, bool fadeOut, uint8_t fadeOutTime = 0, uint16_t animation = 0 );
@ -1086,6 +1090,8 @@ namespace Sapphire::Entity
uint32_t m_mount;
uint32_t m_emoteMode;
Common::PlayerTeleportQuery m_teleportQuery;
Util::SpawnIndexAllocator< uint8_t > m_objSpawnIndexAllocator;
Util::SpawnIndexAllocator< uint8_t > m_actorSpawnIndexAllocator;
};

View file

@ -11,13 +11,12 @@
#include "Network/PacketWrappers/EventFinishPacket.h"
#include "Network/PacketWrappers/DirectorPlayScenePacket.h"
#include "Action/EventAction.h"
#include "Action/EventItemAction.h"
#include "Territory/Zone.h"
#include "ServerMgr.h"
#include "Framework.h"
#include "Action/EventAction.h"
using namespace Sapphire::Common;
using namespace Sapphire::Network::Packets;
using namespace Sapphire::Network::Packets::Server;
@ -279,14 +278,13 @@ void Sapphire::Entity::Player::eventFinish( uint32_t eventId, uint32_t freePlaye
void Sapphire::Entity::Player::eventActionStart( uint32_t eventId,
uint32_t action,
ActionCallback finishCallback,
ActionCallback interruptCallback,
Action::ActionCallback finishCallback,
Action::ActionCallback interruptCallback,
uint64_t additional )
{
auto pEventAction = Action::make_EventAction( getAsChara(), eventId, action,
finishCallback, interruptCallback, additional, m_pFw );
setCurrentAction( pEventAction );
auto pEvent = getEvent( eventId );
if( !pEvent && getEventCount() )
@ -303,22 +301,24 @@ void Sapphire::Entity::Player::eventActionStart( uint32_t eventId,
if( pEvent )
pEvent->setPlayedScene( true );
pEventAction->onStart();
setCurrentAction( pEventAction );
pEventAction->start();
}
void Sapphire::Entity::Player::eventItemActionStart( uint32_t eventId,
uint32_t action,
ActionCallback finishCallback,
ActionCallback interruptCallback,
Action::ActionCallback finishCallback,
Action::ActionCallback interruptCallback,
uint64_t additional )
{
Action::ActionPtr pEventItemAction = Action::make_EventItemAction( getAsChara(), eventId, action,
finishCallback, interruptCallback, additional );
setCurrentAction( pEventItemAction );
pEventItemAction->onStart();
// Action::ActionPtr pEventItemAction = Action::make_EventItemAction( getAsChara(), eventId, action,
// finishCallback, interruptCallback, additional );
//
// setCurrentAction( pEventItemAction );
//
// pEventItemAction->onStart();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

View file

@ -751,7 +751,7 @@ void Sapphire::Entity::Player::swapItem( uint16_t fromInventoryId, uint8_t fromS
void Sapphire::Entity::Player::discardItem( uint16_t fromInventoryId, uint8_t fromSlotId )
{
// i am not entirely sure how this should be generated or if it even is important for us...
uint32_t transactionId = getNextInventorySequence();
uint32_t sequence = getNextInventorySequence();
auto fromItem = m_storageMap[ fromInventoryId ]->getItem( fromSlotId );
@ -761,7 +761,7 @@ void Sapphire::Entity::Player::discardItem( uint16_t fromInventoryId, uint8_t fr
updateContainer( fromInventoryId, fromSlotId, nullptr );
auto invTransPacket = makeZonePacket< FFXIVIpcInventoryTransaction >( getId() );
invTransPacket->data().transactionId = transactionId;
invTransPacket->data().sequence = sequence;
invTransPacket->data().ownerId = getId();
invTransPacket->data().storageId = fromInventoryId;
invTransPacket->data().catalogId = fromItem->getId();
@ -771,8 +771,8 @@ void Sapphire::Entity::Player::discardItem( uint16_t fromInventoryId, uint8_t fr
queuePacket( invTransPacket );
auto invTransFinPacket = makeZonePacket< FFXIVIpcInventoryTransactionFinish >( getId() );
invTransFinPacket->data().transactionId = transactionId;
invTransFinPacket->data().transactionId1 = transactionId;
invTransFinPacket->data().sequenceId = sequence;
invTransFinPacket->data().sequenceId1 = sequence;
queuePacket( invTransFinPacket );
}
@ -883,7 +883,7 @@ Sapphire::ItemPtr Sapphire::Entity::Player::dropInventoryItem( Sapphire::Common:
// send inv update
auto invTransPacket = makeZonePacket< FFXIVIpcInventoryTransaction >( getId() );
invTransPacket->data().transactionId = seq;
invTransPacket->data().sequence = seq;
invTransPacket->data().ownerId = getId();
invTransPacket->data().storageId = type;
invTransPacket->data().catalogId = item->getId();
@ -893,8 +893,8 @@ Sapphire::ItemPtr Sapphire::Entity::Player::dropInventoryItem( Sapphire::Common:
queuePacket( invTransPacket );
auto invTransFinPacket = makeZonePacket< FFXIVIpcInventoryTransactionFinish >( getId() );
invTransFinPacket->data().transactionId = seq;
invTransFinPacket->data().transactionId1 = seq;
invTransFinPacket->data().sequenceId = seq;
invTransFinPacket->data().sequenceId1 = seq;
queuePacket( invTransFinPacket );
return item;

View file

@ -84,11 +84,9 @@ TYPE_FORWARD( EventHandler );
namespace Action
{
TYPE_FORWARD( Action );
TYPE_FORWARD( ActionTeleport );
TYPE_FORWARD( ActionCast );
TYPE_FORWARD( ActionMount );
TYPE_FORWARD( EventAction );
TYPE_FORWARD( EventItemAction );
using ActionCallback = std::function< void( Entity::Player&, uint32_t, uint64_t ) >;
}
namespace Network
@ -117,8 +115,6 @@ namespace Scripting
class NativeScriptMgr;
}
typedef std::function< void( Entity::Player&, uint32_t, uint64_t ) > ActionCallback;
}

View file

@ -0,0 +1,122 @@
#include "ActionMgr.h"
#include "Action/Action.h"
#include "Script/ScriptMgr.h"
#include "Actor/Player.h"
#include <Exd/ExdDataGenerated.h>
#include "Framework.h"
#include <Network/PacketWrappers/EffectPacket.h>
using namespace Sapphire;
World::Manager::ActionMgr::ActionMgr( Sapphire::FrameworkPtr pFw ) :
BaseManager( pFw )
{
}
void World::Manager::ActionMgr::handleAoEPlayerAction( Entity::Player& player, uint32_t actionId,
Data::ActionPtr actionData, Common::FFXIVARR_POSITION3 pos )
{
player.sendDebug( "got aoe act: {0}", actionData->name );
auto action = Action::make_Action( player.getAsPlayer(), actionId, actionData, framework() );
if( !action->init() )
return;
if( !actionData->targetArea )
{
// not an action that has an aoe, cancel it
action->interrupt();
return;
}
action->setPos( pos );
bootstrapAction( player, action, *actionData );
}
void World::Manager::ActionMgr::handleTargetedPlayerAction( Entity::Player& player, uint32_t actionId,
Data::ActionPtr actionData, uint64_t targetId )
{
auto action = Action::make_Action( player.getAsPlayer(), actionId, actionData, framework() );
if( !action->init() )
return;
// cancel any aoe actions casted with this packet
if( actionData->targetArea )
{
action->interrupt();
return;
}
action->setTargetId( targetId );
bootstrapAction( player, action, *actionData );
}
void World::Manager::ActionMgr::handleItemAction( Sapphire::Entity::Player& player, uint32_t itemId,
Data::ItemActionPtr itemActionData,
uint16_t itemSourceSlot, uint16_t itemSourceContainer )
{
player.sendDebug( "got item act: {0}, slot: {1}, container: {2}", itemId, itemSourceSlot, itemSourceContainer );
// todo: check we have item & remove item from inventory
switch( itemActionData->type )
{
default:
{
player.sendDebug( "ItemAction type {0} not supported.", itemActionData->type );
break;
}
case Common::ItemActionType::ItemActionVFX:
{
handleItemActionVFX( player, itemId, itemActionData->data[ 0 ] );
break;
}
}
}
void World::Manager::ActionMgr::bootstrapAction( Entity::Player& player,
Action::ActionPtr currentAction,
Data::Action& actionData )
{
if( !currentAction->precheck() )
{
// forcefully interrupt the action and reset the cooldown
currentAction->interrupt();
return;
}
// if we have a cast time we want to associate the action with the player so update is called
if( currentAction->hasCastTime() )
{
player.setCurrentAction( currentAction );
}
// todo: what do in cases of swiftcast/etc? script callback?
currentAction->start();
}
void World::Manager::ActionMgr::handleItemActionVFX( Sapphire::Entity::Player& player, uint32_t itemId, uint16_t vfxId )
{
Common::EffectEntry effect{};
effect.effectType = Common::ActionEffectType::VFX;
effect.value = vfxId;
auto effectPacket = std::make_shared< Network::Packets::Server::EffectPacket >( player.getId(), player.getId(), itemId );
effectPacket->setTargetActor( player.getId() );
effectPacket->setAnimationId( Common::ItemActionType::ItemActionVFX );
effectPacket->setDisplayType( Common::ActionEffectDisplayType::ShowItemName );
effectPacket->addEffect( effect );
player.sendToInRangeSet( effectPacket, true );
}

View file

@ -0,0 +1,40 @@
#ifndef SAPPHIRE_ACTIONMGR_H
#define SAPPHIRE_ACTIONMGR_H
#include "BaseManager.h"
#include "ForwardsZone.h"
namespace Sapphire::Data
{
struct Action;
using ActionPtr = std::shared_ptr< Action >;
struct ItemAction;
using ItemActionPtr = std::shared_ptr< ItemAction >;
}
namespace Sapphire::World::Manager
{
class ActionMgr : public Manager::BaseManager
{
public:
explicit ActionMgr( FrameworkPtr pFw );
~ActionMgr() = default;
void handleTargetedPlayerAction( Entity::Player& player, uint32_t actionId,
Data::ActionPtr actionData, uint64_t targetId );
void handleAoEPlayerAction( Entity::Player& player, uint32_t actionId,
Data::ActionPtr actionData, Common::FFXIVARR_POSITION3 pos );
void handleItemAction( Entity::Player& player, uint32_t itemId, Data::ItemActionPtr itemActionData,
uint16_t itemSourceSlot, uint16_t itemSourceContainer );
private:
void bootstrapAction( Entity::Player& player, Action::ActionPtr currentAction, Data::Action& actionData );
// item action handlers
void handleItemActionVFX( Entity::Player& player, uint32_t itemId, uint16_t vfxId );
};
}
#endif //SAPPHIRE_ACTIONMGR_H

View file

@ -73,6 +73,7 @@ Sapphire::Network::GameConnection::GameConnection( Sapphire::Network::HivePtr pH
setZoneHandler( ClientZoneIpcType::DiscoveryHandler, "DiscoveryHandler", &GameConnection::discoveryHandler );
setZoneHandler( ClientZoneIpcType::SkillHandler, "ActionHandler", &GameConnection::actionHandler );
setZoneHandler( ClientZoneIpcType::AoESkillHandler, "AoESkillHandler", &GameConnection::aoeActionHandler );
setZoneHandler( ClientZoneIpcType::GMCommand1, "GMCommand1", &GameConnection::gm1Handler );
setZoneHandler( ClientZoneIpcType::GMCommand2, "GMCommand2", &GameConnection::gm2Handler );

View file

@ -14,6 +14,7 @@
namespace Sapphire::Network::Packets
{
class GamePacket;
class PacketContainer;
}
namespace Sapphire::Network
@ -156,6 +157,8 @@ namespace Sapphire::Network
DECLARE_HANDLER( actionHandler );
DECLARE_HANDLER( aoeActionHandler );
DECLARE_HANDLER( gm1Handler );
DECLARE_HANDLER( gm2Handler );

View file

@ -1,37 +1,18 @@
#include <Common.h>
#include <Network/CommonNetwork.h>
#include <Exd/ExdDataGenerated.h>
#include <Network/GamePacketNew.h>
#include <Network/PacketContainer.h>
#include <Network/CommonActorControl.h>
#include <Network/PacketDef/Zone/ClientZoneDef.h>
#include <Logging/Logger.h>
#include <Util/Util.h>
#include <Actor/Player.h>
#include "Network/GameConnection.h"
#include "Network/PacketWrappers/ServerNoticePacket.h"
#include "Network/PacketWrappers/ActorControlPacket142.h"
#include "Network/PacketWrappers/ActorControlPacket143.h"
#include "Network/PacketWrappers/ActorControlPacket144.h"
#include "Network/PacketWrappers/MoveActorPacket.h"
#include "Network/PacketWrappers/PlayerStateFlagsPacket.h"
#include "Manager/DebugCommandMgr.h"
#include "Action/Action.h"
#include "Action/ActionCast.h"
#include "Action/ActionMount.h"
#include "Script/ScriptMgr.h"
#include "Session.h"
#include "Framework.h"
#include "Manager/ActionMgr.h"
using namespace Sapphire::Common;
using namespace Sapphire::Network::Packets;
using namespace Sapphire::Network::Packets::Server;
using namespace Sapphire::Network::ActorControl;
void Sapphire::Network::GameConnection::actionHandler( FrameworkPtr pFw,
const Packets::FFXIVARR_PACKET_RAW& inPacket,
@ -40,96 +21,96 @@ void Sapphire::Network::GameConnection::actionHandler( FrameworkPtr pFw,
const auto packet = ZoneChannelPacket< Client::FFXIVIpcSkillHandler >( inPacket );
const auto type = packet.data().type;
const auto action = packet.data().actionId;
const auto useCount = packet.data().useCount;
const auto actionId = packet.data().actionId;
const auto sequence = packet.data().sequence;
const auto targetId = packet.data().targetId;
const auto itemSourceSlot = packet.data().itemSourceSlot;
const auto itemSourceContainer = packet.data().itemSourceContainer;
player.sendDebug( "Skill type: {0}", type );
// player.sendDebug( "Skill type: {0}, sequence: {1}, actionId: {2}, targetId: {3}", type, sequence, actionId, targetId );
auto pExdData = pFw->get< Data::ExdDataGenerated >();
auto pScriptMgr = pFw->get< Scripting::ScriptMgr >();
auto exdData = m_pFw->get< Data::ExdDataGenerated >();
assert( exdData );
auto actionMgr = pFw->get< World::Manager::ActionMgr >();
switch( type )
{
default:
{
player.sendDebug( "Skill type {0} not supported. Defaulting to normal action", type );
}
case Common::SkillType::Normal:
if( action < 1000000 ) // normal action
{
std::string actionIdStr = Util::intToHexString( action, 4 );
player.sendDebug( "---------------------------------------" );
player.sendDebug( "ActionHandler ( {0} | {1} | {2} )",
actionIdStr, pExdData->get< Sapphire::Data::Action >( action )->name, targetId );
auto action = exdData->get< Data::Action >( actionId );
player.queuePacket( makeActorControl142( player.getId(), ActorControlType::ActionStart, 0x01, action ) );
// ignore invalid actions
if( !action )
return;
if( action == 5 )
{
auto currentAction = player.getCurrentAction();
// we should always have an action here, if not there is a bug
assert( currentAction );
currentAction->onStart();
}
else
{
Sapphire::Entity::ActorPtr targetActor = player.getAsPlayer();
if( targetId != player.getId() )
{
targetActor = player.lookupTargetById( targetId );
actionMgr->handleTargetedPlayerAction( player, actionId, action, targetId );
break;
}
// Check if we actually have an actor
if( !targetActor )
case Common::SkillType::ItemAction:
{
// todo: interrupt a cast.
player.sendDebug( "Invalid target." );
auto item = exdData->get< Data::Item >( actionId );
if( !item )
return;
if( item->itemAction == 0 )
return;
auto itemAction = exdData->get< Data::ItemAction >( item->itemAction );
if( !itemAction )
return;
actionMgr->handleItemAction( player, actionId, itemAction, itemSourceSlot, itemSourceContainer );
break;
}
case Common::SkillType::MountSkill:
{
break;
}
}
}
void Sapphire::Network::GameConnection::aoeActionHandler( FrameworkPtr pFw,
const Packets::FFXIVARR_PACKET_RAW& inPacket,
Entity::Player& player )
{
const auto packet = ZoneChannelPacket< Client::FFXIVIpcAoESkillHandler >( inPacket );
const auto type = packet.data().type;
const auto actionId = packet.data().actionId;
const auto sequence = packet.data().sequence;
const auto pos = packet.data().pos;
// todo: find out if there are any other action types which actually use this handler
if( type != Common::SkillType::Normal )
{
player.sendDebug( "Skill type {0} not supported by aoe action handler!", type );
return;
}
if( !player.actionHasCastTime( action ) )
{
pScriptMgr->onCastFinish( player, targetActor->getAsChara(), action );
}
else
{
auto pActionCast = Action::make_ActionCast( player.getAsPlayer(), targetActor->getAsChara(), action, m_pFw );
player.setCurrentAction( pActionCast );
player.sendDebug( "setCurrentAction()" );
player.getCurrentAction()->onStart();
}
}
}
else if( action < 2000000 ) // craft action
{
}
else if( action < 3000000 ) // item action
{
auto info = pExdData->get< Sapphire::Data::EventItem >( action );
if( info )
{
pScriptMgr->onEventItem( player, action, info->quest, info->castTime, targetId );
}
}
else if( action > 3000000 ) // unknown
{
}
break;
case Common::SkillType::MountSkill:
player.sendDebug( "Request mount {0}", action );
auto pActionMount = Action::make_ActionMount( player.getAsPlayer(), action );
player.setCurrentAction( pActionMount );
player.sendDebug( "setCurrentAction()" );
player.getCurrentAction()->onStart();
break;
}
// player.sendDebug( "Skill type: {0}, sequence: {1}, actionId: {2}, x:{3}, y:{4}, z:{5}",
// type, sequence, actionId, pos.x, pos.y, pos.z );
auto exdData = m_pFw->get< Data::ExdDataGenerated >();
assert( exdData );
auto action = exdData->get< Data::Action >( actionId );
// ignore invalid actions
if( !action )
return;
auto actionMgr = pFw->get< World::Manager::ActionMgr >();
actionMgr->handleAoEPlayerAction( player, actionId, action, pos );
}

View file

@ -26,7 +26,6 @@
#include "Manager/EventMgr.h"
#include "Action/Action.h"
#include "Action/ActionTeleport.h"
#include "Session.h"
@ -140,7 +139,7 @@ void Sapphire::Network::GameConnection::clientTriggerHandler( FrameworkPtr pFw,
case ClientTriggerType::CastCancel: // Cancel cast
{
if( player.getCurrentAction() )
player.getCurrentAction()->setInterrupted();
player.getCurrentAction()->setInterrupted( Common::ActionInterruptType::RegularInterrupt );
break;
}
case ClientTriggerType::Examine:
@ -275,11 +274,15 @@ void Sapphire::Network::GameConnection::clientTriggerHandler( FrameworkPtr pFw,
case ClientTriggerType::Teleport: // Teleport
{
player.teleportQuery( param11, pFw );
player.teleportQuery( param11 );
break;
}
case ClientTriggerType::DyeItem: // Dye item
{
// param11 = item to dye container
// param12 = item to dye slot
// param2 = dye bag container
// param4 = dye bag slot
break;
}
case ClientTriggerType::DirectorInitFinish: // Director init finish

View file

@ -41,7 +41,6 @@
#include "Manager/RNGMgr.h"
#include "Action/Action.h"
#include "Action/ActionTeleport.h"
#include "Session.h"
#include "ServerMgr.h"
@ -197,7 +196,7 @@ void Sapphire::Network::GameConnection::updatePositionHandler( FrameworkPtr pFw,
player.setPos( updatePositionPacket.data().position );
if( ( player.getCurrentAction() != nullptr ) && bPosChanged )
player.getCurrentAction()->setInterrupted();
player.getCurrentAction()->setInterrupted( Common::ActionInterruptType::RegularInterrupt );
// if no one is in range, don't bother trying to send a position update
if( !player.hasInRangeActor() )

View file

@ -27,12 +27,12 @@ namespace Sapphire::Network::Packets::Server
m_data.effectDisplayType = Common::ActionEffectDisplayType::ShowActionName;
}
void addEffect( const Server::EffectEntry& effect )
void addEffect( const Common::EffectEntry& effect )
{
assert( m_data.effectCount <= 8 );
std::memset( m_data.effects, 0, sizeof( Server::EffectEntry ) * 8 );
std::memcpy( &m_data.effects[ m_data.effectCount * 8 ], &effect, sizeof( Server::EffectEntry ) );
std::memset( m_data.effects, 0, sizeof( Common::EffectEntry ) * 8 );
std::memcpy( &m_data.effects[ m_data.effectCount * 8 ], &effect, sizeof( Common::EffectEntry ) );
m_data.effectCount++;
}
@ -41,6 +41,11 @@ namespace Sapphire::Network::Packets::Server
m_data.actionAnimationId = animationId;
}
void setDisplayType( Common::ActionEffectDisplayType displayType )
{
m_data.effectDisplayType = displayType;
}
void setEffectFlags( uint32_t effectFlags )
{
m_data.effectFlags = effectFlags;
@ -58,6 +63,11 @@ namespace Sapphire::Network::Packets::Server
FFXIVPacketBase::setTargetActor( targetId );
}
void setSequence( uint32_t sequence )
{
m_data.sequence = sequence;
}
};
}

View file

@ -88,15 +88,15 @@ namespace Sapphire::ScriptAPI
{
}
void ActionScript::onStart( Entity::Chara& sourceActor, Entity::Chara& targetActor )
void ActionScript::onStart( Sapphire::Action::Action& action )
{
}
void ActionScript::onCastFinish( Entity::Player& player, Entity::Chara& targetActor )
void ActionScript::onExecute( Sapphire::Action::Action& action )
{
}
void ActionScript::onInterrupt( Entity::Chara& sourceActor/*, Sapphire::Entity::Chara targetActor*/ )
void ActionScript::onInterrupt( Sapphire::Action::Action& action )
{
}
@ -141,6 +141,10 @@ namespace Sapphire::ScriptAPI
{
}
void EventScript::onEObjHit( Sapphire::Entity::Player& player, uint64_t actorId )
{
}
///////////////////////////////////////////////////////////////////
EventObjectScript::EventObjectScript( uint32_t eobjId ) :

View file

@ -140,11 +140,11 @@ namespace Sapphire::ScriptAPI
public:
explicit ActionScript( uint32_t abilityId );
virtual void onStart( Sapphire::Entity::Chara& sourceActor, Sapphire::Entity::Chara& targetActor );
virtual void onStart( Sapphire::Action::Action& action );
virtual void onCastFinish( Sapphire::Entity::Player& player, Sapphire::Entity::Chara& targetActor );
virtual void onExecute( Sapphire::Action::Action& action );
virtual void onInterrupt( Sapphire::Entity::Chara& sourceActor/*, Sapphire::Entity::Chara targetActor*/ );
virtual void onInterrupt( Sapphire::Action::Action& action );
};
/*!
@ -180,6 +180,8 @@ namespace Sapphire::ScriptAPI
virtual void onEventHandlerTradeReturn( Sapphire::Entity::Player& player, uint32_t eventId, uint16_t subEvent, uint16_t param,
uint32_t catalogId );
virtual void onEObjHit( Sapphire::Entity::Player& player, uint64_t actorId );
};
/*!

View file

@ -9,6 +9,7 @@
#include "Actor/EventObject.h"
#include "ServerMgr.h"
#include "Event/EventHandler.h"
#include "Action/Action.h"
#include "Manager/EventMgr.h"
@ -299,14 +300,70 @@ bool Sapphire::Scripting::ScriptMgr::onBNpcKill( Entity::Player& player, uint16_
return true;
}
bool Sapphire::Scripting::ScriptMgr::onCastFinish( Entity::Player& player, Entity::CharaPtr pTarget, uint32_t actionId )
bool Sapphire::Scripting::ScriptMgr::onEObjHit( Sapphire::Entity::Player& player, uint64_t actorId )
{
auto script = m_nativeScriptMgr->getScript< Sapphire::ScriptAPI::ActionScript >( actionId );
auto pEventMgr = framework()->get< World::Manager::EventMgr >();
bool didCallScript = false;
for( size_t i = 0; i < 30; i++ )
{
auto activeQuests = player.getQuestActive( static_cast< uint16_t >( i ) );
if( !activeQuests )
continue;
uint32_t questId = activeQuests->c.questId | Event::EventHandler::EventHandlerType::Quest << 16;
auto script = m_nativeScriptMgr->getScript< Sapphire::ScriptAPI::EventScript >( questId );
if( script )
{
didCallScript = true;
std::string objName = pEventMgr->getEventName( questId );
player.sendDebug( "Calling: {0}.onEObjHit actorId#{1}", objName, actorId );
script->onEObjHit( player, actorId );
}
}
return didCallScript;
}
bool Sapphire::Scripting::ScriptMgr::onExecute( Action::Action& action )
{
auto script = m_nativeScriptMgr->getScript< Sapphire::ScriptAPI::ActionScript >( action.getId() );
if( script )
script->onCastFinish( player, *pTarget );
{
script->onExecute( action );
return true;
}
return false;
}
bool Sapphire::Scripting::ScriptMgr::onInterrupt( Action::Action& action )
{
auto script = m_nativeScriptMgr->getScript< Sapphire::ScriptAPI::ActionScript >( action.getId() );
if( script )
{
script->onInterrupt( action );
return true;
}
return false;
}
bool Sapphire::Scripting::ScriptMgr::onStart( Action::Action& action )
{
auto script = m_nativeScriptMgr->getScript< Sapphire::ScriptAPI::ActionScript >( action.getId() );
if( script )
{
script->onStart( action );
return true;
}
return false;
}
bool Sapphire::Scripting::ScriptMgr::onStatusReceive( Entity::CharaPtr pActor, uint32_t effectId )
{

View file

@ -70,7 +70,13 @@ namespace Sapphire::Scripting
bool onBNpcKill( Entity::Player& player, uint16_t nameId );
bool onCastFinish( Entity::Player& pPlayer, Entity::CharaPtr pTarget, uint32_t actionId );
bool onEObjHit( Entity::Player& player, uint64_t actorId );
bool onStart( Action::Action& action );
bool onInterrupt( Action::Action& action );
bool onExecute( Action::Action& action );
bool onStatusReceive( Entity::CharaPtr pActor, uint32_t effectId );

View file

@ -42,6 +42,7 @@
#include "Manager/MarketMgr.h"
#include "Manager/RNGMgr.h"
#include "Manager/NaviMgr.h"
#include "Manager/ActionMgr.h"
using namespace Sapphire::World::Manager;
@ -170,6 +171,9 @@ void Sapphire::World::ServerMgr::run( int32_t argc, char* argv[] )
}
framework()->set< Scripting::ScriptMgr >( pScript );
auto pActionMgr = std::make_shared< Manager::ActionMgr >( framework() );
framework()->set< Manager::ActionMgr >( pActionMgr );
loadBNpcTemplates();
auto pNaviMgr = std::make_shared< Manager::NaviMgr >( framework() );

View file

@ -864,3 +864,8 @@ void Sapphire::Zone::updateSpawnPoints()
}
uint32_t Sapphire::Zone::getNextEffectSequence()
{
return m_effectCounter++;
}

View file

@ -63,6 +63,8 @@ namespace Sapphire
std::vector< Entity::SpawnGroup > m_spawnGroups;
uint32_t m_effectCounter;
public:
Zone();
@ -161,6 +163,8 @@ namespace Sapphire
InstanceContentPtr getAsInstanceContent();
void updateSpawnPoints();
uint32_t getNextEffectSequence();
};
}