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

Convert action lut to JSON

This commit is contained in:
Lucy 2023-01-27 05:23:13 +01:00
parent cc0a7aa70a
commit f3627a9566
15 changed files with 180975 additions and 19337 deletions

View file

@ -15,6 +15,8 @@ add_custom_target( copy_runtime_files ALL
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/web ${CMAKE_BINARY_DIR}/bin/web
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/sql_import.sh ${CMAKE_BINARY_DIR}/bin/sql_import.sh )
file( COPY ${CMAKE_SOURCE_DIR}/data DESTINATION ${CMAKE_BINARY_DIR}/bin )
######################################
# Dependencies and compiler settings #
######################################

82365
data/actions/player.json Normal file

File diff suppressed because it is too large Load diff

26724
deps/nlohmann/json.hpp vendored

File diff suppressed because it is too large Load diff

View file

@ -798,6 +798,103 @@ namespace Sapphire::Common
};
enum class ParamModifier : uint16_t
{
None = 0,
Strength = 1,
Dexterity = 2,
Vitality = 3,
Intelligence = 4,
Mind = 5,
Piety = 6,
HP = 7,
MP = 8,
TP = 9,
GP = 10,
CP = 11,
PhysicalDamage = 12,
MagicDamage = 13,
Delay = 14,
AdditionalEffect = 15,
AttackSpeed = 16,
BlockRate = 17,
BlockStrength = 18,
Parry = 19,
AttackPower = 20,
Defense = 21,
Accuracy = 22,
Evasion = 23,
MagicDefense = 24,
CriticalHitPower = 25,
CriticalHitResilience = 26,
CriticalHit = 27,
CriticalHitEvasion = 28,
SlashingResistance = 29,
PiercingResistance = 30,
BluntResistance = 31,
ProjectileResistance = 32,
AttackMagicPotency = 33,
HealingMagicPotency = 34,
EnhancementMagicPotency = 35,
ElementalBonus = 36,
FireResistance = 37,
IceResistance = 38,
WindResistance = 39,
EarthResistance = 40,
LightningResistance = 41,
WaterResistance = 42,
MagicResistance = 43,
Determination = 44,
SkillSpeed = 45,
SpellSpeed = 46,
Haste = 47,
Morale = 48,
Enmity = 49,
EnmityReduction = 50,
CarefulDesynthesis = 51,
EXPBonus = 52,
Regen = 53,
Refresh = 54,
MainAttribute = 55,
SecondaryAttribute = 56,
SlowResistance = 57,
PetrificationResistance = 58,
ParalysisResistance = 59,
SilenceResistance = 60,
BlindResistance = 61,
PoisonResistance = 62,
StunResistance = 63,
SleepResistance = 64,
BindResistance = 65,
HeavyResistance = 66,
DoomResistance = 67,
ReducedDurabilityLoss = 68,
IncreasedSpiritbondGain = 69,
Craftsmanship = 70,
Control = 71,
Gathering = 72,
Perception = 73,
// Unique modifiers
HPPercent = 1000,
MPPercent = 1001,
TPPercent = 1002,
GPPercent = 1003,
CPPercent = 1004,
PhysicalDamagePercent = 1005,
MagicDamagePercent = 1006,
AttackPowerPercent = 1007,
DefensePercent = 1008,
AccuracyPercent = 1009,
EvasionPercent = 1010,
MagicDefensePercent = 1011,
CriticalHitPowerPercent = 1012,
CriticalHitResiliencePercent = 1013,
CriticalHitPercent = 1014,
EnmityPercent = 1015,
EnmityReductionPercent = 1016,
};
enum struct ActionAspect : uint8_t
{
None = 0, // Doesn't imply unaspected

View file

@ -12,4 +12,3 @@ if (UNIX)
else()
target_link_libraries( action_parse common xivdat mysql zlib)
endif()

File diff suppressed because it is too large Load diff

View file

@ -9,10 +9,12 @@
#include <iostream>
#include <cctype>
#include <set>
#include <string>
#include <Exd/ExdData.h>
#include <Exd/Structs.h>
#include <Logging/Logger.h>
#include <Common.h>
#include <nlohmann/json.hpp>
#include <fstream>
#include <streambuf>
@ -29,6 +31,18 @@ Sapphire::Data::ExdData g_exdDataGen;
std::string datLocation( "C:\\Data\\Dev\\ffxiv3.01\\game\\sqpack" );
//const std::string datLocation( "/mnt/c/Program Files (x86)/Steam/steamapps/common/FINAL FANTASY XIV Online/game/sqpack" );
struct StatusEntry
{
uint16_t id;
std::unordered_map< std::string, uint16_t > modifiers;
};
struct StatusEffect
{
std::vector< StatusEntry > caster;
std::vector< StatusEntry > target;
};
struct ActionEntry
{
uint32_t id;
@ -41,8 +55,37 @@ struct ActionEntry
uint32_t curePotency;
uint32_t restorePercentage;
std::vector< uint32_t > nextCombo{};
StatusEffect statuses;
};
void to_json(nlohmann::ordered_json& j, const StatusEntry& statusEntry)
{
j = nlohmann::ordered_json{
{ "id", statusEntry.id },
{ "modifiers", statusEntry.modifiers }
};
}
void to_json(nlohmann::ordered_json& j, const ActionEntry& action)
{
j = nlohmann::ordered_json{
{ "name", action.name },
{ "potency", action.potency },
{ "comboPotency", action.comboPotency },
{ "flankPotency", action.flankPotency },
{ "frontPotency", action.frontPotency },
{ "rearPotency", action.rearPotency },
{ "curePotency", action.curePotency },
{ "restorePercentage", action.restorePercentage },
{ "nextCombo", action.nextCombo },
{ "statuses", {
{ "caster", action.statuses.caster },
{ "target", action.statuses.target },
}
}
};
}
bool invalidChar( char c )
{
return !( c >= 0 && c < 128 );
@ -89,9 +132,6 @@ int main( int argc, char* argv[] )
Logger::init( "action_parse" );
if( !fs::exists( "ActionLutData.cpp.tmpl" ) )
throw std::runtime_error( "ActionLut.cpp.tmpl is missing in working directory" );
if( argc == 2 )
{
datLocation = std::string( argv[ 1 ] );
@ -267,7 +307,7 @@ int main( int argc, char* argv[] )
// dump entries
Logger::info( "Found {} player actions", actions.size() );
std::string output;
nlohmann::ordered_json output;
Logger::info( std::to_string( traversedCombos.size() ) );
for( const auto& action : actions )
{
@ -279,29 +319,11 @@ int main( int argc, char* argv[] )
// action.first, data.name, data.potency, data.flankPotency, data.frontPotency, data.rearPotency,
// data.curePotency, data.restorePercentage );
auto comboStr = stringVec( data.nextCombo );
if( !comboStr.empty() )
comboStr = " " + comboStr + " ";
auto out = fmt::format( " // {}\n {{ {}, {{ {}, {}, {}, {}, {}, {}, {}, {{{}}} }} }},\n",
data.name, action.first,
data.potency, data.comboPotency,
data.flankPotency, data.frontPotency, data.rearPotency,
data.curePotency, 0, comboStr );
output += out;
// Logger::info( out );
output[ std::to_string(action.first) ] = data;
}
std::ifstream ifs( "ActionLutData.cpp.tmpl" );
std::string actionTmpl( ( std::istreambuf_iterator< char >( ifs ) ),
std::istreambuf_iterator< char >() );
auto result = std::regex_replace( actionTmpl, std::regex( "%INSERT_GARBAGE%" ), output );
std::ofstream outH( "ActionLutData.cpp" );
outH << result;
std::ofstream outH( "actions/player.json" );
outH << std::setw(2) << output << std::endl;
outH.close();
return 0;

View file

@ -2,10 +2,25 @@
#include <cstdint>
#include <unordered_map>
#include <string>
#include <vector>
namespace Sapphire::World::Action
{
using StatusModifier = std::unordered_map< std::string, uint16_t >;
struct StatusEntry
{
uint16_t id;
StatusModifier modifiers;
};
struct StatusEffect
{
std::vector< StatusEntry > caster;
std::vector< StatusEntry > target;
};
struct ActionEntry
{
uint16_t potency;
@ -16,6 +31,7 @@ namespace Sapphire::World::Action
uint16_t curePotency;
uint16_t restoreMPPercentage;
std::vector< uint32_t > nextCombo;
StatusEffect statuses;
};
class ActionLut

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,32 @@
#include "ActionLut.h"
#include <nlohmann/json.hpp>
namespace Sapphire::World::Action
{
class ActionLutData
{
public:
static bool cacheActions();
static bool reloadActions();
};
inline void from_json( const nlohmann::json& j, StatusEntry& statusEntry )
{
j.at( "id" ).get_to( statusEntry.id );
j.at( "modifiers" ).get_to( statusEntry.modifiers );
}
inline void from_json( const nlohmann::json& j, ActionEntry& action )
{
j.at( "potency" ).get_to( action.potency );
j.at( "comboPotency" ).get_to( action.comboPotency );
j.at( "flankPotency" ).get_to( action.flankPotency );
j.at( "frontPotency" ).get_to( action.frontPotency );
j.at( "rearPotency" ).get_to( action.rearPotency );
j.at( "curePotency" ).get_to( action.curePotency );
j.at( "restorePercentage" ).get_to( action.restoreMPPercentage );
j.at( "nextCombo" ).get_to( action.nextCombo );
j.at( "statuses" ).at( "caster" ).get_to( action.statuses.caster );
j.at( "statuses" ).at( "target" ).get_to( action.statuses.target );
}
}

View file

@ -1,6 +1,7 @@
#include "ActionMgr.h"
#include "PlayerMgr.h"
#include "Action/ActionLutData.h"
#include "Action/Action.h"
#include "Action/ItemAction.h"
#include "Action/EventItemAction.h"
@ -16,6 +17,11 @@
using namespace Sapphire;
using namespace Sapphire::World::Manager;
bool ActionMgr::cacheActionLut()
{
return Action::ActionLutData::cacheActions();
}
void ActionMgr::handlePlacedPlayerAction( Entity::Player& player, uint32_t actionId,
Excel::ExcelStructPtr< Excel::Action > actionData, Common::FFXIVARR_POSITION3 pos,
uint16_t sequence )

View file

@ -20,6 +20,8 @@ namespace Sapphire::World::Manager
ActionMgr() = default;
~ActionMgr() = default;
bool cacheActionLut();
void handleTargetedPlayerAction( Entity::Player& player, uint32_t actionId,
std::shared_ptr< Excel::ExcelStruct< Excel::Action > > actionData, uint64_t targetId, uint16_t sequence );
void handlePlacedPlayerAction( Entity::Player& player, uint32_t actionId,

View file

@ -28,6 +28,8 @@
#include "Actor/EventObject.h"
#include "Actor/BNpc.h"
#include "Action/ActionLutData.h"
#include "Territory/Territory.h"
#include "Territory/HousingZone.h"
#include "Territory/InstanceContent.h"
@ -76,6 +78,7 @@ DebugCommandMgr::DebugCommandMgr()
registerCommand( "linkshell", &DebugCommandMgr::linkshell, "Linkshell creation", 1 );
registerCommand( "cf", &DebugCommandMgr::contentFinder, "Content-Finder", 1 );
registerCommand( "ew", &DebugCommandMgr::easyWarp, "Easy warping", 1 );
registerCommand( "reload", &DebugCommandMgr::hotReload, "Reloads a resource", 1 );
}
// clear all loaded commands
@ -1471,3 +1474,42 @@ void DebugCommandMgr::easyWarp( char* data, Sapphire::Entity::Player& player, st
else
PlayerMgr::sendUrgent( player, "{0} is not a valid easyWarp location.", subCommand );
}
void DebugCommandMgr::hotReload( char* data, Sapphire::Entity::Player& player, std::shared_ptr< DebugCommand > command )
{
std::string subCommand;
std::string params = "";
// check if the command has parameters
std::string tmpCommand = std::string( data + command->getName().length() + 1 );
std::size_t pos = tmpCommand.find_first_of( ' ' );
if( pos != std::string::npos )
// command has parameters, grab the first part
subCommand = tmpCommand.substr( 0, pos );
else
// no subcommand given
subCommand = tmpCommand;
if( command->getName().length() + 1 + pos + 1 < strlen( data ) )
params = std::string( data + command->getName().length() + 1 + pos + 1 );
Logger::debug( "[{0}] subCommand: {1} params: {2}", player.getId(), subCommand, params );
if( subCommand == "actions" )
{
if( Action::ActionLutData::reloadActions() )
{
PlayerMgr::sendDebug( player, "Successfully reloaded actions." );
}
else
{
PlayerMgr::sendDebug( player, "There was an error reloading actions." );
}
}
else
{
PlayerMgr::sendDebug( player, "Unknown sub command." );
}
}

View file

@ -63,6 +63,8 @@ namespace Sapphire::World::Manager
void easyWarp( char* data, Entity::Player& player, std::shared_ptr< DebugCommand > command );
void hotReload( char* data, Sapphire::Entity::Player& player, std::shared_ptr< DebugCommand > command );
};
}

View file

@ -201,6 +201,13 @@ void WorldServer::run( int32_t argc, char* argv[] )
Common::Service< Sapphire::InstanceObjectCache >::set( pInstanceObjCache );
auto pActionMgr = std::make_shared< Manager::ActionMgr >();
Logger::info( "ActionMgr: Caching action LUT" );
if( !pActionMgr->cacheActionLut() )
{
Logger::fatal( "Unable to cache actions!" );
return;
}
Common::Service< Manager::ActionMgr >::set( pActionMgr );
auto pNaviMgr = std::make_shared< Manager::NaviMgr >();