Files
VOIDRPG/Assets/86 - ScriptableObjects/Generic/BasicStatus.cs
T
2026-07-09 21:33:33 +02:00

161 lines
5.3 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using Sirenix.OdinInspector;
using UnityEngine;
using VOID.Generic.Objects.Abstract;
using VOID.Generic.Objects.Abstract.Events;
using VOID.Generic.Objects.Unit;
using VOID.Generic.Status.Effect;
namespace VOID.ScriptableObjects
{
[Serializable]
[CreateAssetMenu(fileName = "Status", menuName = "GAME DATA/Status", order = 0)]
public class BasicStatus : ScriptableObject
{
[Title("Nested into:")]
[ShowInInspector] public AbstractObject forObject { get; private set; }
[Title("Display")]
[Required] public string displayName;
[Required] public bool hidden = false;
[Required] public Texture2D displayIcon;
[Required, TextArea(10,10)] public string description;
[Title("Effects list")]
[Required, SerializeReference] public List<BasicEffect> effects = new();
[Title("Statuses interactions")]
public List<BasicStatus> removes = new();
[Title("Duration")]
public bool permanent = false;
[MinValue(0)] public int durationInTurns;
[ReadOnly] public int durationLeftInTurns;
[ReadOnly] public float durationLeft;
public event Action OnTimeDecrease;
public void Init(AbstractObject forObject, UnitObject source = null)
{
this.forObject = forObject;
effects.ForEach(effect => effect.Init(forObject, this, source));
}
public void Apply()
{
if (permanent) durationInTurns = 1;
// TODO: zdefiniować gdzieś ile czasu w sekundach to tura, na sztywno tutaj dodane 4 sekundy
durationLeftInTurns = durationInTurns;
durationLeft = durationInTurns*4f - 0.0001f;
var otherStatuses = forObject.statusManager.GetStatuses();
var selfRemove = false;
foreach (var otherStatus in otherStatuses)
{
if (otherStatus == this) continue;
// if other status removes current one
selfRemove = selfRemove || otherStatus.removes.Any(removeStatus => removeStatus.GetType() == GetType());
// if other status is removed by current one
if (removes.Any(statusToRemove => statusToRemove.GetType() == otherStatus.GetType())) otherStatus.Cancel();
}
if (selfRemove)
{
forObject.statusManager.RemoveStatus(this);
return;
}
forObject.basicEvents.onStatusStart.Invoke(new StatusEvent
{
obj = forObject,
status = this
});
// Statuses already added via editor inspector need to be started this way
foreach (var effect in effects)
{
effect.OnApply();
forObject.basicEvents.onEffectStart.Invoke(new EffectEvent
{
effect = effect
});
}
}
public void End()
{
if (permanent)
{
durationLeftInTurns = 1;
// TODO: zdefiniować gdzieś ile czasu w sekundach to tura, na sztywno tutaj dodane 4 sekundy
durationLeft += durationInTurns * 4f;
return;
}
foreach (var effect in effects)
{
effect.OnEnd();
forObject.basicEvents.onEffectEnd.Invoke(new EffectEvent
{
effect = effect
});
}
forObject.statusManager.RemoveStatus(this);
forObject.basicEvents.onStatusEnd.Invoke(new StatusEvent
{
obj = forObject,
status = this
});
}
public void Cancel()
{
effects.ForEach(effect =>
{
effect.OnCancel();
forObject.basicEvents.onEffectEnd.Invoke(new EffectEvent { effect = effect });
});
forObject.statusManager.RemoveStatus(this);
forObject.basicEvents.onStatusEnd.Invoke(new StatusEvent { obj = forObject, status = this });
}
public void OnTurnSelfStart()
{
// TODO: zdefiniować gdzieś ile czasu w sekundach to tura, na sztywno tutaj dodane 4 sekundy
durationLeftInTurns -= 1;
durationLeft -= 4f;
effects.ForEach(effect => effect.OnTurnSelfStart());
OnTimeDecrease?.Invoke();
}
public void OnTurnSelfEnd()
{
effects.ForEach(effect => effect.OnTurnSelfEnd());
if (durationLeft <= 0f) End();
}
public void DecreaseDurationRealTime()
{
// TODO: zdefiniować gdzieś ile czasu w sekundach to tura, na sztywno tutaj dodane 4 sekundy
if (durationLeft%4f - Time.fixedDeltaTime < 0f)
{
effects.ForEach(effect => effect.OnTurnSelfStart());
effects.ForEach(effect => effect.OnTurnSelfEnd());
durationLeftInTurns -= 1;
}
OnTimeDecrease?.Invoke();
durationLeft -= Time.fixedDeltaTime;
if (durationLeft < 0f) End();
}
}
}