diff options
Diffstat (limited to 'src/ecs')
| -rw-r--r-- | src/ecs/char_controller.moon | 70 | ||||
| -rw-r--r-- | src/ecs/client_networked.moon | 19 | ||||
| -rw-r--r-- | src/ecs/component.moon | 16 | ||||
| -rw-r--r-- | src/ecs/graphics.moon | 67 | ||||
| -rw-r--r-- | src/ecs/networked.moon | 71 | ||||
| -rw-r--r-- | src/ecs/player_graphic.moon | 66 | ||||
| -rw-r--r-- | src/ecs/predicted.moon | 25 | ||||
| -rw-r--r-- | src/ecs/script.moon | 16 |
8 files changed, 350 insertions, 0 deletions
diff --git a/src/ecs/char_controller.moon b/src/ecs/char_controller.moon new file mode 100644 index 0000000..e5e3db7 --- /dev/null +++ b/src/ecs/char_controller.moon @@ -0,0 +1,70 @@ +ScriptComponent = require("ecs.script") +win = require("window") +log = require("log") +world = require("world") + +class CharacterControllerComponent extends ScriptComponent + new: (name, properties, netc_name) => + log.info("Creating new character controller", {"ecs"}) + properties.script = () -> + --log.info("Character controller running", {"ecs"}) + any_change = false + assert(@net.__class.__name == "ClientNetworkedComponent", "Wrong net component, was a " .. @net.__class.__name) + assert(@pred,"No predicted component") + assert(world.network, "Network must be created before CharacterControllerComponent starts running") + if win\key_pressed("w") + log.info("Key down w",{"net","ecs","client","player"}) + @net.properties.acc[2] = 1 + any_change = true + elseif win\key_released("w") + log.info("Key up w",{"net","ecs","client","player"}) + any_change = true + @net.properties.acc[2] = 0 + if win\key_pressed("s") + log.info("Key down s",{"net","ecs","client","player"}) + any_change = true + @net.properties.acc[2] = -1 + elseif win\key_released("s") + log.info("Key up s",{"net","ecs","client","player"}) + any_change = true + @net.properties.acc[2] = 0 + if win\key_pressed("a") + log.info("Key down a", {"net","ecs","client","player"}) + any_change = true + @net.properties.acc[1] = -1 + elseif win\key_released("a") + log.info("Key up a", {"net","ecs","client","player"}) + any_change = true + @net.properties.acc[1] = 0 + if win\key_pressed("d") + log.info("Key down d", {"net","ecs","client","player"}) + any_change = true + @net.properties.acc[1] = 1 + elseif win\key_released("d") + log.info("Key up d", {"net","ecs","client","player"}) + any_change = true + @net.properties.acc[1] = 0 + + -- We can't actually update the network on the client, + -- but we still want to do predicted movement + if any_change + @net.properties.last_update = am.eval_js("Date.now();") + @net.properties.pos = @pred.properties.pos + --@net.properties.vel = @pred.properties.vel + world.network\send("SuggestPlayerUpdate",{ + acc: @net.properties.acc + vel: @net.properties.vel + pos: @pred.properties.pos + }) + return false + --print("Running character controller",win\key_pressed("w")) + @netc_name = netc_name + super(name, properties) + join: (entity) => + log.debug("Components was:" .. tostring(entity.components), {"ecs"}) + @net = entity\get(@netc_name) + @pred = entity\get("pred") + assert(@net, "Must have added network component: " .. @netc_name .. ".") + super(entity) + +CharacterControllerComponent diff --git a/src/ecs/client_networked.moon b/src/ecs/client_networked.moon new file mode 100644 index 0000000..fc70dc2 --- /dev/null +++ b/src/ecs/client_networked.moon @@ -0,0 +1,19 @@ +world = require("world") +log = require("log") +NetworkedComponent = require("ecs.networked") +Component = require("ecs.component") + +class ClientNetworkedComponent extends Component + new: (name, properties) => + log.info("Creating client networked info", {"client"}) + super(name, properties) + listen_events: () -> + assert(wold.network, "world.network needs to be set before hooking events") + world.network\listen("create","client_network_component",(hubid, data) -> + error("ClientNetworkComponent create received:".. tostring(data)) + ) + world.network\listen("update","client_network_component",(hubid, data) -> + error("ClientNetworkComponent update received:".. tostring(data)) + ) + +ClientNetworkedComponent diff --git a/src/ecs/component.moon b/src/ecs/component.moon new file mode 100644 index 0000000..6ce16bd --- /dev/null +++ b/src/ecs/component.moon @@ -0,0 +1,16 @@ +-- Base component class of the ECS +class Component + depends: {} + new: (name, properties) => + @name = name + @properties = properties or {} + join: (e, cid) => + @ + post_join: (e, cid) => + @ + leave: (e) => + @ + __tostring: () => + return string.format("%s<%s> {\n%s\n}",@@__name,@name or "no name given",tostring(@properties)) + +Component diff --git a/src/ecs/graphics.moon b/src/ecs/graphics.moon new file mode 100644 index 0000000..66e5e80 --- /dev/null +++ b/src/ecs/graphics.moon @@ -0,0 +1,67 @@ +Component = require("ecs.component") +sprites = require("sprites") +gworld = require("shaders.world") +world = require("world") +log = require("log") + +sd = sprites.floor +w1 = sprites.wall1_diffuse + +panel = { + vec3(0, 1, 0.4), + vec3(1, 1, 0.4), + vec3(1, 0, 0.4), + vec3(1, 0, 0.4), + vec3(0, 0, 0.4), + vec3(0, 1, 0.4) +} + +class GraphicsComponent extends Component + new: (name, properties) => + --assert(properties and properties.node , "Failed to find node for graphics component") + --assert(@@node, ".node not set for GraphicsComponent") + assert(world.geom_view,".geom_view not set for world") + assert(world.uv_view, ".uv_view not set for world") + --@node = properties.node + super(name, properties) + static: () => + @@static + join: () => + --log.info("Joining with graphics component" .. tostring(@node), {"graphics"}) + --@@node\append(@node) + gworld.add(@) + leave: () => + gworld.remove(@) + --@@node\remove(@node) + node: () => + error("Tried to access graphic component's .node") + --@properties.node + tris: () => + 2 + populate_buf: (geom_view, uv_view, offset) => + assert(@properties.graphic, "Graphics component needs a graphic") + assert(offset == 1, "Offset was " .. tostring(offset)) + log.info("Populating:" .. tostring(offset) .. ":" .. tostring(@properties.graphic), {"graphic","ecs"}) + log.info(debug.traceback(), {"graphic","ecs"}) + log.info("Populating with:" .. tostring(panel),{"graphic","ecs"}) + geom_view\set(panel, offset, @tris! * 3) + @geom_view = geom_view + @uv_view = uv_view + @offset = offset + uv = @properties.graphic + uv_view[1] = vec4(uv.s1,uv.t1,1,1) + uv_view[2] = vec4(uv.s1,uv.t2,1,1) + uv_view[3] = vec4(uv.s2,uv.t2,1,1) + uv_view[4] = vec4(uv.s2,uv.t2,1,1) + uv_view[5] = vec4(uv.s2,uv.t1,1,1) + uv_view[6] = vec4(uv.s1,uv.t1,1,1) + --error("Graphics components must override .populate_buf()") + move: (move_off) => + for i, set in ipairs(panel) + @geom_view[@offset + i - 1] = @geom_view[@offset + i - 1] + move_off + moveto: (loc) => + assert(@offset, "Moveto called before populate_buf") + for i, set in ipairs(panel) + @geom_view[@offset + i - 1] = loc + set + +GraphicsComponent diff --git a/src/ecs/networked.moon b/src/ecs/networked.moon new file mode 100644 index 0000000..6673a7d --- /dev/null +++ b/src/ecs/networked.moon @@ -0,0 +1,71 @@ +Component = require("ecs.component") +world = require("world") +log = require("log") + +network_log = {} + +class NetworkedComponent extends Component + @q: {} + + new: (name, properties) => + assert(properties.id == nil, "networked component's id needs to be nil") + assert(properties.name == nil, "network component's name needs to be nil") + properties.id = world.level_sync.entid + world.level_sync.entid += 1 + nwc = @ + update = (key, value) => + if not world.hub + error("Tried to update network on the client") + return + if not properties[key] + error("Trying to set key not defined in properties:" .. key) + properties[key] = value + properties.last_update = am.eval_js("Date.now();") + nwc.__class.q[nwc] = true + -- Broadcast update to other peers through client + --world.hub\broadcast("update", properties) + --actually, we only want to update each network component *at most* once per frame. + + proxy = {} + setmetatable(proxy, { + __index: properties, + __newindex: update + }) + super(name, proxy) + @net_properties = properties + join: (e, cid) => + @@node\action("Send Updates", ()-> + @@update_dirty! + ) + @net_properties.id = e.id + @net_properties.name = cid + log.info("Added networked componenet name " .. @name .. " to entity id " .. e.id, {"net","server","ecs"}) + -- Send initial create message through client + --if world.hub -- Actually, entity creation is hard, just sync each entity individually. + --world.hub\broadcast("create", properties) + super(e) + + pack: () => + assert(@entity, "Tried to pack on a NetworkedComponent without an Entity") + log.info("Packing data from proxy:" .. tostring(@proxy), {"net","ecs"}) + return am.to_json({ + id: @entity.id + data: @net_properties + time: am.current_time! + }) + + unpack: () -> + assert(@entity, "Tried to unpack on a NEtworkedComponent without an Entity") + + @update_dirty: () => + for component, _ in pairs(@q) + world.hub\broadcast("update", component.net_properties) + @q = {} + + -- Each different kind of entity needs to have it's own create and listen network + -- hooks, it's way too complicated and heavy to push every entity with every componenet + -- over the network. + +assert(NetworkedComponent.q, "No queue found!") + +NetworkedComponent diff --git a/src/ecs/player_graphic.moon b/src/ecs/player_graphic.moon new file mode 100644 index 0000000..5ad9cab --- /dev/null +++ b/src/ecs/player_graphic.moon @@ -0,0 +1,66 @@ +GraphicsComponent = require("ecs.graphics") +sprites = require("sprites") + +geom_fac = { + {-1, -1, 1}, + {-1, 1, 1}, + {-1, -1, 1}, + {1, 1, 1}, + {1, -1, 1}, + {-1, -1, 1} +} + +class PlayerGraphicComponent extends GraphicsComponent + @player_size = 0.25 + @static = false + --new: (name, properties) => + --print("New PlayerGraphicsComponenet, super is", @@__init) + --print("But graphicsComponent's __init is:", GraphicsComponent.__init) + --GraphicsComponent.__init(@, name, properties) + --super(name, properties) + tris: () -> + 2 + populate_buf: (geom_view, uv_view, offset) => + @playerbuf = geom_view + h = @@player_size / 2 + for i, set in ipairs(geom_fac) + geom_view[i] = vec3(h*set[1], h*set[2], h*set[3]) + uv = sprites.player_normal + uv_view[1] = vec2(uv.s1,uv.t1) + uv_view[2] = vec2(uv.s1,uv.t2) + uv_view[3] = vec2(uv.s2,uv.t2) + uv_view[4] = vec2(uv.s2,uv.t2) + uv_view[5] = vec2(uv.s2,uv.t1) + uv_view[6] = vec2(uv.s1,uv.t1) + join: (entity) => + super(entity) + aspect = win.width / win.height + -- inject nodes into the scene graph + program = @.node("use_program") + pred_component = entity\get("pred") + graphic = entity\get("graphic") + @node\remove(program) + @node\append(am.blend("alpha")\append(am.depth_test("less", true)\append(program))) + @node\action(() => + pred_loc = pred_component.properties.pos + graphic\move(pred_loc.x, pred_loc.y) + ) + --@.node("bind").highlight = color.am_color.black + move: (x,y) => + assert(x, "x required") + assert(y, "y required") + world.level.move_lamp(@lamp, x + @lamp_offset.x, y + @lamp_offset.y) + h = @@player_size / 2 + z = 0.5 + @playerbuf[1] = vec3(x-h,y-h,z) + @playerbuf[2] = vec3(x-h,y+h,z) + @playerbuf[3] = vec3(x+h,y+h,z) + @playerbuf[4] = vec3(x+h,y+h,z) + @playerbuf[5] = vec3(x+h,y-h,z) + @playerbuf[6] = vec3(x-h,y-h,z) + --print("Move called", @playerbuf[1]) + face: (direction) => + --print("direction",direction) + @.node("bind").rot = (direction ) % (math.pi * 2) + +PlayerGraphicComponent diff --git a/src/ecs/predicted.moon b/src/ecs/predicted.moon new file mode 100644 index 0000000..b8bdd28 --- /dev/null +++ b/src/ecs/predicted.moon @@ -0,0 +1,25 @@ +Component = require("ecs.component") + +class PredictedComponent extends Component + new: (name, properties, netc_name, calculate) => + super(name, properties) + @netc_name = netc_name + assert(calculate and type(calculate) == "table", "Calculate must be a table, was " .. type(calculate)) + @calculate = calculate + join: (entity) => + @net = @entity\get(@netc_name) + @node = am.group! + @node\action(() -> + @forward! + ) + @@node\append(@node) + super(entity) + leave: (entity) => + @@node\remove(@node) + forward: () => + for property, calculation in pairs(@calculate) + @properties[property] = calculation(@) + + + +PredictedComponent diff --git a/src/ecs/script.moon b/src/ecs/script.moon new file mode 100644 index 0000000..05869c0 --- /dev/null +++ b/src/ecs/script.moon @@ -0,0 +1,16 @@ +Component = require("ecs.component") + +class ScriptComponent extends Component + new: (name, properties) => + print("Creating new script component") + assert(properties and properties.script, "Failed to find script name for script component") + super(name, properties) + join: (e) => + print("Script component is joining an entity") + @node = am.group! + @@node\append(@node) + @node\action(@properties.script) + + leave: (e) => + print("Script component is leaving an entity") + @@node\remove(@node) |
