Master builder: favour buys double labour and XP for players, not finished work

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
rope 2026-10-19 11:01:29 +01:00
parent e6b8c327e8
commit fb4b8bf7c8
4 changed files with 53 additions and 21 deletions

View file

@ -519,15 +519,33 @@ class FavourTest(unittest.TestCase):
self.p = self.world["players"]["fred"]
self.p["favour"] = 5000
def test_builders_do_half_the_work_left(self):
def test_master_builder_doubles_labour_and_xp_for_a_while(self):
world, p = self.world, self.p
self.assertEqual(game.spend_favour(world, p, "builders", T0), "Nothing is being built")
world["city"]["construction"] = {"building": "walls", "repair": False, "start": T0, "labour": 60.0, "needed": 360}
cost = game.favours(world, T0)["builders"]["cost"]
self.assertEqual(cost, 101) # 150 labour at 0.67 favour each
world["city"]["construction"] = {"building": "walls", "repair": False, "start": T0, "labour": 0.0, "needed": 360}
self.assertEqual(game.favours(world, T0)["builders"]["cost"], 150)
self.assertIsNone(game.spend_favour(world, p, "builders", T0))
self.assertEqual(world["city"]["construction"]["labour"], 210)
self.assertEqual(p["favour"], 5000 - 101)
self.assertEqual(game.favours(world, T0)["builders"]["cost"], 225)
self.assertEqual(world["city"]["construction"]["labour"], 0) # nothing is built for you
game.start_action(world, p, "labour", T0)
summary = game.process_player(world, p, T0 + 24 * 60, random.Random(1)) # pioneer: 24s an action
self.assertEqual(summary["done"], 60)
self.assertEqual(summary["labour"], 60 + 50) # the first 50 labour counted double
self.assertEqual(world["city"]["site_boost"], 0)
self.assertEqual(summary["xp"]["construction"], 10 * 60 + 10 * 50)
def test_master_builder_price_resets_on_a_new_site(self):
world, p = self.world, self.p
city = world["city"]
city["construction"] = {"building": "walls", "repair": False, "start": T0, "labour": 359.0, "needed": 360}
game.spend_favour(world, p, "builders", T0)
city["buildings"]["houses"]["fund"] = {k: v for k, v in game.build_cost("houses", 1).items()}
city["queue"] = ["houses"]
city["construction"]["labour"] = 360
game.tick(world, T0 + 1, random.Random(1))
self.assertEqual(city["construction"]["building"], "houses")
self.assertEqual(game.favours(world, T0)["builders"]["cost"], 150)
self.assertEqual(city["site_boost"], 50) # unused boost carries over
def test_informant_raises_intel(self):
world, p = self.world, self.p
@ -558,7 +576,7 @@ class FavourTest(unittest.TestCase):
def test_not_enough_favour(self):
self.p["favour"] = 10
self.world["city"]["construction"] = {"building": "walls", "repair": False, "start": T0, "labour": 0.0, "needed": 360}
self.assertEqual(game.spend_favour(self.world, self.p, "builders", T0), "Needs 121 favour")
self.assertEqual(game.spend_favour(self.world, self.p, "builders", T0), "Needs 150 favour")