Program Listing for File E_Mother.cpp¶
↰ Return to documentation for file (gui/Entities/E_Mother.cpp)
#include <cstdlib>
#include <iostream>
#include <sstream>
#include <string>
#include "Entities/E_Mother.hpp"
#include "API/Inventory/Inventory.hpp"
#include "Demeter/Renderer/asset_dir.hpp"
#include "Entities/E_Coms.hpp"
#include "logging/Logger.hpp"
bool E_Mother::Init(Dem::Demeter &d)
{
std::shared_ptr<E_Coms> eComsPtr = std::
dynamic_pointer_cast<E_Coms>(d.GetEntity(0));
_api = eComsPtr->GetApi();
fd = _api->GetEventsInFd();
_pollOutFd[0].fd = fd;
_pollOutFd[0].events = POLLIN;
_pollOutFd[0].revents = 0;
auto tmp = d.AddObject3D(ASSET_DIR "/cube.obj3D");
if (!tmp) {
Log::failed << "Failed to load object: " ASSET_DIR "/cube.obj3D";
return false;
}
_tile = *tmp;
tmp = d.AddObject3D(ASSET_DIR "/rock.obj3D");
if (!tmp) {
Log::failed << "Failed to load object: " ASSET_DIR "/rock.obj3D";
return false;
}
_ressources = *tmp;
tmp = d.AddObject3D(ASSET_DIR "/17855_Alien_v1.obj3D");
if (!tmp) {
Log::failed << "Failed to load object: " ASSET_DIR "/17855_Alien_v1.obj3D";
return false;
}
_player = *tmp;
tmp = d.AddObject3D(ASSET_DIR "/Egg.obj3D");
if (!tmp) {
Log::failed << "Failed to load object: " ASSET_DIR "/Egg.obj3D";
return false;
}
_egg = *tmp;
_textureTile = d.AddTexture(ASSET_DIR "/textures/grass.png");
_textureFood = d.AddTexture(ASSET_DIR "/textures/brown.png");
_textureLinemate = d.AddTexture(ASSET_DIR "/textures/yellow.png");
_textureDeraumere = d.AddTexture(ASSET_DIR "/textures/green.png");
_textureSibur = d.AddTexture(ASSET_DIR "/textures/blue.png");
_textureMendiane = d.AddTexture(ASSET_DIR "/textures/red.png");
_texturePhiras = d.AddTexture(ASSET_DIR "/textures/white.png");
_textureThystame = d.AddTexture(ASSET_DIR "/textures/pink.png");
_texturePlayer = d.AddTexture(ASSET_DIR "/textures/purple.png");
_textureEgg = d.AddTexture(ASSET_DIR "/textures/white.png");
_textureTeams[0] = d.AddTexture(ASSET_DIR "/textures/red.png");
_textureTeams[1] = d.AddTexture(ASSET_DIR "/textures/orange.png");
_textureTeams[2] = d.AddTexture(ASSET_DIR "/textures/yellow.png");
_textureTeams[3] = d.AddTexture(ASSET_DIR "/textures/green.png");
_textureTeams[4] = d.AddTexture(ASSET_DIR "/textures/cyan.png");
_textureTeams[5] = d.AddTexture(ASSET_DIR "/textures/light_blue.png");
_textureTeams[6] = d.AddTexture(ASSET_DIR "/textures/purple.png");
_textureTeams[7] = d.AddTexture(ASSET_DIR "/textures/pink.png");
return true;
}
namespace {
std::string getTeamNameFromMessage(
const std::string &message,
const std::map<std::string, std::vector<Trantor>> &teams)
{
try {
std::istringstream iss(message);
std::string command;
iss >> command;
int id = -1;
std::string teamName;
if (command == "pnw") {
std::string idStr;
int x;
int y;
int o;
int l;
iss >> idStr >> x >> y >> o >> l >> teamName;
if (teams.contains(teamName))
return teamName;
if (idStr[0] == '#')
id = std::stoi(idStr.substr(1));
}
else if (
command == "ppo" || command == "plv" || command == "pin"
|| command == "pex" || command == "pbc" || command == "pfk"
|| command == "pdr" || command == "pgt" || command == "pdi") {
std::string idStr;
iss >> idStr;
if (!idStr.empty() && idStr[0] == '#')
id = std::stoi(idStr.substr(1));
}
else if (command == "enw") {
std::string eggStr;
std::string idStr;
int x;
int y;
iss >> eggStr >> idStr >> x >> y;
if (!idStr.empty() && idStr[0] == '#')
id = std::stoi(idStr.substr(1));
}
if (id != -1) {
for (const auto &[team, trantors]: teams) {
for (const auto &trantor: trantors)
if (trantor.GetId() == id)
return team;
}
}
} catch (const std::exception &e) {
Log::warn << "Failed to parse team name from message: " << e.what();
}
return {};
}
} // namespace
bool E_Mother::Update(Dem::Demeter &)
{
_api->AskAllPlayerInventory();
_api->AskAllPlayerLevel();
_api->AskAllPlayerPos();
_api->AskAllTeamName();
_api->AskAllTileContent();
if (_api->GetTilemap().GetSize().first == 0
|| _api->GetTilemap().GetSize().second == 0) {
return false;
}
if (_tilemap.empty()) {
auto [width, height] = _api->GetTilemap().GetSize();
_tilemap.resize(height, std::vector<TileData>(width));
for (int i = 0; i < height; ++i)
for (int j = 0; j < width; ++j)
_tilemap[i][j] = {.x = i, .y = 0, .z = j, .rotation = 0.0};
}
std::array<char, 1024> buffer;
std::string fullData;
while (true) {
if (poll(_pollOutFd.data(), _pollOutFd.size(), 0) == -1) {
Log::failed << "Poll failed in E_Mother::Update";
return false;
}
if (!(_pollOutFd[0].revents & POLLIN))
break; // No data to read
ssize_t bytesRead = read(fd, buffer.data(), buffer.size());
if (bytesRead == -1) {
Log::failed << "Read failed in E_Mother::Update";
return false;
}
if (bytesRead == 0)
break; // No more data
fullData.append(buffer.data(), bytesRead);
}
std::stringstream ss(fullData);
std::string message;
while (std::getline(ss, message)) {
_eventIndex = (_eventIndex + 1) % _events.size();
// Set _events[_eventIndex].first to the team name
if (!getTeamNameFromMessage(message, _api->GetTeams()).empty()) {
_events[_eventIndex].first = getTeamNameFromMessage(
message, _api->GetTeams());
_events[_eventIndex].second = std::move(message);
if (_eventCount < _events.size())
_eventCount++;
}
}
return true;
}
static constexpr float tileHeight = 1.0;
bool E_Mother::Draw(Dem::Demeter &d)
{
// Draw Tiles
for (int i = 0; i < _api->GetTilemap().GetSize().second; i++)
for (int j = 0; j < _api->GetTilemap().GetSize().first; j++) {
modelMatrix = glm::translate(glm::mat4(1.0), glm::vec3(i, 0.0, j));
_tile->modelMatrix = modelMatrix;
_tile->SetTexture(0, _textureTile);
_tile->Draw(*d.GetShader(), d.camera);
std::map<std::string, size_t> tileInventory =
_api->GetTilemap().GetTileInventory(j, i).GetInventory();
int itemId = 0;
for (auto &item: tileInventory) {
for (size_t q = 0; q < item.second; q++) {
modelMatrix = glm::translate(
glm::mat4(1.0),
glm::vec3(
(i) + (0.1F * itemId) - 0.25F, tileHeight + (0.05F * q), (j)));
_ressources->modelMatrix = modelMatrix;
if (item.first == "food")
_ressources->SetTexture(0, _textureFood);
else if (item.first == "linemate")
_ressources->SetTexture(0, _textureLinemate);
else if (item.first == "deraumere")
_ressources->SetTexture(0, _textureDeraumere);
else if (item.first == "sibur")
_ressources->SetTexture(0, _textureSibur);
else if (item.first == "mendiane")
_ressources->SetTexture(0, _textureMendiane);
else if (item.first == "phiras")
_ressources->SetTexture(0, _texturePhiras);
else if (item.first == "thystame")
_ressources->SetTexture(0, _textureThystame);
else {
Log::warn
<< "Unknown item type: " << item.first << ", skipping drawing.";
continue; // Skip unknown items
}
_ressources->Draw(*d.GetShader(), d.camera);
}
itemId++;
}
}
// Draw Players
for (auto &teams: _api->GetTeams()) {
for (Trantor &trantor: teams.second) {
modelMatrix = glm::translate(
glm::mat4(1.0),
glm::vec3(
trantor.GetPosition().first
+ hashToRange(trantor.GetId() + trantor.GetPosition().first, 0.5),
tileHeight,
trantor.GetPosition().second
+ hashToRange(
trantor.GetId() + trantor.GetPosition().second, 0.5)));
modelMatrix = glm::rotate(
modelMatrix,
glm::radians(trantor.GetRotation() * 45.0F),
glm::vec3(0.0, 1.0, 0.0));
_player->modelMatrix = modelMatrix;
size_t teamsIndex = 0;
for (const auto &teamName: _api->GetTeamsName()) {
if (teamName == teams.first)
break;
teamsIndex++;
}
_player->SetTexture(0, _textureTeams[teamsIndex]);
_player->Draw(*d.GetShader(), d.camera);
}
}
// Draw Eggs
for (auto &egg: _api->GetEggList()) {
modelMatrix = glm::translate(
glm::mat4(1.0),
glm::vec3(
egg.second.first + hashToRange(egg.first + egg.second.first, 0.5),
tileHeight,
egg.second.second + hashToRange(egg.first + egg.second.second, 0.5)));
_egg->modelMatrix = modelMatrix;
_egg->SetTexture(0, _textureEgg);
_egg->Draw(*d.GetShader(), d.camera);
}
// Draw ImGui
_subWindowHandler.Run(d, _api, _events, _eventIndex, _eventCount);
return true;
}