Skip to content

Commit

Permalink
Merge pull request #536 from FFXIV-CombatReborn/mergeWIP
Browse files Browse the repository at this point in the history
merge chaotic changes
  • Loading branch information
CarnifexOptimus authored Jan 1, 2025
2 parents 39b729b + 0d9d1b7 commit 0ae8cf3
Show file tree
Hide file tree
Showing 10 changed files with 237 additions and 64 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ class Break(BossModule module) : Components.GenericGaze(module)
{
public readonly List<Eye> Eyes = [];

public override IEnumerable<Eye> ActiveEyes(int slot, Actor actor) => Eyes;//_casters.Where(c => c.CastInfo?.TargetID != actor.InstanceID).Select(c => new Eye(EyePosition(c), Module.CastFinishAt(c.CastInfo), Range: range));
public override IEnumerable<Eye> ActiveEyes(int slot, Actor actor) => Eyes;

public override void OnCastStarted(Actor caster, ActorCastInfo spell)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ class Atomos(BossModule module) : Components.Adds(module, (uint)OID.Atomos);
class LoomingChaos(BossModule module) : Components.CastCounter(module, ActionID.MakeSpell(AID.LoomingChaosAOE));

// TODO: tankswap hints component for phase1
// TODO: phase 2 squares, break timer, teleport zones
// TODO: phase 2 squares, break timer, teleport zones, outer ring safety
// TODO: grim embrace / curse of darkness prevent turning

[ModuleInfo(BossModuleInfo.Maturity.WIP, Contributors = "The Combat Reborn Team (Malediktus, LTS)", GroupType = BossModuleInfo.GroupType.CFC, GroupID = 1010, NameID = 13624, PlanLevel = 100)]
[ModuleInfo(BossModuleInfo.Maturity.Verified, Contributors = "The Combat Reborn Team (Malediktus, LTS)", GroupType = BossModuleInfo.GroupType.CFC, GroupID = 1010, NameID = 13624, PlanLevel = 100)]
public class Ch01CloudOfDarkness(WorldState ws, Actor primary) : BossModule(ws, primary, DefaultCenter, DefaultArena)
{
public static readonly WPos DefaultCenter = new(100, 100);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,18 +140,17 @@ public enum AID : uint
public enum SID : uint
{
//_Gen_ArcaneDesign = 4180, // Boss->Boss, extra=0x0
//_Gen_VeilOfDarkness = 4179, // Boss->Boss, extra=0x0
//_Gen_LightningResistanceDown = 4386, // Helper/Boss->player, extra=0x1/0x2/0x3/0x4/0x5/0x6/0x7/0x8/0x9/0xA/0xB/0xC/0xD/0xE/0xF/0x10
DeadlyEmbrace = 4181, // none->player, extra=0x0
AbyssalEdge = 4182, // Boss->Boss, extra=0x0 (endeath/enaero stored)
//_Gen_VeilOfDarkness = 4179, // Boss->Boss, extra=0x0
//_Gen_CloyingCondensation = 2532, // none->player, extra=0x0
//_Gen_CloyingCondensation = 2532, // none->player, extra=0x0, prevent jumps?
//_Gen_ = 4388, // none->StygianShadow, extra=0x1052
//_Gen_ = 4387, // none->Boss, extra=0x1051
InnerDarkness = 4177, // none->player, extra=0x0, on main platform
OuterDarkness = 4178, // none->player, extra=0x0, on side platform
//_Gen_Rehabilitation = 4191, // none->Boss, extra=0x1/0x4/0x3/0x2
//_Gen_LifeDrain = 1377, // none->player, extra=0x0
//_Gen_CraftersGrace = 45, // player->player, extra=0x50
CurseOfDarkness = 2387, // none->player, extra=0x0
//_Gen_StabWound = 3061, // none->player, extra=0x0
//_Gen_StabWound = 3062, // none->player, extra=0x0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,7 @@ private void Subphase2(uint id, float delay)
ThirdArtOfDarknessParticleConcentration(id + 0x20000, 4);
GhastlyGloom(id + 0x30000, 12.3f);
CurseOfDarkness(id + 0x40000, 8.3f);
EvilSeed(id + 0x50000, 9.9f);
ChaosCondensedDiffusiveForceParticleBeam(id + 0x60000, 8.1f);
EvilSeedChaosCondensedDiffusiveForceParticleBeam(id + 0x50000, 9.9f);
ActivePivotParticleBeam(id + 0x70000, 4.4f);
LoomingChaos(id + 0x80000, 6.2f);

Expand Down Expand Up @@ -240,7 +239,8 @@ private void ThirdArtOfDarknessParticleConcentration(uint id, float delay)
.DeactivateOnExit<ThirdArtOfDarknessHyperFocusedParticleBeam>()
.DeactivateOnExit<ThirdArtOfDarknessMultiProngedParticleBeam>()
.DeactivateOnExit<ThirdArtOfDarknessCleave>();
ComponentCondition<ParticleConcentration>(id + 0x50, 3.6f, comp => comp.NumCasts > 0, "Towers")
ComponentCondition<ParticleConcentration>(id + 0x50, 3.6f, comp => comp.Towers.Count == 0, "Towers")
.ExecOnEnter<ParticleConcentration>(comp => comp.ShowOuterTowers())
.DeactivateOnExit<ParticleConcentration>();
}

Expand Down Expand Up @@ -270,29 +270,29 @@ private State FloodOfDarknessAdds(uint id, float delay)
.DeactivateOnExit<FloodOfDarknessAdd>();
}

// TODO: this one needs a lot of thought
private void EvilSeed(uint id, float delay)
private void EvilSeedChaosCondensedDiffusiveForceParticleBeam(uint id, float delay)
{
ComponentCondition<EvilSeedBait>(id, delay, comp => comp.Baiters.Any())
.ActivateOnEnter<EvilSeedBait>();
ComponentCondition<EvilSeedAOE>(id + 0x10, 8.1f, comp => comp.Casters.Count > 0, "Seed plant")
.ActivateOnEnter<EvilSeedAOE>()
.ActivateOnEnter<EvilSeedVoidzone>()
.DeactivateOnExit<EvilSeedBait>();

GhastlyGloom(id + 0x1000, 2.8f)
.DeactivateOnExit<EvilSeedAOE>();

ComponentCondition<ThornyVine>(id + 0x2000, 14, comp => comp.Targets.Any())
.ActivateOnEnter<ThornyVine>();
ComponentCondition<ThornyVine>(id + 0x2010, 3, comp => comp.HaveTethers);
FloodOfDarknessAdds(id + 0x2020, 2.2f)
.DeactivateOnExit<ThornyVine>();
}
ComponentCondition<ThornyVine>(id + 0x2010, 3, comp => comp.TethersAssigned, "Tethers");
FloodOfDarknessAdds(id + 0x2020, 2.2f);

private void ChaosCondensedDiffusiveForceParticleBeam(uint id, float delay)
{
CastMulti(id, [AID.ChaosCondensedParticleBeam, AID.DiffusiveForceParticleBeam], delay, 8)
CastMulti(id + 0x3000, [AID.ChaosCondensedParticleBeam, AID.DiffusiveForceParticleBeam], 8.1f, 8)
.ActivateOnEnter<ChaosCondensedParticleBeam>()
.ActivateOnEnter<DiffusiveForceParticleBeam>();
Condition(id + 0x10, 0.7f, () => Module.FindComponent<ChaosCondensedParticleBeam>()?.NumCasts > 0 || Module.FindComponent<DiffusiveForceParticleBeam>()?.Spreads.Count == 0, "Spread/line stacks")
.ActivateOnEnter<DiffusiveForceParticleBeam>()
.DeactivateOnExit<EvilSeedVoidzone>()
.DeactivateOnExit<ThornyVine>();
Condition(id + 0x3010, 0.7f, () => Module.FindComponent<ChaosCondensedParticleBeam>()?.NumCasts > 0 || Module.FindComponent<DiffusiveForceParticleBeam>()?.Spreads.Count == 0, "Spread/line stacks")
.DeactivateOnExit<ChaosCondensedParticleBeam>()
.DeactivateOnExit<DiffusiveForceParticleBeam>(); // TODO: show second wave ...
}
Expand Down Expand Up @@ -335,7 +335,8 @@ private void ParticleConcentrationPhaser(uint id, float delay)
.ActivateOnEnter<ParticleConcentration>(); // TODO: towers appear 1s after cast end
ComponentCondition<Phaser>(id + 0x11, 1.5f, comp => comp.NumCasts >= 6, "Adds sides/front")
.DeactivateOnExit<Phaser>();
ComponentCondition<ParticleConcentration>(id + 0x20, 6.6f, comp => comp.NumCasts > 0, "Towers")
ComponentCondition<ParticleConcentration>(id + 0x20, 6.6f, comp => comp.Towers.Count == 0, "Towers")
.ExecOnEnter<ParticleConcentration>(comp => comp.ShowOuterTowers())
.DeactivateOnExit<ParticleConcentration>();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
namespace BossMod.Dawntrail.Chaotic.Ch01CloudOfDarkness;

// TODO: who gets radius 7 and who gets radius 5?
// TODO: show for second wave too...
// note: it seems that normally first wave (radius 7) hits people inside, and second wave (radius 5) hits people outside
// however, if some of the players in the mid are dead, some players on the outside will be hit by first wave (up to a total of 12 hits)
// if there are <= 12 players alive, everyone will be hit by the first wave, and the second wave will never happen
// so for safety we just show larger radius around everyone
// TODO: show second wave for players not hit by first wave
class DiffusiveForceParticleBeam(BossModule module) : Components.UniformStackSpread(module, 0, 7)
{
public override void OnCastStarted(Actor caster, ActorCastInfo spell)
{
if ((AID)spell.Action.ID == AID.DiffusiveForceParticleBeam)
AddSpreads(Raid.WithoutSlot(), Module.CastFinishAt(spell, 0.7f));
AddSpreads(Raid.WithoutSlot(true), Module.CastFinishAt(spell, 0.7f));
}

public override void OnEventCast(Actor caster, ActorCastEvent spell)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,15 @@ public override void OnEventIcon(Actor actor, uint iconID, ulong targetID)

class EvilSeedAOE(BossModule module) : Components.LocationTargetedAOEs(module, ActionID.MakeSpell(AID.EvilSeedAOE), 5);

// todo: should be chains...
class ThornyVine(BossModule module) : BossComponent(module)
class EvilSeedVoidzone(BossModule module) : Components.PersistentVoidzone(module, 5, module => module.Enemies(OID.EvilSeed).Where(z => z.EventState != 7));

class ThornyVine(BossModule module) : Components.Chains(module, (uint)TetherID.ThornyVine, default, 25)
{
public BitMask Targets;
public bool HaveTethers;

public override void OnEventIcon(Actor actor, uint iconID, ulong targetID)
{
if (iconID == (uint)IconID.ThornyVineBait)
Targets.Set(Raid.FindSlot(actor.InstanceID));
}

public override void OnTethered(Actor source, ActorTetherInfo tether)
{
if (tether.ID == (uint)TetherID.ThornyVine)
HaveTethers = true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,107 @@
// 47-56 = 1-man tower falling orb
// 57-66 = 2-man tower falling orb
// 67-6E = 3-man tower falling orb
class ParticleConcentration(BossModule module) : Components.CastCounter(module, ActionID.MakeSpell(AID.ParticleBeam1)) { }
class ParticleConcentration(BossModule module) : Components.GenericTowers(module)
{
private BitMask _innerPlayers;
private BitMask _outerPlayers;
private readonly List<WPos> _outerTowers = []; // note: initially we don't show outer towers, as players resolve different mechanics first

public void ShowOuterTowers()
{
var activation = Towers.Count > 0 ? Towers[0].Activation : default;
Towers.AddRange(_outerTowers.Select(p => new Tower(p, 3, 3, 3, _innerPlayers, activation)));
}

public override void OnStatusGain(Actor actor, ActorStatus status)
{
switch ((SID)status.ID)
{
case SID.InnerDarkness:
_innerPlayers.Set(Raid.FindSlot(actor.InstanceID));
break;
case SID.OuterDarkness:
_outerPlayers.Set(Raid.FindSlot(actor.InstanceID));
break;
}
}

public override void OnStatusLose(Actor actor, ActorStatus status)
{
switch ((SID)status.ID)
{
case SID.InnerDarkness:
_innerPlayers.Clear(Raid.FindSlot(actor.InstanceID));
break;
case SID.OuterDarkness:
_outerPlayers.Clear(Raid.FindSlot(actor.InstanceID));
break;
}
}

public override void OnEventEnvControl(byte index, uint state)
{
if (state != 0x00020001) // appear
return;

var (offset, count) = index switch
{
0x1F => (new(-9, -15), 1),
0x20 => (new(+9, -15), 1),
0x21 => (new(-21, -15), 1),
0x22 => (new(+21, -15), 1),
0x23 => (new(-15, -9), 1),
0x24 => (new(+15, -9), 1),
0x25 => (new(-15, -21), 1),
0x26 => (new(+15, -21), 1),
0x27 => (new(-9, +15), 1),
0x28 => (new(+9, +15), 1),
0x29 => (new(-21, +15), 1),
0x2A => (new(+21, +15), 1),
0x2B => (new(-15, +9), 1),
0x2C => (new(+15, +9), 1),
0x2D => (new(-15, +21), 1),
0x2E => (new(+15, +21), 1),
0x2F => (new(-12, -15), 2),
0x30 => (new(+12, -15), 2),
0x31 => (new(-18, -15), 2),
0x32 => (new(+18, -15), 2),
0x33 => (new(-15, -12), 2),
0x34 => (new(+15, -12), 2),
0x35 => (new(-15, -18), 2),
0x36 => (new(+15, -18), 2),
0x37 => (new(-12, +15), 2),
0x38 => (new(+12, +15), 2),
0x39 => (new(-18, +15), 2),
0x3A => (new(+18, +15), 2),
0x3B => (new(-15, +12), 2),
0x3C => (new(+15, +12), 2),
0x3D => (new(-15, +18), 2),
0x3E => (new(+15, +18), 2),
0x3F => (new(-26.5f, -4.5f), 3),
0x40 => (new(-22, 0), 3),
0x41 => (new(-26.5f, +4.5f), 3),
0x42 => (new(-31, 0), 3),
0x43 => (new(+26.5f, -4.5f), 3),
0x44 => (new(+22, 0), 3),
0x45 => (new(+26.5f, +4.5f), 3),
0x46 => (new(+31, 0), 3),
_ => (default(WDir), 0)
};

if (count == 3)
_outerTowers.Add(Module.Center + offset);
else if (count > 0)
Towers.Add(new(Module.Center + offset, 3, count, count, _outerPlayers, WorldState.FutureTime(10.1f)));
}

public override void OnEventCast(Actor caster, ActorCastEvent spell)
{
if ((AID)spell.Action.ID is AID.ParticleBeam1 or AID.ParticleBeam2 or AID.ParticleBeam3)
{
++NumCasts;
if (Towers.RemoveAll(t => t.Position.AlmostEqual(caster.Position, 1)) != 1)
ReportError($"Unexpected tower position @ {caster.Position}");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ class ThirdArtOfDarknessCleave(BossModule module) : Components.GenericAOEs(modul
public enum Mechanic { None, Left, Right, Stack, Spread }

public readonly Dictionary<Actor, List<(Mechanic mechanic, DateTime activation)>> Mechanics = [];
public BitMask PlatformPlayers;

private static readonly AOEShapeCone _shape = new(15, 90.Degrees());

Expand All @@ -25,12 +26,28 @@ public override IEnumerable<AOEInstance> ActiveAOEs(int slot, Actor actor)

public override void AddHints(int slot, Actor actor, TextHints hints)
{
var (a, m) = Mechanics.FirstOrDefault(kv => kv.Key.InstanceID == actor.TargetID);
if (a != null && m.Count > 0)
hints.Add($"Order: {string.Join(" > ", m.Select(m => m.mechanic))}", false);
if (PlatformPlayers[slot])
{
var playerSide = actor.Position.X - Module.Center.X;
var (a, m) = Mechanics.FirstOrDefault(kv => (kv.Key.Position.X - Module.Center.X) * playerSide > 0);
if (a != null && m.Count > 0)
hints.Add($"Order: {string.Join(" > ", m.Select(m => m.mechanic))}", false);
}
base.AddHints(slot, actor, hints);
}

public override void OnStatusGain(Actor actor, ActorStatus status)
{
if ((SID)status.ID == SID.OuterDarkness)
PlatformPlayers.Set(Raid.FindSlot(actor.InstanceID));
}

public override void OnStatusLose(Actor actor, ActorStatus status)
{
if ((SID)status.ID == SID.OuterDarkness)
PlatformPlayers.Clear(Raid.FindSlot(actor.InstanceID));
}

public override void OnEventIcon(Actor actor, uint iconID, ulong targetID)
{
if ((OID)actor.OID == OID.StygianShadow)
Expand Down Expand Up @@ -100,7 +117,7 @@ public override void Update()
foreach (var (a, m) in _main.Mechanics)
if (m.Count > 0 && m[0].mechanic == ThirdArtOfDarknessCleave.Mechanic.Stack)
foreach (var p in Raid.WithoutSlot().SortedByRange(a.Position).Take(3))
AddStack(p, m[0].activation);
AddStack(p, m[0].activation, ~_main.PlatformPlayers);
base.Update();
}
}
Loading

0 comments on commit 0ae8cf3

Please sign in to comment.