1
\$\begingroup\$

I am creating a nuclear war simulation game a bit like Defcon if any of you have played that. In the game you can chose one of several regions to play as and in my game I want each region to have different stats for their weapons and I want these stats to be changeable throughout the game if a region decides to develop a particular weapon for instance.

So I have a generic Weapon class that has a damage, a cost, a range etc. I then have different types of Weapon all stored in a WeaponArsenal class (ICBM, MRBM etc). Each region has different values for each of these and it needs to be possible to change them when the player or AI decides to upgrade a weapon.

Of course I can't predict which region the player will pick and therefore can't determine which regions will be AI controlled and which will be the player region. At the moment each available region is a class which has its own values for its weapons through an object but I don't know how I can chose which class to use for the player at run time without very repetitive if statements.

How can I therefore allow the player to upgrade their selected region's weapons without knowing their chosen region and calling a function explicitly?

Should I make a pointer to an object and point it to a different class's object depending on input at the start and then use this object pointer to change a region's variables throughout the game, and is having each region be its own class the best way of setting the game up? I have heard that making each region a map might make things easier but do not now how I would implement this. Which data structure should I use and how should I implement it?

The weapon class:

class Weapon 
{
private:
    int count;
    int damage;
    float cost;
    int range;

public:
    void upgradeRange(Weapon wep, float p) {
        float percentDecimal = p / 100;
        float modifier = percentDecimal + 1;
        wep.range * modifier;
    }
    // more functions for upgrading each stat
    // more functions for setting and getting each stat

}

The WeaponArsenal class:

class WeaponArsenal
{ /* Weapon Types */
public:
    Weapon icbm;
    Weapon mrbm;
    Weapon srbm;
    Weapon bomb;

    WeaponArsenal() { 

        // DEFAULT ICBM VALUES
        icbm.setCount(0);
        icbm.setCost(120);
        icbm.setRange(8000);
        icbm.setDamage(80);

        // DEFAULT MRBM VALUES
        mrbm.setCount(0);
        mrbm.setCost(100);
        mrbm.setRange(2000);
        mrbm.setDamage(70);

        // DEFAULT SRBM VALUES
        srbm.setCount(0);
        srbm.setCost(80);
        srbm.setRange(800);
        srbm.setDamage(55);
    }
};

A region class:

class Europe
{
private:
    WeaponArsenal arsenal;

public:   

    Europe() {    
    }
};

Full main.cpp file so far is on Github:

\$\endgroup\$
  • \$\begingroup\$ github.com/exitc0d3/Contingency-Project/blob/master/main.cpp \$\endgroup\$ – exitcode Sep 10 '16 at 17:48
  • \$\begingroup\$ Isn't this better asked at StackOverflow? \$\endgroup\$ – Tristan Kreuziger Sep 10 '16 at 23:11
  • 1
    \$\begingroup\$ Why are regions classes, if their main difference is just data? Your class hierarchy doesn't need to be a taxonomy to categorise every game entity. \$\endgroup\$ – DMGregory Sep 10 '16 at 23:15
  • \$\begingroup\$ @DomnallAust I don't think so because it is a question about game programming structure and the problem I'm sure is very common in game programming and so there are probably more people likely to be able to answer this question on gamedev than SO. On SO it would have just been down-voted to oblivion anyway. \$\endgroup\$ – exitcode Sep 11 '16 at 9:49
1
\$\begingroup\$

There are many ways to build an object hierarchy. There is no one "right" way. Just methods which don't work at all, and you seem to have implemented one, because it doesn't allow you to easily do what you want to do. But this is how I would do it:

  1. Make Region a class. All the regions should be instances of that class. If the different regions have different game mechanics which need to be expressed with code (and that's a big IF), you could have some regions be classes inheriting from Region.
  2. Have each Region own a list of Weapons. The additional class WeaponArsenal doesn't seem to add much value at this point of development. I would place that functionality directly in Region. When the game becomes more complex and the class Region too large, it might make sense to outsource parts of its functionality into different classes. But IMO it's too early to make that call.
  3. Add a method to Region which is used to upgrade the weapons it owns. Also add methods for everything else a Region can do (fire weapons, surrender etc.)
  4. Create a class PlayerController which holds a reference to a Region. Assign that reference to the region the player selected. The PlayerController's purpose is to process the players input and translate it into method-calls of the Region-object assigned to it.
  5. Create a class AiController. Just as the PlayerController you assign a Region to it. The difference is that it decides for itself when to call which method on Region.
\$\endgroup\$
  • \$\begingroup\$ Do you think it might make sense to nest the WeaponArsenal class inside the Region class rather than just integrating it so I can separate the constructors and have a cleaner Region initialization list? The WeaponArsenal class will probably have a very long initialization list when the game is complete. \$\endgroup\$ – exitcode Sep 11 '16 at 12:10
  • \$\begingroup\$ @exitc0de This is really a matter of personal preference, but I usually only nest very small and trivial classes. When the class is more complex, it should be in its own source file. Otherwise it goes against the reason why you split the class into two in the first place. \$\endgroup\$ – Philipp Sep 11 '16 at 16:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.