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?
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
You need a distance function, like this:
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
if (cDistracted.DistanceFrom(player) < 50) ...
Oh neat, thank you! I'd never even seen that function before.
It's a pretty neat feature called extender function (https://adventuregamestudio.github.io/ags-manual/ExtenderFunctions.html) 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:
// GlobalScript.ash
import int DistanceFrom(this Character*, Character* other);