You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Babushka/scripts/CSharp/Common/Fight/FighterAction.cs

124 lines
3.7 KiB

using System;
using System.Threading.Tasks;
using Babushka.scripts.CSharp.Common.Util;
using Godot;
namespace Babushka.scripts.CSharp.Common.Fight;
public abstract class FighterAction
{
// enum has explicit values, because they are set in godot signals as integers
// e.g. here: BabushkaSceneFightHappening => ActionSelect/BottomPanel/VBoxContainer/MarginContainer/HBoxContainer/MarginContainer/AttackButton
public enum AllyActionButton
{
None,
Attack = 1,
Summon = 2,
Talk = 3,
Flee = 4,
}
public class TargetSelection
{
// ReSharper disable once MemberHidesStaticFromOuterClass
public static readonly TargetSelection Skip = new() { skipTargetSelection = () => true };
public Func<bool> skipTargetSelection = () => false;
}
public abstract class FighterActionDetail
{
public abstract bool DetailComplete();
}
#region Shortcuts
protected static FightWorld.FightHappeningData HappeningData =>
FightWorld.Instance.fightHappeningData ?? throw new NoFightHappeningException();
#endregion
/// <summary>
/// Executes the data modification for the action. This must happen instantly and not via a coroutines or callbacks.
/// To get a multiple hit effect for one action, use appropriate Visual Manipulation functions in AnimateAction.
/// </summary>
public virtual void ExecuteAction()
{
}
/// <summary>
/// Returns a way to determine, when an action animation is done
/// </summary>
/// <returns>
/// A variant that can be <c>float</c> or <c>Func&lt;bool&gt;</c>.<br/>
/// When the return type is <c>float</c>, the animation will take the return value amount of seconds.<br/>
/// When the return type is <c>Func&lt;bool&gt;</c>, the animation will be done, when the function returns true.
/// </returns>
public abstract Variant<float, Func<bool>> GetAnimationEnd();
/// <summary>
/// Animates the action.
/// </summary>
/// <param name="allFightersVisual"></param>
/// <param name="animationContext"></param>
public virtual async Task AnimateAction(AllFightersVisual allFightersVisual,
FightHappeningAnimationContext animationContext)
{
}
public virtual bool ShouldAbort() => false;
/// <summary>
/// Returns the FighterActionDetail, that is currently handled.
/// </summary>
/// <returns></returns>
public virtual FighterActionDetail CurrentDetail()
{
throw new Exception("Action has no details to handle");
}
/// <summary>
/// Sets the next Detail to be handled. Returns false, when there are no more details to handle.
/// </summary>
/// <returns></returns>
public abstract bool NextDetail();
/// <summary>
/// Returns the action point cost of this action.
/// Right now, only the values 1 and 0 make sense.
/// </summary>
/// <returns></returns>
public virtual int GetActionPointCost()
{
return 1;
}
/// <summary>
/// Will be called right after the action is selected by the player. Can be used to reset the state of the details
/// </summary>
public virtual void Reset()
{
}
/// <summary>
/// If this action should be bound to an action button in the UI, return the corresponding enum value here.
/// </summary>
/// <returns></returns>
public virtual AllyActionButton BindToActionButton()
{
return AllyActionButton.None;
}
public class Skip : FighterAction
{
public override Variant<float, Func<bool>> GetAnimationEnd()
{
return 0f;
}
public override bool NextDetail()
{
return false;
}
}
}