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)
145 local rider = minetest.get_player_by_name(self.rider)
146 local move = rider:get_player_control().up
150 local currentvel = self.object:get_velocity()
151 local goal = rider:get_look_dir()
152 if self.on_land == true then
153 goal = vector.multiply(goal,1)
155 goal = vector.multiply(goal,20)
157 local acceleration = vector.new(goal.x-currentvel.x,0,goal.z-currentvel.z)
158 acceleration = vector.multiply(acceleration, 0.01)
159 self.object:add_velocity(acceleration)
168 push = function(self)
169 local pos = self.object:get_pos()
170 for _,object in ipairs(minetest.get_objects_inside_radius(pos, 1)) do
171 if object:is_player() and object:get_player_name() ~= self.rider then
172 local player_pos = object:get_pos()
176 local currentvel = self.object:get_velocity()
177 local vel = vector.subtract(pos, player_pos)
178 vel = vector.normalize(vel)
179 local distance = vector.distance(pos,player_pos)
180 distance = (1-distance)*10
181 vel = vector.multiply(vel,distance)
182 local acceleration = vector.new(vel.x-currentvel.x,0,vel.z-currentvel.z)
183 self.object:add_velocity(acceleration)
184 acceleration = vector.multiply(acceleration, -1)
185 object:add_player_velocity(acceleration)
190 --makes the boat float
191 float = function(self)
192 local pos = self.object:get_pos()
193 local node = minetest.get_node(pos).name
194 self.swimming = false
196 --flow normally if floating else don't
197 if node == "main:water" or node =="main:waterflow" then
198 self.object:set_acceleration(vector.new(0,0,0))
200 local vel = self.object:get_velocity()
202 local acceleration = vector.new(0,goal-vel.y,0)
203 acceleration = vector.multiply(acceleration, 0.01)
204 self.object:add_velocity(acceleration)
205 --self.object:set_acceleration(vector.new(0,0,0))
207 self.object:set_acceleration(vector.new(0,-10,0))
212 --slows the boat down
213 slowdown = function(self)
214 if not self.moving == true then
215 local vel = self.object:get_velocity()
216 local acceleration = vector.new(-vel.x,0,-vel.z)
217 local deceleration = vector.multiply(acceleration, 0.01)
218 self.object:add_velocity(deceleration)
222 lag_correction = function(self,dtime)
223 local pos = self.object:get_pos()
224 local velocity = self.object:get_velocity()
225 if self.lag_check then
226 local chugent = minetest.get_us_time()/1000000 - self.lag_check
228 --print("lag = "..chugent.." ms")
229 if chugent > 1 and self.old_pos and self.old_velocity then
230 self.object:move_to(self.old_pos)
231 self.object:set_velocity(self.old_velocity)
235 self.old_velocity = velocity
236 self.lag_check = minetest.get_us_time()/1000000
239 flow = function(self)
240 local flow_dir = flow(self.object:get_pos())
242 flow_dir = vector.multiply(flow_dir,10)
243 local vel = self.object:get_velocity()
244 local acceleration = vector.new(flow_dir.x-vel.x,flow_dir.y-vel.y,flow_dir.z-vel.z)
245 acceleration = vector.multiply(acceleration, 0.01)
246 self.object:add_velocity(acceleration)
250 on_step = function(self, dtime)
251 self.check_if_on_land(self)
257 self.lag_correction(self,dtime)
261 minetest.register_craftitem("boat:boat", {
262 description = "Boat",
263 inventory_image = "boatitem.png",
264 wield_image = "boatitem.png",
265 liquids_pointable = true,
266 on_place = function(itemstack, placer, pointed_thing)
267 if not pointed_thing.type == "node" then
271 local sneak = placer:get_player_control().sneak
272 local noddef = minetest.registered_nodes[minetest.get_node(pointed_thing.under).name]
273 if not sneak and noddef.on_rightclick then
274 minetest.item_place(itemstack, placer, pointed_thing)
278 minetest.add_entity(pointed_thing.above, "boat:boat")
280 itemstack:take_item()
286 minetest.register_craft({
287 output = "boat:boat",
289 {"main:wood", "", "main:wood"},
290 {"main:wood", "main:wood", "main:wood"},
294 ----------------------------------
298 minetest.register_entity("boat:iron_boat", {
299 initial_properties = {
302 collide_with_objects = false,
303 collisionbox = {-0.4, 0, -0.4, 0.4, 0.5, 0.4},
306 textures = {"iron_boat.png"},
307 visual_size = {x=1,y=1,z=1},
309 automatic_face_movement_dir = -90.0,
310 automatic_face_movement_max_rotation_per_sec = 600,
316 get_staticdata = function(self)
317 return minetest.serialize({
318 --itemstring = self.itemstring,
322 on_activate = function(self, staticdata, dtime_s)
323 if string.sub(staticdata, 1, string.len("return")) == "return" then
324 local data = minetest.deserialize(staticdata)
325 if data and type(data) == "table" then
326 --self.itemstring = data.itemstring
329 --self.itemstring = staticdata
331 self.object:set_armor_groups({immortal = 1})
332 self.object:set_velocity({x = 0, y = 0, z = 0})
333 self.object:set_acceleration({x = 0, y = 0, z = 0})
335 on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, dir)
336 local pos = self.object:get_pos()
337 minetest.add_item(pos, "boat:iron_boat")
342 on_rightclick = function(self,clicker)
343 if not clicker or not clicker:is_player() then
346 local player_name = clicker:get_player_name()
348 if self.rider and player_name == self.rider then
350 local pos = self.object:get_pos()
353 clicker:add_player_velocity(vector.new(0,11,0))
356 player_is_attached(clicker,false)
357 force_update_animation(clicker)
359 elseif not self.rider then
360 self.rider = player_name
361 clicker:set_attach(self.object, "", {x=0, y=2, z=0}, {x=0, y=0, z=0})
363 set_player_animation(clicker,"sit",0)
364 player_is_attached(clicker,true)
367 --check if the boat is stuck on land
368 check_if_on_land = function(self)
369 local pos = self.object:get_pos()
371 local bottom_node = minetest.get_node(pos).name
372 if (bottom_node == "nether:lava" or bottom_node == "nether:lavaflow" or bottom_node == "air") then
380 --players drive the baot
381 drive = function(self)
382 if self.rider and not self.on_land == true then
383 local rider = minetest.get_player_by_name(self.rider)
384 local move = rider:get_player_control().up
387 local currentvel = self.object:get_velocity()
388 local goal = rider:get_look_dir()
389 goal = vector.multiply(goal,20)
390 local acceleration = vector.new(goal.x-currentvel.x,0,goal.z-currentvel.z)
391 acceleration = vector.multiply(acceleration, 0.01)
392 self.object:add_velocity(acceleration)
401 push = function(self)
402 local pos = self.object:get_pos()
403 for _,object in ipairs(minetest.get_objects_inside_radius(pos, 1)) do
404 if object:is_player() and object:get_player_name() ~= self.rider then
405 local player_pos = object:get_pos()
409 local currentvel = self.object:get_velocity()
410 local vel = vector.subtract(pos, player_pos)
411 vel = vector.normalize(vel)
412 local distance = vector.distance(pos,player_pos)
413 distance = (1-distance)*10
414 vel = vector.multiply(vel,distance)
415 local acceleration = vector.new(vel.x-currentvel.x,0,vel.z-currentvel.z)
416 self.object:add_velocity(acceleration)
417 acceleration = vector.multiply(acceleration, -1)
418 object:add_player_velocity(acceleration)
423 --makes the boat float
424 float = function(self)
425 local pos = self.object:get_pos()
426 local node = minetest.get_node(pos).name
427 self.swimming = false
429 --flow normally if floating else don't
430 if node == "nether:lava" or node =="nether:lavaflow" then
432 local vel = self.object:get_velocity()
434 local acceleration = vector.new(0,goal-vel.y,0)
435 acceleration = vector.multiply(acceleration, 0.01)
436 self.object:add_velocity(acceleration)
437 --self.object:set_acceleration(vector.new(0,0,0))
439 local vel = self.object:get_velocity()
441 local acceleration = vector.new(0,goal-vel.y,0)
442 acceleration = vector.multiply(acceleration, 0.01)
443 self.object:add_velocity(acceleration)
444 --self.object:set_acceleration(vector.new(0,0,0))
448 --slows the boat down
449 slowdown = function(self)
450 if not self.moving == true then
451 local vel = self.object:get_velocity()
452 local acceleration = vector.new(-vel.x,0,-vel.z)
453 local deceleration = vector.multiply(acceleration, 0.01)
454 self.object:add_velocity(deceleration)
458 lag_correction = function(self,dtime)
459 local pos = self.object:get_pos()
460 local velocity = self.object:get_velocity()
461 if self.lag_check then
462 local chugent = minetest.get_us_time()/1000000- self.lag_check
464 --print("lag = "..chugent.." ms")
465 if chugent > 70 and self.old_pos and self.old_velocity then
466 self.object:move_to(self.old_pos)
467 self.object:set_velocity(self.old_velocity)
471 self.old_velocity = velocity
472 self.lag_check = minetest.get_us_time()/1000000
475 on_step = function(self, dtime)
476 self.check_if_on_land(self)
482 self.lag_correction(self,dtime)
486 minetest.register_craftitem("boat:iron_boat", {
487 description = "Nether Iron Boat",
488 inventory_image = "iron_boatitem.png",
489 wield_image = "iron_boatitem.png",
490 liquids_pointable = true,
491 on_place = function(itemstack, placer, pointed_thing)
492 if not pointed_thing.type == "node" then
496 local sneak = placer:get_player_control().sneak
497 local noddef = minetest.registered_nodes[minetest.get_node(pointed_thing.under).name]
498 if not sneak and noddef.on_rightclick then
499 minetest.item_place(itemstack, placer, pointed_thing)
503 minetest.add_entity(pointed_thing.above, "boat:iron_boat")
505 itemstack:take_item()
511 minetest.register_craft({
512 output = "boat:iron_boat",
514 {"main:iron", "main:coal", "main:iron"},
515 {"main:iron", "main:iron", "main:iron"},