1
0
mirror of https://repo.or.cz/minetest_playereffects.git synced 2025-06-29 06:40:42 +02:00

Compare commits

3 Commits

Author SHA1 Message Date
9b3b4d1c32 Stop repeater effect if entity died 2019-02-22 04:30:18 +01:00
e24c55d0bd More refactoring for non-player entity support 2019-02-22 03:31:07 +01:00
08b2c5fd22 Can apply effects to non-player entities 2019-02-22 03:10:26 +01:00
5 changed files with 105 additions and 87 deletions

View File

@ -1,2 +0,0 @@
Wuzzy <Wuzzy@disroot.org> <Wuzzy2@mail.ru>
Wuzzy <Wuzzy@disroot.org> <almikes@aol.com>

View File

@ -14,7 +14,9 @@ This is an framework for assigning temporary status effects to players. This mod
This mod alone is not aimed directly at players. Briefly, the point of this mod is to help other mods to implement temporary status effects for players in a clean and consistant way. This mod alone is not aimed directly at players. Briefly, the point of this mod is to help other mods to implement temporary status effects for players in a clean and consistant way.
Here is the information which may be relevant to you: Your current status effects are shown on the HUD on the right side, along with a timer which shows the time until the effect gets disabled. It is possible for the server to disable this feature entirely. Some status effects may also be hidden and are never exposed to the HUD. Here is the information which may be relevant to you: Your current status effects are shown on the HUD on the right side, along with a timer which shows the time until the effect gets disabled. It is possible for the server to disable this feature entirely. Some status effects may also be hidden and are never exposed to the HUD.
You only have to install this mod iff you have a mod which implements Player Effects. You only have to install this mod iff you have a mod which implements Player Effects. Here is a list of known mods which do:
* Magic Beans—Wuzzys Fork [`magicbeans_w`]
## Information for server operators ## Information for server operators
By default, this mod stores the effects into the file `playereffects.mt` in the current world path every 10 seconds. On a regular server shutdown, this file is also written to. The data in this file is read when the mod is started. By default, this mod stores the effects into the file `playereffects.mt` in the current world path every 10 seconds. On a regular server shutdown, this file is also written to. The data in this file is read when the mod is started.

0
depends.txt Normal file
View File

184
init.lua
View File

@ -56,10 +56,10 @@ do
if(string ~= nil) then if(string ~= nil) then
local savetable = minetest.deserialize(string) local savetable = minetest.deserialize(string)
playereffects.inactive_effects = savetable.inactive_effects playereffects.inactive_effects = savetable.inactive_effects
minetest.log("action", "[playereffects] playereffects.mt successfully read.") minetest.debug("[playereffects] playereffects.mt successfully read.")
minetest.log("verbose", "[playereffects] inactive_effects = "..dump(playereffects.inactive_effects)) minetest.debug("[playereffects] inactive_effects = "..dump(playereffects.inactive_effects))
playereffects.last_effect_id = savetable.last_effect_id playereffects.last_effect_id = savetable.last_effect_id
minetest.log("verbose", "[playereffects] last_effect_id = "..dump(playereffects.last_effect_id)) minetest.debug("[playereffects] last_effect_id = "..dump(playereffects.last_effect_id))
end end
end end
@ -98,32 +98,30 @@ function playereffects.register_effect_type(effect_type_id, description, icon, g
minetest.log("action", "[playereffects] Effect type "..effect_type_id.." registered!") minetest.log("action", "[playereffects] Effect type "..effect_type_id.." registered!")
end end
function playereffects.apply_effect_type(effect_type_id, duration, player, repeat_interval_time_left) function playereffects.apply_effect_type(effect_type_id, duration, entity, repeat_interval_time_left)
local start_time = os.time() local start_time = os.time()
local is_player = false local is_player = false
if(type(player)=="userdata") then if(type(entity)=="userdata") then
if(player.is_player ~= nil) then if(entity.is_player ~= nil) then
if(player:is_player() == true) then if(entity:is_player() == true) then
is_player = true is_player = true
end end
end end
end end
if(is_player == false) then
minetest.log("error", "[playereffects] Attempted to apply effect type "..effect_type_id.." to a non-player!")
return false
end
local playername = player:get_player_name() local playername = entity:get_player_name()
local groups = playereffects.effect_types[effect_type_id].groups local groups = playereffects.effect_types[effect_type_id].groups
for k,v in pairs(groups) do for k,v in pairs(groups) do
playereffects.cancel_effect_group(v, playername) playereffects.cancel_effect_group(v, entity)
end end
local metadata local metadata
if(playereffects.effect_types[effect_type_id].repeat_interval == nil) then if(playereffects.effect_types[effect_type_id].repeat_interval == nil) then
local status = playereffects.effect_types[effect_type_id].apply(player) local status = playereffects.effect_types[effect_type_id].apply(entity)
if(status == false) then if(status == false) then
minetest.log("action", "[playereffects] Attempt to apply effect type "..effect_type_id.." to player "..playername.." failed!") if is_player then
minetest.log("action", "[playereffects] Attempt to apply effect type "..effect_type_id.." to player "..playername.." failed!")
end
return false return false
else else
metadata = status metadata = status
@ -132,32 +130,8 @@ function playereffects.apply_effect_type(effect_type_id, duration, player, repea
local effect_id = playereffects.next_effect_id() local effect_id = playereffects.next_effect_id()
local smallest_hudpos
local biggest_hudpos = -1
local free_hudpos
if(playereffects.hudinfos[playername] == nil) then
playereffects.hudinfos[playername] = {}
end
local hudinfos = playereffects.hudinfos[playername]
for effect_id, hudinfo in pairs(hudinfos) do
local hudpos = hudinfo.pos
if(hudpos > biggest_hudpos) then
biggest_hudpos = hudpos
end
if(smallest_hudpos == nil) then
smallest_hudpos = hudpos
elseif(hudpos < smallest_hudpos) then
smallest_hudpos = hudpos
end
end
if(smallest_hudpos == nil) then
free_hudpos = 0
elseif(smallest_hudpos >= 0) then
free_hudpos = smallest_hudpos - 1
else
free_hudpos = biggest_hudpos + 1
end
-- repeat stuff
local repeat_interval = playereffects.effect_types[effect_type_id].repeat_interval local repeat_interval = playereffects.effect_types[effect_type_id].repeat_interval
if(repeat_interval ~= nil) then if(repeat_interval ~= nil) then
if(repeat_interval_time_left == nil) then if(repeat_interval_time_left == nil) then
@ -165,18 +139,47 @@ function playereffects.apply_effect_type(effect_type_id, duration, player, repea
end end
end end
--[[ show no more than 20 effects on the screen, so that hud_update does not need to be called so often ]] -- Handle HUD
local text_id, icon_id if is_player then
if(free_hudpos <= 20) then local smallest_hudpos
text_id, icon_id = playereffects.hud_effect(effect_type_id, player, free_hudpos, duration, repeat_interval_time_left) local biggest_hudpos = -1
local hudinfo = { local free_hudpos
text_id = text_id, if(playereffects.hudinfos[playername] == nil) then
icon_id = icon_id, playereffects.hudinfos[playername] = {}
pos = free_hudpos, end
} local hudinfos = playereffects.hudinfos[playername]
playereffects.hudinfos[playername][effect_id] = hudinfo for effect_id, hudinfo in pairs(hudinfos) do
else local hudpos = hudinfo.pos
text_id, icon_id = nil, nil if(hudpos > biggest_hudpos) then
biggest_hudpos = hudpos
end
if(smallest_hudpos == nil) then
smallest_hudpos = hudpos
elseif(hudpos < smallest_hudpos) then
smallest_hudpos = hudpos
end
end
if(smallest_hudpos == nil) then
free_hudpos = 0
elseif(smallest_hudpos >= 0) then
free_hudpos = smallest_hudpos - 1
else
free_hudpos = biggest_hudpos + 1
end
--[[ show no more than 20 effects on the screen, so that hud_update does not need to be called so often ]]
local text_id, icon_id
if(free_hudpos <= 20) then
text_id, icon_id = playereffects.hud_effect(effect_type_id, entity, free_hudpos, duration, repeat_interval_time_left)
local hudinfo = {
text_id = text_id,
icon_id = icon_id,
pos = free_hudpos,
}
playereffects.hudinfos[playername][effect_id] = hudinfo
else
text_id, icon_id = nil, nil
end
end end
local effect = { local effect = {
@ -193,7 +196,7 @@ function playereffects.apply_effect_type(effect_type_id, duration, player, repea
playereffects.effects[effect_id] = effect playereffects.effects[effect_id] = effect
if(repeat_interval ~= nil) then if(repeat_interval ~= nil) then
minetest.after(repeat_interval_time_left, playereffects.repeater, effect_id, duration, player, playereffects.effect_types[effect_type_id].apply) minetest.after(repeat_interval_time_left, playereffects.repeater, effect_id, duration, entity, playereffects.effect_types[effect_type_id].apply)
else else
minetest.after(duration, function(effect_id) playereffects.cancel_effect(effect_id) end, effect_id) minetest.after(duration, function(effect_id) playereffects.cancel_effect(effect_id) end, effect_id)
end end
@ -201,11 +204,11 @@ function playereffects.apply_effect_type(effect_type_id, duration, player, repea
return effect_id return effect_id
end end
function playereffects.repeater(effect_id, repetitions, player, apply) function playereffects.repeater(effect_id, repetitions, entity, apply)
local effect = playereffects.effects[effect_id] local effect = playereffects.effects[effect_id]
if(effect ~= nil) then if(effect ~= nil and entity ~= nil and entity:get_luaentity() ~= nil) then
local repetitions = effect.time_left local repetitions = effect.time_left
apply(player) apply(entity)
repetitions = repetitions - 1 repetitions = repetitions - 1
effect.time_left = repetitions effect.time_left = repetitions
if(repetitions <= 0) then if(repetitions <= 0) then
@ -219,15 +222,15 @@ function playereffects.repeater(effect_id, repetitions, player, apply)
playereffects.repeater, playereffects.repeater,
effect_id, effect_id,
repetitions, repetitions,
player, entity,
apply apply
) )
end end
end end
end end
function playereffects.cancel_effect_type(effect_type_id, cancel_all, playername) function playereffects.cancel_effect_type(effect_type_id, cancel_all, entity_or_playername)
local effects = playereffects.get_player_effects(playername) local effects = playereffects.get_player_effects(entity_or_playername)
if(cancel_all==nil) then cancel_all = false end if(cancel_all==nil) then cancel_all = false end
for e=1, #effects do for e=1, #effects do
if(effects[e].effect_type_id == effect_type_id) then if(effects[e].effect_type_id == effect_type_id) then
@ -239,8 +242,8 @@ function playereffects.cancel_effect_type(effect_type_id, cancel_all, playername
end end
end end
function playereffects.cancel_effect_group(groupname, playername) function playereffects.cancel_effect_group(groupname, entity_or_playername)
local effects = playereffects.get_player_effects(playername) local effects = playereffects.get_player_effects(entity_or_playername)
for e=1,#effects do for e=1,#effects do
local effect = effects[e] local effect = effects[e]
local thesegroups = playereffects.effect_types[effect.effect_type_id].groups local thesegroups = playereffects.effect_types[effect.effect_type_id].groups
@ -268,22 +271,35 @@ function playereffects.cancel_effect(effect_id)
local effect = playereffects.effects[effect_id] local effect = playereffects.effects[effect_id]
if(effect ~= nil) then if(effect ~= nil) then
local player = minetest.get_player_by_name(effect.playername) local player = minetest.get_player_by_name(effect.playername)
local hudinfo = playereffects.hudinfos[effect.playername][effect_id] if player then
if(hudinfo ~= nil) then local hudinfo = playereffects.hudinfos[effect.playername][effect_id]
if(hudinfo.text_id~=nil) then if(hudinfo ~= nil) then
player:hud_remove(hudinfo.text_id) if(hudinfo.text_id~=nil) then
player:hud_remove(hudinfo.text_id)
end
if(hudinfo.icon_id~=nil) then
player:hud_remove(hudinfo.icon_id)
end
playereffects.hudinfos[effect.playername][effect_id] = nil
end end
if(hudinfo.icon_id~=nil) then
player:hud_remove(hudinfo.icon_id) -- TODO: Implement cancellation for non-players
end playereffects.effect_types[effect.effect_type_id].cancel(effect, player)
playereffects.hudinfos[effect.playername][effect_id] = nil
end end
playereffects.effect_types[effect.effect_type_id].cancel(effect, player)
playereffects.effects[effect_id] = nil playereffects.effects[effect_id] = nil
end end
end end
function playereffects.get_player_effects(playername) function playereffects.get_player_effects(entity_or_playername)
-- TODO: support entity
local playername = ""
if type(entity_or_playername) == "string" then
playername = entity_or_playername
elseif type(entity_or_playername) == "userdata" and entity_or_playername:is_player() then
playername = entity_or_playername:get_player_name()
else
return {}
end
if(minetest.get_player_by_name(playername) ~= nil) then if(minetest.get_player_by_name(playername) ~= nil) then
local effects = {} local effects = {}
for k,v in pairs(playereffects.effects) do for k,v in pairs(playereffects.effects) do
@ -297,8 +313,8 @@ function playereffects.get_player_effects(playername)
end end
end end
function playereffects.has_effect_type(playername, effect_type_id) function playereffects.has_effect_type(entity_or_playername, effect_type_id)
local pe = playereffects.get_player_effects(playername) local pe = playereffects.get_player_effects(entity_or_playername)
for i=1,#pe do for i=1,#pe do
if pe[i].effect_type_id == effect_type_id then if pe[i].effect_type_id == effect_type_id then
return true return true
@ -314,11 +330,13 @@ function playereffects.save_to_file()
local inactive_effects = {} local inactive_effects = {}
for id,effecttable in pairs(playereffects.inactive_effects) do for id,effecttable in pairs(playereffects.inactive_effects) do
local playername = id local playername = id
if(inactive_effects[playername] == nil) then if playername ~= "" then
inactive_effects[playername] = {} if(inactive_effects[playername] == nil) then
end inactive_effects[playername] = {}
for i=1,#effecttable do end
table.insert(inactive_effects[playername], effecttable[i]) for i=1,#effecttable do
table.insert(inactive_effects[playername], effecttable[i])
end
end end
end end
for id,effect in pairs(playereffects.effects) do for id,effect in pairs(playereffects.effects) do
@ -342,7 +360,9 @@ function playereffects.save_to_file()
if(inactive_effects[effect.playername] == nil) then if(inactive_effects[effect.playername] == nil) then
inactive_effects[effect.playername] = {} inactive_effects[effect.playername] = {}
end end
table.insert(inactive_effects[effect.playername], new_effect) if effect.playername ~= "" then
table.insert(inactive_effects[effect.playername], new_effect)
end
end end
savetable.inactive_effects = inactive_effects savetable.inactive_effects = inactive_effects
@ -355,7 +375,7 @@ function playereffects.save_to_file()
if file then if file then
file:write(savestring) file:write(savestring)
io.close(file) io.close(file)
minetest.log("info", "[playereffects] Wrote playereffects data into "..filepath..".") minetest.log("action", "[playereffects] Wrote playereffects data into "..filepath..".")
else else
minetest.log("error", "[playereffects] Failed to write playereffects data into "..filepath..".") minetest.log("error", "[playereffects] Failed to write playereffects data into "..filepath..".")
end end
@ -393,7 +413,7 @@ minetest.register_on_leaveplayer(function(player)
end) end)
minetest.register_on_shutdown(function() minetest.register_on_shutdown(function()
minetest.log("info", "[playereffects] Server shuts down. Rescuing data into playereffects.mt") minetest.log("action", "[playereffects] Server shuts down. Rescuing data into playereffects.mt")
playereffects.save_to_file() playereffects.save_to_file()
end) end)
@ -427,7 +447,7 @@ minetest.register_globalstep(function(dtime)
-- Autosave into file -- Autosave into file
if(playereffects.use_autosave == true and playereffects.autosave_timer >= playereffects.autosave_time) then if(playereffects.use_autosave == true and playereffects.autosave_timer >= playereffects.autosave_time) then
playereffects.autosave_timer = 0 playereffects.autosave_timer = 0
minetest.log("info", "[playereffects] Autosaving mod data to playereffects.mt ...") minetest.log("action", "[playereffects] Autosaving mod data to playereffects.mt ...")
playereffects.save_to_file() playereffects.save_to_file()
end end
end) end)

View File

@ -1,3 +1 @@
name = playereffects name = playereffects
title = Player Effects
description = Framework for temporary effects for players.