Okay, let's see if I can decipher this.
The cause of all this is what DROD expects from the command list when you pick up a Mimic/Clone/Decoy Potion. On replays, it will immediately expect that once you pick up the potion, the next command will be placing the double.
This doesn't follow in two circumstances: when you're asked a Question, and when a Cutscene is running. In the former, the Question takes priority. In the latter, a Cutscene will prevent you from using normal movement commands other than Wait and clicking on the screen (metacommands are still allowed though), and it will send Waits every so many milliseconds.
Question/Answer shouldn't *immediately* cause problems, because they're already given priority when seen. They do cause an Assertion though, so the relevant lines that check for CMD_DOUBLE should also check for CMD_YES, CMD_NO and CMD_ANSWER. And they also break savegames, since DROD will see a lack of CMD_DOUBLE as meaning that it should convert old demo data, and will thus discard Answer commands and then possibly complain that it's found a CMD_DOUBLE... so we should probably update CCurrentGame::PlayAllCommands to fix that.
Cutscene waits are a thornier problem. For starters, when you're playing ingame, the Cutscene will start running and then prevent you from making *any* movement or placing the double until the first automatic wait is sent. At that point, the game will read it as attempting to place the double exactly where your cursor is (and usually fail since you're there, but it gets a bit stranger if a Player Role None is called on the same turn). Whether this succeeds or fails, it counts as a processed command, and it will then terminate the cutscene because the character scripting doesn't have a chance to keep the cutscene going during this extra turn.
When you come to actually undoing the turn and causing the game to replay the saved commands, then we start hitting more problems. I'm not exactly sure why crashes and gamestate breakage occur though. The first cutscene Wait should cancel the cutscene and fail to place the Double (usually), leaving the game to place the Double as normal (which would be the next command). There may be a problem elsewhere that this difference is highlighting.
===
Either way though, there is a very clear problem: cutscenes are still attempting to run while you are placing the results of a potion. There's a few possibilities available to deal with this, but I'd assume that since the Mimic placement currently takes priority and already cancels a cutscene, then it should continue to take priority and be coded as such, especially since this solves the problem of DROD expecting a CMD_DOUBLE immediately after a potion is drunk. This means that cutscenes should *not* attempt to run during Double Placement. So to start with, we'd want the following extra routine added:
currentgame.h
Click here to view the secret text
× bool IsCurrentRoomExplored() const;
bool IsCutScenePlaying() const {return this->dwCutScene && !this->swordsman.wPlacingDoubleType;}
bool IsDemoRecording() const {return this->bIsDemoRecording;}
This new routine should be used to replace most dwCutScene checks that are intended to stop the player from entering commands or cause the game to send automatic Wait commands for the player. (But it shouldn't replace the checks that shouldn't change whether there's a Mimic being placed or not.) This allows the player to place a Mimic/Clone/Decoy on the first turn of a Cutscene, stops assertions and savegame bugs by causing CMD_WAIT to be added during double placement, and should prevent the gamestate problems and crashes related to this.
Secondly, we probably *don't* want to cancel the cutscene just because a Double was placed. If this is the case, then we need to update the following code:
CCurrentGame::ProcessCommand
Click here to view the secret text
× if (this->swordsman.wPlacingDoubleType)
{
ProcessDoublePlacement(nCommand, CueEvents, wX, wY);
this->bContinueCutScene = true;
}
EDIT: Actually, don't think we need a new variable: we can just reuse bContinueCutScene, since it's only ever used to stop a cutscene during ProcessCommand and is only ever set to false near the start of a ProcessCommand. Have edited proposed code to reflect this.
===
I'm not sure that solves *all* the issues, and Question/Answer interactions might have more hidden surprises waiting to be pulled out. But I think this should at least solve the main issue with Double Placement during cutscenes.
[Last edited by TFMurphy at 11-02-2010 02:02 PM]