Macro Use Cases

Doc requests, organization, and submissions

Moderators: dorpond, trevor, Azhrei

User avatar
BigO
Dragon
Posts: 558
Joined: Mon Jul 28, 2008 12:23 pm
Location: Oshkosh, WI
Contact:

Macro Use Cases

Post by BigO »

With the release of 1.3.b39 several changes and new features were added to the Macros. This has sparked a lot of discussion about what the future development path of the Macro syntax should be. To help the development team understand what the community is looking for, and to look for solutions that will meet everyone's needs, I have started this thread (at Trevor's request) to document a set of the most common "use cases" for macro use.

The idea here is not to quibble about syntax but to clearly express the task you are trying to accomplish, and how you expect the system to behave in order to get you there. Here is Trevor's request from the 1.3.b39 announcement thread:
what it sounds like we need to do is create a couple very precise examples, use cases, sans implementation, of ways people want to use it. Then, after we have those cases, look at how to implement them now, and how we can improve their use.
I will watch this thread and update this parent post to reflect the use cases that come from the ensuing discussion. For more information about use cases, see this wikipedia article.

Let's keep this friendly!

Code: Select all

Use Case 1:
A player has a weapon that does 1d8 damage. She wants to be able to store that information in a property and have it display as 1d8 on the stat sheet, and still have it be easy to roll the random value via a macro.

Code: Select all

Use Case 2:
A player wants to write blocks of re-usable macro code that can then be used multiple times within the same macro, or called for execution by other macros.
jfrazierjr wrote:Use Case 3:
Set Token state 'a' via macro.
Unset tokenstate 'a via right click menu
Attempt to query token state via a macro

Set Token state 'a' via macro.
Unset tokenstate 'a via Token edit dialog window
Attempt to query token state via a macro
Last edited by BigO on Thu Aug 07, 2008 12:20 pm, edited 3 times in total.
--O

I am a small and fragile flower.
http://maptool.rocks.andyousuck.com

User avatar
kat2cute
Dragon
Posts: 297
Joined: Wed Jan 30, 2008 3:46 pm

Post by kat2cute »

I'll start us off with something complicated. I have a token which has HP and MaxHP properties. I want to click a Damage Macro and have the HP deducted from the current HP and stored in the token, visible in the statsheet for some. I also want special states to occur when the token falls below 0 HP, in which the token's Dexterity falls to 0. Currently, I can't do this (as the token doesn't remember what the original Dexterity was without creating a separate property for pretty much every property that could possibly be changed). Current work-around is to alter the DexMod to -5 instead (since it is calculated from Dexterity), and reset to the appropriate equation when healed or the unconscious state is gone, back to floor((Dexterity-10)/2), or whatever the appropriate syntax dictates. This workaround doesn't let me have a up-to-date Dexterity property on the stat sheet though.
1.3.b39. Properties: HP, MaxHP, TempHP, DexMod, Dex
Damage D&D 3.X

Code: Select all

<!-- [DamageTaken = ChangeHP] [TempHP = TempHP - DamageTaken] [HP = HP + min(0, TempHP)] [TempHP = max(0,TempHP)] [state.Disabled = if(HP==0,1,0)] [state.Dying = if(HP<0,1,0)] [DexMod=if(state.Dying>=1,-5, "{floor((Dex-10)/2)}")] [state.Prone = state.Dying + state.Prone] -->
<b> {DamageTaken} Damage </b>
Healing D&D 3.X

Code: Select all

<span style="font-size:0">[HealingGained = HealedHP][HP = min(HP +HealingGained,MaxHP)] [state.Dying = 0] [state.Disabled = if(HP==0,1,0)] [state.Unconscious = if(HP<0,1,0)][DexMod=if(state.Unconscious>=1,-5,"{floor((Dex-10)/2)}")] </span> <b>{HealingGained} Healed!</b>
Last edited by kat2cute on Mon Aug 04, 2008 10:44 pm, edited 2 times in total.
Quote from an underwater D&D fight:
Alright fighter, it's your turn. What do you do?
Fighter: What do you think I do? I FAIL MY F**KING SWIM CHECK

Aabra
Kobold
Posts: 15
Joined: Wed Jun 18, 2008 1:56 am

Post by Aabra »

In D&D 4E whenever you roll a 20 it's a critical hit and whenever you roll a 1 it's always a miss. For me this is a situation that is just screaming to be made into a macro.

Anyways, if anybody could make/post a good example of how to do this - say for example by modifying my Magic Missile here so that if it rolls a 20 it does max damage + Implement1Crit.... but being as verbose as normal so people can see how everything is calculated (without wasting too much space) that would be great. Everything gets hidden when I try which is problematic as everybody else will want to know how I'm calculating my damage/etc in case I'm making a mistake.

<table border="1" width=400><tr bgcolor="308014"><td><b><font color="FFFFFF">Magic Missile</font></b> <font color="FFFFFF">-</font> <i><font color="FFFFFF"> Ranged 20</font></i></tr> </td><tr><b>Attack:</b>[1d20+IntBonus+Implement1Bonus+LevelBonus+modHit] vs. <b>Reflex</b><tr bgcolor="EEDFCC"><b>Hit:</b> [2d4+IntBonus+Implement1Bonus+modDamage] force damage</tr></table>

User avatar
TK
Giant
Posts: 162
Joined: Fri Jun 27, 2008 12:02 am

Post by TK »

I want to run a variety of macros before I attack which will allow me to add up a miscellaneous modifier property. I would like to build up this modifier using an arbitrary combination of flat modifiers (+3, -2), other properties (+strMod), and/or a die string (+2d6). If a die string is added, or if a property which contains a die string is added, it shouldn't evaluate that die roll until the miscellaneous property is used, (IE when you add +miscellaneous + miscellaneous you should (statistically) be adding two different numbers). And then once it's the end of the turn, I want to set that miscellaneous mod back to 0.

User avatar
RedDog
Dragon
Posts: 393
Joined: Sat Jan 05, 2008 10:02 pm
Location: Clearwater, FL

Re: Macro Use Cases

Post by RedDog »

I want to be able to place a variable that represents a Token Property on another Token Property and have the ability to pull the value back out as an evaluated result or a string (for example, a Weapon switching macro that 'switches' the weapons and tells the user the statistics including the actual die used).

User avatar
RPTroll
TheBard
Posts: 3159
Joined: Tue Mar 21, 2006 7:26 pm
Location: Austin, Tx
Contact:

Post by RPTroll »

What RD said. Weapons damage in Savage Worlds is Strength + d'something'. The ability to have that in the property without the {} would be nice.

User avatar
Mathemagician
Dragon
Posts: 666
Joined: Tue May 22, 2007 2:27 pm

Post by Mathemagician »

Aabra wrote:In D&D 4E whenever you roll a 20 it's a critical hit and whenever you roll a 1 it's always a miss. For me this is a situation that is just screaming to be made into a macro.

Anyways, if anybody could make/post a good example of how to do this - say for example by modifying my Magic Missile here so that if it rolls a 20 it does max damage + Implement1Crit.... but being as verbose as normal so people can see how everything is calculated (without wasting too much space) that would be great. Everything gets hidden when I try which is problematic as everybody else will want to know how I'm calculating my damage/etc in case I'm making a mistake.

<table><tr><td><b><font>Magic Missile</font></b> <font>-</font> <i><font> Ranged 20</font></i></tr> </td><tr><b>Attack:</b>[1d20+IntBonus+Implement1Bonus+LevelBonus+modHit] vs. <b>Reflex</b><tr><b>Hit:</b> [2d4+IntBonus+Implement1Bonus+modDamage] force damage</tr></table>
You might check out my macro tutorials here, http://forums.rptools.net/viewtopic.php?t=4950 . I do an example of critical hits near the end.

User avatar
Orchard
Great Wyrm
Posts: 1852
Joined: Fri May 09, 2008 10:45 am
Location: Doylestown PA
Contact:

Post by Orchard »

kat2cute wrote:I'll start us off with something complicated. I have a token which has HP and MaxHP properties. I want to click a Damage Macro and have the HP deducted from the current HP and stored in the token, visible in the statsheet for some. I also want special states to occur when the token falls below 0 HP, in which the token's Dexterity falls to 0. Currently, I can't do this (as the token doesn't remember what the original Dexterity was without creating a separate property for pretty much every property that could possibly be changed). Current work-around is to alter the DexMod to -5 instead (since it is calculated from Dexterity), and reset to the appropriate equation when healed or the unconscious state is gone, back to floor((Dexterity-10)/2), or whatever the appropriate syntax dictates. This workaround doesn't let me have a up-to-date Dexterity property on the stat sheet though.
Interesting case--most of which is available via the chartool and would be usable if maptool and chartool were more tightly inegrated, I believe. I think mostly this discussion is largely related to the use of strings and numbers in properties, but the use of temporary states in properties is an interesting UC (use case).

Can I propose that for further clarity in this discussion it might be helpful if we had individuals post actual macros and token files (and even property files) so that we can see exactly how they have been used in the past. Please indicate what build you were using to make these when they worked and when they quite working and in what way. Furthermore, please give your feelings about what can be done to reach a compromise for all systems.

The goal, as I understand it, is to reach a generic system that works all around.

Thanks.
0+0=1, for very unstable CPUs.

User avatar
Mathemagician
Dragon
Posts: 666
Joined: Tue May 22, 2007 2:27 pm

Post by Mathemagician »

Let's pretend for a moment my token has the property: CurrentWeapon (which is somehow not a weapon dealing with water flow), where I desire more than anything in the world, to put the 1d8 into it, to use for rolling later.

My options, are:

Code: Select all

{CurrentWeapon="1d8"}
{eval(CurrentWeapon)}
or

Code: Select all

[CurrentWeapon="{1d8}"]
{CurrentWeapon}
Advantages to the first:
1) If "CurrentWeapon" was shown on the statsheet, it would show up as 1d8, not a random number.

Disadvantage to the first: Requires "eval" every time I want to use the damage dice. Sad face.

Advantage to the second: Doesn't have the first's disadvantage, I don't need to litter my code with eval.

Disadvantage to the second: Have to remember to put things in { }. Which, in a weapon switching context, requires silly notation like "{"+newDice+"}" where newDice is a string containing "1d6", say.
A further disadvantage is that if CurrentWeapon is a stat-sheet viewable property, it will show random numbers every time you hover over the token.


-----------

Proposed solution: Add a new campaign property delimiter, "evaluate in macro call", let's call it "!" for now (since this topic is so exciting).

in all of the following, I'll assume this:
CurrentWeapon="1d6"

CurrentWeapon does not have the ! flag
Must type {eval(CurrentWeapon)} in a macro.

CurrentWeapon has the ! flag,
Must type {CurrentWeapon} in a macro.

In both cases, the stat sheet comes up as "1d6".

User avatar
RedDog
Dragon
Posts: 393
Joined: Sat Jan 05, 2008 10:02 pm
Location: Clearwater, FL

Re: Macro Use Cases

Post by RedDog »

BigO wrote:

Code: Select all

Use Case 1:
A player has a weapon that does 1d8 damage. She wants to be able to store that information in a property and have it display as 1d8 on the stat sheet, and still have it be easy to roll the random value via a macro.
Here is a possible solution to this. Add a Campaign Property flag, such as $, that makes the stat block display the field value as a string instead of evaluate it. This would only affect the stat block. Without it, the stat block shows the evaluated value.

Some other brainstorming...
Another idea for having the ability to pull a Token Property as text is to come up with another set of 'brackets' for macros. [] could be used for evaluation and full output, {} for evaluation and simple result, and the new bracket could be used to display the Token Property as text. Unfortunately, we are out of bracket sets. I wouldn't suggest using pipes(||) in case object linking comes along (ie targeting). Perhaps %% or ${}.

Another thought along this line is to use [[ ]] for full output, [] for simple result output, and {} for text only.

User avatar
RPTroll
TheBard
Posts: 3159
Joined: Tue Mar 21, 2006 7:26 pm
Location: Austin, Tx
Contact:

Post by RPTroll »

Also embeddable {} might help or evaluate anything with {} so that when I set the property d6e+Strength I can macro {property} and it evaluates as it should.

bobthedog
Cave Troll
Posts: 85
Joined: Sun Aug 03, 2008 7:17 pm

Post by bobthedog »

One thing that I have been trying to do (and would also like suggestions from the excellent people here) is have macros that have "steps". Let me explain:

In 4e, the warlock's curse (and similar added damage features, like Sneak Attack) can be added once per round (but maptool doesn't do rounds -yet- so this is not an issue) to an attack, AFTER you roll the damage total. As of now, this can be implemented by:
  • running a separate macro: this is good because you have the attack macro calculate everything and if you want to add curse/sneak, you just click the curse macro. The bad part is that you either need a "variable storing" property to keep the damage values of the first macro if you want to have the second macro give you final results instead of just the difference.
  • adding a "cursed damage" bit to the attack macro: this is good because you have the damage with and without curse easily visible, and you can automate calculations. The bad part is that it could be exploited (like if you see that you rolled a 1 on curse damage, you opt not to use it) and you're always showing a "cursed damage" line, even when it doesn't apply.
  • prompting for "cursed" every time: this is good because you can work with damage values within a macro, and you can choose to add or not when you activate an attack. Also good is that it can be done differently according to specific needs. The bad part is that you can't see the damage calculation (or the attack roll) before you choose to use (or not) the warlock's curse.
So, any thoughts on how to make a "this is the first part of the macro, what do you want to do on the second part?" thing work?

User avatar
BigO
Dragon
Posts: 558
Joined: Mon Jul 28, 2008 12:23 pm
Location: Oshkosh, WI
Contact:

Post by BigO »

bobthedog wrote:One thing that I have been trying to do (and would also like suggestions from the excellent people here) is have macros that have "steps". Let me explain:

In 4e, the warlock's curse (and similar added damage features, like Sneak Attack) can be added once per round (but maptool doesn't do rounds -yet- so this is not an issue) to an attack, AFTER you roll the damage total. As of now, this can be implemented by:
  • running a separate macro: this is good because you have the attack macro calculate everything and if you want to add curse/sneak, you just click the curse macro. The bad part is that you either need a "variable storing" property to keep the damage values of the first macro if you want to have the second macro give you final results instead of just the difference.
  • adding a "cursed damage" bit to the attack macro: this is good because you have the damage with and without curse easily visible, and you can automate calculations. The bad part is that it could be exploited (like if you see that you rolled a 1 on curse damage, you opt not to use it) and you're always showing a "cursed damage" line, even when it doesn't apply.
  • prompting for "cursed" every time: this is good because you can work with damage values within a macro, and you can choose to add or not when you activate an attack. Also good is that it can be done differently according to specific needs. The bad part is that you can't see the damage calculation (or the attack roll) before you choose to use (or not) the warlock's curse.
So, any thoughts on how to make a "this is the first part of the macro, what do you want to do on the second part?" thing work?
One way to handle it would be to have a "DoCurse" or "DoSneakAttack" bit property set up and have the GM (or player as appropriate) set the value before the attack fires off. For example, the GM would know if the monster is immune to sneak attack so would set the bit before your turn to zero, then your attack macro would be set up to not roll for the sneak attack.
--O

I am a small and fragile flower.
http://maptool.rocks.andyousuck.com

bobthedog
Cave Troll
Posts: 85
Joined: Sun Aug 03, 2008 7:17 pm

Post by bobthedog »

BigO wrote:One way to handle it would be to have a "DoCurse" or "DoSneakAttack" bit property set up and have the GM (or player as appropriate) set the value before the attack fires off. For example, the GM would know if the monster is immune to sneak attack so would set the bit before your turn to zero, then your attack macro would be set up to not roll for the sneak attack.
Since I was thinking 4e, I didn't even consider immunity to Sneak Attack; that adds a different focus for the activation of the extra damage, and your idea might work well in that case.

As for the "DoCurse", I have implemented something similar for Power Attack:

Code: Select all

*@Power Attack = {if(PowAttack > 0, "ON", "OFF")}
PowAttack = 0
PowAttackBonus = {if(PowAttack > 0, 3, 0)}
I added those properties to the "standard 4e list" I found in these forums, then updated these:

Code: Select all

Weapon1Bonus = etc+etc+etc-PowAttack
Weapon1DamBonus = etc+etc+etc+PowAttackBonus
So that attack powers that include power-attack-able weapons work the same way as other attack powers.

Then I made a "toggle" macro for power attack:

Code: Select all

/self <!--[PowAttack = if(PowAttack>0, 0, 2)]-->
<b>Power Attack:</b> {if(PowAttack > 0, "ON", "OFF")}
This works nice for toggle-powers, though you'd have to include two properties (or three if you want a statsheet visual aid) for each toggled ability.
Last edited by bobthedog on Wed Aug 06, 2008 2:21 pm, edited 2 times in total.

Esaquam
Cave Troll
Posts: 32
Joined: Thu Jul 24, 2008 11:55 pm

Use case: Dynamic token properties

Post by Esaquam »

Use case: Adding/removing temporary state w/ variable data to a token, for the length of an encounter/spell duration/etc.

Possible implementation: I'd like to be able to dynamically add (and then remove) 'temporary' properties on a token to track predictable but relatively rare effects over several rounds -- which, I realized belatedly, are arguably separate token manipulation commands, tangential to macros (as long as macros can use them).

This prevents having to predict and pre-code every possible temporary condition variable that may arise during play. I'd prefer that non-temporary properties not be removable (for obvious reasons). I'd like the temporary properties clearly identifiable so that they can be cleaned up easily (facilitate deleting all of them at the end of an encounter/day/session/whatever).

Example: D&D-type Regeneration, where certain kinds of damage (fire, acid) cannot be regenerated. To track during battle, I need 3 HP properties: MaxPossibleHP, MaxRecoverableHP (which will decrease only with non-regenerable damage, but can increase back to MaxPossibleHP with Healing spells or longer-term rest), and CurrentHP (which will decrease with all types of damage, but will regenerate a few points/round back to MaxRecoverableHP during battle). And I need a RegenRate, rather than hardcoding or typing in the same value every round (and maybe a string, NonRegenDamageHint, in case it's something other than Fire/Acid).

Since only a handful of beasties can normally regenerate, but *any* PC/NPC can regenerate with certain spells/items, I would rather not have to add these properties to every single token that gets created: There are hundreds of similar cases that would bloat every token with lots of unused properties. I would rather have a set of macros, addRegen (to token), doRegen (per turn), takeRegenDamage (asks separately for FireAcid and Other damage), and then removeRegen to tear down the temporary token properties.

Post Reply

Return to “Documentation Requests/Discussion”