A lamp lights the people standing in it
The goods yard fight made the case: three agents inside the same pool of light shot at -50% while the fourth, four metres away, shot at -10%. A lamp now has a reach, per item rather than global, because a weapon lamp and a vehicle searchlight are not the same offer — 4 m for cold light strips, 6 m for a weapon lamp, 10 m for the issue field lamp, 30 m for a roof searchlight. Anyone inside it is in the light and the card names whose lamp it is, so both halves of the rule travel together: the pool is one position and the whole group is standing in it. Measured from the tokens. The shot that started this — no lamp of her own, four metres from somebody else's, in pitch dark — goes from 20% to 60%, while an agent twenty-five metres out still eats the full -50%. An UNKNOWN distance is explicitly not lit: Number(null) is 0, so an unmeasured distance would otherwise have read as standing on top of the lamp and lit any scene with no tokens placed. The dialog carries a tick instead, pre-set when the canvas could measure it and the GM's answer when it could not. Note: template.json is read when Foundry loads the system, so a deployed server needs a restart and not just a pull before the migration can stamp the new field. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
5c640d65cf
commit
4bfa7110d0
@@ -730,6 +730,39 @@ export const LIGHTING = {
|
||||
/** A lamp never makes it daylight. This is the best it gets you. */
|
||||
export const LIGHT_FLOOR = "dim";
|
||||
|
||||
/**
|
||||
* HOW FAR A LAMP THROWS.
|
||||
*
|
||||
* A lamp used to light exactly one person: the one holding it. Played out, that put
|
||||
* three agents standing inside the same pool of light shooting at −50% while the
|
||||
* fourth, an arm's length away, shot at −10%. Nobody would run that at a table.
|
||||
*
|
||||
* So a lamp has a REACH, and anyone inside it is in the light — including the people
|
||||
* it is showing to whatever is out there, which is the half of the rule that costs
|
||||
* something. The reach is per item, because a weapon lamp and a roof searchlight are
|
||||
* not the same offer.
|
||||
*/
|
||||
export const LAMP = { reachM: 10 };
|
||||
|
||||
export function lampReachFor(reachM) {
|
||||
const r = Number(reachM);
|
||||
return r > 0 ? r : LAMP.reachM;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this person inside that lamp's pool? Distance in metres, as everything else is.
|
||||
*
|
||||
* An UNKNOWN distance is not "in the light". `Number(null)` is 0, so a missing
|
||||
* measurement would otherwise read as standing on top of the lamp and light the whole
|
||||
* scene for free — which is precisely the failure this rule exists to correct.
|
||||
*/
|
||||
export function lampCovers(distanceM, reachM) {
|
||||
if (distanceM === null || distanceM === undefined || distanceM === "") return false;
|
||||
const d = Number(distanceM);
|
||||
if (!Number.isFinite(d) || d < 0) return false;
|
||||
return d <= lampReachFor(reachM);
|
||||
}
|
||||
|
||||
export function lightingFor(id) {
|
||||
return LIGHTING[id] || LIGHTING.lit;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user