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:
		
							parent
							
								
									e28f3ca2db
								
							
						
					
					
						commit
						f37cded831
					
				
					 14 changed files with 285 additions and 114 deletions
				
			
		| 
						 | 
				
			
			@ -93,7 +93,7 @@ namespace ScarletMansion.DunGenPatch {
 | 
			
		|||
 | 
			
		||||
      var addTilesProperties = props.AdditionalTilesProperties;
 | 
			
		||||
      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);
 | 
			
		||||
 | 
			
		||||
      Lights.ScarletLightCleanup.weights = new float[] { 
 | 
			
		||||
| 
						 | 
				
			
			@ -104,12 +104,12 @@ namespace ScarletMansion.DunGenPatch {
 | 
			
		|||
 | 
			
		||||
      DungeonFlow.GlobalPropSettings GetGlobalPropSetting(int id) {
 | 
			
		||||
        foreach(var p in dungeonConfig.dungeon.GlobalProps){
 | 
			
		||||
          if (p.ID == id ) return p;
 | 
			
		||||
          if (p.ID == id) return p;
 | 
			
		||||
        }
 | 
			
		||||
        return null;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      GetGlobalPropSetting(254).Count = new DunGen.IntRange(
 | 
			
		||||
      GetGlobalPropSetting(254).Count = new IntRange(
 | 
			
		||||
        dungeonConfig.paintingCountValue, 
 | 
			
		||||
        dungeonConfig.paintingCountValue
 | 
			
		||||
      );
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,12 +5,23 @@ using System.Linq;
 | 
			
		|||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using UnityEngine;
 | 
			
		||||
using UnityEngine.Events;
 | 
			
		||||
 | 
			
		||||
namespace ScarletMansion {
 | 
			
		||||
 | 
			
		||||
  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 GameObject renderGameObject;
 | 
			
		||||
 | 
			
		||||
    public void Start(){
 | 
			
		||||
      if (GameNetworkManager.Instance.isHostingGame) 
 | 
			
		||||
| 
						 | 
				
			
			@ -45,6 +56,13 @@ namespace ScarletMansion {
 | 
			
		|||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void OnStop(){
 | 
			
		||||
      renderGameObject.SetActive(false);
 | 
			
		||||
      StopAllCoroutines();
 | 
			
		||||
 | 
			
		||||
      //GetUnityEvent(isNormal).onStop.Invoke();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,7 +21,7 @@ namespace ScarletMansion.GamePatch.Components {
 | 
			
		|||
    public static ActionList onBedroomEndEvent = new ActionList("onBedroomEnd");
 | 
			
		||||
 | 
			
		||||
    [Header("References")]
 | 
			
		||||
    public ScarletVent vent;
 | 
			
		||||
    public ScarletVentVisuals vent;
 | 
			
		||||
    public Transform paintingSpawnTransform;
 | 
			
		||||
    public AudioSource screamAudioSource;
 | 
			
		||||
    public Transform[] itemSpawns;
 | 
			
		||||
| 
						 | 
				
			
			@ -32,7 +32,7 @@ namespace ScarletMansion.GamePatch.Components {
 | 
			
		|||
    private EnemyReferenceSpawnLogic bonusEnemy;
 | 
			
		||||
 | 
			
		||||
    const float spawnTime = 10f;
 | 
			
		||||
    const float cloudTime = 4f;
 | 
			
		||||
    const float cloudTime = 7f;
 | 
			
		||||
 | 
			
		||||
    public void Anger(Transform target){
 | 
			
		||||
      AngerManager.Instance.Anger();
 | 
			
		||||
| 
						 | 
				
			
			@ -84,9 +84,9 @@ namespace ScarletMansion.GamePatch.Components {
 | 
			
		|||
      onBedroomEndEvent.Call();
 | 
			
		||||
 | 
			
		||||
      // stop volume stuff
 | 
			
		||||
      vent.OpenVentClientRpc();
 | 
			
		||||
      vent.shakeAudioSource.Stop();
 | 
			
		||||
      vent.shakeAudioSource.volume = 0f;
 | 
			
		||||
      vent.StopSpawnParticles();
 | 
			
		||||
      vent.StopLightningParticles();
 | 
			
		||||
      ScarletNetworkManager.Instance.CreateSpawnAudioPrefabLocal(target.transform.position);
 | 
			
		||||
 | 
			
		||||
      // unlock doors
 | 
			
		||||
      if (roundmanager.IsServer){
 | 
			
		||||
| 
						 | 
				
			
			@ -97,13 +97,13 @@ namespace ScarletMansion.GamePatch.Components {
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    public IEnumerator IncreaseVentAudio(){ 
 | 
			
		||||
      yield return new WaitForSeconds(1f);
 | 
			
		||||
      yield return new WaitForSeconds(3f);
 | 
			
		||||
 | 
			
		||||
      vent.shakeAudioSource.Play();
 | 
			
		||||
      vent.StartSpawnParticles();
 | 
			
		||||
      var t = 0f;
 | 
			
		||||
      while (t < cloudTime){
 | 
			
		||||
        vent.shakeAudioSource.volume = t / cloudTime;
 | 
			
		||||
        t += Time.deltaTime;
 | 
			
		||||
        vent.SetVolumeLazy(t / cloudTime);
 | 
			
		||||
        yield return null;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -41,12 +41,19 @@ namespace ScarletMansion.GamePatch.Components {
 | 
			
		|||
 | 
			
		||||
    void Start() {
 | 
			
		||||
      audioSource.volume = maxVolume * (volume * 0.1f);
 | 
			
		||||
 | 
			
		||||
      var inst = ScarletGenericManager.Instance;
 | 
			
		||||
      if (inst) {
 | 
			
		||||
        audioClips = inst.radioAudioClips;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public override void OnNetworkSpawn() {
 | 
			
		||||
      if (IsOwner) {
 | 
			
		||||
        ToggleOnOffSwitchClientRpc(UnityEngine.Random.value > 0.9f);
 | 
			
		||||
        ToggleVolumeSwitchClientRpc(UnityEngine.Random.Range(3, 7));
 | 
			
		||||
 | 
			
		||||
        if (audioClips.Length == 0) return;
 | 
			
		||||
        ToggleSongSwitchClientRpc(UnityEngine.Random.Range(0, audioClips.Length));
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -112,6 +119,8 @@ namespace ScarletMansion.GamePatch.Components {
 | 
			
		|||
 | 
			
		||||
    [ServerRpc(RequireOwnership = false)]
 | 
			
		||||
    public void ToggleSongSwitchServerRpc(){
 | 
			
		||||
      if (audioClips.Length == 0) return;
 | 
			
		||||
 | 
			
		||||
      ToggleSongSwitchClientRpc((audioIndex + 1) % audioClips.Length);
 | 
			
		||||
      treasureRoomEvent?.UpdateTreasureDoorStatus();
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +1,5 @@
 | 
			
		|||
using System;
 | 
			
		||||
using ScarletMansion.GamePatch.Components;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
| 
						 | 
				
			
			@ -7,61 +8,43 @@ using System.Threading.Tasks;
 | 
			
		|||
using UnityEngine;
 | 
			
		||||
 | 
			
		||||
namespace ScarletMansion {
 | 
			
		||||
  public class ScarletVent : MonoBehaviour {
 | 
			
		||||
  public class ScarletVent : EnemyVent {
 | 
			
		||||
 | 
			
		||||
    public AudioSource shakeAudioSource;
 | 
			
		||||
    public AudioSource summonAudioSource;
 | 
			
		||||
    public PlayAudioAnimationEvent audioEvent;
 | 
			
		||||
    [Header("References")]
 | 
			
		||||
    public ScarletVentVisuals visuals;
 | 
			
		||||
    public EnemyType ignoreEnemyType;
 | 
			
		||||
 | 
			
		||||
    [Header("Shake")]
 | 
			
		||||
    public ParticleSystem spawningPartciles;
 | 
			
		||||
    public ParticleSystem lightingParticles;
 | 
			
		||||
    public ParticleSystem emitParticles;
 | 
			
		||||
    public float volumeToRate = 1f;
 | 
			
		||||
    void Awake(){
 | 
			
		||||
      ignoreEnemyType = Assets.knight.enemyType;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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 (!prewarm){
 | 
			
		||||
        OpenVentClientRpc();
 | 
			
		||||
        prewarm = true;
 | 
			
		||||
        Plugin.logger.LogDebug("Prewarming particles by forcing it emit now lmao");
 | 
			
		||||
        if (startTime < enemyType.timeToPlayAudio) {
 | 
			
		||||
          isPlayingAudio = true;
 | 
			
		||||
          visuals.StartSpawnParticles();
 | 
			
		||||
          return;
 | 
			
		||||
        }
 | 
			
		||||
      } 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(){
 | 
			
		||||
      emitParticles.Play();
 | 
			
		||||
      audioEvent.PlayAudio1Oneshot();
 | 
			
		||||
      ScarletNetworkManager.Instance.CreateSpawnAudioPrefabLocal(transform.position);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -24,6 +24,9 @@ namespace ScarletMansion {
 | 
			
		|||
 | 
			
		||||
    public AudioClip[] ramAudioClips;
 | 
			
		||||
 | 
			
		||||
    public KnightSpawnPoint spawnPoint;
 | 
			
		||||
		public bool activated;
 | 
			
		||||
 | 
			
		||||
    public override void Start(){
 | 
			
		||||
      base.Start();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -31,10 +34,18 @@ namespace ScarletMansion {
 | 
			
		|||
 | 
			
		||||
      if (IsOwner && KnightSpawnManager.Instance) {
 | 
			
		||||
        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);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	  public override void DoAIInterval() {
 | 
			
		||||
| 
						 | 
				
			
			@ -44,6 +55,7 @@ namespace ScarletMansion {
 | 
			
		|||
 | 
			
		||||
		  if (targetPlayer == null || !targetPlayer.IsOwner) return;
 | 
			
		||||
      if (isEnemyDead) return;
 | 
			
		||||
      if (timeSinceSpawn < 1f) return;
 | 
			
		||||
 | 
			
		||||
      var targetOutOfMap = !PlayerIsTargetable(targetPlayer);
 | 
			
		||||
      if (targetOutOfMap){
 | 
			
		||||
| 
						 | 
				
			
			@ -67,6 +79,12 @@ namespace ScarletMansion {
 | 
			
		|||
	  public override void Update() {
 | 
			
		||||
		  base.Update();
 | 
			
		||||
		  if (isEnemyDead) return;
 | 
			
		||||
      if (timeSinceSpawn < 1f) return;
 | 
			
		||||
 | 
			
		||||
      if (!activated) { 
 | 
			
		||||
				activated = true;
 | 
			
		||||
				creatureAnimator.SetBool("Activate", true);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
      var trueSpeed = currentBehaviourStateIndex == 0 ? maxChaseSpeed : slowChaseSpeed;
 | 
			
		||||
      if (IsOwner) {
 | 
			
		||||
| 
						 | 
				
			
			@ -80,6 +98,8 @@ namespace ScarletMansion {
 | 
			
		|||
	  public override void OnCollideWithPlayer(Collider other) {
 | 
			
		||||
		  base.OnCollideWithPlayer(other);
 | 
			
		||||
 | 
			
		||||
      if (timeSinceSpawn < 1f) return;
 | 
			
		||||
 | 
			
		||||
		  var playerControllerB = MeetsStandardPlayerCollisionConditions(other, false, false);
 | 
			
		||||
		  if (playerControllerB != null && playerControllerB.IsOwner && playerControllerB == targetPlayer) {
 | 
			
		||||
				var damage = ScarletNetworkManagerUtility.GetMarkedDamageToPlayer(playerControllerB);
 | 
			
		||||
| 
						 | 
				
			
			@ -92,7 +112,7 @@ namespace ScarletMansion {
 | 
			
		|||
					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();
 | 
			
		||||
		  }
 | 
			
		||||
	  }
 | 
			
		||||
| 
						 | 
				
			
			@ -102,25 +122,26 @@ namespace ScarletMansion {
 | 
			
		|||
      Plugin.logger.LogDebug($"Spawning ghost 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();
 | 
			
		||||
        }
 | 
			
		||||
        spawnPoint = KnightSpawnManager.Instance.GetSpawnPoint(index);
 | 
			
		||||
        KnightSpawnManager.Instance.SpawnEnemyOnSpawnPoint(this, spawnPoint);
 | 
			
		||||
      } catch (Exception e){
 | 
			
		||||
        Plugin.logger.LogError($"Tried to ghost knight spawn at {index}, but completely failed");
 | 
			
		||||
        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){
 | 
			
		||||
      var validPlayers = StartOfRound.Instance.allPlayerScripts.Where(p => p != null && PlayerIsTargetable(p));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -48,6 +48,9 @@ namespace ScarletMansion.GamePatch.Enemies {
 | 
			
		|||
 | 
			
		||||
		// Token: 0x04000F2A RID: 3882
 | 
			
		||||
		private bool inCooldownAnimation;
 | 
			
		||||
		public KnightSpawnPoint spawnPoint;
 | 
			
		||||
		public bool activated;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		public override void Start(){
 | 
			
		||||
      base.Start();
 | 
			
		||||
| 
						 | 
				
			
			@ -56,7 +59,10 @@ namespace ScarletMansion.GamePatch.Enemies {
 | 
			
		|||
			
 | 
			
		||||
      if (IsOwner && KnightSpawnManager.Instance) {
 | 
			
		||||
        var index = KnightSpawnManager.Instance.GetSpawnPointIndex();
 | 
			
		||||
        if (index == -1) return;
 | 
			
		||||
				Plugin.logger.LogInfo($"Selected index {index}");
 | 
			
		||||
        if (index == -1) { 
 | 
			
		||||
					return;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
        SyncKnightReplacementClientRpc(index);
 | 
			
		||||
      }
 | 
			
		||||
| 
						 | 
				
			
			@ -95,7 +101,8 @@ namespace ScarletMansion.GamePatch.Enemies {
 | 
			
		|||
			base.DoAIInterval();
 | 
			
		||||
			if (StartOfRound.Instance.allPlayersDead) return;
 | 
			
		||||
			if (isEnemyDead) return;
 | 
			
		||||
 | 
			
		||||
			if (timeSinceSpawn < 1f) return;
 | 
			
		||||
			
 | 
			
		||||
			var currentBehaviourStateIndex = this.currentBehaviourStateIndex;
 | 
			
		||||
			if (currentBehaviourStateIndex != 0) {
 | 
			
		||||
				if (currentBehaviourStateIndex != 1) return;
 | 
			
		||||
| 
						 | 
				
			
			@ -242,7 +249,13 @@ namespace ScarletMansion.GamePatch.Enemies {
 | 
			
		|||
			base.Update();
 | 
			
		||||
			if (isEnemyDead) return;
 | 
			
		||||
			if (hitPlayerTimer >= 0f) hitPlayerTimer -= Time.deltaTime;
 | 
			
		||||
			if (timeSinceSpawn < 1f) return;
 | 
			
		||||
 | 
			
		||||
      if (!activated) { 
 | 
			
		||||
				activated = true;
 | 
			
		||||
				creatureAnimator.SetBool("Activate", true);
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
			if (!IsOwner) {
 | 
			
		||||
				stopMovementTimer = 5f;
 | 
			
		||||
				loseAggroTimer = 0f;
 | 
			
		||||
| 
						 | 
				
			
			@ -419,6 +432,8 @@ namespace ScarletMansion.GamePatch.Enemies {
 | 
			
		|||
				return;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (timeSinceSpawn < 1f) return;
 | 
			
		||||
 | 
			
		||||
			var playerControllerB = MeetsStandardPlayerCollisionConditions(other, false, false);
 | 
			
		||||
			if (playerControllerB != null) {
 | 
			
		||||
				hitPlayerTimer = 0.2f;
 | 
			
		||||
| 
						 | 
				
			
			@ -443,19 +458,9 @@ namespace ScarletMansion.GamePatch.Enemies {
 | 
			
		|||
      Plugin.logger.LogDebug($"Spawning knight at {index}");
 | 
			
		||||
 | 
			
		||||
      try {
 | 
			
		||||
        var target = KnightSpawnManager.Instance.GetSpawnPointTransform(index);
 | 
			
		||||
        target.gameObject.SetActive(false);
 | 
			
		||||
        spawnPoint = KnightSpawnManager.Instance.GetSpawnPoint(index);
 | 
			
		||||
				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){
 | 
			
		||||
        Plugin.logger.LogError($"Tried to knight spawn at {index}, but completely failed");
 | 
			
		||||
        Plugin.logger.LogError(e);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -221,26 +221,7 @@ namespace ScarletMansion {
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    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);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,6 +5,7 @@ using System.Text;
 | 
			
		|||
using System.Threading.Tasks;
 | 
			
		||||
using UnityEngine;
 | 
			
		||||
using HarmonyLib;
 | 
			
		||||
using OdinSerializer;
 | 
			
		||||
 | 
			
		||||
namespace ScarletMansion.GamePatch {
 | 
			
		||||
  [HarmonyPatch(typeof(EnemyVent))]
 | 
			
		||||
| 
						 | 
				
			
			@ -35,14 +36,25 @@ namespace ScarletMansion.GamePatch {
 | 
			
		|||
    public static void OpenVentClientRpcPatchPost(ref EnemyVent __instance){
 | 
			
		||||
      if (setActive == false) return;
 | 
			
		||||
 | 
			
		||||
      var comp = __instance.GetComponent<ScarletVent>();
 | 
			
		||||
      if (comp) {
 | 
			
		||||
      var scarlet = __instance as ScarletVent;
 | 
			
		||||
      if (scarlet && (scarlet.enemyType != scarlet.ignoreEnemyType || !KnightSpawnManager.WillSpawnOnSpawnPoint())) {
 | 
			
		||||
        Plugin.logger.LogDebug("Doing scalet open vent");
 | 
			
		||||
        comp.OpenVentClientRpc();
 | 
			
		||||
        scarlet.OpenVentClientRpc();
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      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;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,6 +5,8 @@ using System.Text;
 | 
			
		|||
using System.Threading.Tasks;
 | 
			
		||||
using UnityEngine;
 | 
			
		||||
using DunGen;
 | 
			
		||||
using static LethalLevelLoader.ExtendedEvent;
 | 
			
		||||
using UnityEngine.AI;
 | 
			
		||||
 | 
			
		||||
namespace ScarletMansion {
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -22,6 +24,13 @@ namespace ScarletMansion {
 | 
			
		|||
      Instance = this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static bool WillSpawnOnSpawnPoint(){
 | 
			
		||||
      if (Instance) {
 | 
			
		||||
        return !Instance.disableNextKnightSpecialSpawn && Instance.spawnPoints.Count > 0;
 | 
			
		||||
      }
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void OnDungeonComplete(Dungeon dungeon) {
 | 
			
		||||
      var points = dungeon.GetComponentsInChildren<KnightSpawnPoint>();
 | 
			
		||||
      spawnPoints = points.ToList();
 | 
			
		||||
| 
						 | 
				
			
			@ -60,10 +69,29 @@ namespace ScarletMansion {
 | 
			
		|||
      return item.index;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Transform GetSpawnPointTransform(int index){
 | 
			
		||||
      return spawnPoints[index].transform;
 | 
			
		||||
    public KnightSpawnPoint GetSpawnPoint(int index){
 | 
			
		||||
      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);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16,6 +16,10 @@ namespace ScarletMansion.GamePatch.Managers {
 | 
			
		|||
 | 
			
		||||
    public static ScarletGenericManager Instance { get; private set; }
 | 
			
		||||
 | 
			
		||||
    [Header("Settings")]
 | 
			
		||||
    public AudioClip[] radioAudioClips;
 | 
			
		||||
 | 
			
		||||
    [Header("Debug")]
 | 
			
		||||
    public List<Transform> roomsOfInterest;
 | 
			
		||||
    public List<ScarletBedroom> bedrooms;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -42,7 +46,8 @@ namespace ScarletMansion.GamePatch.Managers {
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    void Update(){
 | 
			
		||||
      if (!StartOfRound.Instance.IsServer) return;
 | 
			
		||||
      if (!StartOfRound.Instance) return;
 | 
			
		||||
      if (StartOfRound.Instance.IsServer) return;
 | 
			
		||||
      if (selfDestroyTargets == null) return;
 | 
			
		||||
 | 
			
		||||
      var time = Utility.GetTime();    
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,7 +10,6 @@ using GameNetcodeStuff;
 | 
			
		|||
using ScarletMansion.GamePatch.Items;
 | 
			
		||||
using ScarletMansion.GamePatch;
 | 
			
		||||
using ScarletMansion.GamePatch.Components;
 | 
			
		||||
using static LethalLevelLoader.ExtendedEvent;
 | 
			
		||||
using ScarletMansion.GamePatch.Managers;
 | 
			
		||||
using ScarletMansion.Configs;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -306,7 +305,7 @@ namespace ScarletMansion {
 | 
			
		|||
 | 
			
		||||
    public void CreateSpawnAudioPrefab(Vector3 positon, ulong playerId) {
 | 
			
		||||
      CreateSpawnAudioPrefabServerRpc(positon, playerId);
 | 
			
		||||
      CreateSpawnAudioPrefab(positon);
 | 
			
		||||
      CreateSpawnAudioPrefabLocal(positon);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [ServerRpc(RequireOwnership = false)]
 | 
			
		||||
| 
						 | 
				
			
			@ -317,10 +316,10 @@ namespace ScarletMansion {
 | 
			
		|||
    [ClientRpc]
 | 
			
		||||
    public void CreateSpawnAudioPrefabClientRpc(Vector3 position, ulong playerId){
 | 
			
		||||
      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 audioSource = copy.GetComponentInChildren<AudioSource>();
 | 
			
		||||
      audioSource.time = 0.5f;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -187,6 +187,7 @@
 | 
			
		|||
    <Compile Include="GamePatch\Components\ScarletProp.cs" />
 | 
			
		||||
    <Compile Include="GamePatch\Components\ScarletRadio.cs" />
 | 
			
		||||
    <Compile Include="GamePatch\Components\ScarletVent.cs" />
 | 
			
		||||
    <Compile Include="GamePatch\Components\ScarletVentVisuals.cs" />
 | 
			
		||||
    <Compile Include="GamePatch\Components\ScarletYukariTrigger.cs" />
 | 
			
		||||
    <Compile Include="GamePatch\Components\TreasureRoom\TreasureRoom.cs" />
 | 
			
		||||
    <Compile Include="GamePatch\Components\TreasureRoom\TreasureRoomBookSwitch.cs" />
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue