From c605983f04072752bc7cbb44efbfe4391ec3152b Mon Sep 17 00:00:00 2001 From: lahm86 <33758420+lahm86@users.noreply.github.com> Date: Mon, 11 Oct 2021 19:45:48 +0100 Subject: [PATCH 1/3] #219 Initial TR3 Support - Merged updates from TRGE for TR3 support. - Introduced TR3LevelNames and updated previous LevelNames with TR2LevelNames. - The Resources folder has been restructured so there will now be a folder for each TR version. Locations and restrictions now also have their own folder. - FDUtilities updated to allow removing entity triggers for TR3Level. - Solution and projects have all been renamed to TR... rather than TR2... - TR2LevelRandomizer has been removed and in place are now TR2RandoEditor and TR3RandoEditor. These are initialised based on the current TR version. - All rando settings are now stored in RandomizerSettings and this is passed as a whole to each randomizer rather havng to duplicate variables. - Refactored LevelProcessor to allow generics, so we can define one for each version. There will be a base randomizer for each version that extends the relevant LevelProcessor, and then each randomizer extends that. - All current randomizers are now TR2 specific (explicit in their names). The idea is we can work out the shared logic when it comes to each version and look at potential utility classes. Some randomizers (e.g. EnemyRandomizer) are hugely specific to each level so this avoids having bloated classes that cover all versions. - TRRandomizerController now allows determining what randomizer types are available for the current version (so currently everything is available for TR2, but only scripting aspects for TR3). - UI updated to remove specific references to TR2 (main title, dialog titles etc). - The UI will grey out options that are not currently supported for the opened TR version. - The default UI settings such as unarmed level count, ammoless count are now retrieved from the core rather than being hard-coded. --- Deps/TRGE.Coord.dll | Bin 1617920 -> 1620992 bytes Deps/TRGE.Core.dll | Bin 125952 -> 128000 bytes TR2Randomizer/MainWindow.xaml.cs | 4 +- TR2Randomizer/Randomizers/EnemyRandomizer.cs | 4 +- TR2Randomizer/Randomizers/ItemRandomizer.cs | 8 +- TR2Randomizer/Randomizers/RandomizerBase.cs | 2 +- TR2Randomizer/Utilities/RoomWaterUtilities.cs | 36 +- .../Processors/LevelProcessor.cs | 152 --- .../Randomizers/RandomizerBase.cs | 12 - .../Randomizers/TR2LevelRandomizer.cs | 511 -------- TR2RandomizerCore/TR2RandomizerCore.csproj | 107 -- TR2RandomizerView/Model/ProfileString.cs | 316 ----- TREnvironmentEditor/EMEditorMapping.cs | 3 +- TRFDControl/Utilities/FDUtilities.cs | 51 +- .../TR2LevelNames.cs} | 10 +- .../Helpers/LevelNames/TR3LevelNames.cs | 104 ++ TRLevelReader/Helpers/TR2EntityUtilities.cs | 104 +- .../Utilities/MassTRModelExporter.cs | 38 +- .../Utilities/MassTRTextureDeduplicator.cs | 4 +- TR2Randomizer.sln => TRRandomizer.sln | 6 +- TRRandomizerCore/Editors/ISettingsProvider.cs | 7 + .../Editors/RandomizerSettings.cs | 287 +++++ TRRandomizerCore/Editors/TR2RandoEditor.cs | 245 ++++ TRRandomizerCore/Editors/TR3RandoEditor.cs | 57 + .../Globalisation/G11N.cs | 6 +- .../Globalisation/GameStrings.cs | 2 +- .../Globalisation/GlobalStrings.cs | 2 +- .../Globalisation/Language.cs | 2 +- .../Globalisation/LevelStrings.cs | 2 +- .../Helpers/CollectionExtensions.cs | 2 +- .../Helpers/Difficulty.cs | 2 +- .../Helpers/EnemyDifficulty.cs | 2 +- .../Helpers/ItemDifficulty.cs | 2 +- .../Helpers/LandmarkImporter.cs | 8 +- .../Helpers/Location.cs | 2 +- .../Helpers/MeshEditor.cs | 2 +- .../Helpers/ModificationStamp.cs | 2 +- .../Helpers/RandoDifficulty.cs | 2 +- .../Helpers/TROpenRestoreEventArgs.cs | 2 +- .../Helpers/TRRandomizationCategory.cs | 2 +- .../Helpers/TRRandomizationEventArgs.cs | 2 +- .../Levels}/TR2CombinedLevel.cs | 8 +- .../Levels}/TR2LevelTextureWeightComparer.cs | 2 +- TRRandomizerCore/Levels/TR3CombinedLevel.cs | 64 + .../Processors/AbstractLevelProcessor.cs | 105 ++ .../Processors/AbstractProcessorThread.cs | 4 +- .../Processors/ILevelProcessor.cs | 10 + .../Processors/TR2/TR2LevelProcessor.cs | 75 ++ .../Processors/TR2/TR2ModelAdjuster.cs | 6 +- .../Processors/TR2/TR2TextureDeduplicator.cs | 12 +- .../Processors/TR3/TR3LevelProcessor.cs | 75 ++ .../Randomizers/IRandomizer.cs | 2 +- .../Randomizers/TR2/BaseTR2Randomizer.cs | 16 + .../Randomizers/TR2/TR2AudioRandomizer.cs | 30 +- .../Randomizers/TR2/TR2EnemyRandomizer.cs | 82 +- .../TR2/TR2EnvironmentRandomizer.cs | 34 +- .../TR2/TR2GameStringRandomizer.cs | 32 +- .../Randomizers/TR2/TR2ItemRandomizer.cs | 50 +- .../Randomizers/TR2/TR2NightModeRandomizer.cs | 27 +- .../Randomizers/TR2/TR2OutfitRandomizer.cs | 51 +- .../Randomizers/TR2/TR2SecretRandomizer.cs | 47 +- .../TR2/TR2StartPositionRandomizer.cs | 23 +- .../Randomizers/TR2/TR2TextureRandomizer.cs | 32 +- .../Randomizers/TR3/BaseTR3Randomizer.cs | 15 + .../Resources/Documentation/ENEMIES.md | 0 .../Resources/Documentation/ORDER.md | 0 .../Resources/TR2/Audio/audio_tracks.json | 0 .../Resources/TR2/Audio/sfx.json | 0 .../Environment/ASSAULT.TR2-Environment.json | 0 .../Environment/BOAT.TR2-Environment.json | 0 .../Environment/CATACOMB.TR2-Environment.json | 0 .../Environment/DECK.TR2-Environment.json | 0 .../Environment/EMPRTOMB.TR2-Environment.json | 0 .../Environment/FLOATING.TR2-Environment.json | 0 .../Environment/HOUSE.TR2-Environment.json | 0 .../Environment/ICECAVE.TR2-Environment.json | 0 .../Environment/KEEL.TR2-Environment.json | 0 .../Environment/LIVING.TR2-Environment.json | 0 .../Environment/MONASTRY.TR2-Environment.json | 0 .../Environment/OPERA.TR2-Environment.json | 0 .../Environment/PLATFORM.TR2-Environment.json | 0 .../TR2}/Environment/RIG.TR2-Environment.json | 0 .../Environment/SKIDOO.TR2-Environment.json | 0 .../Environment/UNWATER.TR2-Environment.json | 0 .../Environment/VENICE.TR2-Environment.json | 0 .../Environment/WALL.TR2-Environment.json | 0 .../Environment/XIAN.TR2-Environment.json | 0 .../TR2/Locations}/item_locations.json | 0 .../Resources/TR2/Locations}/locations.json | 0 .../TR2/Locations}/start_positions.json | 0 .../TR2/Locations}/unarmed_locations.json | 0 .../TR2/Locations}/vehicle_locations.json | 0 .../TR2}/Models/BarracudaIce/Data.json | 0 .../TR2}/Models/BarracudaIce/Segments.png | Bin .../TR2}/Models/BarracudaUnwater/Data.json | 0 .../TR2}/Models/BarracudaUnwater/Segments.png | Bin .../TR2}/Models/BarracudaXian/Data.json | 0 .../TR2}/Models/BarracudaXian/Segments.png | Bin .../TR2}/Models/BengalTiger/Data.json | 0 .../TR2}/Models/BengalTiger/Segments.png | Bin .../TR2}/Models/BirdMonster/Data.json | 0 .../TR2}/Models/BirdMonster/Segments.png | Bin .../TR2}/Models/BlackMorayEel/Data.json | 0 .../TR2}/Models/BlackMorayEel/Segments.png | Bin .../TR2}/Models/BlackSnowmob/Data.json | 0 .../TR2}/Models/BlackSnowmob/Segments.png | Bin .../Resources/TR2}/Models/Boat/Data.json | 0 .../Resources/TR2}/Models/Boat/Segments.png | Bin .../Resources/TR2}/Models/Crow/Data.json | 0 .../Resources/TR2}/Models/Crow/Segments.png | Bin .../Resources/TR2}/Models/Doberman/Data.json | 0 .../TR2}/Models/Doberman/Segments.png | Bin .../TR2}/Models/DragonBack_H/Data.json | 0 .../TR2}/Models/DragonBack_H/Segments.png | Bin .../TR2}/Models/DragonBonesBack_H/Data.json | 0 .../Models/DragonBonesBack_H/Segments.png | Bin .../TR2}/Models/DragonBonesFront_H/Data.json | 0 .../Models/DragonBonesFront_H/Segments.png | Bin .../TR2}/Models/DragonExplosion1_H/Data.json | 0 .../Models/DragonExplosion1_H/Segments.png | Bin .../TR2}/Models/DragonExplosion2_H/Data.json | 0 .../Models/DragonExplosion2_H/Segments.png | Bin .../TR2}/Models/DragonExplosion3_H/Data.json | 0 .../Models/DragonExplosion3_H/Segments.png | Bin .../Models/DragonExplosionEmitter_N/Data.json | 0 .../TR2}/Models/DragonFront_H/Data.json | 0 .../TR2}/Models/DragonFront_H/Segments.png | Bin .../Resources/TR2}/Models/Eagle/Data.json | 0 .../Resources/TR2}/Models/Eagle/Segments.png | Bin .../TR2}/Models/FlamethrowerGoon/Data.json | 0 .../TR2}/Models/FlamethrowerGoon/Segments.png | Bin .../TR2}/Models/GiantSpider/Data.json | 0 .../TR2}/Models/GiantSpider/Segments.png | Bin .../Resources/TR2}/Models/Gunman1/Data.json | 0 .../TR2}/Models/Gunman1/Segments.png | Bin .../Resources/TR2}/Models/Gunman2/Data.json | 0 .../TR2}/Models/Gunman2/Segments.png | Bin .../TR2}/Models/KnifeProjectile_H/Data.json | 0 .../Models/KnifeProjectile_H/Segments.png | Bin .../TR2}/Models/Knifethrower/Data.json | 0 .../TR2}/Models/Knifethrower/Segments.png | Bin .../TR2}/Models/LaraAutoAnim_H_Home/Data.json | 0 .../Models/LaraAutoAnim_H_Home/Segments.png | Bin .../TR2}/Models/LaraAutoAnim_H_Snow/Data.json | 0 .../Models/LaraAutoAnim_H_Snow/Segments.png | Bin .../TR2}/Models/LaraAutoAnim_H_Sun/Data.json | 0 .../Models/LaraAutoAnim_H_Sun/Segments.png | Bin .../Models/LaraAutoAnim_H_Unwater/Data.json | 0 .../LaraAutoAnim_H_Unwater/Segments.png | Bin .../TR2}/Models/LaraBoatAnim_H/Data.json | 0 .../Resources/TR2}/Models/LaraHome/Data.json | 0 .../TR2}/Models/LaraHome/Segments.png | Bin .../TR2}/Models/LaraMiscAnim_H_Ice/Data.json | 0 .../Models/LaraMiscAnim_H_Unwater/Data.json | 0 .../TR2}/Models/LaraMiscAnim_H_Wall/Data.json | 0 .../TR2}/Models/LaraMiscAnim_H_Xian/Data.json | 0 .../Models/LaraMiscAnim_H_Xian/Segments.png | Bin .../Models/LaraPistolAnim_H_Home/Data.json | 0 .../Models/LaraPistolAnim_H_Home/Segments.png | Bin .../Models/LaraPistolAnim_H_Snow/Data.json | 0 .../Models/LaraPistolAnim_H_Snow/Segments.png | Bin .../Models/LaraPistolAnim_H_Sun/Data.json | 0 .../Models/LaraPistolAnim_H_Sun/Segments.png | Bin .../Models/LaraPistolAnim_H_Unwater/Data.json | 0 .../LaraPistolAnim_H_Unwater/Segments.png | Bin .../Resources/TR2}/Models/LaraSnow/Data.json | 0 .../TR2}/Models/LaraSnow/Segments.png | Bin .../TR2}/Models/LaraSnowmobAnim_H/Data.json | 0 .../Resources/TR2}/Models/LaraSun/Data.json | 0 .../TR2}/Models/LaraSun/Segments.png | Bin .../TR2}/Models/LaraUnwater/Data.json | 0 .../TR2}/Models/LaraUnwater/Segments.png | Bin .../TR2}/Models/LaraUziAnim_H_Home/Data.json | 0 .../Models/LaraUziAnim_H_Home/Segments.png | Bin .../TR2}/Models/LaraUziAnim_H_Snow/Data.json | 0 .../Models/LaraUziAnim_H_Snow/Segments.png | Bin .../TR2}/Models/LaraUziAnim_H_Sun/Data.json | 0 .../Models/LaraUziAnim_H_Sun/Segments.png | Bin .../Models/LaraUziAnim_H_Unwater/Data.json | 0 .../Models/LaraUziAnim_H_Unwater/Segments.png | Bin .../TR2}/Models/MarcoBartoli/Data.json | 0 .../TR2}/Models/MarcoBartoli/Segments.png | Bin .../TR2}/Models/MaskedGoon1/Data.json | 0 .../TR2}/Models/MaskedGoon1/Segments.png | Bin .../TR2}/Models/MaskedGoon2/Data.json | 0 .../TR2}/Models/MaskedGoon2/Segments.png | Bin .../TR2}/Models/MaskedGoon3/Data.json | 0 .../TR2}/Models/MaskedGoon3/Segments.png | Bin .../TR2}/Models/MercSnowmobDriver/Data.json | 0 .../Models/MercSnowmobDriver/Segments.png | Bin .../TR2}/Models/Mercenary1/Data.json | 0 .../TR2}/Models/Mercenary1/Segments.png | Bin .../TR2}/Models/Mercenary2/Data.json | 0 .../TR2}/Models/Mercenary2/Segments.png | Bin .../TR2}/Models/Mercenary3/Data.json | 0 .../TR2}/Models/Mercenary3/Segments.png | Bin .../TR2}/Models/MonkWithKnifeStick/Data.json | 0 .../Models/MonkWithKnifeStick/Segments.png | Bin .../TR2}/Models/MonkWithLongStick/Data.json | 0 .../Models/MonkWithLongStick/Segments.png | Bin .../TR2}/Models/Puzzle2_M_H_Dagger/Data.json | 0 .../Models/Puzzle2_M_H_Dagger/Segments.png | Bin .../Resources/TR2}/Models/Rat/Data.json | 0 .../Resources/TR2}/Models/Rat/Segments.png | Bin .../TR2}/Models/RedSnowmobile/Data.json | 0 .../TR2}/Models/RedSnowmobile/Segments.png | Bin .../TR2}/Models/ScubaDiver/Data.json | 0 .../TR2}/Models/ScubaDiver/Segments.png | Bin .../Models/ScubaHarpoonProjectile_H/Data.json | 0 .../ScubaHarpoonProjectile_H/Segments.png | Bin .../Resources/TR2}/Models/Shark/Data.json | 0 .../Resources/TR2}/Models/Shark/Segments.png | Bin .../TR2}/Models/ShotgunGoon/Data.json | 0 .../TR2}/Models/ShotgunGoon/Segments.png | Bin .../TR2}/Models/SnowLeopard/Data.json | 0 .../TR2}/Models/SnowLeopard/Segments.png | Bin .../TR2}/Models/SnowmobileBelt/Data.json | 0 .../TR2}/Models/SnowmobileBelt/Segments.png | Bin .../Resources/TR2}/Models/Spider/Data.json | 0 .../Resources/TR2}/Models/Spider/Segments.png | Bin .../StickWieldingGoon1Bandana/Data.json | 0 .../StickWieldingGoon1Bandana/Segments.png | Bin .../StickWieldingGoon1BlackJacket/Data.json | 0 .../Segments.png | Bin .../StickWieldingGoon1BodyWarmer/Data.json | 0 .../StickWieldingGoon1BodyWarmer/Segments.png | Bin .../StickWieldingGoon1GreenVest/Data.json | 0 .../StickWieldingGoon1GreenVest/Segments.png | Bin .../StickWieldingGoon1WhiteVest/Data.json | 0 .../StickWieldingGoon1WhiteVest/Segments.png | Bin .../TR2}/Models/StickWieldingGoon2/Data.json | 0 .../Models/StickWieldingGoon2/Segments.png | Bin .../Resources/TR2}/Models/TRex/Data.json | 0 .../Resources/TR2}/Models/TRex/Segments.png | Bin .../TR2}/Models/WhiteTiger/Data.json | 0 .../TR2}/Models/WhiteTiger/Segments.png | Bin .../Resources/TR2}/Models/Winston/Data.json | 0 .../TR2}/Models/Winston/Segments.png | Bin .../TR2}/Models/XianGuardSpear/Data.json | 0 .../TR2}/Models/XianGuardSpear/Segments.png | Bin .../Models/XianGuardSpearStatue/Data.json | 0 .../Models/XianGuardSpearStatue/Segments.png | Bin .../TR2}/Models/XianGuardSword/Data.json | 0 .../TR2}/Models/XianGuardSword/Segments.png | Bin .../Models/XianGuardSwordStatue/Data.json | 0 .../Models/XianGuardSwordStatue/Segments.png | Bin .../TR2}/Models/YellowMorayEel/Data.json | 0 .../TR2}/Models/YellowMorayEel/Segments.png | Bin .../Resources/TR2}/Models/Yeti/Data.json | 0 .../Resources/TR2}/Models/Yeti/Segments.png | Bin .../enemy_restrictions_default.json | 0 .../enemy_restrictions_technical.json | 0 .../Resources/TR2}/Strings/G11N/defaults.json | 0 .../TR2}/Strings/G11N/gamestrings_CS.json | 0 .../TR2}/Strings/G11N/gamestrings_DE.json | 0 .../TR2}/Strings/G11N/gamestrings_EN.json | 0 .../TR2}/Strings/G11N/gamestrings_FI.json | 0 .../TR2}/Strings/G11N/gamestrings_FR.json | 0 .../TR2}/Strings/G11N/gamestrings_HR.json | 0 .../TR2}/Strings/G11N/gamestrings_IT.json | 0 .../TR2}/Strings/G11N/gamestrings_JA.json | 0 .../TR2}/Strings/G11N/gamestrings_NL.json | 0 .../TR2}/Strings/G11N/gamestrings_PL.json | 0 .../TR2}/Strings/G11N/gamestrings_PT.json | 0 .../TR2}/Strings/G11N/gamestrings_RU.json | 0 .../TR2}/Strings/G11N/gamestrings_SV.json | 0 .../Resources/TR2}/Strings/languages.json | 0 .../Deduplication/BOAT.TR2-TextureRemap.json | 0 .../CATACOMB.TR2-TextureRemap.json | 0 .../Deduplication/DECK.TR2-TextureRemap.json | 0 .../EMPRTOMB.TR2-TextureRemap.json | 0 .../FLOATING.TR2-TextureRemap.json | 0 .../FLOATING.TR2-UKBox-TextureRemap.json | 0 .../Deduplication/HOUSE.TR2-TextureRemap.json | 0 .../ICECAVE.TR2-TextureRemap.json | 0 .../Deduplication/KEEL.TR2-TextureRemap.json | 0 .../LIVING.TR2-TextureRemap.json | 0 .../MONASTRY.TR2-TextureRemap.json | 0 .../Deduplication/OPERA.TR2-TextureRemap.json | 0 .../PLATFORM.TR2-TextureRemap.json | 0 .../Deduplication/RIG.TR2-TextureRemap.json | 0 .../SKIDOO.TR2-TextureRemap.json | 0 .../UNWATER.TR2-TextureRemap.json | 0 .../VENICE.TR2-TextureRemap.json | 0 .../Deduplication/WALL.TR2-TextureRemap.json | 0 .../Deduplication/XIAN.TR2-TextureRemap.json | 0 .../Mapping/ASSAULT.TR2-Textures.json | 0 .../Textures/Mapping/BOAT.TR2-Textures.json | 0 .../Mapping/CATACOMB.TR2-Textures.json | 0 .../Textures/Mapping/CUT1.TR2-Textures.json | 0 .../Textures/Mapping/CUT2.TR2-Textures.json | 0 .../Textures/Mapping/CUT3.TR2-Textures.json | 0 .../Textures/Mapping/CUT4.TR2-Textures.json | 0 .../Textures/Mapping/DECK.TR2-Textures.json | 0 .../Mapping/EMPRTOMB.TR2-Textures.json | 0 .../Mapping/FLOATING.TR2-Textures.json | 0 .../Mapping/FLOATING.TR2-UKBox-Textures.json | 0 .../Textures/Mapping/HOUSE.TR2-Textures.json | 0 .../Mapping/ICECAVE.TR2-Textures.json | 0 .../Textures/Mapping/KEEL.TR2-Textures.json | 0 .../Textures/Mapping/LIVING.TR2-Textures.json | 0 .../Mapping/MONASTRY.TR2-Textures.json | 0 .../Textures/Mapping/OPERA.TR2-Textures.json | 0 .../Mapping/PLATFORM.TR2-Textures.json | 0 .../Textures/Mapping/RIG.TR2-Textures.json | 0 .../Textures/Mapping/SKIDOO.TR2-Textures.json | 0 .../Mapping/UNWATER.TR2-Textures.json | 0 .../Textures/Mapping/VENICE.TR2-Textures.json | 0 .../Textures/Mapping/WALL.TR2-Textures.json | 0 .../Textures/Mapping/XIAN.TR2-Textures.json | 0 .../Source/Dynamic/China/WallTheme.json | 0 .../Source/Dynamic/Opera/PlaneTheme.json | 0 .../Source/Dynamic/Tibet/SnowTheme.json | 0 .../Source/Dynamic/Underwater/MariaTheme.json | 0 .../Source/Static/Enemies/Barney/Data.json | 0 .../Source/Static/Enemies/Barney/Segments.png | Bin .../Source/Static/Enemies/Bartoli/Data.json | 0 .../Static/Enemies/Bartoli/Segments.png | Bin .../Source/Static/Enemies/Chicken/Data.json | 0 .../Static/Enemies/Chicken/Segments.png | Bin .../Source/Static/Enemies/Dragon/Data.json | 0 .../Source/Static/Enemies/Dragon/Segments.png | Bin .../Static/Enemies/Guard/Spear/Data.json | 0 .../Static/Enemies/Guard/Spear/Segments.png | Bin .../Static/Enemies/Guard/Sword/Data.json | 0 .../Static/Enemies/Guard/Sword/Segments.png | Bin .../Static/Enemies/Knifethrower/Data.json | 0 .../Static/Enemies/Knifethrower/Segments.png | Bin .../Static/Enemies/Monk/KnifeStick/Data.json | 0 .../Enemies/Monk/KnifeStick/Segments.png | Bin .../Static/Enemies/Monk/LongStick/Data.json | 0 .../Enemies/Monk/LongStick/Segments.png | Bin .../Static/Enemies/ShotgunGoon/Data.json | 0 .../Static/Enemies/ShotgunGoon/Segments.png | Bin .../Source/Static/Enemies/Spider/Data.json | 0 .../Source/Static/Enemies/Spider/Segments.png | Bin .../Source/Static/Enemies/Steve/Data.json | 0 .../Source/Static/Enemies/Steve/Segments.png | Bin .../Enemies/StickGoon/Bandana/Data.json | 0 .../Enemies/StickGoon/Bandana/Segments.png | Bin .../Enemies/StickGoon/BlackJacket/Data.json | 0 .../StickGoon/BlackJacket/Segments.png | Bin .../Enemies/StickGoon/BodyWarmer/Data.json | 0 .../Enemies/StickGoon/BodyWarmer/Segments.png | Bin .../Enemies/StickGoon/GreenVest/Data.json | 0 .../Enemies/StickGoon/GreenVest/Segments.png | Bin .../Static/Enemies/StickGoon/Sonics/Data.json | 0 .../Enemies/StickGoon/Sonics/Segments.png | Bin .../Source/Static/Enemies/Winston/Data.json | 0 .../Static/Enemies/Winston/Segments.png | Bin .../Source/Static/Fire/Explosion/Data.json | 0 .../Source/Static/Fire/Explosion/Segments.png | Bin .../Source/Static/Fire/Flame/Data.json | 0 .../Source/Static/Fire/Flame/Segments.png | Bin .../Source/Static/Fire/Flare/Data.json | 0 .../Source/Static/Fire/Flare/Segments.png | Bin .../Source/Static/GreatWall/Laptop/Data.json | 0 .../Static/GreatWall/Laptop/Segments.png | Bin .../Static/GreatWall/NightSky/Data.json | 0 .../Static/GreatWall/NightSky/Segments.png | Bin .../Source/Static/GreatWall/Sky/Data.json | 0 .../Source/Static/GreatWall/Sky/Segments.png | Bin .../Source/Static/HSH/Carpet/Data.json | 0 .../Source/Static/HSH/Carpet/Segments.png | Bin .../Source/Static/HSH/Cushions/Data.json | 0 .../Source/Static/HSH/Cushions/Segments.png | Bin .../Source/Static/HSH/Duvet/Data.json | 0 .../Source/Static/HSH/Duvet/Segments.png | Bin .../Source/Static/HSH/Marble/Data.json | 0 .../Source/Static/HSH/Marble/Segments.png | Bin .../Source/Static/HSH/NightSky/Data.json | 0 .../Source/Static/HSH/NightSky/Segments.png | Bin .../Source/Static/HSH/Paintings/Data.json | 0 .../Source/Static/HSH/Paintings/Segments.png | Bin .../Textures/Source/Static/HSH/Sky/Data.json | 0 .../Source/Static/HSH/Sky/Segments.png | Bin .../Source/Static/HSH/Tiles/Data.json | 0 .../Source/Static/HSH/Tiles/Segments.png | Bin .../Source/Static/Hazards/Boulder/Data.json | 0 .../Static/Hazards/Boulder/Segments.png | Bin .../Source/Static/Hazards/Spikes/Data.json | 0 .../Source/Static/Hazards/Spikes/Segments.png | Bin .../Source/Static/Hazards/Spindle/Data.json | 0 .../Static/Hazards/Spindle/Segments.png | Bin .../Static/Inventory/Background/Data.json | 0 .../Static/Inventory/Background/Segments.png | Bin .../Source/Static/Inventory/Font/Data.json | 0 .../Source/Static/Inventory/Font/Segments.png | Bin .../Source/Static/Inventory/Health/Data.json | 0 .../Static/Inventory/Health/Segments.png | Bin .../Static/Inventory/Passport/Data.json | 0 .../Static/Inventory/Passport/Segments.png | Bin .../Source/Static/Inventory/UIFrame/Data.json | 0 .../Static/Inventory/UIFrame/Segments.png | Bin .../Source/Static/Landmarks/BRB/Data.json | 0 .../Source/Static/Landmarks/BRB/Segments.png | Bin .../Source/Static/Landmarks/DAStep/Data.json | 0 .../Static/Landmarks/DAStep/Segments.png | Bin .../Static/Landmarks/FullLoss/Data.json | 0 .../Static/Landmarks/FullLoss/Segments.png | Bin .../Static/Landmarks/NLNMFirst/Data.json | 0 .../Static/Landmarks/NLNMFirst/Segments.png | Bin .../Source/Static/Landmarks/NoSaves/Data.json | 0 .../Static/Landmarks/NoSaves/Segments.png | Bin .../Source/Static/Lara/Bobble/Data.json | 0 .../Source/Static/Lara/Bobble/Segments.png | Bin .../Source/Static/Lara/Braid/Data.json | 0 .../Source/Static/Lara/Braid/Segments.png | Bin .../Source/Static/Lara/DivingSuit/Data.json | 0 .../Static/Lara/DivingSuit/Segments.png | Bin .../Source/Static/Lara/DressingGown/Data.json | 0 .../Static/Lara/DressingGown/Segments.png | Bin .../Source/Static/Lara/Socks/Data.json | 0 .../Source/Static/Lara/Socks/Segments.png | Bin .../Source/Static/Lara/Top/Snow/Data.json | 0 .../Source/Static/Lara/Top/Snow/Segments.png | Bin .../Source/Static/Lara/Top/Sun/Data.json | 0 .../Source/Static/Lara/Top/Sun/Segments.png | Bin .../Source/Static/Offshore/Acid/Data.json | 0 .../Source/Static/Offshore/Acid/Segments.png | Bin .../Source/Static/Offshore/Cordon/Data.json | 0 .../Static/Offshore/Cordon/Segments.png | Bin .../Offshore/Keycard/Keycard1/Data.json | 0 .../Offshore/Keycard/Keycard1/Segments.png | Bin .../Offshore/Keycard/Keycard2/Data.json | 0 .../Offshore/Keycard/Keycard2/Segments.png | Bin .../Offshore/Keycard/Keycard3/Data.json | 0 .../Offshore/Keycard/Keycard3/Segments.png | Bin .../Offshore/Keycard/Keycard4/Data.json | 0 .../Offshore/Keycard/Keycard4/Segments.png | Bin .../Source/Static/Offshore/Plane/Data.json | 0 .../Source/Static/Offshore/Plane/Segments.png | Bin .../Source/Static/Offshore/Sub/Data.json | 0 .../Source/Static/Offshore/Sub/Segments.png | Bin .../Source/Static/Offshore/Tank/Data.json | 0 .../Source/Static/Offshore/Tank/Segments.png | Bin .../Textures/Source/Static/Secrets/Data.json | 0 .../Source/Static/Secrets/Segments.png | Bin .../Textures/Source/Static/Seraph/Data.json | 0 .../Source/Static/Seraph/Segments.png | Bin .../Source/Static/Tibet/Bell/Data.json | 0 .../Source/Static/Tibet/Bell/Segments.png | Bin .../Source/Static/Tibet/Gate/Data.json | 0 .../Source/Static/Tibet/Gate/Segments.png | Bin .../Source/Static/Tibet/NightSky/Data.json | 0 .../Source/Static/Tibet/NightSky/Segments.png | Bin .../Source/Static/Tibet/Sky/Data.json | 0 .../Source/Static/Tibet/Sky/Segments.png | Bin .../Static/Underwater/Lifeboat/Data.json | 0 .../Static/Underwater/Lifeboat/Segments.png | Bin .../Source/Static/Vehicles/Boat/Data.json | 0 .../Source/Static/Vehicles/Boat/Segments.png | Bin .../Static/Vehicles/Skidoo/Turbo/Data.json | 0 .../Static/Vehicles/Skidoo/Turbo/Segments.png | Bin .../Source/Static/Venice/Awning/Data.json | 0 .../Source/Static/Venice/Awning/Segments.png | Bin .../Source/Static/Venice/BarberPole/Data.json | 0 .../Static/Venice/BarberPole/Segments.png | Bin .../Source/Static/Venice/Curtains/Data.json | 0 .../Static/Venice/Curtains/Segments.png | Bin .../Source/Static/Venice/Floor/Data.json | 0 .../Source/Static/Venice/Floor/Segments.png | Bin .../Static/Venice/NightSky/Bartoli/Data.json | 0 .../Venice/NightSky/Bartoli/Segments.png | Bin .../Static/Venice/NightSky/Boat/Data.json | 0 .../Static/Venice/NightSky/Boat/Segments.png | Bin .../Static/Venice/Sky/Bartoli/Data.json | 0 .../Static/Venice/Sky/Bartoli/Segments.png | Bin .../Source/Static/Venice/Sky/Boat/Data.json | 0 .../Static/Venice/Sky/Boat/Segments.png | Bin .../Textures/Source/Static/Water/Data.json | 0 .../Textures/Source/Static/Water/Segments.png | Bin .../Source/Static/Xian/Building/Data.json | 0 .../Source/Static/Xian/Building/Segments.png | Bin .../Source/Static/Xian/Cracker/Data.json | 0 .../Source/Static/Xian/Cracker/Segments.png | Bin .../Source/Static/Xian/Islands/Data.json | 0 .../Source/Static/Xian/Islands/Segments.png | Bin .../Source/Static/Xian/Lamp/Data.json | 0 .../Source/Static/Xian/Lamp/Segments.png | Bin .../Source/Static/Xian/Lava/Data.json | 0 .../Source/Static/Xian/Lava/Segments.png | Bin .../Source/Static/Xian/Metal/Data.json | 0 .../Source/Static/Xian/Metal/Segments.png | Bin .../Source/Static/Xian/Rock/Data.json | 0 .../Source/Static/Xian/Rock/Segments.png | Bin .../Textures/Source/Static/Xian/Sky/Data.json | 0 .../Source/Static/Xian/Sky/Segments.png | Bin .../Source/Static/Xian/Stone/Data.json | 0 .../Source/Static/Xian/Stone/Segments.png | Bin .../Source/Static/Xian/Tree/Data.json | 0 .../Source/Static/Xian/Tree/Segments.png | Bin .../Textures/Source/Static/entity_lookup.json | 0 .../Source/Static/global_grouping.json | 0 .../Resources/TR2}/Zones/BOAT.TR2-Zones.json | 0 .../TR2}/Zones/CATACOMB.TR2-Zones.json | 0 .../Resources/TR2}/Zones/DECK.TR2-Zones.json | 0 .../TR2}/Zones/EMPRTOMB.TR2-Zones.json | 0 .../TR2}/Zones/FLOATING.TR2-Zones.json | 0 .../Resources/TR2}/Zones/HOUSE.TR2-Zones.json | 0 .../TR2}/Zones/ICECAVE.TR2-Zones.json | 0 .../Resources/TR2}/Zones/KEEL.TR2-Zones.json | 0 .../TR2}/Zones/LIVING.TR2-Zones.json | 0 .../TR2}/Zones/MONASTRY.TR2-Zones.json | 0 .../Resources/TR2}/Zones/OPERA.TR2-Zones.json | 0 .../TR2}/Zones/PLATFORM.TR2-Zones.json | 0 .../Resources/TR2}/Zones/RIG.TR2-Zones.json | 0 .../TR2}/Zones/SKIDOO.TR2-Zones.json | 0 .../TR2}/Zones/UNWATER.TR2-Zones.json | 0 .../TR2}/Zones/VENICE.TR2-Zones.json | 0 .../Resources/TR2}/Zones/WALL.TR2-Zones.json | 0 .../Resources/TR2}/Zones/XIAN.TR2-Zones.json | 0 .../Resources/TR3/Audio/audio_tracks.json | 1108 +++++++++++++++++ .../TR3/Locations/unarmed_locations.json | 222 ++++ .../SFX/TRSFXCreatureCategory.cs | 2 +- .../SFX/TRSFXDefinition.cs | 2 +- .../SFX/TRSFXGeneralCategory.cs | 2 +- .../TRRandomizerController.cs | 61 +- .../TRRandomizerCoord.cs | 30 +- TRRandomizerCore/TRRandomizerCore.csproj | 44 + TRRandomizerCore/TRRandomizerType.cs | 22 + .../Utilities/EnemyUtilities.cs | 67 +- .../Utilities/ItemUtilities.cs | 2 +- .../Utilities/RoomWaterUtilities.cs | 38 +- .../Utilities/SpatialConverters.cs | 4 +- .../Utilities/TexturePositionMonitor.cs | 2 +- .../Utilities/TexturePositionMonitorBroker.cs | 2 +- .../Utilities/VehicleUtilities.cs | 6 +- .../Zones/LevelZones.cs | 2 +- .../Zones/ZonedLocationCollection.cs | 8 +- .../App.config | 0 .../App.xaml | 16 +- .../App.xaml.cs | 16 +- .../Commands/WindowCommands.cs | 2 +- .../Controls/EditorControl.xaml | 53 +- .../Controls/EditorControl.xaml.cs | 18 +- .../Controls/FolderLoadControl.xaml | 6 +- .../Controls/FolderLoadControl.xaml.cs | 16 +- .../Controls/ManagedSeedAdvancedControl.xaml | 9 +- .../ManagedSeedAdvancedControl.xaml.cs | 11 +- .../Controls/ManagedSeedBoolControl.xaml | 7 +- .../Controls/ManagedSeedBoolControl.xaml.cs | 7 +- .../Controls/ManagedSeedControl.xaml | 7 +- .../Controls/ManagedSeedControl.xaml.cs | 16 +- .../Controls/ManagedSeedIntControl.xaml | 7 +- .../Controls/ManagedSeedIntControl.xaml.cs | 18 +- .../Controls/NumericUpDown.xaml | 2 +- .../Controls/NumericUpDown.xaml.cs | 2 +- .../Controls/SeedControl.xaml | 4 +- .../Controls/SeedControl.xaml.cs | 2 +- .../Converters/BindingProxy.cs | 2 +- .../Converters/BoolToVisibilityConverter.cs | 2 +- .../Converters/BooleanAndConverter.cs | 6 +- .../Converters/ComparisonConverter.cs | 2 +- .../Converters/InverseBooleanConverter.cs | 2 +- .../Events/DataFolderEventArgs.cs | 8 +- .../Events/EditorEventArgs.cs | 2 +- .../Model/BoolItemControlClass.cs | 2 +- .../Model/ControllerOptions.cs | 232 +++- .../Model/IRecentFolderOpener.cs | 2 +- .../Model/ManagedSeed.cs | 2 +- .../Model/ManagedSeedBool.cs | 2 +- .../Model/ManagedSeedNumeric.cs | 2 +- .../Model/RecentFolder.cs | 2 +- .../Model/RecentFolderList.cs | 6 +- .../Properties/AssemblyInfo.cs | 6 +- .../Properties/Resources.Designer.cs | 45 +- .../Properties/Resources.resx | 0 .../Properties/Settings.Designer.cs | 21 +- .../Properties/Settings.settings | 0 .../Resources/Darkness/0.jpg | Bin .../Resources/Darkness/1.jpg | Bin .../Resources/Darkness/10.jpg | Bin .../Resources/Darkness/2.jpg | Bin .../Resources/Darkness/3.jpg | Bin .../Resources/Darkness/4.jpg | Bin .../Resources/Darkness/5.jpg | Bin .../Resources/Darkness/6.jpg | Bin .../Resources/Darkness/7.jpg | Bin .../Resources/Darkness/8.jpg | Bin .../Resources/Darkness/9.jpg | Bin .../Resources/arrows.png | Bin .../Resources/down.png | Bin .../Resources/loading.png | Bin .../Resources/rando.ico | Bin .../Resources/rando.png | Bin .../Resources/up.png | Bin .../TRRandomizerView.csproj | 9 +- .../Updates/Update.cs | 2 +- .../Updates/UpdateChecker.cs | 2 +- .../Updates/UpdateEventArgs.cs | 2 +- .../Utilities/ControlUtils.cs | 2 +- .../Utilities/WindowUtils.cs | 2 +- .../Windows/AboutWindow.xaml | 2 +- .../Windows/AboutWindow.xaml.cs | 4 +- .../Windows/AdvancedWindow.xaml | 8 +- .../Windows/AdvancedWindow.xaml.cs | 10 +- .../Windows/GlobalSeedWindow.xaml | 4 +- .../Windows/GlobalSeedWindow.xaml.cs | 18 +- .../Windows/MainWindow.xaml | 10 +- .../Windows/MainWindow.xaml.cs | 12 +- .../Windows/MessageWindow.xaml | 4 +- .../Windows/MessageWindow.xaml.cs | 6 +- .../Windows/OpenProgressWindow.xaml | 2 +- .../Windows/OpenProgressWindow.xaml.cs | 16 +- .../Windows/RandomizeProgressWindow.xaml | 2 +- .../Windows/RandomizeProgressWindow.xaml.cs | 14 +- .../Windows/RestoreProgressWindow.xaml | 2 +- .../Windows/RestoreProgressWindow.xaml.cs | 12 +- .../Windows/UpdateAvailableWindow.xaml | 4 +- .../Windows/UpdateAvailableWindow.xaml.cs | 6 +- .../app.manifest | 0 .../packages.config | 0 .../Textures/Grouping/GlobalGrouping.cs | 2 +- .../Textures/TextureDatabase.cs | 6 +- .../Textures/TextureLevelMapping.cs | 2 +- TextureExport/HtmlTileBuilder.cs | 2 +- TextureExport/Program.cs | 4 +- 618 files changed, 3400 insertions(+), 1874 deletions(-) delete mode 100644 TR2RandomizerCore/Processors/LevelProcessor.cs delete mode 100644 TR2RandomizerCore/Randomizers/RandomizerBase.cs delete mode 100644 TR2RandomizerCore/Randomizers/TR2LevelRandomizer.cs delete mode 100644 TR2RandomizerCore/TR2RandomizerCore.csproj delete mode 100644 TR2RandomizerView/Model/ProfileString.cs rename TRLevelReader/Helpers/{LevelNames.cs => LevelNames/TR2LevelNames.cs} (94%) create mode 100644 TRLevelReader/Helpers/LevelNames/TR3LevelNames.cs rename TR2Randomizer.sln => TRRandomizer.sln (94%) create mode 100644 TRRandomizerCore/Editors/ISettingsProvider.cs create mode 100644 TRRandomizerCore/Editors/RandomizerSettings.cs create mode 100644 TRRandomizerCore/Editors/TR2RandoEditor.cs create mode 100644 TRRandomizerCore/Editors/TR3RandoEditor.cs rename {TR2RandomizerCore => TRRandomizerCore}/Globalisation/G11N.cs (91%) rename {TR2RandomizerCore => TRRandomizerCore}/Globalisation/GameStrings.cs (98%) rename {TR2RandomizerCore => TRRandomizerCore}/Globalisation/GlobalStrings.cs (84%) rename {TR2RandomizerCore => TRRandomizerCore}/Globalisation/Language.cs (95%) rename {TR2RandomizerCore => TRRandomizerCore}/Globalisation/LevelStrings.cs (88%) rename {TR2RandomizerCore => TRRandomizerCore}/Helpers/CollectionExtensions.cs (97%) rename {TR2RandomizerCore => TRRandomizerCore}/Helpers/Difficulty.cs (68%) rename {TR2RandomizerCore => TRRandomizerCore}/Helpers/EnemyDifficulty.cs (77%) rename {TR2RandomizerCore => TRRandomizerCore}/Helpers/ItemDifficulty.cs (65%) rename {TR2RandomizerCore => TRRandomizerCore}/Helpers/LandmarkImporter.cs (98%) rename {TR2RandomizerCore => TRRandomizerCore}/Helpers/Location.cs (96%) rename {TR2RandomizerCore => TRRandomizerCore}/Helpers/MeshEditor.cs (99%) rename {TR2RandomizerCore => TRRandomizerCore}/Helpers/ModificationStamp.cs (91%) rename {TR2RandomizerCore => TRRandomizerCore}/Helpers/RandoDifficulty.cs (67%) rename {TR2RandomizerCore => TRRandomizerCore}/Helpers/TROpenRestoreEventArgs.cs (93%) rename {TR2RandomizerCore => TRRandomizerCore}/Helpers/TRRandomizationCategory.cs (80%) rename {TR2RandomizerCore => TRRandomizerCore}/Helpers/TRRandomizationEventArgs.cs (98%) rename {TR2RandomizerCore/Helpers => TRRandomizerCore/Levels}/TR2CombinedLevel.cs (95%) rename {TR2RandomizerCore/Helpers => TRRandomizerCore/Levels}/TR2LevelTextureWeightComparer.cs (95%) create mode 100644 TRRandomizerCore/Levels/TR3CombinedLevel.cs create mode 100644 TRRandomizerCore/Processors/AbstractLevelProcessor.cs rename {TR2RandomizerCore => TRRandomizerCore}/Processors/AbstractProcessorThread.cs (96%) create mode 100644 TRRandomizerCore/Processors/ILevelProcessor.cs create mode 100644 TRRandomizerCore/Processors/TR2/TR2LevelProcessor.cs rename TR2RandomizerCore/Processors/ModelAdjuster.cs => TRRandomizerCore/Processors/TR2/TR2ModelAdjuster.cs (95%) rename TR2RandomizerCore/Processors/TextureDeduplicator.cs => TRRandomizerCore/Processors/TR2/TR2TextureDeduplicator.cs (87%) create mode 100644 TRRandomizerCore/Processors/TR3/TR3LevelProcessor.cs rename {TR2RandomizerCore => TRRandomizerCore}/Randomizers/IRandomizer.cs (65%) create mode 100644 TRRandomizerCore/Randomizers/TR2/BaseTR2Randomizer.cs rename TR2RandomizerCore/Randomizers/AudioRandomizer.cs => TRRandomizerCore/Randomizers/TR2/TR2AudioRandomizer.cs (95%) rename TR2RandomizerCore/Randomizers/EnemyRandomizer.cs => TRRandomizerCore/Randomizers/TR2/TR2EnemyRandomizer.cs (93%) rename TR2RandomizerCore/Randomizers/EnvironmentRandomizer.cs => TRRandomizerCore/Randomizers/TR2/TR2EnvironmentRandomizer.cs (85%) rename TR2RandomizerCore/Randomizers/GameStringRandomizer.cs => TRRandomizerCore/Randomizers/TR2/TR2GameStringRandomizer.cs (90%) rename TR2RandomizerCore/Randomizers/ItemRandomizer.cs => TRRandomizerCore/Randomizers/TR2/TR2ItemRandomizer.cs (95%) rename TR2RandomizerCore/Randomizers/NightModeRandomizer.cs => TRRandomizerCore/Randomizers/TR2/TR2NightModeRandomizer.cs (88%) rename TR2RandomizerCore/Randomizers/OutfitRandomizer.cs => TRRandomizerCore/Randomizers/TR2/TR2OutfitRandomizer.cs (92%) rename TR2RandomizerCore/Randomizers/SecretReplacer.cs => TRRandomizerCore/Randomizers/TR2/TR2SecretRandomizer.cs (89%) rename TR2RandomizerCore/Randomizers/StartPositionRandomizer.cs => TRRandomizerCore/Randomizers/TR2/TR2StartPositionRandomizer.cs (85%) rename TR2RandomizerCore/Randomizers/TextureRandomizer.cs => TRRandomizerCore/Randomizers/TR2/TR2TextureRandomizer.cs (94%) create mode 100644 TRRandomizerCore/Randomizers/TR3/BaseTR3Randomizer.cs rename {TR2RandomizerCore => TRRandomizerCore}/Resources/Documentation/ENEMIES.md (100%) rename {TR2RandomizerCore => TRRandomizerCore}/Resources/Documentation/ORDER.md (100%) rename TR2RandomizerCore/Resources/tr2audio.json => TRRandomizerCore/Resources/TR2/Audio/audio_tracks.json (100%) rename TR2RandomizerCore/Resources/tr2sfx.json => TRRandomizerCore/Resources/TR2/Audio/sfx.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Environment/ASSAULT.TR2-Environment.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Environment/BOAT.TR2-Environment.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Environment/CATACOMB.TR2-Environment.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Environment/DECK.TR2-Environment.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Environment/EMPRTOMB.TR2-Environment.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Environment/FLOATING.TR2-Environment.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Environment/HOUSE.TR2-Environment.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Environment/ICECAVE.TR2-Environment.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Environment/KEEL.TR2-Environment.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Environment/LIVING.TR2-Environment.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Environment/MONASTRY.TR2-Environment.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Environment/OPERA.TR2-Environment.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Environment/PLATFORM.TR2-Environment.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Environment/RIG.TR2-Environment.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Environment/SKIDOO.TR2-Environment.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Environment/UNWATER.TR2-Environment.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Environment/VENICE.TR2-Environment.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Environment/WALL.TR2-Environment.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Environment/XIAN.TR2-Environment.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2/Locations}/item_locations.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2/Locations}/locations.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2/Locations}/start_positions.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2/Locations}/unarmed_locations.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2/Locations}/vehicle_locations.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/BarracudaIce/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/BarracudaIce/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/BarracudaUnwater/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/BarracudaUnwater/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/BarracudaXian/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/BarracudaXian/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/BengalTiger/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/BengalTiger/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/BirdMonster/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/BirdMonster/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/BlackMorayEel/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/BlackMorayEel/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/BlackSnowmob/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/BlackSnowmob/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/Boat/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/Boat/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/Crow/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/Crow/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/Doberman/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/Doberman/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/DragonBack_H/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/DragonBack_H/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/DragonBonesBack_H/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/DragonBonesBack_H/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/DragonBonesFront_H/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/DragonBonesFront_H/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/DragonExplosion1_H/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/DragonExplosion1_H/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/DragonExplosion2_H/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/DragonExplosion2_H/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/DragonExplosion3_H/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/DragonExplosion3_H/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/DragonExplosionEmitter_N/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/DragonFront_H/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/DragonFront_H/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/Eagle/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/Eagle/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/FlamethrowerGoon/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/FlamethrowerGoon/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/GiantSpider/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/GiantSpider/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/Gunman1/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/Gunman1/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/Gunman2/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/Gunman2/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/KnifeProjectile_H/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/KnifeProjectile_H/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/Knifethrower/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/Knifethrower/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/LaraAutoAnim_H_Home/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/LaraAutoAnim_H_Home/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/LaraAutoAnim_H_Snow/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/LaraAutoAnim_H_Snow/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/LaraAutoAnim_H_Sun/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/LaraAutoAnim_H_Sun/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/LaraAutoAnim_H_Unwater/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/LaraAutoAnim_H_Unwater/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/LaraBoatAnim_H/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/LaraHome/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/LaraHome/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/LaraMiscAnim_H_Ice/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/LaraMiscAnim_H_Unwater/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/LaraMiscAnim_H_Wall/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/LaraMiscAnim_H_Xian/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/LaraMiscAnim_H_Xian/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/LaraPistolAnim_H_Home/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/LaraPistolAnim_H_Home/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/LaraPistolAnim_H_Snow/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/LaraPistolAnim_H_Snow/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/LaraPistolAnim_H_Sun/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/LaraPistolAnim_H_Sun/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/LaraPistolAnim_H_Unwater/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/LaraPistolAnim_H_Unwater/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/LaraSnow/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/LaraSnow/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/LaraSnowmobAnim_H/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/LaraSun/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/LaraSun/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/LaraUnwater/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/LaraUnwater/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/LaraUziAnim_H_Home/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/LaraUziAnim_H_Home/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/LaraUziAnim_H_Snow/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/LaraUziAnim_H_Snow/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/LaraUziAnim_H_Sun/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/LaraUziAnim_H_Sun/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/LaraUziAnim_H_Unwater/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/LaraUziAnim_H_Unwater/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/MarcoBartoli/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/MarcoBartoli/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/MaskedGoon1/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/MaskedGoon1/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/MaskedGoon2/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/MaskedGoon2/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/MaskedGoon3/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/MaskedGoon3/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/MercSnowmobDriver/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/MercSnowmobDriver/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/Mercenary1/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/Mercenary1/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/Mercenary2/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/Mercenary2/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/Mercenary3/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/Mercenary3/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/MonkWithKnifeStick/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/MonkWithKnifeStick/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/MonkWithLongStick/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/MonkWithLongStick/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/Puzzle2_M_H_Dagger/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/Puzzle2_M_H_Dagger/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/Rat/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/Rat/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/RedSnowmobile/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/RedSnowmobile/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/ScubaDiver/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/ScubaDiver/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/ScubaHarpoonProjectile_H/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/ScubaHarpoonProjectile_H/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/Shark/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/Shark/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/ShotgunGoon/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/ShotgunGoon/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/SnowLeopard/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/SnowLeopard/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/SnowmobileBelt/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/SnowmobileBelt/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/Spider/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/Spider/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/StickWieldingGoon1Bandana/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/StickWieldingGoon1Bandana/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/StickWieldingGoon1BlackJacket/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/StickWieldingGoon1BlackJacket/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/StickWieldingGoon1BodyWarmer/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/StickWieldingGoon1BodyWarmer/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/StickWieldingGoon1GreenVest/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/StickWieldingGoon1GreenVest/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/StickWieldingGoon1WhiteVest/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/StickWieldingGoon1WhiteVest/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/StickWieldingGoon2/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/StickWieldingGoon2/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/TRex/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/TRex/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/WhiteTiger/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/WhiteTiger/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/Winston/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/Winston/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/XianGuardSpear/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/XianGuardSpear/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/XianGuardSpearStatue/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/XianGuardSpearStatue/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/XianGuardSword/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/XianGuardSword/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/XianGuardSwordStatue/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/XianGuardSwordStatue/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/YellowMorayEel/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/YellowMorayEel/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/Yeti/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Models/Yeti/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2/Restrictions}/enemy_restrictions_default.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2/Restrictions}/enemy_restrictions_technical.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Strings/G11N/defaults.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Strings/G11N/gamestrings_CS.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Strings/G11N/gamestrings_DE.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Strings/G11N/gamestrings_EN.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Strings/G11N/gamestrings_FI.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Strings/G11N/gamestrings_FR.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Strings/G11N/gamestrings_HR.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Strings/G11N/gamestrings_IT.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Strings/G11N/gamestrings_JA.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Strings/G11N/gamestrings_NL.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Strings/G11N/gamestrings_PL.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Strings/G11N/gamestrings_PT.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Strings/G11N/gamestrings_RU.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Strings/G11N/gamestrings_SV.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Strings/languages.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Deduplication/BOAT.TR2-TextureRemap.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Deduplication/CATACOMB.TR2-TextureRemap.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Deduplication/DECK.TR2-TextureRemap.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Deduplication/EMPRTOMB.TR2-TextureRemap.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Deduplication/FLOATING.TR2-TextureRemap.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Deduplication/FLOATING.TR2-UKBox-TextureRemap.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Deduplication/HOUSE.TR2-TextureRemap.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Deduplication/ICECAVE.TR2-TextureRemap.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Deduplication/KEEL.TR2-TextureRemap.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Deduplication/LIVING.TR2-TextureRemap.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Deduplication/MONASTRY.TR2-TextureRemap.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Deduplication/OPERA.TR2-TextureRemap.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Deduplication/PLATFORM.TR2-TextureRemap.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Deduplication/RIG.TR2-TextureRemap.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Deduplication/SKIDOO.TR2-TextureRemap.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Deduplication/UNWATER.TR2-TextureRemap.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Deduplication/VENICE.TR2-TextureRemap.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Deduplication/WALL.TR2-TextureRemap.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Deduplication/XIAN.TR2-TextureRemap.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Mapping/ASSAULT.TR2-Textures.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Mapping/BOAT.TR2-Textures.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Mapping/CATACOMB.TR2-Textures.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Mapping/CUT1.TR2-Textures.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Mapping/CUT2.TR2-Textures.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Mapping/CUT3.TR2-Textures.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Mapping/CUT4.TR2-Textures.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Mapping/DECK.TR2-Textures.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Mapping/EMPRTOMB.TR2-Textures.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Mapping/FLOATING.TR2-Textures.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Mapping/FLOATING.TR2-UKBox-Textures.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Mapping/HOUSE.TR2-Textures.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Mapping/ICECAVE.TR2-Textures.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Mapping/KEEL.TR2-Textures.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Mapping/LIVING.TR2-Textures.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Mapping/MONASTRY.TR2-Textures.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Mapping/OPERA.TR2-Textures.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Mapping/PLATFORM.TR2-Textures.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Mapping/RIG.TR2-Textures.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Mapping/SKIDOO.TR2-Textures.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Mapping/UNWATER.TR2-Textures.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Mapping/VENICE.TR2-Textures.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Mapping/WALL.TR2-Textures.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Mapping/XIAN.TR2-Textures.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Dynamic/China/WallTheme.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Dynamic/Opera/PlaneTheme.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Dynamic/Tibet/SnowTheme.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Dynamic/Underwater/MariaTheme.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Enemies/Barney/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Enemies/Barney/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Enemies/Bartoli/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Enemies/Bartoli/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Enemies/Chicken/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Enemies/Chicken/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Enemies/Dragon/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Enemies/Dragon/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Enemies/Guard/Spear/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Enemies/Guard/Spear/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Enemies/Guard/Sword/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Enemies/Guard/Sword/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Enemies/Knifethrower/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Enemies/Knifethrower/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Enemies/Monk/KnifeStick/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Enemies/Monk/KnifeStick/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Enemies/Monk/LongStick/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Enemies/Monk/LongStick/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Enemies/ShotgunGoon/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Enemies/ShotgunGoon/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Enemies/Spider/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Enemies/Spider/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Enemies/Steve/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Enemies/Steve/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Enemies/StickGoon/Bandana/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Enemies/StickGoon/Bandana/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Enemies/StickGoon/BlackJacket/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Enemies/StickGoon/BlackJacket/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Enemies/StickGoon/BodyWarmer/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Enemies/StickGoon/BodyWarmer/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Enemies/StickGoon/GreenVest/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Enemies/StickGoon/GreenVest/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Enemies/StickGoon/Sonics/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Enemies/StickGoon/Sonics/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Enemies/Winston/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Enemies/Winston/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Fire/Explosion/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Fire/Explosion/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Fire/Flame/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Fire/Flame/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Fire/Flare/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Fire/Flare/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/GreatWall/Laptop/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/GreatWall/Laptop/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/GreatWall/NightSky/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/GreatWall/NightSky/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/GreatWall/Sky/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/GreatWall/Sky/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/HSH/Carpet/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/HSH/Carpet/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/HSH/Cushions/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/HSH/Cushions/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/HSH/Duvet/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/HSH/Duvet/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/HSH/Marble/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/HSH/Marble/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/HSH/NightSky/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/HSH/NightSky/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/HSH/Paintings/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/HSH/Paintings/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/HSH/Sky/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/HSH/Sky/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/HSH/Tiles/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/HSH/Tiles/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Hazards/Boulder/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Hazards/Boulder/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Hazards/Spikes/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Hazards/Spikes/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Hazards/Spindle/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Hazards/Spindle/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Inventory/Background/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Inventory/Background/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Inventory/Font/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Inventory/Font/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Inventory/Health/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Inventory/Health/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Inventory/Passport/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Inventory/Passport/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Inventory/UIFrame/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Inventory/UIFrame/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Landmarks/BRB/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Landmarks/BRB/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Landmarks/DAStep/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Landmarks/DAStep/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Landmarks/FullLoss/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Landmarks/FullLoss/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Landmarks/NLNMFirst/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Landmarks/NLNMFirst/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Landmarks/NoSaves/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Landmarks/NoSaves/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Lara/Bobble/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Lara/Bobble/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Lara/Braid/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Lara/Braid/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Lara/DivingSuit/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Lara/DivingSuit/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Lara/DressingGown/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Lara/DressingGown/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Lara/Socks/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Lara/Socks/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Lara/Top/Snow/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Lara/Top/Snow/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Lara/Top/Sun/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Lara/Top/Sun/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Offshore/Acid/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Offshore/Acid/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Offshore/Cordon/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Offshore/Cordon/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Offshore/Keycard/Keycard1/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Offshore/Keycard/Keycard1/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Offshore/Keycard/Keycard2/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Offshore/Keycard/Keycard2/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Offshore/Keycard/Keycard3/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Offshore/Keycard/Keycard3/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Offshore/Keycard/Keycard4/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Offshore/Keycard/Keycard4/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Offshore/Plane/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Offshore/Plane/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Offshore/Sub/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Offshore/Sub/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Offshore/Tank/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Offshore/Tank/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Secrets/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Secrets/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Seraph/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Seraph/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Tibet/Bell/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Tibet/Bell/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Tibet/Gate/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Tibet/Gate/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Tibet/NightSky/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Tibet/NightSky/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Tibet/Sky/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Tibet/Sky/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Underwater/Lifeboat/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Underwater/Lifeboat/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Vehicles/Boat/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Vehicles/Boat/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Vehicles/Skidoo/Turbo/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Vehicles/Skidoo/Turbo/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Venice/Awning/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Venice/Awning/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Venice/BarberPole/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Venice/BarberPole/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Venice/Curtains/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Venice/Curtains/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Venice/Floor/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Venice/Floor/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Venice/NightSky/Bartoli/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Venice/NightSky/Bartoli/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Venice/NightSky/Boat/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Venice/NightSky/Boat/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Venice/Sky/Bartoli/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Venice/Sky/Bartoli/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Venice/Sky/Boat/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Venice/Sky/Boat/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Water/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Water/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Xian/Building/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Xian/Building/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Xian/Cracker/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Xian/Cracker/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Xian/Islands/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Xian/Islands/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Xian/Lamp/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Xian/Lamp/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Xian/Lava/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Xian/Lava/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Xian/Metal/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Xian/Metal/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Xian/Rock/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Xian/Rock/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Xian/Sky/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Xian/Sky/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Xian/Stone/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Xian/Stone/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Xian/Tree/Data.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/Xian/Tree/Segments.png (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/entity_lookup.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Textures/Source/Static/global_grouping.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Zones/BOAT.TR2-Zones.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Zones/CATACOMB.TR2-Zones.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Zones/DECK.TR2-Zones.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Zones/EMPRTOMB.TR2-Zones.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Zones/FLOATING.TR2-Zones.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Zones/HOUSE.TR2-Zones.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Zones/ICECAVE.TR2-Zones.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Zones/KEEL.TR2-Zones.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Zones/LIVING.TR2-Zones.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Zones/MONASTRY.TR2-Zones.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Zones/OPERA.TR2-Zones.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Zones/PLATFORM.TR2-Zones.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Zones/RIG.TR2-Zones.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Zones/SKIDOO.TR2-Zones.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Zones/UNWATER.TR2-Zones.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Zones/VENICE.TR2-Zones.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Zones/WALL.TR2-Zones.json (100%) rename {TR2RandomizerCore/Resources => TRRandomizerCore/Resources/TR2}/Zones/XIAN.TR2-Zones.json (100%) create mode 100644 TRRandomizerCore/Resources/TR3/Audio/audio_tracks.json create mode 100644 TRRandomizerCore/Resources/TR3/Locations/unarmed_locations.json rename {TR2RandomizerCore => TRRandomizerCore}/SFX/TRSFXCreatureCategory.cs (76%) rename {TR2RandomizerCore => TRRandomizerCore}/SFX/TRSFXDefinition.cs (97%) rename {TR2RandomizerCore => TRRandomizerCore}/SFX/TRSFXGeneralCategory.cs (94%) rename TR2RandomizerCore/TR2RandomizerController.cs => TRRandomizerCore/TRRandomizerController.cs (88%) rename TR2RandomizerCore/TR2RandomizerCoord.cs => TRRandomizerCore/TRRandomizerCoord.cs (75%) create mode 100644 TRRandomizerCore/TRRandomizerCore.csproj create mode 100644 TRRandomizerCore/TRRandomizerType.cs rename {TR2RandomizerCore => TRRandomizerCore}/Utilities/EnemyUtilities.cs (93%) rename {TR2RandomizerCore => TRRandomizerCore}/Utilities/ItemUtilities.cs (98%) rename {TR2RandomizerCore => TRRandomizerCore}/Utilities/RoomWaterUtilities.cs (67%) rename {TR2RandomizerCore => TRRandomizerCore}/Utilities/SpatialConverters.cs (90%) rename {TR2RandomizerCore => TRRandomizerCore}/Utilities/TexturePositionMonitor.cs (99%) rename {TR2RandomizerCore => TRRandomizerCore}/Utilities/TexturePositionMonitorBroker.cs (99%) rename {TR2RandomizerCore => TRRandomizerCore}/Utilities/VehicleUtilities.cs (88%) rename {TR2RandomizerCore => TRRandomizerCore}/Zones/LevelZones.cs (92%) rename {TR2RandomizerCore => TRRandomizerCore}/Zones/ZonedLocationCollection.cs (97%) rename {TR2RandomizerView => TRRandomizerView}/App.config (100%) rename {TR2RandomizerView => TRRandomizerView}/App.xaml (89%) rename {TR2RandomizerView => TRRandomizerView}/App.xaml.cs (85%) rename {TR2RandomizerView => TRRandomizerView}/Commands/WindowCommands.cs (98%) rename {TR2RandomizerView => TRRandomizerView}/Controls/EditorControl.xaml (89%) rename {TR2RandomizerView => TRRandomizerView}/Controls/EditorControl.xaml.cs (96%) rename {TR2RandomizerView => TRRandomizerView}/Controls/FolderLoadControl.xaml (95%) rename {TR2RandomizerView => TRRandomizerView}/Controls/FolderLoadControl.xaml.cs (93%) rename {TR2RandomizerView => TRRandomizerView}/Controls/ManagedSeedAdvancedControl.xaml (89%) rename {TR2RandomizerView => TRRandomizerView}/Controls/ManagedSeedAdvancedControl.xaml.cs (94%) rename {TR2RandomizerView => TRRandomizerView}/Controls/ManagedSeedBoolControl.xaml (93%) rename {TR2RandomizerView => TRRandomizerView}/Controls/ManagedSeedBoolControl.xaml.cs (95%) rename {TR2RandomizerView => TRRandomizerView}/Controls/ManagedSeedControl.xaml (87%) rename {TR2RandomizerView => TRRandomizerView}/Controls/ManagedSeedControl.xaml.cs (86%) rename {TR2RandomizerView => TRRandomizerView}/Controls/ManagedSeedIntControl.xaml (93%) rename {TR2RandomizerView => TRRandomizerView}/Controls/ManagedSeedIntControl.xaml.cs (91%) rename {TR2RandomizerView => TRRandomizerView}/Controls/NumericUpDown.xaml (97%) rename {TR2RandomizerView => TRRandomizerView}/Controls/NumericUpDown.xaml.cs (98%) rename {TR2RandomizerView => TRRandomizerView}/Controls/SeedControl.xaml (90%) rename {TR2RandomizerView => TRRandomizerView}/Controls/SeedControl.xaml.cs (97%) rename {TR2RandomizerView => TRRandomizerView}/Converters/BindingProxy.cs (94%) rename {TR2RandomizerView => TRRandomizerView}/Converters/BoolToVisibilityConverter.cs (95%) rename {TR2RandomizerView => TRRandomizerView}/Converters/BooleanAndConverter.cs (83%) rename {TR2RandomizerView => TRRandomizerView}/Converters/ComparisonConverter.cs (92%) rename {TR2RandomizerView => TRRandomizerView}/Converters/InverseBooleanConverter.cs (94%) rename {TR2RandomizerView => TRRandomizerView}/Events/DataFolderEventArgs.cs (51%) rename {TR2RandomizerView => TRRandomizerView}/Events/EditorEventArgs.cs (85%) rename {TR2RandomizerView => TRRandomizerView}/Model/BoolItemControlClass.cs (96%) rename {TR2RandomizerView => TRRandomizerView}/Model/ControllerOptions.cs (87%) rename {TR2RandomizerView => TRRandomizerView}/Model/IRecentFolderOpener.cs (74%) rename {TR2RandomizerView => TRRandomizerView}/Model/ManagedSeed.cs (77%) rename {TR2RandomizerView => TRRandomizerView}/Model/ManagedSeedBool.cs (74%) rename {TR2RandomizerView => TRRandomizerView}/Model/ManagedSeedNumeric.cs (74%) rename {TR2RandomizerView => TRRandomizerView}/Model/RecentFolder.cs (95%) rename {TR2RandomizerView => TRRandomizerView}/Model/RecentFolderList.cs (76%) rename {TR2RandomizerView => TRRandomizerView}/Properties/AssemblyInfo.cs (93%) rename {TR2RandomizerView => TRRandomizerView}/Properties/Resources.Designer.cs (81%) rename {TR2RandomizerView => TRRandomizerView}/Properties/Resources.resx (100%) rename {TR2RandomizerView => TRRandomizerView}/Properties/Settings.Designer.cs (82%) rename {TR2RandomizerView => TRRandomizerView}/Properties/Settings.settings (100%) rename {TR2RandomizerView => TRRandomizerView}/Resources/Darkness/0.jpg (100%) rename {TR2RandomizerView => TRRandomizerView}/Resources/Darkness/1.jpg (100%) rename {TR2RandomizerView => TRRandomizerView}/Resources/Darkness/10.jpg (100%) rename {TR2RandomizerView => TRRandomizerView}/Resources/Darkness/2.jpg (100%) rename {TR2RandomizerView => TRRandomizerView}/Resources/Darkness/3.jpg (100%) rename {TR2RandomizerView => TRRandomizerView}/Resources/Darkness/4.jpg (100%) rename {TR2RandomizerView => TRRandomizerView}/Resources/Darkness/5.jpg (100%) rename {TR2RandomizerView => TRRandomizerView}/Resources/Darkness/6.jpg (100%) rename {TR2RandomizerView => TRRandomizerView}/Resources/Darkness/7.jpg (100%) rename {TR2RandomizerView => TRRandomizerView}/Resources/Darkness/8.jpg (100%) rename {TR2RandomizerView => TRRandomizerView}/Resources/Darkness/9.jpg (100%) rename {TR2RandomizerView => TRRandomizerView}/Resources/arrows.png (100%) rename {TR2RandomizerView => TRRandomizerView}/Resources/down.png (100%) rename {TR2RandomizerView => TRRandomizerView}/Resources/loading.png (100%) rename {TR2RandomizerView => TRRandomizerView}/Resources/rando.ico (100%) rename {TR2RandomizerView => TRRandomizerView}/Resources/rando.png (100%) rename {TR2RandomizerView => TRRandomizerView}/Resources/up.png (100%) rename TR2RandomizerView/TR2RandomizerView.csproj => TRRandomizerView/TRRandomizerView.csproj (97%) rename {TR2RandomizerView => TRRandomizerView}/Updates/Update.cs (94%) rename {TR2RandomizerView => TRRandomizerView}/Updates/UpdateChecker.cs (99%) rename {TR2RandomizerView => TRRandomizerView}/Updates/UpdateEventArgs.cs (86%) rename {TR2RandomizerView => TRRandomizerView}/Utilities/ControlUtils.cs (98%) rename {TR2RandomizerView => TRRandomizerView}/Utilities/WindowUtils.cs (99%) rename {TR2RandomizerView => TRRandomizerView}/Windows/AboutWindow.xaml (98%) rename {TR2RandomizerView => TRRandomizerView}/Windows/AboutWindow.xaml.cs (97%) rename {TR2RandomizerView => TRRandomizerView}/Windows/AdvancedWindow.xaml (98%) rename {TR2RandomizerView => TRRandomizerView}/Windows/AdvancedWindow.xaml.cs (96%) rename {TR2RandomizerView => TRRandomizerView}/Windows/GlobalSeedWindow.xaml (95%) rename {TR2RandomizerView => TRRandomizerView}/Windows/GlobalSeedWindow.xaml.cs (66%) rename {TR2RandomizerView => TRRandomizerView}/Windows/MainWindow.xaml (97%) rename {TR2RandomizerView => TRRandomizerView}/Windows/MainWindow.xaml.cs (98%) rename {TR2RandomizerView => TRRandomizerView}/Windows/MessageWindow.xaml (97%) rename {TR2RandomizerView => TRRandomizerView}/Windows/MessageWindow.xaml.cs (98%) rename {TR2RandomizerView => TRRandomizerView}/Windows/OpenProgressWindow.xaml (97%) rename {TR2RandomizerView => TRRandomizerView}/Windows/OpenProgressWindow.xaml.cs (86%) rename {TR2RandomizerView => TRRandomizerView}/Windows/RandomizeProgressWindow.xaml (97%) rename {TR2RandomizerView => TRRandomizerView}/Windows/RandomizeProgressWindow.xaml.cs (94%) rename {TR2RandomizerView => TRRandomizerView}/Windows/RestoreProgressWindow.xaml (97%) rename {TR2RandomizerView => TRRandomizerView}/Windows/RestoreProgressWindow.xaml.cs (92%) rename {TR2RandomizerView => TRRandomizerView}/Windows/UpdateAvailableWindow.xaml (96%) rename {TR2RandomizerView => TRRandomizerView}/Windows/UpdateAvailableWindow.xaml.cs (97%) rename {TR2RandomizerView => TRRandomizerView}/app.manifest (100%) rename {TR2RandomizerView => TRRandomizerView}/packages.config (100%) diff --git a/Deps/TRGE.Coord.dll b/Deps/TRGE.Coord.dll index 81a90ca0736356f50356a4f735497f9308208949..42b569d494bff51a7051e76cceaff94b4448cc97 100644 GIT binary patch delta 22503 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 diff --git a/Deps/TRGE.Core.dll b/Deps/TRGE.Core.dll index ab62c8818e4e96c84e0e10fe82a3da5b4b984552..2ffbefe2c13428914f8fc503a8a1493d4b1fe4fb 100644 GIT binary patch literal 128000 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 V773KYR=T>Oh3xPC{?OcPQJ1VS@C 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 routeLocations = RouteToLocationsConverter.Convert(filename); //What level are we importing for? - string level = LevelNames.AsList[ImportLevel.SelectedIndex]; + string level = TR2LevelNames.AsList[ImportLevel.SelectedIndex]; //What locations do we want to import for? secrets or items Dictionary> Locations; @@ -263,7 +263,7 @@ private void TextureInject_Click(object sender, RoutedEventArgs e) string CurrentDir = Directory.GetCurrentDirectory(); - string LvlName = LevelNames.AsList[ImportLevel.SelectedIndex]; + string LvlName = TR2LevelNames.AsList[ImportLevel.SelectedIndex]; instance = reader.ReadLevel(LvlName); diff --git a/TR2Randomizer/Randomizers/EnemyRandomizer.cs b/TR2Randomizer/Randomizers/EnemyRandomizer.cs index 79f935116..a32f1ea57 100644 --- a/TR2Randomizer/Randomizers/EnemyRandomizer.cs +++ b/TR2Randomizer/Randomizers/EnemyRandomizer.cs @@ -45,14 +45,14 @@ private void RandomizeEnemyTypes(string lvl) for (int i = 0; i < _levelInstance.Entities.Count(); i++) { - if (lvl == LevelNames.CHICKEN && + if (lvl == TR2LevelNames.CHICKEN && _levelInstance.Entities[i].Room == 143 && _levelInstance.Entities[i].TypeID == (int)TR2Entities.BirdMonster) { //#60 - Ice Palace - Room 143 chicken man must remain to avoid softlock. continue; } - else if (lvl == LevelNames.HOME && _levelInstance.Entities[i].TypeID == (int)TR2Entities.ShotgunGoon) + else if (lvl == TR2LevelNames.HOME && _levelInstance.Entities[i].TypeID == (int)TR2Entities.ShotgunGoon) { //#62 - Avoid randomizing shotgun goon in HSH continue; diff --git a/TR2Randomizer/Randomizers/ItemRandomizer.cs b/TR2Randomizer/Randomizers/ItemRandomizer.cs index 3396078c2..4b4594c9b 100644 --- a/TR2Randomizer/Randomizers/ItemRandomizer.cs +++ b/TR2Randomizer/Randomizers/ItemRandomizer.cs @@ -31,17 +31,17 @@ public override void Randomize(int seed) //Read the level into a level object _levelInstance = LoadLevel(lvl); - if (lvl == LevelNames.RIG) { CleanPlaneCargo(); FindPlaneCargoIndex(); } - if (lvl == LevelNames.HOME) { InjectHSHWeaponTextures(); CleanHSHCloset(); } + if (lvl == TR2LevelNames.RIG) { CleanPlaneCargo(); FindPlaneCargoIndex(); } + if (lvl == TR2LevelNames.HOME) { InjectHSHWeaponTextures(); CleanHSHCloset(); } //Apply the modifications RepositionItems(Locations[lvl]); //#44 - Randomize OR pistol type - if (lvl == LevelNames.RIG) { RandomizeORPistol(); } + if (lvl == TR2LevelNames.RIG) { RandomizeORPistol(); } //#47 - Randomize the HSH weapon closet - if (lvl == LevelNames.HOME) { PopulateHSHCloset(); } + if (lvl == TR2LevelNames.HOME) { PopulateHSHCloset(); } //Write back the level file SaveLevel(_levelInstance, lvl); diff --git a/TR2Randomizer/Randomizers/RandomizerBase.cs b/TR2Randomizer/Randomizers/RandomizerBase.cs index 207f2e7d5..ad067d717 100644 --- a/TR2Randomizer/Randomizers/RandomizerBase.cs +++ b/TR2Randomizer/Randomizers/RandomizerBase.cs @@ -24,7 +24,7 @@ public abstract class RandomizerBase : IRandomizer public RandomizerBase() { - _levels = LevelNames.AsList; + _levels = TR2LevelNames.AsList; _reader = new TR2LevelReader(); _writer = new TR2LevelWriter(); diff --git a/TR2Randomizer/Utilities/RoomWaterUtilities.cs b/TR2Randomizer/Utilities/RoomWaterUtilities.cs index d29975823..afa931da9 100644 --- a/TR2Randomizer/Utilities/RoomWaterUtilities.cs +++ b/TR2Randomizer/Utilities/RoomWaterUtilities.cs @@ -12,94 +12,94 @@ public static class RoomWaterUtilities { public static Dictionary>> RoomRemovalWaterMap = new Dictionary>> { - { LevelNames.GW, new List> + { TR2LevelNames.GW, new List> { //No drain areas defined for now } }, - { LevelNames.VENICE, new List> + { TR2LevelNames.VENICE, new List> { //No drain areas defined for now } }, - { LevelNames.BARTOLI, new List> + { TR2LevelNames.BARTOLI, new List> { //No drain areas defined for now } }, - { LevelNames.OPERA, new List> + { TR2LevelNames.OPERA, new List> { //No drain areas defined for now } }, - { LevelNames.RIG, new List> + { TR2LevelNames.RIG, new List> { //No drain areas defined for now } }, - { LevelNames.DA, new List> + { TR2LevelNames.DA, new List> { //No drain areas defined for now } }, - { LevelNames.FATHOMS, new List> + { TR2LevelNames.FATHOMS, new List> { new List() { 33, 63, 64 } } }, - { LevelNames.DORIA, new List> + { TR2LevelNames.DORIA, new List> { new List() { 19, 42, 112 }, new List() { 85, 94 }, new List() { 2, 6, 7, 87, 88, 99, 100, 101, 102, 103} } }, - { LevelNames.LQ, new List> + { TR2LevelNames.LQ, new List> { new List() { 28, 32, 72, 77 } } }, - { LevelNames.DECK, new List> + { TR2LevelNames.DECK, new List> { new List() { 59, 93 } } }, - { LevelNames.TIBET, new List> + { TR2LevelNames.TIBET, new List> { //No drain areas defined for now } }, - { LevelNames.MONASTERY, new List> + { TR2LevelNames.MONASTERY, new List> { //No drain areas defined for now } }, - { LevelNames.COT, new List> + { TR2LevelNames.COT, new List> { new List() { 21, 22, 28, 82 } } }, - { LevelNames.CHICKEN, new List> + { TR2LevelNames.CHICKEN, new List> { new List() { 24, 29, 71 } } }, - { LevelNames.XIAN, new List> + { TR2LevelNames.XIAN, new List> { //No drain areas defined for now } }, - { LevelNames.FLOATER, new List> + { TR2LevelNames.FLOATER, new List> { //No drain areas defined for now } }, - { LevelNames.LAIR, new List> + { TR2LevelNames.LAIR, new List> { //No drain areas defined for now } }, - { LevelNames.HOME, new List> + { TR2LevelNames.HOME, new List> { //No drain areas defined for now } diff --git a/TR2RandomizerCore/Processors/LevelProcessor.cs b/TR2RandomizerCore/Processors/LevelProcessor.cs deleted file mode 100644 index f41d934a4..000000000 --- a/TR2RandomizerCore/Processors/LevelProcessor.cs +++ /dev/null @@ -1,152 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Runtime.ExceptionServices; -using TR2RandomizerCore.Helpers; -using TRGE.Core; -using TRLevelReader; -using TRLevelReader.Model; - -namespace TR2RandomizerCore.Processors -{ - public class LevelProcessor - { - protected uint _maxThreads; - - protected TR2LevelReader _reader; - protected TR2LevelWriter _writer; - protected TR2CombinedLevel _levelInstance; - - protected ExceptionDispatchInfo _processingException; - - protected readonly object _readLock, _writeLock, _monitorLock; - - internal TR23ScriptEditor ScriptEditor { get; set; } - internal List Levels { get; set; } - internal TRSaveMonitor SaveMonitor; - - public string BasePath { get; set; } - - public LevelProcessor() - { - _reader = new TR2LevelReader(); - _writer = new TR2LevelWriter(); - - _readLock = new object(); - _writeLock = new object(); - _monitorLock = new object(); - - _maxThreads = 3; - } - - protected void LoadLevelInstance(TR23ScriptedLevel scriptedLevel) - { - _levelInstance = LoadCombinedLevel(scriptedLevel); - } - - protected void ReloadLevelInstanceData() - { - _levelInstance.Data = LoadLevelData(_levelInstance.Name); - if (_levelInstance.HasCutScene) - { - _levelInstance.CutSceneLevel.Data = LoadLevelData(_levelInstance.CutSceneLevel.Name); - } - } - - protected void ReloadLevelData(TR2CombinedLevel level) - { - level.Data = LoadLevelData(level.Name); - if (level.HasCutScene) - { - level.CutSceneLevel.Data = LoadLevelData(level.CutSceneLevel.Name); - } - } - - public TR2CombinedLevel LoadCombinedLevel(TR23ScriptedLevel scriptedLevel) - { - TR2CombinedLevel level = new TR2CombinedLevel - { - Data = LoadLevelData(scriptedLevel.LevelFileBaseName), - Script = scriptedLevel - }; - - if (scriptedLevel.HasCutScene) - { - level.CutSceneLevel = LoadCombinedLevel(scriptedLevel.CutSceneLevel as TR23ScriptedLevel); - level.CutSceneLevel.ParentLevel = level; - } - - return level; - } - - public TR2Level LoadLevelData(string name) - { - lock (_readLock) - { - string fullPath = Path.Combine(BasePath, name); - return _reader.ReadLevel(fullPath); - } - } - - protected void SaveLevelInstance() - { - SaveLevel(_levelInstance); - } - - protected void SaveLevel(TR2CombinedLevel level) - { - SaveLevel(level.Data, level.Name); - if (level.HasCutScene) - { - SaveLevel(level.CutSceneLevel.Data, level.CutSceneLevel.Name); - } - - lock (_writeLock) - { - // Save any script changes. - ScriptEditor.SaveScript(); - } - } - - public void SaveLevel(TR2Level level, string name) - { - lock (_writeLock) - { - string fullPath = Path.Combine(BasePath, name); - _writer.WriteLevelToFile(level, fullPath); - } - } - - /// - /// Informs the save monitor to update its progress by 1. - /// - /// True if the save process has not been cancelled and the current error state is null. - internal bool TriggerProgress(int progress = 1) - { - lock (_monitorLock) - { - SaveMonitor.FireSaveStateChanged(progress); - return !SaveMonitor.IsCancelled && _processingException == null; - } - } - - internal void SetMessage(string text) - { - lock (_monitorLock) - { - SaveMonitor.FireSaveStateChanged(customDescription: text); - } - } - - internal void HandleException(Exception e) - { - lock (_monitorLock) - { - if (_processingException == null) - { - _processingException = ExceptionDispatchInfo.Capture(e); - } - } - } - } -} \ No newline at end of file diff --git a/TR2RandomizerCore/Randomizers/RandomizerBase.cs b/TR2RandomizerCore/Randomizers/RandomizerBase.cs deleted file mode 100644 index d5968cd33..000000000 --- a/TR2RandomizerCore/Randomizers/RandomizerBase.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; -using TR2RandomizerCore.Processors; - -namespace TR2RandomizerCore.Randomizers -{ - public abstract class RandomizerBase : LevelProcessor, IRandomizer - { - protected Random _generator; - - public abstract void Randomize(int seed); - } -} \ No newline at end of file diff --git a/TR2RandomizerCore/Randomizers/TR2LevelRandomizer.cs b/TR2RandomizerCore/Randomizers/TR2LevelRandomizer.cs deleted file mode 100644 index abc2a85da..000000000 --- a/TR2RandomizerCore/Randomizers/TR2LevelRandomizer.cs +++ /dev/null @@ -1,511 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using TR2RandomizerCore.Globalisation; -using TR2RandomizerCore.Helpers; -using TR2RandomizerCore.Processors; -using TR2RandomizerCore.Utilities; -using TRGE.Coord; -using TRGE.Core; - -namespace TR2RandomizerCore.Randomizers -{ - public class TR2LevelRandomizer : TR2LevelEditor - { - internal bool RandomizeSecrets { get; set; } - internal bool RandomizeItems { get; set; } - internal bool RandomizeEnemies { get; set; } - internal bool RandomizeTextures { get; set; } - internal bool RandomizeOutfits { get; set; } - internal bool RandomizeGameStrings { get; set; } - internal bool RandomizeNightMode { get; set; } - internal bool RandomizeAudio { get; set; } - internal bool RandomizeStartPosition { get; set; } - internal bool RandomizeEnvironment { get; set; } - - internal int SecretSeed { get; set; } - internal int ItemSeed { get; set; } - internal int EnemySeed { get; set; } - internal int TextureSeed { get; set; } - internal int OutfitSeed { get; set; } - internal int GameStringsSeed { get; set; } - internal int NightModeSeed { get; set; } - internal int AudioSeed { get; set; } - internal int StartPositionSeed { get; set; } - internal int EnvironmentSeed { get; set; } - - internal bool HardSecrets { get; set; } - internal bool IncludeKeyItems { get; set; } - internal bool DevelopmentMode { get; set; } - internal ItemDifficulty RandoItemDifficulty { get; set; } - internal bool PersistTextureVariants { get; set; } - internal bool RetainKeySpriteTextures { get; set; } - internal bool RetainSecretSpriteTextures { get; set; } - internal bool CrossLevelEnemies { get; set; } - internal bool ProtectMonks { get; set; } - internal bool DocileBirdMonsters { get; set; } - internal RandoDifficulty RandoEnemyDifficulty { get; set; } - internal bool GlitchedSecrets { get; set; } - internal bool PersistOutfits { get; set; } - internal bool RemoveRobeDagger { get; set; } - internal uint HaircutLevelCount { get; set; } - internal bool AssaultCourseHaircut { get; set; } - internal uint InvisibleLevelCount { get; set; } - internal bool AssaultCourseInvisible { get; set; } - internal bool RetainLevelNames { get; set; } - internal bool RetainKeyItemNames { get; set; } - internal Language GameStringLanguage { get; set; } - internal uint NightModeCount { get; set; } - internal uint NightModeDarkness { get; set; } - internal bool NightModeAssaultCourse { get; set; } - internal bool ChangeTriggerTracks { get; set; } - internal bool SeparateSecretTracks { get; set; } - internal bool ChangeWeaponSFX { get; set; } - internal bool ChangeCrashSFX { get; set; } - internal bool ChangeEnemySFX { get; set; } - internal bool LinkCreatureSFX { get; set; } - internal bool RotateStartPositionOnly { get; set; } - internal bool RandomizeWaterLevels { get; set; } - internal bool RandomizeSlotPositions { get; set; } - internal bool RandomizeLadders { get; set; } - internal uint MirroredLevelCount { get; set; } - internal bool MirrorAssaultCourse { get; set; } - internal bool AutoLaunchGame { get; set; } - internal bool PuristMode { get; set; } - - internal bool DeduplicateTextures => RandomizeTextures || RandomizeNightMode || (RandomizeEnemies && CrossLevelEnemies) || RandomizeOutfits;// || RandomizeEnvironment; // Not needed until trap model import takes place - internal bool ReassignPuzzleNames => RandomizeEnemies && CrossLevelEnemies; - - internal TR2LevelRandomizer(TRDirectoryIOArgs args) - : base(args) { } - - protected override void ApplyConfig(Config config) - { - int defaultSeed = int.Parse(DateTime.Now.ToString("yyyyMMdd")); - - RandomizeSecrets = config.GetBool(nameof(RandomizeSecrets)); - SecretSeed = config.GetInt(nameof(SecretSeed), defaultSeed); - HardSecrets = config.GetBool(nameof(HardSecrets)); - GlitchedSecrets = config.GetBool(nameof(GlitchedSecrets)); - - RandomizeItems = config.GetBool(nameof(RandomizeItems)); - ItemSeed = config.GetInt(nameof(ItemSeed), defaultSeed); - IncludeKeyItems = config.GetBool(nameof(IncludeKeyItems), true); - RandoItemDifficulty = (ItemDifficulty)config.GetEnum(nameof(RandoItemDifficulty), typeof(ItemDifficulty), ItemDifficulty.Default); - - RandomizeEnemies = config.GetBool(nameof(RandomizeEnemies)); - EnemySeed = config.GetInt(nameof(EnemySeed), defaultSeed); - CrossLevelEnemies = config.GetBool(nameof(CrossLevelEnemies), true); - ProtectMonks = config.GetBool(nameof(ProtectMonks), true); - DocileBirdMonsters = config.GetBool(nameof(DocileBirdMonsters)); - RandoEnemyDifficulty = (RandoDifficulty)config.GetEnum(nameof(RandoEnemyDifficulty), typeof(RandoDifficulty), RandoDifficulty.Default); - - RandomizeTextures = config.GetBool(nameof(RandomizeTextures)); - TextureSeed = config.GetInt(nameof(TextureSeed), defaultSeed); - PersistTextureVariants = config.GetBool(nameof(PersistTextureVariants)); - RetainKeySpriteTextures = config.GetBool(nameof(RetainKeySpriteTextures), true); - RetainSecretSpriteTextures = config.GetBool(nameof(RetainSecretSpriteTextures), true); - - RandomizeOutfits = config.GetBool(nameof(RandomizeOutfits)); - OutfitSeed = config.GetInt(nameof(OutfitSeed), defaultSeed); - PersistOutfits = config.GetBool(nameof(PersistOutfits)); - RemoveRobeDagger = config.GetBool(nameof(RemoveRobeDagger), true); - HaircutLevelCount = config.GetUInt(nameof(HaircutLevelCount), 9); - AssaultCourseHaircut = config.GetBool(nameof(AssaultCourseHaircut), true); - InvisibleLevelCount = config.GetUInt(nameof(InvisibleLevelCount), 2); - AssaultCourseInvisible = config.GetBool(nameof(AssaultCourseInvisible)); - - RandomizeGameStrings = config.GetBool(nameof(RandomizeGameStrings)); - GameStringsSeed = config.GetInt(nameof(GameStringsSeed), defaultSeed); - RetainKeyItemNames = config.GetBool(nameof(RetainKeyItemNames)); - RetainLevelNames = config.GetBool(nameof(RetainLevelNames)); - GameStringLanguage = G11N.Instance.GetLanguage(config.GetString(nameof(GameStringLanguage), Language.DefaultTag)); - - RandomizeNightMode = config.GetBool(nameof(RandomizeNightMode)); - NightModeSeed = config.GetInt(nameof(NightModeSeed), defaultSeed); - NightModeCount = config.GetUInt(nameof(NightModeCount), 1); - NightModeDarkness = config.GetUInt(nameof(NightModeDarkness), 4); - NightModeAssaultCourse = config.GetBool(nameof(NightModeAssaultCourse), true); - - // Note that the main audio config options (on/off and seed) are held in TRGE for now - ChangeTriggerTracks = config.GetBool(nameof(ChangeTriggerTracks), true); - SeparateSecretTracks = config.GetBool(nameof(SeparateSecretTracks), true); - ChangeWeaponSFX = config.GetBool(nameof(ChangeWeaponSFX), true); - ChangeCrashSFX = config.GetBool(nameof(ChangeCrashSFX), true); - ChangeEnemySFX = config.GetBool(nameof(ChangeEnemySFX), true); - LinkCreatureSFX = config.GetBool(nameof(LinkCreatureSFX)); - - RandomizeStartPosition = config.GetBool(nameof(RandomizeStartPosition)); - StartPositionSeed = config.GetInt(nameof(StartPositionSeed), defaultSeed); - RotateStartPositionOnly = config.GetBool(nameof(RotateStartPositionOnly)); - - RandomizeEnvironment = config.GetBool(nameof(RandomizeEnvironment)); - EnvironmentSeed = config.GetInt(nameof(EnvironmentSeed), defaultSeed); - RandomizeWaterLevels = config.GetBool(nameof(RandomizeWaterLevels), true); - RandomizeSlotPositions = config.GetBool(nameof(RandomizeSlotPositions), true); - RandomizeLadders = config.GetBool(nameof(RandomizeLadders), true); - MirroredLevelCount = config.GetUInt(nameof(MirroredLevelCount), 9); - MirrorAssaultCourse = config.GetBool(nameof(MirrorAssaultCourse), true); - - DevelopmentMode = config.GetBool(nameof(DevelopmentMode)); - AutoLaunchGame = config.GetBool(nameof(AutoLaunchGame)); - PuristMode = config.GetBool(nameof(PuristMode)); - } - - protected override void StoreConfig(Config config) - { - config[nameof(RandomizeSecrets)] = RandomizeSecrets; - config[nameof(SecretSeed)] = SecretSeed; - config[nameof(HardSecrets)] = HardSecrets; - config[nameof(GlitchedSecrets)] = GlitchedSecrets; - - config[nameof(RandomizeItems)] = RandomizeItems; - config[nameof(ItemSeed)] = ItemSeed; - config[nameof(IncludeKeyItems)] = IncludeKeyItems; - config[nameof(RandoItemDifficulty)] = RandoItemDifficulty; - - config[nameof(RandomizeEnemies)] = RandomizeEnemies; - config[nameof(EnemySeed)] = EnemySeed; - config[nameof(CrossLevelEnemies)] = CrossLevelEnemies; - config[nameof(ProtectMonks)] = ProtectMonks; - config[nameof(DocileBirdMonsters)] = DocileBirdMonsters; - config[nameof(RandoEnemyDifficulty)] = RandoEnemyDifficulty; - - config[nameof(RandomizeTextures)] = RandomizeTextures; - config[nameof(TextureSeed)] = TextureSeed; - config[nameof(PersistTextureVariants)] = PersistTextureVariants; - config[nameof(RetainKeySpriteTextures)] = RetainKeySpriteTextures; - config[nameof(RetainSecretSpriteTextures)] = RetainSecretSpriteTextures; - - config[nameof(RandomizeOutfits)] = RandomizeOutfits; - config[nameof(OutfitSeed)] = OutfitSeed; - config[nameof(PersistOutfits)] = PersistOutfits; - config[nameof(RemoveRobeDagger)] = RemoveRobeDagger; - config[nameof(HaircutLevelCount)] = HaircutLevelCount; - config[nameof(AssaultCourseHaircut)] = AssaultCourseHaircut; - config[nameof(InvisibleLevelCount)] = InvisibleLevelCount; - config[nameof(AssaultCourseInvisible)] = AssaultCourseInvisible; - - config[nameof(RandomizeGameStrings)] = RandomizeGameStrings; - config[nameof(GameStringsSeed)] = GameStringsSeed; - config[nameof(RetainKeyItemNames)] = RetainKeyItemNames; - config[nameof(RetainLevelNames)] = RetainLevelNames; - config[nameof(GameStringLanguage)] = GameStringLanguage.Tag; - - config[nameof(RandomizeNightMode)] = RandomizeNightMode; - config[nameof(NightModeSeed)] = NightModeSeed; - config[nameof(NightModeCount)] = NightModeCount; - config[nameof(NightModeDarkness)] = NightModeDarkness; - config[nameof(NightModeAssaultCourse)] = NightModeAssaultCourse; - - config[nameof(ChangeTriggerTracks)] = ChangeTriggerTracks; - config[nameof(SeparateSecretTracks)] = SeparateSecretTracks; - config[nameof(ChangeWeaponSFX)] = ChangeWeaponSFX; - config[nameof(ChangeCrashSFX)] = ChangeCrashSFX; - config[nameof(ChangeEnemySFX)] = ChangeEnemySFX; - config[nameof(LinkCreatureSFX)] = LinkCreatureSFX; - - config[nameof(RandomizeStartPosition)] = RandomizeStartPosition; - config[nameof(StartPositionSeed)] = StartPositionSeed; - config[nameof(RotateStartPositionOnly)] = RotateStartPositionOnly; - - config[nameof(RandomizeEnvironment)] = RandomizeEnvironment; - config[nameof(EnvironmentSeed)] = EnvironmentSeed; - config[nameof(RandomizeWaterLevels)] = RandomizeWaterLevels; - config[nameof(RandomizeSlotPositions)] = RandomizeSlotPositions; - config[nameof(RandomizeLadders)] = RandomizeLadders; - config[nameof(MirroredLevelCount)] = MirroredLevelCount; - config[nameof(MirrorAssaultCourse)] = MirrorAssaultCourse; - - config[nameof(DevelopmentMode)] = DevelopmentMode; - config[nameof(AutoLaunchGame)] = AutoLaunchGame; - config[nameof(PuristMode)] = PuristMode; - } - - /// - /// This is called before the script data is saved so gives us an opportunity to - /// customise the script outwith TRGE before the main SaveImpl. - /// - protected override void PreSaveImpl(AbstractTRScriptEditor scriptEditor) - { - // Either fully randomize the gamestrings, or allow for specific strings - // to be replaced if models are being moved around as a result of cross- - // level enemies (e.g. Dagger of Xian). - if (RandomizeGameStrings || ReassignPuzzleNames) - { - GameStringRandomizer stringRandomizer = new GameStringRandomizer - { - ScriptEditor = scriptEditor as TR23ScriptEditor, - RetainKeyItemNames = RetainKeyItemNames, - RetainLevelNames = RetainLevelNames, - Language = GameStringLanguage, - RandomizeAllStrings = RandomizeGameStrings, - ReassignPuzzleNames = ReassignPuzzleNames - }; - stringRandomizer.Randomize(GameStringsSeed); - } - } - - protected override int GetSaveTarget(int numLevels) - { - // TODO: move these target calculations into the relevant classes - they don't belong here - int target = base.GetSaveTarget(numLevels); - if (RandomizeNightMode) - { - target += numLevels; - if (!RandomizeTextures) - { - target += numLevels; - } - } - if (RandomizeSecrets) target += numLevels; - if (RandomizeAudio) target += numLevels; - if (RandomizeItems) target += numLevels * 2; // standard/key rando followed by unarmed logic after enemy rando - if (RandomizeStartPosition) target += numLevels; - if (DeduplicateTextures) target += numLevels * 2; - if (RandomizeEnemies) target += CrossLevelEnemies ? numLevels * 4 : numLevels; // 4 => 3 for multithreading work, 1 for ModelAdjuster - if (RandomizeTextures) target += numLevels * 3; - if (RandomizeOutfits) target += numLevels * 2; - - target += numLevels; // Environment randomizer always runs - - return target; - } - - /// - /// The scripting randomization will be complete at this stage, so access to which levels - /// are available, which are unarmed, ammoless etc is accurate at this point. The list of - /// levels is always in the original sequence when accessed here, but can be sorted by level - /// sequence if it's preferred to add an additional randomization factor. The save monitor - /// is used to report progress and checks should be performed regularly on IsCancelled. - /// - protected override void SaveImpl(AbstractTRScriptEditor scriptEditor, TRSaveMonitor monitor) - { - List levels = new List - ( - scriptEditor.EnabledScriptedLevels.Cast().ToList() - ); - - if (scriptEditor.GymAvailable) - { - levels.Add(scriptEditor.AssaultLevel as TR23ScriptedLevel); - } - - // Each processor will have a reference to the script editor, so can - // make on-the-fly changes as required. - TR23ScriptEditor tr23ScriptEditor = scriptEditor as TR23ScriptEditor; - string wipDirectory = _io.WIPOutputDirectory.FullName; - - // Texture monitoring is needed between enemy and texture randomization - // to track where imported enemies are placed. - using (TexturePositionMonitorBroker textureMonitor = new TexturePositionMonitorBroker()) - { - if (!monitor.IsCancelled && DeduplicateTextures) - { - // This is needed to make as much space as possible available for cross-level enemies. - // We do this if we are implementing cross-level enemies OR if randomizing textures, - // as the texture mapping is optimised for levels that have been deduplicated. - monitor.FireSaveStateBeginning(TRSaveCategory.Custom, "Deduplicating textures"); - new TextureDeduplicator - { - ScriptEditor = tr23ScriptEditor, - Levels = levels, - BasePath = wipDirectory, - SaveMonitor = monitor - }.Deduplicate(); - } - - if (!monitor.IsCancelled && RandomizeSecrets) - { - monitor.FireSaveStateBeginning(TRSaveCategory.Custom, "Randomizing secrets"); - new SecretReplacer - { - ScriptEditor = tr23ScriptEditor, - AllowHard = HardSecrets, - AllowGlitched = GlitchedSecrets, - Levels = levels, - BasePath = wipDirectory, - SaveMonitor = monitor, - IsDevelopmentModeOn = DevelopmentMode - }.Randomize(SecretSeed); - } - - ItemRandomizer itemRandomizer = null; - if (!monitor.IsCancelled && RandomizeItems) - { - monitor.FireSaveStateBeginning(TRSaveCategory.Custom, string.Format("Randomizing standard{0} items", IncludeKeyItems ? " and key" : string.Empty)); - (itemRandomizer = new ItemRandomizer - { - ScriptEditor = tr23ScriptEditor, - Levels = levels, - BasePath = wipDirectory, - SaveMonitor = monitor, - IncludeKeyItems = IncludeKeyItems, - Difficulty = RandoItemDifficulty, - PerformEnemyWeighting = RandomizeEnemies && CrossLevelEnemies, - TextureMonitor = textureMonitor, - IsDevelopmentModeOn = DevelopmentMode - }).Randomize(ItemSeed); - } - - if (!monitor.IsCancelled && RandomizeEnemies) - { - if (CrossLevelEnemies) - { - // For now all P2 items become P3 to avoid dragon issues. This must take place after Item - // randomization for P2/3 zoning because P2 entities will become P3. - monitor.FireSaveStateBeginning(TRSaveCategory.Custom, "Adjusting level models"); - new ModelAdjuster - { - ScriptEditor = tr23ScriptEditor, - Levels = levels, - BasePath = wipDirectory, - SaveMonitor = monitor - }.AdjustModels(); - } - - monitor.FireSaveStateBeginning(TRSaveCategory.Custom, "Randomizing enemies"); - new EnemyRandomizer - { - ScriptEditor = tr23ScriptEditor, - Levels = levels, - BasePath = wipDirectory, - SaveMonitor = monitor, - CrossLevelEnemies = CrossLevelEnemies, - ProtectMonks = ProtectMonks, - DocileBirdMonsters = DocileBirdMonsters, - TextureMonitor = textureMonitor, - RandoEnemyDifficulty = RandoEnemyDifficulty - }.Randomize(EnemySeed); - } - - // Randomize ammo/weapon in unarmed levels post enemy randomization - if (!monitor.IsCancelled && RandomizeItems) - { - monitor.FireSaveStateBeginning(TRSaveCategory.Custom, "Randomizing unarmed level items"); - itemRandomizer.RandomizeAmmo(); - } - - if (!monitor.IsCancelled && RandomizeStartPosition) - { - monitor.FireSaveStateBeginning(TRSaveCategory.Custom, "Randomizing start positions"); - new StartPositionRandomizer - { - ScriptEditor = tr23ScriptEditor, - Levels = levels, - BasePath = wipDirectory, - SaveMonitor = monitor, - RotateOnly = RotateStartPositionOnly, - DevelopmentMode = DevelopmentMode - }.Randomize(StartPositionSeed); - } - - if (!monitor.IsCancelled) - { - monitor.FireSaveStateBeginning(TRSaveCategory.Custom, RandomizeEnvironment ? "Randomizing environment" : "Applying default environment packs"); - new EnvironmentRandomizer - { - ScriptEditor = tr23ScriptEditor, - Levels = levels, - BasePath = wipDirectory, - SaveMonitor = monitor, - EnforcedModeOnly = !RandomizeEnvironment, - PuristMode = PuristMode, - NumMirrorLevels = MirroredLevelCount, - MirrorAssaultCourse = MirrorAssaultCourse, - RandomizeWater = RandomizeWaterLevels, - RandomizeSlots = RandomizeSlotPositions, - RandomizeLadders = RandomizeLadders, - TextureMonitor = textureMonitor - }.Randomize(EnvironmentSeed); - } - - if (!monitor.IsCancelled && RandomizeAudio) - { - monitor.FireSaveStateBeginning(TRSaveCategory.Custom, "Randomizing audio tracks"); - new AudioRandomizer - { - ScriptEditor = tr23ScriptEditor, - Levels = levels, - BasePath = wipDirectory, - SaveMonitor = monitor, - ChangeTriggerTracks = ChangeTriggerTracks, - SeparateSecretTracks = SeparateSecretTracks, - ChangeWeaponSFX = ChangeWeaponSFX, - ChangeCrashSFX = ChangeCrashSFX, - ChangeEnemySFX = ChangeEnemySFX, - LinkCreatureSFX = LinkCreatureSFX - }.Randomize(AudioSeed); - } - - if (!monitor.IsCancelled && RandomizeOutfits) - { - monitor.FireSaveStateBeginning(TRSaveCategory.Custom, "Randomizing outfits"); - new OutfitRandomizer - { - ScriptEditor = tr23ScriptEditor, - Levels = levels, - BasePath = wipDirectory, - SaveMonitor = monitor, - PersistOutfits = PersistOutfits, - RemoveRobeDagger = RemoveRobeDagger, - NumHaircutLevels = HaircutLevelCount, - AssaultCourseHaircut = AssaultCourseHaircut, - NumInvisibleLevels = InvisibleLevelCount, - AssaultCourseInvisible = AssaultCourseInvisible, - TextureMonitor = textureMonitor - }.Randomize(OutfitSeed); - } - - if (!monitor.IsCancelled && RandomizeNightMode) - { - monitor.FireSaveStateBeginning(TRSaveCategory.Custom, "Randomizing night mode"); - new NightModeRandomizer - { - ScriptEditor = tr23ScriptEditor, - Levels = levels, - BasePath = wipDirectory, - SaveMonitor = monitor, - NumLevels = NightModeCount, - DarknessScale = NightModeDarkness, - NightModeAssaultCourse = NightModeAssaultCourse, - TextureMonitor = textureMonitor - }.Randomize(NightModeSeed); - } - - if (!monitor.IsCancelled) - { - if (RandomizeTextures) - { - monitor.FireSaveStateBeginning(TRSaveCategory.Custom, "Randomizing textures"); - new TextureRandomizer - { - ScriptEditor = tr23ScriptEditor, - Levels = levels, - BasePath = wipDirectory, - SaveMonitor = monitor, - PersistVariants = PersistTextureVariants, - RetainKeySprites = RetainKeySpriteTextures, - RetainSecretSprites = RetainSecretSpriteTextures, - NightModeOnly = !RandomizeTextures, - TextureMonitor = textureMonitor - }.Randomize(TextureSeed); - } - else if (RandomizeNightMode) - { - monitor.FireSaveStateBeginning(TRSaveCategory.Custom, "Randomizing night mode textures"); - new TextureRandomizer - { - ScriptEditor = tr23ScriptEditor, - Levels = levels, - BasePath = wipDirectory, - SaveMonitor = monitor, - NightModeOnly = true, - TextureMonitor = textureMonitor - }.Randomize(NightModeSeed); - } - } - } - } - } -} \ No newline at end of file diff --git a/TR2RandomizerCore/TR2RandomizerCore.csproj b/TR2RandomizerCore/TR2RandomizerCore.csproj deleted file mode 100644 index a207648b7..000000000 --- a/TR2RandomizerCore/TR2RandomizerCore.csproj +++ /dev/null @@ -1,107 +0,0 @@ - - - net472 - 4 - Copyright © Tombrunners 2021 - false - - - - False - ..\Deps\RectanglePacker.dll - - - ..\Deps\TRGE.Coord.dll - - - ..\Deps\TRGE.Core.dll - - - - - - - - - - - - - - - - PreserveNewest - - - - - Never - - - Never - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - \ No newline at end of file diff --git a/TR2RandomizerView/Model/ProfileString.cs b/TR2RandomizerView/Model/ProfileString.cs deleted file mode 100644 index 136979c7e..000000000 --- a/TR2RandomizerView/Model/ProfileString.cs +++ /dev/null @@ -1,316 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace TR2RandomizerView.Model -{ - public static class ProfileString - { - /** - * The profile string is composed of three parts. - * 1. Between position 0 and the first position of R, each rando element is encoded as follows: - * RandoElementID + SeedIndex + {CustomInt|CustomBool} - * No separator is used between these. RandoElementID is L, U, A etc; SeedIndex is the base 36 index in - * the seed array to use. If the element has a custom int, this number is added. If it has a custom - * bool and that bool is true, b is added. - * 2. A single R marks the end of the rando elements and the start of the seeds array. - * 3. Each unique seed is added to the end of the string, separated by R. The seed is changed to base 36 - * to keep the string as short as possible (26 chars + 10 digits = 36). - * We could potentially use punctuation in order to use a higher base, which would shorten the string further. - */ - - private const char _levelSeqID = 'L'; - private const char _unarmedID = 'U'; - private const char _ammolessID = 'A'; - private const char _rewardsID = 'B'; - private const char _sunsetsID = 'S'; - private const char _tracksID = 'T'; - private const char _itemsID = 'I'; - private const char _enemiesID = 'E'; - private const char _secretsID = 'C'; - private const char _texturesID = 'X'; - - private static readonly char[] _allIDs = new char[] - { - _levelSeqID, _unarmedID, _ammolessID, _rewardsID, _sunsetsID, _tracksID, _itemsID, _enemiesID, _secretsID, _texturesID - }; - - private const char _seedID = 'R'; - private const char _boolID = 'b'; - - private const string _chars = "0123456789abcdefghijklmnopqrstuvwxyz"; - - private const int _seedBase = 36; - private const int _intBase = 36; - - public static string Create(ControllerOptions controller) - { - List seeds = new List(); - - StringBuilder sb = new StringBuilder(); - BuildRandoString(_levelSeqID, controller.RandomizeLevelSequencing, controller.LevelSequencingSeed, seeds, sb); - BuildRandoString(_unarmedID, controller.RandomizeUnarmedLevels, controller.UnarmedLevelsSeed, seeds, sb); - if (controller.RandomizeUnarmedLevels) - { - sb.Append(ToBase((int)controller.UnarmedLevelCount, _intBase)); - } - BuildRandoString(_ammolessID, controller.RandomizeAmmolessLevels, controller.AmmolessLevelsSeed, seeds, sb); - if (controller.RandomizeAmmolessLevels) - { - sb.Append(ToBase((int)controller.AmmolessLevelCount, _intBase)); - } - - BuildRandoString(_rewardsID, controller.RandomizeSecretRewards, controller.SecretRewardSeed, seeds, sb); - BuildRandoString(_sunsetsID, controller.RandomizeSunsets, controller.SunsetsSeed, seeds, sb); - if (controller.RandomizeSunsets) - { - sb.Append(ToBase((int)controller.SunsetCount, _intBase)); - } - - BuildRandoString(_tracksID, controller.RandomizeAudioTracks, controller.AudioTracksSeed, seeds, sb); - if (controller.RandomizeAudioTracks && controller.IncludeBlankTracks.Value) - { - sb.Append(_boolID); - } - - BuildRandoString(_itemsID, controller.RandomizeItems, controller.ItemSeed, seeds, sb); - if (controller.RandomizeItems && controller.IncludeKeyItems.Value) - { - sb.Append(_boolID); - } - BuildRandoString(_enemiesID, controller.RandomizeEnemies, controller.EnemySeed, seeds, sb); - BuildRandoString(_secretsID, controller.RandomizeSecrets, controller.SecretSeed, seeds, sb); - if (controller.RandomizeSecrets && controller.IsHardSecrets.Value) - { - sb.Append(_boolID); - } - BuildRandoString(_texturesID, controller.RandomizeTextures, controller.TextureSeed, seeds, sb); - - List base36Seeds = new List(); - seeds.ForEach(e => base36Seeds.Add(ToBase(e, _seedBase))); - - return sb.ToString() + _seedID + string.Join(_seedID.ToString(), base36Seeds); - } - - private static void BuildRandoString(char id, bool randoOption, int seed, List seeds, StringBuilder sb) - { - if (randoOption) - { - if (!seeds.Contains(seed)) - { - seeds.Add(seed); - } - - sb.Append(id).Append(ToBase(seeds.IndexOf(seed), _intBase)); - } - } - - private static string ToBase(int value, int bse) - { - if (value == 0) - { - return "0"; - } - - StringBuilder sb = new StringBuilder(); - while (value > 0) - { - sb.Append(_chars[value % bse]); - value /= bse; - } - - return sb.ToString(); - } - - private static int FromBase(string value, int bse) - { - char[] chars = value.ToCharArray(); - int result = 0; - int pos = 0; - foreach (char c in chars) - { - result += _chars.IndexOf(c) * (int)Math.Pow(bse, pos++); - } - return result; - } - - public static void Apply(ControllerOptions controller, string profile) - { - int rpos = profile.IndexOf(_seedID); - if (rpos == -1) - { - throw new ArgumentException(string.Format("Missing {0} separator in profile string.", _seedID)); - } - if (rpos == 0 || rpos == profile.Length - 1) - { - throw new ArgumentException("Invalid separator position in profile string."); - } - - string randoElements = profile.Substring(0, rpos); - string seedElements = profile.Substring(rpos + 1); //skip the first seed separator - - List seeds = new List(); - foreach (string seedString in seedElements.Split(_seedID)) - { - seeds.Add(FromBase(seedString, _seedBase)); - } - - bool randomizeLevelSequencing = false, randomizeUnarmedLevels = false, randomizeAmmolessLevels = false, - randomizeSecretRewards = false, randomizeSunsets = false, randomizeAudioTracks = false, - randomizeItems = false, randomizeSecrets = false, randomizeEnemies = false, randomizeTextures = false; - - int levelSequencingSeed = -1, unarmledSeed = -1, ammolessSeed = -1, - secretRewardsSeed = -1, sunsetsSeed = -1, tracksSeed = -1, - itemsSeed = -1, secretsSeed = -1, enemiesSeed = -1, texturesSeed = -1; - - int unarmedLevelCount = -1, ammolessLevelCount = -1, sunsetCount = -1; - - bool blankTracks = false, includeKeyItems = false, hardSecrets = false; - - for (int i = 0; i < randoElements.Length; i++) - { - char randoID = randoElements[i]; - switch (randoID) - { - case _levelSeqID: - randomizeLevelSequencing = true; - break; - case _unarmedID: - randomizeUnarmedLevels = true; - break; - case _ammolessID: - randomizeAmmolessLevels = true; - break; - case _rewardsID: - randomizeSecretRewards = true; - break; - case _sunsetsID: - randomizeSunsets = true; - break; - case _tracksID: - randomizeAudioTracks = true; - break; - case _itemsID: - randomizeItems = true; - break; - case _enemiesID: - randomizeEnemies = true; - break; - case _secretsID: - randomizeSecrets = true; - break; - case _texturesID: - randomizeTextures = true; - break; - default: - continue; - } - - if (i == randoElements.Length - 1) - { - throw new ArgumentException("Invalid profile string - unexpected EOF."); - } - - string seedString = randoElements[++i].ToString(); - int seedIndex = FromBase(seedString, _intBase); - if (seedIndex < 0 || seedIndex > seeds.Count - 1) - { - throw new ArgumentException(string.Format("Invalid seed index ({0}).", seedString)); - } - - switch (randoID) - { - case _levelSeqID: - levelSequencingSeed = seeds[seedIndex]; - break; - case _unarmedID: - unarmledSeed = seeds[seedIndex]; - break; - case _ammolessID: - ammolessSeed = seeds[seedIndex]; - break; - case _rewardsID: - secretRewardsSeed = seeds[seedIndex]; - break; - case _sunsetsID: - sunsetsSeed = seeds[seedIndex]; - break; - case _tracksID: - tracksSeed = seeds[seedIndex]; - break; - case _itemsID: - itemsSeed = seeds[seedIndex]; - break; - case _enemiesID: - enemiesSeed = seeds[seedIndex]; - break; - case _secretsID: - secretsSeed = seeds[seedIndex]; - break; - case _texturesID: - texturesSeed = seeds[seedIndex]; - break; - default: - continue; - } - - if (i < randoElements.Length - 2 && !_allIDs.Contains(randoElements[i + 1])) - { - char c = randoElements[++i]; - switch (randoID) - { - case _unarmedID: - unarmedLevelCount = FromBase(c.ToString(), _intBase); - break; - case _ammolessID: - ammolessLevelCount = FromBase(c.ToString(), _intBase); - break; - case _sunsetsID: - sunsetCount = FromBase(c.ToString(), _intBase); - break; - case _tracksID: - blankTracks = c == _boolID; - break; - case _secretsID: - hardSecrets = c == _boolID; - break; - case _itemsID: - includeKeyItems = c == _boolID; - break; - } - } - } - - controller.RandomizeLevelSequencing = randomizeLevelSequencing; - controller.RandomizeUnarmedLevels = randomizeUnarmedLevels; - controller.RandomizeAmmolessLevels = randomizeAmmolessLevels; - controller.RandomizeSecretRewards = randomizeSecretRewards; - controller.RandomizeSunsets = randomizeSunsets; - controller.RandomizeAudioTracks = randomizeAudioTracks; - controller.RandomizeItems = randomizeItems; - controller.RandomizeEnemies = randomizeEnemies; - controller.RandomizeSecrets = randomizeSecrets; - controller.RandomizeTextures = randomizeTextures; - - if (levelSequencingSeed != -1) controller.LevelSequencingSeed = levelSequencingSeed; - if (unarmledSeed != -1) controller.UnarmedLevelsSeed = unarmledSeed; - if (ammolessSeed != -1) controller.AmmolessLevelsSeed = ammolessSeed; - if (secretRewardsSeed != -1) controller.SecretRewardSeed = secretRewardsSeed; - if (sunsetsSeed != -1) controller.SunsetsSeed = sunsetsSeed; - if (tracksSeed != -1) controller.AudioTracksSeed = tracksSeed; - if (itemsSeed != -1) controller.ItemSeed = itemsSeed; - if (enemiesSeed != -1) controller.EnemySeed = enemiesSeed; - if (secretsSeed != -1) controller.SecretSeed = secretsSeed; - if (texturesSeed != -1) controller.TextureSeed = texturesSeed; - - if (unarmedLevelCount > 0) controller.UnarmedLevelCount = (uint)unarmedLevelCount; - if (ammolessLevelCount > 0) controller.AmmolessLevelCount = (uint)ammolessLevelCount; - if (sunsetCount > 0) controller.SunsetCount = (uint)sunsetCount; - - controller.IncludeBlankTracks.Value = blankTracks; - controller.IsHardSecrets.Value = hardSecrets; - controller.IncludeKeyItems.Value = includeKeyItems; - } - } -} \ No newline at end of file diff --git a/TREnvironmentEditor/EMEditorMapping.cs b/TREnvironmentEditor/EMEditorMapping.cs index 7920c0812..396539d34 100644 --- a/TREnvironmentEditor/EMEditorMapping.cs +++ b/TREnvironmentEditor/EMEditorMapping.cs @@ -30,9 +30,8 @@ public EMEditorMapping() Mirrored = new EMEditorSet(); } - public static EMEditorMapping Get(string lvlName) + public static EMEditorMapping Get(string packPath) { - string packPath = string.Format(@"Resources\Environment\{0}-Environment.json", lvlName); if (File.Exists(packPath)) { return JsonConvert.DeserializeObject(File.ReadAllText(packPath), _converter); diff --git a/TRFDControl/Utilities/FDUtilities.cs b/TRFDControl/Utilities/FDUtilities.cs index 4268d5335..844e11d63 100644 --- a/TRFDControl/Utilities/FDUtilities.cs +++ b/TRFDControl/Utilities/FDUtilities.cs @@ -74,32 +74,45 @@ public static void RemoveEntityTriggers(TR2Level level, int entityIndex, FDContr { foreach (TR2Room room in level.Rooms) { - foreach (TRRoomSector sector in room.SectorList) + RemoveEntityTriggers(room.SectorList, entityIndex, control); + } + } + + public static void RemoveEntityTriggers(TR3Level level, int entityIndex, FDControl control) + { + foreach (TR3Room room in level.Rooms) + { + RemoveEntityTriggers(room.Sectors, entityIndex, control); + } + } + + public static void RemoveEntityTriggers(IEnumerable sectorList, int entityIndex, FDControl control) + { + foreach (TRRoomSector sector in sectorList) + { + if (sector.FDIndex == 0) { - if (sector.FDIndex == 0) - { - continue; - } + continue; + } - List entries = control.Entries[sector.FDIndex]; - for (int i = entries.Count - 1; i >= 0; i--) + List entries = control.Entries[sector.FDIndex]; + for (int i = entries.Count - 1; i >= 0; i--) + { + FDEntry entry = entries[i]; + if (entry is FDTriggerEntry trig) { - FDEntry entry = entries[i]; - if (entry is FDTriggerEntry trig) + trig.TrigActionList.RemoveAll(a => a.TrigAction == FDTrigAction.Object && a.Parameter == entityIndex); + if (trig.TrigActionList.Count == 0) { - trig.TrigActionList.RemoveAll(a => a.TrigAction == FDTrigAction.Object && a.Parameter == entityIndex); - if (trig.TrigActionList.Count == 0) - { - entries.RemoveAt(i); - } + entries.RemoveAt(i); } } + } - if (entries.Count == 0) - { - // If there isn't anything left, reset the sector to point to the dummy FD - control.RemoveFloorData(sector); - } + if (entries.Count == 0) + { + // If there isn't anything left, reset the sector to point to the dummy FD + control.RemoveFloorData(sector); } } } diff --git a/TRLevelReader/Helpers/LevelNames.cs b/TRLevelReader/Helpers/LevelNames/TR2LevelNames.cs similarity index 94% rename from TRLevelReader/Helpers/LevelNames.cs rename to TRLevelReader/Helpers/LevelNames/TR2LevelNames.cs index d48a0b042..fb532d331 100644 --- a/TRLevelReader/Helpers/LevelNames.cs +++ b/TRLevelReader/Helpers/LevelNames/TR2LevelNames.cs @@ -1,12 +1,8 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System.Collections.Generic; namespace TRLevelReader.Helpers { - public static class LevelNames + public static class TR2LevelNames { public const string GW = "WALL.TR2"; public const string VENICE = "BOAT.TR2"; @@ -92,4 +88,4 @@ public static List AsListGold } } } -} +} \ No newline at end of file diff --git a/TRLevelReader/Helpers/LevelNames/TR3LevelNames.cs b/TRLevelReader/Helpers/LevelNames/TR3LevelNames.cs new file mode 100644 index 000000000..bd0f62089 --- /dev/null +++ b/TRLevelReader/Helpers/LevelNames/TR3LevelNames.cs @@ -0,0 +1,104 @@ +using System.Collections.Generic; + +namespace TRLevelReader.Helpers +{ + public static class TR3LevelNames + { + public const string JUNGLE = "JUNGLE.TR2"; + public const string RUINS = "TEMPLE.TR2"; + public const string GANGES = "QUADCHAS.TR2"; + public const string CAVES = "TONYBOSS.TR2"; + public const string COASTAL = "SHORE.TR2"; + public const string CRASH = "CRASH.TR2"; + public const string MADUBU = "RAPIDS.TR2"; + public const string PUNA = "TRIBOSS.TR2"; + public const string THAMES = "ROOFS.TR2"; + public const string ALDWYCH = "SEWER.TR2"; + public const string LUDS = "TOWER.TR2"; + public const string CITY = "OFFICE.TR2"; + public const string NEVADA = "NEVADA.TR2"; + public const string HSC = "COMPUND.TR2"; + public const string AREA51 = "AREA51.TR2"; + public const string ANTARC = "ANTARC.TR2"; + public const string RXTECH = "MINES.TR2"; + public const string TINNOS = "CITY.TR2"; + public const string WILLY = "CHAMBER.TR2"; + public const string HALLOWS = "STPAUL.TR2"; + public const string ASSAULT = "HOUSE.TR2"; + + public const string JUNGLE_CUT = "CUT6.TR2"; + public const string RUINS_CUT = "CUT9.TR2"; + public const string COASTAL_CUT = "CUT1.TR2"; + public const string CRASH_CUT = "CUT4.TR2"; + public const string THAMES_CUT = "CUT2.TR2"; + public const string ALDWYCH_CUT = "CUT5.TR2"; + public const string LUDS_CUT = "CUT11.TR2"; + public const string NEVADA_CUT = "CUT7.TR2"; + public const string HSC_CUT = "CUT8.TR2"; + public const string ANTARC_CUT = "CUT3.TR2"; + public const string TINNOS_CUT = "CUT12.TR2"; + + public const string FLING = "SCOTLAND.TR2"; + public const string LAIR = "WILLSDEN.TR2"; + public const string CLIFF = "CHUNNEL.TR2"; + public const string FISHES = "UNDERSEA.TR2"; + public const string MADHOUSE = "ZOO.TR2"; + public const string REUNION = "SLINC.TR2"; + + public static List AsList + { + get + { + return new List + { + JUNGLE, + RUINS, + GANGES, + CAVES, + COASTAL, + CRASH, + MADUBU, + PUNA, + THAMES, + ALDWYCH, + LUDS, + CITY, + NEVADA, + HSC, + AREA51, + ANTARC, + RXTECH, + TINNOS, + WILLY, + HALLOWS + }; + } + } + + public static List AsListWithAssault + { + get + { + List lvls = AsList; + lvls.Add(ASSAULT); + return lvls; + } + } + + public static List AsListGold + { + get + { + return new List + { + FLING, + LAIR, + CLIFF, + FISHES, + MADHOUSE, + REUNION + }; + } + } + } +} \ No newline at end of file diff --git a/TRLevelReader/Helpers/TR2EntityUtilities.cs b/TRLevelReader/Helpers/TR2EntityUtilities.cs index 7d3d29e6b..b2e0e11b1 100644 --- a/TRLevelReader/Helpers/TR2EntityUtilities.cs +++ b/TRLevelReader/Helpers/TR2EntityUtilities.cs @@ -10,44 +10,44 @@ public static class TR2EntityUtilities [TR2Entities.Lara] = new Dictionary> { [TR2Entities.LaraSun] = - new List { LevelNames.GW, LevelNames.GW_CUT, LevelNames.VENICE, LevelNames.BARTOLI, LevelNames.OPERA, LevelNames.OPERA_CUT, LevelNames.RIG, LevelNames.DA, LevelNames.DA_CUT, LevelNames.XIAN, LevelNames.XIAN_CUT, LevelNames.FLOATER, LevelNames.LAIR }, + new List { TR2LevelNames.GW, TR2LevelNames.GW_CUT, TR2LevelNames.VENICE, TR2LevelNames.BARTOLI, TR2LevelNames.OPERA, TR2LevelNames.OPERA_CUT, TR2LevelNames.RIG, TR2LevelNames.DA, TR2LevelNames.DA_CUT, TR2LevelNames.XIAN, TR2LevelNames.XIAN_CUT, TR2LevelNames.FLOATER, TR2LevelNames.LAIR }, [TR2Entities.LaraUnwater] = - new List { LevelNames.FATHOMS, LevelNames.DORIA, LevelNames.LQ, LevelNames.DECK }, + new List { TR2LevelNames.FATHOMS, TR2LevelNames.DORIA, TR2LevelNames.LQ, TR2LevelNames.DECK }, [TR2Entities.LaraSnow] = - new List { LevelNames.TIBET, LevelNames.MONASTERY, LevelNames.COT, LevelNames.CHICKEN }, + new List { TR2LevelNames.TIBET, TR2LevelNames.MONASTERY, TR2LevelNames.COT, TR2LevelNames.CHICKEN }, [TR2Entities.LaraHome] = - new List { LevelNames.HOME } + new List { TR2LevelNames.HOME } }, [TR2Entities.Barracuda] = new Dictionary> { [TR2Entities.BarracudaIce] = - new List { LevelNames.COT, LevelNames.CHICKEN }, + new List { TR2LevelNames.COT, TR2LevelNames.CHICKEN }, [TR2Entities.BarracudaUnwater] = - new List { LevelNames.FATHOMS, LevelNames.DORIA, LevelNames.LQ, LevelNames.DECK }, + new List { TR2LevelNames.FATHOMS, TR2LevelNames.DORIA, TR2LevelNames.LQ, TR2LevelNames.DECK }, [TR2Entities.BarracudaXian] = - new List { LevelNames.XIAN } + new List { TR2LevelNames.XIAN } }, [TR2Entities.StickWieldingGoon1] = new Dictionary> { [TR2Entities.StickWieldingGoon1Bandana] = - new List { LevelNames.RIG, LevelNames.DA }, + new List { TR2LevelNames.RIG, TR2LevelNames.DA }, [TR2Entities.StickWieldingGoon1BlackJacket] = - new List { LevelNames.HOME }, + new List { TR2LevelNames.HOME }, [TR2Entities.StickWieldingGoon1BodyWarmer] = - new List { LevelNames.VENICE }, + new List { TR2LevelNames.VENICE }, [TR2Entities.StickWieldingGoon1GreenVest] = - new List { LevelNames.FATHOMS, LevelNames.DORIA, LevelNames.LQ, LevelNames.DECK }, + new List { TR2LevelNames.FATHOMS, TR2LevelNames.DORIA, TR2LevelNames.LQ, TR2LevelNames.DECK }, [TR2Entities.StickWieldingGoon1WhiteVest] = - new List { LevelNames.BARTOLI, LevelNames.OPERA } + new List { TR2LevelNames.BARTOLI, TR2LevelNames.OPERA } }, [TR2Entities.TigerOrSnowLeopard] = new Dictionary> { [TR2Entities.BengalTiger] = - new List { LevelNames.GW, LevelNames.XIAN }, + new List { TR2LevelNames.GW, TR2LevelNames.XIAN }, [TR2Entities.SnowLeopard] = - new List { LevelNames.TIBET, LevelNames.COT }, + new List { TR2LevelNames.TIBET, TR2LevelNames.COT }, [TR2Entities.WhiteTiger] = - new List { LevelNames.CHICKEN } + new List { TR2LevelNames.CHICKEN } } }; @@ -325,79 +325,79 @@ public static Dictionary> GetEnemyTypeDictionary() { return new Dictionary> { - { LevelNames.GW, + { TR2LevelNames.GW, new List{ TR2Entities.Crow, TR2Entities.TigerOrSnowLeopard, TR2Entities.Spider, TR2Entities.TRex } }, - { LevelNames.VENICE, + { TR2LevelNames.VENICE, new List{ TR2Entities.Doberman, TR2Entities.MaskedGoon2, TR2Entities.MaskedGoon3, TR2Entities.StickWieldingGoon1, TR2Entities.Rat, TR2Entities.MaskedGoon1 } }, - { LevelNames.BARTOLI, + { TR2LevelNames.BARTOLI, new List{ TR2Entities.StickWieldingGoon1, TR2Entities.Doberman, TR2Entities.MaskedGoon1, TR2Entities.MaskedGoon2, TR2Entities.MaskedGoon3, TR2Entities.Rat } }, - { LevelNames.OPERA, + { TR2LevelNames.OPERA, new List{ TR2Entities.Doberman, TR2Entities.MaskedGoon1, TR2Entities.MaskedGoon2, TR2Entities.MaskedGoon3, TR2Entities.Rat, TR2Entities.StickWieldingGoon1, TR2Entities.ShotgunGoon } }, - { LevelNames.RIG, + { TR2LevelNames.RIG, new List{ TR2Entities.Gunman2, TR2Entities.StickWieldingGoon1, TR2Entities.Doberman, TR2Entities.Gunman1, TR2Entities.ScubaDiver } }, - { LevelNames.DA, + { TR2LevelNames.DA, new List{ TR2Entities.FlamethrowerGoon, TR2Entities.StickWieldingGoon1, TR2Entities.Doberman, TR2Entities.Gunman1, TR2Entities.Gunman2, TR2Entities.ScubaDiver } }, - { LevelNames.FATHOMS, + { TR2LevelNames.FATHOMS, new List{ TR2Entities.Shark, TR2Entities.ScubaDiver, TR2Entities.Gunman1, TR2Entities.Barracuda, TR2Entities.StickWieldingGoon1 } }, - { LevelNames.DORIA, + { TR2LevelNames.DORIA, new List{ TR2Entities.Shark, TR2Entities.ScubaDiver, TR2Entities.Gunman1, TR2Entities.Barracuda, TR2Entities.StickWieldingGoon1, TR2Entities.YellowMorayEel, TR2Entities.Gunman2 } }, - { LevelNames.LQ, + { TR2LevelNames.LQ, new List{ TR2Entities.StickWieldingGoon2, TR2Entities.StickWieldingGoon1, TR2Entities.Gunman1, TR2Entities.ScubaDiver, TR2Entities.BlackMorayEel, TR2Entities.Barracuda } }, - { LevelNames.DECK, + { TR2LevelNames.DECK, new List{ TR2Entities.StickWieldingGoon1, TR2Entities.FlamethrowerGoon, TR2Entities.Barracuda, TR2Entities.ScubaDiver, TR2Entities.Shark, TR2Entities.Gunman1 } }, - { LevelNames.TIBET, + { TR2LevelNames.TIBET, new List{ TR2Entities.Eagle, TR2Entities.Mercenary2, TR2Entities.Mercenary3, TR2Entities.TigerOrSnowLeopard, TR2Entities.MercSnowmobDriver } }, - { LevelNames.MONASTERY, + { TR2LevelNames.MONASTERY, new List{ TR2Entities.MonkWithKnifeStick, TR2Entities.MonkWithLongStick, TR2Entities.Mercenary1, TR2Entities.Crow, TR2Entities.Mercenary2 } }, - { LevelNames.COT, + { TR2LevelNames.COT, new List{ TR2Entities.TigerOrSnowLeopard, TR2Entities.Mercenary1, TR2Entities.Mercenary2, TR2Entities.Yeti, TR2Entities.Barracuda } }, - { LevelNames.CHICKEN, + { TR2LevelNames.CHICKEN, new List{ TR2Entities.TigerOrSnowLeopard, TR2Entities.Barracuda, TR2Entities.Yeti, TR2Entities.BirdMonster } }, - { LevelNames.XIAN, + { TR2LevelNames.XIAN, new List{ TR2Entities.Barracuda, TR2Entities.TigerOrSnowLeopard, TR2Entities.Eagle, TR2Entities.Spider, TR2Entities.GiantSpider } }, - { LevelNames.FLOATER, + { TR2LevelNames.FLOATER, new List{ TR2Entities.XianGuardSword, TR2Entities.XianGuardSpear, TR2Entities.Knifethrower } }, - { LevelNames.LAIR, + { TR2LevelNames.LAIR, new List{ TR2Entities.Knifethrower, TR2Entities.XianGuardSpear, TR2Entities.MarcoBartoli } }, - { LevelNames.HOME, + { TR2LevelNames.HOME, new List{ TR2Entities.Doberman, TR2Entities.MaskedGoon1, TR2Entities.StickWieldingGoon1, TR2Entities.ShotgunGoon } }, - { LevelNames.ASSAULT, + { TR2LevelNames.ASSAULT, new List{ } }, @@ -625,75 +625,75 @@ public static Dictionary> DroppableEnemyTypes() { return new Dictionary> { - { LevelNames.GW, + { TR2LevelNames.GW, new List{ } }, - { LevelNames.VENICE, + { TR2LevelNames.VENICE, new List{ TR2Entities.Doberman, TR2Entities.MaskedGoon2, TR2Entities.MaskedGoon3, TR2Entities.StickWieldingGoon1, TR2Entities.MaskedGoon1 } }, - { LevelNames.BARTOLI, + { TR2LevelNames.BARTOLI, new List{ TR2Entities.StickWieldingGoon1, TR2Entities.Doberman, TR2Entities.MaskedGoon1, TR2Entities.MaskedGoon2, TR2Entities.MaskedGoon3, TR2Entities.StickWieldingGoon1 } }, - { LevelNames.OPERA, + { TR2LevelNames.OPERA, new List{ TR2Entities.StickWieldingGoon1, TR2Entities.Doberman, TR2Entities.MaskedGoon1, TR2Entities.MaskedGoon2, TR2Entities.MaskedGoon3, TR2Entities.Rat, TR2Entities.StickWieldingGoon1, TR2Entities.ShotgunGoon } }, - { LevelNames.RIG, + { TR2LevelNames.RIG, new List{ TR2Entities.Gunman2, TR2Entities.StickWieldingGoon1, TR2Entities.Doberman, TR2Entities.Gunman1 } }, - { LevelNames.DA, + { TR2LevelNames.DA, new List{ TR2Entities.FlamethrowerGoon, TR2Entities.StickWieldingGoon1, TR2Entities.Doberman, TR2Entities.Gunman1, TR2Entities.Gunman2 } }, - { LevelNames.FATHOMS, + { TR2LevelNames.FATHOMS, new List{ TR2Entities.Gunman1, TR2Entities.StickWieldingGoon1 } }, - { LevelNames.DORIA, + { TR2LevelNames.DORIA, new List{ TR2Entities.Gunman1, TR2Entities.StickWieldingGoon1, TR2Entities.Gunman2 } }, - { LevelNames.LQ, + { TR2LevelNames.LQ, new List{ TR2Entities.StickWieldingGoon2, TR2Entities.StickWieldingGoon1, TR2Entities.Gunman1 } }, - { LevelNames.DECK, + { TR2LevelNames.DECK, new List{ TR2Entities.StickWieldingGoon1, TR2Entities.FlamethrowerGoon, TR2Entities.Gunman1 } }, - { LevelNames.TIBET, + { TR2LevelNames.TIBET, new List{ TR2Entities.Mercenary2, TR2Entities.Mercenary3 } }, - { LevelNames.MONASTERY, + { TR2LevelNames.MONASTERY, new List{ TR2Entities.MonkWithKnifeStick, TR2Entities.MonkWithLongStick, TR2Entities.Mercenary1, TR2Entities.Mercenary2 } }, - { LevelNames.COT, + { TR2LevelNames.COT, new List{ TR2Entities.Mercenary1, TR2Entities.Mercenary2 } }, - { LevelNames.CHICKEN, + { TR2LevelNames.CHICKEN, new List{ } }, - { LevelNames.XIAN, + { TR2LevelNames.XIAN, new List{ } }, - { LevelNames.FLOATER, + { TR2LevelNames.FLOATER, new List{ TR2Entities.Knifethrower } }, - { LevelNames.LAIR, + { TR2LevelNames.LAIR, new List{ TR2Entities.Knifethrower } }, - { LevelNames.HOME, + { TR2LevelNames.HOME, new List{ TR2Entities.Doberman, TR2Entities.MaskedGoon1, TR2Entities.ShotgunGoon, TR2Entities.StickWieldingGoon1 } }, diff --git a/TRModelTransporter/Utilities/MassTRModelExporter.cs b/TRModelTransporter/Utilities/MassTRModelExporter.cs index 5f4123a05..4e6fb261e 100644 --- a/TRModelTransporter/Utilities/MassTRModelExporter.cs +++ b/TRModelTransporter/Utilities/MassTRModelExporter.cs @@ -26,7 +26,7 @@ public MassTRModelExporter(bool exportIndividualSegments) public void Export(string levelFileDirectory) { - List allLevels = LevelNames.AsListWithAssault; + List allLevels = TR2LevelNames.AsListWithAssault; foreach (string lvlName in allLevels) { if (ExportModelTypes.ContainsKey(lvlName)) @@ -61,7 +61,7 @@ private void Export(string levelPath, TR2Entities entity) public static readonly Dictionary> ExportModelTypes = new Dictionary> { - { LevelNames.GW, + { TR2LevelNames.GW, new List { TR2Entities.Pistols_M_H, TR2Entities.Shotgun_M_H, TR2Entities.Uzi_M_H, TR2Entities.Autos_M_H, TR2Entities.Harpoon_M_H, TR2Entities.M16_M_H, TR2Entities.GrenadeLauncher_M_H, @@ -69,71 +69,71 @@ private void Export(string levelPath, TR2Entities entity) } }, - { LevelNames.VENICE, + { TR2LevelNames.VENICE, new List{ TR2Entities.Boat, TR2Entities.Doberman, TR2Entities.MaskedGoon1, TR2Entities.MaskedGoon2, TR2Entities.MaskedGoon3, TR2Entities.Rat, TR2Entities.StickWieldingGoon1BodyWarmer } }, - { LevelNames.BARTOLI, + { TR2LevelNames.BARTOLI, new List{ TR2Entities.StickWieldingGoon1WhiteVest } }, - { LevelNames.OPERA, + { TR2LevelNames.OPERA, new List{ TR2Entities.ShotgunGoon } }, - { LevelNames.RIG, + { TR2LevelNames.RIG, new List{ TR2Entities.Gunman1, TR2Entities.Gunman2, TR2Entities.ScubaDiver, TR2Entities.StickWieldingGoon1Bandana } }, - { LevelNames.DA, + { TR2LevelNames.DA, new List{ TR2Entities.FlamethrowerGoon } }, - { LevelNames.FATHOMS, + { TR2LevelNames.FATHOMS, new List{ TR2Entities.LaraUnwater, TR2Entities.BarracudaUnwater, TR2Entities.Shark } }, - { LevelNames.DORIA, + { TR2LevelNames.DORIA, new List{ TR2Entities.StickWieldingGoon1GreenVest, TR2Entities.YellowMorayEel } }, - { LevelNames.LQ, + { TR2LevelNames.LQ, new List{ TR2Entities.BlackMorayEel, TR2Entities.StickWieldingGoon2 } }, - { LevelNames.TIBET, + { TR2LevelNames.TIBET, new List{ TR2Entities.LaraSnow, TR2Entities.Eagle, TR2Entities.Mercenary2, TR2Entities.Mercenary3, TR2Entities.MercSnowmobDriver, TR2Entities.SnowLeopard } }, - { LevelNames.MONASTERY, + { TR2LevelNames.MONASTERY, new List{ TR2Entities.Mercenary1, TR2Entities.MonkWithKnifeStick, TR2Entities.MonkWithLongStick } }, - { LevelNames.COT, + { TR2LevelNames.COT, new List{ TR2Entities.BarracudaIce, TR2Entities.Yeti } }, - { LevelNames.CHICKEN, + { TR2LevelNames.CHICKEN, new List{ TR2Entities.BirdMonster, TR2Entities.WhiteTiger } }, - { LevelNames.XIAN, + { TR2LevelNames.XIAN, new List{ TR2Entities.BarracudaXian, TR2Entities.GiantSpider } }, - { LevelNames.FLOATER, + { TR2LevelNames.FLOATER, new List{ TR2Entities.Knifethrower, TR2Entities.XianGuardSword, TR2Entities.XianGuardSpear } }, - { LevelNames.LAIR, + { TR2LevelNames.LAIR, new List{ TR2Entities.MarcoBartoli } }, - { LevelNames.HOME, + { TR2LevelNames.HOME, new List{ TR2Entities.LaraHome, TR2Entities.StickWieldingGoon1BlackJacket } }, - { LevelNames.ASSAULT, + { TR2LevelNames.ASSAULT, new List{ TR2Entities.Winston } } }; diff --git a/TRModelTransporter/Utilities/MassTRTextureDeduplicator.cs b/TRModelTransporter/Utilities/MassTRTextureDeduplicator.cs index 46d0cb36e..4767f91b3 100644 --- a/TRModelTransporter/Utilities/MassTRTextureDeduplicator.cs +++ b/TRModelTransporter/Utilities/MassTRTextureDeduplicator.cs @@ -43,7 +43,7 @@ public void Export() try { - foreach (string lvlName in LevelNames.AsList) + foreach (string lvlName in TR2LevelNames.AsList) { _currentLevel = lvlName; _currentSave = 0; @@ -67,7 +67,7 @@ public void Export() public void Import() { - foreach (string lvlName in LevelNames.AsList) + foreach (string lvlName in TR2LevelNames.AsList) { string lvlPath = Path.Combine(_levelFileDirectory, lvlName); string mapPath = Path.Combine(_outputDirectory, lvlName + "-TextureRemap.json"); diff --git a/TR2Randomizer.sln b/TRRandomizer.sln similarity index 94% rename from TR2Randomizer.sln rename to TRRandomizer.sln index 7360fdf4b..54be9396c 100644 --- a/TR2Randomizer.sln +++ b/TRRandomizer.sln @@ -17,9 +17,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TextureExport", "TextureExp EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TRTexture16Importer", "TRTexture16Importer\TRTexture16Importer.csproj", "{29F10C62-F4D8-4ACA-91ED-6920AE3F1AC0}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TR2RandomizerView", "TR2RandomizerView\TR2RandomizerView.csproj", "{6CE82358-524D-4B12-A514-0903521ED13C}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TRRandomizerView", "TRRandomizerView\TRRandomizerView.csproj", "{6CE82358-524D-4B12-A514-0903521ED13C}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TR2RandomizerCore", "TR2RandomizerCore\TR2RandomizerCore.csproj", "{B657D758-A095-44B5-AEF1-C77C30667DAF}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TRRandomizerCore", "TRRandomizerCore\TRRandomizerCore.csproj", "{B657D758-A095-44B5-AEF1-C77C30667DAF}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TRFDControl", "TRFDControl\TRFDControl.csproj", "{09ABCF27-6777-4866-8740-3EAD3F6B86FC}" EndProject @@ -27,7 +27,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TRModelTransporter", "TRMod EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TREnvironmentEditor", "TREnvironmentEditor\TREnvironmentEditor.csproj", "{1667C53D-0CCA-48A9-90B7-4950BD92BDFF}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SFXExport", "SFXExport\SFXExport.csproj", "{D3662F36-C8D8-471C-8F43-192CE748B04E}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SFXExport", "SFXExport\SFXExport.csproj", "{D3662F36-C8D8-471C-8F43-192CE748B04E}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/TRRandomizerCore/Editors/ISettingsProvider.cs b/TRRandomizerCore/Editors/ISettingsProvider.cs new file mode 100644 index 000000000..b609196eb --- /dev/null +++ b/TRRandomizerCore/Editors/ISettingsProvider.cs @@ -0,0 +1,7 @@ +namespace TRRandomizerCore.Editors +{ + public interface ISettingsProvider + { + RandomizerSettings Settings { get; } + } +} \ No newline at end of file diff --git a/TRRandomizerCore/Editors/RandomizerSettings.cs b/TRRandomizerCore/Editors/RandomizerSettings.cs new file mode 100644 index 000000000..57bed95bf --- /dev/null +++ b/TRRandomizerCore/Editors/RandomizerSettings.cs @@ -0,0 +1,287 @@ +using System; +using TRRandomizerCore.Globalisation; +using TRRandomizerCore.Helpers; +using TRGE.Core; + +namespace TRRandomizerCore.Editors +{ + public class RandomizerSettings + { + public bool RandomizeSecrets { get; set; } + public bool RandomizeItems { get; set; } + public bool RandomizeEnemies { get; set; } + public bool RandomizeTextures { get; set; } + public bool RandomizeOutfits { get; set; } + public bool RandomizeGameStrings { get; set; } + public bool RandomizeNightMode { get; set; } + public bool RandomizeAudio { get; set; } + public bool RandomizeStartPosition { get; set; } + public bool RandomizeEnvironment { get; set; } + + public int SecretSeed { get; set; } + public int ItemSeed { get; set; } + public int EnemySeed { get; set; } + public int TextureSeed { get; set; } + public int OutfitSeed { get; set; } + public int GameStringsSeed { get; set; } + public int NightModeSeed { get; set; } + public int AudioSeed { get; set; } + public int StartPositionSeed { get; set; } + public int EnvironmentSeed { get; set; } + + public bool HardSecrets { get; set; } + public bool IncludeKeyItems { get; set; } + public bool DevelopmentMode { get; set; } + public ItemDifficulty RandoItemDifficulty { get; set; } + public bool PersistTextureVariants { get; set; } + public bool RetainKeySpriteTextures { get; set; } + public bool RetainSecretSpriteTextures { get; set; } + public bool CrossLevelEnemies { get; set; } + public bool ProtectMonks { get; set; } + public bool DocileBirdMonsters { get; set; } + public RandoDifficulty RandoEnemyDifficulty { get; set; } + public bool GlitchedSecrets { get; set; } + public bool PersistOutfits { get; set; } + public bool RemoveRobeDagger { get; set; } + public uint HaircutLevelCount { get; set; } + public bool AssaultCourseHaircut { get; set; } + public uint InvisibleLevelCount { get; set; } + public bool AssaultCourseInvisible { get; set; } + public bool RetainLevelNames { get; set; } + public bool RetainKeyItemNames { get; set; } + public Language GameStringLanguage { get; set; } + public uint NightModeCount { get; set; } + public uint NightModeDarkness { get; set; } + public bool NightModeAssaultCourse { get; set; } + public bool ChangeTriggerTracks { get; set; } + public bool SeparateSecretTracks { get; set; } + public bool ChangeWeaponSFX { get; set; } + public bool ChangeCrashSFX { get; set; } + public bool ChangeEnemySFX { get; set; } + public bool LinkCreatureSFX { get; set; } + public bool RotateStartPositionOnly { get; set; } + public bool RandomizeWaterLevels { get; set; } + public bool RandomizeSlotPositions { get; set; } + public bool RandomizeLadders { get; set; } + public uint MirroredLevelCount { get; set; } + public bool MirrorAssaultCourse { get; set; } + public bool AutoLaunchGame { get; set; } + public bool PuristMode { get; set; } + + public bool DeduplicateTextures => RandomizeTextures || RandomizeNightMode || (RandomizeEnemies && CrossLevelEnemies) || RandomizeOutfits;// || RandomizeEnvironment; // Not needed until trap model import takes place + public bool ReassignPuzzleNames => RandomizeEnemies && CrossLevelEnemies; + + public void ApplyConfig(Config config) + { + int defaultSeed = int.Parse(DateTime.Now.ToString("yyyyMMdd")); + + RandomizeSecrets = config.GetBool(nameof(RandomizeSecrets)); + SecretSeed = config.GetInt(nameof(SecretSeed), defaultSeed); + HardSecrets = config.GetBool(nameof(HardSecrets)); + GlitchedSecrets = config.GetBool(nameof(GlitchedSecrets)); + + RandomizeItems = config.GetBool(nameof(RandomizeItems)); + ItemSeed = config.GetInt(nameof(ItemSeed), defaultSeed); + IncludeKeyItems = config.GetBool(nameof(IncludeKeyItems), true); + RandoItemDifficulty = (ItemDifficulty)config.GetEnum(nameof(RandoItemDifficulty), typeof(ItemDifficulty), ItemDifficulty.Default); + + RandomizeEnemies = config.GetBool(nameof(RandomizeEnemies)); + EnemySeed = config.GetInt(nameof(EnemySeed), defaultSeed); + CrossLevelEnemies = config.GetBool(nameof(CrossLevelEnemies), true); + ProtectMonks = config.GetBool(nameof(ProtectMonks), true); + DocileBirdMonsters = config.GetBool(nameof(DocileBirdMonsters)); + RandoEnemyDifficulty = (RandoDifficulty)config.GetEnum(nameof(RandoEnemyDifficulty), typeof(RandoDifficulty), RandoDifficulty.Default); + + RandomizeTextures = config.GetBool(nameof(RandomizeTextures)); + TextureSeed = config.GetInt(nameof(TextureSeed), defaultSeed); + PersistTextureVariants = config.GetBool(nameof(PersistTextureVariants)); + RetainKeySpriteTextures = config.GetBool(nameof(RetainKeySpriteTextures), true); + RetainSecretSpriteTextures = config.GetBool(nameof(RetainSecretSpriteTextures), true); + + RandomizeOutfits = config.GetBool(nameof(RandomizeOutfits)); + OutfitSeed = config.GetInt(nameof(OutfitSeed), defaultSeed); + PersistOutfits = config.GetBool(nameof(PersistOutfits)); + RemoveRobeDagger = config.GetBool(nameof(RemoveRobeDagger), true); + HaircutLevelCount = config.GetUInt(nameof(HaircutLevelCount), 9); + AssaultCourseHaircut = config.GetBool(nameof(AssaultCourseHaircut), true); + InvisibleLevelCount = config.GetUInt(nameof(InvisibleLevelCount), 2); + AssaultCourseInvisible = config.GetBool(nameof(AssaultCourseInvisible)); + + RandomizeGameStrings = config.GetBool(nameof(RandomizeGameStrings)); + GameStringsSeed = config.GetInt(nameof(GameStringsSeed), defaultSeed); + RetainKeyItemNames = config.GetBool(nameof(RetainKeyItemNames)); + RetainLevelNames = config.GetBool(nameof(RetainLevelNames)); + GameStringLanguage = G11N.Instance.GetLanguage(config.GetString(nameof(GameStringLanguage), Language.DefaultTag)); + + RandomizeNightMode = config.GetBool(nameof(RandomizeNightMode)); + NightModeSeed = config.GetInt(nameof(NightModeSeed), defaultSeed); + NightModeCount = config.GetUInt(nameof(NightModeCount), 1); + NightModeDarkness = config.GetUInt(nameof(NightModeDarkness), 4); + NightModeAssaultCourse = config.GetBool(nameof(NightModeAssaultCourse), true); + + // Note that the main audio config options (on/off and seed) are held in TRGE for now + ChangeTriggerTracks = config.GetBool(nameof(ChangeTriggerTracks), true); + SeparateSecretTracks = config.GetBool(nameof(SeparateSecretTracks), true); + ChangeWeaponSFX = config.GetBool(nameof(ChangeWeaponSFX), true); + ChangeCrashSFX = config.GetBool(nameof(ChangeCrashSFX), true); + ChangeEnemySFX = config.GetBool(nameof(ChangeEnemySFX), true); + LinkCreatureSFX = config.GetBool(nameof(LinkCreatureSFX)); + + RandomizeStartPosition = config.GetBool(nameof(RandomizeStartPosition)); + StartPositionSeed = config.GetInt(nameof(StartPositionSeed), defaultSeed); + RotateStartPositionOnly = config.GetBool(nameof(RotateStartPositionOnly)); + + RandomizeEnvironment = config.GetBool(nameof(RandomizeEnvironment)); + EnvironmentSeed = config.GetInt(nameof(EnvironmentSeed), defaultSeed); + RandomizeWaterLevels = config.GetBool(nameof(RandomizeWaterLevels), true); + RandomizeSlotPositions = config.GetBool(nameof(RandomizeSlotPositions), true); + RandomizeLadders = config.GetBool(nameof(RandomizeLadders), true); + MirroredLevelCount = config.GetUInt(nameof(MirroredLevelCount), 9); + MirrorAssaultCourse = config.GetBool(nameof(MirrorAssaultCourse), true); + + DevelopmentMode = config.GetBool(nameof(DevelopmentMode)); + AutoLaunchGame = config.GetBool(nameof(AutoLaunchGame)); + PuristMode = config.GetBool(nameof(PuristMode)); + } + + public void StoreConfig(Config config) + { + config[nameof(RandomizeSecrets)] = RandomizeSecrets; + config[nameof(SecretSeed)] = SecretSeed; + config[nameof(HardSecrets)] = HardSecrets; + config[nameof(GlitchedSecrets)] = GlitchedSecrets; + + config[nameof(RandomizeItems)] = RandomizeItems; + config[nameof(ItemSeed)] = ItemSeed; + config[nameof(IncludeKeyItems)] = IncludeKeyItems; + config[nameof(RandoItemDifficulty)] = RandoItemDifficulty; + + config[nameof(RandomizeEnemies)] = RandomizeEnemies; + config[nameof(EnemySeed)] = EnemySeed; + config[nameof(CrossLevelEnemies)] = CrossLevelEnemies; + config[nameof(ProtectMonks)] = ProtectMonks; + config[nameof(DocileBirdMonsters)] = DocileBirdMonsters; + config[nameof(RandoEnemyDifficulty)] = RandoEnemyDifficulty; + + config[nameof(RandomizeTextures)] = RandomizeTextures; + config[nameof(TextureSeed)] = TextureSeed; + config[nameof(PersistTextureVariants)] = PersistTextureVariants; + config[nameof(RetainKeySpriteTextures)] = RetainKeySpriteTextures; + config[nameof(RetainSecretSpriteTextures)] = RetainSecretSpriteTextures; + + config[nameof(RandomizeOutfits)] = RandomizeOutfits; + config[nameof(OutfitSeed)] = OutfitSeed; + config[nameof(PersistOutfits)] = PersistOutfits; + config[nameof(RemoveRobeDagger)] = RemoveRobeDagger; + config[nameof(HaircutLevelCount)] = HaircutLevelCount; + config[nameof(AssaultCourseHaircut)] = AssaultCourseHaircut; + config[nameof(InvisibleLevelCount)] = InvisibleLevelCount; + config[nameof(AssaultCourseInvisible)] = AssaultCourseInvisible; + + config[nameof(RandomizeGameStrings)] = RandomizeGameStrings; + config[nameof(GameStringsSeed)] = GameStringsSeed; + config[nameof(RetainKeyItemNames)] = RetainKeyItemNames; + config[nameof(RetainLevelNames)] = RetainLevelNames; + config[nameof(GameStringLanguage)] = GameStringLanguage.Tag; + + config[nameof(RandomizeNightMode)] = RandomizeNightMode; + config[nameof(NightModeSeed)] = NightModeSeed; + config[nameof(NightModeCount)] = NightModeCount; + config[nameof(NightModeDarkness)] = NightModeDarkness; + config[nameof(NightModeAssaultCourse)] = NightModeAssaultCourse; + + config[nameof(ChangeTriggerTracks)] = ChangeTriggerTracks; + config[nameof(SeparateSecretTracks)] = SeparateSecretTracks; + config[nameof(ChangeWeaponSFX)] = ChangeWeaponSFX; + config[nameof(ChangeCrashSFX)] = ChangeCrashSFX; + config[nameof(ChangeEnemySFX)] = ChangeEnemySFX; + config[nameof(LinkCreatureSFX)] = LinkCreatureSFX; + + config[nameof(RandomizeStartPosition)] = RandomizeStartPosition; + config[nameof(StartPositionSeed)] = StartPositionSeed; + config[nameof(RotateStartPositionOnly)] = RotateStartPositionOnly; + + config[nameof(RandomizeEnvironment)] = RandomizeEnvironment; + config[nameof(EnvironmentSeed)] = EnvironmentSeed; + config[nameof(RandomizeWaterLevels)] = RandomizeWaterLevels; + config[nameof(RandomizeSlotPositions)] = RandomizeSlotPositions; + config[nameof(RandomizeLadders)] = RandomizeLadders; + config[nameof(MirroredLevelCount)] = MirroredLevelCount; + config[nameof(MirrorAssaultCourse)] = MirrorAssaultCourse; + + config[nameof(DevelopmentMode)] = DevelopmentMode; + config[nameof(AutoLaunchGame)] = AutoLaunchGame; + config[nameof(PuristMode)] = PuristMode; + } + + public int GetSaveTarget(int numLevels) + { + int target = 0; + + if (RandomizeGameStrings || ReassignPuzzleNames) + { + target++; + } + + if (RandomizeNightMode) + { + target += numLevels; + if (!RandomizeTextures) + { + // Texture randomizer will run if night mode is on to ensure skyboxes and such like match + target += numLevels; + } + } + + if (RandomizeSecrets) + { + target += numLevels; + } + + if (RandomizeAudio) + { + target += numLevels; + } + + if (RandomizeItems) + { + // Standard/key item rando followed by unarmed logic after enemy rando + target += numLevels * 2; + } + + if (RandomizeStartPosition) + { + target += numLevels; + } + + if (DeduplicateTextures) + { + // *2 because of multithreaded approach + target += numLevels * 2; + } + + if (RandomizeEnemies) + { + // *4 => 3 for multithreading work, 1 for ModelAdjuster + target += CrossLevelEnemies ? numLevels * 4 : numLevels; + } + + if (RandomizeTextures) + { + // *3 because of multithreaded approach + target += numLevels * 3; + } + + if (RandomizeOutfits) + { + // *2 because of multithreaded approach + target += numLevels * 2; + } + + // Environment randomizer always runs + target += numLevels; + + return target; + } + } +} \ No newline at end of file diff --git a/TRRandomizerCore/Editors/TR2RandoEditor.cs b/TRRandomizerCore/Editors/TR2RandoEditor.cs new file mode 100644 index 000000000..008e5aa2c --- /dev/null +++ b/TRRandomizerCore/Editors/TR2RandoEditor.cs @@ -0,0 +1,245 @@ +using System.Collections.Generic; +using System.Linq; +using TRRandomizerCore.Processors; +using TRRandomizerCore.Randomizers; +using TRRandomizerCore.Utilities; +using TRGE.Coord; +using TRGE.Core; + +namespace TRRandomizerCore.Editors +{ + public class TR2RandoEditor : TR2LevelEditor, ISettingsProvider + { + public RandomizerSettings Settings { get; private set; } + + public TR2RandoEditor(TRDirectoryIOArgs args, TREdition edition) + : base(args, edition) { } + + protected override void ApplyConfig(Config config) + { + Settings = new RandomizerSettings(); + Settings.ApplyConfig(config); + } + + protected override void StoreConfig(Config config) + { + Settings.StoreConfig(config); + } + + protected override int GetSaveTarget(int numLevels) + { + return base.GetSaveTarget(numLevels) + Settings.GetSaveTarget(numLevels); + } + + protected override void SaveImpl(AbstractTRScriptEditor scriptEditor, TRSaveMonitor monitor) + { + List levels = new List + ( + scriptEditor.EnabledScriptedLevels.Cast().ToList() + ); + + if (scriptEditor.GymAvailable) + { + levels.Add(scriptEditor.AssaultLevel as TR23ScriptedLevel); + } + + // Each processor will have a reference to the script editor, so can + // make on-the-fly changes as required. + TR23ScriptEditor tr23ScriptEditor = scriptEditor as TR23ScriptEditor; + string wipDirectory = _io.WIPOutputDirectory.FullName; + + // Texture monitoring is needed between enemy and texture randomization + // to track where imported enemies are placed. + using (TexturePositionMonitorBroker textureMonitor = new TexturePositionMonitorBroker()) + { + if (!monitor.IsCancelled && (Settings.RandomizeGameStrings || Settings.ReassignPuzzleNames)) + { + monitor.FireSaveStateBeginning(TRSaveCategory.Custom, "Adjusting game strings"); + new TR2GameStringRandomizer + { + ScriptEditor = tr23ScriptEditor, + Levels = levels, + BasePath = wipDirectory, + SaveMonitor = monitor, + Settings = Settings + }.Randomize(Settings.GameStringsSeed); + } + + if (!monitor.IsCancelled && Settings.DeduplicateTextures) + { + // This is needed to make as much space as possible available for cross-level enemies. + // We do this if we are implementing cross-level enemies OR if randomizing textures, + // as the texture mapping is optimised for levels that have been deduplicated. + monitor.FireSaveStateBeginning(TRSaveCategory.Custom, "Deduplicating textures"); + new TR2TextureDeduplicator + { + ScriptEditor = tr23ScriptEditor, + Levels = levels, + BasePath = wipDirectory, + SaveMonitor = monitor + }.Deduplicate(); + } + + if (!monitor.IsCancelled && Settings.RandomizeSecrets) + { + monitor.FireSaveStateBeginning(TRSaveCategory.Custom, "Randomizing secrets"); + new TR2SecretRandomizer + { + ScriptEditor = tr23ScriptEditor, + Levels = levels, + BasePath = wipDirectory, + SaveMonitor = monitor, + Settings = Settings + }.Randomize(Settings.SecretSeed); + } + + TR2ItemRandomizer itemRandomizer = null; + if (!monitor.IsCancelled && Settings.RandomizeItems) + { + monitor.FireSaveStateBeginning(TRSaveCategory.Custom, string.Format("Randomizing standard{0} items", Settings.IncludeKeyItems ? " and key" : string.Empty)); + (itemRandomizer = new TR2ItemRandomizer + { + ScriptEditor = tr23ScriptEditor, + Levels = levels, + BasePath = wipDirectory, + SaveMonitor = monitor, + Settings = Settings, + TextureMonitor = textureMonitor + }).Randomize(Settings.ItemSeed); + } + + if (!monitor.IsCancelled && Settings.RandomizeEnemies) + { + if (Settings.CrossLevelEnemies) + { + // For now all P2 items become P3 to avoid dragon issues. This must take place after Item + // randomization for P2/3 zoning because P2 entities will become P3. + monitor.FireSaveStateBeginning(TRSaveCategory.Custom, "Adjusting level models"); + new TR2ModelAdjuster + { + ScriptEditor = tr23ScriptEditor, + Levels = levels, + BasePath = wipDirectory, + SaveMonitor = monitor + }.AdjustModels(); + } + + monitor.FireSaveStateBeginning(TRSaveCategory.Custom, "Randomizing enemies"); + new TR2EnemyRandomizer + { + ScriptEditor = tr23ScriptEditor, + Levels = levels, + BasePath = wipDirectory, + SaveMonitor = monitor, + Settings = Settings, + TextureMonitor = textureMonitor + }.Randomize(Settings.EnemySeed); + } + + // Randomize ammo/weapon in unarmed levels post enemy randomization + if (!monitor.IsCancelled && Settings.RandomizeItems) + { + monitor.FireSaveStateBeginning(TRSaveCategory.Custom, "Randomizing unarmed level items"); + itemRandomizer.RandomizeAmmo(); + } + + if (!monitor.IsCancelled && Settings.RandomizeStartPosition) + { + monitor.FireSaveStateBeginning(TRSaveCategory.Custom, "Randomizing start positions"); + new TR2StartPositionRandomizer + { + ScriptEditor = tr23ScriptEditor, + Levels = levels, + BasePath = wipDirectory, + SaveMonitor = monitor, + Settings = Settings + }.Randomize(Settings.StartPositionSeed); + } + + if (!monitor.IsCancelled) + { + monitor.FireSaveStateBeginning(TRSaveCategory.Custom, Settings.RandomizeEnvironment ? "Randomizing environment" : "Applying default environment packs"); + new TR2EnvironmentRandomizer + { + ScriptEditor = tr23ScriptEditor, + Levels = levels, + BasePath = wipDirectory, + SaveMonitor = monitor, + Settings = Settings, + TextureMonitor = textureMonitor + }.Randomize(Settings.EnvironmentSeed); + } + + if (!monitor.IsCancelled && Settings.RandomizeAudio) + { + monitor.FireSaveStateBeginning(TRSaveCategory.Custom, "Randomizing audio tracks"); + new TR2AudioRandomizer + { + ScriptEditor = tr23ScriptEditor, + Levels = levels, + BasePath = wipDirectory, + SaveMonitor = monitor, + Settings = Settings + }.Randomize(Settings.AudioSeed); + } + + if (!monitor.IsCancelled && Settings.RandomizeOutfits) + { + monitor.FireSaveStateBeginning(TRSaveCategory.Custom, "Randomizing outfits"); + new TR2OutfitRandomizer + { + ScriptEditor = tr23ScriptEditor, + Levels = levels, + BasePath = wipDirectory, + SaveMonitor = monitor, + Settings = Settings, + TextureMonitor = textureMonitor + }.Randomize(Settings.OutfitSeed); + } + + if (!monitor.IsCancelled && Settings.RandomizeNightMode) + { + monitor.FireSaveStateBeginning(TRSaveCategory.Custom, "Randomizing night mode"); + new TR2NightModeRandomizer + { + ScriptEditor = tr23ScriptEditor, + Levels = levels, + BasePath = wipDirectory, + SaveMonitor = monitor, + Settings = Settings, + TextureMonitor = textureMonitor + }.Randomize(Settings.NightModeSeed); + } + + if (!monitor.IsCancelled) + { + if (Settings.RandomizeTextures) + { + monitor.FireSaveStateBeginning(TRSaveCategory.Custom, "Randomizing textures"); + new TR2TextureRandomizer + { + ScriptEditor = tr23ScriptEditor, + Levels = levels, + BasePath = wipDirectory, + SaveMonitor = monitor, + Settings = Settings, + TextureMonitor = textureMonitor + }.Randomize(Settings.TextureSeed); + } + else if (Settings.RandomizeNightMode) + { + monitor.FireSaveStateBeginning(TRSaveCategory.Custom, "Randomizing night mode textures"); + new TR2TextureRandomizer + { + ScriptEditor = tr23ScriptEditor, + Levels = levels, + BasePath = wipDirectory, + SaveMonitor = monitor, + TextureMonitor = textureMonitor + }.Randomize(Settings.NightModeSeed); + } + } + } + } + } +} \ No newline at end of file diff --git a/TRRandomizerCore/Editors/TR3RandoEditor.cs b/TRRandomizerCore/Editors/TR3RandoEditor.cs new file mode 100644 index 000000000..3230ff390 --- /dev/null +++ b/TRRandomizerCore/Editors/TR3RandoEditor.cs @@ -0,0 +1,57 @@ +using System.Collections.Generic; +using System.Linq; +using TRGE.Coord; +using TRGE.Core; + +namespace TRRandomizerCore.Editors +{ + public class TR3RandoEditor : TR3LevelEditor, ISettingsProvider + { + public RandomizerSettings Settings { get; private set; } + + public TR3RandoEditor(TRDirectoryIOArgs args, TREdition edition) + : base(args, edition) { } + + protected override void ApplyConfig(Config config) + { + Settings = new RandomizerSettings(); + Settings.ApplyConfig(config); + } + + protected override void StoreConfig(Config config) + { + Settings.StoreConfig(config); + } + + protected override int GetSaveTarget(int numLevels) + { + return base.GetSaveTarget(numLevels);// + Settings.GetSaveTarget(numLevels); + } + + protected override void SaveImpl(AbstractTRScriptEditor scriptEditor, TRSaveMonitor monitor) + { + List levels = new List + ( + scriptEditor.EnabledScriptedLevels.Cast().ToList() + ); + + if (scriptEditor.GymAvailable) + { + levels.Add(scriptEditor.AssaultLevel as TR23ScriptedLevel); + } + + // Each processor will have a reference to the script editor, so can + // make on-the-fly changes as required. + TR23ScriptEditor tr23ScriptEditor = scriptEditor as TR23ScriptEditor; + // string wipDirectory = _io.WIPOutputDirectory.FullName; + + if (Settings.DevelopmentMode) + { + (tr23ScriptEditor.Script as TR23Script).LevelSelectEnabled = true; + scriptEditor.SaveScript(); + } + + // TODO: Randomize... + } + } +} \ No newline at end of file diff --git a/TR2RandomizerCore/Globalisation/G11N.cs b/TRRandomizerCore/Globalisation/G11N.cs similarity index 91% rename from TR2RandomizerCore/Globalisation/G11N.cs rename to TRRandomizerCore/Globalisation/G11N.cs index 7d5e3a7dd..fed5478c5 100644 --- a/TR2RandomizerCore/Globalisation/G11N.cs +++ b/TRRandomizerCore/Globalisation/G11N.cs @@ -4,7 +4,7 @@ using System.Linq; using System.Text; -namespace TR2RandomizerCore.Globalisation +namespace TRRandomizerCore.Globalisation { public class G11N { @@ -32,7 +32,7 @@ public static G11N Instance private G11N() { _languageMap = new SortedDictionary(); - Language[] languages = JsonConvert.DeserializeObject(File.ReadAllText(@"Resources\Strings\languages.json")); + Language[] languages = JsonConvert.DeserializeObject(File.ReadAllText(@"Resources\TR2\Strings\languages.json")); _realLanguages = new SortedSet(); foreach (Language language in languages) { @@ -65,7 +65,7 @@ public GameStrings GetGameStrings(Language language) if (_languageMap[language] == null && !language.IsHybrid) { - string path = string.Format(@"Resources\Strings\G11N\gamestrings_{0}.json", language.Tag); + string path = string.Format(@"Resources\TR2\Strings\G11N\gamestrings_{0}.json", language.Tag); _languageMap[language] = JsonConvert.DeserializeObject(File.ReadAllText(path, Encoding.UTF8)); } diff --git a/TR2RandomizerCore/Globalisation/GameStrings.cs b/TRRandomizerCore/Globalisation/GameStrings.cs similarity index 98% rename from TR2RandomizerCore/Globalisation/GameStrings.cs rename to TRRandomizerCore/Globalisation/GameStrings.cs index bf9713ead..90ed88e2d 100644 --- a/TR2RandomizerCore/Globalisation/GameStrings.cs +++ b/TRRandomizerCore/Globalisation/GameStrings.cs @@ -2,7 +2,7 @@ using System.Globalization; using System.Text; -namespace TR2RandomizerCore.Globalisation +namespace TRRandomizerCore.Globalisation { public class GameStrings { diff --git a/TR2RandomizerCore/Globalisation/GlobalStrings.cs b/TRRandomizerCore/Globalisation/GlobalStrings.cs similarity index 84% rename from TR2RandomizerCore/Globalisation/GlobalStrings.cs rename to TRRandomizerCore/Globalisation/GlobalStrings.cs index e6242b442..f4c6c1877 100644 --- a/TR2RandomizerCore/Globalisation/GlobalStrings.cs +++ b/TRRandomizerCore/Globalisation/GlobalStrings.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; -namespace TR2RandomizerCore.Globalisation +namespace TRRandomizerCore.Globalisation { public class GlobalStrings { diff --git a/TR2RandomizerCore/Globalisation/Language.cs b/TRRandomizerCore/Globalisation/Language.cs similarity index 95% rename from TR2RandomizerCore/Globalisation/Language.cs rename to TRRandomizerCore/Globalisation/Language.cs index 982747d81..2b86b45b5 100644 --- a/TR2RandomizerCore/Globalisation/Language.cs +++ b/TRRandomizerCore/Globalisation/Language.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; -namespace TR2RandomizerCore.Globalisation +namespace TRRandomizerCore.Globalisation { public class Language : IComparable { diff --git a/TR2RandomizerCore/Globalisation/LevelStrings.cs b/TRRandomizerCore/Globalisation/LevelStrings.cs similarity index 88% rename from TR2RandomizerCore/Globalisation/LevelStrings.cs rename to TRRandomizerCore/Globalisation/LevelStrings.cs index 1c2738d1f..0c188208f 100644 --- a/TR2RandomizerCore/Globalisation/LevelStrings.cs +++ b/TRRandomizerCore/Globalisation/LevelStrings.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; -namespace TR2RandomizerCore.Globalisation +namespace TRRandomizerCore.Globalisation { public class LevelStrings { diff --git a/TR2RandomizerCore/Helpers/CollectionExtensions.cs b/TRRandomizerCore/Helpers/CollectionExtensions.cs similarity index 97% rename from TR2RandomizerCore/Helpers/CollectionExtensions.cs rename to TRRandomizerCore/Helpers/CollectionExtensions.cs index 7bf289ba2..39b543722 100644 --- a/TR2RandomizerCore/Helpers/CollectionExtensions.cs +++ b/TRRandomizerCore/Helpers/CollectionExtensions.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; -namespace TR2RandomizerCore.Helpers +namespace TRRandomizerCore.Helpers { public static class CollectionExtensions { diff --git a/TR2RandomizerCore/Helpers/Difficulty.cs b/TRRandomizerCore/Helpers/Difficulty.cs similarity index 68% rename from TR2RandomizerCore/Helpers/Difficulty.cs rename to TRRandomizerCore/Helpers/Difficulty.cs index 20bf1dc01..7c58c3fab 100644 --- a/TR2RandomizerCore/Helpers/Difficulty.cs +++ b/TRRandomizerCore/Helpers/Difficulty.cs @@ -1,4 +1,4 @@ -namespace TR2RandomizerCore.Helpers +namespace TRRandomizerCore.Helpers { public enum Difficulty { diff --git a/TR2RandomizerCore/Helpers/EnemyDifficulty.cs b/TRRandomizerCore/Helpers/EnemyDifficulty.cs similarity index 77% rename from TR2RandomizerCore/Helpers/EnemyDifficulty.cs rename to TRRandomizerCore/Helpers/EnemyDifficulty.cs index 9eb2d7651..f6c9ccb24 100644 --- a/TR2RandomizerCore/Helpers/EnemyDifficulty.cs +++ b/TRRandomizerCore/Helpers/EnemyDifficulty.cs @@ -1,4 +1,4 @@ -namespace TR2RandomizerCore.Helpers +namespace TRRandomizerCore.Helpers { public enum EnemyDifficulty { diff --git a/TR2RandomizerCore/Helpers/ItemDifficulty.cs b/TRRandomizerCore/Helpers/ItemDifficulty.cs similarity index 65% rename from TR2RandomizerCore/Helpers/ItemDifficulty.cs rename to TRRandomizerCore/Helpers/ItemDifficulty.cs index bbfeb105e..6a6c4f356 100644 --- a/TR2RandomizerCore/Helpers/ItemDifficulty.cs +++ b/TRRandomizerCore/Helpers/ItemDifficulty.cs @@ -1,4 +1,4 @@ -namespace TR2RandomizerCore.Helpers +namespace TRRandomizerCore.Helpers { public enum ItemDifficulty { diff --git a/TR2RandomizerCore/Helpers/LandmarkImporter.cs b/TRRandomizerCore/Helpers/LandmarkImporter.cs similarity index 98% rename from TR2RandomizerCore/Helpers/LandmarkImporter.cs rename to TRRandomizerCore/Helpers/LandmarkImporter.cs index 6c07e6986..8c48ac9b5 100644 --- a/TR2RandomizerCore/Helpers/LandmarkImporter.cs +++ b/TRRandomizerCore/Helpers/LandmarkImporter.cs @@ -1,11 +1,9 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Drawing; using System.Drawing.Imaging; using System.Linq; using System.Runtime.InteropServices; -using System.Text; -using System.Threading.Tasks; +using TRRandomizerCore.Levels; using TRLevelReader.Model; using TRModelTransporter.Model.Textures; using TRModelTransporter.Packing; @@ -14,7 +12,7 @@ using TRTexture16Importer.Textures.Source; using TRTexture16Importer.Textures.Target; -namespace TR2RandomizerCore.Helpers +namespace TRRandomizerCore.Helpers { // This class is in RandoCore rathern than TRTexture16Importer as otherwise // there is a cyclic dependency between it and ModelTransporter diff --git a/TR2RandomizerCore/Helpers/Location.cs b/TRRandomizerCore/Helpers/Location.cs similarity index 96% rename from TR2RandomizerCore/Helpers/Location.cs rename to TRRandomizerCore/Helpers/Location.cs index e74988d80..30b6968cb 100644 --- a/TR2RandomizerCore/Helpers/Location.cs +++ b/TRRandomizerCore/Helpers/Location.cs @@ -1,6 +1,6 @@ using TRViewInterop.Routes; -namespace TR2RandomizerCore.Helpers +namespace TRRandomizerCore.Helpers { public class Location { diff --git a/TR2RandomizerCore/Helpers/MeshEditor.cs b/TRRandomizerCore/Helpers/MeshEditor.cs similarity index 99% rename from TR2RandomizerCore/Helpers/MeshEditor.cs rename to TRRandomizerCore/Helpers/MeshEditor.cs index cf54cf508..bb8419405 100644 --- a/TR2RandomizerCore/Helpers/MeshEditor.cs +++ b/TRRandomizerCore/Helpers/MeshEditor.cs @@ -3,7 +3,7 @@ using TRLevelReader.Helpers; using TRLevelReader.Model; -namespace TR2RandomizerCore.Helpers +namespace TRRandomizerCore.Helpers { public class MeshEditor { diff --git a/TR2RandomizerCore/Helpers/ModificationStamp.cs b/TRRandomizerCore/Helpers/ModificationStamp.cs similarity index 91% rename from TR2RandomizerCore/Helpers/ModificationStamp.cs rename to TRRandomizerCore/Helpers/ModificationStamp.cs index e8e39ba6c..989d02d4b 100644 --- a/TR2RandomizerCore/Helpers/ModificationStamp.cs +++ b/TRRandomizerCore/Helpers/ModificationStamp.cs @@ -1,6 +1,6 @@ using TRGE.Core; -namespace TR2RandomizerCore.Helpers +namespace TRRandomizerCore.Helpers { public class ModificationStamp { diff --git a/TR2RandomizerCore/Helpers/RandoDifficulty.cs b/TRRandomizerCore/Helpers/RandoDifficulty.cs similarity index 67% rename from TR2RandomizerCore/Helpers/RandoDifficulty.cs rename to TRRandomizerCore/Helpers/RandoDifficulty.cs index f20fff583..d6d719054 100644 --- a/TR2RandomizerCore/Helpers/RandoDifficulty.cs +++ b/TRRandomizerCore/Helpers/RandoDifficulty.cs @@ -1,4 +1,4 @@ -namespace TR2RandomizerCore.Helpers +namespace TRRandomizerCore.Helpers { public enum RandoDifficulty { diff --git a/TR2RandomizerCore/Helpers/TROpenRestoreEventArgs.cs b/TRRandomizerCore/Helpers/TROpenRestoreEventArgs.cs similarity index 93% rename from TR2RandomizerCore/Helpers/TROpenRestoreEventArgs.cs rename to TRRandomizerCore/Helpers/TROpenRestoreEventArgs.cs index 8918adf5f..9ad15cff3 100644 --- a/TR2RandomizerCore/Helpers/TROpenRestoreEventArgs.cs +++ b/TRRandomizerCore/Helpers/TROpenRestoreEventArgs.cs @@ -1,6 +1,6 @@ using TRGE.Coord; -namespace TR2RandomizerCore.Helpers +namespace TRRandomizerCore.Helpers { // This is a wrapper class to avoid anything that uses core having a direct dependency on TRGE public class TROpenRestoreEventArgs diff --git a/TR2RandomizerCore/Helpers/TRRandomizationCategory.cs b/TRRandomizerCore/Helpers/TRRandomizationCategory.cs similarity index 80% rename from TR2RandomizerCore/Helpers/TRRandomizationCategory.cs rename to TRRandomizerCore/Helpers/TRRandomizationCategory.cs index 15135a24c..a911be285 100644 --- a/TR2RandomizerCore/Helpers/TRRandomizationCategory.cs +++ b/TRRandomizerCore/Helpers/TRRandomizationCategory.cs @@ -1,4 +1,4 @@ -namespace TR2RandomizerCore.Helpers +namespace TRRandomizerCore.Helpers { public enum TRRandomizationCategory { diff --git a/TR2RandomizerCore/Helpers/TRRandomizationEventArgs.cs b/TRRandomizerCore/Helpers/TRRandomizationEventArgs.cs similarity index 98% rename from TR2RandomizerCore/Helpers/TRRandomizationEventArgs.cs rename to TRRandomizerCore/Helpers/TRRandomizationEventArgs.cs index 425dab405..e21a0bbed 100644 --- a/TR2RandomizerCore/Helpers/TRRandomizationEventArgs.cs +++ b/TRRandomizerCore/Helpers/TRRandomizationEventArgs.cs @@ -1,6 +1,6 @@ using TRGE.Core; -namespace TR2RandomizerCore.Helpers +namespace TRRandomizerCore.Helpers { // This is a wrapper class to avoid anything that uses core having a direct dependency on TRGE public class TRRandomizationEventArgs diff --git a/TR2RandomizerCore/Helpers/TR2CombinedLevel.cs b/TRRandomizerCore/Levels/TR2CombinedLevel.cs similarity index 95% rename from TR2RandomizerCore/Helpers/TR2CombinedLevel.cs rename to TRRandomizerCore/Levels/TR2CombinedLevel.cs index b4f6b0e1b..e0f4ba6e1 100644 --- a/TR2RandomizerCore/Helpers/TR2CombinedLevel.cs +++ b/TRRandomizerCore/Levels/TR2CombinedLevel.cs @@ -1,12 +1,12 @@ using System.Collections.Generic; using System.Linq; -using TR2RandomizerCore.Utilities; +using TRRandomizerCore.Utilities; using TRGE.Core; using TRLevelReader.Helpers; using TRLevelReader.Model; using TRLevelReader.Model.Enums; -namespace TR2RandomizerCore.Helpers +namespace TRRandomizerCore.Levels { public class TR2CombinedLevel { @@ -61,7 +61,7 @@ public class TR2CombinedLevel // We previously checked for NumBoxes but with environment rando, this can now change. We instead look for the first // animated texture index (the lava) as this is 1702 in UKBox and 1686 in EPC/Multipatch. This remains consistent // regardless of texture deduplication. - public bool IsUKBox => Is(LevelNames.FLOATER) && Data.AnimatedTextures[0].Textures[0] == 1702; + public bool IsUKBox => Is(TR2LevelNames.FLOATER) && Data.AnimatedTextures[0].Textures[0] == 1702; /// /// Returns {Name}-UKBox if this level is for UKBox, otherwise just {Name}. @@ -71,7 +71,7 @@ public class TR2CombinedLevel /// /// Checks if the current level is the assault course. /// - public bool IsAssault => Is(LevelNames.ASSAULT); + public bool IsAssault => Is(TR2LevelNames.ASSAULT); public bool CanPerformDraining(short room) { diff --git a/TR2RandomizerCore/Helpers/TR2LevelTextureWeightComparer.cs b/TRRandomizerCore/Levels/TR2LevelTextureWeightComparer.cs similarity index 95% rename from TR2RandomizerCore/Helpers/TR2LevelTextureWeightComparer.cs rename to TRRandomizerCore/Levels/TR2LevelTextureWeightComparer.cs index 6dba6790c..ac2100fd2 100644 --- a/TR2RandomizerCore/Helpers/TR2LevelTextureWeightComparer.cs +++ b/TRRandomizerCore/Levels/TR2LevelTextureWeightComparer.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; using TRLevelReader.Helpers; -namespace TR2RandomizerCore.Helpers +namespace TRRandomizerCore.Levels { public class TR2LevelTextureWeightComparer : IComparer { diff --git a/TRRandomizerCore/Levels/TR3CombinedLevel.cs b/TRRandomizerCore/Levels/TR3CombinedLevel.cs new file mode 100644 index 000000000..3f84c6d34 --- /dev/null +++ b/TRRandomizerCore/Levels/TR3CombinedLevel.cs @@ -0,0 +1,64 @@ +using TRGE.Core; +using TRLevelReader.Helpers; +using TRLevelReader.Model; + +namespace TRRandomizerCore.Levels +{ + public class TR3CombinedLevel + { + /// + /// The main level data stored in the corresponding .TR2 file. + /// + public TR3Level Data { get; set; } + + /// + /// The scripting information for the level stored in TOMBPC.dat. + /// + public TR23ScriptedLevel Script { get; set; } + + /// + /// The uppercase base file name of the level e.g. KEEL.TR2 + /// + public string Name => Script.LevelFileBaseName.ToUpper(); + + /// + /// The level data for the cutscene at the end of this level, if any. + /// + public TR3CombinedLevel CutSceneLevel { get; set; } + + /// + /// A reference to the main level if this is a CutScene level. + /// + public TR3CombinedLevel ParentLevel { get; set; } + + /// + /// True if this is a CutScene level, and so has a parent level. + /// + public bool IsCutScene => ParentLevel != null; + + /// + /// Whether or not this level has a cutscene at the end. + /// + public bool HasCutScene => Script.HasCutScene; + + /// + /// Gets the level's sequence in the game. If this is a CutScene level, this returns the parent sequence. + /// + public int Sequence => IsCutScene ? ParentLevel.Sequence : Script.Sequence; + + /// + /// Compares the given file name or path against the base file name of the level (case-insensitive). + /// + public bool Is(string levelFileName) => Script.Is(levelFileName); + + /// + /// Checks if the current level is the assault course. + /// + public bool IsAssault => Is(TR3LevelNames.ASSAULT); + + /// + /// The exposure meter is hard-coded to the Antarctica and RX-Tech Mines level sequences. + /// + public bool HasExposureMeter => Sequence == 16 || Sequence == 17; + } +} \ No newline at end of file diff --git a/TRRandomizerCore/Processors/AbstractLevelProcessor.cs b/TRRandomizerCore/Processors/AbstractLevelProcessor.cs new file mode 100644 index 000000000..ebb257d1c --- /dev/null +++ b/TRRandomizerCore/Processors/AbstractLevelProcessor.cs @@ -0,0 +1,105 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Runtime.ExceptionServices; +using TRGE.Core; + +namespace TRRandomizerCore.Processors +{ + public abstract class AbstractLevelProcessor : ILevelProcessor where S : AbstractTRScriptedLevel + { + protected uint _maxThreads; + protected C _levelInstance; // Combined script/data level + + protected ExceptionDispatchInfo _processingException; + + protected readonly object _readLock, _writeLock, _monitorLock; + + internal AbstractTRScriptEditor ScriptEditor { get; set; } + internal List Levels { get; set; } + internal TRSaveMonitor SaveMonitor; + + public string BasePath { get; set; } + + public AbstractLevelProcessor() + { + _readLock = new object(); + _writeLock = new object(); + _monitorLock = new object(); + + _maxThreads = 3; + } + + protected void LoadLevelInstance(S scriptedLevel) + { + _levelInstance = LoadCombinedLevel(scriptedLevel); + } + + protected abstract C LoadCombinedLevel(S scriptedLevel); + + protected void ReloadLevelInstanceData() + { + ReloadLevelData(_levelInstance); + } + + protected abstract void ReloadLevelData(C level); + + protected void SaveLevelInstance() + { + SaveLevel(_levelInstance); + } + + protected abstract void SaveLevel(C level); + + protected void SaveScript() + { + lock (_writeLock) + { + // Save any script changes. + ScriptEditor.SaveScript(); + } + } + + /// + /// Informs the save monitor to update its progress by 1. + /// + /// True if the save process has not been cancelled and the current error state is null. + public bool TriggerProgress(int progress = 1) + { + lock (_monitorLock) + { + SaveMonitor.FireSaveStateChanged(progress); + return !SaveMonitor.IsCancelled && _processingException == null; + } + } + + internal void SetMessage(string text) + { + lock (_monitorLock) + { + SaveMonitor.FireSaveStateChanged(customDescription: text); + } + } + + public void HandleException(Exception e) + { + lock (_monitorLock) + { + if (_processingException == null) + { + _processingException = ExceptionDispatchInfo.Capture(e); + } + } + } + + protected string GetResourcePath(string filePath) + { + return Path.Combine("Resources", filePath); + } + + protected string ReadResource(string filePath) + { + return File.ReadAllText(GetResourcePath(filePath)); + } + } +} \ No newline at end of file diff --git a/TR2RandomizerCore/Processors/AbstractProcessorThread.cs b/TRRandomizerCore/Processors/AbstractProcessorThread.cs similarity index 96% rename from TR2RandomizerCore/Processors/AbstractProcessorThread.cs rename to TRRandomizerCore/Processors/AbstractProcessorThread.cs index d8d00fcde..6a03afa4f 100644 --- a/TR2RandomizerCore/Processors/AbstractProcessorThread.cs +++ b/TRRandomizerCore/Processors/AbstractProcessorThread.cs @@ -1,9 +1,9 @@ using System; using System.Threading; -namespace TR2RandomizerCore.Processors +namespace TRRandomizerCore.Processors { - internal abstract class AbstractProcessorThread where R : LevelProcessor + internal abstract class AbstractProcessorThread where R : ILevelProcessor { protected readonly R _outer; protected readonly Thread _thread; diff --git a/TRRandomizerCore/Processors/ILevelProcessor.cs b/TRRandomizerCore/Processors/ILevelProcessor.cs new file mode 100644 index 000000000..7f493039e --- /dev/null +++ b/TRRandomizerCore/Processors/ILevelProcessor.cs @@ -0,0 +1,10 @@ +using System; + +namespace TRRandomizerCore.Processors +{ + public interface ILevelProcessor + { + void HandleException(Exception e); + bool TriggerProgress(int progress); + } +} \ No newline at end of file diff --git a/TRRandomizerCore/Processors/TR2/TR2LevelProcessor.cs b/TRRandomizerCore/Processors/TR2/TR2LevelProcessor.cs new file mode 100644 index 000000000..b5bcb78bc --- /dev/null +++ b/TRRandomizerCore/Processors/TR2/TR2LevelProcessor.cs @@ -0,0 +1,75 @@ +using System.IO; +using TRRandomizerCore.Levels; +using TRGE.Core; +using TRLevelReader; +using TRLevelReader.Model; + +namespace TRRandomizerCore.Processors +{ + public class TR2LevelProcessor : AbstractLevelProcessor + { + protected TR2LevelReader _reader; + protected TR2LevelWriter _writer; + + public TR2LevelProcessor() + { + _reader = new TR2LevelReader(); + _writer = new TR2LevelWriter(); + } + + protected override TR2CombinedLevel LoadCombinedLevel(TR23ScriptedLevel scriptedLevel) + { + TR2CombinedLevel level = new TR2CombinedLevel + { + Data = LoadLevelData(scriptedLevel.LevelFileBaseName), + Script = scriptedLevel + }; + + if (scriptedLevel.HasCutScene) + { + level.CutSceneLevel = LoadCombinedLevel(scriptedLevel.CutSceneLevel as TR23ScriptedLevel); + level.CutSceneLevel.ParentLevel = level; + } + + return level; + } + + public TR2Level LoadLevelData(string name) + { + lock (_readLock) + { + string fullPath = Path.Combine(BasePath, name); + return _reader.ReadLevel(fullPath); + } + } + + protected override void ReloadLevelData(TR2CombinedLevel level) + { + level.Data = LoadLevelData(level.Name); + if (level.HasCutScene) + { + level.CutSceneLevel.Data = LoadLevelData(level.CutSceneLevel.Name); + } + } + + protected override void SaveLevel(TR2CombinedLevel level) + { + SaveLevel(level.Data, level.Name); + if (level.HasCutScene) + { + SaveLevel(level.CutSceneLevel.Data, level.CutSceneLevel.Name); + } + + SaveScript(); + } + + public void SaveLevel(TR2Level level, string name) + { + lock (_writeLock) + { + string fullPath = Path.Combine(BasePath, name); + _writer.WriteLevelToFile(level, fullPath); + } + } + } +} \ No newline at end of file diff --git a/TR2RandomizerCore/Processors/ModelAdjuster.cs b/TRRandomizerCore/Processors/TR2/TR2ModelAdjuster.cs similarity index 95% rename from TR2RandomizerCore/Processors/ModelAdjuster.cs rename to TRRandomizerCore/Processors/TR2/TR2ModelAdjuster.cs index 18ae21cf2..48511942e 100644 --- a/TR2RandomizerCore/Processors/ModelAdjuster.cs +++ b/TRRandomizerCore/Processors/TR2/TR2ModelAdjuster.cs @@ -5,9 +5,9 @@ using TRLevelReader.Model; using TRLevelReader.Model.Enums; -namespace TR2RandomizerCore.Processors +namespace TRRandomizerCore.Processors { - public class ModelAdjuster : LevelProcessor + public class TR2ModelAdjuster : TR2LevelProcessor { private static readonly Dictionary _modelRemap = new Dictionary { @@ -40,7 +40,7 @@ public void AdjustModels() private void AdjustInstanceModels() { - if (_levelInstance.Is(LevelNames.LAIR)) + if (_levelInstance.Is(TR2LevelNames.LAIR)) { return; } diff --git a/TR2RandomizerCore/Processors/TextureDeduplicator.cs b/TRRandomizerCore/Processors/TR2/TR2TextureDeduplicator.cs similarity index 87% rename from TR2RandomizerCore/Processors/TextureDeduplicator.cs rename to TRRandomizerCore/Processors/TR2/TR2TextureDeduplicator.cs index 4922a87cf..d44e1932c 100644 --- a/TR2RandomizerCore/Processors/TextureDeduplicator.cs +++ b/TRRandomizerCore/Processors/TR2/TR2TextureDeduplicator.cs @@ -1,12 +1,12 @@ using System.Collections.Generic; using System.IO; -using TR2RandomizerCore.Helpers; +using TRRandomizerCore.Levels; using TRGE.Core; using TRModelTransporter.Utilities; -namespace TR2RandomizerCore.Processors +namespace TRRandomizerCore.Processors { - internal class TextureDeduplicator : LevelProcessor + internal class TR2TextureDeduplicator : TR2LevelProcessor { public void Deduplicate() { @@ -51,14 +51,14 @@ public void Deduplicate() } } - internal class DeduplicationProcessor : AbstractProcessorThread + internal class DeduplicationProcessor : AbstractProcessorThread { private readonly List _levels; private readonly TRLevelTextureDeduplicator _deduplicator; internal override int LevelCount => _levels.Count; - internal DeduplicationProcessor(TextureDeduplicator outer) + internal DeduplicationProcessor(TR2TextureDeduplicator outer) :base(outer) { _levels = new List(); @@ -74,7 +74,7 @@ protected override void ProcessImpl() { foreach (TR2CombinedLevel level in _levels) { - string dedupPath = @"Resources\Textures\Deduplication\" + level.JsonID + "-TextureRemap.json"; + string dedupPath = _outer.GetResourcePath(@"TR2\Textures\Deduplication\" + level.JsonID + "-TextureRemap.json"); if (File.Exists(dedupPath)) { _deduplicator.Level = level.Data; diff --git a/TRRandomizerCore/Processors/TR3/TR3LevelProcessor.cs b/TRRandomizerCore/Processors/TR3/TR3LevelProcessor.cs new file mode 100644 index 000000000..c543b1e70 --- /dev/null +++ b/TRRandomizerCore/Processors/TR3/TR3LevelProcessor.cs @@ -0,0 +1,75 @@ +using System.IO; +using TRRandomizerCore.Levels; +using TRGE.Core; +using TRLevelReader; +using TRLevelReader.Model; + +namespace TRRandomizerCore.Processors +{ + public class TR3LevelProcessor : AbstractLevelProcessor + { + protected TR3LevelReader _reader; + protected TR3LevelWriter _writer; + + public TR3LevelProcessor() + { + _reader = new TR3LevelReader(); + _writer = new TR3LevelWriter(); + } + + protected override TR3CombinedLevel LoadCombinedLevel(TR23ScriptedLevel scriptedLevel) + { + TR3CombinedLevel level = new TR3CombinedLevel + { + Data = LoadLevelData(scriptedLevel.LevelFileBaseName), + Script = scriptedLevel + }; + + if (scriptedLevel.HasCutScene) + { + level.CutSceneLevel = LoadCombinedLevel(scriptedLevel.CutSceneLevel as TR23ScriptedLevel); + level.CutSceneLevel.ParentLevel = level; + } + + return level; + } + + public TR3Level LoadLevelData(string name) + { + lock (_readLock) + { + string fullPath = Path.Combine(BasePath, name); + return _reader.ReadLevel(fullPath); + } + } + + protected override void ReloadLevelData(TR3CombinedLevel level) + { + level.Data = LoadLevelData(level.Name); + if (level.HasCutScene) + { + level.CutSceneLevel.Data = LoadLevelData(level.CutSceneLevel.Name); + } + } + + protected override void SaveLevel(TR3CombinedLevel level) + { + SaveLevel(level.Data, level.Name); + if (level.HasCutScene) + { + SaveLevel(level.CutSceneLevel.Data, level.CutSceneLevel.Name); + } + + SaveScript(); + } + + public void SaveLevel(TR3Level level, string name) + { + lock (_writeLock) + { + string fullPath = Path.Combine(BasePath, name); + _writer.WriteLevelToFile(level, fullPath); + } + } + } +} \ No newline at end of file diff --git a/TR2RandomizerCore/Randomizers/IRandomizer.cs b/TRRandomizerCore/Randomizers/IRandomizer.cs similarity index 65% rename from TR2RandomizerCore/Randomizers/IRandomizer.cs rename to TRRandomizerCore/Randomizers/IRandomizer.cs index eb08345bd..de78baf4d 100644 --- a/TR2RandomizerCore/Randomizers/IRandomizer.cs +++ b/TRRandomizerCore/Randomizers/IRandomizer.cs @@ -1,4 +1,4 @@ -namespace TR2RandomizerCore.Randomizers +namespace TRRandomizerCore.Randomizers { public interface IRandomizer { diff --git a/TRRandomizerCore/Randomizers/TR2/BaseTR2Randomizer.cs b/TRRandomizerCore/Randomizers/TR2/BaseTR2Randomizer.cs new file mode 100644 index 000000000..c73b93fd6 --- /dev/null +++ b/TRRandomizerCore/Randomizers/TR2/BaseTR2Randomizer.cs @@ -0,0 +1,16 @@ +using System; +using System.IO; +using TRRandomizerCore.Editors; +using TRRandomizerCore.Processors; + +namespace TRRandomizerCore.Randomizers +{ + public abstract class BaseTR2Randomizer : TR2LevelProcessor, IRandomizer + { + public RandomizerSettings Settings { get; internal set; } + + protected Random _generator; + + public abstract void Randomize(int seed); + } +} \ No newline at end of file diff --git a/TR2RandomizerCore/Randomizers/AudioRandomizer.cs b/TRRandomizerCore/Randomizers/TR2/TR2AudioRandomizer.cs similarity index 95% rename from TR2RandomizerCore/Randomizers/AudioRandomizer.cs rename to TRRandomizerCore/Randomizers/TR2/TR2AudioRandomizer.cs index 0520c3c36..3b4909664 100644 --- a/TR2RandomizerCore/Randomizers/AudioRandomizer.cs +++ b/TRRandomizerCore/Randomizers/TR2/TR2AudioRandomizer.cs @@ -1,10 +1,9 @@ using Newtonsoft.Json; using System; using System.Collections.Generic; -using System.IO; using System.Linq; -using TR2RandomizerCore.Helpers; -using TR2RandomizerCore.SFX; +using TRRandomizerCore.Levels; +using TRRandomizerCore.SFX; using TRFDControl; using TRFDControl.FDEntryTypes; using TRFDControl.Utilities; @@ -13,17 +12,10 @@ using TRLevelReader.Model; using TRLevelReader.Model.Enums; -namespace TR2RandomizerCore.Randomizers +namespace TRRandomizerCore.Randomizers { - public class AudioRandomizer : RandomizerBase + public class TR2AudioRandomizer : BaseTR2Randomizer { - public bool ChangeTriggerTracks { get; set; } - public bool SeparateSecretTracks { get; set; } - public bool ChangeWeaponSFX { get; set; } - public bool ChangeCrashSFX { get; set; } - public bool ChangeEnemySFX { get; set; } - public bool LinkCreatureSFX { get; set; } - private IReadOnlyDictionary> _tracks; private List _soundEffects; @@ -57,12 +49,12 @@ private void RandomizeMusicTriggers(TR2CombinedLevel level) FDControl floorData = new FDControl(); floorData.ParseFromLevel(level.Data); - if (ChangeTriggerTracks) + if (Settings.ChangeTriggerTracks) { RandomizeFloorTracks(level.Data, floorData); } - if (SeparateSecretTracks) + if (Settings.SeparateSecretTracks) { RandomizeSecretTracks(level.Data, floorData); } @@ -212,7 +204,7 @@ private void LoadAudioData() // Decide which sound effect categories we want to randomize. _sfxCategories = new List(); - if (ChangeWeaponSFX) + if (Settings.ChangeWeaponSFX) { // Pistols, Autos etc _sfxCategories.Add(TRSFXGeneralCategory.StandardWeaponFiring); @@ -220,7 +212,7 @@ private void LoadAudioData() _sfxCategories.Add(TRSFXGeneralCategory.FastWeaponFiring); } - if (ChangeCrashSFX) + if (Settings.ChangeCrashSFX) { // Grenades, 40F crash, dragon explosion _sfxCategories.Add(TRSFXGeneralCategory.Explosion); @@ -230,7 +222,7 @@ private void LoadAudioData() _sfxCategories.Add(TRSFXGeneralCategory.Breaking); } - if (ChangeEnemySFX) + if (Settings.ChangeEnemySFX) { // General death noises _sfxCategories.Add(TRSFXGeneralCategory.Death); @@ -249,7 +241,7 @@ private void LoadAudioData() // Only load the SFX if we are changing at least one category if (_sfxCategories.Count > 0) { - _soundEffects = JsonConvert.DeserializeObject>(File.ReadAllText(@"Resources\tr2sfx.json")); + _soundEffects = JsonConvert.DeserializeObject>(ReadResource(@"TR2\Audio\sfx.json")); } } @@ -275,7 +267,7 @@ private void RandomizeSoundEffects(TR2CombinedLevel level) // The following allows choosing to keep humans making human noises, and animals animal noises. // Other humans can use Lara's SFX. Predicate pred; - if (LinkCreatureSFX && definition.Creature > TRSFXCreatureCategory.Lara) + if (Settings.LinkCreatureSFX && definition.Creature > TRSFXCreatureCategory.Lara) { pred = sfx => { diff --git a/TR2RandomizerCore/Randomizers/EnemyRandomizer.cs b/TRRandomizerCore/Randomizers/TR2/TR2EnemyRandomizer.cs similarity index 93% rename from TR2RandomizerCore/Randomizers/EnemyRandomizer.cs rename to TRRandomizerCore/Randomizers/TR2/TR2EnemyRandomizer.cs index 43257da87..aee8fdab1 100644 --- a/TR2RandomizerCore/Randomizers/EnemyRandomizer.cs +++ b/TRRandomizerCore/Randomizers/TR2/TR2EnemyRandomizer.cs @@ -1,11 +1,10 @@ -using Newtonsoft.Json; -using System; +using System; using System.Collections.Generic; -using System.IO; using System.Linq; -using TR2RandomizerCore.Helpers; -using TR2RandomizerCore.Processors; -using TR2RandomizerCore.Utilities; +using TRRandomizerCore.Helpers; +using TRRandomizerCore.Levels; +using TRRandomizerCore.Processors; +using TRRandomizerCore.Utilities; using TRGE.Core; using TRLevelReader.Helpers; using TRLevelReader.Model; @@ -13,20 +12,16 @@ using TRModelTransporter.Packing; using TRModelTransporter.Transport; -namespace TR2RandomizerCore.Randomizers +namespace TRRandomizerCore.Randomizers { - public class EnemyRandomizer : RandomizerBase + public class TR2EnemyRandomizer : BaseTR2Randomizer { private Dictionary> _gameEnemyTracker; - internal bool CrossLevelEnemies { get; set; } - internal bool ProtectMonks { get; set; } - internal bool DocileBirdMonsters { get; set; } internal int MaxPackingAttempts { get; set; } internal TexturePositionMonitorBroker TextureMonitor { get; set; } - internal RandoDifficulty RandoEnemyDifficulty { get; set; } - public EnemyRandomizer() + public TR2EnemyRandomizer() { MaxPackingAttempts = 5; } @@ -34,7 +29,7 @@ public EnemyRandomizer() public override void Randomize(int seed) { _generator = new Random(seed); - if (CrossLevelEnemies) + if (Settings.CrossLevelEnemies) { RandomizeEnemiesCrossLevel(); } @@ -97,7 +92,7 @@ private void RandomizeEnemiesCrossLevel() } // Track enemies whose counts across the game are restricted - _gameEnemyTracker = EnemyUtilities.PrepareEnemyGameTracker(DocileBirdMonsters, RandoEnemyDifficulty); + _gameEnemyTracker = EnemyUtilities.PrepareEnemyGameTracker(Settings.DocileBirdMonsters, Settings.RandoEnemyDifficulty); SetMessage("Randomizing enemies - importing models"); foreach (EnemyProcessor processor in processors) @@ -148,7 +143,7 @@ private EnemyTransportCollection SelectCrossLevelEnemies(TR2CombinedLevel level, // us to randomize the ones inside the gate (except the final shotgun goon). // If however, we are on the final packing attempt, we will just change the stick goon // alias and add docile bird monsters (if selected) as this is known to be supported. - if (level.Is(LevelNames.HOME) && reduceEnemyCountBy > 0) + if (level.Is(TR2LevelNames.HOME) && reduceEnemyCountBy > 0) { TR2Entities newGoon = TR2Entities.StickWieldingGoon1BlackJacket; List goonies = TR2EntityUtilities.GetEntityFamily(newGoon); @@ -162,7 +157,7 @@ private EnemyTransportCollection SelectCrossLevelEnemies(TR2CombinedLevel level, newEntities.Remove(TR2Entities.StickWieldingGoon1); newEntities.Add(newGoon); - if (DocileBirdMonsters) + if (Settings.DocileBirdMonsters) { newEntities.Remove(TR2Entities.MaskedGoon1); newEntities.Add(TR2Entities.BirdMonster); @@ -186,19 +181,19 @@ private EnemyTransportCollection SelectCrossLevelEnemies(TR2CombinedLevel level, { entity = waterEnemies[_generator.Next(0, waterEnemies.Count)]; } - while (!EnemyUtilities.IsEnemySupported(level.Name, entity, RandoEnemyDifficulty)); + while (!EnemyUtilities.IsEnemySupported(level.Name, entity, Settings.RandoEnemyDifficulty)); newEntities.Add(entity); } if (droppableEnemyRequired) { - List droppableEnemies = TR2EntityUtilities.GetCrossLevelDroppableEnemies(!ProtectMonks); + List droppableEnemies = TR2EntityUtilities.GetCrossLevelDroppableEnemies(!Settings.ProtectMonks); TR2Entities entity; do { entity = droppableEnemies[_generator.Next(0, droppableEnemies.Count)]; } - while (!EnemyUtilities.IsEnemySupported(level.Name, entity, RandoEnemyDifficulty)); + while (!EnemyUtilities.IsEnemySupported(level.Name, entity, Settings.RandoEnemyDifficulty)); newEntities.Add(entity); } @@ -219,19 +214,19 @@ private EnemyTransportCollection SelectCrossLevelEnemies(TR2CombinedLevel level, TR2Entities entity = allEnemies[_generator.Next(0, allEnemies.Count)]; // Make sure this isn't known to be unsupported in the level - if (!EnemyUtilities.IsEnemySupported(level.Name, entity, RandoEnemyDifficulty)) + if (!EnemyUtilities.IsEnemySupported(level.Name, entity, Settings.RandoEnemyDifficulty)) { continue; } // If it's the chicken in HSH but we're not using docile, we don't want it ending the level - if (!DocileBirdMonsters && entity == TR2Entities.BirdMonster && level.Is(LevelNames.HOME)) + if (!Settings.DocileBirdMonsters && entity == TR2Entities.BirdMonster && level.Is(TR2LevelNames.HOME)) { continue; } // If it's a docile chicken in Barkhang, it won't work because we can't disguise monks in this level. - if (DocileBirdMonsters && entity == TR2Entities.BirdMonster && level.Is(LevelNames.MONASTERY)) + if (Settings.DocileBirdMonsters && entity == TR2Entities.BirdMonster && level.Is(TR2LevelNames.MONASTERY)) { continue; } @@ -261,7 +256,7 @@ private EnemyTransportCollection SelectCrossLevelEnemies(TR2CombinedLevel level, { // #144 We can include docile chickens provided we aren't including everything // that can be disguised as a chicken. - if (DocileBirdMonsters) + if (Settings.DocileBirdMonsters) { bool guisersAvailable = !chickenGuisers.All(g => newEntities.Contains(g)); // If the selected entity is the chicken, it can be added provided there are @@ -288,7 +283,7 @@ private EnemyTransportCollection SelectCrossLevelEnemies(TR2CombinedLevel level, } // #144 Decide at this point who will be guising unless it has already been decided above (e.g. HSH) - if (DocileBirdMonsters && newEntities.Contains(TR2Entities.BirdMonster) && chickenGuiser == TR2Entities.BirdMonster) + if (Settings.DocileBirdMonsters && newEntities.Contains(TR2Entities.BirdMonster) && chickenGuiser == TR2Entities.BirdMonster) { int guiserIndex = chickenGuisers.FindIndex(g => !newEntities.Contains(g)); if (guiserIndex != -1) @@ -317,7 +312,7 @@ private void RandomizeEnemiesNatively(TR2CombinedLevel level) List droppableEnemies = TR2EntityUtilities.DroppableEnemyTypes()[level.Name]; List waterEnemies = TR2EntityUtilities.FilterWaterEnemies(availableEnemyTypes); - if (DocileBirdMonsters && level.Is(LevelNames.CHICKEN)) + if (Settings.DocileBirdMonsters && level.Is(TR2LevelNames.CHICKEN)) { DisguiseEntity(level, TR2Entities.MaskedGoon1, TR2Entities.BirdMonster); } @@ -341,7 +336,7 @@ private void DisguiseEntity(TR2CombinedLevel level, TR2Entities guiser, TR2Entit } TRModel disguiseAsModel = models[models.FindIndex(m => m.ID == (short)targetEntity)]; - if (targetEntity == TR2Entities.BirdMonster && level.Is(LevelNames.CHICKEN)) + if (targetEntity == TR2Entities.BirdMonster && level.Is(TR2LevelNames.CHICKEN)) { // We have to keep the original model for the boss, so in // this instance we just clone the model for the guiser @@ -366,8 +361,8 @@ private void DisguiseEntity(TR2CombinedLevel level, TR2Entities guiser, TR2Entit private void RandomizeEnemies(TR2CombinedLevel level, EnemyRandomizationCollection enemies) { - bool shotgunGoonSeen = level.Is(LevelNames.HOME); // 1 ShotgunGoon in HSH only - bool dragonSeen = level.Is(LevelNames.LAIR); // 1 Marco in DL only + bool shotgunGoonSeen = level.Is(TR2LevelNames.HOME); // 1 ShotgunGoon in HSH only + bool dragonSeen = level.Is(TR2LevelNames.LAIR); // 1 Marco in DL only // Get a list of current enemy entities List enemyEntities = level.GetEnemyEntities(); @@ -380,7 +375,7 @@ private void RandomizeEnemies(TR2CombinedLevel level, EnemyRandomizationCollecti // StickGoons will have been excluded from the cross-level pool for simplicity // Their textures will have been removed but they won't spawn anyway as we aren't // defining triggers - the game only needs them to be present in the entity list. - if (level.Is(LevelNames.HOME) && !enemies.Available.Contains(TR2Entities.Doberman)) + if (level.Is(TR2LevelNames.HOME) && !enemies.Available.Contains(TR2Entities.Doberman)) { for (int i = 0; i < 15; i++) { @@ -400,7 +395,7 @@ private void RandomizeEnemies(TR2CombinedLevel level, EnemyRandomizationCollecti } // First iterate through any enemies that are restricted by room - Dictionary> enemyRooms = EnemyUtilities.GetRestrictedEnemyRooms(level.Name, RandoEnemyDifficulty); + Dictionary> enemyRooms = EnemyUtilities.GetRestrictedEnemyRooms(level.Name, Settings.RandoEnemyDifficulty); if (enemyRooms != null) { foreach (TR2Entities entity in enemyRooms.Keys) @@ -411,7 +406,7 @@ private void RandomizeEnemies(TR2CombinedLevel level, EnemyRandomizationCollecti } List rooms = enemyRooms[entity]; - int maxEntityCount = EnemyUtilities.GetRestrictedEnemyLevelCount(entity, RandoEnemyDifficulty); + int maxEntityCount = EnemyUtilities.GetRestrictedEnemyLevelCount(entity, Settings.RandoEnemyDifficulty); if (maxEntityCount == -1) { // We are allowed any number, but this can't be more than the number of unique rooms, @@ -496,7 +491,7 @@ private void RandomizeEnemies(TR2CombinedLevel level, EnemyRandomizationCollecti newEntityType = enemies.Available[_generator.Next(0, enemies.Available.Count)]; //Do we need to ensure the enemy can drop the item on the same tile? - if (!TR2EntityUtilities.CanDropPickups(newEntityType, !ProtectMonks) && isPickupItem) + if (!TR2EntityUtilities.CanDropPickups(newEntityType, !Settings.ProtectMonks) && isPickupItem) { //Ensure the new random entity can drop pickups newEntityType = enemies.Droppable[_generator.Next(0, enemies.Droppable.Count)]; @@ -511,10 +506,10 @@ private void RandomizeEnemies(TR2CombinedLevel level, EnemyRandomizationCollecti short roomIndex = currentEntity.Room; TR2Room room = level.Data.Rooms[roomIndex]; - if (level.Is(LevelNames.DA) && roomIndex == 77) + if (level.Is(TR2LevelNames.DA) && roomIndex == 77) { // Make sure the end level trigger isn't blocked by an unkillable enemy - while (TR2EntityUtilities.IsHazardCreature(newEntityType) || (ProtectMonks && TR2EntityUtilities.IsMonk(newEntityType))) + while (TR2EntityUtilities.IsHazardCreature(newEntityType) || (Settings.ProtectMonks && TR2EntityUtilities.IsMonk(newEntityType))) { newEntityType = enemies.Available[_generator.Next(0, enemies.Available.Count)]; } @@ -567,7 +562,7 @@ private void RandomizeEnemies(TR2CombinedLevel level, EnemyRandomizationCollecti // If we are restricting count per level for this enemy and have reached that count, pick // something else. This applies when we are restricting by in-level count, but not by room // (e.g. Winston). - int maxEntityCount = EnemyUtilities.GetRestrictedEnemyLevelCount(newEntityType, RandoEnemyDifficulty); + int maxEntityCount = EnemyUtilities.GetRestrictedEnemyLevelCount(newEntityType, Settings.RandoEnemyDifficulty); if (maxEntityCount != -1) { if (level.Data.Entities.ToList().FindAll(e => e.TypeID == (short)newEntityType).Count >= maxEntityCount) @@ -582,7 +577,7 @@ private void RandomizeEnemies(TR2CombinedLevel level, EnemyRandomizationCollecti // #144 Disguise something as the Chicken. Pre-checks will have been done to ensure // the guiser is suitable for the level. - if (DocileBirdMonsters && newEntityType == TR2Entities.BirdMonster) + if (Settings.DocileBirdMonsters && newEntityType == TR2Entities.BirdMonster) { newEntityType = enemies.BirdMonsterGuiser; } @@ -597,7 +592,7 @@ private void RandomizeEnemies(TR2CombinedLevel level, EnemyRandomizationCollecti } // MercSnowMobDriver relies on RedSnowmobile so it will be available in the model list - if (!level.Is(LevelNames.TIBET)) + if (!level.Is(TR2LevelNames.TIBET)) { TR2Entity mercDriver = level.Data.Entities.ToList().Find(e => e.TypeID == (short)TR2Entities.MercSnowmobDriver); if (mercDriver != null) @@ -650,13 +645,13 @@ private void RandomizeEnemies(TR2CombinedLevel level, EnemyRandomizationCollecti } } - internal class EnemyProcessor : AbstractProcessorThread + internal class EnemyProcessor : AbstractProcessorThread { private readonly Dictionary> _enemyMapping; internal override int LevelCount => _enemyMapping.Count; - internal EnemyProcessor(EnemyRandomizer outer) + internal EnemyProcessor(TR2EnemyRandomizer outer) : base(outer) { _enemyMapping = new Dictionary>(); @@ -728,7 +723,8 @@ private bool Import(TR2CombinedLevel level, EnemyTransportCollection enemies) EntitiesToRemove = enemies.EntitiesToRemove, Level = level.Data, LevelName = level.Name, - TextureRemapPath = @"Resources\Textures\Deduplication\" + level.JsonID + "-TextureRemap.json", + DataFolder = _outer.GetResourcePath(@"TR2\Models"), + TextureRemapPath = _outer.GetResourcePath(@"TR2\Textures\Deduplication\" + level.JsonID + "-TextureRemap.json"), TexturePositionMonitor = _outer.TextureMonitor.CreateMonitor(level.Name, enemies.EntitiesToImport), AliasPriority = EnemyUtilities.GetAliasPriority(level.Name, enemies.EntitiesToImport) }; @@ -784,11 +780,11 @@ internal void ApplyRandomization() EnemyRandomizationCollection enemies = new EnemyRandomizationCollection { Available = importedCollection.EntitiesToImport, - Droppable = TR2EntityUtilities.FilterDroppableEnemies(importedCollection.EntitiesToImport, !_outer.ProtectMonks), + Droppable = TR2EntityUtilities.FilterDroppableEnemies(importedCollection.EntitiesToImport, !_outer.Settings.ProtectMonks), Water = TR2EntityUtilities.FilterWaterEnemies(importedCollection.EntitiesToImport) }; - if (_outer.DocileBirdMonsters && importedCollection.BirdMonsterGuiser != TR2Entities.BirdMonster) + if (_outer.Settings.DocileBirdMonsters && importedCollection.BirdMonsterGuiser != TR2Entities.BirdMonster) { _outer.DisguiseEntity(level, importedCollection.BirdMonsterGuiser, TR2Entities.BirdMonster); enemies.BirdMonsterGuiser = importedCollection.BirdMonsterGuiser; diff --git a/TR2RandomizerCore/Randomizers/EnvironmentRandomizer.cs b/TRRandomizerCore/Randomizers/TR2/TR2EnvironmentRandomizer.cs similarity index 85% rename from TR2RandomizerCore/Randomizers/EnvironmentRandomizer.cs rename to TRRandomizerCore/Randomizers/TR2/TR2EnvironmentRandomizer.cs index db3aba6cf..509602c8c 100644 --- a/TR2RandomizerCore/Randomizers/EnvironmentRandomizer.cs +++ b/TRRandomizerCore/Randomizers/TR2/TR2EnvironmentRandomizer.cs @@ -1,25 +1,19 @@ using System; using System.Collections.Generic; -using TR2RandomizerCore.Helpers; -using TR2RandomizerCore.Utilities; +using TRRandomizerCore.Helpers; +using TRRandomizerCore.Levels; +using TRRandomizerCore.Utilities; using TREnvironmentEditor; using TREnvironmentEditor.Model; using TREnvironmentEditor.Model.Types; using TRGE.Core; using TRLevelReader.Helpers; -namespace TR2RandomizerCore.Randomizers +namespace TRRandomizerCore.Randomizers { - public class EnvironmentRandomizer : RandomizerBase + public class TR2EnvironmentRandomizer : BaseTR2Randomizer { - public bool EnforcedModeOnly { get; set; } - public bool PuristMode { get; set; } - public uint NumMirrorLevels { get; set; } - public bool MirrorAssaultCourse { get; set; } - public bool RandomizeWater { get; set; } - public bool RandomizeSlots { get; set; } - public bool RandomizeLadders { get; set; } - + internal bool EnforcedModeOnly => !Settings.RandomizeEnvironment; internal TexturePositionMonitorBroker TextureMonitor { get; set; } private List _disallowedTypes; @@ -30,24 +24,24 @@ public override void Randomize(int seed) _generator = new Random(seed); _disallowedTypes = new List(); - if (!RandomizeWater) + if (!Settings.RandomizeWaterLevels) { _disallowedTypes.Add(EMType.Flood); _disallowedTypes.Add(EMType.Drain); } - if (!RandomizeSlots) + if (!Settings.RandomizeSlotPositions) { _disallowedTypes.Add(EMType.MoveSlot); _disallowedTypes.Add(EMType.SwapSlot); } - if (!RandomizeLadders) + if (!Settings.RandomizeLadders) { _disallowedTypes.Add(EMType.Ladder); } - _levelsToMirror = Levels.RandomSelection(_generator, (int)NumMirrorLevels, exclusions:new HashSet + _levelsToMirror = Levels.RandomSelection(_generator, (int)Settings.MirroredLevelCount, exclusions:new HashSet { - Levels.Find(l => l.Is(LevelNames.ASSAULT)) + Levels.Find(l => l.Is(TR2LevelNames.ASSAULT)) }); foreach (TR23ScriptedLevel lvl in Levels) @@ -67,7 +61,7 @@ public override void Randomize(int seed) private void RandomizeEnvironment(TR2CombinedLevel level) { - EMEditorMapping mapping = EMEditorMapping.Get(level.Name); + EMEditorMapping mapping = EMEditorMapping.Get(GetResourcePath(@"TR2\Environment\" + level.Name + "-Environment.json")); if (mapping != null) { if (level.IsUKBox) @@ -79,7 +73,7 @@ private void RandomizeEnvironment(TR2CombinedLevel level) ApplyMappingToLevel(level, mapping); } - if (!EnforcedModeOnly && (_levelsToMirror.Contains(level.Script) || (level.IsAssault && MirrorAssaultCourse))) + if (!EnforcedModeOnly && (_levelsToMirror.Contains(level.Script) || (level.IsAssault && Settings.MirrorAssaultCourse))) { MirrorLevel(level, mapping); } @@ -94,7 +88,7 @@ private void ApplyMappingToLevel(TR2CombinedLevel level, EMEditorMapping mapping // textures. mapping.All.ApplyToLevel(level.Data, emptyExclusions); - if (!EnforcedModeOnly || !PuristMode) + if (!EnforcedModeOnly || !Settings.PuristMode) { // Non-purist packs generally make return paths available. // These are applied only if Purist mode is off or if Environment diff --git a/TR2RandomizerCore/Randomizers/GameStringRandomizer.cs b/TRRandomizerCore/Randomizers/TR2/TR2GameStringRandomizer.cs similarity index 90% rename from TR2RandomizerCore/Randomizers/GameStringRandomizer.cs rename to TRRandomizerCore/Randomizers/TR2/TR2GameStringRandomizer.cs index b813602a4..6aed2074a 100644 --- a/TR2RandomizerCore/Randomizers/GameStringRandomizer.cs +++ b/TRRandomizerCore/Randomizers/TR2/TR2GameStringRandomizer.cs @@ -1,33 +1,27 @@ using System; using System.Collections.Generic; using System.Linq; -using TR2RandomizerCore.Globalisation; +using TRRandomizerCore.Globalisation; using TRGE.Core; using TRLevelReader.Helpers; -namespace TR2RandomizerCore.Randomizers +namespace TRRandomizerCore.Randomizers { - public class GameStringRandomizer : RandomizerBase + public class TR2GameStringRandomizer : BaseTR2Randomizer { private const int _maxLevelNameLength = 24; - public Language Language { get; set; } - public bool RandomizeAllStrings { get; set; } - public bool ReassignPuzzleNames { get; set; } - public bool RetainKeyItemNames { get; set; } - public bool RetainLevelNames { get; set; } - private GameStrings _gameStrings, _defaultGameStrings; public override void Randomize(int seed) { - if (RandomizeAllStrings) + if (Settings.RandomizeGameStrings) { _generator = new Random(seed); - if (!Language.IsHybrid) + if (!Settings.GameStringLanguage.IsHybrid) { - _gameStrings = G11N.Instance.GetGameStrings(Language); + _gameStrings = G11N.Instance.GetGameStrings(Settings.GameStringLanguage); } _defaultGameStrings = G11N.Instance.GetDefaultGameStrings(); @@ -47,22 +41,26 @@ public override void Randomize(int seed) } } - if (ReassignPuzzleNames) + if (Settings.ReassignPuzzleNames) { // This is specific to the Dagger of Xian if it appears in other levels with the dragon. We'll just // use whatever has already been allocated as the dagger name in Lair. - string daggerName = ScriptEditor.ScriptedLevels.ToList().Find(l => l.Is(LevelNames.LAIR)).Puzzles[1]; + string daggerName = ScriptEditor.ScriptedLevels.ToList().Find(l => l.Is(TR2LevelNames.LAIR)).Puzzles[1]; foreach (AbstractTRScriptedLevel level in ScriptEditor.ScriptedLevels) { MoveAndReplacePuzzle(level, 1, 2, daggerName); } } + + SaveScript(); + + TriggerProgress(); } private GameStrings GetGameStrings() { // This allows for a hybrid language to be used, so each call will randomly pick another language. - if (Language.IsHybrid) + if (Settings.GameStringLanguage.IsHybrid) { Language[] availableLangs = G11N.Instance.RealLanguages; return G11N.Instance.GetGameStrings(availableLangs[_generator.Next(0, availableLangs.Length)]); @@ -141,7 +139,7 @@ private void ProcessLevelStrings(AbstractTRScriptedLevel level) LevelStrings defaultLevelStrings = _defaultGameStrings.LevelStrings[levelID]; - if (!RetainLevelNames && defaultLevelStrings.Names != null && defaultLevelStrings.Names.Length > 0) + if (!Settings.RetainLevelNames && defaultLevelStrings.Names != null && defaultLevelStrings.Names.Length > 0) { string[] options = GetLevelStrings(levelID).Names; string levelName; @@ -154,7 +152,7 @@ private void ProcessLevelStrings(AbstractTRScriptedLevel level) level.Name = GameStrings.Encode(levelName); } - if (RetainKeyItemNames) + if (Settings.RetainKeyItemNames) { return; } diff --git a/TR2RandomizerCore/Randomizers/ItemRandomizer.cs b/TRRandomizerCore/Randomizers/TR2/TR2ItemRandomizer.cs similarity index 95% rename from TR2RandomizerCore/Randomizers/ItemRandomizer.cs rename to TRRandomizerCore/Randomizers/TR2/TR2ItemRandomizer.cs index ff85bcbfb..85cc42311 100644 --- a/TR2RandomizerCore/Randomizers/ItemRandomizer.cs +++ b/TRRandomizerCore/Randomizers/TR2/TR2ItemRandomizer.cs @@ -1,11 +1,10 @@ using Newtonsoft.Json; using System; using System.Collections.Generic; -using System.IO; using System.Linq; -using TR2RandomizerCore.Helpers; -using TR2RandomizerCore.Utilities; -using TR2RandomizerCore.Zones; +using TRRandomizerCore.Helpers; +using TRRandomizerCore.Utilities; +using TRRandomizerCore.Zones; using TRGE.Core; using TRLevelReader.Helpers; using TRLevelReader.Model; @@ -13,16 +12,12 @@ using TRModelTransporter.Packing; using TRModelTransporter.Transport; -namespace TR2RandomizerCore.Randomizers +namespace TRRandomizerCore.Randomizers { - public class ItemRandomizer : RandomizerBase + public class TR2ItemRandomizer : BaseTR2Randomizer { private static readonly List _devRooms = null; - public bool IncludeKeyItems { get; set; } - public bool IsDevelopmentModeOn { get; set; } - public bool PerformEnemyWeighting { get; set; } - public ItemDifficulty Difficulty { get; set; } internal TexturePositionMonitorBroker TextureMonitor { get; set; } // This replaces plane cargo index as TRGE may have randomized the weaponless level(s), but will also have injected pistols @@ -30,16 +25,16 @@ public class ItemRandomizer : RandomizerBase private int _unarmedLevelPistolIndex; private readonly Dictionary> _pistolLocations; - public ItemRandomizer() + public TR2ItemRandomizer() { - _pistolLocations = JsonConvert.DeserializeObject>>(File.ReadAllText(@"Resources\unarmed_locations.json")); + _pistolLocations = JsonConvert.DeserializeObject>>(ReadResource(@"TR2\Locations\unarmed_locations.json")); } public override void Randomize(int seed) { _generator = new Random(seed); - Dictionary> locations = JsonConvert.DeserializeObject>>(File.ReadAllText(@"Resources\item_locations.json")); + Dictionary> locations = JsonConvert.DeserializeObject>>(ReadResource(@"TR2\Locations\item_locations.json")); foreach (TR23ScriptedLevel lvl in Levels) { @@ -71,7 +66,7 @@ public void RandomizeAmmo() //Read the level into a combined data/script level object LoadLevelInstance(lvl); - if (IsDevelopmentModeOn && _pistolLocations.ContainsKey(_levelInstance.Name)) + if (Settings.DevelopmentMode && _pistolLocations.ContainsKey(_levelInstance.Name)) { PlaceAllItems(_pistolLocations[_levelInstance.Name], TR2Entities.Pistols_S_P, false); } @@ -82,7 +77,7 @@ public void RandomizeAmmo() if (lvl.RemovesWeapons) { RandomizeUnarmedLevelWeapon(); } //#47 - Randomize the HSH weapon closet - if (lvl.Is(LevelNames.HOME)) { PopulateHSHCloset(); } + if (lvl.Is(TR2LevelNames.HOME)) { PopulateHSHCloset(); } //Write back the level file SaveLevelInstance(); @@ -125,7 +120,7 @@ private void PlaceAllItems(List locations, TR2Entities entityToAdd = T private void RepositionItems(List ItemLocs) { - if (IsDevelopmentModeOn) + if (Settings.DevelopmentMode) { PlaceAllItems(ItemLocs); return; @@ -138,14 +133,14 @@ private void RepositionItems(List ItemLocs) targetents.AddRange(TR2EntityUtilities.GetListOfAmmoTypes()); //And also key items... - if (IncludeKeyItems) + if (Settings.IncludeKeyItems) { targetents.AddRange(TR2EntityUtilities.GetListOfKeyItemTypes()); } //It's important to now start zoning key items as softlocks must be avoided. ZonedLocationCollection ZonedLocations = new ZonedLocationCollection(); - ZonedLocations.PopulateZones(_levelInstance.Name, ItemLocs, ZonePopulationMethod.KeyPuzzleQuestOnly); + ZonedLocations.PopulateZones(GetResourcePath(@"TR2\Zones\" + _levelInstance.Name + "-Zones.json"), ItemLocs, ZonePopulationMethod.KeyPuzzleQuestOnly); for (int i = 0; i < _levelInstance.Data.Entities.Count(); i++) { @@ -164,7 +159,7 @@ private void RepositionItems(List ItemLocs) case TR2Entities.Puzzle1_S_P: if (ZonedLocations.Puzzle1Zone.Count > 0) { - if (_levelInstance.Name == LevelNames.DA) + if (_levelInstance.Name == TR2LevelNames.DA) { int burnerChipID = 120; int consoleChipID = 7; @@ -233,7 +228,7 @@ private void RepositionItems(List ItemLocs) case TR2Entities.Key1_S_P: if (ZonedLocations.Key1Zone.Count > 0) { - if (_levelInstance.Name == LevelNames.OPERA) + if (_levelInstance.Name == TR2LevelNames.OPERA) { int startKeyID = 172; int fanKeyID = 118; @@ -336,7 +331,7 @@ private void RepositionItems(List ItemLocs) } } - if (Difficulty == ItemDifficulty.OneLimit) + if (Settings.RandoItemDifficulty == ItemDifficulty.OneLimit) { List oneOfEachType = new List(); List allEntities = _levelInstance.Data.Entities.ToList(); @@ -426,13 +421,13 @@ private void RandomizeUnarmedLevelWeapon() TR2Entities weaponType = replacementWeapons[_generator.Next(0, replacementWeapons.Count)]; // force pistols for OneLimit and then we're done - if (Difficulty == ItemDifficulty.OneLimit) + if (Settings.RandoItemDifficulty == ItemDifficulty.OneLimit) { weaponType = replacementWeapons[replacementWeapons.Count - 1]; return; } - if (_levelInstance.Is(LevelNames.CHICKEN)) + if (_levelInstance.Is(TR2LevelNames.CHICKEN)) { // Grenade Launcher and Harpoon cannot trigger the bells in Ice Palace while (weaponType.Equals(TR2Entities.GrenadeLauncher_S_P) || weaponType.Equals(TR2Entities.Harpoon_S_P)) @@ -449,7 +444,7 @@ private void RandomizeUnarmedLevelWeapon() if (_startingAmmoToGive.ContainsKey(weaponType)) { ammoToGive = _startingAmmoToGive[weaponType]; - if (PerformEnemyWeighting) + if (Settings.RandomizeEnemies && Settings.CrossLevelEnemies) { // Create a score based on each type of enemy in this level and increase the ammo count based on this EnemyDifficulty difficulty = EnemyUtilities.GetEnemyDifficulty(_levelInstance.GetEnemyEntities()); @@ -471,7 +466,7 @@ private void RandomizeUnarmedLevelWeapon() largeMediToGive++; } } - else if (_levelInstance.Is(LevelNames.LAIR)) + else if (_levelInstance.Is(TR2LevelNames.LAIR)) { ammoToGive *= 6; } @@ -579,7 +574,7 @@ private void PopulateHSHCloset() { entity.TypeID = (short)replacementWeapon; - if (replacementWeapon == TR2Entities.Harpoon_S_P || (Difficulty == ItemDifficulty.OneLimit && replacementWeapon != TR2Entities.Pistols_S_P)) + if (replacementWeapon == TR2Entities.Harpoon_S_P || (Settings.RandoItemDifficulty == ItemDifficulty.OneLimit && replacementWeapon != TR2Entities.Pistols_S_P)) { harpoonWeapon = entity; } @@ -589,7 +584,7 @@ private void PopulateHSHCloset() entity.TypeID = (short)replacementAmmo; } - if (Difficulty == ItemDifficulty.OneLimit) + if (Settings.RandoItemDifficulty == ItemDifficulty.OneLimit) { // look for extra utility/ammo items and hide them TR2Entities eType = (TR2Entities)entity.TypeID; @@ -642,6 +637,7 @@ private void RandomizeVehicles() LevelName = _levelInstance.Name, ClearUnusedSprites = false, EntitiesToImport = vehicles.Keys, + DataFolder = GetResourcePath(@"TR2\Models"), TexturePositionMonitor = TextureMonitor.CreateMonitor(_levelInstance.Name, vehicles.Keys.ToList()) }; diff --git a/TR2RandomizerCore/Randomizers/NightModeRandomizer.cs b/TRRandomizerCore/Randomizers/TR2/TR2NightModeRandomizer.cs similarity index 88% rename from TR2RandomizerCore/Randomizers/NightModeRandomizer.cs rename to TRRandomizerCore/Randomizers/TR2/TR2NightModeRandomizer.cs index 11acb8b80..8fd7c7fec 100644 --- a/TR2RandomizerCore/Randomizers/NightModeRandomizer.cs +++ b/TRRandomizerCore/Randomizers/TR2/TR2NightModeRandomizer.cs @@ -1,23 +1,20 @@ using System; using System.Collections.Generic; using System.Linq; -using TR2RandomizerCore.Helpers; -using TR2RandomizerCore.Utilities; +using TRRandomizerCore.Helpers; +using TRRandomizerCore.Levels; +using TRRandomizerCore.Utilities; using TRGE.Core; using TRLevelReader.Helpers; using TRLevelReader.Model; using TRLevelReader.Model.Enums; -namespace TR2RandomizerCore.Randomizers +namespace TRRandomizerCore.Randomizers { - public class NightModeRandomizer : RandomizerBase + public class TR2NightModeRandomizer : BaseTR2Randomizer { public const uint DarknessRange = 10; // 0 = Dusk, 10 = Night - public uint NumLevels { get; set; } - public uint DarknessScale { get; set; } - public bool NightModeAssaultCourse { get; set; } - internal TexturePositionMonitorBroker TextureMonitor { get; set; } private List _nightLevels; @@ -26,7 +23,7 @@ public override void Randomize(int seed) { _generator = new Random(seed); - DarknessScale = Math.Min(DarknessScale, DarknessRange); + Settings.NightModeDarkness = Math.Min(Settings.NightModeDarkness, DarknessRange); ChooseNightLevels(); @@ -49,11 +46,11 @@ public override void Randomize(int seed) private void ChooseNightLevels() { - TR23ScriptedLevel assaultCourse = Levels.Find(l => l.Is(LevelNames.ASSAULT)); + TR23ScriptedLevel assaultCourse = Levels.Find(l => l.Is(TR2LevelNames.ASSAULT)); ISet exlusions = new HashSet { assaultCourse }; - _nightLevels = Levels.RandomSelection(_generator, (int)NumLevels, exclusions: exlusions); - if (NightModeAssaultCourse) + _nightLevels = Levels.RandomSelection(_generator, (int)Settings.NightModeCount, exclusions: exlusions); + if (Settings.NightModeAssaultCourse) { _nightLevels.Add(assaultCourse); } @@ -76,7 +73,7 @@ private void SetNightMode(TR2CombinedLevel level) private void DarkenRooms(TR2Level level) { - double scale = (100 - DarknessRange + DarknessScale) / 100d; + double scale = (100 - DarknessRange + Settings.NightModeDarkness) / 100d; short intensity1 = (short)(TR2Room.DarknessIntensity1 * scale); ushort intensity2 = (ushort)(TR2Room.DarknessIntensity2 * (2 - scale)); @@ -144,10 +141,10 @@ private void HideDaytimeEntities(TR2Level level, string levelName) private static readonly Dictionary _staticMeshesToHide = new Dictionary { // The washing lines come in at night - [LevelNames.VENICE] = + [TR2LevelNames.VENICE] = new uint[] { 32, 33 }, // The monks are washing their prayer flags - [LevelNames.MONASTERY] = + [TR2LevelNames.MONASTERY] = new uint[] { 36 } }; } diff --git a/TR2RandomizerCore/Randomizers/OutfitRandomizer.cs b/TRRandomizerCore/Randomizers/TR2/TR2OutfitRandomizer.cs similarity index 92% rename from TR2RandomizerCore/Randomizers/OutfitRandomizer.cs rename to TRRandomizerCore/Randomizers/TR2/TR2OutfitRandomizer.cs index e1c789595..01ce0d142 100644 --- a/TR2RandomizerCore/Randomizers/OutfitRandomizer.cs +++ b/TRRandomizerCore/Randomizers/TR2/TR2OutfitRandomizer.cs @@ -2,9 +2,10 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using TR2RandomizerCore.Helpers; -using TR2RandomizerCore.Processors; -using TR2RandomizerCore.Utilities; +using TRRandomizerCore.Helpers; +using TRRandomizerCore.Levels; +using TRRandomizerCore.Processors; +using TRRandomizerCore.Utilities; using TRGE.Core; using TRLevelReader.Helpers; using TRLevelReader.Model; @@ -12,17 +13,10 @@ using TRModelTransporter.Packing; using TRModelTransporter.Transport; -namespace TR2RandomizerCore.Randomizers +namespace TRRandomizerCore.Randomizers { - public class OutfitRandomizer : RandomizerBase + public class TR2OutfitRandomizer : BaseTR2Randomizer { - internal bool PersistOutfits { get; set; } - internal bool RemoveRobeDagger { get; set; } - internal uint NumHaircutLevels { get; set; } - internal bool AssaultCourseHaircut { get; set; } - internal uint NumInvisibleLevels { get; set; } - internal bool AssaultCourseInvisible { get; set; } - internal TexturePositionMonitorBroker TextureMonitor { get; set; } private TR2Entities _persistentOutfit; @@ -55,7 +49,7 @@ public override void Randomize(int seed) } } - if (RemoveRobeDagger) + if (Settings.RemoveRobeDagger) { // Keep a reference to the first dragon level if we are removing the dagger from the dressing gown. This needs to be done // based on the level sequencing. @@ -101,7 +95,7 @@ private List GetLaraTypes() private void SetPersistentOutfit() { - if (PersistOutfits) + if (Settings.PersistOutfits) { List allLaras = GetLaraTypes(); _persistentOutfit = allLaras[_generator.Next(0, allLaras.Count)]; @@ -110,17 +104,17 @@ private void SetPersistentOutfit() private void ChooseFilteredLevels() { - TR23ScriptedLevel assaultCourse = Levels.Find(l => l.Is(LevelNames.ASSAULT)); + TR23ScriptedLevel assaultCourse = Levels.Find(l => l.Is(TR2LevelNames.ASSAULT)); ISet exlusions = new HashSet { assaultCourse }; - _haircutLevels = Levels.RandomSelection(_generator, (int)NumHaircutLevels, exclusions: exlusions); - if (AssaultCourseHaircut) + _haircutLevels = Levels.RandomSelection(_generator, (int)Settings.HaircutLevelCount, exclusions: exlusions); + if (Settings.AssaultCourseHaircut) { _haircutLevels.Add(assaultCourse); } - _invisibleLevels = Levels.RandomSelection(_generator, (int)NumInvisibleLevels, exclusions: exlusions); - if (AssaultCourseInvisible) + _invisibleLevels = Levels.RandomSelection(_generator, (int)Settings.InvisibleLevelCount, exclusions: exlusions); + if (Settings.AssaultCourseInvisible) { _invisibleLevels.Add(assaultCourse); } @@ -136,7 +130,7 @@ private bool IsInvisibleLevel(TR23ScriptedLevel lvl) return _invisibleLevels.Contains(lvl); } - internal class OutfitProcessor : AbstractProcessorThread + internal class OutfitProcessor : AbstractProcessorThread { // Each of these needs to be removed and replaced with the corresponding animation // models for the associated outfit. @@ -167,7 +161,7 @@ internal class OutfitProcessor : AbstractProcessorThread internal override int LevelCount => _outfitAllocations.Count; - internal OutfitProcessor(OutfitRandomizer outer) + internal OutfitProcessor(TR2OutfitRandomizer outer) : base(outer) { _outfitAllocations = new Dictionary>(); @@ -198,7 +192,7 @@ protected override void StartImpl() { // Add the persistent outfit first, but we will populate the candidate // list regardless in case a level cannot support this choice. - if (_outer.PersistOutfits) + if (_outer.Settings.PersistOutfits) { _outfitAllocations[level].Add(_outer._persistentOutfit); } @@ -266,10 +260,11 @@ private bool Import(TR2CombinedLevel level, TR2Entities lara) ClearUnusedSprites = false, EntitiesToImport = laraImport, EntitiesToRemove = laraRemovals, - TexturePositionMonitor = _outer.TextureMonitor.CreateMonitor(level.Name, laraImport) + TexturePositionMonitor = _outer.TextureMonitor.CreateMonitor(level.Name, laraImport), + DataFolder = _outer.GetResourcePath(@"TR2\Models") }; - string remapPath = @"Resources\Textures\Deduplication\" + level.JsonID + "-TextureRemap.json"; + string remapPath = _outer.GetResourcePath(@"TR2\Textures\Deduplication\" + level.JsonID + "-TextureRemap.json"); if (File.Exists(remapPath)) { importer.TextureRemapPath = remapPath; @@ -327,7 +322,7 @@ private void HideEntities(TR2CombinedLevel level, IEnumerable entit private void AdjustOutfit(TR2CombinedLevel level, TR2Entities lara) { - if (level.Is(LevelNames.HOME) && lara != TR2Entities.LaraHome) + if (level.Is(TR2LevelNames.HOME) && lara != TR2Entities.LaraHome) { // This ensures that Lara's hips match the new outfit for the starting animation and shower cutscene, // otherwise the dressing gown hips are rendered, but the mesh is completely different for this, plus @@ -337,7 +332,7 @@ private void AdjustOutfit(TR2CombinedLevel level, TR2Entities lara) TR2LevelUtilities.DuplicateMesh(level.Data, laraMiscMesh, laraHipsMesh); } - if (_outer.RemoveRobeDagger) + if (_outer.Settings.RemoveRobeDagger) { // We will get rid of the dagger from Lara's dressing gown if this level takes place before any other // level that contains a dragon, or if this level itself has the dragon. If it's a cutscene that @@ -361,7 +356,7 @@ private void AdjustOutfit(TR2CombinedLevel level, TR2Entities lara) // If it's HSH, go one step further and remove the model itself, so Lara is imagining what the dagger // will be like during the cutscene. It will still be present in the inventory but will be invisible. - if (level.Is(LevelNames.HOME)) + if (level.Is(TR2LevelNames.HOME)) { // This removes it from the starting cutscene - mesh 10 is Lara's hand holding the dagger, // so we basically just retain the hand. @@ -386,7 +381,7 @@ private void AdjustOutfit(TR2CombinedLevel level, TR2Entities lara) } } - if (level.Is(LevelNames.DA_CUT) && lara != TR2Entities.LaraSun) + if (level.Is(TR2LevelNames.DA_CUT) && lara != TR2Entities.LaraSun) { // There are actually 2 Lara models in this cutscene. Model ID 0 is Lara after she has changed // into the diving suit, but model ID 99 is the one before. We always want the cutscene actor to diff --git a/TR2RandomizerCore/Randomizers/SecretReplacer.cs b/TRRandomizerCore/Randomizers/TR2/TR2SecretRandomizer.cs similarity index 89% rename from TR2RandomizerCore/Randomizers/SecretReplacer.cs rename to TRRandomizerCore/Randomizers/TR2/TR2SecretRandomizer.cs index 6d58218d9..aeea1db4a 100644 --- a/TR2RandomizerCore/Randomizers/SecretReplacer.cs +++ b/TRRandomizerCore/Randomizers/TR2/TR2SecretRandomizer.cs @@ -1,35 +1,26 @@ -using System; +using Newtonsoft.Json; +using System; using System.Collections.Generic; -using System.IO; using System.Linq; -using TRLevelReader.Model; -using Newtonsoft.Json; -using TRLevelReader.Model.Enums; -using TR2RandomizerCore.Utilities; -using TR2RandomizerCore.Zones; -using TR2RandomizerCore.Helpers; +using TRRandomizerCore.Helpers; +using TRRandomizerCore.Utilities; +using TRRandomizerCore.Zones; using TRGE.Core; using TRLevelReader.Helpers; +using TRLevelReader.Model; +using TRLevelReader.Model.Enums; -namespace TR2RandomizerCore.Randomizers +namespace TRRandomizerCore.Randomizers { - public class SecretReplacer : RandomizerBase + public class TR2SecretRandomizer : BaseTR2Randomizer { private static readonly List _devRooms = null; - - public bool AllowHard { get; set; } - public bool AllowGlitched { get; set; } - public bool IsDevelopmentModeOn { get; set; } - public SecretReplacer() : base() - { - } - private void RandomizeSecrets(List LevelLocations) { if (LevelLocations.Count > 2) { - if (IsDevelopmentModeOn) + if (Settings.DevelopmentMode) { PlaceAllSecrets(LevelLocations); return; @@ -38,7 +29,7 @@ private void RandomizeSecrets(List LevelLocations) //Apply zoning to the locations to ensure they are spread out. ZonedLocationCollection ZonedLocations = new ZonedLocationCollection(); - ZonedLocations.PopulateZones(_levelInstance.Name, LevelLocations, ZonePopulationMethod.SecretsOnly); + ZonedLocations.PopulateZones(GetResourcePath(@"TR2\Zones\" + _levelInstance.Name + "-Zones.json"), LevelLocations, ZonePopulationMethod.SecretsOnly); Location GoldSecret; Location JadeSecret; @@ -49,24 +40,24 @@ private void RandomizeSecrets(List LevelLocations) do { GoldSecret = ZonedLocations.GoldZone[_generator.Next(0, ZonedLocations.GoldZone.Count)]; - } while ((GoldSecret.Difficulty == Difficulty.Hard && AllowHard == false) || - (GoldSecret.RequiresGlitch == true && AllowGlitched == false)); + } while ((GoldSecret.Difficulty == Difficulty.Hard && Settings.HardSecrets == false) || + (GoldSecret.RequiresGlitch == true && Settings.GlitchedSecrets == false)); do { JadeSecret = ZonedLocations.JadeZone[_generator.Next(0, ZonedLocations.JadeZone.Count)]; } while ((JadeSecret.Room == GoldSecret.Room) || - (JadeSecret.Difficulty == Difficulty.Hard && AllowHard == false) || - (JadeSecret.RequiresGlitch == true && AllowGlitched == false)); + (JadeSecret.Difficulty == Difficulty.Hard && Settings.HardSecrets == false) || + (JadeSecret.RequiresGlitch == true && Settings.GlitchedSecrets == false)); do { StoneSecret = ZonedLocations.StoneZone[_generator.Next(0, ZonedLocations.StoneZone.Count)]; } while ((StoneSecret.Room == GoldSecret.Room) || (StoneSecret.Room == JadeSecret.Room) || - (StoneSecret.Difficulty == Difficulty.Hard && AllowHard == false) || - (StoneSecret.RequiresGlitch == true && AllowGlitched == false)); + (StoneSecret.Difficulty == Difficulty.Hard && Settings.HardSecrets == false) || + (StoneSecret.RequiresGlitch == true && Settings.GlitchedSecrets == false)); //Due to TRMod only accepting room space coords entities are actually stored in level space. So include some //calls to support a transformation of any locations that are specified in room space to maintain backwards compatbility @@ -171,7 +162,7 @@ private void PlaceAllSecrets(List LevelLocations) { ZonedLocationCollection ZonedLocations = new ZonedLocationCollection(); - ZonedLocations.PopulateZones(_levelInstance.Name, LevelLocations, ZonePopulationMethod.SecretsOnly); + ZonedLocations.PopulateZones(GetResourcePath(@"TR2\Zones\" + _levelInstance.Name + "-Zones.json"), LevelLocations, ZonePopulationMethod.SecretsOnly); List ents = _levelInstance.Data.Entities.ToList(); @@ -232,7 +223,7 @@ public override void Randomize(int seed) { _generator = new Random(seed); - Dictionary> Locations = JsonConvert.DeserializeObject>>(File.ReadAllText(@"Resources\locations.json")); + Dictionary> Locations = JsonConvert.DeserializeObject>>(ReadResource(@"TR2\Locations\locations.json")); foreach (TR23ScriptedLevel lvl in Levels) { diff --git a/TR2RandomizerCore/Randomizers/StartPositionRandomizer.cs b/TRRandomizerCore/Randomizers/TR2/TR2StartPositionRandomizer.cs similarity index 85% rename from TR2RandomizerCore/Randomizers/StartPositionRandomizer.cs rename to TRRandomizerCore/Randomizers/TR2/TR2StartPositionRandomizer.cs index b6fae43a0..f29e7c567 100644 --- a/TR2RandomizerCore/Randomizers/StartPositionRandomizer.cs +++ b/TRRandomizerCore/Randomizers/TR2/TR2StartPositionRandomizer.cs @@ -1,27 +1,24 @@ using Newtonsoft.Json; using System; using System.Collections.Generic; -using System.IO; using System.Linq; -using TR2RandomizerCore.Helpers; +using TRRandomizerCore.Helpers; +using TRRandomizerCore.Levels; using TRGE.Core; using TRLevelReader.Helpers; using TRLevelReader.Model; using TRLevelReader.Model.Enums; -namespace TR2RandomizerCore.Randomizers +namespace TRRandomizerCore.Randomizers { - public class StartPositionRandomizer : RandomizerBase + public class TR2StartPositionRandomizer : BaseTR2Randomizer { - public bool RotateOnly { get; set; } - public bool DevelopmentMode { get; set; } - private Dictionary> _startLocations; public override void Randomize(int seed) { _generator = new Random(seed); - _startLocations = JsonConvert.DeserializeObject>>(File.ReadAllText(@"Resources\start_positions.json")); + _startLocations = JsonConvert.DeserializeObject>>(ReadResource(@"TR2\Locations\start_positions.json")); foreach (TR23ScriptedLevel lvl in Levels) { @@ -53,17 +50,17 @@ private void RandomizeStartPosition(TR2CombinedLevel level) // We only change position if there is not a secret in the same room as Lara, This is just in case it ends up // where she starts on a slope (GW or Opera House for example), as its X,Y,Z values may not be identical to Lara's, // or she may have to jump on the first frame to get it. - if (!DevelopmentMode && entities.Find(e => e.Room == lara.Room && TR2EntityUtilities.IsSecretType((TR2Entities)e.TypeID)) != null) + if (!Settings.DevelopmentMode && entities.Find(e => e.Room == lara.Room && TR2EntityUtilities.IsSecretType((TR2Entities)e.TypeID)) != null) { return; } // If we haven't defined anything for a level, Lara will just be rotated. This is most likely where there are // triggers just after Lara's starting spot, so we just skip them here. - if (!RotateOnly && _startLocations.ContainsKey(level.Name)) + if (!Settings.RotateStartPositionOnly && _startLocations.ContainsKey(level.Name)) { List locations = _startLocations[level.Name]; - if (DevelopmentMode) + if (Settings.DevelopmentMode) { foreach (Location loc in locations) { @@ -94,7 +91,7 @@ private void RandomizeStartPosition(TR2CombinedLevel level) RotateLara(lara, level); - if (DevelopmentMode) + if (Settings.DevelopmentMode) { level.Data.Entities = entities.ToArray(); level.Data.NumEntities = (uint)entities.Count; @@ -112,7 +109,7 @@ private void RotateLara(TR2Entity lara, TR2CombinedLevel level) while (lara.Angle == currentAngle); // Spin the boat around too - if (level.Is(LevelNames.BARTOLI)) + if (level.Is(TR2LevelNames.BARTOLI)) { TR2Entity boat = level.Data.Entities.ToList().Find(e => e.TypeID == (short)TR2Entities.Boat); boat.Angle = lara.Angle; diff --git a/TR2RandomizerCore/Randomizers/TextureRandomizer.cs b/TRRandomizerCore/Randomizers/TR2/TR2TextureRandomizer.cs similarity index 94% rename from TR2RandomizerCore/Randomizers/TextureRandomizer.cs rename to TRRandomizerCore/Randomizers/TR2/TR2TextureRandomizer.cs index c9e7f6ceb..dcbf23cdf 100644 --- a/TR2RandomizerCore/Randomizers/TextureRandomizer.cs +++ b/TRRandomizerCore/Randomizers/TR2/TR2TextureRandomizer.cs @@ -1,30 +1,28 @@ using System; using System.Collections.Generic; using System.Linq; -using TR2RandomizerCore.Helpers; -using TR2RandomizerCore.Processors; -using TR2RandomizerCore.Utilities; +using TRRandomizerCore.Helpers; +using TRRandomizerCore.Levels; +using TRRandomizerCore.Processors; +using TRRandomizerCore.Utilities; using TRGE.Core; using TRTexture16Importer.Textures; using TRTexture16Importer.Textures.Grouping; using TRTexture16Importer.Textures.Source; -namespace TR2RandomizerCore.Randomizers +namespace TRRandomizerCore.Randomizers { - public class TextureRandomizer : RandomizerBase + public class TR2TextureRandomizer : BaseTR2Randomizer { private readonly Dictionary _persistentVariants; private readonly object _drawLock; private TextureDatabase _textureDatabase; private Dictionary _textureOptions; - internal bool NightModeOnly { get; set; } - internal bool PersistVariants { get; set; } - internal bool RetainKeySprites { get; set; } - internal bool RetainSecretSprites { get; set; } + internal bool NightModeOnly => !Settings.RandomizeTextures; internal TexturePositionMonitorBroker TextureMonitor { get; set; } - public TextureRandomizer() + public TR2TextureRandomizer() { _persistentVariants = new Dictionary(); _drawLock = new object(); @@ -88,8 +86,8 @@ private void RandomizeAllTextures() // These options are used to switch on/off specific textures _textureOptions = new Dictionary { - [TextureCategory.KeyItem] = !RetainKeySprites, - [TextureCategory.Secret] = !RetainSecretSprites + [TextureCategory.KeyItem] = !Settings.RetainKeySpriteTextures, + [TextureCategory.Secret] = !Settings.RetainSecretSpriteTextures }; SetMessage("Randomizing textures - loading levels"); @@ -140,7 +138,7 @@ private string GetSourceVariant(AbstractTextureSource source) { lock (_drawLock) { - if (PersistVariants && _persistentVariants.ContainsKey(source)) + if (Settings.PersistTextureVariants && _persistentVariants.ContainsKey(source)) { return _persistentVariants[source]; } @@ -155,7 +153,7 @@ private string GetSourceVariant(AbstractTextureSource source) private void StoreVariant(AbstractTextureSource source, string variant) { - if (PersistVariants) + if (Settings.PersistTextureVariants) { _persistentVariants[source] = variant; } @@ -184,14 +182,14 @@ private void RedrawTargets(TextureLevelMapping mapping, AbstractTextureSource so } } - internal class TextureProcessor : AbstractProcessorThread + internal class TextureProcessor : AbstractProcessorThread { private readonly Dictionary _holders; private readonly LandmarkImporter _landmarkImporter; internal override int LevelCount => _holders.Count; - internal TextureProcessor(TextureRandomizer outer) + internal TextureProcessor(TR2TextureRandomizer outer) :base(outer) { _holders = new Dictionary(); @@ -291,7 +289,7 @@ internal class TextureHolder : IDisposable internal TextureLevelMapping Mapping { get; private set; } internal Dictionary Variants { get; private set; } - internal TextureHolder(TextureLevelMapping mapping, TextureRandomizer outer, TextureHolder parentHolder = null) + internal TextureHolder(TextureLevelMapping mapping, TR2TextureRandomizer outer, TextureHolder parentHolder = null) { Mapping = mapping; Variants = new Dictionary(); diff --git a/TRRandomizerCore/Randomizers/TR3/BaseTR3Randomizer.cs b/TRRandomizerCore/Randomizers/TR3/BaseTR3Randomizer.cs new file mode 100644 index 000000000..46cf9df1d --- /dev/null +++ b/TRRandomizerCore/Randomizers/TR3/BaseTR3Randomizer.cs @@ -0,0 +1,15 @@ +using System; +using TRRandomizerCore.Editors; +using TRRandomizerCore.Processors; + +namespace TRRandomizerCore.Randomizers +{ + public abstract class BaseTR3Randomizer : TR3LevelProcessor, IRandomizer + { + public RandomizerSettings Settings { get; internal set; } + + protected Random _generator; + + public abstract void Randomize(int seed); + } +} \ No newline at end of file diff --git a/TR2RandomizerCore/Resources/Documentation/ENEMIES.md b/TRRandomizerCore/Resources/Documentation/ENEMIES.md similarity index 100% rename from TR2RandomizerCore/Resources/Documentation/ENEMIES.md rename to TRRandomizerCore/Resources/Documentation/ENEMIES.md diff --git a/TR2RandomizerCore/Resources/Documentation/ORDER.md b/TRRandomizerCore/Resources/Documentation/ORDER.md similarity index 100% rename from TR2RandomizerCore/Resources/Documentation/ORDER.md rename to TRRandomizerCore/Resources/Documentation/ORDER.md diff --git a/TR2RandomizerCore/Resources/tr2audio.json b/TRRandomizerCore/Resources/TR2/Audio/audio_tracks.json similarity index 100% rename from TR2RandomizerCore/Resources/tr2audio.json rename to TRRandomizerCore/Resources/TR2/Audio/audio_tracks.json diff --git a/TR2RandomizerCore/Resources/tr2sfx.json b/TRRandomizerCore/Resources/TR2/Audio/sfx.json similarity index 100% rename from TR2RandomizerCore/Resources/tr2sfx.json rename to TRRandomizerCore/Resources/TR2/Audio/sfx.json diff --git a/TR2RandomizerCore/Resources/Environment/ASSAULT.TR2-Environment.json b/TRRandomizerCore/Resources/TR2/Environment/ASSAULT.TR2-Environment.json similarity index 100% rename from TR2RandomizerCore/Resources/Environment/ASSAULT.TR2-Environment.json rename to TRRandomizerCore/Resources/TR2/Environment/ASSAULT.TR2-Environment.json diff --git a/TR2RandomizerCore/Resources/Environment/BOAT.TR2-Environment.json b/TRRandomizerCore/Resources/TR2/Environment/BOAT.TR2-Environment.json similarity index 100% rename from TR2RandomizerCore/Resources/Environment/BOAT.TR2-Environment.json rename to TRRandomizerCore/Resources/TR2/Environment/BOAT.TR2-Environment.json diff --git a/TR2RandomizerCore/Resources/Environment/CATACOMB.TR2-Environment.json b/TRRandomizerCore/Resources/TR2/Environment/CATACOMB.TR2-Environment.json similarity index 100% rename from TR2RandomizerCore/Resources/Environment/CATACOMB.TR2-Environment.json rename to TRRandomizerCore/Resources/TR2/Environment/CATACOMB.TR2-Environment.json diff --git a/TR2RandomizerCore/Resources/Environment/DECK.TR2-Environment.json b/TRRandomizerCore/Resources/TR2/Environment/DECK.TR2-Environment.json similarity index 100% rename from TR2RandomizerCore/Resources/Environment/DECK.TR2-Environment.json rename to TRRandomizerCore/Resources/TR2/Environment/DECK.TR2-Environment.json diff --git a/TR2RandomizerCore/Resources/Environment/EMPRTOMB.TR2-Environment.json b/TRRandomizerCore/Resources/TR2/Environment/EMPRTOMB.TR2-Environment.json similarity index 100% rename from TR2RandomizerCore/Resources/Environment/EMPRTOMB.TR2-Environment.json rename to TRRandomizerCore/Resources/TR2/Environment/EMPRTOMB.TR2-Environment.json diff --git a/TR2RandomizerCore/Resources/Environment/FLOATING.TR2-Environment.json b/TRRandomizerCore/Resources/TR2/Environment/FLOATING.TR2-Environment.json similarity index 100% rename from TR2RandomizerCore/Resources/Environment/FLOATING.TR2-Environment.json rename to TRRandomizerCore/Resources/TR2/Environment/FLOATING.TR2-Environment.json diff --git a/TR2RandomizerCore/Resources/Environment/HOUSE.TR2-Environment.json b/TRRandomizerCore/Resources/TR2/Environment/HOUSE.TR2-Environment.json similarity index 100% rename from TR2RandomizerCore/Resources/Environment/HOUSE.TR2-Environment.json rename to TRRandomizerCore/Resources/TR2/Environment/HOUSE.TR2-Environment.json diff --git a/TR2RandomizerCore/Resources/Environment/ICECAVE.TR2-Environment.json b/TRRandomizerCore/Resources/TR2/Environment/ICECAVE.TR2-Environment.json similarity index 100% rename from TR2RandomizerCore/Resources/Environment/ICECAVE.TR2-Environment.json rename to TRRandomizerCore/Resources/TR2/Environment/ICECAVE.TR2-Environment.json diff --git a/TR2RandomizerCore/Resources/Environment/KEEL.TR2-Environment.json b/TRRandomizerCore/Resources/TR2/Environment/KEEL.TR2-Environment.json similarity index 100% rename from TR2RandomizerCore/Resources/Environment/KEEL.TR2-Environment.json rename to TRRandomizerCore/Resources/TR2/Environment/KEEL.TR2-Environment.json diff --git a/TR2RandomizerCore/Resources/Environment/LIVING.TR2-Environment.json b/TRRandomizerCore/Resources/TR2/Environment/LIVING.TR2-Environment.json similarity index 100% rename from TR2RandomizerCore/Resources/Environment/LIVING.TR2-Environment.json rename to TRRandomizerCore/Resources/TR2/Environment/LIVING.TR2-Environment.json diff --git a/TR2RandomizerCore/Resources/Environment/MONASTRY.TR2-Environment.json b/TRRandomizerCore/Resources/TR2/Environment/MONASTRY.TR2-Environment.json similarity index 100% rename from TR2RandomizerCore/Resources/Environment/MONASTRY.TR2-Environment.json rename to TRRandomizerCore/Resources/TR2/Environment/MONASTRY.TR2-Environment.json diff --git a/TR2RandomizerCore/Resources/Environment/OPERA.TR2-Environment.json b/TRRandomizerCore/Resources/TR2/Environment/OPERA.TR2-Environment.json similarity index 100% rename from TR2RandomizerCore/Resources/Environment/OPERA.TR2-Environment.json rename to TRRandomizerCore/Resources/TR2/Environment/OPERA.TR2-Environment.json diff --git a/TR2RandomizerCore/Resources/Environment/PLATFORM.TR2-Environment.json b/TRRandomizerCore/Resources/TR2/Environment/PLATFORM.TR2-Environment.json similarity index 100% rename from TR2RandomizerCore/Resources/Environment/PLATFORM.TR2-Environment.json rename to TRRandomizerCore/Resources/TR2/Environment/PLATFORM.TR2-Environment.json diff --git a/TR2RandomizerCore/Resources/Environment/RIG.TR2-Environment.json b/TRRandomizerCore/Resources/TR2/Environment/RIG.TR2-Environment.json similarity index 100% rename from TR2RandomizerCore/Resources/Environment/RIG.TR2-Environment.json rename to TRRandomizerCore/Resources/TR2/Environment/RIG.TR2-Environment.json diff --git a/TR2RandomizerCore/Resources/Environment/SKIDOO.TR2-Environment.json b/TRRandomizerCore/Resources/TR2/Environment/SKIDOO.TR2-Environment.json similarity index 100% rename from TR2RandomizerCore/Resources/Environment/SKIDOO.TR2-Environment.json rename to TRRandomizerCore/Resources/TR2/Environment/SKIDOO.TR2-Environment.json diff --git a/TR2RandomizerCore/Resources/Environment/UNWATER.TR2-Environment.json b/TRRandomizerCore/Resources/TR2/Environment/UNWATER.TR2-Environment.json similarity index 100% rename from TR2RandomizerCore/Resources/Environment/UNWATER.TR2-Environment.json rename to TRRandomizerCore/Resources/TR2/Environment/UNWATER.TR2-Environment.json diff --git a/TR2RandomizerCore/Resources/Environment/VENICE.TR2-Environment.json b/TRRandomizerCore/Resources/TR2/Environment/VENICE.TR2-Environment.json similarity index 100% rename from TR2RandomizerCore/Resources/Environment/VENICE.TR2-Environment.json rename to TRRandomizerCore/Resources/TR2/Environment/VENICE.TR2-Environment.json diff --git a/TR2RandomizerCore/Resources/Environment/WALL.TR2-Environment.json b/TRRandomizerCore/Resources/TR2/Environment/WALL.TR2-Environment.json similarity index 100% rename from TR2RandomizerCore/Resources/Environment/WALL.TR2-Environment.json rename to TRRandomizerCore/Resources/TR2/Environment/WALL.TR2-Environment.json diff --git a/TR2RandomizerCore/Resources/Environment/XIAN.TR2-Environment.json b/TRRandomizerCore/Resources/TR2/Environment/XIAN.TR2-Environment.json similarity index 100% rename from TR2RandomizerCore/Resources/Environment/XIAN.TR2-Environment.json rename to TRRandomizerCore/Resources/TR2/Environment/XIAN.TR2-Environment.json diff --git a/TR2RandomizerCore/Resources/item_locations.json b/TRRandomizerCore/Resources/TR2/Locations/item_locations.json similarity index 100% rename from TR2RandomizerCore/Resources/item_locations.json rename to TRRandomizerCore/Resources/TR2/Locations/item_locations.json diff --git a/TR2RandomizerCore/Resources/locations.json b/TRRandomizerCore/Resources/TR2/Locations/locations.json similarity index 100% rename from TR2RandomizerCore/Resources/locations.json rename to TRRandomizerCore/Resources/TR2/Locations/locations.json diff --git a/TR2RandomizerCore/Resources/start_positions.json b/TRRandomizerCore/Resources/TR2/Locations/start_positions.json similarity index 100% rename from TR2RandomizerCore/Resources/start_positions.json rename to TRRandomizerCore/Resources/TR2/Locations/start_positions.json diff --git a/TR2RandomizerCore/Resources/unarmed_locations.json b/TRRandomizerCore/Resources/TR2/Locations/unarmed_locations.json similarity index 100% rename from TR2RandomizerCore/Resources/unarmed_locations.json rename to TRRandomizerCore/Resources/TR2/Locations/unarmed_locations.json diff --git a/TR2RandomizerCore/Resources/vehicle_locations.json b/TRRandomizerCore/Resources/TR2/Locations/vehicle_locations.json similarity index 100% rename from TR2RandomizerCore/Resources/vehicle_locations.json rename to TRRandomizerCore/Resources/TR2/Locations/vehicle_locations.json diff --git a/TR2RandomizerCore/Resources/Models/BarracudaIce/Data.json b/TRRandomizerCore/Resources/TR2/Models/BarracudaIce/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/BarracudaIce/Data.json rename to TRRandomizerCore/Resources/TR2/Models/BarracudaIce/Data.json diff --git a/TR2RandomizerCore/Resources/Models/BarracudaIce/Segments.png b/TRRandomizerCore/Resources/TR2/Models/BarracudaIce/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/BarracudaIce/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/BarracudaIce/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/BarracudaUnwater/Data.json b/TRRandomizerCore/Resources/TR2/Models/BarracudaUnwater/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/BarracudaUnwater/Data.json rename to TRRandomizerCore/Resources/TR2/Models/BarracudaUnwater/Data.json diff --git a/TR2RandomizerCore/Resources/Models/BarracudaUnwater/Segments.png b/TRRandomizerCore/Resources/TR2/Models/BarracudaUnwater/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/BarracudaUnwater/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/BarracudaUnwater/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/BarracudaXian/Data.json b/TRRandomizerCore/Resources/TR2/Models/BarracudaXian/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/BarracudaXian/Data.json rename to TRRandomizerCore/Resources/TR2/Models/BarracudaXian/Data.json diff --git a/TR2RandomizerCore/Resources/Models/BarracudaXian/Segments.png b/TRRandomizerCore/Resources/TR2/Models/BarracudaXian/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/BarracudaXian/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/BarracudaXian/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/BengalTiger/Data.json b/TRRandomizerCore/Resources/TR2/Models/BengalTiger/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/BengalTiger/Data.json rename to TRRandomizerCore/Resources/TR2/Models/BengalTiger/Data.json diff --git a/TR2RandomizerCore/Resources/Models/BengalTiger/Segments.png b/TRRandomizerCore/Resources/TR2/Models/BengalTiger/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/BengalTiger/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/BengalTiger/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/BirdMonster/Data.json b/TRRandomizerCore/Resources/TR2/Models/BirdMonster/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/BirdMonster/Data.json rename to TRRandomizerCore/Resources/TR2/Models/BirdMonster/Data.json diff --git a/TR2RandomizerCore/Resources/Models/BirdMonster/Segments.png b/TRRandomizerCore/Resources/TR2/Models/BirdMonster/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/BirdMonster/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/BirdMonster/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/BlackMorayEel/Data.json b/TRRandomizerCore/Resources/TR2/Models/BlackMorayEel/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/BlackMorayEel/Data.json rename to TRRandomizerCore/Resources/TR2/Models/BlackMorayEel/Data.json diff --git a/TR2RandomizerCore/Resources/Models/BlackMorayEel/Segments.png b/TRRandomizerCore/Resources/TR2/Models/BlackMorayEel/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/BlackMorayEel/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/BlackMorayEel/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/BlackSnowmob/Data.json b/TRRandomizerCore/Resources/TR2/Models/BlackSnowmob/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/BlackSnowmob/Data.json rename to TRRandomizerCore/Resources/TR2/Models/BlackSnowmob/Data.json diff --git a/TR2RandomizerCore/Resources/Models/BlackSnowmob/Segments.png b/TRRandomizerCore/Resources/TR2/Models/BlackSnowmob/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/BlackSnowmob/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/BlackSnowmob/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/Boat/Data.json b/TRRandomizerCore/Resources/TR2/Models/Boat/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/Boat/Data.json rename to TRRandomizerCore/Resources/TR2/Models/Boat/Data.json diff --git a/TR2RandomizerCore/Resources/Models/Boat/Segments.png b/TRRandomizerCore/Resources/TR2/Models/Boat/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/Boat/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/Boat/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/Crow/Data.json b/TRRandomizerCore/Resources/TR2/Models/Crow/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/Crow/Data.json rename to TRRandomizerCore/Resources/TR2/Models/Crow/Data.json diff --git a/TR2RandomizerCore/Resources/Models/Crow/Segments.png b/TRRandomizerCore/Resources/TR2/Models/Crow/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/Crow/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/Crow/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/Doberman/Data.json b/TRRandomizerCore/Resources/TR2/Models/Doberman/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/Doberman/Data.json rename to TRRandomizerCore/Resources/TR2/Models/Doberman/Data.json diff --git a/TR2RandomizerCore/Resources/Models/Doberman/Segments.png b/TRRandomizerCore/Resources/TR2/Models/Doberman/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/Doberman/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/Doberman/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/DragonBack_H/Data.json b/TRRandomizerCore/Resources/TR2/Models/DragonBack_H/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/DragonBack_H/Data.json rename to TRRandomizerCore/Resources/TR2/Models/DragonBack_H/Data.json diff --git a/TR2RandomizerCore/Resources/Models/DragonBack_H/Segments.png b/TRRandomizerCore/Resources/TR2/Models/DragonBack_H/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/DragonBack_H/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/DragonBack_H/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/DragonBonesBack_H/Data.json b/TRRandomizerCore/Resources/TR2/Models/DragonBonesBack_H/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/DragonBonesBack_H/Data.json rename to TRRandomizerCore/Resources/TR2/Models/DragonBonesBack_H/Data.json diff --git a/TR2RandomizerCore/Resources/Models/DragonBonesBack_H/Segments.png b/TRRandomizerCore/Resources/TR2/Models/DragonBonesBack_H/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/DragonBonesBack_H/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/DragonBonesBack_H/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/DragonBonesFront_H/Data.json b/TRRandomizerCore/Resources/TR2/Models/DragonBonesFront_H/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/DragonBonesFront_H/Data.json rename to TRRandomizerCore/Resources/TR2/Models/DragonBonesFront_H/Data.json diff --git a/TR2RandomizerCore/Resources/Models/DragonBonesFront_H/Segments.png b/TRRandomizerCore/Resources/TR2/Models/DragonBonesFront_H/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/DragonBonesFront_H/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/DragonBonesFront_H/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/DragonExplosion1_H/Data.json b/TRRandomizerCore/Resources/TR2/Models/DragonExplosion1_H/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/DragonExplosion1_H/Data.json rename to TRRandomizerCore/Resources/TR2/Models/DragonExplosion1_H/Data.json diff --git a/TR2RandomizerCore/Resources/Models/DragonExplosion1_H/Segments.png b/TRRandomizerCore/Resources/TR2/Models/DragonExplosion1_H/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/DragonExplosion1_H/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/DragonExplosion1_H/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/DragonExplosion2_H/Data.json b/TRRandomizerCore/Resources/TR2/Models/DragonExplosion2_H/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/DragonExplosion2_H/Data.json rename to TRRandomizerCore/Resources/TR2/Models/DragonExplosion2_H/Data.json diff --git a/TR2RandomizerCore/Resources/Models/DragonExplosion2_H/Segments.png b/TRRandomizerCore/Resources/TR2/Models/DragonExplosion2_H/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/DragonExplosion2_H/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/DragonExplosion2_H/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/DragonExplosion3_H/Data.json b/TRRandomizerCore/Resources/TR2/Models/DragonExplosion3_H/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/DragonExplosion3_H/Data.json rename to TRRandomizerCore/Resources/TR2/Models/DragonExplosion3_H/Data.json diff --git a/TR2RandomizerCore/Resources/Models/DragonExplosion3_H/Segments.png b/TRRandomizerCore/Resources/TR2/Models/DragonExplosion3_H/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/DragonExplosion3_H/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/DragonExplosion3_H/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/DragonExplosionEmitter_N/Data.json b/TRRandomizerCore/Resources/TR2/Models/DragonExplosionEmitter_N/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/DragonExplosionEmitter_N/Data.json rename to TRRandomizerCore/Resources/TR2/Models/DragonExplosionEmitter_N/Data.json diff --git a/TR2RandomizerCore/Resources/Models/DragonFront_H/Data.json b/TRRandomizerCore/Resources/TR2/Models/DragonFront_H/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/DragonFront_H/Data.json rename to TRRandomizerCore/Resources/TR2/Models/DragonFront_H/Data.json diff --git a/TR2RandomizerCore/Resources/Models/DragonFront_H/Segments.png b/TRRandomizerCore/Resources/TR2/Models/DragonFront_H/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/DragonFront_H/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/DragonFront_H/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/Eagle/Data.json b/TRRandomizerCore/Resources/TR2/Models/Eagle/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/Eagle/Data.json rename to TRRandomizerCore/Resources/TR2/Models/Eagle/Data.json diff --git a/TR2RandomizerCore/Resources/Models/Eagle/Segments.png b/TRRandomizerCore/Resources/TR2/Models/Eagle/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/Eagle/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/Eagle/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/FlamethrowerGoon/Data.json b/TRRandomizerCore/Resources/TR2/Models/FlamethrowerGoon/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/FlamethrowerGoon/Data.json rename to TRRandomizerCore/Resources/TR2/Models/FlamethrowerGoon/Data.json diff --git a/TR2RandomizerCore/Resources/Models/FlamethrowerGoon/Segments.png b/TRRandomizerCore/Resources/TR2/Models/FlamethrowerGoon/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/FlamethrowerGoon/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/FlamethrowerGoon/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/GiantSpider/Data.json b/TRRandomizerCore/Resources/TR2/Models/GiantSpider/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/GiantSpider/Data.json rename to TRRandomizerCore/Resources/TR2/Models/GiantSpider/Data.json diff --git a/TR2RandomizerCore/Resources/Models/GiantSpider/Segments.png b/TRRandomizerCore/Resources/TR2/Models/GiantSpider/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/GiantSpider/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/GiantSpider/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/Gunman1/Data.json b/TRRandomizerCore/Resources/TR2/Models/Gunman1/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/Gunman1/Data.json rename to TRRandomizerCore/Resources/TR2/Models/Gunman1/Data.json diff --git a/TR2RandomizerCore/Resources/Models/Gunman1/Segments.png b/TRRandomizerCore/Resources/TR2/Models/Gunman1/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/Gunman1/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/Gunman1/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/Gunman2/Data.json b/TRRandomizerCore/Resources/TR2/Models/Gunman2/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/Gunman2/Data.json rename to TRRandomizerCore/Resources/TR2/Models/Gunman2/Data.json diff --git a/TR2RandomizerCore/Resources/Models/Gunman2/Segments.png b/TRRandomizerCore/Resources/TR2/Models/Gunman2/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/Gunman2/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/Gunman2/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/KnifeProjectile_H/Data.json b/TRRandomizerCore/Resources/TR2/Models/KnifeProjectile_H/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/KnifeProjectile_H/Data.json rename to TRRandomizerCore/Resources/TR2/Models/KnifeProjectile_H/Data.json diff --git a/TR2RandomizerCore/Resources/Models/KnifeProjectile_H/Segments.png b/TRRandomizerCore/Resources/TR2/Models/KnifeProjectile_H/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/KnifeProjectile_H/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/KnifeProjectile_H/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/Knifethrower/Data.json b/TRRandomizerCore/Resources/TR2/Models/Knifethrower/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/Knifethrower/Data.json rename to TRRandomizerCore/Resources/TR2/Models/Knifethrower/Data.json diff --git a/TR2RandomizerCore/Resources/Models/Knifethrower/Segments.png b/TRRandomizerCore/Resources/TR2/Models/Knifethrower/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/Knifethrower/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/Knifethrower/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/LaraAutoAnim_H_Home/Data.json b/TRRandomizerCore/Resources/TR2/Models/LaraAutoAnim_H_Home/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/LaraAutoAnim_H_Home/Data.json rename to TRRandomizerCore/Resources/TR2/Models/LaraAutoAnim_H_Home/Data.json diff --git a/TR2RandomizerCore/Resources/Models/LaraAutoAnim_H_Home/Segments.png b/TRRandomizerCore/Resources/TR2/Models/LaraAutoAnim_H_Home/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/LaraAutoAnim_H_Home/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/LaraAutoAnim_H_Home/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/LaraAutoAnim_H_Snow/Data.json b/TRRandomizerCore/Resources/TR2/Models/LaraAutoAnim_H_Snow/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/LaraAutoAnim_H_Snow/Data.json rename to TRRandomizerCore/Resources/TR2/Models/LaraAutoAnim_H_Snow/Data.json diff --git a/TR2RandomizerCore/Resources/Models/LaraAutoAnim_H_Snow/Segments.png b/TRRandomizerCore/Resources/TR2/Models/LaraAutoAnim_H_Snow/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/LaraAutoAnim_H_Snow/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/LaraAutoAnim_H_Snow/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/LaraAutoAnim_H_Sun/Data.json b/TRRandomizerCore/Resources/TR2/Models/LaraAutoAnim_H_Sun/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/LaraAutoAnim_H_Sun/Data.json rename to TRRandomizerCore/Resources/TR2/Models/LaraAutoAnim_H_Sun/Data.json diff --git a/TR2RandomizerCore/Resources/Models/LaraAutoAnim_H_Sun/Segments.png b/TRRandomizerCore/Resources/TR2/Models/LaraAutoAnim_H_Sun/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/LaraAutoAnim_H_Sun/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/LaraAutoAnim_H_Sun/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/LaraAutoAnim_H_Unwater/Data.json b/TRRandomizerCore/Resources/TR2/Models/LaraAutoAnim_H_Unwater/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/LaraAutoAnim_H_Unwater/Data.json rename to TRRandomizerCore/Resources/TR2/Models/LaraAutoAnim_H_Unwater/Data.json diff --git a/TR2RandomizerCore/Resources/Models/LaraAutoAnim_H_Unwater/Segments.png b/TRRandomizerCore/Resources/TR2/Models/LaraAutoAnim_H_Unwater/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/LaraAutoAnim_H_Unwater/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/LaraAutoAnim_H_Unwater/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/LaraBoatAnim_H/Data.json b/TRRandomizerCore/Resources/TR2/Models/LaraBoatAnim_H/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/LaraBoatAnim_H/Data.json rename to TRRandomizerCore/Resources/TR2/Models/LaraBoatAnim_H/Data.json diff --git a/TR2RandomizerCore/Resources/Models/LaraHome/Data.json b/TRRandomizerCore/Resources/TR2/Models/LaraHome/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/LaraHome/Data.json rename to TRRandomizerCore/Resources/TR2/Models/LaraHome/Data.json diff --git a/TR2RandomizerCore/Resources/Models/LaraHome/Segments.png b/TRRandomizerCore/Resources/TR2/Models/LaraHome/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/LaraHome/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/LaraHome/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/LaraMiscAnim_H_Ice/Data.json b/TRRandomizerCore/Resources/TR2/Models/LaraMiscAnim_H_Ice/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/LaraMiscAnim_H_Ice/Data.json rename to TRRandomizerCore/Resources/TR2/Models/LaraMiscAnim_H_Ice/Data.json diff --git a/TR2RandomizerCore/Resources/Models/LaraMiscAnim_H_Unwater/Data.json b/TRRandomizerCore/Resources/TR2/Models/LaraMiscAnim_H_Unwater/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/LaraMiscAnim_H_Unwater/Data.json rename to TRRandomizerCore/Resources/TR2/Models/LaraMiscAnim_H_Unwater/Data.json diff --git a/TR2RandomizerCore/Resources/Models/LaraMiscAnim_H_Wall/Data.json b/TRRandomizerCore/Resources/TR2/Models/LaraMiscAnim_H_Wall/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/LaraMiscAnim_H_Wall/Data.json rename to TRRandomizerCore/Resources/TR2/Models/LaraMiscAnim_H_Wall/Data.json diff --git a/TR2RandomizerCore/Resources/Models/LaraMiscAnim_H_Xian/Data.json b/TRRandomizerCore/Resources/TR2/Models/LaraMiscAnim_H_Xian/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/LaraMiscAnim_H_Xian/Data.json rename to TRRandomizerCore/Resources/TR2/Models/LaraMiscAnim_H_Xian/Data.json diff --git a/TR2RandomizerCore/Resources/Models/LaraMiscAnim_H_Xian/Segments.png b/TRRandomizerCore/Resources/TR2/Models/LaraMiscAnim_H_Xian/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/LaraMiscAnim_H_Xian/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/LaraMiscAnim_H_Xian/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/LaraPistolAnim_H_Home/Data.json b/TRRandomizerCore/Resources/TR2/Models/LaraPistolAnim_H_Home/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/LaraPistolAnim_H_Home/Data.json rename to TRRandomizerCore/Resources/TR2/Models/LaraPistolAnim_H_Home/Data.json diff --git a/TR2RandomizerCore/Resources/Models/LaraPistolAnim_H_Home/Segments.png b/TRRandomizerCore/Resources/TR2/Models/LaraPistolAnim_H_Home/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/LaraPistolAnim_H_Home/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/LaraPistolAnim_H_Home/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/LaraPistolAnim_H_Snow/Data.json b/TRRandomizerCore/Resources/TR2/Models/LaraPistolAnim_H_Snow/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/LaraPistolAnim_H_Snow/Data.json rename to TRRandomizerCore/Resources/TR2/Models/LaraPistolAnim_H_Snow/Data.json diff --git a/TR2RandomizerCore/Resources/Models/LaraPistolAnim_H_Snow/Segments.png b/TRRandomizerCore/Resources/TR2/Models/LaraPistolAnim_H_Snow/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/LaraPistolAnim_H_Snow/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/LaraPistolAnim_H_Snow/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/LaraPistolAnim_H_Sun/Data.json b/TRRandomizerCore/Resources/TR2/Models/LaraPistolAnim_H_Sun/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/LaraPistolAnim_H_Sun/Data.json rename to TRRandomizerCore/Resources/TR2/Models/LaraPistolAnim_H_Sun/Data.json diff --git a/TR2RandomizerCore/Resources/Models/LaraPistolAnim_H_Sun/Segments.png b/TRRandomizerCore/Resources/TR2/Models/LaraPistolAnim_H_Sun/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/LaraPistolAnim_H_Sun/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/LaraPistolAnim_H_Sun/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/LaraPistolAnim_H_Unwater/Data.json b/TRRandomizerCore/Resources/TR2/Models/LaraPistolAnim_H_Unwater/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/LaraPistolAnim_H_Unwater/Data.json rename to TRRandomizerCore/Resources/TR2/Models/LaraPistolAnim_H_Unwater/Data.json diff --git a/TR2RandomizerCore/Resources/Models/LaraPistolAnim_H_Unwater/Segments.png b/TRRandomizerCore/Resources/TR2/Models/LaraPistolAnim_H_Unwater/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/LaraPistolAnim_H_Unwater/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/LaraPistolAnim_H_Unwater/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/LaraSnow/Data.json b/TRRandomizerCore/Resources/TR2/Models/LaraSnow/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/LaraSnow/Data.json rename to TRRandomizerCore/Resources/TR2/Models/LaraSnow/Data.json diff --git a/TR2RandomizerCore/Resources/Models/LaraSnow/Segments.png b/TRRandomizerCore/Resources/TR2/Models/LaraSnow/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/LaraSnow/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/LaraSnow/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/LaraSnowmobAnim_H/Data.json b/TRRandomizerCore/Resources/TR2/Models/LaraSnowmobAnim_H/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/LaraSnowmobAnim_H/Data.json rename to TRRandomizerCore/Resources/TR2/Models/LaraSnowmobAnim_H/Data.json diff --git a/TR2RandomizerCore/Resources/Models/LaraSun/Data.json b/TRRandomizerCore/Resources/TR2/Models/LaraSun/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/LaraSun/Data.json rename to TRRandomizerCore/Resources/TR2/Models/LaraSun/Data.json diff --git a/TR2RandomizerCore/Resources/Models/LaraSun/Segments.png b/TRRandomizerCore/Resources/TR2/Models/LaraSun/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/LaraSun/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/LaraSun/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/LaraUnwater/Data.json b/TRRandomizerCore/Resources/TR2/Models/LaraUnwater/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/LaraUnwater/Data.json rename to TRRandomizerCore/Resources/TR2/Models/LaraUnwater/Data.json diff --git a/TR2RandomizerCore/Resources/Models/LaraUnwater/Segments.png b/TRRandomizerCore/Resources/TR2/Models/LaraUnwater/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/LaraUnwater/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/LaraUnwater/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/LaraUziAnim_H_Home/Data.json b/TRRandomizerCore/Resources/TR2/Models/LaraUziAnim_H_Home/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/LaraUziAnim_H_Home/Data.json rename to TRRandomizerCore/Resources/TR2/Models/LaraUziAnim_H_Home/Data.json diff --git a/TR2RandomizerCore/Resources/Models/LaraUziAnim_H_Home/Segments.png b/TRRandomizerCore/Resources/TR2/Models/LaraUziAnim_H_Home/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/LaraUziAnim_H_Home/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/LaraUziAnim_H_Home/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/LaraUziAnim_H_Snow/Data.json b/TRRandomizerCore/Resources/TR2/Models/LaraUziAnim_H_Snow/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/LaraUziAnim_H_Snow/Data.json rename to TRRandomizerCore/Resources/TR2/Models/LaraUziAnim_H_Snow/Data.json diff --git a/TR2RandomizerCore/Resources/Models/LaraUziAnim_H_Snow/Segments.png b/TRRandomizerCore/Resources/TR2/Models/LaraUziAnim_H_Snow/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/LaraUziAnim_H_Snow/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/LaraUziAnim_H_Snow/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/LaraUziAnim_H_Sun/Data.json b/TRRandomizerCore/Resources/TR2/Models/LaraUziAnim_H_Sun/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/LaraUziAnim_H_Sun/Data.json rename to TRRandomizerCore/Resources/TR2/Models/LaraUziAnim_H_Sun/Data.json diff --git a/TR2RandomizerCore/Resources/Models/LaraUziAnim_H_Sun/Segments.png b/TRRandomizerCore/Resources/TR2/Models/LaraUziAnim_H_Sun/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/LaraUziAnim_H_Sun/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/LaraUziAnim_H_Sun/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/LaraUziAnim_H_Unwater/Data.json b/TRRandomizerCore/Resources/TR2/Models/LaraUziAnim_H_Unwater/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/LaraUziAnim_H_Unwater/Data.json rename to TRRandomizerCore/Resources/TR2/Models/LaraUziAnim_H_Unwater/Data.json diff --git a/TR2RandomizerCore/Resources/Models/LaraUziAnim_H_Unwater/Segments.png b/TRRandomizerCore/Resources/TR2/Models/LaraUziAnim_H_Unwater/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/LaraUziAnim_H_Unwater/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/LaraUziAnim_H_Unwater/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/MarcoBartoli/Data.json b/TRRandomizerCore/Resources/TR2/Models/MarcoBartoli/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/MarcoBartoli/Data.json rename to TRRandomizerCore/Resources/TR2/Models/MarcoBartoli/Data.json diff --git a/TR2RandomizerCore/Resources/Models/MarcoBartoli/Segments.png b/TRRandomizerCore/Resources/TR2/Models/MarcoBartoli/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/MarcoBartoli/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/MarcoBartoli/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/MaskedGoon1/Data.json b/TRRandomizerCore/Resources/TR2/Models/MaskedGoon1/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/MaskedGoon1/Data.json rename to TRRandomizerCore/Resources/TR2/Models/MaskedGoon1/Data.json diff --git a/TR2RandomizerCore/Resources/Models/MaskedGoon1/Segments.png b/TRRandomizerCore/Resources/TR2/Models/MaskedGoon1/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/MaskedGoon1/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/MaskedGoon1/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/MaskedGoon2/Data.json b/TRRandomizerCore/Resources/TR2/Models/MaskedGoon2/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/MaskedGoon2/Data.json rename to TRRandomizerCore/Resources/TR2/Models/MaskedGoon2/Data.json diff --git a/TR2RandomizerCore/Resources/Models/MaskedGoon2/Segments.png b/TRRandomizerCore/Resources/TR2/Models/MaskedGoon2/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/MaskedGoon2/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/MaskedGoon2/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/MaskedGoon3/Data.json b/TRRandomizerCore/Resources/TR2/Models/MaskedGoon3/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/MaskedGoon3/Data.json rename to TRRandomizerCore/Resources/TR2/Models/MaskedGoon3/Data.json diff --git a/TR2RandomizerCore/Resources/Models/MaskedGoon3/Segments.png b/TRRandomizerCore/Resources/TR2/Models/MaskedGoon3/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/MaskedGoon3/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/MaskedGoon3/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/MercSnowmobDriver/Data.json b/TRRandomizerCore/Resources/TR2/Models/MercSnowmobDriver/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/MercSnowmobDriver/Data.json rename to TRRandomizerCore/Resources/TR2/Models/MercSnowmobDriver/Data.json diff --git a/TR2RandomizerCore/Resources/Models/MercSnowmobDriver/Segments.png b/TRRandomizerCore/Resources/TR2/Models/MercSnowmobDriver/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/MercSnowmobDriver/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/MercSnowmobDriver/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/Mercenary1/Data.json b/TRRandomizerCore/Resources/TR2/Models/Mercenary1/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/Mercenary1/Data.json rename to TRRandomizerCore/Resources/TR2/Models/Mercenary1/Data.json diff --git a/TR2RandomizerCore/Resources/Models/Mercenary1/Segments.png b/TRRandomizerCore/Resources/TR2/Models/Mercenary1/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/Mercenary1/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/Mercenary1/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/Mercenary2/Data.json b/TRRandomizerCore/Resources/TR2/Models/Mercenary2/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/Mercenary2/Data.json rename to TRRandomizerCore/Resources/TR2/Models/Mercenary2/Data.json diff --git a/TR2RandomizerCore/Resources/Models/Mercenary2/Segments.png b/TRRandomizerCore/Resources/TR2/Models/Mercenary2/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/Mercenary2/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/Mercenary2/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/Mercenary3/Data.json b/TRRandomizerCore/Resources/TR2/Models/Mercenary3/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/Mercenary3/Data.json rename to TRRandomizerCore/Resources/TR2/Models/Mercenary3/Data.json diff --git a/TR2RandomizerCore/Resources/Models/Mercenary3/Segments.png b/TRRandomizerCore/Resources/TR2/Models/Mercenary3/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/Mercenary3/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/Mercenary3/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/MonkWithKnifeStick/Data.json b/TRRandomizerCore/Resources/TR2/Models/MonkWithKnifeStick/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/MonkWithKnifeStick/Data.json rename to TRRandomizerCore/Resources/TR2/Models/MonkWithKnifeStick/Data.json diff --git a/TR2RandomizerCore/Resources/Models/MonkWithKnifeStick/Segments.png b/TRRandomizerCore/Resources/TR2/Models/MonkWithKnifeStick/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/MonkWithKnifeStick/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/MonkWithKnifeStick/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/MonkWithLongStick/Data.json b/TRRandomizerCore/Resources/TR2/Models/MonkWithLongStick/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/MonkWithLongStick/Data.json rename to TRRandomizerCore/Resources/TR2/Models/MonkWithLongStick/Data.json diff --git a/TR2RandomizerCore/Resources/Models/MonkWithLongStick/Segments.png b/TRRandomizerCore/Resources/TR2/Models/MonkWithLongStick/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/MonkWithLongStick/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/MonkWithLongStick/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/Puzzle2_M_H_Dagger/Data.json b/TRRandomizerCore/Resources/TR2/Models/Puzzle2_M_H_Dagger/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/Puzzle2_M_H_Dagger/Data.json rename to TRRandomizerCore/Resources/TR2/Models/Puzzle2_M_H_Dagger/Data.json diff --git a/TR2RandomizerCore/Resources/Models/Puzzle2_M_H_Dagger/Segments.png b/TRRandomizerCore/Resources/TR2/Models/Puzzle2_M_H_Dagger/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/Puzzle2_M_H_Dagger/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/Puzzle2_M_H_Dagger/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/Rat/Data.json b/TRRandomizerCore/Resources/TR2/Models/Rat/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/Rat/Data.json rename to TRRandomizerCore/Resources/TR2/Models/Rat/Data.json diff --git a/TR2RandomizerCore/Resources/Models/Rat/Segments.png b/TRRandomizerCore/Resources/TR2/Models/Rat/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/Rat/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/Rat/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/RedSnowmobile/Data.json b/TRRandomizerCore/Resources/TR2/Models/RedSnowmobile/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/RedSnowmobile/Data.json rename to TRRandomizerCore/Resources/TR2/Models/RedSnowmobile/Data.json diff --git a/TR2RandomizerCore/Resources/Models/RedSnowmobile/Segments.png b/TRRandomizerCore/Resources/TR2/Models/RedSnowmobile/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/RedSnowmobile/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/RedSnowmobile/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/ScubaDiver/Data.json b/TRRandomizerCore/Resources/TR2/Models/ScubaDiver/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/ScubaDiver/Data.json rename to TRRandomizerCore/Resources/TR2/Models/ScubaDiver/Data.json diff --git a/TR2RandomizerCore/Resources/Models/ScubaDiver/Segments.png b/TRRandomizerCore/Resources/TR2/Models/ScubaDiver/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/ScubaDiver/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/ScubaDiver/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/ScubaHarpoonProjectile_H/Data.json b/TRRandomizerCore/Resources/TR2/Models/ScubaHarpoonProjectile_H/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/ScubaHarpoonProjectile_H/Data.json rename to TRRandomizerCore/Resources/TR2/Models/ScubaHarpoonProjectile_H/Data.json diff --git a/TR2RandomizerCore/Resources/Models/ScubaHarpoonProjectile_H/Segments.png b/TRRandomizerCore/Resources/TR2/Models/ScubaHarpoonProjectile_H/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/ScubaHarpoonProjectile_H/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/ScubaHarpoonProjectile_H/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/Shark/Data.json b/TRRandomizerCore/Resources/TR2/Models/Shark/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/Shark/Data.json rename to TRRandomizerCore/Resources/TR2/Models/Shark/Data.json diff --git a/TR2RandomizerCore/Resources/Models/Shark/Segments.png b/TRRandomizerCore/Resources/TR2/Models/Shark/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/Shark/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/Shark/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/ShotgunGoon/Data.json b/TRRandomizerCore/Resources/TR2/Models/ShotgunGoon/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/ShotgunGoon/Data.json rename to TRRandomizerCore/Resources/TR2/Models/ShotgunGoon/Data.json diff --git a/TR2RandomizerCore/Resources/Models/ShotgunGoon/Segments.png b/TRRandomizerCore/Resources/TR2/Models/ShotgunGoon/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/ShotgunGoon/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/ShotgunGoon/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/SnowLeopard/Data.json b/TRRandomizerCore/Resources/TR2/Models/SnowLeopard/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/SnowLeopard/Data.json rename to TRRandomizerCore/Resources/TR2/Models/SnowLeopard/Data.json diff --git a/TR2RandomizerCore/Resources/Models/SnowLeopard/Segments.png b/TRRandomizerCore/Resources/TR2/Models/SnowLeopard/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/SnowLeopard/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/SnowLeopard/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/SnowmobileBelt/Data.json b/TRRandomizerCore/Resources/TR2/Models/SnowmobileBelt/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/SnowmobileBelt/Data.json rename to TRRandomizerCore/Resources/TR2/Models/SnowmobileBelt/Data.json diff --git a/TR2RandomizerCore/Resources/Models/SnowmobileBelt/Segments.png b/TRRandomizerCore/Resources/TR2/Models/SnowmobileBelt/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/SnowmobileBelt/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/SnowmobileBelt/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/Spider/Data.json b/TRRandomizerCore/Resources/TR2/Models/Spider/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/Spider/Data.json rename to TRRandomizerCore/Resources/TR2/Models/Spider/Data.json diff --git a/TR2RandomizerCore/Resources/Models/Spider/Segments.png b/TRRandomizerCore/Resources/TR2/Models/Spider/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/Spider/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/Spider/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/StickWieldingGoon1Bandana/Data.json b/TRRandomizerCore/Resources/TR2/Models/StickWieldingGoon1Bandana/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/StickWieldingGoon1Bandana/Data.json rename to TRRandomizerCore/Resources/TR2/Models/StickWieldingGoon1Bandana/Data.json diff --git a/TR2RandomizerCore/Resources/Models/StickWieldingGoon1Bandana/Segments.png b/TRRandomizerCore/Resources/TR2/Models/StickWieldingGoon1Bandana/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/StickWieldingGoon1Bandana/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/StickWieldingGoon1Bandana/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/StickWieldingGoon1BlackJacket/Data.json b/TRRandomizerCore/Resources/TR2/Models/StickWieldingGoon1BlackJacket/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/StickWieldingGoon1BlackJacket/Data.json rename to TRRandomizerCore/Resources/TR2/Models/StickWieldingGoon1BlackJacket/Data.json diff --git a/TR2RandomizerCore/Resources/Models/StickWieldingGoon1BlackJacket/Segments.png b/TRRandomizerCore/Resources/TR2/Models/StickWieldingGoon1BlackJacket/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/StickWieldingGoon1BlackJacket/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/StickWieldingGoon1BlackJacket/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/StickWieldingGoon1BodyWarmer/Data.json b/TRRandomizerCore/Resources/TR2/Models/StickWieldingGoon1BodyWarmer/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/StickWieldingGoon1BodyWarmer/Data.json rename to TRRandomizerCore/Resources/TR2/Models/StickWieldingGoon1BodyWarmer/Data.json diff --git a/TR2RandomizerCore/Resources/Models/StickWieldingGoon1BodyWarmer/Segments.png b/TRRandomizerCore/Resources/TR2/Models/StickWieldingGoon1BodyWarmer/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/StickWieldingGoon1BodyWarmer/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/StickWieldingGoon1BodyWarmer/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/StickWieldingGoon1GreenVest/Data.json b/TRRandomizerCore/Resources/TR2/Models/StickWieldingGoon1GreenVest/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/StickWieldingGoon1GreenVest/Data.json rename to TRRandomizerCore/Resources/TR2/Models/StickWieldingGoon1GreenVest/Data.json diff --git a/TR2RandomizerCore/Resources/Models/StickWieldingGoon1GreenVest/Segments.png b/TRRandomizerCore/Resources/TR2/Models/StickWieldingGoon1GreenVest/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/StickWieldingGoon1GreenVest/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/StickWieldingGoon1GreenVest/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/StickWieldingGoon1WhiteVest/Data.json b/TRRandomizerCore/Resources/TR2/Models/StickWieldingGoon1WhiteVest/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/StickWieldingGoon1WhiteVest/Data.json rename to TRRandomizerCore/Resources/TR2/Models/StickWieldingGoon1WhiteVest/Data.json diff --git a/TR2RandomizerCore/Resources/Models/StickWieldingGoon1WhiteVest/Segments.png b/TRRandomizerCore/Resources/TR2/Models/StickWieldingGoon1WhiteVest/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/StickWieldingGoon1WhiteVest/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/StickWieldingGoon1WhiteVest/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/StickWieldingGoon2/Data.json b/TRRandomizerCore/Resources/TR2/Models/StickWieldingGoon2/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/StickWieldingGoon2/Data.json rename to TRRandomizerCore/Resources/TR2/Models/StickWieldingGoon2/Data.json diff --git a/TR2RandomizerCore/Resources/Models/StickWieldingGoon2/Segments.png b/TRRandomizerCore/Resources/TR2/Models/StickWieldingGoon2/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/StickWieldingGoon2/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/StickWieldingGoon2/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/TRex/Data.json b/TRRandomizerCore/Resources/TR2/Models/TRex/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/TRex/Data.json rename to TRRandomizerCore/Resources/TR2/Models/TRex/Data.json diff --git a/TR2RandomizerCore/Resources/Models/TRex/Segments.png b/TRRandomizerCore/Resources/TR2/Models/TRex/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/TRex/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/TRex/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/WhiteTiger/Data.json b/TRRandomizerCore/Resources/TR2/Models/WhiteTiger/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/WhiteTiger/Data.json rename to TRRandomizerCore/Resources/TR2/Models/WhiteTiger/Data.json diff --git a/TR2RandomizerCore/Resources/Models/WhiteTiger/Segments.png b/TRRandomizerCore/Resources/TR2/Models/WhiteTiger/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/WhiteTiger/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/WhiteTiger/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/Winston/Data.json b/TRRandomizerCore/Resources/TR2/Models/Winston/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/Winston/Data.json rename to TRRandomizerCore/Resources/TR2/Models/Winston/Data.json diff --git a/TR2RandomizerCore/Resources/Models/Winston/Segments.png b/TRRandomizerCore/Resources/TR2/Models/Winston/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/Winston/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/Winston/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/XianGuardSpear/Data.json b/TRRandomizerCore/Resources/TR2/Models/XianGuardSpear/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/XianGuardSpear/Data.json rename to TRRandomizerCore/Resources/TR2/Models/XianGuardSpear/Data.json diff --git a/TR2RandomizerCore/Resources/Models/XianGuardSpear/Segments.png b/TRRandomizerCore/Resources/TR2/Models/XianGuardSpear/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/XianGuardSpear/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/XianGuardSpear/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/XianGuardSpearStatue/Data.json b/TRRandomizerCore/Resources/TR2/Models/XianGuardSpearStatue/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/XianGuardSpearStatue/Data.json rename to TRRandomizerCore/Resources/TR2/Models/XianGuardSpearStatue/Data.json diff --git a/TR2RandomizerCore/Resources/Models/XianGuardSpearStatue/Segments.png b/TRRandomizerCore/Resources/TR2/Models/XianGuardSpearStatue/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/XianGuardSpearStatue/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/XianGuardSpearStatue/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/XianGuardSword/Data.json b/TRRandomizerCore/Resources/TR2/Models/XianGuardSword/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/XianGuardSword/Data.json rename to TRRandomizerCore/Resources/TR2/Models/XianGuardSword/Data.json diff --git a/TR2RandomizerCore/Resources/Models/XianGuardSword/Segments.png b/TRRandomizerCore/Resources/TR2/Models/XianGuardSword/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/XianGuardSword/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/XianGuardSword/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/XianGuardSwordStatue/Data.json b/TRRandomizerCore/Resources/TR2/Models/XianGuardSwordStatue/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/XianGuardSwordStatue/Data.json rename to TRRandomizerCore/Resources/TR2/Models/XianGuardSwordStatue/Data.json diff --git a/TR2RandomizerCore/Resources/Models/XianGuardSwordStatue/Segments.png b/TRRandomizerCore/Resources/TR2/Models/XianGuardSwordStatue/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/XianGuardSwordStatue/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/XianGuardSwordStatue/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/YellowMorayEel/Data.json b/TRRandomizerCore/Resources/TR2/Models/YellowMorayEel/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/YellowMorayEel/Data.json rename to TRRandomizerCore/Resources/TR2/Models/YellowMorayEel/Data.json diff --git a/TR2RandomizerCore/Resources/Models/YellowMorayEel/Segments.png b/TRRandomizerCore/Resources/TR2/Models/YellowMorayEel/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/YellowMorayEel/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/YellowMorayEel/Segments.png diff --git a/TR2RandomizerCore/Resources/Models/Yeti/Data.json b/TRRandomizerCore/Resources/TR2/Models/Yeti/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Models/Yeti/Data.json rename to TRRandomizerCore/Resources/TR2/Models/Yeti/Data.json diff --git a/TR2RandomizerCore/Resources/Models/Yeti/Segments.png b/TRRandomizerCore/Resources/TR2/Models/Yeti/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Models/Yeti/Segments.png rename to TRRandomizerCore/Resources/TR2/Models/Yeti/Segments.png diff --git a/TR2RandomizerCore/Resources/enemy_restrictions_default.json b/TRRandomizerCore/Resources/TR2/Restrictions/enemy_restrictions_default.json similarity index 100% rename from TR2RandomizerCore/Resources/enemy_restrictions_default.json rename to TRRandomizerCore/Resources/TR2/Restrictions/enemy_restrictions_default.json diff --git a/TR2RandomizerCore/Resources/enemy_restrictions_technical.json b/TRRandomizerCore/Resources/TR2/Restrictions/enemy_restrictions_technical.json similarity index 100% rename from TR2RandomizerCore/Resources/enemy_restrictions_technical.json rename to TRRandomizerCore/Resources/TR2/Restrictions/enemy_restrictions_technical.json diff --git a/TR2RandomizerCore/Resources/Strings/G11N/defaults.json b/TRRandomizerCore/Resources/TR2/Strings/G11N/defaults.json similarity index 100% rename from TR2RandomizerCore/Resources/Strings/G11N/defaults.json rename to TRRandomizerCore/Resources/TR2/Strings/G11N/defaults.json diff --git a/TR2RandomizerCore/Resources/Strings/G11N/gamestrings_CS.json b/TRRandomizerCore/Resources/TR2/Strings/G11N/gamestrings_CS.json similarity index 100% rename from TR2RandomizerCore/Resources/Strings/G11N/gamestrings_CS.json rename to TRRandomizerCore/Resources/TR2/Strings/G11N/gamestrings_CS.json diff --git a/TR2RandomizerCore/Resources/Strings/G11N/gamestrings_DE.json b/TRRandomizerCore/Resources/TR2/Strings/G11N/gamestrings_DE.json similarity index 100% rename from TR2RandomizerCore/Resources/Strings/G11N/gamestrings_DE.json rename to TRRandomizerCore/Resources/TR2/Strings/G11N/gamestrings_DE.json diff --git a/TR2RandomizerCore/Resources/Strings/G11N/gamestrings_EN.json b/TRRandomizerCore/Resources/TR2/Strings/G11N/gamestrings_EN.json similarity index 100% rename from TR2RandomizerCore/Resources/Strings/G11N/gamestrings_EN.json rename to TRRandomizerCore/Resources/TR2/Strings/G11N/gamestrings_EN.json diff --git a/TR2RandomizerCore/Resources/Strings/G11N/gamestrings_FI.json b/TRRandomizerCore/Resources/TR2/Strings/G11N/gamestrings_FI.json similarity index 100% rename from TR2RandomizerCore/Resources/Strings/G11N/gamestrings_FI.json rename to TRRandomizerCore/Resources/TR2/Strings/G11N/gamestrings_FI.json diff --git a/TR2RandomizerCore/Resources/Strings/G11N/gamestrings_FR.json b/TRRandomizerCore/Resources/TR2/Strings/G11N/gamestrings_FR.json similarity index 100% rename from TR2RandomizerCore/Resources/Strings/G11N/gamestrings_FR.json rename to TRRandomizerCore/Resources/TR2/Strings/G11N/gamestrings_FR.json diff --git a/TR2RandomizerCore/Resources/Strings/G11N/gamestrings_HR.json b/TRRandomizerCore/Resources/TR2/Strings/G11N/gamestrings_HR.json similarity index 100% rename from TR2RandomizerCore/Resources/Strings/G11N/gamestrings_HR.json rename to TRRandomizerCore/Resources/TR2/Strings/G11N/gamestrings_HR.json diff --git a/TR2RandomizerCore/Resources/Strings/G11N/gamestrings_IT.json b/TRRandomizerCore/Resources/TR2/Strings/G11N/gamestrings_IT.json similarity index 100% rename from TR2RandomizerCore/Resources/Strings/G11N/gamestrings_IT.json rename to TRRandomizerCore/Resources/TR2/Strings/G11N/gamestrings_IT.json diff --git a/TR2RandomizerCore/Resources/Strings/G11N/gamestrings_JA.json b/TRRandomizerCore/Resources/TR2/Strings/G11N/gamestrings_JA.json similarity index 100% rename from TR2RandomizerCore/Resources/Strings/G11N/gamestrings_JA.json rename to TRRandomizerCore/Resources/TR2/Strings/G11N/gamestrings_JA.json diff --git a/TR2RandomizerCore/Resources/Strings/G11N/gamestrings_NL.json b/TRRandomizerCore/Resources/TR2/Strings/G11N/gamestrings_NL.json similarity index 100% rename from TR2RandomizerCore/Resources/Strings/G11N/gamestrings_NL.json rename to TRRandomizerCore/Resources/TR2/Strings/G11N/gamestrings_NL.json diff --git a/TR2RandomizerCore/Resources/Strings/G11N/gamestrings_PL.json b/TRRandomizerCore/Resources/TR2/Strings/G11N/gamestrings_PL.json similarity index 100% rename from TR2RandomizerCore/Resources/Strings/G11N/gamestrings_PL.json rename to TRRandomizerCore/Resources/TR2/Strings/G11N/gamestrings_PL.json diff --git a/TR2RandomizerCore/Resources/Strings/G11N/gamestrings_PT.json b/TRRandomizerCore/Resources/TR2/Strings/G11N/gamestrings_PT.json similarity index 100% rename from TR2RandomizerCore/Resources/Strings/G11N/gamestrings_PT.json rename to TRRandomizerCore/Resources/TR2/Strings/G11N/gamestrings_PT.json diff --git a/TR2RandomizerCore/Resources/Strings/G11N/gamestrings_RU.json b/TRRandomizerCore/Resources/TR2/Strings/G11N/gamestrings_RU.json similarity index 100% rename from TR2RandomizerCore/Resources/Strings/G11N/gamestrings_RU.json rename to TRRandomizerCore/Resources/TR2/Strings/G11N/gamestrings_RU.json diff --git a/TR2RandomizerCore/Resources/Strings/G11N/gamestrings_SV.json b/TRRandomizerCore/Resources/TR2/Strings/G11N/gamestrings_SV.json similarity index 100% rename from TR2RandomizerCore/Resources/Strings/G11N/gamestrings_SV.json rename to TRRandomizerCore/Resources/TR2/Strings/G11N/gamestrings_SV.json diff --git a/TR2RandomizerCore/Resources/Strings/languages.json b/TRRandomizerCore/Resources/TR2/Strings/languages.json similarity index 100% rename from TR2RandomizerCore/Resources/Strings/languages.json rename to TRRandomizerCore/Resources/TR2/Strings/languages.json diff --git a/TR2RandomizerCore/Resources/Textures/Deduplication/BOAT.TR2-TextureRemap.json b/TRRandomizerCore/Resources/TR2/Textures/Deduplication/BOAT.TR2-TextureRemap.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Deduplication/BOAT.TR2-TextureRemap.json rename to TRRandomizerCore/Resources/TR2/Textures/Deduplication/BOAT.TR2-TextureRemap.json diff --git a/TR2RandomizerCore/Resources/Textures/Deduplication/CATACOMB.TR2-TextureRemap.json b/TRRandomizerCore/Resources/TR2/Textures/Deduplication/CATACOMB.TR2-TextureRemap.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Deduplication/CATACOMB.TR2-TextureRemap.json rename to TRRandomizerCore/Resources/TR2/Textures/Deduplication/CATACOMB.TR2-TextureRemap.json diff --git a/TR2RandomizerCore/Resources/Textures/Deduplication/DECK.TR2-TextureRemap.json b/TRRandomizerCore/Resources/TR2/Textures/Deduplication/DECK.TR2-TextureRemap.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Deduplication/DECK.TR2-TextureRemap.json rename to TRRandomizerCore/Resources/TR2/Textures/Deduplication/DECK.TR2-TextureRemap.json diff --git a/TR2RandomizerCore/Resources/Textures/Deduplication/EMPRTOMB.TR2-TextureRemap.json b/TRRandomizerCore/Resources/TR2/Textures/Deduplication/EMPRTOMB.TR2-TextureRemap.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Deduplication/EMPRTOMB.TR2-TextureRemap.json rename to TRRandomizerCore/Resources/TR2/Textures/Deduplication/EMPRTOMB.TR2-TextureRemap.json diff --git a/TR2RandomizerCore/Resources/Textures/Deduplication/FLOATING.TR2-TextureRemap.json b/TRRandomizerCore/Resources/TR2/Textures/Deduplication/FLOATING.TR2-TextureRemap.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Deduplication/FLOATING.TR2-TextureRemap.json rename to TRRandomizerCore/Resources/TR2/Textures/Deduplication/FLOATING.TR2-TextureRemap.json diff --git a/TR2RandomizerCore/Resources/Textures/Deduplication/FLOATING.TR2-UKBox-TextureRemap.json b/TRRandomizerCore/Resources/TR2/Textures/Deduplication/FLOATING.TR2-UKBox-TextureRemap.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Deduplication/FLOATING.TR2-UKBox-TextureRemap.json rename to TRRandomizerCore/Resources/TR2/Textures/Deduplication/FLOATING.TR2-UKBox-TextureRemap.json diff --git a/TR2RandomizerCore/Resources/Textures/Deduplication/HOUSE.TR2-TextureRemap.json b/TRRandomizerCore/Resources/TR2/Textures/Deduplication/HOUSE.TR2-TextureRemap.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Deduplication/HOUSE.TR2-TextureRemap.json rename to TRRandomizerCore/Resources/TR2/Textures/Deduplication/HOUSE.TR2-TextureRemap.json diff --git a/TR2RandomizerCore/Resources/Textures/Deduplication/ICECAVE.TR2-TextureRemap.json b/TRRandomizerCore/Resources/TR2/Textures/Deduplication/ICECAVE.TR2-TextureRemap.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Deduplication/ICECAVE.TR2-TextureRemap.json rename to TRRandomizerCore/Resources/TR2/Textures/Deduplication/ICECAVE.TR2-TextureRemap.json diff --git a/TR2RandomizerCore/Resources/Textures/Deduplication/KEEL.TR2-TextureRemap.json b/TRRandomizerCore/Resources/TR2/Textures/Deduplication/KEEL.TR2-TextureRemap.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Deduplication/KEEL.TR2-TextureRemap.json rename to TRRandomizerCore/Resources/TR2/Textures/Deduplication/KEEL.TR2-TextureRemap.json diff --git a/TR2RandomizerCore/Resources/Textures/Deduplication/LIVING.TR2-TextureRemap.json b/TRRandomizerCore/Resources/TR2/Textures/Deduplication/LIVING.TR2-TextureRemap.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Deduplication/LIVING.TR2-TextureRemap.json rename to TRRandomizerCore/Resources/TR2/Textures/Deduplication/LIVING.TR2-TextureRemap.json diff --git a/TR2RandomizerCore/Resources/Textures/Deduplication/MONASTRY.TR2-TextureRemap.json b/TRRandomizerCore/Resources/TR2/Textures/Deduplication/MONASTRY.TR2-TextureRemap.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Deduplication/MONASTRY.TR2-TextureRemap.json rename to TRRandomizerCore/Resources/TR2/Textures/Deduplication/MONASTRY.TR2-TextureRemap.json diff --git a/TR2RandomizerCore/Resources/Textures/Deduplication/OPERA.TR2-TextureRemap.json b/TRRandomizerCore/Resources/TR2/Textures/Deduplication/OPERA.TR2-TextureRemap.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Deduplication/OPERA.TR2-TextureRemap.json rename to TRRandomizerCore/Resources/TR2/Textures/Deduplication/OPERA.TR2-TextureRemap.json diff --git a/TR2RandomizerCore/Resources/Textures/Deduplication/PLATFORM.TR2-TextureRemap.json b/TRRandomizerCore/Resources/TR2/Textures/Deduplication/PLATFORM.TR2-TextureRemap.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Deduplication/PLATFORM.TR2-TextureRemap.json rename to TRRandomizerCore/Resources/TR2/Textures/Deduplication/PLATFORM.TR2-TextureRemap.json diff --git a/TR2RandomizerCore/Resources/Textures/Deduplication/RIG.TR2-TextureRemap.json b/TRRandomizerCore/Resources/TR2/Textures/Deduplication/RIG.TR2-TextureRemap.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Deduplication/RIG.TR2-TextureRemap.json rename to TRRandomizerCore/Resources/TR2/Textures/Deduplication/RIG.TR2-TextureRemap.json diff --git a/TR2RandomizerCore/Resources/Textures/Deduplication/SKIDOO.TR2-TextureRemap.json b/TRRandomizerCore/Resources/TR2/Textures/Deduplication/SKIDOO.TR2-TextureRemap.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Deduplication/SKIDOO.TR2-TextureRemap.json rename to TRRandomizerCore/Resources/TR2/Textures/Deduplication/SKIDOO.TR2-TextureRemap.json diff --git a/TR2RandomizerCore/Resources/Textures/Deduplication/UNWATER.TR2-TextureRemap.json b/TRRandomizerCore/Resources/TR2/Textures/Deduplication/UNWATER.TR2-TextureRemap.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Deduplication/UNWATER.TR2-TextureRemap.json rename to TRRandomizerCore/Resources/TR2/Textures/Deduplication/UNWATER.TR2-TextureRemap.json diff --git a/TR2RandomizerCore/Resources/Textures/Deduplication/VENICE.TR2-TextureRemap.json b/TRRandomizerCore/Resources/TR2/Textures/Deduplication/VENICE.TR2-TextureRemap.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Deduplication/VENICE.TR2-TextureRemap.json rename to TRRandomizerCore/Resources/TR2/Textures/Deduplication/VENICE.TR2-TextureRemap.json diff --git a/TR2RandomizerCore/Resources/Textures/Deduplication/WALL.TR2-TextureRemap.json b/TRRandomizerCore/Resources/TR2/Textures/Deduplication/WALL.TR2-TextureRemap.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Deduplication/WALL.TR2-TextureRemap.json rename to TRRandomizerCore/Resources/TR2/Textures/Deduplication/WALL.TR2-TextureRemap.json diff --git a/TR2RandomizerCore/Resources/Textures/Deduplication/XIAN.TR2-TextureRemap.json b/TRRandomizerCore/Resources/TR2/Textures/Deduplication/XIAN.TR2-TextureRemap.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Deduplication/XIAN.TR2-TextureRemap.json rename to TRRandomizerCore/Resources/TR2/Textures/Deduplication/XIAN.TR2-TextureRemap.json diff --git a/TR2RandomizerCore/Resources/Textures/Mapping/ASSAULT.TR2-Textures.json b/TRRandomizerCore/Resources/TR2/Textures/Mapping/ASSAULT.TR2-Textures.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Mapping/ASSAULT.TR2-Textures.json rename to TRRandomizerCore/Resources/TR2/Textures/Mapping/ASSAULT.TR2-Textures.json diff --git a/TR2RandomizerCore/Resources/Textures/Mapping/BOAT.TR2-Textures.json b/TRRandomizerCore/Resources/TR2/Textures/Mapping/BOAT.TR2-Textures.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Mapping/BOAT.TR2-Textures.json rename to TRRandomizerCore/Resources/TR2/Textures/Mapping/BOAT.TR2-Textures.json diff --git a/TR2RandomizerCore/Resources/Textures/Mapping/CATACOMB.TR2-Textures.json b/TRRandomizerCore/Resources/TR2/Textures/Mapping/CATACOMB.TR2-Textures.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Mapping/CATACOMB.TR2-Textures.json rename to TRRandomizerCore/Resources/TR2/Textures/Mapping/CATACOMB.TR2-Textures.json diff --git a/TR2RandomizerCore/Resources/Textures/Mapping/CUT1.TR2-Textures.json b/TRRandomizerCore/Resources/TR2/Textures/Mapping/CUT1.TR2-Textures.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Mapping/CUT1.TR2-Textures.json rename to TRRandomizerCore/Resources/TR2/Textures/Mapping/CUT1.TR2-Textures.json diff --git a/TR2RandomizerCore/Resources/Textures/Mapping/CUT2.TR2-Textures.json b/TRRandomizerCore/Resources/TR2/Textures/Mapping/CUT2.TR2-Textures.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Mapping/CUT2.TR2-Textures.json rename to TRRandomizerCore/Resources/TR2/Textures/Mapping/CUT2.TR2-Textures.json diff --git a/TR2RandomizerCore/Resources/Textures/Mapping/CUT3.TR2-Textures.json b/TRRandomizerCore/Resources/TR2/Textures/Mapping/CUT3.TR2-Textures.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Mapping/CUT3.TR2-Textures.json rename to TRRandomizerCore/Resources/TR2/Textures/Mapping/CUT3.TR2-Textures.json diff --git a/TR2RandomizerCore/Resources/Textures/Mapping/CUT4.TR2-Textures.json b/TRRandomizerCore/Resources/TR2/Textures/Mapping/CUT4.TR2-Textures.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Mapping/CUT4.TR2-Textures.json rename to TRRandomizerCore/Resources/TR2/Textures/Mapping/CUT4.TR2-Textures.json diff --git a/TR2RandomizerCore/Resources/Textures/Mapping/DECK.TR2-Textures.json b/TRRandomizerCore/Resources/TR2/Textures/Mapping/DECK.TR2-Textures.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Mapping/DECK.TR2-Textures.json rename to TRRandomizerCore/Resources/TR2/Textures/Mapping/DECK.TR2-Textures.json diff --git a/TR2RandomizerCore/Resources/Textures/Mapping/EMPRTOMB.TR2-Textures.json b/TRRandomizerCore/Resources/TR2/Textures/Mapping/EMPRTOMB.TR2-Textures.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Mapping/EMPRTOMB.TR2-Textures.json rename to TRRandomizerCore/Resources/TR2/Textures/Mapping/EMPRTOMB.TR2-Textures.json diff --git a/TR2RandomizerCore/Resources/Textures/Mapping/FLOATING.TR2-Textures.json b/TRRandomizerCore/Resources/TR2/Textures/Mapping/FLOATING.TR2-Textures.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Mapping/FLOATING.TR2-Textures.json rename to TRRandomizerCore/Resources/TR2/Textures/Mapping/FLOATING.TR2-Textures.json diff --git a/TR2RandomizerCore/Resources/Textures/Mapping/FLOATING.TR2-UKBox-Textures.json b/TRRandomizerCore/Resources/TR2/Textures/Mapping/FLOATING.TR2-UKBox-Textures.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Mapping/FLOATING.TR2-UKBox-Textures.json rename to TRRandomizerCore/Resources/TR2/Textures/Mapping/FLOATING.TR2-UKBox-Textures.json diff --git a/TR2RandomizerCore/Resources/Textures/Mapping/HOUSE.TR2-Textures.json b/TRRandomizerCore/Resources/TR2/Textures/Mapping/HOUSE.TR2-Textures.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Mapping/HOUSE.TR2-Textures.json rename to TRRandomizerCore/Resources/TR2/Textures/Mapping/HOUSE.TR2-Textures.json diff --git a/TR2RandomizerCore/Resources/Textures/Mapping/ICECAVE.TR2-Textures.json b/TRRandomizerCore/Resources/TR2/Textures/Mapping/ICECAVE.TR2-Textures.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Mapping/ICECAVE.TR2-Textures.json rename to TRRandomizerCore/Resources/TR2/Textures/Mapping/ICECAVE.TR2-Textures.json diff --git a/TR2RandomizerCore/Resources/Textures/Mapping/KEEL.TR2-Textures.json b/TRRandomizerCore/Resources/TR2/Textures/Mapping/KEEL.TR2-Textures.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Mapping/KEEL.TR2-Textures.json rename to TRRandomizerCore/Resources/TR2/Textures/Mapping/KEEL.TR2-Textures.json diff --git a/TR2RandomizerCore/Resources/Textures/Mapping/LIVING.TR2-Textures.json b/TRRandomizerCore/Resources/TR2/Textures/Mapping/LIVING.TR2-Textures.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Mapping/LIVING.TR2-Textures.json rename to TRRandomizerCore/Resources/TR2/Textures/Mapping/LIVING.TR2-Textures.json diff --git a/TR2RandomizerCore/Resources/Textures/Mapping/MONASTRY.TR2-Textures.json b/TRRandomizerCore/Resources/TR2/Textures/Mapping/MONASTRY.TR2-Textures.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Mapping/MONASTRY.TR2-Textures.json rename to TRRandomizerCore/Resources/TR2/Textures/Mapping/MONASTRY.TR2-Textures.json diff --git a/TR2RandomizerCore/Resources/Textures/Mapping/OPERA.TR2-Textures.json b/TRRandomizerCore/Resources/TR2/Textures/Mapping/OPERA.TR2-Textures.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Mapping/OPERA.TR2-Textures.json rename to TRRandomizerCore/Resources/TR2/Textures/Mapping/OPERA.TR2-Textures.json diff --git a/TR2RandomizerCore/Resources/Textures/Mapping/PLATFORM.TR2-Textures.json b/TRRandomizerCore/Resources/TR2/Textures/Mapping/PLATFORM.TR2-Textures.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Mapping/PLATFORM.TR2-Textures.json rename to TRRandomizerCore/Resources/TR2/Textures/Mapping/PLATFORM.TR2-Textures.json diff --git a/TR2RandomizerCore/Resources/Textures/Mapping/RIG.TR2-Textures.json b/TRRandomizerCore/Resources/TR2/Textures/Mapping/RIG.TR2-Textures.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Mapping/RIG.TR2-Textures.json rename to TRRandomizerCore/Resources/TR2/Textures/Mapping/RIG.TR2-Textures.json diff --git a/TR2RandomizerCore/Resources/Textures/Mapping/SKIDOO.TR2-Textures.json b/TRRandomizerCore/Resources/TR2/Textures/Mapping/SKIDOO.TR2-Textures.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Mapping/SKIDOO.TR2-Textures.json rename to TRRandomizerCore/Resources/TR2/Textures/Mapping/SKIDOO.TR2-Textures.json diff --git a/TR2RandomizerCore/Resources/Textures/Mapping/UNWATER.TR2-Textures.json b/TRRandomizerCore/Resources/TR2/Textures/Mapping/UNWATER.TR2-Textures.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Mapping/UNWATER.TR2-Textures.json rename to TRRandomizerCore/Resources/TR2/Textures/Mapping/UNWATER.TR2-Textures.json diff --git a/TR2RandomizerCore/Resources/Textures/Mapping/VENICE.TR2-Textures.json b/TRRandomizerCore/Resources/TR2/Textures/Mapping/VENICE.TR2-Textures.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Mapping/VENICE.TR2-Textures.json rename to TRRandomizerCore/Resources/TR2/Textures/Mapping/VENICE.TR2-Textures.json diff --git a/TR2RandomizerCore/Resources/Textures/Mapping/WALL.TR2-Textures.json b/TRRandomizerCore/Resources/TR2/Textures/Mapping/WALL.TR2-Textures.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Mapping/WALL.TR2-Textures.json rename to TRRandomizerCore/Resources/TR2/Textures/Mapping/WALL.TR2-Textures.json diff --git a/TR2RandomizerCore/Resources/Textures/Mapping/XIAN.TR2-Textures.json b/TRRandomizerCore/Resources/TR2/Textures/Mapping/XIAN.TR2-Textures.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Mapping/XIAN.TR2-Textures.json rename to TRRandomizerCore/Resources/TR2/Textures/Mapping/XIAN.TR2-Textures.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Dynamic/China/WallTheme.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Dynamic/China/WallTheme.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Dynamic/China/WallTheme.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Dynamic/China/WallTheme.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Dynamic/Opera/PlaneTheme.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Dynamic/Opera/PlaneTheme.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Dynamic/Opera/PlaneTheme.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Dynamic/Opera/PlaneTheme.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Dynamic/Tibet/SnowTheme.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Dynamic/Tibet/SnowTheme.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Dynamic/Tibet/SnowTheme.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Dynamic/Tibet/SnowTheme.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Dynamic/Underwater/MariaTheme.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Dynamic/Underwater/MariaTheme.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Dynamic/Underwater/MariaTheme.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Dynamic/Underwater/MariaTheme.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/Barney/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/Barney/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/Barney/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/Barney/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/Barney/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/Barney/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/Barney/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/Barney/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/Bartoli/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/Bartoli/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/Bartoli/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/Bartoli/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/Bartoli/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/Bartoli/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/Bartoli/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/Bartoli/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/Chicken/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/Chicken/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/Chicken/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/Chicken/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/Chicken/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/Chicken/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/Chicken/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/Chicken/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/Dragon/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/Dragon/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/Dragon/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/Dragon/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/Dragon/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/Dragon/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/Dragon/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/Dragon/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/Guard/Spear/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/Guard/Spear/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/Guard/Spear/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/Guard/Spear/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/Guard/Spear/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/Guard/Spear/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/Guard/Spear/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/Guard/Spear/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/Guard/Sword/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/Guard/Sword/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/Guard/Sword/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/Guard/Sword/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/Guard/Sword/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/Guard/Sword/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/Guard/Sword/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/Guard/Sword/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/Knifethrower/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/Knifethrower/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/Knifethrower/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/Knifethrower/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/Knifethrower/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/Knifethrower/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/Knifethrower/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/Knifethrower/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/Monk/KnifeStick/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/Monk/KnifeStick/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/Monk/KnifeStick/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/Monk/KnifeStick/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/Monk/KnifeStick/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/Monk/KnifeStick/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/Monk/KnifeStick/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/Monk/KnifeStick/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/Monk/LongStick/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/Monk/LongStick/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/Monk/LongStick/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/Monk/LongStick/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/Monk/LongStick/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/Monk/LongStick/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/Monk/LongStick/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/Monk/LongStick/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/ShotgunGoon/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/ShotgunGoon/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/ShotgunGoon/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/ShotgunGoon/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/ShotgunGoon/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/ShotgunGoon/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/ShotgunGoon/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/ShotgunGoon/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/Spider/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/Spider/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/Spider/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/Spider/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/Spider/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/Spider/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/Spider/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/Spider/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/Steve/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/Steve/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/Steve/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/Steve/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/Steve/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/Steve/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/Steve/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/Steve/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/StickGoon/Bandana/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/StickGoon/Bandana/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/StickGoon/Bandana/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/StickGoon/Bandana/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/StickGoon/Bandana/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/StickGoon/Bandana/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/StickGoon/Bandana/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/StickGoon/Bandana/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/StickGoon/BlackJacket/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/StickGoon/BlackJacket/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/StickGoon/BlackJacket/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/StickGoon/BlackJacket/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/StickGoon/BlackJacket/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/StickGoon/BlackJacket/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/StickGoon/BlackJacket/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/StickGoon/BlackJacket/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/StickGoon/BodyWarmer/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/StickGoon/BodyWarmer/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/StickGoon/BodyWarmer/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/StickGoon/BodyWarmer/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/StickGoon/BodyWarmer/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/StickGoon/BodyWarmer/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/StickGoon/BodyWarmer/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/StickGoon/BodyWarmer/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/StickGoon/GreenVest/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/StickGoon/GreenVest/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/StickGoon/GreenVest/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/StickGoon/GreenVest/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/StickGoon/GreenVest/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/StickGoon/GreenVest/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/StickGoon/GreenVest/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/StickGoon/GreenVest/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/StickGoon/Sonics/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/StickGoon/Sonics/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/StickGoon/Sonics/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/StickGoon/Sonics/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/StickGoon/Sonics/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/StickGoon/Sonics/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/StickGoon/Sonics/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/StickGoon/Sonics/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/Winston/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/Winston/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/Winston/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/Winston/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/Winston/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/Winston/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Enemies/Winston/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Enemies/Winston/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Fire/Explosion/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Fire/Explosion/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Fire/Explosion/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Fire/Explosion/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Fire/Explosion/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Fire/Explosion/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Fire/Explosion/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Fire/Explosion/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Fire/Flame/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Fire/Flame/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Fire/Flame/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Fire/Flame/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Fire/Flame/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Fire/Flame/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Fire/Flame/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Fire/Flame/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Fire/Flare/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Fire/Flare/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Fire/Flare/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Fire/Flare/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Fire/Flare/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Fire/Flare/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Fire/Flare/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Fire/Flare/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/GreatWall/Laptop/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/GreatWall/Laptop/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/GreatWall/Laptop/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/GreatWall/Laptop/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/GreatWall/Laptop/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/GreatWall/Laptop/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/GreatWall/Laptop/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/GreatWall/Laptop/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/GreatWall/NightSky/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/GreatWall/NightSky/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/GreatWall/NightSky/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/GreatWall/NightSky/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/GreatWall/NightSky/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/GreatWall/NightSky/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/GreatWall/NightSky/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/GreatWall/NightSky/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/GreatWall/Sky/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/GreatWall/Sky/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/GreatWall/Sky/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/GreatWall/Sky/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/GreatWall/Sky/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/GreatWall/Sky/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/GreatWall/Sky/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/GreatWall/Sky/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/HSH/Carpet/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/HSH/Carpet/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/HSH/Carpet/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/HSH/Carpet/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/HSH/Carpet/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/HSH/Carpet/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/HSH/Carpet/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/HSH/Carpet/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/HSH/Cushions/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/HSH/Cushions/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/HSH/Cushions/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/HSH/Cushions/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/HSH/Cushions/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/HSH/Cushions/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/HSH/Cushions/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/HSH/Cushions/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/HSH/Duvet/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/HSH/Duvet/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/HSH/Duvet/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/HSH/Duvet/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/HSH/Duvet/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/HSH/Duvet/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/HSH/Duvet/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/HSH/Duvet/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/HSH/Marble/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/HSH/Marble/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/HSH/Marble/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/HSH/Marble/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/HSH/Marble/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/HSH/Marble/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/HSH/Marble/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/HSH/Marble/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/HSH/NightSky/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/HSH/NightSky/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/HSH/NightSky/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/HSH/NightSky/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/HSH/NightSky/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/HSH/NightSky/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/HSH/NightSky/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/HSH/NightSky/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/HSH/Paintings/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/HSH/Paintings/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/HSH/Paintings/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/HSH/Paintings/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/HSH/Paintings/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/HSH/Paintings/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/HSH/Paintings/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/HSH/Paintings/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/HSH/Sky/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/HSH/Sky/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/HSH/Sky/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/HSH/Sky/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/HSH/Sky/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/HSH/Sky/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/HSH/Sky/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/HSH/Sky/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/HSH/Tiles/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/HSH/Tiles/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/HSH/Tiles/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/HSH/Tiles/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/HSH/Tiles/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/HSH/Tiles/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/HSH/Tiles/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/HSH/Tiles/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Hazards/Boulder/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Hazards/Boulder/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Hazards/Boulder/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Hazards/Boulder/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Hazards/Boulder/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Hazards/Boulder/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Hazards/Boulder/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Hazards/Boulder/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Hazards/Spikes/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Hazards/Spikes/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Hazards/Spikes/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Hazards/Spikes/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Hazards/Spikes/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Hazards/Spikes/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Hazards/Spikes/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Hazards/Spikes/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Hazards/Spindle/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Hazards/Spindle/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Hazards/Spindle/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Hazards/Spindle/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Hazards/Spindle/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Hazards/Spindle/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Hazards/Spindle/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Hazards/Spindle/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Inventory/Background/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Inventory/Background/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Inventory/Background/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Inventory/Background/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Inventory/Background/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Inventory/Background/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Inventory/Background/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Inventory/Background/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Inventory/Font/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Inventory/Font/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Inventory/Font/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Inventory/Font/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Inventory/Font/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Inventory/Font/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Inventory/Font/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Inventory/Font/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Inventory/Health/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Inventory/Health/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Inventory/Health/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Inventory/Health/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Inventory/Health/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Inventory/Health/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Inventory/Health/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Inventory/Health/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Inventory/Passport/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Inventory/Passport/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Inventory/Passport/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Inventory/Passport/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Inventory/Passport/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Inventory/Passport/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Inventory/Passport/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Inventory/Passport/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Inventory/UIFrame/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Inventory/UIFrame/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Inventory/UIFrame/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Inventory/UIFrame/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Inventory/UIFrame/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Inventory/UIFrame/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Inventory/UIFrame/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Inventory/UIFrame/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Landmarks/BRB/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Landmarks/BRB/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Landmarks/BRB/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Landmarks/BRB/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Landmarks/BRB/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Landmarks/BRB/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Landmarks/BRB/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Landmarks/BRB/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Landmarks/DAStep/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Landmarks/DAStep/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Landmarks/DAStep/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Landmarks/DAStep/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Landmarks/DAStep/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Landmarks/DAStep/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Landmarks/DAStep/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Landmarks/DAStep/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Landmarks/FullLoss/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Landmarks/FullLoss/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Landmarks/FullLoss/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Landmarks/FullLoss/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Landmarks/FullLoss/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Landmarks/FullLoss/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Landmarks/FullLoss/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Landmarks/FullLoss/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Landmarks/NLNMFirst/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Landmarks/NLNMFirst/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Landmarks/NLNMFirst/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Landmarks/NLNMFirst/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Landmarks/NLNMFirst/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Landmarks/NLNMFirst/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Landmarks/NLNMFirst/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Landmarks/NLNMFirst/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Landmarks/NoSaves/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Landmarks/NoSaves/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Landmarks/NoSaves/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Landmarks/NoSaves/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Landmarks/NoSaves/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Landmarks/NoSaves/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Landmarks/NoSaves/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Landmarks/NoSaves/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Lara/Bobble/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Lara/Bobble/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Lara/Bobble/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Lara/Bobble/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Lara/Bobble/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Lara/Bobble/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Lara/Bobble/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Lara/Bobble/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Lara/Braid/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Lara/Braid/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Lara/Braid/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Lara/Braid/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Lara/Braid/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Lara/Braid/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Lara/Braid/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Lara/Braid/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Lara/DivingSuit/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Lara/DivingSuit/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Lara/DivingSuit/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Lara/DivingSuit/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Lara/DivingSuit/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Lara/DivingSuit/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Lara/DivingSuit/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Lara/DivingSuit/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Lara/DressingGown/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Lara/DressingGown/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Lara/DressingGown/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Lara/DressingGown/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Lara/DressingGown/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Lara/DressingGown/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Lara/DressingGown/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Lara/DressingGown/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Lara/Socks/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Lara/Socks/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Lara/Socks/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Lara/Socks/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Lara/Socks/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Lara/Socks/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Lara/Socks/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Lara/Socks/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Lara/Top/Snow/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Lara/Top/Snow/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Lara/Top/Snow/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Lara/Top/Snow/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Lara/Top/Snow/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Lara/Top/Snow/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Lara/Top/Snow/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Lara/Top/Snow/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Lara/Top/Sun/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Lara/Top/Sun/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Lara/Top/Sun/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Lara/Top/Sun/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Lara/Top/Sun/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Lara/Top/Sun/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Lara/Top/Sun/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Lara/Top/Sun/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Offshore/Acid/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Offshore/Acid/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Offshore/Acid/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Offshore/Acid/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Offshore/Acid/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Offshore/Acid/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Offshore/Acid/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Offshore/Acid/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Offshore/Cordon/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Offshore/Cordon/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Offshore/Cordon/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Offshore/Cordon/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Offshore/Cordon/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Offshore/Cordon/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Offshore/Cordon/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Offshore/Cordon/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Offshore/Keycard/Keycard1/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Offshore/Keycard/Keycard1/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Offshore/Keycard/Keycard1/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Offshore/Keycard/Keycard1/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Offshore/Keycard/Keycard1/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Offshore/Keycard/Keycard1/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Offshore/Keycard/Keycard1/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Offshore/Keycard/Keycard1/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Offshore/Keycard/Keycard2/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Offshore/Keycard/Keycard2/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Offshore/Keycard/Keycard2/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Offshore/Keycard/Keycard2/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Offshore/Keycard/Keycard2/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Offshore/Keycard/Keycard2/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Offshore/Keycard/Keycard2/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Offshore/Keycard/Keycard2/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Offshore/Keycard/Keycard3/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Offshore/Keycard/Keycard3/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Offshore/Keycard/Keycard3/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Offshore/Keycard/Keycard3/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Offshore/Keycard/Keycard3/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Offshore/Keycard/Keycard3/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Offshore/Keycard/Keycard3/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Offshore/Keycard/Keycard3/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Offshore/Keycard/Keycard4/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Offshore/Keycard/Keycard4/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Offshore/Keycard/Keycard4/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Offshore/Keycard/Keycard4/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Offshore/Keycard/Keycard4/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Offshore/Keycard/Keycard4/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Offshore/Keycard/Keycard4/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Offshore/Keycard/Keycard4/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Offshore/Plane/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Offshore/Plane/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Offshore/Plane/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Offshore/Plane/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Offshore/Plane/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Offshore/Plane/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Offshore/Plane/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Offshore/Plane/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Offshore/Sub/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Offshore/Sub/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Offshore/Sub/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Offshore/Sub/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Offshore/Sub/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Offshore/Sub/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Offshore/Sub/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Offshore/Sub/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Offshore/Tank/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Offshore/Tank/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Offshore/Tank/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Offshore/Tank/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Offshore/Tank/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Offshore/Tank/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Offshore/Tank/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Offshore/Tank/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Secrets/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Secrets/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Secrets/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Secrets/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Secrets/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Secrets/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Secrets/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Secrets/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Seraph/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Seraph/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Seraph/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Seraph/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Seraph/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Seraph/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Seraph/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Seraph/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Tibet/Bell/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Tibet/Bell/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Tibet/Bell/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Tibet/Bell/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Tibet/Bell/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Tibet/Bell/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Tibet/Bell/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Tibet/Bell/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Tibet/Gate/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Tibet/Gate/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Tibet/Gate/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Tibet/Gate/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Tibet/Gate/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Tibet/Gate/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Tibet/Gate/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Tibet/Gate/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Tibet/NightSky/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Tibet/NightSky/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Tibet/NightSky/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Tibet/NightSky/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Tibet/NightSky/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Tibet/NightSky/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Tibet/NightSky/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Tibet/NightSky/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Tibet/Sky/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Tibet/Sky/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Tibet/Sky/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Tibet/Sky/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Tibet/Sky/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Tibet/Sky/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Tibet/Sky/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Tibet/Sky/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Underwater/Lifeboat/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Underwater/Lifeboat/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Underwater/Lifeboat/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Underwater/Lifeboat/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Underwater/Lifeboat/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Underwater/Lifeboat/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Underwater/Lifeboat/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Underwater/Lifeboat/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Vehicles/Boat/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Vehicles/Boat/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Vehicles/Boat/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Vehicles/Boat/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Vehicles/Boat/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Vehicles/Boat/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Vehicles/Boat/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Vehicles/Boat/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Vehicles/Skidoo/Turbo/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Vehicles/Skidoo/Turbo/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Vehicles/Skidoo/Turbo/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Vehicles/Skidoo/Turbo/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Vehicles/Skidoo/Turbo/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Vehicles/Skidoo/Turbo/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Vehicles/Skidoo/Turbo/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Vehicles/Skidoo/Turbo/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Venice/Awning/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Venice/Awning/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Venice/Awning/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Venice/Awning/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Venice/Awning/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Venice/Awning/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Venice/Awning/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Venice/Awning/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Venice/BarberPole/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Venice/BarberPole/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Venice/BarberPole/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Venice/BarberPole/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Venice/BarberPole/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Venice/BarberPole/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Venice/BarberPole/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Venice/BarberPole/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Venice/Curtains/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Venice/Curtains/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Venice/Curtains/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Venice/Curtains/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Venice/Curtains/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Venice/Curtains/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Venice/Curtains/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Venice/Curtains/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Venice/Floor/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Venice/Floor/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Venice/Floor/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Venice/Floor/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Venice/Floor/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Venice/Floor/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Venice/Floor/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Venice/Floor/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Venice/NightSky/Bartoli/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Venice/NightSky/Bartoli/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Venice/NightSky/Bartoli/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Venice/NightSky/Bartoli/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Venice/NightSky/Bartoli/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Venice/NightSky/Bartoli/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Venice/NightSky/Bartoli/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Venice/NightSky/Bartoli/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Venice/NightSky/Boat/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Venice/NightSky/Boat/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Venice/NightSky/Boat/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Venice/NightSky/Boat/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Venice/NightSky/Boat/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Venice/NightSky/Boat/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Venice/NightSky/Boat/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Venice/NightSky/Boat/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Venice/Sky/Bartoli/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Venice/Sky/Bartoli/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Venice/Sky/Bartoli/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Venice/Sky/Bartoli/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Venice/Sky/Bartoli/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Venice/Sky/Bartoli/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Venice/Sky/Bartoli/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Venice/Sky/Bartoli/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Venice/Sky/Boat/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Venice/Sky/Boat/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Venice/Sky/Boat/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Venice/Sky/Boat/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Venice/Sky/Boat/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Venice/Sky/Boat/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Venice/Sky/Boat/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Venice/Sky/Boat/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Water/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Water/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Water/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Water/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Water/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Water/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Water/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Water/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Xian/Building/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Xian/Building/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Xian/Building/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Xian/Building/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Xian/Building/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Xian/Building/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Xian/Building/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Xian/Building/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Xian/Cracker/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Xian/Cracker/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Xian/Cracker/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Xian/Cracker/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Xian/Cracker/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Xian/Cracker/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Xian/Cracker/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Xian/Cracker/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Xian/Islands/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Xian/Islands/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Xian/Islands/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Xian/Islands/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Xian/Islands/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Xian/Islands/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Xian/Islands/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Xian/Islands/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Xian/Lamp/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Xian/Lamp/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Xian/Lamp/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Xian/Lamp/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Xian/Lamp/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Xian/Lamp/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Xian/Lamp/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Xian/Lamp/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Xian/Lava/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Xian/Lava/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Xian/Lava/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Xian/Lava/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Xian/Lava/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Xian/Lava/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Xian/Lava/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Xian/Lava/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Xian/Metal/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Xian/Metal/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Xian/Metal/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Xian/Metal/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Xian/Metal/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Xian/Metal/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Xian/Metal/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Xian/Metal/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Xian/Rock/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Xian/Rock/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Xian/Rock/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Xian/Rock/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Xian/Rock/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Xian/Rock/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Xian/Rock/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Xian/Rock/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Xian/Sky/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Xian/Sky/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Xian/Sky/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Xian/Sky/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Xian/Sky/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Xian/Sky/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Xian/Sky/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Xian/Sky/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Xian/Stone/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Xian/Stone/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Xian/Stone/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Xian/Stone/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Xian/Stone/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Xian/Stone/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Xian/Stone/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Xian/Stone/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Xian/Tree/Data.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Xian/Tree/Data.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Xian/Tree/Data.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Xian/Tree/Data.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/Xian/Tree/Segments.png b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/Xian/Tree/Segments.png similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/Xian/Tree/Segments.png rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/Xian/Tree/Segments.png diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/entity_lookup.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/entity_lookup.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/entity_lookup.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/entity_lookup.json diff --git a/TR2RandomizerCore/Resources/Textures/Source/Static/global_grouping.json b/TRRandomizerCore/Resources/TR2/Textures/Source/Static/global_grouping.json similarity index 100% rename from TR2RandomizerCore/Resources/Textures/Source/Static/global_grouping.json rename to TRRandomizerCore/Resources/TR2/Textures/Source/Static/global_grouping.json diff --git a/TR2RandomizerCore/Resources/Zones/BOAT.TR2-Zones.json b/TRRandomizerCore/Resources/TR2/Zones/BOAT.TR2-Zones.json similarity index 100% rename from TR2RandomizerCore/Resources/Zones/BOAT.TR2-Zones.json rename to TRRandomizerCore/Resources/TR2/Zones/BOAT.TR2-Zones.json diff --git a/TR2RandomizerCore/Resources/Zones/CATACOMB.TR2-Zones.json b/TRRandomizerCore/Resources/TR2/Zones/CATACOMB.TR2-Zones.json similarity index 100% rename from TR2RandomizerCore/Resources/Zones/CATACOMB.TR2-Zones.json rename to TRRandomizerCore/Resources/TR2/Zones/CATACOMB.TR2-Zones.json diff --git a/TR2RandomizerCore/Resources/Zones/DECK.TR2-Zones.json b/TRRandomizerCore/Resources/TR2/Zones/DECK.TR2-Zones.json similarity index 100% rename from TR2RandomizerCore/Resources/Zones/DECK.TR2-Zones.json rename to TRRandomizerCore/Resources/TR2/Zones/DECK.TR2-Zones.json diff --git a/TR2RandomizerCore/Resources/Zones/EMPRTOMB.TR2-Zones.json b/TRRandomizerCore/Resources/TR2/Zones/EMPRTOMB.TR2-Zones.json similarity index 100% rename from TR2RandomizerCore/Resources/Zones/EMPRTOMB.TR2-Zones.json rename to TRRandomizerCore/Resources/TR2/Zones/EMPRTOMB.TR2-Zones.json diff --git a/TR2RandomizerCore/Resources/Zones/FLOATING.TR2-Zones.json b/TRRandomizerCore/Resources/TR2/Zones/FLOATING.TR2-Zones.json similarity index 100% rename from TR2RandomizerCore/Resources/Zones/FLOATING.TR2-Zones.json rename to TRRandomizerCore/Resources/TR2/Zones/FLOATING.TR2-Zones.json diff --git a/TR2RandomizerCore/Resources/Zones/HOUSE.TR2-Zones.json b/TRRandomizerCore/Resources/TR2/Zones/HOUSE.TR2-Zones.json similarity index 100% rename from TR2RandomizerCore/Resources/Zones/HOUSE.TR2-Zones.json rename to TRRandomizerCore/Resources/TR2/Zones/HOUSE.TR2-Zones.json diff --git a/TR2RandomizerCore/Resources/Zones/ICECAVE.TR2-Zones.json b/TRRandomizerCore/Resources/TR2/Zones/ICECAVE.TR2-Zones.json similarity index 100% rename from TR2RandomizerCore/Resources/Zones/ICECAVE.TR2-Zones.json rename to TRRandomizerCore/Resources/TR2/Zones/ICECAVE.TR2-Zones.json diff --git a/TR2RandomizerCore/Resources/Zones/KEEL.TR2-Zones.json b/TRRandomizerCore/Resources/TR2/Zones/KEEL.TR2-Zones.json similarity index 100% rename from TR2RandomizerCore/Resources/Zones/KEEL.TR2-Zones.json rename to TRRandomizerCore/Resources/TR2/Zones/KEEL.TR2-Zones.json diff --git a/TR2RandomizerCore/Resources/Zones/LIVING.TR2-Zones.json b/TRRandomizerCore/Resources/TR2/Zones/LIVING.TR2-Zones.json similarity index 100% rename from TR2RandomizerCore/Resources/Zones/LIVING.TR2-Zones.json rename to TRRandomizerCore/Resources/TR2/Zones/LIVING.TR2-Zones.json diff --git a/TR2RandomizerCore/Resources/Zones/MONASTRY.TR2-Zones.json b/TRRandomizerCore/Resources/TR2/Zones/MONASTRY.TR2-Zones.json similarity index 100% rename from TR2RandomizerCore/Resources/Zones/MONASTRY.TR2-Zones.json rename to TRRandomizerCore/Resources/TR2/Zones/MONASTRY.TR2-Zones.json diff --git a/TR2RandomizerCore/Resources/Zones/OPERA.TR2-Zones.json b/TRRandomizerCore/Resources/TR2/Zones/OPERA.TR2-Zones.json similarity index 100% rename from TR2RandomizerCore/Resources/Zones/OPERA.TR2-Zones.json rename to TRRandomizerCore/Resources/TR2/Zones/OPERA.TR2-Zones.json diff --git a/TR2RandomizerCore/Resources/Zones/PLATFORM.TR2-Zones.json b/TRRandomizerCore/Resources/TR2/Zones/PLATFORM.TR2-Zones.json similarity index 100% rename from TR2RandomizerCore/Resources/Zones/PLATFORM.TR2-Zones.json rename to TRRandomizerCore/Resources/TR2/Zones/PLATFORM.TR2-Zones.json diff --git a/TR2RandomizerCore/Resources/Zones/RIG.TR2-Zones.json b/TRRandomizerCore/Resources/TR2/Zones/RIG.TR2-Zones.json similarity index 100% rename from TR2RandomizerCore/Resources/Zones/RIG.TR2-Zones.json rename to TRRandomizerCore/Resources/TR2/Zones/RIG.TR2-Zones.json diff --git a/TR2RandomizerCore/Resources/Zones/SKIDOO.TR2-Zones.json b/TRRandomizerCore/Resources/TR2/Zones/SKIDOO.TR2-Zones.json similarity index 100% rename from TR2RandomizerCore/Resources/Zones/SKIDOO.TR2-Zones.json rename to TRRandomizerCore/Resources/TR2/Zones/SKIDOO.TR2-Zones.json diff --git a/TR2RandomizerCore/Resources/Zones/UNWATER.TR2-Zones.json b/TRRandomizerCore/Resources/TR2/Zones/UNWATER.TR2-Zones.json similarity index 100% rename from TR2RandomizerCore/Resources/Zones/UNWATER.TR2-Zones.json rename to TRRandomizerCore/Resources/TR2/Zones/UNWATER.TR2-Zones.json diff --git a/TR2RandomizerCore/Resources/Zones/VENICE.TR2-Zones.json b/TRRandomizerCore/Resources/TR2/Zones/VENICE.TR2-Zones.json similarity index 100% rename from TR2RandomizerCore/Resources/Zones/VENICE.TR2-Zones.json rename to TRRandomizerCore/Resources/TR2/Zones/VENICE.TR2-Zones.json diff --git a/TR2RandomizerCore/Resources/Zones/WALL.TR2-Zones.json b/TRRandomizerCore/Resources/TR2/Zones/WALL.TR2-Zones.json similarity index 100% rename from TR2RandomizerCore/Resources/Zones/WALL.TR2-Zones.json rename to TRRandomizerCore/Resources/TR2/Zones/WALL.TR2-Zones.json diff --git a/TR2RandomizerCore/Resources/Zones/XIAN.TR2-Zones.json b/TRRandomizerCore/Resources/TR2/Zones/XIAN.TR2-Zones.json similarity index 100% rename from TR2RandomizerCore/Resources/Zones/XIAN.TR2-Zones.json rename to TRRandomizerCore/Resources/TR2/Zones/XIAN.TR2-Zones.json diff --git a/TRRandomizerCore/Resources/TR3/Audio/audio_tracks.json b/TRRandomizerCore/Resources/TR3/Audio/audio_tracks.json new file mode 100644 index 000000000..c3948a91b --- /dev/null +++ b/TRRandomizerCore/Resources/TR3/Audio/audio_tracks.json @@ -0,0 +1,1108 @@ +{ + "WAD": "tr3audio.wad", + "Tracks": [ + { + "ID": 0, + "Name": "Blank", + "Offset": 0, + "Length": 0, + "Categories": [ + 0 + ] + }, + { + "ID": 2, + "Name": "The Puzzle Element", + "Offset": 0, + "Length": 4838648, + "Categories": [ + 1, + 2 + ] + }, + { + "ID": 3, + "Name": "No Waiting Around 1", + "Offset": 4838648, + "Length": 4331910, + "Categories": [ + 1, + 2 + ] + }, + { + "ID": 4, + "Name": "Something Spooky is in that Jungle", + "Offset": 9170558, + "Length": 3945394, + "Categories": [ + 1, + 2 + ] + }, + { + "ID": 5, + "Name": "Lara's Themes", + "Offset": 13115952, + "Length": 3854906, + "Categories": [ + 2 + ] + }, + { + "ID": 6, + "Name": "The Cavern Sewers", + "Offset": 16970858, + "Length": 3801904, + "Categories": [ + 1, + 2 + ] + }, + { + "ID": 7, + "Name": "Geordie Bob", + "Offset": 20772762, + "Length": 3795442, + "Categories": [ + 1, + 2 + ] + }, + { + "ID": 8, + "Name": "Tony (The Loon)", + "Offset": 24568204, + "Length": 3114190, + "Categories": [ + 1, + 2 + ] + }, + { + "ID": 9, + "Name": "No Waiting Around 2", + "Offset": 27682394, + "Length": 2187324, + "Categories": [ + 1, + 2 + ] + }, + { + "ID": 10, + "Name": "The Greedy Mob", + "Offset": 29869718, + "Length": 1721952, + "Categories": [ + 1, + 3 + ] + }, + { + "ID": 11, + "Name": "A Long Way Up", + "Offset": 31591670, + "Length": 1374218, + "Categories": [ + 1 + ] + }, + { + "ID": 12, + "Name": "No Waiting Around 3", + "Offset": 32965888, + "Length": 1344484, + "Categories": [ + 1, + 2 + ] + }, + { + "ID": 13, + "Name": "There Be Butterflies Here 2", + "Offset": 34310372, + "Length": 1334144, + "Categories": [ + 1 + ] + }, + { + "ID": 14, + "Name": "She's Cool", + "Offset": 35644516, + "Length": 1106628, + "Categories": [ + 1, + 2 + ] + }, + { + "ID": 15, + "Name": "Mind the Gap 2", + "Offset": 36751144, + "Length": 1023896, + "Categories": [ + 1, + 2 + ] + }, + { + "ID": 16, + "Name": "Around the Corner 2", + "Offset": 37775040, + "Length": 859724, + "Categories": [ + 1 + ] + }, + { + "ID": 17, + "Name": "Around the Corner 1", + "Offset": 38634764, + "Length": 840332, + "Categories": [ + 1 + ] + }, + { + "ID": 18, + "Name": "Kneel and Pray", + "Offset": 39475096, + "Length": 778284, + "Categories": [ + 1 + ] + }, + { + "ID": 19, + "Name": "Around the Corner 4", + "Offset": 40253380, + "Length": 767942, + "Categories": [ + 1 + ] + }, + { + "ID": 20, + "Name": "Around the Corner 3", + "Offset": 41021322, + "Length": 690380, + "Categories": [ + 1 + ] + }, + { + "ID": 21, + "Name": "Seeing is Believing 1", + "Offset": 41711702, + "Length": 615404, + "Categories": [ + 1 + ] + }, + { + "ID": 22, + "Name": "Look What We Have Here 3", + "Offset": 42327106, + "Length": 601184, + "Categories": [ + 1 + ] + }, + { + "ID": 23, + "Name": "There Be Butterflies Here 4", + "Offset": 42928290, + "Length": 586962, + "Categories": [ + 1 + ] + }, + { + "ID": 24, + "Name": "Stone the Crows 10", + "Offset": 43515252, + "Length": 584378, + "Categories": [ + 1 + ] + }, + { + "ID": 25, + "Name": "There Be Butterflies Here 3", + "Offset": 44099630, + "Length": 574036, + "Categories": [ + 1 + ] + }, + { + "ID": 26, + "Name": "Meteorite Cavern", + "Offset": 44673666, + "Length": 5874100, + "Categories": [ + 1, + 3 + ] + }, + { + "ID": 27, + "Name": "Steady", + "Offset": 50547766, + "Length": 5138554, + "Categories": [ + 1, + 3 + ] + }, + { + "ID": 28, + "Name": "Antarctica", + "Offset": 55686320, + "Length": 4661550, + "Categories": [ + 1, + 3 + ] + }, + { + "ID": 29, + "Name": "Things", + "Offset": 60347870, + "Length": 3538194, + "Categories": [ + 1, + 3 + ] + }, + { + "ID": 30, + "Name": "Anyone There", + "Offset": 63886064, + "Length": 3308094, + "Categories": [ + 1, + 3 + ] + }, + { + "ID": 31, + "Name": "Grotto", + "Offset": 67194158, + "Length": 3297752, + "Categories": [ + 1, + 3 + ] + }, + { + "ID": 32, + "Name": "On the Beach", + "Offset": 70491910, + "Length": 2946138, + "Categories": [ + 1, + 3 + ] + }, + { + "ID": 33, + "Name": "Gamma Pals", + "Offset": 73438048, + "Length": 2778088, + "Categories": [ + 1, + 3 + ] + }, + { + "ID": 34, + "Name": "In the Jungle", + "Offset": 76216136, + "Length": 2540230, + "Categories": [ + 1, + 3 + ] + }, + { + "ID": 35, + "Name": "Piranha Waters", + "Offset": 78756366, + "Length": 2471718, + "Categories": [ + 1, + 3 + ] + }, + { + "ID": 36, + "Name": "The Rapids", + "Offset": 81228084, + "Length": 1847344, + "Categories": [ + 1, + 3 + ] + }, + { + "ID": 37, + "Name": "Supper Time", + "Offset": 83075428, + "Length": 1605610, + "Categories": [ + 1, + 3 + ] + }, + { + "ID": 38, + "Name": "Look out 5", + "Offset": 84681038, + "Length": 527500, + "Categories": [ + 1 + ] + }, + { + "ID": 39, + "Name": "Look What We Have Here 1", + "Offset": 85208538, + "Length": 496474, + "Categories": [ + 1 + ] + }, + { + "ID": 40, + "Name": "Around the Corner 5", + "Offset": 85705012, + "Length": 488718, + "Categories": [ + 1 + ] + }, + { + "ID": 41, + "Name": "Seeing is Believing 2", + "Offset": 86193730, + "Length": 458986, + "Categories": [ + 1 + ] + }, + { + "ID": 42, + "Name": "Stone the Crows 9", + "Offset": 86652716, + "Length": 453816, + "Categories": [ + 1 + ] + }, + { + "ID": 43, + "Name": "Look out 8", + "Offset": 87106532, + "Length": 363326, + "Categories": [ + 1 + ] + }, + { + "ID": 44, + "Name": "Look out 4", + "Offset": 87469858, + "Length": 354278, + "Categories": [ + 1 + ] + }, + { + "ID": 45, + "Name": "Stone the Crows 7", + "Offset": 87824136, + "Length": 162958, + "Categories": [ + 1 + ] + }, + { + "ID": 46, + "Name": "Stone the Crows 3", + "Offset": 87987094, + "Length": 323254, + "Categories": [ + 1 + ] + }, + { + "ID": 47, + "Name": "Stone the Crows 8", + "Offset": 88310348, + "Length": 307740, + "Categories": [ + 1 + ] + }, + { + "ID": 48, + "Name": "Look What We Have Here 2", + "Offset": 88618088, + "Length": 299984, + "Categories": [ + 1 + ] + }, + { + "ID": 49, + "Name": "Stone the Crows 4", + "Offset": 88918072, + "Length": 288350, + "Categories": [ + 1 + ] + }, + { + "ID": 50, + "Name": "Stone the Crows 6", + "Offset": 89206422, + "Length": 288350, + "Categories": [ + 1 + ] + }, + { + "ID": 51, + "Name": "Look out 3", + "Offset": 89494772, + "Length": 254740, + "Categories": [ + 1 + ] + }, + { + "ID": 52, + "Name": "Look out 1", + "Offset": 89749512, + "Length": 237936, + "Categories": [ + 1 + ] + }, + { + "ID": 53, + "Name": "There Be Butterflies Here 1", + "Offset": 89987448, + "Length": 210788, + "Categories": [ + 1 + ] + }, + { + "ID": 54, + "Name": "Stone the Crows 1", + "Offset": 90198236, + "Length": 201740, + "Categories": [ + 1 + ] + }, + { + "ID": 55, + "Name": "Stone the Crows 5", + "Offset": 90399976, + "Length": 165544, + "Categories": [ + 1 + ] + }, + { + "ID": 56, + "Name": "Mind the Gap 1", + "Offset": 90565520, + "Length": 159080, + "Categories": [ + 1 + ] + }, + { + "ID": 57, + "Name": "There Be Butterflies Here 5", + "Offset": 90724600, + "Length": 140982, + "Categories": [ + 1 + ] + }, + { + "ID": 58, + "Name": "Look out 2", + "Offset": 90865582, + "Length": 140982, + "Categories": [ + 1 + ] + }, + { + "ID": 59, + "Name": "Look out 7", + "Offset": 91006564, + "Length": 140982, + "Categories": [ + 1 + ] + }, + { + "ID": 60, + "Name": "Stone the Crows 2", + "Offset": 91147546, + "Length": 140982, + "Categories": [ + 1 + ] + }, + { + "ID": 61, + "Name": "Look out 6", + "Offset": 91288528, + "Length": 140982, + "Categories": [ + 1 + ] + }, + { + "ID": 62, + "Name": "Scott's Hut", + "Offset": 91429510, + "Length": 3874296, + "Categories": [ + 5 + ] + }, + { + "ID": 63, + "Name": "Cavern Sewers", + "Offset": 95303806, + "Length": 3801904, + "Categories": [ + 5 + ] + }, + { + "ID": 64, + "Name": "Jungle Camp", + "Offset": 99105710, + "Length": 3114190, + "Categories": [ + 5 + ] + }, + { + "ID": 65, + "Name": "Worship Room", + "Offset": 102219900, + "Length": 2787136, + "Categories": [ + 5 + ] + }, + { + "ID": 66, + "Name": "Cavern", + "Offset": 105007036, + "Length": 2675964, + "Categories": [ + 5 + ] + }, + { + "ID": 67, + "Name": "Rooftops", + "Offset": 107683000, + "Length": 2546694, + "Categories": [ + 5 + ] + }, + { + "ID": 68, + "Name": "Tree Shack", + "Offset": 110229694, + "Length": 2538938, + "Categories": [ + 5 + ] + }, + { + "ID": 69, + "Name": "Temple Exit", + "Offset": 112768632, + "Length": 1724538, + "Categories": [ + 5 + ] + }, + { + "ID": 70, + "Name": "Delivery Truck", + "Offset": 114493170, + "Length": 1353534, + "Categories": [ + 5 + ] + }, + { + "ID": 71, + "Name": "Penthouse", + "Offset": 115846704, + "Length": 1203580, + "Categories": [ + 5 + ] + }, + { + "ID": 72, + "Name": "Ravine", + "Offset": 117050284, + "Length": 1109214, + "Categories": [ + 1 + ] + }, + { + "ID": 73, + "Name": "Old Smokey", + "Offset": 118159498, + "Length": 3759246, + "Categories": [ + 3 + ] + }, + { + "ID": 74, + "Name": "Under Smokey", + "Offset": 121918744, + "Length": 4718464, + "Categories": [ + 3 + ] + }, + { + "ID": 75, + "Name": "Refining Plant", + "Offset": 126637208, + "Length": 4658962, + "Categories": [ + 1 + ] + }, + { + "ID": 76, + "Name": "Rumble Sub", + "Offset": 131296170, + "Length": 3295166, + "Categories": [ + 1 + ] + }, + { + "ID": 77, + "Name": "Quake", + "Offset": 134591336, + "Length": 2767746, + "Categories": [ + 1 + ] + }, + { + "ID": 78, + "Name": "Blank", + "Offset": 137359082, + "Length": 140982, + "Categories": [ + 1 + ] + }, + { + "ID": 82, + "Name": "Excellent", + "Offset": 137500064, + "Length": 18176, + "Categories": [ + 1 + ] + }, + { + "ID": 83, + "Name": "That's Great", + "Offset": 137518240, + "Length": 20762, + "Categories": [ + 1 + ] + }, + { + "ID": 84, + "Name": "Training 1", + "Offset": 137539002, + "Length": 41444, + "Categories": [ + 1 + ] + }, + { + "ID": 85, + "Name": "Training 2", + "Offset": 137580446, + "Length": 44030, + "Categories": [ + 1 + ] + }, + { + "ID": 86, + "Name": "Training 3", + "Offset": 137624476, + "Length": 45324, + "Categories": [ + 1 + ] + }, + { + "ID": 87, + "Name": "Training 4", + "Offset": 137669800, + "Length": 47908, + "Categories": [ + 1 + ] + }, + { + "ID": 88, + "Name": "Training 5", + "Offset": 137717708, + "Length": 49202, + "Categories": [ + 1 + ] + }, + { + "ID": 89, + "Name": "Fancy a Swim?", + "Offset": 137766910, + "Length": 54372, + "Categories": [ + 1 + ] + }, + { + "ID": 90, + "Name": "Let's Go Outside", + "Offset": 137821282, + "Length": 55664, + "Categories": [ + 1 + ] + }, + { + "ID": 91, + "Name": "Hey", + "Offset": 137876946, + "Length": 55664, + "Categories": [ + 1 + ] + }, + { + "ID": 92, + "Name": "Now it's Time...", + "Offset": 137932610, + "Length": 58250, + "Categories": [ + 1 + ] + }, + { + "ID": 93, + "Name": "Training 6", + "Offset": 137990860, + "Length": 67298, + "Categories": [ + 1 + ] + }, + { + "ID": 94, + "Name": "Training 7", + "Offset": 138058158, + "Length": 78934, + "Categories": [ + 1 + ] + }, + { + "ID": 95, + "Name": "Gosh", + "Offset": 138137092, + "Length": 81518, + "Categories": [ + 1 + ] + }, + { + "ID": 96, + "Name": "Training 8", + "Offset": 138218610, + "Length": 81518, + "Categories": [ + 1 + ] + }, + { + "ID": 97, + "Name": "Training 9", + "Offset": 138300128, + "Length": 94446, + "Categories": [ + 1 + ] + }, + { + "ID": 98, + "Name": "Training 10", + "Offset": 138394574, + "Length": 98322, + "Categories": [ + 1 + ] + }, + { + "ID": 99, + "Name": "Training 11", + "Offset": 138492896, + "Length": 102202, + "Categories": [ + 1 + ] + }, + { + "ID": 100, + "Name": "Training 12", + "Offset": 138595098, + "Length": 106080, + "Categories": [ + 1 + ] + }, + { + "ID": 101, + "Name": "Welcome Back", + "Offset": 138701178, + "Length": 106080, + "Categories": [ + 1 + ] + }, + { + "ID": 102, + "Name": "Training 13", + "Offset": 138807258, + "Length": 113836, + "Categories": [ + 1 + ] + }, + { + "ID": 103, + "Name": "Training 14", + "Offset": 138921094, + "Length": 121592, + "Categories": [ + 1 + ] + }, + { + "ID": 104, + "Name": "Training 15", + "Offset": 139042686, + "Length": 125470, + "Categories": [ + 1 + ] + }, + { + "ID": 105, + "Name": "Training 16", + "Offset": 139168156, + "Length": 137104, + "Categories": [ + 1 + ] + }, + { + "ID": 106, + "Name": "Training 17", + "Offset": 139305260, + "Length": 140982, + "Categories": [ + 1 + ] + }, + { + "ID": 107, + "Name": "Training 18", + "Offset": 139446242, + "Length": 144860, + "Categories": [ + 1 + ] + }, + { + "ID": 108, + "Name": "Training 19", + "Offset": 139591102, + "Length": 183642, + "Categories": [ + 1 + ] + }, + { + "ID": 109, + "Name": "Training 20", + "Offset": 139774744, + "Length": 250862, + "Categories": [ + 1 + ] + }, + { + "ID": 110, + "Name": "Training 21", + "Offset": 140025606, + "Length": 257326, + "Categories": [ + 1 + ] + }, + { + "ID": 111, + "Name": "Training 22", + "Offset": 140282932, + "Length": 289644, + "Categories": [ + 1 + ] + }, + { + "ID": 112, + "Name": "Training 23", + "Offset": 140572576, + "Length": 316788, + "Categories": [ + 1 + ] + }, + { + "ID": 113, + "Name": "Training 24", + "Offset": 140889364, + "Length": 355570, + "Categories": [ + 1 + ] + }, + { + "ID": 114, + "Name": "Training 25", + "Offset": 141244934, + "Length": 404694, + "Categories": [ + 1 + ] + }, + { + "ID": 115, + "Name": "Training 26", + "Offset": 141649628, + "Length": 422790, + "Categories": [ + 1 + ] + }, + { + "ID": 116, + "Name": "Training 27", + "Offset": 142072418, + "Length": 438304, + "Categories": [ + 1 + ] + }, + { + "ID": 117, + "Name": "Training 28", + "Offset": 142510722, + "Length": 462864, + "Categories": [ + 1 + ] + }, + { + "ID": 118, + "Name": "Training 29", + "Offset": 142973586, + "Length": 477084, + "Categories": [ + 1 + ] + }, + { + "ID": 119, + "Name": "Training 30", + "Offset": 143450670, + "Length": 524914, + "Categories": [ + 1 + ] + }, + { + "ID": 120, + "Name": "In the Hut", + "Offset": 143975584, + "Length": 4661550, + "Categories": [ + 3 + ] + }, + { + "ID": 121, + "Name": "And so on...", + "Offset": 148637134, + "Length": 2241616, + "Categories": [ + 1 + ] + }, + { + "ID": 122, + "Name": "Secret 1", + "Offset": 150878750, + "Length": 179762, + "Categories": [ + 4 + ] + }, + { + "ID": 123, + "Name": "Secret 2", + "Offset": 151058512, + "Length": 179762, + "Categories": [ + 4 + ] + } + ] +} \ No newline at end of file diff --git a/TRRandomizerCore/Resources/TR3/Locations/unarmed_locations.json b/TRRandomizerCore/Resources/TR3/Locations/unarmed_locations.json new file mode 100644 index 000000000..6f073ae89 --- /dev/null +++ b/TRRandomizerCore/Resources/TR3/Locations/unarmed_locations.json @@ -0,0 +1,222 @@ +{ + "JUNGLE.TR2": [ + { + "X": 31201, + "Y": -1243, + "Z": 28137, + "Room": 4 + }, + { + "X": 29173, + "Y": 25209, + "Z": 63002, + "Room": 147 + }, + { + "X": 29173, + "Y": 27136, + "Z": 67068, + "Room": 147 + }, + { + "X": 34354, + "Y": 27276, + "Z": 70109, + "Room": 147 + }, + { + "X": 34231, + "Y": 27245, + "Z": 73262, + "Room": 147 + }, + { + "X": 31183, + "Y": 26342, + "Z": 80439, + "Room": 31 + }, + { + "X": 25087, + "Y": -256, + "Z": 28163, + "Room": 4 + }, + { + "X": 24045, + "Y": 106, + "Z": 30292, + "Room": 4 + }, + { + "X": 24114, + "Y": 1024, + "Z": 33229, + "Room": 4 + }, + { + "X": 25898, + "Y": 5450, + "Z": 39618, + "Room": 21 + }, + { + "X": 29099, + "Y": 5790, + "Z": 40465, + "Room": 20 + } + ], + "TEMPLE.TR2": [ + { + "X": 91845, + "Y": -256, + "Z": 24873, + "Room": 18 + } + ], + "QUADCHAS.TR2": [ + { + "X": 82425, + "Y": -256, + "Z": 59869, + "Room": 1 + } + ], + "TONYBOSS.TR2": [ + { + "X": 9688, + "Y": -15360, + "Z": 49664, + "Room": 9 + } + ], + "SHORE.TR2": [ + { + "X": 21992, + "Y": 3328, + "Z": 27121, + "Room": 7 + } + ], + "CRASH.TR2": [ + { + "X": 33289, + "Y": -1784, + "Z": 73177, + "Room": 93 + } + ], + "RAPIDS.TR2": [ + { + "X": 76311, + "Y": -26112, + "Z": 48662, + "Room": 50 + } + ], + "TRIBOSS.TR2": [ + { + "X": 46616, + "Y": -9728, + "Z": 52772, + "Room": 23 + } + ], + "ROOFS.TR2": [ + { + "X": 38382, + "Y": -21504, + "Z": 45894, + "Room": 25 + } + ], + "SEWER.TR2": [ + { + "X": 72208, + "Y": 1024, + "Z": 98539, + "Room": 21 + } + ], + "TOWER.TR2": [ + { + "X": 71145, + "Y": -15616, + "Z": 34322, + "Room": 141 + } + ], + "OFFICE.TR2": [ + { + "X": 52708, + "Y": 0, + "Z": 44516, + "Room": 19 + } + ], + "NEVADA.TR2": [ + { + "X": 30109, + "Y": -128, + "Z": 25090, + "Room": 6 + } + ], + "COMPOUND.TR2": [ + { + "X": 76288, + "Y": 512, + "Z": 51712, + "Room": 167 + } + ], + "AREA51.TR2": [ + { + "X": 63982, + "Y": 2048, + "Z": 50637, + "Room": 31 + } + ], + "ANTARC.TR2": [ + { + "X": 38633, + "Y": -5120, + "Z": 10529, + "Room": 64 + } + ], + "MINES.TR2": [ + { + "X": 56767, + "Y": -512, + "Z": 22103, + "Room": 47 + } + ], + "CITY.TR2": [ + { + "X": 94741, + "Y": -256, + "Z": 75976, + "Room": 15 + } + ], + "CHAMBER.TR2": [ + { + "X": 62044, + "Y": -512, + "Z": 61990, + "Room": 5 + } + ], + "STPAUL.TR2": [ + { + "X": 45508, + "Y": -9216, + "Z": 56002, + "Room": 48 + } + ] +} \ No newline at end of file diff --git a/TR2RandomizerCore/SFX/TRSFXCreatureCategory.cs b/TRRandomizerCore/SFX/TRSFXCreatureCategory.cs similarity index 76% rename from TR2RandomizerCore/SFX/TRSFXCreatureCategory.cs rename to TRRandomizerCore/SFX/TRSFXCreatureCategory.cs index dfdd368d0..9e04acb08 100644 --- a/TR2RandomizerCore/SFX/TRSFXCreatureCategory.cs +++ b/TRRandomizerCore/SFX/TRSFXCreatureCategory.cs @@ -1,4 +1,4 @@ -namespace TR2RandomizerCore.SFX +namespace TRRandomizerCore.SFX { public enum TRSFXCreatureCategory { diff --git a/TR2RandomizerCore/SFX/TRSFXDefinition.cs b/TRRandomizerCore/SFX/TRSFXDefinition.cs similarity index 97% rename from TR2RandomizerCore/SFX/TRSFXDefinition.cs rename to TRRandomizerCore/SFX/TRSFXDefinition.cs index 1f4f73bb4..8717cd74d 100644 --- a/TR2RandomizerCore/SFX/TRSFXDefinition.cs +++ b/TRRandomizerCore/SFX/TRSFXDefinition.cs @@ -3,7 +3,7 @@ using System.Text; using TRLevelReader.Model; -namespace TR2RandomizerCore.SFX +namespace TRRandomizerCore.SFX { public class TRSFXDefinition { diff --git a/TR2RandomizerCore/SFX/TRSFXGeneralCategory.cs b/TRRandomizerCore/SFX/TRSFXGeneralCategory.cs similarity index 94% rename from TR2RandomizerCore/SFX/TRSFXGeneralCategory.cs rename to TRRandomizerCore/SFX/TRSFXGeneralCategory.cs index 8221e089d..21544288b 100644 --- a/TR2RandomizerCore/SFX/TRSFXGeneralCategory.cs +++ b/TRRandomizerCore/SFX/TRSFXGeneralCategory.cs @@ -1,4 +1,4 @@ -namespace TR2RandomizerCore.SFX +namespace TRRandomizerCore.SFX { public enum TRSFXGeneralCategory { diff --git a/TR2RandomizerCore/TR2RandomizerController.cs b/TRRandomizerCore/TRRandomizerController.cs similarity index 88% rename from TR2RandomizerCore/TR2RandomizerController.cs rename to TRRandomizerCore/TRRandomizerController.cs index c9071d6b2..59cc2302e 100644 --- a/TR2RandomizerCore/TR2RandomizerController.cs +++ b/TRRandomizerCore/TRRandomizerController.cs @@ -1,30 +1,70 @@ using System; -using System.Collections.Generic; using System.IO; -using TR2RandomizerCore.Globalisation; -using TR2RandomizerCore.Helpers; -using TR2RandomizerCore.Randomizers; +using TRRandomizerCore.Editors; +using TRRandomizerCore.Globalisation; +using TRRandomizerCore.Helpers; +using TRRandomizerCore.Randomizers; using TRGE.Coord; using TRGE.Core; +using System.Collections.Generic; -namespace TR2RandomizerCore +namespace TRRandomizerCore { - public class TR2RandomizerController + public class TRRandomizerController { + // Only the versions defined in this dictionary can be opened for randomization. The supported type list is an indicator + // to callers as to what can be applied during randomization i.e. for UI options to be enabled/disabled appropriately. + // Once all randomizers for a particular version have been implemented, simply add TRRandomizerType.All against the version + // as per TR2. + private static readonly Dictionary> _supportedTypes = new Dictionary> + { + [TRVersion.TR2] = new List + { + TRRandomizerType.All + }, + [TRVersion.TR3] = new List + { + TRRandomizerType.LevelSequence, TRRandomizerType.Unarmed, TRRandomizerType.Ammoless, TRRandomizerType.Audio + } + }; + private readonly TREditor _editor; internal TR23ScriptEditor ScriptEditor => _editor.ScriptEditor as TR23ScriptEditor; - internal TR2LevelRandomizer LevelRandomizer => _editor.LevelEditor as TR2LevelRandomizer; + internal RandomizerSettings LevelRandomizer => (_editor.LevelEditor as ISettingsProvider).Settings; - internal TR2RandomizerController(string directoryPath) + internal TRRandomizerController(string directoryPath) { // If there is a checksum mismatch, we will just ignore the previous backup and open the folder afresh _editor = TRCoord.Instance.Open(directoryPath, TRScriptOpenOption.DiscardBackup); _editor.SaveProgressChanged += Editor_SaveProgressChanged; _editor.RestoreProgressChanged += Editor_RestoreProgressChanged; StoreExternalOrganisations(); + + if (!IsRandomizationSupported()) + { + throw new NotSupportedException(string.Format("Randomization of {0} is not currently supported.", EditionTitle)); + } } + #region Version Support + public bool IsRandomizationSupported() + { + return _supportedTypes.ContainsKey(ScriptEditor.Edition.Version); + } + + public bool IsRandomizationSupported(TRRandomizerType randomizerType) + { + return IsRandomizationSupported(ScriptEditor.Edition.Version, randomizerType); + } + + public bool IsRandomizationSupported(TRVersion version, TRRandomizerType randomizerType) + { + return _supportedTypes.ContainsKey(version) && + (_supportedTypes[version].Contains(TRRandomizerType.All) || _supportedTypes[version].Contains(randomizerType)); + } + #endregion + #region ScriptEditor Passthrough private Organisation _extLevelOrganisation, _extPlayableOrganisation, _extUnarmedOrganisation, _extAmmolessOrganisation, _extSecretRewardsOrganisation, _extSunsetOrganisation, _extAudioOrganisation; @@ -45,6 +85,9 @@ private void StoreExternalOrganisations() } public int LevelCount => ScriptEditor.ScriptedLevels.Count; + public int DefaultUnarmedLevelCount => ScriptEditor.Edition.UnarmedLevelCount; + public int DefaultAmmolessLevelCount => ScriptEditor.Edition.AmmolessLevelCount; + public int DefaultSunsetCount => ScriptEditor.Edition.SunsetLevelCount; public bool RandomizeLevelSequencing { @@ -424,7 +467,7 @@ public uint NightModeDarkness set => LevelRandomizer.NightModeDarkness = value; } - public uint NightModeDarknessRange => NightModeRandomizer.DarknessRange; + public uint NightModeDarknessRange => TR2NightModeRandomizer.DarknessRange; public bool NightModeAssaultCourse { diff --git a/TR2RandomizerCore/TR2RandomizerCoord.cs b/TRRandomizerCore/TRRandomizerCoord.cs similarity index 75% rename from TR2RandomizerCore/TR2RandomizerCoord.cs rename to TRRandomizerCore/TRRandomizerCoord.cs index be27edb41..945508961 100644 --- a/TR2RandomizerCore/TR2RandomizerCoord.cs +++ b/TRRandomizerCore/TRRandomizerCoord.cs @@ -1,23 +1,23 @@ using System; using System.Collections.Generic; -using TR2RandomizerCore.Helpers; -using TR2RandomizerCore.Randomizers; +using TRRandomizerCore.Editors; +using TRRandomizerCore.Helpers; using TRGE.Coord; using TRGE.Core; -namespace TR2RandomizerCore +namespace TRRandomizerCore { - public class TR2RandomizerCoord + public class TRRandomizerCoord { - private static TR2RandomizerCoord _instance; + private static TRRandomizerCoord _instance; - public static TR2RandomizerCoord Instance + public static TRRandomizerCoord Instance { get { if (_instance == null) { - _instance = new TR2RandomizerCoord(); + _instance = new TRRandomizerCoord(); } return _instance; } @@ -32,7 +32,7 @@ public static TR2RandomizerCoord Instance public string ConfigDirectory => TRCoord.Instance.ConfigDirectory; public string ConfigFilePath => TRCoord.Instance.ConfigFilePath; - private TR2RandomizerCoord() { } + private TRRandomizerCoord() { } private void TRCoord_HistoryChanged(object sender, EventArgs e) { @@ -59,8 +59,14 @@ public void Initialise(string applicationID, string version, string taggedVersio TRInterop.ExecutingVersion = version; TRInterop.TaggedVersion = taggedVersion; TRInterop.RandomisationSupported = true; - TRLevelEditorFactory.RegisterEditor(TRVersion.TR2, typeof(TR2LevelRandomizer)); - TRLevelEditorFactory.RegisterEditor(TRVersion.TR2G, typeof(TR2LevelRandomizer)); + TRInterop.SecretRewardsSupported = true; + + TRLevelEditorFactory.RegisterEditor(TRVersion.TR2, typeof(TR2RandoEditor)); + TRLevelEditorFactory.RegisterEditor(TRVersion.TR3, typeof(TR3RandoEditor)); + + // Not yet fully supported i.e. no locations, textures etc defined + //TRLevelEditorFactory.RegisterEditor(TRVersion.TR2G, typeof(TR2RandoEditor)); + //TRLevelEditorFactory.RegisterEditor(TRVersion.TR3G, typeof(TR3RandoEditor)); // #125 Invoke TRCoord.Instance after defining TRInterop.ExecutingVersionName otherwise // TRGE will not know the config file name to look for. @@ -70,10 +76,10 @@ public void Initialise(string applicationID, string version, string taggedVersio TRCoord.Instance.BackupProgressChanged += TRCoord_BackupProgressChanged; } - public TR2RandomizerController Open(string directoryPath) + public TRRandomizerController Open(string directoryPath) { _openEventArgs = new TROpenRestoreEventArgs(); - return new TR2RandomizerController(directoryPath); + return new TRRandomizerController(directoryPath); } public void ClearHistory() diff --git a/TRRandomizerCore/TRRandomizerCore.csproj b/TRRandomizerCore/TRRandomizerCore.csproj new file mode 100644 index 000000000..43bf3cbec --- /dev/null +++ b/TRRandomizerCore/TRRandomizerCore.csproj @@ -0,0 +1,44 @@ + + + net472 + 4 + Copyright © Tombrunners 2021 + false + + + + False + ..\Deps\RectanglePacker.dll + + + ..\Deps\TRGE.Coord.dll + + + ..\Deps\TRGE.Core.dll + + + + + + + + + + + + + + + + PreserveNewest + + + + + Never + + + Never + + + \ No newline at end of file diff --git a/TRRandomizerCore/TRRandomizerType.cs b/TRRandomizerCore/TRRandomizerType.cs new file mode 100644 index 000000000..921deef94 --- /dev/null +++ b/TRRandomizerCore/TRRandomizerType.cs @@ -0,0 +1,22 @@ +namespace TRRandomizerCore +{ + public enum TRRandomizerType + { + All, + LevelSequence, + Unarmed, + Ammoless, + Sunset, + NightMode, + Secret, + SecretReward, + Item, + Enemy, + Texture, + StartPosition, + Audio, + Outfit, + Text, + Environment + } +} \ No newline at end of file diff --git a/TR2RandomizerCore/Utilities/EnemyUtilities.cs b/TRRandomizerCore/Utilities/EnemyUtilities.cs similarity index 93% rename from TR2RandomizerCore/Utilities/EnemyUtilities.cs rename to TRRandomizerCore/Utilities/EnemyUtilities.cs index 14e969be4..149d69dc0 100644 --- a/TR2RandomizerCore/Utilities/EnemyUtilities.cs +++ b/TRRandomizerCore/Utilities/EnemyUtilities.cs @@ -3,7 +3,8 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using TR2RandomizerCore.Helpers; +using TRRandomizerCore.Helpers; +using TRRandomizerCore.Levels; using TRFDControl; using TRFDControl.FDEntryTypes; using TRFDControl.Utilities; @@ -11,7 +12,7 @@ using TRLevelReader.Model; using TRLevelReader.Model.Enums; -namespace TR2RandomizerCore.Utilities +namespace TRRandomizerCore.Utilities { public static class EnemyUtilities { @@ -249,37 +250,37 @@ public static EnemyDifficulty GetEnemyDifficulty(List enemies) // These enemies are unsupported due to technical reasons, NOT difficulty reasons. private static readonly Dictionary> _unsupportedEnemiesTechnical = new Dictionary> { - [LevelNames.VENICE] = + [TR2LevelNames.VENICE] = new List { TR2Entities.MarcoBartoli }, - [LevelNames.BARTOLI] = + [TR2LevelNames.BARTOLI] = new List { TR2Entities.MarcoBartoli }, // #192 The Barkhang/Opera House freeze appears to be caused by dead floating water creatures, so they're all banished - [LevelNames.OPERA] = + [TR2LevelNames.OPERA] = new List { TR2Entities.Barracuda, TR2Entities.BlackMorayEel, TR2Entities.ScubaDiver, TR2Entities.Shark, TR2Entities.YellowMorayEel }, - [LevelNames.RIG] = + [TR2LevelNames.RIG] = new List { TR2Entities.MarcoBartoli }, - [LevelNames.DA] = + [TR2LevelNames.DA] = new List { TR2Entities.MarcoBartoli }, - [LevelNames.FATHOMS] = + [TR2LevelNames.FATHOMS] = new List { TR2Entities.MarcoBartoli }, - [LevelNames.LQ] = + [TR2LevelNames.LQ] = new List { TR2Entities.MarcoBartoli }, // #192 The Barkhang/Opera House freeze appears to be caused by dead floating water creatures, so they're all banished - [LevelNames.MONASTERY] = + [TR2LevelNames.MONASTERY] = new List { TR2Entities.Barracuda, TR2Entities.BlackMorayEel, TR2Entities.ScubaDiver, TR2Entities.Shark, TR2Entities.YellowMorayEel }, - [LevelNames.XIAN] = + [TR2LevelNames.XIAN] = new List { TR2Entities.MarcoBartoli }, - [LevelNames.FLOATER] = + [TR2LevelNames.FLOATER] = new List { TR2Entities.MarcoBartoli }, - [LevelNames.HOME] = + [TR2LevelNames.HOME] = // #148 Although we say here that the Doberman, MaskedGoons and StickGoons // aren't supported, this is only for cross-level purposes because we // are making placeholder entities to prevent breaking the kill counter. @@ -294,19 +295,19 @@ public static EnemyDifficulty GetEnemyDifficulty(List enemies) private static readonly Dictionary> _unsupportedEnemiesDefault = new Dictionary> { - [LevelNames.LAIR] = + [TR2LevelNames.LAIR] = new List { TR2Entities.MercSnowmobDriver }, - [LevelNames.HOME] = + [TR2LevelNames.HOME] = new List { TR2Entities.Spider, TR2Entities.Rat } }; private static readonly Dictionary> _requiredEnemies = new Dictionary> { - [LevelNames.CHICKEN] = + [TR2LevelNames.CHICKEN] = new List { TR2Entities.BirdMonster }, // #60 - Ice Palace chicken man must remain to avoid softlock. - [LevelNames.LAIR] = + [TR2LevelNames.LAIR] = new List { TR2Entities.MarcoBartoli }, // #97 - Marco/Dragon to remain in the same place to trigger door opening - [LevelNames.HOME] = + [TR2LevelNames.HOME] = new List { TR2Entities.ShotgunGoon } // #62 - Avoid randomizing shotgun goon in HSH }; @@ -341,11 +342,11 @@ static EnemyUtilities() { _restrictedEnemyZonesDefault = JsonConvert.DeserializeObject>>> ( - File.ReadAllText(@"Resources\enemy_restrictions_default.json") + File.ReadAllText(@"Resources\TR2\Restrictions\enemy_restrictions_default.json") ); _restrictedEnemyZonesTechnical = JsonConvert.DeserializeObject>>> ( - File.ReadAllText(@"Resources\enemy_restrictions_technical.json") + File.ReadAllText(@"Resources\TR2\Restrictions\enemy_restrictions_technical.json") ); } @@ -405,14 +406,14 @@ static EnemyUtilities() */ private static readonly Dictionary _enemyAdjustmentCount = new Dictionary { - [LevelNames.GW] = 2, - [LevelNames.OPERA] = -1, - [LevelNames.DA] = -1, - [LevelNames.FATHOMS] = 1, - [LevelNames.TIBET] = 1, - [LevelNames.CHICKEN] = 1, - [LevelNames.FLOATER] = 1, - [LevelNames.LAIR] = 1 + [TR2LevelNames.GW] = 2, + [TR2LevelNames.OPERA] = -1, + [TR2LevelNames.DA] = -1, + [TR2LevelNames.FATHOMS] = 1, + [TR2LevelNames.TIBET] = 1, + [TR2LevelNames.CHICKEN] = 1, + [TR2LevelNames.FLOATER] = 1, + [TR2LevelNames.LAIR] = 1 }; public static List GetEnemyGuisers(TR2Entities entity) @@ -479,15 +480,15 @@ public static Dictionary GetAliasPriority(string lvlNa { switch (lvlName) { - case LevelNames.RIG: - case LevelNames.DA: - case LevelNames.DORIA: + case TR2LevelNames.RIG: + case TR2LevelNames.DA: + case TR2LevelNames.DORIA: priorities[TR2Entities.LaraMiscAnim_H] = TR2Entities.LaraMiscAnim_H_Unwater; break; - case LevelNames.CHICKEN: + case TR2LevelNames.CHICKEN: priorities[TR2Entities.LaraMiscAnim_H] = TR2Entities.LaraMiscAnim_H_Ice; break; - case LevelNames.HOME: + case TR2LevelNames.HOME: priorities[TR2Entities.LaraMiscAnim_H] = TR2Entities.LaraMiscAnim_H_HSH; break; } diff --git a/TR2RandomizerCore/Utilities/ItemUtilities.cs b/TRRandomizerCore/Utilities/ItemUtilities.cs similarity index 98% rename from TR2RandomizerCore/Utilities/ItemUtilities.cs rename to TRRandomizerCore/Utilities/ItemUtilities.cs index d568050e5..30257acab 100644 --- a/TR2RandomizerCore/Utilities/ItemUtilities.cs +++ b/TRRandomizerCore/Utilities/ItemUtilities.cs @@ -3,7 +3,7 @@ using TRGE.Core.Item.Enums; using TRLevelReader.Model.Enums; -namespace TR2RandomizerCore.Utilities +namespace TRRandomizerCore.Utilities { public static class ItemUtilities { diff --git a/TR2RandomizerCore/Utilities/RoomWaterUtilities.cs b/TRRandomizerCore/Utilities/RoomWaterUtilities.cs similarity index 67% rename from TR2RandomizerCore/Utilities/RoomWaterUtilities.cs rename to TRRandomizerCore/Utilities/RoomWaterUtilities.cs index 7acae696e..fadc8322f 100644 --- a/TR2RandomizerCore/Utilities/RoomWaterUtilities.cs +++ b/TRRandomizerCore/Utilities/RoomWaterUtilities.cs @@ -1,98 +1,98 @@ using System.Collections.Generic; using TRLevelReader.Helpers; -namespace TR2RandomizerCore.Utilities +namespace TRRandomizerCore.Utilities { public static class RoomWaterUtilities { public static Dictionary>> RoomRemovalWaterMap = new Dictionary>> { - { LevelNames.GW, new List> + { TR2LevelNames.GW, new List> { //No drain areas defined for now } }, - { LevelNames.VENICE, new List> + { TR2LevelNames.VENICE, new List> { //No drain areas defined for now } }, - { LevelNames.BARTOLI, new List> + { TR2LevelNames.BARTOLI, new List> { //No drain areas defined for now } }, - { LevelNames.OPERA, new List> + { TR2LevelNames.OPERA, new List> { //No drain areas defined for now } }, - { LevelNames.RIG, new List> + { TR2LevelNames.RIG, new List> { //No drain areas defined for now } }, - { LevelNames.DA, new List> + { TR2LevelNames.DA, new List> { //No drain areas defined for now } }, - { LevelNames.FATHOMS, new List> + { TR2LevelNames.FATHOMS, new List> { //No drain areas defined for now } }, - { LevelNames.DORIA, new List> + { TR2LevelNames.DORIA, new List> { //No drain areas defined for now } }, - { LevelNames.LQ, new List> + { TR2LevelNames.LQ, new List> { //No drain areas defined for now } }, - { LevelNames.DECK, new List> + { TR2LevelNames.DECK, new List> { //No drain areas defined for now } }, - { LevelNames.TIBET, new List> + { TR2LevelNames.TIBET, new List> { //No drain areas defined for now } }, - { LevelNames.MONASTERY, new List> + { TR2LevelNames.MONASTERY, new List> { //No drain areas defined for now } }, - { LevelNames.COT, new List> + { TR2LevelNames.COT, new List> { //No drain areas defined for now } }, - { LevelNames.CHICKEN, new List> + { TR2LevelNames.CHICKEN, new List> { //No drain areas defined for now } }, - { LevelNames.XIAN, new List> + { TR2LevelNames.XIAN, new List> { //No drain areas defined for now } }, - { LevelNames.FLOATER, new List> + { TR2LevelNames.FLOATER, new List> { //No drain areas defined for now } }, - { LevelNames.LAIR, new List> + { TR2LevelNames.LAIR, new List> { //No drain areas defined for now } }, - { LevelNames.HOME, new List> + { TR2LevelNames.HOME, new List> { //No drain areas defined for now } diff --git a/TR2RandomizerCore/Utilities/SpatialConverters.cs b/TRRandomizerCore/Utilities/SpatialConverters.cs similarity index 90% rename from TR2RandomizerCore/Utilities/SpatialConverters.cs rename to TRRandomizerCore/Utilities/SpatialConverters.cs index 764eb8c0f..d68e9e3be 100644 --- a/TR2RandomizerCore/Utilities/SpatialConverters.cs +++ b/TRRandomizerCore/Utilities/SpatialConverters.cs @@ -1,7 +1,7 @@ -using TR2RandomizerCore.Helpers; +using TRRandomizerCore.Helpers; using TRLevelReader.Model; -namespace TR2RandomizerCore.Utilities +namespace TRRandomizerCore.Utilities { internal static class SpatialConverters { diff --git a/TR2RandomizerCore/Utilities/TexturePositionMonitor.cs b/TRRandomizerCore/Utilities/TexturePositionMonitor.cs similarity index 99% rename from TR2RandomizerCore/Utilities/TexturePositionMonitor.cs rename to TRRandomizerCore/Utilities/TexturePositionMonitor.cs index 4c51d301c..954ad5008 100644 --- a/TR2RandomizerCore/Utilities/TexturePositionMonitor.cs +++ b/TRRandomizerCore/Utilities/TexturePositionMonitor.cs @@ -4,7 +4,7 @@ using TRTexture16Importer.Textures.Source; using TRTexture16Importer.Textures.Target; -namespace TR2RandomizerCore.Utilities +namespace TRRandomizerCore.Utilities { public class TexturePositionMonitor : ITexturePositionMonitor { diff --git a/TR2RandomizerCore/Utilities/TexturePositionMonitorBroker.cs b/TRRandomizerCore/Utilities/TexturePositionMonitorBroker.cs similarity index 99% rename from TR2RandomizerCore/Utilities/TexturePositionMonitorBroker.cs rename to TRRandomizerCore/Utilities/TexturePositionMonitorBroker.cs index 09844f138..26047a18b 100644 --- a/TR2RandomizerCore/Utilities/TexturePositionMonitorBroker.cs +++ b/TRRandomizerCore/Utilities/TexturePositionMonitorBroker.cs @@ -6,7 +6,7 @@ using TRTexture16Importer.Textures.Source; using TRTexture16Importer.Textures.Target; -namespace TR2RandomizerCore.Utilities +namespace TRRandomizerCore.Utilities { internal class TexturePositionMonitorBroker : IDisposable { diff --git a/TR2RandomizerCore/Utilities/VehicleUtilities.cs b/TRRandomizerCore/Utilities/VehicleUtilities.cs similarity index 88% rename from TR2RandomizerCore/Utilities/VehicleUtilities.cs rename to TRRandomizerCore/Utilities/VehicleUtilities.cs index 70320d446..3ddd06f36 100644 --- a/TR2RandomizerCore/Utilities/VehicleUtilities.cs +++ b/TRRandomizerCore/Utilities/VehicleUtilities.cs @@ -2,17 +2,17 @@ using System; using System.Collections.Generic; using System.IO; -using TR2RandomizerCore.Helpers; +using TRRandomizerCore.Helpers; using TRLevelReader.Model.Enums; -namespace TR2RandomizerCore.Utilities +namespace TRRandomizerCore.Utilities { public static class VehicleUtilities { private static readonly Dictionary>> _allVehicleLocations; static VehicleUtilities() { - _allVehicleLocations = JsonConvert.DeserializeObject>>>(File.ReadAllText(@"Resources\vehicle_locations.json")); + _allVehicleLocations = JsonConvert.DeserializeObject>>>(File.ReadAllText(@"Resources\TR2\Locations\vehicle_locations.json")); } public static Location GetRandomLocation(string levelName, TR2Entities vehicle, Random random) diff --git a/TR2RandomizerCore/Zones/LevelZones.cs b/TRRandomizerCore/Zones/LevelZones.cs similarity index 92% rename from TR2RandomizerCore/Zones/LevelZones.cs rename to TRRandomizerCore/Zones/LevelZones.cs index 467b0a38a..c0fad5d15 100644 --- a/TR2RandomizerCore/Zones/LevelZones.cs +++ b/TRRandomizerCore/Zones/LevelZones.cs @@ -1,4 +1,4 @@ -namespace TR2RandomizerCore.Zones +namespace TRRandomizerCore.Zones { enum LevelZones : int { diff --git a/TR2RandomizerCore/Zones/ZonedLocationCollection.cs b/TRRandomizerCore/Zones/ZonedLocationCollection.cs similarity index 97% rename from TR2RandomizerCore/Zones/ZonedLocationCollection.cs rename to TRRandomizerCore/Zones/ZonedLocationCollection.cs index 9946e70b3..6e86768c8 100644 --- a/TR2RandomizerCore/Zones/ZonedLocationCollection.cs +++ b/TRRandomizerCore/Zones/ZonedLocationCollection.cs @@ -2,9 +2,9 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using TR2RandomizerCore.Helpers; +using TRRandomizerCore.Helpers; -namespace TR2RandomizerCore.Zones +namespace TRRandomizerCore.Zones { class ZonedLocationCollection { @@ -141,9 +141,9 @@ public List GetZoneLocations(int zone) return null; } - public void PopulateZones(string lvl, List locations, ZonePopulationMethod popMethod) + public void PopulateZones(string zoneFilePath, List locations, ZonePopulationMethod popMethod) { - Dictionary> ZoneMap = JsonConvert.DeserializeObject>>(File.ReadAllText(@"Resources\Zones\" + lvl + "-Zones.json")); + Dictionary> ZoneMap = JsonConvert.DeserializeObject>>(File.ReadAllText(zoneFilePath)); if (popMethod == ZonePopulationMethod.SecretsOnly || popMethod == ZonePopulationMethod.Full) { diff --git a/TR2RandomizerView/App.config b/TRRandomizerView/App.config similarity index 100% rename from TR2RandomizerView/App.config rename to TRRandomizerView/App.config diff --git a/TR2RandomizerView/App.xaml b/TRRandomizerView/App.xaml similarity index 89% rename from TR2RandomizerView/App.xaml rename to TRRandomizerView/App.xaml index 6b99c76ee..1e3ab440c 100644 --- a/TR2RandomizerView/App.xaml +++ b/TRRandomizerView/App.xaml @@ -1,4 +1,4 @@ - @@ -28,6 +28,12 @@ + + + + + + @@ -132,5 +138,13 @@ + + \ No newline at end of file diff --git a/TR2RandomizerView/App.xaml.cs b/TRRandomizerView/App.xaml.cs similarity index 85% rename from TR2RandomizerView/App.xaml.cs rename to TRRandomizerView/App.xaml.cs index f11bca593..08965cc16 100644 --- a/TR2RandomizerView/App.xaml.cs +++ b/TRRandomizerView/App.xaml.cs @@ -2,11 +2,11 @@ using System.IO; using System.Reflection; using System.Windows; -using TR2RandomizerCore; -using TR2RandomizerCore.Helpers; -using TR2RandomizerView.Utilities; +using TRRandomizerCore; +using TRRandomizerCore.Helpers; +using TRRandomizerView.Utilities; -namespace TR2RandomizerView +namespace TRRandomizerView { /// /// Interaction logic for App.xaml @@ -65,11 +65,11 @@ public App() TaggedVersion = "v" + Version; } - TR2RandomizerCoord.Instance.Initialise("TR2Rando", Version, TaggedVersion, new ModificationStamp + TRRandomizerCoord.Instance.Initialise("TR2Rando", Version, TaggedVersion, new ModificationStamp { - English = "Modified by TR2Rando", - French = "Modifié par TR2Rando", - German = "Geändert von TR2Rando" + English = "Modified by TRRando", + French = "Modifié par TRRando", + German = "Geändert von TRRando" }); } } diff --git a/TR2RandomizerView/Commands/WindowCommands.cs b/TRRandomizerView/Commands/WindowCommands.cs similarity index 98% rename from TR2RandomizerView/Commands/WindowCommands.cs rename to TRRandomizerView/Commands/WindowCommands.cs index cc42f8bdd..9e8a1d4bb 100644 --- a/TR2RandomizerView/Commands/WindowCommands.cs +++ b/TRRandomizerView/Commands/WindowCommands.cs @@ -1,6 +1,6 @@ using System.Windows.Input; -namespace TR2RandomizerView.Commands +namespace TRRandomizerView.Commands { public static class WindowCommands { diff --git a/TR2RandomizerView/Controls/EditorControl.xaml b/TRRandomizerView/Controls/EditorControl.xaml similarity index 89% rename from TR2RandomizerView/Controls/EditorControl.xaml rename to TRRandomizerView/Controls/EditorControl.xaml index 6a4fc25a1..71edc22e1 100644 --- a/TR2RandomizerView/Controls/EditorControl.xaml +++ b/TRRandomizerView/Controls/EditorControl.xaml @@ -1,12 +1,12 @@ - + @@ -37,6 +38,7 @@ - + - - - - + TextWrapping="Wrap" + Style="{StaticResource StatusAwareTextBlock}"/>