diff --git a/mods/ctf/ctf_alloc/init.lua b/mods/ctf/ctf_alloc/init.lua index e565a20..f1449b1 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 0000000..ebcb037 --- /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 0000000..93c9d8b --- /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 0000000..bd19398 --- /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 0000000..0747762 --- /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 0000000..5417632 Binary files /dev/null and b/mods/ctf/ctf_classes/textures/ctf_classes_knight.png differ 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 0000000..901c6cb Binary files /dev/null and b/mods/ctf/ctf_classes/textures/ctf_classes_medic.png differ diff --git a/mods/ctf/ctf_classes/textures/ctf_classes_shooter.png b/mods/ctf/ctf_classes/textures/ctf_classes_shooter.png new file mode 100644 index 0000000..451ed5f Binary files /dev/null and b/mods/ctf/ctf_classes/textures/ctf_classes_shooter.png differ 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 0000000..76ab60c Binary files /dev/null and b/mods/ctf/ctf_classes/textures/ctf_classes_skins_knight_blue.png differ diff --git a/mods/ctf/ctf_classes/textures/ctf_classes_skins_knight_red.png b/mods/ctf/ctf_classes/textures/ctf_classes_skins_knight_red.png new file mode 100644 index 0000000..b8f862c Binary files /dev/null and b/mods/ctf/ctf_classes/textures/ctf_classes_skins_knight_red.png differ diff --git a/mods/ctf/ctf_classes/textures/ctf_classes_skins_medic_blue.png b/mods/ctf/ctf_classes/textures/ctf_classes_skins_medic_blue.png new file mode 100644 index 0000000..cdb2563 Binary files /dev/null and b/mods/ctf/ctf_classes/textures/ctf_classes_skins_medic_blue.png differ 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 0000000..e701b84 Binary files /dev/null and b/mods/ctf/ctf_classes/textures/ctf_classes_skins_medic_red.png differ 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 0000000..1d362d0 Binary files /dev/null and b/mods/ctf/ctf_classes/textures/ctf_classes_skins_shooter_blue.png differ 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 0000000..d6645eb Binary files /dev/null and b/mods/ctf/ctf_classes/textures/ctf_classes_skins_shooter_red.png differ 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 7a313bd..4878616 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 d020602..58b5053 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 3a03494..775b451 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 57bffa0..7ef94ab 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