-
Help with code
To begin with, I apologize if the code is disorganized or ugly.
His idea is to convert all units of time into seconds, minutes to seconds, hours to seconds, days to seconds.
I did what I knew to dig, because it's worth remembering and stressing I'm not a programmer.
Anyway, this is the error message that pops up to me:
[<color="red">ERROR</color>] Failed to load script buffer (Cypher System) (EffectManager2): [string "scripts/manager_effect2.lua"]:122: 'end' expected (to close 'if' at line 120) near 'return'
And this is the code that I "made"
Code:
--
-- Please see the license.html file included with this distribution for
-- attribution and copyright information.
--
-- Given a combat tracker node, return true if the node currently has an active "dazed" effect on it.
-- Otherwise return false.
--
function onInit()
EffectManager.registerEffectVar("nStatus", { sDBType = "number", sDBField = "status", bSkipAdd = false });
EffectManager.registerEffectVar("sUnits", { sDBType = "string", sDBField = "units", bSkipAdd = false });
EffectManager.setCustomOnEffectAddStart(onEffectAddStart);
EffectManager.setCustomOnEffectStartTurn(onEffectStartTurn);
EffectManager.setCustomOnEffectEndTurn(onEffectEndTurn);
EffectManager.setCustomOnEffectActorStartTurn(onEffectActorStartTurn);
EffectManager.setCustomOnEffectActorEndTurn(onEffectActorEndTurn);
EffectManager.setCustomOnEffectTextEncode(onEffectTextEncode);
EffectManager.setCustomOnEffectTextDecode(onEffectTextDecode);
end
function onEffectAddStart(rEffect)
rEffect.nStatus = 0;
rEffect.nDuration = rEffect.nDuration or 1;
if rEffect.sUnits == "min" then
rEffect.nDuration = rEffect.nDuration * 60;
rEffect.sUnits = "sec";
elseif rEffect.sUnits == "hr" then
rEffect.nDuration = rEffect.nDuration * 3600;
rEffect.sUnits = "sec";
elseif rEffect.sUnits == "day" then
rEffect.nDuration = rEffect.nDuration * 86400;
rEffect.sUnits = "sec";
if rEffect.sUnits and rEffect.sUnits == "sec" then
rEffect.sUnits = "sec";
rEffect.nStatus = 1;
end
end
end
function onEffectStartTurn(nodeEffect)
return true;
end
function onEffectEndTurn(nodeEffect)
return true;
end
function onEffectActorStartTurn(nodeActor, nodeEffect)
DB.setValue(nodeEffect, "status", "number", 1);
end
function onEffectActorEndTurn(nodeActor, nodeEffect)
local nDuration = DB.getValue(nodeEffect, "duration", 1);
local sUnits = DB.getValue(nodeEffect, "units", "");
local nStatus = DB.getValue(nodeEffect, "status", 1);
-- Convert to seconds
if sUnits == "min" then
sUnits = "sec";
nDuration = nDuration * 60;
DB.setValue(nodeEffect, "units", "string", sUnits);
elseif sUnits == "hr" then
sUnits = "sec";
nDuration = nDuration * 3600;
DB.setValue(nodeEffect, "units", "string", sUnits);
elseif sUnits == "day" then
sUnits = "sec";
nDuration = nDuration * 86400;
DB.setValue(nodeEffect, "units", "string", sUnits);
if sUnits and nStatus == 1 then
sUnits = "sec";
nDuration = nDuration - 1;
end
end
end
function onEffectTextEncode(rEffect)
local aMessage = {};
if rEffect.sUnits and rEffect.sUnits ~= "" then
local sOutputUnits = nil;
if rEffect.sUnits == "sec" then
sOutputUnits = "SEC";
elseif rEffect.sUnits == "min" then
sOutputUnits = "MIN";
elseif rEffect.sUnits == "hr" then
sOutputUnits = "HR";
elseif rEffect.sUnits == "day" then
sOutputUnits = "DAY";
if sOutputUnits then
table.insert(aMessage, "[UNITS " .. sOutputUnits .. "]");
return table.concat(aMessage, " ");
end
end
end
end
function onEffectTextDecode(sEffect, rEffect)
local s = sEffect;
local sUnits = s:match("%[UNITS ([^]]+)]");
if sUnits then
s = s:gsub("%[UNITS ([^]]+)]", "");
if sUnits == "SEC" then
rEffect.sUnits = "sec";
elseif sUnits == "MIN" then
rEffect.sUnits = "min";
elseif sUnits == "HR" then
rEffect.sUnits = "hr";
elseif sUnits == "DAY" then
rEffect.sUnits = "day";
return s;
end
end
end
function isDazed(nodeCT)
for _,nodeChild in pairs(DB.getChildren(nodeCT, "effects")) do
if string.lower(DB.getValue(nodeChild, "label", "")) == "dazed" and DB.getValue(nodeChild, "isactive") == 1 then
return true;
return false;
end
end
end
-
Moved thread to the workshop forum.
You can’t have 2 return commands like that. Delete the second one at line 122.
-
Trenloe, as you indicated I made the change of return, and some new additions to see if the time is decreasing, because I was and I have this problem, but this message appears now that I try to apply the effect
Error message: [<color="red">ERROR</color>] Script execution error: [string "scripts/manager_effect.lua"]:942: attempt to index local 's' (a nil value)
This message appears when I click to apply the second, minute, and hour effects, but not with days, the days effect converts time to seconds, but does not decrease.
Code changed
Code:
--
-- Please see the license.html file included with this distribution for
-- attribution and copyright information.
--
-- Given a combat tracker node, return true if the node currently has an active "dazed" effect on it.
-- Otherwise return false.
--
function onInit()
EffectManager.registerEffectVar("nStatus", { sDBType = "number", sDBField = "status", bSkipAdd = false });
EffectManager.registerEffectVar("sUnits", { sDBType = "string", sDBField = "units", bSkipAdd = false });
EffectManager.setCustomOnEffectAddStart(onEffectAddStart);
EffectManager.setCustomOnEffectStartTurn(onEffectStartTurn);
EffectManager.setCustomOnEffectEndTurn(onEffectEndTurn);
EffectManager.setCustomOnEffectActorStartTurn(onEffectActorStartTurn);
EffectManager.setCustomOnEffectActorEndTurn(onEffectActorEndTurn);
EffectManager.setCustomOnEffectTextEncode(onEffectTextEncode);
EffectManager.setCustomOnEffectTextDecode(onEffectTextDecode);
end
function onEffectAddStart(rEffect)
rEffect.nStatus = 0;
rEffect.nDuration = rEffect.nDuration or 1;
if rEffect.sUnits == "min" then
rEffect.nDuration = rEffect.nDuration * 60;
rEffect.sUnits = "sec";
elseif rEffect.sUnits == "hr" then
rEffect.nDuration = rEffect.nDuration * 3600;
rEffect.sUnits = "sec";
elseif rEffect.sUnits == "day" then
rEffect.nDuration = rEffect.nDuration * 86400;
rEffect.sUnits = "sec";
if rEffect.sUnits and rEffect.sUnits == "min" then
rEffect.sUnits = "sec";
rEffect.nStatus = 1;
elseif rEffect.sUnits and rEffect.sUnits == "hr" then
rEffect.sUnits = "sec";
rEffect.nStatus = 1;
elseif rEffect.sUnits and rEffect.sUnits == "day" then
rEffect.sUnits = "sec";
rEffect.nStatus = 1;
end
end
end
function onEffectStartTurn(nodeEffect)
return true;
end
function onEffectEndTurn(nodeEffect)
return true;
end
function onEffectActorStartTurn(nodeActor, nodeEffect)
DB.setValue(nodeEffect, "status", "number", 1);
end
function onEffectActorEndTurn(nodeActor, nodeEffect)
local nDuration = DB.getValue(nodeEffect, "duration", 1);
local sUnits = DB.getValue(nodeEffect, "units", "");
local nStatus = DB.getValue(nodeEffect, "status", 1);
-- Convert to seconds
if sUnits == "min" then
sUnits = "sec";
nDuration = nDuration * 60;
DB.setValue(nodeEffect, "units", "string", sUnits);
elseif sUnits == "hr" then
sUnits = "sec";
nDuration = nDuration * 3600;
DB.setValue(nodeEffect, "units", "string", sUnits);
elseif sUnits == "day" then
sUnits = "sec";
nDuration = nDuration * 86400;
DB.setValue(nodeEffect, "units", "string", sUnits);
if sUnits == "min" and nStatus == 1 then
sUnits = "sec";
nDuration = nDuration - 1;
elseif sUnits == "hr" and nStatus == 1 then
sUnits = "sec";
nDuration = nDuration - 1;
elseif sUnits == "day" and nStatus == 1 then
sUnits = "sec";
nDuration = nDuration - 1;
end
end
end
function onEffectTextEncode(rEffect)
local aMessage = {};
if rEffect.sUnits and rEffect.sUnits ~= "" then
local sOutputUnits = nil;
if rEffect.sUnits == "sec" then
sOutputUnits = "SEC";
elseif rEffect.sUnits == "min" then
sOutputUnits = "MIN";
elseif rEffect.sUnits == "hr" then
sOutputUnits = "HR";
elseif rEffect.sUnits == "day" then
sOutputUnits = "DAY";
if sOutputUnits then
table.insert(aMessage, "[UNITS " .. sOutputUnits .. "]");
return table.concat(aMessage, " ");
end
end
end
end
function onEffectTextDecode(sEffect, rEffect)
local s = sEffect;
local sUnits = s:match("%[UNITS ([^]]+)]");
if sUnits then
s = s:gsub("%[UNITS ([^]]+)]", "");
if sUnits == "SEC" then
rEffect.sUnits = "sec";
elseif sUnits == "MIN" then
rEffect.sUnits = "min";
elseif sUnits == "HR" then
rEffect.sUnits = "hr";
elseif sUnits == "DAY" then
rEffect.sUnits = "day";
return s;
end
end
end
function isDazed(nodeCT)
for _,nodeChild in pairs(DB.getChildren(nodeCT, "effects")) do
if string.lower(DB.getValue(nodeChild, "label", "")) == "dazed" and DB.getValue(nodeChild, "isactive") == 1 then
return true;
end
end
end
-
yako2020,
Your onEffectTextDecode function must have a return value at all exit points; or else you will get this error because you are returning nil if you don't specify a return value.
Make sure to review the 5E ruleset for an example of this situation in a live case:
scripts/manager_effect_5E.lua (Lines 58-83)
Regards,
JPG
-
Finally, I was able to convert the units of time, minutes, hours and days to seconds but I can't make the time decrement!
Attachment 31223
-
Code:
-- -- Please see the license.html file included with this distribution for
-- attribution and copyright information.
--
function onInit()
EffectManager.registerEffectVar("nStatus", { sDBType = "number", sDBField = "status", bSkipAdd = false });
EffectManager.registerEffectVar("sUnits", { sDBType = "string", sDBField = "units", bSkipAdd = false });
EffectManager.setCustomOnEffectAddStart(onEffectAddStart);
EffectManager.setCustomOnEffectStartTurn(onEffectStartTurn);
EffectManager.setCustomOnEffectEndTurn(onEffectEndTurn);
EffectManager.setCustomOnEffectActorStartTurn(onEffectActorStartTurn);
EffectManager.setCustomOnEffectActorEndTurn(onEffectActorEndTurn);
EffectManager.setCustomOnEffectTextEncode(onEffectTextEncode);
EffectManager.setCustomOnEffectTextDecode(onEffectTextDecode);
end
function onEffectAddStart(rEffect)
rEffect.nStatus = 0;
rEffect.nDuration = rEffect.nDuration or 1;
if rEffect.sUnits == "min" then
rEffect.nDuration = rEffect.nDuration * 60;
rEffect.sUnits = "sec";
elseif rEffect.sUnits == "hr" then
rEffect.nDuration = rEffect.nDuration * 3600;
rEffect.sUnits = "sec";
elseif rEffect.sUnits == "day" then
rEffect.nDuration = rEffect.nDuration * 86400;
rEffect.sUnits = "sec";
if rEffect.sUnits == "" then
rEffect.nStatus = 1;
end
end
end
function onEffectStartTurn(nodeEffect)
return true;
end
function onEffectEndTurn(nodeEffect)
return true;
end
function onEffectActorStartTurn(nodeActor, nodeEffect)
DB.setValue(nodeEffect, "status", "number", 1);
end
function onEffectActorEndTurn(nodeActor, nodeEffect)
local nDuration = DB.getValue(nodeEffect, "duration", 0);
local sUnits = DB.getValue(nodeEffect, "units", "");
local nStatus = DB.getValue(nodeEffect, "status", 0);
-- Convert to seconds
if sUnits == "min" then
sUnits = "sec";
nDuration = nDuration * 60;
DB.setValue(nodeEffect, "units", "string", sUnits);
elseif sUnits == "hr" then
sUnits = "sec";
nDuration = nDuration * 3600;
DB.setValue(nodeEffect, "units", "string", sUnits);
elseif sUnits == "day" then
sUnits = "sec";
nDuration = nDuration * 86400;
DB.setValue(nodeEffect, "units", "string", sUnits);
end
if sUnits == "min" and nStatus == 1 then
sUnits = "sec";
nDuration = nDuration - 1;
elseif sUnits == "hr" and nStatus == 1 then
sUnits = "sec";
nDuration = nDuration - 1;
elseif sUnits == "day" and nStatus == 1 then
sUnits = "sec";
nDuration = nDuration - 1;
if nDuration <= 0 and sUnits ~= "min" then
EffectManager.expireEffect(nodeActor, nodeEffect, 0);
elseif nDuration <= 0 and sUnits ~= "hr" then
EffectManager.expireEffect(nodeActor, nodeEffect, 0);
elseif nDuration <= 0 and sUnits ~= "" then
EffectManager.expireEffect(nodeActor, nodeEffect, 0);
else
DB.setValue(nodeEffect, "status", "number", 1);
DB.setValue(nodeEffect, "duration", "number", nDuration);
end
end
end
function onEffectTextEncode(rEffect)
local aMessage = {};
if rEffect.sUnits and rEffect.sUnits ~= "" then
local sOutputUnits = nil;
if rEffect.sUnits == "sec+" then
sOutputUnits = "SEC+";
elseif rEffect.sUnits == "sec" then
sOutputUnits = "SEC";
elseif rEffect.sUnits == "min" then
sOutputUnits = "MIN";
elseif rEffect.sUnits == "hr" then
sOutputUnits = "HR";
elseif rEffect.sUnits == "day" then
sOutputUnits = "DAY";
end
if sOutputUnits then
table.insert(aMessage, "[UNITS " .. sOutputUnits .. "]");
end
end
return table.concat(aMessage, " ");
end
function onEffectTextDecode(sEffect, rEffect)
local s = sEffect;
local sUnits = s:match("%[UNITS ([^]]+)]");
if sUnits then
s = s:gsub("%[UNITS ([^]]+)]", "");
if sUnits == "SEC" then
rEffect.sUnits = "sec";
elseif sUnits == "MIN" then
rEffect.sUnits = "min";
elseif sUnits == "HR" then
rEffect.sUnits = "hr";
elseif sUnits == "DAY" then
rEffect.sUnits = "day";
end
end
return s;
end
function isDazed(nodeCT)
for _,nodeChild in pairs(DB.getChildren(nodeCT, "effects")) do
if string.lower(DB.getValue(nodeChild, "label", "")) == "dazed" and DB.getValue(nodeChild, "isactive") == 1 then
return true;
end
end
return false;
end
-
Finally! It is now decreasing the time and expiring when the value reaches 0.
Now I will apply sec + to GURPS which is a scheme that instead of decrementing increments the value.
Many thanks to all who helped me in this my madness!
-
If you are interested in the code there, it is worth remembering that it will not be beautiful, nor so unprofessional, but it works.
One day maybe a transform into an extension.
Code:
-- -- Please see the license.html file included with this distribution for
-- attribution and copyright information.
--
function onInit()
EffectManager.registerEffectVar("nStatus", { sDBType = "number", sDBField = "status", bSkipAdd = false });
EffectManager.registerEffectVar("sUnits", { sDBType = "string", sDBField = "units", bSkipAdd = false });
EffectManager.setCustomOnEffectAddStart(onEffectAddStart);
EffectManager.setCustomOnEffectStartTurn(onEffectStartTurn);
EffectManager.setCustomOnEffectEndTurn(onEffectEndTurn);
EffectManager.setCustomOnEffectActorStartTurn(onEffectActorStartTurn);
EffectManager.setCustomOnEffectActorEndTurn(onEffectActorEndTurn);
EffectManager.setCustomOnEffectTextEncode(onEffectTextEncode);
EffectManager.setCustomOnEffectTextDecode(onEffectTextDecode);
end
function onEffectAddStart(rEffect)
rEffect.nStatus = 0;
rEffect.nDuration = rEffect.nDuration or 1;
if rEffect.sUnits == "min" then
rEffect.nDuration = rEffect.nDuration * 60;
rEffect.sUnits = "sec";
elseif rEffect.sUnits == "hr" then
rEffect.nDuration = rEffect.nDuration * 3600;
rEffect.sUnits = "sec";
elseif rEffect.sUnits == "day" then
rEffect.nDuration = rEffect.nDuration * 86400;
rEffect.sUnits = "sec";
if rEffect.sUnits == "sec" then
rEffect.nStatus = 1;
elseif rEffect.sUnits == "min" then
rEffect.nStatus = 1;
elseif rEffect.sUnits == "hr" then
rEffect.nStatus = 1;
elseif rEffect.sUnits == "day" then
rEffect.nStatus = 1;
end
end
end
function onEffectStartTurn(nodeEffect)
return true;
end
function onEffectEndTurn(nodeEffect)
return true;
end
function onEffectActorStartTurn(nodeActor, nodeEffect)
DB.setValue(nodeEffect, "status", "number", 1);
end
function onEffectActorEndTurn(nodeActor, nodeEffect)
local nDuration = DB.getValue(nodeEffect, "duration", 0);
local sUnits = DB.getValue(nodeEffect, "units", "");
local nStatus = DB.getValue(nodeEffect, "status", 0);
-- Convert to seconds
if sUnits == "min" then
sUnits = "sec";
nDuration = nDuration * 60;
DB.setValue(nodeEffect, "units", "string", sUnits);
elseif sUnits == "hr" then
sUnits = "sec";
nDuration = nDuration * 3600;
DB.setValue(nodeEffect, "units", "string", sUnits);
elseif sUnits == "day" then
sUnits = "sec";
nDuration = nDuration * 86400;
DB.setValue(nodeEffect, "units", "string", sUnits);
end
if sUnits == "sec" and nStatus == 1 then
sUnits = "sec";
nDuration = nDuration - 1;
if nDuration <= 0 then
EffectManager.expireEffect(nodeActor, nodeEffect, 0);
else
DB.setValue(nodeEffect, "status", "number", 1);
DB.setValue(nodeEffect, "duration", "number", nDuration);
end
end
end
function onEffectTextEncode(rEffect)
local aMessage = {};
if rEffect.sUnits and rEffect.sUnits ~= "" then
local sOutputUnits = nil;
if rEffect.sUnits == "sec" then
sOutputUnits = "SEC";
elseif rEffect.sUnits == "min" then
sOutputUnits = "MIN";
elseif rEffect.sUnits == "hr" then
sOutputUnits = "HR";
elseif rEffect.sUnits == "day" then
sOutputUnits = "DAY";
end
if sOutputUnits then
table.insert(aMessage, "[UNITS " .. sOutputUnits .. "]");
end
end
return table.concat(aMessage, " ");
end
function onEffectTextDecode(sEffect, rEffect)
local s = sEffect;
local sUnits = s:match("%[UNITS ([^]]+)]");
if sUnits then
s = s:gsub("%[UNITS ([^]]+)]", "");
if sUnits == "SEC" then
rEffect.sUnits = "sec";
elseif sUnits == "MIN" then
rEffect.sUnits = "min";
elseif sUnits == "HR" then
rEffect.sUnits = "hr";
elseif sUnits == "DAY" then
rEffect.sUnits = "day";
end
end
return s;
end
-
Thanks for your work Yako!
-
Happy to contribute, even with my follies!
But unfortunately I detected a failure and I have no idea why.
When there is only one "actor" in CT the effects "counter" does not work and when there is more than one "actor" the "counter" does not work in the last one.