Display an input box under certain circumstances

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
xavram
Dragon
Posts: 891
Joined: Tue Apr 20, 2010 8:22 pm

Display an input box under certain circumstances

Post by xavram »

Is this possible? When a token that has a certain state assigned to it gets initiative, I want an input box to pop up for the player who owns that token. Is this even possible?

Situation : In Pathfinder, there's a spell called Blessing of Fervor that gives the character the ability to choose from one of 5 abilities at the start of their turn. When their turn comes around again, they can select a new ability. I wanted to see if I can simulate this in the UI in Maptool.

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

Re: Display an input box under certain circumstances

Post by aliasmask »

You need something to track the event of "beginning of turn". This can be done with another event that tracks and checks the built in initiative order or some user created macros that manually changes the turn like a NEXT button.

xavram
Dragon
Posts: 891
Joined: Tue Apr 20, 2010 8:22 pm

Re: Display an input box under certain circumstances

Post by xavram »

well, I've got that already and it does a bunch of things when it "becomes" someone's turn.

But I can't figure out how to pop up an input box for JUST the player who's turn its become (assuming he has this state set on him, but that's the easy part). If I just make the input box appear as part of the "Next Turn" macro, then EVERYONE will get the input box, not just the player who owns the token whose turn it is.

See what I mean?

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

Re: Display an input box under certain circumstances

Post by aliasmask »

You need to broadcast() a macroLink to only that one player if not the current player. The macroLink macro needs to have autoexecute checked.

So, for example:

Code: Select all

[H: tokenOwner = getOwners("json",tokenId)]
[H, if(json.isEmpty(tokenOwner)): tokenOwner = json.get(getInfo("server"),"gm")]
[H: tokenOwner = json.get(tokenOwner,0)] <!-- only 1 owner -->
[H: linkText = macroLinkText(macroName,"none",args,tokenId)]
[H: outputLink = strformat('Get user input<a src="%{linkText}"></a>.')]
[H, if(tokenOwner == getPlayerName()): execLink(linkText); broadcast(outputLink,tokenOwner)] 
This is untested and only works for b91 and later. Obviously, some variables will need to have values set by you before it will work, like tokenId, args...

edit: I updated function call to correct one.

xavram
Dragon
Posts: 891
Joined: Tue Apr 20, 2010 8:22 pm

Re: Display an input box under certain circumstances

Post by xavram »

Thanks, I will play around with this sample and see if I can get it to work!! Appreciate the help!

xavram
Dragon
Posts: 891
Joined: Tue Apr 20, 2010 8:22 pm

Re: Display an input box under certain circumstances

Post by xavram »

in the last line of your sample code, you use "currentPlayer()". Is that some custom function? I don't see it in the list of commands on the wiki and it throws back an error if I try just calling it by itself.

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

Re: Display an input box under certain circumstances

Post by aliasmask »

xavram wrote:in the last line of your sample code, you use "currentPlayer()". Is that some custom function? I don't see it in the list of commands on the wiki and it throws back an error if I try just calling it by itself.
Sorry, brain-fart. I mixed currentToken and getPlayerName. Should be the 2nd one. OP updated.

xavram
Dragon
Posts: 891
Joined: Tue Apr 20, 2010 8:22 pm

Re: Display an input box under certain circumstances

Post by xavram »

okay, hmm, there's the issue.

[H, if(tokenOwner == getPlayerName()): execLink(linkText); broadcast(outputLink,tokenOwner)]

The problem is, this macro runs when a player clicks "Done with turn". A bunch of things happen during this and at the end of it all, it moves the initative to the next token. THEN it checks this state to see if the UI should com up for that player to pick from the options. So getPlayerName() returns the name of the token that fired off the "Done with Turn" macro. I need to get back the player name of the owner of the CURRENT token and tell THAT player to display the UI. Does that make sense?

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

Re: Display an input box under certain circumstances

Post by aliasmask »

Yes, it makes sense, but it is not necessary. As long as you use the right values, it doesn't matter who runs the macro. The player check is just there to see if you need to use execLink or post a link via broadcast to the correct player.

xavram
Dragon
Posts: 891
Joined: Tue Apr 20, 2010 8:22 pm

Re: Display an input box under certain circumstances

Post by xavram »

"post a link to via broadcast tot he correct player"

Maybe that's the part I'm not getting. What I wanted was for THIS macro to be run automatically, for the correct player

Code: Select all

[h:status=input("bofOptions|+2 to Attack/Dodge/Reflex, +30 to Speed, Stand as a Swift without AoO, Cast 2nd or lower with Enlarged/Extended/Silent/Still, Gain extra attack on full attack|Blessing of Fervor options|RADIO")]
[h:abort(status)]
...but maybe that's not possible? Is the best that can be done is to have a link for them to click display in the chat box? Using your code, I am seeing this displayed in the chat box for the right player...

Get user input

...but its just text, not a clickable link. Here's the code that I got from you, slightly modified. Have I messed something up when putting that link together?

Code: Select all

[h, if(getState("BlessingofFervor")), code : {
  [h: tokenOwner = getOwners("json",initToken)]
  [h: tokenOwner = json.get(tokenOwner,0)] <!-- only 1 owner -->
  [h: linkText = macroLinkText("DisplayBoFOptions@Lib:PC_CombatMacros",'all','', initToken)]
  [h: outputLink = strformat('Get user input<a src="%{linkText}"></a>.')]
  [h, if(tokenOwner == getPlayerName()): execLink(linkText); broadcast(outputLink,tokenOwner)] 
};{}]

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

Re: Display an input box under certain circumstances

Post by aliasmask »

It would help if you post all the code including the code that handles the initiative so I can see your process and suggest a good spot to make the check.

Generally speaking, if you have a NEXT macro, the current player will hardly ever be the owner of the next token unless you're the gm. You'll need to get the id of the next token and not use the current one for the player who clicked NEXT.

The example I gave doesn't have a clickable link so you must check the autoexecute checkbox on the DisplayBoFOptions macro. So, when the link is posted to the player it will run.

xavram
Dragon
Posts: 891
Joined: Tue Apr 20, 2010 8:22 pm

Re: Display an input box under certain circumstances

Post by xavram »

Heh, really didn't want to post the "DoneWithTurn" macro, but if you insist....the part you've been helping me is at the very end

Code: Select all

[h : switchToken(getInitiativeToken())]

[h : setLight("Auras", "Positive", 0)]
[h : setLight("Auras", "Negative", 0)]
[r, if(BardUsed >= Bard && getState("Performing")), code : {
[r : "doesn't have any more rounds of bardic performance!"]
[h : setState("Performing",0)]
[h : VirtPerform = 0]
};{}]

[h,  if(getState("Performing") && PerformedThisRound == 0), code : {
 [h : BardUsed = BardUsed +1+VirtPerform]
 [h : PerformedThisRound =1]
}]

[h: oldInit = eval(string(macro.args))]

[h : initRound = getInitiativeRound()]
[r, switch(initRound), Code :
case -1: {
	[h : setInitiativeRound(1) ]
	[h: setCurrentInitiative(0)]	
    };
default: {
	[h: nextInitiative()]
    };
]

[h : initToken = getInitiativeToken()]
[h : switchToken(initToken)]

[h :setState("Charging",0,initToken)]
[h: setState("SwiftImmediate",0,initToken)]
[r, if(getState("Reckless_Aim")) : broadcast("<b>" + getName() + "'s AC penalty for Reckless Aim fades</b>")] 
[h :setState("Reckless_Aim",0,initToken)]
[r, if(getState("Defensive_Flurry")) : broadcast("<b>" + getName() + "'s defensive flurry fades</b>")] 
[h :setState("Defensive_Flurry",0,initToken)]
[h: setProperty("LastMoveWas", 0, initToken)]
[h: setProperty("FortuneUsed", 0, initToken)]

[MACRO("ModifyBuffs_Step1@Lib:PC_CombatMacros"):oldInit]

[h : performRegen = 0]
[h, if(getProperty("FastHealing") > 0 && !getState("Dead")) : performRegen =1]
[h, if(getProperty("Regeneration") > 0) : performRegen =1]
[h, if(performRegen == 1 && CurrHP != MaxHp), code : {
  [h : setState("Bleed",0)]
  [h : setProperty("BleedDamage",0)]
  [h : amountToHeal = getProperty("FastHealing") + getProperty("Regeneration")]
  [h:changeHP=
    json.set(
    "",
    "CHPB", 	0-amountToHeal,
    "DR",	0,
    "NL", 	0,
    "TID",        getInitiativeToken()
    )]
   [MACRO("Change HP@Lib:PC_CombatMacros"):changeHP]

  [broadcast("<b>Some of " + getName() + "s wounds knit and heal closed!</b>")]
};{}]

[h, if (getState("Bleed")), code : {
[h : bleedDamageToTake = eval(string(getProperty("BleedDamage")))]
[h : bleedText = "<b>" + getName() + " is bleeding and takes " + bleedDamageToTake + " points of damage"] 

  [h:changeHP=
    json.set(
    "",
    "CHPB", 	bleedDamageToTake,
    "DR",	0,
    "NL", 	0,
    "TID",        getInitiativeToken()
    )]
   [MACRO("Change HP@Lib:PC_CombatMacros"):changeHP]
[h , if(getState("Staggered")) : bleedText = bleedText + " and is Staggered!!!"]
[h , if(getState("Unconscious")) : bleedText = bleedText + " and is Unconscious!!!"]
[h , if(getState("Dying")) : bleedText = bleedText +  " and is DYING!!!"]
[h , if(getState("Dead")) : bleedText = bleedText +  " and DIES!!!"]
[broadcast(bleedText)]
};{}]

[h, if (getState("Dying") && !performRegen), code : {
  [h : conCheck = 1d20+CurrHP+ConBonus]
  [h, if (conCheck >=10), code : {
   [broadcast("<b>" + getName() + " stabilizies and is no longer dying!</b>")]
   [h : setState("Dying",0)]
   [h : setState("Unconscious",1)]
  };
  {
   [h: stabilizeText = "<b>" + getName() + " fails to stabilize and takes 1 pt of damage")]
   [h:CurrHp = CurrHp-1]
   [h,if(CurrHp<DeathVal+1):setState("Dead",1);setState("Dead",0)]
   [h,if(CurrHp<0&&CurrHp>DeathVal):setState("Dying",1);setState("Dying",0)]
   [h,if(CurrHp==0):setState("Disabled",1);setState("Disabled",0)]
   [h,if(CurrHP<0):setState("Prone",1)]
   [h, if(getState("Dead")) : stabilizeText = stabilizeText + " and DIES!!!"]
   [broadcast(stabilizeText + "!</b>")]
  }]
};{}]

[h, if(indexOf(Specials, "Ferocity") >= 0), code : {
[h, if(CurrHP<0 && !getState("Dead")), code : {
  [h: ferocityText = "<b>" + getName() + "s ferocious nature keeps him/her alive but takes 1 pt of damage")]
   [h:CurrHp = CurrHp-1]
   [h,if(CurrHp<DeathVal+1):setState("Dead",1);setState("Dead",0)]
   [h, if(getState("Dead")) : ferocityText = ferocityText + " and DIES!!!"]
   [broadcast(ferocityText + "!</b>")]
};{}]
};{}]

[h : confusionRoll = d100]
[h : confusionStr = " but may act normally this round!"]
[h : confusionDmg = Max(1d8+StrBonus,0)]
[h, if(confusionRoll >26 && confusionRoll <=50) : confusionStr = " and does nothing but babble incoherently!"]
[h, if(confusionRoll >51 && confusionRoll <= 75) : confusionStr = " and smashes himself in the face, doing " + confusionDmg + " damage! (Need to manually put in damage)"]
[h, if(confusionRoll >75) : confusionStr = " and attacks the nearest target!"]

[r, if(!getState("Dead")), code : {
[r, if(getState("BlessingofFervor")) : broadcast("<b>" + getName() + " is under the effect of Blessing of Fervor, choose a benefit for this round! (+30 to speed, stand as a swift w/o AoO, make one extra attack with full attack, +2 to attack/dodge/reflex, or cast 2nd lvl or lower spell with enlarged/extended/silent/still)</b>")]
[r, if(getState("Confused")) : broadcast("<b>" + getName() + " is confused " + confusionStr + "</b>")] 
[r, if(getState("Cowering")) : broadcast("<b>" + getName() + " is cowering in fear and cannot act!!!</b>")] 
[r, if(getState("Dazed")) : broadcast("<b>" + getName() + " is dazed and cannot take any actions</b>")] 
[r, if(getState("Exhausted")) : broadcast("<b>" + getName() + " is exhausted so can only move at half speed, cannot run or charge, and takes a -6 on Str and Dex (to hit/damage penalty/CMB/CMD/AC is already calculated, Skills must be done manually)</b>")]
[r, if(getState("Entangled")) : broadcast("<b>" + getName() + " is entangled and moves at half speed, cannot run or charge, takes a -2 penalty on attack rolls and a -4 penalty on Dexterity!  Spells cast require a DC 15 + Spell level Concentration check or spell is lost!</b>")]
[r, if(getState("Fatigued")) : broadcast("<b>" + getName() + " is fatigued so cannot run or charge and takes a -2 on Str and Dex (to hit/damage penalty/CMB/CMD/AC is already calculated, Skills must be done manually)</b>")]
[r, if(getState("Frightened")) : broadcast("<b>" + getName() + " is frightened and must try to flee from the source of its fear.  It can fight if fleeing is impossible.</b>")] 
[r, if(getState("Grappled")) : broadcast("<b>" + getName() + " is grappling, so takes a 4 penalty to Dex, -2 to hit and combat manuever checks (except to escape/maintain grapple), and cannot take actions that require 2 hands.  If you are the grappler, add 5 to maintain the grapple.</b>")] 
[r, if(getState("Nauseated")) : broadcast("<b>" + getName() + " is nauseated and can only take a single move action</b>")] 
[r, if(getState("Panicked")) : broadcast("<b>" + getName() + " is panicked so must drop anything it holds and flee at top speed from the source of its fear, as well as any other dangers it encounters, along a random path. It can't take any other actions.</b>")] 
[r, if(getState("Paralyzed")) : broadcast("<b>" + getName() + " is paralyzed so cannot move or take actions.  He has effective Dex and Strength of zero and is considered helpless (attackers get +4 to hit)</b>")] 
[r, if(getState("Slowed")) : broadcast("<b>" + getName() + " is slowed so can only take a single move OR standard action, not both  Speed is reduced by half!</b>")] 
[r, if(getState("Staggered")) : broadcast("<b>" + getName() + " is staggered so can only take a single move OR standard action, not both</b>")] 
[r, if(getState("Stunned")) : broadcast("<b>" + getName() + " is stunned and drops everything held, can't take actions, and loses its Dexterity bonus to AC</b>")] 

[h, if (getProperty("Poisoned")>0), code : {
[h : poisonRounds = getProperty("Poisoned")]
[h : setProperty("Poisoned", poisonRounds-1)]
[broadcast("<b>" + getName() + " still is poisoned and must make another save!</b>")]
[h, if(getProperty("Poisoned") == 0) : broadcast("<b>The poison fades away after this final save!</b>")]
};{}]

[h, if (getProperty("Reminder") != "0"), code : {
[broadcast(strformat('<font color="red"><b>' + getName() + ' - ' + getProperty("Reminder") + '</b></font>'), "gm")]
};{}]

};{}]

[h : selectTokens(initToken)]
[h : switchToken(initToken)]
[h, if(getState("Dying") || getState("Dead") || getState("Unconscious")), code : {
  [h : currentInit = getInitiative()]
  [MACRO("DoneWithTurn@Lib:PC_CombatMacros"):currentInit]
};
{
[h: setHalo("Yellow", initToken)]
}]

[h, if(getState("Dying") || getState("Dead") || getState("Unconscious")), code : {
[h : sendToBack(initToken)]
};
{
[h : bringToFront(initToken)]
}]

[h, if(getCurrentInitiative() ==0), code : {
  [h: ids = getExposedTokens()]
  [h, foreach(id, ids, ""), code : {
    [h : setProperty("PerformedThisRound", 0, id)]
    [h : setProperty("FortuneUsed", 0, id)]
}]
}]

[h, if(getState("BlessingofFervor")), code : {
  [h: tokenOwner = getOwners("json",initToken)]
  [h: tokenOwner = json.get(tokenOwner,0)] <!-- only 1 owner -->
  [h: linkText = macroLinkText("DisplayBoFOptions@Lib:PC_CombatMacros",'all','', initToken)]
  [h: outputLink = strformat('Get user input<a src="%{linkText}"></a>.')]
  [broadcast(outputLink,tokenOwner)] 
};{}]

xavram
Dragon
Posts: 891
Joined: Tue Apr 20, 2010 8:22 pm

Re: Display an input box under certain circumstances

Post by xavram »

With a slight tweak of the code, I got this working EXACTLY how I wanted! Using macroLink instead...

Code: Select all

[h, if(getState("BlessingofFervor")), code : {
  [h: tokenOwner = getOwners("json",initToken)]
  [h: tokenOwner = json.get(tokenOwner,0)] <!-- only 1 owner -->
  [h: linkText = macroLink("Click for BOF options", "DisplayBoFOptions@Lib:PC_CombatMacros",tokenOwner,'', initToken)]
  [broadcast(linkText,tokenOwner)] 
};{}]
My one nagging issue is that I don't want the "Click for BOF options" to display in the chat window. In the writeup for macrolink, it says...

To auto-execute in the chat window, it must not be hidden by roll options like [h:], but may be hidden by being contained within an HTML comment.

...can someone tell me how to "hide it within an html comment"? If I can get that piece, then things will be golden!

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

Re: Display an input box under certain circumstances

Post by aliasmask »

For the link to work you have to show something even if it blank. You can use "" for the link text. You'll get a blank post after that.

xavram
Dragon
Posts: 891
Joined: Tue Apr 20, 2010 8:22 pm

Re: Display an input box under certain circumstances

Post by xavram »

awesome sauce...that's perfect!

Post Reply

Return to “Macros”