mod.registerTile("dirt", (new Swan::Tile("assets/tiles/dirt.png"))); | mod.registerTile("dirt", (new Swan::Tile("assets/tiles/dirt.png"))); | ||||
mod.registerTile("grass", (new Swan::Tile("assets/tiles/grass.png"))); | mod.registerTile("grass", (new Swan::Tile("assets/tiles/grass.png"))); | ||||
mod.registerWorldGen("Default", new DefaultWorldGen::Factory()); | |||||
mod.registerWorldGen("default", new DefaultWorldGen::Factory()); | |||||
} | } | ||||
int main() { | int main() { |
#pragma once | |||||
#include <memory> | |||||
#include "common.h" | |||||
namespace Swan { | |||||
class Entity { | |||||
public: | |||||
class Factory { | |||||
public: | |||||
std::string name_; | |||||
virtual Entity *create(const Vec2 &pos) = 0; | |||||
}; | |||||
virtual void draw(Win &win) {} | |||||
virtual void update(float dt) {} | |||||
virtual void tick() {} | |||||
}; | |||||
} |
std::unique_ptr<World> world_ = NULL; | std::unique_ptr<World> world_ = NULL; | ||||
void loadMod(const std::string &path); | void loadMod(const std::string &path); | ||||
void createWorld(); | |||||
void createWorld(std::string worldgen); | |||||
void draw(Win &win); | void draw(Win &win); | ||||
void update(float dt); | void update(float dt); |
#include "Tile.h" | #include "Tile.h" | ||||
#include "WorldGen.h" | #include "WorldGen.h" | ||||
#include "Entity.h" | |||||
namespace Swan { | namespace Swan { | ||||
std::string path_; | std::string path_; | ||||
std::vector<std::shared_ptr<Tile>> tiles_; | std::vector<std::shared_ptr<Tile>> tiles_; | ||||
std::vector<std::shared_ptr<WorldGen::Factory>> worldgens_; | std::vector<std::shared_ptr<WorldGen::Factory>> worldgens_; | ||||
std::vector<std::shared_ptr<Entity::Factory>> entities_; | |||||
bool inited_ = false; | bool inited_ = false; | ||||
void init(const std::string &name); | void init(const std::string &name); | ||||
void registerTile(const std::string &name, Tile *tile); | void registerTile(const std::string &name, Tile *tile); | ||||
void registerWorldGen(const std::string &name, WorldGen::Factory *gen); | void registerWorldGen(const std::string &name, WorldGen::Factory *gen); | ||||
void registerEntity(const std::string &name, Entity::Factory *ent); | |||||
}; | }; | ||||
} | } |
#include "Player.h" | #include "Player.h" | ||||
#include "Tile.h" | #include "Tile.h" | ||||
#include "WorldPlane.h" | #include "WorldPlane.h" | ||||
#include "WorldPlane.h" | |||||
#include "Tile.h" | |||||
#include "WorldGen.h" | |||||
#include "Entity.h" | |||||
namespace Swan { | namespace Swan { | ||||
WorldPlane::ID current_plane_; | WorldPlane::ID current_plane_; | ||||
std::vector<WorldPlane> planes_; | std::vector<WorldPlane> planes_; | ||||
std::string default_worldgen_; | |||||
WorldGen::ID default_worldgen_; | |||||
std::vector<std::shared_ptr<WorldGen::Factory>> worldgens_; | |||||
TileMap tile_map_; | TileMap tile_map_; | ||||
std::map<std::string, std::shared_ptr<WorldGen::Factory>> worldgens_; | |||||
std::map<std::string, std::shared_ptr<Entity::Factory>> ents_; | |||||
WorldPlane::ID addPlane(WorldGen::ID gen); | |||||
WorldPlane::ID addPlane(std::string gen); | |||||
WorldPlane::ID addPlane() { return addPlane(default_worldgen_); } | WorldPlane::ID addPlane() { return addPlane(default_worldgen_); } | ||||
void setCurrentPlane(WorldPlane::ID id) { current_plane_ = id; } | void setCurrentPlane(WorldPlane::ID id) { current_plane_ = id; } | ||||
WorldPlane &getPlane(WorldPlane::ID id) { return planes_[id]; } | WorldPlane &getPlane(WorldPlane::ID id) { return planes_[id]; } | ||||
} | } | ||||
void registerWorldGen(std::shared_ptr<WorldGen::Factory> gen) { | void registerWorldGen(std::shared_ptr<WorldGen::Factory> gen) { | ||||
worldgens_.push_back(gen); | |||||
worldgens_[gen->name_] = gen; | |||||
} | |||||
void registerEntity(std::shared_ptr<Entity::Factory> ent) { | |||||
ents_[ent->name_] = ent; | |||||
} | } | ||||
void draw(Win &win); | void draw(Win &win); |
class WorldGen { | class WorldGen { | ||||
public: | public: | ||||
using ID = int; | |||||
class Factory { | class Factory { | ||||
public: | public: | ||||
std::string name_; | std::string name_; |
#include "Tile.h" | #include "Tile.h" | ||||
#include "TileMap.h" | #include "TileMap.h" | ||||
#include "WorldGen.h" | #include "WorldGen.h" | ||||
#include "Entity.h" | |||||
namespace Swan { | namespace Swan { | ||||
public: | public: | ||||
using ID = uint16_t; | using ID = uint16_t; | ||||
std::map<std::pair<int, int>, Chunk> chunks_; | |||||
ID id_; | ID id_; | ||||
World *world_; | World *world_; | ||||
std::shared_ptr<WorldGen> gen_; | std::shared_ptr<WorldGen> gen_; | ||||
std::map<std::pair<int, int>, Chunk> chunks_; | |||||
std::vector<std::shared_ptr<Entity>> entities_; | |||||
WorldPlane(ID id, World *world, std::shared_ptr<WorldGen> gen): | WorldPlane(ID id, World *world, std::shared_ptr<WorldGen> gen): | ||||
id_(id), world_(world), gen_(gen) {} | id_(id), world_(world), gen_(gen) {} |
mod_init(mod); | mod_init(mod); | ||||
} | } | ||||
void Game::createWorld() { | |||||
void Game::createWorld(std::string worldgen) { | |||||
world_.reset(new World()); | world_.reset(new World()); | ||||
for (auto &mod: registered_mods_) { | for (auto &mod: registered_mods_) { | ||||
for (auto &tile: mod.tiles_) | for (auto &tile: mod.tiles_) | ||||
world_->registerTile(tile); | world_->registerTile(tile); | ||||
for (auto &worldgen: mod.worldgens_) | for (auto &worldgen: mod.worldgens_) | ||||
world_->registerWorldGen(worldgen); | world_->registerWorldGen(worldgen); | ||||
for (auto &entity: mod.entities_) | |||||
world_->registerEntity(entity); | |||||
} | } | ||||
world_->default_worldgen_ = worldgen; | |||||
} | } | ||||
void Game::draw(Win &win) { | void Game::draw(Win &win) { |
} | } | ||||
void Mod::registerWorldGen(const std::string &name, WorldGen::Factory *gen) { | void Mod::registerWorldGen(const std::string &name, WorldGen::Factory *gen) { | ||||
gen->name_ = name; | |||||
gen->name_ = name_ + "::" + name; | |||||
worldgens_.push_back(std::shared_ptr<WorldGen::Factory>(gen)); | worldgens_.push_back(std::shared_ptr<WorldGen::Factory>(gen)); | ||||
} | } | ||||
void Mod::registerEntity(const std::string &name, Entity::Factory *ent) { | |||||
ent->name_ = name_ + "::" + name; | |||||
entities_.push_back(std::shared_ptr<Entity::Factory>(ent)); | |||||
} | |||||
} | } |
namespace Swan { | namespace Swan { | ||||
WorldPlane::ID World::addPlane(WorldGen::ID gen) { | |||||
WorldPlane::ID World::addPlane(std::string gen) { | |||||
WorldPlane::ID id = planes_.size(); | WorldPlane::ID id = planes_.size(); | ||||
if (worldgens_.find(gen) == worldgens_.end()) { | |||||
fprintf(stderr, "Tried to add plane with non-existant world gen '%s'!\n", | |||||
gen.c_str()); | |||||
abort(); | |||||
} | |||||
WorldGen *g = worldgens_[gen]->create(tile_map_); | WorldGen *g = worldgens_[gen]->create(tile_map_); | ||||
planes_.push_back(WorldPlane(id, this, std::shared_ptr<WorldGen>(g))); | planes_.push_back(WorldPlane(id, this, std::shared_ptr<WorldGen>(g))); | ||||
return id; | return id; |
void WorldPlane::draw(Win &win) { | void WorldPlane::draw(Win &win) { | ||||
for (auto &p: chunks_) { | for (auto &p: chunks_) { | ||||
p.second.draw(win); | p.second.draw(win); | ||||
for (auto &ent: entities_) | |||||
ent->draw(win); | |||||
} | } | ||||
} | } | ||||
void WorldPlane::update(float dt) { | void WorldPlane::update(float dt) { | ||||
for (auto &ent: entities_) | |||||
ent->update(dt); | |||||
} | } | ||||
void WorldPlane::tick() { | void WorldPlane::tick() { | ||||
for (auto &ent: entities_) | |||||
ent->tick(); | |||||
} | } | ||||
} | } |
Game game; | Game game; | ||||
game.loadMod("core.mod"); | game.loadMod("core.mod"); | ||||
game.createWorld(); | |||||
game.createWorld("core::default"); | |||||
game.world_->setCurrentPlane(game.world_->addPlane()); | game.world_->setCurrentPlane(game.world_->addPlane()); | ||||
game.world_->player_ = new Player(Vec2(1, 1)); | game.world_->player_ = new Player(Vec2(1, 1)); | ||||