FG Spreadshirt Swag
  1. #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
    Manager_action_save.lua changes are marked in comments -- added and colored
    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
    Will have to add Manager_char.lua changes in post below this since its too long to submit all together
    Last edited by mr900rr; June 24th, 2018 at 23:40.

  2. #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.

  3. #3
    damned's Avatar
    Join Date
    Mar 2011
    Location
    Australia
    Posts
    26,684
    Blog Entries
    1
    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.

  4. #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

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
DICE PACKS BUNDLE

Log in

Log in