Prechádzať zdrojové kódy

Merge branch 'gui' into dev

Ivan Arkhipov 6 rokov pred
rodič
commit
a04845a7d3

+ 1 - 0
assets/units/races.txt

@@ -0,0 +1 @@
+warcraft

+ 18 - 5
client.pro

@@ -30,24 +30,37 @@ SOURCES += \
     source/gui/uniticon.cpp \
     source/gui/gui.cpp \
     source/gui/recruitmentscene.cpp \
-    source/unit.cpp \
-    source/player.cpp \
+    source/units/unit.cpp \
     source/gui/mainmenu.cpp \
     source/gui/guiscenemanager.cpp \
     source/gui/detatchedwidget.cpp \
-    source/gui/playervsplayerintro.cpp
+    source/gui/playervsplayerintro.cpp \
+    source/race.cpp \
+    source/racemanager.cpp \
+    source/units/mage.cpp \
+    source/units/warrior.cpp \
+    source/gui/scene.cpp \
+    source/gui/raceicon.cpp \
+    source/playermanager.cpp
 
 HEADERS += \
     include/gui/uniticon.h \
     include/gui/gui.h \
     include/gui/recruitmentscene.h \
-    include/unit.h \
+    include/units/unit.h \
     include/abstractfactory.h \
     include/player.h \
     include/gui/mainmenu.h \
     include/gui/guiscenemanager.h \
     include/gui/detatchedwidget.h \
-    include/gui/playervsplayerintro.h
+    include/gui/playervsplayerintro.h \
+    include/race.h \
+    include/racemanager.h \
+    include/units/mage.h \
+    include/units/warrior.h \
+    include/gui/scene.h \
+    include/gui/raceicon.h \
+    include/playermanager.h
 
 FORMS += \
     include/gui/gui.ui \

+ 14 - 14
include/abstractfactory.h

@@ -3,20 +3,20 @@
 #include <string>
 #include <map>
 
-template <class Base, typename IdType>
+template <class Base, typename CreatorParam>
 class AbstractCreator {
 public:
 	virtual ~AbstractCreator() {}
-	virtual Base* create(const IdType &id) const = 0;
+    virtual Base* create(const CreatorParam &id) const = 0;
 };
 
-template <class ObjectClass, class Base, typename IdType>
-class Creator : public AbstractCreator <Base, IdType> {
+template <class ObjectClass, class Base, typename CreatorParam>
+class Creator : public AbstractCreator<Base, CreatorParam> {
 public:
-	Creator(IdType id) {}
+    Creator() {}
 	virtual ~Creator() {}
-	Base* create(const IdType &id) const {
-		return dynamic_cast<Base*>(new ObjectClass(id));
+    Base* create(const CreatorParam &params) const {
+        return dynamic_cast<Base*>(new ObjectClass(params));
 	}
 };
 
@@ -34,14 +34,14 @@ public:
 			delete item.second;
 	}
 
-	template <class C, typename idCreator>
-	void add(const IdType &id) {
-		registerClass(id, new Creator<C, Base, idCreator>(id));
+    template <class C, typename CreatorParam>
+    void addClass(const IdType &id) {
+        registerClass(id, new Creator<C, Base, CreatorParam>());
 	}
 
-	template <typename idCreator>
-	Base* create(const IdType &idClass, const idCreator &id) {
-		return factory_[idClass]->create(id);
+    template <typename CreatorParam>
+    Base* createObject(const IdType &idClass, const CreatorParam &parameters) {
+        return factory_[idClass]->create(parameters);
 	}
 
 protected:
@@ -52,4 +52,4 @@ protected:
 		else
 			delete ConcreteFabric;
 	}
-};
+};

+ 4 - 2
include/gui/guiscenemanager.h

@@ -1,6 +1,8 @@
 #ifndef INCLUDEGUIGUISCENEMANAGER_H
 #define INCLUDEGUIGUISCENEMANAGER_H
 
+#include "gui/scene.h"
+
 #include <QObject>
 
 #include <map>
@@ -20,7 +22,7 @@ public:
         return instance;
     }
 
-    bool registerScene(QString scene_name, QWidget* name);
+    bool registerScene(QString scene_name, Scene* name);
 
     bool changeScene(QString scene_name, QString args = "");
 
@@ -29,7 +31,7 @@ public:
     void destroyDetachedScene(QString scene_name);
 
 private:
-    std::map<QString, QWidget*> scenes_;
+    std::map<QString, Scene*> scenes_;
     QString current_scene_;
     GUI* gui_;
 

+ 5 - 1
include/gui/mainmenu.h

@@ -1,13 +1,15 @@
 #ifndef MAINMENU_H
 #define MAINMENU_H
 
+#include "gui/scene.h"
+
 #include <QWidget>
 
 namespace Ui {
 class MainMenu;
 }
 
-class MainMenu : public QWidget
+class MainMenu : public Scene
 {
     Q_OBJECT
 
@@ -15,6 +17,8 @@ public:
     explicit MainMenu(QWidget *parent = 0);
     ~MainMenu();
 
+    void ParseArgs(QString args) {}
+
 private slots:
 
     void on_exit_button_clicked();

+ 9 - 1
include/gui/mainmenu.ui

@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <ui version="4.0">
  <class>MainMenu</class>
- <widget class="QWidget" name="MainMenu">
+ <widget class="Scene" name="MainMenu">
   <property name="geometry">
    <rect>
     <x>0</x>
@@ -56,6 +56,14 @@
    </property>
   </widget>
  </widget>
+ <customwidgets>
+  <customwidget>
+   <class>Scene</class>
+   <extends>QWidget</extends>
+   <header location="global">gui/scene.h</header>
+   <container>1</container>
+  </customwidget>
+ </customwidgets>
  <resources/>
  <connections/>
 </ui>

+ 0 - 45
include/gui/mainwindow.ui

@@ -1,45 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>Form</class>
- <widget class="QWidget" name="Form">
-  <property name="geometry">
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>940</width>
-    <height>720</height>
-   </rect>
-  </property>
-  <property name="windowTitle">
-   <string>Form</string>
-  </property>
-  <widget class="QLabel" name="divider_">
-   <property name="geometry">
-    <rect>
-     <x>0</x>
-     <y>170</y>
-     <width>940</width>
-     <height>91</height>
-    </rect>
-   </property>
-   <property name="text">
-    <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;img src=&quot;:/assets/recruitscene/divider.png&quot; width=&quot;940&quot;/&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
-   </property>
-  </widget>
-  <widget class="QLabel" name="title_">
-   <property name="geometry">
-    <rect>
-     <x>0</x>
-     <y>100</y>
-     <width>941</width>
-     <height>101</height>
-    </rect>
-   </property>
-   <property name="text">
-    <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;&lt;span style=&quot; font-size:24pt; color:#b12d2d;&quot;&gt;Супер-мега-крутая-игрушка-&lt;br&gt;название-которой-мы-ещё-не-придумали&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
-   </property>
-  </widget>
- </widget>
- <resources/>
- <connections/>
-</ui>

+ 4 - 1
include/gui/playervsplayerintro.h

@@ -1,13 +1,15 @@
 #ifndef PLAYERVSPLAYERINTRO_H
 #define PLAYERVSPLAYERINTRO_H
 
+#include "gui/scene.h"
+
 #include <QWidget>
 
 namespace Ui {
 class PlayerVsPlayerIntro;
 }
 
-class PlayerVsPlayerIntro : public QWidget
+class PlayerVsPlayerIntro : public Scene
 {
     Q_OBJECT
 
@@ -15,6 +17,7 @@ public:
     explicit PlayerVsPlayerIntro(QWidget *parent = 0);
     ~PlayerVsPlayerIntro();
 
+    void ParseArgs(QString args) {}
 private slots:
     void on_back_to_menu_clicked();
 

+ 10 - 2
include/gui/playervsplayerintro.ui

@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <ui version="4.0">
  <class>PlayerVsPlayerIntro</class>
- <widget class="QWidget" name="PlayerVsPlayerIntro">
+ <widget class="Scene" name="PlayerVsPlayerIntro">
   <property name="geometry">
    <rect>
     <x>0</x>
@@ -107,7 +107,7 @@
     <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;&lt;span style=&quot; font-size:12pt; color:#b12d2d;&quot;&gt;Кол-во монет:&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
    </property>
   </widget>
-  <widget class="QLineEdit" name="lineEdit">
+  <widget class="QLineEdit" name="money_">
    <property name="geometry">
     <rect>
      <x>462</x>
@@ -121,6 +121,14 @@
    </property>
   </widget>
  </widget>
+ <customwidgets>
+  <customwidget>
+   <class>Scene</class>
+   <extends>QWidget</extends>
+   <header location="global">gui/scene.h</header>
+   <container>1</container>
+  </customwidget>
+ </customwidgets>
  <resources/>
  <connections/>
 </ui>

+ 64 - 0
include/gui/raceicon.h

@@ -0,0 +1,64 @@
+#ifndef RACEICON_H
+#define RACEICON_H
+
+#include "units/unit.h"
+
+#include <QObject>
+#include <QWidget>
+#include <QLabel>
+#include <QImage>
+#include <QPixmap>
+#include <QPainter>
+#include <QTime>
+
+class RaceIcon : public QLabel {
+Q_OBJECT
+
+public:
+    explicit RaceIcon(QWidget* parent = 0, int width = 64, int height = 64);
+    ~RaceIcon();
+
+    void setRaceIcon(QString racename);
+    void setRaceIcon(QImage icon);
+    void resize(int w, int h);
+    void unsetRaceIcon();
+
+    void deactivate();
+    void activate();
+
+
+protected:
+    void mousePressEvent(QMouseEvent* event);
+    void enterEvent(QEvent* event);
+    void leaveEvent(QEvent* event);
+
+
+signals:
+    void clicked();
+    void doubleclicked();
+    void hovered();
+    void unhovered();
+
+private:
+    void drawIcon();
+
+    int width_;
+    int height_;
+
+    int state_; // 0 = not initialized;
+                // 1 = default;
+                // 2 = hover;
+                // 3 = active;
+
+    QPixmap pixmap_;
+    QImage active_border_;
+    QImage hover_border_;
+    QImage default_border_;
+    QImage icon_;
+
+    QTime previous_click_time_;
+
+    Unit* unit_;
+};
+
+#endif // RACEICON_H

+ 21 - 1
include/gui/recruitmentscene.h

@@ -1,17 +1,21 @@
 #ifndef RECRUITMENTSCENE_H
 #define RECRUITMENTSCENE_H
 
+#include "gui/scene.h"
+
 #include <QWidget>
 
 #include <vector>
 
 class UnitIcon;
+class RaceIcon;
+class Player;
 
 namespace Ui {
 class RecruitmentScene;
 }
 
-class RecruitmentScene : public QWidget
+class RecruitmentScene : public Scene
 {
     Q_OBJECT
 
@@ -19,13 +23,29 @@ public:
     explicit RecruitmentScene(QWidget *parent = 0);
     ~RecruitmentScene();
 
+    void parseArgs(QString args) override;
+    void init() override;
+
+private:
+    void initAvailableRaces();
+    void initAvailableUnits();
+    void initChosenUnits();
+
 private slots:
     void on_back_button_clicked();
 
 private:
+    int available_money_;
+    int current_money_;
+
+    int current_player_id_;
+    Player* current_player_;
+
     Ui::RecruitmentScene *ui;
     UnitIcon* available_units_icons_[5];
     UnitIcon* chosen_units_icons_[10];
+
+    RaceIcon* available_races_icons_[3];
 };
 
 #endif // RECRUITMENTSCENE_H

+ 9 - 17
include/gui/recruitmentscene.ui

@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <ui version="4.0">
  <class>RecruitmentScene</class>
- <widget class="QWidget" name="RecruitmentScene">
+ <widget class="Scene" name="RecruitmentScene">
   <property name="geometry">
    <rect>
     <x>0</x>
@@ -92,9 +92,9 @@
   <widget class="QLabel" name="title_">
    <property name="geometry">
     <rect>
-     <x>-3</x>
+     <x>0</x>
      <y>0</y>
-     <width>941</width>
+     <width>940</width>
      <height>71</height>
     </rect>
    </property>
@@ -416,19 +416,6 @@
     </rect>
    </property>
   </widget>
-  <widget class="QLabel" name="title_1">
-   <property name="geometry">
-    <rect>
-     <x>270</x>
-     <y>350</y>
-     <width>941</width>
-     <height>71</height>
-    </rect>
-   </property>
-   <property name="text">
-    <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;&lt;span style=&quot; font-size:24pt; color:#b12d2d;&quot;&gt;Набор юнитов&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
-   </property>
-  </widget>
   <zorder>divider_</zorder>
   <zorder>chosen_race_text_</zorder>
   <zorder>chosen_race_image_</zorder>
@@ -445,9 +432,14 @@
   <zorder>apply</zorder>
   <zorder>unit_spec_widget_</zorder>
   <zorder>widget</zorder>
-  <zorder>title_1</zorder>
  </widget>
  <customwidgets>
+  <customwidget>
+   <class>Scene</class>
+   <extends>QWidget</extends>
+   <header location="global">gui/scene.h</header>
+   <container>1</container>
+  </customwidget>
   <customwidget>
    <class>UnitIcon</class>
    <extends>QLabel</extends>

+ 23 - 0
include/gui/scene.h

@@ -0,0 +1,23 @@
+#ifndef INCLUDEGUISCENE_H
+#define INCLUDEGUISCENE_H
+
+#include <QWidget>
+
+class Scene : public QWidget
+{
+    Q_OBJECT
+public:
+    explicit Scene(QWidget *parent = nullptr);
+
+    virtual ~Scene() {}
+
+    virtual void parseArgs(QString args) {}
+
+    virtual void init() {}
+
+signals:
+
+public slots:
+};
+
+#endif // INCLUDEGUISCENE_H

+ 4 - 2
include/gui/uniticon.h

@@ -1,6 +1,8 @@
 #ifndef UNITICON_H
 #define UNITICON_H
 
+#include "units/unit.h"
+
 #include <QObject>
 #include <QWidget>
 #include <QLabel>
@@ -9,15 +11,15 @@
 #include <QPainter>
 #include <QTime>
 
-#include <unit.h>
-
 class UnitIcon : public QLabel {
 Q_OBJECT
 
 public:
     explicit UnitIcon(QWidget* parent = 0, int width = 64, int height = 64);
     ~UnitIcon();
+
     void setUnitIcon(QString racename, QString unitname);
+    void setUnitIcon(QImage icon);
     void resize(int w, int h);
     void unsetUnitIcon();
 

+ 30 - 9
include/player.h

@@ -1,21 +1,43 @@
 #ifndef INCLUDEPLAYER_H
 #define INCLUDEPLAYER_H
 
+#include "units/unit.h"
+#include "racemanager.h"
+
 #include <QObject>
 
 #include <set>
 
-class Unit;
-class Faction;
+class Race;
 
 template<class Obj, class Identifier>
 class ObjectFactory;
 
-class Player : public QObject
-{
-    Q_OBJECT
+class Player {
 public:
-    explicit Player(QObject *parent = nullptr);
+    Player() {
+
+    }
+
+    void init(int id) {
+        player_name_ = "Игрок " + QString::number(id);
+        race_ = RaceManager::getInstance().getRace(
+                    RaceManager::getInstance().getAvailableRacesList()[0]
+                );
+        units_.clear();
+    }
+
+    QString getPlayerName() {
+        return player_name_;
+    }
+
+    const std::set<Unit>& getUnits() {
+        return units_;
+    }
+
+    Race* getRace() {
+        return race_;
+    }
 
 signals:
 
@@ -23,9 +45,8 @@ public slots:
 
 private:
     QString player_name_;
-    //std::set<Unit*> units_;
-    //Faction* faction_;
-
+    std::set<Unit> units_;
+    Race* race_;
 };
 
 #endif // INCLUDEPLAYER_H

+ 33 - 0
include/playermanager.h

@@ -0,0 +1,33 @@
+#ifndef INCLUDEPLAYERMANAGER_H
+#define INCLUDEPLAYERMANAGER_H
+
+#include <player.h>
+
+#include <QObject>
+
+#include <vector>
+
+class PlayerManager : public QObject
+{
+    Q_OBJECT
+private:
+    explicit PlayerManager(QObject *parent = nullptr);
+public:
+    static PlayerManager& getInstance() {
+        static PlayerManager instance;
+        return instance;
+    }
+
+    Player* getPlayer(int id);
+    int getPlayersNum();
+    void setPlayersNum(int num);
+
+private:
+    std::vector<Player> players_;
+
+signals:
+
+public slots:
+};
+
+#endif // INCLUDEPLAYERMANAGER_H

+ 44 - 0
include/race.h

@@ -0,0 +1,44 @@
+#ifndef INCLUDEACE_H
+#define INCLUDEACE_H
+
+#include <QObject>
+#include <QString>
+#include <QImage>
+
+#include <vector>
+
+#include "abstractfactory.h"
+
+class Unit;
+
+class Race : public QObject
+{
+    Q_OBJECT
+public:
+    explicit Race(QString race_name, QObject *parent = nullptr);
+
+    Unit* createUnit(QString unit_name);
+
+    const std::vector<QString> &getAvailableUnitsList();
+    const std::vector<Unit*> &getAllUnitsList();
+
+    QString getRaceId();
+    QString getRaceName();
+    QImage getRaceIcon();
+    QString getRaceDescr();
+
+private:
+    QString race_id_;
+    QString race_name_;
+    QImage race_icon_;
+    QString race_descr_;
+    ObjectFactory<Unit, QString> units_factory_;
+    std::vector<QString> available_units_list_;
+    std::vector<Unit*> all_units_list_;
+
+signals:
+
+public slots:
+};
+
+#endif // INCLUDEACE_H

+ 33 - 0
include/racemanager.h

@@ -0,0 +1,33 @@
+#ifndef INCLUDEACEMANAGER_H
+#define INCLUDEACEMANAGER_H
+
+#include <QObject>
+
+#include <vector>
+
+class Race;
+
+class RaceManager : public QObject
+{
+    Q_OBJECT
+private:
+    explicit RaceManager(QObject *parent = nullptr);
+public:
+    static RaceManager& getInstance() {
+        static RaceManager instance;
+        return instance;
+    }
+
+    Race* getRace(QString race_name);
+    const std::vector<QString>& getAvailableRacesList();
+
+private:
+    std::vector<QString> available_races_;
+    std::map<QString, Race*> races_;
+
+signals:
+
+public slots:
+};
+
+#endif // INCLUDEACEMANAGER_H

+ 0 - 151
include/unit.h

@@ -1,151 +0,0 @@
-#pragma once
-#include <iostream>
-#include <vector>
-#include "AbstractFactory.h"
-
-class Spell {
-public:
-    int a;
-};
-
-class Cell {
-	//waiting for a realisation
-public:
-	//must be in cell.h
-	bool isEmpty() { 
-		return true;
-	}
-	std::vector <Cell*> actualPath(Cell* destination) { //the shortest existing path from (*this) to (*destination)
-		std::vector <Cell*> path;
-		return path;
-	}
-};
-
-class Unit {
-
-protected:
-	std::vector <Spell> skills_;
-
-private:
-	//personal information
-	int cost_;
-	std::string parent_spec_;
-	std::vector<std::string> upgrade_specs_;
-	double experience_;
-	double level_;
-	std::string race_; //lower case
-
-	//actions and events
-	double initiative_;
-	int activity_points_;
-
-	//movement
-	Cell* location_;
-	int movement_speed_;	//how many cells can move for one activity point
-	double real_x_;
-	double real_y_;
-
-	//attack action
-	double agility_;
-	double attack_range_;
-	double damage_per_hit_;
-	double intelligence_;
-	double strength_;
-	int attack_cost_;     //how many activity points does attack cost
-
-	//durability
-	double health_points_;
-	double magic_defence_;  //less or equal 40
-	double physic_defence_; //less or equal 40
-
-public:
-	Unit() = delete;
-	Unit(std::string path) {
-
-	}
-	virtual ~Unit() = delete;
-
-	int getCost();
-	void setCost(int value);
-
-	std::string getParentSpec();
-	void setParentSpec(std::string specId);
-
-	std::vector<std::string> getUpgradeSpecs();
-	void setUpgradeSpecs(std::vector <std::string> specs);
-
-	double getExperience();
-	void setExperience(double value);
-
-	double getLevel();
-	void setLevel(double value);
-
-	double getHealthPoints();
-	void setHealthPoints(double value);
-
-	double getAttackRange();
-	void setAttackRange(double value);
-
-	int getActivityPoints();
-	void setActivityPoints(int value);
-
-	Cell* getLocation();
-	void setLocation(Cell* to);
-
-	int getMovementSpeed();
-	void setMovementSpeed(int value);
-
-	int getAttackCost();
-	void setAttackCost(int value);
-
-	double getInitiative();
-	void setInitiative(double value);
-
-	double getDamagePerHit();
-	void setDamagePerHit(double value);
-
-	double getIntelligence();
-	void setIntelligence(double value);
-
-	double getStrength();
-	void setStrength(double value);
-
-	double getAgility();
-	void setAgility(double value);
-
-	int getAttackPoints();
-	void setAttackPoints(int value);
-
-	double getMagicDefence();
-	void setMagicDefence(double value);
-
-	double getPhysicDefence();
-	void setPhysicDefence(double value);
-
-	std::string getRace();
-	void setRace(std::string new_race);
-
-	double getRealX();
-	void setRealX(double x);
-
-	double getRealY();
-	void setRealY(double y);
-
-	virtual void calculateDamagePerHit();
-
-	virtual double reduceIncomingDamage(std::string damageType, int value);
-
-	int lenOfActualPath(Cell* destination);
-
-	virtual bool canMoveForDistance(int distance);
-
-	virtual bool canMoveToCell(Cell* destination);
-
-	virtual void moveToCell(Cell* destination);
-
-	virtual	bool canAttackForDistance(int distance) = 0;
-
-	virtual bool canAttackToCell(Cell* destination) = 0;
-
-	virtual bool canAttackUnit(Unit* target) = 0;
-};

+ 14 - 0
include/units/mage.h

@@ -0,0 +1,14 @@
+#ifndef UNITS_MAGE_H
+#define UNITS_MAGE_H
+
+#include "units/unit.h"
+
+#include <QObject>
+
+class Mage : public Unit
+{
+public:
+    explicit Mage(QString parameters);
+};
+
+#endif // UNITS_MAGE_H

+ 183 - 0
include/units/unit.h

@@ -0,0 +1,183 @@
+#pragma once
+
+#include "AbstractFactory.h"
+
+#include <QObject>
+#include <QString>
+#include <QImage>
+
+#include <iostream>
+#include <vector>
+
+class Spell {
+public:
+    int a;
+};
+
+class Cell {
+	//waiting for a realisation
+public:
+	//must be in cell.h
+	bool isEmpty() { 
+		return true;
+	}
+	std::vector <Cell*> actualPath(Cell* destination) { //the shortest existing path from (*this) to (*destination)
+		std::vector <Cell*> path;
+		return path;
+	}
+};
+
+class Unit : public QObject {
+    Q_OBJECT
+
+public:
+    explicit Unit(QString parameters);
+
+    virtual ~Unit() {}
+
+    //---------------------------------------------//
+    //---------Basic traits getters section--------//
+    //---------------------------------------------//
+
+	double getExperience();
+	double getLevel();
+    int    getMovementSpeed();
+	double getInitiative();
+	double getDamagePerHit();
+
+	double getIntelligence();
+	double getStrength();
+	double getAgility();
+
+    int    getActivityPoints();
+    int    getAttackPoints();
+    int    getAttackCost();
+    double getAttackRange();
+
+    double getHealthPoints();
+
+    double getMagicDefence();
+	double getPhysicDefence();
+
+    int getCost();
+    void setCost(int value);
+
+    std::vector<QString> getParentSpecs();
+    std::vector<QString> getUpgradeSpecs();
+
+    //---------------------------------------------//
+    //------------Unit location section------------//
+    //---------------------------------------------//
+
+    Cell* getLocation();
+    void setLocation(Cell* to);
+
+	double getRealX();
+	void setRealX(double x);
+
+	double getRealY();
+	void setRealY(double y);
+
+
+    //---------------------------------------------//
+    //--------Damage checkers & calculators--------//
+    //---------------------------------------------//
+
+    virtual void calculateDamagePerHit();
+
+    virtual double reduceIncomingDamage(std::string damageType, int value);
+
+    virtual	bool canAttackForDistance(int distance) {}
+
+    virtual bool canAttackToCell(Cell* destination) {}
+
+    virtual bool canAttackUnit(Unit* target) {}
+
+    //---------------------------------------------//
+    //-------Movement checkers & calculators-------//
+    //---------------------------------------------//
+
+
+    int lenOfActualPath(Cell* destination);
+
+    virtual bool canMoveForDistance(int distance);
+
+    virtual bool canMoveToCell(Cell* destination);
+
+    virtual void moveToCell(Cell* destination);
+
+    //---------------------------------------------//
+    //----------------GUI section------------------//
+    //---------------------------------------------//
+
+    QString getUnitName() const;
+    QString getUnitDescr() const;
+    QString getUnitBaseClassId() const;
+    std::vector<QString> getUnitTraits() const;
+    QImage getUnitIcon() const;
+
+    //---------------------------------------------//
+    //-----------Parameters load section-----------//
+    //---------------------------------------------//
+
+private:
+    void loadUnitName(QString unit_folder);
+    void loadUnitDescr(QString unit_folder);
+    void loadUnitBaseClass(QString unit_folder);
+    void loadUnitTraits(QString unit_folder);
+    void loadUnitIcon(QString unit_folder);
+    void loadUnitPrevSpecs(QString unit_folder);
+    void loadUnitUpgradeSpecs(QString unit_folder);
+
+public:
+    bool operator <(const Unit &b) {
+        if (base_class_id_ != b.base_class_id_)
+            return base_class_id_ < b.base_class_id_;
+        return unit_id_ < b.unit_id_;
+    }
+
+protected:
+    std::vector <Spell> skills_;
+
+    //personal information
+    int cost_;
+
+    std::vector<QString> parent_specs_;
+    std::vector<QString> upgrade_specs_;
+
+    double experience_;
+    double level_;
+    std::string race_; //lower case
+
+    //actions and events
+    double initiative_;
+    int activity_points_;
+
+    //movement
+    Cell* location_;
+    int movement_speed_;	//how many cells can move for one activity point
+    double real_x_;
+    double real_y_;
+
+    //attack action
+    double agility_;
+    double attack_range_;
+    double damage_per_hit_;
+    double intelligence_;
+    double strength_;
+    int attack_cost_;     //how many activity points does attack cost
+
+    //durability
+    double health_points_;
+    double magic_defence_;  //less or equal 40
+    double physic_defence_; //less or equal 40
+
+    // GUI values
+    QString race_id_;
+    QString unit_id_;
+
+    QString unit_name_;
+    QString unit_descr_;
+    QString base_class_id_;
+    QImage unit_icon_;
+};

+ 15 - 0
include/units/warrior.h

@@ -0,0 +1,15 @@
+#ifndef UNITS_WARRIOR_H
+#define UNITS_WARRIOR_H
+
+#include "units/unit.h"
+
+#include <QObject>
+#include <QString>
+
+class Warrior : public Unit
+{
+public:
+    explicit Warrior(QString parameters);
+};
+
+#endif // UNITS_WARRIOR_H

+ 3 - 8
source/gui/guiscenemanager.cpp

@@ -16,15 +16,10 @@ GuiSceneManager::GuiSceneManager(QObject *parent) : QObject(parent) {
     changeScene("main_menu");
 }
 
-GuiSceneManager::~GuiSceneManager() {
-    delete gui_;
-    for (auto scene : scenes_) {
-        delete scene.second;
-    }
-}
+GuiSceneManager::~GuiSceneManager() {}
 
 
-bool GuiSceneManager::registerScene(QString scene_name, QWidget* name) {
+bool GuiSceneManager::registerScene(QString scene_name, Scene* name) {
     if (scene_name == "none")
         return false;
 
@@ -45,7 +40,7 @@ bool GuiSceneManager::changeScene(QString scene_name, QString args) {
     if (current_scene_ != "none")
         scenes_[current_scene_]->hide();
 
-    //scenes_[scene_name]->parseArgs(args);
+    scenes_[scene_name]->parseArgs(args);
     scenes_[scene_name]->show();
     current_scene_ = scene_name;
     return true;

+ 1 - 1
source/gui/mainmenu.cpp

@@ -6,7 +6,7 @@
 #include <QApplication>
 
 MainMenu::MainMenu(QWidget *parent) :
-    QWidget(parent),
+    Scene(parent),
     ui(new Ui::MainMenu)
 {
     ui->setupUi(this);

+ 7 - 2
source/gui/playervsplayerintro.cpp

@@ -1,9 +1,12 @@
 #include "gui/playervsplayerintro.h"
 #include "gui/guiscenemanager.h"
+#include "playermanager.h"
+#include "gui/scene.h"
+
 #include "ui_playervsplayerintro.h"
 
 PlayerVsPlayerIntro::PlayerVsPlayerIntro(QWidget *parent) :
-    QWidget(parent),
+    Scene(parent),
     ui(new Ui::PlayerVsPlayerIntro)
 {
     ui->setupUi(this);
@@ -21,5 +24,7 @@ void PlayerVsPlayerIntro::on_back_to_menu_clicked()
 
 void PlayerVsPlayerIntro::on_go_next_clicked()
 {
-    GuiSceneManager::getInstance().changeScene("recruit_army");
+    PlayerManager::getInstance().setPlayersNum(2);
+    /// TODO - Check if money input correct
+    GuiSceneManager::getInstance().changeScene("recruit_army", "1|" + ui->money_->text());
 }

+ 122 - 0
source/gui/raceicon.cpp

@@ -0,0 +1,122 @@
+#include <gui/raceicon.h>.h>
+#include <QDebug>
+#include <QTime>
+
+RaceIcon::RaceIcon(QWidget* parent, int width, int height)
+    : QLabel(parent)
+{
+    state_ = 0;
+    width_ = width;
+    height_ = height;
+
+    setAttribute(Qt::WA_Hover, true);
+    installEventFilter(this);
+
+    default_border_.load(":/assets/common/unit_icon_default.png");
+    hover_border_.load(":/assets/common/unit_icon_hover.png");
+    active_border_.load(":/assets/common/unit_icon_active.png");
+
+    drawIcon();
+}
+
+RaceIcon::~RaceIcon()
+{}
+
+void RaceIcon::drawIcon() {
+    QPixmap combined(width_, height_);
+    QPainter p(&combined);
+
+    if (state_ == 0) {
+        p.setBrush(Qt::NoBrush);
+        p.setPen(Qt::black);
+        p.drawRect(0, 0, width_, height_);
+    } else {
+        p.drawImage(QPoint(0, 0), icon_.scaled(width_, height_, Qt::KeepAspectRatio));
+    }
+
+    if (state_ == 0 || state_ == 1)
+        p.drawImage(QPoint(0, 0), default_border_.scaled(width_, height_, Qt::KeepAspectRatio));
+
+    if (state_ == 2)
+        p.drawImage(QPoint(0, 0), hover_border_.scaled(width_, height_, Qt::KeepAspectRatio));
+
+    if (state_ == 3)
+        p.drawImage(QPoint(0, 0), active_border_.scaled(width_, height_, Qt::KeepAspectRatio));
+
+    p.end();
+    setPixmap(combined);
+}
+
+void RaceIcon::setRaceIcon(QString racename) {
+    icon_.load(":/assets/units/" + racename + "/icon.png");
+    if (state_ == 0)
+        state_ = 1;
+    drawIcon();
+}
+
+void RaceIcon::setRaceIcon(QImage icon) {
+    icon_ = icon;
+    if (state_ == 0)
+        state_ = 1;
+    drawIcon();
+}
+
+
+void RaceIcon::unsetRaceIcon() {
+    state_ = 0;
+    drawIcon();
+}
+
+void RaceIcon::resize(int w, int h) {
+    width_ = w;
+    height_ = h;
+    drawIcon();
+}
+
+void RaceIcon::deactivate() {
+    if (state_ > 1)
+        state_ = 1;
+    drawIcon();
+}
+
+void RaceIcon::activate() {
+    state_ = 3;
+    drawIcon();
+}
+
+void RaceIcon::mousePressEvent(QMouseEvent*)
+{
+    if (state_ == 0)
+        return;
+
+    activate();
+
+    QTime current_time = QTime::currentTime();
+    if (current_time.msecsSinceStartOfDay() - previous_click_time_.msecsSinceStartOfDay() < 200) {
+        deactivate();
+        emit doubleclicked();
+    } else {
+        previous_click_time_ = current_time;
+        emit clicked();
+    }
+}
+
+void RaceIcon::enterEvent(QEvent*)
+{
+    if (state_ == 0 || state_ == 3)
+        return;
+
+    state_ = 2;
+    drawIcon();
+    emit hovered();
+}
+
+void RaceIcon::leaveEvent(QEvent*)
+{
+    if (state_ == 0 || state_ == 3)
+        return;
+
+    state_ = 1;
+    drawIcon();
+    emit unhovered();
+}

+ 54 - 1
source/gui/recruitmentscene.cpp

@@ -1,12 +1,22 @@
 #include <gui/recruitmentscene.h>
 #include <gui/uniticon.h>
+#include <gui/raceicon.h>
 #include <gui/guiscenemanager.h>
+#include <gui/scene.h>
+#include <playermanager.h>
+#include <player.h>
+#include <racemanager.h>
+#include <race.h>
 
 #include <ui_recruitmentscene.h>
 #include <QHBoxLayout>
+#include <QString>
+#include <QStringList>
+
+#include <cassert>
 
 RecruitmentScene::RecruitmentScene(QWidget *parent)
-    : QWidget(parent)
+    : Scene(parent)
     , ui(new Ui::RecruitmentScene)
 {
     ui->setupUi(this);
@@ -52,6 +62,49 @@ RecruitmentScene::~RecruitmentScene()
     delete ui;
 }
 
+void RecruitmentScene::parseArgs(QString args) {
+    QStringList list = args.split("|");
+    assert(list.size() >= 2);
+
+    current_player_id_ = list[0].toInt();
+    current_player_ = PlayerManager::getInstance().getPlayer(current_player_id_);
+    available_money_ = list[1].toInt();
+}
+
+void RecruitmentScene::init() {
+    current_money_ = available_money_;
+    initAvailableRaces();
+    initAvailableUnits();
+    initChosenUnits();
+}
+
+void RecruitmentScene::initAvailableRaces() {
+    auto races = RaceManager::getInstance().getAvailableRacesList();
+
+    int race_id = 0;
+    for (QString race_name : races) {
+        assert(race_id < 5);
+        auto race = RaceManager::getInstance().getRace(race_name);
+        available_races_icons_[race_id]->setRaceIcon(race_name);
+        race_id++;
+    }
+
+
+}
+
+void RecruitmentScene::initAvailableUnits() {
+    int unit_id = 0;
+    for (Unit* unit : current_player_->getRace()->getAllUnitsList()) {
+        available_units_icons_[unit_id]->setUnitIcon(unit->getUnitIcon());
+        unit_id++;
+    }
+}
+
+void RecruitmentScene::initChosenUnits() {
+
+}
+
+
 void RecruitmentScene::on_back_button_clicked()
 {
     GuiSceneManager::getInstance().changeScene("main_menu");

+ 6 - 0
source/gui/scene.cpp

@@ -0,0 +1,6 @@
+#include "gui/scene.h"
+
+Scene::Scene(QWidget *parent) : QWidget(parent)
+{
+
+}

+ 7 - 0
source/gui/uniticon.cpp

@@ -55,6 +55,13 @@ void UnitIcon::setUnitIcon(QString racename, QString unitname) {
     drawIcon();
 }
 
+void UnitIcon::setUnitIcon(QImage icon) {
+    icon_ = icon;
+    if (state_ == 0)
+        state_ = 1;
+    drawIcon();
+}
+
 void UnitIcon::unsetUnitIcon() {
     state_ = 0;
     drawIcon();

+ 2 - 1
source/main.cpp

@@ -8,6 +8,7 @@ int main(int argc, char *argv[])
 {
     QApplication a(argc, argv);
 
-    GuiSceneManager::getInstance().changeScene("main_menu");
+    GuiSceneManager::getInstance();
+
     return a.exec();
 }

+ 0 - 6
source/player.cpp

@@ -1,6 +0,0 @@
-#include <player.h>
-
-Player::Player(QObject *parent) : QObject(parent)
-{
-
-}

+ 23 - 0
source/playermanager.cpp

@@ -0,0 +1,23 @@
+#include "playermanager.h"
+
+#include <cassert>
+
+PlayerManager::PlayerManager(QObject *parent) : QObject(parent)
+{
+
+}
+
+Player* PlayerManager::getPlayer(int id) {
+    assert(id < players_.size());
+    return &players_[id];
+}
+
+int PlayerManager::getPlayersNum() {
+    return players_.size();
+}
+
+void PlayerManager::setPlayersNum(int num) {
+    players_.resize(num);
+    for (int i = 0; i < num; i++)
+        players_[i].init(i);
+}

+ 74 - 0
source/race.cpp

@@ -0,0 +1,74 @@
+#include "race.h"
+#include "units/unit.h"
+#include "units/warrior.h"
+#include "units/mage.h"
+
+#include <QFile>
+#include <QTextStream>
+#include <QString>
+
+#include <cassert>
+#include <vector>
+#include <algorithm>
+
+Race::Race(QString race_name, QObject *parent) : QObject(parent)
+{
+    race_id_ = race_name;
+
+    units_factory_.addClass<Warrior, QString>("Warrior");
+    units_factory_.addClass<Warrior, QString>("Mage");
+
+    QFile file(":/assets/units/" + race_name + "/units.txt");
+    QTextStream in(&file);
+    QString unit_name = in.readLine();
+
+    while (!in.atEnd()) {
+        all_units_list_.push_back(createUnit(unit_name));
+        available_units_list_.push_back(unit_name);
+        unit_name = in.readLine();
+    }
+
+    QFile file0(":/assets/units/" + race_name + "/racename.txt");
+    QTextStream in0(&file);
+    race_name_ = in0.readLine();
+
+    QFile file1(":/assets/units/" + race_name + "/descr.txt");
+    QTextStream in1(&file);
+    race_descr_ = in1.readAll();
+
+    race_icon_.load(":/assets/units/" + race_name + "/descr.txt");
+}
+
+QString Race::getRaceId() {
+    return race_id_;
+}
+
+QString Race::getRaceName() {
+    return race_name_;
+}
+
+QImage Race::getRaceIcon() {
+    return race_icon_;
+}
+
+QString Race::getRaceDescr() {
+    return race_descr_;
+}
+
+Unit* Race::createUnit(QString unit_name) {
+    assert(std::count(available_units_list_.begin(), available_units_list_.end(), unit_name) != 0);
+
+    QFile file(":/asserts/units/" + race_id_ + "/" + unit_name + "/baseclass.txt");
+    QTextStream in(&file);
+    QString class_id = in.readLine();
+
+    return units_factory_.createObject<QString>(class_id, race_id_ + "|" + unit_name);
+}
+
+const std::vector<QString>& Race::getAvailableUnitsList() {
+    return available_units_list_;
+}
+
+const std::vector<Unit*> &Race::getAllUnitsList() {
+    return all_units_list_;
+}

+ 37 - 0
source/racemanager.cpp

@@ -0,0 +1,37 @@
+#include "racemanager.h"
+#include "race.h"
+
+#include <QFile>
+#include <QTextStream>
+#include <QDebug>
+
+RaceManager::RaceManager(QObject *parent) : QObject(parent)
+{
+    QFile file(":/assets/units/raceslist.txt");
+    QTextStream in(&file);
+    QString race_name = in.readLine();
+
+    while(!in.atEnd()) {
+        if (races_.count(race_name) != 0) {
+            qWarning() << "Warning! found double occurences of races in raceslist.txt";
+            continue;
+        }
+
+        available_races_.push_back(race_name);
+        races_[race_name] = new Race(race_name);
+        race_name = in.readLine();
+    }
+}
+
+Race* RaceManager::getRace(QString race_name) {
+    if (races_.count(race_name) == 0) {
+        qWarning() << "Error! Not found race with name " << race_name;
+        return nullptr;
+    }
+
+    return races_[race_name];
+}
+
+const std::vector<QString>& RaceManager::getAvailableRacesList() {
+    return available_races_;
+}

+ 7 - 0
source/units/mage.cpp

@@ -0,0 +1,7 @@
+#include "units/mage.h"
+#include "units/unit.h"
+
+Mage::Mage(QString parameters) : Unit(parameters)
+{
+
+}

+ 105 - 68
source/unit.cpp → source/units/unit.cpp

@@ -1,72 +1,120 @@
+#include "AbstractFactory.h"
+#include "units/unit.h"
+
 #include <iostream>
 #include <algorithm>
 #include <cassert>
 #include <string>
-#include "unit.h"
-#include "AbstractFactory.h"
 
-int Unit::getCost(){
-	return cost_;
+#include <QFile>
+#include <QString>
+#include <QTextStream>
+
+Unit::Unit(QString parameters) {
+    QStringList params = parameters.split("|");
+
+    assert(params.size() >= 2);
+
+    unit_id_ = params[0];
+    race_id_ = params[1];
+
+    QString unit_folder = ":/assets/units/" + race_id_ + "/" + unit_id_ + "/";
+
+    loadUnitName(unit_folder);
+    loadUnitDescr(unit_folder);
+    loadUnitBaseClass(unit_folder);
+    loadUnitTraits(unit_folder);
+    loadUnitIcon(unit_folder);
+    loadUnitPrevSpecs(unit_folder);
+    loadUnitUpgradeSpecs(unit_folder);
 }
 
-void Unit::setCost(int value){
-	cost_ = value;
+void Unit::loadUnitName(QString unit_folder) {
+    QFile file(unit_folder + "unitname.txt");
+    QTextStream in(&file);
+    unit_name_ = in.readLine();
 }
 
-std::string Unit::getParentSpec(){
-	return parent_spec_;
+void Unit::loadUnitDescr(QString unit_folder) {
+    QFile file(unit_folder + "descr.txt");
+    QTextStream in(&file);
+    unit_descr_ = in.readAll();
 }
 
-void Unit::setParentSpec(std::string specId){
-	parent_spec_ = specId;
+void Unit::loadUnitBaseClass(QString unit_folder) {
+    QFile file(unit_folder + "baseclass.txt");
+    QTextStream in(&file);
+    base_class_id_ = in.readLine();
 }
 
-std::vector<std::string> Unit::getUpgradeSpecs(){
-	return upgrade_specs_;
+void Unit::loadUnitTraits(QString unit_folder) {
+   // TO BE DONE!!!
+    health_points_ = rand();
+    activity_points_ = rand();
+    attack_cost_ = rand();
+    attack_range_ = rand();
 }
 
-void Unit::setUpgradeSpecs(std::vector<std::string> specs){
-	upgrade_specs_ = specs;
+void Unit::loadUnitIcon(QString unit_folder) {
+    unit_icon_.load(unit_folder + "icon.png");
+}
+
+void Unit::loadUnitPrevSpecs(QString unit_folder) {
+    QFile file(unit_folder + "prevgrades.txt");
+    QTextStream in(&file);
+    QString line = in.readLine();
+    while (in.atEnd()) {
+        parent_specs_.push_back(line);
+        line = in.readLine();
+    }
+}
+
+void Unit::loadUnitUpgradeSpecs(QString unit_folder) {
+    QFile file(unit_folder + "nextgrades.txt");
+    QTextStream in(&file);
+    QString line = in.readLine();
+    while (in.atEnd()) {
+        upgrade_specs_.push_back(line);
+        line = in.readLine();
+    }
+}
+
+int Unit::getCost(){
+	return cost_;
+}
+
+std::vector<QString> Unit::getParentSpecs(){
+    return parent_specs_;
+}
+
+std::vector<QString> Unit::getUpgradeSpecs(){
+	return upgrade_specs_;
 }
 
 double Unit::getExperience() {
 	return experience_;
 }
-void Unit::setExperience(double value) {
-	experience_ = value;
-}
 
 double Unit::getLevel() {
 	return level_;
-};
-void Unit::setLevel(double value) {
-	level_ = value;
 }
 
 double Unit::getHealthPoints() {
 	return health_points_;
-};
-void Unit::setHealthPoints(double value) {
-	health_points_ = value;
 }
 
 double Unit::getAttackRange() {
 	return attack_range_;
 }
-void Unit::setAttackRange(double value) {
-	attack_range_ = value;
-}
 
 int Unit::getActivityPoints(){
 	return activity_points_;
 }
-void Unit::setActivityPoints(int value){
-	activity_points_ = value;
-}
 
 Cell* Unit::getLocation() {
 	return location_;
 }
+
 void Unit::setLocation(Cell* to) {
 	location_ = to;
 }
@@ -74,83 +122,47 @@ void Unit::setLocation(Cell* to) {
 int Unit::getMovementSpeed() {
 	return movement_speed_;
 }
-void Unit::setMovementSpeed(int value) {
-	movement_speed_ = value;
-}
 
 int Unit::getAttackCost(){
 	return attack_cost_;
 }
-void Unit::setAttackCost(int value){
-	attack_cost_ = value;
-}
 
 double Unit::getInitiative() {
 	return initiative_;
 }
-void Unit::setInitiative(double value) {
-	initiative_ = value;
-}
 
 double Unit::getDamagePerHit() {
 	return damage_per_hit_;
 }
-void Unit::setDamagePerHit(double value) {
-	damage_per_hit_ = value;
-}
 
 double Unit::getIntelligence() {
 	return intelligence_;
 }
-void Unit::setIntelligence(double value) {
-	intelligence_ = value;
-}
 
 double Unit::getStrength() {
 	return strength_;
 }
-void Unit::setStrength(double value) {
-	strength_ = value;
-}
 
 double Unit::getAgility() {
 	return agility_;
 }
-void Unit::setAgility(double value) {
-	agility_ = value;
-}
 
 int Unit::getAttackPoints(){
 	return attack_cost_;
 }
-void Unit::setAttackPoints(int value){
-	attack_cost_ = value;
-}
 
 double Unit::getMagicDefence() {
 	return magic_defence_;
 }
-void Unit::setMagicDefence(double value) {
-	magic_defence_ = value;
-}
 
 double Unit::getPhysicDefence() {
 	return physic_defence_;
 }
-void Unit::setPhysicDefence(double value) {
-	physic_defence_ = value;
-}
-
-std::string Unit::getRace() {
-	return race_;
-}
-void Unit::setRace(std::string new_race) {
-	race_ = new_race;
-}
 
 double Unit::getRealX() {
 	return real_x_;
 }
+
 void Unit::setRealX(double x) {
 	real_x_ = x;
 }
@@ -158,6 +170,7 @@ void Unit::setRealX(double x) {
 double Unit::getRealY() {
 	return real_y_;
 }
+
 void Unit::setRealY(double y) {
 	real_y_ = y;
 }
@@ -195,8 +208,32 @@ void Unit::moveToCell(Cell* destination) {
 	if (!canMoveToCell(destination))
 		return;	//here could be a gui-message about failed move (x-mark, for example)
 	else {
-		int decreasedValue = getMovementSpeed() - lenOfActualPath(destination);
-		setMovementSpeed(decreasedValue);
+        movement_speed_ -= lenOfActualPath(destination);
 		setLocation(destination);
 	}
 }
+
+QString Unit::getUnitName() const {
+    return unit_name_;
+}
+
+QString Unit::getUnitDescr() const {
+    return unit_descr_;
+}
+
+QString Unit::getUnitBaseClassId() const {
+    return base_class_id_;
+}
+
+std::vector<QString> Unit::getUnitTraits() const {
+    return {
+            QString::number(health_points_),
+            QString::number(attack_range_),
+            QString::number(activity_points_),
+            QString::number(initiative_)
+    };
+}
+
+QImage Unit::getUnitIcon() const {
+    return unit_icon_;
+}

+ 7 - 0
source/units/warrior.cpp

@@ -0,0 +1,7 @@
+#include "units/warrior.h"
+#include "units/unit.h"
+
+Warrior::Warrior(QString parameters) : Unit(parameters)
+{
+
+}