Vector data binding

I have a Monsters class, and when an instance is created, it must associate each monster with a weapon. ex. The monster Gryphon should have an attack on griffin 1 and an attack on griffin 2, of course, the name of the attack is TBD, but now it's good to use the attacks of griffin 1 and 2.

Currenly I have it.

#include <vector> typedef enum {Living, Dead, Nature} Race; typedef enum {Gryphon, Oracle, Mercenary,Templar, Satyr,Fallin Angel,ArcAngel,Satan,Grimreaper, Unbaptized Babies,Boggart,Succubus,Meat Wagon, Djinns,Manticore,Water Nymph,Plant Nymph, Mother Nature, Cannibal Tribesmen,Wyvern, Vegetable Lamb, Ent, Lava Worm, Alpha Dragon } MonsterType; typedef enum {gryphon1,Oracle1, Mercenary1,Templar1, Satyr1,Fallin Angel1,ArcAngel1,Satan1,Grimreaper1, Unbaptized Babies1,Boggart1,Succubus1,Meat Wagon1, Djinns1,Manticore1,Water Nymph1,Plant Nymph1, Mother Nature1, Cannibal Tribesmen1,Wyvern1, Vegetable Lamb1, Ent1, Lava Worm1,Alpha Dragon1, Gryphon2, Oracle2, Mercenary2,Templar2, Satyr2,Fallin Angel2,ArcAngel2,Satan2,Grimreaper2, Unbaptized Babies2,Boggart2,Succubus2,Meat Wagon2, Djinns2,Manticore2,Water Nymph2,Plant Nymph2, Mother Nature2, Cannibal Tribesmen2,Wyvern2, Vegetable Lamb2, Ent2, Lava Worm2, Alpha Dragon2 } Weapon; Class Monsters{ protected: MonsterType type; Race race; std::vector<Weapon> weapon_list; public: bool flying; bool lava; bool water; int life; int karmaCost; int move; int crit; int defMagic; int defNonMagic; bool isDead; bool canMove; bool canAttack; bool onFlag; int nextTurn; }; 

I am not sure about the vector, and if necessary, these were just some of the experiments I was busy with. But what is the best way to link a weapon to a monster? Also note that each weapon has values ​​that go with it, So

 gryphon attack 1 { int range = 10 int ticks = 5 bool magical = false int power = 23 bool heals = false } gryphon attack 2 { int range = 5 int ticks = 7 bool magical = true int power = 29 bool heals = true } 

actual values ​​are read from ini or the network, so I don’t worry about real values ​​yet, but I need to know that I can add the values gryphon->weapon1->range = 5

I'm still very new to this, so if something seems very wrong, tell me.

+6
source share
3 answers

Speaking from experience: your chosen approach will lead to many problems in the future. I know that I certainly do not answer your question, but I do this only to save you some trouble. Forgive me and / ord neglect this below if you want to do it your own way.

Do not create custom classes for each of your monsters or characters. Create a single abstract abstract composite class with many properties that describe the various aspects of this game object. Example:

 // simplified class declaration, not a C++ code class GameActor { ActorVisualization visualization; vector<InventoryItems> inventory; ActorStatistics stats; vector<ActorEffects> appliedEffects; } 

Such an abstract object will be used for all Actors in your game, including the characters of the players.

The next step is to use the visitor template for all the things that can happen to this actor.

 // continued class GameActor { bool applies(Visitor& visitor); void accept(Visitor& visitor) { if (applies(visitor)) { visitor.visit(this); } } } class Visitor { void visit(GameActor& actor); } 

Extend GameActor to suit your needs, if necessary. Whenever you add new features, try using the already implemented visitor mechanism. Create a new GameActor property only if necessary.

Samples of visitors? It could be written in different ways, but I hope that he will explain how everything should be done.

 class DamageInflictedVisitor { int amount; damageType_t dmgType; void visit(GameActor& actor) { double res = actor.getStats().getResistances().getResistanceForType(dmgType); int finalAmount = amount * (1-res); actor.getStats().inflictDamage(finalAmount); } } class ActorAliveVisitor { void visit(GameActor& actor) { if (actor.getStats().hp <= 0) { if (actor.getType() == AT_MONSTER) { // remove from the game, create a new ExperienceGained visitor applicable for players, etc. } else if (actor.getType() == AT_PLAYER) { // notify the game that the given player is dead } } } } 

Using such simple visitors, you have very good readability of the code, you know what each visitor does simply by looking at this name.

+4
source

Try creating a hierarchical structure for your monsters instead of a large list of types. For example, baseclass Monster, which only has a position / orientation and a race. then you make the derived class LivingMonster, which has, for example, added health, and the class LivingArmedMonster, which has weapons. this ensures that you don’t get a bloated class and make it easier to add monsters later using other functions without blowing up a large monster class.

as for your weapon: the list is a great idea, the only thing I would add is maybe use a pointer, since then you can have another weapon (derived from the base class: weapon) without changing the list. it will also be easier to exchange weapons between the monster (you have a weapon storage that creates all the weapons), then you can drop the weapon and take it, so you simply move the pointer from one vector of the monster’s weapon to another. it's less intense than copying a full object

+1
source
 Class Weapon { int range; int ticks; bool magical; int power; bool heals; public Weapon(int range, ......){ this->range = range; ... } }; Class Monster{ protected: MonsterType type; Race race; std::vector<Weapon> weapon_list; public: int life; int karmaCost; ... void addWeapon(Weapon w){ weapon_list.push_back(w); } }; Class FlyingMonster : public Monster{ public: int flightSpeed; } Class MonsterFactory{ static FlyingMonster *CreateGryphon(){ FlyingMonster *gryphon = new FlyingMonster(); gryphon.addWeapon(WeaponFactory::CreateGryphonAttack1()); gryphon.addWeapon(WeaponFactory::CreateGryphonAttack2()); return gryphon; } }; Class WeaponFactory{ static Weapon* CreateGryphonAttack1(){ Weapon* w = new Weapon(gryphonAttack1BaseRange); return w; } }; FlyingMonster* tom = MonsterFactory::CreateGryphon(); tom->weapon_list[0].range = 50; 
+1
source

Source: https://habr.com/ru/post/946921/


All Articles