Alice Alice - 2 months ago 9
C++ Question

How do I wait until a variable reaches a certain number to do something?

I am creating a game in C++. In this game, I have created a class called

Player
. The
Player
class has an attribute called
magic
. This attribute is an integer and constantly goes up throughout the game, when a user does something or accomplishes a task, they can gain
magic
. Once it reaches a certain point, the user gets a new spell, the spells are held in an array in the player class.

I want to be able to check this attribute throughout the game to see if it has reached a certain level.

I was thinking of just checking every time the
magic
attribute goes up, but this could add a lot of conditionals every time it does so. Such as:

user.magic++
if(user.magic == 2) {
//Give a new spell
}
else if(user.magic == 3) {
//Give a new spell
}


And do this every time the
magic
attribute is updated. This seems like it would take a lot of time and effort to constantly type this. Should I put the code above in a function and just run it every time the
magic
updates?

Is there a better way to do this?

Answer

First step: you decouple the user.magic from he spells available. Reason: maybe in the future you want to assign spells for NPC-es as well, not only users.

struct spell {
  int type;
  int cost;
  int damage;
}

static const spell walk_on_water={SURVIVAL, 10, 0};
static const spell resurect={DARK_MAGIC, 100, 0};
static const spell fireball_minor={OFFENSIVE, 30, 4};
static const spell fireball_big={OFFENSIVE, 300, 25};

void getSpellsForMagicLevel(int userMagic, std::vector<const spell&>& resultHere) {
  resultHere.clear();
  switch(useMagic) {
    case 1:
      resultHere.push_back(walk_on_water);
      break;
    case 2:
      resultHere.push_back(walk_on_water);
      resultHere.push_back(fireball_minor);
      break;
    //...
    case 10:
      resultHere.push_back(walk_on_water);
      resultHere.push_back(resurect);
      resultHere.push_back(fireball_minor);
      resultHere.push_back(fireball_big);
      break;
  }
} 

and then you call this single function any time you want to know what available spells are there for a player.magic


Then you note that user's spell inventory only changes when the magic modifies (up - due to increased experience - or down e.g. due to a damaging potion) - so why rely on calling this function again and again? So:

class Player {
protected:
  int magic;
  std::vector<const spell&> spell_inventory;
public:
// ...
  void set_magic(int newMagicLevel) {
    if(this->magic != newMagicLevel) { // do nothing if no change
       this->magic = newMagicLevel;
       getSpellsForMagicLevel(this->magic, this->spell_inventory);
    }
  }
// ...
};

class User : public Player {
  //...
};

class NonPlayerCharacter : public Player {
  //...
};
Comments