#include "menu.h" #include "gui.h" #include #include #include #include #include #include #include #include // #include #include "../world/world.h" #include "../asset/asset.h" #include #include #include #include #include #include #include namespace { ext::Gui* mainText; ext::Gui* commandText; ext::Gui* transientSprite; ext::Gui* transientSpriteShadow; ext::Gui* circleIn; ext::Gui* circleOut; ext::Gui* coverBar; ext::Gui* tenkouseiOption; ext::Gui* closeOption; ext::Gui* quitOption; } namespace { void playSound( ext::GuiMenu& entity, const std::string& key ) { ext::Scene& world = entity.getRootParent(); uf::Serializer& metadata = entity.getComponent(); uf::Serializer& masterdata = world.getComponent(); std::string url = "./data/audio/ui/" + key + ".ogg"; ext::Asset& assetLoader = world.getComponent(); assetLoader.cache(url, "asset:Cache." + std::to_string(entity.getUid())); } ext::World* world; uf::Serializer masterTableGet( const std::string& table ) { if ( !world ) world = (ext::World*) uf::Entity::globalFindByName("World"); if ( !world ) return std::string(); uf::Serializer& mastertable = world->getComponent(); return mastertable["system"]["mastertable"][table]; } uf::Serializer masterDataGet( const std::string& table, const std::string& key ) { if ( !world ) world = (ext::World*) uf::Entity::globalFindByName("World"); if ( !world ) return std::string(); uf::Serializer& mastertable = world->getComponent(); return mastertable["system"]["mastertable"][table][key]; } inline int64_t parseInt( const std::string& str ) { return atoi(str.c_str()); } } void ext::GuiMenu::initialize() { ext::Gui::initialize(); ext::Scene& world = this->getRootParent(); uf::Serializer& masterdata = world.getComponent(); uf::Serializer& metadata = this->getComponent(); // asset loading this->addHook( "asset:Cache." + std::to_string(this->getUid()), [&](const std::string& event)->std::string{ uf::Serializer json = event; std::string filename = json["filename"].asString(); if ( uf::string::extension(filename) != "ogg" ) return "false"; if ( filename == "" ) return "false"; uf::Audio& sfx = this->getComponent(); if ( sfx.playing() ) sfx.stop(); sfx = uf::Audio(); sfx.load(filename); sfx.setVolume(masterdata["volumes"]["sfx"].asFloat()); sfx.play(); return "true"; }); // release control { uf::Serializer payload; payload["state"] = true; uf::hooks.call("window:Mouse.CursorVisibility", payload); uf::hooks.call("window:Mouse.Lock"); } // opened playSound(*this, "menu open"); /* Magic Circle Outter */ { circleOut = new ext::Gui; this->addChild(*circleOut); circleOut->load("./entities/gui/pause/circle-out.json"); circleOut->initialize(); } /* Magic Circle Inner */ { circleIn = new ext::Gui; this->addChild(*circleIn); circleIn->load("./entities/gui/pause/circle-in.json"); circleIn->initialize(); } /* set sprite order */ { metadata["portraits"]["i"] = 0; uf::Serializer& pMetadata = world.getController()->getComponent(); int i = 0; for ( auto& k : pMetadata[""]["party"] ) { std::string id = k.asString(); uf::Serializer member = pMetadata[""]["transients"][id]; uf::Serializer cardData = masterDataGet("Card", id); std::string name = cardData["filename"].asString(); if ( member["skin"].isString() ) name += "_" + member["skin"].asString(); std::string filename = "https://cdn..xyz//unity/Android/fg/fg_" + name + ".png"; if ( cardData["internal"].asBool() ) { filename = "./data/smtsamo/fg/fg_" + name + ".png"; } metadata["portraits"]["list"][i++] = filename; } } { std::string portrait = metadata["portraits"]["list"][0].asString(); /* Transient shadow background */ { transientSpriteShadow = new ext::Gui; ext::Asset& assetLoader = transientSpriteShadow->getComponent(); this->addChild(*transientSpriteShadow); uf::Serializer& pMetadata = transientSpriteShadow->getComponent(); pMetadata["system"]["assets"][0] = portrait; transientSpriteShadow->load("./entities/gui/pause/transient-shadow.json"); transientSpriteShadow->initialize(); } /* Transient transientSprite */ { transientSprite = new ext::Gui; ext::Asset& assetLoader = transientSprite->getComponent(); this->addChild(*transientSprite); uf::Serializer& pMetadata = transientSprite->getComponent(); pMetadata["system"]["assets"][0] = portrait; transientSprite->load("./entities/gui/pause/transient-portrait.json"); transientSprite->initialize(); } } /* Main Text (the one that scrolls) */ { mainText = new ext::Gui; this->addChild(*mainText); mainText->load("./entities/gui/pause/main-text.json"); mainText->initialize(); } /* Command text */ { commandText = new ext::Gui; this->addChild(*commandText); commandText->load("./entities/gui/pause/command-text.json"); commandText->initialize(); } /* Cover bar */ { coverBar = new ext::Gui; this->addChild(*coverBar); coverBar->load("./entities/gui/pause/yellow-box.json"); coverBar->initialize(); } /* Option 1 */ { tenkouseiOption = new ext::Gui; this->addChild(*tenkouseiOption); tenkouseiOption->load("./entities/gui/pause/tenkousei.json"); tenkouseiOption->initialize(); } /* Option 2 */ { closeOption = new ext::Gui; this->addChild(*closeOption); closeOption->load("./entities/gui/pause/close.json"); closeOption->initialize(); } /* Option 3 */ { quitOption = new ext::Gui; this->addChild(*quitOption); quitOption->load("./entities/gui/pause/quit.json"); quitOption->initialize(); } this->addHook("menu:Close.%UID%", [&]( const std::string& event ) -> std::string { /* // kill this->getParent().removeChild(*this); this->destroy(); delete this; return "true"; */ metadata["system"]["closing"] = true; return "true"; }); } void ext::GuiMenu::tick() { ext::Gui::tick(); ext::Scene& world = this->getRootParent(); uf::Serializer& masterdata = world.getComponent(); static uf::Timer timer(false); static uf::Audio sfx; if ( !timer.running() ) timer.start(); static float alpha = 0.0f; { uf::Serializer& metadata = this->getComponent(); /* if ( uf::Window::isKeyPressed("Escape") && !metadata["system"]["closing"].asBool() ) { metadata["system"]["closing"] = true; playSound(*this, "menu close"); } */ if ( metadata["system"]["closing"].asBool() ) { if ( alpha <= 0.0f ) { alpha = 0.0f; metadata["system"]["closing"] = false; metadata["system"]["closed"] = true; } else alpha -= uf::physics::time::delta; metadata["color"][3] = alpha; } else if ( metadata["system"]["closed"].asBool() ) { // kill this->getParent().removeChild(*this); this->destroy(); delete this; return; } else { if ( !metadata["initialized"].asBool() ) alpha = 0.0f; metadata["initialized"] = true; if ( alpha >= 1.0f ) alpha = 1.0f; else alpha += uf::physics::time::delta * 1.5f; metadata["color"][3] = alpha; } } if ( mainText ) { pod::Transform<>& transform = mainText->getComponent>(); uf::Serializer& metadata = mainText->getComponent(); float speed = 0.5f; if ( metadata["hovered"].asBool() ) speed = 0.75f; transform.position.y += uf::physics::time::delta * speed; if ( transform.position.y > 2 ) transform.position.y = -2; transform.orientation = uf::quaternion::axisAngle( { 0.0f, 0.0f, 1.0f }, -1.5707963f ); if ( alpha < 0.6f ) metadata["color"][3] = alpha; } if ( circleIn ) { pod::Transform<>& transform = circleIn->getComponent>(); static float time = 0.0f; float speed = 0.0125f; uf::Serializer& metadata = circleIn->getComponent(); if ( metadata["hovered"].asBool() ) speed = 0.25f; time += uf::physics::time::delta * -speed; transform.orientation = uf::quaternion::axisAngle( { 0.0f, 0.0f, 1.0f }, time ); static pod::Vector3f start = { transform.position.x, -2.0f, 0.0f }; static pod::Vector3f end = transform.position; static float delta = 0.0f; if ( !metadata["initialized"].asBool() ) delta = 0.0f; metadata["initialized"] = true; if ( delta >= 1 ) delta = 1; else { delta += uf::physics::time::delta * 1.5f; transform.position = uf::vector::lerp( start, end, delta ); } metadata["color"][3] = alpha; } if ( circleOut ) { pod::Transform<>& transform = circleOut->getComponent>(); uf::Serializer& metadata = circleOut->getComponent(); static float time = 0.0f; float speed = 0.0125f; if ( metadata["hovered"].asBool() ) speed = 0.25f; time += uf::physics::time::delta * speed; transform.orientation = uf::quaternion::axisAngle( { 0.0f, 0.0f, 1.0f }, time ); static pod::Vector3f start = { transform.position.x, 2.0f, 0.0f }; static pod::Vector3f end = transform.position; static float delta = 0.0f; if ( !metadata["initialized"].asBool() ) delta = 0.0f; metadata["initialized"] = true; if ( delta >= 1 ) delta = 1; else { delta += uf::physics::time::delta * 1.5f; transform.position = uf::vector::lerp( start, end, delta ); } metadata["color"][3] = alpha; } if ( coverBar ) { pod::Transform<>& transform = coverBar->getComponent>(); static pod::Vector3f start = { -1.5f, transform.position.y, 0.0f }; static pod::Vector3f end = transform.position; static float delta = 0.0f; uf::Serializer& metadata = coverBar->getComponent(); if ( !metadata["initialized"].asBool() ) delta = 0.0f; metadata["initialized"] = true; if ( delta >= 1 ) delta = 1; else { delta += uf::physics::time::delta * 1.5f; transform.position = uf::vector::lerp( start, end, delta ); } metadata["color"][3] = alpha; } if ( transientSprite ) { pod::Transform<>& transform = transientSprite->getComponent>(); static pod::Vector3f start = { 2.0f, transform.position.y, 0.0f }; static pod::Vector3f end = transform.position; static float delta = 0.0f; uf::Serializer& metadata = transientSprite->getComponent(); if ( !metadata["initialized"].asBool() ) delta = 0.0f; metadata["initialized"] = true; if ( delta >= 1 ) delta = 1; else { delta += uf::physics::time::delta * 1.5f; transform.position = uf::vector::lerp( start, end, delta ); } metadata["color"][3] = alpha; // cycle transients if ( metadata["clicked"].asBool() && timer.elapsed().asDouble() >= 1 ) { timer.reset(); playSound(*this, "menu flip"); uf::Serializer& master = this->getComponent(); int index = master["portraits"]["i"].asInt() + 1; if ( index >= master["portraits"]["list"].size() ) index = 0; master["portraits"]["i"] = index; std::string filename = master["portraits"]["list"][index].asString(); { std::string portrait = master["portraits"]["list"][index].asString(); /* Transient shadow background */ if ( transientSpriteShadow ) { transientSpriteShadow->destroy(); this->removeChild(*transientSpriteShadow); delete transientSpriteShadow; transientSpriteShadow = new ext::Gui; ext::Asset& assetLoader = transientSpriteShadow->getComponent(); this->addChild(*transientSpriteShadow); uf::Serializer& pMetadata = transientSpriteShadow->getComponent(); pMetadata["system"]["assets"][0] = portrait; transientSpriteShadow->load("./entities/gui/pause/transient-shadow.json"); transientSpriteShadow->initialize(); } /* Transient transientSprite */ if ( transientSprite ) { transientSprite->destroy(); this->removeChild(*transientSprite); delete transientSprite; transientSprite = new ext::Gui; ext::Asset& assetLoader = transientSprite->getComponent(); this->addChild(*transientSprite); uf::Serializer& pMetadata = transientSprite->getComponent(); pMetadata["system"]["assets"][0] = portrait; transientSprite->load("./entities/gui/pause/transient-portrait.json"); transientSprite->initialize(); } } if ( mainText ) { pod::Transform cTransform = mainText->getComponent>(); mainText->destroy(); this->removeChild(*mainText); delete mainText; mainText = new ext::Gui; this->addChild(*mainText); mainText->load("./entities/gui/pause/main-text.json"); mainText->getComponent>() = cTransform; mainText->initialize(); } } } if ( transientSpriteShadow ) { pod::Transform<>& transform = transientSpriteShadow->getComponent>(); static pod::Vector3f start = { 2.0f, transform.position.y, 0.0f }; static pod::Vector3f end = transform.position; static float delta = 0.0f; uf::Serializer& metadata = transientSpriteShadow->getComponent(); if ( !metadata["initialized"].asBool() ) delta = 0.0f; metadata["initialized"] = true; if ( delta >= 1 ) delta = 1; else { delta += uf::physics::time::delta * 1.5f; transform.position = uf::vector::lerp( start, end, delta ); } metadata["color"][3] = alpha; } if ( commandText ) { pod::Transform<>& transform = commandText->getComponent>(); static pod::Vector3f start = { -1.5f, transform.position.y, 0.0f }; static pod::Vector3f end = transform.position; static float delta = 0.0f; uf::Serializer& metadata = commandText->getComponent(); if ( !metadata["initialized"].asBool() ) delta = 0.0f; metadata["initialized"] = true; if ( delta >= 1 ) delta = 1; else { delta += uf::physics::time::delta * 1.5f; transform.position = uf::vector::lerp( start, end, delta ); } metadata["color"][3] = alpha; for ( uf::Entity* pointer : commandText->getChildren() ) { uf::Serializer& cMetadata = pointer->getComponent(); // std::cout << pointer->getName() << ": " << cMetadata["text settings"]["color"] << std::endl; cMetadata["text settings"]["color"][3] = alpha; } } if ( tenkouseiOption ) { pod::Transform<>& transform = tenkouseiOption->getComponent>(); static pod::Vector3f start = { -1.5f, transform.position.y, 0.0f }; static pod::Vector3f end = transform.position; static float delta = 0.0f; uf::Serializer& metadata = tenkouseiOption->getComponent(); if ( !metadata["initialized"].asBool() ) delta = 0.0f; metadata["initialized"] = true; if ( delta >= 1 ) delta = 1; else { delta += uf::physics::time::delta * 1.5f; transform.position = uf::vector::lerp( start, end, delta ); } if ( metadata["clicked"].asBool() && timer.elapsed().asDouble() >= 1 ) { timer.reset(); playSound(*this, "invalid select"); } metadata["color"][3] = alpha; for ( uf::Entity* pointer : tenkouseiOption->getChildren() ) { uf::Serializer& cMetadata = pointer->getComponent(); cMetadata["text settings"]["color"][3] = alpha; if ( metadata["hovered"].asBool() ) { cMetadata["color"][0] = 0; cMetadata["color"][1] = 0; cMetadata["color"][2] = 0; } else { cMetadata["color"][0] = 1; cMetadata["color"][1] = 1; cMetadata["color"][2] = 1; } } } if ( closeOption ) { pod::Transform<>& transform = closeOption->getComponent>(); static pod::Vector3f start = { -1.5f, transform.position.y, 0.0f }; static pod::Vector3f end = transform.position; static float delta = 0.0f; uf::Serializer& metadata = closeOption->getComponent(); if ( !metadata["initialized"].asBool() ) delta = 0.0f; metadata["initialized"] = true; if ( delta >= 1 ) delta = 1; else { delta += uf::physics::time::delta * 1.5f; transform.position = uf::vector::lerp( start, end, delta ); } if ( metadata["clicked"].asBool() && timer.elapsed().asDouble() >= 1 ) { timer.reset(); this->callHook("menu:Close.%UID%"); playSound(*this, "menu close"); } metadata["color"][3] = alpha; for ( uf::Entity* pointer : closeOption->getChildren() ) { uf::Serializer& cMetadata = pointer->getComponent(); cMetadata["text settings"]["color"][3] = alpha; if ( metadata["hovered"].asBool() ) { cMetadata["color"][0] = 0; cMetadata["color"][1] = 0; cMetadata["color"][2] = 0; } else { cMetadata["color"][0] = 1; cMetadata["color"][1] = 1; cMetadata["color"][2] = 1; } } } if ( quitOption ) { pod::Transform<>& transform = quitOption->getComponent>(); static pod::Vector3f start = { -1.5f, transform.position.y, 0.0f }; static pod::Vector3f end = transform.position; static float delta = 0.0f; uf::Serializer& metadata = quitOption->getComponent(); if ( !metadata["initialized"].asBool() ) delta = 0.0f; metadata["initialized"] = true; if ( delta >= 1 ) delta = 1; else { delta += uf::physics::time::delta * 1.5f; transform.position = uf::vector::lerp( start, end, delta ); } if ( metadata["clicked"].asBool() && timer.elapsed().asDouble() >= 1 ) { timer.reset(); this->callHook("menu:Close.%UID%"); playSound(*this, "menu close"); /* ext::Scene& world = this->getRootParent(); world.queueHook("system:Quit.%UID%", "", 1.0f); */ } metadata["color"][3] = alpha; for ( uf::Entity* pointer : quitOption->getChildren() ) { uf::Serializer& cMetadata = pointer->getComponent(); cMetadata["text settings"]["color"][3] = alpha; if ( metadata["hovered"].asBool() ) { cMetadata["color"][0] = 0; cMetadata["color"][1] = 0; cMetadata["color"][2] = 0; } else { cMetadata["color"][0] = 1; cMetadata["color"][1] = 1; cMetadata["color"][2] = 1; } } } // Close menu if ( uf::Window::isKeyPressed("Escape") && timer.elapsed().asDouble() >= 1 ) { timer.reset(); this->callHook("menu:Close.%UID%"); } /* if ( uf::Window::isKeyPressed("O") && uf::Window::isKeyPressed("J") ) { transform.scale.x += uf::physics::time::delta * -0.5f; std::cout << "Scale: " << transform.scale.x << ", " << transform.scale.y << std::endl; } if ( uf::Window::isKeyPressed("O") && uf::Window::isKeyPressed("L") ) { transform.scale.x += uf::physics::time::delta * 0.5f; std::cout << "Scale: " << transform.scale.x << ", " << transform.scale.y << std::endl; } if ( uf::Window::isKeyPressed("O") && uf::Window::isKeyPressed("I") ) { transform.scale.y += uf::physics::time::delta * -0.5f; std::cout << "Scale: " << transform.scale.x << ", " << transform.scale.y << std::endl; } if ( uf::Window::isKeyPressed("O") && uf::Window::isKeyPressed("K") ) { transform.scale.y += uf::physics::time::delta * 0.5f; std::cout << "Scale: " << transform.scale.x << ", " << transform.scale.y << std::endl; } if ( uf::Window::isKeyPressed("J") ) { transform.position.x += uf::physics::time::delta * -0.5f; std::cout << "Position: " << transform.position.x << ", " << transform.position.y << std::endl; } if ( uf::Window::isKeyPressed("L") ) { transform.position.x += uf::physics::time::delta * 0.5f; std::cout << "Position: " << transform.position.x << ", " << transform.position.y << std::endl; } if ( uf::Window::isKeyPressed("I") ) { transform.position.y += uf::physics::time::delta * -0.5f; std::cout << "Position: " << transform.position.x << ", " << transform.position.y << std::endl; } if ( uf::Window::isKeyPressed("K") ) { transform.position.y += uf::physics::time::delta * 0.5f; std::cout << "Position: " << transform.position.x << ", " << transform.position.y << std::endl; } */ } void ext::GuiMenu::render() { ext::Gui::render(); } void ext::GuiMenu::destroy() { uf::Serializer& metadata = this->getComponent(); /* Play sound effect */ if ( !metadata["system"]["closed"].asBool() ) { ext::Scene& world = this->getRootParent(); ext::Asset& assetLoader = world.getComponent(); std::string canonical = assetLoader.load("./data/audio/ui/menu close.ogg"); uf::Audio& sfx = assetLoader.get(canonical); uf::Serializer& masterdata = world.getComponent(); sfx.setVolume(masterdata["volumes"]["sfx"].asFloat()); sfx.play(); } ext::Gui::destroy(); }