--atan2 counts angles clockwise, minetest does counterclockwise
minetest.register_privilege("train_place", {
description = "Player can place trains on tracks not owned by player",
give_to_singleplayer= false,
});
minetest.register_privilege("train_remove", {
description = "Player can remove trains not owned by player",
give_to_singleplayer= false,
});
minetest.register_privilege("train_operator", {
description = "Player may operate trains and switch signals. Given by default. Revoke to prevent players from griefing automated subway systems.",
give_to_singleplayer= true,
default= true,
});
local wagon={
collisionbox = {-0.5,-0.5,-0.5, 0.5,0.5,0.5},
--physical = true,
visual = "mesh",
mesh = "wagon.b3d",
visual_size = {x=3, y=3},
textures = {"black.png"},
is_wagon=true,
wagon_span=1,--how many index units of space does this wagon consume
has_inventory=false,
static_save=false,
}
function wagon:train()
return advtrains.trains[self.train_id]
end
--[[about 'initalized':
when initialized is false, the entity hasn't got any data yet and should wait for these to be set before doing anything
when loading an existing object (with staticdata), it will be set
when instanciating a new object via add_entity, it is not set at the time on_activate is called.
then, wagon:initialize() will be called
wagon will save only uid in staticdata, no serialized table
]]
function wagon:on_activate(sd_uid, dtime_s)
if sd_uid~="" then
--destroy when loaded from static block.
self.object:remove()
return
end
self.object:set_armor_groups({immortal=1})
self.entity_name=self.name
end
function wagon:get_staticdata()
return advtrains.pcall(function()
if not self:ensure_init() then return end
atprint("[wagon "..((self.unique_id and self.unique_id~="" and self.unique_id) or "no-id").."]: saving to wagon_save")
--serialize inventory, if it has one
if self.has_inventory then
local inv=minetest.get_inventory({type="detached", name="advtrains_wgn_"..self.unique_id})
self.ser_inv=advtrains.serialize_inventory(inv)
end
--save to table before being unloaded
advtrains.wagon_save[self.unique_id]=advtrains.save_keys(self, {
"seatp", "owner", "ser_inv", "wagon_flipped", "train_id",
"dcpl_lock", "seat_access",
})
advtrains.wagon_save[self.unique_id].entity_name=self.name
return self.unique_id
end)
end
--returns: uid of wagon
function wagon:init_new_instance(train_id, properties)
local new_id=advtrains.random_id()
while advtrains.wagon_save[new_id] do new_id=advtrains.random_id() end--ensure uniqueness
self.unique_id=new_id
self.train_id=train_id
for k,v in pairs(properties) do
if k~="name" and k~="object" then
self[k]=v
end
end
self:init_shared()
self.initialized=true
atprint("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:init_shared()
self.initialized=true
minetest.after(0.2, function() self:reattach_all() end)
atprint("init_from_wagon_save "..self.unique_id.." ("..self.train_id..")")
end
function wagon:init_shared()
if self.has_inventory then
local uid_noptr=self.unique_id..""
--to be used later
local inv=minetest.create_detached_inventory("advtrains_wgn_"..self.unique_id, {
allow_move = function(inv, from_list, from_index, to_list, to_index, count, player)
return count
end,
allow_put = function(inv, listname, index, stack, player)
return stack:get_count()
end,
allow_take = function(inv, listname, index, stack, player)
return stack:get_count()
end
})
if self.ser_inv then
advtrains.deserialize_inventory(self.ser_inv, inv)
end
if self.inventory_list_sizes then
for lst, siz in pairs(self.inventory_list_sizes) do
inv:set_size(lst, siz)
end
end
end
if self.doors then
self.door_anim_timer=0
self.door_state=0
end
if self.custom_on_activate then
self:custom_on_activate(dtime_s)
end
-- reset line and infotext cache to update object properties on first call
self.line_cache=nil
self.infotext_cache=nil
end
function wagon:ensure_init()
if self.initialized then
if self.noninitticks then self.noninitticks=nil end
return true
end
if not self.noninitticks then self.noninitticks=0 end
self.noninitticks=self.noninitticks+1
if self.noninitticks>20 then
self.object:remove()
else
self.object:setvelocity({x=0,y=0,z=0})
end
return false
end
-- Remove the wagon
function wagon:on_punch(puncher, time_from_last_punch, tool_capabilities, direction)
return advtrains.pcall(function()
if not self:ensure_init() then return end
if not puncher or not puncher:is_player() then
return
end
if self.owner and puncher:get_player_name()~=self.owner and (not minetest.check_player_privs(puncher, {train_remove = true })) then
|