Added more radio music, based on dungeon variant.

Redid vent code to work better and like work in general.
Knight animation now pauses for a second.
Knights no longer trigger the default scarlet vent animation.
Revenants now spawn at a vent if no knights exist.
This commit is contained in:
LadyAliceMargatroid 2025-01-15 20:41:48 -08:00
parent e28f3ca2db
commit f37cded831
14 changed files with 285 additions and 114 deletions

View File

@ -93,7 +93,7 @@ namespace ScarletMansion.DunGenPatch {
var addTilesProperties = props.AdditionalTilesProperties; var addTilesProperties = props.AdditionalTilesProperties;
var copyTarget = addTilesProperties.AdditionalTileSets[0]; var copyTarget = addTilesProperties.AdditionalTileSets[0];
addTilesProperties.AdditionalTileSets = new List<AdditionalTileSetList>(); addTilesProperties.AdditionalTileSets = new List<AdditionalTileSetList>();
for(var j = 0; j < count; ++j) addTilesProperties.AdditionalTileSets.Add(copyTarget); for(var j = 0; j < count; ++j) addTilesProperties.AdditionalTileSets.Add(copyTarget);
Lights.ScarletLightCleanup.weights = new float[] { Lights.ScarletLightCleanup.weights = new float[] {
@ -104,12 +104,12 @@ namespace ScarletMansion.DunGenPatch {
DungeonFlow.GlobalPropSettings GetGlobalPropSetting(int id) { DungeonFlow.GlobalPropSettings GetGlobalPropSetting(int id) {
foreach(var p in dungeonConfig.dungeon.GlobalProps){ foreach(var p in dungeonConfig.dungeon.GlobalProps){
if (p.ID == id ) return p; if (p.ID == id) return p;
} }
return null; return null;
} }
GetGlobalPropSetting(254).Count = new DunGen.IntRange( GetGlobalPropSetting(254).Count = new IntRange(
dungeonConfig.paintingCountValue, dungeonConfig.paintingCountValue,
dungeonConfig.paintingCountValue dungeonConfig.paintingCountValue
); );

View File

@ -5,12 +5,23 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using UnityEngine; using UnityEngine;
using UnityEngine.Events;
namespace ScarletMansion { namespace ScarletMansion {
public class KnightSpawnPoint : MonoBehaviour { public class KnightSpawnPoint : MonoBehaviour {
//[System.Serializable]
//public class OnRemoveUnityEvent {
// public UnityEvent onSelected;
// public UnityEvent onStop;
//}
//public OnRemoveUnityEvent onRemoveNormalUnityEvent;
//public OnRemoveUnityEvent onRemoveGhostUnityEvent;
public int index; public int index;
public GameObject renderGameObject;
public void Start(){ public void Start(){
if (GameNetworkManager.Instance.isHostingGame) if (GameNetworkManager.Instance.isHostingGame)
@ -45,6 +56,13 @@ namespace ScarletMansion {
} }
} }
public void OnStop(){
renderGameObject.SetActive(false);
StopAllCoroutines();
//GetUnityEvent(isNormal).onStop.Invoke();
}
} }
} }

View File

@ -21,7 +21,7 @@ namespace ScarletMansion.GamePatch.Components {
public static ActionList onBedroomEndEvent = new ActionList("onBedroomEnd"); public static ActionList onBedroomEndEvent = new ActionList("onBedroomEnd");
[Header("References")] [Header("References")]
public ScarletVent vent; public ScarletVentVisuals vent;
public Transform paintingSpawnTransform; public Transform paintingSpawnTransform;
public AudioSource screamAudioSource; public AudioSource screamAudioSource;
public Transform[] itemSpawns; public Transform[] itemSpawns;
@ -32,7 +32,7 @@ namespace ScarletMansion.GamePatch.Components {
private EnemyReferenceSpawnLogic bonusEnemy; private EnemyReferenceSpawnLogic bonusEnemy;
const float spawnTime = 10f; const float spawnTime = 10f;
const float cloudTime = 4f; const float cloudTime = 7f;
public void Anger(Transform target){ public void Anger(Transform target){
AngerManager.Instance.Anger(); AngerManager.Instance.Anger();
@ -84,9 +84,9 @@ namespace ScarletMansion.GamePatch.Components {
onBedroomEndEvent.Call(); onBedroomEndEvent.Call();
// stop volume stuff // stop volume stuff
vent.OpenVentClientRpc(); vent.StopSpawnParticles();
vent.shakeAudioSource.Stop(); vent.StopLightningParticles();
vent.shakeAudioSource.volume = 0f; ScarletNetworkManager.Instance.CreateSpawnAudioPrefabLocal(target.transform.position);
// unlock doors // unlock doors
if (roundmanager.IsServer){ if (roundmanager.IsServer){
@ -97,13 +97,13 @@ namespace ScarletMansion.GamePatch.Components {
} }
public IEnumerator IncreaseVentAudio(){ public IEnumerator IncreaseVentAudio(){
yield return new WaitForSeconds(1f); yield return new WaitForSeconds(3f);
vent.shakeAudioSource.Play(); vent.StartSpawnParticles();
var t = 0f; var t = 0f;
while (t < cloudTime){ while (t < cloudTime){
vent.shakeAudioSource.volume = t / cloudTime;
t += Time.deltaTime; t += Time.deltaTime;
vent.SetVolumeLazy(t / cloudTime);
yield return null; yield return null;
} }
} }

View File

@ -41,12 +41,19 @@ namespace ScarletMansion.GamePatch.Components {
void Start() { void Start() {
audioSource.volume = maxVolume * (volume * 0.1f); audioSource.volume = maxVolume * (volume * 0.1f);
var inst = ScarletGenericManager.Instance;
if (inst) {
audioClips = inst.radioAudioClips;
}
} }
public override void OnNetworkSpawn() { public override void OnNetworkSpawn() {
if (IsOwner) { if (IsOwner) {
ToggleOnOffSwitchClientRpc(UnityEngine.Random.value > 0.9f); ToggleOnOffSwitchClientRpc(UnityEngine.Random.value > 0.9f);
ToggleVolumeSwitchClientRpc(UnityEngine.Random.Range(3, 7)); ToggleVolumeSwitchClientRpc(UnityEngine.Random.Range(3, 7));
if (audioClips.Length == 0) return;
ToggleSongSwitchClientRpc(UnityEngine.Random.Range(0, audioClips.Length)); ToggleSongSwitchClientRpc(UnityEngine.Random.Range(0, audioClips.Length));
} }
} }
@ -112,6 +119,8 @@ namespace ScarletMansion.GamePatch.Components {
[ServerRpc(RequireOwnership = false)] [ServerRpc(RequireOwnership = false)]
public void ToggleSongSwitchServerRpc(){ public void ToggleSongSwitchServerRpc(){
if (audioClips.Length == 0) return;
ToggleSongSwitchClientRpc((audioIndex + 1) % audioClips.Length); ToggleSongSwitchClientRpc((audioIndex + 1) % audioClips.Length);
treasureRoomEvent?.UpdateTreasureDoorStatus(); treasureRoomEvent?.UpdateTreasureDoorStatus();
} }

View File

@ -1,4 +1,5 @@
using System; using ScarletMansion.GamePatch.Components;
using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
@ -7,61 +8,43 @@ using System.Threading.Tasks;
using UnityEngine; using UnityEngine;
namespace ScarletMansion { namespace ScarletMansion {
public class ScarletVent : MonoBehaviour { public class ScarletVent : EnemyVent {
public AudioSource shakeAudioSource; [Header("References")]
public AudioSource summonAudioSource; public ScarletVentVisuals visuals;
public PlayAudioAnimationEvent audioEvent; public EnemyType ignoreEnemyType;
[Header("Shake")] void Awake(){
public ParticleSystem spawningPartciles; ignoreEnemyType = Assets.knight.enemyType;
public ParticleSystem lightingParticles; }
public ParticleSystem emitParticles;
public float volumeToRate = 1f;
public static bool prewarm; public void ScarletUpdate(){
if (occupied && enemyType != ignoreEnemyType){
var startTime = spawnTime - roundManager.timeScript.currentDayTime;
if (isPlayingAudio) {
var lerp = Mathf.Abs(startTime / enemyType.timeToPlayAudio - 1f);
visuals.SetVolumeLazy(lerp);
lowPassFilter.lowpassResonanceQ = Math.Abs(lerp * 2f - 2f);
return;
}
void Start(){ if (startTime < enemyType.timeToPlayAudio) {
if (!prewarm){ isPlayingAudio = true;
OpenVentClientRpc(); visuals.StartSpawnParticles();
prewarm = true; return;
Plugin.logger.LogDebug("Prewarming particles by forcing it emit now lmao"); }
} else if (isPlayingAudio) {
isPlayingAudio = false;
visuals.StopSpawnParticles();
visuals.StopLightningParticles();
} }
}
private void PlayParticleSystem(ParticleSystem ps){
if (ps.isPlaying) return;
ps.Play();
}
private void StopParticleSystem(ParticleSystem ps){
if (!ps.isPlaying) return;
ps.Stop();
} }
public void OpenVentClientRpc(){ public void OpenVentClientRpc(){
emitParticles.Play(); ScarletNetworkManager.Instance.CreateSpawnAudioPrefabLocal(transform.position);
audioEvent.PlayAudio1Oneshot();
} }
void Update(){
var isPlaying = shakeAudioSource.isPlaying;
if (isPlaying){
PlayParticleSystem(spawningPartciles);
SetEmissionRate(spawningPartciles, shakeAudioSource.volume * volumeToRate);
if (shakeAudioSource.volume >= 0.8f) PlayParticleSystem(lightingParticles);
else StopParticleSystem(lightingParticles);
} else {
StopParticleSystem(spawningPartciles);
StopParticleSystem(lightingParticles);
}
}
private void SetEmissionRate(ParticleSystem ps, float mult){
var emis = ps.emission;
emis.rateOverTimeMultiplier = mult;
}
} }
} }

View File

@ -0,0 +1,109 @@
using OdinSerializer;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Remoting.Metadata.W3cXsd2001;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
namespace ScarletMansion.GamePatch.Components
{
public class ScarletVentVisuals : MonoBehaviour {
[Header("Shake")]
public AudioSource shakeAudioSource;
public ParticleSystem spawningPartciles;
[Header("Shake")]
public AudioSource lightingAudioSource;
public ParticleSystem lightingParticles;
public static bool prewarm;
void Start(){
if (!prewarm){
prewarm = true;
Plugin.logger.LogDebug("Prewarming particles by forcing it emit now lmao");
}
}
private IEnumerator StopAudioSourceLerp(AudioSource audioSource, float volume){
while(audioSource.volume != volume){
audioSource.volume = Mathf.MoveTowards(audioSource.volume, volume, Time.deltaTime * 2f);
yield return null;
}
if (volume == 0f) audioSource.Stop();
}
public void SetVolumeLazy(float volume){
SetSpawnParticlesVolume(volume);
var altVolume = Mathf.InverseLerp(0.7f, 1f, volume);
if (altVolume > 0f){
StartLightningParticles();
SetLightningVolume(altVolume);
}
}
private Coroutine previousSpawnParticlesCoroutine;
public void StartSpawnParticles(){
if (!spawningPartciles.isPlaying) {
spawningPartciles.Play();
shakeAudioSource.Play();
shakeAudioSource.volume = 0f;
}
}
public void StopSpawnParticles(){
if (spawningPartciles.isPlaying) {
spawningPartciles.Stop();
spawningPartciles.Clear();
if (previousSpawnParticlesCoroutine != null) StopCoroutine(previousSpawnParticlesCoroutine);
previousSpawnParticlesCoroutine = StartCoroutine(StopAudioSourceLerp(shakeAudioSource, 0f));
}
}
public void SetSpawnParticlesVolume(float volume){
shakeAudioSource.volume = volume * 0.6f;
SetEmissionRate(spawningPartciles, volume * 5f);
}
private Coroutine previousLightningParticlesCoroutine;
public void StartLightningParticles(){
if (!lightingParticles.isPlaying) {
lightingParticles.Play();
lightingAudioSource.Play();
lightingAudioSource.volume = 0f;
}
}
public void StopLightningParticles(){
if (lightingParticles.isPlaying) {
lightingParticles.Stop();
if (previousLightningParticlesCoroutine != null) StopCoroutine(previousLightningParticlesCoroutine);
previousLightningParticlesCoroutine = StartCoroutine(StopAudioSourceLerp(lightingAudioSource, 0f));
}
}
public void SetLightningVolume(float volume){
lightingAudioSource.volume = volume * 0.6f;
}
private void SetEmissionRate(ParticleSystem ps, float mult){
var emis = ps.emission;
emis.rateOverTimeMultiplier = mult;
}
}
}

View File

@ -24,6 +24,9 @@ namespace ScarletMansion {
public AudioClip[] ramAudioClips; public AudioClip[] ramAudioClips;
public KnightSpawnPoint spawnPoint;
public bool activated;
public override void Start(){ public override void Start(){
base.Start(); base.Start();
@ -31,10 +34,18 @@ namespace ScarletMansion {
if (IsOwner && KnightSpawnManager.Instance) { if (IsOwner && KnightSpawnManager.Instance) {
var index = KnightSpawnManager.Instance.GetSpawnPointIndex(); var index = KnightSpawnManager.Instance.GetSpawnPointIndex();
if (index == -1) return; if (index == -1) {
// grab position instead
var allVents = RoundManager.Instance.allEnemyVents;
var anyEnemyVent = allVents[UnityEngine.Random.Range(0, allVents.Length)];
SyncKnightAtPositionClientRpc(anyEnemyVent.floorNode.position, Quaternion.Euler(0f, anyEnemyVent.floorNode.eulerAngles.y, 0f));
return;
}
SyncKnightReplacementClientRpc(index); SyncKnightReplacementClientRpc(index);
} }
} }
public override void DoAIInterval() { public override void DoAIInterval() {
@ -44,6 +55,7 @@ namespace ScarletMansion {
if (targetPlayer == null || !targetPlayer.IsOwner) return; if (targetPlayer == null || !targetPlayer.IsOwner) return;
if (isEnemyDead) return; if (isEnemyDead) return;
if (timeSinceSpawn < 1f) return;
var targetOutOfMap = !PlayerIsTargetable(targetPlayer); var targetOutOfMap = !PlayerIsTargetable(targetPlayer);
if (targetOutOfMap){ if (targetOutOfMap){
@ -67,6 +79,12 @@ namespace ScarletMansion {
public override void Update() { public override void Update() {
base.Update(); base.Update();
if (isEnemyDead) return; if (isEnemyDead) return;
if (timeSinceSpawn < 1f) return;
if (!activated) {
activated = true;
creatureAnimator.SetBool("Activate", true);
}
var trueSpeed = currentBehaviourStateIndex == 0 ? maxChaseSpeed : slowChaseSpeed; var trueSpeed = currentBehaviourStateIndex == 0 ? maxChaseSpeed : slowChaseSpeed;
if (IsOwner) { if (IsOwner) {
@ -80,6 +98,8 @@ namespace ScarletMansion {
public override void OnCollideWithPlayer(Collider other) { public override void OnCollideWithPlayer(Collider other) {
base.OnCollideWithPlayer(other); base.OnCollideWithPlayer(other);
if (timeSinceSpawn < 1f) return;
var playerControllerB = MeetsStandardPlayerCollisionConditions(other, false, false); var playerControllerB = MeetsStandardPlayerCollisionConditions(other, false, false);
if (playerControllerB != null && playerControllerB.IsOwner && playerControllerB == targetPlayer) { if (playerControllerB != null && playerControllerB.IsOwner && playerControllerB == targetPlayer) {
var damage = ScarletNetworkManagerUtility.GetMarkedDamageToPlayer(playerControllerB); var damage = ScarletNetworkManagerUtility.GetMarkedDamageToPlayer(playerControllerB);
@ -92,7 +112,7 @@ namespace ScarletMansion {
Assets.onPlayerDeath.Call(new ModPatch.CoronerParameters(playerControllerB, ModPatch.CoronerDeathEnum.GhostKnight)); Assets.onPlayerDeath.Call(new ModPatch.CoronerParameters(playerControllerB, ModPatch.CoronerDeathEnum.GhostKnight));
} }
RoundManager.PlayRandomClip(creatureVoice, ramAudioClips, false, 1f, 0); RoundManager.PlayRandomClip(creatureVoice, ramAudioClips, false, 1f, 1);
CallDisappear(); CallDisappear();
} }
} }
@ -102,25 +122,26 @@ namespace ScarletMansion {
Plugin.logger.LogDebug($"Spawning ghost knight at {index}"); Plugin.logger.LogDebug($"Spawning ghost knight at {index}");
try { try {
var target = KnightSpawnManager.Instance.GetSpawnPointTransform(index); spawnPoint = KnightSpawnManager.Instance.GetSpawnPoint(index);
target.gameObject.SetActive(false); KnightSpawnManager.Instance.SpawnEnemyOnSpawnPoint(this, spawnPoint);
transform.position = target.position;
transform.rotation = target.rotation;
serverPosition = target.position;
if (agent == null) agent = GetComponentInChildren<NavMeshAgent>();
agent.Warp(target.position);
if (IsOwner) {
SyncPositionToClients();
}
} catch (Exception e){ } catch (Exception e){
Plugin.logger.LogError($"Tried to ghost knight spawn at {index}, but completely failed"); Plugin.logger.LogError($"Tried to ghost knight spawn at {index}, but completely failed");
Plugin.logger.LogError(e); Plugin.logger.LogError(e);
} }
} }
[ClientRpc]
public void SyncKnightAtPositionClientRpc(Vector3 position, Quaternion rotation){
Plugin.logger.LogDebug($"Spawning ghost knight at {position}");
try {
KnightSpawnManager.Instance.SpawnEnemyOnSpawnPoint(this, position, rotation);
} catch (Exception e){
Plugin.logger.LogError($"Tried to ghost knight spawn at {position}, but completely failed");
Plugin.logger.LogError(e);
}
}
public void FindAndTunnelPlayer(Vector3 searchPosition){ public void FindAndTunnelPlayer(Vector3 searchPosition){
var validPlayers = StartOfRound.Instance.allPlayerScripts.Where(p => p != null && PlayerIsTargetable(p)); var validPlayers = StartOfRound.Instance.allPlayerScripts.Where(p => p != null && PlayerIsTargetable(p));

View File

@ -48,6 +48,9 @@ namespace ScarletMansion.GamePatch.Enemies {
// Token: 0x04000F2A RID: 3882 // Token: 0x04000F2A RID: 3882
private bool inCooldownAnimation; private bool inCooldownAnimation;
public KnightSpawnPoint spawnPoint;
public bool activated;
public override void Start(){ public override void Start(){
base.Start(); base.Start();
@ -56,7 +59,10 @@ namespace ScarletMansion.GamePatch.Enemies {
if (IsOwner && KnightSpawnManager.Instance) { if (IsOwner && KnightSpawnManager.Instance) {
var index = KnightSpawnManager.Instance.GetSpawnPointIndex(); var index = KnightSpawnManager.Instance.GetSpawnPointIndex();
if (index == -1) return; Plugin.logger.LogInfo($"Selected index {index}");
if (index == -1) {
return;
}
SyncKnightReplacementClientRpc(index); SyncKnightReplacementClientRpc(index);
} }
@ -95,7 +101,8 @@ namespace ScarletMansion.GamePatch.Enemies {
base.DoAIInterval(); base.DoAIInterval();
if (StartOfRound.Instance.allPlayersDead) return; if (StartOfRound.Instance.allPlayersDead) return;
if (isEnemyDead) return; if (isEnemyDead) return;
if (timeSinceSpawn < 1f) return;
var currentBehaviourStateIndex = this.currentBehaviourStateIndex; var currentBehaviourStateIndex = this.currentBehaviourStateIndex;
if (currentBehaviourStateIndex != 0) { if (currentBehaviourStateIndex != 0) {
if (currentBehaviourStateIndex != 1) return; if (currentBehaviourStateIndex != 1) return;
@ -242,7 +249,13 @@ namespace ScarletMansion.GamePatch.Enemies {
base.Update(); base.Update();
if (isEnemyDead) return; if (isEnemyDead) return;
if (hitPlayerTimer >= 0f) hitPlayerTimer -= Time.deltaTime; if (hitPlayerTimer >= 0f) hitPlayerTimer -= Time.deltaTime;
if (timeSinceSpawn < 1f) return;
if (!activated) {
activated = true;
creatureAnimator.SetBool("Activate", true);
}
if (!IsOwner) { if (!IsOwner) {
stopMovementTimer = 5f; stopMovementTimer = 5f;
loseAggroTimer = 0f; loseAggroTimer = 0f;
@ -419,6 +432,8 @@ namespace ScarletMansion.GamePatch.Enemies {
return; return;
} }
if (timeSinceSpawn < 1f) return;
var playerControllerB = MeetsStandardPlayerCollisionConditions(other, false, false); var playerControllerB = MeetsStandardPlayerCollisionConditions(other, false, false);
if (playerControllerB != null) { if (playerControllerB != null) {
hitPlayerTimer = 0.2f; hitPlayerTimer = 0.2f;
@ -443,19 +458,9 @@ namespace ScarletMansion.GamePatch.Enemies {
Plugin.logger.LogDebug($"Spawning knight at {index}"); Plugin.logger.LogDebug($"Spawning knight at {index}");
try { try {
var target = KnightSpawnManager.Instance.GetSpawnPointTransform(index); spawnPoint = KnightSpawnManager.Instance.GetSpawnPoint(index);
target.gameObject.SetActive(false); KnightSpawnManager.Instance.SpawnEnemyOnSpawnPoint(this, spawnPoint);
transform.position = target.position;
transform.rotation = target.rotation;
serverPosition = target.position;
if (agent == null) agent = GetComponentInChildren<NavMeshAgent>();
agent.Warp(target.position);
if (IsOwner) {
SyncPositionToClients();
}
} catch (Exception e){ } catch (Exception e){
Plugin.logger.LogError($"Tried to knight spawn at {index}, but completely failed"); Plugin.logger.LogError($"Tried to knight spawn at {index}, but completely failed");
Plugin.logger.LogError(e); Plugin.logger.LogError(e);

View File

@ -221,26 +221,7 @@ namespace ScarletMansion {
} }
public void SyncKnightReplacement(int index){ public void SyncKnightReplacement(int index){
Plugin.logger.LogDebug($"Spawning knight at {index}");
try {
var target = KnightSpawnManager.Instance.GetSpawnPointTransform(index);
target.gameObject.SetActive(false);
transform.position = target.position;
transform.rotation = target.rotation;
serverPosition = target.position;
if (agent == null) agent = GetComponentInChildren<NavMeshAgent>();
agent.Warp(target.position);
if (IsOwner) {
SyncPositionToClients();
}
} catch (Exception e){
Plugin.logger.LogError($"Tried to knight spawn at {index}, but completely failed");
Plugin.logger.LogError(e);
}
} }

View File

@ -5,6 +5,7 @@ using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using UnityEngine; using UnityEngine;
using HarmonyLib; using HarmonyLib;
using OdinSerializer;
namespace ScarletMansion.GamePatch { namespace ScarletMansion.GamePatch {
[HarmonyPatch(typeof(EnemyVent))] [HarmonyPatch(typeof(EnemyVent))]
@ -35,14 +36,25 @@ namespace ScarletMansion.GamePatch {
public static void OpenVentClientRpcPatchPost(ref EnemyVent __instance){ public static void OpenVentClientRpcPatchPost(ref EnemyVent __instance){
if (setActive == false) return; if (setActive == false) return;
var comp = __instance.GetComponent<ScarletVent>(); var scarlet = __instance as ScarletVent;
if (comp) { if (scarlet && (scarlet.enemyType != scarlet.ignoreEnemyType || !KnightSpawnManager.WillSpawnOnSpawnPoint())) {
Plugin.logger.LogDebug("Doing scalet open vent"); Plugin.logger.LogDebug("Doing scalet open vent");
comp.OpenVentClientRpc(); scarlet.OpenVentClientRpc();
} }
setActive = false; setActive = false;
} }
[HarmonyPrefix]
[HarmonyPatch("Update")]
public static bool UpdatePrePatch(ref EnemyVent __instance){
var scarlet = __instance as ScarletVent;
if (scarlet != null) {
scarlet.ScarletUpdate();
return false;
}
return true;
}
} }
} }

View File

@ -5,6 +5,8 @@ using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using UnityEngine; using UnityEngine;
using DunGen; using DunGen;
using static LethalLevelLoader.ExtendedEvent;
using UnityEngine.AI;
namespace ScarletMansion { namespace ScarletMansion {
@ -22,6 +24,13 @@ namespace ScarletMansion {
Instance = this; Instance = this;
} }
public static bool WillSpawnOnSpawnPoint(){
if (Instance) {
return !Instance.disableNextKnightSpecialSpawn && Instance.spawnPoints.Count > 0;
}
return false;
}
public void OnDungeonComplete(Dungeon dungeon) { public void OnDungeonComplete(Dungeon dungeon) {
var points = dungeon.GetComponentsInChildren<KnightSpawnPoint>(); var points = dungeon.GetComponentsInChildren<KnightSpawnPoint>();
spawnPoints = points.ToList(); spawnPoints = points.ToList();
@ -60,10 +69,29 @@ namespace ScarletMansion {
return item.index; return item.index;
} }
public Transform GetSpawnPointTransform(int index){ public KnightSpawnPoint GetSpawnPoint(int index){
return spawnPoints[index].transform; return spawnPoints[index];
} }
public void SpawnEnemyOnSpawnPoint(EnemyAI enemyAI, KnightSpawnPoint spawnPoint){
SpawnEnemyOnSpawnPoint(enemyAI, spawnPoint.transform.position, spawnPoint.transform.rotation);
spawnPoint.OnStop();
}
public void SpawnEnemyOnSpawnPoint(EnemyAI enemyAI, Vector3 position, Quaternion rotation){
enemyAI.transform.position = position;
enemyAI.transform.rotation = rotation;
enemyAI.serverPosition = position;
if (enemyAI.agent == null) enemyAI.agent = GetComponentInChildren<NavMeshAgent>();
enemyAI.agent.Warp(position);
if (enemyAI.IsOwner) {
enemyAI.SyncPositionToClients();
}
ScarletNetworkManager.Instance?.CreateSpawnAudioPrefabLocal(position);
}
} }
} }

View File

@ -16,6 +16,10 @@ namespace ScarletMansion.GamePatch.Managers {
public static ScarletGenericManager Instance { get; private set; } public static ScarletGenericManager Instance { get; private set; }
[Header("Settings")]
public AudioClip[] radioAudioClips;
[Header("Debug")]
public List<Transform> roomsOfInterest; public List<Transform> roomsOfInterest;
public List<ScarletBedroom> bedrooms; public List<ScarletBedroom> bedrooms;
@ -42,7 +46,8 @@ namespace ScarletMansion.GamePatch.Managers {
} }
void Update(){ void Update(){
if (!StartOfRound.Instance.IsServer) return; if (!StartOfRound.Instance) return;
if (StartOfRound.Instance.IsServer) return;
if (selfDestroyTargets == null) return; if (selfDestroyTargets == null) return;
var time = Utility.GetTime(); var time = Utility.GetTime();

View File

@ -10,7 +10,6 @@ using GameNetcodeStuff;
using ScarletMansion.GamePatch.Items; using ScarletMansion.GamePatch.Items;
using ScarletMansion.GamePatch; using ScarletMansion.GamePatch;
using ScarletMansion.GamePatch.Components; using ScarletMansion.GamePatch.Components;
using static LethalLevelLoader.ExtendedEvent;
using ScarletMansion.GamePatch.Managers; using ScarletMansion.GamePatch.Managers;
using ScarletMansion.Configs; using ScarletMansion.Configs;
@ -306,7 +305,7 @@ namespace ScarletMansion {
public void CreateSpawnAudioPrefab(Vector3 positon, ulong playerId) { public void CreateSpawnAudioPrefab(Vector3 positon, ulong playerId) {
CreateSpawnAudioPrefabServerRpc(positon, playerId); CreateSpawnAudioPrefabServerRpc(positon, playerId);
CreateSpawnAudioPrefab(positon); CreateSpawnAudioPrefabLocal(positon);
} }
[ServerRpc(RequireOwnership = false)] [ServerRpc(RequireOwnership = false)]
@ -317,10 +316,10 @@ namespace ScarletMansion {
[ClientRpc] [ClientRpc]
public void CreateSpawnAudioPrefabClientRpc(Vector3 position, ulong playerId){ public void CreateSpawnAudioPrefabClientRpc(Vector3 position, ulong playerId){
if (StartOfRound.Instance.localPlayerController.actualClientId == playerId) return; if (StartOfRound.Instance.localPlayerController.actualClientId == playerId) return;
CreateSpawnAudioPrefab(position); CreateSpawnAudioPrefabLocal(position);
} }
private void CreateSpawnAudioPrefab(Vector3 position) { public void CreateSpawnAudioPrefabLocal(Vector3 position) {
var copy = Instantiate(Assets.networkObjectList.yukariSpawnPrefab, position, Quaternion.identity); var copy = Instantiate(Assets.networkObjectList.yukariSpawnPrefab, position, Quaternion.identity);
var audioSource = copy.GetComponentInChildren<AudioSource>(); var audioSource = copy.GetComponentInChildren<AudioSource>();
audioSource.time = 0.5f; audioSource.time = 0.5f;

View File

@ -187,6 +187,7 @@
<Compile Include="GamePatch\Components\ScarletProp.cs" /> <Compile Include="GamePatch\Components\ScarletProp.cs" />
<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\ScarletVentVisuals.cs" />
<Compile Include="GamePatch\Components\ScarletYukariTrigger.cs" /> <Compile Include="GamePatch\Components\ScarletYukariTrigger.cs" />
<Compile Include="GamePatch\Components\TreasureRoom\TreasureRoom.cs" /> <Compile Include="GamePatch\Components\TreasureRoom\TreasureRoom.cs" />
<Compile Include="GamePatch\Components\TreasureRoom\TreasureRoomBookSwitch.cs" /> <Compile Include="GamePatch\Components\TreasureRoom\TreasureRoomBookSwitch.cs" />