forked from VoxeLibre/VoxeLibre
Give furnace minecart minimum velocity when lit, add train separation code, update logging code, add sequence number to entity staticdata to allow respawn/despawn when carts move when the entity is unloaded
This commit is contained in:
parent
c918b34871
commit
de45866ac9
|
@ -59,6 +59,15 @@ function mcl_util.mcl_log(message, module, bypass_default_logger)
|
|||
minetest.log(selected_module .. " " .. message)
|
||||
end
|
||||
end
|
||||
function mcl_util.make_mcl_logger(label, option)
|
||||
-- Return dummy function if debug option isn't set
|
||||
if not minetest.settings:get_bool(option,false) then return function() end, false end
|
||||
|
||||
local label_text = "["..tostring(label).."]"
|
||||
return function(message)
|
||||
mcl_util.mcl_log(message, label_text, true)
|
||||
end, true
|
||||
end
|
||||
|
||||
local player_timers = {}
|
||||
|
||||
|
@ -1176,6 +1185,9 @@ end
|
|||
function mcl_util.get_active_object_id_from_uuid(uuid)
|
||||
return uuid_to_aoid_cache[uuid] or scan_active_objects() or uuid_to_aoid_cache[uuid]
|
||||
end
|
||||
function mcl_util.get_luaentity_from_uuid(uuid)
|
||||
return minetest.luaentities[ mcl_util.get_active_object_id_from_uuid(uuid) ]
|
||||
end
|
||||
function mcl_util.get_uuid(obj)
|
||||
local le = obj:get_luaentity()
|
||||
|
||||
|
|
|
@ -3,13 +3,7 @@ local modpath = minetest.get_modpath(modname)
|
|||
local mod = mcl_minecarts
|
||||
local S = minetest.get_translator(modname)
|
||||
|
||||
local LOGGING_ON = minetest.settings:get_bool("mcl_logging_minecarts", false)
|
||||
local DEBUG = false
|
||||
local function mcl_log(message)
|
||||
if LOGGING_ON then
|
||||
mcl_util.mcl_log(message, "[Minecarts]", true)
|
||||
end
|
||||
end
|
||||
local mcl_log = mcl_util.make_mcl_logger("mcl_logging_minecarts", "Minecarts")
|
||||
|
||||
-- Imports
|
||||
local table_merge = mcl_util.table_merge
|
||||
|
@ -53,6 +47,7 @@ local function make_staticdata( railtype, connected_at, dir )
|
|||
velocity = 0,
|
||||
dir = vector.new(dir),
|
||||
mass = 1,
|
||||
seq = 1,
|
||||
}
|
||||
end
|
||||
|
||||
|
@ -86,8 +81,15 @@ function DEFAULT_CART_DEF:on_activate(staticdata, dtime_s)
|
|||
if not data.uuid then
|
||||
data.uuid = mcl_util.get_uuid(self.object)
|
||||
end
|
||||
self._seq = data.seq or 1
|
||||
|
||||
local cd = get_cart_data(data.uuid)
|
||||
if not cd then update_cart_data(data) end
|
||||
if not cd then
|
||||
update_cart_data(data)
|
||||
else
|
||||
if not cd.seq then cd.seq = 1 end
|
||||
data = cd
|
||||
end
|
||||
|
||||
-- Initialize
|
||||
if type(data) == "table" then
|
||||
|
@ -121,7 +123,7 @@ function DEFAULT_CART_DEF:on_activate(staticdata, dtime_s)
|
|||
end
|
||||
function DEFAULT_CART_DEF:get_staticdata()
|
||||
save_cart_data(self._staticdata.uuid)
|
||||
return minetest.serialize({uuid = self._staticdata.uuid})
|
||||
return minetest.serialize({uuid = self._staticdata.uuid, seq=self._seq})
|
||||
end
|
||||
|
||||
function DEFAULT_CART_DEF:add_node_watch(pos)
|
||||
|
@ -147,6 +149,15 @@ function DEFAULT_CART_DEF:remove_node_watch(pos)
|
|||
end
|
||||
staticdata.node_watches = new_watches
|
||||
end
|
||||
function DEFAULT_CART_DEF:get_cart_position()
|
||||
local staticdata = self._staticdata
|
||||
|
||||
if staticdata.connected_at then
|
||||
return staticdata.connected_at + staticdata.dir * staticdata.distance
|
||||
else
|
||||
return self.object:get_pos()
|
||||
end
|
||||
end
|
||||
function DEFAULT_CART_DEF:on_step(dtime)
|
||||
local staticdata = self._staticdata
|
||||
if not staticdata then
|
||||
|
@ -154,6 +165,11 @@ function DEFAULT_CART_DEF:on_step(dtime)
|
|||
self._staticdata = staticdata
|
||||
end
|
||||
|
||||
if self._seq ~= staticdata.seq then
|
||||
print("TODO: remove cart #"..staticdata.uuid.." with sequence number mismatch")
|
||||
print("self.seq="..tostring(self._seq)..", staticdata.seq="..tostring(staticdata.seq))
|
||||
end
|
||||
|
||||
-- Regen
|
||||
local hp = self.object:get_hp()
|
||||
if hp < MINECART_MAX_HP then
|
||||
|
|
|
@ -73,6 +73,10 @@ mcl_minecarts.register_minecart({
|
|||
|
||||
-- Update furnace stuff
|
||||
if (staticdata.fueltime or 0) > 0 then
|
||||
if staticdata.velocity < 0.25 then
|
||||
staticdata.velocity = 0.25
|
||||
end
|
||||
|
||||
staticdata.fueltime = (staticdata.fueltime or dtime) - dtime
|
||||
if staticdata.fueltime <= 0 then
|
||||
self.object:set_properties({textures =
|
||||
|
|
|
@ -5,9 +5,10 @@ local mod = mcl_minecarts
|
|||
mcl_minecarts.modpath = modpath
|
||||
|
||||
-- Constants
|
||||
mcl_minecarts.speed_max = 10
|
||||
mcl_minecarts.check_float_time = 15
|
||||
mcl_minecarts.FRICTION = 0.4
|
||||
mod.speed_max = 10
|
||||
mod.check_float_time = 15
|
||||
mod.FRICTION = 0.4
|
||||
mod.MAX_TRAIN_LENGTH = 4
|
||||
|
||||
for _,filename in pairs({"storage","functions","rails","train","carts"}) do
|
||||
dofile(modpath.."/"..filename..".lua")
|
||||
|
|
|
@ -4,8 +4,9 @@ local mod = mcl_minecarts
|
|||
local S = minetest.get_translator(modname)
|
||||
|
||||
-- Constants
|
||||
local DEBUG = false
|
||||
local mcl_debug,DEBUG = mcl_util.make_mcl_logger("mcl_logging_minecart_debug", "Minecart Debug")
|
||||
local friction = mcl_minecarts.FRICTION
|
||||
local MAX_TRAIN_LENGTH = mod.MAX_TRAIN_LENGTH
|
||||
|
||||
-- Imports
|
||||
local train_length = mod.train_length
|
||||
|
@ -131,6 +132,10 @@ local function handle_cart_collision(cart1, prev_pos, next_dir)
|
|||
|
||||
local meta = minetest.get_meta(vector.add(pos,next_dir))
|
||||
if not cart_uuid then return end
|
||||
|
||||
-- Don't collide with the train car in front of you
|
||||
if cart1._staticdata.ahead == cart_uuid then return end
|
||||
|
||||
minetest.log("action","cart #"..cart1._staticdata.uuid.." collided with cart #"..cart_uuid.." at "..tostring(pos))
|
||||
|
||||
local cart2_aoid = mcl_util.get_active_object_id_from_uuid(cart_uuid)
|
||||
|
@ -146,8 +151,8 @@ local function handle_cart_collision(cart1, prev_pos, next_dir)
|
|||
local m1 = cart1_staticdata.mass
|
||||
local m2 = cart2_staticdata.mass
|
||||
|
||||
print("u1="..tostring(u1)..",u2="..tostring(u2))
|
||||
if u2 == 0 and u1 < 4 and train_length(cart1) < 3 then
|
||||
--print("u1="..tostring(u1)..",u2="..tostring(u2))
|
||||
if u2 == 0 and u1 < 4 and train_length(cart1) < MAX_TRAIN_LENGTH then
|
||||
link_cart_ahead(cart1, cart2)
|
||||
cart2_staticdata.dir = mcl_minecarts:get_rail_direction(cart2_staticdata.connected_at, cart1_staticdata.dir)
|
||||
cart2_staticdata.velocity = cart1_staticdata.velocity
|
||||
|
@ -275,7 +280,7 @@ local function do_movement_step(self, dtime)
|
|||
end
|
||||
|
||||
if DEBUG and ( v_0 > 0 or a ~= 0 ) then
|
||||
print( " cart "..tostring(staticdata.uuid)..
|
||||
mcl_debug(" cart "..tostring(staticdata.uuid)..
|
||||
": a="..tostring(a)..
|
||||
",v_0="..tostring(v_0)..
|
||||
",x_0="..tostring(x_0)..
|
||||
|
@ -334,7 +339,7 @@ local function do_movement_step(self, dtime)
|
|||
staticdata.distance = x_1
|
||||
|
||||
if DEBUG and (1==0) and ( v_0 > 0 or a ~= 0 ) then
|
||||
print( "- cart #"..tostring(staticdata.uuid)..
|
||||
mcl_debug( "- cart #"..tostring(staticdata.uuid)..
|
||||
": a="..tostring(a)..
|
||||
",v_0="..tostring(v_0)..
|
||||
",v_1="..tostring(v_1)..
|
||||
|
@ -362,7 +367,7 @@ local function do_movement_step(self, dtime)
|
|||
-- Get the next direction
|
||||
local next_dir,_ = mcl_minecarts:get_rail_direction(pos, staticdata.dir, nil, nil, staticdata.railtype)
|
||||
if DEBUG and next_dir ~= staticdata.dir then
|
||||
print( "Changing direction from "..tostring(staticdata.dir).." to "..tostring(next_dir))
|
||||
mcl_debug( "Changing direction from "..tostring(staticdata.dir).." to "..tostring(next_dir))
|
||||
end
|
||||
|
||||
-- Handle cart collisions
|
||||
|
@ -376,7 +381,7 @@ local function do_movement_step(self, dtime)
|
|||
|
||||
-- Handle end of track
|
||||
if next_dir == staticdata.dir * -1 and next_dir.y == 0 then
|
||||
if DEBUG then print("Stopping cart at end of track at "..tostring(pos)) end
|
||||
if DEBUG then mcl_debug("Stopping cart at end of track at "..tostring(pos)) end
|
||||
staticdata.velocity = 0
|
||||
end
|
||||
|
||||
|
@ -384,7 +389,7 @@ local function do_movement_step(self, dtime)
|
|||
staticdata.dir = next_dir
|
||||
elseif stops_in_block and v_1 < (friction/5) and a <= 0 then
|
||||
-- Handle direction flip due to gravity
|
||||
if DEBUG then print("Gravity flipped direction") end
|
||||
if DEBUG then mcl_debug("Gravity flipped direction") end
|
||||
|
||||
-- Velocity should be zero at this point
|
||||
staticdata.velocity = 0
|
||||
|
@ -405,7 +410,7 @@ local function do_movement_step(self, dtime)
|
|||
|
||||
-- Debug reporting
|
||||
if DEBUG and ( v_0 > 0 or v_1 > 0 ) then
|
||||
print( " cart #"..tostring(staticdata.uuid)..
|
||||
mcl_debug( " cart #"..tostring(staticdata.uuid)..
|
||||
": a="..tostring(a)..
|
||||
",v_0="..tostring(v_0)..
|
||||
",v_1="..tostring(v_1)..
|
||||
|
|
|
@ -4,7 +4,9 @@ local mod = mcl_minecarts
|
|||
|
||||
-- Imports
|
||||
local get_cart_data = mod.get_cart_data
|
||||
local MAX_TRAIN_LENGTH = mod.MAX_TRAIN_LENGTH
|
||||
|
||||
-- Follow .behind to the back end of a train
|
||||
local function find_back(start)
|
||||
while start.behind do
|
||||
local nxt = get_cart_data(start.behind)
|
||||
|
@ -14,10 +16,13 @@ local function find_back(start)
|
|||
return start
|
||||
end
|
||||
|
||||
-- Iterate across all the cars in a train
|
||||
local function train_cars(anchor)
|
||||
local back = find_back(anchor._staticdata)
|
||||
local limit = MAX_TRAIN_LENGTH
|
||||
return function()
|
||||
if not back then return end
|
||||
if not back or limit <= 0 then return end
|
||||
limit = limit - 1
|
||||
|
||||
local ret = back
|
||||
if back.ahead then
|
||||
|
@ -28,26 +33,6 @@ local function train_cars(anchor)
|
|||
return ret
|
||||
end
|
||||
end
|
||||
|
||||
function mod.update_train(cart)
|
||||
local sum_velocity = 0
|
||||
local count = 0
|
||||
for cart in train_cars(cart) do
|
||||
count = count + 1
|
||||
sum_velocity = sum_velocity + (cart.velocity or 0)
|
||||
end
|
||||
local avg_velocity = sum_velocity / count
|
||||
if count == 0 then return end
|
||||
|
||||
print("Using velocity "..tostring(avg_velocity))
|
||||
|
||||
-- Set the entire train to the average velocity
|
||||
for c in train_cars(cart) do
|
||||
print(tostring(c.behind).."->"..c.uuid.."->"..tostring(c.ahead).." setting cart #"..c.uuid.." velocity to "..tostring(avg_velocity))
|
||||
c.velocity = avg_velocity
|
||||
end
|
||||
end
|
||||
|
||||
function mod.train_length(cart)
|
||||
local count = 0
|
||||
for cart in train_cars(cart) do
|
||||
|
@ -55,6 +40,68 @@ function mod.train_length(cart)
|
|||
end
|
||||
return count
|
||||
end
|
||||
|
||||
function mod.is_in_same_train(anchor, other)
|
||||
for cart in train_cars(anchor) do
|
||||
if cart.uuid == other.uuid then return true end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function mod.distance_between_cars(car1, car2)
|
||||
if not car1.connected_at then return nil end
|
||||
if not car2.connected_at then return nil end
|
||||
|
||||
if not car1.dir then car1.dir = vector.zero() end
|
||||
if not car2.dir then car2.dir = vector.zero() end
|
||||
|
||||
local pos1 = vector.add(car1.connected_at, vector.multiply(car1.dir, car1.distance))
|
||||
local pos2 = vector.add(car2.connected_at, vector.multiply(car2.dir, car2.distance))
|
||||
|
||||
return vector.distance(pos1, pos2)
|
||||
end
|
||||
local distance_between_cars = mod.distance_between_cars
|
||||
|
||||
function mod.update_train(cart)
|
||||
local staticdata = cart._staticdata
|
||||
|
||||
-- Only update from the back
|
||||
if staticdata.behind or not staticdata.ahead then return end
|
||||
print("\nUpdating train")
|
||||
|
||||
-- Do no special processing if the cart is not part of a train
|
||||
if not staticdata.ahead and not staticdata.behind then return end
|
||||
|
||||
-- Calculate the average velocity of all train cars
|
||||
local sum_velocity = 0
|
||||
for cart in train_cars(cart) do
|
||||
if cart.velocity or 0 > velocity then
|
||||
velocity = cart.velocity
|
||||
end
|
||||
end
|
||||
print("Using velocity "..tostring(velocity))
|
||||
|
||||
-- Set the entire train to the average velocity
|
||||
local behind = nil
|
||||
for c in train_cars(cart) do
|
||||
local e = 0
|
||||
local separation
|
||||
if behind then
|
||||
separation = distance_between_cars(behind, c)
|
||||
local e = 0
|
||||
if separation > 1.25 then
|
||||
velocity = velocity * 0.9
|
||||
elseif separation < 1.15 then
|
||||
velocity = velocity * 1.1
|
||||
end
|
||||
end
|
||||
print(tostring(c.behind).."->"..c.uuid.."->"..tostring(c.ahead).."("..tostring(separation)..") setting cart #"..c.uuid.." velocity to "..tostring(velocity))
|
||||
c.velocity = velocity
|
||||
|
||||
behind = c
|
||||
end
|
||||
end
|
||||
|
||||
function mod.link_cart_ahead(cart, cart_ahead)
|
||||
local staticdata = cart._staticdata
|
||||
local ca_staticdata = cart_ahead._staticdata
|
||||
|
@ -64,9 +111,3 @@ function mod.link_cart_ahead(cart, cart_ahead)
|
|||
staticdata.ahead = ca_staticdata.uuid
|
||||
ca_staticdata.behind = staticdata.uuid
|
||||
end
|
||||
function mod.is_in_same_train(anchor, other)
|
||||
for cart in train_cars(anchor) do
|
||||
if cart.uuid == other.uuid then return true end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue