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

Commit

Permalink
fix: add an option to heal only to self when no healer.
Browse files Browse the repository at this point in the history
  • Loading branch information
ArchiDog1998 committed Nov 1, 2023
1 parent 507fdc1 commit c997eb4
Show file tree
Hide file tree
Showing 6 changed files with 35 additions and 12 deletions.
1 change: 1 addition & 0 deletions RotationSolver.Basic/Configuration/Configs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,7 @@ public enum PluginConfigBool : byte
[Default(false)] JustSayHelloOnce,

[Default(false)] UseAdditionalConditions,
[Default(false)] OnlyHealselfWhenNoHealer,
}

public enum PluginConfigFloat : byte
Expand Down
19 changes: 15 additions & 4 deletions RotationSolver.Basic/Helpers/TargetFilter.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using ECommons.DalamudServices;
using ECommons.ExcelServices;
using ECommons.GameHelpers;
using Lumina.Excel.GeneratedSheets;
using RotationSolver.Basic.Configuration;
Expand All @@ -14,23 +15,33 @@ public static class TargetFilter
{
#region Find one target
internal static IEnumerable<BattleChara> MeleeRangeTargetFilter(IEnumerable<BattleChara> availableCharas)
=> availableCharas.Where(t => t.DistanceToPlayer() >= 3 + Service.Config.GetValue(Configuration.PluginConfigFloat.MeleeRangeOffset));
=> availableCharas.Where(t => t.DistanceToPlayer() >= 3 + Service.Config.GetValue(PluginConfigFloat.MeleeRangeOffset));

internal static BattleChara DefaultChooseFriend(IEnumerable<BattleChara> availableCharas, bool mustUse)
{
if (availableCharas == null || !availableCharas.Any()) return null;

var player = Svc.ClientState.LocalPlayer;
var onlyHealSelf = Service.Config.GetValue(PluginConfigBool.OnlyHealselfWhenNoHealer) && player?.ClassJob.GameData?.GetJobRole() != JobRole.Healer;

if (onlyHealSelf)
{
if (player == null) return null;
if (player.GetHealthRatio() == 1) return null;
return player;
}

availableCharas = availableCharas.Where(StatusHelper.NeedHealing);

var healerTars = availableCharas.GetJobCategory(JobRole.Healer);
var tankTars = availableCharas.GetJobCategory(JobRole.Tank);

var healerTar = tankTars.OrderBy(ObjectHelper.GetHealthRatio).FirstOrDefault();
if (healerTar != null && healerTar.GetHealthRatio() < Service.Config.GetValue(Configuration.PluginConfigFloat.HealthHealerRatio))
if (healerTar != null && healerTar.GetHealthRatio() < Service.Config.GetValue(PluginConfigFloat.HealthHealerRatio))
return healerTar;

var tankTar = tankTars.OrderBy(ObjectHelper.GetHealthRatio).FirstOrDefault();
if (tankTar != null && tankTar.GetHealthRatio() < Service.Config.GetValue(Configuration.PluginConfigFloat.HealthTankRatio))
if (tankTar != null && tankTar.GetHealthRatio() < Service.Config.GetValue(PluginConfigFloat.HealthTankRatio))
return tankTar;

var tar = availableCharas.OrderBy(ObjectHelper.GetHealthRatio).FirstOrDefault();
Expand All @@ -44,7 +55,7 @@ internal static BattleChara DefaultFindHostile(IEnumerable<BattleChara> availabl
{
if (availableCharas == null || !availableCharas.Any()) return null;

if (Service.Config.GetValue(Configuration.PluginConfigBool.FilterStopMark))
if (Service.Config.GetValue(PluginConfigBool.FilterStopMark))
{
var charas = MarkingHelper.FilterStopCharaes(availableCharas);
if (charas?.Any() ?? false) availableCharas = charas;
Expand Down
1 change: 1 addition & 0 deletions RotationSolver/Localization/ConfigTranslation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ internal static class ConfigTranslation
PluginConfigBool.RecordCastingArea => "Record AOE actions",
PluginConfigBool.HealWhenNothingTodo => LocalizationManager.RightLang.ConfigWindow_Param_HealWhenNothingTodo,
PluginConfigBool.UseResourcesAction => LocalizationManager.RightLang.ConfigWindow_Auto_UseResourcesAction,
PluginConfigBool.OnlyHealselfWhenNoHealer => LocalizationManager.RightLang.ConfigWindow_Auto_OnlyHealselfWhenNoHealer,

// target
PluginConfigBool.AddEnemyListToHostile => LocalizationManager.RightLang.ConfigWindow_Param_AddEnemyListToHostile,
Expand Down
2 changes: 2 additions & 0 deletions RotationSolver/Localization/Strings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -772,6 +772,8 @@ internal class Strings
public string ConfigWindow_Actions_ConditionDescription { get; set; } = "Forced Conditions have a higher priority. If Forced Conditions are met, Disabled Condition will be ignored.";

public string ConfigWindow_Auto_UseResourcesAction { get; set; } = "Use actions that use resources";
public string ConfigWindow_Auto_OnlyHealselfWhenNoHealer { get; set; } = "Only Healself When No Healer";

public string ConfigWindow_Auto_HealthForAutoDefense { get; set; } = "HP Ratio about defense single of Tanks";
public string ConfigWindow_Basic_SayHelloToUsers { get; set; } = "Say hello to the users of Rotation Solver.";
public string ConfigWindow_Basic_SayHelloToUsersDesc { get; set; } = "It can only be disabled for users, not authors and contributors.\nIf you want to be greeted by other users, please DM ArchiTed in Discord Server with your Hash!";
Expand Down
3 changes: 2 additions & 1 deletion RotationSolver/UI/RotationConfigWindow_Config.cs
Original file line number Diff line number Diff line change
Expand Up @@ -647,7 +647,8 @@ private static void DrawAutoActionCondition()
private static readonly ISearchable[] _autoActionConditionSearchable_Heal = new ISearchable[]
{
new AutoHealCheckBox(
new CheckBoxSearchPlugin(PluginConfigBool.UseHealWhenNotAHealer)
new CheckBoxSearchPlugin(PluginConfigBool.UseHealWhenNotAHealer,
new CheckBoxSearchPlugin(PluginConfigBool.OnlyHealselfWhenNoHealer))
{
JobRoles = new JobRole[]
{
Expand Down
21 changes: 14 additions & 7 deletions RotationSolver/Updaters/TargetUpdater.cs
Original file line number Diff line number Diff line change
Expand Up @@ -400,8 +400,11 @@ static void UpdateCanHeal(PlayerCharacter player)

var singleAbility = ShouldHealSingle(StatusHelper.SingleHots, job.GetHealthSingleAbility(), job.GetHealthSingleAbilityHot());
var singleSpell = ShouldHealSingle(StatusHelper.SingleHots, job.GetHealthSingleSpell(), job.GetHealthSingleSpellHot());
DataCenter.CanHealSingleAbility = singleAbility > 0;
DataCenter.CanHealSingleSpell = singleSpell > 0;

var onlyHealSelf = Service.Config.GetValue(PluginConfigBool.OnlyHealselfWhenNoHealer) && player.ClassJob.GameData?.GetJobRole() != JobRole.Healer;
DataCenter.CanHealSingleAbility = onlyHealSelf ? ShouldHealSingle(Svc.ClientState.LocalPlayer, StatusHelper.SingleHots, job.GetHealthSingleAbility(), job.GetHealthSingleAbilityHot())
: singleAbility > 0;
DataCenter.CanHealSingleSpell = onlyHealSelf ? ShouldHealSingle(Svc.ClientState.LocalPlayer,StatusHelper.SingleHots, job.GetHealthSingleSpell(), job.GetHealthSingleSpellHot()) : singleSpell > 0;
DataCenter.CanHealAreaAbility = singleAbility > 2;
DataCenter.CanHealAreaSpell = singleSpell > 2;

Expand Down Expand Up @@ -441,15 +444,19 @@ static float GetHealingOfTimeRatio(BattleChara target, params StatusID[] statusI
return Math.Min(1, buffTime / buffWholeTime);
}

static int ShouldHealSingle(StatusID[] hotStatus, float healSingle, float healSingleHot) => DataCenter.PartyMembers.Count(p =>
static int ShouldHealSingle(StatusID[] hotStatus, float healSingle, float healSingleHot) => DataCenter.PartyMembers.Count(p => ShouldHealSingle(p, hotStatus, healSingle, healSingleHot));

static bool ShouldHealSingle(BattleChara target, StatusID[] hotStatus, float healSingle, float healSingleHot)
{
var ratio = GetHealingOfTimeRatio(p, hotStatus);
if(target == null) return false;

var ratio = GetHealingOfTimeRatio(target, hotStatus);

var h = p.GetHealthRatio();
if (h == 0 || !p.NeedHealing()) return false;
var h = target.GetHealthRatio();
if (h == 0 || !target.NeedHealing()) return false;

return h < Lerp(healSingle, healSingleHot, ratio);
});
}

static float Lerp(float a, float b, float ratio)
{
Expand Down

0 comments on commit c997eb4

Please sign in to comment.