1 --this is where mobs are defined
4 local path = minetest.get_modpath(minetest.get_current_modname())
6 dofile(path.."/spawning.lua")
7 dofile(path.."/items.lua")
11 minetest.register_entity("mob:pig", {
12 initial_properties = {
15 collide_with_objects = false,
16 collisionbox = {-0.37, -0.01, -0.37, 0.37, 0.865, 0.37},
18 visual_size = {x = 3, y = 3},
21 "nothing.png", -- baby
23 "nothing.png", -- saddle
27 automatic_face_movement_dir = -90.0,
28 automatic_face_movement_max_rotation_per_sec = 300,
34 direction_timer_goal = 0,
35 direction_change = false,
36 change_direction = false,
38 direction_goal = vector.new(0,0,0),
43 get_staticdata = function(self)
44 return minetest.serialize({
50 on_activate = function(self, staticdata, dtime_s)
51 self.object:set_armor_groups({immortal = 1})
52 --self.object:set_velocity({x = math.random(-5,5), y = 5, z = math.random(-5,5)})
53 self.object:set_acceleration({x = 0, y = -9.81, z = 0})
54 if string.sub(staticdata, 1, string.len("return")) == "return" then
55 local data = minetest.deserialize(staticdata)
56 if data and type(data) == "table" then
57 --self.range = data.range
61 self.object:set_animation({x=0,y=40}, 20, 0, true)
62 self.object:set_hp(self.hp)
65 on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, dir)
67 local hurt = tool_capabilities.damage_groups.fleshy
71 local hp = self.object:get_hp()
72 self.object:set_hp(hp-hurt)
74 minetest.sound_play("hurt", {object=self.object, gain = 1.0, max_hear_distance = 60,pitch = math.random(80,100)/100})
79 on_death = function(self, killer)
80 local pos = self.object:getpos()
82 minetest.sound_play("mob_die", {pos = pos, gain = 1.0})
83 minetest.add_particlespawner({
88 minvel = vector.new(-5,-5,-5),
89 maxvel = vector.new(5,5,5),
90 minacc = {x=0, y=0, z=0},
91 maxacc = {x=0, y=0, z=0},
96 collisiondetection = false,
98 texture = "smoke.png",
100 local obj = minetest.add_item(pos,"mob:raw_porkchop")
104 push = function(self)
105 local pos = self.object:getpos()
107 for _,object in ipairs(minetest.get_objects_inside_radius(pos, radius)) do
108 if object:is_player() or object:get_luaentity().mob == true then
109 local player_pos = object:getpos()
113 local currentvel = self.object:getvelocity()
114 local vel = vector.subtract(pos, player_pos)
115 vel = vector.normalize(vel)
116 local distance = vector.distance(pos,player_pos)
117 distance = (radius-distance)*10
118 vel = vector.multiply(vel,distance)
119 local acceleration = vector.new(vel.x-currentvel.x,0,vel.z-currentvel.z)
122 self.object:add_velocity(acceleration)
124 acceleration = vector.multiply(acceleration, -0.5)
125 object:add_player_velocity(acceleration)
130 --this is the brain of the mob
131 logic = function(self,dtime)
132 if not self.path then
135 self.delete_path_node(self)
137 if self.path and table.getn(self.path) > 0 then
138 for _,p in pairs(self.path) do
139 minetest.add_particle({
141 velocity = {x=0, y=0, z=0},
142 acceleration = {x=0, y=0, z=0},
143 expirationtime = 0.1,
145 collisiondetection = false,
147 texture = "wood.png",
155 delete_path_node = function(self)
156 local pos = self.object:getpos()
158 local goalnode = self.path[1]
160 local distance = vector.distance(pos,goalnode)
162 if distance < 0.01 then
163 print("deleting path node")
164 table.remove(self.path, 1)
166 if table.getn(self.path) < 1 then
171 path_find = function(self)
172 local pos2 = self.find_position(self)
173 if not self.path and pos2 then
174 local pos = vector.floor(vector.add(self.object:getpos(),0.5))
175 local path = minetest.find_path(pos,pos2,10,1,3,"A*")
184 --this sets a random position for the mob to go to when randomly walking around
185 find_position = function(self)
188 local pos = vector.floor(vector.add(self.object:getpos(),0.5))
189 local x = pos.x + math.random(-10,10)
190 local z = pos.z + math.random(-10,10)
193 local location = minetest.find_nodes_in_area_under_air(vector.new(x,pos.y-32,z), vector.new(x,pos.y+32,z), {"group:pathable"})
195 --print(dump(spawner))
196 if table.getn(location) > 0 then
197 local goal_pos = location[1]
198 goal_pos.y = goal_pos.y + 1
206 --This makes the mob walk at a certain speed
207 move = function(self)
209 local vel = self.object:getvelocity()
210 local pos = self.object:getpos()
212 local goal = self.path[1]
215 local dir = vector.normalize(vector.subtract(goal,pos))
216 local goal = vector.multiply(dir,2)
220 local acceleration = vector.new(goal.x-vel.x,0,goal.z-vel.z)
221 self.object:add_velocity(acceleration)
226 jump = function(self,punched)
228 local pos = self.object:getpos()
229 local pos2 = self.path[1]
231 --print(pos.y, pos2.y)
232 --print(pos.y - pos2.y)
233 if pos2.y > pos.y then
235 local vel = self.object:getvelocity()
237 local acceleration = vector.new(0,goal-vel.y,0)
238 self.object:add_velocity(acceleration)
244 swim = function(self)
245 local pos = self.object:getpos()
247 local node = minetest.get_node(pos).name
248 local vel = self.object:getvelocity()
250 local acceleration = vector.new(0,goal-vel.y,0)
251 self.swimming = false
253 if node == "main:water" or node =="main:waterflow" then
255 self.object:add_velocity(acceleration)
259 --sets the mob animation and speed
260 set_animation = function(self)
261 local distance = vector.distance(vector.new(0,0,0), self.object:getvelocity())
262 self.object:set_animation_frame_speed(distance*20)
265 on_step = function(self, dtime)
267 self.logic(self,dtime)
269 self.jump(self,false)
270 self.set_animation(self)