fixed even more lua errors and made stable

This commit is contained in:
orwell96 2016-05-30 19:58:09 +02:00
parent c71b020927
commit d81509c049
5 changed files with 115 additions and 60 deletions

View File

@ -97,9 +97,9 @@ e.g. itemstack:take_item(); return itemstack
^ The default functions handle regular use cases. ^ The default functions handle regular use cases.
]] ]]
}) })
minetest.register_tool("advtrains:tttool", minetest.register_tool("advtrains:tunnelborer",
{ {
description = "traintester tool", description = "tunnelborer",
groups = {cracky=1}, -- key=name, value=rating; rating=1..3. groups = {cracky=1}, -- key=name, value=rating; rating=1..3.
inventory_image = "drwho_screwdriver.png", inventory_image = "drwho_screwdriver.png",
wield_image = "drwho_screwdriver.png", wield_image = "drwho_screwdriver.png",
@ -113,17 +113,14 @@ minetest.register_tool("advtrains:tttool",
^ Shall place item and return the leftover itemstack ^ Shall place item and return the leftover itemstack
^ default: minetest.item_place ]] ^ default: minetest.item_place ]]
on_use = function(itemstack, user, pointed_thing) on_use = function(itemstack, user, pointed_thing)
if pointed_thing.type=="object" then if pointed_thing.type=="node" then
local luaent=pointed_thing.ref:get_luaentity() for x=-1,1 do
if luaent and luaent.is_wagon then for y=-1,1 do
minetest.chat_send_all("wagon yaw is "..pointed_thing.ref:getyaw()) for z=-1,1 do
minetest.chat_send_all("trains last yaw is set to "..luaent:train().last_front_yaw) minetest.remove_node(vector.add(pointed_thing.under, {x=x, y=y, z=z}))
minetest.chat_send_all("end report") end
end
end end
else
minetest.chat_send_all(dump(minetest.get_node(pointed_thing.under)))
local c1, c2=advtrains.get_track_connections(minetest.get_node(pointed_thing.under).name, minetest.get_node(pointed_thing.under).param2)
minetest.chat_send_all(c1.." <-> "..c2)
end end
end, end,
--[[ --[[

View File

@ -107,7 +107,7 @@ function advtrains.conway(midreal, prev, traintype)--in order prev,mid,return
return nil return nil
end end
local nextnode_ok, nextdir1, nextdir2, nextrely1, nextrely2, nextrailheight=advtrains.get_rail_info_at(advtrains.round_vector_floor_y(mid), traintype) local nextnode_ok, nextdir1, nextdir2, nextrely1, nextrely2, nextrailheight=advtrains.get_rail_info_at(advtrains.round_vector_floor_y(next), traintype)
--is it a rail? --is it a rail?
if(not nextnode_ok) then if(not nextnode_ok) then
@ -115,7 +115,7 @@ function advtrains.conway(midreal, prev, traintype)--in order prev,mid,return
next.y=next.y-1 next.y=next.y-1
y_offset=y_offset-1 y_offset=y_offset-1
nextnode_ok, nextdir1, nextdir2, nextrely1, nextrely2, nextrailheight=advtrains.get_rail_info_at(advtrains.round_vector_floor_y(mid), traintype) nextnode_ok, nextdir1, nextdir2, nextrely1, nextrely2, nextrailheight=advtrains.get_rail_info_at(advtrains.round_vector_floor_y(next), traintype)
if(not nextnode_ok) then if(not nextnode_ok) then
print("[advtrains]in conway: one below "..minetest.pos_to_string(next).." is not a rail either, returning!") print("[advtrains]in conway: one below "..minetest.pos_to_string(next).." is not a rail either, returning!")
return nil return nil
@ -128,7 +128,7 @@ function advtrains.conway(midreal, prev, traintype)--in order prev,mid,return
next.y=next.y-1 next.y=next.y-1
y_offset=y_offset-1 y_offset=y_offset-1
nextnode_ok, nextdir1, nextdir2, nextrely1, nextrely2, nextrailheight=advtrains.get_rail_info_at(advtrains.round_vector_floor_y(mid), traintype) nextnode_ok, nextdir1, nextdir2, nextrely1, nextrely2, nextrailheight=advtrains.get_rail_info_at(advtrains.round_vector_floor_y(next), traintype)
if(not nextnode_ok) then if(not nextnode_ok) then
print("[advtrains]in conway: (at connecting if check again) one below "..minetest.pos_to_string(next).." is not a rail either, returning!") print("[advtrains]in conway: (at connecting if check again) one below "..minetest.pos_to_string(next).." is not a rail either, returning!")
return nil return nil

View File

@ -1,3 +1,4 @@
local print=function(t) minetest.log("action", t) minetest.chat_send_all(t) end
--pseudoload.lua --pseudoload.lua
--responsible for keeping up a database of all rail nodes existant in the world, regardless of whether the mapchunk is loaded. --responsible for keeping up a database of all rail nodes existant in the world, regardless of whether the mapchunk is loaded.
@ -9,6 +10,9 @@ advtrains.trackdb={}
--[] may be missing if 0,0,0 --[] may be missing if 0,0,0
--load initially --load initially
--[[ TODO temporary outcomment
--delayed since all traintypes need to be registered --delayed since all traintypes need to be registered
minetest.after(0, function() minetest.after(0, function()
@ -23,9 +27,10 @@ for tt, _ in pairs(advtrains.all_traintypes) do
--custom format to save memory --custom format to save memory
while true do while true do
local xbytes=file:read(2) local xbytes=file:read(2)
if not xbytes then if not xbytes or #xbytes<2 then
break --eof reached break --eof reached
end end
print(xbytes)
local ybytes=file:read(2) local ybytes=file:read(2)
local zbytes=file:read(2) local zbytes=file:read(2)
local x=(string.byte(xbytes[1])-128)*256+(string.byte(xbytes[2])) local x=(string.byte(xbytes[1])-128)*256+(string.byte(xbytes[2]))
@ -74,9 +79,10 @@ function advtrains.save_trackdb()
print("[advtrains]Failed saving advtrains trackdb save file "..er) print("[advtrains]Failed saving advtrains trackdb save file "..er)
else else
--custom format to save memory --custom format to save memory
for x,txl in pairs(advtrains.trackdb[tt]) do for y,tyl in pairs(advtrains.trackdb[tt]) do
for y,tyl in pairs(txl) do for x,txl in pairs(tyl) do
for z,rail in pairs(tyl) do for z,rail in pairs(txl) do
print("write "..x.." "..y.." "..z.." "..minetest.serialize(rail))
file:write(string.char(math.floor(x/256)+128)..string.char((x%256))) file:write(string.char(math.floor(x/256)+128)..string.char((x%256)))
file:write(string.char(math.floor(y/256)+128)..string.char((y%256))) file:write(string.char(math.floor(y/256)+128)..string.char((y%256)))
file:write(string.char(math.floor(z/256)+128)..string.char((z%256))) file:write(string.char(math.floor(z/256)+128)..string.char((z%256)))
@ -93,6 +99,33 @@ function advtrains.save_trackdb()
end end
end end
end end
]]--end temp outcomment
advtrains.trackdb={}
advtrains.fpath_tdb=minetest.get_worldpath().."/advtrains_trackdb"
local file, err = io.open(advtrains.fpath_tdb, "r")
if not file then
local er=err or "Unknown Error"
print("[advtrains]Failed loading advtrains save file "..er)
else
local tbl = minetest.deserialize(file:read("*a"))
if type(tbl) == "table" then
advtrains.trackdb=tbl
end
file:close()
end
function advtrains.save_trackdb()
local datastr = minetest.serialize(advtrains.trackdb)
if not datastr then
minetest.log("error", "[advtrains] Failed to serialize trackdb data!")
return
end
local file, err = io.open(advtrains.fpath_tdb, "w")
if err then
return err
end
file:write(datastr)
file:close()
end
--get_node with pseudoload. --get_node with pseudoload.
--returns: --returns:

View File

@ -68,7 +68,18 @@ advtrains.save = function()
advtrains.wagon_save[wagon.unique_id]=advtrains.merge_tables(wagon)--so, will only copy non_metatable elements advtrains.wagon_save[wagon.unique_id]=advtrains.merge_tables(wagon)--so, will only copy non_metatable elements
end end
end end
--cross out userdata
for w_id, data in pairs(advtrains.wagon_save) do
data.name=nil
data.object=nil
if data.driver then
data.driver_name=data.driver:get_player_name()
data.driver=nil
else
data.driver_name=nil
end
end
--print(dump(advtrains.wagon_save))
datastr = minetest.serialize(advtrains.wagon_save) datastr = minetest.serialize(advtrains.wagon_save)
if not datastr then if not datastr then
minetest.log("error", "[advtrains] Failed to serialize train data!") minetest.log("error", "[advtrains] Failed to serialize train data!")
@ -80,6 +91,8 @@ advtrains.save = function()
end end
file:write(datastr) file:write(datastr)
file:close() file:close()
advtrains.save_trackdb()
end end
minetest.register_on_shutdown(advtrains.save) minetest.register_on_shutdown(advtrains.save)
@ -90,7 +103,7 @@ minetest.register_globalstep(function(dtime)
--print("[advtrains] audit step") --print("[advtrains] audit step")
--clean up orphaned trains --clean up orphaned trains
for k,v in pairs(advtrains.trains) do for k,v in pairs(advtrains.trains) do
advtrains.update_trainpart_properties(k) --advtrains.update_trainpart_properties(k)
if #v.trainparts==0 then if #v.trainparts==0 then
advtrains.trains[k]=nil advtrains.trains[k]=nil
end end
@ -112,7 +125,7 @@ function advtrains.train_step(id, train, dtime)
--if not train.last_pos then advtrains.trains[id]=nil return end --if not train.last_pos then advtrains.trains[id]=nil return end
if not advtrains.pathpredict(id, train) then if not advtrains.pathpredict(id, train) then
--print("pathpredict failed(returned false)") print("pathpredict failed(returned false)")
train.velocity=0 train.velocity=0
train.tarvelocity=0 train.tarvelocity=0
return return
@ -122,7 +135,7 @@ function advtrains.train_step(id, train, dtime)
if not path then if not path then
train.velocity=0 train.velocity=0
train.tarvelocity=0 train.tarvelocity=0
--print("train has no path") print("train has no path for whatever reason")
return return
end end
--apply off-track handling: --apply off-track handling:
@ -169,40 +182,48 @@ function advtrains.train_step(id, train, dtime)
end end
end end
--check for any trainpart entities if they have been unloaded. do this only if both front and end positions are loaded, to ensure train entities will be placed inside loaded area, and only every second. --check for any trainpart entities if they have been unloaded. do this only if train is near a player, to not spawn entities into unloaded areas
train.check_trainpartload=(train.check_trainpartload or 0)-dtime train.check_trainpartload=(train.check_trainpartload or 0)-dtime
if train.check_trainpartload<=0 and posfront and posback and minetest.get_node_or_nil(posfront) and minetest.get_node_or_nil(posback) then local node_range=(math.max((minetest.setting_get("active_block_range") or 0),1)*16)
--it is better to iterate luaentites only once if train.check_trainpartload<=0 and posfront and posback then
local found_uids={} print(minetest.pos_to_string(posfront))
for _,wagon in pairs(minetest.luaentities) do local should_check=false
if wagon.is_wagon and wagon.initialized and wagon.train_id==id then for _,p in ipairs(minetest.get_connected_players()) do
if found_uids[wagon.unique_id] then should_check=should_check or ((vector.distance(posfront, p:getpos())<node_range) and (vector.distance(posback, p:getpos())<node_range))
--duplicate found, delete it end
if wagon.object then wagon.object:remove() end if should_check then
else --it is better to iterate luaentites only once
found_uids[wagon.unique_id]=true print("check_trainpartload")
local found_uids={}
for _,wagon in pairs(minetest.luaentities) do
if wagon.is_wagon and wagon.initialized and wagon.train_id==id then
if found_uids[wagon.unique_id] then
--duplicate found, delete it
if wagon.object then wagon.object:remove() end
else
found_uids[wagon.unique_id]=true
end
end end
end end
end print("found_uids: "..dump(found_uids))
--now iterate trainparts and check. then cross them out to see if there are wagons over for any reason --now iterate trainparts and check. then cross them out to see if there are wagons over for any reason
for pit, w_id in ipairs(train.trainparts) do for pit, w_id in ipairs(train.trainparts) do
if found_uids[w_id] then if found_uids[w_id] then
found_uids[w_id]=nil print(w_id.." still loaded")
elseif advtrains.wagon_save[w_id] then elseif advtrains.wagon_save[w_id] then
--spawn a new and initialize it with the properties from wagon_save print(w_id.." not loaded, but save available")
local le=minetest.env:add_entity(posfront, advtrains.wagon_save[w_id].name):get_luaentity() --spawn a new and initialize it with the properties from wagon_save
for k,v in pairs(advtrains.wagon_save[w_id]) do local le=minetest.env:add_entity(posfront, advtrains.wagon_save[w_id].entity_name):get_luaentity()
le[k]=v for k,v in pairs(advtrains.wagon_save[w_id]) do
le[k]=v
end
advtrains.wagon_save[w_id].name=nil
advtrains.wagon_save[w_id].object=nil
else
print(w_id.." not loaded and no save available")
--what the hell...
table.remove(train.trainparts, pit)
end end
advtrains.wagon_save[w_id].name=nil
advtrains.wagon_save[w_id].object=nil
else
--what the hell...
local le=minetest.env:add_entity(posfront, advtrains.wagon_save[w_id].name):get_luaentity()
le.unique_id=w_id
le.train_id=id
le.pos_in_trainparts=pit
advtrains.update_trainpart_properties(id, train)
end end
end end
train.check_trainpartload=1 train.check_trainpartload=1
@ -419,6 +440,7 @@ function advtrains.update_trainpart_properties(train_id, invert_flipstate)
local rel_pos=0 local rel_pos=0
local count_l=0 local count_l=0
for i, w_id in ipairs(train.trainparts) do for i, w_id in ipairs(train.trainparts) do
local any_loaded=false
for _,wagon in pairs(minetest.luaentities) do for _,wagon in pairs(minetest.luaentities) do
if wagon.is_wagon and wagon.initialized and wagon.unique_id==w_id then if wagon.is_wagon and wagon.initialized and wagon.unique_id==w_id then
rel_pos=rel_pos+wagon.wagon_span rel_pos=rel_pos+wagon.wagon_span
@ -433,8 +455,12 @@ function advtrains.update_trainpart_properties(train_id, invert_flipstate)
wagon.wagon_flipped = not wagon.wagon_flipped wagon.wagon_flipped = not wagon.wagon_flipped
end end
rel_pos=rel_pos+wagon.wagon_span rel_pos=rel_pos+wagon.wagon_span
any_loaded=true
end end
end end
if not any_loaded then
print("update_trainpart_properties wagon "..w_id.." not loaded, ignoring it.")
end
end end
train.trainlen=rel_pos train.trainlen=rel_pos
train.locomotives_in_train=count_l train.locomotives_in_train=count_l

View File

@ -67,6 +67,7 @@ function wagon:on_activate(staticdata, dtime_s)
self.old_pos = self.object:getpos() self.old_pos = self.object:getpos()
self.old_velocity = self.velocity self.old_velocity = self.velocity
self.initialized_pre=true self.initialized_pre=true
self.entity_name=self.name
--same code is in on_step --same code is in on_step
--does this object already have an ID? --does this object already have an ID?
@ -125,6 +126,7 @@ function wagon:on_punch(puncher, time_from_last_punch, tool_capabilities, direct
table.remove(self:train().trainparts, self.pos_in_trainparts) table.remove(self:train().trainparts, self.pos_in_trainparts)
advtrains.update_trainpart_properties(self.train_id) advtrains.update_trainpart_properties(self.train_id)
advtrains.wagon_save[self.unique_id]=nil
return return
@ -138,18 +140,15 @@ function wagon:on_step(dtime)
return return
end end
self.entity_name=self.name
--does this object already have an ID? --does this object already have an ID?
if not self.unique_id then if not self.unique_id then
self.unique_id=os.time()..os.clock()--should be random enough. self.unique_id=os.time()..os.clock()--should be random enough.
end end
--is my train still here --is my train still here
if not self.train_id or not self:train() then if not self.train_id or not self:train() then
if self.initialized then print("[advtrains][wagon "..self.unique_id.."] missing train_id, destroying")
print("[advtrains][wagon "..self.unique_id.."] missing train_id, destroying") self.object:remove()
self.object:remove()
return
end
print("[advtrains][wagon "..self.unique_id.."] missing train_id, but not yet initialized, returning")
return return
elseif not self.initialized then elseif not self.initialized then
self.initialized=true self.initialized=true
@ -166,7 +165,7 @@ function wagon:on_step(dtime)
elseif (not self.wagon_flipped and pc.down) or (self.wagon_flipped and pc.up) then --slower elseif (not self.wagon_flipped and pc.down) or (self.wagon_flipped and pc.up) then --slower
self:train().tarvelocity=math.max(self:train().tarvelocity-1, -(advtrains.all_traintypes[self:train().traintype].max_speed or 10)) self:train().tarvelocity=math.max(self:train().tarvelocity-1, -(advtrains.all_traintypes[self:train().traintype].max_speed or 10))
elseif pc.aux1 then --slower elseif pc.aux1 then --slower
if math.abs(self:train().velocity)<=3 then if true or math.abs(self:train().velocity)<=3 then--TODO debug
self.driver:set_detach() self.driver:set_detach()
self.driver:set_eye_offset({x=0,y=0,z=0}, {x=0,y=0,z=0}) self.driver:set_eye_offset({x=0,y=0,z=0}, {x=0,y=0,z=0})
advtrains.set_trainhud(self.driver:get_player_name(), "") advtrains.set_trainhud(self.driver:get_player_name(), "")