[SOLVED] AreThingsOverlapping with SayBackground Timer?

Started by HyperAnimated, Fri 24/11/2023 23:32:44

Previous topic - Next topic

HyperAnimated

Hi everybody!  I'm coding a character named Distracted to annoyingly follow as Ego runs away, talking every 5 seconds in the background, saying 1 of 5 different phrases in order each time he talks.

The code below works.  Timer 1 is when to speak, timer 2 is just to fake a speech view animation over the SayBackground's.

But I'd really like Distracted to only talk when he's close to Ego, because otherwise he doesn't need to say "excuse me".  :grin:

I tried a couple if statements inside the (IsTimerExpired(1)) section, first using AreThingsOverlapping, then replacing that with checking if Distracted's x/y were close enough to Ego's.  The first way Distracted never spoke, the second he just kept talking every 5 seconds instead of only when he was close to Ego.

Can anyone think of a way to add "only talk when close to Ego" code to this, please?

Code: ags

function repeatedly_execute_always()
{

if (DistractedSeen == 1) {  //This activates in Room 1 code when Ego crosses a region near Distracted.  The region then disables.
  cDistracted.FollowCharacter(cEgo, 10, 0);  //Start chasing and wandering near Ego.
  }
  
if (IsTimerExpired(1)) {  //This timer also activates for 200 cycles when Ego first enters that room 1 region.
 DistractedTalk ++;       //Started at value 0.
  if (DistractedTalk == 1) {
    cDistracted.LockView(29, eKeepMoving); //Speech view
    SetTimer(2, 70); //Speech view timer
    cDistracted.SayBackground("Oops.  Shall we dance?");
    SetTimer(1, 200); //Distracted won't talk again for 5 seconds.
    }
  else if (DistractedTalk == 2) {
    cDistracted.LockView(29, eKeepMoving); //Speech view
    SetTimer(2, 80); //Speech view timer
    cDistracted.SayBackground("Ha, well THAT just happened.");
    SetTimer(1, 200); //Distracted won't talk again for 5 seconds.
    }
  else if (DistractedTalk == 3) {
    cDistracted.LockView(29, eKeepMoving); //Speech view
    SetTimer(2, 65); //Speech view timer
    cDistracted.SayBackground("Whoops, excuse me.");
    SetTimer(1, 200); //Distracted won't talk again for 5 seconds.
    }
  else if (DistractedTalk == 4) {
    cDistracted.LockView(29, eKeepMoving); //Speech view
    SetTimer(2, 120); //Speech view timer
    cDistracted.SayBackground("We just keep running into each other, ha ha.");
    SetTimer(1, 200); //Distracted won't talk again for 5 seconds.
    }
  else if (DistractedTalk == 5) {
    cDistracted.LockView(29, eKeepMoving); //Speech view
    SetTimer(2, 70); //Speech view timer
    cDistracted.SayBackground("Oh, ha.  Awkward.");
    SetTimer(1, 200); //Distracted won't talk again for 5 seconds.
    DistractedTalk = 0; //Loop back to the start of the different phrases.
    }
}

if (IsTimerExpired(2)) { // Speech view timing for Distracted
  cDistracted.UnlockView();
  }

} //End of repeatedly_execute_always

Khris

You need a distance function, like this:

Code: ags
int DistanceFrom(this Character*, Character* other) {
  float dx = IntToFloat(this.x - other.x);
  float dy = IntToFloat(this.y - other.y) * 2.0; // perspective correction
  return FloatToInt(Maths.Sqrt(dx * dx + dy * dy), eRoundNearest);
}

Now you can do
Code: ags
  if (cDistracted.DistanceFrom(player) < 50) ... 

HyperAnimated

Oh neat, thank you!  I'd never even seen that function before.

Khris

It's a pretty neat feature called extender function where you can extend the built-in API using a special syntax.
You actually need to put the function definition into your global script, and you also need to import it in the global header if you want to use it in room scripts:

Code: ags
// GlobalScript.ash
import int DistanceFrom(this Character*, Character* other);

SMF spam blocked by CleanTalk