From 621aab73d479c78156816d488255317226df8331 Mon Sep 17 00:00:00 2001
From: EndrII <EndrIIMail@gmail.com>
Date: Wed, 4 Aug 2021 16:47:55 +0300
Subject: [PATCH 01/19] ref #98 rename the IPlayer to the PlayableObject

---
 src/Core/Crawl/iworld.cpp                     |  7 +-
 src/Core/Crawl/iworld.h                       |  9 +--
 .../Crawl/{iplayer.cpp => playableobject.cpp} | 32 ++-------
 .../Crawl/{iplayer.h => playableobject.h}     | 71 ++++++++-----------
 src/Core/Crawl/snake.cpp                      |  4 +-
 src/Core/Crawl/snake.h                        |  4 +-
 src/Core/CrawlModule/qmldir                   |  4 --
 src/CrawlAbstractLvl/private/abslvlworld.cpp  |  2 +-
 src/CrawlAbstractLvl/private/abslvlworld.h    |  2 +-
 src/CrawlTestLvl/private/world.cpp            |  2 +-
 src/CrawlTestLvl/private/world.h              |  2 +-
 src/JungleLvl/private/world.cpp               |  2 +-
 src/JungleLvl/private/world.h                 |  2 +-
 tests/units/clasterstest.cpp                  |  2 +-
 14 files changed, 52 insertions(+), 93 deletions(-)
 rename src/Core/Crawl/{iplayer.cpp => playableobject.cpp} (59%)
 rename src/Core/Crawl/{iplayer.h => playableobject.h} (52%)

diff --git a/src/Core/Crawl/iworld.cpp b/src/Core/Crawl/iworld.cpp
index 995c55d..61df549 100644
--- a/src/Core/Crawl/iworld.cpp
+++ b/src/Core/Crawl/iworld.cpp
@@ -58,11 +58,6 @@ void IWorld::render(unsigned int tbfMsec) {
 
     _ItemsMutex.unlock();
 
-
-    if (_player->isDead()) {
-        emit sigGameFinished(_player->getCurrentStatus());
-    }
-
     updateWorld();
 
     int waitTime = 1000 / _targetFps - tbfMsec;
@@ -101,7 +96,7 @@ void IWorld::setPlayer(QObject *newPlayer) {
     if (_player == newPlayer)
         return;
 
-    auto newPlayerObject = dynamic_cast<IPlayer*>(newPlayer);
+    auto newPlayerObject = dynamic_cast<PlayableObject*>(newPlayer);
     if (!newPlayerObject) {
         QuasarAppUtils::Params::log("Failed to set player object. The input object is not player.",
                                     QuasarAppUtils::Error);
diff --git a/src/Core/Crawl/iworld.h b/src/Core/Crawl/iworld.h
index 54c2e5e..6f8a433 100644
--- a/src/Core/Crawl/iworld.h
+++ b/src/Core/Crawl/iworld.h
@@ -8,7 +8,8 @@
 #ifndef CRAWL_IWORLD_H
 #define CRAWL_IWORLD_H
 
-#include "iplayer.h"
+#include "gameresult.h"
+#include "playableobject.h"
 
 #include <QHash>
 #include <QMap>
@@ -26,7 +27,7 @@ class ClastersTest;
 namespace CRAWL {
 
 class IWorldItem;
-class IPlayer;
+class PlayableObject;
 class GroundClaster;
 class IControl;
 class IAI;
@@ -67,7 +68,7 @@ public:
      * @note The Palyer object will be deleted when wold distroed.
      *  So do not delete your created player pbject yuorself.
      */
-    virtual IPlayer* initPlayer() const = 0;
+    virtual PlayableObject* initPlayer() const = 0;
 
     /**
      * @brief initWorldRules The implementation of this interface must be retun initialized list of the world rules.
@@ -494,7 +495,7 @@ private:
     WorldRule *_worldRules = nullptr;
     WorldRule::const_iterator _currendWorldLevel;
 
-    IPlayer *_player = nullptr;
+    PlayableObject *_player = nullptr;
     IControl *_userInterface = nullptr;
     IAI *_backgroundAI = nullptr;
     int _worldStatus = 0;
diff --git a/src/Core/Crawl/iplayer.cpp b/src/Core/Crawl/playableobject.cpp
similarity index 59%
rename from src/Core/Crawl/iplayer.cpp
rename to src/Core/Crawl/playableobject.cpp
index ed9f5ff..f34831f 100644
--- a/src/Core/Crawl/iplayer.cpp
+++ b/src/Core/Crawl/playableobject.cpp
@@ -6,55 +6,35 @@
 //#
 
 #include "defaultcontrol.h"
-#include "iplayer.h"
+#include "playableobject.h"
 
 namespace CRAWL {
 
 
-IPlayer::IPlayer(const QString &name,
+PlayableObject::PlayableObject(const QString &name,
                  const QString &viewTempalte,
                  QObject *ptr):
     IWorldItem(name, viewTempalte, ptr) {
 
 }
 
-GameResult IPlayer::getCurrentStatus() const {
-    return {_currentPoints, static_cast<int>(position().distanceToPoint({0,0,0}))};
-}
-
-bool IPlayer::isDead() const {
-    return _fDead;
-}
-
-void IPlayer::reward(int value) {
-    _currentPoints += value;
-}
-
-void IPlayer::fine(int value) {
-    _currentPoints -= value;
-}
-
-void IPlayer::render(unsigned int tbfMsec) {
+void PlayableObject::render(unsigned int tbfMsec) {
     MovableObject::render(tbfMsec);
 }
 
-void IPlayer::setControl(const IControl *control) {
+void PlayableObject::setControl(const IControl *control) {
 
 
     if (auto oldControl = dynamic_cast<const DefaultControl*>(_currentControl)) {
-        disconnect(oldControl, &DefaultControl::userTap, this, &IPlayer::onTap);
+        disconnect(oldControl, &DefaultControl::userTap, this, &PlayableObject::onTap);
     }
 
     auto defaultControl = dynamic_cast<const DefaultControl*>(control);
     _currentControl = defaultControl;
 
     if (_currentControl) {
-        connect(defaultControl, &DefaultControl::userTap, this, &IPlayer::onTap);
+        connect(defaultControl, &DefaultControl::userTap, this, &PlayableObject::onTap);
     }
 }
 
-void IPlayer::kill() {
-    _fDead = true;
-}
-
 }
diff --git a/src/Core/Crawl/iplayer.h b/src/Core/Crawl/playableobject.h
similarity index 52%
rename from src/Core/Crawl/iplayer.h
rename to src/Core/Crawl/playableobject.h
index 76f7a97..5b150cc 100644
--- a/src/Core/Crawl/iplayer.h
+++ b/src/Core/Crawl/playableobject.h
@@ -5,10 +5,9 @@
 //# of this license document, but changing it is not allowed.
 //#
 
-#ifndef IPLAYER_H
-#define IPLAYER_H
+#ifndef PLAYABLEOBJECT_H
+#define PLAYABLEOBJECT_H
 
-#include "gameresult.h"
 #include "global.h"
 #include "iworlditem.h"
 #include "Extensions/movableobject.h"
@@ -19,56 +18,46 @@ namespace CRAWL {
 class IControl;
 
 /**
- * @brief The IPlayer class This is base class of the player functions.
+ * @brief The PlayableObject class support works withe the IControl child classes.
+ * **How to is works**? You need to override the  PlayableObject::setControl method for adding your own cpntroll classes. By Default This class use The DefaultControl class.
  */
-class CRAWL_EXPORT IPlayer: public IWorldItem, public MovableObject {
+class CRAWL_EXPORT PlayableObject: public IWorldItem, public MovableObject {
     Q_OBJECT
 public:
-    IPlayer(const QString& name,
+    PlayableObject(const QString& name,
             const QString& viewTempalte = DEFAULT_VIEW_TEMPLATE,
             QObject *ptr = nullptr);
 
-    /**
-     * @brief getCurrentStatus This method return current game state of the player.
-     * @return current gameState.
-     */
-    GameResult getCurrentStatus() const;
-
-    /**
-     * @brief isDead This method return true if your player are dead.
-     * @return true if a player are dead.
-     */
-    bool isDead() const;
-
     /**
      * @brief setControl This method should be connect player object with control object.
      * @param control This is control object.
      * @note This method can invoked two or more times, for example connect with AI control object and player control object. So your implementation should be contains disconnect methods.
+     *
+     * ### Example of use
+     *
+     * @code{cpp}
+        void MyPlayableObject::setControl(const IControl *control) {
+
+
+            if (auto oldControl = dynamic_cast<const DefaultControl*>(_currentControl)) {
+                disconnect(oldControl, &DefaultControl::userTap, this, &PlayableObject::onTap);
+                // some disconnect methodots
+            }
+
+            auto defaultControl = dynamic_cast<const DefaultControl*>(control);
+            _currentControl = defaultControl;
+
+            if (_currentControl) {
+                connect(defaultControl, &DefaultControl::userTap, this, &PlayableObject::onTap);
+                // some connect methodots
+
+            }
+        }
+     * @endcode
      */
     virtual void setControl(const IControl* control);
 
 protected:
-
-    /**
-     * @brief kill This method kill your player.
-     *  Invoke this method when you want to kell your player.
-     */
-    void kill();
-
-    /**
-     * @brief reward This method add reward for player.
-     * @param value This is new value;
-     * @note This method increment current value.
-     */
-    void reward(int value);
-
-    /**
-     * @brief fine This method remove reward for player.
-     * @param value This is fine amount;
-     * @note This method decriment current points value.
-     */
-    void fine(int value);
-
     void render(unsigned int tbfMsec) override;
 
 protected slots:
@@ -80,12 +69,10 @@ protected slots:
 
 
 private:
-    bool _fDead = false;
-    int _currentPoints = 0;
     const IControl * _currentControl = nullptr;
 
 };
 
 }
 
-#endif // IPLAYER_H
+#endif // PLAYABLEOBJECT_H
diff --git a/src/Core/Crawl/snake.cpp b/src/Core/Crawl/snake.cpp
index 1142c05..9c14643 100644
--- a/src/Core/Crawl/snake.cpp
+++ b/src/Core/Crawl/snake.cpp
@@ -15,7 +15,7 @@ namespace CRAWL {
 
 
 Snake::Snake(const QString &name, const QString &viewTempalte, QObject *ptr):
-    IPlayer (name, viewTempalte, ptr) {
+    PlayableObject (name, viewTempalte, ptr) {
 
     _vectors = new QVector3D[2];
     setAngularVelocity(100);
@@ -39,7 +39,7 @@ Snake::~Snake( ){
 }
 
 void Snake::render(unsigned int tbfMsec) {
-    IPlayer::render(tbfMsec);
+    PlayableObject::render(tbfMsec);
 }
 
 void Snake::add(ClasterItem *object) {
diff --git a/src/Core/Crawl/snake.h b/src/Core/Crawl/snake.h
index 7a32877..497e4d3 100644
--- a/src/Core/Crawl/snake.h
+++ b/src/Core/Crawl/snake.h
@@ -8,7 +8,7 @@
 #ifndef CRAWL_SNAKE_H
 #define CRAWL_SNAKE_H
 
-#include "iplayer.h"
+#include "playableobject.h"
 #include "Extensions/autogenerateclaster.h"
 
 namespace CRAWL {
@@ -18,7 +18,7 @@ class SnakeItem;
 /**
  * @brief The Snake class This class implement render mehod for snake object.
  */
-class CRAWL_EXPORT Snake : public IPlayer, public AutoGenerateClaster
+class CRAWL_EXPORT Snake : public PlayableObject, public AutoGenerateClaster
 {
     Q_OBJECT
 public:
diff --git a/src/Core/CrawlModule/qmldir b/src/Core/CrawlModule/qmldir
index d6f71f8..925eebe 100644
--- a/src/Core/CrawlModule/qmldir
+++ b/src/Core/CrawlModule/qmldir
@@ -4,7 +4,3 @@ DefaultMenu 1.0 DefaultMenu.qml
 GraphicItem 1.0 GraphicItem.qml
 ParticleEffect 1.0 ParticleEffect.qml
 Light 1.0 Light.qml
-GraphicItem 1.0 GraphicItem.qml
-GraphicItem 1.0 GraphicItem.qml
-GraphicItem 1.0 GraphicItem.qml
-GraphicItem 1.0 GraphicItem.qml
diff --git a/src/CrawlAbstractLvl/private/abslvlworld.cpp b/src/CrawlAbstractLvl/private/abslvlworld.cpp
index 0e286c9..5b3aeee 100644
--- a/src/CrawlAbstractLvl/private/abslvlworld.cpp
+++ b/src/CrawlAbstractLvl/private/abslvlworld.cpp
@@ -23,7 +23,7 @@ AbsLvlWorld::AbsLvlWorld() {
     setCameraRotation(QQuaternion::fromEulerAngles({0,0,0}));
 }
 
-CRAWL::IPlayer *AbsLvlWorld::initPlayer() const {
+CRAWL::PlayableObject *AbsLvlWorld::initPlayer() const {
     return new AbsLvlSnake();
 }
 
diff --git a/src/CrawlAbstractLvl/private/abslvlworld.h b/src/CrawlAbstractLvl/private/abslvlworld.h
index 773336b..2f075cf 100644
--- a/src/CrawlAbstractLvl/private/abslvlworld.h
+++ b/src/CrawlAbstractLvl/private/abslvlworld.h
@@ -20,7 +20,7 @@ public:
     AbsLvlWorld();
 
 
-    CRAWL::IPlayer *initPlayer() const override;
+    CRAWL::PlayableObject *initPlayer() const override;
     CRAWL::WorldRule *initWorldRules() override;
     QString initHdrBackGround() const override;
     QString description() const override;
diff --git a/src/CrawlTestLvl/private/world.cpp b/src/CrawlTestLvl/private/world.cpp
index bdfa823..281bb39 100644
--- a/src/CrawlTestLvl/private/world.cpp
+++ b/src/CrawlTestLvl/private/world.cpp
@@ -73,7 +73,7 @@ void World::initPlayerControl(CRAWL::IControl *control) {
     return IWorld::initPlayerControl(control);
 }
 
-CRAWL::IPlayer *World::initPlayer() const {
+CRAWL::PlayableObject *World::initPlayer() const {
     return new TestSnake();
 }
 
diff --git a/src/CrawlTestLvl/private/world.h b/src/CrawlTestLvl/private/world.h
index 7c45e9d..f8038f7 100644
--- a/src/CrawlTestLvl/private/world.h
+++ b/src/CrawlTestLvl/private/world.h
@@ -28,7 +28,7 @@ public:
     int costToUnlock() const override;
     CRAWL::IControl *initUserInterface() const override;
     void initPlayerControl(CRAWL::IControl *control) override;
-    CRAWL::IPlayer *initPlayer() const override;
+    CRAWL::PlayableObject *initPlayer() const override;
     CRAWL::IAI *initBackGroundAI() const override;
 
 private slots:
diff --git a/src/JungleLvl/private/world.cpp b/src/JungleLvl/private/world.cpp
index 62db223..b036387 100644
--- a/src/JungleLvl/private/world.cpp
+++ b/src/JungleLvl/private/world.cpp
@@ -108,7 +108,7 @@ void World::initPlayerControl(CRAWL::IControl *control) {
     return IWorld::initPlayerControl(control);
 }
 
-CRAWL::IPlayer *World::initPlayer() const {
+CRAWL::PlayableObject *World::initPlayer() const {
     return new Snake();
 }
 
diff --git a/src/JungleLvl/private/world.h b/src/JungleLvl/private/world.h
index 5862250..98bf398 100644
--- a/src/JungleLvl/private/world.h
+++ b/src/JungleLvl/private/world.h
@@ -27,7 +27,7 @@ public:
     int costToUnlock() const override;
     CRAWL::IControl *initUserInterface() const override;
     void initPlayerControl(CRAWL::IControl *control) override;
-    CRAWL::IPlayer *initPlayer() const override;
+    CRAWL::PlayableObject *initPlayer() const override;
     CRAWL::IAI *initBackGroundAI() const override;
 
 private slots:
diff --git a/tests/units/clasterstest.cpp b/tests/units/clasterstest.cpp
index f48f62a..219c0e6 100644
--- a/tests/units/clasterstest.cpp
+++ b/tests/units/clasterstest.cpp
@@ -45,7 +45,7 @@ public:
 
     // IWorld interface
 public:
-    CRAWL::IPlayer *initPlayer() const {return nullptr;};
+    CRAWL::PlayableObject *initPlayer() const {return nullptr;};
     CRAWL::WorldRule *initWorldRules() {return nullptr;};
     QString initHdrBackGround() const {return "";};
     QString description() const {return "";};

From f3df22ff1ee1b932e970d4564f67308b70bb5b80 Mon Sep 17 00:00:00 2001
From: EndrII <EndrIIMail@gmail.com>
Date: Thu, 5 Aug 2021 18:43:01 +0300
Subject: [PATCH 02/19] added event server

---
 src/Core/Crawl/iworld.cpp            | 11 +++++-----
 src/Core/Crawl/iworld.h              |  3 +++
 src/Core/CrawlModule/GraphicItem.qml |  3 +++
 src/Core/Extensions/basemotion.h     |  1 +
 src/Core/private/eventserver.cpp     | 27 +++++++++++++++++++++++
 src/Core/private/eventserver.h       | 33 ++++++++++++++++++++++++++++
 6 files changed, 73 insertions(+), 5 deletions(-)
 create mode 100644 src/Core/private/eventserver.cpp
 create mode 100644 src/Core/private/eventserver.h

diff --git a/src/Core/Crawl/iworld.cpp b/src/Core/Crawl/iworld.cpp
index 61df549..f82c12f 100644
--- a/src/Core/Crawl/iworld.cpp
+++ b/src/Core/Crawl/iworld.cpp
@@ -19,6 +19,7 @@
 #include "thread"
 #include "chrono"
 #include "diff.h"
+#include "eventserver.h"
 
 namespace CRAWL {
 
@@ -26,10 +27,13 @@ namespace CRAWL {
 IWorld::IWorld() {
     qRegisterMetaType<WorldRule::const_iterator>("WorldRule::const_iterator");
     connect(this, &IWorld::sigWorldChanged, this, &IWorld::worldChanged, Qt::QueuedConnection);
+
+    _eventServer = new EventServer;
 }
 
 IWorld::~IWorld() {
     reset();
+    delete _eventServer;
 }
 
 void IWorld::init() {prepare();}
@@ -50,17 +54,14 @@ void IWorld::render(unsigned int tbfMsec) {
     for (auto i = _items.begin(); i != _items.end(); ++i) {
         (*i)->render(tbfMsec);
 
-        // intersects event.
-        if ((*i)->intersects(*_player)) {
-            _player->onIntersects((*i));
-        }
+        _eventServer->process(*i);
     }
 
     _ItemsMutex.unlock();
 
     updateWorld();
 
-    int waitTime = 1000 / _targetFps - tbfMsec;
+    int waitTime = 1000 / targetFps() - tbfMsec;
     if (waitTime > 0)
         std::this_thread::sleep_for(std::chrono::milliseconds(waitTime));
 }
diff --git a/src/Core/Crawl/iworld.h b/src/Core/Crawl/iworld.h
index 6f8a433..d06fcb7 100644
--- a/src/Core/Crawl/iworld.h
+++ b/src/Core/Crawl/iworld.h
@@ -32,6 +32,7 @@ class GroundClaster;
 class IControl;
 class IAI;
 class IWorldLight;
+class EventServer;
 
 /**
  * @brief WorldObjects This is map list of the avalable objects and its count on a lvl-long point.
@@ -482,6 +483,8 @@ private:
     void removeAnyItemFromGroup(const QString &group,
                                 QList<int>* removedObjectsList = nullptr);
 
+    EventServer * _eventServer = nullptr;
+
     QHash<int, IWorldItem*> _items;
     QMultiHash<QString, int> _itemsGroup;
     QMultiHash<QString, int> _lastItemsGroup;
diff --git a/src/Core/CrawlModule/GraphicItem.qml b/src/Core/CrawlModule/GraphicItem.qml
index af312be..6ff4224 100644
--- a/src/Core/CrawlModule/GraphicItem.qml
+++ b/src/Core/CrawlModule/GraphicItem.qml
@@ -66,6 +66,9 @@ Model {
     ]
 
     rotation: (model)? model.rotation: Qt.quaternion(0, 0, 0, 0)
+
+
+
     scale: (model)? model.size: Qt.vector3d(0, 0, 0);
     source: (model)? model.mash: "#Cube";
     position: (model) ? model.position: Qt.vector3d(0,0,0);
diff --git a/src/Core/Extensions/basemotion.h b/src/Core/Extensions/basemotion.h
index 2752458..69da274 100644
--- a/src/Core/Extensions/basemotion.h
+++ b/src/Core/Extensions/basemotion.h
@@ -22,6 +22,7 @@ class GuiObject;
  * For Create your own motion alghoritm you need to override two methods:
  *  * renderPosition
  *  * renderRotation
+ *
  */
 class CRAWL_EXPORT BaseMotion : public virtual IRender
 {
diff --git a/src/Core/private/eventserver.cpp b/src/Core/private/eventserver.cpp
new file mode 100644
index 0000000..c4e822b
--- /dev/null
+++ b/src/Core/private/eventserver.cpp
@@ -0,0 +1,27 @@
+//#
+//# Copyright (C) 2021-2021 QuasarApp.
+//# Distributed under the GPLv3 software license, see the accompanying
+//# Everyone is permitted to copy and distribute verbatim copies
+//# of this license document, but changing it is not allowed.
+//#
+
+#include "eventserver.h"
+
+#include <Crawl/iworlditem.h>
+
+namespace CRAWL {
+
+EventServer::EventServer() {
+
+}
+
+void EventServer::process(IWorldItem *item) {
+    // intersects event.
+
+
+
+//    if ((item)->intersects(*_player)) {
+//        _player->onIntersects((*i));
+//    }
+}
+}
diff --git a/src/Core/private/eventserver.h b/src/Core/private/eventserver.h
new file mode 100644
index 0000000..272285b
--- /dev/null
+++ b/src/Core/private/eventserver.h
@@ -0,0 +1,33 @@
+//#
+//# Copyright (C) 2021-2021 QuasarApp.
+//# Distributed under the GPLv3 software license, see the accompanying
+//# Everyone is permitted to copy and distribute verbatim copies
+//# of this license document, but changing it is not allowed.
+//#
+
+
+#ifndef EVENTSERVER_H
+#define EVENTSERVER_H
+
+namespace CRAWL {
+
+class IWorldItem;
+
+/**
+ * @brief The EventServer class process all game events.
+ */
+class EventServer
+{
+public:
+    EventServer();
+
+    /**
+     * @brief process This method process al events of an @a item object
+     * @param item This is processed object.
+     */
+    void process(IWorldItem* item);
+};
+
+}
+
+#endif // EVENTSERVER_H

From cb033f8f8837ea15d61304a6e62a181718d2bd31 Mon Sep 17 00:00:00 2001
From: EndrII <EndrIIMail@gmail.com>
Date: Fri, 6 Aug 2021 14:17:08 +0300
Subject: [PATCH 03/19] added event processor

---
 src/Core/Crawl/iworld.cpp         | 12 +++--
 src/Core/Crawl/iworld.h           | 11 ++++
 src/Core/Crawl/iworlditem.cpp     | 28 ++++++++++
 src/Core/Crawl/iworlditem.h       | 64 ++++++++++++++++++++++-
 src/Core/Crawl/playableobject.cpp |  1 +
 src/Core/Crawl/snake.cpp          |  3 ++
 src/Core/private/eventserver.cpp  | 87 ++++++++++++++++++++++++++++---
 src/Core/private/eventserver.h    | 54 ++++++++++++++++---
 8 files changed, 244 insertions(+), 16 deletions(-)

diff --git a/src/Core/Crawl/iworld.cpp b/src/Core/Crawl/iworld.cpp
index f82c12f..08f5d1a 100644
--- a/src/Core/Crawl/iworld.cpp
+++ b/src/Core/Crawl/iworld.cpp
@@ -28,7 +28,11 @@ IWorld::IWorld() {
     qRegisterMetaType<WorldRule::const_iterator>("WorldRule::const_iterator");
     connect(this, &IWorld::sigWorldChanged, this, &IWorld::worldChanged, Qt::QueuedConnection);
 
-    _eventServer = new EventServer;
+    _eventServer = new EventServer(this);
+
+    connect(_eventServer, &EventServer::sigIntersect, this, &IWorld::onIntersects);
+    connect(this, &IWorld::sigOBjctsListChanged, _eventServer, &EventServer::handleAvailableObjectChanges);
+
 }
 
 IWorld::~IWorld() {
@@ -53,8 +57,6 @@ void IWorld::render(unsigned int tbfMsec) {
 
     for (auto i = _items.begin(); i != _items.end(); ++i) {
         (*i)->render(tbfMsec);
-
-        _eventServer->process(*i);
     }
 
     _ItemsMutex.unlock();
@@ -349,6 +351,10 @@ void IWorld::updateWorld() {
     }
 }
 
+void IWorld::onIntersects(QList<const IWorldItem *> list) {
+    Q_UNUSED(list);
+}
+
 const QQuaternion &IWorld::cameraRotation() const {
     return _cameraRotation;
 }
diff --git a/src/Core/Crawl/iworld.h b/src/Core/Crawl/iworld.h
index d06fcb7..9256ea6 100644
--- a/src/Core/Crawl/iworld.h
+++ b/src/Core/Crawl/iworld.h
@@ -26,6 +26,14 @@ class ClastersTest;
 
 namespace CRAWL {
 
+/**
+ * @brief The Events enum contains availabele events of the World.
+ */
+enum Events {
+    /// If object support this event then for them will be check intersection with all not decorative objects.
+    Intersects = 0x01,
+};
+
 class IWorldItem;
 class PlayableObject;
 class GroundClaster;
@@ -384,6 +392,9 @@ protected:
      */
     void updateWorld();
 
+protected slots:
+    virtual void onIntersects(QList<const IWorldItem *> list);
+
 private slots:
 
     /**
diff --git a/src/Core/Crawl/iworlditem.cpp b/src/Core/Crawl/iworlditem.cpp
index da37964..d103ce6 100644
--- a/src/Core/Crawl/iworlditem.cpp
+++ b/src/Core/Crawl/iworlditem.cpp
@@ -56,6 +56,34 @@ void IWorldItem::initOnWorld(const IWorld *world, const IWorldItem * player) {
     _playerObject = player;
 }
 
+int IWorldItem::supportedEvents() const {
+    return _supportedEvents;
+}
+
+bool IWorldItem::isSopportEvent(int event) const {
+    return (_supportedEvents & event) == event;
+}
+
+void IWorldItem::setSupportedEvents(int newSupportedEvents) {
+    _supportedEvents = newSupportedEvents;
+}
+
+void IWorldItem::addSupportOfEvent(int newSupportedEvent) {
+
+}
+
+void IWorldItem::dropSupportOfEvent(int depricatedEvent) {
+
+}
+
+bool IWorldItem::isDecorative() const {
+    return _fDecorative;
+}
+
+void IWorldItem::setFDecorative(bool newFDecorative) {
+    _fDecorative = newFDecorative;
+}
+
 const IWorld *IWorldItem::world() const {
     return _world;
 }
diff --git a/src/Core/Crawl/iworlditem.h b/src/Core/Crawl/iworlditem.h
index 0e2c9c9..438f684 100644
--- a/src/Core/Crawl/iworlditem.h
+++ b/src/Core/Crawl/iworlditem.h
@@ -13,7 +13,6 @@
 
 namespace CRAWL {
 
-
 class IWorld;
 /**
  * @brief The IWorldItem class This is World item. This class contains functions for control event system.
@@ -36,6 +35,30 @@ public:
     void render(unsigned int tbfMsec) override;
     void init() override;
 
+    /**
+     * @brief isDecorative This method return true if the object is decarative.
+     *  The decorative objects not patricipate in event process.
+     * @return true if this ovjects is decorative.
+     */
+    bool isDecorative() const;
+
+    /**
+     * @brief supportedEvents This method return mask of the supported events. For get more information about events see the CRAWL::Events enum.
+     * @return integer mask of the supported events.
+     * @see IWorldItem::setSupportedEvents
+     * @see IWorldItem::addSupportOfEvent
+     * @see IWorldItem::dropSupportOfEvent
+     * @see IWorldItem::supportedEvents
+     */
+    int supportedEvents() const;
+
+    /**
+     * @brief isSopportEvent This method return true ithis objects support a @a event.f
+     * @return true if this objects support a @a event else false.
+     * @note If a @a event is mask with multiple events the this method return true if this objects support all events from a @a event mask.
+     */
+    bool isSopportEvent(int event) const;
+
 protected:
 
     /**
@@ -56,13 +79,52 @@ protected:
      */
     const IWorldItem * getPlayer() const;
 
+    /**
+     * @brief setFDecorative This method sets if object declarative or physical.
+     * @param newFDecorative new value of the fDecorative property
+     */
+    void setFDecorative(bool newFDecorative);
 
+    /**
+     * @brief setSupportedEvents This method overwrite the mask og the supported events.
+     * @param newSupportedEvents This is new value of the supported events mask.
+     * @see IWorldItem::setSupportedEvents
+     * @see IWorldItem::addSupportOfEvent
+     * @see IWorldItem::dropSupportOfEvent
+     * @see IWorldItem::supportedEvents
+     */
+    void setSupportedEvents(int newSupportedEvents);
+
+    /**
+     * @brief addSupportOfEvent This method add support of a @a newSupportedEvent.
+     * @param newSupportedEvent This is new value of a supported event.
+     * @see IWorldItem::setSupportedEvents
+     * @see IWorldItem::addSupportOfEvent
+     * @see IWorldItem::dropSupportOfEvent
+     * @see IWorldItem::supportedEvents
+     */
+    void addSupportOfEvent(int newSupportedEvent);
+
+    /**
+     * @brief dropSupportOfEvent This method drop support of a @a depricatedEvent
+     * @param depricatedEvent This is event that will be dropped.
+     * @see IWorldItem::setSupportedEvents
+     * @see IWorldItem::addSupportOfEvent
+     * @see IWorldItem::dropSupportOfEvent
+     * @see IWorldItem::supportedEvents
+     */
+    void dropSupportOfEvent(int depricatedEvent);
 
 private:
     void initOnWorld(const IWorld* world, const IWorldItem *player);
 
     const IWorld* _world = nullptr;
     const IWorldItem *_playerObject = nullptr;
+
+    bool _fDecorative = true;
+
+    int _supportedEvents;
+
     friend class IWorld;
 };
 }
diff --git a/src/Core/Crawl/playableobject.cpp b/src/Core/Crawl/playableobject.cpp
index f34831f..0eb9eb0 100644
--- a/src/Core/Crawl/playableobject.cpp
+++ b/src/Core/Crawl/playableobject.cpp
@@ -16,6 +16,7 @@ PlayableObject::PlayableObject(const QString &name,
                  QObject *ptr):
     IWorldItem(name, viewTempalte, ptr) {
 
+    setFDecorative(false);
 }
 
 void PlayableObject::render(unsigned int tbfMsec) {
diff --git a/src/Core/Crawl/snake.cpp b/src/Core/Crawl/snake.cpp
index 9c14643..0674ecd 100644
--- a/src/Core/Crawl/snake.cpp
+++ b/src/Core/Crawl/snake.cpp
@@ -10,6 +10,7 @@
 #include <QQuaternion>
 #include <quasarapp.h>
 #include <cmath>
+#include "iworld.h"
 
 namespace CRAWL {
 
@@ -32,6 +33,8 @@ Snake::Snake(const QString &name, const QString &viewTempalte, QObject *ptr):
     setLengthBetwinItemsMap({{0, 0.8},
                               {0.4, 1.2},
                               {1, 0.5}});
+
+    addSupportOfEvent(Events::Intersects);
 }
 
 Snake::~Snake( ){
diff --git a/src/Core/private/eventserver.cpp b/src/Core/private/eventserver.cpp
index c4e822b..f251646 100644
--- a/src/Core/private/eventserver.cpp
+++ b/src/Core/private/eventserver.cpp
@@ -8,20 +8,95 @@
 #include "eventserver.h"
 
 #include <Crawl/iworlditem.h>
+#include <Crawl/iworld.h>
+#include <QtConcurrent>
 
 namespace CRAWL {
 
-EventServer::EventServer() {
+EventServer::EventServer(IWorld *instance) {
+    debug_assert(instance, "Invalid World pointer in EventServer");
+    _worldInstance = instance;
 
+    _supportedEventsKeys = {Events::Intersects};
 }
 
-void EventServer::process(IWorldItem *item) {
-    // intersects event.
+EventServer::~EventServer() {
+    stop();
+}
 
+void EventServer::start() {
+    if (_renderLoopFuture.isRunning())
+        return;
 
+    _renderLoop = true;
+    _renderLoopFuture = QtConcurrent::run([this](){renderLoop();});
+}
 
-//    if ((item)->intersects(*_player)) {
-//        _player->onIntersects((*i));
-//    }
+void EventServer::stop() {
+    _renderLoop = false;
+    _renderLoopFuture.waitForFinished();
+}
+
+void EventServer::handleAvailableObjectChanges(const Diff &diff) {
+    for (int added: diff.addedIds) {
+        auto obj = _worldInstance->getItem(added);
+
+        if (!obj->isDecorative()) {
+            continue;
+        }
+
+        for (int event: qAsConst(_supportedEventsKeys)) {
+            addToSupportedEvents(obj, event);
+        }
+
+        _objects.insert(obj->guiId(), obj);
+    }
+
+    for (int removed: diff.removeIds) {
+        for (int event: qAsConst(_supportedEventsKeys)) {
+            _supportedEvents[event].remove(removed);
+        }
+        _objects.remove(removed);
+    }
+}
+
+void EventServer::eventProcess() {
+    for (auto it  = _supportedEvents.begin(); it != _supportedEvents.end(); ++it) {
+        for (const IWorldItem* item : qAsConst(it.value())) {
+
+            switch (it.key()) {
+
+            case Events::Intersects : {
+                QList<const IWorldItem*> result;
+                for (const IWorldItem *object : qAsConst(_objects)) {
+                    if (item != object && item->intersects(*object)) {
+                        result.append(object);
+                    }
+                }
+
+                if (result.size()) {
+                    emit sigIntersect(result << item);
+                }
+            }
+
+            default: {
+                QuasarAppUtils::Params::log("Not supported event", QuasarAppUtils::Error);
+            }
+
+            }
+        }
+    }
+}
+
+void EventServer::addToSupportedEvents(const IWorldItem * obj, int event) {
+    if (obj->isSopportEvent(event)) {
+        _supportedEvents[event].insert(obj->guiId(), obj);
+    };
+}
+
+void EventServer::renderLoop() {
+    while (_renderLoop) {
+        eventProcess();
+    }
 }
 }
diff --git a/src/Core/private/eventserver.h b/src/Core/private/eventserver.h
index 272285b..da88061 100644
--- a/src/Core/private/eventserver.h
+++ b/src/Core/private/eventserver.h
@@ -5,6 +5,12 @@
 //# of this license document, but changing it is not allowed.
 //#
 
+#include <QFuture>
+#include <QObject>
+
+#include <Crawl/diff.h>
+#include <QMultiHash>
+
 
 #ifndef EVENTSERVER_H
 #define EVENTSERVER_H
@@ -12,20 +18,56 @@
 namespace CRAWL {
 
 class IWorldItem;
+class IWorld;
 
 /**
  * @brief The EventServer class process all game events.
- */
-class EventServer
+ * This class process all game events on the separate thread and do not change the game objects. All signal of the events return constant object pointers.
+*/
+class EventServer: public QObject
 {
+    Q_OBJECT
 public:
-    EventServer();
+    EventServer(IWorld * instance);
+    ~EventServer();
 
     /**
-     * @brief process This method process al events of an @a item object
-     * @param item This is processed object.
+     * @brief start This method start a processing og the objects events.
      */
-    void process(IWorldItem* item);
+    void start();
+
+    /**
+     * @brief stop This method stop the processing of the objects.
+     */
+    void stop();
+
+public slots:
+    /**
+     * @brief handleAvailableObjectChanges This slots handle all changes of the world.
+     * @param diff This is changes on the world.
+     */
+    void handleAvailableObjectChanges(const Diff& diff);
+
+signals:
+    /**
+     * @brief sigIntersect This signal emit when objects intersect on the world.
+     * @param objects This is list of the intersects objects.
+     */
+    void sigIntersect(QList<const IWorldItem*> objects);
+
+private:
+    void eventProcess();
+    void addToSupportedEvents(const IWorldItem *obj, int event);
+
+    void renderLoop();
+
+    IWorld * _worldInstance = nullptr;
+    QHash<int, const IWorldItem*> _objects;
+    QHash<int, QHash<int, const IWorldItem*>> _supportedEvents;
+    QList<int> _supportedEventsKeys;
+    QFuture<void> _renderLoopFuture;
+    bool _renderLoop = false;
+
 };
 
 }

From 1b4aaf03378f94c38006ea6e50298007590270f2 Mon Sep 17 00:00:00 2001
From: EndrII <EndrIIMail@gmail.com>
Date: Fri, 6 Aug 2021 14:55:52 +0300
Subject: [PATCH 04/19] some fixes

---
 src/Core/Crawl/iworld.cpp        |  2 ++
 src/Core/Crawl/snakeitem.cpp     |  1 +
 src/Core/private/eventserver.cpp | 13 +++++++++++++
 src/Core/private/eventserver.h   |  1 +
 4 files changed, 17 insertions(+)

diff --git a/src/Core/Crawl/iworld.cpp b/src/Core/Crawl/iworld.cpp
index 08f5d1a..5da6e7d 100644
--- a/src/Core/Crawl/iworld.cpp
+++ b/src/Core/Crawl/iworld.cpp
@@ -87,6 +87,7 @@ bool IWorld::start() {
     worldChanged(_worldRules->cbegin());
     setTargetFps(60);
     setRunning(true);
+    _eventServer->start();
 
     return true;
 }
@@ -121,6 +122,7 @@ IWorldItem *IWorld::generate(const QString &objectType) const {
 
 bool IWorld::stop() {
     setRunning(false);
+    _eventServer->stop();
     return true;
 }
 
diff --git a/src/Core/Crawl/snakeitem.cpp b/src/Core/Crawl/snakeitem.cpp
index 65ce3ef..1be6f53 100644
--- a/src/Core/Crawl/snakeitem.cpp
+++ b/src/Core/Crawl/snakeitem.cpp
@@ -14,6 +14,7 @@ namespace CRAWL {
 SnakeItem::SnakeItem(const QString &name, const QString &viewTempalte, QObject *ptr):
     SingleClasterWorldItem(name, viewTempalte, ptr) {
     setAngularVelocity(-1);
+    setFDecorative(true);
 
 }
 
diff --git a/src/Core/private/eventserver.cpp b/src/Core/private/eventserver.cpp
index f251646..76ad6e1 100644
--- a/src/Core/private/eventserver.cpp
+++ b/src/Core/private/eventserver.cpp
@@ -77,6 +77,7 @@ void EventServer::eventProcess() {
                 if (result.size()) {
                     emit sigIntersect(result << item);
                 }
+                break;
             }
 
             default: {
@@ -96,7 +97,19 @@ void EventServer::addToSupportedEvents(const IWorldItem * obj, int event) {
 
 void EventServer::renderLoop() {
     while (_renderLoop) {
+        quint64 currentTime = QDateTime::currentMSecsSinceEpoch();
+
+        if (!_oldTimeRender) {
+            _oldTimeRender = currentTime;
+            continue;
+        }
+
         eventProcess();
+        int waitTime = 100 - currentTime + _oldTimeRender;
+        _oldTimeRender = currentTime;
+
+        if (waitTime > 0)
+            std::this_thread::sleep_for(std::chrono::milliseconds(waitTime));
     }
 }
 }
diff --git a/src/Core/private/eventserver.h b/src/Core/private/eventserver.h
index da88061..99d7add 100644
--- a/src/Core/private/eventserver.h
+++ b/src/Core/private/eventserver.h
@@ -67,6 +67,7 @@ private:
     QList<int> _supportedEventsKeys;
     QFuture<void> _renderLoopFuture;
     bool _renderLoop = false;
+    quint64 _oldTimeRender = 0;
 
 };
 

From a2ba48e76f6f3ed130ba46586c45a462d22be0bc Mon Sep 17 00:00:00 2001
From: EndrII <EndrIIMail@gmail.com>
Date: Fri, 6 Aug 2021 18:03:23 +0300
Subject: [PATCH 05/19] ref #98 "added user structure"

---
 src/Core/Crawl/icontrol.h         |  1 +
 src/Core/Crawl/iworld.cpp         |  9 +++++++-
 src/Core/Crawl/iworlditem.cpp     | 35 ++++++++++++++++++++-----------
 src/Core/Crawl/iworlditem.h       | 20 +++++++++++++++++-
 src/Core/Crawl/playableobject.cpp |  4 ++++
 src/Core/Crawl/playableobject.h   |  6 ++++++
 src/Core/Crawl/player.cpp         | 14 +++++++++++++
 src/Core/Crawl/player.h           | 26 +++++++++++++++++++++++
 src/Core/private/user.cpp         | 16 ++++++++++++++
 src/Core/private/user.h           | 31 +++++++++++++++++++++++++++
 10 files changed, 148 insertions(+), 14 deletions(-)
 create mode 100644 src/Core/Crawl/player.cpp
 create mode 100644 src/Core/Crawl/player.h
 create mode 100644 src/Core/private/user.cpp
 create mode 100644 src/Core/private/user.h

diff --git a/src/Core/Crawl/icontrol.h b/src/Core/Crawl/icontrol.h
index ef14381..cd8a7ee 100644
--- a/src/Core/Crawl/icontrol.h
+++ b/src/Core/Crawl/icontrol.h
@@ -42,6 +42,7 @@ public:
      * @return return path to qml view.
      */
     const QString &view() const;
+
 signals:
     void viewChanged();
 
diff --git a/src/Core/Crawl/iworld.cpp b/src/Core/Crawl/iworld.cpp
index 5da6e7d..8a6f9f9 100644
--- a/src/Core/Crawl/iworld.cpp
+++ b/src/Core/Crawl/iworld.cpp
@@ -54,13 +54,20 @@ void IWorld::render(unsigned int tbfMsec) {
     }
 
     _ItemsMutex.lock();
-
+    QList<int> toRemove;
     for (auto i = _items.begin(); i != _items.end(); ++i) {
+        if ((*i)->destroyIsScheduled())
+            toRemove.push_back((*i)->guiId());
+
         (*i)->render(tbfMsec);
     }
 
     _ItemsMutex.unlock();
 
+    for (int id: toRemove) {
+        removeItem(id);
+    }
+
     updateWorld();
 
     int waitTime = 1000 / targetFps() - tbfMsec;
diff --git a/src/Core/Crawl/iworlditem.cpp b/src/Core/Crawl/iworlditem.cpp
index d103ce6..4ca9e24 100644
--- a/src/Core/Crawl/iworlditem.cpp
+++ b/src/Core/Crawl/iworlditem.cpp
@@ -36,16 +36,7 @@ const IWorldItem *IWorldItem::getPlayer() const {
 void IWorldItem::render(unsigned int) {
     if (_playerObject->position().distanceToPoint(position()) >
             _world->cameraReleativePosition().z() * 3) {
-
-        float dX = _world->cameraReleativePosition().z() * 2 +
-                (rand() % static_cast<int>(_world->cameraReleativePosition().z()));
-
-        setX(_playerObject->position().x() + dX);
-
-        float dY = (rand() % static_cast<int>(_world->cameraReleativePosition().z() * 3)
-                                             - _world->cameraReleativePosition().z() * 1.5);
-
-        setY(_playerObject->position().y() + dY);
+        respawn();
     }
 }
 
@@ -64,16 +55,36 @@ bool IWorldItem::isSopportEvent(int event) const {
     return (_supportedEvents & event) == event;
 }
 
+void IWorldItem::destroy() {
+    _fDistroy = true;
+}
+
+void IWorldItem::respawn() {
+    float dX = _world->cameraReleativePosition().z() * 2 +
+            (rand() % static_cast<int>(_world->cameraReleativePosition().z()));
+
+    setX(_playerObject->position().x() + dX);
+
+    float dY = (rand() % static_cast<int>(_world->cameraReleativePosition().z() * 3)
+                                         - _world->cameraReleativePosition().z() * 1.5);
+
+    setY(_playerObject->position().y() + dY);
+}
+
+bool IWorldItem::destroyIsScheduled() const {
+    return _fDistroy;
+}
+
 void IWorldItem::setSupportedEvents(int newSupportedEvents) {
     _supportedEvents = newSupportedEvents;
 }
 
 void IWorldItem::addSupportOfEvent(int newSupportedEvent) {
-
+    _supportedEvents = _supportedEvents | newSupportedEvent;
 }
 
 void IWorldItem::dropSupportOfEvent(int depricatedEvent) {
-
+    _supportedEvents = _supportedEvents & (~depricatedEvent);
 }
 
 bool IWorldItem::isDecorative() const {
diff --git a/src/Core/Crawl/iworlditem.h b/src/Core/Crawl/iworlditem.h
index 438f684..62ed575 100644
--- a/src/Core/Crawl/iworlditem.h
+++ b/src/Core/Crawl/iworlditem.h
@@ -59,6 +59,24 @@ public:
      */
     bool isSopportEvent(int event) const;
 
+    /**
+     * @brief destroy this method will schedule a destroing of this object on the world.
+     * @see IWorldItem::destroyIsScheduled
+     */
+    virtual void destroy();
+
+    /**
+     * @brief respawn this method will schedule a repawning of this object on the world.
+     */
+    virtual void respawn();
+
+    /**
+     * @brief destroyIsScheduled This method return true if the current object has been scheduled to destroy.
+     * @return true if the current object has been scheduled to destroy, else false.
+     * @see IWorldItem::destroy
+     */
+    bool destroyIsScheduled() const;
+
 protected:
 
     /**
@@ -122,7 +140,7 @@ private:
     const IWorldItem *_playerObject = nullptr;
 
     bool _fDecorative = true;
-
+    bool _fDistroy = false;
     int _supportedEvents;
 
     friend class IWorld;
diff --git a/src/Core/Crawl/playableobject.cpp b/src/Core/Crawl/playableobject.cpp
index 0eb9eb0..a9f187e 100644
--- a/src/Core/Crawl/playableobject.cpp
+++ b/src/Core/Crawl/playableobject.cpp
@@ -23,6 +23,10 @@ void PlayableObject::render(unsigned int tbfMsec) {
     MovableObject::render(tbfMsec);
 }
 
+const IControl *PlayableObject::currentControl() const {
+    return _currentControl;
+}
+
 void PlayableObject::setControl(const IControl *control) {
 
 
diff --git a/src/Core/Crawl/playableobject.h b/src/Core/Crawl/playableobject.h
index 5b150cc..e6a39f6 100644
--- a/src/Core/Crawl/playableobject.h
+++ b/src/Core/Crawl/playableobject.h
@@ -57,6 +57,12 @@ public:
      */
     virtual void setControl(const IControl* control);
 
+    /**
+     * @brief currentControl This method return pointer to current control
+     * @return
+     */
+    const IControl *currentControl() const;
+
 protected:
     void render(unsigned int tbfMsec) override;
 
diff --git a/src/Core/Crawl/player.cpp b/src/Core/Crawl/player.cpp
new file mode 100644
index 0000000..f3c5baa
--- /dev/null
+++ b/src/Core/Crawl/player.cpp
@@ -0,0 +1,14 @@
+//#
+//# Copyright (C) 2021-2021 QuasarApp.
+//# Distributed under the GPLv3 software license, see the accompanying
+//# Everyone is permitted to copy and distribute verbatim copies
+//# of this license document, but changing it is not allowed.
+//#
+
+#include "player.h"
+namespace CRAWL {
+
+Player::Player() {
+
+}
+}
diff --git a/src/Core/Crawl/player.h b/src/Core/Crawl/player.h
new file mode 100644
index 0000000..4a33df0
--- /dev/null
+++ b/src/Core/Crawl/player.h
@@ -0,0 +1,26 @@
+//#
+//# Copyright (C) 2021-2021 QuasarApp.
+//# Distributed under the GPLv3 software license, see the accompanying
+//# Everyone is permitted to copy and distribute verbatim copies
+//# of this license document, but changing it is not allowed.
+//#
+
+
+#ifndef PLAYER_H
+#define PLAYER_H
+
+#include "icontrol.h"
+
+namespace CRAWL {
+
+/**
+ * @brief The Player class is main class of users.
+ */
+class CRAWL_EXPORT Player: public IControl
+{
+    Q_OBJECT
+public:
+    Player();
+};
+}
+#endif // PLAYER_H
diff --git a/src/Core/private/user.cpp b/src/Core/private/user.cpp
new file mode 100644
index 0000000..041d3b6
--- /dev/null
+++ b/src/Core/private/user.cpp
@@ -0,0 +1,16 @@
+//#
+//# Copyright (C) 2021-2021 QuasarApp.
+//# Distributed under the GPLv3 software license, see the accompanying
+//# Everyone is permitted to copy and distribute verbatim copies
+//# of this license document, but changing it is not allowed.
+//#
+
+#include "user.h"
+namespace CRAWL {
+
+User::User()
+{
+
+}
+
+}
diff --git a/src/Core/private/user.h b/src/Core/private/user.h
new file mode 100644
index 0000000..47d7796
--- /dev/null
+++ b/src/Core/private/user.h
@@ -0,0 +1,31 @@
+//#
+//# Copyright (C) 2021-2021 QuasarApp.
+//# Distributed under the GPLv3 software license, see the accompanying
+//# Everyone is permitted to copy and distribute verbatim copies
+//# of this license document, but changing it is not allowed.
+//#
+
+#include <QSet>
+
+#ifndef USER_H
+#define USER_H
+
+namespace CRAWL {
+
+/**
+ * @brief The User class This is internal class for collection all user data and user state.
+ */
+class User
+{
+public:
+    User();
+
+private:
+    int _moneu = 0;
+    int _lvl = 0;
+    QSet<int> _unlockedItems;
+
+};
+}
+
+#endif // USER_H

From efca1133cecf2e2444259142f442ff0117ad9da7 Mon Sep 17 00:00:00 2001
From: EndrII <EndrIIMail@gmail.com>
Date: Sat, 7 Aug 2021 17:46:37 +0300
Subject: [PATCH 06/19] added base interace for game items

---
 src/Core/Crawl/clientapp.cpp                 |  2 +-
 src/Core/Crawl/iitem.cpp                     | 30 ++++++++
 src/Core/Crawl/iitem.h                       | 77 ++++++++++++++++++++
 src/Core/Crawl/iworld.h                      | 27 +------
 src/Core/private/engine.cpp                  |  2 +-
 src/Core/private/worldviewdata.cpp           |  6 +-
 src/CrawlAbstractLvl/private/abslvlworld.cpp | 10 ++-
 src/CrawlAbstractLvl/private/abslvlworld.h   |  8 +-
 src/CrawlTestLvl/private/world.cpp           | 10 ++-
 src/CrawlTestLvl/private/world.h             | 10 ++-
 src/JungleLvl/private/world.cpp              | 10 ++-
 src/JungleLvl/private/world.h                |  7 +-
 tests/units/clasterstest.cpp                 | 16 ++--
 13 files changed, 158 insertions(+), 57 deletions(-)
 create mode 100644 src/Core/Crawl/iitem.cpp
 create mode 100644 src/Core/Crawl/iitem.h

diff --git a/src/Core/Crawl/clientapp.cpp b/src/Core/Crawl/clientapp.cpp
index 77d11d7..45efbc2 100644
--- a/src/Core/Crawl/clientapp.cpp
+++ b/src/Core/Crawl/clientapp.cpp
@@ -132,7 +132,7 @@ void ClientApp::addLvl(IWorld *levelWordl) {
 
     data.model = levelWordl;
     data.viewModel = new WorldViewData(data.model);
-    _availableLvls.insert(data.model->name(), data);
+    _availableLvls.insert(data.model->itemName(), data);
     _menu->addWorldViewModel(data.viewModel);
 }
 
diff --git a/src/Core/Crawl/iitem.cpp b/src/Core/Crawl/iitem.cpp
new file mode 100644
index 0000000..504b66b
--- /dev/null
+++ b/src/Core/Crawl/iitem.cpp
@@ -0,0 +1,30 @@
+//#
+//# Copyright (C) 2021-2021 QuasarApp.
+//# Distributed under the GPLv3 software license, see the accompanying
+//# Everyone is permitted to copy and distribute verbatim copies
+//# of this license document, but changing it is not allowed.
+//#
+
+
+#include "iitem.h"
+#include <QHash>
+
+namespace CRAWL {
+
+IItem::IItem() {
+
+}
+
+unsigned int IItem::itemId() {
+    if (_id) {
+        return _id;
+    }
+
+    _id = qHash(itemTextId());
+    return _id;
+}
+
+unsigned int IItem::itemId() const {
+    return _id;
+}
+}
diff --git a/src/Core/Crawl/iitem.h b/src/Core/Crawl/iitem.h
new file mode 100644
index 0000000..6bfaf27
--- /dev/null
+++ b/src/Core/Crawl/iitem.h
@@ -0,0 +1,77 @@
+//#
+//# Copyright (C) 2021-2021 QuasarApp.
+//# Distributed under the GPLv3 software license, see the accompanying
+//# Everyone is permitted to copy and distribute verbatim copies
+//# of this license document, but changing it is not allowed.
+//#
+
+
+#ifndef IITEM_H
+#define IITEM_H
+
+#include <QString>
+#include "global.h"
+
+namespace CRAWL {
+
+/**
+ * @brief The IItem class contains base description of the game items (player perks, game levels, and levels items.)
+ */
+class CRAWL_EXPORT IItem
+{
+public:
+    IItem();
+
+    /**
+     * @brief itemTextId All items contains own ids, override this method for create base for generate new item id.
+     * @return item text id.
+     * @see IItem::itemId
+     * @note do not use the tr function for implementation of this method.
+     *  If you want to translate the name of the item then use the IItem::itemName method.
+     */
+    virtual QString itemTextId() const = 0;
+
+    /**
+     * @brief itemName This method should be return name of the item.
+     * @return Name of the item (translated to all supported languages)
+     */
+    virtual QString itemName() const = 0;
+
+    /**
+     * @brief description This method must be return full description of this item. The description should be translated to all supported languages.
+     * @return Full description of this item.
+     */
+    virtual QString description() const = 0;
+
+    /**
+     * @brief image This method should be return path to image preview of the item object.
+     * @return path to image form qt resources.
+     */
+    virtual QString image() const = 0;
+
+    /**
+     * @brief cost This method should be return costo to unlock.
+     * @return costo to unlock.
+     */
+    virtual int cost() const = 0;
+
+    /**
+     * @brief itemId This method return hash of the IItem::itemTextId.
+     * @return hash of the IItem::itemTextId.
+     * @note The not const implementation inlike const implementation write a id to cache.
+     */
+    unsigned int itemId();
+
+    /**
+     * @brief itemId This method return hash of the IItem::itemTextId.
+     * @return hash of the IItem::itemTextId.
+     * @warning if the object are const and not const implementation of the IItem::itemId method never invoked then this method return 0.
+     */
+    unsigned int itemId() const;
+
+private:
+    unsigned int _id = 0;
+};
+
+}
+#endif // IITEM_H
diff --git a/src/Core/Crawl/iworld.h b/src/Core/Crawl/iworld.h
index 9256ea6..fd6dfd4 100644
--- a/src/Core/Crawl/iworld.h
+++ b/src/Core/Crawl/iworld.h
@@ -9,6 +9,7 @@
 #define CRAWL_IWORLD_H
 
 #include "gameresult.h"
+#include "iitem.h"
 #include "playableobject.h"
 
 #include <QHash>
@@ -55,7 +56,7 @@ typedef QMap<int, WorldObjects> WorldRule;
 /**
  * @brief The IWorld class use this interface for implementation your own game levels
  */
-class CRAWL_EXPORT IWorld : public QObject, public IRender
+class CRAWL_EXPORT IWorld : public QObject, public IRender, public IItem
 {
     Q_OBJECT
     Q_PROPERTY(QVector3D cameraReleativePosition READ cameraReleativePosition NOTIFY cameraReleativePositionChanged)
@@ -118,30 +119,6 @@ public:
      */
     virtual QString initHdrBackGround() const = 0;
 
-    /**
-     * @brief description This method shold be return lvl description.
-     * @return lvel description string.
-     */
-    virtual QString description() const = 0;
-
-    /**
-     * @brief imagePreview This method should be return path to banner of the lvl.
-     * @return path to level banner.
-     */
-    virtual QString imagePreview() const = 0;
-
-    /**
-     * @brief name This method shold be return lvl name.
-     * @return lvl name.
-     */
-    virtual QString name() const = 0;
-
-    /**
-     * @brief costToUnlock This method shold be return unlock cost.
-     * @return unlock cost
-     */
-    virtual int costToUnlock() const = 0;
-
     /**
      * @brief render this method recursive invoke all render functions of the all world items.
      *  The render function is main function of the SnakeEngine This method recal all propertys of all objects.
diff --git a/src/Core/private/engine.cpp b/src/Core/private/engine.cpp
index f01a0b9..d8c9b3b 100644
--- a/src/Core/private/engine.cpp
+++ b/src/Core/private/engine.cpp
@@ -49,7 +49,7 @@ void Engine::setWorld(IWorld *world) {
     emit worldChanged();
 
     if (!prepareNewWorld()) {
-        QuasarAppUtils::Params::log("Failed to init world. World name: " + _currentWorld->name(),
+        QuasarAppUtils::Params::log("Failed to init world. World name: " + _currentWorld->itemName(),
                                     QuasarAppUtils::Error);
 
         _currentWorld = nullptr;
diff --git a/src/Core/private/worldviewdata.cpp b/src/Core/private/worldviewdata.cpp
index dba250b..db4068a 100644
--- a/src/Core/private/worldviewdata.cpp
+++ b/src/Core/private/worldviewdata.cpp
@@ -15,7 +15,7 @@ WorldViewData::WorldViewData(const IWorld *data) {
 
 QString WorldViewData::name() const {
     if (_worldObject) {
-        return _worldObject->name();
+        return _worldObject->itemName();
     }
 
     return "";
@@ -31,7 +31,7 @@ QString WorldViewData::desc() const {
 
 int WorldViewData::cost() const {
     if (_worldObject) {
-        return _worldObject->costToUnlock();
+        return _worldObject->cost();
     }
 
     return 0;
@@ -50,7 +50,7 @@ void WorldViewData::setUnlocked(bool newUnlocked) {
 
 QString WorldViewData::image() const {
     if (_worldObject) {
-        return _worldObject->imagePreview();
+        return _worldObject->image();
     }
 
     return "";
diff --git a/src/CrawlAbstractLvl/private/abslvlworld.cpp b/src/CrawlAbstractLvl/private/abslvlworld.cpp
index 5b3aeee..5050c43 100644
--- a/src/CrawlAbstractLvl/private/abslvlworld.cpp
+++ b/src/CrawlAbstractLvl/private/abslvlworld.cpp
@@ -60,16 +60,16 @@ QString AbsLvlWorld::description() const {
     return tr("This a abstract lvl");
 }
 
-QString AbsLvlWorld::imagePreview() const {
+QString AbsLvlWorld::image() const {
     return "qrc:/hdr/hdr/testHDR.jpg";
 
 }
 
-QString AbsLvlWorld::name() const {
+QString AbsLvlWorld::itemName() const {
     return tr("AbstractLvl");
 }
 
-int AbsLvlWorld::costToUnlock() const {
+int AbsLvlWorld::cost() const {
     return 0;
 }
 
@@ -81,4 +81,8 @@ void AbsLvlWorld::initPlayerControl(CRAWL::IControl *control) {
     return IWorld::initPlayerControl(control);
 }
 
+QString AbsLvlWorld::itemTextId() const {
+    return "AbstractLevel";
+}
+
 }
diff --git a/src/CrawlAbstractLvl/private/abslvlworld.h b/src/CrawlAbstractLvl/private/abslvlworld.h
index 2f075cf..2944ae4 100644
--- a/src/CrawlAbstractLvl/private/abslvlworld.h
+++ b/src/CrawlAbstractLvl/private/abslvlworld.h
@@ -19,16 +19,16 @@ public:
 
     AbsLvlWorld();
 
-
     CRAWL::PlayableObject *initPlayer() const override;
     CRAWL::WorldRule *initWorldRules() override;
     QString initHdrBackGround() const override;
     QString description() const override;
-    QString imagePreview() const override;
-    QString name() const override;
-    int costToUnlock() const override;
+    QString image() const override;
+    QString itemName() const override;
+    int cost() const override;
     CRAWL::IControl *initUserInterface() const override;
     void initPlayerControl(CRAWL::IControl *control) override;
+    QString itemTextId() const override;
 
 };
 
diff --git a/src/CrawlTestLvl/private/world.cpp b/src/CrawlTestLvl/private/world.cpp
index 281bb39..dc8b0fe 100644
--- a/src/CrawlTestLvl/private/world.cpp
+++ b/src/CrawlTestLvl/private/world.cpp
@@ -48,15 +48,15 @@ QString World::description() const {
     return "This a test lvl";
 }
 
-QString World::imagePreview() const {
+QString World::image() const {
     return "qrc:/hdr/hdr/testHDR.jpg";
 }
 
-QString World::name() const {
+QString World::itemName() const {
     return "Test";
 }
 
-int World::costToUnlock() const {
+int World::cost() const {
     return 0;
 }
 
@@ -81,6 +81,10 @@ CRAWL::IAI *World::initBackGroundAI() const {
     return IWorld::initBackGroundAI();
 }
 
+QString World::itemTextId() const {
+    return "TestLevel";
+}
+
 void World::handleXViewChanged(double dx) {
     auto eilorRotation = cameraRotation().toEulerAngles();
     eilorRotation.setX(eilorRotation.x() + dx);
diff --git a/src/CrawlTestLvl/private/world.h b/src/CrawlTestLvl/private/world.h
index f8038f7..a1f42f2 100644
--- a/src/CrawlTestLvl/private/world.h
+++ b/src/CrawlTestLvl/private/world.h
@@ -23,18 +23,22 @@ public:
     CRAWL::WorldRule *initWorldRules() override;
     QString initHdrBackGround() const override;
     QString description() const override;
-    QString imagePreview() const override;
-    QString name() const override;
-    int costToUnlock() const override;
+    QString image() const override;
+    QString itemName() const override;
+    int cost() const override;
     CRAWL::IControl *initUserInterface() const override;
     void initPlayerControl(CRAWL::IControl *control) override;
     CRAWL::PlayableObject *initPlayer() const override;
     CRAWL::IAI *initBackGroundAI() const override;
+    QString itemTextId() const override;
 
 private slots:
     void handleXViewChanged(double dx);
     void handleYViewChanged(double dy);
 
+
+
+
 };
 
 
diff --git a/src/JungleLvl/private/world.cpp b/src/JungleLvl/private/world.cpp
index b036387..e80ebb7 100644
--- a/src/JungleLvl/private/world.cpp
+++ b/src/JungleLvl/private/world.cpp
@@ -88,15 +88,15 @@ QString World::description() const {
     return tr("Jungle world.");
 }
 
-QString World::imagePreview() const {
+QString World::image() const {
     return "qrc:/hdr/hdr/jungleBanner.jpg";
 }
 
-QString World::name() const {
+QString World::itemName() const {
     return tr("Jungle");
 }
 
-int World::costToUnlock() const {
+int World::cost() const {
     return 0;
 }
 
@@ -116,6 +116,10 @@ CRAWL::IAI *World::initBackGroundAI() const {
     return IWorld::initBackGroundAI();
 }
 
+QString World::itemTextId() const {
+    return "JungleLevel";
+}
+
 void World::handleXViewChanged(double dx) {
     auto eilorRotation = cameraRotation().toEulerAngles();
     eilorRotation.setX(eilorRotation.x() + dx);
diff --git a/src/JungleLvl/private/world.h b/src/JungleLvl/private/world.h
index 98bf398..3c323e3 100644
--- a/src/JungleLvl/private/world.h
+++ b/src/JungleLvl/private/world.h
@@ -22,13 +22,14 @@ public:
     CRAWL::WorldRule *initWorldRules() override;
     QString initHdrBackGround() const override;
     QString description() const override;
-    QString imagePreview() const override;
-    QString name() const override;
-    int costToUnlock() const override;
+    QString image() const override;
+    QString itemName() const override;
+    int cost() const override;
     CRAWL::IControl *initUserInterface() const override;
     void initPlayerControl(CRAWL::IControl *control) override;
     CRAWL::PlayableObject *initPlayer() const override;
     CRAWL::IAI *initBackGroundAI() const override;
+    QString itemTextId() const override;
 
 private slots:
     void handleXViewChanged(double dx);
diff --git a/tests/units/clasterstest.cpp b/tests/units/clasterstest.cpp
index 219c0e6..a63bcc5 100644
--- a/tests/units/clasterstest.cpp
+++ b/tests/units/clasterstest.cpp
@@ -45,14 +45,14 @@ public:
 
     // IWorld interface
 public:
-    CRAWL::PlayableObject *initPlayer() const {return nullptr;};
-    CRAWL::WorldRule *initWorldRules() {return nullptr;};
-    QString initHdrBackGround() const {return "";};
-    QString description() const {return "";};
-    QString imagePreview() const {return "";};
-    QString name() const {return "TestWorld";};
-    int costToUnlock() const {return 0;};
-
+    CRAWL::PlayableObject *initPlayer() const override {return nullptr;};
+    CRAWL::WorldRule *initWorldRules() override {return nullptr;};
+    QString initHdrBackGround() const override {return "";};
+    QString description() const override {return "";};
+    QString image() const override {return "";};
+    QString itemName() const override {return "TestWorld";};
+    int cost() const override {return 0;};
+    QString itemTextId() const override {return "TestWorld";};
     friend class ClastersTest;
 };
 

From a037b15adc58a421e00849a3cf908302013adfcc Mon Sep 17 00:00:00 2001
From: EndrII <EndrIIMail@gmail.com>
Date: Sun, 8 Aug 2021 13:20:47 +0300
Subject: [PATCH 07/19] added user class

---
 src/Core/private/user.cpp     |  96 +++++++++++++++++++++-
 src/Core/private/user.h       | 149 ++++++++++++++++++++++++++++++++--
 tests/units/groupobjecttest.h |   7 +-
 3 files changed, 242 insertions(+), 10 deletions(-)

diff --git a/src/Core/private/user.cpp b/src/Core/private/user.cpp
index 041d3b6..fcf9b37 100644
--- a/src/Core/private/user.cpp
+++ b/src/Core/private/user.cpp
@@ -8,9 +8,103 @@
 #include "user.h"
 namespace CRAWL {
 
-User::User()
+constexpr float tierMul = 1.2;
+constexpr int firstTierCount = 10;
+
+// Tiers table
+template <int N>
+struct Tiers
 {
+    enum { value = static_cast<const int>(tierMul * Tiers<N - 1>::value)};
+};
+
+template <>
+struct Tiers<0>
+{
+    enum { value = 0 };
+};
+
+template <>
+struct Tiers<1>
+{
+    enum { value = firstTierCount };
+};
+// End Tiers table
+
+constexpr int maximumTear = 100;
+
+#define T(X) Tiers<X>::value
+constexpr int tiersTable[maximumTear] = {T(0), T(1), T(2), T(3), T(4), T(5), T(6), T(7), T(8), T(9),
+                                         T(10), T(11), T(12), T(13), T(14), T(15), T(16), T(17), T(18), T(19),
+                                         T(20), T(21), T(22), T(23), T(24), T(25), T(26), T(27), T(28), T(29),
+                                         T(30), T(31), T(32), T(33), T(34), T(35), T(36), T(37), T(38), T(39),
+                                         T(40), T(41), T(42), T(43), T(44), T(45), T(46), T(47), T(48), T(49),
+                                         T(50), T(51), T(52), T(53), T(54), T(55), T(56), T(57), T(58), T(59),
+                                         T(60), T(61), T(62), T(63), T(64), T(65), T(66), T(67), T(68), T(69),
+                                         T(70), T(71), T(72), T(73), T(74), T(75), T(76), T(77), T(78), T(79),
+                                         T(80), T(81), T(82), T(83), T(84), T(85), T(86), T(87), T(88), T(89),
+                                         T(90), T(91), T(92), T(93), T(94), T(95), T(96), T(97), T(98), T(99)};
+User::User() {
 
 }
 
+const QSet<int> &User::unlockedItems() const {
+    return _unlockedItems;
+}
+
+bool User::isUnlocked(int item) const {
+    return _unlockedItems.contains(item);
+}
+
+void User::unclokItem(int item) {
+    _unlockedItems.insert(item);
+}
+
+void User::droppItem(int item) {
+    _unlockedItems.remove(item);
+}
+
+void User::setUnlockedItems(const QSet<int> &newUnlockedItems) {
+    _unlockedItems = newUnlockedItems;
+}
+
+int User::recalcTier() {
+    int _tier = 0;
+
+    while (xp() > tiersTable[_tier]) {
+        _tier++;
+    }
+
+    return _tier;
+}
+
+int User::xp() const {
+    return _xp;
+}
+
+void User::setXp(int newXp) {
+    if (_xp == newXp)
+        return;
+    _xp = newXp;
+
+    recalcTier();
+
+    emit xpChanged();
+}
+
+int User::tier() {
+    return _tier;
+}
+
+int User::money() const {
+    return _money;
+}
+
+void User::setMoney(int newMoney) {
+    if (_money == newMoney)
+        return;
+    _money = newMoney;
+    emit moneyChanged();
+}
+
 }
diff --git a/src/Core/private/user.h b/src/Core/private/user.h
index 47d7796..02faf4f 100644
--- a/src/Core/private/user.h
+++ b/src/Core/private/user.h
@@ -6,6 +6,7 @@
 //#
 
 #include <QSet>
+#include <QObject>
 
 #ifndef USER_H
 #define USER_H
@@ -15,16 +16,154 @@ namespace CRAWL {
 /**
  * @brief The User class This is internal class for collection all user data and user state.
  */
-class User
+class User : public QObject
 {
+
+    Q_OBJECT
+
+    /**
+     * @brief money This current user money count. An user can buy and sell game items using own money amount.
+     * @see User::setMoney
+     * @see User::money()
+     */
+    Q_PROPERTY(int money READ money WRITE setMoney NOTIFY moneyChanged)
+
+    /**
+     * @brief xp This is experience count of an user. The experience unlock new tiers and make available new items for buying.
+     * @see User::setXp
+     * @see User::xp()
+     * @see User::tier
+     * @see User::tier()
+     */
+    Q_PROPERTY(int xp READ xp WRITE setXp NOTIFY xpChanged)
+
+    /**
+     * @brief tier This us user tier. This value automaticaly generated by cuuren user experience count.
+     * @see User::xp
+     * @see User::xp()
+     * @see User::tier()
+     */
+    Q_PROPERTY(int tier READ tier NOTIFY tierChanged)
+
 public:
     User();
 
-private:
-    int _moneu = 0;
-    int _lvl = 0;
-    QSet<int> _unlockedItems;
+    /**
+     * @brief money This current user money count. An user can buy and sell game items using own money amount.
+     * @return current value of the User::money property
+     * @see User::setMoney
+     * @see User::money
+     */
+    int money() const;
 
+    /**
+     * @brief setMoney This method sets new value of the user money amount.
+     * @param newMoney this is new value of users money.
+     * @see User::money()
+     * @see User::money
+     */
+    void setMoney(int newMoney);
+
+    /**
+     * @brief xp This is experience count of an user. The experience unlock new tiers and make available new items for buying.
+     * @return current user xpereans.
+     * @see User::setXp
+     * @see User::xp
+     * @see User::tier
+     * @see User::tier()
+     */
+    int xp() const;
+
+    /**
+     * @brief setXp This method sets new value of the user experience.
+     * @param newXp This is new value of the users experience.
+     * @note This method can be change the User::tier property
+     * @see User::xp
+     * @see User::xp()
+     * @see User::tier
+     * @see User::tier()
+     */
+    void setXp(int newXp);
+
+    /**
+     * @brief tier This us user tier. This value automaticaly generated by cuuren user experience count.
+     * @return current value of the users tier.
+     * @see User::xp
+     * @see User::xp()
+     * @see User::tier
+     */
+    int tier();
+
+    /**
+     * @brief unlockedItems This method return set of the unlocked items of this user.
+     * @return Set of the unlocked items of this user.
+     * @see User::unclokItem
+     * @see User::unlockedItems
+     * @see User::droppItem
+     * @see User::isUnlocked
+     * @see User::setUnlockedItems
+     */
+    const QSet<int> &unlockedItems() const;
+
+    /**
+     * @brief isUnlocked This method check if the @a item is unlocked for this user.
+     * @param item This is id of the checked item.
+     * @return true if the item is uncloked else false.
+     * @see User::unclokItem
+     * @see User::unlockedItems
+     * @see User::droppItem
+     * @see User::isUnlocked
+     * @see User::setUnlockedItems
+     */
+    bool isUnlocked(int item) const;
+
+    /**
+     * @brief unclokItem This method unclok the @a item for current user.
+     * @param item This is id of item that need to unclok.
+     * @see User::unclokItem
+     * @see User::unlockedItems
+     * @see User::droppItem
+     * @see User::isUnlocked
+     * @see User::setUnlockedItems
+     */
+    void unclokItem(int item);
+
+    /**
+     * @brief droppItem This method dropp item from user.
+     * @param item This is id of the dropped item
+     * @see User::unclokItem
+     * @see User::unlockedItems
+     * @see User::droppItem
+     * @see User::isUnlocked
+     * @see User::setUnlockedItems
+     */
+    void droppItem(int item);
+
+signals:
+    void moneyChanged();
+    void tierChanged();
+    void xpChanged();
+
+protected:
+    /**
+     * @brief setUnlockedItems This method sets new set of uncloked items
+     * @param newUnlockedItems This is new set of the uncloked items
+     * @see User::unclokItem
+     * @see User::unlockedItems
+     * @see User::droppItem
+     * @see User::isUnlocked
+     * @see User::setUnlockedItems
+     */
+    void setUnlockedItems(const QSet<int> &newUnlockedItems);
+
+private:
+
+    int recalcTier();
+
+    int _money = 0;
+    int _xp = 0;
+    int _tier = 0;
+    QSet<int> _unlockedItems;
 };
 }
 
diff --git a/tests/units/groupobjecttest.h b/tests/units/groupobjecttest.h
index 04b9efa..2812ad0 100644
--- a/tests/units/groupobjecttest.h
+++ b/tests/units/groupobjecttest.h
@@ -5,13 +5,12 @@
 //# of this license document, but changing it is not allowed.
 //#
 
-#include "test.h"
-#include "testutils.h"
-
-
 #ifndef GROUPOBJECTTEST_H
 #define GROUPOBJECTTEST_H
 
+#include "test.h"
+#include "testutils.h"
+
 /**
  * @brief The GroupObjectTest class will be tests the CRAWL::GroupObject class from the core library.
  */

From 48b1e7b966ef13c305310a8d50908f3bd42275d8 Mon Sep 17 00:00:00 2001
From: EndrII <EndrIIMail@gmail.com>
Date: Sun, 8 Aug 2021 13:23:12 +0300
Subject: [PATCH 08/19] fix signal of the tier

---
 src/Core/private/user.cpp | 11 ++++++++++-
 src/Core/private/user.h   |  2 ++
 2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/src/Core/private/user.cpp b/src/Core/private/user.cpp
index fcf9b37..591d121 100644
--- a/src/Core/private/user.cpp
+++ b/src/Core/private/user.cpp
@@ -78,6 +78,15 @@ int User::recalcTier() {
     return _tier;
 }
 
+void User::setTier(int tier) {
+    if (_tier == tier)
+        return;
+
+    _tier = tier;
+
+    emit tierChanged();
+}
+
 int User::xp() const {
     return _xp;
 }
@@ -87,7 +96,7 @@ void User::setXp(int newXp) {
         return;
     _xp = newXp;
 
-    recalcTier();
+    setTier(recalcTier());
 
     emit xpChanged();
 }
diff --git a/src/Core/private/user.h b/src/Core/private/user.h
index 02faf4f..4def157 100644
--- a/src/Core/private/user.h
+++ b/src/Core/private/user.h
@@ -160,6 +160,8 @@ private:
 
     int recalcTier();
 
+    void setTier();
+
     int _money = 0;
     int _xp = 0;
     int _tier = 0;

From 4f541facd7059717a8f99aa2d0ac2728fae1fc4d Mon Sep 17 00:00:00 2001
From: EndrII <EndrIIMail@gmail.com>
Date: Sun, 8 Aug 2021 13:24:07 +0300
Subject: [PATCH 09/19] fix tier

---
 src/Core/private/user.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/Core/private/user.h b/src/Core/private/user.h
index 4def157..f72bda0 100644
--- a/src/Core/private/user.h
+++ b/src/Core/private/user.h
@@ -160,7 +160,7 @@ private:
 
     int recalcTier();
 
-    void setTier();
+    void setTier(int tier);
 
     int _money = 0;
     int _xp = 0;

From 959a8384929f844d991e044c375516cd61eb1144 Mon Sep 17 00:00:00 2001
From: EndrII <EndrIIMail@gmail.com>
Date: Sun, 8 Aug 2021 15:37:34 +0300
Subject: [PATCH 10/19] fix docs

---
 src/Core/private/user.h | 40 ++++++++++++++++++++--------------------
 1 file changed, 20 insertions(+), 20 deletions(-)

diff --git a/src/Core/private/user.h b/src/Core/private/user.h
index f72bda0..ec0da42 100644
--- a/src/Core/private/user.h
+++ b/src/Core/private/user.h
@@ -24,75 +24,75 @@ class User : public QObject
     /**
      * @brief money This current user money count. An user can buy and sell game items using own money amount.
      * @see User::setMoney
-     * @see User::money()
+     * @see User::getMoney
      */
-    Q_PROPERTY(int money READ money WRITE setMoney NOTIFY moneyChanged)
+    Q_PROPERTY(int money READ getMoney WRITE setMoney NOTIFY moneyChanged)
 
     /**
      * @brief xp This is experience count of an user. The experience unlock new tiers and make available new items for buying.
      * @see User::setXp
-     * @see User::xp()
+     * @see User::getXp
      * @see User::tier
-     * @see User::tier()
+     * @see User::getTier
      */
-    Q_PROPERTY(int xp READ xp WRITE setXp NOTIFY xpChanged)
+    Q_PROPERTY(int xp READ getXp WRITE setXp NOTIFY xpChanged)
 
     /**
      * @brief tier This us user tier. This value automaticaly generated by cuuren user experience count.
      * @see User::xp
-     * @see User::xp()
-     * @see User::tier()
+     * @see User::getXp
+     * @see User::getTier
      */
-    Q_PROPERTY(int tier READ tier NOTIFY tierChanged)
+    Q_PROPERTY(int tier READ getTier NOTIFY tierChanged)
 
 public:
     User();
 
     /**
-     * @brief money This current user money count. An user can buy and sell game items using own money amount.
+     * @brief getMoney This current user money count. An user can buy and sell game items using own money amount.
      * @return current value of the User::money property
      * @see User::setMoney
      * @see User::money
      */
-    int money() const;
+    int getMoney() const;
 
     /**
      * @brief setMoney This method sets new value of the user money amount.
      * @param newMoney this is new value of users money.
-     * @see User::money()
+     * @see User::getMoney
      * @see User::money
      */
     void setMoney(int newMoney);
 
     /**
-     * @brief xp This is experience count of an user. The experience unlock new tiers and make available new items for buying.
+     * @brief getXp This is experience count of an user. The experience unlock new tiers and make available new items for buying.
      * @return current user xpereans.
      * @see User::setXp
-     * @see User::xp
+     * @see User::getXp
      * @see User::tier
-     * @see User::tier()
+     * @see User::getTier
      */
-    int xp() const;
+    int getXp() const;
 
     /**
      * @brief setXp This method sets new value of the user experience.
      * @param newXp This is new value of the users experience.
      * @note This method can be change the User::tier property
      * @see User::xp
-     * @see User::xp()
+     * @see User::getXp
      * @see User::tier
-     * @see User::tier()
+     * @see User::getTier
      */
     void setXp(int newXp);
 
     /**
-     * @brief tier This us user tier. This value automaticaly generated by cuuren user experience count.
+     * @brief getTier This us user tier. This value automaticaly generated by cuuren user experience count.
      * @return current value of the users tier.
      * @see User::xp
-     * @see User::xp()
+     * @see User::getXp
      * @see User::tier
      */
-    int tier();
+    int getTier();
 
     /**
      * @brief unlockedItems This method return set of the unlocked items of this user.

From 05021f3e501d7d0476568544e63d42e06cfa662e Mon Sep 17 00:00:00 2001
From: EndrII <EndrIIMail@gmail.com>
Date: Sun, 8 Aug 2021 15:38:51 +0300
Subject: [PATCH 11/19] fix build

---
 src/Core/private/user.cpp | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/Core/private/user.cpp b/src/Core/private/user.cpp
index 591d121..54f4f32 100644
--- a/src/Core/private/user.cpp
+++ b/src/Core/private/user.cpp
@@ -71,7 +71,7 @@ void User::setUnlockedItems(const QSet<int> &newUnlockedItems) {
 int User::recalcTier() {
     int _tier = 0;
 
-    while (xp() > tiersTable[_tier]) {
+    while (getXp() > tiersTable[_tier]) {
         _tier++;
     }
 
@@ -87,7 +87,7 @@ void User::setTier(int tier) {
     emit tierChanged();
 }
 
-int User::xp() const {
+int User::getXp() const {
     return _xp;
 }
 
@@ -101,11 +101,11 @@ void User::setXp(int newXp) {
     emit xpChanged();
 }
 
-int User::tier() {
+int User::getTier() {
     return _tier;
 }
 
-int User::money() const {
+int User::getMoney() const {
     return _money;
 }
 

From b1711d5d5a2e224a8bafe22ed3fb41ec465e6ba4 Mon Sep 17 00:00:00 2001
From: EndrII <EndrIIMail@gmail.com>
Date: Sun, 8 Aug 2021 16:52:58 +0300
Subject: [PATCH 12/19] added base implementation of the store class

---
 src/Core/Crawl/iitem.h     |  6 +++++
 src/Core/private/store.cpp | 46 +++++++++++++++++++++++++++++++++
 src/Core/private/store.h   | 52 ++++++++++++++++++++++++++++++++++++++
 src/Core/private/user.cpp  |  4 ++-
 4 files changed, 107 insertions(+), 1 deletion(-)
 create mode 100644 src/Core/private/store.cpp
 create mode 100644 src/Core/private/store.h

diff --git a/src/Core/Crawl/iitem.h b/src/Core/Crawl/iitem.h
index 6bfaf27..c5473a3 100644
--- a/src/Core/Crawl/iitem.h
+++ b/src/Core/Crawl/iitem.h
@@ -55,6 +55,12 @@ public:
      */
     virtual int cost() const = 0;
 
+    /**
+     * @brief requiredTier This method return requried level to unlock.
+     * @return requried level to unlock.
+     */
+    virtual int requiredTier() const = 0;
+
     /**
      * @brief itemId This method return hash of the IItem::itemTextId.
      * @return hash of the IItem::itemTextId.
diff --git a/src/Core/private/store.cpp b/src/Core/private/store.cpp
new file mode 100644
index 0000000..75ebb4f
--- /dev/null
+++ b/src/Core/private/store.cpp
@@ -0,0 +1,46 @@
+//#
+//# Copyright (C) 2021-2021 QuasarApp.
+//# Distributed under the GPLv3 software license, see the accompanying
+//# Everyone is permitted to copy and distribute verbatim copies
+//# of this license document, but changing it is not allowed.
+//#
+
+
+#include "store.h"
+
+#include <Crawl/iitem.h>
+namespace CRAWL {
+
+Store::Store()
+{
+
+}
+
+bool Store::buy(User &buyer, int itemId) {
+
+    auto item = getItemById(itemId);
+
+    if (buyer.getTier() < item->requiredTier()) {
+        return false;
+    }
+
+    if (buyer.getMoney() < item->cost()) {
+        return false;
+    }
+
+    buyer.setMoney(buyer.getMoney() - item->cost());
+    buyer.unclokItem(itemId);
+
+    return true;
+}
+
+bool Store::init(const QHash<int, const IItem *> &availabelItems) {
+    _store = availabelItems;
+
+    return true;
+}
+
+const IItem *Store::getItemById(int id) const {
+    return _store.value(id, nullptr);
+}
+}
diff --git a/src/Core/private/store.h b/src/Core/private/store.h
new file mode 100644
index 0000000..087cad2
--- /dev/null
+++ b/src/Core/private/store.h
@@ -0,0 +1,52 @@
+//#
+//# Copyright (C) 2021-2021 QuasarApp.
+//# Distributed under the GPLv3 software license, see the accompanying
+//# Everyone is permitted to copy and distribute verbatim copies
+//# of this license document, but changing it is not allowed.
+//#
+
+
+#ifndef STORE_H
+#define STORE_H
+
+#include "user.h"
+
+namespace CRAWL {
+
+class IItem;
+
+/**
+ * @brief The Store class contains method for control all game items beetwin users.
+ */
+class Store
+{
+public:
+    Store();
+
+    /**
+     * @brief buy This method unlock the item with @a itemId for @a buyer. The
+     * @param buyer This is user that will be buy item with @a itemId id.
+     * @param itemId This is id of the item that @a buyer will be buy
+     * @return true if the deal gas been completed successfully
+     */
+    bool buy(User& buyer, int itemId);
+
+    /**
+     * @brief init This method initialise store of the game.
+     * @param availabelItems This is hash of the available item.
+     * @return true if the items inited successfuly else false.
+     */
+    bool init(const QHash<int, const IItem*>& availabelItems);
+
+    /**
+     * @brief getItemById This method return item by id.
+     * @param id This is id of the required item.
+     * @return pointer to item. if The item with @a id not found then return nullptr.
+     */
+    const IItem* getItemById(int id) const;
+
+private:
+    QHash<int, const IItem*> _store;
+};
+}
+#endif // STORE_H
diff --git a/src/Core/private/user.cpp b/src/Core/private/user.cpp
index 54f4f32..2c939ed 100644
--- a/src/Core/private/user.cpp
+++ b/src/Core/private/user.cpp
@@ -11,19 +11,21 @@ namespace CRAWL {
 constexpr float tierMul = 1.2;
 constexpr int firstTierCount = 10;
 
-// Tiers table
+/// @private
 template <int N>
 struct Tiers
 {
     enum { value = static_cast<const int>(tierMul * Tiers<N - 1>::value)};
 };
 
+/// @private
 template <>
 struct Tiers<0>
 {
     enum { value = 0 };
 };
 
+/// @private
 template <>
 struct Tiers<1>
 {

From 2e4162b1dc988dec6db88cf4c3816b679719cb85 Mon Sep 17 00:00:00 2001
From: EndrII <EndrIIMail@gmail.com>
Date: Sun, 8 Aug 2021 23:32:06 +0300
Subject: [PATCH 13/19] added store class

---
 src/Core/Crawl/clientapp.cpp                 | 13 ++++++++++
 src/Core/Crawl/clientapp.h                   |  3 +++
 src/Core/Crawl/iitem.cpp                     | 25 +++++++++++++++++-
 src/Core/Crawl/iitem.h                       | 27 ++++++++++++++++++++
 src/Core/private/engine.cpp                  |  2 +-
 src/Core/private/engine.h                    |  1 +
 src/Core/private/store.cpp                   |  2 +-
 src/Core/private/store.h                     |  4 +--
 src/CrawlAbstractLvl/private/abslvlworld.cpp |  4 +++
 src/CrawlAbstractLvl/private/abslvlworld.h   |  1 +
 src/CrawlTestLvl/private/world.cpp           |  4 +++
 src/CrawlTestLvl/private/world.h             |  5 +---
 src/JungleLvl/private/world.cpp              |  4 +++
 src/JungleLvl/private/world.h                |  1 +
 tests/units/clasterstest.cpp                 |  2 ++
 15 files changed, 89 insertions(+), 9 deletions(-)

diff --git a/src/Core/Crawl/clientapp.cpp b/src/Core/Crawl/clientapp.cpp
index 45efbc2..e8f0244 100644
--- a/src/Core/Crawl/clientapp.cpp
+++ b/src/Core/Crawl/clientapp.cpp
@@ -14,6 +14,7 @@
 #include <QQmlApplicationEngine>
 #include <QQmlContext>
 #include <quasarapp.h>
+#include <store.h>
 
 #include <engine.h>
 #include <qmlnotifyservice.h>
@@ -38,6 +39,7 @@ QByteArray ClientApp::initTheme() {
 ClientApp::ClientApp() {
     _engine = new Engine();
     _menu = new MainMenuModel();
+    _store = new Store();
 
     connect(_menu, &MainMenuModel::sigNewGame, this, &ClientApp::start);
 }
@@ -45,6 +47,7 @@ ClientApp::ClientApp() {
 ClientApp::~ClientApp() {
     delete _menu;
     delete _engine;
+    delete _store;
 
     for (auto it = _availableLvls.begin(); it != _availableLvls.end(); ++it) {
         delete it.value().viewModel;
@@ -64,6 +67,15 @@ IWorld *ClientApp::getLastWorld() {
     return nullptr;
 }
 
+void ClientApp::initStore(Store *store) {
+    QMultiHash<int, const IItem *> storeItems;
+    for (const auto &data : qAsConst(_availableLvls)) {
+        storeItems.unite(data.model->childItemsRecursive());
+    }
+
+    store->init(storeItems);
+}
+
 void ClientApp::start(const QString &lvl) {
     WordlData data = _availableLvls.value(lvl);
 
@@ -123,6 +135,7 @@ bool ClientApp::init(QQmlApplicationEngine *engine) {
 
     _engine->setWorld(getLastWorld());
     _engine->setQmlEngine(engine);
+    initStore(_store);
 
     return true;
 }
diff --git a/src/Core/Crawl/clientapp.h b/src/Core/Crawl/clientapp.h
index 184e7ab..69b9dd0 100644
--- a/src/Core/Crawl/clientapp.h
+++ b/src/Core/Crawl/clientapp.h
@@ -25,6 +25,7 @@ class IWorld;
 class WorldViewData;
 class MainMenuModel;
 class IControl;
+class Store;
 
 
 /**
@@ -69,6 +70,7 @@ private:
     QByteArray initTheme();
     IWorld* getLastWorld();
 
+    void initStore(Store* store);
     /**
      * @brief addLvl This method should be add level to game.
      * @param levelWordl This is world instance
@@ -84,6 +86,7 @@ private:
     QHash<QString, WordlData> _availableLvls;
     MainMenuModel *_menu = nullptr;
     Engine *_engine = nullptr;
+    Store *_store = nullptr;
 };
 
 }
diff --git a/src/Core/Crawl/iitem.cpp b/src/Core/Crawl/iitem.cpp
index 504b66b..37e6275 100644
--- a/src/Core/Crawl/iitem.cpp
+++ b/src/Core/Crawl/iitem.cpp
@@ -15,6 +15,25 @@ IItem::IItem() {
 
 }
 
+QList<const IItem *> IItem::childItems() const {
+    return _childs;
+}
+
+QMultiHash<int, const IItem *> IItem::childItemsRecursive() const {
+    QMultiHash<int, const IItem *> result;
+
+    for (const IItem* item : _childs) {
+        result.unite(item->childItemsRecursive());
+    }
+
+    result.insert(itemId(), this);
+    return result;
+}
+
+void IItem::addChildItem(const IItem *item) {
+    _childs.push_back(item);
+}
+
 unsigned int IItem::itemId() {
     if (_id) {
         return _id;
@@ -25,6 +44,10 @@ unsigned int IItem::itemId() {
 }
 
 unsigned int IItem::itemId() const {
-    return _id;
+    if (_id) {
+        return _id;
+    }
+
+    return qHash(itemTextId());
 }
 }
diff --git a/src/Core/Crawl/iitem.h b/src/Core/Crawl/iitem.h
index c5473a3..5e2936d 100644
--- a/src/Core/Crawl/iitem.h
+++ b/src/Core/Crawl/iitem.h
@@ -9,6 +9,7 @@
 #ifndef IITEM_H
 #define IITEM_H
 
+#include <QList>
 #include <QString>
 #include "global.h"
 
@@ -61,6 +62,31 @@ public:
      */
     virtual int requiredTier() const = 0;
 
+    /**
+     * @brief childItems This method shold be return list of the child items available for unlocked for this item.
+     * @return list of the child items pointers.
+     * @note The child items connot be removed automaticalu. All child items will be removed in the Store object.
+     * @see IItem::addChildItem
+     * @see IItem::childItemsRecursive
+     */
+    QList<const IItem*> childItems() const;
+
+    /**
+     * @brief childItemsRecursive This method return hash map of all items of this item.
+     * @note This method working recursive.
+     * @return Hash map of the all child items (include current item).
+     * @see IItem::addChildItem
+     * @see IItem::childItems
+     */
+    QMultiHash<int, const IItem *> childItemsRecursive() const;
+
+    /**
+     * @brief addChildItem This method add child item.
+     * @param item This is pointe of the item.
+     * @see IItem::childItems
+     */
+    void addChildItem(const IItem* item);
+
     /**
      * @brief itemId This method return hash of the IItem::itemTextId.
      * @return hash of the IItem::itemTextId.
@@ -77,6 +103,7 @@ public:
 
 private:
     unsigned int _id = 0;
+    QList<const IItem*> _childs;
 };
 
 }
diff --git a/src/Core/private/engine.cpp b/src/Core/private/engine.cpp
index d8c9b3b..f8ae55e 100644
--- a/src/Core/private/engine.cpp
+++ b/src/Core/private/engine.cpp
@@ -15,11 +15,11 @@
 #include "Crawl/icontrol.h"
 #include "QDateTime"
 #include "QtConcurrent"
+#include "store.h"
 
 namespace CRAWL {
 
 Engine::Engine(QObject *parent): QObject(parent) {
-
 }
 
 Engine::~Engine() {
diff --git a/src/Core/private/engine.h b/src/Core/private/engine.h
index c27a114..feaac87 100644
--- a/src/Core/private/engine.h
+++ b/src/Core/private/engine.h
@@ -16,6 +16,7 @@
 namespace CRAWL {
 
 class IWorld;
+class Store;
 
 /**
  * @brief The Engine class
diff --git a/src/Core/private/store.cpp b/src/Core/private/store.cpp
index 75ebb4f..423d49e 100644
--- a/src/Core/private/store.cpp
+++ b/src/Core/private/store.cpp
@@ -34,7 +34,7 @@ bool Store::buy(User &buyer, int itemId) {
     return true;
 }
 
-bool Store::init(const QHash<int, const IItem *> &availabelItems) {
+bool Store::init(const QMultiHash<int, const IItem *> &availabelItems) {
     _store = availabelItems;
 
     return true;
diff --git a/src/Core/private/store.h b/src/Core/private/store.h
index 087cad2..8454166 100644
--- a/src/Core/private/store.h
+++ b/src/Core/private/store.h
@@ -36,7 +36,7 @@ public:
      * @param availabelItems This is hash of the available item.
      * @return true if the items inited successfuly else false.
      */
-    bool init(const QHash<int, const IItem*>& availabelItems);
+    bool init(const QMultiHash<int, const IItem *> &availabelItems);
 
     /**
      * @brief getItemById This method return item by id.
@@ -46,7 +46,7 @@ public:
     const IItem* getItemById(int id) const;
 
 private:
-    QHash<int, const IItem*> _store;
+    QMultiHash<int, const IItem*> _store;
 };
 }
 #endif // STORE_H
diff --git a/src/CrawlAbstractLvl/private/abslvlworld.cpp b/src/CrawlAbstractLvl/private/abslvlworld.cpp
index 5050c43..24657d5 100644
--- a/src/CrawlAbstractLvl/private/abslvlworld.cpp
+++ b/src/CrawlAbstractLvl/private/abslvlworld.cpp
@@ -85,4 +85,8 @@ QString AbsLvlWorld::itemTextId() const {
     return "AbstractLevel";
 }
 
+int AbsLvlWorld::requiredTier() const {
+    return 0;
+}
+
 }
diff --git a/src/CrawlAbstractLvl/private/abslvlworld.h b/src/CrawlAbstractLvl/private/abslvlworld.h
index 2944ae4..56f5454 100644
--- a/src/CrawlAbstractLvl/private/abslvlworld.h
+++ b/src/CrawlAbstractLvl/private/abslvlworld.h
@@ -29,6 +29,7 @@ public:
     CRAWL::IControl *initUserInterface() const override;
     void initPlayerControl(CRAWL::IControl *control) override;
     QString itemTextId() const override;
+    int requiredTier() const override;
 
 };
 
diff --git a/src/CrawlTestLvl/private/world.cpp b/src/CrawlTestLvl/private/world.cpp
index dc8b0fe..a373c60 100644
--- a/src/CrawlTestLvl/private/world.cpp
+++ b/src/CrawlTestLvl/private/world.cpp
@@ -85,6 +85,10 @@ QString World::itemTextId() const {
     return "TestLevel";
 }
 
+int World::requiredTier() const {
+    return 0;
+}
+
 void World::handleXViewChanged(double dx) {
     auto eilorRotation = cameraRotation().toEulerAngles();
     eilorRotation.setX(eilorRotation.x() + dx);
diff --git a/src/CrawlTestLvl/private/world.h b/src/CrawlTestLvl/private/world.h
index a1f42f2..03365cb 100644
--- a/src/CrawlTestLvl/private/world.h
+++ b/src/CrawlTestLvl/private/world.h
@@ -31,14 +31,11 @@ public:
     CRAWL::PlayableObject *initPlayer() const override;
     CRAWL::IAI *initBackGroundAI() const override;
     QString itemTextId() const override;
+    int requiredTier() const override;
 
 private slots:
     void handleXViewChanged(double dx);
     void handleYViewChanged(double dy);
-
-
-
-
 };
 
 
diff --git a/src/JungleLvl/private/world.cpp b/src/JungleLvl/private/world.cpp
index e80ebb7..8c1b314 100644
--- a/src/JungleLvl/private/world.cpp
+++ b/src/JungleLvl/private/world.cpp
@@ -120,6 +120,10 @@ QString World::itemTextId() const {
     return "JungleLevel";
 }
 
+int World::requiredTier() const {
+    return 0;
+}
+
 void World::handleXViewChanged(double dx) {
     auto eilorRotation = cameraRotation().toEulerAngles();
     eilorRotation.setX(eilorRotation.x() + dx);
diff --git a/src/JungleLvl/private/world.h b/src/JungleLvl/private/world.h
index 3c323e3..9320b2e 100644
--- a/src/JungleLvl/private/world.h
+++ b/src/JungleLvl/private/world.h
@@ -30,6 +30,7 @@ public:
     CRAWL::PlayableObject *initPlayer() const override;
     CRAWL::IAI *initBackGroundAI() const override;
     QString itemTextId() const override;
+    int requiredTier() const override;
 
 private slots:
     void handleXViewChanged(double dx);
diff --git a/tests/units/clasterstest.cpp b/tests/units/clasterstest.cpp
index a63bcc5..f341674 100644
--- a/tests/units/clasterstest.cpp
+++ b/tests/units/clasterstest.cpp
@@ -53,6 +53,8 @@ public:
     QString itemName() const override {return "TestWorld";};
     int cost() const override {return 0;};
     QString itemTextId() const override {return "TestWorld";};
+    int requiredTier() const override {return 0;};
+
     friend class ClastersTest;
 };
 

From 4b23cdacfab1c3e2f8aaafdd3cdc0dbae8cf37bc Mon Sep 17 00:00:00 2001
From: EndrII <EndrIIMail@gmail.com>
Date: Mon, 9 Aug 2021 16:44:52 +0300
Subject: [PATCH 14/19] added first action function

---
 src/Core/Crawl/iworld.cpp        | 7 +++++--
 src/Core/Crawl/iworld.h          | 2 +-
 src/Core/Crawl/iworlditem.cpp    | 4 ++++
 src/Core/Crawl/iworlditem.h      | 7 +++++++
 src/Core/private/eventserver.cpp | 2 +-
 src/Core/private/eventserver.h   | 3 ++-
 6 files changed, 20 insertions(+), 5 deletions(-)

diff --git a/src/Core/Crawl/iworld.cpp b/src/Core/Crawl/iworld.cpp
index 8a6f9f9..528d7e7 100644
--- a/src/Core/Crawl/iworld.cpp
+++ b/src/Core/Crawl/iworld.cpp
@@ -360,8 +360,11 @@ void IWorld::updateWorld() {
     }
 }
 
-void IWorld::onIntersects(QList<const IWorldItem *> list) {
-    Q_UNUSED(list);
+void IWorld::onIntersects(const IWorldItem *trigger, QList<const IWorldItem *> list) {
+
+    for (const IWorldItem* item : list) {
+        const_cast<IWorldItem*>(item)->action(const_cast<IWorldItem*>(trigger));
+    }
 }
 
 const QQuaternion &IWorld::cameraRotation() const {
diff --git a/src/Core/Crawl/iworld.h b/src/Core/Crawl/iworld.h
index fd6dfd4..6f712ab 100644
--- a/src/Core/Crawl/iworld.h
+++ b/src/Core/Crawl/iworld.h
@@ -370,7 +370,7 @@ protected:
     void updateWorld();
 
 protected slots:
-    virtual void onIntersects(QList<const IWorldItem *> list);
+    virtual void onIntersects(const IWorldItem * trigger, QList<const IWorldItem *> list);
 
 private slots:
 
diff --git a/src/Core/Crawl/iworlditem.cpp b/src/Core/Crawl/iworlditem.cpp
index 4ca9e24..dd18590 100644
--- a/src/Core/Crawl/iworlditem.cpp
+++ b/src/Core/Crawl/iworlditem.cpp
@@ -75,6 +75,10 @@ bool IWorldItem::destroyIsScheduled() const {
     return _fDistroy;
 }
 
+void IWorldItem::action(IWorldItem *) {
+
+}
+
 void IWorldItem::setSupportedEvents(int newSupportedEvents) {
     _supportedEvents = newSupportedEvents;
 }
diff --git a/src/Core/Crawl/iworlditem.h b/src/Core/Crawl/iworlditem.h
index 62ed575..e45c85b 100644
--- a/src/Core/Crawl/iworlditem.h
+++ b/src/Core/Crawl/iworlditem.h
@@ -77,6 +77,13 @@ public:
      */
     bool destroyIsScheduled() const;
 
+    /**
+     * @brief action This method contains actions releative another game objects.
+     * @param item This is pointer to item that will be interaction with this object.
+     * @note The default implementation do nothing.
+     */
+    virtual void action(IWorldItem* item);
+
 protected:
 
     /**
diff --git a/src/Core/private/eventserver.cpp b/src/Core/private/eventserver.cpp
index 76ad6e1..b4393b6 100644
--- a/src/Core/private/eventserver.cpp
+++ b/src/Core/private/eventserver.cpp
@@ -75,7 +75,7 @@ void EventServer::eventProcess() {
                 }
 
                 if (result.size()) {
-                    emit sigIntersect(result << item);
+                    emit sigIntersect(item, result);
                 }
                 break;
             }
diff --git a/src/Core/private/eventserver.h b/src/Core/private/eventserver.h
index 99d7add..3e2494f 100644
--- a/src/Core/private/eventserver.h
+++ b/src/Core/private/eventserver.h
@@ -51,9 +51,10 @@ public slots:
 signals:
     /**
      * @brief sigIntersect This signal emit when objects intersect on the world.
+     * @param trigger This is pointer to object that support this evvent.
      * @param objects This is list of the intersects objects.
      */
-    void sigIntersect(QList<const IWorldItem*> objects);
+    void sigIntersect(const IWorldItem* trigger, QList<const IWorldItem*> objects);
 
 private:
     void eventProcess();

From 3adc7c9eb3fcb14bfc250239b876ac2d96778404 Mon Sep 17 00:00:00 2001
From: EndrII <EndrIIMail@gmail.com>
Date: Mon, 9 Aug 2021 18:30:18 +0300
Subject: [PATCH 15/19] first work action

---
 src/Core/Crawl/day.h                             |  3 ---
 src/Core/Crawl/defaultlight.cpp                  |  3 ---
 src/Core/Crawl/defaultlight.h                    |  4 ----
 src/Core/Crawl/fire.cpp                          |  3 +--
 src/Core/Crawl/guiobject.cpp                     | 10 +++++++---
 src/Core/Crawl/guiobject.h                       |  8 ++++++++
 src/Core/Crawl/iworlditem.h                      |  6 ------
 src/Core/Crawl/particleeffect.cpp                |  1 +
 src/Core/Crawl/snake.h                           |  2 ++
 src/Core/Crawl/wint.cpp                          |  2 --
 src/Core/Crawl/wint.h                            |  3 +--
 src/Core/private/eventserver.cpp                 |  2 +-
 src/CrawlAbstractLvl/private/abslvlsnake.cpp     |  3 ---
 src/CrawlAbstractLvl/private/abslvlsnake.h       |  4 ----
 src/CrawlAbstractLvl/private/abslvlsnakeitem.cpp |  5 -----
 src/CrawlAbstractLvl/private/abslvlsnakeitem.h   |  3 ---
 src/CrawlAbstractLvl/private/baff.cpp            |  3 ---
 src/CrawlAbstractLvl/private/baff.h              |  4 ----
 src/CrawlAbstractLvl/private/obstacleblue.cpp    |  4 ----
 src/CrawlAbstractLvl/private/obstacleblue.h      |  4 ----
 src/CrawlAbstractLvl/private/obstaclered.cpp     |  4 ----
 src/CrawlAbstractLvl/private/obstaclered.h       |  3 ---
 src/CrawlTestLvl/private/background.cpp          |  4 ----
 src/CrawlTestLvl/private/background.h            |  7 -------
 src/CrawlTestLvl/private/box.cpp                 | 11 +++++++++--
 src/CrawlTestLvl/private/box.h                   |  5 +----
 src/CrawlTestLvl/private/plate.cpp               |  4 ----
 src/CrawlTestLvl/private/plate.h                 |  4 ----
 src/CrawlTestLvl/private/testsnake.cpp           |  6 +-----
 src/CrawlTestLvl/private/testsnake.h             |  4 ----
 src/CrawlTestLvl/private/testsnakeitem.cpp       |  4 ----
 src/CrawlTestLvl/private/testsnakeitem.h         |  4 ----
 src/CrawlTestLvl/private/world.cpp               |  2 +-
 src/JungleLvl/private/absaluteplate.cpp          |  2 --
 src/JungleLvl/private/absaluteplate.h            |  4 ----
 src/JungleLvl/private/grees.cpp                  |  4 ----
 src/JungleLvl/private/grees.h                    |  4 ----
 src/JungleLvl/private/ground.cpp                 |  4 ----
 src/JungleLvl/private/ground.h                   |  7 -------
 src/JungleLvl/private/groundplate.cpp            |  4 ----
 src/JungleLvl/private/groundplate.h              |  3 ---
 src/JungleLvl/private/longgress.cpp              |  3 ---
 src/JungleLvl/private/longgress.h                |  3 ---
 src/JungleLvl/private/snake.cpp                  |  4 ----
 src/JungleLvl/private/snake.h                    |  1 -
 src/JungleLvl/private/snakeitem.cpp              |  4 ----
 src/JungleLvl/private/snakeitem.h                |  4 ----
 src/JungleLvl/private/tree.cpp                   |  3 ---
 src/JungleLvl/private/tree.h                     |  4 ----
 tests/units/groupobjecttest.cpp                  |  4 ----
 50 files changed, 33 insertions(+), 168 deletions(-)

diff --git a/src/Core/Crawl/day.h b/src/Core/Crawl/day.h
index bc20a2b..a509b06 100644
--- a/src/Core/Crawl/day.h
+++ b/src/Core/Crawl/day.h
@@ -167,9 +167,6 @@ public:
         }
     }
 
-protected:
-    void onIntersects(const IWorldItem *) override {};
-
 private:
     float lengthToSpeed(float length) const {
         return (2 * M_PI * radius()) / length;
diff --git a/src/Core/Crawl/defaultlight.cpp b/src/Core/Crawl/defaultlight.cpp
index 51538ce..f0c915f 100644
--- a/src/Core/Crawl/defaultlight.cpp
+++ b/src/Core/Crawl/defaultlight.cpp
@@ -24,7 +24,4 @@ void DefaultLight::init() {
 
 }
 
-void DefaultLight::onIntersects(const IWorldItem *) {
-
-}
 }
diff --git a/src/Core/Crawl/defaultlight.h b/src/Core/Crawl/defaultlight.h
index 50c14e2..1343365 100644
--- a/src/Core/Crawl/defaultlight.h
+++ b/src/Core/Crawl/defaultlight.h
@@ -26,10 +26,6 @@ public:
 
     void render(unsigned int tbfMsec) override;
     void init() override;
-
-    // IWorldItem interface
-protected:
-    void onIntersects(const IWorldItem *item) override;
 };
 
 }
diff --git a/src/Core/Crawl/fire.cpp b/src/Core/Crawl/fire.cpp
index 4c40764..e3b67f6 100644
--- a/src/Core/Crawl/fire.cpp
+++ b/src/Core/Crawl/fire.cpp
@@ -19,8 +19,7 @@ Fire::Fire(): ParticleEffect(AUTO_CLASS_NAME, "qrc:/CrawlModule/particles/Fire.q
 
     setLifeSpanVariation(500);
     setColor("#ffaf2c");
-    setSize({1, 1, 1});
-    setposition({0,0,10});
+    setposition({0,0,1});
     setEnabled(true);
 
     setParticleDelegate("qrc:/CrawlModule/particles/FireParticel.qml");
diff --git a/src/Core/Crawl/guiobject.cpp b/src/Core/Crawl/guiobject.cpp
index ff776f1..9642fb3 100644
--- a/src/Core/Crawl/guiobject.cpp
+++ b/src/Core/Crawl/guiobject.cpp
@@ -36,6 +36,10 @@ void GuiObject::generateId() {
     setGuiId(id++);
 }
 
+void GuiObject::setContainerSize(const QVector3D &newContainerSize) {
+    _containerSize = newContainerSize;
+}
+
 bool GuiObject::visible() const {
     return _visible;
 }
@@ -132,14 +136,14 @@ QVector3D GuiObject::center() const {
 }
 
 bool GuiObject::intersects(const QVector3D &point) const {
-    auto radius = _size / 2;
+    auto radius = _containerSize / 2;
     float thisMidRadius = (radius.z() + radius.y() + radius.x()) / 3;
     return center().distanceToPoint(point) < thisMidRadius ;
 }
 
 bool GuiObject::intersects(const GuiObject &object) const {
-    auto radius = _size / 2;
-    auto objRadius = object.size() / 2;
+    auto radius = _containerSize / 2;
+    auto objRadius = object._containerSize / 2;
     float thisMidRadius = (radius.z() + radius.y() + radius.x()) / 3;
     float objMidRadius = (objRadius.z() + objRadius.y() + objRadius.x()) / 3;
 
diff --git a/src/Core/Crawl/guiobject.h b/src/Core/Crawl/guiobject.h
index 727968e..ab362be 100644
--- a/src/Core/Crawl/guiobject.h
+++ b/src/Core/Crawl/guiobject.h
@@ -157,6 +157,13 @@ public:
     int guiId() const;
     void setGuiId(int guiId);
 
+    /**
+     * @brief containerSize This method sets container size of object. Change this propertye for setting correct work the GuiObject::intersects method.
+     * @param newContainerSize new is new value of the object contaier cube.
+     * @see GuiObject::intersects
+     */
+    void setContainerSize(const QVector3D &newContainerSize);
+
 signals:
     void guiIdChanged(int guiId);
     void colorChanged(QString color);
@@ -213,6 +220,7 @@ private:
 
     QVector3D _position;
     QVector3D _size;
+    QVector3D _containerSize = {1,1,1};
     QQuaternion _rotation;
     QString _mash;
     QString _className;
diff --git a/src/Core/Crawl/iworlditem.h b/src/Core/Crawl/iworlditem.h
index e45c85b..8e60047 100644
--- a/src/Core/Crawl/iworlditem.h
+++ b/src/Core/Crawl/iworlditem.h
@@ -86,12 +86,6 @@ public:
 
 protected:
 
-    /**
-     * @brief onIntersects This is intersect event betwin this and subscribet objects.
-     * @param item This is pointer to the event object.
-     */
-    virtual void onIntersects(const IWorldItem *item) = 0;
-
     /**
      * @brief getItem This method return item world by id. If object is not exits then return nullptr.
      * @return constant pointer tot the item world.
diff --git a/src/Core/Crawl/particleeffect.cpp b/src/Core/Crawl/particleeffect.cpp
index fd4fa6f..e998e11 100644
--- a/src/Core/Crawl/particleeffect.cpp
+++ b/src/Core/Crawl/particleeffect.cpp
@@ -17,6 +17,7 @@ ParticleEffect::ParticleEffect(const QString &name,
                                QObject *ptr):
     IWorldItem(name, viewTempalte, ptr) {
 
+    setFDecorative(true);
 }
 
 bool ParticleEffect::enabled() const {
diff --git a/src/Core/Crawl/snake.h b/src/Core/Crawl/snake.h
index 497e4d3..4fc5423 100644
--- a/src/Core/Crawl/snake.h
+++ b/src/Core/Crawl/snake.h
@@ -131,6 +131,8 @@ private:
     QVector3D* _vectors;
     float _speed;
 
+    int _hp = 100;
+
 };
 
 }
diff --git a/src/Core/Crawl/wint.cpp b/src/Core/Crawl/wint.cpp
index 8660c2c..19cbc1e 100644
--- a/src/Core/Crawl/wint.cpp
+++ b/src/Core/Crawl/wint.cpp
@@ -13,8 +13,6 @@ namespace CRAWL {
 Wint::Wint(): Affector(AUTO_CLASS_NAME, "qrc:/CrawlModule/particles/Wint.qml") {
 }
 
-void Wint::onIntersects(const IWorldItem *) {}
-
 float Wint::magnitude() const {
     return _magnitude;
 }
diff --git a/src/Core/Crawl/wint.h b/src/Core/Crawl/wint.h
index 5ec9051..c3cb74f 100644
--- a/src/Core/Crawl/wint.h
+++ b/src/Core/Crawl/wint.h
@@ -66,8 +66,7 @@ signals:
     void directionChanged();
     void magnitudeChanged();
 
-protected:
-    void onIntersects(const IWorldItem *item) override;
+private:
 
     QVector3D _direction = {1, 0, 0};
     float _magnitude = 10;
diff --git a/src/Core/private/eventserver.cpp b/src/Core/private/eventserver.cpp
index b4393b6..fe6f097 100644
--- a/src/Core/private/eventserver.cpp
+++ b/src/Core/private/eventserver.cpp
@@ -41,7 +41,7 @@ void EventServer::handleAvailableObjectChanges(const Diff &diff) {
     for (int added: diff.addedIds) {
         auto obj = _worldInstance->getItem(added);
 
-        if (!obj->isDecorative()) {
+        if (obj->isDecorative()) {
             continue;
         }
 
diff --git a/src/CrawlAbstractLvl/private/abslvlsnake.cpp b/src/CrawlAbstractLvl/private/abslvlsnake.cpp
index 90d7ed3..7aa1338 100644
--- a/src/CrawlAbstractLvl/private/abslvlsnake.cpp
+++ b/src/CrawlAbstractLvl/private/abslvlsnake.cpp
@@ -30,8 +30,5 @@ AbsLvlSnake::AbsLvlSnake(): Snake(AUTO_CLASS_NAME) {
     registerItemType<AbsLvlSnakeItem>();
 }
 
-void AbsLvlSnake::onIntersects(const IWorldItem *item) {
-    Q_UNUSED(item);
-}
 
 }
diff --git a/src/CrawlAbstractLvl/private/abslvlsnake.h b/src/CrawlAbstractLvl/private/abslvlsnake.h
index 3b07aec..73f3f66 100644
--- a/src/CrawlAbstractLvl/private/abslvlsnake.h
+++ b/src/CrawlAbstractLvl/private/abslvlsnake.h
@@ -19,10 +19,6 @@ class AbsLvlSnake : public CRAWL::Snake {
 public:
     AbsLvlSnake();
 
-    // IWorldItem interface
-protected:
-    void onIntersects(const IWorldItem *item) override;
-
 };
 
 }
diff --git a/src/CrawlAbstractLvl/private/abslvlsnakeitem.cpp b/src/CrawlAbstractLvl/private/abslvlsnakeitem.cpp
index 0de3831..cb175e9 100644
--- a/src/CrawlAbstractLvl/private/abslvlsnakeitem.cpp
+++ b/src/CrawlAbstractLvl/private/abslvlsnakeitem.cpp
@@ -15,9 +15,4 @@ AbsLvlSnakeItem::AbsLvlSnakeItem():CRAWL::SnakeItem(AUTO_CLASS_NAME) {
     setSize({1,1,1});
 }
 
-void AbsLvlSnakeItem::onIntersects(const IWorldItem *item) {
-    Q_UNUSED(item);
-
-}
-
 }
diff --git a/src/CrawlAbstractLvl/private/abslvlsnakeitem.h b/src/CrawlAbstractLvl/private/abslvlsnakeitem.h
index 77bea76..07ecc72 100644
--- a/src/CrawlAbstractLvl/private/abslvlsnakeitem.h
+++ b/src/CrawlAbstractLvl/private/abslvlsnakeitem.h
@@ -19,9 +19,6 @@ class AbsLvlSnakeItem: public CRAWL::SnakeItem {
 public:
     AbsLvlSnakeItem();
 
-    // IWorldItem interface
-protected:
-    void onIntersects(const IWorldItem *item) override;
 };
 
 }
diff --git a/src/CrawlAbstractLvl/private/baff.cpp b/src/CrawlAbstractLvl/private/baff.cpp
index 47b5e7f..770a3ec 100644
--- a/src/CrawlAbstractLvl/private/baff.cpp
+++ b/src/CrawlAbstractLvl/private/baff.cpp
@@ -17,8 +17,5 @@ Baff::Baff() : IWorldItem(AUTO_CLASS_NAME) {
     setZ(0);
 }
 
-void Baff::onIntersects(const IWorldItem *item) {
-        Q_UNUSED(item);
-}
 
 }
diff --git a/src/CrawlAbstractLvl/private/baff.h b/src/CrawlAbstractLvl/private/baff.h
index 7377a38..97ddf65 100644
--- a/src/CrawlAbstractLvl/private/baff.h
+++ b/src/CrawlAbstractLvl/private/baff.h
@@ -14,10 +14,6 @@ namespace AbstractLvl {
 class Baff: public CRAWL::IWorldItem {
 public:
     Baff();
-
-    // IWorldItem interface
-protected:
-    void onIntersects(const IWorldItem *item) override;
 };
 
 }
diff --git a/src/CrawlAbstractLvl/private/obstacleblue.cpp b/src/CrawlAbstractLvl/private/obstacleblue.cpp
index 72259bc..de1b766 100644
--- a/src/CrawlAbstractLvl/private/obstacleblue.cpp
+++ b/src/CrawlAbstractLvl/private/obstacleblue.cpp
@@ -16,8 +16,4 @@ ObstacleBlue::ObstacleBlue() : IWorldItem(AUTO_CLASS_NAME) {
     setZ(0);
 }
 
-void ObstacleBlue::onIntersects(const IWorldItem *item) {
-        Q_UNUSED(item);
-}
-
 }
diff --git a/src/CrawlAbstractLvl/private/obstacleblue.h b/src/CrawlAbstractLvl/private/obstacleblue.h
index 1506373..55e55e2 100644
--- a/src/CrawlAbstractLvl/private/obstacleblue.h
+++ b/src/CrawlAbstractLvl/private/obstacleblue.h
@@ -14,10 +14,6 @@ namespace AbstractLvl {
 class ObstacleBlue: public CRAWL::IWorldItem {
 public:
     ObstacleBlue();
-
-    // IWorldItem interface
-protected:
-    void onIntersects(const IWorldItem *item) override;
 };
 
 }
diff --git a/src/CrawlAbstractLvl/private/obstaclered.cpp b/src/CrawlAbstractLvl/private/obstaclered.cpp
index 60a42c5..e0d03ac 100644
--- a/src/CrawlAbstractLvl/private/obstaclered.cpp
+++ b/src/CrawlAbstractLvl/private/obstaclered.cpp
@@ -16,8 +16,4 @@ ObstacleRed::ObstacleRed() : IWorldItem(AUTO_CLASS_NAME) {
     setZ(0);
 }
 
-void ObstacleRed::onIntersects(const IWorldItem *item) {
-        Q_UNUSED(item);
-}
-
 }
diff --git a/src/CrawlAbstractLvl/private/obstaclered.h b/src/CrawlAbstractLvl/private/obstaclered.h
index c82c017..24bd915 100644
--- a/src/CrawlAbstractLvl/private/obstaclered.h
+++ b/src/CrawlAbstractLvl/private/obstaclered.h
@@ -15,9 +15,6 @@ class ObstacleRed: public CRAWL::IWorldItem {
 public:
     ObstacleRed();
 
-    // IWorldItem interface
-protected:
-    void onIntersects(const IWorldItem *item) override;
 };
 
 }
diff --git a/src/CrawlTestLvl/private/background.cpp b/src/CrawlTestLvl/private/background.cpp
index 454aa04..d005ba6 100644
--- a/src/CrawlTestLvl/private/background.cpp
+++ b/src/CrawlTestLvl/private/background.cpp
@@ -14,10 +14,6 @@ Background::Background(): CRAWL::GroundClaster("TestBackground") {
     registerItemType<Plate>();
 }
 
-void Background::onIntersects(const IWorldItem *item) {
-    Q_UNUSED(item)
-}
-
 unsigned int Background::itemsCount() const {
     return 3;
 }
diff --git a/src/CrawlTestLvl/private/background.h b/src/CrawlTestLvl/private/background.h
index 02196eb..0d8816c 100644
--- a/src/CrawlTestLvl/private/background.h
+++ b/src/CrawlTestLvl/private/background.h
@@ -19,13 +19,6 @@ class Background: public CRAWL::GroundClaster
 {
 public:
     Background();
-
-    // IWorldItem interface
-protected:
-    void onIntersects(const IWorldItem *item) override;
-
-    // AutoGenerateClaster interface
-public:
     unsigned int itemsCount() const override;
 };
 
diff --git a/src/CrawlTestLvl/private/box.cpp b/src/CrawlTestLvl/private/box.cpp
index 1d49667..3002463 100644
--- a/src/CrawlTestLvl/private/box.cpp
+++ b/src/CrawlTestLvl/private/box.cpp
@@ -24,9 +24,16 @@ Box::Box(): IWorldItem("Box") {
     setposition({static_cast<float>(rand() % 100) - 50,
                  static_cast<float>(rand() % 100) - 50,
                  0 });
+
+    setFDecorative(false);
+
+    setContainerSize({4, 4, 4});
 }
 
-void Box::onIntersects(const IWorldItem *item) {
-    Q_UNUSED(item);
+void Box::action(IWorldItem *item) {
+    if (item->className() == getPlayer()->className()) {
+        respawn();
+    }
 }
+
 }
diff --git a/src/CrawlTestLvl/private/box.h b/src/CrawlTestLvl/private/box.h
index 7a9ae7e..2f86385 100644
--- a/src/CrawlTestLvl/private/box.h
+++ b/src/CrawlTestLvl/private/box.h
@@ -16,10 +16,7 @@ class Box: public CRAWL::IWorldItem {
 
 public:
     Box();
-
-    // IWorldItem interface
-protected:
-    void onIntersects(const IWorldItem *item) override;
+    void action(IWorldItem *item) override;
 };
 }
 #endif // BOX_H
diff --git a/src/CrawlTestLvl/private/plate.cpp b/src/CrawlTestLvl/private/plate.cpp
index 4ecb3c3..0f41f1f 100644
--- a/src/CrawlTestLvl/private/plate.cpp
+++ b/src/CrawlTestLvl/private/plate.cpp
@@ -18,10 +18,6 @@ Plate::Plate(): CRAWL::GroundTile("TestPlate")
     setZ(0);
 }
 
-void Plate::onIntersects(const IWorldItem *item) {
-    Q_UNUSED(item)
-}
-
 void Plate::render(unsigned int){
 
 }
diff --git a/src/CrawlTestLvl/private/plate.h b/src/CrawlTestLvl/private/plate.h
index 991ac08..f73c5e4 100644
--- a/src/CrawlTestLvl/private/plate.h
+++ b/src/CrawlTestLvl/private/plate.h
@@ -19,10 +19,6 @@ class Plate: public CRAWL::GroundTile {
 public:
     Plate();
 
-    // IWorldItem interface
-protected:
-    void onIntersects(const IWorldItem *item) override;
-
     // IRender interface
 public:
     void render(unsigned int tbfMsec) override;
diff --git a/src/CrawlTestLvl/private/testsnake.cpp b/src/CrawlTestLvl/private/testsnake.cpp
index e6e65d0..b1c1fc7 100644
--- a/src/CrawlTestLvl/private/testsnake.cpp
+++ b/src/CrawlTestLvl/private/testsnake.cpp
@@ -18,11 +18,7 @@ TestSnake::TestSnake(): Snake("Snake") {
     setSize({2,1,1});
 
     registerItemType<TestSnakeItem>();
-
-}
-
-void TestSnake::onIntersects(const IWorldItem *item) {
-    Q_UNUSED(item);
+    setContainerSize({2, 2, 2});
 
 }
 
diff --git a/src/CrawlTestLvl/private/testsnake.h b/src/CrawlTestLvl/private/testsnake.h
index b85b9ba..90d358e 100644
--- a/src/CrawlTestLvl/private/testsnake.h
+++ b/src/CrawlTestLvl/private/testsnake.h
@@ -19,10 +19,6 @@ class TestSnake : public CRAWL::Snake {
 public:
     TestSnake();
 
-    // IWorldItem interface
-protected:
-    void onIntersects(const IWorldItem *item) override;
-
 
     // AutoGenerateClaster interface
 public:
diff --git a/src/CrawlTestLvl/private/testsnakeitem.cpp b/src/CrawlTestLvl/private/testsnakeitem.cpp
index 6e86400..7a60c54 100644
--- a/src/CrawlTestLvl/private/testsnakeitem.cpp
+++ b/src/CrawlTestLvl/private/testsnakeitem.cpp
@@ -15,8 +15,4 @@ TestSnakeItem::TestSnakeItem():CRAWL::SnakeItem("TestSnakeItem") {
 
 }
 
-void TestSnakeItem::onIntersects(const IWorldItem *item) {
-    Q_UNUSED(item);
-
-}
 }
diff --git a/src/CrawlTestLvl/private/testsnakeitem.h b/src/CrawlTestLvl/private/testsnakeitem.h
index b2cc1d2..6fe9649 100644
--- a/src/CrawlTestLvl/private/testsnakeitem.h
+++ b/src/CrawlTestLvl/private/testsnakeitem.h
@@ -19,10 +19,6 @@ class TestSnakeItem: public CRAWL::SnakeItem
     Q_OBJECT
 public:
     TestSnakeItem();
-
-    // IWorldItem interface
-protected:
-    void onIntersects(const IWorldItem *item) override;
 };
 
 }
diff --git a/src/CrawlTestLvl/private/world.cpp b/src/CrawlTestLvl/private/world.cpp
index a373c60..4ceb308 100644
--- a/src/CrawlTestLvl/private/world.cpp
+++ b/src/CrawlTestLvl/private/world.cpp
@@ -31,7 +31,7 @@ CRAWL::WorldRule *World::initWorldRules() {
     using Day = CRAWL::Day<CRAWL::Sun, CRAWL::Moon>;
 
     return new CRAWL::WorldRule {
-        {0, {{registerObject<Box>(), 100},
+        {0, {{registerObject<Box>(), 1000},
              {registerObject<CRAWL::Fire>(), 10},
              {registerObject<CRAWL::DynamicWint>(), 1},
 
diff --git a/src/JungleLvl/private/absaluteplate.cpp b/src/JungleLvl/private/absaluteplate.cpp
index 90000f3..d29f8e9 100644
--- a/src/JungleLvl/private/absaluteplate.cpp
+++ b/src/JungleLvl/private/absaluteplate.cpp
@@ -16,8 +16,6 @@ AbsalutePlate::AbsalutePlate(): CRAWL::IWorldItem(AUTO_CLASS_NAME) {
     setColor("#000000");
 }
 
-void AbsalutePlate::onIntersects(const IWorldItem *) {}
-
 void AbsalutePlate::render(unsigned int ) {
     setposition(getPlayer()->position() + QVector3D{0,0,-100});
 }
diff --git a/src/JungleLvl/private/absaluteplate.h b/src/JungleLvl/private/absaluteplate.h
index 1ee3c52..e7246fa 100644
--- a/src/JungleLvl/private/absaluteplate.h
+++ b/src/JungleLvl/private/absaluteplate.h
@@ -11,10 +11,6 @@ class AbsalutePlate : public CRAWL::IWorldItem
 public:
     AbsalutePlate();
 
-    // IWorldItem interface
-protected:
-    void onIntersects(const IWorldItem *item) override;
-
     // IRender interface
 public:
     void render(unsigned int tbfMsec) override;
diff --git a/src/JungleLvl/private/grees.cpp b/src/JungleLvl/private/grees.cpp
index 67a2457..f25cc4b 100644
--- a/src/JungleLvl/private/grees.cpp
+++ b/src/JungleLvl/private/grees.cpp
@@ -17,8 +17,4 @@ Grees::Grees(): CRAWL::IWorldItem(AUTO_CLASS_NAME) {
 
 }
 
-void Grees::onIntersects(const IWorldItem *) {
-
-}
-
 }
diff --git a/src/JungleLvl/private/grees.h b/src/JungleLvl/private/grees.h
index 712187e..e6133da 100644
--- a/src/JungleLvl/private/grees.h
+++ b/src/JungleLvl/private/grees.h
@@ -23,10 +23,6 @@ class CRAWL_JUNGLE_LEVEL_EXPORT Grees: public CRAWL::IWorldItem
     Q_OBJECT
 public:
     Grees();
-
-    // IWorldItem interface
-protected:
-    void onIntersects(const IWorldItem *item) override;
 };
 }
 #endif // GREES_H
diff --git a/src/JungleLvl/private/ground.cpp b/src/JungleLvl/private/ground.cpp
index a4f116a..baf9bbb 100644
--- a/src/JungleLvl/private/ground.cpp
+++ b/src/JungleLvl/private/ground.cpp
@@ -13,10 +13,6 @@ Ground::Ground() : CRAWL::GroundClaster("JungelGroud") {
     registerItemType<GroundPlate>();
 }
 
-void Ground::onIntersects(const IWorldItem *) {
-
-}
-
 unsigned int Ground::itemsCount() const {
     return 3;
 }
diff --git a/src/JungleLvl/private/ground.h b/src/JungleLvl/private/ground.h
index 46b59fb..6d49d65 100644
--- a/src/JungleLvl/private/ground.h
+++ b/src/JungleLvl/private/ground.h
@@ -20,13 +20,6 @@ class Ground : public CRAWL::GroundClaster
 {
 public:
     Ground();
-
-    // IWorldItem interface
-protected:
-    void onIntersects(const IWorldItem *item) override;
-
-    // AutoGenerateClaster interface
-public:
     unsigned int itemsCount() const override;
 };
 
diff --git a/src/JungleLvl/private/groundplate.cpp b/src/JungleLvl/private/groundplate.cpp
index 28eea8d..f212346 100644
--- a/src/JungleLvl/private/groundplate.cpp
+++ b/src/JungleLvl/private/groundplate.cpp
@@ -21,10 +21,6 @@ GroundPlate::GroundPlate(): CRAWL::GroundTile("JungleGroundTile",
 
 }
 
-void GroundPlate::onIntersects(const IWorldItem *) {
-
-}
-
 int GroundPlate::tiliesCount() const {
     return _tiliesCount;
 }
diff --git a/src/JungleLvl/private/groundplate.h b/src/JungleLvl/private/groundplate.h
index bd86151..a83a982 100644
--- a/src/JungleLvl/private/groundplate.h
+++ b/src/JungleLvl/private/groundplate.h
@@ -30,9 +30,6 @@ public:
 signals:
     void tiliesCountChanged();
 
-protected:
-    void onIntersects(const IWorldItem *item) override;
-
 private:
     int _tiliesCount = 1;
 };
diff --git a/src/JungleLvl/private/longgress.cpp b/src/JungleLvl/private/longgress.cpp
index 06fc34b..2eb1e4e 100644
--- a/src/JungleLvl/private/longgress.cpp
+++ b/src/JungleLvl/private/longgress.cpp
@@ -15,7 +15,4 @@ LongGress::LongGress(): CRAWL::IWorldItem(AUTO_CLASS_NAME) {
     setRotation(QQuaternion::fromEulerAngles({0,0, static_cast<float>(rand() % 360)}));
 }
 
-void LongGress::onIntersects(const IWorldItem *) {
-
-}
 }
diff --git a/src/JungleLvl/private/longgress.h b/src/JungleLvl/private/longgress.h
index 2e495ed..82e519b 100644
--- a/src/JungleLvl/private/longgress.h
+++ b/src/JungleLvl/private/longgress.h
@@ -22,9 +22,6 @@ class CRAWL_JUNGLE_LEVEL_EXPORT LongGress: public CRAWL::IWorldItem
 public:
     LongGress();
 
-    // IWorldItem interface
-protected:
-    void onIntersects(const IWorldItem *item) override;
 };
 
 }
diff --git a/src/JungleLvl/private/snake.cpp b/src/JungleLvl/private/snake.cpp
index 3ffff0b..eacf1c1 100644
--- a/src/JungleLvl/private/snake.cpp
+++ b/src/JungleLvl/private/snake.cpp
@@ -31,10 +31,6 @@ Snake::Snake(): CRAWL::Snake("JungleSnake") {
                              {1, 0.5}});
 }
 
-void Snake::onIntersects(const IWorldItem *) {
-
-}
-
 unsigned int Snake::itemsCount() const {
     return 50;
 }
diff --git a/src/JungleLvl/private/snake.h b/src/JungleLvl/private/snake.h
index e357550..3d49c0c 100644
--- a/src/JungleLvl/private/snake.h
+++ b/src/JungleLvl/private/snake.h
@@ -26,7 +26,6 @@ public:
 
     // IWorldItem interface
 protected:
-    void onIntersects(const IWorldItem *) override;
     unsigned int itemsCount() const override;
 
 };
diff --git a/src/JungleLvl/private/snakeitem.cpp b/src/JungleLvl/private/snakeitem.cpp
index 67b6a90..de4b147 100644
--- a/src/JungleLvl/private/snakeitem.cpp
+++ b/src/JungleLvl/private/snakeitem.cpp
@@ -19,8 +19,4 @@ void SnakeItem::init() {
 
 }
 
-void SnakeItem::onIntersects(const IWorldItem *) {
-
-}
-
 }
diff --git a/src/JungleLvl/private/snakeitem.h b/src/JungleLvl/private/snakeitem.h
index 51d9e5a..9bf3cb9 100644
--- a/src/JungleLvl/private/snakeitem.h
+++ b/src/JungleLvl/private/snakeitem.h
@@ -18,10 +18,6 @@ class SnakeItem : public CRAWL::SnakeItem
 public:
     SnakeItem();
     void init() override;
-
-    // IWorldItem interface
-protected:
-    void onIntersects(const IWorldItem *item) override;
 };
 
 }
diff --git a/src/JungleLvl/private/tree.cpp b/src/JungleLvl/private/tree.cpp
index 5e6fa45..d506126 100644
--- a/src/JungleLvl/private/tree.cpp
+++ b/src/JungleLvl/private/tree.cpp
@@ -31,7 +31,4 @@ Tree::Tree(): CRAWL::IWorldItem(AUTO_CLASS_NAME) {
         setZ(-static_cast<float>(rand() % 10));
 }
 
-void Tree::onIntersects(const IWorldItem *) {
-
-}
 }
diff --git a/src/JungleLvl/private/tree.h b/src/JungleLvl/private/tree.h
index 32975b1..e4090e0 100644
--- a/src/JungleLvl/private/tree.h
+++ b/src/JungleLvl/private/tree.h
@@ -21,10 +21,6 @@ class CRAWL_JUNGLE_LEVEL_EXPORT Tree : public CRAWL::IWorldItem
     Q_OBJECT
 public:
     Tree();
-
-    // IWorldItem interface
-protected:
-    void onIntersects(const IWorldItem *) override;
 };
 }
 #endif // TREE_H
diff --git a/tests/units/groupobjecttest.cpp b/tests/units/groupobjecttest.cpp
index c79f31d..cf60629 100644
--- a/tests/units/groupobjecttest.cpp
+++ b/tests/units/groupobjecttest.cpp
@@ -19,8 +19,6 @@ public:
     TestGroupObject(): CRAWL::IWorldItem(AUTO_CLASS_NAME) {
 
     }
-protected:
-    void onIntersects(const IWorldItem *) override {};
 
     // IRender interface
     void render(unsigned int tbfMsec) override {
@@ -40,8 +38,6 @@ public:
     TestGroupObjectItem(): CRAWL::ClasterItem(AUTO_CLASS_NAME) {
 
     }
-protected:
-    void onIntersects(const IWorldItem *) override {};
 };
 
 GroupObjectTest::GroupObjectTest() {

From 1148a0c566863751256ea9c6b04dea236dc3b2be Mon Sep 17 00:00:00 2001
From: EndrII <EndrIIMail@gmail.com>
Date: Wed, 11 Aug 2021 00:21:22 +0300
Subject: [PATCH 16/19] begin refactoring init level system

---
 src/Core/Crawl.qrc                    |   1 +
 src/Core/Crawl/defaultcontrol.h       |   5 +-
 src/Core/Crawl/iitem.h                |   1 +
 src/Core/Crawl/ilevel.cpp             |  27 ++++++
 src/Core/Crawl/ilevel.h               |  38 +++++++-
 src/Core/Crawl/ipreviewscaneworld.cpp |  47 +++++++++
 src/Core/Crawl/ipreviewscaneworld.h   |  43 ++++++++
 src/Core/Crawl/iworld.cpp             |  14 +--
 src/Core/Crawl/iworld.h               |  11 ++-
 src/Core/Crawl/iworlditem.cpp         |  17 +++-
 src/Core/Crawl/iworlditem.h           |   3 +-
 src/Core/Crawl/player.cpp             |  20 ++++
 src/Core/Crawl/player.h               |  31 ++++++
 src/Core/Crawl/snake.h                |   5 +-
 src/Core/Crawl/startdata.cpp          |  38 ++++++++
 src/Core/Crawl/startdata.h            |  61 ++++++++++++
 src/Core/CrawlModule/PreviewScane.qml | 135 ++++++++++++++++++++++++++
 17 files changed, 474 insertions(+), 23 deletions(-)
 create mode 100644 src/Core/Crawl/ipreviewscaneworld.cpp
 create mode 100644 src/Core/Crawl/ipreviewscaneworld.h
 create mode 100644 src/Core/Crawl/startdata.cpp
 create mode 100644 src/Core/Crawl/startdata.h
 create mode 100644 src/Core/CrawlModule/PreviewScane.qml

diff --git a/src/Core/Crawl.qrc b/src/Core/Crawl.qrc
index b3644af..b8766fd 100644
--- a/src/Core/Crawl.qrc
+++ b/src/Core/Crawl.qrc
@@ -24,5 +24,6 @@
         <file>CrawlCoreAssets/particles/smokeSprite.png</file>
         <file>CrawlModule/particles/Fire.qml</file>
         <file>CrawlModule/particles/Wint.qml</file>
+        <file>CrawlModule/PreviewScane.qml</file>
     </qresource>
 </RCC>
diff --git a/src/Core/Crawl/defaultcontrol.h b/src/Core/Crawl/defaultcontrol.h
index 249176d..fc65cc7 100644
--- a/src/Core/Crawl/defaultcontrol.h
+++ b/src/Core/Crawl/defaultcontrol.h
@@ -8,8 +8,7 @@
 #ifndef DEFAULTCONTROL_H
 #define DEFAULTCONTROL_H
 
-#include "icontrol.h"
-#include "global.h"
+#include "player.h"
 
 namespace CRAWL {
 
@@ -17,7 +16,7 @@ namespace CRAWL {
 /**
  * @brief The DefaultControl class This class contains default implementation of the game menu.
  */
-class CRAWL_EXPORT DefaultControl : public IControl {
+class CRAWL_EXPORT DefaultControl : public Player {
     Q_OBJECT
 public:
     DefaultControl();
diff --git a/src/Core/Crawl/iitem.h b/src/Core/Crawl/iitem.h
index 5e2936d..1bf3ade 100644
--- a/src/Core/Crawl/iitem.h
+++ b/src/Core/Crawl/iitem.h
@@ -22,6 +22,7 @@ class CRAWL_EXPORT IItem
 {
 public:
     IItem();
+    virtual ~IItem() = default;
 
     /**
      * @brief itemTextId All items contains own ids, override this method for create base for generate new item id.
diff --git a/src/Core/Crawl/ilevel.cpp b/src/Core/Crawl/ilevel.cpp
index 33bb3c3..e08d667 100644
--- a/src/Core/Crawl/ilevel.cpp
+++ b/src/Core/Crawl/ilevel.cpp
@@ -5,4 +5,31 @@
 //# of this license document, but changing it is not allowed.
 //#
 
+#include "iitem.h"
 #include "ilevel.h"
+#include "iworld.h"
+
+namespace CRAWL {
+
+ILevel::~ILevel() {
+    delete _world;
+    delete _previewScane;
+}
+
+IWorld *ILevel::world() {
+    return _world;
+}
+
+IWorld *ILevel::previewScane() {
+    return _previewScane;
+}
+
+void ILevel::setWorld(IWorld *newWorld) {
+    _world = newWorld;
+}
+
+void ILevel::setPreviewScane(IWorld *newPreviewScane) {
+    _previewScane = newPreviewScane;
+}
+
+}
diff --git a/src/Core/Crawl/ilevel.h b/src/Core/Crawl/ilevel.h
index 5cad4c6..bddf661 100644
--- a/src/Core/Crawl/ilevel.h
+++ b/src/Core/Crawl/ilevel.h
@@ -5,6 +5,8 @@
 //# of this license document, but changing it is not allowed.
 //#
 
+#include <QHash>
+
 #ifndef LEVEL_H
 #define LEVEL_H
 
@@ -12,22 +14,54 @@ namespace CRAWL {
 
 
 class IWorld;
+class IItem;
 
 /**
  * @brief The ILevel class This interface make the world instance object.
  * All levels libraries should be override this interface.
+ *
  */
 class ILevel
 {
 public:
     ILevel() = default;
-    virtual ~ILevel() = default;
+    virtual ~ILevel();
 
     /**
      * @brief world This method should be return pointer to the level world.
      * @return pointer to the level world.
+     * @see ILevel::setWorld
      */
-    virtual IWorld* world() = 0;
+    IWorld* world();
+
+    /**
+     * @brief previewScane this method should be create a model of the snake preview scane.
+     * @return pointer to the model of the preview scane.
+     * @see ILevel::setPreviewScane
+     */
+    IWorld* previewScane();
+
+protected:
+    /**
+     * @brief setWorld This method sets new world pointer.
+     * @param newWorld This is new world model object.
+     * @note The @a newWorld item will be distroued with the parent object.
+     * @see ILevel::world
+     */
+    void setWorld(IWorld *newWorld);
+
+    /**
+     * @brief setPreviewScane This method sets new object for the preview scane.
+     * @param newPreviewScane This is new value of the preview scane.
+     * @note The @a newPreviewScane item will be distroued with the parent object.
+     * @see ILevel::previewScane
+     */
+    void setPreviewScane(IWorld *newPreviewScane);
+
+private:
+
+    IWorld* _world = nullptr;
+    IWorld* _previewScane = nullptr;
 };
 
 }
diff --git a/src/Core/Crawl/ipreviewscaneworld.cpp b/src/Core/Crawl/ipreviewscaneworld.cpp
new file mode 100644
index 0000000..947b995
--- /dev/null
+++ b/src/Core/Crawl/ipreviewscaneworld.cpp
@@ -0,0 +1,47 @@
+//#
+//# Copyright (C) 2021-2021 QuasarApp.
+//# Distributed under the GPLv3 software license, see the accompanying
+//# Everyone is permitted to copy and distribute verbatim copies
+//# of this license document, but changing it is not allowed.
+//#
+
+#include "ipreviewscaneworld.h"
+namespace CRAWL {
+
+IPreviewScaneWorld::IPreviewScaneWorld() {
+
+}
+
+QString IPreviewScaneWorld::itemTextId() const {
+    return "preview";
+}
+
+QString IPreviewScaneWorld::itemName() const {
+    return itemTextId();
+}
+
+QString IPreviewScaneWorld::description() const {
+    return "";
+}
+
+QString IPreviewScaneWorld::image() const {
+    return "";
+}
+
+int IPreviewScaneWorld::cost() const {
+    return 0;
+}
+
+int IPreviewScaneWorld::requiredTier() const {
+    return 0;
+}
+
+bool IPreviewScaneWorld::start(const StartData& config) {
+    _configuration = config;
+}
+
+bool IPreviewScaneWorld::stop() {
+
+}
+
+}
diff --git a/src/Core/Crawl/ipreviewscaneworld.h b/src/Core/Crawl/ipreviewscaneworld.h
new file mode 100644
index 0000000..a38b7ed
--- /dev/null
+++ b/src/Core/Crawl/ipreviewscaneworld.h
@@ -0,0 +1,43 @@
+//#
+//# Copyright (C) 2021-2021 QuasarApp.
+//# Distributed under the GPLv3 software license, see the accompanying
+//# Everyone is permitted to copy and distribute verbatim copies
+//# of this license document, but changing it is not allowed.
+//#
+
+#ifndef IPREVIEWSCANEWORLD_H
+#define IPREVIEWSCANEWORLD_H
+
+#include "iworld.h"
+
+namespace CRAWL {
+
+/**
+ * @brief The IPreviewScaneWorld class is interface of the all preview scanes models.
+ */
+class CRAWL_EXPORT IPreviewScaneWorld: public IWorld
+{
+public:
+    IPreviewScaneWorld();
+
+    // IItem interface
+public:
+    QString itemTextId() const override final;
+    QString itemName() const override final;
+    QString description() const override final;
+    QString image() const override final;
+    int cost() const override final;
+    int requiredTier() const override final;
+
+    bool start(const StartData &config) override;
+    bool stop() override;
+
+signals:
+    void sigPrepareIsFinished(const StartData& config);
+
+private:
+    StartData _configuration;
+};
+
+}
+#endif // IPREVIEWSCANEWORLD_H
diff --git a/src/Core/Crawl/iworld.cpp b/src/Core/Crawl/iworld.cpp
index 528d7e7..337fd80 100644
--- a/src/Core/Crawl/iworld.cpp
+++ b/src/Core/Crawl/iworld.cpp
@@ -20,6 +20,7 @@
 #include "chrono"
 #include "diff.h"
 #include "eventserver.h"
+#include "player.h"
 
 namespace CRAWL {
 
@@ -40,9 +41,11 @@ IWorld::~IWorld() {
     delete _eventServer;
 }
 
-void IWorld::init() {prepare();}
+void IWorld::init() {
+    prepare();
+}
 
-IControl *IWorld::initUserInterface() const {
+Player *IWorld::initUserInterface() const {
     return new DefaultControl;
 }
 
@@ -83,12 +86,13 @@ void IWorld::initPlayerControl(IControl *control) {
     }
 }
 
-bool IWorld::start() {
+bool IWorld::start(const StartData& config) {
     _player->setposition({0,0,0});
 
     setWorldStatus(WorldStatus::Game);
     _backgroundAI->stopAI();
     _player->setControl(_userInterface);
+    setPlayer(initPlayer());
 
 
     worldChanged(_worldRules->cbegin());
@@ -151,8 +155,6 @@ bool IWorld::prepare() {
     _worldRules = initWorldRules();
 
     setHdr(initHdrBackGround());
-    setPlayer(initPlayer());
-    _player->initOnWorld(this, _player);
     _userInterface = initUserInterface();
     _backgroundAI = initBackGroundAI();
 
@@ -283,7 +285,7 @@ void IWorld::addAtomicItem(IWorldItem* obj) {
     _items.insert(obj->guiId(), obj);
     _itemsGroup.insert(obj->className(), obj->guiId());
 
-    obj->initOnWorld(this, _player);
+    obj->initOnWorld(this);
 }
 
 bool IWorld::removeAtomicItem(int id) {
diff --git a/src/Core/Crawl/iworld.h b/src/Core/Crawl/iworld.h
index 6f712ab..32de6b7 100644
--- a/src/Core/Crawl/iworld.h
+++ b/src/Core/Crawl/iworld.h
@@ -11,6 +11,7 @@
 #include "gameresult.h"
 #include "iitem.h"
 #include "playableobject.h"
+#include "startdata.h"
 
 #include <QHash>
 #include <QMap>
@@ -42,6 +43,7 @@ class IControl;
 class IAI;
 class IWorldLight;
 class EventServer;
+class Player;
 
 /**
  * @brief WorldObjects This is map list of the avalable objects and its count on a lvl-long point.
@@ -110,7 +112,7 @@ public:
      * @note The base implementation return default user interface.
      * @return pointer to userInterface.
      */
-    virtual IControl* initUserInterface() const;
+    virtual Player *initUserInterface() const;
 
     /**
      * @brief initHdrBackGround The implementation of this method must be return valid path to the hdr image map.
@@ -127,17 +129,18 @@ public:
 
     /**
      * @brief initPlayerControl This method should be configure all connections of @a control object.
-     * @brief control This is control object
+     * @param control This is control object
      * @note override this method if you have own IControl object.
      */
     virtual void initPlayerControl(IControl* control);
 
     /**
      * @brief start This method will be invoked when user click start button.
+     * @param config This is initialize level arguments.
      * @note The Default implementation reset all positions for all objects.
      * @return true if game started successful.
      */
-    virtual bool start();
+    virtual bool start(const StartData &config);
 
     /**
      * @brief stop This methos will be invoked when user click to return to main menu button.
@@ -487,8 +490,8 @@ private:
     WorldRule::const_iterator _currendWorldLevel;
 
     PlayableObject *_player = nullptr;
-    IControl *_userInterface = nullptr;
     IAI *_backgroundAI = nullptr;
+    Player *_userInterface = nullptr;
     int _worldStatus = 0;
     QHash<QString, std::function<IWorldItem*()>> _registeredTypes;
 
diff --git a/src/Core/Crawl/iworlditem.cpp b/src/Core/Crawl/iworlditem.cpp
index dd18590..94195b3 100644
--- a/src/Core/Crawl/iworlditem.cpp
+++ b/src/Core/Crawl/iworlditem.cpp
@@ -30,10 +30,17 @@ const IWorldItem *IWorldItem::getItem(int id) const {
 }
 
 const IWorldItem *IWorldItem::getPlayer() const {
-    return _playerObject;
+    if (!_world)
+        return nullptr;
+    return static_cast<const IWorldItem *>(_world->player());
 }
 
 void IWorldItem::render(unsigned int) {
+    auto _playerObject = getPlayer();
+
+    if (!_playerObject)
+        return;
+
     if (_playerObject->position().distanceToPoint(position()) >
             _world->cameraReleativePosition().z() * 3) {
         respawn();
@@ -42,9 +49,8 @@ void IWorldItem::render(unsigned int) {
 
 void IWorldItem::init() {}
 
-void IWorldItem::initOnWorld(const IWorld *world, const IWorldItem * player) {
+void IWorldItem::initOnWorld(const IWorld *world) {
     _world = world;
-    _playerObject = player;
 }
 
 int IWorldItem::supportedEvents() const {
@@ -60,6 +66,11 @@ void IWorldItem::destroy() {
 }
 
 void IWorldItem::respawn() {
+    auto _playerObject = getPlayer();
+
+    if (!_playerObject)
+        return;
+
     float dX = _world->cameraReleativePosition().z() * 2 +
             (rand() % static_cast<int>(_world->cameraReleativePosition().z()));
 
diff --git a/src/Core/Crawl/iworlditem.h b/src/Core/Crawl/iworlditem.h
index 8e60047..6df04b9 100644
--- a/src/Core/Crawl/iworlditem.h
+++ b/src/Core/Crawl/iworlditem.h
@@ -135,10 +135,9 @@ protected:
     void dropSupportOfEvent(int depricatedEvent);
 
 private:
-    void initOnWorld(const IWorld* world, const IWorldItem *player);
+    void initOnWorld(const IWorld* world);
 
     const IWorld* _world = nullptr;
-    const IWorldItem *_playerObject = nullptr;
 
     bool _fDecorative = true;
     bool _fDistroy = false;
diff --git a/src/Core/Crawl/player.cpp b/src/Core/Crawl/player.cpp
index f3c5baa..0bb6bdf 100644
--- a/src/Core/Crawl/player.cpp
+++ b/src/Core/Crawl/player.cpp
@@ -6,9 +6,29 @@
 //#
 
 #include "player.h"
+#include <user.h>
+
 namespace CRAWL {
 
 Player::Player() {
 
 }
+
+void Player::addXp(int newXp) {
+    if (_userData)
+        _userData->setXp(_userData->getXp() + newXp);
+}
+
+void Player::addMoney(int money) {
+    if (_userData)
+        _userData->setMoney(_userData->getMoney() + money);
+}
+
+User *Player::userData() const {
+    return _userData;
+}
+
+void Player::setUserData(User *newUserData) {
+    _userData = newUserData;
+}
 }
diff --git a/src/Core/Crawl/player.h b/src/Core/Crawl/player.h
index 4a33df0..5808846 100644
--- a/src/Core/Crawl/player.h
+++ b/src/Core/Crawl/player.h
@@ -11,8 +11,11 @@
 
 #include "icontrol.h"
 
+
 namespace CRAWL {
 
+class User;
+
 /**
  * @brief The Player class is main class of users.
  */
@@ -21,6 +24,34 @@ class CRAWL_EXPORT Player: public IControl
     Q_OBJECT
 public:
     Player();
+
+    /**
+     * @brief addXp This method add new xp to palyer.
+     * @param newXp this is value of experience
+     */
+    void addXp(int newXp);
+
+    /**
+     * @brief addMoney This method add money to user.
+     * @param money added amount of money
+     */
+    void addMoney(int money);
+
+    /**
+     * @brief userData This method sets user that control this object.
+     * @return current control user.
+     */
+    User *userData() const;
+
+    /**
+     * @brief setUserData This method sets user that control this object.
+     * @param newUserData This is new pointer of the new user.
+     */
+    void setUserData(User *newUserData);
+
+private:
+
+    User *_userData = nullptr;
 };
 }
 #endif // PLAYER_H
diff --git a/src/Core/Crawl/snake.h b/src/Core/Crawl/snake.h
index 4fc5423..669c425 100644
--- a/src/Core/Crawl/snake.h
+++ b/src/Core/Crawl/snake.h
@@ -8,6 +8,7 @@
 #ifndef CRAWL_SNAKE_H
 #define CRAWL_SNAKE_H
 
+#include "iitem.h"
 #include "playableobject.h"
 #include "Extensions/autogenerateclaster.h"
 
@@ -18,7 +19,7 @@ class SnakeItem;
 /**
  * @brief The Snake class This class implement render mehod for snake object.
  */
-class CRAWL_EXPORT Snake : public PlayableObject, public AutoGenerateClaster
+class CRAWL_EXPORT Snake : public PlayableObject, public AutoGenerateClaster, public IItem
 {
     Q_OBJECT
 public:
@@ -34,7 +35,6 @@ public:
     void remove(int id) override;
     void init() override;
 
-
     // IPlayer interface
     /**
      * @brief lengthBetwinItems This method return length betwin snake items;
@@ -132,7 +132,6 @@ private:
     float _speed;
 
     int _hp = 100;
-
 };
 
 }
diff --git a/src/Core/Crawl/startdata.cpp b/src/Core/Crawl/startdata.cpp
new file mode 100644
index 0000000..98761b7
--- /dev/null
+++ b/src/Core/Crawl/startdata.cpp
@@ -0,0 +1,38 @@
+//#
+//# Copyright (C) 2021-2021 QuasarApp.
+//# Distributed under the GPLv3 software license, see the accompanying
+//# Everyone is permitted to copy and distribute verbatim copies
+//# of this license document, but changing it is not allowed.
+//#
+
+#include "startdata.h"
+
+namespace CRAWL {
+
+StartData::StartData() {
+
+}
+
+StartData::StartData(User *player, int snake) {
+    setPlayer(player);
+    setSnakeType(snake);
+}
+
+
+User *StartData::player() const{
+    return _player;
+}
+
+void StartData::setPlayer(User *newPlayer) {
+    _player = newPlayer;
+}
+
+int StartData::snakeType() const {
+    return _snakeType;
+}
+
+void StartData::setSnakeType(int newSnake) {
+    _snakeType = newSnake;
+}
+
+}
diff --git a/src/Core/Crawl/startdata.h b/src/Core/Crawl/startdata.h
new file mode 100644
index 0000000..8cd7758
--- /dev/null
+++ b/src/Core/Crawl/startdata.h
@@ -0,0 +1,61 @@
+//#
+//# Copyright (C) 2021-2021 QuasarApp.
+//# Distributed under the GPLv3 software license, see the accompanying
+//# Everyone is permitted to copy and distribute verbatim copies
+//# of this license document, but changing it is not allowed.
+//#
+
+#ifndef STARTDATA_H
+#define STARTDATA_H
+
+namespace CRAWL {
+
+class User;
+class PlayableObject;
+
+/**
+ * @brief The StartData class This class contains arguments for starting new game session.
+ */
+class StartData
+{
+public:
+    StartData();
+
+    StartData(User * player, int snake);
+
+    /**
+     * @brief player This method return pointer to user that will be control player snake.
+     * @return pointer to user that will be control player snake.
+     * @see StartData::setPlayer
+     */
+    User *player() const;
+
+    /**
+     * @brief setPlayer This method sets
+     * @param newPlayer This is new object of the user.
+     * @see StartData::player
+     */
+    void setPlayer(User *newPlayer);
+
+    /**
+     * @brief snakeType This method return select for game snake object type.
+     * @return select for game snake object.
+     * @see StartData::setSnakeType
+     */
+    int snakeType() const;
+
+    /**
+     * @brief setSnakeType This method sets new selected for game object type,
+     * @param newSnake This is  new selected for game object
+     * @see StartData::snakeType
+     */
+    void setSnakeType(int newSnake);
+
+private:
+    User *_player = nullptr;
+    int _snakeType;
+};
+
+}
+
+#endif // STARTDATA_H
diff --git a/src/Core/CrawlModule/PreviewScane.qml b/src/Core/CrawlModule/PreviewScane.qml
new file mode 100644
index 0000000..e7ed5a1
--- /dev/null
+++ b/src/Core/CrawlModule/PreviewScane.qml
@@ -0,0 +1,135 @@
+import QtQuick
+import QtQuick3D
+import QtQuick.Controls.Material
+import QtQuick.Controls
+import QtQuick.Layouts
+import QtQuick3D.Particles3D
+
+
+View3D {
+    id: scene;
+
+    property var model: null;
+    renderMode: View3D.Offscreen
+
+    PerspectiveCamera {
+        id: camera
+        position: Qt.vector3d(0,0, 100)
+    }
+
+    SceneEnvironment {
+        id: defautlBackground
+        backgroundMode: SceneEnvironment.Color
+        clearColor: "#777777"
+    }
+
+    environment: /*(privateRoot.world)? background:*/ defautlBackground
+
+    ParticleSystem3D {
+        id: privateRoot
+        property var arrayObjects: []
+        property var world: (model)? model.world: null
+
+        property var gameMenuModel: (model)? model.menu: null
+        property var player: (world)? world.player: null
+        property var releativeCameraPosition: (world)? world.cameraReleativePosition: null
+
+        function add (cppObjId) {
+            if (!model) {
+                console.log("create object fail")
+                return;
+            }
+
+            const objModel = model.getGameObject(cppObjId);
+
+            if (!objModel) {
+                console.log("object model not found");
+                return;
+            }
+
+            var viewTemplate = objModel.viewTemplate;
+
+            var temp = Qt.createComponent(viewTemplate)
+            if (temp.status === Component.Ready) {
+                var obj = temp.createObject(privateRoot)
+                obj.model = objModel;
+                arrayObjects.push(obj)
+            } else {
+                console.log("wrong viewTemplate in model " + temp.errorString());
+            }
+        }
+
+        function remove(id) {
+            if (typeof id !== "number" || id < 0) {
+                console.log("id not found");
+                return;
+            }
+
+            for (var i = 0; i < arrayObjects.length; ++i) {
+                if (id === arrayObjects[i].guiId) {
+                    arrayObjects[i].destroy();
+                    arrayObjects.splice(i,1);
+
+                }
+            }
+        }
+
+        Connections {
+            target: privateRoot.world;
+            function onSigOBjctsListChanged(diff) {
+                if (!diff) {
+                    console.log("diff not found");
+                    return;
+                }
+
+                let tempDifRem = [];
+                tempDifRem = diff.getRemoveIds();
+                let tempDifAdd = [];
+                tempDifAdd = diff.getAddedIds();
+
+                for (let i = 0; i < tempDifAdd.length; ++i) {
+                    privateRoot.add(tempDifAdd[i]);
+                }
+
+                for (let j = 0; j < tempDifRem.length; ++j) {
+                    privateRoot.remove(tempDifRem[j]);
+                }
+            }
+        }
+
+        Connections {
+            target: privateRoot;
+
+            function onGameMenuModelChanged() {
+                if (!privateRoot.gameMenuModel) {
+                    return;
+                }
+
+                const comp = Qt.createComponent(privateRoot.gameMenuModel.view);
+                if (comp.status === Component.Ready) {
+                    if (privateRoot.gameMenu) {
+                        privateRoot.gameMenu.destroy()
+                    }
+
+                    privateRoot.gameMenu = comp.createObject(scene);
+                    if (privateRoot.gameMenu === null) {
+                        // Error Handling
+                        console.log("Error creating object");
+                    }
+
+                    privateRoot.gameMenu.model = privateRoot.gameMenuModel;
+
+                } else if (comp.status === Component.Error) {
+                    // Error Handling
+                    console.log("Error loading component: " + privateRoot.gameMenuModel.view, comp.errorString());
+                }
+            }
+
+            function onShowMenuChanged() {
+                if (privateRoot.gameMenu) {
+                    privateRoot.gameMenu.visible = !showMenu
+                }
+            }
+        }
+    }
+}

From eb5d8cd796007d736450a64c323ed710adaba821 Mon Sep 17 00:00:00 2001
From: EndrII <EndrIIMail@gmail.com>
Date: Thu, 12 Aug 2021 14:22:59 +0300
Subject: [PATCH 17/19] tmp commit

---
 src/Client/languages/de.ts                   |  11 ++
 src/Client/languages/en.ts                   |  11 ++
 src/Client/languages/es.ts                   |  11 ++
 src/Client/languages/fr.ts                   |  11 ++
 src/Client/languages/ja.ts                   |  11 ++
 src/Client/languages/pl.ts                   |  11 ++
 src/Client/languages/ru.ts                   |  11 ++
 src/Client/languages/tr.ts                   |  11 ++
 src/Client/languages/uk.ts                   |  11 ++
 src/Client/languages/zh.ts                   |  11 ++
 src/Core/Crawl.qrc                           |   1 +
 src/Core/Crawl/clientapp.h                   |   2 +-
 src/Core/Crawl/icontrol.cpp                  |  11 +-
 src/Core/Crawl/icontrol.h                    |  10 +-
 src/Core/Crawl/iitem.cpp                     |  24 +++-
 src/Core/Crawl/iitem.h                       |  58 ++++++++-
 src/Core/Crawl/ilevel.cpp                    |   5 +
 src/Core/Crawl/ilevel.h                      |   5 +
 src/Core/Crawl/ipreviewscaneworld.cpp        |  65 +++++++++-
 src/Core/Crawl/ipreviewscaneworld.h          |  24 +++-
 src/Core/Crawl/iworld.cpp                    |  91 +++++++-------
 src/Core/Crawl/iworld.h                      | 118 +++++++++++--------
 src/Core/Crawl/previewcontrol.cpp            |  21 ++++
 src/Core/Crawl/previewcontrol.h              |  52 ++++++++
 src/Core/Crawl/startdata.cpp                 |   8 ++
 src/Core/Crawl/startdata.h                   |  21 +++-
 src/Core/CrawlModule/PreviewControl.qml      |  85 +++++++++++++
 src/Core/CrawlModule/Scene.qml               |   2 +-
 src/Core/private/engine.cpp                  |  64 ++++------
 src/Core/private/engine.h                    |  28 ++---
 src/CrawlAbstractLvl/private/abslvlworld.cpp |   4 +-
 src/CrawlAbstractLvl/private/abslvlworld.h   |   2 +-
 src/CrawlTestLvl/private/world.cpp           |   4 +-
 src/CrawlTestLvl/private/world.h             |   2 +-
 src/JungleLvl/private/world.cpp              |   4 +-
 src/JungleLvl/private/world.h                |   2 +-
 36 files changed, 634 insertions(+), 189 deletions(-)
 create mode 100644 src/Core/Crawl/previewcontrol.cpp
 create mode 100644 src/Core/Crawl/previewcontrol.h
 create mode 100644 src/Core/CrawlModule/PreviewControl.qml

diff --git a/src/Client/languages/de.ts b/src/Client/languages/de.ts
index 053544d..c78ae05 100644
--- a/src/Client/languages/de.ts
+++ b/src/Client/languages/de.ts
@@ -52,6 +52,17 @@
         <translation type="unfinished"></translation>
     </message>
 </context>
+<context>
+    <name>PreviewControl</name>
+    <message>
+        <source>Back to menu.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Start</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 <context>
     <name>SelectLvlView</name>
     <message>
diff --git a/src/Client/languages/en.ts b/src/Client/languages/en.ts
index 948f1f9..2cba5b8 100644
--- a/src/Client/languages/en.ts
+++ b/src/Client/languages/en.ts
@@ -52,6 +52,17 @@
         <translation type="unfinished"></translation>
     </message>
 </context>
+<context>
+    <name>PreviewControl</name>
+    <message>
+        <source>Back to menu.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Start</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 <context>
     <name>SelectLvlView</name>
     <message>
diff --git a/src/Client/languages/es.ts b/src/Client/languages/es.ts
index 726a274..300328b 100644
--- a/src/Client/languages/es.ts
+++ b/src/Client/languages/es.ts
@@ -52,6 +52,17 @@
         <translation type="unfinished"></translation>
     </message>
 </context>
+<context>
+    <name>PreviewControl</name>
+    <message>
+        <source>Back to menu.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Start</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 <context>
     <name>SelectLvlView</name>
     <message>
diff --git a/src/Client/languages/fr.ts b/src/Client/languages/fr.ts
index 948f1f9..2cba5b8 100644
--- a/src/Client/languages/fr.ts
+++ b/src/Client/languages/fr.ts
@@ -52,6 +52,17 @@
         <translation type="unfinished"></translation>
     </message>
 </context>
+<context>
+    <name>PreviewControl</name>
+    <message>
+        <source>Back to menu.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Start</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 <context>
     <name>SelectLvlView</name>
     <message>
diff --git a/src/Client/languages/ja.ts b/src/Client/languages/ja.ts
index 948f1f9..2cba5b8 100644
--- a/src/Client/languages/ja.ts
+++ b/src/Client/languages/ja.ts
@@ -52,6 +52,17 @@
         <translation type="unfinished"></translation>
     </message>
 </context>
+<context>
+    <name>PreviewControl</name>
+    <message>
+        <source>Back to menu.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Start</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 <context>
     <name>SelectLvlView</name>
     <message>
diff --git a/src/Client/languages/pl.ts b/src/Client/languages/pl.ts
index 948f1f9..2cba5b8 100644
--- a/src/Client/languages/pl.ts
+++ b/src/Client/languages/pl.ts
@@ -52,6 +52,17 @@
         <translation type="unfinished"></translation>
     </message>
 </context>
+<context>
+    <name>PreviewControl</name>
+    <message>
+        <source>Back to menu.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Start</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 <context>
     <name>SelectLvlView</name>
     <message>
diff --git a/src/Client/languages/ru.ts b/src/Client/languages/ru.ts
index 948f1f9..2cba5b8 100644
--- a/src/Client/languages/ru.ts
+++ b/src/Client/languages/ru.ts
@@ -52,6 +52,17 @@
         <translation type="unfinished"></translation>
     </message>
 </context>
+<context>
+    <name>PreviewControl</name>
+    <message>
+        <source>Back to menu.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Start</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 <context>
     <name>SelectLvlView</name>
     <message>
diff --git a/src/Client/languages/tr.ts b/src/Client/languages/tr.ts
index 948f1f9..2cba5b8 100644
--- a/src/Client/languages/tr.ts
+++ b/src/Client/languages/tr.ts
@@ -52,6 +52,17 @@
         <translation type="unfinished"></translation>
     </message>
 </context>
+<context>
+    <name>PreviewControl</name>
+    <message>
+        <source>Back to menu.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Start</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 <context>
     <name>SelectLvlView</name>
     <message>
diff --git a/src/Client/languages/uk.ts b/src/Client/languages/uk.ts
index 948f1f9..2cba5b8 100644
--- a/src/Client/languages/uk.ts
+++ b/src/Client/languages/uk.ts
@@ -52,6 +52,17 @@
         <translation type="unfinished"></translation>
     </message>
 </context>
+<context>
+    <name>PreviewControl</name>
+    <message>
+        <source>Back to menu.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Start</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 <context>
     <name>SelectLvlView</name>
     <message>
diff --git a/src/Client/languages/zh.ts b/src/Client/languages/zh.ts
index 948f1f9..2cba5b8 100644
--- a/src/Client/languages/zh.ts
+++ b/src/Client/languages/zh.ts
@@ -52,6 +52,17 @@
         <translation type="unfinished"></translation>
     </message>
 </context>
+<context>
+    <name>PreviewControl</name>
+    <message>
+        <source>Back to menu.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Start</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 <context>
     <name>SelectLvlView</name>
     <message>
diff --git a/src/Core/Crawl.qrc b/src/Core/Crawl.qrc
index b8766fd..cf6a78a 100644
--- a/src/Core/Crawl.qrc
+++ b/src/Core/Crawl.qrc
@@ -25,5 +25,6 @@
         <file>CrawlModule/particles/Fire.qml</file>
         <file>CrawlModule/particles/Wint.qml</file>
         <file>CrawlModule/PreviewScane.qml</file>
+        <file>CrawlModule/PreviewControl.qml</file>
     </qresource>
 </RCC>
diff --git a/src/Core/Crawl/clientapp.h b/src/Core/Crawl/clientapp.h
index 69b9dd0..25dfd4e 100644
--- a/src/Core/Crawl/clientapp.h
+++ b/src/Core/Crawl/clientapp.h
@@ -33,7 +33,7 @@ class Store;
  */
 struct WordlData {
     WorldViewData* viewModel = nullptr;
-    IWorld * model = nullptr;
+    ILevel * model = nullptr;
 };
 
 /**
diff --git a/src/Core/Crawl/icontrol.cpp b/src/Core/Crawl/icontrol.cpp
index dcbe3ab..7588f86 100644
--- a/src/Core/Crawl/icontrol.cpp
+++ b/src/Core/Crawl/icontrol.cpp
@@ -18,13 +18,12 @@ IControl::~IControl() {
 
 }
 
-const QString &IControl::view() const {
-    return _view;
-}
+const QString &IControl::view() {
+    if (_view.isEmpty()) {
+        setView(initQmlView());
+    }
 
-bool IControl::init() {
-    setView(initQmlView());
-    return _view.size();
+    return _view;
 }
 
 void IControl::setView(const QString &newView) {
diff --git a/src/Core/Crawl/icontrol.h b/src/Core/Crawl/icontrol.h
index cd8a7ee..9f5cd10 100644
--- a/src/Core/Crawl/icontrol.h
+++ b/src/Core/Crawl/icontrol.h
@@ -41,20 +41,12 @@ public:
      * @brief view This method retun qml view element.
      * @return return path to qml view.
      */
-    const QString &view() const;
+    const QString &view();
 
 signals:
     void viewChanged();
 
 private:
-
-    /**
-     * @brief init This method intialize this object.
-     * @note do not invoke this method monualy.
-     * @return True if initialize finished succesfful.
-     */
-    bool init();
-
     /**
      * @brief setView This method sets new value of qml view element.
      * @param newView path to qml view.
diff --git a/src/Core/Crawl/iitem.cpp b/src/Core/Crawl/iitem.cpp
index 37e6275..5c6f23d 100644
--- a/src/Core/Crawl/iitem.cpp
+++ b/src/Core/Crawl/iitem.cpp
@@ -15,7 +15,7 @@ IItem::IItem() {
 
 }
 
-QList<const IItem *> IItem::childItems() const {
+const QHash<int, const IItem *>& IItem::childItems() const {
     return _childs;
 }
 
@@ -31,7 +31,7 @@ QMultiHash<int, const IItem *> IItem::childItemsRecursive() const {
 }
 
 void IItem::addChildItem(const IItem *item) {
-    _childs.push_back(item);
+    _childs.insert(item->itemId(), item);
 }
 
 unsigned int IItem::itemId() {
@@ -50,4 +50,24 @@ unsigned int IItem::itemId() const {
 
     return qHash(itemTextId());
 }
+
+const QSet<int> &IItem::activeItems() const {
+    return _activeItems;
+}
+
+void IItem::setActiveItems(const QSet<int> &newActiveItems) {
+    _activeItems = newActiveItems;
+}
+
+void IItem::activate(int item) {
+    _activeItems += item;
+}
+
+void IItem::deactivate(int item) {
+    _activeItems -= item;
+}
+
+bool IItem::isActive(int item) {
+    return _childs.contains(item) && _activeItems.contains(item);
+}
 }
diff --git a/src/Core/Crawl/iitem.h b/src/Core/Crawl/iitem.h
index 1bf3ade..804fed8 100644
--- a/src/Core/Crawl/iitem.h
+++ b/src/Core/Crawl/iitem.h
@@ -10,6 +10,7 @@
 #define IITEM_H
 
 #include <QList>
+#include <QSet>
 #include <QString>
 #include "global.h"
 
@@ -70,7 +71,7 @@ public:
      * @see IItem::addChildItem
      * @see IItem::childItemsRecursive
      */
-    QList<const IItem*> childItems() const;
+    const QHash<int, const IItem *> &childItems() const;
 
     /**
      * @brief childItemsRecursive This method return hash map of all items of this item.
@@ -102,9 +103,62 @@ public:
      */
     unsigned int itemId() const;
 
+    /**
+     * @brief activeItems This method return set of the actived items.
+     * @return set of the actived items.
+     * @see IItem::setActiveItems
+     * @see IItem::activate
+     * @see IItem::deactivate
+     * @see IItem::isActive
+     */
+    const QSet<int> &activeItems() const;
+
+    /**
+     * @brief setActiveItems This method sets new set of the actived items.
+     * @param newActiveItems This is new set of the ctived items.
+     * @see IItem::activeItems
+     * @see IItem::activate
+     * @see IItem::deactivate
+     * @see IItem::isActive
+     */
+    virtual void setActiveItems(const QSet<int> &newActiveItems);
+
+    /**
+     * @brief activate This method activate the child item with @a item id of this item.
+     * @param item activated item id.
+     * @see IItem::setActiveItems
+     * @see IItem::activeItems
+     * @see IItem::deactivate
+     * @see IItem::isActive
+     */
+    virtual void activate(int item);
+
+    /**
+     * @brief deactivate This method deactivate the child item with @a item id of this item.
+     * @param item deactivated item id.
+     * @see IItem::setActiveItems
+     * @see IItem::activate
+     * @see IItem::activeItems
+     * @see IItem::isActive
+     */
+    virtual void deactivate(int item);
+
+    /**
+     * @brief isActive This method will be return true if the @a item is actived. else false. If the item not child item of this object the this method return false.
+     * @param item This is checked item id.
+     * @return true if the @a item is actived. else false. If the item not child item of this object the this method return false.
+     * @see IItem::setActiveItems
+     * @see IItem::activate
+     * @see IItem::deactivate
+     * @see IItem::activeItems
+     */
+    bool isActive(int item);
+
 private:
     unsigned int _id = 0;
-    QList<const IItem*> _childs;
+    QHash<int, const IItem*> _childs;
+    QSet<int> _activeItems;
+
 };
 
 }
diff --git a/src/Core/Crawl/ilevel.cpp b/src/Core/Crawl/ilevel.cpp
index e08d667..b73cec0 100644
--- a/src/Core/Crawl/ilevel.cpp
+++ b/src/Core/Crawl/ilevel.cpp
@@ -24,6 +24,11 @@ IWorld *ILevel::previewScane() {
     return _previewScane;
 }
 
+void ILevel::reset() {
+    _world->reset();
+    _previewScane->reset();
+}
+
 void ILevel::setWorld(IWorld *newWorld) {
     _world = newWorld;
 }
diff --git a/src/Core/Crawl/ilevel.h b/src/Core/Crawl/ilevel.h
index bddf661..0516f21 100644
--- a/src/Core/Crawl/ilevel.h
+++ b/src/Core/Crawl/ilevel.h
@@ -41,6 +41,11 @@ public:
      */
     IWorld* previewScane();
 
+    /**
+     * @brief reset This method unload all loaded data from level.
+     */
+    void reset();
+
 protected:
     /**
      * @brief setWorld This method sets new world pointer.
diff --git a/src/Core/Crawl/ipreviewscaneworld.cpp b/src/Core/Crawl/ipreviewscaneworld.cpp
index 947b995..01acb17 100644
--- a/src/Core/Crawl/ipreviewscaneworld.cpp
+++ b/src/Core/Crawl/ipreviewscaneworld.cpp
@@ -6,10 +6,13 @@
 //#
 
 #include "ipreviewscaneworld.h"
+#include "previewcontrol.h"
+
 namespace CRAWL {
 
-IPreviewScaneWorld::IPreviewScaneWorld() {
-
+IPreviewScaneWorld::IPreviewScaneWorld(const IWorld* mainWorld) {
+    debug_assert(mainWorld, "The mainWorld world option should be initialized.");
+    _mainWorld = mainWorld;
 }
 
 QString IPreviewScaneWorld::itemTextId() const {
@@ -36,12 +39,70 @@ int IPreviewScaneWorld::requiredTier() const {
     return 0;
 }
 
+PlayableObject *IPreviewScaneWorld::initPlayer(int objectType) const {
+    return _mainWorld->initPlayer(objectType);
+}
+
 bool IPreviewScaneWorld::start(const StartData& config) {
     _configuration = config;
+
+    setPlayer(initPlayer(config.snakeType()));
+
+    worldChanged(worldRules()->cbegin());
+    setTargetFps(60);
+    setRunning(true);
+
+    return true;
 }
 
 bool IPreviewScaneWorld::stop() {
+    setRunning(false);
+    reset();
+    return true;
+}
 
+void IPreviewScaneWorld::handleStop() {
+    stop();
+}
+
+void IPreviewScaneWorld::handleRotation(double x, double y) {
+    auto normal = (QQuaternion::fromEulerAngles(x, y, 0) * QVector3D{0,0,1}).normalized();
+
+    setCameraReleativePosition(normal * 100);
+    setCameraRotation(QQuaternion::rotationTo({1.0f, 0.0, 0.0}, {0,0,0}));
+}
+
+void IPreviewScaneWorld::handleStart() {
+    auto playerObj = dynamic_cast<IItem*>(player());
+    _configuration.setSnakePerks(playerObj->activeItems());
+    emit sigPrepareIsFinished(_configuration);
+    handleStop();
+}
+
+void IPreviewScaneWorld::handleSelect(int item, bool isSelected) {
+    auto playerItem = dynamic_cast<IItem*>(player());
+
+    if (isSelected) {
+        playerItem->activate(item);
+    } else {
+        playerItem->deactivate(item);
+    }
+}
+
+void IPreviewScaneWorld::initControl(IControl *control) {
+    auto controlObject = dynamic_cast<PreviewControl*>(control);
+
+    if (controlObject) {
+        connect(controlObject, &PreviewControl::backToMenu, this, &IPreviewScaneWorld::handleStop);
+        connect(controlObject, &PreviewControl::mousePositionChanged, this, &IPreviewScaneWorld::handleRotation);
+        connect(controlObject, &PreviewControl::start, this, &IPreviewScaneWorld::handleStart);
+        connect(controlObject, &PreviewControl::select, this, &IPreviewScaneWorld::handleSelect);
+
+    }
+}
+
+IControl *IPreviewScaneWorld::initUserInterface() const {
+    return new PreviewControl();
 }
 
 }
diff --git a/src/Core/Crawl/ipreviewscaneworld.h b/src/Core/Crawl/ipreviewscaneworld.h
index a38b7ed..98e736c 100644
--- a/src/Core/Crawl/ipreviewscaneworld.h
+++ b/src/Core/Crawl/ipreviewscaneworld.h
@@ -18,7 +18,11 @@ namespace CRAWL {
 class CRAWL_EXPORT IPreviewScaneWorld: public IWorld
 {
 public:
-    IPreviewScaneWorld();
+    /**
+     * @brief IPreviewScaneWorld This is main constructo of the preview world model.
+     * @param mainWorld This pointer to the main world. This is needed for correctly working initPalayer methods. The implementation of the some methods should be identy with the main world.
+     */
+    IPreviewScaneWorld(const IWorld* mainWorld);
 
     // IItem interface
 public:
@@ -28,15 +32,31 @@ public:
     QString image() const override final;
     int cost() const override final;
     int requiredTier() const override final;
-
+    PlayableObject *initPlayer(int objectType) const override final;
+    void initControl(IControl *control) override;
+    IControl* initUserInterface() const override;
     bool start(const StartData &config) override;
     bool stop() override;
 
 signals:
+    /**
+     * @brief sigPrepareIsFinished This signal emited when user finished prepare to game.
+     * @param config This is data for start.
+     */
     void sigPrepareIsFinished(const StartData& config);
 
+private slots:
+
+    void handleStop();
+    void handleRotation(double x, double y);
+    void handleStart();
+    void handleSelect(int item, bool isSelected);
+
 private:
     StartData _configuration;
+    const IWorld* _mainWorld;
+
+
 };
 
 }
diff --git a/src/Core/Crawl/iworld.cpp b/src/Core/Crawl/iworld.cpp
index 337fd80..04f7112 100644
--- a/src/Core/Crawl/iworld.cpp
+++ b/src/Core/Crawl/iworld.cpp
@@ -42,10 +42,9 @@ IWorld::~IWorld() {
 }
 
 void IWorld::init() {
-    prepare();
 }
 
-Player *IWorld::initUserInterface() const {
+IControl *IWorld::initUserInterface() const {
     return new DefaultControl;
 }
 
@@ -78,7 +77,7 @@ void IWorld::render(unsigned int tbfMsec) {
         std::this_thread::sleep_for(std::chrono::milliseconds(waitTime));
 }
 
-void IWorld::initPlayerControl(IControl *control) {
+void IWorld::initControl(IControl *control) {
     auto controlObject = dynamic_cast<DefaultControl*>(control);
 
     if (controlObject) {
@@ -87,13 +86,12 @@ void IWorld::initPlayerControl(IControl *control) {
 }
 
 bool IWorld::start(const StartData& config) {
-    _player->setposition({0,0,0});
 
     setWorldStatus(WorldStatus::Game);
     _backgroundAI->stopAI();
-    _player->setControl(_userInterface);
-    setPlayer(initPlayer());
+    setPlayer(initPlayer(config.snakeType()));
 
+    userInterface()->setUserData(config.player());
 
     worldChanged(_worldRules->cbegin());
     setTargetFps(60);
@@ -122,6 +120,9 @@ void IWorld::setPlayer(QObject *newPlayer) {
         removeItem(_player->guiId());
 
     _player = newPlayerObject;
+    _player->setposition({0,0,0});
+    _player->setControl(userInterface());
+
     addItem(_player);
 
     emit playerChanged();
@@ -147,34 +148,6 @@ IWorldItem *IWorld::getItem(int id) const {
     return _items.value(id, nullptr);
 }
 
-bool IWorld::prepare() {
-
-    if (isInit())
-        return true;
-
-    _worldRules = initWorldRules();
-
-    setHdr(initHdrBackGround());
-    _userInterface = initUserInterface();
-    _backgroundAI = initBackGroundAI();
-
-    if (!isInit()) {
-        QuasarAppUtils::Params::log("Failed to init world implementation.");
-        reset();
-        return false;
-    }
-
-    if (!_worldRules->size()) {
-        reset();
-        return false;
-    }
-
-    initPlayerControl(_userInterface);
-    initPlayerControl(dynamic_cast<IControl*>(_backgroundAI));
-
-    return true;
-}
-
 void IWorld::clearItems() {
     stop();
 
@@ -326,6 +299,14 @@ void IWorld::removeAnyItemFromGroup(const QString &group,
     removeItem(anyObjectId, removedObjectsList);
 }
 
+const WorldRule *IWorld::worldRules() {
+
+    if (!_worldRules)
+        initWorldRules();
+
+    return _worldRules;
+}
+
 bool IWorld::running() const {
     return _running;
 }
@@ -352,7 +333,7 @@ void IWorld::setHdr(const QString &hdr) {
 
 void IWorld::updateWorld() {
 
-    if (_currendWorldLevel->isEmpty() || !_worldRules || !_player)
+    if (_currendWorldLevel->isEmpty() || !_player)
         return;
 
     float distance = _player->position().x();
@@ -380,16 +361,24 @@ void IWorld::setCameraRotation(const QQuaternion &newCameraRotation) {
     emit cameraRotationChanged();
 }
 
-IAI *IWorld::backgroundAI() const {
+IAI *IWorld::backgroundAI() {
+
+    if (!_backgroundAI) {
+        _backgroundAI = initBackGroundAI();
+        initControl(dynamic_cast<IControl*>(_backgroundAI));
+    }
+
     return _backgroundAI;
 }
 
-IControl *IWorld::userInterface() const {
-    return _userInterface;
-}
+Player *IWorld::userInterface() {
 
-bool IWorld::isInit() const {
-    return _userInterface && _player && _worldRules && _backgroundAI;
+    if (!_userInterface) {
+        _userInterface = dynamic_cast<Player*>(initUserInterface());
+        initControl(_userInterface);
+    }
+
+    return _userInterface;
 }
 
 void IWorld::setCameraReleativePosition(const QVector3D &newCameraReleativePosition) {
@@ -447,12 +436,16 @@ void IWorld::setWorldStatus(int newWorldStatus) {
 }
 
 
-const QString &IWorld::hdr() const {
+const QString &IWorld::hdr() {
+    if (_hdrMap.isEmpty())
+        setHdr(initHdrBackGround());
+
     return _hdrMap;
 }
 
 void IWorld::runAsBackGround() {
-    start();
+    StartData data(nullptr, 0);
+    start(data);
 
     setWorldStatus(WorldStatus::Background);
     _player->setControl(dynamic_cast<IControl*>(_backgroundAI));
@@ -462,4 +455,16 @@ void IWorld::runAsBackGround() {
     setTargetFps(30);
 }
 
+QObject *IWorld::getMenu() const {
+    return _menu;
+}
+
+void IWorld::setMenu(QObject *newMenu) {
+    if (_menu == newMenu)
+        return;
+
+    _menu = newMenu;
+    emit menuChanged();
+}
+
 }
diff --git a/src/Core/Crawl/iworld.h b/src/Core/Crawl/iworld.h
index 32de6b7..7adba82 100644
--- a/src/Core/Crawl/iworld.h
+++ b/src/Core/Crawl/iworld.h
@@ -64,6 +64,14 @@ class CRAWL_EXPORT IWorld : public QObject, public IRender, public IItem
     Q_PROPERTY(QVector3D cameraReleativePosition READ cameraReleativePosition NOTIFY cameraReleativePositionChanged)
     Q_PROPERTY(QQuaternion cameraRotation READ cameraRotation NOTIFY cameraRotationChanged)
     Q_PROPERTY(QObject * player READ player WRITE setPlayer NOTIFY playerChanged)
+
+    /**
+     * @brief menu This propertye contains user interface model that initialised on the IWorld::userInterface method. For get more information see the IContol class.
+     * @see IWorld::setMenu
+     * @see IWorld::getMenu
+     * @see IWorld::userInterface
+    */
+    Q_PROPERTY(QObject * menu READ menu WRITE setMenu NOTIFY menuChanged)
     Q_PROPERTY(QString hdr READ hdr NOTIFY hdrChanged)
 
     Q_PROPERTY(int worldStatus READ wordlStatus WRITE setWorldStatus NOTIFY worldStatusChanged)
@@ -75,12 +83,13 @@ public:
     void init() override;
 
     /**
-     * @brief initPlayer The implementation of This interface must be return playerObject.
+     * @brief initPlayer The implementation of This interface must be return playerObject by type.
+     * @param objectType This is type of requried snake object.
      * @return raw pointer to the player object.
      * @note The Palyer object will be deleted when wold distroed.
      *  So do not delete your created player pbject yuorself.
      */
-    virtual PlayableObject* initPlayer() const = 0;
+    virtual PlayableObject* initPlayer(int objectType) const = 0;
 
     /**
      * @brief initWorldRules The implementation of this interface must be retun initialized list of the world rules.
@@ -112,7 +121,7 @@ public:
      * @note The base implementation return default user interface.
      * @return pointer to userInterface.
      */
-    virtual Player *initUserInterface() const;
+    virtual IControl *initUserInterface() const;
 
     /**
      * @brief initHdrBackGround The implementation of this method must be return valid path to the hdr image map.
@@ -128,11 +137,11 @@ public:
     virtual void render(unsigned int tbfMsec) override;
 
     /**
-     * @brief initPlayerControl This method should be configure all connections of @a control object.
+     * @brief initControl This method should be configure all connections of @a control object.
      * @param control This is control object
      * @note override this method if you have own IControl object.
      */
-    virtual void initPlayerControl(IControl* control);
+    virtual void initControl(IControl* control);
 
     /**
      * @brief start This method will be invoked when user click start button.
@@ -173,13 +182,7 @@ public:
      * @brief userInterface This method return pointer to userinterface.
      * @return pointer to user interface
      */
-    IControl *userInterface() const;
-
-    /**
-     * @brief isInit This method return true if the object initialized correctly else false.
-     * @return true if the object initialized correctly else false.
-     */
-    bool isInit() const;
+    Player *userInterface();
 
     /**
      * @brief wordlStatus This method return current world status.
@@ -197,7 +200,7 @@ public:
      * @brief backgroundAI This method return current backgroundAI.
      * @return Raw pointer to background AI object
      */
-    IAI *backgroundAI() const;
+    IAI *backgroundAI();
 
     /**
      * @brief cameraRotation This method return curent camera rotation.
@@ -215,7 +218,7 @@ public:
      * @brief hdr This method return path to hdr map of the lvl.
      * @return path to hdr map of this lvl.
      */
-    const QString &hdr() const;
+    const QString &hdr();
 
     /**
      * @brief runAsBackGround This method run this world as a backgroud.
@@ -223,6 +226,28 @@ public:
      */
     void runAsBackGround();
 
+    /**
+     * @brief menu This method return current pointer to the user interface of this world.
+     * @return pointer of the user Interface of this world.
+     * @see IWorld::setMenu
+     * @see IWorld::menu
+     * @see IWorld::userInterface
+     */
+    QObject *getMenu() const;
+    /**
+     * @brief setMenu This method sets new user interface object fot this world.
+     * @param newMenu This is new object of user interfavce of this world.
+     * @see IWorld::getMenu
+     * @see IWorld::menu
+     * @see IWorld::userInterface
+     */
+    void setMenu(QObject *newMenu);
+
+    /**
+     * @brief reset This method reset all world objects.
+     */
+    void reset();
+
 signals:
     /**
      * @brief sigGameFinished This signal emit when game are finished
@@ -274,6 +299,11 @@ signals:
      */
     void sigWorldChanged(WorldRule::const_iterator objects);
 
+    /**
+     * @brief menuChanged This signal emited when user interface is changed.
+     */
+    void menuChanged();
+
 protected:
 
     /**
@@ -372,15 +402,27 @@ protected:
      */
     void updateWorld();
 
-protected slots:
-    virtual void onIntersects(const IWorldItem * trigger, QList<const IWorldItem *> list);
-
-private slots:
+    /**
+     * @brief running This varibale check in render function if the running is true then render loop are working correctly
+     * @return status of the render function
+     */
+    bool running() const;
 
     /**
-     * @brief handleStop This slot invoked when user click return main menu button.
+     * @brief setRunning This method sets runnign render function status.
+     * @param newRunning new status of the render function
      */
-    void handleStop();
+    void setRunning(bool newRunning);
+
+    /**
+     * @brief worldRules This method return world cure map.
+     * @return world rule map.
+     */
+    const WorldRule *worldRules();
+
+
+protected slots:
+    virtual void onIntersects(const IWorldItem * trigger, QList<const IWorldItem *> list);
 
     /**
      * @brief worldChanged This method generate diff for the qml
@@ -389,31 +431,14 @@ private slots:
      */
     void worldChanged(WorldRule::const_iterator objects);
 
+private slots:
+
+    /**
+     * @brief handleStop This slot invoked when user click return main menu button.
+     */
+    void handleStop();
+
 private:
-    /**
-     * @brief prepare This method initialize world object.
-     * @note If object alredy initalize then this method do nothing.
-     * @return true if world initialized successful
-     */
-    bool prepare();
-
-    /**
-     * @brief reset This method reset all world objects.
-     */
-    void reset();
-
-
-    /**
-     * @brief running This varibale check in render function if the running is true then render loop are working correctly
-     * @return
-     */
-    bool running() const;
-
-    /**
-     * @brief setRunning
-     * @param newRunning
-     */
-    void setRunning(bool newRunning);
 
     /**
      * @brief clearItems This method remove all created items from world.
@@ -492,15 +517,14 @@ private:
     PlayableObject *_player = nullptr;
     IAI *_backgroundAI = nullptr;
     Player *_userInterface = nullptr;
+    QObject *_menu = nullptr;
+
     int _worldStatus = 0;
     QHash<QString, std::function<IWorldItem*()>> _registeredTypes;
 
     int _targetFps = 60;
     bool _running = false;
 
-    // engine
-    friend class Engine;
-
     // testing
     friend ClastersTest;
 };
diff --git a/src/Core/Crawl/previewcontrol.cpp b/src/Core/Crawl/previewcontrol.cpp
new file mode 100644
index 0000000..3d89dbe
--- /dev/null
+++ b/src/Core/Crawl/previewcontrol.cpp
@@ -0,0 +1,21 @@
+//#
+//# Copyright (C) 2021-2021 QuasarApp.
+//# Distributed under the GPLv3 software license, see the accompanying
+//# Everyone is permitted to copy and distribute verbatim copies
+//# of this license document, but changing it is not allowed.
+//#
+
+
+#include "previewcontrol.h"
+
+namespace CRAWL {
+
+PreviewControl::PreviewControl() {
+
+}
+
+QString PreviewControl::initQmlView() const {
+    return "qrc:/CrawlModule/PreviewControl.qml";
+}
+
+}
diff --git a/src/Core/Crawl/previewcontrol.h b/src/Core/Crawl/previewcontrol.h
new file mode 100644
index 0000000..76922e8
--- /dev/null
+++ b/src/Core/Crawl/previewcontrol.h
@@ -0,0 +1,52 @@
+//#
+//# Copyright (C) 2021-2021 QuasarApp.
+//# Distributed under the GPLv3 software license, see the accompanying
+//# Everyone is permitted to copy and distribute verbatim copies
+//# of this license document, but changing it is not allowed.
+//#
+
+#ifndef PREVIEWCONTROL_H
+#define PREVIEWCONTROL_H
+
+#include "icontrol.h"
+
+namespace CRAWL {
+
+/**
+ * @brief The PreviewControl class This is base class of the preview popup control.
+ */
+class CRAWL_EXPORT PreviewControl: public IControl
+{
+    Q_OBJECT
+public:
+    PreviewControl();
+    QString initQmlView() const override;
+
+signals:
+    /**
+     * @brief backToMenu Emit when user click the return to main menu button.
+     */
+    void backToMenu();
+
+    /**
+     * @brief start emited when user click start button from the preview menu.
+     */
+    void start();
+
+    /**
+     * @brief mousePositionChanged This signal emited when user true change the preview postion
+     * @param x delta by x axis
+     * @param y delta by y axis
+     */
+    void mousePositionChanged(double x, double y);
+
+    /**
+     * @brief select This signal emited when user select new item on hew own inventary.
+     * @param id This is id of the selected item
+     * @param isSelected this is bool option for set selected or diselected.
+     */
+    void select(int id, bool isSelected);
+
+};
+}
+#endif // PREVIEWCONTROL_H
diff --git a/src/Core/Crawl/startdata.cpp b/src/Core/Crawl/startdata.cpp
index 98761b7..f0c3e12 100644
--- a/src/Core/Crawl/startdata.cpp
+++ b/src/Core/Crawl/startdata.cpp
@@ -35,4 +35,12 @@ void StartData::setSnakeType(int newSnake) {
     _snakeType = newSnake;
 }
 
+const QSet<int> &StartData::snakePerks() const {
+    return _snakePerks;
+}
+
+void StartData::setSnakePerks(const QSet<int> &newSnakePerks) {
+    _snakePerks = newSnakePerks;
+}
+
 }
diff --git a/src/Core/Crawl/startdata.h b/src/Core/Crawl/startdata.h
index 8cd7758..3320f48 100644
--- a/src/Core/Crawl/startdata.h
+++ b/src/Core/Crawl/startdata.h
@@ -5,6 +5,10 @@
 //# of this license document, but changing it is not allowed.
 //#
 
+#include <QList>
+#include <QSet>
+#include "global.h"
+
 #ifndef STARTDATA_H
 #define STARTDATA_H
 
@@ -16,7 +20,7 @@ class PlayableObject;
 /**
  * @brief The StartData class This class contains arguments for starting new game session.
  */
-class StartData
+class CRAWL_EXPORT StartData
 {
 public:
     StartData();
@@ -51,9 +55,24 @@ public:
      */
     void setSnakeType(int newSnake);
 
+    /**
+     * @brief snakePerks This method return the list of the used snake upgrades.
+     * @return list of the used upgrades of the snake.
+     * @see StartData::setSnakePerks
+     */
+    const QSet<int> &snakePerks() const;
+
+    /**
+     * @brief setSnakePerks This method sets new list of the used upgrades.
+     * @param newSnakePerks This is list of the used upgrades.
+     * @see StartData::snakePerks
+     */
+    void setSnakePerks(const QSet<int> &newSnakePerks);
+
 private:
     User *_player = nullptr;
     int _snakeType;
+    QSet<int> _snakePerks;
 };
 
 }
diff --git a/src/Core/CrawlModule/PreviewControl.qml b/src/Core/CrawlModule/PreviewControl.qml
new file mode 100644
index 0000000..3deda36
--- /dev/null
+++ b/src/Core/CrawlModule/PreviewControl.qml
@@ -0,0 +1,85 @@
+//#
+//# Copyright (C) 2021-2021 QuasarApp.
+//# Distributed under the GPLv3 software license, see the accompanying
+//# Everyone is permitted to copy and distribute verbatim copies
+//# of this license document, but changing it is not allowed.
+//#
+
+
+import QtQuick
+import QtQuick.Controls.Material
+import QtQuick.Controls
+import QtQuick.Layouts
+
+AbstractMenuView {
+    columns: 2
+    rows: 2
+
+    MouseArea {
+        cursorShape: Qt.DragMoveCursor
+
+        Layout.fillHeight: true
+        Layout.fillWidth: true
+        Layout.columnSpan: 2
+        Layout.rowSpan: 1
+
+        onClicked: {
+            model.userTap()
+        }
+
+
+        property bool track: false
+        property real oldX: 0
+        property real oldY: 0
+
+        onPressed: (mouse) => {
+                       track = true
+                       oldX = mouse.x
+                       oldY = mouse.y
+
+                   }
+
+        onReleased: {
+            track = false
+        }
+
+        onPositionChanged: (mouse) => {
+                               if (!model) {
+                                   return;
+                               }
+
+                               if (!track) {
+                                   return;
+                               }
+
+                               let delta = mouse.y - oldY;
+                               let radianDeltaY = (delta / (parent.height / 2)) * 45
+
+                               delta = mouse.x - oldX;
+                               let radianDeltaX = (delta / (parent.width / 2)) * 45
+
+                               model.mousePositionChanged(radianDeltaX, radianDeltaY)
+                               oldY = mouse.y;
+                               oldX = mouse.x;
+
+                           }
+    }
+
+    Button {
+        text: qsTr("Back to menu.")
+        onClicked: {
+            if (model) {
+                model.backToMenu()
+            }
+        }
+    }
+
+    Button {
+        text: qsTr("Start")
+        onClicked: {
+            if (model) {
+                model.backToMenu()
+            }
+        }
+    }
+}
diff --git a/src/Core/CrawlModule/Scene.qml b/src/Core/CrawlModule/Scene.qml
index 45e472c..1988796 100644
--- a/src/Core/CrawlModule/Scene.qml
+++ b/src/Core/CrawlModule/Scene.qml
@@ -46,7 +46,7 @@ View3D {
         property var arrayObjects: []
         property var world: (model)? model.world: null
 
-        property var gameMenuModel: (model)? model.menu: null
+        property var gameMenuModel: (world)? world.menu: null
         property var player: (world)? world.player: null
         property var releativeCameraPosition: (world)? world.cameraReleativePosition: null
         property var progress: (model)? model.prepareLvlProgress: null
diff --git a/src/Core/private/engine.cpp b/src/Core/private/engine.cpp
index f8ae55e..a50015d 100644
--- a/src/Core/private/engine.cpp
+++ b/src/Core/private/engine.cpp
@@ -37,27 +37,33 @@ void Engine::setQmlEngine(QQmlEngine *newEngine) {
     _engine = newEngine;
 }
 
-void Engine::setWorld(IWorld *world) {
-    if (_currentWorld == world)
+void Engine::setLevel(ILevel *world) {
+    if (_currentLevel == world)
         return ;
 
-    if (_currentWorld) {
-        _currentWorld->reset();
+    if (_currentLevel) {
+        _currentLevel->reset();
     }
 
-    _currentWorld = world;
+    _currentLevel = world;
     emit worldChanged();
 
-    if (!prepareNewWorld()) {
-        QuasarAppUtils::Params::log("Failed to init world. World name: " + _currentWorld->itemName(),
-                                    QuasarAppUtils::Error);
+    if (_currentLevel && _currentLevel->world() && !_currentLevel->world()->)) {
 
-        _currentWorld = nullptr;
+        if (_currentLevel->world()) {
+            QuasarAppUtils::Params::log("Failed to init world. World name: " + _currentLevel->world()->itemName(),
+                                        QuasarAppUtils::Error);
+        } else {
+            QuasarAppUtils::Params::log("Failed to init world. The World object is null! ",
+                                        QuasarAppUtils::Error);
+        }
+
+        _currentLevel = nullptr;
         return;
     }
 
     startRenderLoop();
-    _currentWorld->runAsBackGround();
+    _currentLevel->world()->runAsBackGround();
 }
 
 void Engine::setScane(QObject *newScane) {
@@ -68,28 +74,14 @@ void Engine::setScane(QObject *newScane) {
 }
 
 QObject *Engine::player() const {
-    if (_currentWorld)
-        return _currentWorld->_player;
+    if (_currentLevel && _currentLevel->world())
+        return _currentLevel->world()->player();
 
     return nullptr;
 }
 
 QObject *Engine::world() const {
-    return _currentWorld;
-}
-
-
-QObject *Engine::menu() const {
-    return _menu;
-}
-
-void Engine::setMenu(QObject *newMenu) {
-    if (_menu == newMenu) {
-        return;
-    }
-
-    _menu = newMenu;
-    emit menuChanged();
+    return _currentLevel->world();
 }
 
 int Engine::prepareLvlProgress() const {
@@ -97,10 +89,10 @@ int Engine::prepareLvlProgress() const {
 }
 
 bool Engine::start() const {
-    if (!_currentWorld)
+    if (!_currentLevel)
         return false;
 
-    if (!_currentWorld->isInit())
+    if (!_currentLevel->isInit())
         return false;
 
     return _currentWorld->start();
@@ -138,20 +130,6 @@ void Engine::setPrepareLvlProgress(int newPrepareLvlProgress) {
     emit prepareLvlProgressChanged();
 }
 
-bool Engine::prepareNewWorld() {
-    if (!_currentWorld->prepare()) {
-        return false;
-    }
-
-    if (!_currentWorld->userInterface()->init()) {
-        return false;
-    }
-
-    setMenu(_currentWorld->userInterface());
-
-    return true;
-}
-
 void Engine::renderLoop() {
 
     if (!_currentWorld)
diff --git a/src/Core/private/engine.h b/src/Core/private/engine.h
index feaac87..2471041 100644
--- a/src/Core/private/engine.h
+++ b/src/Core/private/engine.h
@@ -12,6 +12,7 @@
 #include <QObject>
 #include <QQmlEngine>
 #include <Crawl/diff.h>
+#include <Crawl/ilevel.h>
 
 namespace CRAWL {
 
@@ -28,7 +29,6 @@ class Engine : public QObject {
     Q_PROPERTY(QObject* world READ world NOTIFY worldChanged)
 
     Q_PROPERTY(QObject* scane READ scane WRITE setScane NOTIFY scaneChanged)
-    Q_PROPERTY(QObject* menu READ menu WRITE setMenu NOTIFY menuChanged)
     Q_PROPERTY(int _prepareLvlProgress READ prepareLvlProgress WRITE setPrepareLvlProgress NOTIFY prepareLvlProgressChanged)
 
 public:
@@ -48,10 +48,10 @@ public:
     void setQmlEngine(QQmlEngine *newEngine);
 
     /**
-     * @brief setWorld This method set new world for game.
-     * @param world This is pointer to new world.
+     * @brief setLevel This method set new world level for game.
+     * @param world This is pointer to new world level.
      */
-    void setWorld(IWorld *world);
+    void setLevel(ILevel *world);
 
     /**
      * @brief setScane This method sets new scane object. The scane object are
@@ -77,19 +77,6 @@ public:
      */
     QObject* world() const;
 
-    /**
-     * @brief menu This method return pointer to cistom menu.
-     * @return pointer to custom menu.
-     * @note menu creating in the Wolrld object.
-     */
-    QObject *menu() const;
-
-    /**
-     * @brief setMenu This method sets new menu object.
-     * @param newMenu
-     */
-    void setMenu(QObject *newMenu);
-
     /**
      * @brief prepareLvlProgress This method return rurrent progress of the loading lvl.
      * @return current progress of loading new level on the world. progress range is 0 - 100 
@@ -130,19 +117,18 @@ signals:
     void playerChanged();
     void worldChanged();
 
-    void menuChanged();
     void prepareLvlProgressChanged();
 
 private:
     void setPrepareLvlProgress(int newPrepareLvlProgress);
-    bool prepareNewWorld();
     void renderLoop();
 
 
     QObject *_scane = nullptr;
     QQmlEngine *_engine = nullptr;
-    IWorld* _currentWorld = nullptr;
-    QObject *_menu = nullptr;
+//    IWorld* _currentWorld = nullptr;
+    ILevel* _currentLevel = nullptr;
+
     int _prepareLvlProgress;
 
     quint64 _oldTimeRender = 0;
diff --git a/src/CrawlAbstractLvl/private/abslvlworld.cpp b/src/CrawlAbstractLvl/private/abslvlworld.cpp
index 24657d5..a6df278 100644
--- a/src/CrawlAbstractLvl/private/abslvlworld.cpp
+++ b/src/CrawlAbstractLvl/private/abslvlworld.cpp
@@ -77,8 +77,8 @@ CRAWL::IControl *AbsLvlWorld::initUserInterface() const {
     return new AbsLvlControl();
 }
 
-void AbsLvlWorld::initPlayerControl(CRAWL::IControl *control) {
-    return IWorld::initPlayerControl(control);
+void AbsLvlWorld::initControl(CRAWL::IControl *control) {
+    return IWorld::initControl(control);
 }
 
 QString AbsLvlWorld::itemTextId() const {
diff --git a/src/CrawlAbstractLvl/private/abslvlworld.h b/src/CrawlAbstractLvl/private/abslvlworld.h
index 56f5454..2f1d967 100644
--- a/src/CrawlAbstractLvl/private/abslvlworld.h
+++ b/src/CrawlAbstractLvl/private/abslvlworld.h
@@ -27,7 +27,7 @@ public:
     QString itemName() const override;
     int cost() const override;
     CRAWL::IControl *initUserInterface() const override;
-    void initPlayerControl(CRAWL::IControl *control) override;
+    void initControl(CRAWL::IControl *control) override;
     QString itemTextId() const override;
     int requiredTier() const override;
 
diff --git a/src/CrawlTestLvl/private/world.cpp b/src/CrawlTestLvl/private/world.cpp
index 4ceb308..01400a3 100644
--- a/src/CrawlTestLvl/private/world.cpp
+++ b/src/CrawlTestLvl/private/world.cpp
@@ -64,13 +64,13 @@ CRAWL::IControl *World::initUserInterface() const {
     return new TestControl();
 }
 
-void World::initPlayerControl(CRAWL::IControl *control) {
+void World::initControl(CRAWL::IControl *control) {
     if (auto test = dynamic_cast<TestControl*>(control)) {
         connect(test, &TestControl::xChanged, this, &World::handleXViewChanged);
         connect(test, &TestControl::yChanged, this, &World::handleYViewChanged);
     }
 
-    return IWorld::initPlayerControl(control);
+    return IWorld::initControl(control);
 }
 
 CRAWL::PlayableObject *World::initPlayer() const {
diff --git a/src/CrawlTestLvl/private/world.h b/src/CrawlTestLvl/private/world.h
index 03365cb..e94b136 100644
--- a/src/CrawlTestLvl/private/world.h
+++ b/src/CrawlTestLvl/private/world.h
@@ -27,7 +27,7 @@ public:
     QString itemName() const override;
     int cost() const override;
     CRAWL::IControl *initUserInterface() const override;
-    void initPlayerControl(CRAWL::IControl *control) override;
+    void initControl(CRAWL::IControl *control) override;
     CRAWL::PlayableObject *initPlayer() const override;
     CRAWL::IAI *initBackGroundAI() const override;
     QString itemTextId() const override;
diff --git a/src/JungleLvl/private/world.cpp b/src/JungleLvl/private/world.cpp
index 8c1b314..b6f146c 100644
--- a/src/JungleLvl/private/world.cpp
+++ b/src/JungleLvl/private/world.cpp
@@ -104,8 +104,8 @@ CRAWL::IControl *World::initUserInterface() const {
     return IWorld::initUserInterface();
 }
 
-void World::initPlayerControl(CRAWL::IControl *control) {
-    return IWorld::initPlayerControl(control);
+void World::initControl(CRAWL::IControl *control) {
+    return IWorld::initControl(control);
 }
 
 CRAWL::PlayableObject *World::initPlayer() const {
diff --git a/src/JungleLvl/private/world.h b/src/JungleLvl/private/world.h
index 9320b2e..e94f435 100644
--- a/src/JungleLvl/private/world.h
+++ b/src/JungleLvl/private/world.h
@@ -26,7 +26,7 @@ public:
     QString itemName() const override;
     int cost() const override;
     CRAWL::IControl *initUserInterface() const override;
-    void initPlayerControl(CRAWL::IControl *control) override;
+    void initControl(CRAWL::IControl *control) override;
     CRAWL::PlayableObject *initPlayer() const override;
     CRAWL::IAI *initBackGroundAI() const override;
     QString itemTextId() const override;

From 8979ba73ce8f2f8aeac26d836b5adeb8d36fa858 Mon Sep 17 00:00:00 2001
From: EndrII <EndrIIMail@gmail.com>
Date: Thu, 12 Aug 2021 23:27:20 +0300
Subject: [PATCH 18/19] update core library

---
 src/Client/languages/de.ts             |   8 +-
 src/Client/languages/en.ts             |   8 +-
 src/Client/languages/es.ts             |   8 +-
 src/Client/languages/fr.ts             |   8 +-
 src/Client/languages/ja.ts             |   8 +-
 src/Client/languages/pl.ts             |   8 +-
 src/Client/languages/ru.ts             |   8 +-
 src/Client/languages/tr.ts             |   8 +-
 src/Client/languages/uk.ts             |   8 +-
 src/Client/languages/zh.ts             |   8 +-
 src/Core/Crawl.qrc                     |   1 -
 src/Core/Crawl/clientapp.cpp           |  44 ++++----
 src/Core/Crawl/clientapp.h             |  13 ++-
 src/Core/Crawl/ilevel.cpp              |   6 +-
 src/Core/Crawl/ilevel.h                |   7 +-
 src/Core/Crawl/ipreviewscaneworld.cpp  |   4 +
 src/Core/Crawl/ipreviewscaneworld.h    |   3 +
 src/Core/Crawl/iworld.cpp              |  28 ++++-
 src/Core/Crawl/iworld.h                |  28 ++++-
 src/Core/CrawlModule/Crawl.qml         |  10 +-
 src/Core/CrawlModule/MainMenu.qml      |   2 +-
 src/Core/CrawlModule/PreviewScane.qml  | 135 -------------------------
 src/Core/CrawlModule/Scene.qml         |  18 ++--
 src/Core/private/engine.cpp            |  97 +++++++++++++-----
 src/Core/private/engine.h              |  71 +++++++++----
 src/Core/private/mainmenumodel.cpp     |   4 +-
 src/Core/private/mainmenumodel.h       |   4 +-
 src/Core/private/store.cpp             |   8 ++
 src/Core/private/store.h               |  12 +++
 src/Core/private/storeviewmodel.cpp    |  93 +++++++++++++++++
 src/Core/private/storeviewmodel.h      |  62 ++++++++++++
 src/CrawlAbstractLvl/abstractlevel.cpp |   9 +-
 src/CrawlAbstractLvl/abstractlevel.h   |   4 -
 33 files changed, 457 insertions(+), 286 deletions(-)
 delete mode 100644 src/Core/CrawlModule/PreviewScane.qml
 create mode 100644 src/Core/private/storeviewmodel.cpp
 create mode 100644 src/Core/private/storeviewmodel.h

diff --git a/src/Client/languages/de.ts b/src/Client/languages/de.ts
index c78ae05..8a287e7 100644
--- a/src/Client/languages/de.ts
+++ b/src/Client/languages/de.ts
@@ -39,10 +39,6 @@
 </context>
 <context>
     <name>MainMenu</name>
-    <message>
-        <source>Play game</source>
-        <translation type="unfinished"></translation>
-    </message>
     <message>
         <source>My Settings</source>
         <translation type="unfinished"></translation>
@@ -51,6 +47,10 @@
         <source>Exit</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <source>Select level</source>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>PreviewControl</name>
diff --git a/src/Client/languages/en.ts b/src/Client/languages/en.ts
index 2cba5b8..e65072a 100644
--- a/src/Client/languages/en.ts
+++ b/src/Client/languages/en.ts
@@ -39,10 +39,6 @@
 </context>
 <context>
     <name>MainMenu</name>
-    <message>
-        <source>Play game</source>
-        <translation type="unfinished"></translation>
-    </message>
     <message>
         <source>My Settings</source>
         <translation type="unfinished"></translation>
@@ -51,6 +47,10 @@
         <source>Exit</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <source>Select level</source>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>PreviewControl</name>
diff --git a/src/Client/languages/es.ts b/src/Client/languages/es.ts
index 300328b..ffbe3b7 100644
--- a/src/Client/languages/es.ts
+++ b/src/Client/languages/es.ts
@@ -39,10 +39,6 @@
 </context>
 <context>
     <name>MainMenu</name>
-    <message>
-        <source>Play game</source>
-        <translation type="unfinished"></translation>
-    </message>
     <message>
         <source>My Settings</source>
         <translation type="unfinished"></translation>
@@ -51,6 +47,10 @@
         <source>Exit</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <source>Select level</source>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>PreviewControl</name>
diff --git a/src/Client/languages/fr.ts b/src/Client/languages/fr.ts
index 2cba5b8..e65072a 100644
--- a/src/Client/languages/fr.ts
+++ b/src/Client/languages/fr.ts
@@ -39,10 +39,6 @@
 </context>
 <context>
     <name>MainMenu</name>
-    <message>
-        <source>Play game</source>
-        <translation type="unfinished"></translation>
-    </message>
     <message>
         <source>My Settings</source>
         <translation type="unfinished"></translation>
@@ -51,6 +47,10 @@
         <source>Exit</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <source>Select level</source>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>PreviewControl</name>
diff --git a/src/Client/languages/ja.ts b/src/Client/languages/ja.ts
index 2cba5b8..e65072a 100644
--- a/src/Client/languages/ja.ts
+++ b/src/Client/languages/ja.ts
@@ -39,10 +39,6 @@
 </context>
 <context>
     <name>MainMenu</name>
-    <message>
-        <source>Play game</source>
-        <translation type="unfinished"></translation>
-    </message>
     <message>
         <source>My Settings</source>
         <translation type="unfinished"></translation>
@@ -51,6 +47,10 @@
         <source>Exit</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <source>Select level</source>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>PreviewControl</name>
diff --git a/src/Client/languages/pl.ts b/src/Client/languages/pl.ts
index 2cba5b8..e65072a 100644
--- a/src/Client/languages/pl.ts
+++ b/src/Client/languages/pl.ts
@@ -39,10 +39,6 @@
 </context>
 <context>
     <name>MainMenu</name>
-    <message>
-        <source>Play game</source>
-        <translation type="unfinished"></translation>
-    </message>
     <message>
         <source>My Settings</source>
         <translation type="unfinished"></translation>
@@ -51,6 +47,10 @@
         <source>Exit</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <source>Select level</source>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>PreviewControl</name>
diff --git a/src/Client/languages/ru.ts b/src/Client/languages/ru.ts
index 2cba5b8..e65072a 100644
--- a/src/Client/languages/ru.ts
+++ b/src/Client/languages/ru.ts
@@ -39,10 +39,6 @@
 </context>
 <context>
     <name>MainMenu</name>
-    <message>
-        <source>Play game</source>
-        <translation type="unfinished"></translation>
-    </message>
     <message>
         <source>My Settings</source>
         <translation type="unfinished"></translation>
@@ -51,6 +47,10 @@
         <source>Exit</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <source>Select level</source>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>PreviewControl</name>
diff --git a/src/Client/languages/tr.ts b/src/Client/languages/tr.ts
index 2cba5b8..e65072a 100644
--- a/src/Client/languages/tr.ts
+++ b/src/Client/languages/tr.ts
@@ -39,10 +39,6 @@
 </context>
 <context>
     <name>MainMenu</name>
-    <message>
-        <source>Play game</source>
-        <translation type="unfinished"></translation>
-    </message>
     <message>
         <source>My Settings</source>
         <translation type="unfinished"></translation>
@@ -51,6 +47,10 @@
         <source>Exit</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <source>Select level</source>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>PreviewControl</name>
diff --git a/src/Client/languages/uk.ts b/src/Client/languages/uk.ts
index 2cba5b8..e65072a 100644
--- a/src/Client/languages/uk.ts
+++ b/src/Client/languages/uk.ts
@@ -39,10 +39,6 @@
 </context>
 <context>
     <name>MainMenu</name>
-    <message>
-        <source>Play game</source>
-        <translation type="unfinished"></translation>
-    </message>
     <message>
         <source>My Settings</source>
         <translation type="unfinished"></translation>
@@ -51,6 +47,10 @@
         <source>Exit</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <source>Select level</source>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>PreviewControl</name>
diff --git a/src/Client/languages/zh.ts b/src/Client/languages/zh.ts
index 2cba5b8..e65072a 100644
--- a/src/Client/languages/zh.ts
+++ b/src/Client/languages/zh.ts
@@ -39,10 +39,6 @@
 </context>
 <context>
     <name>MainMenu</name>
-    <message>
-        <source>Play game</source>
-        <translation type="unfinished"></translation>
-    </message>
     <message>
         <source>My Settings</source>
         <translation type="unfinished"></translation>
@@ -51,6 +47,10 @@
         <source>Exit</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <source>Select level</source>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>PreviewControl</name>
diff --git a/src/Core/Crawl.qrc b/src/Core/Crawl.qrc
index cf6a78a..d91496d 100644
--- a/src/Core/Crawl.qrc
+++ b/src/Core/Crawl.qrc
@@ -24,7 +24,6 @@
         <file>CrawlCoreAssets/particles/smokeSprite.png</file>
         <file>CrawlModule/particles/Fire.qml</file>
         <file>CrawlModule/particles/Wint.qml</file>
-        <file>CrawlModule/PreviewScane.qml</file>
         <file>CrawlModule/PreviewControl.qml</file>
     </qresource>
 </RCC>
diff --git a/src/Core/Crawl/clientapp.cpp b/src/Core/Crawl/clientapp.cpp
index e8f0244..5d18c6a 100644
--- a/src/Core/Crawl/clientapp.cpp
+++ b/src/Core/Crawl/clientapp.cpp
@@ -23,6 +23,7 @@
 #include "pluginloader.h"
 #include <viewsolutions.h>
 #include "worldstatus.h"
+#include "user.h"
 
 namespace CRAWL {
 
@@ -36,18 +37,27 @@ QByteArray ClientApp::initTheme() {
     }
 }
 
+ILevel *ClientApp::getLastLevel() {
+    for (const auto &data : qAsConst(_availableLvls)) {
+        if (data.model && data.model->world() && _engine->currentUser() &&
+                _engine->currentUser()->isUnlocked(data.model->world()->itemId())) {
+            return data.model;
+        }
+    }
+
+    return nullptr;
+}
+
 ClientApp::ClientApp() {
     _engine = new Engine();
     _menu = new MainMenuModel();
-    _store = new Store();
 
-    connect(_menu, &MainMenuModel::sigNewGame, this, &ClientApp::start);
+    connect(_menu, &MainMenuModel::sigLevelChanged, this, &ClientApp::changeLevel);
 }
 
 ClientApp::~ClientApp() {
     delete _menu;
     delete _engine;
-    delete _store;
 
     for (auto it = _availableLvls.begin(); it != _availableLvls.end(); ++it) {
         delete it.value().viewModel;
@@ -57,26 +67,17 @@ ClientApp::~ClientApp() {
     _availableLvls.clear();
 }
 
-IWorld *ClientApp::getLastWorld() {
-    for (const auto &data : qAsConst(_availableLvls)) {
-        if (data.viewModel && data.viewModel->unlocked()) {
-            return data.model;
-        }
-    }
-
-    return nullptr;
-}
-
 void ClientApp::initStore(Store *store) {
     QMultiHash<int, const IItem *> storeItems;
     for (const auto &data : qAsConst(_availableLvls)) {
-        storeItems.unite(data.model->childItemsRecursive());
+        if (data.model && data.model->world())
+            storeItems.unite(data.model->world()->childItemsRecursive());
     }
 
     store->init(storeItems);
 }
 
-void ClientApp::start(const QString &lvl) {
+void ClientApp::changeLevel(int lvl) {
     WordlData data = _availableLvls.value(lvl);
 
     if (!data.model) {
@@ -91,8 +92,7 @@ void ClientApp::start(const QString &lvl) {
         return;
     }
 
-    _engine->setWorld(data.model);
-    _engine->start();
+    _engine->setLevel(data.model);
 }
 
 bool ClientApp::init(QQmlApplicationEngine *engine) {
@@ -133,19 +133,19 @@ bool ClientApp::init(QQmlApplicationEngine *engine) {
     if (engine->rootObjects().isEmpty())
         return false;
 
-    _engine->setWorld(getLastWorld());
+    _engine->setLevel(getLastLevel());
     _engine->setQmlEngine(engine);
-    initStore(_store);
+    initStore(_engine->store());
 
     return true;
 }
 
-void ClientApp::addLvl(IWorld *levelWordl) {
+void ClientApp::addLvl(ILevel *levelWordl) {
     WordlData data;
 
     data.model = levelWordl;
-    data.viewModel = new WorldViewData(data.model);
-    _availableLvls.insert(data.model->itemName(), data);
+    data.viewModel = new WorldViewData(data.model->world());
+    _availableLvls.insert(data.model->world()->itemId(), data);
     _menu->addWorldViewModel(data.viewModel);
 }
 
diff --git a/src/Core/Crawl/clientapp.h b/src/Core/Crawl/clientapp.h
index 25dfd4e..593a5c3 100644
--- a/src/Core/Crawl/clientapp.h
+++ b/src/Core/Crawl/clientapp.h
@@ -27,7 +27,6 @@ class MainMenuModel;
 class IControl;
 class Store;
 
-
 /**
  * @brief The WordlData struct simple structure that contains information about world.
  */
@@ -68,25 +67,25 @@ public:
 
 private:
     QByteArray initTheme();
-    IWorld* getLastWorld();
+    ILevel *getLastLevel();
 
     void initStore(Store* store);
     /**
      * @brief addLvl This method should be add level to game.
      * @param levelWordl This is world instance
      */
-    void addLvl(IWorld* levelWordl);
+    void addLvl(ILevel* levelWordl);
 
     /**
-     * @brief start This method star new game in @a lvl
+     * @brief changeLevel This method star new game in @a lvl
      * @param lvl This is lvl name
      */
-    void start(const QString& lvl);
+    void changeLevel(int lvl);
 
-    QHash<QString, WordlData> _availableLvls;
+    QHash<int, WordlData> _availableLvls;
     MainMenuModel *_menu = nullptr;
     Engine *_engine = nullptr;
-    Store *_store = nullptr;
+
 };
 
 }
diff --git a/src/Core/Crawl/ilevel.cpp b/src/Core/Crawl/ilevel.cpp
index b73cec0..7fdf80f 100644
--- a/src/Core/Crawl/ilevel.cpp
+++ b/src/Core/Crawl/ilevel.cpp
@@ -7,7 +7,7 @@
 
 #include "iitem.h"
 #include "ilevel.h"
-#include "iworld.h"
+#include "ipreviewscaneworld.h"
 
 namespace CRAWL {
 
@@ -20,7 +20,7 @@ IWorld *ILevel::world() {
     return _world;
 }
 
-IWorld *ILevel::previewScane() {
+IPreviewScaneWorld *ILevel::previewScane() {
     return _previewScane;
 }
 
@@ -33,7 +33,7 @@ void ILevel::setWorld(IWorld *newWorld) {
     _world = newWorld;
 }
 
-void ILevel::setPreviewScane(IWorld *newPreviewScane) {
+void ILevel::setPreviewScane(IPreviewScaneWorld *newPreviewScane) {
     _previewScane = newPreviewScane;
 }
 
diff --git a/src/Core/Crawl/ilevel.h b/src/Core/Crawl/ilevel.h
index 0516f21..bc21c36 100644
--- a/src/Core/Crawl/ilevel.h
+++ b/src/Core/Crawl/ilevel.h
@@ -15,6 +15,7 @@ namespace CRAWL {
 
 class IWorld;
 class IItem;
+class IPreviewScaneWorld;
 
 /**
  * @brief The ILevel class This interface make the world instance object.
@@ -39,7 +40,7 @@ public:
      * @return pointer to the model of the preview scane.
      * @see ILevel::setPreviewScane
      */
-    IWorld* previewScane();
+    IPreviewScaneWorld* previewScane();
 
     /**
      * @brief reset This method unload all loaded data from level.
@@ -61,12 +62,12 @@ protected:
      * @note The @a newPreviewScane item will be distroued with the parent object.
      * @see ILevel::previewScane
      */
-    void setPreviewScane(IWorld *newPreviewScane);
+    void setPreviewScane(IPreviewScaneWorld *newPreviewScane);
 
 private:
 
     IWorld* _world = nullptr;
-    IWorld* _previewScane = nullptr;
+    IPreviewScaneWorld* _previewScane = nullptr;
 };
 
 }
diff --git a/src/Core/Crawl/ipreviewscaneworld.cpp b/src/Core/Crawl/ipreviewscaneworld.cpp
index 01acb17..2b44afa 100644
--- a/src/Core/Crawl/ipreviewscaneworld.cpp
+++ b/src/Core/Crawl/ipreviewscaneworld.cpp
@@ -89,6 +89,10 @@ void IPreviewScaneWorld::handleSelect(int item, bool isSelected) {
     }
 }
 
+const StartData &IPreviewScaneWorld::configuration() const {
+    return _configuration;
+}
+
 void IPreviewScaneWorld::initControl(IControl *control) {
     auto controlObject = dynamic_cast<PreviewControl*>(control);
 
diff --git a/src/Core/Crawl/ipreviewscaneworld.h b/src/Core/Crawl/ipreviewscaneworld.h
index 98e736c..3c27a29 100644
--- a/src/Core/Crawl/ipreviewscaneworld.h
+++ b/src/Core/Crawl/ipreviewscaneworld.h
@@ -17,6 +17,7 @@ namespace CRAWL {
  */
 class CRAWL_EXPORT IPreviewScaneWorld: public IWorld
 {
+    Q_OBJECT
 public:
     /**
      * @brief IPreviewScaneWorld This is main constructo of the preview world model.
@@ -38,6 +39,8 @@ public:
     bool start(const StartData &config) override;
     bool stop() override;
 
+    const StartData &configuration() const;
+
 signals:
     /**
      * @brief sigPrepareIsFinished This signal emited when user finished prepare to game.
diff --git a/src/Core/Crawl/iworld.cpp b/src/Core/Crawl/iworld.cpp
index 04f7112..3884643 100644
--- a/src/Core/Crawl/iworld.cpp
+++ b/src/Core/Crawl/iworld.cpp
@@ -67,6 +67,10 @@ void IWorld::render(unsigned int tbfMsec) {
     _ItemsMutex.unlock();
 
     for (int id: toRemove) {
+        if (id == static_cast<IWorldItem *>(player())->guiId()) {
+            playerIsDead(static_cast<PlayableObject*>(player()));
+        }
+
         removeItem(id);
     }
 
@@ -97,6 +101,7 @@ bool IWorld::start(const StartData& config) {
     setTargetFps(60);
     setRunning(true);
     _eventServer->start();
+    setVisible(true);
 
     return true;
 }
@@ -134,6 +139,7 @@ IWorldItem *IWorld::generate(const QString &objectType) const {
 
 bool IWorld::stop() {
     setRunning(false);
+    setVisible(false);
     _eventServer->stop();
     return true;
 }
@@ -149,7 +155,7 @@ IWorldItem *IWorld::getItem(int id) const {
 }
 
 void IWorld::clearItems() {
-    stop();
+    IWorld::stop();
 
     while (_items.cbegin() != _items.cend()) {
         removeItem(*_items.cbegin());
@@ -307,6 +313,19 @@ const WorldRule *IWorld::worldRules() {
     return _worldRules;
 }
 
+void IWorld::setVisible(bool visible) {
+    if (_visible == visible) {
+        return;
+    }
+
+    _visible = visible;
+    emit visibleChanged();
+}
+
+void IWorld::playerIsDead(PlayableObject *) const {
+    emit sigGameFinished();
+}
+
 bool IWorld::running() const {
     return _running;
 }
@@ -390,7 +409,7 @@ void IWorld::setCameraReleativePosition(const QVector3D &newCameraReleativePosit
 }
 
 void IWorld::handleStop() {
-    runAsBackGround();
+    stop();
 }
 
 const QVector3D &IWorld::cameraReleativePosition() const {
@@ -467,4 +486,9 @@ void IWorld::setMenu(QObject *newMenu) {
     emit menuChanged();
 }
 
+bool IWorld::visible() const
+{
+    return _visible;
+}
+
 }
diff --git a/src/Core/Crawl/iworld.h b/src/Core/Crawl/iworld.h
index 7adba82..45a31e2 100644
--- a/src/Core/Crawl/iworld.h
+++ b/src/Core/Crawl/iworld.h
@@ -71,8 +71,9 @@ class CRAWL_EXPORT IWorld : public QObject, public IRender, public IItem
      * @see IWorld::getMenu
      * @see IWorld::userInterface
     */
-    Q_PROPERTY(QObject * menu READ menu WRITE setMenu NOTIFY menuChanged)
+    Q_PROPERTY(QObject * menu READ getMenu WRITE setMenu NOTIFY menuChanged)
     Q_PROPERTY(QString hdr READ hdr NOTIFY hdrChanged)
+    Q_PROPERTY(bool visible READ visible NOTIFY visibleChanged)
 
     Q_PROPERTY(int worldStatus READ wordlStatus WRITE setWorldStatus NOTIFY worldStatusChanged)
 
@@ -248,12 +249,17 @@ public:
      */
     void reset();
 
+    /**
+     * @brief visible This metohd retunr current value of the visible object.
+     * @return true if view is visible else false.
+     */
+    bool visible() const;
+
 signals:
     /**
      * @brief sigGameFinished This signal emit when game are finished
-     * @brief result This is player statistics after finished level,
      */
-    void sigGameFinished(GameResult result);
+    void sigGameFinished() const;
 
     /**
      * @brief sigOBjctsListChanged This signal emited when lvel status are changed.
@@ -304,6 +310,11 @@ signals:
      */
     void menuChanged();
 
+    /**
+     * @brief visibleChanged This signal emited when visible of the view changed.
+     */
+    void visibleChanged();
+
 protected:
 
     /**
@@ -420,6 +431,16 @@ protected:
      */
     const WorldRule *worldRules();
 
+    /**
+     * @brief setVisible This method sets visible propertye for the qml view.
+     * @param visible This is new value of a property
+     */
+    void setVisible(bool visible);
+
+    /**
+     * @brief playerIsDead This method will be invoked when player object get signal dead.
+     */
+    virtual void playerIsDead(PlayableObject*) const;
 
 protected slots:
     virtual void onIntersects(const IWorldItem * trigger, QList<const IWorldItem *> list);
@@ -524,6 +545,7 @@ private:
 
     int _targetFps = 60;
     bool _running = false;
+    bool _visible = true;
 
     // testing
     friend ClastersTest;
diff --git a/src/Core/CrawlModule/Crawl.qml b/src/Core/CrawlModule/Crawl.qml
index 8346cf8..e68014d 100644
--- a/src/Core/CrawlModule/Crawl.qml
+++ b/src/Core/CrawlModule/Crawl.qml
@@ -18,11 +18,19 @@ ApplicationWindow {
     height: 720;
     title: qsTr("Crawl");
 
+    property var model: engine
+
     Metrix {id: metrix}
 
     Scene {
         id: scane;
-        model: engine;
+        model: (model)? model.world : null;
+        anchors.fill: parent;
+    }
+
+    Scene {
+        id: nest;
+        model: (model)? model.world : null;
         anchors.fill: parent;
     }
 
diff --git a/src/Core/CrawlModule/MainMenu.qml b/src/Core/CrawlModule/MainMenu.qml
index fcf4302..ad21db9 100644
--- a/src/Core/CrawlModule/MainMenu.qml
+++ b/src/Core/CrawlModule/MainMenu.qml
@@ -38,7 +38,7 @@ Item {
 
         MainMenuButton {
             id: play
-            text: qsTr("Play game")
+            text: qsTr("Select level")
 
             onClicked: {
                 selectLvl.open()
diff --git a/src/Core/CrawlModule/PreviewScane.qml b/src/Core/CrawlModule/PreviewScane.qml
deleted file mode 100644
index e7ed5a1..0000000
--- a/src/Core/CrawlModule/PreviewScane.qml
+++ /dev/null
@@ -1,135 +0,0 @@
-import QtQuick
-import QtQuick3D
-import QtQuick.Controls.Material
-import QtQuick.Controls
-import QtQuick.Layouts
-import QtQuick3D.Particles3D
-
-
-View3D {
-    id: scene;
-
-    property var model: null;
-    renderMode: View3D.Offscreen
-
-    PerspectiveCamera {
-        id: camera
-        position: Qt.vector3d(0,0, 100)
-    }
-
-    SceneEnvironment {
-        id: defautlBackground
-        backgroundMode: SceneEnvironment.Color
-        clearColor: "#777777"
-    }
-
-    environment: /*(privateRoot.world)? background:*/ defautlBackground
-
-    ParticleSystem3D {
-        id: privateRoot
-        property var arrayObjects: []
-        property var world: (model)? model.world: null
-
-        property var gameMenuModel: (model)? model.menu: null
-        property var player: (world)? world.player: null
-        property var releativeCameraPosition: (world)? world.cameraReleativePosition: null
-
-        function add (cppObjId) {
-            if (!model) {
-                console.log("create object fail")
-                return;
-            }
-
-            const objModel = model.getGameObject(cppObjId);
-
-            if (!objModel) {
-                console.log("object model not found");
-                return;
-            }
-
-            var viewTemplate = objModel.viewTemplate;
-
-            var temp = Qt.createComponent(viewTemplate)
-            if (temp.status === Component.Ready) {
-                var obj = temp.createObject(privateRoot)
-                obj.model = objModel;
-                arrayObjects.push(obj)
-            } else {
-                console.log("wrong viewTemplate in model " + temp.errorString());
-            }
-        }
-
-        function remove(id) {
-            if (typeof id !== "number" || id < 0) {
-                console.log("id not found");
-                return;
-            }
-
-            for (var i = 0; i < arrayObjects.length; ++i) {
-                if (id === arrayObjects[i].guiId) {
-                    arrayObjects[i].destroy();
-                    arrayObjects.splice(i,1);
-
-                }
-            }
-        }
-
-        Connections {
-            target: privateRoot.world;
-            function onSigOBjctsListChanged(diff) {
-                if (!diff) {
-                    console.log("diff not found");
-                    return;
-                }
-
-                let tempDifRem = [];
-                tempDifRem = diff.getRemoveIds();
-                let tempDifAdd = [];
-                tempDifAdd = diff.getAddedIds();
-
-                for (let i = 0; i < tempDifAdd.length; ++i) {
-                    privateRoot.add(tempDifAdd[i]);
-                }
-
-                for (let j = 0; j < tempDifRem.length; ++j) {
-                    privateRoot.remove(tempDifRem[j]);
-                }
-            }
-        }
-
-        Connections {
-            target: privateRoot;
-
-            function onGameMenuModelChanged() {
-                if (!privateRoot.gameMenuModel) {
-                    return;
-                }
-
-                const comp = Qt.createComponent(privateRoot.gameMenuModel.view);
-                if (comp.status === Component.Ready) {
-                    if (privateRoot.gameMenu) {
-                        privateRoot.gameMenu.destroy()
-                    }
-
-                    privateRoot.gameMenu = comp.createObject(scene);
-                    if (privateRoot.gameMenu === null) {
-                        // Error Handling
-                        console.log("Error creating object");
-                    }
-
-                    privateRoot.gameMenu.model = privateRoot.gameMenuModel;
-
-                } else if (comp.status === Component.Error) {
-                    // Error Handling
-                    console.log("Error loading component: " + privateRoot.gameMenuModel.view, comp.errorString());
-                }
-            }
-
-            function onShowMenuChanged() {
-                if (privateRoot.gameMenu) {
-                    privateRoot.gameMenu.visible = !showMenu
-                }
-            }
-        }
-    }
-}
diff --git a/src/Core/CrawlModule/Scene.qml b/src/Core/CrawlModule/Scene.qml
index 1988796..6401b87 100644
--- a/src/Core/CrawlModule/Scene.qml
+++ b/src/Core/CrawlModule/Scene.qml
@@ -11,10 +11,12 @@ import engine.worldstatus
 View3D {
     id: scene;
 
-    property var model: null;
+    property var worldModel: null;
     property alias showMenu: privateRoot.showMenu
     renderMode: View3D.Offscreen
 
+    visible: worldModel && worldModel.visible
+
     Label {
         text: scane.renderStats.fps
         x: 200
@@ -44,18 +46,16 @@ View3D {
     ParticleSystem3D {
         id: privateRoot
         property var arrayObjects: []
-        property var world: (model)? model.world: null
 
-        property var gameMenuModel: (world)? world.menu: null
-        property var player: (world)? world.player: null
-        property var releativeCameraPosition: (world)? world.cameraReleativePosition: null
-        property var progress: (model)? model.prepareLvlProgress: null
+        property var gameMenuModel: (worldModel)? worldModel.menu: null
+        property var player: (worldModel)? worldModel.player: null
+        property var releativeCameraPosition: (worldModel)? worldModel.cameraReleativePosition: null
 
         property var gameMenu: null
-        property bool showMenu: (world)? WorldStatus.Game !== world.worldStatus : false;
+        property bool showMenu: (worldModel)? WorldStatus.Game !== worldModel.worldStatus : false;
 
         function add (cppObjId) {
-            if (!model) {
+            if (!worldModel) {
                 console.log("create object fail")
                 return;
             }
@@ -95,7 +95,7 @@ View3D {
         }
 
         Connections {
-            target: privateRoot.world;
+            target: worldModel;
             function onSigOBjctsListChanged(diff) {
                 if (!diff) {
                     console.log("diff not found");
diff --git a/src/Core/private/engine.cpp b/src/Core/private/engine.cpp
index a50015d..4a5a8ef 100644
--- a/src/Core/private/engine.cpp
+++ b/src/Core/private/engine.cpp
@@ -9,9 +9,11 @@
 
 #include <QQmlComponent>
 #include <Crawl/guiobject.h>
+#include <Crawl/ipreviewscaneworld.h>
 #include "Crawl/iworld.h"
 #include <QThread>
 #include <quasarapp.h>
+#include <storeviewmodel.h>
 #include "Crawl/icontrol.h"
 #include "QDateTime"
 #include "QtConcurrent"
@@ -20,10 +22,14 @@
 namespace CRAWL {
 
 Engine::Engine(QObject *parent): QObject(parent) {
+    _store = new Store();
+    _storeView = new StoreViewModel;
+
 }
 
 Engine::~Engine() {
     stopRenderLoop();
+    delete _storeView;
 }
 
 QObject *Engine::scane() {
@@ -48,15 +54,19 @@ void Engine::setLevel(ILevel *world) {
     _currentLevel = world;
     emit worldChanged();
 
-    if (_currentLevel && _currentLevel->world() && !_currentLevel->world()->)) {
+    if (!_currentLevel) {
 
-        if (_currentLevel->world()) {
-            QuasarAppUtils::Params::log("Failed to init world. World name: " + _currentLevel->world()->itemName(),
-                                        QuasarAppUtils::Error);
-        } else {
-            QuasarAppUtils::Params::log("Failed to init world. The World object is null! ",
-                                        QuasarAppUtils::Error);
-        }
+        QuasarAppUtils::Params::log("Failed to init world. The World object is null! ",
+                                    QuasarAppUtils::Error);
+
+        _currentLevel = nullptr;
+        return;
+    }
+
+    if (_currentLevel->world()) {
+        QuasarAppUtils::Params::log("Failed to init world. World name: " +
+                                    _currentLevel->world()->itemName(),
+                                    QuasarAppUtils::Error);
 
         _currentLevel = nullptr;
         return;
@@ -64,6 +74,12 @@ void Engine::setLevel(ILevel *world) {
 
     startRenderLoop();
     _currentLevel->world()->runAsBackGround();
+
+    connect(_currentLevel->previewScane(), &IPreviewScaneWorld::sigPrepareIsFinished,
+            this, &Engine::start);
+
+    connect(_currentLevel->world(), &IPreviewScaneWorld::sigGameFinished,
+            this, &Engine::stop);
 }
 
 void Engine::setScane(QObject *newScane) {
@@ -81,28 +97,41 @@ QObject *Engine::player() const {
 }
 
 QObject *Engine::world() const {
+    if (!_currentLevel)
+        return nullptr;
+
     return _currentLevel->world();
 }
 
-int Engine::prepareLvlProgress() const {
-    return _prepareLvlProgress;
+void Engine::start(const StartData& config) const {
+    if (!_currentLevel)
+        return;
+
+
+    if (!_currentLevel->previewScane()->stop()) {
+        return;
+    }
+
+    _currentLevel->world()->start(config);
 }
 
-bool Engine::start() const {
+void Engine::stop() const {
     if (!_currentLevel)
-        return false;
+        return;
 
-    if (!_currentLevel->isInit())
-        return false;
 
-    return _currentWorld->start();
+    if (!_currentLevel->world()->stop()) {
+        return;
+    }
+
+    _currentLevel->previewScane()->start(_currentLevel->previewScane()->configuration());
 }
 
 QObject *Engine::getGameObject(int id) const {
-    if (!_currentWorld)
+    if (!_currentLevel)
         return nullptr;
 
-    return _currentWorld->getItem(id);
+    return _currentLevel->world()->getItem(id);
 }
 
 void Engine::startRenderLoop() {
@@ -122,17 +151,9 @@ bool Engine::isRendering() const {
     return _renderLoopFuture.isRunning();
 }
 
-void Engine::setPrepareLvlProgress(int newPrepareLvlProgress) {
-    if (_prepareLvlProgress == newPrepareLvlProgress) {
-        return;
-    }
-    _prepareLvlProgress = newPrepareLvlProgress;
-    emit prepareLvlProgressChanged();
-}
-
 void Engine::renderLoop() {
 
-    if (!_currentWorld)
+    if (!_currentLevel)
         return;
 
     while (_renderLoop) {
@@ -144,11 +165,33 @@ void Engine::renderLoop() {
             continue;
         }
 
-        _currentWorld->render(currentTime - _oldTimeRender);
+        _currentLevel->world()->render(currentTime - _oldTimeRender);
         _oldTimeRender = currentTime;
     }
+}
 
+Store *Engine::store() const {
+    return _store;
+}
 
+QObject *Engine::nest() const {
+    if (!_currentLevel)
+        return nullptr;
+
+    return _currentLevel->previewScane();
+}
+
+User *Engine::currentUser() const {
+    return _currentUser;
+}
+
+QObject *Engine::storeView() const {
+    return _storeView;
+}
+
+void Engine::initStore(const QMultiHash<int, const IItem *> &availabelItems) {
+    _store->init(availabelItems);
+    _storeView->init(_store, _currentUser);
 }
 
 }
diff --git a/src/Core/private/engine.h b/src/Core/private/engine.h
index 2471041..1b80c12 100644
--- a/src/Core/private/engine.h
+++ b/src/Core/private/engine.h
@@ -18,6 +18,9 @@ namespace CRAWL {
 
 class IWorld;
 class Store;
+class StartData;
+class User;
+class StoreViewModel;
 
 /**
  * @brief The Engine class
@@ -27,9 +30,10 @@ class Engine : public QObject {
     Q_OBJECT
     Q_PROPERTY(QObject* player READ player NOTIFY playerChanged)
     Q_PROPERTY(QObject* world READ world NOTIFY worldChanged)
+    Q_PROPERTY(QObject* nest READ nest NOTIFY worldChanged)
+    Q_PROPERTY(QObject* storeView READ storeView NOTIFY storeViewChanged)
 
     Q_PROPERTY(QObject* scane READ scane WRITE setScane NOTIFY scaneChanged)
-    Q_PROPERTY(int _prepareLvlProgress READ prepareLvlProgress WRITE setPrepareLvlProgress NOTIFY prepareLvlProgressChanged)
 
 public:
     Engine(QObject * parent = nullptr);
@@ -77,18 +81,6 @@ public:
      */
     QObject* world() const;
 
-    /**
-     * @brief prepareLvlProgress This method return rurrent progress of the loading lvl.
-     * @return current progress of loading new level on the world. progress range is 0 - 100 
-     */
-    int prepareLvlProgress() const;
-
-    /**
-     * @brief start This method run current lvl
-     * @return true if lvl started successful.
-     */
-    bool start() const;
-
     /**
      * @brief getGameObject This method using in qml for getting main model of the gui objects.
      * @param id This is id of the gui object.
@@ -112,27 +104,68 @@ public:
      */
     bool isRendering() const;
 
+    /**
+     * @brief currentUser This method return pointer too current user.
+     * @return pointer too current user.
+     */
+    User *currentUser() const;
+
+    /**
+     * @brief storeView This method return pointer to store view model
+     * @return pointer to store view model
+     */
+    QObject *storeView() const;
+
+    /**
+     * @brief initStore This method is wrapper of the Store::init method.
+     * @param availabelItems This is list of available items.
+     */
+    void initStore(const QMultiHash<int, const IItem *> &availabelItems);
+
+    /**
+     * @brief store This pointer return pointer to store.
+     * @return pointer to store.
+     */
+    Store *store() const;
+
+    /**
+     * @brief nest This method return pointer to the nest model.
+     * @return pointer to the nest model.
+     */
+    QObject *nest() const ;
+
 signals:
     void scaneChanged();
     void playerChanged();
     void worldChanged();
+    void storeViewChanged();
 
-    void prepareLvlProgressChanged();
+private slots:
+    /**
+     * @brief start This method run current lvl ( move prepared data from the nest to game world)
+     * @param config This is confuguration that created new game world.
+     * @return true if lvl started successful.
+     */
+    void start(const StartData &config) const;
+
+    /**
+     * @brief stop This slots invoked when world finished own session.
+     */
+    void stop() const;
 
 private:
-    void setPrepareLvlProgress(int newPrepareLvlProgress);
     void renderLoop();
 
-
     QObject *_scane = nullptr;
     QQmlEngine *_engine = nullptr;
-//    IWorld* _currentWorld = nullptr;
     ILevel* _currentLevel = nullptr;
 
-    int _prepareLvlProgress;
-
     quint64 _oldTimeRender = 0;
 
+    User *_currentUser = nullptr;
+    StoreViewModel *_storeView = nullptr;
+    Store *_store = nullptr;
+
     QFuture<void> _renderLoopFuture;
     bool _renderLoop = false;
 };
diff --git a/src/Core/private/mainmenumodel.cpp b/src/Core/private/mainmenumodel.cpp
index 6426c36..c4c4ef8 100644
--- a/src/Core/private/mainmenumodel.cpp
+++ b/src/Core/private/mainmenumodel.cpp
@@ -37,8 +37,8 @@ void MainMenuModel::setAvailableLvls(const QList<QObject*> &newData) {
     _availableLvlsModel->setSource(newData);
 }
 
-void MainMenuModel::newGame(const QString &lvl) {
-    emit sigNewGame(lvl);
+void MainMenuModel::changeLevel(int lvl) {
+    emit sigLevelChanged(lvl);
 }
 
 }
diff --git a/src/Core/private/mainmenumodel.h b/src/Core/private/mainmenumodel.h
index 4428fcb..ed0d22a 100644
--- a/src/Core/private/mainmenumodel.h
+++ b/src/Core/private/mainmenumodel.h
@@ -36,12 +36,12 @@ public:
     QObject* availableLvlsModel() const;
     void addWorldViewModel(QObject *);
     void setAvailableLvls(const QList<QObject *> &newData);
-    Q_INVOKABLE void newGame(const QString& lvl);
+    Q_INVOKABLE void changeLevel(int lvl);
 
 
 signals:
     void userSettingsModelChanged(QObject* userSettingsModel);
-    void sigNewGame(const QString& lvl);
+    void sigLevelChanged(int lvl);
     void availableLvlsModelChanged();
 
 private:
diff --git a/src/Core/private/store.cpp b/src/Core/private/store.cpp
index 423d49e..68da23c 100644
--- a/src/Core/private/store.cpp
+++ b/src/Core/private/store.cpp
@@ -43,4 +43,12 @@ bool Store::init(const QMultiHash<int, const IItem *> &availabelItems) {
 const IItem *Store::getItemById(int id) const {
     return _store.value(id, nullptr);
 }
+
+int Store::size() const {
+    return _store.size();
+}
+
+QList<int> Store::keysList() const {
+    return QList<int>{_store.keyBegin(), _store.keyEnd()};
+}
 }
diff --git a/src/Core/private/store.h b/src/Core/private/store.h
index 8454166..d3b04cb 100644
--- a/src/Core/private/store.h
+++ b/src/Core/private/store.h
@@ -45,6 +45,18 @@ public:
      */
     const IItem* getItemById(int id) const;
 
+    /**
+     * @brief size This method return count of the available items in store.
+     * @return count of the available items.
+     */
+    int size() const;
+
+    /**
+     * @brief keysList This method return a list of available keys
+     * @return a list of available keys
+     */
+    QList<int> keysList() const;
+
 private:
     QMultiHash<int, const IItem*> _store;
 };
diff --git a/src/Core/private/storeviewmodel.cpp b/src/Core/private/storeviewmodel.cpp
new file mode 100644
index 0000000..e0a5429
--- /dev/null
+++ b/src/Core/private/storeviewmodel.cpp
@@ -0,0 +1,93 @@
+#include "storeviewmodel.h"
+#include "store.h"
+#include "user.h"
+
+#include <Crawl/iitem.h>
+
+namespace CRAWL {
+
+StoreViewModel::StoreViewModel() {
+
+}
+
+QModelIndex StoreViewModel::index(int row, int column, const QModelIndex &parent) const {
+    return QAbstractListModel::index(row, column, parent);
+}
+
+int StoreViewModel::rowCount(const QModelIndex &) const {
+    return _keys.size();
+}
+
+int StoreViewModel::columnCount(const QModelIndex &) const {
+    return 1;
+}
+
+QVariant StoreViewModel::data(const QModelIndex &index, int role) const {
+    if (!_store)
+        return {};
+
+    if (index.row() >= rowCount()) {
+        return {};
+    }
+
+    int id = _keys.at(index.row());
+
+    const IItem* item = _store->getItemById(id);
+
+    if (!item)
+        return {};
+
+    switch (role) {
+    case ItemId: return id;
+    case ItemName: return item->itemName();
+    case ItemImage: return item->image();
+    case ItemDescription: return item->description();
+    case ItemWasBuy: return _currentUser && _currentUser->isUnlocked(id);
+    default:
+        return {};
+    }
+}
+
+QHash<int, QByteArray> StoreViewModel::roleNames() const {
+    QHash<int, QByteArray> roles;
+
+    roles[ItemId] = "itemId";
+    roles[ItemName] = "itemName";
+    roles[ItemDescription] = "itemDescription";
+    roles[ItemImage] = "itemImage";
+    roles[ItemWasBuy] = "itemWasBuy";
+
+    return roles;
+}
+
+void StoreViewModel::init(const Store * store, const User* user) {
+    setUser(user);
+
+    int diff = store->size() - _keys.size();
+
+    if (diff > 0) {
+        beginInsertRows({}, _keys.size(), store->size() - 1);
+
+        _store = store;
+        _keys = store->keysList();
+
+        endInsertRows();
+
+    } else if (diff == 0) {
+        emit dataChanged(index(0,0), index(rowCount() - 1, columnCount() - 1));
+
+    } else  {
+        beginRemoveRows({}, store->size(), _keys.size() - 1);
+
+        _store = store;
+        _keys = store->keysList();
+
+        endRemoveRows();
+    }
+}
+
+void StoreViewModel::setUser(const User *user) {
+    _currentUser = user;
+    emit dataChanged(index(0,0), index(rowCount() - 1, columnCount() - 1), {ItemWasBuy});
+}
+}
diff --git a/src/Core/private/storeviewmodel.h b/src/Core/private/storeviewmodel.h
new file mode 100644
index 0000000..ffd2b5d
--- /dev/null
+++ b/src/Core/private/storeviewmodel.h
@@ -0,0 +1,62 @@
+//#
+//# Copyright (C) 2021-2021 QuasarApp.
+//# Distributed under the GPLv3 software license, see the accompanying
+//# Everyone is permitted to copy and distribute verbatim copies
+//# of this license document, but changing it is not allowed.
+//#
+
+#ifndef STOREVIEWMODEL_H
+#define STOREVIEWMODEL_H
+
+#include <QAbstractListModel>
+
+namespace CRAWL {
+
+class Store;
+class User;
+
+/**
+ * @brief The StoreViewModel class This is view model of the store. The object of this class should be initialized it he Store class.
+ */
+class StoreViewModel: public QAbstractListModel
+{
+    Q_OBJECT
+public:
+    StoreViewModel();
+
+    QModelIndex index(int row, int column, const QModelIndex &parent = {}) const override;
+    int rowCount(const QModelIndex &parent = {}) const override;
+    int columnCount(const QModelIndex &parent = {}) const override;
+    QVariant data(const QModelIndex &index, int role) const override;
+    QHash<int, QByteArray> roleNames() const override;
+
+    /**
+     * @brief init This method initialize data of the view model.
+     * @param _store This is poiter to store that contains all inforamtion about store items.
+     * @param user This is new pointer to current user.
+     * @see StoreViewModel::setUser
+     */
+    void init(const Store * store, const User* user);
+
+    /**
+     * @brief setUser This method update user pointer
+     * @param user This is new pointer to current user.
+     */
+    void setUser(const User* user);
+private:
+
+    enum StoreRoles {
+        ItemId,
+        ItemName,
+        ItemImage,
+        ItemDescription,
+        ItemWasBuy
+    };
+
+    const Store *_store = nullptr;
+    QList<int> _keys;
+    const User* _currentUser = nullptr;
+};
+
+}
+#endif // STOREVIEWMODEL_H
diff --git a/src/CrawlAbstractLvl/abstractlevel.cpp b/src/CrawlAbstractLvl/abstractlevel.cpp
index 7ed9c2d..5a5e7c9 100644
--- a/src/CrawlAbstractLvl/abstractlevel.cpp
+++ b/src/CrawlAbstractLvl/abstractlevel.cpp
@@ -9,10 +9,9 @@
 #include "abslvlworld.h"
 
 AbstractLevel::AbstractLevel() {
-
-}
-
-CRAWL::IWorld *AbstractLevel::world() {
     initAbstractLvlResources();
-    return new AbstractLvl::AbsLvlWorld();
+
+    setWorld(new AbstractLvl::AbsLvlWorld());
+    setPreviewScane(new AbstractLvl::AbsLvlWorld());
 }
+
diff --git a/src/CrawlAbstractLvl/abstractlevel.h b/src/CrawlAbstractLvl/abstractlevel.h
index a6641d8..d740d7c 100644
--- a/src/CrawlAbstractLvl/abstractlevel.h
+++ b/src/CrawlAbstractLvl/abstractlevel.h
@@ -19,10 +19,6 @@ inline void initAbstractLvlResources() { Q_INIT_RESOURCE(abstractLevel);
 class CRAWL_ABSTRACT_LEVEL_EXPORT AbstractLevel: public CRAWL::ILevel {
 public:
     AbstractLevel();
-
-    // ILevel interface
-public:
-    CRAWL::IWorld *world() override;
 };
 
 #endif // ABSTRACTLEVEL_H

From c97cf9f4e0f5aedafcf865262c2cae13f811c200 Mon Sep 17 00:00:00 2001
From: EndrII <EndrIIMail@gmail.com>
Date: Fri, 13 Aug 2021 17:35:42 +0300
Subject: [PATCH 19/19] fix build

---
 src/Client/languages/de.ts                   | 11 +++++++++
 src/Client/languages/en.ts                   | 11 +++++++++
 src/Client/languages/es.ts                   | 11 +++++++++
 src/Client/languages/fr.ts                   | 11 +++++++++
 src/Client/languages/ja.ts                   | 11 +++++++++
 src/Client/languages/pl.ts                   | 11 +++++++++
 src/Client/languages/ru.ts                   | 11 +++++++++
 src/Client/languages/tr.ts                   | 11 +++++++++
 src/Client/languages/uk.ts                   | 11 +++++++++
 src/Client/languages/zh.ts                   | 11 +++++++++
 src/Core/Crawl/clientapp.h                   |  2 +-
 src/Core/CrawlModule/Crawl.qml               |  4 ++--
 src/CrawlAbstractLvl/abstractlevel.cpp       |  1 -
 src/CrawlAbstractLvl/private/abslvlsnake.cpp | 25 ++++++++++++++++++++
 src/CrawlAbstractLvl/private/abslvlsnake.h   |  9 +++++++
 src/CrawlAbstractLvl/private/abslvlworld.cpp |  2 +-
 src/CrawlAbstractLvl/private/abslvlworld.h   |  2 +-
 src/CrawlTestLvl/private/testsnake.cpp       | 24 +++++++++++++++++++
 src/CrawlTestLvl/private/testsnake.h         |  9 +++++++
 src/CrawlTestLvl/private/world.cpp           |  2 +-
 src/CrawlTestLvl/private/world.h             |  2 +-
 src/CrawlTestLvl/testlevel.cpp               |  6 +----
 src/CrawlTestLvl/testlevel.h                 |  4 ----
 src/JungleLvl/jungle.cpp                     |  7 ++----
 src/JungleLvl/jungle.h                       |  3 ---
 src/JungleLvl/private/snake.cpp              | 24 +++++++++++++++++++
 src/JungleLvl/private/snake.h                |  8 ++++++-
 src/JungleLvl/private/world.cpp              |  2 +-
 src/JungleLvl/private/world.h                |  2 +-
 tests/units/clasterstest.cpp                 |  2 +-
 30 files changed, 221 insertions(+), 29 deletions(-)

diff --git a/src/Client/languages/de.ts b/src/Client/languages/de.ts
index 8a287e7..12ce0f2 100644
--- a/src/Client/languages/de.ts
+++ b/src/Client/languages/de.ts
@@ -1,6 +1,17 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!DOCTYPE TS>
 <TS version="2.1" language="de">
+<context>
+    <name>AbstractLvl::AbsLvlSnake</name>
+    <message>
+        <source>AbsLvlSnake</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>AbsLvlSnake Snake</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 <context>
     <name>AbstractLvl::AbsLvlWorld</name>
     <message>
diff --git a/src/Client/languages/en.ts b/src/Client/languages/en.ts
index e65072a..ff6a4b6 100644
--- a/src/Client/languages/en.ts
+++ b/src/Client/languages/en.ts
@@ -1,6 +1,17 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!DOCTYPE TS>
 <TS version="2.1">
+<context>
+    <name>AbstractLvl::AbsLvlSnake</name>
+    <message>
+        <source>AbsLvlSnake</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>AbsLvlSnake Snake</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 <context>
     <name>AbstractLvl::AbsLvlWorld</name>
     <message>
diff --git a/src/Client/languages/es.ts b/src/Client/languages/es.ts
index ffbe3b7..285d0f2 100644
--- a/src/Client/languages/es.ts
+++ b/src/Client/languages/es.ts
@@ -1,6 +1,17 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!DOCTYPE TS>
 <TS version="2.1" language="ru">
+<context>
+    <name>AbstractLvl::AbsLvlSnake</name>
+    <message>
+        <source>AbsLvlSnake</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>AbsLvlSnake Snake</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 <context>
     <name>AbstractLvl::AbsLvlWorld</name>
     <message>
diff --git a/src/Client/languages/fr.ts b/src/Client/languages/fr.ts
index e65072a..ff6a4b6 100644
--- a/src/Client/languages/fr.ts
+++ b/src/Client/languages/fr.ts
@@ -1,6 +1,17 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!DOCTYPE TS>
 <TS version="2.1">
+<context>
+    <name>AbstractLvl::AbsLvlSnake</name>
+    <message>
+        <source>AbsLvlSnake</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>AbsLvlSnake Snake</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 <context>
     <name>AbstractLvl::AbsLvlWorld</name>
     <message>
diff --git a/src/Client/languages/ja.ts b/src/Client/languages/ja.ts
index e65072a..ff6a4b6 100644
--- a/src/Client/languages/ja.ts
+++ b/src/Client/languages/ja.ts
@@ -1,6 +1,17 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!DOCTYPE TS>
 <TS version="2.1">
+<context>
+    <name>AbstractLvl::AbsLvlSnake</name>
+    <message>
+        <source>AbsLvlSnake</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>AbsLvlSnake Snake</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 <context>
     <name>AbstractLvl::AbsLvlWorld</name>
     <message>
diff --git a/src/Client/languages/pl.ts b/src/Client/languages/pl.ts
index e65072a..ff6a4b6 100644
--- a/src/Client/languages/pl.ts
+++ b/src/Client/languages/pl.ts
@@ -1,6 +1,17 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!DOCTYPE TS>
 <TS version="2.1">
+<context>
+    <name>AbstractLvl::AbsLvlSnake</name>
+    <message>
+        <source>AbsLvlSnake</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>AbsLvlSnake Snake</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 <context>
     <name>AbstractLvl::AbsLvlWorld</name>
     <message>
diff --git a/src/Client/languages/ru.ts b/src/Client/languages/ru.ts
index e65072a..ff6a4b6 100644
--- a/src/Client/languages/ru.ts
+++ b/src/Client/languages/ru.ts
@@ -1,6 +1,17 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!DOCTYPE TS>
 <TS version="2.1">
+<context>
+    <name>AbstractLvl::AbsLvlSnake</name>
+    <message>
+        <source>AbsLvlSnake</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>AbsLvlSnake Snake</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 <context>
     <name>AbstractLvl::AbsLvlWorld</name>
     <message>
diff --git a/src/Client/languages/tr.ts b/src/Client/languages/tr.ts
index e65072a..ff6a4b6 100644
--- a/src/Client/languages/tr.ts
+++ b/src/Client/languages/tr.ts
@@ -1,6 +1,17 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!DOCTYPE TS>
 <TS version="2.1">
+<context>
+    <name>AbstractLvl::AbsLvlSnake</name>
+    <message>
+        <source>AbsLvlSnake</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>AbsLvlSnake Snake</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 <context>
     <name>AbstractLvl::AbsLvlWorld</name>
     <message>
diff --git a/src/Client/languages/uk.ts b/src/Client/languages/uk.ts
index e65072a..ff6a4b6 100644
--- a/src/Client/languages/uk.ts
+++ b/src/Client/languages/uk.ts
@@ -1,6 +1,17 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!DOCTYPE TS>
 <TS version="2.1">
+<context>
+    <name>AbstractLvl::AbsLvlSnake</name>
+    <message>
+        <source>AbsLvlSnake</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>AbsLvlSnake Snake</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 <context>
     <name>AbstractLvl::AbsLvlWorld</name>
     <message>
diff --git a/src/Client/languages/zh.ts b/src/Client/languages/zh.ts
index e65072a..ff6a4b6 100644
--- a/src/Client/languages/zh.ts
+++ b/src/Client/languages/zh.ts
@@ -1,6 +1,17 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!DOCTYPE TS>
 <TS version="2.1">
+<context>
+    <name>AbstractLvl::AbsLvlSnake</name>
+    <message>
+        <source>AbsLvlSnake</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>AbsLvlSnake Snake</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
 <context>
     <name>AbstractLvl::AbsLvlWorld</name>
     <message>
diff --git a/src/Core/Crawl/clientapp.h b/src/Core/Crawl/clientapp.h
index 593a5c3..c697900 100644
--- a/src/Core/Crawl/clientapp.h
+++ b/src/Core/Crawl/clientapp.h
@@ -62,7 +62,7 @@ public:
         static_assert(std::is_base_of_v<ILevel, LevelType>,
                 "Plrease use the child classes of the ILevel interface for tegistering new levels in the crawl game.");
 
-        addLvl(LevelType().world());
+        addLvl(new LevelType());
     }
 
 private:
diff --git a/src/Core/CrawlModule/Crawl.qml b/src/Core/CrawlModule/Crawl.qml
index e68014d..c2e1d58 100644
--- a/src/Core/CrawlModule/Crawl.qml
+++ b/src/Core/CrawlModule/Crawl.qml
@@ -24,13 +24,13 @@ ApplicationWindow {
 
     Scene {
         id: scane;
-        model: (model)? model.world : null;
+        worldModel: (model)? model.world : null;
         anchors.fill: parent;
     }
 
     Scene {
         id: nest;
-        model: (model)? model.world : null;
+        worldModel: (model)? model.world : null;
         anchors.fill: parent;
     }
 
diff --git a/src/CrawlAbstractLvl/abstractlevel.cpp b/src/CrawlAbstractLvl/abstractlevel.cpp
index 5a5e7c9..c688db5 100644
--- a/src/CrawlAbstractLvl/abstractlevel.cpp
+++ b/src/CrawlAbstractLvl/abstractlevel.cpp
@@ -12,6 +12,5 @@ AbstractLevel::AbstractLevel() {
     initAbstractLvlResources();
 
     setWorld(new AbstractLvl::AbsLvlWorld());
-    setPreviewScane(new AbstractLvl::AbsLvlWorld());
 }
 
diff --git a/src/CrawlAbstractLvl/private/abslvlsnake.cpp b/src/CrawlAbstractLvl/private/abslvlsnake.cpp
index 7aa1338..8dc8a38 100644
--- a/src/CrawlAbstractLvl/private/abslvlsnake.cpp
+++ b/src/CrawlAbstractLvl/private/abslvlsnake.cpp
@@ -30,5 +30,30 @@ AbsLvlSnake::AbsLvlSnake(): Snake(AUTO_CLASS_NAME) {
     registerItemType<AbsLvlSnakeItem>();
 }
 
+QString AbsLvlSnake::itemTextId() const {
+    return "AbsLvlSnake";
+}
+
+QString AbsLvlSnake::itemName() const {
+    return tr("AbsLvlSnake");
+}
+
+QString AbsLvlSnake::description() const {
+    return tr("AbsLvlSnake Snake");
+
+}
+
+QString AbsLvlSnake::image() const {
+    return "";
+}
+
+int AbsLvlSnake::cost() const {
+    return 0;
+}
+
+int AbsLvlSnake::requiredTier() const {
+    return 0;
+}
+
 
 }
diff --git a/src/CrawlAbstractLvl/private/abslvlsnake.h b/src/CrawlAbstractLvl/private/abslvlsnake.h
index 73f3f66..db2c61d 100644
--- a/src/CrawlAbstractLvl/private/abslvlsnake.h
+++ b/src/CrawlAbstractLvl/private/abslvlsnake.h
@@ -19,6 +19,15 @@ class AbsLvlSnake : public CRAWL::Snake {
 public:
     AbsLvlSnake();
 
+
+    // IItem interface
+public:
+    QString itemTextId() const override;
+    QString itemName() const override;
+    QString description() const override;
+    QString image() const override;
+    int cost() const override;
+    int requiredTier() const override;
 };
 
 }
diff --git a/src/CrawlAbstractLvl/private/abslvlworld.cpp b/src/CrawlAbstractLvl/private/abslvlworld.cpp
index a6df278..5d36d6c 100644
--- a/src/CrawlAbstractLvl/private/abslvlworld.cpp
+++ b/src/CrawlAbstractLvl/private/abslvlworld.cpp
@@ -23,7 +23,7 @@ AbsLvlWorld::AbsLvlWorld() {
     setCameraRotation(QQuaternion::fromEulerAngles({0,0,0}));
 }
 
-CRAWL::PlayableObject *AbsLvlWorld::initPlayer() const {
+CRAWL::PlayableObject *AbsLvlWorld::initPlayer(int) const {
     return new AbsLvlSnake();
 }
 
diff --git a/src/CrawlAbstractLvl/private/abslvlworld.h b/src/CrawlAbstractLvl/private/abslvlworld.h
index 2f1d967..0927625 100644
--- a/src/CrawlAbstractLvl/private/abslvlworld.h
+++ b/src/CrawlAbstractLvl/private/abslvlworld.h
@@ -19,7 +19,7 @@ public:
 
     AbsLvlWorld();
 
-    CRAWL::PlayableObject *initPlayer() const override;
+    CRAWL::PlayableObject *initPlayer(int type) const override;
     CRAWL::WorldRule *initWorldRules() override;
     QString initHdrBackGround() const override;
     QString description() const override;
diff --git a/src/CrawlTestLvl/private/testsnake.cpp b/src/CrawlTestLvl/private/testsnake.cpp
index b1c1fc7..0b5affb 100644
--- a/src/CrawlTestLvl/private/testsnake.cpp
+++ b/src/CrawlTestLvl/private/testsnake.cpp
@@ -25,4 +25,28 @@ TestSnake::TestSnake(): Snake("Snake") {
 unsigned int TestSnake::itemsCount() const {
     return 50;
 }
+
+QString TestSnake::itemTextId() const {
+    return "TestSnake";
+}
+
+QString TestSnake::itemName() const {
+    return tr("TestSnake");
+}
+
+QString TestSnake::description() const {
+    return tr("TestSnake Snake");
+}
+
+QString TestSnake::image() const {
+    return "";
+}
+
+int TestSnake::cost() const {
+    return 0;
+}
+
+int TestSnake::requiredTier() const {
+    return 0;
+}
 }
diff --git a/src/CrawlTestLvl/private/testsnake.h b/src/CrawlTestLvl/private/testsnake.h
index 90d358e..846e550 100644
--- a/src/CrawlTestLvl/private/testsnake.h
+++ b/src/CrawlTestLvl/private/testsnake.h
@@ -23,6 +23,15 @@ public:
     // AutoGenerateClaster interface
 public:
     unsigned int itemsCount() const override;
+
+    // IItem interface
+public:
+    QString itemTextId() const override;
+    QString itemName() const override;
+    QString description() const override;
+    QString image() const override;
+    int cost() const override;
+    int requiredTier() const override;
 };
 
 }
diff --git a/src/CrawlTestLvl/private/world.cpp b/src/CrawlTestLvl/private/world.cpp
index 01400a3..7bf6964 100644
--- a/src/CrawlTestLvl/private/world.cpp
+++ b/src/CrawlTestLvl/private/world.cpp
@@ -73,7 +73,7 @@ void World::initControl(CRAWL::IControl *control) {
     return IWorld::initControl(control);
 }
 
-CRAWL::PlayableObject *World::initPlayer() const {
+CRAWL::PlayableObject *World::initPlayer(int) const {
     return new TestSnake();
 }
 
diff --git a/src/CrawlTestLvl/private/world.h b/src/CrawlTestLvl/private/world.h
index e94b136..e376fb0 100644
--- a/src/CrawlTestLvl/private/world.h
+++ b/src/CrawlTestLvl/private/world.h
@@ -28,7 +28,7 @@ public:
     int cost() const override;
     CRAWL::IControl *initUserInterface() const override;
     void initControl(CRAWL::IControl *control) override;
-    CRAWL::PlayableObject *initPlayer() const override;
+    CRAWL::PlayableObject *initPlayer(int type) const override;
     CRAWL::IAI *initBackGroundAI() const override;
     QString itemTextId() const override;
     int requiredTier() const override;
diff --git a/src/CrawlTestLvl/testlevel.cpp b/src/CrawlTestLvl/testlevel.cpp
index 32b15ac..fef833d 100644
--- a/src/CrawlTestLvl/testlevel.cpp
+++ b/src/CrawlTestLvl/testlevel.cpp
@@ -9,10 +9,6 @@
 #include "world.h"
 
 TestLevel::TestLevel() {
-
-}
-
-CRAWL::IWorld *TestLevel::world() {
     initTestLvlResources();
-    return new TestLvl::World();
+    setWorld(new TestLvl::World());
 }
diff --git a/src/CrawlTestLvl/testlevel.h b/src/CrawlTestLvl/testlevel.h
index 44c28c4..610152e 100644
--- a/src/CrawlTestLvl/testlevel.h
+++ b/src/CrawlTestLvl/testlevel.h
@@ -21,10 +21,6 @@ class CRAWL_TEST_LEVEL_EXPORT TestLevel: public CRAWL::ILevel
 {
 public:
     TestLevel();
-
-    // ILevel interface
-public:
-    CRAWL::IWorld *world() override;
 };
 
 #endif // TESTLVL_H
diff --git a/src/JungleLvl/jungle.cpp b/src/JungleLvl/jungle.cpp
index d2a1ea3..971b4b1 100644
--- a/src/JungleLvl/jungle.cpp
+++ b/src/JungleLvl/jungle.cpp
@@ -10,10 +10,7 @@
 #include "world.h"
 
 Jungle::Jungle() {
-
-}
-
-CRAWL::IWorld *Jungle::world() {
     initJungleLvlResources();
-    return new JungleLvl::World();
+
+    setWorld(new JungleLvl::World());
 }
diff --git a/src/JungleLvl/jungle.h b/src/JungleLvl/jungle.h
index 53040be..2e91e39 100644
--- a/src/JungleLvl/jungle.h
+++ b/src/JungleLvl/jungle.h
@@ -26,9 +26,6 @@ class CRAWL_JUNGLE_LEVEL_EXPORT Jungle: public CRAWL::ILevel
 public:
     Jungle();
 
-    // ILevel interface
-public:
-    CRAWL::IWorld *world() override;
 };
 
 #endif // JUNGLE_H
diff --git a/src/JungleLvl/private/snake.cpp b/src/JungleLvl/private/snake.cpp
index eacf1c1..150bd23 100644
--- a/src/JungleLvl/private/snake.cpp
+++ b/src/JungleLvl/private/snake.cpp
@@ -31,6 +31,30 @@ Snake::Snake(): CRAWL::Snake("JungleSnake") {
                              {1, 0.5}});
 }
 
+QString Snake::itemTextId() const {
+    return "JungleSnake";
+}
+
+QString Snake::itemName() const {
+    return tr("JungleSnake");
+}
+
+QString Snake::description() const {
+    return tr("JungleSnake Snake");;
+}
+
+QString Snake::image() const {
+    return "";
+}
+
+int Snake::cost() const {
+    return 0;
+}
+
+int Snake::requiredTier() const {
+    return 0;
+}
+
 unsigned int Snake::itemsCount() const {
     return 50;
 }
diff --git a/src/JungleLvl/private/snake.h b/src/JungleLvl/private/snake.h
index 3d49c0c..d45c228 100644
--- a/src/JungleLvl/private/snake.h
+++ b/src/JungleLvl/private/snake.h
@@ -23,11 +23,17 @@ class Snake: public CRAWL::Snake
 
 public:
     Snake();
-
+    QString itemTextId() const override;
+    QString itemName() const override;
+    QString description() const override;
+    QString image() const override;
+    int cost() const override;
+    int requiredTier() const override;
     // IWorldItem interface
 protected:
     unsigned int itemsCount() const override;
 
+
 };
 
 
diff --git a/src/JungleLvl/private/world.cpp b/src/JungleLvl/private/world.cpp
index b6f146c..7005a19 100644
--- a/src/JungleLvl/private/world.cpp
+++ b/src/JungleLvl/private/world.cpp
@@ -108,7 +108,7 @@ void World::initControl(CRAWL::IControl *control) {
     return IWorld::initControl(control);
 }
 
-CRAWL::PlayableObject *World::initPlayer() const {
+CRAWL::PlayableObject *World::initPlayer(int) const {
     return new Snake();
 }
 
diff --git a/src/JungleLvl/private/world.h b/src/JungleLvl/private/world.h
index e94f435..063a7e6 100644
--- a/src/JungleLvl/private/world.h
+++ b/src/JungleLvl/private/world.h
@@ -27,7 +27,7 @@ public:
     int cost() const override;
     CRAWL::IControl *initUserInterface() const override;
     void initControl(CRAWL::IControl *control) override;
-    CRAWL::PlayableObject *initPlayer() const override;
+    CRAWL::PlayableObject *initPlayer(int) const override;
     CRAWL::IAI *initBackGroundAI() const override;
     QString itemTextId() const override;
     int requiredTier() const override;
diff --git a/tests/units/clasterstest.cpp b/tests/units/clasterstest.cpp
index f341674..d9baa3a 100644
--- a/tests/units/clasterstest.cpp
+++ b/tests/units/clasterstest.cpp
@@ -45,7 +45,7 @@ public:
 
     // IWorld interface
 public:
-    CRAWL::PlayableObject *initPlayer() const override {return nullptr;};
+    CRAWL::PlayableObject *initPlayer(int) const override {return nullptr;};
     CRAWL::WorldRule *initWorldRules() override {return nullptr;};
     QString initHdrBackGround() const override {return "";};
     QString description() const override {return "";};