Help creating a Macro.

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
SquirrelDude
Kobold
Posts: 6
Joined: Sat Nov 24, 2012 7:07 pm

Help creating a Macro.

Post by SquirrelDude »

New to Maptool + No experience in Computer Science = Problems with creating macros. I think, unless my syntax is wrong. >.>

I'm trying to create a Macro for a Pathfinder campaign.
Token Properties in use: CharacterName, BaseAttackBonus, StrengthBonus

The code as it now stands.
Spoiler
[r: CharacterName] strikes!
[h: AtkMod = BaseAttackBonus+StrengthBonus+2+MiscAtkBonus]
[r: CharacterName] has a +[r: AtkMod] to attack rolls. <br>

[h: ResultA = 1d20]<br>
[h: rollA = ResultA + AtkMod]
[h: Damage = 1d8 + StrengthBonus + MiscDmgBonus + ExtraDice]

{if( ResultA == 1, "<br> It is a roll of a natural 1 on the twenty-side die, the attack misses.", " ")}
{if( ResultA > 1 && ResultA < 19, CharacterName + " rolls a " + rollA + ". The attack does " + Damage " damage.", " ")}
{if( ResultA >= 19, CharacterName + " rolls a " + rollA + ". <br>" + CharacterName +"<b> scored a critical threat </b> and rolls to confirm the critical."," ")}

[h: ResultB = 1d20 ]
[h: rollB = ResultB + AtkMod]
[h: CritDamage = 2d8 + 2*StrengthBonus + 2*MiscDmgBonus + ExtraDice]
{if(ResultB == 1, "The roll is a natural 1, the attack is not a critical.", " "}
{if(ResultB != 1, "The result is " + rollB + ". If the attack is hit, then the attack does " +CritDamage + ".", " ")


I'm not seeing the problem with the code, or why it isn't working. The error I'm being given is
java.lang.NullPointerException error executing expression
I removed the {if(ResultA...)} statements and there are also apparently problems with the {if(ResultB...)} codes. The other issue is that the {if(ResultB...)} will be run whether or not the attack is a critical. I was wondering if anyone knew how to do that.

User avatar
JML
Dragon
Posts: 515
Joined: Mon May 31, 2010 7:03 am
Location: Blagnac, France

Re: Help creating a Macro.

Post by JML »

Working much better with the matching ")", "}" and "+" :wink:

Code: Select all

[r: CharacterName] strikes!
[h: AtkMod = BaseAttackBonus+StrengthBonus+2+MiscAtkBonus]
[r: CharacterName] has a +[r: AtkMod] to attack rolls. <br>

[h: ResultA = 1d20]<br>
[h: rollA = ResultA + AtkMod]
[h: Damage = 1d8 + StrengthBonus + MiscDmgBonus + ExtraDice]

{if( ResultA == 1, "<br> It is a roll of a natural 1 on the twenty-side die, the attack misses.", " ")}
{if( ResultA > 1 && ResultA < 19, CharacterName + " rolls a " + rollA + ". The attack does " + Damage + " damage.", " ")}
{if( ResultA >= 19, CharacterName + " rolls a " + rollA + ". <br>" + CharacterName +"<b> scored a critical threat </b> and rolls to confirm the critical."," ")}

[h: ResultB = 1d20 ]
[h: rollB = ResultB + AtkMod]
[h: CritDamage = 2d8 + 2*StrengthBonus + 2*MiscDmgBonus + ExtraDice]
{if(ResultB == 1, "The roll is a natural 1, the attack is not a critical.", " ")}
{if(ResultB != 1, "The result is " + rollB + ". If the attack is hit, then the attack does " + CritDamage + ".", " ")} 
I would suggest using [if:] instead of Wiki: if() when you have choice, as the latter executes both the true and false instructions even if it displays only one. This can update variables and properties when you don't want it.
You could do this:

Code: Select all

[r, if( ResultA == 1): "<br> It is a roll of a natural 1 on the twenty-side die, the attack misses."] 

User avatar
JML
Dragon
Posts: 515
Joined: Mon May 31, 2010 7:03 am
Location: Blagnac, France

Re: Help creating a Macro.

Post by JML »

Late thought: to avoid forgetting matching symbols like (), etc. I use to type both at once and then type back inside them. I don't have to think of it again this way. As a coder laziness is your friend :twisted:

User avatar
aliasmask
RPTools Team
Posts: 9023
Joined: Tue Nov 10, 2009 6:11 pm
Location: Bay Area

Re: Help creating a Macro.

Post by aliasmask »

First off, welcome to the world of macro writing. There's a lot of stuff to learn, but lets concentrate on some basics to make things easier for you. Here are some simple guidelines and tips to help you along.
  • Use variable naming best practices. You'll find yourself looking at code you wrote a month later and asking yourself what you were thinking. So, don't abbreviate a word in the variable. Of course, there are exceptions to the rule for very well known acronyms. Also, the first word is usually lower case and additional words have the first letter capitalized (like variableName or strengthBonus).
  • Don't rely on magic variables. When you define properties on a token, those variables essentially become global variables and can be reference in any macro on that token. This does make things easier at first, but can lead to problems for properties with common words. You'll likely end up accidentally changing a variable when you don't mean to. You'll also have to make your code less clear to accommodate the use of the variable because the reader will see a variable name, but no source. And to avoid accidentally changing the global name, you'll have to tweak the variable name like tStrength to avoid mix ups. I recommend your global property names be a little more complicated to avoid those kind of mix ups like stat.strength. Also, I generally don't include any global properties on a token unless it appears on the stat sheet. Using Wiki: setProperty() and Wiki: getProperty() is the preferred method for getting/setting variables. But if you really do need to use a global variable, you should at least comment that it is a global variable or give a hint as to its use.
  • Use html comments (<!-- comment -->) in code on separate lines. This helps you define and organize what you are doing and make it easier to read later on. Warning: Don't use ', {} or anything that looks like code in your comments because the MT parser doesn't like it or will execute it. MT doesn't care if your code is in html comments, it will still execute it.
  • Assign your output to a variable. Mixing code and raw output leaves a lot of room for simple mistakes and makes the code hard to read.
  • Indent your code. This is another tip to improve the readability of your code and to separate logic.
  • Use {} sparingly. You only get to nest it twice. Instead use [r:].
  • Provide structure to your code. Generally speaking, this is the basic flow of your code:
    • Get/Define Data - get needed data from your sources. This can be done by defining local variables from passed arguments to function, using Wiki: getProperty() to get data from a token, requesting Wiki: input() from the user or just setting some constants to be used later in the code like lists or a default value.
    • Process Data - After you have all your numbers you can then do your number crunching. You'll likely have to store your data and the urge to print it right away is there, but you're better off saving the end results in variables and leave the output for the last step.
    • Output/Save Data - Having all your output done in one location and at the end not only makes it easier to read and debug, but also makes it easy to manipulate and change when needed.
Here's my take on a macro rewrite of your code:

Code: Select all

<!-- macro re-write -->

<!-- Get needed data -->
[H: BAB = getProperty("BaseAttackBonus")]
[H: strengthBonus = getProperty("StrengthBonus")]
[H: miscAttackBonus = getProperty("MiscAtkBonus")]
[H: miscDamageBonus = getProperty("MiscDamageBonus")]
[H: extraDiceDamage = getProperty("ExtraDice")]
[H: name = getProperty("CharacterName")]

<!-- predefined data, constants and variable initialization -->
[H: dieRoll = 1d20]
[H: critRoll = 1d20]
[H: fumble = 1]
[H: critThreat = 19]
[H: weaponBaseDamage = "1d8"]
<!-- This could be due to feats and special abilities -->
[H: weaponBaseAttackMod = 2]
[H: critMultiplier = 2]

<!-- Process data -->
<!-- ATTACK -->
[H: attackMod = BAB + strengthBonus + miscAttackBonus + weaponBaseAttackMod]
[H: attackResult = dieRoll + attackMod]
[H: critResult = critRoll + attackMod]
[H: isFumble = if(dieRoll == fumble,1,0)]
[H: isCritThreat = if(dieRoll >= critThreat,1,0)]

<!-- make a tooltip for the attack with attack details -->
[H: output.tip = strformat("<html>
   <table><tr><td colspan=2><b><center>ATTACK</center></b></td></tr>
      <tr><td>Attack Roll:</td><td>%{dieRoll}</td></tr>
      <tr><td>Crit Threat Roll:</td><td>%{critRoll}</td></tr>
      <tr><td>BAB:</td><td>%{BAB}</td></tr>
      <tr><td>Strength Bonus:</td><td>%{strengthBonus}</td></tr>
      <tr><td>Misc Attack Bonus:</td><td>%{miscAttackBonus}</td></tr>
      <tr><td>Weapon Attack Mod:</td><td>%{weaponBaseAttackMod}</td></tr>
      <tr><td><b>Attack Result:</b></td><td><b>%{attackResult}</b></td></tr>
   </table></html>")]
[H: output.attack = strformat("%{name} hits AC %{attackResult}%s",
   if(isFumble," (Fumble)",if(isCritThreat,strformat(" (Crit: %{critResult})"),"")))]
[H: output = strformat('<span title="%{output.tip}">%{output.attack}</span>')]
   
<!-- DAMAGE -->
[H, if(! isFumble), code: {
   [H: weaponBaseDamageResult = eval(weaponBaseDamage)]
   [H: damage = weaponBaseDamageResult + strengthBonus + miscDamageBonus + extraDiceDamage]
   [H: critDamage = damage]
   [H: critDamageRolls = weaponBaseDamageResult]
   <!-- I put loop here because the crit damage is rolled separately rather than just multiplied -->
   [H, C(critMultiplier-1), code: {
      [H: critBaseDamage = eval(weaponBaseDamage)]
      [H: critDamageRolls = listAppend(critDamageRolls,critBaseDamage)]
      [H: critDamage = critDamage + critBaseDamage + strengthBonus + miscDamageBonus]
   }]
   
   <!-- make a tooltip for the damage with damage details -->
   [H, if(isCritThreat): critRollString = strformat("<tr><td>Crit Damage Roll(s):</td><td>%{critDamageRolls}</td></tr>"); critRollString = ""]
   [H, if(isCritThreat): critTotalString = strformat('
         <tr style="color:red"><td><b>Crit Damage Total:</b></td><td><b>%{critDamage}</b></td></tr>
         <tr><td style="font-size:8px" colspan=2><i><b>note:</b> critical damage total is the damage total with successful critical.</i></td></tr>'); 
      critTotalString = ""]
   [H: output.tip = strformat("<html>
      <table><tr><td colspan=2><b><center>DAMAGE</center></b></td></tr>
         <tr><td>Weapon Base Damage:</td><td>%{weaponBaseDamage} = %{weaponBaseDamageResult}</td></tr>
         %{critRollString}
         <tr><td>Strength Damage:</td><td>%{strengthBonus}</td></tr>
         <tr><td>Misc Damage Bonus:</td><td>%{miscDamageBonus}</td></tr>
         <tr><td>Extra Dice Damage:</td><td>%{extraDiceDamage}</td></tr>
         <tr><td><b>Damage Total:</b></td><td><b>%{damage}</b></td></tr>
         %{critTotalString}
      </table></html>")]
   [H: output.damage = strformat('DAMAGE: %{damage}%s',if(isCritThreat,strformat(" (%{critDamage})"),""))]
   [H: output = output + "<br>" + strformat('<span title="%{output.tip}" style="color:red">%{output.damage}</span>')]
};{}]

<!-- OUTPUT -->
[R: output] 
edit: Code tested as good. But I should also note that there is no validation for the variables in this example. So, if things are blank, there could be problems.
... OUTPUT ...
example.jpg
example.jpg (95.71 KiB) Viewed 3944 times
. Note that I edited the output image to include the tooltip popups with the attack. You have to mouse over the Attack/Damage to see tooltip. You can use my test token to see how it works.

To better understand the code, I recommend reading the wiki on Wiki: strformat(), the difference between Wiki: if() and [if:], Wiki: eval(), and some of the Tutorials on Macro Branching and Loops.

In my signature, I have links to Notepad++ and RPEdit drop-in. I use these for all my big and small projects when creating macros. Notepad++ with the MapTool keyword highlighting and function tips should be a real help. RPEdit is useful for updating your macros in MapTool.

keyword: amsave bestpractices attackmacro
Attachments
Test Token Attack Macro.rptok
(175.83 KiB) Downloaded 105 times

SquirrelDude
Kobold
Posts: 6
Joined: Sat Nov 24, 2012 7:07 pm

Re: Help creating a Macro.

Post by SquirrelDude »

I. Derp on the lack of matching parenthesis/brackets.

II. Alias. That looks pretty awesome. I tested it and it seems to work (atleast the program isn't yelling at me about how broken it is). There are a few things that worry me, though.
1. It's not asking me for the MiscAtkBonus/MiscDamageBonus/Extradice like I would expect considering that I don't have those put in as token properties.
2. When it runs, I'm getting attack roll results ranging from 113 to 132. The character who I'm using to test this has a StrengthBonus of 6 and a BaseAttackBonus of 5.

User avatar
aliasmask
RPTools Team
Posts: 9023
Joined: Tue Nov 10, 2009 6:11 pm
Location: Bay Area

Re: Help creating a Macro.

Post by aliasmask »

For my test, I just set those values on the token. You should use an Wiki: input() dialog to set that data. The attack roll results probably are trying to add an empty space to attack so you end up with a string rather than a number. For example, if I add 13 + "" + 2 I get 132 rather than 15. That's what I was talking about with data validation.

SquirrelDude
Kobold
Posts: 6
Joined: Sat Nov 24, 2012 7:07 pm

Re: Help creating a Macro.

Post by SquirrelDude »

Thanks for the tips. I've made a few changes to it so that it will be easier for me to quickly create a set of attack macros for each token.

I only made a few changes, so I saw no reason to overly expand the page.

Code: Select all

<!-- Rogue Composite Longbow Sneak Attack -->

<!-- Get needed data. Replace Dexterity with Strength and vice versa in the calculations when necessary.-->
[H: BAB = getProperty("BaseAttackBonus")]
[H: strengthBonus = getProperty("StrengthBonus")]
[H: dexterityBonus = getProperty("DexterityBonus")]
[H: name = getProperty("CharacterName")]

<!-- Make extraDiceDamage = 0 when applying to a rogue, except for "Sneak Attack" macro -->
[H: extraDiceDamage = getProperty("ExtraDice")]

<!-- Ask player for input -->
[h: input("MiscAttackBonus","MiscDamageBonus")]
[H: miscAttackBonus = MiscAttackBonus]
[H: miscDamageBonus = MiscDamageBonus]

<!-- Weapon information. Adjust for each character/attack macro -->
[H: dieRoll = 1d20]
[H: critRoll = 1d20]
[H: fumble = 1]
[H: critThreat = 20]
[H: weaponBaseDamage = "1d8"]
<!-- This could be due to feats, magic and special abilities -->
[H: weaponBaseAttackMod = 2]
[H: weaponDamageBonus = 1]
[H: critMultiplier = 3]

<!-- Process data -->
<!-- ATTACK -->
[H: attackMod = BAB + dexterityBonus + miscAttackBonus + weaponBaseAttackMod]
[H: attackResult = dieRoll + attackMod]
[H: critResult = critRoll + attackMod]
[H: isFumble = if(dieRoll == fumble,1,0)]
[H: isCritThreat = if(dieRoll >= critThreat,1,0)]

<!-- make a tooltip for the attack with attack details -->
[H: output.tip = strformat("<html>
   <table><tr><td colspan=2><b><center>ATTACK</center></b></td></tr>
      <tr><td>Attack Roll:</td><td>%{dieRoll}</td></tr>
      <tr><td>Crit Threat Roll:</td><td>%{critRoll}</td></tr>
      <tr><td>BAB:</td><td>%{BAB}</td></tr>
      <tr><td>Dexterity Bonus:</td><td>%{dexterityBonus}</td></tr>
      <tr><td>Misc Attack Bonus:</td><td>%{miscAttackBonus}</td></tr>
      <tr><td>Weapon Attack Mod:</td><td>%{weaponBaseAttackMod}</td></tr>
      <tr><td><b>Attack Result:</b></td><td><b>%{attackResult}</b></td></tr>
   </table></html>")]
   
<!-- change output depending on character and weapon, to better describe action -->
[H: output.attack = strformat("%{name} fires his longbow, getting sneak attack, and hitting an AC of %{attackResult}%s",
   if(isFumble," (Fumble)",if(isCritThreat,strformat(" (Crit: %{critResult})"),"")))]
[H: output = strformat('<span title="%{output.tip}">%{output.attack}</span>')]
   
<!-- DAMAGE. Remove strength bonus for most ranged weapons in damage calculation and tooptip -->
[H, if(! isFumble), code: {
   [H: weaponBaseDamageResult = eval(weaponBaseDamage)]
   [H: damage = weaponBaseDamageResult + strengthBonus + miscDamageBonus + weaponDamageBonus + extraDiceDamage]
   [H: critDamage = damage]
   [H: critDamageRolls = weaponBaseDamageResult]
   <!-- I put loop here because the crit damage is rolled separately rather than just multiplied -->
   [H, C(critMultiplier-1), code: {
      [H: critBaseDamage = eval(weaponBaseDamage)]
      [H: critDamageRolls = listAppend(critDamageRolls,critBaseDamage)]
      [H: critDamage = critDamage + critBaseDamage + strengthBonus + miscDamageBonus + weaponDamageBonus]
   }]
   
   <!-- make a tooltip for the damage with damage details -->
   [H, if(isCritThreat): critRollString = strformat("<tr><td>Crit Damage Roll(s):</td><td>%{critDamageRolls}</td></tr>"); critRollString = ""]
   [H, if(isCritThreat): critTotalString = strformat('
         <tr style="color:red"><td><b>Crit Damage Total:</b></td><td><b>%{critDamage}</b></td></tr>
         <tr><td style="font-size:8px" colspan=2><i><b>note:</b> critical damage total is the damage total with successful critical.</i></td></tr>'); 
      critTotalString = ""]
   [H: output.tip = strformat("<html>
      <table><tr><td colspan=2><b><center>DAMAGE</center></b></td></tr>
         <tr><td>Weapon Base Damage:</td><td>%{weaponBaseDamage} = %{weaponBaseDamageResult}</td></tr>
         %{critRollString}
          <tr><td>Strength Damage:</td><td>%{strengthBonus}</td></tr>
         <tr><td>Misc Damage Bonus:</td><td>%{miscDamageBonus}</td></tr>
         <tr><td>Extra Dice Damage:</td><td>%{extraDiceDamage}</td></tr>
         <tr><td>Weapon Damage Bonus:</td><td>%{weaponDamageBonus}</td></tr>
         <tr><td><b>Damage Total:</b></td><td><b>%{damage}</b></td></tr>
         %{critTotalString}
      </table></html>")]
   [H: output.damage = strformat('DAMAGE: %{damage}%s',if(isCritThreat,strformat(" (%{critDamage})"),""))]
   [H: output = output + "<br>" + strformat('<span title="%{output.tip}" style="color:red">%{output.damage}</span>')]
};{}]

<!-- OUTPUT -->
[R: output] 
Key changes:
- added the suggested input(...) function.
- Added weaponDamageBonus to go along with the weaponBaseAtttackMod
- Had the macro also grab the Dexterity Bonus in case it was necessary for ranged attacks or melee attacks using weapon finesse

I've tested the program with using attacks that have a 1.5 strength bonus to damage. They work fine, except for the hiccup that the tooltip has trouble showing this bonus. It's still calculated properly though, so I'm okay with that.

I may just add a [H: strengthDamageBonus = strengthBonus] or a [H: strengthDamageBonus = 1.5*strengthBonus] when necessary and move the strengthDamage where it needs to be if I get annoyed/less lazy enough.

Thank you very much for the help. :D
Last edited by SquirrelDude on Mon Nov 26, 2012 6:40 pm, edited 3 times in total.

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

Re: Help creating a Macro.

Post by wolph42 »

SquirrelDude wrote:(...) Thank you very much for the help. :D
You might want to add a code block around that, cause code really is not readable on this forum without the code block. You can then also leave out the spoiler tags...:

Code: Select all

<!-- Rogue Composite Longbow Sneak Attack -->

<!-- Get needed data. Replace Dexterity with Strength and vice versa in the calculations when necessary.-->
[H: BAB = getProperty("BaseAttackBonus")]
[H: strengthBonus = getProperty("StrengthBonus")]
[H: dexterityBonus = getProperty("DexterityBonus")]
[H: name = getProperty("CharacterName")]

<!-- Make extraDiceDamage = 0 when applying to a rogue, except for "Sneak Attack" macro -->
[H: extraDiceDamage = getProperty("ExtraDice")]

<!-- Ask player for input -->
[h: input("MiscAttackBonus","MiscDamageBonus")]
[H: miscAttackBonus = MiscAttackBonus]
[H: miscDamageBonus = MiscDamageBonus]

<!-- Weapon information. Adjust for each character/attack macro -->
[H: dieRoll = 1d20]
[H: critRoll = 1d20]
[H: fumble = 1]
[H: critThreat = 20]
[H: weaponBaseDamage = "1d8"]
<!-- This could be due to feats, magic and special abilities -->
[H: weaponBaseAttackMod = 2]
[H: weaponDamageBonus = 1]
[H: critMultiplier = 3]

<!-- Process data -->
<!-- ATTACK -->
[H: attackMod = BAB + dexterityBonus + miscAttackBonus + weaponBaseAttackMod]
[H: attackResult = dieRoll + attackMod]
[H: critResult = critRoll + attackMod]
[H: isFumble = if(dieRoll == fumble,1,0)]
[H: isCritThreat = if(dieRoll >= critThreat,1,0)]

<!-- make a tooltip for the attack with attack details -->
[H: output.tip = strformat("<html>
   <table><tr><td colspan=2><b><center>ATTACK</center></b></td></tr>
      <tr><td>Attack Roll:</td><td>%{dieRoll}</td></tr>
      <tr><td>Crit Threat Roll:</td><td>%{critRoll}</td></tr>
      <tr><td>BAB:</td><td>%{BAB}</td></tr>
      <tr><td>Dexterity Bonus:</td><td>%{dexterityBonus}</td></tr>
      <tr><td>Misc Attack Bonus:</td><td>%{miscAttackBonus}</td></tr>
      <tr><td>Weapon Attack Mod:</td><td>%{weaponBaseAttackMod}</td></tr>
      <tr><td><b>Attack Result:</b></td><td><b>%{attackResult}</b></td></tr>
   </table></html>")]
   
<!-- change output depending on character and weapon, to better describe action -->
[H: output.attack = strformat("%{name} fires his longbow, getting sneak attack, and hitting an AC of %{attackResult}%s",
   if(isFumble," (Fumble)",if(isCritThreat,strformat(" (Crit: %{critResult})"),"")))]
[H: output = strformat('<span title="%{output.tip}">%{output.attack}</span>')]
   
<!-- DAMAGE. Remove strength bonus for most ranged weapons in damage calculation and tooptip -->
[H, if(! isFumble), code: {
   [H: weaponBaseDamageResult = eval(weaponBaseDamage)]
   [H: damage = weaponBaseDamageResult + strengthBonus + miscDamageBonus + weaponDamageBonus + extraDiceDamage]
   [H: critDamage = damage]
   [H: critDamageRolls = weaponBaseDamageResult]
   <!-- I put loop here because the crit damage is rolled separately rather than just multiplied -->
   [H, C(critMultiplier-1), code: {
      [H: critBaseDamage = eval(weaponBaseDamage)]
      [H: critDamageRolls = listAppend(critDamageRolls,critBaseDamage)]
      [H: critDamage = critDamage + critBaseDamage + strengthBonus + miscDamageBonus + weaponDamageBonus]
   }]
   
   <!-- make a tooltip for the damage with damage details -->
   [H, if(isCritThreat): critRollString = strformat("<tr><td>Crit Damage Roll(s):</td><td>%{critDamageRolls}</td></tr>"); critRollString = ""]
   [H, if(isCritThreat): critTotalString = strformat('
         <tr style="color:red"><td><b>Crit Damage Total:</b></td><td><b>%{critDamage}</b></td></tr>
         <tr><td style="font-size:8px" colspan=2><i><b>note:</b> critical damage total is the damage total with successful critical.</i></td></tr>'); 
      critTotalString = ""]
   [H: output.tip = strformat("<html>
      <table><tr><td colspan=2><b><center>DAMAGE</center></b></td></tr>
         <tr><td>Weapon Base Damage:</td><td>%{weaponBaseDamage} = %{weaponBaseDamageResult}</td></tr>
         %{critRollString}
          <tr><td>Strength Damage:</td><td>%{strengthBonus}</td></tr>
         <tr><td>Misc Damage Bonus:</td><td>%{miscDamageBonus}</td></tr>
         <tr><td>Extra Dice Damage:</td><td>%{extraDiceDamage}</td></tr>
         <tr><td>Weapon Damage Bonus:</td><td>%{weaponDamageBonus}</td></tr>
         <tr><td><b>Damage Total:</b></td><td><b>%{damage}</b></td></tr>
         %{critTotalString}
      </table></html>")]
   [H: output.damage = strformat('DAMAGE: %{damage}%s',if(isCritThreat,strformat(" (%{critDamage})"),""))]
   [H: output = output + "<br>" + strformat('<span title="%{output.tip}" style="color:red">%{output.damage}</span>')]
};{}]

<!-- OUTPUT -->
[R: output] 

SquirrelDude
Kobold
Posts: 6
Joined: Sat Nov 24, 2012 7:07 pm

Re: Help creating a Macro.

Post by SquirrelDude »

*Edits as suggested*
Thanks for the tip.


Am I allowed to ask for another one? I figued I would just move this code over to saving throws, because the concept is the same (1 being a fumble, and 20 being a success).

I put in this:

Code: Select all

<<!-- WILL SAVE -->
<!-- Getting Needed Data -->
[h: name = getProperty("CharacterName")]
[h: willSave = getProperty("BaseWillSave")]
[h: wisdomBonus = getProperty("WisdomBonus")]
[h: resistanceBonus = getProperty("ResistanceBonus")]

<!-- Ask players for input -->
[h: Input("Misc.Bonus", "RacialBonus")]
[h: miscSaveBonus = Misc.Bonus]
[h: racialSaveBonus = RacialBonus]

<!-- Define Roll -->
[h: dieRoll = 1d20]
[h: fumble = 1]
[h: autoSuccess = 20]

<!-- Process Data -->
[h: saveMod = willSave + resistanceBonus + wisdomBonus + miscSaveBonus + racialSaveBonus]
[h: saveResult = dieRoll + saveMod]
[h: isFumble = if(dieRoll == fumble, 1, 0)]
[h: isAutoSuccess = if(dieRoll == autoSuccess, 1, 0)]

<!-- Make tooltip for the save with save modifiers -->
[h: output.tip = strformat("<html>
   <table><tr><td colspan=2><b><center>WILL SAVE</center></b></td></tr>
      <tr><td>Save Roll:</td><td>%{dieRoll}</td></tr>
      <tr><td>Base Save:</td><td>%{willSave}</td></tr>
      <tr><td>Wisdom Bonus:</td><td>%{wisdomBonus}</td></tr>
      <tr><td>Resistance Bonus:</td><td>%{resistanceBonus}</td></tr>
      <tr><td>Misc Save Bonus:</td><td>%{miscSaveBonus}</td></tr>
      <tr><td>Racial Bonus:</td><td>%{racialSaveBonus}</td></tr>
   </table></html>")]

<!-- Create Output -->
[h: output.save = strformat("%{name} makes an will save and gets a %{saveResult}%s", if(isFumble," (Fumble)", if(isAutoSuccess, strformat("%{name} rolled a 20 and automatically passes the save"),"")))]
[h: output = strformat('<span title="%{output.tip}">%{output.save}</span>')] 

The output is
Boris the Strong and Fearless:
Just, nothing. A lovely blank space. I'm sure how I messed this up is quite funny.

User avatar
CoveredInFish
Demigod
Posts: 3104
Joined: Mon Jun 29, 2009 10:37 am
Location: Germany
Contact:

Re: Help creating a Macro.

Post by CoveredInFish »

is it just the missing

Code: Select all

<!-- OUTPUT -->
[R: output] 
?

This is the line that actually creates visible chat output .. everthing else in the macro is hidden by [h:]

SquirrelDude
Kobold
Posts: 6
Joined: Sat Nov 24, 2012 7:07 pm

Re: Help creating a Macro.

Post by SquirrelDude »

CoveredInFish wrote:is it just the missing

Code: Select all

<!-- OUTPUT -->
[R: output] 
?

This is the line that actually creates visible chat output .. everthing else in the macro is hidden by [h:]
Yup! There it is.

Alright, I think I've asked enough of you guys. Thanks for the help. I'm going to go learn how to read.

Post Reply

Return to “Macros”