2022-04-06 21:37:28 +02:00
# include <STDInclude.hpp>
2022-06-22 17:36:06 +02:00
# include "IGameWorldMp.hpp"
2017-01-16 17:42:50 +01:00
2022-12-14 09:40:15 +01:00
# define IW4X_GAMEWORLD_VERSION 1
2017-01-16 17:42:50 +01:00
namespace Assets
{
void IGameWorldMp : : save ( Game : : XAssetHeader header , Components : : ZoneBuilder : : Zone * builder )
{
AssertSize ( Game : : GameWorldMp , 8 ) ;
Utils : : Stream * buffer = builder - > getBuffer ( ) ;
Game : : GameWorldMp * asset = header . gameWorldMp ;
Game : : GameWorldMp * dest = buffer - > dest < Game : : GameWorldMp > ( ) ;
buffer - > save ( asset ) ;
buffer - > pushBlock ( Game : : XFILE_BLOCK_VIRTUAL ) ;
if ( asset - > name )
{
buffer - > saveString ( builder - > getAssetName ( this - > getType ( ) , asset - > name ) ) ;
Utils : : Stream : : ClearPointer ( & dest - > name ) ;
}
2018-05-09 14:33:52 +02:00
if ( asset - > g_glassData )
2017-01-16 17:42:50 +01:00
{
buffer - > align ( Utils : : Stream : : ALIGN_4 ) ;
// Save_G_GlassData
{
AssertSize ( Game : : G_GlassData , 128 ) ;
2016-12-20 20:16:23 +01:00
Game : : G_GlassData * destGlass = buffer - > dest < Game : : G_GlassData > ( ) ;
2018-05-09 14:33:52 +02:00
buffer - > save ( asset - > g_glassData ) ;
2017-01-16 17:42:50 +01:00
2018-05-09 14:33:52 +02:00
if ( asset - > g_glassData - > glassPieces )
2017-01-16 17:42:50 +01:00
{
AssertSize ( Game : : G_GlassPiece , 12 ) ;
buffer - > align ( Utils : : Stream : : ALIGN_4 ) ;
2018-05-09 14:33:52 +02:00
buffer - > saveArray ( asset - > g_glassData - > glassPieces , asset - > g_glassData - > pieceCount ) ;
2017-01-16 17:42:50 +01:00
Utils : : Stream : : ClearPointer ( & destGlass - > glassPieces ) ;
}
2018-05-09 14:33:52 +02:00
if ( asset - > g_glassData - > glassNames )
2017-01-16 17:42:50 +01:00
{
AssertSize ( Game : : G_GlassName , 12 ) ;
buffer - > align ( Utils : : Stream : : ALIGN_4 ) ;
Game : : G_GlassName * destGlassNames = buffer - > dest < Game : : G_GlassName > ( ) ;
2018-05-09 14:33:52 +02:00
buffer - > saveArray ( asset - > g_glassData - > glassNames , asset - > g_glassData - > glassNameCount ) ;
2017-01-16 17:42:50 +01:00
2018-05-09 14:33:52 +02:00
for ( unsigned int i = 0 ; i < asset - > g_glassData - > glassNameCount ; + + i )
2017-01-16 17:42:50 +01:00
{
Game : : G_GlassName * destGlassName = & destGlassNames [ i ] ;
2018-05-09 14:33:52 +02:00
Game : : G_GlassName * glassName = & asset - > g_glassData - > glassNames [ i ] ;
2017-01-16 17:42:50 +01:00
if ( glassName - > nameStr )
{
buffer - > saveString ( glassName - > nameStr ) ;
Utils : : Stream : : ClearPointer ( & destGlassName - > nameStr ) ;
}
if ( glassName - > pieceIndices )
{
buffer - > align ( Utils : : Stream : : ALIGN_2 ) ;
buffer - > saveArray ( glassName - > pieceIndices , glassName - > pieceCount ) ;
Utils : : Stream : : ClearPointer ( & destGlassName - > pieceIndices ) ;
}
}
Utils : : Stream : : ClearPointer ( & destGlass - > glassNames ) ;
}
}
2018-05-09 14:33:52 +02:00
Utils : : Stream : : ClearPointer ( & dest - > g_glassData ) ;
2017-01-16 17:42:50 +01:00
}
buffer - > popBlock ( ) ;
}
2022-12-14 09:40:15 +01:00
void IGameWorldMp : : load ( Game : : XAssetHeader * header , const std : : string & _name , Components : : ZoneBuilder : : Zone * builder )
{
std : : string name = _name ;
Utils : : String : : Replace ( name , " maps/mp/ " , " " ) ;
Utils : : String : : Replace ( name , " .d3dbsp " , " " ) ;
Components : : FileSystem : : File gameWorld ( std : : format ( " gameworld/{}.iw4x.json " , name ) ) ;
if ( gameWorld . exists ( ) )
{
nlohmann : : json gameWorldJson ;
try
{
gameWorldJson = nlohmann : : json : : parse ( gameWorld . getBuffer ( ) ) ;
}
catch ( const std : : exception & e )
{
Components : : Logger : : PrintError ( Game : : CON_CHANNEL_ERROR , " Invalid JSON for gameworld {}! {} " , name , e . what ( ) ) ;
return ;
}
auto * asset = builder - > getAllocator ( ) - > allocate < Game : : GameWorldMp > ( ) ;
if ( ! gameWorldJson . is_object ( ) )
{
Components : : Logger : : PrintError ( Game : : CON_CHANNEL_ERROR , " Invalid GameWorldMp json for {} \n " , name ) ;
return ;
}
auto version = gameWorldJson [ " version " ] . is_number ( ) ? gameWorldJson [ " version " ] . get < int > ( ) : 0 ;
if ( version ! = IW4X_GAMEWORLD_VERSION )
{
Components : : Logger : : PrintError ( Game : : CON_CHANNEL_ERROR , " Invalid GameWorld json version for {}, expected {} and got {} \n " , name , IW4X_GAMEWORLD_VERSION , version ) ;
return ;
}
if ( ! gameWorldJson [ " name " ] . is_string ( ) )
{
Components : : Logger : : PrintError ( Game : : CON_CHANNEL_ERROR , " Missing gameworld name! on {} \n " , name ) ;
return ;
}
asset - > name = builder - > getAllocator ( ) - > duplicateString ( gameWorldJson [ " name " ] . get < std : : string > ( ) ) ;
auto glassData = builder - > getAllocator ( ) - > allocate < Game : : G_GlassData > ( ) ;
if ( gameWorldJson [ " glassData " ] . is_object ( ) )
{
auto jsonGlassData = gameWorldJson [ " glassData " ] ;
try
{
glassData - > damageToDestroy = jsonGlassData [ " damageToDestroy " ] . get < unsigned short > ( ) ;
glassData - > damageToWeaken = jsonGlassData [ " damageToWeaken " ] . get < unsigned short > ( ) ;
if ( jsonGlassData [ " glassNames " ] . is_array ( ) )
{
nlohmann : : json : : array_t glassNames = jsonGlassData [ " glassNames " ] ;
glassData - > glassNameCount = glassNames . size ( ) ;
glassData - > glassNames = builder - > getAllocator ( ) - > allocateArray < Game : : G_GlassName > ( glassData - > glassNameCount ) ;
for ( size_t i = 0 ; i < glassData - > glassNameCount ; i + + )
{
auto jsonGlassName = glassNames [ i ] ;
glassData - > glassNames [ i ] . nameStr = builder - > getAllocator ( ) - > duplicateString ( jsonGlassName [ " nameStr " ] ) ;
glassData - > glassNames [ i ] . name = jsonGlassName [ " name " ] . get < unsigned short > ( ) ;
if ( jsonGlassName [ " piecesIndices " ] . is_array ( ) )
{
nlohmann : : json : : array_t jsonPiecesIndices = jsonGlassName [ " piecesIndices " ] ;
glassData - > glassNames [ i ] . pieceCount = static_cast < unsigned short > ( jsonPiecesIndices . size ( ) ) ;
2023-02-04 18:29:04 +00:00
2022-12-14 09:40:15 +01:00
for ( size_t j = 0 ; j < glassData - > glassNames [ i ] . pieceCount ; j + + )
{
glassData - > glassNames [ i ] . pieceIndices [ j ] = jsonPiecesIndices [ j ] . get < unsigned short > ( ) ;
}
}
}
}
2023-02-04 18:29:04 +00:00
if ( gameWorldJson [ " glassPieces " ] . is_array ( ) )
2022-12-14 09:40:15 +01:00
{
2023-02-04 18:29:04 +00:00
nlohmann : : json : : array_t glassPieces = gameWorldJson [ " glassPieces " ] ;
2022-12-14 09:40:15 +01:00
glassData - > pieceCount = glassPieces . size ( ) ;
glassData - > glassPieces = builder - > getAllocator ( ) - > allocateArray < Game : : G_GlassPiece > ( glassData - > pieceCount ) ;
for ( size_t i = 0 ; i < glassData - > pieceCount ; i + + )
{
glassData - > glassPieces [ i ] . collapseTime = glassPieces [ i ] [ " collapseTime " ] . get < unsigned short > ( ) ;
glassData - > glassPieces [ i ] . damageTaken = glassPieces [ i ] [ " damageTaken " ] . get < unsigned short > ( ) ;
glassData - > glassPieces [ i ] . lastStateChangeTime = glassPieces [ i ] [ " lastStateChangeTime " ] . get < int > ( ) ;
glassData - > glassPieces [ i ] . impactDir = glassPieces [ i ] [ " impactDir " ] . get < char > ( ) ;
nlohmann : : json : : array_t jsonPos = glassPieces [ i ] [ " impactPos " ] ;
glassData - > glassPieces [ i ] . impactPos [ 0 ] = jsonPos [ 0 ] . get < char > ( ) ;
glassData - > glassPieces [ i ] . impactPos [ 1 ] = jsonPos [ 1 ] . get < char > ( ) ;
}
}
}
catch ( const nlohmann : : json : : exception & e )
{
Components : : Logger : : PrintError ( Game : : CON_CHANNEL_ERROR , " Malformed GameWorldMp json for {} ({}) \n " , name , e . what ( ) ) ;
return ;
}
}
asset - > g_glassData = glassData ;
header - > gameWorldMp = asset ;
}
}
2017-01-16 17:42:50 +01:00
}