diff --git a/src/game/engine/scenes/world_map/world_map_combat.gd b/src/game/engine/scenes/world_map/world_map_combat.gd index 328dfb07..27233c2f 100644 --- a/src/game/engine/scenes/world_map/world_map_combat.gd +++ b/src/game/engine/scenes/world_map/world_map_combat.gd @@ -13,13 +13,20 @@ const CombatResultScene: PackedScene = preload( const PromotionPickerScene: PackedScene = preload( "res://engine/scenes/combat/promotion_picker.tscn" ) +const LairModePickerScene: PackedScene = preload( + "res://engine/scenes/combat/lair_mode_picker.tscn" +) var _combat_preview: CanvasLayer = null var _combat_result: CanvasLayer = null var _promotion_picker: CanvasLayer = null +var _lair_mode_picker: CanvasLayer = null var _pending_attacker: RefCounted = null var _pending_defender: RefCounted = null +## Lair engagement awaiting a mode choice from the picker. +var _pending_lair: Dictionary = {} + func setup(parent: Node) -> void: _combat_preview = CombatPreviewScene.instantiate() @@ -31,11 +38,16 @@ func setup(parent: Node) -> void: _promotion_picker = PromotionPickerScene.instantiate() parent.add_child(_promotion_picker) + _lair_mode_picker = LairModePickerScene.instantiate() + parent.add_child(_lair_mode_picker) + EventBus.combat_resolved.connect(_on_combat_resolved) _combat_result.result_dismissed.connect(_on_result_dismissed) _combat_result.promotion_requested.connect(_on_promotion_requested) _promotion_picker.promotion_chosen.connect(_on_promotion_chosen) _promotion_picker.promotion_cancelled.connect(_on_promotion_cancelled) + _lair_mode_picker.mode_chosen.connect(_on_lair_mode_chosen) + _lair_mode_picker.cancelled.connect(_on_lair_mode_cancelled) func get_lair_at(axial: Vector2i) -> Dictionary: @@ -99,14 +111,59 @@ func initiate_lair_combat( lair_diet: String, lair_name: String, ) -> void: - ## Show combat preview for attacker vs a lair creature at lair_pos. - ## Uses GdCombatResolver.wild_stats() for the defender. + ## Open the Assault / Raid / Siege mode picker for a lair engagement (p3-10a). + ## The chosen mode routes through _on_lair_mode_chosen; Assault proceeds to + ## the p0-17 lair-clear flow (the existing assault path). Raid/Siege are shown + ## disabled by the picker until p3-10c/p3-10b land their dispatcher branches. + _pending_lair = { + "attacker": attacker, + "pos": lair_pos, + "tier": lair_tier, + "size": lair_size, + "diet": lair_diet, + "name": lair_name, + } + if _lair_mode_picker == null: + ## No picker wired (e.g. headless unit context) — fall back to direct + ## assault so the p0-17 clear path is never regressed. + _begin_lair_assault(_pending_lair) + _pending_lair = {} + return + _lair_mode_picker.show_picker(lair_name) + + +func _on_lair_mode_chosen(mode: String) -> void: + var lair: Dictionary = _pending_lair + _pending_lair = {} + if lair.is_empty(): + return + ## Only Assault is wired in Game-1 (Raid/Siege are disabled in the picker). + if mode == _lair_mode_picker.MODE_ASSAULT: + _begin_lair_assault(lair) + + +func _on_lair_mode_cancelled() -> void: + ## Player backed out of the engagement; the stack stays where it is. + _pending_lair = {} + + +func _begin_lair_assault(lair: Dictionary) -> void: + ## Show the combat preview for the attacker vs the lair creature. + ## Uses GdCombatResolver.wild_stats() for the defender (inside the preview). + var attacker: RefCounted = lair.get("attacker") + if attacker == null: + return _pending_attacker = attacker _pending_defender = null var game_map: RefCounted = GameState.get_game_map() var all_units: Array = _collect_all_units() _combat_preview.show_lair_preview( - attacker, lair_pos, lair_tier, lair_size, lair_diet, lair_name, + attacker, + lair.get("pos", Vector2i.ZERO), + int(lair.get("tier", 4)), + str(lair.get("size", "medium")), + str(lair.get("diet", "carnivore")), + str(lair.get("name", "Lair Creature")), game_map, all_units )