2019-03-21 01:36:59 +00:00
|
|
|
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.pros = def.pros or {}
|
|
|
|
def.cons = def.cons or {}
|
2019-03-22 04:31:57 +00:00
|
|
|
|
|
|
|
def.properties = def.properties or {}
|
|
|
|
if def.properties.can_capture == nil then
|
|
|
|
def.properties.can_capture = true
|
|
|
|
end
|
2020-03-14 17:50:24 +00:00
|
|
|
|
|
|
|
def.properties.initial_stuff = def.properties.initial_stuff or {}
|
|
|
|
|
|
|
|
if not def.properties.item_blacklist then
|
|
|
|
def.properties.item_blacklist = {}
|
2020-10-13 23:23:09 +00:00
|
|
|
for i, item in ipairs(def.properties.initial_stuff) do
|
|
|
|
local iname = ItemStack(item):get_name()
|
|
|
|
|
|
|
|
-- Only add to item blacklist if not in the whitelist
|
|
|
|
if table.indexof(def.properties.item_whitelist or {}, iname) == -1 then
|
|
|
|
def.properties.item_blacklist[i] = iname
|
|
|
|
end
|
2020-03-14 17:50:24 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
if def.properties.additional_item_blacklist then
|
|
|
|
for i=1, #def.properties.additional_item_blacklist do
|
2020-03-14 21:51:24 +00:00
|
|
|
table.insert(def.properties.item_blacklist,
|
|
|
|
def.properties.additional_item_blacklist[i])
|
2020-03-14 17:50:24 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2020-03-14 21:51:24 +00:00
|
|
|
-- Validate items
|
|
|
|
for i=1, #def.properties.initial_stuff do
|
|
|
|
local item_name = ItemStack(def.properties.initial_stuff[i]):get_name()
|
|
|
|
assert(minetest.registered_items[item_name], "Item " .. item_name .. " not found")
|
|
|
|
end
|
|
|
|
for i=1, #def.properties.item_blacklist do
|
|
|
|
local item_name = def.properties.item_blacklist[i]
|
|
|
|
assert(minetest.registered_items[item_name], "Item " .. item_name .. " not found")
|
|
|
|
end
|
|
|
|
|
2019-03-22 04:31:57 +00:00
|
|
|
def.properties.speed = def.properties.speed or 1
|
|
|
|
def.properties.max_hp = def.properties.max_hp or 20
|
2019-03-21 01:36:59 +00:00
|
|
|
end
|
|
|
|
|
2020-03-13 21:58:42 +00:00
|
|
|
local registered_on_changed = {}
|
|
|
|
function ctf_classes.register_on_changed(func)
|
|
|
|
table.insert(registered_on_changed, func)
|
|
|
|
end
|
|
|
|
|
2019-03-21 01:36:59 +00:00
|
|
|
function ctf_classes.set_skin(player, color, class)
|
|
|
|
player:set_properties({
|
2019-03-22 04:27:05 +00:00
|
|
|
textures = {"ctf_classes_skin_" .. class.name .. "_" .. (color or "blue") .. ".png"}
|
2019-03-21 01:36:59 +00:00
|
|
|
})
|
|
|
|
end
|
|
|
|
|
|
|
|
function ctf_classes.get(player)
|
|
|
|
if type(player) == "string" then
|
|
|
|
player = minetest.get_player_by_name(player)
|
|
|
|
end
|
|
|
|
|
2020-05-07 09:22:14 +00:00
|
|
|
-- Return class from player meta if valid, or default class
|
|
|
|
local cname = player:get_meta():get("ctf_classes:class")
|
|
|
|
if not ctf_classes.__classes[cname] then
|
|
|
|
cname = ctf_classes.default_class
|
|
|
|
end
|
2019-03-21 01:36:59 +00:00
|
|
|
return ctf_classes.__classes[cname]
|
|
|
|
end
|
|
|
|
|
2020-03-13 21:58:42 +00:00
|
|
|
function ctf_classes.set(player, new_name)
|
|
|
|
assert(type(new_name) == "string")
|
|
|
|
local new = ctf_classes.__classes[new_name]
|
|
|
|
assert(new)
|
2019-03-21 01:36:59 +00:00
|
|
|
|
|
|
|
local meta = player:get_meta()
|
2020-03-13 21:58:42 +00:00
|
|
|
local old_name = meta:get("ctf_classes:class")
|
|
|
|
|
|
|
|
meta:set_string("ctf_classes:class", new_name)
|
2019-03-21 01:36:59 +00:00
|
|
|
ctf_classes.update(player)
|
|
|
|
|
2020-06-04 16:45:13 +00:00
|
|
|
ctf_classes.set_cooldown(player:get_player_name())
|
|
|
|
|
2020-03-13 21:58:42 +00:00
|
|
|
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
|
2019-03-21 01:36:59 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
local function set_max_hp(player, max_hp)
|
|
|
|
local cur_hp = player:get_hp()
|
2019-03-22 04:31:57 +00:00
|
|
|
local old_max = player:get_properties().hp_max
|
|
|
|
local new_hp = cur_hp + max_hp - old_max
|
2019-03-21 01:36:59 +00:00
|
|
|
player:set_properties({
|
|
|
|
hp_max = max_hp
|
|
|
|
})
|
|
|
|
|
2019-03-22 04:31:57 +00:00
|
|
|
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
|
|
|
|
|
2019-03-21 01:36:59 +00:00
|
|
|
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)
|
2020-03-13 21:58:42 +00:00
|
|
|
local name = player:get_player_name()
|
|
|
|
|
2019-03-21 01:36:59 +00:00
|
|
|
local class = ctf_classes.get(player)
|
2020-03-13 21:58:42 +00:00
|
|
|
local color = ctf_colors.get_color(ctf.player(name)).text
|
2019-03-21 01:36:59 +00:00
|
|
|
|
2019-03-22 04:31:57 +00:00
|
|
|
set_max_hp(player, class.properties.max_hp)
|
2019-03-21 01:36:59 +00:00
|
|
|
ctf_classes.set_skin(player, color, class)
|
2020-03-13 21:58:42 +00:00
|
|
|
|
2020-10-13 23:23:09 +00:00
|
|
|
physics.set(player:get_player_name(), "ctf_classes:physics", {
|
2020-05-01 06:12:16 +00:00
|
|
|
speed = class.properties.speed,
|
2020-10-13 23:23:09 +00:00
|
|
|
jump = class.properties.jump,
|
|
|
|
gravity = class.properties.gravity,
|
2019-03-21 01:36:59 +00:00
|
|
|
})
|
2020-03-14 22:48:50 +00:00
|
|
|
|
|
|
|
crafting.lock_all(player:get_player_name())
|
|
|
|
for i=1, #(class.properties.crafting or {}) do
|
|
|
|
crafting.unlock(player:get_player_name(), class.properties.crafting[i])
|
|
|
|
end
|
2019-03-21 01:36:59 +00:00
|
|
|
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)
|
2020-04-26 09:21:51 +00:00
|
|
|
if minetest.check_player_privs(player, "ctf_admin") then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
2020-06-04 16:45:13 +00:00
|
|
|
if ctf_classes.get_cooldown(player:get_player_name()) then
|
|
|
|
return false, "You need to wait to change classes again!"
|
|
|
|
end
|
|
|
|
|
2019-03-21 01:36:59 +00:00
|
|
|
local flag_pos = get_flag_pos(player)
|
2020-06-04 16:45:13 +00:00
|
|
|
if flag_pos then
|
|
|
|
return sqdist(player:get_pos(), flag_pos) < 25,
|
|
|
|
"Move closer to the flag to change classes!"
|
2019-03-21 01:36:59 +00:00
|
|
|
end
|
|
|
|
|
2020-06-04 16:45:13 +00:00
|
|
|
return false, "Flag does not exist!"
|
2019-03-21 01:36:59 +00:00
|
|
|
end
|
2020-06-04 16:45:13 +00:00
|
|
|
|
|
|
|
-- Cooldown time to prevent consumables abuse by changing to a class and back
|
|
|
|
local COOLDOWN_TIME = 30
|
|
|
|
local cooldown = {}
|
|
|
|
|
|
|
|
function ctf_classes.get_cooldown(name)
|
|
|
|
return cooldown[name]
|
|
|
|
end
|
|
|
|
|
|
|
|
function ctf_classes.set_cooldown(name)
|
|
|
|
cooldown[name] = true
|
|
|
|
minetest.after(COOLDOWN_TIME, function()
|
|
|
|
cooldown[name] = nil
|
|
|
|
end)
|
|
|
|
end
|
|
|
|
|
|
|
|
minetest.register_on_dieplayer(function(player)
|
|
|
|
cooldown[player:get_player_name()] = nil
|
|
|
|
end)
|