Added spooky dark souls enemies

Added potential fix for items spawning near doorways (and enemies potentially using them)
This commit is contained in:
LadyAliceMargatroid 2024-05-06 02:13:04 -07:00
parent 882c4a0c3e
commit 37e3d6e9b1
8 changed files with 116 additions and 5 deletions

View File

@ -33,6 +33,8 @@ namespace ScarletMansion.DunGenPatch.Doorways {
} }
public void OnDungeonComplete(Dungeon dungeon) { public void OnDungeonComplete(Dungeon dungeon) {
// fix for items spawning on doorways
SetBlockers(true);
DoorwayManager.Instance.AddDoorwayCleanup(this); DoorwayManager.Instance.AddDoorwayCleanup(this);
} }
@ -55,6 +57,10 @@ namespace ScarletMansion.DunGenPatch.Doorways {
} }
} }
public void SetBlockers(bool state){
foreach(var b in blockers) b.SetActive(state);
}
public void SwitchConnectorBlocker(bool isConnector){ public void SwitchConnectorBlocker(bool isConnector){
if (overrideConnector) isConnector = true; if (overrideConnector) isConnector = true;
foreach(var c in connectors) c.SetActive(isConnector); foreach(var c in connectors) c.SetActive(isConnector);

View File

@ -14,6 +14,9 @@ using GameNetcodeStuff;
namespace ScarletMansion.GamePatch.Components { namespace ScarletMansion.GamePatch.Components {
public class ScarletBedroom : MonoBehaviour, IDungeonCompleteReceiver { public class ScarletBedroom : MonoBehaviour, IDungeonCompleteReceiver {
public const string ENEMY_SPAWN_LIST_DEFAULT = "knight@s1,crawler,nutcracker,springman,maskedplayerenemy,jester@s1,butler";
public static readonly string[] ENEMY_EVIL_LIST = new string[] { "knight", "crawler", "nutcracker", "springman" ,"maskedplayerenemy" ,"jester", "butler" };
public static ActionList onBedroomEndEvent = new ActionList("onBedroomEnd"); public static ActionList onBedroomEndEvent = new ActionList("onBedroomEnd");
[Header("References")] [Header("References")]
@ -133,7 +136,7 @@ namespace ScarletMansion.GamePatch.Components {
public static void CreateRandomEnemyList(List<SpawnableEnemyWithRarity> enemies){ public static void CreateRandomEnemyList(List<SpawnableEnemyWithRarity> enemies){
var lower = PluginConfig.Instance.paintingEnemyListValue.ToLowerInvariant(); var lower = PluginConfig.Instance.paintingEnemyListValue.ToLowerInvariant();
if (lower == "default"){ if (lower == "default"){
lower = "knight@s1,crawler,nutcracker,springman,maskedplayerenemy,jester@s1"; lower = ENEMY_SPAWN_LIST_DEFAULT;
} }
spawnableEnemiesTrueList = new List<EnemyReferenceSpawnLogic>(); spawnableEnemiesTrueList = new List<EnemyReferenceSpawnLogic>();
@ -193,7 +196,9 @@ namespace ScarletMansion.GamePatch.Components {
bonusEnemy.ApplySpawnLogic(); bonusEnemy.ApplySpawnLogic();
roundmanager.currentEnemyPower += enemy.PowerLevel; roundmanager.currentEnemyPower += enemy.PowerLevel;
roundmanager.SpawnEnemyServerRpc(vent.transform.position, y, enemyIndex); var spawnedEnemy = roundmanager.SpawnEnemyGameObject(vent.transform.position, y, enemyIndex);
ScarletNetworkManager.Instance.RequestEvilSkinApply(spawnedEnemy, enemy.name.ToLowerInvariant());
} }
} catch (Exception e) { } catch (Exception e) {
var enemyString = bonusEnemy != null ? bonusEnemy.ToString() : "NULL"; var enemyString = bonusEnemy != null ? bonusEnemy.ToString() : "NULL";

View File

@ -18,8 +18,8 @@ namespace ScarletMansion.GamePatch {
if (DunGenPatch.Patch.active && active && __instance.IsOwner) { if (DunGenPatch.Patch.active && active && __instance.IsOwner) {
Plugin.logger.LogInfo("Activing kill order for Jester"); Plugin.logger.LogInfo("Activing kill order for Jester");
__instance.SwitchToBehaviourState(1); __instance.SwitchToBehaviourState(1);
active = false;
} }
active = false;
} }
} }

View File

@ -6,6 +6,9 @@ using System.Threading.Tasks;
using UnityEngine; using UnityEngine;
using DunGen; using DunGen;
using ScarletMansion.DunGenPatch.Doorways; using ScarletMansion.DunGenPatch.Doorways;
using Unity.AI.Navigation;
using UnityEngine.AI;
using DunGen.Adapters;
namespace ScarletMansion.GamePatch.Managers { namespace ScarletMansion.GamePatch.Managers {
public class DoorwayManager : MonoBehaviour { public class DoorwayManager : MonoBehaviour {
@ -20,6 +23,39 @@ namespace ScarletMansion.GamePatch.Managers {
doorwayCleanup = new List<DoorwayCleanup>(); doorwayCleanup = new List<DoorwayCleanup>();
} }
/*
private NavMeshSurface surface;
private GameObject meshGameObject;
private MeshFilter meshFilter;
void Update(){
if (surface == null){
surface = FindObjectOfType<NavMeshSurface>();
}
if (surface != null){
if (meshFilter == null){
meshGameObject = new GameObject("Nav Mesh V");
meshFilter = meshGameObject.AddComponent<MeshFilter>();
var renderer = meshGameObject.AddComponent<MeshRenderer>();
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){ public void AddDoorwayCleanup(DoorwayCleanup dw){
doorwayCleanup.Add(dw); doorwayCleanup.Add(dw);
} }
@ -28,8 +64,20 @@ namespace ScarletMansion.GamePatch.Managers {
if (Instance && DunGenPatch.Patch.active) { if (Instance && DunGenPatch.Patch.active) {
var doorwayCleanups = Instance.doorwayCleanup; var doorwayCleanups = Instance.doorwayCleanup;
foreach(var d in doorwayCleanups){ foreach(var d in doorwayCleanups){
d.SetBlockers(false);
d.Cleanup(); d.Cleanup();
} }
try{
var dungeonGen = RoundManager.Instance.dungeonGenerator;
var navmesh = dungeonGen.transform.parent.GetComponentInChildren<UnityNavMeshAdapter>();
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());
}
} }
} }

View File

@ -9,6 +9,7 @@ using Unity.Netcode;
using GameNetcodeStuff; using GameNetcodeStuff;
using ScarletMansion.GamePatch.Items; using ScarletMansion.GamePatch.Items;
using ScarletMansion.GamePatch; using ScarletMansion.GamePatch;
using ScarletMansion.GamePatch.Components;
namespace ScarletMansion { namespace ScarletMansion {
@ -261,6 +262,45 @@ namespace ScarletMansion {
} }
} }
public void RequestEvilSkinApply(NetworkObjectReference reference, string enemyName) {
if (PluginConfig.Instance.paintingEnemyEvilSkinValue && ScarletBedroom.ENEMY_EVIL_LIST.Contains(enemyName)) {
RequestEvilSkinApplyClientRpc(reference);
}
}
[ClientRpc]
public void RequestEvilSkinApplyClientRpc(NetworkObjectReference reference){
void ApplyMaterialToRenderers<T>(T[] renderers) where T: Renderer{
foreach(var render in renderers) {
var mats = render.materials;
for(var i = 0; i < mats.Length; i++) {
var material = new Material(Assets.networkObjectList.ghostMaterial);
material.mainTexture = mats[i].mainTexture;
mats[i] = material;
}
render.materials = mats;
}
}
if (reference.TryGet(out var obj)){
var enemy = obj.GetComponentInParent<EnemyAI>();
if (enemy == null) return;
var enemyName = enemy.name;
try {
Plugin.logger.LogInfo($"Applying evil material to {enemyName}");
ApplyMaterialToRenderers(enemy.GetComponentsInChildren<SkinnedMeshRenderer>());
ApplyMaterialToRenderers(enemy.GetComponentsInChildren<MeshRenderer>());
} catch (Exception e){
Plugin.logger.LogWarning($"Failed to apply evil material to {enemyName}");
Plugin.logger.LogWarning(e.ToString());
}
}
}
} }
public static class ScarletNetworkManagerUtility { public static class ScarletNetworkManagerUtility {

View File

@ -32,6 +32,9 @@ namespace ScarletMansion {
[Header("Main Prefabs")] [Header("Main Prefabs")]
public GameObject scarletNetworkManager; public GameObject scarletNetworkManager;
[Header("Mis References")]
public Material ghostMaterial;
public AudioClip sinkingAudioClip; public AudioClip sinkingAudioClip;
} }
} }

View File

@ -33,7 +33,7 @@ namespace ScarletMansion {
public class Plugin : BaseUnityPlugin { public class Plugin : BaseUnityPlugin {
public const string modGUID = "ImoutoSama.ScarletMansion"; public const string modGUID = "ImoutoSama.ScarletMansion";
private const string modName = "Scarlet Mansion"; private const string modName = "Scarlet Mansion";
private const string modVersion = "1.3.13"; private const string modVersion = "1.3.15";
public readonly Harmony harmony = new Harmony(modGUID); public readonly Harmony harmony = new Harmony(modGUID);

View File

@ -12,6 +12,7 @@ using BepInEx.Configuration;
using BepInEx.Logging; using BepInEx.Logging;
using UnityEngine; using UnityEngine;
using System.Reflection; using System.Reflection;
using ScarletMansion.GamePatch.Components;
namespace ScarletMansion { namespace ScarletMansion {
@ -368,7 +369,14 @@ namespace ScarletMansion {
dungeonPaintingEventPrefix, dungeonPaintingEventPrefix,
"Enemy List", "Enemy List",
"default", "default",
"The enemies that can spawn when the bedroom's painting event ends, in the form of a comma separated list of enemy names along with optional parameters separated or '@'.It can accept either the enemy's internal or display name.\n\nThe available parameters are:\nSpawn Logic: 's#' where '#' is either '0' for normal spawn logic or '1' for special spawn logic. Only the knight and jester have special spawn logic. When their special spawn logic is enabled, the knight will spawn properly in the bedroom and the jester will spawn already cranking.\n\nThe following string \"default\" is a preset that uses the following string \"knight@s1,crawler,nutcracker,springman,maskedplayerenemy,jester@s1\"." $"The enemies that can spawn when the bedroom's painting event ends, in the form of a comma separated list of enemy names along with optional parameters separated or '@'.It can accept either the enemy's internal or display name.\n\nThe available parameters are:\nSpawn Logic: 's#' where '#' is either '0' for normal spawn logic or '1' for special spawn logic. Only the knight and jester have special spawn logic. When their special spawn logic is enabled, the knight will spawn properly in the bedroom and the jester will spawn already cranking.\n\nThe following string \"default\" is a preset that uses the following string \"{ScarletBedroom.ENEMY_SPAWN_LIST_DEFAULT}\"."
);
public static ConfigEntryBundle<bool> paintingEnemyEvilSkin = new ConfigEntryBundle<bool>(
dungeonPaintingEventPrefix,
"Invader Apperance",
true,
"Enemies spawned from the bedroom's painting event has a pitch black and red appearance. Only valid for the default enemy list."
); );
public static ConfigEntryBundle<bool> facilityMeltdownActive = new ConfigEntryBundle<bool>( public static ConfigEntryBundle<bool> facilityMeltdownActive = new ConfigEntryBundle<bool>(
@ -383,6 +391,7 @@ namespace ScarletMansion {
public IntRange paintingExtraLootValue = new IntRange("painting extra loot"); public IntRange paintingExtraLootValue = new IntRange("painting extra loot");
public bool paintingSpawnEnemyValue; public bool paintingSpawnEnemyValue;
public string paintingEnemyListValue; public string paintingEnemyListValue;
public bool paintingEnemyEvilSkinValue;
public bool facilityMeltdownActiveValue; public bool facilityMeltdownActiveValue;
// lighting // lighting