feat(combat): support partial and improved cover levels

This commit is contained in:
2026-09-10 11:32:08 +02:00
parent 2eed752f7f
commit e6125b04f6
6 changed files with 401 additions and 23 deletions
+43 -7
View File
@@ -921,7 +921,7 @@ def test_observation_enriched_terrain_semantics_all_types() -> None:
When: an Observation is built
Then: terrain_semantics has one entry per distinct terrain type
(sorted by type for determinism), each carrying
type/move_cost/blocks_los/cover."""
type/move_cost/blocks_los/cover/cover_bonus."""
hero = make_combatant("hero")
foe = make_combatant("foe")
hero_state = make_state(hero, "players", (0, 0))
@@ -932,9 +932,27 @@ def test_observation_enriched_terrain_semantics_all_types() -> None:
obs = _snapshot(engine, hero_state)
semantics = obs["terrain_semantics"]
assert semantics == (
{"type": "floor", "move_cost": 1, "blocks_los": False, "cover": False},
{"type": "pillar", "move_cost": None, "blocks_los": False, "cover": True},
{"type": "wall", "move_cost": None, "blocks_los": True, "cover": False},
{
"type": "floor",
"move_cost": 1,
"blocks_los": False,
"cover": False,
"cover_bonus": 0,
},
{
"type": "pillar",
"move_cost": None,
"blocks_los": False,
"cover": True,
"cover_bonus": 0,
},
{
"type": "wall",
"move_cost": None,
"blocks_los": True,
"cover": False,
"cover_bonus": 0,
},
)
@@ -950,7 +968,13 @@ def test_observation_enriched_terrain_semantics_single_type() -> None:
obs = _snapshot(engine, hero_state)
assert obs["terrain_semantics"] == (
{"type": "floor", "move_cost": 1, "blocks_los": False, "cover": False},
{
"type": "floor",
"move_cost": 1,
"blocks_los": False,
"cover": False,
"cover_bonus": 0,
},
)
@@ -970,7 +994,13 @@ def test_observation_enriched_terrain_semantics_no_grid_iteration_needed() -> No
obs = _snapshot(engine, hero_state)
assert obs["terrain_semantics"] == (
{"type": "wall", "move_cost": None, "blocks_los": True, "cover": False},
{
"type": "wall",
"move_cost": None,
"blocks_los": True,
"cover": False,
"cover_bonus": 0,
},
)
@@ -990,7 +1020,13 @@ def test_observation_enriched_terrain_semantics_no_callable_no_share() -> None:
data = obs.to_dict()
json.dumps(data) # must not raise
for entry in data["terrain_semantics"]:
assert set(entry) == {"type", "move_cost", "blocks_los", "cover"}
assert set(entry) == {
"type",
"move_cost",
"blocks_los",
"cover",
"cover_bonus",
}
# ---------------------------------------------------------------------------