Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lots of random changes #1

Merged
merged 104 commits into from
Mar 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
104 commits
Select commit Hold shift + click to select a range
3b49e54
not working
CarnifexOptimus Mar 17, 2024
6ed7a1d
ChasingAOE component, OnActorModelStateChange, EurekaOrthos F30 Tiama…
CarnifexOptimus Mar 18, 2024
cce4cb7
added head path prediction
CarnifexOptimus Mar 18, 2024
5973959
reduced size of predicted zone
CarnifexOptimus Mar 18, 2024
50c7cf0
Reworked interrupt hint
CarnifexOptimus Mar 19, 2024
840a0cf
fix
CarnifexOptimus Mar 19, 2024
cb0bf69
PersistentInvertibleVoidzone
CarnifexOptimus Mar 19, 2024
2400382
removed pointless lines
CarnifexOptimus Mar 19, 2024
48f724e
fixed activation
CarnifexOptimus Mar 19, 2024
7206d93
SS rank forgiven rebellion
CarnifexOptimus Mar 19, 2024
fcd4afd
added hint
CarnifexOptimus Mar 19, 2024
4a593da
fix incase 2nd rotation happens
CarnifexOptimus Mar 19, 2024
d43364b
.
CarnifexOptimus Mar 19, 2024
2368b94
.
CarnifexOptimus Mar 19, 2024
d5fcec6
Aetherfont improvements
CarnifexOptimus Mar 20, 2024
3b1765c
code cleanup
CarnifexOptimus Mar 20, 2024
8e9b3f4
removed pointless tetherIDs
CarnifexOptimus Mar 20, 2024
7d3df4d
formatting
CarnifexOptimus Mar 20, 2024
d49bdcf
tower of zot improvements
CarnifexOptimus Mar 21, 2024
d27c940
Merge branch 'master' into slave_OnActorModelStateChange
CarnifexOptimus Mar 21, 2024
e98119b
Lunar Subterrane WIP
CarnifexOptimus Mar 22, 2024
91c5a07
Merge branch 'master' into slave_OnActorModelStateChange
CarnifexOptimus Mar 22, 2024
94160aa
lunar subterrane
CarnifexOptimus Mar 22, 2024
c76046e
Merge branch 'master' into slave_zot
CarnifexOptimus Mar 22, 2024
3561eeb
improved activation
CarnifexOptimus Mar 22, 2024
b88f25c
activation
CarnifexOptimus Mar 22, 2024
7d612ea
Merge branch 'master' into slave_shadowbringer_hunts
CarnifexOptimus Mar 22, 2024
874c361
Aglaope module
CarnifexOptimus Mar 22, 2024
5979303
added bonus adds to Altar Kelpie
CarnifexOptimus Mar 22, 2024
61c9c5b
seductive sonata improvement
CarnifexOptimus Mar 22, 2024
d4372bb
Gunitt module
CarnifexOptimus Mar 23, 2024
8d1f62b
Tarchia module
CarnifexOptimus Mar 23, 2024
e8bf01d
Tyger module
CarnifexOptimus Mar 23, 2024
85678bd
Forgiven Pedantry
CarnifexOptimus Mar 23, 2024
ac9437c
cleanup
CarnifexOptimus Mar 23, 2024
28f5550
Ixtab module
CarnifexOptimus Mar 23, 2024
750b96a
Nariphon module
CarnifexOptimus Mar 23, 2024
4b010d8
Nuckelavee module
CarnifexOptimus Mar 23, 2024
7f9e665
added comment
CarnifexOptimus Mar 23, 2024
89fc850
Merge branch 'master' into slave_aetherfront
CarnifexOptimus Mar 24, 2024
5d392cf
code cleanup
CarnifexOptimus Mar 24, 2024
fa5c07f
removed obsolete line
CarnifexOptimus Mar 24, 2024
671be8f
cleanup
CarnifexOptimus Mar 24, 2024
a867588
cleanup + reverse of AI change
CarnifexOptimus Mar 24, 2024
1529d6d
cleanup
CarnifexOptimus Mar 24, 2024
426c6cd
lots of random improvements
CarnifexOptimus Mar 24, 2024
48a4c77
removed pointless lines
CarnifexOptimus Mar 24, 2024
bc2ef44
.
CarnifexOptimus Mar 24, 2024
7346cba
Merge branch 'master' into slave_interrupt
CarnifexOptimus Mar 24, 2024
88bc9be
improved D053 module
CarnifexOptimus Mar 24, 2024
c5f6775
cleanup
CarnifexOptimus Mar 24, 2024
fa9b629
fixed masked carnivale 14
CarnifexOptimus Mar 24, 2024
ecce423
fixed holminster chains
CarnifexOptimus Mar 24, 2024
6e2dbc3
Mudman module
CarnifexOptimus Mar 24, 2024
8d3ad28
O Poorest Paudia module
CarnifexOptimus Mar 24, 2024
c26547e
Baal
CarnifexOptimus Mar 24, 2024
58d3998
Rusalka module
CarnifexOptimus Mar 24, 2024
1f6c167
Huracan module
CarnifexOptimus Mar 24, 2024
805b358
reworked hint
CarnifexOptimus Mar 24, 2024
f2cdf4a
LilMurderer module
CarnifexOptimus Mar 24, 2024
05b6872
Grassman module
CarnifexOptimus Mar 24, 2024
424f87a
supay module
CarnifexOptimus Mar 24, 2024
d808c52
cardinal font size change
CarnifexOptimus Mar 24, 2024
c9fa67f
metal fox chaos refactor
CarnifexOptimus Mar 25, 2024
575256e
finished metalfoxchaos refactoring
CarnifexOptimus Mar 25, 2024
dd79a35
random improvements
CarnifexOptimus Mar 25, 2024
9aae0c5
random improvements
CarnifexOptimus Mar 25, 2024
4a41e98
improvement
CarnifexOptimus Mar 25, 2024
ed002a9
file rename
CarnifexOptimus Mar 25, 2024
f44e6a1
refactor pvp goblin merc
CarnifexOptimus Mar 25, 2024
6a43ac7
leviathan hard refactors
CarnifexOptimus Mar 25, 2024
315b6ea
improvements
CarnifexOptimus Mar 25, 2024
9f3f2fd
stylistic changes
CarnifexOptimus Mar 25, 2024
3276ebd
removed line
CarnifexOptimus Mar 25, 2024
3f42bfc
formatting
CarnifexOptimus Mar 25, 2024
1ea81f0
improvement Familiar Face
CarnifexOptimus Mar 25, 2024
76ea45b
further improvements for CE44
CarnifexOptimus Mar 25, 2024
82d4042
removed pointless line
CarnifexOptimus Mar 25, 2024
7da51d2
.
CarnifexOptimus Mar 25, 2024
a6f9d99
angada update
CarnifexOptimus Mar 26, 2024
12aa413
fix Greedy Pixie bug
CarnifexOptimus Mar 26, 2024
cf1e0d7
added bonus add to secret undine
CarnifexOptimus Mar 26, 2024
1634147
Secret Porxie module
CarnifexOptimus Mar 26, 2024
0a6f454
added Lines.Count>0
CarnifexOptimus Mar 26, 2024
d408dee
added Lines.Count > 0)
CarnifexOptimus Mar 26, 2024
857325a
refactored philia exaflares
CarnifexOptimus Mar 26, 2024
5bace49
Merge branch 'master' into slave_shadowbringer_hunts
CarnifexOptimus Mar 26, 2024
6e4e416
Merge branch 'master' into slave_aetherfront
CarnifexOptimus Mar 27, 2024
4f10884
refactored some stuff
CarnifexOptimus Mar 27, 2024
f4eaff3
some refactoring
CarnifexOptimus Mar 27, 2024
8ecb3a7
.
CarnifexOptimus Mar 27, 2024
5c42f94
refactoring
CarnifexOptimus Mar 27, 2024
9d6bf21
move to other PR
CarnifexOptimus Mar 27, 2024
111c246
move to other PR
CarnifexOptimus Mar 27, 2024
35d744e
refactored some code
CarnifexOptimus Mar 27, 2024
39371ca
more refactoring
CarnifexOptimus Mar 27, 2024
528086c
Merge pull request #2 from CarnifexOptimus/slave_aetherfront
CarnifexOptimus Mar 28, 2024
99265da
Merge pull request #1 from FFXIV-CombatReborn/master
CarnifexOptimus Mar 28, 2024
2d58649
Merge pull request #3 from CarnifexOptimus/slave_cardinals
CarnifexOptimus Mar 28, 2024
6a4480f
Merge pull request #4 from CarnifexOptimus/slave_OnActorModelStateChange
CarnifexOptimus Mar 28, 2024
5891fcd
Merge pull request #5 from CarnifexOptimus/slave_interrupt
CarnifexOptimus Mar 28, 2024
229178d
Merge pull request #6 from CarnifexOptimus/slave_invertedvoidzone
CarnifexOptimus Mar 28, 2024
9343ada
Merge pull request #7 from CarnifexOptimus/slave_shadowbringer_hunts
CarnifexOptimus Mar 28, 2024
d40336b
Merge pull request #8 from CarnifexOptimus/slave_zot
CarnifexOptimus Mar 28, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions BossMod/BossModule/BossComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ public virtual void OnActorEState(BossModule module, Actor actor, ushort state)
public virtual void OnActorEAnim(BossModule module, Actor actor, uint state) { }
public virtual void OnActorPlayActionTimelineEvent(BossModule module, Actor actor, ushort id) { }
public virtual void OnActorNpcYell(BossModule module, Actor actor, ushort id) { }
public virtual void OnActorModelStateChange(BossModule module, Actor actor, byte modelstate, byte animstate1, byte animstate2) { }
public virtual void OnEventEnvControl(BossModule module, byte index, uint state) { }
}
}
8 changes: 8 additions & 0 deletions BossMod/BossModule/BossModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ public BossModule(WorldState ws, Actor primary, ArenaBounds bounds)
WorldState.Actors.EventObjectAnimation += OnActorEAnim;
WorldState.Actors.PlayActionTimelineEvent += OnActorPlayActionTimelineEvent;
WorldState.Actors.EventNpcYell += OnActorNpcYell;
WorldState.Actors.ModelStateChanged += OnActorModelStateChange;
WorldState.EnvControl += OnEnvControl;
foreach (var v in WorldState.Actors)
OnActorCreated(null, v);
Expand Down Expand Up @@ -170,6 +171,7 @@ protected virtual void Dispose(bool disposing)
WorldState.Actors.EventObjectAnimation -= OnActorEAnim;
WorldState.Actors.PlayActionTimelineEvent -= OnActorPlayActionTimelineEvent;
WorldState.Actors.EventNpcYell -= OnActorNpcYell;
WorldState.Actors.ModelStateChanged += OnActorModelStateChange;
WorldState.EnvControl -= OnEnvControl;
}
}
Expand Down Expand Up @@ -481,6 +483,12 @@ private void OnActorNpcYell(object? sender, (Actor actor, ushort id) arg)
comp.OnActorNpcYell(this, arg.actor, arg.id);
}

private void OnActorModelStateChange(object? sender, (Actor actor, byte modelstate, byte animstate1, byte animstate2) arg)
{
foreach (var comp in _components)
comp.OnActorModelStateChange(this, arg.actor, arg.modelstate, arg.animstate1, arg.animstate2);
}

private void OnEnvControl(object? sender, WorldState.OpEnvControl op)
{
foreach (var comp in _components)
Expand Down
4 changes: 4 additions & 0 deletions BossMod/BossModule/BossModuleConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ public class BossModuleConfig : ConfigNode
[PropertyDisplay("Show cardinal direction names")]
public bool ShowCardinals = false;

[PropertyDisplay("Cardinal direction font size")]
[PropertySlider(0.1f, 100, Speed = 1)]
public float CadrdinalsFontSize = 17;

[PropertyDisplay("Show waymarks on radar")]
public bool ShowWaymarks = false;

Expand Down
9 changes: 5 additions & 4 deletions BossMod/BossModule/MiniArena.cs
Original file line number Diff line number Diff line change
Expand Up @@ -211,13 +211,14 @@ public void Border(uint color)

public void CardinalNames()
{
var fontsize = Service.Config.Get<BossModuleConfig>().CadrdinalsFontSize;
var offCenter = ScreenHalfSize + ScreenMarginSize / 2;
var offS = RotatedCoords(new(0, offCenter));
var offE = RotatedCoords(new(offCenter, 0));
TextScreen(ScreenCenter - offS, "N", ArenaColor.Border);
TextScreen(ScreenCenter + offS, "S", ArenaColor.Border);
TextScreen(ScreenCenter + offE, "E", ArenaColor.Border);
TextScreen(ScreenCenter - offE, "W", ArenaColor.Border);
TextScreen(ScreenCenter - offS, "N", ArenaColor.Border, fontsize);
TextScreen(ScreenCenter + offS, "S", ArenaColor.Border, fontsize);
TextScreen(ScreenCenter + offE, "E", ArenaColor.Border, fontsize);
TextScreen(ScreenCenter - offE, "W", ArenaColor.Border, fontsize);
}

// draw actor representation
Expand Down
9 changes: 8 additions & 1 deletion BossMod/Components/BaitAway.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public Bait(Actor source, Actor target, AOEShape shape, DateTime activation = de
public bool CenterAtTarget; // if true, aoe source is at target
public bool AllowDeadTargets = true; // if false, baits with dead targets are ignored
public bool EnableHints = true;
public bool EndsOnCastEvent;
public bool IgnoreOtherBaits = false; // if true, don't show hints/aoes for baits by others
public PlayerPriority BaiterPriority = PlayerPriority.Interesting;
public BitMask ForbiddenPlayers; // these players should avoid baiting
Expand Down Expand Up @@ -202,7 +203,13 @@ public override void OnCastStarted(BossModule module, Actor caster, ActorCastInf

public override void OnCastFinished(BossModule module, Actor caster, ActorCastInfo spell)
{
if (spell.Action == WatchedAction)
if (spell.Action == WatchedAction && !EndsOnCastEvent)
CurrentBaits.RemoveAll(b => b.Source == caster);
}

public override void OnEventCast(BossModule module, Actor caster, ActorCastEvent spell)
{
if (spell.Action == WatchedAction && EndsOnCastEvent)
CurrentBaits.RemoveAll(b => b.Source == caster);
}
}
Expand Down
60 changes: 50 additions & 10 deletions BossMod/Components/CastHint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ namespace BossMod.Components
public class CastHint : CastCounter
{
public string Hint;
public bool EndsOnCastEvent;
public bool ShowCastTimeLeft; // if true, show cast time left until next instance
private List<Actor> _casters = new();
public IReadOnlyList<Actor> Casters => _casters;
Expand All @@ -32,28 +33,67 @@ public override void OnCastStarted(BossModule module, Actor caster, ActorCastInf

public override void OnCastFinished(BossModule module, Actor caster, ActorCastInfo spell)
{
if (spell.Action == WatchedAction)
if (spell.Action == WatchedAction && !EndsOnCastEvent)
_casters.Remove(caster);
}

public override void OnEventCast(BossModule module, Actor caster, ActorCastEvent spell)
{
if (spell.Action == WatchedAction && EndsOnCastEvent)
_casters.Remove(caster);
}
}

public class CastInterruptHint : CastHint
{
public bool CanBeInterrupted { get; init; }
public bool CanBeStunned { get; init; }
public bool CanBeInterrupted;
public bool CanBeStunned;
public bool ShowNameInHint;
public string HintExtra;
private List<Actor> _casters = new();
public new IReadOnlyList<Actor> Casters => _casters;
public new bool Active => _casters.Count > 0;

public CastInterruptHint(ActionID aid, bool canBeInterrupted = true, bool canBeStunned = false, string hint = "") : base(aid, "")
public CastInterruptHint(ActionID aid, bool canBeInterrupted = true, bool canBeStunned = false, string hintExtra = "", bool showNameInHint = false) : base(aid, hintExtra)
{
CanBeInterrupted = canBeInterrupted;
CanBeStunned = canBeStunned;
if (canBeInterrupted || canBeStunned)
{
Hint = !canBeStunned ? "Interrupt" : !canBeInterrupted ? "Stun" : "Interrupt/stun";
if (hint.Length > 0)
Hint += $" {hint}";
}
ShowNameInHint = showNameInHint;
HintExtra = hintExtra;
}

public override void AddGlobalHints(BossModule module, GlobalHints hints)
{
if (!Active) return;
string action = "";
if (CanBeInterrupted && !CanBeStunned)
action = "Interrupt";
else if (CanBeInterrupted && CanBeStunned)
action = "Interrupt/Stun";
else if (!CanBeInterrupted && CanBeStunned)
action = "Stun";
string hint = $"{action}!";
if (ShowNameInHint && Casters.Count > 0)
hint = $"{action} {Casters[0].Name}!";
if (HintExtra.Length > 0)
hint += $" {HintExtra}";
hints.Add(hint);
}

public override void OnCastStarted(BossModule module, Actor caster, ActorCastInfo spell)
{
if (spell.Action == WatchedAction)
_casters.Add(caster);
}

public override void OnCastFinished(BossModule module, Actor caster, ActorCastInfo spell)
{
if (spell.Action == WatchedAction)
_casters.Remove(caster);
}



public override void AddAIHints(BossModule module, int slot, Actor actor, PartyRolesConfig.Assignment assignment, AIHints hints)
{
foreach (var c in Casters)
Expand Down
139 changes: 139 additions & 0 deletions BossMod/Components/ChasingAOEs.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
using System;
using System.Collections.Generic;
using System.Linq;

namespace BossMod.Components
{
// generic 'chasing AOE' component - these are AOEs that follow the target for a set amount of casts
public class ChasingAOEs : GenericAOEs
{
public class Chaser
{
public Actor Player;
public WPos? Pos;
public int NumCasts;
public DateTime Activation;

public Chaser(Actor player)
{
Player = player;
}

public WPos PredictedPosition()
{
if (Pos == null)
return default;
if (NumCasts == 0)
return Pos.Value;
var toPlayer = Player.Position - Pos.Value;
var dist = toPlayer.Length();
if (dist < MoveDist)
return Player.Position;
return Pos.Value + toPlayer * MoveDist / dist;
}
}

private List<Chaser> _chasers = new();

public bool Active => _chasers.Count > 0;

public AOEShape Shape;
public static int MaxCasts;
public static float MoveDist;
public bool LocationTargeted; //if true chaser is location targeted instead of self targeted
public Angle Rotation;
public uint Icon;
public ActionID ChasingAOEFirst;
public ActionID ChasingAOERest;
public float TimeBetweenCasts;

public ChasingAOEs(uint icon, AOEShape shape, ActionID chasingAOEFirst, ActionID chasingAOERest, float movedist, int maxCasts, float timeBetweenCasts, bool locationtargeted = false, Angle rotation = default) : base(chasingAOEFirst, "GTFO from chasing AOE!")
{
Shape = shape;
Icon = icon;
ChasingAOEFirst = chasingAOEFirst;
ChasingAOERest = chasingAOERest;
MoveDist = movedist;
MaxCasts = maxCasts;
TimeBetweenCasts = timeBetweenCasts;
LocationTargeted = locationtargeted;
Rotation = rotation;
}

public override IEnumerable<AOEInstance> ActiveAOEs(BossModule module, int slot, Actor actor) => _chasers.Select(c => new AOEInstance(Shape, c.PredictedPosition(), Rotation, c.Activation));

public override void Update(BossModule module)
{
_chasers.RemoveAll(c => (c.Player.IsDestroyed || c.Player.IsDead) && (c.Pos == null || c.NumCasts > 0));
}

public override void DrawArenaForeground(BossModule module, int pcSlot, Actor pc, MiniArena arena)
{
foreach (var c in _chasers)
if (c.Pos != null)
{
if (arena.Config.ShowOutlinesAndShadows)
arena.AddLine(c.Pos.Value, c.Player.Position, 0xFF000000, 2);
arena.AddLine(c.Pos.Value, c.Player.Position, ArenaColor.Danger);
}
}

public override void OnEventIcon(BossModule module, Actor actor, uint iconID)
{
if (iconID == Icon)
_chasers.Add(new(actor));
}

public override void OnCastStarted(BossModule module, Actor caster, ActorCastInfo spell)
{
if (spell.Action == ChasingAOEFirst && _chasers.Where(c => c.Pos == null).MinBy(c => (c.Player.Position - caster.Position).LengthSq()) is var chaser && chaser != null)
{
if (LocationTargeted)
chaser.Pos = spell.LocXZ;
else
chaser.Pos = caster.Position;
chaser.Activation = spell.NPCFinishAt;
}
}

public override void OnCastFinished(BossModule module, Actor caster, ActorCastInfo spell)
{
if (spell.Action == ChasingAOEFirst)
{
if (LocationTargeted)
Advance(module, spell.LocXZ);
else
Advance(module, caster.Position);
}
}

public override void OnEventCast(BossModule module, Actor caster, ActorCastEvent spell)
{
if (spell.Action == ChasingAOERest)
{
if (LocationTargeted)
Advance(module, spell.TargetXZ);
else
Advance(module, caster.Position);
}
}

private void Advance(BossModule module, WPos pos)
{
++NumCasts;
var chaser = _chasers.MinBy(c => c.Pos != null ? (c.PredictedPosition() - pos).LengthSq() : float.MaxValue);
if (chaser == null)
return;

if (++chaser.NumCasts < MaxCasts)
{
chaser.Pos = pos;
chaser.Activation = module.WorldState.CurrentTime.AddSeconds(TimeBetweenCasts);
}
else
{
_chasers.Remove(chaser);
}
}
}
}
69 changes: 69 additions & 0 deletions BossMod/Components/PersistentVoidzone.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;

namespace BossMod.Components
{
Expand Down Expand Up @@ -77,4 +78,72 @@ public override void OnEventCast(BossModule module, Actor caster, ActorCastEvent
_predictedByEvent.Add((module.WorldState.Actors.Find(spell.MainTargetID)?.Position ?? spell.TargetXZ, module.WorldState.CurrentTime.AddSeconds(CastEventToSpawn)));
}
}

// voidzone (circle aoe that stays active for some time) centered at each existing object with specified OID, assumed to be persistent voidzone center
// inverts from dangerous to safe when a specific AID is being casted
public class PersistentInvertibleVoidzone : GenericAOEs
{
public AOEShapeCircle Shape { get; private init; }
public Func<BossModule, IEnumerable<Actor>> Sources { get; private init; }
private bool inverting;
private DateTime _activation;
private float Radius;

public PersistentInvertibleVoidzone(float radius, ActionID aid, Func<BossModule, IEnumerable<Actor>> sources) : base(aid, "GTFO from voidzone!")
{
Shape = new(radius);
Sources = sources;
Radius = radius;
}

public override IEnumerable<AOEInstance> ActiveAOEs(BossModule module, int slot, Actor actor)
{
if (!inverting)
foreach (var s in Sources(module))
yield return new(Shape, s.Position);
if (inverting)
foreach (var s in Sources(module))
yield return new(Shape, s.Position, activation: _activation, color: ArenaColor.SafeFromAOE, risky: false);
}

public override void OnCastStarted(BossModule module, Actor caster, ActorCastInfo spell)
{
if (spell.Action == WatchedAction)
{
inverting = true;
_activation = spell.NPCFinishAt;
}
}

public override void OnCastFinished(BossModule module, Actor caster, ActorCastInfo spell)
{
if (spell.Action == WatchedAction)
inverting = false;
}

public override void AddAIHints(BossModule module, int slot, Actor actor, PartyRolesConfig.Assignment assignment, AIHints hints)
{
var shapes = new List<Func<WPos, float>>();
foreach (var c in ActiveAOEs(module, slot, actor))
{
if (c.Risky)
hints.AddForbiddenZone(c.Shape, c.Origin, c.Rotation, c.Activation);
if (inverting)
shapes.Add(ShapeDistance.InvertedCircle(c.Origin, Radius));
}
if (shapes.Count > 0)
hints.AddForbiddenZone(p => shapes.Select(f => f(p)).Max(), _activation);
if (shapes.Count > 0 && !inverting)
shapes.Clear();
}

public override void AddHints(BossModule module, int slot, Actor actor, TextHints hints, MovementHints? movementHints)
{
base.AddHints(module, slot, actor, hints, movementHints);
if (ActiveAOEs(module, slot, actor).Any(c => c.Check(actor.Position)) && inverting)
hints.Add("Wait in puddle until mechanic resolves!", false);
if (!ActiveAOEs(module, slot, actor).Any(c => c.Check(actor.Position)) && inverting)
hints.Add("Go into puddle until mechanic resolves!");
}
}
}
Loading