RPTools.net

Discussion and Support

Skip to content

It is currently Sun Nov 19, 2017 6:59 pm 




Forum rules


Discussion regarding lmarkus001's framework only. Other posts deleted without notice! :)



Reply to topic  [ 50 posts ]  Go to page Previous  1, 2, 3, 4

Previous topic | Next topic 

  Print view

Author Message
User avatar  Offline
Deity
 
Joined: Tue Nov 10, 2009 6:11 pm
Posts: 7947
Location: Bay Area
 Post subject: Re: [AM Macros] Lindsay's PF/3.5 Campaign FW (9-1-15)
PostPosted: Thu Oct 29, 2015 4:51 pm 
I also have a group of new macros for dealing with the character advancement chart in regards to xp and gold.

Lib:libDnD35Pathfinder wrote:
Code:
@@ @tabTable
@PROPS@ fontColor=black ; autoExecute=true ; fontSize=11pt ; sortBy=500 ; color=aqua ; playerEditable=false ; applyToSelected=false ; group=AM Updates ; tooltip= ; minWidth=94 ;
<!-- tabTable(rawData,headers,rowReference)
   rawData - tab deliminated table where all the last column data is filled in (error if not)
   headers - Use the first line as a header making the inside dimension an object where the key is the column name
      A value of 0 is no header, a value of 1 includes the header and a value of 2 makes the internal object just a string prop.
   rowReference - Use the first data item as a row header. This makes the outside dimension an object where the key is the first data item
      This item is still included in the data object.
     
   Convert tab deliminated text to a two dimensional json object.
-->

[H: rawData = arg(0)]
[H, if(argCount() >= 2): headers = arg(1); headers = 0]
[H, if(argCount() >= 3): rowRef = arg(2); rowRef = 0]

[H: TAB = decode("%09")]
[H: EOL = decode("%0A")]

[H: rawDataObj = json.fromList(rawData,EOL)]
[H, if(rowRef): returnData = "{}"; "[]"]

[H, foreach(line,rawDataObj), code: {
   [H: index = roll.count]
   [H: lineData = json.fromList(line,TAB)]
   [H: firstData = json.get(lineData,0)]
   [H, if(index == 0 && headers), code: {
      [H: propList = json.fromList(line,TAB)]
   };{}]
   [H, if(headers && index >= 1), code: {
      [H: lineObj = "{}"]
      [H, foreach(item,lineData): lineObj = json.set(lineObj,json.get(propList,roll.count),item)]
   };{
      [H: lineObj = lineData]
   }]
   [H, if(headers == 2): lineObj = json.toStrProp(lineObj)]
   [H, if(rowRef && index >= 1): returnData = json.set(returnData,firstData,lineObj)]
   [H, if(! rowRef && index >= 1): returnData = json.append(returnData,lineObj)]
}]

[H: macro.return = returnData]

!!
@@ @getMonsterXp
@PROPS@ fontColor=black ; autoExecute=true ; fontSize=11pt ; sortBy=500 ; color=aqua ; playerEditable=false ; applyToSelected=true ; group=AM Updates ; tooltip= ; minWidth=94 ;
<!-- getMonsterXp(cr): xp -->

[H: monsterCr = round(100 * arg(0))/100]
[H: monsterXpTable = getLibProperty("monsterXp")]
[H: monsterXp = json.get(json.get(monsterXpTable,monsterCr),"monster.xp")]

[H: macro.return = monsterXp]

!!
@@ @getCharXpGold
@PROPS@ fontColor=black ; autoExecute=true ; fontSize=11pt ; sortBy=500 ; color=aqua ; playerEditable=false ; applyToSelected=false ; group=AM Updates ; tooltip= ; minWidth=94 ;
<!-- getCharXpGold(progression,level): XP or gold value
   progression - fast,medium,slow,gold are the options for returning the respective xp or gold value from advancement table
   level - From 1 to 20. Level 1 is a homebrew value.
-->

[H: progression = lower(arg(0))]
[H: charLevel = arg(1)]

[H: propName = "xp."+progression]
[H: charAdvancementTable = getLibProperty("charAdvancement")]
[H: levelAdvancement = json.get(charAdvancementTable,charLevel)]

[H: macro.return = json.get(levelAdvancement,propName)]

!!
@@ @initXpTables
@PROPS@ fontColor=black ; autoExecute=true ; fontSize=11pt ; sortBy=500 ; color=aqua ; playerEditable=false ; applyToSelected=false ; group=AM Updates ; tooltip= ; minWidth=94 ;
[H: charAdvancement = 'xp.level   xp.slow   xp.medium   xp.fast   xp.gold
1   0   0   0   500
2   3000   2000   1300   1000
3   7500   5000   3300   3000
4   14000   9000   6000   6000
5   23000   15000   10000   10500
6   35000   23000   15000   16000
7   53000   35000   23000   23500
8   77000   51000   34000   33000
9   115000   75000   50000   46000
10   160000   105000   71000   62000
11   235000   155000   105000   82000
12   330000   220000   145000   108000
13   475000   315000   210000   140000
14   665000   445000   295000   185000
15   955000   635000   425000   240000
16   1350000   890000   600000   315000
17   1900000   1300000   850000   410000
18   2700000   1800000   1200000   530000
19   3850000   2550000   1700000   685000
20   5350000   3600000   2400000   880000']

[H: charAdvancement.table = am.tabTable(charAdvancement,1,1)]
[H: setLibProperty("charAdvancement",charAdvancement.table)]

[H: monsterXp = 'monster.cr   monster.xp
0.13   50
0.17   65
0.25   100
0.33   135
0.50   200
1   400
2   600
3   800
4   1200
5   1600
6   2400
7   3200
8   4800
9   6400
10   9600
11   12800
12   19200
13   25600
14   38400
15   51200
16   76800
17   102400
18   153600
19   204800
20   307200
21   409600
22   614400
23   819200
24   1228800
25   1638400
26   2457600
27   3276800
28   4915200
29   6553600
30   9830400']

[H: monsterXp.table = am.tabTable(monsterXp,1,1)]
[H: setLibProperty("monsterXp",monsterXp.table)]

!!


Once the macros are loaded you will need to run initXpTables once on the lib token.

Add this to onCampaignLoad
Code:
...
[H: defineFunction("am.tabTable","tabTable@"+thisLib,1)]
[H: defineFunction("am.getMonsterXp","getMonsterXp@"+thisLib,1)]
[H: defineFunction("am.getCharXpGold","getCharXpGold@"+thisLib,1)]
...


After update, run onCampaignLoad once for current session. It'll be done automatically in the future.

Add this to the Pathfinder token type:
Code:
*sheet.monsterXp (XP Award):[R, if(isNPC()): am.getMonsterXp(eval( "" + getStrProp(getProperty("Levels"),"ECL")));""]


I haven't done anything yet with the PC xp or gold progression but the function will retrieve the value from the table given the column name (fast,medium,slow,gold), level and return the entry. For example:

Code:
[H: abort(input("input.progression|Fast,Medium,Slow|Chose XP Progression|LIST|value=string","input.level|1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20|Chose Level|LIST|value=string"))]
[H: thisLevel = am.getCharXpGold(input.progression,input.level)]
[H: nextLevel = am.getCharXpGold(input.progression,min(20,input.level+1))]
[H: startGold = am.getCharXpGold("gold",input.level)]
[R: strformat("Level: %{thisLevel}/%{nextLevel}; Gold: %{startGold}")]

_________________
Downloads:


Top
 Profile  
 
User avatar  Offline
Deity
 
Joined: Tue Nov 10, 2009 6:11 pm
Posts: 7947
Location: Bay Area
 Post subject: Re: [AM Macros] Lindsay's PF/3.5 Campaign FW (10-29-15)
PostPosted: Sat Nov 14, 2015 5:59 am 
MIRROR IMAGE MACRO

Okay, this has a bunch of requirements that are not in the normal framework, but it will activate, set state images (and bar) to show the number of mirror images +1 (includes the caster). Basically and thematically, it's easier to show the number of possible targets than the number of extra images. So, if you have 6 images, there are 7 of you. Roll 1d7 and on a 1 the caster may be hit.

Active Mod
You need to create an active mod for this spell "Mirror Image". When creating it you need to set the state to MirrorImage. That's it.

Images for state and bar
The zip file has the state image and counter images for the bar you need to create. I also added some screen shots to help you set those up. The bar has 11 increments starting with blank, counter_1 to 9 and ending in blank for full bar.

Macro
You'll need to add the mirrorImage macro to Lib:libDnD35Pathfinder. The calling macro could be on a token or in the campaign macros. You can use [macro:] or create a UDF (Wiki: defineFunction()).

One thing to note is that attacks that are at 5 less than the target's AC can break an image. So, when it says May Hit Caster, this is what I'm talking about. You can handle this 1 or 2 ways. Just set all the potential hits for your number of attacks, then decide which images were destroyed or run macro once for each potential hit separately. The problem with doing it all at once is the May Hit may actually break an image if that attack was less than target's AC screwing up the next roll. What you could do is just ignore the next roll when that happens and go down to the one that has the correct 1:X chance to hit. But if you do it one at a time, when that happens you can set the number of images down by one manually.

Attachment:
Mirror Image Example.jpg
Mirror Image Example.jpg [ 78.67 KiB | Viewed 644 times ]


Code:
@@ @mirrorImage
<!-- Check Active Mod -->
[
H: isActiveMod = json.contains(json.get(PrivateJSON,"ActiveTempModSets"),"Mirror Image")]

<!--
 subModToggle settings -->
[
H: modToToggle = "Mirror Image" ]
[
H: modType = 0 ] <!-- modType 0 = mod, 1 = item -->
[
H: tcasterlvl = getProperty("am.casterLevel")]
[
H, if(json.isEmpty(tcasterlvl)): tcasterlvl = 3] <!-- min level for mirror image -->
[
H: output = "[]"]

<!--
 if not active, activate -->
[
H, if(! isActiveMod), code: {
   [H: selectLevel = tcasterlvl -1]
   [H: abort(input(strformat("tcasterlvl|1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20|Set Caster Level|RADIO|orient=H value=string select=%{selectLevel}")))]
   [H: setProperty("am.casterLevel",tcasterlvl)]
   [H, if(isPC()): CLtext = strformat("<b>Caster Level: <font color=blue>%{tcasterlvl}</font></b>"); CLtext = ""]
   [MACRO( "subModToggle@Lib:libDnD35Pathfinder" ): json.set( "{}", "tokenID", currentToken(), "setID", modToToggle, "setType", modType, "casterlevel", tcasterlvl ) ]
   [H: output = json.append(output,trim(macro.return)+CLtext)]
   [H: setBar("Counter",min(9,1d4+floor(tcasterlvl/3)+1)/10)]
   [H: defaultNumAttacks = 0]
};{
   [H: defaultNumAttacks = 1]
}]

<!--
 bar should be on because it holds the count of the images plus the caster -->
[
H, if(isBarVisible("Counter")): imageCount = floor(getBar("Counter") * 10); imageCount = 0]

<!--
 allow user to modify the starting number of images -->
[
H: abort(input("tip|<html><b>* Current number of images including the caster.</b></html>|Changing value to 1 or less will end spell.|LABEL|SPAN=TRUE",
   strformat("newCount|<html><b color=gray>0</b></html>,<html><b color=gray>1</b></html>,2,3,4,5,6,7,8,9|Current Images (+1)|RADIO|select=%{imageCount} orient=H"),
   "tip|<html><br><b>* Number of attacks that threaten to break an image.</b></html>|Once all images are broken, then the spell ends.|LABEL|SPAN=TRUE",
   strformat("numAttacks|0,1,2,3,4,5,6,7,8,9|How many attacks|RADIO|orient=H select=%{defaultNumAttacks}")
))]

[
H, if(newCount != imageCount): output = json.append(output,strformat("Images changed from %{imageCount} to %{newCount} by user."))]

<!--
 count the swings it takes to destroy all the images -->
[
H: attackCounter = numAttacks]
[
H: imagesDestroyed = 0]
[
H: attackNum = 0]
[
H, while(imagesDestroyed < newCount -&& attackCounter), code: {
   [H: attackNum = roll.count +1]
   [H: imagesRemaining = newCount - imagesDestroyed]
   [H: chance = strformat("(1:%{imagesRemaining})")]
   [H: miss = roll(1,imagesRemaining) -1]
   [H, if(miss): imagesDestroyed = imagesDestroyed +1]
   [H: attackCounter = attackCounter -1]
   [H,if(! miss): output = json.append(output,strformat("Attack %{attackNum} %{chance}: <font color=red>May Hit Caster</font>")); 
      output 
= json.append(output,strformat("Attack %{attackNum} %{chance}: <font color=blue>Destroys Image</font>"))]
}]

[
H: imagesRemaining = newCount - imagesDestroyed]
[
H, if(imagesRemaining <= 1), code: {
   [H: output = json.append(output,strformat("All images destroyed"))]
   [MACRO( "subModToggle@Lib:libDnD35Pathfinder" ): json.set( "{}", "tokenID", currentToken(), "setID", modToToggle, "setType", modType, "casterlevel", tcasterlvl ) ]
   [H: output = json.append(output,macro.return)]
   [H: setBarVisible("Counter",0)]
};{
   <!-- update bar "Counter" to current number of images -->
   [H: setBar("Counter",imagesRemaining/10)]
}]

[
H: remainingAttacks = numAttacks - attackNum]
[
H, if(remainingAttacks): output = json.append(output,strformat("The remaining %{remainingAttacks} attacks strike as normal"))]

<!--
 mirror image report -->
[
H: imageLink = am.tokenImageLink(currentToken())]
[
H: output = json.toList(output,"<br>")]
[
H: output.block = strformat('
   <table style="border-spacing:1pt;border-width:0px;border-style:solid;padding:0px;">
      <tr><td colspan=2 style="background-color:#FF99FF;border-width:1pt;border-style:solid;padding:0px 3px 0px 6px;"><b>%{token.name}</b> - Spell: Mirror Image</td></tr>
      <tr valign="top">
         <td width="34" style="padding:0px;border-width:1pt;border-style:solid;text-align:center;">%{imageLink}</td>
         <td width="250" style="background-color:#FFCCFF;border-width:1pt;border-style:solid;padding:0px 3px 0px 6px;font-weight:bold;">%{output}</td>
      </tr>
   </table>
'
)]
[
H: broadcast(output.block)]

!!
 


edit: I did a small edit to the code and post. I decided to do the caster level setting in the macro to avoid an exploit if done through globalMod. ie, you can put level 200 and it would always give you max images. So, I get level in the macro to avoid that.

edit: After some use, I find it more convenient to just do the default single attack. In the case of "May hit Caster" if it actually misses caster because it was with in 5 AC then I decrement images and run again or if it was last attack set attacks to 0 so that the number of images is correct.


Mirror Image.zip [221.58 KiB]
Downloaded 57 times

_________________
Downloads:
Top
 Profile  
 
User avatar  Offline
Great Wyrm
 
Joined: Fri Mar 28, 2008 11:30 pm
Posts: 1870
Location: Layfayette Hill, PA
 Post subject: Re: [AM Macros] Lindsay's PF/3.5 Campaign FW (11-13-15)
PostPosted: Tue Nov 17, 2015 2:44 pm 
Nice addition! I continue to incorporate your additions into my core framework, so next update will have this.

Personally I don't worry about exploits. Anyone foolish enough to game the system while I GM shall suffer the consequences as I have ultimate control of the narrative (wow, that orc had over 300 hitpoints and never missed a single swing!).

_________________
D&D3.5 / Pathfinder Framework


Top
 Profile  
 
User avatar  Offline
Deity
 
Joined: Tue Nov 10, 2009 6:11 pm
Posts: 7947
Location: Bay Area
 Post subject: Re: [AM Macros] Lindsay's PF/3.5 Campaign FW (11-13-15)
PostPosted: Tue Nov 17, 2015 4:03 pm 
I also updated all the normal states from 3x3 to 4x4 because of the image placement. I also updated the elevation states to be smaller (top half of upper right corner). It looks better and is less dominating of the token. The numbers are still in the same position but I changed them to mouseover. I also included a state behind the numbers so they stand out over the elevation state. I also added AirWalk to the list.

That post will soon be here.

_________________
Downloads:


Top
 Profile  
 
User avatar  Offline
Deity
 
Joined: Tue Nov 10, 2009 6:11 pm
Posts: 7947
Location: Bay Area
 Post subject: Re: [AM Macros] Lindsay's PF/3.5 Campaign FW (11-13-15)
PostPosted: Fri Feb 12, 2016 10:57 am 
I recently had a player create a Summoner (Synthesist). The framework doesn't handle the tracking of hitpoints very well so I wrote some code, created some health bars and states to help with that. It's very one dimensional right now only handling the case of a single class Synthesist, but I was wondering if anyone out there has a need for this. If so, I can share what I have and perhaps develop it more.

_________________
Downloads:


Top
 Profile  
 
Display posts from previous:  Sort by  
Reply to topic  [ 50 posts ]  Go to page Previous  1, 2, 3, 4

You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:

Who is online

In total there is 1 user online :: 0 registered, 0 hidden and 1 guest (based on users active over the past 5 minutes)
Most users ever online was 243 on Sun Nov 04, 2012 6:14 am

Users browsing this forum: No registered users and 1 guest





Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group

Style based on Andreas08 by Andreas Viklund

Style by Elizabeth Shulman