Add networked crab gathering prototype
This commit is contained in:
parent
f55663c105
commit
a62cce6404
56 changed files with 2692 additions and 56 deletions
|
|
@ -4,6 +4,7 @@ extends Node
|
|||
const FishingRodDataType = preload("res://items/fishing_rod_data.gd")
|
||||
|
||||
const ArtShopStockType = preload("res://economy/art_shop_stock.gd")
|
||||
const FishingShopStockType = preload("res://economy/fishing_shop_stock.gd")
|
||||
|
||||
const MAX_LEDGER_ENTRIES: int = 64
|
||||
|
||||
|
|
@ -292,6 +293,13 @@ func get_effects_for_peer(peer_id: int) -> PlayerItemEffects:
|
|||
return avatar.item_effects if avatar != null else null
|
||||
|
||||
|
||||
func get_equipped_item_id(peer_id: int) -> StringName:
|
||||
var state: Dictionary = _equipped_states.get(peer_id, {})
|
||||
if state.is_empty() or not bool(state.get("owns_item", false)):
|
||||
return StringName()
|
||||
return StringName(str(state.get("item_id", "")))
|
||||
|
||||
|
||||
func submit_local_equipped(item_id: StringName, owns_item: bool) -> void:
|
||||
if _session == null or not _session.is_gameplay_session_active():
|
||||
return
|
||||
|
|
@ -377,6 +385,10 @@ func _apply_equipped(data: Dictionary) -> void:
|
|||
item.icon if item != null else null,
|
||||
item_id == ArtShopStockType.ART_KIT_ITEM_ID and bool(data["owns_item"]),
|
||||
)
|
||||
avatar.set_active_catching_net(
|
||||
item_id == FishingShopStockType.CRAB_NET_ID
|
||||
and bool(data["owns_item"]),
|
||||
)
|
||||
equipped_state_changed.emit(
|
||||
peer_id, StringName(str(data["item_id"])), int(data["category"])
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
class_name NetworkProtocol
|
||||
extends RefCounted
|
||||
|
||||
const PROTOCOL_VERSION: int = 4
|
||||
const PROTOCOL_VERSION: int = 5
|
||||
const GAME_BUILD: String = "prealpha"
|
||||
const MAX_GAME_VERSION_LENGTH: int = 64
|
||||
const MAX_DISPLAY_NAME_LENGTH: int = 24
|
||||
|
|
@ -25,6 +25,7 @@ const WORLD_TIME_CAPABILITY: String = "world_time_v1"
|
|||
const WORLD_WEATHER_CAPABILITY: String = "world_weather_v1"
|
||||
const FISH_QUALITY_CAPABILITY: String = "fish_quality_v1"
|
||||
const JOBS_CAPABILITY: String = "jobs_v1"
|
||||
const WORLD_SPAWN_CAPABILITY: String = "world_spawn_envelope_v1"
|
||||
|
||||
enum RejectionCode {
|
||||
NONE,
|
||||
|
|
@ -172,6 +173,7 @@ static func make_client_hello(
|
|||
WORLD_TIME_CAPABILITY,
|
||||
WORLD_WEATHER_CAPABILITY,
|
||||
JOBS_CAPABILITY,
|
||||
WORLD_SPAWN_CAPABILITY,
|
||||
]),
|
||||
"cosmetic_snapshot": cosmetic_snapshot,
|
||||
"identity_fingerprint": identity_fingerprint,
|
||||
|
|
@ -313,6 +315,7 @@ static func make_server_hello(
|
|||
WORLD_TIME_CAPABILITY,
|
||||
WORLD_WEATHER_CAPABILITY,
|
||||
JOBS_CAPABILITY,
|
||||
WORLD_SPAWN_CAPABILITY,
|
||||
"chat_v1",
|
||||
"mail_v1",
|
||||
"profile_v1",
|
||||
|
|
|
|||
|
|
@ -267,6 +267,7 @@ func _register_player_host() -> void:
|
|||
NetworkProtocol.WORLD_TIME_CAPABILITY,
|
||||
NetworkProtocol.WORLD_WEATHER_CAPABILITY,
|
||||
NetworkProtocol.JOBS_CAPABILITY,
|
||||
NetworkProtocol.WORLD_SPAWN_CAPABILITY,
|
||||
]),
|
||||
)
|
||||
_registry.update_appearance(1, _local_appearance_snapshot)
|
||||
|
|
@ -555,6 +556,7 @@ func supports_server_capability(capability: StringName) -> bool:
|
|||
NetworkProtocol.SURFACE_DRAWING_CAPABILITY,
|
||||
NetworkProtocol.WORLD_TIME_CAPABILITY,
|
||||
NetworkProtocol.WORLD_WEATHER_CAPABILITY,
|
||||
NetworkProtocol.WORLD_SPAWN_CAPABILITY,
|
||||
"chat_v1",
|
||||
"mail_v1",
|
||||
"profile_v1",
|
||||
|
|
|
|||
94
network/network_world_spawn_protocol.gd
Normal file
94
network/network_world_spawn_protocol.gd
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
class_name NetworkWorldSpawnProtocol
|
||||
extends RefCounted
|
||||
|
||||
const CAPABILITY: StringName = &"world_spawn_envelope_v1"
|
||||
const ENVELOPE_VERSION: int = 1
|
||||
const RELIABLE_CHANNEL: int = NetworkProtocol.ITEM_RELIABLE_CHANNEL
|
||||
const SNAPSHOT_CHANNEL: int = 4
|
||||
const MAX_SESSION_ID_LENGTH: int = 96
|
||||
const MAX_EVENT_ID_LENGTH: int = 48
|
||||
const MAX_ENTITY_ID_LENGTH: int = 128
|
||||
const MAX_TYPE_ID_LENGTH: int = 96
|
||||
const MAX_ENTITIES_PER_SNAPSHOT: int = 128
|
||||
## Keeps unreliable movement envelopes below ENet's practical MTU while
|
||||
## allowing reliable population envelopes to carry a larger initial state.
|
||||
const SNAPSHOT_ENTITIES_PER_ENVELOPE: int = 4
|
||||
|
||||
|
||||
static func make_envelope(
|
||||
session_id: String,
|
||||
sequence: int,
|
||||
event_id: StringName,
|
||||
payload: Dictionary,
|
||||
) -> Dictionary:
|
||||
return {
|
||||
"envelope_version": ENVELOPE_VERSION,
|
||||
"session_id": session_id,
|
||||
"sequence": sequence,
|
||||
"event_id": str(event_id),
|
||||
"payload": payload.duplicate(true),
|
||||
}
|
||||
|
||||
|
||||
static func validate_envelope(value: Variant) -> bool:
|
||||
if typeof(value) != TYPE_DICTIONARY:
|
||||
return false
|
||||
var data: Dictionary = value
|
||||
return (
|
||||
typeof(data.get("envelope_version")) == TYPE_INT
|
||||
and int(data["envelope_version"]) == ENVELOPE_VERSION
|
||||
and typeof(data.get("session_id")) == TYPE_STRING
|
||||
and not str(data["session_id"]).is_empty()
|
||||
and str(data["session_id"]).length() <= MAX_SESSION_ID_LENGTH
|
||||
and typeof(data.get("sequence")) == TYPE_INT
|
||||
and int(data["sequence"]) >= 0
|
||||
and typeof(data.get("event_id")) == TYPE_STRING
|
||||
and not str(data["event_id"]).is_empty()
|
||||
and str(data["event_id"]).length() <= MAX_EVENT_ID_LENGTH
|
||||
and typeof(data.get("payload")) == TYPE_DICTIONARY
|
||||
)
|
||||
|
||||
|
||||
static func validate_entity_state(value: Variant) -> bool:
|
||||
if typeof(value) != TYPE_DICTIONARY:
|
||||
return false
|
||||
var data: Dictionary = value
|
||||
var position: Variant = data.get("position")
|
||||
if typeof(position) != TYPE_ARRAY or position.size() != 3:
|
||||
return false
|
||||
for component: Variant in position:
|
||||
if typeof(component) not in [TYPE_FLOAT, TYPE_INT]:
|
||||
return false
|
||||
if not is_finite(float(component)):
|
||||
return false
|
||||
return (
|
||||
typeof(data.get("entity_id")) == TYPE_STRING
|
||||
and not str(data["entity_id"]).is_empty()
|
||||
and str(data["entity_id"]).length() <= MAX_ENTITY_ID_LENGTH
|
||||
and typeof(data.get("type_id")) == TYPE_STRING
|
||||
and not str(data["type_id"]).is_empty()
|
||||
and str(data["type_id"]).length() <= MAX_TYPE_ID_LENGTH
|
||||
and typeof(data.get("yaw")) in [TYPE_FLOAT, TYPE_INT]
|
||||
and is_finite(float(data["yaw"]))
|
||||
and typeof(data.get("revision")) == TYPE_INT
|
||||
and int(data["revision"]) >= 0
|
||||
)
|
||||
|
||||
|
||||
static func vector3_to_array(value: Vector3) -> Array[float]:
|
||||
return [value.x, value.y, value.z]
|
||||
|
||||
|
||||
static func array_to_vector3(value: Variant) -> Vector3:
|
||||
if typeof(value) != TYPE_ARRAY or value.size() != 3:
|
||||
return Vector3(INF, INF, INF)
|
||||
for component: Variant in value:
|
||||
if typeof(component) not in [TYPE_FLOAT, TYPE_INT]:
|
||||
return Vector3(INF, INF, INF)
|
||||
if not is_finite(float(component)):
|
||||
return Vector3(INF, INF, INF)
|
||||
return _array_to_vector3(value)
|
||||
|
||||
|
||||
static func _array_to_vector3(value: Array) -> Vector3:
|
||||
return Vector3(float(value[0]), float(value[1]), float(value[2]))
|
||||
1
network/network_world_spawn_protocol.gd.uid
Normal file
1
network/network_world_spawn_protocol.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://wstcwpwk41mf
|
||||
1126
network/network_world_spawn_service.gd
Normal file
1126
network/network_world_spawn_service.gd
Normal file
File diff suppressed because it is too large
Load diff
1
network/network_world_spawn_service.gd.uid
Normal file
1
network/network_world_spawn_service.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://bmuhkkl2cxsck
|
||||
Loading…
Add table
Add a link
Reference in a new issue