David M. said: Lionel, the following Turn Undead update checks for resistance/immunity in the npctrait repeating section of the 5e npc character sheet and updates the logic accordingly. Note: this macro requires scriptcards and radar scripts (though the latter can be removed from the macro if you don't want the animation). It also uses a custom statusmarker (Fear::1510130). You should change that to a statusmarker of your choosing, found in the FailedSave procedure. !script {{
--#title|@{selected|character_name} Turns Undead!
--#leftsub|Save DC @{selected|spell_save_dc}
--:(0) CREATE AN ANIMATED WAVEFRONT WITH RADAR SCRIPT| uses SelectManager to retain selected token
--@forselected|radar_range|30ft _pinglife|0 _wavedelay|20 _wavespacing|10 _silent|true
--:(1) DETERMINE CR OF UNDEAD THAT CAN BE DESTROYED|
--=charLevel|@{selected|level}
--?[$charLevel] -lt 5|>SetCRdestroy;0
--?[$charLevel] -ge 5 -and [$charLevel] -lt 8|>SetCRdestroy;0.5
--?[$charLevel] -ge 8 -and [$charLevel] -lt 11|>SetCRdestroy;1
--?[$charLevel] -ge 11 -and [$charLevel] -lt 14|>SetCRdestroy;2
--?[$charLevel] -ge 14 -and [$charLevel] -lt 17|>SetCRdestroy;3
--?[$charLevel] -ge 17|>SetCRdestroy;4
--:(2) GET ALL TOKENS INTO THE "allTokens" ARRAY| will have blank 1st element to be removed later
--~|array;pagetokens;allTokens;@{selected|token_id}
--:(3) CREATE THE "inRange" ARRAY TO HOLD TOKENS IN RANGE|
--~|array;define;inRange;
--:(4) PREP ARRAY FOR LOOP| if no array elements then end macro
--~tokenid|array;getfirst;allTokens
--?[&tokenid] -eq ArrayError|endOutput
--:(5) FIND ALL TOKENS IN RANGE|
--:RangeLoop|
--:TOKEN MUST BE ON OBJECTS OR GMLAYER AND TYPE MUST INCLUDE UNDEAD|
--?[*[&tokenid]:t-layer] -ne objects -and [*[&tokenid]:t-layer] -ne gmlayer|NextToken
--?"[*[&tokenid]:npc_type]" -ninc "undead"|NextToken
--:CHECK DISTANCE IN UNITS. 30ft is 6UNITS|
--~dist|euclideandistance;@{selected|token_id};[&tokenid]
--?[$dist] -gt 6|NextToken
--:ADD TO THE "inRange" ARRAY|
--~|array;add;inRange;[&tokenid]
--:NextToken|
--~tokenid|array;getnext;allTokens
--?[&tokenid] -ne ArrayError|RangeLoop
--:(6) REMOVE DUMMY FIRST ITEM IN inRange ARRAY|
--~|array;removeat;inRange;0
--:(7) ROLL SAVES FOR EACH TOKEN IN RANGE| if fail, set a token condition marker to denote turned
--~tokenid|array;getfirst;inRange
--?[&tokenid] -eq ArrayError|End
--:SaveLoop|
-->CheckResistImmunity|[&tokenid]
--?[$immune] -eq 1|>PrintImmune
-->GetSaveBonus|[&tokenid];wisdom;wis
--?[$resistant] -eq 1|[
--=SaveRoll|2d20kh1 + [$saveBonus] [BONUS]
--]|[
--=SaveRoll|1d20 + [$saveBonus] [BONUS]
--]|
--?[$SaveRoll.Total] -ge @{selected|spell_save_dc} -and [$immune] -eq 0|>MadeSave|
--?[$SaveRoll.Total] -lt @{selected|spell_save_dc} -and [$immune] -eq 0|>FailedSave
--~tokenid|array;getnext;inRange
--?[&tokenid] -ne ArrayError|SaveLoop
--:End|
--X|
--:PROCEDURES|
--:CheckResistImmunity|
--Rfirst|[*[%1%]:character_id];repeating_npctrait
--?"[*R:name]" -eq "NoRepeatingAttributeLoaded"|[
--=resistant|0
--=immune|0
--^LIST_END|
--]|
--:CheckTraits| Start of loop
--=resistant|0
--=immune|0
--?"[*R:name]" -inc "Turn Immunity"|=immune;1
--?"[*R:name]" -inc "Turn Resistance"|=resistant;1
--?[$immune] -eq 1 -or [$resistant] -eq 1|[
--<| early return
--]|
--Rnext|
--?"[*R:[&Rname]]" -ne "NoRepeatingAttributeLoaded"|CheckTraits
--:LIST_END |
--<|
--:SetCRdestroy| accepts CR as parameter
--=CRdestroy|[%1%]
--<|
--:GetSaveBonus| accepts tokenid, full attribute name, short attribute name as parameters
--:TAKE THE GREATER OF "attribute_save_bonus" OR "npc_attr_save"|
--=bonus1|[*[%1%]:[%2%]_save_bonus]
--&bonus2|[*[%1%]:npc_[%3%]_save_base]
--:SOMETIMES "npc_attr_save_base" IS BLANK, SO SET TO -99. OTHERWISE USE ATTR VALUE|
--?X[&bonus2] -eq "X"|>Set_npc_attr_save_bonus;-99|>Set_npc_attr_save_bonus;[&bonus2]
--:FINALLY SET THE SAVE BONUS|
--?[$bonus2] -gt [$bonus1]|>SetSaveBonus;[$bonus2]|>SetSaveBonus;[$bonus1]
--<|
--:Set_npc_attr_save_bonus| blank value is set to -99, otherwise use value stored in attribute
--=bonus2|[%1%]
--<|
--:SetSaveBonus|
--=saveBonus|[%1%]
--<|
--:MadeSave|
--+[*[&tokenid]:character_name]:|[#009900][b]Made Save[/b][/#] [$SaveRoll]
--<|
--:PrintImmune|
--+[*[&tokenid]:character_name]:|[#009900][b]Immune![/b][/#]
--<|
--:FailedSave| add either a dead or fear condition marker to the token, depending on CR
--+[*[&tokenid]:character_name]:|[#990000][b]Failed Save[/b][/#] [$SaveRoll]
--=CR|[*[&tokenid]:npc_challenge]
--?[$CR] -le [$CRdestroy]|>AddConditionMarker;[&tokenid];dead|>AddConditionMarker;[&tokenid];Fear::1510130
--<|
--:AddConditionMarker| accepts tokenID and condition marker as parameter
--@token-mod|_ignore-selected _ids [%1%] _set statusmarkers|[%2%]
--<|
}} Hey David thank you so much that will help grandly in achieving what i needed. I'll have to insert in the npc traits a text that says turn immunity or turn resistance so it is found properly in the script. I've modified the radar part to a spawn holyburst thing. and i've also added the function in hiding the name of the creature in the results for the players, but not for the gm I see that you refer to npc_repeatingtraits in the script, How would i refer to Resistances or immunities field ? would it need to look in 2 different places and thus would complicate the script ? It works fine like that for the turn undead, but i'm already thinking of using this procedure in checking for damages resistances or immunities in some scriptcards (scorching ray for example) here's my resulting scriptcard : !script {{
--#title|@{selected|character_name} Renvoie les Impies!
--#leftsub|JP DD @{selected|spell_save_dc}
--:(0) CREATE AN ANIMATED EFFECT WITH SPAWN SCRIPT| uses SelectManager to retain selected token
--@forselected|Spawn _name|HolyBurst _expand|50,50, true _size|13,13 _order|tofront
--:(1) DETERMINE CR OF UNDEAD THAT CAN BE DESTROYED|
--=charLevel|@{selected|level}
--?[$charLevel] -lt 5|>SetCRdestroy;0
--?[$charLevel] -ge 5 -and [$charLevel] -lt 8|>SetCRdestroy;0.5
--?[$charLevel] -ge 8 -and [$charLevel] -lt 11|>SetCRdestroy;1
--?[$charLevel] -ge 11 -and [$charLevel] -lt 14|>SetCRdestroy;2
--?[$charLevel] -ge 14 -and [$charLevel] -lt 17|>SetCRdestroy;3
--?[$charLevel] -ge 17|>SetCRdestroy;4
--:(2) GET ALL TOKENS INTO THE "allTokens" ARRAY| will have blank 1st element to be removed later
--~|array;pagetokens;allTokens;@{selected|token_id}
--:(3) CREATE THE "inRange" ARRAY TO HOLD TOKENS IN RANGE|
--~|array;define;inRange;
--:(4) PREP ARRAY FOR LOOP| if no array elements then end macro
--~tokenid|array;getfirst;allTokens
--?[&tokenid] -eq ArrayError|endOutput
--:(5) FIND ALL TOKENS IN RANGE|
--:RangeLoop|
--:TOKEN MUST BE ON OBJECTS OR GMLAYER AND TYPE MUST INCLUDE UNDEAD|
--?[*[&tokenid]:t-layer] -ne objects -and [*[&tokenid]:t-layer] -ne gmlayer|NextToken
--?"[*[&tokenid]:npc_type]" -ninc "undead"|NextToken
--:CHECK DISTANCE IN UNITS. 30ft is 6UNITS|
--~dist|distance;@{selected|token_id};[&tokenid]
--?[$dist] -gt 6|NextToken
--:ADD TO THE "inRange" ARRAY|
--~|array;add;inRange;[&tokenid]
--:NextToken|
--~tokenid|array;getnext;allTokens
--?[&tokenid] -ne ArrayError|RangeLoop
--:(6) REMOVE DUMMY FIRST ITEM IN inRange ARRAY|
--~|array;removeat;inRange;0
--:(7) ROLL SAVES FOR EACH TOKEN IN RANGE| if fail, set a token condition marker to denote turned
--~tokenid|array;getfirst;inRange
--?[&tokenid] -eq ArrayError|End
--:SaveLoop|
-->CheckResistImmunity|[&tokenid]
--?[$immune] -eq 1|>PrintImmune
-->GetSaveBonus|[&tokenid];wisdom;wis
--?[$resistant] -eq 1|[
--=SaveRoll|2d20kh1 + [$saveBonus] [BONUS]
--]|[
--=SaveRoll|1d20 + [$saveBonus] [BONUS]
--]|
--?[$SaveRoll.Total] -ge @{selected|spell_save_dc} -and [$immune] -eq 0|>MadeSave|
--?[$SaveRoll.Total] -lt @{selected|spell_save_dc} -and [$immune] -eq 0|>FailedSave
--~tokenid|array;getnext;inRange
--?[&tokenid] -ne ArrayError|SaveLoop
--:End|
--X|
--:PROCEDURES|
--:CheckResistImmunity|
--Rfirst|[*[%1%]:character_id];repeating_npctrait
--?"[*R:name]" -eq "NoRepeatingAttributeLoaded"|[
--=resistant|0
--=immune|0
--^LIST_END|
--]|
--:CheckTraits| Start of loop
--=resistant|0
--=immune|0
--?"[*R:name]" -inc "Turn Immunity"|=immune;1
--?"[*R:name]" -inc "Turn Resistance"|=resistant;1
--?[$immune] -eq 1 -or [$resistant] -eq 1|[
--<| early return
--]|
--Rnext|
--?"[*R:[&Rname]]" -ne "NoRepeatingAttributeLoaded"|CheckTraits
--:LIST_END |
--<|
--:SetCRdestroy| accepts CR as parameter
--=CRdestroy|[%1%]
--<|
--:GetSaveBonus| accepts tokenid, full attribute name, short attribute name as parameters
--:TAKE THE GREATER OF "attribute_save_bonus" OR "npc_attr_save"|
--=bonus1|[*[%1%]:[%2%]_save_bonus]
--&bonus2|[*[%1%]:npc_[%3%]_save_base]
--:SOMETIMES "npc_attr_save_base" IS BLANK, SO SET TO -99. OTHERWISE USE ATTR VALUE|
--?X[&bonus2] -eq "X"|>Set_npc_attr_save_bonus;-99|>Set_npc_attr_save_bonus;[&bonus2]
--:FINALLY SET THE SAVE BONUS|
--?[$bonus2] -gt [$bonus1]|>SetSaveBonus;[$bonus2]|>SetSaveBonus;[$bonus1]
--<|
--:Set_npc_attr_save_bonus| blank value is set to -99, otherwise use value stored in attribute
--=bonus2|[%1%]
--<|
--:SetSaveBonus|
--=saveBonus|[%1%]
--<|
--:MadeSave|
--*[*[&tokenid]:character_name]:|[#009900][b]JP Réussi[/b][/#] [$SaveRoll]
--+Creature [%1%]:|[#009900][b]JP Réussi[/b][/#] [$SaveRoll]
--<|
--:PrintImmune|
--*[*[&tokenid]:character_name]:|[#009900][b]Immunisé![/b][/#]
--+Creature [%1%]:|[#009900][b]Immunisée![/b][/#] [$SaveRoll]
--<|
--:FailedSave| add either a dead or fear condition marker to the token, depending on CR
--=CR|[*[&tokenid]:npc_challenge]
--?[$CR] -le [$CRdestroy]|>AddConditionMarker;[&tokenid];Mort::4017244;-Dest.|>AddConditionMarker;[&tokenid];Effraye2::4023355;-Peur
--*[*[&tokenid]:character_name]:|[#990000][b]JP Raté[/b][/#] [$SaveRoll] [b][&FailureText][/b]
--+Creature [%1%]:|[#990000][b]JP Raté[/b][/#] [$SaveRoll] [b][&FailureText][/b]
--<|
--:AddConditionMarker| accepts tokenID, condition marker, and descriptive text as parameters
--@token-mod|_ignore-selected _ids [%1%] _set statusmarkers|[%2%]
--&FailureText|[%3%]
--<|
}}