mirror of
https://github.com/TwilitRealm/dusklight
synced 2026-06-02 01:30:00 -04:00
basic backend for tracking
This commit is contained in:
@@ -378,6 +378,7 @@ namespace dusk {
|
||||
}
|
||||
m_menuRandomizer.windowRandoStats();
|
||||
m_menuRandomizer.windowRandoGeneration();
|
||||
m_menuRandomizer.windowRandoTracker();
|
||||
|
||||
// Hide mouse cursor if the F1 menu is not open and the cursor is idle for 3 seconds.
|
||||
if (dusk::getSettings().game.gyroMode.getValue() != GyroMode::Mouse)
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <filesystem>
|
||||
|
||||
#include "dusk/data.hpp"
|
||||
#include "dusk/randomizer/generator/logic/search.hpp"
|
||||
|
||||
namespace dusk {
|
||||
|
||||
@@ -142,6 +143,8 @@ namespace dusk {
|
||||
}
|
||||
ImGui::Checkbox("Show Rando Stats", &m_showRandoStats);
|
||||
|
||||
ImGui::Checkbox("Show Rando Tracker", &m_showRandoTracker);
|
||||
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
}
|
||||
@@ -207,4 +210,84 @@ namespace dusk {
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
|
||||
void ImGuiMenuRandomizer::windowRandoTracker() {
|
||||
if (!m_showRandoTracker) {
|
||||
return;
|
||||
}
|
||||
|
||||
ImGuiWindowFlags windowFlags = ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_AlwaysAutoResize |
|
||||
ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoNav;
|
||||
|
||||
if (ImGui::Begin("Rando Tracker", nullptr, windowFlags)) {
|
||||
auto trackerRando = getTrackerRando();
|
||||
ImGui::Text("Here's where the tracker will be");
|
||||
|
||||
if (ImGui::Button("Update Tracker")) {
|
||||
auto trackerRando = getTrackerRando();
|
||||
|
||||
// Generate tracker world if it doesn't exist
|
||||
auto contextHash = randomizer_GetContext().mHash;
|
||||
auto trackerHash = trackerRando->GetConfig().GetHash(false);
|
||||
// If no hash, or seeds switched, try to create tracker world from currently active seed
|
||||
if (trackerHash.empty() || (trackerHash != contextHash && !contextHash.empty())) {
|
||||
*trackerRando = randomizer::Randomizer(data::configured_data_path());
|
||||
trackerRando->GenerateTrackerWorld();
|
||||
auto trackerWorld = trackerRando->GetWorlds()[0].get();
|
||||
auto currentItems = trackerWorld->GetStartingItemPool();
|
||||
|
||||
m_currentSearch = randomizer::logic::search::Search::Accessible(&trackerRando->GetWorlds(), currentItems);
|
||||
m_currentSearch.SearchWorlds();
|
||||
} else {
|
||||
// Don't try to update inventory when on the title screen
|
||||
if (!playerIsOnTitleScreen()) {
|
||||
// TODO: Translate game save inventory into ItemPool that can be used for searching
|
||||
randomizer::logic::item_pool::ItemPool currentItems = {};
|
||||
m_currentSearch = randomizer::logic::search::Search::Accessible(&trackerRando->GetWorlds(), currentItems);
|
||||
}
|
||||
|
||||
m_currentSearch.SearchWorlds();
|
||||
}
|
||||
}
|
||||
|
||||
if (trackerRando->GetConfig().GetHash(false).empty()) {
|
||||
ImGui::Text("There is currently no tracker world");
|
||||
} else {
|
||||
ImGui::Text("Tracker world loaded from seed %s", trackerRando->GetConfig().GetHash().c_str());
|
||||
|
||||
// Show total number of available locations
|
||||
auto locations = trackerRando->GetWorlds()[0]->GetAllLocations();
|
||||
auto numAvailableLocations = m_currentSearch._visitedLocations.size();
|
||||
ImGui::Text("Locations Available: %zu / %zu", numAvailableLocations, locations.size());
|
||||
|
||||
if (ImGui::BeginChild("ScrollRegion", ImVec2(500, 500), true))
|
||||
{
|
||||
// Show all locations. Green for accessible. Red for Unaccessible
|
||||
for (auto location : locations) {
|
||||
// Color red
|
||||
auto color = ImVec4(1.f, 0.f, 0.f, 1.f);
|
||||
|
||||
// If the search found this location, change color to green
|
||||
if (m_currentSearch._visitedLocations.contains(location)) {
|
||||
color = ImVec4(0.f, 1.f, 0.f, 1.f);
|
||||
}
|
||||
|
||||
ImGui::TextColored(color, "%s", location->GetName().c_str());
|
||||
|
||||
// Show requirements for the location below it (formatting isn't pretty right now)
|
||||
ImGui::Text(" %s", location->GetComputedRequirement().to_string().c_str());
|
||||
}
|
||||
}
|
||||
ImGui::EndChild();
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
randomizer::Randomizer* ImGuiMenuRandomizer::getTrackerRando() {
|
||||
static randomizer::Randomizer trackerRando{data::configured_data_path()};
|
||||
return &trackerRando;
|
||||
}
|
||||
|
||||
} // namespace dusk
|
||||
@@ -1,7 +1,14 @@
|
||||
|
||||
|
||||
#ifndef DUSK_IMGUI_MENU_RANDOMIZER_HPP
|
||||
#define DUSK_IMGUI_MENU_RANDOMIZER_HPP
|
||||
#include "dusk/randomizer/generator/logic/search.hpp"
|
||||
|
||||
namespace randomizer {
|
||||
class Randomizer;
|
||||
|
||||
namespace logic::search {
|
||||
class Search;
|
||||
}
|
||||
}
|
||||
|
||||
namespace dusk {
|
||||
class ImGuiMenuRandomizer {
|
||||
@@ -11,10 +18,16 @@ public:
|
||||
|
||||
void windowRandoStats();
|
||||
void windowRandoGeneration();
|
||||
void windowRandoTracker();
|
||||
|
||||
randomizer::Randomizer* getTrackerRando();
|
||||
|
||||
private:
|
||||
bool m_showRandoStats{false};
|
||||
bool m_showRandoGeneration{false};
|
||||
bool m_showRandoTracker{false};
|
||||
|
||||
randomizer::logic::search::Search m_currentSearch = randomizer::logic::search::Search();
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,10 @@
|
||||
|
||||
namespace randomizer::logic::search
|
||||
{
|
||||
Search::Search(): _searchMode(SearchMode::NO_SEARCH) {
|
||||
|
||||
}
|
||||
|
||||
Search::Search(const SearchMode& searchMode,
|
||||
world::WorldPool* worlds,
|
||||
const item_pool::ItemPool& items /* = {} */,
|
||||
|
||||
@@ -48,6 +48,7 @@ namespace randomizer::logic::search
|
||||
{
|
||||
enum class SearchMode
|
||||
{
|
||||
NO_SEARCH,
|
||||
ACCESSIBLE_LOCATIONS,
|
||||
GAME_BEATABLE,
|
||||
ALL_LOCATIONS_REACHABLE,
|
||||
@@ -59,6 +60,7 @@ namespace randomizer::logic::search
|
||||
class Search
|
||||
{
|
||||
public:
|
||||
Search();
|
||||
Search(const SearchMode& searchMode,
|
||||
world::WorldPool* worlds,
|
||||
const item_pool::ItemPool& items = {},
|
||||
|
||||
@@ -13,10 +13,9 @@
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "seedgen/seed.hpp"
|
||||
#include "SDL3/SDL_filesystem.h"
|
||||
#include "dusk/app_info.hpp"
|
||||
#include "dusk/data.hpp"
|
||||
#include "dusk/logging.h"
|
||||
#include "dusk/randomizer/game/randomizer_context.hpp"
|
||||
|
||||
namespace randomizer
|
||||
{
|
||||
@@ -36,6 +35,38 @@ namespace randomizer
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
void Randomizer::GenerateTrackerWorld() {
|
||||
auto contextHash = randomizer_GetContext().mHash;
|
||||
|
||||
if (contextHash.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::filesystem::path seedSettings = dusk::data::configured_data_path() / "randomizer" / "seeds" /
|
||||
contextHash / (contextHash + " Anti-Spoiler Log.txt");
|
||||
|
||||
this->_config.LoadFromFile(seedSettings, GetPrefPath());
|
||||
this->_config.SetHash(contextHash);
|
||||
|
||||
std::unique_ptr<logic::world::World> world = std::make_unique<logic::world::World>(1, this);
|
||||
world->SetSettings(this->_config.GetSettingsList().front());
|
||||
world->Build();
|
||||
this->_worlds.emplace_back(std::move(world));
|
||||
|
||||
auto trackerWorld = this->_worlds.at(0).get();
|
||||
trackerWorld->SetNonProgressLocations();
|
||||
trackerWorld->AssignAreaProperties();
|
||||
trackerWorld->AssignGoalLocations();
|
||||
|
||||
// Cache exit form times. This *must* run before conducting the flattening search, otherwise
|
||||
// the flattening search will pollute the exit timeform cache with a bunch of zeros
|
||||
logic::fill::CacheExitTimeForms(this->_worlds);
|
||||
|
||||
// Set raw requirements for each location
|
||||
FlattenSearch search = FlattenSearch(trackerWorld);
|
||||
search.doSearch();
|
||||
}
|
||||
|
||||
void Randomizer::GenerateWorlds()
|
||||
{
|
||||
utility::time::ScopedTimer<"Seed generation took ", std::chrono::milliseconds> timer;
|
||||
|
||||
@@ -19,6 +19,7 @@ namespace randomizer
|
||||
*/
|
||||
std::optional<std::string> Generate();
|
||||
void GenerateWorlds();
|
||||
void GenerateTrackerWorld();
|
||||
|
||||
auto& GetConfig() { return this->_config; }
|
||||
auto& GetWorlds() { return this->_worlds; }
|
||||
|
||||
@@ -320,9 +320,9 @@ namespace randomizer::seedgen::config
|
||||
WritePreferencesToFile(preferencesPath);
|
||||
}
|
||||
|
||||
std::string Config::GetHash()
|
||||
std::string Config::GetHash(bool generateIfEmpty)
|
||||
{
|
||||
if (this->_hash.empty())
|
||||
if (this->_hash.empty() && generateIfEmpty)
|
||||
{
|
||||
this->_hash = seed::GenerateHash();
|
||||
}
|
||||
|
||||
@@ -71,11 +71,13 @@ namespace randomizer::seedgen::config
|
||||
// std::string getPermalink(const bool& internal = false) const;
|
||||
|
||||
/**
|
||||
* @brief Returns the hash for the config. If the hash is an empty string, then a new one will be generated.
|
||||
* @brief Returns the hash for the config.
|
||||
* @param generateIfEmpty Generates a new hash if the current hash is empty
|
||||
*
|
||||
* @return The hash as a string
|
||||
*/
|
||||
std::string GetHash();
|
||||
std::string GetHash(bool generateIfEmpty = true);
|
||||
void SetHash(const std::string& newHash) { this->_hash = newHash; }
|
||||
|
||||
private:
|
||||
fspath _plandomizerPath;
|
||||
|
||||
Reference in New Issue
Block a user