VS Last changes
This commit is contained in:
@@ -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
|
|
||||||
@@ -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
|
|
||||||
@@ -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
|
|
||||||
@@ -334,9 +334,6 @@ func _enter_active() -> void:
|
|||||||
# Spawn 6 static orbiting projectiles
|
# Spawn 6 static orbiting projectiles
|
||||||
_spawn_orbiters()
|
_spawn_orbiters()
|
||||||
|
|
||||||
# Emit boss health bar start
|
|
||||||
EventBus.boss_health_changed.emit(current_health, max_health, "THE HIVEMIND")
|
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# Phase 2 — Active (teleport + orbiters + sweep)
|
# Phase 2 — Active (teleport + orbiters + sweep)
|
||||||
@@ -864,7 +861,6 @@ func take_damage(amount: float) -> void:
|
|||||||
current_health -= amount
|
current_health -= amount
|
||||||
_flash_timer = 0.1
|
_flash_timer = 0.1
|
||||||
AudioManager.play("enemy_hit")
|
AudioManager.play("enemy_hit")
|
||||||
EventBus.boss_health_changed.emit(maxf(current_health, 0.0), max_health, "THE HIVEMIND")
|
|
||||||
|
|
||||||
if current_health <= 0.0:
|
if current_health <= 0.0:
|
||||||
_enter_climax()
|
_enter_climax()
|
||||||
|
|||||||
@@ -370,7 +370,6 @@ func take_damage(amount: float) -> void:
|
|||||||
|
|
||||||
current_health -= amount
|
current_health -= amount
|
||||||
AudioManager.play("enemy_hit")
|
AudioManager.play("enemy_hit")
|
||||||
EventBus.boss_health_changed.emit(current_health, max_health, "THE RELAY")
|
|
||||||
|
|
||||||
if current_health <= 5.0 and _phase != Phase.CLIMAX:
|
if current_health <= 5.0 and _phase != Phase.CLIMAX:
|
||||||
_enter_climax()
|
_enter_climax()
|
||||||
|
|||||||
@@ -320,7 +320,6 @@ func take_damage(amount: float) -> void:
|
|||||||
return # already dying
|
return # already dying
|
||||||
current_health -= amount
|
current_health -= amount
|
||||||
_flash_timer = 0.1
|
_flash_timer = 0.1
|
||||||
EventBus.boss_health_changed.emit(maxf(current_health, 0.0), max_health, "THE SUPERVISOR")
|
|
||||||
if current_health <= 0.0:
|
if current_health <= 0.0:
|
||||||
_enter_climax()
|
_enter_climax()
|
||||||
|
|
||||||
|
|||||||
@@ -371,7 +371,6 @@ func take_damage(amount: float) -> void:
|
|||||||
current_health -= amount
|
current_health -= amount
|
||||||
_flash_timer = 0.1
|
_flash_timer = 0.1
|
||||||
AudioManager.play("enemy_hit")
|
AudioManager.play("enemy_hit")
|
||||||
EventBus.boss_health_changed.emit(maxf(current_health, 0.0), max_health, "THE WARDEN")
|
|
||||||
if current_health <= 0.0:
|
if current_health <= 0.0:
|
||||||
_enter_climax()
|
_enter_climax()
|
||||||
|
|
||||||
|
|||||||
@@ -66,7 +66,6 @@ signal card_game_ended(player_won: bool)
|
|||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# Boss
|
# Boss
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
signal boss_health_changed(current: float, maximum: float, boss_name: String)
|
|
||||||
signal boss_died
|
signal boss_died
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|||||||
+12
-4
@@ -72,11 +72,19 @@ func _build_hub() -> void:
|
|||||||
room_node.setup(room_type, conn, self)
|
room_node.setup(room_type, conn, self)
|
||||||
_rooms[grid_pos] = room_node
|
_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))
|
var staging_world := _grid_to_world(Vector2i(0, 0))
|
||||||
camera.position = staging_world
|
camera.position = staging_world
|
||||||
player.global_position = staging_world + Vector2(0, 80)
|
_current_grid = Vector2i(0, 0)
|
||||||
_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:
|
func _compute_connections() -> Dictionary:
|
||||||
|
|||||||
@@ -158,7 +158,7 @@ func _apply_run_items() -> void:
|
|||||||
fragmented_map = true
|
fragmented_map = true
|
||||||
RunItem.Effect.OVERCLOCK:
|
RunItem.Effect.OVERCLOCK:
|
||||||
overclock = true
|
overclock = true
|
||||||
fire_rate *= 1.6
|
fire_rate *= 1.4
|
||||||
|
|
||||||
func _apply_part_flags() -> void:
|
func _apply_part_flags() -> void:
|
||||||
shield_projector = false
|
shield_projector = false
|
||||||
|
|||||||
+23
-5
@@ -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 STATION_DOOR_SCR = preload("res://scripts/rooms/station_door.gd")
|
||||||
|
|
||||||
const ALL_PART_PATHS: Array[String] = [
|
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_reinforced_chassis.tres",
|
||||||
"res://data/body_parts/torso_lightweight_frame.tres",
|
"res://data/body_parts/torso_lightweight_frame.tres",
|
||||||
"res://data/body_parts/left_arm_scatter_emitter.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/static_discharge.tres",
|
||||||
"res://data/run_items/fragmented_map.tres",
|
"res://data/run_items/fragmented_map.tres",
|
||||||
"res://data/run_items/patch_kit.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:
|
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
|
# Drop a random part the player hasn't yet acquired
|
||||||
var unacquired: Array[String] = []
|
var unacquired: Array[String] = []
|
||||||
for path in ALL_PART_PATHS:
|
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)
|
poly.color = Color(1.0, 0.85, 0.05, 0.90)
|
||||||
area.add_child(poly)
|
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:
|
area.body_entered.connect(func(b: Node) -> void:
|
||||||
if b.is_in_group("player") and b.has_method("take_damage"):
|
if b.is_in_group("player"):
|
||||||
b.take_damage(1.0))
|
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)
|
contents.add_child(area)
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,9 @@ var npc_ids_on_run: Array[String] = []
|
|||||||
# --- Floor-to-floor carry (not saved, only lives for one scene reload) ---
|
# --- 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
|
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:
|
func start_run(brought_credits: int, brought_buffs: Array[Resource], brought_npc_ids: Array[String]) -> void:
|
||||||
current_floor = 1
|
current_floor = 1
|
||||||
current_room_id = ""
|
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:
|
func end_run(player_survived: bool) -> void:
|
||||||
run_active = false
|
run_active = false
|
||||||
|
returning_from_run = true
|
||||||
if player_survived:
|
if player_survived:
|
||||||
_apply_run_rewards()
|
_apply_run_rewards()
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ const ROOM_COLORS := {
|
|||||||
}
|
}
|
||||||
const CURRENT_OUTLINE := Color(1.0, 1.0, 0.4) # bright yellow
|
const CURRENT_OUTLINE := Color(1.0, 1.0, 0.4) # bright yellow
|
||||||
const CONNECTION_COLOR := Color(0.5, 0.5, 0.6)
|
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 UNVISITED_ALPHA := 0.35
|
||||||
const BACKGROUND_COLOR := Color(0.08, 0.08, 0.10, 0.85)
|
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 map_pos := _grid_to_map_pos(pos)
|
||||||
var rect := Rect2(map_pos, ROOM_SIZE)
|
var rect := Rect2(map_pos, ROOM_SIZE)
|
||||||
|
|
||||||
# Room color with alpha based on visited state
|
# Fog of war: unvisited rooms show as generic grey (hide type info)
|
||||||
var color: Color = ROOM_COLORS.get(room.type, ROOM_COLORS[RoomData.RoomType.COMBAT])
|
var color: Color
|
||||||
if not is_visited:
|
if is_visited:
|
||||||
|
color = ROOM_COLORS.get(room.type, ROOM_COLORS[RoomData.RoomType.COMBAT])
|
||||||
|
else:
|
||||||
|
color = UNVISITED_COLOR
|
||||||
color.a = UNVISITED_ALPHA
|
color.a = UNVISITED_ALPHA
|
||||||
draw_rect(rect, color)
|
draw_rect(rect, color)
|
||||||
|
|
||||||
|
|||||||
@@ -9,4 +9,16 @@ func _on_body_entered(body: Node) -> void:
|
|||||||
if body.is_in_group("player") and part != null:
|
if body.is_in_group("player") and part != null:
|
||||||
AudioManager.play("item_pickup")
|
AudioManager.play("item_pickup")
|
||||||
UpgradeManager.acquire_part(part)
|
UpgradeManager.acquire_part(part)
|
||||||
|
_show_pickup_label()
|
||||||
queue_free()
|
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,6 +1,6 @@
|
|||||||
extends Node
|
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 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
|
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)
|
# slot -> BodyPart resource path (empty string = default/base part)
|
||||||
var equipped_parts: Dictionary = {
|
var equipped_parts: Dictionary = {
|
||||||
"head": "",
|
|
||||||
"torso": "",
|
"torso": "",
|
||||||
"left_arm": "",
|
"left_arm": "",
|
||||||
"right_arm": "",
|
"right_arm": "",
|
||||||
|
|||||||
Reference in New Issue
Block a user