diff --git a/src/scripts/instances/questbattles/ChasingShadows.cpp b/src/scripts/instances/questbattles/ChasingShadows.cpp index 6398411f..5033b596 100644 --- a/src/scripts/instances/questbattles/ChasingShadows.cpp +++ b/src/scripts/instances/questbattles/ChasingShadows.cpp @@ -1,6 +1,8 @@ #include #include #include +#include +#include using namespace Sapphire; @@ -37,8 +39,17 @@ public: void onInit( QuestBattle& instance ) override { - instance.registerEObj( "unknown_0", 2005192, 5760474, 4, { -51.493111f, 0.309087f, 71.436897f }, 1.000000f, -0.000006f ); - + instance.registerEObj( "unknown_0", 2005192, 5760474, 4, { -51.493111f, 0.309087f, 71.436897f }, 1.000000f, -0.000006f ); + auto a1 = instance.createBNpcFromLevelEntry( INIT_POP_BOSS, 12, 0, 21141, 939, instance.getDirectorId(), 4 ); + auto a2 = instance.createBNpcFromLevelEntry( INIT_POP_ENEMY_B_01, 10, 0, 1440, 938, instance.getDirectorId(), 4 ); + auto a3 = instance.createBNpcFromLevelEntry( INIT_POP_ENEMY_B_02, 10, 0, 1440, 938, instance.getDirectorId(), 4 ); + instance.pushActor( a1 ); + instance.pushActor( a2 ); + instance.pushActor( a3 ); + auto a4 = instance.createBNpcFromLevelEntry( INIT_P_POP_IDA, 50, 0, 27780, 1375, instance.getDirectorId(), 0 ); + auto a5 = instance.createBNpcFromLevelEntry( INIT_P_POP_PAPARIMO, 50, 0, 27780, 1376, instance.getDirectorId(), 0 ); + instance.pushActor( a4 ); + instance.pushActor( a5 ); } void onUpdate( QuestBattle& instance, uint64_t tickCount ) override diff --git a/src/tools/quest_parser/main.cpp b/src/tools/quest_parser/main.cpp index 5b891221..0fa1a6f2 100644 --- a/src/tools/quest_parser/main.cpp +++ b/src/tools/quest_parser/main.cpp @@ -292,9 +292,9 @@ int main( int argc, char** argv ) bool unluac = false; // std::string datLocation( "/opt/sapphire_3_15_0/bin/sqpack" ); //std::string datLocation( "C:/Program Files (x86)/SquareEnix/FINAL FANTASY XIV - A Realm Reborn/game/sqpack" ); - //std::string datLocation( "C:/SquareEnix/FINAL FANTASY XIV - A Realm Reborn/game/sqpack" ); + std::string datLocation( "C:/SquareEnix/FINAL FANTASY XIV - A Realm Reborn/game/sqpack" ); - std::string datLocation( "/home/mordred/sqpack" ); + // std::string datLocation( "/home/mordred/sqpack" ); if( argc > 1 ) datLocation = std::string( argv[ 1 ] ); if( argc > 2 ) diff --git a/src/tools/questbattle_bruteforce/main.cpp b/src/tools/questbattle_bruteforce/main.cpp index 66b38d5e..37ecd51d 100644 --- a/src/tools/questbattle_bruteforce/main.cpp +++ b/src/tools/questbattle_bruteforce/main.cpp @@ -30,7 +30,8 @@ using namespace Sapphire; namespace fs = std::experimental::filesystem; //const std::string datLocation( "/opt/sapphire_3_15_0/bin/sqpack" ); -const std::string datLocation( "/mnt/c/Program Files (x86)/Steam/steamapps/common/FINAL FANTASY XIV Online/game/sqpack" ); +//const std::string datLocation( "/mnt/c/Program Files (x86)/Steam/steamapps/common/FINAL FANTASY XIV Online/game/sqpack" ); +std::string datLocation( "C:/SquareEnix/FINAL FANTASY XIV - A Realm Reborn/game/sqpack" ); void exportFile( const std::string& path ) { diff --git a/src/world/Actor/BNpcTemplate.cpp b/src/world/Actor/BNpcTemplate.cpp index 5646c9c4..f7559ff8 100644 --- a/src/world/Actor/BNpcTemplate.cpp +++ b/src/world/Actor/BNpcTemplate.cpp @@ -3,9 +3,9 @@ #include Sapphire::Entity::BNpcTemplate::BNpcTemplate( uint32_t id, uint32_t baseId, uint32_t nameId, uint64_t weaponMain, uint64_t weaponSub, - uint8_t aggressionMode, uint8_t enemyType, uint8_t onlineStatus, uint8_t pose, - uint16_t modelChara, uint32_t displayFlags, uint32_t* modelEquip, - uint8_t* customize ) : + uint8_t aggressionMode, uint8_t enemyType, uint8_t onlineStatus, uint8_t pose, + uint16_t modelChara, uint32_t displayFlags, uint32_t* modelEquip, + uint8_t* customize ) : m_id( id ), m_bNpcBaseId( baseId ), m_bNpcNameId( nameId ), diff --git a/src/world/Actor/Chara.cpp b/src/world/Actor/Chara.cpp index 06f447dc..5d2ec509 100644 --- a/src/world/Actor/Chara.cpp +++ b/src/world/Actor/Chara.cpp @@ -37,7 +37,8 @@ Sapphire::Entity::Chara::Chara( ObjKind type, FrameworkPtr pFw ) : Actor( type ), m_pose( 0 ), m_targetId( INVALID_GAME_OBJECT_ID64 ), - m_pFw( std::move( std::move( pFw ) ) ) + m_pFw( std::move( std::move( pFw ) ) ), + m_directorId( 0 ) { m_lastTickTime = 0; @@ -686,3 +687,13 @@ uint32_t Sapphire::Entity::Chara::getLastComboActionId() const return m_lastComboActionId; } + +uint32_t Sapphire::Entity::Chara::getDirectorId() const +{ + return m_directorId; +} + +void Sapphire::Entity::Chara::setDirectorId( uint32_t directorId ) +{ + m_directorId = directorId; +} diff --git a/src/world/Actor/Chara.h b/src/world/Actor/Chara.h index d8945fb2..b6826325 100644 --- a/src/world/Actor/Chara.h +++ b/src/world/Actor/Chara.h @@ -103,6 +103,8 @@ namespace Sapphire::Entity uint64_t m_targetId; /*! Ptr to a queued action */ Action::ActionPtr m_pCurrentAction; + /*! id of the director this chara is assigned to */ + uint32_t m_directorId; /*! * @brief the id of the last combo action used (IgnoresCombo) @@ -262,6 +264,9 @@ namespace Sapphire::Entity uint32_t getBonusStat( Common::BaseParam bonus ) const; + uint32_t getDirectorId() const; + void setDirectorId( uint32_t directorId ); + }; } diff --git a/src/world/Network/PacketWrappers/NpcSpawnPacket.h b/src/world/Network/PacketWrappers/NpcSpawnPacket.h index 65568849..b9d585fd 100644 --- a/src/world/Network/PacketWrappers/NpcSpawnPacket.h +++ b/src/world/Network/PacketWrappers/NpcSpawnPacket.h @@ -58,6 +58,7 @@ namespace Sapphire::Network::Packets::Server m_data.classJob = 0; + m_data.directorId = bnpc.getDirectorId(); m_data.targetId = bnpc.getTargetId(); m_data.spawnerId = Common::INVALID_GAME_OBJECT_ID64; m_data.parentActorId = Common::INVALID_GAME_OBJECT_ID64; diff --git a/src/world/Territory/QuestBattle.cpp b/src/world/Territory/QuestBattle.cpp index b0cb598e..17693c6d 100644 --- a/src/world/Territory/QuestBattle.cpp +++ b/src/world/Territory/QuestBattle.cpp @@ -12,6 +12,8 @@ #include "Actor/Player.h" #include "Actor/EventObject.h" +#include "Actor/BNpc.h" +#include "Actor/BNpcTemplate.h" #include "Network/PacketWrappers/ActorControlPacket142.h" #include "Network/PacketWrappers/ActorControlPacket143.h" @@ -371,3 +373,96 @@ uint32_t Sapphire::QuestBattle::getQuestId() const { return m_pBattleDetails->quest; } + +Sapphire::Entity::BNpcPtr + Sapphire::QuestBattle::createBNpcFromLevelEntry( uint32_t levelId, uint8_t level, uint8_t type, + uint32_t hp, uint16_t nameId, uint32_t directorId, + uint8_t bnpcType ) +{ + auto pExdData = m_pFw->get< Data::ExdDataGenerated >(); + auto levelData = pExdData->get< Sapphire::Data::Level >( levelId ); + if( !levelData ) + return nullptr; + + if( levelData->type != 9 ) + return nullptr; + + auto bnpcBaseId = levelData->object; + + auto bnpcBaseData = pExdData->get< Sapphire::Data::BNpcBase >( bnpcBaseId ); + if( !bnpcBaseData ) + return nullptr; + + //BNpcTemplate( uint32_t id, uint32_t baseId, uint32_t nameId, uint64_t weaponMain, uint64_t weaponSub, + // uint8_t aggressionMode, uint8_t enemyType, uint8_t onlineStatus, uint8_t pose, + // uint16_t modelChara, uint32_t displayFlags, uint32_t* modelEquip, + // uint8_t* customize ) + + std::vector< uint8_t > customize( 26 ); + if( bnpcBaseData->bNpcCustomize != 0 ) + { + auto bnpcCustomizeData = pExdData->get< Sapphire::Data::BNpcCustomize >( bnpcBaseData->bNpcCustomize ); + if( bnpcCustomizeData ) + { + customize[0] = bnpcCustomizeData->race; + customize[1] = bnpcCustomizeData->gender; + customize[2] = bnpcCustomizeData->bodyType; + customize[3] = bnpcCustomizeData->height; + customize[4] = bnpcCustomizeData->tribe; + customize[5] = bnpcCustomizeData->face; + customize[6] = bnpcCustomizeData->hairStyle; + customize[7] = bnpcCustomizeData->hairHighlight; + customize[8] = bnpcCustomizeData->skinColor; + customize[9] = bnpcCustomizeData->eyeHeterochromia; + customize[10] = bnpcCustomizeData->hairColor; + customize[11] = bnpcCustomizeData->hairHighlightColor; + customize[12] = bnpcCustomizeData->facialFeature; + customize[13] = bnpcCustomizeData->facialFeatureColor; + customize[14] = bnpcCustomizeData->eyebrows; + customize[15] = bnpcCustomizeData->eyeColor; + customize[16] = bnpcCustomizeData->eyeShape; + customize[17] = bnpcCustomizeData->nose; + customize[18] = bnpcCustomizeData->jaw; + customize[19] = bnpcCustomizeData->mouth; + customize[20] = bnpcCustomizeData->lipColor; + customize[21] = bnpcCustomizeData->bustOrTone1; + customize[22] = bnpcCustomizeData->extraFeature1; + customize[23] = bnpcCustomizeData->extraFeature2OrBust; + customize[24] = bnpcCustomizeData->facePaint; + customize[25] = bnpcCustomizeData->facePaintColor; + } + } + + std::vector< uint32_t > models( 10 ); + uint64_t modelMain = 0; + uint64_t modeloff = 0; + if( bnpcBaseData->npcEquip != 0 ) + { + auto npcEquipData = pExdData->get< Sapphire::Data::NpcEquip >( bnpcBaseData->npcEquip ); + if( npcEquipData ) + { + modelMain = npcEquipData->modelMainHand; + modeloff = npcEquipData->modelOffHand; + + models[0] = npcEquipData->modelHead; + models[1] = npcEquipData->modelBody; + models[2] = npcEquipData->modelHands; + models[3] = npcEquipData->modelLegs; + models[4] = npcEquipData->modelFeet; + models[5] = npcEquipData->modelEars; + models[6] = npcEquipData->modelNeck; + models[7] = npcEquipData->modelWrists; + models[8] = npcEquipData->modelLeftRing; + models[9] = npcEquipData->modelRightRing; + } + } + + auto tmp = std::make_shared< Entity::BNpcTemplate >( 0, bnpcBaseId, nameId, modelMain, modeloff, 1, bnpcType, 0, 4, + bnpcBaseData->modelChara, 0, &models[0], &customize[0] ); + + auto bnpc = std::make_shared< Entity::BNpc >( getNextActorId(), tmp, levelData->x, levelData->y, levelData->z, + levelData->yaw, level, hp, shared_from_this(), m_pFw ); + + bnpc->setDirectorId( directorId ); + return bnpc; +} diff --git a/src/world/Territory/QuestBattle.h b/src/world/Territory/QuestBattle.h index e1bffc42..1f5395c8 100644 --- a/src/world/Territory/QuestBattle.h +++ b/src/world/Territory/QuestBattle.h @@ -79,6 +79,10 @@ namespace Sapphire /*! number of milliseconds after all players are ready for the instance to commence (spawn circle removed) */ const uint32_t instanceStartDelay = 1250; + Entity::BNpcPtr createBNpcFromLevelEntry( uint32_t levelId, uint8_t level, uint8_t type, + uint32_t hp, uint16_t nameId, uint32_t directorId, + uint8_t bnpcType ); + private: std::shared_ptr< Sapphire::Data::QuestBattle > m_pBattleDetails; uint32_t m_questBattleId;