Preview enemy reactions on move cells
This commit is contained in:
@@ -6542,6 +6542,14 @@ func _ai_zone_cells_for_unit(unit: Dictionary) -> Array[Vector2i]:
|
||||
return cells
|
||||
|
||||
|
||||
func _ai_zone_contains_cell(unit: Dictionary, cell: Vector2i) -> bool:
|
||||
var radius := _ai_zone_radius_for_unit(unit)
|
||||
var anchor := _ai_zone_anchor_for_unit(unit)
|
||||
if radius < 0 or not state.is_inside(anchor) or not state.is_inside(cell):
|
||||
return false
|
||||
return absi(cell.x - anchor.x) + absi(cell.y - anchor.y) <= radius
|
||||
|
||||
|
||||
func _ai_zone_anchor_for_unit(unit: Dictionary) -> Vector2i:
|
||||
var behavior := str(unit.get("ai_behavior", "")).strip_edges().to_lower()
|
||||
var fallback: Vector2i = unit.get("pos", Vector2i(-1, -1))
|
||||
@@ -8618,10 +8626,49 @@ func _hover_intent_preview_badge(selected: Dictionary, target: Dictionary) -> Di
|
||||
return _make_target_preview_badge("선택", "select")
|
||||
return {}
|
||||
if move_cells.has(hover_cell):
|
||||
return _make_target_preview_badge("행군", "move")
|
||||
return _move_cell_preview_badge(hover_cell)
|
||||
return {}
|
||||
|
||||
|
||||
func _move_cell_preview_badge(cell: Vector2i) -> Dictionary:
|
||||
var sentry_names := _ai_reaction_unit_names_for_cell(cell, "sentry")
|
||||
if not sentry_names.is_empty():
|
||||
var lure_badge := _make_target_preview_badge_at("유인", "advance", cell)
|
||||
lure_badge["tooltip"] = "초병 반응권: %s" % _compact_name_list(sentry_names, 2)
|
||||
return lure_badge
|
||||
var guard_names := _ai_reaction_unit_names_for_cell(cell, "guard")
|
||||
if not guard_names.is_empty():
|
||||
var guard_badge := _make_target_preview_badge_at("경계", "select", cell)
|
||||
guard_badge["tooltip"] = "거점 경계권: %s" % _compact_name_list(guard_names, 2)
|
||||
return guard_badge
|
||||
var threat_names := state.get_threatening_unit_names(cell, BattleState.TEAM_ENEMY)
|
||||
if not threat_names.is_empty():
|
||||
var danger_badge := _make_target_preview_badge_at("위험", "danger", cell)
|
||||
danger_badge["tooltip"] = "현재 적 공격권: %s" % _compact_name_list(threat_names, 2)
|
||||
return danger_badge
|
||||
return _make_target_preview_badge_at("행군", "move", cell)
|
||||
|
||||
|
||||
func _ai_reaction_unit_names_for_cell(cell: Vector2i, behavior: String) -> Array[String]:
|
||||
var names: Array[String] = []
|
||||
var normalized_behavior := behavior.strip_edges().to_lower()
|
||||
if normalized_behavior.is_empty() or not state.is_inside(cell):
|
||||
return names
|
||||
for unit in state.get_living_units(BattleState.TEAM_ENEMY):
|
||||
if not bool(unit.get("deployed", true)):
|
||||
continue
|
||||
if str(unit.get("ai_behavior", "")).strip_edges().to_lower() != normalized_behavior:
|
||||
continue
|
||||
if normalized_behavior == "sentry" and bool(unit.get("ai_awake", false)):
|
||||
continue
|
||||
if not _ai_zone_contains_cell(unit, cell):
|
||||
continue
|
||||
var unit_name := str(unit.get("name", unit.get("id", "부대")))
|
||||
if not names.has(unit_name):
|
||||
names.append(unit_name)
|
||||
return names
|
||||
|
||||
|
||||
func _make_target_preview_badge(text: String, kind: String) -> Dictionary:
|
||||
return _make_target_preview_badge_at(text, kind, hover_cell)
|
||||
|
||||
|
||||
@@ -4743,10 +4743,14 @@ func _check_hover_intent_badges(failures: Array[String]) -> void:
|
||||
return
|
||||
scene.battle_started = true
|
||||
var enemy: Dictionary = scene.state.get_unit("yellow_turban_1")
|
||||
enemy["pos"] = Vector2i(1, 5)
|
||||
scene.state.select_unit("cao_cao")
|
||||
scene._refresh_ranges()
|
||||
|
||||
var enemy_alive_states := {}
|
||||
for foe in scene.state.get_living_units(BattleStateScript.TEAM_ENEMY):
|
||||
enemy_alive_states[str(foe.get("id", ""))] = bool(foe.get("alive", false))
|
||||
foe["alive"] = false
|
||||
scene._refresh_ranges()
|
||||
scene.hover_cell = Vector2i(2, 5)
|
||||
var move_badge := scene._target_preview_badge()
|
||||
if str(move_badge.get("text", "")) != "행군" or str(move_badge.get("kind", "")) != "move":
|
||||
@@ -4757,6 +4761,19 @@ func _check_hover_intent_badges(failures: Array[String]) -> void:
|
||||
failures.append("MOVE badge should use generated jade panel metadata: %s" % str(move_badge))
|
||||
if not scene._hover_info_badge().is_empty():
|
||||
failures.append("hover info badge should yield to active move intent badge")
|
||||
for unit_id in enemy_alive_states.keys():
|
||||
var restored_enemy: Dictionary = scene.state.get_unit(str(unit_id))
|
||||
if not restored_enemy.is_empty():
|
||||
restored_enemy["alive"] = bool(enemy_alive_states[unit_id])
|
||||
scene._refresh_ranges()
|
||||
enemy["pos"] = Vector2i(1, 5)
|
||||
scene._refresh_ranges()
|
||||
scene.hover_cell = Vector2i(2, 5)
|
||||
var danger_move_badge := scene._target_preview_badge()
|
||||
if str(danger_move_badge.get("text", "")) != "위험" or str(danger_move_badge.get("kind", "")) != "danger":
|
||||
failures.append("moving into current enemy attack range should show DANGER badge: %s" % str(danger_move_badge))
|
||||
if not str(danger_move_badge.get("tooltip", "")).contains("현재 적 공격권"):
|
||||
failures.append("danger move badge should explain current enemy attack range: %s" % str(danger_move_badge))
|
||||
|
||||
scene.hover_cell = Vector2i(1, 7)
|
||||
var select_badge := scene._target_preview_badge()
|
||||
@@ -4830,6 +4847,11 @@ func _check_hover_intent_badges(failures: Array[String]) -> void:
|
||||
failures.append("sleeping sentry hover badge should expose lure timing compactly: %s" % str(sentry_hover_badge))
|
||||
if not sentry_hover_text.contains("유인 밖 4칸"):
|
||||
failures.append("sleeping sentry hover badge should expose current lure distance: %s" % str(sentry_hover_badge))
|
||||
var lure_move_badge := scene._move_cell_preview_badge(Vector2i(5, 6))
|
||||
if str(lure_move_badge.get("text", "")) != "유인" or str(lure_move_badge.get("kind", "")) != "advance":
|
||||
failures.append("move preview should mark cells that wake sleeping sentries: %s" % str(lure_move_badge))
|
||||
if not str(lure_move_badge.get("tooltip", "")).contains("초병 반응권"):
|
||||
failures.append("lure move badge should explain sentry reaction zone: %s" % str(lure_move_badge))
|
||||
central_sentry["ai_awake"] = true
|
||||
var awake_sentry_hover_badge := scene._hover_info_badge()
|
||||
if not str(awake_sentry_hover_badge.get("lines", [])).contains("초병 경계"):
|
||||
@@ -4856,6 +4878,11 @@ func _check_hover_intent_badges(failures: Array[String]) -> void:
|
||||
var guard_hover_text := str(guard_hover_badge.get("lines", []))
|
||||
if not guard_hover_text.contains("수비") or not guard_hover_text.contains("거점 밖 4칸"):
|
||||
failures.append("guard hover badge should expose current guard-zone distance: %s" % str(guard_hover_badge))
|
||||
var guard_move_badge := scene._move_cell_preview_badge(Vector2i(4, 5))
|
||||
if str(guard_move_badge.get("text", "")) != "경계" or str(guard_move_badge.get("kind", "")) != "select":
|
||||
failures.append("move preview should mark guard reaction cells: %s" % str(guard_move_badge))
|
||||
if not str(guard_move_badge.get("tooltip", "")).contains("거점 경계권"):
|
||||
failures.append("guard move badge should explain guard reaction zone: %s" % str(guard_move_badge))
|
||||
var hovered_guard: Dictionary = scene._hovered_ai_zone_unit()
|
||||
if str(hovered_guard.get("id", "")) != "yellow_turban_4":
|
||||
failures.append("hovered guard should expose a drawable AI zone: %s" % str(hovered_guard))
|
||||
|
||||
Reference in New Issue
Block a user