-Subproject commit 46d3c2d2fb145405994b69291037a3c9e66ab3d1
+Subproject commit ce337a6b5afd87607a94f006631a390eefceeec1
struct {
world::Set<world::Resource> resources;
- world::Set<world::TileType> tiles;
+ world::Set<world::TileType> tile_types;
} data;
struct {
}
{
- std::ifstream tile_file(data_path + "tiles");
+ std::ifstream tile_file(data_path + "tile_types");
io::TokenStreamReader tile_reader(tile_file);
ReadTileTypes(tile_reader);
}
in.Skip(io::Token::EQUALS);
int id = 0;
- if (data.tiles.Has(name)) {
- id = data.tiles[name].id;
+ if (data.tile_types.Has(name)) {
+ id = data.tile_types[name].id;
} else {
world::TileType type;
type.name = name;
- id = data.tiles.Add(type);
+ id = data.tile_types.Add(type);
}
in.Skip(io::Token::ANGLE_BRACKET_OPEN);
in.ReadIdentifier(name);
in.Skip(io::Token::EQUALS);
if (name == "label") {
- in.ReadString(data.tiles[id].label);
+ in.ReadString(data.tile_types[id].label);
} else if (name == "texture") {
- data.tiles[id].texture = in.GetInt();
+ data.tile_types[id].texture = in.GetInt();
} else if (name == "yield") {
in.Skip(io::Token::BRACKET_OPEN);
while (in.Peek().type != io::Token::BRACKET_CLOSE) {
in.Skip(io::Token::SEMICOLON);
}
in.Skip(io::Token::ANGLE_BRACKET_CLOSE);
- data.tiles[id].resources.push_back(yield);
+ data.tile_types[id].resources.push_back(yield);
if (in.Peek().type == io::Token::COMMA) {
in.Skip(io::Token::COMMA);
}
second_planet.AxialTilt(glm::dvec2(PI * 0.95, 0.0));
second_planet.AngularMomentum(1.0e8);
- world::Simulation sim(sun);
+ world::Simulation sim(sun, assets.data.resources, assets.data.tile_types);
sim.AddSun(sun);
sim.AddPlanet(planet);
sim.AddPlanet(second_planet);
sim.AddPlanet(moon);
- world::GenerateEarthlike(assets.data.tiles, planet);
+ world::GenerateEarthlike(assets.data.tile_types, planet);
planet.Atmosphere(assets.data.resources["air"].id);
- world::GenerateTest(assets.data.tiles, moon);
- world::GenerateTest(assets.data.tiles, second_planet);
+ world::GenerateTest(assets.data.tile_types, moon);
+ world::GenerateTest(assets.data.tile_types, second_planet);
std::cout << "length of year: " << planet.OrbitalPeriod() << "s" << std::endl;
std::cout << "length of moon cycle: " << moon.OrbitalPeriod() << "s" << std::endl;
int resource;
double speed;
double damage;
+ bool ingesting;
};
namespace blobs {
namespace world {
class Planet;
+ class Tile;
+ class TileType;
}
namespace creature {
public:
bool OnPlanet() const noexcept;
world::Planet &GetPlanet() const noexcept { return *planet; }
+ bool OnSurface() const noexcept;
int Surface() const noexcept { return surface; }
const glm::dvec3 &Position() const noexcept { return position; }
+ world::Tile &GetTile() const noexcept;
+ const world::TileType &GetTileType() const noexcept;
void SetPlanetSurface(world::Planet &, int srf, const glm::dvec3 &pos) noexcept;
#include "../app/Assets.hpp"
#include "../world/Body.hpp"
#include "../world/Planet.hpp"
+#include "../world/Simulation.hpp"
#include "../world/TileType.hpp"
#include <glm/gtx/transform.hpp>
std::map<int, double> yields;
for (int y = start; y < end; ++y) {
for (int x = start; x < end; ++x) {
- const world::TileType &t = assets.data.tiles[p.TileAt(0, x, y).type];
+ const world::TileType &t = assets.data.tile_types[p.TileAt(0, x, y).type];
for (auto yield : t.resources) {
yields[yield.resource] += yield.ubiquity;
}
std::cout << "require drinking " << assets.data.resources[liquid].label << std::endl;
std::unique_ptr<Need> need(new IngestNeed(liquid, 0.2, 0.01));
need->name = assets.data.resources[liquid].label;
- need->gain = 0.0001;
+ need->gain = 0.01;
need->inconvenient = 0.6;
need->critical = 0.95;
c.AddNeed(std::move(need));
}
if (solid > -1) {
std::cout << "require eating " << assets.data.resources[solid].label << std::endl;
- std::unique_ptr<Need> need(new IngestNeed(solid, 0.03, 0.001));
+ std::unique_ptr<Need> need(new IngestNeed(solid, 0.1, 0.001));
need->name = assets.data.resources[solid].label;
- need->gain = 0.00001;
+ need->gain = 0.007;
need->inconvenient = 0.6;
need->critical = 0.95;
c.AddNeed(std::move(need));
return type == PLANET_SURFACE;
}
+bool Situation::OnSurface() const noexcept {
+ return type == PLANET_SURFACE;
+}
+
+world::Tile &Situation::GetTile() const noexcept {
+ double side_length = planet->SideLength();
+ double offset = side_length * 0.5;
+ double x = std::max(0.0, std::min(side_length, position.x + offset));
+ double y = std::max(0.0, std::min(side_length, position.y + offset));
+ return planet->TileAt(surface, int(x), int(y));
+}
+
+const world::TileType &Situation::GetTileType() const noexcept {
+ return planet->GetSimulation().TileTypes()[GetTile().type];
+}
+
void Situation::SetPlanetSurface(world::Planet &p, int srf, const glm::dvec3 &pos) noexcept {
type = PLANET_SURFACE;
planet = &p;
#include "Creature.hpp"
#include "../world/Planet.hpp"
+#include "../world/TileType.hpp"
namespace blobs {
IngestNeed::IngestNeed(int resource, double speed, double damage)
: resource(resource)
, speed(speed)
-, damage(damage) {
+, damage(damage)
+, ingesting(false) {
}
IngestNeed::~IngestNeed() {
}
void IngestNeed::ApplyEffect(Creature &c, double dt) {
+ if (!IsSatisfied()) {
+ ingesting = true;
+ }
if (!IsSatisfied()) {
// TODO: find resource and start ingest task
+ if (c.GetSituation().OnSurface()) {
+ const world::TileType &t = c.GetSituation().GetTileType();
+ for (auto &yield : t.resources) {
+ if (yield.resource == resource) {
+ Decrease(std::min(yield.ubiquity, speed) * dt);
+ break;
+ }
+ }
+ }
}
if (IsCritical()) {
c.Hurt(damage * dt);
}
void InhaleNeed::ApplyEffect(Creature &c, double dt) {
- if (!IsSatisfied() && !inhaling) {
+ if (!IsSatisfied()) {
inhaling = true;
}
if (inhaling) {
return tiles[IndexOf(surface, x, y)];
}
+ const TileType &TypeAt(int surface, int x, int y) const;
+
/// Convert coordinates into a tile index.
int IndexOf(int surface, int x, int y) const {
assert(0 <= surface && surface <= 5);
#ifndef BLOBS_WORLD_SIMULATION_HPP_
#define BLOBS_WORLD_SIMULATION_HPP_
+#include "Set.hpp"
+
#include <set>
class Body;
class Planet;
+class Resource;
class Sun;
+class TileType;
class Simulation {
public:
- explicit Simulation(Body &root);
+ explicit Simulation(Body &root, const Set<Resource> &, const Set<TileType> &);
~Simulation();
Simulation(const Simulation &) = delete;
Body &Root() noexcept { return root; }
const Body &Root() const noexcept { return root; }
+ const Set<Resource> &Resources() const noexcept { return resources; }
+ const Set<TileType> &TileTypes() const noexcept { return tile_types; }
+
const std::set<Body *> &Bodies() const noexcept { return bodies; }
const std::set<Planet *> &Planets() const noexcept { return planets; }
const std::set<Sun *> &Suns() const noexcept { return suns; }
private:
Body &root;
+ const Set<Resource> &resources;
+ const Set<TileType> &tile_types;
std::set<Body *> bodies;
std::set<Planet *> planets;
std::set<Sun *> suns;
namespace blobs {
namespace world {
-Simulation::Simulation(Body &r)
+Simulation::Simulation(Body &r, const Set<Resource> &res, const Set<TileType> &tile)
: root(r)
+, resources(res)
+, tile_types(tile)
, bodies()
, planets()
, suns()
Planet::~Planet() {
}
+const TileType &Planet::TypeAt(int surface, int x, int y) const {
+ return GetSimulation().TileTypes()[TileAt(surface, x, y).type];
+}
+
glm::dvec3 Planet::TileCenter(int surface, int x, int y) const noexcept {
glm::dvec3 center(0.0f);
center[(surface + 0) % 3] = x + 0.5 - Radius();