diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
new file mode 100644
index 0000000..eefd4d8
--- /dev/null
+++ b/.github/workflows/build.yml
@@ -0,0 +1,75 @@
+name: Build
+
+on:
+ # Trigger the workflow on pushes to only the 'main' branch (this avoids duplicate checks being run e.g., for dependabot pull requests)
+ push:
+ branches: [main]
+ # Trigger the workflow on any pull request
+ pull_request:
+ workflow_call:
+ inputs:
+ ref:
+ description: "A tag reference passed from Publish workflow"
+ default: ${{ github.sha }}
+ required: false
+ type: string
+
+jobs:
+ build:
+ name: Build
+ runs-on: ubuntu-latest
+ steps:
+ - name: Fetch Sources
+ uses: actions/checkout@v4
+ with:
+ ref: ${{ inputs.ref }}
+ fetch-depth: 0
+ filter: tree:0
+
+ - name: Setup .NET environment
+ uses: actions/setup-dotnet@v4
+ with:
+ dotnet-version: "8.0.100"
+
+ - name: Install Evaisa's netcode-patcher
+ run: |
+ dotnet tool install -g Evaisa.NetcodePatcher.Cli
+ - name: Restore project
+ run: |
+ dotnet restore
+ dotnet tool restore
+ - name: Build and pack solution
+ run: |
+ dotnet pack -c Release
+ - name: Set MOD_NAME environment variable
+ run: echo "MOD_NAME=$(cat ./*/dist/name.txt )" >> $GITHUB_ENV
+
+ - name: Set MOD_VERSION environment variable
+ run: echo "MOD_VERSION=$(cat ./*/dist/version.txt )" >> $GITHUB_ENV
+
+ - name: Set ZIP_PATH environment variable
+ run: echo "ZIP_PATH=./${{ env.MOD_NAME }}/dist/curseforge.zip" >> $GITHUB_ENV
+
+ - name: Upload CurseForge artifact
+ uses: actions/upload-artifact@v4
+ with:
+ name: curseforge-build
+ path: ./*/dist/*.zip
+
+ - name: Upload Thunderstore artifact
+ uses: actions/upload-artifact@v4
+ with:
+ name: thunderstore-build
+ path: ./*/dist/*.zip
+
+ - name: Upload nupkg artifact
+ uses: actions/upload-artifact@v4
+ with:
+ name: nupkg-build
+ path: ./*/bin/Release/*.nupkg
+
+ - name: Upload Versions artifact
+ uses: actions/upload-artifact@v4
+ with:
+ name: versions
+ path: ./*/dist/*.txt
\ No newline at end of file
diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
new file mode 100644
index 0000000..b41f2b5
--- /dev/null
+++ b/.github/workflows/publish.yml
@@ -0,0 +1,46 @@
+name: Publish
+
+on:
+ release:
+ types: [prereleased, released]
+
+jobs:
+ build:
+ uses: ./.github/workflows/build.yml
+ with:
+ ref: ${{ github.event.release.tag_name }}
+
+ upload-release-artifacts:
+ name: Add artifacts to Release
+ needs: build
+ runs-on: ubuntu-latest
+ steps:
+ - name: Fetch Sources
+ uses: actions/checkout@v4
+
+ - name: Download all artifacts
+ uses: actions/download-artifact@v4
+
+ - name: Upload artifacts to Release
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB }}
+ run: gh release upload ${{ github.event.release.tag_name }} thunderstore-build/*/dist/*.zip nupkg-build/*/bin/Release/*.nupkg
+
+ release-curseforge:
+ needs: build
+ uses: ./.github/workflows/release-curseforge.yml
+ secrets:
+ curseforge-token: ${{ secrets.CURSEFORGE_API_KEY }}
+ project-id: ${{ secrets.CURSEFORGE_PROJECTID }}
+
+ release-thunderstore:
+ needs: build
+ uses: ./.github/workflows/release-thunderstore.yml
+ secrets:
+ thunderstore-token: ${{ secrets.THUNDERSTORE_API_KEY }}
+
+ release-nuget:
+ needs: build
+ uses: ./.github/workflows/release-nuget.yml
+ secrets:
+ nuget-token: ${{ secrets.NUGET_API_KEY }}
\ No newline at end of file
diff --git a/.github/workflows/release-curseforge.yml b/.github/workflows/release-curseforge.yml
new file mode 100644
index 0000000..fa7d759
--- /dev/null
+++ b/.github/workflows/release-curseforge.yml
@@ -0,0 +1,46 @@
+name: Release on Curseforge
+
+on:
+ workflow_call:
+ secrets:
+ curseforge-token:
+ required: true
+ project-id:
+ required: true
+
+jobs:
+ curseforge:
+ name: Upload
+ runs-on: ubuntu-latest
+ steps:
+ - name: Fetch Sources
+ uses: actions/checkout@v4
+
+ - name: Download Curseforge artifact
+ uses: actions/download-artifact@v4
+ with:
+ name: curseforge-build
+
+ - name: Download Versions artifact
+ uses: actions/download-artifact@v4
+ with:
+ name: versions
+
+ - name: Set MOD_NAME environment variable
+ run: echo "MOD_NAME=$(cat ./*/dist/name.txt )" >> $GITHUB_ENV
+
+ - name: Set MOD_VERSION environment variable
+ run: echo "MOD_VERSION=$(cat ./*/dist/version.txt )" >> $GITHUB_ENV
+
+ - name: Set ZIP_PATH environment variable
+ run: echo "ZIP_PATH=./${{ env.MOD_NAME }}/dist/curseforge.zip" >> $GITHUB_ENV
+
+ - name: "Upload to CurseForge"
+ uses: itsmeow/curseforge-upload@v3
+ with:
+ token: ${{ secrets.curseforge-token }}
+ project_id: ${{ secrets.project-id }}
+ game_endpoint: "lethal-company"
+ game_versions: "0.50.0"
+ file_path: ${{ env.ZIP_PATH }}
+ display_name: ${{ env.MOD_NAME }} v${{ env.MOD_VERSION }}
\ No newline at end of file
diff --git a/.github/workflows/release-nuget.yml b/.github/workflows/release-nuget.yml
new file mode 100644
index 0000000..0b1a570
--- /dev/null
+++ b/.github/workflows/release-nuget.yml
@@ -0,0 +1,29 @@
+name: Release on Nuget
+
+on:
+ workflow_call:
+ secrets:
+ nuget-token:
+ required: true
+
+jobs:
+ nuget:
+ name: Upload
+ runs-on: ubuntu-latest
+ steps:
+ - name: Fetch Sources
+ uses: actions/checkout@v4
+
+ - name: Download nupkg artifact
+ uses: actions/download-artifact@v4
+ with:
+ name: nupkg-build
+
+ - name: Setup .NET environment
+ uses: actions/setup-dotnet@v3
+ with:
+ dotnet-version: "8.0.100"
+
+ - name: Publish to NuGet.org
+ run: |
+ dotnet nuget push ./*/bin/Release/*.nupkg --api-key ${{ secrets.nuget-token }} --source https://api.nuget.org/v3/index.json
\ No newline at end of file
diff --git a/.github/workflows/release-thunderstore.yml b/.github/workflows/release-thunderstore.yml
new file mode 100644
index 0000000..224b602
--- /dev/null
+++ b/.github/workflows/release-thunderstore.yml
@@ -0,0 +1,37 @@
+name: Release on Thunderstore
+
+on:
+ workflow_call:
+ secrets:
+ thunderstore-token:
+ required: true
+
+jobs:
+ thunderstore:
+ name: Upload
+ runs-on: ubuntu-latest
+ steps:
+ - name: Fetch Sources
+ uses: actions/checkout@v4
+
+ - name: Download Thunderstore artifact
+ uses: actions/download-artifact@v4
+ with:
+ name: thunderstore-build
+
+ - name: Setup .NET environment
+ uses: actions/setup-dotnet@v3
+ with:
+ dotnet-version: "8.0.100"
+
+ - name: Install Evaisa's netcode-patcher
+ run: |
+ dotnet tool install -g Evaisa.NetcodePatcher.Cli
+ - name: Restore dotnet tools
+ run: |
+ dotnet tool restore
+ - name: Publish to Thunderstore
+ env:
+ TCLI_AUTH_TOKEN: ${{ secrets.thunderstore-token }}
+ run: |
+ dotnet build -target:PublishThunderstore
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8e15aac..6711b56 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,120 @@
**Changelog**
--
+**Version 1.3.8
**
+
+**Features
**
+
+* Added interior selection history to DayHistory
+
+
+
+
+
+**Version 1.3.7
**
+
+**Fixes
**
+
+* Added additional safety checks to ExtendedFootstepSurface patches
+
+
+
+
+
+**Version 1.3.6
**
+
+**Features
**
+
+* Added content restoration support for basegame water shader
+
+
+
+
+
+**Version 1.3.5
**
+
+**Fixes
**
+
+* Added safety checks to new FootstepSurface Material cache system.
+* Added safety checks to new ExtendedLevel override fog size feature.
+* Changed ContentRestoring of EnemyType's to use ScriptableObject name rather than enemyName
+* Fixed issue where synced audio clip that plays when previewing enemy beastiary file was not playing for custom enemies
+* Fixed issue where custom Enemy beastiary files did not have Info as a default keyword
+
+
+
+
+
+**Version 1.3.4
**
+
+**Fixes
**
+
+* Updated .csproj and thunderstore.toml
+* Updated outdated README.md
+
+
+
+
+
+**Version 1.3.3
**
+
+**Features
**
+
+* Implemented ExtendedFootstepSurface
+
+
+
+
+
+**Version 1.3.2
**
+
+**Fixes
**
+
+* Updated onApparatusTaken ExtendedEvent
+
+
+
+
+
+**Version 1.3.1
**
+
+**Fixes
**
+
+* Fixed issue regarding deprecated Level list.
+
+
+
+
+
+
+**Version 1.3.0
**
+
+**Features
**
+
+* Updated mod for Lethal Company version 56
+* Added initial ExtendedBuyableVehicle implementation
+* Added LevelEvents.onShipLand ExtendedEvent
+* Added LevelEvents.onShipLeave ExtendedEvent
+* Added ExtendedLevel.OverrideDustStormVolumeSize Value
+* Added ExtendedLevel.OverrideFoggyVolumeSize Value
+* Added PatchedContent.TryGetExtendedContent() Function.
+* Added public references to basegame manager instances to OriginalContent
+* Updated ContentTag's for new Version 55/56 content
+
+
+
+**Fixes
**
+
+* Fixed issue with onApparatusTaken event running at unintended moments
+* Added safeguard to prevent multiple Lethalbundles with identical names from causing a gamebreaking error
+* Moved LethalLib from a Hard Dependency to a Soft Dependency
+* Fixed ExtendedItem's not correctly playing the purchased SFX when purchased from Terminal
+* Merged various pull requests to improve the workflow and deployment of further LethalLevelLoader development
+
+
+
+
+
**Version 1.2.2
**
**Fixes
**
diff --git a/LethalLevelLoader/Components/ExtendedContent/ExtendedBuyableVehicle.cs b/LethalLevelLoader/Components/ExtendedContent/ExtendedBuyableVehicle.cs
index aba73bc..ad5761c 100644
--- a/LethalLevelLoader/Components/ExtendedContent/ExtendedBuyableVehicle.cs
+++ b/LethalLevelLoader/Components/ExtendedContent/ExtendedBuyableVehicle.cs
@@ -8,14 +8,14 @@ namespace LethalLevelLoader
[CreateAssetMenu(fileName = "ExtendedBuyableVehicle", menuName = "Lethal Level Loader/Extended Content/ExtendedBuyableVehicle", order = 21)]
public class ExtendedBuyableVehicle : ExtendedContent
{
- [field: SerializeField] public BuyableVehicle BuyableVehicle { get; set; }
+ [field: SerializeField] public BuyableVehicle BuyableVehicle { get; set; } = null!;
[field: SerializeField] public string TerminalKeywordName { get; set; } = string.Empty;
public int VehicleID { get; set; }
- public TerminalNode VehicleBuyNode { get; set; }
- public TerminalNode VehicleBuyConfirmNode { get; set; }
- public TerminalNode VehicleInfoNode { get; set; }
+ public TerminalNode VehicleBuyNode { get; set; } = null!;
+ public TerminalNode VehicleBuyConfirmNode { get; set; } = null!;
+ public TerminalNode VehicleInfoNode { get; set; } = null!;
internal static ExtendedBuyableVehicle Create(BuyableVehicle newBuyableVehicle)
{
diff --git a/LethalLevelLoader/Components/ExtendedContent/ExtendedContent.cs b/LethalLevelLoader/Components/ExtendedContent/ExtendedContent.cs
index c1766a8..bf1094e 100644
--- a/LethalLevelLoader/Components/ExtendedContent/ExtendedContent.cs
+++ b/LethalLevelLoader/Components/ExtendedContent/ExtendedContent.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Text;
using UnityEngine;
@@ -8,7 +9,7 @@ namespace LethalLevelLoader
{
public class ExtendedContent : ScriptableObject
{
- public ExtendedMod ExtendedMod { get; internal set; }
+ public ExtendedMod ExtendedMod { get; internal set; } = null!;
public ContentType ContentType { get; internal set; } = ContentType.Vanilla;
/*Obsolete*/ public List ContentTagStrings { get; internal set; } = new List();
[field: SerializeField] public List ContentTags { get; internal set; } = new List();
@@ -30,7 +31,7 @@ public bool TryGetTag(string tag)
return (false);
}
- public bool TryGetTag(string tag, out ContentTag returnTag)
+ public bool TryGetTag(string tag, [NotNullWhen(returnValue: true)] out ContentTag? returnTag)
{
returnTag = null;
foreach (ContentTag contentTag in ContentTags)
diff --git a/LethalLevelLoader/Components/ExtendedContent/ExtendedDungeonFlow.cs b/LethalLevelLoader/Components/ExtendedContent/ExtendedDungeonFlow.cs
index c587916..4fbab59 100644
--- a/LethalLevelLoader/Components/ExtendedContent/ExtendedDungeonFlow.cs
+++ b/LethalLevelLoader/Components/ExtendedContent/ExtendedDungeonFlow.cs
@@ -15,19 +15,19 @@ namespace LethalLevelLoader
public class ExtendedDungeonFlow : ExtendedContent
{
[field: Header("General Settings")]
- [field: SerializeField] public DungeonFlow DungeonFlow { get; set; }
+ [field: SerializeField] public DungeonFlow DungeonFlow { get; set; } = null!;
[field: SerializeField] public string DungeonName { get; set; } = string.Empty;
[field: SerializeField] public float MapTileSize { get; set; } = 1f;
- [field: SerializeField] public AudioClip FirstTimeDungeonAudio { get; set; }
+ [field: SerializeField] public AudioClip FirstTimeDungeonAudio { get; set; } = null!;
[field: Space(5)]
[field: Header("Dynamic Injection Matching Settings")]
- [field: SerializeField] public LevelMatchingProperties LevelMatchingProperties { get; set; }
+ [field: SerializeField] public LevelMatchingProperties LevelMatchingProperties { get; set; } = null!;
[field: Space(5)]
[field: Header("Extended Feature Settings")]
- [field: SerializeField] public GameObject OverrideKeyPrefab { get; set; }
+ [field: SerializeField] public GameObject OverrideKeyPrefab { get; set; } = null!;
[field: SerializeField] public List SpawnableMapObjects { get; set; } = new List();
[field: SerializeField] public List GlobalPropCountOverridesList { get; set; } = new List();
@@ -49,8 +49,8 @@ public class ExtendedDungeonFlow : ExtendedContent
[Obsolete] public float dungeonSizeMin = 1;
[Obsolete] public float dungeonSizeMax = 1;
[Obsolete][Range(0, 1)] public float dungeonSizeLerpPercentage = 1;
- [Obsolete] public AudioClip dungeonFirstTimeAudio;
- [Obsolete] public DungeonFlow dungeonFlow;
+ [Obsolete] public AudioClip? dungeonFirstTimeAudio;
+ [Obsolete] public DungeonFlow? dungeonFlow;
[Obsolete] public string dungeonDisplayName = string.Empty;
[Obsolete] public string contentSourceName = string.Empty;
[Obsolete] public List dynamicLevelTagsList = new List();
@@ -65,11 +65,11 @@ public class ExtendedDungeonFlow : ExtendedContent
public bool IsCurrentDungeon => (DungeonManager.CurrentExtendedDungeonFlow == this);
[HideInInspector] public DungeonEvents DungeonEvents { get; internal set; } = new DungeonEvents();
- internal static ExtendedDungeonFlow Create(DungeonFlow newDungeonFlow, AudioClip newFirstTimeDungeonAudio)
+ internal static ExtendedDungeonFlow Create(DungeonFlow newDungeonFlow, AudioClip? newFirstTimeDungeonAudio)
{
ExtendedDungeonFlow newExtendedDungeonFlow = ScriptableObject.CreateInstance();
newExtendedDungeonFlow.DungeonFlow = newDungeonFlow;
- newExtendedDungeonFlow.FirstTimeDungeonAudio = newFirstTimeDungeonAudio;
+ newExtendedDungeonFlow.FirstTimeDungeonAudio = newFirstTimeDungeonAudio!;
if (newExtendedDungeonFlow.LevelMatchingProperties == null)
newExtendedDungeonFlow.LevelMatchingProperties = LevelMatchingProperties.Create(newExtendedDungeonFlow);
diff --git a/LethalLevelLoader/Components/ExtendedContent/ExtendedEnemyType.cs b/LethalLevelLoader/Components/ExtendedContent/ExtendedEnemyType.cs
index c7f1e86..3c906de 100644
--- a/LethalLevelLoader/Components/ExtendedContent/ExtendedEnemyType.cs
+++ b/LethalLevelLoader/Components/ExtendedContent/ExtendedEnemyType.cs
@@ -12,27 +12,27 @@ public class ExtendedEnemyType : ExtendedContent
{
[field: Header("General Settings")]
- [field: SerializeField] public EnemyType EnemyType { get; set; }
- [field: SerializeField] public string EnemyDisplayName { get; set; }
+ [field: SerializeField] public EnemyType EnemyType { get; set; } = null!;
+ [field: SerializeField] public string EnemyDisplayName { get; set; } = null!;
[field: Space(5)]
[field: Header("Dynamic Injection Matching Settings")]
- [field: SerializeField] public LevelMatchingProperties OutsideLevelMatchingProperties { get; set; }
- [field: SerializeField] public LevelMatchingProperties DaytimeLevelMatchingProperties { get; set; }
+ [field: SerializeField] public LevelMatchingProperties OutsideLevelMatchingProperties { get; set; } = null!;
+ [field: SerializeField] public LevelMatchingProperties DaytimeLevelMatchingProperties { get; set; } = null!;
- [field: SerializeField] public LevelMatchingProperties InsideLevelMatchingProperties { get; set; }
- [field: SerializeField] public DungeonMatchingProperties InsideDungeonMatchingProperties { get; set; }
+ [field: SerializeField] public LevelMatchingProperties InsideLevelMatchingProperties { get; set; } = null!;
+ [field: SerializeField] public DungeonMatchingProperties InsideDungeonMatchingProperties { get; set; } = null!;
[field: Space(5)]
[field: Header("Terminal Bestiary Override Settings")]
[field: SerializeField] [field: TextArea(2,20)] public string InfoNodeDescription { get; set; } = string.Empty;
- [field: SerializeField] public VideoClip InfoNodeVideoClip { get; set; }
+ [field: SerializeField] public VideoClip? InfoNodeVideoClip { get; set; }
- public ScanNodeProperties ScanNodeProperties { get; internal set; }
+ public ScanNodeProperties ScanNodeProperties { get; internal set; } = null!;
public int EnemyID { get; internal set; }
- public TerminalNode EnemyInfoNode { get; internal set; }
+ public TerminalNode? EnemyInfoNode { get; internal set; }
public static ExtendedEnemyType Create(EnemyType enemyType, ExtendedMod extendedMod, ContentType contentType)
{
diff --git a/LethalLevelLoader/Components/ExtendedContent/ExtendedFootstepSurface.cs b/LethalLevelLoader/Components/ExtendedContent/ExtendedFootstepSurface.cs
index 385f9ad..d10682d 100644
--- a/LethalLevelLoader/Components/ExtendedContent/ExtendedFootstepSurface.cs
+++ b/LethalLevelLoader/Components/ExtendedContent/ExtendedFootstepSurface.cs
@@ -8,8 +8,7 @@ namespace LethalLevelLoader;
[CreateAssetMenu(fileName = "ExtendedFootstepSurface", menuName = "Lethal Level Loader/Extended Content/ExtendedFootstepSurface", order = 27)]
public class ExtendedFootstepSurface : ExtendedContent
{
- public FootstepSurface footstepSurface;
- public List associatedMaterials;
- public List associatedGameObjects;
+ public FootstepSurface footstepSurface = null!;
+ public List associatedMaterials = null!;
internal int arrayIndex;
}
diff --git a/LethalLevelLoader/Components/ExtendedContent/ExtendedItem.cs b/LethalLevelLoader/Components/ExtendedContent/ExtendedItem.cs
index f7f8d2e..9bf70ca 100644
--- a/LethalLevelLoader/Components/ExtendedContent/ExtendedItem.cs
+++ b/LethalLevelLoader/Components/ExtendedContent/ExtendedItem.cs
@@ -10,15 +10,15 @@ public class ExtendedItem : ExtendedContent
{
[field: Header("General Settings")]
- [field: SerializeField] public Item Item { get; set; }
+ [field: SerializeField] public Item Item { get; set; } = null!;
[field: SerializeField] public string PluralisedItemName { get; set; } = string.Empty;
[field: SerializeField] public bool IsBuyableItem { get; set; }
[field: Space(5)]
[field: Header("Dynamic Injection Matching Settings")]
- [field: SerializeField] public LevelMatchingProperties LevelMatchingProperties { get; set; }
- [field: SerializeField] public DungeonMatchingProperties DungeonMatchingProperties { get; set; }
+ [field: SerializeField] public LevelMatchingProperties LevelMatchingProperties { get; set; } = null!;
+ [field: SerializeField] public DungeonMatchingProperties DungeonMatchingProperties { get; set; } = null!;
[field: Space(5)]
[field: Header("Terminal Store & Info Override Settings")]
@@ -27,9 +27,9 @@ public class ExtendedItem : ExtendedContent
[field: SerializeField] public string OverrideBuyNodeDescription { get; set; } = string.Empty;
[field: SerializeField] public string OverrideBuyConfirmNodeDescription { get; set; } = string.Empty;
- public TerminalNode BuyNode { get; internal set; }
- public TerminalNode BuyConfirmNode { get; internal set; }
- public TerminalNode BuyInfoNode { get; internal set; }
+ public TerminalNode? BuyNode { get; internal set; }
+ public TerminalNode? BuyConfirmNode { get; internal set; }
+ public TerminalNode? BuyInfoNode { get; internal set; }
public int CreditsWorth
{
diff --git a/LethalLevelLoader/Components/ExtendedContent/ExtendedLevel.cs b/LethalLevelLoader/Components/ExtendedContent/ExtendedLevel.cs
index feec484..06f8cc2 100644
--- a/LethalLevelLoader/Components/ExtendedContent/ExtendedLevel.cs
+++ b/LethalLevelLoader/Components/ExtendedContent/ExtendedLevel.cs
@@ -14,7 +14,7 @@ namespace LethalLevelLoader
public class ExtendedLevel : ExtendedContent
{
[field: Header("General Settings")]
- [field: SerializeField] public SelectableLevel SelectableLevel { get; set; }
+ [field: SerializeField] public SelectableLevel SelectableLevel { get; set; } = null!;
[Space(5)] [SerializeField] private int routePrice = 0;
[field: Header("Extended Feature Settings")]
@@ -22,7 +22,7 @@ public class ExtendedLevel : ExtendedContent
[field: Space(5)]
- [field: SerializeField] public GameObject OverrideQuicksandPrefab { get; set; }
+ [field: SerializeField] public GameObject OverrideQuicksandPrefab { get; set; } = null!;
[field: Space(5)]
@@ -32,13 +32,20 @@ public class ExtendedLevel : ExtendedContent
[field: Space(5)]
- [field: SerializeField] public AnimationClip ShipFlyToMoonClip { get; set; }
- [field: SerializeField] public AnimationClip ShipFlyFromMoonClip { get; set; }
+ [field: SerializeField] public AnimationClip ShipFlyToMoonClip { get; set; } = null!;
+ [field: SerializeField] public AnimationClip ShipFlyFromMoonClip { get; set; } = null!;
[field: Space(5)]
[field: SerializeField] public List SceneSelections { get; set; } = new List();
+ [field: Space(5)]
+ [field: Header("Weather Fog Distance Override Settings")]
+
+ [field: SerializeField] public Vector3 OverrideDustStormVolumeSize { get; set; } = Vector3.zero;
+ [field: SerializeField] public Vector3 OverrideFoggyVolumeSize { get; set; } = Vector3.zero;
+
+
[field: Space(5)]
[field: Header("Terminal Route Override Settings")]
@@ -53,7 +60,7 @@ public class ExtendedLevel : ExtendedContent
[Space(25)]
[Header("Obsolete (Legacy Fields, Will Be Removed In The Future)")]
- [Obsolete] public SelectableLevel selectableLevel;
+ [Obsolete] public SelectableLevel? selectableLevel;
[Obsolete][Space(5)] public string contentSourceName = string.Empty; //Levels from AssetBundles will have this as their Assembly Name.
[Obsolete][Space(5)] public List levelTags = new List();
@@ -94,13 +101,13 @@ public int RoutePrice
[HideInInspector] public LevelEvents LevelEvents { get; internal set; } = new LevelEvents();
- public TerminalNode RouteNode { get; internal set; }
- public TerminalNode RouteConfirmNode { get; internal set; }
- public TerminalNode InfoNode { get; internal set; }
+ public TerminalNode RouteNode { get; internal set; } = null!;
+ public TerminalNode RouteConfirmNode { get; internal set; } = null!;
+ public TerminalNode InfoNode { get; internal set; } = null!;
//Dunno about these yet
public List EnabledExtendedWeatherEffects { get; set; } = new List();
- public ExtendedWeatherEffect CurrentExtendedWeatherEffect { get; set; }
+ public ExtendedWeatherEffect? CurrentExtendedWeatherEffect { get; set; }
internal static ExtendedLevel Create(SelectableLevel newSelectableLevel)
{
@@ -199,14 +206,14 @@ internal void SetLevelID()
internal void SetExtendedDungeonFlowMatches()
{
foreach (IntWithRarity intWithRarity in SelectableLevel.dungeonFlowTypes)
- if (DungeonManager.TryGetExtendedDungeonFlow(Patches.RoundManager.dungeonFlowTypes[intWithRarity.id].dungeonFlow, out ExtendedDungeonFlow extendedDungeonFlow))
+ if (DungeonManager.TryGetExtendedDungeonFlow(Patches.RoundManager.dungeonFlowTypes[intWithRarity.id].dungeonFlow, out ExtendedDungeonFlow? extendedDungeonFlow))
extendedDungeonFlow.LevelMatchingProperties.planetNames.Add(new StringWithRarity(NumberlessPlanetName, intWithRarity.rarity));
if (SelectableLevel.sceneName == "Level4March")
foreach (IndoorMapType indoorMapType in Patches.RoundManager.dungeonFlowTypes)
if (indoorMapType.dungeonFlow.name == "Level1Flow3Exits")
- if (DungeonManager.TryGetExtendedDungeonFlow(indoorMapType.dungeonFlow, out ExtendedDungeonFlow marchDungeonFlow))
+ if (DungeonManager.TryGetExtendedDungeonFlow(indoorMapType.dungeonFlow, out ExtendedDungeonFlow? marchDungeonFlow))
marchDungeonFlow.LevelMatchingProperties.planetNames.Add(new StringWithRarity(NumberlessPlanetName, 300));
}
diff --git a/LethalLevelLoader/Components/ExtendedContent/ExtendedMod.cs b/LethalLevelLoader/Components/ExtendedContent/ExtendedMod.cs
index d5c888e..16a1819 100644
--- a/LethalLevelLoader/Components/ExtendedContent/ExtendedMod.cs
+++ b/LethalLevelLoader/Components/ExtendedContent/ExtendedMod.cs
@@ -237,6 +237,8 @@ internal void UnregisterAllExtendedContent()
ExtendedEnemyTypes.Clear();
ExtendedWeatherEffects.Clear();
ExtendedFootstepSurfaces.Clear();
+ ExtendedStoryLogs.Clear();
+ ExtendedBuyableVehicles.Clear();
}
internal void SortRegisteredContent()
@@ -247,6 +249,8 @@ internal void SortRegisteredContent()
ExtendedEnemyTypes.Sort((s1, s2) => s1.name.CompareTo(s2.name));
ExtendedWeatherEffects.Sort((s1, s2) => s1.name.CompareTo(s2.name));
ExtendedFootstepSurfaces.Sort((s1, s2) => s1.name.CompareTo(s2.name));
+ ExtendedStoryLogs.Sort((s1, s2) => s1.name.CompareTo(s2.name));
+ ExtendedBuyableVehicles.Sort((s1, s2) => s1.name.CompareTo(s2.name));
}
internal void Example()
diff --git a/LethalLevelLoader/Components/ExtendedContent/ExtendedWeatherEffect.cs b/LethalLevelLoader/Components/ExtendedContent/ExtendedWeatherEffect.cs
index c0bcec1..ca870a3 100644
--- a/LethalLevelLoader/Components/ExtendedContent/ExtendedWeatherEffect.cs
+++ b/LethalLevelLoader/Components/ExtendedContent/ExtendedWeatherEffect.cs
@@ -14,8 +14,8 @@ public class ExtendedWeatherEffect : ExtendedContent
[field: SerializeField] public LevelWeatherType BaseWeatherType { get; set; } = LevelWeatherType.None;
[field: SerializeField] public string WeatherDisplayName { get; set; } = string.Empty;
- [field: SerializeField] public GameObject WorldObject { get; set; }
- [field: SerializeField] public GameObject GlobalObject { get; set; }
+ [field: SerializeField] public GameObject? WorldObject { get; set; }
+ [field: SerializeField] public GameObject? GlobalObject { get; set; }
public ContentType contentType;
@@ -29,7 +29,7 @@ internal static ExtendedWeatherEffect Create(LevelWeatherType levelWeatherType,
return (ExtendedWeatherEffect.Create(levelWeatherType, weatherEffect.effectObject, weatherEffect.effectPermanentObject, weatherDisplayName, newContentType));
}
- internal static ExtendedWeatherEffect Create(LevelWeatherType levelWeatherType, GameObject worldObject, GameObject globalObject, string newWeatherDisplayName, ContentType newContentType)
+ internal static ExtendedWeatherEffect Create(LevelWeatherType levelWeatherType, GameObject? worldObject, GameObject? globalObject, string newWeatherDisplayName, ContentType newContentType)
{
ExtendedWeatherEffect newExtendedWeatherEffect = ScriptableObject.CreateInstance();
diff --git a/LethalLevelLoader/Components/MatchingProperties/ContentTag.cs b/LethalLevelLoader/Components/MatchingProperties/ContentTag.cs
index 239419d..6974c00 100644
--- a/LethalLevelLoader/Components/MatchingProperties/ContentTag.cs
+++ b/LethalLevelLoader/Components/MatchingProperties/ContentTag.cs
@@ -8,7 +8,7 @@ namespace LethalLevelLoader
[CreateAssetMenu(fileName = "ContentTag", menuName = "Lethal Level Loader/Utility/ContentTag", order = 11)]
public class ContentTag : ScriptableObject
{
- public string contentTagName;
+ public string contentTagName = null!;
public Color contentTagColor;
diff --git a/LethalLevelLoader/Components/MatchingProperties/DungeonMatchingProperties.cs b/LethalLevelLoader/Components/MatchingProperties/DungeonMatchingProperties.cs
index 3c4daeb..9408c22 100644
--- a/LethalLevelLoader/Components/MatchingProperties/DungeonMatchingProperties.cs
+++ b/LethalLevelLoader/Components/MatchingProperties/DungeonMatchingProperties.cs
@@ -30,7 +30,7 @@ public int GetDynamicRarity(ExtendedDungeonFlow extendedDungeonFlow)
}
- public void ApplyValues(List newModNames = null, List newAuthorNames = null, List newDungeonTags = null, List newDungeonNames = null)
+ public void ApplyValues(List? newModNames = null, List? newAuthorNames = null, List? newDungeonTags = null, List? newDungeonNames = null)
{
if (newModNames != null && newModNames.Count != 0)
modNames = new List(newModNames);
diff --git a/LethalLevelLoader/Components/MatchingProperties/LevelMatchingProperties.cs b/LethalLevelLoader/Components/MatchingProperties/LevelMatchingProperties.cs
index 15abf5d..516699d 100644
--- a/LethalLevelLoader/Components/MatchingProperties/LevelMatchingProperties.cs
+++ b/LethalLevelLoader/Components/MatchingProperties/LevelMatchingProperties.cs
@@ -35,7 +35,7 @@ public int GetDynamicRarity(ExtendedLevel extendedLevel)
return (returnRarity);
}
- public void ApplyValues(List newModNames = null, List newAuthorNames = null, List newLevelTags = null, List newRoutePrices = null, List newCurrentWeathers = null, List newPlanetNames = null)
+ public void ApplyValues(List? newModNames = null, List? newAuthorNames = null, List? newLevelTags = null, List? newRoutePrices = null, List? newCurrentWeathers = null, List? newPlanetNames = null)
{
if (newModNames != null && newModNames.Count != 0)
modNames = new List(newModNames);
diff --git a/LethalLevelLoader/Components/MatchingProperties/MatchingProperties.cs b/LethalLevelLoader/Components/MatchingProperties/MatchingProperties.cs
index e3162fc..cf729dd 100644
--- a/LethalLevelLoader/Components/MatchingProperties/MatchingProperties.cs
+++ b/LethalLevelLoader/Components/MatchingProperties/MatchingProperties.cs
@@ -18,7 +18,7 @@ public static MatchingProperties Create(ExtendedContent extendedContent)
return (matchingProperties);
}
- internal static bool UpdateRarity(ref int currentValue, int newValue, string debugActionObject = null, string debugActionReason = null)
+ internal static bool UpdateRarity(ref int currentValue, int newValue, string? debugActionObject = null, string? debugActionReason = null)
{
if (newValue > currentValue)
{
diff --git a/LethalLevelLoader/General/Content.cs b/LethalLevelLoader/General/Content.cs
index e7a9b42..13a2972 100644
--- a/LethalLevelLoader/General/Content.cs
+++ b/LethalLevelLoader/General/Content.cs
@@ -11,12 +11,17 @@ namespace LethalLevelLoader
{
public static class PatchedContent
{
- public static ExtendedMod VanillaMod { get; internal set; }
+ public static ExtendedMod VanillaMod { get; internal set; } = null!;
public static List AllLevelSceneNames { get; internal set; } = new List();
public static List ExtendedMods { get; internal set; } = new List();
+ internal static Dictionary ExtendedLevelDictionary = new Dictionary();
+ internal static Dictionary ExtendedDungeonFlowDictionary = new Dictionary();
+ internal static Dictionary- ExtendedItemDictionary = new Dictionary
- ();
+ internal static Dictionary ExtendedEnemyTypeDictionary = new Dictionary();
+ internal static Dictionary ExtendedBuyableVehicleDictionary = new Dictionary();
public static List ExtendedLevels { get; internal set; } = new List();
@@ -45,6 +50,13 @@ public static List CustomExtendedLevels
}
}
+ [Obsolete("Use PatchedContent.SelectableLevels instead.")] // probably used by no mod, but this is public so we should be careful
+ public static List SeletectableLevels
+ {
+ get { return (SelectableLevels); }
+ }
+
+
public static List SelectableLevels
{
@@ -245,10 +257,62 @@ internal static void SortExtendedMods()
extendedMod.SortRegisteredContent();
}
}
+
+ internal static void PopulateContentDictionaries()
+ {
+ foreach (ExtendedLevel extendedLevel in ExtendedLevels)
+ TryAdd(ExtendedLevelDictionary, extendedLevel.SelectableLevel, extendedLevel);
+ foreach (ExtendedDungeonFlow extendedDungeonFlow in ExtendedDungeonFlows)
+ TryAdd(ExtendedDungeonFlowDictionary, extendedDungeonFlow.DungeonFlow, extendedDungeonFlow);
+ foreach (ExtendedItem extendedItem in ExtendedItems)
+ TryAdd(ExtendedItemDictionary, extendedItem.Item, extendedItem);
+ foreach (ExtendedEnemyType extendedEnemyType in ExtendedEnemyTypes)
+ TryAdd(ExtendedEnemyTypeDictionary, extendedEnemyType.EnemyType, extendedEnemyType);
+ foreach (ExtendedBuyableVehicle extendedBuyableVehicle in ExtendedBuyableVehicles)
+ TryAdd(ExtendedBuyableVehicleDictionary, extendedBuyableVehicle.BuyableVehicle, extendedBuyableVehicle);
+ }
+
+ internal static void TryAdd(Dictionary dict, T1 key, T2 value)
+ {
+ if (!dict.ContainsKey(key))
+ dict.Add(key, value);
+ else
+ DebugHelper.LogError("Could not add " + key.ToString() + " to dictionary.", DebugType.Developer);
+ }
+
+ public static bool TryGetExtendedContent(SelectableLevel selectableLevel, out ExtendedLevel extendedLevel)
+ {
+ return (ExtendedLevelDictionary.TryGetValue(selectableLevel, out extendedLevel));
+ }
+
+ public static bool TryGetExtendedContent(DungeonFlow dungeonFlow, out ExtendedDungeonFlow extendedDungeonFlow)
+ {
+ return (ExtendedDungeonFlowDictionary.TryGetValue(dungeonFlow, out extendedDungeonFlow));
+ }
+
+ public static bool TryGetExtendedContent(Item item, out ExtendedItem extendedItem)
+ {
+ return (ExtendedItemDictionary.TryGetValue(item, out extendedItem));
+ }
+
+ public static bool TryGetExtendedContent(EnemyType enemyType, out ExtendedEnemyType extendedEnemyType)
+ {
+ return (ExtendedEnemyTypeDictionary.TryGetValue(enemyType, out extendedEnemyType));
+ }
+
+ public static bool TryGetExtendedContent(BuyableVehicle buyableVehicle, out ExtendedBuyableVehicle extendedBuyableVehicle)
+ {
+ return (ExtendedBuyableVehicleDictionary.TryGetValue(buyableVehicle, out extendedBuyableVehicle));
+ }
}
public static class OriginalContent
{
+ public static StartOfRound StartOfRound => Patches.StartOfRound;
+ public static RoundManager RoundManager => Patches.RoundManager;
+ public static Terminal Terminal => Patches.Terminal;
+ public static TimeOfDay TimeOfDay => Patches.TimeOfDay;
+
//Levels
public static List SelectableLevels { get; internal set; } = new List();
diff --git a/LethalLevelLoader/General/EventPatches.cs b/LethalLevelLoader/General/EventPatches.cs
index f2c7f84..16e5e99 100644
--- a/LethalLevelLoader/General/EventPatches.cs
+++ b/LethalLevelLoader/General/EventPatches.cs
@@ -133,7 +133,7 @@ internal static void RoundManagerSpawnSyncedProps_Postfix()
}
}
- private static EnemyVent cachedSelectedVent;
+ private static EnemyVent? cachedSelectedVent;
[HarmonyPriority(Patches.harmonyPriority)]
[HarmonyPatch(typeof(RoundManager), "SpawnEnemyFromVent")]
[HarmonyPrefix]
@@ -161,7 +161,7 @@ internal static void RoundManagerSpawnEventFromVent_Postfix()
[HarmonyPostfix]
internal static void RoundManagerSpawnMapObjects_Postfix()
{
- if (DungeonManager.CurrentExtendedDungeonFlow != null)
+ if (DungeonManager.CurrentExtendedDungeonFlow != null && LevelManager.CurrentExtendedLevel != null)
{
List mapObjects = new List();
foreach (GameObject rootObject in SceneManager.GetSceneByName(LevelManager.CurrentExtendedLevel.SelectableLevel.sceneName).GetRootGameObjects())
@@ -249,9 +249,9 @@ internal static void EntranceTeleportTeleportPlayerServerRpc_Prefix(EntranceTele
[HarmonyPriority(Patches.harmonyPriority)]
[HarmonyPatch(typeof(LungProp), "EquipItem")]
[HarmonyPrefix]
- internal static void LungPropEquipItem_Postfix(LungProp __instance)
+ internal static void LungPropEquipItem_Prefix(LungProp __instance)
{
- if (__instance.IsServer == true && __instance.isLungDockedInElevator)
+ if (__instance.IsServer == true && __instance.isLungDocked)
{
if (DungeonManager.CurrentExtendedDungeonFlow != null)
{
@@ -285,18 +285,27 @@ internal static void TimeOfDayGetDayPhase_Postfix(DayMode __result)
public class ExtendedEvent
{
public delegate void ParameterEvent(T param);
- private event ParameterEvent onParameterEvent;
+
+ private event ParameterEvent? onParameterEvent;
+ private event Action? onEvent;
+
public bool HasListeners => (Listeners != 0);
public int Listeners { get; internal set; }
- public void Invoke(T param) { onParameterEvent?.Invoke(param); }
+
+ public void Invoke(T param) { onParameterEvent?.Invoke(param); onEvent?.Invoke(); }
+ public void Invoke() { onEvent?.Invoke(); }
+
public void AddListener(ParameterEvent listener) { onParameterEvent += listener; Listeners++; }
+ public void AddListener(Action listener) { onEvent += listener; Listeners++; }
+
public void RemoveListener(ParameterEvent listener) { onParameterEvent -= listener; Listeners--; }
+ public void RemoveListener(Action listener) { onEvent -= listener; Listeners--; }
}
public class ExtendedEvent
{
public delegate void Event();
- private event Event onEvent;
+ private event Event? onEvent;
public bool HasListeners => (Listeners != 0);
public int Listeners { get; internal set; }
public void Invoke() { onEvent?.Invoke(); }
diff --git a/LethalLevelLoader/General/Extensions.cs b/LethalLevelLoader/General/Extensions.cs
index c862b9d..7bc5d10 100644
--- a/LethalLevelLoader/General/Extensions.cs
+++ b/LethalLevelLoader/General/Extensions.cs
@@ -33,7 +33,7 @@ public static List GetTiles(this DungeonFlow dungeonFlow)
foreach (Tile tile in new List(tilesList))
if (tile == null)
- tilesList.Remove(tile);
+ tilesList.Remove(tile!);
return (tilesList);
}
diff --git a/LethalLevelLoader/General/OptionalPatches/LethalLibPatches.cs b/LethalLevelLoader/General/OptionalPatches/LethalLibPatches.cs
new file mode 100644
index 0000000..99fd793
--- /dev/null
+++ b/LethalLevelLoader/General/OptionalPatches/LethalLibPatches.cs
@@ -0,0 +1,30 @@
+using HarmonyLib;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace LethalLevelLoader
+{
+ internal class LethalLibPatches
+ {
+ [HarmonyPriority(Patches.harmonyPriority)]
+ [HarmonyPatch(typeof(LethalLib.Modules.Dungeon), "RoundManager_Start")]
+ [HarmonyPrefix]
+ internal static bool Dungeon_Start_Prefix(Action orig, RoundManager self)
+ {
+ DebugHelper.LogWarning("Disabling LethalLib Dungeon.RoundManager_Start() Function To Prevent Conflicts", DebugType.User);
+ orig(self);
+ return (false);
+ }
+
+ [HarmonyPriority(Patches.harmonyPriority)]
+ [HarmonyPatch(typeof(LethalLib.Modules.Dungeon), "RoundManager_GenerateNewFloor")]
+ [HarmonyPrefix]
+ internal static bool Dungeon_GenerateNewFloor_Prefix(Action orig, RoundManager self)
+ {
+ DebugHelper.LogWarning("Disabling LethalLib Dungeon.RoundManager_GenerateNewFloor() Function To Prevent Conflicts", DebugType.User);
+ orig(self);
+ return (false);
+ }
+ }
+}
diff --git a/LethalLevelLoader/General/Patches.cs b/LethalLevelLoader/General/Patches.cs
index 6d3efbe..96c92e6 100644
--- a/LethalLevelLoader/General/Patches.cs
+++ b/LethalLevelLoader/General/Patches.cs
@@ -18,6 +18,8 @@
using UnityEngine;
using UnityEngine.Audio;
using UnityEngine.Device;
+using UnityEngine.InputSystem.Utilities;
+using UnityEngine.Rendering.HighDefinition;
using UnityEngine.SceneManagement;
using static LethalLevelLoader.AssetBundleLoader;
using NetworkManager = Unity.Netcode.NetworkManager;
@@ -33,10 +35,10 @@ internal static class Patches
internal static List allSceneNamesCalledToLoad = new List();
//Singletons and such for these are set in each classes Awake function, But they all are accessible on the first awake function of the earliest one of these four managers awake function, so i grab them directly via findobjectoftype to safely access them as early as possible.
- public static StartOfRound StartOfRound { get; internal set; }
- public static RoundManager RoundManager { get; internal set; }
- public static Terminal Terminal { get; internal set; }
- public static TimeOfDay TimeOfDay { get; internal set; }
+ public static StartOfRound StartOfRound { get; internal set; } = null!;
+ public static RoundManager RoundManager { get; internal set; } = null!;
+ public static Terminal Terminal { get; internal set; } = null!;
+ public static TimeOfDay TimeOfDay { get; internal set; } = null!;
[HarmonyPriority(harmonyPriority)]
[HarmonyPatch(typeof(PreInitSceneScript), "Awake")]
@@ -210,9 +212,38 @@ internal static void StartOfRoundAwake_Prefix(StartOfRound __instance)
//Initialize ExtendedContent Objects For Custom Content.
AssetBundleLoader.InitializeBundles();
+ PatchedContent.PopulateContentDictionaries();
+
foreach (ExtendedLevel extendedLevel in PatchedContent.CustomExtendedLevels)
extendedLevel.SetLevelID();
+ foreach (WeatherEffect weatherEffect in TimeOfDay.effects)
+ {
+ if (weatherEffect.effectObject != null && weatherEffect.effectObject.name == "DustStorm")
+ if (weatherEffect.effectObject.TryGetComponent(out LocalVolumetricFog dustFog))
+ {
+ LevelLoader.dustCloudFog = dustFog;
+ LevelLoader.defaultDustCloudFogVolumeSize = dustFog.parameters.size;
+ break;
+ }
+ }
+
+ LevelLoader.foggyFog = TimeOfDay.foggyWeather;
+ LevelLoader.defaultFoggyFogVolumeSize = TimeOfDay.foggyWeather.parameters.size;
+
+ foreach (ExtendedLevel vanillaLevel in PatchedContent.VanillaExtendedLevels)
+ {
+ vanillaLevel.OverrideDustStormVolumeSize = LevelLoader.defaultDustCloudFogVolumeSize;
+ vanillaLevel.OverrideFoggyVolumeSize = LevelLoader.defaultFoggyFogVolumeSize;
+ }
+ foreach (ExtendedLevel customLevel in PatchedContent.CustomExtendedLevels)
+ {
+ if (customLevel.OverrideDustStormVolumeSize == Vector3.zero)
+ customLevel.OverrideDustStormVolumeSize = LevelLoader.defaultDustCloudFogVolumeSize;
+ if (customLevel.OverrideFoggyVolumeSize == Vector3.zero)
+ customLevel.OverrideFoggyVolumeSize = LevelLoader.defaultFoggyFogVolumeSize;
+ }
+
//Some Debugging.
string debugString = "LethalLevelLoader Loaded The Following ExtendedLevels:" + "\n";
foreach (ExtendedLevel extendedLevel in PatchedContent.ExtendedLevels)
@@ -314,6 +345,7 @@ internal static void StartOfRoundAwake_Prefix(StartOfRound __instance)
TerminalManager.AddTerminalNodeEventListener(TerminalManager.moonsKeyword.specialKeywordResult, TerminalManager.RefreshMoonsCataloguePage, TerminalManager.LoadNodeActionType.After);
}
+ LevelLoader.defaultFootstepSurfaces = new List(StartOfRound.footstepSurfaces).ToArray();
//We Might Not Need This Now
/*if (LevelManager.invalidSaveLevelID != -1 && StartOfRound.levels.Length > LevelManager.invalidSaveLevelID)
{
@@ -427,7 +459,7 @@ internal static void TerminalParseWord_Postfix(Terminal __instance, ref Terminal
{
if (__result != null)
{
- TerminalKeyword newKeyword = TerminalManager.TryFindAlternativeNoun(__instance, __result, playerWord);
+ TerminalKeyword? newKeyword = TerminalManager.TryFindAlternativeNoun(__instance, __result, playerWord);
if (newKeyword != null)
__result = newKeyword;
}
@@ -494,7 +526,7 @@ internal static void OnSceneLoaded(Scene scene, LoadSceneMode loadSceneMode)
if (LevelManager.CurrentExtendedLevel != null && LevelManager.CurrentExtendedLevel.IsLevelLoaded)
foreach (GameObject rootObject in SceneManager.GetSceneByName(LevelManager.CurrentExtendedLevel.SelectableLevel.sceneName).GetRootGameObjects())
{
- LevelLoader.UpdateStoryLogs(LevelManager.CurrentExtendedLevel, rootObject);
+ LevelLoader.RefreshFogSize(LevelManager.CurrentExtendedLevel);
ContentRestorer.RestoreAudioAssetReferencesInParent(rootObject);
}
@@ -508,7 +540,7 @@ internal static void StartOfRoundStartGame_Prefix()
if (LethalLevelLoaderNetworkManager.networkManager.IsServer == false)
return;
- ExtendedLevel extendedLevel = LevelManager.CurrentExtendedLevel;
+ ExtendedLevel? extendedLevel = LevelManager.CurrentExtendedLevel;
if (extendedLevel == null) return;
@@ -517,7 +549,7 @@ internal static void StartOfRoundStartGame_Prefix()
RoundManager.InitializeRandomNumberGenerators();
int counter = 1;
- foreach (StringWithRarity sceneSelection in LevelManager.CurrentExtendedLevel.SceneSelections)
+ foreach (StringWithRarity sceneSelection in LevelManager.CurrentExtendedLevel!.SceneSelections)
{
DebugHelper.Log("Scene Selection #" + counter + " \"" + sceneSelection.Name + "\" (" + sceneSelection.Rarity + ")", DebugType.Developer);
counter++;
@@ -619,6 +651,20 @@ internal static void RoundManagerSpawnOutsideHazards_Prefix()
RoundManager.quicksandPrefab = LevelManager.CurrentExtendedLevel.OverrideQuicksandPrefab;
}
+ [HarmonyPriority(harmonyPriority)]
+ [HarmonyPatch(typeof(RoundManager), nameof(RoundManager.FinishGeneratingNewLevelClientRpc))]
+ [HarmonyPostfix]
+ internal static void RoundManagerFinishGeneratingNewLevelClientRpc_Prefix()
+ {
+ if (TimeOfDay.sunAnimator != null)
+ {
+ LevelLoader.RefreshFootstepSurfaces();
+ LevelLoader.BakeSceneColliderMaterialData(TimeOfDay.sunAnimator.gameObject.scene);
+ if (LevelLoader.vanillaWaterShader != null)
+ LevelLoader.TryRestoreWaterShaders(TimeOfDay.sunAnimator.gameObject.scene);
+ }
+ }
+
/*
[HarmonyPriority(harmonyPriority)]
[HarmonyPatch(typeof(MoldSpreadManager), nameof(MoldSpreadManager.Start))]
@@ -683,43 +729,15 @@ internal static void RoundManagerSpawnMapObjects_Postfix()
temporarySpawnableMapObjectList.Clear();
}
- internal static GameObject previousHit;
- internal static FootstepSurface previouslyAssignedFootstepSurface;
-
- [HarmonyPriority(harmonyPriority)]
- [HarmonyPatch(typeof(PlayerControllerB), "GetCurrentMaterialStandingOn")]
- [HarmonyPrefix]
- internal static bool PlayerControllerBGetCurrentMaterialStandingOn_Prefix(PlayerControllerB __instance)
- {
- /*if (LevelManager.CurrentExtendedLevel.extendedFootstepSurfaces.Count != 0)
- if (Physics.Raycast(new Ray(__instance.thisPlayerBody.position + Vector3.up, -Vector3.up), out RaycastHit hit, 6f, Patches.StartOfRound.walkableSurfacesMask, QueryTriggerInteraction.Ignore))
- if (hit.collider.gameObject == previousHit)
- return (false);*/
- return (true);
- }
+ static FootstepSurface? previousFootstepSurface;
[HarmonyPriority(harmonyPriority)]
[HarmonyPatch(typeof(PlayerControllerB), "GetCurrentMaterialStandingOn")]
[HarmonyPostfix]
internal static void PlayerControllerBGetCurrentMaterialStandingOn_Postfix(PlayerControllerB __instance)
{
- /*if (LevelManager.CurrentExtendedLevel.extendedFootstepSurfaces.Count != 0)
- if (Physics.Raycast(new Ray(__instance.thisPlayerBody.position + Vector3.up, -Vector3.up), out RaycastHit hit, 6f, Patches.StartOfRound.walkableSurfacesMask, QueryTriggerInteraction.Ignore))
- if (hit.collider.gameObject != previousHit || previousHit == null)
- {
- previousHit = hit.collider.gameObject;
- if (hit.collider.CompareTag("Untagged") || !LevelManager.cachedFootstepSurfaceTagsList.Contains(hit.collider.tag))
- if (hit.collider.gameObject.TryGetComponent(out MeshRenderer meshRenderer))
- foreach (Material material in meshRenderer.sharedMaterials)
- foreach (ExtendedFootstepSurface extendedFootstepSurface in LevelManager.CurrentExtendedLevel.extendedFootstepSurfaces)
- foreach (Material associatedMaterial in extendedFootstepSurface.associatedMaterials)
- if (material.name == associatedMaterial.name)
- {
- __instance.currentFootstepSurfaceIndex = extendedFootstepSurface.arrayIndex;
- return;
- }
- }
- */
+ if (LevelLoader.TryGetFootstepSurface(__instance.hit.collider, out FootstepSurface footstepSurface))
+ __instance.currentFootstepSurfaceIndex = StartOfRound.footstepSurfaces.IndexOf(footstepSurface);
}
//DunGen Optimization Patches (Credit To LadyRaphtalia, Author Of Scarlet Devil Mansion)
diff --git a/LethalLevelLoader/General/SafetyPatches.cs b/LethalLevelLoader/General/SafetyPatches.cs
index a9facf7..232c5ff 100644
--- a/LethalLevelLoader/General/SafetyPatches.cs
+++ b/LethalLevelLoader/General/SafetyPatches.cs
@@ -132,25 +132,5 @@ internal static void TimeOfDaySetWeatherBasedOnVariables_Prefix(TimeOfDay __inst
}
}
}
-
- [HarmonyPriority(harmonyPriority)]
- [HarmonyPatch(typeof(LethalLib.Modules.Dungeon), "RoundManager_Start")]
- [HarmonyPrefix]
- internal static bool Dungeon_Start_Prefix(Action orig, RoundManager self)
- {
- DebugHelper.LogWarning("Disabling LethalLib Dungeon.RoundManager_Start() Function To Prevent Conflicts", DebugType.User);
- orig(self);
- return (false);
- }
-
- [HarmonyPriority(harmonyPriority)]
- [HarmonyPatch(typeof(LethalLib.Modules.Dungeon), "RoundManager_GenerateNewFloor")]
- [HarmonyPrefix]
- internal static bool Dungeon_GenerateNewFloor_Prefix(Action orig, RoundManager self)
- {
- DebugHelper.LogWarning("Disabling LethalLib Dungeon.RoundManager_GenerateNewFloor() Function To Prevent Conflicts", DebugType.User);
- orig(self);
- return (false);
- }
}
}
diff --git a/LethalLevelLoader/LethalLevelLoader.csproj b/LethalLevelLoader/LethalLevelLoader.csproj
index 0293a6f..6b99fe6 100644
--- a/LethalLevelLoader/LethalLevelLoader.csproj
+++ b/LethalLevelLoader/LethalLevelLoader.csproj
@@ -25,6 +25,7 @@
embedded
$([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)'))=./
+ enable
@@ -91,12 +92,24 @@
-
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/LethalLevelLoader/Loaders/DungeonLoader.cs b/LethalLevelLoader/Loaders/DungeonLoader.cs
index e367d39..e7b8a76 100644
--- a/LethalLevelLoader/Loaders/DungeonLoader.cs
+++ b/LethalLevelLoader/Loaders/DungeonLoader.cs
@@ -27,7 +27,7 @@ public class ExtendedDungeonFlowWithRarity
public static class DungeonLoader
{
- internal static GameObject defaultKeyPrefab;
+ internal static GameObject defaultKeyPrefab = null!;
internal static void SelectDungeon()
{
@@ -39,8 +39,8 @@ internal static void SelectDungeon()
internal static void PrepareDungeon()
{
DungeonGenerator dungeonGenerator = Patches.RoundManager.dungeonGenerator.Generator;
- ExtendedLevel currentExtendedLevel = LevelManager.CurrentExtendedLevel;
- ExtendedDungeonFlow currentExtendedDungeonFlow = DungeonManager.CurrentExtendedDungeonFlow;
+ ExtendedLevel currentExtendedLevel = LevelManager.CurrentExtendedLevel!; // checked for null in calling method
+ ExtendedDungeonFlow currentExtendedDungeonFlow = DungeonManager.CurrentExtendedDungeonFlow!;
//PatchDungeonSize(dungeonGenerator, currentExtendedLevel, currentExtendedDungeonFlow);
PatchFireEscapes(dungeonGenerator, currentExtendedLevel, SceneManager.GetSceneByName(currentExtendedLevel.SelectableLevel.sceneName));
@@ -49,8 +49,8 @@ internal static void PrepareDungeon()
public static float GetClampedDungeonSize()
{
- ExtendedDungeonFlow extendedDungeonFlow = DungeonManager.CurrentExtendedDungeonFlow;
- ExtendedLevel extendedLevel = LevelManager.CurrentExtendedLevel;
+ ExtendedDungeonFlow? extendedDungeonFlow = DungeonManager.CurrentExtendedDungeonFlow;
+ ExtendedLevel? extendedLevel = LevelManager.CurrentExtendedLevel;
float calculatedMultiplier = CalculateDungeonMultiplier(LevelManager.CurrentExtendedLevel, DungeonManager.CurrentExtendedDungeonFlow);
if (DungeonManager.CurrentExtendedDungeonFlow != null && DungeonManager.CurrentExtendedDungeonFlow.IsDynamicDungeonSizeRestrictionEnabled == true)
{
@@ -99,7 +99,7 @@ internal static void PatchFireEscapes(DungeonGenerator dungeonGenerator, Extende
{
string debugString = "Fire Exit Patch Report, Details Below;" + "\n" + "\n";
- if (DungeonManager.TryGetExtendedDungeonFlow(dungeonGenerator.DungeonFlow, out ExtendedDungeonFlow extendedDungeonFlow))
+ if (DungeonManager.TryGetExtendedDungeonFlow(dungeonGenerator.DungeonFlow, out ExtendedDungeonFlow? extendedDungeonFlow))
{
List entranceTeleports = GetEntranceTeleports(scene).OrderBy(o => o.entranceId).ToList();
diff --git a/LethalLevelLoader/Loaders/LevelLoader.cs b/LethalLevelLoader/Loaders/LevelLoader.cs
index 63a9888..275c651 100644
--- a/LethalLevelLoader/Loaders/LevelLoader.cs
+++ b/LethalLevelLoader/Loaders/LevelLoader.cs
@@ -9,18 +9,36 @@
using Unity.AI.Navigation;
using UnityEngine.AI;
using LethalLevelLoader.Tools;
+using UnityEngine.Rendering.HighDefinition;
+using UnityEngine.Rendering;
namespace LethalLevelLoader
{
- public class LevelLoader
+ public static class LevelLoader
{
internal static List customLevelMeshCollidersList = new List();
- internal static AnimatorOverrideController shipAnimatorOverrideController;
- internal static AnimationClip defaultShipFlyToMoonClip;
- internal static AnimationClip defaultShipFlyFromMoonClip;
+ internal static AnimatorOverrideController shipAnimatorOverrideController = null!;
+ internal static AnimationClip defaultShipFlyToMoonClip = null!;
+ internal static AnimationClip defaultShipFlyFromMoonClip = null!;
- internal static GameObject defaultQuicksandPrefab;
+ internal static Vector3 defaultDustCloudFogVolumeSize;
+ internal static Vector3 defaultFoggyFogVolumeSize;
+
+ internal static LocalVolumetricFog? dustCloudFog;
+ internal static LocalVolumetricFog? foggyFog;
+
+
+ internal static GameObject defaultQuicksandPrefab = null!;
+
+ internal static FootstepSurface[] defaultFootstepSurfaces = null!;
+
+ internal static Dictionary> cachedLevelColliderMaterialDictionary = new Dictionary>();
+ internal static Dictionary> cachedLevelMaterialColliderDictionary = new Dictionary>();
+ internal static Dictionary activeExtendedFootstepSurfaceDictionary = new Dictionary();
+ internal static LayerMask triggerMask;
+
+ internal static Shader vanillaWaterShader;
internal static async void EnableMeshColliders()
{
@@ -51,15 +69,137 @@ internal static async Task EnableMeshCollider(MeshCollider meshCollider)
await Task.Yield();
}
- internal static void UpdateStoryLogs(ExtendedLevel extendedLevel, GameObject sceneRootObject)
- {
- }
-
internal static void RefreshShipAnimatorClips(ExtendedLevel extendedLevel)
{
DebugHelper.Log("Refreshing Ship Animator Clips!", DebugType.Developer);
shipAnimatorOverrideController["HangarShipLandB"] = extendedLevel.ShipFlyToMoonClip;
shipAnimatorOverrideController["ShipLeave"] = extendedLevel.ShipFlyFromMoonClip;
}
+
+ internal static void RefreshFogSize(ExtendedLevel extendedLevel)
+ {
+ if (dustCloudFog != null)
+ dustCloudFog.parameters.size = extendedLevel.OverrideDustStormVolumeSize;
+ if (foggyFog != null)
+ foggyFog.parameters.size = extendedLevel.OverrideFoggyVolumeSize;
+ }
+
+ internal static void RefreshFootstepSurfaces()
+ {
+ List activeFootstepSurfaces = new List(defaultFootstepSurfaces);
+ foreach (ExtendedFootstepSurface extendedSurface in LevelManager.CurrentExtendedLevel.ExtendedMod.ExtendedFootstepSurfaces)
+ {
+ extendedSurface.footstepSurface.surfaceTag = "Untagged";
+ activeFootstepSurfaces.Add(extendedSurface.footstepSurface);
+ }
+
+ Patches.StartOfRound.footstepSurfaces = activeFootstepSurfaces.ToArray();
+ }
+
+ internal static void TryRestoreWaterShaders(Scene scene)
+ {
+ List uniqueMaterials = new List();
+ foreach (MeshRenderer meshRenderer in Object.FindObjectsByType(FindObjectsSortMode.None))
+ if (meshRenderer.gameObject.scene == scene)
+ foreach (Material sharedMaterial in meshRenderer.sharedMaterials)
+ {
+ if (sharedMaterial != null && !string.IsNullOrEmpty(sharedMaterial.name))
+ if (!uniqueMaterials.Contains(sharedMaterial))
+ uniqueMaterials.Add(sharedMaterial);
+ }
+
+ foreach (Material sharedMaterial in uniqueMaterials)
+ ContentRestorer.TryRestoreWaterShader(sharedMaterial);
+ }
+
+ internal static void BakeSceneColliderMaterialData(Scene scene)
+ {
+ cachedLevelColliderMaterialDictionary.Clear();
+ cachedLevelMaterialColliderDictionary.Clear();
+ activeExtendedFootstepSurfaceDictionary = GetActiveExtendedFoostepSurfaceDictionary();
+
+ triggerMask = LayerMask.NameToLayer("Triggers");
+
+ List allValidSceneColliders = new List();
+
+ foreach (GameObject rootObject in scene.GetRootGameObjects())
+ {
+ foreach (Collider collider in rootObject.GetComponents())
+ {
+ if (ValidateCollider(collider) && !allValidSceneColliders.Contains(collider))
+ allValidSceneColliders.Add(collider);
+ }
+ foreach (Collider collider in rootObject.GetComponentsInChildren())
+ {
+ if (ValidateCollider(collider) && !allValidSceneColliders.Contains(collider))
+ allValidSceneColliders.Add(collider);
+ }
+ }
+
+ foreach (Collider sceneCollider in allValidSceneColliders)
+ {
+ if (sceneCollider.TryGetComponent(out MeshRenderer meshRenderer))
+ {
+ List validMaterials = new List();
+ foreach (Material material in meshRenderer.sharedMaterials)
+ if (material != null && !string.IsNullOrEmpty(material.name))
+ validMaterials.Add(material);
+
+ if (!cachedLevelColliderMaterialDictionary.ContainsKey(sceneCollider))
+ cachedLevelColliderMaterialDictionary.Add(sceneCollider, new List(validMaterials));
+
+ foreach (Material material in validMaterials)
+ {
+ if (!cachedLevelMaterialColliderDictionary.ContainsKey(material.name))
+ cachedLevelMaterialColliderDictionary.Add(material.name, new List { sceneCollider });
+ else if (!cachedLevelMaterialColliderDictionary[material.name].Contains(sceneCollider))
+ cachedLevelMaterialColliderDictionary[material.name].Add(sceneCollider);
+ }
+ }
+ }
+
+ //DebugHelper.DebugCachedLevelColliderData();
+ }
+
+ internal static bool ValidateCollider(Collider collider)
+ {
+ if (collider == null) return (false);
+ if (collider.gameObject.activeSelf == false) return (false);
+ if (collider.isTrigger == true) return (false);
+ if (collider.gameObject.layer == triggerMask) return (false);
+ if (collider.gameObject.CompareTag("Untagged") == false) return (false);
+
+ return (true);
+ }
+
+ internal static Dictionary GetActiveExtendedFoostepSurfaceDictionary()
+ {
+ Dictionary returnDict = new Dictionary();
+
+ foreach (ExtendedFootstepSurface extendedFootstepSurface in LevelManager.CurrentExtendedLevel.ExtendedMod.ExtendedFootstepSurfaces)
+ foreach (Material material in extendedFootstepSurface.associatedMaterials)
+ if (material != null && !string.IsNullOrEmpty(material.name))
+ if (!returnDict.ContainsKey(material.name))
+ returnDict.Add(material.name, extendedFootstepSurface.footstepSurface);
+
+
+ return (returnDict);
+ }
+
+ public static bool TryGetFootstepSurface(Collider collider, out FootstepSurface? footstepSurface)
+ {
+ footstepSurface = null;
+
+ if (collider == null)
+ return (false);
+
+ if (cachedLevelColliderMaterialDictionary.TryGetValue(collider, out List materials))
+ if (materials != null)
+ foreach (Material material in materials)
+ if (material != null && !string.IsNullOrEmpty(material.name))
+ activeExtendedFootstepSurfaceDictionary.TryGetValue(material.name, out footstepSurface);
+
+ return (footstepSurface != null);
+ }
}
}
\ No newline at end of file
diff --git a/LethalLevelLoader/Patches/DungeonManager.cs b/LethalLevelLoader/Patches/DungeonManager.cs
index f4ddf6c..373ad99 100644
--- a/LethalLevelLoader/Patches/DungeonManager.cs
+++ b/LethalLevelLoader/Patches/DungeonManager.cs
@@ -3,6 +3,7 @@
using HarmonyLib;
using System;
using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
using System.Linq;
using UnityEngine;
using UnityEngine.Events;
@@ -11,13 +12,13 @@ namespace LethalLevelLoader
{
public class DungeonManager
{
- public static ExtendedDungeonFlow CurrentExtendedDungeonFlow
+ public static ExtendedDungeonFlow? CurrentExtendedDungeonFlow
{
get
{
- ExtendedDungeonFlow returnFlow = null;
+ ExtendedDungeonFlow? returnFlow = null;
if (Patches.RoundManager != null && Patches.RoundManager.dungeonGenerator != null)
- if (TryGetExtendedDungeonFlow(Patches.RoundManager.dungeonGenerator.Generator.DungeonFlow, out ExtendedDungeonFlow flow))
+ if (TryGetExtendedDungeonFlow(Patches.RoundManager.dungeonGenerator.Generator.DungeonFlow, out ExtendedDungeonFlow? flow))
returnFlow = flow;
return (returnFlow);
}
@@ -119,10 +120,10 @@ internal static void RefreshDungeonFlowIDs()
Patches.RoundManager.dungeonFlowTypes = indoorMapTypes.ToArray();
}
- internal static bool TryGetExtendedDungeonFlow(DungeonFlow dungeonFlow, out ExtendedDungeonFlow returnExtendedDungeonFlow, ContentType contentType = ContentType.Any)
+ internal static bool TryGetExtendedDungeonFlow(DungeonFlow dungeonFlow, [NotNullWhen(returnValue: true)] out ExtendedDungeonFlow? returnExtendedDungeonFlow, ContentType contentType = ContentType.Any)
{
returnExtendedDungeonFlow = null;
- List extendedDungeonFlowsList = null;
+ List extendedDungeonFlowsList = null!;
if (dungeonFlow == null) return (false);
@@ -140,7 +141,7 @@ internal static bool TryGetExtendedDungeonFlow(DungeonFlow dungeonFlow, out Exte
return (returnExtendedDungeonFlow != null);
}
- internal static bool TryGetExtendedDungeonFlow(IndoorMapType indoorMapType, out ExtendedDungeonFlow returnExtendedDungeonFlow, ContentType contentType = ContentType.Any)
+ internal static bool TryGetExtendedDungeonFlow(IndoorMapType indoorMapType, out ExtendedDungeonFlow? returnExtendedDungeonFlow, ContentType contentType = ContentType.Any)
{
return (TryGetExtendedDungeonFlow(indoorMapType.dungeonFlow, out returnExtendedDungeonFlow, contentType));
}
diff --git a/LethalLevelLoader/Patches/EnemyManager.cs b/LethalLevelLoader/Patches/EnemyManager.cs
index 5346f50..69ae689 100644
--- a/LethalLevelLoader/Patches/EnemyManager.cs
+++ b/LethalLevelLoader/Patches/EnemyManager.cs
@@ -20,9 +20,9 @@ public static void InjectCustomEnemyTypesIntoLevelViaDynamicRarity(ExtendedLevel
foreach (ExtendedEnemyType extendedEnemyType in PatchedContent.CustomExtendedEnemyTypes)
{
string debugString = string.Empty;
- SpawnableEnemyWithRarity alreadyInjectedInsideEnemy = null;
- SpawnableEnemyWithRarity alreadyInjectedOutsideEnemy = null;
- SpawnableEnemyWithRarity alreadyInjectedDaytimeEnemy = null;
+ SpawnableEnemyWithRarity? alreadyInjectedInsideEnemy;
+ SpawnableEnemyWithRarity? alreadyInjectedOutsideEnemy;
+ SpawnableEnemyWithRarity? alreadyInjectedDaytimeEnemy;
foreach (SpawnableEnemyWithRarity spawnableEnemyWithRarity in extendedLevel.SelectableLevel.Enemies)
if (spawnableEnemyWithRarity.enemyType == extendedEnemyType)
@@ -56,7 +56,7 @@ public static void InjectCustomEnemyTypesIntoLevelViaDynamicRarity(ExtendedLevel
internal static bool TryInjectEnemyIntoPool(List enemyPool, ExtendedEnemyType extendedEnemy, int newRarity, out SpawnableEnemyWithRarity spawnableEnemyWithRarity)
{
- spawnableEnemyWithRarity = null;
+ spawnableEnemyWithRarity = null!;
foreach (SpawnableEnemyWithRarity currentSpawnableEnemyWithRarity in enemyPool)
if (currentSpawnableEnemyWithRarity.enemyType == extendedEnemy.EnemyType)
spawnableEnemyWithRarity = currentSpawnableEnemyWithRarity;
diff --git a/LethalLevelLoader/Patches/ItemManager.cs b/LethalLevelLoader/Patches/ItemManager.cs
index c53457b..028b31c 100644
--- a/LethalLevelLoader/Patches/ItemManager.cs
+++ b/LethalLevelLoader/Patches/ItemManager.cs
@@ -21,7 +21,7 @@ public static void InjectCustomItemsIntoLevelViaDynamicRarity(ExtendedLevel exte
if (extendedItem.Item.isScrap)
{
string debugString = string.Empty;
- SpawnableItemWithRarity alreadyInjectedItem = null;
+ SpawnableItemWithRarity? alreadyInjectedItem = null;
foreach (SpawnableItemWithRarity spawnableItem in extendedLevel.SelectableLevel.spawnableScrap)
if (spawnableItem.spawnableItem == extendedItem)
alreadyInjectedItem = spawnableItem;
diff --git a/LethalLevelLoader/Patches/LethalLevelLoaderNetworkManager.cs b/LethalLevelLoader/Patches/LethalLevelLoaderNetworkManager.cs
index a23fabe..4aec83b 100644
--- a/LethalLevelLoader/Patches/LethalLevelLoaderNetworkManager.cs
+++ b/LethalLevelLoader/Patches/LethalLevelLoaderNetworkManager.cs
@@ -14,8 +14,8 @@ namespace LethalLevelLoader
{
public class LethalLevelLoaderNetworkManager : NetworkBehaviour
{
- public static GameObject networkingManagerPrefab;
- private static LethalLevelLoaderNetworkManager _instance;
+ public static GameObject networkingManagerPrefab = null!;
+ private static LethalLevelLoaderNetworkManager? _instance;
public static LethalLevelLoaderNetworkManager Instance
{
get
@@ -24,11 +24,11 @@ public static LethalLevelLoaderNetworkManager Instance
_instance = UnityEngine.Object.FindObjectOfType();
if (_instance == null)
DebugHelper.LogError("LethalLevelLoaderNetworkManager Could Not Be Found! Returning Null!", DebugType.User);
- return _instance;
+ return _instance!;
}
set { _instance = value; }
}
- public static NetworkManager networkManager;
+ public static NetworkManager networkManager = null!;
private static List queuedNetworkPrefabs = new List();
public static bool networkHasStarted;
@@ -192,7 +192,7 @@ internal static void RegisterPrefabs(NetworkManager networkManager)
public class StringContainer : INetworkSerializable
{
- public string SomeText;
+ public string SomeText = null!;
public void NetworkSerialize(BufferSerializer serializer) where T : IReaderWriter
{
if (serializer.IsWriter)
diff --git a/LethalLevelLoader/Patches/LevelManager.cs b/LethalLevelLoader/Patches/LevelManager.cs
index 8965884..dd8a704 100644
--- a/LethalLevelLoader/Patches/LevelManager.cs
+++ b/LethalLevelLoader/Patches/LevelManager.cs
@@ -2,6 +2,7 @@
using HarmonyLib;
using System;
using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reflection;
using Unity.AI.Navigation;
@@ -14,13 +15,13 @@ namespace LethalLevelLoader
{
public class LevelManager
{
- public static ExtendedLevel CurrentExtendedLevel
+ public static ExtendedLevel? CurrentExtendedLevel
{
get
{
- ExtendedLevel returnLevel = null;
+ ExtendedLevel? returnLevel = null;
if (Patches.StartOfRound != null)
- if (TryGetExtendedLevel(Patches.StartOfRound.currentLevel, out ExtendedLevel level))
+ if (TryGetExtendedLevel(Patches.StartOfRound.currentLevel, out ExtendedLevel? level))
returnLevel = level;
return returnLevel;
}
@@ -33,11 +34,6 @@ public static ExtendedLevel CurrentExtendedLevel
public static int invalidSaveLevelID = -1;
- public static List cachedFootstepSurfaceTagsList = new List();
- public static List cachedExtendedFootstepSurfaceMaterialsList = new List();
- public static List cachedExtendedFootstepSurfaceGameObjectsList = new List();
- public static Dictionary cachedFootstepSurfacesDictionary = new Dictionary();
-
public static Dictionary dynamicRiskLevelDictionary = new Dictionary()
{
{"D-", 0},
@@ -88,10 +84,10 @@ internal static void InitializeShipAnimatorOverrideController()
//shipAnimator.enabled = false;
}
- public static bool TryGetExtendedLevel(SelectableLevel selectableLevel, out ExtendedLevel returnExtendedLevel, ContentType levelType = ContentType.Any)
+ public static bool TryGetExtendedLevel(SelectableLevel selectableLevel, [NotNullWhen(returnValue: true)] out ExtendedLevel? returnExtendedLevel, ContentType levelType = ContentType.Any)
{
returnExtendedLevel = null;
- List extendedLevelsList = null;
+ List extendedLevelsList = null!;
if (selectableLevel == null) return false;
@@ -111,7 +107,7 @@ public static bool TryGetExtendedLevel(SelectableLevel selectableLevel, out Exte
public static ExtendedLevel GetExtendedLevel(SelectableLevel selectableLevel)
{
- ExtendedLevel returnExtendedLevel = null;
+ ExtendedLevel returnExtendedLevel = null!;
foreach (ExtendedLevel extendedLevel in PatchedContent.ExtendedLevels)
if (extendedLevel.SelectableLevel == selectableLevel)
@@ -308,6 +304,7 @@ public static void LogDayHistory()
DayHistory newDayHistory = new DayHistory();
daysTotal++;
+ newDayHistory.allViableOptions = DungeonManager.GetValidExtendedDungeonFlows(CurrentExtendedLevel, false).Select(e => e.extendedDungeonFlow).ToList();
newDayHistory.extendedLevel = LevelManager.CurrentExtendedLevel;
newDayHistory.extendedDungeonFlow = DungeonManager.CurrentExtendedDungeonFlow;
newDayHistory.day = daysTotal;
@@ -392,8 +389,9 @@ public class DayHistory
{
public int quota;
public int day;
- public ExtendedLevel extendedLevel;
- public ExtendedDungeonFlow extendedDungeonFlow;
+ public ExtendedLevel? extendedLevel;
+ public List? allViableOptions; // this whole class should have a constructor that set all these variables
+ public ExtendedDungeonFlow? extendedDungeonFlow;
public LevelWeatherType weatherEffect;
}
}
\ No newline at end of file
diff --git a/LethalLevelLoader/Patches/SaveManager.cs b/LethalLevelLoader/Patches/SaveManager.cs
index 384ee93..e73e40f 100644
--- a/LethalLevelLoader/Patches/SaveManager.cs
+++ b/LethalLevelLoader/Patches/SaveManager.cs
@@ -10,7 +10,7 @@ namespace LethalLevelLoader
{
internal static class SaveManager
{
- public static LLLSaveFile currentSaveFile;
+ public static LLLSaveFile currentSaveFile = null!;
public static bool parityCheck;
internal static void InitializeSave()
@@ -392,10 +392,10 @@ internal static List GetConstructedSavedShipItemData(Dictiona
string currentSaveFileName = GameNetworkManager.Instance.currentSaveFileName;
- List shipGrabbableItemIDs = null;
- List shipGrabbableItemPos = null;
- List shipScrapValues = null;
- List shipItemSaveData = null;
+ List shipGrabbableItemIDs;
+ List shipGrabbableItemPos;
+ List shipScrapValues;
+ List shipItemSaveData;
if (ES3.KeyExists("shipGrabbableItemIDs", currentSaveFileName))
shipGrabbableItemIDs = ES3.Load("shipGrabbableItemIDs", currentSaveFileName).ToList();
diff --git a/LethalLevelLoader/Patches/TerminalManager.cs b/LethalLevelLoader/Patches/TerminalManager.cs
index 731e3fb..10c709c 100644
--- a/LethalLevelLoader/Patches/TerminalManager.cs
+++ b/LethalLevelLoader/Patches/TerminalManager.cs
@@ -12,7 +12,7 @@ namespace LethalLevelLoader
{
public class TerminalManager
{
- private static Terminal _terminal;
+ private static Terminal? _terminal;
internal static Terminal Terminal
{
get
@@ -24,30 +24,30 @@ internal static Terminal Terminal
}
}
- internal static TerminalNode lockedNode;
+ internal static TerminalNode lockedNode = null!;
- public static MoonsCataloguePage defaultMoonsCataloguePage { get; internal set; }
- public static MoonsCataloguePage currentMoonsCataloguePage { get; internal set; }
+ public static MoonsCataloguePage defaultMoonsCataloguePage { get; internal set; } = null!;
+ public static MoonsCataloguePage currentMoonsCataloguePage { get; internal set; } = null!;
//Cached References To Important Base-Game TerminalKeywords;
- internal static TerminalKeyword routeKeyword;
- internal static TerminalKeyword routeInfoKeyword;
- internal static TerminalKeyword routeConfirmKeyword;
- internal static TerminalKeyword routeDenyKeyword;
- internal static TerminalKeyword moonsKeyword;
- internal static TerminalKeyword viewKeyword;
- internal static TerminalKeyword buyKeyword;
- internal static TerminalNode cancelRouteNode;
- internal static TerminalNode cancelPurchaseNode;
-
- internal static string currentTagFilter;
+ internal static TerminalKeyword routeKeyword = null!;
+ internal static TerminalKeyword routeInfoKeyword = null!;
+ internal static TerminalKeyword routeConfirmKeyword = null!;
+ internal static TerminalKeyword routeDenyKeyword = null!;
+ internal static TerminalKeyword moonsKeyword = null!;
+ internal static TerminalKeyword viewKeyword = null!;
+ internal static TerminalKeyword buyKeyword = null!;
+ internal static TerminalNode cancelRouteNode = null!;
+ internal static TerminalNode cancelPurchaseNode = null!;
+
+ internal static string currentTagFilter = null!;
internal static float defaultTerminalFontSize;
- internal static TerminalKeyword lastParsedVerbKeyword;
+ internal static TerminalKeyword? lastParsedVerbKeyword;
public delegate string PreviewInfoText(ExtendedLevel extendedLevel, PreviewInfoType infoType);
- public static event PreviewInfoText onBeforePreviewInfoTextAdded;
+ public static event PreviewInfoText? onBeforePreviewInfoTextAdded;
//internal static Dictionary> terminalNodeRegisteredEventDictionary = new Dictionary>();
@@ -371,7 +371,7 @@ public static string GetExtendedLevelPreviewInfo(ExtendedLevel extendedLevel)
if (extendedLevel.IsRouteLocked == true)
levelPreviewInfo += " (Locked)";
- string overridePreviewInfo = onBeforePreviewInfoTextAdded?.Invoke(extendedLevel, Settings.levelPreviewInfoType);
+ string? overridePreviewInfo = onBeforePreviewInfoTextAdded?.Invoke(extendedLevel, Settings.levelPreviewInfoType);
if (overridePreviewInfo != null && overridePreviewInfo != string.Empty)
levelPreviewInfo = overridePreviewInfo;
@@ -391,7 +391,7 @@ public static string GetWeatherConditions(ExtendedLevel extendedLevel)
public static string GetHistoryConditions(ExtendedLevel extendedLevel)
{
- DayHistory dayHistory = null;
+ DayHistory? dayHistory = null;
foreach (DayHistory loggedDayHistory in LevelManager.dayHistoryList)
if (loggedDayHistory.extendedLevel == extendedLevel)
@@ -465,9 +465,9 @@ public static string GetOffsetExtendedLevelName(ExtendedLevel extendedLevel)
return returnString;
}
- internal static TerminalKeyword TryFindAlternativeNoun(Terminal terminal, TerminalKeyword foundKeyword, string playerInput)
+ internal static TerminalKeyword? TryFindAlternativeNoun(Terminal terminal, TerminalKeyword? foundKeyword, string playerInput)
{
- if (foundKeyword != null & terminal.hasGottenVerb == false && foundKeyword.isVerb == true)
+ if (foundKeyword != null && terminal.hasGottenVerb == false && foundKeyword.isVerb == true)
lastParsedVerbKeyword = foundKeyword;
if (foundKeyword != null && foundKeyword.isVerb == false && terminal.hasGottenVerb == true && lastParsedVerbKeyword != null)
@@ -775,10 +775,11 @@ internal static void CreateItemTerminalData(ExtendedItem extendedItem)
terminalNodeBuyConfirm.maxCharactersToType = 35;
terminalNodeBuyConfirm.buyItemIndex = buyableItemIndex;
terminalNodeBuyConfirm.isConfirmationNode = false;
+ terminalNodeBuyConfirm.playSyncedClip = 0;
}
//Terminal Info Node
- TerminalNode terminalNodeInfo = null;
+ TerminalNode? terminalNodeInfo = null;
if (!string.IsNullOrEmpty(extendedItem.OverrideInfoNodeDescription))
{
if (extendedItem.BuyInfoNode != null)
@@ -814,12 +815,14 @@ internal static void CreateEnemyTypeTerminalData(ExtendedEnemyType extendedEnemy
TerminalKeyword newEnemyInfoKeyword = CreateNewTerminalKeyword();
newEnemyInfoKeyword.name = extendedEnemyType.name + "BestiaryKeyword";
newEnemyInfoKeyword.word = extendedEnemyType.EnemyDisplayName.ToLower();
+ newEnemyInfoKeyword.defaultVerb = routeInfoKeyword;
TerminalNode newEnemyInfoNode = CreateNewTerminalNode();
newEnemyInfoNode.name = extendedEnemyType.name + "BestiaryNode";
newEnemyInfoNode.displayText = extendedEnemyType.InfoNodeDescription;
newEnemyInfoNode.creatureFileID = extendedEnemyType.EnemyID;
newEnemyInfoNode.creatureName = extendedEnemyType.EnemyDisplayName;
+ newEnemyInfoNode.playSyncedClip = 2;
if (extendedEnemyType.InfoNodeVideoClip != null)
{
@@ -862,6 +865,7 @@ internal static void CreateBuyableVehicleTerminalData(ExtendedBuyableVehicle ext
newVehicleBuyConfirmNode.buyVehicleIndex = extendedBuyableVehicle.VehicleID;
newVehicleBuyConfirmNode.clearPreviousText = true;
newVehicleBuyConfirmNode.maxCharactersToType = 35;
+ newVehicleBuyConfirmNode.playSyncedClip = 0;
newVehicleBuyConfirmNode.displayText =
"Ordered the " + extendedBuyableVehicle.BuyableVehicle.vehicleDisplayName + ". Your new balance is [playerCredits]." + "\n\n" +
"We are so confident in the quality of this product, it comes with a life-time warranty! If your " + extendedBuyableVehicle.BuyableVehicle.vehicleDisplayName + " is lost or destroyed, you can get one free replacement. Items cannot be purchased while the vehicle is en route." + "\n\n";
@@ -931,16 +935,20 @@ internal static List CreateTerminalEventNodes(string newVerbKeywor
return (CreateTerminalEventNodes(newVerbKeywordWord, convertedList));
}
- internal static List CreateTerminalEventNodes(string newVerbKeywordWord, List nounWords, List terminalEventStrings = null, bool createNewVerbKeyword = true)
+ internal static List CreateTerminalEventNodes(string newVerbKeywordWord, List nounWords, List? terminalEventStrings = null, bool createNewVerbKeyword = true)
{
List newTerminalNodes = new List();
- TerminalKeyword verbKeyword = null;
+ TerminalKeyword? verbKeyword = null;
if (createNewVerbKeyword == true)
verbKeyword = CreateNewTerminalKeyword();
else
foreach (TerminalKeyword terminalKeyword in Terminal.terminalNodes.allKeywords)
if (terminalKeyword.isVerb == true && terminalKeyword.word == newVerbKeywordWord.ToLower())
- verbKeyword = terminalKeyword;
+ verbKeyword = terminalKeyword;
+
+ if (verbKeyword == null) // Should this throw? I left the possible NRE where it was, but with a clear message.
+ throw new NullReferenceException($"A new 'VerbKeyword' was not created, and an existing verb called '{newVerbKeywordWord}' wasn't found!");
+
verbKeyword.word = newVerbKeywordWord.ToLower();
verbKeyword.name = newVerbKeywordWord.ToLower() + "Keyword";
verbKeyword.isVerb = true;
diff --git a/LethalLevelLoader/Patches/WeatherManager.cs b/LethalLevelLoader/Patches/WeatherManager.cs
index c361ac0..664b91f 100644
--- a/LethalLevelLoader/Patches/WeatherManager.cs
+++ b/LethalLevelLoader/Patches/WeatherManager.cs
@@ -9,7 +9,7 @@ namespace LethalLevelLoader
{
internal class WeatherManager
{
- public static ExtendedWeatherEffect CurrentExtendedWeatherEffect;
+ public static ExtendedWeatherEffect? CurrentExtendedWeatherEffect; // temporarily marked as nullable since no usage
public static Dictionary vanillaExtendedWeatherEffectsDictionary = new Dictionary();
@@ -111,7 +111,7 @@ public static ExtendedWeatherEffect GetVanillaExtendedWeatherEffect(LevelWeather
if (extendedWeatherEffect.BaseWeatherType == levelWeatherType)
return (extendedWeatherEffect);
- return (null);
+ return (null!);
}
}
}
diff --git a/LethalLevelLoader/Plugin.cs b/LethalLevelLoader/Plugin.cs
index 9bd88e4..1f1d6d3 100644
--- a/LethalLevelLoader/Plugin.cs
+++ b/LethalLevelLoader/Plugin.cs
@@ -1,4 +1,5 @@
using BepInEx;
+using BepInEx.Bootstrap;
using BepInEx.Configuration;
using DunGen;
using HarmonyLib;
@@ -10,32 +11,33 @@
using Unity.Netcode;
using UnityEngine;
using UnityEngine.Device;
+using UnityEngine.Rendering;
using UnityEngine.SceneManagement;
using Application = UnityEngine.Application;
namespace LethalLevelLoader
{
[BepInPlugin(ModGUID, ModName, ModVersion)]
- [BepInDependency(LethalLib.Plugin.ModGUID)]
+ [BepInDependency(LethalLib.Plugin.ModGUID, BepInDependency.DependencyFlags.SoftDependency)]
[BepInDependency(LethalModDataLib.PluginInfo.PLUGIN_GUID)]
public class Plugin : BaseUnityPlugin
{
public const string ModGUID = "imabatby.lethallevelloader";
public const string ModName = "LethalLevelLoader";
- public const string ModVersion = "1.3.0";
+ public const string ModVersion = "1.3.8";
- internal static Plugin Instance;
+ internal static Plugin Instance = null!;
- internal static AssetBundle MainAssets;
+ internal static AssetBundle? MainAssets;
internal static readonly Harmony Harmony = new Harmony(ModGUID);
- internal static BepInEx.Logging.ManualLogSource logger;
+ internal static BepInEx.Logging.ManualLogSource logger = null!;
- public static event Action onBeforeSetup;
- public static event Action onSetupComplete;
+ public static event Action? onBeforeSetup;
+ public static event Action? onSetupComplete;
public static bool IsSetupComplete { get; private set; } = false;
- internal static GameObject networkManagerPrefab;
+ internal static GameObject? networkManagerPrefab;
private void Awake()
{
@@ -46,32 +48,34 @@ private void Awake()
Logger.LogInfo($"LethalLevelLoader loaded!!");
+ //We do this here to try and assure this doesn't accidently catch anything from any AssetBundles
+ LevelLoader.vanillaWaterShader = Shader.Find("Shader Graphs/WaterShaderHDRP");
+ if (LevelLoader.vanillaWaterShader == null)
+ DebugHelper.LogError("Could Not Find Water Shader", DebugType.User);
+
Harmony.PatchAll(typeof(LethalLevelLoaderNetworkManager));
Harmony.PatchAll(typeof(DungeonLoader));
Harmony.PatchAll(typeof(Patches));
Harmony.PatchAll(typeof(EventPatches));
Harmony.PatchAll(typeof(SafetyPatches));
+
+ TrySoftPatch(LethalLib.Plugin.ModGUID, typeof(LethalLibPatches));
NetworkScenePatcher.Patch();
Patches.InitMonoModHooks();
NetcodePatch();
- //AssetBundleLoader.LoadBundles();
- //AssetBundleLoader.Instance.pluginInstace = this;
-
- GameObject test = new GameObject("LethalLevelLoader AssetBundleLoader");
- test.AddComponent().LoadBundles();
+ GameObject assetBundleLoaderObject = new GameObject("LethalLevelLoader AssetBundleLoader");
+ assetBundleLoaderObject.AddComponent().LoadBundles();
if (Application.isEditor)
- DontDestroyOnLoad(test);
+ DontDestroyOnLoad(assetBundleLoaderObject);
else
- test.hideFlags = HideFlags.HideAndDontSave;
+ assetBundleLoaderObject.hideFlags = HideFlags.HideAndDontSave;
AssetBundleLoader.onBundlesFinishedLoading += AssetBundleLoader.LoadContentInBundles;
ConfigLoader.BindGeneralConfigs();
-
- //UnityEngine.Object.FindFirstObjectByType()
}
internal static void OnBeforeSetupInvoke()
@@ -106,8 +110,18 @@ private void NetcodePatch()
}
catch
{
- DebugHelper.Log("NetcodePatcher did a big fucksie wuckise!", DebugType.Developer);
+ DebugHelper.LogError("NetcodePatcher Failed! This Is Very Bad.", DebugType.Developer);
+ }
+ }
+
+ internal static void TrySoftPatch(string pluginName, Type type)
+ {
+ if (Chainloader.PluginInfos.ContainsKey(pluginName))
+ {
+ Harmony.CreateClassProcessor(type, true).Patch();
+ DebugHelper.Log(pluginName + "found, enabling compatability patches.", DebugType.User);
}
+
}
}
}
\ No newline at end of file
diff --git a/LethalLevelLoader/Tools/AssetBundleLoader.cs b/LethalLevelLoader/Tools/AssetBundleLoader.cs
index db04ef3..be275de 100644
--- a/LethalLevelLoader/Tools/AssetBundleLoader.cs
+++ b/LethalLevelLoader/Tools/AssetBundleLoader.cs
@@ -23,22 +23,22 @@ namespace LethalLevelLoader
{
public class AssetBundleLoader : MonoBehaviour
{
- public static AssetBundleLoader Instance;
+ public static AssetBundleLoader Instance = null!;
- internal Plugin pluginInstace;
+ internal Plugin? pluginInstace;
public const string specifiedFileExtension = "*.lethalbundle";
internal static DirectoryInfo lethalLibFile = new DirectoryInfo(Assembly.GetExecutingAssembly().Location);
- internal static DirectoryInfo lethalLibFolder;
- internal static DirectoryInfo pluginsFolder;
+ internal static DirectoryInfo lethalLibFolder = null!;
+ internal static DirectoryInfo pluginsFolder = null!;
internal static Dictionary obtainedExtendedModsDictionary = new Dictionary();
public enum LoadingStatus { Inactive, Loading, Complete };
public static LoadingStatus CurrentLoadingStatus { get; internal set; } = LoadingStatus.Inactive;
- internal static Dictionary assetBundles = new Dictionary();
+ internal static Dictionary assetBundles = new Dictionary();
internal static Dictionary assetBundleLoadTimes = new Dictionary();
internal static Dictionary>> onLethalBundleLoadedRequestDictionary = new Dictionary>>();
@@ -49,7 +49,7 @@ internal static bool HaveBundlesFinishedLoading
get
{
bool bundlesFinishedLoading = true;
- foreach (KeyValuePair assetBundle in assetBundles)
+ foreach (KeyValuePair assetBundle in assetBundles)
if (assetBundle.Value == null)
bundlesFinishedLoading = false;
return (bundlesFinishedLoading);
@@ -61,7 +61,7 @@ internal static int BundlesFinishedLoadingCount
get
{
int bundlesFinishedLoading = 0;
- foreach (KeyValuePair assetBundle in assetBundles)
+ foreach (KeyValuePair assetBundle in assetBundles)
if (assetBundle.Value != null)
bundlesFinishedLoading++;
return (bundlesFinishedLoading);
@@ -69,12 +69,12 @@ internal static int BundlesFinishedLoadingCount
}
public delegate void BundlesFinishedLoading();
- public static event BundlesFinishedLoading onBundlesFinishedLoading;
+ public static event BundlesFinishedLoading? onBundlesFinishedLoading;
public delegate void BundleFinishedLoading(AssetBundle assetBundle);
- public static event BundleFinishedLoading onBundleFinishedLoading;
+ public static event BundleFinishedLoading? onBundleFinishedLoading;
- internal static TextMeshProUGUI loadingBundlesHeaderText;
+ internal static TextMeshProUGUI? loadingBundlesHeaderText;
internal static bool noBundlesFound = false;
@@ -123,13 +123,16 @@ internal void LoadBundles()
int counter = 0;
foreach (string file in Directory.GetFiles(pluginsFolder.FullName, specifiedFileExtension, SearchOption.AllDirectories))
{
- counter++;
FileInfo fileInfo = new FileInfo(file);
- assetBundles.Add(fileInfo.Name, null);
- UpdateLoadingBundlesHeaderText(null);
-
- //preInitSceneScript.StartCoroutine(Instance.LoadBundle(file, fileInfo.Name));
- this.StartCoroutine(Instance.LoadBundle(file, fileInfo.Name));
+ if (!assetBundles.ContainsKey(fileInfo.Name))
+ {
+ counter++;
+ assetBundles.Add(fileInfo.Name, null);
+ UpdateLoadingBundlesHeaderText(null);
+ StartCoroutine(Instance.LoadBundle(file, fileInfo.Name));
+ }
+ else
+ DebugHelper.LogError("Failed To Load Lethalbundle: " + fileInfo.Name + ". A Lethalbundle with an indentical name has already been found.", DebugType.User);
}
if (counter == 0)
{
@@ -209,7 +212,7 @@ internal static void RegisterExtendedMod(ExtendedMod extendedMod)
{
DebugHelper.Log("Found ExtendedMod: " + extendedMod.name, DebugType.User);
extendedMod.ModNameAliases.Add(extendedMod.ModName);
- ExtendedMod matchingExtendedMod = null;
+ ExtendedMod? matchingExtendedMod = null;
foreach (ExtendedMod registeredExtendedMod in obtainedExtendedModsDictionary.Values)
{
if (extendedMod.ModMergeSetting == ModMergeSetting.MatchingModName && registeredExtendedMod.ModMergeSetting == ModMergeSetting.MatchingModName)
@@ -281,7 +284,7 @@ public static void AddOnLethalBundleLoadedListener(Action invokedFu
}
}
- public static void AddOnExtendedModLoadedListener(Action invokedFunction, string extendedModAuthorName = null, string extendedModModName = null)
+ public static void AddOnExtendedModLoadedListener(Action invokedFunction, string? extendedModAuthorName = null, string? extendedModModName = null)
{
if (invokedFunction != null && !string.IsNullOrEmpty(extendedModAuthorName))
{
@@ -319,7 +322,7 @@ internal static void OnBundlesFinishedLoading()
foreach (KeyValuePair>> kvp in onLethalBundleLoadedRequestDictionary)
if (assetBundles.ContainsKey(kvp.Key))
foreach (Action action in kvp.Value)
- action(assetBundles[kvp.Key]);
+ action(assetBundles[kvp.Key]!);
foreach (KeyValuePair>> kvp in onExtendedModLoadedRequestDictionary)
foreach (ExtendedMod extendedMod in PatchedContent.ExtendedMods)
@@ -337,7 +340,7 @@ internal static void RegisterNewExtendedContent(ExtendedContent extendedContent,
return;
}
- ExtendedMod extendedMod = null;
+ ExtendedMod? extendedMod = null;
if (extendedContent is ExtendedLevel extendedLevel)
{
if (string.IsNullOrEmpty(extendedLevel.contentSourceName))
@@ -419,7 +422,7 @@ internal static void LoadContentInBundles()
{
foundExtendedLevelScene = false;
string debugString = "Could Not Find Scene File For ExtendedLevel: " + extendedLevel.SelectableLevel.name + ", Unregistering Early. \nSelectable Scene Name Is: " + extendedLevel.SelectableLevel.sceneName + ". Scenes Found In Bundles Are: " + "\n";
- foreach (KeyValuePair assetBundle in assetBundles)
+ foreach (KeyValuePair assetBundle in assetBundles)
if (assetBundle.Value != null && assetBundle.Value.isStreamedSceneAssetBundle)
foreach (string scenePath in assetBundle.Value.GetAllScenePaths())
{
@@ -604,7 +607,7 @@ internal static void CreateVanillaExtendedWeatherEffects(StartOfRound startOfRou
internal static void CreateVanillaExtendedDungeonFlow(DungeonFlow dungeonFlow)
{
- AudioClip firstTimeDungeonAudio = null;
+ AudioClip? firstTimeDungeonAudio = null;
string dungeonDisplayName = string.Empty;
if (dungeonFlow.name.Contains("Level1"))
@@ -702,13 +705,13 @@ internal static void NetworkRegisterDungeonContent(ExtendedDungeonFlow extendedD
internal static void SetVanillaLevelTags(ExtendedLevel vanillaLevel)
{
foreach (IntWithRarity intWithRarity in vanillaLevel.SelectableLevel.dungeonFlowTypes)
- if (DungeonManager.TryGetExtendedDungeonFlow(Patches.RoundManager.dungeonFlowTypes[intWithRarity.id].dungeonFlow, out ExtendedDungeonFlow extendedDungeonFlow))
+ if (DungeonManager.TryGetExtendedDungeonFlow(Patches.RoundManager.dungeonFlowTypes[intWithRarity.id].dungeonFlow, out ExtendedDungeonFlow? extendedDungeonFlow))
extendedDungeonFlow.LevelMatchingProperties.planetNames.Add(new StringWithRarity(vanillaLevel.NumberlessPlanetName, intWithRarity.rarity));
if (vanillaLevel.SelectableLevel.sceneName == "Level4March")
foreach (IndoorMapType indoorMapType in Patches.RoundManager.dungeonFlowTypes)
if (indoorMapType.dungeonFlow.name == "Level1Flow3Exits")
- if (DungeonManager.TryGetExtendedDungeonFlow(indoorMapType.dungeonFlow, out ExtendedDungeonFlow marchDungeonFlow))
+ if (DungeonManager.TryGetExtendedDungeonFlow(indoorMapType.dungeonFlow, out ExtendedDungeonFlow? marchDungeonFlow))
marchDungeonFlow.LevelMatchingProperties.planetNames.Add(new StringWithRarity(vanillaLevel.NumberlessPlanetName, 300));
foreach (CompatibleNoun infoNoun in TerminalManager.routeInfoKeyword.compatibleNouns)
@@ -753,7 +756,7 @@ internal static void CreateLoadingBundlesHeaderText(PreInitSceneScript preInitSc
}
- internal static void UpdateLoadingBundlesHeaderText(AssetBundle _)
+ internal static void UpdateLoadingBundlesHeaderText(AssetBundle? _)
{
if (loadingBundlesHeaderText != null)
{
diff --git a/LethalLevelLoader/Tools/ConfigLoader.cs b/LethalLevelLoader/Tools/ConfigLoader.cs
index 95289cf..9a42515 100644
--- a/LethalLevelLoader/Tools/ConfigLoader.cs
+++ b/LethalLevelLoader/Tools/ConfigLoader.cs
@@ -14,7 +14,7 @@ internal static class ConfigLoader
{
public static string debugLevelsString = string.Empty;
public static string debugDungeonsString = string.Empty;
- public static ConfigFile configFile;
+ public static ConfigFile configFile = null!;
internal static void BindConfigs()
{
@@ -74,14 +74,14 @@ internal static string GetConfigCategory(string categoryName, string contentName
public class GeneralSettingsConfig : ConfigTemplate
{
- private ConfigEntry previewInfoTypeToggle;
- private ConfigEntry sortInfoTypeToggle;
- private ConfigEntry filterInfoTypeToggle;
- private ConfigEntry simulateInfoTypeToggle;
- private ConfigEntry debugTypeToggle;
+ private ConfigEntry previewInfoTypeToggle = null!;
+ private ConfigEntry sortInfoTypeToggle = null!;
+ private ConfigEntry filterInfoTypeToggle = null!;
+ private ConfigEntry simulateInfoTypeToggle = null!;
+ private ConfigEntry debugTypeToggle = null!;
- private ConfigEntry moonsCatalogueSplitCount;
- private ConfigEntry requireMatchesOnAllDungeonFlows;
+ private ConfigEntry moonsCatalogueSplitCount = null!;
+ private ConfigEntry requireMatchesOnAllDungeonFlows = null!;
public GeneralSettingsConfig(ConfigFile newConfigFile, string newCategory, int newSortingPriority) : base(newConfigFile, newCategory, newSortingPriority) { }
@@ -113,20 +113,20 @@ public void BindConfigs()
public class ExtendedDungeonConfig : ConfigTemplate
{
- public ConfigEntry enableContentConfiguration;
+ public ConfigEntry enableContentConfiguration = null!;
- public ConfigEntry manualLevelNames;
- public ConfigEntry manualModNames;
+ public ConfigEntry? manualLevelNames;
+ public ConfigEntry? manualModNames;
- public ConfigEntry enableDynamicDungeonSizeRestriction;
- public ConfigEntry minimumDungeonSizeMultiplier;
- public ConfigEntry maximumDungeonSizeMultiplier;
- public ConfigEntry restrictDungeonSizeScaler;
+ public ConfigEntry? enableDynamicDungeonSizeRestriction;
+ public ConfigEntry? minimumDungeonSizeMultiplier;
+ public ConfigEntry? maximumDungeonSizeMultiplier;
+ public ConfigEntry? restrictDungeonSizeScaler;
- public ConfigEntry dynamicLevelTags;
- public ConfigEntry dynamicRoutePrices;
+ public ConfigEntry? dynamicLevelTags;
+ public ConfigEntry? dynamicRoutePrices;
- public ConfigEntry disabledWarning;
+ public ConfigEntry? disabledWarning;
public ExtendedDungeonConfig(ConfigFile newConfigFile, string newCategory, int sortingPriority) : base(newConfigFile, newCategory, sortingPriority) { }
@@ -194,33 +194,33 @@ public void BindConfigs(ExtendedDungeonFlow extendedDungeonFlow)
public class ExtendedLevelConfig : ConfigTemplate
{
//General
- public ConfigEntry enableContentConfiguration;
+ public ConfigEntry enableContentConfiguration = null!;
- public ConfigEntry routePrice;
- public ConfigEntry daySpeedMultiplier;
- public ConfigEntry doesPlanetHaveTime;
- public ConfigEntry isLevelHidden;
- public ConfigEntry isLevelRegistered;
+ public ConfigEntry? routePrice;
+ public ConfigEntry? daySpeedMultiplier;
+ public ConfigEntry? doesPlanetHaveTime;
+ public ConfigEntry? isLevelHidden;
+ public ConfigEntry? isLevelRegistered;
//Scrap
- public ConfigEntry minScrapItemSpawns;
- public ConfigEntry maxScrapItemSpawns;
+ public ConfigEntry? minScrapItemSpawns;
+ public ConfigEntry? maxScrapItemSpawns;
- public ConfigEntry minTotalScrapValue;
- public ConfigEntry maxTotalScrapValue;
+ public ConfigEntry? minTotalScrapValue;
+ public ConfigEntry? maxTotalScrapValue;
- public ConfigEntry scrapOverrides;
+ public ConfigEntry? scrapOverrides;
//Enemies
- public ConfigEntry maxInsideEnemyPowerCount;
- public ConfigEntry maxOutsideDaytimeEnemyPowerCount;
- public ConfigEntry maxOutsideNighttimeEnemyPowerCount;
+ public ConfigEntry? maxInsideEnemyPowerCount;
+ public ConfigEntry? maxOutsideDaytimeEnemyPowerCount;
+ public ConfigEntry? maxOutsideNighttimeEnemyPowerCount;
- public ConfigEntry insideEnemiesOverrides;
- public ConfigEntry outsideDaytimeEnemiesOverrides;
- public ConfigEntry outsideNighttimeEnemiesOverrides;
+ public ConfigEntry? insideEnemiesOverrides;
+ public ConfigEntry? outsideDaytimeEnemiesOverrides;
+ public ConfigEntry? outsideNighttimeEnemiesOverrides;
- public ConfigEntry disabledWarning;
+ public ConfigEntry? disabledWarning;
public ExtendedLevelConfig(ConfigFile newConfigFile, string newCategory, int sortingPriority) : base(newConfigFile, newCategory, sortingPriority) { }
diff --git a/LethalLevelLoader/Tools/ContentExtractor.cs b/LethalLevelLoader/Tools/ContentExtractor.cs
index 5640940..568e4e2 100644
--- a/LethalLevelLoader/Tools/ContentExtractor.cs
+++ b/LethalLevelLoader/Tools/ContentExtractor.cs
@@ -39,17 +39,16 @@ internal static void TryScrapeVanillaContent(StartOfRound startOfRound, RoundMan
{
if (Plugin.IsSetupComplete == false)
{
- if (startOfRound != null)
- {
- foreach (IndoorMapType indoorFlowType in roundManager.dungeonFlowTypes)
- TryAddReference(OriginalContent.DungeonFlows, indoorFlowType.dungeonFlow);
+
+ foreach (IndoorMapType indoorFlowType in roundManager.dungeonFlowTypes)
+ TryAddReference(OriginalContent.DungeonFlows, indoorFlowType.dungeonFlow);
- foreach (SelectableLevel selectableLevel in startOfRound.levels)
- ExtractSelectableLevelReferences(selectableLevel);
+ foreach (SelectableLevel selectableLevel in startOfRound.levels)
+ ExtractSelectableLevelReferences(selectableLevel);
- foreach (IndoorMapType indoorFlowType in roundManager.dungeonFlowTypes)
- ExtractDungeonFlowReferences(indoorFlowType.dungeonFlow);
- }
+ foreach (IndoorMapType indoorFlowType in roundManager.dungeonFlowTypes)
+ ExtractDungeonFlowReferences(indoorFlowType.dungeonFlow);
+
if (TerminalManager.Terminal.currentNode != null)
TryAddReference(OriginalContent.TerminalNodes, TerminalManager.Terminal.currentNode);
diff --git a/LethalLevelLoader/Tools/ContentRestorer.cs b/LethalLevelLoader/Tools/ContentRestorer.cs
index c7a14c3..f1cf2ab 100644
--- a/LethalLevelLoader/Tools/ContentRestorer.cs
+++ b/LethalLevelLoader/Tools/ContentRestorer.cs
@@ -5,6 +5,7 @@
using System.Text;
using UnityEngine;
using UnityEngine.Audio;
+using UnityEngine.Rendering;
using Object = UnityEngine.Object;
namespace LethalLevelLoader.Tools
@@ -60,7 +61,7 @@ internal static void RestoreVanillaLevelAssetReferences(ExtendedLevel extendedLe
foreach (EnemyType vanillaEnemyType in OriginalContent.Enemies)
foreach (SpawnableEnemyWithRarity enemyRarityPair in extendedLevel.SelectableLevel.Enemies.Concat(extendedLevel.SelectableLevel.DaytimeEnemies).Concat(extendedLevel.SelectableLevel.OutsideEnemies))
- if (enemyRarityPair.enemyType != null && enemyRarityPair.enemyType.enemyName == vanillaEnemyType.enemyName)
+ if (enemyRarityPair.enemyType != null && !string.IsNullOrEmpty(enemyRarityPair.enemyType.name) && enemyRarityPair.enemyType.name == vanillaEnemyType.name)
enemyRarityPair.enemyType = RestoreAsset(enemyRarityPair.enemyType, vanillaEnemyType);
foreach (SpawnableMapObject spawnableMapObject in extendedLevel.SelectableLevel.spawnableMapObjects)
@@ -125,8 +126,8 @@ internal static void TryRestoreAudioSource(AudioSource audioSource)
AudioMixerGroup targetMixerGroup = audioSource.outputAudioMixerGroup;
AudioMixer targetMixer = audioSource.outputAudioMixerGroup.audioMixer;
- AudioMixerGroup restoredMixerGroup = null;
- AudioMixer restoredMixer = null;
+ AudioMixerGroup? restoredMixerGroup = null;
+ AudioMixer? restoredMixer = null;
foreach (AudioMixer vanillaMixer in OriginalContent.AudioMixers)
if (targetMixer.name == vanillaMixer.name)
@@ -157,6 +158,24 @@ internal static void DestroyRestoredAssets(bool debugAction = false)
objectsToDestroy.Clear();
}
+ internal static void TryRestoreWaterShader(Material customMaterial)
+ {
+ if (customMaterial == null || customMaterial.shader == null || string.IsNullOrEmpty(customMaterial.shader.name))
+ return;
+
+ if (customMaterial.shader == LevelLoader.vanillaWaterShader)
+ return;
+
+ if (customMaterial.shader.name == LevelLoader.vanillaWaterShader.name)
+ {
+ customMaterial.shader = LevelLoader.vanillaWaterShader;
+ customMaterial.DisableKeyword("_BLENDMODE_ALPHA");
+ customMaterial.EnableKeyword("_SURFACE_TYPE_TRANSPARENT");
+ customMaterial.EnableKeyword("_ENABLE_FOG_ON_TRANSPARENT");
+ customMaterial.EnableKeyword("_DISABLE_SSR_TRANSPARENT");
+ }
+ }
+
internal static T RestoreAsset(UnityEngine.Object currentAsset, T newAsset, bool debugAction = false, bool destroyOnReplace = true)
{
diff --git a/LethalLevelLoader/Tools/DebugHelper.cs b/LethalLevelLoader/Tools/DebugHelper.cs
index da6bf3d..8c21fa5 100644
--- a/LethalLevelLoader/Tools/DebugHelper.cs
+++ b/LethalLevelLoader/Tools/DebugHelper.cs
@@ -653,6 +653,32 @@ public static void DebugAllContentTags()
}
}
+ public static void DebugCachedLevelColliderData()
+ {
+ string debugString = "Cached Level Collider-Material Data" + "\n\n";
+
+ foreach (KeyValuePair> kvp in LevelLoader.cachedLevelColliderMaterialDictionary)
+ {
+ debugString += "\n" + "Collider: " + kvp.Key.gameObject.name + " - Materials: ";
+ foreach (Material material in kvp.Value)
+ {
+ debugString += material.name;
+ if (material != kvp.Value.Last())
+ debugString += ", ";
+ }
+ }
+
+ DebugHelper.Log(debugString, DebugType.User);
+
+ debugString = "Cached Level Material-Collider Data" + "\n\n";
+
+ foreach (KeyValuePair> kvp in LevelLoader.cachedLevelMaterialColliderDictionary)
+ debugString += "\n" + kvp.Key+ " (" + kvp.Value.Count + ")";
+
+ DebugHelper.Log(debugString, DebugType.User);
+
+ }
+
public static void LogDebugInstructionsFrom(CodeMatcher matcher)
{
var methodName = new StackTrace().GetFrame(1).GetMethod().Name;
diff --git a/LethalLevelLoader/Tools/HookHelper.cs b/LethalLevelLoader/Tools/HookHelper.cs
index 6498333..dca3191 100644
--- a/LethalLevelLoader/Tools/HookHelper.cs
+++ b/LethalLevelLoader/Tools/HookHelper.cs
@@ -10,13 +10,13 @@
internal static class HookHelper
{
public static MethodInfo methodof(Delegate method) => method.Method;
- public static MethodInfo EzGetMethod(Type type, string name, Type[] parameters = null)
+ public static MethodInfo EzGetMethod(Type type, string name, Type[]? parameters = null)
{
BindingFlags query = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static;
if (parameters == null) return type.GetMethod(name, query);
return type.GetMethod(name, query, null, parameters, null);
}
- public static MethodInfo EzGetMethod(string name, Type[] parameters = null) => EzGetMethod(typeof(T), name, parameters);
+ public static MethodInfo EzGetMethod(string name, Type[]? parameters = null) => EzGetMethod(typeof(T), name, parameters);
public class DisposableHookCollection
{
@@ -36,11 +36,11 @@ public void Clear()
}
ilHooks.Clear();
}
- public void ILHook(string methodName, ILContext.Manipulator to, Type[] parameters = null)
+ public void ILHook(string methodName, ILContext.Manipulator to, Type[]? parameters = null)
{
ilHooks.Add(new(EzGetMethod(methodName, parameters), to));
}
- public void Hook