Retheme battle HUD command wording

This commit is contained in:
2026-06-19 02:08:50 +09:00
parent 50692fa05d
commit 1911038d70
3 changed files with 169 additions and 161 deletions

View File

@@ -565,33 +565,33 @@ func _create_hud() -> void:
side_column.add_child(button_row)
wait_button = Button.new()
wait_button.text = "Wait"
wait_button.text = "Hold"
wait_button.pressed.connect(_on_wait_pressed)
button_row.add_child(wait_button)
tactic_button = Button.new()
tactic_button.text = "Tactic"
tactic_button.text = "Stratagem"
tactic_button.pressed.connect(_on_tactic_pressed)
button_row.add_child(tactic_button)
item_button = Button.new()
item_button.text = "Item"
item_button.text = "Supply"
item_button.pressed.connect(_on_item_pressed)
button_row.add_child(item_button)
equip_button = Button.new()
equip_button.text = "Equip"
equip_button.text = "Arms"
equip_button.pressed.connect(_on_equip_pressed)
button_row.add_child(equip_button)
threat_button = Button.new()
threat_button.text = "Threat"
threat_button.text = "Enemy Lines"
threat_button.toggle_mode = true
threat_button.pressed.connect(_on_threat_pressed)
button_row.add_child(threat_button)
end_turn_button = Button.new()
end_turn_button.text = "End Turn"
end_turn_button.text = "Pass Command"
end_turn_button.pressed.connect(_on_end_turn_pressed)
button_row.add_child(end_turn_button)
@@ -601,7 +601,7 @@ func _create_hud() -> void:
side_column.add_child(tactic_menu)
var tactic_title := Label.new()
tactic_title.text = "Tactics"
tactic_title.text = "Stratagems"
_apply_label_style(tactic_title, UI_OLD_BRONZE, 14)
tactic_menu.add_child(tactic_title)
@@ -615,7 +615,7 @@ func _create_hud() -> void:
side_column.add_child(item_menu)
var item_title := Label.new()
item_title.text = "Items"
item_title.text = "Supplies"
_apply_label_style(item_title, UI_OLD_BRONZE, 14)
item_menu.add_child(item_title)
@@ -629,7 +629,7 @@ func _create_hud() -> void:
side_column.add_child(equip_menu)
var equip_title := Label.new()
equip_title.text = "Equipment"
equip_title.text = "Arms Ledger"
_apply_label_style(equip_title, UI_OLD_BRONZE, 14)
equip_menu.add_child(equip_title)
@@ -662,26 +662,26 @@ func _create_hud() -> void:
post_move_column.add_child(post_move_grid)
post_move_attack_button = Button.new()
post_move_attack_button.text = "Attack"
post_move_attack_button.text = "Strike"
post_move_attack_button.tooltip_text = "Mark an enemy from this unit's current position."
post_move_attack_button.pressed.connect(_on_post_move_attack_pressed)
post_move_grid.add_child(post_move_attack_button)
post_move_tactic_button = Button.new()
post_move_tactic_button.text = "Tactic"
post_move_tactic_button.tooltip_text = "Open tactics after this move."
post_move_tactic_button.text = "Stratagem"
post_move_tactic_button.tooltip_text = "Open stratagems after this move."
post_move_tactic_button.pressed.connect(_on_post_move_tactic_pressed)
post_move_grid.add_child(post_move_tactic_button)
post_move_item_button = Button.new()
post_move_item_button.text = "Item"
post_move_item_button.tooltip_text = "Open consumable items after this move."
post_move_item_button.text = "Supply"
post_move_item_button.tooltip_text = "Open field supplies after this move."
post_move_item_button.pressed.connect(_on_post_move_item_pressed)
post_move_grid.add_child(post_move_item_button)
post_move_wait_button = Button.new()
post_move_wait_button.text = "Wait"
post_move_wait_button.tooltip_text = "Commit this move and end the unit's action."
post_move_wait_button.text = "Hold"
post_move_wait_button.tooltip_text = "Commit this move and seal the unit's order."
post_move_wait_button.pressed.connect(_on_post_move_wait_pressed)
post_move_grid.add_child(post_move_wait_button)
@@ -737,7 +737,7 @@ func _create_hud() -> void:
post_move_picker_cancel_move_button = Button.new()
post_move_picker_cancel_move_button.text = "Recall Step"
post_move_picker_cancel_move_button.tooltip_text = "Right-click also returns to the starting cell."
post_move_picker_cancel_move_button.tooltip_text = "Right-click also recalls the banner to its starting ground."
post_move_picker_cancel_move_button.pressed.connect(_on_post_move_picker_cancel_move_pressed)
picker_button_row.add_child(post_move_picker_cancel_move_button)
@@ -777,7 +777,7 @@ func _create_hud() -> void:
targeting_hint_cancel_move_button = Button.new()
targeting_hint_cancel_move_button.text = "Recall Step"
targeting_hint_cancel_move_button.tooltip_text = "Return to the starting cell."
targeting_hint_cancel_move_button.tooltip_text = "Recall the banner to its starting ground."
targeting_hint_cancel_move_button.pressed.connect(_on_targeting_cancel_move_pressed)
targeting_button_row.add_child(targeting_hint_cancel_move_button)
@@ -2894,7 +2894,7 @@ func _update_hud() -> void:
var hovered_unit := _hovered_unit_for_hud_portrait()
_update_hud_unit_portrait(hovered_unit)
if hovered_unit.is_empty():
selected_label.text = "No unit selected."
selected_label.text = "No banner marked."
else:
selected_label.text = _format_unit_focus_text(hovered_unit, "Hover")
_update_wait_button({})
@@ -2935,12 +2935,12 @@ func _format_objective_hud_text() -> String:
func _format_unit_focus_text(unit: Dictionary, prefix: String) -> String:
if unit.is_empty():
return "No unit selected."
return "No banner marked."
var roster_mark := " *" if unit.get("loaded_from_roster", false) else ""
var control_label := " Protected" if not bool(unit.get("controllable", true)) else ""
var lines := []
lines.append("%s: %s%s%s" % [
prefix,
_unit_focus_prefix_text(prefix),
str(unit.get("name", "Unit")),
roster_mark,
control_label
@@ -2951,14 +2951,14 @@ func _format_unit_focus_text(unit: Dictionary, prefix: String) -> String:
str(unit.get("class", "Unit")),
_unit_role_text(unit)
])
lines.append("HP %d/%d MP %d/%d EXP %d" % [
lines.append("Troops %d/%d Qi %d/%d Merit %d" % [
int(unit.get("hp", 0)),
int(unit.get("max_hp", 1)),
int(unit.get("mp", 0)),
int(unit.get("max_mp", 0)),
int(unit.get("exp", 0))
])
lines.append("ATK %d DEF %d INT %d AGI %d" % [
lines.append("Might %d Guard %d Counsel %d Tempo %d" % [
int(unit.get("atk", 0)),
int(unit.get("def", 0)),
int(unit.get("int", 0)),
@@ -2976,25 +2976,33 @@ func _format_unit_focus_text(unit: Dictionary, prefix: String) -> String:
lines.append(terrain_text)
var status_effects := state.get_status_effect_summary(str(unit.get("id", "")))
if not status_effects.is_empty():
lines.append("Effects: %s" % status_effects)
lines.append("Conditions: %s" % status_effects)
return _join_strings(lines, "\n")
func _unit_focus_prefix_text(prefix: String) -> String:
if prefix == "Selected":
return "Banner"
if prefix == "Hover":
return "Sighted"
return prefix
func _unit_action_status_text(unit: Dictionary) -> String:
var unit_id := str(unit.get("id", ""))
if unit_id.is_empty():
return "Order: Unavailable"
return "Command: Sealed"
var team := str(unit.get("team", ""))
if team != BattleState.TEAM_PLAYER:
return "Order: Enemy command"
return "Command: Enemy banner"
if not bool(unit.get("controllable", true)):
return "Order: Protected escort"
return "Command: Guarded escort"
if not bool(unit.get("alive", true)) or not bool(unit.get("deployed", true)):
return "Order: Unavailable"
return "Command: Sealed"
if bool(unit.get("acted", false)):
return "Order: Done"
return "Command: Sealed"
if not state.can_player_act():
return "Order: Awaiting turn"
return "Command: Awaiting phase"
var actions: Array[String] = []
if not bool(unit.get("moved", false)) and not state.get_movement_range(unit_id).is_empty():
actions.append("March")
@@ -3002,14 +3010,14 @@ func _unit_action_status_text(unit: Dictionary) -> String:
actions.append("Strike")
var skill_id := state.get_first_usable_skill_id(unit_id)
if not skill_id.is_empty() and not state.get_skill_cells(unit_id, skill_id).is_empty():
actions.append("Tactic")
actions.append("Stratagem")
if _unit_has_usable_item_target(unit_id):
actions.append("Supply")
if not bool(unit.get("moved", false)):
actions.append("Arms")
actions.append("Wait")
actions.append("Hold")
var suffix := " (marched)" if bool(unit.get("moved", false)) else ""
return "Order: %s%s" % [_join_strings(actions, ", "), suffix]
return "Command: %s%s" % [_join_strings(actions, ", "), suffix]
func _unit_has_usable_item_target(unit_id: String) -> bool:
@@ -3058,13 +3066,13 @@ func _unit_role_text(unit: Dictionary) -> String:
if class_id.contains("cavalry"):
return "Shock cavalry"
if class_id.contains("archer") or class_id.contains("marksman"):
return "Ranged pressure"
return "Bow pressure"
if class_id.contains("strategist") or class_id.contains("advisor"):
return "Tactics support"
return "Stratagem counsel"
if class_id.contains("hero") or class_id.contains("commander"):
return "Command tactics"
return "Command authority"
if class_id.contains("warrior") or class_id.contains("champion") or class_id.contains("bandit"):
return "Assault fighter"
return "Assault vanguard"
return "Line infantry"
@@ -3160,7 +3168,7 @@ func _update_cell_info() -> void:
var unit: Dictionary = summary["unit"]
if not unit.is_empty():
var control_label := " Protected" if not bool(unit.get("controllable", true)) else ""
text += "\nTroop: %s%s %s Lv.%d\n%s %s HP %d/%d MP %d/%d\nArms: %s" % [
text += "\nBanner: %s%s %s Lv.%d\n%s %s Troops %d/%d Qi %d/%d\nArms: %s" % [
unit["name"],
control_label,
str(unit["team"]).capitalize(),
@@ -3182,7 +3190,7 @@ func _update_cell_info() -> void:
text += "\nWeapon threat: %s" % _format_physical_threat_preview_text(physical_threats, 3)
var skill_threats := state.get_skill_threat_previews(cell, BattleState.TEAM_ENEMY)
if not skill_threats.is_empty():
text += "\nTactic threat: %s" % _format_skill_threat_preview_text(skill_threats, 3)
text += "\nStratagem threat: %s" % _format_skill_threat_preview_text(skill_threats, 3)
cell_info_label.text = text
@@ -3262,7 +3270,7 @@ func _compact_name_list(names: Array[String], limit: int) -> String:
func _update_forecast() -> void:
var selected := state.get_selected_unit()
if selected.is_empty() or not state.is_inside(hover_cell):
forecast_label.text = "Forecast: -"
forecast_label.text = "War Read: -"
return
if not selected_skill_id.is_empty():
@@ -3274,16 +3282,16 @@ func _update_forecast() -> void:
var target := state.get_unit_at(hover_cell)
if target.is_empty() or target.get("team", "") == selected.get("team", ""):
forecast_label.text = "Forecast: -"
forecast_label.text = "War Read: -"
return
var preview := state.get_damage_preview(selected["id"], target["id"])
if preview.is_empty():
forecast_label.text = "Forecast: -"
forecast_label.text = "War Read: -"
return
if bool(preview.get("attack_locked", false)):
forecast_label.text = "Forecast: disarmed.\nCannot use physical attacks."
forecast_label.text = "War Read: disarmed.\nCannot strike with weapons."
return
var range_text := "ready" if preview["in_range"] else "out of range"
@@ -3293,7 +3301,7 @@ func _update_forecast() -> void:
if preview["counter_in_range"]:
var counter_defeat := " Defeat" if preview["counter_would_defeat"] else ""
var counter_effective_text := _format_effective_forecast_text(preview, "counter_effective_bonus", "counter_effective_target_type")
counter_text = "\nCounter %d%s, Hit %d%%, your HP %d/%d.%s" % [
counter_text = "\nCounter %d%s, Hit %d%%, your Troops %d/%d.%s" % [
preview["counter_damage"],
counter_effective_text,
preview.get("counter_hit_chance", 0),
@@ -3301,7 +3309,7 @@ func _update_forecast() -> void:
selected["max_hp"],
counter_defeat
]
forecast_label.text = "Forecast: %s\n%d damage%s, Hit %d%%, target HP %d/%d.%s%s" % [
forecast_label.text = "War Read: %s\n%d damage%s, Hit %d%%, foe Troops %d/%d.%s%s" % [
range_text,
preview["damage"],
effective_text,
@@ -3326,19 +3334,19 @@ func _format_effective_forecast_text(preview: Dictionary, bonus_key: String, typ
func _update_skill_forecast(selected: Dictionary) -> void:
var preview := state.get_skill_preview(selected["id"], selected_skill_id, hover_cell)
if preview.is_empty():
forecast_label.text = "Forecast: -"
forecast_label.text = "War Read: -"
return
var range_text := "ready" if preview["in_range"] else "out of range"
var mp_text := "" if preview["has_mp"] else " Not enough MP."
var mp_text := "" if preview["has_mp"] else " Not enough Qi."
if bool(preview.get("skill_locked", false)):
forecast_label.text = "%s: sealed, %d MP.\nCannot use tactics." % [
forecast_label.text = "%s: sealed, %d Qi.\nCannot use stratagems." % [
preview["skill_name"],
preview["mp_cost"]
]
return
if not preview["valid_target"]:
forecast_label.text = "%s: %s, %d MP.%s\nNo valid target." % [
forecast_label.text = "%s: %s, %d Qi.%s\nNo valid mark." % [
preview["skill_name"],
range_text,
preview["mp_cost"],
@@ -3350,11 +3358,11 @@ func _update_skill_forecast(selected: Dictionary) -> void:
var target_max_hp := int(target.get("max_hp", 1)) if not target.is_empty() else 1
var target_count := int(preview.get("target_count", 1))
var has_area := bool(preview.get("has_area", false))
var area_text := " Area targets: %d." % target_count if has_area else ""
var area_text := " Area marks: %d." % target_count if has_area else ""
if preview["kind"] == "heal":
var total_heal := int(preview.get("total_heal", preview.get("heal", 0)))
if not has_area:
forecast_label.text = "%s: %s, %d MP.%s\nRestore %d HP, target HP %d/%d." % [
forecast_label.text = "%s: %s, %d Qi.%s\nRestore %d Troops, banner Troops %d/%d." % [
preview["skill_name"],
range_text,
preview["mp_cost"],
@@ -3364,7 +3372,7 @@ func _update_skill_forecast(selected: Dictionary) -> void:
target_max_hp
]
return
forecast_label.text = "%s: %s, %d MP.%s%s\nRestore %d HP total, focus HP %d/%d." % [
forecast_label.text = "%s: %s, %d Qi.%s%s\nRestore %d Troops total, focus Troops %d/%d." % [
preview["skill_name"],
range_text,
preview["mp_cost"],
@@ -3376,7 +3384,7 @@ func _update_skill_forecast(selected: Dictionary) -> void:
]
elif preview["kind"] == "support":
var refresh_text := " Refresh." if bool(preview.get("already_active", false)) else ""
forecast_label.text = "%s: %s, %d MP.%s%s\n%s.%s" % [
forecast_label.text = "%s: %s, %d Qi.%s%s\n%s.%s" % [
preview["skill_name"],
range_text,
preview["mp_cost"],
@@ -3391,7 +3399,7 @@ func _update_skill_forecast(selected: Dictionary) -> void:
var total_damage := int(preview.get("total_damage", preview.get("damage", 0)))
if not has_area:
var single_defeat_text := " Defeat" if bool(preview.get("would_defeat", false)) else ""
forecast_label.text = "%s: %s, %d MP.%s\n%d damage, target HP %d/%d.%s" % [
forecast_label.text = "%s: %s, %d Qi.%s\n%d damage, foe Troops %d/%d.%s" % [
preview["skill_name"],
range_text,
preview["mp_cost"],
@@ -3402,7 +3410,7 @@ func _update_skill_forecast(selected: Dictionary) -> void:
single_defeat_text
]
return
forecast_label.text = "%s: %s, %d MP.%s%s\n%d total damage, focus HP %d/%d.%s" % [
forecast_label.text = "%s: %s, %d Qi.%s%s\n%d total damage, focus Troops %d/%d.%s" % [
preview["skill_name"],
range_text,
preview["mp_cost"],
@@ -3418,14 +3426,14 @@ func _update_skill_forecast(selected: Dictionary) -> void:
func _update_item_forecast(selected: Dictionary) -> void:
var preview := state.get_item_preview(selected["id"], selected_item_id, hover_cell)
if preview.is_empty():
forecast_label.text = "Forecast: -"
forecast_label.text = "War Read: -"
return
var target := state.get_unit_at(hover_cell)
var range_text := "ready" if preview["in_range"] else "out of range"
var count_text := "x%d" % int(preview.get("count", 0))
if target.is_empty() or not preview["valid_target"]:
forecast_label.text = "%s: %s, %s\nNo valid target." % [
forecast_label.text = "%s: %s, %s\nNo valid mark." % [
preview["item_name"],
range_text,
count_text
@@ -3436,7 +3444,7 @@ func _update_item_forecast(selected: Dictionary) -> void:
var mp_heal := int(preview.get("mp_heal", 0))
var cure_statuses: Array = preview.get("cure_statuses", [])
if hp_heal <= 0 and mp_heal <= 0 and cure_statuses.is_empty():
forecast_label.text = "%s: %s, %s\nNo item effect needed." % [
forecast_label.text = "%s: %s, %s\nNo supply effect needed." % [
preview["item_name"],
range_text,
count_text
@@ -3445,13 +3453,13 @@ func _update_item_forecast(selected: Dictionary) -> void:
var recovery_parts := []
if hp_heal > 0:
recovery_parts.append("Restore %d HP, target HP %d/%d" % [
recovery_parts.append("Restore %d Troops, banner Troops %d/%d" % [
hp_heal,
preview["target_hp_after"],
target["max_hp"]
])
if mp_heal > 0:
recovery_parts.append("Restore %d MP, target MP %d/%d" % [
recovery_parts.append("Restore %d Qi, banner Qi %d/%d" % [
mp_heal,
preview["target_mp_after"],
target.get("max_mp", 0)
@@ -5377,14 +5385,14 @@ func _rebuild_armory_menu() -> void:
var equipment_label := Label.new()
equipment_label.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
equipment_label.text = "Equipped: %s" % _format_unit_equipment(selected)
equipment_label.text = "Arms Held: %s" % _format_unit_equipment(selected)
_apply_label_style(equipment_label, UI_AGED_INK)
armory_list.add_child(equipment_label)
var equipped_slots := state.get_equipped_equipment_slots(armory_unit_id)
if not equipped_slots.is_empty():
var unequip_title := Label.new()
unequip_title.text = "Unequip"
unequip_title.text = "Remove Arms"
_apply_label_style(unequip_title, UI_CINNABAR, 14)
armory_list.add_child(unequip_title)
var equipment := state.get_equipment_snapshot(armory_unit_id)
@@ -6377,25 +6385,25 @@ func _update_post_move_menu() -> void:
return
_position_post_move_menu()
if post_move_title_label != null:
post_move_title_label.text = "%s: choose action" % str(selected.get("name", "Unit"))
post_move_title_label.text = "%s: issue order" % str(selected.get("name", "Unit"))
if post_move_attack_button != null:
var attack_blocked := not _has_basic_attack_target(pending_move_unit_id)
post_move_attack_button.disabled = attack_blocked
post_move_attack_button.tooltip_text = "No enemy is in range after this move." if attack_blocked else "Mark an enemy from this unit's current position."
post_move_attack_button.tooltip_text = "No enemy banner is within reach." if attack_blocked else "Mark an enemy from this banner's current ground."
if post_move_tactic_button != null:
var skill_blocked := not _unit_has_usable_skill_target(pending_move_unit_id)
post_move_tactic_button.disabled = skill_blocked
post_move_tactic_button.tooltip_text = "No tactic has a valid target after this move." if skill_blocked else "Select a tactic writ from this unit's current position."
post_move_tactic_button.tooltip_text = "No stratagem can reach from this ground." if skill_blocked else "Select a stratagem writ from this banner's current ground."
if post_move_item_button != null:
var item_blocked := not _unit_has_usable_item_target(pending_move_unit_id)
post_move_item_button.disabled = item_blocked
post_move_item_button.tooltip_text = "No usable item target is in range." if item_blocked else "Open consumable items after this move."
post_move_item_button.tooltip_text = "No supply can reach from this ground." if item_blocked else "Open field supplies after this move."
if post_move_wait_button != null:
post_move_wait_button.disabled = false
post_move_wait_button.tooltip_text = "Commit this move and end the unit's action."
post_move_wait_button.tooltip_text = "Commit this march and seal the banner's order."
if post_move_cancel_button != null:
post_move_cancel_button.disabled = false
post_move_cancel_button.tooltip_text = "Right-click also returns to the starting cell."
post_move_cancel_button.tooltip_text = "Right-click also recalls the banner to its starting ground."
func _local_command_panel_position_for_cell(cell: Vector2i, panel_size: Vector2) -> Vector2:
@@ -6520,17 +6528,17 @@ func _position_post_move_picker() -> void:
func _post_move_picker_title_text(selected: Dictionary) -> String:
var unit_name := str(selected.get("name", "Unit"))
if post_move_picker_mode == "tactic":
return "%s: choose tactic" % unit_name
return "%s: choose stratagem" % unit_name
if post_move_picker_mode == "item":
return "%s: choose item" % unit_name
return "%s: choose" % unit_name
return "%s: choose supply" % unit_name
return "%s: choose writ" % unit_name
func _post_move_picker_detail_text() -> String:
if post_move_picker_mode == "tactic":
return "Pick a tactic, then click a highlighted target."
return "Select a stratagem, then mark highlighted ground."
if post_move_picker_mode == "item":
return "Pick an item, then click a highlighted ally."
return "Select a supply, then mark a highlighted ally."
return "Select a writ."
@@ -6538,7 +6546,7 @@ func _rebuild_post_move_tactic_picker(selected: Dictionary) -> void:
var skill_ids := state.get_skill_ids(selected["id"])
if skill_ids.is_empty():
var empty_label := Label.new()
empty_label.text = "No tactics"
empty_label.text = "No stratagems"
_apply_label_style(empty_label, UI_PARCHMENT_TEXT)
post_move_picker_list.add_child(empty_label)
return
@@ -6559,7 +6567,7 @@ func _rebuild_post_move_item_picker(selected: Dictionary) -> void:
var item_ids := state.get_usable_item_ids()
if item_ids.is_empty():
var empty_label := Label.new()
empty_label.text = "No items"
empty_label.text = "No supplies"
_apply_label_style(empty_label, UI_PARCHMENT_TEXT)
post_move_picker_list.add_child(empty_label)
return
@@ -6589,10 +6597,10 @@ func _format_post_move_tactic_button_text(skill_id: String, skill: Dictionary, s
if state.is_unit_skill_sealed(selected["id"]):
disabled_text = " - Sealed"
elif int(selected.get("mp", 0)) < mp_cost:
disabled_text = " - MP"
disabled_text = " - Qi"
elif not _skill_has_valid_target(str(selected.get("id", "")), skill_id):
disabled_text = " - No target"
return "%s%s %dMP %s R%s%s" % [marker, skill_name, mp_cost, kind, range_text, disabled_text]
disabled_text = " - No mark"
return "%s%s %d Qi %s Reach %s%s" % [marker, skill_name, mp_cost, kind, range_text, disabled_text]
func _format_post_move_item_button_text(item_id: String, item: Dictionary, count: int) -> String:
@@ -6608,9 +6616,9 @@ func _format_post_move_item_effect_text(item: Dictionary) -> String:
continue
var effect_type := str(effect.get("type", ""))
if effect_type == "heal_hp":
return "HP +%d" % int(effect.get("amount", 0))
return "Troops +%d" % int(effect.get("amount", 0))
if effect_type == "heal_mp":
return "MP +%d" % int(effect.get("amount", 0))
return "Qi +%d" % int(effect.get("amount", 0))
if effect_type == "cure_status" or effect_type == "cleanse_debuffs":
has_cure = true
if has_cure:
@@ -6620,15 +6628,15 @@ func _format_post_move_item_effect_text(item: Dictionary) -> String:
func _post_move_tactic_disabled_reason(selected: Dictionary, skill_id: String, skill: Dictionary) -> String:
if skill.is_empty():
return "Unknown tactic."
return "Unknown stratagem."
if state.is_unit_skill_sealed(selected["id"]):
return "This unit is sealed."
return "This banner is sealed."
if bool(selected.get("acted", false)):
return "This unit has already acted."
return "This banner has already acted."
if int(selected.get("mp", 0)) < int(skill.get("mp_cost", 0)):
return "Not enough MP."
return "Not enough Qi."
if not _skill_has_valid_target(str(selected.get("id", "")), skill_id):
return "No valid target from this tile."
return "No valid mark from this ground."
return ""
@@ -6636,7 +6644,7 @@ func _post_move_item_disabled_reason(selected: Dictionary, item_id: String, coun
if count <= 0:
return "No stock remains."
if not _item_has_valid_target(str(selected.get("id", "")), item_id):
return "No valid target from this tile."
return "No valid mark from this ground."
return ""
@@ -6772,7 +6780,7 @@ func _update_targeting_hint_panel() -> void:
if targeting_hint_cancel_move_button != null:
targeting_hint_cancel_move_button.visible = _has_pending_move()
targeting_hint_cancel_move_button.disabled = not _has_pending_move()
targeting_hint_cancel_move_button.tooltip_text = "Right-click also returns to the starting cell."
targeting_hint_cancel_move_button.tooltip_text = "Right-click also recalls the banner to its starting ground."
targeting_hint_panel.visible = true
@@ -6801,18 +6809,18 @@ func _targeting_hint_detail_text() -> String:
if basic_attack_targeting:
var markers := _attack_target_marker_entries()
if markers.is_empty():
return "No enemy is in range."
return "%d enemy target%s. Click a marked enemy." % [markers.size(), "" if markers.size() == 1 else "s"]
return "No enemy banner is within reach."
return "%d enemy mark%s. Strike a marked foe." % [markers.size(), "" if markers.size() == 1 else "s"]
if not selected_skill_id.is_empty():
var markers := _skill_target_marker_entries()
if markers.is_empty():
return "No valid tactic target."
return "%d tactic target%s. Click a marked cell." % [markers.size(), "" if markers.size() == 1 else "s"]
return "No valid stratagem mark."
return "%d stratagem mark%s. Choose marked ground." % [markers.size(), "" if markers.size() == 1 else "s"]
if not selected_item_id.is_empty():
var markers := _item_target_marker_entries()
if markers.is_empty():
return "No valid item target."
return "%d item target%s. Click a marked unit." % [markers.size(), "" if markers.size() == 1 else "s"]
return "No valid supply mark."
return "%d supply mark%s. Choose a marked banner." % [markers.size(), "" if markers.size() == 1 else "s"]
return "Mark a highlighted target."
@@ -6851,27 +6859,27 @@ func _set_action_button_blocked(button: Button, base_label: String, reason_label
func _action_phase_block_reason() -> Dictionary:
if campaign_complete_screen:
return {
"label": "Campaign Done",
"label": "Chronicle Sealed",
"tooltip": "The campaign is complete."
}
if not battle_started:
return {
"label": "Start Battle",
"label": "Enter Field",
"tooltip": "Begin the battle before using combat actions."
}
if state.battle_status != BattleState.STATUS_ACTIVE:
return {
"label": "Battle Over",
"label": "Field Settled",
"tooltip": "Combat actions are unavailable after the battle ends."
}
if state.current_team != BattleState.TEAM_PLAYER:
return {
"label": "Enemy Turn",
"tooltip": "Wait for the player phase."
"label": "Enemy Phase",
"tooltip": "Await the player command phase."
}
if _is_input_locked():
return {
"label": "Busy",
"label": "Resolving",
"tooltip": "Finish the current dialogue, result, or animation first."
}
return {}
@@ -6881,16 +6889,16 @@ func _update_wait_button(selected: Dictionary) -> void:
if wait_button == null:
return
if selected.is_empty():
_set_action_button_blocked(wait_button, "Wait", "Select Unit", "Select a controllable player unit before waiting.")
_set_action_button_blocked(wait_button, "Hold", "Mark Banner", "Mark a controllable banner before holding.")
return
if bool(selected.get("acted", false)):
_set_action_button_blocked(wait_button, "Wait", "Done", "This unit has already acted.")
_set_action_button_blocked(wait_button, "Hold", "Sealed", "This banner has already acted.")
return
var phase_block := _action_phase_block_reason()
if not phase_block.is_empty():
_set_action_button_blocked(wait_button, "Wait", str(phase_block.get("label", "Busy")), str(phase_block.get("tooltip", "")))
_set_action_button_blocked(wait_button, "Hold", str(phase_block.get("label", "Resolving")), str(phase_block.get("tooltip", "")))
return
_set_action_button_state(wait_button, "Wait", false, "End this unit's action for the current turn.")
_set_action_button_state(wait_button, "Hold", false, "Seal this banner's order for the current phase.")
func _update_end_turn_button() -> void:
@@ -6898,9 +6906,9 @@ func _update_end_turn_button() -> void:
return
var phase_block := _action_phase_block_reason()
if not phase_block.is_empty():
_set_action_button_blocked(end_turn_button, "End Turn", str(phase_block.get("label", "Busy")), str(phase_block.get("tooltip", "")))
_set_action_button_blocked(end_turn_button, "Pass Command", str(phase_block.get("label", "Resolving")), str(phase_block.get("tooltip", "")))
return
_set_action_button_state(end_turn_button, "End Turn", false, "End the player phase and let enemies act.")
_set_action_button_state(end_turn_button, "Pass Command", false, "End the player phase and let enemy banners act.")
func _update_threat_button() -> void:
@@ -6908,46 +6916,46 @@ func _update_threat_button() -> void:
return
threat_button.button_pressed = show_threat_overlay
if campaign_complete_screen:
_set_action_button_blocked(threat_button, "Threat", "Campaign Done", "The campaign is complete.")
_set_action_button_blocked(threat_button, "Enemy Lines", "Chronicle Sealed", "The campaign is complete.")
return
if not battle_started:
_set_action_button_blocked(threat_button, "Threat", "Start Battle", "Begin the battle before showing enemy threat range.")
_set_action_button_blocked(threat_button, "Enemy Lines", "Enter Field", "Begin the battle before reading enemy lines.")
return
if state.battle_status != BattleState.STATUS_ACTIVE:
_set_action_button_blocked(threat_button, "Threat", "Battle Over", "Threat range is only available during active battles.")
_set_action_button_blocked(threat_button, "Enemy Lines", "Field Settled", "Enemy lines are only available during active battles.")
return
_set_action_button_state(threat_button, "Threat", false, "Toggle enemy attack and hostile tactic reach.")
_set_action_button_state(threat_button, "Enemy Lines", false, "Toggle enemy weapon and hostile stratagem reach.")
func _update_tactic_button(selected: Dictionary) -> void:
if tactic_button == null:
return
if selected.is_empty():
_set_action_button_blocked(tactic_button, "Tactic", "Select Unit", "Select a controllable player unit before using tactics.")
_set_action_button_blocked(tactic_button, "Stratagem", "Mark Banner", "Mark a controllable banner before using stratagems.")
return
var skill_ids := state.get_skill_ids(selected["id"])
if skill_ids.is_empty():
_set_action_button_blocked(tactic_button, "Tactic", "None", "This unit has no tactics.")
_set_action_button_blocked(tactic_button, "Stratagem", "None", "This banner has no stratagems.")
return
if state.is_unit_skill_sealed(selected["id"]):
_set_action_button_blocked(tactic_button, "Tactic", "Sealed", "This unit is sealed and cannot use tactics.")
_set_action_button_blocked(tactic_button, "Stratagem", "Sealed", "This banner is sealed and cannot use stratagems.")
return
if bool(selected.get("acted", false)):
_set_action_button_blocked(tactic_button, "Tactic", "Done", "This unit has already acted.")
_set_action_button_blocked(tactic_button, "Stratagem", "Sealed", "This banner has already acted.")
return
var phase_block := _action_phase_block_reason()
if not phase_block.is_empty():
_set_action_button_blocked(tactic_button, "Tactic", str(phase_block.get("label", "Busy")), str(phase_block.get("tooltip", "")))
_set_action_button_blocked(tactic_button, "Stratagem", str(phase_block.get("label", "Resolving")), str(phase_block.get("tooltip", "")))
return
if not selected_skill_id.is_empty():
var skill := state.get_skill_def(selected_skill_id)
_set_action_button_state(tactic_button, "Tactic: %s" % str(skill.get("name", selected_skill_id)), false, "Target this tactic on the map.")
_set_action_button_state(tactic_button, "Stratagem: %s" % str(skill.get("name", selected_skill_id)), false, "Mark this stratagem on the field.")
elif tactic_menu != null and tactic_menu.visible:
_set_action_button_state(tactic_button, "Close Tactic", false, "Close the tactics menu.")
_set_action_button_state(tactic_button, "Close Stratagems", false, "Close the stratagem menu.")
else:
_set_action_button_state(tactic_button, "Tactic", false, "Open tactics. %d known." % skill_ids.size())
_set_action_button_state(tactic_button, "Stratagem", false, "Open stratagems. %d known." % skill_ids.size())
func _show_tactic_menu(selected: Dictionary) -> void:
@@ -6972,14 +6980,14 @@ func _rebuild_tactic_menu(selected: Dictionary) -> void:
var skill_ids := state.get_skill_ids(selected["id"])
if skill_ids.is_empty():
var empty_label := Label.new()
empty_label.text = "No tactics"
empty_label.text = "No stratagems"
_apply_label_style(empty_label, UI_PARCHMENT_TEXT)
tactic_list.add_child(empty_label)
return
var skill_sealed := state.is_unit_skill_sealed(selected["id"])
if skill_sealed:
var sealed_label := Label.new()
sealed_label.text = "Tactics sealed"
sealed_label.text = "Stratagems sealed"
_apply_label_style(sealed_label, UI_PARCHMENT_TEXT)
tactic_list.add_child(sealed_label)
@@ -6993,7 +7001,7 @@ func _rebuild_tactic_menu(selected: Dictionary) -> void:
tactic_list.add_child(skill_button)
var cancel_button := Button.new()
cancel_button.text = "Cancel"
cancel_button.text = "Return"
_apply_button_style(cancel_button)
cancel_button.pressed.connect(_on_tactic_cancel_pressed)
tactic_list.add_child(cancel_button)
@@ -7016,8 +7024,8 @@ func _format_tactic_button_text(skill_id: String, skill: Dictionary, selected: D
if state.is_unit_skill_sealed(selected["id"]):
disabled_text = " - Sealed"
elif int(selected.get("mp", 0)) < mp_cost:
disabled_text = " - MP"
return "%s%s %dMP %s R%s %s%s" % [marker, skill_name, mp_cost, kind, range_text, effect_text, disabled_text]
disabled_text = " - Qi"
return "%s%s %d Qi %s Reach %s %s%s" % [marker, skill_name, mp_cost, kind, range_text, effect_text, disabled_text]
func _format_tactic_effect_text(skill: Dictionary) -> String:
@@ -7110,28 +7118,28 @@ func _update_item_button(selected: Dictionary) -> void:
if item_button == null:
return
if selected.is_empty():
_set_action_button_blocked(item_button, "Item", "Select Unit", "Select a controllable player unit before using items.")
_set_action_button_blocked(item_button, "Supply", "Mark Banner", "Mark a controllable banner before using supplies.")
return
if bool(selected.get("acted", false)):
_set_action_button_blocked(item_button, "Item", "Done", "This unit has already acted.")
_set_action_button_blocked(item_button, "Supply", "Sealed", "This banner has already acted.")
return
var phase_block := _action_phase_block_reason()
if not phase_block.is_empty():
_set_action_button_blocked(item_button, "Item", str(phase_block.get("label", "Busy")), str(phase_block.get("tooltip", "")))
_set_action_button_blocked(item_button, "Supply", str(phase_block.get("label", "Resolving")), str(phase_block.get("tooltip", "")))
return
var item_ids := state.get_usable_item_ids()
if item_ids.is_empty():
_set_action_button_blocked(item_button, "Item", "None", "No consumable items are available.")
_set_action_button_blocked(item_button, "Supply", "Empty", "No field supplies are available.")
return
if not selected_item_id.is_empty():
var item := state.get_item_def(selected_item_id)
_set_action_button_state(item_button, "Item: %s" % str(item.get("name", selected_item_id)), false, "Target this item on the map.")
_set_action_button_state(item_button, "Supply: %s" % str(item.get("name", selected_item_id)), false, "Mark this supply on the field.")
elif item_menu != null and item_menu.visible:
_set_action_button_state(item_button, "Close Item", false, "Close the item menu.")
_set_action_button_state(item_button, "Close Supplies", false, "Close the supply menu.")
else:
_set_action_button_state(item_button, "Item", false, "Open items. %d consumable types available." % item_ids.size())
_set_action_button_state(item_button, "Supply", false, "Open field supplies. %d types available." % item_ids.size())
func _show_item_menu(selected: Dictionary) -> void:
@@ -7156,7 +7164,7 @@ func _rebuild_item_menu(selected: Dictionary) -> void:
var item_ids := state.get_usable_item_ids()
if item_ids.is_empty():
var empty_label := Label.new()
empty_label.text = "No items"
empty_label.text = "No supplies"
_apply_label_style(empty_label, UI_PARCHMENT_TEXT)
item_list.add_child(empty_label)
return
@@ -7175,7 +7183,7 @@ func _rebuild_item_menu(selected: Dictionary) -> void:
item_list.add_child(use_button)
var cancel_button := Button.new()
cancel_button.text = "Cancel"
cancel_button.text = "Return"
_apply_button_style(cancel_button)
cancel_button.pressed.connect(_on_item_cancel_pressed)
item_list.add_child(cancel_button)
@@ -7201,7 +7209,7 @@ func _format_item_effect_text(item: Dictionary) -> String:
if str(effect.get("type", "")) == "heal_hp":
parts.append("Heal %d" % int(effect.get("amount", 0)))
elif str(effect.get("type", "")) == "heal_mp":
parts.append("MP %d" % int(effect.get("amount", 0)))
parts.append("Qi %d" % int(effect.get("amount", 0)))
elif str(effect.get("type", "")) == "cure_status":
parts.append("Cure %s" % str(effect.get("status", "status")).replace("_", " ").capitalize())
elif str(effect.get("type", "")) == "cleanse_debuffs":
@@ -7241,23 +7249,23 @@ func _update_equip_button(selected: Dictionary) -> void:
if equip_button == null:
return
if selected.is_empty():
_set_action_button_blocked(equip_button, "Equip", "Select Unit", "Select a controllable player unit before changing equipment.")
_set_action_button_blocked(equip_button, "Arms", "Mark Banner", "Mark a controllable banner before changing arms.")
return
if bool(selected.get("acted", false)):
_set_action_button_blocked(equip_button, "Equip", "Done", "This unit has already acted.")
_set_action_button_blocked(equip_button, "Arms", "Sealed", "This banner has already acted.")
return
if bool(selected.get("moved", false)):
_set_action_button_blocked(equip_button, "Equip", "Moved", "Equipment can only be changed before this unit moves.")
_set_action_button_blocked(equip_button, "Arms", "Marched", "Arms can only be changed before this banner marches.")
return
var phase_block := _action_phase_block_reason()
if not phase_block.is_empty():
_set_action_button_blocked(equip_button, "Equip", str(phase_block.get("label", "Busy")), str(phase_block.get("tooltip", "")))
_set_action_button_blocked(equip_button, "Arms", str(phase_block.get("label", "Resolving")), str(phase_block.get("tooltip", "")))
return
if equip_menu != null and equip_menu.visible:
_set_action_button_state(equip_button, "Close Equip", false, "Close the equipment menu.")
_set_action_button_state(equip_button, "Close Arms", false, "Close the arms ledger.")
else:
_set_action_button_state(equip_button, "Equip", false, "Change weapons, armor, or accessories before moving.")
_set_action_button_state(equip_button, "Arms", false, "Change weapons, armor, or accessories before marching.")
func _show_equip_menu(selected: Dictionary) -> void:
@@ -7281,14 +7289,14 @@ func _rebuild_equip_menu(selected: Dictionary) -> void:
_clear_equip_list()
var equipment_label := Label.new()
equipment_label.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
equipment_label.text = "Equipped: %s" % _format_unit_equipment(selected)
equipment_label.text = "Arms Held: %s" % _format_unit_equipment(selected)
_apply_label_style(equipment_label, UI_PARCHMENT_TEXT)
equip_list.add_child(equipment_label)
var equipped_slots := state.get_equipped_equipment_slots(str(selected["id"]))
if not equipped_slots.is_empty():
var unequip_title := Label.new()
unequip_title.text = "Unequip"
unequip_title.text = "Remove Arms"
_apply_label_style(unequip_title, UI_OLD_BRONZE, 14)
equip_list.add_child(unequip_title)
var equipment := state.get_equipment_snapshot(str(selected["id"]))
@@ -7307,7 +7315,7 @@ func _rebuild_equip_menu(selected: Dictionary) -> void:
var item_ids := state.get_equippable_item_ids(selected["id"])
if item_ids.is_empty():
var empty_label := Label.new()
empty_label.text = "No compatible equipment"
empty_label.text = "No compatible arms"
_apply_label_style(empty_label, UI_PARCHMENT_TEXT)
equip_list.add_child(empty_label)
else:
@@ -7329,7 +7337,7 @@ func _rebuild_equip_menu(selected: Dictionary) -> void:
equip_list.add_child(equip_item_button)
var cancel_button := Button.new()
cancel_button.text = "Cancel"
cancel_button.text = "Return"
_apply_button_style(cancel_button)
cancel_button.pressed.connect(_on_equip_cancel_pressed)
equip_list.add_child(cancel_button)