From 8204c8b366a4b716b6a94e5e3704dbb95546fe8a Mon Sep 17 00:00:00 2001 From: Jacob Keller Date: Sat, 25 Apr 2026 18:56:54 -0700 Subject: [PATCH 1/6] raidboss: timelines and basic triggers for San d'Oria Second Walk I finally got around to completing some basic timelines and triggers for the second Dawntrail Alliance Raid: San d'Oria: The Second Walk. This AR is quite tricky, especially the timeline for the first boss, Faithbound Kirin. I really didn't do a great job on that one, because there are so many branching paths and possibilities. I am reasonably confident in the loops for Kam'lanaut and Eald'narche, as I compared against several super long fflogs runs. Entries may still need some minor adjusting, and I think some of the "duration" mechanics might benefit from a better more verbose timeline. The triggers are mostly tested in game now, but might still have mistakes, so that needs some testing and verification, especially the elemental blade triggers for Kam'lanaut. There are still a lot of tasks left unfulfilled, but this might be closing on decent enough to merge *something*. As such, here's a summary of what I think is still missing.. Faithbound Kirin: - [ ] Missing timeline data for 2 of the 4 summons - [ ] A proper full timeline and loop (if we dare...) - [ ] Entries for --jump-- or --untargetable-- - [ ] A full trigger solution for the wrought arms mechanics? Ultima/Omega leftovers: - [ ] Triggers for some of the mechanics - [ ] --jump--, --targetable-- entries - [ ] triggers for the various spread / run away mechanics Kam'lanaut leftovers: - [ ] trigger for some of the element mechanics - [ ] timeline entries for --untargetable--, --stun--, etc - [ ] improve the timeline entries for elemental blade - [ ] simplify sublime elements timeline entries? Eald'narche leftovers: - [ ] timeline for Ancient Triad? (lots of branching...) - [ ] triggers for ancient triad - [ ] other basic triggers - [ ] improvement to duplicate timeline entries? - [ ] --untargetable-- etc for the phase Signed-off-by: Jacob Keller --- .../07-dt/alliance/san-doria-second-walk.ts | 372 ++++++++++ .../07-dt/alliance/san-doria-second-walk.txt | 685 ++++++++++++++++++ 2 files changed, 1057 insertions(+) create mode 100644 ui/raidboss/data/07-dt/alliance/san-doria-second-walk.ts create mode 100644 ui/raidboss/data/07-dt/alliance/san-doria-second-walk.txt diff --git a/ui/raidboss/data/07-dt/alliance/san-doria-second-walk.ts b/ui/raidboss/data/07-dt/alliance/san-doria-second-walk.ts new file mode 100644 index 00000000000..5a9dd20f6b3 --- /dev/null +++ b/ui/raidboss/data/07-dt/alliance/san-doria-second-walk.ts @@ -0,0 +1,372 @@ +import Outputs from '../../../../../resources/outputs'; +import { Responses } from '../../../../../resources/responses'; +import ZoneId from '../../../../../resources/zone_id'; +import { RaidbossData } from '../../../../../types/data'; +import { TriggerSet } from '../../../../../types/trigger'; + +const effectB9AMap = { + '3AC': 'fire', + '3AD': 'earth', + '3AE': 'water', + '3AF': 'ice', + '3B0': 'thunder', + '3B1': 'wind', +} as const; + +type B9AMapKeys = keyof typeof effectB9AMap; +type B9AMapValues = typeof effectB9AMap[B9AMapKeys] | 'unknown'; + +const isEffectB9AKey = (key: string | undefined): key is B9AMapKeys => { + if (key === undefined) + return false; + return Object.keys(effectB9AMap).includes(key); +}; + +const b9aValueToElement = ( + id: string | undefined, +): B9AMapValues | 'unknown' => { + if (isEffectB9AKey(id)) + return effectB9AMap[id]; + return 'unknown'; +}; + +const elementOutputStrings = { + fire: { + en: 'Fire', + }, + earth: { + en: 'Earth', + }, + water: { + en: 'Water', + }, + ice: { + en: 'Ice', + }, + thunder: { + en: 'Thunder', + }, + wind: { + en: 'Wind', + }, + separator: { + en: '/', + }, + combo: { + en: 'Away from ${elements}', + }, +}; + +export interface Data extends RaidbossData { + expectedElements: 0 | 2 | 3; + storedElements: B9AMapValues[]; + tankbusters: string[]; +} + +// TODO: +// Kirin +// Shijin mechanics +// Wrought Arms +// Synchronized Strike?? +// +// Ultima & Omega +// ??? +// +// Kam'lanaut +// Princely Blow Tank Buster + knockback +// Sublime Elements full solve +// Illumed Facet solve +// Illumed Facet + Shield Bash solve? +// +// Eald'narche +// Spread markers for Empyeal Vortex +// Spread + Follow ups from Omega Javelin +// duplicate/visions of paradise solve? +// Ancient Triad mechanics? +// Finish Cronos Sling + +const triggerSet: TriggerSet = { + id: 'San d\'Oria: The Second Walk', + zoneId: ZoneId.SanDoriaTheSecondWalk, + timelineFile: 'san-doria-second-walk.txt', + initData: () => ({ + expectedElements: 0, + storedElements: [], + tankbusters: [], + }), + triggers: [ + { + id: 'Sandoria Second Walk Kirin Stonega IV', + type: 'StartsUsing', + netRegex: { id: 'AD2B', source: 'Faithbound Kirin', capture: false }, + response: Responses.aoe(), + }, + { + id: 'Sandoria Second Walk Kirin Crimson Riddle Breath', + type: 'StartsUsing', + netRegex: { id: 'AFF4', source: 'Faithbound Kirin', capture: false }, + response: Responses.getBehind(), + }, + { + id: 'Sandoria Second Walk Kirin Crimson Riddle Tail', + type: 'StartsUsing', + netRegex: { id: 'AFF5', source: 'Faithbound Kirin', capture: false }, + response: Responses.goFront(), + }, + { + id: 'Sandoria Second Walk Kirin Chiseled Arm Shockwave', + type: 'StartsUsing', + netRegex: { id: 'ADC0', source: 'Chiseled Arm', capture: false }, + response: Responses.aoe(), + }, + { + id: 'Sandoria Second Walk Kirin Deadly Hold', + type: 'StartsUsing', + netRegex: { id: 'ADB2', source: 'Faithbound Kirin', capture: false }, + condition: (data) => data.role === 'tank', + response: Responses.getTowers(), + }, + { + id: 'Sandoria Second Walk Omega Ion Efflux', + type: 'StartsUsing', + netRegex: { id: 'AD2B', source: 'Omega, the One', capture: false }, + response: Responses.aoe(), + }, + { + id: 'Sandoria Second Walk Ultima Antimatter Collector', + type: 'StartsUsing', + netRegex: { id: 'AD11', source: 'Ultima, the Feared', capture: true }, + run: (data, matches) => data.tankbusters.push(matches.target), + }, + { + id: 'Sandoria Second Walk Ultima Antimatter', + type: 'StartsUsing', + netRegex: { id: 'AD11', source: 'Ultima, the Feared', capture: false }, + delaySeconds: 0.3, + suppressSeconds: 1, + response: (data, _matches, output) => { + // cactbot-builtin-response + output.responseOutputStrings = { + tankCleaveOnYou: Outputs.tankCleaveOnYou, + tankCleaves: Outputs.avoidTankCleaves, + }; + + if (data.tankbusters.includes(data.me)) + return { alertText: output.tankCleaveOnYou!() }; + return { infoText: output.tankCleaves!() }; + }, + run: (data) => data.tankbusters = [], + }, + { + id: 'Sandoria Second Walk Omega Fore-to-aft Fire', + type: 'StartsUsing', + netRegex: { id: 'AD25', source: 'Omega, the One', capture: false }, + durationSeconds: 8, + response: Responses.getBackThenFront(), + }, + { + id: 'Sandoria Second Walk Omega Aft-to-fore Fire', + type: 'StartsUsing', + netRegex: { id: 'AD27', source: 'Omega, the One', capture: false }, + durationSeconds: 8, + response: Responses.getFrontThenBack(), + }, + { + id: 'Sandoria Second Walk Ultima Tractor Beam', + type: 'StartsUsing', + netRegex: { id: 'AD06', source: 'Ultima, the Feared', capture: false }, + response: Responses.drawIn(), + }, + { + id: 'Sandoria Second Walk Ultima Citadel Buster', + type: 'StartsUsing', + netRegex: { id: 'AD1B', source: 'Ultima, the Feared', capture: false }, + response: Responses.bigAoe(), + }, + { + id: 'Sandoria Second Walk Kamlanaut Enspirited Swordplay', + type: 'StartsUsing', + netRegex: { id: 'ACBD', source: 'Kam\'lanaut', capture: false }, + response: Responses.aoe(), + }, + { + id: 'Sandoria Second Walk Kamlanaut Elemental Blade x2', + type: 'StartsUsing', + netRegex: { id: 'AC91', source: 'Kam\'lanaut', capture: false }, + run: (data) => { + data.storedElements = []; + data.expectedElements = 2; + }, + }, + { + id: 'Sandoria Second Walk Kamlanaut Elemental Blade x3', + type: 'StartsUsing', + netRegex: { id: 'AC92', source: 'Kam\'lanaut', capture: false }, + run: (data) => { + data.storedElements = []; + data.expectedElements = 3; + }, + }, + { + id: 'Sandoria Second Walk Kamlanaut Elemental Blade Collector', + type: 'GainsEffect', + netRegex: { effectId: 'B9A', count: Object.keys(effectB9AMap), capture: true }, + condition: (data, matches) => { + if (data.expectedElements === 0) + return false; + + const element = b9aValueToElement(matches.count); + data.storedElements.push(element); + + return true; + }, + durationSeconds: 3, + infoText: (_data, matches, output) => { + const element = b9aValueToElement(matches.count); + return output[element]!(); + }, + outputStrings: elementOutputStrings, + }, + { + id: 'Sandoria Second Walk Kamlanaut Elemental Blade', + type: 'Ability', + netRegex: { id: 'AC91', source: 'Kam\'lanaut', capture: false }, + condition: (data) => data.expectedElements > 0, + durationSeconds: 10, + alertText: (data, _matches, output) => { + const elements = data.storedElements.join(output.separator!()); + return output.combo!({ elements: elements }); + }, + outputStrings: elementOutputStrings, + }, + { + id: 'Sandoria Second Walk Kamlanaut Great Wheel', + type: 'StartsUsing', + netRegex: { id: ['ACAD', 'ACAE', 'ACAF', 'ACB0'], source: 'Kam\'lanaut', capture: false }, + infoText: (_data, _matches, output) => output.text!(), + outputStrings: { + text: { + en: 'Out of Melee => Get Behind', + }, + }, + }, + { + id: 'Sandoria Second Walk Kamlanaut Transcendent Union', + type: 'StartsUsing', + netRegex: { id: 'ACB4', source: 'Kam\'lanaut', capture: false }, + durationSeconds: 11.1, + alertText: (_data, _matches, output) => output.text!(), + outputStrings: { + text: { + en: 'AoE x5 => Big AoE', + }, + }, + }, + { + id: 'Sandoria Second Walk Kamlanaut Shield Bash', + type: 'StartsUsing', + netRegex: { id: 'ACBE', source: 'Kam\'lanaut', capture: false }, + response: Responses.knockback(), + }, + { + id: 'Sandoria Second Walk Kamlanaut Empyreal Banish IV', + type: 'StartsUsing', + netRegex: { id: 'ACC0', source: 'Kam\'lanaut', capture: true }, + response: Responses.stackMarkerOn(), + }, + { + id: 'Sandoria Second Walk Ealdnarche Uranos Cascade Collector', + type: 'StartsUsing', + netRegex: { id: 'AD52', source: 'Eald\'narche', capture: true }, + run: (data, matches) => data.tankbusters.push(matches.target), + }, + { + id: 'Sandoria Second Walk Ealdnarche Uranos Cascade', + type: 'StartsUsing', + netRegex: { id: 'AD52', source: 'Eald\'narche', capture: false }, + delaySeconds: 0.3, + suppressSeconds: 1, + response: (data, _matches, output) => { + // cactbot-builtin-response + output.responseOutputStrings = { + tankCleaveOnYou: Outputs.tankCleaveOnYou, + tankCleaves: Outputs.avoidTankCleaves, + }; + + if (data.tankbusters.includes(data.me)) + return { alertText: output.tankCleaveOnYou!() }; + return { infoText: output.tankCleaves!() }; + }, + run: (data) => data.tankbusters = [], + }, + { + id: 'Sandoria Second Walk Ealdnarche Cronos Sling Out + Right', + type: 'StartsUsing', + netRegex: { id: 'AD49', source: 'Eald\'narche', capture: false }, + alertText: (_data, _matches, output) => output.text!(), + outputStrings: { + text: { + en: 'Out => Right', + }, + }, + }, + { + id: 'Sandoria Second Walk Ealdnarche Cronos Sling Out + Left', + type: 'StartsUsing', + netRegex: { id: 'AD4A', source: 'Eald\'narche', capture: false }, + alertText: (_data, _matches, output) => output.text!(), + outputStrings: { + text: { + en: 'Out => Left', + }, + }, + }, + { + id: 'Sandoria Second Walk Ealdnarche Cronos Sling In + Right', + type: 'StartsUsing', + netRegex: { id: 'AD4B', source: 'Eald\'narche', capture: false }, + alertText: (_data, _matches, output) => output.text!(), + outputStrings: { + text: { + en: 'In => Right', + }, + }, + }, + { + id: 'Sandoria Second Walk Ealdnarche Cronos Sling In + Left', + type: 'StartsUsing', + netRegex: { id: 'AD4C', source: 'Eald\'narche', capture: false }, + alertText: (_data, _matches, output) => output.text!(), + outputStrings: { + text: { + en: 'In => Left', + }, + }, + }, + { + id: 'Sandoria Second Walk Ealdnarche Warp', + type: 'StartsUsing', + netRegex: { id: 'AD56', source: 'Eald\'narche', capture: false }, + alertText: (_data, _matches, output) => output.text!(), + outputStrings: { + text: { + en: 'Follow Warp => Get Behind', + }, + }, + }, + { + id: 'Sandoria Second Walk Ealdnarche Empyreal Vortex', + type: 'StartsUsing', + netRegex: { id: 'AD6D', source: 'Eald\'narche', capture: false }, + infoText: (_data, _matches, output) => output.text!(), + outputStrings: { + text: { + en: 'AoE x5', + }, + }, + }, + ], + timelineReplace: [], +}; + +export default triggerSet; diff --git a/ui/raidboss/data/07-dt/alliance/san-doria-second-walk.txt b/ui/raidboss/data/07-dt/alliance/san-doria-second-walk.txt new file mode 100644 index 00000000000..7be1eaaf761 --- /dev/null +++ b/ui/raidboss/data/07-dt/alliance/san-doria-second-walk.txt @@ -0,0 +1,685 @@ +### SAN D'ORIA: THE SECOND WALK +# ZoneId: 1304 + +hideall "--Reset--" +hideall "--sync--" + +0.0 "--Reset--" ActorControl { command: "4000000F" } window 0,1000000 jump 0 + +# .*is no longer sealed +0.0 "--Reset--" SystemLogMessage { id: "7DE" } window 0,1000000 jump 0 + +#~~~~~~~~~~~~~~~~~~# +# Faithbound Kirin # +#~~~~~~~~~~~~~~~~~~# + +# -ic "Alxaal" +# -ii ADCD + +# The Highland Battlefield will be sealed off +10000.0 "--sync--" SystemLogMessage { id: "7DC", param1: "148C" } window 10000,1 +10007.2 "--sync--" StartsUsing { id: "ADCA", source: "Faithbound Kirin" } window 10007.4,10 +10012.1 "Stonega IV" Ability { id: "ADCA", source: "Faithbound Kirin" } + +# Wrought Arms 1 (Tutorial) +10022.8 "Wrought Arms" Ability { id: "AD91", source: "Faithbound Kirin" } +10033.7 "Synchronized Strike" Ability { id: "AD95", source: "Faithbound Kirin" } +10034.4 "--sync--" Ability { id: "AD96", source: "Faithbound Kirin" } +10038.8 "Synchronized Smite" Ability { id: ["AD9B", "AD9C"], source: "Sculpted Arm" } +10045.8 "Synchronized Strike" Ability { id: "AD95", source: "Faithbound Kirin" } +10046.5 "--sync--" Ability { id: "AD96", source: "Faithbound Kirin" } +10050.9 "Synchronized Smite" Ability { id: ["AD9B", "AD9C"], source: "Sculpted Arm" } +10061.7 "Crimson Riddle" Ability { id: ["AFF4", "AFF5"], source: "Faithbound Kirin" } +10068.8 "Crimson Riddle" Ability { id: ["AFF4", "AFF5"], source: "Faithbound Kirin" } + +# Shijin Summoning +# +# The Combatants get added at the start of the fight, so we can't sync to +# the AddedCombatant line. Additionally, the summons do not appear to "cast" +# actions, so we can't sync to the first cast ability they use. +10083.0 "Summon Shijin" Ability { id: "AD7E", source: "Faithbound Kirin" } +10085.0 "--sync--" GameLog { code: "0044", line: "O Suzaku, conjure your infernal flames!" } jump "kirin-shijin-suzaku" +10085.0 "--sync--" GameLog { code: "0044", line: "O Genbu, entomb in rock and earth!" } jump "kirin-shijin-genbu" + +# Sunbound Suzaku +11000.0 label "kirin-shijin-suzaku" +11007.2 "Sun Powder" Ability { id: "AD89", source: "Sunbound Suzaku" } +11015.2 "Vermilion Flight" Ability { id: "AD8A", source: "Sunbound Suzaku" } +11018.3 "Arm of Purgatory" #Ability { id: "AEFC", source: "Ball of Fire" } +11018.3 "Arm of Purgatory" #Ability { id: "AEFC", source: "Ball of Fire" } +11018.7 "Vermilion Flight" Ability { id: "AEFB", source: "Sunbound Suzaku" } +11018.7 "Arm of Purgatory" Ability { id: "AEFA", source: "Sunbound Suzaku" } +11022.6 "Sun Powder" Ability { id: "AD89", source: "Sunbound Suzaku" } +11030.3 "Stonega III" Ability { id: "B079", source: "Faithbound Kirin" } +11030.5 "Vermilion Flight" Ability { id: "AD8A", source: "Sunbound Suzaku" } +11033.6 "Arm of Purgatory" Ability { id: "AEFC", source: "Ball of Fire" } +11033.9 "Vermilion Flight" Ability { id: "AEFB", source: "Sunbound Suzaku" } +11033.9 "Arm of Purgatory" Ability { id: "AEFA", source: "Sunbound Suzaku" } +11038.1 "Stonega III" Ability { id: "B07A", source: "Faithbound Kirin" } +11044.2 "--sync--" StartsUsing { id: "AD91", source: "Faithbound Kirin" } window 10,10 forcejump "kirin-wrought-arms-2" + +# Dawnbound Seiryu +12000.0 label "kirin-shijin-seiryu" + +# Moonbound Genbu +13000.0 label "kirin-shijin-genbu" +13010.2 "Shattering Stomp" Ability { id: "AD84", source: "Moonbound Genbu" } +13020.4 "Moontide Font" Ability { id: "AD86", source: "Moonbound Genbu" } +13025.4 "Moontide Font" Ability { id: "AD86", source: "Moonbound Genbu" } +13030.2 "Midwinter March" Ability { id: "AD87", source: "Moonbound Genbu" } +13031.2 "--sync--" Ability { id: "AD31", source: "Moonbound Genbu" } +13036.3 "Northern Current" Ability { id: "AD88", source: "Moonbound Genbu" } +13041.6 "Crimson Riddle" Ability { id: ["AFF4", "AFF5"], source: "Faithbound Kirin" } +13049.0 "--sync--" StartsUsing { id: "AD91", source: "Faithbound Kirin" } window 10,10 forcejump "kirin-wrought-arms-2" + +# Duskbound Byakko +14000.0 label "kirin-shijin-byakko" + +# Wrought Arms 2 +15000.0 label "kirin-wrought-arms-2" +15000.0 "--sync---" StartsUsing { id: "AD91", source: "Faithbound Kirin" } window 3950,1 +15003.3 "Wrought Arms" Ability { id: "AD91", source: "Faithbound Kirin" } +15011.7 "Wringer" Ability { id: "AD92", source: "Faithbound Kirin" } +15016.7 "Dead Wringer" Ability { id: ["AD97", "AD98"], source: "Sculpted Arm" } +15026.3 "Striking Left/Striking Right" Ability { id: ["AD93", "AD94"], source: "Faithbound Kirin" } +15031.3 "Smiting Left/Right" Ability { id: ["AD99", "AD9A"], source: "Sculpted Arm" } +15036.5 "Stonega IV" Ability { id: "ADCA", source: "Faithbound Kirin" } + +# The boss and hands will do an extremely large number of possible sequences +# which are difficult to split into separate timeline segments, due to the +# sheer number of combinations and overlap between casts. The timeline +# matching doesn't handle this very well. Instead, just show a duration +# line with an estimated length... +15042.3 "--synchronized sequence--" duration 20 + +# Adds Phase +15500.0 label "kirin-chiseled-arms" +15500.0 "--sync--" StartsUsing { id: "ADB1", source: "Faithbound Kirin" } window 500,1 +15506.9 "Mighty Grip" Ability { id: "ADB1", source: "Faithbound Kirin" } +15517.7 "Shockwave" Ability { id: "ADC0", source: "Chiseled Arm" } +15526.7 "Shockwave" Ability { id: "ADC0", source: "Chiseled Arm" } +15527.7 "Deadly Hold" Ability { id: "ADB2", source: "Faithbound Kirin" } +15535.9 "--sync--" Ability { id: "ADB4", source: "Faithbound Kirin" } +# Both Chiseled Arms must be destroyed before this cast finishes +15539.1 "Kirin Captivator" StartsUsing { id: "ADB3", source: "Faithbound Kirin" } duration 29.7 +15541.1 "Shockwave" Ability { id: "ADC0", source: "Chiseled Arm" } +15550.1 "Shockwave" Ability { id: "ADC0", source: "Chiseled Arm" } + +# TODO: +# Can we sync to the enrage canceling or adds dying? +16000.0 label "kirin-wrought-arms-3" +16000.0 "--sync--" StartsUsing { id: "AD91", source: "Faithbound Kirin" } window 395,1 +16003.5 "Wrought Arms" Ability { id: "AD91", source: "Faithbound Kirin" } + +# From this point, its extremely unclear from logs what the boss will do. It +# repeats mechanics until you kill it. Wiki says that another Shijin can be +# summoned, but I don't have logs of that. I don't know how to make a +# timeline of this... +16011.5 "--mechanics repeat...-" duration 120 +16011.5 "--goodluck!--" duration 120 + +# ALL ENCOUNTER ABILITIES +# 366 attack +# AA33 Savage Blade +# AA34 Vorpal Blade +# AA35 Spirits Within +# AC05 --sync-- +# AD7E Summon Shijin +# AD89 Sun Powder +# AD8A Vermilion Flight +# AD91 Wrought Arms +# AD92 Wringer +# AD94 Striking Left +# AD95 Synchronized Strike +# AD96 Synchronized Strike +# AD97 Dead Wringer +# AD98 Dead Wringer +# AD9A Smiting Left +# AD9B Synchronized Smite +# AD9C Synchronized Smite +# AD9F Smiting Left Sequence +# ADA0 Synchronized Sequence +# ADA1 Synchronized Sequence +# ADA2 Wringer +# ADA3 Striking Right +# ADA7 Dead Wringer +# ADA8 Dead Wringer +# ADA9 Smiting Right +# ADAD Wringer +# ADAE Striking Right +# ADAF Striking Left +# ADB0 Synchronized Strike +# ADB1 Mighty Grip +# ADB2 Deadly Hold +# ADB4 --sync-- +# ADB5 Deadly Hold +# ADB6 Deadly Hold +# ADB7 --sync-- +# ADB8 --sync-- +# ADB9 --sync-- +# ADBA --sync-- +# ADBF Bury +# ADC0 Shockwave +# ADCA Stonega IV +# ADCD --sync-- +# AEFA Arm of Purgatory +# AEFB Vermilion Flight +# AEFC Arm of Purgatory +# AF80 Deadly Hold +# AFF4 Crimson Riddle +# AFF5 Crimson Riddle +# B079 Stonega III +# B07A Stonega III +# B0FA attack + +#~~~~~~~~~~~~~~~~# +# Ultima & Omega # +#~~~~~~~~~~~~~~~~# + +# -ii AD1D AD2C AD30 +# -ic "Alxaal" + +# Armada Airship will be sealed off +20000.0 "--sync--" SystemLogMessage { id: "7DC", param1: "14B2" } window 20000,1 +20005.5 "--sync--" StartsUsing { id: "AD2B", source: "Omega, the One" } window 20005.5,10 +20011.7 "Ion Efflux" Ability { id: "AD2B", source: "Omega, the One" } +20015.5 "--sync--" Ability { id: "AD10", source: "Ultima, the Feared" } +20016.5 "Antimatter" Ability { id: "AD11", source: "Ultima, the Feared" } +20020.6 "Energy Orb" Ability { id: "AD08", source: "Ultima, the Feared" } +20028.8 "Energy Ray" Ability { id: "AD32", source: "Energy Orb" } +20031.8 "Aft-to-fore Fire/Fore-to-aft Fire" Ability { id: ["AD25", "AD27"], source: "Omega, the One" } +20032.4 "Omega Blaster" Ability { id: "AD29", source: "Omega, the One" } +20034.0 "Foreward Blaster/Aftward Blaster" Ability { id: ["AD26", "AD28"], source: "Omega, the One" } +20034.8 "Omega Blaster" Ability { id: "AD2A", source: "Omega, the One" } +20048.4 "Tractor Beam" Ability { id: "AD06", source: "Ultima, the Feared" } +20048.6 "Anti-personnel Missile" Ability { id: "B087", source: "Omega, the One" } +20048.8 "Crash" Ability { id: "AD07", source: "Ultima, the Feared" } +20048.8 "Tractor Beam" #Ability { id: "B086", source: "Ultima, the Feared" } +20053.6 "Anti-personnel Missile" Ability { id: "B088", source: "Omega, the One" } +20065.9 "Surface Missile" Ability { id: "B075", source: "Omega, the One" } +20066.9 "Surface Missile" #Ability { id: "B076", source: "Omega, the One" } +20067.9 "Energy Orb" Ability { id: "AD08", source: "Ultima, the Feared" } +20069.0 "Surface Missile" #Ability { id: "B076", source: "Omega, the One" } +20069.0 "Surface Missile" #Ability { id: "B076", source: "Omega, the One" } +20071.0 "Surface Missile" #Ability { id: "B076", source: "Omega, the One" } +20071.0 "Surface Missile" #Ability { id: "B076", source: "Omega, the One" } +20075.0 "Anti-personnel Missile" Ability { id: "B087", source: "Omega, the One" } +20076.0 "Energy Ray" Ability { id: "AD32", source: "Energy Orb" } +20080.0 "Anti-personnel Missile" #Ability { id: "B088", source: "Omega, the One" } +20080.0 "Anti-personnel Missile" #Ability { id: "B088", source: "Omega, the One" } +20083.0 "Mana Screen" Ability { id: "AD09", source: "Ultima, the Feared" } +20088.1 "Energy Orb" Ability { id: "AD08", source: "Ultima, the Feared" } +20096.3 "Energy Ray" Ability { id: "AD32", source: "Energy Orb" } +20097.1 "Energy Ray" #Ability { id: "AD0D", source: "Ultima, the Feared" } +20102.0 "Trajectory Projection" Ability { id: "AD23", source: "Omega, the One" } +20112.7 "Guided Missile" #Ability { id: "AD24", source: "Omega, the One" } +20112.7 "Guided Missile" #Ability { id: "AD24", source: "Omega, the One" } + +# Jump from the airship before it's reduced to ash! +20118.3 "Tractor Field" Ability { id: "AD12", source: "Ultima, the Feared" } +20118.7 "Tractor Field" Ability { id: "AD13", source: "Ultima, the Feared" } +20123.6 "Multi-missile" Ability { id: "AFEB", source: "Omega, the One" } +20123.6 "Citadel Siege" Ability { id: "AD14", source: "Ultima, the Feared" } +20125.4 "Multi-missile" Ability { id: "AFED", source: "Omega, the One" } +20125.5 "Multi-missile" Ability { id: "AFEC", source: "Omega, the One" } +20127.6 "Citadel Siege" Ability { id: "AD15", source: "Ultima, the Feared" } +20127.7 "Multi-missile" Ability { id: "AFEB", source: "Omega, the One" } +20128.6 "Citadel Siege" Ability { id: "AD18", source: "Ultima, the Feared" } +20129.6 "Multi-missile" Ability { id: "AFED", source: "Omega, the One" } +20129.7 "Multi-missile" Ability { id: "AFEC", source: "Omega, the One" } +20131.7 "Citadel Siege" Ability { id: "AD16", source: "Ultima, the Feared" } +20132.0 "Multi-missile" Ability { id: "AFEB", source: "Omega, the One" } +20132.7 "Citadel Siege" Ability { id: "AD18", source: "Ultima, the Feared" } +20133.9 "Multi-missile" Ability { id: "AFED", source: "Omega, the One" } +20134.0 "Multi-missile" Ability { id: "AFEC", source: "Omega, the One" } +20135.7 "Citadel Siege" Ability { id: "AD17", source: "Ultima, the Feared" } +20136.3 "Multi-missile" Ability { id: "AFEB", source: "Omega, the One" } +20136.7 "Citadel Siege" Ability { id: "AD18", source: "Ultima, the Feared" } +20138.1 "Multi-missile" Ability { id: "AFED", source: "Omega, the One" } +20138.2 "Multi-missile" #Ability { id: "AFEC", source: "Omega, the One" } +20138.2 "Multi-missile" #Ability { id: "AFEC", source: "Omega, the One" } +20140.6 "Citadel Siege" Ability { id: "AD18", source: "Ultima, the Feared" } +20152.7 "Citadel Buster" Ability { id: "AD1B", source: "Ultima, the Feared" } +20158.6 "Hyper Pulse" Ability { id: "AD2F", source: "Omega, the One" } + +# Phase 2 +20175.8 label "ultima-omega-p2-loop" +20175.8 "Tractor Beam" Ability { id: "AD06", source: "Ultima, the Feared" } +20176.2 "Crash" Ability { id: "AD07", source: "Ultima, the Feared" } +20176.2 "Tractor Beam" #Ability { id: "B086", source: "Ultima, the Feared" } +20176.4 "Trajectory Projection" Ability { id: "AD23", source: "Omega, the One" } +20187.0 "Mana Screen" Ability { id: "AD09", source: "Ultima, the Feared" } +20187.1 "Guided Missile" #Ability { id: "AD24", source: "Omega, the One" } +20192.1 "Energy Orb" Ability { id: "AD08", source: "Ultima, the Feared" } +20200.3 "Energy Ray" Ability { id: "AD32", source: "Energy Orb" } +20201.1 "Energy Ray" #Ability { id: "AD0C", source: "Ultima, the Feared" } +20201.4 "Anti-personnel Missile" Ability { id: "B087", source: "Omega, the One" } +20201.6 "Energy Ray" Ability { id: "AD0B", source: "Ultima, the Feared" } +20206.4 "Anti-personnel Missile" Ability { id: "B088", source: "Omega, the One" } +20214.9 "Chemical Bomb" Ability { id: "AD0E", source: "Ultima, the Feared" } +20215.5 "Chemical Bomb" Ability { id: "AD0F", source: "Ultima, the Feared" } +20218.5 "Chemical Bomb" Ability { id: "AD0F", source: "Ultima, the Feared" } +20221.5 "Chemical Bomb" Ability { id: "AD0F", source: "Ultima, the Feared" } +20224.5 "Chemical Bomb" Ability { id: "AD0F", source: "Ultima, the Feared" } +20233.2 "Surface Missile" Ability { id: "B075", source: "Omega, the One" } +20234.2 "Surface Missile" #Ability { id: "B076", source: "Omega, the One" } +20236.2 "Energy Orb" Ability { id: "AD08", source: "Ultima, the Feared" } +20236.2 "Surface Missile" #Ability { id: "B076", source: "Omega, the One" } +20236.2 "Surface Missile" #Ability { id: "B076", source: "Omega, the One" } +20238.2 "Surface Missile" #Ability { id: "B076", source: "Omega, the One" } +20238.2 "Surface Missile" #Ability { id: "B076", source: "Omega, the One" } +20244.0 "Aft-to-fore Fire/Fore-to-aft Fire" Ability { id: ["AD25", "AD27"], source: "Omega, the One" } +20244.3 "Energy Ray" Ability { id: "AD32", source: "Energy Orb" } +20244.4 "Omega Blaster" Ability { id: "AD29", source: "Omega, the One" } +20246.1 "Foreward Blaster/Aftward Blaster" Ability { id: ["AD26", "AD28"], source: "Omega, the One" } +20246.9 "Omega Blaster" Ability { id: "AD2A", source: "Omega, the One" } +20262.9 "Ion Efflux" Ability { id: "AD2B", source: "Omega, the One" } +20274.6 "Antimatter" Ability { id: "AD10", source: "Ultima, the Feared" } +20275.6 "Antimatter" Ability { id: "AD11", source: "Ultima, the Feared" } +20293.6 "Tractor Beam" Ability { id: "AD06", source: "Ultima, the Feared" } window 30,30 forcejump "ultima-omega-p2-loop" +20342.5 "Chemical Bomb" Ability { id: "AD0F", source: "Ultima, the Feared" } + +# IGNORED ABILITIES +# AD1D --sync-- +# AD2C --sync-- +# AD30 Energizing Equilibrium + +# ALL ENCOUNTER ABILITIES +# AD06 Tractor Beam +# AD07 Crash +# AD08 Energy Orb +# AD09 Mana Screen +# AD0B Energy Ray +# AD0C Energy Ray +# AD0D Energy Ray +# AD0E Chemical Bomb +# AD0F Chemical Bomb +# AD10 Antimatter +# AD11 Antimatter +# AD12 Tractor Field +# AD13 Tractor Field +# AD14 Citadel Siege +# AD15 Citadel Siege +# AD16 Citadel Siege +# AD17 Citadel Siege +# AD18 Citadel Siege +# AD1B Citadel Buster +# AD1C Energizing Equilibrium +# AD1D --sync-- +# AD23 Trajectory Projection +# AD24 Guided Missile +# AD25 Fore-to-aft Fire +# AD26 Foreward Blaster +# AD27 Aft-to-fore Fire +# AD28 Aftward Blaster +# AD29 Omega Blaster +# AD2A Omega Blaster +# AD2B Ion Efflux +# AD2C --sync-- +# AD2F Hyper Pulse +# AD30 Energizing Equilibrium +# AD32 Energy Ray +# AFEB Multi-missile +# AFEC Multi-missile +# AFED Multi-missile +# B075 Surface Missile +# B076 Surface Missile +# B086 Tractor Beam +# B087 Anti-personnel Missile +# B088 Anti-personnel Missile +# B0FC attack + +#~~~~~~~~~~~~~~~~~# +# Stellar Fulcrum # +#~~~~~~~~~~~~~~~~~# + +# The Stellar Fulcrum will be sealed off +30000.0 "--sync--" SystemLogMessage { id: "7DC", param1: "1488" } window 30000,1 +30006.4 "--sync--" StartsUsing { id: "ACBD", source: "Kam'lanaut" } window 30006.4,1 +30011.1 "Enspirited Swordplay" Ability { id: "ACBD", source: "Kam'lanaut" } +30014.3 "--sync--" Ability { id: "ACC1", source: "Kam'lanaut" } +30019.4 "Proving Ground" Ability { id: "B009", source: "Kam'lanaut" } +# TODO: Add sync for elemental buffs? +30032.5 "Elemental Blade" Ability { id: "AC91", source: "Kam'lanaut" } +30043.6 "Sublime Elements" Ability { id: "B00A", source: "Kam'lanaut" } +# TODO: condense sublime elements, based on which of these is "real" +# TODO: verify if the two variants of Sublime Elements can appear in +# different order +30044.6 "Sublime Earth" #Ability { id: "AC94", source: "Kam'lanaut" } +30044.6 "Sublime Fire" #Ability { id: "AC93", source: "Kam'lanaut" } +30044.6 "Sublime Ice" #Ability { id: "AC9C", source: "Kam'lanaut" } +30044.6 "Sublime Lightning" #Ability { id: "AC97", source: "Kam'lanaut" } +30044.6 "Sublime Water" #Ability { id: "AC9B", source: "Kam'lanaut" } +30044.6 "Sublime Wind" #Ability { id: "AC98", source: "Kam'lanaut" } +30054.7 "Elemental Blade" Ability { id: "AC91", source: "Kam'lanaut" } +30065.8 "Sublime Elements" Ability { id: "B00A", source: "Kam'lanaut" } +30066.8 "Earth Blade" #Ability { id: "ACA0", source: "Kam'lanaut" } +30066.8 "Fire Blade" #Ability { id: "AC9F", source: "Kam'lanaut" } +30066.8 "Ice Blade" #Ability { id: "ACA8", source: "Kam'lanaut" } +30066.8 "Lightning Blade" #Ability { id: "ACA9", source: "Kam'lanaut" } +30066.8 "Water Blade" #Ability { id: "ACA1", source: "Kam'lanaut" } +30066.8 "Wind Blade" #Ability { id: "ACA4", source: "Kam'lanaut" } +# TODO: Check which ablity hurts? +30076.1 "--sync--" Ability { id: "ACBB", source: "Kam'lanaut" } +30077.1 "Princely Blow" Ability { id: "ACBC", source: "Kam'lanaut" } +30082.2 "Light Blade" Ability { id: "ACAB", source: "Kam'lanaut" } +30088.2 "Sublime Estoc" #Ability { id: "ACAC", source: "Sublime Estoc" } +30088.2 "Sublime Estoc" #Ability { id: "ACAC", source: "Sublime Estoc" } +30091.3 "Great Wheel" Ability { id: ["ACAF", "ACB0"], source: "Kam'lanaut" } +30097.2 "Great Wheel" Ability { id: "ACB1", source: "Kam'lanaut" } +30104.4 "Enspirited Swordplay" Ability { id: "ACBD", source: "Kam'lanaut" } +30111.5 "--sync--" Ability { id: "ACC1", source: "Kam'lanaut" } + +# Phase Transition +# TODO: Add --untargettable--?? and maybe a duration? +30124.8 "Esoteric Scrivening" Ability { id: "ACB2", source: "Kam'lanaut" } +30129.9 "--sync--" Ability { id: "AD79", source: "Kam'lanaut" } +30143.0 "--sync--" Ability { id: "AD7A", source: "Kam'lanaut" } +30148.2 "Shockwave" Ability { id: "ACB3", source: "Kam'lanaut" } +30148.2 "--sync--" Ability { id: "A2FF", source: "Kam'lanaut" } +30156.8 "Transcendent Union" Ability { id: "ACB4", source: "Kam'lanaut" } +30157.8 "Elemental Edge" #Ability { id: "AD01", source: "Kam'lanaut" } +30158.1 "Elemental Edge" #Ability { id: "AD01", source: "Kam'lanaut" } +30158.4 "Elemental Edge" #Ability { id: "AD01", source: "Kam'lanaut" } +30158.8 "Elemental Edge" #Ability { id: "AD01", source: "Kam'lanaut" } +30159.2 "Elemental Edge" #Ability { id: "AD01", source: "Kam'lanaut" } +30159.9 "Elemental Edge" #Ability { id: "AD01", source: "Kam'lanaut" } +30163.2 "Transcendent Union" Ability { id: "ACB5", source: "Kam'lanaut" } +30174.0 "--sync--" Ability { id: "ACC1", source: "Kam'lanaut" } + +# Phase 2 +30179.2 "Esoteric Palisade" Ability { id: "ACB6", source: "Kam'lanaut" } +30185.3 "Crystalline Resonance" Ability { id: "ACB7", source: "Kam'lanaut" } +30193.2 "Elemental Resonance" Ability { id: "ACB8", source: "Kam'lanaut" } +30200.2 "Elemental Resonance" Ability { id: "ACB8", source: "Kam'lanaut" } +30207.2 "Elemental Resonance" Ability { id: "ACB8", source: "Kam'lanaut" } +30207.4 "Illumed Facet" Ability { id: "ACB9", source: "Kam'lanaut" } +30207.4 "Empyreal Banish III" #Ability { id: "ACBF", source: "Kam'lanaut" } +30218.4 "Illumed Estoc" Ability { id: "ACBA", source: "Kam'lanaut" } +30225.7 "Shield Bash" Ability { id: "ACBE", source: "Kam'lanaut" } +# TODO: check which of these matters +30234.8 "Empyreal Banish IV" Ability { id: "AF6B", source: "Kam'lanaut" } +30235.8 "Empyreal Banish IV" Ability { id: "ACC0", source: "Kam'lanaut" } +30245.1 "--sync--" Ability { id: "ACBB", source: "Kam'lanaut" } +30246.1 "Princely Blow" Ability { id: "ACBC", source: "Kam'lanaut" } +30255.2 "--sync--" Ability { id: "ACC1", source: "Kam'lanaut" } +30260.3 "Proving Ground" Ability { id: "B009", source: "Kam'lanaut" } +30274.4 "Elemental Blade" Ability { id: "AC92", source: "Kam'lanaut" } +30285.5 "Sublime Elements" Ability { id: "B00A", source: "Kam'lanaut" } +30286.5 "Sublime Earth" #Ability { id: "AC94", source: "Kam'lanaut" } +30286.5 "Sublime Fire" #Ability { id: "AC99", source: "Kam'lanaut" } +30286.5 "Sublime Ice" #Ability { id: "AC9C", source: "Kam'lanaut" } +30286.5 "Sublime Lightning" #Ability { id: "AC9D", source: "Kam'lanaut" } +30286.5 "Sublime Water" #Ability { id: "AC95", source: "Kam'lanaut" } +30286.5 "Sublime Wind" #Ability { id: "AC98", source: "Kam'lanaut" } +30292.6 "Light Blade" Ability { id: "ACAB", source: "Kam'lanaut" } +30298.6 "Sublime Estoc" #Ability { id: "ACAC", source: "Sublime Estoc" } +30298.6 "Sublime Estoc" #Ability { id: "ACAC", source: "Sublime Estoc" } +30298.6 "Empyreal Banish III" Ability { id: "ACBF", source: "Kam'lanaut" } +30301.7 "Great Wheel" Ability { id: ["ACAD", "ACAE", "ACAF", "ACB0"], source: "Kam'lanaut" } +30307.6 "Great Wheel" Ability { id: "ACB1", source: "Kam'lanaut" } +30307.7 "Empyreal Banish IV" Ability { id: "ACC0", source: "Kam'lanaut" } +30314.8 "Enspirited Swordplay" Ability { id: "ACBD", source: "Kam'lanaut" } +30322.0 "--sync--" Ability { id: "ACC1", source: "Kam'lanaut" } + +# Phase 2 Loop Start +30327.2 label "kamlanaut-loop" +30327.2 "Esoteric Palisade" Ability { id: "ACB6", source: "Kam'lanaut" } +30333.3 "Crystalline Resonance" Ability { id: "ACB7", source: "Kam'lanaut" } +30341.2 "Elemental Resonance" Ability { id: "ACB8", source: "Kam'lanaut" } +30348.2 "Elemental Resonance" Ability { id: "ACB8", source: "Kam'lanaut" } +30355.2 "Elemental Resonance" Ability { id: "ACB8", source: "Kam'lanaut" } +30358.4 "Light Blade" Ability { id: "ACAB", source: "Kam'lanaut" } +30364.4 "Sublime Estoc" #Ability { id: "ACAC", source: "Sublime Estoc" } +30364.4 "Sublime Estoc" #Ability { id: "ACAC", source: "Sublime Estoc" } +30364.4 "Empyreal Banish III" Ability { id: "ACBF", source: "Kam'lanaut" } +30371.2 "Elemental Resonance" Ability { id: "ACB8", source: "Kam'lanaut" } +30372.8 "Illumed Facet" Ability { id: "ACB9", source: "Kam'lanaut" } +30382.9 "Shield Bash" Ability { id: "ACBE", source: "Kam'lanaut" } +30383.7 "Illumed Estoc" Ability { id: "ACBA", source: "Kam'lanaut" } +30392.1 "Empyreal Banish IV" Ability { id: "AF6B", source: "Kam'lanaut" } +30393.1 "Empyreal Banish IV" Ability { id: "ACC0", source: "Kam'lanaut" } +30398.2 "Proving Ground" Ability { id: "B009", source: "Kam'lanaut" } +30412.3 "Elemental Blade" Ability { id: "AC92", source: "Kam'lanaut" } +30423.4 "Sublime Elements" Ability { id: "B00A", source: "Kam'lanaut" } +30424.4 "Earth Blade" #Ability { id: "ACA6", source: "Kam'lanaut" } +30424.4 "Fire Blade" #Ability { id: "ACA5", source: "Kam'lanaut" } +30424.4 "Ice Blade" #Ability { id: "ACA2", source: "Kam'lanaut" } +30424.4 "Lightning Blade" #Ability { id: "ACA3", source: "Kam'lanaut" } +30424.4 "Water Blade" #Ability { id: "ACA1", source: "Kam'lanaut" } +30424.4 "Wind Blade" #Ability { id: "ACAA", source: "Kam'lanaut" } +30431.5 "Enspirited Swordplay" Ability { id: "ACBD", source: "Kam'lanaut" } +30441.8 "--sync--" Ability { id: "ACBB", source: "Kam'lanaut" } +30442.8 "Princely Blow" Ability { id: "ACBC", source: "Kam'lanaut" } +30452.0 "--sync--" Ability { id: "ACC1", source: "Kam'lanaut" } +30457.1 "Proving Ground" Ability { id: "B009", source: "Kam'lanaut" } +30471.2 "Elemental Blade" Ability { id: "AC92", source: "Kam'lanaut" } +30482.3 "Sublime Elements" Ability { id: "B00A", source: "Kam'lanaut" } +30483.3 "Sublime Earth" #Ability { id: "AC94", source: "Kam'lanaut" } +30483.3 "Sublime Fire" #Ability { id: "AC99", source: "Kam'lanaut" } +30483.3 "Sublime Ice" #Ability { id: "AC9C", source: "Kam'lanaut" } +30483.3 "Sublime Lightning" #Ability { id: "AC9D", source: "Kam'lanaut" } +30483.3 "Sublime Water" #Ability { id: "AC95", source: "Kam'lanaut" } +30483.3 "Sublime Wind" #Ability { id: "AC98", source: "Kam'lanaut" } +30489.4 "Light Blade" Ability { id: "ACAB", source: "Kam'lanaut" } +30495.4 "Sublime Estoc" Ability { id: "ACAC", source: "Sublime Estoc" } +30495.4 "Empyreal Banish III" Ability { id: "ACBF", source: "Kam'lanaut" } +30498.5 "Great Wheel" Ability { id: ["ACAD", "ACAE", "ACAF", "ACB0"], source: "Kam'lanaut" } +30504.4 "Great Wheel" Ability { id: "ACB1", source: "Kam'lanaut" } +30504.5 "Empyreal Banish IV" Ability { id: "ACC0", source: "Kam'lanaut" } +30511.6 "Enspirited Swordplay" Ability { id: "ACBD", source: "Kam'lanaut" } +30518.8 "--sync--" Ability { id: "ACC1", source: "Kam'lanaut" } +30524.0 "Esoteric Palisade" Ability { id: "ACB6", source: "Kam'lanaut" } window 30,30 forcejump "kamlanaut-loop" + +# IGNORED ABILITIES +# AF4C --sync-- + +# ALL ENCOUNTER ABILITIES +# A2FF --sync-- +# AC91 Elemental Blade +# AC92 Elemental Blade +# AC93 Sublime Fire +# AC94 Sublime Earth +# AC95 Sublime Water +# AC97 Sublime Lightning +# AC98 Sublime Wind +# AC99 Sublime Fire +# AC9B Sublime Water +# AC9C Sublime Ice +# AC9D Sublime Lightning +# AC9F Fire Blade +# ACA0 Earth Blade +# ACA1 Water Blade +# ACA2 Ice Blade +# ACA3 Lightning Blade +# ACA4 Wind Blade +# ACA5 Fire Blade +# ACA6 Earth Blade +# ACA8 Ice Blade +# ACA9 Lightning Blade +# ACAA Wind Blade +# ACAB Light Blade +# ACAC Sublime Estoc +# ACAE Great Wheel +# ACAF Great Wheel +# ACB0 Great Wheel +# ACB1 Great Wheel +# ACB2 Esoteric Scrivening +# ACB3 Shockwave +# ACB4 Transcendent Union +# ACB5 Transcendent Union +# ACB6 Esoteric Palisade +# ACB7 Crystalline Resonance +# ACB8 Elemental Resonance +# ACB9 Illumed Facet +# ACBA Illumed Estoc +# ACBB Princely Blow +# ACBC Princely Blow +# ACBD Enspirited Swordplay +# ACBE Shield Bash +# ACBF Empyreal Banish III +# ACC0 Empyreal Banish IV +# ACC1 --sync-- +# AD01 Elemental Edge +# AD79 --sync-- +# AD7A --sync-- +# AF4C --sync-- +# AF6B Empyreal Banish IV +# B009 Proving Ground +# B00A Sublime Elements + +#~~~~~~~~~~~~~~~~~# +# Celestial Nexus # +#~~~~~~~~~~~~~~~~~# + +# -ii AD47 + +# Phase 1 +40000.0 "--sync--" SystemLogMessage { id: "7DC", param1: "148A" } window 40000,1 +40006.4 "--sync--" StartsUsing { id: "AD51", source: "Eald'narche" } window 40006.4,1 +40010.1 "--sync--" Ability { id: "AD51", source: "Eald'narche" } +40011.1 "Uranos Cascade" Ability { id: "AD52", source: "Eald'narche" } +40023.2 "Cronos Sling" Ability { id: ["AD49", "AD4A", "AD4B", "AD4C"], source: "Eald'narche" } +40023.6 "--sync--" Ability { id: ["AD4D", "AD4E"], source: "Eald'narche" } +40029.5 "Cronos Sling" Ability { id: ["AD4F", "AD50"], source: "Eald'narche" } +40039.8 "Empyreal Vortex" Ability { id: "AD6D", source: "Eald'narche" } duration 5.8 +40045.6 "--sync--" Ability { id: "AD70", source: "Eald'narche" } +40056.9 "Cronos Sling" Ability { id: ["AD49", "AD4A", "AD4B", "AD4C"], source: "Eald'narche" } +40057.3 "--sync--" Ability { id: ["AD4D", "AD4E"], source: "Eald'narche" } +40063.1 "Cronos Sling" Ability { id: ["AD4F", "AD50"], source: "Eald'narche" } +40070.4 "Warp" Ability { id: "AD56", source: "Eald'narche" } +40071.1 "--sync--" Ability { id: "AD48", source: "Eald'narche" } +40077.0 "Sleepga" Ability { id: "AD58", source: "Eald'narche" } +40079.1 "--sync--" Ability { id: "AD48", source: "Eald'narche" } +40084.4 "Gaea Stream" Ability { id: "AD53", source: "Eald'narche" } duration 11.1 +40090.7 "--sync--" StartsUsing { id: "AD5C", source: "Eald'narche" } window 5,5 +40094.4 "Omega Javelin" Ability { id: "AD5C", source: "Eald'narche" } +40095.5 "--sync--" Ability { id: "AD5D", source: "Eald'narche" } +40099.9 "Omega Javelin" Ability { id: "AD5E", source: "Eald'narche" } +40105.6 "Duplicate" Ability { id: "AD77", source: "Eald'narche" } duration 26.2 +40116.7 "--sync--" Ability { id: "AD78", source: "Eald'narche" } +40120.7 "--sync--" Ability { id: "AD77", source: "Eald'narche" } +40131.8 "--sync--" Ability { id: "AD78", source: "Eald'narche" } +40140.8 "--sync--" Ability { id: "AD48", source: "Eald'narche" } +40150.1 "Excelsior" Ability { id: "B040", source: "Eald'narche" } +40150.5 "--sync--" Ability { id: "AF17", source: "Eald'narche" } +40155.2 "Phase Shift" Ability { id: "AD59", source: "Eald'narche" } duration 22.2 +40155.4 "--sync--" Ability { id: "AD2E", source: "Eald'narche" } +40156.1 "--sync--" Ability { id: "AD5B", source: "Eald'narche" } +40177.4 "--sync--" Ability { id: "AD5A", source: "Eald'narche" } window 23.1,5 + +# Phase 2 Begins +40189.6 "Duplicate" Ability { id: "AD77", source: "Eald'narche" } duration 13.1 +40198.7 "Visions of Paradise" Ability { id: "AD75", source: "Eald'narche" } +40207.7 "Stellar Burst" Ability { id: "AD72", source: "Eald'narche" } +40207.7 "--sync--" Ability { id: "AD7D", source: "Eald'narche" } +40208.7 "Stellar Burst" Ability { id: "AD73", source: "Eald'narche" } +40215.4 "Stellar Burst" Ability { id: "AD74", source: "Eald'narche" } +40224.0 "--sync--" Ability { id: "AD48", source: "Eald'narche" } +# TODO: There are many variations of Ancient Triad which are not really +# worth creating branching timelines for. Just use a duration to indicate +# that mechanics are ongoing. Note that this duration likely isn't accurate +# for every variation, however the mechanics should mostly be done resolving +# by this time. +40232.3 "Ancient Triad" Ability { id: "AD5F", source: "Eald'narche" } duration 10.7 +40248.0 "Gaea Stream" Ability { id: "AD53", source: "Eald'narche" } duration 17 +40263.1 "--sync--" StartsUsing { id: "AD51", source: "Eald'narche" } window 15,5 +40266.8 "--sync--" Ability { id: "AD51", source: "Eald'narche" } +40267.8 "Uranos Cascade" Ability { id: "AD52", source: "Eald'narche" } +40273.9 "Duplicate" Ability { id: "AD77", source: "Eald'narche" } duration 13.1 +40283.0 "Visions of Paradise" Ability { id: "AD75", source: "Eald'narche" } + +# Phase 2 Loop +40292.0 label "ealdnarche-phase-2-loop" +40292.0 "Omega Javelin" Ability { id: "AD5C", source: "Eald'narche" } +40293.1 "--sync--" Ability { id: "AD5D", source: "Eald'narche" } +40295.1 "--sync--" Ability { id: "AD48", source: "Eald'narche" } +40297.5 "Omega Javelin" Ability { id: "AD5E", source: "Eald'narche" } +40300.5 "Gaea Stream" Ability { id: "AD53", source: "Eald'narche" } duration 17 +40313.5 "Cronos Sling" Ability { id: ["AD49", "AD4A", "AD4B", "AD4C"], source: "Eald'narche" } +40313.9 "--sync--" Ability { id: ["AD4D", "AD4E"], source: "Eald'narche" } +40319.6 "Cronos Sling" Ability { id: ["AD4F", "AD50"], source: "Eald'narche" } +40327.5 "Stellar Burst" Ability { id: "AD72", source: "Eald'narche" } +40327.5 "--sync--" Ability { id: "AD7D", source: "Eald'narche" } +40328.5 "Stellar Burst" Ability { id: "AD73", source: "Eald'narche" } +40335.2 "Stellar Burst" Ability { id: "AD74", source: "Eald'narche" } +40342.9 "--sync--" Ability { id: "AD48", source: "Eald'narche" } +40351.0 "Ancient Triad" Ability { id: "AD5F", source: "Eald'narche" } duration 10.7 +40359.7 "Duplicate" Ability { id: "AD77", source: "Eald'narche" } duration 13.1 +40368.9 "Visions of Paradise" Ability { id: "AD75", source: "Eald'narche" } +40373.0 "--sync--" Ability { id: "AD76", source: "Eald'narche" } +40377.0 "Empyreal Vortex" Ability { id: "AD6D", source: "Eald'narche" } duration 5.8 +40382.8 "--sync--" Ability { id: "AD70", source: "Eald'narche" } +40386.6 "Warp" Ability { id: "AD56", source: "Eald'narche" } +40387.3 "--sync--" Ability { id: "AD48", source: "Eald'narche" } +40393.2 "Sleepga" Ability { id: "AD58", source: "Eald'narche" } +40395.3 "--sync--" Ability { id: "AD48", source: "Eald'narche" } +40401.6 "Omega Javelin" Ability { id: "AD5C", source: "Eald'narche" } +40402.7 "--sync--" Ability { id: "AD5D", source: "Eald'narche" } +40407.1 "Omega Javelin" Ability { id: "AD5E", source: "Eald'narche" } +40411.7 "Cronos Sling" Ability { id: ["AD49", "AD4A", "AD4B", "AD4C"], source: "Eald'narche" } +40412.1 "--sync--" Ability { id: ["AD4D", "AD4E"], source: "Eald'narche" } +40417.9 "Cronos Sling" Ability { id: ["AD4F", "AD50"], source: "Eald'narche" } +40429.2 "--sync--" Ability { id: "AD51", source: "Eald'narche" } +40430.2 "Uranos Cascade" Ability { id: "AD52", source: "Eald'narche" } +40444.3 "Duplicate" Ability { id: "AD77", source: "Eald'narche" } duration 13.1 +40453.4 "Visions of Paradise" Ability { id: "AD75", source: "Eald'narche" } +40457.5 "--sync--" Ability { id: "AD76", source: "Eald'narche" } +40462.5 "Omega Javelin" Ability { id: "AD5C", source: "Eald'narche" } forcejump "ealdnarche-phase-2-loop" + +# IGNORED ABILITIES +# AD47 --sync-- + +# ALL ENCOUNTER ABILITIES +# AD2E Phase Shift +# AD35 Tornado +# AD47 --sync-- +# AD48 --sync-- +# AD49 Cronos Sling +# AD4B Cronos Sling +# AD4C Cronos Sling +# AD4D Cronos Sling +# AD4E Cronos Sling +# AD4F Cronos Sling +# AD50 Cronos Sling +# AD51 Uranos Cascade +# AD52 Uranos Cascade +# AD53 Gaea Stream +# AD54 Gaea Stream +# AD55 Gaea Stream +# AD56 Warp +# AD57 --sync-- +# AD58 Sleepga +# AD59 Phase Shift +# AD5A Phase Shift +# AD5B --sync-- +# AD5C Omega Javelin +# AD5D Omega Javelin +# AD5E Omega Javelin +# AD5F Ancient Triad +# AD60 Flare +# AD61 Flare +# AD64 Quake +# AD65 Freeze +# AD66 Flood +# AD67 Flood +# AD68 Flood +# AD69 Flood +# AD6A Flood +# AD6B Tornado +# AD6C Tornado +# AD6D Empyreal Vortex +# AD6E Empyreal Vortex +# AD6F Empyreal Vortex +# AD70 Empyreal Vortex +# AD71 Empyreal Vortex +# AD72 Stellar Burst +# AD73 Stellar Burst +# AD74 Stellar Burst +# AD75 Visions of Paradise +# AD76 Duplicate +# AD77 Duplicate +# AD78 Duplicate +# AD7D --sync-- +# AF17 --sync-- +# B040 Excelsior From 77babd8f1786983227bb4fb54f2750352bfb2fdb Mon Sep 17 00:00:00 2001 From: Harbinger Date: Wed, 6 May 2026 23:28:59 -0700 Subject: [PATCH 2/6] raidboss: add additional triggers for San d'Oria Replace most of the triggers for San d'Oria with improved versions, which have better callouts, including many additions to Faithbound Kirin, Ultima and Omega, and Kam'lanaut. Co-authored-by: Jacob Keller --- .../07-dt/alliance/san-doria-second-walk.ts | 1335 ++++++++++++++--- 1 file changed, 1157 insertions(+), 178 deletions(-) diff --git a/ui/raidboss/data/07-dt/alliance/san-doria-second-walk.ts b/ui/raidboss/data/07-dt/alliance/san-doria-second-walk.ts index 5a9dd20f6b3..b591c7e1188 100644 --- a/ui/raidboss/data/07-dt/alliance/san-doria-second-walk.ts +++ b/ui/raidboss/data/07-dt/alliance/san-doria-second-walk.ts @@ -1,306 +1,1275 @@ +import Conditions from '../../../../../resources/conditions'; +import { UnreachableCode } from '../../../../../resources/not_reached'; import Outputs from '../../../../../resources/outputs'; +import { callOverlayHandler } from '../../../../../resources/overlay_plugin_api'; import { Responses } from '../../../../../resources/responses'; +import { DirectionOutput8, Directions } from '../../../../../resources/util'; import ZoneId from '../../../../../resources/zone_id'; import { RaidbossData } from '../../../../../types/data'; -import { TriggerSet } from '../../../../../types/trigger'; +import { PluginCombatantState } from '../../../../../types/event'; +import { Matches } from '../../../../../types/net_matches'; +import type { LocaleText, Output, TriggerSet } from '../../../../../types/trigger'; -const effectB9AMap = { - '3AC': 'fire', - '3AD': 'earth', - '3AE': 'water', - '3AF': 'ice', - '3B0': 'thunder', - '3B1': 'wind', -} as const; +type KirinSequenceStep = + | 'out' + | 'under' + | 'sides' + | 'awayBossArms' + | 'awayBoss' + | 'awayArms' + | 'awayTethered' + | 'flank'; // | 'dodge' + +type KamSixDirection = 'dirN' | 'dirNE' | 'dirSE' | 'dirS' | 'dirSW' | 'dirNW'; -type B9AMapKeys = keyof typeof effectB9AMap; -type B9AMapValues = typeof effectB9AMap[B9AMapKeys] | 'unknown'; +type KamElement = 'fire' | 'earth' | 'water' | 'ice' | 'lightning' | 'wind'; -const isEffectB9AKey = (key: string | undefined): key is B9AMapKeys => { - if (key === undefined) - return false; - return Object.keys(effectB9AMap).includes(key); +type KamBlade = { + x: number; + y: number; + // heading: number; }; +const kirinCenter = [-850.00, 780.00]; -const b9aValueToElement = ( - id: string | undefined, -): B9AMapValues | 'unknown' => { - if (isEffectB9AKey(id)) - return effectB9AMap[id]; - return 'unknown'; +const kirinSequenceOutputStrings = { + out: Outputs.out, + under: Outputs.getUnder, + sides: Outputs.sides, + awayBossArms: { + en: 'Away from boss & arms', + }, + awayBoss: { + en: 'Away from boss', + }, + awayArms: { + en: 'Away from Arms (on boss hitbox)', + }, + awayTethered: { + en: 'Away from tethered arm (${dir})', + }, + flank: { + en: 'Max melee on flank', + }, + // dodge: { + // en: 'Dodge' + // }, + next: Outputs.next, + east: Outputs.east, + west: Outputs.west, }; -const elementOutputStrings = { +const kamlanautElementalOutputStrings: { [key in KamElement]: LocaleText } = { fire: { en: 'Fire', }, - earth: { - en: 'Earth', - }, water: { en: 'Water', }, - ice: { - en: 'Ice', - }, - thunder: { - en: 'Thunder', - }, wind: { en: 'Wind', }, - separator: { - en: '/', + earth: { + en: 'Earth', + }, + lightning: { + en: 'Lightning', }, - combo: { - en: 'Away from ${elements}', + ice: { + en: 'Ice', }, }; +const kamSixDirections = [ + 'dirSE', + 'dirS', + 'dirSW', + 'dirNW', + 'dirN', + 'dirNE', +]; + +const kamlanautElementBuffIds: { [key: string]: KamElement } = { + '3AC': 'fire', + '3AD': 'earth', + '3AE': 'water', + '3AF': 'ice', + '3B0': 'lightning', + '3B1': 'wind', +}; + +const kamlanautSublimeConeCasts: { [key: string]: KamElement } = { + 'AC93': 'fire', + 'AC94': 'earth', + 'AC95': 'water', + 'AC96': 'ice', + 'AC97': 'lightning', + 'AC98': 'wind', + // ## aoes that expand + 'AC99': 'fire', + 'AC9A': 'earth', + 'AC9B': 'water', + 'AC9C': 'ice', + 'AC9D': 'lightning', + 'AC9E': 'wind', +}; +const kamlanautSublimeBladeCasts: { [key: string]: KamElement } = { + 'AC9F': 'fire', + 'ACA0': 'earth', + 'ACA1': 'water', + 'ACA2': 'ice', + 'ACA3': 'lightning', + 'ACA4': 'wind', + // ## aoes that expand + 'ACA5': 'fire', + 'ACA6': 'earth', + 'ACA7': 'water', + 'ACA8': 'ice', + 'ACA9': 'lightning', + 'ACAA': 'wind', +}; + +const kamlanautCrystalNpcIds: { [key: string]: KamElement } = { + '1EBE84': 'fire', + '1EBE85': 'water', + '1EBE86': 'wind', + '1EBE87': 'earth', + '1EBE88': 'ice', + '1EBE89': 'lightning', +}; + +const kirinSequenceInfoOutput = ( + sequence: KirinSequenceStep[], + ability: string[], + direction?: 'east' | 'west', +) => { + return (data: Data, _matches: Matches, output: Output) => { + data.kirinSequencedSafeCallouts = {}; + const items: string[] = []; + sequence.forEach((step, index) => { + const key = ability[index]; + if (key !== undefined) { + const call = step === 'awayTethered' + ? output[step]!({ dir: output[direction!]!() }) + : output[step]!(); + data.kirinSequencedSafeCallouts[key] = call; + items.push(call); + // console.info(`${index} - ${key} => ${call}`); + } + }); + data.kirinSequenceCalls = items.length - 1; + // console.table(data.kirinSequencedSafeCallouts); + const result = items.join(output.next!()); + console.log(result); + return result; + // return { infoText: result }; + }; +}; + +const floatNear = (n1: number, n2: number, epsilon = 0.1) => { + return Math.abs(n1 - n2) < epsilon; +}; + +const isValidSiXDir = (dir: DirectionOutput8 | undefined): dir is KamSixDirection => { + return kamSixDirections.includes(dir!); +}; + +const emptySixDirections = () => { + return { + dirSE: undefined, + dirS: undefined, + dirSW: undefined, + dirNW: undefined, + dirN: undefined, + dirNE: undefined, + }; +}; + +type OrbLocation = 'north' | 'middle' | 'south'; + +const sublimeElementsBladeSafespot = ( + blades: { [p: string]: KamBlade }, + elements: KamElement[], +) => { + const cols: Record = { [-220]: null, [-200]: null, [-180]: null }; + const rows: Record = { 130: null, 150: null, 170: null }; + + for (const [ele, pos] of Object.entries(blades)) { + const x = Number(pos.x); + const y = Number(pos.y); + const val = elements.includes(ele as KamElement) ? 'BAD' : ele; + if (floatNear(y, 110, 0.5)) { + cols[x] = val; + } else { + rows[y] = val; + } + } + + const validCols = Object.values(cols).filter((v) => (v !== null) && v !== 'BAD') as string[]; + const validRows = Object.values(rows).filter((v) => (v !== null) && v !== 'BAD') as string[]; + + if (!(validCols.length >= 1 || validRows.length >= 1)) { + throw new Error('Invalid blade configuration'); + } + + const result: string[] = []; + if (validCols.length === 1) { + result.push(validCols[0]!); + if (validRows.length < 3) + result.push(validRows[0]!); + } else if (validRows.length === 1) { + result.push(validRows[0]!); + if (validCols.length < 3) + result.push(validCols[0]!); + } + + return result; +}; + +const OmegaManaScreenPatterns: { [key: string]: { [key in OrbLocation]?: string } } = { + 'ceB,nwC,seB': { middle: 'frontRight' }, + 'ceC,nwB,seC': { south: 'backLeft' }, + 'ceC,nwB,swC': { south: 'frontMiddle' }, + 'cwC,neB,seB': { north: 'backMiddle' }, + 'cwC,nwB,seB': { north: 'frontRight', middle: 'frontRight' }, +}; + export interface Data extends RaidbossData { - expectedElements: 0 | 2 | 3; - storedElements: B9AMapValues[]; - tankbusters: string[]; + tankbusterTargets: string[]; + combatantData: PluginCombatantState[]; + kirinSequencedSafeCallouts: { [key: string]: string }; + kirinSequenceCalls: number; + omegaOrbs: OrbLocation[]; + omegaManaScreens: string[]; + kamElements: KamElement[]; + kamElementalCones: Record; + kamElementalBlades: { [key: string]: KamBlade }; + kamEstocHeadings: number[]; + kamCrystalLocations: { [key: string]: KamElement }; + kamCrystalCasts: KamSixDirection[]; } -// TODO: -// Kirin -// Shijin mechanics -// Wrought Arms -// Synchronized Strike?? -// -// Ultima & Omega -// ??? -// -// Kam'lanaut -// Princely Blow Tank Buster + knockback -// Sublime Elements full solve -// Illumed Facet solve -// Illumed Facet + Shield Bash solve? -// -// Eald'narche -// Spread markers for Empyeal Vortex -// Spread + Follow ups from Omega Javelin -// duplicate/visions of paradise solve? -// Ancient Triad mechanics? -// Finish Cronos Sling - const triggerSet: TriggerSet = { id: 'San d\'Oria: The Second Walk', zoneId: ZoneId.SanDoriaTheSecondWalk, timelineFile: 'san-doria-second-walk.txt', - initData: () => ({ - expectedElements: 0, - storedElements: [], - tankbusters: [], - }), + initData: () => { + return { + tankbusterTargets: [], + combatantData: [], + kirinSequencedSafeCallouts: {}, + kirinSequenceCalls: 0, + omegaOrbs: [], + omegaManaScreens: [], + kamElements: [], + kamElementalCones: emptySixDirections(), + kamElementalBlades: {}, + kamEstocHeadings: [], + kamCrystalLocations: {}, + kamCrystalCasts: [], + }; + }, triggers: [ + // ---------------------- + // Faithbound Kirin { - id: 'Sandoria Second Walk Kirin Stonega IV', + id: 'San dOria Second Walk Faithbound Kirin Stonega IV', type: 'StartsUsing', - netRegex: { id: 'AD2B', source: 'Faithbound Kirin', capture: false }, + netRegex: { id: 'ADCA', source: 'Faithbound Kirin', capture: false }, response: Responses.aoe(), }, { - id: 'Sandoria Second Walk Kirin Crimson Riddle Breath', + id: 'San dOria Second Walk Faithbound Kirin Crimson Riddle Front', type: 'StartsUsing', - netRegex: { id: 'AFF4', source: 'Faithbound Kirin', capture: false }, + netRegex: { id: ['AFF4'], source: 'Faithbound Kirin', capture: false }, response: Responses.getBehind(), }, { - id: 'Sandoria Second Walk Kirin Crimson Riddle Tail', + id: 'San dOria Second Walk Faithbound Kirin Crimson Riddle Rear', type: 'StartsUsing', - netRegex: { id: 'AFF5', source: 'Faithbound Kirin', capture: false }, + netRegex: { id: ['AFF5'], source: 'Faithbound Kirin', capture: false }, response: Responses.goFront(), }, { - id: 'Sandoria Second Walk Kirin Chiseled Arm Shockwave', + id: 'San dOria Second Walk Faithbound Kirin Punishment', type: 'StartsUsing', - netRegex: { id: 'ADC0', source: 'Chiseled Arm', capture: false }, - response: Responses.aoe(), + netRegex: { id: 'ADCB', source: 'Faithbound Kirin' }, + response: Responses.tankBuster(), }, { - id: 'Sandoria Second Walk Kirin Deadly Hold', + // every tower must be taken, or it is a wipe + // arms also cast AF80, ADB6 (slightly different timings for some reason) + // ADBF - damage from tower (Bury) + id: 'San dOria Second Walk Faithbound Kirin Deadly Hold', type: 'StartsUsing', netRegex: { id: 'ADB2', source: 'Faithbound Kirin', capture: false }, - condition: (data) => data.role === 'tank', - response: Responses.getTowers(), + suppressSeconds: 1, + alertText: (data, _matches, output) => { + if (data.role === 'tank' || data.job === 'BLU') + return output.tankTower!(); + }, + outputStrings: { + tankTower: { + en: 'Soak Tank Tower', + }, + }, }, { - id: 'Sandoria Second Walk Omega Ion Efflux', + id: 'San dOria Second Walk Chiseled Arm Shockwave', type: 'StartsUsing', - netRegex: { id: 'AD2B', source: 'Omega, the One', capture: false }, + netRegex: { id: 'ADC0', source: 'Chiseled Arm', capture: false }, response: Responses.aoe(), }, { - id: 'Sandoria Second Walk Ultima Antimatter Collector', + id: 'San dOria Second Walk Faithbound Kirin Striking Right', type: 'StartsUsing', - netRegex: { id: 'AD11', source: 'Ultima, the Feared', capture: true }, - run: (data, matches) => data.tankbusters.push(matches.target), + netRegex: { id: 'AD93', source: 'Faithbound Kirin', capture: false }, + infoText: (_data, _matches, output) => { + return output.awayTethered!({ dir: output.east!() }); + }, + outputStrings: kirinSequenceOutputStrings, }, { - id: 'Sandoria Second Walk Ultima Antimatter', + id: 'San dOria Second Walk Faithbound Kirin Striking Left', type: 'StartsUsing', - netRegex: { id: 'AD11', source: 'Ultima, the Feared', capture: false }, - delaySeconds: 0.3, + netRegex: { id: 'ADAF', source: 'Faithbound Kirin', capture: false }, + infoText: (_data, _matches, output) => { + return output.awayTethered!({ dir: output.west!() }); + }, + outputStrings: kirinSequenceOutputStrings, + }, + { + // AD95 - mechanic cast + // AD96 - from boss x2 + // AD9C, AD9B - from Sculpted Arms + id: 'San dOria Second Walk Faithbound Kirin Synchronized Strike', + type: 'StartsUsing', + netRegex: { id: 'AD95', source: 'Faithbound Kirin', capture: false }, + infoText: kirinSequenceInfoOutput(['sides', 'awayArms'], ['_', 'AD95']), + outputStrings: kirinSequenceOutputStrings, + // en: 'dodge => away from Arms (on boss hitbox)', + }, + { + // ADA0 - mech cast + // ADB0 - preview line aoes from boss + // ADAD - preview out aoe -OR- ADAE (Striking Right)/ADAF (Left) + // ADA1 - line aoes from boss (Synchronized Sequence) + // AD9C,AD9B - line aoes from arms + // ADA2 - out (Wringer) -OR- ADA3 (Striking Right)/ADA4 *probably + // ADA8 - under (Dead Wringer) ADA9 -or- (Smiting Right) + id: 'San dOria Second Walk Faithbound Kirin Synchronized Sequence', + type: 'StartsUsing', + netRegex: { id: 'ADA0', source: 'Faithbound Kirin', capture: false }, + durationSeconds: 10, + infoText: kirinSequenceInfoOutput(['sides', 'awayBossArms', 'under'], ['_', 'ADA1', 'ADA2']), + outputStrings: kirinSequenceOutputStrings, + // en: 'Sides => Away from boss & arms => Under boss', + }, + { + // AD9D - mech cast + // ADAD - preview out aoe + // ADB0 - preview line aoes from boss + // AD9D - out aoe (Double Wringer) + // ADA6 - line aoes from boss (ADA5 selfcast) + // AD97 - under (Dead Wringer) + // ADAB,ADAC - line aoes from arms + id: 'San dOria Second Walk Faithbound Kirin Double Wringer', + type: 'StartsUsing', + netRegex: { id: 'AD9D', source: 'Faithbound Kirin', capture: false }, + durationSeconds: 10, + infoText: kirinSequenceInfoOutput(['out', 'flank', 'under'], ['_', 'AD9D', 'ADA6']), + outputStrings: kirinSequenceOutputStrings, + // en: 'Out => Max melee on flank => Under boss', + }, + { + id: 'San dOria Second Walk Faithbound Kirin Smiting Right Sequence', + type: 'StartsUsing', + netRegex: { id: 'AD9E', source: 'Faithbound Kirin', capture: false }, + durationSeconds: 12, + infoText: kirinSequenceInfoOutput(['awayTethered', 'awayBoss', 'under'], [ + '_', + 'AD9E', + 'ADA2', + ], 'east'), + outputStrings: kirinSequenceOutputStrings, + // en: 'Away from tethered arm (East) => away from boss => under', + }, + { + // AD9F - cast + // ADAF - left punch preview + // ADAD - out preview + // AD9F - left punch damage + // ADA2 - Wringer damage + // AD9A - arm punch (Smiting Left) + // ADA7 - under (Dead Wringer) + id: 'San dOria Second Walk Faithbound Kirin Smiting Left Sequence', + type: 'StartsUsing', + netRegex: { id: 'AD9F', source: 'Faithbound Kirin', capture: false }, + durationSeconds: 12, + infoText: kirinSequenceInfoOutput(['awayTethered', 'awayBoss', 'under'], [ + '_', + 'AD9F', + 'ADA2', + ], 'west'), + outputStrings: kirinSequenceOutputStrings, + // en: 'Away from tethered arm (West) => away from boss => under', + }, + { + // AD92 - cast + // AD97, AD98 - from Sculpted Arms + id: 'San dOria Second Walk Faithbound Kirin Wringer', + type: 'StartsUsing', + netRegex: { id: 'AD92', source: 'Faithbound Kirin', capture: false }, + infoText: kirinSequenceInfoOutput(['out', 'under'], ['_', 'AD92']), + outputStrings: kirinSequenceOutputStrings, + }, + + { + id: 'San dOria Second Walk Faithbound Kirin Sequenced Mechanics', + type: 'Ability', + netRegex: { + id: ['AD9D', 'ADA6', 'AD96', 'AD97', 'ADA1', 'AD9C', 'ADA2', 'AD9E', 'AD9F'], + source: 'Faithbound Kirin', + capture: true, + }, + condition: (data) => data.kirinSequenceCalls > 0, suppressSeconds: 1, - response: (data, _matches, output) => { - // cactbot-builtin-response - output.responseOutputStrings = { - tankCleaveOnYou: Outputs.tankCleaveOnYou, - tankCleaves: Outputs.avoidTankCleaves, - }; + alertText: (data, matches, _output) => { + if (!Object.keys(data.kirinSequencedSafeCallouts).includes(matches.id)) { + return; + } + const call = data.kirinSequencedSafeCallouts[matches.id]; + if (call === undefined) { + throw new UnreachableCode(); + } + data.kirinSequenceCalls--; + console.info(`SEQMECH - ${matches.ability} ${matches.id} => ${call}`); + return call; + }, + outputStrings: {}, + }, + // SUMMON: Seiryu + { + // AD80 - orange/CW + // AD81 - blue/CCW + id: 'San dOria Second Walk Faithbound Kirin Eastwind Wheel', + type: 'StartsUsing', + netRegex: { id: ['AD80', 'AD81'], source: 'Dawnbound Seiryu' }, + // promise: async (data, matches) => { + // data.combatantData = []; + // + // data.combatantData = (await callOverlayHandler({ + // call: 'getCombatants', + // ids: [parseInt(matches.sourceId, 16)], + // })).combatants; + // }, + infoText: (_data, matches, output) => { + // const [combatant] = data.combatantData; + // if (combatant === undefined || data.combatantData.length !== 1) + // return; //todo: remove me after verifying not needed + // Seiryu only spawns east or south but can spin either way so just +/-1 depending on the rotation. + const x = parseFloat(matches.x); + const y = parseFloat(matches.y); + const rotation = matches.id === 'AD81' ? -1 : 1; + // N = 0, E = 1, S = 2, W = 3 + const card = Directions.xyTo4DirNum(x, y, kirinCenter[0]!, kirinCenter[1]!); + const safeHalf = ['north', 'east', 'south', 'west'][(card + rotation) % 4]; + if (safeHalf !== undefined) + return output.dodgeDir!({ dir: output[safeHalf]!() }); + return output.dodge!(); + }, + outputStrings: { + dodge: { + en: 'Avoid rotating AoE', + }, + dodgeDir: { + en: '${dir} half safe', + }, + north: Outputs.north, + east: Outputs.east, + west: Outputs.west, + south: Outputs.south, + }, + }, + { + // Stonega III is used in both Seiryu (A917) and Suzaku (B07A) + id: 'San dOria Second Walk Faithbound Kirin Stonega III', + type: 'StartsUsing', + netRegex: { id: ['A917', 'B07A'], source: 'Faithbound Kirin' }, + condition: Conditions.targetIsYou(), + response: Responses.spread(), + }, + // SUMMON Genbu + { + // large AOE (dash destination) followed by get under + id: 'San dOria Second Walk Faithbound Kirin Midwinter March', + type: 'StartsUsing', + netRegex: { id: 'AD87', source: 'Moonbound Genbu', capture: false }, + infoText: (_data, _matches, output) => output.text!(), + outputStrings: { + text: { + en: 'Follow Moonbound Genbu => Get under', + }, + }, + }, + // { + // id: 'San dOria Second Walk Faithbound Kirin Northern Current', + // type: 'StartsUsing', + // netRegex: { id: 'AD88', source: 'Moonbound Genbu' }, + // infoText: (_data, matches, output) => { + // return output.under!({ name: matches.source }); + // }, + // outputStrings: { + // under: { + // en: 'Get under ${name}', + // }, + // }, + // }, + { + id: 'San dOria Second Walk Faithbound Kirin Shattering Stomp', + type: 'StartsUsing', + netRegex: { id: 'AD84', source: 'Moonbound Genbu', capture: false }, + response: Responses.aoe(), + }, + { + // floor explosions + id: 'San dOria Second Walk Faithbound Kirin Moontide Font', + type: 'StartsUsing', + netRegex: { id: ['AD85', 'AD86'], source: 'Moonbound Genbu', capture: false }, + suppressSeconds: 10, + infoText: (_data, _matches, output) => { + return output.avoid!(); + }, + outputStrings: { + avoid: { + en: 'Avoid geyser explosions', + }, + }, + }, + // SUMMON Byakko + { + // dashes to the panel opposite and uses Razor Fang (AD90) + id: 'San dOria Second Walk Faithbound Kirin Gloaming Gleam', + type: 'StartsUsing', + netRegex: { id: 'AD8F', source: 'Duskbound Byakko' }, + alertText: (_data, matches, output) => { + return output.sides!({ name: matches.source }); + }, + outputStrings: { + sides: { + en: 'Go to sides of ${name} (not in front)', + }, + }, + }, + { + // 3 random puddles on the floor + id: 'San dOria Second Walk Faithbound Kirin Quake', + type: 'StartsUsing', + netRegex: { id: ['B07B', 'B07C'], source: 'Faithbound Kirin', capture: false }, + // response: Responses.aoe(), // todo: probs just remove + }, + // SUMMON Suzaku + { + // self-target AD8A + id: 'San dOria Second Walk Faithbound Kirin Vermilion Flight', + type: 'StartsUsing', + netRegex: { id: 'AEFB', source: 'Sunbound Suzaku' }, + durationSeconds: 7, + alertText: (_data, matches, output) => { + return output.sides!({ name: matches.source }); + }, + outputStrings: { + sides: { + en: 'Avoid ${name} dash + dodge ground AoEs', + }, + }, + }, - if (data.tankbusters.includes(data.me)) - return { alertText: output.tankCleaveOnYou!() }; - return { infoText: output.tankCleaves!() }; + // ---------------------- + // Ultima & Omega + + { + id: 'San dOria Second Walk Omega, the One Ion Efflux', + type: 'StartsUsing', + netRegex: { id: 'AD2B', source: 'Omega, the One', capture: false }, + response: Responses.aoe(), + }, + { + id: 'San dOria Second Walk Omega, the One Citadel Buster', + type: 'StartsUsing', + netRegex: { id: 'AD1B', source: 'Ultima, the Feared', capture: false }, + response: Responses.aoe(), + }, + { + // B087 is the cast, but happens way in advance + id: 'San dOria Second Walk Omega, the One Anti-personnel Missile', + type: 'StartsUsing', + netRegex: { id: 'B088', source: 'Omega, the One' }, + condition: Conditions.targetIsYou(), + response: Responses.spread(), + }, + { + id: 'San dOria Second Walk Omega, the One Antimatter', + type: 'StartsUsing', + netRegex: { id: 'AD11', source: 'Ultima, the Feared' }, + condition: Conditions.targetIsYou(), + alertText: (_data, _matches, output) => { + return output.tankBusterOnYou!(); + }, + outputStrings: { + tankBusterOnYou: Outputs.tankBusterOnYou, + }, + }, + { + id: 'San dOria Second Walk Omega, the One Mana Screen Collect', + type: 'CombatantMemory', + netRegex: { change: 'Add', pair: [{ key: 'BNpcID', value: ['1EBE8B', '1EBE8C'] }] }, + run: (data, matches) => { + const x = parseFloat(matches.pairPosX ?? '0'); + const y = parseFloat(matches.pairPosY ?? '0'); + // both platforms are in line with each other, so for X we need to check 2 values + const col1 = floatNear(x, 725) || floatNear(x, 790); + // const col2 = floatNear(x, 745) || floatNear(x, 810); + const row1 = floatNear(y, 784); + const row2 = floatNear(y, 800); + // const row3 = floatNear(y, 816); + const direction = matches.pairBNpcID === '1EBE8B' ? 'B' : 'C'; + const key = `${row1 ? 'n' : (row2 ? 'c' : 's')}${col1 ? 'w' : 'e'}${direction}`; + data.omegaManaScreens.push(key); + }, + }, + { + id: 'San dOria Second Walk Omega, the One Energy Orb (cast)', + type: 'Ability', + netRegex: { id: 'AD08', source: 'Ultima, the Feared', capture: false }, + delaySeconds: 2, + durationSeconds: 7, + promise: async (data) => { + const actors = (await callOverlayHandler({ + call: 'getCombatants', + })).combatants; + const orbs = actors.filter((actor) => actor.BNpcID === 18714 && actor.ModelStatus === 0); + // const visibleOrbs = orbs.filter((orb) => orb.ModelStatus === 0); + // const search = (visibleOrbs.length === 0) ? orbs : visibleOrbs; + // console.info(JSON.stringify(orbs)); + // console.info('visible', JSON.stringify(visibleOrbs)); + orbs.forEach((orb) => { + const y = Number(orb.PosY); + if (floatNear(y, 784)) + data.omegaOrbs.push('north'); + else if (floatNear(y, 800)) + data.omegaOrbs.push('middle'); + else if (floatNear(y, 816)) + data.omegaOrbs.push('south'); + }); + // console.info(`Omega, the One Energy Orb: ${data.omegaOrbs.join(', ')}`); + }, + infoText: (data, _matches, output) => { + if (data.omegaOrbs.length === 1 && data.omegaManaScreens.length === 0 && data.omegaOrbs[0]) + // just one energy orb going off + return output.avoidLaserDir!({ dir: output[data.omegaOrbs[0]]!() }); + else if (data.omegaOrbs.length === 2 && data.omegaManaScreens.length === 0) + // 2 orbs is always middle + return output.middle!(); + else if (data.omegaOrbs.length === 1 && data.omegaManaScreens.length === 1) { + // simple 1 orb/1 screen pattern, just opposite corner really + const loc = data.omegaManaScreens[0]!; + if (data.omegaOrbs[0] === 'north' && loc === 'neB') { + return output.getLocation!({ dir: output.backRight!() }); + } else if (data.omegaOrbs[0] === 'south' && loc === 'seC') { + return output.getLocation!({ dir: output.backLeft!() }); + } + } else if (data.omegaOrbs.length === 1 && data.omegaManaScreens.length === 3) { + // 3 screen pattern + const key = data.omegaManaScreens.sort().join(','); + const patterns = OmegaManaScreenPatterns[key]; + if (patterns !== undefined) { + const call = patterns[data.omegaOrbs[0]!]; + if (call !== undefined) + return output.getLocation!({ dir: output[call]!() }); + } + } + console.error(`Second Walk Omega, the One Energy Orb: unknown pattern +${data.omegaOrbs.join(', ')} ${data.omegaManaScreens.join(', ')}`); + return `UNKNOWN PATTERN ${data.omegaManaScreens.join(',')}`; // TODO: Remove me + // return output.avoid!(); + }, + outputStrings: { + avoid: { + en: 'Avoid lasers', + }, + avoidLaserDir: { + en: 'Avoid ${dir} laser', + }, + getLocation: { + en: '${dir}', + }, + getMiddle: { + en: 'Get Middle', + }, + frontLeft: { + en: 'Front Left', + de: 'Vorne Links', + fr: 'Avant Gauche', + ja: '前左', + cn: '左前', + ko: '앞 왼쪽', + }, + frontMiddle: { + en: 'Front Middle', + }, + frontRight: { + en: 'Front Right', + de: 'Vorne Rechts', + fr: 'Avant Droit', + ja: '前右', + cn: '右前', + ko: '앞 오른쪽', + }, + backLeft: { + en: 'Back Left', + de: 'Hinten Links', + fr: 'Arrière Gauche', + ja: '後左', + cn: '左后', + ko: '뒤 왼쪽', + }, + backMiddle: { + en: 'Back Middle', + }, + backRight: { + en: 'Back Right', + de: 'Hinten Rechts', + fr: 'Arrière Droit', + ja: '後ろ右', + cn: '右后', + ko: '뒤 오른쪽', + }, + north: Outputs.left, + middle: Outputs.middle, + south: Outputs.right, + }, + }, + { + id: 'San dOria Second Walk Omega, the One Orb/Screen Cleanup', + type: 'Ability', + netRegex: { id: 'AD32', source: 'Energy Orb', capture: false }, + run: (data) => { + data.omegaOrbs = []; + data.omegaManaScreens = []; }, - run: (data) => data.tankbusters = [], }, { - id: 'Sandoria Second Walk Omega Fore-to-aft Fire', + id: 'San dOria Second Walk Omega, the One Hyper Pulse', type: 'StartsUsing', - netRegex: { id: 'AD25', source: 'Omega, the One', capture: false }, - durationSeconds: 8, - response: Responses.getBackThenFront(), + netRegex: { id: 'AD2F', source: 'Omega, the One', capture: false }, + infoText: (_data, _matches, output) => { + return output.outOfMiddle!(); + }, + outputStrings: { + outOfMiddle: { + en: 'Out of Middle', + }, + }, }, { - id: 'Sandoria Second Walk Omega Aft-to-fore Fire', + // targeted aoe drops in the direction it is moving + id: 'San dOria Second Walk Omega, the One Trajectory Projection', + type: 'HeadMarker', + netRegex: { id: ['0269', '026A', '026B', '026C'], capture: true }, + condition: Conditions.targetIsYou(), + countdownSeconds: 8.9, + infoText: (_data, matches, output) => { + switch (matches.id) { + case '0269': + return output.droppingAoeDir!({ dir: output.east!() }); + case '026A': + return output.droppingAoeDir!({ dir: output.west!() }); + case '026B': + return output.droppingAoeDir!({ dir: output.south!() }); + case '026C': + return output.droppingAoeDir!({ dir: output.north!() }); + } + return Outputs.unknown; + }, + outputStrings: { + droppingAoeDir: { + en: 'Dropping aoe to your ${dir}, move opposite in', + }, + north: Outputs.north, + east: Outputs.east, + west: Outputs.west, + south: Outputs.south, + }, + }, + { + id: 'San dOria Second Walk Omega, the One Chemical Bomb', + type: 'StartsUsing', + netRegex: { id: 'AD0E', source: 'Ultima, the Feared', capture: false }, + infoText: (_data, _matches, output) => output.text!(), + outputStrings: { + text: { + en: 'Rotate away from proximity markers', + de: 'Weg rotieren von den Distanzmarkierungen', + fr: 'Tournez loin des marqueurs de proximité', + ja: '距離減衰マーカー 3発目から1発目に避ける', + cn: '远离距离衰减 AoE 落点', + ko: '회전하면서 거리감쇠 징 피하기', + }, + }, + }, + { + id: 'San dOria Second Walk Omega, the One Aft-to-fore Fire', type: 'StartsUsing', netRegex: { id: 'AD27', source: 'Omega, the One', capture: false }, - durationSeconds: 8, response: Responses.getFrontThenBack(), }, { - id: 'Sandoria Second Walk Ultima Tractor Beam', + id: 'San dOria Second Walk Omega, the One Fore-to-aft Fire', + type: 'StartsUsing', + netRegex: { id: 'AD25', source: 'Omega, the One', capture: false }, + response: Responses.getBackThenFront(), + }, + { + id: 'San dOria Second Walk Omega, the One Tractor Beam', type: 'StartsUsing', netRegex: { id: 'AD06', source: 'Ultima, the Feared', capture: false }, - response: Responses.drawIn(), + infoText: (_data, _matches, output) => output.text!(), + outputStrings: { + text: { + en: 'Go to west edge, avoid ship', + }, + }, }, { - id: 'Sandoria Second Walk Ultima Citadel Buster', + // this might be too much, could be good though? + id: 'San dOria Second Walk Omega, the One Multi-missile', type: 'StartsUsing', - netRegex: { id: 'AD1B', source: 'Ultima, the Feared', capture: false }, - response: Responses.bigAoe(), + netRegex: { id: 'AFEC', source: 'Omega, the One', capture: false }, + suppressSeconds: 1, + countdownSeconds: 3.9, + soundVolume: 0, + infoText: (_data, _matches, output) => output.text!(), + outputStrings: { + text: { + en: 'ground AoEs go off', + }, + }, }, + // ---------------------- + // Kam'lanaut { - id: 'Sandoria Second Walk Kamlanaut Enspirited Swordplay', + id: 'San dOria Second Walk Kam\'lanaut Enspirited Swordplay', type: 'StartsUsing', netRegex: { id: 'ACBD', source: 'Kam\'lanaut', capture: false }, response: Responses.aoe(), }, { - id: 'Sandoria Second Walk Kamlanaut Elemental Blade x2', + id: 'San dOria Second Walk Kam\'lanaut Shockwave', type: 'StartsUsing', - netRegex: { id: 'AC91', source: 'Kam\'lanaut', capture: false }, - run: (data) => { - data.storedElements = []; - data.expectedElements = 2; - }, + netRegex: { id: 'ACB3', source: 'Kam\'lanaut', capture: false }, + response: Responses.aoe('alert'), }, { - id: 'Sandoria Second Walk Kamlanaut Elemental Blade x3', - type: 'StartsUsing', - netRegex: { id: 'AC92', source: 'Kam\'lanaut', capture: false }, - run: (data) => { - data.storedElements = []; - data.expectedElements = 3; + id: 'San dOria Second Walk Kam\'lanaut Empyreal Banish III', + type: 'HeadMarker', + netRegex: { id: '0178' }, + condition: Conditions.targetIsYou(), + response: Responses.spread(), + }, + { + id: 'San dOria Second Walk Kam\'lanaut Princely Blow', + type: 'HeadMarker', + netRegex: { id: '0265', capture: true }, + alertText: (data, matches, output) => { + // targets the boss itself unfortunately, so need to use data0 + const target = data.party?.idToName_?.[matches.data0]; + data.tankbusterTargets.push(target ?? ''); + if (data.me === target) + return output.tankBusterKnockBack!(); + }, + outputStrings: { + tankBusterKnockBack: { + en: 'Tank Buster + Knockback', + }, }, }, { - id: 'Sandoria Second Walk Kamlanaut Elemental Blade Collector', - type: 'GainsEffect', - netRegex: { effectId: 'B9A', count: Object.keys(effectB9AMap), capture: true }, - condition: (data, matches) => { - if (data.expectedElements === 0) - return false; + id: 'San dOria Second Walk Kam\'lanaut Princely Blow Not You', + type: 'HeadMarker', + netRegex: { id: '0265', capture: false }, + delaySeconds: 0.3, + suppressSeconds: 5, + infoText: (data, _matches, output) => { + if (data.tankbusterTargets.length === 0 || data.tankbusterTargets.includes(data.me)) + return; - const element = b9aValueToElement(matches.count); - data.storedElements.push(element); + if (data.role === 'healer') + return output.tankBuster!(); - return true; + return output.avoidTankCleaves!(); }, - durationSeconds: 3, - infoText: (_data, matches, output) => { - const element = b9aValueToElement(matches.count); - return output[element]!(); + run: (data, _matches) => data.tankbusterTargets = [], + outputStrings: { + tankBuster: Outputs.tankBuster, + avoidTankCleaves: Outputs.avoidTankCleaves, }, - outputStrings: elementOutputStrings, }, { - id: 'Sandoria Second Walk Kamlanaut Elemental Blade', + id: 'San dOria Second Walk Kam\'lanaut Light Blade', type: 'Ability', - netRegex: { id: 'AC91', source: 'Kam\'lanaut', capture: false }, - condition: (data) => data.expectedElements > 0, - durationSeconds: 10, - alertText: (data, _matches, output) => { - const elements = data.storedElements.join(output.separator!()); - return output.combo!({ elements: elements }); + netRegex: { id: 'ACAB', source: 'Kam\'lanaut', capture: false }, + alertText: (_data, _matches, output) => output.text!(), + outputStrings: { + text: { + en: 'Behind a sword', + }, }, - outputStrings: elementOutputStrings, }, { - id: 'Sandoria Second Walk Kamlanaut Great Wheel', - type: 'StartsUsing', - netRegex: { id: ['ACAD', 'ACAE', 'ACAF', 'ACB0'], source: 'Kam\'lanaut', capture: false }, - infoText: (_data, _matches, output) => output.text!(), + // ACAF - aoe under boss -> cleave + // ACAE - aoe under boss => cleave + stack + // ACB1 - cleave + // ACC0 - stack Empyreal Banish IV + id: 'San dOria Second Walk Kam\'lanaut Great Wheel', + type: 'Ability', + netRegex: { id: 'ACAF', source: 'Kam\'lanaut', capture: false }, + suppressSeconds: 1, + response: Responses.getBehind(), + }, + { + id: 'San dOria Second Walk Kam\'lanaut Great Wheel Stack', + type: 'Ability', + netRegex: { id: 'ACAE', source: 'Kam\'lanaut', capture: false }, + suppressSeconds: 1, + alertText: (_data, _matches, output) => output.behindStack!(), outputStrings: { - text: { - en: 'Out of Melee => Get Behind', + behindStack: { + en: 'Get behind and Stack', }, }, }, { - id: 'Sandoria Second Walk Kamlanaut Transcendent Union', + id: 'San dOria Second Walk Kam\'lanaut Empyreal Banish IV', + type: 'StartsUsing', + netRegex: { id: 'ACC0', source: 'Kam\'lanaut' }, + condition: Conditions.targetIsYou(), + infoText: (_data, _matches, output) => output.stackOnYou!(), + outputStrings: { + stackOnYou: Outputs.stackOnYou, + }, + }, + { + // AD01 Elemental Edge x6 aoe + // ACB5 big damage at end + id: 'San dOria Second Walk Kam\'lanaut Transcendent Union', type: 'StartsUsing', netRegex: { id: 'ACB4', source: 'Kam\'lanaut', capture: false }, - durationSeconds: 11.1, - alertText: (_data, _matches, output) => output.text!(), + delaySeconds: 2, + durationSeconds: 9, + response: Responses.bigAoe('alarm'), + }, + { + id: 'San dOria Second Walk Kam\'lanaut Illumed Estoc', + type: 'StartsUsing', + netRegex: { id: 'ACBA', source: 'Kam\'lanaut' }, + infoText: (data, matches, output) => { + data.kamEstocHeadings.push(Number(matches.heading)); + if (data.kamEstocHeadings.length === 3) { + data.kamEstocHeadings = []; + return output.text!(); + } + }, outputStrings: { text: { - en: 'AoE x5 => Big AoE', + en: 'Dodge clone line AoEs on edge', // FEEDBACK: better wording? }, }, }, { - id: 'Sandoria Second Walk Kamlanaut Shield Bash', + id: 'San dOria Second Walk Kam\'lanaut Shield Bash', type: 'StartsUsing', netRegex: { id: 'ACBE', source: 'Kam\'lanaut', capture: false }, - response: Responses.knockback(), + alertText: (data, _matches, output) => { + if (data.kamEstocHeadings.length === 0) { + return output.knockbackAny!(); + } else if (data.kamEstocHeadings.length === 2) { + const allDirections: DirectionOutput8[] = ['dirN', 'dirSW', 'dirSE']; + const headingsAsDir = data.kamEstocHeadings.map((h) => + Directions.output8Dir[Directions.hdgTo8DirNum(h)] + ); + const call = allDirections.filter((x) => !headingsAsDir.includes(x))[0]!; + data.kamEstocHeadings = []; + return output.knockbackDir!({ dir: output[call]!() }); + } + }, + outputStrings: { + knockbackAny: { + en: 'Get knocked down long platform', + }, + knockbackDir: { + en: 'Get knocked down ${dir} platform', + }, + dirN: Outputs.north, + dirSW: Outputs.southwest, + dirSE: Outputs.southeast, + }, + }, + { + id: 'San dOria Second Walk Kam\'lanaut Elemental Blade Buff Collect', + type: 'GainsEffect', + netRegex: { effectId: 'B9A' }, + durationSeconds: 1.5, + soundVolume: 0, + infoText: (data, matches, output) => { + const element = kamlanautElementBuffIds[matches.count]; + if (element === undefined) + throw new UnreachableCode(); + data.kamElements.push(element); + return output[element]!(); + }, + outputStrings: kamlanautElementalOutputStrings, + }, + { + id: 'San dOria Second Walk Kam\'lanaut Elemental Blade Blade Collect', + type: 'StartsUsingExtra', + netRegex: { id: Object.keys(kamlanautSublimeBladeCasts) }, + run: (data, matches, _output) => { + const element = kamlanautSublimeBladeCasts[matches.id]; + if (element === undefined) + throw new UnreachableCode(); + data.kamElementalBlades[element] = { + x: parseFloat(matches.x), + y: parseFloat(matches.y), + }; + }, + }, + { + id: 'San dOria Second Walk Kam\'lanaut Elemental Blade Cone Collect', + type: 'StartsUsingExtra', + netRegex: { id: Object.keys(kamlanautSublimeConeCasts) }, + run: (data, matches, _output) => { + const element = kamlanautSublimeConeCasts[matches.id]; + if (!element) + throw new UnreachableCode(); + + const dir = + Directions.output8Dir[Directions.hdgTo8DirNum(Number.parseFloat(matches.heading))]; + + if (isValidSiXDir(dir)) + data.kamElementalCones[dir] = element; + }, }, { - id: 'Sandoria Second Walk Kamlanaut Empyreal Banish IV', + // for both pizza slice and cross line aoe elemental mechanics + id: 'San dOria Second Walk Kam\'lanaut Sublime Elements', type: 'StartsUsing', - netRegex: { id: 'ACC0', source: 'Kam\'lanaut', capture: true }, - response: Responses.stackMarkerOn(), + netRegex: { id: 'B00A', source: 'Kam\'lanaut', capture: false }, + delaySeconds: 0.5, + durationSeconds: 7, + alertText: (data, _matches, output) => { + // crossing line aoes, of which 2 or 3 expand + // console.info('elements:', data.kamElements); + // console.info('Blades:', data.kamElementalBlades); + // console.info('Cones:', data.kamElementalCones); + if (data.kamElementalBlades['fire'] !== undefined) { + const result = sublimeElementsBladeSafespot(data.kamElementalBlades, data.kamElements); + console.info(result); + if (result.length === 2) { + return output.nextToCross!({ + ele1: output[result[0]!]!(), + ele2: output[result[1]!]!(), + }); + } else if (result.length === 1) { + return output.nextToBlade!({ ele: output[result[0]!]!() }); + } + console.error('Sublime Blades: unknown pattern'); + return 'Error'; + } + // cone aoes from the boss, of which 2 or 3 expand + // Object.entries(data.kamElementalCones).forEach(([card, element]) => { + // data.kamElementalCones[card as KamConeDirection] = data.kamElements.includes(element as KamElement) ? 'BAD' : element; + // }); + const dirs = Object.keys(data.kamElementalCones) as KamSixDirection[]; + for (let i = 0; i < dirs.length; i++) { + const d1 = dirs[i]!; + const d2 = dirs[(i + 1) % dirs.length]!; + + const e1 = data.kamElementalCones[d1]!; + const e2 = data.kamElementalCones[d2]!; + // console.info(i, d1, d2); + // console.info(i, e1, e2); + if ( + !data.kamElements.includes(e1) && e1 !== null && !data.kamElements.includes(e2) && + e2 !== null + ) { + // console.info('>>>', e1, e2); + return output.betweenSlice!({ ele1: output[e1]!(), ele2: output[e2]!() }); + } + } + }, + outputStrings: { + betweenSlice: { + en: 'Between ${ele1} and ${ele2}', + }, + nextToBlade: { + en: 'Next to ${ele}', + }, + nextToCross: { + en: 'go to ${ele1} and ${ele2} intersection', // FEEDBACK: wording? + }, + ...kamlanautElementalOutputStrings, + }, }, { - id: 'Sandoria Second Walk Ealdnarche Uranos Cascade Collector', + id: 'San dOria Second Walk Kam\'lanaut Sublime Elements Cleanup', + type: 'Ability', + netRegex: { id: 'B00A', source: 'Kam\'lanaut', capture: false }, + run: (data) => { + data.kamElements = []; + data.kamElementalCones = emptySixDirections(); + data.kamElementalBlades = {}; + }, + }, + { + id: 'San dOria Second Walk Kam\'lanaut Crystal Spawn Collect', + type: 'CombatantMemory', + netRegex: { + change: 'Add', + pair: [{ key: 'BNpcID', value: Object.keys(kamlanautCrystalNpcIds) }], + }, + run: (data, matches, _output) => { + const element = kamlanautCrystalNpcIds[matches.pairBNpcID ?? '']; + const x = Number.parseFloat(matches.pairPosX ?? '0'); + const y = Number.parseFloat(matches.pairPosY ?? '0'); + if (!element) + throw new UnreachableCode(); + const dir = Directions.output8Dir[Directions.xyTo8DirNum(x, y, -200.00, 150.0)]; + if (isValidSiXDir(dir)) + data.kamCrystalLocations[dir] = element; + }, + }, + { + // ACB7 - initial, shorter cast + id: 'San dOria Second Walk Kam\'lanaut Elemental Resonance (crystals)', + type: 'StartsUsingExtra', + netRegex: { id: ['ACB7', 'ACB8'] }, + preRun: (data, matches) => { + const x = Number.parseFloat(matches.x); + const y = Number.parseFloat(matches.y); + const dir = Directions.output8Dir[Directions.xyTo8DirNum(x, y, -200.00, 150.0)]; + if (isValidSiXDir(dir)) { + data.kamCrystalCasts.push(dir); + } + }, + alertText: (data, _matches, output) => { + const crystalCount = Object.keys(data.kamCrystalLocations).length; + // console.info('Crystals:', crystalCount); + console.info('Casts:', data.kamCrystalCasts); + // console.info('Locations:', data.kamCrystalLocations); + if (crystalCount === 3 && data.kamCrystalCasts.length === 1) { + // SIMPLE 3 CRYSTALS - only call which to avoid + const explodingCrystal = data.kamCrystalCasts[0]!; + const explodingEle = data.kamCrystalLocations[explodingCrystal]; + data.kamCrystalCasts = []; // reset for the next pattern + if (explodingEle) { + console.info('Exploding:', explodingCrystal); + return output.avoid!({ ele: output[explodingEle]!() }); + } + } else if (crystalCount === 6 && data.kamCrystalCasts.length === 2) { + // SIX CRYSTAL PATTERN + // get the index of two crystals exploding + // const temp = Array(100).fill('O'); + const explodingIndex1 = kamSixDirections.indexOf(data.kamCrystalCasts[0]!); + const explodingIndex2 = kamSixDirections.indexOf(data.kamCrystalCasts[1]!); + if (explodingIndex1 === -1 || explodingIndex2 === -1) { + console.error('Kam\'lanaut Elemental Resonance (crystals) - invalid crystals'); + return; + } + const directDist = Math.abs(explodingIndex1 - explodingIndex2); + console.info('Exp index:', explodingIndex1, explodingIndex2, directDist); + if (Math.min(directDist, 6 - directDist) === 3) { + // TWO SAFE SPOTS - crystals far apart + // crystals are farther apart, leaving 2 safe spots farthest from each crystal. + // safe spot = area between the crystals 1 and 2 away + const lastCrystal = Math.max(explodingIndex1, explodingIndex2); + const safe1 = data.kamCrystalLocations[kamSixDirections[(lastCrystal + 1) % 6]!]; + const safe2 = data.kamCrystalLocations[kamSixDirections[(lastCrystal + 2) % 6]!]; + console.info('Exploding 2spot:', lastCrystal, safe1, safe2); + console.info('Safe6:', safe1, safe2); + data.kamCrystalCasts = []; // reset + if (safe1 && safe2) + return output.betweenCrystals!({ ele1: output[safe1]!(), ele2: output[safe2]!() }); + } + // ONE SAFE SPOT - crystal AoEs overlapping + // crystals overlap, there is one large safe spot centered on a crystal + // safe spot = crystal 2 away + let safeIndex = (explodingIndex1 + 2) % 6; + if (safeIndex === explodingIndex1 || safeIndex === explodingIndex2) + safeIndex = (safeIndex + 2) % 6; + console.info('Exploding 1spot:', explodingIndex1, explodingIndex2, '->', safeIndex); + const safe = data.kamCrystalLocations[kamSixDirections[safeIndex]!]; + data.kamCrystalCasts = []; // reset + if (safe) + return output.safeCrystal!({ ele: output[safe]!() }); + } + }, + outputStrings: { + betweenCrystals: { + en: 'Between ${ele1} and ${ele2} crystals', + }, + safeCrystal: { + en: 'Go to ${ele} crystal', + }, + avoid: { + en: 'Away from ${ele} crystal', + }, + ...kamlanautElementalOutputStrings, + }, + }, + { + // cleanup of crystals + id: 'San dOria Second Walk Kam\'lanaut Illumed Facet', + type: 'Ability', + netRegex: { id: 'ACB9', source: 'Kam\'lanaut', capture: false }, + delaySeconds: 3, + run: (data) => { + data.kamCrystalLocations = {}; + data.kamCrystalCasts = []; + }, + }, + // ---------------------- + // Eald'narche + { + id: 'San dOria Second Walk Eald\'narche Uranos Cascade', type: 'StartsUsing', - netRegex: { id: 'AD52', source: 'Eald\'narche', capture: true }, - run: (data, matches) => data.tankbusters.push(matches.target), + netRegex: { id: 'AD52', source: 'Eald\'narche' }, + alertText: (data, matches, output) => { + if (matches.target === data.me) + return output.tankBusterOnYou!(); + }, + run: (data, matches) => data.tankbusterTargets.push(matches.target), + outputStrings: { + tankBusterOnYou: Outputs.tankBusterOnYou, + }, }, { - id: 'Sandoria Second Walk Ealdnarche Uranos Cascade', + id: 'San dOria Second Walk Eald\'narche Uranos Cascade Not You', type: 'StartsUsing', netRegex: { id: 'AD52', source: 'Eald\'narche', capture: false }, delaySeconds: 0.3, - suppressSeconds: 1, - response: (data, _matches, output) => { - // cactbot-builtin-response - output.responseOutputStrings = { - tankCleaveOnYou: Outputs.tankCleaveOnYou, - tankCleaves: Outputs.avoidTankCleaves, - }; - - if (data.tankbusters.includes(data.me)) - return { alertText: output.tankCleaveOnYou!() }; - return { infoText: output.tankCleaves!() }; + suppressSeconds: 5, + infoText: (data, _matches, output) => { + if (data.tankbusterTargets.includes(data.me)) + return; + return output.tankBusters!(); + }, + run: (data) => data.tankbusterTargets = [], + outputStrings: { + tankBusters: Outputs.tankBusters, }, - run: (data) => data.tankbusters = [], }, { - id: 'Sandoria Second Walk Ealdnarche Cronos Sling Out + Right', + id: 'San dOriea Second Walk Eald\'narche Cronos Sling Out + Right', type: 'StartsUsing', netRegex: { id: 'AD49', source: 'Eald\'narche', capture: false }, alertText: (_data, _matches, output) => output.text!(), @@ -311,7 +1280,7 @@ const triggerSet: TriggerSet = { }, }, { - id: 'Sandoria Second Walk Ealdnarche Cronos Sling Out + Left', + id: 'San dOria Second Walk Eald\'narche Cronos Sling Out + Left', type: 'StartsUsing', netRegex: { id: 'AD4A', source: 'Eald\'narche', capture: false }, alertText: (_data, _matches, output) => output.text!(), @@ -322,7 +1291,7 @@ const triggerSet: TriggerSet = { }, }, { - id: 'Sandoria Second Walk Ealdnarche Cronos Sling In + Right', + id: 'San dOria Second Walk Eald\'narche Cronos Sling In + Right', type: 'StartsUsing', netRegex: { id: 'AD4B', source: 'Eald\'narche', capture: false }, alertText: (_data, _matches, output) => output.text!(), @@ -333,7 +1302,7 @@ const triggerSet: TriggerSet = { }, }, { - id: 'Sandoria Second Walk Ealdnarche Cronos Sling In + Left', + id: 'San dOria Second Walk Eald\'narche Cronos Sling In + Left', type: 'StartsUsing', netRegex: { id: 'AD4C', source: 'Eald\'narche', capture: false }, alertText: (_data, _matches, output) => output.text!(), @@ -344,7 +1313,7 @@ const triggerSet: TriggerSet = { }, }, { - id: 'Sandoria Second Walk Ealdnarche Warp', + id: 'San dOria Second Walk Eald\'narche Warp', type: 'StartsUsing', netRegex: { id: 'AD56', source: 'Eald\'narche', capture: false }, alertText: (_data, _matches, output) => output.text!(), @@ -355,7 +1324,7 @@ const triggerSet: TriggerSet = { }, }, { - id: 'Sandoria Second Walk Ealdnarche Empyreal Vortex', + id: 'San dOria Second Walk Eald\'narche Empyreal Vortex', type: 'StartsUsing', netRegex: { id: 'AD6D', source: 'Eald\'narche', capture: false }, infoText: (_data, _matches, output) => output.text!(), @@ -365,6 +1334,16 @@ const triggerSet: TriggerSet = { }, }, }, + + // ---------------------- + // Adds + { + id: 'San dOria Second Walk Detector Electroswipe', + type: 'StartsUsing', + netRegex: { id: 'AA27', source: 'Detector' }, + suppressSeconds: 5, + response: Responses.interruptIfPossible('info'), + }, ], timelineReplace: [], }; From 990338c527d732f9bcd72c04b98590345f00940b Mon Sep 17 00:00:00 2001 From: Jacob Keller Date: Thu, 7 May 2026 00:37:34 -0700 Subject: [PATCH 3/6] raidboss: timeline improvements for ultima/omega Inspired by some work from Harbinger, fix a few missing elements add some --jump-- and --(un)targetable-- entries. Signed-off-by: Jacob Keller --- .../data/07-dt/alliance/san-doria-second-walk.txt | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/ui/raidboss/data/07-dt/alliance/san-doria-second-walk.txt b/ui/raidboss/data/07-dt/alliance/san-doria-second-walk.txt index 7be1eaaf761..77e2f5de81f 100644 --- a/ui/raidboss/data/07-dt/alliance/san-doria-second-walk.txt +++ b/ui/raidboss/data/07-dt/alliance/san-doria-second-walk.txt @@ -200,8 +200,6 @@ hideall "--sync--" 20066.9 "Surface Missile" #Ability { id: "B076", source: "Omega, the One" } 20067.9 "Energy Orb" Ability { id: "AD08", source: "Ultima, the Feared" } 20069.0 "Surface Missile" #Ability { id: "B076", source: "Omega, the One" } -20069.0 "Surface Missile" #Ability { id: "B076", source: "Omega, the One" } -20071.0 "Surface Missile" #Ability { id: "B076", source: "Omega, the One" } 20071.0 "Surface Missile" #Ability { id: "B076", source: "Omega, the One" } 20075.0 "Anti-personnel Missile" Ability { id: "B087", source: "Omega, the One" } 20076.0 "Energy Ray" Ability { id: "AD32", source: "Energy Orb" } @@ -212,8 +210,9 @@ hideall "--sync--" 20096.3 "Energy Ray" Ability { id: "AD32", source: "Energy Orb" } 20097.1 "Energy Ray" #Ability { id: "AD0D", source: "Ultima, the Feared" } 20102.0 "Trajectory Projection" Ability { id: "AD23", source: "Omega, the One" } -20112.7 "Guided Missile" #Ability { id: "AD24", source: "Omega, the One" } -20112.7 "Guided Missile" #Ability { id: "AD24", source: "Omega, the One" } +20112.7 "Guided Missile" Ability { id: "AD24", source: "Omega, the One" } +20118.2 "--untargetable--" Ability { id: "AD12", source: "Ultima, the Feared" } +20118.3 "--jump--" Ability { id: "AD2C", source: "Omega, the One" } # Jump from the airship before it's reduced to ash! 20118.3 "Tractor Field" Ability { id: "AD12", source: "Ultima, the Feared" } @@ -239,8 +238,11 @@ hideall "--sync--" 20138.2 "Multi-missile" #Ability { id: "AFEC", source: "Omega, the One" } 20138.2 "Multi-missile" #Ability { id: "AFEC", source: "Omega, the One" } 20140.6 "Citadel Siege" Ability { id: "AD18", source: "Ultima, the Feared" } +20145.8 "--ultima targetable--" 20152.7 "Citadel Buster" Ability { id: "AD1B", source: "Ultima, the Feared" } 20158.6 "Hyper Pulse" Ability { id: "AD2F", source: "Omega, the One" } +20160.8 "--omega targetable--" +20171.2 "--jump--" Ability { id: "AD2C", source: "Omega, the One" } # Phase 2 20175.8 label "ultima-omega-p2-loop" @@ -256,7 +258,6 @@ hideall "--sync--" 20201.4 "Anti-personnel Missile" Ability { id: "B087", source: "Omega, the One" } 20201.6 "Energy Ray" Ability { id: "AD0B", source: "Ultima, the Feared" } 20206.4 "Anti-personnel Missile" Ability { id: "B088", source: "Omega, the One" } -20214.9 "Chemical Bomb" Ability { id: "AD0E", source: "Ultima, the Feared" } 20215.5 "Chemical Bomb" Ability { id: "AD0F", source: "Ultima, the Feared" } 20218.5 "Chemical Bomb" Ability { id: "AD0F", source: "Ultima, the Feared" } 20221.5 "Chemical Bomb" Ability { id: "AD0F", source: "Ultima, the Feared" } @@ -265,8 +266,6 @@ hideall "--sync--" 20234.2 "Surface Missile" #Ability { id: "B076", source: "Omega, the One" } 20236.2 "Energy Orb" Ability { id: "AD08", source: "Ultima, the Feared" } 20236.2 "Surface Missile" #Ability { id: "B076", source: "Omega, the One" } -20236.2 "Surface Missile" #Ability { id: "B076", source: "Omega, the One" } -20238.2 "Surface Missile" #Ability { id: "B076", source: "Omega, the One" } 20238.2 "Surface Missile" #Ability { id: "B076", source: "Omega, the One" } 20244.0 "Aft-to-fore Fire/Fore-to-aft Fire" Ability { id: ["AD25", "AD27"], source: "Omega, the One" } 20244.3 "Energy Ray" Ability { id: "AD32", source: "Energy Orb" } From 7c3e8369eac1cdb60053acab35838ad4ae129a7c Mon Sep 17 00:00:00 2001 From: Jacob Keller Date: Thu, 7 May 2026 00:38:35 -0700 Subject: [PATCH 4/6] raidboss: improve timeline for Kam'lanaut Improve the timeline entries for the Kam'lanaut fight, slightly adjusting the timing to better match against my example logs. In addition, remove the element and blade log lines, as it appears these can alternate instead of always repeating the same order. Add GainsEffect log lines for when the elements charge, to help users better predict when they need to pay attention to the charged up element animations. Signed-off-by: Jacob Keller --- .../07-dt/alliance/san-doria-second-walk.txt | 232 ++++++++---------- 1 file changed, 108 insertions(+), 124 deletions(-) diff --git a/ui/raidboss/data/07-dt/alliance/san-doria-second-walk.txt b/ui/raidboss/data/07-dt/alliance/san-doria-second-walk.txt index 77e2f5de81f..69cc2200bff 100644 --- a/ui/raidboss/data/07-dt/alliance/san-doria-second-walk.txt +++ b/ui/raidboss/data/07-dt/alliance/san-doria-second-walk.txt @@ -334,141 +334,125 @@ hideall "--sync--" # The Stellar Fulcrum will be sealed off 30000.0 "--sync--" SystemLogMessage { id: "7DC", param1: "1488" } window 30000,1 -30006.4 "--sync--" StartsUsing { id: "ACBD", source: "Kam'lanaut" } window 30006.4,1 +30006.2 "--sync--" StartsUsing { id: "ACBD", source: "Kam'lanaut" } window 30006.2,1 30011.1 "Enspirited Swordplay" Ability { id: "ACBD", source: "Kam'lanaut" } 30014.3 "--sync--" Ability { id: "ACC1", source: "Kam'lanaut" } -30019.4 "Proving Ground" Ability { id: "B009", source: "Kam'lanaut" } -# TODO: Add sync for elemental buffs? -30032.5 "Elemental Blade" Ability { id: "AC91", source: "Kam'lanaut" } -30043.6 "Sublime Elements" Ability { id: "B00A", source: "Kam'lanaut" } -# TODO: condense sublime elements, based on which of these is "real" -# TODO: verify if the two variants of Sublime Elements can appear in -# different order -30044.6 "Sublime Earth" #Ability { id: "AC94", source: "Kam'lanaut" } -30044.6 "Sublime Fire" #Ability { id: "AC93", source: "Kam'lanaut" } -30044.6 "Sublime Ice" #Ability { id: "AC9C", source: "Kam'lanaut" } -30044.6 "Sublime Lightning" #Ability { id: "AC97", source: "Kam'lanaut" } -30044.6 "Sublime Water" #Ability { id: "AC9B", source: "Kam'lanaut" } -30044.6 "Sublime Wind" #Ability { id: "AC98", source: "Kam'lanaut" } -30054.7 "Elemental Blade" Ability { id: "AC91", source: "Kam'lanaut" } -30065.8 "Sublime Elements" Ability { id: "B00A", source: "Kam'lanaut" } -30066.8 "Earth Blade" #Ability { id: "ACA0", source: "Kam'lanaut" } -30066.8 "Fire Blade" #Ability { id: "AC9F", source: "Kam'lanaut" } -30066.8 "Ice Blade" #Ability { id: "ACA8", source: "Kam'lanaut" } -30066.8 "Lightning Blade" #Ability { id: "ACA9", source: "Kam'lanaut" } -30066.8 "Water Blade" #Ability { id: "ACA1", source: "Kam'lanaut" } -30066.8 "Wind Blade" #Ability { id: "ACA4", source: "Kam'lanaut" } +30019.5 "Proving Ground" Ability { id: "B009", source: "Kam'lanaut" } +30024.7 "Elemental Blade" StartsUsing { id: "AC91", source: "Kam'lanaut" } duration 7.7 +30026.6 "--first charge--" GainsEffect { effectId: "B9A", target: "Kam'lanaut" } +30030.1 "--second charge--" GainsEffect { effectId: "B9A", target: "Kam'lanaut" } +30032.6 "--sync--" Ability { id: "AC91", source: "Kam'lanaut" } +30043.7 "Sublime Elements" Ability { id: "B00A", source: "Kam'lanaut" } +30046.9 "Elemental Blade" StartsUsing { id: "AC91", source: "Kam'lanaut" } duration 7.7 +30048.8 "--first charge--" GainsEffect { effectId: "B9A", target: "Kam'lanaut" } +30052.3 "--second charge--" GainsEffect { effectId: "B9A", target: "Kam'lanaut" } +30054.8 "--sync--" Ability { id: "AC91", source: "Kam'lanaut" } +30065.9 "Sublime Elements" Ability { id: "B00A", source: "Kam'lanaut" } # TODO: Check which ablity hurts? -30076.1 "--sync--" Ability { id: "ACBB", source: "Kam'lanaut" } -30077.1 "Princely Blow" Ability { id: "ACBC", source: "Kam'lanaut" } -30082.2 "Light Blade" Ability { id: "ACAB", source: "Kam'lanaut" } -30088.2 "Sublime Estoc" #Ability { id: "ACAC", source: "Sublime Estoc" } -30088.2 "Sublime Estoc" #Ability { id: "ACAC", source: "Sublime Estoc" } -30091.3 "Great Wheel" Ability { id: ["ACAF", "ACB0"], source: "Kam'lanaut" } -30097.2 "Great Wheel" Ability { id: "ACB1", source: "Kam'lanaut" } -30104.4 "Enspirited Swordplay" Ability { id: "ACBD", source: "Kam'lanaut" } -30111.5 "--sync--" Ability { id: "ACC1", source: "Kam'lanaut" } +30076.2 "--sync--" Ability { id: "ACBB", source: "Kam'lanaut" } +30077.2 "Princely Blow" Ability { id: "ACBC", source: "Kam'lanaut" } +30082.3 "Light Blade" Ability { id: "ACAB", source: "Kam'lanaut" } +30088.3 "Sublime Estoc" #Ability { id: "ACAC", source: "Sublime Estoc" } +30088.3 "Sublime Estoc" #Ability { id: "ACAC", source: "Sublime Estoc" } +30091.4 "Great Wheel" Ability { id: ["ACAF", "ACB0"], source: "Kam'lanaut" } +30097.3 "Great Wheel" Ability { id: "ACB1", source: "Kam'lanaut" } +30104.5 "Enspirited Swordplay" Ability { id: "ACBD", source: "Kam'lanaut" } +30111.6 "--sync--" Ability { id: "ACC1", source: "Kam'lanaut" } # Phase Transition # TODO: Add --untargettable--?? and maybe a duration? -30124.8 "Esoteric Scrivening" Ability { id: "ACB2", source: "Kam'lanaut" } -30129.9 "--sync--" Ability { id: "AD79", source: "Kam'lanaut" } -30143.0 "--sync--" Ability { id: "AD7A", source: "Kam'lanaut" } -30148.2 "Shockwave" Ability { id: "ACB3", source: "Kam'lanaut" } -30148.2 "--sync--" Ability { id: "A2FF", source: "Kam'lanaut" } -30156.8 "Transcendent Union" Ability { id: "ACB4", source: "Kam'lanaut" } -30157.8 "Elemental Edge" #Ability { id: "AD01", source: "Kam'lanaut" } -30158.1 "Elemental Edge" #Ability { id: "AD01", source: "Kam'lanaut" } -30158.4 "Elemental Edge" #Ability { id: "AD01", source: "Kam'lanaut" } -30158.8 "Elemental Edge" #Ability { id: "AD01", source: "Kam'lanaut" } -30159.2 "Elemental Edge" #Ability { id: "AD01", source: "Kam'lanaut" } -30159.9 "Elemental Edge" #Ability { id: "AD01", source: "Kam'lanaut" } -30163.2 "Transcendent Union" Ability { id: "ACB5", source: "Kam'lanaut" } -30174.0 "--sync--" Ability { id: "ACC1", source: "Kam'lanaut" } +30124.9 "Esoteric Scrivening" Ability { id: "ACB2", source: "Kam'lanaut" } +30130.0 "--sync--" Ability { id: "AD79", source: "Kam'lanaut" } +30143.1 "--sync--" Ability { id: "AD7A", source: "Kam'lanaut" } +30148.3 "Shockwave" Ability { id: "ACB3", source: "Kam'lanaut" } +30148.3 "--sync--" Ability { id: "A2FF", source: "Kam'lanaut" } +30156.9 "Transcendent Union" Ability { id: "ACB4", source: "Kam'lanaut" } +30157.9 "Elemental Edge" #Ability { id: "AD01", source: "Kam'lanaut" } +30158.2 "Elemental Edge" #Ability { id: "AD01", source: "Kam'lanaut" } +30158.5 "Elemental Edge" #Ability { id: "AD01", source: "Kam'lanaut" } +30158.9 "Elemental Edge" #Ability { id: "AD01", source: "Kam'lanaut" } +30159.3 "Elemental Edge" #Ability { id: "AD01", source: "Kam'lanaut" } +30160.0 "Elemental Edge" #Ability { id: "AD01", source: "Kam'lanaut" } +30163.4 "Transcendent Union" Ability { id: "ACB5", source: "Kam'lanaut" } +30174.2 "--sync--" Ability { id: "ACC1", source: "Kam'lanaut" } # Phase 2 -30179.2 "Esoteric Palisade" Ability { id: "ACB6", source: "Kam'lanaut" } -30185.3 "Crystalline Resonance" Ability { id: "ACB7", source: "Kam'lanaut" } -30193.2 "Elemental Resonance" Ability { id: "ACB8", source: "Kam'lanaut" } -30200.2 "Elemental Resonance" Ability { id: "ACB8", source: "Kam'lanaut" } -30207.2 "Elemental Resonance" Ability { id: "ACB8", source: "Kam'lanaut" } -30207.4 "Illumed Facet" Ability { id: "ACB9", source: "Kam'lanaut" } -30207.4 "Empyreal Banish III" #Ability { id: "ACBF", source: "Kam'lanaut" } -30218.4 "Illumed Estoc" Ability { id: "ACBA", source: "Kam'lanaut" } -30225.7 "Shield Bash" Ability { id: "ACBE", source: "Kam'lanaut" } +30179.4 "Esoteric Palisade" Ability { id: "ACB6", source: "Kam'lanaut" } +30185.5 "Crystalline Resonance" Ability { id: "ACB7", source: "Kam'lanaut" } +30193.4 "Elemental Resonance" Ability { id: "ACB8", source: "Kam'lanaut" } +30200.4 "Elemental Resonance" Ability { id: "ACB8", source: "Kam'lanaut" } +30207.4 "Elemental Resonance" Ability { id: "ACB8", source: "Kam'lanaut" } +30207.6 "Illumed Facet" Ability { id: "ACB9", source: "Kam'lanaut" } +30207.6 "Empyreal Banish III" #Ability { id: "ACBF", source: "Kam'lanaut" } +30218.5 "Illumed Estoc" Ability { id: "ACBA", source: "Kam'lanaut" } +30225.8 "Shield Bash" Ability { id: "ACBE", source: "Kam'lanaut" } # TODO: check which of these matters -30234.8 "Empyreal Banish IV" Ability { id: "AF6B", source: "Kam'lanaut" } -30235.8 "Empyreal Banish IV" Ability { id: "ACC0", source: "Kam'lanaut" } -30245.1 "--sync--" Ability { id: "ACBB", source: "Kam'lanaut" } -30246.1 "Princely Blow" Ability { id: "ACBC", source: "Kam'lanaut" } -30255.2 "--sync--" Ability { id: "ACC1", source: "Kam'lanaut" } -30260.3 "Proving Ground" Ability { id: "B009", source: "Kam'lanaut" } -30274.4 "Elemental Blade" Ability { id: "AC92", source: "Kam'lanaut" } -30285.5 "Sublime Elements" Ability { id: "B00A", source: "Kam'lanaut" } -30286.5 "Sublime Earth" #Ability { id: "AC94", source: "Kam'lanaut" } -30286.5 "Sublime Fire" #Ability { id: "AC99", source: "Kam'lanaut" } -30286.5 "Sublime Ice" #Ability { id: "AC9C", source: "Kam'lanaut" } -30286.5 "Sublime Lightning" #Ability { id: "AC9D", source: "Kam'lanaut" } -30286.5 "Sublime Water" #Ability { id: "AC95", source: "Kam'lanaut" } -30286.5 "Sublime Wind" #Ability { id: "AC98", source: "Kam'lanaut" } -30292.6 "Light Blade" Ability { id: "ACAB", source: "Kam'lanaut" } -30298.6 "Sublime Estoc" #Ability { id: "ACAC", source: "Sublime Estoc" } -30298.6 "Sublime Estoc" #Ability { id: "ACAC", source: "Sublime Estoc" } -30298.6 "Empyreal Banish III" Ability { id: "ACBF", source: "Kam'lanaut" } -30301.7 "Great Wheel" Ability { id: ["ACAD", "ACAE", "ACAF", "ACB0"], source: "Kam'lanaut" } -30307.6 "Great Wheel" Ability { id: "ACB1", source: "Kam'lanaut" } -30307.7 "Empyreal Banish IV" Ability { id: "ACC0", source: "Kam'lanaut" } -30314.8 "Enspirited Swordplay" Ability { id: "ACBD", source: "Kam'lanaut" } -30322.0 "--sync--" Ability { id: "ACC1", source: "Kam'lanaut" } +30234.9 "Empyreal Banish IV" Ability { id: "AF6B", source: "Kam'lanaut" } +30235.9 "Empyreal Banish IV" Ability { id: "ACC0", source: "Kam'lanaut" } +30245.2 "--sync--" Ability { id: "ACBB", source: "Kam'lanaut" } +30246.2 "Princely Blow" Ability { id: "ACBC", source: "Kam'lanaut" } +30255.4 "--sync--" Ability { id: "ACC1", source: "Kam'lanaut" } +30260.5 "Proving Ground" Ability { id: "B009", source: "Kam'lanaut" } +30263.7 "Elemental Blade" StartsUsing { id: "AC92", source: "Kam'lanaut" } duration 10.7 +30265.6 "--first charge--" GainsEffect { effectId: "B9A", target: "Kam'lanaut" } +30269.1 "--second charge--" GainsEffect { effectId: "B9A", target: "Kam'lanaut" } +30272.6 "--third charge--" GainsEffect { effectId: "B9A", target: "Kam'lanaut" } +30274.7 "--sync--" Ability { id: "AC92", source: "Kam'lanaut" } +30285.8 "Sublime Elements" Ability { id: "B00A", source: "Kam'lanaut" } +30292.9 "Light Blade" Ability { id: "ACAB", source: "Kam'lanaut" } +30298.9 "Sublime Estoc" #Ability { id: "ACAC", source: "Sublime Estoc" } +30298.9 "Sublime Estoc" #Ability { id: "ACAC", source: "Sublime Estoc" } +30298.9 "Empyreal Banish III" Ability { id: "ACBF", source: "Kam'lanaut" } +30302.0 "Great Wheel" Ability { id: ["ACAD", "ACAE", "ACAF", "ACB0"], source: "Kam'lanaut" } +30307.9 "Great Wheel" Ability { id: "ACB1", source: "Kam'lanaut" } +30308.0 "Empyreal Banish IV" Ability { id: "ACC0", source: "Kam'lanaut" } +30315.1 "Enspirited Swordplay" Ability { id: "ACBD", source: "Kam'lanaut" } +30322.3 "--sync--" Ability { id: "ACC1", source: "Kam'lanaut" } # Phase 2 Loop Start -30327.2 label "kamlanaut-loop" -30327.2 "Esoteric Palisade" Ability { id: "ACB6", source: "Kam'lanaut" } -30333.3 "Crystalline Resonance" Ability { id: "ACB7", source: "Kam'lanaut" } -30341.2 "Elemental Resonance" Ability { id: "ACB8", source: "Kam'lanaut" } -30348.2 "Elemental Resonance" Ability { id: "ACB8", source: "Kam'lanaut" } -30355.2 "Elemental Resonance" Ability { id: "ACB8", source: "Kam'lanaut" } -30358.4 "Light Blade" Ability { id: "ACAB", source: "Kam'lanaut" } -30364.4 "Sublime Estoc" #Ability { id: "ACAC", source: "Sublime Estoc" } -30364.4 "Sublime Estoc" #Ability { id: "ACAC", source: "Sublime Estoc" } -30364.4 "Empyreal Banish III" Ability { id: "ACBF", source: "Kam'lanaut" } -30371.2 "Elemental Resonance" Ability { id: "ACB8", source: "Kam'lanaut" } -30372.8 "Illumed Facet" Ability { id: "ACB9", source: "Kam'lanaut" } -30382.9 "Shield Bash" Ability { id: "ACBE", source: "Kam'lanaut" } -30383.7 "Illumed Estoc" Ability { id: "ACBA", source: "Kam'lanaut" } -30392.1 "Empyreal Banish IV" Ability { id: "AF6B", source: "Kam'lanaut" } -30393.1 "Empyreal Banish IV" Ability { id: "ACC0", source: "Kam'lanaut" } -30398.2 "Proving Ground" Ability { id: "B009", source: "Kam'lanaut" } -30412.3 "Elemental Blade" Ability { id: "AC92", source: "Kam'lanaut" } -30423.4 "Sublime Elements" Ability { id: "B00A", source: "Kam'lanaut" } -30424.4 "Earth Blade" #Ability { id: "ACA6", source: "Kam'lanaut" } -30424.4 "Fire Blade" #Ability { id: "ACA5", source: "Kam'lanaut" } -30424.4 "Ice Blade" #Ability { id: "ACA2", source: "Kam'lanaut" } -30424.4 "Lightning Blade" #Ability { id: "ACA3", source: "Kam'lanaut" } -30424.4 "Water Blade" #Ability { id: "ACA1", source: "Kam'lanaut" } -30424.4 "Wind Blade" #Ability { id: "ACAA", source: "Kam'lanaut" } -30431.5 "Enspirited Swordplay" Ability { id: "ACBD", source: "Kam'lanaut" } -30441.8 "--sync--" Ability { id: "ACBB", source: "Kam'lanaut" } -30442.8 "Princely Blow" Ability { id: "ACBC", source: "Kam'lanaut" } -30452.0 "--sync--" Ability { id: "ACC1", source: "Kam'lanaut" } -30457.1 "Proving Ground" Ability { id: "B009", source: "Kam'lanaut" } -30471.2 "Elemental Blade" Ability { id: "AC92", source: "Kam'lanaut" } -30482.3 "Sublime Elements" Ability { id: "B00A", source: "Kam'lanaut" } -30483.3 "Sublime Earth" #Ability { id: "AC94", source: "Kam'lanaut" } -30483.3 "Sublime Fire" #Ability { id: "AC99", source: "Kam'lanaut" } -30483.3 "Sublime Ice" #Ability { id: "AC9C", source: "Kam'lanaut" } -30483.3 "Sublime Lightning" #Ability { id: "AC9D", source: "Kam'lanaut" } -30483.3 "Sublime Water" #Ability { id: "AC95", source: "Kam'lanaut" } -30483.3 "Sublime Wind" #Ability { id: "AC98", source: "Kam'lanaut" } -30489.4 "Light Blade" Ability { id: "ACAB", source: "Kam'lanaut" } -30495.4 "Sublime Estoc" Ability { id: "ACAC", source: "Sublime Estoc" } -30495.4 "Empyreal Banish III" Ability { id: "ACBF", source: "Kam'lanaut" } -30498.5 "Great Wheel" Ability { id: ["ACAD", "ACAE", "ACAF", "ACB0"], source: "Kam'lanaut" } -30504.4 "Great Wheel" Ability { id: "ACB1", source: "Kam'lanaut" } -30504.5 "Empyreal Banish IV" Ability { id: "ACC0", source: "Kam'lanaut" } -30511.6 "Enspirited Swordplay" Ability { id: "ACBD", source: "Kam'lanaut" } -30518.8 "--sync--" Ability { id: "ACC1", source: "Kam'lanaut" } -30524.0 "Esoteric Palisade" Ability { id: "ACB6", source: "Kam'lanaut" } window 30,30 forcejump "kamlanaut-loop" +30327.5 label "kamlanaut-loop" +30327.5 "Esoteric Palisade" Ability { id: "ACB6", source: "Kam'lanaut" } +30333.6 "Crystalline Resonance" Ability { id: "ACB7", source: "Kam'lanaut" } +30341.5 "Elemental Resonance" Ability { id: "ACB8", source: "Kam'lanaut" } +30348.5 "Elemental Resonance" Ability { id: "ACB8", source: "Kam'lanaut" } +30355.5 "Elemental Resonance" Ability { id: "ACB8", source: "Kam'lanaut" } +30358.7 "Light Blade" Ability { id: "ACAB", source: "Kam'lanaut" } +30364.7 "Sublime Estoc" #Ability { id: "ACAC", source: "Sublime Estoc" } +30364.7 "Sublime Estoc" #Ability { id: "ACAC", source: "Sublime Estoc" } +30364.7 "Empyreal Banish III" Ability { id: "ACBF", source: "Kam'lanaut" } +30371.5 "Elemental Resonance" Ability { id: "ACB8", source: "Kam'lanaut" } +30373.1 "Illumed Facet" Ability { id: "ACB9", source: "Kam'lanaut" } +30383.2 "Shield Bash" Ability { id: "ACBE", source: "Kam'lanaut" } +30384.0 "Illumed Estoc" Ability { id: "ACBA", source: "Kam'lanaut" } +30392.4 "Empyreal Banish IV" Ability { id: "AF6B", source: "Kam'lanaut" } +30393.4 "Empyreal Banish IV" Ability { id: "ACC0", source: "Kam'lanaut" } +30398.5 "Proving Ground" Ability { id: "B009", source: "Kam'lanaut" } +30401.7 "Elemental Blade" StartsUsing { id: "AC92", source: "Kam'lanaut" } duration 10.7 +30403.6 "--first charge--" GainsEffect { effectId: "B9A", target: "Kam'lanaut" } +30407.1 "--second charge--" GainsEffect { effectId: "B9A", target: "Kam'lanaut" } +30410.6 "--third charge--" GainsEffect { effectId: "B9A", target: "Kam'lanaut" } +30412.7 "--sync--" Ability { id: "AC92", source: "Kam'lanaut" } +30423.8 "Sublime Elements" Ability { id: "B00A", source: "Kam'lanaut" } +30431.9 "Enspirited Swordplay" Ability { id: "ACBD", source: "Kam'lanaut" } +30442.2 "--sync--" Ability { id: "ACBB", source: "Kam'lanaut" } +30443.2 "Princely Blow" Ability { id: "ACBC", source: "Kam'lanaut" } +30452.4 "--sync--" Ability { id: "ACC1", source: "Kam'lanaut" } +30457.5 "Proving Ground" Ability { id: "B009", source: "Kam'lanaut" } +30460.9 "Elemental Blade" StartsUsing { id: "AC92", source: "Kam'lanaut" } duration 10.7 +30462.6 "--first charge--" GainsEffect { effectId: "B9A", target: "Kam'lanaut" } +30466.1 "--second charge--" GainsEffect { effectId: "B9A", target: "Kam'lanaut" } +30469.6 "--third charge--" GainsEffect { effectId: "B9A", target: "Kam'lanaut" } +30471.6 "--sync--" Ability { id: "AC92", source: "Kam'lanaut" } +30482.7 "Sublime Elements" Ability { id: "B00A", source: "Kam'lanaut" } +30489.8 "Light Blade" Ability { id: "ACAB", source: "Kam'lanaut" } +30495.8 "Sublime Estoc" Ability { id: "ACAC", source: "Sublime Estoc" } +30495.8 "Empyreal Banish III" Ability { id: "ACBF", source: "Kam'lanaut" } +30498.9 "Great Wheel" Ability { id: ["ACAD", "ACAE", "ACAF", "ACB0"], source: "Kam'lanaut" } +30504.8 "Great Wheel" Ability { id: "ACB1", source: "Kam'lanaut" } +30504.9 "Empyreal Banish IV" Ability { id: "ACC0", source: "Kam'lanaut" } +30512.0 "Enspirited Swordplay" Ability { id: "ACBD", source: "Kam'lanaut" } +30519.2 "--sync--" Ability { id: "ACC1", source: "Kam'lanaut" } +30524.4 "Esoteric Palisade" Ability { id: "ACB6", source: "Kam'lanaut" } window 30,30 forcejump "kamlanaut-loop" # IGNORED ABILITIES # AF4C --sync-- From 2c6f32bedc3585b7bacda9f980fee635a8a7d25d Mon Sep 17 00:00:00 2001 From: Jacob Keller Date: Thu, 7 May 2026 00:54:00 -0700 Subject: [PATCH 5/6] raidboss: more improvements for ultima/omega timeline Signed-off-by: Jacob Keller --- .../07-dt/alliance/san-doria-second-walk.txt | 80 +++++++++---------- 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/ui/raidboss/data/07-dt/alliance/san-doria-second-walk.txt b/ui/raidboss/data/07-dt/alliance/san-doria-second-walk.txt index 69cc2200bff..8e2e4cb7235 100644 --- a/ui/raidboss/data/07-dt/alliance/san-doria-second-walk.txt +++ b/ui/raidboss/data/07-dt/alliance/san-doria-second-walk.txt @@ -181,17 +181,17 @@ hideall "--sync--" # Armada Airship will be sealed off 20000.0 "--sync--" SystemLogMessage { id: "7DC", param1: "14B2" } window 20000,1 -20005.5 "--sync--" StartsUsing { id: "AD2B", source: "Omega, the One" } window 20005.5,10 +20005.2 "--sync--" StartsUsing { id: "AD2B", source: "Omega, the One" } window 20005.2,10 20011.7 "Ion Efflux" Ability { id: "AD2B", source: "Omega, the One" } 20015.5 "--sync--" Ability { id: "AD10", source: "Ultima, the Feared" } 20016.5 "Antimatter" Ability { id: "AD11", source: "Ultima, the Feared" } 20020.6 "Energy Orb" Ability { id: "AD08", source: "Ultima, the Feared" } 20028.8 "Energy Ray" Ability { id: "AD32", source: "Energy Orb" } 20031.8 "Aft-to-fore Fire/Fore-to-aft Fire" Ability { id: ["AD25", "AD27"], source: "Omega, the One" } -20032.4 "Omega Blaster" Ability { id: "AD29", source: "Omega, the One" } -20034.0 "Foreward Blaster/Aftward Blaster" Ability { id: ["AD26", "AD28"], source: "Omega, the One" } -20034.8 "Omega Blaster" Ability { id: "AD2A", source: "Omega, the One" } -20048.4 "Tractor Beam" Ability { id: "AD06", source: "Ultima, the Feared" } +20032.3 "Omega Blaster" Ability { id: "AD29", source: "Omega, the One" } +20033.9 "Foreward Blaster/Aftward Blaster" Ability { id: ["AD26", "AD28"], source: "Omega, the One" } +20034.7 "Omega Blaster" Ability { id: "AD2A", source: "Omega, the One" } +20048.3 "Tractor Beam" Ability { id: "AD06", source: "Ultima, the Feared" } 20048.6 "Anti-personnel Missile" Ability { id: "B087", source: "Omega, the One" } 20048.8 "Crash" Ability { id: "AD07", source: "Ultima, the Feared" } 20048.8 "Tractor Beam" #Ability { id: "B086", source: "Ultima, the Feared" } @@ -201,28 +201,28 @@ hideall "--sync--" 20067.9 "Energy Orb" Ability { id: "AD08", source: "Ultima, the Feared" } 20069.0 "Surface Missile" #Ability { id: "B076", source: "Omega, the One" } 20071.0 "Surface Missile" #Ability { id: "B076", source: "Omega, the One" } -20075.0 "Anti-personnel Missile" Ability { id: "B087", source: "Omega, the One" } -20076.0 "Energy Ray" Ability { id: "AD32", source: "Energy Orb" } -20080.0 "Anti-personnel Missile" #Ability { id: "B088", source: "Omega, the One" } -20080.0 "Anti-personnel Missile" #Ability { id: "B088", source: "Omega, the One" } -20083.0 "Mana Screen" Ability { id: "AD09", source: "Ultima, the Feared" } -20088.1 "Energy Orb" Ability { id: "AD08", source: "Ultima, the Feared" } -20096.3 "Energy Ray" Ability { id: "AD32", source: "Energy Orb" } -20097.1 "Energy Ray" #Ability { id: "AD0D", source: "Ultima, the Feared" } -20102.0 "Trajectory Projection" Ability { id: "AD23", source: "Omega, the One" } -20112.7 "Guided Missile" Ability { id: "AD24", source: "Omega, the One" } -20118.2 "--untargetable--" Ability { id: "AD12", source: "Ultima, the Feared" } -20118.3 "--jump--" Ability { id: "AD2C", source: "Omega, the One" } +20075.2 "Anti-personnel Missile" Ability { id: "B087", source: "Omega, the One" } +20076.2 "Energy Ray" Ability { id: "AD32", source: "Energy Orb" } +20080.2 "Anti-personnel Missile" #Ability { id: "B088", source: "Omega, the One" } +20080.2 "Anti-personnel Missile" #Ability { id: "B088", source: "Omega, the One" } +20083.3 "Mana Screen" Ability { id: "AD09", source: "Ultima, the Feared" } +20088.4 "Energy Orb" Ability { id: "AD08", source: "Ultima, the Feared" } +20096.6 "Energy Ray" Ability { id: "AD32", source: "Energy Orb" } +20097.4 "Energy Ray" #Ability { id: "AD0D", source: "Ultima, the Feared" } +20102.1 "Trajectory Projection" Ability { id: "AD23", source: "Omega, the One" } +20112.8 "Guided Missile" Ability { id: "AD24", source: "Omega, the One" } +20118.3 "--untargetable--" Ability { id: "AD12", source: "Ultima, the Feared" } +20118.4 "--jump--" Ability { id: "AD2C", source: "Omega, the One" } # Jump from the airship before it's reduced to ash! -20118.3 "Tractor Field" Ability { id: "AD12", source: "Ultima, the Feared" } -20118.7 "Tractor Field" Ability { id: "AD13", source: "Ultima, the Feared" } -20123.6 "Multi-missile" Ability { id: "AFEB", source: "Omega, the One" } -20123.6 "Citadel Siege" Ability { id: "AD14", source: "Ultima, the Feared" } -20125.4 "Multi-missile" Ability { id: "AFED", source: "Omega, the One" } -20125.5 "Multi-missile" Ability { id: "AFEC", source: "Omega, the One" } -20127.6 "Citadel Siege" Ability { id: "AD15", source: "Ultima, the Feared" } -20127.7 "Multi-missile" Ability { id: "AFEB", source: "Omega, the One" } +20118.4 "Tractor Field" Ability { id: "AD12", source: "Ultima, the Feared" } +20118.8 "Tractor Field" Ability { id: "AD13", source: "Ultima, the Feared" } +20123.7 "Multi-missile" Ability { id: "AFEB", source: "Omega, the One" } +20123.7 "Citadel Siege" Ability { id: "AD14", source: "Ultima, the Feared" } +20125.5 "Multi-missile" Ability { id: "AFED", source: "Omega, the One" } +20125.6 "Multi-missile" Ability { id: "AFEC", source: "Omega, the One" } +20127.7 "Citadel Siege" Ability { id: "AD15", source: "Ultima, the Feared" } +20127.8 "Multi-missile" Ability { id: "AFEB", source: "Omega, the One" } 20128.6 "Citadel Siege" Ability { id: "AD18", source: "Ultima, the Feared" } 20129.6 "Multi-missile" Ability { id: "AFED", source: "Omega, the One" } 20129.7 "Multi-missile" Ability { id: "AFEC", source: "Omega, the One" } @@ -262,21 +262,21 @@ hideall "--sync--" 20218.5 "Chemical Bomb" Ability { id: "AD0F", source: "Ultima, the Feared" } 20221.5 "Chemical Bomb" Ability { id: "AD0F", source: "Ultima, the Feared" } 20224.5 "Chemical Bomb" Ability { id: "AD0F", source: "Ultima, the Feared" } -20233.2 "Surface Missile" Ability { id: "B075", source: "Omega, the One" } -20234.2 "Surface Missile" #Ability { id: "B076", source: "Omega, the One" } -20236.2 "Energy Orb" Ability { id: "AD08", source: "Ultima, the Feared" } -20236.2 "Surface Missile" #Ability { id: "B076", source: "Omega, the One" } -20238.2 "Surface Missile" #Ability { id: "B076", source: "Omega, the One" } -20244.0 "Aft-to-fore Fire/Fore-to-aft Fire" Ability { id: ["AD25", "AD27"], source: "Omega, the One" } -20244.3 "Energy Ray" Ability { id: "AD32", source: "Energy Orb" } -20244.4 "Omega Blaster" Ability { id: "AD29", source: "Omega, the One" } -20246.1 "Foreward Blaster/Aftward Blaster" Ability { id: ["AD26", "AD28"], source: "Omega, the One" } -20246.9 "Omega Blaster" Ability { id: "AD2A", source: "Omega, the One" } -20262.9 "Ion Efflux" Ability { id: "AD2B", source: "Omega, the One" } -20274.6 "Antimatter" Ability { id: "AD10", source: "Ultima, the Feared" } -20275.6 "Antimatter" Ability { id: "AD11", source: "Ultima, the Feared" } -20293.6 "Tractor Beam" Ability { id: "AD06", source: "Ultima, the Feared" } window 30,30 forcejump "ultima-omega-p2-loop" -20342.5 "Chemical Bomb" Ability { id: "AD0F", source: "Ultima, the Feared" } +20233.1 "Surface Missile" Ability { id: "B075", source: "Omega, the One" } +20234.1 "Surface Missile" #Ability { id: "B076", source: "Omega, the One" } +20236.3 "Energy Orb" Ability { id: "AD08", source: "Ultima, the Feared" } +20236.3 "Surface Missile" #Ability { id: "B076", source: "Omega, the One" } +20238.3 "Surface Missile" #Ability { id: "B076", source: "Omega, the One" } +20244.1 "Aft-to-fore Fire/Fore-to-aft Fire" Ability { id: ["AD25", "AD27"], source: "Omega, the One" } +20244.5 "Energy Ray" Ability { id: "AD32", source: "Energy Orb" } +20244.6 "Omega Blaster" Ability { id: "AD29", source: "Omega, the One" } +20246.3 "Foreward Blaster/Aftward Blaster" Ability { id: ["AD26", "AD28"], source: "Omega, the One" } +20247.1 "Omega Blaster" Ability { id: "AD2A", source: "Omega, the One" } +20263.1 "Ion Efflux" Ability { id: "AD2B", source: "Omega, the One" } +20274.8 "Antimatter" Ability { id: "AD10", source: "Ultima, the Feared" } +20275.8 "Antimatter" Ability { id: "AD11", source: "Ultima, the Feared" } +20293.8 "Tractor Beam" Ability { id: "AD06", source: "Ultima, the Feared" } window 30,30 forcejump "ultima-omega-p2-loop" +20342.7 "Chemical Bomb" Ability { id: "AD0F", source: "Ultima, the Feared" } # IGNORED ABILITIES # AD1D --sync-- From 37850f48902b0dad21455343f950e8c73780aba8 Mon Sep 17 00:00:00 2001 From: Jacob Keller Date: Thu, 7 May 2026 01:08:24 -0700 Subject: [PATCH 6/6] raidboss: timeline improvements for Eald'narche Signed-off-by: Jacob Keller --- .../07-dt/alliance/san-doria-second-walk.txt | 116 +++++++++--------- 1 file changed, 58 insertions(+), 58 deletions(-) diff --git a/ui/raidboss/data/07-dt/alliance/san-doria-second-walk.txt b/ui/raidboss/data/07-dt/alliance/san-doria-second-walk.txt index 8e2e4cb7235..6fc46952b65 100644 --- a/ui/raidboss/data/07-dt/alliance/san-doria-second-walk.txt +++ b/ui/raidboss/data/07-dt/alliance/san-doria-second-walk.txt @@ -334,7 +334,7 @@ hideall "--sync--" # The Stellar Fulcrum will be sealed off 30000.0 "--sync--" SystemLogMessage { id: "7DC", param1: "1488" } window 30000,1 -30006.2 "--sync--" StartsUsing { id: "ACBD", source: "Kam'lanaut" } window 30006.2,1 +30006.0 "--sync--" StartsUsing { id: "ACBD", source: "Kam'lanaut" } window 30006,1 30011.1 "Enspirited Swordplay" Ability { id: "ACBD", source: "Kam'lanaut" } 30014.3 "--sync--" Ability { id: "ACC1", source: "Kam'lanaut" } 30019.5 "Proving Ground" Ability { id: "B009", source: "Kam'lanaut" } @@ -519,13 +519,13 @@ hideall "--sync--" # Phase 1 40000.0 "--sync--" SystemLogMessage { id: "7DC", param1: "148A" } window 40000,1 -40006.4 "--sync--" StartsUsing { id: "AD51", source: "Eald'narche" } window 40006.4,1 +40006.2 "--sync--" StartsUsing { id: "AD51", source: "Eald'narche" } window 40006.2,1 40010.1 "--sync--" Ability { id: "AD51", source: "Eald'narche" } 40011.1 "Uranos Cascade" Ability { id: "AD52", source: "Eald'narche" } 40023.2 "Cronos Sling" Ability { id: ["AD49", "AD4A", "AD4B", "AD4C"], source: "Eald'narche" } 40023.6 "--sync--" Ability { id: ["AD4D", "AD4E"], source: "Eald'narche" } -40029.5 "Cronos Sling" Ability { id: ["AD4F", "AD50"], source: "Eald'narche" } -40039.8 "Empyreal Vortex" Ability { id: "AD6D", source: "Eald'narche" } duration 5.8 +40029.4 "Cronos Sling" Ability { id: ["AD4F", "AD50"], source: "Eald'narche" } +40039.7 "Empyreal Vortex" Ability { id: "AD6D", source: "Eald'narche" } duration 5.8 40045.6 "--sync--" Ability { id: "AD70", source: "Eald'narche" } 40056.9 "Cronos Sling" Ability { id: ["AD49", "AD4A", "AD4B", "AD4C"], source: "Eald'narche" } 40057.3 "--sync--" Ability { id: ["AD4D", "AD4E"], source: "Eald'narche" } @@ -535,13 +535,13 @@ hideall "--sync--" 40077.0 "Sleepga" Ability { id: "AD58", source: "Eald'narche" } 40079.1 "--sync--" Ability { id: "AD48", source: "Eald'narche" } 40084.4 "Gaea Stream" Ability { id: "AD53", source: "Eald'narche" } duration 11.1 -40090.7 "--sync--" StartsUsing { id: "AD5C", source: "Eald'narche" } window 5,5 -40094.4 "Omega Javelin" Ability { id: "AD5C", source: "Eald'narche" } -40095.5 "--sync--" Ability { id: "AD5D", source: "Eald'narche" } -40099.9 "Omega Javelin" Ability { id: "AD5E", source: "Eald'narche" } -40105.6 "Duplicate" Ability { id: "AD77", source: "Eald'narche" } duration 26.2 +40090.6 "--sync--" StartsUsing { id: "AD5C", source: "Eald'narche" } window 5,5 +40094.5 "Omega Javelin" Ability { id: "AD5C", source: "Eald'narche" } +40095.6 "--sync--" Ability { id: "AD5D", source: "Eald'narche" } +40100.0 "Omega Javelin" Ability { id: "AD5E", source: "Eald'narche" } +40105.6 "Duplicate" Ability { id: "AD77", source: "Eald'narche" } duration 11.1 40116.7 "--sync--" Ability { id: "AD78", source: "Eald'narche" } -40120.7 "--sync--" Ability { id: "AD77", source: "Eald'narche" } +40120.7 "Duplicate" Ability { id: "AD77", source: "Eald'narche" } duration 11.1 40131.8 "--sync--" Ability { id: "AD78", source: "Eald'narche" } 40140.8 "--sync--" Ability { id: "AD48", source: "Eald'narche" } 40150.1 "Excelsior" Ability { id: "B040", source: "Eald'narche" } @@ -554,61 +554,61 @@ hideall "--sync--" # Phase 2 Begins 40189.6 "Duplicate" Ability { id: "AD77", source: "Eald'narche" } duration 13.1 40198.7 "Visions of Paradise" Ability { id: "AD75", source: "Eald'narche" } -40207.7 "Stellar Burst" Ability { id: "AD72", source: "Eald'narche" } -40207.7 "--sync--" Ability { id: "AD7D", source: "Eald'narche" } -40208.7 "Stellar Burst" Ability { id: "AD73", source: "Eald'narche" } -40215.4 "Stellar Burst" Ability { id: "AD74", source: "Eald'narche" } -40224.0 "--sync--" Ability { id: "AD48", source: "Eald'narche" } +40207.8 "Stellar Burst" Ability { id: "AD72", source: "Eald'narche" } +40207.8 "--sync--" Ability { id: "AD7D", source: "Eald'narche" } +40208.8 "Stellar Burst" Ability { id: "AD73", source: "Eald'narche" } +40215.5 "Stellar Burst" Ability { id: "AD74", source: "Eald'narche" } +40224.1 "--sync--" Ability { id: "AD48", source: "Eald'narche" } # TODO: There are many variations of Ancient Triad which are not really # worth creating branching timelines for. Just use a duration to indicate # that mechanics are ongoing. Note that this duration likely isn't accurate # for every variation, however the mechanics should mostly be done resolving # by this time. -40232.3 "Ancient Triad" Ability { id: "AD5F", source: "Eald'narche" } duration 10.7 -40248.0 "Gaea Stream" Ability { id: "AD53", source: "Eald'narche" } duration 17 -40263.1 "--sync--" StartsUsing { id: "AD51", source: "Eald'narche" } window 15,5 -40266.8 "--sync--" Ability { id: "AD51", source: "Eald'narche" } -40267.8 "Uranos Cascade" Ability { id: "AD52", source: "Eald'narche" } -40273.9 "Duplicate" Ability { id: "AD77", source: "Eald'narche" } duration 13.1 -40283.0 "Visions of Paradise" Ability { id: "AD75", source: "Eald'narche" } +40232.4 "Ancient Triad" Ability { id: "AD5F", source: "Eald'narche" } duration 10.7 +40248.1 "Gaea Stream" Ability { id: "AD53", source: "Eald'narche" } duration 17 +40263.2 "--sync--" StartsUsing { id: "AD51", source: "Eald'narche" } window 15,5 +40266.9 "--sync--" Ability { id: "AD51", source: "Eald'narche" } +40267.9 "Uranos Cascade" Ability { id: "AD52", source: "Eald'narche" } +40274.0 "Duplicate" Ability { id: "AD77", source: "Eald'narche" } duration 13.1 +40283.1 "Visions of Paradise" Ability { id: "AD75", source: "Eald'narche" } # Phase 2 Loop -40292.0 label "ealdnarche-phase-2-loop" -40292.0 "Omega Javelin" Ability { id: "AD5C", source: "Eald'narche" } -40293.1 "--sync--" Ability { id: "AD5D", source: "Eald'narche" } -40295.1 "--sync--" Ability { id: "AD48", source: "Eald'narche" } -40297.5 "Omega Javelin" Ability { id: "AD5E", source: "Eald'narche" } -40300.5 "Gaea Stream" Ability { id: "AD53", source: "Eald'narche" } duration 17 -40313.5 "Cronos Sling" Ability { id: ["AD49", "AD4A", "AD4B", "AD4C"], source: "Eald'narche" } -40313.9 "--sync--" Ability { id: ["AD4D", "AD4E"], source: "Eald'narche" } -40319.6 "Cronos Sling" Ability { id: ["AD4F", "AD50"], source: "Eald'narche" } -40327.5 "Stellar Burst" Ability { id: "AD72", source: "Eald'narche" } -40327.5 "--sync--" Ability { id: "AD7D", source: "Eald'narche" } -40328.5 "Stellar Burst" Ability { id: "AD73", source: "Eald'narche" } -40335.2 "Stellar Burst" Ability { id: "AD74", source: "Eald'narche" } -40342.9 "--sync--" Ability { id: "AD48", source: "Eald'narche" } -40351.0 "Ancient Triad" Ability { id: "AD5F", source: "Eald'narche" } duration 10.7 -40359.7 "Duplicate" Ability { id: "AD77", source: "Eald'narche" } duration 13.1 -40368.9 "Visions of Paradise" Ability { id: "AD75", source: "Eald'narche" } -40373.0 "--sync--" Ability { id: "AD76", source: "Eald'narche" } -40377.0 "Empyreal Vortex" Ability { id: "AD6D", source: "Eald'narche" } duration 5.8 -40382.8 "--sync--" Ability { id: "AD70", source: "Eald'narche" } -40386.6 "Warp" Ability { id: "AD56", source: "Eald'narche" } -40387.3 "--sync--" Ability { id: "AD48", source: "Eald'narche" } -40393.2 "Sleepga" Ability { id: "AD58", source: "Eald'narche" } -40395.3 "--sync--" Ability { id: "AD48", source: "Eald'narche" } -40401.6 "Omega Javelin" Ability { id: "AD5C", source: "Eald'narche" } -40402.7 "--sync--" Ability { id: "AD5D", source: "Eald'narche" } -40407.1 "Omega Javelin" Ability { id: "AD5E", source: "Eald'narche" } -40411.7 "Cronos Sling" Ability { id: ["AD49", "AD4A", "AD4B", "AD4C"], source: "Eald'narche" } -40412.1 "--sync--" Ability { id: ["AD4D", "AD4E"], source: "Eald'narche" } -40417.9 "Cronos Sling" Ability { id: ["AD4F", "AD50"], source: "Eald'narche" } -40429.2 "--sync--" Ability { id: "AD51", source: "Eald'narche" } -40430.2 "Uranos Cascade" Ability { id: "AD52", source: "Eald'narche" } -40444.3 "Duplicate" Ability { id: "AD77", source: "Eald'narche" } duration 13.1 -40453.4 "Visions of Paradise" Ability { id: "AD75", source: "Eald'narche" } -40457.5 "--sync--" Ability { id: "AD76", source: "Eald'narche" } -40462.5 "Omega Javelin" Ability { id: "AD5C", source: "Eald'narche" } forcejump "ealdnarche-phase-2-loop" +40292.2 label "ealdnarche-phase-2-loop" +40292.2 "Omega Javelin" Ability { id: "AD5C", source: "Eald'narche" } +40293.3 "--sync--" Ability { id: "AD5D", source: "Eald'narche" } +40295.3 "--sync--" Ability { id: "AD48", source: "Eald'narche" } +40297.7 "Omega Javelin" Ability { id: "AD5E", source: "Eald'narche" } +40300.6 "Gaea Stream" Ability { id: "AD53", source: "Eald'narche" } duration 17 +40313.7 "Cronos Sling" Ability { id: ["AD49", "AD4A", "AD4B", "AD4C"], source: "Eald'narche" } +40314.1 "--sync--" Ability { id: ["AD4D", "AD4E"], source: "Eald'narche" } +40319.8 "Cronos Sling" Ability { id: ["AD4F", "AD50"], source: "Eald'narche" } +40327.7 "Stellar Burst" Ability { id: "AD72", source: "Eald'narche" } +40327.7 "--sync--" Ability { id: "AD7D", source: "Eald'narche" } +40328.7 "Stellar Burst" Ability { id: "AD73", source: "Eald'narche" } +40335.4 "Stellar Burst" Ability { id: "AD74", source: "Eald'narche" } +40343.1 "--sync--" Ability { id: "AD48", source: "Eald'narche" } +40351.2 "Ancient Triad" Ability { id: "AD5F", source: "Eald'narche" } duration 10.7 +40359.9 "Duplicate" Ability { id: "AD77", source: "Eald'narche" } duration 13.1 +40369.1 "Visions of Paradise" Ability { id: "AD75", source: "Eald'narche" } +40373.2 "--sync--" Ability { id: "AD76", source: "Eald'narche" } +40377.2 "Empyreal Vortex" Ability { id: "AD6D", source: "Eald'narche" } duration 5.8 +40383.1 "--sync--" Ability { id: "AD70", source: "Eald'narche" } +40386.9 "Warp" Ability { id: "AD56", source: "Eald'narche" } +40387.6 "--sync--" Ability { id: "AD48", source: "Eald'narche" } +40393.5 "Sleepga" Ability { id: "AD58", source: "Eald'narche" } +40395.6 "--sync--" Ability { id: "AD48", source: "Eald'narche" } +40401.9 "Omega Javelin" Ability { id: "AD5C", source: "Eald'narche" } +40403.0 "--sync--" Ability { id: "AD5D", source: "Eald'narche" } +40407.4 "Omega Javelin" Ability { id: "AD5E", source: "Eald'narche" } +40412.0 "Cronos Sling" Ability { id: ["AD49", "AD4A", "AD4B", "AD4C"], source: "Eald'narche" } +40412.4 "--sync--" Ability { id: ["AD4D", "AD4E"], source: "Eald'narche" } +40418.2 "Cronos Sling" Ability { id: ["AD4F", "AD50"], source: "Eald'narche" } +40429.5 "--sync--" Ability { id: "AD51", source: "Eald'narche" } +40430.5 "Uranos Cascade" Ability { id: "AD52", source: "Eald'narche" } +40444.6 "Duplicate" Ability { id: "AD77", source: "Eald'narche" } duration 13.1 +40453.7 "Visions of Paradise" Ability { id: "AD75", source: "Eald'narche" } +40457.8 "--sync--" Ability { id: "AD76", source: "Eald'narche" } +40462.8 "Omega Javelin" Ability { id: "AD5C", source: "Eald'narche" } forcejump "ealdnarche-phase-2-loop" # IGNORED ABILITIES # AD47 --sync--