Scriptcard for Cone of Cold Spell Based off of Kurt's Burning Hands Scriptcard Can be used for Breath Weapon attack of Dragon by changing damage type. Or prompt for damage type with ?{Damage Type|acid|cold|fire|lightning|poison} Arrays are expanded for 60 ft cones (I used Excel to map out the cells). Visually, the Up, Down, Left and Right arrays are overlapped by the Diagonals, but the arrays are the full area of effect. Expanded Saving Throws section to show if target was Resistant, Immune or Vulnerable Maybe some other changes, since I based this off my Burning Hands script which was based on Kurt's !script {{ --/|Based on Kurt's Burning Hands script. Updated arrays for 60' cone and other parameters. --&spellName|Cone of Cold --/|Note: because the spell will be cast at a min level of 5, we use 3 here to get the total dice (3+5=8) --&spellL0DamageDice|3 --/|Prompt for the spell level. Update this to account for the minimum level of the spell --=SpellLevel|?{Spell Slot Level?|5|6|7|8|9} --&spellDamageDieType|8 --&damageType|cold --&saveType|constitution --&tokenVFX|burn-frost --&lineVFX|breath-frost --/|Set this to either "token-mod", "alterbars", or anything else to not apply damage --&damageApplyScript|token-mod --/|Set this to the bar number you use to track hit points --&hitPointsBar|1 --/|Set this to a list of layers to a semicolon separated check for tokens on. By default, objects and gmlayer are checked. --/|possible values are objects, gmlayer, and map, so to check all three, use "objects;gmlayer;map" --&checkLayers|objects --/|Source Token is the caster, and target token is the "end of the line". Can be a non-creature (no represents) token. --#sourcetoken|@{selected|token_id} --/|Get all of the tokens on the page so we can cache their positions --~|array;pagetokens;alltokens;@{selected|token_id} --#leftsub|Save DC @{selected|spell_save_dc} --#rightsub|Spell Level: [$SpellLevel] --#title|[&spellName] --#emoteBackground|#eeffee --#emoteText|*@{selected|token_name} casts [&spellName].* -->GetAndCheckSlotInformation| -->DeductSpellSlot| --/|Calculate damage based on spell slot. --=DamageDice|[$SpellLevel.Total] + [&spellL0DamageDice] --=Damage|[$DamageDice.Total]d[&spellDamageDieType] --=HalfDamage|[$Damage.Total] \ 2 --=DoubleDamage|[$Damage.Total] * 2 --=ImmuneDamage|[$Damage.Total] * 0 --=QuarterDamage|[$Damage.Total] \ 4 --/|Determine damage subroutine. Start by assuming we aren't going to apply damage --&damageRoutine|DontApplyDamage --?[&damageApplyScript] -eq "token-mod"|&damageRoutine;ApplyDamageTokenmod --?[&damageApplyScript] -eq "alterbars"|&damageRoutine;ApplyDamageAlterbars --/|Since we want to be able to hover over a roll and see the dice details, output the rolled damage at the --/|top of the card. If all critters make their save, the half damage roll won't contain the details. --+|[c][b]Damage Roll: [/b][$Damage][/c] --+|[c]60ft cone, [$Damage.RollText] [&damageType] damage[/c] --/|Create an array to hold the tokens that are intersected by the line. --~|array;define;tokensHit; -->createTokenLookup| --/|Prompt for a direction for the cast, and define arrays that indicate the relative spaces that will be hit. --&direction|?{Direction|&#x2B06; (UP),U|&#x2197; (UP-RIGHT),UR|&#x27A1; (RIGHT),R|&#x2198; (DOWN-RIGHT),DR|&#x2B07; (DOWN),D|&#x2199; (DOWN-LEFT),DL|&#x2B05; (LEFT),L|&#x2196 (UP-LEFT);,UL|} --~|array;define;U;0,-1;-1,-2;0,-2;1,-2;-1,-3;0,-3;1,-3;-2,-4;-1,-4;0,-4;1,-4;2,-4;-2,-5;-1,-5;0,-5;1,-5;2,-5;-3,-6;-2,-6;-1,-6;0,-6;1,-6;2,-6;3,-6;-3,-7;-2,-7;-1,-7;0,-7;1,-7;2,-7;3,-7;-4,-8;-3,-8;-2,-8;-1,-8;0,-8;1,-8;2,-8;3,-8;4,-8;-4,-9;-3,-9;-2,-9;-1,-9;0,-9;1,-9;2,-9;3,-9;4,-9;-5,-10;-4,-10;-3,-10;-2,-10;-1,-10;0,-10;1,-10;2,-10;3,-10;4,-10;5,-10;-5,-11;-4,-11;-3,-11;-2,-11;-1,-11;0,-11;1,-11;2,-11;3,-11;4,-11;5,-11;-6,-12;-5,-12;-4,-12;-3,-12;-2,-12;-1,-12;0,-12;1,-12;2,-12;3,-12;4,-12;5,-12;6,-12 --~|array;define;D;0,1;-1,2;0,2;1,2;-1,3;0,3;1,3;-2,4;-1,4;0,4;1,4;2,4;-2,5;-1,5;0,5;1,5;2,5;-3,6;-2,6;-1,6;0,6;1,6;2,6;3,6;-3,7;-2,7;-1,7;0,7;1,7;2,7;3,7;-4,8;-3,8;-2,8;-1,8;0,8;1,8;2,8;3,8;4,8;-4,9;-3,9;-2,9;-1,9;0,9;1,9;2,9;3,9;4,9;-5,10;-4,10;-3,10;-2,10;-1,10;0,10;1,10;2,10;3,10;4,10;5,10;-5,11;-4,11;-3,11;-2,11;-1,11;0,11;1,11;2,11;3,11;4,11;5,11;-6,12;-5,12;-4,12;-3,12;-2,12;-1,12;0,12;1,12;2,12;3,12;4,12;5,12;6,12 --~|array;define;R;1,0;2,-1;2,0;2,1;3,-1;3,0;3,1;4,-2;4,-1;4,0;4,1;4,2;5,-2;5,-1;5,0;5,1;5,2;6,-3;6,-2;6,-1;6,0;6,1;6,2;6,3;7,-3;7,-2;7,-1;7,0;7,1;7,2;7,3;8,-4;8,-3;8,-2;8,-1;8,0;8,1;8,2;8,3;8,4;9,-4;9,-3;9,-2;9,-1;9,0;9,1;9,2;9,3;9,4;10,-5;10,-4;10,-3;10,-2;10,-1;10,0;10,1;10,2;10,3;10,4;10,5;11,-5;11,-4;11,-3;11,-2;11,-1;11,0;11,1;11,2;11,3;11,4;11,5;12,-6;12,-5;12,-4;12,-3;12,-2;12,-1;12,0;12,1;12,2;12,3;12,4;12,5;12,6 --~|array;define;L;-1,0;-2,-1;-2,0;-2,1;-3,-1;-3,0;-3,1;-4,-2;-4,-1;-4,0;-4,1;-4,2;-5,-2;-5,-1;-5,0;-5,1;-5,2;-6,-3;-6,-2;-6,-1;-6,0;-6,1;-6,2;-6,3;-7,-3;-7,-2;-7,-1;-7,0;-7,1;-7,2;-7,3;-8,-4;-8,-3;-8,-2;-8,-1;-8,0;-8,1;-8,2;-8,3;-8,4;-9,-4;-9,-3;-9,-2;-9,-1;-9,0;-9,1;-9,2;-9,3;-9,4;-10,-5;-10,-4;-10,-3;-10,-2;-10,-1;-10,0;-10,1;-10,2;-10,3;-10,4;-10,5;-11,-5;-11,-4;-11,-3;-11,-2;-11,-1;-11,0;-11,1;-11,2;-11,3;-11,4;-11,5;-12,-6;-12,-5;-12,-4;-12,-3;-12,-2;-12,-1;-12,0;-12,1;-12,2;-12,3;-12,4;-12,5;-12,6 --~|array;define;UR;1,-1;1,-2;1,-3;2,-1;2,-2;2,-3;2,-4;2,-5;2,-6;3,-1;3,-2;3,-3;3,-4;3,-5;3,-6;3,-7;3,-8;3,-9;4,-2;4,-3;4,-4;4,-5;4,-6;4,-7;4,-8;4,-9;4,-10;4,-11;4,-12;5,-2;5,-3;5,-4;5,-5;5,-6;5,-7;5,-8;5,-9;5,-10;5,-11;5,-12;5,-13;6,-2;6,-3;6,-4;6,-5;6,-6;6,-7;6,-8;6,-9;6,-10;6,-11;6,-12;7,-3;7,-4;7,-5;7,-6;7,-7;7,-8;7,-9;7,-10;7,-11;8,-3;8,-4;8,-5;8,-6;8,-7;8,-8;8,-9;8,-10;9,-3;9,-4;9,-5;9,-6;9,-7;9,-8;9,-9;10,-4;10,-5;10,-6;10,-7;10,-8;11,-4;11,-5;11,-6;11,-7;12,-4;12,-5;12,-6;13,-5 --~|array;define;DR;1,1;2,1;3,1;1,2;2,2;3,2;4,2;5,2;6,2;1,3;2,3;3,3;4,3;5,3;6,3;7,3;8,3;9,3;2,4;3,4;4,4;5,4;6,4;7,4;8,4;9,4;10,4;11,4;12,4;2,5;3,5;4,5;5,5;6,5;7,5;8,5;9,5;10,5;11,5;12,5;13,5;2,6;3,6;4,6;5,6;6,6;7,6;8,6;9,6;10,6;11,6;12,6;3,7;4,7;5,7;6,7;7,7;8,7;9,7;10,7;11,7;3,8;4,8;5,8;6,8;7,8;8,8;9,8;10,8;3,9;4,9;5,9;6,9;7,9;8,9;9,9;4,10;5,10;6,10;7,10;8,10;4,11;5,11;6,11;7,11;4,12;5,12;6,12;5,13 --~|array;define;UL;-1,-1;-1,-2;-1,-3;-2,-1;-2,-2;-2,-3;-2,-4;-2,-5;-2,-6;-3,-1;-3,-2;-3,-3;-3,-4;-3,-5;-3,-6;-3,-7;-3,-8;-3,-9;-4,-2;-4,-3;-4,-4;-4,-5;-4,-6;-4,-7;-4,-8;-4,-9;-4,-10;-4,-11;-4,-12;-5,-2;-5,-3;-5,-4;-5,-5;-5,-6;-5,-7;-5,-8;-5,-9;-5,-10;-5,-11;-5,-12;-5,-13;-6,-2;-6,-3;-6,-4;-6,-5;-6,-6;-6,-7;-6,-8;-6,-9;-6,-10;-6,-11;-6,-12;-7,-3;-7,-4;-7,-5;-7,-6;-7,-7;-7,-8;-7,-9;-7,-10;-7,-11;-8,-3;-8,-4;-8,-5;-8,-6;-8,-7;-8,-8;-8,-9;-8,-10;-9,-3;-9,-4;-9,-5;-9,-6;-9,-7;-9,-8;-9,-9;-10,-4;-10,-5;-10,-6;-10,-7;-10,-8;-11,-4;-11,-5;-11,-6;-11,-7;-12,-4;-12,-5;-12,-6;-13,-5 --~|array;define;DL;-1,1;-1,2;-1,3;-2,1;-2,2;-2,3;-2,4;-2,5;-2,6;-3,1;-3,2;-3,3;-3,4;-3,5;-3,6;-3,7;-3,8;-3,9;-4,2;-4,3;-4,4;-4,5;-4,6;-4,7;-4,8;-4,9;-4,10;-4,11;-4,12;-5,2;-5,3;-5,4;-5,5;-5,6;-5,7;-5,8;-5,9;-5,10;-5,11;-5,12;-5,13;-6,2;-6,3;-6,4;-6,5;-6,6;-6,7;-6,8;-6,9;-6,10;-6,11;-6,12;-7,3;-7,4;-7,5;-7,6;-7,7;-7,8;-7,9;-7,10;-7,11;-8,3;-8,4;-8,5;-8,6;-8,7;-8,8;-8,9;-8,10;-9,3;-9,4;-9,5;-9,6;-9,7;-9,8;-9,9;-10,4;-10,5;-10,6;-10,7;-10,8;-11,4;-11,5;-11,6;-11,7;-12,4;-12,5;-12,6;-13,5 --/|Call the "checkForTokenHits" subroutine. The passed parameter will be the per-space VFX. Leave blank for none. -->checkForTokenHits|[&tokenVFX] --/|The first item in the array will be a blank dummy item, so remove it. --~|array;removeat;tokensHit;0 --/|Loop through the tokensHit tokens and roll saves for each one and apply damage --~tokenid|array;getfirst;tokensHit --?[&tokenid] -eq ArrayError|endOutput --:loopDisplay| --=SaveRoll|1d20 + [*[&tokenid]:[&saveType]_save_bonus] --/|Make the Saving Throw, checking whether creature is immune, resistant, or vulnerable. Output Result and Apply Damage. --/|Compare the save roll to the save DC and either apply full or half damage --?"[*[&tokenid]:npc_immunities]" -inc "[&damageType]"|Immune --?"[*[&tokenid]:npc_resistances]" -inc "[&damageType]"|Resistant --?"[*[&tokenid]:npc_vulnerabilities]" -inc "[&damageType]"|Vulnerable --?[$SaveRoll.Total] -lt @{selected|spell_save_dc}|>FailedSave|>madeSave --/|Here are various damage applications if the creature is immune, resistant, or vulnerable. In some cases, we will reuse output lines, --/|for example, a resistant creature that fails its save will jump to "madeSave", since that is the correct damage amount. (half), while --/|a vulnerable creature that makes its save will jump to "FailedSave" since that will be normal damage. --/|Output a line, apply damage and add status marker for a failed saving throw --:FailedSave| -->[&damageRoutine]|[&tokenid];[&hitPointsBar];[$Damage.Total] --+[*[&tokenid]:t-name]:|Fail [r][$Damage] [&damageType][/r] --^afterSave| --:Immune| --+[*[&tokenid]:t-name]:|Immune [r][$ImmuneDamage] [&damageType][/r] --^afterSave| --:Resistant| --?[$SaveRoll.Total] -lt @{selected|spell_save_dc}|>ResistantFail|>ResistantSave --^afterSave| --/|Output a line and apply damage for a successful saving throw for Resistant --:ResistantSave| -->[&damageRoutine]|[&tokenid];[&hitPointsBar];[$QuarterDamage.Total] --+[*[&tokenid]:t-name]:|Save (Resistant) [r][$QuarterDamage] [&damageType][/r] --^afterSave| --/|Output a line, apply damage and add status marker for a failed saving throw for Resistant --:ResistantFail| -->[&damageRoutine]|[&tokenid];[&hitPointsBar];[$HalfDamage.Total] --+[*[&tokenid]:t-name]:|Fail (Resistant) [r][$HalfDamage] [&damageType][/r] --^afterSave| --:Vulnerable| --?[$SaveRoll.Total] -lt @{selected|spell_save_dc}|>VulnerableFail|>VulnerableSave --^afterSave| --/|Output a line for a successful saving throw for Vulnerable --:VulnerableSave| -->[&damageRoutine]|[&tokenid];[&hitPointsBar];[$Damage.Total] --+[*[&tokenid]:t-name]:|Save (Vulnerable) [r][$Damage] [&damageType][/r] --^afterSave| --/|Output a line, apply damage and status marker for a failed saving throw for Vulnerable --:VulnerableFail| -->[&damageRoutine]|[&tokenid];[&hitPointsBar];[$DoubleDamage.Total] --+[*[&tokenid]:t-name]:|Fail (Vulnerable) [r][$DoubleDamage] [&damageType][/r] --^afterSave| --/|Output a line and apply damage for a successful saving throw --:madeSave| -->[&damageRoutine]|[&tokenid];[&hitPointsBar];[$HalfDamage.Total] --+[*[&tokenid]:t-name]:|Save [r][$HalfDamage] [&damageType][/r] --:afterSave| --~tokenid|array;getnext;tokensHit --?[&tokenid] -ne ArrayError|loopDisplay --/|Put a visual effect on impacted tokens --vtoken|[&tokenid] [&tokenVFX] --~tokenid|array;getnext;inRange --?[&tokenid] -ne ArrayError|loopDisplay --/|Add some extra visual effects - a nova-fire at the target, and a beam-fire from source to target --vbetweentokens|@{selected|token_id} @{target|token_id} [&lineVFX] --:endOutput| --X| --:ApplyDamageTokenmod|Parameters are tokenid;bar#;amount --@token-mod|_ignore-selected _ids [%1%] _set bar[%2%]_value|-[%3%]! --<| --/|AlterBars supports relative values for the amount parameter, so we just pass it the value with a "-" in front of it. --:ApplyDamageAlterbars|Parameters are tokenid;bar#;amount --@alter|_target|[%1%] _bar|[%2%] _amount|-[%3%] _show|none --<| --/|Just a dummy routine that doesn't do anything, but it is easier to do it this way than adding logic to see if we are --/|skipping applying damage in the main routine. --:DontApplyDamage| --<| --:checkForTokenHits|parameter is vfx descriptor --=baseX|[*S:t-left] - 1 \ 70 --=baseY|[*S:t-top] - 1 \ 70 --~offset|array;getfirst;?{Direction} --:checkTokenLoop| --?"[&offset]" -eq "ArrayError"|endCheckForTokenHits --~split|string;split;,;[&offset] --=thisX|[$baseX] + [&split1] --=thisY|[$baseY] + [&split2] --/|IF we passed a visual effect specifier in %1%, create a point VFX in the square --?"X[%1%]X" -ne "XX" |[ --=VX|[$thisX] * 70 + 35 --=VY|[$thisY] * 70 + 35 --vpoint|[$VX] [$VY] [%1%] --]| -->checkTokens|[$thisX];[$thisY] --~offset|array;getnext;?{Direction} --^checkTokenLoop| --:endCheckForTokenHits| --<| --/|Reads the variables created by createTokenLookup to find any tokens that occupy a given space. --:checkTokens|x;y --?"X[&tok[%1%]-[%2%]]X" -ne "XX"|[ --~split|string;split;!;[&tok[%1%]-[%2%]] --%P|1;[$splitCount.Total];1 --=var|split[&P] --?"X[&[$var.RollText]]X" -eq "XX"|% --~exists|array;indexof;tokensHit;[&[$var.RollText]] --?[&exists] -ne ArrayError|skipAdd --?[&[$var.RollText]] -eq ArrayError|skipAdd --~|array;add;tokensHit;[&[$var.RollText]] --:skipAdd| --%| --<| --/|Creates a series of string variables with names like 'tok12-15' which represent the various squares that are --/|occupied by tokens on the page. Handle 1x1, 2x2, and 3x3 tokens by simply adding extra squares in the appropriate --/|pattern around the center point location. The result is that if there are two tokens at 12,15, the tok12-15 string --/|will contain something like "-asln34njfn2nafd!-sdnfklaserfs" (IDs separated by exclamation points) that we can use to --/|quickly evaluate hits by essentially asking "what is in square 12x15" by just reading the variable. --:createTokenLookup| --~tokenid|array;getfirst;alltokens --:tokenSetupLoop| --?[&tokenid] -eq ArrayError|endSetupLoop --?[&checkLayers] -ninc [*[&tokenid]:t-layer]|skipThisToken --?[*[&tokenid]:t-bar[&hitPointsBar]_value] -le 0|skipThisToken --=tLeft|[*[&tokenid]:t-left] - 1 \ 70 --=tTop|[*[&tokenid]:t-top] - 1 \ 70 --=tWidth|[*[&tokenid]:t-width] --?[$tWidth] -eq 70|[ --&tok[$tLeft]-[$tTop]|+[&tokenid]! --/+[*[&tokenid]:character_name]|At [$tLeft],[$tTop] : [&tok[$tLeft.Total]-[$tTop.Total]] --]| --?[$tWidth] -eq 140|[ --=NX|[$tLeft] + 1 --=NY|[$tTop] + 1 --&tok[$tLeft]-[$tTop]|+[&tokenid]! --&tok[$tLeft]-[$NY]|+[&tokenid]! --&tok[$NX]-[$tTop]|+[&tokenid]! --&tok[$NX]-[$NY]|+[&tokenid]! --]| --?[$tWidth] -eq 210|[ --=PX|[$tLeft] - 1 --=PY|[$tTop] - 1 --=NX|[$tLeft] + 1 --=NY|[$tTop] + 1 --&tok[$tLeft]-[$tTop]|+[&tokenid]! --&tok[$PX]-[$PY]|+[&tokenid]! --&tok[$tLeft]-[$PY]|+[&tokenid]! --&tok[$NX]-[$PY]|+[&tokenid]! --&tok[$PX]-[$tTop]|+[&tokenid]! --&tok[$NX]-[$tTop]|+[&tokenid]! --&tok[$PX]-[$NY]|+[&tokenid]! --&tok[$tLeft]-[$NY]|+[&tokenid]! --&tok[$NX]-[$NY]|+[&tokenid]! --]| --:skipThisToken| --~tokenid|array;getnext;alltokens --^tokenSetupLoop| --:endSetupLoop| --<| --:GetAndCheckSlotInformation| --=SlotLevel|[$SpellLevel] --=SlotsTotal|[*S:lvl[$SlotLevel]_slots_total] --=SlotsExpended|[*S:lvl[$SlotLevel]_slots_expended] --?[$SlotsExpended.Total] -eq 0|NoSlotsLeft --?[$SlotsExpended.Total] -gt [$SlotsTotal.Total]|NoSlotsLeft --<| --:DeductSpellSlot| --=SlotsExpended|[$SlotsExpended] -1 --@setattr|_charid [*S:character_id] _lvl[$SlotLevel]_slots_expended|[$SlotsExpended] _silent --=SlotsRemaining|[$SlotsTotal] - 1 --<| --:NoSlotsLeft| --+|[b][*S:character_name] has no level [$SlotLevel.Total] spell slots available.[/b] --X|NoSlotsLeftStop }}