mirror of
https://github.com/SapphireServer/Sapphire.git
synced 2025-04-27 22:57:45 +00:00
Merge branch 'develop' into action
This commit is contained in:
commit
4deac81abd
28 changed files with 826 additions and 4993 deletions
198
deps/datReader/DatCategories/bg/LgbTypes.h
vendored
Normal file
198
deps/datReader/DatCategories/bg/LgbTypes.h
vendored
Normal file
|
@ -0,0 +1,198 @@
|
|||
#ifndef SAPPHIRE_LGBTYPES_H
|
||||
#define SAPPHIRE_LGBTYPES_H
|
||||
|
||||
#include "vec3.h"
|
||||
|
||||
enum class LgbEntryType : uint32_t
|
||||
{
|
||||
BgParts = 1,
|
||||
Attribute = 2,
|
||||
Light = 3,
|
||||
Vfx = 4,
|
||||
PositionMarker = 5,
|
||||
Gimmick = 6,
|
||||
SharedGroup6 = 6,// secondary variable is set to 2
|
||||
Sound = 7,
|
||||
EventNpc = 8,
|
||||
BattleNpc = 9,
|
||||
RoutePath = 10,
|
||||
Character = 11,
|
||||
Aetheryte = 12,
|
||||
EnvSpace = 13,
|
||||
Gathering = 14,
|
||||
SharedGroup15 = 15,// secondary variable is set to 13
|
||||
Treasure = 16,
|
||||
Player = 37,
|
||||
Monster = 38,
|
||||
Weapon = 39,
|
||||
PopRange = 40,
|
||||
ExitRange = 41,
|
||||
LVB = 42,
|
||||
MapRange = 43,
|
||||
NaviMeshRange = 44,
|
||||
EventObject = 45,
|
||||
DemiHuman = 46,
|
||||
EnvLocation = 47,
|
||||
ControlPoint = 48,
|
||||
EventRange = 49,
|
||||
RestBonusRange = 50,
|
||||
QuestMarker = 51,
|
||||
TimeLine = 52,
|
||||
ObjectBehaviorSet = 53,
|
||||
Movie = 54,
|
||||
ScenarioEXD = 55,
|
||||
ScenarioText = 56,
|
||||
CollisionBox = 57,
|
||||
DoorRange = 58,
|
||||
LineVfx = 59,
|
||||
SoundEnvSet = 60,
|
||||
CutActionTimeline = 61,
|
||||
CharaScene = 62,
|
||||
CutAction = 63,
|
||||
EquipPreset = 64,
|
||||
ClientPath = 65,
|
||||
ServerPath = 66,
|
||||
GimmickRange = 67,
|
||||
TargetMarker = 68,
|
||||
ChairMarker = 69,
|
||||
ClickableRange = 70,
|
||||
PrefetchRange = 71,
|
||||
FateRange = 72,
|
||||
PartyMember = 73,
|
||||
KeepRange = 74,
|
||||
SphereCastRange = 75,
|
||||
IndoorObject = 76,
|
||||
OutdoorObject = 77,
|
||||
EditGroup = 78,
|
||||
StableChocobo = 79
|
||||
};
|
||||
|
||||
enum PopType : uint32_t
|
||||
{
|
||||
PopTypePC = 0x1,
|
||||
PopTypeNPC = 0x2,
|
||||
PopTypeBNPC = 0x2,
|
||||
PopTypeContent = 0x3,
|
||||
};
|
||||
|
||||
struct Transformation
|
||||
{
|
||||
vec3 translation;
|
||||
vec3 rotation;
|
||||
vec3 scale;
|
||||
};
|
||||
|
||||
struct InstanceObject
|
||||
{
|
||||
LgbEntryType type;
|
||||
uint32_t instanceId;
|
||||
uint32_t nameOffset;
|
||||
Transformation transform;
|
||||
};
|
||||
|
||||
struct BgPartsData : public InstanceObject
|
||||
{
|
||||
uint32_t modelFileOffset;
|
||||
uint32_t collisionFileOffset;
|
||||
uint32_t unknown4;
|
||||
uint32_t unknown5;
|
||||
uint32_t unknown6;
|
||||
uint32_t unknown7;
|
||||
uint32_t unknown8;
|
||||
uint32_t unknown9;
|
||||
};
|
||||
|
||||
struct RelativePositions
|
||||
{
|
||||
int32_t Pos;
|
||||
int32_t PosCount;
|
||||
};
|
||||
|
||||
struct PopRangeData : public InstanceObject
|
||||
{
|
||||
PopType popType;
|
||||
RelativePositions relativePositions;
|
||||
float innerRadiusRatio;
|
||||
uint8_t index;
|
||||
uint8_t padding00[3];
|
||||
uint32_t reserved;
|
||||
};
|
||||
|
||||
struct GimmickData : public InstanceObject
|
||||
{
|
||||
uint32_t gimmickFileOffset;
|
||||
char unknownBytes[100];
|
||||
};
|
||||
|
||||
struct ENpcData : public InstanceObject
|
||||
{
|
||||
uint32_t enpcId;
|
||||
uint8_t unknown1[0x24];
|
||||
};
|
||||
|
||||
struct EObjData : public InstanceObject
|
||||
{
|
||||
uint32_t eobjId;
|
||||
uint32_t levelHierachyId;
|
||||
uint8_t unknown1[0xC];
|
||||
};
|
||||
|
||||
enum TriggerBoxShape : uint32_t
|
||||
{
|
||||
TriggerBoxShapeBox = 0x1,
|
||||
TriggerBoxShapeSphere = 0x2,
|
||||
TriggerBoxShapeCylinder = 0x3,
|
||||
TriggerBoxShapeBoard = 0x4,
|
||||
TriggerBoxShapeMesh = 0x5,
|
||||
TriggerBoxShapeBoardBothSides = 0x6,
|
||||
};
|
||||
|
||||
struct TriggerBoxInstanceObject
|
||||
{
|
||||
TriggerBoxShape triggerBoxShape;
|
||||
int16_t priority;
|
||||
int8_t enabled;
|
||||
uint8_t padding;
|
||||
uint32_t reserved;
|
||||
};
|
||||
|
||||
struct ExitRangeData : public InstanceObject
|
||||
{
|
||||
TriggerBoxInstanceObject triggerBoxType;
|
||||
uint32_t exitType;
|
||||
uint16_t zoneId;
|
||||
uint16_t destTerritoryType;
|
||||
int index;
|
||||
uint32_t destInstanceObjectId;
|
||||
uint32_t returnInstanceObjectId;
|
||||
float direction;
|
||||
uint32_t reserved;
|
||||
};
|
||||
|
||||
struct MapRangeData : public InstanceObject
|
||||
{
|
||||
TriggerBoxInstanceObject triggerBoxType;
|
||||
uint32_t mapId;
|
||||
uint32_t placeNameBlock;
|
||||
uint32_t placeNameSpot;
|
||||
uint32_t bGM;
|
||||
uint32_t weather;
|
||||
uint32_t reserved;
|
||||
uint32_t reserved2;
|
||||
uint16_t reserved3;
|
||||
uint8_t housingBlockId;
|
||||
int8_t restBonusEffective;
|
||||
uint8_t discoveryIndex;
|
||||
int8_t mapEnabled;
|
||||
int8_t placeNameEnabled;
|
||||
int8_t discoveryEnabled;
|
||||
int8_t bGMEnabled;
|
||||
int8_t weatherEnabled;
|
||||
int8_t restBonusEnabled;
|
||||
int8_t bGMPlayZoneInOnly;
|
||||
int8_t liftEnabled;
|
||||
int8_t housingEnabled;
|
||||
uint16_t padding;
|
||||
};
|
||||
|
||||
#endif //SAPPHIRE_LGBTYPES_H
|
248
deps/datReader/DatCategories/bg/lgb.h
vendored
248
deps/datReader/DatCategories/bg/lgb.h
vendored
|
@ -12,87 +12,33 @@
|
|||
#include "matrix4.h"
|
||||
#include "vec3.h"
|
||||
#include "sgb.h"
|
||||
#include "LgbTypes.h"
|
||||
|
||||
// garbage to skip model loading
|
||||
extern bool ignoreModels;
|
||||
|
||||
// all credit to
|
||||
// https://github.com/ufx/SaintCoinach/blob/master/SaintCoinach/Graphics/Lgb/
|
||||
// this is simply their work ported to c++ since we dont c#
|
||||
// based on https://github.com/ufx/SaintCoinach/blob/master/SaintCoinach/Graphics/Lgb/
|
||||
struct LGB_FILE;
|
||||
struct LGB_FILE_HEADER;
|
||||
struct LGB_GROUP;
|
||||
struct LGB_GROUP_HEADER;
|
||||
|
||||
enum class LgbEntryType :
|
||||
uint32_t
|
||||
{
|
||||
BgParts = 1,
|
||||
Light = 3,
|
||||
Vfx = 4,
|
||||
PositionMarker = 5,
|
||||
Gimmick = 6,
|
||||
SharedGroup6 = 6,// secondary variable is set to 2
|
||||
Sound = 7,
|
||||
EventNpc = 8,
|
||||
BattleNpc = 9,
|
||||
Aetheryte = 12,
|
||||
EnvSpace = 13,
|
||||
Gathering = 14,
|
||||
SharedGroup15 = 15,// secondary variable is set to 13
|
||||
Treasure = 16,
|
||||
Weapon = 39,
|
||||
PopRange = 40,
|
||||
ExitRange = 41,
|
||||
MapRange = 43,
|
||||
NaviMeshRange = 44,
|
||||
EventObject = 45,
|
||||
EnvLocation = 47,
|
||||
EventRange = 49,
|
||||
QuestMarker = 51,
|
||||
CollisionBox = 57,
|
||||
DoorRange = 58,
|
||||
LineVfx = 59,
|
||||
ClientPath = 65,
|
||||
ServerPath = 66,
|
||||
GimmickRange = 67,
|
||||
TargetMarker = 68,
|
||||
ChairMarker = 69,
|
||||
ClickableRange = 70,
|
||||
PrefetchRange = 71,
|
||||
FateRange = 72,
|
||||
SphereCastRange = 75,
|
||||
};
|
||||
|
||||
struct LGB_ENTRY_HEADER
|
||||
{
|
||||
LgbEntryType type;
|
||||
uint32_t unknown;
|
||||
uint32_t nameOffset;
|
||||
vec3 translation;
|
||||
vec3 rotation;
|
||||
vec3 scale;
|
||||
};
|
||||
|
||||
class LGB_ENTRY
|
||||
class LgbEntry
|
||||
{
|
||||
public:
|
||||
char* m_buf;
|
||||
uint32_t m_offset;
|
||||
LGB_ENTRY_HEADER header;
|
||||
InstanceObject header;
|
||||
|
||||
LGB_ENTRY()
|
||||
LgbEntry()
|
||||
{
|
||||
m_buf = nullptr;
|
||||
m_offset = 0;
|
||||
memset( &header, 0, sizeof( header ) );
|
||||
};
|
||||
|
||||
LGB_ENTRY( char* buf, uint32_t offset )
|
||||
LgbEntry( char* buf, uint32_t offset )
|
||||
{
|
||||
m_buf = buf;
|
||||
m_offset = offset;
|
||||
header = *reinterpret_cast< LGB_ENTRY_HEADER* >( buf + offset );
|
||||
header = *reinterpret_cast< InstanceObject* >( buf + offset );
|
||||
};
|
||||
|
||||
const LgbEntryType getType() const
|
||||
|
@ -100,30 +46,16 @@ public:
|
|||
return header.type;
|
||||
};
|
||||
|
||||
virtual ~LGB_ENTRY()
|
||||
virtual ~LgbEntry()
|
||||
{
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
struct LGB_BGPARTS_HEADER :
|
||||
public LGB_ENTRY_HEADER
|
||||
{
|
||||
uint32_t modelFileOffset;
|
||||
uint32_t collisionFileOffset;
|
||||
uint32_t unknown4;
|
||||
uint32_t unknown5;
|
||||
uint32_t unknown6;
|
||||
uint32_t unknown7;
|
||||
uint32_t unknown8;
|
||||
uint32_t unknown9;
|
||||
};
|
||||
|
||||
class LGB_BGPARTS_ENTRY :
|
||||
public LGB_ENTRY
|
||||
class LGB_BGPARTS_ENTRY : public LgbEntry
|
||||
{
|
||||
public:
|
||||
LGB_BGPARTS_HEADER header;
|
||||
BgPartsData data;
|
||||
std::string name;
|
||||
std::string modelFileName;
|
||||
std::string collisionFileName;
|
||||
|
@ -132,124 +64,94 @@ public:
|
|||
{
|
||||
};
|
||||
|
||||
LGB_BGPARTS_ENTRY( char* buf, uint32_t offset ) :
|
||||
LGB_ENTRY( buf, offset )
|
||||
LGB_BGPARTS_ENTRY( char* buf, uint32_t offset ) : LgbEntry( buf, offset )
|
||||
{
|
||||
header = *reinterpret_cast<LGB_BGPARTS_HEADER*>( buf + offset );
|
||||
data = *reinterpret_cast< BgPartsData* >( buf + offset );
|
||||
name = std::string( buf + offset + header.nameOffset );
|
||||
modelFileName = std::string( buf + offset + header.modelFileOffset );
|
||||
collisionFileName = std::string( buf + offset + header.collisionFileOffset );
|
||||
modelFileName = std::string( buf + offset + data.modelFileOffset );
|
||||
collisionFileName = std::string( buf + offset + data.collisionFileOffset );
|
||||
};
|
||||
};
|
||||
|
||||
struct LGB_GIMMICK_HEADER :
|
||||
public LGB_ENTRY_HEADER
|
||||
{
|
||||
uint32_t gimmickFileOffset;
|
||||
char unknownBytes[100];
|
||||
};
|
||||
|
||||
class LGB_GIMMICK_ENTRY :
|
||||
public LGB_ENTRY
|
||||
class LGB_GIMMICK_ENTRY : public LgbEntry
|
||||
{
|
||||
public:
|
||||
LGB_GIMMICK_HEADER header;
|
||||
GimmickData data;
|
||||
std::string name;
|
||||
std::string gimmickFileName;
|
||||
|
||||
LGB_GIMMICK_ENTRY( char* buf, uint32_t offset ) :
|
||||
LGB_ENTRY( buf, offset )
|
||||
LGB_GIMMICK_ENTRY( char* buf, uint32_t offset ) : LgbEntry( buf, offset )
|
||||
{
|
||||
header = *reinterpret_cast<LGB_GIMMICK_HEADER*>( buf + offset );
|
||||
data = *reinterpret_cast< GimmickData* >( buf + offset );
|
||||
name = std::string( buf + offset + header.nameOffset );
|
||||
gimmickFileName = std::string( buf + offset + header.gimmickFileOffset );
|
||||
//std::cout << "\t " << gimmickFileName << " unknown: " << header.unknown << "\n";
|
||||
gimmickFileName = std::string( buf + offset + data.gimmickFileOffset );
|
||||
};
|
||||
};
|
||||
|
||||
struct LGB_ENPC_HEADER :
|
||||
public LGB_ENTRY_HEADER
|
||||
{
|
||||
uint32_t enpcId;
|
||||
uint8_t unknown1[0x24];
|
||||
};
|
||||
|
||||
class LGB_ENPC_ENTRY :
|
||||
public LGB_ENTRY
|
||||
class LGB_ENPC_ENTRY : public LgbEntry
|
||||
{
|
||||
public:
|
||||
LGB_ENPC_HEADER header;
|
||||
ENpcData data;
|
||||
std::string name;
|
||||
|
||||
LGB_ENPC_ENTRY( char* buf, uint32_t offset ) :
|
||||
LGB_ENTRY( buf, offset )
|
||||
LgbEntry( buf, offset )
|
||||
{
|
||||
header = *reinterpret_cast< LGB_ENPC_HEADER* >( buf + offset );
|
||||
name = std::string( buf + offset + header.nameOffset );
|
||||
//std::cout << "\t ENpc " << header.enpcId << " " << name << "\n";
|
||||
};
|
||||
};
|
||||
|
||||
struct LGB_EOBJ_HEADER :
|
||||
public LGB_ENTRY_HEADER
|
||||
{
|
||||
uint32_t eobjId;
|
||||
uint32_t levelHierachyId;
|
||||
uint8_t unknown1[0xC];
|
||||
};
|
||||
|
||||
class LGB_EOBJ_ENTRY :
|
||||
public LGB_ENTRY
|
||||
{
|
||||
public:
|
||||
LGB_EOBJ_HEADER header;
|
||||
std::string name;
|
||||
|
||||
LGB_EOBJ_ENTRY( char* buf, uint32_t offset ) :
|
||||
LGB_ENTRY( buf, offset )
|
||||
{
|
||||
header = *reinterpret_cast< LGB_EOBJ_HEADER* >( buf + offset );
|
||||
//std::cout << "\t " << header.eobjId << " " << name << " unknown: " << header.unknown << "\n";
|
||||
data = *reinterpret_cast< ENpcData* >( buf + offset );
|
||||
name = std::string( buf + offset + header.nameOffset );
|
||||
};
|
||||
};
|
||||
|
||||
struct LGB_MAPRANGE_HEADER :
|
||||
public LGB_ENTRY_HEADER
|
||||
{
|
||||
uint32_t type;
|
||||
uint8_t unknown2;
|
||||
uint8_t unknown2_1;
|
||||
uint16_t unknown3;
|
||||
uint32_t unknown5;
|
||||
uint32_t mapId;
|
||||
uint32_t offsetX;
|
||||
uint32_t offsetY;
|
||||
uint32_t unkInts[4];
|
||||
uint16_t unkShort;
|
||||
uint8_t unkFlag;
|
||||
uint8_t unkFlag2;
|
||||
uint8_t discoveryIndex;
|
||||
uint8_t unkFlag3;
|
||||
uint8_t unkFlag4;
|
||||
uint8_t unknown4[0x09];
|
||||
};
|
||||
|
||||
struct LGB_MAPRANGE_ENTRY :
|
||||
public LGB_ENTRY
|
||||
class LGB_EOBJ_ENTRY : public LgbEntry
|
||||
{
|
||||
public:
|
||||
LGB_MAPRANGE_HEADER header;
|
||||
EObjData data;
|
||||
std::string name;
|
||||
|
||||
LGB_MAPRANGE_ENTRY( char* buf, uint32_t offset ) :
|
||||
LGB_ENTRY( buf, offset )
|
||||
LGB_EOBJ_ENTRY( char* buf, uint32_t offset ) : LgbEntry( buf, offset )
|
||||
{
|
||||
header = *reinterpret_cast< LGB_MAPRANGE_HEADER* >( buf + offset );
|
||||
data = *reinterpret_cast< EObjData* >( buf + offset );
|
||||
name = std::string( buf + offset + header.nameOffset );
|
||||
};
|
||||
};
|
||||
|
||||
struct LGB_MAP_RANGE_ENTRY : public LgbEntry
|
||||
{
|
||||
public:
|
||||
MapRangeData data;
|
||||
std::string name;
|
||||
|
||||
LGB_MAP_RANGE_ENTRY( char* buf, uint32_t offset ) : LgbEntry( buf, offset )
|
||||
{
|
||||
data = *reinterpret_cast< MapRangeData* >( buf + offset );
|
||||
name = std::string( buf + offset + header.nameOffset );
|
||||
};
|
||||
};
|
||||
|
||||
struct LGB_EXIT_RANGE_ENTRY : public LgbEntry
|
||||
{
|
||||
public:
|
||||
ExitRangeData data;
|
||||
std::string name;
|
||||
|
||||
LGB_EXIT_RANGE_ENTRY( char* buf, uint32_t offset ) : LgbEntry( buf, offset )
|
||||
{
|
||||
data = *reinterpret_cast< ExitRangeData* >( buf + offset );
|
||||
name = std::string( buf + offset + header.nameOffset );
|
||||
};
|
||||
};
|
||||
|
||||
struct LGB_POP_RANGE_ENTRY : public LgbEntry
|
||||
{
|
||||
public:
|
||||
PopRangeData data;
|
||||
|
||||
LGB_POP_RANGE_ENTRY( char* buf, uint32_t offset ) : LgbEntry( buf, offset )
|
||||
{
|
||||
data = *reinterpret_cast< PopRangeData* >( buf + offset );
|
||||
};
|
||||
};
|
||||
|
||||
struct LGB_GROUP_HEADER
|
||||
{
|
||||
uint32_t id;
|
||||
|
@ -272,15 +174,13 @@ struct LGB_GROUP
|
|||
LGB_FILE* parent;
|
||||
LGB_GROUP_HEADER header;
|
||||
std::string name;
|
||||
std::vector< std::shared_ptr< LGB_ENTRY > > entries;
|
||||
std::vector< std::shared_ptr< LgbEntry > > entries;
|
||||
|
||||
LGB_GROUP( char* buf, LGB_FILE* parentStruct, uint32_t offset )
|
||||
{
|
||||
parent = parentStruct;
|
||||
header = *reinterpret_cast< LGB_GROUP_HEADER* >( buf + offset );
|
||||
name = std::string( buf + offset + header.groupNameOffset );
|
||||
//entries.resize( header.entryCount );
|
||||
//std::cout << name << "\n\t unknown: " << header.unknown << "\n";
|
||||
const auto entriesOffset = offset + header.entriesOffset;
|
||||
for( auto i = 0; i < header.entryCount; ++i )
|
||||
{
|
||||
|
@ -288,8 +188,7 @@ struct LGB_GROUP
|
|||
|
||||
try
|
||||
{
|
||||
const auto type = *reinterpret_cast<LgbEntryType*>( buf + entryOffset );
|
||||
// garbage to skip model loading
|
||||
const auto type = *reinterpret_cast< LgbEntryType* >( buf + entryOffset );
|
||||
if( type == LgbEntryType::BgParts )
|
||||
{
|
||||
entries.push_back( std::make_shared< LGB_BGPARTS_ENTRY >( buf, entryOffset ) );
|
||||
|
@ -306,16 +205,18 @@ struct LGB_GROUP
|
|||
{
|
||||
entries.push_back( std::make_shared< LGB_EOBJ_ENTRY >( buf, entryOffset ) );
|
||||
}
|
||||
else if( type == LgbEntryType::ExitRange )
|
||||
{
|
||||
entries.push_back( std::make_shared< LGB_EXIT_RANGE_ENTRY >( buf, entryOffset ) );
|
||||
}
|
||||
else if( type == LgbEntryType::MapRange )
|
||||
{
|
||||
entries.push_back( std::make_shared< LGB_MAPRANGE_ENTRY >( buf, entryOffset ) );
|
||||
entries.push_back( std::make_shared< LGB_MAP_RANGE_ENTRY >( buf, entryOffset ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
entries.push_back( std::make_shared< LGB_ENTRY >( buf, entryOffset ) );
|
||||
entries.push_back( std::make_shared< LgbEntry >( buf, entryOffset ) );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
catch( std::exception& e )
|
||||
{
|
||||
|
@ -344,8 +245,7 @@ struct LGB_FILE
|
|||
std::vector< LGB_GROUP > groups;
|
||||
std::string m_name;
|
||||
|
||||
LGB_FILE( char* buf, const std::string& name ) :
|
||||
LGB_FILE( buf )
|
||||
LGB_FILE( char* buf, const std::string& name ) : LGB_FILE( buf )
|
||||
{
|
||||
m_name = name;
|
||||
}
|
||||
|
@ -356,8 +256,6 @@ struct LGB_FILE
|
|||
if( strncmp( &header.magic[ 0 ], "LGB1", 4 ) != 0 || strncmp( &header.magic2[ 0 ], "LGP1", 4 ) != 0 )
|
||||
throw std::runtime_error( "Invalid LGB file!" );
|
||||
|
||||
//groups.resize(header.groupCount);
|
||||
|
||||
constexpr auto baseOffset = sizeof( header );
|
||||
for( auto i = 0; i < header.groupCount; ++i )
|
||||
{
|
||||
|
|
12
deps/datReader/DatCategories/bg/sgb.h
vendored
12
deps/datReader/DatCategories/bg/sgb.h
vendored
|
@ -22,15 +22,13 @@ struct SGB_GROUP;
|
|||
struct SGB_GROUP_HEADER;
|
||||
|
||||
|
||||
enum SgbDataType :
|
||||
uint32_t
|
||||
enum SgbDataType : uint32_t
|
||||
{
|
||||
Unknown0008 = 0x0008,
|
||||
Group = 0x0100,
|
||||
};
|
||||
|
||||
enum SgbGroupEntryType :
|
||||
uint32_t
|
||||
enum SgbGroupEntryType : uint32_t
|
||||
{
|
||||
Model = 0x01,
|
||||
Gimmick = 0x06,
|
||||
|
@ -124,15 +122,13 @@ struct SGB_ENTRY_HEADER
|
|||
vec3 scale;
|
||||
};
|
||||
|
||||
struct SGB_MODEL_HEADER :
|
||||
public SGB_ENTRY_HEADER
|
||||
struct SGB_MODEL_HEADER : public SGB_ENTRY_HEADER
|
||||
{
|
||||
int32_t modelFileOffset;
|
||||
int32_t collisionFileOffset;
|
||||
};
|
||||
|
||||
struct SGB_MODEL_ENTRY :
|
||||
public SGB_GROUP_ENTRY
|
||||
struct SGB_MODEL_ENTRY : public SGB_GROUP_ENTRY
|
||||
{
|
||||
SGB_MODEL_HEADER header;
|
||||
SgbGroupEntryType type;
|
||||
|
|
2
deps/datReader/Index.cpp
vendored
2
deps/datReader/Index.cpp
vendored
|
@ -84,7 +84,7 @@ Index::Index(const std::experimental::filesystem::path& path) :
|
|||
// The dat number is found in the offset, last four bits
|
||||
hashTableEntry.datNum = ( indexHashTableEntry.datOffset & 0xF ) / 0x2;
|
||||
// The offset in the dat file, needs to strip the dat number indicator
|
||||
hashTableEntry.datOffset = ( indexHashTableEntry.datOffset & 0xFFFFFFF0 ) * 0x08;
|
||||
hashTableEntry.datOffset = ( indexHashTableEntry.datOffset - ( indexHashTableEntry.datOffset & 0x000F ) ) * 0x08;
|
||||
hashTableEntry.dirHash = indexHashTableEntry.dirHash;
|
||||
hashTableEntry.filenameHash = indexHashTableEntry.filenameHash;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -400,13 +400,6 @@ CREATE TABLE `dbupdate` (
|
|||
PRIMARY KEY(`name`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE `discoveryinfo` (
|
||||
`id` int(10) NOT NULL,
|
||||
`map_id` int(3) NOT NULL,
|
||||
`discover_id` int(3) NOT NULL,
|
||||
PRIMARY KEY(`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE `house` (
|
||||
`HouseId` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`LandSetId` int(10) UNSIGNED DEFAULT NULL,
|
||||
|
|
|
@ -5957,6 +5957,11 @@ struct ZoneSharedGroup
|
|||
std::shared_ptr< xiv::dat::GameData > m_data;
|
||||
std::shared_ptr< xiv::exd::ExdData > m_exd_data;
|
||||
|
||||
std::shared_ptr< xiv::dat::GameData > getGameData()
|
||||
{
|
||||
return m_data;
|
||||
}
|
||||
|
||||
template< class T >
|
||||
std::shared_ptr< T > get( uint32_t id )
|
||||
{
|
||||
|
|
|
@ -295,7 +295,7 @@ namespace Sapphire::Network::Packets
|
|||
|
||||
|
||||
CFRegisterDuty = 0x0071,
|
||||
CFRegisterRoulette = 0x0072,
|
||||
CFRegisterRoulette = 0xFF72,
|
||||
PlayTimeHandler = 0x0276, // updated 5.1
|
||||
LogoutHandler = 0x015D, // updated 5.18
|
||||
CancelLogout = 0x008F, // updated 5.1
|
||||
|
@ -342,8 +342,8 @@ namespace Sapphire::Network::Packets
|
|||
PlaceFieldMarker = 0x013C, // updated 5.0
|
||||
SkillHandler = 0x01BE, // updated 5.18
|
||||
GMCommand1 = 0x014D, // updated 5.18
|
||||
GMCommand2 = 0x032C, // updated 5.18
|
||||
AoESkillHandler = 0x140, // updated 5.0
|
||||
GMCommand2 = 0x03C2, // updated 5.18
|
||||
AoESkillHandler = 0x0072, // updated 5.18
|
||||
|
||||
UpdatePositionHandler = 0x0318, // updated 5.18
|
||||
|
||||
|
@ -352,7 +352,7 @@ namespace Sapphire::Network::Packets
|
|||
InventoryEquipRecommendedItems = 0x0149, // updated 5.0
|
||||
|
||||
ReqPlaceHousingItem = 0x014B, // updated 5.0
|
||||
BuildPresetHandler = 0x014F, // updated 5.0
|
||||
BuildPresetHandler = 0x0150, // updated 5.0
|
||||
|
||||
TalkEventHandler = 0x02FD, // updated 5.18
|
||||
EmoteEventHandler = 0x0183, // updated 5.18
|
||||
|
|
|
@ -1564,11 +1564,10 @@ namespace Sapphire::Network::Packets::Server
|
|||
*/
|
||||
struct FFXIVIpcDiscovery : FFXIVIpcBasePacket< Discovery >
|
||||
{
|
||||
/* 0000 */ uint32_t map_part_id;
|
||||
/* 0004 */ uint32_t map_id;
|
||||
/* 0000 */ uint32_t mapPartId;
|
||||
/* 0004 */ uint32_t mapId;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* UNKOWN TYPE
|
||||
*/
|
||||
|
|
|
@ -39,7 +39,7 @@ public:
|
|||
return;
|
||||
|
||||
// todo: this needs to be done properly and used queued zoning + aethernet animation
|
||||
// moving a player inside an event will crash the game so we end it hre
|
||||
// moving a player inside an event will crash the game so we end it here
|
||||
player.eventFinish( eventId, 1 );
|
||||
|
||||
auto playerMgr = framework()->get< Sapphire::World::Manager::PlayerMgr >();
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
#include <ScriptObject.h>
|
||||
#include <Actor/Player.h>
|
||||
|
||||
#include <datReader/DatCategories/bg/LgbTypes.h>
|
||||
#include <datReader/DatCategories/bg/Lgb.h>
|
||||
|
||||
#include "Territory/InstanceObjectCache.h"
|
||||
|
||||
#include <Exd/ExdDataGenerated.h>
|
||||
#include <Framework.h>
|
||||
#include <Manager/PlayerMgr.h>
|
||||
|
@ -28,11 +33,25 @@ public:
|
|||
player.eventFinish( getId(), 1 );
|
||||
|
||||
auto exdData = framework()->get< Sapphire::Data::ExdDataGenerated >();
|
||||
auto pPopRange = framework()->get< Sapphire::InstanceObjectCache >();
|
||||
|
||||
auto warp = exdData->get< Sapphire::Data::Warp >( getId() );
|
||||
if( !warp )
|
||||
return;
|
||||
|
||||
auto playerMgr = framework()->get< Sapphire::World::Manager::PlayerMgr >();
|
||||
|
||||
auto pPop = pPopRange->getPopRange( warp->level, warp->level );
|
||||
|
||||
if( !pPop )
|
||||
{
|
||||
std::cout << "not found...";
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "found!!";
|
||||
}
|
||||
|
||||
playerMgr->movePlayerToLandDestination( player, warp->level, result.param3 );
|
||||
}
|
||||
else
|
||||
|
|
|
@ -36,10 +36,11 @@ struct ZoneInfo
|
|||
uint16_t id;
|
||||
std::string name;
|
||||
std::string path;
|
||||
uint16_t mapId;
|
||||
};
|
||||
|
||||
// parsing shit
|
||||
std::string gamePath( "C:\\Program Files (x86)\\SquareEnix\\FINAL FANTASY XIV - A Realm Reborn\\game\\sqpack" );
|
||||
std::string gamePath( "C:\\SquareEnix\\FINAL FANTASY XIV - A Realm Reborn\\game\\sqpack" );
|
||||
std::unordered_map< uint32_t, std::string > eobjNameMap;
|
||||
std::unordered_map< uint16_t, ZoneInfo > zoneInfoMap;
|
||||
std::unordered_map< uint16_t, std::vector< std::pair< uint16_t, std::string > > > zoneInstanceMap;
|
||||
|
@ -60,8 +61,7 @@ struct vec2
|
|||
float x, y;
|
||||
};
|
||||
|
||||
struct DiscoveryMap :
|
||||
std::enable_shared_from_this< DiscoveryMap >
|
||||
struct DiscoveryMap : std::enable_shared_from_this< DiscoveryMap >
|
||||
{
|
||||
std::string path;
|
||||
Image img;
|
||||
|
@ -120,11 +120,11 @@ struct DiscoveryMap :
|
|||
std::map< uint16_t, std::map< uint16_t, std::map< uint16_t, std::shared_ptr< DiscoveryMap > > > > discoveryMaps;
|
||||
|
||||
|
||||
enum class TerritoryTypeExdIndexes :
|
||||
size_t
|
||||
enum class TerritoryTypeExdIndexes : size_t
|
||||
{
|
||||
TerritoryType = 0,
|
||||
Path = 1
|
||||
Path = 1,
|
||||
Map = 6
|
||||
};
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
@ -165,6 +165,8 @@ std::string zoneNameToPath( const std::string& name )
|
|||
info.id = row.first;
|
||||
info.path = teriPath;
|
||||
info.name = teriName;
|
||||
info.mapId = std::get< uint16_t >(
|
||||
fields.at( static_cast< size_t >( TerritoryTypeExdIndexes::Map ) ) );
|
||||
zoneInfoMap[ row.first ] = info;
|
||||
|
||||
if( !found && ( Common::Util::toLowerCopy( name ) == Common::Util::toLowerCopy( teriName ) ) )
|
||||
|
@ -217,69 +219,31 @@ void loadEobjNames()
|
|||
}
|
||||
}
|
||||
|
||||
void writeEobjEntry( std::ofstream& out, LGB_ENTRY* pObj )
|
||||
void writeMapRangeEntry( std::ofstream& out, LgbEntry* pObj )
|
||||
{
|
||||
static std::string mapRangeStr( "\"MapRange\", " );
|
||||
std::ofstream discoverySql( zoneName + "_poprange.txt", std::ios::app );
|
||||
uint32_t id;
|
||||
uint32_t unknown2 = 0, unknown2_1 = 0, unknown3 = 0;
|
||||
std::string name;
|
||||
std::string typeStr;
|
||||
uint32_t eobjlevelHierachyId = 0;
|
||||
static std::map< uint32_t, std::map< uint32_t, uint32_t > > exportedMapRange;
|
||||
auto pMapRange = reinterpret_cast< LGB_MAP_RANGE_ENTRY* >( pObj );
|
||||
if( !pMapRange->data.discoveryEnabled )
|
||||
return;
|
||||
|
||||
auto pMapRange = reinterpret_cast< LGB_MAPRANGE_ENTRY* >( pObj );
|
||||
id = pMapRange->header.unknown;
|
||||
unknown2 = pMapRange->header.unknown2;
|
||||
unknown2_1 = pMapRange->header.unknown2_1;
|
||||
unknown3 = pMapRange->header.unknown3;
|
||||
typeStr = mapRangeStr;
|
||||
|
||||
// discovery shit
|
||||
vec2 pos{ 0 };
|
||||
auto subArea = 0;
|
||||
auto mapId = -1;
|
||||
auto discoveryIndex = pMapRange->header.discoveryIndex;
|
||||
auto discoveryIndex = pMapRange->data.discoveryIndex;
|
||||
|
||||
vec3 translation = pObj->header.translation;
|
||||
vec3 translation = pObj->header.transform.translation;
|
||||
|
||||
bool found = false;
|
||||
float scale = 100.f; //pMapRange->header.unknown2
|
||||
|
||||
std::string outStr( pMapRange->name + " " + std::to_string( pMapRange->header.unknown ) + " " +
|
||||
std::to_string( pMapRange->header.translation.x ) + " " +
|
||||
std::to_string( pMapRange->header.translation.y ) + " " +
|
||||
std::to_string( pMapRange->header.translation.z ) + " " +
|
||||
std::to_string( pMapRange->header.rotation.y ) + "\n"
|
||||
std::string outStr( pMapRange->name + " " + std::to_string( pMapRange->header.instanceId ) + " " +
|
||||
std::to_string( pMapRange->header.transform.translation.x ) + " " +
|
||||
std::to_string( pMapRange->header.transform.translation.y ) + " " +
|
||||
std::to_string( pMapRange->header.transform.translation.z ) + " " +
|
||||
std::to_string( pMapRange->header.transform.rotation.y ) + " " +
|
||||
std::to_string( pMapRange->data.mapId ) + " " +
|
||||
std::to_string( pMapRange->data.discoveryIndex ) + "\n"
|
||||
);
|
||||
|
||||
//std::to_string( pObj->header.translation.x ) + ", " + std::to_string( pObj->header.translation.y ) + ", " + std::to_string( pObj->header.translation.z ) +
|
||||
//", " + std::to_string( subArea ) + "" + "\n"
|
||||
//);
|
||||
discoverySql.write( outStr.c_str(), outStr.size() );
|
||||
//out.write( outStr.c_str(), outStr.size() );
|
||||
}
|
||||
out.write( outStr.c_str(), outStr.size() );
|
||||
|
||||
void readFileToBuffer( const std::string& path, std::vector< char >& buf )
|
||||
{
|
||||
auto inFile = std::ifstream( path, std::ios::binary );
|
||||
if( inFile.good() )
|
||||
{
|
||||
inFile.seekg( 0, inFile.end );
|
||||
int32_t fileSize = ( int32_t ) inFile.tellg();
|
||||
buf.resize( fileSize );
|
||||
inFile.seekg( 0, inFile.beg );
|
||||
inFile.read( &buf[ 0 ], fileSize );
|
||||
inFile.close();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::runtime_error( "Unable to open " + path );
|
||||
}
|
||||
}
|
||||
|
||||
bool isEx = false;
|
||||
|
||||
int main( int argc, char* argv[] )
|
||||
{
|
||||
auto startTime = std::chrono::system_clock::now();
|
||||
|
@ -288,10 +252,6 @@ int main( int argc, char* argv[] )
|
|||
std::vector< std::string > argVec( argv + 1, argv + argc );
|
||||
zoneName = "s1h1";
|
||||
|
||||
bool dumpAll = ignoreModels = std::remove_if( argVec.begin(), argVec.end(), []( auto arg )
|
||||
{ return arg == "--dump-all"; } ) != argVec.end();
|
||||
dumpAll = true;
|
||||
ignoreModels = true;
|
||||
if( argc > 1 )
|
||||
{
|
||||
zoneName = argv[ 1 ];
|
||||
|
@ -304,118 +264,42 @@ int main( int argc, char* argv[] )
|
|||
}
|
||||
|
||||
initExd( gamePath );
|
||||
std::ofstream discoverySql( zoneName + "_poprange.txt", std::ios::trunc );
|
||||
discoverySql.close();
|
||||
std::ofstream discoverySql( "maprange_export.txt", std::ios::trunc );
|
||||
|
||||
if( dumpAll )
|
||||
zoneNameToPath( "f1f1" );
|
||||
zoneDumpList.emplace( "f1f1" );
|
||||
zoneDumpList.emplace( "f1f2" );
|
||||
|
||||
for( const auto& zoneName : zoneDumpList )
|
||||
{
|
||||
zoneNameToPath( "s1h1" );
|
||||
|
||||
zoneDumpList.emplace( "s1h1" );
|
||||
zoneDumpList.emplace( "f1h1" );
|
||||
zoneDumpList.emplace( "w1h1" );
|
||||
zoneDumpList.emplace( "e1h1" );
|
||||
}
|
||||
else
|
||||
{
|
||||
zoneDumpList.emplace( zoneName );
|
||||
}
|
||||
|
||||
LABEL_DUMP:
|
||||
entryStartTime = std::chrono::system_clock::now();
|
||||
zoneName = *zoneDumpList.begin();
|
||||
discoverySql.open( zoneName + "_poprange.txt", std::ios::trunc );
|
||||
discoverySql.write( ( zoneName + "\n" ).c_str() , zoneName.size() + 1 );
|
||||
try
|
||||
{
|
||||
const auto zonePath = zoneNameToPath( zoneName );
|
||||
|
||||
std::string listPcbPath( zonePath + "/collision/list.pcb" );
|
||||
std::string bgLgbPath( zonePath + "/level/bg.lgb" );
|
||||
std::string planmapLgbPath( zonePath + "/level/planmap.lgb" );
|
||||
std::string collisionFilePath( zonePath + "/collision/" );
|
||||
|
||||
isEx = bgLgbPath.find( "ex1" ) != -1 || bgLgbPath.find( "ex2" ) != -1;
|
||||
std::vector< char > section;
|
||||
std::vector< char > section1;
|
||||
std::vector< char > section2;
|
||||
|
||||
auto test_file = gameData->getFile( bgLgbPath );
|
||||
section = test_file->access_data_sections().at( 0 );
|
||||
|
||||
auto planmap_file = gameData->getFile( planmapLgbPath );
|
||||
section2 = planmap_file->access_data_sections().at( 0 );
|
||||
|
||||
auto test_file1 = gameData->getFile( listPcbPath );
|
||||
section1 = test_file1->access_data_sections().at( 0 );
|
||||
|
||||
std::vector< std::string > stringList;
|
||||
|
||||
uint32_t offset1 = 0x20;
|
||||
|
||||
//loadEobjNames();
|
||||
//getMapExdEntries( zoneId );
|
||||
|
||||
std::string eobjFileName( zoneName + "_eobj.csv" );
|
||||
std::ofstream eobjOut( eobjFileName, std::ios::trunc );
|
||||
if( !eobjOut.good() )
|
||||
throw std::string( "Unable to create " + zoneName +
|
||||
"_eobj.csv for eobj entries. Run as admin or check there isnt already a handle on the file." ).c_str();
|
||||
|
||||
eobjOut.close();
|
||||
eobjOut.open( eobjFileName, std::ios::app );
|
||||
|
||||
if( !eobjOut.good() )
|
||||
throw std::string( "Unable to create " + zoneName +
|
||||
"_eobj.csv for eobj entries. Run as admin or check there isnt already a handle on the file." ).c_str();
|
||||
|
||||
if( 0 )
|
||||
entryStartTime = std::chrono::system_clock::now();
|
||||
discoverySql.write( ( zoneName + "\n" ).c_str(), zoneName.size() + 1 );
|
||||
try
|
||||
{
|
||||
for( ;; )
|
||||
{
|
||||
const auto zonePath = zoneNameToPath( zoneName );
|
||||
|
||||
uint16_t trId = *( uint16_t* ) §ion1[ offset1 ];
|
||||
std::string bgLgbPath( zonePath + "/level/bg.lgb" );
|
||||
std::string planmapLgbPath( zonePath + "/level/planmap.lgb" );
|
||||
std::vector< char > section;
|
||||
std::vector< char > section2;
|
||||
|
||||
char someString[200];
|
||||
sprintf( someString, "%str%04d.pcb", collisionFilePath.c_str(), trId );
|
||||
stringList.push_back( std::string( someString ) );
|
||||
//std::cout << someString << "\n";
|
||||
offset1 += 0x20;
|
||||
auto test_file = gameData->getFile( bgLgbPath );
|
||||
section = test_file->access_data_sections().at( 0 );
|
||||
|
||||
if( offset1 >= section1.size() )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
LGB_FILE bgLgb( §ion[ 0 ], "bg" );
|
||||
LGB_FILE planmapLgb( §ion2[ 0 ], "planmap" );
|
||||
auto planmap_file = gameData->getFile( planmapLgbPath );
|
||||
section2 = planmap_file->access_data_sections().at( 0 );
|
||||
|
||||
std::vector< LGB_FILE > lgbList{ bgLgb, planmapLgb };
|
||||
uint32_t max_index = 0;
|
||||
std::vector< std::string > stringList;
|
||||
|
||||
// dont bother if we cant write to a file
|
||||
FILE* fp_out = nullptr;
|
||||
//auto fp_out = ignoreModels ? ( FILE* )nullptr : fopen( ( zoneName + ".obj" ).c_str(), "w" );
|
||||
if( fp_out )
|
||||
{
|
||||
fprintf( fp_out, "\n" );
|
||||
fclose( fp_out );
|
||||
}
|
||||
else if( /*!ignoreModels*/ false )
|
||||
{
|
||||
std::string errorMessage( "Cannot create " + zoneName + ".obj\n" +
|
||||
" Check no programs have a handle to file and run as admin.\n" );
|
||||
std::cout << errorMessage;
|
||||
throw std::runtime_error( errorMessage.c_str() );
|
||||
return 0;
|
||||
}
|
||||
uint32_t offset1 = 0x20;
|
||||
|
||||
LGB_FILE bgLgb( §ion[ 0 ], "bg" );
|
||||
LGB_FILE planmapLgb( §ion2[ 0 ], "planmap" );
|
||||
|
||||
{
|
||||
std::map< std::string, PCB_FILE > pcbFiles;
|
||||
std::vector< LGB_FILE > lgbList{ bgLgb, planmapLgb };
|
||||
uint32_t max_index = 0;
|
||||
|
||||
std::cout << "[Info] " << ( ignoreModels ? "Dumping MapRange and EObj" : "Writing obj file " ) << "\n";
|
||||
std::cout << "[Info] " << "Dumping MapRange and EObj" << "\n";
|
||||
uint32_t totalGroups = 0;
|
||||
uint32_t totalGroupEntries = 0;
|
||||
|
||||
|
@ -423,48 +307,46 @@ int main( int argc, char* argv[] )
|
|||
{
|
||||
for( const auto& group : lgb.groups )
|
||||
{
|
||||
//std::cout << "\t" << group.name << " Size " << group.header.entryCount << "\n";
|
||||
totalGroups++;
|
||||
for( const auto& pEntry : group.entries )
|
||||
{
|
||||
if( pEntry->getType() == LgbEntryType::PopRange )
|
||||
if( pEntry->getType() == LgbEntryType::MapRange )
|
||||
{
|
||||
totalGroupEntries++;
|
||||
writeEobjEntry( eobjOut, pEntry.get() );
|
||||
writeMapRangeEntry( discoverySql, pEntry.get() );
|
||||
}
|
||||
else if( pEntry->getType() == LgbEntryType::ExitRange )
|
||||
{
|
||||
auto pExitRange = reinterpret_cast< LGB_EXIT_RANGE_ENTRY* >( pEntry.get() );
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
std::cout << "[Info] " << "Loaded " << pcbFiles.size() << " PCB Files \n";
|
||||
std::cout << "[Info] " << "Total Groups " << totalGroups << " Total entries " << totalGroupEntries << "\n";
|
||||
|
||||
std::cout << "[Success] " << "Exported " << zoneName << " in " <<
|
||||
std::chrono::duration_cast< std::chrono::seconds >(
|
||||
std::chrono::system_clock::now() - entryStartTime ).count() << " seconds\n";
|
||||
}
|
||||
std::cout << "[Success] " << "Exported " << zoneName << " in " <<
|
||||
std::chrono::duration_cast< std::chrono::seconds >(
|
||||
std::chrono::system_clock::now() - entryStartTime ).count() << " seconds\n";
|
||||
catch( std::exception& e )
|
||||
{
|
||||
std::cout << "[Error] " << e.what() << std::endl;
|
||||
std::cout << "[Error] "
|
||||
<< "Unable to extract collision data.\n\tIf using standalone ensure your working directory folder layout is \n\tbg/[ffxiv|ex1|ex2]/teri/type/zone/[level|collision]"
|
||||
<< std::endl;
|
||||
std::cout << std::endl;
|
||||
std::cout << "[Info] " << "Usage: pcb_reader2 territory \"path/to/game/sqpack/ffxiv\" " << std::endl;
|
||||
}
|
||||
std::cout << "\n";
|
||||
if( discoverySql.good() )
|
||||
discoverySql.flush();
|
||||
}
|
||||
catch( std::exception& e )
|
||||
{
|
||||
std::cout << "[Error] " << e.what() << std::endl;
|
||||
std::cout << "[Error] "
|
||||
<< "Unable to extract collision data.\n\tIf using standalone ensure your working directory folder layout is \n\tbg/[ffxiv|ex1|ex2]/teri/type/zone/[level|collision]"
|
||||
<< std::endl;
|
||||
std::cout << std::endl;
|
||||
std::cout << "[Info] " << "Usage: pcb_reader2 territory \"path/to/game/sqpack/ffxiv\" " << std::endl;
|
||||
}
|
||||
std::cout << "\n\n\n";
|
||||
if( discoverySql.good() )
|
||||
discoverySql.flush();
|
||||
|
||||
LABEL_NEXT_ZONE_ENTRY:
|
||||
zoneDumpList.erase( zoneName );
|
||||
if( !zoneDumpList.empty() )
|
||||
goto LABEL_DUMP;
|
||||
|
||||
|
||||
std::cout << "\n\n\n[Success] Finished all tasks in " <<
|
||||
std::cout << "\n[Success] Finished all tasks in " <<
|
||||
std::chrono::duration_cast< std::chrono::seconds >( std::chrono::system_clock::now() - startTime ).count()
|
||||
<< " seconds\n";
|
||||
|
||||
std::cout << "Press any key to exit...";
|
||||
getchar();
|
||||
|
||||
if( eData )
|
||||
|
|
|
@ -284,10 +284,10 @@ int main( int argc, char* argv[] )
|
|||
uint32_t eobjlevelHierachyId = 0;
|
||||
|
||||
auto pEobj = reinterpret_cast< LGB_EOBJ_ENTRY* >( pObj );
|
||||
id = pEobj->header.eobjId;
|
||||
unknown = pEobj->header.unknown;
|
||||
id = pEobj->data.eobjId;
|
||||
unknown = pEobj->header.instanceId;
|
||||
|
||||
eobjlevelHierachyId = pEobj->header.levelHierachyId;
|
||||
eobjlevelHierachyId = pEobj->data.levelHierachyId;
|
||||
|
||||
std::string states = "";
|
||||
std::string gimmickName = "";
|
||||
|
@ -295,7 +295,7 @@ int main( int argc, char* argv[] )
|
|||
{
|
||||
auto pGObj = pEntry1.get();
|
||||
if( pGObj->getType() == LgbEntryType::Gimmick &&
|
||||
pGObj->header.unknown == pEobj->header.levelHierachyId )
|
||||
pGObj->header.instanceId == pEobj->data.levelHierachyId )
|
||||
{
|
||||
auto pGObjR = reinterpret_cast< LGB_GIMMICK_ENTRY* >( pGObj );
|
||||
char* dataSection = nullptr;
|
||||
|
@ -361,13 +361,13 @@ int main( int argc, char* argv[] )
|
|||
eobjects += " instance.registerEObj( \"" + name + "\", " + std::to_string( id ) +
|
||||
", " + std::to_string( eobjlevelHierachyId ) + ", " + std::to_string( state ) +
|
||||
", " +
|
||||
"{ " + std::to_string( pObj->header.translation.x ) + "f, "
|
||||
+ std::to_string( pObj->header.translation.y ) + "f, "
|
||||
+ std::to_string( pObj->header.translation.z ) + "f }, " +
|
||||
std::to_string( pObj->header.scale.x ) + "f, " +
|
||||
"{ " + std::to_string( pObj->header.transform.translation.x ) + "f, "
|
||||
+ std::to_string( pObj->header.transform.translation.y ) + "f, "
|
||||
+ std::to_string( pObj->header.transform.translation.z ) + "f }, " +
|
||||
std::to_string( pObj->header.transform.scale.x ) + "f, " +
|
||||
|
||||
// the rotation inside the sgbs is the inverse of what the game uses
|
||||
std::to_string( pObj->header.rotation.y * -1.f ) + "f ); \n" + states;
|
||||
std::to_string( pObj->header.transform.rotation.y * -1.f ) + "f ); \n" + states;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,6 +43,11 @@ STRUCTS
|
|||
std::shared_ptr< xiv::dat::GameData > m_data;
|
||||
std::shared_ptr< xiv::exd::ExdData > m_exd_data;
|
||||
|
||||
std::shared_ptr< xiv::dat::GameData > getGameData()
|
||||
{
|
||||
return m_data;
|
||||
}
|
||||
|
||||
template< class T >
|
||||
std::shared_ptr< T > get( uint32_t id )
|
||||
{
|
||||
|
|
|
@ -68,7 +68,7 @@ enum class LgbEntryType :
|
|||
SphereCastRange = 75,
|
||||
};
|
||||
|
||||
struct LGB_ENTRY_HEADER
|
||||
struct InstanceObject
|
||||
{
|
||||
LgbEntryType type;
|
||||
uint32_t unknown;
|
||||
|
@ -78,25 +78,25 @@ struct LGB_ENTRY_HEADER
|
|||
vec3 scale;
|
||||
};
|
||||
|
||||
class LGB_ENTRY
|
||||
class LgbEntry
|
||||
{
|
||||
public:
|
||||
char* m_buf;
|
||||
uint32_t m_offset;
|
||||
LGB_ENTRY_HEADER header;
|
||||
InstanceObject header;
|
||||
|
||||
LGB_ENTRY()
|
||||
LgbEntry()
|
||||
{
|
||||
m_buf = nullptr;
|
||||
m_offset = 0;
|
||||
memset( &header, 0, sizeof( header ) );
|
||||
};
|
||||
|
||||
LGB_ENTRY( char* buf, uint32_t offset )
|
||||
LgbEntry( char* buf, uint32_t offset )
|
||||
{
|
||||
m_buf = buf;
|
||||
m_offset = offset;
|
||||
header = *reinterpret_cast< LGB_ENTRY_HEADER* >( buf + offset );
|
||||
header = *reinterpret_cast< InstanceObject* >( buf + offset );
|
||||
};
|
||||
|
||||
const LgbEntryType getType() const
|
||||
|
@ -104,14 +104,14 @@ public:
|
|||
return header.type;
|
||||
};
|
||||
|
||||
virtual ~LGB_ENTRY()
|
||||
virtual ~LgbEntry()
|
||||
{
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
struct LGB_BGPARTS_HEADER :
|
||||
public LGB_ENTRY_HEADER
|
||||
struct BgPartsData :
|
||||
public InstanceObject
|
||||
{
|
||||
uint32_t modelFileOffset;
|
||||
uint32_t collisionFileOffset;
|
||||
|
@ -124,10 +124,10 @@ struct LGB_BGPARTS_HEADER :
|
|||
};
|
||||
|
||||
class LGB_BGPARTS_ENTRY :
|
||||
public LGB_ENTRY
|
||||
public LgbEntry
|
||||
{
|
||||
public:
|
||||
LGB_BGPARTS_HEADER header;
|
||||
BgPartsData header;
|
||||
std::string name;
|
||||
std::string modelFileName;
|
||||
std::string collisionFileName;
|
||||
|
@ -137,65 +137,65 @@ public:
|
|||
};
|
||||
|
||||
LGB_BGPARTS_ENTRY( char* buf, uint32_t offset ) :
|
||||
LGB_ENTRY( buf, offset )
|
||||
LgbEntry( buf, offset )
|
||||
{
|
||||
header = *reinterpret_cast<LGB_BGPARTS_HEADER*>( buf + offset );
|
||||
header = *reinterpret_cast<BgPartsData*>( buf + offset );
|
||||
name = std::string( buf + offset + header.nameOffset );
|
||||
modelFileName = std::string( buf + offset + header.modelFileOffset );
|
||||
collisionFileName = std::string( buf + offset + header.collisionFileOffset );
|
||||
};
|
||||
};
|
||||
|
||||
struct LGB_GIMMICK_HEADER :
|
||||
public LGB_ENTRY_HEADER
|
||||
struct GimmickData :
|
||||
public InstanceObject
|
||||
{
|
||||
uint32_t gimmickFileOffset;
|
||||
char unknownBytes[100];
|
||||
};
|
||||
|
||||
class LGB_GIMMICK_ENTRY :
|
||||
public LGB_ENTRY
|
||||
public LgbEntry
|
||||
{
|
||||
public:
|
||||
LGB_GIMMICK_HEADER header;
|
||||
GimmickData header;
|
||||
std::string name;
|
||||
std::string gimmickFileName;
|
||||
|
||||
LGB_GIMMICK_ENTRY( char* buf, uint32_t offset ) :
|
||||
LGB_ENTRY( buf, offset )
|
||||
LgbEntry( buf, offset )
|
||||
{
|
||||
header = *reinterpret_cast<LGB_GIMMICK_HEADER*>( buf + offset );
|
||||
header = *reinterpret_cast<GimmickData*>( buf + offset );
|
||||
name = std::string( buf + offset + header.nameOffset );
|
||||
gimmickFileName = std::string( buf + offset + header.gimmickFileOffset );
|
||||
//std::cout << "\t " << gimmickFileName << " unknown: " << header.unknown << "\n";
|
||||
};
|
||||
};
|
||||
|
||||
struct LGB_ENPC_HEADER :
|
||||
public LGB_ENTRY_HEADER
|
||||
struct ENpcData :
|
||||
public InstanceObject
|
||||
{
|
||||
uint32_t enpcId;
|
||||
uint8_t unknown1[0x24];
|
||||
};
|
||||
|
||||
class LGB_ENPC_ENTRY :
|
||||
public LGB_ENTRY
|
||||
public LgbEntry
|
||||
{
|
||||
public:
|
||||
LGB_ENPC_HEADER header;
|
||||
ENpcData header;
|
||||
std::string name;
|
||||
|
||||
LGB_ENPC_ENTRY( char* buf, uint32_t offset ) :
|
||||
LGB_ENTRY( buf, offset )
|
||||
LgbEntry( buf, offset )
|
||||
{
|
||||
header = *reinterpret_cast< LGB_ENPC_HEADER* >( buf + offset );
|
||||
header = *reinterpret_cast< ENpcData* >( buf + offset );
|
||||
name = std::string( buf + offset + header.nameOffset );
|
||||
//std::cout << "\t ENpc " << header.enpcId << " " << name << "\n";
|
||||
};
|
||||
};
|
||||
|
||||
struct LGB_EOBJ_HEADER :
|
||||
public LGB_ENTRY_HEADER
|
||||
struct EObjData :
|
||||
public InstanceObject
|
||||
{
|
||||
uint32_t eobjId;
|
||||
uint32_t levelHierachyId;
|
||||
|
@ -203,23 +203,23 @@ struct LGB_EOBJ_HEADER :
|
|||
};
|
||||
|
||||
class LGB_EOBJ_ENTRY :
|
||||
public LGB_ENTRY
|
||||
public LgbEntry
|
||||
{
|
||||
public:
|
||||
LGB_EOBJ_HEADER header;
|
||||
EObjData header;
|
||||
std::string name;
|
||||
|
||||
LGB_EOBJ_ENTRY( char* buf, uint32_t offset ) :
|
||||
LGB_ENTRY( buf, offset )
|
||||
LgbEntry( buf, offset )
|
||||
{
|
||||
header = *reinterpret_cast< LGB_EOBJ_HEADER* >( buf + offset );
|
||||
header = *reinterpret_cast< EObjData* >( buf + offset );
|
||||
//std::cout << "\t " << header.eobjId << " " << name << " unknown: " << header.unknown << "\n";
|
||||
name = std::string( buf + offset + header.nameOffset );
|
||||
};
|
||||
};
|
||||
|
||||
struct LGB_MAPRANGE_HEADER :
|
||||
public LGB_ENTRY_HEADER
|
||||
struct MapRangeData :
|
||||
public InstanceObject
|
||||
{
|
||||
uint32_t type;
|
||||
uint16_t unknown2;
|
||||
|
@ -227,35 +227,35 @@ struct LGB_MAPRANGE_HEADER :
|
|||
uint8_t unknown4[0x10];
|
||||
};
|
||||
|
||||
struct LGB_MAPRANGE_ENTRY :
|
||||
public LGB_ENTRY
|
||||
struct LGB_MAP_RANGE_ENTRY :
|
||||
public LgbEntry
|
||||
{
|
||||
public:
|
||||
LGB_MAPRANGE_HEADER header;
|
||||
MapRangeData header;
|
||||
std::string name;
|
||||
|
||||
LGB_MAPRANGE_ENTRY( char* buf, uint32_t offset ) :
|
||||
LGB_ENTRY( buf, offset )
|
||||
LGB_MAP_RANGE_ENTRY( char* buf, uint32_t offset ) :
|
||||
LgbEntry( buf, offset )
|
||||
{
|
||||
header = *reinterpret_cast< LGB_MAPRANGE_HEADER* >( buf + offset );
|
||||
header = *reinterpret_cast< MapRangeData* >( buf + offset );
|
||||
name = std::string( buf + offset + header.nameOffset );
|
||||
};
|
||||
};
|
||||
|
||||
struct LGB_COLLISION_BOX_HEADER :
|
||||
public LGB_ENTRY_HEADER
|
||||
public InstanceObject
|
||||
{
|
||||
uint8_t unk[100];
|
||||
};
|
||||
|
||||
struct LGB_COLLISION_BOX_ENTRY :
|
||||
public LGB_ENTRY
|
||||
public LgbEntry
|
||||
{
|
||||
LGB_COLLISION_BOX_HEADER header;
|
||||
std::string name;
|
||||
|
||||
LGB_COLLISION_BOX_ENTRY( char* buf, uint32_t offset ) :
|
||||
LGB_ENTRY( buf, offset )
|
||||
LgbEntry( buf, offset )
|
||||
{
|
||||
header = *reinterpret_cast< LGB_COLLISION_BOX_HEADER* >( buf + offset );
|
||||
header.type = LgbEntryType::CollisionBox;
|
||||
|
@ -305,7 +305,7 @@ struct LGB_GROUP
|
|||
LGB_FILE* parent;
|
||||
LGB_GROUP_HEADER header;
|
||||
std::string name;
|
||||
std::vector< std::shared_ptr< LGB_ENTRY > > entries;
|
||||
std::vector< std::shared_ptr< LgbEntry > > entries;
|
||||
|
||||
LGB_GROUP( char* buf, LGB_FILE* parentStruct, uint32_t offset )
|
||||
{
|
||||
|
|
|
@ -257,7 +257,7 @@ bool pcbTransformModel( const std::string& fileName, const vec3* scale, const ve
|
|||
return true;
|
||||
};
|
||||
|
||||
void exportSgbModel( const std::string& sgbFilePath, LGB_ENTRY* pGimmick, ExportedGroup& exportgroup, bool isEobj = false )
|
||||
void exportSgbModel( const std::string& sgbFilePath, LgbEntry* pGimmick, ExportedGroup& exportgroup, bool isEobj = false )
|
||||
{
|
||||
if( auto pSgbFile = pCache->getSgbFile( sgbFilePath ) )
|
||||
{
|
||||
|
|
|
@ -68,7 +68,7 @@ enum class LgbEntryType :
|
|||
SphereCastRange = 75,
|
||||
};
|
||||
|
||||
struct LGB_ENTRY_HEADER
|
||||
struct InstanceObject
|
||||
{
|
||||
LgbEntryType type;
|
||||
uint32_t unknown;
|
||||
|
@ -78,25 +78,25 @@ struct LGB_ENTRY_HEADER
|
|||
vec3 scale;
|
||||
};
|
||||
|
||||
class LGB_ENTRY
|
||||
class LgbEntry
|
||||
{
|
||||
public:
|
||||
char* m_buf;
|
||||
uint32_t m_offset;
|
||||
LGB_ENTRY_HEADER header;
|
||||
InstanceObject header;
|
||||
|
||||
LGB_ENTRY()
|
||||
LgbEntry()
|
||||
{
|
||||
m_buf = nullptr;
|
||||
m_offset = 0;
|
||||
memset( &header, 0, sizeof( header ) );
|
||||
};
|
||||
|
||||
LGB_ENTRY( char* buf, uint32_t offset )
|
||||
LgbEntry( char* buf, uint32_t offset )
|
||||
{
|
||||
m_buf = buf;
|
||||
m_offset = offset;
|
||||
header = *reinterpret_cast< LGB_ENTRY_HEADER* >( buf + offset );
|
||||
header = *reinterpret_cast< InstanceObject* >( buf + offset );
|
||||
};
|
||||
|
||||
const LgbEntryType getType() const
|
||||
|
@ -104,14 +104,14 @@ public:
|
|||
return header.type;
|
||||
};
|
||||
|
||||
virtual ~LGB_ENTRY()
|
||||
virtual ~LgbEntry()
|
||||
{
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
struct LGB_BGPARTS_HEADER :
|
||||
public LGB_ENTRY_HEADER
|
||||
struct BgPartsData :
|
||||
public InstanceObject
|
||||
{
|
||||
uint32_t modelFileOffset;
|
||||
uint32_t collisionFileOffset;
|
||||
|
@ -124,10 +124,10 @@ struct LGB_BGPARTS_HEADER :
|
|||
};
|
||||
|
||||
class LGB_BGPARTS_ENTRY :
|
||||
public LGB_ENTRY
|
||||
public LgbEntry
|
||||
{
|
||||
public:
|
||||
LGB_BGPARTS_HEADER header;
|
||||
BgPartsData header;
|
||||
std::string name;
|
||||
std::string modelFileName;
|
||||
std::string collisionFileName;
|
||||
|
@ -137,65 +137,65 @@ public:
|
|||
};
|
||||
|
||||
LGB_BGPARTS_ENTRY( char* buf, uint32_t offset ) :
|
||||
LGB_ENTRY( buf, offset )
|
||||
LgbEntry( buf, offset )
|
||||
{
|
||||
header = *reinterpret_cast<LGB_BGPARTS_HEADER*>( buf + offset );
|
||||
header = *reinterpret_cast<BgPartsData*>( buf + offset );
|
||||
name = std::string( buf + offset + header.nameOffset );
|
||||
modelFileName = std::string( buf + offset + header.modelFileOffset );
|
||||
collisionFileName = std::string( buf + offset + header.collisionFileOffset );
|
||||
};
|
||||
};
|
||||
|
||||
struct LGB_GIMMICK_HEADER :
|
||||
public LGB_ENTRY_HEADER
|
||||
struct GimmickData :
|
||||
public InstanceObject
|
||||
{
|
||||
uint32_t gimmickFileOffset;
|
||||
char unknownBytes[100];
|
||||
};
|
||||
|
||||
class LGB_GIMMICK_ENTRY :
|
||||
public LGB_ENTRY
|
||||
public LgbEntry
|
||||
{
|
||||
public:
|
||||
LGB_GIMMICK_HEADER header;
|
||||
GimmickData header;
|
||||
std::string name;
|
||||
std::string gimmickFileName;
|
||||
|
||||
LGB_GIMMICK_ENTRY( char* buf, uint32_t offset ) :
|
||||
LGB_ENTRY( buf, offset )
|
||||
LgbEntry( buf, offset )
|
||||
{
|
||||
header = *reinterpret_cast<LGB_GIMMICK_HEADER*>( buf + offset );
|
||||
header = *reinterpret_cast<GimmickData*>( buf + offset );
|
||||
name = std::string( buf + offset + header.nameOffset );
|
||||
gimmickFileName = std::string( buf + offset + header.gimmickFileOffset );
|
||||
//std::cout << "\t " << gimmickFileName << " unknown: " << header.unknown << "\n";
|
||||
};
|
||||
};
|
||||
|
||||
struct LGB_ENPC_HEADER :
|
||||
public LGB_ENTRY_HEADER
|
||||
struct ENpcData :
|
||||
public InstanceObject
|
||||
{
|
||||
uint32_t enpcId;
|
||||
uint8_t unknown1[0x24];
|
||||
};
|
||||
|
||||
class LGB_ENPC_ENTRY :
|
||||
public LGB_ENTRY
|
||||
public LgbEntry
|
||||
{
|
||||
public:
|
||||
LGB_ENPC_HEADER header;
|
||||
ENpcData header;
|
||||
std::string name;
|
||||
|
||||
LGB_ENPC_ENTRY( char* buf, uint32_t offset ) :
|
||||
LGB_ENTRY( buf, offset )
|
||||
LgbEntry( buf, offset )
|
||||
{
|
||||
header = *reinterpret_cast< LGB_ENPC_HEADER* >( buf + offset );
|
||||
header = *reinterpret_cast< ENpcData* >( buf + offset );
|
||||
name = std::string( buf + offset + header.nameOffset );
|
||||
//std::cout << "\t ENpc " << header.enpcId << " " << name << "\n";
|
||||
};
|
||||
};
|
||||
|
||||
struct LGB_EOBJ_HEADER :
|
||||
public LGB_ENTRY_HEADER
|
||||
struct EObjData :
|
||||
public InstanceObject
|
||||
{
|
||||
uint32_t eobjId;
|
||||
uint32_t levelHierachyId;
|
||||
|
@ -203,23 +203,23 @@ struct LGB_EOBJ_HEADER :
|
|||
};
|
||||
|
||||
class LGB_EOBJ_ENTRY :
|
||||
public LGB_ENTRY
|
||||
public LgbEntry
|
||||
{
|
||||
public:
|
||||
LGB_EOBJ_HEADER header;
|
||||
EObjData header;
|
||||
std::string name;
|
||||
|
||||
LGB_EOBJ_ENTRY( char* buf, uint32_t offset ) :
|
||||
LGB_ENTRY( buf, offset )
|
||||
LgbEntry( buf, offset )
|
||||
{
|
||||
header = *reinterpret_cast< LGB_EOBJ_HEADER* >( buf + offset );
|
||||
header = *reinterpret_cast< EObjData* >( buf + offset );
|
||||
//std::cout << "\t " << header.eobjId << " " << name << " unknown: " << header.unknown << "\n";
|
||||
name = std::string( buf + offset + header.nameOffset );
|
||||
};
|
||||
};
|
||||
|
||||
struct LGB_MAPRANGE_HEADER :
|
||||
public LGB_ENTRY_HEADER
|
||||
struct MapRangeData :
|
||||
public InstanceObject
|
||||
{
|
||||
uint32_t type;
|
||||
uint16_t unknown2;
|
||||
|
@ -227,35 +227,34 @@ struct LGB_MAPRANGE_HEADER :
|
|||
uint8_t unknown4[0x10];
|
||||
};
|
||||
|
||||
struct LGB_MAPRANGE_ENTRY :
|
||||
public LGB_ENTRY
|
||||
struct LGB_MAP_RANGE_ENTRY : public LgbEntry
|
||||
{
|
||||
public:
|
||||
LGB_MAPRANGE_HEADER header;
|
||||
MapRangeData header;
|
||||
std::string name;
|
||||
|
||||
LGB_MAPRANGE_ENTRY( char* buf, uint32_t offset ) :
|
||||
LGB_ENTRY( buf, offset )
|
||||
LGB_MAP_RANGE_ENTRY( char* buf, uint32_t offset ) :
|
||||
LgbEntry( buf, offset )
|
||||
{
|
||||
header = *reinterpret_cast< LGB_MAPRANGE_HEADER* >( buf + offset );
|
||||
header = *reinterpret_cast< MapRangeData* >( buf + offset );
|
||||
name = std::string( buf + offset + header.nameOffset );
|
||||
};
|
||||
};
|
||||
|
||||
struct LGB_COLLISION_BOX_HEADER :
|
||||
public LGB_ENTRY_HEADER
|
||||
public InstanceObject
|
||||
{
|
||||
uint8_t unk[100];
|
||||
};
|
||||
|
||||
struct LGB_COLLISION_BOX_ENTRY :
|
||||
public LGB_ENTRY
|
||||
public LgbEntry
|
||||
{
|
||||
LGB_COLLISION_BOX_HEADER header;
|
||||
std::string name;
|
||||
|
||||
LGB_COLLISION_BOX_ENTRY( char* buf, uint32_t offset ) :
|
||||
LGB_ENTRY( buf, offset )
|
||||
LgbEntry( buf, offset )
|
||||
{
|
||||
header = *reinterpret_cast< LGB_COLLISION_BOX_HEADER* >( buf + offset );
|
||||
header.type = LgbEntryType::CollisionBox;
|
||||
|
@ -305,7 +304,7 @@ struct LGB_GROUP
|
|||
LGB_FILE* parent;
|
||||
LGB_GROUP_HEADER header;
|
||||
std::string name;
|
||||
std::vector< std::shared_ptr< LGB_ENTRY > > entries;
|
||||
std::vector< std::shared_ptr< LgbEntry > > entries;
|
||||
|
||||
LGB_GROUP( char* buf, LGB_FILE* parentStruct, uint32_t offset )
|
||||
{
|
||||
|
|
|
@ -429,7 +429,7 @@ int main( int argc, char* argv[] )
|
|||
}
|
||||
return true;
|
||||
};
|
||||
auto exportSgbModel = [&]( const std::string& sgbFilePath, LGB_ENTRY* pGimmick, bool isEobj = false )
|
||||
auto exportSgbModel = [&]( const std::string& sgbFilePath, LgbEntry* pGimmick, bool isEobj = false )
|
||||
{
|
||||
if( auto pSgbFile = pCache->getSgbFile( sgbFilePath ) )
|
||||
{
|
||||
|
|
|
@ -727,7 +727,7 @@ void Sapphire::Entity::BNpc::calculateStats()
|
|||
m_baseStats.vit = static_cast< uint32_t >( base * ( static_cast< float >( classInfo->modifierVitality ) / 100 ) );
|
||||
m_baseStats.inte = static_cast< uint32_t >( base * ( static_cast< float >( classInfo->modifierIntelligence ) / 100 ) );
|
||||
m_baseStats.mnd = static_cast< uint32_t >( base * ( static_cast< float >( classInfo->modifierMind ) / 100 ) );
|
||||
m_baseStats.pie = static_cast< uint32_t >( base * ( static_cast< float >( classInfo->modifierPiety ) / 100 ) );
|
||||
//m_baseStats.pie = static_cast< uint32_t >( base * ( static_cast< float >( classInfo->modifierPiety ) / 100 ) );
|
||||
|
||||
m_baseStats.determination = static_cast< uint32_t >( base );
|
||||
m_baseStats.pie = static_cast< uint32_t >( base );
|
||||
|
|
|
@ -3,6 +3,9 @@
|
|||
#include <Util/UtilMath.h>
|
||||
#include <Logging/Logger.h>
|
||||
#include <Exd/ExdDataGenerated.h>
|
||||
#include <datReader/DatCategories/bg/LgbTypes.h>
|
||||
#include <datReader/DatCategories/bg/Lgb.h>
|
||||
|
||||
#include <Network/PacketContainer.h>
|
||||
#include <Network/CommonActorControl.h>
|
||||
#include <Network/PacketWrappers/EffectPacket.h>
|
||||
|
@ -19,6 +22,7 @@
|
|||
#include "Territory/Territory.h"
|
||||
#include "Territory/ZonePosition.h"
|
||||
#include "Territory/InstanceContent.h"
|
||||
#include "Territory/InstanceObjectCache.h"
|
||||
#include "Territory/Land.h"
|
||||
|
||||
#include "Network/GameConnection.h"
|
||||
|
@ -269,8 +273,8 @@ void Sapphire::Entity::Player::calculateStats()
|
|||
tribeInfo->iNT );
|
||||
m_baseStats.mnd = static_cast< uint32_t >( base * ( static_cast< float >( classInfo->modifierMind ) / 100 ) +
|
||||
tribeInfo->mND );
|
||||
m_baseStats.pie = static_cast< uint32_t >( base * ( static_cast< float >( classInfo->modifierPiety ) / 100 ) +
|
||||
tribeInfo->pIE );
|
||||
/*m_baseStats.pie = static_cast< uint32_t >( base * ( static_cast< float >( classInfo->modifierPiety ) / 100 ) +
|
||||
tribeInfo->pIE );*/
|
||||
|
||||
m_baseStats.determination = static_cast< uint32_t >( base );
|
||||
m_baseStats.pie = static_cast< uint32_t >( base );
|
||||
|
@ -346,12 +350,12 @@ void Sapphire::Entity::Player::teleport( uint16_t aetheryteId, uint8_t type )
|
|||
auto data = pExdData->get< Sapphire::Data::Aetheryte >( aetheryteId );
|
||||
|
||||
if( data == nullptr )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
setStateFlag( PlayerStateFlag::BetweenAreas );
|
||||
auto targetPos = pTeriMgr->getTerritoryPosition( data->level.at( 0 ) );
|
||||
|
||||
auto pInstanceObjectCache = m_pFw->get< InstanceObjectCache >();
|
||||
auto pop = pInstanceObjectCache->getPopRange( data->territory, data->level[ 0 ] );
|
||||
|
||||
Common::FFXIVARR_POSITION3 pos;
|
||||
pos.x = 0;
|
||||
|
@ -359,10 +363,18 @@ void Sapphire::Entity::Player::teleport( uint16_t aetheryteId, uint8_t type )
|
|||
pos.z = 0;
|
||||
float rot = 0;
|
||||
|
||||
if( targetPos != nullptr )
|
||||
if( pop )
|
||||
{
|
||||
pos = targetPos->getTargetPosition();
|
||||
rot = targetPos->getTargetRotation();
|
||||
sendDebug( "Teleport: popRange {0} found!", data->level.at( 0 ) );
|
||||
|
||||
pos.x = pop->header.transform.translation.x;
|
||||
pos.y = pop->header.transform.translation.y;
|
||||
pos.z = pop->header.transform.translation.z;
|
||||
rot = pop->header.transform.rotation.y;
|
||||
}
|
||||
else
|
||||
{
|
||||
sendDebug( "Teleport: popRange {0} not found in {1}!", data->level[ 0 ], data->territory );
|
||||
}
|
||||
|
||||
sendDebug( "Teleport: {0} {1} ({2})",
|
||||
|
|
|
@ -678,7 +678,9 @@ Sapphire::Entity::Player::moveItem( uint16_t fromInventoryId, uint8_t fromSlotId
|
|||
if( static_cast< InventoryType >( fromInventoryId ) == GearSet0 )
|
||||
unequipItem( static_cast< GearSetSlot >( fromSlotId ), tmpItem, true );
|
||||
|
||||
|
||||
if( static_cast< InventoryType >( toInventoryId ) == GearSet0 ||
|
||||
static_cast< InventoryType >( fromInventoryId ) == GearSet0 )
|
||||
sendStatusEffectUpdate(); // send if any equip is changed
|
||||
}
|
||||
|
||||
bool Sapphire::Entity::Player::updateContainer( uint16_t storageId, uint8_t slotId, ItemPtr pItem )
|
||||
|
@ -813,6 +815,10 @@ void Sapphire::Entity::Player::swapItem( uint16_t fromInventoryId, uint8_t fromS
|
|||
|
||||
updateContainer( toInventoryId, toSlot, fromItem );
|
||||
updateContainer( fromInventoryId, fromSlotId, toItem );
|
||||
|
||||
if( static_cast< InventoryType >( toInventoryId ) == GearSet0 ||
|
||||
static_cast< InventoryType >( fromInventoryId ) == GearSet0 )
|
||||
sendStatusEffectUpdate(); // send if any equip is changed
|
||||
}
|
||||
|
||||
void Sapphire::Entity::Player::discardItem( uint16_t fromInventoryId, uint8_t fromSlotId )
|
||||
|
|
|
@ -217,6 +217,10 @@ bool Sapphire::Entity::Player::load( uint32_t charId, World::SessionPtr pSession
|
|||
m_modelSubWeapon = 0;
|
||||
m_lastTickTime = 0;
|
||||
|
||||
//m_pInventory->load();
|
||||
|
||||
initInventory(); // moved up so we don't lose hp every login
|
||||
|
||||
calculateStats();
|
||||
|
||||
// first login, run the script event
|
||||
|
@ -242,10 +246,6 @@ bool Sapphire::Entity::Player::load( uint32_t charId, World::SessionPtr pSession
|
|||
|
||||
setStateFlag( PlayerStateFlag::BetweenAreas );
|
||||
|
||||
//m_pInventory->load();
|
||||
|
||||
initInventory();
|
||||
|
||||
initHateSlotQueue();
|
||||
|
||||
initSpawnIdQueue();
|
||||
|
|
|
@ -209,31 +209,10 @@ void Sapphire::World::Manager::DebugCommandMgr::set( char* data, Entity::Player&
|
|||
sscanf( params.c_str(), "%i %i", &map_id, &discover_id );
|
||||
|
||||
auto discoveryPacket = makeZonePacket< FFXIVIpcDiscovery >( player.getId() );
|
||||
discoveryPacket->data().map_id = static_cast< uint32_t >( map_id );
|
||||
discoveryPacket->data().map_part_id = static_cast< uint32_t >( discover_id );
|
||||
discoveryPacket->data().mapId = static_cast< uint32_t >( map_id );
|
||||
discoveryPacket->data().mapPartId = static_cast< uint32_t >( discover_id );
|
||||
player.queuePacket( discoveryPacket );
|
||||
}
|
||||
|
||||
else if( ( subCommand == "discovery_pos" ) && ( params != "" ) )
|
||||
{
|
||||
int32_t map_id;
|
||||
int32_t discover_id;
|
||||
int32_t pos_id;
|
||||
sscanf( params.c_str(), "%i %i %i", &pos_id, &map_id, &discover_id );
|
||||
|
||||
std::string query2 = "UPDATE IGNORE `discoveryinfo` SET `discover_id` = '" + std::to_string( discover_id ) +
|
||||
"' WHERE `discoveryinfo`.`id` = " + std::to_string( pos_id ) + ";";
|
||||
|
||||
std::string query1 =
|
||||
"INSERT IGNORE INTO `discoveryinfo` (`id`, `map_id`, `discover_id`) VALUES ('" + std::to_string( pos_id ) +
|
||||
"', '" + std::to_string( map_id ) +
|
||||
"', '" + std::to_string( discover_id ) + "')";
|
||||
|
||||
pDb->execute( query1 );
|
||||
pDb->execute( query2 );
|
||||
|
||||
}
|
||||
|
||||
else if( subCommand == "discovery_reset" )
|
||||
{
|
||||
player.resetDiscovery();
|
||||
|
|
|
@ -19,55 +19,55 @@ const int levelTable[81][6] =
|
|||
{
|
||||
// MAIN,SUB,DIV,HP,ELMT,THREAT
|
||||
{ 1, 1, 1, 1, 1, 1 },
|
||||
{ 20, 56, 56, 0, 52, 2 },
|
||||
{ 21, 57, 57, 0, 54, 2 },
|
||||
{ 22, 60, 60, 0, 56, 3 },
|
||||
{ 24, 62, 62, 0, 58, 3 },
|
||||
{ 26, 65, 65, 0, 60, 3 },
|
||||
{ 27, 68, 68, 0, 62, 3 },
|
||||
{ 29, 70, 70, 0, 64, 4 },
|
||||
{ 31, 73, 73, 0, 66, 4 },
|
||||
{ 33, 76, 76, 0, 68, 4 },
|
||||
{ 35, 78, 78, 0, 70, 5 },
|
||||
{ 36, 82, 82, 0, 73, 5 },
|
||||
{ 38, 85, 85, 0, 75, 5 },
|
||||
{ 41, 89, 89, 0, 78, 6 },
|
||||
{ 44, 93, 93, 0, 81, 6 },
|
||||
{ 46, 96, 96, 0, 84, 7 },
|
||||
{ 49, 100, 100, 0, 86, 7 },
|
||||
{ 52, 104, 104, 0, 89, 8 },
|
||||
{ 54, 109, 109, 0, 93, 9 },
|
||||
{ 57, 113, 113, 0, 95, 9 },
|
||||
{ 60, 116, 116, 0, 98, 10 },
|
||||
{ 63, 122, 122, 0, 102, 10 },
|
||||
{ 67, 127, 127, 0, 105, 11 },
|
||||
{ 71, 133, 133, 0, 109, 12 },
|
||||
{ 74, 138, 138, 0, 113, 13 },
|
||||
{ 78, 144, 144, 0, 117, 14 },
|
||||
{ 81, 150, 150, 0, 121, 15 },
|
||||
{ 85, 155, 155, 0, 125, 16 },
|
||||
{ 89, 162, 162, 0, 129, 17 },
|
||||
{ 92, 168, 168, 0, 133, 18 },
|
||||
{ 97, 173, 173, 0, 137, 19 },
|
||||
{ 101, 181, 181, 0, 143, 20 },
|
||||
{ 106, 188, 188, 0, 148, 22 },
|
||||
{ 110, 194, 194, 0, 153, 23 },
|
||||
{ 115, 202, 202, 0, 159, 25 },
|
||||
{ 119, 209, 209, 0, 165, 27 },
|
||||
{ 124, 215, 215, 0, 170, 29 },
|
||||
{ 128, 223, 223, 0, 176, 31 },
|
||||
{ 134, 229, 229, 0, 181, 33 },
|
||||
{ 139, 236, 236, 0, 186, 35 },
|
||||
{ 144, 244, 244, 0, 192, 38 },
|
||||
{ 150, 253, 253, 0, 200, 40 },
|
||||
{ 155, 263, 263, 0, 207, 43 },
|
||||
{ 161, 272, 272, 0, 215, 46 },
|
||||
{ 166, 283, 283, 0, 223, 49 },
|
||||
{ 171, 292, 292, 0, 231, 52 },
|
||||
{ 177, 302, 302, 0, 238, 55 },
|
||||
{ 183, 311, 311, 0, 246, 58 },
|
||||
{ 189, 322, 322, 0, 254, 62 },
|
||||
{ 196, 331, 331, 0, 261, 66 },
|
||||
{ 20, 56, 56, 86, 52, 2 },
|
||||
{ 21, 57, 57, 101, 54, 2 },
|
||||
{ 22, 60, 60, 109, 56, 3 },
|
||||
{ 24, 62, 62, 116, 58, 3 },
|
||||
{ 26, 65, 65, 123, 60, 3 },
|
||||
{ 27, 68, 68, 131, 62, 3 },
|
||||
{ 29, 70, 70, 138, 64, 4 },
|
||||
{ 31, 73, 73, 145, 66, 4 },
|
||||
{ 33, 76, 76, 153, 68, 4 },
|
||||
{ 35, 78, 78, 160, 70, 5 },
|
||||
{ 36, 82, 82, 174, 73, 5 },
|
||||
{ 38, 85, 85, 188, 75, 5 },
|
||||
{ 41, 89, 89, 202, 78, 6 },
|
||||
{ 44, 93, 93, 216, 81, 6 },
|
||||
{ 46, 96, 96, 230, 84, 7 },
|
||||
{ 49, 100, 100, 244, 86, 7 },
|
||||
{ 52, 104, 104, 258, 89, 8 },
|
||||
{ 54, 109, 109, 272, 93, 9 },
|
||||
{ 57, 113, 113, 286, 95, 9 },
|
||||
{ 60, 116, 116, 300, 98, 10 },
|
||||
{ 63, 122, 122, 333, 102, 10 },
|
||||
{ 67, 127, 127, 366, 105, 11 },
|
||||
{ 71, 133, 133, 399, 109, 12 },
|
||||
{ 74, 138, 138, 432, 113, 13 },
|
||||
{ 78, 144, 144, 465, 117, 14 },
|
||||
{ 81, 150, 150, 498, 121, 15 },
|
||||
{ 85, 155, 155, 531, 125, 16 },
|
||||
{ 89, 162, 162, 564, 129, 17 },
|
||||
{ 92, 168, 168, 597, 133, 18 },
|
||||
{ 97, 173, 173, 630, 137, 19 },
|
||||
{ 101, 181, 181, 669, 143, 20 },
|
||||
{ 106, 188, 188, 708, 148, 22 },
|
||||
{ 110, 194, 194, 747, 153, 23 },
|
||||
{ 115, 202, 202, 786, 159, 25 },
|
||||
{ 119, 209, 209, 825, 165, 27 },
|
||||
{ 124, 215, 215, 864, 170, 29 },
|
||||
{ 128, 223, 223, 903, 176, 31 },
|
||||
{ 134, 229, 229, 942, 181, 33 },
|
||||
{ 139, 236, 236, 981, 186, 35 },
|
||||
{ 144, 244, 244, 1020, 192, 38 },
|
||||
{ 150, 253, 253, 1088, 200, 40 },
|
||||
{ 155, 263, 263, 1156, 207, 43 },
|
||||
{ 161, 272, 272, 1224, 215, 46 },
|
||||
{ 166, 283, 283, 1292, 223, 49 },
|
||||
{ 171, 292, 292, 1360, 231, 52 },
|
||||
{ 177, 302, 302, 1428, 238, 55 },
|
||||
{ 183, 311, 311, 1496, 246, 58 },
|
||||
{ 189, 322, 322, 1564, 254, 62 },
|
||||
{ 196, 331, 331, 1632, 261, 66 },
|
||||
{ 202, 341, 341, 1700, 269, 70 },
|
||||
{ 204, 342, 393, 1774, 270, 84 },
|
||||
{ 205, 344, 444, 1851, 271, 99 },
|
||||
|
@ -92,7 +92,7 @@ const int levelTable[81][6] =
|
|||
|
||||
// todo: add proper shbr values - hp/elmt/threat
|
||||
// sub/div added from http://theoryjerks.akhmorning.com/resources/levelmods/
|
||||
{ 296, 365, 2263, 3600, 466, 466 },
|
||||
{ 296, 365, 2263, 3600, 295, 466 },
|
||||
{ 300, 366, 2360, 3600, 295, 466 },
|
||||
{ 305, 367, 2461, 3600, 295, 466 },
|
||||
{ 310, 368, 2566, 3600, 295, 466 },
|
||||
|
@ -131,7 +131,7 @@ float CalcStats::calculateBaseStat( const Chara& chara )
|
|||
if( level > Common::MAX_PLAYER_LEVEL )
|
||||
level = Common::MAX_PLAYER_LEVEL;
|
||||
|
||||
return static_cast< float >( levelTable[level][2] );
|
||||
return static_cast< float >( levelTable[ level ][ Common::LevelTableEntry::MAIN ] );
|
||||
}
|
||||
|
||||
// Leggerless' HP Formula
|
||||
|
@ -160,13 +160,16 @@ uint32_t CalcStats::calculateMaxHp( PlayerPtr pPlayer, Sapphire::FrameworkPtr pF
|
|||
float approxBaseHp = 0.0f; // Read above
|
||||
|
||||
// These values are not precise.
|
||||
|
||||
/*
|
||||
if( level >= 60 )
|
||||
approxBaseHp = static_cast< float >( 2600 + ( level - 60 ) * 100 );
|
||||
else if( level >= 50 )
|
||||
approxBaseHp = 1700 + ( ( level - 50 ) * ( 1700 * 1.04325f ) );
|
||||
else
|
||||
approxBaseHp = paramGrowthInfo->mpModifier * 0.7667f;
|
||||
*/
|
||||
// just use the table at least better than what it was
|
||||
approxBaseHp = static_cast< float >( levelTable[ level ][ Common::LevelTableEntry::HP ] );
|
||||
|
||||
uint16_t result = static_cast< uint16_t >( floor( jobModHp * ( approxBaseHp / 100.0f ) ) +
|
||||
floor( hpMod / 100.0f * ( vitStat - baseStat ) ) );
|
||||
|
|
|
@ -9,6 +9,9 @@
|
|||
#include <Database/DatabaseDef.h>
|
||||
#include <Util/Util.h>
|
||||
|
||||
#include <datReader/DatCategories/bg/LgbTypes.h>
|
||||
#include <datReader/DatCategories/bg/Lgb.h>
|
||||
|
||||
#include <unordered_map>
|
||||
#include <Network/PacketDef/Zone/ClientZoneDef.h>
|
||||
#include <Logging/Logger.h>
|
||||
|
@ -20,6 +23,7 @@
|
|||
#include "Territory/Land.h"
|
||||
#include "Territory/ZonePosition.h"
|
||||
#include "Territory/House.h"
|
||||
#include "Territory/InstanceObjectCache.h"
|
||||
|
||||
#include "Network/PacketWrappers/PlayerSetupPacket.h"
|
||||
#include "Network/PacketWrappers/PingPacket.h"
|
||||
|
@ -274,45 +278,44 @@ void Sapphire::Network::GameConnection::zoneLineHandler( FrameworkPtr pFw,
|
|||
const Packets::FFXIVARR_PACKET_RAW& inPacket,
|
||||
Entity::Player& player )
|
||||
{
|
||||
auto pTeriMgr = pFw->get< TerritoryMgr >();
|
||||
|
||||
const auto packet = ZoneChannelPacket< Client::FFXIVIpcZoneLineHandler >( inPacket );
|
||||
const auto zoneLineId = packet.data().zoneLineId;
|
||||
|
||||
player.sendDebug( "Walking ZoneLine#{0}", zoneLineId );
|
||||
auto pTeriMgr = pFw->get< TerritoryMgr >();
|
||||
auto pInstanceObjectCache = pFw->get< InstanceObjectCache >();
|
||||
auto tInfo = player.getCurrentTerritory()->getTerritoryTypeInfo();
|
||||
|
||||
auto pZone = player.getCurrentTerritory();
|
||||
|
||||
auto pLine = pTeriMgr->getTerritoryPosition( zoneLineId );
|
||||
auto pExitRange = pInstanceObjectCache->getExitRange( player.getTerritoryTypeId(), zoneLineId );
|
||||
|
||||
Common::FFXIVARR_POSITION3 targetPos{};
|
||||
uint32_t targetZone;
|
||||
float rotation = 0.0f;
|
||||
|
||||
if( pLine != nullptr )
|
||||
if( pExitRange )
|
||||
{
|
||||
player.sendDebug( "ZoneLine #{0} found.", zoneLineId );
|
||||
targetPos = pLine->getTargetPosition();
|
||||
targetZone = pLine->getTargetZoneId();
|
||||
rotation = pLine->getTargetRotation();
|
||||
auto pPopRange = pInstanceObjectCache->getPopRange( pExitRange->data.destTerritoryType,
|
||||
pExitRange->data.destInstanceObjectId );
|
||||
if( pPopRange )
|
||||
{
|
||||
targetZone = pExitRange->data.destTerritoryType;
|
||||
rotation = pPopRange->header.transform.rotation.y;
|
||||
targetPos = Common::FFXIVARR_POSITION3 { pPopRange->header.transform.translation.x,
|
||||
pPopRange->header.transform.translation.y,
|
||||
pPopRange->header.transform.translation.z };
|
||||
|
||||
auto preparePacket = makeZonePacket< FFXIVIpcPrepareZoning >( player.getId() );
|
||||
preparePacket->data().targetZone = targetZone;
|
||||
player.sendDebug( "ZoneLine #{0} found.", zoneLineId );
|
||||
|
||||
//ActorControlSelfPacket controlPacket( pPlayer, ActorControlType::DespawnZoneScreenMsg,
|
||||
// 0x03, player.getId(), 0x01, targetZone );
|
||||
player.queuePacket( preparePacket );
|
||||
}
|
||||
else
|
||||
{
|
||||
// No zoneline found, revert to last zone
|
||||
player.sendUrgent( "ZoneLine {0} not found.", zoneLineId );
|
||||
targetPos.x = 0;
|
||||
targetPos.y = 0;
|
||||
targetPos.z = 0;
|
||||
targetZone = pZone->getTerritoryTypeId();
|
||||
auto preparePacket = makeZonePacket< FFXIVIpcPrepareZoning >( player.getId() );
|
||||
preparePacket->data().targetZone = pExitRange->data.destTerritoryType;
|
||||
|
||||
player.queuePacket( preparePacket );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
player.sendDebug( "Walking ZoneLine#{0}", zoneLineId );
|
||||
|
||||
player.performZoning( targetZone, targetPos, rotation );
|
||||
}
|
||||
|
||||
|
@ -321,29 +324,23 @@ void Sapphire::Network::GameConnection::discoveryHandler( FrameworkPtr pFw,
|
|||
const Packets::FFXIVARR_PACKET_RAW& inPacket,
|
||||
Entity::Player& player )
|
||||
{
|
||||
auto pInstanceObjectCache = pFw->get< InstanceObjectCache >();
|
||||
auto tInfo = player.getCurrentTerritory()->getTerritoryTypeInfo();
|
||||
const auto packet = ZoneChannelPacket< Client::FFXIVIpcDiscoveryHandler >( inPacket );
|
||||
const auto positionRef = packet.data().positionRef;
|
||||
|
||||
auto pDb = pFw->get< Db::DbWorkerPool< Db::ZoneDbConnection > >();
|
||||
auto pRefInfo = pInstanceObjectCache->getMapRange( player.getTerritoryTypeId(), positionRef );
|
||||
|
||||
auto pQR = pDb->query( "SELECT id, map_id, discover_id "
|
||||
"FROM discoveryinfo "
|
||||
"WHERE id = " + std::to_string( positionRef ) + ";" );
|
||||
|
||||
if( !pQR->next() )
|
||||
{
|
||||
player.sendDebug( "Discovery ref pos id#{0} not found!", positionRef );
|
||||
return;
|
||||
}
|
||||
|
||||
auto discoveryPacket = makeZonePacket< FFXIVIpcDiscovery >( player.getId() );
|
||||
discoveryPacket->data().map_id = pQR->getUInt( 2 );
|
||||
discoveryPacket->data().map_part_id = pQR->getUInt( 3 );
|
||||
|
||||
player.queuePacket( discoveryPacket );
|
||||
player.sendDebug( "Discovery ref pos id#{0}", positionRef );
|
||||
|
||||
player.discover( pQR->getUInt16( 2 ), pQR->getUInt16( 3 ) );
|
||||
if( pRefInfo )
|
||||
{
|
||||
auto discoveryPacket = makeZonePacket< FFXIVIpcDiscovery >( player.getId() );
|
||||
discoveryPacket->data().mapId = tInfo->map;
|
||||
discoveryPacket->data().mapPartId = pRefInfo->data.discoveryIndex;
|
||||
player.queuePacket( discoveryPacket );
|
||||
player.discover( tInfo->map, pRefInfo->data.discoveryIndex );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -44,6 +44,8 @@
|
|||
#include "Manager/NaviMgr.h"
|
||||
#include "Manager/ActionMgr.h"
|
||||
|
||||
#include "Territory/InstanceObjectCache.h"
|
||||
|
||||
using namespace Sapphire::World::Manager;
|
||||
|
||||
Sapphire::World::ServerMgr::ServerMgr( const std::string& configName, FrameworkPtr pFw ) :
|
||||
|
@ -171,6 +173,10 @@ void Sapphire::World::ServerMgr::run( int32_t argc, char* argv[] )
|
|||
}
|
||||
framework()->set< Scripting::ScriptMgr >( pScript );
|
||||
|
||||
Logger::info( "Setting up InstanceObjectCache" );
|
||||
auto pInstanceObjCache = std::make_shared< Sapphire::InstanceObjectCache >( framework() );
|
||||
framework()->set< Sapphire::InstanceObjectCache >( pInstanceObjCache );
|
||||
|
||||
auto pActionMgr = std::make_shared< Manager::ActionMgr >( framework() );
|
||||
framework()->set< Manager::ActionMgr >( pActionMgr );
|
||||
|
||||
|
|
125
src/world/Territory/InstanceObjectCache.cpp
Normal file
125
src/world/Territory/InstanceObjectCache.cpp
Normal file
|
@ -0,0 +1,125 @@
|
|||
#include "InstanceObjectCache.h"
|
||||
#include "Exd/ExdDataGenerated.h"
|
||||
#include <Framework.h>
|
||||
|
||||
#include <datReader/DatCategories/bg/pcb.h>
|
||||
#include <datReader/DatCategories/bg/lgb.h>
|
||||
#include <datReader/DatCategories/bg/sgb.h>
|
||||
#include <GameData.h>
|
||||
#include <File.h>
|
||||
#include <DatCat.h>
|
||||
#include <ExdData.h>
|
||||
#include <ExdCat.h>
|
||||
#include <Exd.h>
|
||||
|
||||
#include <Logging/Logger.h>
|
||||
|
||||
Sapphire::InstanceObjectCache::InstanceObjectCache( std::shared_ptr< Framework > pFramework ) :
|
||||
m_pFramework( pFramework )
|
||||
{
|
||||
|
||||
auto pExd = pFramework->get< Sapphire::Data::ExdDataGenerated >();
|
||||
auto idList = pExd->getTerritoryTypeIdList();
|
||||
|
||||
size_t count = 0;
|
||||
for( const auto& id : idList )
|
||||
{
|
||||
// show some loading indication...
|
||||
if( count++ % 10 == 0 )
|
||||
std::cout << ".";
|
||||
|
||||
auto territoryType = pExd->get< Sapphire::Data::TerritoryType >( id );
|
||||
if( !territoryType )
|
||||
continue;
|
||||
|
||||
auto path = territoryType->bg;
|
||||
|
||||
if( path.empty() )
|
||||
continue;
|
||||
|
||||
path = std::string( "bg/" ) + path.substr( 0, path.find( "/level/" ) );
|
||||
|
||||
// TODO: it does feel like this needs to be streamlined into the datReader instead of being done here...
|
||||
std::string bgLgbPath( path + "/level/bg.lgb" );
|
||||
std::string planmapLgbPath( path + "/level/planmap.lgb" );
|
||||
std::vector< char > bgSection;
|
||||
std::vector< char > planmapSection;
|
||||
|
||||
std::unique_ptr< xiv::dat::File > bgFile;
|
||||
std::unique_ptr< xiv::dat::File > planmap_file;
|
||||
|
||||
try
|
||||
{
|
||||
bgFile = pExd->getGameData()->getFile( bgLgbPath );
|
||||
planmap_file = pExd->getGameData()->getFile( planmapLgbPath );
|
||||
}
|
||||
catch( std::runtime_error& )
|
||||
{
|
||||
// ignore files that aren't found
|
||||
continue;
|
||||
}
|
||||
|
||||
bgSection = bgFile->access_data_sections().at( 0 );
|
||||
planmapSection = planmap_file->access_data_sections().at( 0 );
|
||||
|
||||
std::vector< std::string > stringList;
|
||||
|
||||
uint32_t offset1 = 0x20;
|
||||
|
||||
LGB_FILE bgLgb( &bgSection[ 0 ], "bg" );
|
||||
LGB_FILE planmapLgb( &planmapSection[ 0 ], "planmap" );
|
||||
|
||||
std::vector< LGB_FILE > lgbList{ bgLgb, planmapLgb };
|
||||
uint32_t max_index = 0;
|
||||
|
||||
for( const auto& lgb : lgbList )
|
||||
{
|
||||
for( const auto& group : lgb.groups )
|
||||
{
|
||||
for( const auto& pEntry : group.entries )
|
||||
{
|
||||
if( pEntry->getType() == LgbEntryType::MapRange )
|
||||
{
|
||||
auto pMapRange = reinterpret_cast< LGB_MAP_RANGE_ENTRY* >( pEntry.get() );
|
||||
m_mapRangeCache.insert( id, *pMapRange );
|
||||
}
|
||||
else if( pEntry->getType() == LgbEntryType::ExitRange )
|
||||
{
|
||||
auto pExitRange = reinterpret_cast< LGB_EXIT_RANGE_ENTRY* >( pEntry.get() );
|
||||
m_exitRangeCache.insert( id, *pExitRange);
|
||||
}
|
||||
else if( pEntry->getType() == LgbEntryType::PopRange )
|
||||
{
|
||||
auto pPopRange = reinterpret_cast< LGB_POP_RANGE_ENTRY* >( pEntry.get() );
|
||||
m_popRangeCache.insert( id, *pPopRange );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
std::cout << "\n";
|
||||
|
||||
Logger::debug(
|
||||
"InstanceObjectCache Cached: MapRange: {} ExitRange: {} PopRange: {}",
|
||||
m_mapRangeCache.size(), m_exitRangeCache.size(), m_popRangeCache.size()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Sapphire::InstanceObjectCache::MapRangePtr
|
||||
Sapphire::InstanceObjectCache::getMapRange( uint16_t zoneId, uint32_t mapRangeId )
|
||||
{
|
||||
return m_mapRangeCache.get( zoneId, mapRangeId );
|
||||
}
|
||||
|
||||
Sapphire::InstanceObjectCache::ExitRangePtr
|
||||
Sapphire::InstanceObjectCache::getExitRange( uint16_t zoneId, uint32_t exitRangeId )
|
||||
{
|
||||
return m_exitRangeCache.get( zoneId, exitRangeId );
|
||||
}
|
||||
|
||||
Sapphire::InstanceObjectCache::PopRangePtr
|
||||
Sapphire::InstanceObjectCache::getPopRange( uint16_t zoneId, uint32_t popRangeId )
|
||||
{
|
||||
return m_popRangeCache.get( zoneId, popRangeId );
|
||||
}
|
88
src/world/Territory/InstanceObjectCache.h
Normal file
88
src/world/Territory/InstanceObjectCache.h
Normal file
|
@ -0,0 +1,88 @@
|
|||
#ifndef SAPPHIRE_INSTANCEOBJECTCACHE_H
|
||||
#define SAPPHIRE_INSTANCEOBJECTCACHE_H
|
||||
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
|
||||
struct LGB_MAP_RANGE_ENTRY;
|
||||
struct LGB_EXIT_RANGE_ENTRY;
|
||||
struct LGB_POP_RANGE_ENTRY;
|
||||
|
||||
|
||||
namespace Sapphire
|
||||
{
|
||||
class Framework;
|
||||
|
||||
template< typename T >
|
||||
class ObjectCache
|
||||
{
|
||||
|
||||
using ObjectPtr = std::shared_ptr< T >;
|
||||
using ObjectMap = std::unordered_map< uint32_t, ObjectPtr >;
|
||||
using ZoneObjectCache = std::unordered_map< uint16_t, ObjectMap >;
|
||||
|
||||
ZoneObjectCache m_objectCache;
|
||||
|
||||
public:
|
||||
ObjectPtr get( uint16_t zoneId, uint32_t id )
|
||||
{
|
||||
auto it = m_objectCache.find( zoneId );
|
||||
if( it != m_objectCache.end() )
|
||||
{
|
||||
auto rangeIt = it->second.find( id );
|
||||
if( rangeIt != it->second.end() )
|
||||
{
|
||||
return rangeIt->second;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void insert( uint16_t zoneId, T& entry )
|
||||
{
|
||||
auto pShared = std::make_shared< T >( entry );
|
||||
if( m_objectCache.find( zoneId ) == m_objectCache.end() )
|
||||
{
|
||||
ObjectMap cache;
|
||||
cache[ entry.header.instanceId ] = pShared;
|
||||
m_objectCache[ zoneId ] = cache;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto it = m_objectCache.find( zoneId );
|
||||
it->second[ entry.header.instanceId ] = pShared;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t size() const
|
||||
{
|
||||
return m_objectCache.size();
|
||||
}
|
||||
};
|
||||
|
||||
class InstanceObjectCache
|
||||
{
|
||||
public:
|
||||
using MapRangePtr = std::shared_ptr< LGB_MAP_RANGE_ENTRY >;
|
||||
using ExitRangePtr = std::shared_ptr< LGB_EXIT_RANGE_ENTRY >;
|
||||
using PopRangePtr = std::shared_ptr< LGB_POP_RANGE_ENTRY >;
|
||||
|
||||
InstanceObjectCache( std::shared_ptr< Framework > pFramework );
|
||||
~InstanceObjectCache() = default;
|
||||
|
||||
MapRangePtr getMapRange( uint16_t zoneId, uint32_t mapRangeId );
|
||||
ExitRangePtr getExitRange( uint16_t zoneId, uint32_t exitRangeId );
|
||||
PopRangePtr getPopRange( uint16_t zoneId, uint32_t popRangeId );
|
||||
|
||||
private:
|
||||
ObjectCache< LGB_MAP_RANGE_ENTRY > m_mapRangeCache;
|
||||
ObjectCache< LGB_EXIT_RANGE_ENTRY > m_exitRangeCache;
|
||||
ObjectCache< LGB_POP_RANGE_ENTRY > m_popRangeCache;
|
||||
std::shared_ptr< Framework > m_pFramework;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif //SAPPHIRE_INSTANCEOBJECTCACHE_H
|
Loading…
Add table
Reference in a new issue