Adventure Game Studio

AGS Support => Beginners' Technical Questions => Topic started by: deadsuperhero on Sun 07/06/2020 20:57:30

Title: Using a generic function on all characters
Post by: deadsuperhero on Sun 07/06/2020 20:57:30
I've been thinking recently about introducing wandering NPCs into my game world, and would love to have circumstances where they can wander into shops, sit down and eat, go to work, etc. Having characters follow a specific agenda is part of a higher-level thing I want to explore, but to get to it, I first have to ask about this low-level foundational thing:

Is there a way to write functions which apply to all characters universally, not just specific ones?

For example, if I make my character walk off the side of the screen, I would call cEgo.Walk prior to changing the room cEgo is in.
But what if I wanted to apply the same thing to any character that did that, regardless of whether cEgo did it or not?

Is there something like a script name that can universally apply to all characters, or can I perhaps write some kind of wrapper function that plops in a character's script name into a Walk / ChangeRoom function?
Title: Re: Using a generic function on all characters
Post by: Cassiebsg on Sun 07/06/2020 21:08:10
Short answer: yes, it's possible to do
Longer answer: You need to code the function yourself, as there isn't any built in. Check function with pointers (is this the correct term?) in the manual.

Basically you need to create a character variable that can hold the character name you want to use. Then once the character has reached that point you store the name in that variable. After that you run your custom function... somethings like this.ChangeRoom(-1); (where "this" will be the character variable you have stored.

Something along these lines, sorry it's not a complete script but I would need to have time to sit, write it and then test it and currently don't have that time. But hopefully a nudge in the right direction will be good enough to get you looking in the right manual entries... or example code on the forum.
Title: Re: Using a generic function on all characters
Post by: morganw on Sun 07/06/2020 21:11:34
Quote from: DeadSuperHero on Sun 07/06/2020 20:57:30
Is there a way to write functions which apply to all characters universally, not just specific ones?
You can just define an extender function (https://adventuregamestudio.github.io/ags-manual/ExtenderFunctions.html).
Title: Re: Using a generic function on all characters
Post by: deadsuperhero on Sun 07/06/2020 21:54:28
Quote from: morganw on Sun 07/06/2020 21:11:34
Quote from: DeadSuperHero on Sun 07/06/2020 20:57:30
Is there a way to write functions which apply to all characters universally, not just specific ones?
You can just define an extender function (https://adventuregamestudio.github.io/ags-manual/ExtenderFunctions.html).

Thanks...it's funny that you brought that up, as I was just looking into the extender function documentation after posting this!
It seems like it would solve my issue; I'll try setting up a dummy NPC and make him walk around with this.
Title: Re: Using a generic function on all characters
Post by: deadsuperhero on Sun 07/06/2020 22:37:27
This is what I've come up with so far. It "works", but with one caveat:

Code (ags) Select

function walk_toRoom(this Character*, int roomNumber,  int x,  int y,  int x_out,  int y_out)
{
  this.Walk(x, y, eNoBlock, eAnywhere);
  if (this.Moving == false) {
    this.ChangeRoom(roomNumber,  x_out,  y_out);
  }
}


Edit: updated the code to account for character movement.  :wink:
Title: Re: Using a generic function on all characters
Post by: Cassiebsg on Sun 07/06/2020 22:41:19
Oh, you have to do it in two "functions"

One to walk there, an once he reaches the destiny then you change him to the next room
Title: Re: Using a generic function on all characters
Post by: deadsuperhero on Sun 07/06/2020 22:43:53
Quote from: Cassiebsg on Sun 07/06/2020 22:41:19
Oh, you have to do it in two "functions"

One to walk there, an once he reaches the destiny then you change him to the next room

Thanks, I ended up figuring it out!  :cheesy:
Title: Re: Using a generic function on all characters
Post by: deadsuperhero on Sun 07/06/2020 23:37:29
Hmm, after a bit more testing, I've come up against a new snag: the character only appears in the next room if I use eNoBlock in my function. This applies to NPCs as well as cEgo...

I'm kind of curious as to why this happens. For now, I can at least let cEgo move from room to room by checking which character is following the function:

Code (ags) Select

function walk_toRoom(this Character*, int roomNumber,  int x,  int y,  int x_out,  int y_out,  const string facing)
{
  if (this == cEgo) {
    cEgo.Walk(x, y, eBlock, eAnywhere);
    cEgo.SetTextProperty("entering_from", facing);
          if (cEgo.Moving == false) {
        cEgo.ChangeRoom(roomNumber,  x_out,  y_out);
    }
  }
  else {
    this.Walk(x, y, eNoBlock, eAnywhere);
    this.SetTextProperty("entering_from", facing);
      if (this.Moving == false) {
        this.ChangeRoom(roomNumber,  x_out,  y_out);
    }
  }
}


I need to find a way to get NPCs to show up in the other room without using eBlock...  :undecided:
Title: Re: Using a generic function on all characters
Post by: Khris on Sun 07/06/2020 23:47:02
Running a command with a  eNoBlock  params means that AGS will proceed to the next line right away.

You can let characters appear randomly in rooms, then make them walk somewhere.
But if you want to make them walk somewhere, then do something once they have reached those coordinates, you have to constantly check their coordinates / whether they're .Moving  in repeatedly_execute.

If you want them to follow actual paths, in the sense that you could follow them from room to room if you wanted, it gets A LOT more complicated. You basically have to create a virtual map, have them walk around that map, then map their map coordinates to AGS room coordinates.
Heroine's Quest did this, and I imagine the scripting was a nightmare.
Title: Re: Using a generic function on all characters
Post by: deadsuperhero on Sun 07/06/2020 23:53:01
Quote from: Khris on Sun 07/06/2020 23:47:02
if you want to make them walk somewhere, then do something once they have reached those coordinates, you have to constantly check their coordinates / whether they're .Moving  in repeatedly_execute.

Yeah, this is basically what I'm running into now. It looks like part of the problem is that I'm making the character walk off-screen, where no walkable areas exist, prior to changing rooms. if I use eBlock, the character will reach their destination, stop moving, and then appear at the new coordinates in the new room. However, under eNoBlock, the character never appears to arrive at those coordinates (or uh, stop moving, according to the engine), despite walking off-screen.

QuoteYou basically have to create a virtual map

I'm kind of curious, how might a virtual map be represented in AGS?
Title: Re: Using a generic function on all characters
Post by: deadsuperhero on Mon 08/06/2020 01:20:55
Update: I managed to get this to work by moving the function to the repeatedly_execute block for the room script. Previously, I was relying on clicking on the character directly to get him to move.

I guess now, I'll need to figure out how to get the character to move around independently of the player character being in a room, but that's probably out of the scope of this thread.  :tongue:

Thank you all for your help and insights!