[Scene] Splitted into Controllers. [Config] New 'useItemDrop' option.

This commit is contained in:
Quentin Bazin 2020-04-05 01:10:50 +02:00
parent fbbeae5f7f
commit d090e6903d
19 changed files with 408 additions and 50 deletions

View File

@ -29,6 +29,7 @@
// Gameplay
bool Config::isFlyModeEnabled = false;
bool Config::isNoClipEnabled = false;
bool Config::useItemDrops = true;
// Interface
bool Config::isBlockInfoWidgetEnabled = true;
@ -68,6 +69,7 @@ void Config::loadConfigFromFile(const char *file) {
isFlyModeEnabled = lua["isFlyModeEnabled"].get_or(isFlyModeEnabled);
isNoClipEnabled = lua["isNoClipEnabled"].get_or(isNoClipEnabled);
useItemDrops = lua["useItemDrops"].get_or(useItemDrops);
isBlockInfoWidgetEnabled = lua["isBlockInfoWidgetEnabled"].get_or(isBlockInfoWidgetEnabled);
isFpsCounterEnabled = lua["isFpsCounterEnabled"].get_or(isFpsCounterEnabled);

View File

@ -33,6 +33,7 @@ namespace Config {
// Gameplay
extern bool isFlyModeEnabled;
extern bool isNoClipEnabled;
extern bool useItemDrops;
// Interface
extern bool isBlockInfoWidgetEnabled;

View File

@ -149,8 +149,11 @@ void BlockCursor::update(const Hotbar &hotbar) {
timeToBreak = m_currentBlock->timeToBreak(currentStack.item().harvestCapability(), currentStack.item().miningSpeed());
if (ticks > m_animationStart + timeToBreak * 1000) {
ItemStack itemDrop = m_currentBlock->getItemDrop();
m_player.inventory().addStack(itemDrop.item().stringID(), itemDrop.amount());
if (!Config::useItemDrops) {
ItemStack itemDrop = m_currentBlock->getItemDrop();
m_player.inventory().addStack(itemDrop.item().stringID(), itemDrop.amount());
}
m_world.setBlock(m_selectedBlock.x, m_selectedBlock.y, m_selectedBlock.z, 0);
m_animationStart = ticks;

View File

@ -0,0 +1,58 @@
/*
* =====================================================================================
*
* OpenMiner
*
* Copyright (C) 2018-2020 Unarelith, Quentin Bazin <openminer@unarelith.net>
* Copyright (C) 2019-2020 the OpenMiner contributors (see CONTRIBUTORS.md)
*
* This file is part of OpenMiner.
*
* OpenMiner is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* OpenMiner is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with OpenMiner; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* =====================================================================================
*/
#ifndef ANIMATIONCOMPONENT_HPP_
#define ANIMATIONCOMPONENT_HPP_
enum class AnimationType {
Rotation,
};
struct AnimationComponent {
AnimationComponent(float axisX, float axisY, float axisZ, float angle) {
type = AnimationType::Rotation;
rotation.axisX = axisX;
rotation.axisY = axisY;
rotation.axisZ = axisZ;
rotation.angle = angle;
}
AnimationType type;
union {
struct {
float axisX;
float axisY;
float axisZ;
float angle;
} rotation;
};
};
#endif // ANIMATIONCOMPONENT_HPP_

View File

@ -0,0 +1,38 @@
/*
* =====================================================================================
*
* OpenMiner
*
* Copyright (C) 2018-2020 Unarelith, Quentin Bazin <openminer@unarelith.net>
* Copyright (C) 2019-2020 the OpenMiner contributors (see CONTRIBUTORS.md)
*
* This file is part of OpenMiner.
*
* OpenMiner is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* OpenMiner is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with OpenMiner; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* =====================================================================================
*/
#include "AnimationComponent.hpp"
#include "AnimationController.hpp"
#include "InventoryCube.hpp"
void AnimationController::update(entt::DefaultRegistry &registry) {
// FIXME: This shouldn't use InventoryCube but a more generic class
registry.view<InventoryCube, AnimationComponent>().each([](auto, auto &cube, auto &animation) {
if (animation.type == AnimationType::Rotation)
cube.rotate(animation.rotation.angle, {animation.rotation.axisX, animation.rotation.axisY, animation.rotation.axisZ});
});
}

View File

@ -0,0 +1,37 @@
/*
* =====================================================================================
*
* OpenMiner
*
* Copyright (C) 2018-2020 Unarelith, Quentin Bazin <openminer@unarelith.net>
* Copyright (C) 2019-2020 the OpenMiner contributors (see CONTRIBUTORS.md)
*
* This file is part of OpenMiner.
*
* OpenMiner is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* OpenMiner is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with OpenMiner; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* =====================================================================================
*/
#ifndef ANIMATIONCONTROLLER_HPP_
#define ANIMATIONCONTROLLER_HPP_
#include <entt/entt.hpp>
class AnimationController {
public:
static void update(entt::DefaultRegistry &registry);
};
#endif // ANIMATIONCONTROLLER_HPP_

View File

@ -0,0 +1,43 @@
/*
* =====================================================================================
*
* OpenMiner
*
* Copyright (C) 2018-2020 Unarelith, Quentin Bazin <openminer@unarelith.net>
* Copyright (C) 2019-2020 the OpenMiner contributors (see CONTRIBUTORS.md)
*
* This file is part of OpenMiner.
*
* OpenMiner is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* OpenMiner is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with OpenMiner; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* =====================================================================================
*/
#include "ClientPlayer.hpp"
#include "CollisionController.hpp"
#include "InventoryCube.hpp"
#include "ItemStack.hpp"
void CollisionController::update(entt::DefaultRegistry &registry, ClientPlayer &player) {
// FIXME: This shouldn't use InventoryCube, but instead a callback stored in a CollisionComponent
registry.view<InventoryCube, gk::DoubleBox, ItemStack>().each([&](auto entity, auto &cube, auto &box, auto &itemStack) {
gk::DoubleBox hitbox = box + cube.getPosition();
gk::DoubleBox playerHitbox = player.hitbox() + gk::Vector3d{player.x(), player.y(), player.z()};
if (hitbox.intersects(playerHitbox)) {
player.inventory().addStack(itemStack.item().stringID(), itemStack.amount());
registry.destroy(entity);
}
});
}

View File

@ -0,0 +1,39 @@
/*
* =====================================================================================
*
* OpenMiner
*
* Copyright (C) 2018-2020 Unarelith, Quentin Bazin <openminer@unarelith.net>
* Copyright (C) 2019-2020 the OpenMiner contributors (see CONTRIBUTORS.md)
*
* This file is part of OpenMiner.
*
* OpenMiner is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* OpenMiner is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with OpenMiner; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* =====================================================================================
*/
#ifndef COLLISIONCONTROLLER_HPP_
#define COLLISIONCONTROLLER_HPP_
#include <entt/entt.hpp>
class ClientPlayer;
class CollisionController {
public:
static void update(entt::DefaultRegistry &registry, ClientPlayer &player);
};
#endif // COLLISIONCONTROLLER_HPP_

View File

@ -0,0 +1,45 @@
/*
* =====================================================================================
*
* OpenMiner
*
* Copyright (C) 2018-2020 Unarelith, Quentin Bazin <openminer@unarelith.net>
* Copyright (C) 2019-2020 the OpenMiner contributors (see CONTRIBUTORS.md)
*
* This file is part of OpenMiner.
*
* OpenMiner is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* OpenMiner is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with OpenMiner; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* =====================================================================================
*/
#include "AnimationComponent.hpp"
#include "InventoryCube.hpp"
#include "ItemDropFactory.hpp"
#include "ItemStack.hpp"
#include "Registry.hpp"
void ItemDropFactory::create(entt::DefaultRegistry &registry, double x, double y, double z, const std::string &itemID, u16 amount) {
auto entity = registry.create();
InventoryCube &cube = registry.assign<InventoryCube>(entity, 0.25f, true);
cube.setOrigin(cube.size() / 2.f, cube.size() / 2.f, cube.size() / 2.f);
cube.setPosition(x + 0.5, y + 0.5, z + 0.5);
cube.updateVertexBuffer(Registry::getInstance().getBlockFromStringID(itemID));
registry.assign<AnimationComponent>(entity, 0.f, 0.f, 1.f, 0.5f);
registry.assign<gk::DoubleBox>(entity, 0., 0., 0., cube.size(), cube.size(), cube.size());
registry.assign<ItemStack>(entity, itemID, amount);
}

View File

@ -0,0 +1,39 @@
/*
* =====================================================================================
*
* OpenMiner
*
* Copyright (C) 2018-2020 Unarelith, Quentin Bazin <openminer@unarelith.net>
* Copyright (C) 2019-2020 the OpenMiner contributors (see CONTRIBUTORS.md)
*
* This file is part of OpenMiner.
*
* OpenMiner is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* OpenMiner is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with OpenMiner; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* =====================================================================================
*/
#ifndef ITEMDROPFACTORY_HPP_
#define ITEMDROPFACTORY_HPP_
#include <gk/core/IntTypes.hpp>
#include <entt/entt.hpp>
class ItemDropFactory {
public:
static void create(entt::DefaultRegistry &registry, double x, double y, double z, const std::string &itemID, u16 amount = 1);
};
#endif // ITEMDROPFACTORY_HPP_

View File

@ -0,0 +1,36 @@
/*
* =====================================================================================
*
* OpenMiner
*
* Copyright (C) 2018-2020 Unarelith, Quentin Bazin <openminer@unarelith.net>
* Copyright (C) 2019-2020 the OpenMiner contributors (see CONTRIBUTORS.md)
*
* This file is part of OpenMiner.
*
* OpenMiner is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* OpenMiner is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with OpenMiner; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* =====================================================================================
*/
#include "InventoryCube.hpp"
#include "RenderingController.hpp"
void RenderingController::draw(entt::DefaultRegistry &registry, gk::RenderTarget &target, gk::RenderStates states) {
// FIXME: There's probably another way to do this
registry.view<InventoryCube>().each([&](auto, auto &cube) {
target.draw(cube, states);
});
}

View File

@ -0,0 +1,40 @@
/*
* =====================================================================================
*
* OpenMiner
*
* Copyright (C) 2018-2020 Unarelith, Quentin Bazin <openminer@unarelith.net>
* Copyright (C) 2019-2020 the OpenMiner contributors (see CONTRIBUTORS.md)
*
* This file is part of OpenMiner.
*
* OpenMiner is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* OpenMiner is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with OpenMiner; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* =====================================================================================
*/
#ifndef RENDERINGCONTROLLER_HPP_
#define RENDERINGCONTROLLER_HPP_
#include <gk/gl/RenderStates.hpp>
#include <gk/gl/RenderTarget.hpp>
#include <entt/entt.hpp>
class RenderingController {
public:
static void draw(entt::DefaultRegistry &registry, gk::RenderTarget &target, gk::RenderStates states);
};
#endif // RENDERINGCONTROLLER_HPP_

View File

@ -24,54 +24,18 @@
*
* =====================================================================================
*/
#include "AnimationController.hpp"
#include "ClientPlayer.hpp"
#include "CollisionController.hpp"
#include "Scene.hpp"
struct RotationAnimation {
float axisX;
float axisY;
float axisZ;
float angle;
};
#include "InventoryCube.hpp"
#include "ItemStack.hpp"
#include "Registry.hpp"
#include "RenderingController.hpp"
Scene::Scene(ClientPlayer &player) : m_player(player) {
}
void Scene::init() {
auto testEntity = m_registry.create();
InventoryCube &cube = m_registry.assign<InventoryCube>(testEntity, 0.25f, true);
cube.setOrigin(cube.size() / 2.f, cube.size() / 2.f, cube.size() / 2.f);
cube.setPosition(14 + cube.getOrigin().x, 13 + cube.getOrigin().y, 16 + cube.getOrigin().z);
cube.updateVertexBuffer(Registry::getInstance().getBlockFromStringID("default:cobblestone"));
m_registry.assign<RotationAnimation>(testEntity, 0.f, 0.f, 1.f, 1.f);
m_registry.assign<gk::DoubleBox>(testEntity, 0., 0., 0., cube.size(), cube.size(), cube.size());
m_registry.assign<ItemStack>(testEntity, "default:stick", 1);
m_isInitialized = true;
}
void Scene::update() {
if (!m_isInitialized) init();
m_registry.view<InventoryCube, RotationAnimation>().each([](auto, auto &cube, auto &rotation) {
cube.rotate(rotation.angle, {rotation.axisX, rotation.axisY, rotation.axisZ});
});
m_registry.view<InventoryCube, gk::DoubleBox, ItemStack>().each([this](auto entity, auto &cube, auto &box, auto &itemStack) {
gk::DoubleBox hitbox = box + cube.getPosition();
gk::DoubleBox playerHitbox = m_player.hitbox() + gk::Vector3d{m_player.x(), m_player.y(), m_player.z()};
if (hitbox.intersects(playerHitbox)) {
m_player.inventory().addStack(itemStack.item().stringID(), itemStack.amount());
m_registry.destroy(entity);
}
});
AnimationController::update(m_registry);
CollisionController::update(m_registry, m_player);
}
void Scene::draw(gk::RenderTarget &target, gk::RenderStates states) const {
@ -81,8 +45,6 @@ void Scene::draw(gk::RenderTarget &target, gk::RenderStates states) const {
gk::Vector3d cameraPosition = m_camera->getDPosition();
states.transform.translate(-cameraPosition.x, -cameraPosition.y, -cameraPosition.z);
m_registry.view<InventoryCube>().each([&](auto, auto &cube) {
target.draw(cube, states);
});
RenderingController::draw(m_registry, target, states);
}

View File

@ -39,17 +39,15 @@ class Scene : public gk::Drawable {
public:
Scene(ClientPlayer &player);
void init();
void update();
void setCamera(gk::Camera &camera) { m_camera = &camera; }
entt::DefaultRegistry &registry() { return m_registry; }
private:
void draw(gk::RenderTarget &target, gk::RenderStates states) const override;
bool m_isInitialized = false;
ClientPlayer &m_player;
gk::Camera *m_camera = nullptr;

View File

@ -137,6 +137,7 @@ void SettingsMenuState::addGameplayButtons() {
addToggleButton("Fly Mode", Config::isFlyModeEnabled, false);
addToggleButton("No Clip", Config::isNoClipEnabled, false);
addToggleButton("Use item drops", Config::useItemDrops, false);
}
void SettingsMenuState::addInterfaceButtons() {

View File

@ -34,6 +34,7 @@
#include "ClientCommandHandler.hpp"
#include "ClientPlayer.hpp"
#include "ClientWorld.hpp"
#include "ItemDropFactory.hpp"
#include "Registry.hpp"
#include "Sky.hpp"
#include "TextureAtlas.hpp"
@ -100,6 +101,11 @@ void ClientWorld::checkPlayerChunk(double playerX, double playerY, double player
}
}
void ClientWorld::onBlockDestroyed(int x, int y, int z, const Block &block) {
if (Config::useItemDrops)
ItemDropFactory::create(m_scene.registry(), x, y, z, block.getItemDrop().item().stringID(), block.getItemDrop().amount());
}
void ClientWorld::clear() {
m_chunks.clear();
}

View File

@ -51,6 +51,8 @@ class ClientWorld : public World, public gk::Drawable {
void sendChunkRequests();
void checkPlayerChunk(double playerX, double playerY, double playerZ);
void onBlockDestroyed(int x, int y, int z, const Block &block) override;
void clear();
void updateSky(u16 dimensionID);
@ -60,6 +62,8 @@ class ClientWorld : public World, public gk::Drawable {
Chunk *getChunk(int cx, int cy, int cz) const override;
Scene &scene() { return m_scene; }
void setClient(ClientCommandHandler &client) { m_client = &client; }
void setCamera(gk::Camera &camera) { m_camera = &camera; m_scene.setCamera(camera); }

View File

@ -31,6 +31,7 @@
#include "Chunk.hpp"
#include "EngineConfig.hpp"
#include "Registry.hpp"
#include "World.hpp"
Chunk::Chunk(s32 x, s32 y, s32 z, World &world) : m_world(world) {
m_x = x;
@ -88,10 +89,12 @@ void Chunk::setBlock(int x, int y, int z, u16 type) {
}
onBlockPlaced(x, y, z, block);
m_world.onBlockPlaced(x + m_x * width, y + m_y * depth, z + m_z * height, block);
if (m_data[z][y][x] != 0) {
const Block &oldBlock = Registry::getInstance().getBlock(m_data[z][y][x]);
onBlockDestroyed(x, y, z, oldBlock);
m_world.onBlockDestroyed(x + m_x * width, y + m_y * depth, z + m_z * height, oldBlock);
}
setBlockRaw(x, y, z, type);

View File

@ -46,6 +46,9 @@ class World {
u16 getData(int x, int y, int z) const;
void setData(int x, int y, int z, u16 data) const;
virtual void onBlockPlaced(int, int, int, const Block &) {}
virtual void onBlockDestroyed(int, int, int, const Block &) {}
static bool isReloadRequested;
};