Add antidote status cure item

This commit is contained in:
2026-06-18 09:43:23 +09:00
parent 1fa7e2afac
commit b8b2626d97
15 changed files with 112 additions and 14 deletions

View File

@@ -776,8 +776,10 @@ func get_item_preview(user_id: String, item_id: String, target_cell: Vector2i) -
var hp_heal_amount := _item_hp_heal_amount(target, item)
var mp_heal_amount := _item_mp_heal_amount(target, item)
var cured_statuses := _item_curable_status_names(target, item)
preview["heal"] = hp_heal_amount
preview["mp_heal"] = mp_heal_amount
preview["cure_statuses"] = cured_statuses
preview["target_hp_after"] = min(int(target.get("max_hp", 1)), int(target.get("hp", 0)) + hp_heal_amount)
preview["target_mp_after"] = min(int(target.get("max_mp", 0)), int(target.get("mp", 0)) + mp_heal_amount)
return preview
@@ -1740,6 +1742,12 @@ func _apply_item_effects(user: Dictionary, target: Dictionary, item: Dictionary)
applied = true
_emit_log("%s recovers %d MP." % [target["name"], restored])
_emit_combat_feedback(target, "+%d MP" % restored, "mp")
elif effect_type == "cure_status":
var cured_statuses := _apply_item_status_cure(target, str(effect.get("status", "")))
if not cured_statuses.is_empty():
applied = true
_emit_log("%s is cured of %s." % [target["name"], _join_strings(cured_statuses, ", ")])
_emit_combat_feedback(target, "CURE", "support")
if not applied:
_emit_log("%s has no effect on %s." % [item.get("name", "Item"), target["name"]])
return applied
@@ -1763,6 +1771,29 @@ func _apply_item_mp_heal(target: Dictionary, amount: int) -> int:
return restored
func _apply_item_status_cure(target: Dictionary, status: String) -> Array:
var cured_statuses := []
if typeof(target.get("status_effects", [])) != TYPE_ARRAY:
return cured_statuses
var normalized_status := status.strip_edges().to_lower()
var kept_effects := []
for effect in _active_status_effects(target):
var effect_status := str(effect.get("status", "")).strip_edges().to_lower()
var effect_type := str(effect.get("type", ""))
var should_cure := (
effect_type == "damage_over_time"
and (normalized_status.is_empty() or effect_status == normalized_status)
)
if should_cure:
var display_name := _status_display_name(str(effect.get("status", normalized_status)))
if not cured_statuses.has(display_name):
cured_statuses.append(display_name)
continue
kept_effects.append(effect)
target["status_effects"] = kept_effects
return cured_statuses
func _item_hp_heal_amount(target: Dictionary, item: Dictionary) -> int:
var total := 0
for effect in item.get("effects", []):
@@ -1785,6 +1816,28 @@ func _item_mp_heal_amount(target: Dictionary, item: Dictionary) -> int:
return max(0, min(total, missing_mp))
func _item_curable_status_names(target: Dictionary, item: Dictionary) -> Array:
var result := []
if target.is_empty():
return result
for effect in item.get("effects", []):
if typeof(effect) != TYPE_DICTIONARY:
continue
if str(effect.get("type", "")) != "cure_status":
continue
var status := str(effect.get("status", "")).strip_edges().to_lower()
for active_effect in _active_status_effects(target):
if str(active_effect.get("type", "")) != "damage_over_time":
continue
var active_status := str(active_effect.get("status", "")).strip_edges().to_lower()
if not status.is_empty() and active_status != status:
continue
var display_name := _status_display_name(str(active_effect.get("status", status)))
if not result.has(display_name):
result.append(display_name)
return result
func _equipment_slot_for_item(item: Dictionary) -> String:
var kind := str(item.get("kind", ""))
if kind == "weapon" or kind == "armor" or kind == "accessory":

View File

@@ -1161,8 +1161,11 @@ func _item_target_preview_badge(selected: Dictionary, target: Dictionary) -> Dic
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")
var cure_statuses: Array = preview.get("cure_statuses", [])
if hp_heal <= 0 and mp_heal <= 0 and cure_statuses.is_empty():
return _make_target_preview_badge("NO FX", "invalid")
if not cure_statuses.is_empty():
return _make_target_preview_badge("CURE", "support")
if hp_heal > 0 and mp_heal > 0:
return _make_target_preview_badge("+%d/%d" % [hp_heal, mp_heal], "heal")
if hp_heal > 0:
@@ -1474,8 +1477,9 @@ func _update_item_forecast(selected: Dictionary) -> void:
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:
forecast_label.text = "%s: %s, %s\nNo recovery needed." % [
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." % [
preview["item_name"],
range_text,
count_text
@@ -1495,6 +1499,8 @@ func _update_item_forecast(selected: Dictionary) -> void:
preview["target_mp_after"],
target.get("max_mp", 0)
])
if not cure_statuses.is_empty():
recovery_parts.append("Cure %s" % _join_strings(cure_statuses, ", "))
forecast_label.text = "%s: %s, %s\n%s." % [
preview["item_name"],
@@ -3389,6 +3395,8 @@ func _format_item_effect_text(item: Dictionary) -> String:
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)))
elif str(effect.get("type", "")) == "cure_status":
parts.append("Cure %s" % str(effect.get("status", "status")).replace("_", " ").capitalize())
if parts.is_empty():
return str(item.get("kind", "item")).capitalize()
return _join_strings(parts, ", ")