This repository has been archived on 2020-09-30. You can view files and clone it, but cannot push or open issues or pull requests.
odyssey-old/Actors/Systems/Electricity/PowerNetwork.gd

107 lines
2.7 KiB
GDScript

extends Node
class_name PowerNetwork
const DEBUG = false
var nodes = []
var sockets = []
var total_source = 0
var total_usage = 0
var unpowered = 0
var debugColor = Color.cyan
func _ready():
name = "PowerNetwork"
debugColor = Color.from_hsv(randf(), 0.8, 0.8)
remotesync func add_node(node) -> void:
nodes.append(node)
if "connections" in node:
sockets.append(node)
remotesync func remove_node(node) -> void:
var node_idx = nodes.find(node)
if node_idx >= 0:
nodes.remove(node_idx)
var sock_idx = sockets.find(node)
if sock_idx >= 0:
sockets.remove(sock_idx)
# Do other splitting here
node.network = null
remotesync func join(network) -> void:
for node in network.nodes:
nodes.append(node)
node.network = self
for socket in network.sockets:
sockets.append(socket)
socket.network = self
# Do other merging here
network.queue_free()
func _physics_process(_delta: float) -> void:
if not is_network_master():
return
# Recalculate power availability and usage
total_source = 0
total_usage = 0
var sources = []
var sinks = []
# Calculate totals
for socket in sockets:
for connection in socket.connections:
var manager = connection as PowerManager
match socket.flow:
ElectricSocket.Flow.SINK:
total_usage += manager.power_usage
sinks.append(manager)
ElectricSocket.Flow.SOURCE:
total_source += manager.power_source
sources.append(manager)
ElectricSocket.Flow.BIDIRECTIONAL:
total_usage += manager.power_usage
total_source += manager.power_source
sinks.append(manager)
sources.append(manager)
# Update manager stats
var available_supply = total_source
unpowered = 0
for sink in sinks:
# Check if item can be powered this cycle
if sink.power_usage > 0:
if available_supply > sink.power_usage:
available_supply -= sink.power_usage
if not sink.powered:
sink.rpc("set_powered", true)
else:
if sink.powered:
sink.rpc("set_powered", false)
unpowered += 1
# Update available power to sinks
for sink in sinks:
sink.available = available_supply
# Check how much we actually need to drain from sources
var remaining_drain = total_source - available_supply
if remaining_drain > 0:
for source in sources:
var source_load = source.power_source / total_source * remaining_drain
source.power_load = source_load
func serialize():
var node_paths = []
var socket_paths = []
for node in nodes:
node_paths.append(get_path_to(node))
for socket in sockets:
socket_paths.append(get_path_to(socket))
return { "nodes": node_paths, "sockets": socket_paths }
func deserialize(data):
for node_path in data["nodes"]:
nodes.append(get_node(node_path))
for socket_path in data["sockets"]:
sockets.append(get_node(socket_path))