Zones instead of road timers: journeys, flights, meeting stone
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
7150b2f89c
commit
0e396ee5d4
7 changed files with 363 additions and 230 deletions
|
|
@ -35,16 +35,28 @@ class Content(unittest.TestCase):
|
|||
for ab in spec["abilities"]:
|
||||
self.assertIn(ab, content.ABILITIES)
|
||||
|
||||
def test_places_link_both_ways_and_hunts_exist(self):
|
||||
def test_places_sit_in_zones_and_hunts_exist(self):
|
||||
hunts = set()
|
||||
for pid, place in content.PLACES.items():
|
||||
for other in place["links"]:
|
||||
self.assertIn(pid, content.PLACES[other]["links"], f"{pid} -> {other}")
|
||||
self.assertIn(place["zone"], content.ZONES)
|
||||
for hunt, pulls in place.get("hunts", {}).items():
|
||||
self.assertNotIn((place["zone"], hunt), hunts, "hunts must be unique within a zone")
|
||||
hunts.add((place["zone"], hunt))
|
||||
self.assertIn(hunt, content.MOBS)
|
||||
for pull in pulls:
|
||||
for mob in pull:
|
||||
self.assertIn(mob, content.MOBS)
|
||||
|
||||
def test_roads_join_zones_through_real_mobs(self):
|
||||
for road in content.ROADS.values():
|
||||
for zone in road["zones"]:
|
||||
self.assertIn(zone, content.ZONES)
|
||||
self.assertIn(road["rare"], content.MOBS)
|
||||
for stop in road["stops"]:
|
||||
for pull in stop["pulls"]:
|
||||
for mob in pull:
|
||||
self.assertIn(mob, content.MOBS)
|
||||
|
||||
def test_quests_point_at_real_things(self):
|
||||
for qid, quest in content.QUESTS.items():
|
||||
self.assertIn(quest["giver"], content.PLACES)
|
||||
|
|
@ -181,8 +193,8 @@ class World(unittest.TestCase):
|
|||
world = world_with(("fred", "warrior"))
|
||||
fred = world["players"]["fred"]
|
||||
self.assertIsNone(game.accept(fred, "kobold_camp_cleanup"))
|
||||
fred["place"] = "northshire_valley"
|
||||
self.assertIsNone(game.start_hunt(world, fred, "kobold_vermin", 1000))
|
||||
self.assertEqual(fred["place"], "northshire_valley")
|
||||
game.process(world, 1000 + 20 * 60, random.Random(1))
|
||||
self.assertGreater(fred["level"], 1)
|
||||
self.assertEqual(fred["quests"]["kobold_camp_cleanup"], [10])
|
||||
|
|
@ -190,7 +202,6 @@ class World(unittest.TestCase):
|
|||
def test_hunting_stops_after_the_offline_cap(self):
|
||||
world = world_with(("fred", "warrior"))
|
||||
fred = world["players"]["fred"]
|
||||
fred["place"] = "northshire_valley"
|
||||
game.start_hunt(world, fred, "kobold_vermin", 1000)
|
||||
game.process(world, 1000 + game.OFFLINE_CAP + 3600, random.Random(1))
|
||||
self.assertIsNone(fred["activity"])
|
||||
|
|
@ -201,33 +212,73 @@ class World(unittest.TestCase):
|
|||
fred = world["players"]["fred"]
|
||||
game.accept(fred, "kobold_camp_cleanup")
|
||||
fred["quests"]["kobold_camp_cleanup"] = [10]
|
||||
fred["place"] = "goldshire"
|
||||
fred["place"] = "sentinel_hill"
|
||||
self.assertIn("Turn it in", game.turn_in(world, fred, "kobold_camp_cleanup", 2, 0))
|
||||
fred["place"] = "northshire_abbey"
|
||||
fred["place"] = "fargodeep" # anywhere in Elwynn will do
|
||||
self.assertEqual(game.turn_in(world, fred, "kobold_camp_cleanup", None, 0), "Pick a reward")
|
||||
self.assertIsNone(game.turn_in(world, fred, "kobold_camp_cleanup", 2, 0))
|
||||
self.assertIn("w/feet/mail/4", fred["bags"])
|
||||
self.assertIn("investigate_echo_ridge", game.available_quests(fred))
|
||||
|
||||
def test_travel_takes_the_shortest_road(self):
|
||||
minutes, path = game.route("northshire_abbey", "moonbrook")
|
||||
self.assertEqual(path, ["northshire_abbey", "goldshire", "sentinel_hill", "moonbrook"])
|
||||
self.assertEqual(minutes, 14)
|
||||
def test_a_journey_is_a_fight_at_every_stop(self):
|
||||
world = world_with(("fred", "warrior"))
|
||||
fred = world["players"]["fred"]
|
||||
self.assertIsNone(game.travel(world, fred, "goldshire", 1000))
|
||||
game.process(world, 1000 + 4 * 60 - 1, random.Random(1))
|
||||
self.assertEqual(fred["place"], "northshire_abbey")
|
||||
game.process(world, 1000 + 4 * 60, random.Random(1))
|
||||
self.assertEqual(fred["place"], "goldshire")
|
||||
game.dev_level(world, fred, 14, 1000)
|
||||
self.assertIsNone(game.accept(fred, "riverpaw_gnoll_bounty"))
|
||||
fred["done"].append("riverpaw_gnoll_bounty")
|
||||
fred["quests"].pop("riverpaw_gnoll_bounty")
|
||||
self.assertIsNone(game.accept(fred, "report_to_gryan"))
|
||||
self.assertIsNone(game.journey(world, fred, "westfall", 1000))
|
||||
self.assertIn("road", game.start_hunt(world, fred, "kobold_vermin", 1000))
|
||||
fights = 0
|
||||
for step in range(2000):
|
||||
game.process(world, 1000 + step, random.Random(step))
|
||||
if fred["fight"]:
|
||||
fights += step == 0 or world["fights"][fred["fight"]]["t"] <= 1
|
||||
if not fred["activity"]:
|
||||
break
|
||||
self.assertEqual(fred["place"], "sentinel_hill")
|
||||
self.assertEqual(fred["zones"], ["elwynn", "westfall"])
|
||||
self.assertEqual(fred["quests"]["report_to_gryan"], [1])
|
||||
self.assertGreaterEqual(fights, 3)
|
||||
|
||||
def test_dying_on_the_road_sends_you_back(self):
|
||||
world = world_with(("fred", "mage"))
|
||||
fred = world["players"]["fred"]
|
||||
self.assertIsNone(game.journey(world, fred, "westfall", 1000))
|
||||
game.process(world, 1000 + 600, random.Random(1))
|
||||
self.assertIsNone(fred["activity"])
|
||||
self.assertEqual(game.zone_of(fred["place"]), "elwynn")
|
||||
self.assertEqual(fred["zones"], ["elwynn"])
|
||||
|
||||
def test_flying_needs_the_zone_reached_and_the_fare(self):
|
||||
world = world_with(("fred", "warrior"))
|
||||
fred = world["players"]["fred"]
|
||||
self.assertIn("on foot", game.fly(world, fred, "westfall", 0))
|
||||
fred["zones"].append("westfall")
|
||||
self.assertIn("money", game.fly(world, fred, "westfall", 0))
|
||||
fred["copper"] = 100
|
||||
self.assertIsNone(game.fly(world, fred, "westfall", 0))
|
||||
self.assertEqual(fred["place"], "sentinel_hill")
|
||||
self.assertEqual(fred["copper"], 100 - content.FLIGHT_COST)
|
||||
|
||||
def test_old_worlds_migrate(self):
|
||||
world = world_with(("fred", "warrior"))
|
||||
world["version"] = 1
|
||||
fred = world["players"]["fred"]
|
||||
del fred["zones"]
|
||||
fred["activity"] = {"kind": "travel", "to": "sentinel_hill", "end": 0}
|
||||
fred["quests"]["report_to_goldshire"] = [0]
|
||||
game.migrate(world)
|
||||
self.assertEqual((fred["place"], fred["activity"], fred["zones"]), ("sentinel_hill", None, ["westfall"]))
|
||||
self.assertEqual(fred["quests"]["report_to_goldshire"], [])
|
||||
|
||||
def test_a_group_clears_the_deadmines(self):
|
||||
world = world_with(*[(uid, cls) for uid, cls in
|
||||
(("t", "warrior"), ("h", "priest"), ("m", "mage"), ("r", "rogue"), ("x", "hunter"))])
|
||||
for uid, player in world["players"].items():
|
||||
game.dev_level(world, player, 20, 1000)
|
||||
player["place"] = "moonbrook"
|
||||
world["players"]["t"]["place"] = "sentinel_hill"
|
||||
leader = world["players"]["t"]
|
||||
game.create_group(world, leader)
|
||||
gid = leader["group"]
|
||||
|
|
@ -240,17 +291,20 @@ class World(unittest.TestCase):
|
|||
loot = sum(len(p["bags"]) for p in world["players"].values())
|
||||
self.assertGreater(loot, 0)
|
||||
|
||||
def test_dungeon_needs_everyone_at_the_door(self):
|
||||
def test_the_meeting_stone_summons_the_group(self):
|
||||
world = world_with(("a", "warrior"), ("b", "priest"), dev=False)
|
||||
a, b = world["players"]["a"], world["players"]["b"]
|
||||
a["place"] = "moonbrook"
|
||||
game.create_group(world, a)
|
||||
self.assertIn("no dungeon", game.enter_dungeon(world, a, 0))
|
||||
a["place"] = "sentinel_hill"
|
||||
self.assertIn("at least 2", game.enter_dungeon(world, a, 0))
|
||||
game.join_group(world, b, a["group"])
|
||||
game.journey(world, b, "westfall", 0)
|
||||
self.assertIn("Waiting on B", game.enter_dungeon(world, a, 0))
|
||||
b["place"] = "moonbrook"
|
||||
game.stop(world, b, 0)
|
||||
self.assertIsNone(game.enter_dungeon(world, a, 0))
|
||||
self.assertEqual(b["activity"]["kind"], "dungeon")
|
||||
self.assertEqual((b["activity"]["kind"], b["place"]), ("dungeon", "moonbrook"))
|
||||
self.assertIn("westfall", b["zones"])
|
||||
game.leave_group(world, b, 10)
|
||||
self.assertIsNone(b["activity"])
|
||||
self.assertEqual(b["place"], "moonbrook")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue