Wintermute Engine Forum

Wintermute Engine => Bug reports => Not a bug => Topic started by: Kaz on August 10, 2009, 06:37:36 PM

Title: Declaring and setting globals in same statement unreliable?
Post by: Kaz on August 10, 2009, 06:37:36 PM
No complaint, this engine rocks, and nothing invented by humans can be perfect. Here is a weird one.

I have a script that does this:
Code: [Select]
else
  {
  Game.TakeItem("LetterRhiannon");
  global gGotLetterRhiannon = true;
  }
Rhiannon's letter goes to inventory as it should but occasionally - not on every playing - the global doesn't get set. The player complains that "the letter is still there". I have a savegame from a player to attest. I can see the letter in inventory, but the debugger tells me that the global is in a null state.
I believe I'm right that I can declare and set a global in the same statement, and the majority of times the game is played, both instructions are executed. It sounds like a bug, because usually it works and occasionally it doesn't.
Should I have used
Code: [Select]
else
  {
  Game.TakeItem("LetterRhiannon");
  global gGotLetterRhiannon;
  gGotLetterRhiannon = true;
  }
instead, as a best practice principle anyway?

Cheers

Noel
Title: Re: Declaring and setting globals in same statement unreliable?
Post by: Mnemonic on August 10, 2009, 07:20:31 PM
I'm quite sure the problem is elsewhere. What is the *actual* code? It's in some event handler, I suppose, is there more code in the handler? Please post the exact script.
Title: Re: Declaring and setting globals in same statement unreliable?
Post by: Kaz on August 10, 2009, 08:22:43 PM
Mnem,

Thanks for having a look at this but I don't think there's any point sending any other code. There's only one place where the letter goes to inventory and there's only one place where the global gets set or not. The letter is in inventory, so it has to happen in that sequence. If the 'else' is entered, the letter gets taken, so the global should get set. But sometimes it's null.

Just one of those things I guess.

Suggest we classify it as 'can't reproduce'.

Noel
Title: Re: Declaring and setting globals in same statement unreliable?
Post by: Mnemonic on August 10, 2009, 08:58:28 PM
You should know that I usually have a good reason for asking the things I'm asking about.
And naturally, I can't diagnose or fix problems I don't have enough information about.
Title: Re: Declaring and setting globals in same statement unreliable?
Post by: Kaz on August 10, 2009, 10:34:38 PM
Acknowledged.
Title: Re: Declaring and setting globals in same statement unreliable?
Post by: Mnemonic on August 11, 2009, 10:07:22 AM
Acknowledged but still no info provided :-\
There are many factors that can affect this. For example, is your TakeItem method overridden? Does the handler with this code contain some "blocking" method, such as Talk, GoTo, PlayAnim?
Saying "hey! there's a bug but I won't tell you anything about it" is kind of... useless.
Title: Re: Declaring and setting globals in same statement unreliable?
Post by: Mnemonic on August 11, 2009, 10:23:18 AM
And judging by this thread (http://forum.dead-code.org/index.php?topic=2854.msg18012#msg18012) you are indeed using an overridden TakeItem() method. So one innocently looking line actually calls much more code under the hood. That's why knowing the context is extremely important when diagnosing "bugs"...
Title: Re: Declaring and setting globals in same statement unreliable?
Post by: Kaz on August 11, 2009, 01:27:18 PM
Mnem

I humbly and apologetically take your point. The overriding TakeItem from game.script:

Code: [Select]
method TakeItem(var ItemName)
  {
  // call the original method we have just overriden
  this.TakeItem(ItemName);
  global InventoryOn;
  if(InventoryOn == true)
    {
    Game.PlaySound("sounds\ToInventory.ogg");
  global InventoryHint = true;
  Sleep(1000);
  InventoryHint = false;
}
  }

The full script where the method is called:
Code: [Select]
#include "scripts\base.inc"
#include "scripts\keys.inc"

self.GoExclusive();

on "LeftClick"
  {
  var a = Game.IsItemTaken("LetterRhiannon");
  if(a == true)
    {
Game.PlaySound("sounds\NoticeboardOn.ogg");
}
  else
    {
    Game.TakeItem("LetterRhiannon");
global gGotLetterRhiannon = true;
    }
  self.Close;
  Game.UnloadObject(this);
  }

The script that checks whether the letter is in inventory as a condition on an action:

Code: [Select]
if(gFAC.Seen != true)
  {
  global gFireIsLit;
  global gGotLetterRhiannon;
  if(gFireIsLit != true || gGotLetterRhiannon != true)
    {
    // Fire not lit or study not visited - just rattle the door
    Game.PlaySound("sounds\LockedSuffolkDoor.ogg");
gRhiannonHaunt.TriedDoor = true;
}
  else
    {
// Play the FAC sequence
    Game.Interactive = false;
gRhiannonHaunt.Summon = false;
    Game.PlaySound("sounds\LockedSuffolkDoor.ogg");
    Sleep(1000);
    Game.SetMousePos(1024, 768);
    var video = Scene.GetNode("video");
    video.Active = true;
    video.PlayTheora("Video\FAC.ogg");
    Sleep(20000);
    video.Active = false;
// This gFAC.Seen = true will prevent the Summons from running again
    gFAC.Seen = true;
    gFAC.Solved = false;
    Scene.InitializeDoor();
    Game.Interactive = true;
}
  }

Anything you can suggest as to why it works usually, but not always?

Thanks
Title: Re: Declaring and setting globals in same statement unreliable?
Post by: Mnemonic on August 11, 2009, 02:01:21 PM
Thanks :)

Now, what happens if the player clicks the window, and then, while the game is displaying the acquired item for one second, he clicks the window again? The LeftClick handler is executed again, it will find the item is already taken, so it will just play some sound and kill the window. Killing the window will also kill the original LeftClick handler, which is still executing the TakeItem line (waiting for one second) so it will never get to the second line.

A good practice is to enclose atomic actions invoked by player between Game.Interactive = false / true. That way the player cannot click again until the original click handler finishes.
Title: Re: Declaring and setting globals in same statement unreliable?
Post by: Kaz on August 11, 2009, 02:53:09 PM
Of course! Hemm, I mean, that sounds reasonable. No wonder you smiled  :)

We'll test it.

Ah - double-clicked it as fast as I could. And it worked as it should. :(

Never mind, your suggestion sounds right, so we'll lock the routine down.

Thanks