]> git.lizzy.rs Git - Crafter.git/blob - mods/mob/api/movement.lua
overhaul mob jumping to use raycasting and moveresult
[Crafter.git] / mods / mob / api / movement.lua
1 --
2 mobs.create_movement_functions = function(def,mob_register)
3         --makes the mob swim
4         mob_register.swim = function(self,dtime)
5                 local pos = self.object:get_pos()
6                 pos.y = pos.y + 0.3
7                 local node = minetest.get_node(pos).name
8                 self.swimming = false
9                 if node == "main:water" or node =="main:waterflow" then
10                         local vel = self.object:getvelocity()
11                         local goal = 3
12                         local acceleration = vector.new(0,goal-vel.y,0)
13                         --jump out of the water
14                         if (vel.x == 0 and self.direction.x ~= 0) or (vel.z == 0 and self.direction.z ~= 0) then
15                                 self.object:set_velocity(vector.new(vel.x,5,vel.z))
16                         --else swim
17                         else
18                                 self.object:add_velocity(acceleration)
19                         end
20                         self.swimming = true
21                 end
22         end
23
24         local get_group = minetest.get_item_group
25         local get_node = minetest.get_node
26         mob_register.hurt_inside = function(self,dtime)
27                 if self.hp > 0 and self.hurt_inside_timer <= 0 then
28                         local pos = self.object:get_pos()
29                         local hurty = get_group(get_node(pos).name, "hurt_inside")
30                         if hurty > 0 then
31                                 self.object:punch(self.object, 2, 
32                                         {
33                                         full_punch_interval=1.5,
34                                         damage_groups = {damage=hurty},
35                                 })
36                         end
37                 else
38                         self.hurt_inside_timer = self.hurt_inside_timer - dtime
39                 end
40         end
41
42         --This makes the mob walk at a certain speed and jump
43         if def.movement_type == "walk" then
44                 mob_register.move = function(self,dtime,moveresult)
45                         self.manage_jump_timer(self,dtime)
46                         self.timer = self.timer - dtime
47
48                         --jump
49                         self.jump(self,moveresult)
50                         
51                         --swim
52                         self.swim(self,dtime)
53                         
54                         --print(self.timer)
55                         --direction state change
56                         if self.timer <= 0 and not self.following == true then
57                                 --print("changing direction")
58                                 self.timer = math.random(2,7)
59                                 self.direction = vector.new(math.random()*math.random(-1,1),0,math.random()*math.random(-1,1))
60                                 --local yaw = self.object:get_yaw() + dtime
61                                 self.speed = math.random(0,self.max_speed)
62                                 --self.object:set_yaw(yaw)
63                         end
64
65                         self.hurt_inside(self,dtime)
66
67                         local currentvel = self.object:get_velocity()
68                         local goal = vector.multiply(self.direction,self.speed)
69                         local acceleration = vector.new(goal.x-currentvel.x,0,goal.z-currentvel.z)
70                         acceleration = vector.multiply(acceleration, 0.05)
71                         self.object:add_velocity(acceleration)
72                 end
73                 mob_register.jump = function(self,moveresult)
74                         if moveresult and moveresult.touching_ground and self.direction then
75                                 local pos = self.object:get_pos()
76                                 pos.y = pos.y+0.1
77                                 --assume collisionbox is even x and z
78                                 local modifier = self.object:get_properties().collisionbox[4]*3
79                                 
80
81                                 local pos2 = vector.add(vector.multiply(self.direction,modifier),pos)
82
83                                 local ray = minetest.raycast(pos, pos2, false, false)
84
85                                 if ray then
86                                         local pointed_thing = ray:next()
87                                         if pointed_thing then
88                                                 if minetest.get_nodedef(minetest.get_node(pointed_thing.under).name, "walkable") then
89                                                         minetest.add_particle({
90                                                                 pos = pointed_thing.intersection_point,
91                                                                 velocity = {x=0, y=0, z=0},
92                                                                 acceleration = {x=0, y=0, z=0},
93                                                                 expirationtime = 5,
94                                                                 size = 1,
95                                                                 texture = "dirt.png",
96                                                         })
97                                                         local vel = self.object:get_velocity()
98                                                         self.jump_timer = 1+math.random()
99                                                         self.object:set_velocity(vector.new(vel.x,5,vel.z))
100                                                 end
101                                         end
102                                 end
103                         end
104                 end
105         elseif def.movement_type == "jump" then
106                 mob_register.move = function(self,dtime,moveresult)
107                         self.manage_jump_timer(self,dtime)
108                         self.timer = self.timer - dtime
109                         
110                         --jump
111                         self.jump(self,moveresult)
112                         
113                         --swim
114                         self.swim(self,dtime)
115                         
116                         --print(self.timer)
117                         --direction state change
118                         if self.timer <= 0 and not self.following == true then
119                                 --print("changing direction")
120                                 self.timer = math.random(2,7)
121                                 self.direction = vector.new(math.random()*math.random(-1,1),0,math.random()*math.random(-1,1))
122                                 --local yaw = self.object:get_yaw() + dtime
123                                 self.speed = math.random(0,self.max_speed)
124                                 --self.object:set_yaw(yaw)
125                         end
126
127                         self.hurt_inside(self,dtime)    
128                         
129                         local currentvel = self.object:get_velocity()
130                         if currentvel.y ~= 0 then
131                                 local goal = vector.multiply(self.direction,self.speed)
132                                 local acceleration = vector.new(goal.x-currentvel.x,0,goal.z-currentvel.z)
133                                 acceleration = vector.multiply(acceleration, 0.05)
134                                 self.object:add_velocity(acceleration)
135                         end
136                 end
137                 
138                 mob_register.jump = function(self,moveresult)
139                         if moveresult and moveresult.touching_ground and self.direction then
140                                 if self.make_jump_noise then
141                                         minetest.sound_play("slime_splat", {object=self.object, gain = 1.0, max_hear_distance = 10,pitch = math.random(80,100)/100})
142                                 end
143                                 local vel = self.object:get_velocity()
144                                 self.object:set_velocity(vector.new(vel.x,5,vel.z))
145                                 if self.jump_timer <= 0 then
146                                         if self.hostile == true then
147                                                 self.jump_timer = 0.5
148                                         else
149                                                 self.jump_timer = 1+math.random()
150                                         end
151                                 else
152                                         self.object:set_velocity(vector.new(0,0,0))
153                                 end
154                         end
155                 end
156         end
157         
158         if def.pathfinds then
159
160
161         end
162         
163         return(mob_register)
164 end
165