1 --this is where all the code is stored for the pig mob's head
3 --converts the degrees to radians
4 local degrees_to_radians = function(degrees)
6 return(degrees/180.0*math.pi)
9 --converts yaw to degrees
10 local degrees = function(yaw)
12 return(yaw*180.0/math.pi)
15 --rounds it up to an integer
16 local degree_round = function(degree)
17 return(degree + 0.5 - (degree + 0.5) % 1)
19 --turns radians into degrees - not redundant
21 local radians_to_degrees = function(radians)
22 return(radians*180.0/math.pi)
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)
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)
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)
44 local radians = head_rotation_to_radians(head_rotation)
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)
50 local convert_to_pitch = minetest.yaw_to_dir(radians.z)
51 dir.y = convert_to_pitch.x * math.pi/1.5
54 local pos = self.head_pos
56 local pos2 = vector.add(pos,vector.multiply(dir,self.view_distance))
58 return(minetest.raycast(pos, pos2, false, true))
62 --this makes a mob check if they're about to walk off a cliff
63 mob.look_below = function(self)
65 local yaw = degrees_to_radians(self.yaw+180)
66 local dir = minetest.yaw_to_dir(yaw)
67 local pos = self.object:get_pos()
69 local ray_pos = vector.add(dir,pos)
71 local pos_below = vector.new(ray_pos.x,ray_pos.y - 5,ray_pos.z)
73 minetest.add_particle({
75 velocity = {x=0, y=0, z=0},
76 acceleration = {x=0, y=0, z=0},
79 collisiondetection = false,
82 playername = "singleplayer"
85 return(minetest.raycast(ray_pos, pos_below, false, true))
89 --a movement test to move the head
90 mob.move_head = function(self,pos2)
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
102 --pos is where the head actually is
103 pos = vector.add(pos,dir)
105 --use this to literally look around
109 --if the function was given a pos
112 local head_yaw = degree_round(degrees(minetest.dir_to_yaw(vector.direction(pos,pos2))))
114 local new_yaw = (body_yaw-head_yaw)
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
123 local triangle = vector.new(vector.distance(pos,pos2),0,pos2.y-pos.y)
125 local tri_yaw = minetest.dir_to_yaw(triangle)+(math.pi/2)
127 pitch = radians_to_degrees(tri_yaw)
129 pitch = math.floor(pitch+90 + 0.5)
132 local goal_yaw = 180-new_yaw
135 goal_yaw = goal_yaw + 360
138 if goal_yaw > 360 then
139 goal_yaw = goal_yaw - 360
142 local current_yaw = self.head_rotation.y
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
153 if math.abs(math.abs(goal_yaw) - math.abs(current_yaw)) <= 4 then
155 --print(math.abs(goal_yaw) - math.abs(current_yaw))
156 current_yaw = goal_yaw
158 --print(" NOT SKIPPING")
159 --print(math.abs(goal_yaw) - math.abs(current_yaw))
163 local goal_pitch = pitch
165 local current_pitch = self.head_rotation.z
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
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)
178 self.return_head_to_origin(self)
182 --if nothing to look at
184 --print("not looking")
185 self.return_head_to_origin(self)
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
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
201 rotation.y = rotation.y - 2
202 elseif rotation.y < 180 then
203 if rotation.y < 0 then
204 rotation.y = rotation.y + 360
206 rotation.y = rotation.y + 2
209 if math.abs(rotation.y)+1 == 180 then
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
220 rotation.z = math.floor(rotation.z + 0.5)
221 rotation.y = math.floor(rotation.y + 0.5)
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