3 minetest,vector,math,pairs
5 minetest,vector,math,pairs
19 local function lavaflow(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:lavaflow" 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:lavaflow" or nodename == "main:lava" 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 --minetest.get_node_level(pos)
60 minetest.register_entity("boat:boat", {
61 initial_properties = {
64 collide_with_objects = false,
65 collisionbox = {-0.4, 0, -0.4, 0.4, 0.5, 0.4},
68 textures = {"boat.png"},
69 visual_size = {x=1,y=1,z=1},
71 automatic_face_movement_dir = -90.0,
72 automatic_face_movement_max_rotation_per_sec = 600,
78 get_staticdata = function(self)
79 return minetest.serialize({
80 --itemstring = self.itemstring,
84 on_activate = function(self, staticdata, dtime_s)
85 if string.sub(staticdata, 1, string.len("return")) == "return" then
86 local data = minetest.deserialize(staticdata)
87 if data and type(data) == "table" then
88 --self.itemstring = data.itemstring
91 --self.itemstring = staticdata
93 self.object:set_armor_groups({immortal = 1})
94 self.object:set_velocity({x = 0, y = 0, z = 0})
95 self.object:set_acceleration({x = 0, y = 0, z = 0})
97 on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, dir)
98 local pos = self.object:get_pos()
99 minetest.add_item(pos, "boat:boat")
104 on_rightclick = function(self,clicker)
105 if not clicker or not clicker:is_player() then
108 local player_name = clicker:get_player_name()
110 if self.rider and player_name == self.rider then
112 local pos = self.object:get_pos()
115 clicker:add_player_velocity(vector.new(0,11,0))
118 player_is_attached(clicker,false)
119 force_update_animation(clicker)
121 elseif not self.rider then
122 self.rider = player_name
123 clicker:set_attach(self.object, "", {x=0, y=2, z=0}, {x=0, y=0, z=0})
125 set_player_animation(clicker,"sit",0)
126 player_is_attached(clicker,true)
129 --check if the boat is stuck on land
130 check_if_on_land = function(self)
131 local pos = self.object:get_pos()
133 local bottom_node = minetest.get_node(pos).name
134 if (bottom_node == "main:water" or bottom_node == "main:waterflow" or bottom_node == "air") then
142 --players drive the baot
143 drive = function(self)
144 if self.rider and not self.on_land == true then
145 local rider = minetest.get_player_by_name(self.rider)
146 local move = rider:get_player_control().up
149 local currentvel = self.object:get_velocity()
150 local goal = rider:get_look_dir()
151 goal = vector.multiply(goal,20)
152 local acceleration = vector.new(goal.x-currentvel.x,0,goal.z-currentvel.z)
153 acceleration = vector.multiply(acceleration, 0.01)
154 self.object:add_velocity(acceleration)
163 push = function(self)
164 local pos = self.object:get_pos()
165 for _,object in ipairs(minetest.get_objects_inside_radius(pos, 1)) do
166 if object:is_player() and object:get_player_name() ~= self.rider then
167 local player_pos = object:get_pos()
171 local currentvel = self.object:get_velocity()
172 local vel = vector.subtract(pos, player_pos)
173 vel = vector.normalize(vel)
174 local distance = vector.distance(pos,player_pos)
175 distance = (1-distance)*10
176 vel = vector.multiply(vel,distance)
177 local acceleration = vector.new(vel.x-currentvel.x,0,vel.z-currentvel.z)
178 self.object:add_velocity(acceleration)
179 acceleration = vector.multiply(acceleration, -1)
180 object:add_player_velocity(acceleration)
185 --makes the boat float
186 float = function(self)
187 local pos = self.object:get_pos()
188 local node = minetest.get_node(pos).name
189 self.swimming = false
191 --flow normally if floating else don't
192 if node == "main:water" or node =="main:waterflow" then
193 self.object:set_acceleration(vector.new(0,0,0))
195 local vel = self.object:get_velocity()
197 local acceleration = vector.new(0,goal-vel.y,0)
198 acceleration = vector.multiply(acceleration, 0.01)
199 self.object:add_velocity(acceleration)
200 --self.object:set_acceleration(vector.new(0,0,0))
202 self.object:set_acceleration(vector.new(0,-10,0))
207 --slows the boat down
208 slowdown = function(self)
209 if not self.moving == true then
210 local vel = self.object:get_velocity()
211 local acceleration = vector.new(-vel.x,0,-vel.z)
212 local deceleration = vector.multiply(acceleration, 0.01)
213 self.object:add_velocity(deceleration)
217 lag_correction = function(self,dtime)
218 local pos = self.object:get_pos()
219 local velocity = self.object:get_velocity()
220 if self.lag_check then
221 local chugent = minetest.get_us_time()/1000000 - self.lag_check
223 --print("lag = "..chugent.." ms")
224 if chugent > 1 and self.old_pos and self.old_velocity then
225 self.object:move_to(self.old_pos)
226 self.object:set_velocity(self.old_velocity)
230 self.old_velocity = velocity
231 self.lag_check = minetest.get_us_time()/1000000
234 flow = function(self)
235 local flow_dir = flow(self,self.object:get_pos())
237 flow_dir = vector.multiply(flow_dir,10)
238 local vel = self.object:get_velocity()
239 local acceleration = vector.new(flow_dir.x-vel.x,flow_dir.y-vel.y,flow_dir.z-vel.z)
240 acceleration = vector.multiply(acceleration, 0.01)
241 self.object:add_velocity(acceleration)
245 on_step = function(self, dtime)
246 self.check_if_on_land(self)
252 self.lag_correction(self,dtime)
256 minetest.register_craftitem("boat:boat", {
257 description = "Boat",
258 inventory_image = "boatitem.png",
259 wield_image = "boatitem.png",
260 liquids_pointable = true,
261 on_place = function(itemstack, placer, pointed_thing)
262 if not pointed_thing.type == "node" then
266 local sneak = placer:get_player_control().sneak
267 local noddef = minetest.registered_nodes[minetest.get_node(pointed_thing.under).name]
268 if not sneak and noddef.on_rightclick then
269 minetest.item_place(itemstack, placer, pointed_thing)
273 minetest.add_entity(pointed_thing.above, "boat:boat")
275 itemstack:take_item()
281 minetest.register_craft({
282 output = "boat:boat",
284 {"main:wood", "", "main:wood"},
285 {"main:wood", "main:wood", "main:wood"},
289 ----------------------------------
293 minetest.register_entity("boat:iron_boat", {
294 initial_properties = {
297 collide_with_objects = false,
298 collisionbox = {-0.4, 0, -0.4, 0.4, 0.5, 0.4},
301 textures = {"iron_boat.png"},
302 visual_size = {x=1,y=1,z=1},
304 automatic_face_movement_dir = -90.0,
305 automatic_face_movement_max_rotation_per_sec = 600,
311 get_staticdata = function(self)
312 return minetest.serialize({
313 --itemstring = self.itemstring,
317 on_activate = function(self, staticdata, dtime_s)
318 if string.sub(staticdata, 1, string.len("return")) == "return" then
319 local data = minetest.deserialize(staticdata)
320 if data and type(data) == "table" then
321 --self.itemstring = data.itemstring
324 --self.itemstring = staticdata
326 self.object:set_armor_groups({immortal = 1})
327 self.object:set_velocity({x = 0, y = 0, z = 0})
328 self.object:set_acceleration({x = 0, y = 0, z = 0})
330 on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, dir)
331 local pos = self.object:get_pos()
332 minetest.add_item(pos, "boat:iron_boat")
337 on_rightclick = function(self,clicker)
338 if not clicker or not clicker:is_player() then
341 local player_name = clicker:get_player_name()
343 if self.rider and player_name == self.rider then
345 local pos = self.object:get_pos()
348 clicker:add_player_velocity(vector.new(0,11,0))
351 player_is_attached(clicker,false)
352 force_update_animation(clicker)
354 elseif not self.rider then
355 self.rider = player_name
356 clicker:set_attach(self.object, "", {x=0, y=2, z=0}, {x=0, y=0, z=0})
358 set_player_animation(clicker,"sit",0)
359 player_is_attached(clicker,true)
362 --check if the boat is stuck on land
363 check_if_on_land = function(self)
364 local pos = self.object:get_pos()
366 local bottom_node = minetest.get_node(pos).name
367 if (bottom_node == "nether:lava" or bottom_node == "nether:lavaflow" or bottom_node == "air") then
375 --players drive the baot
376 drive = function(self)
377 if self.rider and not self.on_land == true then
378 local rider = minetest.get_player_by_name(self.rider)
379 local move = rider:get_player_control().up
382 local currentvel = self.object:get_velocity()
383 local goal = rider:get_look_dir()
384 goal = vector.multiply(goal,20)
385 local acceleration = vector.new(goal.x-currentvel.x,0,goal.z-currentvel.z)
386 acceleration = vector.multiply(acceleration, 0.01)
387 self.object:add_velocity(acceleration)
396 push = function(self)
397 local pos = self.object:get_pos()
398 for _,object in ipairs(minetest.get_objects_inside_radius(pos, 1)) do
399 if object:is_player() and object:get_player_name() ~= self.rider then
400 local player_pos = object:get_pos()
404 local currentvel = self.object:get_velocity()
405 local vel = vector.subtract(pos, player_pos)
406 vel = vector.normalize(vel)
407 local distance = vector.distance(pos,player_pos)
408 distance = (1-distance)*10
409 vel = vector.multiply(vel,distance)
410 local acceleration = vector.new(vel.x-currentvel.x,0,vel.z-currentvel.z)
411 self.object:add_velocity(acceleration)
412 acceleration = vector.multiply(acceleration, -1)
413 object:add_player_velocity(acceleration)
418 --makes the boat float
419 float = function(self)
420 local pos = self.object:get_pos()
421 local node = minetest.get_node(pos).name
422 self.swimming = false
424 --flow normally if floating else don't
425 if node == "nether:lava" or node =="nether:lavaflow" then
427 local vel = self.object:get_velocity()
429 local acceleration = vector.new(0,goal-vel.y,0)
430 acceleration = vector.multiply(acceleration, 0.01)
431 self.object:add_velocity(acceleration)
432 --self.object:set_acceleration(vector.new(0,0,0))
434 local vel = self.object:get_velocity()
436 local acceleration = vector.new(0,goal-vel.y,0)
437 acceleration = vector.multiply(acceleration, 0.01)
438 self.object:add_velocity(acceleration)
439 --self.object:set_acceleration(vector.new(0,0,0))
443 --slows the boat down
444 slowdown = function(self)
445 if not self.moving == true then
446 local vel = self.object:get_velocity()
447 local acceleration = vector.new(-vel.x,0,-vel.z)
448 local deceleration = vector.multiply(acceleration, 0.01)
449 self.object:add_velocity(deceleration)
453 lag_correction = function(self,dtime)
454 local pos = self.object:get_pos()
455 local velocity = self.object:get_velocity()
456 if self.lag_check then
457 local chugent = minetest.get_us_time()/1000000- self.lag_check
459 --print("lag = "..chugent.." ms")
460 if chugent > 70 and self.old_pos and self.old_velocity then
461 self.object:move_to(self.old_pos)
462 self.object:set_velocity(self.old_velocity)
466 self.old_velocity = velocity
467 self.lag_check = minetest.get_us_time()/1000000
470 on_step = function(self, dtime)
471 self.check_if_on_land(self)
477 self.lag_correction(self,dtime)
481 minetest.register_craftitem("boat:iron_boat", {
482 description = "Nether Iron Boat",
483 inventory_image = "iron_boatitem.png",
484 wield_image = "iron_boatitem.png",
485 liquids_pointable = true,
486 on_place = function(itemstack, placer, pointed_thing)
487 if not pointed_thing.type == "node" then
491 local sneak = placer:get_player_control().sneak
492 local noddef = minetest.registered_nodes[minetest.get_node(pointed_thing.under).name]
493 if not sneak and noddef.on_rightclick then
494 minetest.item_place(itemstack, placer, pointed_thing)
498 minetest.add_entity(pointed_thing.above, "boat:iron_boat")
500 itemstack:take_item()
506 minetest.register_craft({
507 output = "boat:iron_boat",
509 {"main:iron", "main:coal", "main:iron"},
510 {"main:iron", "main:iron", "main:iron"},