yeah, so... I forgot I made this repo, anyway here's what we've got this far (very WIP)

This commit is contained in:
Giov4 2022-10-03 18:51:13 +02:00
parent 11d5fd6c4c
commit 7edfdc40fd
53 changed files with 2023 additions and 0 deletions

21
SETTINGS.lua Normal file
View File

@ -0,0 +1,21 @@
--[[
! WARNING !
Don't change the variables names if you don't know what you're doing!
(fbrawl_settings.variable_name = value)
]]
-- ARENA LIB'S SETTINGS --
-- The table that stores all the global variables, don't touch this.
fbrawl_settings = {}
-- The maximum amount of time between the loading state and the start of the match.
fbrawl_settings.max_loading_time = 10
-- The time between the end of the match and the respawn at the hub.
fbrawl_settings.celebration_time = 5
-- What's going to appear in most of the lines printed by fantasy brawl.
fbrawl_settings.prefix = "Fantasy Brawl > "

View File

@ -0,0 +1,76 @@
local function on_load() end
local T = fbrawl.T
arena_lib.on_enable("fbrawl", function(arena, pl_name)
return true
end)
arena_lib.on_start("fbrawl", function(arena)
arena.match_id = math.random(1, 9999999999)
arena_lib.send_message_in_arena(
arena,
"players",
minetest.colorize("#f9a31b",
fbrawl_settings.prefix ..
T(
"You have @1 seconds to choose your class!",
fbrawl_settings.max_loading_time
)
)
)
arena_lib.HUD_send_msg_all(
"broadcast",
arena,
T("Read your items' description to learn their utility"),
fbrawl_settings.max_loading_time
)
minetest.after(fbrawl_settings.max_loading_time, function() on_load(arena) end)
end)
arena_lib.on_celebration("fbrawl", function(arena, winner_name)
for pl_name, _ in pairs(arena.players) do
arena.classes[pl_name]:on_end(arena, pl_name)
end
end)
arena_lib.on_death("fbrawl", function(arena, pl_name, reason)
arena.classes[pl_name]:on_death(arena, pl_name, reason)
end)
arena_lib.on_timeout("fbrawl", function(arena)
-- cose
end)
arena_lib.on_quit("fbrawl", function(arena, pl_name, is_spectator)
-- cose
end)
arena_lib.on_time_tick("fbrawl", function(arena)
for pl_name, _ in pairs(arena.players) do
fbrawl.update_HUD(pl_name, "timer_ID", arena.current_time)
end
end)
arena_lib.on_load("fbrawl", function(arena)
for pl_name in pairs(arena.players) do
arena.classes[pl_name]:on_start(arena, pl_name)
end
end

View File

@ -0,0 +1,15 @@
local function apply_class() end
local T = fbrawl.T
function fbrawl.is_player_playing(pl_name)
local arena = arena_lib.get_arena_by_player(pl_name)
return arena and not arena.in_celebration and not arena.in_loading and not arena.in_queue
end
function fbrawl.prekick_operations(pl_name)
fbrawl.remove_HUD(pl_name)
end

170
_classes/classes_system.lua Normal file
View File

@ -0,0 +1,170 @@
--[[
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 : {...}
HUD_timer : string =
a custom texture for the timer HUD.
sound : string =
the sound that will be reproduced to the player when this class
will be assigned to them.
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.
}
]]
local function get_valid_class() end
local function set_callbacks() end
local function set_physics() end
fbrawl.classes = {} -- index : number = class : {}
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
-- Unlocking the player's skins.
for i, skill_name in pairs(class.skills) do
player_inv:unlock_skill(skill_name)
end
player:set_physics_override(class.physics_override)
--minetest.sound_play(class.sound, {to_player = pl_name})
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 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)
on_start(self, arena, pl_name)
end
class.on_kill = function(self, arena, pl_name, killed_pl_name)
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)
-- If the player was killed using fbrawl.kill_player().
if reason and reason.type == "punch" then
local killer_name = reason.object:get_player_name()
local killer_class = arena.classes[killer_name]
fbrawl.print_msg(pl_name, T("@1 (@2) killed you!", killer_name, T(killer_class.name)))
killer_class:on_kill(arena, killer_name, pl_name)
end
end
class.on_end = function(self, arena, pl_name)
fbrawl.prekick_operations(pl_name)
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

18
_classes/mage/items.lua Normal file
View File

@ -0,0 +1,18 @@
local T = fbrawl.T
minetest.register_craftitem("fantasy_brawl:mage_staff", {
description = T("Pew pew them with magical bullets!"),
inventory_image = "fbrawl_mage_staff.png",
stack_max = 1,
on_drop = function() return end,
on_use = function(itemstack, player)
local pl_name = player:get_player_name()
local sound = {name = "fbrawl_mage_staff", pos = player:get_pos(), max_hear_distance = 12}
if pl_name:cast_skill("fbrawl:magic_bullet") then
minetest.sound_play(sound, sound, true)
end
end
})

13
_classes/mage/mage.lua Normal file
View File

@ -0,0 +1,13 @@
fbrawl.register_class("mage", {
name = "Mage",
physics_override = {
speed = 1.5,
gravity = 0.9
},
items = {"fbrawl:mage_staff", "fbrawl:"},
skills = {"fbrawl:smash"},
sound = "mage-class"
})
dofile(minetest.get_modpath("fantasy_brawl") .. "/_classes/mage/skills/magic_bullet.lua")
dofile(minetest.get_modpath("fantasy_brawl") .. "/_classes/mage/items.lua")

View File

@ -0,0 +1,148 @@
local function look_raycast() end
local T = fbrawl.T
skillz.register_skill("fbrawl:magic_bullet", {
name = "Magic bullet",
slot = 1,
cooldown = 1.5,
chat_warnings = {
cooldown = false
},
--sounds = {
-- cast = {name = ""}
--},
cast = function(self)
local cast_starting_pos = vector.add({x=0, y=0.9, z=0}, self.player:get_pos())
minetest.add_entity(cast_starting_pos, "fantasy_brawl:magic_bullet", self.pl_name)
end
})
-- The magic bullet entity declaration.
local magic_bullet = {
initial_properties = {
hp_max = 999,
physical = true,
collide_with_objects = false,
collisionbox = {-0.1, -0.1, -0.1, 0.1, 0.1, 0.1},
visual = "sprite",
visual_size = {x = 1, y = 1},
textures = {"fbrawl_mage_bullet_entity.png"},
spritediv = {x = 1, y = 1},
initial_sprite_basepos = {x = 0, y = 0},
speed = 50,
range = 1,
damage = 4
},
pl_name = "",
hit = false,
time_passed = 0
}
-- staticdata = player's username.
function magic_bullet:on_activate(staticdata, dtime_s)
local obj = self.object
if staticdata then
self.pl_name = staticdata
local player = minetest.get_player_by_name(self.pl_name)
if not player then
obj:remove()
return
end
local dir = player:get_look_dir()
local bullet_props = self.initial_properties
obj:set_velocity({
x=(dir.x * bullet_props.speed),
y=(dir.y * bullet_props.speed),
z=(dir.z * bullet_props.speed),
})
else
obj:remove()
return
end
minetest.add_particlespawner({
amount = 80,
time = 0,
minpos = {x = -0.2, y = 0, z = -0.2},
maxpos = {x = 0.2, y = 0.2, z = 0.2},
minvel = {x = 0, y = -0.3, z = 0},
maxvel = {x = 0, y = -0.3, z = 0},
minsize = 4,
maxsize = 6,
texture = {
name = "fbrawl_mage_bullet_entity.png",
alpha_tween = {1, 0}
},
minexptime = 1.5,
maxexptime = 1.5,
attached = obj
})
end
function magic_bullet:remove()
local sound = {name = "fbrawl_magic_bullet", pos = self.object:get_pos(), max_hear_distance = 16}
minetest.sound_play(sound, sound, true)
minetest.add_particlespawner({
amount = 40,
time = 0.3,
minvel = {x = -2, y = -2, z = -2},
maxvel = {x = 2, y = 2, z = 2},
minsize = 4,
maxsize = 6,
texture = {
name = "fbrawl_mage_bullet_entity.png",
alpha_tween = {1, 0}
},
minexptime = 1,
maxexptime = 1.5,
pos = self.object:get_pos()
})
self.object:remove()
end
function magic_bullet:on_step(dtime, moveresult)
local player = minetest.get_player_by_name(self.pl_name)
if not player or moveresult.collides == true then
self:remove()
return
end
local arena = arena_lib.get_arena_by_player(self.pl_name)
-- todo: iterare giocatori in arena
for i, hit_pl in pairs(minetest.get_connected_players()) do
local hit_pl_pos = vector.add({x=0, y=1, z=0}, hit_pl:get_pos())
local bullet_pos = self.object:get_pos()
local distance = vector.distance(bullet_pos, hit_pl_pos)
if hit_pl == player then distance = 9999 end
if distance <= self.initial_properties.range then
fbrawl.hit_player(player, hit_pl, self.initial_properties.damage)
self:remove()
end
end
end
minetest.register_entity("fantasy_brawl:magic_bullet", magic_bullet)

101
_classes/mana.lua Normal file
View File

@ -0,0 +1,101 @@
skillz.register_skill("fbrawl:mana", {
name = "fbrawl:mana",
passive = true,
hud = {{
name = "bar",
hud_elem_type = "image",
text = "fbrawl_manabar_hud.png",
position = {x=0.57, y=0.91},
scale = {x=13, y=1.1}
}},
data = {
amount = 100
},
loop_params = {
cast_rate = 0.05,
},
recharge_duration = 10,
-- "PUBLIC" FUNCTIONS
set = function(self, new_amount)
if new_amount < 0 then
new_amount = 0
elseif new_amount > 100 then
new_amount = 100
end
self.data.amount = new_amount
end,
add = function(self, amount)
self:set(self.data.amount + amount)
end,
sub = function(self, amount)
self:set(self.data.amount - amount)
end,
-- SKILL LOGIC
cast = function(self)
local recharge_step = 100 / self.recharge_duration * self.loop_params.cast_rate
self:add(recharge_step)
self:update_bar_size()
self:update_bar_color()
end,
-- "PRIVATE" FUNCTIONS
update_bar_size = function(self)
local max_length = 13
local progress = self.data.amount/100
local scale_x = progress * max_length
local x_offset = 0.06083 - (progress * 0.06083)
self.player:hud_change(self.data._hud["bar"], "scale", {x=scale_x, y=1.1})
self.player:hud_change(self.data._hud["bar"], "position", {x=0.57-x_offset, y=0.912})
end,
update_bar_color = function(self)
local wielded_item_name = self.player:get_wielded_item():get_name()
local skill = self.pl_name:get_skill(wielded_item_name:gsub("fantasy_brawl", "fbrawl"))
if skill and skill.mana then
if not fbrawl.has_enough_mana(skill) then
self.player:hud_change(self.data._hud["bar"], "text", "fbrawl_manabar_nomana_hud.png")
return
end
end
self.player:hud_change(self.data._hud["bar"], "text", "fbrawl_manabar_hud.png")
end
})
function fbrawl.consume_mana(skill)
if fbrawl.has_enough_mana(skill) then
local mana_skill = skill.pl_name:get_skill("fbrawl:mana")
if skill.cooldown_timer > 0 then
skill:cast() --
skill:start() -- this will print an error in the chat
return false
end
mana_skill:sub(skill.mana)
return true
else
-- todo: sound
return false
end
end
function fbrawl.has_enough_mana(skill)
local mana_skill = skill.pl_name:get_skill("fbrawl:mana")
if skill.mana and mana_skill and mana_skill.is_active then
return mana_skill.data.amount >= skill.mana
else
-- todo: sound
return false
end
end

125
_classes/warrior/items.lua Normal file
View File

@ -0,0 +1,125 @@
local T = fbrawl.T
minetest.register_craftitem("fantasy_brawl:sword", {
description = T("Slice 'em all!"),
inventory_image = "fbrawl_sword_item.png",
stack_max = 1,
tool_capabilities = {
full_punch_interval = 1.0,
damage_groups = {fleshy = 4},
},
on_drop = function() return end,
wield_image = "fbrawl_sword_item.png"
})
minetest.register_craftitem("fantasy_brawl:warrior_jump", {
description = T("Jump very high to crush them better!"),
inventory_image = "fbrawl_smash_skill.png",
stack_max = 1,
on_drop = function() return end,
on_use =
function(itemstack, player)
if fbrawl.is_on_the_ground(player) then
local pl_name = player:get_player_name()
local warrior_jump = pl_name:get_skill("fbrawl:warrior_jump")
if warrior_jump and fbrawl.consume_mana(warrior_jump) then
warrior_jump:cast()
end
end
end
})
minetest.register_craftitem("fantasy_brawl:smash", {
description = T("Time to go back down!"),
inventory_image = "fbrawl_smash_item.png",
stack_max = 1,
on_drop = function() return end,
on_use =
function(itemstack, player)
local pl_name = player:get_player_name()
local jump_skill = pl_name:get_skill("fbrawl:warrior_jump")
if jump_skill then
local fall_force = -jump_skill.jump_force * 2
player:add_player_velocity({x = 0, y = fall_force, z = 0})
end
end
})
minetest.register_craftitem("fantasy_brawl:iron_skin", {
description = T("It's getting pretty tough!"),
inventory_image = "fbrawl_iron_skin_skill.png",
stack_max = 1,
on_drop = function() return end,
on_use =
function(itemstack, player)
local pl_name = player:get_player_name()
local iron_skin = pl_name:get_skill("fbrawl:iron_skin")
if iron_skin and not iron_skin.is_active and fbrawl.consume_mana(iron_skin) then
iron_skin:start()
end
end
})
minetest.register_craftitem("fantasy_brawl:perfect_combo", {
description = T("A combo they won't forget!"),
inventory_image = "fbrawl_perfect_combo_skill.png",
stack_max = 1,
on_drop = function() return end,
})
minetest.register_craftitem("fantasy_brawl:hero_fury", {
description = T("Unleash the fury of the strongest warrior alive!"),
inventory_image = "fbrawl_hero_fury_skill.png",
stack_max = 1,
on_drop = function() return end,
})
minetest.register_on_punchplayer(function(player, hitter, time_from_last_punch, tool_capabilities, dir, damage)
local pl_name = hitter:get_player_name()
local hit_pl_name = player:get_player_name()
local wielded_item = hitter:get_wielded_item():get_name()
local perfect_combo = pl_name:get_skill("fbrawl:perfect_combo")
local hero_fury = pl_name:get_skill("fbrawl:hero_fury")
if
wielded_item == "fantasy_brawl:perfect_combo"
and perfect_combo
and not perfect_combo.is_active
and fbrawl.consume_mana(perfect_combo)
then
perfect_combo:start(player)
end
if
wielded_item == "fantasy_brawl:hero_fury"
and hero_fury
and not hero_fury.is_active
and fbrawl.consume_mana(hero_fury)
then
if not fbrawl.area_raycast_up(player:get_pos(), 10, 25, false) then
hero_fury:start(player:get_player_name())
else
-- todo: funzione error con tanto di suono
minetest.chat_send_player(pl_name, T("There's not enough space here!"))
end
end
end)

View File

@ -0,0 +1,223 @@
local function hit() end
local function look_at() end
skillz.register_skill("fbrawl:hero_fury", {
name = "fbrawl:hero_fury",
mana = 0,
loop_params = {
cast_rate = 0.2,
},
damage = 4,
slot = 4,
upward_force = 50,
punch_force = 20,
data = {
hits = 0,
hit_player = nil
},
on_start = function(self)
self.data.hits = 0
end,
cast = function(self, hit_pl_name)
local hit_player = minetest.get_player_by_name(hit_pl_name)
if not hit_player then return end
self.data.hit_player = hit_player
local hit_pos = hit_player:get_pos()
self.data.hits = self.data.hits + 1
if self.data.hits == 1 then
fbrawl.reset_velocity(hit_player)
fbrawl.reset_velocity(self.player)
self.player:set_physics_override({gravity = 0})
hit_player:set_physics_override({gravity = 0})
hit_player:add_velocity({x=0, y=self.upward_force, z=0})
minetest.add_entity({x=0,y=0,z=0}, "fantasy_brawl:forward_punch", self.player:get_player_name())
hit_pl_name:unlock_skill("fbrawl:hit_by_hero_fury")
minetest.after(0.2, function() hit_pl_name:start_skill("fbrawl:hit_by_hero_fury") end)
elseif self.data.hits == 3 then
hit(self.player, hit_player, {x=1, y=0, z=0})
elseif self.data.hits == 4 then
hit(self.player, hit_player, {x=-1, y=0, z=0})
elseif self.data.hits == 5 then
hit(self.player, hit_player, {x=0, y=0, z=1})
elseif self.data.hits == 6 then
hit(self.player, hit_player, {x=-1, y=0, z=-1})
elseif self.data.hits == 7 then
hit(self.player, hit_player, {x=1, y=0, z=0})
elseif self.data.hits == 8 then
hit(self.player, hit_player, {x=-1, y=0, z=0})
elseif self.data.hits == 9 then
hit(self.player, hit_player, {x=0, y=0, z=1})
elseif self.data.hits == 10 then
hit(self.player, hit_player, {x=-1, y=0, z=-1})
elseif self.data.hits == 12 then
hit(self.player, hit_player, {x=0, y=1.5, z=0}, "last")
self.player:set_physics_override({gravity = 1})
hit_player:set_physics_override({gravity = 1})
fbrawl.camera_shake(self.pl_name, 6, 0.4)
minetest.after(3, function() self:stop() end)
else
return
end
minetest.sound_play({name = "punch"}, {pos = hit_pos, max_hear_distance = 6}, true)
end
})
skillz.register_skill("fbrawl:hit_by_hero_fury", {
name = "fbrawl:hit_by_hero_fury",
mana = 0,
sounds = {
bgm = {name="while_jumping", max_hear_distance = 6},
stop = {name="smash", max_hear_distance = 6},
},
attachments = {
particles = {{
amount = 15,
time = 0,
minpos = {x = -0.3, y = 0, z = -0.3},
maxpos = {x = 0.3, y = 0.5, z = 0.3},
minvel = {x = 0, y = 0, z = 0},
maxvel = {x = 0, y = 0, z = 0},
minsize = 4,
maxsize = 9,
texture = "fbrawl_wjump_particle.png",
minexptime = 1.5,
maxexptime = 1.5,
}}
},
cast = function(self, hit_player)
if fbrawl.is_on_the_ground(self.player) or self.player:get_hp() == 0 then
self:stop()
end
end,
on_stop = function(self)
minetest.add_particlespawner({
amount = 40,
time = 1,
minpos = self.player:get_pos(),
maxpos = self.player:get_pos(),
minvel = {x = -4, y = 1, z = -4},
maxvel = {x = 4, y = 2, z = 4},
minsize = 10,
maxsize = 12.2,
texture = "fbrawl_wjump_particle.png",
minexptime = 0.5,
maxexptime = 0.5,
})
fbrawl.camera_shake(self.pl_name, 6, 0.4)
end
})
-------------------
-- PUNCH ENTITY --
-------------------
local forward_punch = {
initial_properties = {
physical = false,
visual_size = {x = 1, y = 1},
textures = {"fbrawl_punch_entity.png"},
pointable = false,
visual = "sprite",
},
}
function forward_punch:on_activate(pl_name, dtime_s)
if pl_name ~= "" then
local hero_fury = pl_name:get_skill("fbrawl:hero_fury")
local hit_player = hero_fury.data.hit_player
local entity_duration = 0.32
local entity_speed = 9
local player = minetest.get_player_by_name(pl_name)
local obj = self.object
local player_center = vector.add(player:get_pos(), {x=0, y=1, z=0})
local look_dir = player:get_look_dir()
obj:set_pos(player_center)
obj:set_velocity(vector.multiply(look_dir, entity_speed))
-- Preventing the skill from killing the player,
-- they have to die falling.k
if hit_player:get_hp() > hero_fury.damage then
fbrawl.hit_player(hero_fury.player, hit_player, hero_fury.damage)
else
hit_player:set_hp(1)
end
minetest.after(entity_duration, function() obj:remove() end)
else
self.object:remove()
end
end
minetest.register_entity("fantasy_brawl:forward_punch", forward_punch)
function hit(player, hit_player, offset, last)
local hit_pl_pos = hit_player:get_pos()
local punch_force = skillz.get_skill_def("fbrawl:hero_fury").punch_force
fbrawl.reset_velocity(player)
fbrawl.reset_velocity(hit_player)
player:set_pos(vector.add(hit_pl_pos, offset))
look_at(player, hit_pl_pos)
look_at(hit_player, player:get_pos())
if last then
player:set_look_vertical(2)
punch_force = skillz.get_skill_def("fbrawl:hero_fury").upward_force
else
player:set_look_vertical(0)
end
local hitter_look_dir = player:get_look_dir()
local push_force = vector.multiply(hitter_look_dir, punch_force)
minetest.add_entity({x=0,y=0,z=0}, "fantasy_brawl:forward_punch", player:get_player_name())
hit_player:add_velocity(push_force)
end
function look_at(player, target)
local pos = player:get_pos()
local delta = vector.subtract(target, pos)
player:set_look_horizontal(math.atan2(delta.z, delta.x) - math.pi / 2)
end

View File

@ -0,0 +1,72 @@
skillz.register_skill("fbrawl:iron_skin", {
name = "fbrawl:iron_skin",
mana = 50,
slot = 3,
cooldown = 20,
loop_params = {
duration = 5,
},
chat_warnings = {
cooldown = true
},
sounds = {
start = {name = "iron_skin_on", max_hear_distance = 6},
stop = {name = "iron_skin_off", max_hear_distance = 6},
},
attachments = {
entities = {{
name = "fantasy_brawl:shield",
pos = {x = 0, y = 22, z = 0}
}}
},
hud = {{
name = "shield",
hud_elem_type = "image",
text = "fbrawl_iron_skin_skill.png",
scale = {x=3, y=3},
position = {x=0.5, y=0.82},
}},
})
minetest.register_on_player_hpchange(function(player, hp_change, reason)
local pl_name = player:get_player_name()
local iron_skin_skill = pl_name:get_skill("fbrawl:iron_skin")
if iron_skin_skill and iron_skin_skill.is_active and player:get_hp() > 2 then
return hp_change / 2
else
return hp_change
end
end, true)
-------------------
-- SHIELD ENTITY --
-------------------
local shield = {
initial_properties = {
hp_max = 999,
physical = false,
visual_size = {x = 0.35, y = 0.35},
textures = {"fbrawl_iron_skin_skill.png"},
pointable = false,
visual = "sprite",
glow = 1
},
}
function shield:on_activate(pl_name, dtime_s)
if pl_name == "" then
self.object:remove()
end
end
minetest.register_entity("fantasy_brawl:shield", shield)

View File

@ -0,0 +1,144 @@
local random_seed_counter = 0
skillz.register_skill("fbrawl:perfect_combo", {
name = "fbrawl:perfect_combo",
mana = 75,
loop_params = {
cast_rate = 0.15,
},
damage = 2,
slot = 4,
data = {
hits = 0
},
on_start = function(self)
self.data.hits = 0
end,
cast = function(self, hit_player)
local pl_name = hit_player:get_player_name()
local hit_pos = hit_player:get_pos()
self.data.hits = self.data.hits + 1
if self.data.hits == 1 then
minetest.add_entity({x=0,y=0,z=0}, "fantasy_brawl:punch", pl_name)
minetest.sound_play({name = "punch"}, {pos = hit_pos, max_hear_distance = 6}, true)
elseif self.data.hits == 2 then
minetest.add_entity({x=0,y=0,z=0}, "fantasy_brawl:punch", pl_name)
minetest.sound_play({name = "punch"}, {pos = hit_pos, max_hear_distance = 6}, true)
elseif self.data.hits == 3 then
minetest.add_entity({x=0,y=0,z=0}, "fantasy_brawl:kick", pl_name)
minetest.sound_play({name = "kick"}, {pos = hit_pos, max_hear_distance = 6}, true)
elseif self.data.hits == 4 then
minetest.add_entity({x=0,y=0,z=0}, "fantasy_brawl:punch", pl_name)
minetest.sound_play({name = "punch"}, {pos = hit_pos, max_hear_distance = 6}, true)
elseif self.data.hits == 5 then
minetest.add_entity({x=0,y=0,z=0}, "fantasy_brawl:kick", pl_name)
minetest.sound_play({name = "kick"}, {pos = hit_pos, max_hear_distance = 6}, true)
fbrawl.hit_player(self.player, hit_player, self.damage)
self:stop()
end
fbrawl.hit_player(self.player, hit_player, self.damage)
end
})
local function entity_activate(lua_entity, pl_name)
local entity_duration = 0.32
local entity_speed = 9
local push_multiplier = 5
random_seed_counter = random_seed_counter + 1
local player = minetest.get_player_by_name(pl_name)
local obj = lua_entity.object
local rnd = PseudoRandom(os.time() * random_seed_counter)
local rnd_y = rnd:next(30, 50) / 100
local rnd_x = rnd:next(-10, 10) / 20
local rnd_z = rnd:next(-10, 10) / 20
local rnd_offset = {x = rnd_x, y = rnd_y, z = rnd_z}
local pos = vector.add(player:get_pos(), rnd_offset)
local player_center = vector.add(player:get_pos(), {x=0, y=1, z=0})
local dir_to_player = vector.direction(pos, player_center)
local push_force = vector.multiply(dir_to_player, push_multiplier)
obj:set_pos(pos)
obj:set_velocity(vector.multiply(dir_to_player, entity_speed))
player:add_velocity(push_force)
minetest.after(entity_duration, function() obj:remove() end)
end
-------------------
-- PUNCH ENTITY --
-------------------
local punch = {
initial_properties = {
physical = false,
visual_size = {x = 1, y = 1},
textures = {"fbrawl_punch_entity.png"},
pointable = false,
visual = "sprite",
},
}
function punch:on_activate(pl_name, dtime_s)
if pl_name ~= "" then
entity_activate(self, pl_name)
else
self.object:remove()
end
end
minetest.register_entity("fantasy_brawl:punch", punch)
-----------------
-- KICK ENTITY --
-----------------
local kick = {
initial_properties = {
physical = false,
visual_size = {x = 1, y = 1},
textures = {"fbrawl_kick_entity.png"},
pointable = false,
visual = "sprite",
speed = 5,
duration = 1
},
}
function kick:on_activate(pl_name, dtime_s)
self.pl_name = pl_name
if pl_name ~= "" then
entity_activate(self, pl_name)
else
self.object:remove()
end
end
minetest.register_entity("fantasy_brawl:kick", kick)

View File

@ -0,0 +1,196 @@
local T = fbrawl.T
skillz.register_skill("fbrawl:warrior_jump", {
name = "fbrawl:warrior_jump",
mana = 100,
slot = 2,
jump_force = 25,
cooldown = 0.5,
sounds = {
cast = {name = "wjump", max_hear_distance = 6}
},
chat_warnings = {
cooldown = false
},
cast = function(self)
local push_force = vector.multiply(self.player:get_look_dir(), self.jump_force)
push_force.y = self.jump_force
self.player:add_velocity(push_force)
minetest.add_particlespawner({
amount = 40,
time = 0.5,
minpos = vector.add(self.player:get_pos(), {x=0, y=0.5, z=0}),
maxpos = self.player:get_pos(),
minvel = {x = -4,y = 0, z = -4},
maxvel = {x = 4, y = 0, z = 4},
minsize = 8,
maxsize = 10,
texture = {
name = "fbrawl_smoke_particle.png",
alpha_tween = {1, 0}
},
minexptime = 0.5,
maxexptime = 0.5,
})
minetest.after(0.2, function() self.pl_name:start_skill("fbrawl:smash") end)
return true
end,
})
skillz.register_skill("fbrawl:smash", {
name = "fbrawl:smash",
description = T("Jump very high and then crush to the ground, damaging and slowing near players down."),
slot = 2,
damage = 4,
range = 6,
slow_down_factor = 0.5,
slow_down_time = 2,
sounds = {
bgm = {name="while_jumping", max_hear_distance = 6},
stop = {name="smash", max_hear_distance = 6}
},
data = {
hit_players = {}
},
loop_params = {
cast_rate = 0
},
attachments = {
particles = {{
amount = 35,
time = 0,
minpos = {x = -0.3, y = 0, z = -0.3},
maxpos = {x = 0.3, y = 0.5, z = 0.3},
minvel = {x = 0, y = 0, z = -1},
maxvel = {x = 0, y = 0, z = -2},
minsize = 4,
maxsize = 9,
texture = {
name = "fbrawl_wjump_particle.png",
alpha_tween = {1, 0}
},
minexptime = 1.5,
maxexptime = 1.5,
}},
},
on_start = function(self)
self.data.hit_players = {}
fbrawl.replace_slot_item(self.player, 2, "fantasy_brawl:smash")
self.data.fall_damage = false
end,
on_stop = function(self)
fbrawl.replace_slot_item(self.player, 2, "fantasy_brawl:warrior_jump")
minetest.after(self.slow_down_time, function()
if not self.is_active then
self.data.fall_damage = true
end
for i, player in ipairs(self.data.hit_players) do
local pl_speed = player:get_physics_override().speed
player:set_physics_override({speed = pl_speed + self.slow_down_factor})
end
end)
fbrawl.camera_shake(self.pl_name, 6, 0.4)
end,
cast = function(self)
if fbrawl.is_on_the_ground(self.player) then
for i, player in ipairs(minetest.get_connected_players()) do
local pl_name = player:get_player_name()
local pl_distance = vector.distance(player:get_pos(), self.player:get_pos())
local pl_vertical_distance = math.abs(self.player:get_pos().y - player:get_pos().y)
if
pl_distance <= self.range
and pl_vertical_distance < 2
and pl_name ~= self.pl_name
then
local pl_speed = player:get_physics_override().speed
-- Slow the hit player down
player:set_physics_override({speed = pl_speed - self.slow_down_factor})
table.insert(self.data.hit_players, player)
fbrawl.hit_player(self.player, player, self.damage)
end
end
minetest.add_entity(self.player:get_pos(), "fantasy_brawl:seismic_wave", self.pl_name)
self:stop()
end
end,
})
-------------------------
-- SEISMIC WAVE ENTITY --
-------------------------
local seismic_wave = {
initial_properties = {
hp_max = 999,
physical = false,
collisionbox = {-1, -1, -1, 1, 1.0, 1},
visual_size = {x = 1, y = 0.2},
textures = {
"fbrawl_wave_entity.png", "fbrawl_transparent.png",
"fbrawl_transparent.png", "fbrawl_transparent.png",
"fbrawl_transparent.png", "fbrawl_transparent.png"
},
initial_sprite_basepos = {x = 0, y = 0},
pointable = false,
visual = "cube",
},
dropped = false,
duration = 0.6,
speed = 11.3,
damage = 4,
counter = 0
}
function seismic_wave:on_activate(pl_name, dtime_s)
local obj = self.object
if pl_name then
minetest.after(self.duration, function() if obj then obj:remove() end end)
else
obj:remove()
end
end
function seismic_wave:on_step(dtime)
local increase_per_step = self.speed * dtime
local props = self.object:get_properties()
self.counter = self.counter + dtime
if self.counter > 0.3 then
local new_wave = minetest.add_entity(self.object:get_pos(), "fantasy_brawl:seismic_wave", self.pl_name)
new_wave:get_luaentity().counter = -10
self.counter = 0
end
props.visual_size = vector.add(props.visual_size, increase_per_step)
props.visual_size.y = 0.2
self.object:set_properties(props)
end
minetest.register_entity("fantasy_brawl:seismic_wave", seismic_wave)

View File

@ -0,0 +1,45 @@
fbrawl.register_class("warrior", {
name = "Warrior",
physics_override = {
speed = 1.5,
gravity = 0.9
},
items = {"fbrawl:sword_warrior", "fbrawl:warrior_jump"},
skills = {"fbrawl:smash"},
sound = "warrior-class"
})
dofile(minetest.get_modpath("fantasy_brawl") .. "/_classes/warrior/items.lua")
dofile(minetest.get_modpath("fantasy_brawl") .. "/_classes/warrior/skills/smash.lua")
dofile(minetest.get_modpath("fantasy_brawl") .. "/_classes/warrior/skills/iron_skin.lua")
dofile(minetest.get_modpath("fantasy_brawl") .. "/_classes/warrior/skills/perfect_combo.lua")
dofile(minetest.get_modpath("fantasy_brawl") .. "/_classes/warrior/skills/hero_fury.lua")
-- Preventing fall damage if smash or hero_fury is active
minetest.register_on_player_hpchange(function(player, hp_change, reason)
local pl_name = player:get_player_name()
local hero_fury = pl_name:get_skill("fbrawl:hero_fury")
local smash = pl_name:get_skill("fbrawl:smash")
-- Hero fury
if
reason.type == "fall"
and hero_fury
and hero_fury.is_active
then
return 0
end
-- Smash
if
reason.type == "fall"
and smash
and not smash.data.fall_damage
then
return 0
end
return hp_change
end, true)

306
chatcmdbuilder.lua Normal file
View File

@ -0,0 +1,306 @@
ChatCmdBuilder = {}
function ChatCmdBuilder.new(name, func, def)
def = def or {}
local cmd = ChatCmdBuilder.build(func)
cmd.def = def
def.func = cmd.run
minetest.register_chatcommand(name, def)
return cmd
end
local STATE_READY = 1
local STATE_PARAM = 2
local STATE_PARAM_TYPE = 3
local bad_chars = {}
bad_chars["("] = true
bad_chars[")"] = true
bad_chars["."] = true
bad_chars["%"] = true
bad_chars["+"] = true
bad_chars["-"] = true
bad_chars["*"] = true
bad_chars["?"] = true
bad_chars["["] = true
bad_chars["^"] = true
bad_chars["$"] = true
local function escape(char)
if bad_chars[char] then
return "%" .. char
else
return char
end
end
local dprint = function() end
ChatCmdBuilder.types = {
pos = "%(? *(%-?[%d.]+) *, *(%-?[%d.]+) *, *(%-?[%d.]+) *%)?",
text = "(.+)",
number = "(%-?[%d.]+)",
int = "(%-?[%d]+)",
word = "([^ ]+)",
alpha = "([A-Za-z]+)",
modname = "([a-z0-9_]+)",
alphascore = "([A-Za-z_]+)",
alphanumeric = "([A-Za-z0-9]+)",
username = "([A-Za-z0-9-_]+)",
}
function ChatCmdBuilder.build(func)
local cmd = {
_subs = {}
}
function cmd:sub(route, func, def)
dprint("Parsing " .. route)
def = def or {}
if string.trim then
route = string.trim(route)
end
local sub = {
pattern = "^",
params = {},
func = func
}
-- End of param reached: add it to the pattern
local param = ""
local param_type = ""
local should_be_eos = false
local function finishParam()
if param ~= "" and param_type ~= "" then
dprint(" - Found param " .. param .. " type " .. param_type)
local pattern = ChatCmdBuilder.types[param_type]
if not pattern then
error("Unrecognised param_type=" .. param_type)
end
sub.pattern = sub.pattern .. pattern
table.insert(sub.params, param_type)
param = ""
param_type = ""
end
end
-- Iterate through the route to find params
local state = STATE_READY
local catching_space = false
local match_space = " " -- change to "%s" to also catch tabs and newlines
local catch_space = match_space.."+"
for i = 1, #route do
local c = route:sub(i, i)
if should_be_eos then
error("Should be end of string. Nothing is allowed after a param of type text.")
end
if state == STATE_READY then
if c == ":" then
dprint(" - Found :, entering param")
state = STATE_PARAM
param_type = "word"
catching_space = false
elseif c:match(match_space) then
print(" - Found space")
if not catching_space then
catching_space = true
sub.pattern = sub.pattern .. catch_space
end
else
catching_space = false
sub.pattern = sub.pattern .. escape(c)
end
elseif state == STATE_PARAM then
if c == ":" then
dprint(" - Found :, entering param type")
state = STATE_PARAM_TYPE
param_type = ""
elseif c:match(match_space) then
print(" - Found whitespace, leaving param")
state = STATE_READY
finishParam()
catching_space = true
sub.pattern = sub.pattern .. catch_space
elseif c:match("%W") then
dprint(" - Found nonalphanum, leaving param")
state = STATE_READY
finishParam()
sub.pattern = sub.pattern .. escape(c)
else
param = param .. c
end
elseif state == STATE_PARAM_TYPE then
if c:match(match_space) then
print(" - Found space, leaving param type")
state = STATE_READY
finishParam()
catching_space = true
sub.pattern = sub.pattern .. catch_space
elseif c:match("%W") then
dprint(" - Found nonalphanum, leaving param type")
state = STATE_READY
finishParam()
sub.pattern = sub.pattern .. escape(c)
else
param_type = param_type .. c
end
end
end
dprint(" - End of route")
finishParam()
sub.pattern = sub.pattern .. "$"
dprint("Pattern: " .. sub.pattern)
table.insert(self._subs, sub)
end
if func then
func(cmd)
end
cmd.run = function(name, param)
for i = 1, #cmd._subs do
local sub = cmd._subs[i]
local res = { string.match(param, sub.pattern) }
if #res > 0 then
local pointer = 1
local params = { name }
for j = 1, #sub.params do
local param = sub.params[j]
if param == "pos" then
local pos = {
x = tonumber(res[pointer]),
y = tonumber(res[pointer + 1]),
z = tonumber(res[pointer + 2])
}
table.insert(params, pos)
pointer = pointer + 3
elseif param == "number" or param == "int" then
table.insert(params, tonumber(res[pointer]))
pointer = pointer + 1
else
table.insert(params, res[pointer])
pointer = pointer + 1
end
end
if table.unpack then
-- lua 5.2 or later
return sub.func(table.unpack(params))
else
-- lua 5.1 or earlier
return sub.func(unpack(params))
end
end
end
return false, "Invalid command"
end
return cmd
end
local function run_tests()
if not (ChatCmdBuilder.build(function(cmd)
cmd:sub("bar :one and :two:word", function(name, one, two)
if name == "singleplayer" and one == "abc" and two == "def" then
return true
end
end)
end)).run("singleplayer", "bar abc and def") then
error("Test 1 failed")
end
local move = ChatCmdBuilder.build(function(cmd)
cmd:sub("move :target to :pos:pos", function(name, target, pos)
if name == "singleplayer" and target == "player1" and
pos.x == 0 and pos.y == 1 and pos.z == 2 then
return true
end
end)
end).run
if not move("singleplayer", "move player1 to 0,1,2") then
error("Test 2 failed")
end
if not move("singleplayer", "move player1 to (0,1,2)") then
error("Test 3 failed")
end
if not move("singleplayer", "move player1 to 0, 1,2") then
error("Test 4 failed")
end
if not move("singleplayer", "move player1 to 0 ,1, 2") then
error("Test 5 failed")
end
if not move("singleplayer", "move player1 to 0, 1, 2") then
error("Test 6 failed")
end
if not move("singleplayer", "move player1 to 0 ,1 ,2") then
error("Test 7 failed")
end
if not move("singleplayer", "move player1 to ( 0 ,1 ,2)") then
error("Test 8 failed")
end
if move("singleplayer", "move player1 to abc,def,sdosd") then
error("Test 9 failed")
end
if move("singleplayer", "move player1 to abc def sdosd") then
error("Test 10 failed")
end
if not (ChatCmdBuilder.build(function(cmd)
cmd:sub("does :one:int plus :two:int equal :three:int", function(name, one, two, three)
if name == "singleplayer" and one + two == three then
return true
end
end)
end)).run("singleplayer", "does 1 plus 2 equal 3") then
error("Test 11 failed")
end
local checknegint = ChatCmdBuilder.build(function(cmd)
cmd:sub("checknegint :x:int", function(name, x)
return x
end)
end).run
if checknegint("checker","checknegint -2") ~= -2 then
error("Test 12 failed")
end
local checknegnumber = ChatCmdBuilder.build(function(cmd)
cmd:sub("checknegnumber :x:number", function(name, x)
return x
end)
end).run
if checknegnumber("checker","checknegnumber -3.3") ~= -3.3 then
error("Test 13 failed")
end
local checknegpos = ChatCmdBuilder.build(function(cmd)
cmd:sub("checknegpos :pos:pos", function(name, pos)
return pos
end)
end).run
local negpos = checknegpos("checker","checknegpos (-13.3,-4.6,-1234.5)")
if negpos.x ~= -13.3 or negpos.y ~= -4.6 or negpos.z ~= -1234.5 then
error("Test 14 failed")
end
local checktypes = ChatCmdBuilder.build(function(cmd)
cmd:sub("checktypes :int:int :number:number :pos:pos :word:word :text:text", function(name, int, number, pos, word, text)
return int, number, pos.x, pos.y, pos.z, word, text
end)
end).run
local int, number, posx, posy, posz, word, text
int, number, posx, posy, posz, word, text = checktypes("checker","checktypes -1 -2.4 (-3,-5.3,6.12) some text to finish off with")
--dprint(int, number, posx, posy, posz, word, text)
if int ~= -1 or number ~= -2.4 or posx ~= -3 or posy ~= -5.3 or posz ~= 6.12 or word ~= "some" or text ~= "text to finish off with" then
error("Test 15 failed")
end
dprint("All tests passed")
end
if not minetest then
run_tests()
end

18
commands.lua Normal file
View File

@ -0,0 +1,18 @@
ChatCmdBuilder.new("fbrawl", function(cmd)
cmd:sub("list", function(name)
minetest.chat_send_player(name, "\nSkillz > Skills list")
for mod, def in pairs(skillz.get_registered_skills()) do
local skill_name = def.name
local skill_desc = def.description
minetest.chat_send_player(name, skill_name:upper() .. " \n" .. skill_desc .. "\n\n")
end
end)
end, {
description = [[
- list: lists every registered skill
]]
})

114
hud.lua Normal file
View File

@ -0,0 +1,114 @@
local saved_huds = {} -- pl_name = {hud name = id}
local T = fbrawl.T
function fbrawl.generate_HUD(arena, pl_name)
local player = minetest.get_player_by_name(pl_name)
local pl_class = arena.classes[pl_name]
local background
local timer
local class = T(pl_class.internal_name)
local vignette
-- Sets the class background image.
background = player:hud_add({
hud_elem_type = "image",
position = {x = 1, y = 0},
offset = {x = -179, y = 32},
text = pl_class.HUD_timer or "HUD_fbrawl_timer.png",
alignment = { x = 1.0},
scale = { x = 1.15, y = 1.15},
number = 0xFFFFFF,
z_index = 100
})
-- Sets the timer text.
timer = player:hud_add({
hud_elem_type = "text",
position = {x = 1, y = 0},
offset = {x = -51, y = 32},
text = arena.initial_time,
alignment = { x = 1.0},
scale = { x = 2, y = 2},
number = 0xFFFFFF,
z_index = 100,
})
-- Sets the class text.
class = player:hud_add({
hud_elem_type = "text",
position = {x = 1, y = 0},
offset = {x = -136, y = 32},
text = class,
alignment = { x = 0},
scale = { x = 100, y = 10},
number = 0xFFFFFF,
z_index = 100
})
vignette = player:hud_add({
hud_elem_type = "image",
position = {x = 0.5, y = 0.5},
scale = {
x = -100,
y = -100
},
text = pl_class.vignette or "HUD_fbrawl_vignette.png",
z_index = 99
})
-- Save the huds IDs for each player.
saved_huds[pl_name] = {
class_ID = class,
backgound_ID = background,
timer_ID = timer,
vignette_ID = vignette
}
end
function fbrawl.update_HUD(pl_name, field, new_value)
if saved_huds[pl_name] and saved_huds[pl_name][field] then
local player = minetest.get_player_by_name(pl_name)
player:hud_change(saved_huds[pl_name][field], "text", new_value)
end
end
function fbrawl.remove_HUD(pl_name)
minetest.after(1, function()
local player = minetest.get_player_by_name(pl_name)
if not player or not saved_huds[pl_name] then return end
for name, id in pairs(saved_huds[pl_name]) do
player:hud_remove(id)
end
saved_huds[pl_name] = {}
end)
end
function fbrawl.add_temp_hud(pl_name, hud, time)
local player = minetest.get_player_by_name(pl_name)
hud = player:hud_add(hud)
saved_huds[pl_name] = saved_huds[pl_name] or {}
saved_huds[pl_name][tostring(hud)] = hud
-- Removing the hud after "time" seconds if the player still has it.
minetest.after(time, function()
if saved_huds[pl_name] and saved_huds[pl_name][tostring(hud)] then
player:hud_remove(hud)
saved_huds[pl_name][tostring(hud)] = nil
end
end)
return hud
end

48
init.lua Normal file
View File

@ -0,0 +1,48 @@
fbrawl = {}
fbrawl.T = minetest.get_translator("fantasy_brawl")
dofile(minetest.get_modpath("fantasy_brawl") .. "/SETTINGS.lua")
dofile(minetest.get_modpath("fantasy_brawl") .. "/chatcmdbuilder.lua")
dofile(minetest.get_modpath("fantasy_brawl") .. "/utils.lua")
dofile(minetest.get_modpath("fantasy_brawl") .. "/_classes/classes_system.lua")
dofile(minetest.get_modpath("fantasy_brawl") .. "/_classes/mana.lua")
dofile(minetest.get_modpath("fantasy_brawl") .. "/_classes/warrior/warrior.lua")
dofile(minetest.get_modpath("fantasy_brawl") .. "/_classes/mage/mage.lua")
dofile(minetest.get_modpath("fantasy_brawl") .. "/commands.lua")
arena_lib.register_minigame("murder", {
prefix = fbrawl_settings.prefix,
temp_properties = {
classes = {}, -- pl_name : string = class : {}
match_id = 0,
},
player_properties = {
class = ""
},
load_time = fbrawl_settings.max_loading_time,
show_nametags = false,
show_minimap = false,
celebration_time = fbrawl_settings.celebration_time,
disabled_damage_types = {"fall"},
time_mode = "decremental"
})
minetest.register_allow_player_inventory_action(function(player, action, inventory, inventory_info)
local pl_name = player:get_player_name()
if arena_lib.is_player_in_arena(pl_name, "fantasy_brawl") then
return 0
end
end)
minetest.register_on_joinplayer(function(p, last_login)
end)
skillz.register_on_unlock("fbrawl", function(def) minetest.log("+ " .. def.name .. " to " .. def.pl_name) end)

4
mod.conf Normal file
View File

@ -0,0 +1,4 @@
name = fantasy_brawl
depends = skillz, arena_lib
description = To write.
author = giov4

Binary file not shown.

BIN
sounds/fbrawl_error.ogg Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
sounds/iron_skin_off.ogg Normal file

Binary file not shown.

BIN
sounds/iron_skin_on.ogg Normal file

Binary file not shown.

BIN
sounds/kick.ogg Normal file

Binary file not shown.

BIN
sounds/punch.ogg Normal file

Binary file not shown.

BIN
sounds/smash.ogg Normal file

Binary file not shown.

BIN
sounds/while_jumping.ogg Normal file

Binary file not shown.

BIN
sounds/wjump.ogg Normal file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 219 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 368 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 487 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 350 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 190 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 411 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 174 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 317 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 198 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 509 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 178 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 263 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 173 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 B

166
utils.lua Normal file
View File

@ -0,0 +1,166 @@
local function random_2dvectors() end
local last_pls_y_velocity = {} -- pl_name = y_velocity
local get_node = minetest.get_node
local get_pl_by_name = minetest.get_player_by_name
function fbrawl.replace_slot_item(player, slot, item)
local inv = player:get_inventory()
local list = inv:get_list("main")
list[slot] = ItemStack(item)
inv:set_list("main", list)
end
function fbrawl.hit_player(puncher, player, damage)
player:set_hp(player:get_hp() - damage, {
type = "punch",
object = puncher,
from = "mod"
})
end
function fbrawl.is_on_the_ground(player)
local pl_name = player:get_player_name()
local under_pl_feet = player:get_pos()
local pl_velocity = player:get_velocity()
local last_y_velocity = last_pls_y_velocity[pl_name] or pl_velocity.y
under_pl_feet.y = under_pl_feet.y - 0.4
local is_on_the_ground =
not (get_node(under_pl_feet).name == "air")
or (pl_velocity.y == 0 and last_y_velocity < 0)
last_pls_y_velocity[pl_name] = pl_velocity.y
return is_on_the_ground
end
function fbrawl.area_raycast_up(center, radius, range, objects, liquids)
local ray_distance = 0.5
if type(radius) == "number" then
radius_x = radius
radius_z = radius
else
radius_x = radius.x
radius_z = radius.z
end
local start_pos = {x = center.x - radius_x, y = center.y + 0.5, z = center.z - radius_z}
local final_pos = {x = center.x + radius_x, y = center.y + 0.5, z = center.z + radius_z}
for x = start_pos.x, final_pos.x, ray_distance do
for z = start_pos.z, final_pos.z, ray_distance do
local pos1 = {x = x, y = start_pos.y, z = z}
local pos2 = vector.add(pos1, {x = 0, y = range, z = 0})
local result = minetest.raycast(pos1, pos2, objects, liquids):next()
if result then
return result
end
end
end
return false
end
-- TODO: improve
function fbrawl.camera_shake(pl_name, duration, strength, offsets, next_offset, eye_offset, last)
local player = get_pl_by_name(pl_name)
local speed = 0.4
local last = last or false
offsets = offsets or random_2dvectors(duration, strength)
next_offset = next_offset or 1
if not player then
return
end
-- When offsets finish go back to zero
if next_offset > #offsets then
offsets[next_offset] = {x = 0, y = 0}
last = true
end
eye_offset = eye_offset or player:get_eye_offset()
local target_offset = offsets[next_offset]
local new_offset = {
x = fbrawl.interpolate(eye_offset.x, target_offset.x, speed),
y = fbrawl.interpolate(eye_offset.y, target_offset.y, speed),
z = 0
}
eye_offset = new_offset
-- If new_offset and eye_offset are equal go to the next offset or return if it was
-- the last offset
if target_offset.x == eye_offset.x and target_offset.y == eye_offset.y then
if last then
return
end
next_offset = next_offset + 1
else
player:set_eye_offset(new_offset, new_offset)
end
minetest.after(0, function()
fbrawl.camera_shake(pl_name, duration, strength, offsets, next_offset, eye_offset, last)
end)
end
function fbrawl.reset_velocity(player)
player:add_velocity(vector.multiply(player:get_velocity(), -1))
end
function fbrawl.interpolate(a, b, factor)
local distance = math.abs(a-b)
local min_step = 0.1
local step = distance * factor
if step < min_step then step = min_step end
if a > b then
a = a - step
if a <= b then
a = b
end
else
a = a + step
if a >= b then
a = b
end
end
return a
end
function random_2dvectors(amount, strength)
local rnd = PcgRandom(os.time())
local vectors = {}
for i = 1, amount, 1 do
local rnd_vector = {
x = rnd:next(-1, 1) * strength,
y = rnd:next(-1, 1) * strength,
}
table.insert(vectors, rnd_vector)
end
return vectors
end