[SOLVED] Relative scripts for character ID's

Started by Glenjamin, Wed 19/12/2018 16:35:47

Previous topic - Next topic

Glenjamin

Sorry for the several posts lately,  this should be the last one until i'll have a great base to work off.

Once again we're talking variable management with characters.


For example, I have this script to indicate a character has died:

Code: ags


 function repeatedly_execute(){
    
 if (NPHealth[cJerry.ID] == 0){
   
   cJerry.Say("Looks like I'm dead friend.");
   
   }

 }


With the current setup I'd need to do an if statement for every NPC in the entire game.

I'm looking for a way for AGS to grab the character.ID of any NPC who's health has reached zero, and then use it to run the death script.

(Theoretically looking like this)

Code: ags


 function repeatedly_execute(){
    
 if (NPHealth[Character.ID] == 0){
   
   Character[character.ID].Say("Looks like I'm dead friend.");
   
   }

 }


(I've also added +1 to the health array so the character.ID's align properly)

Thanks.

dayowlron

you need to set up a for loop to check all the characters.
Code: ags

for (int i = 0; i < Game.CharacterCount; i++)
{
   if (NPHealth[character[i].id] == 0){ 
           character[i].Say("Looks like I'm dead friend.");
   }
}

can't test my code but it should be something similar to this.
Pro is the opposite of Con                       Kids of today are so much different
This fact can clearly be seen,                  Don't you know?
If progress means to move forward         Just ask them where they are from
Then what does congress mean?             And they tell you where you can go.  --Nipsey Russell

Snarky

#2
(Edit: Sniped by dayowlron. I'll just add that character[i].id is redundant: the ID of character[i] is always i.)

That's easy; it's just character[i].

However, do note that particularly when you're calling something from repeatedly_execute(), you need some logic to make sure it doesn't get called over and over again. So, in this case, you need to make sure that NPHealth[i] is NOT 0 on the next game loop.

Typically you might do something like:

Code: ags
function repeatedly_execute() {
  for(int i=0; i<Game.CharacterCount; i++)  // If you only want to check a subset of the characters, you can change that here
    if (character[i]!= player && NPHealth[i] == 0) {
      character[i].Say("Looks like I'm dead, friend.");  // Added a comma for grammar. :p
      NPHealth[i] = -1;  // Set this to -1 so it doesn't get called again next loop
    }
}


Edit 2: However, rather than having this in repeatedly_execute() (as I always say: if you're a novice AGS coder and you're writing code in repeatedly_execute(), you're almost certainly doing something wrong), a better solution would usually be to do the check and action when you modify the NPHealth of the character. For example, have a Character.Damage(int damagePoints) function that you always call when you want to apply damage to a character, which subtracts the health points, checks whether they're 0 and if so gives the response.

Glenjamin

I used snarky's snippet and It worked like a charm. Thanks guys.

When the game first loaded every character in the game started doing a rolecall of "Looks like im dead, friend". I thought it wasn't working until I realized they only said that because I didnt declare their health variables yet!

Time to really get cracking.

Khris

For reference, here's the rep_exe-less solution:

Code: ags
// header
import void HealthChange(this Character*, int amount);

// main script
void HealthChange(this Character*, int amount) {
  NPHealth[this.ID] += amount;
  if (NPHealth[this.ID] <= 0) {
    this.Say("Looks like I'm dead, friend.");
    // ...
  }
}


Use it like this:
Code: ags
  cJerry.HealthChange(-10); // lose 10 HP

SMF spam blocked by CleanTalk