91.08 Pathfinder + D&D3.5 Framework

Discussion concerning lmarkus' campaign framework for D&D3.x and Pathfinder.

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

Forum rules
Discussion regarding lmarkus001's framework only. Other posts deleted without notice! :)
User avatar
lmarkus001
Great Wyrm
Posts: 1867
Joined: Sat Mar 29, 2008 12:30 am
Location: Layfayette Hill, PA

Re: 91.08 Pathfinder + D&D3.5 Framework NEW!

Post by lmarkus001 »

tohavetobe wrote:Is there any tutorials or manuals of this framework?
From this forum category:
http://forums.rptools.net/viewtopic.php?f=53&t=25374

User avatar
Oryan77
Dragon
Posts: 452
Joined: Sun Feb 20, 2011 3:14 pm

Re: 91.08 Pathfinder + D&D3.5 Framework NEW!

Post by Oryan77 »

I have been trying to do this for hours now. I give up.

I have duplicated the "Creature Size" macro on the campaign window from this framework.

All I want to do is edit this duplicate macro and reverse the order of the radial buttons so that "Reduced" works on the left side and "Enlarged" works on the right side.

I don't want to mess with the "LibEnlargeReduce" macro on the lib token though because I still want to keep the original "Creature Size" macro working as-is.

All I seem to keep doing is making both radial buttons either "enlarge" the token or both will "reduce" the token. I can't seem to just flip them around.

Can you help me out here? Thanks!

User avatar
Oryan77
Dragon
Posts: 452
Joined: Sun Feb 20, 2011 3:14 pm

Re: 91.08 Pathfinder + D&D3.5 Framework NEW!

Post by Oryan77 »

Sorry, I have another question that maybe you can help me with.

I just to port over the "Lib:libDnD35Pathfinder" token to my own campaign. I am trying to use the "Elevation" macro from that token.

I think I created all of the proper states needed for that macro. I am able to set an elevation and choose the Elevation Type. The states appear on the token as they should.

The problem is that when I use the macro again to change the elevation, the "numbers" (states) do not get removed like they do in your campaign file. On mine, they stay and the new numbers (states) appear over them. I can keep doing this and the new numbers (states) keep stacking on the old ones. For example:

I set Current Elevation to "100". "100" appears on the token.
I set Current Elevation to "250". The tens and hundredths number (1 and 0) stay on the token, and 2 and 5 appear over them.

Any idea what I have not done correctly to make this work right?

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

Re: 91.08 Pathfinder + D&D3.5 Framework NEW!

Post by aliasmask »

In my code, you should get the group the states appear in and loop through setting them to 0 removing them and then set the states needed.

User avatar
Oryan77
Dragon
Posts: 452
Joined: Sun Feb 20, 2011 3:14 pm

Re: 91.08 Pathfinder + D&D3.5 Framework NEW!

Post by Oryan77 »

aliasmask wrote:In my code, you should get the group the states appear in and loop through setting them to 0 removing them and then set the states needed.
My ability and knowledge about code is extremely limited. What you said did not make much sense to me other than letting me know to check the name of the state group. I renamed the group my states were in to "Elevation" and that seemed to fix the problem. I'm not really sure how I can name the group to my own group name and still get the code to work. But thanks for getting me this far!

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

Re: 91.08 Pathfinder + D&D3.5 Framework NEW!

Post by aliasmask »

When setting the group name of a state it creates that group if not already there. It's under Campaign Properties, States Tab and field on the right named Group. My original code uses the "Elevations" group.

Here's the code I use.
||| CODE |||

Code: Select all

<!-- changeElevation(): output -->
[H: elevation.start = getProperty("Elevation")]
[H: elevation.states = getProperty("elevation.states")]
[H: elevation.type = getProperty("elevation.type")]
[H, if(! isNumber(elevation.start)): elevation.value = 0; elevation.value = elevation.start]
[H, if(! isNumber(elevation.states)): elevation.states = 0]

[H: elevationTypes = ",Fly,AirWalk,Levitate,Climb,Burrow,Swim,Above,Below"]
[H: type.index = max(0,listFind(elevationTypes,elevation.type))]

[H: abort(input(
   strformat('elevation.input|%{elevation.value}|Set Elevation|TEXT'),
   strformat('elevation.type|%{elevationTypes}|Set Elevation Type|LIST|VALUE=STRING SELECT=%{type.index}'),
   "output.secret|0|Secret Output|CHECK"
))]

<!-- error checking -->
[H, if(! isNumber(elevation.input)): elevation.input = 0]
<!-- enforce 5ft increments -->
[H: elevation.new = floor(elevation.input/5)*5]

[H, if(elevation.type == ""): elevation.states = 0; elevation.states = 1]
[H, if(! elevation.states && elevation.new == 0): elevation.type = ""]

<!-- update elevation based on new elevation and elevation type, ie underground is negative -->
[H: limit = 0]
[H, if(listContains("Burrow,Below",elevation.type)): limit = -5]
[H, if(elevation.type == "Above"): limit = 5]
[H, if(listContains("Burrow,Swim,Below",elevation.type)): elevation.new = min(limit,elevation.new); elevation.new = max(limit,elevation.new)]

<!-- clear elevation states -->
[H: newStates = getTokenStates("json","Elevations")]
[H, foreach(state,newStates): setState(state,0)]

<!-- set states -->
[H, if(elevation.states), code: {
   [H: setState("Elevation"+elevation.type,1)]
   [H: setState("ElevationBG",1)]
   <!-- convert elevation to state name -->
   [H: elevation.string = max(-95,min(995,elevation.new))]
   [H, if(elevation.string < 0): setState("negative",1)]
   [H: elevation.string = abs(elevation.string)]
   [H: elevation.100 = floor(elevation.string / 100)]
   [H: elevation.10 = floor((elevation.string - elevation.100 * 100)/10)]
   [H: elevation.1 = elevation.string - (elevation.100 * 100) - (elevation.10 * 10)]
   [H, if(elevation.100), code: {
      [H: setState("e"+elevation.100+"__",1)]
      [H: setState("e_"+elevation.10+"_",1)]
      [H: setState("e__"+elevation.1,1)]
   };{
      [H, if(elevation.10): setState("e_"+elevation.10+"_",1)]
      [H: setState("e__"+elevation.1,1)]
   }]   
};{}]

[H, if(! elevation.states && elevation.new == 0): elevation.type = ""]

<!-- set elevation value -->
[H: setProperty("Elevation",elevation.new)]
[H: setProperty("elevation.states",elevation.states)]
[H: setProperty("elevation.type",elevation.type)]

<!-- output elevation changes -->
[H: tokenImage = am.tokenImageLink(currentToken())]

[H: output = strformat('
   <table style="border-spacing:0px;border-style:solid;border-color:black;border-width:1pt;padding:0px">
      <tr>
         <td width="34" style="padding:0px">%{tokenImage}</td>
         <td width="250" style="background-color:aqua;padding:0px 5px 2px 5px;">%{token.name} (<b>%{elevation.type}</b>): Elevation changed from %{elevation.start} to %{elevation.new}.</td>
      </tr>
   </table>
')]

[H, if(output.secret), code: {
   [H: targets = am.getPlayerGroups("owner,gm")]
   [H, if(json.isEmpty(targets)): targets = "all")]
   [H: broadcast(output,targets)]
};{
   [H: broadcast(output)]
}]

Code: Select all

<!-- tokenImageLink(tokenId): imageLink
   tokenId - Can be id or name of token
   imageLink - small image of token that displays info about token in tooltip. 
      Clicking link selects token. Clicking link of selected token moves view to token.
      
This function will create an image link with token info in tooltip and can select token or move to using link.
-->

[H: tokenId = arg(0)]
[H: current = currentToken()]
[H: switchToken(tokenId)]

[H: isOnMap = findToken(current)]
[H, if(json.isEmpty(isOnMap)): t.image = getImage(current); t.image = getTokenImage()]

[H, if(getPropertyType(current) == getPropertyType(tokenId) && getPropertyType(current) == "Pathfinder"), code: {
   [H: t.ac = getProperty("AC")]
   [H: t.tactical = getProperty("sheet.moveReach")]
   [H: t.distance = distanceStatSheet(tokenId)]
   <!-- Calc health without revealing hit points -->
   [H: effectiveHP = getProperty("HP") + getProperty("HPtemp") - getProperty("HPNonLethalDMG")]
   [H: effectiveMaxHP = getProperty("HPmax") + getProperty("HPtemp")]
   [H, if(! json.isEmpty(effectiveHP)): percentHP = floor(effectiveHP/effectiveMaxHP*100); percentHP = 100]
   [H: healthLevels = "-1,0,9,50,79,99,100"]
   [H: healthNames = "Unconscious,Staggered,Frail,Wounded,Battered,Bruised,Unharmed"]
   [H: healthNames = "Unconscious,Staggered,Frail (0-9%),Wounded (10-50%),Battered (51-80%),Bruised (81-100%),Unharmed"]
   [H: healthStyles = "background-color:black;color:#FF4500;border-color:#FF4500;, background-color:gray;color:black;border-color:black;, background-color:red;color:white;border-color:black;, background-color:orange;color:black;border-color:black;, background-color:yellow;color:black;border-color:black;, background-color:#90EE90;color:black;border-color:black;, background-color:white;color:black;border-color:black;"]
   <!-- Get current HP level -->
   [H: index = 0]
   [H: isHigher = if(percentHP > listGet(healthLevels,index) && listCount(healthLevels) > index +1,1,0)]
   [H, while(isHigher), code: {
      [H: index = index + 1]
      [H: isHigher = if(percentHP > listGet(healthLevels,index) && listCount(healthLevels) > index +1,1,0)]
   }]
   [H: healthName = listGet(healthNames,index)]
   [H: healthStyle = listGet(healthStyles,index)]
   [H: col1 = "text-align:right;padding:0px 5px 0px 5px;font-weight:bold;"]
   [H: col2 = "padding:0px 5px 0px 0px;"]

   <!-- Create Tooltip text -->
   [H: tokenData = json.append("", 
      strformat('
         <table style="border-spacing:0px;padding:0px;">
            <tr style="border-width:2px;border-style:solid;%{healthStyle}">
               <td style="%{col1}">Status:</td>
               <td style="%{col2}font-weight:bold;padding-bottom:2px;" NOWRAP>%{healthName}</td>
            </tr>'),
      strformat('
            <tr>
               <td style="%{col1}">Name:</td>
               <td style="%{col2}">%{token.name}</td>
            </tr>')
   )]

   [H, if(! json.isEmpty(t.ac)): tokenData = json.append(tokenData,strformat('<tr><td style="%{col1}">AC/TH/FF (CMD/FF):</td><td style="%{col2}">%{t.ac}</td></tr>'))]
   [H, if(! json.isEmpty(t.tactical)): tokenData = json.append(tokenData,strformat('<tr><td style="%{col1}">Tactical:</td><td style="%{col2}">%{t.tactical}</td></tr>'))]
   [H, if(! json.isEmpty(t.distance)): tokenData = json.append(tokenData,strformat('<tr><td style="%{col1}">Distance:</td><td style="%{col2}">%{t.distance}</td></tr>'))]
   [H: tokenData = json.toList(tokenData,"")+"</table>"]
   [H: tooltip = strformat('<html><body style="background-color:white;"><table style="font-size:14pt;"><tr valign="top"><td><img src="%{t.image}" width="100" height="100" /></td><td>%{tokenData}</td></tr></table></body></html>')]
   [H: tooltip = replace(tooltip,'"',""")]
   [H: thisLib = getMacroLocation()]
   [H: imageLink = strformat('<a href="macro://gotoSelect@%{thisLib}/none/%{tokenId}?"><img border="0" src="%{t.image}" alt="%{tooltip}" width="30" height="30" /></a>')]
};{
   [H: imageLink = strformat('<img src="%{t.image}" alt="%{token.name}" width="30" height="30" />')]
}]
[H: switchToken(current)]

[H: macro.return = imageLink]

Code: Select all

<!-- getPlayerGroups(targets,token)
   targets - (default to all) A list or json of player names and/or groups who will see chatText.
      * all - all players (keywords are case sensitive) 
      * owner - anyone who owns the token. token must be valid and on current map
      * other - anyone who doesn't own token. token must be valid and on current map
      * gm - only gm players
      * -gm - anyone but the gm
      * self - only displayed to self
      * -self - display to all other players
      (Note: when posting multiple versions of the same output, using owner and other is most common)
   token - (default is currentToken) Specify owned token to post as. If currentToken is valid, but "" is passed, then chatText
      is posted as the player.

   Return players names based on target groups.
-->

[H, if(argCount() >= 1): targets = arg(0); targets = "all"]
[H, if(argCount() >= 2): token = arg(1); token = currentToken()]

<!-- validate token is on current map -->
[H: tokenId = findToken(token)]
[H, if(! json.isEmpty(tokenId)), code: {
   [H: tokenName = getName(tokenId)]
   [H: tokenImage = getImage(tokenId)]
};{}]

<!-- parse list of targets in to list of players names -->
[H, if(json.type(targets) == "UNKNOWN"): targets = json.fromList(targets)]

[H: players.all = getAllPlayerNames("json")]
[H: players.gm = json.get(getInfo("server"),"gm")]
[H: player.self = json.append("",getPlayerName())]
[H, if(json.isEmpty(tokenId)), code: {
	[H: players.owner = json.union(players.gm,players.self)]
	[H: players.other = json.difference(players.all,players.owner)]
};{
	[H, if(isOwnedByAll(tokenId)), code: {
		[H: players.owner = players.all]
		[H: players.other = "[]"]
	};{
		[H: players.owner = getOwners("json",tokenId)]
		[H: players.other = json.difference(players.all,players.owner)]
	}]
}]

<!-- get player names based on groups -->
[H: targetNames = "[]"]
[H, if(json.isEmpty(targets)), code: {
	[H: targetNames = players.all]
};{
	[H, if(json.contains(targets,"all")): targetNames = json.union(targetNames,players.all)]
	[H, if(json.contains(targets,"gm")): targetNames = json.union(targetNames,players.gm)]
	[H, if(json.contains(targets,"self")): targetNames = json.union(targetNames,players.self)]
	[H, if(json.contains(targets,"owner")): targetNames = json.union(targetNames,players.owner)]
	[H, if(json.contains(targets,"other")): targetNames = json.union(targetNames,players.other)]
	[H, if(json.contains(targets,"-gm")): targetNames = json.difference(targetNames,players.gm)]
	[H, if(json.contains(targets,"-self")): targetNames = json.difference(targetNames,player.self)]
	[H: targets = json.difference(targets,json.append("","all","gm","self","owner","other","-gm","-self"))]
	[H, if(! json.isEmpty(targets)): targetNames = json.intersection(players.all,json.union(targetNames,targets))]
}]

[H: macro.return = targetNames]

User avatar
Oryan77
Dragon
Posts: 452
Joined: Sun Feb 20, 2011 3:14 pm

Re: 91.08 Pathfinder + D&D3.5 Framework NEW!

Post by Oryan77 »

I am not sure what to change in the code since I see the word elevation appearing over and over and I'm not sure which text in the code refers to the state group name and which refers to other important features of the code using the same word elevation.

Is it simply that any line in the code with quotations around the word Elevation the only bit of code referring to the state group named Elevation? So changing just "Elevation" in the code to something like "My States" will work if my states are located in the My States group?

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

Re: 91.08 Pathfinder + D&D3.5 Framework NEW!

Post by aliasmask »

These are the relevant lines since your problem was with clearing the existing elevation states.:

Code: Select all

<!-- clear elevation states -->
[H: newStates = getTokenStates("json","Elevations")]
[H, foreach(state,newStates): setState(state,0)]

User avatar
Oryan77
Dragon
Posts: 452
Joined: Sun Feb 20, 2011 3:14 pm

Re: 91.08 Pathfinder + D&D3.5 Framework NEW!

Post by Oryan77 »

aliasmask wrote:These are the relevant lines since your problem was with clearing the existing elevation states.:

Code: Select all

<!-- clear elevation states -->
[H: newStates = getTokenStates("json","Elevations")]
[H, foreach(state,newStates): setState(state,0)]
That worked. Easy fix. Thank you.

User avatar
lmarkus001
Great Wyrm
Posts: 1867
Joined: Sat Mar 29, 2008 12:30 am
Location: Layfayette Hill, PA

Re: 91.08 Pathfinder + D&D3.5 Framework NEW!

Post by lmarkus001 »

Oryan77 wrote:I have been trying to do this for hours now. I give up.

I have duplicated the "Creature Size" macro on the campaign window from this framework.

All I want to do is edit this duplicate macro and reverse the order of the radial buttons so that "Reduced" works on the left side and "Enlarged" works on the right side.

I don't want to mess with the "LibEnlargeReduce" macro on the lib token though because I still want to keep the original "Creature Size" macro working as-is.

All I seem to keep doing is making both radial buttons either "enlarge" the token or both will "reduce" the token. I can't seem to just flip them around.

Can you help me out here? Thanks!
First of all, the Creature Size macro is to permanently resize a D&D3.5 creature. It is older code. I used it to scale a D&D3.5 creature as a GM as it permanently changes the Strength, Dexterity, Constitution of the creature (and changes the deprecated Natural Armor value).

The active-mod resizing actually changes weapon damage as well and is more sophisticated.

Given all that, if you still just want to swap the two choices, the campaign macro code would need to change to:

Code: Select all

/gm
[H: success = input(
  "pMod|Reduced,Enlarged|Size Change -- Selected targets are|Radio|ORIENT=H"
)]
[H: abort(success)]
[H: pMod = if(pMod, 0, 1)]
[H: modType = 1 ]

[MACRO("LibEnlargeReduce@Lib:libDnD35Pathfinder"): "Shrink=" + pMod +"; modType=" + modType + ";"] 

User avatar
Oryan77
Dragon
Posts: 452
Joined: Sun Feb 20, 2011 3:14 pm

Re: 91.08 Pathfinder + D&D3.5 Framework NEW!

Post by Oryan77 »

lmarkus001 wrote: Given all that, if you still just want to swap the two choices, the campaign macro code would need to change to:
That is exactly what I needed. Thanks. I am using it for my VTT campaign which does not use the robust character sheet and combat calculations. I just needed a convenient way to resize a token as if using the Enlarge/Reduce Person spells. This works perfectly for that. Thanks again!

User avatar
lmarkus001
Great Wyrm
Posts: 1867
Joined: Sat Mar 29, 2008 12:30 am
Location: Layfayette Hill, PA

Re: 91.08 Pathfinder + D&D3.5 Framework NEW!

Post by lmarkus001 »

Actually what it does NOT do is Enlarge/Reduce per the spells. The increase/decrease from these are much greater as they are the values used for scaling the size of a creature per the monster manual.

User avatar
Oryan77
Dragon
Posts: 452
Joined: Sun Feb 20, 2011 3:14 pm

Re: 91.08 Pathfinder + D&D3.5 Framework NEW!

Post by Oryan77 »

lmarkus001 wrote:Actually what it does NOT do is Enlarge/Reduce per the spells. The increase/decrease from these are much greater as they are the values used for scaling the size of a creature per the monster manual.
Oh it works fine for what I am using it for. I just need the token to increase/decrease to the next size category, which this does. I don't know enough about coding to create it myself. I don't use the character sheet and stat adjustments in your framework. So this macro may be overkill, but the resizing works and I get no errors. So it seems good enough to me. :P Thank you!

jsharen
Giant
Posts: 196
Joined: Tue Feb 05, 2008 3:39 pm

Re: 91.08 Pathfinder + D&D3.5 Framework NEW!

Post by jsharen »

Lindsay,
How hard would it be to add a clear mod's button? That just simply removes all active mods.

We find ourselves doing this regularly, and a simple button would be a lot smoother than having to uncheck every mod individually. Usually when we end a combat, and go into resting.

Cheers,
Jared

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

Re: 91.08 Pathfinder + D&D3.5 Framework NEW!

Post by aliasmask »

jsharen wrote:Lindsay,
How hard would it be to add a clear mod's button? That just simply removes all active mods.

We find ourselves doing this regularly, and a simple button would be a lot smoother than having to uncheck every mod individually. Usually when we end a combat, and go into resting.

Cheers,
Jared
There's an option in Edit Char that will remove all mods.

Post Reply

Return to “D&D 3.5/Pathfinder 1e Campaign Macros”