From 941aa53d93aeac7ab0a1cd72b798e11e54d5e8ec Mon Sep 17 00:00:00 2001 From: github-actions Date: Tue, 12 Apr 2022 08:02:24 +0000 Subject: [PATCH] triggers build: Revert "resources: update for 6.1 (#4250)" This reverts commit 0f82e51121d0e9e92f25c64204e109bb87e64e1a. 1962ea8e35b977d7c30b4b49ec2359fde8250082 --- 02-arr/trial/ultima-ex.js | 296 ++++++++++++++++++++++++++++++++++ 06-ew/trial/zodiark-ex.js | 326 +++++++++++++++++++++++++++++++++++++- 2 files changed, 621 insertions(+), 1 deletion(-) create mode 100644 02-arr/trial/ultima-ex.js diff --git a/02-arr/trial/ultima-ex.js b/02-arr/trial/ultima-ex.js new file mode 100644 index 0000000000..b3b3dad942 --- /dev/null +++ b/02-arr/trial/ultima-ex.js @@ -0,0 +1,296 @@ +Options.Triggers.push({ + zoneId: ZoneId.TheMinstrelsBalladUltimasBane, + timelineFile: 'ultima-ex.txt', + initData: () => { + return { + plasmTargets: [], + boomCounter: 1, + }; + }, + timelineTriggers: [ + { + id: 'Ultima EX Homing Lasers', + regex: /Homing Lasers/, + beforeSeconds: 4, + alertText: (_data, _matches, output) => output.text(), + outputStrings: { + text: { + en: 'Spread--Homing Lasers', + de: 'Verteilen--Leitlaser', + cn: '分散--追踪激光', + }, + }, + }, + { + id: 'Ultima EX Diffractive Laser', + regex: /Diffractive Laser/, + beforeSeconds: 4, + response: Responses.tankCleave(), + }, + { + id: 'Ultima EX Vulcan Burst', + regex: /Vulcan Burst/, + beforeSeconds: 5, + infoText: (_data, _matches, output) => output.text(), + outputStrings: { + text: { + en: 'Melee knockback', + de: 'Melee Rückstoß', + fr: 'Poussée', + cn: '近战击退', + }, + }, + }, + ], + triggers: [ + { + id: 'Ultima EX Tank Purge', + type: 'StartsUsing', + netRegex: NetRegexes.startsUsing({ id: '5EA', source: 'The Ultima Weapon', capture: false }), + netRegexDe: NetRegexes.startsUsing({ id: '5EA', source: 'Ultima-Waffe', capture: false }), + netRegexFr: NetRegexes.startsUsing({ id: '5EA', source: 'Ultima Arma', capture: false }), + netRegexJa: NetRegexes.startsUsing({ id: '5EA', source: 'アルテマウェポン', capture: false }), + netRegexCn: NetRegexes.startsUsing({ id: '5EA', source: '究极神兵', capture: false }), + netRegexKo: NetRegexes.startsUsing({ id: '5EA', source: '알테마 웨폰', capture: false }), + response: Responses.bigAoe(), + }, + { + // At 5 stacks of Viscous Aetheroplasm, the target begins taking massive damage. + id: 'Ultima EX Viscous Aetheroplasm', + type: 'GainsEffect', + netRegex: NetRegexes.gainsEffect({ effectId: '171', count: '04', capture: false }), + condition: (data) => data.role === 'tank', + alertText: (_data, _matches, output) => output.text(), + outputStrings: { + text: Outputs.tankSwap, + }, + }, + { + id: 'Ultima EX Homing Aetheroplasm Collect', + type: 'Ability', + netRegex: NetRegexes.ability({ id: '672' }), + run: (data, matches) => { + data.plasmTargets = data.plasmTargets ?? (data.plasmTargets = []); + data.plasmTargets.push(matches.target); + }, + }, + { + // This ability is ARR 2.0's version of headmarkers. No associated 27 lines are present. + // These lines are sent by entities with no name and no 03/04 lines. + id: 'Ultima EX Homing Aetheroplasm Call', + type: 'Ability', + netRegex: NetRegexes.ability({ id: '672', capture: false }), + delaySeconds: 0.5, + suppressSeconds: 5, + infoText: (data, _matches, output) => { + if (data.plasmTargets?.includes(data.me)) + return output.target(); + return output.avoid(); + }, + outputStrings: { + target: { + en: 'Homing Aetheroplasm on YOU', + de: 'Verfolgendes Ätheroplasma auf DIR', + fr: 'Laser + Éthéroplasma sur VOUS', + cn: '追踪激光点名', + }, + avoid: { + en: 'Avoid Homing Aetheroplasm', + de: 'Weiche dem verfolgendem Ätheroplasma aus', + fr: 'Évitez le laser + l\'Éthéroplasma', + cn: '躲避追踪激光', + }, + }, + }, + { + id: 'Ultima EX Homing Aetheroplasm Cleanup', + type: 'Ability', + netRegex: NetRegexes.ability({ id: '672', capture: false }), + delaySeconds: 5, + suppressSeconds: 5, + run: (data) => delete data.plasmTargets, + }, + { + // We use a StartsUsing line here because we can't use timeline triggers for this, + // and we want to warn players as early as possible. + id: 'Ultima EX Aetheric Boom Orbs', + type: 'StartsUsing', + netRegex: NetRegexes.startsUsing({ id: '5E7', source: 'The Ultima Weapon', capture: false }), + netRegexDe: NetRegexes.startsUsing({ id: '5E7', source: 'Ultima-Waffe', capture: false }), + netRegexFr: NetRegexes.startsUsing({ id: '5E7', source: 'Ultima Arma', capture: false }), + netRegexJa: NetRegexes.startsUsing({ id: '5E7', source: 'アルテマウェポン', capture: false }), + netRegexCn: NetRegexes.startsUsing({ id: '5E7', source: '究极神兵', capture: false }), + netRegexKo: NetRegexes.startsUsing({ id: '5E7', source: '알테마 웨폰', capture: false }), + alarmText: (data, _matches, output) => output[`boom${data.boomCounter}`](), + run: (data) => data.boomCounter += 1, + outputStrings: { + boom1: { + en: 'Orbs: Cardinals', + de: 'Orbs: Kardinal', + fr: 'Orbes : Cardinaux', + cn: '球: 十字', + }, + boom2: { + en: 'Orbs: Cardinals (N/S first)', + de: 'Orbs: Kardinal (N/S zuerst)', + fr: 'Orbes : Cardinaux (N/S en premier)', + cn: '球: 十字(先南/北)', + }, + boom3: { + en: 'Orbs: Intercardinals', + de: 'Orbs: Interkardinal', + fr: 'Orbes : Intercardinaux', + cn: '球: 方形', + }, + }, + }, + { + id: 'Ultima EX Aetheric Boom Knockback', + type: 'StartsUsing', + netRegex: NetRegexes.startsUsing({ id: '5E7', source: 'The Ultima Weapon', capture: false }), + netRegexDe: NetRegexes.startsUsing({ id: '5E7', source: 'Ultima-Waffe', capture: false }), + netRegexFr: NetRegexes.startsUsing({ id: '5E7', source: 'Ultima Arma', capture: false }), + netRegexJa: NetRegexes.startsUsing({ id: '5E7', source: 'アルテマウェポン', capture: false }), + netRegexCn: NetRegexes.startsUsing({ id: '5E7', source: '究极神兵', capture: false }), + netRegexKo: NetRegexes.startsUsing({ id: '5E7', source: '알테마 웨폰', capture: false }), + response: Responses.knockback(), + }, + ], + timelineReplace: [ + { + 'locale': 'de', + 'replaceSync': { + 'The Ultima Weapon': 'Ultima-Waffe', + 'Ultima Garuda': 'Ultima-Garuda', + 'Ultima Ifrit': 'Ultima-Ifrit', + 'Ultima Titan': 'Ultima-Titan', + }, + 'replaceText': { + 'Aetheric Boom': 'Ätherknall', + 'Ceruleum Vent': 'Erdseim-Entlüfter', + 'Crimson Cyclone': 'Zinnober-Zyklon', + 'Diffractive Laser': 'Diffraktiver Laser', + 'Eruption': 'Eruption', + 'Eye of the Storm': 'Auge des Sturms', + 'Geocrush': 'Geo-Stoß', + 'Homing Lasers': 'Leitlaser', + 'Magitek Ray': 'Magitek-Laser', + 'Mistral Song': 'Mistral-Song', + 'Radiant Plume': 'Scheiterhaufen', + 'Tank Purge': 'Tankreinigung', + 'Ultima': 'Ultima', + 'Viscous Aetheroplasm': 'Viskoses Ätheroplasma', + 'Vulcan Burst': 'Feuerstoß', + 'Weight of the Land': 'Gaias Gewicht', + }, + }, + { + 'locale': 'fr', + 'replaceSync': { + 'The Ultima Weapon': 'Ultima Arma', + 'Ultima Garuda': 'Ultima-Garuda', + 'Ultima Ifrit': 'Ultima-Ifrit', + 'Ultima Titan': 'Ultima-Titan', + }, + 'replaceText': { + 'Aetheric Boom': 'Onde d\'éther', + 'Ceruleum Vent': 'Exutoire à céruleum', + 'Crimson Cyclone': 'Cyclone écarlate', + 'Diffractive Laser': 'Laser diffractif', + 'Eruption': 'Éruption', + 'Eye of the Storm': 'Œil du cyclone', + 'Geocrush': 'Broie-terre', + 'Homing Lasers': 'Lasers autoguidés', + 'Magitek Ray': 'Rayon magitek', + 'Mistral Song': 'Chant du mistral', + 'Radiant Plume': 'Panache radiant', + 'Tank Purge': 'Vidange de réservoir', + 'Ultima': 'Ultima', + 'Viscous Aetheroplasm': 'Éthéroplasma poisseux', + 'Vulcan Burst': 'Explosion volcanique', + 'Weight of the Land': 'Poids de la terre', + }, + }, + { + 'locale': 'ja', + 'replaceSync': { + 'The Ultima Weapon': 'アルテマウェポン', + 'Ultima Garuda': 'アルテマ・ガルーダ', + 'Ultima Ifrit': 'アルテマ・イフリート', + 'Ultima Titan': 'アルテマ・タイタン', + }, + 'replaceText': { + 'Aetheric Boom': 'エーテル波動', + 'Ceruleum Vent': 'セルレアムベント', + 'Crimson Cyclone': 'クリムゾンサイクロン', + 'Diffractive Laser': '拡散レーザー', + 'Eruption': 'エラプション', + 'Eye of the Storm': 'アイ・オブ・ストーム', + 'Geocrush': 'ジオクラッシュ', + 'Homing Lasers': '誘導レーザー', + 'Magitek Ray': '魔導レーザー', + 'Mistral Song': 'ミストラルソング', + 'Radiant Plume': '光輝の炎柱', + 'Tank Purge': '魔導フレア', + 'Ultima': 'アルテマ', + 'Viscous Aetheroplasm': '吸着式エーテル爆雷', + 'Vulcan Burst': 'バルカンバースト', + 'Weight of the Land': '大地の重み', + }, + }, + { + 'locale': 'cn', + 'replaceSync': { + 'The Ultima Weapon': '究极神兵', + 'Ultima Garuda': '究极迦楼罗', + 'Ultima Ifrit': '究极伊弗利特', + 'Ultima Titan': '究极泰坦', + }, + 'replaceText': { + 'Aetheric Boom': '以太波动', + 'Ceruleum Vent': '青磷放射', + 'Crimson Cyclone': '深红旋风', + 'Diffractive Laser': '扩散射线', + 'Eruption': '地火喷发', + 'Eye of the Storm': '台风眼', + 'Geocrush': '大地粉碎', + 'Homing Lasers': '诱导射线', + 'Magitek Ray': '魔导激光', + 'Mistral Song': '寒风之歌', + 'Radiant Plume': '光辉炎柱', + 'Tank Purge': '魔导核爆', + 'Ultima': '究极', + 'Viscous Aetheroplasm': '吸附式以太炸弹', + 'Vulcan Burst': '火神爆裂', + 'Weight of the Land': '大地之重', + }, + }, + { + 'locale': 'ko', + 'replaceSync': { + 'The Ultima Weapon': '알테마 웨폰', + 'Ultima Garuda': '알테마 가루다', + 'Ultima Ifrit': '알테마 이프리트', + 'Ultima Titan': '알테마 타이탄', + }, + 'replaceText': { + 'Aetheric Boom': '에테르 파동', + 'Ceruleum Vent': '청린 방출', + 'Crimson Cyclone': '진홍 회오리', + 'Diffractive Laser': '확산 레이저', + 'Eruption': '용암 분출', + 'Eye of the Storm': '태풍의 눈', + 'Geocrush': '대지 붕괴', + 'Homing Lasers': '유도 레이저', + 'Magitek Ray': '마도 레이저', + 'Mistral Song': '삭풍의 노래', + 'Radiant Plume': '광휘의 불기둥', + 'Tank Purge': '마도 플레어', + 'Ultima': '알테마', + 'Viscous Aetheroplasm': '흡착식 에테르 폭뢰', + 'Vulcan Burst': '폭렬 난사', + 'Weight of the Land': '대지의 무게', + }, + }, + ], +}); diff --git a/06-ew/trial/zodiark-ex.js b/06-ew/trial/zodiark-ex.js index 252ec26720..2746953552 100644 --- a/06-ew/trial/zodiark-ex.js +++ b/06-ew/trial/zodiark-ex.js @@ -1,6 +1,27 @@ +const sigil = { + greenBeam: '67E4', + redBox: '67E5', + blueCone: '67E6', +}; +const fetchCombatantsById = async (id) => { + const decIds = []; + for (const i of id) + decIds.push(parseInt(i, 16)); + const callData = await callOverlayHandler({ + call: 'getCombatants', + ids: decIds, + }); + return callData.combatants; +}; Options.Triggers.push({ zoneId: ZoneId.TheMinstrelsBalladZodiarksFall, timelineFile: 'zodiark-ex.txt', + initData: () => ({ + activeSigils: [], + activeFrontSigils: [], + paradeigmaCounter: 0, + seenAdikia: false, + }), triggers: [ { id: 'ZodiarkEx Ania', @@ -10,7 +31,310 @@ Options.Triggers.push({ netRegexFr: NetRegexes.startsUsing({ id: '67EF', source: 'Zordiarche' }), netRegexJa: NetRegexes.startsUsing({ id: '67EF', source: 'ゾディアーク' }), netRegexCn: NetRegexes.startsUsing({ id: '67EF', source: '佐迪亚克' }), - response: Responses.tankBuster(), + response: Responses.tankBusterSwap(), + }, + { + id: 'ZodiarkEx Kokytos', + type: 'StartsUsing', + netRegex: NetRegexes.startsUsing({ id: '6C60', source: 'Zodiark', capture: false }), + netRegexDe: NetRegexes.startsUsing({ id: '6C60', source: 'Zodiark', capture: false }), + netRegexFr: NetRegexes.startsUsing({ id: '6C60', source: 'Zordiarche', capture: false }), + netRegexJa: NetRegexes.startsUsing({ id: '6C60', source: 'ゾディアーク', capture: false }), + netRegexCn: NetRegexes.startsUsing({ id: '6C60', source: '佐迪亚克', capture: false }), + response: Responses.bigAoe(), + }, + { + id: 'ZodiarkEx Paradeigma', + type: 'Ability', + netRegex: NetRegexes.ability({ id: '67BF', source: 'Zodiark', capture: false }), + netRegexDe: NetRegexes.ability({ id: '67BF', source: 'Zodiark', capture: false }), + netRegexFr: NetRegexes.ability({ id: '67BF', source: 'Zordiarche', capture: false }), + netRegexJa: NetRegexes.ability({ id: '67BF', source: 'ゾディアーク', capture: false }), + netRegexCn: NetRegexes.ability({ id: '67BF', source: '佐迪亚克', capture: false }), + alertText: (data, _matches, output) => { + ++data.paradeigmaCounter; + if (data.paradeigmaCounter === 1) + return output.underQuetz(); + }, + outputStrings: { + underQuetz: { + en: 'Under NW Quetzalcoatl', + de: 'Unter NW Quetzalcoatl', + }, + }, + }, + { + id: 'ZodiarkEx Styx', + type: 'StartsUsing', + netRegex: NetRegexes.startsUsing({ id: '67F3', source: 'Zodiark', capture: false }), + netRegexDe: NetRegexes.startsUsing({ id: '67F3', source: 'Zodiark', capture: false }), + netRegexFr: NetRegexes.startsUsing({ id: '67F3', source: 'Zordiarche', capture: false }), + netRegexJa: NetRegexes.startsUsing({ id: '67F3', source: 'ゾディアーク', capture: false }), + netRegexCn: NetRegexes.startsUsing({ id: '67F3', source: '佐迪亚克', capture: false }), + alertText: (_data, _matches, output) => output.text(), + outputStrings: { + text: { + en: 'Stack x6', + de: 'Sammeln x6', + }, + }, + }, + { + id: 'ZodiarkEx Arcane Sigil End', + type: 'Ability', + netRegex: NetRegexes.ability({ id: [sigil.greenBeam, sigil.redBox, sigil.blueCone], source: 'Arcane Sigil' }), + run: (data, matches, _output) => { + for (let i = 0; i < data.activeSigils.length; ++i) { + const sig = data.activeSigils[i]; + if (sig?.npcId === matches.sourceId) + data.activeSigils.splice(i, 1); + } + }, + }, + { + id: 'ZodiarkEx Blue Cone Tether', + type: 'Tether', + netRegex: NetRegexes.tether({ id: '00A4', source: 'Zodiark' }), + netRegexDe: NetRegexes.tether({ id: '00A4', source: 'Zodiark' }), + netRegexFr: NetRegexes.tether({ id: '00A4', source: 'Zordiarche' }), + netRegexJa: NetRegexes.tether({ id: '00A4', source: 'ゾディアーク' }), + netRegexCn: NetRegexes.tether({ id: '00A4', source: '佐迪亚克' }), + promise: async (data, matches) => { + const portalActors = await fetchCombatantsById([matches.targetId]); + for (const actor of portalActors) { + if (actor.ID) + data.activeSigils.push({ x: actor.PosX, y: actor.PosY, typeId: sigil.blueCone, npcId: actor.ID.toString(16).toUpperCase() }); + } + }, + alertText: (data, matches, output) => { + const target = data.activeSigils[data.activeSigils.length - 1]; + if (!target) { + console.error(`Blue Tether: Missing target, ${JSON.stringify(matches)}`); + return; + } + if (target.x < 100) + return output.westCone(); + if (target.x > 100) + return output.eastCone(); + if (target.y < 100) + return output.northCone(); + return output.southCone(); + }, + outputStrings: { + northCone: { + en: 'North Cone', + de: 'Nördliche Kegel-AoE', + }, + eastCone: { + en: 'East Cone', + de: 'Östliche Kegel-AoE', + }, + westCone: { + en: 'West Cone', + de: 'Westliche Kegel-AoE', + }, + southCone: { + en: 'South Cone', + de: 'Südliche Kegel-AoE', + }, + }, + }, + { + id: 'ZodiarkEx Red Box Tether', + type: 'Tether', + netRegex: NetRegexes.tether({ id: '00AB', source: 'Zodiark' }), + netRegexDe: NetRegexes.tether({ id: '00AB', source: 'Zodiark' }), + netRegexFr: NetRegexes.tether({ id: '00AB', source: 'Zordiarche' }), + netRegexJa: NetRegexes.tether({ id: '00AB', source: 'ゾディアーク' }), + netRegexCn: NetRegexes.tether({ id: '00AB', source: '佐迪亚克' }), + promise: async (data, matches) => { + const portalActors = await fetchCombatantsById([matches.targetId]); + for (const actor of portalActors) { + if (actor.ID) + data.activeSigils.push({ x: actor.PosX, y: actor.PosY, typeId: sigil.redBox, npcId: actor.ID.toString(16).toUpperCase() }); + } + }, + alertText: (data, matches, output) => { + const target = data.activeSigils[data.activeSigils.length - 1]; + if (!target) { + console.error(`Red Tether: Missing target, ${JSON.stringify(matches)}`); + return; + } + if (target.x < 100) + return output.east(); + if (target.x > 100) + return output.west(); + if (target.y < 100) + return output.south(); + return output.north(); + }, + outputStrings: { + north: Outputs.north, + west: Outputs.west, + south: Outputs.south, + east: Outputs.east, + }, + }, + { + id: 'ZodiarkEx Roiling Darkness Spawn', + type: 'AddedCombatant', + netRegex: NetRegexes.addedCombatant({ name: 'Roiling Darkness', capture: false }), + netRegexDe: NetRegexes.addedCombatant({ name: 'Strom Der Dunkelheit', capture: false }), + netRegexFr: NetRegexes.addedCombatant({ name: 'Orbe Des Ténèbres', capture: false }), + netRegexJa: NetRegexes.addedCombatant({ name: '闇の奔流', capture: false }), + netRegexCn: NetRegexes.addedCombatant({ name: '黑暗奔流', capture: false }), + suppressSeconds: 1, + alertText: (_data, _matches, output) => output.text(), + outputStrings: { + text: { + en: Outputs.killAdds.en + '(back first)', + de: Outputs.killAdds.de + '(hinten zuerst)', + }, + }, + }, + { + id: 'ZodiarkEx Arcane Sigil Start', + type: 'StartsUsing', + netRegex: NetRegexes.startsUsing({ id: [sigil.greenBeam, sigil.redBox, sigil.blueCone], source: 'Arcane Sigil' }), + netRegexDe: NetRegexes.startsUsing({ id: [sigil.greenBeam, sigil.redBox, sigil.blueCone], source: 'Geheimzeichen' }), + netRegexFr: NetRegexes.startsUsing({ id: [sigil.greenBeam, sigil.redBox, sigil.blueCone], source: 'Emblème Secret' }), + netRegexJa: NetRegexes.startsUsing({ id: [sigil.greenBeam, sigil.redBox, sigil.blueCone], source: '秘紋' }), + netRegexCn: NetRegexes.startsUsing({ id: [sigil.greenBeam, sigil.redBox, sigil.blueCone], source: '秘纹' }), + run: (data, matches, _output) => { + if (parseFloat(matches.y) < 100) + data.activeFrontSigils.push({ x: parseFloat(matches.x), y: parseFloat(matches.y), typeId: matches.id, npcId: matches.sourceId }); + }, + }, + { + id: 'ZodiarkEx Arcane Sigil', + type: 'StartsUsing', + netRegex: NetRegexes.startsUsing({ id: [sigil.greenBeam, sigil.redBox, sigil.blueCone], source: 'Arcane Sigil', capture: false }), + netRegexDe: NetRegexes.startsUsing({ id: [sigil.greenBeam, sigil.redBox, sigil.blueCone], source: 'Geheimzeichen', capture: false }), + netRegexFr: NetRegexes.startsUsing({ id: [sigil.greenBeam, sigil.redBox, sigil.blueCone], source: 'Emblème Secret', capture: false }), + netRegexJa: NetRegexes.startsUsing({ id: [sigil.greenBeam, sigil.redBox, sigil.blueCone], source: '秘紋', capture: false }), + netRegexCn: NetRegexes.startsUsing({ id: [sigil.greenBeam, sigil.redBox, sigil.blueCone], source: '秘纹', capture: false }), + delaySeconds: 0.2, + suppressSeconds: 0.5, + alertText: (data, _matches, output) => { + const activeFrontSigils = data.activeFrontSigils; + data.activeFrontSigils = []; + if (activeFrontSigils.length === 1 && activeFrontSigils[0]?.typeId === sigil.greenBeam) + return output.sides(); + if (activeFrontSigils.length === 1 && activeFrontSigils[0]?.typeId === sigil.redBox) + return output.south(); + if (activeFrontSigils.length === 1 && activeFrontSigils[0]?.typeId === sigil.blueCone) + return output.north(); + if (activeFrontSigils.length === 2 && activeFrontSigils[0]?.typeId === sigil.greenBeam && activeFrontSigils[1]?.typeId === sigil.greenBeam) + return output.middle(); + if (activeFrontSigils.length === 3) { + for (const sig of activeFrontSigils) { + // Find the middle sigil + if (sig.x > 90 && sig.x < 110) { + if (sig.typeId === sigil.greenBeam) + return output.frontsides(); + if (sig.typeId === sigil.redBox) + return output.backmiddle(); + if (sig.typeId === sigil.blueCone) + return output.frontmiddle(); + } + } + } + }, + outputStrings: { + south: Outputs.south, + north: Outputs.north, + frontsides: { + en: 'front sides', + de: 'Vorne Seiten', + }, + backmiddle: { + en: 'back middle', + de: 'Hinten Mitte', + }, + frontmiddle: { + en: 'front middle', + de: 'Vorne Mitte', + }, + sides: { + // Specify "for laser" to disambiguate with the astral eclipse going on at the same time. + // Similarly, there's a algodon knockback call too. + en: 'sides (for laser)', + de: 'Seiten (für die Laser)', + }, + middle: { + en: 'middle (for laser)', + de: 'Mitte (für die Laser)', + }, + }, + }, + { + // 67EC is leaning left, 67ED is leaning right + id: 'ZodiarkEx Algedon', + type: 'StartsUsing', + netRegex: NetRegexes.startsUsing({ id: ['67EC', '67ED'], source: 'Zodiark' }), + netRegexDe: NetRegexes.startsUsing({ id: ['67EC', '67ED'], source: 'Zodiark' }), + netRegexFr: NetRegexes.startsUsing({ id: ['67EC', '67ED'], source: 'Zordiarche' }), + netRegexJa: NetRegexes.startsUsing({ id: ['67EC', '67ED'], source: 'ゾディアーク' }), + netRegexCn: NetRegexes.startsUsing({ id: ['67EC', '67ED'], source: '佐迪亚克' }), + alertText: (_data, matches, output) => { + if (matches.id === '67EC') { + // NE/SW + return output.combo({ first: output.northeast(), second: output.southwest() }); + } + if (matches.id === '67ED') { + // NW/SE + return output.combo({ first: output.northwest(), second: output.southeast() }); + } + }, + outputStrings: { + northeast: Outputs.dirNE, + northwest: Outputs.dirNW, + southeast: Outputs.dirSE, + southwest: Outputs.dirSW, + combo: { + en: 'Go ${first} / ${second} (knockback)', + de: 'Geh ${first} / ${second} (Rückstoß)', + }, + }, + }, + { + id: 'ZodiarkEx Adikia', + type: 'StartsUsing', + netRegex: NetRegexes.startsUsing({ id: '63A9', source: 'Zodiark', capture: false }), + netRegexDe: NetRegexes.startsUsing({ id: '63A9', source: 'Zodiark', capture: false }), + netRegexFr: NetRegexes.startsUsing({ id: '63A9', source: 'Zordiarche', capture: false }), + netRegexJa: NetRegexes.startsUsing({ id: '63A9', source: 'ゾディアーク', capture: false }), + netRegexCn: NetRegexes.startsUsing({ id: '63A9', source: '佐迪亚克', capture: false }), + alertText: (data, _matches, output) => { + return data.seenAdikia ? output.adikia2() : output.adikia1(); + }, + run: (data) => data.seenAdikia = true, + outputStrings: { + adikia1: { + en: 'Double fists (look for pythons)', + de: 'Doppel-Fäuste (halt Ausschau nach den Pythons)', + }, + adikia2: { + en: 'Double fists', + de: 'Doppel-Fäuste', + }, + }, + }, + { + id: 'ZodiarkEx Phobos', + type: 'StartsUsing', + netRegex: NetRegexes.startsUsing({ id: '67F0', source: 'Zodiark', capture: false }), + netRegexDe: NetRegexes.startsUsing({ id: '67F0', source: 'Zodiark', capture: false }), + netRegexFr: NetRegexes.startsUsing({ id: '67F0', source: 'Zordiarche', capture: false }), + netRegexJa: NetRegexes.startsUsing({ id: '67F0', source: 'ゾディアーク', capture: false }), + netRegexCn: NetRegexes.startsUsing({ id: '67F0', source: '佐迪亚克', capture: false }), + infoText: (_data, _matches, output) => output.text(), + outputStrings: { + text: { + en: 'Heavy DoT', + de: 'Starker DoT', + }, + }, }, ], timelineReplace: [