reward_inv/handle_access.lua

198 lines
6.6 KiB
Lua

-- low-level access, depending on internal structure of reward_inv.player_data
reward_inv.load_data = function(file_name)
local file_name = minetest.get_worldpath()..DIR_DELIM..file_name
-- reward_inv.player_data and reward_inv.inv_data are stored in diffrent files
local file, err = io.open(file_name, "r")
if(err) then
minetest.log("error","[MOD] reward_inv failed to read file "..tostring(file_name))
return {}
end
io.input(file)
local content = io.read()
io.close(file)
return minetest.deserialize(content or "")
end
-- this saves *only* reward_inv.player_data (which items has a player taken?)
reward_inv.save_player_data = function()
local data = minetest.serialize(reward_inv.player_data)
local file_name = minetest.get_worldpath()..DIR_DELIM..reward_inv.file_name_player_data
if(not(minetest.safe_file_write(file_name, data))) then
minetest.log("error","[MOD] reward_inv failed to write file "..tostring(file_name))
end
end
-- this saves *only* reward_inv.inv_data (which reward_inv contains which items?)
reward_inv.save_inv_data = function()
local data = minetest.serialize(reward_inv.inv_data)
local file_name = minetest.get_worldpath()..DIR_DELIM..reward_inv.file_name_inv_data
if(not(minetest.safe_file_write(file_name, data))) then
minetest.log("error","[MOD] reward_inv failed to write file "..tostring(file_name))
end
end
reward_inv.set_inv_data = function(reward_id, reward_data)
if(not(reward_id) or reward_id == "") then
return
end
reward_inv.inv_data[reward_id] = reward_data
reward_inv.save_inv_data()
if(not(reward_inv.player_data[reward_id])) then
-- Which player has taken how much out of this reward chest?
reward_inv.player_data[reward_id] = {}
-- write it to disc
reward_inv.save_player_data()
end
end
-- good for some abstraction from underlying data structure
reward_inv.reward_id_exists = function(reward_id)
return (reward_id and reward_inv.player_data[reward_id])
end
-- returns true if pname has the right to get the reward inv reward_id
reward_inv.check_has_access = function(pname, reward_id)
return (pname
and reward_inv.player_data
and reward_inv.player_data[reward_id]
and reward_inv.player_data[reward_id][pname])
end
-- like above, but get the data (abstraction of access)
reward_inv.get_access_data = function(pname, reward_id)
-- in edit mode: we do not care about the access data of that player
-- because we want to edit the data, not get a reward
if(reward_inv.player_is_editing[pname]) then
return {os.time(), 0, {}, 0, 0}
end
if(not(reward_inv.check_has_access(pname, reward_id))) then
return
end
return reward_inv.player_data[reward_id][pname]
end
-- set access data and store it (abstraction of access)
reward_inv.set_access_data = function(pname, reward_id, data)
if(not(pname) or not(reward_inv.reward_id_exists(reward_id))) then
return
end
reward_inv.player_data[reward_id][pname] = data
-- write it to disc
reward_inv.save_player_data()
end
-- keep a statistic of how many players gained access
reward_inv.granted_access_first_time = function(pname, reward_id)
-- reward does not exist? error
if(not(reward_inv.inv_data[reward_id])) then
return
end
local old = reward_inv.inv_data[reward_id]
if(not(old.anz_found)) then
old.anz_found = 0
end
reward_inv.inv_data[reward_id].anz_found = old.anz_found + 1
reward_inv.inv_data[reward_id].last_taken = os.time()
-- has the reward been discovered for the first time?
if(not(old.first_found) or old.first_found == 0) then
reward_inv.inv_data[reward_id].first_found = os.time()
end
reward_inv.inv_data[reward_id].last_found = os.time()
reward_inv.save_inv_data()
end
-- keep a statistic of how many players gained access
reward_inv.update_reward_last_taken = function(reward_id)
if(not(reward_inv.inv_data[reward_id])) then
return
end
reward_inv.inv_data[reward_id].last_taken = os.time()
reward_inv.save_inv_data()
end
-- the player took a reward out of a chest; store that it was taken
-- (this gets called by reward_inv.reward_inv_on_take)
reward_inv.store_reward_taken = function(inv, listname, index, stack, player)
if(not(player) or not(index) or not(stack)) then
return
end
local pname = player:get_player_name()
local reward_id = reward_inv.player_using[pname]
local data = reward_inv.get_access_data(pname, reward_id)
if(not(data)) then
-- either the reward_id does not exist or the player has no access
minetest.log("error", "[MOD] reward_inv Player "..tostring(pname)..
" tried to illegally access reward_id "..
tostring(reward_id).." and took "..
stack:to_string().." from it.")
return
end
-- was this the last item taken?
if(inv and inv:is_empty("main")) then
-- all rewards have been claimed
data[2] = 1
-- no need to further store how much has been taken
data[3] = {}
else
-- store how much of that stack was taken
local old_value = data[3][index] or 0
data[3][index] = old_value + stack:get_count()
end
-- we store when at least part of the reward was taken - but
-- not when the player just checks the reward
-- (needs to be called before changing the player_data because
-- this function here does not write the values to disc)
reward_inv.update_reward_last_taken(reward_id)
-- the player has taken from this inventory now
data[4] = os.time()
-- keep track of how many items the player got alltogether from this chest
-- (mostly relevant for chests that refill)
if(not(data[5])) then
data[5] = 0
end
data[5] = data[5] + stack:get_count()
-- store it
reward_inv.set_access_data(pname, reward_id, data)
end
-- more abstract access to the stored data, only depending on the
-- structure of the data field
-- grants pname access to the reward inv reward_id
reward_inv.grant_access = function(pname, reward_id)
-- we can only grant access to *known* rewards
if(not(pname) or not(reward_inv.reward_id_exists(reward_id))) then
return
end
local data = reward_inv.get_access_data(pname, reward_id)
-- the player already has access to this reward
if(data) then
return true
end
-- keep a statistic of how many players got access
-- (needs to be called before changing the player_data because
-- this function here does not write the values to disc)
reward_inv.granted_access_first_time(pname, reward_id)
-- data strucutre for each player:
-- 1. Time when access was first granted for this player
-- 2. Have all rewards been claimed?
-- 3. How much has been taken out of which slot?
-- 4. When has the player last taken from this inventory?
-- 5. How many items has the player taken out? Relevant mostly for chests with autorefill.
data = {os.time(), 0, {}, 0, 0}
reward_inv.set_access_data(pname, reward_id, data)
end