fix(map): complete rewrite of arena layout
Problems fixed: - Player spawn moved from inside central platform to open area (z=20) - Removed broken internal stairs inside tower (disconnected ramps) - Removed corner towers, walkways, stepping stones, wall-run corridor, wall-climb surfaces, grapple anchors — all were overlapping or unreachable - Reduced arena from 96x96 to 80x80 for tighter gameplay - Crates properly spaced (1.5u apart), no overlaps or intersections - Reduced from 6 spawns to 4 (corners only), each with 2 L-shaped cover walls and clear exit routes — no more 3-wall traps - Spawn alcoves use 2 walls max with open diagonal exits - Dummies placed in open areas away from geometry: TargetDummy at (0,-25), KillableDummy at (25,0), WalkingDummy patrols z=-30 from x=-20 to 20 - Central platform simplified: 16x16 base (2u) + 8x8 upper (4u) - 4 cardinal ramps properly connect ground to platform edge - Cover walls placed in open lanes, not blocking movement - Barrels placed along outer walls, not in pathways
This commit is contained in:
+100
-448
@@ -21,7 +21,6 @@ var _debug_ui_panel: PanelContainer
|
|||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
|
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
|
||||||
_load_props()
|
|
||||||
_build_materials()
|
_build_materials()
|
||||||
_build_geometry()
|
_build_geometry()
|
||||||
_build_hud()
|
_build_hud()
|
||||||
@@ -52,26 +51,18 @@ func _build_materials() -> void:
|
|||||||
|
|
||||||
|
|
||||||
# ═══════════════════════════════════════════════════════════════════════════════
|
# ═══════════════════════════════════════════════════════════════════════════════
|
||||||
# GEOMETRY
|
# GEOMETRY — Clean 80x80 arena
|
||||||
# ═══════════════════════════════════════════════════════════════════════════════
|
# ═══════════════════════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
func _build_geometry() -> void:
|
func _build_geometry() -> void:
|
||||||
_build_environment()
|
_build_environment()
|
||||||
_build_floor()
|
_build_floor()
|
||||||
_build_outer_walls()
|
_build_outer_walls()
|
||||||
_build_central_structure()
|
_build_central_platform()
|
||||||
_build_corner_towers()
|
|
||||||
_build_elevated_walkways()
|
|
||||||
_build_ramps()
|
_build_ramps()
|
||||||
_build_stepping_stones()
|
_build_cover()
|
||||||
_build_wall_run_surfaces()
|
|
||||||
_build_wall_climb_surfaces()
|
|
||||||
_build_grapple_anchors()
|
|
||||||
_build_cover_system()
|
|
||||||
_build_speed_corridor()
|
|
||||||
_build_spawn_alcoves()
|
_build_spawn_alcoves()
|
||||||
_build_decorations()
|
_build_dummies()
|
||||||
_build_target_dummy()
|
|
||||||
_build_lighting()
|
_build_lighting()
|
||||||
|
|
||||||
|
|
||||||
@@ -103,63 +94,21 @@ func _ramp_static(pos: Vector3, size: Vector3, rot_deg: Vector3, color: Color, n
|
|||||||
return body
|
return body
|
||||||
|
|
||||||
|
|
||||||
# ── GLB Prop Scenes (generated via Blender headless) ──────────────────────────
|
|
||||||
var prop_crate: PackedScene
|
|
||||||
var prop_barrel: PackedScene
|
|
||||||
var prop_pillar: PackedScene
|
|
||||||
var prop_ramp: PackedScene
|
|
||||||
var prop_weapon_pickup: PackedScene
|
|
||||||
var prop_health_pack: PackedScene
|
|
||||||
var prop_ammo_pack: PackedScene
|
|
||||||
|
|
||||||
func _load_props() -> void:
|
|
||||||
prop_crate = load("res://assets/props/crate.glb")
|
|
||||||
prop_barrel = load("res://assets/props/barrel.glb")
|
|
||||||
prop_pillar = load("res://assets/props/pillar.glb")
|
|
||||||
prop_ramp = load("res://assets/props/ramp.glb")
|
|
||||||
prop_weapon_pickup = load("res://assets/props/weapon_pickup.glb")
|
|
||||||
prop_health_pack = load("res://assets/props/health_pack.glb")
|
|
||||||
prop_ammo_pack = load("res://assets/props/ammo_pack.glb")
|
|
||||||
# Log which props loaded
|
|
||||||
if prop_crate: print("Prop loaded: crate")
|
|
||||||
else: print("WARN: crate.glb not imported yet - run Godot editor once to import")
|
|
||||||
if prop_barrel: print("Prop loaded: barrel")
|
|
||||||
if prop_pillar: print("Prop loaded: pillar")
|
|
||||||
|
|
||||||
|
|
||||||
func _place_prop(scene: PackedScene, pos: Vector3, name: String = "") -> void:
|
|
||||||
if not scene:
|
|
||||||
return # Skip if not imported yet
|
|
||||||
var inst = scene.instantiate()
|
|
||||||
if inst:
|
|
||||||
inst.name = name if not name.is_empty() else scene.resource_path.get_file().get_basename()
|
|
||||||
inst.position = pos
|
|
||||||
add_child(inst)
|
|
||||||
|
|
||||||
|
|
||||||
# ── Color Palette ─────────────────────────────────────────────────────────────
|
# ── Color Palette ─────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
var C_FLOOR: Color = Color(0.22, 0.22, 0.25)
|
var C_FLOOR := Color(0.22, 0.22, 0.25)
|
||||||
var C_FLOOR_ACCENT: Color = Color(0.28, 0.26, 0.22)
|
var C_WALL := Color(0.35, 0.28, 0.22)
|
||||||
var C_WALL: Color = Color(0.35, 0.28, 0.22)
|
var C_WALL_DARK := Color(0.25, 0.20, 0.18)
|
||||||
var C_WALL_DARK: Color = Color(0.25, 0.20, 0.18)
|
var C_METAL := Color(0.50, 0.52, 0.55)
|
||||||
var C_METAL: Color = Color(0.50, 0.52, 0.55)
|
var C_METAL_DARK := Color(0.35, 0.37, 0.40)
|
||||||
var C_METAL_DARK: Color = Color(0.35, 0.37, 0.40)
|
var C_TEAL := Color(0.20, 0.45, 0.55)
|
||||||
var C_TEAL: Color = Color(0.20, 0.45, 0.55)
|
var C_CRATE := Color(0.65, 0.50, 0.30)
|
||||||
var C_PURPLE: Color = Color(0.45, 0.25, 0.55)
|
var C_RED := Color(0.70, 0.22, 0.22)
|
||||||
var C_ORANGE: Color = Color(0.60, 0.35, 0.15)
|
var C_BLUE := Color(0.22, 0.30, 0.70)
|
||||||
var C_WOOD: Color = Color(0.55, 0.38, 0.22)
|
var C_ACCENT_WARM := Color(0.85, 0.55, 0.20)
|
||||||
var C_CRATE: Color = Color(0.65, 0.50, 0.30)
|
var C_ACCENT_COOL := Color(0.20, 0.50, 0.85)
|
||||||
var C_RED: Color = Color(0.70, 0.22, 0.22)
|
var C_RAMP := Color(0.60, 0.35, 0.15)
|
||||||
var C_BLUE: Color = Color(0.22, 0.30, 0.70)
|
var C_YELLOW := Color(0.80, 0.75, 0.20)
|
||||||
var C_ACCENT_WARM: Color = Color(0.85, 0.55, 0.20)
|
|
||||||
var C_ACCENT_COOL: Color = Color(0.20, 0.50, 0.85)
|
|
||||||
var C_WALLRUN: Color = Color(0.20, 0.45, 0.65)
|
|
||||||
var C_WALLCLIMB: Color = Color(0.55, 0.45, 0.20)
|
|
||||||
var C_GREEN: Color = Color(0.20, 0.35, 0.20)
|
|
||||||
var C_DARK_GREEN: Color = Color(0.15, 0.25, 0.15)
|
|
||||||
var C_YELLOW: Color = Color(0.80, 0.75, 0.20)
|
|
||||||
var C_RAMP: Color = Color(0.60, 0.35, 0.15)
|
|
||||||
|
|
||||||
|
|
||||||
# ── Environment ───────────────────────────────────────────────────────────────
|
# ── Environment ───────────────────────────────────────────────────────────────
|
||||||
@@ -193,340 +142,107 @@ func _build_environment() -> void:
|
|||||||
# ── Floor ─────────────────────────────────────────────────────────────────────
|
# ── Floor ─────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
func _build_floor() -> void:
|
func _build_floor() -> void:
|
||||||
# Main arena floor (96x96)
|
# Main arena floor (80x80)
|
||||||
_box_static(Vector3(0, -0.5, 0), Vector3(96, 1.0, 96), C_FLOOR, "Floor_Main")
|
_box_static(Vector3(0, -0.5, 0), Vector3(80, 1.0, 80), C_FLOOR, "Floor_Main")
|
||||||
|
|
||||||
# Floor accent tiles (checkerboard pattern in central area)
|
|
||||||
for ix in range(-4, 5):
|
|
||||||
for iz in range(-4, 5):
|
|
||||||
if (ix + iz) % 2 == 0:
|
|
||||||
_box_static(
|
|
||||||
Vector3(float(ix) * 4.0, -0.49, float(iz) * 4.0),
|
|
||||||
Vector3(3.8, 0.02, 3.8),
|
|
||||||
C_FLOOR_ACCENT,
|
|
||||||
"Floor_Tile_%d_%d" % [ix, iz]
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
# ── Outer Walls ───────────────────────────────────────────────────────────────
|
# ── Outer Walls ───────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
func _build_outer_walls() -> void:
|
func _build_outer_walls() -> void:
|
||||||
var wall_height := 12.0
|
var wall_height := 10.0
|
||||||
var map_half := 48.0
|
var half := 40.0
|
||||||
|
_box_static(Vector3(0, wall_height / 2.0, -half), Vector3(80, wall_height, 1.0), C_WALL, "Wall_North")
|
||||||
# North
|
_box_static(Vector3(0, wall_height / 2.0, half), Vector3(80, wall_height, 1.0), C_WALL, "Wall_South")
|
||||||
_box_static(Vector3(0, wall_height * 0.5, -map_half), Vector3(96, wall_height, 1.0), C_WALL, "Wall_North")
|
_box_static(Vector3(half, wall_height / 2.0, 0), Vector3(1.0, wall_height, 80), C_WALL, "Wall_East")
|
||||||
# South
|
_box_static(Vector3(-half, wall_height / 2.0, 0), Vector3(1.0, wall_height, 80), C_WALL, "Wall_West")
|
||||||
_box_static(Vector3(0, wall_height * 0.5, map_half), Vector3(96, wall_height, 1.0), C_WALL, "Wall_South")
|
|
||||||
# East
|
|
||||||
_box_static(Vector3(map_half, wall_height * 0.5, 0), Vector3(1.0, wall_height, 96), C_WALL, "Wall_East")
|
|
||||||
# West
|
|
||||||
_box_static(Vector3(-map_half, wall_height * 0.5, 0), Vector3(1.0, wall_height, 96), C_WALL, "Wall_West")
|
|
||||||
|
|
||||||
|
|
||||||
# ── Central Structure ─────────────────────────────────────────────────────────
|
# ── Central Platform ──────────────────────────────────────────────────────────
|
||||||
|
|
||||||
func _build_central_structure() -> void:
|
func _build_central_platform() -> void:
|
||||||
# Main platform (3u high, 20x20)
|
# Raised platform (2u high, 16x16) — the main fight area
|
||||||
_box_static(Vector3(0, 1.5, 0), Vector3(20, 3.0, 20), C_METAL_DARK, "Central_Platform")
|
_box_static(Vector3(0, 1.0, 0), Vector3(16, 2.0, 16), C_METAL_DARK, "Central_Platform")
|
||||||
|
# Upper platform (4u high, 8x8) — sniper perch
|
||||||
# Upper tower (6u high, 10x10)
|
_box_static(Vector3(0, 3.0, 0), Vector3(8, 2.0, 8), C_METAL, "Central_Upper")
|
||||||
_box_static(Vector3(0, 6.0, 0), Vector3(10, 6.0, 10), C_WALL_DARK, "Central_Tower")
|
|
||||||
|
|
||||||
# Tower top platform (9u high, 14x14) - grapple target
|
|
||||||
_box_static(Vector3(0, 11.5, 0), Vector3(14, 1.0, 14), C_METAL, "Central_Top")
|
|
||||||
|
|
||||||
# Tower crown walls (partial cover on top)
|
|
||||||
_box_static(Vector3(-5, 13.5, -5), Vector3(4, 3.0, 0.5), C_METAL, "Crown_NW")
|
|
||||||
_box_static(Vector3(5, 13.5, 5), Vector3(4, 3.0, 0.5), C_METAL, "Crown_SE")
|
|
||||||
_box_static(Vector3(-5, 13.5, 5), Vector3(0.5, 3.0, 4), C_METAL, "Crown_SW")
|
|
||||||
_box_static(Vector3(5, 13.5, -5), Vector3(0.5, 3.0, 4), C_METAL, "Crown_NE")
|
|
||||||
|
|
||||||
# Staircase inside tower (ramp approximation with steps)
|
|
||||||
for i in range(8):
|
|
||||||
var step_y := 2.0 + float(i) * 0.85
|
|
||||||
var step_size := 6.0 - float(i) * 0.4
|
|
||||||
_box_static(
|
|
||||||
Vector3(0, step_y, -3.0 + float(i) * 0.3),
|
|
||||||
Vector3(step_size, 0.3, 2.5),
|
|
||||||
C_METAL,
|
|
||||||
"Central_Step_%d" % i
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
# ── Corner Towers ─────────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
func _build_corner_towers() -> void:
|
|
||||||
# Each corner has a tower (5u high, 8x8 base) with spawn alcoves at base
|
|
||||||
var tower_offsets := [
|
|
||||||
Vector3(-36, 0, -36),
|
|
||||||
Vector3(36, 0, -36),
|
|
||||||
Vector3(-36, 0, 36),
|
|
||||||
Vector3(36, 0, 36),
|
|
||||||
]
|
|
||||||
for offset in tower_offsets:
|
|
||||||
# Tower base
|
|
||||||
_box_static(offset + Vector3(0, 2.5, 0), Vector3(8, 5.0, 8), C_WALL_DARK, "Tower_%d" % tower_offsets.find(offset))
|
|
||||||
# Tower top platform
|
|
||||||
_box_static(offset + Vector3(0, 5.5, 0), Vector3(10, 1.0, 10), C_METAL, "TowerTop_%d" % tower_offsets.find(offset))
|
|
||||||
# Tower corner railing
|
|
||||||
_box_static(offset + Vector3(4, 7.0, 4), Vector3(2, 2.0, 0.4), C_METAL, "TowerRailA_%d" % tower_offsets.find(offset))
|
|
||||||
_box_static(offset + Vector3(4, 7.0, -4), Vector3(0.4, 2.0, 2), C_METAL, "TowerRailB_%d" % tower_offsets.find(offset))
|
|
||||||
|
|
||||||
|
|
||||||
# ── Elevated Walkways ─────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
func _build_elevated_walkways() -> void:
|
|
||||||
# Mid-side elevated walkways (3u high) connecting central to edges
|
|
||||||
# North walkway
|
|
||||||
_box_static(Vector3(0, 3.0, -30), Vector3(6, 0.6, 20), C_METAL, "Walkway_North")
|
|
||||||
# South walkway
|
|
||||||
_box_static(Vector3(0, 3.0, 30), Vector3(6, 0.6, 20), C_METAL, "Walkway_South")
|
|
||||||
# East walkway
|
|
||||||
_box_static(Vector3(30, 3.0, 0), Vector3(20, 0.6, 6), C_METAL, "Walkway_East")
|
|
||||||
# West walkway
|
|
||||||
_box_static(Vector3(-30, 3.0, 0), Vector3(20, 0.6, 6), C_METAL, "Walkway_West")
|
|
||||||
|
|
||||||
# Walkway railings
|
|
||||||
_box_static(Vector3(-3.2, 4.5, -30), Vector3(0.3, 2.0, 20), C_METAL, "Rail_N_W")
|
|
||||||
_box_static(Vector3(3.2, 4.5, -30), Vector3(0.3, 2.0, 20), C_METAL, "Rail_N_E")
|
|
||||||
_box_static(Vector3(-3.2, 4.5, 30), Vector3(0.3, 2.0, 20), C_METAL, "Rail_S_W")
|
|
||||||
_box_static(Vector3(3.2, 4.5, 30), Vector3(0.3, 2.0, 20), C_METAL, "Rail_S_E")
|
|
||||||
|
|
||||||
|
|
||||||
# ── Ramps ─────────────────────────────────────────────────────────────────────
|
# ── Ramps ─────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
func _build_ramps() -> void:
|
func _build_ramps() -> void:
|
||||||
# Ramps from ground to central platform (4 cardinal)
|
# 4 cardinal ramps from ground to central platform
|
||||||
_ramp_static(Vector3(0, 1.5, -14), Vector3(8, 0.5, 8), Vector3(12, 0, 0), C_RAMP, "Ramp_CN")
|
# North ramp (slopes down toward -z)
|
||||||
_ramp_static(Vector3(0, 1.5, 14), Vector3(8, 0.5, 8), Vector3(-12, 0, 0), C_RAMP, "Ramp_CS")
|
_ramp_static(Vector3(0, 1.0, -11), Vector3(6, 0.4, 6), Vector3(14, 0, 0), C_RAMP, "Ramp_N")
|
||||||
_ramp_static(Vector3(14, 1.5, 0), Vector3(8, 0.5, 8), Vector3(0, 0, 12), C_RAMP, "Ramp_CE")
|
# South ramp
|
||||||
_ramp_static(Vector3(-14, 1.5, 0), Vector3(8, 0.5, 8), Vector3(0, 0, -12), C_RAMP, "Ramp_CW")
|
_ramp_static(Vector3(0, 1.0, 11), Vector3(6, 0.4, 6), Vector3(-14, 0, 0), C_RAMP, "Ramp_S")
|
||||||
|
# East ramp
|
||||||
# Ramps from ground to corner towers
|
_ramp_static(Vector3(11, 1.0, 0), Vector3(6, 0.4, 6), Vector3(0, 0, -14), C_RAMP, "Ramp_E")
|
||||||
_ramp_static(Vector3(-36, 1.5, -28), Vector3(5, 0.5, 10), Vector3(15, 0, 0), C_WOOD, "Ramp_Tower_NW")
|
# West ramp
|
||||||
_ramp_static(Vector3(36, 1.5, -28), Vector3(5, 0.5, 10), Vector3(15, 0, 0), C_WOOD, "Ramp_Tower_NE")
|
_ramp_static(Vector3(-11, 1.0, 0), Vector3(6, 0.4, 6), Vector3(0, 0, 14), C_RAMP, "Ramp_W")
|
||||||
_ramp_static(Vector3(-36, 1.5, 28), Vector3(5, 0.5, 10), Vector3(-15, 0, 0), C_WOOD, "Ramp_Tower_SW")
|
|
||||||
_ramp_static(Vector3(36, 1.5, 28), Vector3(5, 0.5, 10), Vector3(-15, 0, 0), C_WOOD, "Ramp_Tower_SE")
|
|
||||||
|
|
||||||
# Ramps to elevated walkways
|
|
||||||
_ramp_static(Vector3(0, 1.5, -20), Vector3(5, 0.5, 6), Vector3(10, 0, 0), C_RAMP, "Ramp_Walk_N")
|
|
||||||
_ramp_static(Vector3(0, 1.5, 20), Vector3(5, 0.5, 6), Vector3(-10, 0, 0), C_RAMP, "Ramp_Walk_S")
|
|
||||||
_ramp_static(Vector3(20, 1.5, 0), Vector3(6, 0.5, 5), Vector3(0, 0, 10), C_RAMP, "Ramp_Walk_E")
|
|
||||||
_ramp_static(Vector3(-20, 1.5, 0), Vector3(6, 0.5, 5), Vector3(0, 0, -10), C_RAMP, "Ramp_Walk_W")
|
|
||||||
|
|
||||||
# Quarter-pipe (curved ramp approximation) near center
|
|
||||||
for i in range(8):
|
|
||||||
var angle := float(i) * 11.25
|
|
||||||
var x_off := sin(deg_to_rad(angle)) * 6.0
|
|
||||||
var y_off := (1.0 - cos(deg_to_rad(angle))) * 6.0
|
|
||||||
_ramp_static(
|
|
||||||
Vector3(20 + x_off, y_off + 0.2, -20 + float(i) * 0.6),
|
|
||||||
Vector3(6, 0.3, 2),
|
|
||||||
Vector3(angle, 0, 0),
|
|
||||||
C_ORANGE,
|
|
||||||
"QuarterPipe_%d" % i
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
# ── Stepping Stones ───────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
func _build_stepping_stones() -> void:
|
|
||||||
# Parkour chain: NW quadrant
|
|
||||||
_box_static(Vector3(-12, 0.6, -12), Vector3(3, 1.2, 3), C_TEAL, "Step_NW_1")
|
|
||||||
_box_static(Vector3(-16, 1.5, -16), Vector3(3, 0.5, 3), C_TEAL, "Step_NW_2")
|
|
||||||
_box_static(Vector3(-20, 2.5, -20), Vector3(3, 0.5, 3), C_TEAL, "Step_NW_3")
|
|
||||||
_box_static(Vector3(-24, 3.5, -24), Vector3(3, 0.5, 3), C_TEAL, "Step_NW_4")
|
|
||||||
|
|
||||||
# Parkour chain: SE quadrant
|
|
||||||
_box_static(Vector3(12, 0.6, 12), Vector3(3, 1.2, 3), C_TEAL, "Step_SE_1")
|
|
||||||
_box_static(Vector3(16, 1.5, 16), Vector3(3, 0.5, 3), C_TEAL, "Step_SE_2")
|
|
||||||
_box_static(Vector3(20, 2.5, 20), Vector3(3, 0.5, 3), C_TEAL, "Step_SE_3")
|
|
||||||
_box_static(Vector3(24, 3.5, 24), Vector3(3, 0.5, 3), C_TEAL, "Step_SE_4")
|
|
||||||
|
|
||||||
# Parkour chain: NE quadrant (lower, for double-jump practice)
|
|
||||||
_box_static(Vector3(12, 0.6, -12), Vector3(3, 1.2, 3), C_PURPLE, "Step_NE_1")
|
|
||||||
_box_static(Vector3(16, 2.0, -16), Vector3(2.5, 0.5, 2.5), C_PURPLE, "Step_NE_2")
|
|
||||||
_box_static(Vector3(20, 3.5, -20), Vector3(2.5, 0.5, 2.5), C_PURPLE, "Step_NE_3")
|
|
||||||
|
|
||||||
# Parkour chain: SW quadrant
|
|
||||||
_box_static(Vector3(-12, 0.6, 12), Vector3(3, 1.2, 3), C_PURPLE, "Step_SW_1")
|
|
||||||
_box_static(Vector3(-16, 2.0, 16), Vector3(2.5, 0.5, 2.5), C_PURPLE, "Step_SW_2")
|
|
||||||
_box_static(Vector3(-20, 3.5, 20), Vector3(2.5, 0.5, 2.5), C_PURPLE, "Step_SW_3")
|
|
||||||
|
|
||||||
|
|
||||||
# ── Wall-Run Surfaces ────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
func _build_wall_run_surfaces() -> void:
|
|
||||||
# Dedicated wall-run corridor (North side, between walkway and north wall)
|
|
||||||
# Left wall
|
|
||||||
_box_static(Vector3(-8, 6, -38), Vector3(0.5, 12, 16), C_WALLRUN, "WallRunWall_L")
|
|
||||||
# Right wall
|
|
||||||
_box_static(Vector3(8, 6, -38), Vector3(0.5, 12, 16), C_WALLRUN, "WallRunWall_R")
|
|
||||||
|
|
||||||
# Obstacles in corridor to jump over
|
|
||||||
_box_static(Vector3(0, 0.75, -34), Vector3(16, 1.5, 1.0), C_RED, "WallRun_Obs1")
|
|
||||||
_box_static(Vector3(0, 0.75, -42), Vector3(16, 1.5, 1.0), C_RED, "WallRun_Obs2")
|
|
||||||
|
|
||||||
# Floor gap in corridor (forces wall-run)
|
|
||||||
_box_static(Vector3(-5, -0.75, -38), Vector3(6, 0.5, 16), C_FLOOR, "WallRun_Floor_L")
|
|
||||||
_box_static(Vector3(5, -0.75, -38), Vector3(6, 0.5, 16), C_FLOOR, "WallRun_Floor_R")
|
|
||||||
|
|
||||||
# Wall-run sections on outer walls (lower portions)
|
|
||||||
_box_static(Vector3(-40, 4, -47.5), Vector3(16, 8, 0.5), C_WALLRUN, "OuterWallRun_N1")
|
|
||||||
_box_static(Vector3(40, 4, -47.5), Vector3(16, 8, 0.5), C_WALLRUN, "OuterWallRun_N2")
|
|
||||||
_box_static(Vector3(-40, 4, 47.5), Vector3(16, 8, 0.5), C_WALLRUN, "OuterWallRun_S1")
|
|
||||||
_box_static(Vector3(40, 4, 47.5), Vector3(16, 8, 0.5), C_WALLRUN, "OuterWallRun_S2")
|
|
||||||
_box_static(Vector3(-47.5, 4, -40), Vector3(0.5, 8, 16), C_WALLRUN, "OuterWallRun_W1")
|
|
||||||
_box_static(Vector3(-47.5, 4, 40), Vector3(0.5, 8, 16), C_WALLRUN, "OuterWallRun_W2")
|
|
||||||
_box_static(Vector3(47.5, 4, -40), Vector3(0.5, 8, 16), C_WALLRUN, "OuterWallRun_E1")
|
|
||||||
_box_static(Vector3(47.5, 4, 40), Vector3(0.5, 8, 16), C_WALLRUN, "OuterWallRun_E2")
|
|
||||||
|
|
||||||
|
|
||||||
# ── Wall-Climb Surfaces ──────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
func _build_wall_climb_surfaces() -> void:
|
|
||||||
# Textured walls for wall-climbing (distinct warm color)
|
|
||||||
# Around central tower
|
|
||||||
_box_static(Vector3(-7, 4, 0), Vector3(0.5, 6, 6), C_WALLCLIMB, "WallClimb_C1")
|
|
||||||
_box_static(Vector3(7, 4, 0), Vector3(0.5, 6, 6), C_WALLCLIMB, "WallClimb_C2")
|
|
||||||
|
|
||||||
# Mid-map wall-climb walls
|
|
||||||
_box_static(Vector3(-24, 4, 0), Vector3(0.5, 8, 8), C_WALLCLIMB, "WallClimb_W")
|
|
||||||
_box_static(Vector3(24, 4, 0), Vector3(0.5, 8, 8), C_WALLCLIMB, "WallClimb_E")
|
|
||||||
|
|
||||||
|
|
||||||
# ── Grapple Anchors ───────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
func _build_grapple_anchors() -> void:
|
|
||||||
# Tall pillar structures that serve as grapple targets
|
|
||||||
# Each is a tall, visible pillar with a distinct top
|
|
||||||
var pillar_positions := [
|
|
||||||
Vector3(-30, 0, 0),
|
|
||||||
Vector3(30, 0, 0),
|
|
||||||
Vector3(0, 0, -30),
|
|
||||||
Vector3(0, 0, 30),
|
|
||||||
]
|
|
||||||
for i in range(pillar_positions.size()):
|
|
||||||
var pos: Vector3 = pillar_positions[i]
|
|
||||||
# Pillar shaft (15u tall)
|
|
||||||
_box_static(pos + Vector3(0, 7.5, 0), Vector3(2, 15, 2), C_METAL, "GrapplePillar_%d" % i)
|
|
||||||
# Pillar top (grapple target marker)
|
|
||||||
_box_static(pos + Vector3(0, 15.5, 0), Vector3(4, 1.0, 4), C_ACCENT_WARM, "GrappleTop_%d" % i)
|
|
||||||
# Pillar base
|
|
||||||
_box_static(pos + Vector3(0, 0.5, 0), Vector3(4, 1.0, 4), C_METAL_DARK, "GrappleBase_%d" % i)
|
|
||||||
|
|
||||||
|
|
||||||
# ── Cover System ──────────────────────────────────────────────────────────────
|
# ── Cover System ──────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
func _build_cover_system() -> void:
|
func _build_cover() -> void:
|
||||||
# Low walls (1.5u) for crouch cover - central area
|
# Low walls (1.5u high) for crouch cover — placed in open areas, not overlapping anything
|
||||||
_box_static(Vector3(-8, 0.75, -8), Vector3(5, 1.5, 0.5), C_WALL, "Cover_C1")
|
_box_static(Vector3(-12, 0.75, -12), Vector3(4, 1.5, 0.5), C_WALL, "Cover_NW")
|
||||||
_box_static(Vector3(8, 0.75, 8), Vector3(5, 1.5, 0.5), C_WALL, "Cover_C2")
|
_box_static(Vector3(12, 0.75, 12), Vector3(4, 1.5, 0.5), C_WALL, "Cover_SE")
|
||||||
_box_static(Vector3(-8, 0.75, 8), Vector3(0.5, 1.5, 5), C_WALL, "Cover_C3")
|
_box_static(Vector3(-12, 0.75, 12), Vector3(0.5, 1.5, 4), C_WALL, "Cover_SW")
|
||||||
_box_static(Vector3(8, 0.75, -8), Vector3(0.5, 1.5, 5), C_WALL, "Cover_C4")
|
_box_static(Vector3(12, 0.75, -12), Vector3(0.5, 1.5, 4), C_WALL, "Cover_NE")
|
||||||
|
|
||||||
# Crate clusters
|
# Mid-map corridor walls — create lanes without blocking movement
|
||||||
_crate(Vector3(-15, 0.6, 0))
|
_box_static(Vector3(-22, 2.0, -8), Vector3(12, 4.0, 0.4), C_WALL_DARK, "LaneWall_W")
|
||||||
_crate(Vector3(-15, 0.6, 1.4))
|
_box_static(Vector3(22, 2.0, 8), Vector3(12, 4.0, 0.4), C_WALL_DARK, "LaneWall_E")
|
||||||
_crate(Vector3(-15, 1.2, 0.7))
|
|
||||||
|
|
||||||
_crate(Vector3(15, 0.6, 0))
|
# Crate clusters — properly spaced, no overlaps
|
||||||
_crate(Vector3(15, 0.6, -1.4))
|
# NW cluster
|
||||||
_crate(Vector3(15, 1.2, -0.7))
|
_box_static(Vector3(-20, 0.6, -20), Vector3(1.2, 1.2, 1.2), C_CRATE, "Crate_NW1")
|
||||||
|
_box_static(Vector3(-20, 0.6, -21.5), Vector3(1.2, 1.2, 1.2), C_CRATE, "Crate_NW2")
|
||||||
|
_box_static(Vector3(-21.5, 0.6, -20), Vector3(1.2, 1.2, 1.2), C_CRATE, "Crate_NW3")
|
||||||
|
# SE cluster
|
||||||
|
_box_static(Vector3(20, 0.6, 20), Vector3(1.2, 1.2, 1.2), C_CRATE, "Crate_SE1")
|
||||||
|
_box_static(Vector3(20, 0.6, 21.5), Vector3(1.2, 1.2, 1.2), C_CRATE, "Crate_SE2")
|
||||||
|
_box_static(Vector3(21.5, 0.6, 20), Vector3(1.2, 1.2, 1.2), C_CRATE, "Crate_SE3")
|
||||||
|
# Center-side crates
|
||||||
|
_box_static(Vector3(-8, 0.6, 0), Vector3(1.2, 1.2, 1.2), C_CRATE, "Crate_C1")
|
||||||
|
_box_static(Vector3(8, 0.6, 0), Vector3(1.2, 1.2, 1.2), C_CRATE, "Crate_C2")
|
||||||
|
|
||||||
_crate(Vector3(0, 0.6, -15))
|
# Barrels — placed along walls, not blocking paths
|
||||||
_crate(Vector3(1.4, 0.6, -15))
|
_box_static(Vector3(-35, 0.5, -5), Vector3(0.8, 1.0, 0.8), Color(0.50, 0.45, 0.30), "Barrel_1")
|
||||||
_crate(Vector3(0.7, 1.2, -15))
|
_box_static(Vector3(-35, 0.5, 5), Vector3(0.8, 1.0, 0.8), Color(0.50, 0.45, 0.30), "Barrel_2")
|
||||||
|
_box_static(Vector3(35, 0.5, -5), Vector3(0.8, 1.0, 0.8), Color(0.50, 0.45, 0.30), "Barrel_3")
|
||||||
_crate(Vector3(0, 0.6, 15))
|
_box_static(Vector3(35, 0.5, 5), Vector3(0.8, 1.0, 0.8), Color(0.50, 0.45, 0.30), "Barrel_4")
|
||||||
_crate(Vector3(-1.4, 0.6, 15))
|
|
||||||
_crate(Vector3(-0.7, 1.2, 15))
|
|
||||||
|
|
||||||
# Corridor walls (create engagement lanes)
|
|
||||||
_box_static(Vector3(-20, 2.0, -10), Vector3(16, 4.0, 0.5), C_WALL_DARK, "LaneWall_W1")
|
|
||||||
_box_static(Vector3(-20, 2.0, 10), Vector3(16, 4.0, 0.5), C_WALL_DARK, "LaneWall_W2")
|
|
||||||
_box_static(Vector3(20, 2.0, -10), Vector3(16, 4.0, 0.5), C_WALL_DARK, "LaneWall_E1")
|
|
||||||
_box_static(Vector3(20, 2.0, 10), Vector3(16, 4.0, 0.5), C_WALL_DARK, "LaneWall_E2")
|
|
||||||
|
|
||||||
# Structural pillars (cover in open areas)
|
|
||||||
_pillar(Vector3(-14, 3.5, -14))
|
|
||||||
_pillar(Vector3(14, 3.5, -14))
|
|
||||||
_pillar(Vector3(-14, 3.5, 14))
|
|
||||||
_pillar(Vector3(14, 3.5, 14))
|
|
||||||
|
|
||||||
|
|
||||||
func _crate(pos: Vector3) -> void:
|
|
||||||
_place_prop(prop_crate, pos, "Crate")
|
|
||||||
|
|
||||||
|
|
||||||
func _pillar(pos: Vector3) -> void:
|
|
||||||
_place_prop(prop_pillar, pos, "Pillar")
|
|
||||||
|
|
||||||
|
|
||||||
# ── Speed Corridor ────────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
func _build_speed_corridor() -> void:
|
|
||||||
# Long straight for sprint -> slide -> bunny-hop chains
|
|
||||||
var corridor_color := C_DARK_GREEN
|
|
||||||
|
|
||||||
# Side rails
|
|
||||||
_box_static(Vector3(38, 2.0, -20), Vector3(0.4, 4, 30), corridor_color, "SpeedRail_L")
|
|
||||||
_box_static(Vector3(44, 2.0, -20), Vector3(0.4, 4, 30), corridor_color, "SpeedRail_R")
|
|
||||||
|
|
||||||
# Speed bumps
|
|
||||||
for i in range(-15, 16, 8):
|
|
||||||
_box_static(Vector3(41, 0.2, float(i)), Vector3(6, 0.4, 0.6), C_YELLOW, "SpeedBump_%d" % i)
|
|
||||||
|
|
||||||
# Floor markings
|
|
||||||
for i in range(-12, 13, 4):
|
|
||||||
_box_static(Vector3(41, 0.02, float(i)), Vector3(4, 0.02, 0.3), C_YELLOW, "SpeedMark_%d" % i)
|
|
||||||
|
|
||||||
|
|
||||||
# ── Spawn Alcoves ─────────────────────────────────────────────────────────────
|
# ── Spawn Alcoves ─────────────────────────────────────────────────────────────
|
||||||
# 6 spawns: 3 red (NW, SW, West-mid), 3 blue (NE, SE, East-mid)
|
# 4 spawns: 2 red (NW, SW), 2 blue (NE, SE)
|
||||||
# Each spawn is in a covered alcove with 2+ exit routes.
|
# Each spawn has 2 cover walls forming an L-shape, with 2 clear exit routes
|
||||||
|
|
||||||
func _build_spawn_alcoves() -> void:
|
func _build_spawn_alcoves() -> void:
|
||||||
# ── Red Spawns ──
|
var spawn_y := 0.01
|
||||||
|
|
||||||
# Red Spawn 1: NW corner
|
# Red Spawn 1: NW corner — L-wall on north and west sides
|
||||||
_spawn_floor(Vector3(-42, 0.01, -42), C_RED, "Spawn_Red_1")
|
_spawn_floor(Vector3(-35, spawn_y, -35), C_RED, "Spawn_Red_1")
|
||||||
_spawn_cover(Vector3(-40, 1.5, -45), Vector3(6, 3.0, 0.4), C_RED, "SpawnCover_R1A")
|
_spawn_cover(Vector3(-33, 1.5, -39.5), Vector3(6, 3.0, 0.4), C_RED, "SCover_R1A") # North wall
|
||||||
_spawn_cover(Vector3(-45, 1.5, -40), Vector3(0.4, 3.0, 6), C_RED, "SpawnCover_R1B")
|
_spawn_cover(Vector3(-39.5, 1.5, -33), Vector3(0.4, 3.0, 6), C_RED, "SCover_R1B") # West wall
|
||||||
_spawn_cover(Vector3(-38, 1.5, -38), Vector3(0.4, 3.0, 4), C_WALL_DARK, "SpawnCover_R1C")
|
# Exits: southeast (open)
|
||||||
|
|
||||||
# Red Spawn 2: SW corner
|
# Red Spawn 2: SW corner — L-wall on south and west sides
|
||||||
_spawn_floor(Vector3(-42, 0.01, 42), C_RED, "Spawn_Red_2")
|
_spawn_floor(Vector3(-35, spawn_y, 35), C_RED, "Spawn_Red_2")
|
||||||
_spawn_cover(Vector3(-40, 1.5, 45), Vector3(6, 3.0, 0.4), C_RED, "SpawnCover_R2A")
|
_spawn_cover(Vector3(-33, 1.5, 39.5), Vector3(6, 3.0, 0.4), C_RED, "SCover_R2A") # South wall
|
||||||
_spawn_cover(Vector3(-45, 1.5, 40), Vector3(0.4, 3.0, 6), C_RED, "SpawnCover_R2B")
|
_spawn_cover(Vector3(-39.5, 1.5, 33), Vector3(0.4, 3.0, 6), C_RED, "SCover_R2B") # West wall
|
||||||
_spawn_cover(Vector3(-38, 1.5, 38), Vector3(0.4, 3.0, 4), C_WALL_DARK, "SpawnCover_R2C")
|
# Exits: northeast (open)
|
||||||
|
|
||||||
# Red Spawn 3: West mid
|
# Blue Spawn 1: NE corner — L-wall on north and east sides
|
||||||
_spawn_floor(Vector3(-44, 0.01, 0), C_RED, "Spawn_Red_3")
|
_spawn_floor(Vector3(35, spawn_y, -35), C_BLUE, "Spawn_Blue_1")
|
||||||
_spawn_cover(Vector3(-42, 1.5, -3), Vector3(0.4, 3.0, 6), C_RED, "SpawnCover_R3A")
|
_spawn_cover(Vector3(33, 1.5, -39.5), Vector3(6, 3.0, 0.4), C_BLUE, "SCover_B1A") # North wall
|
||||||
_spawn_cover(Vector3(-42, 1.5, 3), Vector3(0.4, 3.0, 6), C_RED, "SpawnCover_R3B")
|
_spawn_cover(Vector3(39.5, 1.5, -33), Vector3(0.4, 3.0, 6), C_BLUE, "SCover_B1B") # East wall
|
||||||
_spawn_cover(Vector3(-40, 1.5, 0), Vector3(4, 3.0, 0.4), C_WALL_DARK, "SpawnCover_R3C")
|
# Exits: southwest (open)
|
||||||
|
|
||||||
# ── Blue Spawns ──
|
# Blue Spawn 2: SE corner — L-wall on south and east sides
|
||||||
|
_spawn_floor(Vector3(35, spawn_y, 35), C_BLUE, "Spawn_Blue_2")
|
||||||
# Blue Spawn 1: NE corner
|
_spawn_cover(Vector3(33, 1.5, 39.5), Vector3(6, 3.0, 0.4), C_BLUE, "SCover_B2A") # South wall
|
||||||
_spawn_floor(Vector3(42, 0.01, -42), C_BLUE, "Spawn_Blue_1")
|
_spawn_cover(Vector3(39.5, 1.5, 33), Vector3(0.4, 3.0, 6), C_BLUE, "SCover_B2B") # East wall
|
||||||
_spawn_cover(Vector3(40, 1.5, -45), Vector3(6, 3.0, 0.4), C_BLUE, "SpawnCover_B1A")
|
# Exits: northwest (open)
|
||||||
_spawn_cover(Vector3(45, 1.5, -40), Vector3(0.4, 3.0, 6), C_BLUE, "SpawnCover_B1B")
|
|
||||||
_spawn_cover(Vector3(38, 1.5, -38), Vector3(0.4, 3.0, 4), C_WALL_DARK, "SpawnCover_B1C")
|
|
||||||
|
|
||||||
# Blue Spawn 2: SE corner
|
|
||||||
_spawn_floor(Vector3(42, 0.01, 42), C_BLUE, "Spawn_Blue_2")
|
|
||||||
_spawn_cover(Vector3(40, 1.5, 45), Vector3(6, 3.0, 0.4), C_BLUE, "SpawnCover_B2A")
|
|
||||||
_spawn_cover(Vector3(45, 1.5, 40), Vector3(0.4, 3.0, 6), C_BLUE, "SpawnCover_B2B")
|
|
||||||
_spawn_cover(Vector3(38, 1.5, 38), Vector3(0.4, 3.0, 4), C_WALL_DARK, "SpawnCover_B2C")
|
|
||||||
|
|
||||||
# Blue Spawn 3: East mid
|
|
||||||
_spawn_floor(Vector3(44, 0.01, 0), C_BLUE, "Spawn_Blue_3")
|
|
||||||
_spawn_cover(Vector3(42, 1.5, -3), Vector3(0.4, 3.0, 6), C_BLUE, "SpawnCover_B3A")
|
|
||||||
_spawn_cover(Vector3(42, 1.5, 3), Vector3(0.4, 3.0, 6), C_BLUE, "SpawnCover_B3B")
|
|
||||||
_spawn_cover(Vector3(40, 1.5, 0), Vector3(4, 3.0, 0.4), C_WALL_DARK, "SpawnCover_B3C")
|
|
||||||
|
|
||||||
|
|
||||||
func _spawn_floor(pos: Vector3, color: Color, label: String) -> void:
|
func _spawn_floor(pos: Vector3, color: Color, label: String) -> void:
|
||||||
@@ -548,81 +264,27 @@ func _spawn_cover(pos: Vector3, size: Vector3, color: Color, label: String) -> v
|
|||||||
_box_static(pos, size, color, label)
|
_box_static(pos, size, color, label)
|
||||||
|
|
||||||
|
|
||||||
# ── Decorations ───────────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
func _build_decorations() -> void:
|
|
||||||
# Accent beams on outer walls
|
|
||||||
for i in range(-5, 6):
|
|
||||||
var z_pos := float(i) * 8.0
|
|
||||||
_box_static(Vector3(-47.5, 9.0, z_pos), Vector3(0.3, 0.3, 5.0), C_ACCENT_WARM, "AccentBeam_W_%d" % i)
|
|
||||||
_box_static(Vector3(47.5, 9.0, z_pos), Vector3(0.3, 0.3, 5.0), C_ACCENT_COOL, "AccentBeam_E_%d" % i)
|
|
||||||
|
|
||||||
# Hazard stripes on ramp edges
|
|
||||||
for i in range(4):
|
|
||||||
var offset := -2.5 + float(i) * 1.5
|
|
||||||
_box_static(Vector3(offset, 0.05, -17.8), Vector3(1.0, 0.1, 0.4), C_YELLOW, "Hazard_CN_%d" % i)
|
|
||||||
_box_static(Vector3(offset, 0.05, 17.8), Vector3(1.0, 0.1, 0.4), C_YELLOW, "Hazard_CS_%d" % i)
|
|
||||||
|
|
||||||
# Barrels
|
|
||||||
_barrel(Vector3(-30, 0.5, -5))
|
|
||||||
_barrel(Vector3(-30, 0.5, -6.5))
|
|
||||||
_barrel(Vector3(30, 0.5, 5))
|
|
||||||
_barrel(Vector3(30, 0.5, 6.5))
|
|
||||||
_barrel(Vector3(5, 0.5, -30))
|
|
||||||
_barrel(Vector3(-5, 0.5, 30))
|
|
||||||
_barrel(Vector3(-25, 0.5, 25))
|
|
||||||
_barrel(Vector3(25, 0.5, -25))
|
|
||||||
|
|
||||||
# Pickup props (GLB)
|
|
||||||
_place_prop(prop_weapon_pickup, Vector3(0, 0.05, -25), "WeaponPickup_Center")
|
|
||||||
_place_prop(prop_health_pack, Vector3(-20, 0.05, 0), "HealthPack_West")
|
|
||||||
_place_prop(prop_health_pack, Vector3(20, 0.05, 0), "HealthPack_East")
|
|
||||||
_place_prop(prop_ammo_pack, Vector3(0, 0.05, 25), "AmmoPack_Center")
|
|
||||||
_place_prop(prop_ammo_pack, Vector3(-35, 0.05, -35), "AmmoPack_NW")
|
|
||||||
_place_prop(prop_ammo_pack, Vector3(35, 0.05, 35), "AmmoPack_SE")
|
|
||||||
|
|
||||||
# Spawn area lights
|
|
||||||
_spawn_area_light(Vector3(-42, 3, -42), C_ACCENT_WARM, 6.0, 0.8)
|
|
||||||
_spawn_area_light(Vector3(-42, 3, 42), C_ACCENT_WARM, 6.0, 0.8)
|
|
||||||
_spawn_area_light(Vector3(-44, 3, 0), C_ACCENT_WARM, 6.0, 0.8)
|
|
||||||
_spawn_area_light(Vector3(42, 3, -42), C_ACCENT_COOL, 6.0, 0.8)
|
|
||||||
_spawn_area_light(Vector3(42, 3, 42), C_ACCENT_COOL, 6.0, 0.8)
|
|
||||||
_spawn_area_light(Vector3(44, 3, 0), C_ACCENT_COOL, 6.0, 0.8)
|
|
||||||
|
|
||||||
|
|
||||||
func _barrel(pos: Vector3) -> void:
|
|
||||||
_place_prop(prop_barrel, pos, "Barrel")
|
|
||||||
|
|
||||||
|
|
||||||
func _spawn_area_light(pos: Vector3, color: Color, radius: float, energy: float) -> void:
|
|
||||||
var light := OmniLight3D.new()
|
|
||||||
light.name = "SpawnLight"
|
|
||||||
light.position = pos
|
|
||||||
light.light_color = color
|
|
||||||
light.light_energy = energy
|
|
||||||
light.omni_range = radius
|
|
||||||
light.shadow_enabled = false
|
|
||||||
add_child(light)
|
|
||||||
|
|
||||||
|
|
||||||
# ── Dummies ───────────────────────────────────────────────────────────────────
|
# ── Dummies ───────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
func _build_target_dummy() -> void:
|
func _build_dummies() -> void:
|
||||||
|
# Target dummy — in open area south of center
|
||||||
var dummy = load("res://entities/target_dummy.gd").new()
|
var dummy = load("res://entities/target_dummy.gd").new()
|
||||||
dummy.name = "TargetDummy"
|
dummy.name = "TargetDummy"
|
||||||
dummy.position = Vector3(0, 0, -15)
|
dummy.position = Vector3(0, 0, -25)
|
||||||
add_child(dummy)
|
add_child(dummy)
|
||||||
|
|
||||||
|
# Killable dummy — in open area east of center
|
||||||
var killable = load("res://entities/killable_dummy.gd").new()
|
var killable = load("res://entities/killable_dummy.gd").new()
|
||||||
killable.name = "KillableDummy"
|
killable.name = "KillableDummy"
|
||||||
killable.position = Vector3(5, 0, -15)
|
killable.position = Vector3(25, 0, 0)
|
||||||
add_child(killable)
|
add_child(killable)
|
||||||
|
|
||||||
|
# Walking dummy — patrols along the south side
|
||||||
var walking = load("res://entities/walking_dummy.gd").new()
|
var walking = load("res://entities/walking_dummy.gd").new()
|
||||||
walking.name = "WalkingDummy"
|
walking.name = "WalkingDummy"
|
||||||
walking.position = Vector3(20, 0, -15)
|
walking.position = Vector3(-20, 0, -30)
|
||||||
walking.point_a = Vector3(20, 0, -15)
|
walking.point_a = Vector3(-20, 0, -30)
|
||||||
walking.point_b = Vector3(20, 0, 15)
|
walking.point_b = Vector3(20, 0, -30)
|
||||||
add_child(walking)
|
add_child(walking)
|
||||||
|
|
||||||
|
|
||||||
@@ -636,7 +298,7 @@ func _build_lighting() -> void:
|
|||||||
sun.light_energy = 1.2
|
sun.light_energy = 1.2
|
||||||
sun.shadow_enabled = true
|
sun.shadow_enabled = true
|
||||||
sun.directional_shadow_mode = DirectionalLight3D.SHADOW_PARALLEL_4_SPLITS
|
sun.directional_shadow_mode = DirectionalLight3D.SHADOW_PARALLEL_4_SPLITS
|
||||||
sun.directional_shadow_max_distance = 120.0
|
sun.directional_shadow_max_distance = 100.0
|
||||||
add_child(sun)
|
add_child(sun)
|
||||||
|
|
||||||
var fill := DirectionalLight3D.new()
|
var fill := DirectionalLight3D.new()
|
||||||
@@ -647,16 +309,6 @@ func _build_lighting() -> void:
|
|||||||
fill.shadow_enabled = false
|
fill.shadow_enabled = false
|
||||||
add_child(fill)
|
add_child(fill)
|
||||||
|
|
||||||
# Central area accent light
|
|
||||||
var center_light := OmniLight3D.new()
|
|
||||||
center_light.name = "CenterLight"
|
|
||||||
center_light.position = Vector3(0, 10, 0)
|
|
||||||
center_light.light_color = Color(0.9, 0.85, 0.7)
|
|
||||||
center_light.light_energy = 0.6
|
|
||||||
center_light.omni_range = 25.0
|
|
||||||
center_light.shadow_enabled = false
|
|
||||||
add_child(center_light)
|
|
||||||
|
|
||||||
|
|
||||||
# ── Player ────────────────────────────────────────────────────────────────────
|
# ── Player ────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
@@ -666,7 +318,7 @@ func _spawn_player(pid: int) -> CharacterBody3D:
|
|||||||
player.set_multiplayer_authority(pid)
|
player.set_multiplayer_authority(pid)
|
||||||
|
|
||||||
# Use a slightly random spawn position to avoid exact overlapping
|
# Use a slightly random spawn position to avoid exact overlapping
|
||||||
player.position = Vector3(randf_range(-2, 2), 2.0, randf_range(-2, 2))
|
player.position = Vector3(randf_range(-5, 5), 1.0, 20)
|
||||||
|
|
||||||
# Server Synchronizer (Host is the ground truth)
|
# Server Synchronizer (Host is the ground truth)
|
||||||
var server_sync = MultiplayerSynchronizer.new()
|
var server_sync = MultiplayerSynchronizer.new()
|
||||||
|
|||||||
Reference in New Issue
Block a user