Decode RTINIT providers 3 and 51

This commit is contained in:
gamer147
2026-07-23 16:44:49 -04:00
parent 6ce98da1ab
commit cb68e9eabd
10 changed files with 216 additions and 52 deletions

View File

@@ -109,6 +109,24 @@ MOVEMENT_PROVIDER_PARAMETER_SCHEMAS = {
"produce movement result state 1 without selecting a destination"
),
},
3: {
"behavior": "route_toward_reachable_normal_attack_target",
"parameter_fields": {},
"target_selection": (
"require a usable normal attack, build the acting entity's "
"movement-limited reach grid, and retain active foreign-faction "
"entities whose occupied tile remains element-effective after "
"SETMVWORK filtering and costs no more than current FS; rank "
"candidates by descending remaining-route score with randomized "
"ties, then use the first candidate for which SETROUTE produces "
"a route"
),
"completion": (
"advance the current step's progress counter and produce movement "
"result state 1 after routing toward a reachable normal-attack "
"target"
),
},
4: {
"behavior": "approach_stage_object_slot",
"parameter_fields": {
@@ -349,6 +367,30 @@ MOVEMENT_PROVIDER_PARAMETER_SCHEMAS = {
"Pillar exists within the configured route-step radius"
),
},
51: {
"behavior": "select_effective_attack_target_and_action",
"parameter_fields": {},
"target_selection": (
"require a usable nonzero attack-range band, scan active foreign-"
"faction entities inside the ATSEEK range grid, and retain targets "
"for which at least one allowed normal-attack/equipped-skill "
"element has positive effectiveness against the target's defense "
"element; encountering a lower range band clears earlier "
"candidates, and the final target is randomized from the retained "
"list"
),
"action_selection": (
"after choosing the target, collect the effective actions enabled "
"in the tracked closest range band (0 means normal attack; nonzero "
"values are equipped skill ids), choose randomly, and store both "
"the target entity and selected action"
),
"completion": (
"advance the current step's progress counter and produce immediate-"
"battle result state 2 when a target/action pair is selected; no "
"movement route is produced"
),
},
}
UNIT_STAT_COLUMNS = (

View File

@@ -371,8 +371,8 @@ def test_real_routine_banks() -> None:
and len(meta["used_battle_provider_selectors"]) == 4
and len(meta["record_field_columns"]) == 117,
"RTINIT assembles every populated movement and battle step")
check(meta["decoded_movement_provider_count"] == 12
and meta["decoded_movement_step_count"] == 632
check(meta["decoded_movement_provider_count"] == 14
and meta["decoded_movement_step_count"] == 858
and meta["decoded_movement_parameter_count"] == 974
and meta["decoded_movement_defaulted_parameter_count"] == 13
and meta["ignored_movement_parameter_count"] == 3,
@@ -486,6 +486,18 @@ def test_real_routine_banks() -> None:
and provider_14["provider_behavior"] == "retreat_from_nearby_enemies"
and provider_14["maximum_threat_route_steps"] == 6,
"RTINIT joins RTN_M014's threat-detection radius")
provider_3 = by_id[3]["movement_steps"][3]
check(provider_3["movement_provider_selector"] == 3
and provider_3["provider_behavior"]
== "route_toward_reachable_normal_attack_target"
and "movement_parameter_1" not in provider_3,
"RTINIT joins RTN_M003's parameterless attack-route behavior")
provider_51 = by_id[3]["movement_steps"][1]
check(provider_51["movement_provider_selector"] == 51
and provider_51["provider_behavior"]
== "select_effective_attack_target_and_action"
and "movement_parameter_1" not in provider_51,
"RTINIT joins RTN_M051's parameterless attack-selection behavior")
undecoded_movement = by_id[2]["movement_steps"][1]
check(undecoded_movement["movement_provider_selector"] == 2
and "provider_behavior" not in undecoded_movement

View File

@@ -36,6 +36,17 @@ def test_load_and_lint():
check(entries[0xbf6fe]["name"] == "pathfinding_filtered_route_scores"
and entries[0xcc9f4]["name"] == "offensive_action_scope_masks",
"movement target filtering and offensive scope are curated")
check(entries[0xb8d86]["name"] == "attack_range_distance_grid"
and entries[0xcc9f3]["name"] == "offensive_action_max_range",
"attack-range search state is curated")
check(entries[0x66713]["name"] == "acting_entity_index"
and entries[0x66714]["name"] == "target_entity_index"
and entries[0x52289]["name"] == "entity_selected_action_ids",
"AI actor, target, and selected action state are curated")
check(entries[0xcca08]["name"] == "offensive_action_attack_elements"
and entries[0xab5ba]["name"]
== "attack_element_effectiveness_percent",
"AI action-element eligibility state is curated")
check(entries[0x20543]["name"] == "tile_faction_traversal_masks",
"faction-specific tile traversal masks are curated")
check(entries[0xaba64]["name"] == "stage_object_runtime_flags",