Clarify combat result reports

This commit is contained in:
2026-06-21 01:45:30 +09:00
parent 6cc5db09fc
commit ddec5b5e94
5 changed files with 298 additions and 4 deletions

View File

@@ -7,6 +7,7 @@ signal changed
signal log_added(message: String)
signal dialogue_requested(lines: Array)
signal combat_feedback_requested(unit_id: String, text: String, kind: String)
signal combat_result_reported(report: Dictionary)
signal unit_motion_requested(unit_id: String, from_cell: Vector2i, to_cell: Vector2i)
signal unit_action_motion_requested(unit_id: String, from_cell: Vector2i, to_cell: Vector2i, action_kind: String)
signal objective_updated(victory: String, defeat: String)
@@ -3752,19 +3753,40 @@ func _opposing_team(team: String) -> String:
func _resolve_combat(attacker: Dictionary, target: Dictionary) -> void:
var report := _make_combat_result_report(attacker, target)
var attack_result := _resolve_attack(attacker, target, false)
(report["entries"] as Array).append(attack_result)
var attack_exp := EXP_ATTACK if bool(attack_result.get("hit", false)) else EXP_MISS
if bool(attack_result.get("defeated", false)) or battle_status != STATUS_ACTIVE:
_grant_experience(attacker, attack_exp + (EXP_DEFEAT_BONUS if bool(attack_result.get("defeated", false)) else 0))
var final_attack_exp := attack_exp + (EXP_DEFEAT_BONUS if bool(attack_result.get("defeated", false)) else 0)
_grant_experience(attacker, final_attack_exp)
report["attacker_merit"] = final_attack_exp
combat_result_reported.emit(report)
return
var counter_exp := 0
if bool(target.get("controllable", true)) and _is_in_attack_range(target, attacker["pos"]):
var counter_result := _resolve_attack(target, attacker, true)
(report["entries"] as Array).append(counter_result)
counter_exp = (EXP_COUNTER if bool(counter_result.get("hit", false)) else EXP_MISS) + (EXP_DEFEAT_BONUS if bool(counter_result.get("defeated", false)) else 0)
_grant_experience(attacker, attack_exp)
report["attacker_merit"] = attack_exp
_grant_experience(target, counter_exp)
report["counter_merit"] = counter_exp
combat_result_reported.emit(report)
func _make_combat_result_report(attacker: Dictionary, target: Dictionary) -> Dictionary:
return {
"attacker_id": str(attacker.get("id", "")),
"attacker_name": str(attacker.get("name", "")),
"target_id": str(target.get("id", "")),
"target_name": str(target.get("name", "")),
"attacker_merit": 0,
"counter_merit": 0,
"entries": []
}
func _resolve_attack(attacker: Dictionary, target: Dictionary, is_counter := false) -> Dictionary:
@@ -3780,7 +3802,22 @@ func _resolve_attack(attacker: Dictionary, target: Dictionary, is_counter := fal
if rng.randi_range(1, 100) > hit_chance:
_emit_log("%s %s %s, 헛쳤다. 명중 %d%%." % [attacker["name"], verb, target["name"], hit_chance])
_emit_combat_feedback(target, "헛침", "miss")
return {"hit": false, "defeated": false}
return {
"attacker_id": str(attacker.get("id", "")),
"attacker_name": str(attacker.get("name", "")),
"target_id": str(target.get("id", "")),
"target_name": str(target.get("name", "")),
"is_counter": is_counter,
"hit": false,
"defeated": false,
"damage": 0,
"hit_chance": hit_chance,
"target_hp": int(target.get("hp", 0)),
"target_max_hp": int(target.get("max_hp", 0)),
"directional_label": "",
"directional_bonus": 0,
"effective_bonus": 0
}
var directional_info := get_directional_attack_info(attacker, target)
var damage := calculate_damage(attacker, target)
target["hp"] = max(0, int(target["hp"]) - damage)
@@ -3799,8 +3836,38 @@ func _resolve_attack(attacker: Dictionary, target: Dictionary, is_counter := fal
_emit_log("%s 퇴각." % target["name"])
_emit_combat_feedback(target, "퇴각", "defeat")
_handle_unit_defeated(target)
return {"hit": true, "defeated": true}
return {"hit": true, "defeated": false}
return {
"attacker_id": str(attacker.get("id", "")),
"attacker_name": str(attacker.get("name", "")),
"target_id": str(target.get("id", "")),
"target_name": str(target.get("name", "")),
"is_counter": is_counter,
"hit": true,
"defeated": true,
"damage": damage,
"hit_chance": hit_chance,
"target_hp": int(target.get("hp", 0)),
"target_max_hp": int(target.get("max_hp", 0)),
"directional_label": str(directional_info.get("label", "")),
"directional_bonus": directional_bonus,
"effective_bonus": effective_bonus
}
return {
"attacker_id": str(attacker.get("id", "")),
"attacker_name": str(attacker.get("name", "")),
"target_id": str(target.get("id", "")),
"target_name": str(target.get("name", "")),
"is_counter": is_counter,
"hit": true,
"defeated": false,
"damage": damage,
"hit_chance": hit_chance,
"target_hp": int(target.get("hp", 0)),
"target_max_hp": int(target.get("max_hp", 0)),
"directional_label": str(directional_info.get("label", "")),
"directional_bonus": directional_bonus,
"effective_bonus": effective_bonus
}
func _resolve_skill_damage(caster: Dictionary, target: Dictionary, skill: Dictionary) -> bool: