Can someone edit a hitpoint macro for me please?

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
User avatar
Oryan77
Dragon
Posts: 452
Joined: Sun Feb 20, 2011 3:14 pm

Can someone edit a hitpoint macro for me please?

Post by Oryan77 »

I currently have a feature in place that causes a state to appear over a token when the hitpoints for that token reaches 0 or below (dead) and the token moves to the Object layer. I can't for the life of me figure out how this is working since I implemented it so long ago.

I was hoping to add a similar feature except that when a token's hitpoints get to 50% or lower, a state (state image is called "bloodied") will appear on the token to represent that it is "bloodied" (aka 50% or more HP is lost)? Also, if the token is healed back up for more than 50% of the HP, the blooded state is removed.

Could someone with coding experience please help me out in getting something like this implemented?

The code the I use for hitpoints in my Campaign Properties (Token Properties) to manage a token type (Basic) property is:

Code: Select all

*#HPmax (Max HP):0
*#HP (Current HP):0
*#HPtemp (Temp HP):0
*#HPNonLethalDMG (Non Lethal Dmg):0
I am also using a macro that allows me to adjust hitpoints on a token. I forget where I got this macro, but here is the code:

Code: Select all

[H: ids = getSelected()]
[H: abort(if(ids == "", 0, 1))]

[H: TokenList = getSelected()]
[H: numTList = listCount(tokenList)]
[H: abort(numTList)]

[H: cancel = input(
   "HPt|0|# Hit Points| TEXT | WIDTH=4",
   "HPtype|Healing, Damage, Non-Lethal Damage, Non-Lethal Recovery|Change Type|RADIO|SELECT=1"
)]
[H: abort(cancel)]
[H: HPt = eval( "" + HPt ) ]

[C(numTList,""), CODE:  {

  [H: tToken = listGet(tokenList,roll.count)]
  [H: switchToken(tToken)]

  [R: IF( roll.count > 0, "</td></tr>", "<table>" ) + "<tr><td>" ]
  [R: "<b><i>" + getName(tToken) + "</i></b>:  </td><td>" ]
  [MACRO("HPChange@Lib:libDnD35Pathfinder"): "Page=Main; doinput=0; HPAmount=" + HPt + "; HPtype=" + HPtype + "; Token=" + tToken ]

}]

[R: "</td></tr></table>" ]
[H: abort(0)]

I hope someone can help me with this. I also hope this is all the info you would need. :oops:


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

Re: Can someone edit a hitpoint macro for me please?

Post by Oryan77 »

Does this help?

Code: Select all

[H: page = getStrProp( macro.args, "Page" ) ]
[H, IF( page == "" ): page = "Main" ]
[H: doinput = getStrProp( macro.args, "DoInput" ) ]
[H, IF( doinput == "" ): doinput = 1 ]
[H: HPt = getStrProp( macro.args, "HPAmount" ) ]
[H, IF( HPt == "" ): HPt = 0 ]
[H: HPtype = getStrProp( macro.args, "HPtype" ) ]
[H, IF( HPtype == "" ): HPtype = 1 ]

[H: tToken = getStrProp(macro.args, "Token")]
[H, IF( tToken == "" ): tToken = currentToken(); switchToken( tToken ) ]
[H: tokenType =  if( isPC(), 0, 1 ) ]

[H, IF( doinput ), CODE: {
  [H: cancel = input(
    "HPt|0|# Hit Points| TEXT | WIDTH=4",
    "HPtype|Healing, Damage, Non-Lethal Damage, Non-Lethal Recovery|Change Type|RADIO|SELECT=1",
    "tokenType|PC, NPC|Token Type|RADIO|ORIENT=H SELECT=" +  if(isPC(), 0, 1),
    "junk|NPC=Limited chat info & coarse HP bar|NOTE:|LABEL"
  )]
  [H: abort(cancel)]
}]

<!-- Damage Reduction / Energy Resistance check -->
[H: reduceDMG = 0 ]
[H, IF( DR != "" && HPtype == 1 ), CODE: {
   [ cancel = input(
      "junk|Damage Reduction / Energy Resistance exists!|drerx|LABEL|SPAN=TRUE",
      "junk|" + HPt + "|Damage Taken|LABEL",
      "reduceDMG|0|Damage absorbed by DR/ER|TEXT|WIDTH=4",
      "junk|DR/ER: " + DR + "|DR/ER|LABEL|SPAN=TRUE",
      "junk|Enter negative number to INCREASE damage for things like Vulnerability|Vulnerability|LABEL|SPAN=TRUE"      
   )]
  [H: abort(cancel)]
}]
[H: reduceDMG = reduceDMG ]

[H: tDieHard = getStrProp(Feats, "DieHard")]
[H: tDieHard = if(tDieHard == "", 0, tDieHard)]

[H: tokenType = if(tokenType == 1, "NPC", "PC")]
[H: damage = if((HPtype == 1), 1, 0)]

<!-- If Healing or Hourly regen, then reduce NLD. If Damage, then NLD does not change. -->
[H: HPNonLethalDMG = if((HPtype == 0) || (HPtype == 3), max(0, HPNonLethalDMG - abs(HPt)), HPNonLethalDMG)]
[H: HPNonLethalDMG = if(HPtype == 2, abs(HPt) + HPNonLethalDMG, HPNonLethalDMG)]

[H: dispHP = if( HPtype == 0 || HPtype == 3, abs(HPt), -1 * abs(HPt) )]
<!-- If Healing, then HPt positive.  If Damage then HPt negative.  If NLD then HPt = 0. -->
[H: HPt = if(HPtype == 0, abs(HPt), if(HPtype == 1, min( 0, ( -1 * abs(HPt) ) + reduceDMG ), 0))]

<!-- Process Healing/Damage (and do not forget those temporary hitpoints) -->
[H: HPtemp = HPtemp + damage*HPt]
[H: HPChange = if((HPt < 0), if(HPtemp > 0, 0, HPtemp ), HPt)]
[H: HP = min(HP + HPChange, HPmax)]
[H: HPtemp = max(0,HPtemp)]

<!-- Output details if a PC, just output the basic info if a NPC. -->
[H: output = "<b>" + if(HPt < 1, "", "Gained ") + if(tokenType == "PC", HPChange, dispHP) + " hitpoints!</b>" ]
[H: output = output + if(tokenType == "PC", "  " + HP + " of " + HPmax + "+" + HPtemp + " hitpoints remain...", "")]
[H: output = output + if( (tokenType == "PC") && (HPNonLethalDMG > 0), "<br> " + HPNonLethalDMG + " points of non-lethal damage.", "")]

[H: state.Unconscious = if( ( ( (HP + HPtemp) < 0 ) || ( HPNonLethalDMG > (HP + HPtemp) ) ) && !tDieHard, 1, if((HPChange > 0) && ((HP + HPtemp) >= 0) && ((HP + HPtemp) >= HPNonLethalDMG), 0, state.Unconscious))]
[H: state.StableHP = if( ( (HPChange > 0) && ((HP + HPtemp) < 0) ) || tDieHard, 1, state.StableHP)]
[H: state.StableHP = if( (HP + HPtemp) >= 0, 0, if( ( (damage * HPt) < 0 ) && !tDieHard, 0, state.StableHP) )]

[H, MACRO("subUpdateHPStatesBars@"+getMacroLocation()): "Token=" + tToken]

[R: output ]

[H, IF( isFrameVisible( token.name ) ), CODE:
  {
    [H: callback = "CharSheet@"+getMacroLocation()]
    [H: link = macroLinkText( callback, "self", "Page="+page + " ; Token=" + tToken ) ]
    [H: execLink( link, 1 ) ]
  };
  {
  }
]

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

Re: Can someone edit a hitpoint macro for me please?

Post by aliasmask »

Actually, I think there is a separate state setting macro. The code you want would look something like this:

Code: Select all

[H: isBloodied = if(floor((HPmax+HPtemp)/2)<= HP,1,0)]
[H: setState("Bloodied",isBloodied)]
NLD shouldn't effect the bloodied state since it's not real damage.

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

Re: Can someone edit a hitpoint macro for me please?

Post by Oryan77 »

Oh is it the subUpdateHPStatesBarsAliasmask macro?

Code: Select all

[H: gTok = "Lib:GlobalsSRDPF"]
[H: tToken = getStrProp(macro.args, "Token")]

[H: gTokenUncImgChange = getLibProperty("TokenUncImgChange", gTok)]

[H: switchToken(tToken)]

[H, IF(gTokenUncImgChange), CODE: {
    [ tImageID = getTokenImage() ]
    [ tImageHID = getTokenHandout() ]
    [IF( tImageHID != tImageID ): Private = setStrProp(Private, "TokenImageAssetID", tImageID) ]
    [ tIAID = getStrProp(Private, "TokenImageAssetID")]
};{}]

[H: deathpoint = eval( string( getLibProperty( "DeathPoint", gTok ) ) )]

[H: tType = json.get( Race, "type" )]
[H: tSubtype = json.get( Race, "subtype" )]
[H: variantRDP = table( "SysVars", json.get( table( "SysVars", 0 ), "variantRaceDeathPoint" ) ) ]
[H, FOREACH( dp, variantRDP ), CODE: {
   [H: tDP = json.get( dp, "deathPoint" )]
   [H: typeArray = json.get( dp, "typeArray" )]
   [H: subtypeArray = json.get( dp, "subtypeArray" )]
   [H, FOREACH( t, typeArray ): deathpoint = if( t == tType, tDP, deathpoint )]
   [H, FOREACH( t, subtypeArray ): deathpoint = if( json.contains( tSubtype, t ), tDP, deathpoint )]
}]

[H: tDieHard = getStrProp(Feats, "DieHard")]
[H: tDieHard = if(tDieHard == "", 0, tDieHard)]
[H: disabledPoint = if( tDieHard, deathpoint, 0)]
[H: effectiveHP = HP + HPTemp]
[H: tMaxEffectiveHP = HPmax + HPtemp]

[H: state.Disabled = if((effectiveHP) == 0, 1, 0)]
[H: state.Staggered = if(HPNonLethalDMG == (effectiveHP) && HP > 0, 1, 0)]

[H: active = if( ((effectiveHP) >= HPNonLethalDMG) && ((effectiveHP) >= 0), 1, if( tDieHard, 1, 0) )]

[H: state.Unconscious = if( ( ( (effectiveHP) < 0 ) || ( HPNonLethalDMG > (effectiveHP) ) ) && !tDieHard, 1, state.Unconscious)]

[H: state.Prone = if( active && (state.Prone < 1), 0, 1)]
[H: state.Dying = if(((effectiveHP) > deathpoint) && ((effectiveHP) < 0), 1, 0)]
[H, IF( isNPC() && !tDieHard ): eval(if(state.Dying, 'setLayer("object")', '0'))]
[H: state.StableHP = if(((effectiveHP) >= 0), 0, state.StableHP)]
[H, if(state.StableHP): state.Dying = 0]

[H: state.Dead = if((effectiveHP) <= deathpoint, 1, 0)]
[H, IF(state.Dead), CODE: {
  [H: if(isNPC(), setLayer("object"), '0')]
  [H: state.Dying = 0]
  [H: state.Unconscious = 0]
  [H: state.Prone = 0]
  [H: state.StableHP = 0]
};{}]

[H, if(effectiveHP - HPNonLethalDMG > 0), code: {
   [H: state.Dying = 0]
   [H: state.Unconscious = 0]
   [H: state.StableHP = 0]
}; {}]

[H: eval(if(state.Dead, 'removeFromInitiative()', '0'))]

[H, IF( active ): setLayer("token")]

[H: setBarVisible("HP",0)]
[H: setBarVisible("HPM",0)]
[H: setBarVisible("HPNonLethalDMG",0)]
[H: setBarVisible("HPMNonLethalDMG",0)]

[H, if( state.Dead ), code: {
   [H: setBarVisible("HPdamage",0)]
   [H: setBarVisible("EmptyHP",0)]
}; {
   [H, if( effectiveHP >= 0 ), code: {
      [H: bar.HPdamage = (tMaxEffectiveHP - effectiveHP) / tMaxEffectiveHP]
      [H: setBarVisible("EmptyHP",0)]
   }; {
      [H: bar.HPdamage = max(0,(deathPoint - effectiveHP) / deathPoint) ]
      [H: bar.EmptyHP = 1]
   }]   
}]
[H, if( effectiveHP < 0 || state.Dead), code: {
   [H: setBarVisible("NLD_HP",0) ]
   [H: setBarVisible("TempHP",0) ]
}; {
   [H: bar.TempHP = bar.HPdamage + (HPtemp / tMaxEffectiveHP) ]
   [H: bar.NLD_HP = HPNonLethalDMG / tMaxEffectiveHP ]
}]

[H, if(HP == HPmax && effectiveHP == HP && HPNonLethalDMG == 0), code: {
   [H: "<!-- Turn off all the bars when at max HP with no HP mods -->"]
   [H: setBarVisible("TempHP",0)]
   [H: setBarVisible("HPdamage",0)]
   [H: setBarVisible("NLD_HP",0)]
}; {}]

[H, IF(gTokenUncImgChange), CODE: {
    [H: tImageID= if( ( state.Dead || state.Unconscious ), getTokenHandout(), tIAID ) ]
    [H, IF(tImageID != ""): setTokenImage(tImageID)]
};{}]

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

Re: Can someone edit a hitpoint macro for me please?

Post by aliasmask »

I believe there are two macros. If you're using the fading arc hp meter, then this will work. I got my logic backwards on the above and I adjusted for the variables in the macro including turning off the state when creature is dead.

Code: Select all

[H: gTok = "Lib:GlobalsSRDPF"]
[H: tToken = getStrProp(macro.args, "Token")]

[H: gTokenUncImgChange = getLibProperty("TokenUncImgChange", gTok)]

[H: switchToken(tToken)]

[H, IF(gTokenUncImgChange), CODE: {
    [ tImageID = getTokenImage() ]
    [ tImageHID = getTokenHandout() ]
    [IF( tImageHID != tImageID ): Private = setStrProp(Private, "TokenImageAssetID", tImageID) ]
    [ tIAID = getStrProp(Private, "TokenImageAssetID")]
};{}]

[H: deathpoint = eval( string( getLibProperty( "DeathPoint", gTok ) ) )]

[H: tType = json.get( Race, "type" )]
[H: tSubtype = json.get( Race, "subtype" )]
[H: variantRDP = table( "SysVars", json.get( table( "SysVars", 0 ), "variantRaceDeathPoint" ) ) ]
[H, FOREACH( dp, variantRDP ), CODE: {
   [H: tDP = json.get( dp, "deathPoint" )]
   [H: typeArray = json.get( dp, "typeArray" )]
   [H: subtypeArray = json.get( dp, "subtypeArray" )]
   [H, FOREACH( t, typeArray ): deathpoint = if( t == tType, tDP, deathpoint )]
   [H, FOREACH( t, subtypeArray ): deathpoint = if( json.contains( tSubtype, t ), tDP, deathpoint )]
}]

[H: tDieHard = getStrProp(Feats, "DieHard")]
[H: tDieHard = if(tDieHard == "", 0, tDieHard)]
[H: disabledPoint = if( tDieHard, deathpoint, 0)]
[H: effectiveHP = HP + HPTemp]
[H: tMaxEffectiveHP = HPmax + HPtemp]

[H: state.Disabled = if((effectiveHP) == 0, 1, 0)]
[H: state.Staggered = if(HPNonLethalDMG == (effectiveHP) && HP > 0, 1, 0)]

[H: active = if( ((effectiveHP) >= HPNonLethalDMG) && ((effectiveHP) >= 0), 1, if( tDieHard, 1, 0) )]

[H: state.Unconscious = if( ( ( (effectiveHP) < 0 ) || ( HPNonLethalDMG > (effectiveHP) ) ) && !tDieHard, 1, state.Unconscious)]

[H: state.Prone = if( active && (state.Prone < 1), 0, 1)]
[H: state.Dying = if(((effectiveHP) > deathpoint) && ((effectiveHP) < 0), 1, 0)]
[H, IF( isNPC() && !tDieHard ): eval(if(state.Dying, 'setLayer("object")', '0'))]
[H: state.StableHP = if(((effectiveHP) >= 0), 0, state.StableHP)]
[H, if(state.StableHP): state.Dying = 0]

[H: isBloodied = if(floor(tMaxEffectiveHP/2) >= effectiveHP,1,0)]
[H: setState("Bloodied",isBloodied)]

[H: state.Dead = if((effectiveHP) <= deathpoint, 1, 0)]
[H, IF(state.Dead), CODE: {
  [H: if(isNPC(), setLayer("object"), '0')]
  [H: state.Dying = 0]
  [H: state.Unconscious = 0]
  [H: state.Prone = 0]
  [H: state.StableHP = 0]
  [H: state.Bloodied = 0]
};{}]

[H, if(effectiveHP - HPNonLethalDMG > 0), code: {
   [H: state.Dying = 0]
   [H: state.Unconscious = 0]
   [H: state.StableHP = 0]
}; {}]

[H: eval(if(state.Dead, 'removeFromInitiative()', '0'))]

[H, IF( active ): setLayer("token")]

[H: setBarVisible("HP",0)]
[H: setBarVisible("HPM",0)]
[H: setBarVisible("HPNonLethalDMG",0)]
[H: setBarVisible("HPMNonLethalDMG",0)]

[H, if( state.Dead ), code: {
   [H: setBarVisible("HPdamage",0)]
   [H: setBarVisible("EmptyHP",0)]
}; {
   [H, if( effectiveHP >= 0 ), code: {
      [H: bar.HPdamage = (tMaxEffectiveHP - effectiveHP) / tMaxEffectiveHP]
      [H: setBarVisible("EmptyHP",0)]
   }; {
      [H: bar.HPdamage = max(0,(deathPoint - effectiveHP) / deathPoint) ]
      [H: bar.EmptyHP = 1]
   }]   
}]
[H, if( effectiveHP < 0 || state.Dead), code: {
   [H: setBarVisible("NLD_HP",0) ]
   [H: setBarVisible("TempHP",0) ]
}; {
   [H: bar.TempHP = bar.HPdamage + (HPtemp / tMaxEffectiveHP) ]
   [H: bar.NLD_HP = HPNonLethalDMG / tMaxEffectiveHP ]
}]

[H, if(HP == HPmax && effectiveHP == HP && HPNonLethalDMG == 0), code: {
   [H: "<!-- Turn off all the bars when at max HP with no HP mods -->"]
   [H: setBarVisible("TempHP",0)]
   [H: setBarVisible("HPdamage",0)]
   [H: setBarVisible("NLD_HP",0)]
}; {}]

[H, IF(gTokenUncImgChange), CODE: {
    [H: tImageID= if( ( state.Dead || state.Unconscious ), getTokenHandout(), tIAID ) ]
    [H, IF(tImageID != ""): setTokenImage(tImageID)]
};{}]

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

Re: Can someone edit a hitpoint macro for me please?

Post by Oryan77 »

That works perfectly. Thanks!

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

Re: Can someone edit a hitpoint macro for me please?

Post by Oryan77 »

I just realized after testing some more that the "Bloodied" state still appears when the Hitpoints are in the negatives. Is it an easy enough tweak to the code to set it so that if the hitpoints are negative, or maybe if the "Dying" state is on, then the Bloodied state turns off? I see no need for it if there is a Dying state to represent negative hitpoints.

I would however like the Bloodied state to continue showing even when the token has the Disabled state active (0 hitpoints). So no need to adjust for that.

Sorry to be a pain. I was originally testing it with an NPC token which doesn't use negative hitpoints. I noticed this when I just tested on a PC token that went into negative hitpoints.

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

Re: Can someone edit a hitpoint macro for me please?

Post by aliasmask »

Code: Select all

[H: isBloodied = if(floor(tMaxEffectiveHP/2) >= effectiveHP && ! state.Unconscious,1,0)]

User avatar
StarMan
Dragon
Posts: 939
Joined: Mon Jul 18, 2011 1:10 pm
Location: Toronto

Re: Can someone edit a hitpoint macro for me please?

Post by StarMan »

My framework (link below) is for 4e but it does all of this if you want to take a look.
StarMan - The MacroPolicebox D&D 4E Framework: Import ANYTHING!

Post Reply

Return to “Macros”