Intel: scaled recon costs, time-gated levels, spymaster multiplies recon
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
366a195c6d
commit
27bdb6a154
5 changed files with 113 additions and 33 deletions
|
|
@ -343,21 +343,45 @@ class EventTest(unittest.TestCase):
|
|||
self.assertLessEqual(view["earliest"], raid["fire_at"])
|
||||
self.assertGreaterEqual(view["latest"], raid["fire_at"])
|
||||
|
||||
def test_spymaster_and_recon_sharpen_intel(self):
|
||||
def test_recon_sharpens_intel_as_the_raid_draws_near(self):
|
||||
world = world_with(("sam", "scout"))
|
||||
raid = self.announce(world)
|
||||
world["city"]["buildings"]["spymaster"]["level"] = 1
|
||||
self.assertIn("size", game.event_view(world, raid, T0))
|
||||
p = world["players"]["sam"]
|
||||
p["xp"]["reconnaissance"] = game.XP_TABLE[20]
|
||||
game.start_action(world, p, "recon_camps", T0)
|
||||
game.process_player(world, p, T0 + 8 * 72, random.Random(1))
|
||||
view = game.event_view(world, raid, T0)
|
||||
game.process_player(world, p, T0 + 4 * game.HOUR, random.Random(1))
|
||||
self.assertGreaterEqual(raid["recon"], game.intel_costs(raid)[-1])
|
||||
# Plenty of scouting, but a day or more out only the first level is knowable.
|
||||
view = game.event_view(world, raid, T0 + 4 * game.HOUR)
|
||||
self.assertEqual(view["intel"], 1)
|
||||
self.assertIn("size", view)
|
||||
self.assertNotIn("strength", view)
|
||||
self.assertEqual(view["recon_next"], 0)
|
||||
late = raid["fire_at"] - 12 * game.HOUR
|
||||
self.assertEqual(game.intel_level(world, raid, late), 2)
|
||||
view = game.event_view(world, raid, raid["fire_at"] - game.HOUR)
|
||||
self.assertEqual(view["intel"], 3)
|
||||
self.assertEqual(view["exact"], raid["fire_at"])
|
||||
self.assertIn("strength", view)
|
||||
self.assertTrue(view["camp"])
|
||||
|
||||
def test_bigger_bands_take_more_scouting(self):
|
||||
small = {"kind": "raid", "strength": 20}
|
||||
huge = {"kind": "raid", "strength": 150}
|
||||
dragon = {"kind": "dragon", "strength": 20}
|
||||
self.assertEqual(game.intel_costs(small), [15, 45, 90])
|
||||
self.assertEqual(game.intel_costs(huge), [30, 90, 180])
|
||||
self.assertEqual(game.intel_costs(dragon), [8, 22, 45])
|
||||
|
||||
def test_the_spymasters_guild_boosts_and_gathers_recon(self):
|
||||
world = world_with()
|
||||
raid = self.announce(world)
|
||||
action = game.ACTION_BY_ID["recon_roads"]
|
||||
self.assertEqual(game.recon_gain(world, action), 1)
|
||||
world["city"]["buildings"]["spymaster"]["level"] = 2
|
||||
self.assertEqual(game.recon_gain(world, action), 1.5)
|
||||
game.tick(world, T0 + 2 * game.HOUR, random.Random(2))
|
||||
self.assertAlmostEqual(raid["recon"], 2.0)
|
||||
|
||||
def test_victory_rewards_garrison(self):
|
||||
world = world_with(("wil", "warrior"))
|
||||
raid = self.announce(world)
|
||||
|
|
@ -404,9 +428,11 @@ class EventTest(unittest.TestCase):
|
|||
p["hp"] = game.max_hp(p)
|
||||
raid = self.announce(world)
|
||||
self.assertEqual(game.start_action(world, p, "sabotage", T0), "No bandit camp has been located")
|
||||
raid["recon"] = 3 * game.RECON_PER_INTEL
|
||||
self.assertIsNone(game.start_action(world, p, "sabotage", T0))
|
||||
game.process_player(world, p, T0 + 96 * 20, random.Random(1))
|
||||
raid["recon"] = game.intel_costs(raid)[-1]
|
||||
now = raid["fire_at"] - game.HOUR
|
||||
world["city"]["last_tick"] = p["last_active"] = now
|
||||
self.assertIsNone(game.start_action(world, p, "sabotage", now))
|
||||
game.process_player(world, p, now + 96 * 20, random.Random(1))
|
||||
self.assertGreater(raid["sabotage"], 0)
|
||||
self.assertLessEqual(raid["sabotage"], 0.3)
|
||||
|
||||
|
|
@ -552,11 +578,12 @@ class FavourTest(unittest.TestCase):
|
|||
self.assertEqual(game.spend_favour(world, p, "informant", T0), "No news to dig into")
|
||||
world["next_event_at"] = T0
|
||||
game.tick(world, T0, random.Random(2))
|
||||
event = game.upcoming_event(world)
|
||||
for level in (1, 2, 3):
|
||||
event = game.upcoming_raid(world)
|
||||
while event["recon"] < game.intel_costs(event)[-1]:
|
||||
self.assertIsNone(game.spend_favour(world, p, "informant", T0))
|
||||
self.assertEqual(game.intel_level(world, event), level)
|
||||
self.assertEqual(event["recon"] % game.INFORMANT_RECON, 0)
|
||||
self.assertEqual(game.spend_favour(world, p, "informant", T0), "Nothing more to learn")
|
||||
self.assertEqual(game.intel_level(world, event, T0), 1) # the rest waits for the raid to draw near
|
||||
|
||||
def test_rallies_cost_more_each_time_and_end_with_the_raid(self):
|
||||
world, p = self.world, self.p
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue