From 056cac8df19479d01deccf0c6c304a49c0fb7dae Mon Sep 17 00:00:00 2001 From: LadyAliceMargatroid Date: Fri, 2 Aug 2024 08:56:09 -0700 Subject: [PATCH] Moved dungen code to DunGenPlus Added critical damage as a mechanic Maid knife feed deals critical damage, then kills on second time Added concept of treasure room with kitchen Frames now only start at the player when not being looked New attempt at snowglobe animations, it broke though Added concept of indoor weathers LethalConfig compability now changes the color of configs that my presets touch Added jukebox Changed modGUID Removed AC compability Falling into void deals critical damage and teleports, then kills on second time Maid spawns revenant ghost on death --- ScarletMansion/ScarletMansion/Assets.cs | 13 +- .../ScarletMansion/DunGenAnalyis.cs | 235 ------------- .../DoorwayConnectionSisterChain.cs | 60 ---- .../DoorwayConnectionSisterRuleInfo.cs | 47 --- .../Components/MainRoomDoorwayGroups.cs | 25 -- .../RemoveConnectorIfConnectedDoorwayBasic.cs | 20 -- .../RemoveGameObjectsBasedOnCBSelected.cs | 37 --- ...emoveGameObjectsBasedOnConnectedDoorway.cs | 63 ---- ...SwitchConnectorBlockerBasedOnCBSelected.cs | 42 --- .../DunGenPatch/DoorwayConnectionPatch.cs | 62 ---- .../DoorwayConnectionSisterRule.cs | 91 ----- .../DunGenPatch/Doorways/DCleanBase.cs | 20 -- .../DCleanConnectorBlockerBasedOnSelected.cs | 30 -- .../Doorways/DCleanDoorwayCompare.cs | 45 --- ...DCleanRemoveDoorwayBasedOnConnectedDoor.cs | 26 -- .../DCleanRemoveDoorwayBasedOnSelected.cs | 28 -- ...anRemoveGameObjectsBasedOnConnectedDoor.cs | 26 -- .../DunGenPatch/Doorways/DoorwayCleanup.cs | 75 ----- .../DunGenPatch/GeneratePath.cs | 314 ------------------ .../DunGenPatch/GeneratePathPatch.cs | 88 +---- .../DunGenPatch/OptimizePatch.cs | 59 ---- .../ScarletMansion/DunGenPatch/Patch.cs | 115 +++---- .../DunGenPatch/PostProcessPatch.cs | 24 -- .../GamePatch/Components/PathOpenUpParent.cs | 60 ++++ .../GamePatch/Components/PathOpenup.cs | 40 +++ .../GamePatch/Components/ScarletBedroom.cs | 7 +- .../GamePatch/Components/ScarletClock.cs | 8 +- .../GamePatch/Components/ScarletDoor.cs | 46 ++- .../GamePatch/Components/ScarletDoorLock.cs | 8 +- .../GamePatch/Components/ScarletFrame.cs | 47 +-- .../Components/ScarletPlayerControllerB.cs | 35 +- .../GamePatch/Components/ScarletRadio.cs | 122 +++++++ .../Components/ScarletYukariTrigger.cs | 22 +- .../TreasureRoom/TreasureRoomTimedOpen.cs | 74 +++++ .../GamePatch/Enemies/KnightGhostVariant.cs | 165 +++++++++ .../GamePatch/Enemies/MaidVariant.cs | 5 + .../ScarletMansion/GamePatch/InitPatch.cs | 113 +------ .../Items/PlayerAnimatorStateHelper.cs | 124 ------- .../GamePatch/Items/ScarletKnife.cs | 30 +- .../GamePatch/Items/ScarletSnowGlobe.cs | 54 ++- .../GamePatch/LoadAssetsIntoLevelPatch.cs | 7 +- .../GamePatch/Managers/AngerManager.cs | 13 +- .../GamePatch/Managers/DoorwayManager.cs | 85 ----- .../GamePatch/Managers/KnightSpawnManager.cs | 2 - .../Managers/ScarletNetworkManager.cs | 62 ++++ .../GamePatch/PlayerControllerBPatch.cs | 14 +- .../GamePatch/Props/LocalPropSingle.cs | 2 +- .../GamePatch/Props/SpawnSyncedObjectCycle.cs | 49 --- .../GamePatch/RoundManagerPatch.cs | 6 - .../GamePatch/Weathers/SDMWeatherManager.cs | 35 ++ .../NetworkObjectListScriptableObject.cs | 8 +- .../ModPatch/AdvancedCompanyPatch.cs | 37 --- .../ModPatch/LethalConfigPatch.cs | 55 ++- .../ScarletMansion/ModPatch/ModCompability.cs | 4 +- ScarletMansion/ScarletMansion/Plugin.cs | 15 +- ScarletMansion/ScarletMansion/PluginConfig.cs | 10 - ScarletMansion/ScarletMansion/PresetConfig.cs | 36 ++ .../ScarletMansion/ScarletMansion.csproj | 40 +-- .../ScarletMansion/TranspilerUtilities.cs | 5 + ScarletMansion/ScarletMansion/Utility.cs | 38 +++ .../ScarletMansionMimicsPatch/Patch.cs | 2 +- .../ScarletMansionMimicsPatch/Plugin.cs | 4 +- .../ScarletMansionMimicsPatch.csproj | 3 + 63 files changed, 976 insertions(+), 2061 deletions(-) delete mode 100644 ScarletMansion/ScarletMansion/DunGenAnalyis.cs delete mode 100644 ScarletMansion/ScarletMansion/DunGenPatch/Components/DoorwayConnectionSisterChain.cs delete mode 100644 ScarletMansion/ScarletMansion/DunGenPatch/Components/DoorwayConnectionSisterRuleInfo.cs delete mode 100644 ScarletMansion/ScarletMansion/DunGenPatch/Components/MainRoomDoorwayGroups.cs delete mode 100644 ScarletMansion/ScarletMansion/DunGenPatch/Components/RemoveConnectorIfConnectedDoorwayBasic.cs delete mode 100644 ScarletMansion/ScarletMansion/DunGenPatch/Components/RemoveGameObjectsBasedOnCBSelected.cs delete mode 100644 ScarletMansion/ScarletMansion/DunGenPatch/Components/RemoveGameObjectsBasedOnConnectedDoorway.cs delete mode 100644 ScarletMansion/ScarletMansion/DunGenPatch/Components/SwitchConnectorBlockerBasedOnCBSelected.cs delete mode 100644 ScarletMansion/ScarletMansion/DunGenPatch/DoorwayConnectionPatch.cs delete mode 100644 ScarletMansion/ScarletMansion/DunGenPatch/DoorwayConnectionSisterRule.cs delete mode 100644 ScarletMansion/ScarletMansion/DunGenPatch/Doorways/DCleanBase.cs delete mode 100644 ScarletMansion/ScarletMansion/DunGenPatch/Doorways/DCleanConnectorBlockerBasedOnSelected.cs delete mode 100644 ScarletMansion/ScarletMansion/DunGenPatch/Doorways/DCleanDoorwayCompare.cs delete mode 100644 ScarletMansion/ScarletMansion/DunGenPatch/Doorways/DCleanRemoveDoorwayBasedOnConnectedDoor.cs delete mode 100644 ScarletMansion/ScarletMansion/DunGenPatch/Doorways/DCleanRemoveDoorwayBasedOnSelected.cs delete mode 100644 ScarletMansion/ScarletMansion/DunGenPatch/Doorways/DCleanRemoveGameObjectsBasedOnConnectedDoor.cs delete mode 100644 ScarletMansion/ScarletMansion/DunGenPatch/Doorways/DoorwayCleanup.cs delete mode 100644 ScarletMansion/ScarletMansion/DunGenPatch/GeneratePath.cs delete mode 100644 ScarletMansion/ScarletMansion/DunGenPatch/OptimizePatch.cs delete mode 100644 ScarletMansion/ScarletMansion/DunGenPatch/PostProcessPatch.cs create mode 100644 ScarletMansion/ScarletMansion/GamePatch/Components/PathOpenUpParent.cs create mode 100644 ScarletMansion/ScarletMansion/GamePatch/Components/PathOpenup.cs create mode 100644 ScarletMansion/ScarletMansion/GamePatch/Components/ScarletRadio.cs create mode 100644 ScarletMansion/ScarletMansion/GamePatch/Components/TreasureRoom/TreasureRoomTimedOpen.cs create mode 100644 ScarletMansion/ScarletMansion/GamePatch/Enemies/KnightGhostVariant.cs delete mode 100644 ScarletMansion/ScarletMansion/GamePatch/Items/PlayerAnimatorStateHelper.cs delete mode 100644 ScarletMansion/ScarletMansion/GamePatch/Managers/DoorwayManager.cs delete mode 100644 ScarletMansion/ScarletMansion/GamePatch/Props/SpawnSyncedObjectCycle.cs create mode 100644 ScarletMansion/ScarletMansion/GamePatch/Weathers/SDMWeatherManager.cs delete mode 100644 ScarletMansion/ScarletMansion/ModPatch/AdvancedCompanyPatch.cs diff --git a/ScarletMansion/ScarletMansion/Assets.cs b/ScarletMansion/ScarletMansion/Assets.cs index c3282a6..d6a3eb6 100644 --- a/ScarletMansion/ScarletMansion/Assets.cs +++ b/ScarletMansion/ScarletMansion/Assets.cs @@ -13,6 +13,7 @@ using LethalLib.Modules; using LethalLevelLoader; using ScarletMansion.GamePatch.Items; using static ScarletMansion.Assets; +using DunGenPlus; namespace ScarletMansion { public static class Assets { @@ -26,6 +27,7 @@ namespace ScarletMansion { // main assets public static AssetBundle MainAssetBundle = null; public static DungeonFlow dungeon; + public static DunGenExtender dunGenExtender; public static NetworkObjectListScriptableObject networkObjectList; public static AudioClip entranceAudioClip; @@ -33,11 +35,6 @@ namespace ScarletMansion { public static ExtendedMod extendedMod; public static ExtendedDungeonFlow dungeonExtended; - //public static ExtendedDungeonMapLoad.CustomMoonEntry rendEntry; - //public static ExtendedDungeonMapLoad.CustomMoonEntry dineEntry; - //public static ExtendedDungeonMapLoad.CustomMoonEntry titanEntry; - //public static List customMoonEntryList; - // enemy values public class Enemy { @@ -187,6 +184,7 @@ namespace ScarletMansion { dungeon = Load("SDMLevel"); networkObjectList = Load("SDMList"); + dunGenExtender = Load("DunGenExtender"); entranceAudioClip = Load("entrance_ogg"); knight = new Enemy( @@ -232,6 +230,11 @@ namespace ScarletMansion { globalItems.Add(flashlight); globalItems.Add(flashlightBB); + foreach(var e in networkObjectList.enemies) { + Enemies.RegisterEnemy(e, 0, Levels.LevelTypes.None, null, null); + NetworkPrefabs.RegisterNetworkPrefab(e.enemyPrefab); + } + onAssetsLoadEvent.Call(); } diff --git a/ScarletMansion/ScarletMansion/DunGenAnalyis.cs b/ScarletMansion/ScarletMansion/DunGenAnalyis.cs deleted file mode 100644 index 33155a1..0000000 --- a/ScarletMansion/ScarletMansion/DunGenAnalyis.cs +++ /dev/null @@ -1,235 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using DunGen; -using DunGen.Graph; -using UnityEngine; - -namespace ScarletMansion { - - public static class AnalysisUtilities { - - public class Average { - public List values; - public float total; - - public Average() { - values = new List(); - } - - public void Add(float value) { - values.Add(value); - total += value; - } - - public float GetAverage(){ - if (values.Count == 0) return 0f; - return total / values.Count; - } - - public float GetStdDev(){ - if (values.Count == 0) return 0f; - var avg = GetAverage(); - var x = values.Sum(i => { - var y = i - avg; - return y * y; - }); - return Mathf.Sqrt(x / values.Count); - } - - public override string ToString() { - //var avg = GetAverage(); - //var dev = GetStdDev(); - - var strList = new List(); - values.Sort(); - - var sectionCount = Mathf.Clamp(values.Count, 1, 10); - var sectionDistance = values.Count / sectionCount; - for(var i = 0; i * sectionDistance < values.Count; ++i){ - var avg = GetAverage(values.Skip(i * sectionDistance).Take(sectionDistance)); - strList.Add($"[{i}]{avg}"); - } - - /* - var leftIndex = values.Count / 4; - var rightIndex = values.Count - leftIndex; - var left = values[leftIndex]; - var right = values[rightIndex]; - return $"Avg[{avg:0.00}]({left:0.00} - {right:0.00}) Dev[{dev:0.00}]"; - */ - - var strListFormatted = string.Join(", ", strList); - return $"({strListFormatted})"; - } - - public float GetAverage(IEnumerable items){ - return items.Sum() / items.Count(); - } - } - } - - public static class DunGenAnalyis { - - public class Average { - public float totalVolume; - public float totalWeight; - public float average => totalWeight > 0f ? (totalVolume / totalWeight) : 0f; - - public Dictionary baseDictionary = new Dictionary(){ - { "SM_MayorEntrance_FINAL_32x24 Tile", false } - }; - - public void AddToAverage(float volume, float weight, string name){ - var isBaseUsed = false; - var isBaseTile = baseDictionary.TryGetValue(name, out isBaseUsed); - - if (!isBaseTile) { - totalVolume += volume; - totalWeight += weight; - } - } - - public void AddToBase(float volume, string name){ - var isBaseUsed = false; - var isBaseTile = baseDictionary.TryGetValue(name, out isBaseUsed); - totalWeight = 1f; - - if (isBaseTile && !isBaseUsed) { - totalVolume += volume; - baseDictionary[name] = true; - } - } - - public override string ToString() { - return $"{totalVolume / totalWeight}"; - } - } - - public static void Analysis(DungeonFlow flow, StartOfRound startofround, RoundManager roundmanager){ - - foreach(var l in startofround.levels){ - - var mult = l.factorySizeMultiplier * roundmanager.mapSizeMultiplier; - Plugin.logger.LogInfo($"{l.PlanetName}: {mult}"); - - var length = flow.Length; - var minLength = Mathf.RoundToInt(length.Min * mult); - var maxLength = Mathf.RoundToInt(length.Max * mult); - - var minTotal = 0f; - for(var i = 0; i <= minLength; ++i){ - minTotal += GetAverage(flow, minLength, i, 0); - minTotal += GetAverage(flow, minLength, i, 1); - minTotal += GetAverage(flow, minLength, i, 2); - //Plugin.logger.LogInfo($"new: {minTotal}"); - } - - var maxTotal = 0f; - for(var i = 0; i <= maxLength; ++i){ - maxTotal += GetAverage(flow, maxLength, i, 0); - maxTotal += GetAverage(flow, maxLength, i, 1); - maxTotal += GetAverage(flow, maxLength, i, 2); - //Plugin.logger.LogInfo($"new: {maxTotal}"); - } - - var maxSizeBounds = DunGenPatch.Patch.GetDungeonBounds(mult); - var maxSizeTotal = GetVolume(maxSizeBounds) * (3f / 5f); - - var minPer = (minTotal / maxSizeTotal).ToString("0.00"); - var maxPer = (maxTotal / maxSizeTotal).ToString("0.00"); - - Plugin.logger.LogInfo($"Min size required: {minTotal} - {maxTotal}"); - Plugin.logger.LogInfo($"All space: {maxSizeTotal}"); - Plugin.logger.LogInfo($"Taken space: {minPer} - {maxPer}"); - Plugin.logger.LogInfo(""); - } - } - - public static float GetAverage(DungeonFlow flow, int length, int index, int lineIndex){ - var average = new Average(); - var depth = (float)index / length; - - if (depth <= 1f){ - // start - if (depth == 0f){ - // count the start once - if (lineIndex == 0){ - foreach(var t in flow.Nodes[0].TileSets){ - ModifyAverage(t, average, 0f); - } - } - // skip - else { - - } - - } - // end - else if (depth == 1f) { - foreach(var t in flow.Nodes[1].TileSets){ - ModifyAverage(t, average, depth); - } - } - // entrance tile - else if (index == 1){ - // count the mayor once - if (lineIndex == 0) { - foreach(var a in flow.Lines[0].DungeonArchetypes){ - foreach(var t in a.TileSets){ - AddBase(t, average); - } - } - - - } - // skip - else { - - } - } - // in between - else { - var line = flow.GetLineAtDepth(depth); - foreach(var a in line.DungeonArchetypes){ - foreach(var t in a.TileSets){ - ModifyAverage(t, average, depth); - } - } - } - } - - //Plugin.logger.LogInfo($"b{lineIndex}i{index}l{length}: {average.average}"); - - return average.average; - } - - public static void AddBase(TileSet tileset, Average baseVol) { - foreach(var t in tileset.TileWeights.Weights){ - var gobj = t.Value; - var tile = gobj.GetComponent(); - var volume = GetVolume(tile.TileBoundsOverride); - baseVol.AddToBase(volume, t.Value.name); - } - } - - public static void ModifyAverage(TileSet tileset, Average averageVol, float depth){ - foreach(var t in tileset.TileWeights.Weights){ - var gobj = t.Value; - var tile = gobj.GetComponent(); - var volume = GetVolume(tile.TileBoundsOverride); - var weight = t.MainPathWeight * t.DepthWeightScale.Evaluate(depth); - averageVol.AddToAverage(volume * weight, weight, t.Value.name); - } - } - - public static float GetVolume(Bounds bounds){ - var size = bounds.size; - return size.x * size.y * size.z; - } - - } -} diff --git a/ScarletMansion/ScarletMansion/DunGenPatch/Components/DoorwayConnectionSisterChain.cs b/ScarletMansion/ScarletMansion/DunGenPatch/Components/DoorwayConnectionSisterChain.cs deleted file mode 100644 index 2380e45..0000000 --- a/ScarletMansion/ScarletMansion/DunGenPatch/Components/DoorwayConnectionSisterChain.cs +++ /dev/null @@ -1,60 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using UnityEngine; -using DunGen; - -namespace ScarletMansion { - public class DoorwayConnectionSisterChain : MonoBehaviour { - - public Doorway[] chain; - public bool loop = true; - - [ContextMenu("Create Chain")] - public void CreateChain(){ - if (chain == null) return; - if (chain.Length <= 1) return; - - for(var i = 0; i < chain.Length; ++i){ - var current = chain[i]; - var list = new List(); - - // add prev - if (i > 0 || loop) { - var prev = chain[((i - 1) + chain.Length) % chain.Length]; - list.Add(prev); - } - - if (i < chain.Length - 1 || loop){ - var next = chain[((i + 1) + chain.Length) % chain.Length]; - list.Add(next); - } - - var script = current.GetComponent(); - if (script == null) { - script = current.gameObject.AddComponent(); - } - script.sisters = list.ToArray(); - } - - } - - public void OnDrawGizmosSelected(){ - if (chain == null) return; - if (chain.Length <= 1) return; - - for(var i = 0; i < chain.Length; ++i){ - if (!loop && i == chain.Length - 1) continue; - - var current = chain[i]; - var next = chain[(i + 1) % chain.Length]; - var color = new Color((float)i / chain.Length, 1f, 1f); - Gizmos.color = color; - Gizmos.DrawLine(current.transform.position, next.transform.position); - } - } - - } -} diff --git a/ScarletMansion/ScarletMansion/DunGenPatch/Components/DoorwayConnectionSisterRuleInfo.cs b/ScarletMansion/ScarletMansion/DunGenPatch/Components/DoorwayConnectionSisterRuleInfo.cs deleted file mode 100644 index 669f9b0..0000000 --- a/ScarletMansion/ScarletMansion/DunGenPatch/Components/DoorwayConnectionSisterRuleInfo.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using UnityEngine; -using DunGen; - -namespace ScarletMansion { - public class DoorwayConnectionSisterRuleInfo : MonoBehaviour { - - private Doorway _self; - public Doorway self { - get { - if (_self == null) { - _self = GetComponent(); - } - return _self; - } - } - - public Doorway[] sisters; - - public void OnDrawGizmosSelected(){ - var center = transform.position; - if (sisters == null) return; - - foreach(var sis in sisters){ - var target = sis.transform.position; - var comp = sis.GetComponent(); - - if (self == null) { - Gizmos.color = Color.magenta; - } else if (comp == null || comp.sisters == null){ - Gizmos.color = Color.yellow; - } else if (!comp.sisters.Contains(self)) { - Gizmos.color = Color.red; - } else { - Gizmos.color = Color.green; - } - - Gizmos.DrawLine(center, target); - } - } - } - -} diff --git a/ScarletMansion/ScarletMansion/DunGenPatch/Components/MainRoomDoorwayGroups.cs b/ScarletMansion/ScarletMansion/DunGenPatch/Components/MainRoomDoorwayGroups.cs deleted file mode 100644 index ef12515..0000000 --- a/ScarletMansion/ScarletMansion/DunGenPatch/Components/MainRoomDoorwayGroups.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using UnityEngine; -using DunGen; - -namespace ScarletMansion { - public class MainRoomDoorwayGroups : MonoBehaviour { - - public List groupA; - public List groupB; - - public List groupBasement; - - public List GrabDoorwayGroup(Doorway target){ - if (groupA.Contains(target)) return groupA; - else if (groupB.Contains(target)) return groupB; - else if (groupBasement.Contains(target)) return groupBasement; - return null; - } - - } -} diff --git a/ScarletMansion/ScarletMansion/DunGenPatch/Components/RemoveConnectorIfConnectedDoorwayBasic.cs b/ScarletMansion/ScarletMansion/DunGenPatch/Components/RemoveConnectorIfConnectedDoorwayBasic.cs deleted file mode 100644 index 2d144ea..0000000 --- a/ScarletMansion/ScarletMansion/DunGenPatch/Components/RemoveConnectorIfConnectedDoorwayBasic.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using DunGen; -using UnityEngine; - -namespace ScarletMansion { - public class RemoveConnectorIfConnectedDoorwayBasic : MonoBehaviour, IDungeonCompleteReceiver { - public void OnDungeonComplete(Dungeon dungeon){ - var d = GetComponent(); - if (d == null || d.ConnectedDoorway == null) return; - if (d.ConnectedDoorway.DoorPrefabPriority == 0) { - d.ConnectorSceneObjects[0].SetActive(false); - } - } - - } -} diff --git a/ScarletMansion/ScarletMansion/DunGenPatch/Components/RemoveGameObjectsBasedOnCBSelected.cs b/ScarletMansion/ScarletMansion/DunGenPatch/Components/RemoveGameObjectsBasedOnCBSelected.cs deleted file mode 100644 index 6c07fc9..0000000 --- a/ScarletMansion/ScarletMansion/DunGenPatch/Components/RemoveGameObjectsBasedOnCBSelected.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using DunGen; -using UnityEngine; - -namespace ScarletMansion.DunGenPatch.Components { - public class RemoveGameObjectsBasedOnCBSelected : MonoBehaviour, IDungeonCompleteReceiver { - - public Doorway doorway; - public List targets; - public GameObject cb; - - void Reset(){ - doorway = GetComponent(); - } - - public void OnDungeonComplete(Dungeon dungeon) { - var result = false; - foreach(Transform t in transform){ - if (t.name.Contains(cb.name)) { - result = true; - break; - } - } - - if (result) { - foreach(var t in targets) t.SetActive(false); - } - - } - - - } -} diff --git a/ScarletMansion/ScarletMansion/DunGenPatch/Components/RemoveGameObjectsBasedOnConnectedDoorway.cs b/ScarletMansion/ScarletMansion/DunGenPatch/Components/RemoveGameObjectsBasedOnConnectedDoorway.cs deleted file mode 100644 index aa4b984..0000000 --- a/ScarletMansion/ScarletMansion/DunGenPatch/Components/RemoveGameObjectsBasedOnConnectedDoorway.cs +++ /dev/null @@ -1,63 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using DunGen; -using UnityEngine; - -namespace ScarletMansion.DunGenPatch.Components { - public class RemoveGameObjectsBasedOnConnectedDoorway : MonoBehaviour, IDungeonCompleteReceiver { - - public enum Operation { Equal, NotEqual, LessThan, GreaterThan } - - public Doorway doorway; - public List targets; - public int doorwayPriority; - public Operation operation = Operation.Equal; - - void Reset(){ - doorway = GetComponent(); - } - - public void OnDungeonComplete(Dungeon dungeon) { - if (doorway.connectedDoorway == null) return; - var result = GetOperation().Invoke(doorway.connectedDoorway); - if (result) { - - foreach(var t in targets) t.SetActive(false); - } - } - - public Func GetOperation(){ - switch(operation){ - case Operation.Equal: - return EqualOperation; - case Operation.NotEqual: - return NotEqualOperation; - case Operation.LessThan: - return LessThanOperation; - case Operation.GreaterThan: - return GreaterThanOperation; - } - return null; - } - - public bool EqualOperation(Doorway other){ - return other.DoorPrefabPriority == doorwayPriority; - } - - public bool NotEqualOperation(Doorway other){ - return other.DoorPrefabPriority != doorwayPriority; - } - - public bool LessThanOperation(Doorway other){ - return other.DoorPrefabPriority < doorwayPriority; - } - - public bool GreaterThanOperation(Doorway other){ - return other.DoorPrefabPriority > doorwayPriority; - } - - } -} diff --git a/ScarletMansion/ScarletMansion/DunGenPatch/Components/SwitchConnectorBlockerBasedOnCBSelected.cs b/ScarletMansion/ScarletMansion/DunGenPatch/Components/SwitchConnectorBlockerBasedOnCBSelected.cs deleted file mode 100644 index dec019d..0000000 --- a/ScarletMansion/ScarletMansion/DunGenPatch/Components/SwitchConnectorBlockerBasedOnCBSelected.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using DunGen; -using UnityEngine; - -namespace ScarletMansion.DunGenPatch.Components { - public class SwitchConnectorBlockerBasedOnCBSelected : MonoBehaviour, IDungeonCompleteReceiver{ - - public enum Action { SwitchToConnector, SwitchToBlocker }; - - public Doorway doorway; - public GameObject cb; - public Action switchAction; - - void Reset(){ - doorway = GetComponent(); - } - - public void OnDungeonComplete(Dungeon dungeon) { - var result = false; - foreach(Transform t in transform){ - if (t.name.Contains(cb.name)) { - result = true; - break; - } - } - - if (result) { - var connectorStatus = switchAction == Action.SwitchToConnector; - var blockerStatus = switchAction == Action.SwitchToBlocker; - - foreach(var c in doorway.ConnectorSceneObjects) c.SetActive(connectorStatus); - foreach(var b in doorway.BlockerSceneObjects) b.SetActive(blockerStatus); - } - - } - - } -} diff --git a/ScarletMansion/ScarletMansion/DunGenPatch/DoorwayConnectionPatch.cs b/ScarletMansion/ScarletMansion/DunGenPatch/DoorwayConnectionPatch.cs deleted file mode 100644 index 7136593..0000000 --- a/ScarletMansion/ScarletMansion/DunGenPatch/DoorwayConnectionPatch.cs +++ /dev/null @@ -1,62 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using HarmonyLib; -using GameNetcodeStuff; -using System.Reflection; -using System.Reflection.Emit; -using BepInEx.Logging; -using UnityEngine; -using DunGen; - -namespace ScarletMansion.DunGenPatch { - public class DoorwayConnectionPatch { - - [HarmonyTranspiler] - [HarmonyPatch(typeof(DungeonProxy), "ConnectOverlappingDoorways")] - public static IEnumerable ConnectOverlappingDoorwaysPatch(IEnumerable instructions){ - var callFunction = typeof(DunGen.Graph.DungeonFlow).GetMethod("CanDoorwaysConnect", BindingFlags.Instance | BindingFlags.Public); - - var sequence = new InstructionSequence("doorway connect", false); - sequence.AddBasic(OpCodes.Callvirt, callFunction); - sequence.AddBasic(OpCodes.Brfalse); - - foreach(var instruction in instructions){ - - if (sequence.VerifyStage(instruction)){ - - var method = typeof(DoorwayConnectionSisterRule).GetMethod("CanDoorwaysConnect", BindingFlags.Static | BindingFlags.Public); - var getTileProxy = typeof(DoorwayProxy).GetMethod("get_TileProxy", BindingFlags.Instance | BindingFlags.Public); - - yield return new CodeInstruction(OpCodes.Ldloc_2); - yield return new CodeInstruction(OpCodes.Callvirt, getTileProxy); - yield return new CodeInstruction(OpCodes.Ldloc_S, 4); - yield return new CodeInstruction(OpCodes.Callvirt, getTileProxy); - - yield return new CodeInstruction(OpCodes.Ldloc_2); - yield return new CodeInstruction(OpCodes.Ldloc_S, 4); - - yield return new CodeInstruction(OpCodes.Call, method); - - yield return instruction; - - continue; - } - - yield return instruction; - } - - sequence.ReportComplete(); - } - - [HarmonyPatch(typeof(DungeonProxy), "ConnectOverlappingDoorways")] - [HarmonyPrefix] - public static void ConnectOverlappingDoorwaysPrePatch(ref DungeonProxy __instance){ - var enumerable = __instance.AllTiles.SelectMany(t => t.Doorways); - DoorwayConnectionSisterRule.UpdateCache(enumerable); - } - - } -} diff --git a/ScarletMansion/ScarletMansion/DunGenPatch/DoorwayConnectionSisterRule.cs b/ScarletMansion/ScarletMansion/DunGenPatch/DoorwayConnectionSisterRule.cs deleted file mode 100644 index 73b0479..0000000 --- a/ScarletMansion/ScarletMansion/DunGenPatch/DoorwayConnectionSisterRule.cs +++ /dev/null @@ -1,91 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using DunGen; -using UnityEngine; -using DunGen.Tags; - -namespace ScarletMansion.DunGenPatch { - public static class DoorwayConnectionSisterRule { - - public static bool active => Patch.active; - - public class Data { - public DoorwayConnectionSisterRuleInfo info; - public List proxies; - } - - public static Dictionary doorwayDictionary; - public static Dictionary doorwayProxyDictionary; - - public static void UpdateCache(IEnumerable list){ - if (!active) return; - - Plugin.logger.LogInfo("Updating cache from DungeonProxy"); - doorwayDictionary = new Dictionary(); - doorwayProxyDictionary = new Dictionary(); - - foreach(var a in list){ - - var doorway = a.DoorwayComponent; - if (doorwayDictionary.TryGetValue(doorway, out var data)){ - - data.proxies.Add(a); - doorwayProxyDictionary.Add(a, data); - - } else { - - var proxies = new List(); - proxies.Add(a); - var item = new Data { - info = doorway.GetComponent(), - proxies = proxies - }; - - doorwayProxyDictionary.Add(a, item); - doorwayDictionary.Add(a.DoorwayComponent, item); - - } - } - } - - public static bool CanDoorwaysConnect(bool result, TileProxy tileA, TileProxy tileB, DoorwayProxy doorwayA, DoorwayProxy doorwayB){ - - if (!result) return false; - if (!active) return true; - - var infoA = doorwayProxyDictionary[doorwayA].info; - var infoB = doorwayProxyDictionary[doorwayB].info; - - // deny if any sister doorway is already in use - // cause it feels like dumb otherwise - if (CheckIfSisterActive(infoA, tileB)){ - return false; - } - - if (CheckIfSisterActive(infoB, tileA)){ - return false; - } - - // allow like normal - return true; - } - - public static bool CheckIfSisterActive(DoorwayConnectionSisterRuleInfo info, TileProxy targetTile){ - if (info == null || info.sisters == null) return false; - - foreach(var sis in info.sisters){ - var proxies = doorwayDictionary[sis].proxies; - foreach(var proxy in proxies){ - var result = proxy.ConnectedDoorway != null && proxy.ConnectedDoorway.TileProxy == targetTile; - if (result) return true; - } - } - - return false; - } - - } -} diff --git a/ScarletMansion/ScarletMansion/DunGenPatch/Doorways/DCleanBase.cs b/ScarletMansion/ScarletMansion/DunGenPatch/Doorways/DCleanBase.cs deleted file mode 100644 index 9b253a8..0000000 --- a/ScarletMansion/ScarletMansion/DunGenPatch/Doorways/DCleanBase.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using UnityEngine; - -namespace ScarletMansion.DunGenPatch.Doorways { - public abstract class DCleanBase : MonoBehaviour { - - public DoorwayCleanup parent; - - void Reset(){ - parent = GetComponent(); - } - - public abstract void Cleanup(); - - } -} diff --git a/ScarletMansion/ScarletMansion/DunGenPatch/Doorways/DCleanConnectorBlockerBasedOnSelected.cs b/ScarletMansion/ScarletMansion/DunGenPatch/Doorways/DCleanConnectorBlockerBasedOnSelected.cs deleted file mode 100644 index 5e067e2..0000000 --- a/ScarletMansion/ScarletMansion/DunGenPatch/Doorways/DCleanConnectorBlockerBasedOnSelected.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using UnityEngine; - -namespace ScarletMansion.DunGenPatch.Doorways { - public class DCleanConnectorBlockerBasedOnSelected : DCleanBase { - - public enum Action { SwitchToConnector, SwitchToBlocker }; - public Action switchAction; - public GameObject target; - - public override void Cleanup() { - var result = false; - foreach(Transform t in parent.doorway.transform){ - if (t.gameObject.activeSelf && t.name.Contains(target.name)) { - result = true; - break; - } - } - - if (result) { - parent.SwitchConnectorBlocker(switchAction == Action.SwitchToConnector); - } - } - - } -} diff --git a/ScarletMansion/ScarletMansion/DunGenPatch/Doorways/DCleanDoorwayCompare.cs b/ScarletMansion/ScarletMansion/DunGenPatch/Doorways/DCleanDoorwayCompare.cs deleted file mode 100644 index 8686ae7..0000000 --- a/ScarletMansion/ScarletMansion/DunGenPatch/Doorways/DCleanDoorwayCompare.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using UnityEngine; -using DunGen; - -namespace ScarletMansion.DunGenPatch.Doorways { - public abstract class DCleanDoorwayCompare : DCleanBase { - - public enum Operation { Equal, NotEqual, LessThan, GreaterThan } - - public Func GetOperation(Operation operation){ - switch(operation){ - case Operation.Equal: - return EqualOperation; - case Operation.NotEqual: - return NotEqualOperation; - case Operation.LessThan: - return LessThanOperation; - case Operation.GreaterThan: - return GreaterThanOperation; - } - return null; - } - - public bool EqualOperation(Doorway other, int doorwayPriority){ - return other.DoorPrefabPriority == doorwayPriority; - } - - public bool NotEqualOperation(Doorway other, int doorwayPriority){ - return other.DoorPrefabPriority != doorwayPriority; - } - - public bool LessThanOperation(Doorway other, int doorwayPriority){ - return other.DoorPrefabPriority < doorwayPriority; - } - - public bool GreaterThanOperation(Doorway other, int doorwayPriority){ - return other.DoorPrefabPriority > doorwayPriority; - } - - } -} diff --git a/ScarletMansion/ScarletMansion/DunGenPatch/Doorways/DCleanRemoveDoorwayBasedOnConnectedDoor.cs b/ScarletMansion/ScarletMansion/DunGenPatch/Doorways/DCleanRemoveDoorwayBasedOnConnectedDoor.cs deleted file mode 100644 index c5687ca..0000000 --- a/ScarletMansion/ScarletMansion/DunGenPatch/Doorways/DCleanRemoveDoorwayBasedOnConnectedDoor.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using UnityEngine; -using DunGen; - -namespace ScarletMansion.DunGenPatch.Doorways { - public class DCleanRemoveDoorwayBasedOnConnectedDoor : DCleanDoorwayCompare { - - public int doorwayPriority; - public Operation operation = Operation.Equal; - - public override void Cleanup() { - var doorway = parent.doorway; - if (doorway.connectedDoorway == null) return; - var result = GetOperation(operation).Invoke(doorway.connectedDoorway, doorwayPriority); - - if (result) { - parent.SwitchDoorwayGameObject(false); - } - } - - } -} diff --git a/ScarletMansion/ScarletMansion/DunGenPatch/Doorways/DCleanRemoveDoorwayBasedOnSelected.cs b/ScarletMansion/ScarletMansion/DunGenPatch/Doorways/DCleanRemoveDoorwayBasedOnSelected.cs deleted file mode 100644 index d75c666..0000000 --- a/ScarletMansion/ScarletMansion/DunGenPatch/Doorways/DCleanRemoveDoorwayBasedOnSelected.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using UnityEngine; - -namespace ScarletMansion.DunGenPatch.Doorways { - public class DCleanRemoveDoorwayBasedOnSelected : DCleanBase { - - public GameObject target; - - public override void Cleanup() { - var result = false; - foreach(Transform t in parent.doorway.transform){ - if (t.gameObject.activeSelf && t.name.Contains(target.name)) { - result = true; - break; - } - } - - if (result) { - parent.SwitchDoorwayGameObject(false); - } - } - - } -} diff --git a/ScarletMansion/ScarletMansion/DunGenPatch/Doorways/DCleanRemoveGameObjectsBasedOnConnectedDoor.cs b/ScarletMansion/ScarletMansion/DunGenPatch/Doorways/DCleanRemoveGameObjectsBasedOnConnectedDoor.cs deleted file mode 100644 index b3a13c8..0000000 --- a/ScarletMansion/ScarletMansion/DunGenPatch/Doorways/DCleanRemoveGameObjectsBasedOnConnectedDoor.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using UnityEngine; -using DunGen; - -namespace ScarletMansion.DunGenPatch.Doorways { - public class DCleanRemoveGameObjectsBasedOnConnectedDoor : DCleanDoorwayCompare { - - public List targets; - public int doorwayPriority; - public Operation operation = Operation.Equal; - - public override void Cleanup() { - var doorway = parent.doorway; - if (doorway.connectedDoorway == null) return; - var result = GetOperation(operation).Invoke(doorway.connectedDoorway, doorwayPriority); - if (result) { - foreach(var t in targets) t.SetActive(false); - } - } - - } -} diff --git a/ScarletMansion/ScarletMansion/DunGenPatch/Doorways/DoorwayCleanup.cs b/ScarletMansion/ScarletMansion/DunGenPatch/Doorways/DoorwayCleanup.cs deleted file mode 100644 index e53b253..0000000 --- a/ScarletMansion/ScarletMansion/DunGenPatch/Doorways/DoorwayCleanup.cs +++ /dev/null @@ -1,75 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using DunGen; -using UnityEngine; -using ScarletMansion.GamePatch.Managers; - -namespace ScarletMansion.DunGenPatch.Doorways { - public class DoorwayCleanup : MonoBehaviour, IDungeonCompleteReceiver { - - [Header("Doorway References")] - public Doorway doorway; - public List connectors; - public List blockers; - public GameObject doorwayGameObject; - - [Header("Cleanup References")] - public DCleanBase[] cleanupList; - - [Header("Overrides")] - public bool overrideConnector; - public bool overrideNoDoorway; - - [ContextMenu("Populate")] - public void Populate(){ - cleanupList = GetComponents(); - } - - void Reset(){ - doorway = GetComponent(); - } - - public void OnDungeonComplete(Dungeon dungeon) { - // fix for items spawning on doorways - SetBlockers(true); - DoorwayManager.Instance.AddDoorwayCleanup(this); - } - - public void Cleanup(){ - // start up like in original - SwitchConnectorBlocker(doorway.ConnectedDoorway != null); - - foreach(var c in cleanupList) - c.Cleanup(); - - if (overrideNoDoorway) SwitchDoorwayGameObject(false); - - // clean up like in original - foreach(var c in connectors){ - if (!c.activeSelf) UnityEngine.Object.DestroyImmediate(c, false); - } - - foreach(var b in blockers){ - if (!b.activeSelf) UnityEngine.Object.DestroyImmediate(b, false); - } - } - - public void SetBlockers(bool state){ - foreach(var b in blockers) b.SetActive(state); - } - - public void SwitchConnectorBlocker(bool isConnector){ - if (overrideConnector) isConnector = true; - foreach(var c in connectors) c.SetActive(isConnector); - foreach(var b in blockers) b.SetActive(!isConnector); - } - - public void SwitchDoorwayGameObject(bool isActive){ - doorwayGameObject.SetActive(isActive); - } - - } -} diff --git a/ScarletMansion/ScarletMansion/DunGenPatch/GeneratePath.cs b/ScarletMansion/ScarletMansion/DunGenPatch/GeneratePath.cs deleted file mode 100644 index e034f10..0000000 --- a/ScarletMansion/ScarletMansion/DunGenPatch/GeneratePath.cs +++ /dev/null @@ -1,314 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using UnityEngine; -using DunGen; -using System.Security; -using System.Security.Permissions; -using DunGen.Graph; - -[assembly: SecurityPermission( SecurityAction.RequestMinimum, SkipVerification = true )] -namespace ScarletMansion.DunGenPatch { - public static class GeneratePath { - - public static bool active => Patch.active; - - //public static List> allMainPathTiles; - - public static int analTestCount = 0; - public static int analTestCountMax = 100; - public static int analAltFailCount = 0; - - public static void RandomizeLineArchetypes(DungeonGenerator gen, bool randomizeMainPath){ - var mainPathString = randomizeMainPath ? "main path" : "branching path"; - //Plugin.logger.LogInfo($"Randomizing archetypes of {mainPathString}"); - - var arch = Assets.networkObjectList.archetypes; - var i = 0; - var j = 0; - - var tilesetsUsed = new Dictionary(); - foreach(var t in Assets.networkObjectList.tilesets){ - tilesetsUsed.Add(t, 0); - } - - while(j < 3 && i < arch.Count) { - var a = arch[i]; - PluginConfig.Instance.branchPathSectionOneValue.UpdateValues(a); - var tiles = randomizeMainPath ? a.TileSets : a.BranchCapTileSets; - RandomizeArchetype(gen, tiles, tilesetsUsed); - ++j; - ++i; - } - - j = 0; - while(j < 4 && i < arch.Count) { - var a = arch[i]; - PluginConfig.Instance.branchPathSectionTwoValue.UpdateValues(a); - var tiles = randomizeMainPath ? a.TileSets : a.BranchCapTileSets; - RandomizeArchetype(gen, tiles, tilesetsUsed); - ++j; - ++i; - } - - j = 0; - while(j < 3 && i < arch.Count) { - var a = arch[i]; - PluginConfig.Instance.branchPathSectionThreeValue.UpdateValues(a); - var tiles = randomizeMainPath ? a.TileSets : a.BranchCapTileSets; - RandomizeArchetype(gen, tiles, tilesetsUsed); - ++j; - ++i; - } - - /* - for(var k = 0; k < arch.Count; ++k){ - Plugin.logger.LogInfo($"a{k}"); - var a = arch[k]; - var tiles = randomizeMainPath ? a.TileSets : a.BranchCapTileSets; - foreach(var t in tiles){ - Plugin.logger.LogInfo($" {t.name}"); - } - } - */ - } - - public static void RandomizeArchetype(DungeonGenerator gen, List targetTileSet, Dictionary tilesetsUsed){ - // get 3 random - var newTiles = Assets.networkObjectList.tilesets.OrderBy(t => tilesetsUsed[t] + gen.RandomStream.NextDouble()).Take(3); - - var i = targetTileSet.Count - 1; - foreach(var n in newTiles){ - targetTileSet[i] = n; - --i; - - tilesetsUsed[n] += 1; - } - } - - public static IEnumerator GenerateAlternativeMainPaths(DungeonGenerator gen) { - - // the amount of extra alt. paths - var altV = PluginConfig.Instance.mainPathCountValue; - if (PluginConfig.Instance.disableBasementValue) { - altV = Mathf.Min(altV, 2); - } - var altCount = altV - 1; - - if (!active || altCount == 0){ - Patch.callAlternative = false; - yield return gen.Wait(gen.GenerateBranchPaths()); - Patch.callAlternative = true; - yield break; - } - - gen.ChangeStatus(GenerationStatus.MainPath); - - var allMainPathTiles = new List>(); - allMainPathTiles.Add(gen.proxyDungeon.MainPathTiles.ToList()); - - // main tile is the true main room and not the fake room - // this MUST have multiple doorways as you can imainge - var mainTile = gen.proxyDungeon.MainPathTiles[1]; - var mainTileDoorwayGroups = mainTile.Prefab.GetComponentInChildren(); - var fakeTileProxy = new DoorwayProxy(mainTile, 0, mainTile.doorways[0].DoorwayComponent, Vector3.zero, Quaternion.identity); - - // what this is for needs some explaining - // the alternate main paths are really just branches that can't end early - // since they are just branches, they are affected by the branch prune setting - // as such, the final node of an alternate main path CANNOT be a node that can be pruned - // luckily, the last node is my Nodes section has tiles that won't be pruned - // so i'm just using that so the final node cannot be a target for pruning - - for (var b = 0; b < altCount; ++b) { - RandomizeLineArchetypes(gen, true); - var previousTile = mainTile; - var targetLength = Mathf.RoundToInt(gen.DungeonFlow.Length.GetRandom(gen.RandomStream) * gen.LengthMultiplier); - var archetypes = new List(targetLength); - - var newMainPathTiles = new List(); - newMainPathTiles.Add(mainTile); - - var nodes = gen.DungeonFlow.Nodes.Skip(2); - var nodesVisited = new List(nodes.Count()); - - // most of this code is a mix of the GenerateMainPath() - // and GenerateBranch() code - for(var t = 1; t < targetLength; ++t){ - var lineDepthRatio = Mathf.Clamp01((float)t / (targetLength - 1)); - var lineAtDepth = gen.DungeonFlow.GetLineAtDepth(lineDepthRatio); - if (lineAtDepth == null){ - yield return gen.Wait(gen.InnerGenerate(true)); - yield break; - } - - - - if (lineAtDepth != gen.previousLineSegment){ - gen.currentArchetype = lineAtDepth.GetRandomArchetype(gen.RandomStream, archetypes); - gen.previousLineSegment = lineAtDepth; - } - - // terrible solution but FUCK it - // and yet it worked - // this is how my last node cannot be a target of pruning - GraphNode graphNode = null; - DungeonArchetype archetype = null; - foreach(var g in nodes) { - if (lineDepthRatio >= g.Position && !nodesVisited.Contains(g)) { - graphNode = g; - nodesVisited.Add(g); - break; - } - } - - List useableTileSets; - if (graphNode != null) { - archetype = graphNode.NodeType == NodeType.Normal ? Assets.networkObjectList.hallwayEntranceArchetype : null; - useableTileSets = graphNode.TileSets; - } else { - archetype = gen.currentArchetype; - useableTileSets = archetype.TileSets; - } - - if (t == 1){ - - // go to each doorway - foreach(var doorway in mainTile.doorways){ - // if null or another fake, ignore - // we want the real ones - var con = doorway.ConnectedDoorway; - if (con == fakeTileProxy || con == null) continue; - - // grab its corresponding group - var groups = mainTileDoorwayGroups.GrabDoorwayGroup(doorway.DoorwayComponent); - if (groups == null) continue; - - // go through the list again, but this time we adding fakes to trick the AddTile() - foreach(var again in mainTile.doorways){ - // if null AND its part of the group - // add the fake - if (again.ConnectedDoorway == null && groups.Contains(again.DoorwayComponent)){ - again.ConnectedDoorway = fakeTileProxy; - } - } - } - - } - - - var tileProxy = gen.AddTile(previousTile, useableTileSets, lineDepthRatio, archetype, TilePlacementResult.None); - - if (tileProxy == null) { - if (!Patch.startAnalysis) Plugin.logger.LogInfo($"Alt. main branch gen failed at {b}:{lineDepthRatio}"); - analAltFailCount++; - yield return gen.Wait(gen.InnerGenerate(true)); - yield break; - } - - // this is debug code from when a mysterious bug arised - // the culprit? the final node of the alternate main path being pruned of course - if (lineDepthRatio >= 1f){ - if (!Patch.startAnalysis) Plugin.logger.LogInfo($"Alt. main branch at {b} ended with {tileProxy.PrefabTile.name}"); - } - - tileProxy.Placement.BranchDepth = t; - tileProxy.Placement.NormalizedBranchDepth = lineDepthRatio; - - if (graphNode != null) { - tileProxy.Placement.GraphNode = graphNode; - tileProxy.Placement.GraphLine = null; - } else { - tileProxy.Placement.GraphNode = null; - tileProxy.Placement.GraphLine = lineAtDepth; - } - - - previousTile = tileProxy; - newMainPathTiles.Add(tileProxy); - - if (gen.ShouldSkipFrame(true)) yield return gen.GetRoomPause(); - } - - allMainPathTiles.Add(newMainPathTiles); - - } - - // okay lets fix the fakes - foreach(var doorway in mainTile.doorways){ - if (doorway.ConnectedDoorway == fakeTileProxy) { - doorway.ConnectedDoorway = null; - } - } - - - Patch.callAlternative = false; - if (!Patch.startAnalysis) Plugin.logger.LogInfo($"Created {altCount} alt. paths, creating branches now"); - - gen.ChangeStatus(GenerationStatus.Branching); - - // this is major trickery and it works still - for(var b = 0; b < altCount + 1; ++b){ - if (!Patch.startAnalysis) Plugin.logger.LogInfo($"Branch {b}"); - RandomizeLineArchetypes(gen, false); - gen.proxyDungeon.MainPathTiles = allMainPathTiles[b]; - - /* - foreach (var t in gen.proxyDungeon.MainPathTiles){ - Plugin.logger.LogInfo(t.Prefab.name); - Plugin.logger.LogInfo(t.Placement.Archetype); - } - */ - yield return gen.Wait(gen.GenerateBranchPaths()); - } - - Patch.callAlternative = true; - - gen.proxyDungeon.MainPathTiles = allMainPathTiles[0]; - - if (AnalysisUpdate(gen)) yield return gen.Wait(gen.InnerGenerate(true)); - } - - public static DungeonArchetype ModifyMainBranchNodeArchetype(DungeonArchetype archetype, GraphNode node){ - if (!Patch.active) return archetype; - if (node.NodeType == NodeType.Normal) return Assets.networkObjectList.hallwayEntranceArchetype; - return archetype; - } - - public static bool AnalysisUpdate(DungeonGenerator gen){ - if (Patch.startAnalysis && analTestCount <= analTestCountMax) { - var t = Patch.stopwatch.ElapsedMilliseconds; - //Patch.tileCalculations.Add(t); - //Plugin.logger.LogInfo($"C{TestCount}, T({Patch.tileCalculations.ToString()}), S{AltFailCount}, R{gen.retryCount}, D({Patch.doorwayPairs.ToString()})"); - - var allTiles = gen.proxyDungeon.AllTiles; - var firstTilePos = allTiles[0].Placement.position; - for(var i = 1; i < allTiles.Count; ++i){ - var tile = allTiles[i]; - var tilePrefab = tile.Prefab; - var prefabBasePos = tilePrefab.transform.position; - var scrap = tilePrefab.GetComponentsInChildren(); - foreach(var s in scrap){ - var offPos = s.transform.position - prefabBasePos; - var realPos = tile.Placement.Rotation * offPos + tile.Placement.Position; - //var floor = Mathf.FloorToInt((realPos.y + 16f) / 8f); - Patch.scrapDistance.Add(Vector3.Distance(realPos, firstTilePos)); - //Patch.scrapFloors.Add(floor); - } - } - - Plugin.logger.LogInfo($"C{analTestCount}, S{analAltFailCount}, R{gen.retryCount - analAltFailCount - analTestCount}\nLoot {Patch.scrapDistance.ToString()}"); - - analTestCount++; - Patch.stopwatch.Restart(); - return true; - } - return false; - } - - - } -} diff --git a/ScarletMansion/ScarletMansion/DunGenPatch/GeneratePathPatch.cs b/ScarletMansion/ScarletMansion/DunGenPatch/GeneratePathPatch.cs index 697eab0..7b03896 100644 --- a/ScarletMansion/ScarletMansion/DunGenPatch/GeneratePathPatch.cs +++ b/ScarletMansion/ScarletMansion/DunGenPatch/GeneratePathPatch.cs @@ -12,6 +12,7 @@ using UnityEngine; using System.Collections; using DunGen; using LethalLevelLoader; +using DunGen.Graph; namespace ScarletMansion.DunGenPatch { @@ -20,10 +21,8 @@ namespace ScarletMansion.DunGenPatch { [HarmonyPatch(typeof(RoundManager), "GenerateNewFloor")] [HarmonyPrefix] public static void DungeonGeneratorGenerate_PrefixPrefix(){ - // safety check Plugin.logger.LogInfo("Disabling SDM logic"); Patch.Deactivate(); - //Patch.ActivateAnalysis(); } public static void GeneratePatch(RoundManager roundManager){ @@ -31,91 +30,6 @@ namespace ScarletMansion.DunGenPatch { Patch.Activate(roundManager.dungeonGenerator.Generator); } - [HarmonyPostfix] - [HarmonyPatch(typeof(DungeonGenerator), "GenerateMainPath")] - public static void GenerateMainPathPatch(ref DungeonGenerator __instance, ref IEnumerator __result){ - if (Patch.active && Patch.callAlternative) { - GeneratePath.RandomizeLineArchetypes(__instance, true); - } - } - - [HarmonyPostfix] - [HarmonyPatch(typeof(DungeonGenerator), "GenerateBranchPaths")] - public static void GenerateBranchPathsPatch(ref DungeonGenerator __instance, ref IEnumerator __result){ - if (Patch.active && Patch.callAlternative) { - __result = GeneratePath.GenerateAlternativeMainPaths(__instance); - } - } - - [HarmonyPostfix] - [HarmonyPatch(typeof(RoundManager), "FinishGeneratingLevel")] - public static void GenerateBranchPathsPatch(){ - if (Patch.active) { - Plugin.logger.LogInfo("Alt. InnerGenerate() function complete"); - } - } - - [HarmonyTranspiler] - [HarmonyPatch(typeof(DungeonGenerator), "GenerateMainPath", MethodType.Enumerator)] - public static IEnumerable GenerateMainPathPatch(IEnumerable instructions){ - - var addFunction = typeof(List).GetMethod("Add", BindingFlags.Instance | BindingFlags.Public); - - var sequence = new InstructionSequence("archetype node"); - sequence.AddOperandTypeCheck(OpCodes.Ldfld, typeof(List)); - sequence.AddBasic(OpCodes.Ldnull); - sequence.AddBasic(OpCodes.Callvirt, addFunction); - - foreach(var instruction in instructions){ - - if (sequence.VerifyStage(instruction)){ - - var method = typeof(GeneratePath).GetMethod("ModifyMainBranchNodeArchetype", BindingFlags.Public | BindingFlags.Static); - - yield return new CodeInstruction(OpCodes.Ldloc_S, 8); - yield return new CodeInstruction(OpCodes.Call, method); - - yield return instruction; - - continue; - } - - yield return instruction; - } - - sequence.ReportComplete(); - } - - /* - - [HarmonyPatch(typeof(DungeonGenerator), "AddTile")] - [HarmonyPostfix] - public static void AddTilePatch(TileProxy attachTo, IEnumerable useableTileSets, DungeonArchetype archetype, ref TileProxy __result){ - var atString = attachTo != null ? attachTo.Prefab.ToString() : "NULL"; - var aString = archetype ? archetype.ToString() : "NULL"; - var rString = __result != null ? __result.Prefab.ToString() : "NULL"; - - Plugin.logger.LogInfo($""); - Plugin.logger.LogInfo($"Attach: {atString}"); - Plugin.logger.LogInfo($"ValidCount: {useableTileSets.Sum(u => u.TileWeights.Weights.Count).ToString()}"); - Plugin.logger.LogInfo($"Entry: {aString}"); - Plugin.logger.LogInfo($"Result: {rString}"); - - } - - [HarmonyPatch(typeof(DungeonGenerator), "TryPlaceTile")] - [HarmonyPostfix] - public static void TryPlaceTilePatch(ref TilePlacementResult __result){ - Plugin.logger.LogInfo(__result.ToString()); - } - - [HarmonyPatch(typeof(DoorwayPairFinder), "GetDoorwayPairs")] - [HarmonyPostfix] - public static void GetDoorwayPairsPatch(ref Queue __result){ - Plugin.logger.LogInfo(__result.Count().ToString()); - } - */ - } diff --git a/ScarletMansion/ScarletMansion/DunGenPatch/OptimizePatch.cs b/ScarletMansion/ScarletMansion/DunGenPatch/OptimizePatch.cs deleted file mode 100644 index 3b2e2c0..0000000 --- a/ScarletMansion/ScarletMansion/DunGenPatch/OptimizePatch.cs +++ /dev/null @@ -1,59 +0,0 @@ -/* -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using DunGen; -using UnityEngine; -using HarmonyLib; - -namespace ScarletMansion.DunGenPatch { - public class OptimizePatch { - - [HarmonyPatch(typeof(DoorwayPairFinder), "GetDoorwayPairs")] - [HarmonyPrefix] - public static bool GetDoorwayPairsPatch(ref DoorwayPairFinder __instance, int? maxCount, ref Queue __result){ - - __instance.tileOrder = __instance.CalculateOrderedListOfTiles(); - var doorwayPairs = __instance.PreviousTile == null ? - __instance.GetPotentialDoorwayPairsForFirstTile() : - __instance.GetPotentialDoorwayPairsForNonFirstTile(); - - var num = doorwayPairs.Count(); - if (maxCount != null) { - num = Mathf.Min(num, maxCount.Value); - } - __result = new Queue(num); - - var newList = OrderDoorwayPairs(doorwayPairs, num); - foreach(var item in newList){ - __result.Enqueue(item); - } - - return false; - } - - private class DoorwayPairComparer : IComparer { - public int Compare(DoorwayPair x, DoorwayPair y) { - var tileWeight = y.TileWeight.CompareTo(x.TileWeight); - if (tileWeight == 0) return y.DoorwayWeight.CompareTo(x.DoorwayWeight); - return tileWeight; - } - } - - private static IEnumerable OrderDoorwayPairs(IEnumerable list, int num){ - - var c = list.Count(); - var d = Mathf.Min(c, num); - if (d > 1) { - Patch.doorwayPairs.Add(d); - } - - return list.OrderBy(x => x, new DoorwayPairComparer()).Take(num); - } - - - } -} -*/ \ No newline at end of file diff --git a/ScarletMansion/ScarletMansion/DunGenPatch/Patch.cs b/ScarletMansion/ScarletMansion/DunGenPatch/Patch.cs index db1f491..1f57612 100644 --- a/ScarletMansion/ScarletMansion/DunGenPatch/Patch.cs +++ b/ScarletMansion/ScarletMansion/DunGenPatch/Patch.cs @@ -10,6 +10,9 @@ using UnityEngine.AI; using System.Diagnostics; using UnityEngine.Rendering; using UnityEngine.Rendering.HighDefinition; +using DunGenPlus.Collections; +using GameNetcodeStuff; +using ScarletMansion.GamePatch.Components; namespace ScarletMansion.DunGenPatch { public static class Patch { @@ -18,102 +21,70 @@ namespace ScarletMansion.DunGenPatch { public static bool callAlternative; public static DungeonGenerator generatorInstance; - public static bool startAnalysis; - public static Stopwatch stopwatch; - public static AnalysisUtilities.Average scrapDistance; - public static AnalysisUtilities.Average scrapFloors; - //public static AnalysisUtilities.Average tileCalculations; - //public static AnalysisUtilities.Average doorwayPairs; - - public static HDRenderPipelineAsset previousHDRPAsset; - public static HDRenderPipelineAsset sdmHDRPAsset; - public static void Activate(DungeonGenerator generator){ active = true; callAlternative = true; generatorInstance = generator; - //startAnalysis = true; var scale = generator.LengthMultiplier; - var bounds = GetDungeonBounds(scale); - - generator.DungeonFlow.TileInjectionRules = new List(); - - generator.RestrictDungeonToBounds = true; - generator.TilePlacementBounds = bounds; - Plugin.logger.LogInfo($"Set new dungeon bounds with, {bounds.center} and {bounds.size}"); var mainPathLength = generator.DungeonFlow.Length; Plugin.logger.LogInfo($"Length of main path be: {GetLength(mainPathLength, scale)}"); GamePatch.LoadAssetsIntoLevelPatch.ModifyLevel(StartOfRound.Instance.currentLevel); - - Plugin.logger.LogInfo("Updating HDRP asset: doubling max shadows request"); - try { - previousHDRPAsset = QualitySettings.renderPipeline as HDRenderPipelineAsset; - sdmHDRPAsset = ScriptableObject.Instantiate(previousHDRPAsset); - - var settings = sdmHDRPAsset.currentPlatformRenderPipelineSettings; - Plugin.logger.LogInfo($"maxScreenSpaceShadowSlots: {settings.hdShadowInitParams.maxScreenSpaceShadowSlots} -> {settings.hdShadowInitParams.maxScreenSpaceShadowSlots * 2}"); - //Plugin.logger.LogInfo($"maxShadowRequests: {settings.hdShadowInitParams.maxShadowRequests} -> {settings.hdShadowInitParams.maxShadowRequests * 2}"); - - settings.hdShadowInitParams.maxScreenSpaceShadowSlots *= 2; - //settings.hdShadowInitParams.maxShadowRequests *= 2; - sdmHDRPAsset.currentPlatformRenderPipelineSettings = settings; - - QualitySettings.renderPipeline = sdmHDRPAsset; - } catch (Exception e) { - Plugin.logger.LogError("Failed to update HDRP asset"); - Plugin.logger.LogError(e.ToString()); - } - - if (startAnalysis) ActivateAnalysis(); - } - - - public static void ActivateAnalysis(){ - stopwatch = new Stopwatch(); - stopwatch.Start(); - - scrapDistance = new AnalysisUtilities.Average(); - scrapFloors = new AnalysisUtilities.Average(); - //tileCalculations = new AnalysisUtilities.Average(); - //doorwayPairs = new AnalysisUtilities.Average(); - } - - public static Bounds GetDungeonBounds(float scale){ - var width = PluginConfig.Instance.dunGenWidthBaseValue; - var length = PluginConfig.Instance.dunGenLengthBaseValue; - var widthFac = PluginConfig.Instance.dunGenWidthMultiFactorValue; - var lengthFac = PluginConfig.Instance.dunGenLengthMultiFactorValue; - - var totalwidth = width + (width * (scale - 1) * widthFac); - var totallength = length + (length * (scale - 1) * lengthFac); - - //var - - var offset = new Vector3(0f, 4f, totallength * 0.5f - 8f); - var size = new Vector3(totalwidth, 40f, totallength); - return new Bounds(offset, size); } public static string GetLength(IntRange range, float multi){ return $"({range.Min * multi} - {range.Max * multi})"; } - public static void Deactivate(){ + public static void Deactivate(bool ignoreScarletPlayer = false){ active = false; callAlternative = false; generatorInstance = null; GamePatch.JesterAIPatch.active = false; - if (previousHDRPAsset && QualitySettings.renderPipeline == sdmHDRPAsset) { - Plugin.logger.LogInfo("Restoring original HDRP asset"); + if (ignoreScarletPlayer) return; - QualitySettings.renderPipeline = previousHDRPAsset; - previousHDRPAsset = null; - sdmHDRPAsset = null; + var localPlayer = StartOfRound.Instance.localPlayerController; + var scarletPlayer = ScarletPlayerControllerB.GetScarletPlayerScript(localPlayer); + if (scarletPlayer != null){ + scarletPlayer.stabbedSelf = false; + scarletPlayer.fellInPit = false; + } + + + + } + + public static void UpdateDunGenExtenderProperties(DunGenExtenderProperties props) { + props.MainPathCount = PluginConfig.Instance.mainPathCountValue; + if (PluginConfig.Instance.disableBasementValue) { + props.MainPathCount = Mathf.Min(props.MainPathCount, 2); + } + + var mayorTileSet = PluginConfig.Instance.disableBasementValue ? Assets.networkObjectList.mayorVanillaTileset : Assets.networkObjectList.mayorRegularTileset; + Assets.dungeon.Nodes[1].TileSets = new List() { mayorTileSet }; + props.MainRoomTilePrefab = mayorTileSet.TileWeights.Weights[0].Value; + + props.DungeonSizeBase = new Vector3(PluginConfig.Instance.dunGenWidthBaseValue, props.DungeonSizeBase.y, PluginConfig.Instance.dunGenLengthBaseValue); + props.DungeonSizeFactor = new Vector3(PluginConfig.Instance.dunGenWidthMultiFactorValue, props.DungeonSizeFactor.y, PluginConfig.Instance.dunGenLengthMultiFactorValue); + + var i = 0; + while(i < 3) { + PluginConfig.Instance.branchPathSectionOneValue.UpdateValues(props.LineRandomizerArchetypes[i]); + ++i; + } + + while(i < 7) { + PluginConfig.Instance.branchPathSectionTwoValue.UpdateValues(props.LineRandomizerArchetypes[i]); + ++i; + } + + while(i < 10) { + PluginConfig.Instance.branchPathSectionThreeValue.UpdateValues(props.LineRandomizerArchetypes[i]); + ++i; } } diff --git a/ScarletMansion/ScarletMansion/DunGenPatch/PostProcessPatch.cs b/ScarletMansion/ScarletMansion/DunGenPatch/PostProcessPatch.cs deleted file mode 100644 index c92d77f..0000000 --- a/ScarletMansion/ScarletMansion/DunGenPatch/PostProcessPatch.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using DunGen; -using HarmonyLib; -using UnityEngine; - -namespace ScarletMansion.DunGenPatch { - public class PostProcessPatch { - - [HarmonyPostfix] - [HarmonyPatch(typeof(DungeonGenerator), "PostProcess")] - public static void GenerateBranchPathsPatch(ref DungeonGenerator __instance){ - if (Patch.active) { - var value = __instance.RandomStream.Next(999); - GamePatch.Props.SpawnSyncedObjectCycle.UpdateCycle(value); - } - } - - } -} diff --git a/ScarletMansion/ScarletMansion/GamePatch/Components/PathOpenUpParent.cs b/ScarletMansion/ScarletMansion/GamePatch/Components/PathOpenUpParent.cs new file mode 100644 index 0000000..da53c93 --- /dev/null +++ b/ScarletMansion/ScarletMansion/GamePatch/Components/PathOpenUpParent.cs @@ -0,0 +1,60 @@ +using DunGen; +using System; +using System.Collections.Generic; +using System.Linq; +using UnityEngine; + +namespace ScarletMansion.GamePatch.Components +{ + public class PathOpenUpParent : MonoBehaviour, IDungeonCompleteReceiver { + + [System.Serializable] + public class Chokepoint { + public PathOpenup[] paths; + + public void UpdatePath(System.Random sysRandom){ + var count = sysRandom.Next(1, Mathf.Min(paths.Length, 2)); + var length = paths.Length; + + var items = new int[length]; + for(var i = 0; i < length; i++){ + items[i] = i; + } + Utility.Shuffle(sysRandom, items); + + var j = 0; + while(j < 1) { + paths[j].UpdatePath(PathOpenup.State.Active); + ++j; + } + + while(j < length) { + paths[j].UpdatePath(PathOpenup.State.UnActive); + ++j; + } + } + } + + public Chokepoint[] chokepoints; + public PathOpenup[] paths; + + void Reset(){ + paths = GetComponentsInChildren(); + } + + public void OnDungeonComplete(Dungeon dungeon) { + var anyChanges = true; + var dunRandom = DunGenPatch.Patch.generatorInstance.RandomStream; + var sysRandom = new System.Random(dunRandom.Next()); + + foreach(var c in chokepoints) { + c.UpdatePath(sysRandom); + } + + foreach(var c in paths) { + c.CleanUp(); + } + } + + } +} diff --git a/ScarletMansion/ScarletMansion/GamePatch/Components/PathOpenup.cs b/ScarletMansion/ScarletMansion/GamePatch/Components/PathOpenup.cs new file mode 100644 index 0000000..8df160b --- /dev/null +++ b/ScarletMansion/ScarletMansion/GamePatch/Components/PathOpenup.cs @@ -0,0 +1,40 @@ +using DunGen; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.Remoting.Contexts; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; + +namespace ScarletMansion.GamePatch.Components { + + public class PathOpenup : MonoBehaviour { + + public GameObject[] connectorGameObjects; + public GameObject[] blockerGameObjects; + + public enum State { + NotSet, + UnActive, + Active + } + private State state; + + + public void UpdatePath(State newState){ + if (newState < state) return; + + var connect = newState == State.Active; + foreach(var connectorGameObject in connectorGameObjects) connectorGameObject.SetActive(connect); + foreach(var blockerGameObject in blockerGameObjects) blockerGameObject.SetActive(!connect); + state = newState; + } + + public void CleanUp() { + var targets = state == State.Active ? blockerGameObjects : connectorGameObjects; + foreach(var t in targets) Destroy(t); + } + + } +} diff --git a/ScarletMansion/ScarletMansion/GamePatch/Components/ScarletBedroom.cs b/ScarletMansion/ScarletMansion/GamePatch/Components/ScarletBedroom.cs index 26517c6..4b6c2d3 100644 --- a/ScarletMansion/ScarletMansion/GamePatch/Components/ScarletBedroom.cs +++ b/ScarletMansion/ScarletMansion/GamePatch/Components/ScarletBedroom.cs @@ -182,11 +182,9 @@ namespace ScarletMansion.GamePatch.Components { if (bonusEnemy == null) return; try { - var enemy = bonusEnemy.enemy; - var enemyIndex = bonusEnemy.index; - if (enemyIndex > -1){ + if (bonusEnemy.index > -1){ var pos = vent.transform.position; var dir = target.transform.position - pos; dir.y = 0f; @@ -196,7 +194,7 @@ namespace ScarletMansion.GamePatch.Components { bonusEnemy.ApplySpawnLogic(); roundmanager.currentEnemyPower += enemy.PowerLevel; - var spawnedEnemy = roundmanager.SpawnEnemyGameObject(vent.transform.position, y, enemyIndex); + var spawnedEnemy = ScarletNetworkManagerUtility.CreateEnemyWithRef(bonusEnemy, vent.transform.position, y); ScarletNetworkManager.Instance.RequestEvilSkinApply(spawnedEnemy, enemy.name.ToLowerInvariant()); } @@ -223,6 +221,7 @@ namespace ScarletMansion.GamePatch.Components { public void OnDungeonComplete(Dungeon dungeon) { AngerManager.Instance.AddBedroom(this); + AngerManager.Instance.AddRoomOfInterest(transform); var parent = GetComponentInParent(); lights = parent.GetComponentsInChildren(); diff --git a/ScarletMansion/ScarletMansion/GamePatch/Components/ScarletClock.cs b/ScarletMansion/ScarletMansion/GamePatch/Components/ScarletClock.cs index e70d410..6b42482 100644 --- a/ScarletMansion/ScarletMansion/GamePatch/Components/ScarletClock.cs +++ b/ScarletMansion/ScarletMansion/GamePatch/Components/ScarletClock.cs @@ -39,10 +39,10 @@ namespace ScarletMansion.GamePatch.Components { } } - var timeOfDay = TimeOfDay.Instance; - var totalMinutes = (int)(timeOfDay.normalizedTimeOfDay * (60f * timeOfDay.numberOfHours)) + 360; - var hours = Mathf.FloorToInt(totalMinutes / 60f); - var minutes = totalMinutes % 60; + var time = Utility.GetTime(); + var totalMinutes = time.totalMinutes; + var hours = time.hours; + var minutes = time.minutes; var timeChanged = lastTotalMinutes != totalMinutes; var hourChanged = lastHour != hours; diff --git a/ScarletMansion/ScarletMansion/GamePatch/Components/ScarletDoor.cs b/ScarletMansion/ScarletMansion/GamePatch/Components/ScarletDoor.cs index a273599..4b8c647 100644 --- a/ScarletMansion/ScarletMansion/GamePatch/Components/ScarletDoor.cs +++ b/ScarletMansion/ScarletMansion/GamePatch/Components/ScarletDoor.cs @@ -13,6 +13,9 @@ namespace ScarletMansion.GamePatch.Components { [Header("Door Reference")] public DoorLock door; + public bool doorState; + public bool overrideLock; + public bool overrideUnlock; [Header("Personal Refs")] public NavMeshObstacle obstacle; @@ -25,18 +28,40 @@ namespace ScarletMansion.GamePatch.Components { AngerManager.Instance.AddDoor(this); } - [ServerRpc] - public void LockDoorServerRpc(){ - LockDoorClientRpc(); - } - - [ServerRpc] - public void UnlockDoorServerRpc(){ - UnlockDoorClientRpc(); + [ClientRpc] + public void LockDoorClientRpc(){ + doorState = true; + ReevalulateDoorState(); } [ClientRpc] - public void LockDoorClientRpc(){ + public void UnlockDoorClientRpc(){ + doorState = false; + ReevalulateDoorState(); + } + + [ClientRpc] + public void LockDoorOverrideClientRpc(bool state){ + overrideLock = state; + ReevalulateDoorState(); + } + + [ClientRpc] + public void UnlockDoorOverrideClientRpc(bool state){ + overrideUnlock = state; + ReevalulateDoorState(); + } + + private void ReevalulateDoorState(){ + var state = doorState; + if (overrideUnlock) state = false; + if (overrideLock) state = true; + + if (state) LockDoorCall(); + else UnlockDoorCall(); + } + + private void LockDoorCall(){ if (door){ door.isDoorOpened = false; door.navMeshObstacle.enabled = true; @@ -54,8 +79,7 @@ namespace ScarletMansion.GamePatch.Components { ps.Play(); } - [ClientRpc] - public void UnlockDoorClientRpc(){ + private void UnlockDoorCall() { if (door){ door.doorTrigger.interactable = true; door.isLocked = previousDoorLockValue; diff --git a/ScarletMansion/ScarletMansion/GamePatch/Components/ScarletDoorLock.cs b/ScarletMansion/ScarletMansion/GamePatch/Components/ScarletDoorLock.cs index 94b6bc7..9b7d9af 100644 --- a/ScarletMansion/ScarletMansion/GamePatch/Components/ScarletDoorLock.cs +++ b/ScarletMansion/ScarletMansion/GamePatch/Components/ScarletDoorLock.cs @@ -6,7 +6,9 @@ using System.Threading.Tasks; using UnityEngine; using Unity.Netcode; using ScarletMansion.GamePatch.Enemies; +using System.Security.Permissions; +[assembly: SecurityPermission( SecurityAction.RequestMinimum, SkipVerification = true )] namespace ScarletMansion.GamePatch.Components { public class ScarletDoorLock : DoorLock { @@ -86,7 +88,8 @@ namespace ScarletMansion.GamePatch.Components { { typeof(SpringManAI), (e) => e.currentBehaviourStateIndex == 0 }, { typeof(KnightVariant), (e) => e.currentBehaviourStateIndex == 0 }, { typeof(ButlerEnemyAI), (e) => e.currentBehaviourStateIndex <= 1 }, - { typeof(MaidVariant), (e) => e.currentBehaviourStateIndex <= 1 } + { typeof(MaidVariant), (e) => e.currentBehaviourStateIndex <= 1 }, + { typeof(KnightGhostVariant), (e) => false } }; static readonly Dictionary EnemyDoorDamagePerSecond = new Dictionary(){ @@ -104,7 +107,8 @@ namespace ScarletMansion.GamePatch.Components { { typeof(SpringManAI), 12.5f }, { typeof(KnightVariant), 12.5f }, { typeof(ButlerEnemyAI), 50f }, - { typeof(MaidVariant), 50f } + { typeof(MaidVariant), 50f }, + { typeof(KnightGhostVariant), 9999f } }; public bool IsInOpenDoorNormallyState(EnemyAI enemy){ diff --git a/ScarletMansion/ScarletMansion/GamePatch/Components/ScarletFrame.cs b/ScarletMansion/ScarletMansion/GamePatch/Components/ScarletFrame.cs index f8bbb5e..0750e1b 100644 --- a/ScarletMansion/ScarletMansion/GamePatch/Components/ScarletFrame.cs +++ b/ScarletMansion/ScarletMansion/GamePatch/Components/ScarletFrame.cs @@ -8,42 +8,31 @@ using Unity.Netcode; using GameNetcodeStuff; namespace ScarletMansion.GamePatch.Components { - public class ScarletFrame : NetworkBehaviour { + public class ScarletFrame : MonoBehaviour { - //public MeshRenderer renderer; - //public Material[] materials; + public float visualUpdate = 0.2f; + private float visualUpdateCurrent = 0f; - public void OnInteract(PlayerControllerB player){ - var direction = player.transform.position - transform.position; - direction.y = 0f; - - ChangeDirection(direction); - ChangeDirectionServerRpc(direction); + void Start(){ + visualUpdateCurrent = UnityEngine.Random.value * visualUpdate; } - /* - [ClientRpc] - public void UpdateMaterialClientRpc(int value){ - var mats = new List(2); - renderer.GetMaterials(mats); - - mats[1] = materials[value % materials.Length]; - renderer.SetMaterials(mats); - } - */ - - [ServerRpc(RequireOwnership = false)] - public void ChangeDirectionServerRpc(Vector3 direction){ - ChangeDirectionClientRpc(direction); + void Update() { + visualUpdateCurrent += Time.deltaTime; + if (visualUpdateCurrent > visualUpdate) { + LookAtLocalPlayer(); + visualUpdateCurrent = 0f; + } } - [ClientRpc] - public void ChangeDirectionClientRpc(Vector3 direction){ - ChangeDirection(direction); - } + void LookAtLocalPlayer(){ + var localPlayer = StartOfRound.Instance.localPlayerController; + if (localPlayer && !localPlayer.isPlayerDead) { + var direction = localPlayer.transform.position - transform.position; + direction.y = 0f; - public void ChangeDirection(Vector3 direction){ - transform.rotation = Quaternion.LookRotation(direction); + transform.rotation = Quaternion.LookRotation(direction); + } } } diff --git a/ScarletMansion/ScarletMansion/GamePatch/Components/ScarletPlayerControllerB.cs b/ScarletMansion/ScarletMansion/GamePatch/Components/ScarletPlayerControllerB.cs index 5edd744..cb738c8 100644 --- a/ScarletMansion/ScarletMansion/GamePatch/Components/ScarletPlayerControllerB.cs +++ b/ScarletMansion/ScarletMansion/GamePatch/Components/ScarletPlayerControllerB.cs @@ -9,12 +9,45 @@ using GameNetcodeStuff; namespace ScarletMansion.GamePatch.Components { public class ScarletPlayerControllerB : MonoBehaviour { + public static Dictionary playerControllers; + + // self public PlayerControllerB player; + // animation + public AnimatorOverrideController playerOverrideController; + + // second-chance states + public bool stabbedSelf; + public bool fellInPit; + + public static ScarletPlayerControllerB GetScarletPlayerScript(PlayerControllerB player) { + if (!playerControllers.TryGetValue(player, out var scarlet)) { + scarlet = player.GetComponent(); + if (scarlet == null) { + Plugin.logger.LogError($"Couldn't find scarlet player script for {player}. Kinda bad"); + return null; + } + + Plugin.logger.LogMessage($"Scarlet player script for {player} was not initially registered. We good now but like why?"); + playerControllers.Add(player, scarlet); + } + return scarlet; + } + + public static void InitializeScarletScripts() { + playerControllers = new Dictionary(); + } + public void Initialize(PlayerControllerB player){ this.player = player; CreateHelmetForFlashlight(player, Assets.flashlight, 0); - CreateHelmetForFlashlight(player, Assets.flashlightBB, 1); + CreateHelmetForFlashlight(player, Assets.flashlightBB, 1); + } + + public void Register(){ + if (!playerControllers.ContainsKey(player)) + playerControllers.Add(player, this); } public static void CreateHelmetForFlashlight(PlayerControllerB player, Assets.Flashlight flashlight, int index){ diff --git a/ScarletMansion/ScarletMansion/GamePatch/Components/ScarletRadio.cs b/ScarletMansion/ScarletMansion/GamePatch/Components/ScarletRadio.cs new file mode 100644 index 0000000..cc58f73 --- /dev/null +++ b/ScarletMansion/ScarletMansion/GamePatch/Components/ScarletRadio.cs @@ -0,0 +1,122 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Unity.Netcode; +using UnityEngine; + +namespace ScarletMansion.GamePatch.Components { + public class ScarletRadio : NetworkBehaviour{ + + [Header("Networked Values")] + public int volume; + public bool playing; + public int audioIndex; + + [Header("Songs")] + public AudioClip[] audioClips; + + [Header("References")] + public AudioSource audioSource; + public float maxVolume = 1f; + public Transform onOffSwitchTransform; + public Transform volumeSwitchTransform; + public Transform volumeDialTransform; + public Transform tuneSwitchTransform; + private float onOffSwitchTransformX; + private float volumeSwitchTransformX; + private float volumeDialTransformX; + private float onOffSwitchTransforX; + + [Header("Switch Values")] + public Vector2 onOffSwitchRotation; + public Vector2 volumeSwitchRotation; + public Vector2 volumeDialRotation; + public Vector2 tuneSwitchRotation; + + void Start() { + audioSource.volume = maxVolume * (volume * 0.1f); + } + + void RotateTransformTo(Transform dial, ref float current, float towards){ + current = Mathf.Lerp(current, towards, Time.deltaTime * 2f); + var v = new Vector3(current, 0f, 0f); + dial.localEulerAngles = v; + } + + void RotateTransformTo(Transform dial, ref float current, Vector2 lerpVector, float lerp){ + RotateTransformTo(dial, ref current, Mathf.Lerp(lerpVector.x, lerpVector.y, lerp)); + } + + void Update(){ + RotateTransformTo(onOffSwitchTransform, ref onOffSwitchTransformX, playing ? onOffSwitchRotation.y : onOffSwitchRotation.x); + RotateTransformTo(volumeSwitchTransform, ref volumeSwitchTransformX, volumeSwitchRotation, volume * 0.1f); + RotateTransformTo(volumeDialTransform, ref volumeDialTransformX, volumeDialRotation, volume * 0.1f); + RotateTransformTo(tuneSwitchTransform, ref onOffSwitchTransforX, tuneSwitchRotation, (float)audioIndex / (audioClips.Length - 1)); + } + + public void ToggleOnOffSwitch(){ + ToggleOnOffSwitchServerRpc(); + } + + public void ToggleVolumeSwitchLeft() { + ToggleVolumeSwitchServerRpc(-1); + } + + public void ToggleVolumeSwitchRight() { + ToggleVolumeSwitchServerRpc(1); + } + + public void ToggleSongSwitch(){ + ToggleSongSwitchServerRpc(); + } + + [ServerRpc(RequireOwnership = false)] + public void ToggleOnOffSwitchServerRpc(){ + ToggleOnOffSwitchClientRpc(!playing); + } + + [ClientRpc] + public void ToggleOnOffSwitchClientRpc(bool playing){ + this.playing = playing; + if (playing) AttemptTurnOn(); + else AttemptTurnOff(); + + } + + [ServerRpc(RequireOwnership = false)] + public void ToggleVolumeSwitchServerRpc(int count){ + ToggleVolumeSwitchClientRpc(Mathf.Clamp(volume + count, 0, 10)); + } + + [ClientRpc] + public void ToggleVolumeSwitchClientRpc(int volume){ + this.volume = volume; + audioSource.volume = maxVolume * (volume * 0.1f); + } + + [ServerRpc(RequireOwnership = false)] + public void ToggleSongSwitchServerRpc(){ + ToggleSongSwitchClientRpc((audioIndex + 1) % audioClips.Length); + } + + [ClientRpc] + public void ToggleSongSwitchClientRpc(int audioIndex){ + this.audioIndex = audioIndex; + + if (playing && audioSource.isPlaying) audioSource.Stop(); + audioSource.clip = audioClips[audioIndex]; + AttemptTurnOn(); + } + + public void AttemptTurnOff(){ + if (!playing && audioSource.isPlaying) audioSource.Stop(); + } + + public void AttemptTurnOn(){ + if (playing && !audioSource.isPlaying) audioSource.Play(); + } + + } +} diff --git a/ScarletMansion/ScarletMansion/GamePatch/Components/ScarletYukariTrigger.cs b/ScarletMansion/ScarletMansion/GamePatch/Components/ScarletYukariTrigger.cs index c733485..8e7c539 100644 --- a/ScarletMansion/ScarletMansion/GamePatch/Components/ScarletYukariTrigger.cs +++ b/ScarletMansion/ScarletMansion/GamePatch/Components/ScarletYukariTrigger.cs @@ -29,7 +29,27 @@ namespace ScarletMansion.GamePatch.Components if (audioClipIndex == -1) comp.statusEffectAudioIndex = 0; comp.statusEffectAudioIndex = audioClipIndex; - if (comp.isSinking) return; + if (comp.isSinking) { + // teleporting them out for a second time in life + // won't be easy though kek + var scarletPlayer = ScarletPlayerControllerB.GetScarletPlayerScript(comp); + if (scarletPlayer != null && !scarletPlayer.fellInPit && comp.sinkingValue >= 0.9f && comp.health > 20) { + var selfPos = scarletPlayer.transform.position; + var farthestAINode = RoundManager.Instance.insideAINodes + .Select(n => n.transform.position) + .OrderByDescending(n => (selfPos - n).magnitude).FirstOrDefault(); + + comp.TeleportPlayer(farthestAINode); + var damage = ScarletNetworkManagerUtility.GetCriticalDamageToPlayer(comp, false); + comp.DamagePlayer(damage, false, true, CauseOfDeath.Suffocation); + + ScarletNetworkManager.Instance.CreateSpawnAudioPrefab(farthestAINode, comp.actualClientId); + StopSinkingLocalPlayer(comp); + + scarletPlayer.fellInPit = true; + } + return; + } if (sinkingLocalPlayer){ if (!comp.CheckConditionsForSinkingInQuicksand()) { diff --git a/ScarletMansion/ScarletMansion/GamePatch/Components/TreasureRoom/TreasureRoomTimedOpen.cs b/ScarletMansion/ScarletMansion/GamePatch/Components/TreasureRoom/TreasureRoomTimedOpen.cs new file mode 100644 index 0000000..98dc77f --- /dev/null +++ b/ScarletMansion/ScarletMansion/GamePatch/Components/TreasureRoom/TreasureRoomTimedOpen.cs @@ -0,0 +1,74 @@ +using DunGen; +using ScarletMansion.GamePatch.Managers; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using TMPro; +using UnityEngine; + +namespace ScarletMansion.GamePatch.Components.TreasureRoom { + public class TreasureRoomTimedOpen : MonoBehaviour, IDungeonCompleteReceiver { + + [Header("References")] + public GameObject timeGameObject; + public TextMeshPro timeTextMesh; + + [Header("Values")] + public Vector2Int hourRange; + public bool opened; + private int hourSelected; + private int mintuesSelected; + + private ScarletDoor treasureDoorLock; + + public void Update(){ + if (treasureDoorLock == null) return; + if (!StartOfRound.Instance.IsHost || opened) return; + + var time = Utility.GetTime(); + if (time.hours > hourSelected || (time.hours >= hourSelected && time.minutes >= mintuesSelected)) { + treasureDoorLock.LockDoorOverrideClientRpc(false); + opened = true; + + Plugin.logger.LogInfo($"Opening cause {time.hours}:{time.minutes} > {hourSelected}:{mintuesSelected}"); + } + } + + public void OnDungeonComplete(Dungeon dungeon) { + AngerManager.Instance.AddRoomOfInterest(transform); + + if (!StartOfRound.Instance.IsHost) return; + + var tile = GetComponentInParent(); + var doorways = tile.UsedDoorways; + foreach(var d in doorways) { + var neighboorTile = d.ConnectedDoorway.Tile.gameObject.name.ToLowerInvariant(); + //Plugin.logger.LogInfo(neighboorTile); + if (neighboorTile.Contains("treasure")){ + StartCoroutine(BeginTreasureRoomProcess(d)); + return; + } + } + } + + public IEnumerator BeginTreasureRoomProcess(Doorway doorway){ + yield return new WaitForSecondsRealtime(4f); + + Plugin.logger.LogInfo("Setting up lock for treasure room"); + + treasureDoorLock = AngerManager.Instance.GetScarletDoor(doorway.transform.position); + treasureDoorLock.LockDoorOverrideClientRpc(true); + + hourSelected = UnityEngine.Random.Range(hourRange.x, hourRange.y); + mintuesSelected = UnityEngine.Random.Range(0, 3) * 15; + + timeGameObject.SetActive(true); + timeTextMesh.text = $"{hourSelected}:{mintuesSelected}"; + + Plugin.logger.LogInfo($"Opening at {hourSelected}:{mintuesSelected}"); + } + } +} diff --git a/ScarletMansion/ScarletMansion/GamePatch/Enemies/KnightGhostVariant.cs b/ScarletMansion/ScarletMansion/GamePatch/Enemies/KnightGhostVariant.cs new file mode 100644 index 0000000..8496420 --- /dev/null +++ b/ScarletMansion/ScarletMansion/GamePatch/Enemies/KnightGhostVariant.cs @@ -0,0 +1,165 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; +using Unity.Netcode; +using UnityEngine.AI; +using GameNetcodeStuff; +using ScarletMansion.GamePatch.Components; + +namespace ScarletMansion { + + public class KnightGhostVariant : EnemyAI { + + public float maxChaseSpeed = 14.5f; + public float slowChaseSpeed = 6f; + private float currentAnimSpeed = 1f; + + public Collider mainCollider; + + public MeshRenderer[] knightMeshRenderers; + + public AudioClip[] ramAudioClips; + + public override void Start(){ + base.Start(); + + if (IsOwner && KnightSpawnManager.Instance) { + var index = KnightSpawnManager.Instance.GetSpawnPointIndex(); + if (index == -1) return; + + SyncKnightReplacementClientRpc(index); + } + } + + public override void DoAIInterval() { + base.DoAIInterval(); + + movingTowardsTargetPlayer = true; + + if (targetPlayer == null || !targetPlayer.IsOwner) return; + if (isEnemyDead) return; + + var targetOutOfMap = !PlayerIsTargetable(targetPlayer); + if (targetOutOfMap){ + CallDisappear(); + return; + } + + var targetLookingAtMe = !Physics.Linecast(transform.position + Vector3.up * 0.5f, targetPlayer.gameplayCamera.transform.position, StartOfRound.Instance.collidersAndRoomMaskAndDefault) && Vector3.Distance(base.transform.position, targetPlayer.transform.position) < 30f; + var newBehaviourState = targetLookingAtMe ? 1 : 0; + if (newBehaviourState != currentBehaviourStateIndex) { + SwitchToBehaviourState(newBehaviourState); + } + + } + + public override void Update() { + base.Update(); + if (isEnemyDead) return; + + var trueSpeed = currentBehaviourStateIndex == 0 ? maxChaseSpeed : slowChaseSpeed; + if (IsOwner) { + agent.speed = Mathf.MoveTowards(agent.speed, trueSpeed, 4.5f * Time.deltaTime); + } + + currentAnimSpeed = Mathf.Lerp(currentAnimSpeed, trueSpeed * 0.4597f, 4f * Time.deltaTime); + creatureAnimator.SetFloat("walkSpeed", currentAnimSpeed); + } + + public override void OnCollideWithPlayer(Collider other) { + base.OnCollideWithPlayer(other); + + var playerControllerB = MeetsStandardPlayerCollisionConditions(other, false, false); + if (playerControllerB != null && playerControllerB.IsOwner && playerControllerB == targetPlayer) { + var damage = ScarletNetworkManagerUtility.GetCriticalDamageToPlayer(playerControllerB, false); + playerControllerB.DamagePlayer(damage, true, true, CauseOfDeath.Mauling, 1, false, default(Vector3)); + playerControllerB.JumpToFearLevel(1f, true); + + RoundManager.PlayRandomClip(creatureVoice, ramAudioClips, false, 1f, 0); + + CallDisappear(); + } + } + + [ClientRpc] + public void SyncKnightReplacementClientRpc(int index){ + Plugin.logger.LogInfo($"Spawning ghost knight at {index}"); + + try { + var target = KnightSpawnManager.Instance.GetSpawnPointTransform(index); + target.gameObject.SetActive(false); + + transform.position = target.position; + transform.rotation = target.rotation; + serverPosition = target.position; + + if (agent == null) agent = GetComponentInChildren(); + agent.Warp(target.position); + + if (IsOwner) { + SyncPositionToClients(); + } + } catch (Exception e){ + Plugin.logger.LogError($"Tried to ghost knight spawn at {index}, but completely failed"); + Plugin.logger.LogError(e); + } + } + + + public void FindAndTunnelPlayer(Vector3 searchPosition){ + var validPlayers = StartOfRound.Instance.allPlayerScripts.Where(p => p != null && PlayerIsTargetable(p)); + if (validPlayers.Count() == 0) { + Plugin.logger.LogWarning("Could not find valid target to tunnel"); + return; + } + + var closestPlayer = validPlayers + .OrderBy(p => Vector3.SqrMagnitude(p.transform.position - searchPosition)) + .FirstOrDefault(); + + if (closestPlayer != null) { + ChangeOwnershipOfEnemy(closestPlayer.actualClientId); + TunnelPlayerClientRpc(closestPlayer); + } + } + + [ClientRpc] + public void TunnelPlayerClientRpc(NetworkBehaviourReference playerRef){ + if (playerRef.TryGet(out var player)){ + targetPlayer = player; + Plugin.logger.LogInfo($"Targeting {player.playerUsername} for death"); + + if (targetPlayer.IsOwner) return; + + // other clients will only see eyes of death + foreach(var m in knightMeshRenderers) { + m.enabled = false; + } + } else { + Plugin.logger.LogWarning("Could not find target player through reference"); + } + } + + private bool calledDisappear = false; + public void CallDisappear(){ + if (calledDisappear) return; + + Plugin.logger.LogInfo("Killing ghost knight"); + + calledDisappear = true; + mainCollider.enabled = false; + mainCollider.gameObject.SetActive(false); + + ScarletNetworkManager.Instance.CreateSpawnAudioPrefab(transform.position, targetPlayer.actualClientId); + DisappearServerRpc(); + } + + [ServerRpc(RequireOwnership = false)] + public void DisappearServerRpc(){ + KillEnemy(true); + } + } +} diff --git a/ScarletMansion/ScarletMansion/GamePatch/Enemies/MaidVariant.cs b/ScarletMansion/ScarletMansion/GamePatch/Enemies/MaidVariant.cs index b29c274..aa83c41 100644 --- a/ScarletMansion/ScarletMansion/GamePatch/Enemies/MaidVariant.cs +++ b/ScarletMansion/ScarletMansion/GamePatch/Enemies/MaidVariant.cs @@ -185,6 +185,8 @@ namespace ScarletMansion.GamePatch.Enemies { public Transform knifeRenderTransform; + public EnemyType knightGhostEnemy; + public AudioSource chaseMusicStart; // Token: 0x04000111 RID: 273 @@ -265,6 +267,9 @@ namespace ScarletMansion.GamePatch.Enemies { knifeRender.SetActive(false); if (IsServer) { + var enemy = ScarletNetworkManagerUtility.CreateEnemyWithType(knightGhostEnemy, transform.position, 0f); + enemy.FindAndTunnelPlayer(transform.position); + var newKnife = Object.Instantiate(knifePrefab, base.transform.position + Vector3.up * 0.5f, Quaternion.identity, RoundManager.Instance.spawnedScrapContainer); newKnife.GetComponent().Spawn(); newKnife.GetComponent().LinkKnifeToMaidServerRpc(this); diff --git a/ScarletMansion/ScarletMansion/GamePatch/InitPatch.cs b/ScarletMansion/ScarletMansion/GamePatch/InitPatch.cs index 76a1444..c6ff3a8 100644 --- a/ScarletMansion/ScarletMansion/GamePatch/InitPatch.cs +++ b/ScarletMansion/ScarletMansion/GamePatch/InitPatch.cs @@ -48,19 +48,12 @@ namespace ScarletMansion.GamePatch { [HarmonyPrefix] public static void StartOfRound_Start(ref StartOfRound __instance) { ScarletYukariTrigger.audioClipIndex = -1; - PlayerAnimatorStateHelper.ClearAnimators(); + ScarletPlayerControllerB.InitializeScarletScripts(); __instance.StartCoroutine(WaitForNetworkObject(__instance, CreateNetworkManager)); - /* - foreach(var p in __instance.levels){ - var totalScrap = p.spawnableScrap.Sum(s => s.rarity); - var totalEnemy = p.Enemies.Sum(s => s.rarity); - Plugin.logger.LogInfo($"{p.PlanetName}: S{totalScrap}, E{totalEnemy}"); - }*/ - // safety cleaning - DunGenPatch.Patch.Deactivate(); + DunGenPatch.Patch.Deactivate(true); //ScarletLightingManager.Clean(); FixMapReferences(__instance); @@ -72,28 +65,12 @@ namespace ScarletMansion.GamePatch { statusEffectClips.Add(Assets.networkObjectList.sinkingAudioClip); __instance.statusEffectClips = statusEffectClips.ToArray(); - // DunGenAnalyis.Analysis(Assets.dungeon, __instance, RoundManager.Instance); } [HarmonyPatch(typeof(RoundManager), "Awake")] [HarmonyPrefix] public static void RoundManagerAwakePatch(ref RoundManager __instance) { FixDungeonPrefabValues(__instance); - - /* - foreach(var d in __instance.dungeonFlowTypes) { - Plugin.logger.LogInfo("--------"); - Plugin.logger.LogInfo($"{d.name}: {d.Length.ToString()}"); - Plugin.logger.LogInfo($"{d.BranchMode}: {d.BranchCount.ToString()}"); - foreach(var l in d.Lines){ - Plugin.logger.LogInfo($" {l.Position}, {l.Length}"); - foreach(var a in l.DungeonArchetypes){ - Plugin.logger.LogInfo($" {a.BranchCount.ToString()}, {a.BranchingDepth.ToString()}"); - } - } - Plugin.logger.LogInfo("--------\n"); - } - */ } [HarmonyPatch(typeof(RoundManager), "Start")] @@ -110,24 +87,6 @@ namespace ScarletMansion.GamePatch { return true; } - private static void FixParticleSystemMaterial(ParticleSystemRenderer toFixParticleSystem, ParticleSystemRenderer copyParticleSystem) { - toFixParticleSystem.sharedMaterial = copyParticleSystem.sharedMaterial; - } - - private static void FixParticleSystemMaterial(ParticleSystem toFixParticleSystem, ParticleSystem copyParticleSystem) { - FixParticleSystemMaterial(toFixParticleSystem.GetComponent(), copyParticleSystem.GetComponent()); - } - - private static void FixParticleSystemMaterialAndChildren(ParticleSystem toFixParticleSystem, ParticleSystem copyParticleSystem) { - FixParticleSystemMaterial(toFixParticleSystem, copyParticleSystem); - - for(var i = 0; i < toFixParticleSystem.transform.childCount && i < copyParticleSystem.transform.childCount; ++i) { - var child0 = toFixParticleSystem.transform.GetChild(i).GetComponent(); - var child1 = copyParticleSystem.transform.GetChild(i).GetComponent(); - FixParticleSystemMaterial(child0, child1); - } - } - public static void FixMapReferences(StartOfRound round){ try { @@ -188,7 +147,7 @@ namespace ScarletMansion.GamePatch { var butlerPrefab = butlerItem.enemyType.enemyPrefab; var butlerScript = butlerPrefab.GetComponent(); - FixParticleSystemMaterialAndChildren(maidScript.stabBloodParticle, butlerScript.stabBloodParticle); + Utility.FixParticleSystemMaterialAndChildren(maidScript.stabBloodParticle, butlerScript.stabBloodParticle); LethalLib.Modules.Enemies.RegisterEnemy(type, 0, Levels.LevelTypes.None, maid.terminalNode, maid.terminalKeyword); } @@ -300,8 +259,8 @@ namespace ScarletMansion.GamePatch { scarletScript.hitSFX = knifeScript.hitSFX; scarletScript.swingSFX = knifeScript.swingSFX; - FixParticleSystemMaterialAndChildren(scarletScript.bloodParticle, knifeScript.bloodParticle); - FixParticleSystemMaterial(scarletScript.buffedParticleSystem, knifeScript.bloodParticle); + Utility.FixParticleSystemMaterialAndChildren(scarletScript.bloodParticle, knifeScript.bloodParticle); + Utility.FixParticleSystemMaterial(scarletScript.buffedParticleSystem, knifeScript.bloodParticle); } if (Assets.flashlight.item == null) { @@ -347,12 +306,6 @@ namespace ScarletMansion.GamePatch { var prefabs = networkmanager.NetworkConfig.Prefabs.Prefabs; var prefabFixList = Assets.networkObjectList.toFixGameObjects; - //foreach(var p in prefabs){ - // var hasInteract = p.Prefab.GetComponentInChildren(); - // var interStr = hasInteract ? "YES" : ""; - // Plugin.logger.LogInfo($"{p.Prefab.name}: {interStr}"); - //} - var steeldoor = prefabs.FirstOrDefault(p => p.Prefab.name.ToLowerInvariant() == "fancydoormapmodel"); if (GameReadNullCheck(steeldoor, "FancyDoorMapModel", "SDM doors will have missing icons and sounds")){ var interact = steeldoor.Prefab.GetComponentInChildren(); @@ -404,61 +357,19 @@ namespace ScarletMansion.GamePatch { } - private static IEnumerator UpdateNetworkConfig(RoundManager roundManager){ while(PluginConfig.Synced == false){ yield return null; } - - /* - var list = ExtendedDungeonMapLoad.GetCustomMoons(PluginConfig.Instance.customMapsValue, PluginConfig.Instance.customMapDefaultWeightValue); - ExtendedDungeonMapLoad.ClearLastCustomMoonEntryList(); - - // overriding with dis - if (list.Count > 0){ - Plugin.logger.LogInfo("Overring default snow moons. Loading with custom moon list"); - ExtendedDungeonMapLoad.AddToExtendedDungeonFlow(list); - } - - else { - Plugin.logger.LogInfo("Loading SDM to default snow moons"); - - Assets.dineEntry.SetRarity(PluginConfig.Instance.dungeonSnowWeightValue); - Assets.rendEntry.SetRarity(PluginConfig.Instance.dungeonSnowWeightValue); - Assets.titanEntry.SetRarity(PluginConfig.Instance.dungeonTitanWeightValue); - - var dun = Assets.dungeonExtended; - Assets.dineEntry.Add(dun); - Assets.rendEntry.Add(dun); - Assets.titanEntry.Add(dun); - } - */ Lights.ScarletLightCleanup.weights = new float[] { PluginConfig.Instance.lightsSpawnZeroWeightValue, PluginConfig.Instance.lightsSpawnOneWeightValue, PluginConfig.Instance.lightsSpawnTwoWeightValue - //PluginConfig.Instance.lightsSpawnThreeWeightValue }; - /* - foreach(var item in Assets.items){ - item.UpdateStringWithRarity(); - } - // hack - foreach(var level in PatchedContent.ExtendedLevels) { - Plugin.logger.LogInfo($"{level.name}: {level.AuthorName}"); - var hackCall = typeof(ItemManager).GetMethod("InjectCustomItemsIntoLevelViaDynamicRarity", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic); - hackCall.Invoke(null, new object[] { level, true } ); - } - */ - - //Assets.dungeonExtended.DynamicDungeonSizeMinMax = new Vector2(PluginConfig.Instance.dunGenMultiplierValue.min, PluginConfig.Instance.dunGenMultiplierValue.max); Assets.dungeon.Length = PluginConfig.Instance.mainPathLengthValue.GetDungenIntRange(); - var mayorTileSet = PluginConfig.Instance.disableBasementValue ? Assets.networkObjectList.mayorVanillaTileset : Assets.networkObjectList.mayorRegularTileset; - Assets.dungeon.Nodes[1].TileSets = new List() { mayorTileSet }; - DungeonFlow.GlobalPropSettings GetGlobalPropSetting(int id) { foreach(var p in Assets.dungeon.GlobalProps){ if (p.ID == id ) return p; @@ -474,19 +385,5 @@ namespace ScarletMansion.GamePatch { Plugin.logger.LogInfo("Set networked config values"); } - public static void UpdateTileWeightDebug(string tile, float multiplier){ - var tilesets = Assets.dungeon.GetUsedTileSets(); - foreach(var s in tilesets){ - foreach(var t in s.TileWeights.Weights){ - var n = t.Value.name; - if (n.Contains(tile)) { - Plugin.logger.LogInfo($"{t.Value.name} weight being multiplied by {multiplier}"); - t.MainPathWeight *= multiplier; - t.BranchPathWeight *= multiplier; - } - } - } - } - } } diff --git a/ScarletMansion/ScarletMansion/GamePatch/Items/PlayerAnimatorStateHelper.cs b/ScarletMansion/ScarletMansion/GamePatch/Items/PlayerAnimatorStateHelper.cs deleted file mode 100644 index 231eef2..0000000 --- a/ScarletMansion/ScarletMansion/GamePatch/Items/PlayerAnimatorStateHelper.cs +++ /dev/null @@ -1,124 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using UnityEngine; - -namespace ScarletMansion.GamePatch.Items { - - public class PlayerAnimatorStateHelper { - private Animator animator; - private AnimatorStateInfo currentStateInfo; - private float currentAnimationTime; - private bool isCrouching; - private bool isJumping; - private bool isWalking; - private bool isSprinting; - private RuntimeAnimatorController originalAnimatorController; - - public PlayerAnimatorStateHelper(Animator animator) { - this.animator = animator; - this.originalAnimatorController = animator.runtimeAnimatorController; - } - - private static Dictionary animatorStateHelpers; - - public static PlayerAnimatorStateHelper TryAddAnimator(ulong id, Animator animator){ - if (!animatorStateHelpers.TryGetValue(id, out var v)) { - v = new PlayerAnimatorStateHelper(animator); - animatorStateHelpers.Add(id, v); - } - return v; - } - - public static void ClearAnimators(){ - animatorStateHelpers = new Dictionary(); - } - - //We need to Save the important states due to how unity handles switching animator overrides (So stupid) - public void SaveAnimatorStates() { - if (animator != null) { - isCrouching = animator.GetBool("crouching"); - isJumping = animator.GetBool("Jumping"); - isWalking = animator.GetBool("Walking"); - isSprinting = animator.GetBool("Sprinting"); - currentStateInfo = animator.GetCurrentAnimatorStateInfo(0); - currentAnimationTime = currentStateInfo.normalizedTime; - - //Debug.Log("Saved Animator States - Crouching: " + isCrouching + - // ", Jumping: " + isJumping + - // ", Walking: " + isWalking + - // ", Sprinting: " + isSprinting + - // ", State: " + currentStateInfo.fullPathHash + - // ", Time: " + currentAnimationTime); - } - } - - //We need to Restore the important states due to how unity handles switching animator overrides - public void RestoreAnimatorStates() { - if (animator != null) { - animator.Play(currentStateInfo.fullPathHash, 0, currentAnimationTime); - animator.SetBool("crouching", isCrouching); - animator.SetBool("Jumping", isJumping); - animator.SetBool("Walking", isWalking); - animator.SetBool("Sprinting", isSprinting); - - //Debug.Log("Restored Animator States - Crouching: " + isCrouching + - // ", Jumping: " + isJumping + - // ", Walking: " + isWalking + - // ", Sprinting: " + isSprinting + - // ", State: " + currentStateInfo.fullPathHash + - // ", Time: " + currentAnimationTime); - } - } - - public void RestoreOriginalAnimatorController() { - if (animator != null) { - animator.runtimeAnimatorController = originalAnimatorController; - RestoreAnimatorStates(); - } - } - - public class AnimationClipOverrides : List> { - public AnimationClipOverrides(int capacity) : base(capacity) {} - - public AnimationClip this[string name] { - get => this.Find(x => x.Key.name.Equals(name)).Value; - set { - int index = this.FindIndex(x => x.Key.name.Equals(name)); - if (index != -1) this[index] = new KeyValuePair(this[index].Key, value); - } - } - - public override string ToString() { - var items = this.Select(d => { - var keyValue = d.Key ? d.Key.name : "NULL"; - var vValue = d.Value ? d.Value.name : "NULL"; - return $"{keyValue}: {vValue}"; - }); - return string.Join(", ", items); - } - } - - public void SetAnimatorOverrideController(AnimatorOverrideController overrideController, string originalAnimationClipName, AnimationClip overrideAnimationClip) { - if (animator != null) { - overrideController.runtimeAnimatorController = originalAnimatorController; - - var clipOverrides = new AnimationClipOverrides(overrideController.overridesCount); - overrideController.GetOverrides(clipOverrides); - clipOverrides[originalAnimationClipName] = overrideAnimationClip; - overrideController.ApplyOverrides(clipOverrides); - - animator.runtimeAnimatorController = overrideController; - RestoreAnimatorStates(); - } - } - - public RuntimeAnimatorController GetOriginalAnimatorController() { - return originalAnimatorController; - } - } - - -} diff --git a/ScarletMansion/ScarletMansion/GamePatch/Items/ScarletKnife.cs b/ScarletMansion/ScarletMansion/GamePatch/Items/ScarletKnife.cs index 15298d6..5b71442 100644 --- a/ScarletMansion/ScarletMansion/GamePatch/Items/ScarletKnife.cs +++ b/ScarletMansion/ScarletMansion/GamePatch/Items/ScarletKnife.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Linq; using GameNetcodeStuff; using OdinSerializer; +using ScarletMansion.GamePatch.Components; using ScarletMansion.GamePatch.Enemies; using Unity.Netcode; using UnityEngine; @@ -119,9 +120,20 @@ namespace ScarletMansion.GamePatch.Items // buff if (buffed) { + IHittable target; + int damage; + // prevent the player from one-shotting their friends - var target = component is PlayerControllerB ? previousPlayerHeldBy as IHittable : component; - target.Hit(50, forward, previousPlayerHeldBy, playHitSFX: true); + var targetPlayer = component as PlayerControllerB; + if (targetPlayer != null) { + target = previousPlayerHeldBy; + damage = GetDamageToPlayer(previousPlayerHeldBy); + } else { + target = component; + damage = 40; + } + + target.Hit(damage, forward, previousPlayerHeldBy, playHitSFX: true); UnBuffShovelServerRpc(); } // normal knife @@ -152,6 +164,15 @@ namespace ScarletMansion.GamePatch.Items } } + public int GetDamageToPlayer(PlayerControllerB player) { + var scarletPlayer = ScarletPlayerControllerB.GetScarletPlayerScript(player); + if (scarletPlayer == null) return 85; + + var forceKill = scarletPlayer.stabbedSelf; + scarletPlayer.stabbedSelf = true; + return ScarletNetworkManagerUtility.GetCriticalDamageToPlayer(player, forceKill); + } + [ServerRpc] public void HitShovelServerRpc(int hitSurfaceID) { HitShovelClientRpc(hitSurfaceID); @@ -187,9 +208,8 @@ namespace ScarletMansion.GamePatch.Items player.activatingItem = true; yield return new WaitForSeconds(0.25f); - var dmg = PluginConfig.Instance.maidKnifeSelfDamageValue; - var realDmg = Mathf.Max(dmg, Mathf.RoundToInt(player.health * (dmg / 100f))); - player.DamagePlayer(realDmg, true, true, CauseOfDeath.Stabbing); + var damage = GetDamageToPlayer(player); + player.DamagePlayer(damage, true, true, CauseOfDeath.Stabbing); bloodParticle.Play(withChildren: true); RoundManager.PlayRandomClip(knifeAudio, hitSFX); diff --git a/ScarletMansion/ScarletMansion/GamePatch/Items/ScarletSnowGlobe.cs b/ScarletMansion/ScarletMansion/GamePatch/Items/ScarletSnowGlobe.cs index 7f5ebda..4691cee 100644 --- a/ScarletMansion/ScarletMansion/GamePatch/Items/ScarletSnowGlobe.cs +++ b/ScarletMansion/ScarletMansion/GamePatch/Items/ScarletSnowGlobe.cs @@ -1,4 +1,5 @@ using GameNetcodeStuff; +using ScarletMansion.GamePatch.Components; using System; using System.Collections; using System.Collections.Generic; @@ -19,10 +20,9 @@ namespace ScarletMansion.GamePatch.Items { public AudioSource musicAS; [Header("Extra")] + public PlayerControllerB previouslyHeldBy; public Transform prefabPivot; public ScanNodeProperties scanNode; - public AnimatorOverrideController SnowGlobeOverride; - public string SnowGlobeOriginalHoldClipName; public AnimationClip SnowGlobeOverrideHoldClip; [System.Serializable] @@ -61,51 +61,45 @@ namespace ScarletMansion.GamePatch.Items { scanNode.headerText = $"{currentType.name} Snow Globe"; } - private PlayerAnimatorStateHelper GetAnimator(PlayerControllerB player) { - if (player != null && player.playerBodyAnimator != null) { - return PlayerAnimatorStateHelper.TryAddAnimator(player.actualClientId, player.playerBodyAnimator); - } - return null; + public override void GrabItem() { + base.GrabItem(); + previouslyHeldBy = playerHeldBy; + ReplaceOrPutBackAnimationClip(previouslyHeldBy, true); } public override void EquipItem() { base.EquipItem(); - - var animator = GetAnimator(playerHeldBy); - if (animator != null) { - animator.SaveAnimatorStates(); - animator.SetAnimatorOverrideController(SnowGlobeOverride, SnowGlobeOriginalHoldClipName, SnowGlobeOverrideHoldClip); - Plugin.logger.LogInfo("Animator override set for player: " + playerHeldBy.playerBodyAnimator.gameObject.name); - } - - // Coming from pocketing since this is also called when using inventory + previouslyHeldBy = playerHeldBy; + ReplaceOrPutBackAnimationClip(previouslyHeldBy, true); ToggleParticleRenderer(true); } public override void PocketItem() { - var animator = GetAnimator(playerHeldBy); - if (animator != null) { - animator.SaveAnimatorStates(); - animator.RestoreOriginalAnimatorController(); - Plugin.logger.LogInfo("Animator restored for player: " + playerHeldBy.playerBodyAnimator.gameObject.name); - } base.PocketItem(); - - // Disable Particles renderer + if (previouslyHeldBy != null) { + ReplaceOrPutBackAnimationClip(previouslyHeldBy, false); + } ToggleParticleRenderer(false); } public override void DiscardItem() { - var animator = GetAnimator(playerHeldBy); - if (animator != null) { - animator.SaveAnimatorStates(); - animator.RestoreOriginalAnimatorController(); - Plugin.logger.LogInfo("Animator restored for player: " + playerHeldBy.playerBodyAnimator.gameObject.name); + if (previouslyHeldBy != null) { + ReplaceOrPutBackAnimationClip(previouslyHeldBy, false); } - base.DiscardItem(); } + public void ReplaceOrPutBackAnimationClip(PlayerControllerB player, bool _override) { + if (player == null) return; + + var playerOverrideController = ScarletPlayerControllerB.GetScarletPlayerScript(player).playerOverrideController; + if (playerOverrideController == null) return; + + if (_override) playerOverrideController["HoldClipboard"] = SnowGlobeOverrideHoldClip; + else playerOverrideController["HoldClipboard"] = null; + } + + public override void ItemActivate(bool used, bool buttonDown = true) { base.ItemActivate(used, buttonDown); if (!activated) { diff --git a/ScarletMansion/ScarletMansion/GamePatch/LoadAssetsIntoLevelPatch.cs b/ScarletMansion/ScarletMansion/GamePatch/LoadAssetsIntoLevelPatch.cs index 03cf86e..c7ad4c8 100644 --- a/ScarletMansion/ScarletMansion/GamePatch/LoadAssetsIntoLevelPatch.cs +++ b/ScarletMansion/ScarletMansion/GamePatch/LoadAssetsIntoLevelPatch.cs @@ -85,7 +85,12 @@ namespace ScarletMansion.GamePatch { return TranspilerUtilities.InjectMethod(instructions, itemsInjection, "SpawnScrapInLevel", 4); } - + [HarmonyTranspiler] + [HarmonyPatch(typeof(DunGenPlus.Patches.RoundManagerPatch), "waitForScrapToSpawnToSyncPatch")] + public static IEnumerable waitForScrapToSpawnToSyncPatch(IEnumerable instructions){ + return TranspilerUtilities.InjectMethod(instructions, itemsInjection, "waitForScrapToSpawnToSyncPatch", 1); + } + public static List lastEnemiesRarity; public static List currentEnemiesRarity; diff --git a/ScarletMansion/ScarletMansion/GamePatch/Managers/AngerManager.cs b/ScarletMansion/ScarletMansion/GamePatch/Managers/AngerManager.cs index 49d84c2..7ef5110 100644 --- a/ScarletMansion/ScarletMansion/GamePatch/Managers/AngerManager.cs +++ b/ScarletMansion/ScarletMansion/GamePatch/Managers/AngerManager.cs @@ -23,7 +23,10 @@ namespace ScarletMansion.GamePatch.Managers { //public Dictionary angeredEnemies; public int level; + + public List roomsOfInterest; public List bedrooms; + public List doors; public List lights; @@ -32,6 +35,8 @@ namespace ScarletMansion.GamePatch.Managers { void Awake(){ Instance = this; + + roomsOfInterest = new List(); bedrooms = new List(); doors = new List(); lights = new List(); @@ -91,10 +96,14 @@ namespace ScarletMansion.GamePatch.Managers { bedrooms.Add(b); } + public void AddRoomOfInterest(Transform t) { + roomsOfInterest.Add(t); + } + public void AddDoor(ScarletDoor d){ // I want to get only doors that are revelant - foreach(var b in bedrooms){ - var dist = Vector3.SqrMagnitude(d.transform.position - b.transform.position); + foreach(var t in roomsOfInterest){ + var dist = Vector3.SqrMagnitude(d.transform.position - t.position); if (dist < 16f * 16f){ doors.Add(d); return; diff --git a/ScarletMansion/ScarletMansion/GamePatch/Managers/DoorwayManager.cs b/ScarletMansion/ScarletMansion/GamePatch/Managers/DoorwayManager.cs deleted file mode 100644 index ba8f908..0000000 --- a/ScarletMansion/ScarletMansion/GamePatch/Managers/DoorwayManager.cs +++ /dev/null @@ -1,85 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using UnityEngine; -using DunGen; -using ScarletMansion.DunGenPatch.Doorways; -using Unity.AI.Navigation; -using UnityEngine.AI; -using DunGen.Adapters; - -namespace ScarletMansion.GamePatch.Managers { - public class DoorwayManager : MonoBehaviour { - - public static DoorwayManager Instance { get; private set; } - public static ActionList onMainEntranceTeleportSpawnedEvent = new ActionList("onMainEntranceTeleportSpawned"); - - public List doorwayCleanup; - - public void Awake(){ - Instance = this; - doorwayCleanup = new List(); - } - - /* - - private NavMeshSurface surface; - private GameObject meshGameObject; - private MeshFilter meshFilter; - - void Update(){ - if (surface == null){ - surface = FindObjectOfType(); - } - - if (surface != null){ - if (meshFilter == null){ - meshGameObject = new GameObject("Nav Mesh V"); - meshFilter = meshGameObject.AddComponent(); - - var renderer = meshGameObject.AddComponent(); - renderer.materials = new Material[1]; - renderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off; - } - - var mesh = new Mesh(); - var triangulation = NavMesh.CalculateTriangulation(); - mesh.SetVertices(triangulation.vertices); - mesh.SetIndices(triangulation.indices, MeshTopology.Triangles, 0); - - meshGameObject.transform.position = new Vector3(0f, 0.05f, 0f); - meshFilter.mesh = mesh; - } - } - */ - - - public void AddDoorwayCleanup(DoorwayCleanup dw){ - doorwayCleanup.Add(dw); - } - - public static void onMainEntranceTeleportSpawnedFunction(){ - if (Instance && DunGenPatch.Patch.active) { - var doorwayCleanups = Instance.doorwayCleanup; - foreach(var d in doorwayCleanups){ - d.SetBlockers(false); - d.Cleanup(); - } - - try{ - var dungeonGen = RoundManager.Instance.dungeonGenerator; - var navmesh = dungeonGen.transform.parent.GetComponentInChildren(); - navmesh.Run(dungeonGen.Generator); - Plugin.logger.LogInfo("Rebuild nav mesh"); - } catch (Exception e){ - Plugin.logger.LogError("Failed to rebuild nav mesh"); - Plugin.logger.LogError(e.ToString()); - } - - } - } - - } -} diff --git a/ScarletMansion/ScarletMansion/GamePatch/Managers/KnightSpawnManager.cs b/ScarletMansion/ScarletMansion/GamePatch/Managers/KnightSpawnManager.cs index 3097639..304503f 100644 --- a/ScarletMansion/ScarletMansion/GamePatch/Managers/KnightSpawnManager.cs +++ b/ScarletMansion/ScarletMansion/GamePatch/Managers/KnightSpawnManager.cs @@ -23,8 +23,6 @@ namespace ScarletMansion { } public void OnDungeonComplete(Dungeon dungeon) { - // IDK KNOW IF I CAN TRUST THIS TO BE THE SAME FOR ALL CLIENTS - // but probably var points = dungeon.GetComponentsInChildren(); spawnPoints = points.ToList(); for(var i = 0; i < spawnPoints.Count; ++i){ diff --git a/ScarletMansion/ScarletMansion/GamePatch/Managers/ScarletNetworkManager.cs b/ScarletMansion/ScarletMansion/GamePatch/Managers/ScarletNetworkManager.cs index 50418ab..e5897c8 100644 --- a/ScarletMansion/ScarletMansion/GamePatch/Managers/ScarletNetworkManager.cs +++ b/ScarletMansion/ScarletMansion/GamePatch/Managers/ScarletNetworkManager.cs @@ -10,6 +10,7 @@ using GameNetcodeStuff; using ScarletMansion.GamePatch.Items; using ScarletMansion.GamePatch; using ScarletMansion.GamePatch.Components; +using static LethalLevelLoader.ExtendedEvent; namespace ScarletMansion { @@ -301,16 +302,77 @@ namespace ScarletMansion { } + public void CreateSpawnAudioPrefab(Vector3 positon, ulong playerId) { + CreateSpawnAudioPrefabServerRpc(positon, playerId); + CreateSpawnAudioPrefab(positon); + } + + [ServerRpc(RequireOwnership = false)] + public void CreateSpawnAudioPrefabServerRpc(Vector3 position, ulong playerId){ + CreateSpawnAudioPrefabClientRpc(position, playerId); + } + + [ClientRpc] + public void CreateSpawnAudioPrefabClientRpc(Vector3 position, ulong playerId){ + if (StartOfRound.Instance.localPlayerController.actualClientId == playerId) return; + CreateSpawnAudioPrefab(position); + } + + private void CreateSpawnAudioPrefab(Vector3 position) { + var copy = Instantiate(Assets.networkObjectList.yukariSpawnPrefab, position, Quaternion.identity); + var audioSource = copy.GetComponentInChildren(); + audioSource.time = 0.5f; + Destroy(copy, 5f); + } + } public static class ScarletNetworkManagerUtility { + public static int GetCriticalDamageToPlayer(PlayerControllerB player, bool forceKill) { + if (player.health > 20 && !forceKill) { + return player.health - 15; + } + return player.health; + } + + public static int GetFlashlightId(FlashlightItem flashlightItem){ var flashlight = Assets.GetFlashlight(flashlightItem.itemProperties); if (flashlight != null) return flashlight.itemId; return -1; } + public static NetworkObjectReference CreateEnemyWithRef(EnemyReferenceSpawnLogic enemy, Vector3 position, float yRotation) { + var roundManager = RoundManager.Instance; + if (roundManager == null || !roundManager.IsHost) return default; + + return roundManager.SpawnEnemyGameObject(position, yRotation, enemy.index); + } + + public static T CreateEnemyWithRef(EnemyReferenceSpawnLogic enemy, Vector3 position, float yRotation) where T: EnemyAI { + var spawnedEnemy = CreateEnemyWithRef(enemy, position, yRotation); + if (spawnedEnemy.TryGet(out var obj)) { + return obj.GetComponentInChildren(); + } + return null; + } + + public static NetworkObjectReference CreateEnemyWithType(EnemyType enemy, Vector3 position, float yRotation) { + var roundManager = RoundManager.Instance; + if (roundManager == null || !roundManager.IsHost) return default; + + return roundManager.SpawnEnemyGameObject(position, yRotation, -1, enemy); + } + + public static T CreateEnemyWithType(EnemyType enemy, Vector3 position, float yRotation) where T: EnemyAI { + var spawnedEnemy = CreateEnemyWithType(enemy, position, yRotation); + if (spawnedEnemy.TryGet(out var obj)) { + return obj.GetComponentInChildren(); + } + return null; + } + public static bool CreateFlashlight(PlayerControllerB player, FlashlightItem flashLight, FlandreCrystal crystal){ var color = crystal.colorIndex; var position = crystal.transform.position + Vector3.up * 0.25f; diff --git a/ScarletMansion/ScarletMansion/GamePatch/PlayerControllerBPatch.cs b/ScarletMansion/ScarletMansion/GamePatch/PlayerControllerBPatch.cs index 6030179..5ad5ce5 100644 --- a/ScarletMansion/ScarletMansion/GamePatch/PlayerControllerBPatch.cs +++ b/ScarletMansion/ScarletMansion/GamePatch/PlayerControllerBPatch.cs @@ -14,14 +14,26 @@ namespace ScarletMansion.GamePatch { [HarmonyPatch(typeof(PlayerControllerB), "Awake")] [HarmonyPrefix] public static void AwakePatch(ref PlayerControllerB __instance){ - if (__instance.GetComponent() == null) { + var currentComp = __instance.GetComponent(); + if (currentComp == null) { Plugin.logger.LogInfo($"Adding Scarlet player script to player {__instance.playerClientId}"); var comp = __instance.gameObject.AddComponent(); comp.Initialize(__instance); + comp.Register(); } else { + currentComp.Register(); Plugin.logger.LogWarning($"Player {__instance.playerClientId} already has Scarlet player script. Skipping. YOU CAN PROBABLY IGNORE THIS!"); } } + public static void UpdatePatch(ref PlayerControllerB __instance) { + if (GameNetworkManager.Instance.localPlayerController == null) return; + var controller = ScarletPlayerControllerB.GetScarletPlayerScript(__instance); + if (controller != null) return; + controller.playerOverrideController = new AnimatorOverrideController(__instance.playerBodyAnimator.runtimeAnimatorController); + __instance.playerBodyAnimator.runtimeAnimatorController = controller.playerOverrideController; + + } + } } diff --git a/ScarletMansion/ScarletMansion/GamePatch/Props/LocalPropSingle.cs b/ScarletMansion/ScarletMansion/GamePatch/Props/LocalPropSingle.cs index 6f6e5dc..798f150 100644 --- a/ScarletMansion/ScarletMansion/GamePatch/Props/LocalPropSingle.cs +++ b/ScarletMansion/ScarletMansion/GamePatch/Props/LocalPropSingle.cs @@ -14,7 +14,7 @@ namespace ScarletMansion.GamePatch.Props { if (randomizePosition){ var x = (float)randomStream.NextDouble() * randomPositionRange; var z = (float)randomStream.NextDouble() * randomPositionRange; - transform.localPosition = new Vector3(x, 0f, z); + transform.localPosition += new Vector3(x, 0f, z); } if (randomizeRotation){ diff --git a/ScarletMansion/ScarletMansion/GamePatch/Props/SpawnSyncedObjectCycle.cs b/ScarletMansion/ScarletMansion/GamePatch/Props/SpawnSyncedObjectCycle.cs deleted file mode 100644 index e7cfc1c..0000000 --- a/ScarletMansion/ScarletMansion/GamePatch/Props/SpawnSyncedObjectCycle.cs +++ /dev/null @@ -1,49 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using UnityEngine; -using DunGen; - -namespace ScarletMansion.GamePatch.Props { - - public class SpawnSyncedObjectCycle : MonoBehaviour, IDungeonCompleteReceiver { - - public static int cycle; - public static Dictionary cycleDictionary; - - public SpawnSyncedObject spawn; - public int id; - public List props = new List(); - - void Reset(){ - spawn = GetComponent(); - } - - public static void UpdateCycle(int value){ - Plugin.logger.LogInfo($"Updating SpawnSyncedObject start cycle to {value}"); - cycle = value; - cycleDictionary = new Dictionary(); - } - - public int GetCycle(int id){ - if (!cycleDictionary.TryGetValue(id, out var value)){ - value = cycle; - cycleDictionary.Add(id, value); - } - - cycleDictionary[id] = value + 1; - Plugin.logger.LogInfo($"Cycle{id}: {value}"); - return value; - } - - public void OnDungeonComplete(Dungeon dungeon) { - var index = GetCycle(id) % props.Count; - var prefab = props[index]; - spawn.spawnPrefab = prefab; - } - } - - -} diff --git a/ScarletMansion/ScarletMansion/GamePatch/RoundManagerPatch.cs b/ScarletMansion/ScarletMansion/GamePatch/RoundManagerPatch.cs index 455a94b..b8f6b32 100644 --- a/ScarletMansion/ScarletMansion/GamePatch/RoundManagerPatch.cs +++ b/ScarletMansion/ScarletMansion/GamePatch/RoundManagerPatch.cs @@ -50,11 +50,5 @@ namespace ScarletMansion.GamePatch { return count * PluginConfig.Instance.mapHazardsMultiplierValue; } - [HarmonyPostfix] - [HarmonyPatch(typeof(RoundManager), "SetPowerOffAtStart")] - public static void SetPowerOffAtStartPatch(){ - DoorwayManager.onMainEntranceTeleportSpawnedEvent.Call(); - } - } } diff --git a/ScarletMansion/ScarletMansion/GamePatch/Weathers/SDMWeatherManager.cs b/ScarletMansion/ScarletMansion/GamePatch/Weathers/SDMWeatherManager.cs new file mode 100644 index 0000000..06913ce --- /dev/null +++ b/ScarletMansion/ScarletMansion/GamePatch/Weathers/SDMWeatherManager.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; + +namespace ScarletMansion.GamePatch.Weathers { + public class SDMWeatherManager : MonoBehaviour { + + [Header("Rainy")] + public GameObject rainGameObject; + public ParticleSystem rainParticleSystem; + public AudioSource rainAudioSource; + + // fix itself + void Start() { + var timeofDay = TimeOfDay.Instance; + if (timeofDay == null) { + Plugin.logger.LogError("How is TimeOfDay null?"); + return; + } + + var rainEffect = timeofDay.effects.FirstOrDefault(x => x.name == "rainy"); + var rainGameObject = rainEffect.effectObject; + Utility.FixParticleSystemMaterialAndChildren(rainParticleSystem, rainGameObject.GetComponentInChildren()); + rainAudioSource.clip = rainGameObject.GetComponentInChildren().clip; + rainAudioSource.Play(); + + Plugin.logger.LogInfo("Fixed Rainy weather references"); + + } + + } +} diff --git a/ScarletMansion/ScarletMansion/LoadingPatch/NetworkObjectListScriptableObject.cs b/ScarletMansion/ScarletMansion/LoadingPatch/NetworkObjectListScriptableObject.cs index 3413b3a..cb081a6 100644 --- a/ScarletMansion/ScarletMansion/LoadingPatch/NetworkObjectListScriptableObject.cs +++ b/ScarletMansion/ScarletMansion/LoadingPatch/NetworkObjectListScriptableObject.cs @@ -5,6 +5,7 @@ using System.Text; using System.Threading.Tasks; using UnityEngine; using DunGen; +using DunGen.Graph; namespace ScarletMansion { @@ -22,14 +23,12 @@ namespace ScarletMansion { public List toFixGameObjects; public List items; public List scrapItems; + public List enemies; [Header("DunGen")] public TileSet mayorRegularTileset; public TileSet mayorVanillaTileset; - public DungeonArchetype hallwayEntranceArchetype; - - public List archetypes; - public List tilesets; + public GraphNode gardenEntranceGraphNode; [Header("Main Prefabs")] public GameObject scarletNetworkManager; @@ -37,5 +36,6 @@ namespace ScarletMansion { [Header("Mis References")] public Material ghostMaterial; public AudioClip sinkingAudioClip; + public GameObject yukariSpawnPrefab; } } diff --git a/ScarletMansion/ScarletMansion/ModPatch/AdvancedCompanyPatch.cs b/ScarletMansion/ScarletMansion/ModPatch/AdvancedCompanyPatch.cs deleted file mode 100644 index c457af9..0000000 --- a/ScarletMansion/ScarletMansion/ModPatch/AdvancedCompanyPatch.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Reflection; -using System.Reflection.Emit; -using HarmonyLib; - - -namespace ScarletMansion.ModPatch { - public class AdvancedCompanyPatch : ModPatch { - - public override string warningMessage => "AC compability will stay but if it breaks in the future, I'm not fixing it. Apologies."; - - public AdvancedCompanyPatch(string guid) : base(guid) { } - - public override void AddPatch() { - try { - var desiredTypeString = "AdvancedCompany.Game.Manager+Moons, AdvancedCompany"; - var moonManagerType = System.Type.GetType(desiredTypeString); - - var GetInsideEnemiesAC = moonManagerType.GetMethod("GetInsideEnemies", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy); - var GetLootTableAC = moonManagerType.GetMethod("GetLootTable", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy); - var GetScrapAmountAC = moonManagerType.GetMethod("GetScrapAmountModifier", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy); - - GamePatch.LoadAssetsIntoLevelPatch.enemiesInjection.instructions.Add(new CodeInstruction(OpCodes.Call, GetInsideEnemiesAC)); - //GamePatch.LoadAssetsIntoLevelPatch.itemsInjection.instructions.Add(new CodeInstruction(OpCodes.Call, GetLootTableAC)); - GamePatch.RoundManagerPatch.scrapInjection.instructions.Add(new CodeInstruction(OpCodes.Call, GetScrapAmountAC)); - - } catch (System.Exception e) { - Plugin.logger.LogError("Failed to setup patching for Advanced Company. Custom enemies and items for SDM will not spawn, but bugs should not happen maybe possibly?"); - Plugin.logger.LogError(e); - } - } - } -} diff --git a/ScarletMansion/ScarletMansion/ModPatch/LethalConfigPatch.cs b/ScarletMansion/ScarletMansion/ModPatch/LethalConfigPatch.cs index 8ae5f48..ea64e6d 100644 --- a/ScarletMansion/ScarletMansion/ModPatch/LethalConfigPatch.cs +++ b/ScarletMansion/ScarletMansion/ModPatch/LethalConfigPatch.cs @@ -14,27 +14,27 @@ using ConfigEntryBundleInt = ScarletMansion.PluginConfig.ConfigEntryBundle; using ConfigEntryBundleFloat = ScarletMansion.PluginConfig.ConfigEntryBundle; using ConfigEntryBundleString = ScarletMansion.PluginConfig.ConfigEntryBundle; using ConfigEntryBundleBool = ScarletMansion.PluginConfig.ConfigEntryBundle; +using HarmonyLib; +using LethalConfig.MonoBehaviours.Components; +using UnityEngine.UI; +using LethalConfig.MonoBehaviours; namespace ScarletMansion.ModPatch { public class LethalConfigPatch : ModPatch { public const string section = "_Presets"; - public const string descriptionPrefix = "These are a set of preset config values for your convience. Your config values will automatically update to these preset values every time SDM is loaded. To disable this feature, set this value to Custom."; + public const string descriptionPrefix = "These are a set of preset config values for your convience. Your config values will automatically update to these preset values every time SDM is loaded. These config values are a brighter shade of red. To disable this feature, set this value to Custom."; public const string requiresNewLobby = "Requires a lobby restart for the values to be updated."; + public override string version => "1.4.2"; + public LethalConfigPatch(string guid) : base(guid) { } public static void ForceUIUpdate(){ try { - var desiredTypeString = "LethalConfig.MonoBehaviours.ConfigMenu, LethalConfig"; - var configMenuType = Type.GetType(desiredTypeString); - var configMenuObject = GameObject.FindObjectOfType(configMenuType); - - var closeFunction = configMenuType.GetMethod("Close", BindingFlags.Instance | BindingFlags.Public); - var openFunction = configMenuType.GetMethod("Open", BindingFlags.Instance | BindingFlags.Public); - closeFunction.Invoke(configMenuObject, new object[] {false} ); - openFunction.Invoke(configMenuObject, new object[] {} ); - + var configMenuObject = GameObject.FindObjectOfType(); + configMenuObject.Close(false); + configMenuObject.Open(); } catch (Exception e) { Plugin.logger.LogWarning("Could not force Lethal Config UI update"); Plugin.logger.LogError(e.ToString()); @@ -151,6 +151,41 @@ namespace ScarletMansion.ModPatch { CreatePresetConfig(PluginConfig.lcDungeonLightingPreset.config, PresetConfig.dungeonLightingChangeList); AutoGenerateConfigs(PluginConfig.lcDungeonGenerationPreset, PluginConfig.lcDungeonLightingPreset); + + try { + Plugin.Instance.harmony.PatchAll(typeof(LethalConfigPatch)); + } catch (Exception e) { + Plugin.logger.LogWarning("Tried to HarmonyPatch LethalConfig but failed. Nothing bad will happen but report this bug to dev."); + Plugin.logger.LogError(e.ToString()); + } + } + + [HarmonyPatch(typeof(LethalConfig.MonoBehaviours.ConfigList), "LoadConfigsForMod")] + [HarmonyPostfix] + public static void LoadConfigsForModPatch(ref LethalConfig.MonoBehaviours.ConfigList __instance, ref LethalConfig.Mods.Mod mod) { + try { + if (mod.ModInfo.Guid == Plugin.modGUID) { + + var genChanges = PresetConfig.defaultGeneration.GetAllConfigEntries(); + var lightChanges = PresetConfig.defaultLighting.GetAllConfigEntries(); + + foreach(Transform child in __instance.listContainerObject.transform){ + var controller = child.GetComponentInChildren(); + if (controller == null) continue; + + var config = controller.BaseConfigItem.BaseConfigEntry; + if (genChanges.Contains(config) || lightChanges.Contains(config)) { + foreach(var image in controller.GetComponentsInChildren()) { + image.color = Utility.BrightenColor(image.color, new Color(0.2f, 0.05f, 0.05f)); + } + } + } + } + } catch (Exception e) { + Plugin.logger.LogWarning("Tried to change the label colors of LethalConfig but failed. Nothing bad will happen but report this bug to dev."); + Plugin.logger.LogError(e.ToString()); + } + } } diff --git a/ScarletMansion/ScarletMansion/ModPatch/ModCompability.cs b/ScarletMansion/ScarletMansion/ModPatch/ModCompability.cs index e74a49b..3b9c8b7 100644 --- a/ScarletMansion/ScarletMansion/ModPatch/ModCompability.cs +++ b/ScarletMansion/ScarletMansion/ModPatch/ModCompability.cs @@ -9,13 +9,13 @@ using BepInEx.Bootstrap; namespace ScarletMansion.ModPatch { public class ModCompability { - public const string advancedCompanyGuid = "com.potatoepet.AdvancedCompany"; + //public const string advancedCompanyGuid = "com.potatoepet.AdvancedCompany"; public const string lethalConfigGuid = "ainavt.lc.lethalconfig"; public const string facilityMeldownGuid = "me.loaforc.facilitymeltdown"; public const string reserveFlashlightGuid = "FlipMods.ReservedFlashlightSlot"; public static readonly ModPatch[] modPatches = new ModPatch[] { - new AdvancedCompanyPatch(advancedCompanyGuid), + //new AdvancedCompanyPatch(advancedCompanyGuid), new LethalConfigPatch(lethalConfigGuid), new FacilityMeltdownPatch(facilityMeldownGuid), new ReservedItemSlotPatch(reserveFlashlightGuid) diff --git a/ScarletMansion/ScarletMansion/Plugin.cs b/ScarletMansion/ScarletMansion/Plugin.cs index ad8c931..313134d 100644 --- a/ScarletMansion/ScarletMansion/Plugin.cs +++ b/ScarletMansion/ScarletMansion/Plugin.cs @@ -23,16 +23,17 @@ namespace ScarletMansion { [BepInDependency("imabatby.lethallevelloader", "1.2.0.3")] [BepInDependency("evaisa.lethallib", "0.13.2")] + [BepInDependency("dev.ladyalice.dungenplus", "1.0.0")] - [BepInDependency(ModCompability.advancedCompanyGuid, BepInDependency.DependencyFlags.SoftDependency)] + //[BepInDependency(ModCompability.advancedCompanyGuid, BepInDependency.DependencyFlags.SoftDependency)] [BepInDependency(ModCompability.lethalConfigGuid, BepInDependency.DependencyFlags.SoftDependency)] [BepInDependency(ModCompability.facilityMeldownGuid, BepInDependency.DependencyFlags.SoftDependency)] [BepInDependency(ModCompability.reserveFlashlightGuid, BepInDependency.DependencyFlags.SoftDependency)] [BepInProcess("Lethal Company.exe")] public class Plugin : BaseUnityPlugin { - public const string modGUID = "ImoutoSama.ScarletMansion"; + public const string modGUID = "dev.ladyalice.scarletmansion"; private const string modName = "Scarlet Mansion"; - private const string modVersion = "1.3.21"; + private const string modVersion = "1.3.22"; public readonly Harmony harmony = new Harmony(modGUID); @@ -66,10 +67,7 @@ namespace ScarletMansion { harmony.PatchAll(typeof(ShotgunItemPatch)); harmony.PatchAll(typeof(ShovelPatch)); - //harmony.PatchAll(typeof(OptimizePatch)); - harmony.PatchAll(typeof(DoorwayConnectionPatch)); harmony.PatchAll(typeof(GeneratePathPatch)); - harmony.PatchAll(typeof(PostProcessPatch)); harmony.PatchAll(typeof(PluginConfig)); @@ -130,7 +128,10 @@ namespace ScarletMansion { Assets.dungeonExtended = extendedDungeon; extendedDungeon.DungeonEvents.onBeforeDungeonGenerate.AddListener(GeneratePathPatch.GeneratePatch); - DoorwayManager.onMainEntranceTeleportSpawnedEvent.AddEvent("DoorwayCleanup", DoorwayManager.onMainEntranceTeleportSpawnedFunction); + //DoorwayManager.onMainEntranceTeleportSpawnedEvent.AddEvent("DoorwayCleanup", DoorwayManager.onMainEntranceTeleportSpawnedFunction); + + DunGenPlus.API.AddDunGenExtender(Assets.dungeon, Assets.dunGenExtender); + Assets.dunGenExtender.Events.OnModifyDunGenExtenderProperties.AddListener(DunGenPatch.Patch.UpdateDunGenExtenderProperties); } void SetupForNetcodePatcher(){ diff --git a/ScarletMansion/ScarletMansion/PluginConfig.cs b/ScarletMansion/ScarletMansion/PluginConfig.cs index 91132ca..13f90bb 100644 --- a/ScarletMansion/ScarletMansion/PluginConfig.cs +++ b/ScarletMansion/ScarletMansion/PluginConfig.cs @@ -253,20 +253,10 @@ namespace ScarletMansion { new AcceptableValueRange(0, 999) ); - public static ConfigEntryBundle maidKnifeSelfDamage = new ConfigEntryBundle( - dungeonLootPrefix, - "Maid Knife Feed Damage", - 50, - "The amount of self damage taken by feeding the maid's knife. Can kill.", - null, - new AcceptableValueRange(0, 100) - ); - public float lootMultiplierValue; public int crystalWeightValue; public int crystalBrokenWeightValue; public int snowGlobeWeightValue; - public int maidKnifeSelfDamageValue; // enemies public static ConfigEntryBundle mapHazardsMultiplier = new ConfigEntryBundle( diff --git a/ScarletMansion/ScarletMansion/PresetConfig.cs b/ScarletMansion/ScarletMansion/PresetConfig.cs index 8c99676..72f0cd7 100644 --- a/ScarletMansion/ScarletMansion/PresetConfig.cs +++ b/ScarletMansion/ScarletMansion/PresetConfig.cs @@ -240,11 +240,20 @@ namespace ScarletMansion { return str; } + + public HashSet GetAllConfigEntries(){ + var set = new HashSet(); + foreach(var a in changes.SelectMany(c => c.configBases)){ + set.Add(a); + } + return set; + } } public abstract class Change { public abstract void Update(); public abstract bool IsEqual(Change target); + public abstract IEnumerable configBases { get; } } public abstract class ChangeType : Change { @@ -252,6 +261,12 @@ namespace ScarletMansion { public ConfigEntry configEntry => configBundle.config; public T value; + public override IEnumerable configBases { + get { + yield return configEntry; + } + } + public ChangeType(PluginConfig.ConfigEntryBundle configBundle){ this.configBundle = configBundle; this.value = configBundle.defaultValue; @@ -296,6 +311,13 @@ namespace ScarletMansion { public ChangeInt min; public ChangeInt max; + public override IEnumerable configBases { + get { + yield return min.configEntry; + yield return max.configEntry; + } + } + public ChangeMinMaxInt(PluginConfig.ConfigEntryBundleMinMax configBundle){ min = new ChangeInt(configBundle.min); max = new ChangeInt(configBundle.max); @@ -326,6 +348,13 @@ namespace ScarletMansion { public ChangeFloat min; public ChangeFloat max; + public override IEnumerable configBases { + get { + yield return min.configEntry; + yield return max.configEntry; + } + } + public ChangeMinMaxFloat(PluginConfig.ConfigEntryBundleMinMax configBundle){ min = new ChangeFloat(configBundle.min); max = new ChangeFloat(configBundle.max); @@ -356,6 +385,13 @@ namespace ScarletMansion { public ChangeMinMaxInt count; public ChangeMinMaxInt depth; + public override IEnumerable configBases { + get { + foreach(var a in count.configBases) yield return a; + foreach(var a in depth.configBases) yield return a; + } + } + public ChangeBranchingPath(PluginConfig.ConfigEntryBundleBranchingPath configBundle){ count = new ChangeMinMaxInt(configBundle.count); depth = new ChangeMinMaxInt(configBundle.depth); diff --git a/ScarletMansion/ScarletMansion/ScarletMansion.csproj b/ScarletMansion/ScarletMansion/ScarletMansion.csproj index b7ab0c0..0ed1af3 100644 --- a/ScarletMansion/ScarletMansion/ScarletMansion.csproj +++ b/ScarletMansion/ScarletMansion/ScarletMansion.csproj @@ -37,9 +37,6 @@ ..\..\..\Libraries\AdvancedCompany.dll - - ..\..\..\Libraries\Assembly-CSharp.dll - ..\..\..\Libraries\Assembly-CSharp-firstpass.dll @@ -52,11 +49,14 @@ ..\..\..\Libraries\BepInEx.Harmony.dll + + ..\..\..\Libraries\DunGenPlus.dll + ..\..\..\Libraries\FacilityMeltdown.dll - - ..\..\..\Libraries\LethalConfig.dll + + ..\..\..\Libraries\LethalConfig-publicized.dll ..\..\..\Libraries\LethalLevelLoader.dll @@ -150,33 +150,15 @@ - - - - - - - - - - - - - - - - - - - - + + @@ -187,9 +169,12 @@ + + + @@ -204,7 +189,6 @@ - @@ -212,7 +196,6 @@ - @@ -227,14 +210,13 @@ - + - diff --git a/ScarletMansion/ScarletMansion/TranspilerUtilities.cs b/ScarletMansion/ScarletMansion/TranspilerUtilities.cs index 756bb24..4d40ce6 100644 --- a/ScarletMansion/ScarletMansion/TranspilerUtilities.cs +++ b/ScarletMansion/ScarletMansion/TranspilerUtilities.cs @@ -83,6 +83,10 @@ namespace ScarletMansion { seq.Add((i) => i.opcode == opcode && i.operand == operand); } + public void AddBasicLocal(OpCode opcode, int operand){ + seq.Add((i) => i.opcode == opcode && (i.operand as LocalBuilder).LocalIndex == operand); + } + public void AddOperandTypeCheck(OpCode opcode, Type operandType){ seq.Add((i) => { var fieldInfo = i.operand as FieldInfo; @@ -117,6 +121,7 @@ namespace ScarletMansion { public bool VerifyStage(CodeInstruction current){ var s = seq[stage]; if (s.Invoke(current)) { + //Plugin.logger.LogInfo($"{name}({stage}): current.ToString()"); stage++; } else { stage = 0; diff --git a/ScarletMansion/ScarletMansion/Utility.cs b/ScarletMansion/ScarletMansion/Utility.cs index 6e6339f..32e7fb8 100644 --- a/ScarletMansion/ScarletMansion/Utility.cs +++ b/ScarletMansion/ScarletMansion/Utility.cs @@ -211,6 +211,16 @@ namespace ScarletMansion { } } + public static (int totalMinutes, int hours, int minutes) GetTime(){ + var timeOfDay = TimeOfDay.Instance; + if (timeOfDay == null) return (0, 0, 0); + + var totalMinutes = (int)(timeOfDay.normalizedTimeOfDay * (60f * timeOfDay.numberOfHours)) + 360; + var hours = Mathf.FloorToInt(totalMinutes / 60f); + var minutes = totalMinutes % 60; + return (totalMinutes, hours, minutes); + } + public static List GetDungeonItems(){ return LoadAssetsIntoLevelPatch.GetItems(RoundManager.Instance.currentLevel.spawnableScrap); } @@ -312,6 +322,34 @@ namespace ScarletMansion { return method; } + public static Color BrightenColor(Color color, float amount) { + var diff = (Color.white - color) * amount; + return new Color(color.r + diff.r, color.g + diff.g, color.b + diff.b, color.a); + } + + public static Color BrightenColor(Color color, Color amount) { + var diff = (Color.white - color) * amount; + return new Color(color.r + diff.r, color.g + diff.g, color.b + diff.b, color.a); + } + + public static void FixParticleSystemMaterial(ParticleSystemRenderer toFixParticleSystem, ParticleSystemRenderer copyParticleSystem) { + toFixParticleSystem.sharedMaterial = copyParticleSystem.sharedMaterial; + } + + public static void FixParticleSystemMaterial(ParticleSystem toFixParticleSystem, ParticleSystem copyParticleSystem) { + FixParticleSystemMaterial(toFixParticleSystem.GetComponent(), copyParticleSystem.GetComponent()); + } + + public static void FixParticleSystemMaterialAndChildren(ParticleSystem toFixParticleSystem, ParticleSystem copyParticleSystem) { + FixParticleSystemMaterial(toFixParticleSystem, copyParticleSystem); + + for(var i = 0; i < toFixParticleSystem.transform.childCount && i < copyParticleSystem.transform.childCount; ++i) { + var child0 = toFixParticleSystem.transform.GetChild(i).GetComponent(); + var child1 = copyParticleSystem.transform.GetChild(i).GetComponent(); + FixParticleSystemMaterial(child0, child1); + } + } + /* public static GameObject GetParentWithNetworkObject(GameObject g){ diff --git a/ScarletMansionMimicsPatch/ScarletMansionMimicsPatch/Patch.cs b/ScarletMansionMimicsPatch/ScarletMansionMimicsPatch/Patch.cs index b7cb7b3..aaa8c17 100644 --- a/ScarletMansionMimicsPatch/ScarletMansionMimicsPatch/Patch.cs +++ b/ScarletMansionMimicsPatch/ScarletMansionMimicsPatch/Patch.cs @@ -36,7 +36,7 @@ namespace ScarletMansionMimicsPatch { public override bool IsMyInteriorLoaded => ScarletMansion.DunGenPatch.Patch.active; public override void OnMimicCreated(MimicDoor mimicDoor, Doorway doorway) { - var c = doorway.transform.parent.GetComponentInChildren(); + var c = doorway.transform.parent.GetComponentInChildren(); if (c != null) { c.overrideConnector = true; c.overrideNoDoorway = true; diff --git a/ScarletMansionMimicsPatch/ScarletMansionMimicsPatch/Plugin.cs b/ScarletMansionMimicsPatch/ScarletMansionMimicsPatch/Plugin.cs index 7d2efc4..441bc91 100644 --- a/ScarletMansionMimicsPatch/ScarletMansionMimicsPatch/Plugin.cs +++ b/ScarletMansionMimicsPatch/ScarletMansionMimicsPatch/Plugin.cs @@ -19,12 +19,12 @@ namespace ScarletMansionMimicsPatch { [BepInPlugin(modGUID, modName, modVersion)] - [BepInDependency("ImoutoSama.ScarletMansion", "1.3.12")] + [BepInDependency("dev.ladyalice.scarletmansion", "1.3.22")] [BepInDependency(targetModGUID, BepInDependency.DependencyFlags.SoftDependency)] public class Plugin : BaseUnityPlugin { - public const string modGUID = "ImoutoSama.ScarletMansionMimicsPatch"; + public const string modGUID = "dev.ladyalice.scarletmansion.mimicspatch"; private const string modName = "Scarlet Mansion Mimics Patch"; private const string modVersion = "1.0.0"; diff --git a/ScarletMansionMimicsPatch/ScarletMansionMimicsPatch/ScarletMansionMimicsPatch.csproj b/ScarletMansionMimicsPatch/ScarletMansionMimicsPatch/ScarletMansionMimicsPatch.csproj index 93269db..c7025b5 100644 --- a/ScarletMansionMimicsPatch/ScarletMansionMimicsPatch/ScarletMansionMimicsPatch.csproj +++ b/ScarletMansionMimicsPatch/ScarletMansionMimicsPatch/ScarletMansionMimicsPatch.csproj @@ -40,6 +40,9 @@ ..\..\..\Libraries\BepInEx.dll + + ..\..\..\Libraries\DunGenPlus.dll + ..\..\..\Libraries\Mimics.dll