From c1b7ab7f9fde6f2780d1c468f7dec5fa2b4f22a4 Mon Sep 17 00:00:00 2001 From: rubenwardy Date: Fri, 22 Mar 2019 04:01:36 +0000 Subject: [PATCH] Add better ranged combat for shooters --- mods/ctf/ctf_classes/init.lua | 1 + mods/ctf/ctf_classes/mod.conf | 2 +- mods/ctf/ctf_classes/ranged.lua | 58 +++++++++++++++++++++++++++++++++ mods/pvp/shooter/grapple.lua | 12 +++++-- mods/pvp/shooter/shooter.lua | 35 +++++++++++++------- 5 files changed, 92 insertions(+), 16 deletions(-) create mode 100644 mods/ctf/ctf_classes/ranged.lua diff --git a/mods/ctf/ctf_classes/init.lua b/mods/ctf/ctf_classes/init.lua index cc681b5..14d1455 100644 --- a/mods/ctf/ctf_classes/init.lua +++ b/mods/ctf/ctf_classes/init.lua @@ -6,6 +6,7 @@ ctf_classes = { dofile(minetest.get_modpath("ctf_classes") .. "/api.lua") dofile(minetest.get_modpath("ctf_classes") .. "/gui.lua") dofile(minetest.get_modpath("ctf_classes") .. "/regen.lua") +dofile(minetest.get_modpath("ctf_classes") .. "/ranged.lua") ctf_classes.register("knight", { description = "Knight", diff --git a/mods/ctf/ctf_classes/mod.conf b/mods/ctf/ctf_classes/mod.conf index 0747762..ef91fb4 100644 --- a/mods/ctf/ctf_classes/mod.conf +++ b/mods/ctf/ctf_classes/mod.conf @@ -1,2 +1,2 @@ name = ctf_classes -depends = ctf, ctf_flag, ctf_colors, physics +depends = ctf, ctf_flag, ctf_colors, physics, shooter diff --git a/mods/ctf/ctf_classes/ranged.lua b/mods/ctf/ctf_classes/ranged.lua new file mode 100644 index 0000000..73857f3 --- /dev/null +++ b/mods/ctf/ctf_classes/ranged.lua @@ -0,0 +1,58 @@ +local shooter_specs = {} + + +shooter.get_weapon_spec = function(_, user, name) + local spec = shooter.registered_weapons[name] + if not spec then + return nil + end + spec = spec.spec + spec.name = user:get_player_name() + + if not user then + return spec + end + + local class = ctf_classes.get(user) + if class.name ~= "shooter" then + if name == "shooter:rifle" then + minetest.chat_send_player(user:get_player_name(), + "Only Shooters are skilled enough for rifles! Change your class at spawn") + return nil + end + return spec + end + + if shooter_specs[name] then + return shooter_specs[name] + end + + spec = table.copy(spec) + shooter_specs[name] = spec + + spec.range = spec.range * 1.5 + spec.tool_caps.full_punch_interval = spec.tool_caps.full_punch_interval * 0.8 + return spec +end + + +local function check_grapple(itemname) + local def = minetest.registered_items[itemname] + local old_func = def.on_use + minetest.override_item(itemname, { + description = def.description .. "\nCan only be used by Shooters", + on_use = function(itemstack, user, ...) + if ctf_classes.get(user).name ~= "shooter" then + minetest.chat_send_player(user:get_player_name(), + "Only Shooters are skilled enough for grapples! Change your class at spawn") + + return itemstack + end + + return old_func(itemstack, user, ...) + end, + }) +end + +check_grapple("shooter:grapple_gun_loaded") +check_grapple("shooter:grapple_gun") diff --git a/mods/pvp/shooter/grapple.lua b/mods/pvp/shooter/grapple.lua index cca9206..a6f2599 100644 --- a/mods/pvp/shooter/grapple.lua +++ b/mods/pvp/shooter/grapple.lua @@ -83,13 +83,18 @@ minetest.register_tool("shooter:grapple_gun", { description = "Grappling Gun", inventory_image = "shooter_hook_gun.png", on_use = function(itemstack, user, pointed_thing) + local ent = pointed_thing.ref and pointed_thing.ref:get_luaentity() + if ent and ent.name == "__builtin:item" then + return ent:on_punch(user) + end + local inv = user:get_inventory() if inv:contains_item("main", "shooter:grapple_hook") and - inv:contains_item("main", "tnt:gunpowder") then - inv:remove_item("main", "tnt:gunpowder") + true then --inv:contains_item("main", "tnt:gunpowder") then + -- inv:remove_item("main", "tnt:gunpowder") minetest.sound_play("shooter_reload", {object=user}) local stack = inv:remove_item("main", "shooter:grapple_hook") - itemstack = "shooter:grapple_gun_loaded 1 "..stack:get_wear() + itemstack = ItemStack("shooter:grapple_gun_loaded 1 "..stack:get_wear()) else minetest.sound_play("shooter_click", {object=user}) end @@ -107,6 +112,7 @@ minetest.register_tool("shooter:grapple_gun_loaded", { end minetest.sound_play("shooter_pistol", {object=user}) itemstack = ItemStack("shooter:grapple_hook 1 "..itemstack:get_wear()) + itemstack:add_wear(65536 / 6) throw_hook(itemstack, user, 20) return "shooter:grapple_gun" end, diff --git a/mods/pvp/shooter/shooter.lua b/mods/pvp/shooter/shooter.lua index 27ae7d5..55aa068 100644 --- a/mods/pvp/shooter/shooter.lua +++ b/mods/pvp/shooter/shooter.lua @@ -229,18 +229,20 @@ function shooter:register_weapon(name, def) inventory_image = def.inventory_image, on_use = function(itemstack, user, pointed_thing) if itemstack:get_wear() < max_wear then - def.spec.name = user:get_player_name() - if shots > 1 then - local step = def.spec.tool_caps.full_punch_interval - for i = 0, step * shots, step do - minetest.after(i, function() - shooter:fire_weapon(user, pointed_thing, def.spec) - end) + local spec = shooter:get_weapon_spec(user, name) + if spec then + if shots > 1 then + local step = spec.tool_caps.full_punch_interval + for i = 0, step * shots, step do + minetest.after(i, function() + shooter:fire_weapon(user, pointed_thing, spec) + end) + end + else + shooter:fire_weapon(user, pointed_thing, spec) end - else - shooter:fire_weapon(user, pointed_thing, def.spec) + itemstack:add_wear(wear) end - itemstack:add_wear(wear) else local inv = user:get_inventory() if inv then @@ -259,6 +261,16 @@ function shooter:register_weapon(name, def) }) end +function shooter:get_weapon_spec(user, name) + local spec = shooter.registered_weapons[name] + if not spec then + return nil + end + spec = spec.spec + spec.name = user:get_player_name() + return spec +end + function shooter:fire_weapon(user, pointed_thing, def) if shooter.shots[def.name] then if shooter.time < shooter.shots[def.name] then @@ -466,9 +478,8 @@ if not singleplayer and SHOOTER_ADMIN_WEAPONS then if player:get_player_control().LMB then local name = player:get_player_name() if minetest.check_player_privs(name, {server=true}) then - local spec = shooter.registered_weapons[player:get_wielded_item():get_name()] + local spec = shooter:get_weapon_spec(player, player:get_wielded_item():get_name()) if spec then - spec = spec.spec shooter.shots[name] = false spec.name = name shooter:fire_weapon(player, {}, spec)