raidboss: dmu p1 initial triggers#1069
Conversation
|
Also, I looked a bit at o8s to grab some of the outputs to match. |
|
I'll probably work on the tethers tomorrow, then it should be ready? |
wexxlee
left a comment
There was a problem hiding this comment.
Leaving some fast comments now; will hopefully be able to give a more complete review after I jump in later tonight.
In case it helps, for tethers, there's an ActorSetPos line that comes out with each tether, moving the invisible add that the player is tethered to to either: |
Thanks. I am almost done with the tether triggers, I am just trying to fix tts collisions at this point before pushing. EDIT: Here is my current draft. It conflicts with left/right call and the ice call (within 1s), the pulse call is within 2s but I shortened it to knockback. {
id: 'DMU ActorSetPos Tracker',
// Only in use for P1 Graven Image tethers
type: 'ActorSetPos',
netRegex: { id: '4[0-9A-Fa-f]{7}', capture: true },
run: (data, matches) =>
data.actorPositions[matches.id] = {
x: parseFloat(matches.x),
y: parseFloat(matches.y),
heading: parseFloat(matches.heading),
},
},
{
id: 'DMU Graven Image Tether Collect',
// 271 ActorSetPos lines indicate where the tether is coming from
// 261 CombatantMemory lines may also indicate this
// Graven Image 1:
// (100, 56, 18.5) Center Tether, Will be target of BAA9 Pulse Wave (knockback)
// Graven Image 2:
// (102.5, 27, 22.5) Center Tether, Will be target of BAAC Gravitas (puddles)
// (126, 41.5, 7) Right Tether, Will be target of BAB0 Vitrophyre (rocks)
// Graven Image 3:
// (95, 25, 27) Left Tether, Will be target of BAB5 Indulgent Will which causes 503 Confused
// (107, 43, 8.5) Right tether, Will be target of BAB6 Idyllic Will which causes 131E Sleep
type: 'Tether',
netRegex: { id: headMarkerData['imageTether'], capture: true },
condition: Conditions.targetIsYou(),
delaySeconds: 0.1, // Actor position data can come after tether in log
run: (data, matches) => {
const actor = data.actorPositions[matches.sourceId];
if (actor === undefined) {
data.gravenImageTether = 'unknown';
return;
}
const x = actor.x;
// Graven Image 1: Pulse Wave target
if (x < 101 && x > 99)
data.gravenImageTether = 'pulse';
else if (x < 103 && x > 101) // Graven Image 2: Gravitas target
data.gravenImageTether = 'gravitas';
else if (x > 125) // Graven Image 2: Vitrophyre target
data.gravenImageTether = 'vitrophyre';
else if (x < 100) // Graven Image 3: Indulgent Will target
data.gravenImageTether = 'indulgent';
else if (x < 108 && x > 106) // Graven Image 3: Idyllic Will target
data.gravenImageTether = 'idyllic';
else
data.gravenImageTether = 'unknown';
},
},
{
id: 'DMU Graven Image Tether',
type: 'Tether',
netRegex: { id: headMarkerData['imageTether'], capture: true },
condition: Conditions.targetIsYou(),
delaySeconds: 0.1, // Actor position data can come after tether in log
infoText: (data, matches, output) => {
const actor = data.actorPositions[matches.sourceId];
if (actor === undefined)
return output.tetherOnYou!();
const x = actor.x;
// Graven Image 1: Pulse Wave target
if (x < 101 && x > 99)
return output.pulse!();
else if (x < 103 && x > 101) // Graven Image 2: Gravitas target
return output.gravitas!();
else if (x > 125) // Graven Image 2: Vitrophyre target
return output.vitrophyre!();
else if (x < 100) // Graven Image 3: Indulgent Will target
return output.indulgent!();
else if (x < 108 && x > 106) // Graven Image 3: Idyllic Will target
return output.idyllic!();
else
return output.tetherOnYou!();
},
outputStrings: {
tetherOnYou: {
en: 'Tether on YOU',
de: 'Verbindung auf DIR',
fr: 'Lien sur VOUS',
ja: '線ついた',
cn: '连线点名',
ko: '선 대상자 지정됨',
tc: '連線點名',
},
pulse: Outputs.knockback, // Cannot be immuned, happens within 6s of tether
gravitas: {
en: 'Puddle Tether on YOU',
},
vitrophyre: {
en: 'Rock Tether on YOU',
},
indulgent: {
en: 'Confuse Tether on YOU',
},
idyllic: {
en: 'Sleep Tether on YOU',
},
},
},
{
id: 'DMU P1 Graven Image Tether Cleanup',
// Clear on Ability:
// BAA9 Pulse Wave
// BAAC Gravitas
// BAB0 vitrophyre
// BAB5 Indulgent Will
// BAB6 Idyllic Will
type: 'Ability',
netRegex: {
id: ['BAA9', 'BAAC', 'BAB0', 'BAB5', 'BAB6'],
source: 'Graven Image',
capture: true,
},
suppressSeconds: 1,
run: (data, matches) => {
// Player could die and this ability then not target them
// Need intelligent way to remove once related ability has executed
// Clear data if ability matches our tether
const abilityMap = {
'pulse': 'BAAC',
'gravitas': 'BAA9',
'vitrophyre': 'BAB0',
'indulgent': 'BAB5',
'idyllic': 'BAB6',
'unknown': 'unknown',
};
const tether = data.gravenImageTether ?? 'unknown';
const tetherAbilityId = abilityMap[tether as keyof typeof abilityMap];
if (tetherAbilityId === matches.id || tether === 'unknown')
delete data.gravenImageTether;
},
}, |
The animation is visible ~9.89s before cast goes off, however When animation becomes visible, the players will bbe asleep or confused for another ~3.4s. Once the debuff ends the players have ~6.4s to turn character
|
More testing tonight, most things look good apart from Wave Cannon, Intemperate Will, and Gravitational Wave. As it stands, the call triggers seem to be racing against the collection trigger and winning. I think we need a short delay on each of the call triggers, and then to check the IDs within the popup text function bodies. For example: {
id: 'DMU P1 Impertinent Will',
type: 'ActorControlExtra',
netRegex: { category: '019D', param1: '40', param2: '80', capture: true },
delaySeconds: 1,
alertText: (data, matches, output) => {
if (data.yellowTowerId === matches.id)
return output.goWest!();
},
outputStrings: {
goWest: Outputs.getLeftAndWest,
},
},Alternatively, it might make sense to do a single (Do also note, I'm not going to be able to test triggers much after this week. It's getting distracting to watch for triggers while I'm running with my group, and we're getting into phase 2 enough that I need to be able to focus more. I will be able to test and review timelines though.) |
Shoot, I missed that the promise can take time to set the value.
Less calls to overlayplugin is good. I see this wouldn't be the first time something like this was done. R4N on the first cast by boss has a collector. We can use suppressSeconds here to just do it once. |
|
Yeah, I prefer to avoid calling |
I tried it out, but raidemulator seems to only find the PluginCombatantStates without ID attribute for some reason, so raidemulator isn't able to store IDs to lookup later. Might have it while in game, but not sure. Possibly a bug in the raid emulator not tacking on the ID field from the Add to the plugincombatantstate? |
|
Okay, well I have a solution that works without OverlayPlugin and no need to know bnpcids... It seems that the IDs follow a strict pattern so can just do this on the first tower since it seems to always be the highest ID. const id = parseInt(matches.id, 16);
const blueTowers = [id, id - 1]; // First tower is blue and highest ID
const purpleTowers = [id - 2, id - 4];
const yellowTowers = [id - 3, id - 5];
const eyeTowers = [id - 7, id - 9];
const fakeEyeTowers = [id - 6, id - 8]; |
Since first trigger of the ActorControlExtra is a blue tower, can skip the check and suppress since this only happens once in P1.
|
I have a config for kefka bin and filipino teleportents, but I think it should be held off on for a separate pr. |
There were also cases where player could die to the knockback and still be called in the early trigger.
Remove players from the output if they died between receiving the buff and knockback call.
JLGarber
left a comment
There was a problem hiding this comment.
Further testing tonight looks okay in-game. I'm not strictly happy about relying on the order of entity IDs, but I saw no errors. I think we can merge this and then handle issues as people report them.
Addon to OverlayPlugin#1068. Adds initial p1 triggers. 4d97886
Addon to #1068.
Adds some triggers that I worked on today.
Still to be tested, but raidemulator seemed okay. Currently missing the Graven Image 2 tell, though it is tracked.