Compare commits
2 Commits
whitleands
...
97bbca95e8
| Author | SHA1 | Date | |
|---|---|---|---|
| 97bbca95e8 | |||
| 2b1370bd40 |
@@ -15,8 +15,8 @@ var _enable_state_machine: bool = true
|
||||
@export var anim_player: AnimationPlayer
|
||||
|
||||
@export_group("Entities")
|
||||
enum EntityType { HUMANOID, ANIMAL }
|
||||
@export var entity_type: EntityType = EntityType.HUMANOID
|
||||
enum EntityType { FARMER, CITIZEN_WALKER, CITIZEN_SITTER, CAT, CROW, FOX, GOAT, RACOON, WAGYU }
|
||||
@export var entity_type: EntityType = EntityType.FARMER
|
||||
@export var entity_name: String = ""
|
||||
@export var allowed_biomes: Array[String] = []
|
||||
@export_range(0.0, 100.0, 0.1) var spawn_uniqueness: float = 1.0
|
||||
|
||||
38
core/ai/agents/cat/ai_cat.gd
Normal file
38
core/ai/agents/cat/ai_cat.gd
Normal file
@@ -0,0 +1,38 @@
|
||||
extends AIBase
|
||||
|
||||
class_name AICat
|
||||
|
||||
@export_group("Cat Colors")
|
||||
@export var mesh: MeshInstance3D
|
||||
@export var fur_colors: Array[Color] = []
|
||||
@export var eye_colors: Array[Color] = []
|
||||
|
||||
@export var fur_material_index: int = 0
|
||||
@export var eye_material_index: int = 1
|
||||
|
||||
func _ready() -> void:
|
||||
super._ready()
|
||||
_apply_random_color()
|
||||
|
||||
func _apply_random_color() -> void:
|
||||
if fur_colors.is_empty() or eye_colors.is_empty():
|
||||
return
|
||||
|
||||
if not mesh or not mesh.mesh:
|
||||
return
|
||||
|
||||
var max_index = min(fur_colors.size(), eye_colors.size())
|
||||
var random_idx = randi() % max_index
|
||||
|
||||
_override_material_color(mesh, fur_material_index, fur_colors[random_idx])
|
||||
_override_material_color(mesh, eye_material_index, eye_colors[random_idx])
|
||||
|
||||
func _override_material_color(mesh_node: MeshInstance3D, surface_idx: int, color: Color) -> void:
|
||||
if surface_idx < 0 or surface_idx >= mesh_node.mesh.get_surface_count():
|
||||
return
|
||||
|
||||
var mat = mesh_node.mesh.surface_get_material(surface_idx)
|
||||
if mat and mat is StandardMaterial3D:
|
||||
var new_mat = mat.duplicate() as StandardMaterial3D
|
||||
new_mat.albedo_color = color
|
||||
mesh_node.set_surface_override_material(surface_idx, new_mat)
|
||||
1
core/ai/agents/cat/ai_cat.gd.uid
Normal file
1
core/ai/agents/cat/ai_cat.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://cx67xas1hxv3x
|
||||
@@ -2,12 +2,20 @@
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://clx701xdwelgx" path="res://core/ai/agents/base/ai_base.tscn" id="1_85o24"]
|
||||
[ext_resource type="Script" uid="uid://d3hy70ec8vqo5" path="res://core/ai/framework/run_animation_state.gd" id="2_6mu8r"]
|
||||
[ext_resource type="Script" uid="uid://cx67xas1hxv3x" path="res://core/ai/agents/cat/ai_cat.gd" id="2_cat_script"]
|
||||
[ext_resource type="PackedScene" uid="uid://c5rccx22gs6jt" path="res://core/ai/agents/cat/Cat_rig.fbx" id="2_rohxe"]
|
||||
[ext_resource type="Script" uid="uid://bngfthvt04ivv" path="res://core/ai/framework/patrol_state.gd" id="3_0jm3k"]
|
||||
[ext_resource type="Script" uid="uid://dty1p02kqviwf" path="res://core/ai/framework/sit_state.gd" id="3_scd7t"]
|
||||
|
||||
[node name="AiCat" unique_id=1228675528 node_paths=PackedStringArray("anim_player") instance=ExtResource("1_85o24")]
|
||||
[node name="AiCat" unique_id=1228675528 node_paths=PackedStringArray("mesh", "anim_player") instance=ExtResource("1_85o24")]
|
||||
script = ExtResource("2_cat_script")
|
||||
mesh = NodePath("Cat_rig/Rig_Cat/Skeleton3D/Cat")
|
||||
fur_colors = Array[Color]([])
|
||||
eye_colors = Array[Color]([])
|
||||
fur_material_index = 0
|
||||
eye_material_index = 1
|
||||
anim_player = NodePath("Cat_rig/AnimationPlayer")
|
||||
entity_type = 1
|
||||
entity_type = 3
|
||||
entity_name = "Cat"
|
||||
|
||||
[node name="StateMachine" parent="." index="1" unique_id=1286404264 node_paths=PackedStringArray("initial_state")]
|
||||
@@ -17,9 +25,16 @@ initial_state = NodePath("IdleState")
|
||||
script = ExtResource("2_6mu8r")
|
||||
state_id = &"idle"
|
||||
next_state_id = &"patrol"
|
||||
random_next_state_ids = Array[StringName]([&"patrol", &"sit"])
|
||||
animation_name = "Cat_Idle"
|
||||
|
||||
[node name="PatrolState" type="Node" parent="StateMachine" index="1" unique_id=1861645340]
|
||||
[node name="SitState" type="Node" parent="StateMachine" index="1" unique_id=860354787]
|
||||
script = ExtResource("3_scd7t")
|
||||
state_id = &"sit"
|
||||
next_state_id = &"idle"
|
||||
animation_name = "Cat_Sit"
|
||||
|
||||
[node name="PatrolState" type="Node" parent="StateMachine" index="2" unique_id=1861645340]
|
||||
script = ExtResource("3_0jm3k")
|
||||
state_id = &"patrol"
|
||||
next_state_id = &"idle"
|
||||
@@ -28,7 +43,7 @@ exit_on_action_finished = true
|
||||
|
||||
[node name="Cat_rig" parent="." index="3" unique_id=1332997618 instance=ExtResource("2_rohxe")]
|
||||
|
||||
[node name="Skeleton3D" parent="Cat_rig/Rig_Cat" parent_id_path=PackedInt32Array(1332997618, 1292226211) index="0" unique_id=807490174]
|
||||
[node name="Skeleton3D" parent="Cat_rig/Rig_Cat" parent_id_path=PackedInt32Array(1332997618, 656824407) index="0" unique_id=1952223098]
|
||||
bones/1/position = Vector3(1.6719584e-08, 0.23547882, 0.34218493)
|
||||
bones/1/rotation = Quaternion(0.12769094, -0.6954821, -0.12769029, 0.69548184)
|
||||
bones/2/rotation = Quaternion(-1.5819447e-07, -1.9079575e-07, -0.5904159, 0.8070992)
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
[node name="AiCrow" unique_id=1228675528 node_paths=PackedStringArray("anim_player") instance=ExtResource("1_tx3nx")]
|
||||
anim_player = NodePath("Crow_rig/AnimationPlayer")
|
||||
entity_type = 4
|
||||
entity_name = "Crow"
|
||||
|
||||
[node name="StateMachine" parent="." index="1" unique_id=1286404264 node_paths=PackedStringArray("initial_state")]
|
||||
initial_state = NodePath("WaitTrainState")
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
|
||||
[node name="AiFox" unique_id=1228675528 node_paths=PackedStringArray("anim_player") instance=ExtResource("1_m3efo")]
|
||||
anim_player = NodePath("Fox_rig/AnimationPlayer")
|
||||
entity_type = 5
|
||||
entity_name = "Fox"
|
||||
|
||||
[node name="StateMachine" parent="." index="1" unique_id=1286404264 node_paths=PackedStringArray("initial_state")]
|
||||
initial_state = NodePath("IdleState")
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
[node name="AiGoat" unique_id=1228675528 node_paths=PackedStringArray("anim_player") instance=ExtResource("1_f7hhh")]
|
||||
anim_player = NodePath("Goat_rig/AnimationPlayer")
|
||||
entity_type = 6
|
||||
entity_name = "Goat"
|
||||
|
||||
[node name="StateMachine" parent="." index="1" unique_id=1286404264 node_paths=PackedStringArray("initial_state")]
|
||||
initial_state = NodePath("IdleState")
|
||||
@@ -26,7 +28,7 @@ exit_on_action_finished = true
|
||||
|
||||
[node name="Goat_rig" parent="." index="3" unique_id=1336829719 instance=ExtResource("2_oxwbf")]
|
||||
|
||||
[node name="Skeleton3D" parent="Goat_rig/Rig_Goat" parent_id_path=PackedInt32Array(1336829719, 1896192446) index="0" unique_id=1573667924]
|
||||
[node name="Skeleton3D" parent="Goat_rig/Rig_Goat" parent_id_path=PackedInt32Array(1336829719, 123281310) index="0" unique_id=1526518923]
|
||||
bones/1/position = Vector3(-8.352713e-09, 0.36986786, 0.8951362)
|
||||
bones/1/rotation = Quaternion(0.1276911, -0.695482, -0.12769035, 0.69548184)
|
||||
bones/2/rotation = Quaternion(-8.7811394e-08, -9.458198e-08, -0.5904155, 0.80709946)
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
[ext_resource type="PackedScene" uid="uid://bdqeshcwwnyc4" path="res://core/ai/agents/human/ai_citizen.tscn" id="1_cduuu"]
|
||||
|
||||
[node name="AiCitizenSitter" unique_id=1228675528 instance=ExtResource("1_cduuu")]
|
||||
entity_type = 2
|
||||
entity_name = "CitizenSitter"
|
||||
|
||||
[node name="Skeleton3D" parent="BaseMesh/BaseMesh" parent_id_path=PackedInt32Array(1846171523, 1142246531) index="0" unique_id=928995817]
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
[ext_resource type="Script" uid="uid://bngfthvt04ivv" path="res://core/ai/framework/patrol_state.gd" id="3_8d0tj"]
|
||||
|
||||
[node name="AiCitizenWalker" unique_id=1228675528 instance=ExtResource("1_dms8s")]
|
||||
entity_type = 1
|
||||
entity_name = "CitizenWalker"
|
||||
|
||||
[node name="StateMachine" parent="." index="1" unique_id=1286404264 node_paths=PackedStringArray("initial_state")]
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
[ext_resource type="Script" uid="uid://d3hy70ec8vqo5" path="res://core/ai/framework/run_animation_state.gd" id="4_2oda6"]
|
||||
|
||||
[node name="AiFarmer" unique_id=1228675528 instance=ExtResource("1_l2y7m")]
|
||||
entity_type = 0
|
||||
entity_name = "Farmer"
|
||||
allowed_biomes = Array[String](["countryside"])
|
||||
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
[node name="AiRacoon" unique_id=1228675528 node_paths=PackedStringArray("anim_player") instance=ExtResource("1_seif5")]
|
||||
anim_player = NodePath("Raccoon_rig/AnimationPlayer")
|
||||
entity_type = 7
|
||||
entity_name = "Racoon"
|
||||
|
||||
[node name="StateMachine" parent="." index="1" unique_id=1286404264 node_paths=PackedStringArray("initial_state")]
|
||||
initial_state = NodePath("IdleState")
|
||||
@@ -26,7 +28,7 @@ exit_on_action_finished = true
|
||||
|
||||
[node name="Raccoon_rig" parent="." index="3" unique_id=338211330 instance=ExtResource("2_obtl0")]
|
||||
|
||||
[node name="Skeleton3D" parent="Raccoon_rig/Rig_Raccoon" parent_id_path=PackedInt32Array(338211330, 1484615769) index="0" unique_id=689430915]
|
||||
[node name="Skeleton3D" parent="Raccoon_rig/Rig_Raccoon" parent_id_path=PackedInt32Array(338211330, 590893883) index="0" unique_id=1830599374]
|
||||
bones/1/position = Vector3(2.0224038e-08, 0.20926544, 0.2908604)
|
||||
bones/1/rotation = Quaternion(0.12769087, -0.6954821, -0.12769023, 0.69548184)
|
||||
bones/1/scale = Vector3(1, 0.99999994, 0.99999994)
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
[node name="AiWagyu" unique_id=1228675528 node_paths=PackedStringArray("anim_player") instance=ExtResource("1_01jto")]
|
||||
anim_player = NodePath("Wagyu_rig/AnimationPlayer")
|
||||
entity_type = 1
|
||||
entity_type = 8
|
||||
entity_name = "Wagyu"
|
||||
|
||||
[node name="StateMachine" parent="." index="1" unique_id=1286404264 node_paths=PackedStringArray("initial_state")]
|
||||
|
||||
40
core/ai/framework/sit_state.gd
Normal file
40
core/ai/framework/sit_state.gd
Normal file
@@ -0,0 +1,40 @@
|
||||
extends State
|
||||
|
||||
class_name SitState
|
||||
|
||||
var reverse: bool = false
|
||||
|
||||
func enter() -> void:
|
||||
reverse = false
|
||||
super.enter()
|
||||
|
||||
if agent.anim_player and not agent.anim_player.animation_finished.is_connected(_on_animation_finished):
|
||||
agent.anim_player.animation_finished.connect(_on_animation_finished)
|
||||
|
||||
if runtime_timer and not runtime_timer.is_stopped():
|
||||
runtime_timer.stop()
|
||||
|
||||
run_animation()
|
||||
|
||||
func exit() -> void:
|
||||
super.exit()
|
||||
if agent.anim_player and agent.anim_player.animation_finished.is_connected(_on_animation_finished):
|
||||
agent.anim_player.animation_finished.disconnect(_on_animation_finished)
|
||||
|
||||
func _on_animation_finished(anim_name: StringName) -> void:
|
||||
if animation_name == anim_name:
|
||||
if not reverse:
|
||||
if min_wait_time > 0:
|
||||
var wait_time := randf_range(min_wait_time, max_wait_time)
|
||||
runtime_timer.start(wait_time)
|
||||
else:
|
||||
_on_timer_timeout()
|
||||
else:
|
||||
transitioned.emit(self, get_next_state())
|
||||
|
||||
func _on_timer_timeout() -> void:
|
||||
reverse = true
|
||||
if agent.anim_player and agent.anim_player.has_animation(animation_name):
|
||||
agent.anim_player.play_backwards(animation_name, blend_time)
|
||||
else:
|
||||
transitioned.emit(self, get_next_state())
|
||||
1
core/ai/framework/sit_state.gd.uid
Normal file
1
core/ai/framework/sit_state.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://dty1p02kqviwf
|
||||
@@ -4,11 +4,6 @@ extends Node3D
|
||||
const CHUNK_TYPE_BIOME: int = 0
|
||||
const CHUNK_TYPE_STRAIGHT_TRACK: int = 1
|
||||
const CHUNK_TYPE_CURVED_TRACK: int = 2
|
||||
const ENTITY_TYPE_HUMANOID: int = 0
|
||||
const ENTITY_TYPE_ANIMAL: int = 1
|
||||
const ENTITY_SPAWN_ANY: int = 0
|
||||
const ENTITY_SPAWN_HUMANOID_ONLY: int = 1
|
||||
const ENTITY_SPAWN_ANIMAL_ONLY: int = 2
|
||||
|
||||
const CHUNK_GENERATION_FRAME_BUDGET_USEC: int = 1000 #2 ms/frame to generate chunks
|
||||
const CHUNK_CLEANUP_FRAME_BUDGET_USEC: int = 1000 #1 ms/frame per cleanup
|
||||
@@ -922,11 +917,10 @@ func _spawn_entities_for_chunk(root: Node, biome_name: String) -> void:
|
||||
|
||||
func _get_spawn_point_type_filter(spawn_point: Node) -> int:
|
||||
if "allowed_type" in spawn_point:
|
||||
match spawn_point.allowed_type:
|
||||
ENTITY_SPAWN_HUMANOID_ONLY:
|
||||
return ENTITY_TYPE_HUMANOID
|
||||
ENTITY_SPAWN_ANIMAL_ONLY:
|
||||
return ENTITY_TYPE_ANIMAL
|
||||
if spawn_point.allowed_type == 0:
|
||||
return -1
|
||||
else:
|
||||
return spawn_point.allowed_type - 1
|
||||
return -1
|
||||
|
||||
func _pick_compatible_entity(biome_name: String, type_filter: int) -> PackedScene:
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
extends Marker3D
|
||||
class_name EntitySpawnPoint
|
||||
|
||||
enum AllowedType { ANY, HUMANOID_ONLY, ANIMAL_ONLY }
|
||||
enum AllowedType { ANY, FARMER, CITIZEN_WALKER, CITIZEN_SITTER, CAT, CROW, FOX, GOAT, RACOON, WAGYU }
|
||||
|
||||
@export var allowed_type: AllowedType = AllowedType.ANY
|
||||
@export_range(0.0, 1.0, 0.01) var spawn_chance: float = 1.0
|
||||
|
||||
Reference in New Issue
Block a user