using System; using Continentis.MainGame.Character; using Lean.Pool; using SLSFramework.General; using SLSFramework.UModAssistance; using UniRx; using UnityEngine; namespace Continentis.MainGame.Commands { public class Cmd_SpawnVFX : CommandBase { public VisualEffectBase vfxPrefab; public bool useTargetPosition; public Vector3 spawnPosition; public Vector3 spawnPositionOffset; public bool willWaitUntilFinish; public float overrideDuration; public Cmd_SpawnVFX(string vfxID, bool useTargetPosition = true, Vector3 positionOrOffset = default, bool willWaitUntilFinish = false, float overrideDuration = -1f) : base(null) { this.vfxPrefab = ModManager.GetAsset(vfxID).GetComponent(); this.useTargetPosition = useTargetPosition; if (useTargetPosition) { this.spawnPosition = Vector3.zero; this.spawnPositionOffset = positionOrOffset; } else { this.spawnPosition = positionOrOffset; this.spawnPositionOffset = Vector3.zero; } this.willWaitUntilFinish = willWaitUntilFinish; this.overrideDuration = overrideDuration; } public Cmd_SpawnVFX(GameObject prefab, bool useTargetPosition = true, Vector3 positionOrOffset = default, bool willWaitUntilFinish = false, float overrideDuration = -1f) : base(null) { this.vfxPrefab = prefab.GetComponent(); this.useTargetPosition = useTargetPosition; if (useTargetPosition) { this.spawnPosition = Vector3.zero; this.spawnPositionOffset = positionOrOffset; } else { this.spawnPosition = positionOrOffset; this.spawnPositionOffset = Vector3.zero; } this.willWaitUntilFinish = willWaitUntilFinish; this.overrideDuration = overrideDuration; } protected override IObservable OnExecute(CommandContext outerContext) { if (vfxPrefab == null) { Debug.LogWarning("VFX Prefab is null."); return Observable.Return(Unit.Default); } return base.OnExecute(outerContext); } protected override IObservable CoreExecute(CommandContext outerContext) { if (useTargetPosition) { if (selfContext.context["Target"] is CharacterBase character) { spawnPosition = character.characterView.centerPoint.transform.position; } } VisualEffectBase spawnedVFX = LeanPool.Spawn(vfxPrefab, spawnPosition + spawnPositionOffset, Quaternion.identity); if(!spawnedVFX.isAutoDespawn) Debug.LogWarning("Spawned VFX is not set to auto-despawn. This may lead to memory leaks."); float vfxDuration = overrideDuration > 0 ? overrideDuration : spawnedVFX.autoDespawnTime; if (willWaitUntilFinish) { return Observable.Timer(TimeSpan.FromSeconds(vfxDuration)).AsUnitObservable(); } else { return Observable.Return(Unit.Default); } } } }