Interchanging a variable in a function

Started by BaJankens, Mon 07/07/2014 01:39:03

Previous topic - Next topic

BaJankens

I'm working on a function that needs to call for a specific variable within it. Not the value of the variable, but the variable itself. Is there any way to do that? Am I even doing it right?

Eastwing


BaJankens

#2
I don't think so. I'm trying to call an integer that already exists, but from what I understand of pointers, is that pointers can't call an integer.
Code: ags
  function Tinak_Attack(int monster, [color=#ff0]int monsterhp[/color], int hitpoints){
  
  int ToHit = Random(19)+ cTinak.InventoryQuantity[iFourLeaf.ID];
  
  if (ToHit <=0){
  
  cTinak.Walk(175, 130, eBlock, eAnywhere);
  cTinak.ChangeView(2);
  cTinak.Animate(0, 3, eOnce, eBlock);
  cTinak.SayBackground("Miss");
  Status_Effects();
  cTinak.ChangeView(1);
  cTinak.Walk(100, 130, eBlock, eAnywhere);
  cTinak.FaceLocation(300, 130, eBlock);
  }
  
  if ((ToHit > 0) & (ToHit <19)){
  
  cTinak.Walk(175, 130, eBlock, eAnywhere);
  cTinak.ChangeView(2);
  cTinak.Animate(0, 3, eOnce, eBlock);
  character[monster].SayBackground("Ouch!");
  if (Destruction == false){
  [color=#ff0]monsterhp[/color] -= Damage;
  lblCash.Text = String.Format ("H:%d", BabyGullHP);
  }
  else if (Destruction == true){
    [color=#ff0]monsterhp[/color] -= 10;
    Destruction = false;
  }
  Status_Effects();
  Weapons_Check();
  cTinak.ChangeView(1);
  cTinak.Walk(100, 130, eBlock, eAnywhere);
  cTinak.FaceLocation(300, 130, eBlock);
  }
  
  if (ToHit >= 19){
  
  cTinak.Walk(175, 130, eBlock, eAnywhere);
  cTinak.ChangeView(2);
  cTinak.Animate(0, 3, eOnce, eBlock);
  character[monster].SayBackground("That one REALLY hurt!");
  if (Destruction == false){
 [color=#ff0] monsterhp[/color] -= Damage * Crit;
  lblCash.Text = String.Format ("H:%d", BabyGullHP);
  }
  else if (Destruction == true){
    [color=#ff0]monsterhp[/color] -= 10;
    Destruction = false;
  }
  Status_Effects();
  Weapons_Check();
  cTinak.ChangeView(1);
  cTinak.Walk(100, 130, eBlock, eAnywhere);
  cTinak.FaceLocation(300, 130, eBlock);
  }
  
   if (Enemy_Bleed == true){
      character[monster].Say("I'm BLEEDING!");
      monsterhp -= 1;
   }
      
  if ([color=#ff0]monsterhp[/color]8-) <= 0){
  character[monster].ChangeRoom(0);
  [color=#ff0]monsterhp[/color] = hitpoints;
  MoneyDrop();
  Enemy_Bleed = false;
  cTinak.Walk(315, 130, eBlock, eAnywhere);
  }
  else if ([color=#ff0]monsterhp[/color] > 0){
  
  }
  
  }


this is the current code. The "int monsterhp" is currently the placeholder I have that needs to call a monster's hitpoint integer.

Eastwing

#3
So, you want to get monster's HP and transfer ot to attack function?

If I'm right, there is another way. First add custom property for characters.

Then code something like that:
Code: ags

function Tinak_Attack(Character *badguy)
{
    int BadGuyCurrentHP = badguy.GetProperty("HP");
    //Place Tinak's attack here
    BadGuyCurrentHP -= 100500; //Decreasing monster's current health
    //Some another code
}


Now you just need to call Attack function like that:
Code: ags
Tinak_Attack(cUglyMonster);

BaJankens

Okay, I'll fiddle around with the character properties and get back to you.

Crimson Wizard

#5
Quote from: Eastwing on Mon 07/07/2014 04:04:03
So, you want to get monster's HP and transfer ot to attack function?

If I'm right, there is another way. First add custom property for characters.

Then code something like that:
Code: ags

function Tinak_Attack(Character *badguy)
{
    int BadGuyCurrentHP = badguy.GetProperty("HP");
    //Place Tinak's attack here
    BadGuyCurrentHP -= 100500; //Decreasing monster's current health
    //Some another code
}


This way you are modifying not the character property, but the local variable, which will be destroyed (loosing its value) at the end of the function. Next time you call this function the BadGuyCurrentHP will be same again.
By the way, current version of AGS does not support modifying custom properties at runtime, at all.

The possible solution would be to create user struct to store accompanying data for every existing character:
Code: ags

struct MyCharacterData
{
   int HP;
   // other data
};

MyCharacterData CharData[NUMBER_OF_CHARS_IN_GAME];

function Tinak_Attack(Character *badguy)
{
    int id = badguy.ID;
    //Place Tinak's attack here
    CharData[id].HP -= 100500; //Decreasing monster's current health
    //Some another code
}

Khris

Eastwing,
you should never recommend a solution that you haven't used yourself before.

Eastwing

Okay, it was example of using custom property, not ready-to-use attack function, but sorry.

Anyway, I think that Crimson Wizard's solution is too complicated. Programmer needs to modify script every time something changes (character count or HP of some monster).

Using properties seems more logical and handy for me

Crimson Wizard

Quote from: Eastwing on Mon 07/07/2014 11:55:11
Anyway, I think that Crimson Wizard's solution is too complicated. Programmer needs to modify script every time something changes (character count or HP of some monster).

Using properties seems more logical and handy for me
As I mentioned above, AGS does not support changing properties at runtime at this moment. This means that you won't be able to decrease anyone's HP if they are stored in properties, but only set starting values. To modify these values during game you'll have to use script variables anyway.

Of course, you may init these variables from properties. This way you will be able to edit them in properties editor, if that's what you find more convenient.
Code: ags

function InitCharacterData()
{
   int i = 0;
   while (i < NUMBER_OF_CHARS_IN_GAME)
   {
      CharData[i].HP = character[i].GetProperty("HP");
      i++;
   }
}

Eastwing

QuoteTo modify these values during game you'll have to use script variables anyway.
Yes, I know that. I mean using properties instead in-script struct is more handy and more user-friendly way

Crimson Wizard

#10
Quote from: Eastwing on Mon 07/07/2014 12:13:28
QuoteTo modify these values during game you'll have to use script variables anyway.
Yes, I know that. I mean using properties instead in-script struct is more handy and more user-friendly way
Maybe generally it is, but how will this help in this situation? If using in-script struct solves the problem, but using properties does not.

I'll remind that the topic starter was asking about changing specific value in the function.

Eastwing

For example:

Code: ags
int CurrentHP[NUMBER_OF_CHARACTERS_OR_JUST_BIG_VALUE];

function StartBattle(Character *badguy) //Calls once when player meet enemy and start fighting
{
    CurrentHP[badguy.ID] = badguy.GetProperty("HP");
}

function Tinak_Attack(Character *badguy) //calls repeatly or how you want it to call
{
    //Place Tinak's attack here
    CurrentHP[badguy.ID] -= 100500; //Decreasing monster's current health
    //Some another code
}


Or like in your example, fill array in cycle.
Programmer don't need to define monsters health in scipt, he need just set values in constructor.

Khris

Eastwing, this is not how to deal with a correction by somebody who knows what they're talking about, as opposed to you.

What you suggested previously will not do the trick in this situation, period. Plus, CW's "alternate" solution is not "too complicated". If you don't understand how structs work, please refrain from commenting on their usefulness until you do.

Crimson Wizard

#13
Quote from: Eastwing on Mon 07/07/2014 12:42:44
For example:

Code: ags
int CurrentHP[NUMBER_OF_CHARACTERS_OR_JUST_BIG_VALUE];


Or like in your example, fill array in cycle.

Sure, you can use an array, if HP is the only "extended" property that you need. I used struct in my example to underline, that you may group more data that way.

Quote from: Eastwing on Mon 07/07/2014 12:42:44
Programmer don't need to define monsters health in scipt, he need just set values in constructor.
I did not imply you must define values in script; more, I specifically mentioned the way you can define them in properties and then copy to struct during initialization.

I seriously don't understand, are you critisizing my example for mere use of struct instead of array of ints?

monkey0506

This may be a bit belligerent, and definitely adding to the confusion, but dynamic arrays are passed by reference, so you could use multiple arrays and pass them variably into the function...

But seriously, what CW said is the most friendly approach ATM. Future versions of AGS will support more flexibility with user types, but it's still going to be quite similar in practice.

Crimson Wizard

#15
I want to point out (again), that this question was about modifying values, not initializing it. That's why I focused on telling how to easier modify them and keep their values.

Speaking of initialization, from BaJankens's explanation it wasn't perfectly clear whether every character has certain starting HP bound with it, so whether this is convenient to use character properties as starting values (although that could be possible).

For instance, AGS does not have such thing as "character template", and you can't create new characters at runtime from that template; this makes it making RPG- or Strategy games in AGS somewhat problematic.
Because of that, one of the solutions could be to utilize same character(s) to represent different monsters, and change their Views (sprites & animation) at the start of battle. In such case it won't be convenient to keep initial values in custom properties.
Generally, depending on situation, there could be many ways to initialize variables in script:
* from Custom Properties;
* from Global Variables;
* from global arrays in script;
* read from the file;
* calculate from formula;
etc.


I thought I need to elaborate all this in order to clarify why I did not paid Custom Properties much respect in this thread... so to say.

Eastwing

Okay, I got it and I was wrong by insisting my way :)

Crimson Wizard and monkey_05_06, thanks for explanations.

monkey0506

#17
Eastwing, no worries. We definitely appreciate people trying to help, but if a more experienced member suggests that there is a better way of doing it, then you might just want to step aside. In time you'll pick these things up and be able to give stronger advice yourself. ;)

SMF spam blocked by CleanTalk