Add XP (#141)
This commit is contained in:
parent
6e6f141b44
commit
5b5ed93bc3
|
@ -174,7 +174,7 @@ local function add_text(player)
|
|||
hud[player_name] = player:hud_add({
|
||||
hud_elem_type = "text",
|
||||
position = {x = 0.5, y = 0.975},
|
||||
offset = {x = 0, y = -75},
|
||||
offset = {x = 0, y = -100},
|
||||
alignment = {x = 0, y = 0},
|
||||
number = 0xFFFFFF,
|
||||
text = "",
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
default
|
|
@ -0,0 +1,212 @@
|
|||
experience = {}
|
||||
|
||||
local modname = minetest.get_current_modname()
|
||||
local modpath = minetest.get_modpath(modname)
|
||||
|
||||
dofile(modpath .. "/override.lua")
|
||||
|
||||
local MAX_HUD_XP = 44
|
||||
local MAX_LEVEL = 40
|
||||
local ORB_SOUND_INTERVAL = 0.01
|
||||
local ORB_COLLECT_RADIUS = 3
|
||||
|
||||
local xp, hud = {}, {}
|
||||
|
||||
local get_objs_rad = minetest.get_objects_inside_radius
|
||||
local get_players = minetest.get_connected_players
|
||||
|
||||
local vec_new, vec_dist, vec_mul, vec_sub =
|
||||
vector.new, vector.distance, vector.multiply, vector.subtract
|
||||
|
||||
local function init_data(player, reset)
|
||||
local name = player:get_player_name()
|
||||
local _xp = minetest.deserialize(player:get_attribute("xp"))
|
||||
|
||||
if not _xp or reset then
|
||||
xp[name] = {
|
||||
xp_bar = 0,
|
||||
xp_total = 0,
|
||||
xp_number = 0,
|
||||
level = 0,
|
||||
}
|
||||
else
|
||||
xp[name] = _xp
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_on_joinplayer(function(player)
|
||||
local name = player:get_player_name()
|
||||
init_data(player)
|
||||
|
||||
hud[name] = {
|
||||
-- background (empty bar)
|
||||
hud = player:hud_add({
|
||||
hud_elem_type = "statbar",
|
||||
position = {x = 0.5, y = 0.97},
|
||||
offset = {x = -252, y = -48},
|
||||
scale = {x = 1, y = 1},
|
||||
alignment = {x = -1, y = -1},
|
||||
text = "expbar_empty.png",
|
||||
number = MAX_HUD_XP,
|
||||
}),
|
||||
|
||||
-- foreground (filling bar)
|
||||
hud2 = player:hud_add({
|
||||
hud_elem_type = "statbar",
|
||||
position = {x = 0.5, y = 0.97},
|
||||
offset = {x = -252, y = -48},
|
||||
scale = {x = 1, y = 1},
|
||||
alignment = {x = -1, y = -1},
|
||||
text = "expbar_full.png",
|
||||
}),
|
||||
|
||||
-- level number
|
||||
hud3 = player:hud_add({
|
||||
hud_elem_type = "text",
|
||||
texture = ("xp_blank"),
|
||||
position = {x = 0.5, y = 0.97},
|
||||
offset = {x = 6, y = -42},
|
||||
alignment = {x = -1, y = -1},
|
||||
number = 0x3cff00,
|
||||
text = "",
|
||||
})
|
||||
}
|
||||
end)
|
||||
|
||||
function experience.add_orb(amount, pos)
|
||||
if amount == 0 then return end
|
||||
for _ = 1, amount do
|
||||
local area = vec_new(
|
||||
pos.x + math.random(0,5) / 5 - 0.5,
|
||||
pos.y,
|
||||
pos.z + math.random(0,5) / 5 - 0.5)
|
||||
|
||||
minetest.add_entity(area, "experience:orb")
|
||||
end
|
||||
end
|
||||
|
||||
function experience.get_level(name)
|
||||
return xp[name].level
|
||||
end
|
||||
|
||||
minetest.register_on_dignode(function(pos, oldnode, digger)
|
||||
local name = oldnode.name
|
||||
local xp_min = minetest.get_item_group(name, "xp_min")
|
||||
local xp_max = minetest.get_item_group(name, "xp_max")
|
||||
|
||||
if xp_min and xp_max and xp_max > 0 then
|
||||
experience.add_orb(math.random(xp_min, xp_max), pos)
|
||||
end
|
||||
end)
|
||||
|
||||
minetest.register_on_newplayer(function(player)
|
||||
init_data(player)
|
||||
end)
|
||||
|
||||
minetest.register_on_dieplayer(function(player)
|
||||
init_data(player, true)
|
||||
end)
|
||||
|
||||
minetest.register_globalstep(function(dtime)
|
||||
local players = get_players()
|
||||
for i = 1, #players do
|
||||
local player = players[i]
|
||||
local name = player:get_player_name()
|
||||
local pos = player:get_pos()
|
||||
pos.y = pos.y + 0.5
|
||||
|
||||
xp[name].timer = (xp[name].timer or 0) + dtime
|
||||
|
||||
for _, obj in ipairs(get_objs_rad(pos, ORB_COLLECT_RADIUS)) do
|
||||
local ent = obj:get_luaentity()
|
||||
if not obj:is_player() and ent and ent.name == "experience:orb" then
|
||||
local orb_pos = obj:get_pos()
|
||||
|
||||
if vec_dist(pos, orb_pos) <= 1 then
|
||||
if xp[name].timer >= ((xp[name].last_sound or 0) + ORB_SOUND_INTERVAL) then
|
||||
minetest.sound_play("orb", {to_player = name})
|
||||
xp[name].last_sound = xp[name].timer
|
||||
end
|
||||
|
||||
local inc = 2 * xp[name].level + 7
|
||||
|
||||
if xp[name].level >= 16 then
|
||||
inc = 5 * xp[name].level - 38
|
||||
elseif xp[name].level >= 31 then
|
||||
inc = 9 * xp[name].level - 158
|
||||
end
|
||||
|
||||
xp[name].xp_bar = xp[name].xp_bar + (MAX_HUD_XP / inc)
|
||||
obj:remove()
|
||||
else
|
||||
pos.y = pos.y + 0.2
|
||||
local vec = vec_mul(vec_sub(pos, orb_pos), 3)
|
||||
obj:set_velocity(vec)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if xp[name].xp_bar >= MAX_HUD_XP then
|
||||
if xp[name].level < MAX_LEVEL then
|
||||
xp[name].level = xp[name].level + 1
|
||||
xp[name].xp_bar = xp[name].xp_bar - MAX_HUD_XP
|
||||
else
|
||||
xp[name].xp_bar = MAX_HUD_XP
|
||||
end
|
||||
end
|
||||
|
||||
player:hud_change(hud[name].hud2, "number", xp[name].xp_bar)
|
||||
player:hud_change(hud[name].hud3, "text", xp[name].level)
|
||||
|
||||
player:hud_change(hud[name].hud3, "offset",
|
||||
{x = (xp[name].level >= 10 and 13 or 6), y = -42})
|
||||
end
|
||||
end)
|
||||
|
||||
minetest.register_entity("experience:orb", {
|
||||
timer = 0,
|
||||
glow = 12,
|
||||
physical = true,
|
||||
textures = {"orb.png"},
|
||||
visual_size = {x = 0.15, y = 0.15},
|
||||
collisionbox = {-0.1, -0.1, -0.1, 0.1, 0.1, 0.1},
|
||||
collide_with_objects = false,
|
||||
|
||||
on_activate = function(self, staticdata)
|
||||
local obj = self.object
|
||||
obj:set_armor_groups({immortal = 1})
|
||||
obj:set_velocity(vec_new(0, 1, 0))
|
||||
obj:set_acceleration(vec_new(0, -9.81, 0))
|
||||
end,
|
||||
|
||||
on_step = function(self, dtime)
|
||||
local obj = self.object
|
||||
self.timer = self.timer + dtime
|
||||
self.last_color_change = self.last_color_change or 0
|
||||
self.color_ratio = self.color_ratio or 0
|
||||
|
||||
if self.timer > 300 then
|
||||
obj:remove()
|
||||
elseif self.timer >= self.last_color_change + 0.001 then
|
||||
if self.color_ratio >= 120 then
|
||||
self.color_back = true
|
||||
elseif self.color_ratio <= 0 then
|
||||
self.color_back = nil
|
||||
end
|
||||
|
||||
self.color_ratio = self.color_ratio + (self.color_back and -10 or 10)
|
||||
obj:set_texture_mod("^[colorize:#e5ff02:" .. self.color_ratio)
|
||||
self.last_color_change = self.timer
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_on_shutdown(function()
|
||||
local players = get_players()
|
||||
for i = 1, #players do
|
||||
local player = players[i]
|
||||
local name = player:get_player_name()
|
||||
|
||||
player:set_attribute("xp", minetest.serialize(xp[name]))
|
||||
end
|
||||
end)
|
|
@ -0,0 +1,7 @@
|
|||
minetest.override_item("default:stone_with_coal", {
|
||||
groups = {cracky = 3, xp_min = 0, xp_max = 2},
|
||||
})
|
||||
|
||||
minetest.override_item("default:wood", {
|
||||
groups = {dig_immediate = 3, xp_min = 4, xp_max = 6},
|
||||
})
|
|
@ -0,0 +1 @@
|
|||
http://www.freesound.org/people/partymix/sounds/24102/
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
After Width: | Height: | Size: 1.6 KiB |
Binary file not shown.
After Width: | Height: | Size: 1.7 KiB |
Binary file not shown.
After Width: | Height: | Size: 205 B |
Binary file not shown.
After Width: | Height: | Size: 268 B |
|
@ -1,12 +1,12 @@
|
|||
HUD_SB_SIZE = {x = 24, y = 24}
|
||||
HUD_HEALTH_POS = {x = 0.5, y = 1}
|
||||
HUD_HEALTH_OFFSET = {x = -248, y = -93}
|
||||
HUD_AIR_POS = {x = 0.5, y = 1}
|
||||
HUD_AIR_OFFSET = {x = 6, y = -124}
|
||||
HUD_HUNGER_POS = {x = 0.5, y = 1}
|
||||
HUD_HUNGER_OFFSET = {x = 6, y = -93}
|
||||
HUD_ARMOR_POS = {x = 0.5, y = 1}
|
||||
HUD_ARMOR_OFFSET = {x = -248, y = -124}
|
||||
HUD_SB_SIZE = {x = 24, y = 24}
|
||||
HUD_HEALTH_POS = {x = 0.5, y = 1}
|
||||
HUD_HEALTH_OFFSET = {x = -248, y = -110}
|
||||
HUD_AIR_POS = {x = 0.5, y = 1}
|
||||
HUD_AIR_OFFSET = {x = 6, y = -124}
|
||||
HUD_HUNGER_POS = {x = 0.5, y = 1}
|
||||
HUD_HUNGER_OFFSET = {x = 6, y = -110}
|
||||
HUD_ARMOR_POS = {x = 0.5, y = 1}
|
||||
HUD_ARMOR_OFFSET = {x = -248, y = -124}
|
||||
|
||||
-- read hud.conf settings
|
||||
function hud.read_conf()
|
||||
|
|
|
@ -26,11 +26,18 @@ mobs:register_mob("mobs_animal:pig", {
|
|||
jump = true,
|
||||
follow = {"default:apple", "farming:potato"},
|
||||
view_range = 5,
|
||||
drops = {
|
||||
{name = "mobs:pork_raw", chance = 1, min = 1, max = 1},
|
||||
{name = "mobs:pork_raw", chance = 2, min = 1, max = 1},
|
||||
{name = "mobs:pork_raw", chance = 2, min = 1, max = 1}
|
||||
},
|
||||
drops = function(pos)
|
||||
if rawget(_G, "experience") then
|
||||
--experience.add_orb(math.random(1,3), pos) -- random amount between 1 and 3
|
||||
experience.add_orb(3, pos)
|
||||
end
|
||||
|
||||
return {
|
||||
{name = "mobs:pork_raw", chance = 1, min = 1, max = 1},
|
||||
{name = "mobs:pork_raw", chance = 2, min = 1, max = 1},
|
||||
{name = "mobs:pork_raw", chance = 2, min = 1, max = 1}
|
||||
}
|
||||
end,
|
||||
water_damage = 0,
|
||||
lava_damage = 5,
|
||||
light_damage = 0,
|
||||
|
|
|
@ -665,6 +665,8 @@ end
|
|||
|
||||
-- drop items
|
||||
function mob_class:item_drop()
|
||||
local pos = self.object:get_pos()
|
||||
self.drops = type(self.drops) == "function" and self.drops(pos) or self.drops
|
||||
|
||||
-- check for nil or no drops
|
||||
if not self.drops or #self.drops == 0 then
|
||||
|
@ -682,7 +684,6 @@ function mob_class:item_drop()
|
|||
and self.cause_of_death.puncher:is_player() or nil
|
||||
|
||||
local obj, item, num
|
||||
local pos = self.object:get_pos()
|
||||
|
||||
for n = 1, #self.drops do
|
||||
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
default
|
||||
default
|
||||
experience?
|
||||
|
|
Loading…
Reference in New Issue