3 minetest,vector,math,pairs
5 minetest,vector,math,pairs
19 local function flow(self)
20 pos = self.object:get_pos()
21 pos.y = pos.y + self.object:get_properties().collisionbox[2]
22 pos = vector.round(pos)
23 node = minetest.get_node(pos).name
24 node_above = minetest.get_node(vector.new(pos.x,pos.y+1,pos.z)).name
28 if node == "main:waterflow" then
29 currentvel = self.object:get_velocity()
30 level = minetest.get_node_level(pos)
33 if found == false then
34 nodename = minetest.get_node(vector.new(pos.x+x,pos.y,pos.z+z)).name
35 level2 = minetest.get_node_level(vector.new(pos.x+x,pos.y,pos.z+z))
36 if level2 > level and nodename == "main:waterflow" or nodename == "main:water" then
40 if goalx ~= 0 and goalz ~= 0 then
47 --only add velocity if there is one
48 --else this stops the player
49 if goalx ~= 0 and goalz ~= 0 then
50 acceleration = vector.new(goalx-currentvel.x,0,goalz-currentvel.z)
51 self.object:add_velocity(acceleration)
52 elseif goalx ~= 0 or goalz ~= 0 then
53 acceleration = vector.new(goalx-currentvel.x,0,goalz-currentvel.z)
54 self.object:add_velocity(acceleration)
59 local function lavaflow(self)
60 pos = self.object:get_pos()
61 pos.y = pos.y + self.object:get_properties().collisionbox[2]
62 pos = vector.round(pos)
63 node = minetest.get_node(pos).name
64 node_above = minetest.get_node(vector.new(pos.x,pos.y+1,pos.z)).name
68 if node == "main:lavaflow" then
69 currentvel = self.object:get_velocity()
70 level = minetest.get_node_level(pos)
73 if found == false then
74 nodename = minetest.get_node(vector.new(pos.x+x,pos.y,pos.z+z)).name
75 level2 = minetest.get_node_level(vector.new(pos.x+x,pos.y,pos.z+z))
76 if level2 > level and nodename == "main:lavaflow" or nodename == "main:lava" then
80 if goalx ~= 0 and goalz ~= 0 then
87 --only add velocity if there is one
88 --else this stops the player
89 if goalx ~= 0 and goalz ~= 0 then
90 acceleration = vector.new(goalx-currentvel.x,0,goalz-currentvel.z)
91 self.object:add_velocity(acceleration)
92 elseif goalx ~= 0 or goalz ~= 0 then
93 acceleration = vector.new(goalx-currentvel.x,0,goalz-currentvel.z)
94 self.object:add_velocity(acceleration)
99 --minetest.get_node_level(pos)
100 minetest.register_entity("boat:boat", {
101 initial_properties = {
104 collide_with_objects = false,
105 collisionbox = {-0.4, 0, -0.4, 0.4, 0.5, 0.4},
108 textures = {"boat.png"},
109 visual_size = {x=1,y=1,z=1},
111 automatic_face_movement_dir = -90.0,
112 automatic_face_movement_max_rotation_per_sec = 600,
118 get_staticdata = function(self)
119 return minetest.serialize({
120 --itemstring = self.itemstring,
124 on_activate = function(self, staticdata, dtime_s)
125 if string.sub(staticdata, 1, string.len("return")) == "return" then
126 local data = minetest.deserialize(staticdata)
127 if data and type(data) == "table" then
128 --self.itemstring = data.itemstring
131 --self.itemstring = staticdata
133 self.object:set_armor_groups({immortal = 1})
134 self.object:set_velocity({x = 0, y = 0, z = 0})
135 self.object:set_acceleration({x = 0, y = 0, z = 0})
137 on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, dir)
138 local pos = self.object:get_pos()
139 minetest.add_item(pos, "boat:boat")
144 on_rightclick = function(self,clicker)
145 if not clicker or not clicker:is_player() then
148 local player_name = clicker:get_player_name()
150 if self.rider and player_name == self.rider then
152 local pos = self.object:get_pos()
155 clicker:add_player_velocity(vector.new(0,11,0))
158 player_is_attached(clicker,false)
159 force_update_animation(clicker)
161 elseif not self.rider then
162 self.rider = player_name
163 clicker:set_attach(self.object, "", {x=0, y=2, z=0}, {x=0, y=0, z=0})
165 set_player_animation(clicker,"sit",0)
166 player_is_attached(clicker,true)
169 --check if the boat is stuck on land
170 check_if_on_land = function(self)
171 local pos = self.object:get_pos()
173 local bottom_node = minetest.get_node(pos).name
174 if (bottom_node == "main:water" or bottom_node == "main:waterflow" or bottom_node == "air") then
182 --players drive the baot
183 drive = function(self)
184 if self.rider and not self.on_land == true then
185 local rider = minetest.get_player_by_name(self.rider)
186 local move = rider:get_player_control().up
189 local currentvel = self.object:get_velocity()
190 local goal = rider:get_look_dir()
191 goal = vector.multiply(goal,20)
192 local acceleration = vector.new(goal.x-currentvel.x,0,goal.z-currentvel.z)
193 acceleration = vector.multiply(acceleration, 0.01)
194 self.object:add_velocity(acceleration)
203 push = function(self)
204 local pos = self.object:get_pos()
205 for _,object in ipairs(minetest.get_objects_inside_radius(pos, 1)) do
206 if object:is_player() and object:get_player_name() ~= self.rider then
207 local player_pos = object:get_pos()
211 local currentvel = self.object:get_velocity()
212 local vel = vector.subtract(pos, player_pos)
213 vel = vector.normalize(vel)
214 local distance = vector.distance(pos,player_pos)
215 distance = (1-distance)*10
216 vel = vector.multiply(vel,distance)
217 local acceleration = vector.new(vel.x-currentvel.x,0,vel.z-currentvel.z)
218 self.object:add_velocity(acceleration)
219 acceleration = vector.multiply(acceleration, -1)
220 object:add_player_velocity(acceleration)
225 --makes the boat float
226 float = function(self)
227 local pos = self.object:get_pos()
228 local node = minetest.get_node(pos).name
229 self.swimming = false
231 --flow normally if floating else don't
232 if node == "main:water" or node =="main:waterflow" then
233 self.object:set_acceleration(vector.new(0,0,0))
235 local vel = self.object:get_velocity()
237 local acceleration = vector.new(0,goal-vel.y,0)
238 acceleration = vector.multiply(acceleration, 0.01)
239 self.object:add_velocity(acceleration)
240 --self.object:set_acceleration(vector.new(0,0,0))
242 self.object:set_acceleration(vector.new(0,-10,0))
247 --slows the boat down
248 slowdown = function(self)
249 if not self.moving == true then
250 local vel = self.object:get_velocity()
251 local acceleration = vector.new(-vel.x,0,-vel.z)
252 local deceleration = vector.multiply(acceleration, 0.01)
253 self.object:add_velocity(deceleration)
257 lag_correction = function(self,dtime)
258 local pos = self.object:get_pos()
259 local velocity = self.object:get_velocity()
260 if self.lag_check then
261 local chugent = minetest.get_us_time()/1000000 - self.lag_check
263 --print("lag = "..chugent.." ms")
264 if chugent > 1 and self.old_pos and self.old_velocity then
265 self.object:move_to(self.old_pos)
266 self.object:set_velocity(self.old_velocity)
270 self.old_velocity = velocity
271 self.lag_check = minetest.get_us_time()/1000000
274 on_step = function(self, dtime)
275 self.check_if_on_land(self)
281 self.lag_correction(self,dtime)
285 minetest.register_craftitem("boat:boat", {
286 description = "Boat",
287 inventory_image = "boatitem.png",
288 wield_image = "boatitem.png",
289 liquids_pointable = true,
290 on_place = function(itemstack, placer, pointed_thing)
291 if not pointed_thing.type == "node" then
295 local sneak = placer:get_player_control().sneak
296 local noddef = minetest.registered_nodes[minetest.get_node(pointed_thing.under).name]
297 if not sneak and noddef.on_rightclick then
298 minetest.item_place(itemstack, placer, pointed_thing)
302 minetest.add_entity(pointed_thing.above, "boat:boat")
304 itemstack:take_item()
310 minetest.register_craft({
311 output = "boat:boat",
313 {"main:wood", "", "main:wood"},
314 {"main:wood", "main:wood", "main:wood"},
318 ----------------------------------
322 minetest.register_entity("boat:iron_boat", {
323 initial_properties = {
326 collide_with_objects = false,
327 collisionbox = {-0.4, 0, -0.4, 0.4, 0.5, 0.4},
330 textures = {"iron_boat.png"},
331 visual_size = {x=1,y=1,z=1},
333 automatic_face_movement_dir = -90.0,
334 automatic_face_movement_max_rotation_per_sec = 600,
340 get_staticdata = function(self)
341 return minetest.serialize({
342 --itemstring = self.itemstring,
346 on_activate = function(self, staticdata, dtime_s)
347 if string.sub(staticdata, 1, string.len("return")) == "return" then
348 local data = minetest.deserialize(staticdata)
349 if data and type(data) == "table" then
350 --self.itemstring = data.itemstring
353 --self.itemstring = staticdata
355 self.object:set_armor_groups({immortal = 1})
356 self.object:set_velocity({x = 0, y = 0, z = 0})
357 self.object:set_acceleration({x = 0, y = 0, z = 0})
359 on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, dir)
360 local pos = self.object:get_pos()
361 minetest.add_item(pos, "boat:iron_boat")
366 on_rightclick = function(self,clicker)
367 if not clicker or not clicker:is_player() then
370 local player_name = clicker:get_player_name()
372 if self.rider and player_name == self.rider then
374 local pos = self.object:get_pos()
377 clicker:add_player_velocity(vector.new(0,11,0))
380 player_is_attached(clicker,false)
381 force_update_animation(clicker)
383 elseif not self.rider then
384 self.rider = player_name
385 clicker:set_attach(self.object, "", {x=0, y=2, z=0}, {x=0, y=0, z=0})
387 set_player_animation(clicker,"sit",0)
388 player_is_attached(clicker,true)
391 --check if the boat is stuck on land
392 check_if_on_land = function(self)
393 local pos = self.object:get_pos()
395 local bottom_node = minetest.get_node(pos).name
396 if (bottom_node == "nether:lava" or bottom_node == "nether:lavaflow" or bottom_node == "air") then
404 --players drive the baot
405 drive = function(self)
406 if self.rider and not self.on_land == true then
407 local rider = minetest.get_player_by_name(self.rider)
408 local move = rider:get_player_control().up
411 local currentvel = self.object:get_velocity()
412 local goal = rider:get_look_dir()
413 goal = vector.multiply(goal,20)
414 local acceleration = vector.new(goal.x-currentvel.x,0,goal.z-currentvel.z)
415 acceleration = vector.multiply(acceleration, 0.01)
416 self.object:add_velocity(acceleration)
425 push = function(self)
426 local pos = self.object:get_pos()
427 for _,object in ipairs(minetest.get_objects_inside_radius(pos, 1)) do
428 if object:is_player() and object:get_player_name() ~= self.rider then
429 local player_pos = object:get_pos()
433 local currentvel = self.object:get_velocity()
434 local vel = vector.subtract(pos, player_pos)
435 vel = vector.normalize(vel)
436 local distance = vector.distance(pos,player_pos)
437 distance = (1-distance)*10
438 vel = vector.multiply(vel,distance)
439 local acceleration = vector.new(vel.x-currentvel.x,0,vel.z-currentvel.z)
440 self.object:add_velocity(acceleration)
441 acceleration = vector.multiply(acceleration, -1)
442 object:add_player_velocity(acceleration)
447 --makes the boat float
448 float = function(self)
449 local pos = self.object:get_pos()
450 local node = minetest.get_node(pos).name
451 self.swimming = false
453 --flow normally if floating else don't
454 if node == "nether:lava" or node =="nether:lavaflow" then
456 local vel = self.object:get_velocity()
458 local acceleration = vector.new(0,goal-vel.y,0)
459 acceleration = vector.multiply(acceleration, 0.01)
460 self.object:add_velocity(acceleration)
461 --self.object:set_acceleration(vector.new(0,0,0))
463 local vel = self.object:get_velocity()
465 local acceleration = vector.new(0,goal-vel.y,0)
466 acceleration = vector.multiply(acceleration, 0.01)
467 self.object:add_velocity(acceleration)
468 --self.object:set_acceleration(vector.new(0,0,0))
472 --slows the boat down
473 slowdown = function(self)
474 if not self.moving == true then
475 local vel = self.object:get_velocity()
476 local acceleration = vector.new(-vel.x,0,-vel.z)
477 local deceleration = vector.multiply(acceleration, 0.01)
478 self.object:add_velocity(deceleration)
482 lag_correction = function(self,dtime)
483 local pos = self.object:get_pos()
484 local velocity = self.object:get_velocity()
485 if self.lag_check then
486 local chugent = minetest.get_us_time()/1000000- self.lag_check
488 --print("lag = "..chugent.." ms")
489 if chugent > 70 and self.old_pos and self.old_velocity then
490 self.object:move_to(self.old_pos)
491 self.object:set_velocity(self.old_velocity)
495 self.old_velocity = velocity
496 self.lag_check = minetest.get_us_time()/1000000
499 on_step = function(self, dtime)
500 self.check_if_on_land(self)
506 self.lag_correction(self,dtime)
510 minetest.register_craftitem("boat:iron_boat", {
511 description = "Nether Iron Boat",
512 inventory_image = "iron_boatitem.png",
513 wield_image = "iron_boatitem.png",
514 liquids_pointable = true,
515 on_place = function(itemstack, placer, pointed_thing)
516 if not pointed_thing.type == "node" then
520 local sneak = placer:get_player_control().sneak
521 local noddef = minetest.registered_nodes[minetest.get_node(pointed_thing.under).name]
522 if not sneak and noddef.on_rightclick then
523 minetest.item_place(itemstack, placer, pointed_thing)
527 minetest.add_entity(pointed_thing.above, "boat:iron_boat")
529 itemstack:take_item()
535 minetest.register_craft({
536 output = "boat:iron_boat",
538 {"main:iron", "main:coal", "main:iron"},
539 {"main:iron", "main:iron", "main:iron"},