2016-05-29 11:27:30 -07:00
--atan2 counts angles clockwise, minetest does counterclockwise
2016-11-03 13:21:28 -07:00
--local print=function(t) minetest.log("action", t) minetest.chat_send_all(t) end
local print = function ( ) end
2016-05-29 11:27:30 -07:00
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
2016-11-03 03:27:17 -07:00
has_inventory = false ,
2016-05-29 11:27:30 -07:00
}
function wagon : on_rightclick ( clicker )
2016-11-03 03:27:17 -07:00
if not self : ensure_init ( ) then return end
2016-05-29 11:27:30 -07:00
if not clicker or not clicker : is_player ( ) then
return
end
if clicker : get_player_control ( ) . aux1 then
--advtrains.dumppath(self:train().path)
--minetest.chat_send_all("at index "..(self:train().index or "nil"))
--advtrains.invert_train(self.train_id)
minetest.chat_send_all ( dump ( self : train ( ) ) )
return
end
2016-10-22 11:30:10 -07:00
local no = self : get_seatno ( clicker : get_player_name ( ) )
if no then
self : get_off ( no )
else
self : show_get_on_form ( clicker : get_player_name ( ) )
2016-05-29 11:27:30 -07:00
end
end
function wagon : train ( )
return advtrains.trains [ self.train_id ]
end
2016-11-02 03:17:42 -07:00
--[[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 )
print ( " [advtrains][wagon " .. ( ( sd_uid and sd_uid ~= " " and sd_uid ) or " no-id " ) .. " ] activated " )
2016-05-29 11:27:30 -07:00
self.object : set_armor_groups ( { immortal = 1 } )
2016-11-02 03:17:42 -07:00
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 )
2016-05-29 11:27:30 -07:00
end
end
2016-05-30 10:58:09 -07:00
self.entity_name = self.name
2016-05-29 11:27:30 -07:00
2016-11-02 03:17:42 -07:00
--duplicates?
2016-11-03 03:27:17 -07:00
for ao_id , wagon in pairs ( minetest.luaentities ) do
2016-11-02 03:17:42 -07:00
if wagon.is_wagon and wagon.initialized and wagon.unique_id == self.unique_id and wagon ~= self then --i am a duplicate!
2016-11-03 03:27:17 -07:00
print ( " [advtrains][wagon " .. ( ( sd_uid and sd_uid ~= " " and sd_uid ) or " no-id " ) .. " ] duplicate found(ao_id: " .. ao_id .. " ), removing " )
2016-05-29 11:27:30 -07:00
self.object : remove ( )
2016-11-03 03:27:17 -07:00
minetest.after ( 0.5 , function ( ) advtrains.update_trainpart_properties ( self.train_id ) end )
2016-05-29 11:27:30 -07:00
return
end
end
2016-10-26 06:30:27 -07:00
if self.custom_on_activate then
self : custom_on_activate ( staticdata_table , dtime_s )
end
2016-05-29 11:27:30 -07:00
end
function wagon : get_staticdata ( )
2016-11-02 03:17:42 -07:00
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 " )
2016-11-03 03:27:17 -07:00
--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
2016-05-29 12:33:09 -07:00
--save to table before being unloaded
advtrains.wagon_save [ self.unique_id ] = advtrains.merge_tables ( self )
2016-11-02 03:17:42 -07:00
advtrains.wagon_save [ self.unique_id ] . entity_name = self.name
advtrains.wagon_save [ self.unique_id ] . name = nil
advtrains.wagon_save [ self.unique_id ] . object = nil
return self.unique_id
end
--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
2016-11-03 03:27:17 -07:00
self : init_shared ( )
2016-11-02 03:17:42 -07:00
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
2016-11-03 03:27:17 -07:00
self : init_shared ( )
2016-11-02 03:17:42 -07:00
self.initialized = true
2016-11-03 01:03:23 -07:00
minetest.after ( 1 , function ( ) self : reattach_all ( ) end )
2016-11-02 03:17:42 -07:00
print ( " init_from_wagon_save " .. self.unique_id .. " ( " .. self.train_id .. " ) " )
advtrains.update_trainpart_properties ( self.train_id )
end
2016-11-03 03:27:17 -07:00
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
end
2016-11-02 03:17:42 -07:00
function wagon : ensure_init ( )
if self.initialized then return true end
self.object : setvelocity ( { x = 0 , y = 0 , z = 0 } )
return false
2016-05-29 11:27:30 -07:00
end
-- Remove the wagon
function wagon : on_punch ( puncher , time_from_last_punch , tool_capabilities , direction )
2016-11-02 03:17:42 -07:00
if not self : ensure_init ( ) then return end
2016-09-28 14:27:47 -07:00
if not puncher or not puncher : is_player ( ) then
2016-05-29 11:27:30 -07:00
return
end
2016-09-28 23:20:06 -07:00
if self.owner and puncher : get_player_name ( ) ~= self.owner then
minetest.chat_send_player ( puncher : get_player_name ( ) , " This wagon is owned by " .. self.owner .. " , you can't destroy it. " )
return
end
2016-09-28 14:27:47 -07:00
if minetest.setting_getbool ( " creative_mode " ) then
2016-10-22 11:30:10 -07:00
if not self : destroy ( ) then return end
2016-09-28 14:27:47 -07:00
local inv = puncher : get_inventory ( )
if not inv : contains_item ( " main " , self.name ) then
inv : add_item ( " main " , self.name )
end
else
local pc = puncher : get_player_control ( )
if not pc.sneak then
minetest.chat_send_player ( puncher : get_player_name ( ) , " Warning: If you destroy this wagon, you only get some steel back! If you are sure, shift-leftclick the wagon. " )
return
end
2016-05-29 11:27:30 -07:00
2016-10-22 11:30:10 -07:00
if not self : destroy ( ) then return end
2016-09-28 14:27:47 -07:00
local inv = puncher : get_inventory ( )
for _ , item in ipairs ( self.drops or { self.name } ) do
inv : add_item ( " main " , item )
end
end
end
function wagon : destroy ( )
--some rules:
-- you get only some items back
-- single left-click shows warning
-- shift leftclick destroys
-- not when a driver is inside
2016-10-22 11:30:10 -07:00
for _ , _ in pairs ( self.seatp ) do
return
end
2016-09-28 14:27:47 -07:00
2016-09-28 14:12:01 -07:00
if self.custom_may_destroy then
if not self.custom_may_destroy ( self , puncher , time_from_last_punch , tool_capabilities , direction ) then
return
end
end
if self.custom_on_destroy then
self.custom_on_destroy ( self , puncher , time_from_last_punch , tool_capabilities , direction )
end
2016-09-28 14:27:47 -07:00
2016-11-02 03:17:42 -07:00
print ( " [advtrains][wagon " .. ( ( self.unique_id and self.unique_id ~= " " and self.unique_id ) or " no-id " ) .. " ]: destroying " )
2016-09-28 14:12:01 -07:00
self.object : remove ( )
2016-05-29 11:27:30 -07:00
2016-09-28 14:12:01 -07:00
table.remove ( self : train ( ) . trainparts , self.pos_in_trainparts )
advtrains.update_trainpart_properties ( self.train_id )
advtrains.wagon_save [ self.unique_id ] = nil
if self.discouple then self.discouple . object : remove ( ) end --will have no effect on unloaded objects
2016-10-22 11:30:10 -07:00
return true
2016-05-29 11:27:30 -07:00
end
2016-09-28 14:12:01 -07:00
2016-05-29 11:27:30 -07:00
function wagon : on_step ( dtime )
2016-11-02 03:17:42 -07:00
if not self : ensure_init ( ) then return end
2016-06-02 05:42:01 -07:00
local t = os.clock ( )
2016-05-29 11:27:30 -07:00
local pos = self.object : getpos ( )
2016-10-29 12:08:26 -07:00
if not pos then
print ( " [ " .. self.unique_id .. " ][fatal] missing position (object:getpos() returned nil) " )
return
end
2016-09-28 14:12:01 -07:00
2016-05-30 10:58:09 -07:00
self.entity_name = self.name
2016-11-02 03:17:42 -07:00
2016-05-29 11:27:30 -07:00
--is my train still here
if not self.train_id or not self : train ( ) then
2016-05-30 10:58:09 -07:00
print ( " [advtrains][wagon " .. self.unique_id .. " ] missing train_id, destroying " )
self.object : remove ( )
2016-05-29 11:27:30 -07:00
return
elseif not self.initialized then
self.initialized = true
end
2016-10-26 06:44:35 -07:00
if not self.seatp then
self.seatp = { }
end
2016-09-28 14:12:01 -07:00
--custom on_step function
if self.custom_on_step then
2016-10-26 06:30:27 -07:00
self : custom_on_step ( self , dtime )
2016-09-28 14:12:01 -07:00
end
2016-05-29 11:27:30 -07:00
--driver control
2016-10-22 11:30:10 -07:00
for seatno , seat in ipairs ( self.seats ) do
if seat.driving_ctrl_access then
local driver = self.seatp [ seatno ] and minetest.get_player_by_name ( self.seatp [ seatno ] )
2016-11-25 13:35:57 -08:00
local get_off_pressed = false
2016-10-22 11:30:10 -07:00
if driver and driver : get_player_control_bits ( ) ~= self.old_player_control_bits then
local pc = driver : get_player_control ( )
2016-11-24 11:25:07 -08:00
advtrains.on_control_change ( pc , self : train ( ) , self.wagon_flipped )
2016-11-24 11:56:23 -08:00
if pc.aux1 and pc.sneak then
2016-11-25 13:35:57 -08:00
get_off_pressed = true
2016-11-24 11:56:23 -08:00
end
2016-11-24 11:25:07 -08:00
2016-10-22 11:30:10 -07:00
self.old_player_control_bits = driver : get_player_control_bits ( )
end
if driver then
2016-11-25 13:35:57 -08:00
if get_off_pressed then
self : get_off ( seatno )
else
advtrains.update_driver_hud ( driver : get_player_name ( ) , self : train ( ) , self.wagon_flipped )
end
2016-05-29 11:27:30 -07:00
end
end
end
2016-09-28 14:12:01 -07:00
2016-05-29 11:27:30 -07:00
local gp = self : train ( )
2016-09-28 14:12:01 -07:00
2016-06-09 12:50:11 -07:00
--DisCouple
if self.pos_in_trainparts and self.pos_in_trainparts > 1 then
if gp.velocity == 0 then
2016-06-09 13:16:24 -07:00
if not self.discouple or not self.discouple . object : getyaw ( ) then
2016-06-09 12:50:11 -07:00
local object = minetest.add_entity ( pos , " advtrains:discouple " )
if object then
local le = object : get_luaentity ( )
le.wagon = self
--box is hidden when attached, so unuseful.
--object:set_attach(self.object, "", {x=0, y=0, z=self.wagon_span*10}, {x=0, y=0, z=0})
2016-06-09 13:16:24 -07:00
self.discouple = le
2016-06-09 12:50:11 -07:00
else
print ( " Couldn't spawn DisCouple " )
end
end
else
2016-06-09 13:16:24 -07:00
if self.discouple and self.discouple . object : getyaw ( ) then
self.discouple . object : remove ( )
2016-06-09 12:50:11 -07:00
end
end
end
2016-05-29 11:27:30 -07:00
--for path to be available. if not, skip step
if not advtrains.get_or_create_path ( self.train_id , gp ) then
self.object : setvelocity ( { x = 0 , y = 0 , z = 0 } )
return
end
2016-10-29 12:08:26 -07:00
if not self.pos_in_train then
2016-11-24 11:25:07 -08:00
--why ever. but better continue next step...
advtrains.update_trainpart_properties ( self.train_id )
2016-10-29 12:08:26 -07:00
return
end
2016-05-29 11:27:30 -07:00
2016-06-02 05:42:01 -07:00
local index = advtrains.get_real_path_index ( self : train ( ) , self.pos_in_train )
2016-05-29 11:27:30 -07:00
--print("trainindex "..gp.index.." wagonindex "..index)
--position recalculation
local first_pos = gp.path [ math.floor ( index ) ]
local second_pos = gp.path [ math.floor ( index ) + 1 ]
if not first_pos or not second_pos then
--print("[advtrains] object "..self.unique_id.." path end reached!")
self.object : setvelocity ( { x = 0 , y = 0 , z = 0 } )
return
end
--checking for environment collisions(a 3x3 cube around the center)
if not gp.recently_collided_with_env then
local collides = false
for x =- 1 , 1 do
for y = 0 , 2 do
for z =- 1 , 1 do
local node = minetest.get_node_or_nil ( vector.add ( first_pos , { x = x , y = y , z = z } ) )
2016-08-28 11:59:54 -07:00
if ( advtrains.train_collides ( node ) ) then
2016-05-29 11:27:30 -07:00
collides = true
end
end
end
end
if collides then
gp.recently_collided_with_env = true
gp.velocity =- 0.5 * gp.velocity
gp.tarvelocity = 0
end
end
2016-09-28 23:31:57 -07:00
--FIX: use index of the wagon, not of the train.
2016-11-24 11:25:07 -08:00
local velocity = ( gp.velocity * gp.movedir ) / ( gp.path_dist [ math.floor ( index ) ] or 1 )
2016-09-28 23:41:05 -07:00
local acceleration = ( gp.last_accel or 0 ) / ( gp.path_dist [ math.floor ( index ) ] or 1 )
2016-05-29 11:27:30 -07:00
local factor = index - math.floor ( index )
local actual_pos = { x = first_pos.x - ( first_pos.x - second_pos.x ) * factor , y = first_pos.y - ( first_pos.y - second_pos.y ) * factor , z = first_pos.z - ( first_pos.z - second_pos.z ) * factor , }
local velocityvec = { x = ( first_pos.x - second_pos.x ) * velocity *- 1 , z = ( first_pos.z - second_pos.z ) * velocity *- 1 , y = ( first_pos.y - second_pos.y ) * velocity *- 1 }
2016-09-28 23:41:05 -07:00
local accelerationvec = { x = ( first_pos.x - second_pos.x ) * acceleration *- 1 , z = ( first_pos.z - second_pos.z ) * acceleration *- 1 , y = ( first_pos.y - second_pos.y ) * acceleration *- 1 }
2016-05-29 11:27:30 -07:00
--some additional positions to determine orientation
local aposfwd = gp.path [ math.floor ( index + 2 ) ]
local aposbwd = gp.path [ math.floor ( index - 1 ) ]
local yaw
if aposfwd and aposbwd then
yaw = advtrains.get_wagon_yaw ( aposfwd , second_pos , first_pos , aposbwd , factor ) + math.pi --TODO remove when cleaning up
else
yaw = math.atan2 ( ( first_pos.x - second_pos.x ) , ( second_pos.z - first_pos.z ) )
end
if self.wagon_flipped then
yaw = yaw + math.pi
end
self.updatepct_timer = ( self.updatepct_timer or 0 ) - dtime
2016-09-28 23:41:05 -07:00
if not self.old_velocity_vector
or not vector.equals ( velocityvec , self.old_velocity_vector )
or not self.old_acceleration_vector
or not vector.equals ( accelerationvec , self.old_acceleration_vector )
or self.old_yaw ~= yaw
or self.updatepct_timer <= 0 then --only send update packet if something changed
self.object : setpos ( actual_pos )
2016-05-29 11:27:30 -07:00
self.object : setvelocity ( velocityvec )
2016-09-28 23:41:05 -07:00
self.object : setacceleration ( accelerationvec )
2016-05-29 11:27:30 -07:00
self.object : setyaw ( yaw )
self.updatepct_timer = 2
2016-06-09 08:35:06 -07:00
if self.update_animation then
self : update_animation ( gp.velocity )
end
2016-05-29 11:27:30 -07:00
end
2016-10-22 11:30:10 -07:00
2016-05-29 11:27:30 -07:00
self.old_velocity_vector = velocityvec
2016-09-28 23:41:05 -07:00
self.old_acceleration_vector = accelerationvec
2016-05-29 11:27:30 -07:00
self.old_yaw = yaw
2016-06-02 05:42:01 -07:00
printbm ( " wagon step " , t )
end
function advtrains . get_real_path_index ( train , pit )
local pos_in_train_left = pit
local index = train.index
if pos_in_train_left > ( index - math.floor ( index ) ) * ( train.path_dist [ math.floor ( index ) ] or 1 ) then
pos_in_train_left = pos_in_train_left - ( index - math.floor ( index ) ) * ( train.path_dist [ math.floor ( index ) ] or 1 )
index = math.floor ( index )
while pos_in_train_left > ( train.path_dist [ index - 1 ] or 1 ) do
pos_in_train_left = pos_in_train_left - ( train.path_dist [ index - 1 ] or 1 )
index = index - 1
end
index = index - ( pos_in_train_left / ( train.path_dist [ index - 1 ] or 1 ) )
else
2016-08-21 07:49:48 -07:00
index = index - ( pos_in_train_left / ( train.path_dist [ math.floor ( index - 1 ) ] or 1 ) )
2016-06-02 05:42:01 -07:00
end
return index
2016-05-29 11:27:30 -07:00
end
2016-10-22 11:30:10 -07:00
function wagon : get_on ( clicker , seatno )
if not self.seatp then
self.seatp = { }
end
if not self.seats [ seatno ] then return end
2016-11-24 11:25:07 -08:00
if self.seatp [ seatno ] and self.seatp [ seatno ] ~= clicker : get_player_name ( ) then
2016-10-22 11:30:10 -07:00
self : get_off ( seatno )
end
self.seatp [ seatno ] = clicker : get_player_name ( )
2016-12-05 11:53:43 -08:00
advtrains.player_to_train_mapping [ clicker : get_player_name ( ) ] = self.train_id
2016-10-22 11:30:10 -07:00
clicker : set_attach ( self.object , " " , self.seats [ seatno ] . attach_offset , { x = 0 , y = 0 , z = 0 } )
clicker : set_eye_offset ( self.seats [ seatno ] . view_offset , self.seats [ seatno ] . view_offset )
end
function wagon : get_off_plr ( pname )
local no = self : get_seatno ( pname )
if no then
self : get_off ( no )
end
end
function wagon : get_seatno ( pname )
2016-12-04 14:18:28 -08:00
for no , cont in pairs ( self.seatp ) do
2016-10-22 11:30:10 -07:00
if cont == pname then
return no
end
end
return nil
end
function wagon : get_off ( seatno )
if not self.seatp [ seatno ] then return end
local pname = self.seatp [ seatno ]
local clicker = minetest.get_player_by_name ( pname )
2016-12-05 11:53:43 -08:00
advtrains.player_to_train_mapping [ pname ] = nil
2016-11-24 11:25:07 -08:00
advtrains.clear_driver_hud ( pname )
2016-10-22 11:30:10 -07:00
if clicker then
clicker : set_detach ( )
clicker : set_eye_offset ( { x = 0 , y = 0 , z = 0 } , { x = 0 , y = 0 , z = 0 } )
2016-11-24 12:52:17 -08:00
local objpos = advtrains.round_vector_floor_y ( self.object : getpos ( ) )
local yaw = self.object : getyaw ( )
local isx = ( yaw < math.pi / 4 ) or ( yaw > 3 * math.pi / 4 and yaw < 5 * math.pi / 4 ) or ( yaw > 7 * math.pi / 4 )
--abuse helper function
for _ , r in ipairs ( { - 1 , 1 } ) do
local p = vector.add ( { x = isx and r or 0 , y = 0 , z = not isx and r or 0 } , objpos )
if minetest.get_item_group ( minetest.get_node ( p ) . name , " platform " ) > 0 then
minetest.after ( 0.2 , function ( ) clicker : setpos ( { x = p.x , y = p.y + 1 , z = p.z } ) end )
end
end
2016-10-22 11:30:10 -07:00
end
self.seatp [ seatno ] = nil
end
function wagon : show_get_on_form ( pname )
if not self.initialized then return end
2016-11-03 03:27:17 -07:00
if # self.seats == 0 then
if self.has_inventory and self.get_inventory_formspec then
minetest.show_formspec ( pname , " advtrains_inv_ " .. self.unique_id , self : get_inventory_formspec ( ) )
end
return
end
local form , comma = " size[5,8]label[0.5,0.5;Select seat:]textlist[0.5,1;4,6;seat; " , " "
2016-10-22 11:30:10 -07:00
for seatno , seattbl in ipairs ( self.seats ) do
local addtext , colorcode = " " , " "
if self.seatp and self.seatp [ seatno ] then
colorcode = " #FF0000 "
addtext = " ( " .. self.seatp [ seatno ] .. " ) "
end
form = form .. comma .. colorcode .. seattbl.name .. addtext
comma = " , "
end
2016-11-03 03:27:17 -07:00
form = form .. " ;0,false] "
if self.has_inventory and self.get_inventory_formspec then
form = form .. " button_exit[1,7;3,1;inv;Show Inventory] "
end
minetest.show_formspec ( pname , " advtrains_geton_ " .. self.unique_id , form )
2016-10-22 11:30:10 -07:00
end
minetest.register_on_player_receive_fields ( function ( player , formname , fields )
local uid = string.match ( formname , " ^advtrains_geton_(.+)$ " )
2016-11-03 03:27:17 -07:00
if uid then
for _ , wagon in pairs ( minetest.luaentities ) do
if wagon.is_wagon and wagon.initialized and wagon.unique_id == uid then
if fields.inv then
if wagon.has_inventory and wagon.get_inventory_formspec then
minetest.show_formspec ( player : get_player_name ( ) , " advtrains_inv_ " .. uid , wagon : get_inventory_formspec ( ) )
end
elseif fields.seat then
local val = minetest.explode_textlist_event ( fields.seat )
2016-12-22 09:55:10 -08:00
if val and val.type ~= " INV " and not wagon.seatp [ player : get_player_name ( ) ] then
2016-11-03 03:27:17 -07:00
--get on
wagon : get_on ( player , val.index )
2016-11-23 10:28:39 -08:00
--will work with the new close_formspec functionality. close exactly this formspec.
minetest.show_formspec ( player : get_player_name ( ) , formname , " " )
2016-11-03 03:27:17 -07:00
end
2016-10-22 11:30:10 -07:00
end
end
end
end
end )
function wagon : reattach_all ( )
2016-11-02 03:17:42 -07:00
if not self.seatp then self.seatp = { } end
2016-10-22 11:30:10 -07:00
for seatno , pname in pairs ( self.seatp ) do
local p = minetest.get_player_by_name ( pname )
if p then
self : get_on ( p , seatno )
end
end
end
minetest.register_on_joinplayer ( function ( player )
for _ , wagon in pairs ( minetest.luaentities ) do
if wagon.is_wagon and wagon.initialized then
wagon : reattach_all ( )
end
end
end )
2016-05-29 11:27:30 -07:00
2016-12-22 09:55:10 -08:00
function advtrains . register_wagon ( sysname , prototype , desc , inv_img )
2016-05-29 11:27:30 -07:00
setmetatable ( prototype , { __index = wagon } )
2016-12-20 05:17:39 -08:00
minetest.register_entity ( " :advtrains: " .. sysname , prototype )
2016-05-29 11:27:30 -07:00
2016-12-20 05:17:39 -08:00
minetest.register_craftitem ( " :advtrains: " .. sysname , {
2016-08-28 12:58:13 -07:00
description = desc ,
inventory_image = inv_img ,
wield_image = inv_img ,
2016-05-29 11:27:30 -07:00
stack_max = 1 ,
on_place = function ( itemstack , placer , pointed_thing )
if not pointed_thing.type == " node " then
return
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
2016-12-22 09:55:10 -08:00
if ( not advtrains.is_track_and_drives_on ( nodename , prototype.drives_on ) ) then
2016-11-02 03:17:42 -07:00
print ( " [advtrains]no track here, not placing. " )
2016-05-29 11:27:30 -07:00
return itemstack
end
local conn1 = advtrains.get_track_connections ( node.name , node.param2 )
2016-12-22 09:55:10 -08:00
local id = advtrains.create_new_train_at ( pointed_thing.under , advtrains.dirCoordSet ( pointed_thing.under , conn1 ) )
2016-11-02 03:17:42 -07:00
local ob = minetest.env : add_entity ( pointed_thing.under , " advtrains: " .. sysname )
if not ob then
print ( " [advtrains]couldn't add_entity, aborting " )
end
local le = ob : get_luaentity ( )
le.owner = placer : get_player_name ( )
le.infotext = desc .. " , owned by " .. placer : get_player_name ( )
local wagon_uid = le : init_new_instance ( id , { } )
2016-05-29 11:27:30 -07:00
advtrains.add_wagon_to_train ( le , id )
if not minetest.setting_getbool ( " creative_mode " ) then
itemstack : take_item ( )
end
return itemstack
end ,
} )
end
2016-06-09 08:35:06 -07:00
--[[
wagons can define update_animation ( self , velocity ) if they have a speed - dependent animation
this function will be called when the velocity vector changes or every 2 seconds .
] ]
2016-05-29 11:27:30 -07:00
2016-10-06 00:56:40 -07:00