updates for cleaning functionality
This commit is contained in:
193
scripts/game/UndoSystem.gd
Normal file
193
scripts/game/UndoSystem.gd
Normal file
@@ -0,0 +1,193 @@
|
||||
class_name UndoSystem
|
||||
extends RefCounted
|
||||
|
||||
## UndoSystem - Tracks the last action for undo capability
|
||||
|
||||
signal undo_available_changed(available: bool)
|
||||
signal action_undone(action_name: String)
|
||||
|
||||
# Action types that can be undone
|
||||
enum ActionType {
|
||||
NONE,
|
||||
DISCARD_FOR_CP,
|
||||
DULL_BACKUP_FOR_CP,
|
||||
PLAY_CARD
|
||||
}
|
||||
|
||||
# Stored action data for undo
|
||||
class UndoAction:
|
||||
var type: ActionType = ActionType.NONE
|
||||
var player_index: int = -1
|
||||
var card: CardInstance = null
|
||||
var description: String = ""
|
||||
# Additional data depending on action type
|
||||
var cp_element: Enums.Element = Enums.Element.FIRE
|
||||
var cp_amount: int = 0
|
||||
var previous_card_state: Enums.CardState = Enums.CardState.ACTIVE
|
||||
var from_zone: Enums.ZoneType = Enums.ZoneType.HAND
|
||||
var to_zone: Enums.ZoneType = Enums.ZoneType.FIELD_FORWARDS
|
||||
|
||||
var last_action: UndoAction = null
|
||||
var game_state: GameState = null
|
||||
|
||||
func _init(state: GameState = null) -> void:
|
||||
game_state = state
|
||||
|
||||
## Set the game state reference
|
||||
func set_game_state(state: GameState) -> void:
|
||||
game_state = state
|
||||
|
||||
## Check if undo is available
|
||||
func can_undo() -> bool:
|
||||
return last_action != null and last_action.type != ActionType.NONE
|
||||
|
||||
## Record a discard for CP action
|
||||
func record_discard_for_cp(player_index: int, card: CardInstance, element: Enums.Element) -> void:
|
||||
var action = UndoAction.new()
|
||||
action.type = ActionType.DISCARD_FOR_CP
|
||||
action.player_index = player_index
|
||||
action.card = card
|
||||
action.cp_element = element
|
||||
action.cp_amount = 2
|
||||
action.description = "Discard " + card.get_display_name() + " for CP"
|
||||
|
||||
last_action = action
|
||||
undo_available_changed.emit(true)
|
||||
|
||||
## Record a dull backup for CP action
|
||||
func record_dull_backup_for_cp(player_index: int, card: CardInstance, element: Enums.Element) -> void:
|
||||
var action = UndoAction.new()
|
||||
action.type = ActionType.DULL_BACKUP_FOR_CP
|
||||
action.player_index = player_index
|
||||
action.card = card
|
||||
action.cp_element = element
|
||||
action.cp_amount = 1
|
||||
action.previous_card_state = Enums.CardState.ACTIVE # Was active before dulling
|
||||
action.description = "Dull " + card.get_display_name() + " for CP"
|
||||
|
||||
last_action = action
|
||||
undo_available_changed.emit(true)
|
||||
|
||||
## Record playing a card
|
||||
func record_play_card(player_index: int, card: CardInstance, to_zone: Enums.ZoneType, _cp_spent: Dictionary) -> void:
|
||||
var action = UndoAction.new()
|
||||
action.type = ActionType.PLAY_CARD
|
||||
action.player_index = player_index
|
||||
action.card = card
|
||||
action.from_zone = Enums.ZoneType.HAND
|
||||
action.to_zone = to_zone
|
||||
action.description = "Play " + card.get_display_name()
|
||||
|
||||
last_action = action
|
||||
undo_available_changed.emit(true)
|
||||
|
||||
## Clear the undo history (called when phase changes, combat happens, etc.)
|
||||
func clear_history() -> void:
|
||||
last_action = null
|
||||
undo_available_changed.emit(false)
|
||||
|
||||
## Execute undo of the last action
|
||||
func undo() -> bool:
|
||||
if not can_undo() or not game_state:
|
||||
return false
|
||||
|
||||
var action = last_action
|
||||
var success = false
|
||||
|
||||
match action.type:
|
||||
ActionType.DISCARD_FOR_CP:
|
||||
success = _undo_discard_for_cp(action)
|
||||
ActionType.DULL_BACKUP_FOR_CP:
|
||||
success = _undo_dull_backup_for_cp(action)
|
||||
ActionType.PLAY_CARD:
|
||||
success = _undo_play_card(action)
|
||||
|
||||
if success:
|
||||
var description = action.description
|
||||
last_action = null
|
||||
undo_available_changed.emit(false)
|
||||
action_undone.emit(description)
|
||||
|
||||
return success
|
||||
|
||||
## Undo a discard for CP action
|
||||
func _undo_discard_for_cp(action: UndoAction) -> bool:
|
||||
var player = game_state.get_player(action.player_index)
|
||||
if not player:
|
||||
return false
|
||||
|
||||
# Remove card from break zone
|
||||
if not player.break_zone.has_card(action.card):
|
||||
return false
|
||||
|
||||
player.break_zone.remove_card(action.card)
|
||||
|
||||
# Add card back to hand
|
||||
player.hand.add_card(action.card)
|
||||
|
||||
# Remove the CP that was generated
|
||||
player.cp_pool.add_cp(action.cp_element, -action.cp_amount)
|
||||
|
||||
return true
|
||||
|
||||
## Undo a dull backup for CP action
|
||||
func _undo_dull_backup_for_cp(action: UndoAction) -> bool:
|
||||
var player = game_state.get_player(action.player_index)
|
||||
if not player:
|
||||
return false
|
||||
|
||||
# Check card is still on field
|
||||
if not player.field_backups.has_card(action.card):
|
||||
return false
|
||||
|
||||
# Reactivate the backup
|
||||
action.card.activate()
|
||||
|
||||
# Remove the CP that was generated
|
||||
player.cp_pool.add_cp(action.cp_element, -action.cp_amount)
|
||||
|
||||
return true
|
||||
|
||||
## Undo playing a card
|
||||
func _undo_play_card(action: UndoAction) -> bool:
|
||||
var player = game_state.get_player(action.player_index)
|
||||
if not player:
|
||||
return false
|
||||
|
||||
var card = action.card
|
||||
|
||||
# Remove from field
|
||||
var removed = false
|
||||
if action.to_zone == Enums.ZoneType.FIELD_FORWARDS:
|
||||
if player.field_forwards.has_card(card):
|
||||
player.field_forwards.remove_card(card)
|
||||
removed = true
|
||||
elif action.to_zone == Enums.ZoneType.FIELD_BACKUPS:
|
||||
if player.field_backups.has_card(card):
|
||||
player.field_backups.remove_card(card)
|
||||
removed = true
|
||||
|
||||
if not removed:
|
||||
return false
|
||||
|
||||
# Return to hand
|
||||
player.hand.add_card(card)
|
||||
|
||||
# Reset card state
|
||||
card.state = Enums.CardState.ACTIVE
|
||||
card.turns_on_field = 0
|
||||
|
||||
# Refund the CP (we don't track exact CP spent, so this is simplified)
|
||||
# In a full implementation, we'd track what CP was spent
|
||||
# For now, we'll add back CP equal to the card cost
|
||||
var cost = card.card_data.cost
|
||||
var element = card.get_element()
|
||||
player.cp_pool.add_cp(element, cost)
|
||||
|
||||
return true
|
||||
|
||||
## Get description of the last action (for display)
|
||||
func get_last_action_description() -> String:
|
||||
if not can_undo():
|
||||
return ""
|
||||
return last_action.description
|
||||
Reference in New Issue
Block a user