Skip to content

Commit

Permalink
gamestate: Add players.
Browse files Browse the repository at this point in the history
  • Loading branch information
heinezen committed Aug 16, 2023
1 parent 467b7db commit 4f85999
Show file tree
Hide file tree
Showing 13 changed files with 217 additions and 42 deletions.
6 changes: 3 additions & 3 deletions libopenage/gamestate/component/internal/ownership.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
namespace openage::gamestate::component {

Ownership::Ownership(const std::shared_ptr<openage::event::EventLoop> &loop,
const ownership_id_t owner_id,
const player_id_t owner_id,
const time::time_t &creation_time) :
owner(loop, 0) {
this->owner.set_last(creation_time, owner_id);
Expand All @@ -22,11 +22,11 @@ inline component_t Ownership::get_type() const {
return component_t::OWNERSHIP;
}

void Ownership::set_owner(const time::time_t &time, const ownership_id_t owner_id) {
void Ownership::set_owner(const time::time_t &time, const player_id_t owner_id) {
this->owner.set_last(time, owner_id);
}

const curve::Discrete<ownership_id_t> &Ownership::get_owners() const {
const curve::Discrete<player_id_t> &Ownership::get_owners() const {
return this->owner;
}

Expand Down
11 changes: 5 additions & 6 deletions libopenage/gamestate/component/internal/ownership.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "curve/discrete.h"
#include "gamestate/component/internal_component.h"
#include "gamestate/component/types.h"
#include "gamestate/types.h"
#include "time/time.h"


Expand All @@ -18,8 +19,6 @@ class EventLoop;

namespace gamestate::component {

using ownership_id_t = uint64_t;

class Ownership : public InternalComponent {
public:
/**
Expand All @@ -30,7 +29,7 @@ class Ownership : public InternalComponent {
* @param creation_time Ingame creation time of the component.
*/
Ownership(const std::shared_ptr<openage::event::EventLoop> &loop,
const ownership_id_t owner_id,
const player_id_t owner_id,
const time::time_t &creation_time);

/**
Expand All @@ -48,20 +47,20 @@ class Ownership : public InternalComponent {
* @param time Time at which the owner ID is set.
* @param owner_id New owner ID.
*/
void set_owner(const time::time_t &time, const ownership_id_t owner_id);
void set_owner(const time::time_t &time, const player_id_t owner_id);

/**
* Get the owner IDs over time.
*
* @return Owner ID curve.
*/
const curve::Discrete<ownership_id_t> &get_owners() const;
const curve::Discrete<player_id_t> &get_owners() const;

private:
/**
* Owner ID storage over time.
*/
curve::Discrete<ownership_id_t> owner;
curve::Discrete<player_id_t> owner;
};

} // namespace gamestate::component
Expand Down
45 changes: 34 additions & 11 deletions libopenage/gamestate/entity_factory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include "gamestate/game_entity.h"
#include "gamestate/game_state.h"
#include "gamestate/manager.h"
#include "gamestate/player.h"
#include "gamestate/system/types.h"
#include "log/message.h"
#include "renderer/render_factory.h"
Expand Down Expand Up @@ -152,17 +153,22 @@ std::shared_ptr<activity::Activity> create_test_activity() {
}

EntityFactory::EntityFactory() :
next_id{0},
next_entity_id{0},
next_player_id{0},
render_factory{nullptr} {
}

std::shared_ptr<GameEntity> EntityFactory::add_game_entity(const std::shared_ptr<openage::event::EventLoop> &loop,
const std::shared_ptr<GameState> &state,
player_id_t owner_id,
const nyan::fqon_t &nyan_entity) {
auto entity = std::make_shared<GameEntity>(this->get_next_id());
auto entity = std::make_shared<GameEntity>(this->get_next_entity_id());
entity->set_manager(std::make_shared<GameEntityManager>(loop, state, entity));

init_components(loop, state, entity, nyan_entity);
// use the owner's data to initialize the entity
// this ensures that only the owner's tech upgrades apply
auto db_view = state->get_player(owner_id)->get_db_view();
init_components(loop, db_view, entity, nyan_entity);

if (this->render_factory) {
entity->set_render_entity(this->render_factory->add_world_render_entity());
Expand All @@ -171,14 +177,25 @@ std::shared_ptr<GameEntity> EntityFactory::add_game_entity(const std::shared_ptr
return entity;
}

std::shared_ptr<Player> EntityFactory::add_player(const std::shared_ptr<openage::event::EventLoop> & /* loop */,
const std::shared_ptr<GameState> &state,
const nyan::fqon_t & /* player_setup */) {
auto player = std::make_shared<Player>(this->get_next_player_id(),
state->get_db_view()->new_child());

// TODO: Components (for resources, diplomacy, etc.)

return player;
}

void EntityFactory::attach_renderer(const std::shared_ptr<renderer::RenderFactory> &render_factory) {
std::unique_lock lock{this->mutex};

this->render_factory = render_factory;
}

void EntityFactory::init_components(const std::shared_ptr<openage::event::EventLoop> &loop,
const std::shared_ptr<GameState> &state,
const std::shared_ptr<nyan::View> &owner_db_view,
const std::shared_ptr<GameEntity> &entity,
const nyan::fqon_t &nyan_entity) {
auto position = std::make_shared<component::Position>(loop);
Expand All @@ -190,13 +207,12 @@ void EntityFactory::init_components(const std::shared_ptr<openage::event::EventL
auto command_queue = std::make_shared<component::CommandQueue>(loop);
entity->add_component(command_queue);

auto db_view = state->get_nyan_db();
auto nyan_obj = db_view->get_object(nyan_entity);
auto nyan_obj = owner_db_view->get_object(nyan_entity);
nyan::set_t abilities = nyan_obj.get_set("GameEntity.abilities");

for (const auto &ability_val : abilities) {
auto ability_fqon = std::dynamic_pointer_cast<nyan::ObjectValue>(ability_val.get_ptr())->get_name();
auto ability_obj = db_view->get_object(ability_fqon);
auto ability_obj = owner_db_view->get_object(ability_fqon);

auto ability_parent = ability_obj.get_parents()[0];
if (ability_parent == "engine.ability.type.Move") {
Expand All @@ -218,7 +234,7 @@ void EntityFactory::init_components(const std::shared_ptr<openage::event::EventL
auto attr_settings = ability_obj.get_set("Live.attributes");
for (auto &setting : attr_settings) {
auto setting_obj_val = std::dynamic_pointer_cast<nyan::ObjectValue>(setting.get_ptr());
auto setting_obj = db_view->get_object(setting_obj_val->get_name());
auto setting_obj = owner_db_view->get_object(setting_obj_val->get_name());
auto attribute = setting_obj.get_object("AttributeSetting.attribute");
auto start_value = setting_obj.get_int("AttributeSetting.starting_value");

Expand All @@ -238,9 +254,16 @@ void EntityFactory::init_components(const std::shared_ptr<openage::event::EventL
entity->add_component(activity);
}

entity_id_t EntityFactory::get_next_id() {
auto new_id = this->next_id;
this->next_id++;
entity_id_t EntityFactory::get_next_entity_id() {
auto new_id = this->next_entity_id;
this->next_entity_id++;

return new_id;
}

player_id_t EntityFactory::get_next_player_id() {
auto new_id = this->next_player_id;
this->next_player_id++;

return new_id;
}
Expand Down
39 changes: 35 additions & 4 deletions libopenage/gamestate/entity_factory.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class RenderFactory;
namespace gamestate {
class GameEntity;
class GameState;
class Player;

/**
* Creates game entities that contain data of objects inside the game world.
Expand All @@ -43,14 +44,32 @@ class EntityFactory {
*
* @param loop Event loop for the gamestate.
* @param state State of the game.
* @param owner_id ID of the player owning the entity.
* @param nyan_entity fqon of the GameEntity data in the nyan database.
*
* @return New game entity.
*/
std::shared_ptr<GameEntity> add_game_entity(const std::shared_ptr<openage::event::EventLoop> &loop,
const std::shared_ptr<GameState> &state,
player_id_t owner_id,
const nyan::fqon_t &nyan_entity);

/**
* Create a new player.
*
* This just creates the player. The caller is responsible for initializing
* its components and placing it into the game.
*
* @param loop Event loop for the gamestate.
* @param state State of the game.
* @param player_setup fqon of the player setup in the nyan database.
*
* @return New player.
*/
std::shared_ptr<Player> add_player(const std::shared_ptr<openage::event::EventLoop> &loop,
const std::shared_ptr<GameState> &state,
const nyan::fqon_t &player_setup);

/**
* Attach a renderer which enables graphical display options for all ingame entities.
*
Expand All @@ -64,12 +83,12 @@ class EntityFactory {
* Initialize components of a game entity.
*
* @param loop Event loop for the gamestate.
* @param state State of the game.
* @param owner_db_view View of the nyan database of the player owning the entity.
* @param entity Game entity.
* @param nyan_entity fqon of the GameEntity data in the nyan database.
*/
void init_components(const std::shared_ptr<openage::event::EventLoop> &loop,
const std::shared_ptr<GameState> &state,
const std::shared_ptr<nyan::View> &owner_db_view,
const std::shared_ptr<GameEntity> &entity,
const nyan::fqon_t &nyan_entity);

Expand All @@ -78,12 +97,24 @@ class EntityFactory {
*
* @return Unique ID for a game entity.
*/
entity_id_t get_next_id();
entity_id_t get_next_entity_id();

/**
* Get a unique ID for creating a player.
*
* @return Unique ID for a player.
*/
player_id_t get_next_player_id();

/**
* ID of the next game entity to be created.
*/
entity_id_t next_id;
entity_id_t next_entity_id;

/**
* ID of the next player to be created.
*/
player_id_t next_player_id;

/**
* Factory for creating connector objects to the renderer which make game entities displayable.
Expand Down
7 changes: 4 additions & 3 deletions libopenage/gamestate/event/spawn_entity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ void SpawnEntityHandler::invoke(openage::event::EventLoop & /* loop */,
const param_map &params) {
auto gstate = std::dynamic_pointer_cast<gamestate::GameState>(state);

auto nyan_db = gstate->get_nyan_db();
auto nyan_db = gstate->get_db_view();

auto game_entities = nyan_db->get_obj_children_all("engine.util.game_entity.GameEntity");

Expand Down Expand Up @@ -151,7 +151,8 @@ void SpawnEntityHandler::invoke(openage::event::EventLoop & /* loop */,
}

// Create entity
auto entity = this->factory->add_game_entity(this->loop, gstate, nyan_entity);
player_id_t owner_id = params.get("owner", 0);
auto entity = this->factory->add_game_entity(this->loop, gstate, owner_id, nyan_entity);

// Setup components
auto entity_pos = std::dynamic_pointer_cast<component::Position>(
Expand All @@ -163,7 +164,7 @@ void SpawnEntityHandler::invoke(openage::event::EventLoop & /* loop */,

auto entity_owner = std::dynamic_pointer_cast<component::Ownership>(
entity->get_component(component::component_t::OWNERSHIP));
entity_owner->set_owner(time, params.get("owner", 0));
entity_owner->set_owner(time, owner_id);

auto activity = std::dynamic_pointer_cast<component::Activity>(
entity->get_component(component::component_t::ACTIVITY));
Expand Down
10 changes: 9 additions & 1 deletion libopenage/gamestate/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

#include "assets/mod_manager.h"
#include "assets/modpack.h"
#include "gamestate/entity_factory.h"
#include "gamestate/game_state.h"
#include "gamestate/universe.h"
#include "util/path.h"
Expand All @@ -20,12 +21,19 @@
namespace openage::gamestate {

Game::Game(const std::shared_ptr<openage::event::EventLoop> &event_loop,
const std::shared_ptr<assets::ModManager> &mod_manager) :
const std::shared_ptr<assets::ModManager> &mod_manager,
const std::shared_ptr<EntityFactory> &entity_factory) :
db{nyan::Database::create()},
state{std::make_shared<GameState>(this->db, event_loop)},
universe{std::make_shared<Universe>(state)} {
this->load_data(mod_manager);

// TODO: Testing player creation
auto player1 = entity_factory->add_player(event_loop, state, "");
auto player2 = entity_factory->add_player(event_loop, state, "");
state->add_player(player1);
state->add_player(player2);

// TODO: This lets the spawner event check which modpacks are loaded,
// so that it can decide which entities it can spawn.
// This can be removed when we spawn based on game logic rather than
Expand Down
6 changes: 4 additions & 2 deletions libopenage/gamestate/game.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class Path;

namespace gamestate {
class GameState;
class EntityFactory;
class Universe;

/**
Expand All @@ -46,12 +47,13 @@ class Game {
/**
* Create a new game.
*
* @param root_dir openage root directory.
* @param event_loop Event simulation loop for the gamestate.
* @param mod_manager Mod manager.
* @param entity_factory Factory for creating entities. Used for creating the players.
*/
Game(const std::shared_ptr<openage::event::EventLoop> &event_loop,
const std::shared_ptr<assets::ModManager> &mod_manager);
const std::shared_ptr<assets::ModManager> &mod_manager,
const std::shared_ptr<EntityFactory> &entity_factory);
~Game() = default;

/**
Expand Down
17 changes: 16 additions & 1 deletion libopenage/gamestate/game_state.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "log/log.h"

#include "gamestate/game_entity.h"
#include "gamestate/player.h"


namespace openage::gamestate {
Expand All @@ -18,7 +19,7 @@ GameState::GameState(const std::shared_ptr<nyan::Database> &db,
db_view{db->new_view()} {
}

const std::shared_ptr<nyan::View> &GameState::get_nyan_db() {
const std::shared_ptr<nyan::View> &GameState::get_db_view() {
return this->db_view;
}

Expand All @@ -29,6 +30,13 @@ void GameState::add_game_entity(const std::shared_ptr<GameEntity> &entity) {
this->game_entities[entity->get_id()] = entity;
}

void GameState::add_player(const std::shared_ptr<Player> &player) {
if (this->players.contains(player->get_id())) [[unlikely]] {
throw Error(MSG(err) << "Player with ID " << player->get_id() << " already exists");
}
this->players[player->get_id()] = player;
}

const std::shared_ptr<GameEntity> &GameState::get_game_entity(entity_id_t id) const {
if (!this->game_entities.contains(id)) [[unlikely]] {
throw Error(MSG(err) << "Game entity with ID " << id << " does not exist");
Expand All @@ -40,6 +48,13 @@ const std::unordered_map<entity_id_t, std::shared_ptr<GameEntity>> &GameState::g
return this->game_entities;
}

const std::shared_ptr<Player> &GameState::get_player(player_id_t id) const {
if (!this->players.contains(id)) [[unlikely]] {
throw Error(MSG(err) << "Player with ID " << id << " does not exist");
}
return this->players.at(id);
}

const std::shared_ptr<assets::ModManager> &GameState::get_mod_manager() const {
return this->mod_manager;
}
Expand Down
Loading

0 comments on commit 4f85999

Please sign in to comment.