Add basic player join and leave handling
[minetest_playereffects.git] / init.lua
blobcadfdacbc5e6238241b508894ccd63a4929d2de9
1 --[=[ Main tables ]=]
3 playereffects = {}
5 --[[ table containing the groups (experimental) ]]
6 playereffects.groups = {}
8 --[[ table containing all the effect types ]]
9 playereffects.effect_types = {}
11 --[[ table containing all the active effects ]]
12 playereffects.effects = {}
14 --[[ table containing all the inactive effects.
15 Effects become inactive if a player leaves an become active again if they join again. ]]
16 playereffects.inactive_effects = {}
18 --[[ table (indexed by player names) containing tables containing the active HUD IDs for players
19 Example: { ["Player 1"] = {1,2,3}, ["Player 2"] = {2}, ["Player 3"] = {} }
21 playereffects.hudids = {}
23 -- Variable for counting the effect_id
24 playereffects.last_effect_id = 0
26 function playereffects.next_effect_id()
27 playereffects.last_effect_id = playereffects.last_effect_id + 1
28 return playereffects.last_effect_id
29 end
31 --[=[ API functions ]=]
32 function playereffects.register_effect_type(name, description, groups, apply, cancel)
33 effect_type = {}
34 effect_type.description = description
35 effect_type.apply = apply
36 effect_type.groups = groups
37 if cancel ~= nil then
38 effect_type.cancel = cancel
39 else
40 effect_type.cancel = function() end
41 end
42 playereffects.effect_types[name] = effect_type
43 minetest.log("action", "Effect type "..name.." registered!")
44 end
46 function playereffects.apply_effect_type(effect_type_id, duration, player)
47 local start_time = os.time()
48 local playername = player:get_player_name()
49 local groups = playereffects.effect_types[effect_type_id].groups
50 for k,v in pairs(groups) do
51 playereffects.cancel_effect_group(v, playername)
52 end
53 local effect_id = playereffects.next_effect_id()
54 local hudid = playereffects.hud_effect(effect_type_id, player, #playereffects.get_player_effects(playername))
55 local effect = {
56 playername = playername,
57 effect_id = effect_id,
58 effect_type_id = effect_type_id,
59 start_time = start_time,
60 time_left = duration,
61 hudid = hudid
64 playereffects.effects[effect_id] = effect
66 playereffects.effect_types[effect_type_id].apply(player)
67 minetest.log("action", "Effect type "..effect_type_id.." applied to player "..playername.."!")
68 minetest.after(duration, function(effect_id) playereffects.cancel_effect(effect_id) end, effect_id)
69 end
71 -- TODO
72 function playereffects.cancel_effect_type(effect_type_id, playername)
73 end
75 function playereffects.cancel_effect_group(groupname, playername)
76 local effects = playereffects.get_player_effects(playername)
77 for e=1,#effects do
78 local effect = effects[e]
79 local thesegroups = playereffects.effect_types[effect.effect_type_id].groups
80 minetest.log("action", "thesegroups = "..dump(thesegroups))
81 minetest.log("action", "groupname = "..dump(groupname))
82 local delete = false
83 for g=1,#thesegroups do
84 if(thesegroups[g] == groupname) then
85 playereffects.cancel_effect(effect.effect_id)
86 break
87 end
88 end
89 end
90 end
92 function playereffects.cancel_effect(effect_id)
93 local effect = playereffects.effects[effect_id]
94 if(effect ~= nil) then
95 local player = minetest.get_player_by_name(effect.playername)
96 player:hud_remove(effect.hudid)
97 playereffects.effect_types[effect.effect_type_id].cancel(effect)
98 playereffects.effects[effect_id] = nil
99 minetest.log("action", "Effect type "..effect.effect_type_id.." cancelled from player "..effect.playername.."!")
103 function playereffects.get_player_effects(playername)
104 if(minetest.get_player_by_name(playername) ~= nil) then
105 local effects = {}
106 for k,v in pairs(playereffects.effects) do
107 if(v.playername == playername) then
108 table.insert(effects, v)
111 return effects
112 else
113 return {}
117 --[=[ Callbacks ]=]
118 --[[ Cancel all effects on player death ]]
119 minetest.register_on_dieplayer(function(player)
120 local effects = playereffects.get_player_effects(player:get_player_name())
121 for e=1,#effects do
122 playereffects.cancel_effect(effects[e].effect_id)
124 end)
127 minetest.register_on_leaveplayer(function(player)
128 local leave_time = os.time()
129 local playername = player:get_player_name()
130 local effects = playereffects.get_player_effects(playername)
132 playereffects.hud_clear(player)
133 playereffects.hudids[playername] = nil
135 if(playereffects.inactive_effects[playername] == nil) then
136 playereffects.inactive_effects[playername] = {}
138 for e=1,#effects do
139 local start_time = effects[e].start_time
140 local new_duration = os.difftime(leave_time, start_time)
141 local new_effect = effects[e]
142 new_effect.time_left = new_duration
143 table.insert(playereffects.inactive_effects[playername], new_effect)
144 playereffects.cancel_effect(effects[e].effect_id)
146 end)
149 minetest.register_on_joinplayer(function(player)
150 local playername = player:get_player_name()
152 -- load all the effects again (if any)
153 if(playereffects.inactive_effects[playername] ~= nil) then
154 for i=1,#playereffects.inactive_effects[playername] do
155 local effect = playereffects.inactive_effects[playername][i]
156 -- minetest.after(0, function(effect, player)
157 -- playereffects.apply_effect_type(effect.effect_type_id, effect.time_left, player) end,
158 -- effect, player)
159 playereffects.apply_effect_type(effect.effect_type_id, effect.time_left, player)
161 playereffects.inactive_effects[playername] = nil
164 end)
166 --[[
167 minetest.register_on_shutdown(function()
169 end)
172 --[=[ HUD ]=]
173 function playereffects.hud_update(player)
174 playereffects.hud_clear(player)
175 local effects = playereffects.get_player_effects(player:get_player_name())
176 for e=1,#effects do
177 playereffects.hud_effect(effects[e], player, e-1)
181 function playereffects.hud_clear(player)
182 local playername = player:get_player_name()
183 local effects = playereffects.get_player_effects(playername)
184 if(effects ~= nil) then
185 for i=1,#effects do
186 player:hud_remove(effects[i].hudid)
191 function playereffects.hud_effect(effect_type_id, player, pos)
192 local id
193 id = player:hud_add({
194 hud_elem_type = "text",
195 position = { x = 0.95, y = 0.3 },
196 name = "effect_"..effect_type_id,
197 text = playereffects.effect_types[effect_type_id].description,
198 scale = { x = 20, y = 100},
199 alignment = 1,
200 direction = 1,
201 number = 0xFFFFFF,
202 offset = { x = 0, y = pos*20 }
204 local playername = player:get_player_name()
205 return id
209 ----- EXAMPLE EFFECT TYPES -----
211 playereffects.register_effect_type("high_speed", "high speed", {"speed"},
212 function(player)
213 player:set_physics_override(4,nil,nil)
214 end,
216 function(effect)
217 local player = minetest.get_player_by_name(effect.playername)
218 player:set_physics_override(1,nil,nil)
221 playereffects.register_effect_type("low_speed", "low speed", {"speed"},
222 function(player)
223 player:set_physics_override(0.25,nil,nil)
224 end,
226 function(effect)
227 local player = minetest.get_player_by_name(effect.playername)
228 player:set_physics_override(1,nil,nil)
231 playereffects.register_effect_type("highjump", "greater jump height", {"jump"},
232 function(player)
233 player:set_physics_override(nil,2,nil)
234 end,
235 function(effect)
236 local player = minetest.get_player_by_name(effect.playername)
237 player:set_physics_override(nil,1,nil)
242 minetest.register_chatcommand("fast", {
243 params = "",
244 description = "Makes you fast for a short time.",
245 privs = {},
246 func = function(name, param)
247 playereffects.apply_effect_type("high_speed", 10, minetest.get_player_by_name(name))
248 end,
250 minetest.register_chatcommand("slow", {
251 params = "",
252 description = "Makes you slow for a long time.",
253 privs = {},
254 func = function(name, param)
255 playereffects.apply_effect_type("low_speed", 120, minetest.get_player_by_name(name))
256 end,
258 minetest.register_chatcommand("highjump", {
259 params = "",
260 description = "Makes you jump higher for a short time.",
261 privs = {},
262 func = function(name, param)
263 playereffects.apply_effect_type("highjump", 20, minetest.get_player_by_name(name))
264 end,