Announcement: Be excellent to each other.


Caravel Forum : DROD Boards : Bugs : Concerning Wait for event (Another subtle scripting bug)
New Topic New Poll Post Reply
Poster Message
schep
Level: Smitemaster
Avatar
Rank Points: 865
Registered: 03-01-2005
IP: Logged

File: Events bug.hold (1.1 KB)
Downloaded 43 times.
License: Other
From: Unspecified
icon Concerning Wait for event (+1)  
If:
1. A Wait for event command appears as conditional and tests false,
2. The turn in which (1) executed is ended by a command that takes exactly one turn, and
3. The command in (2) is immediately followed by another Wait for event command;
Then command (3) will be bypassed if its event occured at any time during the turn in which commands (1) and (2) are executed, instead of waiting until the next turn to start checking and waiting.

Yes, it's complicated. A hold is attached. Leave your sword on the orb until the Citizen asks you not to strike it, then turn or move. He will act as though you struck it after his request. View the script and see whether that makes sense.

05-30-2005 at 11:48 PM
View Profile Send Private Message to User Send Email to User Show all user's posts This architect's holds Quote Reply
schep
Level: Smitemaster
Avatar
Rank Points: 865
Registered: 03-01-2005
IP: Logged
icon Re: Concerning Wait for event (0)  
But also: The Wait for event code currently contains comments to the effect that when used as a conditional, it might miss events that happen later than the character's turn. But since fixing the above bug would require mucking with that code anyway, is there a reason CCharacter::CheckForCueEvent can't do something smart with wJumpLabel? I would test out something like:

in CCharacter::Process:
case CCharacterCommand::CC_WaitForCueEvent:
{
  // Wait for cue event X to fire.
  const CUEEVENT_ID cid = static_cast<CUEEVENT_ID>(command.x);
  if (!CueEvents.HasOccured(cid)) {
    // Check again at the end of the turn in function
    // CheckForCueEvent().  Do not change the command index yet.
    this->bWaitingForCueEvent = true;
    return;
  }
  bProcessNextCommand = true;
}
break; 

and
void CCharacter::CheckForCueEvent(CCueEvents &CueEvents) //(in)
//Called once all cue events have been gathered.
//If the current command is waiting for a cue event, satisfying this
//will continue to the appropriate command on the following turn.
{
  if (!this->bWaitingForCueEvent) return;
  ASSERT(this->wCurrentCommandIndex < this->commands.size());
  CCharacterCommand& command = this->commands[this->wCurrentCommandIndex];
  ASSERT(command.command == CCharacterCommand::CC_WaitForCueEvent);

  // Wait for cue event X to fire.
  const CUEEVENT_ID cid = static_cast<CUEEVENT_ID>(command.x);
  bool bOccurred = CueEvents.HasOccurred(cid);
  if (this->wJumpLabel)
  {
    if (bOccurred)
    {
      // Go to jump point
      const int wNextIndex = GetIndexOfCommandWithLabel(this->wJumpLabel);
      if (wNextIndex != -1)
        this->wCurrentCommandIndex = wNextIndex;
      else
        ++this->wCurrentCommandIndex;
    }
    else
      ++this->wCurrentCommandIndex;
  } else {
    if (bOccured)
      ++this->wCurrentCommandIndex;
  }
}


[Edited by schep at Local Time:05-31-2005 at 12:15 AM]
05-31-2005 at 12:12 AM
View Profile Send Private Message to User Send Email to User Show all user's posts This architect's holds Quote Reply
mrimer
Level: Legendary Smitemaster
Avatar
Rank Points: 5058
Registered: 02-04-2003
IP: Logged
icon Re: Concerning Wait for event (0)  
Thanks for pointing this out. I'm looking into it, but for now, I'll respond to the following:
schep wrote:
...since fixing the above bug would require mucking with that code anyway, is there a reason CCharacter::CheckForCueEvent can't do something smart with wJumpLabel? I would test out something like:

in CCharacter::Process:
case CCharacterCommand::CC_WaitForCueEvent:
{
  // Wait for cue event X to fire.
  const CUEEVENT_ID cid = static_cast<CUEEVENT_ID>(command.x);
  if (!CueEvents.HasOccured(cid)) {
    // Check again at the end of the turn in function
    // CheckForCueEvent().  Do not change the command index yet.
    this->bWaitingForCueEvent = true;
    return;
  }
  bProcessNextCommand = true;
}
break; 
Unfortunately, there's something undesirable about this change: on an If <wait for event> go to, if the event does not occur, this code halts NPC script execution for the rest of the turn. This is inconsistent with all other If <Wait for ...> go to conditionals, which continue script execution the same turn the condition is not satisfied.

[Edited by mrimer at Local Time:06-02-2005 at 08:11 PM]

____________________________
Gandalf? Yes... That's what they used to call me.
Gandalf the Grey. That was my name.
I am Gandalf the White.
And I come back to you now at the turn of the tide.
06-02-2005 at 08:03 PM
View Profile Send Private Message to User Send Email to User Show all user's posts High Scores This architect's holds Quote Reply
mrimer
Level: Legendary Smitemaster
Avatar
Rank Points: 5058
Registered: 02-04-2003
IP: Logged
icon Re: Concerning Wait for event (0)  
The first thing I'll do is fix the problem you mention in the post at the top of the thread (incorrectly waiting for a cue event at the end of the room turn). To do this, I will change the code in ProcessTurn() to:
case CCharacterCommand::CC_WaitForCueEvent:
...
if (!CueEvents.HasOccurred(cid))
{
	//If NPC is waiting, try to catch event at end of game turn in CheckForCueEvent().
	//!!NOTE: This won't work for conditional "goto ... if <late cue event>".
	if (!this->wJumpLabel)
		this->bWaitingForCueEvent = true;
	STOP_COMMAND;
}
...
I'm not sure how complex a fix the other more general issue you bring up requires. Currently, I don't see a solution.

____________________________
Gandalf? Yes... That's what they used to call me.
Gandalf the Grey. That was my name.
I am Gandalf the White.
And I come back to you now at the turn of the tide.
06-02-2005 at 08:16 PM
View Profile Send Private Message to User Send Email to User Show all user's posts High Scores This architect's holds Quote Reply
schep
Level: Smitemaster
Avatar
Rank Points: 865
Registered: 03-01-2005
IP: Logged
icon Re: Concerning Wait for event (+1)  
On more thought, I agree about the conditionals not trying to wait for late events. It's just a shame one character can't poll for multiple events at once (though multiple characters can...). The only alternative behavior that would make sense seems to be testing whether an event occured since the character's last turn, and that would change quite a bit of code.

But that's just rambling. I really posted because I came across a related bug, or at least slight inconsistency. CCharacter::CheckForCueEvent can be called a second time and catch additional events within the same turn (as defined by the stopwatch) when a double is placed and its sword does something. So two consecutive Wait for event commands might be processed seemingly at once, even when the first was a late event that would otherwise stop processing until the next turn. And if a Speech or Wait 0 or something is inserted between the event commands, it waits until the next turn after all. The best fix looks like clearing bWaitingForCueEvent when CheckForCueEvent successfully detects an event.
06-02-2005 at 10:06 PM
View Profile Send Private Message to User Send Email to User Show all user's posts This architect's holds Quote Reply
mrimer
Level: Legendary Smitemaster
Avatar
Rank Points: 5058
Registered: 02-04-2003
IP: Logged
icon Re: Concerning Wait for event (0)  
schep wrote:
It's just a shame one character can't poll for multiple events at once (though multiple characters can...).
I'm not sure what you mean -- you can have a looping sequence of If <cue event> go to ... and catch any of them on the same turn, right?
CCharacter::CheckForCueEvent can be called a second time and catch additional events within the same turn (as defined by the stopwatch) when a double is placed and its sword does something. So two consecutive Wait for event commands might be processed seemingly at once, even when the first was a late event that would otherwise stop processing until the next turn. And if a Speech or Wait 0 or something is inserted between the event commands, it waits until the next turn after all. The best fix looks like clearing bWaitingForCueEvent when CheckForCueEvent successfully detects an event.
Yes, that makes a lot of sense. I'll add this.

____________________________
Gandalf? Yes... That's what they used to call me.
Gandalf the Grey. That was my name.
I am Gandalf the White.
And I come back to you now at the turn of the tide.
06-02-2005 at 11:51 PM
View Profile Send Private Message to User Send Email to User Show all user's posts High Scores This architect's holds Quote Reply
Oneiromancer
Level: Legendary Smitemaster
Avatar
Rank Points: 2936
Registered: 03-29-2003
IP: Logged
icon Re: Concerning Wait for event (0)  
mrimer wrote:
schep wrote:
It's just a shame one character can't poll for multiple events at once (though multiple characters can...).
I'm not sure what you mean -- you can have a looping sequence of If <cue event> go to ... and catch any of them on the same turn, right?

Yep! I've done it a bunch, and I'm not even a programmer. ;) Just need to have a Wait 1 turn in there to avoid an infinite loop if none of the events are fulfilled.

Actually, it will only catch one event, right? Whatever the earliest event in the loop is? Or if it goes to another label, which sends it back to the first loop, can it catch another one (and realize that it already caught the first one)?

Game on,

____________________________
"He who is certain he knows the ending of things when he is only beginning them is either extremely wise or extremely foolish; no matter which is true, he is certainly an unhappy man, for he has put a knife in the heart of wonder." -- Tad Williams
06-02-2005 at 11:56 PM
View Profile Send Private Message to User Send Email to User Show all user's posts This architect's holds Quote Reply
mrimer
Level: Legendary Smitemaster
Avatar
Rank Points: 5058
Registered: 02-04-2003
IP: Logged
icon Re: Concerning Wait for event (0)  
Oneiromancer wrote:
Actually, it will only catch one event, right? Whatever the earliest event in the loop is? Or if it goes to another label, which sends it back to the first loop, can it catch another one (and realize that it already caught the first one)?
Mmm, right. It won't do the last thing you mention. I guess that's the issue -- it will only catch the first event. However, this seems true for any kind of any conditional goto, regardless of the Wait for query being performed.

____________________________
Gandalf? Yes... That's what they used to call me.
Gandalf the Grey. That was my name.
I am Gandalf the White.
And I come back to you now at the turn of the tide.
06-03-2005 at 12:01 AM
View Profile Send Private Message to User Send Email to User Show all user's posts High Scores This architect's holds Quote Reply
schep
Level: Smitemaster
Avatar
Rank Points: 865
Registered: 03-01-2005
IP: Logged
icon Re: Concerning Wait for event (0)  
mrimer wrote:
I'm not sure what you mean -- you can have a looping sequence of If <cue event> go to ... and catch any of them on the same turn, right?
What I meant was that using that sort of loop with tests and Wait 1, you can't check for events that happen after characters move (this includes destruction of tar/mud due to weapons, and bombs set off by fuses). There's a trick that lets Wait for event as a normal waiting instruction catch those late events, but used as a condition it makes an immediate decision and simply misses some possibilities. So yeah, I should have been more specific. A loop can poll for multiple events like you pointed out, if you know none of the events will be caused at the very end of the turn.
06-03-2005 at 03:00 AM
View Profile Send Private Message to User Send Email to User Show all user's posts This architect's holds Quote Reply
New Topic New Poll Post Reply
Caravel Forum : DROD Boards : Bugs : Concerning Wait for event (Another subtle scripting bug)
Surf To:


Forum Rules:
Can I post a new topic? No
Can I reply? No
Can I read? Yes
HTML Enabled? No
UBBC Enabled? Yes
Words Filter Enable? No

Contact Us | CaravelGames.com

Powered by: tForum tForumHacks Edition b0.98.8
Originally created by Toan Huynh (Copyright © 2000)
Enhanced by the tForumHacks team and the Caravel team.