Skip to content

Commit

Permalink
Merge pull request #611 from FFXIV-CombatReborn/mergeWIP
Browse files Browse the repository at this point in the history
origenics improvements and DD walls are now a dictionary
  • Loading branch information
CarnifexOptimus authored Feb 16, 2025
2 parents 8be6322 + 6e0e94d commit a48a0cb
Show file tree
Hide file tree
Showing 15 changed files with 5,508 additions and 1,473 deletions.
1 change: 0 additions & 1 deletion BossMod/BossModReborn.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,6 @@
<None Update="DefaultRotationPresets.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<EmbeddedResource Include="Modules\Global\DeepDungeon\*.json" />
</ItemGroup>

<ItemGroup>
Expand Down
4 changes: 2 additions & 2 deletions BossMod/BossModule/SimpleBossModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@

// base class for simple boss modules (hunts, fates, dungeons, etc.)
// these always center map around PC
public abstract class SimpleBossModule(WorldState ws, Actor primary) : BossModule(ws, primary, primary.Position, new ArenaBoundsCircle(30))
public abstract class SimpleBossModule(WorldState ws, Actor primary) : BossModule(ws, primary, primary.Position, new ArenaBoundsCircle(30f))
{
private WPos _prevFramePathfindCenter;

public override bool CheckReset() => !PrimaryActor.InCombat;

protected override bool CheckPull() => base.CheckPull() && (Center - Raid.Player()!.Position).LengthSq() < 900;
protected override bool CheckPull() => base.CheckPull() && (PrimaryActor.Position - Raid.Player()!.Position).LengthSq() < 900f;

protected override void UpdateModule()
{
Expand Down
8 changes: 5 additions & 3 deletions BossMod/Modules/Dawntrail/Alliance/A14ShadowLord/GigaSlash.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@ public override IEnumerable<AOEInstance> ActiveAOEs(int slot, Actor actor)

public override void AddAIHints(int slot, Actor actor, PartyRolesConfig.Assignment assignment, AIHints hints)
{
if (AOEs.Count == 0)
var count = AOEs.Count;
if (count == 0)
return;
base.AddAIHints(slot, actor, assignment, hints);
var aoe = AOEs[0];
// stay close to the middle if there is next imminent aoe from same origin
if (Module.FindComponent<DarkNebula>()?.Casters.Count == 0 && AOEs.Count > 1 && AOEs[0].Origin == AOEs[1].Origin)
hints.AddForbiddenZone(ShapeDistance.InvertedCircle(AOEs[0].Origin, 3), AOEs[0].Activation);
if (Module.FindComponent<DarkNebula>()?.Casters.Count == 0 && count > 1 && aoe.Origin == AOEs[1].Origin)
hints.AddForbiddenZone(ShapeDistance.InvertedCircle(aoe.Origin, 3f), aoe.Activation);
}

public override void OnCastStarted(Actor caster, ActorCastInfo spell)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ public enum AID : uint
GrenadoShot = 35428, // OrigenicsSentryG10->location, 3.0s cast, range 5 circle
}

class IncendiaryCircle(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.IncendiaryCircle), new AOEShapeDonut(3, 12));
class GrenadoShot(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.GrenadoShot), 5);
class IncendiaryCircle(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.IncendiaryCircle), new AOEShapeDonut(3f, 12f));
class GrenadoShot(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.GrenadoShot), 5f);

class D050OrigenicsAerostatStates : StateMachineBuilder
{
Expand All @@ -47,8 +47,11 @@ public D050OrigenicsAerostatStates(D050OrigenicsAerostat module) : base(module)
[ModuleInfo(BossModuleInfo.Maturity.Verified, Contributors = "The Combat Reborn Team (Malediktus)", GroupType = BossModuleInfo.GroupType.CFC, GroupID = 825, NameID = 12895, SortOrder = 2)]
public class D050OrigenicsAerostat(WorldState ws, Actor primary) : BossModule(ws, primary, arena.Center, arena)
{
private static readonly ArenaBoundsComplex arena = new([new Polygon(new(-116, -80), 14.5f, 6, 30.Degrees()), new Rectangle(new(-88, -80), 20, 5.5f),
new Polygon(new(-60, -80), 14.5f, 6, 30.Degrees()), new Rectangle(new(-144, -80), 20, 5.5f)]);
private static readonly Angle a30 = 30f.Degrees();
private static readonly WPos node1Center = new(-60f, -80f), node2Center = new(-116f, -80f), node3Center = new(-172f, -80f);
private static readonly ArenaBoundsComplex arena = new([new Polygon(node1Center, 16f, 6, a30), new Rectangle(new(-88f, -80f), 20f, 6f),
new Polygon(node2Center, 16f, 6, a30), new Polygon(node3Center, 16f, 6, a30), new Rectangle(new(-144f, -80f), 20f, 6f),
new Rectangle(node3Center, 39f, 6f), new Rectangle(node3Center, 6f, 19.6f), new Rectangle(node2Center, 6f, 19.6f), new Rectangle(node1Center, 6f, 19.6f)]);
public static readonly uint[] Trash = [(uint)OID.Boss, (uint)OID.Aerostat2, (uint)OID.OrigenicsSentryS9, (uint)OID.OrigenicsSentryS92, (uint)OID.OrigenicsSentryG10];

protected override void DrawEnemies(int pcSlot, Actor pc)
Expand Down
34 changes: 32 additions & 2 deletions BossMod/Modules/Dawntrail/Dungeon/D05Origenics/D051Herpekaris.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,26 @@ class CollectiveAgony(BossModule module) : Components.LineStack(module, ActionID
class StridentShriek(BossModule module) : Components.RaidwideCast(module, ActionID.MakeSpell(AID.StridentShriek));
class ConvulsiveCrush(BossModule module) : Components.SingleTargetDelayableCast(module, ActionID.MakeSpell(AID.ConvulsiveCrush));
class PoisonHeartSpread(BossModule module) : Components.SpreadFromCastTargets(module, ActionID.MakeSpell(AID.PoisonHeartSpread), 5f);
class PoisonHeartVoidzone(BossModule module) : Components.PersistentVoidzoneAtCastTarget(module, 2f, ActionID.MakeSpell(AID.PoisonHeartVoidzone), m => m.Enemies(OID.PoisonVoidzone).Where(z => z.EventState != 7), 0.9f);
class PoisonHeartVoidzone(BossModule module) : Components.PersistentVoidzoneAtCastTarget(module, 2f, ActionID.MakeSpell(AID.PoisonHeartVoidzone), GetVoidzones, 0.9f)
{
private static Actor[] GetVoidzones(BossModule module)
{
var enemies = module.Enemies((uint)OID.PoisonVoidzone);
var count = enemies.Count;
if (count == 0)
return [];

var voidzones = new Actor[count];
var index = 0;
for (var i = 0; i < count; ++i)
{
var z = enemies[i];
if (z.EventState != 7)
voidzones[index++] = z;
}
return voidzones[..index];
}
}

abstract class PodBurst(BossModule module, AID aid) : Components.SimpleAOEs(module, ActionID.MakeSpell(aid), 6f);
class PodBurst1(BossModule module) : PodBurst(module, AID.PodBurst1);
Expand Down Expand Up @@ -77,7 +96,7 @@ public override IEnumerable<AOEInstance> ActiveAOEs(int slot, Actor actor)

public override void OnCastStarted(Actor caster, ActorCastInfo spell)
{
void AddAOE(AOEShape shape) => _aoes.Add(new(shape, spell.LocXZ, spell.Rotation, WorldState.FutureTime(9.2d + _aoes.Count * 2d)));
void AddAOE(AOEShape shape) => _aoes.Add(new(shape, spell.LocXZ, spell.Rotation, WorldState.FutureTime(7.3d - _aoes.Count * 1d)));
switch (spell.Action.ID)
{
case (uint)AID.RightSweepTelegraph:
Expand All @@ -102,6 +121,17 @@ public override void OnEventCast(Actor caster, ActorCastEvent spell)
break;
}
}

public override void AddAIHints(int slot, Actor actor, PartyRolesConfig.Assignment assignment, AIHints hints)
{
base.AddAIHints(slot, actor, assignment, hints);
// stay close to the middle if there is next imminent aoe
if (_aoes.Count > 1)
{
var aoe = _aoes[0];
hints.AddForbiddenZone(ShapeDistance.InvertedCircle(aoe.Origin, 3f), aoe.Activation);
}
}
}

class D051HerpekarisStates : StateMachineBuilder
Expand Down
65 changes: 19 additions & 46 deletions BossMod/Modules/Dawntrail/Dungeon/D05Origenics/D052Deceiver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -124,18 +124,18 @@ class Surge(BossModule module) : Components.Knockback(module)
private static readonly SafeWall[] walls2B1C = [new(new(XWest, ZRow4), new(XWest, ZRow5)), new(new(XWest, ZRow2), new(XWest, ZRow3)),
new(new(XEast, ZRow3), new(XEast, ZRow4)), new(new(XEast, ZRow1), new(XEast, ZRow2))];
private static readonly AOEShapeCone _shape = new(60f, 90f.Degrees());
private Func<WPos, float>? distance;

public override IEnumerable<Source> Sources(int slot, Actor actor) => SourcesList;

public override void OnCastStarted(Actor caster, ActorCastInfo spell)
{
void AddSource(Angle offset, SafeWall[] safeWalls)
=> SourcesList.Add(new(caster.Position, 30f, Module.CastFinishAt(spell), _shape, spell.Rotation + offset, Kind.DirForward, default, safeWalls));
if (spell.Action.ID == (uint)AID.Surge)
{
var activation = Module.CastFinishAt(spell);
var safewalls = GetActiveSafeWalls();
SourcesList.Add(new(caster.Position, 30f, activation, _shape, spell.Rotation + Angle.AnglesCardinals[3], Kind.DirForward, default, safewalls));
SourcesList.Add(new(caster.Position, 30f, activation, _shape, spell.Rotation + Angle.AnglesCardinals[0], Kind.DirForward, default, safewalls));
AddSource(90.Degrees(), safewalls);
AddSource(-90.Degrees(), safewalls);
}
}

Expand All @@ -161,43 +161,23 @@ public SafeWall[] GetActiveSafeWalls()
public override void OnCastFinished(Actor caster, ActorCastInfo spell)
{
if (spell.Action.ID == (uint)AID.Surge)
{
SourcesList.Clear();
distance = null;
++NumCasts;
}
}

public override void AddAIHints(int slot, Actor actor, PartyRolesConfig.Assignment assignment, AIHints hints)
{
if (SourcesList.Count != 0)
{
if (distance == null)
{
var safewalls = GetActiveSafeWalls();
var forbidden = new List<Func<WPos, float>>(4);
var safewalls = GetActiveSafeWalls();
var forbidden = new List<Func<WPos, float>>(4);

var centerX = Arena.Center.X;
for (var i = 0; i < 4; ++i)
{
var safeWall = safewalls[i];
forbidden.Add(ShapeDistance.InvertedRect(new(centerX, safeWall.Vertex1.Z - 5), safeWall.Vertex1.X == XWest ? -offset : offset, 10, default, 20));
}
distance = p =>
{
var maxDistance = float.MinValue;
for (var i = 0; i < 4; ++i)
{
var distance = forbidden[i](p);
if (distance > maxDistance)
{
maxDistance = distance;
}
}
return maxDistance;
};
var centerX = Arena.Center.X;
for (var i = 0; i < 4; ++i)
{
var safeWall = safewalls[i];
forbidden.Add(ShapeDistance.InvertedRect(new(centerX, safeWall.Vertex1.Z - 5f), safeWall.Vertex1.X == XWest ? -offset : offset, 10f, default, 20f));
}
hints.AddForbiddenZone(distance, SourcesList[0].Activation);
hints.AddForbiddenZone(ShapeDistance.Intersection(forbidden), SourcesList[0].Activation);
}
}
}
Expand All @@ -220,7 +200,7 @@ public override void OnCastStarted(Actor caster, ActorCastInfo spell)
for (var i = 0; i < 4; ++i)
{
var safewall = activeSafeWalls[i].Vertex1;
_hints.Add(new(rect, new(centerX, safewall.Z - 5f), safewall.X == -187.5f ? Angle.AnglesCardinals[0] : Angle.AnglesCardinals[3], default, Colors.SafeFromAOE, false));
_hints.Add(new(rect, new(centerX, safewall.Z - 5f), safewall.X == -187.5f ? -90.Degrees() : 90.Degrees(), default, Colors.SafeFromAOE, false));
}
}
}
Expand All @@ -233,25 +213,19 @@ public override void OnCastFinished(Actor caster, ActorCastInfo spell)

public override void AddHints(int slot, Actor actor, TextHints hints)
{
AOEInstance[] activeSafespot = [.. ActiveAOEs(slot, actor)];
var len = activeSafespot.Length;
if (len != 0)
var count = _hints.Count;
if (count != 0)
{
var isPositionSafe = false;
for (var i = 0; i < len; ++i)
for (var i = 0; i < count; ++i)
{
if (activeSafespot[i].Check(actor.Position))
if (_hints[i].Check(actor.Position))
{
isPositionSafe = true;
break;
}
}
if (!isPositionSafe)
{
hints.Add(Hint);
}
else
hints.Add(Hint, false);
hints.Add(Hint, !isPositionSafe);
}
}
}
Expand Down Expand Up @@ -279,7 +253,6 @@ public class D052Deceiver(WorldState ws, Actor primary) : BossModule(ws, primary
protected override void DrawEnemies(int pcSlot, Actor pc)
{
Arena.Actor(PrimaryActor);
Arena.Actors(Enemies(OID.OrigenicsSentryG92));
Arena.Actors(Enemies(OID.OrigenicsSentryG91));
Arena.Actors(Enemies([(uint)OID.OrigenicsSentryG92, (uint)OID.OrigenicsSentryG91]));
}
}
Loading

0 comments on commit a48a0cb

Please sign in to comment.