From 71f755e1bf737802d1a02e480c21b7cc3d9e4484 Mon Sep 17 00:00:00 2001 From: Mike McGhen Date: Wed, 11 Mar 2026 15:47:12 -0400 Subject: [PATCH] VS Last changes --- data/body_parts/head_sensor_array.tres | 9 -------- data/body_parts/head_targeting_spike.tres | 10 -------- data/body_parts/head_wide_angle_lens.tres | 10 -------- scripts/enemies/hivemind.gd | 4 ---- scripts/enemies/relay.gd | 1 - scripts/enemies/supervisor.gd | 1 - scripts/enemies/warden.gd | 1 - scripts/event_bus.gd | 1 - scripts/hub/hub.gd | 16 +++++++++---- scripts/player/player_stats.gd | 2 +- scripts/rooms/room.gd | 28 +++++++++++++++++++---- scripts/run_manager.gd | 4 ++++ scripts/ui/mini_map.gd | 10 +++++--- scripts/upgrades/body_part_pickup.gd | 12 ++++++++++ scripts/upgrades/upgrade_manager.gd | 3 +-- 15 files changed, 60 insertions(+), 52 deletions(-) delete mode 100644 data/body_parts/head_sensor_array.tres delete mode 100644 data/body_parts/head_targeting_spike.tres delete mode 100644 data/body_parts/head_wide_angle_lens.tres diff --git a/data/body_parts/head_sensor_array.tres b/data/body_parts/head_sensor_array.tres deleted file mode 100644 index 4ad3c7a..0000000 --- a/data/body_parts/head_sensor_array.tres +++ /dev/null @@ -1,9 +0,0 @@ -[gd_resource type="Resource" script_class="BodyPartData" load_steps=2 format=3] - -[ext_resource type="Script" path="res://scripts/upgrades/body_part_data.gd" id="1"] - -[resource] -script = ExtResource("1") -slot = "head" -display_name = "Sensor Array" -mod_range = 40.0 diff --git a/data/body_parts/head_targeting_spike.tres b/data/body_parts/head_targeting_spike.tres deleted file mode 100644 index 34b0912..0000000 --- a/data/body_parts/head_targeting_spike.tres +++ /dev/null @@ -1,10 +0,0 @@ -[gd_resource type="Resource" script_class="BodyPartData" load_steps=2 format=3] - -[ext_resource type="Script" path="res://scripts/upgrades/body_part_data.gd" id="1"] - -[resource] -script = ExtResource("1") -slot = "head" -display_name = "Targeting Spike" -mod_proj_speed = 208.0 -mod_range = 100.0 \ No newline at end of file diff --git a/data/body_parts/head_wide_angle_lens.tres b/data/body_parts/head_wide_angle_lens.tres deleted file mode 100644 index fb964bb..0000000 --- a/data/body_parts/head_wide_angle_lens.tres +++ /dev/null @@ -1,10 +0,0 @@ -[gd_resource type="Resource" script_class="BodyPartData" load_steps=2 format=3] - -[ext_resource type="Script" path="res://scripts/upgrades/body_part_data.gd" id="1"] - -[resource] -script = ExtResource("1") -slot = "head" -display_name = "Wide-Angle Lens" -mod_range = 120.0 -mod_proj_speed = -104.0 \ No newline at end of file diff --git a/scripts/enemies/hivemind.gd b/scripts/enemies/hivemind.gd index d9bcd0b..d10d6c5 100644 --- a/scripts/enemies/hivemind.gd +++ b/scripts/enemies/hivemind.gd @@ -334,9 +334,6 @@ func _enter_active() -> void: # Spawn 6 static orbiting projectiles _spawn_orbiters() - # Emit boss health bar start - EventBus.boss_health_changed.emit(current_health, max_health, "THE HIVEMIND") - # --------------------------------------------------------------------------- # Phase 2 — Active (teleport + orbiters + sweep) @@ -864,7 +861,6 @@ func take_damage(amount: float) -> void: current_health -= amount _flash_timer = 0.1 AudioManager.play("enemy_hit") - EventBus.boss_health_changed.emit(maxf(current_health, 0.0), max_health, "THE HIVEMIND") if current_health <= 0.0: _enter_climax() diff --git a/scripts/enemies/relay.gd b/scripts/enemies/relay.gd index 3b158f8..c01beb8 100644 --- a/scripts/enemies/relay.gd +++ b/scripts/enemies/relay.gd @@ -370,7 +370,6 @@ func take_damage(amount: float) -> void: current_health -= amount AudioManager.play("enemy_hit") - EventBus.boss_health_changed.emit(current_health, max_health, "THE RELAY") if current_health <= 5.0 and _phase != Phase.CLIMAX: _enter_climax() diff --git a/scripts/enemies/supervisor.gd b/scripts/enemies/supervisor.gd index 94899fc..90c1e1e 100644 --- a/scripts/enemies/supervisor.gd +++ b/scripts/enemies/supervisor.gd @@ -320,7 +320,6 @@ func take_damage(amount: float) -> void: return # already dying current_health -= amount _flash_timer = 0.1 - EventBus.boss_health_changed.emit(maxf(current_health, 0.0), max_health, "THE SUPERVISOR") if current_health <= 0.0: _enter_climax() diff --git a/scripts/enemies/warden.gd b/scripts/enemies/warden.gd index 6042027..edfe308 100644 --- a/scripts/enemies/warden.gd +++ b/scripts/enemies/warden.gd @@ -371,7 +371,6 @@ func take_damage(amount: float) -> void: current_health -= amount _flash_timer = 0.1 AudioManager.play("enemy_hit") - EventBus.boss_health_changed.emit(maxf(current_health, 0.0), max_health, "THE WARDEN") if current_health <= 0.0: _enter_climax() diff --git a/scripts/event_bus.gd b/scripts/event_bus.gd index 9f57bab..c3e948e 100644 --- a/scripts/event_bus.gd +++ b/scripts/event_bus.gd @@ -66,7 +66,6 @@ signal card_game_ended(player_won: bool) # --------------------------------------------------------------------------- # Boss # --------------------------------------------------------------------------- -signal boss_health_changed(current: float, maximum: float, boss_name: String) signal boss_died # --------------------------------------------------------------------------- diff --git a/scripts/hub/hub.gd b/scripts/hub/hub.gd index 42a8b76..386b076 100644 --- a/scripts/hub/hub.gd +++ b/scripts/hub/hub.gd @@ -72,11 +72,19 @@ func _build_hub() -> void: room_node.setup(room_type, conn, self) _rooms[grid_pos] = room_node - # Start in Staging Area; player spawns below center so the portal is visible + # Start in Staging Area var staging_world := _grid_to_world(Vector2i(0, 0)) - camera.position = staging_world - player.global_position = staging_world + Vector2(0, 80) - _current_grid = Vector2i(0, 0) + camera.position = staging_world + _current_grid = Vector2i(0, 0) + + # Spawn position depends on whether returning from a run + if RunManager.returning_from_run: + # Spawn at the run portal door (portal is at y=-150, spawn just below it) + player.global_position = staging_world + Vector2(0, -100) + RunManager.returning_from_run = false + else: + # Default spawn below center so the portal is visible + player.global_position = staging_world + Vector2(0, 80) func _compute_connections() -> Dictionary: diff --git a/scripts/player/player_stats.gd b/scripts/player/player_stats.gd index acbd196..394a9aa 100644 --- a/scripts/player/player_stats.gd +++ b/scripts/player/player_stats.gd @@ -158,7 +158,7 @@ func _apply_run_items() -> void: fragmented_map = true RunItem.Effect.OVERCLOCK: overclock = true - fire_rate *= 1.6 + fire_rate *= 1.4 func _apply_part_flags() -> void: shield_projector = false diff --git a/scripts/rooms/room.gd b/scripts/rooms/room.gd index 2b0feb8..103aa9f 100644 --- a/scripts/rooms/room.gd +++ b/scripts/rooms/room.gd @@ -28,8 +28,6 @@ const SHOP_PEDESTAL_SCR = preload("res://scripts/items/shop_item_pedestal.gd") const STATION_DOOR_SCR = preload("res://scripts/rooms/station_door.gd") const ALL_PART_PATHS: Array[String] = [ - "res://data/body_parts/head_wide_angle_lens.tres", - "res://data/body_parts/head_targeting_spike.tres", "res://data/body_parts/torso_reinforced_chassis.tres", "res://data/body_parts/torso_lightweight_frame.tres", "res://data/body_parts/left_arm_scatter_emitter.tres", @@ -47,6 +45,8 @@ const ALL_ITEM_PATHS: Array[String] = [ "res://data/run_items/static_discharge.tres", "res://data/run_items/fragmented_map.tres", "res://data/run_items/patch_kit.tres", + "res://data/run_items/plating_shard.tres", + "res://data/run_items/range_booster.tres", ] # --------------------------------------------------------------------------- @@ -380,6 +380,10 @@ func _spawn_entry_door() -> void: func _spawn_body_part_drop() -> void: + # 50% drop chance so body parts feel more valuable + if randf() > 0.5: + return + # Drop a random part the player hasn't yet acquired var unacquired: Array[String] = [] for path in ALL_PART_PATHS: @@ -518,10 +522,24 @@ func _make_exposed_wiring() -> void: poly.color = Color(1.0, 0.85, 0.05, 0.90) area.add_child(poly) - # Damage on contact — player iframes act as natural cooldown + # Continuous damage while overlapping — timer ticks damage, player iframes limit actual hits + var overlapping_players: Array[Node] = [] + var damage_timer := Timer.new() + damage_timer.wait_time = 0.3 + damage_timer.autostart = true + damage_timer.timeout.connect(func() -> void: + for b in overlapping_players: + if is_instance_valid(b) and b.has_method("take_damage"): + b.take_damage(1.0)) + area.add_child(damage_timer) + area.body_entered.connect(func(b: Node) -> void: - if b.is_in_group("player") and b.has_method("take_damage"): - b.take_damage(1.0)) + if b.is_in_group("player"): + overlapping_players.append(b) + if b.has_method("take_damage"): + b.take_damage(1.0)) + area.body_exited.connect(func(b: Node) -> void: + overlapping_players.erase(b)) contents.add_child(area) diff --git a/scripts/run_manager.gd b/scripts/run_manager.gd index 777fc56..c5253b0 100644 --- a/scripts/run_manager.gd +++ b/scripts/run_manager.gd @@ -22,6 +22,9 @@ var npc_ids_on_run: Array[String] = [] # --- Floor-to-floor carry (not saved, only lives for one scene reload) --- var player_health_carry: float = -1.0 # -1 = no carry, use default full health +# --- Hub spawn flag (cleared after hub reads it) --- +var returning_from_run: bool = false + func start_run(brought_credits: int, brought_buffs: Array[Resource], brought_npc_ids: Array[String]) -> void: current_floor = 1 current_room_id = "" @@ -38,6 +41,7 @@ func start_run(brought_credits: int, brought_buffs: Array[Resource], brought_npc func end_run(player_survived: bool) -> void: run_active = false + returning_from_run = true if player_survived: _apply_run_rewards() else: diff --git a/scripts/ui/mini_map.gd b/scripts/ui/mini_map.gd index 7ccedc7..cfbeaea 100644 --- a/scripts/ui/mini_map.gd +++ b/scripts/ui/mini_map.gd @@ -26,6 +26,7 @@ const ROOM_COLORS := { } const CURRENT_OUTLINE := Color(1.0, 1.0, 0.4) # bright yellow const CONNECTION_COLOR := Color(0.5, 0.5, 0.6) +const UNVISITED_COLOR := Color(0.3, 0.3, 0.35) # generic grey for fog of war const UNVISITED_ALPHA := 0.35 const BACKGROUND_COLOR := Color(0.08, 0.08, 0.10, 0.85) @@ -193,9 +194,12 @@ func _draw() -> void: var map_pos := _grid_to_map_pos(pos) var rect := Rect2(map_pos, ROOM_SIZE) - # Room color with alpha based on visited state - var color: Color = ROOM_COLORS.get(room.type, ROOM_COLORS[RoomData.RoomType.COMBAT]) - if not is_visited: + # Fog of war: unvisited rooms show as generic grey (hide type info) + var color: Color + if is_visited: + color = ROOM_COLORS.get(room.type, ROOM_COLORS[RoomData.RoomType.COMBAT]) + else: + color = UNVISITED_COLOR color.a = UNVISITED_ALPHA draw_rect(rect, color) diff --git a/scripts/upgrades/body_part_pickup.gd b/scripts/upgrades/body_part_pickup.gd index 4255bda..7598bc9 100644 --- a/scripts/upgrades/body_part_pickup.gd +++ b/scripts/upgrades/body_part_pickup.gd @@ -9,4 +9,16 @@ func _on_body_entered(body: Node) -> void: if body.is_in_group("player") and part != null: AudioManager.play("item_pickup") UpgradeManager.acquire_part(part) + _show_pickup_label() queue_free() + +func _show_pickup_label() -> void: + var lbl := Label.new() + lbl.text = part.display_name + lbl.position = global_position + Vector2(-40, -20) + lbl.modulate = Color(1.0, 0.85, 0.3) # gold for body parts + get_tree().current_scene.add_child(lbl) + var tween := lbl.create_tween() + tween.tween_property(lbl, "position", lbl.position + Vector2(0, -60), 1.2) + tween.parallel().tween_property(lbl, "modulate:a", 0.0, 1.2) + tween.tween_callback(lbl.queue_free) diff --git a/scripts/upgrades/upgrade_manager.gd b/scripts/upgrades/upgrade_manager.gd index dba66ca..0a1929a 100644 --- a/scripts/upgrades/upgrade_manager.gd +++ b/scripts/upgrades/upgrade_manager.gd @@ -1,6 +1,6 @@ extends Node -const SLOTS: Array[String] = ["head", "torso", "left_arm", "right_arm", "legs"] +const SLOTS: Array[String] = ["torso", "left_arm", "right_arm", "legs"] var hub_credits: int = 0 # safe bank — survives death, stored in deposit machine var wallet_credits: int = 0 # on-hand scrap — carried by player, shown on HUD @@ -11,7 +11,6 @@ func change_wallet(delta: int) -> void: # slot -> BodyPart resource path (empty string = default/base part) var equipped_parts: Dictionary = { - "head": "", "torso": "", "left_arm": "", "right_arm": "",