Skip to content

Commit 6d9744d

Browse files
committed
encounter_tools: attempt to support CEs without breaking others
I'm not certain this works properly yet, but it appears to locate the CEs if I merge with my occult crescent timeline file. Instead of blindly listing all CEs with their ID, I added look up tables for the CEs to resources. I suspect there is a more elegant way to do this, with less boiler plate code. I also don't really know how to share this data with the trigger files, which need inverted mappings. This method is similar to some code written by Valarnin, but I adapted it so that it will only apply to known valid CEs. That should prevent breaking any other zones or encounter logic. I'm open to other methods of integrating CE support if there are better solutions. Signed-off-by: Jacob Keller <[email protected]>
1 parent 1b2f500 commit 6d9744d

File tree

2 files changed

+111
-1
lines changed

2 files changed

+111
-1
lines changed

resources/ce_info.ts

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// I have no idea if this could be automatically generated
2+
// TODO: share these somehow with the trigger file?
3+
4+
type CEMap = { [id: string]: string };
5+
6+
export const OccultCrescentSouthHornCEs: CEMap = {
7+
'32F': 'Calamity Bound',
8+
'343': 'Company Of Stone',
9+
'330': 'Crawling Death',
10+
'32B': 'Cursed Concern',
11+
'329': 'Eternal Watch',
12+
'32A': 'Flame Of Dusk',
13+
'323': 'From Times Bygone',
14+
'327': 'Noise Complaint',
15+
'338': 'On The Hunt',
16+
'320': 'Scourge Of The Mind',
17+
'32E': 'Shark Attack',
18+
'322': 'The Black Regiment',
19+
'348': 'The Unbridled',
20+
'349': 'Trial By Claw',
21+
'339': 'With Extreme Predjudice',
22+
};
23+
24+
export const BozjanSouthernFrontCEs: CEMap = {
25+
'1CA': 'The Hunt for Red Choctober',
26+
'1CB': 'Metal Fox Chaos',
27+
'1CC': 'The Baying of the Hound(s)',
28+
'1CD': 'The Shadow of Death\'s Hand',
29+
'1CE': 'Trampled under Hoof',
30+
'1D0': 'Vigil for the Lost',
31+
'1D1': 'Patriot Games',
32+
'1D2': 'Aces High',
33+
'1D3': 'And the Flames Went Higher',
34+
'1D4': 'Kill It with Fire',
35+
'1D5': 'The Final Furlong',
36+
'1D6': 'The Fires of War',
37+
'1D7': 'The Battle of Castrum Lacus Litore',
38+
'1D8': 'Adrammelech',
39+
'1DA': 'Albeleo',
40+
'1DB': 'Beast of Man',
41+
'1DC': 'Where Strode the Behemoth',
42+
'1DF': 'Rise of the Robots\'',
43+
};
44+
45+
export const ZadnorCEs: CEMap = {
46+
'207': 'Looks to Die For',
47+
'20E': 'Feeling the Burn',
48+
'20F': 'Never Cry Wolf',
49+
'210': 'There Would Be Blood',
50+
'211': 'On Serpents\' Wings',
51+
'212': 'A Familiar Face',
52+
'218': 'Lean, Mean, Magitek Machines',
53+
'21B': 'From Beyond the Grave',
54+
'21C': 'Here Comes the Cavalry',
55+
'21D': 'Time To Burn',
56+
'21E': 'Head of the Snake',
57+
'21F': 'The Broken Blade',
58+
'220': 'Taking the Lyon\'s Share',
59+
'221': 'With Diremite and Main',
60+
'222': 'Worn to a Shadow',
61+
'213': 'The Dalriada',
62+
'214': 'The Dalraida - Cuchulainn',
63+
'215': 'The Dalriada - Hallway',
64+
'216': 'The Dalriada - Saunion',
65+
'217': 'The Dalriada - Diablo',
66+
};

util/logtools/encounter_tools.ts

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
1+
import {
2+
BozjanSouthernFrontCEs,
3+
OccultCrescentSouthHornCEs,
4+
ZadnorCEs,
5+
} from '../../resources/ce_info';
16
import ContentType from '../../resources/content_type';
27
import DTFuncs from '../../resources/datetime';
38
import NetRegexes, { commonNetRegex } from '../../resources/netregexes';
49
import { UnreachableCode } from '../../resources/not_reached';
510
import PetData from '../../resources/pet_names';
611
import StringFuncs from '../../resources/stringhandlers';
12+
import ZoneId from '../../resources/zone_id';
713
import ZoneInfo from '../../resources/zone_info';
814
import { NetAnyMatches, NetMatches } from '../../types/net_matches';
915
import { CactbotBaseRegExp } from '../../types/net_trigger';
@@ -90,6 +96,7 @@ export class EncounterFinder {
9096
currentZone: ZoneEncInfo = {};
9197
currentFight: FightEncInfo = {};
9298
currentSeal?: string;
99+
currentCE?: string;
93100
zoneInfo?: typeof ZoneInfo[number];
94101

95102
haveWon = false;
@@ -112,6 +119,7 @@ export class EncounterFinder {
112119

113120
sealRegexes: Array<CactbotBaseRegExp<'GameLog'>> = [];
114121
unsealRegexes: Array<CactbotBaseRegExp<'GameLog'>> = [];
122+
ceRegex: CactbotBaseRegExp<'ActorControl'>;
115123

116124
initializeZone(): void {
117125
this.currentZone = {};
@@ -152,6 +160,8 @@ export class EncounterFinder {
152160
const line = `.*?${lang}.*?`;
153161
this.unsealRegexes.push(NetRegexes.message({ line: line }));
154162
}
163+
164+
this.ceRegex = NetRegexes.network6d({ command: '80000014' });
155165
}
156166

157167
skipZone(): boolean {
@@ -324,6 +334,12 @@ export class EncounterFinder {
324334
return;
325335
}
326336
}
337+
338+
const ce = this.ceRegex.exec(line)?.groups;
339+
340+
if (ce) {
341+
this.onCE(line, ce);
342+
}
327343
}
328344

329345
// start/endZone always bracket all fights and seals.
@@ -340,7 +356,7 @@ export class EncounterFinder {
340356
}
341357
onStartFight(
342358
line: string,
343-
matches: NetMatches['Ability' | 'GameLog' | 'SystemLogMessage' | 'InCombat'],
359+
matches: NetMatches['Ability' | 'ActorControl' | 'GameLog' | 'SystemLogMessage' | 'InCombat'],
344360
fightName?: string,
345361
sealId?: string,
346362
): void {
@@ -380,6 +396,34 @@ export class EncounterFinder {
380396
this.onEndFight(line, matches, 'Unseal');
381397
this.currentSeal = undefined;
382398
}
399+
400+
onCE(line: string, matches: NetMatches['ActorControl']): void {
401+
let validCEs = undefined;
402+
if (this.currentZone.zoneId === ZoneId.TheBozjanSouthernFront) {
403+
validCEs = BozjanSouthernFrontCEs;
404+
} else if (this.currentZone.zoneId === ZoneId.Zadnor) {
405+
validCEs = ZadnorCEs;
406+
} else if (this.currentZone.zoneId === ZoneId.TheOccultCrescentSouthHorn) {
407+
validCEs = OccultCrescentSouthHornCEs;
408+
} else {
409+
return;
410+
}
411+
412+
if (matches.data0 === '00') {
413+
this.onEndFight(line, matches, 'CE End');
414+
this.currentCE = undefined;
415+
} else {
416+
const id = matches.data0;
417+
const ceName = validCEs[id];
418+
419+
if (ceName === undefined) {
420+
return;
421+
}
422+
423+
this.currentCE = id;
424+
this.onStartFight(line, matches, ceName);
425+
}
426+
}
383427
}
384428

385429
class EncounterCollector extends EncounterFinder {

0 commit comments

Comments
 (0)