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