Commit 166a53d6 authored by Corentin Bocquillon's avatar Corentin Bocquillon

Merge branch 'sfml' into experimental

parents 37a35855 f8031f41
......@@ -12,32 +12,30 @@ content of the README.md file.
+ Translate the user’s side of the game in esperanto.
+ Continue to follow [XDG Base Directory Specification](https://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html).
+ Create a website.
+ Use Texlive for documentation.
+ Update the list of dependencies in COMPILE.md.
Main
----
+ Put the main loop in the main.cpp file. We need to discuss if it’s necessary.
Players
-------
+ Use the player’s inventory system.
+ Prevent players to move when there is an object where they want to move.
+ Add booleans for movements, per example true if moving left.
Network
-------
+ Create the tcp server which will send the map.
+ Send through the network when we delete/add an object on the map.
+ Run the handle_data_from_network_pipe function in the loop.
+ Rewrite everything.
GUI
---
+ Allow to zoom on the map/items in-game.
+ FPS limit.
+ Display using a system of ticks.
+ Handle the case in which if there is no change in the current view, we don't draw everything again (if it is lighter than redrawing everything).
+ Handle windows resizing correctly.
+ Display using the time.
+ Handle the case in which if there is no change in the current view,
we don't draw everything again (if it is lighter than redrawing
everything).
+ Handle window resizing correctly.
+ Find a way to load translations when “RUN_IN_PLACE” is set to 1.
Events
......@@ -46,11 +44,12 @@ Events
Textures
--------
+ Create the player textures.
+ Create ores’ textures.
+ Create the in-game objects textures.
+ Create menu’s textures.
+ Create the inventory’s textures.
+ Create the player textures,
+ create ores’ textures,
+ create the in-game objects textures,
+ create menu’s textures,
+ create the inventory’s textures,
+ create a texture sheet.
Configuration
-------------
......@@ -63,9 +62,8 @@ Save
Guile
-----
+ Use guile as the extension language.
+ Use guile as an extension language.
+ Create functions to move the view from guile.
+ Create functions to add a texture in the future linked list that will be
used to display informations on the in-game interface.
+ Create functions to add an element to the interface.
+ Provide to guile low level functions for displaying things on the interface
(e.g. the blit function).
#!/bin/bash
protoc --cpp_out=. src/player-data.proto
protoc --cpp_out=. src/tile.proto
{
"1" :
[
0,
0,
24,
24
],
"2" :
[
24,
0,
24,
24
],
"3" :
[
48,
0,
24,
24
]
}
\ No newline at end of file
{
"1" :
[
0,
0,
24,
48
],
"10" :
[
216,
0,
24,
24
],
"11" :
[
240,
0,
24,
24
],
"2" :
[
24,
0,
24,
48
],
"3" :
[
48,
0,
24,
24
],
"4" :
[
72,
0,
24,
24
],
"5" :
[
96,
0,
24,
24
],
"6" :
[
120,
0,
24,
24
],
"7" :
[
144,
0,
24,
24
],
"8" :
[
168,
0,
24,
24
],
"9" :
[
192,
0,
24,
24
]
}
\ No newline at end of file
{
"items" : ["textures/arbre1.png", "textures/arbre2.png",
"textures/charbon1.png", "textures/charbon2.png",
"textures/charbon3.png", "textures/cuivre1.png",
"textures/cuivre2.png", "textures/cuivre3.png",
"textures/fer1.png", "textures/fer2.png", "textures/fer3.png"],
"grounds" : ["textures/biome1.png", "textures/biome2.png",
"textures/biome3.png"]
}
project('Factorywars', 'cpp', license: 'GPLv3+', version: '0.1')
project('Factorywars', 'cpp', license: 'GPLv3+', version: '0.1',
default_options : ['cpp_std=c++11'])
compilateur = meson.get_compiler('cpp')
en_tetes = [include_directories('src'), include_directories('src/sdl')]
sources = ['src/main.cpp', 'src/items.cpp', 'src/config.cpp',
'src/items.cpp', 'src/map.cpp', 'src/tile.pb.cpp',
'src/multiplayer.cpp', 'src/network.cpp', 'src/player.cpp',
'src/player-data.pb.cpp', 'src/utils.cpp', 'src/XMLParser.cpp',
'src/sdl/display_item.cpp', 'src/sdl/display_map.cpp',
'src/sdl/game.cpp', 'src/sdl/game_events.cpp', 'src/sdl/gui_exit.cpp',
'src/sdl/gui_init.cpp', 'src/sdl/gui_utils.cpp', 'src/sdl/menu.cpp',
'src/sdl/keyboard.cpp', 'src/sdl/mouse.cpp', 'src/sdl/FPSCounter.cpp',
'src/sdl/Interface.cpp']
'src/items.cpp', 'src/save.cpp', 'src/tile.pb.cc', 'src/player.cpp',
'src/player-data.pb.cc', 'src/utils.cpp', 'src/XMLParser.cpp',
'src/sdl/display_map.cpp', 'src/sdl/game.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/MapGenerator.cpp', 'src/sdl/map.cpp', 'src/structures.hpp']
libxml2 = dependency('libxml-2.0')
libSDL2 = dependency('sdl2')
SDL2_image = dependency('SDL2_image')
protobuf = dependency('protobuf')
SDL2_ttf = dependency('SDL2_ttf')
guile = dependency('guile-2.0')
json = dependency('jsoncpp')
noise = compilateur.find_library('noise')
compilateur.has_header('noise/noise.h')
if compilateur.has_header('libnoise/noise.h')
add_global_arguments('-DLIBNOISE=1', language:'cpp')
else
compilateur.has_header('noise/noise.h')
endif
sfml = dependency('sfml-graphics')
executable('factorywars', sources, dependencies: [noise, libxml2,
libSDL2, SDL2_image, protobuf, SDL2_ttf, guile], include_directories :
sfml, protobuf, guile, json], include_directories :
en_tetes, cpp_args : ['-DLOCALEDIR="/usr/local/share/locale"',
'-DFONTSDIR="media/fonts"', '-DTEXTURESDIR="media/textures"',
'-DRUN_IN_PLACE=1'])
executable('spritesheet-generator', ['src/spritesheet-generator.cpp'],
dependencies: [sfml, json])
/**
* @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,
square_coordinates.y, 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_items_noise.GetValue
(square_coordinates.x * (1.0/20.0),
square_coordinates.y * (1.0/20.0), 0);
// cout << "Valeur aléatoire : " << random_value
// << "sol : " << floor_id
// << endl;
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 -1;
}
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, 2.0/3.0), // Désert
make_pair (2, 2.0/3.0), // Terre
make_pair (3, 2.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;
}
// for (auto threshold : m_floor_threshold)
// {
// cout << "Biome : " << get<0> (threshold) << " "
// << "[" << get<1> (threshold) << " ; " << get<2> (threshold)
// << "]" << endl;
// }
}
void
MapGenerator::generate_items_thresholds ()
{
m_item_threshold.clear ();
vector<tuple<int,int,double>> probabilities =
{
// Désert
make_tuple (1, 1, 0.0), // Arbre mort
make_tuple (1, 3, (1.0 / 24.0)), // Cuivre
make_tuple (1, 5, (1.0 / 24.0)), // Fer
make_tuple (1, 8, (1.0 / 24.0)), // Charbon
// Terre
make_tuple (2, 2, (1.0 / 3.0)), // Arbre
make_tuple (2, 3, (1.0 / 36.0)),
make_tuple (2, 5, (1.0 / 36.0)),
make_tuple (2, 8, (1.0 / 36.0)),
// Forêt
make_tuple (3, 2, (1.0 / 3.0)),
make_tuple (3, 3, (1.0 / 36.0)),
make_tuple (3, 5, (1.0 / 36.0)),
make_tuple (3, 8, (1.0 / 36.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;
}
// for (auto threshold : m_item_threshold)
// {
// cout << "Biome : " << get<0> (threshold) << " "
// << "Objet : " << get<1> (threshold) << " "
// << "[" << get<2> (threshold) << " ; " << get<3> (threshold)
// << "]" << endl;
// }
}
/**
* @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.hpp"
class MapGenerator
{
public:
/**
* The constructor.
*
* @param seed is the seed of the map.
*/
MapGenerator (int seed = 0);
/**
* 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 ();
};
......@@ -6,7 +6,7 @@
*
* @section LICENSE
*
* Copyright (C) 2016 Corentin Bocquillon <0x539@nybble.fr>
* Copyright (C) 2016-2018 Corentin Bocquillon <0x539@nybble.fr>
*
* Copyright (C) 2016 Loup Fourment
*
......@@ -30,132 +30,43 @@
* config.cpp handle the config file.
*/
#include <string>
#include "config.h"
using namespace std;
int
get_config_value (const char *key, char *dst, size_t dst_len)
Configuration::Configuration (std::string config_path)
: m_configuration_file_path (config_path)
{
string dst_string;
load_configuration ();
}
dst_string = get_config_value (string (key));
if (dst_string != "")
strncpy (dst, dst_string.c_str (), dst_len);
else
return 0;
Configuration::Configuration ()
: Configuration ("configuration.json")
{
return 1;
}
string
get_config_value (const string key)
Configuration::get_config_value (string key)
{
string path, conf_dir;
string config_value;
string filename = "factorywars.conf";
/* We get environment variables */
const char *xdg_config_home = getenv ("XDG_CONFIG_HOME");
const char *home = getenv ("HOME");
int return_default_value = 0;
if (RUN_IN_PLACE)
path = filename;
else if (xdg_config_home == NULL)
{
if (home == NULL)
path = filename;
else
{
/* We have to use the default value of XDG_CONFIG_HOME */
conf_dir = string (home) + "/.config/factorywars";
path = conf_dir + "/" + filename;
}
}
else
{
/* We use the current value of XDG_CONFIG_HOME */
conf_dir = string (xdg_config_home) + "/factorywars";
}
/* Test if conf_dir exists */
struct stat file_stat;
if (!RUN_IN_PLACE)
{
if (stat (conf_dir.c_str (), &file_stat) == -1)
{
if ((config_value = default_config_value (key)) == "")
return "";
return_default_value = 1;
}
else if (!S_ISDIR (file_stat.st_mode))
{
if ((config_value = default_config_value (key)) == "")
return "";
return_default_value = 1;
}
}
return m_root[key].asString ();
}
/* Test if path exists */
if (stat (path.c_str (), &file_stat) == -1)
void
Configuration::load_configuration ()
{
try
{
config_value = default_config_value (key);
if (config_value == "")
return "";
return_default_value = 1;
ifstream config_file (m_configuration_file_path, ifstream::in);
config_file >> m_root;
}
if (!return_default_value)
catch (...)
{
char *c = getValueOfElement (key.c_str (), 0, NULL, NULL, path.c_str ());
config_value = string (c);
free (c);
m_root["width"] = 1280;
m_root["height"] = 720;
m_root["name"] = "foobar";
ofstream config_file (m_configuration_file_path, ofstream::out);
config_file << m_root << endl;
return;
}
return config_value;
}
int
default_config_value (const char *key, char *dst, size_t dst_len)
{
string dst_string;
dst_string = default_config_value (string (key));
if (dst_string == "")
return 0;
else
strncpy (dst, dst_string.c_str (), dst_len);
return 1;
}
string
default_config_value (const string key)
{
string config_value;
if (key == "name")
config_value