diff --git a/mods/ENTITIES/mcl_mobs/api/api.lua b/mods/ENTITIES/mcl_mobs/api/api.lua index 7723e16a69..b6054f281b 100644 --- a/mods/ENTITIES/mcl_mobs/api/api.lua +++ b/mods/ENTITIES/mcl_mobs/api/api.lua @@ -48,6 +48,9 @@ local math_floor = math.floor -- localize vector functions local vector_new = vector.new local vector_length = vector.length +local vector_direction = vector.direction +local vector_normalize = vector.normalize +local vector_multiply = vector.multiply -- mob constants local MAX_MOB_NAME_LENGTH = 30 @@ -324,7 +327,7 @@ function mobs:register_mob(name, def) attacking = nil, visual_size_origin = def.visual_size or {x = 1, y = 1, z = 1}, punch_timer_cooloff = def.punch_timer_cooloff or 0.5, - projectile_cooldown = projectile_cooldown or 2, + projectile_cooldown = def.projectile_cooldown or 2, --end j4i stuff -- MCL2 extensions @@ -439,9 +442,13 @@ end -- END mobs:register_mob function -- register arrow for shoot attack function mobs:register_arrow(name, def) - if not name or not def then return end -- errorcheck + -- errorcheck + if not name or not def then + print("failed to register arrow entity") + return + end - minetest.register_entity(name, { + minetest.register_entity(name.."_entity", { physical = false, visual = def.visual, @@ -458,15 +465,17 @@ function mobs:register_arrow(name, def) switch = 0, owner_id = def.owner_id, rotate = def.rotate, - on_punch = function(self) - local vel = self.object:get_velocity() - --self.object:set_velocity({x=vel.x * -1, y=vel.y * -1, z=vel.z * -1}) - local pos = self.object:get_pos() + speed = def.speed or nil, + on_step = function(self) - if self.switch == 0 - or self.timer > 150 - or not within_limits(pos, 0) then + local vel = self.object:get_velocity() + + local pos = self.object:get_pos() + + if self.timer > 150 + or not mobs.within_limits(pos, 0) then mcl_burning.extinguish(self.object) + print("removing 1") self.object:remove(); return @@ -491,7 +500,7 @@ function mobs:register_arrow(name, def) if self.hit_node then - local node = node_ok(pos).name + local node = minetest_get_node(pos).name if minetest_registered_nodes[node].walkable then @@ -519,32 +528,42 @@ function mobs:register_arrow(name, def) if self.hit_player and player:is_player() then - self.hit_player(self, player) + mobs.arrow_hit(self, player) + + print("wow everything is fucked") self.object:remove(); return end + --[[ local entity = player:get_luaentity() if entity and self.hit_mob and entity._cmi_is_mob == true and tostring(player) ~= self.owner_id - and entity.name ~= self.object:get_luaentity().name then - self.hit_mob(self, player) + and entity.name ~= self.object:get_luaentity().name + and (self._shooter and entity.name ~= self._shooter:get_luaentity().name) then + + --self.hit_mob(self, player) self.object:remove(); return end + ]]-- + --[[ if entity and self.hit_object and (not entity._cmi_is_mob) and tostring(player) ~= self.owner_id - and entity.name ~= self.object:get_luaentity().name then - self.hit_object(self, player) + and entity.name ~= self.object:get_luaentity().name + and (self._shooter and entity.name ~= self._shooter:get_luaentity().name) then + + --self.hit_object(self, player) self.object:remove(); return end + ]]-- end end diff --git a/mods/ENTITIES/mcl_mobs/api/mob_functions/ai.lua b/mods/ENTITIES/mcl_mobs/api/mob_functions/ai.lua index 4c85d9b3a5..11c61f20f4 100644 --- a/mods/ENTITIES/mcl_mobs/api/mob_functions/ai.lua +++ b/mods/ENTITIES/mcl_mobs/api/mob_functions/ai.lua @@ -338,6 +338,12 @@ ______ _ local fly_state_list_wandering = {"stand", "fly"} local fly_state_switch = function(self, dtime) + + if self.hostile and self.attacking then + self.state = "attack" + return + end + self.state_timer = self.state_timer - dtime if self.state_timer <= 0 then self.state_timer = math.random(4,10) + math.random() @@ -440,6 +446,22 @@ local fly_state_execution = function(self,dtime) end mobs.set_fly_velocity(self,self.walk_velocity) + elseif self.state == "attack" then + + --execute mob attack type + --if self.attack_type == "explode" then + + --mobs.explode_attack_fly(self, dtime) + + --elseif self.attack_type == "punch" then + + --mobs.punch_attack_fly(self,dtime) + + if self.attack_type == "projectile" then + + mobs.projectile_attack_fly(self,dtime) + + end end else --make the mob float 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 index 13aeea0875..e60c46aab1 100644 --- a/mods/ENTITIES/mcl_mobs/api/mob_functions/attack_type_instructions.lua +++ b/mods/ENTITIES/mcl_mobs/api/mob_functions/attack_type_instructions.lua @@ -3,6 +3,17 @@ local minetest_dir_to_yaw = minetest.dir_to_yaw local vector_distance = vector.distance local vector_multiply = vector.multiply +--[[ + _ _ _ _ +| | | | | | | | +| | | | __ _ _ __ __| | | | +| | | | / _` | '_ \ / _` | | | +|_| | |___| (_| | | | | (_| | |_| +(_) \_____/\__,_|_| |_|\__,_| (_) +]]-- + + + --[[ _____ _ _ | ___| | | | | @@ -215,4 +226,78 @@ mobs.projectile_attack_walk = function(self,dtime) mobs.jump(self) end +end + + + + + + + + + +--[[ + _ ______ _ _ +| | | ___| | | | +| | | |_ | |_ _ | | +| | | _| | | | | | | | +|_| | | | | |_| | |_| +(_) \_| |_|\__, | (_) + __/ | + |___/ +]]-- + + + + +--[[ +______ _ _ _ _ +| ___ \ (_) | | (_) | +| |_/ / __ ___ _ ___ ___| |_ _| | ___ +| __/ '__/ _ \| |/ _ \/ __| __| | |/ _ \ +| | | | | (_) | | __/ (__| |_| | | __/ +\_| |_| \___/| |\___|\___|\__|_|_|\___| + _/ | + |__/ +]]-- + +mobs.projectile_attack_fly = function(self, dtime) + + --this needs an exception + if self.attacking == nil or not self.attacking:is_player() then + self.attacking = nil + return + end + + local distance_from_attacking = vector_distance(self.object:get_pos(), self.attacking:get_pos()) + + if distance_from_attacking >= self.reach then + mobs.set_yaw_while_attacking(self) + mobs.set_pitch_while_attacking(self) + mobs.set_fly_velocity(self, self.run_velocity) + mobs.set_mob_animation(self,"run") + else + mobs.set_yaw_while_attacking(self) + mobs.set_pitch_while_attacking(self) + mobs.set_fly_velocity(self, 0) + mobs.set_mob_animation(self,"stand") + end + + + --do this to not load data into other mobs + if not self.projectile_timer then + self.projectile_timer = self.projectile_cooldown + end + + --run projectile timer + if self.projectile_timer > 0 then + self.projectile_timer = self.projectile_timer - dtime + + --shoot + if self.projectile_timer <= 0 then + --reset timer + self.projectile_timer = self.projectile_cooldown + mobs.shoot_projectile(self) + end + end end \ No newline at end of file diff --git a/mods/ENTITIES/mcl_mobs/api/mob_functions/backup_code_api.lua b/mods/ENTITIES/mcl_mobs/api/mob_functions/backup_code_api.lua index 0364e70c0e..802201688e 100644 --- a/mods/ENTITIES/mcl_mobs/api/mob_functions/backup_code_api.lua +++ b/mods/ENTITIES/mcl_mobs/api/mob_functions/backup_code_api.lua @@ -1565,25 +1565,7 @@ local function update_roll(self) self.object:set_properties({collisionbox = cbox}) end --- check if within physical map limits (-30911 to 30927) -local within_limits, wmin, wmax = nil, -30913, 30928 -within_limits = function(pos, radius) - if mcl_vars then - if mcl_vars.mapgen_edge_min and mcl_vars.mapgen_edge_max then - wmin, wmax = mcl_vars.mapgen_edge_min, mcl_vars.mapgen_edge_max - within_limits = function(pos, radius) - return pos - and (pos.x - radius) > wmin and (pos.x + radius) < wmax - and (pos.y - radius) > wmin and (pos.y + radius) < wmax - and (pos.z - radius) > wmin and (pos.z + radius) < wmax - end - end - end - return pos - and (pos.x - radius) > wmin and (pos.x + radius) < wmax - and (pos.y - radius) > wmin and (pos.y + radius) < wmax - and (pos.z - radius) > wmin and (pos.z + radius) < wmax -end + -- is mob facing a cliff or danger local is_at_cliff_or_danger = function(self) @@ -1661,19 +1643,7 @@ local is_at_water_danger = function(self) end --- get node but use fallback for nil or unknown -local node_ok = function(pos, fallback) - fallback = fallback or mobs.fallback_node - - local node = minetest_get_node_or_nil(pos) - - if node and minetest_registered_nodes[node.name] then - return node - end - - return minetest_registered_nodes[fallback] -end -- environmental damage (water, lava, fire, light etc.) diff --git a/mods/ENTITIES/mcl_mobs/api/mob_functions/collision.lua b/mods/ENTITIES/mcl_mobs/api/mob_functions/collision.lua index be707b22bd..43b7592692 100644 --- a/mods/ENTITIES/mcl_mobs/api/mob_functions/collision.lua +++ b/mods/ENTITIES/mcl_mobs/api/mob_functions/collision.lua @@ -3,6 +3,8 @@ local minetest_get_objects_inside_radius = minetest.get_objects_inside_radius local math_random = math.random local vector_multiply = vector.multiply +local vector_direction = vector.direction + local integer_test = {-1,1} mobs.collision = function(self) @@ -107,4 +109,30 @@ mobs.collision = function(self) end end +end + + +--this is used for arrow collisions +mobs.arrow_hit = function(self, player) + + player:punch(self.object, 1.0, { + full_punch_interval = 1.0, + damage_groups = {fleshy = self._damage} + }, nil) + + + --knockback + local pos1 = self.object:get_pos() + pos1.y = 0 + local pos2 = player:get_pos() + pos2.y = 0 + local dir = vector_direction(pos1,pos2) + + dir = vector_multiply(dir,3) + + if player:get_velocity().y <= 1 then + dir.y = 5 + end + + player:add_velocity(dir) end \ No newline at end of file diff --git a/mods/ENTITIES/mcl_mobs/api/mob_functions/combat_interaction.lua b/mods/ENTITIES/mcl_mobs/api/mob_functions/combat_interaction.lua deleted file mode 100644 index 5ba67b28c5..0000000000 --- a/mods/ENTITIES/mcl_mobs/api/mob_functions/combat_interaction.lua +++ /dev/null @@ -1 +0,0 @@ ---make mobs scan players and check distance then if direct line of sight then add to list and go after whichever one is closer \ No newline at end of file diff --git a/mods/ENTITIES/mcl_mobs/api/mob_functions/environment.lua b/mods/ENTITIES/mcl_mobs/api/mob_functions/environment.lua index f4e0a3809f..c6a392e577 100644 --- a/mods/ENTITIES/mcl_mobs/api/mob_functions/environment.lua +++ b/mods/ENTITIES/mcl_mobs/api/mob_functions/environment.lua @@ -4,6 +4,8 @@ local minetest_yaw_to_dir = minetest.yaw_to_dir local minetest_get_node = minetest.get_node local minetest_get_item_group = minetest.get_item_group local minetest_get_objects_inside_radius = minetest.get_objects_inside_radius +local minetest_get_node_or_nil = minetest.get_node_or_nil +local minetest_registered_nodes = minetest.registered_nodes local vector_new = vector.new local vector_multiply = vector.multiply @@ -24,10 +26,6 @@ end --a fast function to be able to detect only players without using objects_in_radius mobs.detect_closest_player_within_radius = function(self, line_of_sight, radius, object_height_adder) - line_of_sight = line_of_sight or true --fallback line_of_sight - radius = radius or 10 -- fallback radius - object_height_adder = object_height_adder or 0 --fallback entity (y height) addition for line of sight - local pos1 = self.object:get_pos() local players_in_area = {} local winner_player = nil @@ -165,4 +163,38 @@ mobs.group_attack_initialization = function(self) --end end end +end + +-- check if within physical map limits (-30911 to 30927) +-- within_limits, wmin, wmax = nil, -30913, 30928 +mobs.within_limits = function(pos, radius) + if mcl_vars then + if mcl_vars.mapgen_edge_min and mcl_vars.mapgen_edge_max then + wmin, wmax = mcl_vars.mapgen_edge_min, mcl_vars.mapgen_edge_max + within_limits = function(pos, radius) + return pos + and (pos.x - radius) > wmin and (pos.x + radius) < wmax + and (pos.y - radius) > wmin and (pos.y + radius) < wmax + and (pos.z - radius) > wmin and (pos.z + radius) < wmax + end + end + end + return pos + and (pos.x - radius) > wmin and (pos.x + radius) < wmax + and (pos.y - radius) > wmin and (pos.y + radius) < wmax + and (pos.z - radius) > wmin and (pos.z + radius) < wmax +end + +-- get node but use fallback for nil or unknown +mobs.node_ok = function(pos, fallback) + + fallback = fallback or mobs.fallback_node + + local node = minetest_get_node_or_nil(pos) + + if node and minetest_registered_nodes[node.name] then + return node + end + + return minetest_registered_nodes[fallback] end \ No newline at end of file diff --git a/mods/ENTITIES/mcl_mobs/api/mob_functions/movement.lua b/mods/ENTITIES/mcl_mobs/api/mob_functions/movement.lua index f983734ebe..811488396f 100644 --- a/mods/ENTITIES/mcl_mobs/api/mob_functions/movement.lua +++ b/mods/ENTITIES/mcl_mobs/api/mob_functions/movement.lua @@ -2,14 +2,17 @@ local math_pi = math.pi local math_sin = math.sin local math_cos = math.cos local math_random = math.random +local HALF_PI = math_pi / 2 local DOUBLE_PI = math_pi * 2 -- localize vector functions local vector_new = vector.new local vector_length = vector.length local vector_multiply = vector.multiply +local vector_distance = vector.distance local minetest_yaw_to_dir = minetest.yaw_to_dir +local minetest_dir_to_yaw = minetest.dir_to_yaw local DEFAULT_JUMP_HEIGHT = 5 local DEFAULT_FLOAT_SPEED = 4 @@ -236,6 +239,27 @@ mobs.set_fly_velocity = function(self, v) end end +--a quick and simple pitch calculation between two vector positions +mobs.calculate_pitch = function(pos1, pos2) + + if pos1 == nil or pos2 == nil then + return false + end + + return(minetest_dir_to_yaw(vector_new(vector_distance(vector_new(pos1.x,0,pos1.z),vector_new(pos2.x,0,pos2.z)),0,pos1.y - pos2.y)) + HALF_PI) +end + +--make mobs fly up or down based on their y difference +mobs.set_pitch_while_attacking = function(self) + local pos1 = self.object:get_pos() + local pos2 = self.attacking:get_pos() + + local pitch = mobs.calculate_pitch(pos2,pos1) + + self.pitch = pitch +end + + --[[ ___ diff --git a/mods/ENTITIES/mobs_mc/blaze.lua b/mods/ENTITIES/mobs_mc/blaze.lua index 6bc67300f7..d88a84515c 100644 --- a/mods/ENTITIES/mobs_mc/blaze.lua +++ b/mods/ENTITIES/mobs_mc/blaze.lua @@ -18,6 +18,8 @@ mobs:register_mob("mobs_mc:blaze", { xp_min = 10, xp_max = 10, tilt_fly = false, + hostile = true, + rotate = 270, collisionbox = {-0.3, -0.01, -0.3, 0.3, 1.79, 0.3}, rotate = -180, visual = "mesh", @@ -36,7 +38,7 @@ mobs:register_mob("mobs_mc:blaze", { walk_velocity = .8, run_velocity = 1.6, damage = 6, - reach = 2, + reach = 4, -- don't want blaze getting too close pathfinding = 1, drops = { {name = mobs_mc.items.blaze_rod, @@ -76,6 +78,13 @@ mobs:register_mob("mobs_mc:blaze", { fear_height = 0, glow = 14, fire_resistant = true, + eye_height = 0.75, + shoot_arrow = function(self, pos, dir) + -- 2-4 damage per arrow + local dmg = math.random(2,4) + mcl_bows.shoot_arrow("mobs_mc:blaze_fireball", pos, dir, self.object:get_yaw(), self.object, nil, dmg) + end, + do_custom = function(self) if self.state == "attack" and vector.distance(self.object:get_pos(), self.attack:get_pos()) < 1.2 then mcl_burning.set_on_fire(self.attack, 5) @@ -148,6 +157,7 @@ mobs:register_arrow("mobs_mc:blaze_fireball", { visual_size = {x = 0.3, y = 0.3}, textures = {"mcl_fire_fire_charge.png"}, velocity = 15, + speed = 5, -- Direct hit, no fire... just plenty of pain hit_player = function(self, player) @@ -180,7 +190,9 @@ mobs:register_arrow("mobs_mc:blaze_fireball", { -- Node hit, make fire hit_node = function(self, pos, node) - if node.name == "air" then + if node.name ~= "air" then + local pos_above = table.copy(pos) + pos_above.y = pos_above.y + 1 minetest.set_node(pos_above, {name=mobs_mc.items.fire}) else local v = self.object:get_velocity()