rework entity handling
some modularization, clarify 'initialized' property, some re-implementationsmaster
parent
ee6b7494bb
commit
20a1171144
BIN
advtrains.zip
BIN
advtrains.zip
Binary file not shown.
|
@ -1,7 +1,8 @@
|
||||||
--trainlogic.lua
|
--trainlogic.lua
|
||||||
--controls train entities stuff about connecting/disconnecting/colliding trains and other things
|
--controls train entities stuff about connecting/disconnecting/colliding trains and other things
|
||||||
|
|
||||||
local print=function(t, ...) minetest.log("action", table.concat({t, ...}, " ")) minetest.chat_send_all(table.concat({t, ...}, " ")) end
|
--local print=function(t, ...) minetest.log("action", table.concat({t, ...}, " ")) minetest.chat_send_all(table.concat({t, ...}, " ")) end
|
||||||
|
local print=function() end
|
||||||
|
|
||||||
local benchmark=false
|
local benchmark=false
|
||||||
--printbm=function(str, t) print("[advtrains]"..str.." "..((os.clock()-t)*1000).."ms") end
|
--printbm=function(str, t) print("[advtrains]"..str.." "..((os.clock()-t)*1000).."ms") end
|
||||||
|
@ -95,7 +96,7 @@ advtrains.save = function()
|
||||||
-- update wagon saves
|
-- update wagon saves
|
||||||
for _,wagon in pairs(minetest.luaentities) do
|
for _,wagon in pairs(minetest.luaentities) do
|
||||||
if wagon.is_wagon and wagon.initialized then
|
if wagon.is_wagon and wagon.initialized then
|
||||||
advtrains.wagon_save[wagon.unique_id]=advtrains.merge_tables(wagon)--so, will only copy non_metatable elements
|
wagon:get_staticdata()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
--cross out userdata
|
--cross out userdata
|
||||||
|
@ -140,6 +141,7 @@ minetest.register_globalstep(function(dtime)
|
||||||
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
|
||||||
|
print("[advtrains][train "..k.."] has empty trainparts, removing.")
|
||||||
advtrains.trains[k]=nil
|
advtrains.trains[k]=nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -248,6 +250,7 @@ function advtrains.train_step(id, train, dtime)
|
||||||
local node_range=(math.max((minetest.setting_get("active_block_range") or 0),1)*16)
|
local node_range=(math.max((minetest.setting_get("active_block_range") or 0),1)*16)
|
||||||
if train.check_trainpartload<=0 then
|
if train.check_trainpartload<=0 then
|
||||||
local ori_pos=advtrains.get_real_index_position(path, train.index) --not much to calculate
|
local ori_pos=advtrains.get_real_index_position(path, train.index) --not much to calculate
|
||||||
|
print("[advtrains][train "..id.."] at "..minetest.pos_to_string(vector.round(ori_pos)))
|
||||||
|
|
||||||
local should_check=false
|
local should_check=false
|
||||||
for _,p in ipairs(minetest.get_connected_players()) do
|
for _,p in ipairs(minetest.get_connected_players()) do
|
||||||
|
@ -276,11 +279,7 @@ function advtrains.train_step(id, train, dtime)
|
||||||
--print(w_id.." not loaded, but save available")
|
--print(w_id.." not loaded, but save available")
|
||||||
--spawn a new and initialize it with the properties from wagon_save
|
--spawn a new and initialize it with the properties from wagon_save
|
||||||
local le=minetest.env:add_entity(ori_pos, advtrains.wagon_save[w_id].entity_name):get_luaentity()
|
local le=minetest.env:add_entity(ori_pos, advtrains.wagon_save[w_id].entity_name):get_luaentity()
|
||||||
for k,v in pairs(advtrains.wagon_save[w_id]) do
|
le:init_from_wagon_save(w_id)
|
||||||
le[k]=v
|
|
||||||
end
|
|
||||||
advtrains.wagon_save[w_id].name=nil
|
|
||||||
advtrains.wagon_save[w_id].object=nil
|
|
||||||
else
|
else
|
||||||
print(w_id.." not loaded and no save available")
|
print(w_id.." not loaded and no save available")
|
||||||
--what the hell...
|
--what the hell...
|
||||||
|
|
163
wagons.lua
163
wagons.lua
|
@ -1,5 +1,6 @@
|
||||||
--atan2 counts angles clockwise, minetest does counterclockwise
|
--atan2 counts angles clockwise, minetest does counterclockwise
|
||||||
local print=function(t) minetest.log("action", t) minetest.chat_send_all(t) end
|
--local print=function(t) minetest.log("action", t) minetest.chat_send_all(t) end
|
||||||
|
local print=function() end
|
||||||
|
|
||||||
local wagon={
|
local wagon={
|
||||||
collisionbox = {-0.5,-0.5,-0.5, 0.5,0.5,0.5},
|
collisionbox = {-0.5,-0.5,-0.5, 0.5,0.5,0.5},
|
||||||
|
@ -44,51 +45,36 @@ function wagon:train()
|
||||||
return advtrains.trains[self.train_id]
|
return advtrains.trains[self.train_id]
|
||||||
end
|
end
|
||||||
|
|
||||||
function wagon:on_activate(staticdata, dtime_s)
|
--[[about 'initalized':
|
||||||
--print("[advtrains][wagon "..(self.unique_id or "no-id").."] activated")
|
when initialized is false, the entity hasn't got any data yet and should wait for these to be set before doing anything
|
||||||
self.object:set_armor_groups({immortal=1})
|
when loading an existing object (with staticdata), it will be set
|
||||||
if staticdata then
|
when instanciating a new object via add_entity, it is not set at the time on_activate is called.
|
||||||
local tmp = minetest.deserialize(staticdata)
|
then, wagon:initialize() will be called
|
||||||
if tmp then
|
|
||||||
self.unique_id=tmp.unique_id
|
|
||||||
self.train_id=tmp.train_id
|
|
||||||
self.wagon_flipped=tmp.wagon_flipped
|
|
||||||
self.owner=tmp.owner
|
|
||||||
self.seatp=tmp.seatp
|
|
||||||
end
|
|
||||||
|
|
||||||
|
wagon will save only uid in staticdata, no serialized table
|
||||||
|
]]
|
||||||
|
function wagon:on_activate(sd_uid, dtime_s)
|
||||||
|
print("[advtrains][wagon "..((sd_uid and sd_uid~="" and sd_uid) or "no-id").."] activated")
|
||||||
|
self.object:set_armor_groups({immortal=1})
|
||||||
|
if sd_uid and sd_uid~="" then
|
||||||
|
--legacy
|
||||||
|
--expect this to be a serialized table and handle
|
||||||
|
if minetest.deserialize(sd_uid) then
|
||||||
|
self:init_from_wagon_save(minetest.deserialize(sd_uid).unique_id)
|
||||||
|
else
|
||||||
|
self:init_from_wagon_save(sd_uid)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
self.old_pos = self.object:getpos()
|
|
||||||
self.old_velocity = self.velocity
|
|
||||||
self.initialized_pre=true
|
|
||||||
self.entity_name=self.name
|
self.entity_name=self.name
|
||||||
|
|
||||||
--same code is in on_step
|
--duplicates?
|
||||||
--does this object already have an ID?
|
|
||||||
if not self.unique_id then
|
|
||||||
self.unique_id=os.time()..os.clock()--should be random enough.
|
|
||||||
else
|
|
||||||
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==self.unique_id then--i am a duplicate!
|
if wagon.is_wagon and wagon.initialized and wagon.unique_id==self.unique_id and wagon~=self then--i am a duplicate!
|
||||||
|
print("[advtrains][wagon "..((sd_uid and sd_uid~="" and sd_uid) or "no-id").."] duplicate found, removing")
|
||||||
self.object:remove()
|
self.object:remove()
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
--is my train still here
|
|
||||||
if not self.train_id or not self:train() then
|
|
||||||
if self.initialized then
|
|
||||||
print("[advtrains][wagon "..self.unique_id.."] missing train_id, destroying")
|
|
||||||
self.object:remove()
|
|
||||||
return
|
|
||||||
end
|
|
||||||
print("[advtrains][wagon "..self.unique_id.."] missing train_id, but not yet initialized, returning")
|
|
||||||
return
|
|
||||||
elseif not self.initialized then
|
|
||||||
self.initialized=true
|
|
||||||
end
|
|
||||||
advtrains.update_trainpart_properties(self.train_id)
|
|
||||||
minetest.after(1, function() self:reattach_all() end)
|
|
||||||
|
|
||||||
if self.custom_on_activate then
|
if self.custom_on_activate then
|
||||||
self:custom_on_activate(staticdata_table, dtime_s)
|
self:custom_on_activate(staticdata_table, dtime_s)
|
||||||
|
@ -96,19 +82,57 @@ function wagon:on_activate(staticdata, dtime_s)
|
||||||
end
|
end
|
||||||
|
|
||||||
function wagon:get_staticdata()
|
function wagon:get_staticdata()
|
||||||
|
if not self:ensure_init() then return end
|
||||||
|
print("[advtrains][wagon "..((self.unique_id and self.unique_id~="" and self.unique_id) or "no-id").."]: saving to wagon_save")
|
||||||
--save to table before being unloaded
|
--save to table before being unloaded
|
||||||
advtrains.wagon_save[self.unique_id]=advtrains.merge_tables(self)
|
advtrains.wagon_save[self.unique_id]=advtrains.merge_tables(self)
|
||||||
return minetest.serialize({
|
advtrains.wagon_save[self.unique_id].entity_name=self.name
|
||||||
unique_id=self.unique_id,
|
advtrains.wagon_save[self.unique_id].name=nil
|
||||||
train_id=self.train_id,
|
advtrains.wagon_save[self.unique_id].object=nil
|
||||||
wagon_flipped=self.wagon_flipped,
|
return self.unique_id
|
||||||
owner=self.owner,
|
end
|
||||||
seatp=self.seatp,
|
--returns: uid of wagon
|
||||||
})
|
function wagon:init_new_instance(train_id, properties)
|
||||||
|
self.unique_id=os.time()..os.clock()
|
||||||
|
self.train_id=train_id
|
||||||
|
for k,v in pairs(properties) do
|
||||||
|
if k~="name" and k~="object" then
|
||||||
|
self[k]=v
|
||||||
|
end
|
||||||
|
end
|
||||||
|
minetest.after(1, function() self:reattach_all() end)
|
||||||
|
self.initialized=true
|
||||||
|
print("init_new_instance "..self.unique_id.." ("..self.train_id..")")
|
||||||
|
return self.unique_id
|
||||||
|
end
|
||||||
|
function wagon:init_from_wagon_save(uid)
|
||||||
|
if not advtrains.wagon_save[uid] then
|
||||||
|
self.object:remove()
|
||||||
|
return
|
||||||
|
end
|
||||||
|
self.unique_id=uid
|
||||||
|
for k,v in pairs(advtrains.wagon_save[uid]) do
|
||||||
|
if k~="name" and k~="object" then
|
||||||
|
self[k]=v
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if not self.train_id or not self:train() then
|
||||||
|
self.object:remove()
|
||||||
|
return
|
||||||
|
end
|
||||||
|
self.initialized=true
|
||||||
|
print("init_from_wagon_save "..self.unique_id.." ("..self.train_id..")")
|
||||||
|
advtrains.update_trainpart_properties(self.train_id)
|
||||||
|
end
|
||||||
|
function wagon:ensure_init()
|
||||||
|
if self.initialized then return true end
|
||||||
|
self.object:setvelocity({x=0,y=0,z=0})
|
||||||
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Remove the wagon
|
-- Remove the wagon
|
||||||
function wagon:on_punch(puncher, time_from_last_punch, tool_capabilities, direction)
|
function wagon:on_punch(puncher, time_from_last_punch, tool_capabilities, direction)
|
||||||
|
if not self:ensure_init() then return end
|
||||||
if not puncher or not puncher:is_player() then
|
if not puncher or not puncher:is_player() then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
@ -159,9 +183,9 @@ function wagon:destroy()
|
||||||
self.custom_on_destroy(self, puncher, time_from_last_punch, tool_capabilities, direction)
|
self.custom_on_destroy(self, puncher, time_from_last_punch, tool_capabilities, direction)
|
||||||
end
|
end
|
||||||
|
|
||||||
self.object:remove()
|
print("[advtrains][wagon "..((self.unique_id and self.unique_id~="" and self.unique_id) or "no-id").."]: destroying")
|
||||||
|
|
||||||
if not self.initialized then return end
|
self.object:remove()
|
||||||
|
|
||||||
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)
|
||||||
|
@ -172,6 +196,8 @@ end
|
||||||
|
|
||||||
|
|
||||||
function wagon:on_step(dtime)
|
function wagon:on_step(dtime)
|
||||||
|
if not self:ensure_init() then return end
|
||||||
|
|
||||||
local t=os.clock()
|
local t=os.clock()
|
||||||
local pos = self.object:getpos()
|
local pos = self.object:getpos()
|
||||||
|
|
||||||
|
@ -180,17 +206,8 @@ function wagon:on_step(dtime)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
if not self.initialized_pre then
|
|
||||||
print("[advtrains] wagon stepping while not yet initialized_pre, returning")
|
|
||||||
self.object:setvelocity({x=0,y=0,z=0})
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
self.entity_name=self.name
|
self.entity_name=self.name
|
||||||
--does this object already have an ID?
|
|
||||||
if not self.unique_id then
|
|
||||||
self.unique_id=os.time()..os.clock()--should be random enough.
|
|
||||||
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
|
||||||
print("[advtrains][wagon "..self.unique_id.."] missing train_id, destroying")
|
print("[advtrains][wagon "..self.unique_id.."] missing train_id, destroying")
|
||||||
|
@ -203,17 +220,6 @@ function wagon:on_step(dtime)
|
||||||
self.seatp={}
|
self.seatp={}
|
||||||
end
|
end
|
||||||
|
|
||||||
--re-attach driver if he got lost
|
|
||||||
--if not self.driver and self.driver_name then
|
|
||||||
-- local clicker=minetest.get_player_by_name(self.driver_name)
|
|
||||||
-- if clicker then
|
|
||||||
-- self.driver = clicker
|
|
||||||
-- advtrains.player_to_wagon_mapping[clicker:get_player_name()]=self
|
|
||||||
-- clicker:set_attach(self.object, "", self.attach_offset, {x=0,y=0,z=0})
|
|
||||||
-- clicker:set_eye_offset(self.view_offset, self.view_offset)
|
|
||||||
-- end
|
|
||||||
--end
|
|
||||||
|
|
||||||
--custom on_step function
|
--custom on_step function
|
||||||
if self.custom_on_step then
|
if self.custom_on_step then
|
||||||
self:custom_on_step(self, dtime)
|
self:custom_on_step(self, dtime)
|
||||||
|
@ -444,6 +450,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
function wagon:reattach_all()
|
function wagon:reattach_all()
|
||||||
|
if not self.seatp then self.seatp={} end
|
||||||
for seatno, pname in pairs(self.seatp) do
|
for seatno, pname in pairs(self.seatp) do
|
||||||
local p=minetest.get_player_by_name(pname)
|
local p=minetest.get_player_by_name(pname)
|
||||||
if p then
|
if p then
|
||||||
|
@ -473,6 +480,17 @@ function advtrains.register_wagon(sysname, traintype, prototype, desc, inv_img)
|
||||||
if not pointed_thing.type == "node" then
|
if not pointed_thing.type == "node" then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local node=minetest.env:get_node_or_nil(pointed_thing.under)
|
||||||
|
if not node then print("[advtrains]Ignore at placer position") return itemstack end
|
||||||
|
local nodename=node.name
|
||||||
|
if(not advtrains.is_track_and_drives_on(nodename, advtrains.all_traintypes[traintype].drives_on)) then
|
||||||
|
print("[advtrains]no track here, not placing.")
|
||||||
|
return itemstack
|
||||||
|
end
|
||||||
|
local conn1=advtrains.get_track_connections(node.name, node.param2)
|
||||||
|
local id=advtrains.create_new_train_at(pointed_thing.under, advtrains.dirCoordSet(pointed_thing.under, conn1), traintype)
|
||||||
|
|
||||||
local ob=minetest.env:add_entity(pointed_thing.under, "advtrains:"..sysname)
|
local ob=minetest.env:add_entity(pointed_thing.under, "advtrains:"..sysname)
|
||||||
if not ob then
|
if not ob then
|
||||||
print("[advtrains]couldn't add_entity, aborting")
|
print("[advtrains]couldn't add_entity, aborting")
|
||||||
|
@ -482,15 +500,8 @@ function advtrains.register_wagon(sysname, traintype, prototype, desc, inv_img)
|
||||||
le.owner=placer:get_player_name()
|
le.owner=placer:get_player_name()
|
||||||
le.infotext=desc..", owned by "..placer:get_player_name()
|
le.infotext=desc..", owned by "..placer:get_player_name()
|
||||||
|
|
||||||
local node=minetest.env:get_node_or_nil(pointed_thing.under)
|
local wagon_uid=le:init_new_instance(id, {})
|
||||||
if not node then print("[advtrains]Ignore at placer position") return itemstack end
|
|
||||||
local nodename=node.name
|
|
||||||
if(not advtrains.is_track_and_drives_on(nodename, advtrains.all_traintypes[traintype].drives_on)) then
|
|
||||||
print("[advtrains]no trck here, not placing.")
|
|
||||||
return itemstack
|
|
||||||
end
|
|
||||||
local conn1=advtrains.get_track_connections(node.name, node.param2)
|
|
||||||
local id=advtrains.create_new_train_at(pointed_thing.under, advtrains.dirCoordSet(pointed_thing.under, conn1), traintype)
|
|
||||||
advtrains.add_wagon_to_train(le, id)
|
advtrains.add_wagon_to_train(le, id)
|
||||||
if not minetest.setting_getbool("creative_mode") then
|
if not minetest.setting_getbool("creative_mode") then
|
||||||
itemstack:take_item()
|
itemstack:take_item()
|
||||||
|
|
Loading…
Reference in New Issue