Files

134 lines
4.2 KiB
GDScript

class_name StylizedBerryPatch
extends ResourceAmountVisual
const WIND_SHADER := preload("res://world/jajce/materials/wind.gdshader")
const LEAF_POSITIONS := [
Vector3(-0.52, 0.42, 0.08),
Vector3(0.08, 0.48, -0.14),
Vector3(0.58, 0.4, 0.18),
Vector3(-0.18, 0.7, 0.18),
Vector3(0.38, 0.67, -0.22),
]
const LEAF_SCALES := [
Vector3(0.72, 0.38, 0.62),
Vector3(0.78, 0.44, 0.68),
Vector3(0.66, 0.36, 0.58),
Vector3(0.56, 0.32, 0.52),
Vector3(0.5, 0.28, 0.46),
]
const BERRY_POSITIONS := [
Vector3(-0.7, 0.64, 0.2),
Vector3(-0.43, 0.82, -0.34),
Vector3(-0.14, 0.7, 0.46),
Vector3(0.08, 0.88, -0.08),
Vector3(0.34, 0.7, 0.42),
Vector3(0.48, 0.86, -0.3),
Vector3(0.74, 0.6, 0.12),
Vector3(-0.02, 1.02, 0.22),
]
func _ready() -> void:
add_to_group("interactive_foliage")
_build_leaves()
_build_berries()
super()
func set_contact_field(texture: Texture2D, world_rect: Vector4, enabled: bool) -> void:
for child in [$Leaves, $Berries]:
var material := (child as MultiMeshInstance3D).multimesh.mesh.material as ShaderMaterial
material.set_shader_parameter("foliage_trail_map", texture)
material.set_shader_parameter("foliage_trail_rect", world_rect)
material.set_shader_parameter("foliage_trails_enabled", enabled)
material.set_shader_parameter("contact_root", global_position)
func set_contact_actors(positions: PackedVector3Array, count: int) -> void:
for child in [$Leaves, $Berries]:
var material := (child as MultiMeshInstance3D).multimesh.mesh.material as ShaderMaterial
material.set_shader_parameter("interactor_count", count)
material.set_shader_parameter("interactor_positions", positions)
func get_presentation_instance_count() -> int:
return LEAF_POSITIONS.size() + BERRY_POSITIONS.size()
func get_visible_leaf_count() -> int:
return $Leaves.multimesh.visible_instance_count
func get_visible_berry_count() -> int:
return $Berries.multimesh.visible_instance_count
func _apply_resource_amount_visual(
_amount_remaining: float, remaining_ratio: float, tier: AmountTier
) -> void:
var visible_leaves := LEAF_POSITIONS.size()
if tier == AmountTier.LOW:
visible_leaves = 3
elif tier == AmountTier.DEPLETED:
visible_leaves = 2
$Leaves.multimesh.visible_instance_count = visible_leaves
var visible_berries := ceili(remaining_ratio * BERRY_POSITIONS.size())
if tier == AmountTier.DEPLETED:
visible_berries = 0
$Berries.multimesh.visible_instance_count = visible_berries
func _build_leaves() -> void:
var mesh := SphereMesh.new()
mesh.radius = 1.0
mesh.height = 2.0
mesh.radial_segments = 9
mesh.rings = 5
var material := ShaderMaterial.new()
material.shader = WIND_SHADER
material.set_shader_parameter("albedo", Color("#426c32"))
material.set_shader_parameter("roughness", 0.92)
material.set_shader_parameter("wind_strength", 0.045)
material.set_shader_parameter("wind_speed", 0.48)
material.set_shader_parameter("wind_phase", 1.7)
material.set_shader_parameter("contact_strength", 0.55)
mesh.material = material
var transforms: Array[Transform3D] = []
for index in LEAF_POSITIONS.size():
transforms.append(
Transform3D(Basis.IDENTITY.scaled(LEAF_SCALES[index]), LEAF_POSITIONS[index])
)
$Leaves.multimesh = _create_multimesh(mesh, transforms)
func _build_berries() -> void:
var mesh := SphereMesh.new()
mesh.radius = 0.12
mesh.height = 0.21
mesh.radial_segments = 8
mesh.rings = 4
var material := ShaderMaterial.new()
material.shader = WIND_SHADER
material.set_shader_parameter("albedo", Color("#8f3148"))
material.set_shader_parameter("roughness", 0.78)
material.set_shader_parameter("wind_strength", 0.012)
material.set_shader_parameter("wind_speed", 0.48)
material.set_shader_parameter("wind_phase", 1.7)
material.set_shader_parameter("contact_strength", 0.55)
mesh.material = material
var transforms: Array[Transform3D] = []
for position in BERRY_POSITIONS:
transforms.append(Transform3D(Basis.IDENTITY, position))
$Berries.multimesh = _create_multimesh(mesh, transforms)
func _create_multimesh(mesh: Mesh, transforms: Array) -> MultiMesh:
var multimesh := MultiMesh.new()
multimesh.transform_format = MultiMesh.TRANSFORM_3D
multimesh.mesh = mesh
multimesh.instance_count = transforms.size()
for index in transforms.size():
multimesh.set_instance_transform(index, transforms[index])
return multimesh