]> git.lizzy.rs Git - Crafter.git/blob - mods/boat/init.lua
Push incomplete version of doubletap running due to possible hardware failure
[Crafter.git] / mods / boat / init.lua
1 --minetest.get_node_level(pos)
2 minetest.register_entity("boat:boat", {
3         initial_properties = {
4                 hp_max = 1,
5                 physical = true,
6                 collide_with_objects = false,
7                 collisionbox = {-0.4, -0.35, -0.4, 0.4, 0.3, 0.4},
8                 visual = "mesh",
9                 mesh = "boat.obj",
10                 textures = {"boat.png"},
11                 visual_size = {x=3,y=3,z=3},
12                 is_visible = true,
13                 automatic_face_movement_dir = 90.0,
14                 automatic_face_movement_max_rotation_per_sec = 600,
15         },
16         
17         rider = nil,
18
19
20         get_staticdata = function(self)
21                 return minetest.serialize({
22                         --itemstring = self.itemstring,
23                 })
24         end,
25
26         on_activate = function(self, staticdata, dtime_s)
27                 if string.sub(staticdata, 1, string.len("return")) == "return" then
28                         local data = minetest.deserialize(staticdata)
29                         if data and type(data) == "table" then
30                                 --self.itemstring = data.itemstring
31                         end
32                 else
33                         --self.itemstring = staticdata
34                 end
35                 self.object:set_armor_groups({immortal = 1})
36                 self.object:set_velocity({x = 0, y = 0, z = 0})
37                 self.object:set_acceleration({x = 0, y = -9.81, z = 0})
38         end,
39         on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, dir)
40                 local pos = self.object:getpos()
41                 minetest.add_item(pos, "boat:boat")
42                 self.object:remove()
43         end,
44         
45         
46         on_rightclick = function(self,clicker)
47                 if not clicker or not clicker:is_player() then
48                         return
49                 end
50                 local player_name = clicker:get_player_name()
51                 
52                 if self.rider and player_name == self.rider then
53                         clicker:set_detach()
54                         self.rider = nil
55                 elseif not self.rider then
56                         self.rider = player_name
57                         clicker:set_attach(self.object, "", {x=0, y=-4.5, z=0}, {x=0, y=0, z=0})
58                         --player:set_eye_offset({x=0, y=-4, z=0},{x=0, y=-4, z=0})
59                         --carts:manage_attachment(clicker, self.object)
60
61                         -- player_api does not update the animation
62                         -- when the player is attached, reset to default animation
63                         
64                         --player_api.set_animation(clicker, "stand")
65                 end
66         end,
67         --check if the boat is stuck on land
68         check_if_on_land = function(self)
69                 local pos = self.object:getpos()
70                 pos.y = pos.y - 0.37
71                 local bottom_node = minetest.get_node(pos).name
72                 if (bottom_node == "main:water" or bottom_node == "main:waterflow" or bottom_node == "air") then
73                         self.on_land = false
74                 else
75                         self.on_land = true
76                 end
77         
78         end,
79         
80         --players drive the baot
81         drive = function(self)
82                 if self.rider and not self.on_land == true then
83                         local rider = minetest.get_player_by_name(self.rider)
84                         local move = rider:get_player_control().up
85                         self.moving = nil
86                         if move then
87                                 local currentvel = self.object:getvelocity()
88                                 local goal = rider:get_look_dir()
89                                 goal = vector.multiply(goal,9)
90                                 local acceleration = vector.new(goal.x-currentvel.x,0,goal.z-currentvel.z)
91                                 acceleration = vector.multiply(acceleration, 0.01)
92                                 self.object:add_velocity(acceleration)
93                                 self.moving = true
94                         end
95                 else
96                         self.moving = nil
97                 end
98         end,
99         
100         --players push boat
101         push = function(self)
102                 local pos = self.object:getpos()
103                 for _,object in ipairs(minetest.get_objects_inside_radius(pos, 1)) do
104                         if object:is_player() and object:get_player_name() ~= self.rider then
105                                 local player_pos = object:getpos()
106                                 pos.y = 0
107                                 player_pos.y = 0
108                                 
109                                 local currentvel = self.object:getvelocity()
110                                 local vel = vector.subtract(pos, player_pos)
111                                 vel = vector.normalize(vel)
112                                 local distance = vector.distance(pos,player_pos)
113                                 distance = (1-distance)*10
114                                 vel = vector.multiply(vel,distance)
115                                 local acceleration = vector.new(vel.x-currentvel.x,0,vel.z-currentvel.z)
116                                 self.object:add_velocity(acceleration)
117                                 acceleration = vector.multiply(acceleration, -1)
118                                 object:add_player_velocity(acceleration)
119                         end
120                 end
121         end,
122         
123         --makes the boat float
124         float = function(self)
125                 local pos = self.object:getpos()
126                 local node = minetest.get_node(pos).name
127                 self.swimming = false
128                 
129                 --flow normally if floating else don't
130                 if node == "main:water" or node =="main:waterflow" then
131                         self.swimming = true
132                         local vel = self.object:getvelocity()
133                         local goal = 3
134                         local acceleration = vector.new(0,goal-vel.y,0)
135                         self.object:add_velocity(acceleration)
136                 end
137         end,
138         
139         --makes boats flow
140         flow = function(self)
141                 local pos = self.object:getpos()
142                 pos.y = pos.y - 0.4
143                 local node = minetest.get_node(pos).name
144                 local node_above = minetest.get_node(vector.new(pos.x,pos.y+1,pos.z)).name
145                 local goalx = 0
146                 local goalz = 0
147                 --print(node_above)
148                 if (node == "main:waterflow" or node == "main:water" ) and not self.moving == true and (node_above ~= "main:water" and node_above ~= "main:waterflow") then
149                         local currentvel = self.object:getvelocity()
150                         local level = minetest.get_node_level(pos)
151                         local pos = self.object:getpos()
152                         for x = -1,1 do
153                                 for y = -1,0 do
154                                         for z = -1,1 do
155                                                 if (x == 0 and z ~= 0) or (z == 0 and x ~=0) then
156                                                         local nodename = minetest.get_node(vector.new(pos.x+x,pos.y+y,pos.z+z)).name
157                                                         local level2 = minetest.get_node_level(vector.new(pos.x+x,pos.y+y,pos.z+z))
158                                                         if (level2 < level and nodename == "main:waterflow") or (nodename == "main:water" and level2 == 7)  then
159                                                                 goalx = x*7
160                                                                 goalz = z*7
161                                                                 --break
162                                                         end
163                                                 end
164                                         end
165                                 end
166                         end
167                         --only add velocity if there is one
168                         --else this stops the boat
169                         if goalx ~= 0 or goalz ~= 0 then
170                                 local acceleration = vector.new(goalx-currentvel.x,0,goalz-currentvel.z)
171                                 acceleration = vector.multiply(acceleration, 0.01)
172                                 self.object:add_velocity(acceleration)
173                         end
174                 end
175         end,
176         
177         
178         --slows the boat down
179         slowdown = function(self)
180                 if not self.moving == true then
181                         local vel = self.object:getvelocity()
182                         local deceleration = vector.multiply(vel, -0.01)
183                         self.object:add_velocity(deceleration)
184                 end
185         end,
186
187         on_step = function(self, dtime)
188                 self.check_if_on_land(self)
189                 self.push(self)
190                 self.drive(self)
191                 self.float(self)
192                 self.flow(self)
193                 self.slowdown(self)
194         end,
195 })
196
197 minetest.register_craftitem("boat:boat", {
198         description = "Boat",
199         inventory_image = "boatitem.png",
200         wield_image = "boatitem.png",
201         liquids_pointable = true,
202         on_place = function(itemstack, placer, pointed_thing)
203                 if not pointed_thing.type == "node" then
204                         return
205                 end
206                 
207                 if minetest.get_item_group(minetest.get_node(pointed_thing.under).name, "water")>0 then
208                         minetest.add_entity(pointed_thing.under, "boat:boat")
209                 else
210                         return
211                 end
212
213                 itemstack:take_item()
214
215                 return itemstack
216         end,
217 })
218
219 minetest.register_craft({
220         output = "boat:boat",
221         recipe = {
222                 {"main:wood", "", "main:wood"},
223                 {"main:wood", "main:wood", "main:wood"},
224         },
225 })