Files
gd-playground/Game/Runtime/Handlers/PlayCardFlowHandler.gd
54shitaimzf e465f1cbb0 feat: 基础卡牌场景与卡牌逻辑可扩展框架,以及todo文档
- Added BattleState class to manage battle flow, including turn management and event handling.
- Introduced BuffInstance class to represent buffs applied to combatants.
- Created CardInstance class to handle card definitions and cost calculations.
- Developed CombatantState class to manage combatant attributes and actions.
- Implemented EffectRegistry to apply effects based on event specifications.
- Added various handlers (BlockHandler, DamageHandler, DrawHandler, etc.) to process specific events.
- Created IntentPlanner and IntentState classes to manage enemy actions and intents.
- Established a queue system for handling battle events with BattleEventQueue and BattleEventTask.
- Introduced triggers for applying effects based on game events (e.g., OnCardDrawnGainBlockTrigger).
- Added necessary UID files for new scripts to ensure proper resource management.
2026-04-22 21:58:15 +08:00

72 lines
2.1 KiB
GDScript

class_name PlayCardFlowHandler
extends RefCounted
const BattlePhaseScript = preload("res://Game/Runtime/BattlePhase.gd")
const BattleEventTypeScript = preload("res://Game/Runtime/Queue/BattleEventType.gd")
func handle(task, state) -> Array:
if not state.is_player_turn:
return []
if state.phase != BattlePhaseScript.PLAYER_PLAY:
return []
var hand_index: int = int(task.payload.get("hand_index", -1))
var target_side: String = str(task.payload.get("target_side", "enemy"))
var effect_registry = task.payload.get("effect_registry", null)
if hand_index < 0 or hand_index >= state.hand.size():
return []
var card_instance = state.hand[hand_index]
if card_instance == null or card_instance.card_def == null:
return []
var cost: int = card_instance.get_cost()
if cost > state.energy:
state.event_bus.publish("card_play_rejected", {
"reason": "energy_not_enough",
"card_name": card_instance.card_def.name_text
})
return []
if not _is_target_valid(card_instance.card_def.targeting, target_side):
state.event_bus.publish("card_play_rejected", {
"reason": "invalid_target",
"card_name": card_instance.card_def.name_text
})
return []
state.energy -= cost
state.hand.remove_at(hand_index)
state.discard_pile.append(card_instance)
var source = state.player
var target = state.enemy if target_side == "enemy" else state.player
if effect_registry != null:
effect_registry.apply_specs(card_instance.card_def.on_play_effects, state, source, target)
state.event_bus.publish("card_played", {
"card_name": card_instance.card_def.name_text,
"target": target_side,
"cost": cost
})
state.event_bus.publish(BattleEventTypeScript.CARD_PLAY_RESOLVED, {
"card_id": card_instance.card_def.id,
"target": target_side
})
return []
func _is_target_valid(targeting: int, target_side: String) -> bool:
match targeting:
ECardTargeting.NONE:
return true
ECardTargeting.SELF:
return target_side == "self"
ECardTargeting.SINGLE_ENEMY:
return target_side == "enemy"
ECardTargeting.ANY_UNIT:
return target_side == "self" or target_side == "enemy"
_:
return target_side == "enemy"