From 3b3904d1d6b10236df1526db5d975c188c0aad0e Mon Sep 17 00:00:00 2001 From: raymoo Date: Thu, 26 May 2016 07:58:23 -0700 Subject: [PATCH] Mostly done, I think --- init.lua | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 83 insertions(+), 1 deletion(-) diff --git a/init.lua b/init.lua index def0ea5..92c139f 100644 --- a/init.lua +++ b/init.lua @@ -1 +1,83 @@ --- Nothing yet +-- 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