Token Generation 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
Roh
Cave Troll
Posts: 27
Joined: Wed May 05, 2010 12:46 am

Token Generation Macro

Post by Roh »

I'm slowly getting back into a little project of mine involving lots of random tables. I've got a lot to relearn before this is much of an issue but knowing if it's possible could only be a motivator. I will be making macros to generate NPCs. Is it possible to have the macro place a specific token and apply the statistics rolled to that token in a way that would work with a framework? Maybe put attack macros and such on the token automatically?

I know I could just make one token and copy it but a big part of the system is rolling certain things that make each enemy a little different. Some significantly so. A yes or no would be plenty. Thanks for taking the time to read this.

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

Re: Token Generation Macro

Post by RPTroll »

You can do this, however there can be an issue creating a token and updating its stats inside the same macro.

Please read the wiki article on copyToken paying attention to the note about execLink with deferred execution.

http://lmwcs.com/rptools/wiki/copyToken
ImageImage ImageImageImageImage
Support RPTools by shopping
Image
Image


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

Re: Token Generation Macro

Post by aliasmask »

As long as you don't want to change states and are just updating properties then you can do that at token creation time without defer. defer does work, sometimes. It depends on what you want do and how much of a delay you have, but updating the original token first is best for somethings like states.

I do have an all purpose macro I've been using for awhile.
||| CODE |||

Code: Select all

[H: '<!-- List of Arguments Possible createToken(updates): id
   name - Name of token
   * type - token type for properties
   * snap - snap to grid (default 1, yes)
   owner - json array of owner ("" or name begins with "lib:" set to no owner, no default owner)
   map - map name to move token to 
   target - name of token on current map OR x,y coords
   offset - x,y coord offset (always relative to target, uses useDistance metric)
   useDistance - 0 (grid x,y), 1 (gridless x,y)
   props - json of props to be set on token created
   states - json array of states to be set on token created
   layer - layer for token to be created on
   facing - facing of token
   size - size of token
   label - label of token
   gmName - gm name of token
   tokenImage, portraitImage, handoutImage - token images
-->']

[H: args = arg(0)]
[H: sourceToken = "image:Unknown"]
[H: sourceMap = getLibProperty("play.libMap",getMacroLocation())]
[H: currentMap = getCurrentMapName()]
[H: targetMap = json.get(args,"map")]
[H, if(json.isEmpty(targetMap)): targetMap = currentMap]


[H: updateVars = json.append("","name","label","gmName","facing","size","tokenImage","portraitImage","handoutImage","layer")]
[H: updates = "{}"]
[H, foreach(varName,updateVars), code: {
   [H: value = json.get(args,varName)]
   [H, if(! json.isEmpty(value)): updates = json.set(updates,varName,value)]
}]
[H: useDistance = json.get(args,"useDistance")]
[H, if(json.isEmpty(useDistance)): useDistance = 0]
[H: updates = json.set(updates,"useDistance",useDistance)]
[H: target = json.get(args,"target")]
[H, if(json.isEmpty(target)), code: {
   [H: x = 0]
   [H: y = 0]
};{ 
   [H, if(json.type(target) == "OBJECT"), code: {
      [H: x = json.get(target,"x")]
      [H: y = json.get(target,"y")]
   };{
      [H: x = getTokenX(useDistance,target)]
      [H: y = getTokenY(useDistance,target)]
   }]
}]
[H: offset = json.get(args,"offset")]
[H, if(! json.isEmpty(offset)), code: {
   [H: x = x + json.get(offset,"x")]
   [H: y = y + json.get(offset,"y")]
};{}]
[H: updates = json.set(updates,"x",x,"y",y)]
[H, if(currentMap != sourceMap): setCurrentMap(sourceMap)]
[H: props = json.get(args,"props")]
[H: propsSet = ""]
[H, foreach(prop,props): propsSet = json.append(propsSet,strformat('[H: setProperty("%{prop}",decode("%s"))]',encode(json.get(props,prop))))]
[H: name = json.get(updates,"name")]
[H: isLib = if(startsWith(trim(lower(name)),"lib:"),1,0)]
[H: propsSet = json.toList(propsSet,"")]
[H: name = name+propsSet]
[H: updates = json.set(updates,"name",name)]
[H: states = json.get(args,"states")]
[H: owner = json.get(args,"owner")]
[H, if(json.isEmpty(owner)): owner = "[]"]
[H, if(json.type(owner) == "UNKNOWN"): owner = json.append("",owner)]

<!-- Token pre-updates -->
[H: canCreateToken = ! json.isEmpty(findToken(sourceToken))]
[H, if(canCreateToken), code: {
   [H, foreach(state,states): setState(state,1,sourceToken)]
   [H, if(! isLib && ! json.isEmpty(owner)): setOwner(owner,sourceToken)]

   [H: id = copyToken(sourceToken,1,"",updates)]

   [H: '<!-- Token post-updates -->']
   [H: setAllStates(0,sourceToken)]
   [H, if(! isLib && ! json.isEmpty(owner)): setOwner("",sourceToken)]

   [H, if(currentMap != sourceMap), code: {
      [H: setCurrentMap(currentMap)]
      [H: am.play.deferFunction("moveTokenFromMap",json.append("",id,sourceMap,x,y))]
   };{}]
   [H, if(currentMap != targetMap): am.play.deferFunction("moveTokenToMap",json.append("",id,sourceMap,x,y))]
};{
   [H: id = ""]
   [H, if(currentMap != sourceMap): setCurrentMap(currentMap)]
   [H: am.play.output(am.play.errorMessage("Missing Token",getMacroName(),sourceToken),"server")]
}]
[H: macro.return = id]
 
This does call some other custom macros listed by the "am.play." prefix, but those are only needed for my custom output and to create tokens on maps that are not the current map. You will need a blank token as the base. The code lists it as "image:Unknown" and is always found on a specific map. You can sort though the code and I'll try to answer any questions you may have.

There's a little trick I do to set properties on the copied token using the name property of the token. If you follow PropsSet in the above code, perhaps you can see what I do.

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

Re: Token Generation Macro

Post by RPTroll »

wolph42 wrote:As far as I know defer does not work. What does work is change the original first and then copy of
I use defer in my framework and it seems to work. <shrug> Maybe it's the power of Linux. :)
ImageImage ImageImageImageImage
Support RPTools by shopping
Image
Image

Roh
Cave Troll
Posts: 27
Joined: Wed May 05, 2010 12:46 am

Re: Token Generation Macro

Post by Roh »

Hmm. Seeing that I have options is awesome. As I admitted from the start I have a lot to relearn before I am ready to touch this again but thanks for the link and code snippet to study all the same!

As for the use I have in mind? It's generally to for making random encounters. The tokens would be created, probably placed on a admin map, copied to the encounter map then deleted once the encounter is resolved. Or at most used as a token Id be perfectly content to edit manually. The biggest point of what I'm trying to do is allow myself, and any other GM interested in using it, to not need to make random encounters ahead of time, or have to use boring carbon copies. Or ask the party to wait five or ten minutes while I roll up individual npcs.

I had the macros to roll critters going before, even have a vague memory of how I did it. But that just gave me the statistics. The best I can do with that is have a base token ready for adjustment and do each one at a time. Still saves rolling all the dice involved but.. Well if I can make it so that the appropriate token is placed in a map ready for use? That would be an amazing boon to anyone running the system in question.

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

Re: Token Generation Macro

Post by aliasmask »

RPTroll wrote:
wolph42 wrote:As far as I know defer does not work. What does work is change the original first and then copy of
I use defer in my framework and it seems to work. <shrug> Maybe it's the power of Linux. :)
It depends on what you're doing. Before we had the option to set the token image using a defer to set it only worked sometimes based on the timing. But stuff like setting properties I think worked fine because the token wasn't being redrawn. But that was awhile ago and maybe things work differently now.

Roh
Cave Troll
Posts: 27
Joined: Wed May 05, 2010 12:46 am

Re: Token Generation Macro

Post by Roh »

I let myself get distracted from this little project for a while but the fact that I am actually already running a campaign in this setting has sort of gotten me back into it.

In an effort to get at least something minimal going to help with my game I'm going to content myself with simply copying the base token and using a macro to quickly do a couple rolls and adjust the token properties for me. I'm pretty sure I can manage this well enough.

What I'm less certain of is how I will handle adding extra macros to the tokens. Based an a percentage target most critters can have extra mutations or extra weapons. I plan to represent this by simply adding macro's with the proper name that can be used in play. Would anyone have some suggestions on how I might do this or maybe direct me to the right section of the wiki?

I vaguely remember the idea of making a variable library and I suppose something similar might possibly be useful for what I have in mind but I have no idea where to even start looking to figure out how to use a macro to copy another macro from somewhere and place it on a token.

Roh
Cave Troll
Posts: 27
Joined: Wed May 05, 2010 12:46 am

Re: Token Generation Macro

Post by Roh »

I think I may have found it myself. Maybe. Though it looks like I'm going to have to do a lot more digging before I really understand how to use it. *sigh* A shame. I think I could manage the rest easy enough.

Post Reply

Return to “Macros”