net = require("net") world = require("world") ui = require("ui") log = require("log") ClientNetworkedComponent = require("ecs.client_networked") GraphicsComponent = require("ecs.graphics") PlayerGraphicComponent = require("ecs.player_graphic") CharacterControllerComponent = require("ecs.char_controller") PredictedComponent = require("ecs.predicted") ScriptComponent = require("ecs.script") player_movement = require("shared.player_movement") game_menu = require("menu.game") ecs = require("ecs") sprites =require("sprites") net.register_message("CreatePawn",{ peerid: "string" }) x = {} net.register_message("Notify",{ required: { message: "string" } }) create_entity = (id, chunk) -> log.info("Creating entity of type" .. tostring(chunk.data.type), {"ecs","net","client"}) ent = nil switch chunk.data.type when "level" --ent = ecs.Entity(id) log.info("TODO: What do we refresh with level data?",{"ecs","net","client"}) --nents = #world.level.entities --net_comp = ClientNetworkedComponent("net",chunk.data) --ent\add(net_comp,"net") require(chunk.data.level_name).create(unpack(chunk.data.level_data)) --assert(#world.level.entities == nents, "Entities created in level loading") when "player" ent = ecs.Entity(id) log.info("Creating player",{"ecs","net","client","player"}) net_comp = ClientNetworkedComponent("net",chunk.data) ent\add(net_comp,"net") graphic = GraphicsComponent("graphic",{graphic: sprites.player}) ent\add(graphic,"graphic") predicted = PredictedComponent("pred",{acc: {0,0,0}, vel: {0,0,0}, pos:{0,0,0}}, "net", player_movement) ent\add(predicted,"pred") -- If this is "our" pawn, move our view with it if chunk.data.peerid == world.network.peer.id controller = CharacterControllerComponent("controller",player_movement,"net") ent\add(controller,"controller") move_view = ScriptComponent("move_view",{ script: () -> loc = predicted.properties.pos world.world_x = loc[1] world.world_y = loc[2] --graphic\moveto(vec3(loc[1],loc[2],loc[3])) }) ent\add(move_view,"move_view") move_graphic = ScriptComponent("move_graphic", { script: () -> loc = predicted.properties.pos graphic\moveto(vec3(loc[1],loc[2],loc[3])) }) ent\add(move_graphic, "move_graphic") else error("Tring to create unknown entity:" .. tostring(id) .. ":" .. tostring(data)) --assert(ent.components.net, "Failed to find net component") return ent x.initialize = () -> assert(world, "World must be available") assert(world.network, "Network must be initialized") localpawns = {} net = nil world.network\listen("CreatePawn", nil, (_, data) -> log.info("Creating pawn:" .. tostring(data), {"net","ecs","client"}) unpacked = am.parse_json(data) ent_id = unpacked.id create_entity(ent_id, unpacked) --ent = ecs.Entity(ent_id) --net = ClientNetworkedComponent("net",unpacked.data) --ent\add(net,"net") --graphic = GraphicsComponent("graphic",{ --graphic: sprites.player --}) --ent\add(graphic,"graphic") --pred = PredictedComponent("pred",{acc:{0,0,0}, vel: {0,0,0}, pos: {0,0,0}}, "net", player_movement) --ent\add(pred, "pred") ) world.network\listen("update","client update",(_, data) -> log.info("Updating:" .. tostring(data.id), {"net","ecs","client"}) --log.info("Entities were:" .. tostring(world.level.entities),{"net","client","ecs"}) log.debug("World entities are:" .. tostring(world.level.entities), {"ecs","client","net"}) if not world.level.entities[data.id] log.error("Client instructed to update id " .. data.id .. " but no entity exists! Entities were:" .. tostring(world.level.entities),{"net","client","ecs"}) ent = world.level.entities[data.id] net_component = ent\get(data.name) if not net_component error("Client instructed to update id " .. data.id .. " with network component named " .. tostring(data.name) .. " but no such component exists, entity was:" .. tostring(ent)) net_component.properties = data if net_component == net print("Updating pawn net component") log.info("Successfully updated entity" .. tostring(data.id), {"ecs","client","net"}) ) entities_responded = false world.network\listen("RespondEntities","Respond entities",(_, data) -> -- this is a full refresh, we can wipe entities and build them from scratch. for _, ent in pairs(world.level.entities) ent\destroy! log.info("Wiping and re-creating entities:" .. tostring(data), {"ecs","net","client"}) assert(type(data) == "table") for id, properties in pairs(data) assert(type(id) == "number") assert(type(properties) == "string") create_entity(id, am.parse_json(properties)) log.info("Successfully created entity" .. tostring(id), {"ecs","net","client"}) assert(#world.level.entities == #data, "Failed to create entities correctly") ) world.network\send("RequestEntities", {}) world.network\listen("RespondRole", "Respond role", (_, data) -> -- By this time we're in the game, destory any entities laying around. for _, ent in pairs(world.level.entities) ent\destroy! log.info("Got role from server:" .. tostring(data), {"net","client"}) game_menu.create_graphic(data) am.save_state("gameplay", data) -- Kinda hacky, but if we have a role, just disable net pumping -- to prevent errors on net.create() error("Preventing furhter network pumping!") net.pump = () -> log.info("Tried to pump net!",{"net","client"}) ) --world.network\send("RequestRole",{}) log.info("Client fully initialized",{"net","client","graphic"}) true x