Add multi-cell reach triggers
This commit is contained in:
76
tools/smoke_event_cells.gd
Normal file
76
tools/smoke_event_cells.gd
Normal 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
|
||||
@@ -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") {
|
||||
|
||||
Reference in New Issue
Block a user