]> git.lizzy.rs Git - Crafter.git/blob - mods/mob/api/head_code.lua
Make mobs navigate even better
[Crafter.git] / mods / mob / api / head_code.lua
1 local
2 minetest,math,vector
3 =
4 minetest,math,vector
5
6 --converts the degrees to radians
7 local degrees_to_radians = function(degrees)
8         --print(d)
9         return(degrees/180.0*math.pi)
10 end
11
12 --converts yaw to degrees
13 local degrees = function(yaw)
14         return(yaw*180.0/math.pi)
15 end
16
17 --rounds it up to an integer
18 local degree_round = function(degree)
19         return(degree + 0.5 - (degree + 0.5) % 1)
20 end
21 --turns radians into degrees - not redundant
22 --doesn't add math.pi
23 local radians_to_degrees = function(radians)
24         return(radians*180.0/math.pi)
25 end
26
27 --make sure this is redefined as shown below aka
28 --don't run mob_rotation_degree_to_radians(rotation)
29 --run local radians = mob_rotation_degree_to_radians(rotation)
30 --or the mobs head rotation will become overwritten
31 local head_rotation_to_radians = function(rotation)
32         return{
33                 x = 0, --roll should never be changed
34                 y = degrees_to_radians(180 - rotation.y)*-1,
35                 z = degrees_to_radians(90 - rotation.z)
36         }
37 end
38
39 --
40
41 local pos
42 local body_yaw
43 local head_yaw
44 local dir
45 local head_position
46 local head_rotation
47 mobs.create_head_functions = function(def,mob_register) 
48         --a movement test to move the head
49         mob_register.move_head = function(self,pos2,dtime)
50                 if self.head_bone then
51                         if self.head_coord == "horizontal" then
52                                 --print(self.head_bone)
53                                 head_position,head_rotation = self.object:get_bone_position(self.head_bone)
54                                 --[[ debug
55                                 if rotation then
56                                         --print("--------------------------------")
57                                         --rotation.x = rotation.x + 1
58                                         rotation.z = rotation.z + 1
59                                         rotation.y = 0
60                                         
61                                         if rotation.x > 90 then
62                                                  rotation.x = -90
63                                         end
64                                         if rotation.z > 90 then
65                                                  rotation.z = -90
66                                         end
67                                         
68                                         --print(rotation.x)
69                                         self.object:set_bone_position(self.head_bone, head_position, rotation)
70                                 end
71                                 ]]--
72
73                                 --if passed a direction to look
74                                 pos = self.object:get_pos()
75                                 body_yaw = self.object:get_yaw()-math.pi/2+self.rotational_correction
76                                                                 
77                                 dir = vector.multiply(minetest.yaw_to_dir(body_yaw),self.head_directional_offset)
78                                 
79                                 
80                                 body_yaw = minetest.dir_to_yaw(dir)
81                                 
82                                 --pos is where the head actually is
83                                 pos = vector.add(pos,dir)
84                                 pos.y = pos.y + self.head_height_offset
85                                 
86                                 --use this to literally look around
87                                 --self.head_pos = pos
88                                 
89                                 --if self.debug_head_pos == true then
90                                 --      minetest.add_particle({
91                                 --              pos = pos,
92                                 --              velocity = {x=0, y=0, z=0},
93                                 --              acceleration = {x=0, y=0, z=0},
94                                 --              expirationtime = 0.2,
95                                 --              size = 1,
96                                 --              texture = "dirt.png",
97                                 --      })
98                                 --end
99                                 
100                                 --if the function was given a pos
101                                 if pos2 then
102                                         --compare the head yaw to the body
103                                         --we must do a bunch of calculations to correct
104                                         --strange function returns
105                                         --for some reason get_yaw is offset 90 degrees
106                                         head_yaw = minetest.dir_to_yaw(vector.direction(pos,pos2))
107                                         head_yaw = minetest.dir_to_yaw(minetest.yaw_to_dir(head_yaw))
108                                         head_yaw = degrees(head_yaw)-degrees(body_yaw)
109
110                                         if head_yaw < -180 then
111                                                 head_yaw = head_yaw + 360
112                                         elseif head_yaw > 180 then
113                                                 head_yaw = head_yaw - 360
114                                         end
115
116                                         --if within range then do calculations
117                                         if head_yaw >= -90 and head_yaw <= 90 then
118                                                 ---begin pitch calculation
119                                                 --feed a 2D coordinate flipped into dir to yaw to calculate pitch
120                                                 head_rotation.x = degrees(minetest.dir_to_yaw(vector.new(vector.distance(vector.new(pos.x,0,pos.z),vector.new(pos2.x,0,pos2.z)),0,pos.y-pos2.y))+(math.pi/2))
121                                                 if self.flip_pitch then
122                                                         head_rotation.x = head_rotation.x * -1
123                                                 end
124                                                 head_rotation.z = head_yaw
125                                                 self.object:set_bone_position(self.head_bone, head_position, head_rotation)
126                                                 return(true)
127                                         --nothing to look at
128                                         else
129                                                 self.return_head_to_origin(self,dtime)
130                                                 return(false)
131                                         end
132                                         
133                                 --if nothing to look at
134                                 else
135                                         self.return_head_to_origin(self,dtime)
136                                         return(false)
137                                 end
138
139                         elseif self.head_coord == "vertical" then
140                                 --print(self.head_bone)
141                                 head_position,head_rotation = self.object:get_bone_position(self.head_bone)
142                                 --[[ debug
143                                 if rotation then
144                                         --print("--------------------------------")
145                                         --rotation.x = rotation.x + 1
146                                         rotation.z = rotation.z + 1
147                                         rotation.y = 0
148                                         
149                                         if rotation.x > 90 then
150                                                  rotation.x = -90
151                                         end
152                                         if rotation.z > 90 then
153                                                  rotation.z = -90
154                                         end
155                                         
156                                         --print(rotation.x)
157                                         self.object:set_bone_position(self.head_bone, head_position, rotation)
158                                 end
159                                 ]]--
160                                 
161                                 --print(self.head_rotation.y)
162                                 --if passed a direction to look
163                                 pos = self.object:get_pos()
164                                 body_yaw = self.object:get_yaw()-math.pi/2+self.rotational_correction
165                                                                 
166                                 dir = vector.multiply(minetest.yaw_to_dir(body_yaw),self.head_directional_offset)
167                                 
168                                 
169                                 body_yaw = minetest.dir_to_yaw(dir)
170                                 
171                                 --pos is where the head actually is
172                                 pos = vector.add(pos,dir)
173                                 pos.y = pos.y + self.head_height_offset
174                                 
175                                 --use this to literally look around
176                                 --self.head_pos = pos
177                                 
178                                 --if self.debug_head_pos == true then
179                                 --      minetest.add_particle({
180                                 --              pos = pos,
181                                 --              velocity = {x=0, y=0, z=0},
182                                 --              acceleration = {x=0, y=0, z=0},
183                                 --              expirationtime = 0.2,
184                                 --              size = 1,
185                                 --              texture = "dirt.png",
186                                 --      })
187                                 --end
188                                 
189                                 --if the function was given a pos
190                                 if pos2 then
191                                         --compare the head yaw to the body
192                                         --we must do a bunch of calculations to correct
193                                         --strange function returns
194                                         --for some reason get_yaw is offset 90 degrees
195                                         head_yaw = minetest.dir_to_yaw(vector.direction(pos,pos2))
196                                         head_yaw = minetest.dir_to_yaw(minetest.yaw_to_dir(head_yaw))
197                                         head_yaw = degrees(head_yaw)-degrees(body_yaw)
198
199                                         if head_yaw < -180 then
200                                                 head_yaw = head_yaw + 360
201                                         elseif head_yaw > 180 then
202                                                 head_yaw = head_yaw - 360
203                                         end
204
205                                         --if within range then do calculations
206                                         if head_yaw >= -90 and head_yaw <= 90 then
207                                                 ---begin pitch calculation
208                                                 --feed a 2D coordinate flipped into dir to yaw to calculate pitch
209                                                 head_rotation.x = degrees(minetest.dir_to_yaw(vector.new(vector.distance(vector.new(pos.x,0,pos.z),vector.new(pos2.x,0,pos2.z)),0,pos.y-pos2.y))+(math.pi/2))
210                                                 if self.flip_pitch then
211                                                         head_rotation.x = head_rotation.x * -1
212                                                 end
213                                                 head_rotation.y = -head_yaw
214                                                 self.object:set_bone_position(self.head_bone, head_position, head_rotation)
215                                                 return(true)
216                                         --nothing to look at
217                                         else
218                                                 self.return_head_to_origin(self,dtime)
219                                                 return(false)
220                                         end
221                                         
222                                 --if nothing to look at
223                                 else
224                                         self.return_head_to_origin(self,dtime)
225                                         return(false)
226                                 end
227                         end
228                 end
229         end
230         
231         
232         --this sets the mob to move it's head back to pointing forwards
233
234         mob_register.return_head_to_origin = function(self,dtime)
235                 head_position,head_rotation = self.object:get_bone_position(self.head_bone)
236                 
237                 if self.head_coord == "horizontal" then 
238                         --make the head yaw move back
239                         if head_rotation.x > 0 then
240                                 head_rotation.x = head_rotation.x - (dtime*100)
241                         elseif head_rotation.x < 0 then
242                                 head_rotation.x = head_rotation.x + (dtime*100)
243                         end
244                         
245                         if math.abs(head_rotation.x) < (dtime*100) then
246                                 head_rotation.x = 0
247                         end
248                         
249                         
250                         --move up down (pitch) back to center
251                         if head_rotation.z > 0 then
252                                 head_rotation.z = head_rotation.z - (dtime*100)
253                         elseif head_rotation.z < 0 then
254                                 head_rotation.z = head_rotation.z + (dtime*100)
255                         end
256                         
257                         if math.abs(head_rotation.z) < (dtime*100) then
258                                 head_rotation.z = 0
259                         end
260                 elseif self.head_coord == "vertical" then
261                         --make the head yaw move back
262                         if head_rotation.x > 0 then
263                                 head_rotation.x = head_rotation.x - (dtime*100)
264                         elseif head_rotation.x < 0 then
265                                 head_rotation.x = head_rotation.x + (dtime*100)
266                         end
267                         
268                         if math.abs(head_rotation.x) < (dtime*100) then
269                                 head_rotation.x = 0
270                         end
271                         
272                         
273                         --move up down (pitch) back to center
274                         if head_rotation.y > 0 then
275                                 head_rotation.y = head_rotation.y - (dtime*100)
276                         elseif head_rotation.y < 0 then
277                                 head_rotation.y = head_rotation.y + (dtime*100)
278                         end
279                         
280                         if math.abs(head_rotation.y) < (dtime*100) then
281                                 head_rotation.y = 0
282                         end
283                 end
284                 self.object:set_bone_position(self.head_bone, head_position, head_rotation)
285         end
286         return(mob_register)
287 end