swade-mb-helpers/macros/setTokenVision.js
2025-05-28 22:37:59 -05:00

157 lines
4.6 KiB
JavaScript

const argBright = typeof args === 'undefined' ? null : args.length > 0 ? args[0] : null;
// argument can be one of 'bright', 'dim', 'dark', 'pitchdark'. Other values
// will guess based on scene darkness
const BRIGHT_LEVELS = ['bright', 'dim', 'dark', 'pitchdark'];
const THRESHOLDS = {
dim: 0.4,
dark: 0.6,
pitchdark: 0.8,
};
const RANGES = {
basic: {
bright: 25,
dim: 25,
dark: 10,
pitchdark: 0,
},
lowlight: {
bright: 25,
dim: 25,
dark: 10,
pitchdark: 0,
},
darkvision: {
bright: 25,
dim: 25,
dark: 10,
pitchdark: 10,
},
nightvision: {
bright: 200,
dim: 200,
dark: 200,
pitchdark: 200,
},
blindsense: {
bright: 5,
dim: 5,
dark: 5,
pitchdark: 5,
},
};
const SIGHT_NAMES = {
lowlight: 'low-light-vision',
darkvision: 'darkvision',
nightvision: 'night-vision',
blindsense: 'blindsense',
};
const SIGHT_MODES = {
lowlight: 'lowlight',
darkvision: 'darkvision',
nightvision: 'darkvision',
basic: 'basic',
blindsense: 'blindsense',
};
function findAbility(token, swid) {
return token.actor.items.find((i) => i.type === 'ability' && i.system.swid === swid);
}
async function main() {
const scene = game.scenes.current;
let sceneBright = BRIGHT_LEVELS[0];
if (scene.darkness > THRESHOLDS.pitchdark) {
sceneBright = BRIGHT_LEVELS[3];
} else if (scene.darkness > THRESHOLDS.dark) {
sceneBright = BRIGHT_LEVELS[2];
} else if (scene.darkness > THRESHOLDS.dim) {
sceneBright = BRIGHT_LEVELS[1];
}
let bright = sceneBright;
if (argBright && BRIGHT_LEVELS.includes(argBright)) {
bright = argBright;
}
new foundry.applications.api.DialogV2({
window: { title: 'Select scene brightness' },
content: `
<form>
<h2>Set token vision</h2>
<p>All tokens with vision will be adjusted</p>
<div class="form-group">
<label class="checkbox">
<input type="radio" name="bright" value="${BRIGHT_LEVELS[0]}"
${bright === BRIGHT_LEVELS[0] ? 'checked' : ''}/>
Bright Light
</label>
</div>
<div class="form-group">
<label class="checkbox">
<input type="radio" name="bright" value="${BRIGHT_LEVELS[1]}"
${bright === BRIGHT_LEVELS[1] ? 'checked' : ''}/>
Dim Light
</label>
</div>
<div class="form-group">
<label class="checkbox">
<input type="radio" name="bright" value="${BRIGHT_LEVELS[2]}"
${bright === BRIGHT_LEVELS[2] ? 'checked' : ''}/>
Dark
</label>
</div>
<div class="form-group">
<label class="checkbox">
<input type="radio" name="bright" value="${BRIGHT_LEVELS[3]}"
${bright === BRIGHT_LEVELS[3] ? 'checked' : ''}/>
Pitch Dark
</label>
</div>
</form>
`,
buttons: [
{
action: "submit",
label: 'Select scene Brightness',
value: 'ok',
callback: (event, button, dialog) => {
const form = button.form;
const formDataObject = new foundry.applications.ux.FormDataExtended(form).object;
console.log('form data', formDataObject, form);
bright = formDataObject.bright;
for (const tokenId of scene.tokens.map((t) => t.id)) {
const token = scene.tokens.get(tokenId);
if (!token.sight.enabled) {
console.log(`Skipping ${token.name}, vision not enabled`);
continue;
// don't set sight on a token where it's not enabled
}
let sightType = 'basic';
for (const sight in SIGHT_NAMES) {
if (findAbility(token, SIGHT_NAMES[sight])) {
sightType = sight;
}
}
const range = RANGES[sightType][bright];
const sightMode = SIGHT_MODES[sightType];
const visionModeData = CONFIG.Canvas.visionModes[sightMode].vision.defaults;
const data = {
'sight.range': range,
'sight.visionMode': sightMode,
'sight.attenuation': visionModeData.attenuation,
'sight.brightness': visionModeData.brightness,
'sight.saturation': visionModeData.saturation,
'sight.contrast': visionModeData.contrast,
};
console.log(`Updating ${token.name}:`, sightType, bright, data);
token.update(data);
}
},
},
{ action: "cancel", label: 'Cancel' },
],
}).render(true);
}
main();