198 lines
6.6 KiB
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
|