]> git.lizzy.rs Git - Crafter.git/blob - mods/mob/api/movement.lua
Make combat a bit more fast paced
[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:get_velocity()
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                         self.hurt_inside_timer = 0.25
38                 else
39                         self.hurt_inside_timer = self.hurt_inside_timer - dtime
40                 end
41         end
42
43         --This makes the mob walk at a certain speed and jump
44         if def.movement_type == "walk" then
45                 mob_register.move = function(self,dtime,moveresult)
46                         self.manage_jump_timer(self,dtime)
47                         self.timer = self.timer - dtime
48
49                         --jump
50                         self.jump(self,moveresult)
51                         
52                         --swim
53                         self.swim(self,dtime)
54                         
55                         --print(self.timer)
56                         --direction state change
57                         if self.timer <= 0 and not self.following == true then
58                                 --print("changing direction")
59                                 self.timer = math.random(2,7)
60                                 self.direction = vector.new(math.random()*math.random(-1,1),0,math.random()*math.random(-1,1))
61                                 --local yaw = self.object:get_yaw() + dtime
62                                 self.speed = math.random(0,self.max_speed)
63                                 --self.object:set_yaw(yaw)
64                         end
65
66                         self.hurt_inside(self,dtime)
67
68                         local currentvel = self.object:get_velocity()
69                         local goal = vector.multiply(self.direction,self.speed)
70                         local acceleration = vector.new(goal.x-currentvel.x,0,goal.z-currentvel.z)
71                         acceleration = vector.multiply(acceleration, 0.05)
72                         self.object:add_velocity(acceleration)
73                 end
74                 mob_register.jump = function(self,moveresult)
75                         if moveresult and moveresult.touching_ground and self.direction then
76                                 local pos = self.object:get_pos()
77                                 pos.y = pos.y+0.1
78
79                                 if self.path_data and table.getn(self.path_data) > 0 then
80                                         --smart jump
81                                         local y = math.floor(pos.y+0.5)
82                                         local vel = self.object:get_velocity()
83                                         if y < self.path_data[1].y then
84                                                 self.object:set_velocity(vector.new(vel.x,5,vel.z))
85                                         elseif self.path_data[2] and y < self.path_data[2].y then
86                                                 self.object:set_velocity(vector.new(vel.x,5,vel.z))
87                                         elseif self.path_data[3] and y < self.path_data[3].y then
88                                                 self.object:set_velocity(vector.new(vel.x,5,vel.z))
89                                         elseif ((vel.x == 0 and self.direction.x ~= 0) or (vel.z == 0 and self.direction.z ~= 0)) then
90                                                 self.object:set_velocity(vector.new(vel.x,5,vel.z))
91                                         end
92                                 else
93                                         --assume collisionbox is even x and z
94                                         local modifier = self.object:get_properties().collisionbox[4]*3
95                                         
96
97                                         local pos2 = vector.add(vector.multiply(self.direction,modifier),pos)
98
99                                         local ray = minetest.raycast(pos, pos2, false, false)
100                                         
101                                         local pointed_thing
102
103                                         if ray then
104                                                 pointed_thing = ray:next()
105                                         end
106                                                 
107                                         if pointed_thing then
108                                                 if minetest.get_nodedef(minetest.get_node(pointed_thing.under).name, "walkable") then
109                                                         --print("jump")
110                                                         local vel = self.object:get_velocity()
111                                                         --self.jump_timer = 1+math.random()
112                                                         self.object:set_velocity(vector.new(vel.x,5,vel.z))
113                                                 else
114                                                         --print("velocity check")
115                                                         local vel = self.object:get_velocity()
116                                                         if (vel.x == 0 and self.direction.x ~= 0) or (vel.z == 0 and self.direction.z ~= 0) then
117                                                                 self.object:set_velocity(vector.new(vel.x,5,vel.z))
118                                                         end
119                                                 end
120                                         else
121                                                 --print("velcheck 2")
122                                                 local vel = self.object:get_velocity()
123                                                 if (vel.x == 0 and self.direction.x ~= 0) or (vel.z == 0 and self.direction.z ~= 0) then
124                                                         self.object:set_velocity(vector.new(vel.x,5,vel.z))
125                                                 end
126                                         end
127                                 end
128                         end
129                 end
130         elseif def.movement_type == "jump" then
131                 mob_register.move = function(self,dtime,moveresult)
132                         self.manage_jump_timer(self,dtime)
133                         self.timer = self.timer - dtime
134                         
135                         --jump
136                         self.jump(self,moveresult)
137                         
138                         --swim
139                         self.swim(self,dtime)
140                         
141                         --print(self.timer)
142                         --direction state change
143                         if self.timer <= 0 and not self.following == true then
144                                 --print("changing direction")
145                                 self.timer = math.random(2,7)
146                                 self.direction = vector.new(math.random()*math.random(-1,1),0,math.random()*math.random(-1,1))
147                                 --local yaw = self.object:get_yaw() + dtime
148                                 self.speed = math.random(0,self.max_speed)
149                                 --self.object:set_yaw(yaw)
150                         end
151
152                         self.hurt_inside(self,dtime)    
153                         
154                         local currentvel = self.object:get_velocity()
155                         if currentvel.y ~= 0 then
156                                 local goal = vector.multiply(self.direction,self.speed)
157                                 local acceleration = vector.new(goal.x-currentvel.x,0,goal.z-currentvel.z)
158                                 acceleration = vector.multiply(acceleration, 0.05)
159                                 self.object:add_velocity(acceleration)
160                         end
161                 end
162                 
163                 mob_register.jump = function(self,moveresult)
164                         if moveresult and moveresult.touching_ground and self.direction then
165                                 if self.jump_timer <= 0 then
166                                         if self.make_jump_noise then
167                                                 minetest.sound_play("slime_splat", {object=self.object, gain = 1.0, max_hear_distance = 10,pitch = math.random(80,100)/100})
168                                         end
169                                         local vel = self.object:get_velocity()
170                                         self.object:set_velocity(vector.new(vel.x,5,vel.z))
171                                         if self.following == true then
172                                                 self.jump_timer = 0.5
173                                         else
174                                                 self.jump_timer = 1+math.random()
175                                         end
176                                 else
177                                         self.object:set_velocity(vector.new(0,0,0))
178                                 end
179                         end
180                 end
181         end
182         
183         if def.pathfinds then
184                 mob_register.pathfinding = function(self,dtime)
185                         if self.following and self.following_pos then
186                                 self.pathfinding_timer = self.pathfinding_timer + dtime
187                                 if self.pathfinding_timer > 1 or not self.path_data then
188                                         self.pathfinding_timer = 0
189
190                                         local path = minetest.find_path(self.object:get_pos(),self.following_pos,self.view_distance*2,1,1,"A*")
191                                         
192                                         if path and not self.path_data or (self.path_data and table.getn(self.path_data) < 1) then
193                                                 self.path_data = path
194                                         end
195                                         --[[
196                                         if self.path_data then
197                                                 for index,pos_data in pairs(self.path_data) do
198                                                         --print(dump(pos_data))
199                                                         minetest.add_particle({
200                                                                 pos = pos_data,
201                                                                 velocity = {x=0, y=0, z=0},
202                                                                 acceleration = {x=0, y=0, z=0},
203                                                                 expirationtime = 1,
204                                                                 size = 1,
205                                                                 texture = "dirt.png",
206                                                         })
207                                                 end
208                                         end
209                                         ]]--
210                                 end
211                         elseif not self.following then
212                                 self.path_data = nil
213                         end
214
215
216                         --this is the real time one
217                         local selfpos = self.object:get_pos()
218                         local pos1 = vector.new(selfpos.x,0,selfpos.z)
219
220                         if (self.path_data and table.getn(self.path_data) > 0 and vector.distance(self.object:get_pos(),self.path_data[1]) > 2) or self.swimming == true then
221                                 self.path_data = nil
222                         end
223
224                         if self.path_data and table.getn(self.path_data) > 0 and vector.distance(pos1,vector.new(self.path_data[1].x,0,self.path_data[1].z)) < 1 then
225                                 --shift whole list down
226                                 for i = 2,table.getn(self.path_data) do
227                                         self.path_data[i-1] = self.path_data[i]
228                                 end
229                                 self.path_data[table.getn(self.path_data)] = nil
230                         end
231                 end
232         end
233         
234         return(mob_register)
235 end
236