Add scripted event withdrawals
This commit is contained in:
117
tools/smoke_event_withdraw.gd
Normal file
117
tools/smoke_event_withdraw.gd
Normal file
@@ -0,0 +1,117 @@
|
||||
extends SceneTree
|
||||
|
||||
const BattleStateScript := preload("res://scripts/core/battle_state.gd")
|
||||
|
||||
|
||||
func _init() -> void:
|
||||
var failures: Array[String] = []
|
||||
var state = BattleStateScript.new()
|
||||
if not state.load_battle("res://data/scenarios/009_xiapi_siege.json"):
|
||||
push_error("Could not load Xiapi smoke scenario.")
|
||||
quit(1)
|
||||
return
|
||||
|
||||
_check_single_withdraw(state, failures)
|
||||
_check_multi_withdraw(state, failures)
|
||||
|
||||
if failures.is_empty():
|
||||
print("event withdraw smoke ok")
|
||||
quit(0)
|
||||
return
|
||||
|
||||
for failure in failures:
|
||||
push_error(failure)
|
||||
quit(1)
|
||||
|
||||
|
||||
func _check_single_withdraw(state, failures: Array[String]) -> void:
|
||||
var logs := []
|
||||
var feedback := []
|
||||
state.log_added.connect(func(message: String) -> void:
|
||||
logs.append(message)
|
||||
)
|
||||
state.combat_feedback_requested.connect(func(unit_id: String, text: String, kind: String) -> void:
|
||||
feedback.append({"unit_id": unit_id, "text": text, "kind": kind})
|
||||
)
|
||||
|
||||
_spawn_smoke_unit(state, "withdraw_smoke_enemy", "Smoke Raider", Vector2i(4, 4))
|
||||
logs.clear()
|
||||
feedback.clear()
|
||||
var before_living: int = state.get_living_units("enemy").size()
|
||||
state._execute_event_action({"type": "withdraw_unit", "unit_id": "withdraw_smoke_enemy"})
|
||||
var unit: Dictionary = state.get_unit("withdraw_smoke_enemy")
|
||||
if unit.is_empty():
|
||||
failures.append("single withdraw smoke unit disappeared from state")
|
||||
return
|
||||
if bool(unit.get("deployed", true)):
|
||||
failures.append("single withdraw unit should no longer be deployed")
|
||||
if not bool(unit.get("alive", false)):
|
||||
failures.append("single withdraw unit should stay alive for non-defeat retreat semantics")
|
||||
if not state.get_unit_at(Vector2i(4, 4)).is_empty():
|
||||
failures.append("single withdraw unit should no longer occupy its map cell")
|
||||
if state.get_living_units("enemy").size() != before_living - 1:
|
||||
failures.append("single withdraw should remove one living enemy from battle counts")
|
||||
_check_log_contains(failures, logs, "Smoke Raider withdraws from the battlefield.")
|
||||
_check_feedback_contains(failures, feedback, "withdraw_smoke_enemy", "WITHDRAW", "fade")
|
||||
|
||||
|
||||
func _check_multi_withdraw(state, failures: Array[String]) -> void:
|
||||
_spawn_smoke_unit(state, "withdraw_smoke_north", "North Raider", Vector2i(5, 4))
|
||||
_spawn_smoke_unit(state, "withdraw_smoke_south", "South Raider", Vector2i(6, 4))
|
||||
state._execute_event_action({
|
||||
"type": "withdraw_units",
|
||||
"unit_ids": ["withdraw_smoke_north", "withdraw_smoke_south"]
|
||||
})
|
||||
for unit_id in ["withdraw_smoke_north", "withdraw_smoke_south"]:
|
||||
var unit: Dictionary = state.get_unit(unit_id)
|
||||
if unit.is_empty():
|
||||
failures.append("multi withdraw unit missing from state: %s" % unit_id)
|
||||
continue
|
||||
if bool(unit.get("deployed", true)):
|
||||
failures.append("multi withdraw unit should no longer be deployed: %s" % unit_id)
|
||||
if not bool(unit.get("alive", false)):
|
||||
failures.append("multi withdraw unit should stay alive: %s" % unit_id)
|
||||
|
||||
|
||||
func _spawn_smoke_unit(state, unit_id: String, unit_name: String, cell: Vector2i) -> void:
|
||||
state._execute_event_action({
|
||||
"type": "spawn_deployment",
|
||||
"deployment": {
|
||||
"unit_id": unit_id,
|
||||
"name": unit_name,
|
||||
"class_id": "cavalry",
|
||||
"team": "enemy",
|
||||
"level": 8,
|
||||
"pos": [cell.x, cell.y],
|
||||
"base": {"hp": 40, "atk": 15, "def": 8, "agi": 11}
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
func _check_log_contains(failures: Array[String], logs: Array, expected: String) -> void:
|
||||
for log_entry in logs:
|
||||
if str(log_entry) == expected:
|
||||
return
|
||||
failures.append("expected log `%s` in `%s`" % [expected, logs])
|
||||
|
||||
|
||||
func _check_feedback_contains(
|
||||
failures: Array[String],
|
||||
feedback: Array,
|
||||
expected_unit_id: String,
|
||||
expected_text: String,
|
||||
expected_kind: String
|
||||
) -> void:
|
||||
for entry in feedback:
|
||||
if (
|
||||
str(entry.get("unit_id", "")) == expected_unit_id
|
||||
and str(entry.get("text", "")) == expected_text
|
||||
and str(entry.get("kind", "")) == expected_kind
|
||||
):
|
||||
return
|
||||
failures.append("expected feedback `%s/%s/%s` in `%s`" % [
|
||||
expected_unit_id,
|
||||
expected_text,
|
||||
expected_kind,
|
||||
feedback
|
||||
])
|
||||
@@ -93,7 +93,7 @@ $validConditionTypes = @(
|
||||
"any"
|
||||
)
|
||||
$validTriggers = @("battle_start", "battle_begin", "turn_start", "unit_reaches_tile")
|
||||
$validActions = @("log", "dialogue", "set_objective", "grant_item", "grant_items", "spawn_deployment", "spawn_deployments")
|
||||
$validActions = @("log", "dialogue", "set_objective", "grant_item", "grant_items", "spawn_deployment", "spawn_deployments", "withdraw_unit", "withdraw_units")
|
||||
$validEffects = @("heal_hp", "heal_mp", "cure_status")
|
||||
$validItemKinds = @("weapon", "armor", "accessory", "consumable")
|
||||
$validItemRarities = @("common", "named")
|
||||
@@ -554,6 +554,32 @@ function Check-Event-Grant-Item($Entry, [string]$Context) {
|
||||
}
|
||||
}
|
||||
|
||||
function Check-Event-Withdraw-Unit-Id([string]$UnitId, $KnownUnitIds, [string]$Context) {
|
||||
if ([string]::IsNullOrWhiteSpace($UnitId)) {
|
||||
Fail "$Context has empty unit id."
|
||||
}
|
||||
if (-not $KnownUnitIds.Contains($UnitId)) {
|
||||
Fail "$Context references unknown unit: $UnitId"
|
||||
}
|
||||
}
|
||||
|
||||
function Check-Event-Withdraw-Units($UnitIds, $KnownUnitIds, [string]$Context) {
|
||||
if ($null -eq $UnitIds -or -not ($UnitIds -is [System.Array])) {
|
||||
Fail "$Context unit_ids must be an array."
|
||||
}
|
||||
if (@($UnitIds).Count -le 0) {
|
||||
Fail "$Context unit_ids must not be empty."
|
||||
}
|
||||
$seenWithdrawals = New-Object System.Collections.Generic.HashSet[string]
|
||||
foreach ($unitIdValue in @($UnitIds)) {
|
||||
$unitId = [string]$unitIdValue
|
||||
Check-Event-Withdraw-Unit-Id $unitId $KnownUnitIds $Context
|
||||
if (-not $seenWithdrawals.Add($unitId)) {
|
||||
Fail "$Context has duplicate unit: $unitId"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function Check-Class-Equipment-Slots() {
|
||||
$weaponTypes = @()
|
||||
$armorTypes = @()
|
||||
@@ -1757,6 +1783,13 @@ foreach ($scenario in $campaign.scenarios) {
|
||||
Check-Event-Grant-Item $entry "Scenario $scenarioId event $eventId grant_items"
|
||||
}
|
||||
}
|
||||
if ($actionType -eq "withdraw_unit") {
|
||||
$unitId = [string](Get-Prop $action "unit_id" (Get-Prop $action "id" ""))
|
||||
Check-Event-Withdraw-Unit-Id $unitId $knownUnitIds "Scenario $scenarioId event $eventId withdraw_unit"
|
||||
}
|
||||
if ($actionType -eq "withdraw_units") {
|
||||
Check-Event-Withdraw-Units (Get-Prop $action "unit_ids" $null) $knownUnitIds "Scenario $scenarioId event $eventId withdraw_units"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user