Added treasure rooms

Added keyslot compatibility
Frames look at when you look away
Fixed snow globes
This commit is contained in:
LadyAliceMargatroid 2024-08-04 22:02:12 -07:00
parent 056cac8df1
commit e9152782aa
23 changed files with 530 additions and 87 deletions

View File

@ -144,6 +144,7 @@ namespace ScarletMansion {
public static Flashlight flashlight; public static Flashlight flashlight;
public static Flashlight flashlightBB; public static Flashlight flashlightBB;
public static GlobalItem key;
public static GlobalItem GetGlobalItem(Item item){ public static GlobalItem GetGlobalItem(Item item){
return globalItems.FirstOrDefault(x => x.item == item); return globalItems.FirstOrDefault(x => x.item == item);
@ -227,6 +228,7 @@ namespace ScarletMansion {
flashlight = new Flashlight("Pro Flashlight", 0); flashlight = new Flashlight("Pro Flashlight", 0);
flashlightBB = new Flashlight("Flashlight", 1); flashlightBB = new Flashlight("Flashlight", 1);
key = new GlobalItem(networkObjectList.items[0]);
globalItems.Add(flashlight); globalItems.Add(flashlight);
globalItems.Add(flashlightBB); globalItems.Add(flashlightBB);

View File

@ -86,6 +86,13 @@ namespace ScarletMansion.DunGenPatch {
PluginConfig.Instance.branchPathSectionThreeValue.UpdateValues(props.LineRandomizerArchetypes[i]); PluginConfig.Instance.branchPathSectionThreeValue.UpdateValues(props.LineRandomizerArchetypes[i]);
++i; ++i;
} }
var count = PluginConfig.Instance.treasureRoomCountValue;
props.UseForcedTiles = count > 0;
var copyTarget = props.ForcedTileSets[0];
props.ForcedTileSets = new List<ForcedTileSetList>();
for(var j = 0; j < count; ++j) props.ForcedTileSets.Add(copyTarget);
} }
} }

View File

@ -30,10 +30,16 @@ namespace ScarletMansion.GamePatch.Components {
if (localPlayer && !localPlayer.isPlayerDead) { if (localPlayer && !localPlayer.isPlayerDead) {
var direction = localPlayer.transform.position - transform.position; var direction = localPlayer.transform.position - transform.position;
direction.y = 0f; direction.y = 0f;
direction = direction.normalized;
var playerFacing = -localPlayer.gameplayCamera.transform.forward;
// only face player when player looking away
if (Vector3.Dot(playerFacing, direction) < 0.25f) {
transform.rotation = Quaternion.LookRotation(direction); transform.rotation = Quaternion.LookRotation(direction);
} }
} }
}
} }
} }

View File

@ -39,6 +39,14 @@ namespace ScarletMansion.GamePatch.Components {
audioSource.volume = maxVolume * (volume * 0.1f); audioSource.volume = maxVolume * (volume * 0.1f);
} }
public override void OnNetworkSpawn() {
if (IsOwner) {
ToggleOnOffSwitchClientRpc(UnityEngine.Random.value > 0.9f);
ToggleVolumeSwitchClientRpc(UnityEngine.Random.Range(3, 7));
ToggleSongSwitchClientRpc(UnityEngine.Random.Range(0, audioClips.Length));
}
}
void RotateTransformTo(Transform dial, ref float current, float towards){ void RotateTransformTo(Transform dial, ref float current, float towards){
current = Mathf.Lerp(current, towards, Time.deltaTime * 2f); current = Mathf.Lerp(current, towards, Time.deltaTime * 2f);
var v = new Vector3(current, 0f, 0f); var v = new Vector3(current, 0f, 0f);

View File

@ -0,0 +1,106 @@
using DunGen;
using ScarletMansion.GamePatch.Managers;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Unity.Netcode;
using UnityEngine;
namespace ScarletMansion.GamePatch.Components.TreasureRoom {
public abstract class TreasureRoom : MonoBehaviour, IDungeonCompleteReceiver {
[Header("Door Statuses")]
public GameObject doorStatusPrefab;
protected List<TreasureRoomDoorStatus> treasureDoorStatuses;
protected System.Random randomStream;
protected List<ScarletDoor> treasureDoorLocks;
protected bool opened;
public void Update(){
if (treasureDoorLocks == null) return;
if (!StartOfRound.Instance.IsHost || opened) return;
var time = Utility.GetTime();
if (CanOpen()) {
foreach(var d in treasureDoorLocks){
d.LockDoorOverrideClientRpc(false);
}
opened = true;
}
}
public abstract bool CanOpen();
public virtual int GetDoorStatusValue() => 0;
public void UpdateTreasureDoorStatus(){
var value = GetDoorStatusValue();
foreach(var d in treasureDoorStatuses){
d.UpdateDoorStatusClientRpc(value);
}
}
protected GameObject GetMapPropsContainer(){
var roundManager = RoundManager.Instance;
if (roundManager.mapPropsContainer == null) {
roundManager.mapPropsContainer = GameObject.FindGameObjectWithTag("MapPropsContainer");
}
return roundManager.mapPropsContainer;
}
protected void CreateDoorStatuses(List<Doorway> doorways) {
treasureDoorStatuses = new List<TreasureRoomDoorStatus>();
var mapPropsContainer = GetMapPropsContainer();
foreach(var doorway in doorways) {
var doorStatusGameObject = GameObject.Instantiate(doorStatusPrefab, doorway.transform.position, doorway.transform.rotation, mapPropsContainer.transform);
var networkObject = doorStatusGameObject.GetComponent<NetworkObject>();
var doorStatus = doorStatusGameObject.GetComponentInChildren<TreasureRoomDoorStatus>();
treasureDoorStatuses.Add(doorStatus);
networkObject.Spawn(true);
}
}
public virtual void OnDungeonComplete(Dungeon dungeon) {
AngerManager.Instance.AddRoomOfInterest(transform);
var tile = GetComponentInParent<Tile>();
var doorways = tile.UsedDoorways;
var targetDoorways = new List<Doorway>();
foreach(var d in doorways) {
var neighboorTile = d.ConnectedDoorway.Tile.gameObject.name.ToLowerInvariant();
if (neighboorTile.Contains("treasure")){
targetDoorways.Add(d);
}
}
if (targetDoorways.Count > 0) {
var dunRandom = DunGenPatch.Patch.generatorInstance.RandomStream;
randomStream = new System.Random((int)(dunRandom.NextDouble() * int.MaxValue));
StartCoroutine(LockTreasureDoor(targetDoorways));
}
}
protected virtual IEnumerator LockTreasureDoor(List<Doorway> doorways){
if (!StartOfRound.Instance.IsHost) yield break;
yield return new WaitForSecondsRealtime(4f);
Plugin.logger.LogInfo("Setting up lock for treasure room");
treasureDoorLocks = new List<ScarletDoor>();
foreach(var d in doorways){
var doorLock = AngerManager.Instance.GetScarletDoor(d.transform.position);
doorLock.LockDoorOverrideClientRpc(true);
treasureDoorLocks.Add(doorLock);
}
}
}
}

View File

@ -0,0 +1,63 @@
using DunGen;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Unity.Netcode;
using UnityEngine;
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);
if (ready) {
Plugin.logger.LogInfo($"Opening cause all books pulled");
return ready;
}
return false;
}
public override int GetDoorStatusValue() {
return switches.Count(s => s.pulled);
}
protected override IEnumerator LockTreasureDoor(List<Doorway> doorways) {
yield return base.LockTreasureDoor(doorways);
if (StartOfRound.Instance.IsHost) {
Plugin.logger.LogInfo("Creating book switches");
switches = new TreasureRoomBookSwitch[3];
var switchOrdered = zones.Where(z => z != null && z.gameObject.activeInHierarchy).OrderBy(s => randomStream.NextDouble());
var mapPropsContainer = GetMapPropsContainer();
for(var i = 0; i < 3; ++i) {
var result = switchOrdered.ElementAt(i).GetRandomPosition(randomStream);
var bookGameObject = GameObject.Instantiate(bookPrefab, result.position, result.rotation, mapPropsContainer.transform);
var networkObject = bookGameObject.GetComponent<NetworkObject>();
var bookScript = bookGameObject.GetComponentInChildren<TreasureRoomBookSwitch>();
bookScript.treasureRoom = this;
switches[i] = bookScript;
networkObject.Spawn(true);
}
CreateDoorStatuses(doorways);
}
}
}
}

View File

@ -0,0 +1,47 @@
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.TreasureRoom {
public class TreasureRoomBookSwitch : NetworkBehaviour {
public TreasureRoomBookPullEvent treasureRoom;
public InteractTrigger trigger;
public Transform modelTransform;
public bool pulled;
[ServerRpc(RequireOwnership = false)]
public void PullServerRpc(){
PullClientRpc();
treasureRoom.UpdateTreasureDoorStatus();
}
[ClientRpc]
public void PullClientRpc(){
pulled = true;
trigger.interactable = false;
StartCoroutine(PullCoroutine());
}
public void PullBook(){
PullServerRpc();
}
private IEnumerator PullCoroutine() {
var time = 0f;
while(time < 0.5f) {
time += Time.deltaTime;
modelTransform.localPosition = Vector3.Lerp(Vector3.zero, new Vector3(0f, 0f, 0.1f), time / 0.5f);
modelTransform.localRotation = Quaternion.Slerp(Quaternion.identity, Quaternion.Euler(10f, 0f, 0f), time / 0.5f);
yield return null;
}
}
}
}

View File

@ -0,0 +1,36 @@
using DunGen;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
namespace ScarletMansion.GamePatch.Components.TreasureRoom {
public class TreasureRoomBookZone : MonoBehaviour {
public List<Bounds> spawningRegions;
public (Vector3 position, Quaternion rotation) GetRandomPosition(System.Random random) {
var region = spawningRegions[random.Next(spawningRegions.Count)];
var worldRegion = transform.TransformBounds(region);
var worldPosition = new Vector3(
random.GetRandomNumber(worldRegion.min.x, worldRegion.max.x),
random.GetRandomNumber(worldRegion.min.y, worldRegion.max.y),
random.GetRandomNumber(worldRegion.min.z, worldRegion.max.z)
);
var rotation = transform.rotation;
return (worldPosition, rotation);
}
public void OnDrawGizmosSelected(){
foreach(var r in spawningRegions) {
var b = transform.TransformBounds(r) ;
Gizmos.DrawWireCube(b.center, b.size);
}
}
}
}

View File

@ -0,0 +1,30 @@
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 TreasureRoomDoorStatus : NetworkBehaviour {
public GameObject[] doorStatusTargets;
public TreasureRoom treasureRoom;
[ClientRpc]
public void UpdateDoorStatusClientRpc(int count) {
var i = 0;
while(i < count && i < doorStatusTargets.Length) {
doorStatusTargets[i].SetActive(true);
++i;
}
while(i < doorStatusTargets.Length) {
doorStatusTargets[i].SetActive(false);
++i;
}
}
}
}

View File

@ -0,0 +1,104 @@
using DunGen;
using ScarletMansion.GamePatch.Managers;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TMPro;
using UnityEngine;
namespace ScarletMansion.GamePatch.Components.TreasureRoom {
public class TreasureRoomTimeEvent : TreasureRoom {
[Header("References")]
public GameObject timeClockPrefab;
public Transform[] timeClockSpawnTransforms;
private int timeClockSpawnTransformIndex;
[Header("Values")]
public Vector2Int hourRange;
private int hourSelected;
private int mintuesSelected;
public override bool CanOpen() {
var time = Utility.GetTime();
var ready = time.hours > hourSelected || (time.hours >= hourSelected && time.minutes >= mintuesSelected);
if (ready) {
Plugin.logger.LogInfo($"Opening cause {time.hours}:{time.minutes} > {hourSelected}:{mintuesSelected}");
return ready;
}
return false;
}
protected override IEnumerator LockTreasureDoor(List<Doorway> doorways) {
Plugin.logger.LogInfo("Setting up treasure room (kitchen)");
hourSelected = randomStream.Next(hourRange.x, hourRange.y);
mintuesSelected = randomStream.Next(0, 3) * 15;
Plugin.logger.LogInfo($"Opening at {hourSelected}:{mintuesSelected:D2}");
timeClockSpawnTransformIndex = randomStream.Next(timeClockSpawnTransforms.Length);
var parent = timeClockSpawnTransforms[timeClockSpawnTransformIndex];
var copy = Instantiate(timeClockPrefab, parent);
var textMesh = copy.GetComponentInChildren<TextMeshPro>();
textMesh.text = $"{hourSelected}:{mintuesSelected:D2}";
RandomizeCharacters(textMesh);
yield return base.LockTreasureDoor(doorways);
}
private void RandomizeCharacters(TextMeshPro textMesh){
textMesh.renderMode = TextRenderFlags.DontRender;
textMesh.ForceMeshUpdate();
var textInfo = textMesh.textInfo;
var vertices = textInfo.meshInfo[0].vertices;
var characterCount = textInfo.characterCount;
for(var i = 0; i < characterCount; i++){
var charInfo = textMesh.textInfo.characterInfo[i];
if (!charInfo.isVisible) continue;
var vertexIndex = charInfo.vertexIndex;
var charMidPoint = (vertices[vertexIndex + 0] + vertices[vertexIndex + 2]) * 0.5f;
// offset to mid point just in case
var offset = charMidPoint;
vertices[vertexIndex + 0] += -offset;
vertices[vertexIndex + 1] += -offset;
vertices[vertexIndex + 2] += -offset;
vertices[vertexIndex + 3] += -offset;
// get offset values and setup matrix
var angle = UnityEngine.Random.Range(-5f, 5f);
var position = new Vector3(UnityEngine.Random.Range(-0.1f, 0.1f), UnityEngine.Random.Range(-0.1f, 0.1f), 0f);
var scale = Vector3.one * UnityEngine.Random.Range(0.95f, 1.05f);
var matrix = Matrix4x4.TRS(position, Quaternion.Euler(0f, 0f, angle), scale);
// move
vertices[vertexIndex + 0] = matrix.MultiplyPoint3x4(vertices[vertexIndex + 0]);
vertices[vertexIndex + 1] = matrix.MultiplyPoint3x4(vertices[vertexIndex + 1]);
vertices[vertexIndex + 2] = matrix.MultiplyPoint3x4(vertices[vertexIndex + 2]);
vertices[vertexIndex + 3] = matrix.MultiplyPoint3x4(vertices[vertexIndex + 3]);
// fix offset
vertices[vertexIndex + 0] += offset;
vertices[vertexIndex + 1] += offset;
vertices[vertexIndex + 2] += offset;
vertices[vertexIndex + 3] += offset;
}
textMesh.mesh.vertices = vertices;
textMesh.mesh.uv = textMesh.textInfo.meshInfo[0].uvs0;
textMesh.mesh.uv2= textMesh.textInfo.meshInfo[0].uvs2;
textMesh.mesh.colors32 = textMesh.textInfo.meshInfo[0].colors32;
textMesh.mesh.RecalculateBounds();
}
}
}

View File

@ -1,74 +0,0 @@
using DunGen;
using ScarletMansion.GamePatch.Managers;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TMPro;
using UnityEngine;
namespace ScarletMansion.GamePatch.Components.TreasureRoom {
public class TreasureRoomTimedOpen : MonoBehaviour, IDungeonCompleteReceiver {
[Header("References")]
public GameObject timeGameObject;
public TextMeshPro timeTextMesh;
[Header("Values")]
public Vector2Int hourRange;
public bool opened;
private int hourSelected;
private int mintuesSelected;
private ScarletDoor treasureDoorLock;
public void Update(){
if (treasureDoorLock == null) return;
if (!StartOfRound.Instance.IsHost || opened) return;
var time = Utility.GetTime();
if (time.hours > hourSelected || (time.hours >= hourSelected && time.minutes >= mintuesSelected)) {
treasureDoorLock.LockDoorOverrideClientRpc(false);
opened = true;
Plugin.logger.LogInfo($"Opening cause {time.hours}:{time.minutes} > {hourSelected}:{mintuesSelected}");
}
}
public void OnDungeonComplete(Dungeon dungeon) {
AngerManager.Instance.AddRoomOfInterest(transform);
if (!StartOfRound.Instance.IsHost) return;
var tile = GetComponentInParent<Tile>();
var doorways = tile.UsedDoorways;
foreach(var d in doorways) {
var neighboorTile = d.ConnectedDoorway.Tile.gameObject.name.ToLowerInvariant();
//Plugin.logger.LogInfo(neighboorTile);
if (neighboorTile.Contains("treasure")){
StartCoroutine(BeginTreasureRoomProcess(d));
return;
}
}
}
public IEnumerator BeginTreasureRoomProcess(Doorway doorway){
yield return new WaitForSecondsRealtime(4f);
Plugin.logger.LogInfo("Setting up lock for treasure room");
treasureDoorLock = AngerManager.Instance.GetScarletDoor(doorway.transform.position);
treasureDoorLock.LockDoorOverrideClientRpc(true);
hourSelected = UnityEngine.Random.Range(hourRange.x, hourRange.y);
mintuesSelected = UnityEngine.Random.Range(0, 3) * 15;
timeGameObject.SetActive(true);
timeTextMesh.text = $"{hourSelected}:{mintuesSelected}";
Plugin.logger.LogInfo($"Opening at {hourSelected}:{mintuesSelected}");
}
}
}

View File

@ -0,0 +1,18 @@
using DunGen;
using ScarletMansion.GamePatch.Props;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ScarletMansion.GamePatch.FixValues
{
public class FixTreasureRoom : FixBaseClass<LocalPropSetBasic> {
public void Awake(){
var loot = PluginConfig.Instance.treasureRoomLootValue;
target.propCount = new IntRange(loot.min, loot.max);
}
}
}

View File

@ -95,8 +95,23 @@ namespace ScarletMansion.GamePatch.Items {
var playerOverrideController = ScarletPlayerControllerB.GetScarletPlayerScript(player).playerOverrideController; var playerOverrideController = ScarletPlayerControllerB.GetScarletPlayerScript(player).playerOverrideController;
if (playerOverrideController == null) return; if (playerOverrideController == null) return;
if (_override) playerOverrideController["HoldClipboard"] = SnowGlobeOverrideHoldClip; if (_override) {
else playerOverrideController["HoldClipboard"] = null; if (player.isCrouching) {
player.Crouch(!player.isCrouching);
StartCoroutine(DelayOverrideAnim(playerOverrideController));
} else {
playerOverrideController["HoldLungApparatice"] = SnowGlobeOverrideHoldClip;
}
} else {
playerOverrideController["HoldLungApparatice"] = null;
}
}
private IEnumerator DelayOverrideAnim(AnimatorOverrideController playerOverrideController) {
yield return new WaitForSeconds(0.3f);
if (isHeld && playerHeldBy == previouslyHeldBy) {
playerOverrideController["HoldLungApparatice"] = SnowGlobeOverrideHoldClip;
}
} }

View File

@ -104,7 +104,7 @@ namespace ScarletMansion.GamePatch.Managers {
// I want to get only doors that are revelant // I want to get only doors that are revelant
foreach(var t in roomsOfInterest){ foreach(var t in roomsOfInterest){
var dist = Vector3.SqrMagnitude(d.transform.position - t.position); var dist = Vector3.SqrMagnitude(d.transform.position - t.position);
if (dist < 16f * 16f){ if (dist < 24f * 24f){
doors.Add(d); doors.Add(d);
return; return;
} }

View File

@ -26,10 +26,12 @@ namespace ScarletMansion.GamePatch {
} }
} }
[HarmonyPatch(typeof(PlayerControllerB), "Update")]
[HarmonyPrefix]
public static void UpdatePatch(ref PlayerControllerB __instance) { public static void UpdatePatch(ref PlayerControllerB __instance) {
if (GameNetworkManager.Instance.localPlayerController == null) return; if (GameNetworkManager.Instance.localPlayerController == null) return;
var controller = ScarletPlayerControllerB.GetScarletPlayerScript(__instance); var controller = ScarletPlayerControllerB.GetScarletPlayerScript(__instance);
if (controller != null) return; if (controller.playerOverrideController != null) return;
controller.playerOverrideController = new AnimatorOverrideController(__instance.playerBodyAnimator.runtimeAnimatorController); controller.playerOverrideController = new AnimatorOverrideController(__instance.playerBodyAnimator.runtimeAnimatorController);
__instance.playerBodyAnimator.runtimeAnimatorController = controller.playerOverrideController; __instance.playerBodyAnimator.runtimeAnimatorController = controller.playerOverrideController;

View File

@ -13,12 +13,14 @@ namespace ScarletMansion.ModPatch {
public const string lethalConfigGuid = "ainavt.lc.lethalconfig"; public const string lethalConfigGuid = "ainavt.lc.lethalconfig";
public const string facilityMeldownGuid = "me.loaforc.facilitymeltdown"; public const string facilityMeldownGuid = "me.loaforc.facilitymeltdown";
public const string reserveFlashlightGuid = "FlipMods.ReservedFlashlightSlot"; public const string reserveFlashlightGuid = "FlipMods.ReservedFlashlightSlot";
public const string reserveKeyGuid = "Rogue.ReservedKeySlot";
public static readonly ModPatch[] modPatches = new ModPatch[] { public static readonly ModPatch[] modPatches = new ModPatch[] {
//new AdvancedCompanyPatch(advancedCompanyGuid), //new AdvancedCompanyPatch(advancedCompanyGuid),
new LethalConfigPatch(lethalConfigGuid), new LethalConfigPatch(lethalConfigGuid),
new FacilityMeltdownPatch(facilityMeldownGuid), new FacilityMeltdownPatch(facilityMeldownGuid),
new ReservedItemSlotPatch(reserveFlashlightGuid) new ReservedFlashlightPatch(reserveFlashlightGuid),
new ReservedKeyPatch(reserveKeyGuid),
}; };

View File

@ -7,11 +7,11 @@ using ReservedItemSlotCore.Data;
using UnityEngine; using UnityEngine;
namespace ScarletMansion.ModPatch { namespace ScarletMansion.ModPatch {
public class ReservedItemSlotPatch : ModPatch { public class ReservedFlashlightPatch : ModPatch {
public override string version => "2.0.0"; public override string version => "2.0.0";
public ReservedItemSlotPatch(string guid) : base(guid) { } public ReservedFlashlightPatch(string guid) : base(guid) { }
public override void AddPatch(){ public override void AddPatch(){
Assets.onAssetsLoadEvent.AddEvent("LoadFlashlight", LoadFlashlight); Assets.onAssetsLoadEvent.AddEvent("LoadFlashlight", LoadFlashlight);

View File

@ -0,0 +1,26 @@
using ReservedItemSlotCore.Data;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
namespace ScarletMansion.ModPatch {
public class ReservedKeyPatch : ModPatch {
public override string version => "2.0.0";
public ReservedKeyPatch(string guid) : base(guid) { }
public override void AddPatch(){
Assets.onAssetsLoadEvent.AddEvent("LoadKey", LoadKey);
}
public static void LoadKey(){
var key = new ReservedItemData(Assets.key.item.itemName);
ReservedItemSlotData.TryAddItemDataToReservedItemSlot(key, "key");
}
}
}

View File

@ -23,17 +23,18 @@ namespace ScarletMansion {
[BepInDependency("imabatby.lethallevelloader", "1.2.0.3")] [BepInDependency("imabatby.lethallevelloader", "1.2.0.3")]
[BepInDependency("evaisa.lethallib", "0.13.2")] [BepInDependency("evaisa.lethallib", "0.13.2")]
[BepInDependency("dev.ladyalice.dungenplus", "1.0.0")] [BepInDependency("dev.ladyalice.dungenplus", "1.0.3")]
//[BepInDependency(ModCompability.advancedCompanyGuid, BepInDependency.DependencyFlags.SoftDependency)] //[BepInDependency(ModCompability.advancedCompanyGuid, BepInDependency.DependencyFlags.SoftDependency)]
[BepInDependency(ModCompability.lethalConfigGuid, BepInDependency.DependencyFlags.SoftDependency)] [BepInDependency(ModCompability.lethalConfigGuid, BepInDependency.DependencyFlags.SoftDependency)]
[BepInDependency(ModCompability.facilityMeldownGuid, BepInDependency.DependencyFlags.SoftDependency)] [BepInDependency(ModCompability.facilityMeldownGuid, BepInDependency.DependencyFlags.SoftDependency)]
[BepInDependency(ModCompability.reserveFlashlightGuid, BepInDependency.DependencyFlags.SoftDependency)] [BepInDependency(ModCompability.reserveFlashlightGuid, BepInDependency.DependencyFlags.SoftDependency)]
[BepInDependency(ModCompability.reserveKeyGuid, BepInDependency.DependencyFlags.SoftDependency)]
[BepInProcess("Lethal Company.exe")] [BepInProcess("Lethal Company.exe")]
public class Plugin : BaseUnityPlugin { public class Plugin : BaseUnityPlugin {
public const string modGUID = "dev.ladyalice.scarletmansion"; public const string modGUID = "dev.ladyalice.scarletmansion";
private const string modName = "Scarlet Mansion"; private const string modName = "Scarlet Mansion";
private const string modVersion = "1.3.22"; private const string modVersion = "1.3.23";
public readonly Harmony harmony = new Harmony(modGUID); public readonly Harmony harmony = new Harmony(modGUID);

View File

@ -37,6 +37,7 @@ namespace ScarletMansion {
public const string dungeonFeaturesPrefix = "Dungeon Features"; public const string dungeonFeaturesPrefix = "Dungeon Features";
public const string dungeonPaintingEventPrefix = "Dungeon Painting Event"; public const string dungeonPaintingEventPrefix = "Dungeon Painting Event";
public const string dungeonTreasureRoomPrefix = "Dungeon Treasure Rooms";
public const string dungeonLightingPrefix = "Lighting"; public const string dungeonLightingPrefix = "Lighting";
public const string presetsPrefix = "_Presets"; public const string presetsPrefix = "_Presets";
@ -431,6 +432,31 @@ namespace ScarletMansion {
public bool paintingEnemyEvilSkinValue; public bool paintingEnemyEvilSkinValue;
public bool facilityMeltdownActiveValue; public bool facilityMeltdownActiveValue;
// treasure room
public static ConfigEntryBundle<int> treasureRoomCount = new ConfigEntryBundle<int>(
dungeonTreasureRoomPrefix,
"Treasure Room Count",
2,
"The maximum amount of treasure rooms that spawn in the dungeon.",
null,
new AcceptableValueRange<int>(0, 10)
);
public static ConfigEntryBundleMinMax<int> treasureRoomLoot = new ConfigEntryBundleMinMax<int>(
dungeonTreasureRoomPrefix,
"Treasure Room Loot Min",
"Treasure Room Loot Max",
2,
3,
"The minimum allowed amount of loot that spawns in the treasure room.",
"The maximum allowed amount of loot that spawns in the treasure room.",
null,
new AcceptableValueRange<int>(0, 6)
);
public int treasureRoomCountValue;
public IntRange treasureRoomLootValue = new IntRange("treasure room loot");
// lighting // lighting
public static ConfigEntryBundle<int> hallwayLightsWeight = new ConfigEntryBundle<int>( public static ConfigEntryBundle<int> hallwayLightsWeight = new ConfigEntryBundle<int>(
dungeonLightingPrefix, dungeonLightingPrefix,

View File

@ -42,6 +42,9 @@ namespace ScarletMansion {
new ChangeInt ( PluginConfig.paintingCount ), new ChangeInt ( PluginConfig.paintingCount ),
new ChangeMinMaxInt( PluginConfig.paintingExtraLoot ), new ChangeMinMaxInt( PluginConfig.paintingExtraLoot ),
new ChangeInt( PluginConfig.treasureRoomCount ),
new ChangeMinMaxInt( PluginConfig.treasureRoomLoot ),
new ChangeFloat ( PluginConfig.mapHazardsMultiplier ), new ChangeFloat ( PluginConfig.mapHazardsMultiplier ),
new ChangeInt ( PluginConfig.minIndoorEnemySpawnCount ) new ChangeInt ( PluginConfig.minIndoorEnemySpawnCount )
@ -72,6 +75,9 @@ namespace ScarletMansion {
new ChangeInt ( PluginConfig.paintingCount, 3 ), new ChangeInt ( PluginConfig.paintingCount, 3 ),
new ChangeMinMaxInt( PluginConfig.paintingExtraLoot, 1 , 3 ), new ChangeMinMaxInt( PluginConfig.paintingExtraLoot, 1 , 3 ),
new ChangeInt( PluginConfig.treasureRoomCount, 3 ),
new ChangeMinMaxInt( PluginConfig.treasureRoomLoot, 3, 4 ),
new ChangeFloat ( PluginConfig.mapHazardsMultiplier, 2.2f ), new ChangeFloat ( PluginConfig.mapHazardsMultiplier, 2.2f ),
new ChangeInt ( PluginConfig.minIndoorEnemySpawnCount, 2 ) new ChangeInt ( PluginConfig.minIndoorEnemySpawnCount, 2 )
@ -85,7 +91,8 @@ namespace ScarletMansion {
new ChangeFloat ( PluginConfig.lootMultiplier, 1.5f ), new ChangeFloat ( PluginConfig.lootMultiplier, 1.5f ),
new ChangeInt ( PluginConfig.paintingCount, 3 ), new ChangeInt ( PluginConfig.paintingCount, 3 ),
new ChangeMinMaxInt( PluginConfig.paintingExtraLoot, 1 , 3 ),
new ChangeInt( PluginConfig.treasureRoomCount, 3 ),
new ChangeFloat ( PluginConfig.mapHazardsMultiplier, 1.75f ), new ChangeFloat ( PluginConfig.mapHazardsMultiplier, 1.75f ),
new ChangeInt ( PluginConfig.minIndoorEnemySpawnCount, 2 ) new ChangeInt ( PluginConfig.minIndoorEnemySpawnCount, 2 )

View File

@ -172,7 +172,12 @@
<Compile Include="GamePatch\Components\ScarletRadio.cs" /> <Compile Include="GamePatch\Components\ScarletRadio.cs" />
<Compile Include="GamePatch\Components\ScarletVent.cs" /> <Compile Include="GamePatch\Components\ScarletVent.cs" />
<Compile Include="GamePatch\Components\ScarletYukariTrigger.cs" /> <Compile Include="GamePatch\Components\ScarletYukariTrigger.cs" />
<Compile Include="GamePatch\Components\TreasureRoom\TreasureRoomTimedOpen.cs" /> <Compile Include="GamePatch\Components\TreasureRoom\TreasureRoom.cs" />
<Compile Include="GamePatch\Components\TreasureRoom\TreasureRoomBookSwitch.cs" />
<Compile Include="GamePatch\Components\TreasureRoom\TreasureRoomBookZone.cs" />
<Compile Include="GamePatch\Components\TreasureRoom\TreasureRoomDoorStatus.cs" />
<Compile Include="GamePatch\Components\TreasureRoom\TreasureRoomTimeEvent.cs" />
<Compile Include="GamePatch\Components\TreasureRoom\TreasureRoomBookPullEvent.cs" />
<Compile Include="GamePatch\DoorLockPatch.cs" /> <Compile Include="GamePatch\DoorLockPatch.cs" />
<Compile Include="GamePatch\Enemies\KnightGhostVariant.cs" /> <Compile Include="GamePatch\Enemies\KnightGhostVariant.cs" />
<Compile Include="GamePatch\Enemies\KnightVariant.cs" /> <Compile Include="GamePatch\Enemies\KnightVariant.cs" />
@ -186,6 +191,7 @@
<Compile Include="GamePatch\FixValues\FixHoverIcon.cs" /> <Compile Include="GamePatch\FixValues\FixHoverIcon.cs" />
<Compile Include="GamePatch\FixValues\FixRandomMapObject.cs" /> <Compile Include="GamePatch\FixValues\FixRandomMapObject.cs" />
<Compile Include="GamePatch\FixValues\FixSpawnItemGroup.cs" /> <Compile Include="GamePatch\FixValues\FixSpawnItemGroup.cs" />
<Compile Include="GamePatch\FixValues\FixTreasureRoom.cs" />
<Compile Include="GamePatch\InitPatch.cs" /> <Compile Include="GamePatch\InitPatch.cs" />
<Compile Include="GamePatch\Items\FlandreCrystal.cs" /> <Compile Include="GamePatch\Items\FlandreCrystal.cs" />
<Compile Include="GamePatch\Items\IScarletItem.cs" /> <Compile Include="GamePatch\Items\IScarletItem.cs" />
@ -221,7 +227,8 @@
<Compile Include="ModPatch\LethalConfigPatch.cs" /> <Compile Include="ModPatch\LethalConfigPatch.cs" />
<Compile Include="ModPatch\ModCompability.cs" /> <Compile Include="ModPatch\ModCompability.cs" />
<Compile Include="ModPatch\ModPatch.cs" /> <Compile Include="ModPatch\ModPatch.cs" />
<Compile Include="ModPatch\ReservedItemSlotPatch.cs" /> <Compile Include="ModPatch\ReservedFlashlightPatch.cs" />
<Compile Include="ModPatch\ReservedKeyPatch.cs" />
<Compile Include="Plugin.cs" /> <Compile Include="Plugin.cs" />
<Compile Include="PluginConfig.cs" /> <Compile Include="PluginConfig.cs" />
<Compile Include="PluginConfigClasses.cs" /> <Compile Include="PluginConfigClasses.cs" />

View File

@ -117,6 +117,10 @@ namespace ScarletMansion {
public static class Utility { public static class Utility {
public static float GetRandomNumber(this System.Random random, double minimum, double maximum) {
return (float)(random.NextDouble() * (maximum - minimum) + minimum);
}
public class ParsedString { public class ParsedString {
public string main; public string main;
public string[] parameters; public string[] parameters;