2021-06-15 22:12:41 +03:00
|
|
|
//#
|
|
|
|
//# Copyright (C) 2021-2021 QuasarApp.
|
|
|
|
//# Distributed under the GPLv3 software license, see the accompanying
|
|
|
|
//# Everyone is permitted to copy and distribute verbatim copies
|
|
|
|
//# of this license document, but changing it is not allowed.
|
|
|
|
//#
|
|
|
|
|
2021-06-14 18:15:59 +03:00
|
|
|
#include "iai.h"
|
2021-06-06 15:53:49 +03:00
|
|
|
#include "iworld.h"
|
2021-06-07 17:37:03 +03:00
|
|
|
#include "iworlditem.h"
|
2021-06-14 18:15:59 +03:00
|
|
|
#include <defaultbackgroundai.h>
|
2021-06-06 22:10:43 +03:00
|
|
|
#include <quasarapp.h>
|
2021-06-09 16:38:55 +03:00
|
|
|
#include "iground.h"
|
2021-06-12 18:20:29 +03:00
|
|
|
#include "defaultcontrol.h"
|
2021-06-14 18:15:59 +03:00
|
|
|
#include "worldstatus.h"
|
2021-06-15 16:04:18 +03:00
|
|
|
#include "iai.h"
|
2021-06-06 15:53:49 +03:00
|
|
|
|
|
|
|
IWorld::IWorld() {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
IWorld::~IWorld() {
|
|
|
|
deinit();
|
|
|
|
}
|
|
|
|
|
2021-06-11 21:31:41 +03:00
|
|
|
IControl *IWorld::initUserInterface() const {
|
2021-06-12 18:20:29 +03:00
|
|
|
return new DefaultControl;
|
2021-06-11 21:31:41 +03:00
|
|
|
}
|
|
|
|
|
2021-06-06 22:10:43 +03:00
|
|
|
void IWorld::render(unsigned int tbfMsec) {
|
|
|
|
|
|
|
|
for (auto i = _items.begin(); i != _items.end(); ++i) {
|
|
|
|
(*i).objectPtr->render(tbfMsec);
|
2021-06-07 17:37:03 +03:00
|
|
|
|
|
|
|
// intersects event.
|
|
|
|
if ((*i).objectPtr->intersects(*_player)) {
|
|
|
|
_player->onIntersects((*i).objectPtr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_player->isDead()) {
|
|
|
|
emit sigGameFinished(_player->getCurrentStatus());
|
2021-06-06 22:10:43 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-06-15 16:04:18 +03:00
|
|
|
void IWorld::initPlayerControl(IControl *control) {
|
|
|
|
auto controlObject = dynamic_cast<DefaultControl*>(control);
|
|
|
|
|
|
|
|
if (controlObject) {
|
|
|
|
connect(controlObject, &DefaultControl::backToMenu, this, &IWorld::handleStop);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-06-11 18:09:03 +03:00
|
|
|
bool IWorld::start() {
|
|
|
|
_player->setposition({0,0,0});
|
|
|
|
_player->setSpeed(0);
|
|
|
|
|
2021-06-14 18:15:59 +03:00
|
|
|
setWorldStatus(WorldStatus::Game);
|
|
|
|
_backgroundAI->stopAI();
|
|
|
|
_player->setControl(_userInterface);
|
2021-06-11 18:09:03 +03:00
|
|
|
|
2021-06-16 18:57:50 +03:00
|
|
|
|
|
|
|
worldChanged(*_worldRules->begin());
|
2021-06-11 18:09:03 +03:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2021-06-17 13:57:57 +03:00
|
|
|
QObject *IWorld::player() const {
|
|
|
|
return _player;
|
|
|
|
}
|
|
|
|
|
|
|
|
void IWorld::setPlayer(QObject *newPlayer) {
|
|
|
|
if (_player == newPlayer)
|
|
|
|
return;
|
|
|
|
|
|
|
|
auto newPlayerObject = dynamic_cast<IPlayer*>(newPlayer);
|
|
|
|
if (!newPlayerObject) {
|
|
|
|
QuasarAppUtils::Params::log("Failed to set player object. The input object is not player.",
|
|
|
|
QuasarAppUtils::Error);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_player) {
|
|
|
|
removeItem(_player->guiId());
|
|
|
|
}
|
|
|
|
|
|
|
|
_player = newPlayerObject;
|
|
|
|
addItem("player", _player);
|
|
|
|
|
|
|
|
emit playerChanged();
|
|
|
|
}
|
|
|
|
|
2021-06-14 18:15:59 +03:00
|
|
|
bool IWorld::stop() {
|
|
|
|
start();
|
|
|
|
|
|
|
|
setWorldStatus(WorldStatus::Background);
|
|
|
|
_player->setControl(dynamic_cast<IControl*>(_backgroundAI));
|
|
|
|
|
|
|
|
_backgroundAI->startAI();
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
IAI *IWorld::initBackGroundAI() const {
|
|
|
|
return new DefaultBackgroundAI();
|
|
|
|
}
|
|
|
|
|
2021-06-16 18:57:50 +03:00
|
|
|
IWorldItem *IWorld::getItem(int id) const {
|
2021-06-09 18:23:07 +03:00
|
|
|
return _items.value(id, {}).objectPtr;
|
|
|
|
}
|
|
|
|
|
2021-06-06 15:53:49 +03:00
|
|
|
bool IWorld::init() {
|
|
|
|
|
2021-06-13 15:16:46 +03:00
|
|
|
if (isInit())
|
|
|
|
return true;
|
|
|
|
|
2021-06-06 22:10:43 +03:00
|
|
|
_worldRules = initWorldRules();
|
2021-06-17 13:57:57 +03:00
|
|
|
|
2021-06-06 22:10:43 +03:00
|
|
|
_hdrMap = initHdrBackGround();
|
2021-06-17 13:57:57 +03:00
|
|
|
setPlayer(initPlayer());
|
2021-06-09 16:38:55 +03:00
|
|
|
_player->initOnWorld(this, _player);
|
2021-06-11 21:31:41 +03:00
|
|
|
_userInterface = initUserInterface();
|
2021-06-14 18:15:59 +03:00
|
|
|
_backgroundAI = initBackGroundAI();
|
2021-06-09 16:38:55 +03:00
|
|
|
|
2021-06-13 20:16:36 +03:00
|
|
|
if (!isInit()) {
|
|
|
|
QuasarAppUtils::Params::log("Failed to init world implementation.");
|
|
|
|
deinit();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2021-06-13 15:16:46 +03:00
|
|
|
if (!_worldRules->size()) {
|
|
|
|
deinit();
|
2021-06-06 22:10:43 +03:00
|
|
|
return false;
|
2021-06-13 15:16:46 +03:00
|
|
|
}
|
|
|
|
|
2021-06-15 16:04:18 +03:00
|
|
|
initPlayerControl(_userInterface);
|
|
|
|
initPlayerControl(dynamic_cast<IControl*>(_backgroundAI));
|
2021-06-13 20:16:36 +03:00
|
|
|
|
2021-06-06 22:10:43 +03:00
|
|
|
return true;
|
2021-06-06 15:53:49 +03:00
|
|
|
}
|
|
|
|
|
2021-06-06 22:10:43 +03:00
|
|
|
void IWorld::clearItems() {
|
|
|
|
for (const auto& item : qAsConst(_items)) {
|
|
|
|
delete item.objectPtr;
|
2021-06-06 15:53:49 +03:00
|
|
|
}
|
|
|
|
|
2021-06-06 22:10:43 +03:00
|
|
|
_items.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
void IWorld::deinit() {
|
2021-06-13 15:16:46 +03:00
|
|
|
if (_player) {
|
|
|
|
delete _player;
|
|
|
|
_player = nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_worldRules) {
|
|
|
|
delete _worldRules;
|
|
|
|
_worldRules = nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_userInterface) {
|
|
|
|
delete _userInterface;
|
|
|
|
_userInterface = nullptr;
|
|
|
|
}
|
2021-06-06 15:53:49 +03:00
|
|
|
|
2021-06-15 16:04:18 +03:00
|
|
|
if (_backgroundAI) {
|
|
|
|
delete _backgroundAI;
|
|
|
|
_backgroundAI = nullptr;
|
|
|
|
}
|
|
|
|
|
2021-06-06 22:10:43 +03:00
|
|
|
clearItems();
|
2021-06-06 15:53:49 +03:00
|
|
|
_hdrMap = "";
|
2021-06-06 22:10:43 +03:00
|
|
|
|
2021-06-06 15:53:49 +03:00
|
|
|
}
|
2021-06-06 22:10:43 +03:00
|
|
|
|
2021-06-08 21:56:36 +03:00
|
|
|
|
2021-06-07 17:37:03 +03:00
|
|
|
void IWorld::addItem(const QString& group, IWorldItem* obj) {
|
2021-06-06 22:10:43 +03:00
|
|
|
_items.insert(obj->guiId(), WorldObjectWraper{obj, group});
|
|
|
|
_itemsGroup.insert(group, obj->guiId());
|
|
|
|
}
|
|
|
|
|
|
|
|
bool IWorld::removeItem(int id) {
|
|
|
|
auto obj = _items.value(id);
|
|
|
|
|
|
|
|
if (!obj.objectPtr) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
_itemsGroup.remove(obj.groupName, id);
|
|
|
|
_items.remove(id);
|
|
|
|
|
|
|
|
delete obj.objectPtr;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2021-06-13 20:16:36 +03:00
|
|
|
int IWorld::removeAnyItemFromGroup(const QString &group) {
|
|
|
|
int anyObjectId = _itemsGroup.value(group);
|
|
|
|
if (!removeItem(anyObjectId)) {
|
2021-06-15 09:29:57 +03:00
|
|
|
return false;
|
2021-06-17 13:57:57 +03:00
|
|
|
|
2021-06-13 20:16:36 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
return anyObjectId;
|
2021-06-06 22:10:43 +03:00
|
|
|
}
|
|
|
|
|
2021-06-16 15:46:21 +03:00
|
|
|
const QQuaternion &IWorld::cameraRatation() const {
|
|
|
|
return _cameraRatation;
|
2021-06-14 18:15:59 +03:00
|
|
|
}
|
|
|
|
|
2021-06-16 15:46:21 +03:00
|
|
|
void IWorld::setCameraRatation(const QQuaternion &newCameraRatation) {
|
|
|
|
if (_cameraRatation == newCameraRatation)
|
|
|
|
return;
|
|
|
|
_cameraRatation = newCameraRatation;
|
|
|
|
emit cameraRatationChanged();
|
2021-06-14 18:15:59 +03:00
|
|
|
}
|
|
|
|
|
2021-06-15 16:04:18 +03:00
|
|
|
IAI *IWorld::backgroundAI() const {
|
|
|
|
return _backgroundAI;
|
|
|
|
}
|
|
|
|
|
2021-06-11 21:31:41 +03:00
|
|
|
IControl *IWorld::userInterface() const {
|
|
|
|
return _userInterface;
|
|
|
|
}
|
|
|
|
|
2021-06-13 15:16:46 +03:00
|
|
|
bool IWorld::isInit() const {
|
2021-06-14 18:15:59 +03:00
|
|
|
return _userInterface && _player && _worldRules && _backgroundAI;
|
2021-06-13 15:16:46 +03:00
|
|
|
}
|
|
|
|
|
2021-06-09 16:38:55 +03:00
|
|
|
void IWorld::setCameraReleativePosition(const QVector3D &newCameraReleativePosition) {
|
|
|
|
if (_cameraReleativePosition == newCameraReleativePosition)
|
|
|
|
return;
|
|
|
|
|
|
|
|
_cameraReleativePosition = newCameraReleativePosition;
|
|
|
|
emit cameraReleativePositionChanged();
|
|
|
|
}
|
|
|
|
|
2021-06-14 18:15:59 +03:00
|
|
|
void IWorld::handleStop() {
|
|
|
|
stop();
|
|
|
|
}
|
|
|
|
|
2021-06-09 16:38:55 +03:00
|
|
|
const QVector3D &IWorld::cameraReleativePosition() const {
|
|
|
|
return _cameraReleativePosition;
|
|
|
|
}
|
|
|
|
|
2021-06-08 18:00:42 +03:00
|
|
|
const QString &IWorld::hdrMap() const {
|
|
|
|
return _hdrMap;
|
|
|
|
}
|
|
|
|
|
2021-06-06 22:10:43 +03:00
|
|
|
void IWorld::worldChanged(const WorldObjects &objects) {
|
|
|
|
|
2021-06-13 20:16:36 +03:00
|
|
|
Diff diff;
|
2021-06-06 22:10:43 +03:00
|
|
|
for (auto it = objects.begin(); it != objects.end(); ++it) {
|
|
|
|
|
2021-06-08 21:56:36 +03:00
|
|
|
int count = it.value() - _itemsGroup.count(it.key());
|
2021-06-06 22:10:43 +03:00
|
|
|
|
|
|
|
if (count > 0) {
|
|
|
|
for ( int i = 0; i < count; ++i ) {
|
2021-06-07 17:37:03 +03:00
|
|
|
IWorldItem *obj = generate(it.key());
|
|
|
|
|
2021-06-17 18:32:32 +03:00
|
|
|
TO-Do Add support of clasters.
|
|
|
|
|
2021-06-09 16:38:55 +03:00
|
|
|
obj->initOnWorld(this, _player);
|
2021-06-06 22:10:43 +03:00
|
|
|
|
|
|
|
if (!obj) {
|
2021-06-09 16:38:55 +03:00
|
|
|
QuasarAppUtils::Params::log("object not created line:" +
|
|
|
|
QString::fromLatin1(Q_FUNC_INFO),
|
2021-06-06 22:10:43 +03:00
|
|
|
QuasarAppUtils::Warning);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
addItem(it.key(), obj);
|
2021-06-16 18:57:50 +03:00
|
|
|
diff.addedIds.append(obj->guiId());
|
2021-06-06 22:10:43 +03:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
for (; count < 0; ++count ) {
|
2021-06-13 20:16:36 +03:00
|
|
|
int removedObjectId = removeAnyItemFromGroup(it.key());
|
|
|
|
if (!removedObjectId) {
|
2021-06-06 22:10:43 +03:00
|
|
|
QuasarAppUtils::Params::log("World::changeCountObjects error delete object!",
|
|
|
|
QuasarAppUtils::Warning);
|
|
|
|
break;
|
|
|
|
}
|
2021-06-13 20:16:36 +03:00
|
|
|
diff.removeIds.append(removedObjectId);
|
2021-06-06 22:10:43 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-06-13 20:16:36 +03:00
|
|
|
|
|
|
|
if (diff.addedIds.size() || diff.removeIds.size())
|
|
|
|
emit sigOBjctsListChanged(diff);
|
2021-06-06 22:10:43 +03:00
|
|
|
}
|
|
|
|
|
2021-06-14 18:15:59 +03:00
|
|
|
|
|
|
|
int IWorld::wordlStatus() const {
|
|
|
|
return _worldStatus;
|
|
|
|
}
|
|
|
|
|
|
|
|
void IWorld::setWorldStatus(int newWorldStatus) {
|
2021-06-15 09:29:57 +03:00
|
|
|
if (_worldStatus == newWorldStatus) {
|
2021-06-14 18:15:59 +03:00
|
|
|
return;
|
2021-06-15 09:29:57 +03:00
|
|
|
}
|
2021-06-14 18:15:59 +03:00
|
|
|
_worldStatus = newWorldStatus;
|
|
|
|
emit worldStatusChanged();
|
|
|
|
}
|