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