-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDetectTraps.js
More file actions
219 lines (201 loc) · 12.2 KB
/
Copy pathDetectTraps.js
File metadata and controls
219 lines (201 loc) · 12.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
/* Usage: /:DetectTraps title="<title>"" dice=<dice> adds=<adds> type=<type> adiv=<divisor> rsize=<rsize> attrib=<attribute> difmod=<difficulty> skill=<skill> detectwith=<detectWith> detectdif=<detectDif> tag=<trapTileTag>
Title - name to display on dialog
Dice - dice of damage per energy point; may be a fraction
Adds - modifier to each die of damage, zero if none
Type - Damage type (cr, cut, burn, etc...)
Divisor / Radius - Reduce DR by (x) or spread to Radius hexes
Attribute - DX, ST, DX, IQ, Will, etc
Difficulty Modifier - Trap difficulty
Skill - Skill name Precheck to evade, i.e. Acrobatics
Detect With - Skill or Attribute to detect the trap, i.e. Perception
Detect Difficulty - Difficulty to detect trap; default to trap difficulty
Trap Tile Tag - Tagger tag name for the tile to trigger, default to SpikeTrap01
DetectTraps lets you auto-detect a trap;
Required Macros: DetectTraps, EvadeTrap, ResistEffect
Optional Macros: PoisonSpray, YellowMoldSpores, AlchemistFire, SpikeTrap100x100px, SpikeTrap160x160px
Add your own special effects to this recipe book.
Example chat commands to use in MATT for various trap types (adjust to fit your own trap designs):
/:DetectTraps title="AxeTrap" dice=5d adds=2 type=cut armordiv=5 attrib=DX difmod=-4 skill=Acrobatics detectwith=!PER! detectdif=-6 tag=BuxlanTorAxeTrap01
/:DetectTraps title="Caltrops" dice=1 adds=0 type=thr armordiv=0 attrib=DX difmod=-2 skill=Acrobatics detectwith=!PER! detectdif=-2 tag=DungeonCave05Caltrops01
/:DetectTraps title="AlchemistFire" dice=4 adds=4 type=burn armordiv=5 attrib=DX difmod=-6 skill=Acrobatics detectwith=!PER! detectdif=-8 tag=BuxlanTorrapStatue05
/:DetectTraps title="YellowMold" dice=2 adds=3 type=tox armordiv=3 attrib=HT difmod=-6 skill=Jumping detectwith=!PER! detectdif=-6 tag=BuxlanTorrapStatue01
/:DetectTraps title="Poison" dice=1 adds=9 type=tox armordiv=3 attrib=HT difmod=-3 skill=Jumping detectwith=!PER! detectdif=-8 tag=DungeonCave05TrapStatue03
/:DetectTraps title="Spike Trap" dice=1 adds=9 type=imp rsize=3 attrib=DX difmod=-6 skill=Acrobatics detectwith=!PER! tag=SpikeTrap01
/:DetectTraps title="Pitfall Trap" dice=3 adds=6 type=pi++ rsize=2 attrib=DX difmod=-4 skill=Jumping detectwith=!PER! tag=PitfallTrap01
/:DetectTraps title="AlchemistFire" dice=4 adds=4 type=burn rsize=3 attrib=DX difmod=-5 skill=Jumping detectwith=!PER! detectdif=-8 tag=BuxlanTorrapStatue05
Evade example:
/:EvadeTrap title="Spike Trap" dice=1 adds=9 type=imp rsize=3 attrib=DX difmod=-6 skill=Acrobatics detectwith=!PER! tag=SpikeTrap01
/:EvadeTrap title="Pitfall Trap" dice=3 adds=3 type=pi++ rsize=2 attrib=DX difmod=-4 skill=Acrobatics detectwith=!PER! tag=PitfallTrap01
/:EvadeTrap title="AlchemistFire" dice=4 adds=4 type=burn rsize=3 attrib=DX difmod=-5 skill=Jumping detectwith=!PER! detectdif=-8 tag=BuxlanTorrapStatue05
Difficulty Examples:
- Evade Crude "Spike Trap" DX+2
- Evade Basic "Spike Trap" DX
- Evade Devious "Spike Trap" DX-4
- Evade Vicious "Spike Trap" DX-6
- Evade Deadly "Spike Trap" DX-8
- ["Evade Deadly Spike Trap DX-8"/DX-8 You Evade! /else [3d+3 (2) pi++]
*/
console.log(`---------- Start DetectTraps ---------`);
// optional parameters
// Sk:Default=4
// setup defaults
let title = 'Trap'; // default to Trap; for special types. include a key phrase like "YellowMold" or "Poison"
let dice = 1; // default to 1 die
let adds = 0; // damage bonus default to 0
let type = 'cr'; // default to crushing
let armorDivisor = 0; // default to 0
let radius = 1; // default to 1 hex
let attribName = 'DX'; // default to DX
let difMod = 0; // Trap difficulty
let skillName = 'Jumping'; // default to Jumping for evade
let detectWith = '!PER!'; // default to Perception
// detect difficulty defaults to trap difficulty if not specified separately !PER-${detectDif}!
let detectDif = difMod; // difficulty to detect trap; default to trap difficulty
let trapTag = 'SpikeTrap01'; // tag name for the tile to trigger, default to SpikeTrap01
try {
console.log(scope)
title = scope.title ? scope.title : title;
dice = scope.dice ? parseInt(scope.dice) : dice;
adds = scope.adds ? parseInt(scope.adds) : adds;
type = scope.type ? scope.type : type;
armorDivisor = scope.armordiv ? parseInt(scope.armordiv) : armorDivisor;
radius = scope.rsize ? parseInt(scope.rsize) : radius;
attribName = scope.attrib ? scope.attrib : attribName;
difMod = scope.difmod ? parseInt(scope.difmod) : difMod;
skillName = scope.skill ? scope.skill : skillName;
detectWith = scope.detectwith ? scope.detectwith : detectWith;
detectDif = scope.detectdif ? parseInt(scope.detectdif) : difMod;
trapTag = scope.tag ? scope.tag : trapTag;
} catch (error) {
console.error('Error accessing scope:', error);
}
//
console.log(`---------- Traps detect difficulty detectDif: ${detectDif};`);
console.log(`title: ${title}; dice: ${dice}; adds: ${adds}; type: ${type}; difMod: ${difMod}; attribName: ${attribName}; detectDif: ${detectDif}; trapTag: ${trapTag}`);
// validate dice
let attackDmgDice,attackDmgAmount,attackDmgBonus;
let attackDamageOtF = dice;
let findDice = /\d+d/;
let lastActor = GURPS.LastActor;
if (dice.isNaN) {
attackDmgDice = scope.dice? scope.dice.split('d')[0]: 1; //restore scope.dice and split it
console.log(`NaN attackDmgDice: ${attackDmgDice};`);
} else if (findDice.test(attackDamageOtF)) {
attackDmgDice = attackDamageOtF.split(' ')[0].split('d')[0];
console.log(`attackDmgDice: ${attackDmgDice};`);
} else if (title.includes('Caltrops') == true) {
// Caltrops gets basic damage from the last actor's thrust damage
// no dice in the attackDamageOtF, so use the last actor's thrust damage under assumptions
attackDamageOtF = lastActor.system.thrust;
attackDmgAmount = attackDamageOtF.split(' ')[0];
attackDmgDice = attackDamageOtF.split(' ')[0].split('d')[0];
attackDmgBonus = attackDamageOtF.split(' ')[0].split('d')[1] != undefined ? attackDamageOtF.split(' ')[0].split('d')[1] : 0;
console.log(`Caltrops damage is thrust (lastActor.system.thrust), so attackDmgAmount: ${attackDmgAmount}; attackDmgDice: ${attackDmgDice}; attackDmgBonus: ${attackDmgBonus};`);
dice= `${attackDmgDice}d`;
adds=adds+Number(attackDmgBonus);
console.log(`---------- Recalculated dice from thrust + adds: ${dice}; adds: ${adds};`);
}
// detect
let detectWarningTxt = `You detect a trap!`;
let detectWarningCritTxt = `You detect a trap with such precision that you gain +3 to disarm it! Use [+3 to disarm]`;
let rslTraps = 'PER-5'; // default detect traps
let trapsMod = -5;
let adjustedTrapsMod = -5;
let trapsObj;
let hasTraps = await GURPS.findSkillSpell(_token.actor, 'Traps', true) != undefined ? true : false;
if (hasTraps == true) {
trapsObj = GURPS.findSkillSpell(_token.actor, 'Traps', true);
rslTraps = trapsObj.relativelevel;
console.log(`rslTraps: ${rslTraps};`);
if (rslTraps.includes('-') == true) {
trapsMod = -Number(rslTraps.split('-')[1]);
console.log(`trapsMod from rslTraps: ${trapsMod};`);
} else if (rslTraps.includes('+') == true) {
trapsMod = Number(rslTraps.split('+')[1]); // split(/[+-]/)[1]
console.log(`trapsMod from rslTraps: ${trapsMod};`);
}
}
adjustedTrapsMod = Number(trapsMod)+Number(detectDif);
if (Number.isNaN(adjustedTrapsMod)) adjustedTrapsMod = detectDif;
console.log(`adjustedTrapsMod: ${adjustedTrapsMod};`);
let critFailDifMod = Number(difMod)-5;
console.log(`critFailDifMod: ${critFailDifMod};`);
let modTxt = '';
if (adjustedTrapsMod > -1) modTxt = '+';
let evadeTrapsOtF = '';
let evadeTrapsCfOtF = '';
let resistTrapsOtF = '';
let resistTrapsCfOtF = '';
let failTrapsOtF = '';
let critFailTrapsOtF = '';
let detectTrapsOtF = ``; //${detectWith}${adjustedTrapsMod}
if (game.users.current.isGM) {
detectTrapsOtF = `[PER${modTxt}${adjustedTrapsMod} | Sk:Default=4]`; // ${detectWith}${adjustedTrapsMod} - always default ra 4
} else {
detectTrapsOtF = `[!PER${modTxt}${adjustedTrapsMod}! | !Sk:Default=4]`; // ${detectWith}${adjustedTrapsMod}
}
let dtOtF = '';
// /:EvadeTrap title="AxeTrap" dice=5d adds=2 type=cut armordiv=5 attrib=DX difmod=-4 skill=Acrobatics detectwith=!PER! detectdif=-6
evadeTrapsOtF =`/:EvadeTrap title="${title}" dice=${dice} adds=${adds} type=${type} armordiv=${armorDivisor} attrib=${attribName} difmod=${difMod} skill=${skillName}`;
evadeTrapsCfOtF =`/:EvadeTrap title="${title}" dice=${dice} adds=${adds} type=${type} armordiv=${armorDivisor} attrib=${attribName} difmod=${critFailDifMod} skill=${skillName}`;
resistTrapsOtF = `/:ResistEffect title="${title}" dice=${dice} adds=${adds} type=${type} rsize=${radius} attrib=${attribName} difmod=${difMod}`;
resistTrapsCfOtF = `/:ResistEffect title="${title}" dice=${dice} adds=${adds} type=${type} rsize=${radius} attrib=${attribName} difmod=${critFailDifMod}`;
// Add recipes for special trap effects here
if (title.includes('Poison') == true) {
///:ResistEffect Poison 1d 9 tox 3 HT -6] /:DetectTraps Poison 1d 9 tox 3 HT -6 Jumping !PER! -8 BuxlanTorrapStatue01
failTrapsOtF = `/:PoisonSpray tag=${trapTag} \\\\${resistTrapsOtF}`;
critFailTrapsOtF = `/:PoisonSpray tag=${trapTag} \\\\${resistTrapsCfOtF}`;
console.log(`Poison: ResistEffect;`);
console.log(`resistTrapsOtF: ${resistTrapsOtF}`);
console.log(`failTrapsOtF: ${failTrapsOtF}`);
console.log(`critFailTrapsOtF: ${critFailTrapsOtF}`);
} else if (title.includes('YellowMold') == true) {
failTrapsOtF = `/:YellowMoldSpores tag=${trapTag} \\\\${evadeTrapsOtF}`;
critFailTrapsOtF = `/:YellowMoldSpores tag=${trapTag} \\\\${evadeTrapsCfOtF}`;
console.log(`YellowMold: ResistEffect;`);
console.log(`evadeTrapsOtF: ${evadeTrapsOtF}`);
console.log(`failTrapsOtF: ${failTrapsOtF}`);
console.log(`critFailTrapsOtF: ${critFailTrapsOtF}`);
} else if (title.includes('AlchemistFire') == true) {
///:ResistEffect AlchemistFire 1d 9 tox 3 HT -6] /:DetectTraps "AlchemistFire" 4d 4 burn 5 DX -6 Acrobatics -8 BuxlanTorrapStatue05
failTrapsOtF = `/:AlchemistFire tag=${trapTag} \\\\${evadeTrapsOtF}`;
critFailTrapsOtF = `/:AlchemistFire tag=${trapTag} \\\\${evadeTrapsCfOtF}`;
console.log(`AlchemistFire: EvadeTrap;`); // switch to ResistEffect by using resistTrapsOtF instead of evadeTrapsCfOtF
console.log(`resistTrapsOtF: ${resistTrapsOtF}`);
console.log(`failTrapsOtF: ${failTrapsOtF}`);
console.log(`critFailTrapsOtF: ${critFailTrapsOtF}`);
} else if (title.includes('Caltrops') == true) {
failTrapsOtF = `!/anim Caltrops01_01_Regular_Grey c *0.3 @self \\\\${evadeTrapsOtF}`;
critFailTrapsOtF = `!/anim Caltrops01_01_Regular_Grey c *0.3 @self \\\\${evadeTrapsCfOtF}`;
console.log(`Physical EvadeTrap: ${title};`);
console.log(`failTrapsOtF: ${failTrapsOtF}`);
console.log(`critFailTrapsOtF: ${critFailTrapsOtF}`);
} else if (title.includes('AxeTrap') == true) {
// /:EvadeTrap title="AxeTrap" dice=5d adds=2 type=cut armordiv=5 attrib=DX difmod=-4 skill=Acrobatics detectwith=!PER! detectdif=-6
failTrapsOtF = `${evadeTrapsOtF} \\\\/:TriggerTrap tag=${trapTag}`;
critFailTrapsOtF = `${evadeTrapsCfOtF} \\\\/:TriggerTrap tag=${trapTag}`
console.log(`Physical EvadeTrap: ${title};`);
console.log(`failTrapsOtF: ${failTrapsOtF}`);
console.log(`critFailTrapsOtF: ${critFailTrapsOtF}`);
//game.macros.getName('TriggerActiveTile').execute({tag: trapTag, victim: _token.id}); // TriggeredBuxlanTorAxeTrap01
} else {
console.log(`Physical EvadeTrap: ${title}; trapTag: ${trapTag}`);
if (trapTag == 'BuxlanTorSpikeTrap03') {
failTrapsOtF = `/:SpikeTrap100x100px tag=${trapTag} \\\\${evadeTrapsOtF}`;
critFailTrapsOtF = `/:SpikeTrap100x100px tag=${trapTag} \\\\${evadeTrapsCfOtF}`;
} else if (trapTag == 'BuxlanTorSpikeTrap02') {
failTrapsOtF = `/:SpikeTrap160x160px tag=${trapTag} \\\\${evadeTrapsOtF}`;
critFailTrapsOtF = `/:SpikeTrap160x160px tag=${trapTag} \\\\${evadeTrapsCfOtF}`;
} else if (trapTag == 'BuxlanTorSpikeTrap01') {
failTrapsOtF = `/:SpikeTrap160x160px tag=${trapTag} \\\\${evadeTrapsOtF}`;
critFailTrapsOtF = `/:SpikeTrap160x160px tag=${trapTag} \\\\${evadeTrapsCfOtF}`;
}
console.log(`Physical EvadeTrap;`);
console.log(`failTrapsOtF: ${failTrapsOtF}`);
console.log(`critFailTrapsOtF: ${critFailTrapsOtF}`);
}
console.log(`failTrapsOtF: ${failTrapsOtF}`);
dtOtF = `/if ${detectTrapsOtF} s:{${detectWarningTxt}} cs:{${detectWarningCritTxt}} f:{${failTrapsOtF}} cf:{${critFailTrapsOtF}}`;
console.log(dtOtF);
await GURPS.executeOTF(dtOtF);
console.log(`---------- End DetectTraps ---------`);