Unveränderter Ausgangsstand inklusive Masterprompt und Konzeptbildern unter assets/. .godot/ und docs/screenshots/ bleiben laut .gitignore unversioniert; letztere sind unter ../backups gesichert. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
81 lines
3 KiB
GDScript
81 lines
3 KiB
GDScript
extends Node3D
|
|
## The environment has no colliders: board coordinates remain the gameplay source.
|
|
const TerrainMaterial = preload("res://scripts/presentation/sanctuary.gdshader")
|
|
const WaterMaterial = preload("res://scripts/presentation/river.gdshader")
|
|
const Stone = preload("res://assets/materials/phase10/limestone-albedo.png")
|
|
var _materials: Dictionary = {}
|
|
|
|
func _ready() -> void:
|
|
name = "VerdantRift"
|
|
var landscape: Node3D = preload("res://assets/environment/verdant-rift.glb").instantiate()
|
|
add_child(landscape)
|
|
_decorate(landscape)
|
|
var river := MeshInstance3D.new()
|
|
river.name = "LivingRiver"
|
|
var surface := PlaneMesh.new()
|
|
surface.size = Vector2(180.0, 180.0)
|
|
surface.subdivide_width = 1
|
|
surface.subdivide_depth = 1
|
|
river.mesh = surface
|
|
river.position.y = -3.7
|
|
var water := ShaderMaterial.new()
|
|
water.shader = WaterMaterial
|
|
river.material_override = water
|
|
add_child(river)
|
|
# The embers are deliberately sparse and never cover board cell indicators.
|
|
var motes := GPUParticles3D.new()
|
|
motes.name = "SanctuaryMotes"
|
|
motes.amount = 75
|
|
motes.lifetime = 12
|
|
motes.visibility_aabb = AABB(Vector3(-32,-5,-34), Vector3(64,18,68))
|
|
var motion := ParticleProcessMaterial.new()
|
|
motion.emission_shape = ParticleProcessMaterial.EMISSION_SHAPE_BOX
|
|
motion.emission_box_extents = Vector3(24,1,28)
|
|
motion.gravity = Vector3(.02,.045,.015)
|
|
motion.initial_velocity_min = .01
|
|
motion.initial_velocity_max = .12
|
|
motion.scale_min = .013
|
|
motion.scale_max = .035
|
|
motes.process_material = motion
|
|
var mote := SphereMesh.new()
|
|
mote.radius = 1
|
|
mote.height = 2
|
|
mote.radial_segments = 6
|
|
mote.rings = 3
|
|
var light := StandardMaterial3D.new()
|
|
light.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED
|
|
light.albedo_color = Color("c6d7a0")
|
|
light.emission_enabled = true
|
|
light.emission = Color("b3c985")
|
|
light.emission_energy_multiplier = 1.5
|
|
mote.material = light
|
|
motes.draw_pass_1 = mote
|
|
add_child(motes)
|
|
|
|
func _decorate(node: Node) -> void:
|
|
if node is MeshInstance3D:
|
|
for surface: int in range(node.mesh.get_surface_count()):
|
|
var source: StandardMaterial3D = node.mesh.surface_get_material(surface)
|
|
if source == null:
|
|
continue
|
|
var key: String = source.resource_name
|
|
if "teal" in key or "coral" in key or "brass" in key:
|
|
continue
|
|
if not _materials.has(key):
|
|
_materials[key] = terrain_material(source)
|
|
node.set_surface_override_material(surface, _materials[key])
|
|
for child: Node in node.get_children():
|
|
_decorate(child)
|
|
|
|
## Shared Kluft surface for ENV_* materials; also used by the menu diorama.
|
|
static func terrain_material(source: StandardMaterial3D) -> ShaderMaterial:
|
|
var key: String = source.resource_name
|
|
var material := ShaderMaterial.new()
|
|
material.shader = TerrainMaterial
|
|
material.set_shader_parameter("base_color", source.albedo_color)
|
|
material.set_shader_parameter("stone_map", Stone)
|
|
material.set_shader_parameter("foliage", "leaf" in key)
|
|
material.set_shader_parameter("bark", "bark" in key)
|
|
material.set_shader_parameter("soil", "soil" in key)
|
|
material.set_shader_parameter("paving", "paving" in key)
|
|
return material
|