Commit 422a2acd authored by Corentin Bocquillon's avatar Corentin Bocquillon

WIP map generation.

parent fc99a5d1
......@@ -12,7 +12,8 @@ sources = ['src/main.cpp', 'src/items.cpp', 'src/config.cpp',
'src/sdl/game_events.cpp', 'src/sdl/gui_utils.cpp',
'src/sdl/gui_utils.h', 'src/sdl/menu.cpp', 'src/sdl/keyboard.cpp',
'src/sdl/mouse.cpp', 'src/sdl/FPSCounter.cpp',
'src/sdl/Interface.cpp', 'src/sdl/ground.cpp']
'src/sdl/Interface.cpp', 'src/sdl/ground.cpp',
'src/MapGenerator.cpp']
libxml2 = dependency('libxml-2.0')
protobuf = dependency('protobuf')
......
/**
* @file
* @author Corentin Bocquillon <0x539@nybble.fr>
*
* @section LICENSE
*
* Copyright (C) 2018 Corentin Bocquillon <0x539@nybble.fr>
*
* factorywars is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* factorywars 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with factorywars. If not, see <http://www.gnu.org/licenses/
*
* @section DESCRIPTION
*
* MapGenerator.cpp is the ranom generator of the map.
*/
#include <utility>
#include <vector>
#include "MapGenerator.h"
using namespace std;
MapGenerator::MapGenerator (int seed)
{
set_seed (seed);
generate_floors_thresholds ();
generate_items_thresholds ();
}
int
MapGenerator::get_seed ()
{
return m_seed;
}
void
MapGenerator::set_seed (int seed)
{
m_seed = seed;
m_biomes_noise.SetSeed (seed);
m_items_noise.SetSeed (seed);
}
tile_proto
MapGenerator::generate_tile (coordinates tile_coordinates)
{
tile_proto tile;
tile.set_x (tile_coordinates.x);
tile.set_y (tile_coordinates.y);
coordinates square_coordinates;
for (unsigned i = 0; i < 8 * 8; ++i)
{
chunk_proto *chunk = tile.add_chunks ();
chunk->set_x (i / 8 + 8 * tile.x ());
chunk->set_y (i % 8 + 8 * tile.y ());
for (int j = 0; j < 16 * 16; j++)
{
square_proto *square = chunk->add_squares ();
square->set_x (j / 16);
square->set_y (j % 16);
square_coordinates.x = square->x () + chunk->x () * 16;
square_coordinates.y = square->y () + chunk->y () * 16;
int floor_id = get_floor_id (square_coordinates);
square->set_floor (floor_id);
int item_id = get_item_id (square_coordinates, floor_id);
square->set_item (item_id);
square->set_quantity (get_item_quantity (item_id));
}
}
return tile;
}
int
MapGenerator::get_floor_id (coordinates square_coordinates)
{
double random_value = m_biomes_noise.GetValue
(square_coordinates.x * (1.0/1000.0),
square_coordinates.y = (1.0/1000.0), 0);
for (auto threshold : m_floor_threshold)
{
if (random_value >= get<1> (threshold)
&& random_value <= get<2> (threshold))
return get<0> (threshold);
}
return 3;
}
int
MapGenerator::get_item_id (coordinates square_coordinates, int floor_id)
{
double random_value = m_biomes_noise.GetValue
(square_coordinates.x * (1.0/1000.0),
square_coordinates.y = (1.0/1000.0), 0);
for (auto threshold : m_item_threshold)
{
if (floor_id == get<0> (threshold)
&& random_value >= get<2> (threshold)
&& random_value <= get<3> (threshold))
return get<1> (threshold);
}
return 0;
}
unsigned
MapGenerator::get_item_quantity (int item_id)
{
if (item_id == 1)
return 1;
else if (item_id == 2 || item_id == 5 || item_id == 8)
return 5000;
else
return 1;
}
void
MapGenerator::generate_floors_thresholds ()
{
m_floor_threshold.clear ();
vector<pair<int,double>> probabilities =
{
make_pair (1, 1.0/3.0), // Désert
make_pair (2, 1.0/3.0), // Terre
make_pair (3, 1.0/3.0) // Forêt
};
double lower_bound = -1.0;
for (auto probability : probabilities)
{
double upper_bound = lower_bound + probability.second;
m_floor_threshold.push_back (make_tuple (probability.first, lower_bound,
upper_bound));
lower_bound = upper_bound;
}
}
void
MapGenerator::generate_items_thresholds ()
{
m_item_threshold.clear ();
vector<tuple<int,int,double>> probabilities =
{
// Désert
make_tuple (1, 1, 0.0), // Arbre
make_tuple (1, 2, (1.0 / 12.0)), // Cuivre
make_tuple (1, 5, (1.0 / 12.0)), // Fer
make_tuple (1, 8, (1.0 / 12.0)), // Charbon
// Terre
make_tuple (2, 1, (1.0 / 12.0)),
make_tuple (2, 2, (1.0 / 18.0)),
make_tuple (2, 5, (1.0 / 18.0)),
make_tuple (2, 8, (1.0 / 18.0)),
// Forêt
make_tuple (3, 1, (1.0 / 9.0)),
make_tuple (3, 2, (1.0 / 18.0)),
make_tuple (3, 5, (1.0 / 18.0)),
make_tuple (3, 8, (1.0 / 18.0))
};
double lower_bound = -1.0;
for (auto probability : probabilities)
{
double upper_bound = lower_bound + get<2> (probability);
m_item_threshold.push_back (make_tuple (get<0> (probability), get<1> (probability),
lower_bound, upper_bound));
lower_bound = upper_bound;
}
}
/**
* @file
* @author Corentin Bocquillon <0x539@nybble.fr>
*
* @section LICENSE
*
* Copyright (C) 2018 Corentin Bocquillon <0x539@nybble.fr>
*
* factorywars is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* factorywars 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with factorywars. If not, see <http://www.gnu.org/licenses/
*
* @section DESCRIPTION
*
* MapGenerator.h is the header of MapGenerator.cpp.
*/
#pragma once
#ifdef LIBNOISE
#include <libnoise/noise.h>
#else
#include <noise/noise.h>
#endif
#include <vector>
#include <utility>
#include "tile.pb.h"
#include "structures.h"
class MapGenerator
{
public:
/**
* The constructor.
*
* @param seed is the seed of the map.
*/
MapGenerator (int seed);
/**
* Get the seed.
*
* @return the seed.
*/
int get_seed ();
/**
* Set the seed.
*
* @param seed is the seed.
*/
void set_seed (int seed);
/**
* Randomly generate a tile.
*
* @param tile_coordinates is the tile_coordinates of the tile to
* generate.
*
* @return a tile_proto structure containing the newly generated tile.
*/
tile_proto generate_tile (coordinates tile_coordinates);
private:
/**
* The coherent noise module to randomly generate the floor.
*/
noise::module::Perlin m_biomes_noise;
/**
* The coherent noise module to randomly generate the items.
*/
noise::module::Voronoi m_items_noise;
/**
* floor_id, lower_bound, upper_bound
*/
std::vector<std::tuple<int,double,double>> m_floor_threshold;
/**
* floor_id, item_id, lower_bound, upper_bound
*/
std::vector<std::tuple<int,int,double,double>> m_item_threshold;
/**
* The seed to use for the noise modules.
*/
int m_seed;
/**
* Get the floor’s identifier from a random value.
*
* @return the identifier of the floor.
*/
int get_floor_id (coordinates square_coordinates);
/**
* Get the item’s identifier from a random value.
*
* @return the identifier of the item.
*/
int get_item_id (coordinates square_coordinates, int floor_id);
/**
* Get the item’s quantity.
*
* @return the quantity of the item.
*/
unsigned get_item_quantity (int item_id);
/**
* Generate the floors thresholds.
*/
void generate_floors_thresholds ();
/**
* Generate the items thresholds.
*/
void generate_items_thresholds ();
};
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment