Making a battle system. Help selecting enemies.

Started by Egmundo Huevoz, Tue 19/12/2017 02:51:54

Previous topic - Next topic

Egmundo Huevoz

Hi, I've been absent from the AGS world for several years now. I'm currently checking some of my old projects, and one of them had a pretty nice dialog-based battle system. The problem is, I don't know how to change the target. Khris helped me with a shop system which could be used by any character, and I'm trying to reverse-engineer it from there, but to no avail. This was before I knew about arrays or structs (tbh, I'm not an expert about them now), so the code is as messy as it can get. Any help or pointing in the right direction will be greatly appreciated. Thanks in advance.

Matti

You have to be more precise. What battle system are you aiming at? How do you do you want the enemies to be selected?

Snarky

#2
When writing code that can apply to several different characters, the key is to use a character pointer (Character*) as a variable. A character pointer is a variable you can set to refer to ("point to") any character. E.g. like this:

Code: ags
#define CP_HITPOINTS "HitPoints"
#define ATTACK_MAX_DAMAGE 10

// Returns whether the character is still alive after the attack
bool attackCharacter(Character* targetChar)  // <--- HERE'S THE KEY BIT! "Character* targetChar" lets us pass any character to this function
{
  int hitPoints = targetChar.GetProperty(CP_HITPOINTS);  // We've added a custom "HitPoints" character property

  int damage = Random(ATTACK_MAX_DAMAGE);
  hitPoints -= damage;
  // If the damage brings hitPoints to 0.... 
  if(hitPoints <= 0)
  {
    // ... die!
    targetChar.SetProperty(CP_HITPOINTS, 0);
    playDeathAnimation(targetChar);  // Helper function to play the death animation
    return false;    // character is dead
  }
  // otherwise, just update the hitPoints
  targetChar.SetProperty(CP_HITPOINTS, hitPoints);
  return true;    // character remains alive
}


Now you can call this function on any character. For example if you want to attack a character when you click on them:

Code: ags
function cEnemy_Interact()
{
  attackCharacter(cEnemy);
}


Actually, if you can attack many characters, it's better to have a single function you link to all their interactions. It might look something like:

Code: ags
function character_InteractAttack()
{
  Character* clickedChar = Character.GetAtScreenXY(mouse.x, mouse.y);
  if(clickedChar != null)
  {
    bool alive = attackCharacter(clickedChar);
    // More stuff depending on whether they were killed or survived.
  }
}


Now you can link this function in all the relevant characters' interact events.

Egmundo Huevoz

Quote from: Snarky on Tue 19/12/2017 11:46:20
When writing code that can apply to several different characters, the key is to use a character pointer (Character*) as a variable. A character pointer is a variable you can set to refer to ("point to") any character. E.g. like this:

Code: ags
#define CP_HITPOINTS "HitPoints"
#define ATTACK_MAX_DAMAGE 10

// Returns whether the character is still alive after the attack
bool attackCharacter(Character* targetChar)  // <--- HERE'S THE KEY BIT! "Character* targetChar" lets us pass any character to this function
{
  int hitPoints = targetChar.GetProperty(CP_HITPOINTS);  // We've added a custom "HitPoints" character property

  int damage = Random(ATTACK_MAX_DAMAGE);
  hitPoints -= damage;
  // If the damage brings hitPoints to 0.... 
  if(hitPoints <= 0)
  {
    // ... die!
    targetChar.SetProperty(CP_HITPOINTS, 0);
    playDeathAnimation(targetChar);  // Helper function to play the death animation
    return false;    // character is dead
  }
  // otherwise, just update the hitPoints
  targetChar.SetProperty(CP_HITPOINTS, hitPoints);
  return true;    // character remains alive
}


Now you can call this function on any character. For example if you want to attack a character when you click on them:

Code: ags
function cEnemy_Interact()
{
  attackCharacter(cEnemy);
}


Actually, if you can attack many characters, it's better to have a single function you link to all their interactions. It might look something like:

Code: ags
function character_InteractAttack()
{
  Character* clickedChar = Character.GetAtScreenXY(mouse.x, mouse.y);
  if(clickedChar != null)
  {
    bool alive = attackCharacter(clickedChar);
    // More stuff depending on whether they were killed or survived.
  }
}


Now you can link this function in all the relevant characters' interact events.
Thanks a lot! This looks great. I think with a few tests, I can make it work (laugh) (Still learning these kind of things). I'm gonna take a good look in a couple days, right now I'm studying for a final exam on thursday. I'll be back with more feedback once I test it.

SMF spam blocked by CleanTalk