2015-09-10 13:30:35 -07:00
# include "SCLY.hpp"
# include "ScriptObjects/ScriptTypes.hpp"
2017-12-29 00:08:12 -08:00
namespace DataSpec : : DNAMP1
2015-09-10 13:30:35 -07:00
{
2018-02-21 23:24:51 -08:00
template < >
void SCLY : : Enumerate < BigDNA : : Read > ( athena : : io : : IStreamReader & rs )
2015-09-10 13:30:35 -07:00
{
fourCC = rs . readUint32Little ( ) ;
version = rs . readUint32Big ( ) ;
layerCount = rs . readUint32Big ( ) ;
rs . enumerateBig ( layerSizes , layerCount ) ;
atUint32 i = 0 ;
2018-08-27 22:44:16 -07:00
rs . enumerate < ScriptLayer > ( layers , layerCount ,
[ & i , this ] ( athena : : io : : IStreamReader & rs , ScriptLayer & layer ) {
2015-09-10 13:30:35 -07:00
atUint64 start = rs . position ( ) ;
layer . read ( rs ) ;
2016-03-04 15:04:53 -08:00
rs . seek ( start + layerSizes [ i + + ] , athena : : Begin ) ;
2015-09-10 13:30:35 -07:00
} ) ;
}
2018-02-21 23:24:51 -08:00
template < >
void SCLY : : Enumerate < BigDNA : : Write > ( athena : : io : : IStreamWriter & ws )
2015-09-10 13:30:35 -07:00
{
ws . writeUint32Big ( fourCC ) ;
ws . writeUint32Big ( version ) ;
ws . writeUint32Big ( layerCount ) ;
ws . enumerateBig ( layerSizes ) ;
ws . enumerate ( layers ) ;
}
2018-02-21 23:24:51 -08:00
template < >
void SCLY : : Enumerate < BigDNA : : BinarySize > ( size_t & __isz )
2015-10-17 21:08:45 -07:00
{
__isz + = 12 ;
__isz + = layerSizes . size ( ) * 4 ;
2018-02-21 23:24:51 -08:00
for ( const ScriptLayer & layer : layers )
layer . binarySize ( __isz ) ;
2015-10-17 21:08:45 -07:00
}
2016-08-09 19:52:00 -07:00
void SCLY : : exportToLayerDirectories ( const PAK : : Entry & entry , PAKRouter < PAKBridge > & pakRouter , bool force ) const
2015-09-10 13:30:35 -07:00
{
for ( atUint32 i = 0 ; i < layerCount ; i + + )
{
2016-08-09 19:52:00 -07:00
bool active ;
hecl : : ProjectPath layerPath = pakRouter . getAreaLayerWorking ( entry . id , i , active ) ;
2016-09-18 16:47:48 -07:00
if ( layerPath . isNone ( ) )
2017-01-16 17:23:19 -08:00
layerPath . makeDirChain ( true ) ;
2015-09-10 13:30:35 -07:00
2016-08-09 19:52:00 -07:00
if ( active )
{
hecl : : ProjectPath activePath ( layerPath , " !defaultactive " ) ;
2018-10-14 13:16:21 -07:00
fclose ( hecl : : Fopen ( activePath . getAbsolutePath ( ) . data ( ) , _SYS_STR ( " wb " ) ) ) ;
2016-08-09 19:52:00 -07:00
}
2018-10-14 13:16:21 -07:00
hecl : : ProjectPath yamlFile ( layerPath , _SYS_STR ( " !objects.yaml " ) ) ;
2016-09-18 16:47:48 -07:00
if ( force | | yamlFile . isNone ( ) )
2015-09-10 13:30:35 -07:00
{
2016-08-21 20:47:48 -07:00
athena : : io : : FileWriter writer ( yamlFile . getAbsolutePath ( ) ) ;
2018-02-21 23:24:51 -08:00
athena : : io : : ToYAMLStream ( layers [ i ] , writer ) ;
2015-09-10 13:30:35 -07:00
}
}
}
2018-10-11 13:50:05 -07:00
void SCLY : : addCMDLRigPairs ( PAKRouter < PAKBridge > & pakRouter , CharacterAssociations < UniqueID32 > & charAssoc ) const
2015-10-26 17:19:03 -07:00
{
for ( const ScriptLayer & layer : layers )
2018-10-11 13:50:05 -07:00
layer . addCMDLRigPairs ( pakRouter , charAssoc ) ;
2015-10-26 17:19:03 -07:00
}
2018-10-11 13:50:05 -07:00
void SCLY : : ScriptLayer : : addCMDLRigPairs ( PAKRouter < PAKBridge > & pakRouter , CharacterAssociations < UniqueID32 > & charAssoc ) const
2015-10-26 17:19:03 -07:00
{
2015-11-28 21:59:34 -08:00
for ( const std : : unique_ptr < IScriptObject > & obj : objects )
2018-10-11 13:50:05 -07:00
obj - > addCMDLRigPairs ( pakRouter , charAssoc ) ;
2015-10-26 17:19:03 -07:00
}
void SCLY : : nameIDs ( PAKRouter < PAKBridge > & pakRouter ) const
{
for ( const ScriptLayer & layer : layers )
layer . nameIDs ( pakRouter ) ;
}
void SCLY : : ScriptLayer : : nameIDs ( PAKRouter < PAKBridge > & pakRouter ) const
{
2015-11-28 21:59:34 -08:00
for ( const std : : unique_ptr < IScriptObject > & obj : objects )
2015-10-26 17:19:03 -07:00
obj - > nameIDs ( pakRouter ) ;
}
2018-02-21 23:24:51 -08:00
template < >
void SCLY : : Enumerate < BigDNA : : ReadYaml > ( athena : : io : : YAMLDocReader & docin )
2015-09-10 13:30:35 -07:00
{
fourCC = docin . readUint32 ( " fourCC " ) ;
version = docin . readUint32 ( " version " ) ;
2016-03-03 17:01:37 -08:00
layerCount = docin . enumerate ( " layerSizes " , layerSizes ) ;
docin . enumerate ( " layers " , layers ) ;
2015-09-10 13:30:35 -07:00
}
2018-02-21 23:24:51 -08:00
template < >
void SCLY : : Enumerate < BigDNA : : WriteYaml > ( athena : : io : : YAMLDocWriter & docout )
2015-09-10 13:30:35 -07:00
{
docout . writeUint32 ( " fourCC " , fourCC ) ;
docout . writeUint32 ( " version " , version ) ;
docout . enumerate ( " layerSizes " , layerSizes ) ;
docout . enumerate ( " layers " , layers ) ;
}
2015-09-30 17:46:37 -07:00
const char * SCLY : : DNAType ( )
{
2016-03-04 15:04:53 -08:00
return " urde::DNAMP1::SCLY " ;
2015-09-30 17:46:37 -07:00
}
2018-02-21 23:24:51 -08:00
template < >
void SCLY : : ScriptLayer : : Enumerate < BigDNA : : Read > ( athena : : io : : IStreamReader & rs )
2015-09-10 13:30:35 -07:00
{
unknown = rs . readUByte ( ) ;
objectCount = rs . readUint32Big ( ) ;
2016-03-04 15:04:53 -08:00
objects . clear ( ) ;
2015-09-10 13:30:35 -07:00
objects . reserve ( objectCount ) ;
for ( atUint32 i = 0 ; i < objectCount ; i + + )
{
atUint8 type = rs . readUByte ( ) ;
atUint32 len = rs . readUint32Big ( ) ;
atUint64 start = rs . position ( ) ;
auto iter = std : : find_if ( SCRIPT_OBJECT_DB . begin ( ) , SCRIPT_OBJECT_DB . end ( ) , [ & type ] ( const ScriptObjectSpec * obj ) - > bool
{ return obj - > type = = type ; } ) ;
if ( iter ! = SCRIPT_OBJECT_DB . end ( ) )
{
2015-11-28 21:59:34 -08:00
std : : unique_ptr < IScriptObject > obj ( ( * iter ) - > a ( ) ) ;
2015-09-10 13:30:35 -07:00
obj - > type = type ;
obj - > read ( rs ) ;
2015-11-28 21:59:34 -08:00
objects . push_back ( std : : move ( obj ) ) ;
2015-10-12 02:30:18 -07:00
size_t actualLen = rs . position ( ) - start ;
if ( actualLen ! = len )
2018-10-14 13:16:21 -07:00
Log . report ( logvisor : : Fatal , _SYS_STR ( " Error while reading object of type 0x%.2X, did not read the expected amount of data, read 0x%x, expected 0x%x " ) , ( atUint32 ) type , actualLen , len ) ;
2016-03-04 15:04:53 -08:00
rs . seek ( start + len , athena : : Begin ) ;
2015-09-10 13:30:35 -07:00
}
else
2018-10-14 13:16:21 -07:00
Log . report ( logvisor : : Fatal , _SYS_STR ( " Unable to find type 0x%X in object database " ) , ( atUint32 ) type ) ;
2015-09-10 13:30:35 -07:00
}
}
2018-02-21 23:24:51 -08:00
template < >
void SCLY : : ScriptLayer : : Enumerate < BigDNA : : ReadYaml > ( athena : : io : : YAMLDocReader & rs )
2015-09-10 13:30:35 -07:00
{
unknown = rs . readUByte ( " unknown " ) ;
2016-03-03 17:01:37 -08:00
size_t objCount ;
objects . clear ( ) ;
2017-02-12 15:56:03 -08:00
if ( auto v = rs . enterSubVector ( " objects " , objCount ) )
2015-09-10 13:30:35 -07:00
{
2016-03-03 17:01:37 -08:00
objectCount = objCount ;
objects . reserve ( objCount ) ;
for ( atUint32 i = 0 ; i < objectCount ; i + + )
2015-09-10 13:30:35 -07:00
{
2017-02-12 15:56:03 -08:00
if ( auto rec = rs . enterSubRecord ( nullptr ) )
2016-03-03 17:01:37 -08:00
{
2017-02-12 15:56:03 -08:00
atUint8 type = rs . readUByte ( " type " ) ;
auto iter = std : : find_if ( SCRIPT_OBJECT_DB . begin ( ) , SCRIPT_OBJECT_DB . end ( ) , [ & type ] ( const ScriptObjectSpec * obj ) - > bool
{ return obj - > type = = type ; } ) ;
if ( iter ! = SCRIPT_OBJECT_DB . end ( ) )
{
std : : unique_ptr < IScriptObject > obj ( ( * iter ) - > a ( ) ) ;
obj - > read ( rs ) ;
obj - > type = type ;
objects . push_back ( std : : move ( obj ) ) ;
}
else
2018-10-14 13:16:21 -07:00
Log . report ( logvisor : : Fatal , _SYS_STR ( " Unable to find type 0x%X in object database " ) , ( atUint32 ) type ) ;
2016-03-03 17:01:37 -08:00
}
2015-09-10 13:30:35 -07:00
}
}
2016-03-03 17:01:37 -08:00
else
objectCount = 0 ;
2015-09-10 13:30:35 -07:00
}
2018-02-21 23:24:51 -08:00
template < >
void SCLY : : ScriptLayer : : Enumerate < BigDNA : : Write > ( athena : : io : : IStreamWriter & ws )
2015-09-10 13:30:35 -07:00
{
ws . writeUByte ( unknown ) ;
ws . writeUint32Big ( objectCount ) ;
2015-11-28 21:59:34 -08:00
for ( const std : : unique_ptr < IScriptObject > & obj : objects )
2015-09-10 13:30:35 -07:00
{
ws . writeByte ( obj - > type ) ;
2018-02-21 23:24:51 -08:00
size_t expLen = 0 ;
obj - > binarySize ( expLen ) ;
2016-08-12 18:23:27 -07:00
ws . writeUint32Big ( expLen ) ;
auto start = ws . position ( ) ;
2015-09-10 13:30:35 -07:00
obj - > write ( ws ) ;
2016-08-12 18:23:27 -07:00
auto wrote = ws . position ( ) - start ;
if ( wrote ! = expLen )
Log . report ( logvisor : : Error , " expected writing %lu byte SCLY obj; wrote %llu " , expLen , wrote ) ;
2015-09-10 13:30:35 -07:00
}
}
2018-02-21 23:24:51 -08:00
template < >
void SCLY : : ScriptLayer : : Enumerate < BigDNA : : BinarySize > ( size_t & __isz )
2015-10-17 21:08:45 -07:00
{
__isz + = 5 ;
2015-11-28 21:59:34 -08:00
for ( const std : : unique_ptr < IScriptObject > & obj : objects )
2015-10-17 21:08:45 -07:00
{
2016-08-12 18:23:27 -07:00
__isz + = 5 ;
2018-02-21 23:24:51 -08:00
obj - > binarySize ( __isz ) ;
2015-10-17 21:08:45 -07:00
}
}
2018-02-21 23:24:51 -08:00
template < >
void SCLY : : ScriptLayer : : Enumerate < BigDNA : : WriteYaml > ( athena : : io : : YAMLDocWriter & ws )
2015-09-10 13:30:35 -07:00
{
ws . writeUByte ( " unknown " , unknown ) ;
2017-02-12 15:56:03 -08:00
if ( auto v = ws . enterSubVector ( " objects " ) )
2015-09-10 13:30:35 -07:00
{
2017-02-12 15:56:03 -08:00
for ( const std : : unique_ptr < IScriptObject > & obj : objects )
{
if ( auto rec = ws . enterSubRecord ( nullptr ) )
{
ws . writeUByte ( " type " , obj - > type ) ;
obj - > write ( ws ) ;
}
}
}
2015-09-10 13:30:35 -07:00
}
2015-09-30 17:46:37 -07:00
const char * SCLY : : ScriptLayer : : DNAType ( )
{
2016-03-04 15:04:53 -08:00
return " urde::DNAMP1::SCLY::ScriptLayer " ;
2015-09-30 17:46:37 -07:00
}
2015-09-10 13:30:35 -07:00
}