forked from minetest-mods/player_monoids
		
	Mostly done, I think
This commit is contained in:
		
							
								
								
									
										84
									
								
								init.lua
									
									
									
									
									
								
							
							
						
						
									
										84
									
								
								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 | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user