Work orders: anyone can pool reagents, paid by value

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
rope 2026-10-21 13:40:54 +01:00
parent f7daa4e44d
commit 9ff7a22a5d
3 changed files with 161 additions and 44 deletions

View file

@ -1679,6 +1679,60 @@ class WorkOrderTest(unittest.TestCase):
self.assertEqual(self.mike["bank"].get("iron_warhammer"), 1)
self.assertEqual(self.fred["bank"], {}) # used his own plank and cores, never needed bars
def test_anyone_can_put_reagents_in_and_gets_a_share(self):
self.mike["gold"] = 200
game.post_order(self.world, self.mike, "craft", "iron_warhammer", 1, [], 140, T0)
order = self.world["orders"][0]
self.dave["bank"] = {"iron_bar": 2}
self.mike["bank"] = {"iron_bar": 5}
self.assertIsNone(game.provide_reagent(self.world, self.dave, order["id"], "iron_bar"))
self.assertIsNone(game.provide_reagent(self.world, self.mike, order["id"], "iron_bar"))
self.assertEqual(order["provided"], {"iron_bar": 3}) # only what's needed
self.assertEqual(self.mike["bank"], {"iron_bar": 4})
self.assertEqual(game.provide_reagent(self.world, self.dave, order["id"], "iron_bar"), "Already provided")
self.fred["bank"] = {"oak_plank": 1, "clay_core": 3}
self.assertIsNone(game.work_order(self.world, self.fred, order["id"], T0))
game.process_player(self.world, self.fred, T0 + 600, random.Random(1))
# Reagents are worth 84 a run; Dave's 2 bars (20) earn 20/84 of half the reward.
self.assertEqual(self.dave["gold"], 17)
self.assertEqual(self.fred["gold"], 123) # the requester's own bar leaves its share with the crafter
self.assertEqual(order["earned"], {"dave": 17})
def test_crafter_tops_up_a_short_pool(self):
self.mike["gold"] = 200
game.post_order(self.world, self.mike, "craft", "iron_warhammer", 1, [], 140, T0)
order = self.world["orders"][0]
self.dave["bank"] = {"iron_bar": 1}
game.provide_reagent(self.world, self.dave, order["id"], "iron_bar")
self.fred["bank"] = {"iron_bar": 1, "oak_plank": 1, "clay_core": 3}
self.assertEqual(game.work_order(self.world, self.fred, order["id"], T0), "Out of iron bar")
self.fred["bank"]["iron_bar"] = 2
self.assertIsNone(game.work_order(self.world, self.fred, order["id"], T0))
game.process_player(self.world, self.fred, T0 + 600, random.Random(1))
self.assertEqual(self.mike["bank"].get("iron_warhammer"), 1)
self.assertNotIn("iron_bar", self.fred["bank"])
def test_pooled_reagents_go_back_to_whoever_gave_them(self):
self.mike["gold"] = 200
game.post_order(self.world, self.mike, "craft", "iron_warhammer", 1, [], 140, T0)
order = self.world["orders"][0]
self.dave["bank"] = {"clay_core": 3}
game.provide_reagent(self.world, self.dave, order["id"], "clay_core")
game.cancel_order(self.world, self.mike, order["id"], T0)
self.assertEqual(self.dave["bank"], {"clay_core": 3})
self.assertEqual(self.mike["gold"], 200)
def test_leftover_reagents_return_when_filled_from_a_bank(self):
self.mike["gold"] = 200
game.post_order(self.world, self.mike, "craft", "iron_warhammer", 1, [], 140, T0)
order = self.world["orders"][0]
self.dave["bank"] = {"clay_core": 3}
game.provide_reagent(self.world, self.dave, order["id"], "clay_core")
self.fred["bank"] = {"iron_warhammer": 1}
self.assertIsNone(game.deliver_order(self.world, self.fred, order["id"], T0))
self.assertEqual(order["status"], "done")
self.assertEqual(self.dave["bank"], {"clay_core": 3})
class Always:
"""An rng where every roll comes up: a gem, a drop, whatever's on offer."""