X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=mods%2Fmob%2Fapi%2Finteraction.lua;h=06b1702f85eb6ba3ac4651a3f432e03a203d5326;hb=f81b9d8e374cc524ede759f985be5f5f280e587b;hp=a98d8f4f8f522be16626a4d4c048a34c3f0f9f8c;hpb=dc5ca553e648c8230280a550c47679c894ef933e;p=Crafter.git diff --git a/mods/mob/api/interaction.lua b/mods/mob/api/interaction.lua index a98d8f4..06b1702 100644 --- a/mods/mob/api/interaction.lua +++ b/mods/mob/api/interaction.lua @@ -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 @@ -112,18 +147,25 @@ mobs.create_interaction_functions = function(def,mob_register) 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 + self.punched_timer = 0.25 if self.attacked_hostile then self.hostile = true 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 end end end + else + self.scared = true + self.scared_timer = 10 + end + if self.custom_on_punch then + self.custom_on_punch(self) end end @@ -136,7 +178,6 @@ mobs.create_interaction_functions = function(def,mob_register) self.hp = hp - self.direction = vector.multiply(dir,-1) dir = vector.multiply(dir,10) if vel.y <= 0 then dir.y = 4 @@ -151,7 +192,7 @@ mobs.create_interaction_functions = function(def,mob_register) 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 + self.punched_timer = 0.25 if self.attacked_hostile then self.hostile = true self.hostile_timer = 20 @@ -164,6 +205,9 @@ mobs.create_interaction_functions = function(def,mob_register) end end end + if self.custom_on_punch then + self.custom_on_punch(self) + end end self.death_animation_timer = 1 self.dead = true @@ -181,6 +225,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,19 +250,25 @@ 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(vector.new(pos.x,pos.y+0.1,pos.z),self.item_drop) + minetest.throw_item(vector.new(pos.x,pos.y+0.1,pos.z),item) end else - minetest.throw_item(vector.new(pos.x,pos.y+0.1,pos.z),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) @@ -232,11 +285,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 @@ -267,14 +319,18 @@ mobs.create_interaction_functions = function(def,mob_register) --punch the player if self.attack_type == "punch" then if distance < 2.5 and self.punch_timer <= 0 and object:get_hp() > 0 then - local line_of_sight = minetest.line_of_sight(pos, pos2) - if line_of_sight == true then - self.punch_timer = 1 - object:punch(self.object, 2, - { - full_punch_interval=1.5, - damage_groups = {fleshy=2}, - },vector.direction(pos,pos2)) + local meta = object:get_meta() + local player_punch_timer = meta:get_float("player_punch_timer") + if player_punch_timer <= 0 then + local line_of_sight = minetest.line_of_sight(pos, pos2) + if line_of_sight == true then + self.punch_timer = 0.25 + object:punch(self.object, 2, + { + full_punch_interval=1.5, + damage_groups = {damage=self.attack_damage}, + },vector.direction(pos,pos2)) + end end end elseif self.attack_type == "explode" then @@ -314,6 +370,10 @@ mobs.create_interaction_functions = function(def,mob_register) end self.speed = self.max_speed self.following = true + elseif self.scared == true then + self.speed = self.max_speed + self.direction = vector.direction(vector.new(pos2.x,0,pos2.z),vector.new(pos.x,0,pos.z)) + self.scared_timer = 10 end --only look at one player break