You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
lunarium_OLD/src/world/world.cpp

316 lines
10 KiB
C++

/******************************************************************************
* File - world.cpp
* Author - Joey Pollack
* Date - 2022/01/12 (y/m/d)
* Mod Date - 2022/01/20 (y/m/d)
* Description - Manages a game "world". A world is made up of regions which
* are subdivisions of the world. Each region contains: a set
* of images for the maps layers, a list of objects that spawn
* in this region and static collision data.
******************************************************************************/
#include "world.h"
#include <utils/logger.h>
#include <assets/types/script.h>
#include <assets/types/image.h>
#include <renderer/renderer2D.h>
#include <renderer/orthographic_camera.h>
#include "entity.h"
namespace lunarium
{
// World::World(Camera* pCam, Sizei region_size, Sizei world_size)
// : mpCamera(pCam), mRegionSize(region_size), mpWorldScript(nullptr), mWorldSize(world_size)
// {
// mActiveRegion = { 0, 0 };
// }
World::World(std::string name)
: mUUID(UUID::GetNewID()), mName(name), mpActiveCamera(nullptr)
{
}
void World::OnLoad()
{
// TODO: Call OnLoad in the world script and on each region script
}
void World::OnUnload()
{
// TODO: Call OnUnLoad in the world script and on each region script
}
void World::SetRunMode(RunMode mode)
{
mMode = mode;
}
World::RunMode World::GetRunMode()
{
return mMode;
}
void World::Update(float dt)
{
// TODO: Update all entities
}
void World::Render(lunarium::Renderer2D* pGraphics)
{
// Draw the Renderables that also have a transform
// Code from:
// https://github.com/skypjack/entt/wiki/Crash-Course:-entity-component-system#views-and-groups
// mECSRegistry.view<TransformComponent, BlockOutComponent>().each([&](auto entity, auto &transform, auto &blockout)
// {
// Rectangle rect(transform.Position.x, transform.Position.y, blockout.Size.x, blockout.Size.y);
// Color color(blockout.Color.x, blockout.Color.y, blockout.Color.z, blockout.Color.w);
// glm::mat4 parent_transform(1.0f);
// if (mECSRegistry.all_of<ParentEntityComponent>(entity))
// {
// // UUIDComponent uuid = mECSRegistry.get<UUIDComponent>(entity);
// // LUUID uid = uuid.UUID;
// ParentEntityComponent& parent = mECSRegistry.get<ParentEntityComponent>(entity);
// parent_transform = GetParentTransform(parent.Parent);
// }
// pGraphics->DrawQuad(rect, color, nullptr, 0.0f, Rectangle(-1, -1, -1, -1), parent_transform);
// });
// OLD RENDER HEIRARCHY RENDER SYSTEM
// mECSRegistry.view<TransformComponent, BlockOutComponent>().each([&](auto entity, auto &transform, auto &blockout)
// {
// Rectangle rect(transform.Position.x, transform.Position.y, blockout.Size.x, blockout.Size.y);
// Color color(blockout.Color.x, blockout.Color.y, blockout.Color.z, blockout.Color.w);
// if (!mECSRegistry.all_of<ParentEntityComponent>(entity))
// {
// DrawHeirarchy(pGraphics, entity, transform, blockout, glm::mat4(1.0f));
// }
// });
// NEW RENDER SYSTEM
// First get the group we want
auto group = mECSRegistry.group<>(entt::get<BlockOutComponent, TransformComponent>);
// Next sort the group
group.sort<BlockOutComponent>([](const BlockOutComponent &lhs, const BlockOutComponent &rhs)
{
return lhs.RenderLayer < rhs.RenderLayer;
});
// Render the group
for(auto entity: group)
{
auto &transform = group.get<TransformComponent>(entity);
auto &blockout = group.get<BlockOutComponent>(entity);
Rectangle rect(transform.Position.x, transform.Position.y, blockout.Size.x, blockout.Size.y);
Color color(blockout.Color.x, blockout.Color.y, blockout.Color.z, blockout.Color.w);
// Get and apply parent transforms
LUUID uuid = mECSRegistry.get<UUIDComponent>(entity).UUID;
Entity* pEnt = GetEntity(uuid);
glm::mat4 parent_transform = glm::mat4(1.0f);
if (pEnt->HasComponent<ParentEntityComponent>())
{
parent_transform = GetParentTransform(uuid);
}
pGraphics->DrawQuad(rect, color, nullptr, -transform.Rotation.z, Rectangle(-1, -1, -1, -1), parent_transform);
}
}
void World::SetActiveCamera(OrthographicCamera* pCam)
{
mpActiveCamera = pCam;
}
entt::registry* World::GetEntityRegistry()
{
return &mECSRegistry;
}
LUUID World::CreateEntity()
{
//Logger::Error(LogCategory::GAME_SYSTEM, "World::CreateEntity not implemented!");
Entity* new_ent = new Entity(*this);
if (mEntitiesByUUID.find(new_ent->GetUUID()) != mEntitiesByUUID.end())
{
Logger::Warn(LogCategory::GAME_SYSTEM, "UUID collision when creating new entity! UUID: %d", new_ent->GetUUID());
}
mEntitiesByUUID[new_ent->GetUUID()] = new_ent;
mEntities.push_back(new_ent);
return new_ent->GetUUID();
}
Entity* World::GetEntity(LUUID id)
{
if (mEntitiesByUUID.find(id) == mEntitiesByUUID.end())
{
Logger::Warn(LogCategory::GAME_SYSTEM, "Entity with id: %d not found.", id);
}
return mEntitiesByUUID[id];
}
unsigned int World::GetNumEntities() const
{
return mEntities.size();
}
std::vector<Entity*>::iterator World::EntitiesBegin()
{
return mEntities.begin();
}
bool World::EntitiesIsEnd(std::vector<Entity*>::iterator& iter)
{
return iter == mEntities.end();
}
/////////////////////////////////////////////////////////////////////
// RUN MODE HELPERS
/////////////////////////////////////////////////////////////////////
void World::DrawHeirarchy(lunarium::Renderer2D* g, entt::entity& entity, TransformComponent& my_trans, BlockOutComponent& bo_comp, glm::mat4 current_transform)
{
// Draw current entity
Rectangle rect(my_trans.Position.x, my_trans.Position.y, bo_comp.Size.x, bo_comp.Size.y);
Color color(bo_comp.Color.x, bo_comp.Color.y, bo_comp.Color.z, bo_comp.Color.w);
g->DrawQuad(rect, color, nullptr, -my_trans.Rotation.z, Rectangle(-1, -1, -1, -1), current_transform);
// Apply transform to children's transforms
current_transform *= my_trans.GetTransform();
// Iterate and draw children
if (mECSRegistry.all_of<ChildrenComponent>(entity))
{
ChildrenComponent& children_comp = mECSRegistry.get<ChildrenComponent>(entity);
for (int i = 0; i < children_comp.Children.size(); i++)
{
Entity* pEnt = GetEntity(children_comp.Children[i]);
entt::entity handle = pEnt->GetEnttHandle();
if (pEnt->HasComponent<TransformComponent>() && pEnt->HasComponent<BlockOutComponent>())
{
TransformComponent& trans_comp = pEnt->GetComponent<TransformComponent>();
BlockOutComponent& bo_comp = pEnt->GetComponent<BlockOutComponent>();
DrawHeirarchy(g, handle, trans_comp, bo_comp, current_transform);
}
}
}
}
glm::mat4 World::GetParentTransform(LUUID parent)
{
glm::mat4 transform(1.0f);
Entity* p = GetEntity(parent);
if (p->HasComponent<TransformComponent>())
{
TransformComponent t = p->GetComponent<TransformComponent>();
transform = t.GetTransform();
if (p->HasComponent<ParentEntityComponent>())
{
transform *= GetParentTransform(p->GetComponent<ParentEntityComponent>().Parent);
}
}
return transform;
}
void World::RenderEditor(lunarium::Renderer2D* pGraphics) const
{
// NOTE: MAY BE REMOVED
}
/////////////////////////////////////////////////////////////////////
// SERIALIZING
/////////////////////////////////////////////////////////////////////
OpRes World::Serialize(nlohmann::ordered_json& node)
{
#if !BUILD_NO_EDITOR // Only does this when this is an editor build
node["UUID"] = mUUID;
node["NumberOfEntities"] = mEntities.size();
auto& ents = node["Entities"];
for (int i = 0; i < mEntities.size(); i++)
{
nlohmann::ordered_json e;
mEntities[i]->Serialize(e).LogIfFailed(LogCategory::GAME_SYSTEM);
ents.emplace_back(e);
}
#endif
return OpRes::OK();
}
OpRes World::Deserialize(nlohmann::ordered_json& node)
{
#if !BUILD_NO_EDITOR // Only does this when this is an editor build
mUUID = node["UUID"].get<u64>();
int num_entities = node["NumberOfEntities"].get<int>();
auto& ents = node["Entities"];
for (auto it = ents.begin(); it != ents.end(); ++it)
{
auto& ent = (*it);
Entity* new_ent = new Entity(*this);
if (!new_ent->IsValidNode(ent))
{
delete new_ent;
return OpRes::Fail("Invalid entity node");
}
new_ent->Deserialize(ent).LogIfFailed(LogCategory::GAME_SYSTEM);
mEntities.push_back(new_ent);
mEntitiesByUUID[new_ent->GetUUID()] = new_ent;
}
#endif
return OpRes::OK();
}
bool World::IsValidNode(nlohmann::ordered_json& node)
{
if (node["UUID"].is_null()) { return false; }
if (!node["UUID"].is_number()) { return false; }
if (node["NumberOfEntities"].is_null()) { return false; }
if (!node["NumberOfEntities"].is_number()) { return false; }
if (node["Entities"].is_null()) { return false; }
return false;
}
nlohmann::ordered_json World::AsJSON()
{
#if !BUILD_NO_EDITOR // Only does this when this is an editor build
nlohmann::ordered_json node;
Serialize(node).LogIfFailed(LogCategory::GAME_SYSTEM);
return node;
#endif
return nlohmann::ordered_json();
}
}