diff --git a/src/Client/languages/de.ts b/src/Client/languages/de.ts index 053544d..c7e0ac0 100644 --- a/src/Client/languages/de.ts +++ b/src/Client/languages/de.ts @@ -1,6 +1,17 @@ + + AbstractLvl::AbsLvlSnake + + AbsLvlSnake + + + + AbsLvlSnake Snake + + + AbstractLvl::AbsLvlWorld @@ -18,6 +29,10 @@ Crawl + + Please Select level. If level is not availabel please bue it first. + + DefaultMenu @@ -26,6 +41,17 @@ + + JungleLvl::Snake + + JungleSnake + + + + JungleSnake Snake + + + JungleLvl::World @@ -39,10 +65,6 @@ MainMenu - - Play game - - My Settings @@ -51,14 +73,29 @@ Exit + + Select level + + + + Store + + - SelectLvlView + PreviewControl Start + + SelectLevelView + + Select + + + SettingsView @@ -78,4 +115,22 @@ + + StoreView + + Buy + + + + + TestLvl::TestSnake + + TestSnake + + + + TestSnake Snake + + + diff --git a/src/Client/languages/en.ts b/src/Client/languages/en.ts index 948f1f9..cce6330 100644 --- a/src/Client/languages/en.ts +++ b/src/Client/languages/en.ts @@ -1,6 +1,17 @@ + + AbstractLvl::AbsLvlSnake + + AbsLvlSnake + + + + AbsLvlSnake Snake + + + AbstractLvl::AbsLvlWorld @@ -18,6 +29,10 @@ Crawl + + Please Select level. If level is not availabel please bue it first. + + DefaultMenu @@ -26,6 +41,17 @@ + + JungleLvl::Snake + + JungleSnake + + + + JungleSnake Snake + + + JungleLvl::World @@ -39,10 +65,6 @@ MainMenu - - Play game - - My Settings @@ -51,14 +73,29 @@ Exit + + Select level + + + + Store + + - SelectLvlView + PreviewControl Start + + SelectLevelView + + Select + + + SettingsView @@ -78,4 +115,22 @@ + + StoreView + + Buy + + + + + TestLvl::TestSnake + + TestSnake + + + + TestSnake Snake + + + diff --git a/src/Client/languages/es.ts b/src/Client/languages/es.ts index 726a274..ff74d90 100644 --- a/src/Client/languages/es.ts +++ b/src/Client/languages/es.ts @@ -1,6 +1,17 @@ + + AbstractLvl::AbsLvlSnake + + AbsLvlSnake + + + + AbsLvlSnake Snake + + + AbstractLvl::AbsLvlWorld @@ -18,6 +29,10 @@ Crawl + + Please Select level. If level is not availabel please bue it first. + + DefaultMenu @@ -26,6 +41,17 @@ + + JungleLvl::Snake + + JungleSnake + + + + JungleSnake Snake + + + JungleLvl::World @@ -39,10 +65,6 @@ MainMenu - - Play game - - My Settings @@ -51,14 +73,29 @@ Exit + + Select level + + + + Store + + - SelectLvlView + PreviewControl Start + + SelectLevelView + + Select + + + SettingsView @@ -78,4 +115,22 @@ + + StoreView + + Buy + + + + + TestLvl::TestSnake + + TestSnake + + + + TestSnake Snake + + + diff --git a/src/Client/languages/fr.ts b/src/Client/languages/fr.ts index 948f1f9..cce6330 100644 --- a/src/Client/languages/fr.ts +++ b/src/Client/languages/fr.ts @@ -1,6 +1,17 @@ + + AbstractLvl::AbsLvlSnake + + AbsLvlSnake + + + + AbsLvlSnake Snake + + + AbstractLvl::AbsLvlWorld @@ -18,6 +29,10 @@ Crawl + + Please Select level. If level is not availabel please bue it first. + + DefaultMenu @@ -26,6 +41,17 @@ + + JungleLvl::Snake + + JungleSnake + + + + JungleSnake Snake + + + JungleLvl::World @@ -39,10 +65,6 @@ MainMenu - - Play game - - My Settings @@ -51,14 +73,29 @@ Exit + + Select level + + + + Store + + - SelectLvlView + PreviewControl Start + + SelectLevelView + + Select + + + SettingsView @@ -78,4 +115,22 @@ + + StoreView + + Buy + + + + + TestLvl::TestSnake + + TestSnake + + + + TestSnake Snake + + + diff --git a/src/Client/languages/ja.ts b/src/Client/languages/ja.ts index 948f1f9..cce6330 100644 --- a/src/Client/languages/ja.ts +++ b/src/Client/languages/ja.ts @@ -1,6 +1,17 @@ + + AbstractLvl::AbsLvlSnake + + AbsLvlSnake + + + + AbsLvlSnake Snake + + + AbstractLvl::AbsLvlWorld @@ -18,6 +29,10 @@ Crawl + + Please Select level. If level is not availabel please bue it first. + + DefaultMenu @@ -26,6 +41,17 @@ + + JungleLvl::Snake + + JungleSnake + + + + JungleSnake Snake + + + JungleLvl::World @@ -39,10 +65,6 @@ MainMenu - - Play game - - My Settings @@ -51,14 +73,29 @@ Exit + + Select level + + + + Store + + - SelectLvlView + PreviewControl Start + + SelectLevelView + + Select + + + SettingsView @@ -78,4 +115,22 @@ + + StoreView + + Buy + + + + + TestLvl::TestSnake + + TestSnake + + + + TestSnake Snake + + + diff --git a/src/Client/languages/pl.ts b/src/Client/languages/pl.ts index 948f1f9..cce6330 100644 --- a/src/Client/languages/pl.ts +++ b/src/Client/languages/pl.ts @@ -1,6 +1,17 @@ + + AbstractLvl::AbsLvlSnake + + AbsLvlSnake + + + + AbsLvlSnake Snake + + + AbstractLvl::AbsLvlWorld @@ -18,6 +29,10 @@ Crawl + + Please Select level. If level is not availabel please bue it first. + + DefaultMenu @@ -26,6 +41,17 @@ + + JungleLvl::Snake + + JungleSnake + + + + JungleSnake Snake + + + JungleLvl::World @@ -39,10 +65,6 @@ MainMenu - - Play game - - My Settings @@ -51,14 +73,29 @@ Exit + + Select level + + + + Store + + - SelectLvlView + PreviewControl Start + + SelectLevelView + + Select + + + SettingsView @@ -78,4 +115,22 @@ + + StoreView + + Buy + + + + + TestLvl::TestSnake + + TestSnake + + + + TestSnake Snake + + + diff --git a/src/Client/languages/ru.ts b/src/Client/languages/ru.ts index 948f1f9..cce6330 100644 --- a/src/Client/languages/ru.ts +++ b/src/Client/languages/ru.ts @@ -1,6 +1,17 @@ + + AbstractLvl::AbsLvlSnake + + AbsLvlSnake + + + + AbsLvlSnake Snake + + + AbstractLvl::AbsLvlWorld @@ -18,6 +29,10 @@ Crawl + + Please Select level. If level is not availabel please bue it first. + + DefaultMenu @@ -26,6 +41,17 @@ + + JungleLvl::Snake + + JungleSnake + + + + JungleSnake Snake + + + JungleLvl::World @@ -39,10 +65,6 @@ MainMenu - - Play game - - My Settings @@ -51,14 +73,29 @@ Exit + + Select level + + + + Store + + - SelectLvlView + PreviewControl Start + + SelectLevelView + + Select + + + SettingsView @@ -78,4 +115,22 @@ + + StoreView + + Buy + + + + + TestLvl::TestSnake + + TestSnake + + + + TestSnake Snake + + + diff --git a/src/Client/languages/tr.ts b/src/Client/languages/tr.ts index 948f1f9..cce6330 100644 --- a/src/Client/languages/tr.ts +++ b/src/Client/languages/tr.ts @@ -1,6 +1,17 @@ + + AbstractLvl::AbsLvlSnake + + AbsLvlSnake + + + + AbsLvlSnake Snake + + + AbstractLvl::AbsLvlWorld @@ -18,6 +29,10 @@ Crawl + + Please Select level. If level is not availabel please bue it first. + + DefaultMenu @@ -26,6 +41,17 @@ + + JungleLvl::Snake + + JungleSnake + + + + JungleSnake Snake + + + JungleLvl::World @@ -39,10 +65,6 @@ MainMenu - - Play game - - My Settings @@ -51,14 +73,29 @@ Exit + + Select level + + + + Store + + - SelectLvlView + PreviewControl Start + + SelectLevelView + + Select + + + SettingsView @@ -78,4 +115,22 @@ + + StoreView + + Buy + + + + + TestLvl::TestSnake + + TestSnake + + + + TestSnake Snake + + + diff --git a/src/Client/languages/uk.ts b/src/Client/languages/uk.ts index 948f1f9..cce6330 100644 --- a/src/Client/languages/uk.ts +++ b/src/Client/languages/uk.ts @@ -1,6 +1,17 @@ + + AbstractLvl::AbsLvlSnake + + AbsLvlSnake + + + + AbsLvlSnake Snake + + + AbstractLvl::AbsLvlWorld @@ -18,6 +29,10 @@ Crawl + + Please Select level. If level is not availabel please bue it first. + + DefaultMenu @@ -26,6 +41,17 @@ + + JungleLvl::Snake + + JungleSnake + + + + JungleSnake Snake + + + JungleLvl::World @@ -39,10 +65,6 @@ MainMenu - - Play game - - My Settings @@ -51,14 +73,29 @@ Exit + + Select level + + + + Store + + - SelectLvlView + PreviewControl Start + + SelectLevelView + + Select + + + SettingsView @@ -78,4 +115,22 @@ + + StoreView + + Buy + + + + + TestLvl::TestSnake + + TestSnake + + + + TestSnake Snake + + + diff --git a/src/Client/languages/zh.ts b/src/Client/languages/zh.ts index 948f1f9..cce6330 100644 --- a/src/Client/languages/zh.ts +++ b/src/Client/languages/zh.ts @@ -1,6 +1,17 @@ + + AbstractLvl::AbsLvlSnake + + AbsLvlSnake + + + + AbsLvlSnake Snake + + + AbstractLvl::AbsLvlWorld @@ -18,6 +29,10 @@ Crawl + + Please Select level. If level is not availabel please bue it first. + + DefaultMenu @@ -26,6 +41,17 @@ + + JungleLvl::Snake + + JungleSnake + + + + JungleSnake Snake + + + JungleLvl::World @@ -39,10 +65,6 @@ MainMenu - - Play game - - My Settings @@ -51,14 +73,29 @@ Exit + + Select level + + + + Store + + - SelectLvlView + PreviewControl Start + + SelectLevelView + + Select + + + SettingsView @@ -78,4 +115,22 @@ + + StoreView + + Buy + + + + + TestLvl::TestSnake + + TestSnake + + + + TestSnake Snake + + + diff --git a/src/Core/Crawl.qrc b/src/Core/Crawl.qrc index b3644af..8e8c34d 100644 --- a/src/Core/Crawl.qrc +++ b/src/Core/Crawl.qrc @@ -10,7 +10,6 @@ CrawlModule/Scene.qml CrawlModule/SettingsView.qml CrawlModule/SnakeItem.qml - CrawlModule/SelectLvlView.qml CrawlModule/DefaultMenu.qml CrawlModule/AbstractMenuView.qml CrawlModule/Light.qml @@ -24,5 +23,8 @@ CrawlCoreAssets/particles/smokeSprite.png CrawlModule/particles/Fire.qml CrawlModule/particles/Wint.qml + CrawlModule/PreviewControl.qml + CrawlModule/StoreView.qml + CrawlModule/SelectLevelView.qml diff --git a/src/Core/Crawl/clientapp.cpp b/src/Core/Crawl/clientapp.cpp index 77d11d7..c2c1b8f 100644 --- a/src/Core/Crawl/clientapp.cpp +++ b/src/Core/Crawl/clientapp.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -22,6 +23,7 @@ #include "pluginloader.h" #include #include "worldstatus.h" +#include "user.h" namespace CRAWL { @@ -35,52 +37,13 @@ QByteArray ClientApp::initTheme() { } } + ClientApp::ClientApp() { _engine = new Engine(); - _menu = new MainMenuModel(); - - connect(_menu, &MainMenuModel::sigNewGame, this, &ClientApp::start); } ClientApp::~ClientApp() { - delete _menu; delete _engine; - - for (auto it = _availableLvls.begin(); it != _availableLvls.end(); ++it) { - delete it.value().viewModel; - delete it.value().model; - } - - _availableLvls.clear(); -} - -IWorld *ClientApp::getLastWorld() { - for (const auto &data : qAsConst(_availableLvls)) { - if (data.viewModel && data.viewModel->unlocked()) { - return data.model; - } - } - - return nullptr; -} - -void ClientApp::start(const QString &lvl) { - WordlData data = _availableLvls.value(lvl); - - if (!data.model) { - QuasarAppUtils::Params::log("Failed to start lvl.", QuasarAppUtils::Error); - return; - } - - if (!_engine) { - QuasarAppUtils::Params::log("Failed to start lvl, Engine not initialized.", - QuasarAppUtils::Error); - - return; - } - - _engine->setWorld(data.model); - _engine->start(); } bool ClientApp::init(QQmlApplicationEngine *engine) { @@ -95,7 +58,6 @@ bool ClientApp::init(QQmlApplicationEngine *engine) { engine->addImageProvider(QLatin1String("userItems"), new ImageProvider()); root->setContextProperty("engine", QVariant::fromValue(_engine)); - root->setContextProperty("mainmenu", QVariant::fromValue(_menu)); qmlRegisterUncreatableMetaObject( WorldStatus::staticMetaObject, @@ -121,19 +83,13 @@ bool ClientApp::init(QQmlApplicationEngine *engine) { if (engine->rootObjects().isEmpty()) return false; - _engine->setWorld(getLastWorld()); - _engine->setQmlEngine(engine); + _engine->init(); return true; } -void ClientApp::addLvl(IWorld *levelWordl) { - WordlData data; - - data.model = levelWordl; - data.viewModel = new WorldViewData(data.model); - _availableLvls.insert(data.model->name(), data); - _menu->addWorldViewModel(data.viewModel); +void ClientApp::addLvl(ILevel *levelWordl) { + _engine->addLvl(levelWordl); } } diff --git a/src/Core/Crawl/clientapp.h b/src/Core/Crawl/clientapp.h index 184e7ab..8880bac 100644 --- a/src/Core/Crawl/clientapp.h +++ b/src/Core/Crawl/clientapp.h @@ -22,18 +22,9 @@ namespace CRAWL { class Engine; class IWorld; -class WorldViewData; class MainMenuModel; class IControl; - - -/** - * @brief The WordlData struct simple structure that contains information about world. - */ -struct WordlData { - WorldViewData* viewModel = nullptr; - IWorld * model = nullptr; -}; +class Store; /** * @brief The ClientApp class This is main class of the Game engine. @@ -62,28 +53,20 @@ public: static_assert(std::is_base_of_v, "Plrease use the child classes of the ILevel interface for tegistering new levels in the crawl game."); - addLvl(LevelType().world()); + addLvl(new LevelType()); } private: QByteArray initTheme(); - IWorld* getLastWorld(); /** * @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 - * @param lvl This is lvl name - */ - void start(const QString& lvl); - - QHash _availableLvls; - MainMenuModel *_menu = nullptr; Engine *_engine = nullptr; + }; } 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/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/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/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 ef14381..9f5cd10 100644 --- a/src/Core/Crawl/icontrol.h +++ b/src/Core/Crawl/icontrol.h @@ -41,19 +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 new file mode 100644 index 0000000..b16e11b --- /dev/null +++ b/src/Core/Crawl/iitem.cpp @@ -0,0 +1,91 @@ +//# +//# 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 + +namespace CRAWL { + +IItem::IItem() { + +} + +const QHash& IItem::childItems() const { + return _childs; +} + +QMultiHash IItem::childItemsRecursive() const { + QMultiHash result; + + for (const IItem* item : _childs) { + result.unite(item->childItemsRecursive()); + } + + result.insert(itemId(), this); + return result; +} + +void IItem::addChildItem(const IItem *item) { + _childs.insert(item->itemId(), item); +} + +unsigned int IItem::itemId() { + if (_id) { + return _id; + } + + _id = qHash(itemTextId()); + return _id; +} + +unsigned int IItem::itemId() const { + if (_id) { + return _id; + } + + return qHash(itemTextId()); +} + +const QSet &IItem::activeItems() const { + return _activeItems; +} + +void IItem::setActiveItems(const QSet &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); +} + +unsigned int IItem::itemType() { + if (_typeItem) { + return _typeItem; + } + + _typeItem = qHash(itemTextType()); + return _typeItem; +} + +unsigned int IItem::itemType() const { + if (_typeItem) { + return _typeItem; + } + + return qHash(itemTextType()); +} + +} diff --git a/src/Core/Crawl/iitem.h b/src/Core/Crawl/iitem.h new file mode 100644 index 0000000..cd7b98c --- /dev/null +++ b/src/Core/Crawl/iitem.h @@ -0,0 +1,191 @@ +//# +//# 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 +#include +#include +#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(); + virtual ~IItem() = default; + + /** + * @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 itemTextType This method return text of the item group or type. + * @return text of the item group of type. + * @see IITem::itemType + */ + virtual QString itemTextType() 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 requiredTier This method return requried level to unlock. + * @return requried level to unlock. + */ + 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 + */ + const QHash &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 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. + * @see 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. + * @see IItem::itemTextId + * @warning This method not cached id value, so works sloyle then not cons implementation. + */ + unsigned int itemId() const; + + /** + * @brief itemType This method return item type id. (items group) + * @return item type id. + * @see IItem::itemTextType + * @note The not const implementation inlike const implementation write a id to cache. + */ + unsigned int itemType(); + + /** + * @brief itemType This method return item type id. (items group) + * @return item type id. + * @see IItem::itemTextType + * @warning This method not cached id value, so works sloyle then not cons implementation. + */ + unsigned int itemType() 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 &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 &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; + unsigned int _typeItem = 0; + QHash _childs; + QSet _activeItems; + +}; + +} +#endif // IITEM_H diff --git a/src/Core/Crawl/ilevel.cpp b/src/Core/Crawl/ilevel.cpp index 33bb3c3..7fdf80f 100644 --- a/src/Core/Crawl/ilevel.cpp +++ b/src/Core/Crawl/ilevel.cpp @@ -5,4 +5,36 @@ //# of this license document, but changing it is not allowed. //# +#include "iitem.h" #include "ilevel.h" +#include "ipreviewscaneworld.h" + +namespace CRAWL { + +ILevel::~ILevel() { + delete _world; + delete _previewScane; +} + +IWorld *ILevel::world() { + return _world; +} + +IPreviewScaneWorld *ILevel::previewScane() { + return _previewScane; +} + +void ILevel::reset() { + _world->reset(); + _previewScane->reset(); +} + +void ILevel::setWorld(IWorld *newWorld) { + _world = newWorld; +} + +void ILevel::setPreviewScane(IPreviewScaneWorld *newPreviewScane) { + _previewScane = newPreviewScane; +} + +} diff --git a/src/Core/Crawl/ilevel.h b/src/Core/Crawl/ilevel.h index 5cad4c6..bc21c36 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 + #ifndef LEVEL_H #define LEVEL_H @@ -12,22 +14,60 @@ namespace CRAWL { class IWorld; +class IItem; +class IPreviewScaneWorld; /** * @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 + */ + IPreviewScaneWorld* previewScane(); + + /** + * @brief reset This method unload all loaded data from level. + */ + void reset(); + +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(IPreviewScaneWorld *newPreviewScane); + +private: + + IWorld* _world = nullptr; + IPreviewScaneWorld* _previewScane = nullptr; }; } diff --git a/src/Core/Crawl/ipreviewscaneworld.cpp b/src/Core/Crawl/ipreviewscaneworld.cpp new file mode 100644 index 0000000..87fdb27 --- /dev/null +++ b/src/Core/Crawl/ipreviewscaneworld.cpp @@ -0,0 +1,113 @@ +//# +//# 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" +#include "previewcontrol.h" + +namespace CRAWL { + +IPreviewScaneWorld::IPreviewScaneWorld(const IWorld* mainWorld) { + debug_assert(mainWorld, "The mainWorld world option should be initialized."); + _mainWorld = mainWorld; + + setCameraReleativePosition({0, 100, 100}); + setCameraRotation(QQuaternion::fromEulerAngles(-40,0,0)); +} + +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; +} + +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); + setVisible(true); + startRenderLoop(); + + return true; +} + +bool IPreviewScaneWorld::stop() { + stopRenderLoopWithClearItems(); + setVisible(false); + + return true; +} + +void IPreviewScaneWorld::handleRotation(double x, double y) { + auto rotation = cameraRotation() * QQuaternion::fromEulerAngles(x, y, 0); + auto normal = (rotation * QVector3D{0,0,1}).normalized(); + + setCameraReleativePosition(normal * 100); + setCameraRotation(rotation); +} + +void IPreviewScaneWorld::handleStart() { + auto playerObj = dynamic_cast(player()); + _configuration.setSnakePerks(playerObj->activeItems()); + emit sigPrepareIsFinished(_configuration); + stop(); +} + +void IPreviewScaneWorld::handleSelect(int item, bool isSelected) { + auto playerItem = dynamic_cast(player()); + + if (isSelected) { + playerItem->activate(item); + } else { + playerItem->deactivate(item); + } +} + +const StartData &IPreviewScaneWorld::configuration() const { + return _configuration; +} + +void IPreviewScaneWorld::initControl(IControl *control) { + auto controlObject = dynamic_cast(control); + + if (controlObject) { + 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 new file mode 100644 index 0000000..afedd26 --- /dev/null +++ b/src/Core/Crawl/ipreviewscaneworld.h @@ -0,0 +1,65 @@ +//# +//# 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 +{ + Q_OBJECT +public: + /** + * @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: + 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; + 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; + + const StartData &configuration() const; + +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 handleRotation(double x, double y); + void handleStart(); + void handleSelect(int item, bool isSelected); + +private: + StartData _configuration; + const IWorld* _mainWorld; + + +}; + +} +#endif // IPREVIEWSCANEWORLD_H diff --git a/src/Core/Crawl/iworld.cpp b/src/Core/Crawl/iworld.cpp index 61df549..0aed561 100644 --- a/src/Core/Crawl/iworld.cpp +++ b/src/Core/Crawl/iworld.cpp @@ -19,6 +19,9 @@ #include "thread" #include "chrono" #include "diff.h" +#include "eventserver.h" +#include "player.h" +#include namespace CRAWL { @@ -26,13 +29,34 @@ namespace CRAWL { IWorld::IWorld() { qRegisterMetaType("WorldRule::const_iterator"); connect(this, &IWorld::sigWorldChanged, this, &IWorld::worldChanged, Qt::QueuedConnection); + + _eventServer = new EventServer(this); + + connect(_eventServer, &EventServer::sigIntersect, this, &IWorld::onIntersects); + connect(this, &IWorld::sigOBjctsListChanged, _eventServer, &EventServer::handleAvailableObjectChanges); + } IWorld::~IWorld() { + disconnect(); reset(); + delete _eventServer; } -void IWorld::init() {prepare();} +QString IWorld::itemTextType() const { + return IWorld::typeText(); +} + +unsigned int IWorld::type() { + return qHash(IWorld::typeText()); +} + +QString IWorld::typeText() { + return "WorldObject"; +} + +void IWorld::init() { +} IControl *IWorld::initUserInterface() const { return new DefaultControl; @@ -40,32 +64,33 @@ IControl *IWorld::initUserInterface() const { void IWorld::render(unsigned int tbfMsec) { - if (!_running) { - std::this_thread::sleep_for(std::chrono::milliseconds(1000)); - return; - } - _ItemsMutex.lock(); - + QList toRemove; for (auto i = _items.begin(); i != _items.end(); ++i) { - (*i)->render(tbfMsec); + if ((*i)->destroyIsScheduled()) + toRemove.push_back((*i)->guiId()); - // intersects event. - if ((*i)->intersects(*_player)) { - _player->onIntersects((*i)); - } + (*i)->render(tbfMsec); } _ItemsMutex.unlock(); + for (int id: toRemove) { + if (id == static_cast(player())->guiId()) { + playerIsDead(static_cast(player())); + } + + removeItem(id); + } + updateWorld(); - int waitTime = 1000 / _targetFps - tbfMsec; + int waitTime = 1000 / targetFps() - tbfMsec; if (waitTime > 0) std::this_thread::sleep_for(std::chrono::milliseconds(waitTime)); } -void IWorld::initPlayerControl(IControl *control) { +void IWorld::initControl(IControl *control) { auto controlObject = dynamic_cast(control); if (controlObject) { @@ -73,17 +98,28 @@ void IWorld::initPlayerControl(IControl *control) { } } -bool IWorld::start() { - _player->setposition({0,0,0}); +bool IWorld::start(const StartData& config) { + + auto player = dynamic_cast(userInterface()); + if (!player) { + QuasarAppUtils::Params::log("Failed to start world. T userIterface control should be children class of the Palyer class", + QuasarAppUtils::Error); + + return false; + } setWorldStatus(WorldStatus::Game); - _backgroundAI->stopAI(); - _player->setControl(_userInterface); + backgroundAI()->stopAI(); + setPlayer(initPlayer(config.snakeType())); + player->setUserData(config.player()); - worldChanged(_worldRules->cbegin()); + worldChanged(worldRules()->cbegin()); setTargetFps(60); - setRunning(true); + _eventServer->start(); + setVisible(true); + + startRenderLoop(); return true; } @@ -107,6 +143,9 @@ void IWorld::setPlayer(QObject *newPlayer) { removeItem(_player->guiId()); _player = newPlayerObject; + _player->setposition({0,0,0}); + _player->setControl(userInterface()); + addItem(_player); emit playerChanged(); @@ -117,7 +156,12 @@ IWorldItem *IWorld::generate(const QString &objectType) const { } bool IWorld::stop() { - setRunning(false); + _eventServer->stop(); + + stopRenderLoopWithClearItems(); + setVisible(false); + + emit sigGameFinished(); return true; } @@ -131,38 +175,7 @@ IWorldItem *IWorld::getItem(int id) const { return _items.value(id, nullptr); } -bool IWorld::prepare() { - - if (isInit()) - return true; - - _worldRules = initWorldRules(); - - setHdr(initHdrBackGround()); - setPlayer(initPlayer()); - _player->initOnWorld(this, _player); - _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(_backgroundAI)); - - return true; -} - void IWorld::clearItems() { - stop(); while (_items.cbegin() != _items.cend()) { removeItem(*_items.cbegin()); @@ -237,6 +250,8 @@ void IWorld::removeItem(IWorldItem* item, QList *removedObjectsList) { void IWorld::reset() { + stop(); + if (_player) { _player = nullptr; } @@ -256,7 +271,6 @@ void IWorld::reset() { _backgroundAI = nullptr; } - clearItems(); setHdr(""); } @@ -271,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) { @@ -312,12 +326,63 @@ void IWorld::removeAnyItemFromGroup(const QString &group, removeItem(anyObjectId, removedObjectsList); } -bool IWorld::running() const { - return _running; +void IWorld::startRenderLoop() { + if (isRendering()) + return; + + _renderLoop = true; + _renderLoopFuture = QtConcurrent::run([this](){renderLoop();}); } -void IWorld::setRunning(bool newRunning) { - _running = newRunning; +void IWorld::stopRenderLoopWithClearItems() { + stopRenderLoop(); + clearItems(); +} + +void IWorld::stopRenderLoop() { + _renderLoop = false; + _renderLoopFuture.waitForFinished(); +} + +bool IWorld::isRendering() const { + return _renderLoopFuture.isRunning(); +} + +void IWorld::renderLoop() { + + while (_renderLoop) { + + quint64 currentTime = QDateTime::currentMSecsSinceEpoch(); + + if (!_oldTimeRender) { + _oldTimeRender = currentTime; + continue; + } + + render(currentTime - _oldTimeRender); + _oldTimeRender = currentTime; + } +} + +const WorldRule *IWorld::worldRules() { + + if (!_worldRules) + _worldRules = initWorldRules(); + + return _worldRules; +} + +void IWorld::setVisible(bool visible) { + if (_visible == visible) { + return; + } + + _visible = visible; + emit visibleChanged(); +} + +void IWorld::playerIsDead(PlayableObject *) { + stop(); } int IWorld::targetFps() const { @@ -338,7 +403,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(); @@ -348,6 +413,13 @@ void IWorld::updateWorld() { } } +void IWorld::onIntersects(const IWorldItem *trigger, QList list) { + + for (const IWorldItem* item : list) { + const_cast(item)->action(const_cast(trigger)); + } +} + const QQuaternion &IWorld::cameraRotation() const { return _cameraRotation; } @@ -359,16 +431,24 @@ void IWorld::setCameraRotation(const QQuaternion &newCameraRotation) { emit cameraRotationChanged(); } -IAI *IWorld::backgroundAI() const { +IAI *IWorld::backgroundAI() { + + if (!_backgroundAI) { + _backgroundAI = initBackGroundAI(); + initControl(dynamic_cast(_backgroundAI)); + } + return _backgroundAI; } -IControl *IWorld::userInterface() const { - return _userInterface; -} +IControl *IWorld::userInterface() { -bool IWorld::isInit() const { - return _userInterface && _player && _worldRules && _backgroundAI; + if (!_userInterface) { + _userInterface = initUserInterface(); + initControl(_userInterface); + } + + return _userInterface; } void IWorld::setCameraReleativePosition(const QVector3D &newCameraReleativePosition) { @@ -380,7 +460,7 @@ void IWorld::setCameraReleativePosition(const QVector3D &newCameraReleativePosit } void IWorld::handleStop() { - runAsBackGround(); + stop(); } const QVector3D &IWorld::cameraReleativePosition() const { @@ -426,12 +506,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(_backgroundAI)); @@ -441,4 +525,12 @@ void IWorld::runAsBackGround() { setTargetFps(30); } +QObject *IWorld::getMenu() { + return userInterface(); +} + +bool IWorld::visible() const { + return _visible; +} + } diff --git a/src/Core/Crawl/iworld.h b/src/Core/Crawl/iworld.h index 6f8a433..30e97e8 100644 --- a/src/Core/Crawl/iworld.h +++ b/src/Core/Crawl/iworld.h @@ -9,8 +9,11 @@ #define CRAWL_IWORLD_H #include "gameresult.h" +#include "iitem.h" #include "playableobject.h" +#include "startdata.h" +#include #include #include #include @@ -26,12 +29,22 @@ 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; 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. @@ -46,13 +59,21 @@ typedef QMap 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) 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::getMenu + * @see IWorld::userInterface + */ + Q_PROPERTY(QObject * menu READ getMenu 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) @@ -60,15 +81,32 @@ public: IWorld(); ~IWorld() override; + QString itemTextType() const override; + + /** + * @brief type This method return const string value of the all world types. + * @return const string value of the all world types. + * @see IItem::itemTextType + * @see IItem::type + */ + static QString typeText(); + + /** + * @brief type This is wrapper of the IWorld::typeText method that invoke the qHash function for results string. + * @return integer type object id. + */ + static unsigned int type(); + 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. @@ -100,7 +138,7 @@ public: * @note The base implementation return default user interface. * @return pointer to userInterface. */ - virtual IControl* initUserInterface() const; + virtual IControl *initUserInterface() const; /** * @brief initHdrBackGround The implementation of this method must be return valid path to the hdr image map. @@ -109,30 +147,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. @@ -140,18 +154,19 @@ public: virtual void render(unsigned int tbfMsec) override; /** - * @brief initPlayerControl This method should be configure all connections of @a control object. - * @brief control This is 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. + * @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. @@ -172,7 +187,7 @@ public: * @return pointe to requaried object. * @note if you want to get ovject in the render function of another ItemWorld object then use the IWorldItem::getItem method. */ - IWorldItem *getItem(int id) const; + Q_INVOKABLE IWorldItem *getItem(int id) const; /** * @brief cameraReleativePosition return a releative of player camera position. @@ -184,13 +199,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; + IControl *userInterface(); /** * @brief wordlStatus This method return current world status. @@ -208,7 +217,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. @@ -226,7 +235,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. @@ -234,12 +243,30 @@ 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::menu + * @see IWorld::userInterface + */ + QObject *getMenu(); + + /** + * @brief reset This method reset all world objects. + */ + 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. @@ -285,6 +312,16 @@ signals: */ void sigWorldChanged(WorldRule::const_iterator objects); + /** + * @brief menuChanged This signal emited when user interface is changed. + */ + void menuChanged(); + + /** + * @brief visibleChanged This signal emited when visible of the view changed. + */ + void visibleChanged(); + protected: /** @@ -383,12 +420,53 @@ protected: */ void updateWorld(); -private slots: + /** + * @brief worldRules This method return world cure map. + * @return world rule map. + */ + const WorldRule *worldRules(); /** - * @brief handleStop This slot invoked when user click return main menu button. + * @brief setVisible This method sets visible propertye for the qml view. + * @param visible This is new value of a property */ - void handleStop(); + void setVisible(bool visible); + + /** + * @brief playerIsDead This method will be invoked when player object get signal dead. + */ + virtual void playerIsDead(PlayableObject*); + + /** + * @brief isRendering This method erturn true if the render loop is working else false. + * @return true if the render loop is working else false. + * @see IWorld::stopRenderLoop + * @see IWorld::startRenderLoop + */ + bool isRendering() const; + + /** + * @brief stopRenderLoop This method stop render loop in engine. + * @see IWorld::isRendering + * @see IWorld::startRenderLoop + */ + void stopRenderLoop(); + + /** + * @brief startRenderLoop This method start render loop in engine. + * @see IWorld::stopRenderLoop + * @see IWorld::isRendering + */ + void startRenderLoop(); + + /** + * @brief stopRenderLoopWithClearItems This method stoped render loop and clear all created items. + * @see IWorld::stopRenderLoop + */ + void stopRenderLoopWithClearItems(); + +protected slots: + virtual void onIntersects(const IWorldItem * trigger, QList list); /** * @brief worldChanged This method generate diff for the qml @@ -397,32 +475,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. */ @@ -482,6 +542,11 @@ private: void removeAnyItemFromGroup(const QString &group, QList* removedObjectsList = nullptr); + void renderLoop(); + QFuture _renderLoopFuture; + + EventServer * _eventServer = nullptr; + QHash _items; QMultiHash _itemsGroup; QMultiHash _lastItemsGroup; @@ -496,19 +561,21 @@ private: WorldRule::const_iterator _currendWorldLevel; PlayableObject *_player = nullptr; - IControl *_userInterface = nullptr; IAI *_backgroundAI = nullptr; + IControl *_userInterface = nullptr; + int _worldStatus = 0; QHash> _registeredTypes; int _targetFps = 60; - bool _running = false; + quint64 _oldTimeRender = 0; - // engine - friend class Engine; + bool _visible = true; + bool _renderLoop = false; // testing friend ClastersTest; + }; } diff --git a/src/Core/Crawl/iworlditem.cpp b/src/Core/Crawl/iworlditem.cpp index da37964..d08a21d 100644 --- a/src/Core/Crawl/iworlditem.cpp +++ b/src/Core/Crawl/iworlditem.cpp @@ -30,30 +30,93 @@ const IWorldItem *IWorldItem::getItem(int id) const { } const IWorldItem *IWorldItem::getPlayer() const { - return _playerObject; + if (!_world) + return nullptr; + return static_cast(_world->player()); } void IWorldItem::render(unsigned int) { + auto _playerObject = getPlayer(); + + if (!_playerObject) + return; + + if (_fFirstRenderIteration) { + firstSpawn(); + _fFirstRenderIteration = false; + } + if (_playerObject->position().distanceToPoint(position()) > _world->cameraReleativePosition().z() * 3) { - - float dX = _world->cameraReleativePosition().z() * 2 + - (rand() % static_cast(_world->cameraReleativePosition().z())); - - setX(_playerObject->position().x() + dX); - - float dY = (rand() % static_cast(_world->cameraReleativePosition().z() * 3) - - _world->cameraReleativePosition().z() * 1.5); - - setY(_playerObject->position().y() + dY); + respawn(); } } 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 { + return _supportedEvents; +} + +bool IWorldItem::isSopportEvent(int event) const { + return (_supportedEvents & event) == event; +} + +void IWorldItem::destroy() { + _fDistroy = true; +} + +void IWorldItem::respawn() { + auto _playerObject = getPlayer(); + + if (!_playerObject) + return; + + float dX = _world->cameraReleativePosition().z() * 2 + + (rand() % static_cast(_world->cameraReleativePosition().z())); + + setX(_playerObject->position().x() + dX); + + float dY = (rand() % static_cast(_world->cameraReleativePosition().z() * 3) + - _world->cameraReleativePosition().z() * 1.5); + + setY(_playerObject->position().y() + dY); +} + +void IWorldItem::firstSpawn() { + +} + +bool IWorldItem::destroyIsScheduled() const { + return _fDistroy; +} + +void IWorldItem::action(IWorldItem *) { + +} + +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 { + return _fDecorative; +} + +void IWorldItem::setFDecorative(bool newFDecorative) { + _fDecorative = newFDecorative; } const IWorld *IWorldItem::world() const { diff --git a/src/Core/Crawl/iworlditem.h b/src/Core/Crawl/iworlditem.h index 0e2c9c9..e069165 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,13 +35,61 @@ public: void render(unsigned int tbfMsec) override; void init() override; -protected: + /** + * @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 onIntersects This is intersect event betwin this and subscribet objects. - * @param item This is pointer to the event object. + * @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 */ - virtual void onIntersects(const IWorldItem *item) = 0; + 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; + + /** + * @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 firstSpawn This method is respawn this object on the world when it created. By Default this method do nothing. + */ + virtual void firstSpawn(); + + /** + * @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; + + /** + * @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: /** * @brief getItem This method return item world by id. If object is not exits then return nullptr. @@ -56,13 +103,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); + void initOnWorld(const IWorld* world); const IWorld* _world = nullptr; - const IWorldItem *_playerObject = nullptr; + + bool _fDecorative = true; + bool _fDistroy = false; + bool _fFirstRenderIteration = true; + int _supportedEvents; + friend class IWorld; }; } 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/playableobject.cpp b/src/Core/Crawl/playableobject.cpp index f34831f..a9f187e 100644 --- a/src/Core/Crawl/playableobject.cpp +++ b/src/Core/Crawl/playableobject.cpp @@ -16,12 +16,17 @@ PlayableObject::PlayableObject(const QString &name, QObject *ptr): IWorldItem(name, viewTempalte, ptr) { + setFDecorative(false); } 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..0bb6bdf --- /dev/null +++ b/src/Core/Crawl/player.cpp @@ -0,0 +1,34 @@ +//# +//# 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" +#include + +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 new file mode 100644 index 0000000..5808846 --- /dev/null +++ b/src/Core/Crawl/player.h @@ -0,0 +1,57 @@ +//# +//# 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 { + +class User; + +/** + * @brief The Player class is main class of users. + */ +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/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..cc18584 --- /dev/null +++ b/src/Core/Crawl/previewcontrol.h @@ -0,0 +1,48 @@ +//# +//# 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 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/snake.cpp b/src/Core/Crawl/snake.cpp index 9c14643..d50538d 100644 --- a/src/Core/Crawl/snake.cpp +++ b/src/Core/Crawl/snake.cpp @@ -10,6 +10,7 @@ #include #include #include +#include "iworld.h" namespace CRAWL { @@ -32,12 +33,26 @@ 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( ){ delete [] _vectors; } +QString Snake::itemTextType() const { + return Snake::typeText(); +} + +QString Snake::typeText() { + return "PlayableObject"; +} + +unsigned int Snake::type() { + return qHash(typeText()); +} + void Snake::render(unsigned int tbfMsec) { PlayableObject::render(tbfMsec); } diff --git a/src/Core/Crawl/snake.h b/src/Core/Crawl/snake.h index 497e4d3..6afa0de 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: @@ -27,6 +28,22 @@ public: QObject *ptr = nullptr); ~Snake() override; + QString itemTextType() const override; + + /** + * @brief type This method return const string value of the all world types. + * @return const string value of the all world types. + * @see IItem::itemTextType + * @see IItem::type + */ + static QString typeText(); + + /** + * @brief type This is wrapper of the IWorld::typeText method that invoke the qHash function for results string. + * @return integer type object id. + */ + static unsigned int type(); + void render(unsigned int tbfMsec) override; void add(ClasterItem *object) override; @@ -34,7 +51,6 @@ public: void remove(int id) override; void init() override; - // IPlayer interface /** * @brief lengthBetwinItems This method return length betwin snake items; @@ -131,6 +147,8 @@ private: QVector3D* _vectors; float _speed; + int _hp = 100; + }; } 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/Crawl/startdata.cpp b/src/Core/Crawl/startdata.cpp new file mode 100644 index 0000000..f0c3e12 --- /dev/null +++ b/src/Core/Crawl/startdata.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 "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; +} + +const QSet &StartData::snakePerks() const { + return _snakePerks; +} + +void StartData::setSnakePerks(const QSet &newSnakePerks) { + _snakePerks = newSnakePerks; +} + +} diff --git a/src/Core/Crawl/startdata.h b/src/Core/Crawl/startdata.h new file mode 100644 index 0000000..3320f48 --- /dev/null +++ b/src/Core/Crawl/startdata.h @@ -0,0 +1,80 @@ +//# +//# 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 +#include +#include "global.h" + +#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 CRAWL_EXPORT 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); + + /** + * @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 &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 &newSnakePerks); + +private: + User *_player = nullptr; + int _snakeType; + QSet _snakePerks; +}; + +} + +#endif // STARTDATA_H 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/CrawlModule/Crawl.qml b/src/Core/CrawlModule/Crawl.qml index 8346cf8..274d9e5 100644 --- a/src/Core/CrawlModule/Crawl.qml +++ b/src/Core/CrawlModule/Crawl.qml @@ -18,19 +18,108 @@ ApplicationWindow { height: 720; title: qsTr("Crawl"); + property var model: engine + Metrix {id: metrix} + Label { + anchors.fill: parent + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + font.pixelSize: 25 + wrapMode: Text.WordWrap + text: qsTr("Please Select level. If level is not availabel please bue it first.") + } + Scene { id: scane; - model: engine; + worldModel: (model)? model.world : null; anchors.fill: parent; } - MainMenu { - - model: (mainmenu)? mainmenu: null; + Scene { + id: nest; + worldModel: (model)? model.nest : null; anchors.fill: parent; - visible: scane.showMenu + } + + ToolButton { + text: "👾" + font.pixelSize: 35 + + onClicked: { + mainMenuPopUp.open() + } + visible: !mainMenuPopUp.visible + } + + Drawer { + id: mainMenuPopUp + closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside + + height: parent.height + width: parent.width / 3 + + MainMenu { + id: mainMenu + model: (mainWindow.model)? mainWindow.model.menu: null; + anchors.fill: parent; + } + } + + PagePopUp { + id: settingsPopUp + + source: SettingsView { + id: settingsView + model: mainMenu.model ? mainMenu.model.userSettingsModel: null + } + + standardButtons: Dialog.Save | Dialog.Cancel | Dialog.RestoreDefaults + modal: false; + width: parent.width * 0.8 + height: parent.height * 0.8; + + onAccepted: { + settingsView.save(); + } + + onReset: { + settingsView.reset(); + } + + onOpened: { + settingsView.update(); + } + + } + + PagePopUp { + id: storePopUp + source: StoreView { + id: view + model: mainMenu.model ? mainMenu.model.storeView: null + + } + + modal: false; + width: parent.width * 0.8 + height: parent.height * 0.8; + + } + + PagePopUp { + id: selectLvl + source: SelectLevelView { + id: selectLvlView + model: mainMenu.model ? mainMenu.model.selectLevelModle: null + + } + + modal: false; + width: parent.width * 0.8 + height: parent.height * 0.8; + } NotificationServiceView { 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/CrawlModule/MainMenu.qml b/src/Core/CrawlModule/MainMenu.qml index fcf4302..f263243 100644 --- a/src/Core/CrawlModule/MainMenu.qml +++ b/src/Core/CrawlModule/MainMenu.qml @@ -11,10 +11,10 @@ import QtQuick.Controls import QtQuick.Layouts Item { - id: item1 + id: root property var model: null - visible: true + visible: Boolean(model && model.visible) z: 1 GridLayout { @@ -29,22 +29,30 @@ Item { anchors.bottomMargin: 0 anchors.topMargin: 0 - columns: 3 - rows: 2 + columns: 1 + rows: 10 transformOrigin: Item.Center - MainMenuButton { id: play - text: qsTr("Play game") + text: qsTr("Select level") onClicked: { selectLvl.open() } } + MainMenuButton { + id: store + text: qsTr("Store") + + onClicked: { + storePopUp.open() + } + } + MainMenuButton { id: settings text: qsTr("My Settings") @@ -66,53 +74,6 @@ Item { } - PagePopUp { - id: settingsPopUp - source: SettingsView { - id: settingsView - model: item1.model ? item1.model.userSettingsModel: null - } - - standardButtons: Dialog.Save | Dialog.Cancel | Dialog.RestoreDefaults - modal: false; - width: parent.width * 0.8 - height: parent.height * 0.8; - - onAccepted: { - settingsView.save(); - } - - onReset: { - settingsView.reset(); - } - - onOpened: { - settingsView.update(); - } - - } - - PagePopUp { - id: selectLvl - source: SelectLvlView { - id: view - model: item1.model ? item1.model.availableLvlsModel: null - - onStart: { - if (!item1.model) - return; - - item1.model.newGame(view.selectedLvl) - - selectLvl.close(); - } - } - - modal: false; - width: parent.width * 0.8 - height: parent.height * 0.8; - - } } diff --git a/src/Core/CrawlModule/MainMenuButton.qml b/src/Core/CrawlModule/MainMenuButton.qml index fd6b666..1675f23 100644 --- a/src/Core/CrawlModule/MainMenuButton.qml +++ b/src/Core/CrawlModule/MainMenuButton.qml @@ -13,12 +13,12 @@ import QtQuick.Layouts Button { id: exit Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter - font.pixelSize: height * 0.1 + font.pixelSize: height * 0.2 display: AbstractButton.TextBesideIcon spacing: 4 focusPolicy: Qt.StrongFocus Layout.preferredHeight: parent.height / (parent.rows + 1) - Layout.preferredWidth: parent.width / (parent.columns + 1) + Layout.preferredWidth: parent.width / (parent.columns + 0.5) } diff --git a/src/Core/CrawlModule/PreviewControl.qml b/src/Core/CrawlModule/PreviewControl.qml new file mode 100644 index 0000000..094ef71 --- /dev/null +++ b/src/Core/CrawlModule/PreviewControl.qml @@ -0,0 +1,72 @@ +//# +//# 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: 4 + rows: 2 + + MouseArea { + cursorShape: Qt.DragMoveCursor + + Layout.fillHeight: true + Layout.fillWidth: true + Layout.columnSpan: 4 + Layout.rowSpan: 1 + + + 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("Start") + onClicked: { + if (model) { + model.start() + } + } + } +} diff --git a/src/Core/CrawlModule/Scene.qml b/src/Core/CrawlModule/Scene.qml index 45e472c..7813252 100644 --- a/src/Core/CrawlModule/Scene.qml +++ b/src/Core/CrawlModule/Scene.qml @@ -5,16 +5,15 @@ import QtQuick.Controls import QtQuick.Layouts import QtQuick3D.Particles3D -// https://doc.qt.io/qt-5/qqmlengine.html#qmlRegisterUncreatableMetaObject -import engine.worldstatus View3D { id: scene; - property var model: null; - property alias showMenu: privateRoot.showMenu + property var worldModel: null; renderMode: View3D.Offscreen + visible: worldModel && worldModel.visible + Label { text: scane.renderStats.fps x: 200 @@ -44,26 +43,23 @@ View3D { 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 - 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; function add (cppObjId) { - if (!model) { + if (!worldModel) { console.log("create object fail") return; } - const objModel = model.getGameObject(cppObjId); + const objModel = worldModel.getItem(cppObjId); if (!objModel) { - console.log("object model not found"); + console.log("model of the crawl object is not found"); return; } @@ -95,7 +91,7 @@ View3D { } Connections { - target: privateRoot.world; + target: worldModel; function onSigOBjctsListChanged(diff) { if (!diff) { console.log("diff not found"); @@ -144,12 +140,6 @@ View3D { 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/SelectLevelView.qml b/src/Core/CrawlModule/SelectLevelView.qml new file mode 100644 index 0000000..eb0740b --- /dev/null +++ b/src/Core/CrawlModule/SelectLevelView.qml @@ -0,0 +1,72 @@ +import QtQuick +import ViewSolutionsModule +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts + +Page { + id: store + property var model: null; + ColumnLayout { + anchors.fill: parent + ListView { + id: listView + Layout.fillHeight: true + Layout.fillWidth: true + model: store.model + delegate: delegateRow + + Component { + id: delegateRow + + Rectangle { + width: listView.width + height: 100 + color: (itemId === store.model.currentLevel) ? "#ffaf2c": "#00000000" + + Behavior on color { + + ColorAnimation { + duration: 200 + } + } + + RowLayout { + + anchors.fill: parent + + Image { + id: img + fillMode: Image.PreserveAspectCrop + source: itemImage + Layout.fillHeight: true + Layout.preferredWidth: height * 2 + } + + Label { + text: itemName + Layout.fillHeight: true + } + + Label { + text: itemDescription + Layout.fillWidth: true + Layout.fillHeight: true + } + + Button { + text: qsTr("Select"); + visible: itemId !== store.model.currentLevel + + onClicked: () => { + if (store.model) + store.model.select(itemId); + } + } + } + } + + } + } + } +} diff --git a/src/Core/CrawlModule/SelectLvlView.qml b/src/Core/CrawlModule/SelectLvlView.qml deleted file mode 100644 index 5315e69..0000000 --- a/src/Core/CrawlModule/SelectLvlView.qml +++ /dev/null @@ -1,61 +0,0 @@ -//# -//# 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 ViewSolutionsModule -import QtQuick.Controls -import QtQuick.Controls.Material -import QtQuick.Layouts - -ColumnLayout { - id: root - - property alias model: list.model - property string selectedLvl: "" - - signal start(var lvlName) - - ListView { - id: list - Layout.fillHeight: true - Layout.fillWidth: true - orientation: ListView.Horizontal - clip: true - - delegate: ImageView { - property var data : modelData - hoverColor: "#90f6ff" - selectedColor: "#90f6ff" - - source: data.image - text: data.name - - width: list.height * 1.5 - height: list.height * 0.9 - selected: selectedLvl === data.name - - onClicked: { - selectedLvl = text - } - } - } - - Button { - - Layout.alignment: Qt.AlignRight - - text: qsTr("Start") - enabled: selectedLvl.length - - onClicked: { - root.start(selectedLvl) - } - - } -} - - diff --git a/src/Core/CrawlModule/StoreView.qml b/src/Core/CrawlModule/StoreView.qml new file mode 100644 index 0000000..10515f1 --- /dev/null +++ b/src/Core/CrawlModule/StoreView.qml @@ -0,0 +1,64 @@ +import QtQuick +import ViewSolutionsModule +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts + +Page { + id: store + property var model: null; + ColumnLayout { + anchors.fill: parent + ListView { + id: listView + Layout.fillHeight: true + Layout.fillWidth: true + model: store.model + delegate: delegateRow + + Component { + id: delegateRow + + RowLayout { + width: listView.width + height: 100 + Image { + id: img + fillMode: Image.PreserveAspectCrop + source: itemImage + Layout.fillHeight: true + Layout.preferredWidth: height * 2 + } + + Label { + text: itemName + Layout.fillHeight: true + } + + Label { + text: itemDescription + Layout.fillWidth: true + Layout.fillHeight: true + } + + CheckBox { + id: buyStatus + tristate: false + checkState: (itemWasBuy)? Qt.Checked: Qt.Unchecked + enabled: false + } + + Button { + text: qsTr("Buy"); + visible: !itemWasBuy + + onClicked: () => { + if (store.model) + store.model.buy(itemId); + } + } + } + } + } + } +} 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/availablelevelsmodel.cpp b/src/Core/private/availablelevelsmodel.cpp new file mode 100644 index 0000000..96f5cb4 --- /dev/null +++ b/src/Core/private/availablelevelsmodel.cpp @@ -0,0 +1,36 @@ +//# +//# 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 "availablelevelsmodel.h" +#include "user.h" +#include + +namespace CRAWL { + +AvailableLevelsModel::AvailableLevelsModel() { + +} + +int AvailableLevelsModel::getCurrentLevel() const { + return currentLevel; +} + +void AvailableLevelsModel::setCurrentLevel(int newCurrentLevel) { + if (currentLevel == newCurrentLevel) + return; + currentLevel = newCurrentLevel; + emit currentLevelChanged(); +} + +void AvailableLevelsModel::select(int levelId) { + if (getUser()->isUnlocked(levelId)) { + setCurrentLevel(levelId); + emit sigUserSelectLevel(levelId); + } +} + +} diff --git a/src/Core/private/availablelevelsmodel.h b/src/Core/private/availablelevelsmodel.h new file mode 100644 index 0000000..010478b --- /dev/null +++ b/src/Core/private/availablelevelsmodel.h @@ -0,0 +1,83 @@ +//# +//# 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 AVAILABLELEVELSMODEL_H +#define AVAILABLELEVELSMODEL_H + +#include "baseuserlistmodel.h" + +namespace CRAWL { + +class User; +class IItem; + +/** + * @brief The AvailableLevelsModel class is model of the available levels qml view. + * This model just show available levels of the current user. + * @see the SelectLevelView.qml module. + */ +class AvailableLevelsModel: public BaseUserListModel +{ + Q_OBJECT + /** + * @brief currentLevel This property contains id of the loaded level. + * @see AvailableLevelsModel::getCurrentLevel + * @see AvailableLevelsModel::setCurrentLevel + * @see AvailableLevelsModel::currentLevelChanged + */ + Q_PROPERTY(int currentLevel READ getCurrentLevel WRITE setCurrentLevel NOTIFY currentLevelChanged) + +public: + AvailableLevelsModel(); + + /** + * @brief getCurrentLevel This method return value of the curernt level property + * @return value of the curernt level property + * @see AvailableLevelsModel::currentLevel + * @see AvailableLevelsModel::setCurrentLevel + * @see AvailableLevelsModel::currentLevelChanged + */ + int getCurrentLevel() const; + + /** + * @brief setCurrentLevel This method sets new current level. + * @param newCurrentLevel This is new value of the current level. + * @see AvailableLevelsModel::getCurrentLevel + * @see AvailableLevelsModel::currentLevel + * @see AvailableLevelsModel::currentLevelChanged + */ + void setCurrentLevel(int newCurrentLevel); + + /** + * @brief select This method select new level of user. + * @param levelId This is id of the selected level. + */ + Q_INVOKABLE void select(int levelId); + + +signals: + /** + * @brief currentLevelChanged This signal emited when the currentLevel propertye is changed. + * @see AvailableLevelsModel::getCurrentLevel + * @see AvailableLevelsModel::setCurrentLevel + * @see AvailableLevelsModel::currentLevel + */ + void currentLevelChanged(); + + /** + * @brief sigUserSelectLevel This signal emited when user select new level. + * @param level This is level id that user selected. + */ + void sigUserSelectLevel(int level); + +private: + int currentLevel = -1; + +}; + +} +#endif // AVAILABLELEVELSMODEL_H diff --git a/src/Core/private/baseuserlistmodel.cpp b/src/Core/private/baseuserlistmodel.cpp new file mode 100644 index 0000000..05933e5 --- /dev/null +++ b/src/Core/private/baseuserlistmodel.cpp @@ -0,0 +1,176 @@ +//# +//# 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 "baseuserlistmodel.h" +#include "user.h" +#include "store.h" +#include + +namespace CRAWL { + +BaseUserListModel::BaseUserListModel() { + +} + +void BaseUserListModel::setUser(User *newUser) { + if (_user) { + disconnect(_user, &User::sigDropped, + this, &BaseUserListModel::handleDroppedItem); + disconnect(_user, &User::sigUnlcoked, + this, &BaseUserListModel::handleUnlockedItem); + disconnect(_user, &User::sigUlockedItemsChanged, + this, &BaseUserListModel::handleUnlockedItemsListChanged); + } + + _user = newUser; + + if (_user) { + connect(_user, &User::sigDropped, + this, &BaseUserListModel::handleDroppedItem); + connect(_user, &User::sigUnlcoked, + this, &BaseUserListModel::handleUnlockedItem); + connect(_user, &User::sigUlockedItemsChanged, + this, &BaseUserListModel::handleUnlockedItemsListChanged); + } +} + +int BaseUserListModel::getIndexById(int id) const { + return _keysIndexes.value(id, -1); +} + +Store *BaseUserListModel::store() const { + return _store; +} + +void BaseUserListModel::setStore(Store *newStore) { + _store = newStore; +} + +const QList &BaseUserListModel::keys() const { + return _keys; +} + +void BaseUserListModel::setKeys(const QList &visibleKeysList) { + int diff = visibleKeysList.size() - _keys.size(); + + auto update = [this](const QList & list) { + _keys = list; + for (int index = 0; index < _keys.size(); ++index) { + _keysIndexes[_keys[index]] = index; + } + }; + + if (diff > 0) { + beginInsertRows({}, _keys.size(), visibleKeysList.size() - 1); + update(visibleKeysList); + endInsertRows(); + + } else if (diff == 0) { + emit dataChanged(index(0,0), index(rowCount() - 1, columnCount() - 1)); + + } else { + beginRemoveRows({}, visibleKeysList.size(), _keys.size() - 1); + update(visibleKeysList); + endRemoveRows(); + } +} + +void BaseUserListModel::addKey(int newKey) { + beginInsertRows({}, _keys.size(), _keys.size()); + _keys.push_back(newKey); + _keysIndexes[newKey] = _keys.size() - 1; + endInsertRows(); +} + +void BaseUserListModel::removeKey(int oldKey) { + int idx = getIndexById(oldKey); + + if (idx >= 0) { + beginRemoveRows({}, _keys.size(), _keys.size()); + + _keys.removeAt(idx); + _keysIndexes.remove(oldKey); + + endRemoveRows(); + + } +} + +int BaseUserListModel::rowCount(const QModelIndex &) const { + return _keys.size(); +} + +int BaseUserListModel::columnCount(const QModelIndex &) const { + return 1; +} + +QVariant BaseUserListModel::data(const QModelIndex &index, int role) const { + + if (index.row() >= rowCount()) { + return {}; + } + + int id = _keys.at(index.row()); + + const IItem* item = getItem(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 getUser() && getUser()->isUnlocked(id); + default: + return {}; + } +} + +QHash BaseUserListModel::roleNames() const { + QHash roles; + + roles[ItemId] = "itemId"; + roles[ItemName] = "itemName"; + roles[ItemDescription] = "itemDescription"; + roles[ItemImage] = "itemImage"; + roles[ItemWasBuy] = "itemWasBuy"; + + return roles; +} + +User *BaseUserListModel::getUser() const { + return _user; +} + +void BaseUserListModel::handleUnlockedItem(int item) { + int idx = _keysIndexes.value(item, -1); + + if (idx >= 0) { + emit dataChanged(index(idx,0), index(idx, 0), {ItemWasBuy}); + } +} + +void BaseUserListModel::handleDroppedItem(int item) { + int idx = _keysIndexes.value(item, -1); + + if (idx >= 0) { + emit dataChanged(index(idx,0), index(idx, 0), {ItemWasBuy}); + } +} + +void BaseUserListModel::handleUnlockedItemsListChanged(const QSet &) { + emit dataChanged(index(0,0), index(_keys.size() - 1, 0), {ItemWasBuy}); +} + +const IItem *BaseUserListModel::getItem(int id) const { + return _store->getItemById(id); +} + +} diff --git a/src/Core/private/baseuserlistmodel.h b/src/Core/private/baseuserlistmodel.h new file mode 100644 index 0000000..1bfaaf5 --- /dev/null +++ b/src/Core/private/baseuserlistmodel.h @@ -0,0 +1,134 @@ +//# +//# 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 BASEUSERLISTMODEL_H +#define BASEUSERLISTMODEL_H + +#include + +namespace CRAWL { + +class User; +class IItem; +class Store; + +/** + * @brief The BaseUserListModel class This is base class wint implementation methods for working with user object. + */ +class BaseUserListModel: public QAbstractListModel +{ + Q_OBJECT +public: + BaseUserListModel(); + + /** + * @brief setUser This method update user pointer + * @param user This is new pointer to current user. + */ + void setUser(User *newUser); + + /** + * @brief keys This method retutn curent visible items list. + * @return visible items list. + * @see BaseUserListModel::setKeys + */ + const QList &keys() const; + + /** + * @brief setKeys This method sets lsit of the keys for view. + * @param visibleKeysList This is new valud of the visible keys list. + * @see BaseUserListModel::keys + */ + void setKeys(const QList& visibleKeysList); + + /** + * @brief addKey This method add new key value for view. + * @param newKey new key value. + */ + void addKey(int newKey); + + /** + * @brief removeKey This method remove old key from view. + * @param oldKey This is old key that will be removed. + */ + void removeKey(int oldKey); + + int rowCount(const QModelIndex &parent = {}) const override; + int columnCount(const QModelIndex &parent = {}) const override; + QVariant data(const QModelIndex &index, int role) const override; + QHash roleNames() const override; + + /** + * @brief store This method return pointer to current store object. + * @return current store object. + */ + Store *store() const; + + /** + * @brief setStore This method sets new pointer value for the store property. + * @param newStore This is new value of the store property + */ + void setStore(Store *newStore); + +protected: + + enum ViewItemRoles { + ItemId, + ItemName, + ItemImage, + ItemDescription, + ItemWasBuy + }; + + /** + * @brief getUser This method return pointer to current user. + * @return pointer to current user. + */ + User* getUser() const; + + /** + * @brief handleUnlockedItem This slot invoked when emited the User::unclokItem signal. + * @param item This is id of the unlocked item + */ + virtual void handleUnlockedItem(int item); + + /** + * @brief handleUnlockedItem This slot invoked when emited the User::droppItem signal. + * @param item This is id of the dropped item + */ + virtual void handleDroppedItem(int item); + + /** + * @brief handleUnlockedItem This slot invoked when emited the User::setUnlockedItems signal. + * @param item This is new list of the unclod items. + */ + virtual void handleUnlockedItemsListChanged(const QSet& newSet); + + /** + * @brief getItem This method should be return the item by id. Override this method for correct works this model. + * @param id This is item id + * @return const pointer to item object. + */ + virtual const IItem* getItem(int id) const; + + /** + * @brief getIndexById This method return index of the item by id. + * @param id This is id of the needed item + * @return index of the needed item. If the item with id not exists then return -1 + */ + int getIndexById(int id) const; +private: + + User * _user = nullptr; + QList _keys; + QHash _keysIndexes; + Store *_store = nullptr; + +}; + +} +#endif // BASEUSERLISTMODEL_H diff --git a/src/Core/private/engine.cpp b/src/Core/private/engine.cpp index f01a0b9..7be0bff 100644 --- a/src/Core/private/engine.cpp +++ b/src/Core/private/engine.cpp @@ -5,59 +5,96 @@ //# of this license document, but changing it is not allowed. //# +#include "availablelevelsmodel.h" #include "engine.h" +#include "mainmenumodel.h" #include #include +#include #include "Crawl/iworld.h" #include #include +#include #include "Crawl/icontrol.h" #include "QDateTime" #include "QtConcurrent" +#include "store.h" namespace CRAWL { Engine::Engine(QObject *parent): QObject(parent) { + _store = new Store(); + _menu = new MainMenuModel(); + + setNewUser(new User()); } Engine::~Engine() { - stopRenderLoop(); + + + for (auto it = _availableLvls.begin(); it != _availableLvls.end(); ++it) { + delete it.value(); + } + + _availableLvls.clear(); + + delete _menu; + delete _currentUser; } QObject *Engine::scane() { return _scane; } -void Engine::setQmlEngine(QQmlEngine *newEngine) { - if (_engine == newEngine) - return; +void Engine::setLevel(ILevel *world) { - _engine = newEngine; -} - -void Engine::setWorld(IWorld *world) { - if (_currentWorld == 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->name(), + if (!_currentLevel) { + + QuasarAppUtils::Params::log("Failed to init world. The World object is null! ", QuasarAppUtils::Error); - _currentWorld = nullptr; + _currentLevel = nullptr; return; } - startRenderLoop(); - _currentWorld->runAsBackGround(); + if (!_currentLevel->world()) { + QuasarAppUtils::Params::log("Failed to init world. The World Object is null: " + + _currentLevel->world()->itemName(), + QuasarAppUtils::Error); + + _currentLevel = nullptr; + return; + } + + if (!_currentLevel->previewScane()) { + QuasarAppUtils::Params::log("Failed to init world. The World Preview scane is null. World Name: " + + _currentLevel->world()->itemName(), + QuasarAppUtils::Error); + + _currentLevel = nullptr; + return; + } + + connect(_currentLevel->previewScane(), &IPreviewScaneWorld::sigPrepareIsFinished, + this, &Engine::start); + + connect(_currentLevel->world(), &IPreviewScaneWorld::sigGameFinished, + this, &Engine::stop); + + _currentLevel->previewScane()->start({}); + } void Engine::setScane(QObject *newScane) { @@ -68,109 +105,148 @@ 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; + if (!_currentLevel) + return nullptr; + + return _currentLevel->world(); } +void Engine::start(const StartData& config) const { + if (!_currentLevel) + return; + + + if (!_currentLevel->previewScane()->stop()) { + return; + } + + _currentLevel->world()->start(config); +} + +void Engine::stop() const { + if (!_currentLevel) + return; + + _currentLevel->previewScane()->start(_currentLevel->previewScane()->configuration()); +} + +void Engine::handleUnlockedItem(int item) { + static_cast(_menu->selectLevelModle())->addKey(item); +} + +void Engine::handleDroppedItem(int item) { + static_cast(_menu->selectLevelModle())->removeKey(item); +} + +void Engine::handleUnlockedItemsListChanged(const QSet &newSet) { + static_cast(_menu->selectLevelModle())->setKeys(QList(newSet.begin(), newSet.end())); +} + +void Engine::handleLevelChanged(int levelId) { + + ILevel* data = _availableLvls.value(levelId, nullptr); + + if (!data) { + QuasarAppUtils::Params::log("Failed to start lvl.", QuasarAppUtils::Error); + return; + } + + setLevel(data); +} + +ILevel *Engine::getLastLevel() { + for (const auto &data : qAsConst(_availableLvls)) { + if (data && data->world() && currentUser() && + currentUser()->isUnlocked(data->world()->itemId())) { + return data; + } + } + + return nullptr; +} QObject *Engine::menu() const { return _menu; } -void Engine::setMenu(QObject *newMenu) { - if (_menu == newMenu) { - return; +void Engine::setNewUser(User *user) { + if (_currentUser) { + + disconnect(_currentUser, &User::sigUnlcoked, this, &Engine::handleUnlockedItem); + disconnect(_currentUser, &User::sigDropped, this, &Engine::handleDroppedItem); + disconnect(_currentUser, &User::sigUlockedItemsChanged, + this, &Engine::handleUnlockedItemsListChanged); } - _menu = newMenu; - emit menuChanged(); + _currentUser = user; + static_cast(_menu->storeView())->setUser(_currentUser); + static_cast(_menu->selectLevelModle())->setUser(_currentUser); + + + if (_currentUser) { + + connect(_currentUser, &User::sigUnlcoked, this, &Engine::handleUnlockedItem); + connect(_currentUser, &User::sigDropped, this, &Engine::handleDroppedItem); + connect(_currentUser, &User::sigUlockedItemsChanged, + this, &Engine::handleUnlockedItemsListChanged); + } } -int Engine::prepareLvlProgress() const { - return _prepareLvlProgress; +void Engine::addLvl(ILevel *levelWordl) { + if (!levelWordl->world()) { + QuasarAppUtils::Params::log("The Level not contains world object!!!"); + return; + } + _availableLvls.insert(levelWordl->world()->itemId(), levelWordl); } -bool Engine::start() const { - if (!_currentWorld) - return false; - - if (!_currentWorld->isInit()) - return false; - - return _currentWorld->start(); +Store *Engine::store() const { + return _store; } -QObject *Engine::getGameObject(int id) const { - if (!_currentWorld) +QObject *Engine::nest() const { + if (!_currentLevel) return nullptr; - return _currentWorld->getItem(id); + return _currentLevel->previewScane(); } -void Engine::startRenderLoop() { - if (isRendering()) - return; - - _renderLoop = true; - _renderLoopFuture = QtConcurrent::run([this](){renderLoop();}); +User *Engine::currentUser() const { + return _currentUser; } -void Engine::stopRenderLoop() { - _renderLoop = false; - _renderLoopFuture.waitForFinished(); -} +void Engine::init() { + QMultiHash availabelItems; -bool Engine::isRendering() const { - return _renderLoopFuture.isRunning(); -} - -void Engine::setPrepareLvlProgress(int newPrepareLvlProgress) { - if (_prepareLvlProgress == newPrepareLvlProgress) { - return; - } - _prepareLvlProgress = newPrepareLvlProgress; - emit prepareLvlProgressChanged(); -} - -bool Engine::prepareNewWorld() { - if (!_currentWorld->prepare()) { - return false; + for (const auto &data : qAsConst(_availableLvls)) { + if (data && data->world()) + availabelItems.unite(data->world()->childItemsRecursive()); } - if (!_currentWorld->userInterface()->init()) { - return false; - } + _store->init(availabelItems); + static_cast(_menu->storeView())->init(_store, _currentUser); - setMenu(_currentWorld->userInterface()); - - return true; -} - -void Engine::renderLoop() { - - if (!_currentWorld) - return; - - while (_renderLoop) { - - quint64 currentTime = QDateTime::currentMSecsSinceEpoch(); - - if (!_oldTimeRender) { - _oldTimeRender = currentTime; - continue; + QList availableWorlds; + for (int id : _currentUser->unlockedItems()) { + auto item = availabelItems.value(id); + if (item->itemType() == IWorld::type()) { + availableWorlds.push_back(item->itemId()); } - - _currentWorld->render(currentTime - _oldTimeRender); - _oldTimeRender = currentTime; } +#define selectedLevelModel static_cast(_menu->selectLevelModle()) + selectedLevelModel->setStore(_store); + selectedLevelModel->setKeys(availableWorlds); + connect(selectedLevelModel, &AvailableLevelsModel::sigUserSelectLevel, + this, &Engine::handleLevelChanged); } } diff --git a/src/Core/private/engine.h b/src/Core/private/engine.h index c27a114..5e2af5d 100644 --- a/src/Core/private/engine.h +++ b/src/Core/private/engine.h @@ -12,10 +12,16 @@ #include #include #include +#include namespace CRAWL { class IWorld; +class Store; +class StartData; +class User; +class StoreViewModel; +class MainMenuModel; /** * @brief The Engine class @@ -25,10 +31,11 @@ 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* 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) + Q_PROPERTY(QObject * menu READ menu NOTIFY menuChanged) + public: Engine(QObject * parent = nullptr); @@ -41,16 +48,10 @@ public: Q_INVOKABLE QObject* scane(); /** - * @brief setQmlEngine This method sets qml engine - * @param newEngine This is pointer to the qml engine. + * @brief setLevel This method set new world level for game. + * @param world This is pointer to new world level. */ - void setQmlEngine(QQmlEngine *newEngine); - - /** - * @brief setWorld This method set new world for game. - * @param world This is pointer to new world. - */ - void setWorld(IWorld *world); + void setLevel(ILevel *world); /** * @brief setScane This method sets new scane object. The scane object are @@ -77,52 +78,46 @@ 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. + * @brief currentUser This method return pointer too current user. + * @return pointer too current user. + */ + User *currentUser() const; + + /** + * @brief init This method initialize the main model. Sets available levels and items. + * @param availabelItems This is list of available items. + */ + void init(); + + /** + * @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 ; + + /** + * @brief menu This is a main menu model. + * @return main menu model object. */ QObject *menu() const; /** - * @brief setMenu This method sets new menu object. - * @param newMenu + * @brief setNewUser This method will initialise the new user profile. + * @param user This is pointer to new user profile. */ - void setMenu(QObject *newMenu); + void setNewUser(User* user); /** - * @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 + * @brief addLvl This method should be add level to game. + * @param levelWordl This is world instance */ - 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. - * @return pointer to game object model - */ - Q_INVOKABLE QObject *getGameObject(int id) const; - - /** - * @brief startRenderLoop This method start render loop in engine. - */ - void startRenderLoop(); - - /** - * @brief stopRenderLoop This method stop render loop in engine. - */ - void stopRenderLoop(); - - /** - * @brief isRendering This method erturn true if the render loop is working else false. - * @return true if the render loop is working else false. - */ - bool isRendering() const; + void addLvl(ILevel* levelWordl); signals: void scaneChanged(); @@ -130,24 +125,57 @@ signals: void worldChanged(); void menuChanged(); - 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; + + /** + * @brief handleUnlockedItem This slot invoked when emited the User::unclokItem signal. + * @param item This is id of the unlocked item + */ + void handleUnlockedItem(int item); + + /** + * @brief handleUnlockedItem This slot invoked when emited the User::droppItem signal. + * @param item This is id of the dropped item + */ + void handleDroppedItem(int item); + + /** + * @brief handleUnlockedItem This slot invoked when emited the User::setUnlockedItems signal. + * @param item This is new list of the unclod items. + */ + void handleUnlockedItemsListChanged(const QSet& newSet); + + /** + * @brief handleLevelChanged This slot invoked when user select new level. + * @param levelId level id + */ + void handleLevelChanged(int levelId); private: - void setPrepareLvlProgress(int newPrepareLvlProgress); - bool prepareNewWorld(); + + ILevel * getLastLevel(); + void renderLoop(); - QObject *_scane = nullptr; - QQmlEngine *_engine = nullptr; - IWorld* _currentWorld = nullptr; - QObject *_menu = nullptr; - int _prepareLvlProgress; + ILevel* _currentLevel = nullptr; + QHash _availableLvls; - quint64 _oldTimeRender = 0; + MainMenuModel *_menu = nullptr; - QFuture _renderLoopFuture; - bool _renderLoop = false; + User *_currentUser = nullptr; + Store *_store = nullptr; }; } diff --git a/src/Core/private/eventserver.cpp b/src/Core/private/eventserver.cpp new file mode 100644 index 0000000..fe6f097 --- /dev/null +++ b/src/Core/private/eventserver.cpp @@ -0,0 +1,115 @@ +//# +//# 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 +#include +#include + +namespace CRAWL { + +EventServer::EventServer(IWorld *instance) { + debug_assert(instance, "Invalid World pointer in EventServer"); + _worldInstance = instance; + + _supportedEventsKeys = {Events::Intersects}; +} + +EventServer::~EventServer() { + stop(); +} + +void EventServer::start() { + if (_renderLoopFuture.isRunning()) + return; + + _renderLoop = true; + _renderLoopFuture = QtConcurrent::run([this](){renderLoop();}); +} + +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 result; + for (const IWorldItem *object : qAsConst(_objects)) { + if (item != object && item->intersects(*object)) { + result.append(object); + } + } + + if (result.size()) { + emit sigIntersect(item, result); + } + break; + } + + 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) { + 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 new file mode 100644 index 0000000..3e2494f --- /dev/null +++ b/src/Core/private/eventserver.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. +//# + +#include +#include + +#include +#include + + +#ifndef EVENTSERVER_H +#define EVENTSERVER_H + +namespace CRAWL { + +class IWorldItem; +class IWorld; + +/** + * @brief The EventServer class process all game events. + * 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(IWorld * instance); + ~EventServer(); + + /** + * @brief start This method start a processing og the objects events. + */ + 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 trigger This is pointer to object that support this evvent. + * @param objects This is list of the intersects objects. + */ + void sigIntersect(const IWorldItem* trigger, QList objects); + +private: + void eventProcess(); + void addToSupportedEvents(const IWorldItem *obj, int event); + + void renderLoop(); + + IWorld * _worldInstance = nullptr; + QHash _objects; + QHash> _supportedEvents; + QList _supportedEventsKeys; + QFuture _renderLoopFuture; + bool _renderLoop = false; + quint64 _oldTimeRender = 0; + +}; + +} + +#endif // EVENTSERVER_H diff --git a/src/Core/private/mainmenumodel.cpp b/src/Core/private/mainmenumodel.cpp index 6426c36..49ef03c 100644 --- a/src/Core/private/mainmenumodel.cpp +++ b/src/Core/private/mainmenumodel.cpp @@ -6,8 +6,10 @@ //# #include +#include "availablelevelsmodel.h" #include "mainmenumodel.h" #include "settingsviewmodel.h" +#include "storeviewmodel.h" #include @@ -17,28 +19,36 @@ MainMenuModel::MainMenuModel(QObject *ptr): QObject (ptr) { _conf = QuasarAppUtils::Settings::instance(); _userSettingsModel = new SettingsViewModel(this); - _availableLvlsModel = new ViewSolutions::ListViewModel(this); + _storeView = new StoreViewModel(); + _selectLevelModle = new AvailableLevelsModel(); +} +MainMenuModel::~MainMenuModel() { + delete _storeView; + delete _selectLevelModle; } QObject *MainMenuModel::userSettingsModel() const { return _userSettingsModel; } -QObject *MainMenuModel::availableLvlsModel() const { - return _availableLvlsModel; +bool MainMenuModel::getVisible() const { + return visible; } -void MainMenuModel::addWorldViewModel(QObject * data) { - _availableLvlsModel->addSource(data); +void MainMenuModel::setVisible(bool newVisible) { + if (visible == newVisible) + return; + visible = newVisible; + emit visibleChanged(); } -void MainMenuModel::setAvailableLvls(const QList &newData) { - _availableLvlsModel->setSource(newData); +QObject *MainMenuModel::storeView() const { + return _storeView; } -void MainMenuModel::newGame(const QString &lvl) { - emit sigNewGame(lvl); +QObject *MainMenuModel::selectLevelModle() const { + return _selectLevelModle; } } diff --git a/src/Core/private/mainmenumodel.h b/src/Core/private/mainmenumodel.h index 4428fcb..68e7493 100644 --- a/src/Core/private/mainmenumodel.h +++ b/src/Core/private/mainmenumodel.h @@ -10,7 +10,6 @@ #include #include "settings.h" -#include "worldviewdata.h" namespace ViewSolutions { class ListViewModel; @@ -19,6 +18,8 @@ class ListViewModel; namespace CRAWL { class WorldInfo; +class StoreViewModel; +class AvailableLevelsModel; /** * @brief The MainMenuModel class This is main class for controll user interface @@ -28,26 +29,57 @@ class MainMenuModel : public QObject Q_OBJECT Q_PROPERTY(QObject* userSettingsModel READ userSettingsModel NOTIFY userSettingsModelChanged) - Q_PROPERTY(QObject * availableLvlsModel READ availableLvlsModel NOTIFY availableLvlsModelChanged) + Q_PROPERTY(bool visible READ getVisible WRITE setVisible NOTIFY visibleChanged) + Q_PROPERTY(QObject * storeView READ storeView NOTIFY storeViewChanged) + Q_PROPERTY(QObject * selectLevelModle READ selectLevelModle NOTIFY selectLevelModleChanged) public: MainMenuModel(QObject *ptr = nullptr); + ~MainMenuModel(); + + /** + * @brief userSettingsModel This method return pointer to the setting model. + * @return This is pointer to setting model. + */ QObject* userSettingsModel() const; - QObject* availableLvlsModel() const; - void addWorldViewModel(QObject *); - void setAvailableLvls(const QList &newData); - Q_INVOKABLE void newGame(const QString& lvl); + + /** + * @brief getVisible This method return visible property of the main game menu. + * @return true if the menu is visble. + */ + bool getVisible() const; + + /** + * @brief setVisible This method will change visible of the main menu. + * @param newVisible This is new vlaue of the visible. + */ + void setVisible(bool newVisible); + + /** + * @brief storeView This method return pointer to store view model + * @return pointer to store view model + */ + QObject *storeView() const; + + /** + * @brief selectLevelModle This method return pointer to the available levels model. + * @return pointer to main available levels model. + */ + QObject *selectLevelModle() const; signals: void userSettingsModelChanged(QObject* userSettingsModel); - void sigNewGame(const QString& lvl); - void availableLvlsModelChanged(); + void visibleChanged(); + void storeViewChanged(); + void selectLevelModleChanged(); private: Settings *_conf = nullptr; QObject* _userSettingsModel = nullptr; - ViewSolutions::ListViewModel *_availableLvlsModel = nullptr; + bool visible = true; + StoreViewModel *_storeView = nullptr; + AvailableLevelsModel *_selectLevelModle = nullptr; }; diff --git a/src/Core/private/store.cpp b/src/Core/private/store.cpp new file mode 100644 index 0000000..68da23c --- /dev/null +++ b/src/Core/private/store.cpp @@ -0,0 +1,54 @@ +//# +//# 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 +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 QMultiHash &availabelItems) { + _store = availabelItems; + + return true; +} + +const IItem *Store::getItemById(int id) const { + return _store.value(id, nullptr); +} + +int Store::size() const { + return _store.size(); +} + +QList Store::keysList() const { + return QList{_store.keyBegin(), _store.keyEnd()}; +} +} diff --git a/src/Core/private/store.h b/src/Core/private/store.h new file mode 100644 index 0000000..d3b04cb --- /dev/null +++ b/src/Core/private/store.h @@ -0,0 +1,64 @@ +//# +//# 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 QMultiHash &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; + + /** + * @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 keysList() const; + +private: + QMultiHash _store; +}; +} +#endif // STORE_H diff --git a/src/Core/private/storeviewmodel.cpp b/src/Core/private/storeviewmodel.cpp new file mode 100644 index 0000000..466f475 --- /dev/null +++ b/src/Core/private/storeviewmodel.cpp @@ -0,0 +1,32 @@ +#include "storeviewmodel.h" +#include "store.h" +#include "user.h" + +#include + +namespace CRAWL { + +StoreViewModel::StoreViewModel() { + +} + +void StoreViewModel::init(Store *store, User *user) { + setUser(user); + setStore(store); + setKeys(store->keysList()); +} + +void StoreViewModel::buy(int item) { + if (store() && getUser()) { + store()->buy(*getUser(), item); + } +} + +const IItem *StoreViewModel::getItem(int id) const { + if (!store()) + return nullptr; + + return store()->getItemById(id); +} + +} diff --git a/src/Core/private/storeviewmodel.h b/src/Core/private/storeviewmodel.h new file mode 100644 index 0000000..606e17f --- /dev/null +++ b/src/Core/private/storeviewmodel.h @@ -0,0 +1,49 @@ +//# +//# 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 "baseuserlistmodel.h" + +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 BaseUserListModel +{ + Q_OBJECT + +public: + StoreViewModel(); + + /** + * @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(Store * store, User* user); + + /** + * @brief buy This is qml method for receive signal from view about buying item. + * @param item This is item id that user want to buy. + */ + Q_INVOKABLE void buy(int item); + + // BaseUserListModel interface +protected: + const IItem *getItem(int id) const; + +}; + +} +#endif // STOREVIEWMODEL_H diff --git a/src/Core/private/user.cpp b/src/Core/private/user.cpp new file mode 100644 index 0000000..f15c0f6 --- /dev/null +++ b/src/Core/private/user.cpp @@ -0,0 +1,124 @@ +//# +//# 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 { + +constexpr float tierMul = 1.2; +constexpr int firstTierCount = 10; + +/// @private +template +struct Tiers +{ + enum { value = static_cast(tierMul * Tiers::value)}; +}; + +/// @private +template <> +struct Tiers<0> +{ + enum { value = 0 }; +}; + +/// @private +template <> +struct Tiers<1> +{ + enum { value = firstTierCount }; +}; +// End Tiers table + +constexpr int maximumTear = 100; + +#define T(X) Tiers::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 &User::unlockedItems() const { + return _unlockedItems; +} + +bool User::isUnlocked(int item) const { + return _unlockedItems.contains(item); +} + +void User::unclokItem(int item) { + _unlockedItems.insert(item); + emit sigUnlcoked(item); +} + +void User::droppItem(int item) { + _unlockedItems.remove(item); + emit sigDropped(item); +} + +void User::setUnlockedItems(const QSet &newUnlockedItems) { + _unlockedItems = newUnlockedItems; + emit sigUlockedItemsChanged(newUnlockedItems); +} + +int User::recalcTier() { + int _tier = 0; + + while (getXp() > tiersTable[_tier]) { + _tier++; + } + + return _tier; +} + +void User::setTier(int tier) { + if (_tier == tier) + return; + + _tier = tier; + + emit tierChanged(); +} + +int User::getXp() const { + return _xp; +} + +void User::setXp(int newXp) { + if (_xp == newXp) + return; + _xp = newXp; + + setTier(recalcTier()); + + emit xpChanged(); +} + +int User::getTier() { + return _tier; +} + +int User::getMoney() 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 new file mode 100644 index 0000000..e8f96db --- /dev/null +++ b/src/Core/private/user.h @@ -0,0 +1,192 @@ +//# +//# 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 +#include + +#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 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::getMoney + */ + 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::getXp + * @see User::tier + * @see User::getTier + */ + 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::getXp + * @see User::getTier + */ + Q_PROPERTY(int tier READ getTier NOTIFY tierChanged) + +public: + User(); + + /** + * @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 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::getMoney + * @see User::money + */ + void setMoney(int newMoney); + + /** + * @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::getXp + * @see User::tier + * @see User::getTier + */ + 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::getXp + * @see User::tier + * @see User::getTier + */ + void setXp(int newXp); + + /** + * @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::getXp + * @see User::tier + */ + int getTier(); + + /** + * @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 &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(); + + /** + * @brief sigUlockedItemsChanged This signal emited when users list of unclode items is changed.. + * @param unclokedItems This is unlocked items set. Each items in the set is id of the unclocked item. + */ + void sigUlockedItemsChanged(const QSet & unclokedItems); + + /** + * @brief sigUnlcoked This signal emmited when user unlock one item. + * @param item This is unlocked item id. + * @see User::unclokItem + */ + void sigUnlcoked(int item); + + /** + * @brief sigDropped This signal emmited when user dropped one item. + * @param item This is dpopped item id. + * @see User::droppItem + */ + void sigDropped(int item); + +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 &newUnlockedItems); + +private: + + int recalcTier(); + + void setTier(int tier); + + int _money = 0; + int _xp = 0; + int _tier = 0; + QSet _unlockedItems; +}; +} + +#endif // USER_H diff --git a/src/Core/private/worldviewdata.cpp b/src/Core/private/worldviewdata.cpp deleted file mode 100644 index dba250b..0000000 --- a/src/Core/private/worldviewdata.cpp +++ /dev/null @@ -1,67 +0,0 @@ -//# -//# 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 "worldviewdata.h" -#include "Crawl/iworld.h" -namespace CRAWL { - -WorldViewData::WorldViewData(const IWorld *data) { - setWorldObject(data); -} - -QString WorldViewData::name() const { - if (_worldObject) { - return _worldObject->name(); - } - - return ""; -} - -QString WorldViewData::desc() const { - if (_worldObject) { - return _worldObject->description(); - } - - return ""; -} - -int WorldViewData::cost() const { - if (_worldObject) { - return _worldObject->costToUnlock(); - } - - return 0; -} - -bool WorldViewData::unlocked() const { - return m_unlocked || !cost(); -} - -void WorldViewData::setUnlocked(bool newUnlocked) { - if (m_unlocked == newUnlocked) - return; - m_unlocked = newUnlocked; - emit unlockedChanged(); -} - -QString WorldViewData::image() const { - if (_worldObject) { - return _worldObject->imagePreview(); - } - - return ""; -} - -void WorldViewData::setWorldObject(const IWorld *newWorldObject) { - if (_worldObject == newWorldObject) - return; - - _worldObject = newWorldObject; - emit dataChanged(); - -} -} diff --git a/src/Core/private/worldviewdata.h b/src/Core/private/worldviewdata.h deleted file mode 100644 index 97c8232..0000000 --- a/src/Core/private/worldviewdata.h +++ /dev/null @@ -1,52 +0,0 @@ -//# -//# 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 WORLDVIEWDATA_H -#define WORLDVIEWDATA_H - -#include - -namespace CRAWL { - -class IWorld; - -/** - * @brief The WorldViewData class Simaple class for view world status in gui interface. - */ -class WorldViewData: public QObject -{ - Q_OBJECT - - Q_PROPERTY(QString name READ name NOTIFY dataChanged) - Q_PROPERTY(QString desc READ desc NOTIFY dataChanged) - Q_PROPERTY(int cost READ cost NOTIFY dataChanged) - Q_PROPERTY(bool unlocked READ unlocked WRITE setUnlocked NOTIFY unlockedChanged) - Q_PROPERTY(QString image READ image NOTIFY dataChanged) - -public: - WorldViewData(const IWorld * data); - QString name() const; - QString desc() const; - - int cost() const; - bool unlocked() const; - void setUnlocked(bool newUnlocked); - - QString image() const; - - void setWorldObject(const IWorld *newWorldObject); - -private: - bool m_unlocked; - const IWorld* _worldObject = nullptr; - -signals: - void dataChanged(); - void unlockedChanged(); -}; -} -#endif // WORLDVIEWDATA_H diff --git a/src/CrawlAbstractLvl/abstractlevel.cpp b/src/CrawlAbstractLvl/abstractlevel.cpp index 7ed9c2d..69329bf 100644 --- a/src/CrawlAbstractLvl/abstractlevel.cpp +++ b/src/CrawlAbstractLvl/abstractlevel.cpp @@ -8,11 +8,13 @@ #include "abstractlevel.h" #include "abslvlworld.h" +#include + AbstractLevel::AbstractLevel() { - -} - -CRAWL::IWorld *AbstractLevel::world() { initAbstractLvlResources(); - return new AbstractLvl::AbsLvlWorld(); + + auto world = new AbstractLvl::AbsLvlWorld(); + setWorld(world); + setPreviewScane(new AbstractLvl::AbsNest(world)); } + 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 diff --git a/src/CrawlAbstractLvl/private/abslvlsnake.cpp b/src/CrawlAbstractLvl/private/abslvlsnake.cpp index 90d7ed3..8dc8a38 100644 --- a/src/CrawlAbstractLvl/private/abslvlsnake.cpp +++ b/src/CrawlAbstractLvl/private/abslvlsnake.cpp @@ -30,8 +30,30 @@ AbsLvlSnake::AbsLvlSnake(): Snake(AUTO_CLASS_NAME) { registerItemType(); } -void AbsLvlSnake::onIntersects(const IWorldItem *item) { - Q_UNUSED(item); +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 3b07aec..db2c61d 100644 --- a/src/CrawlAbstractLvl/private/abslvlsnake.h +++ b/src/CrawlAbstractLvl/private/abslvlsnake.h @@ -19,10 +19,15 @@ class AbsLvlSnake : public CRAWL::Snake { public: AbsLvlSnake(); - // IWorldItem interface -protected: - void onIntersects(const IWorldItem *item) 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/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/abslvlworld.cpp b/src/CrawlAbstractLvl/private/abslvlworld.cpp index 5b3aeee..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(); } @@ -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; } @@ -77,8 +77,16 @@ 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 { + return "AbstractLevel"; +} + +int AbsLvlWorld::requiredTier() const { + return 0; } } diff --git a/src/CrawlAbstractLvl/private/abslvlworld.h b/src/CrawlAbstractLvl/private/abslvlworld.h index 2f075cf..0927625 100644 --- a/src/CrawlAbstractLvl/private/abslvlworld.h +++ b/src/CrawlAbstractLvl/private/abslvlworld.h @@ -19,16 +19,17 @@ 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; - 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; + void initControl(CRAWL::IControl *control) override; + QString itemTextId() const override; + int requiredTier() const override; }; diff --git a/src/CrawlAbstractLvl/private/absnest.cpp b/src/CrawlAbstractLvl/private/absnest.cpp new file mode 100644 index 0000000..dfa0994 --- /dev/null +++ b/src/CrawlAbstractLvl/private/absnest.cpp @@ -0,0 +1,35 @@ +//# +//# 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 "absnest.h" +#include "obstacleblue.h" + +#include + +namespace AbstractLvl { + +AbsNest::AbsNest(IWorld * mainWorld): CRAWL::IPreviewScaneWorld(mainWorld) { + +} + +CRAWL::WorldRule *AbsNest::initWorldRules() { + return new CRAWL::WorldRule { + {0, + { + {registerObject(), 1}, + {registerObject(), 1} + } + } + + }; +} + +QString AbsNest::initHdrBackGround() const { + return ""; +} + +} diff --git a/src/CrawlAbstractLvl/private/absnest.h b/src/CrawlAbstractLvl/private/absnest.h new file mode 100644 index 0000000..ae61e1d --- /dev/null +++ b/src/CrawlAbstractLvl/private/absnest.h @@ -0,0 +1,32 @@ +//# +//# 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 ABSNEST_H +#define ABSNEST_H +#include + + +namespace AbstractLvl { + +/** + * @brief The AbsNest class Abstrcat nest level + */ +class AbsNest: public CRAWL::IPreviewScaneWorld +{ +public: + AbsNest(IWorld *mainWorld); + + // IWorld interface +public: + CRAWL::WorldRule *initWorldRules() override; + QString initHdrBackGround() const override; + +}; + +} +#endif // ABSNEST_H 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(); } -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..f1df44c 100644 --- a/src/CrawlTestLvl/private/box.cpp +++ b/src/CrawlTestLvl/private/box.cpp @@ -6,7 +6,7 @@ //# #include "box.h" - +#include "Crawl/iworld.h" #include namespace TestLvl { @@ -24,9 +24,24 @@ Box::Box(): IWorldItem("Box") { setposition({static_cast(rand() % 100) - 50, static_cast(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(); + } } + +void Box::firstSpawn() { + float dX = rand() % static_cast(world()->cameraReleativePosition().z()); + setX(dX); + + float dY = rand() % static_cast(world()->cameraReleativePosition().z()); + setY(dY); +} + } diff --git a/src/CrawlTestLvl/private/box.h b/src/CrawlTestLvl/private/box.h index 7a9ae7e..16adf4b 100644 --- a/src/CrawlTestLvl/private/box.h +++ b/src/CrawlTestLvl/private/box.h @@ -16,10 +16,11 @@ class Box: public CRAWL::IWorldItem { public: Box(); + void action(IWorldItem *item) override; // IWorldItem interface -protected: - void onIntersects(const IWorldItem *item) override; +public: + void firstSpawn() override; }; } #endif // BOX_H diff --git a/src/CrawlTestLvl/private/nest.cpp b/src/CrawlTestLvl/private/nest.cpp new file mode 100644 index 0000000..b7f2ff5 --- /dev/null +++ b/src/CrawlTestLvl/private/nest.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 "background.h" +#include "box.h" +#include "nest.h" + +#include +#include +#include +#include +#include + +namespace TestLvl { + +Nest::Nest(IWorld *mainWorld): CRAWL::IPreviewScaneWorld(mainWorld) { + +} + +CRAWL::WorldRule *Nest::initWorldRules() { + using Day = CRAWL::Day; + + return new CRAWL::WorldRule { + {0, {{registerObject(), 3}, + {registerObject(), 2}, + {registerObject(), 1}, + + {registerObject(), 1}, + {registerObject(), 1}}} + }; +} + +QString Nest::initHdrBackGround() const { + return ""; +} + +CRAWL::IWorldItem *Nest::generate(const QString &objectType) const { + auto object = IPreviewScaneWorld::generate(objectType); + + return object; +} + + +} diff --git a/src/CrawlTestLvl/private/nest.h b/src/CrawlTestLvl/private/nest.h new file mode 100644 index 0000000..a4b56e5 --- /dev/null +++ b/src/CrawlTestLvl/private/nest.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 NEST_H +#define NEST_H + +#include "Crawl/ipreviewscaneworld.h" + +namespace TestLvl { + +/** + * @brief The Nest class Test nest world. + */ +class Nest: public CRAWL::IPreviewScaneWorld +{ +public: + Nest(IWorld* mainWorld); + + // IWorld interface +public: + CRAWL::WorldRule *initWorldRules() override; + QString initHdrBackGround() const override; + + +protected: + CRAWL::IWorldItem *generate(const QString &objectType) const override; +}; + +} +#endif // NEST_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..0b5affb 100644 --- a/src/CrawlTestLvl/private/testsnake.cpp +++ b/src/CrawlTestLvl/private/testsnake.cpp @@ -18,15 +18,35 @@ TestSnake::TestSnake(): Snake("Snake") { setSize({2,1,1}); registerItemType(); - -} - -void TestSnake::onIntersects(const IWorldItem *item) { - Q_UNUSED(item); + setContainerSize({2, 2, 2}); } 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 b85b9ba..846e550 100644 --- a/src/CrawlTestLvl/private/testsnake.h +++ b/src/CrawlTestLvl/private/testsnake.h @@ -19,14 +19,19 @@ class TestSnake : public CRAWL::Snake { public: TestSnake(); - // IWorldItem interface -protected: - void onIntersects(const IWorldItem *item) override; - // 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/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 281bb39..7bf6964 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; return new CRAWL::WorldRule { - {0, {{registerObject(), 100}, + {0, {{registerObject(), 1000}, {registerObject(), 10}, {registerObject(), 1}, @@ -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; } @@ -64,16 +64,16 @@ 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(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 { +CRAWL::PlayableObject *World::initPlayer(int) const { return new TestSnake(); } @@ -81,6 +81,14 @@ CRAWL::IAI *World::initBackGroundAI() const { return IWorld::initBackGroundAI(); } +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 f8038f7..e376fb0 100644 --- a/src/CrawlTestLvl/private/world.h +++ b/src/CrawlTestLvl/private/world.h @@ -23,18 +23,19 @@ 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; + void initControl(CRAWL::IControl *control) override; + CRAWL::PlayableObject *initPlayer(int type) 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/CrawlTestLvl/testlevel.cpp b/src/CrawlTestLvl/testlevel.cpp index 32b15ac..f1cb04d 100644 --- a/src/CrawlTestLvl/testlevel.cpp +++ b/src/CrawlTestLvl/testlevel.cpp @@ -7,12 +7,11 @@ #include "testlevel.h" #include "world.h" +#include "nest.h" TestLevel::TestLevel() { - -} - -CRAWL::IWorld *TestLevel::world() { initTestLvlResources(); - return new TestLvl::World(); + auto world = new TestLvl::World(); + setWorld(world); + setPreviewScane(new TestLvl::Nest(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..cddf393 100644 --- a/src/JungleLvl/jungle.cpp +++ b/src/JungleLvl/jungle.cpp @@ -8,12 +8,14 @@ #include "jungle.h" #include "world.h" +#include "nest.h" Jungle::Jungle() { - -} - -CRAWL::IWorld *Jungle::world() { initJungleLvlResources(); - return new JungleLvl::World(); + + auto world = new JungleLvl::World(); + + setWorld(world); + + setPreviewScane(new JungleLvl::Nest(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/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(); } -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(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/nest.cpp b/src/JungleLvl/private/nest.cpp new file mode 100644 index 0000000..fb44087 --- /dev/null +++ b/src/JungleLvl/private/nest.cpp @@ -0,0 +1,40 @@ +//# +//# 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 "absaluteplate.h" +#include "grees.h" +#include "ground.h" +#include "nest.h" + +#include +#include +#include + +namespace JungleLvl { + +Nest::Nest(IWorld *mainWorld): CRAWL::IPreviewScaneWorld(mainWorld) { + +} + +CRAWL::WorldRule *Nest::initWorldRules() { + using Day = CRAWL::Day; + + return new CRAWL::WorldRule { + {0, { + {registerObject(), 1}, + {registerObject(), 1}, + {registerObject(), 1}, + {registerObject(), 500} + } + } + }; +} + +QString Nest::initHdrBackGround() const { + return ""; +} +} diff --git a/src/JungleLvl/private/nest.h b/src/JungleLvl/private/nest.h new file mode 100644 index 0000000..12e8f30 --- /dev/null +++ b/src/JungleLvl/private/nest.h @@ -0,0 +1,29 @@ +//# +//# 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 NEST_H +#define NEST_H +#include + +namespace JungleLvl { + +/** + * @brief The Nest class + */ +class Nest: public CRAWL::IPreviewScaneWorld +{ +public: + Nest(IWorld *mainWorld); + + // IWorld interface +public: + CRAWL::WorldRule *initWorldRules() override; + QString initHdrBackGround() const override; +}; + +} +#endif // NEST_H diff --git a/src/JungleLvl/private/snake.cpp b/src/JungleLvl/private/snake.cpp index 3ffff0b..150bd23 100644 --- a/src/JungleLvl/private/snake.cpp +++ b/src/JungleLvl/private/snake.cpp @@ -31,8 +31,28 @@ Snake::Snake(): CRAWL::Snake("JungleSnake") { {1, 0.5}}); } -void Snake::onIntersects(const IWorldItem *) { +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 { diff --git a/src/JungleLvl/private/snake.h b/src/JungleLvl/private/snake.h index e357550..d45c228 100644 --- a/src/JungleLvl/private/snake.h +++ b/src/JungleLvl/private/snake.h @@ -23,12 +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: - 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(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/src/JungleLvl/private/world.cpp b/src/JungleLvl/private/world.cpp index b036387..7005a19 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; } @@ -104,11 +104,11 @@ 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 { +CRAWL::PlayableObject *World::initPlayer(int) const { return new Snake(); } @@ -116,6 +116,14 @@ CRAWL::IAI *World::initBackGroundAI() const { return IWorld::initBackGroundAI(); } +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 98bf398..063a7e6 100644 --- a/src/JungleLvl/private/world.h +++ b/src/JungleLvl/private/world.h @@ -22,13 +22,15 @@ 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; + void initControl(CRAWL::IControl *control) override; + CRAWL::PlayableObject *initPlayer(int) 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 219c0e6..d9baa3a 100644 --- a/tests/units/clasterstest.cpp +++ b/tests/units/clasterstest.cpp @@ -45,13 +45,15 @@ 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(int) 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";}; + int requiredTier() const override {return 0;}; friend class ClastersTest; }; 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() { 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. */