Add multi-cell reach triggers

This commit is contained in:
2026-06-18 14:29:04 +09:00
parent 4f5e949d84
commit 0c0a49ad57
10 changed files with 173 additions and 54 deletions

View File

@@ -0,0 +1,76 @@
extends SceneTree
const BattleStateScript := preload("res://scripts/core/battle_state.gd")
func _init() -> void:
var failures: Array[String] = []
_check_condition_cells(failures)
_check_event_cells(failures)
if failures.is_empty():
print("event cells smoke ok")
quit(0)
return
for failure in failures:
push_error(failure)
quit(1)
func _check_condition_cells(failures: Array[String]) -> void:
var state = _loaded_state(failures, "condition cells")
if state == null:
return
state.battle_conditions["victory"] = {
"type": "unit_reaches_tile",
"team": "player",
"unit_ids": ["cao_cao"],
"cells": [[2, 3], [2, 4]]
}
var objective_cells: Array[Vector2i] = state.get_objective_cells()
if not objective_cells.has(Vector2i(2, 3)) or not objective_cells.has(Vector2i(2, 4)):
failures.append("objective cells missing multi-cell destination: %s" % str(objective_cells))
var progress: String = state.get_objective_progress_text(false)
if not progress.contains("(3, 4), (3, 5): not reached"):
failures.append("multi-cell progress text mismatch before reach: %s" % progress)
var cao_cao: Dictionary = state.get_unit("cao_cao")
cao_cao["pos"] = Vector2i(2, 4)
progress = state.get_objective_progress_text(false)
if not progress.contains("(3, 4), (3, 5): reached"):
failures.append("multi-cell progress text mismatch after reach: %s" % progress)
if not state._is_condition_met(state.battle_conditions["victory"]):
failures.append("multi-cell unit_reaches_tile condition should be met")
func _check_event_cells(failures: Array[String]) -> void:
var state = _loaded_state(failures, "event cells")
if state == null:
return
var logs: Array[String] = []
state.log_added.connect(func(message: String) -> void:
logs.append(message)
)
state.fired_event_ids.clear()
state.battle_events.clear()
state.battle_events.append({
"id": "multi_cell_cache",
"once": true,
"when": {"type": "unit_reaches_tile", "team": "player", "cells": [[3, 2], [3, 3]]},
"actions": [
{"type": "log", "text": "Multi-cell trigger fired."}
]
})
var cao_cao: Dictionary = state.get_unit("cao_cao")
cao_cao["pos"] = Vector2i(3, 3)
state._run_events("unit_reaches_tile", "player", 1, cao_cao)
if not logs.has("Multi-cell trigger fired."):
failures.append("multi-cell event did not fire from second cell")
func _loaded_state(failures: Array[String], label: String):
var state = BattleStateScript.new()
if not state.load_battle("res://data/scenarios/001_yellow_turbans.json"):
failures.append("%s could not load smoke scenario" % label)
return null
return state

View File

@@ -239,6 +239,50 @@ if (Has-Prop $campaign "chapters") {
}
}
function Check-Unit-Reaches-Cells($Source, [string]$Context, [int]$Width, [int]$Height, $Rows) {
$hasPos = Has-Prop $Source "pos"
$hasCells = Has-Prop $Source "cells"
if ($hasPos -and $hasCells) {
Fail "$Context must use either pos or cells, not both."
}
if (-not $hasPos -and -not $hasCells) {
Fail "$Context is missing pos or cells."
}
$cellEntries = @()
if ($hasPos) {
$cellEntries += ,$Source.pos
} else {
if (-not ($Source.cells -is [System.Array])) {
Fail "$Context cells must be an array."
}
$cellEntries = @($Source.cells)
if ($cellEntries.Count -le 0) {
Fail "$Context cells must not be empty."
}
}
$seenCells = New-Object System.Collections.Generic.HashSet[string]
foreach ($entry in $cellEntries) {
$cell = Resolve-Cell $entry $Context
$x = [int]$cell.X
$y = [int]$cell.Y
if ($Width -ge 0 -and $Height -ge 0 -and ($x -lt 0 -or $y -lt 0 -or $x -ge $Width -or $y -ge $Height)) {
Fail "$Context is outside map at [$x,$y]."
}
if ($null -ne $Rows) {
$terrainKey = Terrain-At $Rows $x $y
if ([int]$terrain.$terrainKey.move_cost.foot -ge 99 -and [int]$terrain.$terrainKey.move_cost.mounted -ge 99 -and [int]$terrain.$terrainKey.move_cost.archer -ge 99) {
Fail "$Context targets impassable terrain at [$x,$y]."
}
}
$key = "$x,$y"
if (-not $seenCells.Add($key)) {
Fail "$Context has duplicate cell [$x,$y]."
}
}
}
function Check-Condition($Condition, [string]$ScenarioId, $EventIds, [int]$Width = -1, [int]$Height = -1, $Rows = $null, $KnownUnitIds = $null) {
if ($Condition -is [System.Array]) {
foreach ($entry in $Condition) {
@@ -279,21 +323,7 @@ function Check-Condition($Condition, [string]$ScenarioId, $EventIds, [int]$Width
}
}
if ($type -eq "unit_reaches_tile") {
if (-not (Has-Prop $Condition "pos")) {
Fail "Scenario $ScenarioId unit_reaches_tile condition is missing pos."
}
$cell = Resolve-Cell $Condition.pos "Scenario $ScenarioId unit_reaches_tile condition"
$x = [int]$cell.X
$y = [int]$cell.Y
if ($Width -ge 0 -and $Height -ge 0 -and ($x -lt 0 -or $y -lt 0 -or $x -ge $Width -or $y -ge $Height)) {
Fail "Scenario $ScenarioId unit_reaches_tile condition is outside map at [$x,$y]."
}
if ($null -ne $Rows) {
$terrainKey = Terrain-At $Rows $x $y
if ([int]$terrain.$terrainKey.move_cost.foot -ge 99 -and [int]$terrain.$terrainKey.move_cost.mounted -ge 99 -and [int]$terrain.$terrainKey.move_cost.archer -ge 99) {
Fail "Scenario $ScenarioId unit_reaches_tile condition targets impassable terrain at [$x,$y]."
}
}
Check-Unit-Reaches-Cells $Condition "Scenario $ScenarioId unit_reaches_tile condition" $Width $Height $Rows
$unitIdsValue = $null
if (Has-Prop $Condition "unit_ids") {
$unitIdsValue = $Condition.unit_ids
@@ -336,19 +366,7 @@ function Check-Condition($Condition, [string]$ScenarioId, $EventIds, [int]$Width
}
function Check-Unit-Reaches-Event-When($When, [string]$ScenarioId, [int]$Width, [int]$Height, $Rows, $KnownUnitIds) {
if (-not (Has-Prop $When "pos")) {
Fail "Scenario $ScenarioId unit_reaches_tile event is missing pos."
}
$cell = Resolve-Cell $When.pos "Scenario $ScenarioId unit_reaches_tile event"
$x = [int]$cell.X
$y = [int]$cell.Y
if ($x -lt 0 -or $y -lt 0 -or $x -ge $Width -or $y -ge $Height) {
Fail "Scenario $ScenarioId unit_reaches_tile event is outside map at [$x,$y]."
}
$terrainKey = Terrain-At $Rows $x $y
if ([int]$terrain.$terrainKey.move_cost.foot -ge 99 -and [int]$terrain.$terrainKey.move_cost.mounted -ge 99 -and [int]$terrain.$terrainKey.move_cost.archer -ge 99) {
Fail "Scenario $ScenarioId unit_reaches_tile event targets impassable terrain at [$x,$y]."
}
Check-Unit-Reaches-Cells $When "Scenario $ScenarioId unit_reaches_tile event" $Width $Height $Rows
$unitIdsValue = $null
if (Has-Prop $When "unit_ids") {