diff --git a/art/exported/environment/terrain/starter_island.glb b/art/exported/environment/terrain/starter_island.glb new file mode 100644 index 0000000..9612f8d Binary files /dev/null and b/art/exported/environment/terrain/starter_island.glb differ diff --git a/art/exported/environment/terrain/starter_island.glb.import b/art/exported/environment/terrain/starter_island.glb.import new file mode 100644 index 0000000..bedce7c --- /dev/null +++ b/art/exported/environment/terrain/starter_island.glb.import @@ -0,0 +1,45 @@ +[remap] + +importer="scene" +importer_version=1 +type="PackedScene" +uid="uid://bk38p45urtjis" +path="res://.godot/imported/starter_island.glb-2e424e31e476d52eee139d119e5596cc.scn" + +[deps] + +source_file="res://art/exported/environment/terrain/starter_island.glb" +dest_files=["res://.godot/imported/starter_island.glb-2e424e31e476d52eee139d119e5596cc.scn"] + +[params] + +nodes/root_type="" +nodes/root_name="" +nodes/root_script=null +mesh_library/use_node_names_as_mesh_names=false +array_mesh/deduplicate_surfaces=true +nodes/apply_root_scale=true +nodes/root_scale=1.0 +nodes/import_as_skeleton_bones=false +nodes/use_name_suffixes=true +nodes/use_node_type_suffixes=true +meshes/ensure_tangents=true +meshes/generate_lods=true +meshes/create_shadow_meshes=true +meshes/light_baking=1 +meshes/lightmap_texel_size=0.2 +meshes/force_disable_compression=false +skins/use_named_skins=true +animation/import=true +animation/fps=30 +animation/trimming=false +animation/remove_immutable_tracks=true +animation/import_rest_as_RESET=false +import_script/path="" +materials/extract=0 +materials/extract_format=0 +materials/extract_path="" +_subresources={} +gltf/naming_version=2 +gltf/embedded_image_handling=1 +gltf/texture_map_mode=1 diff --git a/art/source/environment/terrain/.gdignore b/art/source/environment/terrain/.gdignore new file mode 100644 index 0000000..e69de29 diff --git a/art/source/environment/terrain/starter_island.blend b/art/source/environment/terrain/starter_island.blend new file mode 100644 index 0000000..aeee334 Binary files /dev/null and b/art/source/environment/terrain/starter_island.blend differ diff --git a/fishing/fishing_presentation.gd b/fishing/fishing_presentation.gd index 0ec9297..a44ed7f 100644 --- a/fishing/fishing_presentation.gd +++ b/fishing/fishing_presentation.gd @@ -72,9 +72,11 @@ var _pickup_position: Vector3 var _active_tween: Tween var _rod_tween: Tween var _bite_tween: Tween +var _default_water_surface_offset_y: float func _ready() -> void: + _default_water_surface_offset_y = water_surface_offset_y _line.mesh = _line_mesh cleanup() @@ -94,6 +96,14 @@ func get_water_surface_height() -> float: return global_position.y + water_surface_offset_y +func set_water_surface_height(surface_height: float) -> void: + water_surface_offset_y = surface_height - global_position.y + + +func reset_water_surface_height() -> void: + water_surface_offset_y = _default_water_surface_offset_y + + func set_line_mode(mode: LineMode) -> void: _line_mode = mode _line.visible = mode != LineMode.HIDDEN diff --git a/fishing/fishing_spot.gd b/fishing/fishing_spot.gd index 6d7cb8e..64d0f36 100644 --- a/fishing/fishing_spot.gd +++ b/fishing/fishing_spot.gd @@ -431,6 +431,7 @@ func _begin_aiming(player: PlayerType) -> void: if state != FishingState.READY or _active_player != null: return + _presentation.reset_water_surface_height() _active_player = player _active_player.set_movement_enabled(false) _cast_direction = _capture_cast_direction(_active_player) @@ -894,6 +895,7 @@ func _cleanup_attempt( _catch_controller.reset() if visual_outcome.is_empty(): _presentation.cleanup() + _presentation.reset_water_surface_height() else: if visual_outcome in [&"catch", &"invalid", &"withdrawal"]: _presentation.set_line_mode( @@ -918,6 +920,7 @@ func _cleanup_attempt( func _return_to_ready() -> void: + _presentation.reset_water_surface_height() state = FishingState.READY _state_time_remaining = 0.0 _cooldown_status = "" @@ -954,11 +957,21 @@ func _capture_cast_direction(player: PlayerType) -> Vector3: func _calculate_cast_target(distance: float) -> Vector3: - return Vector3( + var target := Vector3( _cast_origin_position.x + _cast_direction.x * distance, _presentation.get_water_surface_height(), _cast_origin_position.z + _cast_direction.z * distance ) + var water_region: FishableWaterRegionType = get_fishable_water_region( + target + ) + if water_region != null: + target.y = water_region.surface_height + _presentation.set_water_surface_height(target.y) + else: + _presentation.reset_water_surface_height() + target.y = _presentation.get_water_surface_height() + return target func is_target_fishable(target: Vector3) -> bool: diff --git a/main/main.gd b/main/main.gd index b2bf6c6..133bceb 100644 --- a/main/main.gd +++ b/main/main.gd @@ -54,6 +54,8 @@ var _quit_in_progress: bool = false func _ready() -> void: + _player.global_transform = _test_world.get_player_spawn_transform() + _player.velocity = Vector3.ZERO _player.fish_sale_service.setup( _player.inventory, _player.wallet diff --git a/world/README-WORLD-GRAYBOX.md b/world/README-WORLD-GRAYBOX.md index d1da73f..3cee61e 100644 --- a/world/README-WORLD-GRAYBOX.md +++ b/world/README-WORLD-GRAYBOX.md @@ -1,110 +1,73 @@ -# NETFISHING holdover world +# NETFISHING test world -`world/test_world.tscn` remains the active world. It composes the complete -temporary map, lighting, paths, bounds, and six region scenes. The practical -footprint is approximately 180 × 220 world units, including the coastal water -and outer collision bounds. +`world/test_world.tscn` remains the active world composition. It currently +instances `world/regions/starter_island_region.tscn`, a Godot-owned gameplay +wrapper around the human-authored starter-island GLB. -## Composition +## Starter-island ownership ```text TestWorld ├── Environment -├── SeabedBoundary ├── Regions -│ ├── VillageRegion (0, 0, 15) -│ ├── StarterPondRegion (-42, 0, 15) -│ ├── RiverRegion (0, 0, -40) -│ ├── LakeRegion (53, 0, -25) -│ ├── MarshRegion (56, 0, 38) -│ └── CoastalDockRegion (0, 0, -103) -├── Connectors +│ └── StarterIslandRegion +│ ├── Visuals +│ │ ├── StarterIslandModel +│ │ ├── OceanWater +│ │ └── PondWater +│ ├── StaticCollision +│ ├── FishingWater +│ ├── WaterRecovery +│ ├── SafeRespawns +│ ├── PlayerSpawn +│ └── Interactables ├── Safety └── WorldBounds ``` -Every region uses the same ownership groups: +The imported GLB is visual source content and remains at identity scale. The +wrapper creates concave static collision from its explicit mesh reference and +owns all water, fishing, recovery, spawn, and service placement. -- `Visuals`: replaceable graybox meshes and labels. -- `StaticCollision`: simple gameplay collision paired with the visuals. -- `FishingWater`: explicit `FishableWaterRegion` children. -- `WaterRecovery`: explicit `PlayerWaterTrigger` children. -- `SafeRespawns`: known-safe `SafeRespawnPoint` markers. -- `Interactables`: region-owned services, currently used by the village. - -`GrayboxRegion` only exposes those explicit child groups plus a stable region -ID. `TestWorld` is the aggregation boundary; regions do not select fish, -control recovery, own progression, register globally, or stream themselves. - -## Safe editing - -Move a whole region by moving its region root under `TestWorld/Regions`. This -keeps visuals, collision, water, recovery triggers, safe points, and -interactables synchronized. Moving only a visual mesh does not move collision -or gameplay volumes, so update its paired collision intentionally when editing -inside a region. - -Safe designer targets: - -- Entire region roots under `TestWorld/Regions` -- Children of `Visuals`, together with paired `StaticCollision` -- Safe-respawn marker transforms -- Landmark and label transforms -- Connector transforms and their complete StaticBody children - -Structural land and route blocks extend from the common walkable elevation at -`y=0` down to approximately `y=-6`. Adjacent blocks meet at deliberate shared -edges instead of stacking collision surfaces. Decorative plaza/path color is -non-colliding and sits just above the authoritative ground. - -Gameplay-critical children that must stay aligned: - -- A water plane, its `FishingWater` Area3D, and its `WaterRecovery` Area3D -- A dock or bank mesh and its paired shape in `StaticCollision` -- Safe points and the land/dock they target -- The Fishing Shop visual root and `FishingShopInteraction` +Move the complete `StarterIslandRegion` root to keep visuals and gameplay +volumes synchronized. When editing inside the wrapper, keep each water mesh +aligned with its matching `FishingWater` and `WaterRecovery` shapes. Safe +respawns and `PlayerSpawn` must remain on broad upper terrain. Rename-sensitive paths: - `TestWorld/Regions` -- `VillageRegion/Interactables/FishingShopWorld/FishingShopInteraction` -- `VillageRegion/Interactables/PelicanCoolerPerch` -- Each region's `FishingWater`, `WaterRecovery`, and `SafeRespawns` roots, - unless its exported NodePaths are updated at the same time +- `TestWorld/Regions/StarterIslandRegion` +- the NodePaths exported by `StarterIslandRegion` +- each region's `FishingWater`, `WaterRecovery`, and `SafeRespawns` roots -## Adding water and recovery +## Reverting to the modular graybox -1. Add a `FishableWaterRegion` Area3D under the region's `FishingWater`. -2. Give it collision layer 4, a clear location tag, and an explicit fish pool. -3. Add a matching `PlayerWaterTrigger` under `WaterRecovery`. -4. Give the trigger collision layer 8, mask 2, matching horizontal coverage, - and the correct `surface_height`. -5. Place two or more safe respawns on nearby broad walkable land. -6. Validate casting, shoreline collision, recovery entry, and nearest-point - selection from every side. +The previous region scenes remain unchanged under `world/regions/`. To restore +the prior holdover world, restore `world/test_world.tscn` and +`world/test_world.gd` from commit `633bbd9`, then remove the player-spawn +composition line added to `main/main.gd`. That composition instances: -`TestWorld/Safety/BelowWorldFailsafe` is a temporary whole-map recovery net. -It catches seam and below-world falls that escape normal regional water -coverage. It supplements rather than replaces the five region-local triggers; -the recovery controller still permits only one recovery sequence at a time. +- `village_region.tscn` +- `starter_pond_region.tscn` +- `river_region.tscn` +- `lake_region.tscn` +- `marsh_region.tscn` +- `coastal_dock_region.tscn` -## Services +No region asset needs to be reconstructed or recovered from deleted content. -The Fishing Shop is an instanced scene at the east side of the village plaza. -Move the complete `FishingShopWorld` instance, not only its booth meshes. +## Water and recovery -The Pelican perch is decorative signage, not an interaction NPC. Its sign says -“Sell to Pelicans from the Cooler”; the existing 0.25× Pelican sale remains -available from the Cooler anywhere in the world. Moving or removing the -decorative perch does not change that service. +The pond and surrounding ocean remain separate fishable regions using the +existing test pool. Ocean fishing and recovery use four collision shapes so +the raised island interior is not classified as ocean. Regional recovery is +supplemented by `TestWorld/Safety/BelowWorldFailsafe`. -## Temporary by design +The pond surface is at `y=2.10`. The ocean is at `y=-0.45`, between the +authored upper beach and submerged shelf rings. Fishable regions explicitly +provide their surface heights to the shared fishing presentation. -All terrain, buildings, docks, reeds, landmarks, signage, palette, and lighting -are primitive holdover presentation. A future artist or level designer can -replace `Visuals` and paired static collision without changing fishing, -recovery, shop, save, economy, or player progression code. Region IDs and -gameplay volume ownership should remain stable while visuals are replaced. - -Water surfaces sit near `y=0.2`; the shared graybox seabed is near `y=-6`. -There is no structural walkable layer directly below the fishable surfaces. +The Fishing Shop remains a complete instanced interactable. The Pelican perch +remains convenience signage only; Pelican selling is available through the +Cooler from anywhere. diff --git a/world/fishable_water_region.gd b/world/fishable_water_region.gd index 4fb75ac..e3fe2e8 100644 --- a/world/fishable_water_region.gd +++ b/world/fishable_water_region.gd @@ -6,3 +6,4 @@ const FishPoolType = preload("res://fish/fish_pool.gd") @export var location_tags: Array[StringName] = [] @export var fish_pool: FishPoolType @export var selection_priority: int = 0 +@export var surface_height: float = 0.3 diff --git a/world/regions/starter_island_region.gd b/world/regions/starter_island_region.gd new file mode 100644 index 0000000..5e35493 --- /dev/null +++ b/world/regions/starter_island_region.gd @@ -0,0 +1,66 @@ +class_name StarterIslandRegion +extends GrayboxRegion + +const FishingShopInteractionType = preload( + "res://world/fishing_shop_interaction.gd" +) + +@export var visual_mesh_path: NodePath = ( + ^"Visuals/StarterIslandModel/starter_island" +) +@export var terrain_collision_shape_path: NodePath = ( + ^"StaticCollision/Terrain/Shape" +) +@export var player_spawn_path: NodePath = ^"PlayerSpawn" +@export var fishing_shop_path: NodePath = ( + ^"Interactables/FishingShopWorld/FishingShopInteraction" +) +@export var pelican_landmark_path: NodePath = ( + ^"Interactables/PelicanCoolerPerch" +) + + +func _ready() -> void: + _build_terrain_collision() + + +func get_player_spawn_transform() -> Transform3D: + var spawn: Marker3D = get_node_or_null(player_spawn_path) as Marker3D + return spawn.global_transform if spawn != null else global_transform + + +func get_fishing_shop() -> FishingShopInteractionType: + return get_node_or_null(fishing_shop_path) as FishingShopInteractionType + + +func get_pelican_landmark() -> Node3D: + return get_node_or_null(pelican_landmark_path) as Node3D + + +func has_terrain_collision() -> bool: + var collision_shape: CollisionShape3D = ( + get_node_or_null(terrain_collision_shape_path) as CollisionShape3D + ) + return collision_shape != null and collision_shape.shape != null + + +func _build_terrain_collision() -> void: + var visual_mesh: MeshInstance3D = ( + get_node_or_null(visual_mesh_path) as MeshInstance3D + ) + var collision_shape: CollisionShape3D = ( + get_node_or_null(terrain_collision_shape_path) as CollisionShape3D + ) + if visual_mesh == null or visual_mesh.mesh == null: + push_error("Starter island visual mesh is unavailable.") + return + if collision_shape == null: + push_error("Starter island collision owner is unavailable.") + return + var terrain_shape: ConcavePolygonShape3D = ( + visual_mesh.mesh.create_trimesh_shape() + ) + if terrain_shape == null or terrain_shape.get_faces().is_empty(): + push_error("Starter island terrain collision could not be created.") + return + collision_shape.shape = terrain_shape diff --git a/world/regions/starter_island_region.gd.uid b/world/regions/starter_island_region.gd.uid new file mode 100644 index 0000000..0b57c14 --- /dev/null +++ b/world/regions/starter_island_region.gd.uid @@ -0,0 +1 @@ +uid://j8syuqdau7vl diff --git a/world/regions/starter_island_region.tscn b/world/regions/starter_island_region.tscn new file mode 100644 index 0000000..f2b1d6e --- /dev/null +++ b/world/regions/starter_island_region.tscn @@ -0,0 +1,185 @@ +[gd_scene load_steps=20 format=3] + +[ext_resource type="Script" path="res://world/regions/starter_island_region.gd" id="1_region"] +[ext_resource type="PackedScene" path="res://art/exported/environment/terrain/starter_island.glb" id="2_island"] +[ext_resource type="Script" path="res://world/fishable_water_region.gd" id="3_water"] +[ext_resource type="Resource" path="res://fish/pools/test_water_pool.tres" id="4_pool"] +[ext_resource type="Script" path="res://world/player_water_trigger.gd" id="5_trigger"] +[ext_resource type="Script" path="res://world/safe_respawn_point.gd" id="6_safe"] +[ext_resource type="PackedScene" path="res://world/interactables/fishing_shop_world.tscn" id="7_shop"] +[ext_resource type="PackedScene" path="res://world/interactables/pelican_buyer_world.tscn" id="8_pelican"] + +[sub_resource type="StandardMaterial3D" id="WaterMaterial"] +transparency = 1 +albedo_color = Color(0.10, 0.50, 0.72, 0.76) +roughness = 0.22 + +[sub_resource type="PlaneMesh" id="OceanWaterMesh"] +size = Vector2(120, 90) + +[sub_resource type="PlaneMesh" id="PondWaterMesh"] +size = Vector2(11.5, 8.5) + +[sub_resource type="BoxShape3D" id="OceanWestShape"] +size = Vector3(17, 2, 80) + +[sub_resource type="BoxShape3D" id="OceanEastShape"] +size = Vector3(42, 2, 80) + +[sub_resource type="BoxShape3D" id="OceanNorthSouthShape"] +size = Vector3(48, 2, 18) + +[sub_resource type="BoxShape3D" id="PondFishingShape"] +size = Vector3(11.5, 4, 8.5) + +[sub_resource type="BoxShape3D" id="OceanWestRecoveryShape"] +size = Vector3(17, 5, 80) + +[sub_resource type="BoxShape3D" id="OceanEastRecoveryShape"] +size = Vector3(42, 5, 80) + +[sub_resource type="BoxShape3D" id="OceanNorthSouthRecoveryShape"] +size = Vector3(48, 5, 18) + +[sub_resource type="BoxShape3D" id="PondRecoveryShape"] +size = Vector3(11.5, 4.8, 8.5) + +[node name="StarterIslandRegion" type="Node3D"] +script = ExtResource("1_region") +region_id = &"starter_island" + +[node name="Visuals" type="Node3D" parent="."] + +[node name="StarterIslandModel" parent="Visuals" instance=ExtResource("2_island")] + +[node name="OceanWater" type="MeshInstance3D" parent="Visuals"] +position = Vector3(12, -0.45, 0) +mesh = SubResource("OceanWaterMesh") +material_override = SubResource("WaterMaterial") + +[node name="PondWater" type="MeshInstance3D" parent="Visuals"] +position = Vector3(-9.4, 2.1, 2.1) +mesh = SubResource("PondWaterMesh") +material_override = SubResource("WaterMaterial") + +[node name="StaticCollision" type="Node3D" parent="."] + +[node name="Terrain" type="StaticBody3D" parent="StaticCollision"] + +[node name="Shape" type="CollisionShape3D" parent="StaticCollision/Terrain"] + +[node name="FishingWater" type="Node3D" parent="."] + +[node name="PondWater" type="Area3D" parent="FishingWater"] +position = Vector3(-9.4, 2.1, 2.1) +collision_layer = 4 +collision_mask = 0 +monitoring = false +script = ExtResource("3_water") +location_tags = Array[StringName]([&"starter_pond"]) +fish_pool = ExtResource("4_pool") +selection_priority = 1 +surface_height = 2.1 + +[node name="Shape" type="CollisionShape3D" parent="FishingWater/PondWater"] +shape = SubResource("PondFishingShape") + +[node name="OceanWater" type="Area3D" parent="FishingWater"] +position = Vector3(0, -0.45, 0) +collision_layer = 4 +collision_mask = 0 +monitoring = false +script = ExtResource("3_water") +location_tags = Array[StringName]([&"coast", &"ocean"]) +fish_pool = ExtResource("4_pool") +surface_height = -0.45 + +[node name="WestShape" type="CollisionShape3D" parent="FishingWater/OceanWater"] +position = Vector3(-33.5, 0, 0) +shape = SubResource("OceanWestShape") + +[node name="EastShape" type="CollisionShape3D" parent="FishingWater/OceanWater"] +position = Vector3(44, 0, 0) +shape = SubResource("OceanEastShape") + +[node name="NorthShape" type="CollisionShape3D" parent="FishingWater/OceanWater"] +position = Vector3(-1, 0, 31) +shape = SubResource("OceanNorthSouthShape") + +[node name="SouthShape" type="CollisionShape3D" parent="FishingWater/OceanWater"] +position = Vector3(-1, 0, -31) +shape = SubResource("OceanNorthSouthShape") + +[node name="WaterRecovery" type="Node3D" parent="."] + +[node name="PondRecovery" type="Area3D" parent="WaterRecovery"] +position = Vector3(-9.4, -0.3, 2.1) +collision_layer = 8 +collision_mask = 2 +script = ExtResource("5_trigger") +surface_height = 2.1 + +[node name="Shape" type="CollisionShape3D" parent="WaterRecovery/PondRecovery"] +shape = SubResource("PondRecoveryShape") + +[node name="OceanRecovery" type="Area3D" parent="WaterRecovery"] +position = Vector3(0, -2.95, 0) +collision_layer = 8 +collision_mask = 2 +script = ExtResource("5_trigger") +surface_height = -0.45 + +[node name="WestShape" type="CollisionShape3D" parent="WaterRecovery/OceanRecovery"] +position = Vector3(-33.5, 0, 0) +shape = SubResource("OceanWestRecoveryShape") + +[node name="EastShape" type="CollisionShape3D" parent="WaterRecovery/OceanRecovery"] +position = Vector3(44, 0, 0) +shape = SubResource("OceanEastRecoveryShape") + +[node name="NorthShape" type="CollisionShape3D" parent="WaterRecovery/OceanRecovery"] +position = Vector3(-1, 0, 31) +shape = SubResource("OceanNorthSouthRecoveryShape") + +[node name="SouthShape" type="CollisionShape3D" parent="WaterRecovery/OceanRecovery"] +position = Vector3(-1, 0, -31) +shape = SubResource("OceanNorthSouthRecoveryShape") + +[node name="SafeRespawns" type="Node3D" parent="."] + +[node name="SpawnPlateau" type="Marker3D" parent="SafeRespawns"] +position = Vector3(0, 3.95, 13) +script = ExtResource("6_safe") + +[node name="PondEast" type="Marker3D" parent="SafeRespawns"] +position = Vector3(-0.5, 3.95, 2) +script = ExtResource("6_safe") + +[node name="PondSouth" type="Marker3D" parent="SafeRespawns"] +position = Vector3(-9, 3.95, 11.5) +script = ExtResource("6_safe") + +[node name="ShopApproach" type="Marker3D" parent="SafeRespawns"] +position = Vector3(13.5, 3.95, 6) +script = ExtResource("6_safe") + +[node name="SouthPlateau" type="Marker3D" parent="SafeRespawns"] +position = Vector3(5, 3.95, 15) +script = ExtResource("6_safe") + +[node name="EastShoreApproach" type="Marker3D" parent="SafeRespawns"] +position = Vector3(15, 3.95, -11) +script = ExtResource("6_safe") + +[node name="PlayerSpawn" type="Marker3D" parent="."] +position = Vector3(0, 3.95, 13) + +[node name="Interactables" type="Node3D" parent="."] + +[node name="FishingShopWorld" parent="Interactables" instance=ExtResource("7_shop")] +position = Vector3(8, 3.42, 6) +rotation_degrees = Vector3(0, -25, 0) + +[node name="PelicanCoolerPerch" parent="Interactables" instance=ExtResource("8_pelican")] +position = Vector3(18, 0.35, -16) +rotation_degrees = Vector3(0, -35, 0) diff --git a/world/test_world.gd b/world/test_world.gd index fe484b3..ce389f7 100644 --- a/world/test_world.gd +++ b/world/test_world.gd @@ -6,11 +6,14 @@ const FishingShopInteractionType = preload( ) @onready var _regions_root: Node3D = $Regions +@onready var _starter_island: StarterIslandRegion = ( + $Regions/StarterIslandRegion +) @onready var _below_world_failsafe: PlayerWaterTrigger = ( $Safety/BelowWorldFailsafe ) @onready var _fishing_shop: FishingShopInteractionType = ( - $Regions/VillageRegion/Interactables/FishingShopWorld/FishingShopInteraction + _starter_island.get_fishing_shop() ) @@ -33,6 +36,10 @@ func get_fishing_shop() -> FishingShopInteractionType: return _fishing_shop +func get_player_spawn_transform() -> Transform3D: + return _starter_island.get_player_spawn_transform() + + func get_fishable_water_regions() -> Array[FishableWaterRegion]: var waters: Array[FishableWaterRegion] = [] for region: GrayboxRegion in _get_regions(): @@ -41,10 +48,7 @@ func get_fishable_water_regions() -> Array[FishableWaterRegion]: func get_pelican_convenience_landmark() -> Node3D: - return ( - $Regions/VillageRegion/Interactables/PelicanCoolerPerch - as Node3D - ) + return _starter_island.get_pelican_landmark() func _get_regions() -> Array[GrayboxRegion]: diff --git a/world/test_world.tscn b/world/test_world.tscn index f600b92..b5d4f20 100644 --- a/world/test_world.tscn +++ b/world/test_world.tscn @@ -1,13 +1,8 @@ -[gd_scene load_steps=16 format=3] +[gd_scene load_steps=10 format=3] [ext_resource type="Script" path="res://world/test_world.gd" id="1_world"] -[ext_resource type="PackedScene" path="res://world/regions/village_region.tscn" id="2_village"] -[ext_resource type="PackedScene" path="res://world/regions/starter_pond_region.tscn" id="3_pond"] -[ext_resource type="PackedScene" path="res://world/regions/river_region.tscn" id="4_river"] -[ext_resource type="PackedScene" path="res://world/regions/lake_region.tscn" id="5_lake"] -[ext_resource type="PackedScene" path="res://world/regions/marsh_region.tscn" id="6_marsh"] -[ext_resource type="PackedScene" path="res://world/regions/coastal_dock_region.tscn" id="7_coast"] -[ext_resource type="Script" path="res://world/player_water_trigger.gd" id="8_water_trigger"] +[ext_resource type="PackedScene" path="res://world/regions/starter_island_region.tscn" id="2_island"] +[ext_resource type="Script" path="res://world/player_water_trigger.gd" id="3_water_trigger"] [sub_resource type="Environment" id="Environment"] background_mode = 1 @@ -16,30 +11,14 @@ ambient_light_source = 3 ambient_light_color = Color(0.72, 0.78, 0.84, 1) ambient_light_energy = 0.72 -[sub_resource type="BoxShape3D" id="SeabedShape"] -size = Vector3(180, 1, 220) -[sub_resource type="BoxMesh" id="SeabedMesh"] -size = Vector3(180, 1, 220) -[sub_resource type="StandardMaterial3D" id="SeabedMaterial"] -albedo_color = Color(0.18, 0.36, 0.27, 1) - -[sub_resource type="BoxShape3D" id="RiverPathShape"] -size = Vector3(40, 6, 8) -[sub_resource type="BoxMesh" id="RiverPathMesh"] -size = Vector3(40, 6, 8) -[sub_resource type="BoxShape3D" id="MarshPathShape"] -size = Vector3(5, 6, 10) -[sub_resource type="BoxMesh" id="MarshPathMesh"] -size = Vector3(5, 6, 10) -[sub_resource type="StandardMaterial3D" id="PathMaterial"] -albedo_color = Color(0.72, 0.62, 0.43, 1) - [sub_resource type="BoxShape3D" id="NorthSouthBoundsShape"] -size = Vector3(180, 12, 2) +size = Vector3(120, 14, 2) + [sub_resource type="BoxShape3D" id="EastWestBoundsShape"] -size = Vector3(2, 12, 220) +size = Vector3(2, 14, 90) + [sub_resource type="BoxShape3D" id="FailsafeShape"] -size = Vector3(178, 5, 218) +size = Vector3(118, 4, 88) [node name="TestWorld" type="Node3D"] script = ExtResource("1_world") @@ -54,62 +33,18 @@ rotation_degrees = Vector3(-54, -32, 0) light_energy = 1.1 shadow_enabled = true -[node name="SeabedBoundary" type="StaticBody3D" parent="."] -position = Vector3(0, -6.5, -38) - -[node name="CollisionShape3D" type="CollisionShape3D" parent="SeabedBoundary"] -shape = SubResource("SeabedShape") - -[node name="MeshInstance3D" type="MeshInstance3D" parent="SeabedBoundary"] -mesh = SubResource("SeabedMesh") -material_override = SubResource("SeabedMaterial") - [node name="Regions" type="Node3D" parent="."] -[node name="VillageRegion" parent="Regions" instance=ExtResource("2_village")] -position = Vector3(0, 0, 15) - -[node name="StarterPondRegion" parent="Regions" instance=ExtResource("3_pond")] -position = Vector3(-42, 0, 15) - -[node name="RiverRegion" parent="Regions" instance=ExtResource("4_river")] -position = Vector3(0, 0, -40) - -[node name="LakeRegion" parent="Regions" instance=ExtResource("5_lake")] -position = Vector3(53, 0, -25) - -[node name="MarshRegion" parent="Regions" instance=ExtResource("6_marsh")] -position = Vector3(56, 0, 38) - -[node name="CoastalDockRegion" parent="Regions" instance=ExtResource("7_coast")] -position = Vector3(0, 0, -103) - -[node name="Connectors" type="Node3D" parent="."] - -[node name="VillageRiverPath" type="StaticBody3D" parent="Connectors"] -position = Vector3(0, -3, -7) -[node name="Shape" type="CollisionShape3D" parent="Connectors/VillageRiverPath"] -shape = SubResource("RiverPathShape") -[node name="Mesh" type="MeshInstance3D" parent="Connectors/VillageRiverPath"] -mesh = SubResource("RiverPathMesh") -material_override = SubResource("PathMaterial") - -[node name="VillageMarshPath" type="StaticBody3D" parent="Connectors"] -position = Vector3(26.5, -3, 28) -[node name="Shape" type="CollisionShape3D" parent="Connectors/VillageMarshPath"] -shape = SubResource("MarshPathShape") -[node name="Mesh" type="MeshInstance3D" parent="Connectors/VillageMarshPath"] -mesh = SubResource("MarshPathMesh") -material_override = SubResource("PathMaterial") +[node name="StarterIslandRegion" parent="Regions" instance=ExtResource("2_island")] [node name="Safety" type="Node3D" parent="."] [node name="BelowWorldFailsafe" type="Area3D" parent="Safety"] -position = Vector3(0, -5, -38) +position = Vector3(12, -7, 0) collision_layer = 8 collision_mask = 2 -script = ExtResource("8_water_trigger") -surface_height = 0.2 +script = ExtResource("3_water_trigger") +surface_height = 0.3 [node name="FailsafeShape" type="CollisionShape3D" parent="Safety/BelowWorldFailsafe"] shape = SubResource("FailsafeShape") @@ -117,21 +52,25 @@ shape = SubResource("FailsafeShape") [node name="WorldBounds" type="Node3D" parent="."] [node name="North" type="StaticBody3D" parent="WorldBounds"] -position = Vector3(0, 5, 72) +position = Vector3(12, 5, 45) + [node name="Shape" type="CollisionShape3D" parent="WorldBounds/North"] shape = SubResource("NorthSouthBoundsShape") [node name="South" type="StaticBody3D" parent="WorldBounds"] -position = Vector3(0, 5, -148) +position = Vector3(12, 5, -45) + [node name="Shape" type="CollisionShape3D" parent="WorldBounds/South"] shape = SubResource("NorthSouthBoundsShape") [node name="West" type="StaticBody3D" parent="WorldBounds"] -position = Vector3(-90, 5, -38) +position = Vector3(-48, 5, 0) + [node name="Shape" type="CollisionShape3D" parent="WorldBounds/West"] shape = SubResource("EastWestBoundsShape") [node name="East" type="StaticBody3D" parent="WorldBounds"] -position = Vector3(90, 5, -38) +position = Vector3(72, 5, 0) + [node name="Shape" type="CollisionShape3D" parent="WorldBounds/East"] shape = SubResource("EastWestBoundsShape")