chore: Init

master
NaiJi ✨ 1 year ago
commit 716544321a

2
.gitignore vendored

@ -0,0 +1,2 @@
*.pro.user
*.autosave

@ -0,0 +1,120 @@
#-------------------------------------------------
#
# Project created by QtCreator 2018-02-10T20:30:04
#
#-------------------------------------------------
VERSION = 0.0.1
CONFIG += c++17
QMAKE_CXXFLAGS = -Wall -Werror -Wextra -Wpedantic -Wconversion -std=c++17 -O2 -g
QT += core gui multimedia widgets quickwidgets
# Potato22 is the best vector artist, you can't change my mind.
# The icon is precious!
RC_FILE += add_ico.rc
TARGET = QuestWizard
TEMPLATE = app
DEFINES += QT_DEPRECATED_WARNINGS
SOURCES += main.cpp \
game.cpp \
features/qw_abstractdialoguemanager.cpp \
features/qw_dialoguefactory.cpp \
features/qw_textdialoguemanager.cpp \
features/qw_widgetdialoguemanager.cpp \
features/qw_eventfactory.cpp \
features/qw_inventorymanager.cpp \
features/qw_levelbuilder.cpp \
features/qw_soundplayer.cpp \
features/qw_statemachine.cpp \
qw_globalmetadata.cpp \
\
models/events/qw_abstractevent.cpp \
models/events/qw_abstractinventoryevent.cpp \
models/events/qw_abstractlevelevent.cpp \
models/events/qw_abstractsceneevent.cpp \
models/events/qw_abstractsoundevent.cpp \
models/events/qw_changelocationevent.cpp \
models/events/qw_changetriggerpropertiesevent.cpp \
models/events/qw_deletefrominventoryevent.cpp \
models/events/qw_endlevelevent.cpp \
models/events/qw_newgameevent.cpp \
models/events/qw_pickupitemevent.cpp \
models/events/qw_playmusicevent.cpp \
models/events/qw_playsoundevent.cpp \
models/events/qw_quitgameevent.cpp \
models/events/qw_startdialogueevent.cpp \
models/events/qw_addtriggerevent.cpp \
models/events/qw_removetriggerevent.cpp \
models/events/qw_switcheventsevent.cpp \
models/dialogues/qw_abstractgamedialogue.cpp \
models/dialogues/qw_textdialogue.cpp \
models/dialogues/qw_widgetdialogue.cpp \
models/qw_tagholder.cpp \
models/qw_trigger.cpp \
models/qw_location.cpp \
\
view/controls/pushbuttonsound.cpp \
view/controls/qw_abstractscenecontrol.cpp \
view/controls/scenedialoguepanel.cpp \
view/controls/sceneinventorypanel.cpp \
\
view/qw_scene.cpp \
view/qw_view.cpp
HEADERS += \
game.h \
features/qw_abstractdialoguemanager.h \
features/gamefeatures.h \
features/qw_dialoguefactory.h \
features/qw_textdialoguemanager.h \
features/qw_widgetdialoguemanager.h \
features/qw_eventfactory.h \
features/qw_inventorymanager.h \
features/qw_levelbuilder.h \
features/qw_soundplayer.h \
features/qw_statemachine.h \
qw_globalmetadata.h \
\
models/events/qw_abstractevent.h \
models/events/qw_abstractinventoryevent.h \
models/events/qw_abstractlevelevent.h \
models/events/qw_abstractsceneevent.h \
models/events/qw_abstractsoundevent.h \
models/events/qw_changelocationevent.h \
models/events/qw_changetriggerpropertiesevent.h \
models/events/qw_deletefrominventoryevent.h \
models/events/qw_endlevelevent.h \
models/events/qw_newgameevent.h \
models/events/qw_pickupitemevent.h \
models/events/qw_playmusicevent.h \
models/events/qw_playsoundevent.h \
models/events/qw_quitgameevent.h \
models/events/qw_startdialogueevent.h \
models/events/qw_addtriggerevent.h \
models/events/qw_removetriggerevent.h \
models/events/qw_switcheventsevent.h \
models/dialogues/qw_abstractgamedialogue.h \
models/dialogues/qw_textdialogue.h \
models/dialogues/qw_widgetdialogue.h \
models/qw_tagholder.h \
models/qw_trigger.h \
models/qw_location.h \
\
view/controls/pushbuttonsound.h \
view/controls/qw_abstractscenecontrol.h \
view/controls/scenedialoguepanel.h \
view/controls/sceneinventorypanel.h \
\
view/qw_scene.h \
view/qw_view.h
RESOURCES += \
application.qrc
DISTFILES += \
qml/test.qml

@ -0,0 +1,3 @@
# QuestWizard
I am not really sure what this thing is going to be but anyway here is trello where I try to manage stuff
https://trello.com/b/M3kqOaDB/questwizard-functional-requirements?menu=filter&filter=label:master-merge%201.1

@ -0,0 +1 @@
IDI_ICON1 ICON DISCARDABLE "icon.ico"

@ -0,0 +1,17 @@
<RCC>
<qresource prefix="/">
<file>res/levels/level1.json</file>
<file>res/defaultsave.json</file>
<file>res/menu.json</file>
<file>res/final_background.jpg</file>
<file>res/roomkey_background.jpg</file>
<file>res/spawn_background.jpg</file>
<file>res/cell.png</file>
<file>res/door.png</file>
<file>res/inv.jpg</file>
<file>res/dialogue_panel.jpeg</file>
<file>res/sound.wav</file>
<file>res/osaka.png</file>
<file>res/config.json</file>
</qresource>
</RCC>

@ -0,0 +1,41 @@
#ifndef GAMEFEATURES_H
#define GAMEFEATURES_H
#include "game.h"
#include "qw_levelbuilder.h"
#include "qw_soundplayer.h"
#include "qw_inventorymanager.h"
#include "qw_textdialoguemanager.h"
#include "qw_widgetdialoguemanager.h"
#include "view/qw_view.h"
/* GameFeatures
* The package of all key in-game managers. This way they are easy to transport. */
struct GameFeatures final
{
public:
QWView *ptr_view;
QWScene *ptr_scene;
QWSoundPlayer *ptr_sound_player;
QWInventoryManager *ptr_inventory;
QWLevelBuilder *ptr_builder;
QWTextDialogueManager *ptr_text_dlg;
QWWidgetDialogueManager *ptr_widget_dlg;
explicit GameFeatures(Game *ptr_game)
{
ptr_scene = new QWScene(1280, 720);
ptr_view = new QWView(ptr_scene);
ptr_sound_player = new QWSoundPlayer(ptr_game);
ptr_inventory = new QWInventoryManager(ptr_scene);
ptr_builder = new QWLevelBuilder(ptr_game);
ptr_text_dlg = new QWTextDialogueManager(ptr_scene);
ptr_widget_dlg = new QWWidgetDialogueManager(ptr_scene);
}
~GameFeatures() = default;
};
#endif // GAMEFEATURES_H

@ -0,0 +1,9 @@
#include "qw_abstractdialoguemanager.h"
QWAbstractDialogueManager:: QWAbstractDialogueManager(QWScene *scene) :
QObject(scene),
ptr_scene(scene)
{}
QWAbstractDialogueManager::~QWAbstractDialogueManager()
{}

@ -0,0 +1,29 @@
#ifndef QWABSTRACTDIALOGUEMANAGER_H
#define QWABSTRACTDIALOGUEMANAGER_H
#include <QObject>
#include "view/qw_scene.h"
#include "models/dialogues/qw_abstractgamedialogue.h"
class QWAbstractDialogueManager : public QObject
{
Q_OBJECT
Q_DISABLE_COPY_MOVE(QWAbstractDialogueManager)
protected:
QWScene *ptr_scene;
public:
explicit QWAbstractDialogueManager(QWScene *scene = nullptr);
virtual ~QWAbstractDialogueManager() override = 0;
virtual void activateDialogue(const std::shared_ptr<QWAbstractGameDialogue> &dialogue) = 0;
public slots:
virtual void onClicked(MouseButton mouse_button) = 0;
signals:
void onEntryDialogueTransition();
void onLeaveDialogueTransition();
};
#endif // QWABSTRACTDIALOGUEMANAGER_H

@ -0,0 +1,39 @@
#include "qw_dialoguefactory.h"
#include "qw_levelbuilder.h"
QWDialogueFactory::QWDialogueFactory(QWLevelBuilder *b) :
builder(b)
{}
std::shared_ptr<QWTextDialogue> QWDialogueFactory::createTextDialogue(const QJsonObject &json_object)
{
std::unique_ptr<QWTextDialogue> new_dialogue;
qDebug() << " Found QWTextDialogue. " << json_object["id"].toString() << ".";
Q_ASSERT(json_object.contains("text"));
QStringList text;
const QJsonArray text_pages = json_object["text"].toArray();
for (auto const &page : text_pages)
text << page.toString();
// add events on leave or something
new_dialogue = std::make_unique<QWTextDialogue>(text);
return std::shared_ptr<QWTextDialogue>{std::move(new_dialogue)};
}
std::shared_ptr<QWWidgetDialogue> QWDialogueFactory::createWidgetDialogue(const QJsonObject &json_object)
{
std::unique_ptr<QWWidgetDialogue> new_dialogue;
qDebug() << " Found QWWidgetDialogue. " << json_object["id"].toString() << ".";
Q_ASSERT(json_object.contains("qml_filename"));
new_dialogue = std::make_unique<QWWidgetDialogue>(json_object["qml_filename"].toString());
return std::shared_ptr<QWWidgetDialogue>{std::move(new_dialogue)};
}

@ -0,0 +1,24 @@
#ifndef QWDIALOGUEFACTORY_H
#define QWDIALOGUEFACTORY_H
#include "models/dialogues/qw_textdialogue.h"
#include "models/dialogues/qw_widgetdialogue.h"
/* QWDialogueFactory
* Creates game dialogues of all kinds! */
class QWLevelBuilder;
class QWDialogueFactory final
{
private:
QWLevelBuilder *builder;
public:
explicit QWDialogueFactory(QWLevelBuilder *b);
std::shared_ptr<QWTextDialogue> createTextDialogue(const QJsonObject &json_object);
std::shared_ptr<QWWidgetDialogue> createWidgetDialogue(const QJsonObject &json_object);
};
#endif // QWDIALOGUEFACTORY_H

@ -0,0 +1,221 @@
#include "qw_eventfactory.h"
#include "qw_levelbuilder.h"
#include "qw_widgetdialoguemanager.h"
#include "qw_textdialoguemanager.h"
QWEventFactory::QWEventFactory(QWLevelBuilder *b) :
builder(b)
{}
std::shared_ptr<QWDeleteFromInventoryEvent> QWEventFactory::createDeleteItEvent(const QJsonObject &json_object)
{
std::unique_ptr<QWDeleteFromInventoryEvent> new_event;
qDebug() << " Found QWDeleteFromInventoryEvent. " << json_object["id"].toString() << ".";
Q_ASSERT(json_object.contains("target"));
Q_ASSERT(builder->hash_triggers.contains(json_object["target"].toString()));
new_event = std::make_unique<QWDeleteFromInventoryEvent>(builder->hash_triggers[json_object["target"].toString()]);
new_event->setInventoryManager(builder->ptr_inventory);
return std::shared_ptr<QWDeleteFromInventoryEvent>{std::move(new_event)};
}
std::shared_ptr<QWChangeLocationEvent> QWEventFactory::createChangeLocEvent(const QJsonObject &json_object)
{
std::unique_ptr<QWChangeLocationEvent> new_event;
qDebug() << " Found QWChangeLocationEvent. " << json_object["id"].toString() << ".";
Q_ASSERT(json_object.contains("location"));
Q_ASSERT(builder->hash_locations.contains(json_object["location"].toString()));
new_event = std::make_unique<QWChangeLocationEvent>(builder->hash_locations[json_object["location"].toString()]);
new_event->setScene(builder->ptr_scene);
return std::shared_ptr<QWChangeLocationEvent>{std::move(new_event)};
}
std::shared_ptr<QWChangeTriggerPropertiesEvent> QWEventFactory::createChangeTrProperts(const QJsonObject &json_object)
{
std::unique_ptr<QWChangeTriggerPropertiesEvent> new_event;
qDebug() << " Found QWChangeTriggerPropertiesEvent. " << json_object["id"].toString() << ".";
Q_ASSERT(json_object.contains("target"));
Q_ASSERT(builder->hash_triggers.contains(json_object["target"].toString()));
new_event = std::make_unique<QWChangeTriggerPropertiesEvent>(builder->hash_triggers[json_object["target"].toString()]);
if (json_object.contains("x") && json_object.contains("y"))
new_event->setParams(json_object["x"].toDouble(), json_object["y"].toDouble(),
json_object.contains("path") ? json_object["path"].toString() : "$no_pic");
else
new_event->setParams(json_object.contains("path") ? json_object["path"].toString() : "$no_pic");
return std::shared_ptr<QWChangeTriggerPropertiesEvent>{std::move(new_event)};
}
std::shared_ptr<QWSwitchEventsEvent> QWEventFactory::createSwitchEventsEvent(const QJsonObject &json_object)
{
std::unique_ptr<QWSwitchEventsEvent> new_event;
qDebug() << " Found QWSwitchEventsEvent. " << json_object["id"].toString() << ".";
Q_ASSERT(json_object.contains("target"));
Q_ASSERT(builder->hash_triggers.contains(json_object["target"].toString()));
new_event = std::make_unique<QWSwitchEventsEvent>(builder->hash_triggers[json_object["target"].toString()]);
Q_ASSERT(json_object.contains("enable_evs") && json_object.contains("disable_evs"));
// Linking events of enabled state
QJsonArray evs = json_object["enable_evs"].toArray();
QList<std::shared_ptr<QWAbstractEvent>> list_events;
for (const auto obj : evs) {
Q_ASSERT(builder->hash_events.contains(obj.toString()));
list_events.append(builder->hash_events[obj.toString()]);
}
new_event->setEventsOnEnable(list_events);
list_events.clear();
// Linking events of disabled state
evs = json_object["disable_evs"].toArray();
for (const auto obj : evs) {
Q_ASSERT(builder->hash_events.contains(obj.toString()));
list_events.append(builder->hash_events[obj.toString()]);
}
new_event->setEventsOnDisable(list_events);
new_event->init();
return std::shared_ptr<QWSwitchEventsEvent>{std::move(new_event)};
}
std::shared_ptr<QWPickupItemEvent> QWEventFactory::createPickupItEvent(const QJsonObject &json_object)
{
std::unique_ptr<QWPickupItemEvent> new_event;
qDebug() << " Found QWPickupItemEvent. " << json_object["id"].toString() << ".";
Q_ASSERT(json_object.contains("target"));
Q_ASSERT(builder->hash_triggers.contains(json_object["target"].toString()));
new_event = std::make_unique<QWPickupItemEvent>(builder->hash_triggers[json_object["target"].toString()]);
new_event->setInventoryManager(builder->ptr_inventory);
return std::shared_ptr<QWPickupItemEvent>{std::move(new_event)};
}
std::shared_ptr<QWEndLevelEvent> QWEventFactory::createEndLevelEvent(const QJsonObject &json_object)
{
std::unique_ptr<QWEndLevelEvent> new_event;
qDebug() << " Found QWEndLevelEvent. " << json_object["id"].toString() << ".";
Q_ASSERT(json_object.contains("new_level"));
new_event = std::make_unique<QWEndLevelEvent>(json_object["target"].toString());
new_event->setLevelBuilder(builder);
return std::shared_ptr<QWEndLevelEvent>{std::move(new_event)};
}
std::shared_ptr<QWPlaySoundEvent> QWEventFactory::createPlaySoundEvent(const QJsonObject &json_object)
{
std::unique_ptr<QWPlaySoundEvent> new_event;
qDebug() << " Found QWPlaySoundEvent. " << json_object["id"].toString() << ".";
Q_ASSERT(json_object.contains("sound"));
new_event = std::make_unique<QWPlaySoundEvent>(json_object["sound"].toString());
new_event->setSoundPlayer(builder->ptr_soundplayer);
return std::shared_ptr<QWPlaySoundEvent>{std::move(new_event)};
}
std::shared_ptr<QWNewGameEvent> QWEventFactory::createNewGameEvent(const QJsonObject &json_object)
{
std::unique_ptr<QWNewGameEvent> new_event;
qDebug() << " Found QWNewGameEvent. " << json_object["id"].toString() << ".";
Q_ASSERT(json_object.contains("save_file"));
new_event = std::make_unique<QWNewGameEvent>(json_object["save_file"].toString());
new_event->setLevelBuilder(builder);
return std::shared_ptr<QWNewGameEvent>{std::move(new_event)};
}
std::shared_ptr<QWQuitGameEvent> QWEventFactory::createQuitGameEvent(const QJsonObject &json_object)
{
std::unique_ptr<QWQuitGameEvent> new_event;
qDebug() << " Found QWQuitGameEvent. " << json_object["id"].toString() << ".";
Q_ASSERT(json_object.contains("save_game"));
new_event = std::make_unique<QWQuitGameEvent>(json_object["save_game"].toBool());
new_event->setLevelBuilder(builder);
return std::shared_ptr<QWQuitGameEvent>{std::move(new_event)};
}
std::shared_ptr<QWStartDialogueEvent> QWEventFactory::createStartDlgEvent(const QJsonObject &json_object)
{
std::unique_ptr<QWStartDialogueEvent> new_event;
qDebug() << " Found QWStartTextDialogueEvent. " << json_object["id"].toString() << ".";
Q_ASSERT(json_object.contains("dialogue"));
Q_ASSERT(json_object.contains("dialogue_type"));
Q_ASSERT(builder->hash_dialogues.contains(json_object["dialogue"].toString()));
new_event = std::make_unique<QWStartDialogueEvent>(builder->hash_dialogues[json_object["dialogue"].toString()]);
switch(json_object["dialogue_type"].toInt()) {
case 1:
new_event->setDialogueManager(builder->ptr_widget_dlg);
break;
case 0:
new_event->setDialogueManager(builder->ptr_text_dlg);
break;
default:
Q_ASSERT(false);
}
return std::shared_ptr<QWStartDialogueEvent>{std::move(new_event)};
}
std::shared_ptr<QWAddTriggerEvent> QWEventFactory::createAddTrEvent(const QJsonObject &json_object)
{
std::unique_ptr<QWAddTriggerEvent> new_event;
qDebug() << " Found QWAddTriggerEvent. " << json_object["id"].toString() << ".";
Q_ASSERT(json_object.contains("trigger"));
Q_ASSERT(builder->hash_triggers.contains(json_object["trigger"].toString()));
new_event = std::make_unique<QWAddTriggerEvent>(builder->hash_triggers[json_object["trigger"].toString()]);
Q_ASSERT(json_object.contains("location"));
Q_ASSERT(builder->hash_locations.contains(json_object["location"].toString()));
new_event->setLocation(builder->hash_locations[json_object["location"].toString()]);
return std::shared_ptr<QWAddTriggerEvent>{std::move(new_event)};
}
std::shared_ptr<QWRemoveTriggerEvent> QWEventFactory::createRemoveTrEvent(const QJsonObject &json_object)
{
std::unique_ptr<QWRemoveTriggerEvent> new_event;
qDebug() << " Found QWRemoveTriggerEvent. " << json_object["id"].toString() << ".";
Q_ASSERT(json_object.contains("trigger"));
Q_ASSERT(builder->hash_triggers.contains(json_object["trigger"].toString()));
new_event = std::make_unique<QWRemoveTriggerEvent>(builder->hash_triggers[json_object["trigger"].toString()]);
Q_ASSERT(json_object.contains("location"));
Q_ASSERT(builder->hash_locations.contains(json_object["location"].toString()));
new_event->setLocation(builder->hash_locations[json_object["location"].toString()]);
return std::shared_ptr<QWRemoveTriggerEvent>{std::move(new_event)};
}

@ -0,0 +1,48 @@
#ifndef EVENTFACTORY_H
#define EVENTFACTORY_H
#include <QJsonObject>
#include <QJsonArray>
#include "models/events/qw_abstractevent.h"
#include "models/events/qw_changelocationevent.h"
#include "models/events/qw_switcheventsevent.h"
#include "models/events/qw_deletefrominventoryevent.h"
#include "models/events/qw_pickupitemevent.h"
#include "models/events/qw_endlevelevent.h"
#include "models/events/qw_playsoundevent.h"
#include "models/events/qw_changetriggerpropertiesevent.h"
#include "models/events/qw_newgameevent.h"
#include "models/events/qw_quitgameevent.h"
#include "models/events/qw_startdialogueevent.h"
#include "models/events/qw_addtriggerevent.h"
#include "models/events/qw_removetriggerevent.h"
/* QWEventFactory
* Creates game events of all kinds! */
class QWLevelBuilder;
class QWEventFactory final
{
private:
QWLevelBuilder *builder;
public:
explicit QWEventFactory(QWLevelBuilder *b);
std::shared_ptr<QWDeleteFromInventoryEvent> createDeleteItEvent(const QJsonObject &json_object);
std::shared_ptr<QWChangeLocationEvent> createChangeLocEvent(const QJsonObject &json_object);
std::shared_ptr<QWChangeTriggerPropertiesEvent> createChangeTrProperts(const QJsonObject &json_object);
std::shared_ptr<QWSwitchEventsEvent> createSwitchEventsEvent(const QJsonObject &json_object);
std::shared_ptr<QWPickupItemEvent> createPickupItEvent(const QJsonObject &json_object);
std::shared_ptr<QWEndLevelEvent> createEndLevelEvent(const QJsonObject &json_object);
std::shared_ptr<QWPlaySoundEvent> createPlaySoundEvent(const QJsonObject &json_object);
std::shared_ptr<QWNewGameEvent> createNewGameEvent(const QJsonObject &json_object);
std::shared_ptr<QWQuitGameEvent> createQuitGameEvent(const QJsonObject &json_object);
std::shared_ptr<QWStartDialogueEvent> createStartDlgEvent(const QJsonObject &json_object);
std::shared_ptr<QWAddTriggerEvent> createAddTrEvent(const QJsonObject &json_object);
std::shared_ptr<QWRemoveTriggerEvent> createRemoveTrEvent(const QJsonObject &json_object);
};
#endif // EVENTFACTORY_H

@ -0,0 +1,94 @@
#include "qw_inventorymanager.h"
#include "qw_globalmetadata.h"
#include "view/controls/sceneinventorypanel.h"
#include "view/qw_scene.h"
#include "models/qw_trigger.h"
QWInventoryManager::QWInventoryManager(QWScene *sc) :
ptr_scene(sc),
index_freepan(0)
{
// Loading metadata
metadata.length_wall = QWGlobalMetadata::valueBy("InventoryManager:length_wall").toInt();
metadata.length_cell = QWGlobalMetadata::valueBy("InventoryManager:length_cell").toInt();
metadata.max_amount = QWGlobalMetadata::valueBy("InventoryManager:max_amount").toInt();
metadata.first_wall = QWGlobalMetadata::valueBy("InventoryManager:first_wall").toInt();
metadata.clr_sel = Qt::GlobalColor(QWGlobalMetadata::valueBy("InventoryManager:clr_sel").toInt());
metadata.clr_sth = QWGlobalMetadata::valueBy("InventoryManager:clr_str").toReal();
item_selected_effect = new QGraphicsColorizeEffect();
item_selected_effect->setColor(metadata.clr_sel);
item_selected_effect->setStrength(metadata.clr_sth);
}
void QWInventoryManager::setInventoryPanel(const std::shared_ptr<QGraphicsWidget> &panel) noexcept
{
ptr_panel = panel;
}
int QWInventoryManager::freePanel() const noexcept
{
return index_freepan;
}
void QWInventoryManager::freePanelToRight()
{
++index_freepan;
Q_ASSERT(index_freepan <= metadata.max_amount);
}
void QWInventoryManager::freePanelToLeft()
{
--index_freepan;
Q_ASSERT(index_freepan >= 0);
}
void QWInventoryManager::addInventoryIcon(std::shared_ptr<QWTrigger> &inventory_icon)
{
inventory_icon->setParentItem(ptr_panel.get());
list_inventory_icons.append(inventory_icon);
inventory_icon->setPos(metadata.first_wall
+ ((metadata.length_wall + metadata.length_cell)
* freePanel())
, 0);
freePanelToRight();
}
void QWInventoryManager::removeInventoryIcon(std::shared_ptr<QWTrigger> &inventory_icon)
{
Index panel = metadata.max_amount + 1;
for (Index i = 0; i < list_inventory_icons.size(); ++i)
if (inventory_icon == list_inventory_icons[i])
panel = i;
Q_ASSERT(panel <= metadata.max_amount);
ptr_scene->removeItem(inventory_icon.get());
list_inventory_icons.removeAt(panel);
freePanelToLeft();
reorganizeItems(panel);
}
void QWInventoryManager::reorganizeItems(Index free_panel)
{
// When we remove item from the center we also should carefully move all the right items to the left
for (Index j = free_panel; j < list_inventory_icons.size(); ++j)
{
const std::shared_ptr<QWTrigger> &t = list_inventory_icons.at(j);
t->moveBy(-(metadata.length_cell + metadata.length_wall), 0);
if (j > 0)
list_inventory_icons[j-1] = list_inventory_icons[j];
}
}
void QWInventoryManager::onClicked()
{
for (auto &tr : list_inventory_icons)
if (tr->isUnderMouse()) {
tr->setGraphicsEffect(tr->graphicsEffect() ? nullptr : item_selected_effect);
tr->activate();
} else {
tr->setGraphicsEffect(nullptr);
}
}

@ -0,0 +1,67 @@
#ifndef INVENTORYMANAGER_H
#define INVENTORYMANAGER_H
#include <memory>
#include <QGraphicsColorizeEffect>
/* QWInventoryManager
* Controls everything related to inventory slots and their items. */
class QGraphicsWidget;
class QWScene;
class QWTrigger;
class QWInventoryManager final : public QObject
{
Q_OBJECT
Q_DISABLE_COPY_MOVE(QWInventoryManager)
private:
QList<std::shared_ptr<QWTrigger>> list_inventory_icons;
std::shared_ptr<QGraphicsWidget> ptr_panel;
QWScene *ptr_scene;
QRect rect_hidden;
QRect rect_visible;
using Index = QList<std::shared_ptr<QWTrigger>>::size_type;
Index index_freepan;
QGraphicsColorizeEffect *item_selected_effect;
struct metadata
{
// the separator thinkness
int length_wall;
// the cell side
int length_cell;
// the maximum amount of items to hold
int max_amount;
// the left wall of first item slot
int first_wall;
// the color for selected items
QColor clr_sel;
// the color for selected items
qreal clr_sth;
} metadata;
void reorganizeItems(Index i);
public:
explicit QWInventoryManager(QWScene *sc);
void setInventoryPanel(const std::shared_ptr<QGraphicsWidget> &panel) noexcept;
inline int freePanel() const noexcept;
inline void freePanelToRight();
inline void freePanelToLeft();
void addInventoryIcon(std::shared_ptr<QWTrigger> &inventory_icon);
void removeInventoryIcon(std::shared_ptr<QWTrigger> &inventory_icon);
public slots:
void onClicked();
};
#endif // INVENTORYMANAGER_H

@ -0,0 +1,470 @@
#include <QDebug>
#include "gamefeatures.h"
#include "qw_levelbuilder.h"
#include "qw_eventfactory.h"
#include "qw_dialoguefactory.h"
#include "qw_globalmetadata.h"
#include "view/qw_scene.h"
#include "models/qw_location.h"
#include "models/qw_trigger.h"
QWLevelBuilder::QWLevelBuilder(QObject *parent) :
QObject(parent),
str_current_level(strInitLevel())
{
// Dir for local save files
if (!QDir("save").exists()) {
QDir().mkdir("save");
}
save_dir.setPath("save");
}
template<typename MODEL>
QJsonArray writeEntitesToJsonArray(const QHash<QString, std::shared_ptr<MODEL>> &hash_models)
{
// Writing in active save file all the game elements and their state
QJsonArray json_array;
for (const auto &model : hash_models)
{
QJsonObject model_data;
model->writeToJson(model_data);
json_array.append(model_data);
}
return json_array;
}
void QWLevelBuilder::initMenuLevel()
{
str_current_level = "menu";
QFile file(":/res/menu.json");
Q_ASSERT(file.open(QIODevice::ReadOnly));
const QByteArray json_arr = file.readAll();
file.close();
QJsonObject savefile = QJsonDocument::fromJson(json_arr).object();
init(savefile);
}
void QWLevelBuilder::initSaveProfile(const QString &filename, const QString &profilename)
{
Q_UNUSED(profilename)
// Creating inital save file after beginning the new game:
str_profile_filename = filename;
str_current_level = strInitLevel();
QFile file;
str_profile_filename.remove(".json");
// We move default game description to player's save file
file.setFileName(save_dir.path() + "/" + str_profile_filename + ".json");
qDebug() << save_dir.path() + "/" + str_profile_filename + ".json";
if (!file.exists()) {
qDebug() << "copy file";
QFile::copy(":/res/defaultsave.json", file.fileName());
}
// Now we modify default json file to add the chosen profile name
/*Q_ASSERT(file.open(QIODevice::ReadOnly));
const QByteArray json_arr = file.readAll();
file.close();
QJsonObject savefile = QJsonDocument::fromJson(json_arr).object();
// Pull the saved string from new game dialogue
str_current_profile = profilename;
savefile.insert("save_profile", str_current_profile);
// Write it and resave
Q_ASSERT(file.open(QIODevice::WriteOnly));
file.write(QJsonDocument(savefile).toJson());
file.close();*/
}
void QWLevelBuilder::saveGame(/*QString filename*/)
{
qDebug() << "Save current game!";
QJsonObject savejson;
QJsonArray json_entites;
/* The first Trigger which moves player into its
* needed location where the game starts */
savejson.insert("init", "spawn");
savejson.insert("save_profile", str_current_profile);
qDebug() << "Save triggers!";
json_entites = writeEntitesToJsonArray(hash_triggers);
savejson.insert("triggers", json_entites);
qDebug() << "Save dialogues!";
json_entites = writeEntitesToJsonArray(hash_dialogues);
savejson.insert("dialogues", json_entites);
qDebug() << "Save locations!";
json_entites = writeEntitesToJsonArray(hash_locations);
savejson.insert("locations", json_entites);
qDebug() << "Save events!";
json_entites = writeEntitesToJsonArray(hash_events);
// Creating the inital event where player must appear after game loading
QJsonObject init_spawn_data;
QStringList trs;
for (auto & tr : ptr_scene->currentLocation()->triggers())
trs << tr->tag();
QList<std::shared_ptr<QWTrigger>> list_triggers;
init_spawn_data.insert("id", "spawn");
init_spawn_data.insert("type", 0);
init_spawn_data.insert("trs", QJsonArray::fromStringList(trs));
json_entites.append(init_spawn_data);
savejson.insert("events", json_entites);
// - - - //
QFile file(save_dir.dirName() + "/" + str_profile_filename + ".json");
Q_ASSERT(file.open(QIODevice::ReadOnly));
const QByteArray json_arr = file.readAll();
file.close();
QJsonObject savefile = QJsonDocument::fromJson(json_arr).object();
savefile[str_current_level] = savejson;
Q_ASSERT(file.open(QIODevice::WriteOnly));
file.write(QJsonDocument(savejson).toJson());
file.close();
}
void QWLevelBuilder::loadGame(/*QString filename*/)
{
QFile file;
hash_events.clear();
hash_triggers.clear();
hash_dialogues.clear();
hash_locations.clear();
init_trigger.reset();
file.setFileName(save_dir.dirName() + "/" + str_profile_filename + ".json");
file.open(QIODevice::ReadOnly);
const QByteArray json_arr = file.readAll();
file.close();
QJsonObject savefile = QJsonDocument::fromJson(json_arr).object();
str_current_level = savefile["init_level"].toString();
init(savefile);
}
void QWLevelBuilder::initLevel(const QString &lvlname)
{
str_current_level = lvlname;
QFile file(save_dir.dirName() + "/" + str_profile_filename + ".json");
Q_ASSERT(file.open(QIODevice::ReadOnly));
const QByteArray json_arr = file.readAll();
file.close();
emit ptr_scene->signalLeaveMenu();
QJsonObject savefile = QJsonDocument::fromJson(json_arr).object();
init(savefile);
}
void QWLevelBuilder::init(const QJsonObject & savefile)
{
qDebug() << "Init " << str_current_level << " level!";
hash_events.clear();
hash_triggers.clear();
init_trigger.reset();
level = savefile[str_current_level].toObject();
Q_ASSERT(!level.isEmpty());
// Building level from current json
if (level.contains("triggers"))
setupTriggers(level["triggers"].toArray());
if (level.contains("dialogues"))
setupDialogues(level["dialogues"].toArray());
if (level.contains("locations"))
setupLocations(level["locations"].toArray());
if (level.contains("events"))
setupEvents(level["events"].toArray());
linkEvents(level["triggers"].toArray());
init_trigger = level.contains("init") ? hash_triggers[level["init"].toString()] : nullptr;
// Start the level
Q_ASSERT(init_trigger);
init_trigger->activate();
}
QString QWLevelBuilder::strInitLevel() noexcept
{
return "start";
}
void QWLevelBuilder::setGameFeatures(std::unique_ptr<GameFeatures> &features)
{
ptr_scene = features->ptr_scene;
ptr_inventory = features->ptr_inventory;
ptr_soundplayer = features->ptr_sound_player;
ptr_text_dlg = features->ptr_text_dlg;
ptr_widget_dlg = features->ptr_widget_dlg;
}
void QWLevelBuilder::linkEvents(const QJsonArray &array)
{
qDebug() << "Link the events to triggers!";
for (const QJsonValue &json_value : array)
{
QJsonObject json_object(json_value.toObject());
if (json_object.contains("evs"))
{
qDebug() << " Trigger " << json_object["id"].toString() << " contains events!";
QJsonArray evs = json_object["evs"].toArray();
for (const QJsonValue event : evs)
{
QString obj = event.toString();
qDebug() << " Inserting " << obj << " to its trigger!";
hash_triggers[json_object["id"].toString()]->addEvents(hash_events[obj]);
qDebug() << " Success!";
}
}
if (json_object.contains("examine_dialogue"))
{
qDebug() << " Trigger " << json_object["id"].toString() << " contains examination dialogue!";
const QString dialogue_tag = json_object["examine_dialogue"].toString();
hash_triggers[json_object["id"].toString()]->setExaminationDialogueEvent(hash_events[dialogue_tag]);
}
}
}
// * * * * * * * * * * * * * * SETUP STUFF * * * * * * * * * * * * * *
//
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
void QWLevelBuilder::setupTriggers(const QJsonArray &array)
{
qDebug() << "Setup the triggers!";
QJsonObject json_object;
for (const QJsonValue &json_value : array)
{
json_object = json_value.toObject();
std::shared_ptr<QWTrigger> new_trigger;
// check if the picture exists!
Q_ASSERT(json_object.contains("id"));
QString mask = json_object.contains("mask") ? json_object["mask"].toString() : json_object["id"].toString();
new_trigger = std::make_shared<QWTrigger>(mask);
new_trigger->setTag(json_object["id"].toString());
qDebug() << "! The trigger with id " << json_object["id"].toString() << " was created.";
// setup the position on the scene
if (json_object.contains("x") && json_object.contains("y")) {
new_trigger->setPos(json_object["x"].toDouble(), json_object["y"].toDouble());
qDebug() << " The trigger was moved to "
<< new_trigger->x() << " " << new_trigger->y();
}
hash_triggers.insert(json_object["id"].toString(), new_trigger);
qDebug() << " The trigger was inserted into its map.\n - - -";
}
}
void QWLevelBuilder::setupEvents(const QJsonArray &array)
{
qDebug() << "Setup the events!";
std::unique_ptr<QWEventFactory> factory = std::make_unique<QWEventFactory>(this);
QJsonObject json_object;
QList<QJsonObject> list_later_events;
for (const QJsonValue &json_value : array)
{
json_object = json_value.toObject();
std::shared_ptr<QWAbstractEvent> new_event;
// check if the id exists!
Q_ASSERT(json_object.contains("id"));
qDebug() << "! The event with id " << json_object["id"].toString() << " is about to create.";
// independent events
Q_ASSERT(json_object.contains("type"));
int type = json_object["type"].toInt();
switch (type)
{
case (EVENT_TYPE::CHANGE_LOCATION):
new_event = factory->createChangeLocEvent(json_object);
break;
case (EVENT_TYPE::DELETE_FROM_INVENTORY):
new_event = factory->createDeleteItEvent(json_object);
break;
case (EVENT_TYPE::PICKUP_ITEM):
new_event = factory->createPickupItEvent(json_object);
break;
case (EVENT_TYPE::END_LEVEL):
new_event = factory->createEndLevelEvent(json_object);
break;
case (EVENT_TYPE::CHANGE_TRIGGER_PROPERTIES):
new_event = factory->createChangeTrProperts(json_object);
break;
case (EVENT_TYPE::NEW_GAME):
new_event = factory->createNewGameEvent(json_object);
break;
case (EVENT_TYPE::QUIT_GAME):
new_event = factory->createQuitGameEvent(json_object);
break;
case (EVENT_TYPE::START_DIALOGUE):
new_event = factory->createStartDlgEvent(json_object);
break;
case (EVENT_TYPE::ADD_TRIGGER):
new_event = factory->createAddTrEvent(json_object);
break;
case (EVENT_TYPE::REMOVE_TRIGGER):
new_event = factory->createRemoveTrEvent(json_object);
break;
default:
list_later_events.append(json_object);
continue;
}
new_event->setTag(json_object["id"].toString());
hash_events.insert(json_object["id"].toString(), new_event);
}
// Some events work with other events, so we need to initialize all
// independent events earlier than these
for (const auto &later_event : list_later_events) {
int type = later_event["type"].toInt();
std::shared_ptr<QWAbstractEvent> new_event;
switch (type)
{
case (EVENT_TYPE::SWITCH_EVENTS): // switch events
new_event = factory->createSwitchEventsEvent(later_event);
break;
default:
Q_ASSERT(false);
continue;
}
new_event->setTag(later_event["id"].toString());
hash_events.insert(later_event["id"].toString(), new_event);
}
}
void QWLevelBuilder::setupDialogues(const QJsonArray &array)
{
qDebug() << "Setup the dialogues!";
std::unique_ptr<QWDialogueFactory> factory = std::make_unique<QWDialogueFactory>(this);
QJsonObject json_object;
for (const QJsonValue &json_value : array)
{
json_object = json_value.toObject();
std::shared_ptr<QWAbstractGameDialogue> new_dialogue;
// check if the id exists!
Q_ASSERT(json_object.contains("id"));
qDebug() << "! The dialogue with id " << json_object["id"].toString() << " is about to create.";
Q_ASSERT(json_object.contains("type"));
int type = json_object["type"].toInt();
switch (type)
{
case (DIALOGUE_TYPE::TEXT):
new_dialogue = factory->createTextDialogue(json_object);
break;
case (DIALOGUE_TYPE::WIDGET):
new_dialogue = factory->createWidgetDialogue(json_object);
break;
default:
Q_ASSERT(false);
}
new_dialogue->setTag(json_object["id"].toString());
hash_dialogues.insert(json_object["id"].toString(), new_dialogue);
}
}
void QWLevelBuilder::setupLocations(const QJsonArray &array)
{
qDebug() << "Setup the locations!";
QJsonObject json_object;
for (const QJsonValue & json_value : array)
{
json_object = json_value.toObject();
std::shared_ptr<QWLocation> new_location;
Q_ASSERT(json_object.contains("id"));
qDebug() << "! The level with id " << json_object["id"].toString() << " was created.";
new_location = std::make_shared<QWLocation>();
new_location->setTag(json_object["id"].toString());
// check and add the pixmap triggers
Q_ASSERT(json_object.contains("triggers"));
if (json_object.contains("triggers")) {
qDebug() << " Found triggers!";
QJsonArray loc_triggers = json_value["triggers"].toArray();
for (const QJsonValue trg : loc_triggers)
{
qDebug() << " Added the trigger " << trg.toString();
new_location->addTriggers( hash_triggers[trg.toString()] );
}
}
if (json_object.contains("triggers"))
new_location->setDiscovered(json_object["discovered"].toBool());
// check if it has a background
if (json_object.contains("background")) {
qDebug() << " Here is a background.";
QString b = json_value["background"].toString();
new_location->addTriggers(hash_triggers[b]);
qDebug() << " Background was added.";
}
hash_locations.insert(json_object["id"].toString(), new_location);
qDebug() << " The level was inserted into its map.\n - - -";
}
}

@ -0,0 +1,78 @@
#ifndef LEVELBUILDER_H
#define LEVELBUILDER_H
#include <memory>
#include <functional>
#include <QDir>
#include <QFile>
#include <QJsonObject>
#include <QJsonDocument>
#include <QJsonArray>
/* QWLevelBuilder
* Saves and loads game sessions by managing dependent json files. */
struct GameFeatures;
class QWScene;
class QWAbstractEvent;
class QWAbstractGameDialogue;
class QWInventoryManager;
class QWTextDialogueManager;
class QWWidgetDialogueManager;
class QWSoundPlayer;
class QWTrigger;
class QWLocation;
class QWLevelBuilder final : public QObject
{
Q_OBJECT
Q_DISABLE_COPY_MOVE(QWLevelBuilder)
friend class QWEventFactory;
friend class QWDialogueFactory;
private:
QDir save_dir;
QString str_profile_filename;
QString str_current_profile;
QString str_current_level;
QJsonObject level;
QWInventoryManager *ptr_inventory;
QWScene *ptr_scene;
QWSoundPlayer *ptr_soundplayer;
QWTextDialogueManager *ptr_text_dlg;
QWWidgetDialogueManager *ptr_widget_dlg;
QHash<QString, std::shared_ptr<QWAbstractEvent>> hash_events;
QHash<QString, std::shared_ptr<QWTrigger>> hash_triggers;
QHash<QString, std::shared_ptr<QWAbstractGameDialogue>> hash_dialogues;
QHash<QString, std::shared_ptr<QWLocation>> hash_locations;
std::shared_ptr<QWTrigger> init_trigger;
void setupTriggers(const QJsonArray &array);
void setupEvents(const QJsonArray &array);
void linkEvents(const QJsonArray &array);
void setupDialogues(const QJsonArray &array);
void setupLocations(const QJsonArray &array);
void init(const QJsonObject & savefile);
public:
explicit QWLevelBuilder(QObject *parent = nullptr);
void setGameFeatures(std::unique_ptr<GameFeatures> &features);
void initLevel(const QString &lvlname);
void initSaveProfile(const QString &filename, const QString &profilename);
void initMenuLevel();
static QString strInitLevel() noexcept;
public slots:
void saveGame( );
void loadGame(/*int on_id*/);
};
#endif // LEVELBUILDER_H

@ -0,0 +1,121 @@
#include "qw_soundplayer.h"
QWSoundPlayer::QWSoundPlayer(QObject *parent) :
QObject(parent),
i_volume(100),
b_muted(false),
player_loop(new QMediaPlayer(this)),
playlist_loop(new QMediaPlaylist(this)),
player_single(new QMediaPlayer(this)),
player_music(new QMediaPlayer(this)),
playlist_music(new QMediaPlaylist(this))
{
// Music
playlist_music->setPlaybackMode(QMediaPlaylist::CurrentItemInLoop);
playlist_music->setCurrentIndex(0);
player_music->setAudioRole(QAudio::MusicRole);
player_music->setPlaylist(playlist_music);
QObject::connect(this,
SIGNAL(transferSetMuteness(bool)),
player_music,
SLOT(setMuted(bool)));
QObject::connect(this,
SIGNAL(transferAdjustVolume(int)),
player_music,
SLOT(setVolume(int)));
QObject::connect(this,
SIGNAL(playMusic()),
player_music,
SLOT(play()));
// Loop sounds
playlist_loop->setPlaybackMode(QMediaPlaylist::CurrentItemInLoop);
playlist_loop->setCurrentIndex(0);
player_loop->setAudioRole(QAudio::GameRole);
player_loop->setPlaylist(playlist_loop);
QObject::connect(this,
SIGNAL(transferSetMuteness(bool)),
player_loop,
SLOT(setMuted(bool)));
QObject::connect(this,
SIGNAL(transferAdjustVolume(int)),
player_loop,
SLOT(setVolume(int)));
QObject::connect(this,
SIGNAL(playLoop()),
player_loop,
SLOT(play()));
// Single sounds
player_single->setAudioRole(QAudio::GameRole);
QObject::connect(this,
SIGNAL(transferSetMuteness(bool)),
player_single,
SLOT(setMuted(bool)));
QObject::connect(this,
SIGNAL(transferAdjustVolume(int)),
player_single,
SLOT(setVolume(int)));
QObject::connect(this,
SIGNAL(playSingle()),
player_single,
SLOT(play()));
}
int QWSoundPlayer::addMusic(const QString &path)
{
playlist_music->addMedia(QUrl::fromLocalFile(path));
playlist_music->setCurrentIndex(playlist_music->currentIndex() + 1);
return playlist_music->currentIndex() - 1;
}
bool QWSoundPlayer::isMuted() const noexcept
{
return b_muted;
}
int QWSoundPlayer::volume() const noexcept
{
return i_volume;
}
void QWSoundPlayer::playSound(QMediaContent *sound)
{
player_single->stop();
player_single->setMedia(*sound);
emit playSingle();
}
void QWSoundPlayer::playMusic(const int index)
{
playlist_music->setCurrentIndex(index);
emit playMusic();
}
void QWSoundPlayer::stopMusic()
{
player_music->stop();
}
////////////////////////
void QWSoundPlayer::setMuteness(bool mute) noexcept
{
b_muted = mute;
emit transferSetMuteness(b_muted);
}
void QWSoundPlayer::adjustVolume(int vol) noexcept
{
i_volume = vol;
emit transferAdjustVolume(i_volume);
}
void QWSoundPlayer::onEndLevel() noexcept
{
playlist_music->clear();
playlist_music->setCurrentIndex(0);
}

@ -0,0 +1,61 @@
#ifndef SOUNDPLAYER_H
#define SOUNDPLAYER_H
#include <memory>
#include <QMediaPlayer>
#include <QMediaPlaylist>
/////////////////////////////////////////////////////////////////
//// DOESN'T WORK! Has to be reworked in master-merge 1.2
//// https://trello.com/c/KFUhEbYh/62-reimplement-sound-system
class QWSoundPlayer final : public QObject
{
Q_OBJECT
Q_DISABLE_COPY_MOVE(QWSoundPlayer)
private:
int i_volume;
bool b_muted;
////////////////////////
////////
//// Background sounds in loop.
QMediaPlayer *player_loop;
QMediaPlaylist *playlist_loop;
////////
//// Sounds which should play once per call.
QMediaPlayer *player_single;
////////
//// Music is music.
QMediaPlayer *player_music;
QMediaPlaylist *playlist_music;
public:
explicit QWSoundPlayer(QObject *parent = nullptr);
int addMusic(const QString &path);
inline bool isMuted() const noexcept;
inline int volume() const noexcept;
void playSound(QMediaContent *sound);
void playMusic(const int index);
void stopMusic();
////////////////////////
public slots:
void setMuteness(bool mute) noexcept;
void adjustVolume(int vol) noexcept;
void onEndLevel() noexcept;
signals:
void transferSetMuteness(bool);
void transferAdjustVolume(int);
void playLoop();
void playSingle();
void playMusic();
};
#endif // SOUNDPLAYER_H

@ -0,0 +1,15 @@
#include "qw_statemachine.h"
QWStateMachine::QWStateMachine(QObject *parent) :
QStateMachine(parent)
{}
void QWStateMachine::registerState(QString &&str, QState *state) noexcept
{
hash_states.insert(str, state);
}
QState *QWStateMachine::stateByKey(QString &&str) noexcept
{
return hash_states[str];
}

@ -0,0 +1,23 @@
#ifndef STATEMACHINE_H
#define STATEMACHINE_H
#include <QStateMachine>
/* QWStateMachine
* Inherited realization of qt state machine for simpler state managment. */
class QWStateMachine final : public QStateMachine
{
Q_OBJECT
Q_DISABLE_COPY_MOVE(QWStateMachine)
private:
QHash<QString, QState*> hash_states;
public:
explicit QWStateMachine(QObject *parent = nullptr);
void registerState(QString &&str, QState *state) noexcept;
QState *stateByKey(QString &&str) noexcept;
};
#endif // STATEMACHINE_H

@ -0,0 +1,60 @@
#include "models/dialogues/qw_textdialogue.h"
#include "qw_textdialoguemanager.h"
QWTextDialogueManager::QWTextDialogueManager(QWScene *scene) :
QWAbstractDialogueManager(scene),
p_frametext(new QGraphicsSimpleTextItem)
{
p_frametext->setFont(QFont("Arial", 25));
p_frametext->setBrush(QBrush(Qt::white));
p_frametext->setPos(12, 12);
scene->addItem(p_frametext);
}
QWTextDialogueManager::~QWTextDialogueManager()
{
delete p_frametext;
}
void QWTextDialogueManager::activateDialogue(const std::shared_ptr<QWAbstractGameDialogue> &dialogue)
{
/* Moving to text dialogue state.
* Make the panel with text visible.
* Game freezes until when player reads all
* the frames. */
ptr_text_dialogue = std::dynamic_pointer_cast<QWTextDialogue>(dialogue);
connect(ptr_scene, SIGNAL(signalClickDialogue(MouseButton)), this, SLOT(onClicked(MouseButton)));
emit onEntryDialogueTransition();
p_frametext->show();
// Show the first page of active dialogue.
p_frametext->setText(ptr_text_dialogue->currentText());
}
////////////////////////
void QWTextDialogueManager::setDialoguePanel(const std::shared_ptr<QGraphicsWidget> &panel) noexcept
{
p_textbox = panel;
}
void QWTextDialogueManager::onClicked(MouseButton mouse_button)
{
const bool has_next_pages = ptr_text_dialogue->toNextPage();
if (!has_next_pages || mouse_button == MouseButton::RIGHT) {
p_frametext->hide();
ptr_text_dialogue->resetPage();
ptr_text_dialogue->onExit(static_cast<int>(mouse_button));
disconnect(ptr_scene, SIGNAL(signalClickDialogue(MouseButton)), this, SLOT(onClicked(MouseButton)));
emit onLeaveDialogueTransition();
} else
p_frametext->setText(ptr_text_dialogue->currentText());
}

@ -0,0 +1,37 @@
#ifndef DIALOGUEMANAGER_H
#define DIALOGUEMANAGER_H
#include "qw_abstractdialoguemanager.h"
#include <QGraphicsPixmapItem>
#include <QLinkedList>
#include <QObject>
/* QWTextDialogueManager
* Controls text game-freezing dialogues. */
class QWTextDialogue;
class QWTextDialogueManager final : public QWAbstractDialogueManager
{
Q_OBJECT
Q_DISABLE_COPY_MOVE(QWTextDialogueManager)
private:
std::shared_ptr<QWTextDialogue> ptr_text_dialogue;
std::shared_ptr<QGraphicsWidget> p_textbox;
QGraphicsSimpleTextItem *p_frametext;
public:
explicit QWTextDialogueManager(QWScene *scene = nullptr);
virtual ~QWTextDialogueManager() override;
virtual void activateDialogue(const std::shared_ptr<QWAbstractGameDialogue> &dialogue) override;
////////////////////////
void setDialoguePanel(const std::shared_ptr<QGraphicsWidget> &panel) noexcept;
public slots:
virtual void onClicked(MouseButton mouse_button) override;
};
#endif // DIALOGUEMANAGER_H

@ -0,0 +1,50 @@
#include "models/dialogues/qw_widgetdialogue.h"
#include "qw_widgetdialoguemanager.h"
#include "qw_globalmetadata.h"
#include <QQuickWidget>
#include <QQmlEngine>
#include <QQmlContext>
QWWidgetDialogueManager::QWWidgetDialogueManager(QWScene *scene) :
QWAbstractDialogueManager(scene)
{}
QWWidgetDialogueManager::~QWWidgetDialogueManager()
{}
void QWWidgetDialogueManager::activateDialogue(const std::shared_ptr<QWAbstractGameDialogue> &dialogue)
{
widget_dialogue = std::dynamic_pointer_cast<QWWidgetDialogue>(dialogue);
connect(ptr_scene, SIGNAL(signalClickDialogue(MouseButton)), this, SLOT(onClicked(MouseButton)));
emit onEntryDialogueTransition();
quick_view = new QQuickWidget;
// Moving dialogue model into qml widget to handle the properties from inside
quick_view->engine()->rootContext()->setContextProperty("dialogue", widget_dialogue.get());
quick_view->setSource(QUrl::fromLocalFile(widget_dialogue->qmlPath()));
QObject::connect(quick_view, SIGNAL(destroyed()), this, SLOT(onDestroyingWidget()));
}
void QWWidgetDialogueManager::onClicked(MouseButton mouse_button)
{
if (mouse_button == MouseButton::RIGHT)
quick_view->close();
}
void QWWidgetDialogueManager::onDestroyingWidget()
{
// Testing
qDebug() << "Exit code:" << widget_dialogue->exitCode();
disconnect(ptr_scene, SIGNAL(signalClickDialogue(MouseButton)), this, SLOT(onClicked(MouseButton)));
if (widget_dialogue->isCustomStringToSave())
QWGlobalMetadata::setValue(widget_dialogue->tag(), widget_dialogue->customString());
widget_dialogue->onExit(widget_dialogue->exitCode());
emit onLeaveDialogueTransition();
}

@ -0,0 +1,28 @@
#ifndef QWWIDGETDIALOGUEMANAGER_H
#define QWWIDGETDIALOGUEMANAGER_H
#include "qw_abstractdialoguemanager.h"
class QWWidgetDialogue;
class QQuickWidget;
class QWWidgetDialogueManager final : public QWAbstractDialogueManager
{
Q_OBJECT
Q_DISABLE_COPY_MOVE(QWWidgetDialogueManager)
private:
std::shared_ptr<QWWidgetDialogue> widget_dialogue;
QQuickWidget *quick_view;
public:
explicit QWWidgetDialogueManager(QWScene *scene = nullptr);
virtual ~QWWidgetDialogueManager() override;
virtual void activateDialogue(const std::shared_ptr<QWAbstractGameDialogue> &dialogue) override;
public slots:
virtual void onClicked(MouseButton mouse_button) override;
void onDestroyingWidget();
};
#endif // QWWIDGETDIALOGUEMANAGER_H

@ -0,0 +1,114 @@
#include "game.h"
#include "features/gamefeatures.h"
#include "features/qw_levelbuilder.h"
#include "features/qw_statemachine.h"
Game::Game()
{
game_features = std::make_unique<GameFeatures>(this);
auto &[view, scene, sound_player, inventory, builder, text_dlg, widget_dlg] = *game_features;
builder->setGameFeatures(game_features);
// Connecting all the UI controls to their features
for (auto &widg : scene->inventoryWidgets())
widg->onConnect(game_features);
connect(scene, SIGNAL(signalClickInventory()), inventory, SLOT(onClicked()));
view->setFixedSize(static_cast<int>(scene->sceneRect().width() ),
static_cast<int>(scene->sceneRect().height()));
builder->initSaveProfile("test", "test");
builder->initLevel(QWLevelBuilder::strInitLevel());
buildStateMachine();
buildHotKeys();
}
Game::~Game() = default;
void Game::buildStateMachine()
{
auto *view = game_features->ptr_view;
auto *scene = game_features->ptr_scene;
QWStateMachine *state_machine = new QWStateMachine(view);
// Connecting UI elements to global state machine
for (auto &widg : scene->inventoryWidgets())
widg->onBuildingStateMachine(state_machine, game_features);
QState *state_menu = new QState;
state_machine->registerState("state_menu", state_menu);
connect(state_menu, SIGNAL(entered()), game_features->ptr_scene, SLOT(onEntryMenu()));
const auto &state_gameplay = state_machine->stateByKey("state_gameplay");
QSignalTransition *enter_gameplay_transition = new QSignalTransition(scene, SIGNAL(signalLeaveMenu()));
enter_gameplay_transition->setTargetState(state_gameplay);
state_menu->addTransition(enter_gameplay_transition);
QSignalTransition *leave_gameplay_transition = new QSignalTransition(scene, SIGNAL(signalEnterMenu()));
leave_gameplay_transition->setTargetState(state_menu);
state_gameplay->addTransition(leave_gameplay_transition);
QState *state_examination = new QState;
state_machine->registerState("state_examination", state_examination);
QSignalTransition *enter_examination_transition = new QSignalTransition(scene, SIGNAL(signalEnterExamination()));
enter_examination_transition->setTargetState(state_examination);
state_gameplay->addTransition(enter_examination_transition);
QSignalTransition *leave_examination_transition = new QSignalTransition(scene, SIGNAL(signalLeaveExamination()));
leave_examination_transition->setTargetState(state_gameplay);
state_examination->addTransition(leave_examination_transition);
QState *state_widget_dialogue = new QState;
state_machine->registerState("state_widget_dialogue", state_widget_dialogue);
connect(state_widget_dialogue, SIGNAL(entered()), game_features->ptr_scene, SLOT(onEntryDialogue()));
QSignalTransition *enter_widget_dialogue_transition = new QSignalTransition(game_features->ptr_widget_dlg, SIGNAL(onEntryDialogueTransition()));
enter_widget_dialogue_transition->setTargetState(state_widget_dialogue);
state_menu->addTransition(enter_widget_dialogue_transition);
state_gameplay->addTransition(enter_widget_dialogue_transition);
QSignalTransition *leave_widget_dialogue_transition = new QSignalTransition(game_features->ptr_widget_dlg, SIGNAL(onLeaveDialogueTransition()));
leave_widget_dialogue_transition->setTargetState(state_gameplay);
state_widget_dialogue->addTransition(leave_widget_dialogue_transition);
state_machine->addState(state_menu);
state_machine->addState(state_widget_dialogue);
state_machine->addState(state_examination);
state_machine->setInitialState(state_gameplay);
state_machine->start();
}
void Game::buildHotKeys()
{
auto *builder = game_features->ptr_builder;
auto *view = game_features->ptr_view;
/* For quick exit */
auto quit_action = new QAction(tr("E&xit"), this);
quit_action->setShortcut(tr("Ctrl+Q"));
connect(quit_action, SIGNAL(triggered()), qApp, SLOT(quit()));
view->addAction(quit_action);
/* For quick save */
auto save_action = new QAction(tr("S&ave"), this);
save_action->setShortcut(tr("Ctrl+S"));
connect(save_action, SIGNAL(triggered()), builder, SLOT(saveGame()));
view->addAction(save_action);
/* For quick load */
auto load_action = new QAction(tr("L&oad"), this);
load_action->setShortcut(tr("Ctrl+L"));
connect(load_action, SIGNAL(triggered()), builder, SLOT(loadGame()));
view->addAction(load_action);
}
void Game::start()
{
game_features->ptr_view->show();
}

@ -0,0 +1,38 @@
#ifndef QWABSTRACTGAMEDIALOGUE_H
#define QWABSTRACTGAMEDIALOGUE_H
#include <memory>
#include "models/events/qw_abstractevent.h"
/* QWAbstractGameDialogue
* Interface for all in-game dialogues. */
class QWAbstractGameDialogue : public QWTagHolder
{
protected:
QList<QList<std::shared_ptr<QWAbstractEvent>>> list_events;
public:
QWAbstractGameDialogue();
virtual ~QWAbstractGameDialogue() override = 0;
virtual void onExit(int code);
virtual void setAllEvents(const QList<QList<std::shared_ptr<QWAbstractEvent>>> &evs);
virtual void addEventsList(const QList<std::shared_ptr<QWAbstractEvent>> &evs);
////////////////////////
virtual void writeToJson(QJsonObject &savejson) override = 0;
};
enum DIALOGUE_TYPE
{
// Pure visual-novel-like text
TEXT,
// External widget with inner logic described with qml
WIDGET
};
#endif // QWABSTRACTGAMEDIALOGUE_H

@ -0,0 +1,48 @@
#include "qw_textdialogue.h"
QWTextDialogue::QWTextDialogue(const QStringList &pages)
{
setPages(pages);
}
////////////////////////
bool QWTextDialogue::toNextPage() noexcept
{
const bool has_next = ((it_current_page + 1) != list_pages.end());
if (has_next)
++it_current_page;
return has_next;
}
void QWTextDialogue::resetPage() noexcept
{
it_current_page = list_pages.begin();
}
void QWTextDialogue::setPages(const QStringList &pages) noexcept
{
list_pages = pages;
Q_ASSERT(!list_pages.empty());
it_current_page = list_pages.begin();
}
QStringList QWTextDialogue::pages() const noexcept
{
return list_pages;
}
QString QWTextDialogue::currentText() const noexcept
{
return *it_current_page;
}
////////////////////////
void QWTextDialogue::writeToJson(QJsonObject &savejson)
{
Q_UNUSED(savejson)
}

@ -0,0 +1,35 @@
#ifndef QWTEXTDIALOGUE_H
#define QWTEXTDIALOGUE_H
#include <QStringList>
#include "qw_abstractgamedialogue.h"
/* QWTextDialogue
* Provides text visual-novel-lide dialogue. */
class QWTextDialogue : public QWAbstractGameDialogue
{
protected:
QStringList list_pages;
QStringList::iterator it_current_page;
public:
QWTextDialogue(const QStringList &pages);
virtual ~QWTextDialogue() override {}
////////////////////////
bool toNextPage() noexcept;
void resetPage() noexcept;
void setPages(const QStringList &pages) noexcept;
QStringList pages() const noexcept;
QString currentText() const noexcept;
////////////////////////
virtual void writeToJson(QJsonObject &savejson) override;
};
#endif // QWTEXTDIALOGUE_H

@ -0,0 +1,63 @@
#include "qw_widgetdialogue.h"
QWWidgetDialogue::QWWidgetDialogue(const QString &path) :
qml_path(path)
{
Q_ASSERT(!qml_path.isNull());
// Filepath fixes
if (!qml_path.endsWith(".qml"))
qml_path += ".qml";
if (!qml_path.startsWith("qml/"))
qml_path = "qml/" + qml_path;
}
void QWWidgetDialogue::onExit(int code)
{
Q_UNUSED(code)
}
////////////////////////
QString QWWidgetDialogue::qmlPath() const
{
return qml_path;
}
QString QWWidgetDialogue::customString() const
{
return custom_string;
}
void QWWidgetDialogue::setCustomString(const QString &str)
{
custom_string = str;
}
int QWWidgetDialogue::exitCode() const
{
return exit_code;
}
void QWWidgetDialogue::setExitCode(int code)
{
if (code != exit_code)
exit_code = code;
}
bool QWWidgetDialogue::isCustomStringToSave() const
{
return to_save_string;
}
void QWWidgetDialogue::setCustomStringToSave(bool to_save)
{
to_save_string = to_save;
}
////////////////////////
void QWWidgetDialogue::writeToJson(QJsonObject &savejson)
{
Q_UNUSED(savejson)
}

@ -0,0 +1,45 @@
#ifndef WIDGETDIALOGUE_H
#define WIDGETDIALOGUE_H
#include "qw_abstractgamedialogue.h"
#include <QObject>
class QWWidgetDialogue : public QObject, public QWAbstractGameDialogue
{
Q_OBJECT
Q_DISABLE_COPY_MOVE(QWWidgetDialogue)
Q_PROPERTY(int exit_code READ exitCode WRITE setExitCode)
Q_PROPERTY(QString custom_string READ customString WRITE setCustomString)
Q_PROPERTY(bool to_save_string READ isCustomStringToSave WRITE setCustomStringToSave)
private:
QString qml_path;
QString custom_string;
int exit_code;
bool to_save_string;
public:
explicit QWWidgetDialogue(const QString &path);
virtual ~QWWidgetDialogue() override {}
void onExit(int code) override;
////////////////////////
QString qmlPath() const;
QString customString() const;
void setCustomString(const QString &str);
int exitCode() const;
void setExitCode(int code);
bool isCustomStringToSave() const;
void setCustomStringToSave(bool to_save);
////////////////////////
void writeToJson(QJsonObject &savejson) override;
};
#endif // WIDGETDIALOGUE_H

@ -0,0 +1,43 @@
#ifndef QUESTEVENT_H
#define QUESTEVENT_H
#include <QJsonObject>
#include <QJsonArray>
#include <QDebug>
#include "../qw_tagholder.h"
/* QWAbstractEvent
* Interface for all in-game events. The core of game logic process. */
class QWAbstractEvent : public QWTagHolder
{
public:
QWAbstractEvent();
virtual ~QWAbstractEvent() override = 0;
virtual void execute() = 0;
////////////////////////
virtual void writeToJson(QJsonObject &savejson) override = 0;
};
enum EVENT_TYPE
{
CHANGE_LOCATION,
SWITCH_EVENTS, // <- requires other events to be initialized
DELETE_FROM_INVENTORY,
END_LEVEL,
PICKUP_ITEM,
PLAY_SOUND,
PLAY_MUSIC,
CHANGE_TRIGGER_PROPERTIES,
NEW_GAME,
QUIT_GAME,
START_DIALOGUE,
ADD_TRIGGER,
REMOVE_TRIGGER
};
#endif // QUESTEVENT_H

@ -0,0 +1,20 @@
#include "qw_abstractinventoryevent.h"
QWAbstractInventoryEvent:: QWAbstractInventoryEvent()
{}
QWAbstractInventoryEvent::~QWAbstractInventoryEvent()
{}
////////////////////////
void QWAbstractInventoryEvent::setInventoryManager(QWInventoryManager *const inv) noexcept
{
ptr_inventory = inv;
}
QWInventoryManager *QWAbstractInventoryEvent::inventoryManager() const noexcept
{
return ptr_inventory;
}

@ -0,0 +1,31 @@
#ifndef QUESTABSTRACTINVENTORYEVENT_H
#define QUESTABSTRACTINVENTORYEVENT_H
#include "features/qw_inventorymanager.h"
#include "qw_abstractevent.h"
/* QWAbstractInventoryEvent
* Interface for all in-game inventory events. */
class QWAbstractInventoryEvent : public QWAbstractEvent
{
protected:
QWInventoryManager *ptr_inventory;
public:
QWAbstractInventoryEvent();
virtual ~QWAbstractInventoryEvent() override = 0;
virtual void execute() override = 0;
////////////////////////
void setInventoryManager(QWInventoryManager *const inv) noexcept;
QWInventoryManager *inventoryManager() const noexcept;
////////////////////////
virtual void writeToJson(QJsonObject &savejson) override = 0;
};
#endif // QUESTABSTRACTINVENTORYEVENT_H

@ -0,0 +1,20 @@
#include "qw_abstractlevelevent.h"
QWAbstractLevelEvent:: QWAbstractLevelEvent()
{}
QWAbstractLevelEvent::~QWAbstractLevelEvent()
{}
////////////////////////
void QWAbstractLevelEvent::setLevelBuilder(QWLevelBuilder *const buil) noexcept
{
ptr_builder = buil;
}
QWLevelBuilder *QWAbstractLevelEvent::levelBuilder() const noexcept
{
return ptr_builder;
}

@ -0,0 +1,31 @@
#ifndef QUESTABSTRACTLEVELEVENT_H
#define QUESTABSTRACTLEVELEVENT_H
#include "features/qw_levelbuilder.h"
#include "qw_abstractevent.h"
/* QWAbstractLevelEvent
* Interface for all in-game events which control save files and levels. */
class QWAbstractLevelEvent : public QWAbstractEvent
{
protected:
QWLevelBuilder *ptr_builder;
public:
QWAbstractLevelEvent();
virtual ~QWAbstractLevelEvent() override = 0;
virtual void execute() override = 0;
////////////////////////
void setLevelBuilder(QWLevelBuilder *const buil) noexcept;
QWLevelBuilder *levelBuilder() const noexcept;
////////////////////////
virtual void writeToJson(QJsonObject &savejson) override = 0;
};
#endif // QUESTABSTRACTLEVELEVENT_H

@ -0,0 +1,19 @@
#include "qw_abstractsceneevent.h"
QWAbstractSceneEvent:: QWAbstractSceneEvent()
{}
QWAbstractSceneEvent::~QWAbstractSceneEvent()
{}
////////////////////////
void QWAbstractSceneEvent::setScene(QWScene *const scene) noexcept
{
ptr_scene = scene;
}
QWScene *QWAbstractSceneEvent::scene() const noexcept
{
return ptr_scene;
}

@ -0,0 +1,31 @@
#ifndef QUESTABSTRACTSCENEEVENT_H
#define QUESTABSTRACTSCENEEVENT_H
#include "qw_abstractevent.h"
#include "view/qw_scene.h"
/* QWAbstractSceneEvent
* Interface for all in-game scene events. */
class QWAbstractSceneEvent : public QWAbstractEvent
{
protected:
QWScene *ptr_scene;
public:
QWAbstractSceneEvent();
virtual ~QWAbstractSceneEvent() override = 0;
virtual void execute() override = 0;
////////////////////////
void setScene(QWScene *const scene) noexcept;
QWScene *scene() const noexcept;
////////////////////////
virtual void writeToJson(QJsonObject &savejson) override = 0;
};
#endif // QUESTABSTRACTSCENEEVENT_H

@ -0,0 +1,19 @@
#include "qw_abstractsoundevent.h"
QWAbstractSoundEvent:: QWAbstractSoundEvent()
{}
QWAbstractSoundEvent::~QWAbstractSoundEvent()
{}
////////////////////////
void QWAbstractSoundEvent::setSoundPlayer(QWSoundPlayer *const soundplayer) noexcept
{
ptr_soundplayer = soundplayer;
}
QWSoundPlayer *QWAbstractSoundEvent::soundPlayer() const noexcept
{
return ptr_soundplayer;
}

@ -0,0 +1,31 @@
#ifndef QUESTABSTRACTSOUNDEVENT_H
#define QUESTABSTRACTSOUNDEVENT_H
#include "features/qw_soundplayer.h"
#include "qw_abstractevent.h"
/* QWAbstractSoundEvent
* Interface for all in-game audio events. */
class QWAbstractSoundEvent : public QWAbstractEvent
{
protected:
QWSoundPlayer *ptr_soundplayer;
public:
QWAbstractSoundEvent();
virtual ~QWAbstractSoundEvent() override = 0;
virtual void execute() override = 0;
////////////////////////
void setSoundPlayer(QWSoundPlayer *const soundplayer) noexcept;
QWSoundPlayer *soundPlayer() const noexcept;
////////////////////////
virtual void writeToJson(QJsonObject &savejson) override = 0;
};
#endif // QUESTABSTRACTSOUNDEVENT_H

@ -0,0 +1,49 @@
#include "qw_addtriggerevent.h"
#include "models/qw_trigger.h"
QWAddTriggerEvent::QWAddTriggerEvent(const std::shared_ptr<QWTrigger> &tr) :
trigger(tr)
{
Q_ASSERT(trigger);
}
void QWAddTriggerEvent::execute()
{
Q_ASSERT(location);
if (location->triggers().contains(trigger))
return;
location->addTriggers(trigger);
if (location == ptr_scene->currentLocation())
ptr_scene->addItem(trigger.get());
}
////////////////////////
void QWAddTriggerEvent::setLocation(const std::shared_ptr<QWLocation> &loc) noexcept
{
location = loc;
Q_ASSERT(location);
}
void QWAddTriggerEvent::setTrigger(const std::shared_ptr<QWTrigger> &tr) noexcept
{
trigger = tr;
Q_ASSERT(trigger);
}
////////////////////////
void QWAddTriggerEvent::writeToJson(QJsonObject &event_data)
{
event_data.insert("id", tag());
event_data.insert("type", EVENT_TYPE::ADD_TRIGGER);
event_data.insert("location", location->tag());
event_data.insert("trigger", trigger->tag());
qDebug() << " The add_trigger event:\n" << " id " << tag()
<< "\n location :" << location->tag()
<< "\n trigger :" << trigger->tag();
}

@ -0,0 +1,31 @@
#ifndef QWADDTRIGGER_H
#define QWADDTRIGGER_H
#include "qw_abstractsceneevent.h"
/* QWAddTriggerEvent
* Adds a trigger to its location list. */
class QWAddTriggerEvent : public QWAbstractSceneEvent
{
private:
std::shared_ptr<QWTrigger> trigger; // What to add.
std::shared_ptr<QWLocation> location; // Where to add.
public:
explicit QWAddTriggerEvent(const std::shared_ptr<QWTrigger> &tr);
virtual ~QWAddTriggerEvent() override {}
void execute() override;
////////////////////////
void setLocation(const std::shared_ptr<QWLocation> &loc) noexcept;
void setTrigger(const std::shared_ptr<QWTrigger> &tr) noexcept;
////////////////////////
void writeToJson(QJsonObject &event_data) override;
};
#endif // QWADDTRIGGER_H

@ -0,0 +1,52 @@
#include "qw_changelocationevent.h"
#include "../qw_location.h"
#include "../qw_trigger.h"
QWChangeLocationEvent::QWChangeLocationEvent(const std::shared_ptr<QWLocation> &location) :
target_location(location)
{
Q_ASSERT(target_location);
}
void QWChangeLocationEvent::execute()
{
const QList<std::shared_ptr<QWTrigger>> &triggers = target_location->triggers();
// We clear all the triggers from previous location
ptr_scene->clearLocation();
ptr_scene->setCurrentLocation(target_location);
if (const auto & tr = target_location->firstVisitTrigger(); tr && !target_location->discovered())
tr->activate();
target_location->setDiscovered(true);
int z = 0;
// The first item will be below the others. The last item - above.
// Triggers[0] must be background.
for (auto &trigger : triggers)
{
trigger->setZValue(-1 * ++z);
ptr_scene->addItem(trigger.get());
}
}
////////////////////////
void QWChangeLocationEvent::setLocation(const std::shared_ptr<QWLocation> &location) noexcept
{
target_location = location;
}
////////////////////////
void QWChangeLocationEvent::writeToJson(QJsonObject &event_data)
{
event_data.insert("id", tag());
event_data.insert("type", EVENT_TYPE::CHANGE_LOCATION);
event_data.insert("location", target_location->tag());
qDebug() << " The move_to_location event:\n" << " id " << tag()
<< "\n location :" << target_location->tag();
}

@ -0,0 +1,32 @@
#ifndef QUESTCHANGELOCATIONEVENT_H
#define QUESTCHANGELOCATIONEVENT_H
#include "qw_abstractsceneevent.h"
/* QWChangeLocationEvent
* Moves player to new location by replacing scene triggers. */
class QWTrigger;
class QWLocation;
class QWChangeLocationEvent : public QWAbstractSceneEvent
{
private:
std::shared_ptr<QWLocation> target_location;
public:
explicit QWChangeLocationEvent(const std::shared_ptr<QWLocation> &location);
virtual ~QWChangeLocationEvent() override {}
void execute() override;
////////////////////////
void setLocation(const std::shared_ptr<QWLocation> &location) noexcept;
////////////////////////
void writeToJson(QJsonObject &event_data) override;
};
#endif // QUESTCHANGELOCATIONEVENT_H

@ -0,0 +1,25 @@
#include "qw_endlevelevent.h"
QWEndLevelEvent::QWEndLevelEvent(const QString &level) :
str_nlevel(level)
{
Q_ASSERT(!str_nlevel.isEmpty());
}
void QWEndLevelEvent::execute()
{
ptr_builder->saveGame();
ptr_builder->initLevel(str_nlevel);
}
////////////////////////
void QWEndLevelEvent::writeToJson(QJsonObject &event_data)
{
event_data.insert("id", tag());
event_data.insert("type", EVENT_TYPE::END_LEVEL);
event_data.insert("new_level", str_nlevel);
qDebug() << " The end_level event:\n" << " id " << tag()
<< "\n new_level " << str_nlevel;
}

@ -0,0 +1,25 @@
#ifndef QUESTENDLEVELEVENT_H
#define QUESTENDLEVELEVENT_H
#include "qw_abstractlevelevent.h"
/* QWEndLevelEvent
* Sends its signal to QWLevelBuilder whenever it has to load next level. */
class QWEndLevelEvent : public QWAbstractLevelEvent
{
private:
QString str_nlevel;
public:
explicit QWEndLevelEvent(const QString &level);
virtual ~QWEndLevelEvent() override {}
void virtual execute() override;
////////////////////////
void writeToJson(QJsonObject &event_data) override;
};
#endif // QUESTENDLEVELEVENT_H

@ -0,0 +1,45 @@
#include <QRegExp>
#include "qw_newgameevent.h"
#include "qw_globalmetadata.h"
QWNewGameEvent::QWNewGameEvent(const QString &savefile) :
str_savefile(savefile)
{
Q_ASSERT(!str_savefile.isEmpty());
}
void QWNewGameEvent::execute()
{
const QString profile_name = QWGlobalMetadata::valueBy("new_game_dialogue").toString();
str_savefile = composeFileName(profile_name);
Q_ASSERT(!profile_name.isEmpty());
Q_ASSERT(!str_savefile.isEmpty());
ptr_builder->initSaveProfile(str_savefile, profile_name);
ptr_builder->initLevel(QWLevelBuilder::strInitLevel());
}
////////////////////////
QString QWNewGameEvent::composeFileName(const QString &str)
{
//Turn the chosen by user savename into file name.
QString file_name = str;
const QRegExp regexp("[^0-9a-z]+");
file_name = file_name.toLower().remove(regexp);
return file_name;
}
////////////////////////
void QWNewGameEvent::writeToJson(QJsonObject &event_data)
{
event_data.insert("id", tag());
event_data.insert("type", EVENT_TYPE::NEW_GAME);
event_data.insert("save_file", str_savefile);
qDebug() << " The new_game event:\n" << " id " << tag()
<< "\n save_file " << str_savefile;
}

@ -0,0 +1,27 @@
#ifndef QUESTNEWGAMEEVENT_H
#define QUESTNEWGAMEEVENT_H
#include "qw_abstractlevelevent.h"
/* QWNewGameEvent
* Creates new savefile and begins the game from clear sheet. */
class QWNewGameEvent : public QWAbstractLevelEvent
{
private:
QString str_savefile;
QString composeFileName(const QString &str);
public:
explicit QWNewGameEvent(const QString &savefile);
virtual ~QWNewGameEvent() override {}
void virtual execute() override;
////////////////////////
void writeToJson(QJsonObject &event_data) override;
};
#endif // QUESTNEWGAMEEVENT_H

@ -0,0 +1,37 @@
#include "qw_pickupitemevent.h"
#include "../qw_trigger.h"
QWPickupItemEvent::QWPickupItemEvent(const std::shared_ptr<QWTrigger> &tr) :
ptr_inventory_trigger(tr)
{
Q_ASSERT(ptr_inventory_trigger);
}
void QWPickupItemEvent::execute()
{
ptr_inventory->addInventoryIcon(ptr_inventory_trigger);
}
////////////////////////
void QWPickupItemEvent::setInventoryTrigger(const std::shared_ptr<QWTrigger> &tr) noexcept
{
ptr_inventory_trigger = tr;
}
std::shared_ptr<QWTrigger> QWPickupItemEvent::inventoryTrigger() const noexcept
{
return ptr_inventory_trigger;
}
////////////////////////
void QWPickupItemEvent::writeToJson(QJsonObject &event_data)
{
event_data.insert("id", tag());
event_data.insert("type", EVENT_TYPE::PICKUP_ITEM);
event_data.insert("target", ptr_inventory_trigger->tag());
qDebug() << " The pickup_item event:\n" << " id " << tag()
<< "\n target " << ptr_inventory_trigger->tag();
}

@ -0,0 +1,34 @@
#ifndef QUESTPLAYMUSICEVENT_H
#define QUESTPLAYMUSICEVENT_H
#include "qw_abstractsoundevent.h"
/////////////////////////////////////////////////////////////////
//// DOESN'T WORK! Has to be reworked in master-merge 1.2
//// https://trello.com/c/KFUhEbYh/62-reimplement-sound-system
class QWPlayMusicEvent : public QWAbstractSoundEvent
{
private:
QString str_musicpath;
int index;
public:
explicit QWPlayMusicEvent(const QString &path);
virtual ~QWPlayMusicEvent() override {}
void execute() override;
////////////////////////
inline void setMusicpath(const QString &path) noexcept;
inline QString musicpath() const noexcept;
void attachMusic();
////////////////////////
void writeToJson(QJsonObject &event_data) override;
};
#endif // QUESTPLAYMUSICEVENT_H

@ -0,0 +1,24 @@
#include "qw_playsoundevent.h"
QWPlaySoundEvent::QWPlaySoundEvent(const QString &path) :
media_sound(new QMediaContent(QUrl("qrc:/res/" + path + ".wav")))
{
Q_ASSERT(!media_sound->isNull());
}
void QWPlaySoundEvent::execute()
{
ptr_soundplayer->playSound(media_sound);
}
////////////////////////
void QWPlaySoundEvent::writeToJson(QJsonObject &event_data)
{
event_data.insert("id", tag());
event_data.insert("type", EVENT_TYPE::PLAY_SOUND);
//event_data.insert("sound", media_sound->canonicalUrl().toString());
//qDebug() << " The play_sound event:\n" << " id " << tag()
//<< "\n sound " << media_sound->canonicalUrl().toString();
}

@ -0,0 +1,30 @@
#ifndef QUESTPLAYSOUNDEVENT_H
#define QUESTPLAYSOUNDEVENT_H
#include <memory>
#include <QFile>
#include "qw_abstractsoundevent.h"
/////////////////////////////////////////////////////////////////
//// DOESN'T WORK! Has to be reworked in master-merge 1.2
//// https://trello.com/c/KFUhEbYh/62-reimplement-sound-system
class QSoundEffect;
class QWPlaySoundEvent : public QWAbstractSoundEvent
{
private:
QMediaContent *media_sound;
public:
explicit QWPlaySoundEvent(const QString &path);
virtual ~QWPlaySoundEvent() override {}
void execute() override;
////////////////////////
void writeToJson(QJsonObject &event_data) override;
};
#endif // QUESTPLAYSOUNDEVENT_H

@ -0,0 +1,26 @@
#include <QCoreApplication>
#include "qw_quitgameevent.h"
QWQuitGameEvent::QWQuitGameEvent(bool savegame) :
b_savegame(savegame)
{}
void QWQuitGameEvent::execute()
{
if (b_savegame)
ptr_builder->saveGame();
QCoreApplication::quit();
}
////////////////////////
void QWQuitGameEvent::writeToJson(QJsonObject &event_data)
{
event_data.insert("id", tag());
event_data.insert("type", EVENT_TYPE::QUIT_GAME);
event_data.insert("save_game", b_savegame);
qDebug() << " The quit_game event:\n" << " id " << tag()
<< "\n save_game " << b_savegame;
}

@ -0,0 +1,25 @@
#ifndef QUESTQUITGAMEEVENT_H
#define QUESTQUITGAMEEVENT_H
#include "qw_abstractlevelevent.h"
/* QWQuitGameEvent
* Immediately terminates current session. */
class QWQuitGameEvent : public QWAbstractLevelEvent
{
private:
bool b_savegame;
public:
explicit QWQuitGameEvent(bool savegame = false);
virtual ~QWQuitGameEvent() override {}
void virtual execute() override;
////////////////////////
void writeToJson(QJsonObject &event_data) override;
};
#endif // QUESTQUITGAMEEVENT_H

@ -0,0 +1,49 @@
#include "qw_removetriggerevent.h"
#include "models/qw_trigger.h"
QWRemoveTriggerEvent::QWRemoveTriggerEvent(const std::shared_ptr<QWTrigger> &tr) :
trigger(tr)
{
Q_ASSERT(trigger);
}
void QWRemoveTriggerEvent::execute()
{
Q_ASSERT(location);
if (!location->triggers().contains(trigger))
return;
location->removeTrigger(trigger);
if (location == ptr_scene->currentLocation())
ptr_scene->removeItem(trigger.get());
}
////////////////////////
void QWRemoveTriggerEvent::setLocation(const std::shared_ptr<QWLocation> &loc) noexcept
{
location = loc;
Q_ASSERT(location);
}
void QWRemoveTriggerEvent::setTrigger(const std::shared_ptr<QWTrigger> &tr) noexcept
{
trigger = tr;
Q_ASSERT(trigger);
}
////////////////////////
void QWRemoveTriggerEvent::writeToJson(QJsonObject &event_data)
{
event_data.insert("id", tag());
event_data.insert("type", EVENT_TYPE::REMOVE_TRIGGER);
event_data.insert("location", location->tag());
event_data.insert("trigger", trigger->tag());
qDebug() << " The remove_trigger event:\n" << " id " << tag()
<< "\n location :" << location->tag()
<< "\n trigger :" << trigger->tag();
}

@ -0,0 +1,31 @@
#ifndef QWREMOVETRIGGER_H
#define QWREMOVETRIGGER_H
#include "qw_abstractsceneevent.h"
/* QWRemoveTriggerEvent
* Removes a trigger from its location list. */
class QWRemoveTriggerEvent : public QWAbstractSceneEvent
{
private:
std::shared_ptr<QWTrigger> trigger; // What to add.
std::shared_ptr<QWLocation> location; // Where to add.
public:
explicit QWRemoveTriggerEvent(const std::shared_ptr<QWTrigger> &tr);
virtual ~QWRemoveTriggerEvent() override {}
void execute() override;
////////////////////////
void setLocation(const std::shared_ptr<QWLocation> &loc) noexcept;
void setTrigger(const std::shared_ptr<QWTrigger> &tr) noexcept;
////////////////////////
void writeToJson(QJsonObject &event_data) override;
};
#endif // QWREMOVETRIGGER_H

@ -0,0 +1,36 @@
#include "models/dialogues/qw_abstractgamedialogue.h"
#include "features/qw_abstractdialoguemanager.h"
#include "qw_startdialogueevent.h"
QWStartDialogueEvent::QWStartDialogueEvent(const std::shared_ptr<QWAbstractGameDialogue> &dialogue) :
ptr_dialogue(dialogue)
{}
void QWStartDialogueEvent::execute()
{
ptr_dialogue_manager->activateDialogue(ptr_dialogue);
}
////////////////////////
void QWStartDialogueEvent::setDialogueManager(QWAbstractDialogueManager *dialogman) noexcept
{
ptr_dialogue_manager = dialogman;
}
QWAbstractDialogueManager *QWStartDialogueEvent::dialogueManager() const noexcept
{
return ptr_dialogue_manager;
}
////////////////////////
void QWStartDialogueEvent::writeToJson(QJsonObject &event_data)
{
event_data.insert("id", tag());
event_data.insert("type", EVENT_TYPE::START_DIALOGUE);
event_data.insert("dialogue", ptr_dialogue->tag());
qDebug() << " The start_dialogue event:\n" << " id " << tag()
<< "\n dialogue " << ptr_dialogue->tag();
}

@ -0,0 +1,34 @@
#ifndef QWSTARTDIALOGUEEVENT_H
#define QWSTARTDIALOGUEEVENT_H
#include "qw_abstractevent.h"
/* QWStartDialogueEvent
* Starts a game-freezing dialogue by moving QWScene from gameplay state. */
class QWAbstractDialogueManager;
class QWAbstractGameDialogue;
class QWStartDialogueEvent : public QWAbstractEvent
{
private:
QWAbstractDialogueManager *ptr_dialogue_manager;
std::shared_ptr<QWAbstractGameDialogue> ptr_dialogue;
public:
explicit QWStartDialogueEvent(const std::shared_ptr<QWAbstractGameDialogue> &dialogue);
virtual ~QWStartDialogueEvent() override {}
void execute() override;
////////////////////////
void setDialogueManager(QWAbstractDialogueManager *dialogman) noexcept;
QWAbstractDialogueManager *dialogueManager() const noexcept;
////////////////////////
void writeToJson(QJsonObject &event_data) override;
};
#endif // QWSTARTDIALOGUEEVENT_H

@ -0,0 +1,75 @@
#include "../qw_trigger.h"
#include "qw_switcheventsevent.h"
QWSwitchEventsEvent::QWSwitchEventsEvent(const std::shared_ptr<QWTrigger> &tr) :
ptr_target(tr),
b_active(false)
{
Q_ASSERT(ptr_target);
}
void QWSwitchEventsEvent::execute()
{
/* QWActivateItemEvent changes its state,
* Now we send other list of events for the linked trigger. */
b_active = !b_active;
ptr_target->setEvents(b_active ? list_enabled_events : list_disabled_events);
}
void QWSwitchEventsEvent::init()
{
ptr_target->setEvents(list_disabled_events);
}
////////////////////////
void QWSwitchEventsEvent::setTarget(const std::shared_ptr<QWTrigger> &tr) noexcept
{
ptr_target = tr;
}
std::shared_ptr<QWTrigger> QWSwitchEventsEvent::target() const noexcept
{
return ptr_target;
}
void QWSwitchEventsEvent::setEventsOnEnable(const QList<std::shared_ptr<QWAbstractEvent>> &evs) noexcept
{
list_enabled_events = evs;
}
void QWSwitchEventsEvent::setEventsOnDisable(const QList<std::shared_ptr<QWAbstractEvent>> &evs) noexcept
{
list_disabled_events = evs;
}
////////////////////////
void QWSwitchEventsEvent::writeToJson(QJsonObject & event_data)
{
event_data.insert("id", tag());
event_data.insert("type", EVENT_TYPE::SWITCH_EVENTS);
event_data.insert("target", ptr_target->tag());
QJsonArray trs_en, trs_dis;
for (const auto & ev : list_enabled_events) {
trs_en.append(ev->tag());
}
event_data.insert("enable_evs", trs_en);
for (const auto & ev : list_disabled_events) {
trs_dis.append(ev->tag());
}
event_data.insert("disable_evs", trs_dis);
qDebug() << " The switch_events event:\n" << " id " << tag()
<< "\n trs_en :";
for (const auto tr : trs_en)
qDebug() << " " << tr.toString();
qDebug() << "\n trs_dis :";
for (const auto tr : trs_dis)
qDebug() << " " << tr.toString();
}

@ -0,0 +1,48 @@
#ifndef QUESTACTIVATEITEMEVENT_H
#define QUESTACTIVATEITEMEVENT_H
#include <memory>
#include <QList>
#include "qw_abstractevent.h"
/* QWSwitchEventsEvent
* Changes events of its linked QWTrigger.
* For example: a door is being closed until we pick up a key.
* It's initial state "to print message "go find a key you punk".
* When we activate its key, execute() changes door event to "go through". */
class QWTrigger;
class QWSwitchEventsEvent : public QWAbstractEvent
{
private:
std::shared_ptr<QWTrigger> ptr_target;
bool b_active;
QList<std::shared_ptr<QWAbstractEvent>> list_disabled_events;
QList<std::shared_ptr<QWAbstractEvent>> list_enabled_events;
public:
explicit QWSwitchEventsEvent(const std::shared_ptr<QWTrigger> &tr);
virtual ~QWSwitchEventsEvent() override {}
void execute() override;
////////////////////////
void setTarget(const std::shared_ptr<QWTrigger> &tr) noexcept;
std::shared_ptr<QWTrigger> target() const noexcept;
void setEventsOnDisable(const QList<std::shared_ptr<QWAbstractEvent>> &evs) noexcept;
void setEventsOnEnable(const QList<std::shared_ptr<QWAbstractEvent>> &evs) noexcept;
// init() sets an inital state of ptr_trigger.
void init();
////////////////////////
void writeToJson(QJsonObject &event_data) override;
};
#endif // QUESTACTIVATEITEMEVENT_H

@ -0,0 +1,114 @@
#include "qw_location.h"
#include "qw_trigger.h"
QWLocation::QWLocation() :
flag_discovered(false)
{}
void QWLocation::clearTriggers() noexcept
{
list_triggers.clear();
}
void QWLocation::setTriggers(std::initializer_list<std::shared_ptr<QWTrigger>> &&trs) noexcept
{
list_triggers.clear();
/* For some reason QList(::begin(), ::end())
* doesn't work for MSVC */
#if defined(_MSC_VER)
list_triggers = QList<std::shared_ptr<QWTrigger>>::fromStdList(std::move(trs));
#else
list_triggers = QList(trs.begin(), trs.end());
#endif
}
void QWLocation::setTriggers(const QList<std::shared_ptr<QWTrigger>> &trs) noexcept
{
list_triggers.clear();
list_triggers = trs;
}
void QWLocation::addTriggers(std::initializer_list<std::shared_ptr<QWTrigger>> &&trs) noexcept
{
list_triggers.append(std::move(QList<std::shared_ptr<QWTrigger>>(trs)));
}
void QWLocation::addTriggers(const std::shared_ptr<QWTrigger> &tr) noexcept
{
list_triggers.append(tr);
}
void QWLocation::removeTrigger(const std::shared_ptr<QWTrigger> &tr) noexcept
{
list_triggers.removeOne(tr);
}
QList<std::shared_ptr<QWTrigger>> QWLocation::triggers() const
{
return list_triggers;
}
void QWLocation::setFirstVisitTrigger(const std::shared_ptr<QWTrigger> &tr) noexcept
{
first_visit_trigger = tr;
Q_ASSERT(first_visit_trigger);
}
std::shared_ptr<QWTrigger> QWLocation::firstVisitTrigger() const noexcept
{
return first_visit_trigger;
}
void QWLocation::setDiscovered(bool discovered) noexcept
{
flag_discovered = discovered;
}
bool QWLocation::discovered() const noexcept
{
return flag_discovered;
}
void QWLocation::setMusicPath(const QString &path) noexcept
{
music_path = path;
Q_ASSERT(!music_path.isEmpty());
}
void QWLocation::removeMusic() noexcept
{
music_path.clear();
}
QString QWLocation::musicPath() const noexcept
{
return music_path;
}
////////////////////////
void QWLocation::writeToJson(QJsonObject &location_data)
{
location_data.insert("id", tag());
if (flag_discovered)
location_data.insert("discovered", flag_discovered);
if (!music_path.isEmpty())
location_data.insert("music_path", music_path);
qDebug() << " The location:\n" << " id " << tag()
<< "\n discovered " << flag_discovered
<< "\n music_path " << music_path;
// - Location triggers - //
QJsonArray json_triggers;
for (const auto &trigger : triggers()) {
json_triggers.append(trigger->tag());
qDebug() << " trigger: " << trigger->tag();
}
location_data.insert("trs", json_triggers);
}

@ -0,0 +1,51 @@
#ifndef QWLOCATION_H
#define QWLOCATION_H
#include <memory>
#include <QList>
#include "events/qw_abstractevent.h"
/* QWLocation
* Represents any game location. */
class QWTrigger;
class QWLocation final : public QWTagHolder
{
private:
QList<std::shared_ptr<QWTrigger>> list_triggers;
std::shared_ptr<QWTrigger> first_visit_trigger;
bool flag_discovered;
QString music_path;
public:
explicit QWLocation();
void clearTriggers() noexcept;
void setTriggers(std::initializer_list<std::shared_ptr<QWTrigger>> &&trs) noexcept;
void setTriggers(const QList<std::shared_ptr<QWTrigger>> &trs) noexcept;
void addTriggers(std::initializer_list<std::shared_ptr<QWTrigger>> &&trs) noexcept;
void addTriggers(const std::shared_ptr<QWTrigger> &tr) noexcept;
void removeTrigger(const std::shared_ptr<QWTrigger> &tr) noexcept;
QList<std::shared_ptr<QWTrigger>> triggers() const;
// Should be activated on first visit.
void setFirstVisitTrigger(const std::shared_ptr<QWTrigger> &tr) noexcept;
std::shared_ptr<QWTrigger> firstVisitTrigger() const noexcept;
void setDiscovered(bool discovered) noexcept;
bool discovered() const noexcept;
void setMusicPath(const QString &path) noexcept;
void removeMusic() noexcept;
QString musicPath() const noexcept;
////////////////////////
void writeToJson(QJsonObject &location_data) override;
};
#endif // QWLOCATION_H

@ -0,0 +1,113 @@
#include "qw_trigger.h"
#include <QJsonArray>
#include <QJsonObject>
#include <QDebug>
QWTrigger::QWTrigger(const QString &path)
{
setPos(0, 0);
setPixmap(QPixmap(":/res/" + path));
}
void QWTrigger::clearEvents() noexcept
{
list_events.clear();
}
void QWTrigger::setEvents(std::initializer_list<std::shared_ptr<QWAbstractEvent>> &&evs) noexcept
{
list_events.clear();
/* For some reason QList(::begin(), ::end())
* doesn't work for MSVC */
#if defined(_MSC_VER)
list_events = QList<std::shared_ptr<QWAbstractEvent>>::fromStdList(std::move(evs));
#else
list_events = QList(evs.begin(), evs.end());
#endif
}
void QWTrigger::setEvents(const QList<std::shared_ptr<QWAbstractEvent>> &evs) noexcept
{
list_events.clear();
list_events = evs;
}
void QWTrigger::addEvents(std::initializer_list<std::shared_ptr<QWAbstractEvent>> &&evs) noexcept
{
list_events.append(std::move(QList<std::shared_ptr<QWAbstractEvent>>(evs)));
}
void QWTrigger::addEvents(const std::shared_ptr<QWAbstractEvent> &ev) noexcept
{
list_events.append(ev);
}
QList<std::shared_ptr<QWAbstractEvent>> QWTrigger::events() const
{
return list_events;
}
void QWTrigger::setCover(qreal x, qreal y, const QString &path) noexcept
{
pix_path = path;
setPixmap(QPixmap(":/res/" + path));
setPos(x, y);
}
void QWTrigger::setCover(const QString &path) noexcept
{
pix_path = path;
setPixmap(QPixmap(":/res/" + path));
}
QString QWTrigger::path() const noexcept
{
return pix_path;
}
void QWTrigger::setExaminationDialogueEvent(const std::shared_ptr<QWAbstractEvent> &dialogue_event)
{
examination_event = dialogue_event;
Q_ASSERT(examination_event);
}
void QWTrigger::startExaminationDialogue() const
{
if (examination_event)
examination_event->execute();
}
void QWTrigger::activate() const
{
for (const auto &ev : list_events) {
Q_ASSERT(ev);
ev->execute();
}
}
////////////////////////
void QWTrigger::writeToJson(QJsonObject &trigger_data)
{
trigger_data.insert("id", tag());
trigger_data.insert("mask", path());
trigger_data.insert("x", x());
trigger_data.insert("y", y());
trigger_data.insert("examine_dialogue", examination_event->tag());
qDebug() << " The trigger:\n" << " id " << tag()
<< "\n mask " << tag()
<< "\n xy " << x() << " " << y()
<< "\n examine_dialogue " << examination_event->tag();
// - Trigger events - //
QJsonArray json_trevents;
for (const auto &tr_event : events()) {
json_trevents.append(tr_event->tag());
qDebug() << " event: " << tr_event->tag();
}
trigger_data.insert("evs", json_trevents);
}

@ -0,0 +1,46 @@
#ifndef TRIGGER_H
#define TRIGGER_H
#include <memory>
#include <QGraphicsPixmapItem>
#include "events/qw_abstractevent.h"
/* QWTrigger
* Represents an interactive in-game element. */
class QWStartDialogueEvent;
class QWTrigger : public QGraphicsPixmapItem, public QWTagHolder
{
private:
QList<std::shared_ptr<QWAbstractEvent>> list_events;
std::shared_ptr<QWAbstractEvent> examination_event;
QString pix_path;
public:
explicit QWTrigger(const QString &path);
void clearEvents() noexcept;
void setEvents(std::initializer_list<std::shared_ptr<QWAbstractEvent>> &&evs) noexcept;
void setEvents(const QList<std::shared_ptr<QWAbstractEvent>> &evs) noexcept;
void addEvents(std::initializer_list<std::shared_ptr<QWAbstractEvent>> &&evs) noexcept;
void addEvents(const std::shared_ptr<QWAbstractEvent> &ev) noexcept;
QList<std::shared_ptr<QWAbstractEvent>> events() const;
void setCover(qreal x, qreal y, const QString &path) noexcept;
void setCover(const QString &path) noexcept;
inline QString path() const noexcept;
void setExaminationDialogueEvent(const std::shared_ptr<QWAbstractEvent> &dialogue_event);
void startExaminationDialogue() const;
void activate() const;
////////////////////////
void writeToJson(QJsonObject &trigger_data) override;
};
#endif // TRIGGER_H

@ -0,0 +1,21 @@
import QtQuick 2.6
import QtQuick.Controls 2.0
ApplicationWindow {
id: root
width: 300
height: 480
visible: true
/* This absolutely does not make any practical sense,
* I just try to make it work and see what's
* gonna happen */
TextField {
text: dialogue.exit_code
placeholderText: qsTr("exit code")
anchors.centerIn: parent
onTextChanged: dialogue.exit_code = text
}
}

@ -0,0 +1,42 @@
#include "qw_globalmetadata.h"
#include <QString>
#include <QJsonObject>
#include <QJsonDocument>
#include <QFile>
#include <QDir>
QJsonObject QWGlobalMetadata::config = QJsonObject();
void QWGlobalMetadata::load()
{
QFile file("config.json");
if (!file.exists())
QFile::copy(":/res/config.json", file.fileName());
Q_ASSERT(file.open(QIODevice::ReadOnly));
const QByteArray json_arr = file.readAll();
file.close();
config = QJsonDocument::fromJson(json_arr).object();
}
void QWGlobalMetadata::save()
{
QFile file("config.json");
Q_ASSERT(file.open(QIODevice::WriteOnly));
file.write(QJsonDocument(config).toJson());
file.close();
}
////////////////////////
QVariant QWGlobalMetadata::valueBy(QString &&key)
{
return config[key].toVariant();
}
void QWGlobalMetadata::setValue(QString &&key, const QVariant &val) noexcept
{
config.insert(key, val.toJsonValue());
}

@ -0,0 +1,30 @@
#ifndef GLOBALMETADATA_H
#define GLOBALMETADATA_H
#include <QVariant>
/* QWGlobalMetadata
* Provides config options and metadata for all application classes. */
class QJsonObject;
class QString;
class QWGlobalMetadata final
{
private:
static QJsonObject config;
public:
explicit QWGlobalMetadata() = delete;
~QWGlobalMetadata() = delete;
static void load();
static void save();
////////////////////////
static QVariant valueBy(QString &&key);
static void setValue(QString &&key, const QVariant &val) noexcept;
};
#endif // GLOBALMETADATA_H

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

@ -0,0 +1,28 @@
{
"InventoryManager:length_wall": 15,
"InventoryManager:length_cell": 120,
"InventoryManager:max_amount": 7,
"InventoryManager:first_wall": 0,
"InventoryManager:clr_sel": 12,
"InventoryManager:clr_str": 0.5,
"InventoryPanel:pixmap_path": ":/res/inv.jpg",
"InventoryPanel:on_hid:bot_left_x": 220,
"InventoryPanel:on_hid:bot_left_y": -130,
"InventoryPanel:on_hid:top_right_x": 1060,
"InventoryPanel:on_hid:top_right_y": 0,
"InventoryPanel:on_shw:bot_left_x": 220,
"InventoryPanel:on_shw:bot_left_y": 50,
"InventoryPanel:on_shw:top_right_x": 1060,
"InventoryPanel:on_shw:top_right_y": 170,
"DialoguePanel:pixmap_path": ":/res/dialogue_panel.jpeg",
"DialoguePanel:on_hid:bot_left_x": 110,
"DialoguePanel:on_hid:bot_left_y": -130,
"DialoguePanel:on_hid:top_right_x": 1170,
"DialoguePanel:on_hid:top_right_y": 0,
"DialoguePanel:on_shw:bot_left_x": 110,
"DialoguePanel:on_shw:bot_left_y": 51,
"DialoguePanel:on_shw:top_right_x": 1070,
"DialoguePanel:on_shw:top_right_y": 449
}

@ -0,0 +1,260 @@
{
"init_level": "start",
"start": {
"init": "spawn",
"dialogues": [
{
"id": "on_spawn",
"text": [
"\"Мастер мертв. Он даже не подозревал, что я отравил его вино.\"",
"\"Старый дурак.\"",
"\"Все его секреты заперты внутри его мастерской.\"",
"\"Он никогда не пускал меня внутрь, лишь давал свои глупые поручения.\"",
"\"Мой час настал.\"",
"\"Я заберу то, что теперь принадлежит мне, и никто не сможет меня остановить.\""
],
"type": 0
},
{
"id": "door_general_on_closed",
"text": [
"Путь преграждает дверь в виде массивного механизма.",
"Силой вскрыть не получается."
],
"type": 0
},
{
"id": "door_general_on_look",
"text": [
"\"Чертов безумец!\"",
"\"Кто же в собственную мастерскую делает такую дверь!\"",
"\"Видимо, отмычки тут не помогут.\""
],
"type": 0
},
{
"id": "diary_on_taking",
"text": [
"Старый потрепанный дневник мастера.",
"Страницы исписаны неровным подчерком,\nно кое-что полезное можно будет узнать."
],
"type": 0
},
{
"id": "diary_on_look",
"text": [
"\"Ого, это же записи мастера!\nМожет пригодиться!\""
],
"type": 0
},
{
"id": "portrait_on_click",
"text": [
"Картина покойного хозяина мастерской. Автопортрет."
],
"type": 0
},
{
"id": "portrait_on_look",
"text": [
"\"Он как будто насмехается надо мной.\nДаже после смерти...\""
],
"type": 0
},
{
"id": "table_on_look",
"text": [
"\"Обычный стол, на нём лежат какие-то бумаги.\""
]
},
{
"id": "mechanism_on_pressed",
"text": [
"Слышан характерный механический звук где-то внутри двери."
],
"type": 0
},
{
"id": "mechanism_on_failure",
"text": [
"После нажатия механизм издает резкий скрежет.",
"Все механизмы вернулись на свои места."
],
"type": 0
}
],
"locations": [
{
"id": "location_room",
"triggers": [ "location_room_background", "painting", "table", "global_door" ]
},
{
"id": "location_table",
"triggers": [ "location_table_background", "diary", "backwarder" ]
},
{
"id": "location_nearby_door",
"triggers": [ "location_nearby_door_background", "door", "backwarder" ]
}
],
"triggers": [
{
"id": "location_nearby_door_background"
},
{
"id": "location_table_background"
},
{
"id": "location_room_background"
},
{
"id": "spawn",
"evs": [
"init",
"dial_on_spawn"
]
},
{
"id": "painting",
"x": 0,
"y": 0,
"evs": [
"dial_portrait_on_click"
],
"examine_dialogue": "dial_portrait_on_look"
},
{
"id": "table",
"x": 0,
"y": 0,
"evs": [
"move_to_table"
],
"examine_dialogue": "dial_table_on_look"
},
{
"id": "backwarder",
"x": 0,
"y": 0,
"evs": [
"move_backward"
]
},
{
"id": "global_door",
"x": 0,
"y": 0,
"evs": [
"move_to_global_door"
],
"examine_dialogue": "dial_global_door_on_look"
},
{
"id": "diary",
"x": 0,
"y": 0,
"evs": [
"dial_diary_on_taking",
"take_diary"
],
"examine_dialogue": "dial_diary_on_look"
},
{
"id": "tr_inv_diary"
},
{
"id": "door",
"x": 0,
"y": 0,
"evs": [
"dial_door_general_on_closed"
],
"examine_dialogue": "dial_door_general_on_look"
}
],
"events": [
{
"id": "dial_on_spawn",
"type": 10,
"dialogue_type": 0,
"dialogue": "on_spawn"
},
{
"id": "dial_portrait_on_click",
"type": 10,
"dialogue_type": 0,
"dialogue": "portrait_on_click"
},
{
"id": "dial_door_general_on_closed",
"type": 10,
"dialogue_type": 0,
"dialogue": "door_general_on_closed"
},
{
"id": "dial_door_general_on_look",
"type": 10,
"dialogue_type": 0,
"dialogue": "door_general_on_look"
},
{
"id": "dial_diary_on_taking",
"type": 10,
"dialogue_type": 0,
"dialogue": "diary_on_taking"
},
{
"id": "dial_diary_on_look",
"type": 10,
"dialogue_type": 0,
"dialogue": "diary_on_look"
},
{
"id": "dial_portrait_on_look",
"type": 10,
"dialogue_type": 0,
"dialogue": "portrait_on_look"
},
{
"id": "dial_table_on_look",
"type": 10,
"dialogue_type": 0,
"dialogue": "table_on_look"
},
{
"id": "dial_global_door_on_look",
"type": 10,
"dialogue_type": 0,
"dialogue": "door_general_on_look"
},
{
"id": "move_to_table",
"type": 0,
"location": "location_table"
},
{
"id": "move_to_global_door",
"type": 0,
"location": "location_nearby_door"
},
{
"id": "move_backward",
"type": 0,
"location": "location_room"
},
{
"id": "take_diary",
"type": 4,
"target": "tr_inv_diary"
}
]
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 507 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

@ -0,0 +1,111 @@
{
"init": "spawn",
"triggers": [
{
"id": "spawn_background"
},
{
"id": "roomkey_background"
},
{
"id": "tr_door1",
"mask": "door",
"x": 55,
"y": 67,
"evs": [ "ev1", "sound_event1" ]
},
{
"id": "tr_osaka1",
"mask": "osaka",
"x": 255,
"y": 367,
"evs": [ "sound_event2" ]
},
{
"id": "tr_osaka2",
"mask": "osaka",
"x": 355,
"y": 467,
"evs": [ "sound_event3" ]
},
{
"id": "tr_osaka3",
"mask": "osaka",
"x": 490,
"y": 500,
"evs": [ "sound_event4" ]
},
{
"id": "tr_osaka4",
"mask": "osaka",
"x": 600,
"y": 200,
"evs": [ "sound_event5" ]
},
{
"id": "tr_osaka5",
"mask": "osaka",
"x": 955,
"y": 400,
"evs": [ "sound_event6" ]
},
{
"id": "spawn",
"mask": "",
"x": 0,
"y": 0,
"evs": [ "init_ev" ]
}
],
"events": [
{
"id": "init_ev",
"type": 0,
"trs": [
"tr_osaka1",
"tr_osaka2",
"tr_osaka3",
"tr_osaka4",
"tr_osaka5",
"spawn_background"
]
},
{
"id": "ev1",
"type": 0,
"trs": ["roomkey_background"]
},
{
"id": "sound_event1",
"type": 5,
"sound": "sound"
},
{
"id": "sound_event2",
"type": 5,
"sound": "sound"
},
{
"id": "sound_event3",
"type": 5,
"sound": "sound"
},
{
"id": "sound_event4",
"type": 5,
"sound": "sound"
},
{
"id": "sound_event5",
"type": 5,
"sound": "sound"
},
{
"id": "sound_event6",
"type": 5,
"sound": "sound"
}
]
}

@ -0,0 +1,53 @@
{
"init_level": "menu",
"menu":
{
"init": "spawn",
"triggers": [
{
"id": "spawn",
"evs": [ "init_ev" ]
},
{
"id": "menu_background",
"mask": "menu_background"
},
{
"id": "opt_start_new_game",
"x": 40,
"y": 216,
"evs": [ "start_new_game" ]
},
{
"id": "opt_quit_game",
"x": 40,
"y": 416,
"evs": [ "quit_game" ]
}
],
"events": [
{
"id": "init_ev",
"type": 0,
"trs": [
"opt_quit_game",
"opt_start_new_game",
"menu_background"
]
},
{
"id": "start_new_game",
"type": 8,
"save_file": "wow_new_game_test"
},
{
"id": "quit_game",
"type": 9,
"save_game": false
}
]
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

@ -0,0 +1,37 @@
#include "pushbuttonsound.h"
#include "features/gamefeatures.h"
PushButtonSound::PushButtonSound(const QPixmap &pixmap_off, QGraphicsItem *parent) :
b_on(false),
pix_on(pixmap_off),
pix_off(pixmap_off)
{
setParentItem(parent);
Q_ASSERT(!pixmap_off.isNull());
}
void PushButtonSound::onClick()
{
b_on = !b_on;
emit signalChangeSound(b_on);
}
void PushButtonSound::onConnect(std::unique_ptr<GameFeatures> &game_features)
{
QObject::connect(this, //sender
SIGNAL(signalChangeSound(bool)),
game_features->ptr_sound_player, //receiver
SLOT(setMuteness(bool)));
}
////////////////////////
void PushButtonSound::setPixmapOn(const QPixmap &pixmap_on) noexcept
{
pix_on = pixmap_on;
}
void PushButtonSound::setPixmapOff(const QPixmap &pixmap_off) noexcept
{
pix_off = pixmap_off;
}

@ -0,0 +1,40 @@
#ifndef PUSHBUTTONSOUND_H
#define PUSHBUTTONSOUND_H
#include <QPainter>
#include "qw_abstractscenecontrol.h"
/* PushButtonSound
* Switches current sound state. */
class PushButtonSound : public QWAbstractSceneControl
{
Q_OBJECT
private:
bool b_on;
QPixmap pix_on;
QPixmap pix_off;
protected:
void paint(QPainter *painter, const QStyleOptionGraphicsItem *,
QWidget *) override
{
painter->fillRect(rect(), QBrush(b_on ? pix_on : pix_off));
}
public:
explicit PushButtonSound(const QPixmap &pixmap_off, QGraphicsItem *parent = nullptr);
virtual ~PushButtonSound() override {}
void onClick() override;
void onConnect(std::unique_ptr<GameFeatures> &game_features) override;
////////////////////////
inline void setPixmapOn(const QPixmap &pixmap_on) noexcept;
inline void setPixmapOff(const QPixmap &pixmap_off) noexcept;
signals:
void signalChangeSound(bool);
};
#endif // PUSHBUTTONSOUND_H

@ -0,0 +1,13 @@
#include "qw_abstractscenecontrol.h"
QWAbstractSceneControl:: QWAbstractSceneControl()
{}
QWAbstractSceneControl::~QWAbstractSceneControl()
{}
void QWAbstractSceneControl::onBuildingStateMachine(QWStateMachine *state_machine, std::unique_ptr<GameFeatures> &game_features)
{
Q_UNUSED(state_machine)
Q_UNUSED(game_features)
}

@ -0,0 +1,25 @@
#ifndef ABSTRACTSCENECONTROL_H
#define ABSTRACTSCENECONTROL_H
#include <memory>
#include <QGraphicsWidget>
/* QWAbstractSceneControl
* Interface for scene graphics elements which have
* to manipulate non-logic game processes like sound, view, etc. */
struct GameFeatures;
class QWStateMachine;
class QWAbstractSceneControl : public QGraphicsWidget
{
public:
QWAbstractSceneControl();
~QWAbstractSceneControl() = 0;
virtual void onClick() = 0;
virtual void onConnect(std::unique_ptr<GameFeatures> &game_features) = 0;
virtual void onBuildingStateMachine(QWStateMachine *state_machine, std::unique_ptr<GameFeatures> &game_features);
};
#endif // ABSTRACTSCENECONTROL_H

@ -0,0 +1,71 @@
#include "scenedialoguepanel.h"
#include "features/gamefeatures.h"
#include "features/qw_statemachine.h"
#include "qw_globalmetadata.h"
SceneDialoguePanel::SceneDialoguePanel()
{
metadata.pixmap_path = QWGlobalMetadata::valueBy("DialoguePanel:pixmap_path").toString();
metadata.on_hid = QRect(QPoint(QWGlobalMetadata::valueBy("DialoguePanel:on_hid:bot_left_x" ).toInt(), // x1
QWGlobalMetadata::valueBy("DialoguePanel:on_hid:bot_left_x" ).toInt()), // y1
QPoint(QWGlobalMetadata::valueBy("DialoguePanel:on_hid:top_right_x").toInt(), // x4
QWGlobalMetadata::valueBy("DialoguePanel:on_hid:top_right_y").toInt())); // y4
metadata.on_shw = QRect(QPoint(QWGlobalMetadata::valueBy("DialoguePanel:on_shw:bot_left_x" ).toInt(), // x1
QWGlobalMetadata::valueBy("DialoguePanel:on_shw:bot_left_x" ).toInt()), // y1
QPoint(QWGlobalMetadata::valueBy("DialoguePanel:on_shw:top_right_x").toInt(), // x4
QWGlobalMetadata::valueBy("DialoguePanel:on_shw:top_right_y").toInt())); // y4
/* /
* 2-------4 /
* | | <-
* 1-------3
*/
setPixmap(QPixmap(metadata.pixmap_path));
Q_ASSERT(!pix_rect.isNull());
}
void SceneDialoguePanel::onClick()
{}
void SceneDialoguePanel::onConnect(std::unique_ptr<GameFeatures> &game_features)
{
game_features->ptr_text_dlg->setDialoguePanel(shared_from_this());
}
void SceneDialoguePanel::onBuildingStateMachine(QWStateMachine *state_machine, std::unique_ptr<GameFeatures> &game_features)
{
// Establisihing animation for dialogue panel
const auto &state_gameplay = state_machine->stateByKey("state_gameplay");
QState *state_dialogue = new QState;
state_machine->registerState("state_dialogue", state_dialogue);
connect(state_dialogue, SIGNAL(entered()), game_features->ptr_scene, SLOT(onEntryDialogue()));
QSignalTransition *enter_dialogue_transition = new QSignalTransition(game_features->ptr_text_dlg, SIGNAL(onEntryDialogueTransition()));
enter_dialogue_transition->setTargetState(state_dialogue);
state_gameplay->addTransition(enter_dialogue_transition);
QSignalTransition *leave_dialogue_transition = new QSignalTransition(game_features->ptr_text_dlg, SIGNAL(onLeaveDialogueTransition()));
leave_dialogue_transition->setTargetState(state_gameplay);
state_dialogue->addTransition(leave_dialogue_transition);
state_gameplay->assignProperty(this, "geometry", metadata.on_hid);
state_dialogue->assignProperty(this, "geometry", metadata.on_shw);
state_machine->addState(state_dialogue);
}
////////////////////////
void SceneDialoguePanel::setPixmap(const QPixmap &pix) noexcept
{
pix_rect = pix;
Q_ASSERT(!pix_rect.isNull());
}
QPixmap SceneDialoguePanel::pixmap() const noexcept
{
return pix_rect;
}

@ -0,0 +1,45 @@
#ifndef SCENEDIALOGUEPANEL_H
#define SCENEDIALOGUEPANEL_H
#include <QPainter>
#include "qw_abstractscenecontrol.h"
/* SceneDialoguePanel
* The view for dialogue processes like text, thoughts, etc. */
class SceneDialoguePanel : public QWAbstractSceneControl, public std::enable_shared_from_this<SceneDialoguePanel>
{
private:
QPixmap pix_rect;
struct metadata
{
// path to panel pixmap
QString pixmap_path;
// rect when panel is hidden
QRect on_hid;
// rect when panel is shown
QRect on_shw;
} metadata;
protected:
void paint(QPainter *painter, const QStyleOptionGraphicsItem *,
QWidget *) override
{
painter->fillRect(rect(), QBrush(pix_rect));
}
public:
explicit SceneDialoguePanel();
virtual ~SceneDialoguePanel() override {}
void onClick() override;
void onConnect(std::unique_ptr<GameFeatures> &game_features) override;
void onBuildingStateMachine(QWStateMachine *state_machine, std::unique_ptr<GameFeatures> &game_features) override;
////////////////////////
inline void setPixmap(const QPixmap &pix) noexcept;
inline QPixmap pixmap() const noexcept;
};
#endif // SCENEDIALOGUEPANEL_H

@ -0,0 +1,85 @@
#include "sceneinventorypanel.h"
#include "features/gamefeatures.h"
#include "features/qw_statemachine.h"
#include "qw_globalmetadata.h"
SceneInventoryPanel::SceneInventoryPanel()
{
metadata.pixmap_path = QWGlobalMetadata::valueBy("InventoryPanel:pixmap_path").toString();
metadata.on_hid = QRect(QPoint(QWGlobalMetadata::valueBy("InventoryPanel:on_hid:bot_left_x" ).toInt(), // x1
QWGlobalMetadata::valueBy("InventoryPanel:on_hid:bot_left_y" ).toInt()), // y1
QPoint(QWGlobalMetadata::valueBy("InventoryPanel:on_hid:top_right_x").toInt(), // x4
QWGlobalMetadata::valueBy("InventoryPanel:on_hid:top_right_y").toInt())); // y4
metadata.on_shw = QRect(QPoint(QWGlobalMetadata::valueBy("InventoryPanel:on_shw:bot_left_x" ).toInt(), // x1
QWGlobalMetadata::valueBy("InventoryPanel:on_shw:bot_left_y" ).toInt()), // y1
QPoint(QWGlobalMetadata::valueBy("InventoryPanel:on_shw:top_right_x").toInt(), // x4
QWGlobalMetadata::valueBy("InventoryPanel:on_shw:top_right_y").toInt())); // y4
/* /
* 2-------4 /
* | | <-
* 1-------3
*/
setPixmap(QPixmap(metadata.pixmap_path));
}
void SceneInventoryPanel::onClick()
{
emit signalOnInventory();
}
void SceneInventoryPanel::onConnect(std::unique_ptr<GameFeatures> &game_features)
{
game_features->ptr_inventory->setInventoryPanel(shared_from_this());
QObject::connect(this, //sender
SIGNAL(signalOnInventory()),
game_features->ptr_inventory, // receiver
SLOT(onClicked()));
}
void SceneInventoryPanel::onBuildingStateMachine(QWStateMachine *state_machine, std::unique_ptr<GameFeatures> &game_features)
{
// Establisihing animation for inventory panel
QPropertyAnimation *anim = new QPropertyAnimation(shared_from_this().get(), "geometry");
anim->setDuration(200);
anim->setEasingCurve(QEasingCurve::InBack);
QState *state_gameplay = new QState;
state_machine->registerState("state_gameplay", state_gameplay);
connect(state_gameplay, SIGNAL(entered()), game_features->ptr_scene, SLOT(onEntryGameplay()));
QState *state_inventory = new QState;
state_machine->registerState("state_inventory", state_inventory);
connect(state_inventory, SIGNAL(entered()), game_features->ptr_scene, SLOT(onEntryInventory()));
QEventTransition *enter_inventory_transition = new QEventTransition(game_features->ptr_view, QEvent::Wheel);
enter_inventory_transition->setTargetState(state_inventory);
enter_inventory_transition->addAnimation(anim);
state_gameplay->addTransition(enter_inventory_transition);
QEventTransition *leave_inventory_transition = new QEventTransition(game_features->ptr_view, QEvent::Wheel);
leave_inventory_transition->setTargetState(state_gameplay);
leave_inventory_transition->addAnimation(anim);
state_inventory->addTransition(leave_inventory_transition);
state_gameplay->assignProperty(this, "geometry", metadata.on_hid);
state_inventory->assignProperty(this, "geometry", metadata.on_shw);
state_machine->addState(state_gameplay);
state_machine->addState(state_inventory);
}
////////////////////////
void SceneInventoryPanel::setPixmap(const QPixmap &pix) noexcept
{
pix_rect = pix;
Q_ASSERT(!pix_rect.isNull());
}
QPixmap SceneInventoryPanel::pixmap() const noexcept
{
return pix_rect;
}

@ -0,0 +1,49 @@
#ifndef SCENEINVENTORYPANEL_H
#define SCENEINVENTORYPANEL_H
#include <QPainter>
#include "qw_abstractscenecontrol.h"
/* SceneInventoryPanel
* The view for inventory and all its items on the scene. */
class SceneInventoryPanel : public QWAbstractSceneControl, public std::enable_shared_from_this<SceneInventoryPanel>
{
Q_OBJECT
private:
QPixmap pix_rect;
struct metadata
{
// path to panel pixmap
QString pixmap_path;
// rect when panel is hidden
QRect on_hid;
// rect when panel is shown
QRect on_shw;
} metadata;
protected:
void paint(QPainter *painter, const QStyleOptionGraphicsItem *,
QWidget *) override
{
painter->fillRect(rect(), QBrush(pix_rect));
}
public:
explicit SceneInventoryPanel();
virtual ~SceneInventoryPanel() override {}
void onClick() override;
void onConnect(std::unique_ptr<GameFeatures> &game_features) override;
void onBuildingStateMachine(QWStateMachine *state_machine, std::unique_ptr<GameFeatures> &game_features) override;
////////////////////////
inline void setPixmap(const QPixmap &pix) noexcept;
inline QPixmap pixmap() const noexcept;
signals:
void signalOnInventory();
};
#endif // SCENEINVENTORYPANEL_H

@ -0,0 +1,128 @@
#include "qw_scene.h"
#include "models/qw_trigger.h"
#include "controls/sceneinventorypanel.h"
#include "controls/pushbuttonsound.h"
#include "controls/scenedialoguepanel.h"
QWScene::QWScene(int x, int y) :
QGraphicsScene(0, 0, x, y)
{
QLinkedList<std::shared_ptr<QWAbstractSceneControl>> widgt_list =
{ std::make_shared<SceneInventoryPanel>(),
std::make_shared<SceneDialoguePanel>()
//std::make_shared<PushButtonSound>(QPixmap(":/res/cell.png")/*, ptr_inventory_panel.get()*/),
};
foreach (std::shared_ptr<QWAbstractSceneControl> widgt, widgt_list) {
addItem(widgt.get());
list_on_inventory_widgets.append(std::move(widgt));
}
}
QLinkedList<std::shared_ptr<QWAbstractSceneControl>> QWScene::inventoryWidgets() const noexcept
{
return list_on_inventory_widgets;
}
void QWScene::onEntryGameplay() noexcept
{
status = GAMEPLAY;
}
void QWScene::onEntryInventory() noexcept
{
status = INVENTORY;
}
void QWScene::onEntryMenu() noexcept
{
status = MENU;
emit signalEnterMenu();
}
void QWScene::onEntryDialogue() noexcept
{
status = DIALOGUE;
}
void QWScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
switch (status)
{
case MENU:
case GAMEPLAY:
// On GAMEPLAY and MENU state we check all the in-game entities.
foreach (std::shared_ptr<QWTrigger> tr, location->triggers()) {
if (tr->isUnderMouse() && event->button() == Qt::LeftButton)
tr->activate();
}
break;
case INVENTORY:
// On INVENTORY state we check all the system controls like buttons for sound, etc.
foreach (std::shared_ptr<QWAbstractSceneControl> tr, list_on_inventory_widgets) {
if (tr->isUnderMouse() && event->button() == Qt::LeftButton)
tr->onClick();
}
break;
case DIALOGUE:
// On DIALOGUE state we interact with current dialogue only.
switch (event->button()) {
case Qt::LeftButton:
emit signalClickDialogue(MouseButton::LEFT);
break;
case Qt::RightButton:
emit signalClickDialogue(MouseButton::RIGHT);
break;
default:
break;
}
break;
case EXAMINATION:
// On EXAMINATION state we activate examination events of triggers
foreach (std::shared_ptr<QWTrigger> tr, location->triggers()) {
if (tr->isUnderMouse() && event->button() == Qt::LeftButton)
emit signalLeaveExamination();
tr->startExaminationDialogue();
}
break;
}
}
void QWScene::keyReleaseEvent(QKeyEvent *event)
{
switch (status)
{
case GAMEPLAY:
if (event->key() == Qt::Key_E)
emit signalEnterExamination();
break;
default:
return;
}
}
void QWScene::clearLocation()
{
if (!location)
return;
// Moving to another location by erasing current
foreach (const std::shared_ptr<QWTrigger> trigger, location->triggers())
removeItem(trigger.get());
location = nullptr;
}
void QWScene::setCurrentLocation(const std::shared_ptr<QWLocation> &loc) noexcept
{
location = loc;
}
std::shared_ptr<QWLocation> QWScene::currentLocation() const noexcept
{
return location;
}

@ -0,0 +1,61 @@
#ifndef QUESTSCENE_H
#define QUESTSCENE_H
#include <memory>
#include <QGraphicsScene>
#include <QGraphicsSceneMouseEvent>
#include <QGraphicsEffect>
#include <QLinkedList>
#include "models/qw_location.h"
#include "controls/qw_abstractscenecontrol.h"
/* QWScene
* The game scene itself. */
enum class MouseButton { LEFT, RIGHT };
class QWDialogueFrame;
class QWScene final : public QGraphicsScene
{
Q_OBJECT
Q_DISABLE_COPY_MOVE(QWScene)
private:
std::shared_ptr<QWLocation> location;
QLinkedList<std::shared_ptr<QWAbstractSceneControl>> list_on_inventory_widgets;
enum SceneStatus { GAMEPLAY, INVENTORY, MENU, DIALOGUE, EXAMINATION };
SceneStatus status;
protected:
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
void keyReleaseEvent(QKeyEvent *event) override;
public:
explicit QWScene(int x, int y);
QLinkedList<std::shared_ptr<QWAbstractSceneControl>> inventoryWidgets() const noexcept;
void setCurrentLocation(const std::shared_ptr<QWLocation> &loc) noexcept;
std::shared_ptr<QWLocation> currentLocation() const noexcept;
void clearLocation();
void onEndLevel(const QString &str) noexcept;
signals:
void signalClickInventory();
void signalClickDialogue(MouseButton);
void signalEnterMenu();
void signalLeaveMenu();
void signalEnterExamination();
void signalLeaveExamination();
public slots:
void onEntryGameplay() noexcept;
void onEntryInventory() noexcept;
void onEntryMenu() noexcept;
void onEntryDialogue() noexcept;
};
#endif // QUESTSCENE_H

@ -0,0 +1,9 @@
#include "qw_view.h"
QWView::QWView(QWScene *sc) :
scene(sc)
{
setScene(sc);
//setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
//setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
}

@ -0,0 +1,29 @@
#ifndef QUESTVIEW_H
#define QUESTVIEW_H
#include <QGraphicsView>
#include "qw_scene.h"
/* QWView
* The same QGraphicsView but this one ignores wheel events,
* because wheels are for loosers. */
class QWView final : public QGraphicsView
{
Q_OBJECT
Q_DISABLE_COPY_MOVE(QWView)
private:
QWScene *scene;
protected:
void wheelEvent(QWheelEvent *ev) override
{
ev->ignore();
}
public:
explicit QWView(QWScene *sc);
};
#endif // QUESTVIEW_H
Loading…
Cancel
Save