From 779cb41de401ccc269b9e02767f21aac216a28c6 Mon Sep 17 00:00:00 2001 From: LoneWolfHT Date: Mon, 7 Dec 2020 11:26:12 -0800 Subject: [PATCH] Give knights a sword with a special ability (#711) --- .luacheckrc | 3 +- mods/ctf/ctf_classes/classes.lua | 2 +- mods/ctf/ctf_classes/melee.lua | 96 ++++++++++++++++++++++++++++++++ mods/ctf/ctf_classes/mod.conf | 2 +- mods/ctf/ctf_marker/init.lua | 16 +++--- 5 files changed, 109 insertions(+), 10 deletions(-) diff --git a/.luacheckrc b/.luacheckrc index e0831da..4ab1475 100644 --- a/.luacheckrc +++ b/.luacheckrc @@ -17,7 +17,8 @@ globals = { "ctf_colors", "hudkit", "default", "treasurer", "ChatCmdBuilder", "ctf_map", "ctf_match", "ctf_stats", "ctf_treasure", "ctf_playertag", "chatplus", "irc", "armor", "vote", "give_initial_stuff", "hud_score", "physics", "tsm_chests", - "armor", "shooter", "grenades", "ctf_classes", "ctf_bandages", "ctf_respawn_immunity" + "armor", "shooter", "grenades", "ctf_classes", "ctf_bandages", "ctf_respawn_immunity", + "ctf_marker", } read_globals = { diff --git a/mods/ctf/ctf_classes/classes.lua b/mods/ctf/ctf_classes/classes.lua index 2f5528e..d136a55 100644 --- a/mods/ctf/ctf_classes/classes.lua +++ b/mods/ctf/ctf_classes/classes.lua @@ -11,7 +11,7 @@ ctf_classes.register("knight", { melee_bonus = 1, initial_stuff = { - "default:sword_steel", + "ctf_classes:sword_steel", }, allowed_guns = { diff --git a/mods/ctf/ctf_classes/melee.lua b/mods/ctf/ctf_classes/melee.lua index 9b6d3e0..a313e27 100644 --- a/mods/ctf/ctf_classes/melee.lua +++ b/mods/ctf/ctf_classes/melee.lua @@ -26,3 +26,99 @@ minetest.register_on_player_hpchange(function(player, hp_change, reason) return hp_change end, true) + + +local sword_special_timer = {} +local SWORD_SPECIAL_COOLDOWN = 40 +local function sword_special_timer_func(pname, timeleft) + sword_special_timer[pname] = timeleft + + if timeleft - 10 >= 0 then + minetest.after(10, sword_special_timer_func, pname, timeleft - 10) + else + sword_special_timer[pname] = nil + end +end + +minetest.register_tool("ctf_classes:sword_steel", { + description = "Knight's Sword\nRightclick enemies/items/air to place marker\nMark enemies to show all enemies in area", + inventory_image = "default_tool_steelsword.png", + tool_capabilities = { + full_punch_interval = 0.8, + max_drop_level=1, + groupcaps={ + snappy={times={[1]=2.5, [2]=1.20, [3]=0.35}, uses=0, maxlevel=2}, + }, + damage_groups = {fleshy=6}, + punch_attack_uses = 0, + }, + sound = {breaks = "default_tool_breaks"}, + on_place = function(itemstack, placer, pointed_thing) + local pname = placer:get_player_name() + if not pointed_thing then return end + + if sword_special_timer[pname] then + minetest.chat_send_player(pname, "You can't place a marker yet (>"..sword_special_timer[pname].."s left)") + + if pointed_thing.type == "node" then + return minetest.item_place(itemstack, placer, pointed_thing) + else + return + end + end + + local pteam = ctf.player(pname).team + + if pointed_thing.type == "object" and pointed_thing.ref:is_player() then + if ctf_match.is_in_build_time() then return end + + local enemies = {} + local pos = pointed_thing.ref:get_pos() + + sword_special_timer[pname] = SWORD_SPECIAL_COOLDOWN + sword_special_timer_func(pname, SWORD_SPECIAL_COOLDOWN) + + for _, p in pairs(minetest.get_connected_players()) do + local name = p:get_player_name() + + if pteam ~= ctf.player(name).team and + vector.distance(p:get_pos(), pos) <= 10 then + table.insert(enemies, name) + end + end + + if #enemies > 0 then + ctf_marker.remove_marker(pteam) + ctf_marker.add_marker(pname, pteam, pos, ("[Enemies Found!: <%s>]"):format(table.concat(enemies, ", "))) + end + + return + end + + if pointed_thing.type == "node" then + return minetest.item_place(itemstack, placer, pointed_thing) + end + + sword_special_timer[pname] = 20 + sword_special_timer_func(pname, 20) + + minetest.registered_chatcommands["m"].func(pname, "Marked with "..pname.."'s sword") + end, + on_secondary_use = function(itemstack, user, pointed_thing) + if pointed_thing then + minetest.registered_tools["ctf_classes:sword_steel"].on_place(itemstack, user, pointed_thing) + end + end, +}) + +minetest.register_on_leaveplayer(function(player) + sword_special_timer[player:get_player_name()] = nil +end) + +ctf_match.register_on_new_match(function() + sword_special_timer = {} +end) + +ctf.register_on_new_game(function() + sword_special_timer = {} +end) diff --git a/mods/ctf/ctf_classes/mod.conf b/mods/ctf/ctf_classes/mod.conf index 2799470..c60fda3 100644 --- a/mods/ctf/ctf_classes/mod.conf +++ b/mods/ctf/ctf_classes/mod.conf @@ -1,3 +1,3 @@ name = ctf_classes -depends = ctf, ctf_flag, ctf_colors, ctf_map_core, ctf_stats, ctf_bandages, physics, shooter, hpregen, give_initial_stuff, dropondie, crafting, sniper_rifles, grenades, furnace, ctf_respawn_immunity +depends = ctf, ctf_flag, ctf_colors, ctf_map_core, ctf_stats, ctf_bandages, physics, shooter, hpregen, give_initial_stuff, dropondie, crafting, sniper_rifles, grenades, furnace, ctf_respawn_immunity, ctf_marker, ctf_match description = Adds classes, including knight, shooter, and medic diff --git a/mods/ctf/ctf_marker/init.lua b/mods/ctf/ctf_marker/init.lua index ac69786..956605f 100644 --- a/mods/ctf/ctf_marker/init.lua +++ b/mods/ctf/ctf_marker/init.lua @@ -1,3 +1,5 @@ +ctf_marker = {} + -- Locally cache list of team members when adding -- marker, because the members in the team needn't -- be the same within an extended duration of time @@ -14,7 +16,9 @@ local function msg(str) end -- Remove waypoint element for valid players in team tname -local function remove_marker(tname) +function ctf_marker.remove_marker(tname) + if not teams[tname] then return end + for name, hud in pairs(teams[tname].players) do local player = minetest.get_player_by_name(name) if player then @@ -25,7 +29,7 @@ local function remove_marker(tname) end -- Add waypoint element to all players in the same team as name -local function add_marker(name, tname, pos, str) +function ctf_marker.add_marker(name, tname, pos, str) local player = minetest.get_player_by_name(name) if not player then return @@ -63,7 +67,7 @@ minetest.register_globalstep(function(dtime) -- If time > visibility_time, destroy team marker if time >= visibility_time then - remove_marker(tname) + ctf_marker.remove_marker(tname) end end end) @@ -125,10 +129,8 @@ minetest.register_chatcommand("m", { str = "[" .. str .. "]" -- Remove existing marker if it exists - if teams[tname] then - remove_marker(tname) - end + ctf_marker.remove_marker(tname) - add_marker(name, tname, minetest.get_pointed_thing_position(pointed), str) + ctf_marker.add_marker(name, tname, minetest.get_pointed_thing_position(pointed), str) end })