diff options
author | stujones11 <stujones111@gmail.com> | 2016-02-14 14:36:41 +0000 |
---|---|---|
committer | stujones11 <stujones111@gmail.com> | 2016-02-14 14:36:41 +0000 |
commit | 6be65a5dace16967728677f6c816a18d59ec2e7d (patch) | |
tree | 8c6a4f37d6ce1b3e01976c50862c82c6d6aa65b5 | |
parent | f746e814abddcc6434317bbc21aa452d3e30bef1 (diff) |
Code refactor and api improvements
-rw-r--r-- | railcart/init.lua | 114 | ||||
-rw-r--r-- | railcart/railcart.lua | 144 | ||||
-rw-r--r-- | railtrack/railtrack.lua | 15 |
3 files changed, 156 insertions, 117 deletions
diff --git a/railcart/init.lua b/railcart/init.lua index c72db24..821971c 100644 --- a/railcart/init.lua +++ b/railcart/init.lua @@ -3,6 +3,29 @@ local modpath = minetest.get_modpath(minetest.get_current_modname()) dofile(modpath.."/railcart.lua") local worldpath = minetest.get_worldpath() + +local function create_detached_inventory(id) + local inv = minetest.create_detached_inventory("railcart_"..tostring(id), { + on_put = function(inv, listname, index, stack, player) + railcart:save() + end, + on_take = function(inv, listname, index, stack, player) + railcart:save() + end, + allow_put = function(inv, listname, index, stack, player) + return 1 + end, + allow_take = function(inv, listname, index, stack, player) + return stack:get_count() + end, + allow_move = function(inv, from_list, from_index, to_list, to_index, count, player) + return count + end, + }) + inv:set_size("main", 32) + return inv +end + local input = io.open(worldpath.."/railcart.txt", "r") if input then local data = input:read('*all') @@ -10,12 +33,13 @@ if input then local carts = minetest.deserialize(data) or {} for id, ref in pairs(carts) do local cart = railcart.cart:new(ref) - local inv = railcart:create_detached_inventory(cart.id) - ref.inv = ref.inv or {} - for i, stack in pairs(ref.inv) do - inv:set_stack("main", i, stack) + if ref.inv then + local inv = create_detached_inventory(cart.id) + for i, stack in pairs(ref.inv) do + inv:set_stack("main", i, stack) + end + cart.inv = inv end - cart.inv = inv railcart.allcarts[id] = cart end end @@ -28,39 +52,7 @@ local function is_valid_player(object) end end -minetest.register_globalstep(function(dtime) - for _, cart in pairs(railcart.allcarts) do - cart:on_step(dtime) - end - railcart.timer = railcart.timer + dtime - if railcart.timer > RAILCART_OBJECT_SAVE_TIME then - railcart:save() - railcart.timer = 0 - end -end) - -minetest.register_on_shutdown(function() - railcart:save() -end) - -minetest.register_privilege("carts", "Player can pick-up and place carts.") - -minetest.register_entity("railcart:cart_entity", { - physical = false, - collisionbox = {-0.5,-0.5,-0.5, 0.5,0.5,0.5}, - visual = "mesh", - mesh = "railcart.x", - visual_size = {x=1, y=1}, - textures = {"cart.png"}, - cart = nil, - driver = nil, - timer = 0, - on_activate = function(self, staticdata, dtime_s) - self.object:set_armor_groups({immortal=1}) - if staticdata == "expired" then - self.object:remove() - end - end, +railcart:register_entity("railcart:cart_entity", { on_punch = function(self, puncher, _, _, direction) if not is_valid_player(puncher) then return @@ -105,7 +97,7 @@ minetest.register_entity("railcart:cart_entity", { self.timer = 0 self.cart.target = nil self.cart.prev = pos - self.cart.vel = vector.multiply(dir, RAILCART_SPEED_PUSH) + self.cart.vel = vector.multiply(dir, 5) self.cart.accel = railtrack:get_acceleration(pos) self.object:setvelocity(self.cart.vel) end @@ -138,27 +130,6 @@ minetest.register_entity("railcart:cart_entity", { clicker:set_attach(self.object, "", {x=0,y=5,z=0}, {x=0,y=0,z=0}) end end, - on_step = function(self, dtime) - local cart = self.cart - local object = self.object - if not cart or not object then - return - end - self.timer = self.timer - dtime - if self.timer > 0 then - return - end - self.timer = railcart:update(cart, RAILCART_ENTITY_UPDATE_TIME, object) - end, - get_staticdata = function(self) - if self.cart then - if self.cart:is_loaded() == false then - self.cart.timer = 0 - self.object:remove() - end - end - return "expired" - end, }) minetest.register_craftitem("railcart:cart", { @@ -184,13 +155,16 @@ minetest.register_craftitem("railcart:cart", { if #carts > 0 then return end - local cart = railcart.cart:new() - cart.id = railcart:get_new_id() - cart.inv = railcart:create_detached_inventory(cart.id) - cart.pos = vector.new(pos) - cart.prev = vector.new(pos) - cart.accel = railtrack:get_acceleration(pos) - cart.dir = railcart:get_rail_direction(pos) + local id = railcart:get_new_id() + local ref = { + id = id, + inv = create_detached_inventory(id), + pos = vector.new(pos), + prev = vector.new(pos), + accel = railtrack:get_acceleration(pos), + dir = railcart:get_rail_direction(pos), + } + local cart = railcart.cart:new(ref) table.insert(railcart.allcarts, cart) railcart:save() if not minetest.setting_getbool("creative_mode") then @@ -200,6 +174,8 @@ minetest.register_craftitem("railcart:cart", { end, }) +minetest.register_privilege("carts", "Player can pick-up and place carts.") + minetest.register_craft({ output = "railcart:cart", recipe = { @@ -209,3 +185,7 @@ minetest.register_craft({ }, }) +minetest.register_on_shutdown(function() + railcart:save() +end) + diff --git a/railcart/railcart.lua b/railcart/railcart.lua index 6e5fbd4..dcaa80e 100644 --- a/railcart/railcart.lua +++ b/railcart/railcart.lua @@ -1,15 +1,25 @@ -RAILCART_ENTITY_UPDATE_TIME = 1 -RAILCART_OBJECT_UPDATE_TIME = 5 -RAILCART_OBJECT_SAVE_TIME = 10 -RAILCART_RELOAD_DISTANCE = 32 -RAILCART_SNAP_DISTANCE = 0.5 -RAILCART_SPEED_PUSH = 5 -RAILCART_SPEED_MIN = 0.1 -RAILCART_SPEED_MAX = 20 +local ENTITY_UPDATE_TIME = 1 +local OBJECT_UPDATE_TIME = 5 +local OBJECT_SAVE_TIME = 10 +local RELOAD_DISTANCE = 32 +local SNAP_DISTANCE = 0.5 +local SPEED_MIN = 0.1 +local SPEED_MAX = 15 railcart = { timer = 0, allcarts = {}, + default_entity = { + physical = false, + collisionbox = {-0.5,-0.5,-0.5, 0.5,0.5,0.5}, + visual = "mesh", + mesh = "railcart.x", + visual_size = {x=1, y=1}, + textures = {"cart.png"}, + cart = nil, + driver = nil, + timer = 0, + }, } railcart.cart = { @@ -23,6 +33,7 @@ railcart.cart = { vel = {x=0, y=0, z=0}, acc = {x=0, y=0, z=0}, timer = 0, + name = "railcart:cart_entity", } function railcart.cart:new(obj) @@ -37,7 +48,7 @@ function railcart.cart:is_loaded() local pos = player:getpos() if pos then local dist = railtrack:get_distance(pos, self.pos) - if dist <= RAILCART_RELOAD_DISTANCE then + if dist <= RELOAD_DISTANCE then return true end end @@ -50,13 +61,13 @@ function railcart.cart:on_step(dtime) if self.timer > 0 then return end - self.timer = RAILCART_OBJECT_UPDATE_TIME + self.timer = OBJECT_UPDATE_TIME local entity = railcart:get_cart_entity(self.id) if entity.object then return end if self:is_loaded() then - local object = minetest.add_entity(self.pos, "railcart:cart_entity") + local object = minetest.add_entity(self.pos, self.name) if object then entity = object:get_luaentity() or {} entity.cart = self @@ -68,6 +79,56 @@ function railcart.cart:on_step(dtime) end end +function railcart:register_entity(name, def) + local ref = {} + for k, v in pairs(railcart.default_entity) do + ref[k] = def[k] or railtrack:copy(v) + end + ref.on_activate = function(self, staticdata, dtime_s) + if type(def.on_activate) == "function" then + def.on_activate(self, staticdata, dtime_s) + end + self.object:set_armor_groups({immortal=1}) + if staticdata == "expired" then + self.object:remove() + end + end + ref.on_step = function(self, dtime) + if type(def.on_step) == "function" then + def.on_step(self, dtime) + end + local cart = self.cart + local object = self.object + if not cart or not object then + return + end + self.timer = self.timer - dtime + if self.timer > 0 then + return + end + self.timer = railcart:update(cart, ENTITY_UPDATE_TIME, object) + if type(def.on_update) == "function" then + def.on_update(self) + end + end + ref.get_staticdata = function(self) + if type(def.get_staticdata) == "function" then + def.get_staticdata(self) + end + if self.cart then + if self.cart:is_loaded() == false then + self.cart.timer = 0 + self.object:remove() + end + end + return "expired" + end + for k, v in pairs(def) do + ref[k] = ref[k] or v + end + minetest.register_entity(name, ref) +end + function railcart:save() local carts = {} for id, cart in pairs(railcart.allcarts) do @@ -92,28 +153,6 @@ function railcart:save() end end -function railcart:create_detached_inventory(id) - local inv = minetest.create_detached_inventory("railcart_"..tostring(id), { - on_put = function(inv, listname, index, stack, player) - railcart:save() - end, - on_take = function(inv, listname, index, stack, player) - railcart:save() - end, - allow_put = function(inv, listname, index, stack, player) - return 1 - end, - allow_take = function(inv, listname, index, stack, player) - return stack:get_count() - end, - allow_move = function(inv, from_list, from_index, to_list, to_index, count, player) - return count - end, - }) - inv:set_size("main", 32) - return inv -end - function railcart:remove_cart(id) for i, cart in pairs(railcart.allcarts) do if cart.id == id then @@ -153,6 +192,14 @@ function railcart:get_new_id() return id + 1 end +function railcart:get_cart_ref(id) + for _, cart in pairs(railcart.allcarts) do + if cart.id == id then + return cart + end + end +end + function railcart:get_cart_entity(id) local cart_ref = {} for _, ref in pairs(minetest.luaentities) do @@ -222,10 +269,10 @@ end function railcart:velocity_to_speed(vel) local speed = math.max(math.abs(vel.x), math.abs(vel.z)) - if speed < RAILCART_SPEED_MIN then + if speed < SPEED_MIN then speed = 0 - elseif speed > RAILCART_SPEED_MAX then - speed = RAILCART_SPEED_MAX + elseif speed > SPEED_MAX then + speed = SPEED_MAX end return speed end @@ -234,7 +281,7 @@ function railcart:get_target(pos, vel) local meta = minetest.get_meta(vector.round(pos)) local dir = self:velocity_to_dir(vel) local targets = {} - local rots = RAILTRACK_ROTATIONS + local rots = railtrack.rotations local contype = meta:get_string("contype") or "" local s_junc = meta:get_string("junctions") or "" local s_cons = meta:get_string("connections") or "" @@ -290,7 +337,7 @@ function railcart:update(cart, time, object) else speed = 0 end - if speed > RAILCART_SPEED_MIN then + if speed > SPEED_MIN then local blocked = false local cis = railcart:get_cart_in_sight(cart.pos, cart.target) if cis then @@ -316,16 +363,16 @@ function railcart:update(cart, time, object) local d1 = railtrack:get_distance(cart.prev, cart.target) local d2 = railtrack:get_distance(cart.prev, cart.pos) local dist = d1 - d2 - if dist > RAILCART_SNAP_DISTANCE then - local accel = RAILTRACK_ACCEL_FLAT + if dist > SNAP_DISTANCE then + local accel = railtrack.accel_flat if cart.dir.y == -1 then - accel = RAILTRACK_ACCEL_DOWN + accel = railtrack.accel_down elseif cart.dir.y == 1 then - accel = RAILTRACK_ACCEL_UP + accel = railtrack.accel_up end accel = cart.accel or accel if object then - dist = math.max(dist - RAILCART_SNAP_DISTANCE, 0) + dist = math.max(dist - SNAP_DISTANCE, 0) end local dt = railcart:get_delta_time(speed, accel, dist) if dt < time then @@ -384,3 +431,14 @@ function railcart:update(cart, time, object) return time end +minetest.register_globalstep(function(dtime) + for _, cart in pairs(railcart.allcarts) do + cart:on_step(dtime) + end + railcart.timer = railcart.timer + dtime + if railcart.timer > OBJECT_SAVE_TIME then + railcart:save() + railcart.timer = 0 + end +end) + diff --git a/railtrack/railtrack.lua b/railtrack/railtrack.lua index 75a62a6..664300f 100644 --- a/railtrack/railtrack.lua +++ b/railtrack/railtrack.lua @@ -1,10 +1,11 @@ -RAILTRACK_MAX_SECTION_LEN = 20 -RAILTRACK_ROTATIONS = "FLR" -RAILTRACK_ACCEL_FLAT = -0.5 -RAILTRACK_ACCEL_UP = -2 -RAILTRACK_ACCEL_DOWN = 2 +local MAX_SECTION_LEN = 20 -railtrack = {} +railtrack = { + rotations = "FLR", + accel_flat = -0.5, + accel_up = -2, + accel_down = 2, +} railtrack.default_rail = { description = "Rail", @@ -90,7 +91,7 @@ function railtrack:limit_section_len(player, pos, meta) local junc = minetest.deserialize(s_junc) if #junc == 2 then local dist = railtrack:get_distance(junc[1], junc[2]) - if dist > RAILTRACK_MAX_SECTION_LEN then + if dist > MAX_SECTION_LEN then local node = minetest.get_node(pos) or {} if node.name then minetest.swap_node(pos, {name=node.name.."_union"}) |