local aoe_exclude = { --any entity not including "mobs" is automatically added to this list. ["mobs_mc:spider_eyes"] = true, ["mobs_mc:wither_skull"] = true, ["mobs_mc:fireball"] = true, ["mobs_mc:dragon_fireball"] = true, ["mobs_mc:blaze_fireball"] = true, ["mobs_mc:shulkerbullet"] = true, ["mobs_mc:potion_arrow"] = true, ["mobs_mc:llamaspit"] = true, } local hostile_mobs = { --for Red Matter Sword/Katar ["mobs_mc:baby_hoglin"] = true, ["mobs_mc:baby_husk"] = true, ["mobs_mc:baby_zombie"] = true, ["mobs_mc:blaze"] = true, ["mobs_mc:cave_spider"] = true, ["mobs_mc:creeper"] = true, ["mobs_mc:creeper_charged"] = true, ["mobs_mc:enderdragon"] = true, ["mobs_mc:enderman"] = true, ["mobs_mc:endermite"] = true, ["mobs_mc:evoker"] = true, ["mobs_mc:ghast"] = true, ["mobs_mc:guardian"] = true, ["mobs_mc:guardian_elder"] = true, ["mobs_mc:hoglin"] = true, ["mobs_mc:husk"] = true, ["mobs_mc:illusioner"] = true, ["mobs_mc:killer_bunny"] = true, ["mobs_mc:magma_cube_big"] = true, ["mobs_mc:magma_cube_small"] = true, ["mobs_mc:magma_cube_tiny"] = true, ["mobs_mc:piglin"] = true, ["mobs_mc:piglin_brute"] = true, ["mobs_mc:pillager"] = true, ["mobs_mc:shulker"] = true, ["mobs_mc:skeleton"] = true, ["mobs_mc:silverfish"] = true, ["mobs_mc:slime_big"] = true, ["mobs_mc:slime_tiny"] = true, ["mobs_mc:spider"] = true, ["mobs_mc:stray"] = true, ["mobs_mc:vex"] = true, ["mobs_mc:villager_zombie"] = true, ["mobs_mc:vindicator"] = true, ["mobs_mc:witch"] = true, ["mobs_mc:wither"] = true, ["mobs_mc:witherskeleton"] = true, ["mobs_mc:zombified_piglin"] = true, ["mobs_mc:zoglin"] = true, ["mobs_mc:zombie"] = true, } minetest.register_on_mods_loaded(function() for name, def in pairs(minetest.registered_entities) do if not name:find("mobs") then aoe_exclude[name] = true end end end) function exchangeclone.aoe_attack(info) if not info then return end local damage = info.damage or 12 -- 12 = DM sword AOE local knockback = info.knockback local radius = info.radius local damage_all = info.damage_all --damage all mobs/players or just hostile ones local cooldown = info.cooldown or 0.7 if not (damage and radius and knockback) then return end if damage_all == nil then damage_all = 1 end return function(itemstack, player, pointed_thing) --modified from MineClone's TNT; I would simply use the explosion function but it would hurt the player. -- Use pointed node's on_rightclick function first, if present local click_test = exchangeclone.check_on_rightclick(itemstack, player, pointed_thing) if click_test ~= false then return click_test end if exchangeclone.check_cooldown(player, "sword") then return end exchangeclone.play_sound(player, "exchangeclone_charge_up") local pos = player:get_pos() -- Entities in radius of explosion local objs = minetest.get_objects_inside_radius(pos, radius) -- Trace rays for entity damage for _, obj in pairs(objs) do local ent = obj:get_luaentity() -- Ignore items to lower lag if (obj:is_player() or (ent and not aoe_exclude[ent.name] and not (damage_all == 0 and not hostile_mobs[ent.name]))) --ignore hostile mobs if necessary and obj:get_hp() > 0 and obj ~= player then local opos = obj:get_pos() local distance = math.max(1, vector.distance(pos, opos)) -- Punch entity with damage depending on explosion exposure and -- distance to explosion local punch_vec = vector.subtract(opos, pos) local punch_dir = vector.normalize(punch_vec) punch_dir = {x=punch_dir.x, y=punch_dir.y+0.3, z=punch_dir.z} -- knockback should be more upward local sleep_formspec_doesnt_close_mt53 = false if obj:is_player() then local name = obj:get_player_name() if mcl_beds then local meta = obj:get_meta() if meta:get_string("mcl_beds:sleeping") == "true" then minetest.close_formspec(name, "") -- ABSOLUTELY NECESSARY FOR MT5.3 -- TODO: REMOVE THIS IN THE FUTURE sleep_formspec_doesnt_close_mt53 = true end end end if sleep_formspec_doesnt_close_mt53 then minetest.after(0.3, function() -- 0.2 is minimum delay for closing old formspec and open died formspec -- TODO: REMOVE THIS IN THE FUTURE if not obj:is_player() then return end if exchangeclone.mcl then mcl_util.deal_damage(obj, damage, { type = "hit", direct = player}) else obj:set_hp(obj:get_hp() - damage) end obj:add_velocity(vector.multiply(punch_dir, knockback/distance)) end) else if exchangeclone.mcl then mcl_util.deal_damage(obj, damage, { type = "hit", direct = player}) else obj:set_hp(obj:get_hp() - damage) end obj:add_velocity(vector.multiply(punch_dir, knockback/distance)) end end end exchangeclone.start_cooldown(player, "sword", cooldown) end end local red_matter_sword_action = function(itemstack, player, pointed_thing) local click_test = exchangeclone.check_on_rightclick(itemstack, player, pointed_thing) if click_test ~= false then return click_test end local damage_all = itemstack:get_meta():get_int("exchangeclone_damage_all") if damage_all ~= 0 then damage_all = 1 end if player:get_player_control().sneak then if damage_all == 0 then damage_all = 1 minetest.chat_send_player(player:get_player_name(), "Damage all mobs") else damage_all = 0 minetest.chat_send_player(player:get_player_name(), "Damage hostile mobs") end itemstack:get_meta():set_int("exchangeclone_damage_all", damage_all) return itemstack end local aoe_function = exchangeclone.aoe_attack({damage = 16, knockback = 20, radius = 7.5, damage_all = damage_all, cooldown = 0.7}) aoe_function(itemstack, player, pointed_thing) end minetest.register_tool("exchangeclone:dark_matter_sword", { description = "Dark Matter Sword", wield_image = "exchangeclone_dark_matter_sword.png", inventory_image = "exchangeclone_dark_matter_sword.png", groups = { tool=1, sword=1, dig_speed_class=5, enchantability=0, disable_repair = 1, fire_immune = 1, exchangeclone_upgradable = 1}, wield_scale = exchangeclone.wield_scale, tool_capabilities = { full_punch_interval = 1/1.6, max_drop_level=6, damage_groups = {fleshy=13}, punch_attack_uses = 0, groupcaps={ snappy = {times = exchangeclone.get_mtg_times(14, nil, "snappy"), uses=0, maxlevel=4}, }, }, on_secondary_use = exchangeclone.aoe_attack({damage = 12, knockback = 12, radius = 5, cooldown = 0.7}), on_place = exchangeclone.aoe_attack({damage = 12, knockback = 12, radius = 5, cooldown = 0.7}), sound = { breaks = "default_tool_breaks" }, _mcl_toollike_wield = true, _mcl_diggroups = { swordy = { speed = 14, level = 5, uses = 0 } }, wear_represents = "exchangeclone_charge_level" }) minetest.register_tool("exchangeclone:red_matter_sword", { description = "Red Matter Sword", wield_image = "exchangeclone_red_matter_sword.png", inventory_image = "exchangeclone_red_matter_sword.png", groups = { tool=1, sword=1, dig_speed_class=6, enchantability=0, disable_repair = 1, fire_immune = 1, exchangeclone_upgradable = 1}, wield_scale = exchangeclone.wield_scale, tool_capabilities = { -- 1/1.2 full_punch_interval = 1/1.6, max_drop_level=7, damage_groups = {fleshy=17}, punch_attack_uses = 0, groupcaps={ snappy = {times = exchangeclone.get_mtg_times(16, nil, "snappy"), uses=0, maxlevel=5}, }, }, on_secondary_use = red_matter_sword_action, on_place = red_matter_sword_action, sound = { breaks = "default_tool_breaks" }, _mcl_toollike_wield = true, _mcl_diggroups = { swordy = { speed = 16, level = 6, uses = 0 } }, wear_represents = "exchangeclone_charge_level" }) minetest.register_craft({ output = "exchangeclone:dark_matter_sword", recipe = { {"exchangeclone:dark_matter"}, {"exchangeclone:dark_matter"}, {exchangeclone.itemstrings.diamond} } }) minetest.register_craft({ output = "exchangeclone:red_matter_sword", recipe = { {"exchangeclone:red_matter"}, {"exchangeclone:red_matter"}, {"exchangeclone:dark_matter_sword"}, } })