Targeting group members

For builders to discuss and ask building questions.
Post Reply
Amalia
Sword Grand Master
Sword Grand Master
Posts: 331
Joined: Wed Feb 01, 2006 6:51 pm
Location: Ardeep Forest
Contact:

Targeting group members

Post by Amalia » Sun Mar 11, 2007 2:07 pm

Is there a way for a mob to do a check on the group leader but then, instead of actually targeting the group leader (with, say, speech) to target any group member which meets a certain criteria? I was thinking there might be some use of mpechoaround that could do this, but I'd like to actually make the "echo" interactive-- a certain response from the group members in question would set quest bits on them.

For example, Bob is leading a group into a high-class tavern, a place so snooty that his low charisma is going to get him kicked out in short order. The command I'm looking for would target anyone in the group who has a sufficiently high charisma for the tavern, cause the barkeep to say they can stay in good company or be thrown out with their questionable friend, and ask which it will be. The answer determines that PC's status in the bar henceforth.

(this is nothing to do with the actual scenario, but the code should be the same)
Dear Enemy: May the Lord hate you and all your kind, may you be turned orange in hue, and may your head fall off at an awkward moment.
Dalvyn
Sword Grand Master
Sword Grand Master
Posts: 4708
Joined: Tue Jul 15, 2003 9:26 pm
Location: House of Wonder, Waterdeep

Post by Dalvyn » Sun Mar 11, 2007 4:35 pm

Once again, there is no easy solution for that. There might be a workaround though, depending on what you exactly need.

Code: Select all

mpgroupaction $n <something>
This is a new command that does not have a builder help page yet. It actually performs the action <something> on each character in $n's group.

For example, if a mob has the following command in a greet_prog,

Code: Select all

mpgroupaction $n say Hello
mpgroupaction $n mpoload 8000
mpgroupaction $n drop i8000
the mob (a) say Hello once for each member in the group [i.e., the mob will say Hello k times, where k is the number of members in $n's group; (b) load an item i8000 for each member in the group; then (c) drop an i8000 object k times. Each command is performed for each group member first, before switching to the next mpgroupaction command.

Now, the three commands above did not include any interaction with the group members, and there's a reason for that: in the <something> command, the group member is designed by @n. So, for example, the previous example could be improved into:

Code: Select all

mpgroupaction $n sayto @n Hello!
mpgroupaction mpoload 8000
mpgroupaction give i8000 @n
With this code, the mob would (1) say Hello to each group member, then (2) load k items i8000, and finally (3) give one item to each group member.

Mpgroupaction has been used to code special objects that, once triggered cast group spell. For example:

Code: Select all

mpechoat $n {F0}As you ring the tiny bell, ...
mpechoaround $n {F0}As $N rings the tiny bell, ...
mpgroupaction $n mpechoat @n {F0}... your skin turns to stone!
mpgroupaction $n mpechoaround @n {F0}... @N's skin turns to stone!
mpgroupaction $n mpcast 'stone skin' @n
Amalia
Sword Grand Master
Sword Grand Master
Posts: 331
Joined: Wed Feb 01, 2006 6:51 pm
Location: Ardeep Forest
Contact:

Post by Amalia » Sun Mar 11, 2007 4:55 pm

I think I could make this work quite well, with just one more query-- if I put nothing after a quest bit, does it just not show up in the quest log, or will I create a blank line? I could do what I need with this and a two-step invisible mini-quest, I think.
Dear Enemy: May the Lord hate you and all your kind, may you be turned orange in hue, and may your head fall off at an awkward moment.
Dalvyn
Sword Grand Master
Sword Grand Master
Posts: 4708
Joined: Tue Jul 15, 2003 9:26 pm
Location: House of Wonder, Waterdeep

Post by Dalvyn » Sun Mar 11, 2007 5:00 pm

Back to your program now...

If-checks do not work well with mpgroupaction. For example, what a code like

Code: Select all

mpgroupaction $n if cha(@n) > 16
does is a mystery. I would guess it would do something very strange. The main limitation here is that you can only have one line in the <something> of the mpgroupaction, and a complete if-check (with something to do if the condition is satified, and perhaps an else part, and an endif) takes more than one line.

So... the "easiest" way to make each group member run more than one line with a mpgroupaction is to force the group member (@n) to trigger another program. That program could be on the mob or in the room, or on an object... whatever is easier.

As a first example, let's assume that the innkeeper has the following programs.

Code: Select all

>greet_prog 100~
mpgroupaction $n mpforce @n triggerme
~

>intercept_prog triggerme~
if perm_cha($n) > 16
  sayto $n You are very charismatic!
else
  sayto $n Bleh. Sucks to be you.
endif
~
If Alan leads a group containing himself, Betty, and Candice, what will happen?
  1. The group enters the room with the innkeeper.
  2. The greet_prog triggers for Alan (who came in first, as the group leader).
  3. This forces Alan, Betty, and Candice to trigger the innkeeper with "triggerme".
  4. The innkeeper will address Alan, Betty, and Candice in turn and tell them either "You are very charismatic" or "Bleh. Sucks to be you."
  5. Betty trigger the greet_prog and the same thing happens again: the three group members "triggerme" and get told something by the innkeeper.
  6. Candice triggers the greet_prog and the same thing happens again: the three group members "triggerme" and get told something by the innkeeper.
Ok, not really what you wanted, but it's a first start.

Preventing the program to repeat itself three times is relatively easy. You could simply set a quest bit on the group leader. The group leader for $n is denoted by $W. Naturally, you must reset the quest bit to 0 if they leave, if you want the innkeeper to give them his speech again next time they come in. The programs become:

Code: Select all

>greet_prog 100~
if quest(0,1,$W) == 0
  mpmset $W quest 0 1 1
  mpgroupaction $n mpforce @n triggerme
endif
~

>intercept_prog triggerme~
if perm_cha($n) > 16
  sayto $n You are very charismatic!
else
  sayto $n Bleh. Sucks to be you.
endif
~

>leave_prog 100~
mpmset $n quest 0 1 0
~
That's better... Now, the second problem is that the innkeeper talks to everybody, while you might want the innkeeper to look for someone with a high charisma in the group and only address him/her. An idea to do that would be to use a quest bit on the innkeeper, that would indicate whether or not he has already found someone with a high enough charisma in the group he is currently examining. This quest bit would have to be reset to 0 when a new group is to be examined.

The "triggerme" program would need to be changed too:
  • If we have already found someone with a high charisma in the group (i.e., if the innkeeper's quest bit is 1), do not bother checking anymore.
  • Otherwise (that is, if the innkeeper's quest bit is 0), check $n.
    • If $n is highly charismatic, set the innkeeper's bit to 1 and say that $n is charismatic enough and the group is welcome to stay.
    • Otherwise, say nothing and keep the innkeeper's quest bit to 0.
That yields:

Code: Select all

>greet_prog 100~
if quest(0,1,$W) == 0
  mpmset $W quest 0 1 1
  mpmset self quest 0 1 0
  mpgroupaction $n mpforce @n triggerme
endif
~

>intercept_prog triggerme~
if quest(0,1,self) == 0
  if perm_cha($n) > 16
    sayto $n You are very charismatic!
    sayto $n Your group is welcome to stay!
    mpmset self quest 0 1 1
  endif
endif
~

>leave_prog 100~
mpmset $n quest 0 1 0
~
Are we done yet? Not really... we correctly treated the case when there is a highly charismatic member in the group. We still have to treat the other case: what happens if all the group members have insufficient charisma? Let's say that the innkeeper then throws them out of the inn (and that the exit is west).

Whatever happens should take place after the mpgroupaction, that is, when everybody in the group has been checked. At this point, we simply have to check the innkeeper's quest bit: if it is 0, the group needs to be thrown out of the inn.

Code: Select all

>greet_prog 100~
if quest(0,1,$W) == 0
  mpmset $W quest 0 1 1
  mpmset self quest 0 1 0
  mpgroupaction $n mpforce @n triggerme
  if quest(0,1,self) == 0
    glare
    say What a bunch of crappy uncharismatic people!
    say Out with you!
    mpgroupaction $n mpforce @n west
  endif
endif
~

>intercept_prog triggerme~
if quest(0,1,self) == 0
  if perm_cha($n) > 16
    sayto $n You are very charismatic!
    sayto $n Your group is welcome to stay!
    mpmset self quest 0 1 1
  endif
endif
~

>leave_prog 100~
mpmset $n quest 0 1 0
~
Dalvyn
Sword Grand Master
Sword Grand Master
Posts: 4708
Joined: Tue Jul 15, 2003 9:26 pm
Location: House of Wonder, Waterdeep

Post by Dalvyn » Sun Mar 11, 2007 5:13 pm

Note that, unless the innkeeper is affected with truesight, it is easy to fool him by entering the inn invisible, then going vis. An idea to prevent this is to mark "$W", the group leader, when his group has been successfully checked.

For this, I extend the 0,1 quest bit used to see whether $W's group has been checked into 0,2, so it can have the following value:
  • 0 = the group needs to be checked
  • 1 = the group is being checked
  • 2 = the group has been successfully checked, they can stay.
This yields the following program.

With those values, we do not need to use the quest bit on the innkeeper anymore (since the value2 above means that we have found someone with a high enough charisma in the group).

Code: Select all

>greet_prog 100~
if quest(0,2,$W) == 0
  mpmset $W quest 0 2 1
  mpgroupaction $n mpforce @n triggerme
  if quest(0,2,$W) == 1
    glare
    say What a bunch of crappy uncharismatic people!
    say Out with you!
    mpgroupaction $n mpforce @n west
  endif
endif 
~

>intercept_prog triggerme~
if quest(0,2,$W) == 1
  if perm_cha($n) > 16
    sayto $n You are very charismatic!
    sayto $n Your group is welcome to stay!
    mpmset $W quest 0 2 2
  endif
endif
~

>leave_prog 100~
mpmset $n quest 0 2 0
~

>intercept_prog train~ (or buy, or sell, or anything else)
if quest(0,2,$W) == 2
  sayto $n Ok, I'll do it.
  mpunintercept
else
  frown $n
  sayto $n Did you try to avoid my screening process?
  sayto $n Get out of here, and only come back when
  sayto $n you have decided to not sneak on me anymore!
  mpgroupaction $n mpforce @n west
endif
~
Now, if they come in invisible, then go visible, their quest bit 0,2 will still be 0... and the innkeeper won't let them train/buy/sell/...

Note that there is still a tiny loophole that characters can use to trick the innkeeper. See if you can find it? ... Or read the rest :)

...

Here's the loophole: Alan comes in with his very charismatic buddy Bilbo. They go in the inn while visible and Alan leads the group. The innkeeper notices Bilbo the Charismatic and set the quest bit 0,2 to 2 on Alan. Alan then goes invisible and leaves the inn. This prevents the innkeeper from resetting his quest bit 0,2 to 0 (in order to re-check Alan's group next time he comes in).

The next day, Alan's quest bit 0,2 is still 2... so, when he comes in the inn with his ugly mate Dave the Purulent, the innkeeper does not check the group. That lets both Dave and Alan deal with the innkeeper, even though they do not have anyone highly charismatic with them.

An easy fix is to set the leave_prog on the room instead of on the mob. Room programs are run by the SuperMob, and the SuperMob sees all (affected by true_sight): Alan can't escape from the room without having his quest bit reset to 0 (well, unless he recalls or teleports out... but that can be easily fixed by making the room NORECALL and NOASTRAL).
Dalvyn
Sword Grand Master
Sword Grand Master
Posts: 4708
Joined: Tue Jul 15, 2003 9:26 pm
Location: House of Wonder, Waterdeep

Post by Dalvyn » Sun Mar 11, 2007 5:18 pm

Amalia wrote:I think I could make this work quite well, with just one more query-- if I put nothing after a quest bit, does it just not show up in the quest log, or will I create a blank line? I could do what I need with this and a two-step invisible mini-quest, I think.
It's good practice to list all the quest bit you use in the QUESTS section, in case your area needs to be updated later (to add a quest for example). Each line follows the following format:

Code: Select all

<areavnum> <lowbit> <numberbit> <minvalue> <maxvalue> <comment>~
If you want to list a quest bit that is used without producing any comments, leaving the <comment> field blank won't work, because it will produce a blank line when people type "qlog". What you can do is play with the <minvalue> and <maxvalue>.

The <comment> is only displayed if the character's quest bit sits in-between those two values. To provide a comment that will never be shown, simply set <minvalue> and <maxvalue> so that the character's quest bit value never satisfies this condition.

For example:

Code: Select all

8000 0 1 9 9 Used to see if the char has bowed in front of the altar~
8000 15 4 99 99 Used to count how many hobgoblins the character has killed.~
In the first case, a value of 9 can never be reached for a quest bit range like 0,1 ... so the comment is never displayed. Same with the second line, where a value of 99 can never be obtained for a range of 4 bits.

If you have further questions, please do not hesitate to ask!
Amalia
Sword Grand Master
Sword Grand Master
Posts: 331
Joined: Wed Feb 01, 2006 6:51 pm
Location: Ardeep Forest
Contact:

Post by Amalia » Sun Mar 11, 2007 5:58 pm

Dalvyn, you make me happy enough to squee. That said, I'm sure there will be plenty more questions once I've gotten past this bit :D
Dear Enemy: May the Lord hate you and all your kind, may you be turned orange in hue, and may your head fall off at an awkward moment.
Post Reply