Re-Tooling for GM only text display

Discuss macro implementations, ask for macro help (to share your creations, see User Creations, probably either Campaign Frameworks or Drop-in Resources).

Moderators: dorpond, trevor, Azhrei, giliath, jay, Mr.Ice

Post Reply
qcgreywolf
Cave Troll
Posts: 43
Joined: Mon Dec 09, 2013 10:23 pm

Re-Tooling for GM only text display

Post by qcgreywolf »

I am retooling my framework so that all my NPC's have different macro output from my PC's (you know, so I can hide To-Hits, skill rolls and saving throws from mt PC's). I have been very successful with a super simple solution, below is a short code snippet to elaborate...

Code: Select all

[h: gmOnly = isNPC()]

  [h: output.tip = strformat("<html>
   <table><tr><td colspan=2><b><center>%{skillToRoll} Check</center></b></td></tr>
      <tr><td>Modifier:</td><td>%{skillModifier}</td></tr>
      <tr><td>D20 Roll:</td><td>%{dieRoll}</td></tr>
   </table></html>")]

[h: outputText = strformat("<b>%{skillToRoll}</b> check = %{skillRoll}.")]

  <td><span title="{output.tip}">
	[r: Display.Text(outputText, gmOnly)]
  </span></td>
Then, this is the called macro;

Code: Select all

[if(arg(1) == 1),CODE:{
[g,r: arg(0)]
};{
[r: arg(0)]
}]
Short, sweet and lightning quick.

I have a selection of different calling macros that output a variety of info via that method. Now, here is the hard part... I want to output the text from my complex attack macro via the same method, BUT I have if/then statements peppered into the output text, like below (partial code, complete code at the bottom of the post)

Code: Select all

[h: output.tip = strformat("<html>
   <table><tr><td colspan=2><b><center>To Hit Rolls</center></b></td></tr>
      <tr><td>d20 Roll:</td><td>%{toHitRoll}</td><td>Threat Roll:</td><td>%{criticalThreatRoll}</td></tr>
      <tr><td>Modifier:</td><td>%{toHitModifier}</td><td>Threat Modifier:</td><td>%{criticalThreatMod}</td></tr>
   </table></html>")]

<span title="{output.tip}">
<font color = "FF0000"><b>[r: attackNumber]</b>  - [r: if(toHitRoll == 20,"<b>Hit!</b>","Threat")] - [r: toHit] ([r: if(criticalHit==1 || toHitRoll == 20,toHitRoll,"")]) [r: if(criticalHit==1 || toHitRoll == 20,criticalThreat,"")] ([r: if(criticalHit==1 || toHitRoll == 20,criticalThreatRoll,"")]) </font>
</span>
I realize that this is a rough hack job of the code, but it is possible to do the following... (I didn't add in the %{var} code, but I know I will have to in a final draft o the code, just so the example was clear)

Code: Select all

[h: output.tip = strformat("<html>
   <table><tr><td colspan=2><b><center>To Hit Rolls</center></b></td></tr>
      <tr><td>d20 Roll:</td><td>%{toHitRoll}</td><td>Threat Roll:</td><td>%{criticalThreatRoll}</td></tr>
      <tr><td>Modifier:</td><td>%{toHitModifier}</td><td>Threat Modifier:</td><td>%{criticalThreatMod}</td></tr>
   </table></html>")]

[h: outputText = strformat("<font color = "FF0000"><b>[r: attackNumber]</b>  - [r: if(toHitRoll == 20,"<b>Hit!</b>","Threat")] - [r: toHit] ([r: if(criticalHit==1 || toHitRoll == 20,toHitRoll,"")]) [r: if(criticalHit==1 || toHitRoll == 20,criticalThreat,"")] ([r: if(criticalHit==1 || toHitRoll == 20,criticalThreatRoll,"")]) </font>")]

  <td><span title="{output.tip}">
	[r: Display.Text(outputText, gmOnly)]
  </span></td>
I have not found a way that I can include the if/then statements into the formatted outputText. If there is not an easy way to do this, just let me know the bad news, I will have to completely re-write my attack macro so that it is GMonly output friendly (sigh).

In case it is important for helping, here is the initial calling macro, the bulk attack UDF and the display UDF. Let me know if it is also helpful to include all the little periphery UDF's.

Calling macro

Code: Select all

[h: '<-- Declarations-->']
[h: attackArray1 = ""]	[h: attackArray2 = ""]	[h: attackArray3 = ""]
[h: attackArray4 = ""]	[h: attackArray5 = ""]	[h: attackArray6 = ""]
[h: attackArray7 = ""]	[h: attackArrayH = ""]
[h: CMBattackArray1 = ""]	[h: CMBattackArray2 = ""]	[h: CMBattackArray3 = ""]
[h: CMBattackArray4 = ""]	[h: CMBattackArray5 = ""]	[h: CMBattackArray6 = ""]
[h: CMBattackArray7 = ""]	[h: CMBattackArrayH = ""]
[h: SAattackArray1 = ""]	[h: SAattackArray2 = ""]	[h: SAattackArray3 = ""]
[h: SAattackArray4 = ""]	[h: SAattackArray5 = ""]	[h: SAattackArray6 = ""]
[h: SAattackArray7 = ""]	[h: SAattackArrayH = ""]

		[h: '<-- Building the attack , loading in all the token vars-->']

[ if(AttackPresent1 == "Yes"), CODE:
{
	[h: Pull.Attack(1)]
	[h: attackArray1 = macro.return]

	[h, if(AutoCMB == 1), CODE:
	{
		[h: Pull.CMB()]
		[h: CMBattackArray1 = macro.return]
	};{}]

	[h, if(SneakAttack > 0), CODE:
	{
		[h: Pull.SneakAttack(SneakAttack)]
		[h: SAattackArray1 = macro.return]
	};{}]

[Display.Attack(attackArray1,CMBattackArray1,SAattackArray1)]
};{}]

[ if(getState("Haste") == "1"), CODE:
{
	[h: Pull.Attack("H")]
	[h: attackArrayH = macro.return]

	[h, if(AutoCMB == 1), CODE:
	{
		[h: Pull.CMB()]
		[h: CMBattackArrayH = macro.return]
	};{}]

	[h, if(SneakAttack > 0), CODE:
	{
		[h: Pull.SneakAttack(SneakAttack)]
		[h: SAattackArrayH = macro.return]
	};{}]

[Display.Attack(attackArrayH,CMBattackArrayH,SAattackArrayH)]
};{}]
Display.Attack UDF

Code: Select all

[h: varsFromStrProp(arg(0))]
[h: varsFromStrProp(arg(1))]
[h: varsFromStrProp(arg(2))]
[h: gmOnly = isNPC()]

<tr>
<td>
[if(criticalHit == 1 || toHitRoll == 20), code:
{
[h: output.tip = strformat("<html>
   <table><tr><td colspan=2><b><center>To Hit Rolls</center></b></td></tr>
      <tr><td>d20 Roll:</td><td>%{toHitRoll}</td><td>Threat Roll:</td><td>%{criticalThreatRoll}</td></tr>
      <tr><td>Modifier:</td><td>%{toHitModifier}</td><td>Threat Modifier:</td><td>%{criticalThreatMod}</td></tr>
   </table></html>")]

<span title="{output.tip}">
<font color = "FF0000"><b>[r: attackNumber]</b>  - [r: if(toHitRoll == 20,"<b>Hit!</b>","Threat")] - [r: toHit] ([r: if(criticalHit==1 || toHitRoll == 20,toHitRoll,"")]) [r: if(criticalHit==1 || toHitRoll == 20,criticalThreat,"")] ([r: if(criticalHit==1 || toHitRoll == 20,criticalThreatRoll,"")]) </font>
</span>

};
{
  [if(attackPresent1 == "Yes"), CODE:
    {

    [h: output.tip = strformat("<html>
   <table><tr><td colspan=2><b><center>To Hit Roll</center></b></td></tr>
      <tr><td>d20 Roll:</td><td>%{toHitRoll}</td></tr>
      <tr><td>Modifier:</td><td>%{toHitModifier}</td></tr>
   </table></html>")]

    <span title="{output.tip}">
    <b>[r: attackNumber] - </b> [r: toHit]
    [r: if(toHitRoll == 1, " - CRITICAL MISS! - ", "")]
    </span>
    };{}]

}]
</td>

					<!-- Bulk Formatting 1 -->
[h: output.tip = strformat("<html>
   <table><tr><td colspan=2><b><center>Damage Type: %{damageType11}</center></b></td></tr>
      <tr><td>Damage:</td><td>%{damageDice11} + %{TempDamageModifier}</td><td>Critical Damage:</td><td>%{criticalDamageDice11} + %{tempCriticalDamage}</td></tr>
      <tr><td>Damage Die:</td><td>%{unrolledDice11}</td><td>Threat Multiplier:</td><td>%{unrolledDice11} x %{criticalMultiplier}</td></tr>
   </table></html>")]

<td><span title="{output.tip}">
---- [r: if(damageDice11 == 0, "", damageDice11 + TempDamageModifier)] [r: if(criticalHit == 1, "(", "")][r: if(criticalHit == 1, criticalDamageDice11 + tempCriticalDamage, "")][r: if(criticalHit == 1, ")", "")] [r: if(damageType11 == "", "", damageType11)]
</span></td>

[h: output.tip = strformat("<html>
   <table><tr><td colspan=2><b><center>Damage Type: %{damageType22}</center></b></td></tr>
      <tr><td>Damage:</td><td>%{damageDice22}</td></tr>
      <tr><td>Damage Die:</td><td>%{unrolledDice22}</td></tr>
   </table></html>")]

<td><span title="{output.tip}">
-- [r: if(damageDice22 == 0, "", damageDice22)] [r: if(damageType22 == "", "", damageType22)]
</span></td>

[h: output.tip = strformat("<html>
   <table><tr><td colspan=2><b><center>Damage Type: %{damageType33}</center></b></td></tr>
      <tr><td>Damage:</td><td>%{damageDice33}</td></tr>
      <tr><td>Damage Die:</td><td>%{unrolledDice33}</td></tr>
   </table></html>")]

<td><span title="{output.tip}">
-- [r: if(damageDice33 == 0, "", damageDice33)] [r: if(damageType33 == "", "", damageType33)]
</span></td>

[h: output.tip = strformat("<html>
   <table><tr><td colspan=2><b><center>Damage Type: %{damageType44}</center></b></td></tr>
      <tr><td>Damage:</td><td>%{damageDice44}</td></tr>
      <tr><td>Damage Die:</td><td>%{unrolledDice44}</td></tr>
   </table></html>")]

<td><span title="{output.tip}">
-- [r: if(damageDice44 == 0, "", damageDice44)] [r: if(damageType44 == "", "", damageType44)]
</span></td>

[h: output.tip = strformat("<html>
   <table><tr><td colspan=2><b><center>Damage Type: %{damageType55}</center></b></td></tr>
      <tr><td>Damage:</td><td>%{damageDice55}</td></tr>
      <tr><td>Damage Die:</td><td>%{unrolledDice55}</td></tr>
   </table></html>")]

<td><span title="{output.tip}">
-- [r: if(damageDice55 == 0, "", damageDice55)] [r: if(damageType55 == "", "", damageType55)]
</span></td>

[h: totalDamage = damageDice11 + if(damageDice22 == "", 0, damageDice22) + if(damageDice33 == "", 0, damageDice33) + if(damageDice44 == "", 0, damageDice44) + if(damageDice55 == "", 0, damageDice55) + TempDamageModifier]

[h: output.tip = strformat("<html>
   <table><tr><td colspan=2><b><center>Damage Total</center></b></td></tr>
      <td>%{damageDice11} + %{TempDamageModifier} + %{damageDice22} + %{damageDice33} + %{damageDice44} + %{damageDice55} = %{totalDamage}(%{criticalDamageDice11} + %{tempCriticalDamage}) </td>
   </table></html>")]

<td><span title="{output.tip}">
-- [r: totalDamage] [r: if(criticalHit == 1, "(", "")][r: if(criticalHit == 1, criticalDamageDice11 + tempCriticalDamage, "")][r: if(criticalHit == 1, ")", "")] damage.
</span></td>

[if(autoCMB == 1), CODE:
{
  [h: output.tip = strformat("<html>
   <table><tr><td colspan=2><b><center>CMB Roll</center></b></td></tr>
      <tr><td>Modifier:</td><td>%{CMB}</td></tr>
      <tr><td>Temporary Modifiers:</td><td>%{TempAttackModifier}</td></tr>
   </table></html>")]

  <td><span title="{output.tip}">
 (CMB 
 [r: CMBtotal]</td>
<td>
 (
 [r: CMBroll]
 ))
  </span></td>
};{}]

[if(SneakAttack > 0), CODE:
{
  [h: output.tip = strformat("<html>
   <table><tr><td colspan=2><b><center>Sneak Attack</center></b></td></tr>
      <tr><td>Sneak Attack Dice:</td><td>%{SneakAttack}d6</td></tr>
   </table></html>")]

  <td><span title="{output.tip}">
  ( Sneak Attack 
  [r: SA]
  )
  </td>
};{}]

</tr>
Pull.Attack UDF (this is a biggie)

Code: Select all

<!-- Initalizing the arrays -->
[h: attackArray = "attackNumber=0; toHitRoll=0; toHit=0; toHitModifier=0; criticalThreatRoll=0; criticalThreat=0; criticalThreatMod=0; criticalHit=0; criticalMultiplier=0; damageDice11=0; criticalDamageDice11=0; damageDice22=0; damageDice33=0; damageDice44=0; damageDice55=0; damageType11=0; damageType22=0; damageType33=0; damageType44=0; damageType55=0"]
[h: damageArray = ""]
[h: diceArray = ""]

			<!-- Rolling to-hit's -->

[ if(arg(0) == 1),CODE:
{
	[h: attackArray = setStrProp(attackArray, "attackNumber", "Attack 1")]

	[h: Random.Roller(20)]
	[h: toHitRoll = macro.return]
	[h: attackArray = setStrProp(attackArray, "toHitRoll", macro.return)]

	[h: toHitModifier = DefaultAttackModifier1 + TempAttackModifier]
	[h: toHit = macro.return + toHitModifier]
	[h: attackArray = setStrProp(attackArray, "toHit", toHit)]
	[h: attackArray = setStrProp(attackArray, "toHitModifier", toHitModifier)]

	[h: Random.Roller(20)]
	[h: attackArray = setStrProp(attackArray, "criticalThreatRoll", macro.return)]

	[h: criticalThreatMod = DefaultAttackModifier1 + TempAttackModifier + CriticalThreatModifier]
	[h: criticalThreat = macro.return + criticalThreatMod]
	[h: attackArray = setStrProp(attackArray, "criticalThreat", criticalThreat)]
	[h: attackArray = setStrProp(attackArray, "criticalThreatMod", criticalThreatMod)]

	[h: criticalThreatRange = listGet(CriticalType1, 0)]
	[h: criticalMultiplier = listGet(CriticalType1, 1)]
	[h: criticalHit = if(toHitRoll >= criticalThreatRange, 1, 0)]
	[h: attackArray = setStrProp(attackArray, "criticalHit", criticalHit)]
	[h: attackArray = setStrProp(attackArray, "criticalMultiplier", criticalMultiplier)]

	[h, foreach(list, DamageDice1), CODE:
	{
		[h: damage = eval(listGet(DamageDice1,roll.count))]
		[h: damageArray = listAppend(damageArray, damage)]
	}]

	[h: attackArray = setStrProp(attackArray, "damageDice11", listGet(damageArray, 0))]
	[h: attackArray = setStrProp(attackArray, "damageDice22", listGet(damageArray, 1))]
	[h: attackArray = setStrProp(attackArray, "damageDice33", listGet(damageArray, 2))]
	[h: attackArray = setStrProp(attackArray, "damageDice44", listGet(damageArray, 3))]
	[h: attackArray = setStrProp(attackArray, "damageDice55", listGet(damageArray, 4))]

	[h: damageArray = ""]
	[h, foreach(list, DamageDice1), CODE:
	{
		[h: damage = listGet(DamageDice1,roll.count))]
		[h: damageArray = listAppend(damageArray, damage)]
	}]

	[h: attackArray = setStrProp(attackArray, "unrolledDice11", listGet(damageArray, 0))]
	[h: attackArray = setStrProp(attackArray, "unrolledDice22", listGet(damageArray, 1))]
	[h: attackArray = setStrProp(attackArray, "unrolledDice33", listGet(damageArray, 2))]
	[h: attackArray = setStrProp(attackArray, "unrolledDice44", listGet(damageArray, 3))]
	[h: attackArray = setStrProp(attackArray, "unrolledDice55", listGet(damageArray, 4))]

	[h: Pull.CriticalMultiplier(attackArray)]
	[h: attackArray = macro.return]

	[h, foreach(list, DamageType1), CODE:
	{
		[h: dieType = listGet(DamageType1,roll.count))]
		[h: diceArray = listAppend(diceArray, dieType)]
	}]

	[h: attackArray = setStrProp(attackArray, "damageType11", listGet(diceArray, 0))]
	[h: attackArray = setStrProp(attackArray, "damageType22", listGet(diceArray, 1))]
	[h: attackArray = setStrProp(attackArray, "damageType33", listGet(diceArray, 2))]
	[h: attackArray = setStrProp(attackArray, "damageType44", listGet(diceArray, 3))]
	[h: attackArray = setStrProp(attackArray, "damageType55", listGet(diceArray, 4))]
};{}]

[ if(arg(0) == 2),CODE:
{
	[h: attackArray = setStrProp(attackArray, "attackNumber", "Attack 2")]

	[h: Random.Roller(20)]
	[h: toHitRoll = macro.return]
	[h: attackArray = setStrProp(attackArray, "toHitRoll", macro.return)]

	[h: toHitModifier = DefaultAttackModifier2 + TempAttackModifier]
	[h: toHit = macro.return + toHitModifier]
	[h: attackArray = setStrProp(attackArray, "toHit", toHit)]
	[h: attackArray = setStrProp(attackArray, "toHitModifier", toHitModifier)]

	[h: Random.Roller(20)]
	[h: attackArray = setStrProp(attackArray, "criticalThreatRoll", macro.return)]

	[h: criticalThreatMod = DefaultAttackModifier2 + TempAttackModifier + CriticalThreatModifier]
	[h: criticalThreat = macro.return + criticalThreatMod]
	[h: attackArray = setStrProp(attackArray, "criticalThreat", criticalThreat)]
	[h: attackArray = setStrProp(attackArray, "criticalThreatMod", criticalThreatMod)]

	[h: criticalThreatRange = listGet(CriticalType2, 0)]
	[h: criticalMultiplier = listGet(CriticalType2, 1)]
	[h: criticalHit = if(toHitRoll >= criticalThreatRange, 1, 0)]
	[h: attackArray = setStrProp(attackArray, "criticalHit", criticalHit)]
	[h: attackArray = setStrProp(attackArray, "criticalMultiplier", criticalMultiplier)]

	[h, foreach(list, DamageDice2), CODE:
	{
		[h: damage = eval(listGet(DamageDice2,roll.count))]
		[h: damageArray = listAppend(damageArray, damage)]
	}]

	[h: attackArray = setStrProp(attackArray, "damageDice11", listGet(damageArray, 0))]
	[h: attackArray = setStrProp(attackArray, "damageDice22", listGet(damageArray, 1))]
	[h: attackArray = setStrProp(attackArray, "damageDice33", listGet(damageArray, 2))]
	[h: attackArray = setStrProp(attackArray, "damageDice44", listGet(damageArray, 3))]
	[h: attackArray = setStrProp(attackArray, "damageDice55", listGet(damageArray, 4))]

	[h: damageArray = ""]
	[h, foreach(list, DamageDice2), CODE:
	{
		[h: damage = listGet(DamageDice2,roll.count))]
		[h: damageArray = listAppend(damageArray, damage)]
	}]

	[h: attackArray = setStrProp(attackArray, "unrolledDice11", listGet(damageArray, 0))]
	[h: attackArray = setStrProp(attackArray, "unrolledDice22", listGet(damageArray, 1))]
	[h: attackArray = setStrProp(attackArray, "unrolledDice33", listGet(damageArray, 2))]
	[h: attackArray = setStrProp(attackArray, "unrolledDice44", listGet(damageArray, 3))]
	[h: attackArray = setStrProp(attackArray, "unrolledDice55", listGet(damageArray, 4))]

	[h: Pull.CriticalMultiplier(attackArray)]
	[h: attackArray = macro.return]

	[h, foreach(list, DamageType2), CODE:
	{
		[h: dieType = listGet(DamageType2,roll.count))]
		[h: diceArray = listAppend(diceArray, dieType)]
	}]

	[h: attackArray = setStrProp(attackArray, "damageType11", listGet(diceArray, 0))]
	[h: attackArray = setStrProp(attackArray, "damageType22", listGet(diceArray, 1))]
	[h: attackArray = setStrProp(attackArray, "damageType33", listGet(diceArray, 2))]
	[h: attackArray = setStrProp(attackArray, "damageType44", listGet(diceArray, 3))]
	[h: attackArray = setStrProp(attackArray, "damageType55", listGet(diceArray, 4))]
};{}]

[ if(arg(0) == 3),CODE:
{
	[h: attackArray = setStrProp(attackArray, "attackNumber", "Attack 3")]

	[h: Random.Roller(20)]
	[h: toHitRoll = macro.return]
	[h: attackArray = setStrProp(attackArray, "toHitRoll", macro.return)]

	[h: toHitModifier = DefaultAttackModifier3 + TempAttackModifier]
	[h: toHit = macro.return + toHitModifier]
	[h: attackArray = setStrProp(attackArray, "toHit", toHit)]
	[h: attackArray = setStrProp(attackArray, "toHitModifier", toHitModifier)]

	[h: Random.Roller(20)]
	[h: attackArray = setStrProp(attackArray, "criticalThreatRoll", macro.return)]

	[h: criticalThreatMod = DefaultAttackModifier3 + TempAttackModifier + CriticalThreatModifier]
	[h: criticalThreat = macro.return + criticalThreatMod]
	[h: attackArray = setStrProp(attackArray, "criticalThreat", criticalThreat)]
	[h: attackArray = setStrProp(attackArray, "criticalThreatMod", criticalThreatMod)]

	[h: criticalThreatRange = listGet(CriticalType3, 0)]
	[h: criticalMultiplier = listGet(CriticalType3, 1)]
	[h: criticalHit = if(toHitRoll >= criticalThreatRange, 1, 0)]
	[h: attackArray = setStrProp(attackArray, "criticalHit", criticalHit)]
	[h: attackArray = setStrProp(attackArray, "criticalMultiplier", criticalMultiplier)]

	[h, foreach(list, DamageDice3), CODE:
	{
		[h: damage = eval(listGet(DamageDice3,roll.count))]
		[h: damageArray = listAppend(damageArray, damage)]
	}]

	[h: attackArray = setStrProp(attackArray, "damageDice11", listGet(damageArray, 0))]
	[h: attackArray = setStrProp(attackArray, "damageDice22", listGet(damageArray, 1))]
	[h: attackArray = setStrProp(attackArray, "damageDice33", listGet(damageArray, 2))]
	[h: attackArray = setStrProp(attackArray, "damageDice44", listGet(damageArray, 3))]
	[h: attackArray = setStrProp(attackArray, "damageDice55", listGet(damageArray, 4))]

	[h: damageArray = ""]
	[h, foreach(list, DamageDice3), CODE:
	{
		[h: damage = listGet(DamageDice3,roll.count))]
		[h: damageArray = listAppend(damageArray, damage)]
	}]

	[h: attackArray = setStrProp(attackArray, "unrolledDice11", listGet(damageArray, 0))]
	[h: attackArray = setStrProp(attackArray, "unrolledDice22", listGet(damageArray, 1))]
	[h: attackArray = setStrProp(attackArray, "unrolledDice33", listGet(damageArray, 2))]
	[h: attackArray = setStrProp(attackArray, "unrolledDice44", listGet(damageArray, 3))]
	[h: attackArray = setStrProp(attackArray, "unrolledDice55", listGet(damageArray, 4))]

	[h: Pull.CriticalMultiplier(attackArray)]
	[h: attackArray = macro.return]

	[h, foreach(list, DamageType3), CODE:
	{
		[h: dieType = listGet(DamageType3,roll.count))]
		[h: diceArray = listAppend(diceArray, dieType)]
	}]

	[h: attackArray = setStrProp(attackArray, "damageType11", listGet(diceArray, 0))]
	[h: attackArray = setStrProp(attackArray, "damageType22", listGet(diceArray, 1))]
	[h: attackArray = setStrProp(attackArray, "damageType33", listGet(diceArray, 2))]
	[h: attackArray = setStrProp(attackArray, "damageType44", listGet(diceArray, 3))]
	[h: attackArray = setStrProp(attackArray, "damageType55", listGet(diceArray, 4))]
};{}]

[ if(arg(0) == 4),CODE:
{
	[h: attackArray = setStrProp(attackArray, "attackNumber", "Attack 4")]

	[h: Random.Roller(20)]
	[h: toHitRoll = macro.return]
	[h: attackArray = setStrProp(attackArray, "toHitRoll", macro.return)]

	[h: toHitModifier = DefaultAttackModifier4 + TempAttackModifier]
	[h: toHit = macro.return + toHitModifier]
	[h: attackArray = setStrProp(attackArray, "toHit", toHit)]
	[h: attackArray = setStrProp(attackArray, "toHitModifier", toHitModifier)]

	[h: Random.Roller(20)]
	[h: attackArray = setStrProp(attackArray, "criticalThreatRoll", macro.return)]

	[h: criticalThreatMod = DefaultAttackModifier4 + TempAttackModifier + CriticalThreatModifier]
	[h: criticalThreat = macro.return + criticalThreatMod]
	[h: attackArray = setStrProp(attackArray, "criticalThreat", criticalThreat)]
	[h: attackArray = setStrProp(attackArray, "criticalThreatMod", criticalThreatMod)]

	[h: criticalThreatRange = listGet(CriticalType4, 0)]
	[h: criticalMultiplier = listGet(CriticalType4, 1)]
	[h: criticalHit = if(toHitRoll >= criticalThreatRange, 1, 0)]
	[h: attackArray = setStrProp(attackArray, "criticalHit", criticalHit)]
	[h: attackArray = setStrProp(attackArray, "criticalMultiplier", criticalMultiplier)]

	[h, foreach(list, DamageDice4), CODE:
	{
		[h: damage = eval(listGet(DamageDice4,roll.count))]
		[h: damageArray = listAppend(damageArray, damage)]
	}]

	[h: attackArray = setStrProp(attackArray, "damageDice11", listGet(damageArray, 0))]
	[h: attackArray = setStrProp(attackArray, "damageDice22", listGet(damageArray, 1))]
	[h: attackArray = setStrProp(attackArray, "damageDice33", listGet(damageArray, 2))]
	[h: attackArray = setStrProp(attackArray, "damageDice44", listGet(damageArray, 3))]
	[h: attackArray = setStrProp(attackArray, "damageDice55", listGet(damageArray, 4))]

	[h: damageArray = ""]
	[h, foreach(list, DamageDice4), CODE:
	{
		[h: damage = listGet(DamageDice4,roll.count))]
		[h: damageArray = listAppend(damageArray, damage)]
	}]

	[h: attackArray = setStrProp(attackArray, "unrolledDice11", listGet(damageArray, 0))]
	[h: attackArray = setStrProp(attackArray, "unrolledDice22", listGet(damageArray, 1))]
	[h: attackArray = setStrProp(attackArray, "unrolledDice33", listGet(damageArray, 2))]
	[h: attackArray = setStrProp(attackArray, "unrolledDice44", listGet(damageArray, 3))]
	[h: attackArray = setStrProp(attackArray, "unrolledDice55", listGet(damageArray, 4))]

	[h: Pull.CriticalMultiplier(attackArray)]
	[h: attackArray = macro.return]

	[h, foreach(list, DamageType4), CODE:
	{
		[h: dieType = listGet(DamageType4,roll.count))]
		[h: diceArray = listAppend(diceArray, dieType)]
	}]

	[h: attackArray = setStrProp(attackArray, "damageType11", listGet(diceArray, 0))]
	[h: attackArray = setStrProp(attackArray, "damageType22", listGet(diceArray, 1))]
	[h: attackArray = setStrProp(attackArray, "damageType33", listGet(diceArray, 2))]
	[h: attackArray = setStrProp(attackArray, "damageType44", listGet(diceArray, 3))]
	[h: attackArray = setStrProp(attackArray, "damageType55", listGet(diceArray, 4))]
};{}]

[ if(arg(0) == 5),CODE:
{
	[h: attackArray = setStrProp(attackArray, "attackNumber", "Attack 5")]

	[h: Random.Roller(20)]
	[h: toHitRoll = macro.return]
	[h: attackArray = setStrProp(attackArray, "toHitRoll", macro.return)]

	[h: toHitModifier = DefaultAttackModifier5 + TempAttackModifier]
	[h: toHit = macro.return + toHitModifier]
	[h: attackArray = setStrProp(attackArray, "toHit", toHit)]
	[h: attackArray = setStrProp(attackArray, "toHitModifier", toHitModifier)]

	[h: Random.Roller(20)]
	[h: attackArray = setStrProp(attackArray, "criticalThreatRoll", macro.return)]

	[h: criticalThreatMod = DefaultAttackModifier5 + TempAttackModifier + CriticalThreatModifier]
	[h: criticalThreat = macro.return + criticalThreatMod]
	[h: attackArray = setStrProp(attackArray, "criticalThreat", criticalThreat)]
	[h: attackArray = setStrProp(attackArray, "criticalThreatMod", criticalThreatMod)]

	[h: criticalThreatRange = listGet(CriticalType5, 0)]
	[h: criticalMultiplier = listGet(CriticalType5, 1)]
	[h: criticalHit = if(toHitRoll >= criticalThreatRange, 1, 0)]
	[h: attackArray = setStrProp(attackArray, "criticalHit", criticalHit)]
	[h: attackArray = setStrProp(attackArray, "criticalMultiplier", criticalMultiplier)]

	[h, foreach(list, DamageDice5), CODE:
	{
		[h: damage = eval(listGet(DamageDice5,roll.count))]
		[h: damageArray = listAppend(damageArray, damage)]
	}]

	[h: attackArray = setStrProp(attackArray, "damageDice11", listGet(damageArray, 0))]
	[h: attackArray = setStrProp(attackArray, "damageDice22", listGet(damageArray, 1))]
	[h: attackArray = setStrProp(attackArray, "damageDice33", listGet(damageArray, 2))]
	[h: attackArray = setStrProp(attackArray, "damageDice44", listGet(damageArray, 3))]
	[h: attackArray = setStrProp(attackArray, "damageDice55", listGet(damageArray, 4))]

	[h: damageArray = ""]
	[h, foreach(list, DamageDice5), CODE:
	{
		[h: damage = listGet(DamageDice5,roll.count))]
		[h: damageArray = listAppend(damageArray, damage)]
	}]

	[h: attackArray = setStrProp(attackArray, "unrolledDice11", listGet(damageArray, 0))]
	[h: attackArray = setStrProp(attackArray, "unrolledDice22", listGet(damageArray, 1))]
	[h: attackArray = setStrProp(attackArray, "unrolledDice33", listGet(damageArray, 2))]
	[h: attackArray = setStrProp(attackArray, "unrolledDice44", listGet(damageArray, 3))]
	[h: attackArray = setStrProp(attackArray, "unrolledDice55", listGet(damageArray, 4))]

	[h: Pull.CriticalMultiplier(attackArray)]
	[h: attackArray = macro.return]

	[h, foreach(list, DamageType5), CODE:
	{
		[h: dieType = listGet(DamageType5,roll.count))]
		[h: diceArray = listAppend(diceArray, dieType)]
	}]

	[h: attackArray = setStrProp(attackArray, "damageType11", listGet(diceArray, 0))]
	[h: attackArray = setStrProp(attackArray, "damageType22", listGet(diceArray, 1))]
	[h: attackArray = setStrProp(attackArray, "damageType33", listGet(diceArray, 2))]
	[h: attackArray = setStrProp(attackArray, "damageType44", listGet(diceArray, 3))]
	[h: attackArray = setStrProp(attackArray, "damageType55", listGet(diceArray, 4))]
};{}]

[ if(arg(0) == 6),CODE:
{
	[h: attackArray = setStrProp(attackArray, "attackNumber", "Attack 6")]

	[h: Random.Roller(20)]
	[h: toHitRoll = macro.return]
	[h: attackArray = setStrProp(attackArray, "toHitRoll", macro.return)]

	[h: toHitModifier = DefaultAttackModifier6 + TempAttackModifier]
	[h: toHit = macro.return + toHitModifier]
	[h: attackArray = setStrProp(attackArray, "toHit", toHit)]
	[h: attackArray = setStrProp(attackArray, "toHitModifier", toHitModifier)]

	[h: Random.Roller(20)]
	[h: attackArray = setStrProp(attackArray, "criticalThreatRoll", macro.return)]

	[h: criticalThreatMod = DefaultAttackModifier6 + TempAttackModifier + CriticalThreatModifier]
	[h: criticalThreat = macro.return + criticalThreatMod]
	[h: attackArray = setStrProp(attackArray, "criticalThreat", criticalThreat)]
	[h: attackArray = setStrProp(attackArray, "criticalThreatMod", criticalThreatMod)]

	[h: criticalThreatRange = listGet(CriticalType6, 0)]
	[h: criticalMultiplier = listGet(CriticalType6, 1)]
	[h: criticalHit = if(toHitRoll >= criticalThreatRange, 1, 0)]
	[h: attackArray = setStrProp(attackArray, "criticalHit", criticalHit)]
	[h: attackArray = setStrProp(attackArray, "criticalMultiplier", criticalMultiplier)]

	[h, foreach(list, DamageDice6), CODE:
	{
		[h: damage = eval(listGet(DamageDice6,roll.count))]
		[h: damageArray = listAppend(damageArray, damage)]
	}]

	[h: attackArray = setStrProp(attackArray, "damageDice11", listGet(damageArray, 0))]
	[h: attackArray = setStrProp(attackArray, "damageDice22", listGet(damageArray, 1))]
	[h: attackArray = setStrProp(attackArray, "damageDice33", listGet(damageArray, 2))]
	[h: attackArray = setStrProp(attackArray, "damageDice44", listGet(damageArray, 3))]
	[h: attackArray = setStrProp(attackArray, "damageDice55", listGet(damageArray, 4))]

	[h: damageArray = ""]
	[h, foreach(list, DamageDice6), CODE:
	{
		[h: damage = listGet(DamageDice6,roll.count))]
		[h: damageArray = listAppend(damageArray, damage)]
	}]

	[h: attackArray = setStrProp(attackArray, "unrolledDice11", listGet(damageArray, 0))]
	[h: attackArray = setStrProp(attackArray, "unrolledDice22", listGet(damageArray, 1))]
	[h: attackArray = setStrProp(attackArray, "unrolledDice33", listGet(damageArray, 2))]
	[h: attackArray = setStrProp(attackArray, "unrolledDice44", listGet(damageArray, 3))]
	[h: attackArray = setStrProp(attackArray, "unrolledDice55", listGet(damageArray, 4))]

	[h: Pull.CriticalMultiplier(attackArray)]
	[h: attackArray = macro.return]

	[h, foreach(list, DamageType6), CODE:
	{
		[h: dieType = listGet(DamageType6,roll.count))]
		[h: diceArray = listAppend(diceArray, dieType)]
	}]

	[h: attackArray = setStrProp(attackArray, "damageType11", listGet(diceArray, 0))]
	[h: attackArray = setStrProp(attackArray, "damageType22", listGet(diceArray, 1))]
	[h: attackArray = setStrProp(attackArray, "damageType33", listGet(diceArray, 2))]
	[h: attackArray = setStrProp(attackArray, "damageType44", listGet(diceArray, 3))]
	[h: attackArray = setStrProp(attackArray, "damageType55", listGet(diceArray, 4))]
};{}]

[ if(arg(0) == 7),CODE:
{
	[h: attackArray = setStrProp(attackArray, "attackNumber", "Attack 7")]

	[h: Random.Roller(20)]
	[h: toHitRoll = macro.return]
	[h: attackArray = setStrProp(attackArray, "toHitRoll", macro.return)]

	[h: toHitModifier = DefaultAttackModifier7 + TempAttackModifier]
	[h: toHit = macro.return + toHitModifier]
	[h: attackArray = setStrProp(attackArray, "toHit", toHit)]
	[h: attackArray = setStrProp(attackArray, "toHitModifier", toHitModifier)]

	[h: Random.Roller(20)]
	[h: attackArray = setStrProp(attackArray, "criticalThreatRoll", macro.return)]

	[h: criticalThreatMod = DefaultAttackModifier7 + TempAttackModifier + CriticalThreatModifier]
	[h: criticalThreat = macro.return + criticalThreatMod]
	[h: attackArray = setStrProp(attackArray, "criticalThreat", criticalThreat)]
	[h: attackArray = setStrProp(attackArray, "criticalThreatMod", criticalThreatMod)]

	[h: criticalThreatRange = listGet(CriticalType7, 0)]
	[h: criticalMultiplier = listGet(CriticalType7, 1)]
	[h: criticalHit = if(toHitRoll >= criticalThreatRange, 1, 0)]
	[h: attackArray = setStrProp(attackArray, "criticalHit", criticalHit)]
	[h: attackArray = setStrProp(attackArray, "criticalMultiplier", criticalMultiplier)]

	[h, foreach(list, DamageDice7), CODE:
	{
		[h: damage = eval(listGet(DamageDice7,roll.count))]
		[h: damageArray = listAppend(damageArray, damage)]
	}]

	[h: attackArray = setStrProp(attackArray, "damageDice11", listGet(damageArray, 0))]
	[h: attackArray = setStrProp(attackArray, "damageDice22", listGet(damageArray, 1))]
	[h: attackArray = setStrProp(attackArray, "damageDice33", listGet(damageArray, 2))]
	[h: attackArray = setStrProp(attackArray, "damageDice44", listGet(damageArray, 3))]
	[h: attackArray = setStrProp(attackArray, "damageDice55", listGet(damageArray, 4))]

	[h: damageArray = ""]
	[h, foreach(list, DamageDice7), CODE:
	{
		[h: damage = listGet(DamageDice7,roll.count))]
		[h: damageArray = listAppend(damageArray, damage)]
	}]

	[h: attackArray = setStrProp(attackArray, "unrolledDice11", listGet(damageArray, 0))]
	[h: attackArray = setStrProp(attackArray, "unrolledDice22", listGet(damageArray, 1))]
	[h: attackArray = setStrProp(attackArray, "unrolledDice33", listGet(damageArray, 2))]
	[h: attackArray = setStrProp(attackArray, "unrolledDice44", listGet(damageArray, 3))]
	[h: attackArray = setStrProp(attackArray, "unrolledDice55", listGet(damageArray, 4))]

	[h: Pull.CriticalMultiplier(attackArray)]
	[h: attackArray = macro.return]

	[h, foreach(list, DamageType7), CODE:
	{
		[h: dieType = listGet(DamageType7,roll.count))]
		[h: diceArray = listAppend(diceArray, dieType)]
	}]

	[h: attackArray = setStrProp(attackArray, "damageType11", listGet(diceArray, 0))]
	[h: attackArray = setStrProp(attackArray, "damageType22", listGet(diceArray, 1))]
	[h: attackArray = setStrProp(attackArray, "damageType33", listGet(diceArray, 2))]
	[h: attackArray = setStrProp(attackArray, "damageType44", listGet(diceArray, 3))]
	[h: attackArray = setStrProp(attackArray, "damageType55", listGet(diceArray, 4))]
};{}]

[ if(arg(0) == "H"),CODE:
{
	[h: attackArray = setStrProp(attackArray, "attackNumber", "Haste Attack")]

	[h: Random.Roller(20)]
	[h: toHitRoll = macro.return]
	[h: attackArray = setStrProp(attackArray, "toHitRoll", macro.return)]

	[h: toHitModifier = DefaultAttackModifierH + TempAttackModifier]
	[h: toHit = macro.return + toHitModifier]
	[h: attackArray = setStrProp(attackArray, "toHit", toHit)]
	[h: attackArray = setStrProp(attackArray, "toHitModifier", toHitModifier)]

	[h: Random.Roller(20)]
	[h: attackArray = setStrProp(attackArray, "criticalThreatRoll", macro.return)]

	[h: criticalThreatMod = DefaultAttackModifierH + TempAttackModifier + CriticalThreatModifier]
	[h: criticalThreat = macro.return + criticalThreatMod]
	[h: attackArray = setStrProp(attackArray, "criticalThreat", criticalThreat)]
	[h: attackArray = setStrProp(attackArray, "criticalThreatMod", criticalThreatMod)]

	[h: criticalThreatRange = listGet(CriticalTypeH, 0)]
	[h: criticalMultiplier = listGet(CriticalTypeH, 1)]
	[h: criticalHit = if(toHitRoll >= criticalThreatRange, 1, 0)]
	[h: attackArray = setStrProp(attackArray, "criticalHit", criticalHit)]
	[h: attackArray = setStrProp(attackArray, "criticalMultiplier", criticalMultiplier)]

	[h, foreach(list, DamageDiceH), CODE:
	{
		[h: damage = eval(listGet(DamageDiceH,roll.count))]
		[h: damageArray = listAppend(damageArray, damage)]
	}]

	[h: attackArray = setStrProp(attackArray, "damageDice11", listGet(damageArray, 0))]
	[h: attackArray = setStrProp(attackArray, "damageDice22", listGet(damageArray, 1))]
	[h: attackArray = setStrProp(attackArray, "damageDice33", listGet(damageArray, 2))]
	[h: attackArray = setStrProp(attackArray, "damageDice44", listGet(damageArray, 3))]
	[h: attackArray = setStrProp(attackArray, "damageDice55", listGet(damageArray, 4))]

	[h: damageArray = ""]
	[h, foreach(list, DamageDiceH), CODE:
	{
		[h: damage = listGet(DamageDiceH,roll.count))]
		[h: damageArray = listAppend(damageArray, damage)]
	}]

	[h: attackArray = setStrProp(attackArray, "unrolledDice11", listGet(damageArray, 0))]
	[h: attackArray = setStrProp(attackArray, "unrolledDice22", listGet(damageArray, 1))]
	[h: attackArray = setStrProp(attackArray, "unrolledDice33", listGet(damageArray, 2))]
	[h: attackArray = setStrProp(attackArray, "unrolledDice44", listGet(damageArray, 3))]
	[h: attackArray = setStrProp(attackArray, "unrolledDice55", listGet(damageArray, 4))]

	[h: Pull.CriticalMultiplier(attackArray)]
	[h: attackArray = macro.return]

	[h, foreach(list, DamageTypeH), CODE:
	{
		[h: dieType = listGet(DamageTypeH,roll.count))]
		[h: diceArray = listAppend(diceArray, dieType)]
	}]

	[h: attackArray = setStrProp(attackArray, "damageType11", listGet(diceArray, 0))]
	[h: attackArray = setStrProp(attackArray, "damageType22", listGet(diceArray, 1))]
	[h: attackArray = setStrProp(attackArray, "damageType33", listGet(diceArray, 2))]
	[h: attackArray = setStrProp(attackArray, "damageType44", listGet(diceArray, 3))]
	[h: attackArray = setStrProp(attackArray, "damageType55", listGet(diceArray, 4))]
};{}]

[h: macro.return = attackArray]
And this is an example of the chat window output, obviously without the token images and tool-tip texts.


Well 1: Attack 1 - Threat - 16 (16) 15 (15) ---- 1 (3) Slashing -- 1 Fire -- -- -- -- 2 (3) damage.

Well 1: Attack 1 - 9 ---- 2 Slashing -- 5 Fire -- -- -- -- 7 damage.
Last edited by qcgreywolf on Tue Jan 20, 2015 6:19 pm, edited 1 time in total.

User avatar
wolph42
Winter Wolph
Posts: 9999
Joined: Fri Mar 20, 2009 5:40 am
Location: Netherlands
Contact:

Re: Re-Tooling for GM only text display

Post by wolph42 »

could you pls put your code in code tags, that is the button saying 'code' on top of the post editor. Select code and hit that button!

so what I understand you want to know if (and how) this is possible:

Code: Select all

[h: outputText = strformat("
    <font color = "FF0000">
        <b>[r: attackNumber]</b>
        - [r: if(toHitRoll == 20,"<b>Hit!</b>","Threat")]
        - [r: toHit] ([r: if(criticalHit==1 || toHitRoll == 20,toHitRoll,"")])
        [r: if(criticalHit==1 || toHitRoll == 20,criticalThreat,"")]
        ([r: if(criticalHit==1 || toHitRoll == 20,criticalThreatRoll,"")])
    </font>
")] 
well first of all you're using " both for the strformat string AND the color in the font tag and again in other places, so that CERTAINLY gonna break things. Use " " outside and ' ' inside!

second: the answer to your question is NO: read the introduction here: http://lmwcs.com/rptools/wiki/Introduct ... _syntax.29

it IS however possible in another way as you can embed functions inside functions, (as you canNOT embed macros inside macros, which is what you did).
like this

Code: Select all

[h: outputText = strformat("
    <font color = 'FF0000'>
        <b>%{attackNumber}</b> - " +
            if(toHitRoll == 20,'<b>Hit!</b>','Threat') +
        " - &{toHit} (" + 
            if(criticalHit==1 || toHitRoll == 20,toHitRoll,'')+ 
        ")" + 
            if(criticalHit==1 || toHitRoll == 20,criticalThreat,'')+
        "(" + 
            if(criticalHit==1 || toHitRoll == 20,criticalThreatRoll,'') + 
        ")
    </font>
")] 
What is important here is
1. understand that the ONLY thing you can feed strformat (=STRINGformat) is a string!! (that is text only)
2. if you embed a FUNCTION() (and not a [macro()] ), inside another function than that 'inner function' will get executed first!
to make it applicable: [strformat( if(1,"He", Ho) )] --> the inner function is executed first --> [strformat( "He" )] --> THEN strformat is executed --> "He"
what you did (after I corrected the quotes): [strformat(" [if(1,'He', Ho)] ")] --> now there IS no inner function, and ironically, there is also no macro inside, only a string so this immediately results in: " [if(1,'He', Ho)] "
should you remove the outer " " so its no string: [strformat( [if(1,'He', Ho)] )] than you've violated the core syntax and this will throw up a big error.

qcgreywolf
Cave Troll
Posts: 43
Joined: Mon Dec 09, 2013 10:23 pm

Re: Re-Tooling for GM only text display

Post by qcgreywolf »

Sigh. Thank you, wolph42.

I practically knew the answer, but I wanted someone much more fluent than me to tell me that I couldn't embed if/then statements into strformat() in some creative way.

Another rewriting of my attack macros, here I come! I never really used to understand the statement "code is never finished, just 'good enough'". Thank you maptools for teaching me this lesson :)

User avatar
aliasmask
RPTools Team
Posts: 9031
Joined: Tue Nov 10, 2009 6:11 pm
Location: California

Re: Re-Tooling for GM only text display

Post by aliasmask »

Actually, I never liked the string concatenation method. Too easy to mess up and I'm not a fan of the readability of it. Here's another way to do it:

Code: Select all

[h: outputText = strformat("
    <font color = "FF0000">
        <b>%{attackNumber}</b> - %s - %{toHit} (%s) %s (%s)
    </font>
    ",
    if(toHitRoll == 20,"<b>Hit!</b>","Threat"),
    if(criticalHit==1 || toHitRoll == 20,toHitRoll,""),
    if(criticalHit==1 || toHitRoll == 20,criticalThreat,""),
    if(criticalHit==1 || toHitRoll == 20,criticalThreatRoll,"")
)] 
If you have a single variable name you can use %{variableName} in strformat. The %s is a string substitution and goes in order after the first string of strformat. So strformat(string,arg1,arg2,arg3,...). I actually try to avoid this method because of a MT "thing" when using % in the string. If you want to display % you have to put %% when using the strformat method with arguments. Otherwise, you can use % without the change.

My preferred method is to simply give each argument their own variable name before I use strformat and use %{variableName} instead of %s.


qcgreywolf
Cave Troll
Posts: 43
Joined: Mon Dec 09, 2013 10:23 pm

Re: Re-Tooling for GM only text display

Post by qcgreywolf »

So, I am in the process of retooling the meaty attack macro mentioned above, and I am running into an odd output error.

Firstly, I have narrowed it entirely down to this little piece of code, if I remove it, everything works as intended, and nothing else has been touched (yet).

For troubleshooting purposes, I have it doing double output.

When I use the Roll Options, r: t: h: or no Roll Options, the output is displayed exactly as I would expect.

example(ugly, without my text formatting);

Attack 1 - Threat - 12 (12) 3 (3) Attack 1 - Threat - 12 (12) 3 (3) ---- 5 (11) Slashing -- 5 Fire -- -- -- -- 10 (11) damage.

however, as soon as I use the g: roll option (or any combination, such as r,g:) I get this hideous output that is visible to all players.

gtextOutput = Attack 1 - Threat - 17 (17) 9 (9)Attack 1 - Threat - 17 (17) 9 (9)«  Attack 1 - Threat - 17 (17) 9 (9) ---- 6 (9) Slashing -- 3 Fire -- -- -- -- 9 (9) damage.
 »

EDIT: if I change any of the r: in the 'old way' to a g:, it also breaks the chat output. Is there a rule somewhere for g: that I am missing? The g: roll option wiki is pretty sparse.

Below is the code block that I have added, any glaring problems that I am overlooking?

Code: Select all

[h: varsFromStrProp(arg(0))]
[h: varsFromStrProp(arg(1))]
[h: varsFromStrProp(arg(2))]
[h: gmOnly = isNPC()]

<tr>
<td>
[if(criticalHit == 1 || toHitRoll == 20), code:
{
[h: output.tip = strformat("<html>
   <table><tr><td colspan=2><b><center>To Hit Rolls</center></b></td></tr>
      <tr><td>d20 Roll:</td><td>%{toHitRoll}</td><td>Threat Roll:</td><td>%{criticalThreatRoll}</td></tr>
      <tr><td>Modifier:</td><td>%{toHitModifier}</td><td>Threat Modifier:</td><td>%{criticalThreatMod}</td></tr>
   </table></html>")]

[h: '<!-- Begin code I just added-->']
[h: '<!-- New way of building chat output-->']

[h: textOutput = strformat("<b>%{attackNumber}</b> - ")]
[h: textBuilder = ""]
[h: textBuilder = if(toHitRoll == 20,"<b>Hit! - </b>","Threat - ")]
[h: textOutput = concat(textOutput, textBuilder, toHit, " ")]
[h: textBuilder =  if(criticalHit==1 || toHitRoll == 20,toHitRoll,"")]
[h: textOutput = concat(textOutput, "(", textBuilder, ")", " ")]
[h: textBuilder =  if(criticalHit==1 || toHitRoll == 20,criticalThreat,"")]
[h: textOutput = concat(textOutput, textBuilder, " ")]
[h: textBuilder =  if(criticalHit==1 || toHitRoll == 20,criticalThreatRoll,"")]
[h: textOutput = concat(textOutput, "(", textBuilder, ")")]

[g: textOutput]
<br>

[h: '<!-- Old way of building chat output -->']

<span title="{output.tip}">
<font color = "FF0000">
<b>[r: attackNumber]</b>  - [r: if(toHitRoll == 20,"<b>Hit!</b>","Threat")] - [r: toHit] ([r: if(criticalHit==1 || toHitRoll == 20,toHitRoll,"")]) [r: if(criticalHit==1 || toHitRoll == 20,criticalThreat,"")] ([r: if(criticalHit==1 || toHitRoll == 20,criticalThreatRoll,"")])
</font>
</span>

[h: '<!-- End code I just added-->']

};
{
  [if(attackPresent1 == "Yes"), CODE:
    {

    [h: output.tip = strformat("<html>
   <table><tr><td colspan=2><b><center>To Hit Roll</center></b></td></tr>
      <tr><td>d20 Roll:</td><td>%{toHitRoll}</td></tr>
      <tr><td>Modifier:</td><td>%{toHitModifier}</td></tr>
   </table></html>")]

    <span title="{output.tip}">
    <b>[r: attackNumber] - </b> [r: toHit]
    [r: if(toHitRoll == 1, " - CRITICAL MISS! - ", "")]
    </span>
    };{}]

}]
</td>

User avatar
aliasmask
RPTools Team
Posts: 9031
Joined: Tue Nov 10, 2009 6:11 pm
Location: California

Re: Re-Tooling for GM only text display

Post by aliasmask »

I recommend making sure "Insert Smilies" is unchecked and "Use ToolTips for Inline Rolls" is checked in the preferences (which is probably responsible for weird output).

I also recommend that you use strformat instead of concat and put all your output in to a variable. If you make all your checks before hand, you can format your output in one line.

I would also comment as to what the variables are from the varsFromStrProp results. You use these variables
Spoiler
toHit
toHitRoll
criticalHit
criticalThreat
criticalThreatRoll
criticalThreatMod
toHitModifier
attackNumber
but don't really say what they are. That's when comments are good because a month from now you'll be asking yourself the same question with your own code.

I also recommend a cleaner output and put the other stuff in the tooltip (bottom part of image). Here's an example of what I do. All you really need to show is what AC you hit, add the crit threat roll only if there is a crit threat and then the damage. My output is pretty fancy and covers a lot of different options, but at the core it only shows the hit AC and damage and hides the rest in the tooltip.
Attachments
Attack example.jpg
Attack example.jpg (92.08 KiB) Viewed 804 times

qcgreywolf
Cave Troll
Posts: 43
Joined: Mon Dec 09, 2013 10:23 pm

Re: Re-Tooling for GM only text display

Post by qcgreywolf »

I unchecked smilies and Use inline tool tips was already checked. That was a good catch, although it was not the issue. I had recently re-installed windows and that could have been an issue at some point.

Looking at your output, my final product is very close to yours(sadly, just not as pretty). I only posted the small snippet of code that I am working on right now, the output for the critical hits. If there is not a critical threat(or nat 20), none of that stuff is displayed! On a regular roll, only the toHit is displayed followed by the base damages. The damages only show up if they are used, and in my tooltips I parse out all the individual damage dice rolls, so the player can see which parts of the 52 damage are from temp stuff, str, weapon dice, sneak attack dice, elemental dice and so on. If there is a threat(or nat 20), THEN all the crit info is displayed.

As an end result, that is a great idea, to get rid of the concat(), I do not like how messy it is. It would not fix the current issue, however. There is something weird going on with my UDF's...

This might help more, here is a screen shot of the actual output, this one is with absolutely nothing altered;
https://onedrive.live.com/redir?resid=B ... hoto%2cjpg

This one is making one tiny little change, this is NOT my new code, this is my pre-existing code, all I did was change a simple [r:] to a [g:]. Which, correct me if I am wrong, should always(?) change the output to GM only, especially if there is no code, just a variable [g: attackNumber] (which is just a var containing the current iterative attack.)
https://onedrive.live.com/redir?resid=B ... hoto%2cjpg

All the relevant macros are Trusted Macros, just went through and checked.

Some are "Apply to Selected Tokens", if it is required for that step of the UDF.

All of my one-shot macros do not have this behavior. I have a bunch of macros that handle skills, cure spells, damage, etc; they all have GM only output (with both [g:] and [r,g:]).

Only this big honken attack macro (5ish UDFs) does this with the output.

Here is a link to my campaign file, stripped down to just the Lib Token map, which is enough to use all my macro's, if that will help as well. I left in the [r,g:] in the attack output, so people can possible see it in their maptools as well. The "Full Attack" button at the top of the Campaign tab is what attacks.

https://onedrive.live.com/redir?resid=B ... le%2ccmpgn

User avatar
aliasmask
RPTools Team
Posts: 9031
Joined: Tue Nov 10, 2009 6:11 pm
Location: California

Re: Re-Tooling for GM only text display

Post by aliasmask »

g,r shows up in your output which means you either left out a [ or you have a quote or single quote causing a problem somewhere in your code.

I notice you have this in your code:

Code: Select all

			<!-- Rolling to-hit's -->
The parser doesn't care about html comments and will see the ' and mess with your output. I don't recommend putting ', ", [] or {} in your html comments.

I did change that one line and it didn't fix it though. But I would look for something similar somewhere else other than in lib:IO where I looked.

User avatar
aliasmask
RPTools Team
Posts: 9031
Joined: Tue Nov 10, 2009 6:11 pm
Location: California

Re: Re-Tooling for GM only text display

Post by aliasmask »

One major thing you're doing wrong is how you handle macro.return and UDFs. UDFs don't use macro.return to return the data, for example:

Code: Select all

[H: value = myUDF()]
NOT

Code: Select all

[H: myUDF()]
[H: value = macro.return]
Technically, this could work because macro.return if you specified the UDF to display output will put all the output in to macro.return, but that includes html comments and even some random stuff like character strings in statements. At the end of your UDF, if you put macro.return = result, or whatever values you want to return will return that value in place of the UDF call as in the first example.

Somewhere in your code it's generating a funky character when criticalHit == 1 || toHitRoll == 20 because it'll crash the rest of the code when I use my debug tool, essentially saying the code isn't formatted correctly.

I think it may be related the macro.return usage. For most functions, macro.return should only be in a function once and at the end to send data back to calling function when using UDFs.

I recommend using my starter kit found here which automatically makes all your macros in to UDFs and includes a basic output function.

http://forums.rptools.net/viewtopic.php ... 31#p255459

The zip file contains 2 rptok files and if you drop them in to your campaign you can read the notes on how and why to use. The zip file also has info about installing Notepad++ to edit your lib files.

qcgreywolf
Cave Troll
Posts: 43
Joined: Mon Dec 09, 2013 10:23 pm

Re: Re-Tooling for GM only text display

Post by qcgreywolf »

Hrm, that's disturbing. I'll do a quick rewrite of that now, that's not too hard to fix.

Also, my eyeballs are bleeding now, but I used Natepad++ to Fined/Count all the { [ } ] " ' ( ) in my code, all are matched numerically at least, and I didn;t see any missing sets skimming all my code.

And it makes my OCD scream in despair, but I removed all punctuation from my comments :)

An interesting side note, if I put a [g: junkvar] at the very end of the first (calling) macro, it outputs fine. If I put in a [g: junkvar] in the first line of the first called UDF, it does the junk output. Should that not prove that there is at least a correct matching set of {}, [] and ()?

Still digging. And thanks for the input/help Aliasmask, I appreciate it.

qcgreywolf
Cave Troll
Posts: 43
Joined: Mon Dec 09, 2013 10:23 pm

Re: Re-Tooling for GM only text display

Post by qcgreywolf »

Quick question on the UDF front;

Is it sufficient to have;

(pseudocode)
[h: arrayHasBeenProcessed = Pull.CriticalMultiplier(arrayIWantToProcess)]
to call the UDF

actual code

Code: Select all

	[h: attackArray = Pull.CriticalMultiplier(attackArray)]
and the called code has(at the very end of the UDF);

(pseudocode)
[macro.return=arrayHasBeenProcessed]

actual code

Code: Select all

[macro.return=attackArray]
Even though all 3 of the var names are the same (it's all the save var, just being processed), does that function as I think it does across UDF boundaries?

User avatar
aliasmask
RPTools Team
Posts: 9031
Joined: Tue Nov 10, 2009 6:11 pm
Location: California

Re: Re-Tooling for GM only text display

Post by aliasmask »

I don't think so, if I'm understanding the language of the function. Pull.CriticalMultiplier sounds like the only thing you're doing is obtaining the crit multiple from the attack array.

Code: Select all

[H: criticalMultiplier = Pull.CriticalMultiplier(attackArray)]
As long as the UDF uses a different scope (by default) then any changes to attackArray are ignored in the calling macro. Now, if you want to update the array and return the new array then that looks like what you're doing. But by the naming convention, that doesn't seem to be the case. That would be more like:

Code: Select all

[H: new.attackArray = update.attackArray(attackArray)]
[H: macro.return = new.attackArray]
Naming convention is a minor point for the program running (you could use s23n2ls34 for a name, it doesn't care) but for readability the function names should be relevant. Also, another trap is reusing the same variable name in multiple spots eventhough the data, type or usage changes. If I have some type of complicated data structure I usually put a comment at the top of function where it is created to specify its use and components. An example I had handy:
Spoiler

Code: Select all

<!-- getSaveLink(linkObj): link

linkObj
   saveType - use fort, ref or will for save types
   targetDC - DC of save
   success - Output when successful
   fail - Output when failed
   altText - alternate text for the link
   targets - who can see the results of roll

This function will save data on provoking token that other tokens may test against target DC to get the resultant output -->
edit: On a side note, arrayHasBeenProcessed is more like resultIWantToSendBack.

qcgreywolf
Cave Troll
Posts: 43
Joined: Mon Dec 09, 2013 10:23 pm

Re: Re-Tooling for GM only text display

Post by qcgreywolf »

I re-tooled all my macros so they do not use the macro.return var in the calling macros, I decided to use a token property to transfer the arrays between UDF's instead.

I looked at the variable vomit between many steps, and did not notice any strange artifacts in them (I did find a really weird hex-like anomaly in a non-related macro, that didn't effect anything, but I fixed it anyway, thanks for suggesting to look for odd output hidden in my variables).

I think I am going to have to completely rebuild my attack macros again with the intention of adding GM only output. Not something I want to do without additional ideas or upgrades just yet.

If anyone else has any other ideas, let me know. Thanks for assisting Aliasmask!


https://onedrive.live.com/redir?resid=B ... le%2ccmpgn

User avatar
aliasmask
RPTools Team
Posts: 9031
Joined: Tue Nov 10, 2009 6:11 pm
Location: California

Re: Re-Tooling for GM only text display

Post by aliasmask »

Yeah, when I create output for players and gms/owners I usually do it as 2 different tool tips. Using UDFs is a really good tool and makes coding easier. You should look at my onCampaignLoad of my lib:token example. It suppresses all output and has a custom output function that handles group types not inherent in MapTool. In this case I have "owner" which is the gm and whoever has ownership of token and "other" for everyone else. So, I may have something like this:

Code: Select all

...
[H: am.xx.output.basic(ownerText,"owner",currentToken())]
[H: am.xx.output.basic(playerText,"other",currentToken())]

Post Reply

Return to “Macros”