Phergus wrote: ↑Wed Nov 20, 2019 6:09 pm
In [r: gmOutput] and [r: OutputText], the names used are just variable names. They don't have any meaning beyond what you give to them.
That's what I was trying to say, the difference is in the way the data are stored.
aliasmask wrote: ↑Wed Nov 20, 2019 1:58 pm
See if this works for you. There is no chat output but a popup will show all the hp changes.
Many thanks, it works! I studied your code trying to understand how it works and why. I adapted it to better suit some of my needs, and then I realized it probably was the wrong system to get what I was trying to reach. I scavenged some other code, studied it and readapted with yours and mine, giving life to this Frankenstein monster. I'm sure that it's not optimized nor it's the best way to get everything done, but it works fine in every aspect (for what I tested), except that the final Dialog formatting isn't completely correct as it puts some commas between the rows but, since it works and I don't know how to program, I think I am satisfied.
Code: Select all
<!-- Get Tokens, create ExecPermission, Concentrating List and Result Output -->
[h: TokenIDs = getSelected()]
[h: ExecPermission = 1]
[h: ConcentratingList = ("")]
[h: ResultOutput = ""]
<!-- Checks if the tokens are ready for the macro -->
[h, foreach(Character, TokenIDs), CODE: {
[h: switchToken(Character)]
[h, if(isNumber(HP)):ExecPermission=ExecPermission; ExecPermission = 0]
[h, if(isNumber(MaxHP)):ExecPermission=ExecPermission; ExecPermission = 0]
}]
<!-- Abort the macro if a token is not ready for its execution -->
[h, if(ExecPermission == 0), CODE: {
[dialog("Macro Abort"): {
"Some characters are missing some properties. Check for HP and MaxHP"
}]
[h: abort(0)]
}]
<!-- Create Menu -->
[h: abort(input(
"hpChange|0|Number of Hit Points",
"Operation|Damage,Healing,Kill,Refull|Is the character taking damage or being healed?|RADIO|SELECT=0",
"ShowDead|Yes,No|Alternate the Dead status on tokens|RADIO|SELECT=0"
))]
<!-- Evaluate and floor the expression -->
[h: hpChange = floor(eval(string(hpChange)))]
<!-- Parse operations switching in Characters and editing its properties -->
[g, if(Operation == 0), CODE: {
[h, foreach(Character, TokenIDs), CODE: {
[h: switchToken(Character)]
[h: HP = HP - hpChange]
<!-- Puts concentrating characters in ConcentratingList -->
[h, if(state.Concentrating): ConcentratingList = listappend(ConcentratingList, Character)]
<!-- Tells GM who took damage -->
[h: ResultOutput = listAppend(ResultOutput, token.name)]
}]
[g: ResultOutput + " <b>suffer " + hpChange + " damage</b>"]
}]
[g, if(Operation == 1), CODE: {
[h, foreach(Character, TokenIDs), CODE: {
[h: switchToken(Character)]
[h: HP = min(HP+hpChange, MaxHP)]
[h: ResultOutput = listAppend(ResultOutput, token.name)]
}]
[g: ResultOutput + " <b>healed " + hpChange + " HP</b>"]
}]
[g, if(Operation == 2), CODE: {
[h, foreach(Character, TokenIDs), CODE: {
[h: switchToken(Character)]
[h: HP = 0)]
[h: ResultOutput = listAppend(ResultOutput, token.name)]
}]
[g: ResultOutput + " is/are killed</b>"]
}]
[g, if(Operation == 3), CODE: {
[h, foreach(Character, TokenIDs), CODE: {
[h: switchToken(Character)]
[h: HP = MaxHP)]
[h: ResultOutput = listAppend(ResultOutput, token.name)]
}]
[g: ResultOutput + " is/are completely restored</b>"]
}]
<!-- After the damage or healing has been done, this sets health bar and dead state -->
[h, foreach(Character, TokenIDs), CODE: {
<!-- Sets Health Bar progression -->
[h: switchToken(Character)]
[h: bar.Health = HP / MaxHP]
<!-- Sets Dead State if allowed AND if HP are <= 0 -->
[h, if(ShowDead == 0): state.Dead = if(HP <= 0, 1, 0)]
<!-- If a Character is dead set it to Object Layer, otherwise take it back to Token Layer -->
[h, if(state.Dead == 0): setLayer("Token"); setLayer("Object")]
}]
<!-- Create a Pop Up Dialog with names and concentration modifiers and saves of the damaged character -->
[dialog("Concentration Result"): {
[h: ConSTCD = if(floor((hpChange)/2) > 10, floor((hpChange)/2), 10)]
[r: "Some characters were concentrating: they will keep the concentration if they succed a <b>CD " + ConSTCD + " Constitution Saving Throw.</b><br>"]
<html>
<head>
<style> [R: "
.oddRow { background-color: #FFFFFF }
.evenRow { background-color: #EEEEAA }
#stats th { background-color: #113311; color: #FFFFFF }"
]
</style>
<title>Character Sheet</title>
</head>
<body>
<table id="stats">
<tr>
<th>Character Name</th>
<th>Constitution S.T. Modifier</th>
<th>Final Saving Throw</th>
<th>Save Result</th>
</tr>
[h: class = "oddRow"]
[foreach(Character, ConcentratingList), code: {
[h: switchToken(Character)]
[h: ConSTMod = getProperty("Saving Throw - Constitution")]
[h: ConSTFinal = 1d20+ConSTMod]
<tr class="[r:class]">
<td>[r: token.name]</td>
<td>[r: "+" + if(isNumber(ConSTMod), ConSTMod, 0)ConSTMod]</td>
<td>[r: ConSTFinal]</td>
<td>[r: if(ConSTFinal >= ConSTCD, "Yes", "No")]</td>
</tr>
[h: class = if(class=="oddRow", "evenRow", "oddRow")]
}]
</table>
</body>
</html>
}]
<!-- Since it's not possible to open the dialog with a condition because of depth calculation limits, this closes the dialog immediatley if there's not need to keep it open -->
[r, if(length(ConcentratingList) == 0): closeDialog("Concentration Result")]