Npc Behaviour when leaving and re-entering room. [SOLVED]...Yay!

Started by RetroJay, Wed 20/08/2014 23:35:15

Previous topic - Next topic

RetroJay

Hi Peeps.

In my game I have npc's that walk from left to right and up and down.
I have the code below inside the rooms Rep_Exc_Always.

Code: ags
   // NPC MOVEMENT SCRIPT.
   //---------------------
   // This section makes GHOSTS and other CREATURES move.
   if (!cZomb.Moving) {
     if (cZomb.x < 200) {
       // If the Zombie is on the left hand side of the screen,
       // start it moving towards the right.
       cZomb.Walk(612, cZomb.y, eNoBlock, eAnywhere);
       }
       else {
         // Otherwise, move it towards the left
         cZomb.Walk(28, cZomb.y, eNoBlock, eAnywhere);
       }
   }
  
   if (!cZomb2.Moving) {
     if (cZomb2.x < 200) {
       // If the Zombie is on the left hand side of the screen,
       // start it moving towards the right.
       cZomb2.Walk(398, cZomb2.y, eNoBlock, eAnywhere);
       }
       else {
         // Otherwise, move it towards the left.
         cZomb2.Walk(162, cZomb2.y, eNoBlock, eAnywhere);
       }
   }
  
   if (!cZomb3.Moving) {
     if (cZomb3.x < 300) {
       // If the Zombie is on the left hand side of the screen,
       // start it moving towards the right.
       cZomb3.Walk(612, cZomb3.y, eNoBlock, eAnywhere);
       }
       else {
         // Otherwise, move it towards the left.
         cZomb3.Walk(286, cZomb3.y, eNoBlock, eAnywhere);
       }
   }
  
   if (!cGhost.Moving) {
     if (cGhost.x < 100) {
       // If the Ghost is on the left hand side of the screen,
       // start it moving towards the right.
       cGhost.Walk(582, cGhost.y, eNoBlock, eAnywhere);
       }
       else {
         // Otherwise, move it towards the left
         cGhost.Walk(54, cGhost.y, eNoBlock, eAnywhere);
       }
   }
  
   if (!cGhost2.Moving) {
     if (cGhost2.x < 100) {
       // If the Ghost is on the left hand side of the screen,
       // start it moving towards the right.
       cGhost2.Walk(607, cGhost2.y, eNoBlock, eAnywhere);
       }
       else {
         // Otherwise, move it towards the left.
         cGhost2.Walk(32, cGhost2.y, eNoBlock, eAnywhere);
       }
   }
  
   if (!cSpidey.Moving) {
     if (cSpidey.y < 300) {
       // If the Spider is towards the bottom half of the screen,
       // start it moving towards the top.
       cSpidey.Walk(cSpidey.x, 300, eNoBlock, eAnywhere);
       }
       else {
         // Otherwise, move it towards the bottom.
         cSpidey.Walk(cSpidey.x, 264, eNoBlock, eAnywhere);
       }
   }
  
   if (!cSpidey2.Moving) {
     if (cSpidey2.y < 300) {
       // If the Spider is towards the bottom half of the screen,
       // start it moving towards the top.
       cSpidey2.Walk(cSpidey2.x, 300, eNoBlock, eAnywhere);
       }
       else {
         // Otherwise, move it towards the bottom.
         cSpidey2.Walk(cSpidey2.x, 264, eNoBlock, eAnywhere);
       }
   }
  
   if (!cMummy1.Moving) {
     if (cMummy1.x < 200) {
       // If the Zombie is on the left hand side of the screen,
       // start it moving towards the right.
       cMummy1.Walk(258, cMummy1.y, eNoBlock, eAnywhere);
       }
       else {
         // Otherwise, move it towards the left
         cMummy1.Walk(28, cMummy1.y, eNoBlock, eAnywhere);
       }
   }
 }
  // END OF GHOST AND CREATURE MOVEMENTS SCRIPT.
  //--------------------------------------------


This works just great.
The problem is when I leave this room and re-enter.
If I leave the room when npc's are half way across the screen and then re-enter, the npc's scurry back to their start positions. (This ruins the timing of creatures for this room).

I tried to make a 'Global Bool' and moved my movement script to GlobalScript.asc (Rep_Exc_Always) and call it from the rooms Rep_Exc_Always.
I got this to work but the npc's still behave the same.

Now I know why this is happening but is there a way to either stop them in their tracks, when the player leaves the room, and to continue in the correct direction when player re-enters.
Or to continuously have them moving even when the player is not in that room?

If I could just get this to work, it would be a great leap forward.

Any help would be much appreciated.

Yours.
Jay.

Khris

#1
You could set all NPC's initial positions in room_Load.

Code: ags
// above room_Load
int npcx[20], npcy[20];

void SetupNPCs() {
  bool game_starts = Game.DoOnceOnly("store NPC positions");
  Character *npc;
  int ch = 0;
  while (ch < Game.CharacterCount) {
    npc = character[ch];
    if (npc.Room == player.Room && npc != player) {
      // if this is the start of the game, store all initial positions for later use
      if (game_starts) { npcx[ch] = npc.x; npcy[ch] = npc.y; }
      // otherwise, move characters back to initial positions
      else { npc.x = npcx[ch]; npc.y = npcy[ch]; }
    }
    ch++;
  }
}

  // inside room_Load
  SetupNPCs();


This is just a quick fix; if you want them to continue where they left off it's going to get slightly more complicated.

RetroJay

#2
Hi Khris.

Sorry, I pasted your script but am getting an error with line 6 in your example.
AGS says:
QuoteCannot declare local instance of managed type
Whatever the hell that means.???

I have this, at the moment.
Code: ags
int npcx[20], npcy[20];

void SetupNPCs() {
  bool game_starts = Game.DoOnceOnly("store NPC positions");
  Character npc;
  int ch = 0;
  while (ch < Game.CharacterCount) {
    npc = character[ch];
    if (npc.Room == player.Room && npc != player) {
      // if this is the start of the game, store all initial positions for later use
      if (game_starts) { npcx[ch] = npc.x; npcy[ch] = npc.y; }
      // otherwise, move characters back to initial positions
      else { npc.x = npcx[ch]; npc.y = npcy[ch]; }
    ch++;
  }
}

 
function room_Load() {
  SetupNPCs();
  gui[0].Visible = true;
  mouse.Visible = false;   // This disables MOUSE controls.
  RemoveWalkableArea(2);
  oGrandfather_Clock.SetView(6, 2);
  oGrandfather_Clock.Animate(2, 19, eRepeat, eNoBlock, eForwards);
  if (cDan.PreviousRoom == 4) {
    cDan.FaceLocation (640, 400);
  }
  else {
    cDan.FaceLocation(0, 400);
  }
}


This looks very interesting and, more than likely, just what I need.
It must be said that I don't understand some of it, though.

Yours.
Jay.

Khris

Sorry, I forgot the asterisk:
Code: ags
  Character *npc;


The code iterates over the NPCs and when it is called for the first time, it stores their position in variables.
Whenever the room is entered after that, the character's positions are reset to the stored values.

RetroJay

Hi Khris.

I'm so sorry but I can't get this to work.:(
This game is really doing my head in.

I hope you don't mind but I have sent you a PM regarding this matter.

Once this is resolved I will post the solution to my problem.
It may help other people to achieve what I am so obviously failing to achieve.

Yours.
Jay. 

Khris

#5
I also forgot the closing brace for the if block... sorry :P :-[
There should be an additional closing brace directly above the "ch++;" line.

Btw, this is a nice example why proper indentation is awesome; line 14 moves back left without a closing brace, so that's where it is missing.

RetroJay

Hi Khris.

Ha Ha!
That has done the trick.
It works beautifully.:~(:~( (These are tears of joy.)

Please, Khris, no need to apologise.
I couldn't have got this far without your help.
By the time I'm finished I might just as well say 'Game created by Khris' in the credits.;)

All I need to do now is remember where all the keys went on my yekdraob and purchase a new mouse (It landed somewhere in the neighbours garden.) :P

As always, Khris, Thank you for your help and time.
It is much appreciated.

Yours.
Jay.

SMF spam blocked by CleanTalk