Added new treasure room spawn (servant's quarters)
Fixed treasure room event for bedroom Fixed painting's interaction with MattyFixes Fixed critical damage bug introduced by v62 Increased lights spawn for all presets by a lot Added Coroner compatibility Added Scarlet Devil Mansion (moon) to the interior's spawn list Lights now have a chance of flickering and dying
This commit is contained in:
parent
93e249d838
commit
4413d12ea3
42 changed files with 986 additions and 333 deletions
|
|
@ -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<EnemyAI, int> angeredEnemies;
|
||||
public int level;
|
||||
|
||||
public List<Transform> roomsOfInterest;
|
||||
public List<ScarletBedroom> bedrooms;
|
||||
|
||||
public List<ScarletDoor> doors;
|
||||
public List<ScarletLight> 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<Transform>();
|
||||
bedrooms = new List<ScarletBedroom>();
|
||||
doors = new List<ScarletDoor>();
|
||||
lights = new List<ScarletLight>();
|
||||
}
|
||||
/*
|
||||
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<ScarletLight>();
|
||||
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<EnemyAI>(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);
|
||||
}
|
||||
|
||||
*/
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<Transform> roomsOfInterest;
|
||||
public List<ScarletBedroom> bedrooms;
|
||||
|
||||
public List<ScarletPainting> paintings;
|
||||
|
||||
public List<ScarletDoor> doors;
|
||||
public List<ScarletLight> lights;
|
||||
|
||||
public ScarletBookPath[] bookPaths;
|
||||
|
||||
public List<IScarletSelfDestroy> selfDestroyTargets;
|
||||
private int lastHour;
|
||||
|
||||
void Awake(){
|
||||
Instance = this;
|
||||
|
||||
roomsOfInterest = new List<Transform>();
|
||||
bedrooms = new List<ScarletBedroom>();
|
||||
|
||||
paintings = new List<ScarletPainting>();
|
||||
|
||||
doors = new List<ScarletDoor>();
|
||||
lights = new List<ScarletLight>();
|
||||
}
|
||||
|
||||
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<IScarletSelfDestroy>().ToList();
|
||||
bookPaths = dungeon.GetComponentsInChildren<ScarletBookPath>();
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue