New player data storage method

master
Brandon 2015-09-07 01:25:16 -05:00
parent 3a23193d38
commit f23fc8fb8c
18 changed files with 324 additions and 401 deletions

View File

@ -34,7 +34,7 @@ local function adventuretest_die_player(player)
mg_villages.spawnplayer(player)
end
energy.respawnplayer(player)
stats.increment(player:get_player_name(),STAT_DIED,1)
pd.increment(player:get_player_name(),STAT_DIED,1)
return true
end
@ -61,12 +61,10 @@ local function adventuretest_dignode(pos, node, digger)
-- ENERGY
if digger ~= nil and digger ~= "" then
local name= digger:get_player_name()
if player_energy[name] ~= nil then
player_energy[name] = player_energy[name] - 0.05
end
pd.increment(name,"energy",-0.05)
stats.increment(name,STAT_DUG,1)
local dug = stats.get(name,STAT_DUG)
pd.increment(name,STAT_DUG,1)
local dug = pd.get(name,STAT_DUG)
if dug % 100 == 0 then
local ppos = digger:getpos()
-- every 100 give them some experience
@ -89,9 +87,9 @@ local function adventuretest_placenode(pos, node, placer)
hunger.handle_node_actions(pos,node,placer)
if placer:is_player() then
local name = placer:get_player_name()
stats.increment(name,STAT_PLACED,1)
pd.increment(name,STAT_PLACED,1)
local placed = stats.get(name,STAT_PLACED)
local placed = pd.get(name,STAT_PLACED)
if placed % 100 == 0 then
local ppos = placer:getpos()
-- every 100 give them some experience
@ -114,20 +112,41 @@ local function on_generated(minp,maxp,seed)
end
minetest.register_on_generated(on_generated)
local function on_join(player)
stats.load(player:get_player_name())
local function on_join(player)
pd.load_player(player:get_player_name())
if minetest.setting_getbool("enable_damage") then
hunger_join_player(player)
end
end
minetest.register_on_joinplayer(on_join)
local function on_leave(player)
local name = player:get_player_name()
stats.save(name)
stats.unload(name)
pd.unload_player(name)
end
minetest.register_on_leaveplayer(on_leave)
local function on_shutdown()
stats.save_all()
local function on_new(player)
local name = player:get_player_name()
pd.load_player(name)
-- set some defaults
pd.set(name,"energy",20)
pd.set(name,"stamina",0)
pd.set(name,"mana",20)
pd.set(name,"hunger_lvl",20)
pd.set(name,"hunger_exhaus",0)
pd.set(name,"speed",1)
pd.set(name,"jump",1)
pd.set(name,"gravity",1)
pd.set(name,"level", {level=1,exp=0})
skills.set_default_skills(name)
pd.save_player(name)
mg_villages.on_newplayer(player)
end
minetest.register_on_newplayer(on_new)
local function on_shutdown()
pd.save_all()
end
minetest.register_on_shutdown(on_shutdown)

View File

@ -338,8 +338,12 @@ minetest.register_abm({
function default.serialize_to_file(filename,t)
local f = io.open(filename, "w")
if f ~= nil then
f:write(minetest.serialize(t))
f:close()
else
minetest.log("error","Unable to open for writing "..tostring(filename))
end
end
function default.deserialize_from_file(filename)
@ -417,3 +421,18 @@ function randomChance (percent)
math.randomseed( os.clock() )
return percent >= math.random(1, 100)
end
function default.tprint (tbl, indent)
if not indent then indent = 0 end
for k, v in pairs(tbl) do
local formatting = string.rep(" ", indent) .. k .. ": "
if type(v) == "table" then
print(formatting)
default.tprint(v, indent+1)
elseif type(v) == 'boolean' then
print(formatting .. tostring(v))
else
print(formatting .. v)
end
end
end

View File

@ -165,7 +165,7 @@ function default.player_globalstep(dtime)
local animation_speed_mod = model.animation_speed or 30
-- Determine if the player is walking
if ( controls.up or controls.down or controls.left or controls.right ) and physics.player_frozen[name] ~= true then
if ( controls.up or controls.down or controls.left or controls.right ) and pd.get(name,"frozen") ~= true then
walking = true
end
@ -180,9 +180,10 @@ function default.player_globalstep(dtime)
elseif walking then
if player_anim[name] == "lay" or player_anim[name] == "sit" then
player:set_eye_offset({x=0,y=0,z=0},{x=0,y=0,z=0})
if player_sleephuds[name] ~= nil then
player:hud_remove(player_sleephuds[name])
player_sleephuds[name] = nil
local sleep_hud = pd.get(name,"sleep_hud")
if sleep_hud ~= nil then
player:hud_remove(sleep_hud)
pd.unset(name,"sleep_hud")
end
end
if player_sneak[name] ~= controls.sneak then
@ -197,9 +198,10 @@ function default.player_globalstep(dtime)
elseif controls.LMB then
if player_anim[name] == "lay" or player_anim[name] == "sit" and physics.player_frozen[name] ~= true then
player:set_eye_offset({x=0,y=0,z=0},{x=0,y=0,z=0})
if player_sleephuds[name] ~= nil then
player:hud_remove(player_sleephuds[name])
player_sleephuds[name] = nil
local sleep_hud = pd.get(name,"sleep_hud")
if sleep_hud ~= nil then
player:hud_remove(sleep_hud)
pd.unset(name,"sleep_hud")
end
end
player_set_animation(player, "mine")
@ -214,15 +216,17 @@ end
if minetest.register_on_punchplayer ~= nil then
minetest.register_on_punchplayer( function(player, hitter, time_from_last_punch, tool_capabilities, dir)
local name = player:get_player_name()
process_weapon(player,time_from_last_punch,tool_capabilities)
blood_particles(player:getpos(),0.5,27,"mobs_blood.png")
if player_anim[name] == "lay" or player_anim[name] == "sit" then
player:set_eye_offset({x=0,y=0,z=0},{x=0,y=0,z=0})
if player_sleephuds[name] ~= nil then
player:hud_remove(player_sleephuds[name])
player_sleephuds[name] = nil
end
physics.unfreeze_player(name)
local sleep_hud = pd.get(name,"sleep_hud")
if sleep_hud ~= nil then
player:hud_remove(sleep_hud)
pd.unset(name,"sleep_hud")
physics.unfreeze_player(name)
end
end
if math.random(0,3) == 3 then
local snum = math.random(1,4)

View File

@ -1,20 +1,12 @@
local energy_file = minetest.get_worldpath().."/energy"
local stamina_file = minetest.get_worldpath().."/stamina"
player_energy = default.deserialize_from_file(energy_file)
player_stamina = default.deserialize_from_file(stamina_file)
player_lastpos = {}
player_sleephuds = {}
player_can_boost_stamina = {}
function energy.update_energy(p,name)
-- loop through all online players and check their movement and update their energy
local pos = p:getpos()
if player_lastpos[name] ~= nil and skills.player_levels[name] ~= nil then
if player_energy[name] ~= nil then
local lastpos = pd.get(name,"lastpos")
local p_stamina = pd.get_number(name,"stamina")
local sleep_hud = pd.get(name,"sleep_hud")
if lastpos ~= nil then
if minetest.check_player_privs(name, {immortal=true}) then
player_energy[name] = 20
pd.set(name,"energy",20)
return
end
@ -33,62 +25,59 @@ function energy.update_energy(p,name)
end
-- adjust their energy
local vdiff = pos.y - player_lastpos[name].y
local vdiff = pos.y - lastpos.y
if vdiff > 0 then
adj = adj - ( vdiff * 0.2 )
end
local hdiff = math.sqrt(math.pow(pos.x-player_lastpos[name].x, 2) + math.pow(pos.z-player_lastpos[name].z, 2))
local hdiff = math.sqrt(math.pow(pos.x-lastpos.x, 2) + math.pow(pos.z-lastpos.z, 2))
stats.increment(name,STAT_TRAVEL,math.floor(hdiff))
pd.increment(name,STAT_TRAVEL,math.floor(hdiff))
adj = adj - ( hdiff * 0.03 )
--print("Energy Adjustments")
--print(tostring(adj))
--print("After stamina adjustment")
adj = adj + player_stamina[name]
adj = adj + p_stamina
--print(tostring(adj))
player_energy[name] = player_energy[name] + adj
if player_energy[name] < 0 then
player_energy[name] = 0
pd.increment(name,"energy",adj)
local p_energy = pd.get_number(name,"energy")
if p_energy < 0 then
p_energy = 0
p:set_hp(p:get_hp()-1)
end
if player_energy[name] >= 20 then
player_energy[name] = 20
if p_energy >= 20 then
p_energy = 20
if anim.animation == "lay" then
-- wake them up
default.player_set_animation(p, "stand")
p:set_eye_offset({x=0,y=0,z=0},{x=0,y=0,z=0})
if player_sleephuds[name] ~= nil then
p:hud_remove(player_sleephuds[name])
player_sleephuds[name] = nil
if sleep_hud ~= nil then
p:hud_remove(sleep_hud)
sleep_hud = nil
end
minetest.chat_send_player(name,"You feel fully energized!")
physics.unfreeze_player(name)
end
end
if player_energy[name] < 8 and player_can_boost_stamina[name] == true then
player_can_boost_stamina[name] = false
if player_stamina[name] < 0.65 then
player_stamina[name] = player_stamina[name] + 0.003
--print("Boosted player stamina "..tostring(player_stamina[name]))
default.serialize_to_file(stamina_file,player_stamina)
if p_energy < 8 and pd.get(name,"can_boost_stamina") == true then
pd.set(name,"can_boost_stamina",false)
if p_stamina < 0.65 then
p_stamina = p_stamina + 0.003
end
end
if player_energy[name] < 2 then
if p_energy < 2 then
affects.affectPlayer(name,"tired")
end
if player_energy[name] > 8 then
player_can_boost_stamina[name] = true
if p_energy > 8 then
pd.set(name,"can_boost_stamina",true)
end
else
player_energy[name] = 20
end
pd.set(name,"stamina",p_stamina)
end
player_lastpos[name] = pos
hud.change_item(p,"energy",{number = player_energy[name]})
pd.set(name,"lastpos",pos)
hud.change_item(p,"energy",{number = pd.get(name,"energy")})
end
local affect_tired = {
@ -117,9 +106,10 @@ minetest.register_chatcommand("sit",{
local player = minetest.get_player_by_name(name)
default.player_set_animation(player, "sit")
player:set_eye_offset({x=0,y=-5,z=0},{x=0,y=0,z=0})
if player_sleephuds[name] ~= nil then
player:hud_remove(player_sleephuds[name])
player_sleephuds[name] = nil
local sleep_hud = pd.get(name,"sleep_hud")
if sleep_hud ~= nil then
player:hud_remove(sleep_hud)
pd.unset(name,"sleep_hud")
end
physics.freeze_player(name)
end,
@ -130,7 +120,7 @@ minetest.register_chatcommand("sleep",{
local player = minetest.get_player_by_name(name)
default.player_set_animation(player, "lay")
player:set_eye_offset({x=0,y=-10,z=0},{x=0,y=0,z=0})
player_sleephuds[name] = player:hud_add({
local sleep_hud = player:hud_add({
hud_elem_type = "image",
text = "energy_blackout.png",
position = {x=1,y=1},
@ -140,6 +130,7 @@ minetest.register_chatcommand("sleep",{
offset = {x=0,y=0},
})
physics.freeze_player(name)
pd.set(name,"sleep_hud",sleep_hud)
end,
})
@ -148,10 +139,10 @@ minetest.register_chatcommand("stand",{
local player = minetest.get_player_by_name(name)
default.player_set_animation(player, "stand")
player:set_eye_offset({x=0,y=0,z=0},{x=0,y=0,z=0})
if player_sleephuds[name] ~= nil then
player:hud_remove(player_sleephuds[name])
player_sleephuds[name] = nil
local sleep_hud = pd.get(name,"sleep_hud")
if sleep_hud ~= nil then
player:hud_remove(sleep_hud)
pd.unset(name,"sleep_hud")
end
physics.unfreeze_player(name)
end,
@ -159,33 +150,11 @@ minetest.register_chatcommand("stand",{
function energy.respawnplayer(player)
local name = player:get_player_name()
player_energy[name] = 20
player_lastpos[name] = player:getpos()
energy.update_energy(player,name)
--affects.removeAffect(name,"tired")
pd.set(name,"energy",20)
pd.set(name,"lastpos",player:getpos())
energy.update_energy(player,name)
end
minetest.register_on_joinplayer(function (player)
local name = player:get_player_name()
if player_energy[name] == nil then
player_energy[name] = 20
player_lastpos[name] = player:getpos()
end
if player_stamina[name] == nil then
player_stamina[name] = 0
end
if player_energy[name] > 8 then
player_can_boost_stamina[name] = true
else
player_can_boost_stamina[name] = false
end
end)
minetest.register_on_shutdown(function()
default.serialize_to_file(energy_file,player_energy)
default.serialize_to_file(stamina_file,player_stamina)
end)
local energy_timer = 0
local energy_tick = 5

View File

@ -1,61 +1,24 @@
-- read/write
function hunger.read(player)
local inv = player:get_inventory()
if not inv then
return nil
end
local hgp = inv:get_stack("hunger", 1):get_count()
if hgp == 0 then
hgp = 21
inv:set_stack("hunger", 1, ItemStack({name = ":", count = hgp}))
else
hgp = hgp
end
if tonumber(hgp) > HUNGER_MAX + 1 then
hgp = HUNGER_MAX + 1
end
return hgp - 1
end
function hunger.save(player)
local inv = player:get_inventory()
local name = player:get_player_name()
local value = hunger[name].lvl
if not inv or not value then
return nil
end
if value > HUNGER_MAX then
value = HUNGER_MAX
end
if value < 0 then
value = 0
end
inv:set_stack("hunger", 1, ItemStack({name = ":", count = value + 1}))
return true
end
function hunger.update_hunger(player, new_lvl)
local name = player:get_player_name() or nil
if not name then
return false
end
if minetest.setting_getbool("enable_damage") == false then
hunger[name] = 20
pd.set(name,"hunger_lvl",20)
return
end
local lvl = hunger[name].lvl
local lvl = pd.get(name,"hunger_lvl")
if new_lvl then
lvl = new_lvl
end
if lvl > HUNGER_MAX then
lvl = HUNGER_MAX
end
hunger[name].lvl = lvl
pd.set(name,"hunger_lvl",lvl)
if lvl > 20 then
lvl = 20
end
hud.change_item(player, "hunger", {number = lvl})
hunger.save(player)
end
local update_hunger = hunger.update_hunger
@ -65,9 +28,10 @@ function hunger.handle_node_actions(pos, oldnode, player, ext)
return
end
local name = player:get_player_name()
local exhaus = hunger[name].exhaus
if not exhaus then
hunger[name].exhaus = 0
local exhaus = pd.get_number(name,"hunger_exhaus")
local lvl = pd.get_number(name,"hunger_lvl")
if not exhaus then
exhaus = 0
--return
end
@ -87,13 +51,13 @@ function hunger.handle_node_actions(pos, oldnode, player, ext)
if exhaus > HUNGER_EXHAUST_LVL then
exhaus = 0
local h = tonumber(hunger[name].lvl)
local h = lvl
if h > 0 then
update_hunger(player, h - 1)
end
end
hunger[name].exhaus = exhaus
pd.set(name,"hunger_exhaus",exhaus)
end
-- Time based hunger functions
@ -120,18 +84,16 @@ if minetest.setting_getbool("enable_damage") then
-- lower saturation by 1 point after <HUNGER_TICK> second(s)
if hunger_timer > HUNGER_TICK then
for _,player in ipairs(minetest.get_connected_players()) do
local name = player:get_player_name()
local tab = hunger[name]
local name = player:get_player_name()
if minetest.check_player_privs(name, {immortal=true}) then
update_hunger(player,20)
return
end
if tab then
local hunger = tab.lvl
if hunger > 0 then
update_hunger(player, hunger - 1)
end
end
local hunger = pd.get_number(name,"hunger_lvl")
if hunger > 0 then
update_hunger(player, hunger - 1)
end
end
hunger_timer = 0
end
@ -140,23 +102,22 @@ if minetest.setting_getbool("enable_damage") then
if health_timer > HUNGER_HEALTH_TICK then
for _,player in ipairs(minetest.get_connected_players()) do
local name = player:get_player_name()
local tab = hunger[name]
if tab then
local lvl = pd.get(name,"hunger_lvl")
local air = player:get_breath() or 0
local hp = player:get_hp()
-- heal player by 1 hp if not dead and saturation is > 15 (of 30)
if tonumber(tab.lvl) > HUNGER_HEAL_LVL and air > 0 then
if lvl > HUNGER_HEAL_LVL and air > 0 then
player:set_hp(hp + HUNGER_HEAL)
end
-- or damage player by 1 hp if saturation is < 2 (of 30)
if tonumber(tab.lvl) < HUNGER_STARVE_LVL then
if lvl < HUNGER_STARVE_LVL then
player:set_hp(hp - HUNGER_STARVE)
end
end
end
health_timer = 0
end
end
@ -205,7 +166,7 @@ function hunger.item_eat(hunger_change, replace_with_item, poisen, heal, sound)
return function(itemstack, user, pointed_thing)
if itemstack:take_item() ~= nil and user ~= nil then
local name = user:get_player_name()
local sat = tonumber(hunger[name].lvl)
local sat = pd.get_number(name,"hunger_lvl")
local hp = user:get_hp()
-- Saturation
if sat < HUNGER_MAX and hunger_change then

View File

@ -25,16 +25,10 @@ dofile(modpath .. "/legacy.lua")
-- Callbacks
if minetest.setting_getbool("enable_damage") then
minetest.register_on_joinplayer(function(player)
local inv = player:get_inventory()
inv:set_size("hunger", 1)
local name = player:get_player_name()
hunger[name] = {}
hunger[name].lvl = hunger.read(player)
hunger[name].exhaus = 0
local lvl = hunger[name].lvl
function hunger_join_player(player)
local name = player:get_player_name()
local lvl = pd.get_number(name,"hunger_lvl")
if lvl > 20 then
lvl = 20
end
@ -42,7 +36,7 @@ if minetest.setting_getbool("enable_damage") then
hud.change_item(player, "hunger", {offset = "item", item_name = "hunger"})
hud.change_item(player, "hunger", {number = lvl, max = 20})
end)
end)
minetest.register_on_item_eat(hunger.eat)
end
minetest.register_on_item_eat(hunger.eat)

View File

@ -62,10 +62,12 @@ function magic.cast(id,name,target)
local skb = skills.get_def(SKILL_MAGIC)
local mana = spell.max_mana - ( ( (sk.level - spell.level) / skb.max_level ) * 10 )
if sk.level >= magic._spells[id].level then
if magic.player_magic[name] >= mana then
magic.player_magic[name] = magic.player_magic[name] - mana
local p_mana = pd.get_number(name,"mana")
if p_mana >= mana then
p_mana = p_mana - mana
minetest.chat_send_player(name,"You cast "..spell.desc)
spell.on_cast(spell,name,target)
pd.set(name,"mana",p_mana)
else
minetest.chat_send_player(name,"You don't have enough magic!")
end

View File

@ -1,9 +1,5 @@
magic = { }
local magic_file = minetest.get_worldpath().."/magic"
local magicpath = minetest.get_modpath("magic")
magic.player_magic = default.deserialize_from_file(magic_file)
hud.register("magic", {
hud_elem_type = "statbar",
position = {x = 0.5, y = 1},
@ -23,13 +19,13 @@ dofile(magicpath.."/loop.lua")
function magic.update_magic(player,name)
if minetest.check_player_privs(name, {immortal=true}) then
magic.player_magic[name] = 20
hud.change_item(player,"magic", {number = magic.player_magic[name]})
pd.set(name,"mana",20)
hud.change_item(player,"magic", {number = 20})
return
end
local s = skills.get_skill(name,SKILL_MAGIC)
local baseAdj = 2
if magic.player_magic[name] ~= nil then
local mana = pd.get_number(name,"mana")
if default.player_get_animation(player) == "lay" then
baseAdj = baseAdj + 3
end
@ -40,25 +36,18 @@ function magic.update_magic(player,name)
local adj = baseAdj * ( s.level / 10 )
magic.player_magic[name] = magic.player_magic[name] + adj
mana = mana + adj
if magic.player_magic[name] > 20 then
magic.player_magic[name] = 20
if mana > 20 then
mana = 20
end
if magic.player_magic[name] < 0 then
magic.player_magic[name] = 0
end
else
magic.player_magic[name] = 20
end
hud.change_item(player,"magic", {number = magic.player_magic[name]})
if mana < 0 then
mana = 0
end
pd.set(name,"mana",mana)
hud.change_item(player,"magic", {number = mana})
end
minetest.register_on_shutdown(function()
default.serialize_to_file(magic_file,magic.player_magic)
end)
-- load magic spells
dofile(magicpath.."/thunder.lua")
dofile(magicpath.."/magicmissle.lua")

View File

@ -129,8 +129,10 @@ local magicmissle_spell = {
if sk.level >= 4 then
local mana = 10 - ( ( (sk.level - 2) / skb.max_level ) * 10 )
if magic.player_magic[name] >= mana then
magic.player_magic[name] = magic.player_magic[name] - mana
local p_mana = pd.get_number(name,"mana")
if p_mana >= mana then
p_mana = p_mana - mana
pd.set(name,"mana",p_mana)
minetest.sound_play("magic_magicmissle_cast",{object=user})
local playerpos = user:getpos()
local obj = minetest.env:add_entity({x=playerpos.x,y=playerpos.y+1.5,z=playerpos.z}, "magic:magicmissle")

View File

@ -35,14 +35,12 @@ function mg_villages.spawnplayer(player)
end
player:setpos(min_pos)
local name = player:get_player_name()
if homepos[name] == nil then
homepos[name]=min_pos
end
pd.set(name,"homepos",min_pos)
end
minetest.register_on_newplayer(function(player)
mg_villages.on_newplayer = function(player)
mg_villages.spawnplayer(player)
end)
end
--minetest.register_on_respawnplayer(function(player)
--spawnplayer(player)

View File

@ -5,8 +5,6 @@ if not update_time then
minetest.setting_set("3d_armor_update_time", tostring(update_time))
end
local player_physics_applied = {}
armor = {
player_hp = {},
elements = {"head", "torso", "legs", "feet"},
@ -196,7 +194,6 @@ minetest.register_on_joinplayer(function(player)
inventory_plus.register_button(player,"armor", "Armor")
local player_inv = player:get_inventory()
local name = player:get_player_name()
player_physics_applied[name] = false
local armor_inv = minetest.create_detached_inventory(name.."_armor",{
on_put = function(inv, listname, index, stack, player)
player:get_inventory():set_stack(listname, index, stack)

View File

@ -307,6 +307,8 @@ function mobs:register_mob(name, def)
local pos = self.object:getpos()
if self.object:get_hp() <= 0 then
if hitter and hitter:is_player() and hitter:get_inventory() then
local name = hitter:get_player_name()
pd.increment(name,STAT_KILLS,1)
for _,drop in ipairs(self.drops) do
if math.random(1, 100) < drop.chance then
local d = ItemStack(drop.name.." "..math.random(drop.min, drop.max))

View File

@ -4,13 +4,10 @@
-- physics persist across sessions and server shutdowns
physics = {}
local physics_file = minetest.get_worldpath() .. "/physics"
physics.player_physics = default.deserialize_from_file(physics_file)
physics.player_frozen = {}
function physics.adjust_physics(player,_physics)
local name = player:get_player_name()
for p,v in pairs(_physics) do
physics.player_physics[name][p] = physics.player_physics[name][p] + v
pd.increment(name,p,v)
end
physics.apply(player)
end
@ -18,22 +15,23 @@ end
function physics.apply(player)
if player ~= nil then
local name = player:get_player_name()
if physics.player_frozen[name] ~= true then
player:set_physics_override(physics.player_physics[name])
if pd.get(name,"frozen") ~= true then
local o = physics.get_player_physics(name)
player:set_physics_override(o)
end
end
end
function physics.freeze_player(name)
local player = minetest.get_player_by_name(name)
physics.player_frozen[name] = true
pd.set(name,"frozen",true)
player:set_physics_override({speed=0,jump=0})
end
function physics.unfreeze_player(name)
local player = minetest.get_player_by_name(name)
physics.player_frozen[name] = false
physics.apply(minetest.get_player_by_name(name))
pd.set(name,"frozen",false)
physics.apply(player)
end
function physics.remove_item_physics(player,item)
@ -49,7 +47,11 @@ function physics.remove_item_physics(player,item)
end
function physics.get_player_physics(name)
return physics.player_physics[name]
local o = {}
o["speed"] = pd.get_number(name,"speed")
o["jump"] = pd.get_number(name,"jump")
o["gravity"] = pd.get_number(name,"gravity")
return o
end
function physics.apply_item_physics(player,item)
@ -60,29 +62,12 @@ function physics.apply_item_physics(player,item)
end
end
function physics.init_player(player)
-- reset physics to default when the player joins
local name = player:get_player_name()
if physics.player_physics[name] == nil then
physics.player_physics[name] = {speed = 1, jump = 1, gravity = 1}
end
minetest.after(10,physics.apply,player)
end
function physics.apply_all()
-- reapply physics to everybody just in case we've missed it in a spot, or if it didn't take at the begining
for _,p in pairs(minetest.get_connected_players()) do
physics.apply(p)
end
default.serialize_to_file(physics_file,physics.player_physics)
minetest.after(30,physics.apply_all)
end
minetest.register_on_joinplayer(physics.init_player)
minetest.register_on_shutdown(function ()
default.serialize_to_file(physics_file,physics.player_physics)
end)
minetest.after(30,physics.apply_all)

87
mods/player_data/init.lua Executable file
View File

@ -0,0 +1,87 @@
STAT_DUG = 1
STAT_PLACED = 2
STAT_DIED = 3
STAT_TRAVEL = 4
STAT_PK = 5
STAT_KILLS = 6
local player_data = {}
local player_dir = minetest.get_worldpath() .. "/"
pd = {}
pd.load_player = function(name)
if player_data[name] == nil then -- prevent loading the player twice... specifically when a new player joins
player_data[name] = default.deserialize_from_file(player_dir..name..".data")
end
end
pd.unload_player = function(name)
pd.save_player(name)
player_data[name] = nil
end
pd.save_player = function(name)
if player_data[name] ~= nil then
default.serialize_to_file(player_dir..name..".data",player_data[name])
end
end
pd.save_all = function(again)
minetest.log("action","Saving player data...")
for name,_ in pairs(player_data) do
if player_data[name] ~= nil then
pd.save_player(name)
end
end
if again == true then
minetest.after(300,pd.save_all,true)
end
end
pd.get = function(name,param)
if pd.validate(name,param) then
return player_data[name][param]
else
return nil
end
end
pd.get_number = function(name,param)
return tonumber(pd.get(name,param)) or 0
end
pd.set = function(name, param, value)
if pd.validate(name,param) then
player_data[name][param] = value
else
minetest.log("error","Unable to set "..tostring(param).." to "..tostring(value))
end
end
pd.unset = function(name, param)
pd.set(name,param,nil)
end
pd.increment = function (name, param, amount)
local val = pd.get_number(name,param) + amount
pd.set(name,param,val)
end
pd.validate = function (name,param)
if name ~= nil and param ~= nil then
if player_data[name] ~= nil then
return true
else
return false
end
else
return false
end
end
pd.dump = function()
default.tprint(player_data,4)
end
minetest.after(300,pd.save_all,true)

View File

@ -1,8 +0,0 @@
STAT_DUG = 1
STAT_PLACED = 2
STAT_DIED = 3
STAT_TRAVEL = 4
STAT_PK = 5
STAT_KILLS = 6
strStat = {"Nodes Dug","Nodes Placed","Died","Distance Traveled","Players Killed","Mobs Killed"}

View File

@ -1,58 +1,18 @@
stats = {}
local player_stats = {}
STAT_DUG = 1
STAT_PLACED = 2
STAT_DIED = 3
STAT_TRAVEL = 4
STAT_PK = 5
STAT_KILLS = 6
dofile(minetest.get_modpath("player_stats").."/const.lua")
stats.load = function ( name )
player_stats[name] = default.deserialize_from_file(minetest.get_worldpath() .. "/players/" .. name ..".stats")
end
stats.save = function (name)
default.serialize_to_file(minetest.get_worldpath() .. "/players/" .. name .. ".stats",player_stats[name])
end
stats.save_all = function()
for name,s in pairs(player_stats) do
if s ~= nil then
stats.save(name)
end
end
minetest.after(600,stats.save_all)
end
stats.unload = function(name)
player_stats[name] = nil
end
stats.set = function (name, stat, value)
if player_stats[name] ~= nil then
player_stats[name][stat] = value
end
end
stats.get = function (name, stat)
return player_stats[name][stat]
end
stats.increment = function (name, stat, amount)
print("increment stat "..tostring(stat).." by "..tostring(amount))
if player_stats[name] ~= nil then
if tonumber(player_stats[name][stat]) ~= nil then
player_stats[name][stat] = player_stats[name][stat] + amount
else
player_stats[name][stat] = amount -- stat wasn't set or was invalid so reset it
end
end
end
minetest.after(600,stats.save_all)
strStat = {"Nodes Dug","Nodes Placed","Died","Distance Traveled","Players Killed","Mobs Killed"}
minetest.register_chatcommand("stats",{
params = "",
description = "Shows players stats",
func = function(name, param)
for i,d in pairs(strStat) do
minetest.chat_send_player(name, d..": "..tostring(player_stats[name][i]))
minetest.chat_send_player(name, d..": "..tostring(pd.get(name,i)))
end
end,
})

View File

@ -8,32 +8,6 @@ local cooldown = 300
local max_distance = 5000
----------------------------------
local homes_file = minetest.get_worldpath()..'/homes'
--local homes_file = minetest.get_worldpath() .. "/homes"
homepos = {}
local last_moved = {}
local function loadhomes()
local input = io.open(homes_file, "r")
if input then
while true do
local x = input:read("*n")
if x == nil then
break
end
local y = input:read("*n")
local z = input:read("*n")
local name = input:read("*l")
homepos[name:sub(2)] = {x = x, y = y, z = z}
end
io.close(input)
else
homepos = {}
end
end
loadhomes()
local function get_time()
return os.time()
end
@ -55,43 +29,47 @@ minetest.register_privilege("sethome_other", "Can use /sethome <player> command"
minetest.register_chatcommand("home", {
description = "Teleport you to your home point",
func = function(name, param)
local pname = nil
if param ~= "" then
if minetest.get_player_privs(name)["home_other"] then
if not homepos[param] then
if pd.get(param,"homepos") then
minetest.chat_send_player(name, "The player doesn't have a home now! Set it using /sethome <player>.")
return
end
player_name = param
pname = param
else
minetest.chat_send_player(name, "You don't have permission to run this command (missing privileges: home_other)")
return
end
else
pname = name
end
if player_name then pname = player_name else pname = name end
local last_moved = pd.get_number(pname,"last_moved")
local homepos = pd.get(pname,"homepos")
local player = minetest.env:get_player_by_name(name)
if player == nil then
-- just a check to prevent server death
return false
end
if homepos[pname] then
if homepos then
local time = get_time()
if cooldown ~= 0 and last_moved[name] ~= nil and time - last_moved[name] < cooldown then
minetest.chat_send_player(name, "You can teleport only once in "..cooldown.." seconds. Wait another "..round(cooldown - (time - last_moved[name]), 3).." secs...")
if cooldown ~= 0 and time - last_moved < cooldown then
minetest.chat_send_player(name, "You can teleport only once in "..cooldown.." seconds. Wait another "..round(cooldown - (time - last_moved), 3).." secs...")
return true
end
local pos = player:getpos()
local dst = distance(pos, homepos[pname])
if max_distance ~= 0 and distance(pos, homepos[pname]) > max_distance then
local dst = distance(pos, homepos)
if max_distance ~= 0 and dst > max_distance then
minetest.chat_send_player(name, "You are too far away from your home.")
return true
end
last_moved[name] = time
player_lastpos[pname] = homepos[pname]
player:setpos(homepos[pname])
pd.set(pname,"last_moved",time)
pd.set(pname,"lastpos",homepos)
player:setpos(homepos)
minetest.chat_send_player(name, "Teleported to home!")
else
if param ~= "" then
minetest.chat_send_player(name, "The player don't have a home now! Set it using /sethome <player>.")
minetest.chat_send_player(name, "The player doesn't have a home now! Set it using /sethome <player>.")
else
minetest.chat_send_player(name, "You don't have a home now! Set it using /sethome.")
end
@ -102,24 +80,23 @@ minetest.register_chatcommand("home", {
minetest.register_chatcommand("sethome", {
description = "Set your home point",
func = function(name, param)
local pname = nil
if param ~= "" then
if minetest.get_player_privs(name)["sethome_other"] then
player_name = param
pname = param
else
minetest.chat_send_player(name, "You don't have permission to run this command (missing privileges: sethome_other)")
return
end
else
pname = name
end
if player_name then pname = player_name else pname = name end
local player = minetest.env:get_player_by_name(name)
local pos = player:getpos()
homepos[pname] = pos
pd.set(pname,"homepos",pos)
minetest.chat_send_player(name, "Home set!")
local output = io.open(homes_file, "w")
for i, v in pairs(homepos) do
output:write(v.x.." "..v.y.." "..v.z.." "..i.."\n")
end
io.close(output)
pd.save_player(pname)
end,
})
@ -128,11 +105,11 @@ function sethome_respawnplayer (player)
if minetest.check_player_privs(name,{immortal = true}) then
return true
end
if homepos[name] ~= nil then
player:moveto(homepos[name])
local homepos = pd.get(name,"homepos")
if homepos ~= nil then
player:moveto(homepos)
return true
else
else
return false
end
end

View File

@ -1,53 +1,37 @@
skills = { }
skill_file = minetest.get_worldpath().."/player_skills"
level_file = minetest.get_worldpath().."/player_levels"
skills.available_skills = {}
skills.player_skills = {}
skills.player_levels = {}
function skills.register_skill(skill_id,s_table)
skills.available_skills[skill_id] = s_table
end
function skills.initialize()
minetest.log("action","Loading player skills and levels")
skills.player_skills = default.deserialize_from_file(skill_file)
skills.player_levels = default.deserialize_from_file(level_file)
dofile(minetest.get_modpath("skills").."/register_skills.lua")
minetest.after(120,skills.save)
end
function skills.save()
minetest.log("action","Saving levels and skills")
default.serialize_to_file(skill_file,skills.player_skills)
default.serialize_to_file(level_file,skills.player_levels)
minetest.after(120,skills.save)
end
function skills.get_def(skill_id)
return skills.available_skills[skill_id]
end
function skills.set_default_skills ( name )
minetest.log("action","Setting default skills for "..name)
if skills.player_skills[name] == nil then
skills.player_skills[name] = { }
end
local pskills = pd.get(name,"skills")
if pskills == nil then pskills = {} end
for k,v in pairs(skills.available_skills) do
--print(name.." checking for skill "..v.desc)
if skills.player_skills[name][k] == nil then
--print(name.." adding skill "..tostring(k))
skills.player_skills[name][k] = { level = 1, exp = 0 }
print(name.." checking for skill "..v.desc)
if pskills[k] == nil then
print("Doesn't have skill "..tostring(k))
pskills[k] = { level = 1, exp = 0 }
else
print("Has skill "..tostring(k))
end
end
default.serialize_to_file(skill_file,skills.player_skills)
print("Result!")
default.tprint(pskills,4)
pd.set(name,"skills",pskills)
end
function skills.get_skill(name, skill_id)
-- Existing skill
local playerSkills = skills.player_skills[name]
local playerSkills = pd.get(name,"skills")
local skill = playerSkills and playerSkills[skill_id]
if skill ~= nil then
return skill
@ -58,7 +42,7 @@ function skills.get_skill(name, skill_id)
minetest.log("info", "Requesting skill (id="..tostring(skill_id)..") for player '"..name.."'. Player is new or missing the skill.")
skills.set_default_skills(name)
playerSkills = skills.player_skills[name]
playerSkills = pd.get(name,"skills")
skill = playerSkills and playerSkills[skill_id]
if playerSkills == nil then
@ -71,26 +55,24 @@ function skills.get_skill(name, skill_id)
end
function skills.get_player_level(name)
if skills.player_levels[name] == nil then
skills.player_levels[name] = {level=1,exp=0}
end
return skills.player_levels[name]
return pd.get(name,"level")
end
function skills.add_exp(name, exp)
-- this adds experience to the user and increases their level when needed
local l = skills.get_player_level(name)
skills.player_levels[name].exp = l.exp + exp
local l = pd.get(name,"level")
l.exp = l.exp + exp
local next_level = ((l.level^2) * 50)
if skills.player_levels[name].exp >= next_level then
skills.player_levels[name].level = skills.player_levels[name].level + 1
skills.player_levels[name].exp = skills.player_levels[name].exp - next_level
minetest.chat_send_player(name,"You have gained a level! You are now level "..tostring(skills.player_levels[name].level))
if l.exp >= next_level then
l.level = l.level + 1
l.exp = l.exp - next_level
minetest.chat_send_player(name,"You have gained a level! You are now level "..tostring(l.level))
minetest.sound_play("levelup", {
to_player = name,
gain = 10.0,
})
pd.set(name,"level",l)
end
end
@ -137,16 +119,18 @@ minetest.register_on_joinplayer(function (player)
local sk = skills.get_skill(name,skill_id)
local skill = skills.available_skills[skill_id]
local next_level = math.floor(((sk.level^1.75) * skill.level_exp))
local pskills = pd.get(name,"skills")
skills.player_skills[name][skill_id].exp = skills.player_skills[name][skill_id].exp + exp_dropped
pskills[skill_id].exp = pskills[skill_id].exp + exp_dropped
if skills.player_skills[name][skill_id].exp >= next_level then
if skills.player_skills[name][skill_id].level ~= skill.max_level then
skills.player_skills[name][skill_id].level = skills.player_skills[name][skill_id].level + 1
skills.player_skills[name][skill_id].exp = skills.player_skills[name][skill_id].exp - next_level
end
while pskills[skill_id].exp >= next_level and pskills[skill_id].level < skill.max_level do
pskills[skill_id].level = pskills[skill_id].level + 1
pskills[skill_id].exp = pskills[skill_id].exp - next_level
next_level = math.floor(((pskills[skill_id].level^1.75) * skill.level_exp))
end
pd.set(name,"skills",pskills)
stack:clear()
inv:set_stack(listname,index,stack)
@ -164,24 +148,6 @@ minetest.register_on_joinplayer(function (player)
skill_inv:set_size(list, 1)
skill_inv:set_stack(list, 1, player_inv:get_stack(list, 1))
end
if skills.player_levels[name] == nil then
skills.player_levels[name] = {level=1,exp=1}
end
end)
minetest.register_on_shutdown(function()
default.serialize_to_file(skill_file,skills.player_skills)
default.serialize_to_file(level_file,skills.player_levels)
end)
minetest.register_on_newplayer(function(player)
skills.set_default_skills(player:get_player_name())
skills.player_levels[player:get_player_name()] = {level=1,exp=1}
end)
minetest.register_on_leaveplayer(function(player)
default.serialize_to_file(skill_file,skills.player_skills)
default.serialize_to_file(level_file,skills.player_levels)
end)
minetest.register_chatcommand("skills", {
@ -204,4 +170,4 @@ function skills_on_dieplayer (player)
skills.add_exp(name,decrease)
end
skills.initialize()
dofile(minetest.get_modpath("skills").."/register_skills.lua")