Gameplay changes
This commit is contained in:
@@ -50,8 +50,12 @@ func play(sound_name: String) -> void:
|
|||||||
push_warning("AudioManager: Unknown sound '%s'" % sound_name)
|
push_warning("AudioManager: Unknown sound '%s'" % sound_name)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
var stream = _sounds[sound_name]
|
||||||
|
if stream == null:
|
||||||
|
return # File doesn't exist yet, skip silently
|
||||||
|
|
||||||
var player := _pool[_pool_index]
|
var player := _pool[_pool_index]
|
||||||
_pool_index = (_pool_index + 1) % POOL_SIZE
|
_pool_index = (_pool_index + 1) % POOL_SIZE
|
||||||
|
|
||||||
player.stream = _sounds[sound_name]
|
player.stream = stream
|
||||||
player.play()
|
player.play()
|
||||||
|
|||||||
@@ -66,6 +66,29 @@ const HOMING_PROJ_DAMAGE := 1.0
|
|||||||
const DRIFTER_SCENE = preload("res://scenes/enemies/drifter.tscn")
|
const DRIFTER_SCENE = preload("res://scenes/enemies/drifter.tscn")
|
||||||
const REPEATER_SCENE = preload("res://scenes/enemies/repeater.tscn")
|
const REPEATER_SCENE = preload("res://scenes/enemies/repeater.tscn")
|
||||||
const ANCHOR_SCENE = preload("res://scenes/enemies/anchor.tscn")
|
const ANCHOR_SCENE = preload("res://scenes/enemies/anchor.tscn")
|
||||||
|
const BODY_PART_PICKUP = preload("res://scenes/upgrades/body_part_pickup.tscn")
|
||||||
|
const RUN_ITEM_PICKUP = preload("res://scenes/items/run_item_pickup.tscn")
|
||||||
|
|
||||||
|
const ALL_PART_PATHS: Array[String] = [
|
||||||
|
"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",
|
||||||
|
"res://data/body_parts/left_arm_shield_projector.tres",
|
||||||
|
"res://data/body_parts/right_arm_heavy_emitter.tres",
|
||||||
|
"res://data/body_parts/right_arm_rapid_emitter.tres",
|
||||||
|
]
|
||||||
|
|
||||||
|
const ALL_ITEM_PATHS: Array[String] = [
|
||||||
|
"res://data/run_items/coolant_leak.tres",
|
||||||
|
"res://data/run_items/overclock_module.tres",
|
||||||
|
"res://data/run_items/scrap_magnet.tres",
|
||||||
|
"res://data/run_items/memory_spike.tres",
|
||||||
|
"res://data/run_items/rust_coat.tres",
|
||||||
|
"res://data/run_items/static_discharge.tres",
|
||||||
|
"res://data/run_items/fragmented_map.tres",
|
||||||
|
"res://data/run_items/plating_shard.tres",
|
||||||
|
"res://data/run_items/range_booster.tres",
|
||||||
|
]
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# State
|
# State
|
||||||
@@ -268,6 +291,22 @@ func _on_enemy_died(enemy: Node) -> void:
|
|||||||
_spawned_enemies.erase(enemy)
|
_spawned_enemies.erase(enemy)
|
||||||
_wave_enemies.erase(enemy)
|
_wave_enemies.erase(enemy)
|
||||||
|
|
||||||
|
# Play assembly sound per enemy absorbed
|
||||||
|
AudioManager.play("hivemind_assembly")
|
||||||
|
|
||||||
|
# Defer visual effect to avoid tree manipulation errors
|
||||||
|
call_deferred("_spawn_soul_particle")
|
||||||
|
|
||||||
|
# Check if wave is cleared — spawn next wave
|
||||||
|
if _wave_enemies.size() == 0 and _wave_index < WAVE_COUNT:
|
||||||
|
_wave_index += 1
|
||||||
|
_wave_spawned = false # allow next wave to spawn
|
||||||
|
|
||||||
|
|
||||||
|
func _spawn_soul_particle() -> void:
|
||||||
|
if not is_inside_tree():
|
||||||
|
return
|
||||||
|
|
||||||
# Create purple dot flying to center
|
# Create purple dot flying to center
|
||||||
var part := Polygon2D.new()
|
var part := Polygon2D.new()
|
||||||
var pts := PackedVector2Array()
|
var pts := PackedVector2Array()
|
||||||
@@ -276,7 +315,6 @@ func _on_enemy_died(enemy: Node) -> void:
|
|||||||
pts.append(Vector2(cos(a), sin(a)) * randf_range(8.0, 14.0))
|
pts.append(Vector2(cos(a), sin(a)) * randf_range(8.0, 14.0))
|
||||||
part.polygon = pts
|
part.polygon = pts
|
||||||
part.color = Color(0.5, 0.2, 0.6, 0.9)
|
part.color = Color(0.5, 0.2, 0.6, 0.9)
|
||||||
# Position at edge since we don't know exact death position
|
|
||||||
part.global_position = _room_center + Vector2(randf_range(-150, 150), randf_range(-150, 150))
|
part.global_position = _room_center + Vector2(randf_range(-150, 150), randf_range(-150, 150))
|
||||||
get_parent().add_child(part)
|
get_parent().add_child(part)
|
||||||
|
|
||||||
@@ -287,11 +325,6 @@ func _on_enemy_died(enemy: Node) -> void:
|
|||||||
tw.tween_property(part, "modulate:a", 0.0, 0.2)
|
tw.tween_property(part, "modulate:a", 0.0, 0.2)
|
||||||
tw.tween_callback(part.queue_free)
|
tw.tween_callback(part.queue_free)
|
||||||
|
|
||||||
# Check if wave is cleared — spawn next wave
|
|
||||||
if _wave_enemies.size() == 0 and _wave_index < WAVE_COUNT:
|
|
||||||
_wave_index += 1
|
|
||||||
_wave_spawned = false # allow next wave to spawn
|
|
||||||
|
|
||||||
|
|
||||||
func _grow_core() -> void:
|
func _grow_core() -> void:
|
||||||
# Each kill grows the core toward full size
|
# Each kill grows the core toward full size
|
||||||
@@ -508,6 +541,7 @@ func _clear_orbiters() -> void:
|
|||||||
# Sweep Attack (from Warden)
|
# Sweep Attack (from Warden)
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
func _attack_sweep() -> void:
|
func _attack_sweep() -> void:
|
||||||
|
AudioManager.play("hivemind_sweep")
|
||||||
var inner_left := -ROOM_HW + WALL_T
|
var inner_left := -ROOM_HW + WALL_T
|
||||||
var inner_right := ROOM_HW - WALL_T
|
var inner_right := ROOM_HW - WALL_T
|
||||||
var sweep_dir := 1.0 if randf() < 0.5 else -1.0
|
var sweep_dir := 1.0 if randf() < 0.5 else -1.0
|
||||||
@@ -944,5 +978,30 @@ func _die() -> void:
|
|||||||
_spawned_enemies.clear()
|
_spawned_enemies.clear()
|
||||||
_wave_enemies.clear()
|
_wave_enemies.clear()
|
||||||
|
|
||||||
|
# Always spawn item pickup
|
||||||
|
_spawn_item_drop()
|
||||||
|
# Also spawn body part if player doesn't have all
|
||||||
|
_spawn_body_part_drop()
|
||||||
|
|
||||||
EventBus.boss_died.emit()
|
EventBus.boss_died.emit()
|
||||||
queue_free()
|
queue_free()
|
||||||
|
|
||||||
|
func _spawn_item_drop() -> void:
|
||||||
|
var chosen: String = ALL_ITEM_PATHS[randi() % ALL_ITEM_PATHS.size()]
|
||||||
|
var pickup = RUN_ITEM_PICKUP.instantiate()
|
||||||
|
pickup.item = load(chosen)
|
||||||
|
pickup.global_position = global_position + Vector2(-30, 0)
|
||||||
|
get_parent().add_child(pickup)
|
||||||
|
|
||||||
|
func _spawn_body_part_drop() -> void:
|
||||||
|
var unacquired: Array[String] = []
|
||||||
|
for path in ALL_PART_PATHS:
|
||||||
|
if path not in UpgradeManager.acquired_part_paths:
|
||||||
|
unacquired.append(path)
|
||||||
|
if unacquired.is_empty():
|
||||||
|
return
|
||||||
|
var chosen: String = unacquired[randi() % unacquired.size()]
|
||||||
|
var pickup = BODY_PART_PICKUP.instantiate()
|
||||||
|
pickup.part = load(chosen)
|
||||||
|
pickup.global_position = global_position + Vector2(30, 0)
|
||||||
|
get_parent().add_child(pickup)
|
||||||
|
|||||||
@@ -50,6 +50,29 @@ const BURST_PROJ_DAMAGE := 1.0
|
|||||||
const HOMING_PROJ_DAMAGE := 1.0
|
const HOMING_PROJ_DAMAGE := 1.0
|
||||||
|
|
||||||
const DRIFTER_SCENE = preload("res://scenes/enemies/drifter.tscn")
|
const DRIFTER_SCENE = preload("res://scenes/enemies/drifter.tscn")
|
||||||
|
const BODY_PART_PICKUP = preload("res://scenes/upgrades/body_part_pickup.tscn")
|
||||||
|
const RUN_ITEM_PICKUP = preload("res://scenes/items/run_item_pickup.tscn")
|
||||||
|
|
||||||
|
const ALL_PART_PATHS: Array[String] = [
|
||||||
|
"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",
|
||||||
|
"res://data/body_parts/left_arm_shield_projector.tres",
|
||||||
|
"res://data/body_parts/right_arm_heavy_emitter.tres",
|
||||||
|
"res://data/body_parts/right_arm_rapid_emitter.tres",
|
||||||
|
]
|
||||||
|
|
||||||
|
const ALL_ITEM_PATHS: Array[String] = [
|
||||||
|
"res://data/run_items/coolant_leak.tres",
|
||||||
|
"res://data/run_items/overclock_module.tres",
|
||||||
|
"res://data/run_items/scrap_magnet.tres",
|
||||||
|
"res://data/run_items/memory_spike.tres",
|
||||||
|
"res://data/run_items/rust_coat.tres",
|
||||||
|
"res://data/run_items/static_discharge.tres",
|
||||||
|
"res://data/run_items/fragmented_map.tres",
|
||||||
|
"res://data/run_items/plating_shard.tres",
|
||||||
|
"res://data/run_items/range_booster.tres",
|
||||||
|
]
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# State
|
# State
|
||||||
@@ -130,6 +153,7 @@ func _tick_teleport(delta: float) -> void:
|
|||||||
_reappear()
|
_reappear()
|
||||||
|
|
||||||
func _start_fade_out() -> void:
|
func _start_fade_out() -> void:
|
||||||
|
AudioManager.play("relay_teleport")
|
||||||
_tp_state = TeleportState.FADING_OUT
|
_tp_state = TeleportState.FADING_OUT
|
||||||
_fade_timer = FADE_OUT_TIME
|
_fade_timer = FADE_OUT_TIME
|
||||||
|
|
||||||
@@ -142,7 +166,6 @@ func _enter_transit() -> void:
|
|||||||
_transit_timer = TRANSIT_TIME
|
_transit_timer = TRANSIT_TIME
|
||||||
|
|
||||||
func _reappear() -> void:
|
func _reappear() -> void:
|
||||||
AudioManager.play("relay_teleport")
|
|
||||||
# Pick random position within room bounds
|
# Pick random position within room bounds
|
||||||
var min_x := _room_center.x - ROOM_HW + WALL_T + WALL_MARGIN
|
var min_x := _room_center.x - ROOM_HW + WALL_T + WALL_MARGIN
|
||||||
var max_x := _room_center.x + ROOM_HW - WALL_T - WALL_MARGIN
|
var max_x := _room_center.x + ROOM_HW - WALL_T - WALL_MARGIN
|
||||||
@@ -362,6 +385,11 @@ func _spawn_drifters() -> void:
|
|||||||
var offset := Vector2.from_angle(randf() * TAU) * randf_range(DRIFTER_OFFSET_MIN, DRIFTER_OFFSET_MAX)
|
var offset := Vector2.from_angle(randf() * TAU) * randf_range(DRIFTER_OFFSET_MIN, DRIFTER_OFFSET_MAX)
|
||||||
get_parent().add_child(drifter)
|
get_parent().add_child(drifter)
|
||||||
drifter.global_position = global_position + offset
|
drifter.global_position = global_position + offset
|
||||||
|
# Signal drifters: weaker than normal drifters
|
||||||
|
drifter.max_health = drifter.max_health * 0.5
|
||||||
|
drifter.current_health = drifter.max_health
|
||||||
|
drifter.speed = drifter.speed * 0.7
|
||||||
|
drifter.scale = Vector2(0.7, 0.7)
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# Damage / Phase
|
# Damage / Phase
|
||||||
@@ -416,7 +444,6 @@ func _tick_climax(delta: float) -> void:
|
|||||||
|
|
||||||
func _die() -> void:
|
func _die() -> void:
|
||||||
AudioManager.play("enemy_death")
|
AudioManager.play("enemy_death")
|
||||||
EventBus.boss_died.emit()
|
|
||||||
|
|
||||||
# Cleanup burst projectiles
|
# Cleanup burst projectiles
|
||||||
for proj in _burst_projs:
|
for proj in _burst_projs:
|
||||||
@@ -430,4 +457,30 @@ func _die() -> void:
|
|||||||
proj.queue_free()
|
proj.queue_free()
|
||||||
_homing_projs.clear()
|
_homing_projs.clear()
|
||||||
|
|
||||||
|
# Always spawn item pickup
|
||||||
|
_spawn_item_drop()
|
||||||
|
# Also spawn body part if player doesn't have all
|
||||||
|
_spawn_body_part_drop()
|
||||||
|
|
||||||
|
EventBus.boss_died.emit()
|
||||||
queue_free()
|
queue_free()
|
||||||
|
|
||||||
|
func _spawn_item_drop() -> void:
|
||||||
|
var chosen: String = ALL_ITEM_PATHS[randi() % ALL_ITEM_PATHS.size()]
|
||||||
|
var pickup = RUN_ITEM_PICKUP.instantiate()
|
||||||
|
pickup.item = load(chosen)
|
||||||
|
pickup.global_position = global_position + Vector2(-30, 0)
|
||||||
|
get_parent().add_child(pickup)
|
||||||
|
|
||||||
|
func _spawn_body_part_drop() -> void:
|
||||||
|
var unacquired: Array[String] = []
|
||||||
|
for path in ALL_PART_PATHS:
|
||||||
|
if path not in UpgradeManager.acquired_part_paths:
|
||||||
|
unacquired.append(path)
|
||||||
|
if unacquired.is_empty():
|
||||||
|
return
|
||||||
|
var chosen: String = unacquired[randi() % unacquired.size()]
|
||||||
|
var pickup = BODY_PART_PICKUP.instantiate()
|
||||||
|
pickup.part = load(chosen)
|
||||||
|
pickup.global_position = global_position + Vector2(30, 0)
|
||||||
|
get_parent().add_child(pickup)
|
||||||
|
|||||||
@@ -40,6 +40,30 @@ const FREEZE_DURATION := 1.5
|
|||||||
const SWEEP_PROJ_DAMAGE := 1.0
|
const SWEEP_PROJ_DAMAGE := 1.0
|
||||||
const MINE_DAMAGE := 1.0
|
const MINE_DAMAGE := 1.0
|
||||||
|
|
||||||
|
const BODY_PART_PICKUP = preload("res://scenes/upgrades/body_part_pickup.tscn")
|
||||||
|
const RUN_ITEM_PICKUP = preload("res://scenes/items/run_item_pickup.tscn")
|
||||||
|
|
||||||
|
const ALL_PART_PATHS: Array[String] = [
|
||||||
|
"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",
|
||||||
|
"res://data/body_parts/left_arm_shield_projector.tres",
|
||||||
|
"res://data/body_parts/right_arm_heavy_emitter.tres",
|
||||||
|
"res://data/body_parts/right_arm_rapid_emitter.tres",
|
||||||
|
]
|
||||||
|
|
||||||
|
const ALL_ITEM_PATHS: Array[String] = [
|
||||||
|
"res://data/run_items/coolant_leak.tres",
|
||||||
|
"res://data/run_items/overclock_module.tres",
|
||||||
|
"res://data/run_items/scrap_magnet.tres",
|
||||||
|
"res://data/run_items/memory_spike.tres",
|
||||||
|
"res://data/run_items/rust_coat.tres",
|
||||||
|
"res://data/run_items/static_discharge.tres",
|
||||||
|
"res://data/run_items/fragmented_map.tres",
|
||||||
|
"res://data/run_items/plating_shard.tres",
|
||||||
|
"res://data/run_items/range_booster.tres",
|
||||||
|
]
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# State
|
# State
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
@@ -386,9 +410,35 @@ func _die() -> void:
|
|||||||
if is_instance_valid(entry["node"]):
|
if is_instance_valid(entry["node"]):
|
||||||
entry["node"].queue_free()
|
entry["node"].queue_free()
|
||||||
_sweep_projs.clear()
|
_sweep_projs.clear()
|
||||||
|
|
||||||
|
# Always spawn item pickup
|
||||||
|
_spawn_item_drop()
|
||||||
|
# Also spawn body part if player doesn't have all
|
||||||
|
_spawn_body_part_drop()
|
||||||
|
|
||||||
EventBus.boss_died.emit()
|
EventBus.boss_died.emit()
|
||||||
queue_free()
|
queue_free()
|
||||||
|
|
||||||
|
func _spawn_item_drop() -> void:
|
||||||
|
var chosen: String = ALL_ITEM_PATHS[randi() % ALL_ITEM_PATHS.size()]
|
||||||
|
var pickup = RUN_ITEM_PICKUP.instantiate()
|
||||||
|
pickup.item = load(chosen)
|
||||||
|
pickup.global_position = global_position + Vector2(-30, 0)
|
||||||
|
get_parent().add_child(pickup)
|
||||||
|
|
||||||
|
func _spawn_body_part_drop() -> void:
|
||||||
|
var unacquired: Array[String] = []
|
||||||
|
for path in ALL_PART_PATHS:
|
||||||
|
if path not in UpgradeManager.acquired_part_paths:
|
||||||
|
unacquired.append(path)
|
||||||
|
if unacquired.is_empty():
|
||||||
|
return
|
||||||
|
var chosen: String = unacquired[randi() % unacquired.size()]
|
||||||
|
var pickup = BODY_PART_PICKUP.instantiate()
|
||||||
|
pickup.part = load(chosen)
|
||||||
|
pickup.global_position = global_position + Vector2(30, 0)
|
||||||
|
get_parent().add_child(pickup)
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# Visual — phase-aware tints (overrides EnemyBase._tick_flash)
|
# Visual — phase-aware tints (overrides EnemyBase._tick_flash)
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -240,12 +240,39 @@ func _die() -> void:
|
|||||||
# Static Discharge — instant AoE damage to enemies in radius
|
# Static Discharge — instant AoE damage to enemies in radius
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
func _trigger_static_discharge() -> void:
|
func _trigger_static_discharge() -> void:
|
||||||
|
# Visual: yellow flash on player
|
||||||
|
_spawn_discharge_flash()
|
||||||
|
|
||||||
for enemy in get_tree().get_nodes_in_group("enemies"):
|
for enemy in get_tree().get_nodes_in_group("enemies"):
|
||||||
if not is_instance_valid(enemy):
|
if not is_instance_valid(enemy):
|
||||||
continue
|
continue
|
||||||
if global_position.distance_to(enemy.global_position) <= stats.discharge_radius:
|
if global_position.distance_to(enemy.global_position) <= stats.discharge_radius:
|
||||||
if enemy.has_method("take_damage"):
|
if enemy.has_method("take_damage"):
|
||||||
enemy.take_damage(stats.discharge_damage)
|
var damage := stats.discharge_damage
|
||||||
|
# Bonus damage to slowed enemies
|
||||||
|
var is_slowed := false
|
||||||
|
if enemy.get("is_slowed"):
|
||||||
|
is_slowed = true
|
||||||
|
elif enemy.get("_slow_timer") != null and enemy._slow_timer > 0:
|
||||||
|
is_slowed = true
|
||||||
|
if is_slowed:
|
||||||
|
damage *= 1.5
|
||||||
|
enemy.take_damage(damage)
|
||||||
|
|
||||||
|
func _spawn_discharge_flash() -> void:
|
||||||
|
var flash := Polygon2D.new()
|
||||||
|
var pts := PackedVector2Array()
|
||||||
|
for i in 16:
|
||||||
|
var a := TAU * i / 16.0
|
||||||
|
pts.append(Vector2(cos(a), sin(a)) * stats.discharge_radius)
|
||||||
|
flash.polygon = pts
|
||||||
|
flash.color = Color(1.0, 0.9, 0.2, 0.6) # yellow flash
|
||||||
|
flash.global_position = global_position
|
||||||
|
get_parent().add_child(flash)
|
||||||
|
|
||||||
|
var tw := flash.create_tween()
|
||||||
|
tw.tween_property(flash, "modulate:a", 0.0, 0.2)
|
||||||
|
tw.tween_callback(flash.queue_free)
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# Coolant Leak — spawn a temporary slow zone at player position (1s)
|
# Coolant Leak — spawn a temporary slow zone at player position (1s)
|
||||||
@@ -262,6 +289,16 @@ func _spawn_coolant_zone() -> void:
|
|||||||
zone.add_child(cs)
|
zone.add_child(cs)
|
||||||
zone.position = (get_parent() as Node2D).to_local(global_position)
|
zone.position = (get_parent() as Node2D).to_local(global_position)
|
||||||
|
|
||||||
|
# Visual: blue tint zone indicator
|
||||||
|
var visual := Polygon2D.new()
|
||||||
|
var pts := PackedVector2Array()
|
||||||
|
for i in 12:
|
||||||
|
var a := TAU * i / 12.0
|
||||||
|
pts.append(Vector2(cos(a), sin(a)) * 24.0)
|
||||||
|
visual.polygon = pts
|
||||||
|
visual.color = Color(0.3, 0.6, 1.0, 0.4) # blue tint
|
||||||
|
zone.add_child(visual)
|
||||||
|
|
||||||
zone.body_entered.connect(func(b: Node) -> void:
|
zone.body_entered.connect(func(b: Node) -> void:
|
||||||
if b.has_method("apply_slow"):
|
if b.has_method("apply_slow"):
|
||||||
b.apply_slow(2.0, 0.4)
|
b.apply_slow(2.0, 0.4)
|
||||||
|
|||||||
@@ -126,8 +126,11 @@ const DEFAULT_PARTS: Array[String] = [
|
|||||||
func _rebuild_items() -> void:
|
func _rebuild_items() -> void:
|
||||||
_items.clear()
|
_items.clear()
|
||||||
|
|
||||||
# Add default parts first (always available)
|
# Add default parts first (always available), except default_head
|
||||||
for path: String in DEFAULT_PARTS:
|
for path: String in DEFAULT_PARTS:
|
||||||
|
# Skip default head - not shown as equippable
|
||||||
|
if "head_default" in path:
|
||||||
|
continue
|
||||||
var part := load(path) as BodyPartData
|
var part := load(path) as BodyPartData
|
||||||
if part:
|
if part:
|
||||||
_items.append(part)
|
_items.append(part)
|
||||||
|
|||||||
@@ -84,13 +84,17 @@ func _on_run_ended(_reached_hub: bool) -> void:
|
|||||||
|
|
||||||
|
|
||||||
func _on_room_revealed() -> void:
|
func _on_room_revealed() -> void:
|
||||||
# Fragmented Map effect: reveal types of adjacent unvisited rooms
|
# Fragmented Map effect: reveal types of adjacent unvisited COMBAT rooms only
|
||||||
if not _rooms_data.has(_current_pos):
|
if not _rooms_data.has(_current_pos):
|
||||||
return
|
return
|
||||||
var current_room: RoomData = _rooms_data[_current_pos]
|
var current_room: RoomData = _rooms_data[_current_pos]
|
||||||
for conn_pos in current_room.connections.values():
|
for conn_pos in current_room.connections.values():
|
||||||
if conn_pos not in _revealed_positions:
|
if conn_pos not in _revealed_positions:
|
||||||
_revealed_positions.append(conn_pos)
|
if _rooms_data.has(conn_pos):
|
||||||
|
var room: RoomData = _rooms_data[conn_pos]
|
||||||
|
# Only reveal COMBAT rooms, skip ITEM, SHOP, BOSS
|
||||||
|
if room.type == RoomData.RoomType.COMBAT:
|
||||||
|
_revealed_positions.append(conn_pos)
|
||||||
queue_redraw()
|
queue_redraw()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user