2017-01-16 11:42:50 -05:00
# include "STDInclude.hpp"
namespace Components
{
std : : string Maps : : CurrentMainZone ;
std : : vector < std : : pair < std : : string , std : : string > > Maps : : DependencyList ;
std : : vector < std : : string > Maps : : CurrentDependencies ;
bool Maps : : IsSPMap ;
std : : vector < Maps : : DLC > Maps : : DlcPacks ;
std : : vector < Game : : XAssetEntry > Maps : : EntryPool ;
void Maps : : LoadMapZones ( Game : : XZoneInfo * zoneInfo , unsigned int zoneCount , int sync )
{
if ( ! zoneInfo ) return ;
Maps : : IsSPMap = false ;
Maps : : CurrentMainZone = zoneInfo - > name ;
Maps : : CurrentDependencies . clear ( ) ;
for ( auto i = Maps : : DependencyList . begin ( ) ; i ! = Maps : : DependencyList . end ( ) ; + + i )
{
if ( std : : regex_match ( zoneInfo - > name , std : : regex ( i - > first ) ) )
{
if ( std : : find ( Maps : : CurrentDependencies . begin ( ) , Maps : : CurrentDependencies . end ( ) , i - > second ) = = Maps : : CurrentDependencies . end ( ) )
{
Maps : : CurrentDependencies . push_back ( i - > second ) ;
}
}
}
Utils : : Memory : : Allocator allocator ;
auto teams = Maps : : GetTeamsForMap ( Maps : : CurrentMainZone ) ;
auto dependencies = Maps : : GetDependenciesForMap ( Maps : : CurrentMainZone ) ;
Utils : : Merge ( & Maps : : CurrentDependencies , dependencies . data ( ) , dependencies . size ( ) ) ;
std : : vector < Game : : XZoneInfo > data ;
Utils : : Merge ( & data , zoneInfo , zoneCount ) ;
Game : : XZoneInfo team ;
team . allocFlags = zoneInfo - > allocFlags ;
team . freeFlags = zoneInfo - > freeFlags ;
team . name = allocator . duplicateString ( Utils : : String : : VA ( " iw4x_team_%s " , teams . first . data ( ) ) ) ;
data . push_back ( team ) ;
team . name = allocator . duplicateString ( Utils : : String : : VA ( " iw4x_team_%s " , teams . second . data ( ) ) ) ;
data . push_back ( team ) ;
for ( unsigned int i = 0 ; i < Maps : : CurrentDependencies . size ( ) ; + + i )
{
Game : : XZoneInfo info ;
info . name = ( & Maps : : CurrentDependencies [ i ] ) - > data ( ) ;
info . allocFlags = zoneInfo - > allocFlags ;
info . freeFlags = zoneInfo - > freeFlags ;
data . push_back ( info ) ;
}
// Load patch files
std : : string patchZone = Utils : : String : : VA ( " patch_%s " , zoneInfo - > name ) ;
if ( FastFiles : : Exists ( patchZone ) )
{
data . push_back ( { patchZone . data ( ) , zoneInfo - > allocFlags , zoneInfo - > freeFlags } ) ;
}
return FastFiles : : LoadLocalizeZones ( data . data ( ) , data . size ( ) , sync ) ;
}
void Maps : : OverrideMapEnts ( Game : : MapEnts * ents )
{
auto callback = [ ] ( Game : : XAssetHeader header , void * ents )
{
Game : : MapEnts * mapEnts = reinterpret_cast < Game : : MapEnts * > ( ents ) ;
Game : : clipMap_t * clipMap = header . clipMap ;
if ( clipMap & & mapEnts & & ! _stricmp ( mapEnts - > name , clipMap - > name ) )
{
clipMap - > mapEnts = mapEnts ;
//*Game::marMapEntsPtr = mapEnts;
//Game::G_SpawnEntitiesFromString();
}
} ;
// Internal doesn't lock the thread, as locking is impossible, due to executing this in the thread that holds the current lock
Game : : DB_EnumXAssets_Internal ( Game : : XAssetType : : ASSET_TYPE_CLIPMAP_PVS , callback , ents , true ) ;
Game : : DB_EnumXAssets_Internal ( Game : : XAssetType : : ASSET_TYPE_CLIPMAP , callback , ents , true ) ;
}
void Maps : : LoadAssetRestrict ( Game : : XAssetType type , Game : : XAssetHeader asset , std : : string name , bool * restrict )
{
if ( std : : find ( Maps : : CurrentDependencies . begin ( ) , Maps : : CurrentDependencies . end ( ) , FastFiles : : Current ( ) ) ! = Maps : : CurrentDependencies . end ( )
& & ( FastFiles : : Current ( ) ! = " mp_shipment_long " | | Maps : : CurrentMainZone ! = " mp_shipment " ) ) // Shipment is a special case
{
if ( type = = Game : : XAssetType : : ASSET_TYPE_CLIPMAP_PVS | | type = = Game : : XAssetType : : ASSET_TYPE_CLIPMAP | | type = = Game : : XAssetType : : ASSET_TYPE_GAMEWORLD_SP | | type = = Game : : XAssetType : : ASSET_TYPE_GAMEWORLD_MP | | type = = Game : : XAssetType : : ASSET_TYPE_GFXWORLD | | type = = Game : : XAssetType : : ASSET_TYPE_MAP_ENTS | | type = = Game : : XAssetType : : ASSET_TYPE_COMWORLD | | type = = Game : : XAssetType : : ASSET_TYPE_FX_MAP )
{
* restrict = true ;
return ;
}
}
if ( type = = Game : : XAssetType : : ASSET_TYPE_ADDON_MAP_ENTS )
{
* restrict = true ;
return ;
}
if ( type = = Game : : XAssetType : : ASSET_TYPE_WEAPON )
{
if ( ( ! strstr ( name . data ( ) , " _mp " ) & & name ! = " none " & & name ! = " destructible_car " ) | | Zones : : Version ( ) > = VERSION_ALPHA2 )
{
* restrict = true ;
return ;
}
}
if ( type = = Game : : XAssetType : : ASSET_TYPE_STRINGTABLE )
{
if ( FastFiles : : Current ( ) = = " mp_cross_fire " )
{
* restrict = true ;
return ;
}
}
if ( type = = Game : : XAssetType : : ASSET_TYPE_MAP_ENTS )
{
if ( Flags : : HasFlag ( " dump " ) )
{
Utils : : IO : : WriteFile ( Utils : : String : : VA ( " raw/%s.ents " , name ) , asset . mapEnts - > entityString ) ;
}
static std : : string mapEntities ;
FileSystem : : File ents ( name + " .ents " ) ;
if ( ents . exists ( ) )
{
mapEntities = ents . getBuffer ( ) ;
asset . mapEnts - > entityString = const_cast < char * > ( mapEntities . data ( ) ) ;
asset . mapEnts - > numEntityChars = mapEntities . size ( ) + 1 ;
}
// Apply new mapEnts
// This doesn't work, entities are spawned before the patch file is loaded
//Maps::OverrideMapEnts(asset.mapEnts);
}
// This is broken
if ( ( type = = Game : : XAssetType : : ASSET_TYPE_MENU | | type = = Game : : XAssetType : : ASSET_TYPE_MENULIST ) & & Zones : : Version ( ) > = 359 )
{
* restrict = true ;
return ;
}
}
Game : : G_GlassData * Maps : : GetWorldData ( )
{
if ( ! Utils : : String : : StartsWith ( Maps : : CurrentMainZone , " mp_ " ) | | Maps : : IsSPMap )
{
return Game : : DB_XAssetPool [ Game : : XAssetType : : ASSET_TYPE_GAMEWORLD_SP ] . gameWorldSp [ 0 ] . data ;
}
else
{
return Game : : DB_XAssetPool [ Game : : XAssetType : : ASSET_TYPE_GAMEWORLD_MP ] . gameWorldMp [ 0 ] . data ;
}
}
__declspec ( naked ) void Maps : : GetWorldDataStub ( )
{
__asm
{
push eax
pushad
call Maps : : GetWorldData
mov [ esp + 20 h ] , eax
popad
pop eax
retn
}
}
void Maps : : LoadRawSun ( )
{
Game : : R_FlushSun ( ) ;
Game : : GfxWorld * world = * reinterpret_cast < Game : : GfxWorld * * > ( 0x66DEE94 ) ;
if ( FileSystem : : File ( Utils : : String : : VA ( " sun/%s.sun " , Maps : : CurrentMainZone . data ( ) ) ) . exists ( ) )
{
Game : : R_LoadSunThroughDvars ( Maps : : CurrentMainZone . data ( ) , & world - > sun ) ;
}
}
void Maps : : GetBSPName ( char * buffer , size_t size , const char * format , const char * mapname )
{
if ( ! Utils : : String : : StartsWith ( mapname , " mp_ " ) & & ! Utils : : String : : StartsWith ( mapname , " zm_ " ) )
{
format = " maps/%s.d3dbsp " ;
}
// Redirect shipment to shipment long
if ( mapname = = " mp_shipment " s )
{
mapname = " mp_shipment_long " ;
}
_snprintf_s ( buffer , size , size , format , mapname ) ;
}
void Maps : : HandleAsSPMap ( )
{
Maps : : IsSPMap = true ;
}
void Maps : : AddDependency ( std : : string expression , std : : string zone )
{
// Test expression before adding it
try
{
std : : regex _ ( expression ) ;
}
catch ( const std : : exception e )
{
2017-01-20 16:41:03 -05:00
MessageBoxA ( nullptr , Utils : : String : : VA ( " Invalid regular expression: %s " , expression . data ( ) ) , " Warning " , MB_ICONEXCLAMATION ) ;
2017-01-16 11:42:50 -05:00
return ;
}
Maps : : DependencyList . push_back ( { expression , zone } ) ;
}
int Maps : : IgnoreEntityStub ( const char * entity )
{
return ( Utils : : String : : StartsWith ( entity , " dyn_ " ) | | Utils : : String : : StartsWith ( entity , " node_ " ) | | Utils : : String : : StartsWith ( entity , " actor_ " ) ) ;
}
std : : vector < std : : string > Maps : : GetDependenciesForMap ( std : : string map )
{
for ( int i = 0 ; i < * Game : : arenaCount ; + + i )
{
Game : : newMapArena_t * arena = & ArenaLength : : NewArenas [ i ] ;
if ( arena - > mapName = = map )
{
2017-01-27 08:43:52 -05:00
for ( int j = 0 ; j < ARRAYSIZE ( arena - > keys ) ; + + j )
2017-01-16 11:42:50 -05:00
{
if ( arena - > keys [ j ] = = " dependency " s )
{
return Utils : : String : : Explode ( arena - > values [ j ] , ' ' ) ;
}
}
}
}
return { } ;
}
std : : pair < std : : string , std : : string > Maps : : GetTeamsForMap ( std : : string map )
{
std : : string team_axis = " opforce_composite " ;
std : : string team_allies = " us_army " ;
for ( int i = 0 ; i < * Game : : arenaCount ; + + i )
{
Game : : newMapArena_t * arena = & ArenaLength : : NewArenas [ i ] ;
if ( arena - > mapName = = map )
{
2017-01-27 08:43:52 -05:00
for ( int j = 0 ; j < ARRAYSIZE ( arena - > keys ) ; + + j )
2017-01-16 11:42:50 -05:00
{
if ( arena - > keys [ j ] = = " allieschar " s )
{
team_allies = arena - > values [ j ] ;
}
else if ( arena - > keys [ j ] = = " axischar " s )
{
team_axis = arena - > values [ j ] ;
}
}
break ;
}
}
return { team_axis , team_allies } ;
}
# if defined(DEBUG) && defined(ENABLE_DXSDK)
// Credit to SE2Dev, as we shouldn't share the code, keep that in debug mode!
void Maps : : ExportMap ( Game : : GfxWorld * world )
{
Utils : : Memory : : Allocator allocator ;
if ( ! world ) return ;
Logger : : Print ( " Exporting '%s'... \n " , world - > baseName ) ;
std : : string mtl ;
mtl . append ( " # IW4x MTL File \n " ) ;
mtl . append ( " # Credit to SE2Dev for his D3DBSP Tool \n " ) ;
std : : string map ;
map . append ( " # Generated by IW4x \n " ) ;
map . append ( " # Credit to SE2Dev for his D3DBSP Tool \n " ) ;
map . append ( Utils : : String : : VA ( " o %s \n " , world - > baseName ) ) ;
map . append ( Utils : : String : : VA ( " mtllib %s.mtl \n \n " , world - > baseName ) ) ;
Logger : : Print ( " Writing vertices... \n " ) ;
for ( unsigned int i = 0 ; i < world - > draw . vertexCount ; + + i )
{
float x = world - > draw . vd . vertices [ i ] . xyz [ 1 ] ;
float y = world - > draw . vd . vertices [ i ] . xyz [ 2 ] ;
float z = world - > draw . vd . vertices [ i ] . xyz [ 0 ] ;
map . append ( Utils : : String : : VA ( " v %.6f %.6f %.6f \n " , x , y , z ) ) ;
}
map . append ( " \n " ) ;
Logger : : Print ( " Writing texture coordinates... \n " ) ;
for ( unsigned int i = 0 ; i < world - > draw . vertexCount ; + + i )
{
map . append ( Utils : : String : : VA ( " vt %.6f %.6f \n " , world - > draw . vd . vertices [ i ] . texCoord [ 0 ] , - world - > draw . vd . vertices [ i ] . texCoord [ 1 ] ) ) ;
}
Logger : : Print ( " Searching materials... \n " ) ;
int materialCount = 0 ;
Game : : Material * * materials = allocator . allocateArray < Game : : Material * > ( world - > dpvs . staticSurfaceCount ) ;
for ( unsigned int i = 0 ; i < world - > dpvs . staticSurfaceCount ; + + i )
{
bool isNewMat = true ;
for ( int j = 0 ; j < materialCount ; + + j )
{
if ( world - > dpvs . surfaces [ i ] . material = = materials [ j ] )
{
isNewMat = false ;
break ;
}
}
if ( isNewMat )
{
materials [ materialCount + + ] = world - > dpvs . surfaces [ i ] . material ;
}
}
Utils : : IO : : CreateDirectory ( Utils : : String : : VA ( " raw/mapdump/%s/textures " , world - > baseName ) ) ;
mtl . append ( Utils : : String : : VA ( " # Material Count: %d \n " , materialCount ) ) ;
Logger : : Print ( " Exporting materials and faces... \n " ) ;
for ( int m = 0 ; m < materialCount ; + + m )
{
std : : string name = materials [ m ] - > name ;
auto pos = name . find_last_of ( " / " ) ;
if ( pos ! = std : : string : : npos )
{
name = name . substr ( pos + 1 ) ;
}
map . append ( Utils : : String : : VA ( " \n usemtl %s \n " , name . data ( ) ) ) ;
map . append ( " s off \n " ) ;
Game : : GfxImage * image = materials [ m ] - > textureTable [ 0 ] . info . image ;
for ( char l = 0 ; l < materials [ m ] - > textureCount ; + + l )
{
if ( materials [ m ] - > textureTable [ l ] . nameStart = = ' c ' )
{
if ( materials [ m ] - > textureTable [ l ] . nameEnd = = ' p ' )
{
image = materials [ m ] - > textureTable [ l ] . info . image ; // Hopefully our colorMap
}
}
}
std : : string _name = Utils : : String : : VA ( " raw/mapdump/%s/textures/%s.png " , world - > baseName , image - > name ) ;
D3DXSaveTextureToFile ( std : : wstring ( _name . begin ( ) , _name . end ( ) ) . data ( ) , D3DXIFF_PNG , image - > map , NULL ) ;
mtl . append ( Utils : : String : : VA ( " \n newmtl %s \n " , name . data ( ) ) ) ;
mtl . append ( " Ka 1.0000 1.0000 1.0000 \n " ) ;
mtl . append ( " Kd 1.0000 1.0000 1.0000 \n " ) ;
mtl . append ( " illum 1 \n " ) ;
mtl . append ( Utils : : String : : VA ( " map_Ka textures/%s.png \n " , image - > name ) ) ;
mtl . append ( Utils : : String : : VA ( " map_Kd textures/%s.png \n " , image - > name ) ) ;
for ( unsigned int i = 0 ; i < world - > dpvs . staticSurfaceCount ; + + i )
{
if ( world - > dpvs . surfaces [ i ] . material ! = materials [ m ] )
continue ;
int vertOffset = world - > dpvs . surfaces [ i ] . tris . firstVertex + 1 ; //+1 cus obj starts at 1
int indexOffset = world - > dpvs . surfaces [ i ] . tris . baseIndex ;
for ( unsigned short j = 0 ; j < world - > dpvs . surfaces [ i ] . tris . triCount ; + + j )
{
int a = world - > draw . indices [ indexOffset + j * 3 + 0 ] + vertOffset ;
int b = world - > draw . indices [ indexOffset + j * 3 + 1 ] + vertOffset ;
int c = world - > draw . indices [ indexOffset + j * 3 + 2 ] + vertOffset ;
map . append ( Utils : : String : : VA ( " f %d/%d %d/%d %d/%d \n " , a , a , b , b , c , c ) ) ;
}
}
}
Logger : : Print ( " Writing final files... \n " ) ;
Utils : : IO : : WriteFile ( Utils : : String : : VA ( " raw/mapdump/%s/%s.mtl " , world - > baseName , world - > baseName ) , mtl ) ;
Utils : : IO : : WriteFile ( Utils : : String : : VA ( " raw/mapdump/%s/%s.obj " , world - > baseName , world - > baseName ) , map ) ;
}
# endif
void Maps : : AddDlc ( Maps : : DLC dlc )
{
for ( auto & pack : Maps : : DlcPacks )
{
if ( pack . index = = dlc . index )
{
pack . url = dlc . url ;
pack . maps = dlc . maps ;
Maps : : UpdateDlcStatus ( ) ;
return ;
}
}
Dvar : : Register < bool > ( Utils : : String : : VA ( " isDlcInstalled_%d " , dlc . index ) , false , Game : : DVAR_FLAG_USERCREATED | Game : : DVAR_FLAG_WRITEPROTECTED , " " ) ;
Maps : : DlcPacks . push_back ( dlc ) ;
Maps : : UpdateDlcStatus ( ) ;
}
void Maps : : UpdateDlcStatus ( )
{
bool hasAllDlcs = true ;
for ( auto & pack : Maps : : DlcPacks )
{
bool hasAllMaps = true ;
for ( auto map : pack . maps )
{
if ( ! FastFiles : : Exists ( map ) )
{
hasAllMaps = false ;
hasAllDlcs = false ;
break ;
}
}
Dvar : : Var ( Utils : : String : : VA ( " isDlcInstalled_%d " , pack . index ) ) . setRaw ( hasAllMaps ? 1 : 0 ) ;
}
Dvar : : Var ( " isDlcInstalled_All " ) . setRaw ( hasAllDlcs ? 1 : 0 ) ;
}
void Maps : : reallocateEntryPool ( )
{
AssertSize ( Game : : XAssetEntry , 16 ) ;
Maps : : EntryPool . clear ( ) ;
if ( ZoneBuilder : : IsEnabled ( ) )
{
Maps : : EntryPool . resize ( 1183968 ) ;
}
else
{
Maps : : EntryPool . resize ( 789312 ) ;
}
// Apply new size
Utils : : Hook : : Set < DWORD > ( 0x5BAEB0 , Maps : : EntryPool . size ( ) ) ;
// Apply new pool
Utils : : Hook : : Set < Game : : XAssetEntry * > ( 0x48E6F4 , Maps : : EntryPool . data ( ) ) ;
Utils : : Hook : : Set < Game : : XAssetEntry * > ( 0x4C67E4 , Maps : : EntryPool . data ( ) ) ;
Utils : : Hook : : Set < Game : : XAssetEntry * > ( 0x4C8584 , Maps : : EntryPool . data ( ) ) ;
Utils : : Hook : : Set < Game : : XAssetEntry * > ( 0x5BAEA8 , Maps : : EntryPool . data ( ) ) ;
Utils : : Hook : : Set < Game : : XAssetEntry * > ( 0x5BB0C4 , Maps : : EntryPool . data ( ) ) ;
Utils : : Hook : : Set < Game : : XAssetEntry * > ( 0x5BB0F5 , Maps : : EntryPool . data ( ) ) ;
Utils : : Hook : : Set < Game : : XAssetEntry * > ( 0x5BB1D4 , Maps : : EntryPool . data ( ) ) ;
Utils : : Hook : : Set < Game : : XAssetEntry * > ( 0x5BB235 , Maps : : EntryPool . data ( ) ) ;
Utils : : Hook : : Set < Game : : XAssetEntry * > ( 0x5BB278 , Maps : : EntryPool . data ( ) ) ;
Utils : : Hook : : Set < Game : : XAssetEntry * > ( 0x5BB34C , Maps : : EntryPool . data ( ) ) ;
Utils : : Hook : : Set < Game : : XAssetEntry * > ( 0x5BB484 , Maps : : EntryPool . data ( ) ) ;
Utils : : Hook : : Set < Game : : XAssetEntry * > ( 0x5BB570 , Maps : : EntryPool . data ( ) ) ;
Utils : : Hook : : Set < Game : : XAssetEntry * > ( 0x5BB6B7 , Maps : : EntryPool . data ( ) ) ;
Utils : : Hook : : Set < Game : : XAssetEntry * > ( 0x5BB844 , Maps : : EntryPool . data ( ) ) ;
Utils : : Hook : : Set < Game : : XAssetEntry * > ( 0x5BB98D , Maps : : EntryPool . data ( ) ) ;
Utils : : Hook : : Set < Game : : XAssetEntry * > ( 0x5BBA66 , Maps : : EntryPool . data ( ) ) ;
Utils : : Hook : : Set < Game : : XAssetEntry * > ( 0x5BBB8D , Maps : : EntryPool . data ( ) ) ;
Utils : : Hook : : Set < Game : : XAssetEntry * > ( 0x5BBCB1 , Maps : : EntryPool . data ( ) ) ;
Utils : : Hook : : Set < Game : : XAssetEntry * > ( 0x5BBD9B , Maps : : EntryPool . data ( ) ) ;
Utils : : Hook : : Set < Game : : XAssetEntry * > ( 0x5BBE4C , Maps : : EntryPool . data ( ) ) ;
Utils : : Hook : : Set < Game : : XAssetEntry * > ( 0x5BBF14 , Maps : : EntryPool . data ( ) ) ;
Utils : : Hook : : Set < Game : : XAssetEntry * > ( 0x5BBF54 , Maps : : EntryPool . data ( ) ) ;
Utils : : Hook : : Set < Game : : XAssetEntry * > ( 0x5BBFB8 , Maps : : EntryPool . data ( ) ) ;
Utils : : Hook : : Set < Game : : XAssetEntry * > ( 0x5BAE91 , Maps : : EntryPool . data ( ) + 1 ) ;
Utils : : Hook : : Set < Game : : XAssetEntry * > ( 0x5BAEA2 , Maps : : EntryPool . data ( ) + 1 ) ;
}
2017-01-29 12:27:11 -05:00
bool Maps : : CheckMapInstalled ( const char * mapname , bool error )
{
if ( FastFiles : : Exists ( mapname ) ) return true ;
if ( ! error ) return false ;
for ( auto & pack : Maps : : DlcPacks )
{
for ( auto map : pack . maps )
{
if ( map = = std : : string ( mapname ) )
{
if ( error ) Components : : Logger : : SoftError ( " Missing DLC pack %s (%d) containing map %s (%s). \n Please download it to play this map. " ,
pack . name . data ( ) , pack . index , Game : : UI_LocalizeMapName ( mapname ) , mapname ) ;
}
}
}
if ( error ) Components : : Logger : : SoftError ( " Missing map file %s. \n You may have a damaged installation or are attempting to load a non-existant map. " , mapname ) ;
return false ;
}
2017-01-16 11:42:50 -05:00
Maps : : Maps ( )
{
Dvar : : OnInit ( [ ] ( )
{
Dvar : : Register < bool > ( " isDlcInstalled_All " , false , Game : : DVAR_FLAG_USERCREATED | Game : : DVAR_FLAG_WRITEPROTECTED , " " ) ;
2017-01-29 12:27:11 -05:00
Maps : : AddDlc ( { 1 , " Stimulus Pack " , Utils : : Cache : : GetStaticUrl ( " /dlc/ " ) , { " mp_complex " , " mp_compact " , " mp_storm " , " mp_overgrown " , " mp_crash " } } ) ;
Maps : : AddDlc ( { 2 , " Resergence Pack " , Utils : : Cache : : GetStaticUrl ( " /dlc/ " ) , { " mp_abandon " , " mp_vacant " , " mp_trailerpark " , " mp_strike " , " mp_fuel2 " } } ) ;
Maps : : AddDlc ( { 3 , " Nuketown " , Utils : : Cache : : GetStaticUrl ( " /dlc/ " ) , { " mp_nuked " } } ) ;
Maps : : AddDlc ( { 4 , " Classics Pack " , Utils : : Cache : : GetStaticUrl ( " /dlc/ " ) , { " mp_cross_fire " , " mp_cargoship " , " mp_bloc " } } ) ;
Maps : : AddDlc ( { 5 , " Classics Pack " , Utils : : Cache : : GetStaticUrl ( " /dlc/ " ) , { " mp_killhouse " , " mp_bog_sh " } } ) ;
Maps : : AddDlc ( { 6 , " Freighter " , Utils : : Cache : : GetStaticUrl ( " /dlc/ " ) , { " mp_cargoship_sh " } } ) ;
Maps : : AddDlc ( { 7 , " Resurrection Pack " , Utils : : Cache : : GetStaticUrl ( " /dlc/ " ) , { " mp_shipment_long " , " mp_rust_long " , " mp_firingrange " } } ) ;
Maps : : AddDlc ( { 8 , " Recycled Pack " , Utils : : Cache : : GetStaticUrl ( " /dlc/ " ) , { " mp_bloc_sh " , " mp_crash_tropical " , " mp_estate_tropical " , " mp_fav_tropical " , " mp_storm_spring " } } ) ;
2017-01-16 11:42:50 -05:00
Maps : : UpdateDlcStatus ( ) ;
UIScript : : Add ( " downloadDLC " , [ ] ( UIScript : : Token token )
{
int dlc = token . get < int > ( ) ;
for ( auto pack : Maps : : DlcPacks )
{
if ( pack . index = = dlc )
{
2017-01-20 16:41:03 -05:00
ShellExecuteA ( nullptr , " open " , pack . url . data ( ) , nullptr , nullptr , SW_SHOWNORMAL ) ;
2017-01-16 11:42:50 -05:00
return ;
}
}
Game : : MessageBox ( Utils : : String : : VA ( " DLC %d does not exist! " , dlc ) , " ERROR " ) ;
} ) ;
} ) ;
// Restrict asset loading
AssetHandler : : OnLoad ( Maps : : LoadAssetRestrict ) ;
// hunk size (was 300 MiB)
Utils : : Hook : : Set < DWORD > ( 0x64A029 , 0x1C200000 ) ; // 450 MiB
Utils : : Hook : : Set < DWORD > ( 0x64A057 , 0x1C200000 ) ;
# if DEBUG
// Hunk debugging
Utils : : Hook : : Set < BYTE > ( 0x4FF57B , 0xCC ) ;
Utils : : Hook : : Nop ( 0x4FF57C , 4 ) ;
# endif
// Intercept BSP name resolving
Utils : : Hook ( 0x4C5979 , Maps : : GetBSPName , HOOK_CALL ) . install ( ) - > quick ( ) ;
// Intercept map zone loading
Utils : : Hook ( 0x42C2AF , Maps : : LoadMapZones , HOOK_CALL ) . install ( ) - > quick ( ) ;
// Ignore SP entities
Utils : : Hook ( 0x444810 , Maps : : IgnoreEntityStub , HOOK_JUMP ) . install ( ) - > quick ( ) ;
// WorldData pointer replacement
Utils : : Hook ( 0x4D90B6 , Maps : : GetWorldDataStub , HOOK_CALL ) . install ( ) - > quick ( ) ;
// Allow loading raw suns
Utils : : Hook ( 0x51B46A , Maps : : LoadRawSun , HOOK_CALL ) . install ( ) - > quick ( ) ;
Game : : ReallocateAssetPool ( Game : : XAssetType : : ASSET_TYPE_GAMEWORLD_SP , 1 ) ;
Game : : ReallocateAssetPool ( Game : : XAssetType : : ASSET_TYPE_IMAGE , 7168 ) ;
Game : : ReallocateAssetPool ( Game : : XAssetType : : ASSET_TYPE_LOADED_SOUND , 2700 ) ;
Game : : ReallocateAssetPool ( Game : : XAssetType : : ASSET_TYPE_FX , 1200 ) ;
Game : : ReallocateAssetPool ( Game : : XAssetType : : ASSET_TYPE_LOCALIZE_ENTRY , 14000 ) ;
Game : : ReallocateAssetPool ( Game : : XAssetType : : ASSET_TYPE_XANIMPARTS , 8192 ) ;
Game : : ReallocateAssetPool ( Game : : XAssetType : : ASSET_TYPE_XMODEL , 5125 ) ;
Game : : ReallocateAssetPool ( Game : : XAssetType : : ASSET_TYPE_PHYSPRESET , 128 ) ;
Game : : ReallocateAssetPool ( Game : : XAssetType : : ASSET_TYPE_PIXELSHADER , 10000 ) ;
Game : : ReallocateAssetPool ( Game : : XAssetType : : ASSET_TYPE_VERTEXSHADER , 3072 ) ;
Game : : ReallocateAssetPool ( Game : : XAssetType : : ASSET_TYPE_MATERIAL , 8192 ) ;
Game : : ReallocateAssetPool ( Game : : XAssetType : : ASSET_TYPE_VERTEXDECL , 196 ) ;
Game : : ReallocateAssetPool ( Game : : XAssetType : : ASSET_TYPE_WEAPON , 2400 ) ;
Game : : ReallocateAssetPool ( Game : : XAssetType : : ASSET_TYPE_STRINGTABLE , 800 ) ;
Game : : ReallocateAssetPool ( Game : : XAssetType : : ASSET_TYPE_IMPACT_FX , 8 ) ;
this - > reallocateEntryPool ( ) ;
// Dependencies
//Maps::AddDependency("oilrig", "mp_subbase");
//Maps::AddDependency("gulag", "mp_subbase");
//Maps::AddDependency("invasion", "mp_rust");
//Maps::AddDependency("co_hunted", "mp_storm");
//Maps::AddDependency("mp_shipment", "mp_shipment_long");
# if defined(DEBUG) && defined(ENABLE_DXSDK)
Command : : Add ( " dumpmap " , [ ] ( Command : : Params * )
{
if ( Dedicated : : IsEnabled ( ) | | ZoneBuilder : : IsEnabled ( ) )
{
Logger : : Print ( " DirectX needs to be enabled, please start a client to use this command! \n " ) ;
return ;
}
Game : : GfxWorld * world = nullptr ;
Game : : DB_EnumXAssets ( Game : : XAssetType : : ASSET_TYPE_GFXWORLD , [ ] ( Game : : XAssetHeader header , void * world )
{
* reinterpret_cast < Game : : GfxWorld * * > ( world ) = header . gfxWorld ;
} , & world , false ) ;
if ( world )
{
Maps : : ExportMap ( world ) ;
Logger : : Print ( " Map '%s' exported! \n " , world - > baseName ) ;
}
else
{
Logger : : Print ( " No map loaded, unable to dump anything! \n " ) ;
}
} ) ;
# endif
}
Maps : : ~ Maps ( )
{
Maps : : DlcPacks . clear ( ) ;
Maps : : DependencyList . clear ( ) ;
Maps : : CurrentMainZone . clear ( ) ;
Maps : : CurrentDependencies . clear ( ) ;
Maps : : EntryPool . clear ( ) ;
}
}