From d5391a048ead3c3d87e9a744dd2e48c866d18e1a Mon Sep 17 00:00:00 2001 From: valarnin Date: Mon, 18 Nov 2024 21:51:22 -0500 Subject: [PATCH] raidboss: ex3 triggers and timeline (#498) --- .../data/07-dt/trial/queen-eternal-ex.ts | 662 ++++++++++++++++++ .../data/07-dt/trial/queen-eternal-ex.txt | 209 ++++++ 2 files changed, 871 insertions(+) create mode 100644 ui/raidboss/data/07-dt/trial/queen-eternal-ex.ts create mode 100644 ui/raidboss/data/07-dt/trial/queen-eternal-ex.txt diff --git a/ui/raidboss/data/07-dt/trial/queen-eternal-ex.ts b/ui/raidboss/data/07-dt/trial/queen-eternal-ex.ts new file mode 100644 index 0000000000..4f535f33bf --- /dev/null +++ b/ui/raidboss/data/07-dt/trial/queen-eternal-ex.ts @@ -0,0 +1,662 @@ +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 { DirectionOutputCardinal, Directions } from '../../../../../resources/util'; +import ZoneId from '../../../../../resources/zone_id'; +import { RaidbossData } from '../../../../../types/data'; +import { TriggerSet } from '../../../../../types/trigger'; + +// TODO: +// Earth phase boulders, track the amount that hit platform and specify off for second set if 8 have already hit? +// Divide and Conquer followup trigger for the memorized lines, not sure how to word this +// Ice phase, tethers + line stack, might need a strat option for this + +type CoronationLaser = { + dir: Exclude; + side: Exclude; + name: string; +}; + +export interface Data extends RaidbossData { + actorPositions: { [id: string]: { x: number; y: number } }; + windKnockbackDir?: 'left' | 'right'; + phase: 'p1' | 'wind' | 'earth' | 'ice' | 'p2'; + gravitationalEmpireMech: 'tower' | 'spread' | 'cone'; + absoluteAuthorityDebuff: 'stack' | 'spread'; + radicalShiftCWPlatform?: 'wind' | 'earth' | 'ice'; + radicalShiftCCWPlatform?: 'wind' | 'earth' | 'ice'; + coronationLasers: CoronationLaser[]; +} + +const triggerSet: TriggerSet = { + id: 'TheMinstrelsBalladSphenesBurden', + zoneId: ZoneId.TheMinstrelsBalladSphenesBurden, + timelineFile: 'queen-eternal-ex.txt', + initData: () => ({ + absoluteAuthorityDebuff: 'stack', + gravitationalEmpireMech: 'tower', + phase: 'p1', + actorPositions: {}, + coronationLasers: [], + }), + triggers: [ + // Phase trackers + { + id: 'QueenEternal Ex Phase Tracker Elemental', + type: 'StartsUsing', + netRegex: { id: ['A019', 'A01A', 'A01B'], source: 'Queen Eternal', capture: true }, + run: (data, matches) => { + switch (matches.id) { + case 'A019': + data.phase = 'wind'; + break; + case 'A01A': + data.phase = 'earth'; + break; + case 'A01B': + data.phase = 'ice'; + break; + } + }, + }, + { + id: 'QueenEternal Ex Phase Tracker P1', + type: 'StartsUsing', + netRegex: { id: 'A01C', source: 'Queen Eternal', capture: false }, + run: (data) => data.phase = 'p1', + }, + { + id: 'QueenEternal Ex Phase Tracker P2', + type: 'Ability', + netRegex: { id: 'A04B', source: 'Queen Eternal', capture: false }, + run: (data) => data.phase = 'p2', + }, + // General triggers + { + id: 'QueenEternal Ex General ActorSetPos Tracker', + type: 'ActorSetPos', + netRegex: { id: '4[0-9A-F]{7}', capture: true }, + run: (data, matches) => { + data.actorPositions[matches.id] = { + x: parseFloat(matches.x), + y: parseFloat(matches.y), + }; + }, + }, + { + id: 'QueenEternal Ex General Legitimate Force East Safe First', + type: 'StartsUsing', + netRegex: { id: 'A01E', source: 'Queen Eternal', capture: false }, + condition: (data) => ['p1', 'earth', 'ice'].includes(data.phase), + response: Responses.goRightThenLeft(), + }, + { + id: 'QueenEternal Ex General Legitimate Force West Safe First', + type: 'StartsUsing', + netRegex: { id: 'A020', source: 'Queen Eternal', capture: false }, + condition: (data) => ['p1', 'earth', 'ice'].includes(data.phase), + response: Responses.goLeftThenRight(), + }, + { + id: 'QueenEternal Ex World Shatter', + type: 'StartsUsing', + netRegex: { id: ['7692', 'A01C'], source: 'Queen Eternal', capture: false }, + response: Responses.aoe(), + }, + { + id: 'QueenEternal Ex Prosecution of War', + type: 'StartsUsing', + netRegex: { id: 'A00A', source: 'Queen Eternal', capture: true }, + response: Responses.tankBusterSwap(), + }, + { + id: 'QueenEternal Ex Royal Domain', + type: 'StartsUsing', + netRegex: { id: 'A04E', source: 'Queen Eternal', capture: false }, + response: Responses.aoe(), + }, + { + id: 'QueenEternal Ex Virtual Shift', + type: 'StartsUsing', + netRegex: { id: ['A019', 'A01A', 'A01B'], source: 'Queen Eternal', capture: false }, + response: Responses.bigAoe(), + }, + + // Before wind + { + id: 'QueenEternal Ex Aethertithe Safe Parties', + type: 'MapEffect', + netRegex: { flags: ['04000100', '08000100', '10000100'], location: '00', capture: true }, + infoText: (_data, matches, output) => { + const dirMap: { [flag: string]: 'west' | 'middle' | 'east' } = { + '04000100': 'west', + '08000100': 'middle', + '10000100': 'east', + }; + const dirs: ('east' | 'middle' | 'west')[] = Object.entries(dirMap).filter((entry) => + entry[0] !== matches.flags + ).map((entry) => entry[1]); + + const [dir1, dir2] = dirs; + + if (dirs.length !== 2 || dir1 === undefined || dir2 === undefined) { + return output.unknownCombo!({ + unk: output.unknown!(), + groups: output.healerGroups!(), + }); + } + + return output.combo!({ + dir1: output[dir1]!(), + dir2: output[dir2]!(), + groups: output.healerGroups!(), + }); + }, + outputStrings: { + east: Outputs.east, + middle: Outputs.middle, + west: Outputs.west, + healerGroups: Outputs.healerGroups, + combo: { + en: '${dir1}/${dir2}, ${groups}', + de: '${dir1}/${dir2}, ${groups}', + fr: '${dir1}/${dir2}, ${groups}', + ja: '${dir1}/${dir2}, ${groups}', + cn: '${dir1}/${dir2}, ${groups}', + ko: '${dir1}/${dir2}, ${groups}', + }, + unknown: Outputs.unknown, + unknownCombo: { + en: '${unk} => ${groups}', + de: '${unk} => ${groups}', + fr: '${unk} => ${groups}', + ja: '${unk} => ${groups}', + cn: '${unk} => ${groups}', + ko: '${unk} => ${groups}', + }, + }, + }, + + // Wind phase + { + id: 'QueenEternal Ex Wind Phase Aeroquell', + type: 'StartsUsing', + netRegex: { id: 'A025', source: 'Queen Eternal', capture: false }, + suppressSeconds: 1, + infoText: (_data, _matches, output) => output.stacks!(), + outputStrings: { + stacks: Outputs.healerGroups, + }, + }, + { + id: 'QueenEternal Ex Wind Phase Debuff Collector', + type: 'GainsEffect', + netRegex: { effectId: ['105D', '105E'], capture: true }, + condition: Conditions.targetIsYou(), + run: (data, matches) => + data.windKnockbackDir = matches.effectId === '105E' ? 'right' : 'left', + }, + { + id: 'QueenEternal Ex Wind Phase Legitimate Force', + type: 'StartsUsing', + netRegex: { id: ['A01E', 'A020'], source: 'Queen Eternal', capture: true }, + condition: (data) => data.phase === 'wind', + delaySeconds: 0.5, + durationSeconds: 13.3, + infoText: (data, matches, output) => { + const safeDir: 'leftRight' | 'rightLeft' = matches.id === 'A01E' + ? 'rightLeft' + : 'leftRight'; + const kbDir = data.windKnockbackDir; + + if (kbDir === undefined) { + return output.comboUnknown!({ + break: output.break!(), + safe: output[safeDir]!(), + unk: output.unknown!(), + }); + } + + return output.combo!({ + break: output.break!(), + safe: output[safeDir]!(), + kbDir: output[kbDir]!(), + }); + }, + outputStrings: { + leftRight: Outputs.leftThenRight, + rightLeft: Outputs.rightThenLeft, + left: { + en: 'Knockback Left', + }, + right: { + en: 'Knockback Right', + }, + break: Outputs.breakChains, + unknown: Outputs.unknown, + combo: { + en: '${break} => ${safe} => ${kbDir}', + de: '${break} => ${safe} => ${kbDir}', + fr: '${break} => ${safe} => ${kbDir}', + ja: '${break} => ${safe} => ${kbDir}', + cn: '${break} => ${safe} => ${kbDir}', + ko: '${break} => ${safe} => ${kbDir}', + }, + comboUnknown: { + en: '${break} => ${safe} => ${unk}', + de: '${break} => ${safe} => ${unk}', + fr: '${break} => ${safe} => ${unk}', + ja: '${break} => ${safe} => ${unk}', + cn: '${break} => ${safe} => ${unk}', + ko: '${break} => ${safe} => ${unk}', + }, + }, + }, + + // After wind + { + id: 'QueenEternal Ex Divide and Conquer', + type: 'StartsUsing', + netRegex: { id: 'A017', source: 'Queen Eternal', capture: false }, + response: Responses.spread(), + }, + + // Earth phase + { + id: 'QueenEternal Ex Earth Phase Initial Up', + type: 'Ability', + netRegex: { id: 'A01A', capture: false }, + suppressSeconds: 1, + infoText: (_data, _matches, output) => output.up!(), + outputStrings: { + up: { + en: 'Up', + }, + }, + }, + { + id: 'QueenEternal Ex Earth Phase First Towers', + type: 'Ability', + netRegex: { id: 'A028', capture: false }, + delaySeconds: 14.3, + infoText: (_data, _matches, output) => output.downSoak!(), + outputStrings: { + downSoak: { + en: 'Down, soak tower', + }, + }, + }, + { + id: 'QueenEternal Ex Earth Phase Gravitational Empire Pillar Collector', + type: 'StartsUsing', + netRegex: { id: 'A02C', capture: true }, + condition: Conditions.targetIsYou(), + response: Responses.spread(), + run: (data) => data.gravitationalEmpireMech = 'spread', + }, + { + id: 'QueenEternal Ex Earth Phase Gravitational Empire Ray Collector', + type: 'Tether', + netRegex: { id: '0011', capture: true }, + condition: (data, matches) => matches.source === data.me, + infoText: (_data, _matches, output) => output.cone!(), + run: (data) => data.gravitationalEmpireMech = 'cone', + outputStrings: { + cone: { + en: 'Cone on YOU', + }, + }, + }, + { + id: 'QueenEternal Ex Earth Phase Gravitational Empire Towers', + type: 'StartsUsing', + netRegex: { id: 'A02B', capture: false }, + delaySeconds: 0.5, + infoText: (data, _matches, output) => { + if (data.gravitationalEmpireMech !== 'tower') + return; + + return output.downSoak!(); + }, + outputStrings: { + downSoak: { + en: 'Down, soak tower', + }, + }, + }, + { + id: 'QueenEternal Ex Earth Phase Boulder', + type: 'HeadMarker', + netRegex: { id: '022F', capture: false }, + suppressSeconds: 1, + response: Responses.spread(), + }, + { + id: 'QueenEternal Ex Earth Phase Weighty Blow', + type: 'StartsUsing', + netRegex: { id: 'A033', source: 'Queen Eternal', capture: false }, + infoText: (_data, _matches, output) => output.text!(), + outputStrings: { + text: { + en: 'Hide behind rocks', + }, + }, + }, + + // After earth + { + id: 'QueenEternal Ex Coronation Laser Collector', + type: 'StartsUsing', + netRegex: { id: 'A013', source: 'Queen Eternal', capture: false }, + promise: async (data) => { + const combatants = (await callOverlayHandler({ + call: 'getCombatants', + })); + + if (combatants === null) { + console.error(`Coronation Laser Collector: null data`); + return; + } + + const lasers = combatants.combatants.filter((c) => c.BNpcID === 18043); + + if (lasers.length !== 4) { + console.error( + `Coronation Laser Collector: expected 4, got ${combatants.combatants.length}`, + ); + return; + } + + for (const laser of lasers) { + data.actorPositions[laser.ID?.toString(16).toUpperCase() ?? ''] = { + x: laser.PosX, + y: laser.PosY, + }; + } + }, + }, + { + id: 'QueenEternal Ex Coronation Laser Tether Collector', + type: 'Tether', + netRegex: { id: ['010E', '010F'], capture: true }, + infoText: (data, matches, output) => { + const idToSideMap: { [id: string]: number } = { + '010E': -1, // 'left', + '010F': 1, // 'right', + } as const; + + const offset = idToSideMap[matches.id]; + const pos = data.actorPositions[matches.targetId]; + + if (offset === undefined || pos === undefined) { + console.error( + `Coronation Laser Tether Collector: ${offset ?? 'undefined'}, ${JSON.stringify(pos)}`, + ); + return output.unknown!(); + } + + const laserDirNum = Directions.xyTo4DirNum(pos.x, pos.y, 100.0, 100.0); + const sideDirNum = (4 + laserDirNum + offset) % 4; + + const laserDir = Directions.outputFromCardinalNum(laserDirNum); + const sideDir = Directions.outputFromCardinalNum(sideDirNum); + + if (laserDir === 'unknown' || sideDir === 'unknown') { + console.error( + `Coronation Laser Tether Collector: laserDir = ${laserDir}, sideDir = ${sideDir}`, + ); + return output.unknown!(); + } + + data.coronationLasers.push({ + dir: laserDir, + side: sideDir, + name: matches.source, + }); + + if (data.coronationLasers.length < 8) + return; + + const myLaser = data.coronationLasers.find((laser) => laser.name === data.me); + + if (myLaser === undefined) + throw new UnreachableCode(); + + const partnerLaser = data.coronationLasers.find((laser) => + laser.dir === myLaser.dir && laser !== myLaser + ); + + return output.text!({ + laserDir: output[myLaser.dir]!(), + sideDir: output[myLaser.side]!(), + partner: data.party.member(partnerLaser?.name), + }); + }, + outputStrings: { + ...Directions.outputStringsCardinalDir, + text: { + en: '${laserDir} laser, ${sideDir} side, w/ ${partner}', + }, + unknown: Outputs.unknown, + }, + }, + { + id: 'QueenEternal Ex Absolute Authority', + type: 'StartsUsing', + netRegex: { id: 'A041', source: 'Queen Eternal', capture: false }, + infoText: (_data, _matches, output) => output.bait!(), + outputStrings: { + bait: Outputs.baitPuddles, + }, + }, + { + id: 'QueenEternal Ex Absolute Authority Debuff Collector', + type: 'GainsEffect', + netRegex: { effectId: '105A', capture: true }, + condition: Conditions.targetIsYou(), + run: (data) => data.absoluteAuthorityDebuff = 'spread', + }, + { + id: 'QueenEternal Ex Absolute Authority Debuff Mechanics', + type: 'GainsEffect', + netRegex: { effectId: '105A', capture: false }, + delaySeconds: 1, + suppressSeconds: 1, + infoText: (data, _matches, output) => { + return output.combo!({ + stackSpread: output[data.absoluteAuthorityDebuff]!(), + dorito: output.dorito!(), + }); + }, + outputStrings: { + spread: { + en: 'Flare Marker Spread', + }, + stack: Outputs.stackMarker, + dorito: Outputs.doritoStack, + combo: { + en: '${stackSpread} => ${dorito}', + de: '${stackSpread} => ${dorito}', + fr: '${stackSpread} => ${dorito}', + ja: '${stackSpread} => ${dorito}', + cn: '${stackSpread} => ${dorito}', + ko: '${stackSpread} => ${dorito}', + }, + }, + }, + + // Ice phase + { + id: 'QueenEternal Ex Ice Phase Motion Headmarker', + type: 'HeadMarker', + netRegex: { id: '022A', capture: false }, + suppressSeconds: 1, + response: Responses.moveAround(), + }, + { + id: 'QueenEternal Ex Ice Phase Icecicles', + type: 'Tether', + netRegex: { id: '0039', capture: true }, + condition: Conditions.targetIsYou(), + promise: async (data, matches) => { + const combatants = (await callOverlayHandler({ + call: 'getCombatants', + ids: [parseInt(matches.sourceId, 16)], + })); + + if (combatants === null) { + console.error(`Ice Phase Icecicles: null data`); + return; + } + if (combatants.combatants.length !== 1) { + console.error(`Ice Phase Icecicles: expected 1, got ${combatants.combatants.length}`); + return; + } + + const icecicle = combatants.combatants[0]; + if (!icecicle) + return; + + data.actorPositions[matches.sourceId] = { + x: icecicle.PosX, + y: icecicle.PosY, + }; + }, + infoText: (data, matches, output) => { + const iceciclePos = data.actorPositions[matches.sourceId]; + + if (iceciclePos === undefined) { + return output.unknown!(); + } + + if (iceciclePos.x < 100.0) { + return output.east!(); + } + + return output.west!(); + }, + outputStrings: { + unknown: { + en: 'Spread ???, stretch tethers', + }, + west: { + en: 'Spread West, stretch tethers', + }, + east: { + en: 'Spread East, stretch tethers', + }, + }, + }, + + // Phase two + { + id: 'QueenEternal Ex Platform Tracker', + type: 'MapEffect', + netRegex: { location: ['09', '0A', '0B'], capture: true }, + run: (data, matches) => { + const flags: { [flag: string]: 'cw' | 'ccw' } = { + '00200010': 'ccw', + '00020001': 'cw', + }; + + const slots: { [slot: string]: 'wind' | 'earth' | 'ice' } = { + '09': 'wind', + '0A': 'earth', + '0B': 'ice', + }; + + const dir = flags[matches.flags]; + const element = slots[matches.location]; + + if (dir === undefined || element === undefined) { + return; + } + + if (dir === 'cw') { + data.radicalShiftCWPlatform = element; + } else { + data.radicalShiftCCWPlatform = element; + } + }, + }, + { + id: 'QueenEternal Ex Rotation Direction + Spread', + type: 'MapEffect', + netRegex: { flags: ['08000400', '01000080'], location: '0C', capture: true }, + infoText: (data, matches, output) => { + const dir = matches.flags === '08000400' ? 'cw' : 'ccw'; + let elem = data.radicalShiftCWPlatform; + + if (dir === 'ccw') { + elem = data.radicalShiftCCWPlatform; + } + + if (elem === undefined) { + return output.combo!({ + elem: output.unknown!(), + spread: output.spread!(), + }); + } + + return output.combo!({ + elem: output[elem]!(), + spread: output.spread!(), + }); + }, + outputStrings: { + spread: Outputs.spread, + unknown: Outputs.unknown, + wind: { + en: 'Wind/Green', + }, + earth: { + en: 'Earth/Yellow', + }, + ice: { + en: 'Ice/Blue', + }, + combo: { + en: '${elem} => ${spread}', + de: '${elem} => ${spread}', + fr: '${elem} => ${spread}', + ja: '${elem} => ${spread}', + cn: '${elem} => ${spread}', + ko: '${elem} => ${spread}', + }, + }, + }, + { + id: 'QueenEternal Ex Radical Shift', + type: 'StartsUsing', + netRegex: { id: 'A04F', source: 'Queen Eternal', capture: false }, + response: Responses.bigAoe(), + }, + { + id: 'QueenEternal Ex Dying Memory', + type: 'StartsUsing', + netRegex: { id: 'A059', source: 'Queen Eternal', capture: false }, + response: Responses.aoe(), + }, + { + id: 'QueenEternal Ex Royal Banishment', + type: 'StartsUsing', + netRegex: { id: 'A05A', source: 'Queen Eternal', capture: false }, + response: Responses.aoe(), + }, + { + id: 'QueenEternal Ex Tyranny\'s Grasp', + type: 'StartsUsing', + netRegex: { id: 'A055', source: 'Queen Eternal', capture: false }, + infoText: (_data, _matches, output) => output.back!(), + outputStrings: { + back: { + en: 'Back, Tank Towers => AoE', + }, + }, + }, + ], +}; + +export default triggerSet; diff --git a/ui/raidboss/data/07-dt/trial/queen-eternal-ex.txt b/ui/raidboss/data/07-dt/trial/queen-eternal-ex.txt new file mode 100644 index 0000000000..28536e74a1 --- /dev/null +++ b/ui/raidboss/data/07-dt/trial/queen-eternal-ex.txt @@ -0,0 +1,209 @@ +# -p A04B:1000.0 -ii A008 A009 A00D A00E A00F A010 A011 A018 A026 A027 A02F A030 A053 A054 A056 + +# Phase one pulled from -r XwHyk2NAKnbzZLf7 -rf 3 +# Phase two pulled from -r GBaArv7yzHnXck8D -rf 17 +# A lot of manual cleanup applied + +# Phase one +0.0 "--sync--" InCombat { inGameCombat: "1" } window 0,1 +13.1 "--sync--" StartsUsing { id: "A00C", source: "Queen Eternal" } +15.8 "Aethertithe" Ability { id: "A00C", source: "Queen Eternal" } duration 27.8 +28.9 "Retribute" Ability { id: "A012", source: "Queen Eternal" } +38.1 "Retribute" Ability { id: "A012", source: "Queen Eternal" } +47.3 "Retribute" Ability { id: "A012", source: "Queen Eternal" } +59.7 "Virtual Shift" Ability { id: "A019", source: "Queen Eternal" } window 59.7,10 + +# Wind miniphase +68.8 "Laws of Wind" Ability { id: "A023", source: "Queen Eternal" } +73.8 "Aeroquell" Ability { id: "A025", source: "Queen Eternal" } +86.8 "Legitimate Force" Ability { id: ["A01E", "A020"], source: "Queen Eternal" } +89.9 "Legitimate Force" Ability { id: ["A021", "A022"], source: "Queen Eternal" } +93.0 "Wind of Change" #Ability { id: "A024", source: "Queen Eternal" } +100.9 "World Shatter" Ability { id: "A01C", source: "Queen Eternal" } +# End wind miniphase + +113.0 "Prosecution of War 1" Ability { id: "A00A", source: "Queen Eternal" } +116.1 "Prosecution of War 2" Ability { id: "A00B", source: "Queen Eternal" } +126.8 "Divide and Conquer x8" Ability { id: "A017", source: "Queen Eternal" } duration 7 +# TODO: Better timeline name here. +137.9 "Divide and Conquer" Ability { id: "7729", source: "Queen Eternal" } +145.9 "Royal Domain" Ability { id: "A04E", source: "Queen Eternal" } +159.1 "Virtual Shift" Ability { id: "A01A", source: "Queen Eternal" } window 159.1,10 + +# Earth miniphase +168.2 "Laws of Earth" Ability { id: "A028", source: "Queen Eternal" } +179.3 "Legitimate Force Left/Right" Ability { id: ["A01E", "A020"], source: "Queen Eternal" } +182.4 "Legitimate Force Right/Left" Ability { id: ["A021", "A022"], source: "Queen Eternal" } +187.4 "Burst" Ability { id: "A029", source: "Queen Eternal" } +199.5 "Gravitational Empire" Ability { id: "A02B", source: "Queen Eternal" } +200.5 "Gravity Pillar" Ability { id: "A02C", source: "Queen Eternal" } +200.5 "Gravity Ray" Ability { id: "A02D", source: "Queen Eternal" } +201.4 "Burst" Ability { id: "A029", source: "Queen Eternal" } +205.7 "Meteor Impact 1" Ability { id: "A02E", source: "Queen Eternal" } +212.8 "Meteor Impact 2" Ability { id: "A02E", source: "Queen Eternal" } +226.9 "Weighty Blow (cast)" Ability { id: "A033", source: "Queen Eternal" } +226.9 "Weighty Blow 1 (orb)" Ability { id: "A032", source: "Virtual Boulder" } +230.0 "Weighty Blow 2 (orb)" Ability { id: "A032", source: "Virtual Boulder" } +233.1 "Weighty Blow 3 (orb)" Ability { id: "A032", source: "Virtual Boulder" } +236.2 "Weighty Blow 4 (orb)" Ability { id: "A032", source: "Virtual Boulder" } +241.8 "World Shatter" Ability { id: "A01C", source: "Queen Eternal" } +# End earth miniphase + +254.0 "Prosecution of War 1" Ability { id: "A00A", source: "Queen Eternal" } +257.1 "Prosecution of War 2" Ability { id: "A00B", source: "Queen Eternal" } +263.2 "Coronation" Ability { id: "A013", source: "Queen Eternal" } +269.3 "Atomic Ray (cast)" Ability { id: "A015", source: "Queen Eternal" } +275.3 "Ruthless Regalia" Ability { id: "A014", source: "Queen Eternal" } +276.4 "Atomic Ray (damage)" Ability { id: "A016", source: "Queen Eternal" } +292.5 "Absolute Authority" Ability { id: "A041", source: "Queen Eternal" } duration 13.4 +302.4 "Absolute Authority (Flares/Stack)" Ability { id: "A046", source: "Queen Eternal" } +306.6 "Absolute Authority (Dorito Stack)" Ability { id: "A048", source: "Queen Eternal" } +313.5 "Absolute Authority (Knockback)" Ability { id: "A045", source: "Queen Eternal" } +330.7 "Virtual Shift" Ability { id: "A01B", source: "Queen Eternal" } window 330.7,10 + +# Ice miniphase +339.8 "Laws of Ice (motion)" Ability { id: "A035", source: "Queen Eternal" } +340.8 "Laws of Ice (platforms)" Ability { id: "A036", source: "Queen Eternal" } +357.0 "Rush" Ability { id: "A037", source: "Ice Pillar" } +364.8 "Legitimate Force Left/Right" Ability { id: ["A01E", "A020"], source: "Queen Eternal" } +367.9 "Legitimate Force Right/Left" Ability { id: ["A021", "A022"], source: "Queen Eternal" } +378.0 "Laws of Ice (motion)" Ability { id: "A035", source: "Queen Eternal" } +379.0 "Laws of Ice (platforms)" Ability { id: "A036", source: "Queen Eternal" } +384.1 "Drear Rising" Ability { id: "A03E", source: "Queen Eternal" } +385.1 "Ice Dart" #Ability { id: "A03F", source: "Queen Eternal" } +385.1 "Raised Tribute" #Ability { id: "A040", source: "Queen Eternal" } +391.2 "Drear Rising" Ability { id: "A03E", source: "Queen Eternal" } +392.2 "Ice Dart" #Ability { id: "A03F", source: "Queen Eternal" } +392.2 "Raised Tribute" #Ability { id: "A040", source: "Queen Eternal" } +398.3 "Drear Rising" Ability { id: "A03E", source: "Queen Eternal" } +399.3 "Ice Dart" #Ability { id: "A03F", source: "Queen Eternal" } +399.3 "Raised Tribute" #Ability { id: "A040", source: "Queen Eternal" } +405.4 "Drear Rising" Ability { id: "A03E", source: "Queen Eternal" } +406.4 "Ice Dart" #Ability { id: "A03F", source: "Queen Eternal" } +406.4 "Raised Tribute" #Ability { id: "A040", source: "Queen Eternal" } +414.5 "World Shatter" Ability { id: "A01C", source: "Queen Eternal" } +# End ice miniphase + +427.5 "Prosecution of War 1" Ability { id: "A00A", source: "Queen Eternal" } +430.6 "Prosecution of War 2" Ability { id: "A00B", source: "Queen Eternal" } +443.6 "Royal Domain" Ability { id: "A04E", source: "Queen Eternal" } +457.7 "Legitimate Force Left/Right" Ability { id: ["A01E", "A020"], source: "Queen Eternal" } +460.8 "Legitimate Force Right/Left" Ability { id: ["A021", "A022"], source: "Queen Eternal" } +468.8 "Royal Domain" Ability { id: "A04E", source: "Queen Eternal" } +486.9 "Authority Eternal" Ability { id: "A04A", source: "Queen Eternal" } +487.1 "Authority Eternal (Enrage)" Ability { id: "A04C", source: "Queen Eternal" } + +# Phase two +1000.0 "Authority Eternal" Ability { id: "A04B", source: "Queen Eternal" } window 1000.0,0 +1009.8 "--sync--" Ability { id: "A04D", source: "Queen Eternal" } + +# Radical Shift 1 +1039.8 "Radical Shift (rotate)" Ability { id: "A04F", source: "Queen Eternal" } +1044.9 "Radical Shift (spread)" Ability { id: "A050", source: "Queen Eternal" } +1058.9 "Radical Shift (rotate)" Ability { id: "A04F", source: "Queen Eternal" } +1064.0 "Radical Shift (spread)" Ability { id: "A050", source: "Queen Eternal" } +1072.0 "World Shatter" Ability { id: "7692", source: "Queen Eternal" } + +# Exaflares, front aoe + tank towers +1083.0 "Dimensional Distortion" Ability { id: "A052", source: "Queen Eternal" } duration 7.3 +1094.2 "Tyranny's Grasp (front)" Ability { id: "A055", source: "Queen Eternal" } +1095.4 "Tyranny's Grasp (left tower)" Ability { id: "A057", source: "Queen Eternal" } +1098.2 "Tyranny's Grasp (right tower)" Ability { id: "76D2", source: "Queen Eternal" } + +# damage spam +1099.4 "Dying Memory x7" duration 6.6 #Ability { id: "A059", source: "Queen Eternal" } +1107.1 "Dying Memory (big)" Ability { id: "4E4A", source: "Queen Eternal" } +1115.2 "Royal Banishment x7" Ability { id: "A05A", source: "Queen Eternal" } duration 6.9 +1125.1 "Royal Banishment (big)" Ability { id: "A05C", source: "Queen Eternal" } + +# Radical Shift 2 +1147.4 "Radical Shift (rotate)" Ability { id: "A04F", source: "Queen Eternal" } +1152.5 "Radical Shift (spread)" Ability { id: "A050", source: "Queen Eternal" } +1166.5 "Radical Shift (rotate)" Ability { id: "A04F", source: "Queen Eternal" } +1171.6 "Radical Shift (spread)" Ability { id: "A050", source: "Queen Eternal" } +1179.6 "World Shatter" Ability { id: "7692", source: "Queen Eternal" } + +1200.7 "Preservation (Enrage)" Ability { id: "A05D", source: "Queen Eternal" } + +# ALL ENCOUNTER ABILITIES +# 4E4A Dying Memory +# 7692 World Shatter +# 76D2 Tyranny's Grasp +# 7729 Divide and Conquer +# A008 --sync-- __P1 autoattack__ +# A009 --sync-- __P2 autoattack__ +# A00A Prosecution of War __Tankbuster__ +# A00B Prosecution of War __Tankbuster__ +# A00C Aethertithe __Initial Cast__ +# A00D Aethertithe __Repeated Hits__ +# A00E Aethertithe __Last Hit__ +# A00F Aethertithe __Extra damage spike__ +# A010 Aethertithe __Extra damage spike__ +# A011 Retribute __LP line stack__ +# A012 Retribute __LP line stack__ +# A013 Coronation +# A015 Atomic Ray +# A016 Atomic Ray +# A017 Divide and Conquer __Individual lines__ +# A018 Divide and Conquer __All lines re-fire__ +# A019 Virtual Shift +# A01A Virtual Shift +# A01B Virtual Shift +# A01C World Shatter +# A01E Legitimate Force __East safe, then west safe__ +# A020 Legitimate Force __West safe, then east safe__ +# A021 Legitimate Force __Followup hit for A020__ +# A022 Legitimate Force __Followup hit for A01E__ +# A023 Laws of Wind __Does nothing?__ +# A024 --sync-- __East/West Wind of Change knockback__ +# A025 Aeroquell __Healer stacks__ +# A026 Biting Chains __Damage for not breaking chains fast enough__ +# A027 Aero IV __Twister repeated knockback__ +# A028 Laws of Earth __Spawns the gravity pillars__ +# A029 Burst __Tower soak damage__ +# A02B Gravitational Empire +# A02C Gravity Pillar +# A02D Gravity Ray +# A02E Meteor Impact __Cast__ +# A02F Meteor Impact __Actual meteor drops, on platform__ +# A030 Meteor Impact __Actual meteor drops, off platform__ +# A032 --sync-- __Weighty Blow orbs__ +# A033 Weighty Blow __Cast__ +# A035 Laws of Ice __Spawns/respawns bridges__ +# A036 Laws of Ice __Spawns/respawns bridges__ +# A037 Rush +# A038 Rush +# A039 Rush +# A03A Rush +# A03B Rush __Icecicle failure__ +# A03C Rush __Icecicle failure__ +# A03D Shatter __Icecicle failure__ +# A03E Drear Rising +# A03F Ice Dart +# A040 Raised Tribute +# A041 Absolute Authority __Cast__ +# A042 Absolute Authority __Puddles__ +# A043 Absolute Authority __Puddles__ +# A044 Absolute Authority __Repeated small damage__ +# A045 Absolute Authority __Knockback damage__ +# A046 Absolute Authority __Flare marker damage__ +# A047 Absolute Authority __Stack marker damage__ +# A048 Absolute Authority __Dorito stack damage, success__ +# A049 Absolute Authority __Dorito stack damage, failure__ +# A04A Authority Eternal +# A04B Authority Eternal +# A04D --sync-- +# A04E Royal Domain +# A04F Radical Shift +# A050 Radical Shift +# A052 Dimensional Distortion +# A053 Dimensional Distortion +# A054 Dimensional Distortion +# A055 Tyranny's Grasp +# A056 --sync-- +# A057 Tyranny's Grasp +# A059 Dying Memory +# A05A Royal Banishment +# A05B Royal Banishment +# A05C Royal Banishment +# A05D Preservation