Add portable RV homes and decor prototype

This commit is contained in:
Alexander Sellite 2026-08-30 21:37:26 -04:00
parent 81decf2b71
commit fe099f47dd
56 changed files with 5459 additions and 112 deletions

View file

@ -0,0 +1,2 @@
class_name DecorShopInteraction
extends FishingShopInteraction

View file

@ -0,0 +1 @@
uid://u70jgwedk7ym

View file

@ -9,6 +9,9 @@ const FishingShopInteractionType = preload(
const PlayerStorageInteractionType = preload(
"res://world/player_storage_interaction.gd"
)
const DecorShopInteractionType = preload(
"res://world/decor_shop_interaction.gd"
)
const PrecipitationOcclusionType = preload(
"res://world/environment/precipitation_occlusion.gd"
)
@ -80,8 +83,12 @@ const PROCEDURAL_PROP_GROUPS: Array[StringName] = [
@onready var _player_storage: PlayerStorageInteractionType = (
$Interactables/PlayerStorageBox/InteractionArea
)
@onready var _decor_shop: DecorShopInteractionType = (
$Interactables/DecorShopWorld/InteractionArea
)
@onready var _shop_root: Node3D = %FishingShopWorld
@onready var _storage_root: Node3D = %PlayerStorageBox
@onready var _decor_shop_root: Node3D = %DecorShopWorld
@onready var _decorations: Node3D = %Decorations
@onready var _tree_anchors: GatherableAnchorSet3D = %ReachableTreeTrunks
@onready var _diggable_beach: DiggableArea3D = %DiggableBeach
@ -148,6 +155,10 @@ func get_player_storage() -> PlayerStorageInteractionType:
return _player_storage
func get_decor_shop() -> DecorShopInteractionType:
return _decor_shop
func get_saltwater_shoreline_mesh() -> MeshInstance3D:
return _shoreline_reference
@ -428,6 +439,8 @@ func _place_spawn_amenities(center: Vector3) -> void:
_shop_root.rotation.y = PI
_storage_root.position = center + Vector3(-2.4, 0.0, 1.2)
_storage_root.rotation.y = PI * 0.5
_decor_shop_root.position = center + Vector3(-2.4, 0.0, 1.2)
_decor_shop_root.rotation.y = PI * 0.5
func _configure_static_water() -> void:

View file

@ -1,4 +1,4 @@
[gd_scene load_steps=14 format=3]
[gd_scene load_steps=15 format=3]
[ext_resource type="Script" path="res://world/generation/generated_world_region.gd" id="1_region"]
[ext_resource type="Script" path="res://world/generation/terrain_chunk_generator.gd" id="2_generator"]
@ -13,6 +13,7 @@
[ext_resource type="Resource" path="res://fish/pools/starter_pond_pool.tres" id="11_pond_pool"]
[ext_resource type="Resource" path="res://world/generation/props/terrain_prop_catalog.tres" id="12_prop_catalog"]
[ext_resource type="Resource" path="res://world/generation/biomes/terrain_biome_catalog.tres" id="13_biome_catalog"]
[ext_resource type="PackedScene" path="res://world/interactables/decor_shop_world.tscn" id="14_decor_shop"]
[node name="GeneratedWorldRegion" type="Node3D"]
script = ExtResource("1_region")
@ -98,6 +99,9 @@ unique_name_in_owner = true
[node name="PlayerStorageBox" parent="Interactables" instance=ExtResource("6_storage")]
unique_name_in_owner = true
[node name="DecorShopWorld" parent="Interactables" instance=ExtResource("14_decor_shop")]
unique_name_in_owner = true
[node name="Decorations" type="Node3D" parent="."]
unique_name_in_owner = true

View file

@ -0,0 +1,35 @@
[gd_scene load_steps=5 format=3]
[ext_resource type="Script" path="res://world/decor_shop_interaction.gd" id="1_shop"]
[ext_resource type="PackedScene" path="res://art/exported/characters/base/straywild_base_character.glb" id="2_character"]
[ext_resource type="Script" path="res://world/world_character_display.gd" id="3_display"]
[sub_resource type="SphereShape3D" id="InteractionShape"]
resource_local_to_scene = true
radius = 3.0
[node name="DecorShopWorld" type="Node3D"]
[node name="Shopkeeper" parent="." instance=ExtResource("2_character")]
script = ExtResource("3_display")
species_id = "round"
fur_color_id = "orange"
ears_id = "pointy_short"
tail_id = "cat"
eyes_id = "simple_shine"
nose_id = "dog_round"
mouth_id = "three"
head_look_enabled = true
[node name="AnimationPlayer" parent="Shopkeeper"]
autoplay = "idle"
[node name="InteractionArea" type="Area3D" parent="."]
unique_name_in_owner = true
position = Vector3(0, 1, -0.3)
collision_layer = 0
collision_mask = 2
script = ExtResource("1_shop")
[node name="InteractionShape" type="CollisionShape3D" parent="InteractionArea"]
shape = SubResource("InteractionShape")

View file

@ -27,6 +27,8 @@ size = Vector3(1.62, 0.86, 1.02)
radius = 2.3
[node name="PlayerStorageBox" type="Node3D"]
process_mode = 4
visible = false
[node name="Body" type="MeshInstance3D" parent="."]
position = Vector3(0, 0.35, 0)
@ -44,6 +46,7 @@ collision_mask = 0
[node name="CollisionShape3D" type="CollisionShape3D" parent="StaticBody3D"]
position = Vector3(0, 0.43, 0)
disabled = true
shape = SubResource("CollisionShape")
[node name="InteractionArea" type="Area3D" parent="."]
@ -54,6 +57,7 @@ collision_mask = 2
script = ExtResource("1_interaction")
[node name="CollisionShape3D" type="CollisionShape3D" parent="InteractionArea"]
disabled = true
shape = SubResource("InteractionShape")
[node name="PromptAnchor" type="Marker3D" parent="."]

View file

@ -8,6 +8,9 @@ const FishingShopInteractionType = preload(
const PlayerStorageInteractionType = preload(
"res://world/player_storage_interaction.gd"
)
const DecorShopInteractionType = preload(
"res://world/decor_shop_interaction.gd"
)
const FOLIAGE_WIND_SHADER: Shader = preload(
"res://world/materials/foliage_wind.gdshader"
)
@ -49,6 +52,10 @@ var fishing_shop_path: NodePath = (
var player_storage_path: NodePath = (
^"Interactables/PlayerStorageBox/InteractionArea"
)
@export_node_path("Area3D")
var decor_shop_path: NodePath = (
^"Interactables/DecorShopWorld/InteractionArea"
)
@export_group("Terrain Collision")
# The imported GLB is the collision authority. Rebuild once per region load so
# newly authored terrain and props cannot retain a stale saved fallback shape.
@ -84,6 +91,10 @@ func get_player_storage() -> PlayerStorageInteractionType:
return get_node_or_null(player_storage_path) as PlayerStorageInteractionType
func get_decor_shop() -> DecorShopInteractionType:
return get_node_or_null(decor_shop_path) as DecorShopInteractionType
func get_saltwater_shoreline_mesh() -> MeshInstance3D:
return get_node_or_null(^"ShorelineRibbons/Ocean") as MeshInstance3D

File diff suppressed because one or more lines are too long

View file

@ -18,6 +18,10 @@ func get_fishing_shop() -> FishingShopInteraction:
return null
func get_decor_shop() -> DecorShopInteraction:
return null
func get_player_storage() -> PlayerStorageInteraction:
return null

View file

@ -7,6 +7,9 @@ const FishingShopInteractionType = preload(
const PlayerStorageInteractionType = preload(
"res://world/player_storage_interaction.gd"
)
const DecorShopInteractionType = preload(
"res://world/decor_shop_interaction.gd"
)
const WorldLayoutType = preload("res://world/world_layout.gd")
const GENERATED_REGION_SCENE: PackedScene = preload(
"res://world/generation/generated_world_region.tscn"
@ -31,6 +34,7 @@ var _world_layout: StringName = WorldLayoutType.GENERATED
var _world_seed: int = PlayerSaveManager.DEFAULT_WORLD_SEED
var _light_performance_profile: bool = false
var _dedicated_simulation: bool = false
var _local_home_interior_presentation_active: bool = false
func get_player_water_triggers() -> Array[PlayerWaterTrigger]:
@ -67,6 +71,10 @@ func get_player_storage() -> PlayerStorageInteractionType:
return _active_region.get_player_storage()
func get_decor_shop() -> DecorShopInteractionType:
return _active_region.get_decor_shop()
func get_player_spawn_transform() -> Transform3D:
return _active_region.get_player_spawn_transform()
@ -85,6 +93,12 @@ func set_light_performance_profile(enabled: bool) -> void:
_active_region.set_light_performance_profile(enabled)
func set_local_home_interior_presentation_active(enabled: bool) -> void:
_local_home_interior_presentation_active = enabled
if _active_region != null and not _dedicated_simulation:
_active_region.visible = not enabled
func set_dedicated_simulation(enabled: bool) -> void:
_dedicated_simulation = enabled
if _active_region != null:
@ -272,6 +286,8 @@ func _replace_active_region(layout: StringName, seed: int) -> bool:
_active_region.set_light_performance_profile(_light_performance_profile)
if _dedicated_simulation:
_set_region_presentation_enabled(_active_region, false)
else:
_active_region.visible = not _local_home_interior_presentation_active
return true