diff --git a/ScarletMansion/ScarletMansion/Assets.cs b/ScarletMansion/ScarletMansion/Assets.cs index 3474970..b2174be 100644 --- a/ScarletMansion/ScarletMansion/Assets.cs +++ b/ScarletMansion/ScarletMansion/Assets.cs @@ -8,12 +8,10 @@ using UnityEngine; using System.Reflection; using System.IO; using DunGen.Graph; -using UnityEngine.Experimental.Rendering; using LethalLib.Modules; using LethalLevelLoader; -using ScarletMansion.GamePatch.Items; -using static ScarletMansion.Assets; using DunGenPlus; +using ScarletMansion.ModPatch; namespace ScarletMansion { public static class Assets { @@ -21,6 +19,7 @@ namespace ScarletMansion { static BepInEx.Logging.ManualLogSource logger => Plugin.logger; public static ActionList onAssetsLoadEvent = new ActionList("onAssetsLoad"); + public static ActionList onPlayerDeath = new ActionList("onPlayerDeath"); const string mainAssetBundleName = "scarletmansion"; diff --git a/ScarletMansion/ScarletMansion/DunGenPatch/Patch.cs b/ScarletMansion/ScarletMansion/DunGenPatch/Patch.cs index 9833fca..039f73e 100644 --- a/ScarletMansion/ScarletMansion/DunGenPatch/Patch.cs +++ b/ScarletMansion/ScarletMansion/DunGenPatch/Patch.cs @@ -21,6 +21,18 @@ namespace ScarletMansion.DunGenPatch { public static bool callAlternative; public static DungeonGenerator generatorInstance; + public static RandomStream GetRandomStream(){ + return generatorInstance.RandomStream; + } + + public static int CreateSystemRandomSeed(){ + return GetRandomStream().Next(); + } + + public static System.Random CreateSystemRandom(){ + return new System.Random(CreateSystemRandomSeed()); + } + public static void Activate(DungeonGenerator generator){ active = true; callAlternative = true; diff --git a/ScarletMansion/ScarletMansion/GamePatch/Components/IScarletSelfDestroy.cs b/ScarletMansion/ScarletMansion/GamePatch/Components/IScarletSelfDestroy.cs new file mode 100644 index 0000000..51fb283 --- /dev/null +++ b/ScarletMansion/ScarletMansion/GamePatch/Components/IScarletSelfDestroy.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ScarletMansion.GamePatch.Components { + public interface IScarletSelfDestroy { + + float Chance { get; } + bool IsDestroyed { get; } + + void PreDestroy(); + + void Destroy(); + + } +} diff --git a/ScarletMansion/ScarletMansion/GamePatch/Components/Lights/ScarletLight.cs b/ScarletMansion/ScarletMansion/GamePatch/Components/Lights/ScarletLight.cs index a4e7e4f..6f6722a 100644 --- a/ScarletMansion/ScarletMansion/GamePatch/Components/Lights/ScarletLight.cs +++ b/ScarletMansion/ScarletMansion/GamePatch/Components/Lights/ScarletLight.cs @@ -6,16 +6,32 @@ using System.Text; using System.Threading.Tasks; using UnityEngine; using DunGen; +using LethalLevelLoader; +using ScarletMansion.GamePatch.Components; namespace ScarletMansion.Lights { - public class ScarletLight : MonoBehaviour, IComparable, IDungeonCompleteReceiver { + public class ScarletLight : MonoBehaviour, IComparable, IDungeonCompleteReceiver, IScarletSelfDestroy { public Light light; public int priority = 0; + public float chanceEveryHourToDestroy = 1 / 52f; - private Coroutine anger; - private bool permenantAnger; + public enum FlickeringState { None, Light, Heavy, Broke } + public FlickeringState flickeringState; + private Coroutine flickeringCoroutine; + + public enum ColorState { Normal, TemporaryRed, Red } + public ColorState colorState; + private Coroutine colorCoroutine; + + private bool preDestroy; + private int systemRandomSeed; + + + public float Chance => chanceEveryHourToDestroy; + + public bool IsDestroyed => preDestroy; public int CompareTo(ScarletLight obj) { return obj.priority.CompareTo(priority); @@ -25,15 +41,69 @@ namespace ScarletMansion.Lights { light = GetComponent(); } - public void BeginAngry(float duration, bool forever){ - if (permenantAnger) return; - if (anger != null) StopCoroutine(anger); + public void SetFlickeringState(FlickeringState state) { + if (flickeringState >= state) return; + flickeringState = state; + + if (flickeringCoroutine != null) StopCoroutine(flickeringCoroutine); + flickeringCoroutine = null; + + switch(flickeringState) { + case FlickeringState.None: + light.enabled = true; + break; + case FlickeringState.Broke: + light.enabled = false; + preDestroy = true; + break; + case FlickeringState.Light: + flickeringCoroutine = StartCoroutine(FlickerLight(12, 18, 0.25f, 0.4f, 0.75f, 1f, 1.5f)); + break; + case FlickeringState.Heavy: + flickeringCoroutine = StartCoroutine(FlickerLight(6, 8, 0.15f, 0.25f, 0.5f, 0.6f, 0.5f)); + preDestroy = true; + break; + } - if (forever) permenantAnger = true; - anger = StartCoroutine(AngerCoroutine(duration)); } - private IEnumerator AngerCoroutine(float duration){ + public void SetColorState(ColorState state) { + if (colorState >= state) return; + colorState = state; + + if (colorCoroutine != null) StopCoroutine(colorCoroutine); + colorCoroutine = null; + + switch (colorState){ + case ColorState.Normal: + light.color = Color.white; + break; + case ColorState.TemporaryRed: + colorCoroutine = StartCoroutine(AngerLight(6f)); + break; + case ColorState.Red: + colorCoroutine = StartCoroutine(AngerLight(0f)); + break; + } + } + + private IEnumerator FlickerLight(int minFlicker, int maxFlicker, float minOffPause, float maxOffPause, float minOnPause, float maxOnPause, float cycleMultiplier){ + var random = new System.Random(systemRandomSeed); + + var count = random.Next(minFlicker, maxFlicker); + for (var i = 0; i < count; ++i) { + var cycleM = Mathf.Lerp(1f, cycleMultiplier, (float)i / count); + light.enabled = false; + yield return new WaitForSeconds(random.GetRandomNumber(minOffPause, maxOffPause) * cycleM); + light.enabled = true; + yield return new WaitForSeconds(random.GetRandomNumber(minOnPause, maxOnPause) * cycleM); + } + + light.enabled = false; + flickeringState = FlickeringState.Broke; + } + + private IEnumerator AngerLight(float duration){ var t = 0f; var c = light.color; while(t < 0.375f) { @@ -42,7 +112,7 @@ namespace ScarletMansion.Lights { light.color = Color.Lerp(c, Color.red, t / 0.375f); } - if (permenantAnger) yield break; + if (duration == 0f) yield break; yield return new WaitForSeconds(duration + UnityEngine.Random.value); c = light.color; @@ -53,11 +123,23 @@ namespace ScarletMansion.Lights { light.color = Color.Lerp(c, Color.white, t / 1.25f); } + colorState = ColorState.Normal; } public void OnDungeonComplete(Dungeon dungeon) { if (!gameObject.activeInHierarchy) return; - GamePatch.Managers.AngerManager.Instance.AddLight(this); + + GamePatch.Managers.ScarletGenericManager.Instance.AddLight(this); + systemRandomSeed = DunGenPatch.Patch.CreateSystemRandomSeed(); + //Plugin.logger.LogInfo(systemRandomSeed); + } + + public void PreDestroy() { + preDestroy = true; + } + + public void Destroy() { + SetFlickeringState(FlickeringState.Light); } } diff --git a/ScarletMansion/ScarletMansion/GamePatch/Components/Lights/ScarletLightCleanup.cs b/ScarletMansion/ScarletMansion/GamePatch/Components/Lights/ScarletLightCleanup.cs index 99986c7..0ccdd90 100644 --- a/ScarletMansion/ScarletMansion/GamePatch/Components/Lights/ScarletLightCleanup.cs +++ b/ScarletMansion/ScarletMansion/GamePatch/Components/Lights/ScarletLightCleanup.cs @@ -18,7 +18,7 @@ namespace ScarletMansion.Lights { if (lights.Length == 0) return; // the smallest amount of optimization - var random = DunGenPatch.Patch.generatorInstance.RandomStream; + var random = DunGenPatch.Patch.GetRandomStream(); if (lights.Length > 1){ Utility.Shuffle(random, lights); System.Array.Sort(lights); @@ -29,7 +29,7 @@ namespace ScarletMansion.Lights { var count = GetRandom(random, weights); count = Mathf.Min(count, maxLights); for(var i = count; i < lights.Length; ++i){ - lights[i].gameObject.SetActive(false); + lights[i].SetFlickeringState(ScarletLight.FlickeringState.Broke); } } diff --git a/ScarletMansion/ScarletMansion/GamePatch/Components/PathOpenUpParent.cs b/ScarletMansion/ScarletMansion/GamePatch/Components/PathOpenUpParent.cs index da53c93..db43d5a 100644 --- a/ScarletMansion/ScarletMansion/GamePatch/Components/PathOpenUpParent.cs +++ b/ScarletMansion/ScarletMansion/GamePatch/Components/PathOpenUpParent.cs @@ -44,8 +44,7 @@ namespace ScarletMansion.GamePatch.Components public void OnDungeonComplete(Dungeon dungeon) { var anyChanges = true; - var dunRandom = DunGenPatch.Patch.generatorInstance.RandomStream; - var sysRandom = new System.Random(dunRandom.Next()); + var sysRandom = DunGenPatch.Patch.CreateSystemRandom(); foreach(var c in chokepoints) { c.UpdatePath(sysRandom); diff --git a/ScarletMansion/ScarletMansion/GamePatch/Components/ScarletBedroom.cs b/ScarletMansion/ScarletMansion/GamePatch/Components/ScarletBedroom.cs index aff66d0..de97fed 100644 --- a/ScarletMansion/ScarletMansion/GamePatch/Components/ScarletBedroom.cs +++ b/ScarletMansion/ScarletMansion/GamePatch/Components/ScarletBedroom.cs @@ -66,7 +66,7 @@ namespace ScarletMansion.GamePatch.Components { // lock doors if (roundmanager.IsServer){ foreach(var d in doorways){ - var result = AngerManager.Instance.GetScarletDoor(d.transform.position); + var result = ScarletGenericManager.Instance.GetScarletDoor(d.transform.position); if (result) doors.Add(result); } @@ -112,17 +112,9 @@ namespace ScarletMansion.GamePatch.Components { yield return new WaitForSeconds(UnityEngine.Random.Range(1f, 1.5f)); // scarlet lights flicker - var isScarletLight = light.GetComponent() != null; - if (isScarletLight){ - var count = UnityEngine.Random.Range(6, 8); - for (var i = 0; i < count; ++i) { - light.enabled = false; - yield return new WaitForSeconds(UnityEngine.Random.Range(0.15f, 0.25f) * (1f - count * 0.05f)); - light.enabled = true; - yield return new WaitForSeconds(UnityEngine.Random.Range(0.5f, 0.6f) * (1f - count * 0.05f)); - } - - light.enabled = false; + var scarletLight = light.GetComponent(); + if (scarletLight != null){ + scarletLight.SetFlickeringState(ScarletLight.FlickeringState.Heavy); } // normal lights are candles, so just turn them off else { @@ -211,7 +203,7 @@ namespace ScarletMansion.GamePatch.Components { if (!roundmanager.IsServer) return; try { - AngerManager.Instance.SpawnAngerLoot(bonusItems, itemSpawns); + AngerManager.SpawnAngerLoot(bonusItems, itemSpawns); } catch (Exception e) { var itemStrings = string.Join("\n", bonusItems.Select(i => i != null ? i.ToString() : "NULL")); Plugin.logger.LogError($"Failed to spawn items for bedroom event, the smelly culprits are {itemStrings}"); @@ -220,21 +212,19 @@ namespace ScarletMansion.GamePatch.Components { } public void OnDungeonComplete(Dungeon dungeon) { - AngerManager.Instance.AddBedroom(this); - AngerManager.Instance.AddRoomOfInterest(transform); + ScarletGenericManager.Instance.AddBedroom(this); + ScarletGenericManager.Instance.AddRoomOfInterest(transform); var parent = GetComponentInParent(); lights = parent.GetComponentsInChildren(); doorways = parent.UsedDoorways.ToArray(); - var dunRandom = DunGenPatch.Patch.generatorInstance.RandomStream; - var randomValue = (int)(dunRandom.NextDouble() * int.MaxValue); - var sysRandom = new System.Random(randomValue); + var sysRandom = DunGenPatch.Patch.CreateSystemRandom(); Utility.Shuffle(sysRandom, itemSpawns); var count = sysRandom.Next(PluginConfig.Instance.paintingExtraLootValue.min, PluginConfig.Instance.paintingExtraLootValue.max + 1); - bonusItems = AngerManager.Instance.CreateAngerLoot(count, sysRandom); + bonusItems = AngerManager.CreateAngerLoot(count, sysRandom); bonusEnemy = GetRandomEnemy(sysRandom); } diff --git a/ScarletMansion/ScarletMansion/GamePatch/Components/ScarletBookPath.cs b/ScarletMansion/ScarletMansion/GamePatch/Components/ScarletBookPath.cs new file mode 100644 index 0000000..23dcdd6 --- /dev/null +++ b/ScarletMansion/ScarletMansion/GamePatch/Components/ScarletBookPath.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections; +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 ScarletBookPath : MonoBehaviour { + + public Transform bookTransform; + + [Header("Nodes")] + public Transform[] nodeTransforms; + public float nodeRadius = 0.25f; + public int index = 0; + + [Header("Speed")] + public float velocity = 1f; + public float rotationVelocity = 45f; + + void Update(){ + var nextTransform = nodeTransforms[index]; + + var forwardDirection = nextTransform.position - bookTransform.position; + bookTransform.rotation = Quaternion.RotateTowards(bookTransform.rotation, Quaternion.LookRotation(forwardDirection), Time.deltaTime * rotationVelocity); + + bookTransform.position += forwardDirection.normalized * Time.deltaTime * velocity; + + if (Vector3.SqrMagnitude(forwardDirection) <= nodeRadius * nodeRadius){ + index = (index + 1) % nodeTransforms.Length; + } + } + public void ResetPath(){ + index = 0; + var current = nodeTransforms[index]; + var next= nodeTransforms[index + 1]; + bookTransform.position = current.position; + bookTransform.rotation = Quaternion.LookRotation(next.position - current.position); + } + + public void OnDrawGizmosSelected(){ + Gizmos.color = Color.green; + for(var i = 0; i < nodeTransforms.Length; ++i){ + var current = nodeTransforms[i]; + var next = nodeTransforms[(i + 1) % nodeTransforms.Length]; + Gizmos.DrawWireSphere(current.position, nodeRadius); + Gizmos.DrawLine(current.position, next.position); + } + + } + + } +} diff --git a/ScarletMansion/ScarletMansion/GamePatch/Components/ScarletClock.cs b/ScarletMansion/ScarletMansion/GamePatch/Components/ScarletClock.cs index cba535d..066ec29 100644 --- a/ScarletMansion/ScarletMansion/GamePatch/Components/ScarletClock.cs +++ b/ScarletMansion/ScarletMansion/GamePatch/Components/ScarletClock.cs @@ -8,7 +8,8 @@ using UnityEngine; using Unity.Netcode; namespace ScarletMansion.GamePatch.Components { - public class ScarletClock : NetworkBehaviour { + + public class ScarletClock : MonoBehaviour, IScarletSelfDestroy { [Header("Animations")] public Vector3 eulerAngleOffset = new Vector3(-90f, -90f, -90f); @@ -24,21 +25,18 @@ namespace ScarletMansion.GamePatch.Components { [Header("Destruction Values")] public bool stop; + public bool preStop; public float chanceEveryHourToDestroy = 1f / 52f; private float timerTillDestroyed = -1f; + public float Chance => chanceEveryHourToDestroy; + + public bool IsDestroyed => preStop; + void Update(){ if (stop) return; - if (IsServer && timerTillDestroyed > 0f){ - timerTillDestroyed -= Time.deltaTime; - if (timerTillDestroyed <= 0f) { - StopClockClientRpc(); - return; - } - } - var time = Utility.GetTime(); var totalMinutes = time.totalMinutes; var hours = time.hours; @@ -52,10 +50,6 @@ namespace ScarletMansion.GamePatch.Components { animationCoroutine = StartCoroutine(MoveHands(hours, minutes)); } - if (IsServer && hourChanged){ - HourlySelfDestroyCheck(); - } - lastHour = hours; lastTotalMinutes = totalMinutes; } @@ -103,20 +97,12 @@ namespace ScarletMansion.GamePatch.Components { WalkieTalkie.TransmitOneShotAudio(audioSource, clip); } - public void HourlySelfDestroyCheck(){ - if (stop || timerTillDestroyed > 0) return; - - Plugin.logger.LogDebug("Hourly clock self-destroy check"); - if (UnityEngine.Random.value < chanceEveryHourToDestroy) { - timerTillDestroyed = UnityEngine.Random.value * 60f + 15f; - Plugin.logger.LogDebug($"Clock offing itself in {timerTillDestroyed} sec"); - } + public void PreDestroy() { + preStop = true; } - [ClientRpc] - public void StopClockClientRpc(){ + public void Destroy() { stop = true; } - } } diff --git a/ScarletMansion/ScarletMansion/GamePatch/Components/ScarletDoor.cs b/ScarletMansion/ScarletMansion/GamePatch/Components/ScarletDoor.cs index 881658c..786d261 100644 --- a/ScarletMansion/ScarletMansion/GamePatch/Components/ScarletDoor.cs +++ b/ScarletMansion/ScarletMansion/GamePatch/Components/ScarletDoor.cs @@ -25,7 +25,7 @@ namespace ScarletMansion.GamePatch.Components { private bool previousDoorLockValue; void Awake(){ - AngerManager.Instance.AddDoor(this); + ScarletGenericManager.Instance.AddDoor(this); } [ClientRpc] diff --git a/ScarletMansion/ScarletMansion/GamePatch/Components/ScarletRadio.cs b/ScarletMansion/ScarletMansion/GamePatch/Components/ScarletRadio.cs index 9262cb1..765fe5a 100644 --- a/ScarletMansion/ScarletMansion/GamePatch/Components/ScarletRadio.cs +++ b/ScarletMansion/ScarletMansion/GamePatch/Components/ScarletRadio.cs @@ -1,4 +1,6 @@ -using System; +using ScarletMansion.GamePatch.Components.TreasureRoom; +using ScarletMansion.GamePatch.Managers; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -9,6 +11,8 @@ using UnityEngine; namespace ScarletMansion.GamePatch.Components { public class ScarletRadio : NetworkBehaviour{ + public TreasureRoomRadioEvent treasureRoomEvent; + [Header("Networked Values")] public int volume; public bool playing; @@ -83,6 +87,7 @@ namespace ScarletMansion.GamePatch.Components { [ServerRpc(RequireOwnership = false)] public void ToggleOnOffSwitchServerRpc(){ ToggleOnOffSwitchClientRpc(!playing); + treasureRoomEvent?.UpdateTreasureDoorStatus(); } [ClientRpc] @@ -96,6 +101,7 @@ namespace ScarletMansion.GamePatch.Components { [ServerRpc(RequireOwnership = false)] public void ToggleVolumeSwitchServerRpc(int count){ ToggleVolumeSwitchClientRpc(Mathf.Clamp(volume + count, 0, 10)); + treasureRoomEvent?.UpdateTreasureDoorStatus(); } [ClientRpc] @@ -107,6 +113,7 @@ namespace ScarletMansion.GamePatch.Components { [ServerRpc(RequireOwnership = false)] public void ToggleSongSwitchServerRpc(){ ToggleSongSwitchClientRpc((audioIndex + 1) % audioClips.Length); + treasureRoomEvent?.UpdateTreasureDoorStatus(); } [ClientRpc] diff --git a/ScarletMansion/ScarletMansion/GamePatch/Components/ScarletYukariTrigger.cs b/ScarletMansion/ScarletMansion/GamePatch/Components/ScarletYukariTrigger.cs index a427c2d..3a65292 100644 --- a/ScarletMansion/ScarletMansion/GamePatch/Components/ScarletYukariTrigger.cs +++ b/ScarletMansion/ScarletMansion/GamePatch/Components/ScarletYukariTrigger.cs @@ -1,4 +1,5 @@ using GameNetcodeStuff; +using LethalLib.Modules; using System; using System.Collections.Generic; using System.Linq; @@ -22,49 +23,69 @@ namespace ScarletMansion.GamePatch.Components if (!otherGameObject.CompareTag("Player")) { return; } - var comp = otherGameObject.GetComponent(); - if (comp != GameNetworkManager.Instance.localPlayerController) return; + var playerControllerB = otherGameObject.GetComponent(); + if (playerControllerB != GameNetworkManager.Instance.localPlayerController) return; // sanity check - if (audioClipIndex == -1) comp.statusEffectAudioIndex = 0; - comp.statusEffectAudioIndex = audioClipIndex; + if (audioClipIndex == -1) playerControllerB.statusEffectAudioIndex = 0; + playerControllerB.statusEffectAudioIndex = audioClipIndex; - 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(); + if (playerControllerB.isSinking) { - comp.TeleportPlayer(farthestAINode); - var damage = ScarletNetworkManagerUtility.GetCriticalDamageToPlayer(comp, false); - comp.DamagePlayer(damage, false, true, CauseOfDeath.Suffocation); + // to override the normal sinking kill behaviour + if (playerControllerB.sinkingValue >= 0.9f){ + // teleporting them out for a second time in life + // won't be easy though kek + var scarletPlayer = ScarletPlayerControllerB.GetScarletPlayerScript(playerControllerB); + if (scarletPlayer != null && !scarletPlayer.fellInPit && !playerControllerB.criticallyInjured) { + var selfPos = scarletPlayer.transform.position; + var farthestAINode = RoundManager.Instance.insideAINodes + .Select(n => n.transform.position) + .OrderByDescending(n => (selfPos - n).magnitude).FirstOrDefault(); - ScarletNetworkManager.Instance.CreateSpawnAudioPrefab(farthestAINode, comp.actualClientId); - StopSinkingLocalPlayer(comp); + playerControllerB.TeleportPlayer(farthestAINode); + var damage = ScarletNetworkManagerUtility.GetCriticalDamageToPlayer(playerControllerB, false); + playerControllerB.DamagePlayer(damage, false, true, CauseOfDeath.Suffocation); - scarletPlayer.fellInPit = true; + if (playerControllerB.isPlayerDead) { + Assets.onPlayerDeath.Call(new ModPatch.CoronerParameters(playerControllerB, ModPatch.CoronerDeathEnum.Void)); + } + + StopSinkingLocalPlayer(playerControllerB); + ScarletNetworkManager.Instance.CreateSpawnAudioPrefab(farthestAINode, playerControllerB.actualClientId); + + scarletPlayer.fellInPit = true; + } + // just straight up murder + else { + // this is to prevent Coroner from thinking it's quicksand + playerControllerB.isSinking = false; + playerControllerB.KillPlayer(Vector3.zero, false, CauseOfDeath.Suffocation); + if (playerControllerB.isPlayerDead) { + Assets.onPlayerDeath.Call(new ModPatch.CoronerParameters(playerControllerB, ModPatch.CoronerDeathEnum.Void)); + } else { + // a just in case + playerControllerB.isSinking = true; + } + } } return; } if (sinkingLocalPlayer){ - if (!comp.CheckConditionsForSinkingInQuicksand()) { + if (!playerControllerB.CheckConditionsForSinkingInQuicksand()) { - StopSinkingLocalPlayer(comp); + StopSinkingLocalPlayer(playerControllerB); } return; } - if (comp.CheckConditionsForSinkingInQuicksand()){ + if (playerControllerB.CheckConditionsForSinkingInQuicksand()){ sinkingLocalPlayer = true; - comp.sourcesCausingSinking++; - comp.isMovementHindered++; - comp.hinderedMultiplier *= movementHinderence; - comp.sinkingSpeedMultiplier = sinkingSpeedMultiplier; + playerControllerB.sourcesCausingSinking++; + playerControllerB.isMovementHindered++; + playerControllerB.hinderedMultiplier *= movementHinderence; + playerControllerB.sinkingSpeedMultiplier = sinkingSpeedMultiplier; } } diff --git a/ScarletMansion/ScarletMansion/GamePatch/Components/TreasureRoom/TreasureRoom.cs b/ScarletMansion/ScarletMansion/GamePatch/Components/TreasureRoom/TreasureRoom.cs index 5f8ccf1..8db597f 100644 --- a/ScarletMansion/ScarletMansion/GamePatch/Components/TreasureRoom/TreasureRoom.cs +++ b/ScarletMansion/ScarletMansion/GamePatch/Components/TreasureRoom/TreasureRoom.cs @@ -16,7 +16,7 @@ namespace ScarletMansion.GamePatch.Components.TreasureRoom { public GameObject doorStatusPrefab; protected List treasureDoorStatuses; - protected System.Random randomStream; + protected System.Random systemRandom; protected List treasureDoorLocks; protected bool opened; @@ -69,7 +69,7 @@ namespace ScarletMansion.GamePatch.Components.TreasureRoom { } public virtual void OnDungeonComplete(Dungeon dungeon) { - AngerManager.Instance.AddRoomOfInterest(transform); + ScarletGenericManager.Instance.AddRoomOfInterest(transform); var tile = GetComponentInParent(); var doorways = tile.UsedDoorways; @@ -81,14 +81,19 @@ namespace ScarletMansion.GamePatch.Components.TreasureRoom { } } - if (targetDoorways.Count > 0) { - var dunRandom = DunGenPatch.Patch.generatorInstance.RandomStream; - randomStream = new System.Random((int)(dunRandom.NextDouble() * int.MaxValue)); + var hasTreasureRoom = targetDoorways.Count > 0; + if (hasTreasureRoom) { + systemRandom = DunGenPatch.Patch.CreateSystemRandom(); Plugin.logger.LogInfo($"Adding treasure room event {GetType().ToString()}"); DunGenPlus.Managers.DoorwayManager.onMainEntranceTeleportSpawnedEvent.AddTemporaryEvent("TreasureRoom", () => LockTreasureDoor(targetDoorways)); } - + + OnTreasureRoomSetup(hasTreasureRoom); + } + + protected virtual void OnTreasureRoomSetup(bool hasTreasureRoom){ + } protected virtual void LockTreasureDoor(List doorways){ @@ -103,7 +108,7 @@ namespace ScarletMansion.GamePatch.Components.TreasureRoom { } var doorPosition = d.transform.position; - var doorLock = AngerManager.Instance.GetScarletDoor(doorPosition); + var doorLock = ScarletGenericManager.Instance.GetScarletDoor(doorPosition); doorLock.LockDoorOverrideClientRpc(true); treasureDoorLocks.Add(doorLock); } diff --git a/ScarletMansion/ScarletMansion/GamePatch/Components/TreasureRoom/TreasureRoomBookPullEvent.cs b/ScarletMansion/ScarletMansion/GamePatch/Components/TreasureRoom/TreasureRoomBookPullEvent.cs index 82f64c9..d802c86 100644 --- a/ScarletMansion/ScarletMansion/GamePatch/Components/TreasureRoom/TreasureRoomBookPullEvent.cs +++ b/ScarletMansion/ScarletMansion/GamePatch/Components/TreasureRoom/TreasureRoomBookPullEvent.cs @@ -13,14 +13,13 @@ namespace ScarletMansion.GamePatch.Components.TreasureRoom { public class TreasureRoomBookPullEvent : TreasureRoom { [Header("References")] - public TreasureRoomBookZone[] zones; public TreasureRoomBookSwitch[] switches; [Header("Prefabs")] public GameObject bookPrefab; public override bool CanOpen() { - var ready = switches.All(s => s.pulled); + var ready = GetDoorStatusValue() == switches.Length; if (ready) { Plugin.logger.LogDebug($"Opening cause all books pulled"); return ready; @@ -40,10 +39,11 @@ namespace ScarletMansion.GamePatch.Components.TreasureRoom { Plugin.logger.LogDebug("HOST: Creating book switches"); switches = new TreasureRoomBookSwitch[3]; - var switchOrdered = zones.Where(z => z != null && z.gameObject.activeInHierarchy).OrderBy(s => randomStream.NextDouble()); + var zones = GetComponentInParent().GetComponentsInChildren(); + var switchOrdered = zones.Where(z => z != null && z.gameObject.activeInHierarchy).OrderBy(s => systemRandom.NextDouble()); var mapPropsContainer = GetMapPropsContainer(); for(var i = 0; i < 3; ++i) { - var result = switchOrdered.ElementAt(i).GetRandomPosition(randomStream); + var result = switchOrdered.ElementAt(i).GetRandomPosition(systemRandom); var bookGameObject = GameObject.Instantiate(bookPrefab, result.position, result.rotation, mapPropsContainer.transform); var networkObject = bookGameObject.GetComponent(); diff --git a/ScarletMansion/ScarletMansion/GamePatch/Components/TreasureRoom/TreasureRoomDoorStatus.cs b/ScarletMansion/ScarletMansion/GamePatch/Components/TreasureRoom/TreasureRoomDoorStatus.cs index fb2b84d..c2f543e 100644 --- a/ScarletMansion/ScarletMansion/GamePatch/Components/TreasureRoom/TreasureRoomDoorStatus.cs +++ b/ScarletMansion/ScarletMansion/GamePatch/Components/TreasureRoom/TreasureRoomDoorStatus.cs @@ -11,6 +11,9 @@ namespace ScarletMansion.GamePatch.Components.TreasureRoom { public GameObject[] doorStatusTargets; public TreasureRoom treasureRoom; + public AudioSource audioSource; + + private int previousCount; [ClientRpc] public void UpdateDoorStatusClientRpc(int count) { @@ -24,6 +27,12 @@ namespace ScarletMansion.GamePatch.Components.TreasureRoom { doorStatusTargets[i].SetActive(false); ++i; } + + if (count > previousCount) { + audioSource.PlayOneShot(audioSource.clip); + } + + previousCount = count; } } diff --git a/ScarletMansion/ScarletMansion/GamePatch/Components/TreasureRoom/TreasureRoomPaintingGrabEvent.cs b/ScarletMansion/ScarletMansion/GamePatch/Components/TreasureRoom/TreasureRoomPaintingGrabEvent.cs index 0a2fed1..a30ac0a 100644 --- a/ScarletMansion/ScarletMansion/GamePatch/Components/TreasureRoom/TreasureRoomPaintingGrabEvent.cs +++ b/ScarletMansion/ScarletMansion/GamePatch/Components/TreasureRoom/TreasureRoomPaintingGrabEvent.cs @@ -27,13 +27,15 @@ namespace ScarletMansion.GamePatch.Components.TreasureRoom { protected override void LockTreasureDoor(List doorways) { base.LockTreasureDoor(doorways); - var bedroomEvent = GetComponentInParent().GetComponentInChildren(true); + var bedroomEvent = GetComponentInParent().GetComponentInChildren(); + var globalProp = bedroomEvent.GetComponentInChildren(true); + globalProp.gameObject.SetActive(true); Plugin.logger.LogDebug("Moving vent to inside of the treasure room"); var firstDoorway = doorways.FirstOrDefault(); var treasureRoomCenterTransform = firstDoorway.ConnectedDoorway.Tile.transform; var bedroomEventVent = bedroomEvent.vent.transform; - Plugin.logger.LogInfo($"{bedroomEventVent.position} -> {treasureRoomCenterTransform.position}"); + Plugin.logger.LogDebug($"{bedroomEventVent.position} -> {treasureRoomCenterTransform.position}"); bedroomEventVent.position = treasureRoomCenterTransform.position; bedroomEventVent.rotation = treasureRoomCenterTransform.rotation; @@ -42,7 +44,7 @@ namespace ScarletMansion.GamePatch.Components.TreasureRoom { // grab random painting to use var paintingTransform = bedroomEvent.paintingSpawnTransform; - var allPaintings = FindObjectsOfType(); + var allPaintings = ScarletGenericManager.Instance.paintings; var firstAvailablePainting = allPaintings.Where(p => !p.grabbedByEvent) .OrderBy(p => Vector3.SqrMagnitude(paintingTransform.position - p.transform.position)) .FirstOrDefault(); diff --git a/ScarletMansion/ScarletMansion/GamePatch/Components/TreasureRoom/TreasureRoomRadioEvent.cs b/ScarletMansion/ScarletMansion/GamePatch/Components/TreasureRoom/TreasureRoomRadioEvent.cs new file mode 100644 index 0000000..da83ea0 --- /dev/null +++ b/ScarletMansion/ScarletMansion/GamePatch/Components/TreasureRoom/TreasureRoomRadioEvent.cs @@ -0,0 +1,120 @@ +using DunGen; +using ScarletMansion.GamePatch.Managers; +using ScarletMansion.GamePatch.Props; +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.TreasureRoom { + public class TreasureRoomRadioEvent : TreasureRoom { + + [Header("References")] + public Transform radioParentTransform; + public ScarletRadio radio; + + private int selectedAudioIndex; + private int selectedVolume; + + public override bool CanOpen() { + var ready = GetDoorStatusValue() == 3; + if (ready) { + Plugin.logger.LogDebug($"Opening cause radio all setup"); + return ready; + } + return false; + } + + public override int GetDoorStatusValue() { + if (radio == null) return 3; + + var count = 0; + if (radio.playing) count++; + if (radio.audioIndex == selectedAudioIndex) count++; + if (radio.volume == selectedVolume) count++; + return count; + } + + private IEnumerable GetChildren(Transform parent){ + foreach(Transform child in parent){ + yield return child; + } + } + + protected override void OnTreasureRoomSetup(bool hasTreasureRoom) { + + var randomStream = DunGenPatch.Patch.GetRandomStream(); + var randomProps = GetChildren(radioParentTransform).Where(t => t.gameObject.activeSelf).ToArray(); + Utility.Shuffle(randomStream, randomProps); + + var spawnedRadioProp = false; + foreach(var parentTransform in randomProps) { + var prop = parentTransform.GetComponentInChildren(); + + if (hasTreasureRoom) { + if (!spawnedRadioProp) { + prop.ProcessIndex(randomStream, 0); + spawnedRadioProp = true; + } else { + prop.ProcessSkipCount(randomStream, 1); + } + } else { + prop.Process(randomStream, null); + } + + // so the children get the process prop cycling as well + DunGenPatch.Patch.generatorInstance.ProcessProps(null, prop.transform.GetChild(0).gameObject); + } + + // hack so i can set up the SpawnSycnedObject myself + if (hasTreasureRoom) { + radioParentTransform.gameObject.SetActive(false); + } + } + + protected override void LockTreasureDoor(List doorways) { + base.LockTreasureDoor(doorways); + + radioParentTransform.gameObject.SetActive(true); + + if (StartOfRound.Instance.IsHost) { + + Plugin.logger.LogDebug("HOST: Creating scarlet radio"); + + var mapPropsContainer = GetMapPropsContainer(); + var ssoList = radioParentTransform.GetComponentsInChildren(); + foreach(var sso in ssoList) { + var ssoGameobject = GameObject.Instantiate(sso.spawnPrefab, sso.transform.position, sso.transform.rotation, mapPropsContainer.transform); + var networkObject = ssoGameobject.GetComponent(); + + Plugin.logger.LogDebug($"Spawned {ssoGameobject.name}"); + + var r = ssoGameobject.GetComponentInChildren(); + if (r != null) { + radio = r; + radio.treasureRoomEvent = this; + } + + networkObject.Spawn(true); + } + + if (radio == null) { + Plugin.logger.LogError($"Somehow didn't spawn a scarlet radio. Not really expected but the world won't explode"); + return; + } + + selectedAudioIndex = UnityEngine.Random.Range(0, radio.audioClips.Length); + selectedVolume = UnityEngine.Random.Range(1, 11); + CreateDoorStatuses(doorways); + + UpdateTreasureDoorStatus(); + + Plugin.logger.LogDebug($"HOST: Radio combination is song index {selectedAudioIndex} and volume {selectedVolume}"); + } + } + + } +} diff --git a/ScarletMansion/ScarletMansion/GamePatch/Components/TreasureRoom/TreasureRoomTimeEvent.cs b/ScarletMansion/ScarletMansion/GamePatch/Components/TreasureRoom/TreasureRoomTimeEvent.cs index 2713007..2c67a8f 100644 --- a/ScarletMansion/ScarletMansion/GamePatch/Components/TreasureRoom/TreasureRoomTimeEvent.cs +++ b/ScarletMansion/ScarletMansion/GamePatch/Components/TreasureRoom/TreasureRoomTimeEvent.cs @@ -36,25 +36,14 @@ namespace ScarletMansion.GamePatch.Components.TreasureRoom { protected override void LockTreasureDoor(List doorways) { base.LockTreasureDoor(doorways); - hourSelected = randomStream.Next(hourRange.x, hourRange.y); - mintuesSelected = randomStream.Next(0, 3) * 15; + hourSelected = systemRandom.Next(hourRange.x, hourRange.y); + mintuesSelected = systemRandom.Next(0, 3) * 15; Plugin.logger.LogDebug($"Opening at {hourSelected}:{mintuesSelected:D2}"); - timeClockSpawnTransformIndex = randomStream.Next(timeClockSpawnTransforms.Length); + timeClockSpawnTransformIndex = systemRandom.Next(timeClockSpawnTransforms.Length); var parent = timeClockSpawnTransforms[timeClockSpawnTransformIndex]; var copy = Instantiate(timeClockPrefab, parent); - if (StartOfRound.Instance.IsHost) { - Plugin.logger.LogDebug("HOST: Creating clock"); - - var spawnSyncedObject = copy.GetComponentInChildren(); - var mapPropsContainer = GetMapPropsContainer(); - var spawnedObject = Instantiate(spawnSyncedObject.spawnPrefab, spawnSyncedObject.transform.position, spawnSyncedObject.transform.rotation, mapPropsContainer.transform); - - var networkObject = spawnedObject.GetComponent(); - networkObject.Spawn(true); - } - var textMesh = copy.GetComponentInChildren(); textMesh.text = $"{hourSelected}:{mintuesSelected:D2}"; RandomizeCharacters(textMesh); diff --git a/ScarletMansion/ScarletMansion/GamePatch/Enemies/KnightGhostVariant.cs b/ScarletMansion/ScarletMansion/GamePatch/Enemies/KnightGhostVariant.cs index ff16dd9..797ce72 100644 --- a/ScarletMansion/ScarletMansion/GamePatch/Enemies/KnightGhostVariant.cs +++ b/ScarletMansion/ScarletMansion/GamePatch/Enemies/KnightGhostVariant.cs @@ -82,8 +82,11 @@ namespace ScarletMansion { playerControllerB.DamagePlayer(damage, true, true, CauseOfDeath.Mauling, 1, false, default(Vector3)); playerControllerB.JumpToFearLevel(1f, true); - RoundManager.PlayRandomClip(creatureVoice, ramAudioClips, false, 1f, 0); + if (playerControllerB.isPlayerDead) { + Assets.onPlayerDeath.Call(new ModPatch.CoronerParameters(playerControllerB, ModPatch.CoronerDeathEnum.GhostKnight)); + } + RoundManager.PlayRandomClip(creatureVoice, ramAudioClips, false, 1f, 0); CallDisappear(); } } diff --git a/ScarletMansion/ScarletMansion/GamePatch/Enemies/KnightV2Variant.cs b/ScarletMansion/ScarletMansion/GamePatch/Enemies/KnightV2Variant.cs index fbf9c57..3c95243 100644 --- a/ScarletMansion/ScarletMansion/GamePatch/Enemies/KnightV2Variant.cs +++ b/ScarletMansion/ScarletMansion/GamePatch/Enemies/KnightV2Variant.cs @@ -423,6 +423,10 @@ namespace ScarletMansion.GamePatch.Enemies { playerControllerB.JumpToFearLevel(1f, true); timeSinceHittingPlayer = Time.realtimeSinceStartup; + if (playerControllerB.isPlayerDead) { + Assets.onPlayerDeath.Call(new ModPatch.CoronerParameters(playerControllerB, ModPatch.CoronerDeathEnum.Knight)); + } + SetCoilheadOnCooldownServerRpc(5f); } } diff --git a/ScarletMansion/ScarletMansion/GamePatch/Enemies/MaidVariant.cs b/ScarletMansion/ScarletMansion/GamePatch/Enemies/MaidVariant.cs index 08627f8..8b15a7e 100644 --- a/ScarletMansion/ScarletMansion/GamePatch/Enemies/MaidVariant.cs +++ b/ScarletMansion/ScarletMansion/GamePatch/Enemies/MaidVariant.cs @@ -1189,6 +1189,10 @@ namespace ScarletMansion.GamePatch.Enemies { berserkModeTimer = 3f; } playerControllerB.DamagePlayer(50, true, true, CauseOfDeath.Stabbing, 0, false); + if (playerControllerB.isPlayerDead) { + Assets.onPlayerDeath.Call(new ModPatch.CoronerParameters(playerControllerB, ModPatch.CoronerDeathEnum.Maid)); + } + StabPlayerServerRpc((int)playerControllerB.playerClientId, currentBehaviourStateIndex != 2); } } diff --git a/ScarletMansion/ScarletMansion/GamePatch/Items/ScarletKnife.cs b/ScarletMansion/ScarletMansion/GamePatch/Items/ScarletKnife.cs index 5b71442..c9407c5 100644 --- a/ScarletMansion/ScarletMansion/GamePatch/Items/ScarletKnife.cs +++ b/ScarletMansion/ScarletMansion/GamePatch/Items/ScarletKnife.cs @@ -134,11 +134,22 @@ namespace ScarletMansion.GamePatch.Items } target.Hit(damage, forward, previousPlayerHeldBy, playHitSFX: true); + + var playerComponent = target as PlayerControllerB; + if (playerComponent && playerComponent.isPlayerDead) { + Assets.onPlayerDeath.Call(new ModPatch.CoronerParameters(playerComponent, ModPatch.CoronerDeathEnum.KnifeFriendlyFire)); + } + UnBuffShovelServerRpc(); } // normal knife else { component.Hit(knifeHitForce, forward, previousPlayerHeldBy, playHitSFX: true); + + var playerComponent = component as PlayerControllerB; + if (playerComponent && playerComponent.isPlayerDead) { + Assets.onPlayerDeath.Call(new ModPatch.CoronerParameters(playerComponent, ModPatch.CoronerDeathEnum.Knife)); + } } bloodParticle.Play(withChildren: true); @@ -166,7 +177,7 @@ namespace ScarletMansion.GamePatch.Items public int GetDamageToPlayer(PlayerControllerB player) { var scarletPlayer = ScarletPlayerControllerB.GetScarletPlayerScript(player); - if (scarletPlayer == null) return 85; + if (scarletPlayer == null) return 95; var forceKill = scarletPlayer.stabbedSelf; scarletPlayer.stabbedSelf = true; @@ -209,8 +220,13 @@ namespace ScarletMansion.GamePatch.Items yield return new WaitForSeconds(0.25f); var damage = GetDamageToPlayer(player); + Plugin.logger.LogInfo(damage); player.DamagePlayer(damage, true, true, CauseOfDeath.Stabbing); + if (player.isPlayerDead) { + Assets.onPlayerDeath.Call(new ModPatch.CoronerParameters(player, ModPatch.CoronerDeathEnum.KnifeFeed)); + } + bloodParticle.Play(withChildren: true); RoundManager.PlayRandomClip(knifeAudio, hitSFX); diff --git a/ScarletMansion/ScarletMansion/GamePatch/Items/ScarletPainting.cs b/ScarletMansion/ScarletMansion/GamePatch/Items/ScarletPainting.cs index 5ad303a..6f165f6 100644 --- a/ScarletMansion/ScarletMansion/GamePatch/Items/ScarletPainting.cs +++ b/ScarletMansion/ScarletMansion/GamePatch/Items/ScarletPainting.cs @@ -1,4 +1,5 @@ using System; +using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; @@ -39,18 +40,21 @@ namespace ScarletMansion.GamePatch.Items { public override void LoadItemSaveData(int saveData) { base.LoadItemSaveData(saveData); variation = saveData; - - mainObjectRenderer.material = variationMaterials[variation]; - transform.rotation = Quaternion.Euler(itemProperties.restingRotation); // why zeekers + mainObjectRenderer.material = variationMaterials[variation]; } public override void Start() { base.Start(); if (isAttached){ - bedroom = AngerManager.Instance.GetBedroomWithPainting(transform.position); + var manager = ScarletGenericManager.Instance; + manager.AddPainting(this); + bedroom = manager.GetBedroomWithPainting(transform.position); + scrapValue = PluginConfig.Instance.paintingValueValue; grabbedByEvent = false; + } else { + transform.rotation = Quaternion.Euler(itemProperties.restingRotation); // why zeekers } } @@ -67,8 +71,10 @@ namespace ScarletMansion.GamePatch.Items { [ClientRpc] public void RepositionClientRpc(Vector3 position, Quaternion rotation){ transform.position = position; + targetFloorPosition = transform.localPosition; + transform.rotation = rotation; - bedroom = AngerManager.Instance.GetBedroomWithPainting(position); + bedroom = ScarletGenericManager.Instance.GetBedroomWithPainting(position); grabbedByEvent = true; } diff --git a/ScarletMansion/ScarletMansion/GamePatch/Managers/AngerManager.cs b/ScarletMansion/ScarletMansion/GamePatch/Managers/AngerManager.cs index b4d91f9..a5fb8fe 100644 --- a/ScarletMansion/ScarletMansion/GamePatch/Managers/AngerManager.cs +++ b/ScarletMansion/ScarletMansion/GamePatch/Managers/AngerManager.cs @@ -5,86 +5,22 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using UnityEngine; -using UnityEngine.InputSystem; -using UnityEngine.InputSystem.Controls; -using HarmonyLib; -using Unity.Netcode; using ScarletMansion.GamePatch.Components; using DunGen; -using Key = UnityEngine.InputSystem.Key; using ScarletMansion.Lights; -using UnityEngine.Rendering; -using UnityEngine.Rendering.HighDefinition; +using DunGenPlus.Managers; namespace ScarletMansion.GamePatch.Managers { public class AngerManager : MonoBehaviour, IDungeonCompleteReceiver { public static AngerManager Instance { get; private set; } - //public Dictionary angeredEnemies; public int level; - public List roomsOfInterest; - public List bedrooms; - - public List doors; - public List lights; - - //public KeyboardFloatDebug metal = new KeyboardFloatDebug("metal", 0f, 0f, 1f, 0.1f, Key.Numpad4, Key.Numpad7); - //public KeyboardFloatDebug smooth = new KeyboardFloatDebug("smooth", 0f, 0f, 1f, 0.1f, Key.Numpad6, Key.Numpad9); - void Awake(){ Instance = this; - - roomsOfInterest = new List(); - bedrooms = new List(); - doors = new List(); - lights = new List(); } - /* - void Update(){ - var enabled = 0; - var active = 0; - var total = 0; - foreach(var l in lights){ - if (l.enabled) enabled++; - if (l.gameObject.activeInHierarchy) active++; - total++; - } - Plugin.logger.LogInfo($"{enabled}|{active}/{total}"); - } - */ - /* - void Update(){ - var deltaIntensity = 0; - if (Utility.IfKeyPress(Key.Numpad7)) { - deltaIntensity = 1; - } else if (Utility.IfKeyPress(Key.Numpad4)) { - deltaIntensity = -1; - } - - var deltaRange = 0; - if (Utility.IfKeyPress(Key.Numpad9)) { - deltaRange = 1; - } else if (Utility.IfKeyPress(Key.Numpad6)) { - deltaRange = -1; - } - - if (deltaIntensity != 0 || deltaRange != 0){ - var tile = Utility.GetClosestTileToPlayer(); - var lights = tile.GetComponentsInChildren(); - var localPlayer = StartOfRound.Instance.localPlayerController.transform.position; - var closestLight = lights.OrderBy(t => Vector3.SqrMagnitude(t.transform.position - localPlayer)).FirstOrDefault(); - if (closestLight != null) { - closestLight.light.intensity += deltaIntensity * 0.5f; - closestLight.light.range += deltaRange * 0.25f; - - Plugin.logger.LogInfo($"{closestLight.light.intensity}, {closestLight.light.range}"); - } - } - } - */ public void Anger(int angerAmount = 1){ Plugin.logger.LogDebug($"Raising anger from {level} to {level + angerAmount}"); var manager = RoundManager.Instance; @@ -92,72 +28,7 @@ namespace ScarletMansion.GamePatch.Managers { level += angerAmount; } - public void AddBedroom(ScarletBedroom b){ - 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 t in roomsOfInterest){ - var dist = Vector3.SqrMagnitude(d.transform.position - t.position); - if (dist < 24f * 24f){ - doors.Add(d); - return; - } - } - } - - public ScarletBedroom GetBedroomWithPainting(Vector3 basePosition){ - ScarletBedroom target = null; - var dist = 1f; - - foreach(var b in bedrooms){ - var newdist = Vector3.SqrMagnitude(basePosition - b.paintingSpawnTransform.position); - if (newdist < dist){ - target = b; - dist = newdist; - } - } - - if (target == null){ - Plugin.logger.LogError($"There is no close bedroom painting spawn at {basePosition}"); - return null; - } - - //Plugin.logger.LogInfo($"Closest bedroom painting spawn {dist} away"); - return target; - } - - public ScarletDoor GetScarletDoor(Vector3 basePosition){ - ScarletDoor target = null; - var dist = 1f; - - foreach(var b in doors){ - var newdist = Vector3.SqrMagnitude(basePosition - b.transform.position); - if (newdist < dist){ - target = b; - dist = newdist; - } - } - - if (target == null){ - Plugin.logger.LogError($"There is no close door spawn at {basePosition}"); - return null; - } - - //Plugin.logger.LogInfo($"Closest door spawn {dist} away"); - return target; - } - - public void AddLight(ScarletLight light){ - lights.Add(light); - } - - public ItemReference[] CreateAngerLoot(int count, System.Random sysRandom){ + public static ItemReference[] CreateAngerLoot(int count, System.Random sysRandom){ var roundManager = RoundManager.Instance; if (!roundManager.IsServer) return null; @@ -185,7 +56,7 @@ namespace ScarletMansion.GamePatch.Managers { return bonusItems; } - public void SpawnAngerLoot(ItemReference[] loot, Transform[] spawnTransforms){ + public static void SpawnAngerLoot(ItemReference[] loot, Transform[] spawnTransforms){ var roundManager = RoundManager.Instance; if (loot == null) { @@ -206,61 +77,17 @@ namespace ScarletMansion.GamePatch.Managers { } public void TriggerAngerLightBrief(float duration){ - foreach(var s in lights){ - s.BeginAngry(duration, false); + foreach(var s in ScarletGenericManager.Instance.lights){ + s.SetColorState(ScarletLight.ColorState.TemporaryRed); } } public void TriggerAngerLightForever(){ - foreach(var s in lights){ - s.BeginAngry(0f, true); + foreach(var s in ScarletGenericManager.Instance.lights){ + s.SetColorState(ScarletLight.ColorState.Red); } } - /* - public void Anger(){ - level += 1; - var manager = RoundManager.Instance; - - var enemies = manager.SpawnedEnemies; - foreach(var e in enemies){ - // only inside - if (e.enemyType.isDaytimeEnemy || e.isOutside) continue; - - if (!angeredEnemies.ContainsKey(e)) - angeredEnemies.Add(e, 0); - } - - foreach(var e in angeredEnemies.Keys){ - AngerEnemy(e, level - angeredEnemies[e]); - angeredEnemies[e] = level; - } - } - - [ClientRpc] - public void AngerEnemyClientRpc(NetworkBehaviourReference enemyRef, int levelOffset){ - - if (enemyRef.TryGet(out var enemy)){ - if (levelOffset < 1) return; - - var type = enemy.GetType(); - if (type == typeof(BlobAI)){ - Plugin.logger.LogInfo("Can't anger blob yet"); - } - - else { - Plugin.logger.LogInfo($"Angering {type} is not yet supported"); - } - - } - - } - - public void Remove(EnemyAI enemy){ - angeredEnemies.Remove(enemy); - } - - */ } } diff --git a/ScarletMansion/ScarletMansion/GamePatch/Managers/ScarletGenericManager.cs b/ScarletMansion/ScarletMansion/GamePatch/Managers/ScarletGenericManager.cs new file mode 100644 index 0000000..7d929fd --- /dev/null +++ b/ScarletMansion/ScarletMansion/GamePatch/Managers/ScarletGenericManager.cs @@ -0,0 +1,160 @@ +using DunGen; +using DunGenPlus.Managers; +using ScarletMansion.GamePatch.Components; +using ScarletMansion.GamePatch.Items; +using ScarletMansion.Lights; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; + +namespace ScarletMansion.GamePatch.Managers { + public class ScarletGenericManager : MonoBehaviour, IDungeonCompleteReceiver { + + public static ScarletGenericManager Instance { get; private set; } + + public List roomsOfInterest; + public List bedrooms; + + public List paintings; + + public List doors; + public List lights; + + public ScarletBookPath[] bookPaths; + + public List selfDestroyTargets; + private int lastHour; + + void Awake(){ + Instance = this; + + roomsOfInterest = new List(); + bedrooms = new List(); + + paintings = new List(); + + doors = new List(); + lights = new List(); + } + + void Update(){ + if (!StartOfRound.Instance.IsServer) return; + + var time = Utility.GetTime(); + var hours = time.hours; + var hourChanged = lastHour != hours; + + if (!hourChanged) return; + + Plugin.logger.LogDebug($"New hour: {hours}"); + for (var i = 0; i < selfDestroyTargets.Count; i++){ + var t = selfDestroyTargets[i]; + var index = i; + if (!t.IsDestroyed && UnityEngine.Random.value < t.Chance) { + t.PreDestroy(); + StartCoroutine(DelayDestroy(t, index, UnityEngine.Random.Range(0f, 60f))); + } + } + + lastHour = hours; + } + + private IEnumerator DelayDestroy(IScarletSelfDestroy target, int index, float delay){ + Plugin.logger.LogDebug($"{target} destroying itself in {delay} sec"); + yield return new WaitForSeconds(delay); + ScarletNetworkManager.Instance.CallSelfDestroyTargetClientRpc(index); + } + + public void AddBedroom(ScarletBedroom b){ + bedrooms.Add(b); + } + + public void AddPainting(ScarletPainting painting){ + paintings.Add(painting); + } + + public void AddRoomOfInterest(Transform t) { + roomsOfInterest.Add(t); + } + + public void AddDoor(ScarletDoor d){ + // I want to get only doors that are revelant + foreach(var t in roomsOfInterest){ + var dist = Vector3.SqrMagnitude(d.transform.position - t.position); + if (dist < 24f * 24f){ + doors.Add(d); + return; + } + } + } + + public ScarletBedroom GetBedroomWithPainting(Vector3 basePosition){ + ScarletBedroom target = null; + var dist = 1f; + + foreach(var b in bedrooms){ + var newdist = Vector3.SqrMagnitude(basePosition - b.paintingSpawnTransform.position); + if (newdist < dist){ + target = b; + dist = newdist; + } + } + + if (target == null){ + Plugin.logger.LogError($"There is no close bedroom painting spawn at {basePosition}"); + return null; + } + + //Plugin.logger.LogInfo($"Closest bedroom painting spawn {dist} away"); + return target; + } + + public ScarletDoor GetScarletDoor(Vector3 basePosition){ + ScarletDoor target = null; + var dist = 1f; + + foreach(var b in doors){ + var newdist = Vector3.SqrMagnitude(basePosition - b.transform.position); + if (newdist < dist){ + target = b; + dist = newdist; + } + } + + if (target == null){ + Plugin.logger.LogError($"There is no close door spawn at {basePosition}"); + return null; + } + + //Plugin.logger.LogInfo($"Closest door spawn {dist} away"); + return target; + } + + public void AddLight(ScarletLight light){ + lights.Add(light); + } + + public void OnDungeonComplete(Dungeon dungeon) { + selfDestroyTargets = dungeon.GetComponentsInChildren().ToList(); + bookPaths = dungeon.GetComponentsInChildren(); + + if (StartOfRound.Instance.IsServer){ + DoorwayManager.onMainEntranceTeleportSpawnedEvent.AddTemporaryEvent("BookPaths", () => SetupBookPaths()); + } + } + + private void SetupBookPaths(){ + StartCoroutine(SetupBookPathsDelay(5f)); + } + + private IEnumerator SetupBookPathsDelay(float delay){ + yield return new WaitForSecondsRealtime(delay); + ScarletNetworkManager.Instance.SetupBookPathsClientRpc(); + } + + } +} diff --git a/ScarletMansion/ScarletMansion/GamePatch/Managers/ScarletNetworkManager.cs b/ScarletMansion/ScarletMansion/GamePatch/Managers/ScarletNetworkManager.cs index 6cae2d3..d088ef0 100644 --- a/ScarletMansion/ScarletMansion/GamePatch/Managers/ScarletNetworkManager.cs +++ b/ScarletMansion/ScarletMansion/GamePatch/Managers/ScarletNetworkManager.cs @@ -11,6 +11,7 @@ using ScarletMansion.GamePatch.Items; using ScarletMansion.GamePatch; using ScarletMansion.GamePatch.Components; using static LethalLevelLoader.ExtendedEvent; +using ScarletMansion.GamePatch.Managers; namespace ScarletMansion { @@ -325,13 +326,30 @@ namespace ScarletMansion { Destroy(copy, 5f); } + [ClientRpc] + public void SetupBookPathsClientRpc(){ + if (ScarletGenericManager.Instance == null) return; + + var bookPaths = ScarletGenericManager.Instance.bookPaths; + foreach(var b in bookPaths) { + b.ResetPath(); + } + } + + [ClientRpc] + public void CallSelfDestroyTargetClientRpc(int index){ + if (ScarletGenericManager.Instance == null) return; + + ScarletGenericManager.Instance.selfDestroyTargets[index].Destroy(); + } + } public static class ScarletNetworkManagerUtility { public static int GetCriticalDamageToPlayer(PlayerControllerB player, bool forceKill) { - if (player.health > 20 && !forceKill) { - return player.health - 15; + if (!player.criticallyInjured && !forceKill) { + return player.health - 5; } return player.health; } diff --git a/ScarletMansion/ScarletMansion/GamePatch/Props/RandomPrefabBasic.cs b/ScarletMansion/ScarletMansion/GamePatch/Props/RandomPrefabBasic.cs index a8fae12..790a9da 100644 --- a/ScarletMansion/ScarletMansion/GamePatch/Props/RandomPrefabBasic.cs +++ b/ScarletMansion/ScarletMansion/GamePatch/Props/RandomPrefabBasic.cs @@ -16,8 +16,24 @@ namespace ScarletMansion.GamePatch.Props { var prefab = props[value]; SpawnGameObject(randomStream, prefab); - } + + public void ProcessIndex(RandomStream randomStream, int index){ + if (index >= props.Count) return; + var prefab = props[index]; + + SpawnGameObject(randomStream, prefab); + } + + public void ProcessSkipCount(RandomStream randomStream, int count){ + if (count >= props.Count) return; + + var index = randomStream.Next(count, props.Count); + var prefab = props[index]; + + SpawnGameObject(randomStream, prefab); + } + } } diff --git a/ScarletMansion/ScarletMansion/GamePatch/Props/RandomPrefabBasicBase.cs b/ScarletMansion/ScarletMansion/GamePatch/Props/RandomPrefabBasicBase.cs index 002e96f..a16a803 100644 --- a/ScarletMansion/ScarletMansion/GamePatch/Props/RandomPrefabBasicBase.cs +++ b/ScarletMansion/ScarletMansion/GamePatch/Props/RandomPrefabBasicBase.cs @@ -11,12 +11,24 @@ namespace ScarletMansion.GamePatch.Props { public List props = new List(); + [Header("Randomizer")] public bool randomizePosition = false; public float randomPositionRange = 0f; public bool randomizeRotation = true; public FloatRange randomRotationRange = new FloatRange(0f, 360f); + [Header("Special Logic")] + public bool skipNextSpawn; + public void SpawnGameObject(RandomStream randomStream, GameObject prefab){ + // I really hate that I have to do this + // but DungeonGenerator.ProcessProps() goes through every RandomProp regardless if the gameobject is active or not + // I cannot escape it + if (skipNextSpawn) { + skipNextSpawn = false; + return; + } + var gameObject = GameObject.Instantiate(prefab); var gameObjectTransform = gameObject.transform; gameObjectTransform.parent = transform; @@ -37,6 +49,7 @@ namespace ScarletMansion.GamePatch.Props { } } + public void OnDrawGizmosSelected(){ if (randomizePosition) { Utility.DrawGizmoCircle(transform, randomPositionRange, Color.green); diff --git a/ScarletMansion/ScarletMansion/ModPatch/CoronerParameters.cs b/ScarletMansion/ScarletMansion/ModPatch/CoronerParameters.cs new file mode 100644 index 0000000..b720358 --- /dev/null +++ b/ScarletMansion/ScarletMansion/ModPatch/CoronerParameters.cs @@ -0,0 +1,29 @@ +using GameNetcodeStuff; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ScarletMansion.ModPatch { + public enum CoronerDeathEnum { + Knight, + Maid, + Void, + GhostKnight, + Knife, + KnifeFeed, + KnifeFriendlyFire + } + + public struct CoronerParameters { + public PlayerControllerB player; + public CoronerDeathEnum death; + + public CoronerParameters(PlayerControllerB player, CoronerDeathEnum death){ + this.player = player; + this.death = death; + } + } + +} diff --git a/ScarletMansion/ScarletMansion/ModPatch/ModCompability.cs b/ScarletMansion/ScarletMansion/ModPatch/ModCompability.cs index a1f1940..0f411d1 100644 --- a/ScarletMansion/ScarletMansion/ModPatch/ModCompability.cs +++ b/ScarletMansion/ScarletMansion/ModPatch/ModCompability.cs @@ -20,7 +20,7 @@ namespace ScarletMansion.ModPatch { new LethalConfigPatch(lethalConfigGuid), new FacilityMeltdownPatch(facilityMeldownGuid), new ReservedFlashlightPatch(reserveFlashlightGuid), - new ReservedKeyPatch(reserveKeyGuid), + new ReservedKeyPatch(reserveKeyGuid) }; diff --git a/ScarletMansion/ScarletMansion/Plugin.cs b/ScarletMansion/ScarletMansion/Plugin.cs index 7350507..1bb495c 100644 --- a/ScarletMansion/ScarletMansion/Plugin.cs +++ b/ScarletMansion/ScarletMansion/Plugin.cs @@ -23,7 +23,7 @@ namespace ScarletMansion { [BepInDependency("imabatby.lethallevelloader", "1.2.0.3")] [BepInDependency("evaisa.lethallib", "0.13.2")] - [BepInDependency("dev.ladyalice.dungenplus", "1.1.0")] + [BepInDependency("dev.ladyalice.dungenplus", "1.1.2")] //[BepInDependency(ModCompability.advancedCompanyGuid, BepInDependency.DependencyFlags.SoftDependency)] [BepInDependency(ModCompability.lethalConfigGuid, BepInDependency.DependencyFlags.SoftDependency)] @@ -34,7 +34,7 @@ namespace ScarletMansion { public class Plugin : BaseUnityPlugin { public const string modGUID = "dev.ladyalice.scarletmansion"; private const string modName = "Scarlet Mansion"; - private const string modVersion = "1.3.26"; + private const string modVersion = "1.3.27"; public readonly Harmony harmony = new Harmony(modGUID); @@ -92,6 +92,7 @@ namespace ScarletMansion { sdmLevelMatchProperties.planetNames.Add(new StringWithRarity("Rend", 300)); sdmLevelMatchProperties.planetNames.Add(new StringWithRarity("Titan", 69)); sdmLevelMatchProperties.planetNames.Add(new StringWithRarity("Sanguine", 900)); + sdmLevelMatchProperties.planetNames.Add(new StringWithRarity("Scarlet Devil Mansion", 900)); var extendedContent = new List(); diff --git a/ScarletMansion/ScarletMansion/PluginConfig.cs b/ScarletMansion/ScarletMansion/PluginConfig.cs index b88e66a..174a1dd 100644 --- a/ScarletMansion/ScarletMansion/PluginConfig.cs +++ b/ScarletMansion/ScarletMansion/PluginConfig.cs @@ -473,8 +473,8 @@ namespace ScarletMansion { public static ConfigEntryBundle hallwayLightsWeight = new ConfigEntryBundle( dungeonLightingPrefix, "Hallway Lights Weight", - 75, - "The weight for a hallway wall lamp to appear on its respective walls. With the default weight of 75 against the weight of the empty wall of 75, there is a 50% chance that a wall lamp will spawn. Increasing the weight to 225 will give you a 75% chance, 675=90% chance, and so on.", + 150, + "The weight for a hallway wall lamp to appear on its respective walls. With the default weight of 150 against the weight of the empty wall of 50, there is a 75% chance that a wall lamp will spawn. Setting the weight to 100 will give you a 67% chance, 450=90% chance, and so on.", null, new AcceptableValueRange(0, 999) ); @@ -482,8 +482,8 @@ namespace ScarletMansion { public static ConfigEntryBundle ceilingLightsWeight = new ConfigEntryBundle( dungeonLightingPrefix, "Chandelier Lights Weight", - 75, - "The weight for a chandelier to appear on its respective ceilings. With the default weight of 75 against the weight of the empty ceiling of 75, there is a 50% chance that a chandelier will spawn. Increasing the weight to 225 will give you a 75% chance, 675=90% chance, and so on.", + 150, + "The weight for a chandelier to appear on its respective ceilings. With the default weight of 150 against the weight of the empty ceiling of 50, there is a 75% chance that a chandelier will spawn. Setting the weight to 100 will give you a 67% chance, 450=90% chance, and so on.", null, new AcceptableValueRange(0, 999) ); @@ -491,8 +491,8 @@ namespace ScarletMansion { public static ConfigEntryBundle lightsSpawnZeroWeight = new ConfigEntryBundle( dungeonLightingPrefix, "0 Lights Weight", - 2, - "The weight that none of the spawned light sources (desk lamps, wall lamps, chandeliers) in a given tile will emit light. With the default weight spread of [2, 7, 1], there is a 20% chance that even in a room filled with lamps, none of them will emit light.", + 1, + "The weight that none of the spawned light sources (desk lamps, wall lamps, chandeliers) in a given tile will emit light. With the default weight spread of [1, 7, 2], there is a 10% chance that even in a room filled with lamps, none of them will emit light.", new ConfigEntryBundleExtraParameters(VerifyLightingValues, false), new AcceptableValueRange(0, 99) ); @@ -501,7 +501,7 @@ namespace ScarletMansion { dungeonLightingPrefix, "1 Light Weight", 7, - "The weight that only 1 of the spawned light sources (desk lamps, wall lamps, chandeliers) in a given tile will emit light. With the default weight spread of [2, 7, 1], there is a 70% chance that even in a room filled with lamps, only one of them will emit light.", + "The weight that only 1 of the spawned light sources (desk lamps, wall lamps, chandeliers) in a given tile will emit light. With the default weight spread of [1, 7, 2], there is a 70% chance that even in a room filled with lamps, only one of them will emit light.", new ConfigEntryBundleExtraParameters(VerifyLightingValues, false), new AcceptableValueRange(0, 99) ); @@ -509,8 +509,8 @@ namespace ScarletMansion { public static ConfigEntryBundle lightsSpawnTwoWeight = new ConfigEntryBundle( dungeonLightingPrefix, "2 Lights Weight", - 1, - "The weight that only 2 of the spawned light sources (desk lamps, wall lamps, chandeliers) in a given tile will emit light. With the default weight spread of [2, 7, 1], there is a 10% chance that even in a room filled with lamps, only two of them will emit light.", + 2, + "The weight that only 2 of the spawned light sources (desk lamps, wall lamps, chandeliers) in a given tile will emit light. With the default weight spread of [1, 7, 2], there is a 20% chance that even in a room filled with lamps, only two of them will emit light.", new ConfigEntryBundleExtraParameters(VerifyLightingValues, true), new AcceptableValueRange(0, 99) ); diff --git a/ScarletMansion/ScarletMansion/PresetConfig.cs b/ScarletMansion/ScarletMansion/PresetConfig.cs index 278db26..f2c09aa 100644 --- a/ScarletMansion/ScarletMansion/PresetConfig.cs +++ b/ScarletMansion/ScarletMansion/PresetConfig.cs @@ -129,7 +129,7 @@ namespace ScarletMansion { Dark } - // 2, 7, 1 + // 1, 8, 2 public static ChangeList defaultLighting = new ChangeList( "Default", "The default lighting values.", @@ -145,10 +145,10 @@ namespace ScarletMansion { public static ChangeList brightLighting = new ChangeList( "Bright", "Makes light sources much more common.", - new ChangeInt ( PluginConfig.hallwayLightsWeight, 225 ), - new ChangeInt ( PluginConfig.ceilingLightsWeight, 225 ), - new ChangeInt ( PluginConfig.lightsSpawnZeroWeight, 1 ), - new ChangeInt ( PluginConfig.lightsSpawnOneWeight, 6 ), + new ChangeInt ( PluginConfig.hallwayLightsWeight, 450 ), + new ChangeInt ( PluginConfig.ceilingLightsWeight, 450 ), + new ChangeInt ( PluginConfig.lightsSpawnZeroWeight, 0 ), + new ChangeInt ( PluginConfig.lightsSpawnOneWeight, 7 ), new ChangeInt ( PluginConfig.lightsSpawnTwoWeight, 3 ) //new ChangeInt ( PluginConfig.lightsSpawnThreeWeight, 2 ) ); @@ -156,10 +156,10 @@ namespace ScarletMansion { public static ChangeList darkLighting = new ChangeList( "Dark", "Makes light sources much less common.", - new ChangeInt ( PluginConfig.hallwayLightsWeight, 25 ), - new ChangeInt ( PluginConfig.ceilingLightsWeight, 25 ), - new ChangeInt ( PluginConfig.lightsSpawnZeroWeight, 3 ), - new ChangeInt ( PluginConfig.lightsSpawnOneWeight, 7 ), + new ChangeInt ( PluginConfig.hallwayLightsWeight, 50 ), + new ChangeInt ( PluginConfig.ceilingLightsWeight, 50 ), + new ChangeInt ( PluginConfig.lightsSpawnZeroWeight, 2 ), + new ChangeInt ( PluginConfig.lightsSpawnOneWeight, 8 ), new ChangeInt ( PluginConfig.lightsSpawnTwoWeight, 0 ) //new ChangeInt ( PluginConfig.lightsSpawnThreeWeight, 0 ) ); diff --git a/ScarletMansion/ScarletMansion/ScarletMansion.csproj b/ScarletMansion/ScarletMansion/ScarletMansion.csproj index f28937e..86b5a88 100644 --- a/ScarletMansion/ScarletMansion/ScarletMansion.csproj +++ b/ScarletMansion/ScarletMansion/ScarletMansion.csproj @@ -34,9 +34,6 @@ ..\..\..\Libraries\0Harmony.dll - - ..\..\..\Libraries\AdvancedCompany.dll - ..\..\..\Libraries\Assembly-CSharp-firstpass.dll @@ -154,12 +151,14 @@ + + @@ -177,6 +176,7 @@ + @@ -205,6 +205,7 @@ + @@ -225,6 +226,7 @@ + diff --git a/ScarletMansion/ScarletMansion/Utility.cs b/ScarletMansion/ScarletMansion/Utility.cs index 40b89b4..a04af9b 100644 --- a/ScarletMansion/ScarletMansion/Utility.cs +++ b/ScarletMansion/ScarletMansion/Utility.cs @@ -115,6 +115,31 @@ namespace ScarletMansion { } } + public class ActionList { + public string name; + public List<(string name, Action action)> actionList; + + public ActionList(string name){ + this.name = name; + actionList = new List<(string, Action)>(); + } + + public void AddEvent(string name, Action act){ + actionList.Add((name, act)); + } + + public void Call(T argument){ + foreach(var pair in actionList){ + try { + pair.action.Invoke(argument); + } catch (Exception e) { + Plugin.logger.LogError($"Error with event {name}/{pair.name}"); + Plugin.logger.LogError(e.ToString()); + } + } + } + } + public static class Utility { public static float GetRandomNumber(this System.Random random, double minimum, double maximum) { diff --git a/ScarletMansionCoronerPatch/ScarletMansionCoronerPatch.sln b/ScarletMansionCoronerPatch/ScarletMansionCoronerPatch.sln new file mode 100644 index 0000000..f6d7baf --- /dev/null +++ b/ScarletMansionCoronerPatch/ScarletMansionCoronerPatch.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.10.35122.118 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ScarletMansionCoronerPatch", "ScarletMansionCoronerPatch\ScarletMansionCoronerPatch.csproj", "{CB30B9C8-2679-4C65-86A3-B4680B73DA4F}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {CB30B9C8-2679-4C65-86A3-B4680B73DA4F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CB30B9C8-2679-4C65-86A3-B4680B73DA4F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CB30B9C8-2679-4C65-86A3-B4680B73DA4F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CB30B9C8-2679-4C65-86A3-B4680B73DA4F}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {15C1AA9F-BF3A-43DA-8275-637922601260} + EndGlobalSection +EndGlobal diff --git a/ScarletMansionCoronerPatch/ScarletMansionCoronerPatch/Patch.cs b/ScarletMansionCoronerPatch/ScarletMansionCoronerPatch/Patch.cs new file mode 100644 index 0000000..20286fd --- /dev/null +++ b/ScarletMansionCoronerPatch/ScarletMansionCoronerPatch/Patch.cs @@ -0,0 +1,37 @@ +using Coroner; +using GameNetcodeStuff; +using ScarletMansion.ModPatch; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ScarletMansionCoronerPatch { + public class Patch { + + public static Dictionary causesOfDeath; + + public static void Activate() { + causesOfDeath = new Dictionary(); + + causesOfDeath.Add(CoronerDeathEnum.Knight, AdvancedCauseOfDeath.Build("DeathEnemyKnight")); + causesOfDeath.Add(CoronerDeathEnum.Maid, AdvancedCauseOfDeath.Build("DeathEnemyMaid")); + causesOfDeath.Add(CoronerDeathEnum.Void, AdvancedCauseOfDeath.Build("DeathPitVoid")); + causesOfDeath.Add(CoronerDeathEnum.GhostKnight, AdvancedCauseOfDeath.Build("DeathEnemyGhostKnight")); + causesOfDeath.Add(CoronerDeathEnum.Knife, AdvancedCauseOfDeath.Build("DeathPlayerMaidKnife")); + causesOfDeath.Add(CoronerDeathEnum.KnifeFeed, AdvancedCauseOfDeath.Build("DeathPlayerMaidKnifeFeed")); + causesOfDeath.Add(CoronerDeathEnum.KnifeFriendlyFire, AdvancedCauseOfDeath.Build("DeathPlayerMaidKnifeFriendlyFire")); + + ScarletMansion.Assets.onPlayerDeath.AddEvent("CoronerPatch", ProcessCauseOfDeath); + } + + public static void ProcessCauseOfDeath(CoronerParameters parameters) { + if (causesOfDeath.TryGetValue(parameters.death, out var value)) { + Coroner.API.SetCauseOfDeath(parameters.player, (AdvancedCauseOfDeath)value); + Plugin.logger.LogInfo(parameters.death); + } + } + + } +} diff --git a/ScarletMansionCoronerPatch/ScarletMansionCoronerPatch/Plugin.cs b/ScarletMansionCoronerPatch/ScarletMansionCoronerPatch/Plugin.cs new file mode 100644 index 0000000..3b0a3c9 --- /dev/null +++ b/ScarletMansionCoronerPatch/ScarletMansionCoronerPatch/Plugin.cs @@ -0,0 +1,54 @@ +using BepInEx.Bootstrap; +using BepInEx.Logging; +using BepInEx; +using HarmonyLib; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ScarletMansionCoronerPatch { + [BepInPlugin(modGUID, modName, modVersion)] + + [BepInDependency("dev.ladyalice.scarletmansion", "1.3.27")] + [BepInDependency(targetModGUID, BepInDependency.DependencyFlags.SoftDependency)] + + public class Plugin : BaseUnityPlugin { + + public const string modGUID = "dev.ladyalice.scarletmansion.coronerpatch"; + private const string modName = "Scarlet Mansion Coroner Patch"; + private const string modVersion = "1.0.0"; + + public const string targetModGUID = "com.elitemastereric.coroner"; + public const string targetModVersion = "2.1.0"; + + public readonly Harmony harmony = new Harmony(modGUID); + public static Plugin Instance {get; private set;} + public static ManualLogSource logger { get; internal set; } + + void Awake(){ + if (Instance == null) Instance = this; + + logger = BepInEx.Logging.Logger.CreateLogSource(modGUID); + + var modLoaded = Chainloader.PluginInfos.ContainsKey(targetModGUID); + if (!modLoaded) return; + + bool validVersion; + var pluginInfo = Chainloader.PluginInfos[targetModGUID]; + var loadedVersion = pluginInfo.Metadata.Version; + if (string.IsNullOrWhiteSpace(targetModVersion)){ + validVersion = true; + } else { + var requiredVersion = new Version(targetModVersion); + validVersion = loadedVersion >= requiredVersion; + } + + if (validVersion){ + logger.LogInfo($"Plugin {modName} has been added!"); + Patch.Activate(); + } + } + } +} diff --git a/ScarletMansionCoronerPatch/ScarletMansionCoronerPatch/Properties/AssemblyInfo.cs b/ScarletMansionCoronerPatch/ScarletMansionCoronerPatch/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..f31df09 --- /dev/null +++ b/ScarletMansionCoronerPatch/ScarletMansionCoronerPatch/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// アセンブリに関する一般情報は以下を通して制御されます +// 制御されます。アセンブリに関連付けられている情報を変更するには、 +// これらの属性値を変更してください。 +[assembly: AssemblyTitle("ScarletMansionCoronerPatch")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("ScarletMansionCoronerPatch")] +[assembly: AssemblyCopyright("Copyright © 2024")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// ComVisible を false に設定すると、このアセンブリ内の型は COM コンポーネントから +// 参照できなくなります。COM からこのアセンブリ内の型にアクセスする必要がある場合は、 +// その型の ComVisible 属性を true に設定してください。 +[assembly: ComVisible(false)] + +// このプロジェクトが COM に公開される場合、次の GUID が typelib の ID になります +[assembly: Guid("cb30b9c8-2679-4c65-86a3-b4680b73da4f")] + +// アセンブリのバージョン情報は、以下の 4 つの値で構成されています: +// +// メジャー バージョン +// マイナー バージョン +// ビルド番号 +// リビジョン +// +// すべての値を指定するか、次を使用してビルド番号とリビジョン番号を既定に設定できます +// 既定値にすることができます: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/ScarletMansionCoronerPatch/ScarletMansionCoronerPatch/ScarletMansionCoronerPatch.csproj b/ScarletMansionCoronerPatch/ScarletMansionCoronerPatch/ScarletMansionCoronerPatch.csproj new file mode 100644 index 0000000..27191f0 --- /dev/null +++ b/ScarletMansionCoronerPatch/ScarletMansionCoronerPatch/ScarletMansionCoronerPatch.csproj @@ -0,0 +1,83 @@ + + + + + Debug + AnyCPU + {CB30B9C8-2679-4C65-86A3-B4680B73DA4F} + Library + Properties + ScarletMansionCoronerPatch + ScarletMansionCoronerPatch + v4.8 + 512 + true + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\..\..\Libraries\0Harmony.dll + + + ..\..\..\Libraries\Assembly-CSharp-firstpass.dll + + + ..\..\..\Libraries\Assembly-CSharp-publicized.dll + + + ..\..\..\Libraries\BepInEx.dll + + + ..\..\..\Libraries\BepInEx.Harmony.dll + + + ..\..\..\Libraries\Coroner.dll + + + ..\..\..\Libraries\ScarletMansion.dll + + + + + + + + + + + ..\..\..\Libraries\Unity.Netcode.Components.dll + + + ..\..\..\Libraries\Unity.Netcode.Runtime.dll + + + ..\..\..\Libraries\UnityEngine.dll + + + ..\..\..\Libraries\UnityEngine.CoreModule.dll + + + + + + + + + \ No newline at end of file diff --git a/ScarletMansionMimicsPatch/ScarletMansionMimicsPatch/Patch.cs b/ScarletMansionMimicsPatch/ScarletMansionMimicsPatch/Patch.cs index aaa8c17..4f15df8 100644 --- a/ScarletMansionMimicsPatch/ScarletMansionMimicsPatch/Patch.cs +++ b/ScarletMansionMimicsPatch/ScarletMansionMimicsPatch/Patch.cs @@ -55,7 +55,7 @@ namespace ScarletMansionMimicsPatch { FixDoorwayForSDMFireExit(fixfireexit, mimicDoorMesh, mimicFrame, mimicLight); } - Plugin.logger.LogInfo("Fixed a doorway for a mimic"); + Plugin.logger.LogDebug("Fixed a doorway for a mimic"); } public override void OnMimicAttackStart(MimicDoor mimicDoor, PlayerControllerB playerToAttack) { diff --git a/ScarletMansionMimicsPatch/ScarletMansionMimicsPatch/Plugin.cs b/ScarletMansionMimicsPatch/ScarletMansionMimicsPatch/Plugin.cs index 441bc91..5478907 100644 --- a/ScarletMansionMimicsPatch/ScarletMansionMimicsPatch/Plugin.cs +++ b/ScarletMansionMimicsPatch/ScarletMansionMimicsPatch/Plugin.cs @@ -39,7 +39,6 @@ namespace ScarletMansionMimicsPatch { if (Instance == null) Instance = this; logger = BepInEx.Logging.Logger.CreateLogSource(modGUID); - logger.LogInfo($"Plugin {modName} has been added!"); var modLoaded = Chainloader.PluginInfos.ContainsKey(targetModGUID); if (!modLoaded) return;