Code: Select all
<!-- PowerUseAttack-->
[H: DNT_DiceString = " + %s(%s)"]
[H: DNT_ModString = "%s(%s)"]
[H, forEach(DNT_Variable, "Slot, HideRoll, AttackSlot, AttackCount"): set("DNT_" + DNT_Variable, json.get(macro.args, DNT_Variable))]
[H: DNT_AbilityScores = DNA_AbilityScores]
<!-- reads out power variables and stores them in DNT_EntryVARIABLE -->
[H: DNT_Entry = getProperty("DNA_Power" + DNT_Slot)]
[H, forEach(DNT_Variable, "AttackType, AttackWeapon, AttackAbility, AttackBonus, NoImplement, AttackVS, CriticalRange, DamageSpecial, DamageDice, DamageAbility, DamageBonus, DamageType, CriticalDamage, Hit, Miss"): set("DNT_Entry" + DNT_Variable, json.get(DNT_Entry, DNT_Variable + DNT_AttackSlot))]
[H, switch(DNT_EntryAttackType):
case 1: DNT_TotalAttacks = 1;
case "Multi": DNT_TotalAttacks = if(json.get(macro.args, "NumberOfAttacks" + DNT_AttackSlot) == "", 1, json.get(macro.args, "NumberOfAttacks" + DNT_AttackSlot));
default: DNT_TotalAttacks = 0
]
<!-- Sets the equipped weapon and if empty (Due to either being a 0 slot item or a deleted item error) creates a virtual json object -->
[H: DNT_WeaponSlot = json.get(DNA_Equipped, DNT_EntryAttackWeapon) + 0]
[H: DNT_WeaponEntry = if(json.isEmpty(getProperty("DNA_Item" + DNT_WeaponSlot)) == 1, json.set("", "Name", "Nothing"), getProperty("DNA_Item" + DNT_WeaponSlot))]
<!-- reads out weapon variables and stores them in DNT_WeaponEntryVARIABLE-->
[H, forEach(DNT_Variable, "EnhancementAttack, EnhancementDamage, BaseProficiency, UserProficiency, CriticalRange, DamageDice, BaseDamage, UserDamage, CriticalDamage"): set("DNT_Weapon" + DNT_Variable, json.get(DNT_WeaponEntry, DNT_Variable))]
<!-- Determines power attack and damage bonus has to use the macro roll option of the regex because the eval does not work with the function version. unknown why. it then creates a evaled and a nonevaled version for display purposes-->
[H, if(DNT_EntryAttackAbility == ""): DNT_AttackAbility = 0; DNT_AttackAbility = json.get(json.get(DNT_AbilityScores, DNT_EntryAttackAbility), 2) + DNA_LevelBonus]
[H, macro("Replace@Lib:Sheet"): DNT_EntryAttackBonus]
[H: DNT_AttackBonus = macro.return]
[H, if(DNT_AttackBonus == ""): DNT_AttackBonus = 0]
[H, if(isNumber(DNT_AttackBonus) == 1), CODE:
{
[H: DNT_AttackBonusValue = DNT_AttackBonus]
};{
[H: DNT_AttackBonusValue = eval(DNT_AttackBonus)]
[H: DNT_AttackBonus = strformat(DNT_DiceString, DNT_AttackBonus, DNT_AttackBonusValue)]
}
]
[H, if(DNT_EntryDamageAbility == ""): DNT_DamageAbility = 0; DNT_DamageAbility = json.get(json.get(DNT_AbilityScores, DNT_EntryDamageAbility), 2)]
[H, macro("Replace@Lib:Sheet"): DNT_EntryDamageBonus]
[H: DNT_DamageBonus = macro.return]
[H, if(DNT_DamageBonus == ""): DNT_DamageBonus = 0]
[H, if(isNumber(DNT_DamageBonus) == 1), CODE:
{
[H: DNT_DamageBonusValue = DNT_DamageBonus]
};{
[H: DNT_DamageBonusValue = eval(DNT_DamageBonus)]
[H: DNT_DamageBonus = strformat(DNT_DiceString, DNT_DamageBonus, DNT_DamageBonusValue)]
}
]
[H: DNT_PowerAttack = DNT_AttackAbility + DNT_AttackBonusValue]
[H: PowerAttack = DNT_AttackAbility + DNT_AttackBonus]
[H: DNT_PowerDamage = DNT_DamageAbility + DNT_DamageBonusValue]
[H: PowerDamage = DNT_DamageAbility + DNT_DamageBonus]
<!-- determines the weapon attack and damage bonuses. if the power is implement keyword and the power isn't flagged as noimplement it clears the base proficiency and damage to allow for weapon based implements to not add the weapon portion to the attack. if the power is keyword implement and the weapon is not an implement and the power isn't flagged as noimplement it resets the whole weapon value-->
[H, if(json.contains(DNT_Entry, "KeywordImplement") == 1 && DNT_EntryNoImplement != 1), CODE:
{
[DNT_WeaponBaseProficiency = 0]
[DNT_WeaponBaseDamage = 0]
[DNT_WeaponDamageDice = "0d0"]
}
]
[H: WeaponAttack = number(0 + DNT_WeaponEnhancementAttack) + number(0 + DNT_WeaponBaseProficiency) + number(0 + DNT_WeaponUserProficiency)]
[H: WeaponDamage = number(0 + DNT_WeaponEnhancementDamage) + number(0 + DNT_WeaponBaseDamage) + number(0 + DNT_WeaponUserDamage)]
[H, if(json.contains(DNT_Entry, "KeywordImplement") == 1 && json.contains(DNT_WeaponEntry, "WeaponGroupImplement") == 0 && DNT_EntryNoImplement != 1), CODE:
{
[WeaponAttack = 0]
[WeaponDamage = 0]
}
]
<!-- The damage dice -->
[H: DNT_RawDamageDice = PowerDice(DNT_WeaponDamageDice, DNT_EntryDamageDice)]
<!-- determines highest crit range between weapon and power -->
[H, if(DNT_EntryCriticalRange == ""): DNT_EntryCriticalRange = 20]
[H, if(DNT_WeaponCriticalRange == ""): DNT_WeaponCriticalRange = 20]
[H: DNT_CriticalHit = min(DNT_EntryCriticalRange, DNT_WeaponCriticalRange)]
<!-- Determines crit damage -->
[H: DNT_MaxDamageRoll = listGet(stringToList(DNT_RawDamageDice, "d"), 0) * listGet(stringToList(stringToList(stringToList(stringToList(stringToList(DNT_RawDamageDice, "r"), "R"),"e"), "E"), "d"), 1)]
[H: PowerCritDamage = if(DNT_EntryCriticalDamage == "", 0, DNT_EntryCriticalDamage)]
[H: WeaponCritDamage = if(DNT_WeaponCriticalDamage == "", 0, DNT_WeaponCriticalDamage)]
[H: DNT_ScreenCheck = if(isGM() == 1 && getLibProperty("GMScreen", "Lib:Information") == 1, 1, 0)]
[R: if(DNT_AttackCount == 1 && DNT_ScreenCheck == 1, "<b>[Rolls behind the GM Screen]</b><br>", "")]
[R, for(DNT_AttackNumber, 1, DNT_TotalAttacks + 1, 1, ""), CODE:
{
<br>
[H: Die = if(json.get(macro.args, "GMDieRoll" + DNT_AttackCount) == "", 1d20, json.get(macro.args, "GMDieRoll" + DNT_AttackCount))]
[H: DNT_StaticAtkMods = 0]
[H, forEach(DNT_Mod, "Charge, Marked, CA, Long, Cover, Conceal"): DNT_StaticAtkMods = DNT_StaticAtkMods + json.get(macro.args, DNT_Mod + DNT_AttackCount)]
[H: AttackMods = if(json.get(macro.args, "AtkMod" + DNT_AttackCount) == "", 0, json.get(macro.args, "AtkMod" + DNT_AttackCount))]
[H, if(isNumber(AttackMods) == 1), CODE:
{
[H: AttackMods = AttackMods + DNT_StaticAtkMods]
[H: DNT_AtkMods = AttackMods]
};{
[H: DNT_AtkMods = eval(AttackMods) + DNT_StaticAtkMods]
[H: AttackMods = strformat(DNT_ModString, AttackMods + if(DNT_StaticAtkMods == 0, "", "+" + DNT_StaticAtkMods), DNT_AtkMods)]
}
]
[H: DamageMods = if(json.get(macro.args, "DmgMod" + DNT_AttackCount) == "", 0, json.get(macro.args, "DmgMod" + DNT_AttackCount))]
[H, if(isNumber(DamageMods) == 1), CODE:
{
[H: DNT_DmgMods = DamageMods]
};{
[H: DNT_DmgMods = eval(DamageMods)]
[H: DamageMods = strformat(DNT_ModString, DamageMods, DNT_DmgMods)]
}
]
<b>[R, switch(DNT_AttackSlot): case 1: ""; case 2: "2nd "; case 3: "3rd "; default: DNT_AttackSlot + "th "]Attack[R: if(DNT_EntryAttackType == "Multi", strformat(" #%{DNT_AttackNumber}"), "")]</b>[R, if(json.get(macro.args, "Target" + DNT_AttackCount) == ""): ""; " against " + getName(json.get(macro.args, "Target" + DNT_AttackCount))]:
[R, if(DNT_HideRoll == 1), CODE:
{
[GT, ST, T(if(Die == 1, "<b>Miss!</b>", Die + DNT_PowerAttack + WeaponAttack + DNT_AtkMods)): Die + PowerAttack + WeaponAttack + AttackMods]
};{
[T(if(Die == 1, "<b>Miss!</b>", Die + DNT_PowerAttack + WeaponAttack + DNT_AtkMods)): Die + PowerAttack + WeaponAttack + AttackMods]
}
]
vs
[R: DNT_EntryAttackVs]
[R, if(DNT_AttackNumber == 1 && DNT_EntryDamageSpecial != 1 && DNT_HideRoll != 1), CODE:
{
[H: DNT_DmgDiceResult = DiceRoll(DNT_RawDamageDice)]
[H: DamageDice = strformat("%s(%s)", DNT_RawDamageDice, DNT_DmgDiceResult)]
[H: DNT_TotalDamage = eval(string(DNT_DmgDiceResult)) + DNT_PowerDamage + WeaponDamage + DNT_DmgMods]
<b>Hit</b>: [T(DNT_TotalDamage): DamageDice + PowerDamage + WeaponDamage + DamageMods] [R: DNT_EntryDamageType] <span style="color:black">[R, switch(DNT_EntryDamageSpecial): case 2: macroLink("healing", "Health@Lib:Execute", "none", json.set("", "Type", 2, "Amount", DNT_TotalDamage), currentToken()); case 3: macroLink("HP + Surge", "Health@Lib:Execute", "none", json.set("", "Type", 3, "Amount", DNT_TotalDamage), currentToken()); case 4: macroLink("temp HP", "Health@Lib:Execute", "none", json.set("", "Type", 4, "Amount", DNT_TotalDamage), currentToken()); case 5: macroLink("HP + as if Surge", "Health@Lib:Execute", "none", json.set("", "Type", 5, "Amount", DNT_TotalDamage), currentToken()); case 6: macroLink("HP + costs Surge", "Health@Lib:Execute", "none", json.set("", "Type", 6, "Amount", DNT_TotalDamage), currentToken()); default: macroLink("damage", "Health@Lib:Execute", "none", json.set("", "Type", 0, "Amount", DNT_TotalDamage), currentToken())]</span>
};{
[H: ""]
}
]
[R, if(DNT_AttackNumber == 1 && DNT_EntryDamageSpecial != 1 && DNT_HideRoll == 1), CODE:
{
[H: DNT_DmgDiceResult = DiceRoll(DNT_RawDamageDice)]
[H: DamageDice = strformat("%s(%s)", DNT_RawDamageDice, DNT_DmgDiceResult)]
[H: DNT_TotalDamage = eval(string(DNT_DmgDiceResult)) + DNT_PowerDamage + WeaponDamage + DNT_DmgMods]
<b>Hit</b>: [GT, ST, T(DNT_TotalDamage): DamageDice + PowerDamage + WeaponDamage + DamageMods] [R: DNT_EntryDamageType] <span style="color:black">[R, switch(DNT_EntryDamageSpecial): case 2: macroLink("healing", "Health@Lib:Execute", "none", json.set("", "Type", 2, "Amount", DNT_TotalDamage), currentToken()); case 3: macroLink("HP + Surge", "Health@Lib:Execute", "none", json.set("", "Type", 3, "Amount", DNT_TotalDamage), currentToken()); case 4: macroLink("temp HP", "Health@Lib:Execute", "none", json.set("", "Type", 4, "Amount", DNT_TotalDamage), currentToken()); case 5: macroLink("HP + as if Surge", "Health@Lib:Execute", "none", json.set("", "Type", 5, "Amount", DNT_TotalDamage), currentToken()); case 6: macroLink("HP + costs Surge", "Health@Lib:Execute", "none", json.set("", "Type", 6, "Amount", DNT_TotalDamage), currentToken()); default: macroLink("damage", "Health@Lib:Execute", "none", json.set("", "Type", 0, "Amount", DNT_TotalDamage), currentToken())]</span>
};{
[H: ""]
}
]
[R, if(Die >= DNT_CriticalHit && DNT_EntryDamageSpecial != 1 && DNT_HideRoll != 1), CODE:
{
[H: CriticalDamage = eval(string(PowerCritDamage)) + eval(string(WeaponCritDamage))]
[H: DamageDice = strformat("%s(%s)", DNT_RawDamageDice, DNT_MaxDamageRoll)]
[H: DNT_TotalDamage = DNT_MaxDamageRoll + DNT_PowerDamage + WeaponDamage + DNT_DmgMods + CriticalDamage]
<span style='Color:red'><b>Critical:</b></span> [T(DNT_TotalDamage): DamageDice + PowerDamage + WeaponDamage + DamageMods + CriticalDamage] <span style="color:black">[R, switch(DNT_EntryDamageSpecial): case 2: macroLink("healing", "Health@Lib:Execute", "none", json.set("", "Type", 2, "Amount", DNT_TotalDamage), currentToken()); case 3: macroLink("HP + Surge", "Health@Lib:Execute", "none", json.set("", "Type", 3, "Amount", DNT_TotalDamage), currentToken()); case 4: macroLink("temp HP", "Health@Lib:Execute", "none", json.set("", "Type", 4, "Amount", DNT_TotalDamage), currentToken()); case 5: macroLink("HP + as if Surge", "Health@Lib:Execute", "none", json.set("", "Type", 5, "Amount", DNT_TotalDamage), currentToken()); case 6: macroLink("HP + costs Surge", "Health@Lib:Execute", "none", json.set("", "Type", 6, "Amount", DNT_TotalDamage), currentToken()); default: macroLink("damage", "Health@Lib:Execute", "none", json.set("", "Type", 0, "Amount", DNT_TotalDamage), currentToken())]</span>
};{
[H: ""]
}
]
[R, if(Die >= DNT_CriticalHit && DNT_EntryDamageSpecial != 1 && DNT_HideRoll == 1), CODE:
{
[H: CriticalDamage = eval(string(PowerCritDamage)) + eval(string(WeaponCritDamage))]
[H: DamageDice = strformat("%s(%s)", DNT_RawDamageDice, DNT_MaxDamageRoll)]
[H: DNT_TotalDamage = DNT_MaxDamageRoll + DNT_PowerDamage + WeaponDamage + DNT_DmgMods + CriticalDamage]
<span style='Color:red'><b>Critical:</b></span> [T(DNT_TotalDamage): DamageDice + PowerDamage + WeaponDamage + DamageMods + CriticalDamage] [R, switch(DNT_EntryDamageSpecial): case 2: macroLink("healing", "Health@Lib:Execute", "none", json.set("", "Type", 2, "Amount", DNT_TotalDamage), currentToken()); case 3: macroLink("HP + Surge", "Health@Lib:Execute", "none", json.set("", "Type", 3, "Amount", DNT_TotalDamage), currentToken()); case 4: macroLink("temp HP", "Health@Lib:Execute", "none", json.set("", "Type", 4, "Amount", DNT_TotalDamage), currentToken()); case 5: macroLink("HP + as if Surge", "Health@Lib:Execute", "none", json.set("", "Type", 5, "Amount", DNT_TotalDamage), currentToken()); case 6: macroLink("HP + costs Surge", "Health@Lib:Execute", "none", json.set("", "Type", 6, "Amount", DNT_TotalDamage), currentToken()); default: macroLink("damage", "Health@Lib:Execute", "none", json.set("", "Type", 0, "Amount", DNT_TotalDamage), currentToken())]</span>
};{
[H: ""]
}
]
[H: DNT_AttackCount = DNT_AttackCount + 1]
}
]
[R, if(DNT_EntryAttackType == "" && DNT_EntryDamageSpecial != 1), CODE:
{
[H: DamageMods = if(json.get(macro.args, "DmgMod" + DNT_AttackCount) == "", 0, json.get(macro.args, "DmgMod" + DNT_AttackCount))]
[H, if(isNumber(DamageMods) == 1), CODE:
{
[H: DNT_DmgMods = DamageMods]
};{
[H: DNT_DmgMods = eval(DamageMods)]
[H: DamageMods = strformat(DNT_ModString, DamageMods, DNT_DmgMods)]
}
]
<br>
[R, if(DNT_HideRoll == 1), CODE:
{
[H: DNT_DmgDiceResult = DiceRoll(DNT_RawDamageDice)]
[H: DamageDice = strformat("%s(%s)", DNT_RawDamageDice, DNT_DmgDiceResult)]
[H: DNT_TotalDamage = eval(string(DNT_DmgDiceResult)) + DNT_PowerDamage + WeaponDamage + DNT_DmgMods]
<b>[R, switch(DNT_AttackSlot): case 1: ""; case 2: "2nd "; case 3: "3rd "; default: DNT_AttackSlot + "th "] Hit</b>[R, if(json.get(macro.args, "Target" + DNT_AttackCount) == ""): ""; " against " + getName(json.get(macro.args, "Target" + DNT_AttackCount))]: [GT, ST, T(DNT_TotalDamage): DamageDice + PowerDamage + WeaponDamage + DamageMods] [R: DNT_EntryDamageType] <span style="color:black">[R, switch(DNT_EntryDamageSpecial): case 2: macroLink("healing", "Health@Lib:Execute", "none", json.set("", "Type", 2, "Amount", DNT_TotalDamage), currentToken()); case 3: macroLink("HP + Surge", "Health@Lib:Execute", "none", json.set("", "Type", 3, "Amount", DNT_TotalDamage), currentToken()); case 4: macroLink("temp HP", "Health@Lib:Execute", "none", json.set("", "Type", 4, "Amount", DNT_TotalDamage), currentToken()); case 5: macroLink("HP + as if Surge", "Health@Lib:Execute", "none", json.set("", "Type", 5, "Amount", DNT_TotalDamage), currentToken()); case 6: macroLink("HP + costs Surge", "Health@Lib:Execute", "none", json.set("", "Type", 6, "Amount", DNT_TotalDamage), currentToken()); default: macroLink("damage", "Health@Lib:Execute", "none", json.set("", "Type", 0, "Amount", DNT_TotalDamage), currentToken())]</span>
};{
[H: DNT_DmgDiceResult = DiceRoll(DNT_RawDamageDice)]
[H: DamageDice = strformat("%s(%s)", DNT_RawDamageDice, DNT_DmgDiceResult)]
[H: DNT_TotalDamage = eval(string(DNT_DmgDiceResult)) + DNT_PowerDamage + WeaponDamage + DNT_DmgMods]
<b>[R, switch(DNT_AttackSlot): case 1: ""; case 2: "2nd "; case 3: "3rd "; default: DNT_AttackSlot + "th "] Hit</b>[R, if(json.get(macro.args, "Target" + DNT_AttackCount) == ""): ""; " against " + getName(json.get(macro.args, "Target" + DNT_AttackCount))]: [T(DNT_TotalDamage): DamageDice + PowerDamage + WeaponDamage + DamageMods] [R: DNT_EntryDamageType] <span style="color:black">[R, switch(DNT_EntryDamageSpecial): case 2: macroLink("healing", "Health@Lib:Execute", "none", json.set("", "Type", 2, "Amount", DNT_TotalDamage), currentToken()); case 3: macroLink("HP + Surge", "Health@Lib:Execute", "none", json.set("", "Type", 3, "Amount", DNT_TotalDamage), currentToken()); case 4: macroLink("temp HP", "Health@Lib:Execute", "none", json.set("", "Type", 4, "Amount", DNT_TotalDamage), currentToken()); case 5: macroLink("HP + as if Surge", "Health@Lib:Execute", "none", json.set("", "Type", 5, "Amount", DNT_TotalDamage), currentToken()); case 6: macroLink("HP + costs Surge", "Health@Lib:Execute", "none", json.set("", "Type", 6, "Amount", DNT_TotalDamage), currentToken()); default: macroLink("damage", "Health@Lib:Execute", "none", json.set("", "Type", 0, "Amount", DNT_TotalDamage), currentToken())]</span>
}
]
[H: DNT_AttackCount = DNT_AttackCount + 1]
};{
[H: ""]
}
]
[R, if(json.get(DNT_Entry, "ShowHit" + DNT_AttackSlot) == 1): strformat("<br><b>Hit:</b> %s", RegEx(json.get(DNT_Entry, "Hit" + DNT_AttackSlot)))]
[R, if(json.get(DNT_Entry, "ShowMiss" + DNT_AttackSlot) == 1): strformat("<br><b>Miss:</b> %s", RegEx(json.get(DNT_Entry, "Miss" + DNT_AttackSlot)))]
[H: macro.return = DNT_AttackCount]