Initial commit — Station 0 vertical slice in progress
Includes full design documentation (ARCHITECTURE, DESIGN_NOTES, CONTENT_SPEC, PRODUCTION_NOTES) and active Godot 4 / GDScript codebase. Core systems built: player, floor generation, room system, enemy base, body part upgrades, run manager, save system, HUD, EventBus.
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
extends Resource
|
||||
class_name RunItem
|
||||
|
||||
enum Effect {
|
||||
STAT_MOD = 0, # flat stat modifier
|
||||
RICOCHET = 1, # projectiles bounce off walls once
|
||||
SCATTER = 2, # fire N projectiles in a spread
|
||||
EXPLOSIVE = 3, # projectiles explode on hit
|
||||
HEAL = 4, # immediate HP restore on pickup, no ongoing effect
|
||||
COOLANT_LEAK = 5, # leaves a slow zone on taking damage
|
||||
SCRAP_MAGNET = 6, # scrap tokens auto-attract within magnet_radius
|
||||
MEMORY_SPIKE = 7, # first projectile per room deals 3x damage
|
||||
RUST_COAT = 8, # incoming damage reduced by damage_reduction (min 1)
|
||||
STATIC_DISCHARGE = 9, # AoE burst (discharge_radius) on taking damage
|
||||
FRAGMENTED_MAP = 10, # reveals one unexplored room on each combat clear
|
||||
OVERCLOCK = 11, # fire rate x1.4; every 3rd shot deals 0 damage
|
||||
}
|
||||
|
||||
@export var display_name: String = ""
|
||||
@export var description: String = ""
|
||||
@export var effect: Effect = Effect.STAT_MOD
|
||||
|
||||
# STAT_MOD
|
||||
@export var stat_key: String = "" # "speed"|"max_health"|"damage"|"fire_rate"|"range"
|
||||
@export var stat_delta: float = 0.0
|
||||
|
||||
# SCATTER
|
||||
@export var scatter_count: int = 3
|
||||
@export var scatter_spread_deg: float = 20.0
|
||||
|
||||
# EXPLOSIVE
|
||||
@export var explosion_radius: float = 64.0
|
||||
@export var explosion_damage: float = 2.5
|
||||
|
||||
# HEAL — immediate HP restored on pickup (separate from stat_delta)
|
||||
@export var heal_on_pickup: float = 0.0
|
||||
|
||||
# RUST_COAT
|
||||
@export var damage_reduction: float = 1.0
|
||||
|
||||
# STATIC_DISCHARGE
|
||||
@export var discharge_radius: float = 64.0
|
||||
@export var discharge_damage: float = 1.0
|
||||
|
||||
# SCRAP_MAGNET
|
||||
@export var magnet_radius: float = 192.0
|
||||
@@ -0,0 +1,35 @@
|
||||
extends Area2D
|
||||
|
||||
var item: RunItem = null
|
||||
|
||||
func _ready() -> void:
|
||||
body_entered.connect(_on_body_entered)
|
||||
|
||||
# Placeholder visual — cyan diamond
|
||||
func _draw() -> void:
|
||||
draw_colored_polygon(PackedVector2Array([
|
||||
Vector2(0, -14), Vector2(10, 0), Vector2(0, 14), Vector2(-10, 0)
|
||||
]), Color(0.2, 0.9, 0.85))
|
||||
draw_arc(Vector2.ZERO, 16.0, 0, TAU, 24, Color(0.5, 1.0, 0.95), 1.5)
|
||||
|
||||
func _on_body_entered(body: Node) -> void:
|
||||
if not body.is_in_group("player") or item == null:
|
||||
return
|
||||
RunManager.collect_item(item)
|
||||
if item.heal_on_pickup > 0.0:
|
||||
body.stats.heal(item.heal_on_pickup)
|
||||
body.stats.recalculate()
|
||||
EventBus.player_health_changed.emit(body.stats.current_health, body.stats.max_health)
|
||||
_show_pickup_label()
|
||||
queue_free()
|
||||
|
||||
func _show_pickup_label() -> void:
|
||||
var lbl := Label.new()
|
||||
lbl.text = item.display_name
|
||||
lbl.position = global_position + Vector2(-40, -20)
|
||||
lbl.modulate = Color(0.2, 1.0, 0.85)
|
||||
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)
|
||||
Reference in New Issue
Block a user