Add disarm attack lock tactic

This commit is contained in:
2026-06-18 10:32:32 +09:00
parent b15c5f6869
commit cbfc221782
11 changed files with 68 additions and 26 deletions

View File

@@ -586,6 +586,9 @@ func try_attack_selected(target_id: String) -> bool:
return false
if attacker.get("acted", false):
return false
if _unit_has_action_lock(attacker, "attack"):
_emit_log("%s cannot attack while disarmed." % attacker["name"])
return false
if attacker.get("team", "") == target.get("team", ""):
return false
if not _is_in_attack_range(attacker, target["pos"]):
@@ -696,14 +699,15 @@ func get_damage_preview(attacker_id: String, target_id: String) -> Dictionary:
if attacker.get("team", "") == target.get("team", ""):
return {}
var damage := calculate_damage(attacker, target)
var attack_locked := _unit_has_action_lock(attacker, "attack")
var damage := 0 if attack_locked else calculate_damage(attacker, target)
var target_hp_after: int = maxi(0, int(target["hp"]) - damage)
var counter_damage := 0
var attacker_hp_after := int(attacker["hp"])
var hit_chance := calculate_hit_chance(attacker, target)
var hit_chance := 0 if attack_locked else calculate_hit_chance(attacker, target)
var counter_hit_chance := 0
var counter_in_range := false
if target_hp_after > 0 or hit_chance < 100:
if not attack_locked and (target_hp_after > 0 or hit_chance < 100):
counter_in_range = _is_in_attack_range(target, attacker["pos"])
if counter_in_range:
counter_damage = calculate_damage(target, attacker)
@@ -716,7 +720,8 @@ func get_damage_preview(attacker_id: String, target_id: String) -> Dictionary:
"hit_chance": hit_chance,
"target_hp_after": target_hp_after,
"would_defeat": int(target["hp"]) - damage <= 0,
"in_range": _is_in_attack_range(attacker, target["pos"]),
"in_range": not attack_locked and _is_in_attack_range(attacker, target["pos"]),
"attack_locked": attack_locked,
"counter_in_range": counter_in_range,
"counter_damage": counter_damage,
"counter_hit_chance": counter_hit_chance,
@@ -1065,6 +1070,8 @@ func _action_lock_display_name(action: String) -> String:
return "tactics"
if action == "move":
return "movement"
if action == "attack":
return "attacks"
return "action"
@@ -1179,6 +1186,8 @@ func get_attack_cells(unit_id: String) -> Array[Vector2i]:
return []
if unit.get("team", "") == TEAM_PLAYER and not unit.get("deployed", true):
return []
if _unit_has_action_lock(unit, "attack"):
return []
return _attack_cells_from(unit, unit["pos"])
@@ -1692,6 +1701,8 @@ func _attack_cells_from(unit: Dictionary, origin: Vector2i) -> Array[Vector2i]:
func _is_in_attack_range(attacker: Dictionary, target_cell: Vector2i) -> bool:
if _unit_has_action_lock(attacker, "attack"):
return false
return _attack_cells_from(attacker, attacker["pos"]).has(target_cell)
@@ -2262,6 +2273,8 @@ func _unit_action_threat_score(unit: Dictionary, action: String) -> int:
if int(unit.get("range", 1)) <= 1:
move_score += 10
return move_score
if action == "attack":
return _effective_stat(unit, "atk") * 4 + int(unit.get("range", 1)) * 4
return 0