There is a game, many characters. Everyone has their own unique tricks, for example

Бутылка шампанского 1. метнуть пробкой сквозь противника перекручиваясь через себя 2. залить пол алкоголем, заставив противника подскользнуться упасть 

or

 Варвар 1. Кинуть топор вверх, через секунду топор прилетит в голову сопернику 2. Усыпить соперника рогом шляпы в глаз 

For each character for custom techniques there is a class in which there are three methods: beforeAttack , afterAttack , UpdateAttack . Where beforeAttack and afterAttack are called only once before receiving and after, and UpdateAttack updated 1 time per frame (that is, many). These classes are inherited from the main, which controls the process, something like this:

 abstract class CommonCustom { public virtual void beforeAttack() {} public virtual void afterAttack() {} public virtual void UpdateAttack() {} public virtual void ApplyAll() { // тут некое условие, чтоб этот метод вызывался лишь раз! beforeAttack(); // вызывается много раз пока идет прием UpdateAttack(); // тут некое условие, чтоб этот метод вызывался лишь раз! afterAttack(); } } 

The essence of the problem: I have three methods and each character can have several tricks, it turns out that in each method I write switch/case , for example:

 class Test : CommonCustom { public virtual void beforeAttack() { switch attackType { case beerAttack: //do smth break; case capAttack: //do smth break; // и т.д. } } public virtual void afterAttack() { switch attackType { case beerAttack: //do smth break; case capAttack: //do smth break; // и т.д. } } public virtual void UpdateAttack() { switch attackType { case beerAttack: //do smth break; case capAttack: //do smth break; // и т.д. } } } 

Is it possible to do something in order not to write in every method of swith, but somehow to make the whole thing uniform? Maybe somehow add more classes that need to be implemented or something else.

  • It seems to me that you are here - Andrew Bystrov
  • 3
    @AndrewBystrov is also allowed here. There is even a label. I did not put it the truth. Not sure what exactly should be put now to the question - user221013
  • It is not clear what the Test class is and why it does so. Describe his logic in the subject area. - Monk
  • @Monk what does it mean why he does that? Well, there is a main class with the logic of the game in which there is an UpdateAll method that is called once per frame. (i.e., 60 times per second) ... it calls the ApplyAll() method of the object (player), which is just a character with the class Test . Because Inherited from CommonCustom ApplyAll() also works on it and makes these three methods work. - user221013
  • @Kromster all the logic of various common actions or the work of the controllers or the work of the config are described in different classes. And as for the individual abilities / skills of the character - they can not be unified, because they all are completely different and consist of different things and lead to a common denominator will not work. Therefore, I decided to create separate classes for completely custom individual techniques of each character, in which the logic of these very individual techniques will be spelled out. For example, the combination -> -> <- A detonates a bomb from a hand whirling through itself using the reception properties - user221013

2 answers 2

I would make an IAttack interface:

 public interface IAttack { public void PreAttack(); public void Attack(); public void PostAttack(); } 

BeerAttack and others implement this interface:

 public class BeerAttack : IAttack { public void PreAttack() { //специфическая логика пива } public void Attack() { //специфическая логика пива } public void PostAttack() { //специфическая логика пива } } 

Then like this:

 class Test : CommonCustom { public virtual void beforeAttack(IAttack attack) { attack.PreAttack(); } public virtual void afterAttack(IAttack attack) { attack.PostAttack(); } public virtual void UpdateAttack(IAttack attack) { attack.Attack(); } 

    In any case, you will have to paint this couple of hundreds of scenarios, whether in scripts, classes, cases .. Your task is to find an option that is as convenient as possible, with a minimum of repetitions and opportunities to make a mistake, with the degree of customization and scalability you need. Write ten scenarios, isolate all common. Select an option.

    • Cases, and how their development - Polymorphism
      Make an action class, inherit action classes from it (by type). Use action classes according to the types of actions specified in the data. It is convenient to code, but inconvenient to configure.

    • Date-drive
      When you record all the actions in the game data and there will be one class that will perform them. Rather rigid structure. Something average between hardcode and scripts (see below)

    • Scripting languages
      like Lua. Excellent game modding and scalability. No need to recompile to change some little thing.