PDA

View Full Version : Question about Evasion and Improved Evasion functionality



mr900rr
June 24th, 2018, 22:28
So I noticed that in order for Evasion and Improved Evasion to be calculated against a spell save you had to put the condition/effect "Evasion" or "Improved Evasion" on the PC in the combat tracker, now that works fine but my combat tracker is getting very long with all the condition/effects that are having to be put in. So I was wondering why that isn't auto calculated by the program, sure as with all things there could be situations where its not going to apply but I would rather do the extra steps for the minority of cases rather than the majority. So below I have changed the code in manager_action_save.lua in function applySave(), to check if the PC has the ability Evasion or Improved Evasion and to check if they are under a condition that would prevent Evasion from applying (helpless, paralyzed, unconscious, grappled), and check to make sure the armor they have equipped is not medium or heavy. To do the armor check I changed the code in manager_char.lua in function calcItemArmorClass() to add a node for encumbrance.armortype which gets the Subtype (None, Light, Medium, Heavy) for the armor you have equiped.

Could this be maybe added to a future release or is there another instance/issue I am not foreseeing?

For 3.5E users you will need to add to your classes .mod file the pathfinder style entries in your classes for drag and drop, Evasion example below.

<rogue>
<name type="string">Rogue</name>
<classfeatures>
<id-00004>
<level type="number">2</level>
<locked type="number">1</locked>
<name type="string">Evasion</name>
<source type="string">Rogue</source>
<text type="formattedtext">
<p>At 2nd level and higher, a rogue can avoid even magical and unusual attacks with great agility. If she makes a successful Reflex saving throw against an attack that normally deals half damage on a successful save, she instead takes no damage. Evasion can be used only if the rogue is wearing light armor or no armor. A helpless rogue does not gain the benefit of evasion.</p>
</text>
</id-00004>
</classfeatures>
... etc

Manager_action_save.lua changes are marked in comments -- added and colored

function applySave(rSource, rOrigin, rAction, sUser)
local msgShort = {font = "msgfont"};
local msgLong = {font = "msgfont"};

msgShort.text = "Save";
msgLong.text = "Save [" .. rAction.nTotal .. "]";
if rAction.nTarget then
msgLong.text = msgLong.text .. "[vs. DC " .. rAction.nTarget .. "]";
end
msgShort.text = msgShort.text .. " ->";
msgLong.text = msgLong.text .. " ->";
if rSource then
msgShort.text = msgShort.text .. " [for " .. rSource.sName .. "]";
msgLong.text = msgLong.text .. " [for " .. rSource.sName .. "]";
end
if rOrigin then
msgShort.text = msgShort.text .. " [vs " .. rOrigin.sName .. "]";
msgLong.text = msgLong.text .. " [vs " .. rOrigin.sName .. "]";
end

msgShort.icon = "roll_cast";

local sAttack = "";
local bHalfMatch = false;
if rAction.sSaveDesc then
sAttack = rAction.sSaveDesc:match("%[SAVE VS[^]]*%] ([^[]+)") or "";
bHalfMatch = (rAction.sSaveDesc:match("%[HALF ON SAVE%]") ~= nil);
end
rAction.sResult = "";
-- added
local bHasImpEvasion = false;
local bHasEvasion = false;
local sSourceType, nodeSource = ActorManager.getTypeAndNode(rSource);
if not EffectManager35E.hasEffectCondition(rSource, "Helpless") or EffectManager35E.hasEffectCondition(rSource, "Paralyzed") or EffectManager35E.hasEffectCondition(rSource, "Unconscious") or EffectManager35E.hasEffectCondition(rSource, "Grappled") then
local sArmorType = DB.getValue(nodeSource, "encumbrance.armortype", "");
if sArmorType == "None" or sArmorType == "Light" then
for _,v in pairs(DB.getChildren(nodeSource, "specialabilitylist")) do
if DB.getValue(v, "name", "") == "Improved Evasion" then
bHasImpEvasion = true;
elseif DB.getValue(v, "name", "") == "Evasion" then
bHasEvasion = true;
end
end
end
end
-- end added
if rAction.nTotal >= rAction.nTarget then
msgLong.text = msgLong.text .. " [SUCCESS]";

if rSource then
local bHalfDamage = bHalfMatch;
local bAvoidDamage = false;
if bHalfDamage then
local sSave = rAction.sDesc:match("%[SAVE%] (%w+)");
if sSave then
sSave = sSave:lower();
end
if sSave == "reflex" then
if EffectManager35E.hasEffectCondition(rSource, "Improved Evasion") or bHasImpEvasion then -- added the or condition
bAvoidDamage = true;
msgLong.text = msgLong.text .. " [IMPROVED EVASION]";
elseif EffectManager35E.hasEffectCondition(rSource, "Evasion") or bHasEvasion then -- added the or condition
bAvoidDamage = true;
msgLong.text = msgLong.text .. " [EVASION]";
end
end
end

if bAvoidDamage then
rAction.sResult = "none";
rAction.bRemoveOnMiss = false;
elseif bHalfDamage then
rAction.sResult = "half_success";
rAction.bRemoveOnMiss = false;
end

if rOrigin and rAction.bRemoveOnMiss then
TargetingManager.removeTarget(ActorManager.getCTNo deName(rOrigin), ActorManager.getCTNodeName(rSource));
end
end
else
msgLong.text = msgLong.text .. " [FAILURE]";

if rSource then
local bHalfDamage = false;
if bHalfMatch then
local sSave = rAction.sDesc:match("%[SAVE%] (%w+)");
if sSave then
sSave = sSave:lower();
end
if sSave == "reflex" then
if EffectManager35E.hasEffectCondition(rSource, "Improved Evasion") or bHasImpEvasion then -- added the or condition
bHalfDamage = true;
msgLong.text = msgLong.text .. " [IMPROVED EVASION]";
end
end
end

if bHalfDamage then
rAction.sResult = "half_failure";
end
end
end

ActionsManager.outputResult(rAction.bSecret, rSource, rOrigin, msgLong, msgShort);

if rSource and rOrigin then
ActionDamage.setDamageState(rOrigin, rSource, StringManager.trim(sAttack), rAction.sResult);
end
end

Will have to add Manager_char.lua changes in post below this since its too long to submit all together

mr900rr
June 24th, 2018, 22:30
Manager_char.lua changes are marked in comments -- added and colored

function calcItemArmorClass(nodeChar)
local nMainArmorTotal = 0;
local nMainShieldTotal = 0;
-- added
local sArmorType = "None";
-- end added
local nMainMaxStatBonus = 0;
local nMainCheckPenalty = 0;
local nMainSpellFailure = 0;
local nMainSpeed30 = 0;
local nMainSpeed20 = 0;
for _,vNode in pairs(DB.getChildren(nodeChar, "inventorylist")) do
if DB.getValue(vNode, "carried", 0) == 2 then
local bIsArmor, _, sSubtypeLower = ItemManager2.isArmor(vNode);
if bIsArmor then
local bID = LibraryData.getIDState("item", vNode, true);

local bIsShield = (sSubtypeLower == "shield");
-- added
if DB.getValue(vNode, "type", "") == "Armor" then
if sSubtypeLower == "light" then
sArmorType = "Light";
elseif sSubtypeLower == "medium" then
sArmorType = "Medium";
elseif sSubtypeLower == "heavy" then
sArmorType = "Heavy";
else
sArmorType = "None";
end
end
-- end added
if bIsShield then
if bID then
nMainShieldTotal = nMainShieldTotal + DB.getValue(vNode, "ac", 0) + DB.getValue(vNode, "bonus", 0);
else
nMainShieldTotal = nMainShieldTotal + DB.getValue(vNode, "ac", 0);
end
else
if bID then
nMainArmorTotal = nMainArmorTotal + DB.getValue(vNode, "ac", 0) + DB.getValue(vNode, "bonus", 0);
else
nMainArmorTotal = nMainArmorTotal + DB.getValue(vNode, "ac", 0);
end

local nItemSpeed30 = DB.getValue(vNode, "speed30", 0);
if (nItemSpeed30 > 0) and (nItemSpeed30 < 30) then
if nMainSpeed30 > 0 then
nMainSpeed30 = math.min(nMainSpeed30, nItemSpeed30);
else
nMainSpeed30 = nItemSpeed30;
end
end
local nItemSpeed20 = DB.getValue(vNode, "speed20", 0);
if (nItemSpeed20 > 0) and (nItemSpeed20 < 30) then
if nMainSpeed20 > 0 then
nMainSpeed20 = math.min(nMainSpeed20, nItemSpeed20);
else
nMainSpeed20 = nItemSpeed20;
end
end
end


local nMaxStatBonus = DB.getValue(vNode, "maxstatbonus", 0);
if nMaxStatBonus > 0 then
if nMainMaxStatBonus > 0 then nMainMaxStatBonus = math.min(nMainMaxStatBonus, nMaxStatBonus);
else nMainMaxStatBonus = nMaxStatBonus;
end
end

local nCheckPenalty = DB.getValue(vNode, "checkpenalty", 0);
if nCheckPenalty < 0 then
nMainCheckPenalty = nMainCheckPenalty + nCheckPenalty;
end

local nSpellFailure = DB.getValue(vNode, "spellfailure", 0);
if nSpellFailure > 0 then
nMainSpellFailure = nMainSpellFailure + nSpellFailure;
end
end
end
end

DB.setValue(nodeChar, "ac.sources.armor", "number", nMainArmorTotal);
DB.setValue(nodeChar, "ac.sources.shield", "number", nMainShieldTotal);
if nMainMaxStatBonus > 0 then
DB.setValue(nodeChar, "encumbrance.armormaxstatbonusactive", "number", 1);
DB.setValue(nodeChar, "encumbrance.armormaxstatbonus", "number", nMainMaxStatBonus);
else
DB.setValue(nodeChar, "encumbrance.armormaxstatbonusactive", "number", 0);
DB.setValue(nodeChar, "encumbrance.armormaxstatbonus", "number", 0);
end
-- added
DB.setValue(nodeChar, "encumbrance.armortype", "string", sArmorType);
-- end added
DB.setValue(nodeChar, "encumbrance.armorcheckpenalty", "number", nMainCheckPenalty);
DB.setValue(nodeChar, "encumbrance.spellfailure", "number", nMainSpellFailure);

local bApplySpeedPenalty = true;
if hasTrait(nodeChar, "Slow and Steady") then
bApplySpeedPenalty = false;
end

local nSpeedBase = DB.getValue(nodeChar, "speed.base", 0);
local nSpeedArmor = 0;
if bApplySpeedPenalty then
if (nSpeedBase >= 30) and (nMainSpeed30 > 0) then
nSpeedArmor = nMainSpeed30 - 30;
elseif (nSpeedBase < 30) and (nMainSpeed20 > 0) then
nSpeedArmor = nMainSpeed20 - 20;
end
end
DB.setValue(nodeChar, "speed.armor", "number", nSpeedArmor);
local nSpeedTotal = nSpeedBase + nSpeedArmor + DB.getValue(nodeChar, "speed.misc", 0) + DB.getValue(nodeChar, "speed.temporary", 0);
DB.setValue(nodeChar, "speed.final", "number", nSpeedTotal);
end

damned
June 25th, 2018, 04:20
If you dont get a response from Moon Wizard in a fistful of days you could send an email to support@ and flag it Code Enhancement Attn: Moon Wizard

It may be something he deems to be best done in extension or he may agree with your view.

mr900rr
June 25th, 2018, 06:05
Thanks damned, I shall wait and see, meanwhile I just added it into my Advanced Character Sheet extension I use in my current games.