react_before question
Moderators: Ice Cream Jonsey, joltcountry
-
- Posts: 10
- Joined: Sat Aug 15, 2009 11:08 am
- Contact:
IMO I think it's correct
From what I've understood of Hugo so far, what you did was essentially correct.
"react_before" is similar to Inform 6's property in that it's supposed to trap actions (and/or provide messages) before any other object's "before" property. If the "react_before" property you have is attached to the mechanic character object, then it will be run before the room's "before" property. (Did that make sense?)
The only caveat here is that the player object has to be within the mechanic's scope to make it actually work.
Hopefully I explained it correctly. Otherwise, let's wait for ICJ or Merk to come in.
"react_before" is similar to Inform 6's property in that it's supposed to trap actions (and/or provide messages) before any other object's "before" property. If the "react_before" property you have is attached to the mechanic character object, then it will be run before the room's "before" property. (Did that make sense?)
The only caveat here is that the player object has to be within the mechanic's scope to make it actually work.
Hopefully I explained it correctly. Otherwise, let's wait for ICJ or Merk to come in.
-
- Posts: 10
- Joined: Sat Aug 15, 2009 11:08 am
- Contact:
Re: IMO I think it's correct
Your question was pretty clear to me. However, I didn't see any other way it can be written.Sca wrote:Still, like I said, the code is working fine now as it is, so maybe I shouldn't really be worrying about elegance. (I guess the main reason I'm at all concerned about this is because, even though for this one example it doesn't make much difference, if I end up using react_befores for other objects with more verbroutines involved, if there's a more elegant approach it could save me a significant amount of typing.) But, again, not a big deal.
Anyway, I appreciate your response; I guess I may not have been entirely clear about my question. Thanks for your reply.
I'd like to see a more elegant way to do this as well.
-
- Posts: 192
- Joined: Mon Nov 22, 2004 3:19 pm
- Location: Wichita, KS
- Contact:
That's a pretty common thing to need to do, and I'm aware of two different ways. I'm not sure I've ever used "react_before" though. You can add any before { } or after { } block to any object for handling specific verbs, such as &DoGo.
Way #1:
In the room where the player can't go west, change this:
w_to newroom
to this:
Way #2:
In your "player" object, add this:
I've done both ways. The downside to #1 is that it doesn't lend itself to automatic room exit listing, because if you attempted to get the value of the various room exit properties, you'd end up executing the code inside the w_to block. The downside to #2 is that you have to specific what room and direction *inside* the player object, and if you do this quite a bit, you'll have lots of code that would probably be better placed in each room/direction where it belongs.
There may be a third way, but I forget.
I'm a fan of using the MISC property on an object as special flags, rather than creating a bunch of extra variables. And you can use multiple properties (MISC #1, #2, #3, etc, as long as you set defaults on the object for however many you will use). In my WIP, the player is initially stopped from going East, and a message is shown. When that happens, location.misc #1 is set to true. That's checked when attempting to go "east" so if the player was already warned once, it's allowed the second time.
Good luck!
Way #1:
In the room where the player can't go west, change this:
w_to newroom
to this:
Code: Select all
w_to {
if (your_condition_goes_here) {
"You can't go that way."
!Alternately, you could customize cant_go.
return false
} else {
return newroom
}
}
In your "player" object, add this:
Code: Select all
before {
actor DoGo {
if (location = whatever) and \
(object = w_obj) and \
(your_condition_goes_here) {
"You can't go that way."
} else {
return false; !Default handling.
}
}
}
There may be a third way, but I forget.
I'm a fan of using the MISC property on an object as special flags, rather than creating a bunch of extra variables. And you can use multiple properties (MISC #1, #2, #3, etc, as long as you set defaults on the object for however many you will use). In my WIP, the player is initially stopped from going East, and a message is shown. When that happens, location.misc #1 is set to true. That's checked when attempting to go "east" so if the player was already warned once, it's allowed the second time.
Good luck!
-
- Posts: 192
- Joined: Mon Nov 22, 2004 3:19 pm
- Location: Wichita, KS
- Contact:
And actually, you're second react_before example is good. I checked the source in hugolib.h and I think what you have there is fine. The first one probably didn't work before you were writing react_before as though it was a before (where you specify verb routines directly).
So yeah, your react_before is probably a better idea than either of the options I posted. I'd stick with that. If you have it on the room object, you're probably set. It looks like you could also put it in the player object, but then you'd be adding "(if location = whatever)" to the condition as well.
So yeah, your react_before is probably a better idea than either of the options I posted. I'd stick with that. If you have it on the room object, you're probably set. It looks like you could also put it in the player object, but then you'd be adding "(if location = whatever)" to the condition as well.
-
- Posts: 192
- Joined: Mon Nov 22, 2004 3:19 pm
- Location: Wichita, KS
- Contact:
Oh, and if you *never* want the player to be able to go west from that room, the ideal thing is probably to not add an exit to the west as part of the room, and then handle the message in cant_go property of the room instead. This allows you to customize the default "you can't go that way" message as needed. Return "false" any time you want the default to be printed instead.
Example:
Example:
Code: Select all
cant_go {
if (object = w_object) {
"The mechanic stops you... etc...."
}
elseif (object = n_object) or (object = s_object) {
"A wall is in your way."
} else {
return false
}
}
-
- Posts: 10
- Joined: Sat Aug 15, 2009 11:08 am
- Contact:
This react_before business
Shouldn't react_before act the same way as before routines do? I mean, shouldn't they have the same format, i.e.:
Code: Select all
react_before
{
<usage> <verbroutine>
{
...
}
}
-
- Posts: 192
- Joined: Mon Nov 22, 2004 3:19 pm
- Location: Wichita, KS
- Contact:
-
- Posts: 2256
- Joined: Mon Apr 29, 2002 6:23 pm
- Location: Milwaukee
I thought this thread was a good illustration for the usefulness of react_before, so I used the problem as an example for the react_before entry at Hugo By Example: http://hugo.gerynarsabode.org./index.ph ... act_before.
Let me know if you have any problems with that. I threw that together just now. I figure at some point, I might try to word things better or have a small section going over the order of operations or something.
Let me know if you have any problems with that. I threw that together just now. I figure at some point, I might try to word things better or have a small section going over the order of operations or something.
- Tdarcos
- Posts: 9556
- Joined: Fri May 16, 2008 9:25 am
- Location: Arlington, Virginia
- Contact:
Why go to that much trouble? Super Mario 64 has an endless staircase when you don't have the key, no matter how much you go up it keeps on going up forever. Turn around and you're right where you started.Sca wrote:what actually happens in the game is that the mechanic only stops the player the first time he tries to go west. If the player tries again, the mechanic says "Well, don't say I didn't warn you," but the player is allowed to move west. (Into an endless road (implemented by counting how many times the player tries to move west, and requiring him to go east that many times to get back)... the mechanic's warning is right.)
So just have it say the road west goes on forever, and move west just loops back to this same room saying this. Then a move east goes back to the previous room. Less trouble to implement and I think it will put the point across.
"When I die, I want it easy and peaceful in my sleep, like my uncle.
Not screaming and crying like his passengers."
Not screaming and crying like his passengers."
-
- Posts: 2256
- Joined: Mon Apr 29, 2002 6:23 pm
- Location: Milwaukee
Personally, I like the react_before method the best, but I thought I'd share another way to do it, using the obstacle global.
First off, we need to give the player a before routine that sets the value of the obstacle global before going anywhere:
Then we have our ObstacleUpdate routine to set the value of obstacle:
Lastly, since having an obstacle usually forces a "The [obstacle] blocks your path." message and nobody really uses obstacles anyway, we will get rid of that particular message using NewVMessages:
First off, we need to give the player a before routine that sets the value of the obstacle global before going anywhere:
Code: Select all
player_character you "you"
{
before
{
actor DoGo
{
ObstacleUpdate
return false ! so that DoGo is still run
}
}
}
Code: Select all
routine ObstacleUpdate
{
if Contains(location,mechanic)
{
if object = w_obj
{
if mechanic is not special
{
"You start to head off, but stop when the
mechanic calls out to you.\n\n\"I wouldn't wander
off that way. You won't find anything but road
for more miles than you'll want to walk.\""
mechanic is special
obstacle = 1
return
}
else
{
"The mechanic regards your departure warily, muttering
\"Well, don't say I didn't warn you,\" almost to himself
as he returns to his work."
}
}
}
obstacle = 0
}
Code: Select all
replace NewVMessages(r, num, a, b)
{
select r
case &DoGo
{
select num
case 1: return true ! skip obstacle messages
case else : return false ! do everything else
}
case else : return false
return true ! this line is only reached if we replaced something
}