feat(biome): abyssal bioluminescent + glow blocks + abyssal jellyfish + particles
- BlockDatabase: GLOW_CORAL_CYAN(10), GLOW_CORAL_VIOLET(11), LAVA_VENT(12) with emission data - WorldGenerator: abyssal blocks at y<-40 (cyan 4%, violet 1%, vent 0.5% via 3D noise) - Chunk.gd: multi-surface mesh (solid + 3 emissive surfaces with StandardMaterial3D emission) - MobSpawner: abyssal jellyfish spawn when player y<-30, max 8 - AbyssalJellyfish: cyan fluo, slower, double damage (10), bioluminescent flash on attack - BioluminescentParticles: 200 cyan-green particles follow player, only emit in abyss Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
88
scripts/ambience/BioluminescentParticles.gd
Normal file
88
scripts/ambience/BioluminescentParticles.gd
Normal file
@@ -0,0 +1,88 @@
|
||||
extends GPUParticles3D
|
||||
|
||||
# Bioluminescent floating particles — only active in abyss zone (player y < -30)
|
||||
|
||||
const ABYSS_DEPTH_THRESHOLD: float = -30.0
|
||||
|
||||
var _player: Node3D = null
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
amount = 200
|
||||
lifetime = 12.0
|
||||
one_shot = false
|
||||
explosiveness = 0.0
|
||||
randomness = 1.0
|
||||
visibility_aabb = AABB(Vector3(-30, -25, -30), Vector3(60, 50, 60))
|
||||
|
||||
var process_mat := ParticleProcessMaterial.new()
|
||||
process_mat.emission_shape = ParticleProcessMaterial.EMISSION_SHAPE_BOX
|
||||
process_mat.emission_box_extents = Vector3(28.0, 20.0, 28.0)
|
||||
|
||||
process_mat.direction = Vector3(0.0, 1.0, 0.0)
|
||||
process_mat.spread = 120.0
|
||||
process_mat.initial_velocity_min = 0.0
|
||||
process_mat.initial_velocity_max = 0.08
|
||||
|
||||
process_mat.linear_accel_min = -0.03
|
||||
process_mat.linear_accel_max = 0.03
|
||||
process_mat.radial_accel_min = -0.02
|
||||
process_mat.radial_accel_max = 0.02
|
||||
|
||||
process_mat.damping_min = 0.4
|
||||
process_mat.damping_max = 0.9
|
||||
|
||||
process_mat.scale_min = 0.03
|
||||
process_mat.scale_max = 0.12
|
||||
|
||||
# Cyan-green bioluminescent color
|
||||
var grad := Gradient.new()
|
||||
grad.set_color(0, Color(0.0, 0.8, 0.9, 0.0))
|
||||
grad.set_color(1, Color(0.0, 0.8, 0.9, 0.0))
|
||||
grad.add_point(0.1, Color(0.1, 0.9, 0.8, 0.7))
|
||||
grad.add_point(0.85, Color(0.2, 0.7, 1.0, 0.6))
|
||||
var grad_tex := GradientTexture1D.new()
|
||||
grad_tex.gradient = grad
|
||||
process_mat.color_ramp = grad_tex
|
||||
process_mat.color = Color(0.1, 0.9, 0.8, 0.7)
|
||||
|
||||
process_material = process_mat
|
||||
|
||||
var quad := QuadMesh.new()
|
||||
quad.size = Vector2(0.08, 0.08)
|
||||
|
||||
var mat := StandardMaterial3D.new()
|
||||
mat.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED
|
||||
mat.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA
|
||||
mat.billboard_mode = BaseMaterial3D.BILLBOARD_ENABLED
|
||||
mat.emission_enabled = true
|
||||
mat.emission = Color(0.2, 0.8, 1.0)
|
||||
mat.emission_energy_multiplier = 3.0
|
||||
mat.albedo_color = Color(0.1, 0.9, 0.8, 0.7)
|
||||
|
||||
quad.surface_set_material(0, mat)
|
||||
draw_pass_1 = quad
|
||||
|
||||
# Start inactive until we detect depth
|
||||
emitting = false
|
||||
_find_player()
|
||||
|
||||
|
||||
func _find_player() -> void:
|
||||
var players := get_tree().get_nodes_in_group("player")
|
||||
if players.size() > 0:
|
||||
_player = players[0] as Node3D
|
||||
|
||||
|
||||
func _process(_delta: float) -> void:
|
||||
if _player == null:
|
||||
_find_player()
|
||||
return
|
||||
|
||||
var in_abyss: bool = _player.global_position.y < ABYSS_DEPTH_THRESHOLD
|
||||
if in_abyss != emitting:
|
||||
emitting = in_abyss
|
||||
|
||||
# Follow player horizontally, float at player depth
|
||||
if in_abyss:
|
||||
global_position = _player.global_position
|
||||
Reference in New Issue
Block a user