]> git.lizzy.rs Git - Crafter.git/blobdiff - mods/mob/api/interaction.lua
Implement armor defense and make mobs more powerful
[Crafter.git] / mods / mob / api / interaction.lua
index f276aefaa77b429291193a3e04de0b01819d7604..695c4760708b8b2772fbdb6af778acb03124f5c2 100644 (file)
@@ -39,29 +39,64 @@ mobs.create_interaction_functions = function(def,mob_register)
        mob_register.collision_detection = function(self)
                local pos = self.object:get_pos()
                --do collision detection from the base of the mob
-               pos.y = pos.y - self.object:get_properties().collisionbox[2]
-               for _,object in ipairs(minetest.get_objects_inside_radius(pos, self.collision_boundary)) do
-                       if object:is_player() or object:get_luaentity().mob == true then
+               
+               local collisionbox = self.object:get_properties().collisionbox
+
+               pos.y = pos.y + collisionbox[2]
+               
+               local collision_boundary = collisionbox[4]
+
+               local radius = collision_boundary
+
+               if collisionbox[5] > collision_boundary then
+                       radius = collisionbox[5]
+               end
+
+               for _,object in ipairs(minetest.get_objects_inside_radius(pos, radius*1.25)) do
+                       if object ~= self.object and (object:is_player() or object:get_luaentity().mob == true) and
+                       --don't collide with rider, rider don't collide with thing
+                       (not object:get_attach() or (object:get_attach() and object:get_attach() ~= self.object)) and 
+                       (not self.object:get_attach() or (self.object:get_attach() and self.object:get_attach() ~= object)) then
+
                                local pos2 = object:get_pos()
                                
-                               local dir = vector.direction(pos,pos2)
-                               dir.y = 0
-                               
-                               --eliminate mob being stuck in corners
-                               if dir.x == 0 and dir.z == 0 then
-                                       dir = vector.new(math.random(-1,1)*math.random(),0,math.random(-1,1)*math.random())
-                               end
-                               
-                               local velocity = vector.multiply(dir,1.1)
-                               
-                               local vel1 = vector.multiply(velocity, -1)
-                               local vel2 = velocity
-                               self.object:add_velocity(vel1)
-                               
-                               if object:is_player() then
-                                       object:add_player_velocity(vel2)
-                               else
-                                       object:add_velocity(vel2)
+                               local object_collisionbox = object:get_properties().collisionbox
+
+                               pos2.y = pos2.y + object_collisionbox[2]
+
+                               local object_collision_boundary = object_collisionbox[4]
+
+
+                               --this is checking the difference of the object collided with's possision
+                               --if positive top of other object is inside (y axis) of current object
+                               local y_base_diff = (pos2.y + object_collisionbox[5]) - pos.y
+
+                               local y_top_diff = (pos.y + collisionbox[5]) - pos2.y
+
+
+                               local distance = vector.distance(vector.new(pos.x,0,pos.z),vector.new(pos2.x,0,pos2.z))
+
+                               if distance <= collision_boundary + object_collision_boundary and y_base_diff >= 0 and y_top_diff >= 0 then
+
+                                       local dir = vector.direction(pos,pos2)
+                                       dir.y = 0
+                                       
+                                       --eliminate mob being stuck in corners
+                                       if dir.x == 0 and dir.z == 0 then
+                                               dir = vector.new(math.random(-1,1)*math.random(),0,math.random(-1,1)*math.random())
+                                       end
+                                       
+                                       local velocity = vector.multiply(dir,1.1)
+                                       
+                                       local vel1 = vector.multiply(velocity, -1)
+                                       local vel2 = velocity
+                                       self.object:add_velocity(vel1)
+                                       
+                                       if object:is_player() then
+                                               object:add_player_velocity(vel2)
+                                       else
+                                               object:add_velocity(vel2)
+                                       end
                                end
                        end
                end
@@ -109,7 +144,7 @@ mobs.create_interaction_functions = function(def,mob_register)
                local hp = hp-hurt
 
                if (self.punched_timer <= 0 and hp > 1) and not self.dead then
-                       self.object:set_texture_mod("^[colorize:red:130")
+                       self.object:set_texture_mod("^[colorize:"..self.damage_color..":130")
                        self.hurt_color_timer = 0.25
                        if puncher ~= self.object then
                                self.punched_timer = 0.8
@@ -118,6 +153,7 @@ mobs.create_interaction_functions = function(def,mob_register)
                                        self.hostile_timer = 20
                                        if self.group_attack == true then
                                                for _,object in ipairs(minetest.get_objects_inside_radius(pos, self.view_distance)) do
+
                                                        if not object:is_player() and object:get_luaentity() and object:get_luaentity().mobname == self.mobname then
                                                                object:get_luaentity().hostile = true
                                                                object:get_luaentity().hostile_timer = 20
@@ -148,7 +184,7 @@ mobs.create_interaction_functions = function(def,mob_register)
                        self.object:add_velocity(dir)
                        self.add_sword_wear(self, puncher, time_from_last_punch, tool_capabilities, dir)
                elseif (self.punched_timer <= 0 and self.death_animation_timer == 0) then
-                       self.object:set_texture_mod("^[colorize:red:130")
+                       self.object:set_texture_mod("^[colorize:"..self.damage_color..":130")
                        self.hurt_color_timer = 0.25
                        if puncher ~= self.object then
                                self.punched_timer = 0.8
@@ -181,6 +217,9 @@ mobs.create_interaction_functions = function(def,mob_register)
        --this is what happens when a mob dies
        mob_register.on_death = function(self, killer)
                local pos = self.object:get_pos()
+               if def.hp then
+                       minetest.throw_experience(pos,math.ceil(def.hp/5)+math.random(0,1))
+               end
                --pos.y = pos.y + 0.4
                minetest.sound_play("mob_die", {pos = pos, gain = 1.0})
                minetest.add_particlespawner({
@@ -203,20 +242,30 @@ mobs.create_interaction_functions = function(def,mob_register)
                
                --only throw items if registered
                if self.item_drop then
+                       local item
+                       if type(self.item_drop) == "string" then
+                               item = self.item_drop
+                       elseif type(self.item_drop) == "table" then
+                               item = self.item_drop[math.random(1,table.getn(self.item_drop))]
+                       end
                        --detect if multiple items are going to be added
                        if self.item_max then
                                local data_item_amount = math.random(self.item_minimum, self.item_max)
                                for i = 1 ,data_item_amount do
-                                       minetest.throw_item(pos,self.item_drop)
+                                       minetest.throw_item(vector.new(pos.x,pos.y+0.1,pos.z),item)
                                end
                        else
-                               minetest.throw_item(pos,self.item_drop)
+                               minetest.throw_item(vector.new(pos.x,pos.y+0.1,pos.z),item)
                        end
                end
                        
                global_mob_amount = global_mob_amount - 1
-               print("Mobs Died. Current Mobs: "..global_mob_amount)
+               --print("Mobs Died. Current Mobs: "..global_mob_amount)
                
+               if self.custom_on_death then
+                       self.custom_on_death(self)
+               end
+
                self.object:remove()
        end
        
@@ -228,11 +277,10 @@ mobs.create_interaction_functions = function(def,mob_register)
                        local light_level = minetest.get_node_light(pos)
                        if light_level then
                                if (self.die_in_light == true and light_level > self.die_in_light_level) then
-                                       local damage = self.hp
                                        self.object:punch(self.object, 2, 
                                                {
                                                full_punch_interval=1.5,
-                                               damage_groups = {damage=damage},
+                                               damage_groups = {damage=2},
                                        })
                                end
                        end
@@ -258,7 +306,8 @@ mobs.create_interaction_functions = function(def,mob_register)
                                --print(self.hostile)
                                if self.hostile == true then
                                        local distance = vector.distance(pos,pos2)
-                                       
+                                       self.following_pos = vector.new(pos2.x,pos2.y-1.625,pos2.z)
+
                                        --punch the player
                                        if self.attack_type == "punch" then
                                                if distance < 2.5 and self.punch_timer <= 0 and object:get_hp() > 0 then
@@ -268,7 +317,7 @@ mobs.create_interaction_functions = function(def,mob_register)
                                                                object:punch(self.object, 2, 
                                                                        {
                                                                        full_punch_interval=1.5,
-                                                                       damage_groups = {fleshy=2},
+                                                                       damage_groups = {damage=self.attack_damage},
                                                                },vector.direction(pos,pos2))
                                                        end
                                                end
@@ -291,15 +340,22 @@ mobs.create_interaction_functions = function(def,mob_register)
                                                if self.projectile_timer <= 0 then
                                                        self.projectile_timer = self.projectile_timer_cooldown
                                                        
-                                                       local obj = minetest.add_entity(pos, self.projectile_type)
+                                                       local obj = minetest.add_entity(vector.new(pos.x,pos.y+self.object:get_properties().collisionbox[5],pos.z), self.projectile_type)
                                                        if obj then
-                                                               local dir = vector.multiply(vector.direction(pos,pos2), 50)
+                                                               local dir = vector.multiply(vector.direction(pos,vector.new(pos2.x,pos2.y-3,pos2.z)), 50)
                                                                obj:set_velocity(dir)
                                                                obj:get_luaentity().timer = 2
+                                                               obj:get_luaentity().owner = self.object
                                                        end
                                                end
                                        end
-                                       self.direction = vector.direction(vector.new(pos.x,0,pos.z),vector.new(pos2.x,0,pos2.z))
+                                       --smart
+                                       if self.path_data and table.getn(self.path_data) > 0 then
+                                               self.direction = vector.direction(vector.new(pos.x,0,pos.z), vector.new(self.path_data[1].x,0,self.path_data[1].z))
+                                       --dumb
+                                       else
+                                               self.direction = vector.direction(vector.new(pos.x,0,pos.z),vector.new(pos2.x,0,pos2.z))
+                                       end
                                        self.speed = self.max_speed
                                        self.following = true
                                end
@@ -309,7 +365,12 @@ mobs.create_interaction_functions = function(def,mob_register)
                end
                --stare straight if not found
                if player_found == false then
-                       self.move_head(self,nil,dtime)
+                       if self.move_head then
+                               self.move_head(self,nil,dtime)
+                       end
+                       if self.following_pos then
+                               self.following_pos = nil
+                       end
                        if self.manage_hostile_timer then
                                self.manage_hostile_timer(self,dtime)
                        end
@@ -317,4 +378,4 @@ mobs.create_interaction_functions = function(def,mob_register)
        end
        
        return(mob_register)
-end
+end
\ No newline at end of file