specific view when using SayBackground [solved]

Started by HandsFree, Fri 20/05/2011 21:28:23

Previous topic - Next topic

HandsFree

Hi,

I'm trying to give a character a specific view when he's talking.
I assigned the view to character.speechview, but apparently the speechview doesn't show when I use SayBackground.
If I set the view manually, I will have to set it back when the talking has stopped (and I don't know how to do that either).

Is this possible at all?

thanks

Khris

#1
Yes, you have to animate the character manually.
Using SayBackground returns an Overlay and in order to stop the animation you need to check for the overlay's validity i.e. whether it's still on screen.

Put this at the top of the room script, before the first function:

Code: ags
Overlay*bgs;  // background speech


Create the room's repeatedly_execute function, then change it to look like this:

Code: ags
// above function
bool bgs_active;

function room_RepExec() {

  if (bgs != null && bgs.Valid) bgs_active = true;  // background speech still on screen
  else if (bgs_active) {            // background speech has just disappeared
    cNpc.UnlockView();           // stop animation
    bgs_active = false;          // reset variable
  }
}


Start the background talking like this:

Code: ags
  bgs = cNpc.SayBackground("blah blah");
  cNpc.LockView(cNpc.SpeechView);
  cNpc.Animate(cNpc.Loop, 5, eRepeat, eNoBlock);


What happens is the Overlay with the speech text is stored in bgs and it's constantly checked for still being valid; as soon as it isn't any longer, the character's animation is stopped.

monkey0506

Why do you need the second variable at all if it's just checking the validity of the overlay? Also, it's not safe to use the Overlay.Valid or Character.SpeechView properties like that, as they could be invalid, and if they are then your code would crash.

Code: ags
// top of script
Overlay *backgroundSpeech;

// repeatedly_execute
  if ((backgroundSpeech != null) && (cNpc.SpeechView != 0))
  {
    if (backgroundSpeech.Valid)
    {
      if (cNpc.View != cNpc.SpeechView)
      {
        cNpc.LockView(cNpc.SpeechView);
        cNpc.Animate(cNpc.Loop, cNpc.AnimationSpeed, eRepeat, eNoBlock);
      }
    }
    else if (cNpc.View == cNpc.SpeechView) cNpc.UnlockView();
  }

Khris

I hadn't realized that after the BackgroundSpeech has finished the Overlay remains being not null.
And since I didn't want the game to UnlockView() 40 times per second, I used the variable. Good to know though.

I fixed my code; regarding the SpeechView being 0 though, Handsfree even put it in the title of his thread.

monkey0506

Even if you manually call Overlay.Remove the Overlay pointer remains valid (non-null), it is only removed from being displayed. Your condition still would have lead to a null pointer reference error though, even if the pointer was made null when the overlay became invalidated.

Regarding SpeechView being 0, I understand that in his original post he said that he had assigned the view appropriately, but it's still safer and IMO friendlier to check than to get a fatal run-time error in the event that he ever tried doing the same thing with another character that he forgot to assign a speech view to.

As for the secondary variable, I don't see how it's any more or less beneficial than the way that I've done it, so I'll write it off as a matter of preference. ;)


SMF spam blocked by CleanTalk