-
June 24th, 2018, 22:28 #1
Question about Evasion and Improved Evasion functionality
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.
Code:<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
Code: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.getCTNodeName(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
Last edited by mr900rr; June 24th, 2018 at 23:40.
-
June 24th, 2018, 22:30 #2
Manager_char.lua changes are marked in comments -- added and colored
Code: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
Last edited by mr900rr; June 24th, 2018 at 23:02.
-
June 25th, 2018, 04:20 #3
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.
-
June 25th, 2018, 06:05 #4
Thanks damned, I shall wait and see, meanwhile I just added it into my Advanced Character Sheet extension I use in my current games.
Thread Information
Users Browsing this Thread
There are currently 1 users browsing this thread. (0 members and 1 guests)
Bookmarks