176 lines
4.1 KiB
Lua
176 lines
4.1 KiB
Lua
--[[
|
|
Mobs Monster EXP System
|
|
Copyright (C) 2021 Noodlemire
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Lesser General Public
|
|
License as published by the Free Software Foundation; either
|
|
version 2.1 of the License, or (at your option) any later version.
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Lesser General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public
|
|
License along with this library; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
--]]
|
|
|
|
mobs_exp = {}
|
|
|
|
local data = minetest.get_mod_storage()
|
|
|
|
|
|
|
|
minetest.register_on_dieplayer(function(player)
|
|
local pname = player:get_player_name()
|
|
local loss = math.floor(data:get_int(pname) * 0.2)
|
|
local prev_lvl = mobs_exp.exp_to_level(data:get_int(pname))
|
|
local next_lvl = mobs_exp.exp_to_level(data:get_int(pname) - loss)
|
|
|
|
data:set_int(pname, data:get_int(pname) - loss)
|
|
|
|
minetest.chat_send_player(pname, "Upon death, you lost "..loss.." EXP!")
|
|
|
|
if next_lvl < prev_lvl then
|
|
minetest.chat_send_player(pname, "Level down! You are now Tier: "..mobs_exp.roman(next_lvl))
|
|
end
|
|
end)
|
|
|
|
|
|
|
|
function mobs_exp.exp_to_level(e)
|
|
return 1 + math.floor((math.sqrt(.4 * e + 1) - 1) / 2)
|
|
end
|
|
|
|
function mobs_exp.level_to_exp(l)
|
|
return 10 * l * (l + 1)
|
|
end
|
|
|
|
function mobs_exp.exp_per_level(l)
|
|
return 20 * l
|
|
end
|
|
|
|
function mobs_exp.roman(n)
|
|
local r = ""
|
|
|
|
while n >= 100 do
|
|
r = r.."C"
|
|
n = n - 100
|
|
end
|
|
if n >= 90 then
|
|
r = r.."XC"
|
|
n = n - 90
|
|
end
|
|
if n >= 50 then
|
|
r = r.."L"
|
|
n = n - 50
|
|
end
|
|
if n >= 40 then
|
|
r = r.."XL"
|
|
n = n - 40
|
|
end
|
|
while n >= 10 do
|
|
r = r.."X"
|
|
n = n - 10
|
|
end
|
|
if n >= 9 then
|
|
r = r.."IX"
|
|
n = n - 9
|
|
end
|
|
if n >= 5 then
|
|
r = r.."V"
|
|
n = n - 5
|
|
end
|
|
if n >= 4 then
|
|
r = r.."IV"
|
|
n = n - 4
|
|
end
|
|
while n >= 1 do
|
|
r = r.."I"
|
|
n = n - 1
|
|
end
|
|
|
|
return r
|
|
end
|
|
|
|
|
|
|
|
minetest.register_entity("mobs_exp:orb", {
|
|
initial_properties = {
|
|
physical = true,
|
|
collide_with_objects = false,
|
|
collisionbox = {-0.125, -0.125, -0.125, 0.125, 0.125, 0.125},
|
|
pointable = false,
|
|
visual = "sprite",
|
|
visual_size = {x = 0.125, y = 0.125},
|
|
textures = {"mobs_exp_orb.png"},
|
|
glow = -1,
|
|
static_save = false,
|
|
},
|
|
|
|
on_step = function(self)
|
|
local objs = minetest.get_objects_inside_radius(self.object:get_pos(), 1.5)
|
|
local players = {}
|
|
|
|
for _, obj in ipairs(objs) do
|
|
if obj:is_player() and obj:get_hp() > 0 then
|
|
table.insert(players, obj:get_player_name())
|
|
end
|
|
end
|
|
|
|
if #players > 0 then
|
|
local exp = self.exp or 0
|
|
local player = players[math.random(#players)]
|
|
local prev_lvl = mobs_exp.exp_to_level(data:get_int(player))
|
|
local next_lvl = mobs_exp.exp_to_level(data:get_int(player) + exp)
|
|
|
|
data:set_int(player, data:get_int(player) + exp)
|
|
|
|
minetest.chat_send_player(player, "You gained "..exp.." EXP!")
|
|
|
|
if next_lvl > prev_lvl then
|
|
minetest.chat_send_player(player, "Level up! You are now Tier: "..mobs_exp.roman(next_lvl))
|
|
end
|
|
|
|
self.object:remove()
|
|
end
|
|
end,
|
|
})
|
|
|
|
|
|
|
|
minetest.register_on_punchplayer(function(player, hitter, time_from_last_punch, tool_capabilities, dir, damage)
|
|
if hitter:is_player() and player:get_hp() > 0 and player:get_hp() - damage <= 0 then
|
|
local exp = mobs_exp.exp_to_level(data:get_int(player:get_player_name())) * 5
|
|
local p = player:get_pos()
|
|
local ref = minetest.add_entity({x=p.x, y=p.y+1, z=p.z}, "mobs_exp:orb")
|
|
|
|
if ref then
|
|
ref:get_luaentity().exp = exp
|
|
end
|
|
end
|
|
end)
|
|
|
|
minetest.register_on_mods_loaded(function()
|
|
for name, def in pairs(minetest.registered_entities) do
|
|
if def.mod_origin == "mobs_monster" then
|
|
local old_on_die = def.on_die
|
|
|
|
rawset(def, "on_die", function(self, pos)
|
|
local ref = minetest.add_entity(pos, "mobs_exp:orb")
|
|
|
|
if ref then
|
|
local armor = self.armor > 0 and self.armor or 1
|
|
ref:get_luaentity().exp = math.ceil(((self.hp_min + self.hp_max) / 2 + self.damage) * (100 / self.armor))
|
|
end
|
|
|
|
if old_on_die then
|
|
old_on_die(self, pos)
|
|
end
|
|
end)
|
|
end
|
|
end
|
|
end)
|