]> git.lizzy.rs Git - Crafter.git/blob - mods/boat/init.lua
remove server debug
[Crafter.git] / mods / boat / init.lua
1
2 local
3 minetest,vector,math,pairs
4 =
5 minetest,vector,math,pairs
6
7 local name
8 local pos
9 local node
10 local node_above
11 local goalx
12 local goalz
13 local currentvel
14 local level
15 local level2
16 local nodename
17 local acceleration
18
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
25         goalx = 0
26         goalz = 0
27         found = false
28         if node == "main:lavaflow" then
29                 currentvel = self.object:get_velocity()
30                 level = minetest.get_node_level(pos)
31                 for x = -1,1 do
32                         for z = -1,1 do
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
37                                                 goalx = -x
38                                                 goalz = -z
39                                                 --diagonal flow
40                                                 if goalx ~= 0 and goalz ~= 0 then
41                                                         found = true
42                                                 end
43                                         end
44                                 end
45                         end
46                 end
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)
55                 end
56         end
57 end
58
59 --minetest.get_node_level(pos)
60 minetest.register_entity("boat:boat", {
61         initial_properties = {
62                 hp_max = 1,
63                 physical = true,
64                 collide_with_objects = false,
65                 collisionbox = {-0.4, 0, -0.4, 0.4, 0.5, 0.4},
66                 visual = "mesh",
67                 mesh = "boat.x",
68                 textures = {"boat.png"},
69                 visual_size = {x=1,y=1,z=1},
70                 is_visible = true,
71                 automatic_face_movement_dir = -90.0,
72                 automatic_face_movement_max_rotation_per_sec = 600,
73         },
74         
75         rider = nil,
76         boat = true,
77
78         get_staticdata = function(self)
79                 return minetest.serialize({
80                         --itemstring = self.itemstring,
81                 })
82         end,
83
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
89                         end
90                 else
91                         --self.itemstring = staticdata
92                 end
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})
96         end,
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")
100                 self.object:remove()
101         end,
102         
103         
104         on_rightclick = function(self,clicker)
105                 if not clicker or not clicker:is_player() then
106                         return
107                 end
108                 local player_name = clicker:get_player_name()
109                 
110                 if self.rider and player_name == self.rider then
111                         clicker:set_detach()
112                         local pos = self.object:get_pos()
113                         pos.y = pos.y + 1
114                         clicker:move_to(pos)
115                         clicker:add_player_velocity(vector.new(0,11,0))
116                         self.rider = nil
117                         
118                         player_is_attached(clicker,false)
119                         force_update_animation(clicker)
120
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})
124                         
125                         set_player_animation(clicker,"sit",0)
126                         player_is_attached(clicker,true)
127                 end
128         end,
129         --check if the boat is stuck on land
130         check_if_on_land = function(self)
131                 local pos = self.object:get_pos()
132                 pos.y = pos.y - 0.37
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
135                         self.on_land = false
136                 else
137                         self.on_land = true
138                 end
139         
140         end,
141         
142         --players drive the baot
143         drive = function(self)
144                 if self.rider then
145                         local rider = minetest.get_player_by_name(self.rider)
146                         local move = rider:get_player_control().up
147                         self.moving = nil
148                         if move then
149                                 
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)
154                                 else
155                                         goal = vector.multiply(goal,20)
156                                 end
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)
160                                 self.moving = true
161                         end
162                 else
163                         self.moving = nil
164                 end
165         end,
166         
167         --players push boat
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()
173                                 pos.y = 0
174                                 player_pos.y = 0
175                                 
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)
186                         end
187                 end
188         end,
189         
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
195                 
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))
199                         self.swimming = true
200                         local vel = self.object:get_velocity()
201                         local goal = 9
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))
206                 else
207                         self.object:set_acceleration(vector.new(0,-10,0))
208                 end
209         end,
210         
211         
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)
219                 end
220         end,
221
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
227
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)
232                         end
233                 end
234                 self.old_pos = pos
235                 self.old_velocity = velocity
236                 self.lag_check = minetest.get_us_time()/1000000
237         end,
238
239         flow = function(self)
240                 local flow_dir = flow(self.object:get_pos())
241                 if flow_dir then
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)
247                 end
248         end,
249
250         on_step = function(self, dtime)
251                 self.check_if_on_land(self)
252                 self.push(self)
253                 self.drive(self)
254                 self.float(self)
255                 self.flow(self)
256                 self.slowdown(self)
257                 self.lag_correction(self,dtime)
258         end,
259 })
260
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
268                         return
269                 end
270                 
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)
275                         return
276                 end
277                 
278                 minetest.add_entity(pointed_thing.above, "boat:boat")
279
280                 itemstack:take_item()
281
282                 return itemstack
283         end,
284 })
285
286 minetest.register_craft({
287         output = "boat:boat",
288         recipe = {
289                 {"main:wood", "", "main:wood"},
290                 {"main:wood", "main:wood", "main:wood"},
291         },
292 })
293
294 ----------------------------------
295
296
297
298 minetest.register_entity("boat:iron_boat", {
299         initial_properties = {
300                 hp_max = 1,
301                 physical = true,
302                 collide_with_objects = false,
303                 collisionbox = {-0.4, 0, -0.4, 0.4, 0.5, 0.4},
304                 visual = "mesh",
305                 mesh = "boat.x",
306                 textures = {"iron_boat.png"},
307                 visual_size = {x=1,y=1,z=1},
308                 is_visible = true,
309                 automatic_face_movement_dir = -90.0,
310                 automatic_face_movement_max_rotation_per_sec = 600,
311         },
312         
313         rider = nil,
314         iron_boat = true,
315
316         get_staticdata = function(self)
317                 return minetest.serialize({
318                         --itemstring = self.itemstring,
319                 })
320         end,
321
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
327                         end
328                 else
329                         --self.itemstring = staticdata
330                 end
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})
334         end,
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")
338                 self.object:remove()
339         end,
340         
341         
342         on_rightclick = function(self,clicker)
343                 if not clicker or not clicker:is_player() then
344                         return
345                 end
346                 local player_name = clicker:get_player_name()
347                 
348                 if self.rider and player_name == self.rider then
349                         clicker:set_detach()
350                         local pos = self.object:get_pos()
351                         pos.y = pos.y + 1
352                         clicker:move_to(pos)
353                         clicker:add_player_velocity(vector.new(0,11,0))
354                         self.rider = nil
355                         
356                         player_is_attached(clicker,false)
357                         force_update_animation(clicker)
358
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})
362                         
363                         set_player_animation(clicker,"sit",0)
364                         player_is_attached(clicker,true)
365                 end
366         end,
367         --check if the boat is stuck on land
368         check_if_on_land = function(self)
369                 local pos = self.object:get_pos()
370                 pos.y = pos.y - 0.37
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
373                         self.on_land = false
374                 else
375                         self.on_land = true
376                 end
377         
378         end,
379         
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
385                         self.moving = nil
386                         if move then
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)
393                                 self.moving = true
394                         end
395                 else
396                         self.moving = nil
397                 end
398         end,
399         
400         --players push boat
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()
406                                 pos.y = 0
407                                 player_pos.y = 0
408                                 
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)
419                         end
420                 end
421         end,
422         
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
428                 
429                 --flow normally if floating else don't
430                 if node == "nether:lava" or node =="nether:lavaflow" then
431                         self.swimming = true
432                         local vel = self.object:get_velocity()
433                         local goal = 9
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))
438                 else
439                         local vel = self.object:get_velocity()
440                         local goal = -9.81
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))
445                 end
446         end,
447         
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)
455                 end
456         end,
457
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
463
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)
468                         end
469                 end
470                 self.old_pos = pos
471                 self.old_velocity = velocity
472                 self.lag_check = minetest.get_us_time()/1000000
473         end,
474
475         on_step = function(self, dtime)
476                 self.check_if_on_land(self)
477                 self.push(self)
478                 self.drive(self)
479                 self.float(self)
480                 lavaflow(self)
481                 self.slowdown(self)
482                 self.lag_correction(self,dtime)
483         end,
484 })
485
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
493                         return
494                 end
495                 
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)
500                         return
501                 end
502                 
503                 minetest.add_entity(pointed_thing.above, "boat:iron_boat")
504
505                 itemstack:take_item()
506
507                 return itemstack
508         end,
509 })
510
511 minetest.register_craft({
512         output = "boat:iron_boat",
513         recipe = {
514                 {"main:iron", "main:coal", "main:iron"},
515                 {"main:iron", "main:iron", "main:iron"},
516         },
517 })