VS Last changes

This commit is contained in:
2026-03-11 15:47:12 -04:00
parent 75403e7c1d
commit 71f755e1bf
15 changed files with 60 additions and 52 deletions
-9
View File
@@ -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
-10
View File
@@ -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
-10
View File
@@ -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
-4
View File
@@ -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()
-1
View File
@@ -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()
-1
View File
@@ -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()
-1
View File
@@ -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()
-1
View File
@@ -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
# ---------------------------------------------------------------------------
+10 -2
View File
@@ -72,12 +72,20 @@ 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)
# 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:
var grid := {}
+1 -1
View File
@@ -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
+23 -5
View File
@@ -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
area.body_entered.connect(func(b: Node) -> void:
if b.is_in_group("player") and b.has_method("take_damage"):
# 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"):
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)
+4
View File
@@ -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:
+7 -3
View File
@@ -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)
+12
View File
@@ -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)
+1 -2
View File
@@ -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": "",