161 lines
5.3 KiB
C#
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();
|
|
}
|
|
}
|
|
}
|