forked from woofmeow/straywild
feat: expand seasonal creature collection
This commit is contained in:
parent
925bbb79e5
commit
95c6b8b053
415 changed files with 1688 additions and 389 deletions
|
|
@ -1,7 +1,7 @@
|
|||
class_name NetworkProtocol
|
||||
extends RefCounted
|
||||
|
||||
const PROTOCOL_VERSION: int = 7
|
||||
const PROTOCOL_VERSION: int = 8
|
||||
const GAME_BUILD: String = "prealpha"
|
||||
const MAX_GAME_VERSION_LENGTH: int = 64
|
||||
const MAX_DISPLAY_NAME_LENGTH: int = 24
|
||||
|
|
@ -22,7 +22,7 @@ const ENET_CHANNEL_COUNT: int = 10
|
|||
const SURFACE_DRAWING_CAPABILITY: String = "surface_drawing_v2"
|
||||
const ART_SHOP_CAPABILITY: String = "art_shop_v1"
|
||||
const BACKPACK_SHOP_CAPABILITY: String = "backpack_shop_v1"
|
||||
const WORLD_TIME_CAPABILITY: String = "world_time_v1"
|
||||
const WORLD_TIME_CAPABILITY: String = "world_time_v2"
|
||||
const WORLD_WEATHER_CAPABILITY: String = "world_weather_v1"
|
||||
const FISH_QUALITY_CAPABILITY: String = "fish_quality_v1"
|
||||
const JOBS_CAPABILITY: String = "jobs_v1"
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ const GatherableCatalogType = preload("res://gathering/gatherable_catalog.gd")
|
|||
const GatherableDataType = preload("res://gathering/gatherable_data.gd")
|
||||
const WorldGatherableType = preload("res://gathering/world_gatherable.gd")
|
||||
const TestWorldType = preload("res://world/test_world.gd")
|
||||
const CalendarSeasonType = preload("res://world/calendar_season.gd")
|
||||
|
||||
signal local_capture_received(fish_catch: FishCatch)
|
||||
signal local_interaction_finished(accepted: bool, message: String)
|
||||
|
|
@ -24,6 +25,7 @@ var _session: NetworkSession
|
|||
var _spawn_service: PlayerSpawnService
|
||||
var _world: TestWorldType
|
||||
var _world_root: Node3D
|
||||
var _world_time: WorldTimeService
|
||||
var _catalog: GatherableCatalogType
|
||||
var _fish_catalog: FishPoolType
|
||||
var _local_inventory: FishInventory
|
||||
|
|
@ -65,6 +67,7 @@ func setup(
|
|||
local_experience: PlayerExperience,
|
||||
save_manager: PlayerSaveManager,
|
||||
item_use: NetworkItemUseService,
|
||||
world_time: WorldTimeService = null,
|
||||
) -> void:
|
||||
_session = session
|
||||
_spawn_service = spawn_service
|
||||
|
|
@ -78,10 +81,18 @@ func setup(
|
|||
_local_experience = local_experience
|
||||
_save_manager = save_manager
|
||||
_item_use = item_use
|
||||
_world_time = world_time
|
||||
_rng.randomize()
|
||||
_session.peer_authenticated.connect(_on_peer_authenticated)
|
||||
_session.peer_removed.connect(_on_peer_removed)
|
||||
_session.state_changed.connect(_on_session_state_changed)
|
||||
if (
|
||||
_world_time != null
|
||||
and not _world_time.calendar_date_changed.is_connected(
|
||||
_on_calendar_date_changed
|
||||
)
|
||||
):
|
||||
_world_time.calendar_date_changed.connect(_on_calendar_date_changed)
|
||||
set_physics_process(true)
|
||||
_begin_population_if_ready.call_deferred()
|
||||
|
||||
|
|
@ -193,7 +204,9 @@ func get_charge_duration_for_tool(tool_id: StringName) -> float:
|
|||
var duration: float = 0.0
|
||||
if _catalog == null or tool_id.is_empty():
|
||||
return duration
|
||||
for entry: GatherableDataType in _catalog.get_available_entries():
|
||||
for entry: GatherableDataType in _catalog.get_available_entries(
|
||||
_current_season()
|
||||
):
|
||||
if entry.required_tool_id == tool_id:
|
||||
duration = maxf(duration, entry.charge_duration)
|
||||
return duration
|
||||
|
|
@ -240,7 +253,9 @@ func _begin_population_if_ready() -> void:
|
|||
return
|
||||
_clear_world()
|
||||
_population_session_id = session_id
|
||||
for entry: GatherableDataType in _catalog.get_available_entries():
|
||||
for entry: GatherableDataType in _catalog.get_available_entries(
|
||||
_current_season()
|
||||
):
|
||||
_cache_spawn_surface(entry)
|
||||
for _spawn_index: int in entry.population:
|
||||
_spawn_entity(entry)
|
||||
|
|
@ -557,7 +572,7 @@ func _update_respawns() -> void:
|
|||
var entry: GatherableDataType = _catalog.get_entry(
|
||||
type_id
|
||||
)
|
||||
if entry != null and entry.is_available():
|
||||
if entry != null and entry.is_available(_current_season()):
|
||||
_spawn_entity(entry)
|
||||
_next_respawn_by_type[type_id] = (
|
||||
now + entry.minimum_respawn_spacing_seconds
|
||||
|
|
@ -1193,6 +1208,61 @@ func _on_session_state_changed(_state: NetworkSession.State) -> void:
|
|||
_population_session_id = ""
|
||||
|
||||
|
||||
func _on_calendar_date_changed(_date_id: String) -> void:
|
||||
if (
|
||||
_session == null
|
||||
or not _session.is_host()
|
||||
or not _session.is_gameplay_session_active()
|
||||
or _population_session_id.is_empty()
|
||||
):
|
||||
return
|
||||
_reconcile_seasonal_population()
|
||||
|
||||
|
||||
func _reconcile_seasonal_population() -> void:
|
||||
if _catalog == null:
|
||||
return
|
||||
var season: int = _current_season()
|
||||
for entity_id: String in _entities.keys():
|
||||
var state: Dictionary = _entities.get(entity_id, {})
|
||||
var entry := state.get("data") as GatherableDataType
|
||||
if entry != null and not entry.is_available(season):
|
||||
_despawn_entity(entity_id, &"season_changed", false, false)
|
||||
var retained_respawns: Array[Dictionary] = []
|
||||
for respawn: Dictionary in _respawns:
|
||||
var entry: GatherableDataType = _catalog.get_entry(
|
||||
StringName(str(respawn.get("type_id", "")))
|
||||
)
|
||||
if entry != null and entry.is_available(season):
|
||||
retained_respawns.append(respawn)
|
||||
_respawns = retained_respawns
|
||||
for entry: GatherableDataType in _catalog.get_available_entries(season):
|
||||
_cache_spawn_surface(entry)
|
||||
var current_population: int = _population_for_type(entry.type_id)
|
||||
while current_population < entry.population:
|
||||
_spawn_entity(entry)
|
||||
current_population += 1
|
||||
|
||||
|
||||
func _population_for_type(type_id: StringName) -> int:
|
||||
var count: int = 0
|
||||
for state: Dictionary in _entities.values():
|
||||
if StringName(str(state.get("type_id", ""))) == type_id:
|
||||
count += 1
|
||||
for respawn: Dictionary in _respawns:
|
||||
if StringName(str(respawn.get("type_id", ""))) == type_id:
|
||||
count += 1
|
||||
return count
|
||||
|
||||
|
||||
func _current_season() -> int:
|
||||
return (
|
||||
_world_time.get_season()
|
||||
if _world_time != null
|
||||
else CalendarSeasonType.UNKNOWN
|
||||
)
|
||||
|
||||
|
||||
func _clear_world() -> void:
|
||||
for presentation: WorldGatherableType in _presentations.values():
|
||||
if presentation != null and is_instance_valid(presentation):
|
||||
|
|
|
|||
|
|
@ -23,6 +23,12 @@ func setup(session: NetworkSession, world_time: WorldTimeService) -> void:
|
|||
_world_time.authoritative_time_set.connect(
|
||||
_on_authoritative_time_set
|
||||
)
|
||||
if not _world_time.calendar_date_changed.is_connected(
|
||||
_on_authoritative_calendar_date_changed
|
||||
):
|
||||
_world_time.calendar_date_changed.connect(
|
||||
_on_authoritative_calendar_date_changed
|
||||
)
|
||||
set_process(true)
|
||||
|
||||
|
||||
|
|
@ -90,6 +96,13 @@ func _on_authoritative_time_set(_time_hours: float) -> void:
|
|||
_broadcast_snapshot()
|
||||
|
||||
|
||||
func _on_authoritative_calendar_date_changed(_date_id: String) -> void:
|
||||
if _session == null or not _session.is_host():
|
||||
return
|
||||
_sync_elapsed = 0.0
|
||||
_broadcast_snapshot()
|
||||
|
||||
|
||||
func _broadcast_snapshot() -> void:
|
||||
if _session == null or not _session.is_host():
|
||||
return
|
||||
|
|
@ -107,6 +120,7 @@ func _send_snapshot(peer_id: int) -> void:
|
|||
receive_world_time_snapshot.rpc_id(peer_id, {
|
||||
"session_id": _session.get_session_id(),
|
||||
"time_hours": _world_time.get_time_hours(),
|
||||
"calendar_date_id": _world_time.get_calendar_date_id(),
|
||||
"sequence": _sequence,
|
||||
})
|
||||
|
||||
|
|
@ -128,7 +142,10 @@ func receive_world_time_snapshot(data: Dictionary) -> void:
|
|||
if sequence <= _last_received_sequence:
|
||||
return
|
||||
_last_received_sequence = sequence
|
||||
_world_time.synchronize_time(float(data["time_hours"]))
|
||||
_world_time.synchronize_calendar_time(
|
||||
float(data["time_hours"]),
|
||||
str(data["calendar_date_id"]),
|
||||
)
|
||||
|
||||
|
||||
static func validate_snapshot(data: Variant) -> bool:
|
||||
|
|
@ -143,6 +160,10 @@ static func validate_snapshot(data: Variant) -> bool:
|
|||
and is_finite(float(value["time_hours"]))
|
||||
and float(value["time_hours"]) >= 0.0
|
||||
and float(value["time_hours"]) < WorldTimeService.HOURS_PER_DAY
|
||||
and typeof(value.get("calendar_date_id")) == TYPE_STRING
|
||||
and WorldTimeService.is_valid_calendar_date_id(
|
||||
str(value["calendar_date_id"])
|
||||
)
|
||||
and typeof(value.get("sequence")) == TYPE_INT
|
||||
and int(value["sequence"]) >= 0
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue