Add target preview badges
This commit is contained in:
@@ -34,6 +34,7 @@ const UI_SFX_VOLUME_DB := -8.0
|
||||
const FLOATING_TEXT_LIFETIME := 1.0
|
||||
const FLOATING_TEXT_RISE := 42.0
|
||||
const UNIT_MOVE_ANIMATION_DURATION := 0.18
|
||||
const TARGET_PREVIEW_BADGE_SIZE := Vector2(92, 22)
|
||||
|
||||
var state: BattleState = BattleStateScript.new()
|
||||
var campaign_state: CampaignState = CampaignStateScript.new()
|
||||
@@ -159,6 +160,7 @@ func _draw() -> void:
|
||||
_draw_map()
|
||||
_draw_overlays()
|
||||
_draw_units()
|
||||
_draw_target_preview_badge()
|
||||
_draw_floating_texts()
|
||||
|
||||
|
||||
@@ -911,6 +913,150 @@ func _floating_text_color(kind: String) -> Color:
|
||||
return Color.WHITE
|
||||
|
||||
|
||||
func _draw_target_preview_badge() -> void:
|
||||
var badge := _target_preview_badge()
|
||||
if badge.is_empty():
|
||||
return
|
||||
|
||||
var cell: Vector2i = badge.get("cell", hover_cell)
|
||||
if not state.is_inside(cell):
|
||||
return
|
||||
|
||||
var rect := _rect_for_cell(cell)
|
||||
var size := TARGET_PREVIEW_BADGE_SIZE
|
||||
var badge_rect := Rect2(
|
||||
rect.position + Vector2((TILE_SIZE - size.x) * 0.5, 5.0),
|
||||
size
|
||||
)
|
||||
var kind := str(badge.get("kind", ""))
|
||||
var color := _target_preview_badge_color(kind)
|
||||
var background := Color(0.025, 0.028, 0.034, 0.88)
|
||||
var font := ThemeDB.fallback_font
|
||||
var text := str(badge.get("text", ""))
|
||||
|
||||
draw_rect(badge_rect, background)
|
||||
draw_rect(badge_rect, color, false, 2.0)
|
||||
draw_string(font, badge_rect.position + Vector2(0, 16), text, HORIZONTAL_ALIGNMENT_CENTER, badge_rect.size.x, 14, color)
|
||||
|
||||
|
||||
func _target_preview_badge() -> Dictionary:
|
||||
if _is_input_locked() or not state.is_inside(hover_cell):
|
||||
return {}
|
||||
|
||||
var selected := state.get_selected_unit()
|
||||
if selected.is_empty():
|
||||
return {}
|
||||
|
||||
var target := state.get_unit_at(hover_cell)
|
||||
if not selected_skill_id.is_empty():
|
||||
return _skill_target_preview_badge(selected, target)
|
||||
if not selected_item_id.is_empty():
|
||||
return _item_target_preview_badge(selected, target)
|
||||
return _attack_target_preview_badge(selected, target)
|
||||
|
||||
|
||||
func _attack_target_preview_badge(selected: Dictionary, target: Dictionary) -> Dictionary:
|
||||
if target.is_empty() or target.get("team", "") == selected.get("team", ""):
|
||||
return {}
|
||||
|
||||
var preview := state.get_damage_preview(selected["id"], target["id"])
|
||||
if preview.is_empty():
|
||||
return {}
|
||||
|
||||
if not bool(preview.get("in_range", false)):
|
||||
return _make_target_preview_badge("OUT", "invalid")
|
||||
|
||||
var hit_chance := int(preview.get("hit_chance", 100))
|
||||
var result_text := "KO" if bool(preview.get("would_defeat", false)) else "-%d" % int(preview.get("damage", 0))
|
||||
return _make_target_preview_badge("%s %d%%" % [result_text, hit_chance], "damage")
|
||||
|
||||
|
||||
func _skill_target_preview_badge(selected: Dictionary, target: Dictionary) -> Dictionary:
|
||||
var preview := state.get_skill_preview(selected["id"], selected_skill_id, hover_cell)
|
||||
if preview.is_empty() or target.is_empty():
|
||||
return {}
|
||||
|
||||
if not bool(preview.get("valid_target", false)):
|
||||
return _make_target_preview_badge("INVALID", "invalid")
|
||||
if not bool(preview.get("in_range", false)):
|
||||
return _make_target_preview_badge("OUT", "invalid")
|
||||
if not bool(preview.get("has_mp", false)):
|
||||
return _make_target_preview_badge("NO MP", "invalid")
|
||||
|
||||
var kind := str(preview.get("kind", "damage"))
|
||||
if kind == "heal":
|
||||
var heal := int(preview.get("heal", 0))
|
||||
if heal <= 0:
|
||||
return _make_target_preview_badge("FULL", "invalid")
|
||||
return _make_target_preview_badge("+%d HP" % heal, "heal")
|
||||
if kind == "support":
|
||||
return _make_target_preview_badge(_compact_support_preview_text(str(preview.get("effect_text", "Support"))), "support")
|
||||
|
||||
var result_text := "KO" if bool(preview.get("would_defeat", false)) else "-%d" % int(preview.get("damage", 0))
|
||||
return _make_target_preview_badge(result_text, "damage")
|
||||
|
||||
|
||||
func _item_target_preview_badge(selected: Dictionary, target: Dictionary) -> Dictionary:
|
||||
var preview := state.get_item_preview(selected["id"], selected_item_id, hover_cell)
|
||||
if preview.is_empty() or target.is_empty():
|
||||
return {}
|
||||
|
||||
if not bool(preview.get("valid_target", false)):
|
||||
return _make_target_preview_badge("INVALID", "invalid")
|
||||
if not bool(preview.get("in_range", false)):
|
||||
return _make_target_preview_badge("OUT", "invalid")
|
||||
if int(preview.get("count", 0)) <= 0:
|
||||
return _make_target_preview_badge("NONE", "invalid")
|
||||
|
||||
var hp_heal := int(preview.get("heal", 0))
|
||||
var mp_heal := int(preview.get("mp_heal", 0))
|
||||
if hp_heal <= 0 and mp_heal <= 0:
|
||||
return _make_target_preview_badge("FULL", "invalid")
|
||||
if hp_heal > 0 and mp_heal > 0:
|
||||
return _make_target_preview_badge("+%d/%d" % [hp_heal, mp_heal], "heal")
|
||||
if hp_heal > 0:
|
||||
return _make_target_preview_badge("+%d HP" % hp_heal, "heal")
|
||||
return _make_target_preview_badge("+%d MP" % mp_heal, "mp")
|
||||
|
||||
|
||||
func _make_target_preview_badge(text: String, kind: String) -> Dictionary:
|
||||
if text.is_empty():
|
||||
return {}
|
||||
return {
|
||||
"text": text,
|
||||
"kind": kind,
|
||||
"cell": hover_cell
|
||||
}
|
||||
|
||||
|
||||
func _compact_support_preview_text(effect_text: String) -> String:
|
||||
var parts := []
|
||||
for raw_part in effect_text.split(","):
|
||||
var part := raw_part.strip_edges()
|
||||
var until_index := part.find(" until ")
|
||||
if until_index >= 0:
|
||||
part = part.substr(0, until_index)
|
||||
if not part.is_empty() and part != "No support effect.":
|
||||
parts.append(part)
|
||||
if parts.is_empty():
|
||||
return "SUPPORT"
|
||||
if parts.size() > 1:
|
||||
return "%s+" % parts[0]
|
||||
return str(parts[0])
|
||||
|
||||
|
||||
func _target_preview_badge_color(kind: String) -> Color:
|
||||
if kind == "damage":
|
||||
return Color(1.0, 0.38, 0.26)
|
||||
if kind == "heal":
|
||||
return Color(0.44, 1.0, 0.52)
|
||||
if kind == "mp":
|
||||
return Color(0.54, 0.78, 1.0)
|
||||
if kind == "support":
|
||||
return Color(1.0, 0.88, 0.30)
|
||||
return Color(0.78, 0.80, 0.86)
|
||||
|
||||
|
||||
func _cell_from_screen(screen_position: Vector2) -> Vector2i:
|
||||
var local := screen_position - BOARD_OFFSET
|
||||
if local.x < 0 or local.y < 0:
|
||||
|
||||
Reference in New Issue
Block a user