]> git.lizzy.rs Git - Crafter.git/blob - mods/minecart/oldcode.txt
Set minecarts rotation when turning
[Crafter.git] / mods / minecart / oldcode.txt
1 local path = minetest.get_modpath("minecart")
2 dofile(path.."/rail.lua")
3
4
5 --get if rail
6 local function rail(pos)
7         return(minetest.get_node_group(minetest.get_node(pos).name,"rail")>0)
8 end
9
10 --check if on rail
11 local function on_rail(self,pos)
12         if not rail(pos) and not self.slope then
13                 self.axis = nil
14                 return(false)
15         else
16                 return(true)
17         end
18 end
19
20 --set physical state
21 local function physical(self,pos)
22         if on_rail(self,pos) then
23                 self.object:set_properties({physical = false})
24                 self.object:setacceleration(vector.new(0,0,0))
25         elseif not self.slope then
26                 self.object:set_properties({physical = true})
27                 self.object:setacceleration(vector.new(0,-9.81,0))
28         end
29 end
30
31 --get if node in minecarts direction
32 local function node_ahead(self,pos)
33         local vel = self.object:getvelocity()
34         local dir = vector.normalize(vel)
35         return(rail(vector.add(pos,dir)))
36 end
37
38 --get current axis (prefers x)
39 local function axis(pos)
40         if rail(pos) then
41                 if rail(vector.new(pos.x-1,pos.y,pos.z)) or rail(vector.new(pos.x+1,pos.y,pos.z)) then return("x") end
42                 if rail(vector.new(pos.x,pos.y,pos.z-1)) or rail(vector.new(pos.x,pos.y,pos.z+1)) then return("z") end
43         end
44 end
45
46 --snap object to rail
47 local function snap_rail(self,pos)
48         local slopy = self.slope
49         if not slopy then print("the slope is nil") else
50                 print("the slope is ".. slopy)
51         end
52         local railpos = vector.floor(vector.add(pos, 0.5))
53         local vel = self.object:getvelocity()
54         if self.axis == "x" and pos.x ~= railpos.x then
55                 self.object:moveto(vector.new(pos.x,railpos.y,railpos.z))
56                 self.object:setvelocity(vector.new(vel.x,0,0))
57                 print("snapped to x")
58                 return
59         end
60         if self.axis == "z" and pos.z ~= railpos.z then
61                 self.object:moveto(vector.new(railpos.x,railpos.y,pos.z))
62                 self.object:setvelocity(vector.new(0,0,vel.z))
63                 print("snapped to z")
64                 return
65         end
66 end
67
68 --check if entering new position
69 local function newnode(self,pos)
70         local pos = vector.floor(vector.add(pos,0.5))
71         
72         pos.y = 0
73         
74         local equals = false
75         
76         
77         if self.oldpos then
78                 equals = vector.equals(pos,self.oldpos)
79         end
80         
81         self.oldpos = pos
82         return(not equals)
83 end
84
85 --check if past center - used for turning
86 local function pastcenter(self,pos)
87         
88         local center = vector.floor(vector.add(pos,0.5))
89         center.y = 0
90         local pos2d = vector.new(pos.x,0,pos.z)
91         
92         local vel = self.object:getvelocity()
93         local dir = vector.normalize(vel)
94         dir.y = 0
95         local checker = vector.round(vector.normalize(vector.subtract(pos2d,center)))
96         checker.y = 0
97         local past = vector.equals(checker, dir)
98         return(past)
99 end
100
101 --check if node ahead
102 local function node_forward(self,pos)
103         local vel = self.object:getvelocity()
104         local dir = vector.normalize(vel)
105         return(rail(vector.add(pos,dir)))
106 end
107
108 --check if node above or below
109 local function check_hill(self,pos)
110         local vel = self.object:getvelocity()
111         local dirup = vector.normalize(vel)
112         
113         dirup.y = dirup.y + 1
114         
115         print(dump(dirup))
116         
117         minetest.add_particlespawner({
118                 amount = 5,
119                 time = 0,
120                 minpos = vector.add(pos,dirup),
121                 maxpos = vector.add(pos,dirup),
122                 minvel = vector.new(0,0,0),
123                 maxvel = vector.new(0,0,0),
124                 minacc = {x=0, y=0, z=0},
125                 maxacc = {x=0, y=0, z=0},
126                 minexptime = 5,
127                 maxexptime = 5,
128                 minsize = 1,
129                 maxsize = 1,
130                 attached = player,
131                 collisiondetection = true,
132                 vertical = false,
133                 texture = "treecapitator.png"
134         })
135         
136         local dirdown = vector.new(0,-0.5,0)
137         
138         if rail(vector.add(pos,dirup)) then
139                 self.slope = "up"
140                 return("up")
141         elseif rail(vector.add(pos,dirdown)) then
142                 self.slope = "down"
143                 return("down")
144         else
145                 self.slope = nil
146                 return(nil)
147         end
148 end
149
150 local function gravity(self,pos)
151         
152         if self.slope == up then
153                 local vel = vector.multiply(self.object:getvelocity(), 0.95)
154                 self.object:set_velocity(vel)
155         end
156         if self.slope == up then
157                 local vel = vector.multiply(self.object:getvelocity(), 1.05)
158                 self.object:set_velocity(vel)
159         end
160
161 end
162
163 --make the minecart go up and down hills
164 local function navigate_hill(self)
165         if self.slope then
166                 local vel = self.object:getvelocity()
167                 if self.slope == "up" then
168                 
169                         local yvel = 0
170                         if self.axis == "x" then
171                                 yvel = math.abs(vel.x)*1.1
172                         end
173                         if self.axis == "z" then
174                                 yvel = math.abs(vel.z)*1.1
175                         end
176                         self.object:setvelocity(vector.new(vel.x,yvel,vel.z))
177                 elseif self.slope == "down" then
178                 
179                         local yvel = 0
180                         if self.axis == "x" then
181                                 yvel = math.abs(vel.x)*-1
182                         end
183                         if self.axis == "z" then
184                                 yvel = math.abs(vel.z)*-1
185                         end
186                         
187                         self.object:setvelocity(vector.new(vel.x,yvel,vel.z))
188                 end
189         end
190 end
191
192 --swap axis and speed 90 degrees
193 local function turn_check(self,pos)
194         local axis = self.axis
195         local vel = self.object:getvelocity()
196         vel.x = math.abs(vel.x)
197         vel.y = math.abs(vel.y)
198         vel.z = math.abs(vel.z)
199         
200         if axis == "x" then
201                 if rail(vector.new(pos.x,pos.y,pos.z-1)) then
202                         print("-x")
203                         self.object:setvelocity(vector.new(0,0,vel.x*-1))
204                         self.axis = "z"
205                         snap_rail(self,pos)
206                         self.turn_timer = 0
207                         return
208                 elseif rail(vector.new(pos.x,pos.y,pos.z+1)) then 
209                         print("+x")
210                         self.object:setvelocity(vector.new(0,0,vel.x))
211                         self.axis = "z"
212                         snap_rail(self,pos)
213                         self.turn_timer = 0
214                         return
215                 end
216         end
217         if axis == "z" then
218                 if rail(vector.new(pos.x-1,pos.y,pos.z)) then
219                         print("-z")
220                         self.object:setvelocity(vector.new(vel.z*-1,0,0))
221                         self.axis = "x"
222                         snap_rail(self,pos)
223                         self.turn_timer = 0
224                         return
225                 elseif rail(vector.new(pos.x+1,pos.y,pos.z)) then 
226                         print("+z")
227                         self.object:setvelocity(vector.new(vel.z,0,0))
228                         self.axis = "x"
229                         snap_rail(self,pos)
230                         self.turn_timer = 0
231                         return
232                 end
233         end
234 end
235 --try to turn
236 local function turn(self,pos)
237         if pastcenter(self,pos) then
238                 if not node_forward(self,pos) and self.axis then
239                         turn_check(self,pos)
240                 end
241         end
242 end
243
244 --the main mechanics of the minecart
245 local function minecart_brain(self,dtime)
246         if self.turn_timer < 5 then
247                 self.turn_timer = self.turn_timer + dtime
248         end
249         local pos = self.object:getpos()
250         pos.y = pos.y - 0.5
251
252         
253         if not self.axis then
254                 self.axis = axis(pos)
255         end
256         
257         if newnode(self,pos) then
258                 snap_rail(self,pos)
259         end
260         --check_hill(self,pos)
261         --navigate_hill(self)
262
263         
264         turn(self,pos)
265         
266         on_rail(self,pos)
267         physical(self,pos)
268         --print(self.axis)
269         
270         --check if falling and then fall at the same speed to go down
271 end
272         
273         
274         
275         
276         
277         
278         
279         
280         
281         
282         
283         
284         
285         
286         
287         
288         
289         
290         
291         
292         
293         
294         
295         
296         
297         
298         
299         
300         
301         
302         
303         
304         
305         
306         
307         
308         
309         
310         
311
312 minetest.register_entity("minecart:minecart", {
313         initial_properties = {
314                 physical = true, -- otherwise going uphill breaks
315                 collisionbox = {-0.4, -0.5, -0.4, 0.4, 0.45, 0.4},--{-0.5, -0.4, -0.5, 0.5, 0.25, 0.5},
316                 visual = "mesh",
317                 mesh = "minecart.obj",
318                 visual_size = {x=1, y=1},
319                 textures = {"minecart.png"},
320                 automatic_face_movement_dir = 90.0,
321                 automatic_face_movement_max_rotation_per_sec = 600,
322         },
323
324         rider = nil,
325         punched = false,
326         speed = 0,
327         turn_timer = 0,
328         incline = nil,
329         turn_timer = 5,
330
331         on_rightclick = function(self,clicker)
332                 if not clicker or not clicker:is_player() then
333                         return
334                 end
335                 local player_name = clicker:get_player_name()
336                 
337                 if self.rider and player_name == self.rider then
338                         self.rider = nil
339                         --carts:manage_attachment(clicker, nil)
340                 elseif not self.rider then
341                         self.rider = player_name
342                         clicker:set_attach(self.object, "", {x=0, y=-4.5, z=0}, {x=0, y=0, z=0})
343                         --player:set_eye_offset({x=0, y=-4, z=0},{x=0, y=-4, z=0})
344                         --carts:manage_attachment(clicker, self.object)
345
346                         -- player_api does not update the animation
347                         -- when the player is attached, reset to default animation
348                         
349                         --player_api.set_animation(clicker, "stand")
350                 end
351         end,
352         
353         on_activate = function(self,staticdata, dtime_s)
354                 self.object:set_armor_groups({immortal=1})
355                 if string.sub(staticdata, 1, string.len("return")) ~= "return" then
356                         return
357                 end
358                 local data = minetest.deserialize(staticdata)
359                 if type(data) ~= "table" then
360                         return
361                 end
362                 self.railtype = data.railtype
363                 if data.old_dir then
364                         self.old_dir = data.old_dir
365                 end
366         end,
367
368         get_staticdata = function(self)
369                 return minetest.serialize({
370                 })
371         end,
372         
373         on_punch = function(self,puncher, time_from_last_punch, tool_capabilities, dir, damage)
374                 local obj = minetest.add_item(self.object:getpos(), "minecart:minecart")
375                 self.object:remove()
376         end,
377
378         --repel from players on track "push"
379         push = function(self)
380                 if self.turn_timer > 0.3 then
381                         local pos = self.object:getpos()
382                         local radius = 1.2
383                         for _,object in ipairs(minetest.get_objects_inside_radius(pos, radius)) do
384                                 if object:is_player() and object:get_player_name() ~= self.rider then
385                                         local player_pos = object:getpos()
386                                         pos.y = 0
387                                         player_pos.y = 0
388                                         
389                                         local currentvel = self.object:getvelocity()
390                                         local vel = vector.subtract(pos, player_pos)
391                                         vel = vector.normalize(vel)
392                                         local distance = vector.distance(pos,player_pos)
393                                         distance = (radius-distance)*20
394                                         vel = vector.multiply(vel,distance)
395                                         local acceleration = vector.new(vel.x-currentvel.x,0,vel.z-currentvel.z)
396                                         
397                                         --note : set a maximum velocity that can be added to the cart to limit extreme glitches
398                                         
399                                         if self.axis == "x"     then
400                                                 self.object:add_velocity(vector.new(acceleration.x,0,0))
401                                         elseif self.axis == "z" then
402                                                 self.object:add_velocity(vector.new(0,0,acceleration.z))
403                                         else
404                                                 self.object:add_velocity(acceleration)
405                                         end
406                                         
407                                         --acceleration = vector.multiply(acceleration, -0.5)
408                                         --object:add_player_velocity(acceleration)
409                                 end
410                         end
411                 end
412         end,
413
414         --slows the minecart down
415         slowdown = function(self)
416                 if not self.moving == true then
417                         local vel = self.object:getvelocity()
418                         local deceleration = vector.multiply(vel, -0.01)
419                         self.object:add_velocity(deceleration)
420                 end
421         end,
422
423         --mechanics to follow rails
424         ride_rail = function(self,dtime)
425                 minecart_brain(self,dtime)
426         end,
427
428         on_step = function(self,dtime)
429                 self.push(self)
430                 self.slowdown(self)
431                 self.ride_rail(self,dtime)
432         end,
433         
434 })
435
436 minetest.register_craftitem("minecart:minecart", {
437         description = "Minecart",
438         inventory_image = "minecartitem.png",
439         wield_image = "minecartitem.png",
440         on_place = function(itemstack, placer, pointed_thing)
441                 if not pointed_thing.type == "node" then
442                         return
443                 end
444                 
445                 if minetest.get_item_group(minetest.get_node(pointed_thing.under).name, "rail")>0 then
446                         minetest.add_entity(pointed_thing.under, "minecart:minecart")
447                 else
448                         return
449                 end
450
451                 itemstack:take_item()
452
453                 return itemstack
454         end,
455 })
456
457 minetest.register_craft({
458         output = "minecart:minecart",
459         recipe = {
460                 {"main:iron", "", "main:iron"},
461                 {"main:iron", "main:iron", "main:iron"},
462         },
463 })