Files
Bomberman/sources/Map/Map.cpp
2021-06-19 16:59:14 +02:00

525 lines
22 KiB
C++

//
// Created by Tom Augier on 5/26/21.
// Edited by Benjamin Henry on 5/26/21.
//
#include "Component/Collision/CollisionComponent.hpp"
#include "System/Collision/CollisionSystem.hpp"
#include "Map.hpp"
#include <iostream>
#include <Items/Bonus.hpp>
#include <Component/Levitate/LevitateComponent.hpp>
#include <Component/Timer/TimerComponent.hpp>
#include <Component/Tag/TagComponent.hpp>
#include "Component/Bonus/PlayerBonusComponent.hpp"
#include <Component/BumperTimer/BumperTimerComponent.hpp>
namespace RAY3D = RAY::Drawables::Drawables3D;
using namespace std::chrono_literals;
namespace BBM
{
void MapGenerator::createBonus(WAL::Entity &entity, Vector3f position, Bonus::BonusType bonusType) {
static std::map<Bonus::BonusType, std::vector<std::string>> map = {
{Bonus::BonusType::BOMBSTOCK, {"Bonus Bomb Up", "assets/items/bombup"}},
{Bonus::BonusType::SPEEDUP, {"Bonus Speed Up", "assets/items/speedup"}},
{Bonus::BonusType::EXPLOSIONINC, {"Bonus Fire Up", "assets/items/fireup"}},
{Bonus::BonusType::NOCLIP, {"Bonus Wallpass", "assets/items/wallpass"}}
};
static std::vector<std::function<void (WAL::Entity &, const WAL::Entity &, CollisionComponent::CollidedAxis)>> func = {
&Bonus::BombUpBonus, &Bonus::SpeedUpBonus, &Bonus::ExplosionRangeBonus, &Bonus::NoClipBonus
};
entity.addComponent<PositionComponent>(position)
.addComponent<TagComponent<Blowable>>()
.addComponent<MovableComponent>()
.addComponent<HealthComponent>(1, [](WAL::Entity &myEntity, WAL::Wal &wal) {
myEntity.scheduleDeletion();
})
.addComponent<LevitateComponent>(position.y)
.addComponent<CollisionComponent>([](WAL::Entity &bonus, const WAL::Entity &player, CollisionComponent::CollidedAxis axis) {
bonus.scheduleDeletion();
}, func[bonusType - 1], 0.5, .5)
.addComponent<TimerComponent>(5s, [](WAL::Entity &bonus, WAL::Wal &wal){
bonus.scheduleDeletion();
})
.addComponent<Drawable3DComponent, RAY3D::Model>(map.at(bonusType)[1] + ".obj", false,
std::make_pair(MAP_DIFFUSE, "assets/items/items.png"));
}
void MapGenerator::bumperCollide(WAL::Entity &entity,
const WAL::Entity &wall,
CollisionComponent::CollidedAxis collidedAxis)
{
auto *movable = entity.tryGetComponent<MovableComponent>();
auto *bumperTimer = entity.tryGetComponent<BumperTimerComponent>();
if (!movable || !bumperTimer)
return;
if (!bumperTimer->_isReseting) {
movable->_velocity.y = 2;
bumperTimer->_isReseting = true;
}
}
void MapGenerator::holeCollide(WAL::Entity &entity,
const WAL::Entity &wall,
CollisionComponent::CollidedAxis collidedAxis)
{
auto *health = entity.tryGetComponent<HealthComponent>();
auto *movable = entity.tryGetComponent<MovableComponent>();
auto *wallPos = wall.tryGetComponent<PositionComponent>();
auto *entityPos = entity.tryGetComponent<PositionComponent>();
if (!health)
return;
auto posWall = Vector3f(wallPos->position.x, wallPos->position.y + 1, wallPos->position.z);
auto vec = (posWall - entityPos->position).abs();
if (vec.x < 0.3 && vec.z < 0.3 && posWall.distance(entityPos->position) < 0.5) {
health->takeDmg(health->getHealthPoint());
movable->_velocity = Vector3f();
}
}
void MapGenerator::wallCollision(WAL::Entity &entity,
const WAL::Entity &wall,
CollisionComponent::CollidedAxis collidedAxis)
{
auto *mov = entity.tryGetComponent<MovableComponent>();
if (!mov)
return;
if (collidedAxis & CollisionComponent::CollidedAxis::X)
mov->_velocity.x = 0;
if (collidedAxis & CollisionComponent::CollidedAxis::Y)
mov->_velocity.y = 0;
if (collidedAxis & CollisionComponent::CollidedAxis::Z)
mov->_velocity.z = 0;
}
void MapGenerator::wallCollided(WAL::Entity &entity,
const WAL::Entity &wall,
CollisionComponent::CollidedAxis collidedAxis)
{
auto *playerBonus = entity.tryGetComponent<PlayerBonusComponent>();
if (playerBonus && playerBonus->isNoClipOn)
return;
wallCollision(entity, wall, collidedAxis);
}
void MapGenerator::wallDestroyed(WAL::Entity &entity, WAL::Wal &wal)
{
entity.scheduleDeletion();
auto &position = entity.getComponent<PositionComponent>().position;
static std::map<Bonus::BonusType, std::vector<std::string>> map = {
{Bonus::BonusType::BOMBSTOCK, {"Bonus Bomb Up", "assets/items/bombup"}},
{Bonus::BonusType::SPEEDUP, {"Bonus Speed Up", "assets/items/speedup"}},
{Bonus::BonusType::EXPLOSIONINC, {"Bonus Fire Up", "assets/items/fireup"}},
{Bonus::BonusType::NOCLIP, {"Bonus Wallpass", "assets/items/wallpass"}}
};
auto bonusType = Bonus::getRandomBonusType();
if (bonusType == Bonus::BonusType::NOTHING)
return;
if (!map.contains(bonusType))
return;
createBonus(wal.getScene()->scheduleNewEntity(map.at(bonusType)[0]), position, bonusType);
}
const std::string MapGenerator::assetsPath = "./assets/";
const std::string MapGenerator::wallAssetsPath = MapGenerator::assetsPath + "map/";
const std::string MapGenerator::imageExtension = ".png";
const std::string MapGenerator::objExtension = ".obj";
const std::string MapGenerator::breakableWallPath = MapGenerator::wallAssetsPath + "breakable_wall";
const std::string MapGenerator::outerWallPath = MapGenerator::wallAssetsPath + "outer_wall";
const std::string MapGenerator::unbreakableWallPath = MapGenerator::wallAssetsPath + "unbreakable_wall";
const std::string MapGenerator::floorPath = MapGenerator::wallAssetsPath + "floor";
const std::string MapGenerator::secondFloorPath = MapGenerator::wallAssetsPath + "upper_floor";
const std::string MapGenerator::stairsPath = MapGenerator::wallAssetsPath + "stairs";
const std::string MapGenerator::bumperPath = MapGenerator::wallAssetsPath + "bumper";
const std::string MapGenerator::holePath = MapGenerator::wallAssetsPath + "hole";
const std::string MapGenerator::secondFloorHolePath = MapGenerator::secondFloorPath + "_hole";
void MapGenerator::generateUnbreakableBlock(int width, int height, std::shared_ptr<WAL::Scene> scene)
{
static const std::string unbreakableObj = unbreakableWallPath + objExtension;
static const std::string unbreakablePng = unbreakableWallPath + imageExtension;
for (int i = 0; i < width + 1; i++) {
for (int j = 0; j < height + 1; j++) {
if (!(i % 2) && !(j % 2)) {
scene->addEntity("Unbreakable Wall")
.addComponent<PositionComponent>(i, 0, j)
.addComponent<TagComponent<Blowable>>()
.addComponent<TagComponent<Unbreakable>>()
.addComponent<CollisionComponent>(
WAL::Callback<WAL::Entity &, const WAL::Entity &, CollisionComponent::CollidedAxis>(),
&MapGenerator::wallCollided, 0.25, .75)
.addComponent<Drawable3DComponent, RAY3D::Model>(unbreakableObj, false,
std::make_pair(MAP_DIFFUSE, unbreakablePng));
}
}
}
}
void MapGenerator::generateWall(int width, int height, std::shared_ptr<WAL::Scene> scene)
{
static const std::string outerWallObj = unbreakableWallPath + objExtension;
static const std::string outerWallPnj = unbreakableWallPath + imageExtension;
for (int i = -1; i < height + 2; i++) {
scene->addEntity("Bomb stopper")
.addComponent<PositionComponent>(-1, 0, i)
.addComponent<TagComponent<Blowable>>()
.addComponent<Drawable3DComponent, RAY3D::Model>(outerWallObj, false,
std::make_pair(MAP_DIFFUSE, outerWallPnj));
scene->addEntity("Bomb stopper")
.addComponent<PositionComponent>(width + 1, 0, i)
.addComponent<TagComponent<Blowable>>()
.addComponent<Drawable3DComponent, RAY3D::Model>(outerWallObj, false,
std::make_pair(MAP_DIFFUSE, outerWallPnj));
}
for (int i = 0; i < width + 1; i++) {
scene->addEntity("Bomb stopper")
.addComponent<PositionComponent>(i, 0, -1)
.addComponent<TagComponent<Blowable>>()
.addComponent<Drawable3DComponent, RAY3D::Model>(outerWallObj, false,
std::make_pair(MAP_DIFFUSE, outerWallPnj));
scene->addEntity("Bomb stopper")
.addComponent<PositionComponent>(i, 0, height + 1)
.addComponent<TagComponent<Blowable>>()
.addComponent<Drawable3DComponent, RAY3D::Model>(outerWallObj, false,
std::make_pair(MAP_DIFFUSE, outerWallPnj));
}
scene->addEntity("Bottom Wall")
.addComponent<PositionComponent>(Vector3f((width + 1) / 2, 0, -1))
.addComponent<CollisionComponent>(
WAL::Callback<WAL::Entity &, const WAL::Entity &, CollisionComponent::CollidedAxis>(),
&MapGenerator::wallCollision, Vector3f(-(width + 1) / 2 , 0.25, 0.25), Vector3f(width + 1, 2, 0.75));
scene->addEntity("Upper Wall")
.addComponent<PositionComponent>(Vector3f((width + 1) / 2, 0, height + 1))
.addComponent<CollisionComponent>(
WAL::Callback<WAL::Entity &, const WAL::Entity &, CollisionComponent::CollidedAxis>(),
&MapGenerator::wallCollision, Vector3f(-(width + 1) / 2 , 0.25, 0.25), Vector3f(width + 1, 2, 0.75));
scene->addEntity("Left Wall")
.addComponent<PositionComponent>(Vector3f(width + 1, 0, height / 2))
.addComponent<CollisionComponent>(
WAL::Callback<WAL::Entity &, const WAL::Entity &, CollisionComponent::CollidedAxis>(),
&MapGenerator::wallCollision, Vector3f(0.25, 0.25, -(height + 1) / 2 ), Vector3f(0.75, 2, height + 1));
scene->addEntity("Right Wall")
.addComponent<PositionComponent>(Vector3f(-1, 0, height / 2))
.addComponent<CollisionComponent>(
WAL::Callback<WAL::Entity &, const WAL::Entity &, CollisionComponent::CollidedAxis>(),
&MapGenerator::wallCollision, Vector3f(0.25, 0.25, -(height + 1) / 2 ), Vector3f(0.75, 2, height + 1));
}
void MapGenerator::generateFloor(MapBlock map, int width, int height, std::shared_ptr<WAL::Scene> scene)
{
static const std::string floorObj = floorPath + objExtension;
static const std::string floorPng = floorPath + imageExtension;
for (int i = 0; i < width + 1; i++) {
for (int j = 0; j < height + 1; j++) {
if (map[std::make_tuple(i, 0, j)] != HOLE && map[std::make_tuple(i, -1, j)] != BUMPER)
scene->addEntity("Ground")
.addComponent<PositionComponent>(Vector3f(i, -1, j))
.addComponent<Drawable3DComponent, RAY3D::Model>(floorObj, false,
std::make_pair(MAP_DIFFUSE, floorPng));
}
}
}
void MapGenerator::createElement(Vector3f coords, std::shared_ptr<WAL::Scene> scene, BlockType blockType)
{
std::map<BlockType, MapElem> elements = {
{BREAKABLE, &createBreakable},
{UNBREAKABLE, &createUnbreakable},
{HOLE, &createHole},
{BUMPER, &createBumper},
{UPPERFLOOR, &createUpperFloor},
};
if (blockType == NOTHING || blockType == SPAWNER)
return;
auto element = elements.at(blockType);
element(coords, std::move(scene));
}
void MapGenerator::createBreakable(Vector3f coords, std::shared_ptr<WAL::Scene> scene)
{
static const std::string breakableObj = breakableWallPath + objExtension;
static const std::string breakablePng = breakableWallPath + imageExtension;
scene->addEntity("Breakable Block")
.addComponent<PositionComponent>(coords)
.addComponent<TagComponent<Blowable>>()
.addComponent<TagComponent<Breakable>>()
.addComponent<HealthComponent>(1, &MapGenerator::wallDestroyed)
.addComponent<CollisionComponent>(
WAL::Callback<WAL::Entity &, const WAL::Entity &, CollisionComponent::CollidedAxis>(),
&MapGenerator::wallCollided, 0.25, .75)
.addComponent<Drawable3DComponent, RAY3D::Model>(breakableObj, false, std::make_pair(MAP_DIFFUSE, breakablePng));
}
void MapGenerator::createUpperFloor(Vector3f coords, std::shared_ptr<WAL::Scene> scene)
{
static const std::string floorObj = secondFloorPath + objExtension;
static const std::string floorPng = secondFloorPath + imageExtension;
scene->addEntity("Upper Floor")
.addComponent<PositionComponent>(Vector3f(coords))
.addComponent<Drawable3DComponent, RAY3D::Model>(floorObj, false, std::make_pair(MAP_DIFFUSE, floorPng));
}
void MapGenerator::createUnbreakable(Vector3f coords, std::shared_ptr<WAL::Scene> scene)
{
static const std::string UnbreakableObj = unbreakableWallPath + objExtension;
static const std::string UnbreakablePng = unbreakableWallPath + imageExtension;
scene->addEntity("Unbreakable Block")
.addComponent<PositionComponent>(coords)
.addComponent<TagComponent<Blowable>>()
.addComponent<TagComponent<Unbreakable>>()
.addComponent<CollisionComponent>(
WAL::Callback<WAL::Entity &, const WAL::Entity &, CollisionComponent::CollidedAxis>(),
&MapGenerator::wallCollided, 0.25, .75)
.addComponent<Drawable3DComponent, RAY3D::Model>(UnbreakableObj, false,
std::make_pair(MAP_DIFFUSE, UnbreakablePng));
}
void MapGenerator::createHole(Vector3f coords, std::shared_ptr<WAL::Scene> scene)
{
static const std::string holeObj = holePath + objExtension;
static const std::string holePng = holePath + imageExtension;
static const std::string secondFloorObj = secondFloorHolePath + objExtension;
static const std::string secondFloorPng = secondFloorHolePath + imageExtension;
WAL::Entity &holeEntity = scene->addEntity("Hole Block");
holeEntity.addComponent<PositionComponent>(Vector3f(coords.x, coords.y - 1, coords.z))
.addComponent<TagComponent<Hole>>()
.addComponent<CollisionComponent>(
WAL::Callback<WAL::Entity &, const WAL::Entity &, CollisionComponent::CollidedAxis>(),
&MapGenerator::holeCollide, 0.25, 0.75);
if (coords.y == 0)
holeEntity.addComponent<Drawable3DComponent, RAY3D::Model>(holeObj, false, std::make_pair(MAP_DIFFUSE, holePng), Vector3f(1,1,1), 180);
else
holeEntity.addComponent<Drawable3DComponent, RAY3D::Model>(secondFloorObj, false,
std::make_pair(MAP_DIFFUSE, secondFloorPng));
}
void MapGenerator::createBumper(Vector3f coords, std::shared_ptr<WAL::Scene> scene)
{
static const std::string bumperObj = bumperPath + objExtension;
static const std::string bumperPng = bumperPath + imageExtension;
scene->addEntity("Bumper Block")
.addComponent<PositionComponent>(Vector3f(coords.x, coords.y, coords.z))
.addComponent<TagComponent<Bumper>>()
.addComponent<Drawable3DComponent, RAY3D::Model>(bumperObj, false, std::make_pair(MAP_DIFFUSE, bumperPng))
.addComponent<CollisionComponent>(
WAL::Callback<WAL::Entity &, const WAL::Entity &, CollisionComponent::CollidedAxis>(),
&MapGenerator::bumperCollide, Vector3f(0.25, 0.25, 0.25),Vector3f(0.75, 0.75, 0.75));
}
bool MapGenerator::isCloseToBlockType(std::map<std::tuple<int, int, int>, BlockType> map, int x, int y, int z,
BlockType blockType)
{
return (map[std::make_tuple(x - 1, y, z)] == blockType ||
map[std::make_tuple(x + 1, y, z)] == blockType ||
map[std::make_tuple(x, y, z + 1)] == blockType ||
map[std::make_tuple(x, y, z - 1)] == blockType);
}
MapGenerator::BlockType MapGenerator::getRandomBlockType(bool hasHeight)
{
double rnd = static_cast<double>(std::rand()) / RAND_MAX;
if (rnd > 0.98 && !hasHeight)
return HOLE;
if ((!hasHeight && rnd > 0.25) || rnd > 0.7)
return BREAKABLE;
return NOTHING;
}
MapGenerator::MapBlock MapGenerator::createHeight(MapBlock map, int width, int height)
{
double rnd = static_cast<double>(std::rand()) / RAND_MAX;
if (rnd > 0.01) {
for (int i = 0; i < width + 1; i++) {
map[std::make_tuple(i, 1, height)] = map[std::make_tuple(i, 0, height)];
map[std::make_tuple(i, 0, height)] = UPPERFLOOR;
map[std::make_tuple(i, 1, 0)] = map[std::make_tuple(i, 0, 0)];
map[std::make_tuple(i, 0, 0)] = UPPERFLOOR;
}
map[std::make_tuple(0, -1, height - 1)] = BUMPER;
map[std::make_tuple(0, -1, 1)] = BUMPER;
map[std::make_tuple(width, -1, height - 1)] = BUMPER;
map[std::make_tuple(width, -1, 1)] = BUMPER;
map[std::make_tuple(width / 2, -1, height - 1)] = BUMPER;
map[std::make_tuple(width / 2, -1, 1)] = BUMPER;
}
if (rnd > 0.01) {
for (int i = width / 2 - width / 4; i < width / 2 + width / 4 + 1; i++) {
for (int j = height / 2 - height / 4; j < height / 2 + height / 4 + 1; j++) {
map[std::make_tuple(i, 1, j)] = map[std::make_tuple(i, 0, j)];
map[std::make_tuple(i, 0, j)] = UPPERFLOOR;
}
}
map[std::make_tuple(width / 2 - width / 8, -1, height / 2 + height / 4 + 1)] = BUMPER;
map[std::make_tuple(width / 2 + width / 8, -1, height / 2 - height / 4 - 1)] = BUMPER;
map[std::make_tuple(width / 2 - width / 4 - 1, -1, height / 2 - height / 8)] = BUMPER;
map[std::make_tuple(width / 2 + width / 4 + 1, -1, height / 2 + height / 8)] = BUMPER;
}
return map;
}
MapGenerator::MapBlock MapGenerator::createSpawner(MapBlock map, int width, int height)
{
map[std::make_tuple(0, 0, 0)] = SPAWNER;
map[std::make_tuple(width, 0, 0)] = SPAWNER;
map[std::make_tuple(0, 0, height)] = SPAWNER;
map[std::make_tuple(width, 0, height)] = SPAWNER;
return map;
}
MapGenerator::MapBlock MapGenerator::cleanBreakable(MapBlock map, int width, int height)
{
for (int i = 0; i < width + 1; i++)
for (int j = 0; j < height; j++) {
if (map[std::make_tuple(i, 0, j)] == BREAKABLE && map[std::make_tuple(i, -1, j)] == BUMPER)
map[std::make_tuple(i, 0, j)] = NOTHING;
if (map[std::make_tuple(i, 1, j)] == BREAKABLE && isCloseToBlockType(map, i, -1, j, BUMPER))
map[std::make_tuple(i, 1, j)] = NOTHING;
}
return (map);
}
MapGenerator::MapBlock MapGenerator::createClassicUnbreakable(MapBlock map, int width, int height)
{
for (int i = 0; i < width + 1; i++) {
for (int j = 0; j < height + 1; j++) {
if (!((i + 1) % 2) && !((j + 1) % 2))
map[std::make_tuple(i, 0, j)] = UNBREAKABLE;
}
}
return (map);
}
MapGenerator::MapBlock MapGenerator::createLongClassicUnbreakable(MapBlock map, int width, int height)
{
int placedSpace = 0;
for (int i = 1; i < width; i++) {
placedSpace = 0;
for (int j = 1; j < height; j++) {
if (!(j % 2))
continue;
if (i < (width / 2 - width / 10) || i > (width / 2 + width / 10))
map[std::make_tuple(i, 0, j)] = UNBREAKABLE;
else
placedSpace++;
}
}
return (map);
}
MapGenerator::MapBlock MapGenerator::createMap(int width, int height, bool isHeight, bool isNotClassic)
{
MapBlock map;
width = width % 2 ? width + 1 : width;
height = height % 2 ? height + 1 : height;
for (int i = 0; i < width + 1; i++)
for (int j = 0; j < height + 1; j++) {
map[std::make_tuple(i, 0, j)] = NOTHING;
map[std::make_tuple(i, 1, j)] = NOTHING;
}
map = createSpawner(map, width, height);
for (int i = 0; i < width + 1; i++) {
for (int j = 0; j < height + 1; j++) {
if (map[std::make_tuple(i, 0, j)] == SPAWNER)
continue;
if (isCloseToBlockType(map, i, 0, j, SPAWNER)) {
map[std::make_tuple(i, isNotClassic ? -1 : 0, j)] = isNotClassic ? BUMPER : NOTHING;
} else {
map[std::make_tuple(i, 0, j)] = getRandomBlockType(isHeight);
}
if (map[std::make_tuple(i, 0, j)] == UNBREAKABLE && isCloseToBlockType(map, i, 0, j, UNBREAKABLE))
map[std::make_tuple(i, 0, j)] = BREAKABLE;
}
}
if (!isHeight) {
if (!isNotClassic)
map = createClassicUnbreakable(map, width, height);
else
map = createLongClassicUnbreakable(map, width, height);
}
if (isHeight)
map = createHeight(map, width, height);
map = cleanBreakable(map, width, height);
return (map);
}
void MapGenerator::generateHeightCollision(MapBlock map, int width, int height, std::shared_ptr<WAL::Scene> scene)
{
int floor = 2;
for (int i = 0; i < width + 1; i++) {
if (map[std::make_tuple(i, 0, 0)] != UPPERFLOOR && map[std::make_tuple(i, 0, 0)] != HOLE
&& map[std::make_tuple(i, 0, 0)] != BUMPER) {
floor -= 1;
break;
}
}
for (int i = width / 2 - width / 4; i < width / 2 + width / 4 + 1; i++) {
for (int j = height / 2 - height / 4; j < height / 2 + height / 4 + 1; j++) {
if (map[std::make_tuple(i, 0, j)] != UPPERFLOOR && map[std::make_tuple(i, 0, j)] != HOLE
&& map[std::make_tuple(i, 0, j)] != BUMPER) {
floor -= 1;
break;
}
}
if (floor <= 0)
break;
}
if (floor >= 1) {
scene->addEntity("FloorBot Hitbox")
.addComponent<PositionComponent>(Vector3f(0, 0, 0))
.addComponent<CollisionComponent>(
WAL::Callback<WAL::Entity &, const WAL::Entity &, CollisionComponent::CollidedAxis>(),
&MapGenerator::wallCollided, Vector3f(0.25, 0.25, 0.25), Vector3f(width + 1, 0.75, 0.75));
scene->addEntity("FloorUp Hitbox")
.addComponent<PositionComponent>(Vector3f(0, 0, height))
.addComponent<CollisionComponent>(
WAL::Callback<WAL::Entity &, const WAL::Entity &, CollisionComponent::CollidedAxis>(),
&MapGenerator::wallCollided, Vector3f(0.25, 0.25, 0.25),Vector3f(width + 1, 0.75, 0.75));
}
if (floor >= 2)
scene->addEntity("Middle Hitbox")
.addComponent<PositionComponent>(Vector3f(width / 2 - width / 4, 0, height / 2 - height / 4))
.addComponent<CollisionComponent>(
WAL::Callback<WAL::Entity &, const WAL::Entity &, CollisionComponent::CollidedAxis>(),
&MapGenerator::wallCollided, Vector3f(0.25, 0.25, 0.25),Vector3f(width / 2 + 0.75, 0.75, height / 2 + 0.75));
}
void MapGenerator::loadMap(int width, int height, MapBlock map, const std::shared_ptr<WAL::Scene> &scene)
{
generateHeightCollision(map, width, height, scene);
generateWall(width, height, scene);
generateFloor(map, width, height, scene);
for (int x = 0; x < width + 1; x++)
for (int z = 0; z < height + 1; z++)
for (int y = -1; y < 1 + 1; y++)
createElement(Vector3f(x, y, z), scene, map[std::make_tuple(x, y, z)]);
}
} // namespace BBM