Re: 91.08 Pathfinder + D&D3.5 Framework NEW!
Posted: Sun May 28, 2017 11:10 am
Thank you LM!!!
Code: Select all
[H, if(variable == "string"): "true thing"; "false thing"]
Thx for the quick answeraliasmask wrote:
To track it down, you'll need to restart the launcher and go to the Advanced tab and check the macro handling box. You can then start the campaign, do what you do to get the error and then go to the .maptool folder under user profiles and look at the log.txt file for the exact line where the error occurs (near bottom of file). I recommend maybe deleting this file before restarting the campaign for a fresh file.
You can then copy/paste the error lines and a couple of lines before the error here and someone can take a look at it.
Code: Select all
tjfjMM = json.fields( jMM, "json")
tjfjMM = if(tjfjMM == "", 0, tjfjMM)
Code: Select all
tjfjMM = json.fields( jMM)
tjfjMM = if(tjfjMM == "", 0, tjfjMM)
Code: Select all
tjfjMM = json.fields( jMM, "json")
tjfjMM = if(json.isEmpty(tjfjMM) == 1, 0, tjfjMM)
<!-- although it appears this is the intention, its bad coding as the end result is either numeric OR an array which can lead to all sorts of bugs -->
Code: Select all
@@ @Attack
@PROPS@ fontColor=black ; autoExecute=true ; fontSize=1.00em ; sortBy=1 ; color=gray ; playerEditable=false ; applyToSelected=true ; group=Combat ; tooltip= ; minWidth= ;
<!-- ATTACK -->
[H: fGMSecret = getLibProperty("fGMSecret", "Lib:GlobalsSRDPF")]
[H, IF( json.type( macro.args ) == "UNKNOWN" ), CODE: {
[ weaponID = macro.args ]
[ flagSecret = fGMSecret ]
};{
[ weaponID = json.get( macro.args, "weaponID" ) ]
[ flagSecret = json.get( macro.args, "flagSecret" ) ]
[IF( json.isEmpty( flagSecret ) ): flagSecret = fGMSecret ]
[ numWeapChoice = json.get( macro.args, "numWeapChoice" ) ]
[IF( json.isEmpty( numWeapChoice ) ): numWeapChoice = 10 ]
} ]
[H: tToken = currentToken() ]
[H, TOKEN( tToken ): assert( isOwner() || isGM(), getMacroName() + ": Not your token!" ) ]
[H: weaponID = if( isNumber(weaponID), "Weapon" + weaponID, weaponID ) ]
[H: gTok = "Lib:GlobalsSRDPF" ]
[H: system = getLibProperty("System", gTok)]
[H, SWITCH(system), CODE:
case "Pathfinder": {
[ meleeMods = table( "SysVars", json.get( table( "SysVars", 0 ), "meleeModsPF" ) ) ]
[ pRapid = "Rapid Shot Attack *" ]
[H: tPF= "PF"]
[H: tTable = "PFSpecialATK" ]
[H: sachoices = "None, Disarm, Grapple, Sunder, Trip"]
};
case "D&D3.5": {
[ meleeMods = table( "SysVars", json.get( table( "SysVars", 0 ), "meleeModsSRD" ) ) ]
[ pRapid = "Flurry of Blows/Rapid Shot Attack *" ]
[H: tPF= "PF"]
[H: tTable = "SRDSpecialATK" ]
[H: sachoices = "None, Disarm, Grapple, Sunder, Trip"]
};
default: {
}
]
[H: tPF = if( "Pathfinder" == getPropertyType(), "PF", tPF)]
[H: tPointBlankShot = getStrProp(Feats, "PointBlankShot")]
[H: tPointBlankShot = if(tPointBlankShot == "", 0, tPointBlankShot)]
[H: tManyShot = getStrProp(Feats, "ManyShot")]
[H: tManyShot = if(tManyShot == "", 0, tManyShot)]
[H: manyShot = 0 ]
[H: optManyShot = IF(tManyShot, "manyShot|0|Using Many Shot Feat?|CHECK| ##", "" ) ]
[H: tVitalStrike = getStrProp(Feats, "VitalStrike")]
[H: tVitalStrike = if(tVitalStrike == "", 0, tVitalStrike)]
[H: tImpVitalStrike = getStrProp(Feats, "ImprovedVitalStrike")]
[H: tImpVitalStrike = if(tImpVitalStrike == "", 0, tImpVitalStrike)]
[H: tGrVitalStrike = getStrProp(Feats, "GreaterVitalStrike")]
[H: tGrVitalStrike = if(tGrVitalStrike == "", 0, tGrVitalStrike)]
[H: tVitalStrike = if( tGrVitalStrike || tImpVitalStrike || tVitalStrike, 1, 0 ) ]
[H: vitalStrike = 0 ]
[H: optVitalStrike = IF(tVitalStrike, "vitalStrike|0|Use Vital Strike Feat?|CHECK| ##", "" ) ]
[H: jCC = json.get( PrivateJSON, "CombatConfig" ) ]
[H, IF( json.type( jCC ) == "UNKNOWN" ), CODE: {
[ jCC = json.set( "{}", "fullRound", 1, "rangeIncrement", 1, "flurryRapid", 1, "favEnemy", 0, "sneak", "0d6", "fireIntoMelee", 0, "manyShot", manyShot, "critConfirm", 0, "modCritRange", 0, "sizeVariant", 0, "rollTwice", 0 ) ]
[ PrivateJSON = json.set( PrivateJSON, "CombatConfig", jCC ) ]
}]
[H: sizeVariant = json.get( jCC, "sizeVariant" ) ]
[H, IF( sizeVariant == "" ): sizeVariant = 0; "" ]
[H: rollTwice = json.get( jCC, "rollTwice" ) ]
[H, IF( rollTwice == "" ): rollTwice = 0; "" ]
[H: tCriticalFocus = getStrProp(Feats, "CriticalFocus")]
[H: tCriticalFocus = if(tCriticalFocus == "", 0, tCriticalFocus)]
[H: critConfirm = json.get( jCC, "critConfirm" ) ]
[H: critConfirm = if( critConfirm == 0 && tCriticalFocus, tCriticalFocus*4, critConfirm ) ]
[H: sizeList = table( "SysVars", json.get( table( "SysVars", 0 ), "sizeList" ) ) ]
[H: inCC =
"fullRound|Single, Full Round|Attack|RADIO|ORIENT=H SELECT=1 ##"
+ "concealMiss|0,1,2|Roll How Many Miss Chances?|RADIO|ORIENT=H VALUE=STRING ##"
+ "flagSecret|" + flagSecret + "|<html><font color=red>Secret</font>?</html>|CHECK| ##"
+ "specialATKChoice|" + sachoices + "|Follow-on Special Attack?|LIST|SELECT=0 ##"
+ "tempATK|0|Temporary Attack Bonus|TEXT|WIDTH=10 ##"
+ "tempDMG|0|Temporary Damage Bonus|TEXT|WIDTH=10 ##"
+ "flanking|0|Flanking?|CHECK| ##"
+ "higherGround|0|Attacking from Higher Ground?|CHECK| ##"
+ "cover|0|<html><span title='Use for Melee attacking around a hard corner or Range attacks with impediments (like an ally) in the way (-4 to Attack).'>Target has Cover?</span></html>|CHECK| ##"
+ optManyShot + optVitalStrike
+ "flurryRapid|-2, -1, 0, Normal Attack|"+pRapid+"|RADIO|ORIENT=H SELECT=3 ##"
+ "seperator|<html> * Gives an additional attack if <i>Full Round</i> and weapon is <i>Manufactured</i>.</html>||LABEL|SPAN=TRUE ##"
+ "rangeIncrement|1,2,3,4,5,6,7,8,9,10|Range Increment|RADIO|ORIENT=H SELECT=0 ##"
+ "pointBlank|0|<html>Point Blank Range (<font color=red>30 feet</font>)?</html>|CHECK| ##"
+ "seperator|<html> ------ </i>Persistent</i> ------</html>||LABEL|SPAN=TRUE ##"
+ "fireIntoMelee|" + json.get( jCC, "fireIntoMelee" ) + "|<html><span title='Use for Shooting/Throwing into Melee (-4 to Attack).'>Fire into Melee?</span></html>|CHECK| ##"
+ "modCritRange|" + json.get( jCC, "modCritRange" ) + "|Mod to Crit Range|TEXT|WIDTH=10 ##"
+ "critConfirm|" + critConfirm + "|Bonus to Confirm Critical Hit|TEXT|WIDTH=10 ##"
+ "favEnemy|" + json.get( jCC, "favEnemy" ) + "|Favorite Enemy Bonus|TEXT|WIDTH=10 ##"
+ "sneak|" + json.get( jCC, "sneak" ) + "|Sneak Attack Damage|TEXT|WIDTH=10 ##"
+ "sizeVariant| NA," + sizeList + "|<html><span title='Use when Enlarged or Reduced to change the base damage dice.'>Variant Size</span></html>|RADIO| ORIENT=H SELECT=" + sizeVariant + " ##"
+ "rollTwice| NA, Use Highest, Use Lowest|Roll Attack Twice Variant|RADIO| ORIENT=H SELECT=" + rollTwice
]
[H: aTMS = json.get( PrivateJSON, "ActiveTempModSets" ) ]
[H, IF( json.type( aTMS ) == "UNKNOWN" ), CODE: {
[ PrivateJSON = json.set( PrivateJSON, "ActiveTempModSets", "[]" ) ]
[ aTMS = "[]" ]
}]
[H: jPTM = json.get( PrivateJSON, "CustomModSetValues" ) ]
[H: jMMFields = json.sort( json.fields( meleeMods, "json" ) ) ]
[H: inMods = "" ]
[H: modString = "%{p} | %{v} | %{n} | %{t} | %{o}" ]
[H, FOREACH( m, jMMFields ), CODE: {
[ active = if( json.contains( aTMS, m ), 1, 0 ) ]
[ jMM = json.get( meleeMods, m ) ]
[IF( isNumber( jMM ) ), CODE: {
[ p = replace( replace( m, " ", "_" ), "/", "." ) ]
[ v = active ]
[ n = "<html><b>" + m + "</b></html>" ]
[ t = "CHECK" ]
[ o = "" ]
[ inMods = listAppend( inMods, strformat( modString ), "##" ) ]
};{
[ p = m ]
[ v = "<html><b>" + m + "</b></html>" ]
[ n = m ]
[ t = "LABEL" ]
[ o = "SPAN=TRUE" ]
[ inMods = listAppend( inMods, strformat( modString ), "##" ) ]
[MACRO( "pAttack@this" ): json.set( "{}", "tokenID", tToken, "mod", m, "variables", jMM, "active", active ) ]
[ tinMods = json.get( macro.return, "inMods" ) ]
[ inMods = listAppend( inMods, tinMods, "##" ) ]
}]
}]
[H: inWeap = "" ]
[H, IF(weaponID == ""), CODE: {
[H: weaponNames=""]
[H, C(31, ""): weaponNames = weaponNames + ", " + getStrProp(eval("Weapon" + roll.count), "Name")]
[H: inWeapString = 'Weap%{roll.count}|' + weaponNames + '|Select Attack%{roll.count}| LIST | SELECT=%{tSelect}' ]
[H, C(numWeapChoice, ""), CODE: {
[ tSelect = getStrProp( Private, "LastWeap" + roll.count ) ]
[ inWeap = listAppend( inWeap, strformat( inWeapString ), '##' ) ]
}]
};{
[ weaponNames = getStrProp(eval("" + weaponID), "Name")]
[ inWeap = 'junk|' + weaponNames + '|Weapon| LABEL |' ]
}]
[H: visTokens = "[]" ]
[H: visTokenIDs = getVisibleTokens("json") ]
[H, FOREACH( i, visTokenIDs ),CODE: {
[IF(isNumber(i)): ""; visTokens = json.append( visTokens, json.set( "{}", "name", getName(i), "id", i, "range", lgm.getDistanceElev(i,tToken) ) ) ]
}]
[H: visTokens = json.sort( visTokens, "ascend", "range", "name" ) ]
[H: visTokenNames = "[]" ]
[H, FOREACH( i, visTokens ), CODE: {
[ visTokenRange = json.get( i, "range" ) ]
[ visTokenNames = json.append( visTokenNames, "(" + if( visTokenRange <= 30, "<font color=red>", "" ) + visTokenRange + " ft." + if( visTokenRange <= 30, "</font>", "" ) + ") " + json.get( i, "name" ) ) ]
}]
[H: visTokenNameList = "Not Specified" ]
[H, FOREACH( i, visTokenNames, "" ): visTokenNameList = listAppend( visTokenNameList, "<html>" + replace( i, ",", "_" ) + "</html>" ) ]
[H: cancel = input(
"tab0 | Config Attack | | TAB",
inWeap,
inCC,
"seperator|<html> ---vvvv--- </i>Mod-Sets</i> ---vvvv---</html>||LABEL|SPAN=TRUE",
inMods,
"tab1 | Primary Target | | TAB",
"tTarget1 | " + visTokenNameList + " |Target|RADIO|",
"tab1 | Secondary Target | | TAB",
"tTarget2 | " + visTokenNameList + " |Target|RADIO|"
)]
[H: abort(cancel)]
[H: flurryRapid = flurryRapid - 2 ]
[H, IF( tTarget1 == 0 ): target1ID = ""; target1ID = json.get( json.get( visTokens, tTarget1-1 ), "id" ) ]
[H, IF( tTarget2 == 0 ): target2ID = ""; target2ID = json.get( json.get( visTokens, tTarget2-1 ), "id" ) ]
[H, IF( tTarget1 == 0 ): target1Name = ""; target1Name = json.get( json.get( visTokens, tTarget1-1 ), "name" ) ]
[H, IF( tTarget2 == 0 ): target2Name = ""; target2Name = json.get( json.get( visTokens, tTarget2-1 ), "name" ) ]
[H, IF( target1ID != "" ), CODE: {
[H, IF( am.hasHighGround( tToken, target1ID ) ): higherGround = 1; ""]
[H: tdist = lgm.getDistanceElev(target1ID,tToken)]
[H, IF(tdist <= 30 && tPointBlankShot): pointBlank = 1; pointBlank = 0]
};{}]
[H, IF(weaponID == ""), CODE: {
[H: Private = setStrProp(Private, "LastWeap0", Weap0)]
[H, IF(numWeapChoice >= 2): Private = setStrProp(Private, "LastWeap1", Weap1)]
[H, IF(numWeapChoice >= 3): Private = setStrProp(Private, "LastWeap2", Weap2)]
[H, IF(numWeapChoice >= 4): Private = setStrProp(Private, "LastWeap3", Weap3)]
[H, IF(numWeapChoice >= 5): Private = setStrProp(Private, "LastWeap4", Weap4)]
[H, IF(numWeapChoice >= 6): Private = setStrProp(Private, "LastWeap5", Weap5)]
[H, IF(numWeapChoice >= 7): Private = setStrProp(Private, "LastWeap6", Weap6)]
[H, IF(numWeapChoice >= 8): Private = setStrProp(Private, "LastWeap7", Weap7)]
[H, IF(numWeapChoice >= 9): Private = setStrProp(Private, "LastWeap8", Weap8)]
[H, IF(numWeapChoice >= 10): Private = setStrProp(Private, "LastWeap9", Weap9)]
};
{}]
[FOREACH( m, jMMFields, "" ), CODE: {
[H: changed = 0 ]
[H: disable = 1 ]
[H: active = if( json.contains( aTMS, m ), 1, 0 ) ]
[H: jMM = json.get( meleeMods, m ) ]
[H: presetVars = "" ]
[H: tjfjMM = json.fields( jMM, "json")]
[H, FOREACH( n, tjfjMM ), CODE: {
[ isJObj = if( json.type( jMM ) == "OBJECT", 1, 0 ) ]
[IF( isJObj && active ): v = json.get( json.get( json.get( json.get( jPTM, m ), "mods" ), "globalMod" ), "v" ); v = 0 ]
[IF( isJObj ): tmv = eval( "" + json.get( jMM, n ) ); tmv = eval( "" + replace( replace( m, " ", "_" ), "/", "." ) ) ]
[IF( isJObj ): disable = if( tmv != 0, 0, disable ); disable = 1 ]
[IF( isJObj ): changed = if( v != tmv, 1, changed ); changed = if( active != tmv, 1, changed ) ]
[IF( changed && isJObj ): presetVars = json.set( presetVars, json.get( jMM, n ), tmv ) ]
}]
[IF( changed && active ), CODE: {
[MACRO( "subModToggle@this" ): json.set( "{}", "tokenID", tToken, "setID", m, "setType", 0 ) ]
};{}]
[IF( changed && ( !disable || !active ) ), CODE: {
[MACRO( "subModToggle@this" ): json.set( "{}", "tokenID", tToken, "setID", m, "setType", 0, "presetVars", presetVars ) ]
};{}]
}]
[H,IF(weaponID == ""), CODE: {
[C(numWeapChoice,""), IF( eval("Weap" + roll.count) == "" || eval("Weap" + roll.count) == 0), CODE: {
};{
[H: ti = eval("Weap" + roll.count) - 1]
[H: tWeap = "Weapon" + ti]
[H, IF( target1ID != "" ): lgm.getWeaponset(ti);""]
[H, IF( target1ID != "" ): rangeIncrement = floor((tdist-0.01)/WpnRangeInc);""]
[MACRO("LibAttack@this"): json.set("{}", "weapon", tWeap, "fullRound", fullRound, "flanking", flanking, "higherGround", higherGround, "favEnemy", favEnemy, "rangeIncrement", rangeIncrement, "pointBlank", pointBlank, "cover", cover, "fireIntoMelee", fireIntoMelee, "sneak", sneak, "flurryRapid", flurryRapid, "target1Name", target1Name, "target1ID", target1ID, "target2Name", target2Name, "target2ID", target2ID, "flagSecret", flagSecret, "tempATK", tempATK, "tempDMG", tempDMG, "concealMiss", concealMiss, "manyShot", manyShot, "critConfirm", eval(""+critConfirm), "modCritRange", eval(""+modCritRange), "vitalStrike", vitalStrike, "sizeVariant", sizeVariant, "rollTwice", rollTwice ) ]
}]
};{
[H: ti = replace(lower(weaponID),"weapon","")]
[H, IF( target1ID != "" ): lgm.getWeaponset(ti);""]
[H, IF( target1ID != "" ): rangeIncrement = floor((tdist-0.01)/WpnRangeInc);""]
[MACRO("LibAttack@this"): json.set("{}", "weapon", weaponID, "fullRound", fullRound, "flanking", flanking, "higherGround", higherGround, "favEnemy", favEnemy, "rangeIncrement", rangeIncrement, "pointBlank", pointBlank, "cover", cover, "fireIntoMelee", fireIntoMelee, "sneak", sneak, "flurryRapid", flurryRapid, "target1Name", target1Name, "target1ID", target1ID, "target2Name", target2Name, "target2ID", target2ID, "flagSecret", flagSecret, "tempATK", tempATK, "tempDMG", tempDMG, "concealMiss", concealMiss, "manyShot", manyShot, "critConfirm", eval(""+critConfirm), "modCritRange", eval(""+modCritRange), "vitalStrike", vitalStrike, "sizeVariant", sizeVariant, "rollTwice", rollTwice ) ]
}]
[H: PrivateJSON = json.set( PrivateJSON, "CombatConfig", json.set( "{}", "fullRound", fullRound, "rangeIncrement", rangeIncrement, "pointBlank", pointBlank, "flurryRapid", flurryRapid, "favEnemy", favEnemy, "sneak", sneak, "fireIntoMelee", fireIntoMelee, "manyShot", manyShot, "critConfirm", critConfirm, "modCritRange", modCritRange, "sizeVariant", sizeVariant, "rollTwice", rollTwice ) ) ]
[H: tType = listGet( sachoices, specialATKChoice ) ]
[H: cntAll = table( tTable, 0 )]
[H: ref = ""]
[H: i = 1 ]
[H, WHILE( ref == "" && i <= cntAll ), CODE: {
[H: jType = table( tTable, i )]
[R: cType = json.get( jType, "name" )]
[H, IF(tType == cType): ref = ref + json.get( jType, "ref" )]
[H: i = i + 1 ]
}]
[H: out1 = "<b>" + macroLink( tType, "dispSATKrules@" + getMacroLocation(), "none", json.set( "", "name", tType, "system", system)) + "</b> (" + ref + ")<br />" ]
[H,IF(flagSecret && (specialATKChoice != 0)),CODE:{
[H: broadcast(out1,json.union(lgm.getAllGMs(),getOwners("json",tToken)),"json") ]
};{}]
[H,IF(!flagSecret && (specialATKChoice != 0)),CODE:{
[H: broadcast(out1) ]
};{}]
[H,SWITCH(system), CODE:
case "Pathfinder": {
[SWITCH(specialATKChoice), CODE:
case 0: { };
case 1: { [MACRO("subDisarm"+tPF+"@this"): ""] };
case 2: { [MACRO("subGrapple"+tPF+"@this"): ""] };
case 3: { [MACRO("subSunder"+tPF+"@this"): ""] };
case 4: { [MACRO("subTrip"+tPF+"@this"): ""] };
]
};
case "D&D3.5": {
[SWITCH(specialATKChoice), CODE:
case 0: { };
case 1: { [MACRO("subDisarm"+tPF+"@this"): ""] };
case 2: { [MACRO("subGrapple"+tPF+"@this"): ""] };
case 3: { [MACRO("subSunder"+tPF+"@this"): ""] };
case 4: { [MACRO("subTrip"+tPF+"@this"): ""] };
]
};
default: {}
]
!!
@@ @processAttack
@PROPS@ fontColor=black ; autoExecute=true ; fontSize=1.00em ; sortBy=1 ; color=cyan ; playerEditable=true ; applyToSelected=false ; group=CombatDialog ; tooltip= ; minWidth= ;
[H: margs = macro.args ]
[H: gLib = "Lib:GlobalsSRDPF" ]
[H: submitAction = replace(json.get(margs, "processAttack"),"<[^>]*?>","") ]
[H: numWeapChoice = json.get( margs, "numWeapChoice" ) ]
[H,IF( json.isEmpty( numWeapChoice ) ): numWeapChoice = 4 ]
[H: tToken = json.get(margs, "id") ]
[H: isTokHere = findToken( tToken) ]
[H: tcmap = getCurrentMapName() ]
[H: ttmap = json.get(margs,"tmap") ]
[H, IF( isTokHere == "" ): setCurrentMap( ttmap ); "" ]
[H, IF( isTokHere == "" ): isTokHere2 = findToken( tToken); isTokHere2 = 1 ]
[H, IF( isTokHere2 == "" ): execLink( macroLinkText("subReturnToMap@" + getMacroLocation(), "none", tcmap), 1); "" ]
[H: assert( isTokHere2 != "", "Attack Frame: Token not found. Move to the map containing your token and try again.")]
[H, IF( isTokHere != "" && tcmap != ttmap): margs = json.set(margs,"tmap",tcmap); "" ]
[H: target1ID = json.get(margs, "target1ID") ]
[H, IF(target1ID == ""): tid1name = ""; tid1name = getName(target1ID) ]
[H: target2ID = json.get(margs, "target2ID") ]
[H, IF(target2ID == ""): tid2name = ""; tid2name = getName(target2ID) ]
[H: tSelected = getSelected() ]
[H, IF(submitAction == "Set 1st"), CODE: {
[H: margs = json.set(margs, "target1ID", if( listCount(tSelected) > 1, listGet(tSelected,0), tSelected )) ]
[MACRO("attackFrame@this"): margs ]
[H, IF( isTokHere == "" ): execLink( macroLinkText("subReturnToMap@" + getMacroLocation(), "none", tcmap), 1); "" ]
[H: abort(0)]
};{}]
[H, IF(submitAction == "Set 2nd"), CODE: {
[H: margs = json.set(margs, "target2ID", if( listCount(tSelected) > 1, listGet(tSelected,0), tSelected )) ]
[MACRO("attackFrame@this"): margs ]
[H, IF( isTokHere == "" ): execLink( macroLinkText("subReturnToMap@" + getMacroLocation(), "none", tcmap), 1); "" ]
[H: abort(0)]
};{}]
[H: system = getLibProperty("System", gLib)]
[H, SWITCH(system), CODE:
case "Pathfinder": {
[ meleeMods = table( "SysVars", json.get( table( "SysVars", 0 ), "meleeModsPF" ) ) ]
[H: tPF= "PF"]
[H: tTable = "PFSpecialATK" ]
[H: sachoices = "None, Disarm, Grapple, Sunder, Trip"]
};
case "D&D3.5": {
[ meleeMods = table( "SysVars", json.get( table( "SysVars", 0 ), "meleeModsSRD" ) ) ]
[H: tPF= "PF"]
[H: tTable = "SRDSpecialATK" ]
[H: sachoices = "None, Disarm, Grapple, Sunder, Trip"]
};
default: {
}
]
[H: tPF = if( "Pathfinder" == getPropertyType(tToken), "PF", tPF)]
[H,TOKEN(tToken): aTMS = json.get( PrivateJSON, "ActiveTempModSets" ) ]
[H, IF( json.type( aTMS ) == "UNKNOWN" ), CODE: {
[TOKEN(tToken): PrivateJSON = json.set( PrivateJSON, "ActiveTempModSets", "[]" ) ]
[ aTMS = "[]" ]
};{}]
[H,TOKEN(tToken): jPTM = json.get( PrivateJSON, "CustomModSetValues" ) ]
[H: jMMFields = json.sort( json.fields( meleeMods, "json" ) ) ]
[H: hasChanged = 0 ]
[H,FOREACH( m, jMMFields, "" ), CODE: {
[H: changed = 0 ]
[H: disable = 1 ]
[H: active = if( json.contains( aTMS, m ), 1, 0 ) ]
[H: jMM = json.get( meleeMods, m ) ]
[H: presetVars = "" ]
[H: tjfjMM = json.fields( jMM, "json")]
[H, FOREACH( n, tjfjMM ), CODE: {
[ isJObj = if( json.type( jMM ) == "OBJECT", 1, 0 ) ]
[IF( isJObj && active ): v = json.get( json.get( json.get( json.get( jPTM, m ), "mods" ), "globalMod" ), "v" ); v = 0 ]
[IF( isJObj ): tmv = eval( "" + json.get( margs,json.get( jMM, n ) ) ); tmv = json.get(margs, m) ]
[IF( isJObj ): ""; tmv = if(tmv == "", 0, tmv) ]
[IF( isJObj ): disable = if( tmv != 0, 0, disable ); disable = 1 ]
[IF( isJObj ): changed = if( v != tmv, 1, changed ); changed = if( active != tmv, 1, changed ) ]
[IF( changed && isJObj ): presetVars = json.set( presetVars, json.get( jMM, n ), tmv ); "" ]
}]
[IF( changed && active ), CODE: {
[MACRO( "subModToggle@this" ): json.set( "{}", "tokenID", tToken, "setID", m, "setType", 0 ) ]
[ broadcast(macro.return)]
};{}]
[IF( changed && ( !disable || !active ) ), CODE: {
[MACRO( "subModToggle@this" ): json.set( "{}", "tokenID", tToken, "setID", m, "setType", 0, "presetVars", presetVars ) ]
[ broadcast(macro.return)]
};{}]
[ hasChanged = if( hasChanged || changed, 1, 0 ) ]
}]
[IF(submitAction == "ATTACK"), CODE: {
[H: ttempATK = json.get(margs,"tempATK") ]
[H: ttempDMG = json.get(margs,"tempDMG") ]
[H: tflanking = json.get(margs,"flanking") ]
[H: thigherGround = json.get(margs,"higherGround") ]
[H: tcover = json.get(margs,"cover") ]
[H: tflurryRapid = json.get(margs,"flurryRapid") ]
[H: trangeIncrement = json.get(margs,"rangeIncrement") ]
[H: tpointBlank = json.get(margs,"pointBlank") ]
[H: '<!-- Check point blank -->']
[H: tPointBlankShot = getStrProp(getProperty("Feats", tToken), "PointBlankShot")]
[H: tPointBlankShot = if(tPointBlankShot == "", 0, tPointBlankShot)]
[H, IF( ! json.isEmpty(target1ID) ), CODE: {
[H: tdist = lgm.getDistanceElev(tToken,target1ID)]
[H, IF(tdist <= 30 && tPointBlankShot): tpointBlank = 1; tpointBlank = 0]
[H, IF( am.hasHighGround( tToken, target1ID ) ): thigherGround = 1; thigherGround = 0]
[H: margs = json.set(margs, "pointBlank", tpointBlank, "higherGround", thigherGround)]
};{}]
[H: tfireIntoMelee = json.get(margs,"fireIntoMelee") ]
[H: tmodCritRange = json.get(margs,"modCritRange") ]
[H: tcritConfirm = json.get(margs,"critConfirm") ]
[H: tsneak = json.get(margs,"sneak") ]
[H: tfavEnemy = json.get(margs,"favEnemy") ]
[H: tfullRound = json.get(margs,"fullRound") ]
[H: flagSecret = json.get(margs,"flagSecret") ]
[H: tflagSecret = if( flagSecret == "" || flagSecret ==0, 2, flagSecret)]
[H: tconcealMiss = json.get(margs,"concealMiss") ]
[H: tmanyShot = json.get(margs,"manyShot") ]
[H: tvitalStrike = json.get(margs,"vitalStrike") ]
[H: specialATKChoice = json.get(margs,"specialATKChoice") ]
[H: rollTwice = json.get(margs,"rollTwice") ]
[H: sizeVariant = json.get(margs,"sizeVariant") ]
[H: tpass = json.set("{}", "weapon", "", "id", tToken, "target1Name", tid1name, "target1ID", target1ID, "target2Name", tid2name, "target2ID", target2ID,"fullRound", tfullRound, "flanking", tflanking, "higherGround", thigherGround, "favEnemy", tfavEnemy, "rangeIncrement", trangeIncrement, "pointBlank", tpointBlank, "fireIntoMelee", tfireIntoMelee, "cover", tcover, "sneak", tsneak, "flurryRapid", tflurryRapid, "flagSecret", flagSecret, "tempATK", ttempATK, "tempDMG", ttempDMG, "concealMiss", tconcealMiss, "critConfirm", eval(""+tcritConfirm), "modCritRange", eval(""+tmodCritRange), "manyShot", tmanyShot, "vitalStrike", tvitalStrike, "sizeVariant", sizeVariant, "rollTwice", rollTwice, "numWeapChoice", numWeapChoice )]
[H, FOR(pAi,0,numWeapChoice,1), CODE: {
[H: tweapset = json.get(margs,"weap"+pAi) ]
[H, IF( target1ID != "" && tweapset != "" ): ti = replace(lower(tweapset),"weapon","")]
[H, IF( target1ID != "" && tweapset != "" ): lgm.getWeaponset(ti,tToken);""]
[H, IF( target1ID != "" && tweapset != "" ): trangeIncrement = floor((tdist-0.01)/WpnRangeInc);""]
[H, IF(tweapset != ""): tpass = json.set(tpass, "weapon", tweapset, "rangeIncrement", trangeIncrement ); ""]
[H, IF(tweapset != ""): lgm.LibAttack(tpass);""]
}]
[H: margs = json.set(margs, "rangeIncrement", trangeIncrement, "flagSecret", tflagSecret)]
[H: idxSA = listFind( sachoices, specialATKChoice ) ]
[H: cntAll = table( tTable, 0 )]
[H: ref = ""]
[H: i = 1 ]
[H, WHILE( ref == "" && i <= cntAll ), CODE: {
[H: jType = table( tTable, i )]
[R: cType = json.get( jType, "name" )]
[H, IF(specialATKChoice == cType): ref = ref + json.get( jType, "ref" ); ""]
[H: i = i + 1 ]
}]
[H: out1 = "<b>" + macroLink( specialATKChoice, "dispSATKrules@" + getMacroLocation(), "none", json.set( "", "name", specialATKChoice, "system", system)) + "</b> (" + ref + ")<br />" ]
[H,IF(flagSecret && (idxSA != 0)),CODE:{
[H: broadcast(out1,json.merge(lgm.getAllGMs(),getOwners("json",tToken))) ]
};{}]
[H,IF(!flagSecret && (idxSA != 0)),CODE:{
[H: broadcast(out1) ]
};{}]
[H,SWITCH(idxSA), CODE:
case 0: { };
case 1: { [MACRO("subDisarm"+tPF+"@this"): json.set("","id",tToken)] };
case 2: { [MACRO("subGrapple"+tPF+"@this"): json.set("","id",tToken)] };
case 3: { [MACRO("subSunder"+tPF+"@this"): json.set("","id",tToken)] };
case 4: { [MACRO("subTrip"+tPF+"@this"): json.set("","id",tToken)] };
default: {}
]
};{ [H: broadcast("<pre>"+json.indent(margs)+"</pre>")] }]
[H,MACRO("attackFrame@this"): margs ]
[H: tName = getName(tToken)]
[H, IF( isFrameVisible( tName ) && hasChanged ), CODE:
{
[H: link = macroLinkText( "CharSheet@"+getMacroLocation(), "self", "Page=Main ; Token=" + tToken ) ]
[H: execLink( link, 1 ) ]
};{}
]
[H, IF( isTokHere == "" ): execLink( macroLinkText("subReturnToMap@" + getMacroLocation(), "none", tcmap), 1); "" ]
!!
Code: Select all
@@ @tokenImageLink
@PROPS@ fontColor=silver ; autoExecute=true ; fontSize=11pt ; sortBy= ; color=purple ; playerEditable=false ; applyToSelected=false ; group=Utility ; tooltip= ; minWidth=94 ;
[H: '<!-- 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, IF(argCount() == 2): targetId = arg(1); targetId = ""]
[H: current = currentToken()]
[H,IF(tokenId == current): ""; switchToken(tokenId)]
[H: t.image = getImage(tokenId,0)]
[H: isCreature = if( getPropertyType(tokenId) == "Pathfinder" || getPropertyType(tokenId) == "DnD35", 1, 0 ) ]
[H, if(isCreature ), code: {
[H: t.ac = getProperty("AC",tokenId)]
[H: t.tactical = getProperty("sheet.moveReach",tokenId)]
[H,IF(targetId != ""): t.distance = lgm.getDistanceElev(tokenId,targetId); t.distance = distanceStatSheet(tokenId)]
<!-- Calc health without revealing hit points -->
[H: effectiveHP = getProperty("HP",tokenId) + getProperty("HPtemp",tokenId) - getProperty("HPNonLethalDMG",tokenId)]
[H: effectiveMaxHP = getProperty("HPmax",tokenId) + getProperty("HPtemp",tokenId)]
[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: 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(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()]
<!-- custom request to remove tooltip info -->
[H: tooltip = ""]
[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,IF(tokenId == current): ""; switchToken(current)]
[H: macro.return = imageLink]
!!
Thx alot !aliasmask wrote:In our games, the players have some clue on the defenses and movement of creature which is why I wrote that little bit. This is also seen on the tokens when mousing over it. This is a function called tokenImageLink. I added a line that will not show a tooltip anymore:
Just follow the directions from the last time to apply the change.