(Solved)Cant click on character twice without first stopping speech text

Started by FanOfHumor, Wed 29/12/2021 18:54:22

Previous topic - Next topic

FanOfHumor

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


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



Crimson Wizard

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

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

(this is function's declaration)

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

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

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


FanOfHumor

Would this require placing every  sound that the character says into this
Code: ags

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.

Crimson Wizard

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

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(...).

FanOfHumor

Sorry. I didn't clarify what I meant correctly.

what I want is to modify this same script

Code: ags


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.

Crimson Wizard

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

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.

FanOfHumor

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
 
import function MySay(this Character*, AudioClip *talk, String text);

Crimson Wizard

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
 
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

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.

FanOfHumor

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!");

Crimson Wizard

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?

FanOfHumor

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

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.

Crimson Wizard

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.

FanOfHumor

I still dont understand you.
do I have to change this to play other sounds or not?
  talk.Play();
  this.SayBackground(text);

Crimson Wizard

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

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");

FanOfHumor


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

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;
    }  
  }  
}

Crimson Wizard

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

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;
  } 
}
 

FanOfHumor


SMF spam blocked by CleanTalk