Scale coastal crab spawning by habitat

This commit is contained in:
Alexander Sellite 2026-08-31 16:04:34 -04:00
parent d8bf59bca0
commit 0158b0215f
9 changed files with 261 additions and 59 deletions

View file

@ -10,5 +10,8 @@ catch_data = ExtResource("2_catch")
required_tool_id = &"crab_net"
surface_materials = Array[StringName]([&"sand"])
minimum_surface_y = -0.8
surface_water_relation = 2
population = 4
surface_population_per_100_square_meters = 0.4
maximum_surface_population = 16
sprite_pixel_size = 0.0005

View file

@ -10,7 +10,10 @@ catch_data = ExtResource("2_catch")
required_tool_id = &"crab_net"
surface_materials = Array[StringName]([&"sand"])
minimum_surface_y = -0.44
surface_water_relation = 1
population = 2
surface_population_per_100_square_meters = 0.15
maximum_surface_population = 24
movement_speed = 0.35
roam_radius = 3.5
scare_radius = 2.8

View file

@ -10,6 +10,12 @@ enum PresentationMode {
WATER_SPURT,
}
enum SurfaceWaterRelation {
ANY,
ABOVE_SALT_WATER,
BELOW_SALT_WATER,
}
@export var type_id: StringName
@export var catch_data: FishDataType
@export var required_tool_id: StringName
@ -17,12 +23,20 @@ enum PresentationMode {
@export var diggable_area_id: StringName
@export var spawn_anchor_set_id: StringName
@export_range(-100.0, 100.0, 0.01) var minimum_surface_y: float = 0.08
@export_range(-100.0, 100.0, 0.01) var maximum_surface_y: float = 100.0
@export var surface_water_relation := SurfaceWaterRelation.ANY
@export_range(0.0, 2.0, 0.01) var waterline_margin: float = 0.01
@export_range(0, 64, 1) var population: int = 0
## Anchored gatherables can scale with authored/generated attachment geometry.
## Zero preserves the fixed population above.
@export_range(0.0, 1.0, 0.01) var spawn_anchor_occupancy_ratio := 0.0
## Zero leaves the anchor count as the only ceiling.
@export_range(0, 256, 1) var maximum_anchor_population := 0
## Optional density scaling for large generated surfaces. The authored
## population remains the minimum while the maximum keeps large maps bounded.
@export_range(0.0, 8.0, 0.01)
var surface_population_per_100_square_meters := 0.0
@export_range(0, 256, 1) var maximum_surface_population := 0
@export var presentation_mode: PresentationMode = PresentationMode.VISIBLE_CREATURE
@export var requires_sneaking: bool = true
@export_range(0.0, 120.0, 0.1) var active_lifetime_seconds: float = 0.0
@ -77,6 +91,7 @@ func is_valid() -> bool:
or uses_spawn_anchors
or not surface_materials.is_empty()
)
and maximum_surface_y >= minimum_surface_y
and (
not uses_diggable_area
or catch_data.collection_method
@ -87,6 +102,10 @@ func is_valid() -> bool:
maximum_anchor_population == 0
or maximum_anchor_population >= population
)
and (
maximum_surface_population == 0
or maximum_surface_population >= population
)
and movement_parameters_valid
and _quality_multipliers_are_valid(
quality_movement_speed_multipliers
@ -126,6 +145,24 @@ func target_population_for_anchor_count(anchor_count: int) -> int:
return target
func target_population_for_surface_area(surface_area: float) -> int:
if surface_population_per_100_square_meters <= 0.0:
return population
if surface_area <= 0.0:
return 0
var target := maxi(
population,
ceili(
surface_area
* surface_population_per_100_square_meters
/ 100.0
),
)
if maximum_surface_population > 0:
target = mini(target, maximum_surface_population)
return target
func can_be_scared() -> bool:
return not is_stationary_spawn() and scare_radius > 0.0