mirror of
https://github.com/SapphireServer/Sapphire.git
synced 2025-04-27 06:47:45 +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 "matrix4.h"
|
||||||
#include "vec3.h"
|
#include "vec3.h"
|
||||||
#include "sgb.h"
|
#include "sgb.h"
|
||||||
|
#include "LgbTypes.h"
|
||||||
|
|
||||||
// garbage to skip model loading
|
// based on https://github.com/ufx/SaintCoinach/blob/master/SaintCoinach/Graphics/Lgb/
|
||||||
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#
|
|
||||||
struct LGB_FILE;
|
struct LGB_FILE;
|
||||||
struct LGB_FILE_HEADER;
|
struct LGB_FILE_HEADER;
|
||||||
struct LGB_GROUP;
|
struct LGB_GROUP;
|
||||||
struct LGB_GROUP_HEADER;
|
struct LGB_GROUP_HEADER;
|
||||||
|
|
||||||
enum class LgbEntryType :
|
class LgbEntry
|
||||||
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
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
char* m_buf;
|
char* m_buf;
|
||||||
uint32_t m_offset;
|
uint32_t m_offset;
|
||||||
LGB_ENTRY_HEADER header;
|
InstanceObject header;
|
||||||
|
|
||||||
LGB_ENTRY()
|
LgbEntry()
|
||||||
{
|
{
|
||||||
m_buf = nullptr;
|
m_buf = nullptr;
|
||||||
m_offset = 0;
|
m_offset = 0;
|
||||||
memset( &header, 0, sizeof( header ) );
|
memset( &header, 0, sizeof( header ) );
|
||||||
};
|
};
|
||||||
|
|
||||||
LGB_ENTRY( char* buf, uint32_t offset )
|
LgbEntry( char* buf, uint32_t offset )
|
||||||
{
|
{
|
||||||
m_buf = buf;
|
m_buf = buf;
|
||||||
m_offset = offset;
|
m_offset = offset;
|
||||||
header = *reinterpret_cast< LGB_ENTRY_HEADER* >( buf + offset );
|
header = *reinterpret_cast< InstanceObject* >( buf + offset );
|
||||||
};
|
};
|
||||||
|
|
||||||
const LgbEntryType getType() const
|
const LgbEntryType getType() const
|
||||||
|
@ -100,30 +46,16 @@ public:
|
||||||
return header.type;
|
return header.type;
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual ~LGB_ENTRY()
|
virtual ~LgbEntry()
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct LGB_BGPARTS_HEADER :
|
class LGB_BGPARTS_ENTRY : public LgbEntry
|
||||||
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
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
LGB_BGPARTS_HEADER header;
|
BgPartsData header;
|
||||||
std::string name;
|
std::string name;
|
||||||
std::string modelFileName;
|
std::string modelFileName;
|
||||||
std::string collisionFileName;
|
std::string collisionFileName;
|
||||||
|
@ -132,124 +64,95 @@ public:
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
LGB_BGPARTS_ENTRY( char* buf, uint32_t offset ) :
|
LGB_BGPARTS_ENTRY( char* buf, uint32_t offset ) : LgbEntry( buf, offset )
|
||||||
LGB_ENTRY( buf, offset )
|
|
||||||
{
|
{
|
||||||
header = *reinterpret_cast<LGB_BGPARTS_HEADER*>( buf + offset );
|
header = *reinterpret_cast< BgPartsData* >( buf + offset );
|
||||||
name = std::string( buf + offset + header.nameOffset );
|
name = std::string( buf + offset + header.nameOffset );
|
||||||
modelFileName = std::string( buf + offset + header.modelFileOffset );
|
modelFileName = std::string( buf + offset + header.modelFileOffset );
|
||||||
collisionFileName = std::string( buf + offset + header.collisionFileOffset );
|
collisionFileName = std::string( buf + offset + header.collisionFileOffset );
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LGB_GIMMICK_HEADER :
|
class LGB_GIMMICK_ENTRY : public LgbEntry
|
||||||
public LGB_ENTRY_HEADER
|
|
||||||
{
|
|
||||||
uint32_t gimmickFileOffset;
|
|
||||||
char unknownBytes[100];
|
|
||||||
};
|
|
||||||
|
|
||||||
class LGB_GIMMICK_ENTRY :
|
|
||||||
public LGB_ENTRY
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
LGB_GIMMICK_HEADER header;
|
GimmickData header;
|
||||||
std::string name;
|
std::string name;
|
||||||
std::string gimmickFileName;
|
std::string gimmickFileName;
|
||||||
|
|
||||||
LGB_GIMMICK_ENTRY( char* buf, uint32_t offset ) :
|
LGB_GIMMICK_ENTRY( char* buf, uint32_t offset ) : LgbEntry( buf, offset )
|
||||||
LGB_ENTRY( buf, offset )
|
|
||||||
{
|
{
|
||||||
header = *reinterpret_cast<LGB_GIMMICK_HEADER*>( buf + offset );
|
header = *reinterpret_cast< GimmickData* >( buf + offset );
|
||||||
name = std::string( buf + offset + header.nameOffset );
|
name = std::string( buf + offset + header.nameOffset );
|
||||||
gimmickFileName = std::string( buf + offset + header.gimmickFileOffset );
|
gimmickFileName = std::string( buf + offset + header.gimmickFileOffset );
|
||||||
//std::cout << "\t " << gimmickFileName << " unknown: " << header.unknown << "\n";
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LGB_ENPC_HEADER :
|
class LGB_ENPC_ENTRY : public LgbEntry
|
||||||
public LGB_ENTRY_HEADER
|
|
||||||
{
|
|
||||||
uint32_t enpcId;
|
|
||||||
uint8_t unknown1[0x24];
|
|
||||||
};
|
|
||||||
|
|
||||||
class LGB_ENPC_ENTRY :
|
|
||||||
public LGB_ENTRY
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
LGB_ENPC_HEADER header;
|
ENpcData header;
|
||||||
std::string name;
|
std::string name;
|
||||||
|
|
||||||
LGB_ENPC_ENTRY( char* buf, uint32_t offset ) :
|
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
|
|
||||||
{
|
|
||||||
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";
|
|
||||||
name = std::string( buf + offset + header.nameOffset );
|
name = std::string( buf + offset + header.nameOffset );
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LGB_MAPRANGE_HEADER :
|
class LGB_EOBJ_ENTRY : public LgbEntry
|
||||||
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
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
LGB_MAPRANGE_HEADER header;
|
EObjData header;
|
||||||
std::string name;
|
std::string name;
|
||||||
|
|
||||||
LGB_MAPRANGE_ENTRY( char* buf, uint32_t offset ) :
|
LGB_EOBJ_ENTRY( char* buf, uint32_t offset ) : LgbEntry( buf, offset )
|
||||||
LGB_ENTRY( buf, offset )
|
|
||||||
{
|
{
|
||||||
header = *reinterpret_cast< LGB_MAPRANGE_HEADER* >( buf + offset );
|
header = *reinterpret_cast< EObjData* >( buf + offset );
|
||||||
name = std::string( buf + offset + header.nameOffset );
|
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
|
struct LGB_GROUP_HEADER
|
||||||
{
|
{
|
||||||
uint32_t id;
|
uint32_t id;
|
||||||
|
@ -272,15 +175,13 @@ struct LGB_GROUP
|
||||||
LGB_FILE* parent;
|
LGB_FILE* parent;
|
||||||
LGB_GROUP_HEADER header;
|
LGB_GROUP_HEADER header;
|
||||||
std::string name;
|
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 )
|
LGB_GROUP( char* buf, LGB_FILE* parentStruct, uint32_t offset )
|
||||||
{
|
{
|
||||||
parent = parentStruct;
|
parent = parentStruct;
|
||||||
header = *reinterpret_cast< LGB_GROUP_HEADER* >( buf + offset );
|
header = *reinterpret_cast< LGB_GROUP_HEADER* >( buf + offset );
|
||||||
name = std::string( buf + offset + header.groupNameOffset );
|
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;
|
const auto entriesOffset = offset + header.entriesOffset;
|
||||||
for( auto i = 0; i < header.entryCount; ++i )
|
for( auto i = 0; i < header.entryCount; ++i )
|
||||||
{
|
{
|
||||||
|
@ -288,8 +189,7 @@ struct LGB_GROUP
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
const auto type = *reinterpret_cast<LgbEntryType*>( buf + entryOffset );
|
const auto type = *reinterpret_cast< LgbEntryType* >( buf + entryOffset );
|
||||||
// garbage to skip model loading
|
|
||||||
if( type == LgbEntryType::BgParts )
|
if( type == LgbEntryType::BgParts )
|
||||||
{
|
{
|
||||||
entries.push_back( std::make_shared< LGB_BGPARTS_ENTRY >( buf, entryOffset ) );
|
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 ) );
|
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 )
|
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
|
else
|
||||||
{
|
{
|
||||||
entries.push_back( std::make_shared< LGB_ENTRY >( buf, entryOffset ) );
|
entries.push_back( std::make_shared< LgbEntry >( buf, entryOffset ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
catch( std::exception& e )
|
catch( std::exception& e )
|
||||||
{
|
{
|
||||||
|
@ -344,8 +246,7 @@ struct LGB_FILE
|
||||||
std::vector< LGB_GROUP > groups;
|
std::vector< LGB_GROUP > groups;
|
||||||
std::string m_name;
|
std::string m_name;
|
||||||
|
|
||||||
LGB_FILE( char* buf, const std::string& name ) :
|
LGB_FILE( char* buf, const std::string& name ) : LGB_FILE( buf )
|
||||||
LGB_FILE( buf )
|
|
||||||
{
|
{
|
||||||
m_name = name;
|
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 )
|
if( strncmp( &header.magic[ 0 ], "LGB1", 4 ) != 0 || strncmp( &header.magic2[ 0 ], "LGP1", 4 ) != 0 )
|
||||||
throw std::runtime_error( "Invalid LGB file!" );
|
throw std::runtime_error( "Invalid LGB file!" );
|
||||||
|
|
||||||
//groups.resize(header.groupCount);
|
|
||||||
|
|
||||||
constexpr auto baseOffset = sizeof( header );
|
constexpr auto baseOffset = sizeof( header );
|
||||||
for( auto i = 0; i < header.groupCount; ++i )
|
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;
|
struct SGB_GROUP_HEADER;
|
||||||
|
|
||||||
|
|
||||||
enum SgbDataType :
|
enum SgbDataType : uint32_t
|
||||||
uint32_t
|
|
||||||
{
|
{
|
||||||
Unknown0008 = 0x0008,
|
Unknown0008 = 0x0008,
|
||||||
Group = 0x0100,
|
Group = 0x0100,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum SgbGroupEntryType :
|
enum SgbGroupEntryType : uint32_t
|
||||||
uint32_t
|
|
||||||
{
|
{
|
||||||
Model = 0x01,
|
Model = 0x01,
|
||||||
Gimmick = 0x06,
|
Gimmick = 0x06,
|
||||||
|
@ -124,15 +122,13 @@ struct SGB_ENTRY_HEADER
|
||||||
vec3 scale;
|
vec3 scale;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SGB_MODEL_HEADER :
|
struct SGB_MODEL_HEADER : public SGB_ENTRY_HEADER
|
||||||
public SGB_ENTRY_HEADER
|
|
||||||
{
|
{
|
||||||
int32_t modelFileOffset;
|
int32_t modelFileOffset;
|
||||||
int32_t collisionFileOffset;
|
int32_t collisionFileOffset;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SGB_MODEL_ENTRY :
|
struct SGB_MODEL_ENTRY : public SGB_GROUP_ENTRY
|
||||||
public SGB_GROUP_ENTRY
|
|
||||||
{
|
{
|
||||||
SGB_MODEL_HEADER header;
|
SGB_MODEL_HEADER header;
|
||||||
SgbGroupEntryType type;
|
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
|
// The dat number is found in the offset, last four bits
|
||||||
hashTableEntry.datNum = ( indexHashTableEntry.datOffset & 0xF ) / 0x2;
|
hashTableEntry.datNum = ( indexHashTableEntry.datOffset & 0xF ) / 0x2;
|
||||||
// The offset in the dat file, needs to strip the dat number indicator
|
// 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.dirHash = indexHashTableEntry.dirHash;
|
||||||
hashTableEntry.filenameHash = indexHashTableEntry.filenameHash;
|
hashTableEntry.filenameHash = indexHashTableEntry.filenameHash;
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -400,13 +400,6 @@ CREATE TABLE `dbupdate` (
|
||||||
PRIMARY KEY(`name`)
|
PRIMARY KEY(`name`)
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
) 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` (
|
CREATE TABLE `house` (
|
||||||
`HouseId` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
`HouseId` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||||
`LandSetId` int(10) UNSIGNED DEFAULT NULL,
|
`LandSetId` int(10) UNSIGNED DEFAULT NULL,
|
||||||
|
|
|
@ -5594,6 +5594,11 @@ struct ZoneSharedGroup
|
||||||
std::shared_ptr< xiv::dat::GameData > m_data;
|
std::shared_ptr< xiv::dat::GameData > m_data;
|
||||||
std::shared_ptr< xiv::exd::ExdData > m_exd_data;
|
std::shared_ptr< xiv::exd::ExdData > m_exd_data;
|
||||||
|
|
||||||
|
std::shared_ptr< xiv::dat::GameData > getGameData()
|
||||||
|
{
|
||||||
|
return m_data;
|
||||||
|
}
|
||||||
|
|
||||||
template< class T >
|
template< class T >
|
||||||
std::shared_ptr< T > get( uint32_t id )
|
std::shared_ptr< T > get( uint32_t id )
|
||||||
{
|
{
|
||||||
|
|
|
@ -1550,11 +1550,10 @@ namespace Sapphire::Network::Packets::Server
|
||||||
*/
|
*/
|
||||||
struct FFXIVIpcDiscovery : FFXIVIpcBasePacket< Discovery >
|
struct FFXIVIpcDiscovery : FFXIVIpcBasePacket< Discovery >
|
||||||
{
|
{
|
||||||
/* 0000 */ uint32_t map_part_id;
|
/* 0000 */ uint32_t mapPartId;
|
||||||
/* 0004 */ uint32_t map_id;
|
/* 0004 */ uint32_t mapId;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* UNKOWN TYPE
|
* UNKOWN TYPE
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -36,10 +36,11 @@ struct ZoneInfo
|
||||||
uint16_t id;
|
uint16_t id;
|
||||||
std::string name;
|
std::string name;
|
||||||
std::string path;
|
std::string path;
|
||||||
|
uint16_t mapId;
|
||||||
};
|
};
|
||||||
|
|
||||||
// parsing shit
|
// 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< uint32_t, std::string > eobjNameMap;
|
||||||
std::unordered_map< uint16_t, ZoneInfo > zoneInfoMap;
|
std::unordered_map< uint16_t, ZoneInfo > zoneInfoMap;
|
||||||
std::unordered_map< uint16_t, std::vector< std::pair< uint16_t, std::string > > > zoneInstanceMap;
|
std::unordered_map< uint16_t, std::vector< std::pair< uint16_t, std::string > > > zoneInstanceMap;
|
||||||
|
@ -60,8 +61,7 @@ struct vec2
|
||||||
float x, y;
|
float x, y;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DiscoveryMap :
|
struct DiscoveryMap : std::enable_shared_from_this< DiscoveryMap >
|
||||||
std::enable_shared_from_this< DiscoveryMap >
|
|
||||||
{
|
{
|
||||||
std::string path;
|
std::string path;
|
||||||
Image img;
|
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;
|
std::map< uint16_t, std::map< uint16_t, std::map< uint16_t, std::shared_ptr< DiscoveryMap > > > > discoveryMaps;
|
||||||
|
|
||||||
|
|
||||||
enum class TerritoryTypeExdIndexes :
|
enum class TerritoryTypeExdIndexes : size_t
|
||||||
size_t
|
|
||||||
{
|
{
|
||||||
TerritoryType = 0,
|
TerritoryType = 0,
|
||||||
Path = 1
|
Path = 1,
|
||||||
|
Map = 6
|
||||||
};
|
};
|
||||||
|
|
||||||
using namespace std::chrono_literals;
|
using namespace std::chrono_literals;
|
||||||
|
@ -165,6 +165,8 @@ std::string zoneNameToPath( const std::string& name )
|
||||||
info.id = row.first;
|
info.id = row.first;
|
||||||
info.path = teriPath;
|
info.path = teriPath;
|
||||||
info.name = teriName;
|
info.name = teriName;
|
||||||
|
info.mapId = std::get< uint16_t >(
|
||||||
|
fields.at( static_cast< size_t >( TerritoryTypeExdIndexes::Map ) ) );
|
||||||
zoneInfoMap[ row.first ] = info;
|
zoneInfoMap[ row.first ] = info;
|
||||||
|
|
||||||
if( !found && ( Common::Util::toLowerCopy( name ) == Common::Util::toLowerCopy( teriName ) ) )
|
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\", " );
|
auto pMapRange = reinterpret_cast< LGB_MAP_RANGE_ENTRY* >( pObj );
|
||||||
std::ofstream discoverySql( zoneName + "_poprange.txt", std::ios::app );
|
if( !pMapRange->header.discoveryEnabled )
|
||||||
uint32_t id;
|
return;
|
||||||
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_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 subArea = 0;
|
||||||
auto mapId = -1;
|
auto mapId = -1;
|
||||||
auto discoveryIndex = pMapRange->header.discoveryIndex;
|
auto discoveryIndex = pMapRange->header.discoveryIndex;
|
||||||
|
|
||||||
vec3 translation = pObj->header.translation;
|
vec3 translation = pObj->header.transform.translation;
|
||||||
|
|
||||||
bool found = false;
|
std::string outStr( pMapRange->name + " " + std::to_string( pMapRange->header.instanceId ) + " " +
|
||||||
float scale = 100.f; //pMapRange->header.unknown2
|
std::to_string( pMapRange->header.transform.translation.x ) + " " +
|
||||||
|
std::to_string( pMapRange->header.transform.translation.y ) + " " +
|
||||||
std::string outStr( pMapRange->name + " " + std::to_string( pMapRange->header.unknown ) + " " +
|
std::to_string( pMapRange->header.transform.translation.z ) + " " +
|
||||||
std::to_string( pMapRange->header.translation.x ) + " " +
|
std::to_string( pMapRange->header.transform.rotation.y ) + " " +
|
||||||
std::to_string( pMapRange->header.translation.y ) + " " +
|
std::to_string( pMapRange->header.mapId ) + " " +
|
||||||
std::to_string( pMapRange->header.translation.z ) + " " +
|
std::to_string( pMapRange->header.discoveryIndex ) + "\n"
|
||||||
std::to_string( pMapRange->header.rotation.y ) + "\n"
|
|
||||||
);
|
);
|
||||||
|
|
||||||
//std::to_string( pObj->header.translation.x ) + ", " + std::to_string( pObj->header.translation.y ) + ", " + std::to_string( pObj->header.translation.z ) +
|
out.write( outStr.c_str(), outStr.size() );
|
||||||
//", " + std::to_string( subArea ) + "" + "\n"
|
|
||||||
//);
|
|
||||||
discoverySql.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[] )
|
int main( int argc, char* argv[] )
|
||||||
{
|
{
|
||||||
auto startTime = std::chrono::system_clock::now();
|
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 );
|
std::vector< std::string > argVec( argv + 1, argv + argc );
|
||||||
zoneName = "s1h1";
|
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 )
|
if( argc > 1 )
|
||||||
{
|
{
|
||||||
zoneName = argv[ 1 ];
|
zoneName = argv[ 1 ];
|
||||||
|
@ -304,118 +264,42 @@ int main( int argc, char* argv[] )
|
||||||
}
|
}
|
||||||
|
|
||||||
initExd( gamePath );
|
initExd( gamePath );
|
||||||
std::ofstream discoverySql( zoneName + "_poprange.txt", std::ios::trunc );
|
std::ofstream discoverySql( "maprange_export.txt", std::ios::trunc );
|
||||||
discoverySql.close();
|
|
||||||
|
|
||||||
if( dumpAll )
|
zoneNameToPath( "f1f1" );
|
||||||
|
zoneDumpList.emplace( "f1f1" );
|
||||||
|
zoneDumpList.emplace( "f1f2" );
|
||||||
|
|
||||||
|
for( const auto& zoneName : zoneDumpList )
|
||||||
{
|
{
|
||||||
zoneNameToPath( "s1h1" );
|
entryStartTime = std::chrono::system_clock::now();
|
||||||
|
discoverySql.write( ( zoneName + "\n" ).c_str(), zoneName.size() + 1 );
|
||||||
zoneDumpList.emplace( "s1h1" );
|
try
|
||||||
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 )
|
|
||||||
{
|
{
|
||||||
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];
|
auto test_file = gameData->getFile( bgLgbPath );
|
||||||
sprintf( someString, "%str%04d.pcb", collisionFilePath.c_str(), trId );
|
section = test_file->access_data_sections().at( 0 );
|
||||||
stringList.push_back( std::string( someString ) );
|
|
||||||
//std::cout << someString << "\n";
|
|
||||||
offset1 += 0x20;
|
|
||||||
|
|
||||||
if( offset1 >= section1.size() )
|
auto planmap_file = gameData->getFile( planmapLgbPath );
|
||||||
{
|
section2 = planmap_file->access_data_sections().at( 0 );
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
LGB_FILE bgLgb( §ion[ 0 ], "bg" );
|
|
||||||
LGB_FILE planmapLgb( §ion2[ 0 ], "planmap" );
|
|
||||||
|
|
||||||
std::vector< LGB_FILE > lgbList{ bgLgb, planmapLgb };
|
std::vector< std::string > stringList;
|
||||||
uint32_t max_index = 0;
|
|
||||||
|
|
||||||
// dont bother if we cant write to a file
|
uint32_t offset1 = 0x20;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
LGB_FILE bgLgb( §ion[ 0 ], "bg" );
|
||||||
|
LGB_FILE planmapLgb( §ion2[ 0 ], "planmap" );
|
||||||
|
|
||||||
{
|
std::vector< LGB_FILE > lgbList{ bgLgb, planmapLgb };
|
||||||
std::map< std::string, PCB_FILE > pcbFiles;
|
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 totalGroups = 0;
|
||||||
uint32_t totalGroupEntries = 0;
|
uint32_t totalGroupEntries = 0;
|
||||||
|
|
||||||
|
@ -423,48 +307,46 @@ int main( int argc, char* argv[] )
|
||||||
{
|
{
|
||||||
for( const auto& group : lgb.groups )
|
for( const auto& group : lgb.groups )
|
||||||
{
|
{
|
||||||
//std::cout << "\t" << group.name << " Size " << group.header.entryCount << "\n";
|
|
||||||
totalGroups++;
|
totalGroups++;
|
||||||
for( const auto& pEntry : group.entries )
|
for( const auto& pEntry : group.entries )
|
||||||
{
|
{
|
||||||
if( pEntry->getType() == LgbEntryType::PopRange )
|
if( pEntry->getType() == LgbEntryType::MapRange )
|
||||||
{
|
{
|
||||||
totalGroupEntries++;
|
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 << "[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 " <<
|
catch( std::exception& e )
|
||||||
std::chrono::duration_cast< std::chrono::seconds >(
|
{
|
||||||
std::chrono::system_clock::now() - entryStartTime ).count() << " seconds\n";
|
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 << "\n[Success] Finished all tasks in " <<
|
||||||
{
|
|
||||||
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::chrono::duration_cast< std::chrono::seconds >( std::chrono::system_clock::now() - startTime ).count()
|
std::chrono::duration_cast< std::chrono::seconds >( std::chrono::system_clock::now() - startTime ).count()
|
||||||
<< " seconds\n";
|
<< " seconds\n";
|
||||||
|
|
||||||
|
std::cout << "Press any key to exit...";
|
||||||
getchar();
|
getchar();
|
||||||
|
|
||||||
if( eData )
|
if( eData )
|
||||||
|
|
|
@ -285,7 +285,7 @@ int main( int argc, char* argv[] )
|
||||||
|
|
||||||
auto pEobj = reinterpret_cast< LGB_EOBJ_ENTRY* >( pObj );
|
auto pEobj = reinterpret_cast< LGB_EOBJ_ENTRY* >( pObj );
|
||||||
id = pEobj->header.eobjId;
|
id = pEobj->header.eobjId;
|
||||||
unknown = pEobj->header.unknown;
|
unknown = pEobj->header.instanceId;
|
||||||
|
|
||||||
eobjlevelHierachyId = pEobj->header.levelHierachyId;
|
eobjlevelHierachyId = pEobj->header.levelHierachyId;
|
||||||
|
|
||||||
|
@ -295,7 +295,7 @@ int main( int argc, char* argv[] )
|
||||||
{
|
{
|
||||||
auto pGObj = pEntry1.get();
|
auto pGObj = pEntry1.get();
|
||||||
if( pGObj->getType() == LgbEntryType::Gimmick &&
|
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 );
|
auto pGObjR = reinterpret_cast< LGB_GIMMICK_ENTRY* >( pGObj );
|
||||||
char* dataSection = nullptr;
|
char* dataSection = nullptr;
|
||||||
|
@ -361,13 +361,13 @@ int main( int argc, char* argv[] )
|
||||||
eobjects += " instance.registerEObj( \"" + name + "\", " + std::to_string( id ) +
|
eobjects += " instance.registerEObj( \"" + name + "\", " + std::to_string( id ) +
|
||||||
", " + std::to_string( eobjlevelHierachyId ) + ", " + std::to_string( state ) +
|
", " + std::to_string( eobjlevelHierachyId ) + ", " + std::to_string( state ) +
|
||||||
", " +
|
", " +
|
||||||
"{ " + std::to_string( pObj->header.translation.x ) + "f, "
|
"{ " + std::to_string( pObj->header.transform.translation.x ) + "f, "
|
||||||
+ std::to_string( pObj->header.translation.y ) + "f, "
|
+ std::to_string( pObj->header.transform.translation.y ) + "f, "
|
||||||
+ std::to_string( pObj->header.translation.z ) + "f }, " +
|
+ std::to_string( pObj->header.transform.translation.z ) + "f }, " +
|
||||||
std::to_string( pObj->header.scale.x ) + "f, " +
|
std::to_string( pObj->header.transform.scale.x ) + "f, " +
|
||||||
|
|
||||||
// the rotation inside the sgbs is the inverse of what the game uses
|
// 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::dat::GameData > m_data;
|
||||||
std::shared_ptr< xiv::exd::ExdData > m_exd_data;
|
std::shared_ptr< xiv::exd::ExdData > m_exd_data;
|
||||||
|
|
||||||
|
std::shared_ptr< xiv::dat::GameData > getGameData()
|
||||||
|
{
|
||||||
|
return m_data;
|
||||||
|
}
|
||||||
|
|
||||||
template< class T >
|
template< class T >
|
||||||
std::shared_ptr< T > get( uint32_t id )
|
std::shared_ptr< T > get( uint32_t id )
|
||||||
{
|
{
|
||||||
|
|
|
@ -68,7 +68,7 @@ enum class LgbEntryType :
|
||||||
SphereCastRange = 75,
|
SphereCastRange = 75,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LGB_ENTRY_HEADER
|
struct InstanceObject
|
||||||
{
|
{
|
||||||
LgbEntryType type;
|
LgbEntryType type;
|
||||||
uint32_t unknown;
|
uint32_t unknown;
|
||||||
|
@ -78,25 +78,25 @@ struct LGB_ENTRY_HEADER
|
||||||
vec3 scale;
|
vec3 scale;
|
||||||
};
|
};
|
||||||
|
|
||||||
class LGB_ENTRY
|
class LgbEntry
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
char* m_buf;
|
char* m_buf;
|
||||||
uint32_t m_offset;
|
uint32_t m_offset;
|
||||||
LGB_ENTRY_HEADER header;
|
InstanceObject header;
|
||||||
|
|
||||||
LGB_ENTRY()
|
LgbEntry()
|
||||||
{
|
{
|
||||||
m_buf = nullptr;
|
m_buf = nullptr;
|
||||||
m_offset = 0;
|
m_offset = 0;
|
||||||
memset( &header, 0, sizeof( header ) );
|
memset( &header, 0, sizeof( header ) );
|
||||||
};
|
};
|
||||||
|
|
||||||
LGB_ENTRY( char* buf, uint32_t offset )
|
LgbEntry( char* buf, uint32_t offset )
|
||||||
{
|
{
|
||||||
m_buf = buf;
|
m_buf = buf;
|
||||||
m_offset = offset;
|
m_offset = offset;
|
||||||
header = *reinterpret_cast< LGB_ENTRY_HEADER* >( buf + offset );
|
header = *reinterpret_cast< InstanceObject* >( buf + offset );
|
||||||
};
|
};
|
||||||
|
|
||||||
const LgbEntryType getType() const
|
const LgbEntryType getType() const
|
||||||
|
@ -104,14 +104,14 @@ public:
|
||||||
return header.type;
|
return header.type;
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual ~LGB_ENTRY()
|
virtual ~LgbEntry()
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct LGB_BGPARTS_HEADER :
|
struct BgPartsData :
|
||||||
public LGB_ENTRY_HEADER
|
public InstanceObject
|
||||||
{
|
{
|
||||||
uint32_t modelFileOffset;
|
uint32_t modelFileOffset;
|
||||||
uint32_t collisionFileOffset;
|
uint32_t collisionFileOffset;
|
||||||
|
@ -124,10 +124,10 @@ struct LGB_BGPARTS_HEADER :
|
||||||
};
|
};
|
||||||
|
|
||||||
class LGB_BGPARTS_ENTRY :
|
class LGB_BGPARTS_ENTRY :
|
||||||
public LGB_ENTRY
|
public LgbEntry
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
LGB_BGPARTS_HEADER header;
|
BgPartsData header;
|
||||||
std::string name;
|
std::string name;
|
||||||
std::string modelFileName;
|
std::string modelFileName;
|
||||||
std::string collisionFileName;
|
std::string collisionFileName;
|
||||||
|
@ -137,65 +137,65 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
LGB_BGPARTS_ENTRY( char* buf, uint32_t offset ) :
|
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 );
|
name = std::string( buf + offset + header.nameOffset );
|
||||||
modelFileName = std::string( buf + offset + header.modelFileOffset );
|
modelFileName = std::string( buf + offset + header.modelFileOffset );
|
||||||
collisionFileName = std::string( buf + offset + header.collisionFileOffset );
|
collisionFileName = std::string( buf + offset + header.collisionFileOffset );
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LGB_GIMMICK_HEADER :
|
struct GimmickData :
|
||||||
public LGB_ENTRY_HEADER
|
public InstanceObject
|
||||||
{
|
{
|
||||||
uint32_t gimmickFileOffset;
|
uint32_t gimmickFileOffset;
|
||||||
char unknownBytes[100];
|
char unknownBytes[100];
|
||||||
};
|
};
|
||||||
|
|
||||||
class LGB_GIMMICK_ENTRY :
|
class LGB_GIMMICK_ENTRY :
|
||||||
public LGB_ENTRY
|
public LgbEntry
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
LGB_GIMMICK_HEADER header;
|
GimmickData header;
|
||||||
std::string name;
|
std::string name;
|
||||||
std::string gimmickFileName;
|
std::string gimmickFileName;
|
||||||
|
|
||||||
LGB_GIMMICK_ENTRY( char* buf, uint32_t offset ) :
|
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 );
|
name = std::string( buf + offset + header.nameOffset );
|
||||||
gimmickFileName = std::string( buf + offset + header.gimmickFileOffset );
|
gimmickFileName = std::string( buf + offset + header.gimmickFileOffset );
|
||||||
//std::cout << "\t " << gimmickFileName << " unknown: " << header.unknown << "\n";
|
//std::cout << "\t " << gimmickFileName << " unknown: " << header.unknown << "\n";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LGB_ENPC_HEADER :
|
struct ENpcData :
|
||||||
public LGB_ENTRY_HEADER
|
public InstanceObject
|
||||||
{
|
{
|
||||||
uint32_t enpcId;
|
uint32_t enpcId;
|
||||||
uint8_t unknown1[0x24];
|
uint8_t unknown1[0x24];
|
||||||
};
|
};
|
||||||
|
|
||||||
class LGB_ENPC_ENTRY :
|
class LGB_ENPC_ENTRY :
|
||||||
public LGB_ENTRY
|
public LgbEntry
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
LGB_ENPC_HEADER header;
|
ENpcData header;
|
||||||
std::string name;
|
std::string name;
|
||||||
|
|
||||||
LGB_ENPC_ENTRY( char* buf, uint32_t offset ) :
|
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 );
|
name = std::string( buf + offset + header.nameOffset );
|
||||||
//std::cout << "\t ENpc " << header.enpcId << " " << name << "\n";
|
//std::cout << "\t ENpc " << header.enpcId << " " << name << "\n";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LGB_EOBJ_HEADER :
|
struct EObjData :
|
||||||
public LGB_ENTRY_HEADER
|
public InstanceObject
|
||||||
{
|
{
|
||||||
uint32_t eobjId;
|
uint32_t eobjId;
|
||||||
uint32_t levelHierachyId;
|
uint32_t levelHierachyId;
|
||||||
|
@ -203,23 +203,23 @@ struct LGB_EOBJ_HEADER :
|
||||||
};
|
};
|
||||||
|
|
||||||
class LGB_EOBJ_ENTRY :
|
class LGB_EOBJ_ENTRY :
|
||||||
public LGB_ENTRY
|
public LgbEntry
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
LGB_EOBJ_HEADER header;
|
EObjData header;
|
||||||
std::string name;
|
std::string name;
|
||||||
|
|
||||||
LGB_EOBJ_ENTRY( char* buf, uint32_t offset ) :
|
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";
|
//std::cout << "\t " << header.eobjId << " " << name << " unknown: " << header.unknown << "\n";
|
||||||
name = std::string( buf + offset + header.nameOffset );
|
name = std::string( buf + offset + header.nameOffset );
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LGB_MAPRANGE_HEADER :
|
struct MapRangeData :
|
||||||
public LGB_ENTRY_HEADER
|
public InstanceObject
|
||||||
{
|
{
|
||||||
uint32_t type;
|
uint32_t type;
|
||||||
uint16_t unknown2;
|
uint16_t unknown2;
|
||||||
|
@ -227,35 +227,35 @@ struct LGB_MAPRANGE_HEADER :
|
||||||
uint8_t unknown4[0x10];
|
uint8_t unknown4[0x10];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LGB_MAPRANGE_ENTRY :
|
struct LGB_MAP_RANGE_ENTRY :
|
||||||
public LGB_ENTRY
|
public LgbEntry
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
LGB_MAPRANGE_HEADER header;
|
MapRangeData header;
|
||||||
std::string name;
|
std::string name;
|
||||||
|
|
||||||
LGB_MAPRANGE_ENTRY( char* buf, uint32_t offset ) :
|
LGB_MAP_RANGE_ENTRY( char* buf, uint32_t offset ) :
|
||||||
LGB_ENTRY( buf, 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 );
|
name = std::string( buf + offset + header.nameOffset );
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LGB_COLLISION_BOX_HEADER :
|
struct LGB_COLLISION_BOX_HEADER :
|
||||||
public LGB_ENTRY_HEADER
|
public InstanceObject
|
||||||
{
|
{
|
||||||
uint8_t unk[100];
|
uint8_t unk[100];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LGB_COLLISION_BOX_ENTRY :
|
struct LGB_COLLISION_BOX_ENTRY :
|
||||||
public LGB_ENTRY
|
public LgbEntry
|
||||||
{
|
{
|
||||||
LGB_COLLISION_BOX_HEADER header;
|
LGB_COLLISION_BOX_HEADER header;
|
||||||
std::string name;
|
std::string name;
|
||||||
|
|
||||||
LGB_COLLISION_BOX_ENTRY( char* buf, uint32_t offset ) :
|
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 = *reinterpret_cast< LGB_COLLISION_BOX_HEADER* >( buf + offset );
|
||||||
header.type = LgbEntryType::CollisionBox;
|
header.type = LgbEntryType::CollisionBox;
|
||||||
|
@ -305,7 +305,7 @@ struct LGB_GROUP
|
||||||
LGB_FILE* parent;
|
LGB_FILE* parent;
|
||||||
LGB_GROUP_HEADER header;
|
LGB_GROUP_HEADER header;
|
||||||
std::string name;
|
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 )
|
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;
|
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 ) )
|
if( auto pSgbFile = pCache->getSgbFile( sgbFilePath ) )
|
||||||
{
|
{
|
||||||
|
|
|
@ -68,7 +68,7 @@ enum class LgbEntryType :
|
||||||
SphereCastRange = 75,
|
SphereCastRange = 75,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LGB_ENTRY_HEADER
|
struct InstanceObject
|
||||||
{
|
{
|
||||||
LgbEntryType type;
|
LgbEntryType type;
|
||||||
uint32_t unknown;
|
uint32_t unknown;
|
||||||
|
@ -78,25 +78,25 @@ struct LGB_ENTRY_HEADER
|
||||||
vec3 scale;
|
vec3 scale;
|
||||||
};
|
};
|
||||||
|
|
||||||
class LGB_ENTRY
|
class LgbEntry
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
char* m_buf;
|
char* m_buf;
|
||||||
uint32_t m_offset;
|
uint32_t m_offset;
|
||||||
LGB_ENTRY_HEADER header;
|
InstanceObject header;
|
||||||
|
|
||||||
LGB_ENTRY()
|
LgbEntry()
|
||||||
{
|
{
|
||||||
m_buf = nullptr;
|
m_buf = nullptr;
|
||||||
m_offset = 0;
|
m_offset = 0;
|
||||||
memset( &header, 0, sizeof( header ) );
|
memset( &header, 0, sizeof( header ) );
|
||||||
};
|
};
|
||||||
|
|
||||||
LGB_ENTRY( char* buf, uint32_t offset )
|
LgbEntry( char* buf, uint32_t offset )
|
||||||
{
|
{
|
||||||
m_buf = buf;
|
m_buf = buf;
|
||||||
m_offset = offset;
|
m_offset = offset;
|
||||||
header = *reinterpret_cast< LGB_ENTRY_HEADER* >( buf + offset );
|
header = *reinterpret_cast< InstanceObject* >( buf + offset );
|
||||||
};
|
};
|
||||||
|
|
||||||
const LgbEntryType getType() const
|
const LgbEntryType getType() const
|
||||||
|
@ -104,14 +104,14 @@ public:
|
||||||
return header.type;
|
return header.type;
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual ~LGB_ENTRY()
|
virtual ~LgbEntry()
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct LGB_BGPARTS_HEADER :
|
struct BgPartsData :
|
||||||
public LGB_ENTRY_HEADER
|
public InstanceObject
|
||||||
{
|
{
|
||||||
uint32_t modelFileOffset;
|
uint32_t modelFileOffset;
|
||||||
uint32_t collisionFileOffset;
|
uint32_t collisionFileOffset;
|
||||||
|
@ -124,10 +124,10 @@ struct LGB_BGPARTS_HEADER :
|
||||||
};
|
};
|
||||||
|
|
||||||
class LGB_BGPARTS_ENTRY :
|
class LGB_BGPARTS_ENTRY :
|
||||||
public LGB_ENTRY
|
public LgbEntry
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
LGB_BGPARTS_HEADER header;
|
BgPartsData header;
|
||||||
std::string name;
|
std::string name;
|
||||||
std::string modelFileName;
|
std::string modelFileName;
|
||||||
std::string collisionFileName;
|
std::string collisionFileName;
|
||||||
|
@ -137,65 +137,65 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
LGB_BGPARTS_ENTRY( char* buf, uint32_t offset ) :
|
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 );
|
name = std::string( buf + offset + header.nameOffset );
|
||||||
modelFileName = std::string( buf + offset + header.modelFileOffset );
|
modelFileName = std::string( buf + offset + header.modelFileOffset );
|
||||||
collisionFileName = std::string( buf + offset + header.collisionFileOffset );
|
collisionFileName = std::string( buf + offset + header.collisionFileOffset );
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LGB_GIMMICK_HEADER :
|
struct GimmickData :
|
||||||
public LGB_ENTRY_HEADER
|
public InstanceObject
|
||||||
{
|
{
|
||||||
uint32_t gimmickFileOffset;
|
uint32_t gimmickFileOffset;
|
||||||
char unknownBytes[100];
|
char unknownBytes[100];
|
||||||
};
|
};
|
||||||
|
|
||||||
class LGB_GIMMICK_ENTRY :
|
class LGB_GIMMICK_ENTRY :
|
||||||
public LGB_ENTRY
|
public LgbEntry
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
LGB_GIMMICK_HEADER header;
|
GimmickData header;
|
||||||
std::string name;
|
std::string name;
|
||||||
std::string gimmickFileName;
|
std::string gimmickFileName;
|
||||||
|
|
||||||
LGB_GIMMICK_ENTRY( char* buf, uint32_t offset ) :
|
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 );
|
name = std::string( buf + offset + header.nameOffset );
|
||||||
gimmickFileName = std::string( buf + offset + header.gimmickFileOffset );
|
gimmickFileName = std::string( buf + offset + header.gimmickFileOffset );
|
||||||
//std::cout << "\t " << gimmickFileName << " unknown: " << header.unknown << "\n";
|
//std::cout << "\t " << gimmickFileName << " unknown: " << header.unknown << "\n";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LGB_ENPC_HEADER :
|
struct ENpcData :
|
||||||
public LGB_ENTRY_HEADER
|
public InstanceObject
|
||||||
{
|
{
|
||||||
uint32_t enpcId;
|
uint32_t enpcId;
|
||||||
uint8_t unknown1[0x24];
|
uint8_t unknown1[0x24];
|
||||||
};
|
};
|
||||||
|
|
||||||
class LGB_ENPC_ENTRY :
|
class LGB_ENPC_ENTRY :
|
||||||
public LGB_ENTRY
|
public LgbEntry
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
LGB_ENPC_HEADER header;
|
ENpcData header;
|
||||||
std::string name;
|
std::string name;
|
||||||
|
|
||||||
LGB_ENPC_ENTRY( char* buf, uint32_t offset ) :
|
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 );
|
name = std::string( buf + offset + header.nameOffset );
|
||||||
//std::cout << "\t ENpc " << header.enpcId << " " << name << "\n";
|
//std::cout << "\t ENpc " << header.enpcId << " " << name << "\n";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LGB_EOBJ_HEADER :
|
struct EObjData :
|
||||||
public LGB_ENTRY_HEADER
|
public InstanceObject
|
||||||
{
|
{
|
||||||
uint32_t eobjId;
|
uint32_t eobjId;
|
||||||
uint32_t levelHierachyId;
|
uint32_t levelHierachyId;
|
||||||
|
@ -203,23 +203,23 @@ struct LGB_EOBJ_HEADER :
|
||||||
};
|
};
|
||||||
|
|
||||||
class LGB_EOBJ_ENTRY :
|
class LGB_EOBJ_ENTRY :
|
||||||
public LGB_ENTRY
|
public LgbEntry
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
LGB_EOBJ_HEADER header;
|
EObjData header;
|
||||||
std::string name;
|
std::string name;
|
||||||
|
|
||||||
LGB_EOBJ_ENTRY( char* buf, uint32_t offset ) :
|
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";
|
//std::cout << "\t " << header.eobjId << " " << name << " unknown: " << header.unknown << "\n";
|
||||||
name = std::string( buf + offset + header.nameOffset );
|
name = std::string( buf + offset + header.nameOffset );
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LGB_MAPRANGE_HEADER :
|
struct MapRangeData :
|
||||||
public LGB_ENTRY_HEADER
|
public InstanceObject
|
||||||
{
|
{
|
||||||
uint32_t type;
|
uint32_t type;
|
||||||
uint16_t unknown2;
|
uint16_t unknown2;
|
||||||
|
@ -227,35 +227,34 @@ struct LGB_MAPRANGE_HEADER :
|
||||||
uint8_t unknown4[0x10];
|
uint8_t unknown4[0x10];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LGB_MAPRANGE_ENTRY :
|
struct LGB_MAP_RANGE_ENTRY : public LgbEntry
|
||||||
public LGB_ENTRY
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
LGB_MAPRANGE_HEADER header;
|
MapRangeData header;
|
||||||
std::string name;
|
std::string name;
|
||||||
|
|
||||||
LGB_MAPRANGE_ENTRY( char* buf, uint32_t offset ) :
|
LGB_MAP_RANGE_ENTRY( char* buf, uint32_t offset ) :
|
||||||
LGB_ENTRY( buf, 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 );
|
name = std::string( buf + offset + header.nameOffset );
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LGB_COLLISION_BOX_HEADER :
|
struct LGB_COLLISION_BOX_HEADER :
|
||||||
public LGB_ENTRY_HEADER
|
public InstanceObject
|
||||||
{
|
{
|
||||||
uint8_t unk[100];
|
uint8_t unk[100];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LGB_COLLISION_BOX_ENTRY :
|
struct LGB_COLLISION_BOX_ENTRY :
|
||||||
public LGB_ENTRY
|
public LgbEntry
|
||||||
{
|
{
|
||||||
LGB_COLLISION_BOX_HEADER header;
|
LGB_COLLISION_BOX_HEADER header;
|
||||||
std::string name;
|
std::string name;
|
||||||
|
|
||||||
LGB_COLLISION_BOX_ENTRY( char* buf, uint32_t offset ) :
|
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 = *reinterpret_cast< LGB_COLLISION_BOX_HEADER* >( buf + offset );
|
||||||
header.type = LgbEntryType::CollisionBox;
|
header.type = LgbEntryType::CollisionBox;
|
||||||
|
@ -305,7 +304,7 @@ struct LGB_GROUP
|
||||||
LGB_FILE* parent;
|
LGB_FILE* parent;
|
||||||
LGB_GROUP_HEADER header;
|
LGB_GROUP_HEADER header;
|
||||||
std::string name;
|
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 )
|
LGB_GROUP( char* buf, LGB_FILE* parentStruct, uint32_t offset )
|
||||||
{
|
{
|
||||||
|
|
|
@ -429,7 +429,7 @@ int main( int argc, char* argv[] )
|
||||||
}
|
}
|
||||||
return true;
|
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 ) )
|
if( auto pSgbFile = pCache->getSgbFile( sgbFilePath ) )
|
||||||
{
|
{
|
||||||
|
|
|
@ -19,8 +19,10 @@
|
||||||
#include "Territory/Territory.h"
|
#include "Territory/Territory.h"
|
||||||
#include "Territory/ZonePosition.h"
|
#include "Territory/ZonePosition.h"
|
||||||
#include "Territory/InstanceContent.h"
|
#include "Territory/InstanceContent.h"
|
||||||
|
#include "Territory/InstanceObjectCache.h"
|
||||||
#include "Territory/Land.h"
|
#include "Territory/Land.h"
|
||||||
|
|
||||||
|
|
||||||
#include "Network/GameConnection.h"
|
#include "Network/GameConnection.h"
|
||||||
#include "Network/PacketWrappers/ActorControlPacket.h"
|
#include "Network/PacketWrappers/ActorControlPacket.h"
|
||||||
#include "Network/PacketWrappers/ActorControlSelfPacket.h"
|
#include "Network/PacketWrappers/ActorControlSelfPacket.h"
|
||||||
|
@ -350,8 +352,27 @@ void Sapphire::Entity::Player::teleport( uint16_t aetheryteId, uint8_t type )
|
||||||
}
|
}
|
||||||
|
|
||||||
setStateFlag( PlayerStateFlag::BetweenAreas );
|
setStateFlag( PlayerStateFlag::BetweenAreas );
|
||||||
|
|
||||||
|
auto pInstanceObjectCache = m_pFw->get< InstanceObjectCache >();
|
||||||
|
|
||||||
auto targetPos = pTeriMgr->getTerritoryPosition( data->level.at( 0 ) );
|
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;
|
Common::FFXIVARR_POSITION3 pos;
|
||||||
pos.x = 0;
|
pos.x = 0;
|
||||||
pos.y = 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 );
|
sscanf( params.c_str(), "%i %i", &map_id, &discover_id );
|
||||||
|
|
||||||
auto discoveryPacket = makeZonePacket< FFXIVIpcDiscovery >( player.getId() );
|
auto discoveryPacket = makeZonePacket< FFXIVIpcDiscovery >( player.getId() );
|
||||||
discoveryPacket->data().map_id = map_id;
|
discoveryPacket->data().mapId = map_id;
|
||||||
discoveryPacket->data().map_part_id = discover_id;
|
discoveryPacket->data().mapPartId = discover_id;
|
||||||
player.queuePacket( discoveryPacket );
|
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" )
|
else if( subCommand == "discovery_reset" )
|
||||||
{
|
{
|
||||||
player.resetDiscovery();
|
player.resetDiscovery();
|
||||||
|
|
|
@ -9,6 +9,9 @@
|
||||||
#include <Database/DatabaseDef.h>
|
#include <Database/DatabaseDef.h>
|
||||||
#include <Util/Util.h>
|
#include <Util/Util.h>
|
||||||
|
|
||||||
|
#include <datReader/DatCategories/bg/LgbTypes.h>
|
||||||
|
#include <datReader/DatCategories/bg/Lgb.h>
|
||||||
|
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <Network/PacketDef/Zone/ClientZoneDef.h>
|
#include <Network/PacketDef/Zone/ClientZoneDef.h>
|
||||||
#include <Logging/Logger.h>
|
#include <Logging/Logger.h>
|
||||||
|
@ -20,6 +23,7 @@
|
||||||
#include "Territory/Land.h"
|
#include "Territory/Land.h"
|
||||||
#include "Territory/ZonePosition.h"
|
#include "Territory/ZonePosition.h"
|
||||||
#include "Territory/House.h"
|
#include "Territory/House.h"
|
||||||
|
#include "Territory/InstanceObjectCache.h"
|
||||||
|
|
||||||
#include "Network/PacketWrappers/PlayerSetupPacket.h"
|
#include "Network/PacketWrappers/PlayerSetupPacket.h"
|
||||||
#include "Network/PacketWrappers/PingPacket.h"
|
#include "Network/PacketWrappers/PingPacket.h"
|
||||||
|
@ -274,22 +278,56 @@ void Sapphire::Network::GameConnection::zoneLineHandler( FrameworkPtr pFw,
|
||||||
const Packets::FFXIVARR_PACKET_RAW& inPacket,
|
const Packets::FFXIVARR_PACKET_RAW& inPacket,
|
||||||
Entity::Player& player )
|
Entity::Player& player )
|
||||||
{
|
{
|
||||||
auto pTeriMgr = pFw->get< TerritoryMgr >();
|
|
||||||
|
|
||||||
const auto packet = ZoneChannelPacket< Client::FFXIVIpcZoneLineHandler >( inPacket );
|
const auto packet = ZoneChannelPacket< Client::FFXIVIpcZoneLineHandler >( inPacket );
|
||||||
const auto zoneLineId = packet.data().zoneLineId;
|
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 );
|
player.sendDebug( "Walking ZoneLine#{0}", zoneLineId );
|
||||||
|
|
||||||
auto pZone = player.getCurrentTerritory();
|
auto pZone = player.getCurrentTerritory();
|
||||||
|
|
||||||
auto pLine = pTeriMgr->getTerritoryPosition( zoneLineId );
|
|
||||||
|
|
||||||
Common::FFXIVARR_POSITION3 targetPos{};
|
|
||||||
uint32_t targetZone;
|
|
||||||
float rotation = 0.0f;
|
float rotation = 0.0f;
|
||||||
|
|
||||||
if( pLine != nullptr )
|
/* if( pLine != nullptr )
|
||||||
{
|
{
|
||||||
player.sendDebug( "ZoneLine #{0} found.", zoneLineId );
|
player.sendDebug( "ZoneLine #{0} found.", zoneLineId );
|
||||||
targetPos = pLine->getTargetPosition();
|
targetPos = pLine->getTargetPosition();
|
||||||
|
@ -311,7 +349,7 @@ void Sapphire::Network::GameConnection::zoneLineHandler( FrameworkPtr pFw,
|
||||||
targetPos.y = 0;
|
targetPos.y = 0;
|
||||||
targetPos.z = 0;
|
targetPos.z = 0;
|
||||||
targetZone = pZone->getTerritoryTypeId();
|
targetZone = pZone->getTerritoryTypeId();
|
||||||
}
|
}*/
|
||||||
|
|
||||||
player.performZoning( targetZone, targetPos, rotation );
|
player.performZoning( targetZone, targetPos, rotation );
|
||||||
}
|
}
|
||||||
|
@ -321,29 +359,23 @@ void Sapphire::Network::GameConnection::discoveryHandler( FrameworkPtr pFw,
|
||||||
const Packets::FFXIVARR_PACKET_RAW& inPacket,
|
const Packets::FFXIVARR_PACKET_RAW& inPacket,
|
||||||
Entity::Player& player )
|
Entity::Player& player )
|
||||||
{
|
{
|
||||||
|
auto pInstanceObjectCache = pFw->get< InstanceObjectCache >();
|
||||||
|
auto tInfo = player.getCurrentTerritory()->getTerritoryTypeInfo();
|
||||||
const auto packet = ZoneChannelPacket< Client::FFXIVIpcDiscoveryHandler >( inPacket );
|
const auto packet = ZoneChannelPacket< Client::FFXIVIpcDiscoveryHandler >( inPacket );
|
||||||
const auto positionRef = packet.data().positionRef;
|
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.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/NaviMgr.h"
|
||||||
#include "Manager/ActionMgr.h"
|
#include "Manager/ActionMgr.h"
|
||||||
|
|
||||||
|
#include "Territory/InstanceObjectCache.h"
|
||||||
|
|
||||||
using namespace Sapphire::World::Manager;
|
using namespace Sapphire::World::Manager;
|
||||||
|
|
||||||
Sapphire::World::ServerMgr::ServerMgr( const std::string& configName, FrameworkPtr pFw ) :
|
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 );
|
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() );
|
auto pActionMgr = std::make_shared< Manager::ActionMgr >( framework() );
|
||||||
framework()->set< Manager::ActionMgr >( pActionMgr );
|
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