From f0ef413d2fa47c2be24897fa06a0d1aab43f2af9 Mon Sep 17 00:00:00 2001 From: LadyAliceMargatroid Date: Mon, 10 Feb 2025 12:39:14 -0800 Subject: [PATCH] Fixed FloorCleanupParent to work Added custom connection rule for broken doorways Fixed ghost knight to work in multiplayer --- .../ScarletMansion/DunGenPatch/Patch.cs | 18 ++++++ .../Components/FloorCleanUpParent.cs | 25 +++++--- .../GamePatch/Components/FloorCleanup.cs | 8 ++- .../GamePatch/Enemies/KnightGhostVariant.cs | 62 +++++++------------ .../GamePatch/Enemies/MaidVariant.cs | 15 ++++- .../GamePatch/Managers/KnightSpawnManager.cs | 3 +- .../Managers/ScarletNetworkManager.cs | 14 +++++ 7 files changed, 90 insertions(+), 55 deletions(-) diff --git a/ScarletMansion/ScarletMansion/DunGenPatch/Patch.cs b/ScarletMansion/ScarletMansion/DunGenPatch/Patch.cs index b743d0a..9c53149 100644 --- a/ScarletMansion/ScarletMansion/DunGenPatch/Patch.cs +++ b/ScarletMansion/ScarletMansion/DunGenPatch/Patch.cs @@ -15,12 +15,15 @@ using GameNetcodeStuff; using ScarletMansion.GamePatch.Components; using ScarletMansion.Configs; using DunGen.Graph; +using static DunGen.TileConnectionRule; +using DunGen.Tags; namespace ScarletMansion.DunGenPatch { public static class Patch { public static bool active; public static DungeonGenerator generatorInstance; + public static TileConnectionRule scarletConnectionRule = new TileConnectionRule(CanScarletTilesConnect); public static RandomStream GetRandomStream(){ return generatorInstance.RandomStream; @@ -37,6 +40,7 @@ namespace ScarletMansion.DunGenPatch { public static void Activate(DungeonGenerator generator){ active = true; generatorInstance = generator; + DoorwayPairFinder.CustomConnectionRules.Add(scarletConnectionRule); } public static string GetLength(IntRange range, float multi){ @@ -46,6 +50,7 @@ namespace ScarletMansion.DunGenPatch { public static void Deactivate(bool ignoreScarletPlayer = false){ active = false; generatorInstance = null; + DoorwayPairFinder.CustomConnectionRules.Remove(scarletConnectionRule); GamePatch.JesterAIPatch.active = false; @@ -115,5 +120,18 @@ namespace ScarletMansion.DunGenPatch { ); } + private static Tag brokenDoorwayTag = new Tag(199); + private static Tag treasureDoomTag = new Tag(7); + + public static ConnectionResult CanScarletTilesConnect(Tile tileA, Tile tileB, Doorway doorwayA, Doorway doorwayB){ + // if not we fuck up initial generation + if (doorwayA.Socket != doorwayB.Socket) return ConnectionResult.Passthrough; + // if not we bypass the treasure room rules + if (tileA.Tags.Contains(treasureDoomTag) || tileB.Tags.Contains(treasureDoomTag)) return ConnectionResult.Passthrough; + + if (doorwayA.Tags.Contains(brokenDoorwayTag) || doorwayB.Tags.Contains(brokenDoorwayTag)) return ConnectionResult.Allow; + return ConnectionResult.Passthrough; + } + } } diff --git a/ScarletMansion/ScarletMansion/GamePatch/Components/FloorCleanUpParent.cs b/ScarletMansion/ScarletMansion/GamePatch/Components/FloorCleanUpParent.cs index f3252c9..b5fbde1 100644 --- a/ScarletMansion/ScarletMansion/GamePatch/Components/FloorCleanUpParent.cs +++ b/ScarletMansion/ScarletMansion/GamePatch/Components/FloorCleanUpParent.cs @@ -1,29 +1,36 @@ -using System; -using System.Collections.Generic; +using DunGen; using System.Linq; -using System.Text; -using System.Threading.Tasks; using UnityEngine; -using DunGen; -namespace ScarletMansion { - public class FloorCleanUpParent : MonoBehaviour { +namespace ScarletMansion +{ + public class FloorCleanUpParent : MonoBehaviour, IDungeonCompleteReceiver { public FloorCleanup[] children; + public string tileParentName; void Reset(){ children = GetComponentsInChildren(); } void Awake(){ - DunGenPlus.Managers.DoorwayManager.AddActionHook(DunGenPlus.Components.Scripting.DunGenScriptingHook.OnMainEntranceTeleportSpawned, OnDungeonComplete); + tileParentName = $"{GetComponentInParent().gameObject.name}"; + } - public void OnDungeonComplete() { + public void OnDungeonComplete(Dungeon dungeon) { + // somehow registereding in OnDungeonComplete fixes issues + DunGenPlus.Managers.DoorwayManager.AddActionHook(DunGenPlus.Components.Scripting.DunGenScriptingHook.OnMainEntranceTeleportSpawned, UpdateChildren); + } + + public void UpdateChildren() { var anyChanges = true; while(anyChanges) { anyChanges = false; foreach(var c in children) { + if (c == null) { + continue; + } var lastChanges = c.UpdateRender(); anyChanges|= lastChanges; } diff --git a/ScarletMansion/ScarletMansion/GamePatch/Components/FloorCleanup.cs b/ScarletMansion/ScarletMansion/GamePatch/Components/FloorCleanup.cs index 2afe0e4..f97bf83 100644 --- a/ScarletMansion/ScarletMansion/GamePatch/Components/FloorCleanup.cs +++ b/ScarletMansion/ScarletMansion/GamePatch/Components/FloorCleanup.cs @@ -1,4 +1,5 @@ -using System; +using DunGen; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -53,6 +54,11 @@ namespace ScarletMansion { } } + if (targerGameObject == null) { + Plugin.logger.LogError($"FloorCleanup null. dev fix plz"); + return false; + } + var wasActive = targerGameObject.activeSelf; targerGameObject.SetActive(false); return wasActive; diff --git a/ScarletMansion/ScarletMansion/GamePatch/Enemies/KnightGhostVariant.cs b/ScarletMansion/ScarletMansion/GamePatch/Enemies/KnightGhostVariant.cs index 9a242f0..bfa98dc 100644 --- a/ScarletMansion/ScarletMansion/GamePatch/Enemies/KnightGhostVariant.cs +++ b/ScarletMansion/ScarletMansion/GamePatch/Enemies/KnightGhostVariant.cs @@ -9,6 +9,7 @@ using UnityEngine.AI; using GameNetcodeStuff; using ScarletMansion.GamePatch.Components; using ScarletMansion.Configs; +using LethalLib.Modules; namespace ScarletMansion { @@ -32,9 +33,23 @@ namespace ScarletMansion { maxChaseSpeed = ConfigMain.Instance.revEnemyValue.speed; - if (IsOwner && KnightSpawnManager.Instance) { - var index = KnightSpawnManager.Instance.GetSpawnPointIndex(); - if (index == -1) { + // grab target player + if (StartOfRound.Instance.ClientPlayerList.TryGetValue(NetworkObject.OwnerClientId, out var index)){ + targetPlayer = StartOfRound.Instance.allPlayerScripts[index]; + Plugin.logger.LogInfo($"Targeting {targetPlayer.playerUsername} for death"); + } + + if (!IsOwner) { + // other clients will only see eyes of death + foreach(var m in knightMeshRenderers) { + m.enabled = false; + } + } + + // only server can deal with spawn stuff + if (IsServer) { + var knightSpawnIndex = KnightSpawnManager.Instance ? KnightSpawnManager.Instance.GetSpawnPointIndex() : -1; + if (knightSpawnIndex == -1) { // grab position instead var allVents = RoundManager.Instance.allEnemyVents; var anyEnemyVent = allVents[UnityEngine.Random.Range(0, allVents.Length)]; @@ -42,10 +57,8 @@ namespace ScarletMansion { return; } - SyncKnightReplacementClientRpc(index); + SyncKnightReplacementClientRpc(knightSpawnIndex); } - - } public override void DoAIInterval() { @@ -57,6 +70,8 @@ namespace ScarletMansion { if (isEnemyDead) return; if (timeSinceSpawn < 1f) return; + + var targetOutOfMap = !PlayerIsTargetable(targetPlayer); if (targetOutOfMap){ CallDisappear(); @@ -142,41 +157,6 @@ namespace ScarletMansion { } } - - 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.LogDebug($"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; diff --git a/ScarletMansion/ScarletMansion/GamePatch/Enemies/MaidVariant.cs b/ScarletMansion/ScarletMansion/GamePatch/Enemies/MaidVariant.cs index 7c74d25..a945a11 100644 --- a/ScarletMansion/ScarletMansion/GamePatch/Enemies/MaidVariant.cs +++ b/ScarletMansion/ScarletMansion/GamePatch/Enemies/MaidVariant.cs @@ -1,5 +1,6 @@ //using System; using System.Collections; +using System.Linq; using GameNetcodeStuff; using ScarletMansion.Configs; using ScarletMansion.GamePatch.Items; @@ -280,8 +281,18 @@ namespace ScarletMansion.GamePatch.Enemies { if (IsServer) { if (ConfigMain.Instance.revEnemyValue.enabled){ - var enemy = ScarletNetworkManagerUtility.CreateEnemyWithType(knightGhostEnemy, transform.position, 0f); - enemy.FindAndTunnelPlayer(transform.position); + // I need to parent the network at spawn + // so we gotta do the search stuff more early + var validPlayers = StartOfRound.Instance.allPlayerScripts.Where(p => p != null && PlayerIsTargetable(p)); + if (validPlayers.Count() > 0) { + var closestPlayer = validPlayers + .OrderBy(p => Vector3.SqrMagnitude(p.transform.position - transform.position)) + .FirstOrDefault(); + + ScarletNetworkManagerUtility.CreateEnemyWithTypeAndOwnership(knightGhostEnemy, transform.position, 0f, closestPlayer.actualClientId); + } else { + Plugin.logger.LogWarning("Could not find valid target to tunnel. Not spawning ghost."); + } } var newKnife = Object.Instantiate(knifePrefab, base.transform.position + Vector3.up * 0.5f, Quaternion.identity, RoundManager.Instance.spawnedScrapContainer); diff --git a/ScarletMansion/ScarletMansion/GamePatch/Managers/KnightSpawnManager.cs b/ScarletMansion/ScarletMansion/GamePatch/Managers/KnightSpawnManager.cs index 90783c6..731d9af 100644 --- a/ScarletMansion/ScarletMansion/GamePatch/Managers/KnightSpawnManager.cs +++ b/ScarletMansion/ScarletMansion/GamePatch/Managers/KnightSpawnManager.cs @@ -5,7 +5,6 @@ using System.Text; using System.Threading.Tasks; using UnityEngine; using DunGen; -using static LethalLevelLoader.ExtendedEvent; using UnityEngine.AI; namespace ScarletMansion { @@ -83,7 +82,7 @@ namespace ScarletMansion { enemyAI.transform.rotation = rotation; enemyAI.serverPosition = position; - if (enemyAI.agent == null) enemyAI.agent = GetComponentInChildren(); + if (enemyAI.agent == null) enemyAI.agent = enemyAI.GetComponentInChildren(); enemyAI.agent.Warp(position); if (enemyAI.IsOwner) { diff --git a/ScarletMansion/ScarletMansion/GamePatch/Managers/ScarletNetworkManager.cs b/ScarletMansion/ScarletMansion/GamePatch/Managers/ScarletNetworkManager.cs index 92af75c..cf1b416 100644 --- a/ScarletMansion/ScarletMansion/GamePatch/Managers/ScarletNetworkManager.cs +++ b/ScarletMansion/ScarletMansion/GamePatch/Managers/ScarletNetworkManager.cs @@ -404,6 +404,20 @@ namespace ScarletMansion { return null; } + public static T CreateEnemyWithTypeAndOwnership(EnemyType enemy, Vector3 position, float yRotation, ulong ownerID) where T: EnemyAI { + if (enemy != null) { + var gameObject = GameObject.Instantiate(enemy.enemyPrefab, position, Quaternion.Euler(0f, yRotation, 0f)); + var networkScript = gameObject.GetComponentInChildren(); + networkScript.SpawnWithOwnership(ownerID, true); + Plugin.logger.LogFatal(ownerID); + + var enemyScript = gameObject.GetComponent(); + RoundManager.Instance.SpawnedEnemies.Add(enemyScript); + return enemyScript; + } + 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;