// // Created by Zoe Roux on 6/11/21. // #include "System/Event/EventSystem.hpp" #include "Component/Renderer/Drawable2DComponent.hpp" #include "System/Lobby/LobbySystem.hpp" #include "Component/Controllable/ControllableComponent.hpp" #include "System/MenuControllable/MenuControllableSystem.hpp" #include "Component/Tag/TagComponent.hpp" #include #include #include #include #include #include namespace RAY3D = RAY::Drawables::Drawables3D; namespace BBM { std::array LobbySystem::_colors = { "blue", "red", "green", // "purple", TODO MISSING ICONS // "cyan", "yellow" }; std::array LobbySystem::_rayColors = { BLUE, RED, GREEN, // PURPLE, // SKYBLUE, YELLOW }; LobbySystem::LobbySystem(WAL::Wal &wal) : System(wal) {} void LobbySystem::_nextColor(WAL::ViewEntity &entity) { auto &lobby = entity.get(); if (lobby.color != -1) this->_colorTaken[lobby.color] = false; do { lobby.color++; if (lobby.color >= this->_colorTaken.size()) lobby.color = 0; } while (this->_colorTaken[lobby.color]); this->_colorTaken[lobby.color] = true; entity.get().drawable = std::make_shared("assets/player/icons/" + _colors[lobby.color] + ".png"); lobby.coloredTile.getComponent().drawable->setColor(_rayColors[lobby.color]); } void LobbySystem::onUpdate(WAL::ViewEntity &entity, std::chrono::nanoseconds dtime) { auto &lobby = entity.get(); auto lastTick = std::chrono::steady_clock::now(); if (lastTick - lobby.lastInput < std::chrono::milliseconds(150)) return; if (lobby.layout == ControllableComponent::NONE) { for (auto &[_, ctrl] : this->_wal.getScene()->view()) { auto &controller = ctrl; if (controller.jump) { if (std::any_of(this->getView().begin(), this->getView().end(), [&controller](WAL::ViewEntity &view) { return view.get().layout == controller.layout; })) return; lobby.lastInput = lastTick; lobby.color = -1; this->_nextColor(entity); lobby.layout = controller.layout; controller.jump = false; return; } } } for (auto &[_, controller] : this->_wal.getScene()->view()) { if (controller.layout != lobby.layout) continue; if (controller.jump && !lobby.ready) { lobby.ready = true; lobby.lastInput = lastTick; controller.jump = false; this->_wal.getSystem().now = lastTick; auto *texture = dynamic_cast(lobby.readyButton.getComponent().drawable.get()); if (texture) texture->use("assets/player/icons/ready.png"); } if (controller.bomb && !lobby.ready) { lobby.lastInput = lastTick; this->_nextColor(entity); } } } void LobbySystem::onSelfUpdate() { auto &view = this->_wal.getScene()->view, Drawable2DComponent>(); if (view.size() == 0) return; auto *texture = dynamic_cast(view.front().get().drawable.get()); if (!texture) return; if (playersAreReady(*this->_wal.getScene())) texture->setColor(WHITE); else texture->setColor(GRAY); } bool LobbySystem::playersAreReady(WAL::Scene &scene) { auto &lobby = scene.view(); return std::all_of(lobby.begin(), lobby.end(), [](WAL::ViewEntity &entity) { auto &lobbyPlayer = entity.get(); return lobbyPlayer.ready || lobbyPlayer.layout == ControllableComponent::NONE; }); } void LobbySystem::_addController(WAL::Entity &player, ControllableComponent::Layout layout) { switch (layout) { case ControllableComponent::KEYBOARD_0: case ControllableComponent::KEYBOARD_1: player.addComponent(layout); break; case ControllableComponent::GAMEPAD_0: player.addComponent(0); break; case ControllableComponent::GAMEPAD_1: player.addComponent(1); break; case ControllableComponent::GAMEPAD_2: player.addComponent(2); break; case ControllableComponent::GAMEPAD_3: player.addComponent(3); break; default: throw std::runtime_error("Invalid controller for a player."); } } void LobbySystem::switchToGame(WAL::Wal &wal) { auto scene = Runner::loadGameScene(); int mapWidth = 16; int mapHeight = 16; int playerCount = 0; for (auto &[_, lobby] : wal.getScene()->view()) { if (lobby.layout == ControllableComponent::NONE) continue; auto &player = Runner::createPlayer(*scene); _addController(player, lobby.layout); player.getComponent().position = Vector3f(mapWidth * (playerCount % 2), 0, mapHeight * ((playerCount + 1) % 2)); auto *model = dynamic_cast(player.getComponent().drawable.get()); model->setTextureToMaterial(MAP_DIFFUSE, "assets/player/textures/" + _colors[lobby.color] + ".png"); playerCount++; } Runner::gameState._loadedScenes[GameState::SceneID::GameScene] = scene; Runner::gameState.nextScene = BBM::GameState::SceneID::GameScene; } }