Gold: guard wages, raid retune, strongbox, caravan wares, looks, monuments
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
9d61de2012
commit
cd44709d80
6 changed files with 816 additions and 31 deletions
|
|
@ -435,6 +435,42 @@ class EventTest(unittest.TestCase):
|
|||
self.assertEqual(world["next_fortune_at"], T0 + 20 * game.HOUR)
|
||||
self.assertEqual(world["next_event_at"], T0)
|
||||
|
||||
def test_only_paid_guards_stand_and_hold_kit(self):
|
||||
world = world_with(("sam", "commoner"))
|
||||
city = world["city"]
|
||||
city["population"] = 100
|
||||
city["buildings"]["barracks"]["level"] = 2
|
||||
city["stockpile"] = {"copper_sword": 100}
|
||||
self.assertEqual(game.guard_posts(world), 50)
|
||||
self.assertEqual(game.defence(world)["parts"]["weapons"], 0)
|
||||
p = world["players"]["sam"]
|
||||
p["gold"] = 1000
|
||||
self.assertIsNone(game.pay_wages(world, p, 600, "bank", T0))
|
||||
self.assertEqual(game.guards_on_duty(world), 10)
|
||||
self.assertEqual(p["favour"], 600)
|
||||
parts = game.defence(world)["parts"]
|
||||
self.assertEqual(parts["weapons"], round(0.35 * 10 * 4, 1))
|
||||
self.assertEqual(parts["militia"], round(0.3 * 2 * 100 * 10 / 50, 1))
|
||||
city["treasury"] = 10_000
|
||||
self.assertIsNone(game.pay_wages(world, p, "all", "city", T0))
|
||||
self.assertEqual(city["wages"], 50 * game.GUARD_WAGE) # never more than every post
|
||||
self.assertEqual(game.pay_wages(world, p, 1, "bank", T0), "Every post is paid for")
|
||||
event = {"strength": 1, "sabotage": 0, "group": "the Red Hand"}
|
||||
game._resolve_raid(world, event, T0, random.Random(1))
|
||||
self.assertEqual(event["report"]["guards"], 50)
|
||||
self.assertEqual(city["wages"], 0)
|
||||
|
||||
def test_threat_size_is_against_standing_defence(self):
|
||||
self.assertEqual(game.threat_size({"standing": 100}, 110), 0)
|
||||
self.assertEqual(game.threat_size({"standing": 100}, 260), 3)
|
||||
self.assertEqual(game.threat_size({"strength": 20}, 20), 0) # rumoured before v29
|
||||
|
||||
def test_v28_worlds_pay_the_coming_threats_guards(self):
|
||||
world = world_with()
|
||||
world["version"] = 28
|
||||
game.migrate(world, T0)
|
||||
self.assertEqual(game.guards_on_duty(world), game.guard_posts(world))
|
||||
|
||||
def test_bigger_bands_take_more_scouting(self):
|
||||
small = {"kind": "raid", "strength": 20}
|
||||
huge = {"kind": "raid", "strength": 150}
|
||||
|
|
@ -1098,6 +1134,7 @@ class TierTest(unittest.TestCase):
|
|||
def test_militia_takes_the_best_weapons_first(self):
|
||||
world = world_with()
|
||||
world["city"]["stockpile"] = {"copper_sword": 50, "rune_sword": 2, "iron_shield": 3}
|
||||
world["city"]["wages"] = 10_000
|
||||
parts = game.defence(world)["parts"]
|
||||
armed = int(world["city"]["population"] // 2) # 10
|
||||
self.assertEqual(parts["weapons"], round(0.35 * (2 * 35 + (armed - 2) * 4), 1))
|
||||
|
|
@ -1592,6 +1629,8 @@ class WearTest(unittest.TestCase):
|
|||
|
||||
def test_only_issued_gear_breaks_worst_first(self):
|
||||
self.city["stockpile"] = {"iron_sword": 10, "copper_sword": 30}
|
||||
self.city["buildings"]["barracks"]["level"] = 1
|
||||
self.city["wages"] = 10_000
|
||||
rng = random.Random()
|
||||
rng.random = lambda: 0.0
|
||||
broken = game.wear_kit(self.world, 0.4, rng)
|
||||
|
|
@ -1601,6 +1640,7 @@ class WearTest(unittest.TestCase):
|
|||
|
||||
def test_a_won_raid_breaks_some_kit_and_reports_it(self):
|
||||
self.city["stockpile"] = {"copper_sword": 20, "arrows": 100}
|
||||
self.city["wages"] = 10_000
|
||||
event = {"strength": 1, "sabotage": 0, "group": "the Red Hand"}
|
||||
game._resolve_raid(self.world, event, T0, random.Random(1))
|
||||
self.assertLess(self.city["stockpile"]["copper_sword"], 20)
|
||||
|
|
@ -1610,6 +1650,107 @@ class WearTest(unittest.TestCase):
|
|||
self.assertIn("broken in the fighting", text)
|
||||
|
||||
|
||||
class GoldTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.world = world_with(("ann", "commoner"), ("bob", "commoner"))
|
||||
self.ann, self.bob = self.world["players"]["ann"], self.world["players"]["bob"]
|
||||
self.ann["gold"] = self.bob["gold"] = 200_000
|
||||
|
||||
def caravan(self, wares):
|
||||
self.world["caravan"] = {"id": 7, "at": T0 - 1, "until": T0 + 3600, "wares": wares, "look": "e_wolf"}
|
||||
|
||||
def test_rented_slots_cost_more_each_time(self):
|
||||
before = game.bank_slots(self.world, self.ann)
|
||||
self.assertEqual([game.rent_cost({"rented": n}) for n in range(4)], [1000, 1350, 1800, 2450])
|
||||
self.assertIsNone(game.rent_slot(self.ann))
|
||||
self.assertIsNone(game.rent_slot(self.ann))
|
||||
self.assertEqual(game.bank_slots(self.world, self.ann), before + 2)
|
||||
self.assertEqual(self.ann["gold"], 200_000 - 2350)
|
||||
self.ann["gold"] = 0
|
||||
self.assertEqual(game.rent_slot(self.ann), "Needs 1,800 gold")
|
||||
|
||||
def test_caravan_comes_on_the_prep_day_and_sells_once_per_visit(self):
|
||||
self.world["next_event_at"] = T0
|
||||
game.tick(self.world, T0, random.Random(4))
|
||||
caravan = self.world["caravan"]
|
||||
self.assertTrue(T0 + 2 * game.HOUR <= caravan["at"] <= T0 + 16 * game.HOUR)
|
||||
self.assertIsNone(game.caravan_view(self.world, self.ann, T0))
|
||||
game.tick(self.world, caravan["at"] + 1, random.Random(4))
|
||||
view = game.caravan_view(self.world, self.ann, caravan["at"] + 1)
|
||||
self.assertEqual(len(view["wares"]), game.CARAVAN_WARES)
|
||||
self.assertIsNone(game.caravan_view(self.world, self.ann, caravan["until"] + 1))
|
||||
|
||||
def test_wares_boost_your_own_work_for_their_charges(self):
|
||||
self.caravan(["prospector", "tutor"])
|
||||
self.assertIsNone(game.buy_ware(self.world, self.ann, "prospector", None, T0))
|
||||
self.assertEqual(game.buy_ware(self.world, self.ann, "prospector", None, T0), "One of each per visit")
|
||||
self.assertEqual(self.ann["gold"], 200_000 - 1550) # mining 1: 1,500 × (1 + 1/30)
|
||||
self.assertEqual(game.ware(self.ann, "yield", "mining"), 1.5)
|
||||
self.assertEqual(game.ware(self.bob, "yield", "mining"), 1)
|
||||
self.ann["boosts"][0]["left"] = 1
|
||||
game.ware(self.ann, "yield", "mining", spend=True)
|
||||
self.assertEqual(self.ann["boosts"], [])
|
||||
self.assertEqual(game.buy_ware(self.world, self.ann, "tutor", None, T0), "Pick a skill")
|
||||
self.assertIsNone(game.buy_ware(self.world, self.ann, "tutor", "smithing", T0))
|
||||
self.assertEqual(game.ware(self.ann, "xp", "smithing"), 1.5)
|
||||
|
||||
def test_ware_prices_rise_with_your_level(self):
|
||||
self.ann["xp"]["mining"] = game.XP_TABLE[60]
|
||||
self.assertEqual(game.ware_price(self.ann, "prospector", "mining"), 4500)
|
||||
|
||||
def test_threat_wares_end_with_the_threat(self):
|
||||
self.caravan(["spyglass"])
|
||||
self.assertEqual(game.buy_ware(self.world, self.ann, "spyglass", None, T0), "There's no threat coming")
|
||||
self.world["next_event_at"] = T0
|
||||
game.tick(self.world, T0, random.Random(4))
|
||||
self.caravan(["spyglass"])
|
||||
self.assertIsNone(game.buy_ware(self.world, self.ann, "spyglass", None, T0))
|
||||
self.assertEqual(game.ware(self.ann, "recon", "reconnaissance"), 1.5)
|
||||
raid = game.upcoming_raid(self.world)
|
||||
raid["strength"] = 0
|
||||
game.tick(self.world, raid["fire_at"], random.Random(4))
|
||||
self.assertEqual(game.ware(self.ann, "recon", "reconnaissance"), 1)
|
||||
|
||||
def test_looks_need_owning_or_earning(self):
|
||||
look = {"field": "navy", "trim": "brass", "emblem": None, "title": None}
|
||||
self.assertIsNone(game.set_look(self.ann, look))
|
||||
self.assertEqual(game.set_look(self.ann, {**look, "emblem": "e_wolf"}), "You don't own that")
|
||||
self.caravan([])
|
||||
self.assertIsNone(game.buy_ware(self.world, self.ann, "e_wolf", None, T0))
|
||||
self.assertIsNone(game.set_look(self.ann, {**look, "emblem": "e_wolf"}))
|
||||
self.assertEqual(game.look_view(self.ann)["emblem"], "wolf-head")
|
||||
self.assertEqual(game.set_look(self.ann, {**look, "title": "Master smith"}), "You haven't earned that title")
|
||||
self.ann["xp"]["smithing"] = game.XP_TABLE[50]
|
||||
self.assertIsNone(game.set_look(self.ann, {**look, "title": "Master smith"}))
|
||||
self.assertIsNone(game.upgrade_home(self.ann))
|
||||
self.assertEqual(game.look_view(self.ann)["home"], "Cottage")
|
||||
|
||||
def test_monuments_take_gold_and_carve_the_donors_in(self):
|
||||
city = self.world["city"]
|
||||
self.assertIsNone(game.give_monument(self.world, self.ann, "fountain", 20_000, T0))
|
||||
self.assertIsNone(game.give_monument(self.world, self.bob, "fountain", "all", T0))
|
||||
self.assertEqual(self.bob["gold"], 200_000 - 5_000)
|
||||
self.assertEqual(city["built"][0]["donors"], {"ann": 20_000, "bob": 5_000})
|
||||
self.assertEqual(game.give_monument(self.world, self.ann, "fountain", 1, T0), "It's already built")
|
||||
self.assertEqual(self.ann["favour"], 0)
|
||||
game.give_monument(self.world, self.ann, "statue", 30_000, T0)
|
||||
game.give_monument(self.world, self.bob, "statue", 20_000, T0)
|
||||
self.assertEqual(city["carving"]["by"], "ann")
|
||||
self.assertEqual(game.carve_statue(self.world, self.bob, "bob", T0), "It isn't yours to pick")
|
||||
self.assertIsNone(game.carve_statue(self.world, self.ann, "bob", T0))
|
||||
self.assertEqual(city["built"][-1]["of"], "bob")
|
||||
|
||||
def test_v28_worlds_get_gold_sinks(self):
|
||||
world = world_with(("ann", "commoner"))
|
||||
world["version"] = 28
|
||||
for key in ("rented", "boosts", "bought", "deeds", "owned", "look"):
|
||||
del world["players"]["ann"][key]
|
||||
del world["caravan"]
|
||||
game.migrate(world, T0)
|
||||
self.assertEqual(world["players"]["ann"]["look"], game.DEFAULT_LOOK)
|
||||
self.assertIsNone(world["caravan"])
|
||||
|
||||
|
||||
class ClassTest(unittest.TestCase):
|
||||
def lucky_run(self, cls, action_id, bank):
|
||||
world = world_with(("pat", cls))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue