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[player_name] = player:hud_add({
|
||||||
hud_elem_type = "text",
|
hud_elem_type = "text",
|
||||||
position = {x = 0.5, y = 0.975},
|
position = {x = 0.5, y = 0.975},
|
||||||
offset = {x = 0, y = -75},
|
offset = {x = 0, y = -100},
|
||||||
alignment = {x = 0, y = 0},
|
alignment = {x = 0, y = 0},
|
||||||
number = 0xFFFFFF,
|
number = 0xFFFFFF,
|
||||||
text = "",
|
text = "",
|
||||||
|
1
games/default/files/experience/depends.txt
Normal file
1
games/default/files/experience/depends.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
default
|
212
games/default/files/experience/init.lua
Normal file
212
games/default/files/experience/init.lua
Normal file
@ -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)
|
7
games/default/files/experience/override.lua
Normal file
7
games/default/files/experience/override.lua
Normal file
@ -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},
|
||||||
|
})
|
1
games/default/files/experience/sounds/attributes.txt
Normal file
1
games/default/files/experience/sounds/attributes.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
http://www.freesound.org/people/partymix/sounds/24102/
|
BIN
games/default/files/experience/sounds/level_up.ogg
Normal file
BIN
games/default/files/experience/sounds/level_up.ogg
Normal file
Binary file not shown.
BIN
games/default/files/experience/sounds/orb.1.ogg
Normal file
BIN
games/default/files/experience/sounds/orb.1.ogg
Normal file
Binary file not shown.
BIN
games/default/files/experience/sounds/orb.2.ogg
Normal file
BIN
games/default/files/experience/sounds/orb.2.ogg
Normal file
Binary file not shown.
BIN
games/default/files/experience/sounds/orb.3.ogg
Normal file
BIN
games/default/files/experience/sounds/orb.3.ogg
Normal file
Binary file not shown.
BIN
games/default/files/experience/sounds/orb.4.ogg
Normal file
BIN
games/default/files/experience/sounds/orb.4.ogg
Normal file
Binary file not shown.
BIN
games/default/files/experience/textures/expbar_empty.png
Normal file
BIN
games/default/files/experience/textures/expbar_empty.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.6 KiB |
BIN
games/default/files/experience/textures/expbar_full.png
Normal file
BIN
games/default/files/experience/textures/expbar_full.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.7 KiB |
BIN
games/default/files/experience/textures/orb.png
Normal file
BIN
games/default/files/experience/textures/orb.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 205 B |
BIN
games/default/files/experience/textures/xp_empty.png
Normal file
BIN
games/default/files/experience/textures/xp_empty.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 268 B |
@ -1,10 +1,10 @@
|
|||||||
HUD_SB_SIZE = {x = 24, y = 24}
|
HUD_SB_SIZE = {x = 24, y = 24}
|
||||||
HUD_HEALTH_POS = {x = 0.5, y = 1}
|
HUD_HEALTH_POS = {x = 0.5, y = 1}
|
||||||
HUD_HEALTH_OFFSET = {x = -248, y = -93}
|
HUD_HEALTH_OFFSET = {x = -248, y = -110}
|
||||||
HUD_AIR_POS = {x = 0.5, y = 1}
|
HUD_AIR_POS = {x = 0.5, y = 1}
|
||||||
HUD_AIR_OFFSET = {x = 6, y = -124}
|
HUD_AIR_OFFSET = {x = 6, y = -124}
|
||||||
HUD_HUNGER_POS = {x = 0.5, y = 1}
|
HUD_HUNGER_POS = {x = 0.5, y = 1}
|
||||||
HUD_HUNGER_OFFSET = {x = 6, y = -93}
|
HUD_HUNGER_OFFSET = {x = 6, y = -110}
|
||||||
HUD_ARMOR_POS = {x = 0.5, y = 1}
|
HUD_ARMOR_POS = {x = 0.5, y = 1}
|
||||||
HUD_ARMOR_OFFSET = {x = -248, y = -124}
|
HUD_ARMOR_OFFSET = {x = -248, y = -124}
|
||||||
|
|
||||||
|
@ -26,11 +26,18 @@ mobs:register_mob("mobs_animal:pig", {
|
|||||||
jump = true,
|
jump = true,
|
||||||
follow = {"default:apple", "farming:potato"},
|
follow = {"default:apple", "farming:potato"},
|
||||||
view_range = 5,
|
view_range = 5,
|
||||||
drops = {
|
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 = 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},
|
||||||
{name = "mobs:pork_raw", chance = 2, min = 1, max = 1}
|
{name = "mobs:pork_raw", chance = 2, min = 1, max = 1}
|
||||||
},
|
}
|
||||||
|
end,
|
||||||
water_damage = 0,
|
water_damage = 0,
|
||||||
lava_damage = 5,
|
lava_damage = 5,
|
||||||
light_damage = 0,
|
light_damage = 0,
|
||||||
|
@ -665,6 +665,8 @@ end
|
|||||||
|
|
||||||
-- drop items
|
-- drop items
|
||||||
function mob_class:item_drop()
|
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
|
-- check for nil or no drops
|
||||||
if not self.drops or #self.drops == 0 then
|
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
|
and self.cause_of_death.puncher:is_player() or nil
|
||||||
|
|
||||||
local obj, item, num
|
local obj, item, num
|
||||||
local pos = self.object:get_pos()
|
|
||||||
|
|
||||||
for n = 1, #self.drops do
|
for n = 1, #self.drops do
|
||||||
|
|
||||||
|
@ -1 +1,2 @@
|
|||||||
default
|
default
|
||||||
|
experience?
|
||||||
|
Loading…
x
Reference in New Issue
Block a user