summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorstujones11 <stujones111@gmail.com>2016-02-14 14:36:41 +0000
committerstujones11 <stujones111@gmail.com>2016-02-14 14:36:41 +0000
commit6be65a5dace16967728677f6c816a18d59ec2e7d (patch)
tree8c6a4f37d6ce1b3e01976c50862c82c6d6aa65b5
parentf746e814abddcc6434317bbc21aa452d3e30bef1 (diff)
Code refactor and api improvements
-rw-r--r--railcart/init.lua114
-rw-r--r--railcart/railcart.lua144
-rw-r--r--railtrack/railtrack.lua15
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"})