simple question about changing values in custom structs

Started by wynni2, Thu 09/03/2017 14:29:26

Previous topic - Next topic

wynni2

Sorry for a such a basic question, but I'm clearly missing something.  I have an array of the struct Cstat, which contains some character stats for my game.  For simplicity's sake, I'll focus on "int aggression." 

I have a command to return aggression, which works fine:

Code: ags

int Aggression(this Character*) {
return Cstat[this.ID].aggression;
}

if (this.Aggression() > 10) this.Attack(); 


If I want to increase the character's aggression level I know how to use the script o-name:

Code: ags

Cstat[this.ID].aggression ++; 


What I don't understand is how / if I can write a custom function allowing me to do this:

Code: ags

this.Aggression ++; 


I assume I have to use a method within the struct, but I'm a novice coder and the wiki/manual aren't 100% clear on implementing methods within structs. 

I'm using AGS v 3.3, BTW.

Thanks.

dayowlron

I am not sure if you can do extender functions on structures.

I can tell you if you can, just wondering what is the name of the structure?
I see the occurrence is named Cstat. Lets say the struction is Cstatstruct then from a programming standpoint the code would look something like this:
Code: ags

function IncreaseAggression(this Cstatstruct*) {
    this.aggression ++;
}

The you would call it like this
Code: ags

  IncreaseAggression(Cstat[x]);
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

Khris

It all comes down to what the this is referring to. It looks as if you're lumping together custom structs and extender functions, at least in your question.

First of all, you cannot add variables to built-in structs like Character, only functions (at least afaik, unless it was added very recently)

The common workaround is a pair called getter and setter:

Code: ags
int getAggression(this Character*) {
  return Cstat[this.ID].aggression;
}

void setAggression(this Character*, int val) { 
  Cstat[this.ID].aggression = val;
}


So increasing the aggression by one in another extender function would look like this:
Code: ags
  Cstat[this.ID].setAggression(Cstat[this.ID].getAggression() + 1);


You could also use this:
Code: ags
void changeAggressionBy(this Character*, int val) { 
  Cstat[this.ID].aggression += val;
}


That way you can shorten it to
Code: ags
  Cstat[this.ID].changeAggressionBy(1); // add 1
and pass negative values to lower it.


All of this is still pretty ugly, but you can simply use a completely different approach: use a custom struct with functions, and store the AGS character in it:

Code: ags
struct Person {
  int aggression;
  int hunger;
  ...
  Character *ac;
  import void DoStuff();
};


Now you can simply do this:

Code: ags
Person person[50];

// this instead of extender functions
void Person::DoStuff() {
  if (this.aggression < 10) this.aggression++;
  ...
}

// to actually call an AGS command on the character, simply use the pointer stored in the instance:
function x() {
  person[1].ac = cEgo;
  person[1].aggression++;
  // now we want the AGS character:
  person[1].ac.Walk(150, 100);
}

Crimson Wizard

#3
I think I'll mention, as a potential alternative for certain cases, that since 3.4.0 you can change custom property values at runtime, which allows to use them as "extender variables".

You need to create Property Schema in your game first, by opening, e.g., character for editing and clicking on "Properties" property, and then on "Edit schema..." button. There you create any number of properties you want your game objects have.
The main limitation here is that these properties may only be integer, bool or string. Another thing is that you cannot group these properties, but have just one big list of them.

Later in game you use these properties as:
Code: ags

int num = cMyCharacter.GetProperty("SomeCustomNumber");
cMyCharacter.SetTextProperty("HowShouldIBeCalled", "George");

SMF spam blocked by CleanTalk