Skip to content

Commit

Permalink
Merge branch 'merge' into mergeWIP
Browse files Browse the repository at this point in the history
  • Loading branch information
CarnifexOptimus committed Jan 6, 2025
2 parents 83e35b2 + de2a997 commit 30aeb0b
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 18 deletions.
7 changes: 4 additions & 3 deletions BossMod/Modules/Dawntrail/Ultimate/FRU/FRUEnums.cs
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ public enum AID : uint
AkhMornAOEOracle = 40303, // Helper->players, no cast, range 4 circle, 4-hit 4-man stack
MornAfahUsurper = 40249, // UsurperOfFrostP4->self, 6.0s cast, single-target, visual (full raid stack, lethal if hp difference is large)
MornAfahOracle = 40304, // OracleOfDarknessP4->self, 6.0s cast, single-target, visual (full raid stack, lethal if hp difference is large)
MornAfahAOE = 40250, // Helper->players, no cast, range 4 circle, wipe if hp difference check fails ?
MornAfahAOE = 40250, // Helper->players, no cast, range 4 circle, 8-man stack on usurper target, wipe if hp difference check fails

CrystallizeTimeUsurper = 40240, // UsurperOfFrostP4->self, 10.0s cast, single-target, visual
CrystallizeTimeOracle = 40298, // OracleOfDarknessP4->self, 10.0s cast, range 100 circle, raidwide
Expand All @@ -240,8 +240,9 @@ public enum AID : uint
LongingOfTheLost = 40241, // Helper->location, no cast, range 12 circle, aoe when head is touched
DrachenWandererDisappear = 40244, // DrachenWanderer->self, no cast, single-target, visual (disappear)
JoylessDragonsong = 40242, // Helper->self, no cast, range 40 circle, wipe if ???
CrystallizeTimeHallowedWings = 40229, // UsurperOfFrostP4->self, 4.7+1.3s cast, single-target, visual (??? knockbacks?)
//_Weaponskill_HallowedWings = 40332, // UsurperOfFrostP4->self, 0.5s cast, range 40 width 50 rect
CrystallizeTimeHallowedWings1 = 40229, // UsurperOfFrostP4->self, 4.7+1.3s cast, single-target, visual (first knockback)
CrystallizeTimeHallowedWings2 = 40230, // UsurperOfFrostP4->self, 0.5+1.3s cast, single-target, visual (second knockback)
CrystallizeTimeHallowedWingsAOE = 40332, // UsurperOfFrostP4->self, 0.5s cast, range 40 width 50 rect, knockback 20, heavy damage on first target, vuln on first 4 targets
}

public enum SID : uint
Expand Down
16 changes: 11 additions & 5 deletions BossMod/Modules/Dawntrail/Ultimate/FRU/FRUStates.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ private void Phase34(uint id)
P4DarklitDragonsong(id + 0x110000, 1.9f);
P4AkhMornMornAfah(id + 0x120000, 5.8f);
P4CrystallizeTime(id + 0x130000, 4.6f);
P4AkhMornMornAfah(id + 0x140000, 0.1f);

SimpleState(id + 0xFF0000, 100, "???");
}
Expand Down Expand Up @@ -595,18 +596,23 @@ private void P4CrystallizeTime(uint id, float delay)
.ActivateOnEnter<P4CrystallizeTimeQuietus>()
.DeactivateOnExit<P4CrystallizeTimeQuietus>()
.SetHint(StateMachine.StateHint.Raidwide);
ComponentCondition<P4CrystallizeTimeRewind>(id + 0x80, 1.9f, comp => comp.Done, "Rewind")
.DeactivateOnExit<P4CrystallizeTimeRewind>()
ComponentCondition<P4CrystallizeTimeRewind>(id + 0x80, 1.9f, comp => comp.RewindDone, "Rewind place")
.DeactivateOnExit<P4CrystallizeTimeTidalLight>()
.DeactivateOnExit<P4CrystallizeTimeDragonHead>()
.DeactivateOnExit<P4CrystallizeTime>();
ActorCastStart(id + 0x90, _module.BossP4Oracle, AID.SpiritTaker, 0.4f);
ActorCastStart(id + 0x91, _module.BossP4Usurper, AID.CrystallizeTimeHallowedWings, 2.2f)
ActorCastStart(id + 0x91, _module.BossP4Usurper, AID.CrystallizeTimeHallowedWings1, 2.2f)
.ActivateOnEnter<P3SpiritTaker>();
ActorCastEnd(id + 0x92, _module.BossP4Oracle, 0.8f);
ComponentCondition<P3SpiritTaker>(id + 0x93, 0.3f, comp => comp.Spreads.Count == 0, "Jump")
.DeactivateOnExit<P3SpiritTaker>();
ActorCastEnd(id + 0x94, _module.BossP4Usurper, 3.6f);
// TODO: knockbacks resolve, downtime end
ComponentCondition<P4CrystallizeTimeRewind>(id + 0x94, 3.3f, comp => comp.ReturnDone, "Rewind return")
.DeactivateOnExit<P4CrystallizeTimeRewind>();
ActorCastEnd(id + 0x95, _module.BossP4Usurper, 0.3f);
ActorCast(id + 0xA0, _module.BossP4Usurper, AID.CrystallizeTimeHallowedWingsAOE, 1.4f, 0.5f, true);
ActorCast(id + 0xB0, _module.BossP4Usurper, AID.CrystallizeTimeHallowedWings2, 2.1f, 0.5f, true);
ActorCast(id + 0xC0, _module.BossP4Usurper, AID.CrystallizeTimeHallowedWingsAOE, 1.4f, 0.5f, true);
ActorTargetable(id + 0xD0, _module.BossP4Usurper, true, 5.3f, "Bosses reappear")
.SetHint(StateMachine.StateHint.DowntimeEnd);
}
}
5 changes: 3 additions & 2 deletions BossMod/Modules/Dawntrail/Ultimate/FRU/P4AkhMorn.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
namespace BossMod.Dawntrail.Ultimate.FRU;

// TODO: can target change if boss is provoked mid cast?
class P4AkhMorn(BossModule module) : Components.UniformStackSpread(module, 4, 0, 4)
{
public int NumCasts;

public override void OnCastStarted(Actor caster, ActorCastInfo spell)
{
if ((AID)spell.Action.ID == AID.AkhMornOracle)
AddStacks(Raid.WithoutSlot(true).Where(p => p.Role == Role.Tank), Module.CastFinishAt(spell, 0.9f));
if ((AID)spell.Action.ID is AID.AkhMornOracle or AID.AkhMornUsurper && WorldState.Actors.Find(caster.TargetID) is var target && target != null)
AddStack(target, Module.CastFinishAt(spell, 0.9f));
}

public override void OnEventCast(Actor caster, ActorCastEvent spell)
Expand Down
66 changes: 61 additions & 5 deletions BossMod/Modules/Dawntrail/Ultimate/FRU/P4CrystallizeTime.cs
Original file line number Diff line number Diff line change
Expand Up @@ -424,21 +424,77 @@ private WDir SafeOffsetFangOther(int numHourglassesDone, float northSlowX)
private WDir SafeOffsetFinalNonAir(float northSlowX) => 6 * (northSlowX > 0 ? -150 : 150).Degrees().ToDirection();
}

// TODO: better positioning hints
class P4CrystallizeTimeRewind(BossModule module) : BossComponent(module)
{
public bool Done;
public bool RewindDone;
public bool ReturnDone;
private readonly P4CrystallizeTime? _ct = module.FindComponent<P4CrystallizeTime>();
private readonly P4CrystallizeTimeTidalLight? _exalines = module.FindComponent<P4CrystallizeTimeTidalLight>();

public override void AddHints(int slot, Actor actor, TextHints hints)
{
if (!RewindDone && _ct != null && _exalines != null && _ct.Cleansed[slot])
{
var players = Raid.WithoutSlot(excludeNPCs: true).ToList();
players.SortBy(p => p.Position.X);
var xOrder = players.IndexOf(actor);
players.SortBy(p => p.Position.Z);
var zOrder = players.IndexOf(actor);
if (xOrder >= 0 && zOrder >= 0)
{
if (_exalines.StartingOffset.X > 0)
xOrder = players.Count - 1 - xOrder;
if (_exalines.StartingOffset.Z > 0)
zOrder = players.Count - 1 - zOrder;

var isFirst = xOrder == 0 || zOrder == 0;
var isTank = actor.Role == Role.Tank;
if (isFirst != isTank)
hints.Add(isTank ? "Stay in front of the group!" : "Hide behind tank!");
var isFirstX = xOrder < 4;
var isFirstZ = zOrder < 4;
if (isFirstX == isFirstZ)
hints.Add("Position in group properly!");
}

if (KnockbackSpots(actor.Position).Any(p => !Module.Bounds.Contains(p - Module.Center)))
hints.Add("About to be knocked into wall!");
}
}

public override void DrawArenaForeground(int pcSlot, Actor pc)
{
if (_ct != null && _exalines != null && _ct.Cleansed[pcSlot])
Arena.AddCircle(Arena.Center + 0.5f * _exalines.StartingOffset, 1, Colors.Safe); // TODO: better hints...
if (!RewindDone && _ct != null && _exalines != null && _ct.Cleansed[pcSlot])
{
var vertices = KnockbackSpots(pc.Position).ToList();
Arena.AddQuad(pc.Position, vertices[0], vertices[2], vertices[1], Colors.Danger);
Arena.AddCircle(Arena.Center + 0.5f * _exalines.StartingOffset, 1, Colors.Safe);
}
}

public override void OnStatusGain(Actor actor, ActorStatus status)
{
if ((SID)status.ID == SID.Return)
Done = true;
switch ((SID)status.ID)
{
case SID.Return:
RewindDone = true;
break;
case SID.Stun:
ReturnDone = true;
break;
}
}

private IEnumerable<WPos> KnockbackSpots(WPos starting)
{
if (_exalines != null)
{
var dx = _exalines.StartingOffset.X > 0 ? -20 : +20;
var dz = _exalines.StartingOffset.Z > 0 ? -20 : +20;
yield return starting + new WDir(dx, 0);
yield return starting + new WDir(0, dz);
yield return starting + new WDir(dx, dz);
}
}
}
5 changes: 2 additions & 3 deletions BossMod/Modules/Dawntrail/Ultimate/FRU/P4MornAfah.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@ class P4MornAfah(BossModule module) : Components.UniformStackSpread(module, 4, 0
{
public override void OnCastStarted(Actor caster, ActorCastInfo spell)
{
if ((AID)spell.Action.ID == AID.MornAfahOracle)
if ((AID)spell.Action.ID == AID.MornAfahUsurper)
{
// note: target is random?..
var target = WorldState.Actors.Find(caster.TargetID);
if (target != null)
AddStack(target, Module.CastFinishAt(spell, 0.9f));
Expand All @@ -15,7 +14,7 @@ public override void OnCastStarted(Actor caster, ActorCastInfo spell)

public override void OnEventCast(Actor caster, ActorCastEvent spell)
{
if ((AID)spell.Action.ID == AID.MornAfahAOE) // TODO: proper spell...
if ((AID)spell.Action.ID == AID.MornAfahAOE)
Stacks.Clear();
}
}
Expand Down
17 changes: 17 additions & 0 deletions BossMod/Replay/Visualization/ReplayDetailsWindow.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using BossMod.Autorotation;
using ImGuiNET;
using System.IO;

namespace BossMod.ReplayVisualization;

Expand Down Expand Up @@ -211,6 +212,9 @@ private void DrawControlRow()
ImGui.Checkbox("Show config", ref _showConfig);
ImGui.SameLine();
ImGui.Checkbox("Show debug", ref _showDebug);
ImGui.SameLine();
if (ImGui.Button("Split"))
SplitLog();

if (_showConfig)
_config.Draw();
Expand Down Expand Up @@ -503,4 +507,17 @@ private void ResetPF()
{
_pfVisu = null;
}

private void SplitLog()
{
if (_player.Replay.Ops.Count == 0)
return;

var player = new ReplayPlayer(_player.Replay);
player.WorldState.Frame.Timestamp = _player.Replay.Ops[0].Timestamp; // so that we get correct name etc.
using (var relogger = new ReplayRecorder(player.WorldState, ReplayLogFormat.BinaryCompressed, false, new FileInfo(_player.Replay.Path).Directory!, "Before"))
player.AdvanceTo(_curTime, () => { });
using (var relogger = new ReplayRecorder(player.WorldState, ReplayLogFormat.BinaryCompressed, true, new FileInfo(_player.Replay.Path).Directory!, "After"))
player.AdvanceTo(DateTime.MaxValue, () => { });
}
}

0 comments on commit 30aeb0b

Please sign in to comment.