Add map serialization/deserialization (incomplete)

This commit is contained in:
Hamcha 2020-07-13 21:01:36 +02:00
parent a13eb426ef
commit e1221af9ec
Signed by: hamcha
GPG Key ID: 41467804B19A3315
30 changed files with 505 additions and 183 deletions

View File

@ -2,8 +2,8 @@ extends Area2D
class_name ActivationRange class_name ActivationRange
signal player_entered() signal player_entered(player)
signal player_left() signal player_left(player)
func _ready(): func _ready():
connect("body_entered", self, "_body_entered") connect("body_entered", self, "_body_entered")
@ -14,8 +14,8 @@ func in_range():
func _body_entered(body: Node): func _body_entered(body: Node):
if body == $"/root/scene/world".player: if body == $"/root/scene/world".player:
emit_signal("player_entered") emit_signal("player_entered", body)
func _body_left(body: Node): func _body_left(body: Node):
if body == $"/root/scene/world".player: if body == $"/root/scene/world".player:
emit_signal("player_left") emit_signal("player_left", body)

View File

@ -19,14 +19,10 @@ var powered = false setget set_powered
func get_wired() -> bool: func get_wired() -> bool:
return socket != null return socket != null
func set_powered(val: bool) -> void: remotesync func set_powered(val: bool) -> void:
var current = powered var current = powered
powered = val powered = val
if current and not val: if current and not val:
emit_signal("power_disconnected") emit_signal("power_disconnected")
elif not current and val: elif not current and val:
emit_signal("power_connected") emit_signal("power_connected")
func _physics_process(_delta: float) -> void:
if wired:
pass

36
Actors/Meta/POI/POI.gd Normal file
View File

@ -0,0 +1,36 @@
tool
extends Node2D
class_name POI
enum POIType {
Null,
SpawnPoint
}
enum POIClass {
Null,
Player
}
export(POIType) var poitype = POIType.Null
export(POIClass) var poiclass = POIClass.Null
func _draw():
if Engine.editor_hint:
match poitype:
POIType.SpawnPoint:
match poiclass:
POIClass.Player:
draw_arc(Vector2.ZERO, 10, 0, PI*2, 16, Color.red, 2)
func serialize():
return {
"poitype": poitype,
"poiclass": poiclass
}
func deserialize(data):
poitype = data["poitype"]
poiclass = data["poiclass"]

9
Actors/Meta/POI/POI.tscn Normal file
View File

@ -0,0 +1,9 @@
[gd_scene load_steps=2 format=2]
[ext_resource path="res://Actors/Meta/POI/POI.gd" type="Script" id=1]
[node name="NullPOI" type="Node2D"]
position = Vector2( 208, 256 )
script = ExtResource( 1 )
poitype = 1
poiclass = 1

View File

@ -1,12 +0,0 @@
tool
extends Node2D
class_name SpawnpointPlayer
var poitype = POIData.POIType.SpawnPoint
var poiclass = POIData.POIClass.Player
func _draw():
if Engine.editor_hint:
draw_arc(Vector2.ZERO, 10, 0, PI*2, 16, Color.red)

View File

@ -102,3 +102,13 @@ func _power_status_changed(powered: bool) -> void:
$ScreenAnimation.play("on") $ScreenAnimation.play("on")
else: else:
$ScreenAnimation.play("off") $ScreenAnimation.play("off")
func serialize():
return {
"direction": direction,
"computer_type": computer_type
}
func deserialize(data):
set_direction(data["direction"])
set_type(data["computer_type"])

View File

@ -14,33 +14,40 @@ onready var manager = $PowerManager as PowerManager
signal changed(open) signal changed(open)
func _ready(): func _ready():
if interlockTargetPath != null: if is_network_master():
interlockTarget = get_node_or_null(interlockTargetPath) if interlockTargetPath != null:
if not Engine.editor_hint: interlockTarget = get_node_or_null(interlockTargetPath)
activationRange.visible = true if not Engine.editor_hint:
activationRange.visible = true
func set_open(open: bool): master func set_open(open: bool):
if not manager: if not manager:
return return
manager.power_usage = active_usage manager.power_usage = active_usage
if manager.powered: if manager.powered:
if open: if open:
$Sprite.play("open")
if interlockTarget != null: if interlockTarget != null:
interlockTarget.set_open(false) interlockTarget.set_open(false)
else: rpc("anim_open", open)
$Sprite.play("close")
remotesync func anim_open(open: bool):
if open:
$Sprite.play("open")
else:
$Sprite.play("close")
func _animation_finished(): func _animation_finished():
if manager: if is_network_master():
manager.power_usage = idle_usage if manager:
manager.power_usage = idle_usage
if $Sprite.animation == "open":
# Start timer for auto-close
$Timer.start()
if $Sprite.animation == "open": if $Sprite.animation == "open":
# Disable collider # Disable collider
collision_layer = 16 collision_layer = 16
collision_mask = 16 collision_mask = 16
emit_signal("changed", true) emit_signal("changed", true)
# Start timer for auto-close
$Timer.start()
else: else:
# Enable collider # Enable collider
collision_mask = 1 collision_mask = 1
@ -52,7 +59,13 @@ func _input_event(_viewport, event, _shape_idx):
if event is InputEventMouseButton and event.pressed: if event is InputEventMouseButton and event.pressed:
# Must be in activation range # Must be in activation range
if activationRange.in_range(): if activationRange.in_range():
set_open($Sprite.animation == "close") rpc("set_open", $Sprite.animation == "close")
func _close_timer_triggered(): master func _close_timer_triggered():
$Sprite.play("close") rpc("set_open", false)
func serialize():
return {}
func deserialize(data):
pass

View File

@ -62,3 +62,17 @@ func refresh_sprite() -> void:
socket.material.set_shader_param("cable_color", sink_color) socket.material.set_shader_param("cable_color", sink_color)
Flow.BIDIRECTIONAL: Flow.BIDIRECTIONAL:
socket.material.set_shader_param("cable_color", bidirectional_color) socket.material.set_shader_param("cable_color", bidirectional_color)
func serialize():
return {
"direction": direction,
"flow": flow,
"network": "", #TODO
"connections": [] #TODO
}
func deserialize(data):
set_direction(data["direction"])
set_flow(data["flow"])
#TODO Connections
#TODO Network

View File

@ -54,3 +54,13 @@ func _input_event(_viewport, event, _shape_idx):
if activationRange.in_range(): if activationRange.in_range():
# TODO # TODO
pass pass
func serialize():
return {
"direction": direction,
"strength": strength
}
func deserialize(data):
set_direction(data["direction"])
set_strength(data["strength"])

View File

@ -17,11 +17,11 @@ func _ready():
activationRange.visible = true activationRange.visible = true
refresh_sprite() refresh_sprite()
func set_direction(dir): remotesync func set_direction(dir):
direction = dir direction = dir
refresh_sprite() refresh_sprite()
func set_lit(val): remotesync func set_lit(val):
lit = val lit = val
update_light() update_light()
refresh_sprite() refresh_sprite()
@ -35,7 +35,7 @@ func refresh_sprite():
match direction: match direction:
Direction.DOWN: Direction.DOWN:
$light.region_rect.position = Vector2(32, lit_offset) $light.region_rect.position = Vector2(32, lit_offset)
rot =0 rot = 0
Direction.UP: Direction.UP:
$light.region_rect.position = Vector2(0, lit_offset) $light.region_rect.position = Vector2(0, lit_offset)
rot = PI rot = PI
@ -47,14 +47,13 @@ func refresh_sprite():
rot = PI/2 rot = PI/2
$Light2D.rotation = rot $Light2D.rotation = rot
$ActivationRange.rotation = rot $ActivationRange.rotation = rot
func _input_event(_viewport, event, _shape_idx): func _input_event(_viewport, event, _shape_idx):
if Engine.editor_hint: if Engine.editor_hint:
return return
if event is InputEventMouseButton and event.pressed: if event is InputEventMouseButton and event.pressed:
if activationRange.in_range(): if activationRange.in_range():
set_lit(!lit) rpc("set_lit", !lit)
func _power_status_changed(_powered: bool) -> void: func _power_status_changed(_powered: bool) -> void:
update_light() update_light()
@ -62,3 +61,13 @@ func _power_status_changed(_powered: bool) -> void:
func update_light(): func update_light():
$Light2D.enabled = lit and (manager != null and manager.powered) $Light2D.enabled = lit and (manager != null and manager.powered)
func serialize():
return {
"direction": direction,
"lit": lit
}
func deserialize(data):
set_direction(data["direction"])
set_lit(data["lit"])

View File

@ -80,3 +80,15 @@ func set_max_charge(val: float) -> void:
func set_charge(val: float) -> void: func set_charge(val: float) -> void:
current_charge = val current_charge = val
$Control/PowerUI.set_current_charge(current_charge) $Control/PowerUI.set_current_charge(current_charge)
func serialize():
return {
"current_charge": current_charge,
"max_charge_rate": max_charge_rate,
"max_discharge_rate": max_discharge_rate
}
func deserialize(data):
set_charge(data["current_charge"])
set_max_charge(data["max_charge_rate"])
set_max_discharge(data["max_discharge_rate"])

View File

@ -2,3 +2,8 @@ extends StaticBody2D
class_name GameObjectScanner class_name GameObjectScanner
func serialize():
return {}
func deserialize(data):
pass

View File

@ -5,11 +5,17 @@ const EPSILON = 0.1
const MAX_STAMINA = 3.0 const MAX_STAMINA = 3.0
const BOOST_COEFF = 50.0 const BOOST_COEFF = 50.0
const STAMINA_RECOVER_RATE = 0.3 const STAMINA_RECOVER_RATE = 0.3
const NET_KEY_TRANSFORM_DELAY = 0.2
var velocity = Vector2.ZERO var velocity = Vector2.ZERO
var grip = 1.0 var grip = 1.0
var stamina = MAX_STAMINA var stamina = MAX_STAMINA
var speed_boost = 0 var speed_boost = 0
var transform_update_remaining = 0.0
puppet var pup_motion = Vector2.ZERO
puppet var pup_velocity = Vector2.ZERO
puppet var pup_transform = Transform()
onready var scene = $"/root/scene" onready var scene = $"/root/scene"
onready var world = $"/root/scene/world" onready var world = $"/root/scene/world"
@ -21,33 +27,48 @@ func _ready():
$Camera.current = is_controlled $Camera.current = is_controlled
func _physics_process(delta): func _physics_process(delta):
var motion = Vector2( var motion = Vector2.ZERO
Input.get_action_strength("ui_right")-Input.get_action_strength("ui_left"), if is_network_master():
Input.get_action_strength("ui_down")-Input.get_action_strength("ui_up")) motion = Vector2(
Input.get_action_strength("ui_right")-Input.get_action_strength("ui_left"),
Input.get_action_strength("ui_down")-Input.get_action_strength("ui_up"))
# Check sprinting
var speed = BASE_SPEED
if Input.is_action_pressed("sprint"):
if motion.length() > EPSILON and stamina > 0:
speed_boost += BOOST_COEFF * delta * ease(stamina/MAX_STAMINA, 1.1)
stamina -= delta
update()
else:
if stamina < MAX_STAMINA:
stamina += delta * STAMINA_RECOVER_RATE
update()
# Apply friction to speed boost and the boost itself, if any
if speed_boost > 0:
speed_boost /= 2
speed *= 1.0 + speed_boost
if speed_boost < EPSILON:
speed_boost = 0
# Set velocity
velocity = velocity * (1.0-grip) + motion.clamped(1.0) * speed * grip
rset("pup_motion", motion)
rset("pup_velocity", velocity)
rset("pup_transform", global_transform)
else:
velocity = pup_velocity
motion = pup_motion
if transform_update_remaining <= 0.0:
transform_update_remaining = NET_KEY_TRANSFORM_DELAY
global_transform = pup_transform
else:
transform_update_remaining -= delta
if motion.length() > EPSILON: if motion.length() > EPSILON:
$Sprite/AnimationTree.set("parameters/direction/blend_position", motion) $Sprite/AnimationTree.set("parameters/direction/blend_position", motion)
# Check sprinting
var speed = BASE_SPEED
if Input.is_action_pressed("sprint"):
if motion.length() > EPSILON and stamina > 0:
speed_boost += BOOST_COEFF * delta * ease(stamina/MAX_STAMINA, 1.1)
stamina -= delta
update()
else:
if stamina < MAX_STAMINA:
stamina += delta * STAMINA_RECOVER_RATE
update()
# Apply friction to speed boost and the boost itself, if any
if speed_boost > 0:
speed_boost /= 2
speed *= 1.0 + speed_boost
if speed_boost < EPSILON:
speed_boost = 0
# Set velocity
velocity = velocity * (1.0-grip) + motion.clamped(1.0) * speed * grip
velocity = move_and_slide(velocity) velocity = move_and_slide(velocity)
# Check what tile I'm on # Check what tile I'm on
@ -63,8 +84,9 @@ func set_is_controlled(val):
$Camera.current = val $Camera.current = val
func _draw(): func _draw():
if stamina+EPSILON < MAX_STAMINA: if is_network_master():
draw_circle_arc_poly(Vector2(-10, -30), 6, 0, stamina/MAX_STAMINA * 360, Color.orange) if stamina+EPSILON < MAX_STAMINA:
draw_circle_arc_poly(Vector2(-10, -30), 6, 0, stamina/MAX_STAMINA * 360, Color.orange)
func draw_circle_arc_poly(center, radius, angle_from, angle_to, color): func draw_circle_arc_poly(center, radius, angle_from, angle_to, color):
var nb_points = 32 var nb_points = 32

View File

@ -8,13 +8,13 @@ var neighbours = []
var network: PowerNetwork = null var network: PowerNetwork = null
func _ready(): master func _ready():
if network == null: if network == null:
network = PowerNetwork.new() network = PowerNetwork.new()
network.add_node(self) network.add_node(self)
$"/root/scene/systems".add_child(network, true) $"/root/scene/systems".add_child(network, true)
func _physics_process(_delta): master func _physics_process(_delta):
if PowerNetwork.DEBUG: if PowerNetwork.DEBUG:
update() update()
@ -25,13 +25,13 @@ func _draw():
var delta = (neighbour.global_position - global_position) / global_scale var delta = (neighbour.global_position - global_position) / global_scale
draw_line(center, delta + center, network.debugColor, 2) draw_line(center, delta + center, network.debugColor, 2)
func _got_neighbour(area: Area2D): master func _got_neighbour(area: Area2D):
if area == self: if area == self:
return return
if area.network == null: if area.network == null:
area.network = network area.network = network
network.add_node(area) network.rpc("add_node", area)
elif area.network != network: elif area.network != network:
# Merge networks # Merge networks
network.join(area.network) network.rpc("join", area.network)
neighbours.push_back(area) neighbours.push_back(area)

View File

@ -2,7 +2,7 @@ extends Node
class_name PowerNetwork class_name PowerNetwork
const DEBUG = false const DEBUG = true
var nodes = [] var nodes = []
var sockets = [] var sockets = []
@ -16,12 +16,12 @@ func _ready():
name = "PowerNetwork" name = "PowerNetwork"
debugColor = Color.from_hsv(randf(), 0.8, 0.8) debugColor = Color.from_hsv(randf(), 0.8, 0.8)
func add_node(node) -> void: remotesync func add_node(node) -> void:
nodes.append(node) nodes.append(node)
if "connections" in node: if "connections" in node:
sockets.append(node) sockets.append(node)
func remove_node(node) -> void: remotesync func remove_node(node) -> void:
var node_idx = nodes.find(node) var node_idx = nodes.find(node)
if node_idx >= 0: if node_idx >= 0:
nodes.remove(node_idx) nodes.remove(node_idx)
@ -31,7 +31,7 @@ func remove_node(node) -> void:
# Do other splitting here # Do other splitting here
node.network = null node.network = null
func join(network) -> void: remotesync func join(network) -> void:
for node in network.nodes: for node in network.nodes:
nodes.append(node) nodes.append(node)
node.network = self node.network = self
@ -42,6 +42,8 @@ func join(network) -> void:
network.queue_free() network.queue_free()
func _physics_process(_delta: float) -> void: func _physics_process(_delta: float) -> void:
if not is_network_master():
return
# Recalculate power availability and usage # Recalculate power availability and usage
total_source = 0 total_source = 0
total_usage = 0 total_usage = 0
@ -70,9 +72,11 @@ func _physics_process(_delta: float) -> void:
if sink.power_usage > 0: if sink.power_usage > 0:
if available_supply > sink.power_usage: if available_supply > sink.power_usage:
available_supply -= sink.power_usage available_supply -= sink.power_usage
sink.powered = true if not sink.powered:
sink.rpc("set_powered", true)
else: else:
sink.powered = false if sink.powered:
sink.rpc("set_powered", false)
# Update available power to sinks # Update available power to sinks
for sink in sinks: for sink in sinks:
sink.available = available_supply sink.available = available_supply

View File

@ -1,9 +0,0 @@
class_name POIData
enum POIType {
SpawnPoint
}
enum POIClass {
Player
}

View File

@ -5,9 +5,39 @@ class_name GameInstance
onready var ui = $CanvasLayer/ui onready var ui = $CanvasLayer/ui
onready var world = $world onready var world = $world
onready var systems = $systems onready var systems = $systems
onready var netgame = $"/root/Multiplayer"
func _ready(): func _ready() -> void:
ui.connect("command", world, "process_command") ui.connect("command", world, "process_command")
if netgame.hosting:
world.load_map(netgame.get_current_map())
rpc("spawn_player", 1)
else:
world.load_map(GameWorld.Map.EMPTY)
rpc_id(1, "send_map")
yield(world.map, "map_received")
rpc_id(1, "ready_to_spawn")
master func send_map() -> void:
var id = get_tree().get_rpc_sender_id()
print("sending map data to ", id)
world.map.send_data(id)
master func ready_to_spawn() -> void:
var id = get_tree().get_rpc_sender_id()
print(id, " is ready to spawn players")
# Tell him everyone to spawn
var players = $world/players.get_children()
for player in players:
rpc_id(id, "spawn_player", player.get_network_master())
# Then spawn him as well
rpc("spawn_player", id)
remotesync func spawn_player(id):
print("must spawn ", id)
world.spawn_player(id, multiplayer.get_network_unique_id() == id)
func process_command(cmd: UICommand): func process_command(cmd: UICommand):
match cmd.cmd_type: match cmd.cmd_type:
@ -15,3 +45,4 @@ func process_command(cmd: UICommand):
world.map.ship_speed = cmd.cmd_args[0] world.map.ship_speed = cmd.cmd_args[0]
UICommand.CommandType.SetShipDirection: UICommand.CommandType.SetShipDirection:
world.map.ship_direction = cmd.cmd_args[0] world.map.ship_direction = cmd.cmd_args[0]

View File

@ -12,7 +12,6 @@ script = ExtResource( 5 )
[node name="world" type="Node2D" parent="."] [node name="world" type="Node2D" parent="."]
scale = Vector2( 2, 2 ) scale = Vector2( 2, 2 )
script = ExtResource( 4 ) script = ExtResource( 4 )
mapToLoad = 1
[node name="players" type="Node2D" parent="world"] [node name="players" type="Node2D" parent="world"]

View File

@ -18,9 +18,12 @@ var ms_active = false
var ms_key = "" var ms_key = ""
var server_name = "" var server_name = ""
var hosting = false
export var player_name = "" export var player_name = ""
var player_info = {} var player_info = {}
var round_info = {}
onready var scene_manager = $"/root/SceneManager" onready var scene_manager = $"/root/SceneManager"
@ -84,10 +87,16 @@ func host():
return return
get_tree().network_peer = peer get_tree().network_peer = peer
print("Hosting") print("Hosting")
hosting = true
server_name = player_name + "'s server" server_name = player_name + "'s server"
player_info[1] = { name=player_name } player_info[1] = { "name": player_name }
round_info = { "map": "odyssey" }
scene_manager.load_scene_with_args("res://Scenes/Game.tscn", []) scene_manager.loading_text = null
scene_manager.load_scene("res://Scenes/Game.tscn", [
"res://Scenes/Maps/odyssey.tscn"
])
# Add to master server # Add to master server
create_ms_entry() create_ms_entry()
@ -121,8 +130,7 @@ func leave():
func _player_connected(id): func _player_connected(id):
rpc_id(id, "register_player", player_name) rpc_id(id, "register_player", player_name)
if get_tree().is_network_server(): if get_tree().is_network_server():
pass rpc_id(id, "_handshake", { "round": round_info, "players": player_info })
#rpc_id(id, "spawn_players", mapLoader.map.all_players())
func _player_disconnected(id): func _player_disconnected(id):
print(player_info[id].name, " (", id, ") disconnected") print(player_info[id].name, " (", id, ") disconnected")
@ -130,7 +138,8 @@ func _player_disconnected(id):
func _connected_ok(): func _connected_ok():
print("Connected to server") print("Connected to server")
scene_manager.loading_text = "Connected to server" scene_manager.loading_text = null
scene_manager.load_scene("res://Scenes/Game.tscn", [])
func _server_disconnected(): func _server_disconnected():
print("Disconnected from server") print("Disconnected from server")
@ -143,12 +152,9 @@ remote func register_player(username: String):
player_info[id] = { name=username } player_info[id] = { name=username }
print(player_info[id].name, " (", id, ") connected") print(player_info[id].name, " (", id, ") connected")
remote func spawn_players(players): remote func _handshake(infos):
for player_id in players: round_info = infos["round"]
pass player_info = infos["players"]
#mapLoader.map.spawn_player(player_id)
# Spawn myself as well
#mapLoader.map.rpc("spawn_player", get_tree().network_peer.get_unique_id())
func _ms_request(endpoint: String, data): func _ms_request(endpoint: String, data):
var http_request = HTTPRequest.new() var http_request = HTTPRequest.new()
@ -203,3 +209,12 @@ func _notification(what):
if what == MainLoop.NOTIFICATION_WM_QUIT_REQUEST: if what == MainLoop.NOTIFICATION_WM_QUIT_REQUEST:
leave() leave()
yield(self, "left") yield(self, "left")
func get_current_map():
match round_info.map:
"odyssey":
return GameWorld.Map.ODYSSEY
"runtime":
return GameWorld.Map.RUNTIME
_:
return GameWorld.Map.EMPTY

View File

@ -1,29 +1,40 @@
extends Node extends Node
var queue = null var queue = ResourceQueue.new()
var target_scene = null var target_scene = null
var loading_text = null var loading_text = null
var loader = preload("res://Scenes/Loader.tscn") var loader = preload("res://Scenes/Loader.tscn")
func enter_loader(): func _ready() -> void:
queue.start()
func enter_loader() -> void:
get_tree().change_scene_to(loader) get_tree().change_scene_to(loader)
func load_scene_with_args(scene_path: String, _args: Array): func load_scene(scene_path: String, dependencies: Array) -> void:
queue = ResourceQueue.new()
queue.start()
target_scene = scene_path target_scene = scene_path
queue.queue_resource(scene_path) queue.queue_resource(scene_path)
for dep in dependencies:
queue.queue_resource(dep)
func _physics_process(delta): func _physics_process(_delta: float) -> void:
if queue != null and target_scene != null: if target_scene != null:
if queue.is_ready(target_scene): var remaining = queue.pending.size()
for path in queue.pending:
if queue.is_ready(path):
remaining -= 1
if remaining == 0:
get_tree().change_scene_to(queue.get_resource(target_scene)) get_tree().change_scene_to(queue.get_resource(target_scene))
queue = null
target_scene = null target_scene = null
func get_progress(): func get_progress() -> String:
if loading_text != null: if loading_text != null:
return loading_text return loading_text
if queue != null and target_scene != null: var count = queue.pending.size()
return "Loading scene (" + str(queue.get_progress(target_scene)) + ")" if count == 0:
return "Reticulating splines"
var current = 0
for path in queue.pending:
current += queue.get_progress(path)
return "Loading scene (" + str(round(current/count*100)) + "%)"

View File

@ -3,6 +3,8 @@ extends Node2D
class_name GameMap class_name GameMap
signal map_received()
var ship_direction = 0 var ship_direction = 0
var ship_speed = 0 var ship_speed = 0
@ -31,10 +33,18 @@ func _ready():
if Engine.editor_hint: if Engine.editor_hint:
return return
$editor.queue_free() $editor.queue_free()
set_unlit(false) set_unlit(true)
if not is_network_master():
return
# Run special tiling
$walls.run_conversions()
# Electricity setup # Electricity setup
make_electric_probes($cables, "Wire") make_electric_probes($cables, "Wire")
print(serialize())
func _process(delta: float): func _process(delta: float):
if Engine.editor_hint: if Engine.editor_hint:
@ -53,6 +63,71 @@ func _process(delta: float):
$deepspace.rotation = current_ship_direction-PI/2 $deepspace.rotation = current_ship_direction-PI/2
$deepspace.region_rect.position += Vector2(sin(current_ship_direction), cos(current_ship_direction)) * current_ship_speed * delta $deepspace.region_rect.position += Vector2(sin(current_ship_direction), cos(current_ship_direction)) * current_ship_speed * delta
# Serialization / Deserialization
func serialize() -> Dictionary:
# Get tilemap data
var tilemapdata = {}
for tilemap in tilemaps:
var data = []
for cell in tilemap.get_used_cells():
data.append([cell, tilemap.get_cellv(cell)])
tilemapdata[tilemap.name] = data
# Get objects
var engines = serialize_children($engines)
var objects = serialize_children($objects)
var lights = serialize_children($lights)
var pois = serialize_children($pois)
return {
"tilemaps": tilemapdata,
"engines": engines,
"objects": objects,
"lights": lights,
"pois": pois
}
func deserialize(data: Dictionary) -> void:
for tilemap in data["tilemaps"]:
var tilemap_node = get_node(tilemap) as TileMap
for tile in data["tilemaps"][tilemap]:
tilemap_node.set_cellv(tile[0], tile[1])
tilemap_node.update_bitmask_region()
tilemap_node.update_dirty_quadrants()
deserialize_children($engines, data["engines"])
deserialize_children($objects, data["objects"])
deserialize_children($lights, data["lights"])
deserialize_children($pois, data["pois"])
$walls.run_conversions()
master func send_data(id: int) -> void:
rpc_id(id, "receive_data", serialize())
puppet func receive_data(data: Dictionary) -> void:
deserialize(data)
print("Received map data from master")
emit_signal("map_received")
func serialize_children(node: Node) -> Dictionary:
var data = {}
for child in node.get_children():
data[child.name] = {
"filename": child.filename,
"data": child.serialize(),
"transform": child.transform
}
return data
func deserialize_children(node: Node, data: Dictionary) -> void:
for node_name in data:
var node_data = data[node_name] as Dictionary
var node_scene = load(node_data.filename).instance()
node_scene.name = node_name
node_scene.transform = node_data.transform
node_scene.deserialize(node_data.data)
node.add_child(node_scene, true)
# Lighting # Lighting
func set_unlit(val: bool): func set_unlit(val: bool):

View File

@ -1,17 +0,0 @@
extends TileMap
const objects = {
"Door": preload("res://Actors/Objects/Door/Door.tscn")
}
func _ready():
for cell in get_used_cells():
var id = get_cellv(cell)
var name = tile_set.tile_get_name(id)
if objects.has(name):
var obj = objects[name].instance() as Node2D
add_child(obj)
obj.transform.origin = map_to_world(cell)
else:
print("Placed object tile ", name, " at ", cell, " but has no object associated!")
set_cellv(cell, -1)

96
Scenes/Maps/empty.tscn Normal file
View File

@ -0,0 +1,96 @@
[gd_scene load_steps=10 format=2]
[ext_resource path="res://Graphics/tgstation/walls.tres" type="TileSet" id=1]
[ext_resource path="res://Graphics/tgstation/1x1.tres" type="TileSet" id=2]
[ext_resource path="res://Scenes/Rendering/MapTiles.gd" type="Script" id=3]
[ext_resource path="res://Scenes/Map.gd" type="Script" id=4]
[ext_resource path="res://Graphics/space.png" type="Texture" id=7]
[ext_resource path="res://Graphics/tgstation/floor.tres" type="TileSet" id=9]
[ext_resource path="res://Graphics/tgstation/base.tres" type="TileSet" id=11]
[ext_resource path="res://Graphics/tgstation/cables.tres" type="TileSet" id=13]
[sub_resource type="CanvasItemMaterial" id=1]
light_mode = 1
[node name="map" type="Node2D"]
script = ExtResource( 4 )
[node name="darkness" type="CanvasModulate" parent="."]
visible = false
color = Color( 0, 0, 0, 1 )
[node name="editor" type="Node2D" parent="."]
[node name="deepspace" type="Sprite" parent="."]
material = SubResource( 1 )
texture = ExtResource( 7 )
region_enabled = true
region_rect = Rect2( 0, 0, 10000, 10000 )
__meta__ = {
"_edit_group_": true,
"_edit_lock_": true
}
[node name="base" type="TileMap" parent="."]
z_index = 1
tile_set = ExtResource( 11 )
cell_size = Vector2( 32, 32 )
cell_quadrant_size = 32
occluder_light_mask = -2147483647
format = 1
[node name="cables" type="TileMap" parent="."]
z_index = 2
tile_set = ExtResource( 13 )
cell_size = Vector2( 32, 32 )
cell_quadrant_size = 32
occluder_light_mask = -2147483647
format = 1
[node name="floor" type="TileMap" parent="."]
z_index = 3
tile_set = ExtResource( 9 )
cell_size = Vector2( 32, 32 )
cell_quadrant_size = 32
occluder_light_mask = -2147483647
format = 1
[node name="walls" type="TileMap" parent="."]
z_index = 4
tile_set = ExtResource( 1 )
cell_size = Vector2( 32, 32 )
cell_quadrant_size = 32
occluder_light_mask = -2147483647
format = 1
script = ExtResource( 3 )
extended_tilemap_node = NodePath("../1x1")
[node name="1x1" type="TileMap" parent="."]
z_index = 5
tile_set = ExtResource( 2 )
cell_size = Vector2( 16, 16 )
format = 1
[node name="engines" type="Node2D" parent="."]
modulate = Color( 0.980392, 0.980392, 0.980392, 1 )
__meta__ = {
"_edit_group_": true,
"_edit_lock_": true
}
[node name="objects" type="Node2D" parent="."]
z_index = 10
__meta__ = {
"_editor_description_": ""
}
[node name="lights" type="Node2D" parent="."]
modulate = Color( 0.980392, 0.980392, 0.980392, 1 )
z_index = 11
__meta__ = {
"_edit_group_": true,
"_edit_lock_": true
}
[node name="pois" type="Node2D" parent="."]
z_index = 999

View File

@ -1,9 +0,0 @@
extends GameMap
func _ready():
tilemaps = [
$base,
$cables,
$floor,
$walls
]

View File

@ -4,7 +4,7 @@
[ext_resource path="res://Graphics/tgstation/1x1.tres" type="TileSet" id=2] [ext_resource path="res://Graphics/tgstation/1x1.tres" type="TileSet" id=2]
[ext_resource path="res://Scenes/Rendering/MapTiles.gd" type="Script" id=3] [ext_resource path="res://Scenes/Rendering/MapTiles.gd" type="Script" id=3]
[ext_resource path="res://Actors/Objects/Door/Door.tscn" type="PackedScene" id=4] [ext_resource path="res://Actors/Objects/Door/Door.tscn" type="PackedScene" id=4]
[ext_resource path="res://Scenes/Maps/odyssey.gd" type="Script" id=5] [ext_resource path="res://Scenes/Map.gd" type="Script" id=5]
[ext_resource path="res://Actors/Objects/Computer/Computer.tscn" type="PackedScene" id=6] [ext_resource path="res://Actors/Objects/Computer/Computer.tscn" type="PackedScene" id=6]
[ext_resource path="res://Graphics/space.png" type="Texture" id=7] [ext_resource path="res://Graphics/space.png" type="Texture" id=7]
[ext_resource path="res://Actors/Objects/Lightbulb/Lightbulb.tscn" type="PackedScene" id=8] [ext_resource path="res://Actors/Objects/Lightbulb/Lightbulb.tscn" type="PackedScene" id=8]
@ -14,7 +14,7 @@
[ext_resource path="res://Actors/Objects/PowerStorage/PowerStorage.tscn" type="PackedScene" id=12] [ext_resource path="res://Actors/Objects/PowerStorage/PowerStorage.tscn" type="PackedScene" id=12]
[ext_resource path="res://Graphics/tgstation/cables.tres" type="TileSet" id=13] [ext_resource path="res://Graphics/tgstation/cables.tres" type="TileSet" id=13]
[ext_resource path="res://Actors/Objects/ElectricSocket/ElectricSocket.tscn" type="PackedScene" id=14] [ext_resource path="res://Actors/Objects/ElectricSocket/ElectricSocket.tscn" type="PackedScene" id=14]
[ext_resource path="res://Actors/Meta/POI/Spawnpoints/Player.gd" type="Script" id=15] [ext_resource path="res://Actors/Meta/POI/POI.tscn" type="PackedScene" id=15]
[sub_resource type="CanvasItemMaterial" id=1] [sub_resource type="CanvasItemMaterial" id=1]
light_mode = 1 light_mode = 1
@ -152,7 +152,6 @@ interlockTargetPath = NodePath("../AirlockExt3")
[node name="ControlComp" parent="objects" instance=ExtResource( 6 )] [node name="ControlComp" parent="objects" instance=ExtResource( 6 )]
position = Vector2( 576, 256 ) position = Vector2( 576, 256 )
direction = 0 direction = 0
computer_type = 0
[node name="CommsComp" parent="objects" instance=ExtResource( 6 )] [node name="CommsComp" parent="objects" instance=ExtResource( 6 )]
position = Vector2( 576, 224 ) position = Vector2( 576, 224 )
@ -542,6 +541,4 @@ direction = 2
[node name="pois" type="Node2D" parent="."] [node name="pois" type="Node2D" parent="."]
z_index = 999 z_index = 999
[node name="SpawnpointPlayer" type="Node2D" parent="pois"] [node name="SpawnpointPlayer" parent="pois" instance=ExtResource( 15 )]
position = Vector2( 208, 256 )
script = ExtResource( 15 )

View File

@ -1,4 +0,0 @@
extends GameMap
func _ready():
set_unlit(true)

View File

@ -4,21 +4,27 @@
[ext_resource path="res://Graphics/tgstation/1x1.tres" type="TileSet" id=2] [ext_resource path="res://Graphics/tgstation/1x1.tres" type="TileSet" id=2]
[ext_resource path="res://Scenes/Rendering/MapTiles.gd" type="Script" id=3] [ext_resource path="res://Scenes/Rendering/MapTiles.gd" type="Script" id=3]
[ext_resource path="res://Graphics/tgstation/cables.tres" type="TileSet" id=4] [ext_resource path="res://Graphics/tgstation/cables.tres" type="TileSet" id=4]
[ext_resource path="res://Scenes/Maps/runtime.gd" type="Script" id=5] [ext_resource path="res://Actors/Meta/POI/POI.tscn" type="PackedScene" id=5]
[ext_resource path="res://Actors/Objects/Computer/Computer.tscn" type="PackedScene" id=6] [ext_resource path="res://Actors/Objects/Computer/Computer.tscn" type="PackedScene" id=6]
[ext_resource path="res://Graphics/space.png" type="Texture" id=7] [ext_resource path="res://Graphics/space.png" type="Texture" id=7]
[ext_resource path="res://Actors/Meta/POI/Spawnpoints/Player.gd" type="Script" id=8]
[ext_resource path="res://Graphics/tgstation/floor.tres" type="TileSet" id=9] [ext_resource path="res://Graphics/tgstation/floor.tres" type="TileSet" id=9]
[ext_resource path="res://Actors/Objects/Engine/Engine.tscn" type="PackedScene" id=10] [ext_resource path="res://Actors/Objects/Engine/Engine.tscn" type="PackedScene" id=10]
[ext_resource path="res://Graphics/tgstation/base.tres" type="TileSet" id=11] [ext_resource path="res://Graphics/tgstation/base.tres" type="TileSet" id=11]
[ext_resource path="res://Actors/Objects/PowerStorage/PowerStorage.tscn" type="PackedScene" id=12] [ext_resource path="res://Actors/Objects/PowerStorage/PowerStorage.tscn" type="PackedScene" id=12]
[ext_resource path="res://Actors/Objects/ElectricSocket/ElectricSocket.tscn" type="PackedScene" id=13] [ext_resource path="res://Actors/Objects/ElectricSocket/ElectricSocket.tscn" type="PackedScene" id=13]
[sub_resource type="CanvasItemMaterial" id=1] [sub_resource type="GDScript" id=1]
script/source = "extends GameMap
func _ready():
set_unlit(true)
"
[sub_resource type="CanvasItemMaterial" id=2]
light_mode = 1 light_mode = 1
[node name="map" type="Node2D"] [node name="map" type="Node2D"]
script = ExtResource( 5 ) script = SubResource( 1 )
[node name="darkness" type="CanvasModulate" parent="."] [node name="darkness" type="CanvasModulate" parent="."]
visible = false visible = false
@ -27,7 +33,7 @@ color = Color( 0, 0, 0, 1 )
[node name="editor" type="Node2D" parent="."] [node name="editor" type="Node2D" parent="."]
[node name="deepspace" type="Sprite" parent="."] [node name="deepspace" type="Sprite" parent="."]
material = SubResource( 1 ) material = SubResource( 2 )
texture = ExtResource( 7 ) texture = ExtResource( 7 )
region_enabled = true region_enabled = true
region_rect = Rect2( 0, 0, 10000, 10000 ) region_rect = Rect2( 0, 0, 10000, 10000 )
@ -183,6 +189,7 @@ __meta__ = {
[node name="pois" type="Node2D" parent="."] [node name="pois" type="Node2D" parent="."]
z_index = 999 z_index = 999
[node name="SpawnpointPlayer" type="Node2D" parent="pois"] [node name="SpawnpointPlayer" parent="pois" instance=ExtResource( 5 )]
position = Vector2( 112, 272 ) position = Vector2( 80, 272 )
script = ExtResource( 8 ) poitype = 1
poiclass = 1

View File

@ -12,7 +12,7 @@ export var shadow_intensity = 0.2
onready var extended_tilemap = get_node(extended_tilemap_node) as TileMap onready var extended_tilemap = get_node(extended_tilemap_node) as TileMap
func _ready(): func run_conversions():
# Make occluders # Make occluders
make_occluders() make_occluders()

View File

@ -2,30 +2,38 @@ extends Node2D
class_name GameWorld class_name GameWorld
enum Map { RUNTIME, ODYSSEY } enum Map { RUNTIME, ODYSSEY, EMPTY }
export(Map) var mapToLoad = Map.RUNTIME
const playerRes = preload("res://Actors/Player/Player.tscn") const playerRes = preload("res://Actors/Player/Player.tscn")
var map = null var map = null
var player = null var player = null
func _ready(): onready var scene_manager = $"/root/SceneManager"
match mapToLoad:
func load_map(map_name):
match map_name:
Map.RUNTIME: Map.RUNTIME:
map = load("res://Scenes/Maps/runtime.tscn").instance() map = scene_manager.queue.get_resource("res://Scenes/Maps/runtime.tscn").instance()
Map.ODYSSEY: Map.ODYSSEY:
map = load("res://Scenes/Maps/odyssey.tscn").instance() map = scene_manager.queue.get_resource("res://Scenes/Maps/odyssey.tscn").instance()
Map.EMPTY:
map = preload("res://Scenes/Maps/empty.tscn").instance()
add_child(map) add_child(map)
player = playerRes.instance()
player.is_controlled = true func spawn_player(peer: int, is_current_user: bool):
var spawnpoints = map.get_pois(POIData.POIType.SpawnPoint, POIData.POIClass.Player) var playerNode = playerRes.instance()
playerNode.set_network_master(peer, true)
playerNode.is_controlled = is_current_user
var spawnpoints = map.get_pois(POI.POIType.SpawnPoint, POI.POIClass.Player)
if spawnpoints.size() > 0: if spawnpoints.size() > 0:
player.transform.origin = (spawnpoints[0] as Node2D).transform.origin playerNode.transform.origin = (spawnpoints[0] as Node2D).transform.origin
else: else:
print("Map does not have Player spawnpoint POI! Spawning at origin (very bad)") print("Map does not have Player spawnpoint POI! Spawning at origin (very bad)")
$players.add_child(player) $players.add_child(playerNode, true)
for tilemap in map.tilemaps: if is_current_user:
if tilemap is MapTiles: player = playerNode
tilemap.set_occluder_origin(player) for tilemap in map.tilemaps:
if tilemap is MapTiles:
tilemap.set_occluder_origin(playerNode)
return playerNode

View File

@ -74,10 +74,10 @@ _global_script_classes=[ {
"language": "GDScript", "language": "GDScript",
"path": "res://Scenes/Rendering/Occluder.gd" "path": "res://Scenes/Rendering/Occluder.gd"
}, { }, {
"base": "Reference", "base": "Node2D",
"class": "POIData", "class": "POI",
"language": "GDScript", "language": "GDScript",
"path": "res://Classes/POI.gd" "path": "res://Actors/Meta/POI/POI.gd"
}, { }, {
"base": "Node", "base": "Node",
"class": "PowerManager", "class": "PowerManager",
@ -99,11 +99,6 @@ _global_script_classes=[ {
"language": "GDScript", "language": "GDScript",
"path": "res://Classes/ResourceQueue.gd" "path": "res://Classes/ResourceQueue.gd"
}, { }, {
"base": "Node2D",
"class": "SpawnpointPlayer",
"language": "GDScript",
"path": "res://Actors/Meta/POI/Spawnpoints/Player.gd"
}, {
"base": "Reference", "base": "Reference",
"class": "UICommand", "class": "UICommand",
"language": "GDScript", "language": "GDScript",
@ -123,12 +118,11 @@ _global_script_class_icons={
"GameWorld": "", "GameWorld": "",
"MapTiles": "", "MapTiles": "",
"Occluder": "", "Occluder": "",
"POIData": "", "POI": "",
"PowerManager": "", "PowerManager": "",
"PowerNetwork": "", "PowerNetwork": "",
"ProbeElectric": "", "ProbeElectric": "",
"ResourceQueue": "", "ResourceQueue": "",
"SpawnpointPlayer": "",
"UICommand": "" "UICommand": ""
} }