diff --git a/docs/REVIEW_LOG.md b/docs/REVIEW_LOG.md index 25a41a2..893c4bb 100644 --- a/docs/REVIEW_LOG.md +++ b/docs/REVIEW_LOG.md @@ -4361,3 +4361,33 @@ result instead of trusting it, which is the only reason this log is accurate. **A content wart:** the barghest bites with something called "Vesh grasp limb" — the generic `grasp` weapon still carrying a Ringworld-era display name. Every creature in the bestiary that uses `grasp` inherits it. + +## R-240. 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%. Nobody would run that at a +table, and the rule was wrong rather than merely coarse. + +A lamp now has a **reach**, and it is per item rather than global, because a weapon +lamp and a vehicle searchlight are not the same offer — 6 m, 10 m for the issue field +lamp, 4 m for cold light strips, 30 m for a roof searchlight. Anyone inside the reach +is in the light, and the card names whose lamp it is: *"MODE: Tomas's, 4 m away — you +are in it."* Both halves of the rule travel together, so the pool is one position and +the whole group is standing in it. + +Measured from the tokens, because the canvas already knows who is standing where. The +same shot that started this — Rakhi, no lamp of her own, four metres from Tomas's, in +pitch dark — went from **20% to 60%**, and Ceyla twenty-five metres out still ate the +full −50%. + +**The interesting part was the unknown.** `Number(null)` is 0, so an unmeasured +distance read as *standing on top of the lamp* and would have lit any scene with no +tokens placed. My own spot-check caught it before it ever ran: an unknown distance is +now explicitly not lit, and the dialog carries a tick that arrives pre-set when the +canvas could measure it and is the GM's answer when there is nothing to measure. That +keeps it automatic where it can be and honest where it cannot, rather than quietly +lighting the world. + +Note for deployment: `template.json` is read when Foundry loads the system, so the new +`lightReachM` field did not exist on items until the server was restarted — the +migration then stamped it. A remote server needs the restart, not just a pull. diff --git a/lang/en.json b/lang/en.json index f5aeb7b..38edb88 100644 --- a/lang/en.json +++ b/lang/en.json @@ -861,7 +861,6 @@ "RINGBRP.Sight.reflex": "Reflex sight", "RINGBRP.Sight.telescopic": "Telescopic sight", "RINGBRP.Sight.thermal": "Thermal sight", - "RINGBRP.Sight.LampEffect": "lit, and visible", "RINGBRP.Sight.Revealed": "{name} shows them exactly where you are", "RINGBRP.Lighting.lit": "Lit", "RINGBRP.Lighting.dim": "Dim", @@ -876,5 +875,10 @@ "RINGBRP.Chat.Damage": "damage", "RINGBRP.Chat.Sustained": "sustained", "RINGBRP.Chat.DamageMod": "damage mod", - "RINGBRP.Notify.GearFitted": "Fitted {n} item(s) that were carried before sights and lamps did anything." + "RINGBRP.Notify.GearFitted": "Fitted {n} item(s) that were carried before sights and lamps did anything.", + "RINGBRP.Sight.LampOwn": "yours, {reach} m of it", + "RINGBRP.Sight.LampNear": "{holder}'s, {m} m away — you are in it", + "RINGBRP.Sight.SomeLamp": "The light you are standing in", + "RINGBRP.Dialog.InLight": "I am in the light", + "RINGBRP.Dialog.InLightHint": "Ticked already if a lit lamp is within reach of your token. Tick it yourself when there are no tokens to measure." } diff --git a/packs/armour/000003.log b/packs/armour/000003.log deleted file mode 100644 index 5b23416..0000000 Binary files a/packs/armour/000003.log and /dev/null differ diff --git a/packs/armour/000005.ldb b/packs/armour/000005.ldb new file mode 100644 index 0000000..b406921 Binary files /dev/null and b/packs/armour/000005.ldb differ diff --git a/packs/armour/000006.log b/packs/armour/000006.log new file mode 100644 index 0000000..9d3f468 Binary files /dev/null and b/packs/armour/000006.log differ diff --git a/packs/armour/CURRENT b/packs/armour/CURRENT index 1a84852..cacca75 100644 --- a/packs/armour/CURRENT +++ b/packs/armour/CURRENT @@ -1 +1 @@ -MANIFEST-000002 +MANIFEST-000004 diff --git a/packs/armour/LOG b/packs/armour/LOG index 481972f..2c0939d 100644 --- a/packs/armour/LOG +++ b/packs/armour/LOG @@ -1 +1,5 @@ -2026/08/11-08:56:03.947107 16e763000 Delete type=3 #1 +2026/08/11-09:44:12.196312 1737fb000 Recovering log #3 +2026/08/11-09:44:12.196429 1737fb000 Level-0 table #5: started +2026/08/11-09:44:12.196537 1737fb000 Level-0 table #5: 3269 bytes OK +2026/08/11-09:44:12.196738 1737fb000 Delete type=0 #3 +2026/08/11-09:44:12.196764 1737fb000 Delete type=3 #2 diff --git a/packs/armour/LOG.old b/packs/armour/LOG.old new file mode 100644 index 0000000..088c89c --- /dev/null +++ b/packs/armour/LOG.old @@ -0,0 +1 @@ +2026/08/11-09:43:09.979643 172267000 Delete type=3 #1 diff --git a/packs/armour/MANIFEST-000002 b/packs/armour/MANIFEST-000002 deleted file mode 100644 index bbbc585..0000000 Binary files a/packs/armour/MANIFEST-000002 and /dev/null differ diff --git a/packs/armour/MANIFEST-000004 b/packs/armour/MANIFEST-000004 new file mode 100644 index 0000000..1faa5e9 Binary files /dev/null and b/packs/armour/MANIFEST-000004 differ diff --git a/packs/expedition/000003.log b/packs/expedition/000003.log deleted file mode 100644 index 263295b..0000000 Binary files a/packs/expedition/000003.log and /dev/null differ diff --git a/packs/expedition/000005.ldb b/packs/expedition/000005.ldb new file mode 100644 index 0000000..4ff460d Binary files /dev/null and b/packs/expedition/000005.ldb differ diff --git a/packs/expedition/000006.log b/packs/expedition/000006.log new file mode 100644 index 0000000..268b187 Binary files /dev/null and b/packs/expedition/000006.log differ diff --git a/packs/expedition/CURRENT b/packs/expedition/CURRENT index 1a84852..cacca75 100644 --- a/packs/expedition/CURRENT +++ b/packs/expedition/CURRENT @@ -1 +1 @@ -MANIFEST-000002 +MANIFEST-000004 diff --git a/packs/expedition/LOG b/packs/expedition/LOG index a59eb01..58e611b 100644 --- a/packs/expedition/LOG +++ b/packs/expedition/LOG @@ -1 +1,5 @@ -2026/08/11-08:56:03.980151 16f77b000 Delete type=3 #1 +2026/08/11-09:44:12.205237 172fef000 Recovering log #3 +2026/08/11-09:44:12.205611 172fef000 Level-0 table #5: started +2026/08/11-09:44:12.205721 172fef000 Level-0 table #5: 4129 bytes OK +2026/08/11-09:44:12.205945 172fef000 Delete type=0 #3 +2026/08/11-09:44:12.205992 172fef000 Delete type=3 #2 diff --git a/packs/expedition/LOG.old b/packs/expedition/LOG.old new file mode 100644 index 0000000..231e892 --- /dev/null +++ b/packs/expedition/LOG.old @@ -0,0 +1 @@ +2026/08/11-09:43:10.009129 17327f000 Delete type=3 #1 diff --git a/packs/expedition/MANIFEST-000002 b/packs/expedition/MANIFEST-000002 deleted file mode 100644 index bbbc585..0000000 Binary files a/packs/expedition/MANIFEST-000002 and /dev/null differ diff --git a/packs/expedition/MANIFEST-000004 b/packs/expedition/MANIFEST-000004 new file mode 100644 index 0000000..47fbcd4 Binary files /dev/null and b/packs/expedition/MANIFEST-000004 differ diff --git a/packs/gear/000003.log b/packs/gear/000003.log deleted file mode 100644 index 349523a..0000000 Binary files a/packs/gear/000003.log and /dev/null differ diff --git a/packs/gear/000005.ldb b/packs/gear/000005.ldb new file mode 100644 index 0000000..d9bac03 Binary files /dev/null and b/packs/gear/000005.ldb differ diff --git a/packs/gear/000006.log b/packs/gear/000006.log new file mode 100644 index 0000000..d1deb9b Binary files /dev/null and b/packs/gear/000006.log differ diff --git a/packs/gear/CURRENT b/packs/gear/CURRENT index 1a84852..cacca75 100644 --- a/packs/gear/CURRENT +++ b/packs/gear/CURRENT @@ -1 +1 @@ -MANIFEST-000002 +MANIFEST-000004 diff --git a/packs/gear/LOG b/packs/gear/LOG index 7a5bd92..04e48ba 100644 --- a/packs/gear/LOG +++ b/packs/gear/LOG @@ -1 +1,5 @@ -2026/08/11-08:56:03.949621 16f77b000 Delete type=3 #1 +2026/08/11-09:44:12.197435 172fef000 Recovering log #3 +2026/08/11-09:44:12.198040 172fef000 Level-0 table #5: started +2026/08/11-09:44:12.198321 172fef000 Level-0 table #5: 31614 bytes OK +2026/08/11-09:44:12.198514 172fef000 Delete type=0 #3 +2026/08/11-09:44:12.198552 172fef000 Delete type=3 #2 diff --git a/packs/gear/LOG.old b/packs/gear/LOG.old new file mode 100644 index 0000000..194c71f --- /dev/null +++ b/packs/gear/LOG.old @@ -0,0 +1 @@ +2026/08/11-09:43:09.981180 17327f000 Delete type=3 #1 diff --git a/packs/gear/MANIFEST-000002 b/packs/gear/MANIFEST-000002 deleted file mode 100644 index bbbc585..0000000 Binary files a/packs/gear/MANIFEST-000002 and /dev/null differ diff --git a/packs/gear/MANIFEST-000004 b/packs/gear/MANIFEST-000004 new file mode 100644 index 0000000..f7cd73c Binary files /dev/null and b/packs/gear/MANIFEST-000004 differ diff --git a/packs/npcs/000003.log b/packs/npcs/000003.log deleted file mode 100644 index c13442d..0000000 Binary files a/packs/npcs/000003.log and /dev/null differ diff --git a/packs/npcs/000005.ldb b/packs/npcs/000005.ldb new file mode 100644 index 0000000..434f292 Binary files /dev/null and b/packs/npcs/000005.ldb differ diff --git a/packs/npcs/000006.log b/packs/npcs/000006.log new file mode 100644 index 0000000..a8f297d Binary files /dev/null and b/packs/npcs/000006.log differ diff --git a/packs/npcs/CURRENT b/packs/npcs/CURRENT index 1a84852..cacca75 100644 --- a/packs/npcs/CURRENT +++ b/packs/npcs/CURRENT @@ -1 +1 @@ -MANIFEST-000002 +MANIFEST-000004 diff --git a/packs/npcs/LOG b/packs/npcs/LOG index 28f4fea..abb479c 100644 --- a/packs/npcs/LOG +++ b/packs/npcs/LOG @@ -1 +1,5 @@ -2026/08/11-08:56:03.966944 16ef6f000 Delete type=3 #1 +2026/08/11-09:44:12.184168 172fef000 Recovering log #3 +2026/08/11-09:44:12.185997 172fef000 Level-0 table #5: started +2026/08/11-09:44:12.187435 172fef000 Level-0 table #5: 223489 bytes OK +2026/08/11-09:44:12.187693 172fef000 Delete type=0 #3 +2026/08/11-09:44:12.187728 172fef000 Delete type=3 #2 diff --git a/packs/npcs/LOG.old b/packs/npcs/LOG.old new file mode 100644 index 0000000..0809fd4 --- /dev/null +++ b/packs/npcs/LOG.old @@ -0,0 +1 @@ +2026/08/11-09:43:09.996017 172a73000 Delete type=3 #1 diff --git a/packs/npcs/MANIFEST-000002 b/packs/npcs/MANIFEST-000002 deleted file mode 100644 index bbbc585..0000000 Binary files a/packs/npcs/MANIFEST-000002 and /dev/null differ diff --git a/packs/npcs/MANIFEST-000004 b/packs/npcs/MANIFEST-000004 new file mode 100644 index 0000000..c64c94d Binary files /dev/null and b/packs/npcs/MANIFEST-000004 differ diff --git a/packs/powers/000003.log b/packs/powers/000003.log deleted file mode 100644 index d723043..0000000 Binary files a/packs/powers/000003.log and /dev/null differ diff --git a/packs/powers/000005.ldb b/packs/powers/000005.ldb new file mode 100644 index 0000000..7f540c6 Binary files /dev/null and b/packs/powers/000005.ldb differ diff --git a/packs/powers/000006.log b/packs/powers/000006.log new file mode 100644 index 0000000..43e306f Binary files /dev/null and b/packs/powers/000006.log differ diff --git a/packs/powers/CURRENT b/packs/powers/CURRENT index 1a84852..cacca75 100644 --- a/packs/powers/CURRENT +++ b/packs/powers/CURRENT @@ -1 +1 @@ -MANIFEST-000002 +MANIFEST-000004 diff --git a/packs/powers/LOG b/packs/powers/LOG index 208cfc8..58a312f 100644 --- a/packs/powers/LOG +++ b/packs/powers/LOG @@ -1 +1,5 @@ -2026/08/11-08:56:03.974409 16e763000 Delete type=3 #1 +2026/08/11-09:44:12.193256 1737fb000 Recovering log #3 +2026/08/11-09:44:12.193611 1737fb000 Level-0 table #5: started +2026/08/11-09:44:12.193707 1737fb000 Level-0 table #5: 3295 bytes OK +2026/08/11-09:44:12.193908 1737fb000 Delete type=0 #3 +2026/08/11-09:44:12.193951 1737fb000 Delete type=3 #2 diff --git a/packs/powers/LOG.old b/packs/powers/LOG.old new file mode 100644 index 0000000..037904d --- /dev/null +++ b/packs/powers/LOG.old @@ -0,0 +1 @@ +2026/08/11-09:43:10.003815 172267000 Delete type=3 #1 diff --git a/packs/powers/MANIFEST-000002 b/packs/powers/MANIFEST-000002 deleted file mode 100644 index bbbc585..0000000 Binary files a/packs/powers/MANIFEST-000002 and /dev/null differ diff --git a/packs/powers/MANIFEST-000004 b/packs/powers/MANIFEST-000004 new file mode 100644 index 0000000..20de082 Binary files /dev/null and b/packs/powers/MANIFEST-000004 differ diff --git a/packs/pregens/000003.log b/packs/pregens/000003.log deleted file mode 100644 index 5ed9a47..0000000 Binary files a/packs/pregens/000003.log and /dev/null differ diff --git a/packs/pregens/000005.ldb b/packs/pregens/000005.ldb new file mode 100644 index 0000000..fe8672f Binary files /dev/null and b/packs/pregens/000005.ldb differ diff --git a/packs/pregens/000006.log b/packs/pregens/000006.log new file mode 100644 index 0000000..8d9abc2 Binary files /dev/null and b/packs/pregens/000006.log differ diff --git a/packs/pregens/CURRENT b/packs/pregens/CURRENT index 1a84852..cacca75 100644 --- a/packs/pregens/CURRENT +++ b/packs/pregens/CURRENT @@ -1 +1 @@ -MANIFEST-000002 +MANIFEST-000004 diff --git a/packs/pregens/LOG b/packs/pregens/LOG index 0888ece..8788efa 100644 --- a/packs/pregens/LOG +++ b/packs/pregens/LOG @@ -1 +1,5 @@ -2026/08/11-08:56:03.956900 16ff87000 Delete type=3 #1 +2026/08/11-09:44:12.181257 172fef000 Recovering log #3 +2026/08/11-09:44:12.182096 172fef000 Level-0 table #5: started +2026/08/11-09:44:12.182622 172fef000 Level-0 table #5: 58065 bytes OK +2026/08/11-09:44:12.182900 172fef000 Delete type=0 #3 +2026/08/11-09:44:12.182935 172fef000 Delete type=3 #2 diff --git a/packs/pregens/LOG.old b/packs/pregens/LOG.old new file mode 100644 index 0000000..c0f91ce --- /dev/null +++ b/packs/pregens/LOG.old @@ -0,0 +1 @@ +2026/08/11-09:43:09.987323 173a8b000 Delete type=3 #1 diff --git a/packs/pregens/MANIFEST-000002 b/packs/pregens/MANIFEST-000002 deleted file mode 100644 index bbbc585..0000000 Binary files a/packs/pregens/MANIFEST-000002 and /dev/null differ diff --git a/packs/pregens/MANIFEST-000004 b/packs/pregens/MANIFEST-000004 new file mode 100644 index 0000000..d892f88 Binary files /dev/null and b/packs/pregens/MANIFEST-000004 differ diff --git a/packs/rules/000003.log b/packs/rules/000003.log deleted file mode 100644 index 347e0ec..0000000 Binary files a/packs/rules/000003.log and /dev/null differ diff --git a/packs/rules/000005.ldb b/packs/rules/000005.ldb new file mode 100644 index 0000000..1147e24 Binary files /dev/null and b/packs/rules/000005.ldb differ diff --git a/packs/rules/000006.log b/packs/rules/000006.log new file mode 100644 index 0000000..5e876ff Binary files /dev/null and b/packs/rules/000006.log differ diff --git a/packs/rules/CURRENT b/packs/rules/CURRENT index 1a84852..cacca75 100644 --- a/packs/rules/CURRENT +++ b/packs/rules/CURRENT @@ -1 +1 @@ -MANIFEST-000002 +MANIFEST-000004 diff --git a/packs/rules/LOG b/packs/rules/LOG index d9c2440..ac28fdd 100644 --- a/packs/rules/LOG +++ b/packs/rules/LOG @@ -1 +1,5 @@ -2026/08/11-08:56:03.978547 16ff87000 Delete type=3 #1 +2026/08/11-09:44:12.200848 172fef000 Recovering log #3 +2026/08/11-09:44:12.201122 172fef000 Level-0 table #5: started +2026/08/11-09:44:12.201397 172fef000 Level-0 table #5: 30975 bytes OK +2026/08/11-09:44:12.201635 172fef000 Delete type=0 #3 +2026/08/11-09:44:12.201675 172fef000 Delete type=3 #2 diff --git a/packs/rules/LOG.old b/packs/rules/LOG.old new file mode 100644 index 0000000..150c839 --- /dev/null +++ b/packs/rules/LOG.old @@ -0,0 +1 @@ +2026/08/11-09:43:10.007699 172267000 Delete type=3 #1 diff --git a/packs/rules/MANIFEST-000002 b/packs/rules/MANIFEST-000002 deleted file mode 100644 index bbbc585..0000000 Binary files a/packs/rules/MANIFEST-000002 and /dev/null differ diff --git a/packs/rules/MANIFEST-000004 b/packs/rules/MANIFEST-000004 new file mode 100644 index 0000000..e2e1bf1 Binary files /dev/null and b/packs/rules/MANIFEST-000004 differ diff --git a/packs/skills/000003.log b/packs/skills/000003.log deleted file mode 100644 index e23ff19..0000000 Binary files a/packs/skills/000003.log and /dev/null differ diff --git a/packs/skills/000005.ldb b/packs/skills/000005.ldb new file mode 100644 index 0000000..d613d26 Binary files /dev/null and b/packs/skills/000005.ldb differ diff --git a/packs/skills/000006.log b/packs/skills/000006.log new file mode 100644 index 0000000..aa7dd7d Binary files /dev/null and b/packs/skills/000006.log differ diff --git a/packs/skills/CURRENT b/packs/skills/CURRENT index 1a84852..cacca75 100644 --- a/packs/skills/CURRENT +++ b/packs/skills/CURRENT @@ -1 +1 @@ -MANIFEST-000002 +MANIFEST-000004 diff --git a/packs/skills/LOG b/packs/skills/LOG index 6e545bf..9dd2e32 100644 --- a/packs/skills/LOG +++ b/packs/skills/LOG @@ -1 +1,5 @@ -2026/08/11-08:56:03.938794 16e763000 Delete type=3 #1 +2026/08/11-09:44:12.190287 1737fb000 Recovering log #3 +2026/08/11-09:44:12.190653 1737fb000 Level-0 table #5: started +2026/08/11-09:44:12.190822 1737fb000 Level-0 table #5: 7486 bytes OK +2026/08/11-09:44:12.191038 1737fb000 Delete type=0 #3 +2026/08/11-09:44:12.191067 1737fb000 Delete type=3 #2 diff --git a/packs/skills/LOG.old b/packs/skills/LOG.old new file mode 100644 index 0000000..c5b52aa --- /dev/null +++ b/packs/skills/LOG.old @@ -0,0 +1 @@ +2026/08/11-09:43:09.973842 172a73000 Delete type=3 #1 diff --git a/packs/skills/MANIFEST-000002 b/packs/skills/MANIFEST-000002 deleted file mode 100644 index bbbc585..0000000 Binary files a/packs/skills/MANIFEST-000002 and /dev/null differ diff --git a/packs/skills/MANIFEST-000004 b/packs/skills/MANIFEST-000004 new file mode 100644 index 0000000..792e8a1 Binary files /dev/null and b/packs/skills/MANIFEST-000004 differ diff --git a/packs/slice/000003.log b/packs/slice/000003.log deleted file mode 100644 index 4a86fe9..0000000 Binary files a/packs/slice/000003.log and /dev/null differ diff --git a/packs/slice/000005.ldb b/packs/slice/000005.ldb new file mode 100644 index 0000000..4851c77 Binary files /dev/null and b/packs/slice/000005.ldb differ diff --git a/packs/slice/000006.log b/packs/slice/000006.log new file mode 100644 index 0000000..c7d9b16 Binary files /dev/null and b/packs/slice/000006.log differ diff --git a/packs/slice/CURRENT b/packs/slice/CURRENT index 1a84852..cacca75 100644 --- a/packs/slice/CURRENT +++ b/packs/slice/CURRENT @@ -1 +1 @@ -MANIFEST-000002 +MANIFEST-000004 diff --git a/packs/slice/LOG b/packs/slice/LOG index f3f0f86..c683f39 100644 --- a/packs/slice/LOG +++ b/packs/slice/LOG @@ -1 +1,5 @@ -2026/08/11-08:56:03.972924 16ef6f000 Delete type=3 #1 +2026/08/11-09:44:12.202502 171fd7000 Recovering log #3 +2026/08/11-09:44:12.202661 171fd7000 Level-0 table #5: started +2026/08/11-09:44:12.202854 171fd7000 Level-0 table #5: 16892 bytes OK +2026/08/11-09:44:12.203092 171fd7000 Delete type=0 #3 +2026/08/11-09:44:12.203146 171fd7000 Delete type=3 #2 diff --git a/packs/slice/LOG.old b/packs/slice/LOG.old new file mode 100644 index 0000000..39b83ea --- /dev/null +++ b/packs/slice/LOG.old @@ -0,0 +1 @@ +2026/08/11-09:43:10.002176 173a8b000 Delete type=3 #1 diff --git a/packs/slice/MANIFEST-000002 b/packs/slice/MANIFEST-000002 deleted file mode 100644 index bbbc585..0000000 Binary files a/packs/slice/MANIFEST-000002 and /dev/null differ diff --git a/packs/slice/MANIFEST-000004 b/packs/slice/MANIFEST-000004 new file mode 100644 index 0000000..0552c3a Binary files /dev/null and b/packs/slice/MANIFEST-000004 differ diff --git a/packs/tables/000003.log b/packs/tables/000003.log deleted file mode 100644 index f125b7d..0000000 Binary files a/packs/tables/000003.log and /dev/null differ diff --git a/packs/tables/000005.ldb b/packs/tables/000005.ldb new file mode 100644 index 0000000..64baa1c Binary files /dev/null and b/packs/tables/000005.ldb differ diff --git a/packs/tables/000006.log b/packs/tables/000006.log new file mode 100644 index 0000000..d5e06f3 Binary files /dev/null and b/packs/tables/000006.log differ diff --git a/packs/tables/CURRENT b/packs/tables/CURRENT index 1a84852..cacca75 100644 --- a/packs/tables/CURRENT +++ b/packs/tables/CURRENT @@ -1 +1 @@ -MANIFEST-000002 +MANIFEST-000004 diff --git a/packs/tables/LOG b/packs/tables/LOG index 31ac16d..925bb72 100644 --- a/packs/tables/LOG +++ b/packs/tables/LOG @@ -1 +1,5 @@ -2026/08/11-08:56:03.971218 16e763000 Delete type=3 #1 +2026/08/11-09:44:12.203885 1737fb000 Recovering log #3 +2026/08/11-09:44:12.204195 1737fb000 Level-0 table #5: started +2026/08/11-09:44:12.204288 1737fb000 Level-0 table #5: 3739 bytes OK +2026/08/11-09:44:12.204494 1737fb000 Delete type=0 #3 +2026/08/11-09:44:12.204520 1737fb000 Delete type=3 #2 diff --git a/packs/tables/LOG.old b/packs/tables/LOG.old new file mode 100644 index 0000000..c707369 --- /dev/null +++ b/packs/tables/LOG.old @@ -0,0 +1 @@ +2026/08/11-09:43:10.000153 172267000 Delete type=3 #1 diff --git a/packs/tables/MANIFEST-000002 b/packs/tables/MANIFEST-000002 deleted file mode 100644 index bbbc585..0000000 Binary files a/packs/tables/MANIFEST-000002 and /dev/null differ diff --git a/packs/tables/MANIFEST-000004 b/packs/tables/MANIFEST-000004 new file mode 100644 index 0000000..004ff30 Binary files /dev/null and b/packs/tables/MANIFEST-000004 differ diff --git a/packs/talents/000003.log b/packs/talents/000003.log deleted file mode 100644 index 443b7ea..0000000 Binary files a/packs/talents/000003.log and /dev/null differ diff --git a/packs/talents/000005.ldb b/packs/talents/000005.ldb new file mode 100644 index 0000000..fb653de Binary files /dev/null and b/packs/talents/000005.ldb differ diff --git a/packs/talents/000006.log b/packs/talents/000006.log new file mode 100644 index 0000000..29003f7 Binary files /dev/null and b/packs/talents/000006.log differ diff --git a/packs/talents/CURRENT b/packs/talents/CURRENT index 1a84852..cacca75 100644 --- a/packs/talents/CURRENT +++ b/packs/talents/CURRENT @@ -1 +1 @@ -MANIFEST-000002 +MANIFEST-000004 diff --git a/packs/talents/LOG b/packs/talents/LOG index 730ff0a..7c30526 100644 --- a/packs/talents/LOG +++ b/packs/talents/LOG @@ -1 +1,5 @@ -2026/08/11-08:56:03.942298 16ff87000 Delete type=3 #1 +2026/08/11-09:44:12.191930 172fef000 Recovering log #3 +2026/08/11-09:44:12.192079 172fef000 Level-0 table #5: started +2026/08/11-09:44:12.192222 172fef000 Level-0 table #5: 5770 bytes OK +2026/08/11-09:44:12.192448 172fef000 Delete type=0 #3 +2026/08/11-09:44:12.192478 172fef000 Delete type=3 #2 diff --git a/packs/talents/LOG.old b/packs/talents/LOG.old new file mode 100644 index 0000000..f94ab50 --- /dev/null +++ b/packs/talents/LOG.old @@ -0,0 +1 @@ +2026/08/11-09:43:09.976561 172267000 Delete type=3 #1 diff --git a/packs/talents/MANIFEST-000002 b/packs/talents/MANIFEST-000002 deleted file mode 100644 index bbbc585..0000000 Binary files a/packs/talents/MANIFEST-000002 and /dev/null differ diff --git a/packs/talents/MANIFEST-000004 b/packs/talents/MANIFEST-000004 new file mode 100644 index 0000000..f8c6b47 Binary files /dev/null and b/packs/talents/MANIFEST-000004 differ diff --git a/packs/vehicles/000003.log b/packs/vehicles/000003.log deleted file mode 100644 index 9950ce5..0000000 Binary files a/packs/vehicles/000003.log and /dev/null differ diff --git a/packs/vehicles/000005.ldb b/packs/vehicles/000005.ldb new file mode 100644 index 0000000..f6b2cd4 Binary files /dev/null and b/packs/vehicles/000005.ldb differ diff --git a/packs/vehicles/000006.log b/packs/vehicles/000006.log new file mode 100644 index 0000000..47800e2 Binary files /dev/null and b/packs/vehicles/000006.log differ diff --git a/packs/vehicles/CURRENT b/packs/vehicles/CURRENT index 1a84852..cacca75 100644 --- a/packs/vehicles/CURRENT +++ b/packs/vehicles/CURRENT @@ -1 +1 @@ -MANIFEST-000002 +MANIFEST-000004 diff --git a/packs/vehicles/LOG b/packs/vehicles/LOG index 3c3d6b6..659986e 100644 --- a/packs/vehicles/LOG +++ b/packs/vehicles/LOG @@ -1 +1,5 @@ -2026/08/11-08:56:03.951942 16e763000 Delete type=3 #1 +2026/08/11-09:44:12.199441 1737fb000 Recovering log #3 +2026/08/11-09:44:12.199690 1737fb000 Level-0 table #5: started +2026/08/11-09:44:12.199821 1737fb000 Level-0 table #5: 6939 bytes OK +2026/08/11-09:44:12.200021 1737fb000 Delete type=0 #3 +2026/08/11-09:44:12.200051 1737fb000 Delete type=3 #2 diff --git a/packs/vehicles/LOG.old b/packs/vehicles/LOG.old new file mode 100644 index 0000000..9adb7a1 --- /dev/null +++ b/packs/vehicles/LOG.old @@ -0,0 +1 @@ +2026/08/11-09:43:09.983507 172267000 Delete type=3 #1 diff --git a/packs/vehicles/MANIFEST-000002 b/packs/vehicles/MANIFEST-000002 deleted file mode 100644 index bbbc585..0000000 Binary files a/packs/vehicles/MANIFEST-000002 and /dev/null differ diff --git a/packs/vehicles/MANIFEST-000004 b/packs/vehicles/MANIFEST-000004 new file mode 100644 index 0000000..d4d73b7 Binary files /dev/null and b/packs/vehicles/MANIFEST-000004 differ diff --git a/packs/weapons/000003.log b/packs/weapons/000003.log deleted file mode 100644 index e1488ed..0000000 Binary files a/packs/weapons/000003.log and /dev/null differ diff --git a/packs/weapons/000005.ldb b/packs/weapons/000005.ldb new file mode 100644 index 0000000..742beba Binary files /dev/null and b/packs/weapons/000005.ldb differ diff --git a/packs/weapons/000006.log b/packs/weapons/000006.log new file mode 100644 index 0000000..4d427a6 Binary files /dev/null and b/packs/weapons/000006.log differ diff --git a/packs/weapons/CURRENT b/packs/weapons/CURRENT index 1a84852..cacca75 100644 --- a/packs/weapons/CURRENT +++ b/packs/weapons/CURRENT @@ -1 +1 @@ -MANIFEST-000002 +MANIFEST-000004 diff --git a/packs/weapons/LOG b/packs/weapons/LOG index 7d206d0..0f6fdea 100644 --- a/packs/weapons/LOG +++ b/packs/weapons/LOG @@ -1 +1,5 @@ -2026/08/11-08:56:03.945178 16ef6f000 Delete type=3 #1 +2026/08/11-09:44:12.194742 172fef000 Recovering log #3 +2026/08/11-09:44:12.195028 172fef000 Level-0 table #5: started +2026/08/11-09:44:12.195244 172fef000 Level-0 table #5: 14767 bytes OK +2026/08/11-09:44:12.195470 172fef000 Delete type=0 #3 +2026/08/11-09:44:12.195499 172fef000 Delete type=3 #2 diff --git a/packs/weapons/LOG.old b/packs/weapons/LOG.old new file mode 100644 index 0000000..33e5276 --- /dev/null +++ b/packs/weapons/LOG.old @@ -0,0 +1 @@ +2026/08/11-09:43:09.978238 17327f000 Delete type=3 #1 diff --git a/packs/weapons/MANIFEST-000002 b/packs/weapons/MANIFEST-000002 deleted file mode 100644 index bbbc585..0000000 Binary files a/packs/weapons/MANIFEST-000002 and /dev/null differ diff --git a/packs/weapons/MANIFEST-000004 b/packs/weapons/MANIFEST-000004 new file mode 100644 index 0000000..6a582af Binary files /dev/null and b/packs/weapons/MANIFEST-000004 differ diff --git a/ringbrp.mjs b/ringbrp.mjs index 4528d02..42082b4 100644 --- a/ringbrp.mjs +++ b/ringbrp.mjs @@ -32,7 +32,7 @@ import { FALL, fallDamageFor, ASPHYXIA, breathRoundsFor, FIRE, fireBandFor, BLAST, blastBandFor, blastShareFor, BLAST_COVER, blastAfterCover, BURST, burstHitsFor, burstRoundsSpent, BURST_FUMBLE, BURST_ONE_MAJOR_WOUND, - BURST_HITS, + BURST_HITS, LAMP, lampReachFor, lampCovers, FIRE_MODE, fireModeFor, burstSizesFor, fireModeAttackFor, secondShotPenaltyFor, SUSTAIN, sustainDamageFor, sustainChargeFor, SIGHT, sightFor, sightBonusFor, sightSeesInDark, @@ -887,11 +887,62 @@ export function sightForWeapon(actor, weapon) { /** Is this agent carrying something lit? Lamps are gear, not a checkbox. */ export function carriedLight(actor) { + let best = { on: false, source: "", reachM: 0 }; for (const it of actor?.items ?? []) { if (it.system?.carried === false) continue; - if (it.system?.lightSource) return { on: true, source: it.name }; + if (!it.system?.lightSource) continue; + const reachM = lampReachFor(it.system.lightReachM); + // Two lamps is not twice the light, but the longer one is the one you are using. + if (reachM > best.reachM) best = { on: true, source: it.name, reachM }; } - return { on: false, source: "" }; + return best; +} + +/** Metres between two tokens, in the scene's own units. Null when it cannot be known. */ +function metresBetween(a, b) { + if (!a || !b || !canvas?.ready || !canvas.grid?.size) return null; + const dx = a.center.x - b.center.x, dy = a.center.y - b.center.y; + const px = Math.hypot(dx, dy); + const d = (px / canvas.grid.size) * (canvas.grid.distance || 1); + return Number.isFinite(d) ? d : null; +} + +function tokenFor(actor) { + if (!actor) return null; + const t = actor.getActiveTokens?.(true, false) ?? []; + return t[0] ?? actor.token?.object ?? null; +} + +/** + * The light this agent is actually standing in — theirs or somebody else's. + * + * A lamp used to light exactly one person, and played out that put three agents + * inside the same pool shooting at −50% while the fourth, an arm's length away, shot + * at −10%. A lamp has a reach now, and anyone inside it is in the light. + * + * Measured from the tokens, because the canvas already knows who is standing where. + * When there are no tokens the distance is genuinely unknown, and an unknown distance + * is NOT lit — the dialog offers the GM the tick instead, rather than this quietly + * lighting a whole scene that nobody has placed. + */ +export function lightOn(actor) { + const own = carriedLight(actor); + if (own.on) return { ...own, own: true, distanceM: 0 }; + const me = tokenFor(actor); + if (!me) return { on: false, source: "", reachM: 0, own: false, distanceM: null }; + let best = null; + for (const t of canvas.tokens?.placeables ?? []) { + if (t === me || !t.actor) continue; + const lamp = carriedLight(t.actor); + if (!lamp.on) continue; + const d = metresBetween(me, t); + if (!lampCovers(d, lamp.reachM)) continue; + if (!best || d < best.distanceM) { + best = { on: true, source: lamp.name ?? lamp.source, reachM: lamp.reachM, + own: false, distanceM: d, holder: t.actor.name }; + } + } + return best ?? { on: false, source: "", reachM: 0, own: false, distanceM: null }; } /** @@ -5611,7 +5662,7 @@ async function promptAttackOptions({ weapon, actor }) { // and the lamp by whether anything carried is lit — neither is a thing the player // selects, because both are facts about the pack rather than about the shot. const sight = sightForWeapon(actor, weapon); - const lamp = carriedLight(actor); + const lamp = lightOn(actor); const kit = []; if (sight.id !== "none") { const bands = sightFor(sight.id).bands; @@ -5621,12 +5672,14 @@ async function promptAttackOptions({ weapon, actor }) { .join(" · ") }); } if (lamp.on) { - kit.push({ name: lamp.source, effect: game.i18n.localize("RINGBRP.Sight.LampEffect") }); + kit.push({ name: lamp.source, effect: game.i18n.format( + lamp.own ? "RINGBRP.Sight.LampOwn" : "RINGBRP.Sight.LampNear", + { holder: lamp.holder ?? "", m: Math.round(lamp.distanceM ?? 0), reach: lamp.reachM }) }); } const content = await rbRenderTemplate("systems/ringbrp/templates/dialog-attack.hbs", { RINGBRP, weapon, isRanged: weapon.system.isRanged, ranges: weapon.system.ranges, - bandOptions, fire, kit }); + bandOptions, fire, kit, inLight: lamp.on, lampReach: lamp.reachM || LAMP.reachM }); return new Promise(resolve => { new (rbDialogClass())({ title: weapon.name, @@ -5691,13 +5744,17 @@ async function promptAttackOptions({ weapon, actor }) { } } // The dark, after the lamp and after a sight that does not need one. - const lit = lightingModFor(light, { lightSource: lamp.on, + // The tick is authoritative: it arrives already set when the canvas could + // measure it, and is the GM's answer when there are no tokens to measure. + const inLight = el.querySelector("[name=inlight]")?.checked ?? lamp.on; + const lit = lightingModFor(light, { lightSource: inLight, seesInDark: sightSeesInDark(sight.id) }); if (lit.mod) { mod += lit.mod; lines.push(`${game.i18n.localize(LIGHTING[lit.effective].label)} ${lit.mod}%`); } - if (lit.revealed) lines.push(game.i18n.format("RINGBRP.Sight.Revealed", { name: lamp.source })); + if (lit.revealed) lines.push(game.i18n.format("RINGBRP.Sight.Revealed", + { name: lamp.source || game.i18n.localize("RINGBRP.Sight.SomeLamp") })); const cv = RINGBRP.cover[cover]?.mod ?? 0; if (cv) { mod += cv; lines.push(`${game.i18n.localize(RINGBRP.cover[cover].label)} ${cv}%`); } @@ -6061,7 +6118,7 @@ Hooks.once("init", () => { addDossierItem, useAuthority, widenScope, rehabilitate, tickDying, died, stabilise, reviveIfHealed, conditionFor, dyingLimitFor, fall, asphyxiate, burn, detonate, burstAttack, twoWeaponAttack, - sightForWeapon, carriedLight, fireModeFor, burstSizesFor, sustainDamageFor, + sightForWeapon, carriedLight, lightOn, fireModeFor, burstSizesFor, sustainDamageFor, manStation, bestStationFor, STATIONS, SPACE_BANDS, heatEffectsFor, craftConditionFor, spaceBandAfter, fallDamageFor, breathRoundsFor, fireBandFor, blastBandFor, burstHitsFor, @@ -6104,7 +6161,8 @@ async function migrateFittedGear() { const key = doc.flags?.ringbrp?.key; if (!key) continue; if (doc.system?.optic?.kind || doc.system?.lightSource) { - canon.set(key, { optic: doc.system.optic, lightSource: !!doc.system.lightSource }); + canon.set(key, { optic: doc.system.optic, lightSource: !!doc.system.lightSource, + lightReachM: Number(doc.system.lightReachM) || 0 }); } } if (!canon.size) return 0; @@ -6118,9 +6176,11 @@ async function migrateFittedGear() { const want = canon.get(it.flags?.ringbrp?.key); if (!want) continue; const stale = (it.system.optic?.kind ?? "") !== (want.optic?.kind ?? "") - || !!it.system.lightSource !== want.lightSource; + || !!it.system.lightSource !== want.lightSource + || (Number(it.system.lightReachM) || 0) !== want.lightReachM; if (stale) updates.push({ _id: it.id, "system.optic": want.optic, - "system.lightSource": want.lightSource }); + "system.lightSource": want.lightSource, + "system.lightReachM": want.lightReachM }); } if (updates.length) { await actor.updateEmbeddedDocuments("Item", updates); diff --git a/rules.mjs b/rules.mjs index fcfc9cd..4254bd5 100644 --- a/rules.mjs +++ b/rules.mjs @@ -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; } diff --git a/template.json b/template.json index 27741fc..5547c9f 100644 --- a/template.json +++ b/template.json @@ -256,7 +256,8 @@ "kind": "", "fits": "any" }, - "lightSource": false + "lightSource": false, + "lightReachM": 0 }, "device": { "templates": [ diff --git a/templates/dialog-attack.hbs b/templates/dialog-attack.hbs index 2a8845f..0bb4684 100644 --- a/templates/dialog-attack.hbs +++ b/templates/dialog-attack.hbs @@ -38,6 +38,10 @@ {{/each}} +
{{localize "RINGBRP.Dialog.InLightHint"}}
+Most crossings do not come with the lights on.
${table(["", "To hit"], Object.values(LIGHTING).map(l => [L(l.label), pc(l.mod)]))} -A carried lamp buys the dark back to ${L(LIGHTING[LIGHT_FLOOR].label)} -and never better — and it is a position. The card will say so. A thermal sight removes -the dark outright and does not announce you, which is most of what you are -paying its weight for.
+A lamp buys the dark back to ${L(LIGHTING[LIGHT_FLOOR].label)} and +never better — and it is a position. The card will say so.
+A lamp lights everyone standing in it, not only the person holding +it. Each one has a reach: ${LAMP.reachM} metres for the issue field lamp, less for a +weapon lamp, a great deal more for a vehicle searchlight. Anyone inside that reach is +in the light, with everything that means in both directions — the pool is one position +and the whole group is standing in it. If your tokens are on the map the game works +this out for you; if they are not, the attack dialog asks.
+A thermal sight removes the dark outright and does not announce you, which +is most of what you are paying its weight for.
One roll, not four. The success level says how much of the burst