39 lines
1.6 KiB
GDScript
39 lines
1.6 KiB
GDScript
class_name AnimalAppearance
|
|
extends RefCounted
|
|
## Disposable woodland identities, rebuilt from stable NPC IDs. No simulation RNG.
|
|
|
|
const CEL_SHADER := preload("res://world/presentation/materials/storybook_cel.gdshader")
|
|
const SPECIES: Array[StringName] = [&"fox", &"rabbit", &"badger", &"otter"]
|
|
const MODELS: Array[PackedScene] = [
|
|
preload("res://assets/storybook/fox.glb"),
|
|
preload("res://assets/storybook/rabbit.glb"),
|
|
preload("res://assets/storybook/badger.glb"),
|
|
preload("res://assets/storybook/otter.glb"),
|
|
]
|
|
const PARTS: Array[StringName] = [
|
|
&"Body", &"Head", &"Hair", &"ArmLeft", &"ArmRight", &"LegLeft", &"LegRight", &"Tail"
|
|
]
|
|
|
|
|
|
static func apply_to(root: Node3D, identity: int, npc_body := false) -> void:
|
|
var index := posmod(identity, MODELS.size())
|
|
var source := MODELS[index].instantiate()
|
|
var material := ShaderMaterial.new()
|
|
material.shader = CEL_SHADER
|
|
root.set_meta("animal_species", SPECIES[index])
|
|
for part in PARTS:
|
|
var source_mesh := source.find_child(String(part), true, false) as MeshInstance3D
|
|
var target_name := "MeshInstance3D" if npc_body and part == &"Body" else String(part)
|
|
var target := root.get_node(target_name) as MeshInstance3D
|
|
assert(source_mesh != null, "Missing Blender animation part: " + String(part))
|
|
target.mesh = source_mesh.mesh
|
|
target.material_override = material
|
|
source.free()
|
|
|
|
|
|
static func set_profession_color(root: Node3D, color: Color) -> void:
|
|
var body := root.get_node("MeshInstance3D") as MeshInstance3D
|
|
var material := body.material_override as ShaderMaterial
|
|
material.set_shader_parameter("coat_color", color)
|
|
material.set_shader_parameter("profession_tint", 0.28)
|