Adventure Game Studio

AGS Support => Beginners' Technical Questions => Topic started by: FanOfHumor on Wed 29/12/2021 18:54:22

Title: (Solved)Cant click on character twice without first stopping speech text
Post by: FanOfHumor on Wed 29/12/2021 18:54:22
My character has a sound file play when he talks but I am attempting to make it that you can skip the talking and the text at the same time by clicking him again.

The sound and the text shows. Then when you click again it first stops the text before stopping the sound.
I'm not using the speech files I am using a new sound type called talk.

Code (ags) Select


function max12_AnyClick()
{
  if(Game.IsAudioPlaying(eAudioTypetalk2))
  {
    Game.StopAudio(eAudioTypetalk2);
  } 
  else
  {
    aWeird.Play();
  } 
  player.Say("You mean even dummer than you!");
}


Title: Re: Cant click on character twice without first clicking to stop speech text.
Post by: Crimson Wizard on Wed 29/12/2021 20:09:23
AGS standard speech (Say command) is blocking, which means that it also intercepts any player input.

If you want to be able to click elsewhere while the player speech is on screen, you'd need to create your own custom speech function, where you would not use regular blocking speech (Say command), but would instead use background speech (SayBackground) or custom Overlays (see Overlay functions in the manual).

With non-blocking speech player input will be not intercepted by the speech itself, and instead go directly to an object they are clicking on again.

The big problem there is to decide how does the non-blocking speech stops (under which condition).





Following is the trivial example of such function, that may be placed in a GlobalScript:

In the header (GlobalScript.ash):
Code (ags) Select

import function MySay(this Character*, AudioClip *talk, String text);

(this is function's declaration)

In the script itself (GlobalScript.asc):
Code (ags) Select

function MySay(this Character*, AudioClip *talk, String text)
{
    if(Game.IsAudioPlaying(eAudioTypeTalk2))
    {
        Game.StopAudio(eAudioTypetalk2);
    }
    talk.Play();
    this.SayBackground(text);
}


Now you can use this like:
Code (ags) Select

player.MySay(aWeird, "You mean even dummer than you!");

Title: Re: Cant click on character twice without first clicking to stop speech text.
Post by: FanOfHumor on Wed 29/12/2021 22:19:55
Would this require placing every  sound that the character says into this
Code (ags) Select

import function MySay(this Character*, AudioClip *talk, String text);


Because I need this script  to be easily versatile in order to copy it for everything said.
also this needs to be for all charcters.
Title: Re: Cant click on character twice without first clicking to stop speech text.
Post by: Crimson Wizard on Wed 29/12/2021 22:37:08
Quote from: Pajama Sam on Wed 29/12/2021 22:19:55
Would this require placing every  sound that the character says into this

This example requires you to pass a sound as an argument. This works best if the sounds change often.
If the sound is always same for all characters, then this argument may be removed, and sound's name used directly inside the function.

If the sound is always same per character, then there are couple of possible solutions here, but the most straightforward is to do this:

Code (ags) Select

function MySay(this Character*, String text)
{
    if(Game.IsAudioPlaying(eAudioTypeTalk2))
    {
        Game.StopAudio(eAudioTypetalk2);
    }

    if (this.ID == player.ID) {
         aWeird.Play();
    } else if (this.ID == cOtherGuy.ID) {
         aAnotherSound.Play();
    } else if (this.ID == cSomeDifferentPerson.ID) {
         aAnotherSound2.Play();
    } // and so on...

    this.SayBackground(text);
}


Quote from: Pajama Sam on Wed 29/12/2021 22:19:55
also this needs to be for all charcters.

That will work for all characters; the first argument is basically the Character's pointer, so it will work from any character like cAnotherGuy.MySay(...).
Title: Re: Cant click on character twice without first clicking to stop speech text.
Post by: FanOfHumor on Thu 30/12/2021 00:47:55
Sorry. I didn't clarify what I meant correctly.

what I want is to modify this same script

Code (ags) Select


function max12_AnyClick()
{
  if(Game.IsAudioPlaying(eAudioTypetalk2))
  {
    Game.StopAudio(eAudioTypetalk2);
  } 
  else
  {
    aWeird.Play();
  } 
  player.Say("You mean even dummer than you!");
}

by having a quick way to copy this for any character.and just change the sound name.
but that isnt much of a problem what I mainly want is to be able to skip the sound and the text at the same time so that when the character is clicked twice his 2nd action can perform.

also I want to be able to have this under "function max12_AnyClick()"

But what you said before might work for me so give me some time to try it.
Title: Re: Cant click on character twice without first clicking to stop speech text.
Post by: Crimson Wizard on Thu 30/12/2021 00:53:23
Quote from: Pajama Sam on Thu 30/12/2021 00:47:55
what I want is to modify this same script

by having a quick way to copy this for any character.and just change the sound name.

The point of a custom function is to store the most of the code, so that you dont have to copy all of it over and over again. Instead you just place a function call:

Code (ags) Select

function max12_AnyClick()
{
  player.MySay(aWeird, "You mean even dummer than you!");
}


And then you do same for other characters, or other interactions, changing the name of the sound and text that you pass to the function.
Title: Re: Cant click on character twice without first clicking to stop speech text.
Post by: FanOfHumor on Thu 30/12/2021 01:10:34
I never learned how to make custom functions because I never needed to.
plus I couldn't figure it out.

so do you put anything into this or just place it without descriptions  in globalscript.ash.
Code (ags) Select

import function MySay(this Character*, AudioClip *talk, String text);
Title: Re: Cant click on character twice without first clicking to stop speech text.
Post by: Crimson Wizard on Thu 30/12/2021 01:12:14
Quote from: Pajama Sam on Thu 30/12/2021 01:10:34
so do you put anything into this or just place it without descriptions  in globalscript.ash.
Code (ags) Select

import function MySay(this Character*, AudioClip *talk, String text);


I'm not sure what do you mean by "without descriptions", but yes, you put that function declaration in globalscript.ash (header), and the function itself in globalscript.asc (the script body):

Code (ags) Select

function MySay(this Character*, AudioClip *talk, String text)
{
    if(Game.IsAudioPlaying(eAudioTypeTalk2))
    {
        Game.StopAudio(eAudioTypetalk2);
    }
    talk.Play();
    this.SayBackground(text);
}


This way you will be able to call it inside both GlobalScript and room scripts.
Title: Re: Cant click on character twice without first clicking to stop speech text.
Post by: FanOfHumor on Thu 30/12/2021 01:24:41
Do I have to change anything in this if I want to have the character say more than one saying.   
   
    talk.Play();
    this.SayBackground(text);

or can I just change the sound name in.
player.MySay(aWeird, "You mean even dummer than you!");
Title: Re: Cant click on character twice without first clicking to stop speech text.
Post by: Crimson Wizard on Thu 30/12/2021 01:27:36
Quote from: Pajama Sam on Thu 30/12/2021 01:24:41
Do I have to change anything in this if I want to have the character say more than one saying.   

Do you mean, have more than one speech line after the first line? Or say something else on different interaction?
Title: Re: Cant click on character twice without first clicking to stop speech text.
Post by: FanOfHumor on Thu 30/12/2021 01:35:59
I have it that when you click the character once it says something and every time you click on him it says something different according to a pattern. All I was asking is if I have to change anything in this so I could play the next talking sound.

Code (ags) Select

function MySay(this Character*, AudioClip *talk, String text)
{
    if(Game.IsAudioPlaying(eAudioTypeTalk2))
    {
        Game.StopAudio(eAudioTypetalk2);
    }
    talk.Play();
    this.SayBackground(text);
}


If not then that's good for me.
Title: Re: Cant click on character twice without first clicking to stop speech text.
Post by: Crimson Wizard on Thu 30/12/2021 01:38:21
Quote from: Pajama Sam on Thu 30/12/2021 01:35:59
I have it that when you click the character once it says something and every time you click on him it says something different according to a pattern. All I was asking is if I have to change anything in this so I could play the next talking sound.

Ah okay, no I think it should work if you just call this function with the different sound name / text.

You may require additional changes if you have a more complex behavior, for example, a sequence of lines played one after another after just one click.
Title: Re: Cant click on character twice without first clicking to stop speech text.
Post by: FanOfHumor on Thu 30/12/2021 02:19:07
I still dont understand you.
do I have to change this to play other sounds or not?
  talk.Play();
  this.SayBackground(text);
Title: Re: Cant click on character twice without first clicking to stop speech text.
Post by: Crimson Wizard on Thu 30/12/2021 02:29:53
Quote from: Pajama Sam on Thu 30/12/2021 02:19:07
I still dont understand you.
do I have to change this to play other sounds or not?
  talk.Play();
  this.SayBackground(text);

No, you do not need to change anything in the function itself.
To play different sounds you need to pass different sound names into it.

Code (ags) Select

player.MySay(aWeird, "You mean even dummer than you!");
...
player.MySay(aWeird2, "This is a different text");
...
player.MySay(aSound10, "This is a completely different text");
Title: Re: Cant click on character twice without first clicking to stop speech text.
Post by: FanOfHumor on Thu 30/12/2021 02:46:34

I understand what you mean now but I still cant get this to work
do have any idea why this is only playing one sound?

Code (ags) Select

int speak;
function max12_AnyClick()
{
 
  if(Game.IsAudioPlaying(eAudioTypetalk2))
  {
    Game.StopAudio(eAudioTypetalk2);
  } 
  else
  {
    if(speak==0)
    {
      player.MySay(aWeird, "You mean even dummer than you!");
    }
    if(speak==1)
    {
      player.MySay(aFries1, "dfdgfskjdgsigrjsbdfijsdbsd");
    }
    if(speak<2)
    {
      speak+=1;
    }
    if(speak==2)
    {
      speak=0;
    } 
  } 
}
Title: Re: Cant click on character twice without first clicking to stop speech text.
Post by: Crimson Wizard on Thu 30/12/2021 02:56:40
I think that the first part of the code where you stop the sound is unnecessary, because function MySay will stop the sound itself.
But more importantly, the way you wrote the first if/else pair: if you click second time while the first sound is playing, it will just stop the playing sound but won't start the new one.

Perhaps try this variant:
Code (ags) Select

int speak;
function max12_AnyClick()
{
  if(speak==0)
  {
    player.MySay(aWeird, "You mean even dummer than you!");
  }
  else if(speak==1)
  {
    player.MySay(aFries1, "dfdgfskjdgsigrjsbdfijsdbsd");
  }
 
  speak+=1;
  if(speak==2)
  {
    speak=0;
  }
}

Title: Re: Cant click on character twice without first clicking to stop speech text.
Post by: FanOfHumor on Thu 30/12/2021 04:55:38
That works out great! ;-D
Thanks!