@@ -30,8 +30,6 @@ public Global(string path, PAK2 animPAK)
3030 /// </summary>
3131 public class Level
3232 {
33- public string Name ;
34-
3533 public Textures Textures ;
3634 public Shaders Shaders ;
3735 public Collisions WeightedCollisions ;
@@ -71,6 +69,18 @@ public class State
7169
7270 public Dictionary < string , Dictionary < string , TextDB > > Strings ;
7371
72+ public Global Global => _global ;
73+ private Global _global ;
74+
75+ public string Filepath => _filepath ;
76+ private string _filepath = "" ;
77+
78+ public string Name => _name ;
79+ private string _name = "" ;
80+
81+ public bool Patched => _patched ;
82+ private bool _patched = false ;
83+
7484 /// <summary>
7585 /// Triggered every time one of the files within the level loads.
7686 /// Keep a count of this and divide it by NumberOfTicks to get a loading percentage.
@@ -85,18 +95,15 @@ public class State
8595
8696 public const int NumberOfTicks = 30 ;
8797
88- private Global _global ;
89- private string _path ;
90-
9198 /// <summary>
9299 /// A container for data related to a level in the game's "ENV" folder
93100 /// </summary>
94101 public Level ( string path , Global global , bool loadImmediately = true )
95102 {
96- _path = path ;
97103 _global = global ;
98-
99- Name = _path . ToUpper ( ) . Replace ( "\\ " , "/" ) . Split ( new string [ ] { "DATA/ENV/" } , StringSplitOptions . None ) [ 1 ] . TrimEnd ( '/' ) ;
104+ _filepath = path . Replace ( "\\ " , "/" ) . TrimEnd ( '/' ) . ToUpper ( ) ;
105+ _name = _filepath . Split ( new string [ ] { "DATA/ENV/" } , StringSplitOptions . None ) [ 1 ] ;
106+ _patched = ( Name == "PRODUCTION/DLC/BSPNOSTROMO_RIPLEY" || Name == "PRODUCTION/DLC/BSPNOSTROMO_TWOTEAMS" ) && Directory . Exists ( _filepath + "_PATCH" ) ;
100107
101108 if ( loadImmediately )
102109 Load ( ) ;
@@ -112,44 +119,47 @@ public void Load()
112119 if ( _global ? . AnimationStrings_Debug == null )
113120 throw new Exception ( "Missing Global Animation Strings" ) ;
114121
122+ string renderable = _filepath + "/RENDERABLE/" ;
123+ string world = _filepath + ( _patched ? "_PATCH" : "" ) + "/WORLD/" ;
124+
115125 Parallel . Invoke (
116- ( ) => { Textures = new Textures ( _path + "/RENDERABLE/ LEVEL_TEXTURES.ALL.PAK" ) ; OnLoadTick ? . Invoke ( ) ; } ,
117- ( ) => { Shaders = new Shaders ( _path + "/RENDERABLE/ LEVEL_SHADERS_DX11.PAK" ) ; OnLoadTick ? . Invoke ( ) ; } ,
118- ( ) => { WeightedCollisions = new Collisions ( _path + "/WORLD/ COLLISION.BIN" ) ; OnLoadTick ? . Invoke ( ) ; } ,
119- ( ) => { MorphTargetDB = new MorphTargets ( _path + "/WORLD/ MORPH_TARGET_DB.BIN" ) ; OnLoadTick ? . Invoke ( ) ; } ,
120- ( ) => { Resources = new Resources ( _path + "/WORLD/ RESOURCES.BIN" ) ; OnLoadTick ? . Invoke ( ) ; } ,
121- ( ) => { MaterialMaps = new MaterialMappings ( _path + "/WORLD/ MATERIAL_MAPPINGS.PAK" ) ; OnLoadTick ? . Invoke ( ) ; }
126+ ( ) => { Textures = new Textures ( renderable + "LEVEL_TEXTURES.ALL.PAK" ) ; OnLoadTick ? . Invoke ( ) ; } ,
127+ ( ) => { Shaders = new Shaders ( renderable + "LEVEL_SHADERS_DX11.PAK" ) ; OnLoadTick ? . Invoke ( ) ; } ,
128+ ( ) => { WeightedCollisions = new Collisions ( world + "COLLISION.BIN" ) ; OnLoadTick ? . Invoke ( ) ; } ,
129+ ( ) => { MorphTargetDB = new MorphTargets ( world + "MORPH_TARGET_DB.BIN" ) ; OnLoadTick ? . Invoke ( ) ; } ,
130+ ( ) => { Resources = new Resources ( world + "RESOURCES.BIN" ) ; OnLoadTick ? . Invoke ( ) ; } ,
131+ ( ) => { MaterialMaps = new MaterialMappings ( world + "MATERIAL_MAPPINGS.PAK" ) ; OnLoadTick ? . Invoke ( ) ; }
122132 ) ;
123133
124- Materials = new Materials ( _path + "/RENDERABLE/ LEVEL_MODELS.MTL" , _global . Textures , Textures , Shaders ) ; OnLoadTick ? . Invoke ( ) ;
125- Models = new Models ( _path + "/RENDERABLE/ LEVEL_MODELS.PAK" , Materials , WeightedCollisions , MorphTargetDB ) ; OnLoadTick ? . Invoke ( ) ;
126- RenderableElements = new RenderableElements ( _path + "/WORLD/ REDS.BIN" , Models , Materials ) ; OnLoadTick ? . Invoke ( ) ;
127- Movers = new Movers ( _path + "/WORLD/ MODELS.MVR" , RenderableElements , Resources ) ; OnLoadTick ? . Invoke ( ) ;
134+ Materials = new Materials ( renderable + "LEVEL_MODELS.MTL" , _global . Textures , Textures , Shaders ) ; OnLoadTick ? . Invoke ( ) ;
135+ Models = new Models ( renderable + "LEVEL_MODELS.PAK" , Materials , WeightedCollisions , MorphTargetDB ) ; OnLoadTick ? . Invoke ( ) ;
136+ RenderableElements = new RenderableElements ( world + "REDS.BIN" , Models , Materials ) ; OnLoadTick ? . Invoke ( ) ;
137+ Movers = new Movers ( world + "MODELS.MVR" , RenderableElements , Resources ) ; OnLoadTick ? . Invoke ( ) ;
128138
129139 Parallel . Invoke (
130- ( ) => { EnvironmentMaps = new EnvironmentMaps ( _path + "/WORLD/ ENVIRONMENTMAP.BIN" , Movers ) ; OnLoadTick ? . Invoke ( ) ; } ,
131- ( ) => { PathBarrierResources = new PathBarrierResources ( _path + "/WORLD/ PATH_BARRIER_RESOURCES" , Resources ) ; OnLoadTick ? . Invoke ( ) ; } ,
132- ( ) => { SoundFlashModels = new SoundFlashModels ( _path + "/WORLD/ SOUNDFLASHMODELS.DAT" , _global . Textures , Textures ) ; OnLoadTick ? . Invoke ( ) ; } ,
133- ( ) => { CollisionMaps = new CollisionMaps ( _path + "/WORLD/ COLLISION.MAP" , Materials , MaterialMaps ) ; OnLoadTick ? . Invoke ( ) ; }
140+ ( ) => { EnvironmentMaps = new EnvironmentMaps ( world + "ENVIRONMENTMAP.BIN" , Movers ) ; OnLoadTick ? . Invoke ( ) ; } ,
141+ ( ) => { PathBarrierResources = new PathBarrierResources ( world + "PATH_BARRIER_RESOURCES" , Resources ) ; OnLoadTick ? . Invoke ( ) ; } ,
142+ ( ) => { SoundFlashModels = new SoundFlashModels ( world + "SOUNDFLASHMODELS.DAT" , _global . Textures , Textures ) ; OnLoadTick ? . Invoke ( ) ; } ,
143+ ( ) => { CollisionMaps = new CollisionMaps ( world + "COLLISION.MAP" , Materials , MaterialMaps ) ; OnLoadTick ? . Invoke ( ) ; }
134144 ) ;
135145
136146 Parallel . Invoke (
137- ( ) => { RadInstanceMap = new RadiosityInstanceMap ( _path + "/RENDERABLE/ RADIOSITY_INSTANCE_MAP.TXT" ) ; OnLoadTick ? . Invoke ( ) ; } ,
138- ( ) => { AlphaLight = new AlphaLightLevel ( _path + "/WORLD/ ALPHALIGHT_LEVEL.BIN" ) ; OnLoadTick ? . Invoke ( ) ; } ,
139- ( ) => { AccessorySets = new CharacterAccessorySets ( _path + "/WORLD/ CHARACTERACCESSORYSETS.BIN" ) ; OnLoadTick ? . Invoke ( ) ; } ,
140- ( ) => { EnvironmentAnimations = new EnvironmentAnimations ( _path + "/WORLD/ ENVIRONMENT_ANIMATION.DAT" , _global . AnimationStrings_Debug ) ; OnLoadTick ? . Invoke ( ) ; } ,
141- ( ) => { Lights = new Lights ( _path + "/WORLD/ LIGHTS.BIN" ) ; OnLoadTick ? . Invoke ( ) ; } ,
142- ( ) => { MaterialMappings = new MaterialMappings ( _path + "/WORLD/ MATERIAL_MAPPINGS.PAK" ) ; OnLoadTick ? . Invoke ( ) ; } ,
143- ( ) => { PhysicsMaps = new PhysicsMaps ( _path + "/WORLD/ PHYSICS.MAP" ) ; OnLoadTick ? . Invoke ( ) ; } ,
144- ( ) => { SoundNodeNetwork = new SoundNodeNetwork ( _path + "/WORLD/ SNDNODENETWORK.DAT" ) ; OnLoadTick ? . Invoke ( ) ; } ,
145- ( ) => { SoundBankData = new SoundBankData ( _path + "/WORLD/ SOUNDBANKDATA.DAT" ) ; OnLoadTick ? . Invoke ( ) ; } ,
146- ( ) => { SoundDialogueLookups = new SoundDialogueLookups ( _path + "/WORLD/ SOUNDDIALOGUELOOKUPS.DAT" ) ; OnLoadTick ? . Invoke ( ) ; } ,
147- ( ) => { SoundEnvironmentData = new SoundEnvironmentData ( _path + "/WORLD/ SOUNDENVIRONMENTDATA.DAT" ) ; OnLoadTick ? . Invoke ( ) ; } ,
148- ( ) => { SoundEventData = new SoundEventData ( _path + "/WORLD/ SOUNDEVENTDATA.DAT" ) ; OnLoadTick ? . Invoke ( ) ; } ,
149- ( ) => { SoundLoadZones = new SoundLoadZones ( _path + "/WORLD/ SOUNDLOADZONES.DAT" ) ; OnLoadTick ? . Invoke ( ) ; }
147+ ( ) => { RadInstanceMap = new RadiosityInstanceMap ( renderable + "RADIOSITY_INSTANCE_MAP.TXT" ) ; OnLoadTick ? . Invoke ( ) ; } ,
148+ ( ) => { AlphaLight = new AlphaLightLevel ( world + "ALPHALIGHT_LEVEL.BIN" ) ; OnLoadTick ? . Invoke ( ) ; } ,
149+ ( ) => { AccessorySets = new CharacterAccessorySets ( world + "CHARACTERACCESSORYSETS.BIN" ) ; OnLoadTick ? . Invoke ( ) ; } ,
150+ ( ) => { EnvironmentAnimations = new EnvironmentAnimations ( world + "ENVIRONMENT_ANIMATION.DAT" , _global . AnimationStrings_Debug ) ; OnLoadTick ? . Invoke ( ) ; } ,
151+ ( ) => { Lights = new Lights ( world + "LIGHTS.BIN" ) ; OnLoadTick ? . Invoke ( ) ; } ,
152+ ( ) => { MaterialMappings = new MaterialMappings ( world + "MATERIAL_MAPPINGS.PAK" ) ; OnLoadTick ? . Invoke ( ) ; } ,
153+ ( ) => { PhysicsMaps = new PhysicsMaps ( world + "PHYSICS.MAP" ) ; OnLoadTick ? . Invoke ( ) ; } ,
154+ ( ) => { SoundNodeNetwork = new SoundNodeNetwork ( world + "SNDNODENETWORK.DAT" ) ; OnLoadTick ? . Invoke ( ) ; } ,
155+ ( ) => { SoundBankData = new SoundBankData ( world + "SOUNDBANKDATA.DAT" ) ; OnLoadTick ? . Invoke ( ) ; } ,
156+ ( ) => { SoundDialogueLookups = new SoundDialogueLookups ( world + "SOUNDDIALOGUELOOKUPS.DAT" ) ; OnLoadTick ? . Invoke ( ) ; } ,
157+ ( ) => { SoundEnvironmentData = new SoundEnvironmentData ( world + "SOUNDENVIRONMENTDATA.DAT" ) ; OnLoadTick ? . Invoke ( ) ; } ,
158+ ( ) => { SoundEventData = new SoundEventData ( world + "SOUNDEVENTDATA.DAT" ) ; OnLoadTick ? . Invoke ( ) ; } ,
159+ ( ) => { SoundLoadZones = new SoundLoadZones ( world + "SOUNDLOADZONES.DAT" ) ; OnLoadTick ? . Invoke ( ) ; }
150160 ) ;
151161
152- Commands = new Commands ( _path + "/WORLD/ COMMANDS" + ( File . Exists ( _path + "/WORLD/ COMMANDS.PAK" ) ? ".PAK" : ".BIN" ) , EnvironmentAnimations , CollisionMaps , RenderableElements ) ; OnLoadTick ? . Invoke ( ) ;
162+ Commands = new Commands ( world + "COMMANDS" + ( File . Exists ( world + "COMMANDS.PAK" ) ? ".PAK" : ".BIN" ) , EnvironmentAnimations , CollisionMaps , RenderableElements ) ; OnLoadTick ? . Invoke ( ) ;
153163
154164 //RENDERABLE/DAMAGE/*
155165 //RENDERABLE/GALAXY/*
@@ -158,15 +168,14 @@ public void Load()
158168 //WORLD/COLLISION.HKX
159169 //WORLD/COLLISION.HKX64
160170 //WORLD/CUTSCENE_DIRECTOR_DATA.BIN
161- //WORLD/EXCLUSIVE_MASTER_RESOURCE_INDICES (loaded below)
162171 //WORLD/LEVEL.STR
163172 //WORLD/OCCLUDER_TRIANGLE_BVH.BIN
164173 //WORLD/PHYSICS.HKX
165174 //WORLD/PHYSICS.HKX64
166175 //WORLD/RADIOSITY_COLLISION_MAPPING.BIN
167176
168177 int stateCount = 1 ; // we always implicitly have one state (the default state: state zero)
169- using ( BinaryReader reader = new BinaryReader ( File . OpenRead ( _path + "/WORLD/ EXCLUSIVE_MASTER_RESOURCE_INDICES" ) ) )
178+ using ( BinaryReader reader = new BinaryReader ( File . OpenRead ( world + "EXCLUSIVE_MASTER_RESOURCE_INDICES" ) ) )
170179 {
171180 reader . BaseStream . Position = 4 ; // version: 1
172181 int states = reader . ReadInt32 ( ) ; // number of changeable states
@@ -179,7 +188,7 @@ public void Load()
179188 }
180189 for ( int i = 0 ; i < stateCount ; i ++ )
181190 {
182- string statePath = _path + "/WORLD/ STATE_" + i + "/" ;
191+ string statePath = world + "STATE_" + i + "/" ;
183192
184193 State state = new State ( ) { Index = i } ;
185194 //ASSAULT_POSITIONS
@@ -191,8 +200,8 @@ public void Load()
191200 }
192201 OnLoadTick ? . Invoke ( ) ;
193202
194- string pathDATA = _path . Replace ( '\\ ' , '/' ) . Split ( new string [ ] { "/DATA/ENV" } , StringSplitOptions . None ) [ 0 ] + "/DATA" ;
195- string levelName = Directory . GetParent ( _path ) . Name ;
203+ string pathDATA = _filepath . Replace ( '\\ ' , '/' ) . Split ( new string [ ] { "/DATA/ENV" } , StringSplitOptions . None ) [ 0 ] + "/DATA" ;
204+ string levelName = Directory . GetParent ( _filepath ) . Name ;
196205 XmlNodeList textDBsGlobal = new BML ( pathDATA + "/LEVEL_TEXT_DATABASES.BML" ) . Content . SelectNodes ( "//level_text_databases/level" ) ;
197206 List < string > globalDBs = new List < string > ( ) ;
198207 for ( int i = 0 ; i < textDBsGlobal . Count ; i ++ )
@@ -201,12 +210,12 @@ public void Load()
201210 globalDBs . Add ( textDBsGlobal [ i ] . ChildNodes [ x ] . Attributes [ "name" ] . Value ) ;
202211 List < string > textList = Directory . GetFiles ( pathDATA + "/TEXT/" , "*.TXT" , SearchOption . AllDirectories ) . ToList < string > ( ) ;
203212 List < string > levelDBs = new List < string > ( ) ;
204- if ( File . Exists ( _path + "/TEXT/TEXT_DB_LIST.TXT" ) )
213+ if ( File . Exists ( _filepath + "/TEXT/TEXT_DB_LIST.TXT" ) )
205214 {
206- string [ ] textDBsLevel = File . ReadAllLines ( _path + "/TEXT/TEXT_DB_LIST.TXT" ) ;
215+ string [ ] textDBsLevel = File . ReadAllLines ( _filepath + "/TEXT/TEXT_DB_LIST.TXT" ) ;
207216 for ( int i = 0 ; i < textDBsLevel . Length ; i ++ )
208217 levelDBs . Add ( textDBsLevel [ i ] ) ;
209- textList . AddRange ( Directory . GetFiles ( _path + "/TEXT/" , "*.TXT" , SearchOption . AllDirectories ) ) ;
218+ textList . AddRange ( Directory . GetFiles ( _filepath + "/TEXT/" , "*.TXT" , SearchOption . AllDirectories ) ) ;
210219 }
211220 textList . Reverse ( ) ;
212221 Strings = new Dictionary < string , Dictionary < string , TextDB > > ( ) ;
@@ -300,7 +309,7 @@ public void ImportFromGlobal()
300309 /// <summary>
301310 /// Get all levels available within the ENV folder. Pass the path to the folder that contains AI.exe.
302311 /// </summary>
303- public static List < string > GetLevels ( string gameDirectory , bool swapNostromoForPatch = false )
312+ public static List < string > GetLevels ( string gameDirectory )
304313 {
305314 string [ ] galaxyBins = Directory . GetFiles ( gameDirectory + "/DATA/ENV/" , "GALAXY.DEFINITION_BIN" , SearchOption . AllDirectories ) ;
306315 List < string > mapList = new List < string > ( ) ;
@@ -320,9 +329,7 @@ public static List<string> GetLevels(string gameDirectory, bool swapNostromoForP
320329 int length = file . Length - extraLength ;
321330 if ( length <= 0 ) continue ;
322331
323- string mapName = file . Substring ( 0 , length ) . ToUpper ( ) ;
324- if ( swapNostromoForPatch && ( mapName == "DLC/BSPNOSTROMO_RIPLEY" || mapName == "DLC/BSPNOSTROMO_TWOTEAMS" ) ) mapName += "_PATCH" ;
325- mapList . Add ( mapName . ToUpper ( ) ) ;
332+ mapList . Add ( file . Substring ( 0 , length ) . ToUpper ( ) ) ;
326333 }
327334 return mapList ;
328335 }
0 commit comments