]> git.lizzy.rs Git - Crafter.git/blob - mods/mob/head_code.lua
Make pigs follow players and jump properly
[Crafter.git] / mods / mob / head_code.lua
1 --this is where all the code is stored for the pig mob's head
2
3 --converts the degrees to radians
4 local degrees_to_radians = function(degrees)
5         --print(d)
6         return(degrees/180.0*math.pi)
7 end
8
9 --converts yaw to degrees
10 local degrees = function(yaw)
11         yaw = yaw + math.pi
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 --this is the "eyes" of the mob
39 mob.raycast_look = function(self,dtime)
40         if self.head_rotation and self.head_pos and self.yaw then
41                 --clone the memory as to not overwrite
42                 local head_rotation = table.copy(self.head_rotation)
43                 
44                 local radians = head_rotation_to_radians(head_rotation)
45                 
46                 --get the real rotation of the head in radians
47                 local real_yaw = degrees_to_radians(self.yaw+180)+radians.y
48                 local dir = vector.multiply(minetest.yaw_to_dir(real_yaw),2)
49                 
50                 local convert_to_pitch = minetest.yaw_to_dir(radians.z)
51                 dir.y = convert_to_pitch.x * math.pi/1.5
52                 
53                 
54                 local pos = self.head_pos
55                 
56                 local pos2 = vector.add(pos,vector.multiply(dir,self.view_distance))
57                 
58                 return(minetest.raycast(pos, pos2, false, true))
59         end
60 end
61
62 --this makes a mob check if they're about to walk off a cliff
63 mob.look_below = function(self)
64         if self.yaw then
65                 local yaw = degrees_to_radians(self.yaw+180)
66                 local dir = minetest.yaw_to_dir(yaw)
67                 local pos = self.object:get_pos()
68                 
69                 local ray_pos = vector.add(dir,pos)
70                 
71                 local pos_below = vector.new(ray_pos.x,ray_pos.y - 5,ray_pos.z)
72                 
73                 minetest.add_particle({
74                         pos = ray_pos,
75                         velocity = {x=0, y=0, z=0},
76                         acceleration = {x=0, y=0, z=0},
77                         expirationtime = 1,
78                         size = 1,
79                         collisiondetection = false,
80                         vertical = false,
81                         texture = "wood.png",
82                         playername = "singleplayer"
83                 })
84                 
85                 return(minetest.raycast(ray_pos, pos_below, false, true))
86         end
87 end
88
89 --a movement test to move the head
90 mob.move_head = function(self,pos2)
91         if self.child then
92                 --print(self.head_rotation.y)
93                 --if passed a direction to look
94                 local pos = self.object:get_pos()
95                 local body_yaw = self.object:get_yaw() - (math.pi/2)
96                 local dir = vector.multiply(minetest.yaw_to_dir(body_yaw),0.72)
97                 local real_dir = minetest.yaw_to_dir(body_yaw)
98                 local body_yaw = degree_round(degrees(minetest.dir_to_yaw(dir)))
99                 --save the yaw for debug
100                 self.yaw = body_yaw
101                 
102                 --pos is where the head actually is
103                 pos = vector.add(pos,dir)
104                 pos.y = pos.y + 0.36
105                 --use this to literally look around
106                 self.head_pos = pos
107                 
108                 
109                 --if the function was given a pos
110                 if pos2 then
111
112                         local head_yaw  = degree_round(degrees(minetest.dir_to_yaw(vector.direction(pos,pos2))))                        
113                         
114                         local new_yaw = (body_yaw-head_yaw)
115
116                         local pitch = 0 
117                         local roll = 0
118                         
119                         --print(self.head_rotation.y)
120                         if math.abs(new_yaw) <= 90 or math.abs(new_yaw) >= 270 then
121                                 --do other calculations on pitch and roll
122                                 
123                                 local triangle = vector.new(vector.distance(pos,pos2),0,pos2.y-pos.y)
124                                 
125                                 local tri_yaw = minetest.dir_to_yaw(triangle)+(math.pi/2)
126                                 
127                                 pitch = radians_to_degrees(tri_yaw)
128                                 
129                                 pitch = math.floor(pitch+90 + 0.5)
130                                 
131                                 
132                                 local goal_yaw = 180-new_yaw
133                                 
134                                 if goal_yaw < 0 then
135                                         goal_yaw = goal_yaw + 360
136                                 end
137                                 
138                                 if goal_yaw > 360 then
139                                         goal_yaw = goal_yaw - 360
140                                 end
141                                 
142                                 local current_yaw = self.head_rotation.y
143                                 
144                                 if goal_yaw > current_yaw then
145                                         current_yaw = current_yaw + 4
146                                 elseif goal_yaw < current_yaw then
147                                         current_yaw = current_yaw - 4
148                                 end
149                                 
150                                 --print(current_yaw)
151                                 
152                                 --stop jittering
153                                 if math.abs(math.abs(goal_yaw) - math.abs(current_yaw)) <= 4 then
154                                         --print("skipping:")
155                                         --print(math.abs(goal_yaw) - math.abs(current_yaw))
156                                         current_yaw = goal_yaw
157                                 else
158                                         --print(" NOT SKIPPING")
159                                         --print(math.abs(goal_yaw) - math.abs(current_yaw))
160                                 end
161                                 
162                                 
163                                 local goal_pitch = pitch
164                                 
165                                 local current_pitch = self.head_rotation.z
166                                 
167                                 if goal_pitch > current_pitch then
168                                         current_pitch = current_pitch + 1
169                                 elseif goal_pitch < current_pitch then
170                                         current_pitch = current_pitch - 1
171                                 end
172                                 
173                                 self.child:set_attach(self.object, "", vector.new(2.4,1.2,0), vector.new(180,    current_yaw,    180))
174                                 self.child:set_animation({x=current_pitch,y=current_pitch}, 15, 0, true)        
175                                 self.head_rotation = vector.new(180,    current_yaw,    current_pitch)
176                         --nothing to look at
177                         else
178                                 self.return_head_to_origin(self)
179                         end
180                         --                                                                      roll        newyaw      pitch
181                         
182                 --if nothing to look at
183                 else
184                         --print("not looking")
185                         self.return_head_to_origin(self)
186                 end
187         end
188 end
189
190
191 --this sets the mob to move it's head back to pointing forwards
192 mob.return_head_to_origin = function(self)
193         --print("setting back to origin")
194         local rotation = self.head_rotation
195         
196         --make the head yaw move back twice as fast 
197         if rotation.y > 180 then
198                 if rotation.y > 360 then
199                         rotation.y = rotation.y - 360
200                 end
201                 rotation.y = rotation.y - 2
202         elseif rotation.y < 180 then
203                 if rotation.y < 0 then
204                         rotation.y = rotation.y + 360
205                 end
206                 rotation.y = rotation.y + 2
207         end
208         --finish rotation
209         if math.abs(rotation.y)+1 == 180 then
210                 rotation.y = 180
211         end
212         --move up down (pitch) back to center
213         if rotation.z > 90 then
214                 rotation.z = rotation.z - 1
215         elseif rotation.z < 90 then
216                 rotation.z = rotation.z + 1
217         end
218         
219         
220         rotation.z = math.floor(rotation.z + 0.5)
221         rotation.y = math.floor(rotation.y + 0.5)
222         --print(rotation.y)
223         self.child:set_attach(self.object, "", vector.new(2.4,1.2,0), vector.new(180,    rotation.y,    180))
224         self.child:set_animation({x=rotation.z,y=rotation.z}, 15, 0, true)
225         self.head_rotation = rotation
226 end