|
86 | 86 | `{{--cardstyles|-cl=List all card styles}} ` + |
87 | 87 | `{{--cardstyle|-C [StyleName] [property] [value]=Edit or create a card style}} ` + |
88 | 88 | `{{--delete|-D [Name]=Delete a monitored trigger}} ` + |
89 | | - `{{--help|-h=Show this help}}`); |
| 89 | + `{{--help|-h=Show this help}} ` + |
| 90 | + `{{=**Dynamic Message Content**}} ` + |
| 91 | + `{{**Dice Roll Syntax**=Supported dice notation:}} ` + |
| 92 | + `{{Basic Rolls=1d6, 2d20, 3d8 (XdY format)}} ` + |
| 93 | + `{{With Modifiers=1d20+5, 2d6+3, 1d8-2}} ` + |
| 94 | + `{{Complex=1d20+1d4+3, (2d6+2)*2, 1d100/10}} ` + |
| 95 | + `{{Limits=1-100 dice, 1-1000 sides per die}} ` + |
| 96 | + `{{**Character Attributes**=Supported attribute names:}} ` + |
| 97 | + `{{Core Stats=hp, maxhp, ac, level, gold/gp, inspiration}} ` + |
| 98 | + `{{Abilities=str/dex/con/int/wis/cha (and modifiers)}} ` + |
| 99 | + `{{Examples={playerName.hp}, {monitoredName.ac}, {playerName.gold}}}`); |
90 | 100 | } |
91 | 101 |
|
92 | 102 | /** |
|
278 | 288 | if (state.defaultImagePath && state.defaultImagePath.trim() !== '') { |
279 | 289 | return state.defaultImagePath; |
280 | 290 | } |
281 | | - // Final fallback |
282 | | - return ''; |
| 291 | + // Final fallback - return null to indicate no image |
| 292 | + return null; |
283 | 293 | } |
284 | 294 | /** |
285 | 295 | * Gets the effective name for a token - either the token's name or the character it represents. |
|
994 | 1004 | * @param triggerDistance - Trigger distance in token body widths |
995 | 1005 | * @param tokenIds - Array of Roll20 token IDs representing this trigger |
996 | 1006 | * @param timeout - Cooldown in ms before re-triggering (0 = permanent) |
997 | | - * @param img - Portrait/image URL |
| 1007 | + * @param img - Portrait/image URL (null to hide image) |
998 | 1008 | * @param messages - Array of possible messages |
999 | 1009 | * @param cardStyle - Card style name for this trigger |
1000 | 1010 | * @param mode - Operating mode: 'on', 'off', or 'once' |
|
1190 | 1200 | case 'cardstyle': |
1191 | 1201 | // List all styles for user to pick |
1192 | 1202 | const styleList = state.cardStyles.map(s => `{{[${s.name}](!pt -e ${safeName} cardStyle ${s.name})}}`).join(' '); |
| 1203 | + const currStyle = npc.cardStyle || 'Default'; |
1193 | 1204 | sendChat('Proximity Trigger', `/w ${who} &{template:default} ` + |
1194 | | - `{{name=Select Card Style for ${npc.name}}} ${styleList}`); |
| 1205 | + `{{name=Select Card Style for ${npc.name}}} ` + |
| 1206 | + `{{Current: ${currStyle}}}` + |
| 1207 | + `${styleList}`); |
1195 | 1208 | break; |
1196 | 1209 | case 'triggerdistance': |
1197 | 1210 | const currDist = npc.triggerDistance; |
|
1208 | 1221 | case 'img': |
1209 | 1222 | const imgUrl = npc.img || 'https://raw.githubusercontent.com/bbarrington0099/Roll20API/main/ProximityTrigger/src/ProximityTrigger.png'; |
1210 | 1223 | sendChat('Proximity Trigger', `/w ${who} &{template:default} {{name=Set Image URL for ${npc.name}}} ` + |
1211 | | - `{{Current: [Link](${npc.img || 'none'})}} ` + |
1212 | | - `{{New URL=[Click Here](!pt -e ${safeName} img ?{Enter new image URL|${imgUrl}})}}`); |
| 1224 | + `{{Current: ${npc.img ? `[Link](${npc.img})` : `None`}}} ` + |
| 1225 | + `{{New URL=[Click Here](!pt -e ${safeName} img ?{Enter new image URL ^'clear' to remove^|${imgUrl}})}}`); |
1213 | 1226 | break; |
1214 | 1227 | case 'mode': |
| 1228 | + const modeList = ['on', 'off', 'once'].map(m => `{{[${m.toUpperCase()}](!proximitynpc -e ${toSafeName(npc.name)} mode ${m})}}`).join(" "); |
1215 | 1229 | const currMode = npc.mode || 'on'; |
1216 | 1230 | sendChat('Proximity Trigger', `/w ${who} &{template:default} {{name=Set Mode for ${npc.name}}} ` + |
1217 | 1231 | `{{Current: ${currMode}}} ` + |
1218 | | - `{{New Mode=[Click Here](!pt -e ${safeName} mode ?{Enter new Mode ^on, off, once^|${currMode}})}}`); |
| 1232 | + `${modeList}`); |
1219 | 1233 | break; |
1220 | 1234 | default: |
1221 | 1235 | sendChat('Proximity Trigger', `/w ${who} Unknown property "${property}".`); |
|
1260 | 1274 | } |
1261 | 1275 | break; |
1262 | 1276 | case 'img': |
1263 | | - npc.img = value; |
1264 | | - sendChat('Proximity Trigger', `/w ${who} ${npc.name} image URL updated${tokenInfo}.`); |
| 1277 | + const clear = value.toLowerCase().trim() === 'clear'; |
| 1278 | + npc.img = clear ? null : value; |
| 1279 | + sendChat('Proximity Trigger', `/w ${who} ${clear ? 'Removed' : 'Updated'} ${npc.name} image url${clear ? '' : ` to "${value}"`}${tokenInfo}.`); |
1265 | 1280 | break; |
1266 | 1281 | case 'cardstyle': |
1267 | 1282 | const style = state.cardStyles.find(s => s.name.toLowerCase() === value.toLowerCase()); |
|
1371 | 1386 | { name: 'Whisper', attr: 'whisper', value: cardStyle.whisper }, |
1372 | 1387 | { name: 'Badge', attr: 'badge', value: cardStyle.badge } |
1373 | 1388 | ]; |
1374 | | - const propertyLinks = properties.map(prop => `{{[${prop.name}: ${prop.attr == 'badge' ? (prop.value || 'None').slice(0, 16) : (prop.value || 'None')}](!pt -C ${toSafeName(cardStyle.name)} ${prop.attr})}}`).join(' '); |
| 1389 | + const propertyLinks = properties.map(prop => `{{[${prop.name}: ${prop.attr == 'badge' ? (prop.value || 'None').slice(0, 16) : (prop.value || 'None')}](!pt -C ${toSafeName(cardStyle.name)} ${prop.attr})}}${prop.attr == 'badge' && prop.value ? ` {{[Link](${prop.value || 'None'})}}` : ''}`).join(' '); |
1375 | 1390 | sendChat('Proximity Trigger', `/w ${who} &{template:default} {{name=Edit Card Style: ${cardStyle.name}}} ` + |
1376 | 1391 | `${propertyLinks} ` + |
1377 | 1392 | `{{[Delete Style](!pt -C delete ${toSafeName(cardStyle.name)})}}`); |
|
1401 | 1416 | promptMessage = 'Enter text color ^any CSS color^:'; |
1402 | 1417 | break; |
1403 | 1418 | case 'whisper': |
1404 | | - promptMessage = 'Enter whisper mode ^\'character\', \'gm\', or \'off\'^:'; |
1405 | | - break; |
| 1419 | + const whispers = ['off', 'gm', 'character'].map(w => `{{[${w.toUpperCase()}](!pt -C ${toSafeName(cardStyle.name)} ${property} ${w})}}`).join(" "); |
| 1420 | + sendChat('Proximity Trigger', `/w ${who} &{template:default} {{name=Set Whisper for ${cardStyle.name}}} ` + |
| 1421 | + `{{Current: ${currentValue}}} ` + |
| 1422 | + `${whispers}`); |
| 1423 | + return; |
1406 | 1424 | case 'badge': |
1407 | 1425 | promptMessage = "Enter URL for Badge Image ^'clear' to remove^:"; |
1408 | 1426 | break; |
|
1412 | 1430 | return; |
1413 | 1431 | } |
1414 | 1432 | sendChat('Proximity Trigger', `/w ${who} &{template:default} {{name=Set ${property} for ${cardStyle.name}}} ` + |
1415 | | - `{{Current: ${property == 'badge' ? (currentValue ? currentValue.slice(0, 30) : 'None') : (currentValue || '')}}} ` + |
| 1433 | + `{{Current: ${property == 'badge' ? currentValue ? `[Link](${currentValue || 'None'})` : `None` : (currentValue || '')}}} ` + |
1416 | 1434 | `{{${promptMessage}=[Click Here](!pt -C ${toSafeName(cardStyle.name)} ${property} ?{${promptMessage}|${currentValue}})}}`); |
1417 | 1435 | } |
1418 | 1436 | /** |
|
0 commit comments