fantasy-brawl-cd2025/_classes/classes_system.lua
2022-10-30 01:37:37 +02:00

202 lines
5.3 KiB
Lua

--[[
When the code refers to the player'S class it means the class table
associated to him/her in the arena.classes[pl_name] property.
The definition table to put in register_class() is the following:
{
name : string =
the class name, it is automatically translated in chat
messages.
items : { "name" or {name : string}, ...} =
the items that the player will receive when the match starts.
skills : {"skill1", ...} =
the skills that the player will unlock.
physics_override : {...}
on_start : function(self, arena, pl_name) =
this gets called when this class gets assigned to pl_name. self
is the class table assigned to the player while pl_name is his/her
name.
on_end : function(self, arena, pl_name) =
this gets called when the match finishes (on_celebration).
on_death : function(self, arena, pl_name, reason) =
this gets called when the player dies.
on_kill : function(self, arena, pl_name, killed_pl_name) =
this gets called when the player kills someone.
... other functions or custom properties, just make sure
that their names don't conflict with the already existing
ones.
}
]]
fbrawl.classes = {} -- index : number = class : {}
fbrawl.min_kills_to_use_ultimate = 5
local function get_valid_class() end
local function set_callbacks() end
local function set_physics() end
local T = fbrawl.T
function fbrawl.register_class(name, def)
def = get_valid_class(name, def)
fbrawl.classes[#fbrawl.classes+1] = def
end
function fbrawl.apply_class(pl_name, class)
local player = minetest.get_player_by_name(pl_name)
local player_inv = player:get_inventory()
local arena = arena_lib.get_arena_by_player(pl_name)
-- Adding the class' items to the player.
for i, item in pairs(class.items) do
local item_name = item.name or item
player_inv:add_item("main", ItemStack(item_name))
end
pl_name:unlock_skill("fbrawl:sp")
pl_name:start_skill("fbrawl:sp")
-- Unlocking the player's skills.
for i, skill_name in pairs(class.skills) do
pl_name:unlock_skill(skill_name)
end
player:set_physics_override(class.physics_override)
end
function fbrawl.get_class_by_name(name)
for i, class in pairs(fbrawl.classes) do
if class.name:lower() == name:lower() then return class end
end
end
function fbrawl.get_classes()
local classes = {} -- name: string = def: table
for i, class in pairs(fbrawl.classes) do
classes[class.name] = class
end
return classes
end
function fbrawl.class_has_skill(class_name, skill_name)
local skills = fbrawl.get_classes()[class_name].skills
for i, name in ipairs(skills) do
if skill_name == name then return true end
end
return false
end
function get_valid_class(name, class)
set_physics(class)
set_callbacks(class)
assert(
class.name or class.hotbar_description or class.items or class.skills
"A class hasn't been configured correctly ("..name..")!"
)
assert(
not fbrawl.get_class_by_name(class.name),
"Two classes have the same name ("..name..")!"
)
return class
end
function set_callbacks(class)
local empty_func = function() end
local on_death = class.on_death or empty_func
local on_end = class.on_end or empty_func
local on_eliminated = class.on_eliminated or empty_func
local on_start = class.on_start or empty_func
local on_kill = class.on_kill or empty_func
class.on_start = function(self, arena, pl_name)
local player = minetest.get_player_by_name(pl_name)
self.in_game = true
fbrawl.generate_HUD(arena, pl_name)
-- Hiding the wielded item if 3d_armor is installed.
player:get_meta():set_int("show_wielded_item", 2)
fbrawl.apply_class(pl_name, class)
on_start(self, arena, pl_name)
end
class.on_kill = function(self, arena, pl_name, killed_pl_name)
local props = arena.players[pl_name]
props.kills = props.kills + 1
props.ultimate_recharge = math.min(props.ultimate_recharge + 1, fbrawl.min_kills_to_use_ultimate)
fbrawl.update_hud(pl_name, "kills", props.kills)
on_kill(self, arena, pl_name, killed_pl_name)
end
class.on_death = function(self, arena, pl_name, reason)
on_death(self, arena, pl_name, reason)
local props = arena.players[pl_name]
fbrawl.update_hud(pl_name, "deaths", props.deaths)
if reason and reason.object then
local killer_name = reason.object:get_player_name()
local killer_class = arena.classes[killer_name]
killer_class:on_kill(arena, killer_name, pl_name)
end
end
class.on_end = function(self, arena, pl_name)
pl_name:remove_skill("fbrawl:sp")
on_end(self, arena, pl_name)
end
end
function set_physics(class)
local phys = class.physics_override or {}
phys.speed = phys.speed or 1.2
phys.gravity = phys.gravity or 1
phys.acceleration = phys.acceleration or 1
phys.jump = phys.jump or 1
phys.sneak = phys.sneak or true
phys.sneak_glitch = phys.sneak_glitch or false
phys.new_move = phys.new_move or true
class.physics_override = phys
end
arena_lib.on_death("fantasy_brawl", function(arena, pl_name, reason)
arena.classes[pl_name]:on_death(arena, pl_name, reason)
end)