2015-06-29 20:55:56 +03:00
--
-- Helper functions
--
2015-07-03 07:57:09 +03:00
local init = os.clock ( )
2015-06-29 20:55:56 +03:00
local function is_water ( pos )
local nn = minetest.get_node ( pos ) . name
return minetest.get_item_group ( nn , " water " ) ~= 0
end
local function get_velocity ( v , yaw , y )
local x = - math.sin ( yaw ) * v
local z = math.cos ( yaw ) * v
return { x = x , y = y , z = z }
end
--
-- boat entity
--
local boat = {
physical = true ,
collisionbox = { - 1 , - 0.5 , - 1 , 1 , 0.5 , 1 } ,
visual = " mesh " ,
2017-01-16 20:49:45 +03:00
mesh = " mcl_boats_base.x " ,
2017-01-16 20:47:04 +03:00
_driver = nil ,
_v = 0 ,
_stepcount = 0 ,
_unattended = 0
2015-06-29 20:55:56 +03:00
}
function boat . on_rightclick ( self , clicker )
if not clicker or not clicker : is_player ( ) then
return
end
2017-01-16 20:47:04 +03:00
if self._driver and clicker == self._driver then
self._driver = nil
2015-06-29 20:55:56 +03:00
clicker : set_detach ( )
2017-01-16 20:47:04 +03:00
elseif not self._driver then
self._driver = clicker
2015-06-29 20:55:56 +03:00
clicker : set_attach ( self.object , " " , { x = 0 , y = 5 , z = 0 } , { x = 0 , y = 0 , z = 0 } )
self.object : setyaw ( clicker : get_look_yaw ( ) )
end
end
function boat . on_activate ( self , staticdata , dtime_s )
self.object : set_armor_groups ( { immortal = 1 } )
if staticdata then
2017-01-16 20:47:04 +03:00
self._v = tonumber ( staticdata )
2015-06-29 20:55:56 +03:00
end
end
2017-02-28 04:19:35 +03:00
function boat . get_staticdata ( self )
return tostring ( self._v )
2015-06-29 20:55:56 +03:00
end
function boat . on_punch ( self , puncher , time_from_last_punch , tool_capabilities , direction )
2017-01-16 20:47:04 +03:00
if self._driver then
self._driver : set_detach ( )
self._driver = nil
2017-02-28 04:22:22 +03:00
if puncher and puncher : is_player ( ) and ( not minetest.setting_getbool ( " creative_mode " ) ) then
2017-01-16 20:49:45 +03:00
puncher : get_inventory ( ) : add_item ( " main " , " mcl_boats:boat " )
2015-06-29 20:55:56 +03:00
end
2017-01-16 20:56:40 +03:00
self.object : remove ( )
2015-06-29 20:55:56 +03:00
else
2017-02-28 04:22:22 +03:00
if puncher and puncher : is_player ( ) and ( not minetest.setting_getbool ( " creative_mode " ) ) then
2017-01-16 20:49:45 +03:00
puncher : get_inventory ( ) : add_item ( " main " , " mcl_boats:boat " )
2015-06-29 20:55:56 +03:00
end
2017-01-16 20:56:40 +03:00
self.object : remove ( )
2015-06-29 20:55:56 +03:00
end
end
function boat . on_step ( self , dtime )
2017-01-16 20:47:04 +03:00
self._stepcount = self._stepcount + 1
if self._stepcount > 9 then
2015-06-29 20:55:56 +03:00
2017-01-16 20:47:04 +03:00
self._stepcount = 0
2015-06-29 20:55:56 +03:00
2017-01-16 20:47:04 +03:00
if self._driver then
local ctrl = self._driver : get_player_control ( )
2015-06-29 20:55:56 +03:00
2017-01-16 20:47:04 +03:00
self._unattended = 0
2015-06-29 20:55:56 +03:00
local yaw = self.object : getyaw ( )
2017-01-16 20:47:04 +03:00
if ctrl.up and self._v < 3 then
self._v = self._v + 1
2015-06-29 20:55:56 +03:00
end
2017-01-16 20:47:04 +03:00
if ctrl.down and self._v >=- 1 then
self._v = self._v - 1
2015-06-29 20:55:56 +03:00
end
if ctrl.left then
if ctrl.down then
self.object : setyaw ( yaw - math.pi / 12 - dtime * math.pi / 12 )
else
self.object : setyaw ( yaw + math.pi / 12 + dtime * math.pi / 12 )
end
end
if ctrl.right then
if ctrl.down then
self.object : setyaw ( yaw + math.pi / 12 + dtime * math.pi / 12 )
else
self.object : setyaw ( yaw - math.pi / 12 - dtime * math.pi / 12 )
end
end
end
2017-01-16 20:47:04 +03:00
local tmp_velocity = get_velocity ( self._v , self.object : getyaw ( ) , 0 )
2015-06-29 20:55:56 +03:00
local tmp_pos = self.object : getpos ( )
tmp_velocity.y = 0
if is_water ( tmp_pos ) then
tmp_velocity.y = 2
end
tmp_pos.y = tmp_pos.y - 0.5
if minetest.get_node ( tmp_pos ) . name == " air " then
tmp_velocity.y =- 2
end
self.object : setvelocity ( tmp_velocity )
end
end
2017-01-16 21:10:18 +03:00
local woods = { " " , " _spruce " , " _birch " , " _jungle " , " _dark " , " _acacia " }
local names = { " Oak Boat " , " Spruce Boat " , " Birch Boat " , " Jungle Boat " , " Dark Oak Boat " , " Acacia Boat " }
2017-02-01 01:32:56 +03:00
local craftstuffs = { " mcl_core:wood " , " mcl_core:sprucewood " , " mcl_core:birchwood " , " mcl_core:junglewood " , " mcl_core:darkwood " , " mcl_core:acaciawood " }
2017-02-06 19:58:26 +03:00
local images = { " oak " , " spruce " , " birch " , " jungle " , " dark_oak " , " acacia " }
2015-06-29 20:55:56 +03:00
2017-01-16 21:10:18 +03:00
for w = 1 , # woods do
2017-01-24 04:31:49 +03:00
local textures = { " mcl_boats_texture.png " }
2017-01-16 21:10:18 +03:00
minetest.register_entity ( " mcl_boats:boat " .. woods [ w ] , boat )
2015-06-29 20:55:56 +03:00
2017-01-16 21:10:18 +03:00
minetest.register_craftitem ( " mcl_boats:boat " .. woods [ w ] , {
description = names [ w ] ,
2017-03-18 19:52:41 +03:00
_doc_items_longdesc = " Boats are used to travel on the surface of water. " ,
_doc_items_usagehelp = " Rightclick on a water source to place the boat. Rightclick the boat to enter it. Use [Left] and [Right] to steer, [Forwards] to speed up and [Backwards] to slow down or move backwards. Rightclick the boat again to leave it, punch the boat to collect it. " ,
2017-02-06 19:58:26 +03:00
inventory_image = " mcl_boats_ " .. images [ w ] .. " _boat.png " ,
2017-01-16 21:10:18 +03:00
liquids_pointable = true ,
2017-01-20 06:54:09 +03:00
groups = { boat = 1 , transport = 1 } ,
2017-01-17 01:34:40 +03:00
stack_max = 1 ,
2017-01-16 21:10:18 +03:00
on_place = function ( itemstack , placer , pointed_thing )
if pointed_thing.type ~= " node " then
return
end
2017-03-02 17:44:31 +03:00
-- Call on_rightclick if the pointed node defines it
local node = minetest.get_node ( pointed_thing.under )
if placer and not placer : get_player_control ( ) . sneak then
if minetest.registered_nodes [ node.name ] and minetest.registered_nodes [ node.name ] . on_rightclick then
return minetest.registered_nodes [ node.name ] . on_rightclick ( pointed_thing.under , node , placer , itemstack ) or itemstack
end
end
2017-01-16 21:10:18 +03:00
if not is_water ( pointed_thing.under ) then
return
end
pointed_thing.under . y = pointed_thing.under . y + 0.5
minetest.add_entity ( pointed_thing.under , " mcl_boats:boat " .. woods [ w ] )
if not minetest.setting_getbool ( " creative_mode " ) then
itemstack : take_item ( )
end
return itemstack
end ,
} )
local c = craftstuffs [ w ]
minetest.register_craft ( {
2017-01-17 01:49:09 +03:00
output = " mcl_boats:boat " .. woods [ w ] ,
2017-01-16 21:10:18 +03:00
recipe = {
{ c , " " , c } ,
{ c , c , c } ,
} ,
} )
end
2015-06-29 20:55:56 +03:00
2017-01-10 08:43:07 +03:00
minetest.register_craft ( {
type = " fuel " ,
recipe = " group:boat " ,
burntime = 20 ,
} )
2015-07-03 07:57:09 +03:00
local time_to_load = os.clock ( ) - init
print ( string.format ( " [MOD] " .. minetest.get_current_modname ( ) .. " loaded in %.4f s " , time_to_load ) )