player_monoids/init.lua
2016-05-26 07:58:23 -07:00

84 lines
2.2 KiB
Lua

-- Copyright (c) raymoo 2016
-- Licensed under Apache 2.0 license. See COPYING for details.
-- Any documentation here are internal details, please avoid using them in your
-- mod.
player_monoids = {}
-- Needed for removing players from monoid lists when they leave.
local player_maps = {}
local mon_meta = {}
mon_meta.__index = mon_meta
-- A monoid object is a table with the following fields:
-- player_map: A map from player names to their effect tables. Effect tables
-- are maps from effect IDs to values.
-- value_cache: A map from player names to the cached value for the monoid.
-- next_id: The next unique ID to assign an effect.
local function monoid(def)
local mon = {}
local player_map = {}
mon.players = player_map
table.insert(player_maps, player_map)
mon.next_id = 1
setmetatable(mon, mon_methods)
return mon
end
player_monoids.make_monoid = monoid
function mon_meta:add_change(player, value)
local p_name = player:get_player_name()
local p_effects = self.player_map[p_name]
if p_effects == nil then
p_effects = {}
self.player_map[p_name] = p_effects
end
local actual_id
if id then
actual_id = id
else
actual_id = self.next_id
self.next_id = actual_id + 1
end
local old_total = self.value_cache[p_name]
p_effects[actual_id] = value
local new_total = self.fold(p_effects)
self.value_cache[p_name] = new_total
self.apply(new_total, player)
self.on_change(old_total, new_total, player)
end
function mon_meta:del_change(player, id)
local p_name = player:get_player_name()
local p_effects = self.player_map[p_name]
if p_effects == nil then return end
local old_total = self.value_cache[p_name]
p_effects[id] = nil
local new_total = self.fold(p_effects)
self.value_cache[p_name] = new_total
self.apply(new_total, player)
self.on_change(old_total, new_total, player)
end
function mon_meta:value(player)
local p_name = player:get_player_name()
return self.value_cache[p_name] or self.identity
end