From 8698e472d0a1e354937d67f498c750ce4814f167 Mon Sep 17 00:00:00 2001 From: rubenwardy Date: Thu, 21 Mar 2019 01:36:59 +0000 Subject: [PATCH 01/15] Add classes --- mods/ctf/ctf_alloc/init.lua | 2 +- mods/ctf/ctf_classes/api.lua | 98 ++++++++++++++++++ mods/ctf/ctf_classes/gui.lua | 75 ++++++++++++++ mods/ctf/ctf_classes/init.lua | 75 ++++++++++++++ mods/ctf/ctf_classes/mod.conf | 2 + .../textures/ctf_classes_knight.png | Bin 0 -> 410 bytes .../textures/ctf_classes_medic.png | Bin 0 -> 582 bytes .../textures/ctf_classes_shooter.png | Bin 0 -> 420 bytes .../ctf_classes_skins_knight_blue.png | Bin 0 -> 7414 bytes .../textures/ctf_classes_skins_knight_red.png | Bin 0 -> 7188 bytes .../textures/ctf_classes_skins_medic_blue.png | Bin 0 -> 7527 bytes .../textures/ctf_classes_skins_medic_red.png | Bin 0 -> 7375 bytes .../ctf_classes_skins_shooter_blue.png | Bin 0 -> 7518 bytes .../ctf_classes_skins_shooter_red.png | Bin 0 -> 7189 bytes .../ctf_map_core/give_initial_stuff.lua | 2 +- mods/ctf/ctf_marker/init.lua | 1 + mods/pvp/gauges/init.lua | 4 +- mods/pvp/hpregen/init.lua | 4 +- 18 files changed, 257 insertions(+), 6 deletions(-) create mode 100644 mods/ctf/ctf_classes/api.lua create mode 100644 mods/ctf/ctf_classes/gui.lua create mode 100644 mods/ctf/ctf_classes/init.lua create mode 100644 mods/ctf/ctf_classes/mod.conf create mode 100644 mods/ctf/ctf_classes/textures/ctf_classes_knight.png create mode 100644 mods/ctf/ctf_classes/textures/ctf_classes_medic.png create mode 100644 mods/ctf/ctf_classes/textures/ctf_classes_shooter.png create mode 100644 mods/ctf/ctf_classes/textures/ctf_classes_skins_knight_blue.png create mode 100644 mods/ctf/ctf_classes/textures/ctf_classes_skins_knight_red.png create mode 100644 mods/ctf/ctf_classes/textures/ctf_classes_skins_medic_blue.png create mode 100644 mods/ctf/ctf_classes/textures/ctf_classes_skins_medic_red.png create mode 100644 mods/ctf/ctf_classes/textures/ctf_classes_skins_shooter_blue.png create mode 100644 mods/ctf/ctf_classes/textures/ctf_classes_skins_shooter_red.png diff --git a/mods/ctf/ctf_alloc/init.lua b/mods/ctf/ctf_alloc/init.lua index e565a20969..f1449b1116 100644 --- a/mods/ctf/ctf_alloc/init.lua +++ b/mods/ctf/ctf_alloc/init.lua @@ -126,6 +126,6 @@ function ctf_alloc.set_all() give_initial_stuff(player) end - player:set_hp(20) + player:set_hp(player:get_properties().hp_max) end end diff --git a/mods/ctf/ctf_classes/api.lua b/mods/ctf/ctf_classes/api.lua new file mode 100644 index 0000000000..ebcb0378b1 --- /dev/null +++ b/mods/ctf/ctf_classes/api.lua @@ -0,0 +1,98 @@ +function ctf_classes.register(cname, def) + assert(not ctf_classes.__classes[cname]) + def.name = cname + ctf_classes.__classes[cname] = def + table.insert(ctf_classes.__classes_ordered, def) + + def.max_hp = def.max_hp or 20 + def.speed = def.speed or 1 + def.pros = def.pros or {} + def.cons = def.cons or {} +end + +function ctf_classes.set_skin(player, color, class) + player:set_properties({ + textures = {"ctf_classes_skins_" .. class.name .. "_" .. (color or "blue") .. ".png"} + }) +end + +function ctf_classes.get(player) + if type(player) == "string" then + player = minetest.get_player_by_name(player) + end + + local cname = player:get_meta():get("ctf_classes:class") or "knight" + return ctf_classes.__classes[cname] +end + +function ctf_classes.set(player, cname) + assert(type(cname) == "string") + local class = ctf_classes.__classes[cname] + assert(class) + + local meta = player:get_meta() + local old = meta:get("ctf_classes:class") + meta:set_string("ctf_classes:class", cname) + ctf_classes.update(player) + + if old ~= nil and old ~= cname then + local pname = player:get_player_name() + ctf.chat_send_team(ctf.player(pname).team, + minetest.colorize("#ABCDEF", pname .. " is now a " .. class.description)) + end +end + +local function set_max_hp(player, max_hp) + local cur_hp = player:get_hp() + local new_hp = cur_hp + max_hp - player:get_properties().hp_max + player:set_properties({ + hp_max = max_hp + }) + + assert(new_hp <= max_hp) + if cur_hp > max_hp then + player:set_hp(max_hp) + elseif new_hp > cur_hp then + player:set_hp(new_hp) + end +end + +function ctf_classes.update(player) + local class = ctf_classes.get(player) + local color, _ = ctf_colors.get_color(ctf.player(player:get_player_name())) + + set_max_hp(player, class.max_hp) + ctf_classes.set_skin(player, color, class) + physics.set(player:get_player_name(), "ctf_classes:speed", { + speed = class.speed, + }) +end + +local function sqdist(a, b) + local x = a.x - b.x + local y = a.y - b.y + local z = a.z - b.z + return x*x + y*y + z*z +end + +local function get_flag_pos(player) + local tplayer = ctf.player(player:get_player_name()) + if not tplayer or not tplayer.team then + return nil + end + + local team = ctf.team(tplayer.team) + if team and team.flags[1] then + return vector.new(team.flags[1]) + end + return nil +end + +function ctf_classes.can_change(player) + local flag_pos = get_flag_pos(player) + if not flag_pos then + return false + end + + return sqdist(player:get_pos(), flag_pos) < 25 +end diff --git a/mods/ctf/ctf_classes/gui.lua b/mods/ctf/ctf_classes/gui.lua new file mode 100644 index 0000000000..93c9d8bf4f --- /dev/null +++ b/mods/ctf/ctf_classes/gui.lua @@ -0,0 +1,75 @@ +function ctf_classes.show_gui(name, player) + player = player or minetest.get_player_by_name(name) + assert(player.get_player_name) + if not ctf_classes.can_change(player) then + minetest.chat_send_player(name, "Move closer to the flag to change classes!") + return + end + + local fs = { + "size[9,3.2]" + } + + + local x = 0 + local y = 0 + for _, class in pairs(ctf_classes.__classes_ordered) do + fs[#fs + 1] = "container[" + fs[#fs + 1] = tostring(x*3) + fs[#fs + 1] = "," + fs[#fs + 1] = tostring(y*3.5) + fs[#fs + 1] = "]" + fs[#fs + 1] = "image[1,-0.1;1,1;ctf_classes_" + fs[#fs + 1] = class.name + fs[#fs + 1] = ".png]" + fs[#fs + 1] = "style[select_" + fs[#fs + 1] = class.name + fs[#fs + 1] = ";bgcolor=" + fs[#fs + 1] = class.color + fs[#fs + 1] = "]" + fs[#fs + 1] = "tableoptions[background=#00000000;highlight=#00000000;border=false]" + fs[#fs + 1] = "tablecolumns[color;text]" + fs[#fs + 1] = "table[0,0.9;2.8,1.7;;" + fs[#fs + 1] = class.color + fs[#fs + 1] = "," + fs[#fs + 1] = minetest.formspec_escape(class.description) + fs[#fs + 1] = ",," + for _, item in pairs(class.pros) do + fs[#fs + 1] = ",#cfc," .. minetest.formspec_escape(item) + end + for _, item in pairs(class.cons) do + fs[#fs + 1] = ",#fcc," .. minetest.formspec_escape(item) + end + fs[#fs + 1] = "]" + fs[#fs + 1] = "button_exit[0.5,2.7;2,1;select_" + fs[#fs + 1] = class.name + fs[#fs + 1] = ";Select]" + fs[#fs + 1] = "container_end[]" + + x = x + 1 + if x > 3 then + x = 0 + y = y + 1 + end + end + + minetest.show_formspec(name, "ctf_classes:select", table.concat(fs)) +end + +minetest.register_on_player_receive_fields(function(player, formname, fields) + if formname ~= "ctf_classes:select" then + return false + end + + if not ctf_classes.can_change(player) then + minetest.chat_send_player(player:get_player_name(), + "Move closer to the flag to change classes!") + end + + for _, class in pairs(ctf_classes.__classes_ordered) do + if fields["select_" .. class.name] then + ctf_classes.set(player, class.name) + return true + end + end +end) diff --git a/mods/ctf/ctf_classes/init.lua b/mods/ctf/ctf_classes/init.lua new file mode 100644 index 0000000000..bd19398eb1 --- /dev/null +++ b/mods/ctf/ctf_classes/init.lua @@ -0,0 +1,75 @@ +ctf_classes = { + __classes = {}, + __classes_ordered = {}, +} + +dofile(minetest.get_modpath("ctf_classes") .. "/api.lua") +dofile(minetest.get_modpath("ctf_classes") .. "/gui.lua") + +ctf_classes.register("knight", { + description = "Knight", + pros = { "+10 HP", "+10% melee skill" }, + cons = { "-10% speed" }, + max_hp = 30, + color = "#ccc", +}) + +ctf_classes.register("shooter", { + description = "Shooter", + pros = { "+10% ranged skill", "Can use sniper rifles", "Can use grapling hooks" }, + cons = {}, + speed = 1.1, + color = "#c60", +}) + +ctf_classes.register("medic", { + description = "Medic", + speed = 1.1, + pros = { "x2 regen for nearby friendlies", "Free bandages" }, + cons = { "Can't capture the flag"}, + color = "#0af", +}) + +minetest.register_on_joinplayer(ctf_classes.update) + +minetest.register_chatcommand("class", { + func = function(name, params) + local player = minetest.get_player_by_name(name) + if not player then + return false, "You must be online to do this!" + end + + if not ctf_classes.can_change(player) then + return false, "Move closer to the flag to change classes!" + end + + local cname = params:trim() + if params == "" then + ctf_classes.show_gui(name) + else + if ctf_classes.__classes[cname] then + ctf_classes.set(player, cname) + return true, "Set class to " .. cname + else + return false, "Class '" .. cname .. "' does not exist" + end + end + end +}) + +ctf_colors.set_skin = function(player, color) + ctf_classes.set_skin(player, color, ctf_classes.get(player)) +end + +local flags = { + "ctf_flag:flag", + "ctf_flag:flag_top_red", + "ctf_flag:flag_top_blue", +} + +for _, flag in pairs(flags) do + local function show(_, _, player) + ctf_classes.show_gui(player:get_player_name(), player) + end + minetest.override_item(flag, { on_rightclick = show }) +end diff --git a/mods/ctf/ctf_classes/mod.conf b/mods/ctf/ctf_classes/mod.conf new file mode 100644 index 0000000000..0747762f08 --- /dev/null +++ b/mods/ctf/ctf_classes/mod.conf @@ -0,0 +1,2 @@ +name = ctf_classes +depends = ctf, ctf_flag, ctf_colors, physics diff --git a/mods/ctf/ctf_classes/textures/ctf_classes_knight.png b/mods/ctf/ctf_classes/textures/ctf_classes_knight.png new file mode 100644 index 0000000000000000000000000000000000000000..54176327fc99b15abf6c0616c12129f575d61be3 GIT binary patch literal 410 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^xl_H+M9WCijSl0AZa z85pWm85kOx85n;42huMY7)lKo7+xhXFj&oCU=Yur6o1qWsFo?o+ueoXe|!I#{XiaP zfk$L90|Va?5N4dJ%_j{MWH0gbb!C6Z#Ve$*`hJb&d7x0Qr;B5V#`)ff8~K_IcwFLF zd5E4mG;Qkp$IYK=*W8Sl;9lOr=)CaDHtYQ=R_Yr2zgpc|gBTZ@Emdd}<6e#3UUuEUE7zi0JV|KOg`%*`d@tMf%~ z-pP<-526m#{B#M3&bHzeJNAIVqCQC4`hlOk^)j8JLyOdX&G22WQ% Jmvv4FO#mz^gqHvS literal 0 HcmV?d00001 diff --git a/mods/ctf/ctf_classes/textures/ctf_classes_medic.png b/mods/ctf/ctf_classes/textures/ctf_classes_medic.png new file mode 100644 index 0000000000000000000000000000000000000000..901c6cb76c04b80c28c1e54d410ee3163acbe821 GIT binary patch literal 582 zcmV-M0=fN(P)WFU8GbZ8()Nlj2>E@cM*00F8=L_t(I%dL|!ZWKWf zMPK#I&LGydgb;}(4uC{xgouEv00}p6z&crH7DwR%WY~9bMubCTiN#`Px4Y^S^fJ3b zmJ{f#t5yI1`o9|f@z`y}b}psOi#9b0%FOIefbLY9BzW~$nAIj1)C-(nK@P|twm`Pq z{Prn?D(68DT>=LNH-0W*U=m!TaaNepj3ONo72K2}3a!gZOwMAjWt`4@wx>Aykol6P z@2J2Geib-7ugwR&n7uY6as1i2UW$-mA=YJQXP~n74Gh`1S-~=c?;As@#$GSQw}og- z^k%HXh}{u9jN(?e^R`uQL70(Y)*K0-AbW|YuPggqZb=a#<)55w5kMiy64!_l=ltB< z)VvY~=c3falGGH1^30M91$R&1fbd2>aiF6Ao-U3d7N?g^cJw~%Akey>*Y#5O4j;jj zOGUblv+n(>^yJ<7v-%$%8E!hR!zqz2Dg|Riv50m7tdR#C*eHli+t$olOY5$gy$%f7y2m8eY-RVlqIp1Z5;M1; z!0D*lXOrzS7QVk~x!gs?Mn}zNZ!KfN>iv~y=UG({|qup7nA|@QP#qX8z2P`epu^*|V!&>(Dy;^}wKD@O1Ta JS?83{1OWPorVRi9 literal 0 HcmV?d00001 diff --git a/mods/ctf/ctf_classes/textures/ctf_classes_skins_knight_blue.png b/mods/ctf/ctf_classes/textures/ctf_classes_skins_knight_blue.png new file mode 100644 index 0000000000000000000000000000000000000000..76ab60cbaee413afc3e861cd749294e8fee61985 GIT binary patch literal 7414 zcmV zaB^>EX>4U6ba`-PAZ2)IW&i+q+O3&sk|Vitg#Y6dIznOzEXToWrW@$^`W(z+_w<{2 zW>2Q7nIf6Y#1i4*?tymufByTp|KcY-HMnG@=9crrPim=!&YSvtem<}MN%!ylN$*#D z{>yb2e!d7?ioC|p$GqSBJJ;>k1LYmbkH21bWxnIoccAx+p8=z0)@<*6^&KdN&vpNP zcI|zxr{A{o{vXR7;(PO-pHm?i%eWYW3p@Jw@K+Cp$O>YMo!7|U5Cb>qn%>*JUj9CI z?)&zS;MISK-P7MY;$K7Ip8VdB|A^6h-P_;C?ndbM75SgH;jdq;`RwQSpWkA4&Z_6^ z&+dB4L@K*?Q_nlZeaDT1P{#XM=C|;_@xI*O#&2bdlb|oMIryE<3Of{DLzp4nYc-b8!n_Gc`t>Ii(z9HwJKyw`nV09z;2F#- zn}7bgzq|N<`TY)bj-czkf>}SYVqHN1WEskw{&E)y@#l@H-T2;L_f6}sA0;-DLAznD zY_LD$GsH0e3tRE#IdY#p$-U+5%X$YOM9gh0#z!*nWFO6E|CA7l_r$T1pU%odOkt1# zZx)t!hup-NNlp!#n`er@_XZ1}%TNo6u$W^ZH53rZO3A=aNfiurivG6HhvJ@+qgD zcKSDKZ&v@BHUCHE{(aW`n>A%D-TTU~tZ})NpCP>H#FR5K7Lq69MHv9lK{

PbnyK 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 W%LH36fijf<0000 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 literal 0 HcmV?d00001 diff --git a/mods/ctf/ctf_classes/textures/ctf_classes_skins_medic_red.png b/mods/ctf/ctf_classes/textures/ctf_classes_skins_medic_red.png new file mode 100644 index 0000000000000000000000000000000000000000..e701b841c627ff3949d7b55717be84a63f8c9f7e GIT binary patch literal 7375 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 BIko@* literal 0 HcmV?d00001 diff --git a/mods/ctf/ctf_classes/textures/ctf_classes_skins_shooter_blue.png b/mods/ctf/ctf_classes/textures/ctf_classes_skins_shooter_blue.png new file mode 100644 index 0000000000000000000000000000000000000000..1d362d05995f22ed7a2f85800ec8c6611c8c5668 GIT binary patch literal 7518 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 literal 0 HcmV?d00001 diff --git a/mods/ctf/ctf_classes/textures/ctf_classes_skins_shooter_red.png b/mods/ctf/ctf_classes/textures/ctf_classes_skins_shooter_red.png new file mode 100644 index 0000000000000000000000000000000000000000..d6645eb80f7028f87ba1f42b3de3a65592ad7173 GIT binary patch literal 7189 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 literal 0 HcmV?d00001 diff --git a/mods/ctf/ctf_map/ctf_map_core/give_initial_stuff.lua b/mods/ctf/ctf_map/ctf_map_core/give_initial_stuff.lua index 7a313bdd2b..4878616a95 100644 --- a/mods/ctf/ctf_map/ctf_map_core/give_initial_stuff.lua +++ b/mods/ctf/ctf_map/ctf_map_core/give_initial_stuff.lua @@ -29,7 +29,7 @@ function give_initial_stuff.get_stuff() end minetest.register_on_joinplayer(function(player) - player:set_hp(20) + player:set_hp(player:get_properties().hp_max) give_initial_stuff(player) end) minetest.register_on_respawnplayer(give_initial_stuff) diff --git a/mods/ctf/ctf_marker/init.lua b/mods/ctf/ctf_marker/init.lua index d020602e58..58b5053955 100644 --- a/mods/ctf/ctf_marker/init.lua +++ b/mods/ctf/ctf_marker/init.lua @@ -37,6 +37,7 @@ local function add_marker(name, tname, pos, str) players = {}, time = 0 } + for pname, _ in pairs(team.players) do local tplayer = minetest.get_player_by_name(pname) if tplayer then diff --git a/mods/pvp/gauges/init.lua b/mods/pvp/gauges/init.lua index 3a03494c8e..775b45197c 100644 --- a/mods/pvp/gauges/init.lua +++ b/mods/pvp/gauges/init.lua @@ -33,8 +33,8 @@ function hp_bar:on_step(dtime) return end - local hp = wielder:get_hp() - local breath = wielder:get_breath() + local hp = math.floor(20 * wielder:get_hp() / wielder:get_properties().hp_max) + local breath = math.floor(20 * wielder:get_breath() / wielder:get_properties().breath_max) self.object:set_properties({ textures = { "health_" .. tostring(hp) .. ".png^breath_" .. tostring(breath) .. ".png", diff --git a/mods/pvp/hpregen/init.lua b/mods/pvp/hpregen/init.lua index 57bffa07f9..7ef94ab900 100644 --- a/mods/pvp/hpregen/init.lua +++ b/mods/pvp/hpregen/init.lua @@ -12,8 +12,8 @@ local function regen_all() local oldhp = player:get_hp() if oldhp > 0 then local newhp = oldhp + regen_amount - if newhp > 20 then - newhp = 20 + if newhp > player:get_properties().hp_max then + newhp = player:get_properties().hp_max end player:set_hp(newhp) end From 00b2a8c6f5ad3205e783d8bd25af8991c29d5ef5 Mon Sep 17 00:00:00 2001 From: rubenwardy Date: Fri, 22 Mar 2019 03:18:45 +0000 Subject: [PATCH 02/15] Add hpregen for medics --- mods/ctf/ctf_classes/init.lua | 22 +++++++++- mods/ctf/ctf_classes/regen.lua | 75 ++++++++++++++++++++++++++++++++++ mods/pvp/gauges/init.lua | 2 +- mods/pvp/hpregen/init.lua | 18 ++++++-- 4 files changed, 111 insertions(+), 6 deletions(-) create mode 100644 mods/ctf/ctf_classes/regen.lua diff --git a/mods/ctf/ctf_classes/init.lua b/mods/ctf/ctf_classes/init.lua index bd19398eb1..cc681b554f 100644 --- a/mods/ctf/ctf_classes/init.lua +++ b/mods/ctf/ctf_classes/init.lua @@ -5,6 +5,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") ctf_classes.register("knight", { description = "Knight", @@ -67,9 +68,26 @@ local flags = { "ctf_flag:flag_top_blue", } -for _, flag in pairs(flags) do +for _, flagname in pairs(flags) do + local old_func = minetest.registered_nodes[flagname].on_punch + local function on_punch(pos, node, player, ...) + if ctf_classes.get(player).name == "medic" then + local flag = ctf_flag.get(pos) + local team = ctf.player(player:get_player_name()).team + if not flag or not flag.team or not team or team ~= flag.team then + minetest.chat_send_player(player:get_player_name(), + "Medics can't capture the flag!") + return + end + end + + return old_func(pos, node, player, ...) + end local function show(_, _, player) ctf_classes.show_gui(player:get_player_name(), player) end - minetest.override_item(flag, { on_rightclick = show }) + minetest.override_item(flagname, { + on_punch = on_punch, + on_rightclick = show, + }) end diff --git a/mods/ctf/ctf_classes/regen.lua b/mods/ctf/ctf_classes/regen.lua new file mode 100644 index 0000000000..bde42a28dc --- /dev/null +++ b/mods/ctf/ctf_classes/regen.lua @@ -0,0 +1,75 @@ +local regen_interval = tonumber(minetest.settings:get("regen_interval")) +if regen_interval <= 0 then + regen_interval = 6 +end + +local regen_amount = tonumber(minetest.settings:get("regen_amount")) +if regen_amount <= 0 then + regen_amount = 1 +end + +local function regen_update() + local get = ctf_classes.get + local players = minetest.get_connected_players() + local medic_by_team = { red = {}, blue = {} } + local tnames = {} + local found_medic = false + + -- First get medic positions and team names + for i=1, #players do + local player = players[i] + local pname = player:get_player_name() + local class = get(player) + local tname = ctf.player(pname).team + tnames[pname] = tname + if class.name == "medic" then + if tname then + medic_by_team[tname][#medic_by_team[tname] + 1] = player:get_pos() + found_medic = true + end + end + end + + if not found_medic then + return + end + + -- Next, update hp + + local function sqdist(a, b) + local x = a.x - b.x + local y = a.y - b.y + local z = a.z - b.z + return x*x + y*y + z*z + end + + for i=1, #players do + local player = players[i] + local pname = player:get_player_name() + local tname = tnames[pname] + local hp = player:get_hp() + local max_hp = player:get_properties().hp_max + if tname and hp ~= max_hp and hp > 0 then + local pos = player:get_pos() + local medics = medic_by_team[tname] + for j=1, #medics do + if sqdist(pos, medics[j]) < 100 then + hp = hp + regen_amount + player:set_hp(hp) + break + end + end + end + end +end + +local update = regen_interval / 2 +minetest.register_globalstep(function(delta) + update = update + delta + if update < regen_interval then + return + end + update = update - regen_interval + + regen_update() +end) diff --git a/mods/pvp/gauges/init.lua b/mods/pvp/gauges/init.lua index 775b45197c..d6ea7d93ec 100644 --- a/mods/pvp/gauges/init.lua +++ b/mods/pvp/gauges/init.lua @@ -34,7 +34,7 @@ function hp_bar:on_step(dtime) end local hp = math.floor(20 * wielder:get_hp() / wielder:get_properties().hp_max) - local breath = math.floor(20 * wielder:get_breath() / wielder:get_properties().breath_max) + local breath = math.floor(11 * wielder:get_breath() / wielder:get_properties().breath_max) self.object:set_properties({ textures = { "health_" .. tostring(hp) .. ".png^breath_" .. tostring(breath) .. ".png", diff --git a/mods/pvp/hpregen/init.lua b/mods/pvp/hpregen/init.lua index 7ef94ab900..15222fb70e 100644 --- a/mods/pvp/hpregen/init.lua +++ b/mods/pvp/hpregen/init.lua @@ -15,9 +15,21 @@ local function regen_all() if newhp > player:get_properties().hp_max then newhp = player:get_properties().hp_max end - player:set_hp(newhp) + if oldhp ~= newhp then + player:set_hp(newhp) + end end end - minetest.after(regen_interval, regen_all) end -minetest.after(regen_interval, regen_all) + + +local update = 0 +minetest.register_globalstep(function(delta) + update = update + delta + if update < regen_interval then + return + end + update = update - regen_interval + + regen_all() +end) From b8fd84e60eadac07b8adab5addbc406b1abfd485 Mon Sep 17 00:00:00 2001 From: rubenwardy Date: Fri, 22 Mar 2019 04:01:36 +0000 Subject: [PATCH 03/15] 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 cc681b554f..14d14558df 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 0747762f08..ef91fb437b 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 0000000000..73857f36f3 --- /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 cca920666f..a6f25997b1 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 27ae7d5cd9..55aa068b4d 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) From 6438379a73e91173d35a5050f10ef5fa4bfeb543 Mon Sep 17 00:00:00 2001 From: rubenwardy Date: Fri, 22 Mar 2019 04:27:05 +0000 Subject: [PATCH 04/15] Add skins by GreenDimond/GreenXenith --- README.md | 4 ++++ mods/ctf/ctf_classes/api.lua | 2 +- .../textures/ctf_classes_skin_knight_blue.png | Bin 0 -> 1380 bytes .../textures/ctf_classes_skin_knight_red.png | Bin 0 -> 1388 bytes .../textures/ctf_classes_skin_medic_blue.png | Bin 0 -> 2016 bytes .../textures/ctf_classes_skin_medic_red.png | Bin 0 -> 2036 bytes .../textures/ctf_classes_skin_shooter_blue.png | Bin 0 -> 3339 bytes .../textures/ctf_classes_skin_shooter_red.png | Bin 0 -> 3367 bytes .../textures/ctf_classes_skins_knight_blue.png | Bin 7414 -> 0 bytes .../textures/ctf_classes_skins_knight_red.png | Bin 7188 -> 0 bytes .../textures/ctf_classes_skins_medic_blue.png | Bin 7527 -> 0 bytes .../textures/ctf_classes_skins_medic_red.png | Bin 7375 -> 0 bytes .../textures/ctf_classes_skins_shooter_blue.png | Bin 7518 -> 0 bytes .../textures/ctf_classes_skins_shooter_red.png | Bin 7189 -> 0 bytes 14 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 mods/ctf/ctf_classes/textures/ctf_classes_skin_knight_blue.png create mode 100644 mods/ctf/ctf_classes/textures/ctf_classes_skin_knight_red.png create mode 100644 mods/ctf/ctf_classes/textures/ctf_classes_skin_medic_blue.png create mode 100644 mods/ctf/ctf_classes/textures/ctf_classes_skin_medic_red.png create mode 100644 mods/ctf/ctf_classes/textures/ctf_classes_skin_shooter_blue.png create mode 100644 mods/ctf/ctf_classes/textures/ctf_classes_skin_shooter_red.png delete mode 100644 mods/ctf/ctf_classes/textures/ctf_classes_skins_knight_blue.png delete mode 100644 mods/ctf/ctf_classes/textures/ctf_classes_skins_knight_red.png delete mode 100644 mods/ctf/ctf_classes/textures/ctf_classes_skins_medic_blue.png delete mode 100644 mods/ctf/ctf_classes/textures/ctf_classes_skins_medic_red.png delete mode 100644 mods/ctf/ctf_classes/textures/ctf_classes_skins_shooter_blue.png delete mode 100644 mods/ctf/ctf_classes/textures/ctf_classes_skins_shooter_red.png diff --git a/README.md b/README.md index e1fb578e63..0c1370d921 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,10 @@ Created by [rubenwardy](https://rubenwardy.com/). Code: LGPLv2.1+ Textures: CC-BY-SA 3.0 +### Textures + +* ctf_classes_skin_* found and edited by GreenDimond/GreenXenith + ### Mods Check out [mods/](mods/) to see all the installed mods and their respective licenses. diff --git a/mods/ctf/ctf_classes/api.lua b/mods/ctf/ctf_classes/api.lua index ebcb0378b1..7da3d711f6 100644 --- a/mods/ctf/ctf_classes/api.lua +++ b/mods/ctf/ctf_classes/api.lua @@ -12,7 +12,7 @@ end function ctf_classes.set_skin(player, color, class) player:set_properties({ - textures = {"ctf_classes_skins_" .. class.name .. "_" .. (color or "blue") .. ".png"} + textures = {"ctf_classes_skin_" .. class.name .. "_" .. (color or "blue") .. ".png"} }) end diff --git a/mods/ctf/ctf_classes/textures/ctf_classes_skin_knight_blue.png b/mods/ctf/ctf_classes/textures/ctf_classes_skin_knight_blue.png new file mode 100644 index 0000000000000000000000000000000000000000..eba75f8d97a3111b5463aabf2ecebf581ed45d56 GIT binary patch literal 1380 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 V9Q-S9t?2*&002ovPDHLkV1kstgS7wv literal 0 HcmV?d00001 diff --git a/mods/ctf/ctf_classes/textures/ctf_classes_skin_shooter_red.png b/mods/ctf/ctf_classes/textures/ctf_classes_skin_shooter_red.png new file mode 100644 index 0000000000000000000000000000000000000000..55649e1fa8fcc165c439b7256644cfa048f0710e GIT binary patch literal 3367 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 literal 0 HcmV?d00001 diff --git a/mods/ctf/ctf_classes/textures/ctf_classes_skins_knight_blue.png b/mods/ctf/ctf_classes/textures/ctf_classes_skins_knight_blue.png deleted file mode 100644 index 76ab60cbaee413afc3e861cd749294e8fee61985..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7414 zcmV zaB^>EX>4U6ba`-PAZ2)IW&i+q+O3&sk|Vitg#Y6dIznOzEXToWrW@$^`W(z+_w<{2 zW>2Q7nIf6Y#1i4*?tymufByTp|KcY-HMnG@=9crrPim=!&YSvtem<}MN%!ylN$*#D z{>yb2e!d7?ioC|p$GqSBJJ;>k1LYmbkH21bWxnIoccAx+p8=z0)@<*6^&KdN&vpNP zcI|zxr{A{o{vXR7;(PO-pHm?i%eWYW3p@Jw@K+Cp$O>YMo!7|U5Cb>qn%>*JUj9CI z?)&zS;MISK-P7MY;$K7Ip8VdB|A^6h-P_;C?ndbM75SgH;jdq;`RwQSpWkA4&Z_6^ z&+dB4L@K*?Q_nlZeaDT1P{#XM=C|;_@xI*O#&2bdlb|oMIryE<3Of{DLzp4nYc-b8!n_Gc`t>Ii(z9HwJKyw`nV09z;2F#- zn}7bgzq|N<`TY)bj-czkf>}SYVqHN1WEskw{&E)y@#l@H-T2;L_f6}sA0;-DLAznD zY_LD$GsH0e3tRE#IdY#p$-U+5%X$YOM9gh0#z!*nWFO6E|CA7l_r$T1pU%odOkt1# zZx)t!hup-NNlp!#n`er@_XZ1}%TNo6u$W^ZH53rZO3A=aNfiurivG6HhvJ@+qgD zcKSDKZ&v@BHUCHE{(aW`n>A%D-TTU~tZ})NpCP>H#FR5K7Lq69MHv9lK{

PbnyK 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 W%LH36fijf<0000 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 diff --git a/mods/ctf/ctf_classes/textures/ctf_classes_skins_medic_red.png b/mods/ctf/ctf_classes/textures/ctf_classes_skins_medic_red.png deleted file mode 100644 index e701b841c627ff3949d7b55717be84a63f8c9f7e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7375 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 BIko@* diff --git a/mods/ctf/ctf_classes/textures/ctf_classes_skins_shooter_blue.png b/mods/ctf/ctf_classes/textures/ctf_classes_skins_shooter_blue.png deleted file mode 100644 index 1d362d05995f22ed7a2f85800ec8c6611c8c5668..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7518 zcmV-k9iifhP) zaB^>EX>4U6ba`-PAZ2)IW&i+q+O3&uawNG8g#YstJ_27L$m8%C;T!n){=h1=G_$jg zu*1@>y1TlH4O0W;#n*tzX13Yh`|3MTiqG}%es=AB zuIC@ydH+v(hxpw5`{%3#V+j{ibaAJUJb&%Mm{>t-sq>on8&l*ayJqk6{agPWJNJ3} zTkz`N#LoBkj`V9NoG6ht<=-LhJ8m2dmF{DOU*&({z24u(Z)J;NwO1>A}Upy^pZ+0QcBTc9Mv^x zR?(uWRh#yjYOYdC)mm$-y~UQGFlnW!Yqho3JCk;X?mXSOqxTU<8hOYlLq{EL^hx^6 zJY|-tv(7gAiYqP3f0dqLEZ_U|8#OMgehm?fPQ)++v6usht06!_N5jn5kaINT3^U&%MIjN?f*3d} z7-ArpcZhPr2fJ_N{v&Qq@_&U}{5#~FLHGYa&KYzsa(~6`52&qv6(wDOtO_lrJ{^dS z8+PrncGINibvId~Yskxwwoi^n`v@|}2&-gSY)2)pJd5m>t7jo@q}7q6DY{ZzB5Rfu zgm|v9Yw5ko>FuOi7K3GGI9X%gdmkw))wz5h+~Qs8Qg&yERt^taeA)WC5d;uTe%$ z?j1!(vQZlM*eFY;hRGFT!I%&kbS_fs zQAKooX8gMeGpW&2P#0><^8`(~pS%Y-pc2~vvvOt&i|8$a+R>v)L_{pgarjmF7$cx@ zbFj=#fsCcJT7chJf@gf0O@goz5(%j)W0T)!=-Q1K_nk}aX;~)oz=@uuaXk)#Yj63_ z|Ne??2vhPIy;H$Fon&@}hextGNhNL6!}7_cO_5N?b;ll*ol|L2Nt~@G_p&X0b}HR= zTu3uZP*Dg$dbSXZ6~SdsH&1GF5uxeVng{N=*?m|BMgL~{0t0H*fY@y%dqoP)k>1Gx zvP6$7ddSw%2?pyqm9>#bYpgw>2Sx}cW@CUW?AAqN?iJPFFw5FoSKQ&GJRMkg_=B?7 zKDCwABh@OqiU)Wh5tcu392LrW&T~RR>!-p8BEc5CTb)-$8YA-LSR{Z1{?@%=g92$w z+Pl|KfrIKHB<+bZ^hrXLVkL5B{XKAme-es%cq;D#D;*Ef5h}=(94Qtv z*HuY~Jr_l{rEc<VRP_WTVP<2E!cdJACj2~t(4IjU;UgQWkG;~ks4&>H zvFvdAI*D!IXqiG)S;lYIbOw0C-{K=m8=!#r6edd4)`fZwirqBJ4d8ZU$zV&+7EAtJ7FK2@N>D^qIhR z2#QJ7hSnWr2+i!1kKWrbYtTPiUiAmG#6|KZ2`F_n$F zcCEGygtw&$_b(|U*h9s_$U|*#@57H554|ao(39XQ_JIaxhFE}}O%Ha7WP_cDBo0%P z*K3vYEguIyTbfv0=wC}!44tfLtb6u&_d2e&a|sbMZ_H&*XS5%*Kj4jYb0pC7z)+$=4kvcWSv zSP)oYp=W7Daj-EwYUM!L-HD%hw`C7hxFcc=tkkkQovmH08cfOPD_(lVB^!+AelC=vsJ48ad1>(w_)GW+_IWCZC`0OLoB!H^3s%mGUz z1q#5#^s1I=Vc-FV&xap_PH~3hajKQVSwlAf&ZR=rTS8#%?Cy@WFN7kybBiC2} z;xcfjk#NF>1dU+PbvBY>5{kGplfePVkikjlex$5S3E1pM%WCD32R*D%69)wFzPymIGS0u!UE; z?#sRQ%d)0-s%^ku6=_@e0eK{Qj~29bw8fBQ;!FKzsMkGNMW-T zz7_KTYby5N0@qBZ`4aKCFbs$)X_Yf?Qqt>?4^m*2l`*4M>2ye#G3ut-^t)n4n^kFA zSk%5kOWQ0fnMH0utG8FkcucZU;59~`4q02#3?bskGR#sQQ)_Yyhth{a_~-@5k;f)2 z2jb?IPQw>W$S6;=zq^$sCTd`!EHn+C*}GzmZW{oh_xT+Xk;z)yEmv#yAQWf-SA=D9 zY$2r1x~qkS8o=K33JIX(G-;^bDP%tMaAv9BZ_tWJC4aqf#3Vp2BxfN7X^7Vadt2L3 zFYxrL?`t48t%Nd#pUk}~eJF$&K*6!kdI=r&TmZ$MJGo6QhEb1CDF=`sOL26Bv(p5I zhzj-`_y!5b^OC30t?8=_j2s>a=Z@K}=zAzWA@^#8N;eT%J3PW&+RR27ITG(yl39AV zX<(1BuzmCp2?h*9eORe>lpX()gqqu!vyd%!;I>2?fbB>xvzg25m)V?I0rC;@4>J?E zWWTsDb4tC`%_G7(uAd-AGU>wU#_0_=rjpcB+Dx8w-9zWr`Z2I&8>TXm>ys7dZ7o&B9uEuspfhgQ++qFsdQ9^^P-n8xB$}Zt)wT`mVf?%( ztGFF$F_szIK~eBtxn}>?5Pf8HLDg_N&HqQTmvck=~TOIL?MMQ@NAvybv% z!|Lc>dvVQMAM5GJugMD-8O)o}7kYaOkwVTasOZ;cQUjj4#|q7?jZ(hN+2P6lx@Xv3 zv8vnbgt6VfxN`?DpgP=}eUdLC9@?ZTTNM z-W~;cFp$moQETCS6rxOC@c(&ZK+Gx7uYfHQkEI~V$Thi5N<|3>9t9hir_5;8uMRx& zS{iX==N6&$1ae})8#9K$Bd{xi1C5vflj3HA&1&hqzMD24j&#>dh3Bk?j3iMKvS`{s z2+S4S6?a_L*b#}ledl`>E;t#<@f{DDCwULILiV#K8bEpj`;{ixVCoY`3Sz0fSL+4J0BgVy7#tuc9qjSJ-h-M$rz-C|Xvh#f}jk?wuGiYg`8P@L3&J z3qslm9Kv?nLg)mnNPGMSxgyKi2@&R*@=F;C(PzicS(BY7|FT_V^O91D;=dUQACd;T zW*NThC{}EIrRsnP^NCv^Z7i25zI;y^Azpd|pwwvxsUWF$k<_u<_8{cN7)UUx$6B%c zcSy%w#?E<8Ei& zRE1YZSG>XJcFrsfj<824s<+p=Z58tp3_Iuz=9Z?SRJTZ;)s$G4%dqdV1ACn$QymX0e(-C=m|@*GcF=tiv2?r1Ci2nd$>kB2}_tXI}Sywuzr&*qFk$B z`T{DtaZnjPuTLpHs-6w#4%HIY4K6gj{aQ&}$G%PDOmr01ijMRgJmJLAPIMeeAS({N zfEloG1UG_nD|G%DOJEkR*y+jAhsUedIenq;@fQ5k@C2|-yTX!Zyvxqf{yBKKNcP%M zlO0-MCm0e#Zn3Wqo6SxyuH~h-dyH7^3`gyZ@R|0~E-UIJ4Lh6G(wl_E2k1P90iC3$ z574-J8VBFV;t$R-T4$l|WurldiN5OXs?BW2W@2P{M1ZFDo-++?F&(ponPkd)b^~(I z2rUC!Vxc+2Nn@!i;Uu~ye{lei^K2m3GH$#1aqALe)`3@gG z000aA9d?{x_YL2x>NHJF`}6X#KD*#MjxUNf*4Um zRD!4=DDh$RNl?hBql5&U(T7Bc4{FePQG{SJ5ringQ4nR4%t!Zh`m3tDrmJq%t$Xe{ zXYajy*yrA^+uiA^p-0cly>;rGz4rdEwf^hB))kJqKK$gGR!zVM1p#LbMgRpdf&jIT z#Hd&+bMFemzrVFB_gnvEx_almAEBJR^JDLSM9bRaLqrgqGZ+z2#hCP1?IR&XoHKA_ zH4)*Tzp;H^`{pgj7I>AH079lAwSUuj^hBi#|C0l zRF!w*Iu-yULTtm`h!9l?QL!d{M{?FR6OtoMH1iCO=z<%*>8L#9ErUD zGXR`5G(Hej5rl9g^o)Qjy0a9RhO6s#aNT=m&pW;{Yp7ytUu5QW)f9yf4Db&=v8K~f z7h}X2nGuc=C^AbE;;i&d(?X=(Toaf^qN)<3VvNCAA+v@iByfC)v*%2!CjeFlU1}fj zAriv8mM})>8**pJtN}5z($Iv+LER)aMv-=5l~kgXwqCb{8KN?En2(@D1ei3Q5R`BP{29qc zWq4T8$t;<(h`U{x8Xp)QHe}Wi+e|b@5R>>~>aY;BwV60<`W@d!c+|9D?#wK|iOEBX zqCTPd#m|2hfS>!7PXa9uL?v^AU=m3hnUP}?l&R%EqLIcM5; z!CA{c{r7bN`0=OC=oADSGyx+dv19~iEI}3TBQYi?B!Fa2p-vqlPd~b((_H_%&wZL0 zJU{bm&jJaQgRDhs+gFViD^p|+%nH^qw{!0M-)UzMs>tA2zr9T@{ z43=krMDN)>IBbOrGtx35bnyNb<4>GxF>f^A0?m_yj+p{@vZ1*-UJf}f1pzIvJMtC#VUF}|9B z>g>7D)M$)E@A;b-pG(crtXm5+^)_YmDLW_oW{$}p^!nhbQkasfzk}biSM9>FiJ<|J8K_g(+VpZ|i6wqGM( zJdOH_uYGcZ$?kPJD-Sc-z0Q+A`K&yU67;^pW!+iMFe*t&d1V#a3F zb^XpdFEPYw3?dkp14{G_VSE6jbTTeSHKYTJAs?I~ln3}~|Jdb2xr?!m=5QCHpYwia z<>3bhK*S(oP>pExbh}+*Oj6Vsb8H0k9y-hZ#Vwk0gkVw`5Fy5h1dr=45~~S*JRTNoM&ACBP(e8opTvz5x_WXwlC zvqkU~7>DF51m9r$8%Wm06zkYxz{1%NV2c68+T#>U4^yl@PN*AP?=&%ZO#d_{>tPoj z#$-LR-A~I;TJk#oFWa*Ef$(fnwo2<-r9|rML86tShiCC-{mO!z}-8 z*1@?BAv9PKoa@rmBM3Eqyo2Nen%#>?*2lU6*IDGlfBZ%gJ%clNm%OgcA(9X9+=5+45PG37yrmls7LSDE01Jn0$fQjBtZ> z{Qed4rBgHq*XTU*-s1sKjdT_^F~%as&Xqh+L{cQA%3x4mC5k@jT{KIkY*%t(?JlPd3<~ z8E%uUY!b>{=&i!x+w|5SqgY%a>#q>XA*vbW+n2~!-h*hMyS_3t1LeD{YY$1 zK!U1>F=WL8aT?;Pi3BwwVll2rLrzF3p%It&5-ZmwCX{4@hp28{Buox?tM}`0{)mzh==>qxdlD0gYbyTtkuz4afZ-rvF&1I9aV5ULVCyoMg%BfRA1l5qr+0j9@MtnU6gix3G@fNCr-`Rt;^wjHo z0)}^t*qf5c&Kroyh+#yiOG5cAT>ljQV2f;Fje2+uV=UFqMWVug{J{?aLe}kLTxztc zk%9Oys^0@BuG`1u9bkp}a2eHzu^Bdhg!BJ!3;;=s&;LMVj6;kghGr&b=e2?*MvpNL zn|CQzH)#&vChM($!h6Oq&|O}`c9&Z5GUOZe&mvihmS((5)?cF;A0owRY-Sle`n`m5 zNN43Np&SyUquRSXvwgJRaCwIqJfW%Dx%|9P%eo7Mx|-v(`*1)zHJA=MeCp>lGz34! z+WuTCDPpj$z!-=36GB~5-h7?j+Bw2x4+y^8BRMSXB1y_0p*k8q(TPWH&V3yg2R zPN++Cd<(O5hVsVi*rHE;a06TPsdnEa`gnU#aO8|OFOXn~!MB=3?;53N-TujxU<`+- z)`;9jcy!~-X-u{B3^9xeO$2SGaZC&m4MGf6ih#xQ*t|!+^ay7!e2Q#2A>TdqWZNHH z;moZ+BHo`{RKu%n#kp6%pE^0QZY}~u3^4?( zIoZ!f&W~P69(HcV0Yy;|VL-W_Dj%egD3Te~OhfqtC1`t|Mgw z*(LbPXHymUh3Bu+1n6FdUT$bYnidC5<2WBv|1R8)_Nb61*DoT*AjYJ_Mnm*I>5%q* os3+;yDPy4>eAI{gCj#Jq0RbcZb-&WDe*gdg07*qoM6N<$g7H^n#{d8T diff --git a/mods/ctf/ctf_classes/textures/ctf_classes_skins_shooter_red.png b/mods/ctf/ctf_classes/textures/ctf_classes_skins_shooter_red.png deleted file mode 100644 index d6645eb80f7028f87ba1f42b3de3a65592ad7173..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7189 zcmV+w9O~nVP) zaB^>EX>4U6ba`-PAZ2)IW&i+q+O3({aV*KPME_HYCqnLvIJufp1B(BSXB8U2S*yMG)pw%cpX=`ZY}z}n z#~;Ue|Alg=_}u*G=U52FN?Z)y_#IrZ{MA4o*g{TjjvEJ|40l-Ox9~6VzTDr&Z{>)Spf9pH_?^Zz=ZW@l(Jj~Aar?ebH`!wJ z+ZSHFpFZ4cH5A|cya|Z?n^eBx13#B?*xR1wG*3hfehH}LUP&J;(c+BI9Br0**Q@6gABNo{Bq`y zn-DU|sa|U{rnq~rPyV?KwUCGuaww#R0wP&4Ch${Y1w%cB6irGgr;=)FsppVmPC4h2 z#ZkS45=$z%lu}D8y@ncVs=1b0YpcEa7ND@yax13Q)>`i@+L^jDx^qYG!;diHNF$Fj z>S&`+;4|Y)GtV;XY_l)F!lL|FUd61s+UnbFptR#oJMXgVZo40_cEX7#oqWovr=9-E z+MCtiS#y76?%!w4y;)Pn;=QkYXN}9Hd`;m*CrLRYV?H`EUX%dCQEnH2w{y!pS&oKfoj7nw6k-J7|8&D&pOZS|`t z;U-8`sF>PtAU1B;wfowoNzdzUX^mc7Tz0g5qCce%m*yC5<(L-7DJiZvbJ{Id%SOxy zt0PG>l@*PaSd-h&Ph0jgjRhPHX zHkvCGKsm?nr7x^M1f!-@#%IO9TQCBR9$Yc5`Z$j(A@&pZ00SlYHpp2%v$;j|7D4Uk z(Ig@%DawA>Rr%;WN#kZGWCsUgDXr$$VfA-H;Y=fIAp3yrM%;=D2FYxdPS`#RhMm;PWOxP3&bzHaau5fZH zEmeTC%ZWX2!Dolub>a-n1kh9Nd!h_|0*IVdl1O5J_KdlzE6ICU|Z_~r%fDdYDYvkdm!9Q%r>9h zm4Dq`@!0}sl4En9f!vOSVp6rPbwe4F^T>%OH!&0~2nZ5E6AXbH2S-qn69U3qupP8T z%9ROjKMzBjOVMWsI<>KD)iw~`7AD-kQXWo&vckxqHn{iU$D5CGAra6MXDarA24^~- zNj--ioD#_n&hW%_HO-48%b(vrl5}WkgW?21y*;#_+kixzui~-a|p$Pewa5 z9g#jic;}dzn@44xWqNW!U=tfXt5g&R8^chQ17&v?e%9SW4^+54VoX}8Wpg@5ySZvG zC9^Mo=@pl(G@kp_`0&2m{3;-T=A@##iYxqFkMTuVDNz)O0YHY}2f%vuO(4_PACM8G zPXUY{5Q8BXTo@geC}k)B6Vq!E(%is*V2M&?OL4#YU%vEzd_|``tX#2vgd-0T3ty*l zuGoipp4HD?y&V9&N9r|ZPiiS}PTM9*$zb0xV5W)7p$yy^ez{SW1Rnar3=#O&*5;Tj z#&Kg3xo~8OxP+eM@6;YHG;Y&oFHdY%`fz=DxgKu%sq+m!E-j70rQEj7xwftSu&~KE zLH6UoKl@2*Ro{_oEC6vCxKmF!VMBsOu;@A)pqPZh@5o|sM36Eb)7TeG(Qq0SU8Fo4 zLC?8HPZi31(}^h?U_^u4iZcmcNze$~^951KHQG5qHb!~ekW-KXxE8IW90NnNoGaph#YfXw6zMgS%Nij>Bf7)fw#wl!*#G&5rUW$KeI4( zcybw2msTZwi=M4@MzD+$M}+1o*6nT_wk(Q6lI%G|tHuKLljlv|Qlt0UK12lBxqjE$ z^t=K(l^dYlMwNKF=7Mn(w~N$;p)Id)Bd{|S0j^Q&Rp|k+css{{ghFrE34wmI?#=8c zNN$mIIu4E$tV|T(1$(|jO}Lh$mJjS*A;xpmg)UKBmk14@P(?Ik8&<1S_T?M6qf0U* zN^eLj{5Cf>MBIgA!Q(xx2glx!|5qMQ1a)jIWPIPu7_sIx;=uS#W@NSStdemwXdF>L zI8^}GL6xzm2zA)5nd|o(l)zJ`pEnIp5dzGJW`=Ve4~HWGU+%|z+aQmvzs>?pMQS<2 zz=u2bQdeQbhG$u>ezbxIbQ$+82B#dF8YtP)td#H_Oc*;=G z09mS<`q)*z2UKQvoH*o*lp#M1{zJ;QXpdiC#zVq_6RUK?fNWpsf}T-)eI&fd1Wnq~ z33j<)t0_~wE|Pu{-o5rs8lbM*6~a7NI(Fi*nT!eS*wrfkB$rKWASGgqpLe(q2TNi7 zh&E8i5OUWY6CqSt7O^$8OCM{MsVV*PgPxKTC150L2I!Lx)T7WM`vx!E6h>TmNST{T>bx3PLJ1NHF z=1VP3JzEt^$c!#P7xXNVfj54gnXSAoT=7(I2@<*Fv29&#f+yYw5`>vAIBBSZGlYUe zrY8ITx@y!%Yh*|rSy(4J$Q0V$>Q~3D%y5N79!$YgAZTjfhcy%^IO>K5ifV~IfSO!y z_eQVQzPpp*uQWjqw+%!HHWT5{QTWoUdZ2}mV0*C5yq%v|&E-qQh!iZUCmY1D<9_I| zs7kDxM57u?6~mNK$A%@yKME;jm+eKZo+@BaVnH)6GJ~E&+;W%*aL{LS%VS{*aZVi? zzSi;9T^|yqaMXtc#Bx{lycFoce>UrUy01=+13z&oyS&}U$$BuEK&T1EF?f9-UMJ8o6lm!?9;W6RK4qD(EQJ0? z)n?a!X~EuEF7{bPN2BS8k_324b%ga8j|t{(?2yEfv=n%gRtpB$8mfbKzzY6Ar}k^q z!lV=sq7Fht?Bf#xx>&10{yAA}AQ$F+NFuetqAK3ICj)jV78>w5mStz}Z>zCAQu2=uWaD zfO3$hSroN9JqmF)EsQ-kz%X>c!H8uVpkFFvD2#Gzm^rkvD6&*3b4KbT>8a9PKIRN> z;(ygXboIm-J;U)4K)0MME6py-A2?gkvka`F9*Q7>dQzzSD;X*i`oRKN?U2-qefltQ zOs#ZVl%oe%NUfSJa0$WoKvAA9$7kf~_in-?><9C=Dv$ z#;7eyFw;?C^kHrsYDmkQopJh(CO*mJsUnFWoqd8=>ut`DR2Oeq;^n7G9yXp|NsOTC z8jV`a)&2VRW1J(YXAF8EgNV{j10Y##q;u8j`{sNDd*>>)0r zP$57WvL?~DE8%+d)I?43>enw((day&sYlO=Ml#Db{SVMa)8i>VdcAVlBA3V95@XV; zbsuISU>nCmm!tL|;>yGGXl&|90Xeyk2>@l!6A`V07J^~|<#qg;hyu_0KQHcXSxGgmzL}~#sZGxopxq8it(2PSpHZ?A|N>mZ+5Rd$$2evtyk?idEsSx%` zHXWUXX<(vKC8jhlQ*A~AB-~p;vL0)p=#s@1Y9vIEpBd3-iNy{D4^000SaNLh0L01FcU01FcV0GgZ_00007 zbV*G`2jc@40T?Df0>+F001N3!L_t(&-o2Skj3w7q$A9PCTUGD9?w&HNKq7r6_Fx) z6NMNj;}0g|v1gpNdwRP2)vLN6hsCY;x_f3a)7BX7=9TJI-E;5%obx~bb4$3*_=Woq zTNe^B83=f%r~n3{f&hKYoueSprq)bf3SnVB71T)BH#FXh{#;j~!MewS4 zEsHda{fzmBcW-M3qBr`(H3-F6$3P6=tRQG4!-xh$F@lI(fMPz4v zDHj0#>B~=Gu_JatZ7r&~0u%^fdLr0`82 z(vWS%eu$a0EAsx&0Ps!;F_Fy>gtRO4RKPdmMGDNr)sIK`@lCVmJ&(#MT^{Uhf&Zx?Qa8#hF93kaJ>6@p8$gsGOm`9?Sk+Y$ycqdd&38{b+Q(io$ zgPs65v@)iTiI_4e?bQ;h!l?Fyq15JKg83RNugvRHXsB%=^A%3Sag_zjb4pdIbLnf*UqJ=N!4ok@fn}x&X*Tf;hvy};J zuZ#R97Y`YR#e(M7zWOBqe)BVb0t`Hmjmisx7Lrt1kYh;3eD0DyJ0(Tf0X*jtIdwIN ztl=r|b$A!NbA01_ZwbJ!eB^}9L2$_mFhUVaDtL7yGh)o-T%1q-oEh7ukzeeJ0}FuLcrJw=%b6S_|NNCFOLMg7*3v?~&Dng;&c(j&Ve&g2-+JkaIHwEyU4Ntf zt}phz2#CQye&xy1%DEx~Ca=*_lY=!UtL@J?^kDxZAtxXpF8L-_aCH+SiLV>+GQ za-m;7ciLW^wLJEBe>MP9Hu=||{sPBF6&oqB6(Vuy#h1j2!L_3E%E# zG$#0Fyl9UNxXXKLl#nCNgcG9?Bc~|vMmsCE_aSX#j2vldPEICV>ALq{3Rmg|QUfna z-}mpS^HN}%Gl-zR28}`@&4%G zJ$DX(6Tx{QMMElMJRXyCk)o=4+X%RCG~sf%MrgMXw3Go6a?Zpo98k}U%vO%HeFB9H z)T;E{J_3%`HEXe_5dqaZuNDs-U$H}zg2UQ0a^}!zAs_&1r-W=|%jh75jh&YGgX_=( zhbm7Ojj*1wK$$w9#n1@NS6IzyV*==D>PP9P*xN&Unh4 zr2R@uP)u1TveQ~9gM9$4}wUj zRq;;Au-JSyNJ9sf;!bBaR^ga;gp@ew1rKy7@yugSmU20p^2}pT(xrq44tgP^#4+y} zt8k=JR-EIf4=l6d9cM=k_lz3Ojv4}q<0DVZnd45GIOQJim^kHBUEzU4mEwUT1D_nN z%kSAy!|COv+eg5!efVyB^_>=g2aZf=Do3S`E+l3#E<9eTW7K#;pGam*8qek|aONsp z%b67wHnXuL!iE_i8jrX%3jmxLRlMBJSQTO0Z1L=Y!IO9UifAQ@<`J-#B5Ij78zCi< z2=|RgglOD19&w>-$tm;W5Li|vh;T$boft=}ns-v*fypwz|MK};Mu1PzICE%(isE*u zB^wSqoCqPqr1l6xk0B~xrH zyX%VAyN=D6_@hTI++gT)&mSdN;`Oeh66Ng>fXr(lvr;=Q#K3BHTqe_G;bI7kMOe#` zu?TO^BBQ06wYFu+IsWU~6qU?+Oq`mGxfU`jb5gFB~HS$?2jLLjhD8jG$LHhndQ3X{B%ki6YrXFVx*iO za{KMRXUREU-R{Wbor8j1YjkykBu7qhXvXY@qx5RLv_B=d)n_U-Y}Y2g@%k2K#?KzB znTAZVM4X@J8Cc4Q8C}ebz2nrRVd5P3)-{`9N1xw69xtvxP*)@o?jMiYNQqOEhHg7? zTm-S5`}fv08!2&mso~PBEBqrj>-S41C(iGQ01+jpgwy?fHu5k2I3gl=zrz7d(~xuK zg|&pL0vXj*#7`=}^Xmu3@alHQnWf^rnBlX}AK~0MaCOiT-~0ASUhAfusGEhSU)%0z zV`39fB5Uuy!(BS)00)<59f!O}oDMyFf*5cE4e}+^gPD00000NkvXXu0mjfKwi|N From 26b5654a44465beb99acab0ca406cca34cd658d3 Mon Sep 17 00:00:00 2001 From: rubenwardy Date: Fri, 22 Mar 2019 04:31:57 +0000 Subject: [PATCH 05/15] Remove false promises in class selection, add random messages --- .gitignore | 3 - .luacheckrc | 3 +- docs/accurate_statbar.patch | 18 ++++++ minetest.conf | 4 +- mods/ctf/ctf_classes/api.lua | 24 +++++--- mods/ctf/ctf_classes/gui.lua | 6 +- mods/ctf/ctf_classes/init.lua | 52 +++++++++++++----- mods/ctf/ctf_classes/mod.conf | 3 +- mods/ctf/ctf_classes/ranged.lua | 6 +- mods/ctf/ctf_classes/regen.lua | 18 ++---- .../textures/ctf_classes_skin_medic_blue.png | Bin 2016 -> 6669 bytes .../textures/ctf_classes_skin_medic_red.png | Bin 2036 -> 6719 bytes mods/other/random_messages/init.lua | 4 +- mods/pvp/hpregen/init.lua | 20 ++++--- mods/pvp/medkits/init.lua | 4 +- mods/pvp/shooter/grapple.lua | 2 +- 16 files changed, 107 insertions(+), 60 deletions(-) create mode 100644 docs/accurate_statbar.patch diff --git a/.gitignore b/.gitignore index a2fb45104d..9e132e18d3 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,3 @@ tags *.vim debug.txt - -## Files related to minetest development cycle -*.patch diff --git a/.luacheckrc b/.luacheckrc index b301ed904f..151f963d32 100644 --- a/.luacheckrc +++ b/.luacheckrc @@ -15,7 +15,8 @@ globals = { "crafting", "vector", "table", "minetest", "worldedit", "ctf", "ctf_flag", "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", "vote", "give_initial_stuff", "hud_score", "physics", "tsm_chests", + "armor", "shooter" } read_globals = { diff --git a/docs/accurate_statbar.patch b/docs/accurate_statbar.patch new file mode 100644 index 0000000000..8acf78b17a --- /dev/null +++ b/docs/accurate_statbar.patch @@ -0,0 +1,18 @@ +diff --git a/builtin/game/statbars.lua b/builtin/game/statbars.lua +index 46c947b6..f4372843 100644 +--- builtin/game/statbars.lua ++++ builtin/game/statbars.lua +@@ -24,12 +24,14 @@ local breath_bar_definition = { + local hud_ids = {} + + local function scaleToDefault(player, field) ++ return player["get_" .. field](player) +- -- Scale "hp" or "breath" to the default dimensions +- local current = player["get_" .. field](player) +- local nominal = core["PLAYER_MAX_".. field:upper() .. "_DEFAULT"] +- local max_display = math.max(nominal, +- math.max(player:get_properties()[field .. "_max"], current)) +- return current / max_display * nominal + end + + local function update_builtin_statbars(player) diff --git a/minetest.conf b/minetest.conf index 0eb278f54a..01019e1349 100644 --- a/minetest.conf +++ b/minetest.conf @@ -3,8 +3,8 @@ enable_pvp = true mg_name = singlenode vote.kick_vote = false barrier = 106 -regen_interval = 6 -regen_amount = 1 +hpregen.interval = 6 +hpregen.amount = 1 random_messages_interval = 60 sprint_stamina = 10 enable_lavacooling = false diff --git a/mods/ctf/ctf_classes/api.lua b/mods/ctf/ctf_classes/api.lua index 7da3d711f6..88728e87c2 100644 --- a/mods/ctf/ctf_classes/api.lua +++ b/mods/ctf/ctf_classes/api.lua @@ -4,10 +4,15 @@ function ctf_classes.register(cname, def) ctf_classes.__classes[cname] = def table.insert(ctf_classes.__classes_ordered, def) - def.max_hp = def.max_hp or 20 - def.speed = def.speed or 1 def.pros = def.pros or {} def.cons = def.cons or {} + + def.properties = def.properties or {} + if def.properties.can_capture == nil then + def.properties.can_capture = true + end + def.properties.speed = def.properties.speed or 1 + def.properties.max_hp = def.properties.max_hp or 20 end function ctf_classes.set_skin(player, color, class) @@ -44,12 +49,17 @@ end local function set_max_hp(player, max_hp) local cur_hp = player:get_hp() - local new_hp = cur_hp + max_hp - player:get_properties().hp_max + local old_max = player:get_properties().hp_max + local new_hp = cur_hp + max_hp - old_max player:set_properties({ hp_max = max_hp }) - assert(new_hp <= max_hp) + if new_hp > max_hp then + minetest.log("error", string.format("New hp %d is larger than new max %d, old max is %d", new_hp, max_hp, old_max)) + new_hp = max_hp + end + if cur_hp > max_hp then player:set_hp(max_hp) elseif new_hp > cur_hp then @@ -59,12 +69,12 @@ end function ctf_classes.update(player) local class = ctf_classes.get(player) - local color, _ = ctf_colors.get_color(ctf.player(player:get_player_name())) + local color = ctf_colors.get_color(ctf.player(player:get_player_name())).text - set_max_hp(player, class.max_hp) + set_max_hp(player, class.properties.max_hp) ctf_classes.set_skin(player, color, class) physics.set(player:get_player_name(), "ctf_classes:speed", { - speed = class.speed, + speed = class.properties.speed, }) end diff --git a/mods/ctf/ctf_classes/gui.lua b/mods/ctf/ctf_classes/gui.lua index 93c9d8bf4f..6eb3bcf136 100644 --- a/mods/ctf/ctf_classes/gui.lua +++ b/mods/ctf/ctf_classes/gui.lua @@ -66,9 +66,9 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) "Move closer to the flag to change classes!") end - for _, class in pairs(ctf_classes.__classes_ordered) do - if fields["select_" .. class.name] then - ctf_classes.set(player, class.name) + for name in pairs(ctf_classes.__classes) do + if fields["select_" .. name] then + ctf_classes.set(player, name) return true end end diff --git a/mods/ctf/ctf_classes/init.lua b/mods/ctf/ctf_classes/init.lua index 14d14558df..fdab6f29be 100644 --- a/mods/ctf/ctf_classes/init.lua +++ b/mods/ctf/ctf_classes/init.lua @@ -10,29 +10,43 @@ dofile(minetest.get_modpath("ctf_classes") .. "/ranged.lua") ctf_classes.register("knight", { description = "Knight", - pros = { "+10 HP", "+10% melee skill" }, + pros = { "+50% Health Points" }, cons = { "-10% speed" }, - max_hp = 30, color = "#ccc", + properties = { + max_hp = 30, + speed = 0.90, + }, }) ctf_classes.register("shooter", { description = "Shooter", - pros = { "+10% ranged skill", "Can use sniper rifles", "Can use grapling hooks" }, - cons = {}, - speed = 1.1, + pros = { "+10% ranged skill", "Rifles and grappling hooks" }, + cons = { "Can't capture the flag" }, color = "#c60", + properties = { + can_capture = false, + }, }) ctf_classes.register("medic", { description = "Medic", - speed = 1.1, - pros = { "x2 regen for nearby friendlies", "Free bandages" }, - cons = { "Can't capture the flag"}, + pros = { "x2 regen for nearby friendlies" }, + cons = { "-50% Health Points" }, color = "#0af", + properties = { + max_hp = 10, + }, }) -minetest.register_on_joinplayer(ctf_classes.update) + +minetest.register_on_joinplayer(function(player) + ctf_classes.update(player) + + if minetest.check_player_privs(player, { interact = true }) then + ctf_classes.show_gui(player:get_player_name()) + end +end) minetest.register_chatcommand("class", { func = function(name, params) @@ -72,12 +86,20 @@ local flags = { for _, flagname in pairs(flags) do local old_func = minetest.registered_nodes[flagname].on_punch local function on_punch(pos, node, player, ...) - if ctf_classes.get(player).name == "medic" then - local flag = ctf_flag.get(pos) - local team = ctf.player(player:get_player_name()).team - if not flag or not flag.team or not team or team ~= flag.team then - minetest.chat_send_player(player:get_player_name(), - "Medics can't capture the flag!") + local fpos = pos + if node.name:sub(1, 18) == "ctf_flag:flag_top_" then + fpos = vector.new(pos) + fpos.y = fpos.y - 1 + end + + local class = ctf_classes.get(player) + if not class.properties.can_capture then + local pname = player:get_player_name() + local flag = ctf_flag.get(fpos) + local team = ctf.player(pname).team + if flag and flag.team and team and team ~= flag.team then + minetest.chat_send_player(pname, + "You need to change classes to capture the flag!") return end end diff --git a/mods/ctf/ctf_classes/mod.conf b/mods/ctf/ctf_classes/mod.conf index ef91fb437b..c0e72d51ec 100644 --- a/mods/ctf/ctf_classes/mod.conf +++ b/mods/ctf/ctf_classes/mod.conf @@ -1,2 +1,3 @@ name = ctf_classes -depends = ctf, ctf_flag, ctf_colors, physics, shooter +depends = ctf, ctf_flag, ctf_colors, physics, shooter, hpregen +description = Adds classes, including knight, shooter, and medic diff --git a/mods/ctf/ctf_classes/ranged.lua b/mods/ctf/ctf_classes/ranged.lua index 73857f36f3..4f65452866 100644 --- a/mods/ctf/ctf_classes/ranged.lua +++ b/mods/ctf/ctf_classes/ranged.lua @@ -40,7 +40,7 @@ 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", + description = def.description .. "\n\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(), @@ -56,3 +56,7 @@ end check_grapple("shooter:grapple_gun_loaded") check_grapple("shooter:grapple_gun") + +minetest.override_item("shooter:rifle", { + description = "Rifle\n\nCan only be used by Shooters", +}) diff --git a/mods/ctf/ctf_classes/regen.lua b/mods/ctf/ctf_classes/regen.lua index bde42a28dc..6a0a958a39 100644 --- a/mods/ctf/ctf_classes/regen.lua +++ b/mods/ctf/ctf_classes/regen.lua @@ -1,13 +1,3 @@ -local regen_interval = tonumber(minetest.settings:get("regen_interval")) -if regen_interval <= 0 then - regen_interval = 6 -end - -local regen_amount = tonumber(minetest.settings:get("regen_amount")) -if regen_amount <= 0 then - regen_amount = 1 -end - local function regen_update() local get = ctf_classes.get local players = minetest.get_connected_players() @@ -54,7 +44,7 @@ local function regen_update() local medics = medic_by_team[tname] for j=1, #medics do if sqdist(pos, medics[j]) < 100 then - hp = hp + regen_amount + hp = hp + hpregen.amount player:set_hp(hp) break end @@ -63,13 +53,13 @@ local function regen_update() end end -local update = regen_interval / 2 +local update = hpregen.interval / 2 minetest.register_globalstep(function(delta) update = update + delta - if update < regen_interval then + if update < hpregen.interval then return end - update = update - regen_interval + update = update - hpregen.interval regen_update() end) diff --git a/mods/ctf/ctf_classes/textures/ctf_classes_skin_medic_blue.png b/mods/ctf/ctf_classes/textures/ctf_classes_skin_medic_blue.png index 68ddb3b6889bc5f28deb0cedbb7e311c14c17b4a..15491c5a9369cc7043183b9815fd3e60b576c1c0 100644 GIT binary patch delta 6028 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 diff --git a/mods/ctf/ctf_classes/textures/ctf_classes_skin_medic_red.png b/mods/ctf/ctf_classes/textures/ctf_classes_skin_medic_red.png index 9b72df77984546d387b49067d01ddcb0817bc100..b6294d69809de70240ce3f949b4dd50c3094f5d7 100644 GIT binary patch literal 6719 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 VH|bc!?3w@o002ovPDHLkV1hD}r-c9j delta 2023 zcmVA^=6hJ5zK`9qEA`&LMj(MCKNg(6Wz6z+_8_?s)g34f!3yg+kdf+-nf}cFdIiM8Qimx z+pmh(r+(V5iQKY~-nW=WEg3r`6Wz9!+p&+6mIV2O~z@tSh89F2s;k=*Uxtq|hl-#qE|Ns9sHtXWP zpy0cl;JTdPyPe#!lFX%s-nWSK z5&);Cr>v~3ySuwx6%~SRNNpGxR1*`15ddLOHwfYTuw7)Ryj^WD@+j)rK6}yCl@>)6Y1vdRTC3*VnJ+LJ4+D}S`-v{cXx(`g=ZHR zbs8GmvXU+&9X}xyUlkQ>7#K|{7)THh;=ZBXw11S|wwE{_65za^;=iHdzoI@cCyH9T z6#xJL0d!JMQvg8b*k%9#010qNS#tmYE+YT{E+YYWr9XB600jj}L_t(Y$BmSWR})7R zhd0>}nhi;oV6vFml?B>bpjZRg()3Af35d}|g%uG*@EIVafp&SQG}HxbU~xf65n2VQ zN`Lx50cn-mLh)5vr7f-gJDmyTaS}MEzjNl~&fIgqx%bZ9VAy|>$#F%5GV(bUfvcgS zun=jqIx<=xvtfh5sHG?>Hq?(Pablwh$kha`1|}0whx+wKW>Xxir3@s+#%*A=VE{Tx z79Ss<01}^n;l<6HUrGw~ld+oQ-!&s0buheHaeDB7qF402`G8C)tZxIHs^-=H<66NU|@EH1*U_%oiJ1`Q-1=r z8YpFQf}nTifph?9n~eq_lVx@>45QtxXJHEZ-CDTW#ju$yOWN%u%VKhc1GmtMJcoQw zLc$)oBTqqFaEC%pEB5Z&w^u=H$poE&%x4OAq@|>!?I>XKNrNtd)RJU@-CjVF7-5q~ z0*gthP;nf5MTOF20g-YWfjb;Fn}5TBXBo9IEET8E-;ZI*$@}y5aTFV)HD(zL3+?v8 zLL-LbQ3r|ukU6qBsBDJ}fT9CYIF8d6g0RrIP6wx!Wi^G16&Gq?)>y1gXCx_ufg+8t z``};^3@$D?#Bqm8iXo)vAfO2wA%h}p47tYeu_R;6(m-VyF-smOMVA*JMt>O`E=FmT zf;)W10hJi3B;X^$ha~hT*P5D>dV}50Fm}5kxOG-k zR93lMRZH&bYWIg$cXhR=x__p&wx-&%bpFxDd>xm{rH1k9>+36A4GpdpK;x<0MhK{> zJ$<^iW*Ja&=1kN71GwFvWV_vK0$@BB20$gapq2q%Z%(t5YTD=BGfJNKCnowW1k+ExH(JDkpXh(H)>3#Kj(5y>{&?TB~}nSUbGk=|mY+ zG+n>$>*^F?6iof{Fiam_FLic~1Og)?fsvM$ui=8mx)}(=-=L<6(#0-8`1U(NXzxcw z2%|S{jE>$I4Fqo93X_9pO}~!AA`Tab!&3+`yX!IzJGJ;PS@0rcYpf1bNcqo z?U|WhmNOU$$zTkHkFNk`eZJYLdxQ5M4BneU_N?#Wqel;YvsP;v`qHhxCUIPIDYr6A zZ~!O9=H_5#?UR0QecZo{fz?a|Od) zRi1^r9uFe$g2%J4uxy)?T3buupG|r5sq*6)*5;-7e*yCv4ed 0 then - local newhp = oldhp + regen_amount + local newhp = oldhp + hpregen.amount if newhp > player:get_properties().hp_max then newhp = player:get_properties().hp_max end @@ -26,10 +28,10 @@ end local update = 0 minetest.register_globalstep(function(delta) update = update + delta - if update < regen_interval then + if update < hpregen.interval then return end - update = update - regen_interval + update = update - hpregen.interval regen_all() end) diff --git a/mods/pvp/medkits/init.lua b/mods/pvp/medkits/init.lua index 9450b29e97..791ae3359e 100644 --- a/mods/pvp/medkits/init.lua +++ b/mods/pvp/medkits/init.lua @@ -8,7 +8,7 @@ local players = {} local regen_max = 20 -- Max HP provided by one medkit local regen_interval = 0.5 -- Time in seconds between each iteration -local regen_timer = 0 -- Timer to keep track of regen_interval +local regen_timer = 0 -- Timer to keep track of hpregen.interval local regen_step = 1 -- Number of HP added every iteration -- Boolean function for use by other mods to check if a player is healing @@ -54,7 +54,7 @@ local function stop_healing(player, interrupted) players[name] = nil if interrupted then minetest.chat_send_player(name, minetest.colorize("#FF4444", - "Your healing was interrupted!")) + "Your healing was interrupted!")) player:set_hp(info.hp) player:get_inventory():add_item("main", ItemStack("medkits:medkit 1")) end diff --git a/mods/pvp/shooter/grapple.lua b/mods/pvp/shooter/grapple.lua index a6f25997b1..4e902fadeb 100644 --- a/mods/pvp/shooter/grapple.lua +++ b/mods/pvp/shooter/grapple.lua @@ -112,7 +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) + itemstack:add_wear(65536 / 8) throw_hook(itemstack, user, 20) return "shooter:grapple_gun" end, From 81bd77c8dc43a41824831d818763987c71d70a78 Mon Sep 17 00:00:00 2001 From: rubenwardy Date: Fri, 13 Mar 2020 21:58:42 +0000 Subject: [PATCH 06/15] Add class items --- mods/ctf/ctf_bandages/init.lua | 2 +- mods/ctf/ctf_classes/api.lua | 39 +- mods/ctf/ctf_classes/gui.lua | 18 + mods/ctf/ctf_classes/init.lua | 38 +- mods/ctf/ctf_classes/items.lua | 60 ++++ mods/ctf/ctf_classes/mod.conf | 2 +- mods/ctf/ctf_classes/ranged.lua | 7 + mods/ctf/ctf_crafting/init.lua | 39 +- mods/ctf/ctf_flag/api.lua | 5 +- mods/ctf/ctf_map/ctf_map_core/chest.lua | 336 +++++++++--------- mods/ctf/ctf_map/ctf_map_core/init.lua | 9 +- .../ctf/ctf_map/ctf_map_core/meta_helpers.lua | 2 +- mods/ctf/ctf_map/ctf_map_core/mod.conf | 2 +- mods/ctf/ctf_treasure/init.lua | 4 +- mods/other/crafting | 2 +- .../give_initial_stuff/init.lua} | 26 +- mods/other/give_initial_stuff/mod.conf | 2 + mods/pvp/dropondie/init.lua | 2 +- mods/pvp/dropondie/mod.conf | 2 +- 19 files changed, 385 insertions(+), 212 deletions(-) create mode 100644 mods/ctf/ctf_classes/items.lua rename mods/{ctf/ctf_map/ctf_map_core/give_initial_stuff.lua => other/give_initial_stuff/init.lua} (54%) create mode 100644 mods/other/give_initial_stuff/mod.conf diff --git a/mods/ctf/ctf_bandages/init.lua b/mods/ctf/ctf_bandages/init.lua index 2a95754ab2..37f9a95d98 100644 --- a/mods/ctf/ctf_bandages/init.lua +++ b/mods/ctf/ctf_bandages/init.lua @@ -3,7 +3,7 @@ local healing_limit = 15 minetest.register_craftitem("ctf_bandages:bandage", { - description = "Bandage, heals teammates for 3-4 HP until HP is equal to "..healing_limit, + description = "Bandage\n\nHeals teammates for 3-4 HP until HP is equal to "..healing_limit, inventory_image = "ctf_bandages_bandage.png", on_use = function(itemstack, player, pointed_thing) if pointed_thing.type ~= "object" then diff --git a/mods/ctf/ctf_classes/api.lua b/mods/ctf/ctf_classes/api.lua index 88728e87c2..b1c40803a0 100644 --- a/mods/ctf/ctf_classes/api.lua +++ b/mods/ctf/ctf_classes/api.lua @@ -15,6 +15,11 @@ function ctf_classes.register(cname, def) def.properties.max_hp = def.properties.max_hp or 20 end +local registered_on_changed = {} +function ctf_classes.register_on_changed(func) + table.insert(registered_on_changed, func) +end + function ctf_classes.set_skin(player, color, class) player:set_properties({ textures = {"ctf_classes_skin_" .. class.name .. "_" .. (color or "blue") .. ".png"} @@ -30,20 +35,22 @@ function ctf_classes.get(player) return ctf_classes.__classes[cname] end -function ctf_classes.set(player, cname) - assert(type(cname) == "string") - local class = ctf_classes.__classes[cname] - assert(class) +function ctf_classes.set(player, new_name) + assert(type(new_name) == "string") + local new = ctf_classes.__classes[new_name] + assert(new) local meta = player:get_meta() - local old = meta:get("ctf_classes:class") - meta:set_string("ctf_classes:class", cname) + local old_name = meta:get("ctf_classes:class") + + meta:set_string("ctf_classes:class", new_name) ctf_classes.update(player) - if old ~= nil and old ~= cname then - local pname = player:get_player_name() - ctf.chat_send_team(ctf.player(pname).team, - minetest.colorize("#ABCDEF", pname .. " is now a " .. class.description)) + if old_name == nil or old_name ~= new_name then + local old = old_name and ctf_classes.__classes[old_name] + for i=1, #registered_on_changed do + registered_on_changed[i](player, old, new) + end end end @@ -68,13 +75,21 @@ local function set_max_hp(player, max_hp) end function ctf_classes.update(player) + local name = player:get_player_name() + local class = ctf_classes.get(player) - local color = ctf_colors.get_color(ctf.player(player:get_player_name())).text + local color = ctf_colors.get_color(ctf.player(name)).text set_max_hp(player, class.properties.max_hp) ctf_classes.set_skin(player, color, class) + + local speed = class.properties.speed + if ctf_flag.has_flag(name) and speed > 0.9 then + speed = 0.9 + end + physics.set(player:get_player_name(), "ctf_classes:speed", { - speed = class.properties.speed, + speed = speed, }) end diff --git a/mods/ctf/ctf_classes/gui.lua b/mods/ctf/ctf_classes/gui.lua index 6eb3bcf136..1fd5baed05 100644 --- a/mods/ctf/ctf_classes/gui.lua +++ b/mods/ctf/ctf_classes/gui.lua @@ -41,6 +41,24 @@ function ctf_classes.show_gui(name, player) fs[#fs + 1] = ",#fcc," .. minetest.formspec_escape(item) end fs[#fs + 1] = "]" + + for i, item in pairs(class.properties.items or {}) do + fs[#fs + 1] = "item_image[" + fs[#fs + 1] = tostring(i * 0.5 - 0.4) + fs[#fs + 1] = ",2.15;0.5,0.5;" + fs[#fs + 1] = minetest.formspec_escape(ItemStack(item):get_name()) + fs[#fs + 1] = "]" + + local desc = ItemStack(item):get_description():split("\n")[1] + + fs[#fs + 1] = "tooltip[" + fs[#fs + 1] = tostring(i * 0.5 - 0.4) + fs[#fs + 1] = ",2.15;0.5,0.5;" + fs[#fs + 1] = minetest.formspec_escape(desc) + fs[#fs + 1] = "]" + end + + fs[#fs + 1] = "button_exit[0.5,2.7;2,1;select_" fs[#fs + 1] = class.name fs[#fs + 1] = ";Select]" diff --git a/mods/ctf/ctf_classes/init.lua b/mods/ctf/ctf_classes/init.lua index fdab6f29be..705957b990 100644 --- a/mods/ctf/ctf_classes/init.lua +++ b/mods/ctf/ctf_classes/init.lua @@ -7,6 +7,7 @@ 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") +dofile(minetest.get_modpath("ctf_classes") .. "/items.lua") ctf_classes.register("knight", { description = "Knight", @@ -16,16 +17,23 @@ ctf_classes.register("knight", { properties = { max_hp = 30, speed = 0.90, + + items = { + "default:sword_steel", + }, }, }) ctf_classes.register("shooter", { - description = "Shooter", - pros = { "+10% ranged skill", "Rifles and grappling hooks" }, - cons = { "Can't capture the flag" }, + description = "Sharp Shooter", + pros = { "+10% ranged skill" }, + cons = {}, color = "#c60", properties = { - can_capture = false, + items = { + "shooter:rifle", + "shooter:grapple_gun_loaded", + } }, }) @@ -36,6 +44,10 @@ ctf_classes.register("medic", { color = "#0af", properties = { max_hp = 10, + + items = { + "ctf_bandages:bandage 20", + }, }, }) @@ -48,6 +60,14 @@ minetest.register_on_joinplayer(function(player) end end) +ctf_flag.register_on_pick_up(function(name) + ctf_classes.update(minetest.get_player_by_name(name)) +end) + +ctf_flag.register_on_drop(function(name) + ctf_classes.update(minetest.get_player_by_name(name)) +end) + minetest.register_chatcommand("class", { func = function(name, params) local player = minetest.get_player_by_name(name) @@ -114,3 +134,13 @@ for _, flagname in pairs(flags) do on_rightclick = show, }) end + +ctf_classes.register_on_changed(function(player, old, new) + if not old then + return + end + + local pname = player:get_player_name() + ctf.chat_send_team(ctf.player(pname).team, + minetest.colorize("#ABCDEF", pname .. " is now a " .. new.description)) +end) diff --git a/mods/ctf/ctf_classes/items.lua b/mods/ctf/ctf_classes/items.lua new file mode 100644 index 0000000000..e10ea05e58 --- /dev/null +++ b/mods/ctf/ctf_classes/items.lua @@ -0,0 +1,60 @@ +give_initial_stuff.register_stuff_provider(function(player) + local class = ctf_classes.get(player) + return class.properties.items or {} +end, 1) + +ctf_classes.register_on_changed(function(player, old, new) + local inv = player:get_inventory() + + if old then + local items = old.properties.items or {} + for i = 1, #items do + inv:remove_item("main", ItemStack(items[i])) + end + end + + do + assert(new) + + local items = new.properties.items or {} + for i = 1, #items do + inv:add_item("main", ItemStack(items[i])) + end + end +end) + +local function stack_list_to_map(stacks) + local map = {} + for i = 1, #stacks do + map[ItemStack(stacks[i]):get_name()] = true + end + return map +end + +local old_item_drop = minetest.item_drop +minetest.item_drop = function(itemstack, player, pos) + local class = ctf_classes.get(player) + + local items = stack_list_to_map(class.properties.items or {}) + if items[itemstack:get_name()] then + minetest.chat_send_player(player:get_player_name(), + "You're not allowed to drop class items!") + return itemstack + else + return old_item_drop(itemstack, player, pos) + end +end + +local old_is_allowed = ctf_map.is_item_allowed_in_team_chest +ctf_map.is_item_allowed_in_team_chest = function(listname, stack, player) + local class = ctf_classes.get(player) + + local items = stack_list_to_map(class.properties.items or {}) + if items[stack:get_name()] then + minetest.chat_send_player(player:get_player_name(), + "You're not allowed to put class items in the chest!") + return false + else + return old_is_allowed(listname, stack, player) + end +end diff --git a/mods/ctf/ctf_classes/mod.conf b/mods/ctf/ctf_classes/mod.conf index c0e72d51ec..1967fb0cb7 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, physics, shooter, hpregen +depends = ctf, ctf_flag, ctf_colors, ctf_map_core, physics, shooter, hpregen, give_initial_stuff description = Adds classes, including knight, shooter, and medic diff --git a/mods/ctf/ctf_classes/ranged.lua b/mods/ctf/ctf_classes/ranged.lua index 4f65452866..0f4edf461c 100644 --- a/mods/ctf/ctf_classes/ranged.lua +++ b/mods/ctf/ctf_classes/ranged.lua @@ -49,6 +49,13 @@ local function check_grapple(itemname) return itemstack end + if ctf_flag.has_flag(user:get_player_name()) then + minetest.chat_send_player(user:get_player_name(), + "You can't use grapples whilst carrying the flag") + + return itemstack + end + return old_func(itemstack, user, ...) end, }) diff --git a/mods/ctf/ctf_crafting/init.lua b/mods/ctf/ctf_crafting/init.lua index deef651c44..36fd84c3c3 100644 --- a/mods/ctf/ctf_crafting/init.lua +++ b/mods/ctf/ctf_crafting/init.lua @@ -1,28 +1,33 @@ local full_ores = { - {"diamond", "default:diamond"}, - {"mese", "default:mese_crystal"}, - {"bronze", "default:bronze_ingot"}, - {"steel", "default:steel_ingot"}, - {"stone", "default:cobble"}, + diamond = "default:diamond", + mese = "default:mese_crystal", + bronze = "default:bronze_ingot", + steel = "default:steel_ingot", + stone = "default:cobble", +} + +local upgrades = { + steel = "mese", + mese = "diamond", } -- Swords -for _, orex in pairs(full_ores) do +for from, to in pairs(upgrades) do crafting.register_recipe({ type = "inv", - output = "default:sword_" .. orex[1], - items = { "default:stick", orex[2] .. " 2" }, + output = "default:sword_" .. to, + items = { "default:sword_" .. from, full_ores[to] .. " 2" }, always_known = true, level = 1, }) end -- Pickaxes -for _, orex in pairs(full_ores) do +for ore, ore_item in pairs(full_ores) do crafting.register_recipe({ type = "inv", - output = "default:pick_" .. orex[1], - items = { "default:stick 2", orex[2] .. " 3" }, + output = "default:pick_" .. ore, + items = { "default:stick 2", ore_item .. " 3" }, always_known = true, level = 1, }) @@ -187,22 +192,22 @@ crafting.register_recipe({ }) -- Shovels -for _, orex in pairs(full_ores) do +for ore, ore_item in pairs(full_ores) do crafting.register_recipe({ type = "inv", - output = "default:shovel_" .. orex[1], - items = { "default:stick 2", orex[2] }, + output = "default:shovel_" .. ore, + items = { "default:stick 2", ore_item }, always_known = true, level = 1, }) end -- Axes -for _, orex in pairs(full_ores) do +for ore, ore_item in pairs(full_ores) do crafting.register_recipe({ type = "inv", - output = "default:axe_" .. orex[1], - items = { "default:stick 2", orex[2] .. " 3" }, + output = "default:axe_" .. ore, + items = { "default:stick 2", ore_item .. " 3" }, always_known = true, level = 1, }) diff --git a/mods/ctf/ctf_flag/api.lua b/mods/ctf/ctf_flag/api.lua index 1420ecbe74..4fdeba2e68 100644 --- a/mods/ctf/ctf_flag/api.lua +++ b/mods/ctf/ctf_flag/api.lua @@ -50,13 +50,14 @@ function ctf_flag.collect_claimed() return claimed end -function ctf_flag.get_claimed_by_player(name) +function ctf_flag.has_flag(name) local claimed = ctf_flag.collect_claimed() for _, flag in pairs(claimed) do if flag.claimed.player == name then - return name + return true end end + return false end function ctf_flag.player_drop_flag(name) diff --git a/mods/ctf/ctf_map/ctf_map_core/chest.lua b/mods/ctf/ctf_map/ctf_map_core/chest.lua index 70c9df2c5f..b0e86d45e9 100644 --- a/mods/ctf/ctf_map/ctf_map_core/chest.lua +++ b/mods/ctf/ctf_map/ctf_map_core/chest.lua @@ -6,9 +6,24 @@ local blacklist = { "default:aspen_leaves" } + +function ctf_map.is_item_allowed_in_team_chest(listname, stack, player) + if listname == "helper" then + return false + end + + for _, itemstring in ipairs(blacklist) do + if stack:get_name() == itemstring then + return false + end + end + + return true +end + local colors = {"red", "blue"} for _, chest_color in pairs(colors) do - minetest.register_node("ctf_map_core:chest_" .. chest_color, { + local def = { description = "Chest", tiles = { "default_chest_top_" .. chest_color .. ".png", @@ -22,185 +37,188 @@ for _, chest_color in pairs(colors) do legacy_facedir_simple = true, is_ground_content = false, sounds = default.node_sound_wood_defaults(), - on_construct = function(pos) - local meta = minetest.get_meta(pos) - meta:set_string("infotext", "Chest") - local inv = meta:get_inventory() - inv:set_size("main", 4 * 7) - inv:set_size("pro", 4 * 7) - inv:set_size("helper", 1 * 1) - end, - on_rightclick = function(pos, node, player) - local name = player:get_player_name() - if chest_color ~= ctf.player(name).team then - minetest.chat_send_player(name, "You're not on team " .. chest_color) - return - end - - local territory_owner = ctf.get_territory_owner(pos) - if chest_color ~= territory_owner then - if not territory_owner then - ctf.warning("ctf_map", "Unowned team chest") - minetest.set_node(pos, { name = "air" }) - return - end - ctf.warning("ctf_map", "Wrong chest, changing to " .. - territory_owner .. " from " .. chest_color) - minetest.set_node(pos, "ctf_map_core:chest_" .. territory_owner) - end + } + + function def.on_construct(pos) + local meta = minetest.get_meta(pos) + meta:set_string("infotext", "Chest") + local inv = meta:get_inventory() + inv:set_size("main", 4 * 7) + inv:set_size("pro", 4 * 7) + inv:set_size("helper", 1 * 1) + end + + function def.can_dig(pos, player) + return false + end + + function def.on_rightclick(pos, node, player) + local name = player:get_player_name() + if chest_color ~= ctf.player(name).team then + minetest.chat_send_player(name, "You're not on team " .. chest_color) + return + end - local formspec = table.concat({ - "size[8,12]", - default.gui_bg, - default.gui_bg_img, - default.gui_slots, - default.get_hotbar_bg(0,7.85), - "list[current_player;main;0,7.85;8,1;]", - "list[current_player;main;0,9.08;8,3;8]", - }, "") - - if ctf_stats.player(name).score < 10 then - local msg = "You need at least 10 score to access the team chest.\n" .. - "Try killing an enemy player, or at least try to capture the flag.\n" .. - "Find resources in chests scattered around the map." - formspec = formspec .. "label[0.75,3;" .. minetest.formspec_escape(msg) .. "]" - minetest.show_formspec(name, "ctf_map_core:no_access", formspec) + local territory_owner = ctf.get_territory_owner(pos) + if chest_color ~= territory_owner then + if not territory_owner then + ctf.warning("ctf_map", "Unowned team chest") + minetest.set_node(pos, { name = "air" }) return end + ctf.warning("ctf_map", "Wrong chest, changing to " .. + territory_owner .. " from " .. chest_color) + minetest.set_node(pos, "ctf_map_core:chest_" .. territory_owner) + end - local is_pro = ctf_stats.is_pro(name) - local chestinv = "nodemeta:" .. pos.x .. "," .. pos.y .. "," .. pos.z - - formspec = formspec .. "list[" .. chestinv .. ";main;0,0.3;4,7;]" .. - "background[4,-0.2;4.15,7.7;ctf_map_pro_section.png;false]" + local formspec = table.concat({ + "size[8,12]", + default.gui_bg, + default.gui_bg_img, + default.gui_slots, + default.get_hotbar_bg(0,7.85), + "list[current_player;main;0,7.85;8,1;]", + "list[current_player;main;0,9.08;8,3;8]", + }, "") + + if ctf_stats.player(name).score < 10 then + local msg = "You need at least 10 score to access the team chest.\n" .. + "Try killing an enemy player, or at least try to capture the flag.\n" .. + "Find resources in chests scattered around the map." + formspec = formspec .. "label[0.75,3;" .. minetest.formspec_escape(msg) .. "]" + minetest.show_formspec(name, "ctf_map_core:no_access", formspec) + return + end - if is_pro then - formspec = formspec .. "list[" .. chestinv .. ";pro;4,0.3;4,7;]" .. - "listring[" .. chestinv ..";pro]" .. - "listring[" .. chestinv .. ";helper]" .. - "label[5,-0.2;" .. - minetest.formspec_escape("Pro players only") .. "]" - else - formspec = formspec .. "label[4.75,3;" .. - minetest.formspec_escape("You need at least 10000" .. - "\nscore and 1.5+ KD to\naccess the pro section") .. "]" - end + local is_pro = ctf_stats.is_pro(name) + local chestinv = "nodemeta:" .. pos.x .. "," .. pos.y .. "," .. pos.z + + formspec = formspec .. "list[" .. chestinv .. ";main;0,0.3;4,7;]" .. + "background[4,-0.2;4.15,7.7;ctf_map_pro_section.png;false]" + + if is_pro then + formspec = formspec .. "list[" .. chestinv .. ";pro;4,0.3;4,7;]" .. + "listring[" .. chestinv ..";pro]" .. + "listring[" .. chestinv .. ";helper]" .. + "label[5,-0.2;" .. + minetest.formspec_escape("Pro players only") .. "]" + else + formspec = formspec .. "label[4.75,3;" .. + minetest.formspec_escape("You need at least 10000" .. + "\nscore and 1.5+ KD to\naccess the pro section") .. "]" + end - formspec = formspec .. - "listring[" .. chestinv ..";main]" .. - "listring[current_player;main]" + formspec = formspec .. + "listring[" .. chestinv ..";main]" .. + "listring[current_player;main]" - minetest.show_formspec(name, "ctf_map_core:chest", formspec) - end, + minetest.show_formspec(name, "ctf_map_core:chest", formspec) + end - allow_metadata_inventory_move = function(pos, from_list, from_index, - to_list, to_index, count, player) - local name = player:get_player_name() - if chest_color ~= ctf.player(name).team then - minetest.chat_send_player(name, "You're not on team " .. chest_color) - return 0 - end + function def.allow_metadata_inventory_move(pos, from_list, from_index, + to_list, to_index, count, player) + local name = player:get_player_name() + if chest_color ~= ctf.player(name).team then + minetest.chat_send_player(name, "You're not on team " .. chest_color) + return 0 + end - if ctf_stats.player(name).score < 10 then - return 0 - end + if ctf_stats.player(name).score < 10 then + return 0 + end - if (from_list ~= "pro" and to_list ~= "pro") or ctf_stats.is_pro(name) then - if to_list == "helper" then - -- handle move & overflow - local chestinv = minetest.get_inventory({type = "node", pos = pos}) - local playerinv = player:get_inventory() - local stack = chestinv:get_stack(from_list, from_index) - local leftover = playerinv:add_item("main", stack) - local n_stack = stack - n_stack:set_count(stack:get_count() - leftover:get_count()) - chestinv:remove_item("helper", stack) - chestinv:remove_item("pro", n_stack) - return 0 - elseif from_list == "helper" then - return 0 - else - return count - end - else + if (from_list ~= "pro" and to_list ~= "pro") or ctf_stats.is_pro(name) then + if to_list == "helper" then + -- handle move & overflow + local chestinv = minetest.get_inventory({type = "node", pos = pos}) + local playerinv = player:get_inventory() + local stack = chestinv:get_stack(from_list, from_index) + local leftover = playerinv:add_item("main", stack) + local n_stack = stack + n_stack:set_count(stack:get_count() - leftover:get_count()) + chestinv:remove_item("helper", stack) + chestinv:remove_item("pro", n_stack) return 0 - end - end, - allow_metadata_inventory_put = function(pos, listname, index, stack, player) - if listname == "helper" then + elseif from_list == "helper" then return 0 + else + return count end + else + return 0 + end + end - local name = player:get_player_name() - if chest_color ~= ctf.player(name).team then - minetest.chat_send_player(name, "You're not on team " .. chest_color) - return 0 - end + function def.allow_metadata_inventory_put(pos, listname, index, stack, player) + local name = player:get_player_name() + if chest_color ~= ctf.player(name).team then + minetest.chat_send_player(name, "You're not on team " .. chest_color) + return 0 + end - for _, itemstring in ipairs(blacklist) do - if stack:get_name() == itemstring then - return 0 - end - end + local pstat = ctf_stats.player(name) + if not pstat or not pstat.score or pstat.score < 10 then + return 0 + end - local pstat = ctf_stats.player(name) - if not pstat or not pstat.score or pstat.score < 10 then - return 0 - end + if not ctf_map.is_item_allowed_in_team_chest(listname, stack, player) then + return 0 + end - if listname ~= "pro" or ctf_stats.is_pro(name) then - local chestinv = minetest.get_inventory({type = "node", pos = pos}) - if chestinv:room_for_item("pro", stack) then - return stack:get_count() - else - -- handle overflow - local playerinv = player:get_inventory() - local leftovers = chestinv:add_item("pro", stack) - local leftover = chestinv:add_item("main", leftovers) - local n_stack = stack - n_stack:set_count(stack:get_count() - leftover:get_count()) - playerinv:remove_item("main", n_stack) - return 0 - end + if listname ~= "pro" or ctf_stats.is_pro(name) then + local chestinv = minetest.get_inventory({type = "node", pos = pos}) + if chestinv:room_for_item("pro", stack) then + return stack:get_count() else + -- handle overflow + local playerinv = player:get_inventory() + local leftovers = chestinv:add_item("pro", stack) + local leftover = chestinv:add_item("main", leftovers) + local n_stack = stack + n_stack:set_count(stack:get_count() - leftover:get_count()) + playerinv:remove_item("main", n_stack) return 0 end - end, - allow_metadata_inventory_take = function(pos, listname, index, stack, player) - if listname == "helper" then - return 0 - end + else + return 0 + end + end - local name = player:get_player_name() - if chest_color ~= ctf.player(name).team then - minetest.chat_send_player(name, "You're not on team " .. chest_color) - return 0 - end + function def.allow_metadata_inventory_take(pos, listname, index, stack, player) + if listname == "helper" then + return 0 + end - if ctf_stats.player(name).score < 10 then - return 0 - end + local name = player:get_player_name() + if chest_color ~= ctf.player(name).team then + minetest.chat_send_player(name, "You're not on team " .. chest_color) + return 0 + end - if listname ~= "pro" or ctf_stats.is_pro(name) then - return stack:get_count() - else - return 0 - end - end, - can_dig = function(pos, player) - return false - end, - on_metadata_inventory_put = function(pos, listname, index, stack, player) - minetest.log("action", player:get_player_name() .. - " moves " .. (stack:get_name() or "stuff") .. " " .. - (stack:get_count() or 0) .. " to chest at " .. - minetest.pos_to_string(pos)) - end, - on_metadata_inventory_take = function(pos, listname, index, stack, player) - minetest.log("action", player:get_player_name() .. - " takes " .. (stack:get_name() or "stuff") .. " " .. - (stack:get_count() or 0) .. " from chest at " .. - minetest.pos_to_string(pos)) - end - }) + if ctf_stats.player(name).score < 10 then + return 0 + end + + if listname ~= "pro" or ctf_stats.is_pro(name) then + return stack:get_count() + else + return 0 + end + end + + function def.on_metadata_inventory_put(pos, listname, index, stack, player) + minetest.log("action", player:get_player_name() .. + " moves " .. (stack:get_name() or "stuff") .. " " .. + (stack:get_count() or 0) .. " to chest at " .. + minetest.pos_to_string(pos)) + end + + function def.on_metadata_inventory_take(pos, listname, index, stack, player) + minetest.log("action", player:get_player_name() .. + " takes " .. (stack:get_name() or "stuff") .. " " .. + (stack:get_count() or 0) .. " from chest at " .. + minetest.pos_to_string(pos)) + end + + minetest.register_node("ctf_map_core:chest_" .. chest_color, def) end diff --git a/mods/ctf/ctf_map/ctf_map_core/init.lua b/mods/ctf/ctf_map/ctf_map_core/init.lua index ccb3734baf..ca88a73fb5 100644 --- a/mods/ctf/ctf_map/ctf_map_core/init.lua +++ b/mods/ctf/ctf_map/ctf_map_core/init.lua @@ -34,10 +34,17 @@ dofile(modpath .. "/barrier.lua") if minetest.get_modpath("ctf") then dofile(modpath .. "/base.lua") dofile(modpath .. "/chest.lua") - dofile(modpath .. "/give_initial_stuff.lua") dofile(modpath .. "/meta_helpers.lua") dofile(modpath .. "/schem_map.lua") dofile(modpath .. "/maps_catalog.lua") ctf_match.register_on_build_time_end(ctf_map.remove_middle_barrier) + + give_initial_stuff.register_stuff_provider(function(player) + return ctf_map.map and ctf_map.map.initial_stuff or { + "default:pick_stone", + "default:sword_stone", + "default:torch 3", + } + end) end diff --git a/mods/ctf/ctf_map/ctf_map_core/meta_helpers.lua b/mods/ctf/ctf_map/ctf_map_core/meta_helpers.lua index 186609a651..cbd5106b05 100644 --- a/mods/ctf/ctf_map/ctf_map_core/meta_helpers.lua +++ b/mods/ctf/ctf_map/ctf_map_core/meta_helpers.lua @@ -98,7 +98,7 @@ function ctf_map.register_treasures(map) end else -- If treasure is a part of map's initial stuff, don't register it - local blacklist = ctf_map.map.initial_stuff or give_initial_stuff.get_stuff() + local blacklist = ctf_map.map.initial_stuff or {} for _, def in pairs(ctf_treasure.get_default_treasures()) do local is_valid = true for _, b_item in pairs(blacklist) do diff --git a/mods/ctf/ctf_map/ctf_map_core/mod.conf b/mods/ctf/ctf_map/ctf_map_core/mod.conf index 3f6139ba00..f6f0c72e62 100644 --- a/mods/ctf/ctf_map/ctf_map_core/mod.conf +++ b/mods/ctf/ctf_map/ctf_map_core/mod.conf @@ -1,3 +1,3 @@ name = ctf_map_core depends = default -optional_depends = ctf, ctf_match, ctf_stats, ctf_treasure, stairs, wool, irc, physics +optional_depends = ctf, ctf_match, ctf_stats, ctf_treasure, stairs, wool, irc, physics, give_initial_stuff diff --git a/mods/ctf/ctf_treasure/init.lua b/mods/ctf/ctf_treasure/init.lua index dbbe0ade72..0a4542b423 100644 --- a/mods/ctf/ctf_treasure/init.lua +++ b/mods/ctf/ctf_treasure/init.lua @@ -10,7 +10,6 @@ function ctf_treasure.get_default_treasures() { "ctf_traps:damage_cobble", 0.3, 4, { 10, 20 } }, { "default:pick_steel", 0.5, 5, { 1, 10 } }, - { "default:sword_steel", 0.4, 5, { 1, 4 } }, { "default:shovel_stone", 0.6, 5, { 1, 10 } }, { "default:shovel_steel", 0.3, 5, { 1, 10 } }, { "default:axe_steel", 0.4, 5, { 1, 10 } }, @@ -21,11 +20,10 @@ function ctf_treasure.get_default_treasures() { "shooter:machine_gun", 0.02, 2, 1 }, { "shooter:crossbow", 0.5, 2, { 1, 5 } }, { "shooter:pistol", 0.4, 2, { 1, 5 } }, - { "shooter:rifle", 0.1, 2, { 1, 2 } }, + { "shooter:ammo", 0.3, 2, { 1, 10 } }, { "shooter:arrow_white", 0.5, 2, { 2, 18 } }, { "medkits:medkit", 0.8, 5, 2 }, - { "ctf_bandages:bandage", 0.8, 2, { 2, 4 } } } end diff --git a/mods/other/crafting b/mods/other/crafting index 89f41763da..c6cd6ad62d 160000 --- a/mods/other/crafting +++ b/mods/other/crafting @@ -1 +1 @@ -Subproject commit 89f41763da5a6aa3048d90694c39bdd2d5ba1ba7 +Subproject commit c6cd6ad62d9f4076a22d985defc8a966a17f569d diff --git a/mods/ctf/ctf_map/ctf_map_core/give_initial_stuff.lua b/mods/other/give_initial_stuff/init.lua similarity index 54% rename from mods/ctf/ctf_map/ctf_map_core/give_initial_stuff.lua rename to mods/other/give_initial_stuff/init.lua index 4878616a95..6ba9cd5591 100644 --- a/mods/ctf/ctf_map/ctf_map_core/give_initial_stuff.lua +++ b/mods/other/give_initial_stuff/init.lua @@ -12,7 +12,7 @@ setmetatable(give_initial_stuff, { inv:set_size("craftresult", 0) inv:set_size("hand", 0) - local items = give_initial_stuff.get_stuff() + local items = give_initial_stuff.get_stuff(player) for _, item in pairs(items) do inv:add_item("main", item) @@ -20,12 +20,24 @@ setmetatable(give_initial_stuff, { end }) -function give_initial_stuff.get_stuff() - return ctf_map.map and ctf_map.map.initial_stuff or { - "default:pick_stone", - "default:sword_stone", - "default:torch 3", - } +local registered_stuff_providers = {} +function give_initial_stuff.register_stuff_provider(func, priority) + table.insert(registered_stuff_providers, + priority or (#registered_stuff_providers + 1), + func) +end + +function give_initial_stuff.get_stuff(player) + local stuff = {} + for i=1, #registered_stuff_providers do + local new_stuff = registered_stuff_providers[i](player) + assert(new_stuff) + + for j=1, #new_stuff do + stuff[#stuff + 1] = new_stuff[j] + end + end + return stuff end minetest.register_on_joinplayer(function(player) diff --git a/mods/other/give_initial_stuff/mod.conf b/mods/other/give_initial_stuff/mod.conf new file mode 100644 index 0000000000..3fae27e782 --- /dev/null +++ b/mods/other/give_initial_stuff/mod.conf @@ -0,0 +1,2 @@ +name = give_initial_stuff +description = API to give give_initial_stuff diff --git a/mods/pvp/dropondie/init.lua b/mods/pvp/dropondie/init.lua index 202121067b..5da568c517 100644 --- a/mods/pvp/dropondie/init.lua +++ b/mods/pvp/dropondie/init.lua @@ -36,7 +36,7 @@ local function drop_all(player) pos.y = math.floor(pos.y + 0.5) local inv = player:get_inventory() - for _, item in pairs(give_initial_stuff.get_stuff()) do + for _, item in pairs(give_initial_stuff.get_stuff(player)) do inv:remove_item("main", ItemStack(item)) end drop_list(pos, inv, "main") diff --git a/mods/pvp/dropondie/mod.conf b/mods/pvp/dropondie/mod.conf index 09918c0081..4c1f8b533f 100644 --- a/mods/pvp/dropondie/mod.conf +++ b/mods/pvp/dropondie/mod.conf @@ -1,3 +1,3 @@ name = dropondie -depends = ctf_map_core +depends = give_initial_stuff description = With this mod, players will drop all their items in their inventory on the ground when they die. From 11a0b5d719796334b467fa0e810e636c2e5e2c35 Mon Sep 17 00:00:00 2001 From: rubenwardy Date: Fri, 13 Mar 2020 23:26:53 +0000 Subject: [PATCH 07/15] Improve class shooter modifications --- mods/ctf/ctf_classes/api.lua | 2 +- mods/ctf/ctf_classes/gui.lua | 2 +- mods/ctf/ctf_classes/init.lua | 31 ++++++++++++++++-- mods/ctf/ctf_classes/ranged.lua | 51 ++++++++++++++--------------- mods/other/random_messages/init.lua | 2 +- mods/pvp/shooter/grapple.lua | 4 +-- 6 files changed, 57 insertions(+), 35 deletions(-) diff --git a/mods/ctf/ctf_classes/api.lua b/mods/ctf/ctf_classes/api.lua index b1c40803a0..be38667dd3 100644 --- a/mods/ctf/ctf_classes/api.lua +++ b/mods/ctf/ctf_classes/api.lua @@ -31,7 +31,7 @@ function ctf_classes.get(player) player = minetest.get_player_by_name(player) end - local cname = player:get_meta():get("ctf_classes:class") or "knight" + local cname = player:get_meta():get("ctf_classes:class") or ctf_classes.default_class return ctf_classes.__classes[cname] end diff --git a/mods/ctf/ctf_classes/gui.lua b/mods/ctf/ctf_classes/gui.lua index 1fd5baed05..2cf066f177 100644 --- a/mods/ctf/ctf_classes/gui.lua +++ b/mods/ctf/ctf_classes/gui.lua @@ -2,7 +2,7 @@ function ctf_classes.show_gui(name, player) player = player or minetest.get_player_by_name(name) assert(player.get_player_name) if not ctf_classes.can_change(player) then - minetest.chat_send_player(name, "Move closer to the flag to change classes!") + minetest.chat_send_player(name, "Move closer to your flag to change classes!") return end diff --git a/mods/ctf/ctf_classes/init.lua b/mods/ctf/ctf_classes/init.lua index 705957b990..f7a90a5bd8 100644 --- a/mods/ctf/ctf_classes/init.lua +++ b/mods/ctf/ctf_classes/init.lua @@ -1,6 +1,8 @@ ctf_classes = { __classes = {}, __classes_ordered = {}, + + default_class = "knight", } dofile(minetest.get_modpath("ctf_classes") .. "/api.lua") @@ -9,6 +11,7 @@ dofile(minetest.get_modpath("ctf_classes") .. "/regen.lua") dofile(minetest.get_modpath("ctf_classes") .. "/ranged.lua") dofile(minetest.get_modpath("ctf_classes") .. "/items.lua") + ctf_classes.register("knight", { description = "Knight", pros = { "+50% Health Points" }, @@ -18,6 +21,12 @@ ctf_classes.register("knight", { max_hp = 30, speed = 0.90, + allowed_guns = { + "shooter:pistol", + "shooter:smg", + "shooter:shotgun", + }, + items = { "default:sword_steel", }, @@ -33,7 +42,19 @@ ctf_classes.register("shooter", { items = { "shooter:rifle", "shooter:grapple_gun_loaded", - } + }, + + allowed_guns = { + "shooter:pistol", + "shooter:rifle", + "shooter:smg", + "shooter:shotgun", + }, + + shooter_multipliers = { + range = 1.5, + full_punch_interval = 0.8, + }, }, }) @@ -48,6 +69,12 @@ ctf_classes.register("medic", { items = { "ctf_bandages:bandage 20", }, + + allowed_guns = { + "shooter:pistol", + "shooter:smg", + "shooter:shotgun", + }, }, }) @@ -76,7 +103,7 @@ minetest.register_chatcommand("class", { end if not ctf_classes.can_change(player) then - return false, "Move closer to the flag to change classes!" + return false, "Move closer to your flag to change classes!" end local cname = params:trim() diff --git a/mods/ctf/ctf_classes/ranged.lua b/mods/ctf/ctf_classes/ranged.lua index 0f4edf461c..4d8702fc76 100644 --- a/mods/ctf/ctf_classes/ranged.lua +++ b/mods/ctf/ctf_classes/ranged.lua @@ -1,50 +1,51 @@ -local shooter_specs = {} +local specs_cache = {} - -shooter.get_weapon_spec = function(_, user, name) - local spec = shooter.registered_weapons[name] +local function get_shooter_specs(weapon_name, multiplier) + local spec = shooter.registered_weapons[weapon_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 + -- this will convert the multipler to a table pointer + local idx = ("%s:%s"):format(multiplier or "nil", weapon_name) - if shooter_specs[name] then - return shooter_specs[name] + if specs_cache[idx] then + return specs_cache[idx] end spec = table.copy(spec) - shooter_specs[name] = spec + specs_cache[idx] = spec spec.range = spec.range * 1.5 spec.tool_caps.full_punch_interval = spec.tool_caps.full_punch_interval * 0.8 return spec end +shooter.get_weapon_spec = function(_, user, weapon_name) + local class = ctf_classes.get(user) + + if table.indexof(class.properties.allowed_guns or {}, weapon_name) == -1 then + minetest.chat_send_player(user:get_player_name(), + "Your class can't use that weapon! Change your class at spawn") + return nil + end + + local spec = get_shooter_specs(weapon_name, class.properties.shooter_multipliers) + spec.name = user and user:get_player_name() + + 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 .. "\n\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") + "Your class can't use that weapon! Change your class at spawn") return itemstack end @@ -63,7 +64,3 @@ end check_grapple("shooter:grapple_gun_loaded") check_grapple("shooter:grapple_gun") - -minetest.override_item("shooter:rifle", { - description = "Rifle\n\nCan only be used by Shooters", -}) diff --git a/mods/other/random_messages/init.lua b/mods/other/random_messages/init.lua index 83345a6b3b..6d0f049577 100644 --- a/mods/other/random_messages/init.lua +++ b/mods/other/random_messages/init.lua @@ -75,7 +75,7 @@ function random_messages.read_messages() "Use /summary to check scores of the current match and the previous match.", "Use /maps to view the maps catalog. It also contains license info and attribution details.", "Change your class in your base by right clicking the home flag or typing /class.", - "Medics cause nearby troops to regenerate health faster.", + "Medics cause troops within 10 metres to regenerate health faster.", } end diff --git a/mods/pvp/shooter/grapple.lua b/mods/pvp/shooter/grapple.lua index 4e902fadeb..2bf62f8fa0 100644 --- a/mods/pvp/shooter/grapple.lua +++ b/mods/pvp/shooter/grapple.lua @@ -89,9 +89,7 @@ minetest.register_tool("shooter:grapple_gun", { end local inv = user:get_inventory() - if inv:contains_item("main", "shooter:grapple_hook") and - true then --inv:contains_item("main", "tnt:gunpowder") then - -- inv:remove_item("main", "tnt:gunpowder") + if inv:contains_item("main", "shooter:grapple_hook") then minetest.sound_play("shooter_reload", {object=user}) local stack = inv:remove_item("main", "shooter:grapple_hook") itemstack = ItemStack("shooter:grapple_gun_loaded 1 "..stack:get_wear()) From 8790f354d17ebe03c92e9bf76d9de3adf0f26b5c Mon Sep 17 00:00:00 2001 From: rubenwardy Date: Fri, 13 Mar 2020 23:53:30 +0000 Subject: [PATCH 08/15] Tweak stats --- mods/ctf/ctf_classes/gui.lua | 10 +++++----- mods/ctf/ctf_classes/init.lua | 14 ++++++-------- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/mods/ctf/ctf_classes/gui.lua b/mods/ctf/ctf_classes/gui.lua index 2cf066f177..9d2aef228f 100644 --- a/mods/ctf/ctf_classes/gui.lua +++ b/mods/ctf/ctf_classes/gui.lua @@ -2,12 +2,12 @@ function ctf_classes.show_gui(name, player) player = player or minetest.get_player_by_name(name) assert(player.get_player_name) if not ctf_classes.can_change(player) then - minetest.chat_send_player(name, "Move closer to your flag to change classes!") + minetest.chat_send_player(name, "Move closer to the flag to change classes!") return end local fs = { - "size[9,3.2]" + "size[9,3.4]" } @@ -45,7 +45,7 @@ function ctf_classes.show_gui(name, player) for i, item in pairs(class.properties.items or {}) do fs[#fs + 1] = "item_image[" fs[#fs + 1] = tostring(i * 0.5 - 0.4) - fs[#fs + 1] = ",2.15;0.5,0.5;" + fs[#fs + 1] = ",2.25;0.5,0.5;" fs[#fs + 1] = minetest.formspec_escape(ItemStack(item):get_name()) fs[#fs + 1] = "]" @@ -53,13 +53,13 @@ function ctf_classes.show_gui(name, player) fs[#fs + 1] = "tooltip[" fs[#fs + 1] = tostring(i * 0.5 - 0.4) - fs[#fs + 1] = ",2.15;0.5,0.5;" + fs[#fs + 1] = ",2.25;0.5,0.5;" fs[#fs + 1] = minetest.formspec_escape(desc) fs[#fs + 1] = "]" end - fs[#fs + 1] = "button_exit[0.5,2.7;2,1;select_" + fs[#fs + 1] = "button_exit[0.5,2.9;2,1;select_" fs[#fs + 1] = class.name fs[#fs + 1] = ";Select]" fs[#fs + 1] = "container_end[]" diff --git a/mods/ctf/ctf_classes/init.lua b/mods/ctf/ctf_classes/init.lua index f7a90a5bd8..e6d2734431 100644 --- a/mods/ctf/ctf_classes/init.lua +++ b/mods/ctf/ctf_classes/init.lua @@ -21,21 +21,21 @@ ctf_classes.register("knight", { max_hp = 30, speed = 0.90, + items = { + "default:sword_steel", + }, + allowed_guns = { "shooter:pistol", "shooter:smg", "shooter:shotgun", }, - - items = { - "default:sword_steel", - }, }, }) ctf_classes.register("shooter", { description = "Sharp Shooter", - pros = { "+10% ranged skill" }, + pros = { "+50% range", "+20% faster shooting" }, cons = {}, color = "#c60", properties = { @@ -61,11 +61,9 @@ ctf_classes.register("shooter", { ctf_classes.register("medic", { description = "Medic", pros = { "x2 regen for nearby friendlies" }, - cons = { "-50% Health Points" }, + cons = {}, color = "#0af", properties = { - max_hp = 10, - items = { "ctf_bandages:bandage 20", }, From 3b64a423738166da1141abaef06afba02b0a18e6 Mon Sep 17 00:00:00 2001 From: rubenwardy Date: Sat, 14 Mar 2020 17:22:55 +0000 Subject: [PATCH 09/15] Add rocketeer class --- mods/ctf/ctf_classes/gui.lua | 4 ++-- mods/ctf/ctf_classes/init.lua | 20 ++++++++++++++++++ mods/ctf/ctf_classes/ranged.lua | 6 ++++-- .../textures/ctf_classes_rocketeer.png | Bin 0 -> 679 bytes mods/other/give_initial_stuff/init.lua | 8 ++++++- 5 files changed, 33 insertions(+), 5 deletions(-) create mode 100644 mods/ctf/ctf_classes/textures/ctf_classes_rocketeer.png diff --git a/mods/ctf/ctf_classes/gui.lua b/mods/ctf/ctf_classes/gui.lua index 9d2aef228f..e87e449944 100644 --- a/mods/ctf/ctf_classes/gui.lua +++ b/mods/ctf/ctf_classes/gui.lua @@ -2,12 +2,12 @@ function ctf_classes.show_gui(name, player) player = player or minetest.get_player_by_name(name) assert(player.get_player_name) if not ctf_classes.can_change(player) then - minetest.chat_send_player(name, "Move closer to the flag to change classes!") + minetest.chat_send_player(name, "Move closer to your flag to change classes!") return end local fs = { - "size[9,3.4]" + "size[", #ctf_classes.__classes_ordered * 3 , ",3.4]" } diff --git a/mods/ctf/ctf_classes/init.lua b/mods/ctf/ctf_classes/init.lua index e6d2734431..8eb17c195f 100644 --- a/mods/ctf/ctf_classes/init.lua +++ b/mods/ctf/ctf_classes/init.lua @@ -76,6 +76,26 @@ ctf_classes.register("medic", { }, }) +ctf_classes.register("rocketeer", { + description = "Rocketeer", + pros = { "Can craft rockets" }, + cons = {}, + color = "#fa0", + properties = { + items = { + "shooter:rocket_gun_loaded", + "shooter:rocket 4", + }, + + allowed_guns = { + "shooter:pistol", + "shooter:smg", + "shooter:shotgun", + }, + }, +}) + + minetest.register_on_joinplayer(function(player) ctf_classes.update(player) diff --git a/mods/ctf/ctf_classes/ranged.lua b/mods/ctf/ctf_classes/ranged.lua index 4d8702fc76..8f4dd9a2b1 100644 --- a/mods/ctf/ctf_classes/ranged.lua +++ b/mods/ctf/ctf_classes/ranged.lua @@ -17,8 +17,10 @@ local function get_shooter_specs(weapon_name, multiplier) spec = table.copy(spec) specs_cache[idx] = spec - spec.range = spec.range * 1.5 - spec.tool_caps.full_punch_interval = spec.tool_caps.full_punch_interval * 0.8 + for key, value in pairs(multiplier) do + spec[key] = spec[key] * value + end + return spec end diff --git a/mods/ctf/ctf_classes/textures/ctf_classes_rocketeer.png b/mods/ctf/ctf_classes/textures/ctf_classes_rocketeer.png new file mode 100644 index 0000000000000000000000000000000000000000..3b2dc4d1cc0e433a2c15bc2a09ea3b165f257324 GIT binary patch literal 679 zcmV;Y0$BZtP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2i^x1 z4jMIOyV%tL00JjTL_t(I%bk-yXcJ)=#(!U^shASb1KUeW@gJ5$keXD`f>4UYC|nu{ z3PC7zIXYx)JQ|6Lj!TBgd@WV%{9DlAHVj51Uj2q zt%jy)7>*-yxg4fxQYw{XC!{C9Fbq7;L(?=`qK>7i(zb1UNNues-E5YP(GU-k@sm05 z>-%<<^)KI~ZQJO&&K<`QFP}e^Q{xJ?wW7S6oIA|OQf~{FMy~>(>pC+xPYHnQ+bywN zahbYtj@nvLw%ctonGC9`9tWw@hN36{ykC6H?U^{A-!3sesZ&|C<=p)dUMw~ND3wYg zolYMEIw1f%Etdf$z{ZD90E|!StgNiag@py`^*WYiowQ(C7CSAMoz_8UeDTCsm~c1@ zKr|X Date: Sat, 14 Mar 2020 17:50:24 +0000 Subject: [PATCH 10/15] Fix variants of class items being allowed to drop --- mods/ctf/ctf_classes/api.lua | 16 +++++++++++++ mods/ctf/ctf_classes/gui.lua | 2 +- mods/ctf/ctf_classes/init.lua | 17 +++++++++---- mods/ctf/ctf_classes/items.lua | 44 +++++++++++++++++++--------------- mods/ctf/ctf_classes/mod.conf | 2 +- mods/ctf/ctf_stats/chat.lua | 19 +++++++++++++++ mods/pvp/dropondie/init.lua | 31 +++++++++++++++++------- 7 files changed, 97 insertions(+), 34 deletions(-) diff --git a/mods/ctf/ctf_classes/api.lua b/mods/ctf/ctf_classes/api.lua index be38667dd3..6c9815db0f 100644 --- a/mods/ctf/ctf_classes/api.lua +++ b/mods/ctf/ctf_classes/api.lua @@ -11,6 +11,22 @@ function ctf_classes.register(cname, def) if def.properties.can_capture == nil then def.properties.can_capture = true end + + def.properties.initial_stuff = def.properties.initial_stuff or {} + + if not def.properties.item_blacklist then + def.properties.item_blacklist = {} + for i=1, #def.properties.initial_stuff do + table.insert(def.properties.item_blacklist, def.properties.initial_stuff[i]) + end + end + + if def.properties.additional_item_blacklist then + for i=1, #def.properties.additional_item_blacklist do + table.insert(def.properties.item_blacklist, def.properties.additional_item_blacklist[i]) + end + end + def.properties.speed = def.properties.speed or 1 def.properties.max_hp = def.properties.max_hp or 20 end diff --git a/mods/ctf/ctf_classes/gui.lua b/mods/ctf/ctf_classes/gui.lua index e87e449944..fcec7d0a31 100644 --- a/mods/ctf/ctf_classes/gui.lua +++ b/mods/ctf/ctf_classes/gui.lua @@ -42,7 +42,7 @@ function ctf_classes.show_gui(name, player) end fs[#fs + 1] = "]" - for i, item in pairs(class.properties.items or {}) do + for i, item in pairs(class.properties.initial_stuff) do fs[#fs + 1] = "item_image[" fs[#fs + 1] = tostring(i * 0.5 - 0.4) fs[#fs + 1] = ",2.25;0.5,0.5;" diff --git a/mods/ctf/ctf_classes/init.lua b/mods/ctf/ctf_classes/init.lua index 8eb17c195f..614767d040 100644 --- a/mods/ctf/ctf_classes/init.lua +++ b/mods/ctf/ctf_classes/init.lua @@ -21,7 +21,7 @@ ctf_classes.register("knight", { max_hp = 30, speed = 0.90, - items = { + initial_stuff = { "default:sword_steel", }, @@ -39,11 +39,16 @@ ctf_classes.register("shooter", { cons = {}, color = "#c60", properties = { - items = { + initial_stuff = { "shooter:rifle", "shooter:grapple_gun_loaded", }, + additional_item_blacklist = { + "shooter:grapple_gun", + "shooter:grapple_hook", + }, + allowed_guns = { "shooter:pistol", "shooter:rifle", @@ -64,7 +69,7 @@ ctf_classes.register("medic", { cons = {}, color = "#0af", properties = { - items = { + initial_stuff = { "ctf_bandages:bandage 20", }, @@ -82,11 +87,15 @@ ctf_classes.register("rocketeer", { cons = {}, color = "#fa0", properties = { - items = { + initial_stuff = { "shooter:rocket_gun_loaded", "shooter:rocket 4", }, + additional_item_blacklist = { + "shooter:rocket_gun", + }, + allowed_guns = { "shooter:pistol", "shooter:smg", diff --git a/mods/ctf/ctf_classes/items.lua b/mods/ctf/ctf_classes/items.lua index e10ea05e58..5422d98120 100644 --- a/mods/ctf/ctf_classes/items.lua +++ b/mods/ctf/ctf_classes/items.lua @@ -1,13 +1,29 @@ +local function stack_list_to_map(stacks) + local map = {} + for i = 1, #stacks do + map[ItemStack(stacks[i]):get_name()] = true + end + return map +end + +-- Returns true if the item shouldn't be allowed to be dropped etc +local function is_class_blacklisted(player, itemname) + local class = ctf_classes.get(player) + local items = stack_list_to_map(class.properties.item_blacklist or {}) + return items[itemname] +end + + give_initial_stuff.register_stuff_provider(function(player) local class = ctf_classes.get(player) - return class.properties.items or {} + return class.properties.initial_stuff or {} end, 1) ctf_classes.register_on_changed(function(player, old, new) local inv = player:get_inventory() if old then - local items = old.properties.items or {} + local items = old.properties.item_blacklist or {} for i = 1, #items do inv:remove_item("main", ItemStack(items[i])) end @@ -16,27 +32,16 @@ ctf_classes.register_on_changed(function(player, old, new) do assert(new) - local items = new.properties.items or {} + local items = new.properties.initial_stuff or {} for i = 1, #items do inv:add_item("main", ItemStack(items[i])) end end end) -local function stack_list_to_map(stacks) - local map = {} - for i = 1, #stacks do - map[ItemStack(stacks[i]):get_name()] = true - end - return map -end - local old_item_drop = minetest.item_drop minetest.item_drop = function(itemstack, player, pos) - local class = ctf_classes.get(player) - - local items = stack_list_to_map(class.properties.items or {}) - if items[itemstack:get_name()] then + if is_class_blacklisted(player, itemstack:get_name()) then minetest.chat_send_player(player:get_player_name(), "You're not allowed to drop class items!") return itemstack @@ -47,10 +52,7 @@ end local old_is_allowed = ctf_map.is_item_allowed_in_team_chest ctf_map.is_item_allowed_in_team_chest = function(listname, stack, player) - local class = ctf_classes.get(player) - - local items = stack_list_to_map(class.properties.items or {}) - if items[stack:get_name()] then + if is_class_blacklisted(player, stack:get_name()) then minetest.chat_send_player(player:get_player_name(), "You're not allowed to put class items in the chest!") return false @@ -58,3 +60,7 @@ ctf_map.is_item_allowed_in_team_chest = function(listname, stack, player) return old_is_allowed(listname, stack, player) end end + +dropondie.register_drop_filter(function(player, itemname) + return not is_class_blacklisted(player, itemname) +end) diff --git a/mods/ctf/ctf_classes/mod.conf b/mods/ctf/ctf_classes/mod.conf index 1967fb0cb7..0e9b5679ef 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, physics, shooter, hpregen, give_initial_stuff +depends = ctf, ctf_flag, ctf_colors, ctf_map_core, physics, shooter, hpregen, give_initial_stuff, dropondie description = Adds classes, including knight, shooter, and medic diff --git a/mods/ctf/ctf_stats/chat.lua b/mods/ctf/ctf_stats/chat.lua index 9e02d5b066..a327c5ff2e 100644 --- a/mods/ctf/ctf_stats/chat.lua +++ b/mods/ctf/ctf_stats/chat.lua @@ -194,3 +194,22 @@ minetest.register_chatcommand("transfer_rankings", { return true, "Stats of '" .. src .. "' have been transferred to '" .. dest .. "'." end }) + + +minetest.register_chatcommand("makepro", { + description = "Make self a pro", + privs = {ctf_admin = true}, + func = function(name, param) + local stats, _ = ctf_stats.player(name) + + if stats.kills < 1.5 * (stats.deaths + 1) then + stats.kills = 1.51 * (stats.deaths + 1) + end + + if stats.score < 10000 then + stats.score = 10000 + end + + return true, "Done" + end +}) diff --git a/mods/pvp/dropondie/init.lua b/mods/pvp/dropondie/init.lua index 5da568c517..11dc85143d 100644 --- a/mods/pvp/dropondie/init.lua +++ b/mods/pvp/dropondie/init.lua @@ -1,13 +1,26 @@ +dropondie = {} + +local registered_drop_filters = {} + +-- return true to drop, false to destroy +function dropondie.register_drop_filter(func, priority) + table.insert(registered_drop_filters, + priority or (#registered_drop_filters + 1), + func) +end + local blacklist_drop = {} +dropondie.register_drop_filter(function(player, itemname) + return table.indexof(blacklist_drop, itemname) == -1 +end) -local function drop(pos, itemstack) +local function drop(player, pos, itemstack) local it = itemstack:take_item(itemstack:get_count()) local sname = it:get_name() - for _, item in pairs(blacklist_drop) do - if sname == item then - minetest.log("info", "[dropondie] Not dropping " .. sname) - return + for i=1, #registered_drop_filters do + if not registered_drop_filters[i](player, sname) then + return itemstack end end @@ -24,9 +37,9 @@ local function drop(pos, itemstack) return itemstack end -local function drop_list(pos, inv, list) +local function drop_list(player, pos, inv, list) for i = 1, inv:get_size(list) do - drop(pos, inv:get_stack(list, i)) + drop(player, pos, inv:get_stack(list, i)) inv:set_stack(list, i, nil) end end @@ -39,8 +52,8 @@ local function drop_all(player) for _, item in pairs(give_initial_stuff.get_stuff(player)) do inv:remove_item("main", ItemStack(item)) end - drop_list(pos, inv, "main") - drop_list(pos, inv, "craft") + drop_list(player, pos, inv, "main") + drop_list(player, pos, inv, "craft") end minetest.register_on_dieplayer(drop_all) From 8230a622fa02b4fe23a0b3bbb10d844c9dcc400f Mon Sep 17 00:00:00 2001 From: rubenwardy Date: Sat, 14 Mar 2020 17:54:53 +0000 Subject: [PATCH 11/15] Add wear when throwing grapple hook --- mods/pvp/shooter/grapple.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/mods/pvp/shooter/grapple.lua b/mods/pvp/shooter/grapple.lua index 2bf62f8fa0..d0011ec198 100644 --- a/mods/pvp/shooter/grapple.lua +++ b/mods/pvp/shooter/grapple.lua @@ -74,6 +74,7 @@ minetest.register_tool("shooter:grapple_hook", { if pointed_thing.type ~= "nothing" then return itemstack end + itemstack:add_wear(65536 / 16) throw_hook(itemstack, user, 14) return "" end, From 990378ee14e884880b624e384fd18f514b7f88a6 Mon Sep 17 00:00:00 2001 From: rubenwardy Date: Sat, 14 Mar 2020 19:37:31 +0000 Subject: [PATCH 12/15] Fix non-shooters from being able to use grappling hooks --- mods/ctf/ctf_classes/init.lua | 2 ++ mods/ctf/ctf_classes/ranged.lua | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/mods/ctf/ctf_classes/init.lua b/mods/ctf/ctf_classes/init.lua index 614767d040..dc161d2319 100644 --- a/mods/ctf/ctf_classes/init.lua +++ b/mods/ctf/ctf_classes/init.lua @@ -39,6 +39,8 @@ ctf_classes.register("shooter", { cons = {}, color = "#c60", properties = { + allow_grapples = true, + initial_stuff = { "shooter:rifle", "shooter:grapple_gun_loaded", diff --git a/mods/ctf/ctf_classes/ranged.lua b/mods/ctf/ctf_classes/ranged.lua index 8f4dd9a2b1..628e68b4de 100644 --- a/mods/ctf/ctf_classes/ranged.lua +++ b/mods/ctf/ctf_classes/ranged.lua @@ -45,7 +45,7 @@ local function check_grapple(itemname) local old_func = def.on_use minetest.override_item(itemname, { on_use = function(itemstack, user, ...) - if ctf_classes.get(user).name ~= "shooter" then + if not ctf_classes.get(user).properties.allow_grapples then minetest.chat_send_player(user:get_player_name(), "Your class can't use that weapon! Change your class at spawn") @@ -66,3 +66,4 @@ end check_grapple("shooter:grapple_gun_loaded") check_grapple("shooter:grapple_gun") +check_grapple("shooter:grapple_hook") From a2481239bed91039d43e60c127a0fdf364b8094f Mon Sep 17 00:00:00 2001 From: rubenwardy Date: Sat, 14 Mar 2020 19:52:40 +0000 Subject: [PATCH 13/15] Fix class change on captured flag not working --- mods/ctf/ctf_classes/init.lua | 52 +++++++++++++---------------------- mods/ctf/ctf_flag/flags.lua | 6 ++-- 2 files changed, 23 insertions(+), 35 deletions(-) diff --git a/mods/ctf/ctf_classes/init.lua b/mods/ctf/ctf_classes/init.lua index dc161d2319..b6bc99dcfe 100644 --- a/mods/ctf/ctf_classes/init.lua +++ b/mods/ctf/ctf_classes/init.lua @@ -153,44 +153,30 @@ ctf_colors.set_skin = function(player, color) ctf_classes.set_skin(player, color, ctf_classes.get(player)) end -local flags = { - "ctf_flag:flag", - "ctf_flag:flag_top_red", - "ctf_flag:flag_top_blue", -} - -for _, flagname in pairs(flags) do - local old_func = minetest.registered_nodes[flagname].on_punch - local function on_punch(pos, node, player, ...) - local fpos = pos - if node.name:sub(1, 18) == "ctf_flag:flag_top_" then - fpos = vector.new(pos) - fpos.y = fpos.y - 1 +local old_func = ctf_flag.on_punch +local function on_punch(pos, node, player, ...) + local class = ctf_classes.get(player) + if not class.properties.can_capture then + local pname = player:get_player_name() + local flag = ctf_flag.get(pos) + local team = ctf.player(pname).team + if flag and flag.team and team and team ~= flag.team then + minetest.chat_send_player(pname, + "You need to change classes to capture the flag!") + return end + end - local class = ctf_classes.get(player) - if not class.properties.can_capture then - local pname = player:get_player_name() - local flag = ctf_flag.get(fpos) - local team = ctf.player(pname).team - if flag and flag.team and team and team ~= flag.team then - minetest.chat_send_player(pname, - "You need to change classes to capture the flag!") - return - end - end + return old_func(pos, node, player, ...) +end - return old_func(pos, node, player, ...) - end - local function show(_, _, player) - ctf_classes.show_gui(player:get_player_name(), player) - end - minetest.override_item(flagname, { - on_punch = on_punch, - on_rightclick = show, - }) +local function show(_, _, player) + ctf_classes.show_gui(player:get_player_name(), player) end +ctf_flag.on_rightclick = show +ctf_flag.on_punch = on_punch + ctf_classes.register_on_changed(function(player, old, new) if not old then return diff --git a/mods/ctf/ctf_flag/flags.lua b/mods/ctf/ctf_flag/flags.lua index a7a9d8ddff..776d06eaa2 100644 --- a/mods/ctf/ctf_flag/flags.lua +++ b/mods/ctf/ctf_flag/flags.lua @@ -20,8 +20,10 @@ minetest.register_node("ctf_flag:flag", { } }, groups = {immortal=1,is_flag=1,flag_bottom=1}, - on_punch = ctf_flag.on_punch, - on_rightclick = ctf_flag.on_rightclick, + + -- Wrap fuctions to allow overriding + on_punch = function(...) ctf_flag.on_punch(...) end, + on_rightclick = function(...) ctf_flag.on_rightclick(...) end, on_construct = ctf_flag.on_construct, after_place_node = ctf_flag.after_place_node, on_timer = ctf_flag.flag_tick From 115d70140a5a54dcf9aa57471cbf3861a454a5f3 Mon Sep 17 00:00:00 2001 From: rubenwardy Date: Sat, 14 Mar 2020 19:56:40 +0000 Subject: [PATCH 14/15] Split classes init.lua into multiple files --- mods/ctf/ctf_classes/classes.lua | 95 ++++++++++++++++++++++ mods/ctf/ctf_classes/flags.lua | 31 ++++++++ mods/ctf/ctf_classes/init.lua | 132 +------------------------------ 3 files changed, 128 insertions(+), 130 deletions(-) create mode 100644 mods/ctf/ctf_classes/classes.lua create mode 100644 mods/ctf/ctf_classes/flags.lua diff --git a/mods/ctf/ctf_classes/classes.lua b/mods/ctf/ctf_classes/classes.lua new file mode 100644 index 0000000000..cd5aa7d7b5 --- /dev/null +++ b/mods/ctf/ctf_classes/classes.lua @@ -0,0 +1,95 @@ +ctf_classes.default_class = "knight" + +ctf_classes.register("knight", { + description = "Knight", + pros = { "+50% Health Points" }, + cons = { "-10% speed" }, + color = "#ccc", + properties = { + max_hp = 30, + speed = 0.90, + + initial_stuff = { + "default:sword_steel", + }, + + allowed_guns = { + "shooter:pistol", + "shooter:smg", + "shooter:shotgun", + }, + }, +}) + +ctf_classes.register("shooter", { + description = "Sharp Shooter", + pros = { "+50% range", "+20% faster shooting" }, + cons = {}, + color = "#c60", + properties = { + allow_grapples = true, + + initial_stuff = { + "shooter:rifle", + "shooter:grapple_gun_loaded", + }, + + additional_item_blacklist = { + "shooter:grapple_gun", + "shooter:grapple_hook", + }, + + allowed_guns = { + "shooter:pistol", + "shooter:rifle", + "shooter:smg", + "shooter:shotgun", + }, + + shooter_multipliers = { + range = 1.5, + full_punch_interval = 0.8, + }, + }, +}) + +ctf_classes.register("medic", { + description = "Medic", + pros = { "x2 regen for nearby friendlies" }, + cons = {}, + color = "#0af", + properties = { + initial_stuff = { + "ctf_bandages:bandage 20", + }, + + allowed_guns = { + "shooter:pistol", + "shooter:smg", + "shooter:shotgun", + }, + }, +}) + +ctf_classes.register("rocketeer", { + description = "Rocketeer", + pros = { "Can craft rockets" }, + cons = {}, + color = "#fa0", + properties = { + initial_stuff = { + "shooter:rocket_gun_loaded", + "shooter:rocket 4", + }, + + additional_item_blacklist = { + "shooter:rocket_gun", + }, + + allowed_guns = { + "shooter:pistol", + "shooter:smg", + "shooter:shotgun", + }, + }, +}) diff --git a/mods/ctf/ctf_classes/flags.lua b/mods/ctf/ctf_classes/flags.lua new file mode 100644 index 0000000000..41874d621f --- /dev/null +++ b/mods/ctf/ctf_classes/flags.lua @@ -0,0 +1,31 @@ +ctf_flag.register_on_pick_up(function(name) + ctf_classes.update(minetest.get_player_by_name(name)) +end) + +ctf_flag.register_on_drop(function(name) + ctf_classes.update(minetest.get_player_by_name(name)) +end) + +local old_func = ctf_flag.on_punch +local function on_punch(pos, node, player, ...) + local class = ctf_classes.get(player) + if not class.properties.can_capture then + local pname = player:get_player_name() + local flag = ctf_flag.get(pos) + local team = ctf.player(pname).team + if flag and flag.team and team and team ~= flag.team then + minetest.chat_send_player(pname, + "You need to change classes to capture the flag!") + return + end + end + + return old_func(pos, node, player, ...) +end + +local function show(_, _, player) + ctf_classes.show_gui(player:get_player_name(), player) +end + +ctf_flag.on_rightclick = show +ctf_flag.on_punch = on_punch diff --git a/mods/ctf/ctf_classes/init.lua b/mods/ctf/ctf_classes/init.lua index b6bc99dcfe..da28846a9c 100644 --- a/mods/ctf/ctf_classes/init.lua +++ b/mods/ctf/ctf_classes/init.lua @@ -1,8 +1,6 @@ ctf_classes = { __classes = {}, __classes_ordered = {}, - - default_class = "knight", } dofile(minetest.get_modpath("ctf_classes") .. "/api.lua") @@ -10,102 +8,8 @@ dofile(minetest.get_modpath("ctf_classes") .. "/gui.lua") dofile(minetest.get_modpath("ctf_classes") .. "/regen.lua") dofile(minetest.get_modpath("ctf_classes") .. "/ranged.lua") dofile(minetest.get_modpath("ctf_classes") .. "/items.lua") - - -ctf_classes.register("knight", { - description = "Knight", - pros = { "+50% Health Points" }, - cons = { "-10% speed" }, - color = "#ccc", - properties = { - max_hp = 30, - speed = 0.90, - - initial_stuff = { - "default:sword_steel", - }, - - allowed_guns = { - "shooter:pistol", - "shooter:smg", - "shooter:shotgun", - }, - }, -}) - -ctf_classes.register("shooter", { - description = "Sharp Shooter", - pros = { "+50% range", "+20% faster shooting" }, - cons = {}, - color = "#c60", - properties = { - allow_grapples = true, - - initial_stuff = { - "shooter:rifle", - "shooter:grapple_gun_loaded", - }, - - additional_item_blacklist = { - "shooter:grapple_gun", - "shooter:grapple_hook", - }, - - allowed_guns = { - "shooter:pistol", - "shooter:rifle", - "shooter:smg", - "shooter:shotgun", - }, - - shooter_multipliers = { - range = 1.5, - full_punch_interval = 0.8, - }, - }, -}) - -ctf_classes.register("medic", { - description = "Medic", - pros = { "x2 regen for nearby friendlies" }, - cons = {}, - color = "#0af", - properties = { - initial_stuff = { - "ctf_bandages:bandage 20", - }, - - allowed_guns = { - "shooter:pistol", - "shooter:smg", - "shooter:shotgun", - }, - }, -}) - -ctf_classes.register("rocketeer", { - description = "Rocketeer", - pros = { "Can craft rockets" }, - cons = {}, - color = "#fa0", - properties = { - initial_stuff = { - "shooter:rocket_gun_loaded", - "shooter:rocket 4", - }, - - additional_item_blacklist = { - "shooter:rocket_gun", - }, - - allowed_guns = { - "shooter:pistol", - "shooter:smg", - "shooter:shotgun", - }, - }, -}) - +dofile(minetest.get_modpath("ctf_classes") .. "/flags.lua") +dofile(minetest.get_modpath("ctf_classes") .. "/classes.lua") minetest.register_on_joinplayer(function(player) @@ -116,14 +20,6 @@ minetest.register_on_joinplayer(function(player) end end) -ctf_flag.register_on_pick_up(function(name) - ctf_classes.update(minetest.get_player_by_name(name)) -end) - -ctf_flag.register_on_drop(function(name) - ctf_classes.update(minetest.get_player_by_name(name)) -end) - minetest.register_chatcommand("class", { func = function(name, params) local player = minetest.get_player_by_name(name) @@ -153,30 +49,6 @@ ctf_colors.set_skin = function(player, color) ctf_classes.set_skin(player, color, ctf_classes.get(player)) end -local old_func = ctf_flag.on_punch -local function on_punch(pos, node, player, ...) - local class = ctf_classes.get(player) - if not class.properties.can_capture then - local pname = player:get_player_name() - local flag = ctf_flag.get(pos) - local team = ctf.player(pname).team - if flag and flag.team and team and team ~= flag.team then - minetest.chat_send_player(pname, - "You need to change classes to capture the flag!") - return - end - end - - return old_func(pos, node, player, ...) -end - -local function show(_, _, player) - ctf_classes.show_gui(player:get_player_name(), player) -end - -ctf_flag.on_rightclick = show -ctf_flag.on_punch = on_punch - ctf_classes.register_on_changed(function(player, old, new) if not old then return From dbe7fa44dcf7d6d92b1683f4f31a6955aec690bd Mon Sep 17 00:00:00 2001 From: rubenwardy Date: Sat, 14 Mar 2020 19:59:10 +0000 Subject: [PATCH 15/15] Control x2 hpregen with class property --- mods/ctf/ctf_classes/classes.lua | 2 ++ mods/ctf/ctf_classes/regen.lua | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/mods/ctf/ctf_classes/classes.lua b/mods/ctf/ctf_classes/classes.lua index cd5aa7d7b5..13cf990b62 100644 --- a/mods/ctf/ctf_classes/classes.lua +++ b/mods/ctf/ctf_classes/classes.lua @@ -59,6 +59,8 @@ ctf_classes.register("medic", { cons = {}, color = "#0af", properties = { + nearby_hpregen = true, + initial_stuff = { "ctf_bandages:bandage 20", }, diff --git a/mods/ctf/ctf_classes/regen.lua b/mods/ctf/ctf_classes/regen.lua index 6a0a958a39..44f67a45c4 100644 --- a/mods/ctf/ctf_classes/regen.lua +++ b/mods/ctf/ctf_classes/regen.lua @@ -12,7 +12,7 @@ local function regen_update() local class = get(player) local tname = ctf.player(pname).team tnames[pname] = tname - if class.name == "medic" then + if class.properties.nearby_hpregen then if tname then medic_by_team[tname][#medic_by_team[tname] + 1] = player:get_pos() found_medic = true