Raoden's Quick'n'Dirty Token Manager
Moderators: dorpond, trevor, Azhrei, giliath, Gamerdude, jay, Mr.Ice
Re: Raoden's Quick'n'Dirty Token Manager
The link is the link above and the error is the title of the code was cut off because I think I used Wiki: varsFromStrProp() to declare variables locally.. the title had ; in it, so the rest of the string was ignored, hence the string for "title" was shorter than expected.
No worries on the fix... I'm sure, as you said about no complaints for a year, it's not really a thing that comes up alot. I just got lucky on my first try .
No worries on the fix... I'm sure, as you said about no complaints for a year, it's not really a thing that comes up alot. I just got lucky on my first try .
Downloads:
- Notepad++ MapTool addon
- RPEdit details (v1.3)
- Coding Tips: Modularity and Design
- Videos: Macro Writing Tools
Re: Raoden's Quick'n'Dirty Token Manager
Here's an error I'm getting:
It's a valid json, just in case if you were wondering. I got the contents locally with the following code:
If it wasn't a json, it would have crashed. My thought is the text editing field you create can't handle some of the characters. I'm not sure. Other than this little set back, it's been really useful for me checking to make sure I'm creating the correct hidden properties.
edit: Okay, the json.type does not like strings that resemble arrays or objects. I'm seeing if there is a work around so you can know what the type is of a string, but that is proving difficult.
edit: Here's a conundrum. When piece = '{am.lib.glp("spell.acidarrow")}'.
edit: I'm having one of these moments.
I figured out a work around so Wiki: json.type() doesn't explode in my face.
You "have to" have them on separate lines for it to work. This fixes the problem from above when clicking the link. I did notice another "bug", which isn't all that bad for my purposes, but <p> breaks the link when in the text. I'm going to assume html in a macrolink is processed, so you should probably do a text = replace(text,"<","<") to fix the macro link text (perhaps show the html in a tooltip?). Also, it would be nice when editing a property that is long to have the input be a bit bigger. Perhaps have a min/max set the field size based on the text inside.
I'm clicking on an object with the following contents:Invalid condition in IF(json.type( piece ) == "UNKNOWN") roll option. Statement options (if any): if( json.type( piece ) == "UNKNOWN" ), code Statement Body (first 200 characters): { [h: linkArg = json.append( '[]', key, pathPiece )]
[r: field]
[r: macroLink( piece, "QnD.json.replace@this", "self", linkArg, id )] [r, if( arrayKey ): " " ] [r
Code: Select all
{
"Spell": "[r: spell.acidarrow.spell = \"Acid Arrow\"][h: spell.acidarrow.spell_name = \"Spell\"]",
"School": "[r: spell.acidarrow.school = \"Conjuration\"][h: spell.acidarrow.school_name = \"School\"]",
"Subschool": "[r: spell.acidarrow.subschool = \"Creation\"][h: spell.acidarrow.subschool_name = \"Subschool\"]",
"Descriptor": "[r: spell.acidarrow.descriptor = \"Acid\"][h: spell.acidarrow.descriptor_name = \"Descriptor\"]",
"Level": "[r: spell.acidarrow.level = \"Sorcerer/Wizard 2\"][h: spell.acidarrow.level_name = \"Level\"]",
"Spell Components": "[r: spell.acidarrow.spellcomponents = \"V, S, M, F\"][h: spell.acidarrow.spellcomponents_name = \"Spell Components\"]",
"Casting Time": "[r: spell.acidarrow.castingtime = \"1 standard action\"][h: spell.acidarrow.castingtime_name = \"Casting Time\"]",
"Range": "[r: spell.acidarrow.range = \"Long (400 ft. + 40 ft./level)\"][h: spell.acidarrow.range_name = \"Range\"]",
"Target": "[r: spell.acidarrow.target = \"\"][h: spell.acidarrow.target_name = \"Target\"]",
"Area": "[r: spell.acidarrow.area = \"\"][h: spell.acidarrow.area_name = \"Area\"]",
"Effect": "[r: spell.acidarrow.effect = \"One arrow of acid\"][h: spell.acidarrow.effect_name = \"Effect\"]",
"Duration": "[r: spell.acidarrow.duration = \"1 round + 1 round per three levels\"][h: spell.acidarrow.duration_name = \"Duration\"]",
"Saving Throw": "[r: spell.acidarrow.savingthrow = \"None\"][h: spell.acidarrow.savingthrow_name = \"Saving Throw\"]",
"Spell Resistance": "[r: spell.acidarrow.spellresistance = \"No\"][h: spell.acidarrow.spellresistance_name = \"Spell Resistance\"]",
"Material Components": "[r: spell.acidarrow.materialcomponents = \"Powdered rhubarb leaf and an adder's stomach.\"][h: spell.acidarrow.materialcomponents_name = \"Material Components\"]",
"Focus": "[r: spell.acidarrow.focus = \"a dart\"][h: spell.acidarrow.focus_name = \"Focus\"]",
"XP Cost": "[r: spell.acidarrow.xpcost = \"\"][h: spell.acidarrow.xpcost_name = \"XP Cost\"]",
"Reference": "[r: spell.acidarrow.reference = \"SRD 3.5\"][h: spell.acidarrow.reference_name = \"Reference\"]",
"Short Description": "[r: spell.acidarrow.shortdescription = \"Ranged touch attack; 2d4 damage for 1 round +1 round/three levels.\"][h: spell.acidarrow.shortdescription_name = \"Short Description\"]",
"Description": "[r: spell.acidarrow.description = \"<p>A magical arrow of acid springs from your hand and speeds to its target. You must succeed on a ranged touch attack to hit your target. The arrow deals 2d4 points of acid damage with no splash damage. For every three caster levels (to a maximum of 18th), the acid, unless somehow neutralized, lasts for another round, dealing another 2d4 points of damage in that round.</p> <p/>\"][h: spell.acidarrow.description_name = \"Description\"]"
}
Code: Select all
[dialog("D"):{<pre>[R: json.indent(replace(getProperty("spell.acidarrow"),"<","<"))]</pre>}]
edit: Okay, the json.type does not like strings that resemble arrays or objects. I'm seeing if there is a work around so you can know what the type is of a string, but that is proving difficult.
edit: Here's a conundrum. When piece = '{am.lib.glp("spell.acidarrow")}'.
Code: Select all
[dialog("D"):{<pre>[R: (replace(piece,"<","<"))]</pre>}]
[h: input("pause")]
[R: a = json.type(piece)] <!-- with this line a null point exception -->
<tr>
[ if( json.type( piece ) == "UNKNOWN" ), code: { <!-- without the above, this does not error -->
I figured out a work around so Wiki: json.type() doesn't explode in my face.
Code: Select all
[H: jType = json.append("",data)]
[H: jType = json.type(json.get(jType,0))]
Downloads:
- Notepad++ MapTool addon
- RPEdit details (v1.3)
- Coding Tips: Modularity and Design
- Videos: Macro Writing Tools
Re: Raoden's Quick'n'Dirty Token Manager
Okay, I updated the token with the fixes and the other tweaks I mentioned.
/// NOTES \\\
Code: Select all
Updates for v2.1
* Made input text when modifying long strings, longer
* Links to update text fields have html neutralized, size
limit and a tooltip to show contents in html.
* Fix made for json.type error for special strings
* Display of object keys that begin/end with a space
(see bottom for related error)
Modified macros:
QnD.editProps.input
QnD.json.replace
subFrame.Tokens.Properties
json.layout.editable
Not fixed
* Key names that begin/end with a space break the link
"path". This requires the path to be changed to a json in
all locations and get rid of the listGet because it trims
the path string items. (I found this because I have an
object that saves the macro group names where one of
them starts with a space.)
- Attachments
-
- Lib.TokenManager_v2.1.rptok
- MT v1.3b86
- (52.84 KiB) Downloaded 173 times
Downloads:
- Notepad++ MapTool addon
- RPEdit details (v1.3)
- Coding Tips: Modularity and Design
- Videos: Macro Writing Tools
Re: Raoden's Quick'n'Dirty Token Manager
I found another limitation, which is really a MT limitation and that the list of variables can't exceed 1000 names because of the MT loop limitation. This can be fixed by breaking the loop with a deferred call and passing the built output so far.
Downloads:
- Notepad++ MapTool addon
- RPEdit details (v1.3)
- Coding Tips: Modularity and Design
- Videos: Macro Writing Tools
Re: Raoden's Quick'n'Dirty Token Manager
Since resetProperty now actually deletes properties, one can use that. I wrote a macro out of personal need and then realised others might have use for it. I took a few looks at the token manager macros, but don't feel really comfortable replacing the corresponding macros with my stuff. So I'll just post what I got:
The main macro. It produces a list with checkboxes. The user can either delete specific selected properties or exclude them from deletion (while deleting everything else). You'll get a dialog to confirm the selection you made.
A trivial macro which posts a list of all properties into the chat. I prefered it for a quick overview.
The main macro. It produces a list with checkboxes. The user can either delete specific selected properties or exclude them from deletion (while deleting everything else). You'll get a dialog to confirm the selection you made.
delete selected properties
Code: Select all
[h: propertyList = getMatchingProperties(".*",", ")]
[h, s: assert( listCount(propertyList), "No properties set.", 0)]
[h: checkCounter = 0]
[h: propertyListDisplay = "label|<html>Select properties for deletion<br><br></html>|<html><span></span></html>|LABEL|SPAN=TRUE##invertSelection|0|Invert selection (keep selected)|CHECK"]
[h, foreach(property, propertyList), code:
{ [h: propertyListDisplay = listAppend(propertyListDisplay, "check"+checkCounter+"|1|"+listGet(propertyList, checkCounter)+"|CHECK","##")]
[h: checkCounter = checkCounter + 1] }
]
[h: askReset= input(propertyListDisplay)]
[h: abort(askReset)]
[h: propertyListDeselected = ""]
[h, for(i,checkCounter-1,-1,-1), if( eval("check"+i) == 0), code:
{ [h: propertyListDeselected = listAppend(propertyListDeselected, listGet(propertyList, i) ) ]
[h: propertyList = listDelete(propertyList, i) ] };
{} ]
[h: propertyListDeselected = listSort(propertyListDeselected,"A")]
[h, switch(invertSelection), code:
case0: { [h: resetList = propertyList] [h: confirmList = replace(propertyListDeselected, ",", "<br>")]
[h: confirmText = "All properties <b>except</b> the following will be deleted:<br><br>"] };
case1: { [h: resetList = propertyListDeselected] [h: confirmList = replace(propertyListDeselected, ",", "<br>")]
[h: confirmText = "<b>Only</b> the following properties will be deleted:<br><br>"] }
]
[h, if( listCount(confirmList) == 0 ), code:
{ [h, switch(invertSelection), code:
case0: { [h: confirmList = "<i>All will be deleted.</i>"]};
case1: { [h, s: assert( 0, "No property was selected for deletion.", 0)] }
]}; {}
]
[h: confirmReset = input(
"junk|<html>"+confirmText + confirmList+"</html>|<html><span></span></html>|LABEL|SPAN=TRUE")]
[h: abort(confirmReset)]
[h: resetAmount = listCount(resetList)]
[foreach(propertyName, resetList, ""), code:
{ [h: resetProperty(propertyName) ] }
]
[r: resetAmount] [r: if(resetAmount != 1,"properties","property")] deleted.
list all properties
Code: Select all
[h: propertyList = getMatchingProperties(".*", ", ")]
[r, s, if( listCount(propertyList) == 0): "No properties set."; propertyList]
- Attachments
-
- list all & delete selected properties.mtmacset
- (1.41 KiB) Downloaded 125 times
Re: Raoden's Quick'n'Dirty Token Manager
Recently started using this. I love it. It's really a must-have for anybody using "hidden" properties. Just wanted to thank Raoden and aliasmask.
Re: Raoden's Quick'n'Dirty Token Manager
I've got an error that has me stumped. On a library token that I'm storing the cache for a frame on, I'm getting the following error:
This code is in the "subFrame.Tokens.Properties" macro. If I pull out the IF and the "else", it works. Is there a downside to this, other than not being able to use the JSON editor?
Here's the property that's setting it off:
Code: Select all
Invalid condition in IF(json.type( value ) != "ARRAY" && json.type( value ) != "OBJECT") roll option.
Statement options (if any): r, if( json.type( value ) != "ARRAY" && json.type( value ) != "OBJECT" ), code
Statement Body (first 200 characters): { [H: length = min(max(length(value),0),80)] [H: mValue = replace(substring(value,0,length),"","<")] [H: tValue = replace(value,'"','"')] [H, if(! startsWi
Here's the property that's setting it off:
Code: Select all
[H: TempIDProps = getMatchingLibProperties("class.[0-9]+.name", Token.Library)]
[H: ClassIDs = "[]"]
[H: HighLevel = 0]
[H, FOREACH(Property, TempIDProps, ""), IF(getLibProperty(Property, Token.Library) != ""), CODE: {
[SlotsJSON = getLibProperty(replace(Property, "name", "spellslots"), Token.Library)]
[IF(! json.isEmpty(SlotsJSON)), CODE: {
[ClassIDs = json.append(ClassIDs, Property)]
[C(9): HighLevel = if(json.get(SlotsJSON, roll.count) != 0 && roll.count + 1 > HighLevel, roll.count + 1, HighLevel)]
}; {}]
}; {}]
<table width="100%">
<tr>
<th colspan=[R: HighLevel + 1]>Spells per Day</th>
<tr class="subheading">
<th>CLASS</th>
[R, C(HighLevel, ""): strformat('<th class="minwidth">LV%{roll.count}</th>')]
[R, FOREACH(Property, ClassIDs, ""), CODE: {
[H: ClassName = getLibProperty(Property, Token.Library)]
[H: StringID = strfind(Property, "class.([0-9]+).name")]
[H: ClassID = getGroup(StringID, 1, 1)]
[H: SlotsJSON = getLibProperty(strformat("Class.%{ClassID}.SpellSlots"), Token.Library)]
<tr [R, IF(! band(1, roll.count)): 'class="stripe"']>
<td><span title="Edit [R: ClassName] spells per day.">[R: macroLink(ClassName, "SetSpellSlotsDialog@this", "none", ClassID)]</span></td>
[R, C(HighLevel, ""): strformat('<td align="center">%d</td>', json.get(SlotsJSON, roll.count) + 0)]
}]
<tr class="subheading">
<td colspan=[R: HighLevel + 1] align="center">[R: macroLink("ADD NEW", "SelectCastingClassDialog@this", "none", -1)]</td>
<tr class="subheading"><td colspan=[R: HighLevel + 1]> </td>
</table>
Re: Raoden's Quick'n'Dirty Token Manager
What version of the token manager are you using?
json.type can't handle strings that start and end with {} or [] if they're are not jsons. I think 2.1 has an updated json.type (I think). Anyway, if not, this is the code I use:
I didn't look at your code because it seems unrelated to error. (no matching if statement) This may not be the cause of your error but I'm guessing it is.
json.type can't handle strings that start and end with {} or [] if they're are not jsons. I think 2.1 has an updated json.type (I think). Anyway, if not, this is the code I use:
Code: Select all
@@ @json.type
[H: jType = json.append("",arg(0))]
[H: jType = oldFunction(json.get(jType,0))]
[H: macro.return = jType]
!!
Downloads:
- Notepad++ MapTool addon
- RPEdit details (v1.3)
- Coding Tips: Modularity and Design
- Videos: Macro Writing Tools
Re: Raoden's Quick'n'Dirty Token Manager
That makes sense. I'm on 2.1, but it doesn't look like there's a json.type() included. I'll override it with your code. Thanks a ton.
Edit: Created json.type macro, defined the function, tried to open the frame... no dice. Still the same error. Weird. It works on the dozen other very similar properties. I can live without the JSON editor though.
Another edit: I moved the <table> line up to the beginning and it works fine.
Edit: Created json.type macro, defined the function, tried to open the frame... no dice. Still the same error. Weird. It works on the dozen other very similar properties. I can live without the JSON editor though.
Another edit: I moved the <table> line up to the beginning and it works fine.
Re: Raoden's Quick'n'Dirty Token Manager
Whatever was happening was seeming to break your json formatting.
Downloads:
- Notepad++ MapTool addon
- RPEdit details (v1.3)
- Coding Tips: Modularity and Design
- Videos: Macro Writing Tools
Re: Raoden's Quick'n'Dirty Token Manager
Probably because it started with a '[' but didn't end with one? I dunno ... I've sadly lost much of the knowledge of MapTool code that I had back when I made this tool.
"Fairy tales do not tell children the dragons exist. Children already know that dragons exist. Fairy tales tell children the dragons can be killed."
- G. K. Chesterton
Wonderful HTML/CSS reference * Color Manager * Token Manager 2.0
- G. K. Chesterton
Wonderful HTML/CSS reference * Color Manager * Token Manager 2.0
Re: Raoden's Quick'n'Dirty Token Manager
Question: I would like to be able to select a number of tokens, and change all of their names at once, while have sequential numbers added. So instead of "orc, orc 1, orc 2, etc", I could change them all to "monster, monster 1, etc, etc," after the party has made their Knowledge checks.
Could this token manager do that? Have any macro ideas for this?
Thank you!
Could this token manager do that? Have any macro ideas for this?
Thank you!
- CoveredInFish
- Demigod
- Posts: 3104
- Joined: Mon Jun 29, 2009 10:37 am
- Location: Germany
- Contact:
Re: Raoden's Quick'n'Dirty Token Manager
The token manager is not up to this - it is a tool to edit the properties, even hidden, of a single token - but a short macro can do it.
Code: Select all
[h: tokens = getSelected()]
[h: index = 1]
[h: abort(input("name|Monster|TEXT"))]
[h, foreach(id, tokens), code: {
[setName(strformat("%s %s", name, index), id)]
[h: index = index + 1]
}]
Re: Raoden's Quick'n'Dirty Token Manager
//Highly off topicCoveredInFish wrote:The token manager is not up to this - it is a tool to edit the properties, even hidden, of a single token - but a short macro can do it.Code: Select all
[h: tokens = getSelected()] [h: index = 1] [h: abort(input("name|Monster|TEXT"))] [h, foreach(id, tokens), code: { [setName(strformat("%s %s", name, index), id)] [h: index = index + 1] }]
I see you've updated your sig as well. Does that mean that the MT doc project is now fully disbanded?
GETTING STARTED WITH MAPTOOLS - TUTORIALS, DOCS, VIDEOS, TOOLS, ETC
DISCORD (the new MT forum!)
My stuff
Excel Tools: Table and Light editors
MT Tools: Bag of Tricks: Tools for Maptool, Dungeon Builder I, Dungeon Builder II,onMouseOverEvent.
Frameworks: Dark Heresy, Rogue Trader, Deathwatch, Black Crusade, Only War, SET Card Game, RoboRally
Wiki: Debugging Tutorial, Speed Up Your Macros, Working With Two CODE Levels, Shortcut Keys, Avoiding Stack Overflow, READ THIS
DISCORD (the new MT forum!)
My stuff
Excel Tools: Table and Light editors
MT Tools: Bag of Tricks: Tools for Maptool, Dungeon Builder I, Dungeon Builder II,onMouseOverEvent.
Frameworks: Dark Heresy, Rogue Trader, Deathwatch, Black Crusade, Only War, SET Card Game, RoboRally
Wiki: Debugging Tutorial, Speed Up Your Macros, Working With Two CODE Levels, Shortcut Keys, Avoiding Stack Overflow, READ THIS
Re: Raoden's Quick'n'Dirty Token Manager
Wow, awesome! That worked perfectly. Thank you!CoveredInFish wrote:The token manager is not up to this - it is a tool to edit the properties, even hidden, of a single token - but a short macro can do it.Code: Select all
[h: tokens = getSelected()] [h: index = 1] [h: abort(input("name|Monster|TEXT"))] [h, foreach(id, tokens), code: { [setName(strformat("%s %s", name, index), id)] [h: index = index + 1] }]