diff --git a/mods/ENTITIES/mcl_mobs/api/api.lua b/mods/ENTITIES/mcl_mobs/api/api.lua index 81be0878f5..5734ee1c72 100644 --- a/mods/ENTITIES/mcl_mobs/api/api.lua +++ b/mods/ENTITIES/mcl_mobs/api/api.lua @@ -156,6 +156,7 @@ dofile(api_path .. "environment.lua") dofile(api_path .. "interaction.lua") dofile(api_path .. "movement.lua") dofile(api_path .. "set_up.lua") +dofile(api_path .. "attack_type_instructions.lua") mobs.spawning_mobs = {} @@ -319,6 +320,8 @@ function mobs:register_mob(name, def) jump_only = def.jump_only, hostile = def.hostile, neutral = def.neutral, + attacking = nil, + visual_size_origin = def.visual_size or {x = 1, y = 1, z = 1}, --end j4i stuff -- MCL2 extensions diff --git a/mods/ENTITIES/mcl_mobs/api/mob_functions/ai.lua b/mods/ENTITIES/mcl_mobs/api/mob_functions/ai.lua index 5500d1b962..24942e3ec7 100644 --- a/mods/ENTITIES/mcl_mobs/api/mob_functions/ai.lua +++ b/mods/ENTITIES/mcl_mobs/api/mob_functions/ai.lua @@ -92,10 +92,9 @@ end local land_state_list_wandering = {"stand", "walk"} local land_state_switch = function(self, dtime) - - if self.hostile and attack then - self.state = + if self.hostile and self.attacking then + self.state = "attack" return end @@ -132,6 +131,11 @@ local land_state_execution = function(self,dtime) --set the velocity of the mob mobs.set_velocity(self,0) + --animation fixes for explosive mobs + if self.attack_type == "explode" then + mobs.reverse_explosion_animation(self,dtime) + end + elseif self.state == "walk" then self.walk_timer = self.walk_timer - dtime @@ -178,13 +182,20 @@ local land_state_execution = function(self,dtime) mobs.set_velocity(self,self.walk_velocity) end + --animation fixes for explosive mobs + if self.attack_type == "explode" then + mobs.reverse_explosion_animation(self,dtime) + end + elseif self.state == "run" then print("run") elseif self.state == "attack" then - print("attack") + if self.attack_type == "explode" then + mobs.explode_attack_walk(self, dtime) + end end @@ -587,6 +598,29 @@ mobs.mob_step = function(self, dtime) return false end + + if self.hostile then + --true for line_of_sight is debug + --10 for radius is debug + --1 for eye height adjust is debug + local attacking = mobs.detect_closest_player_within_radius(self,true,10,1) + + --go get the closest player ROAR >:O + if attacking then + self.attacking = attacking + --no player in area + else + + --reset states when coming out of hostile state + if self.attacking ~= nil then + self.state_timer = -1 + end + + self.attacking = nil + end + end + + --jump only (like slimes) if self.jump_only then jump_state_switch(self, dtime) @@ -606,21 +640,7 @@ mobs.mob_step = function(self, dtime) end - if self.hostile then - --true for line_of_sight is debug - --10 for radius is debug - --1 for eye height adjust is debug - local attacking = mobs.detect_closest_player_within_radius(self,true,10,1) - --go get the closest player ROAR >:O - if attacking then - self.attack = attacking - - --no player in area - else - self.attack = nil - end - end -- can mob be pushed, if so calculate direction -- do this last (overrides everything) if self.pushable then diff --git a/mods/ENTITIES/mcl_mobs/api/mob_functions/animation.lua b/mods/ENTITIES/mcl_mobs/api/mob_functions/animation.lua index 97d0f7894e..b7b8fa5748 100644 --- a/mods/ENTITIES/mcl_mobs/api/mob_functions/animation.lua +++ b/mods/ENTITIES/mcl_mobs/api/mob_functions/animation.lua @@ -1,11 +1,12 @@ local math_pi = math.pi local math_floor = math.floor +local math_random = math.random local HALF_PI = math_pi/2 - -local vector_distance = vector.distance -local vector_new = vector.new +local vector_direction = vector.direction +local vector_distance = vector.distance +local vector_new = vector.new local minetest_dir_to_yaw = minetest.dir_to_yaw @@ -114,6 +115,28 @@ mobs.movement_rotation_lock = function(self) end +--this is used when a mob is chasing a player +mobs.set_yaw_while_attacking = function(self) + + if self.object:get_properties().automatic_face_movement_dir then + self.object:set_properties{automatic_face_movement_dir = false} + end + + --turn positions into pseudo 2d vectors + local pos1 = self.object:get_pos() + pos1.y = 0 + + local pos2 = self.attacking:get_pos() + pos2.y = 0 + + local new_direction = vector_direction(pos1,pos2) + local new_yaw = minetest_dir_to_yaw(new_direction) + + self.object:set_yaw(new_yaw) + self.yaw = new_yaw +end + + local calculate_pitch = function(self) local pos = self.object:get_pos() local pos2 = self.old_pos @@ -156,4 +179,25 @@ mobs.set_static_pitch = function(self) self.object:set_rotation(current_rotation) self.pitch_switchfdas = "static" +end + +--this is a helper function for mobs explosion animation +mobs.handle_explosion_animation = function(self) + + --secondary catch-all + if not self.explosion_animation then + self.explosion_animation = 0 + end + + --the timer works from 0 for sense of a 0 based counting + --but this just bumps it up so it's usable in here + local explosion_timer_adjust = self.explosion_animation + 1 + + + local visual_size_modified = table.copy(self.visual_size_origin) + + visual_size_modified.x = visual_size_modified.x * (explosion_timer_adjust ^ 3) + visual_size_modified.y = visual_size_modified.y * explosion_timer_adjust + + self.object:set_properties({visual_size = visual_size_modified}) end \ No newline at end of file diff --git a/mods/ENTITIES/mcl_mobs/api/mob_functions/attack_type_instructions.lua b/mods/ENTITIES/mcl_mobs/api/mob_functions/attack_type_instructions.lua new file mode 100644 index 0000000000..53a6ced4be --- /dev/null +++ b/mods/ENTITIES/mcl_mobs/api/mob_functions/attack_type_instructions.lua @@ -0,0 +1,60 @@ +local vector_direction = vector.direction +local minetest_dir_to_yaw = minetest.dir_to_yaw +local vector_distance = vector.distance + + +mobs.explode_attack_walk = function(self,dtime) + + --this needs an exception + if self.attacking == nil or not self.attacking:is_player() then + self.attacking = nil + return + end + + mobs.set_yaw_while_attacking(self) + + --make mob walk up to player within 2 nodes distance then start exploding + + --THIS NEEDS TO BE RECODED TO TAKE COLLISION BOXES INTO ACCOUNT!!! + if vector_distance(self.object:get_pos(), self.attacking:get_pos()) >= self.reach then + mobs.set_velocity(self, self.run_velocity) + mobs.set_mob_animation(self,"run") + + mobs.reverse_explosion_animation(self,dtime) + else + mobs.set_velocity(self,0) + + --this is the only way I can reference this without dumping extra data on all mobs + if not self.explosion_animation then + self.explosion_animation = 0 + end + mobs.set_mob_animation(self,"stand") + + mobs.handle_explosion_animation(self) + + self.explosion_animation = self.explosion_animation + (dtime/3) + end + + + --do biggening explosion thing + if self.explosion_animation and self.explosion_animation > self.explosion_timer then + mcl_explosions.explode(self.object:get_pos(), self.explosion_strength) + self.object:remove() + end +end + + +--this is a small helper function to make working with explosion animations easier +mobs.reverse_explosion_animation = function(self,dtime) + + + --if explosion animation was greater than 0 then reverse it + if self.explosion_animation ~= nil and self.explosion_animation > 0 then + self.explosion_animation = self.explosion_animation - dtime + if self.explosion_animation < 0 then + self.explosion_animation = 0 + end + end + + mobs.handle_explosion_animation(self) +end \ No newline at end of file diff --git a/mods/ENTITIES/mobs_mc/creeper.lua b/mods/ENTITIES/mobs_mc/creeper.lua index 627ac50615..6c26b422fe 100644 --- a/mods/ENTITIES/mobs_mc/creeper.lua +++ b/mods/ENTITIES/mobs_mc/creeper.lua @@ -169,8 +169,8 @@ mobs:register_mob("mobs_mc:creeper_charged", { explosion_radius = 8, explosion_damage_radius = 8, explosiontimer_reset_radius = 6, - reach = 3, - explosion_timer = 1.5, + reach = 2, + explosion_timer = 0.75, allow_fuse_reset = true, stop_to_explode = true,