How to create an Ammunition C++ class for a game?

Hello.
I'm making a FPS game with Unreal Engine.

I can't find a good way to achieve a good Weapon/Ammunition system.
Let me explain:

I have different kind of Ammunitions, such as Rocket, Grenades, Bullets, Electricity...

I want a weapon system were Ammunitions are independent: that means multiple weapons can use the same kind of ammo.

Let's say I have these 4 kind of Ammunitions:

+Rockets
+Grenades
+Bullets

For each weapon I will implement in the game, I want to establish which kind of Ammunition the weapon's PrimaryFire and SecondaryFire must decrease Ammo from.

EXAMPLE:

I have a Shotgun which only uses Bullets, and another casual weapon which uses Bullets as PrimaryFire and Electricity as Secondary.
In this example, you see I have two weapons which share the same Ammo: Bullets

So this confirms my concept: Ammunitions are independent. They are just there waiting for a Weapon which uses them.

How to achieve this?
Last edited on
Is this a classic application of inheritance and polymorphism?

Couldn't you create a base class called Ammunition which would house the common attributes of all of the ammunition in the base class, and then derive Rockets, Grenades, Bullets? The base class could have a virtual fire() method that each of the derived classes over-ride to specifically handle their own firing events.

From there, each weapon could have a data-member Ammunition* (pointer to ammunition) for primaryFire and secondaryFire which could point to ANY type of ammunition and call it's appropriate fire() method.

Perhaps I'm misunderstanding the problem though. Here's an article on Polymorphism, kinda sounds like what you want: http://www.cplusplus.com/doc/tutorial/polymorphism/
I come from a long experience with C++, so I do know what polymorphism is.

Anyway, the Fire() method is described by the weapon, it's not something an Ammunition has.

Ammunitions in my case are just pieces with a name (or, better, enumeration) to identify them and two integers: MaxAmmo (for storing the maximum ammount of ammo it can hold) and CurrentAmmo (for keeping track of the current ammount of ammo in the player's inventory)

This is my polymorphic approach.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#include <iostream>

/*Ammunition classes*/

class Ammunition
{
public:
	Ammunition() {}
	~Ammunition() {}

	virtual void onFire() = 0;
private:
};

class Rockets : public Ammunition
{
public:
	Rockets() {}
	~Rockets() {}

	void onFire() { std::cout << "Rocket Fired!"; }
private:
};

class Grenade : public Ammunition
{
public:
	Grenade() {}
	~Grenade() {}

	void onFire() {std::cout << "Grenade Thrown!"; }
private:
};

class Bullet : public Ammunition
{
public:
	Bullet() {}
	~Bullet() {}

	void onFire() { std::cout << "Bullet Fired!"; }
private:
};

class Electricity : public Ammunition
{
public:
	Electricity(){}
	~Electricity(){}

	void onFire() {std::cout << "Electricity Fired!";}
private:
};

/*Weapon class*/

class Weapon
{
public:
	Weapon():primary{nullptr}, secondary{nullptr}{}
	~Weapon(){delete primary; delete secondary;}

	void fireWeaponPrimary() {if(primary) primary->onFire();}
	void fireWeaponSeconary() {if(secondary) secondary->onFire();}
	void setWeaponPrimary(Ammunition* newAmmoType) {delete primary; primary = newAmmoType;}
	void setWeaponSecondary(Ammunition* newAmmoType) {delete secondary; secondary = newAmmoType;}
private:
	Ammunition* primary;
	Ammunition* secondary;
};

int main()
{
	Weapon myWeapon;
	myWeapon.setWeaponPrimary(new Bullet);
	myWeapon.setWeaponSecondary(new Grenade);

	myWeapon.fireWeaponPrimary();
	std::cout << std::endl;
	myWeapon.fireWeaponSeconary();

	std::cout << "\n\n***************Changing ammo***************\n\n";

	myWeapon.setWeaponPrimary(new Rockets);
	myWeapon.setWeaponSecondary(new Electricity);

	std::cout << std::endl;
	myWeapon.fireWeaponPrimary();
	std::cout << std::endl;
	myWeapon.fireWeaponSeconary();
}
Last edited on
Yes, that was also mine one. Unfortunately UE4 doesn't support all of these ;(
Something along these lines, perhaps:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
enum ammunition { ROCKET, GRENADE, BULLET } ;

struct inventory { unsigned int capacity /* max */ ; unsigned int size ; /* current */ };

struct weapon { /* .... */ };

#include <map>
#include <vector>

struct player
{
    // ...
    
    std::vector<weapon> weapon_store ;
    std::map< ammunition, inventory > ammunition_store ;
};
Topic archived. No new replies allowed.