mirror of
https://github.com/SapphireServer/Sapphire.git
synced 2025-04-26 14:37:44 +00:00
Major rewrite of zonelines, aetherytes and discoveries
This commit is contained in:
parent
eb75b35e7d
commit
b17af41e67
21 changed files with 738 additions and 4899 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 : 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
|
243
deps/datReader/DatCategories/bg/lgb.h
vendored
243
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 header;
|
||||
std::string name;
|
||||
std::string modelFileName;
|
||||
std::string collisionFileName;
|
||||
|
@ -132,124 +64,95 @@ 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 );
|
||||
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
|
||||
{
|
||||
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 header;
|
||||
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 );
|
||||
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
|
||||
{
|
||||
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 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 );
|
||||
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";
|
||||
header = *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 header;
|
||||
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 );
|
||||
header = *reinterpret_cast< EObjData* >( buf + offset );
|
||||
name = std::string( buf + offset + header.nameOffset );
|
||||
};
|
||||
};
|
||||
|
||||
struct LGB_MAP_RANGE_ENTRY : public LgbEntry
|
||||
{
|
||||
public:
|
||||
MapRangeData header;
|
||||
std::string name;
|
||||
|
||||
LGB_MAP_RANGE_ENTRY( char* buf, uint32_t offset ) : LgbEntry( buf, offset )
|
||||
{
|
||||
header = *reinterpret_cast< MapRangeData* >( buf + offset );
|
||||
name = std::string( buf + offset + header.nameOffset );
|
||||
};
|
||||
};
|
||||
|
||||
struct LGB_EXIT_RANGE_ENTRY : public LgbEntry
|
||||
{
|
||||
public:
|
||||
ExitRangeData header;
|
||||
std::string name;
|
||||
|
||||
LGB_EXIT_RANGE_ENTRY( char* buf, uint32_t offset ) : LgbEntry( buf, offset )
|
||||
{
|
||||
header = *reinterpret_cast< ExitRangeData* >( buf + offset );
|
||||
name = std::string( buf + offset + header.nameOffset );
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
struct LGB_POP_RANGE_ENTRY : public LgbEntry
|
||||
{
|
||||
public:
|
||||
PopRangeData header;
|
||||
|
||||
LGB_POP_RANGE_ENTRY( char* buf, uint32_t offset ) : LgbEntry( buf, offset )
|
||||
{
|
||||
header = *reinterpret_cast< PopRangeData* >( buf + offset );
|
||||
};
|
||||
};
|
||||
|
||||
struct LGB_GROUP_HEADER
|
||||
{
|
||||
uint32_t id;
|
||||
|
@ -272,15 +175,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 +189,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 +206,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 +246,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 +257,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,
|
||||
|
|
|
@ -5594,6 +5594,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 )
|
||||
{
|
||||
|
|
|
@ -1550,11 +1550,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
|
||||
*/
|
||||
|
|
|
@ -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->header.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;
|
||||
|
||||
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->header.mapId ) + " " +
|
||||
std::to_string( pMapRange->header.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 )
|
||||
|
|
|
@ -285,7 +285,7 @@ int main( int argc, char* argv[] )
|
|||
|
||||
auto pEobj = reinterpret_cast< LGB_EOBJ_ENTRY* >( pObj );
|
||||
id = pEobj->header.eobjId;
|
||||
unknown = pEobj->header.unknown;
|
||||
unknown = pEobj->header.instanceId;
|
||||
|
||||
eobjlevelHierachyId = pEobj->header.levelHierachyId;
|
||||
|
||||
|
@ -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->header.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 ) )
|
||||
{
|
||||
|
|
|
@ -19,8 +19,10 @@
|
|||
#include "Territory/Territory.h"
|
||||
#include "Territory/ZonePosition.h"
|
||||
#include "Territory/InstanceContent.h"
|
||||
#include "Territory/InstanceObjectCache.h"
|
||||
#include "Territory/Land.h"
|
||||
|
||||
|
||||
#include "Network/GameConnection.h"
|
||||
#include "Network/PacketWrappers/ActorControlPacket.h"
|
||||
#include "Network/PacketWrappers/ActorControlSelfPacket.h"
|
||||
|
@ -350,8 +352,27 @@ void Sapphire::Entity::Player::teleport( uint16_t aetheryteId, uint8_t type )
|
|||
}
|
||||
|
||||
setStateFlag( PlayerStateFlag::BetweenAreas );
|
||||
|
||||
auto pInstanceObjectCache = m_pFw->get< InstanceObjectCache >();
|
||||
|
||||
auto targetPos = pTeriMgr->getTerritoryPosition( data->level.at( 0 ) );
|
||||
|
||||
auto pop = pInstanceObjectCache->getPopRange( data->territory, data->level[ 0 ] );
|
||||
auto pop1 = pInstanceObjectCache->getPopRange( data->territory, data->level[ 1 ] );
|
||||
|
||||
if( pop )
|
||||
{
|
||||
sendDebug( "Teleport: popRange {0} found!", data->level.at( 0 ) );
|
||||
}
|
||||
else if( pop1 )
|
||||
{
|
||||
sendDebug( "Teleport: popRange {0} found!", data->level.at( 1 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
sendDebug( "Teleport: popRange not found!" );
|
||||
}
|
||||
|
||||
Common::FFXIVARR_POSITION3 pos;
|
||||
pos.x = 0;
|
||||
pos.y = 0;
|
||||
|
|
|
@ -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 = map_id;
|
||||
discoveryPacket->data().map_part_id = discover_id;
|
||||
discoveryPacket->data().mapId = map_id;
|
||||
discoveryPacket->data().mapPartId = 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();
|
||||
|
|
|
@ -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,22 +278,56 @@ 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;
|
||||
|
||||
auto pTeriMgr = pFw->get< TerritoryMgr >();
|
||||
auto pInstanceObjectCache = pFw->get< InstanceObjectCache >();
|
||||
auto tInfo = player.getCurrentTerritory()->getTerritoryTypeInfo();
|
||||
|
||||
auto pExitRange = pInstanceObjectCache->getExitRange( player.getTerritoryTypeId(), zoneLineId );
|
||||
|
||||
Common::FFXIVARR_POSITION3 targetPos{};
|
||||
uint32_t targetZone;
|
||||
if( pExitRange )
|
||||
{
|
||||
player.sendDebug( "Found ExitRange#{0}", zoneLineId );
|
||||
player.sendDebug( "destTerritoryType#{0}", pExitRange->header.destTerritoryType );
|
||||
player.sendDebug( "destInstanceObjectId#{0}", pExitRange->header.destInstanceObjectId );
|
||||
|
||||
auto pPopRange = pInstanceObjectCache->getPopRange( pExitRange->header.destTerritoryType,
|
||||
pExitRange->header.destInstanceObjectId );
|
||||
if( pPopRange )
|
||||
{
|
||||
targetZone = pExitRange->header.destTerritoryType;
|
||||
player.sendDebug( "\tFound PopRange#{0}", pExitRange->header.destInstanceObjectId );
|
||||
player.sendDebug( "\t{0}", pPopRange->header.transform.translation.x );
|
||||
player.sendDebug( "\t{0}", pPopRange->header.transform.translation.y );
|
||||
player.sendDebug( "\t{0}", pPopRange->header.transform.translation.z );
|
||||
targetPos = Common::FFXIVARR_POSITION3 { pPopRange->header.transform.translation.x,
|
||||
pPopRange->header.transform.translation.y,
|
||||
pPopRange->header.transform.translation.z };
|
||||
|
||||
player.sendDebug( "ZoneLine #{0} found.", zoneLineId );
|
||||
|
||||
auto preparePacket = makeZonePacket< FFXIVIpcPrepareZoning >( player.getId() );
|
||||
preparePacket->data().targetZone = pExitRange->header.destTerritoryType;
|
||||
|
||||
//ActorControlSelfPacket controlPacket( pPlayer, ActorControlType::DespawnZoneScreenMsg,
|
||||
// 0x03, player.getId(), 0x01, targetZone );
|
||||
player.queuePacket( preparePacket );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
player.sendDebug( "Walking ZoneLine#{0}", zoneLineId );
|
||||
|
||||
auto pZone = player.getCurrentTerritory();
|
||||
|
||||
auto pLine = pTeriMgr->getTerritoryPosition( zoneLineId );
|
||||
|
||||
Common::FFXIVARR_POSITION3 targetPos{};
|
||||
uint32_t targetZone;
|
||||
float rotation = 0.0f;
|
||||
|
||||
if( pLine != nullptr )
|
||||
/* if( pLine != nullptr )
|
||||
{
|
||||
player.sendDebug( "ZoneLine #{0} found.", zoneLineId );
|
||||
targetPos = pLine->getTargetPosition();
|
||||
|
@ -311,7 +349,7 @@ void Sapphire::Network::GameConnection::zoneLineHandler( FrameworkPtr pFw,
|
|||
targetPos.y = 0;
|
||||
targetPos.z = 0;
|
||||
targetZone = pZone->getTerritoryTypeId();
|
||||
}
|
||||
}*/
|
||||
|
||||
player.performZoning( targetZone, targetPos, rotation );
|
||||
}
|
||||
|
@ -321,29 +359,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->header.discoveryIndex;
|
||||
player.queuePacket( discoveryPacket );
|
||||
player.discover( tInfo->map, pRefInfo->header.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 );
|
||||
|
||||
|
|
118
src/world/Territory/InstanceObjectCache.cpp
Normal file
118
src/world/Territory/InstanceObjectCache.cpp
Normal file
|
@ -0,0 +1,118 @@
|
|||
#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>
|
||||
|
||||
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;
|
||||
|
||||
// TODO: Horrible workaround... Fails if expansion is not installed
|
||||
if( path.find( "ex3" ) != std::string::npos )
|
||||
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;
|
||||
|
||||
auto test_file = pExd->getGameData()->getFile( bgLgbPath );
|
||||
bgSection = test_file->access_data_sections().at( 0 );
|
||||
|
||||
auto planmap_file = pExd->getGameData()->getFile( planmapLgbPath );
|
||||
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 )
|
||||
{
|
||||
if( pEntry->header.instanceId == 1359242 )
|
||||
{
|
||||
std::cout << ">>>" << id << "__" << static_cast< uint32_t >( pEntry->getType() ) << ">>>\n";
|
||||
//break;
|
||||
}
|
||||
|
||||
auto pPopRange = reinterpret_cast< LGB_POP_RANGE_ENTRY* >( pEntry.get() );
|
||||
m_popRangeCache.insert( id, *pPopRange );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
std::cout << "\n";
|
||||
}
|
||||
|
||||
|
||||
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 );
|
||||
}
|
84
src/world/Territory/InstanceObjectCache.h
Normal file
84
src/world/Territory/InstanceObjectCache.h
Normal file
|
@ -0,0 +1,84 @@
|
|||
#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;
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
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;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
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