Skip to content
This repository has been archived by the owner on Aug 28, 2024. It is now read-only.

Commit

Permalink
feat: add setting and config for acion.
Browse files Browse the repository at this point in the history
  • Loading branch information
ArchiDog1998 committed Jan 21, 2024
1 parent ed62c5b commit 5a83808
Show file tree
Hide file tree
Showing 6 changed files with 110 additions and 60 deletions.
40 changes: 13 additions & 27 deletions RotationSolver.Basic/Actions/ActionBasicInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,22 +50,7 @@ public readonly bool IsOnSlot
public bool IsDutyAction { get; }
public Aspect Aspect { get; }

public bool IsFriendly { get; set; }
public bool IsEnable { get; set; } = true;
internal ActionID[]? ComboIdsNot { get; set; }

internal ActionID[]? ComboIds { get; set; }
/// <summary>
/// Status that this action provides.
/// </summary>
public StatusID[]? StatusProvide { get; set; } = null;

/// <summary>
/// Status that this action needs.
/// </summary>
public StatusID[]? StatusNeed { get; set; } = null;

public Func<bool>? ActionCheck { get; set; } = null;

public ActionBasicInfo(IBaseActionNew action, bool isDutyAction)
{
Expand All @@ -75,13 +60,11 @@ public ActionBasicInfo(IBaseActionNew action, bool isDutyAction)
IsLimitBreak = _action.Action.ActionCategory?.Value?.RowId == 9;
IsDutyAction = isDutyAction;
Aspect = (Aspect)_action.Action.Aspect;
//TODO: better friendly check.
IsFriendly = _action.Action.CanTargetFriendly;
}

internal readonly bool BasicCheck(bool skipStatusProvideCheck, bool skipCombo, bool ignoreCastingCheck)
{
if (!IsEnable || !IsOnSlot) return false;
if (!_action.Config.IsEnable || !IsOnSlot) return false;

//Disabled.
if (DataCenter.DisabledActionSequencer?.Contains(ID) ?? false) return false;
Expand All @@ -90,14 +73,14 @@ internal readonly bool BasicCheck(bool skipStatusProvideCheck, bool skipCombo, b

var player = Player.Object;

if (StatusNeed != null)
if (_action.Setting.StatusNeed != null)
{
if (!player.HasStatus(true, StatusNeed)) return false;
if (!player.HasStatus(true, _action.Setting.StatusNeed)) return false;
}

if (StatusProvide != null && !skipStatusProvideCheck)
if (_action.Setting.StatusProvide != null && !skipStatusProvideCheck)
{
if (player.HasStatus(true, StatusProvide)) return false;
if (player.HasStatus(true, _action.Setting.StatusProvide)) return false;
}

if(!skipCombo && IsGeneralGCD)
Expand All @@ -120,25 +103,28 @@ internal readonly bool BasicCheck(bool skipStatusProvideCheck, bool skipCombo, b
if (DataCenter.NoPoslock && DataCenter.IsMoving && !ignoreCastingCheck) return false;
}

if (IsGeneralGCD && StatusProvide?.Length > 0 && IsFriendly && IActionHelper.IsLastGCD(true, _action)
if (IsGeneralGCD && _action.Setting.StatusProvide?.Length > 0 && _action.Setting.IsFriendly
&& IActionHelper.IsLastGCD(true, _action)
&& DataCenter.TimeSinceLastAction.TotalSeconds < 3) return false;

if (!(ActionCheck?.Invoke() ?? true)) return false;
if (!(_action.Setting.ActionCheck?.Invoke() ?? true)) return false;

return true;
}

private readonly bool CheckForCombo()
{
if (ComboIdsNot != null)
if (_action.Setting.ComboIdsNot != null)
{
if (ComboIdsNot.Contains(DataCenter.LastComboAction)) return false;
if (_action.Setting.ComboIdsNot.Contains(DataCenter.LastComboAction)) return false;
}

var comboActions = (_action.Action.ActionCombo?.Row ?? 0) != 0
? new ActionID[] { (ActionID)_action.Action.ActionCombo!.Row }
: [];
if (ComboIds != null) comboActions = comboActions.Union(ComboIds).ToArray();


if (_action.Setting.ComboIds != null) comboActions = [.. comboActions, .. _action.Setting.ComboIds];

if (comboActions.Length > 0)
{
Expand Down
19 changes: 19 additions & 0 deletions RotationSolver.Basic/Actions/ActionConfig.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
namespace RotationSolver.Basic.Actions;

/// <summary>
/// User config.
/// </summary>
public struct ActionConfig()
{
public bool IsEnable { get; set; } = true;

public uint StatusGcdCount { get; set; } = 2;
public byte AoeCount { get; set; } = 3;
public float TimeToKill { get; set; } = 0;

public bool ShouldCheckStatus { get; set; } = true;
public float AutoHealRatio { get; set; } = 0.8f;

public bool IsEnabled { get; set; }
public bool IsInCooldown { get; set; }
}
27 changes: 27 additions & 0 deletions RotationSolver.Basic/Actions/ActionSetting.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
namespace RotationSolver.Basic.Actions;

/// <summary>
/// Setting from the developer.
/// </summary>
public struct ActionSetting()
{
public StatusID[]? TargetStatus { get; set; } = null;
public Func<GameObject, bool> CanTarget { get; set; } = t => true;
internal ActionID[]? ComboIdsNot { get; set; }

internal ActionID[]? ComboIds { get; set; }
/// <summary>
/// Status that this action provides.
/// </summary>
public StatusID[]? StatusProvide { get; set; } = null;

/// <summary>
/// Status that this action needs.
/// </summary>
public StatusID[]? StatusNeed { get; set; } = null;

public Func<bool>? ActionCheck { get; set; } = null;

public bool IsFriendly { get; set; }
public TargetType Type { get; set; } = TargetType.Big;
}
44 changes: 14 additions & 30 deletions RotationSolver.Basic/Actions/ActionTargetInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,8 @@

namespace RotationSolver.Basic.Actions;

public struct ActionTargetInfo
public struct ActionTargetInfo(IBaseActionNew _action)
{
private readonly IBaseActionNew _action;
public bool ShouldCheckStatus { get; set; } = true;
public StatusID[]? TargetStatus { get; set; } = null;
public uint StatusGcdCount { get; set; } = 2;
public byte AoeCount { get; set; } = 3;
public float TimeToKill { get; set; } = 0;
public TargetType Type { get; set; }
public Func<GameObject, bool> CanTarget { get; set; } = t => true;
public float AutoHealRatio { get; set; }
public readonly bool TargetArea => _action.Action.TargetArea;

public readonly float Range => ActionManager.GetActionRange(_action.Info.ID);
Expand Down Expand Up @@ -53,7 +44,7 @@ public readonly IEnumerable<GameObject> CanTargets
get
{
_canTargets.Delay(TargetFilter.GetObjectInRadius(DataCenter.AllTargets, Range)
.Where(GeneralCheck).Where(CanUseTo).Where(InViewTarget).Where(CanTarget));
.Where(GeneralCheck).Where(CanUseTo).Where(InViewTarget).Where(_action.Setting.CanTarget));
return _canTargets;
}
}
Expand All @@ -63,7 +54,7 @@ public readonly IEnumerable<BattleChara> CanAffects
get
{
if (EffectRange == 0) return [];
return TargetFilter.GetObjectInRadius(_action.Info.IsFriendly
return TargetFilter.GetObjectInRadius(_action.Setting.IsFriendly
? DataCenter.PartyMembers
: DataCenter.HostileTargets,
Range + EffectRange).Where(GeneralCheck);
Expand Down Expand Up @@ -108,9 +99,9 @@ private readonly bool GeneralCheck(GameObject gameObject)

private readonly bool CheckStatus(GameObject gameObject)
{
if (TargetStatus == null || !ShouldCheckStatus) return true;
if (_action.Setting.TargetStatus == null || !_action.Config.ShouldCheckStatus) return true;

return gameObject.WillStatusEndGCD(StatusGcdCount, 0, true, TargetStatus);
return gameObject.WillStatusEndGCD(_action.Config.StatusGcdCount, 0, true, _action.Setting.TargetStatus);
}

private readonly bool CheckResistance(GameObject gameObject)
Expand All @@ -137,18 +128,11 @@ private readonly bool CheckTimeToKill(GameObject gameObject)
{
if (gameObject is not BattleChara b) return false;
var time = b.GetTimeToKill();
return float.IsNaN(time) || time >= TimeToKill;
return float.IsNaN(time) || time >= _action.Config.TimeToKill;
}

#endregion


public ActionTargetInfo(IBaseActionNew action)
{
_action = action;
//TODO: figure out how the target type of this action is.
}

/// <summary>
/// Take a little long time..
/// </summary>
Expand All @@ -171,8 +155,8 @@ public ActionTargetInfo(IBaseActionNew action)
return FindTargetArea(canTargets, canAffects, range, player);
}

var targets = GetMostCanTargetObjects(canTargets, canAffects, AoeCount);
var target = FindTargetByType(targets, Type);
var targets = GetMostCanTargetObjects(canTargets, canAffects, _action.Config.AoeCount);
var target = FindTargetByType(targets, _action.Setting.Type);
if (target == null) return null;

return new(target, [.. GetAffects(target, canAffects)], target.Position);
Expand All @@ -181,11 +165,11 @@ public ActionTargetInfo(IBaseActionNew action)
private readonly TargetResult? FindTargetArea(IEnumerable<GameObject> canTargets, IEnumerable<GameObject> canAffects,
float range, PlayerCharacter player)
{
if (Type is TargetType.Move)
if (_action.Setting.Type is TargetType.Move)
{
return FindTargetAreaMove(range);
}
else if (_action.Info.IsFriendly)
else if (_action.Setting.IsFriendly)
{
if (!Service.Config.GetValue(PluginConfigBool.UseGroundBeneficialAbility)) return null;
if (!Service.Config.GetValue(PluginConfigBool.UseGroundBeneficialAbilityWhenMoving) && DataCenter.IsMoving) return null;
Expand All @@ -194,7 +178,7 @@ public ActionTargetInfo(IBaseActionNew action)
}
else
{
return FindTargetAreaHostile(canTargets, canAffects, AoeCount);
return FindTargetAreaHostile(canTargets, canAffects, _action.Config.AoeCount);
}
}

Expand All @@ -207,7 +191,7 @@ public ActionTargetInfo(IBaseActionNew action)
return new(target, [..GetAffects(target, canAffects)], target.Position);
}

private static TargetResult? FindTargetAreaMove(float range)
private TargetResult? FindTargetAreaMove(float range)
{
if (Service.Config.GetValue(PluginConfigBool.MoveAreaActionFarthest))
{
Expand Down Expand Up @@ -345,7 +329,7 @@ private readonly IEnumerable<GameObject> GetAffects(GameObject tar, IEnumerable<
private readonly IEnumerable<GameObject> GetMostCanTargetObjects(IEnumerable<GameObject> canTargets, IEnumerable<GameObject> canAffects, int aoeCount)
{
if (IsSingleTarget || EffectRange <= 0) return canTargets;
if (!_action.Info.IsFriendly && NoAOE) return [];
if (!_action.Setting.IsFriendly && NoAOE) return [];

List<GameObject> objectMax = new(canTargets.Count());

Expand Down Expand Up @@ -443,7 +427,7 @@ private readonly bool CanGetTarget(GameObject target, GameObject subTarget)
TargetType.Weaken => FindWeakenPeople(),
TargetType.Death => FindDeathPeople(),
TargetType.Move => FindTargetForMoving(),
TargetType.Heal => FindHealTarget(AutoHealRatio),
TargetType.Heal => FindHealTarget(_action.Config.AutoHealRatio),
TargetType.BeAttacked => FindBeAttackedTarget(),
_ => FindHostile(),
};
Expand Down
38 changes: 35 additions & 3 deletions RotationSolver.Basic/Actions/BaseActionNew.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,26 @@ public class BaseActionNew : IBaseActionNew
public string Description => string.Empty;

public byte Level => Info.Level;
public bool IsEnabled { get; set; }
public bool IsInCooldown { get; set; }
public bool IsEnabled
{
get => Config.IsEnable;
set
{
var config = Config;
config.IsEnable = value;
Config = config;
}
}
public bool IsInCooldown
{
get => Config.IsInCooldown;
set
{
var config = Config;
config.IsInCooldown = value;
Config = config;
}
}

public bool EnoughLevel => Info.EnoughLevel;
public virtual unsafe uint MPNeed
Expand All @@ -48,12 +66,26 @@ public virtual unsafe uint MPNeed
}
}

public ActionSetting Setting { get; set; }

public ActionConfig Config { get; set; }

public BaseActionNew(ActionID actionID, bool isDutyAction)
{
Action = Service.GetSheet<Action>().GetRow((uint)actionID)!;
TargetInfo = new(this);
Info = new(this, isDutyAction);
Cooldown = new(this);

//TODO: better target type check.
//TODO: better friendly check.
Setting = new()
{
IsFriendly = Action.CanTargetFriendly,
};

//TODO: load the config from the
Config = new();
}

public bool CanUse(out IAction act, bool skipStatusProvideCheck = false, bool skipCombo = false, bool ignoreCastingCheck = false,
Expand All @@ -65,7 +97,7 @@ public bool CanUse(out IAction act, bool skipStatusProvideCheck = false, bool sk
if (!Cooldown.CooldownCheck(isEmpty, onLastAbility, ignoreClippingCheck, gcdCountForAbility)) return false;

if (DataCenter.CurrentMp < MPNeed) return false;
if (Info.IsFriendly && DataCenter.AverageTimeToKill < TargetInfo.TimeToKill) return false;
if (Setting.IsFriendly && DataCenter.AverageTimeToKill < Config.TimeToKill) return false;

Target = TargetInfo.FindTarget();
if (Target == null) return false;
Expand Down
2 changes: 2 additions & 0 deletions RotationSolver.Basic/Actions/IBaseActionNew.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ public interface IBaseActionNew : IAction
ActionTargetInfo TargetInfo { get; }
ActionBasicInfo Info { get; }
ActionCooldownInfo Cooldown { get; }
ActionSetting Setting { get; set; }
ActionConfig Config { get; set; }

bool CanUse(out IAction act, bool skipStatusProvideCheck = false, bool skipCombo = false, bool ignoreCastingCheck = false,
bool isEmpty = false, bool onLastAbility = false, bool ignoreClippingCheck = false, byte gcdCountForAbility = 0);
Expand Down

0 comments on commit 5a83808

Please sign in to comment.