diff --git a/CMakeLists.txt b/CMakeLists.txt index c0bf953..b5452e1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -49,6 +49,16 @@ else() target_compile_definitions(${EXECUTABLE_TARGET} PRIVATE NDEBUG) endif() +# Set C++17 standard +set_target_properties(${EXECUTABLE_TARGET} PROPERTIES + CXX_STANDARD 17 + CXX_EXTENSIONS OFF) +if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + set_target_properties(${EXECUTABLE_TARGET} PROPERTIES COMPILE_FLAGS "-std=c++17") +elseif(MSVC) + set_target_properties(${EXECUTABLE_TARGET} PROPERTIES COMPILE_FLAGS "/std:c++17") +endif() + # Set link flags to show console window on debug builds and hide it on release builds if(MSVC) set_target_properties(${EXECUTABLE_TARGET} PROPERTIES LINK_FLAGS_DEBUG "/SUBSYSTEM:CONSOLE") diff --git a/src/game.cpp b/src/game.cpp index f5cd813..d8b2760 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -18,7 +18,7 @@ */ #include "game.hpp" -#include "resources/csv-table.hpp" +#include "resources/string-table.hpp" #include "states/game-state.hpp" #include "states/sandbox-state.hpp" #include "filesystem.hpp" @@ -500,6 +500,7 @@ void Game::setup() setupGameplay(); screenshotQueued = false; + paused = false; // Load model resources @@ -683,7 +684,11 @@ void Game::setup() }; // Initialize state machine - StateMachine::changeState(&titleState); + #if defined(DEBUG) + StateMachine::changeState(&titleState); + #else + StateMachine::changeState(&splashState); + #endif changeState(sandboxState); } @@ -808,7 +813,7 @@ void Game::setupLocalization() // Match language code with language index languageIndex = 0; - CSVRow* languageCodes = &(*stringTable)[1]; + StringTableRow* languageCodes = &(*stringTable)[1]; for (std::size_t i = 2; i < languageCodes->size(); ++i) { if (language == (*languageCodes)[i]) @@ -1016,13 +1021,13 @@ void Game::setupUI() loadFonts(); // Load splash screen texture - splashTexture = resourceManager->load("epigraph.png"); + splashTexture = resourceManager->load("splash.png"); // Load HUD texture hudSpriteSheetTexture = resourceManager->load("hud.png"); // Read texture atlas file - CSVTable* atlasTable = resourceManager->load("hud-atlas.csv"); + StringTable* atlasTable = resourceManager->load("hud-atlas.csv"); // Build texture atlas for (int row = 0; row < atlasTable->size(); ++row) @@ -1412,12 +1417,22 @@ void Game::setupUI() controlsMenuChangeToolItem = controlsMenu->addItem(); controlsMenuUseToolItem = controlsMenu->addItem(); controlsMenuAdjustCameraItem = controlsMenu->addItem(); + controlsMenuPauseItem = controlsMenu->addItem(); controlsMenuToggleFullscreenItem = controlsMenu->addItem(); controlsMenuTakeScreenshotItem = controlsMenu->addItem(); controlsMenuResetToDefaultItem = controlsMenu->addItem(); controlsMenuBackItem = controlsMenu->addItem(); + // Build pause menu + pauseMenu = new Menu(); + pauseMenuResumeItem = pauseMenu->addItem(); + pauseMenuSettingsItem = pauseMenu->addItem(); + pauseMenuMainMenuItem = pauseMenu->addItem(); + pauseMenuQuitItem = pauseMenu->addItem(); + // Setup main menu callbacks + mainMenuContinueItem->setActivatedCallback(std::bind(&Game::continueGame, this)); + mainMenuNewGameItem->setActivatedCallback(std::bind(&Game::newGame, this)); mainMenuSettingsItem->setActivatedCallback(std::bind(&Game::openMenu, this, settingsMenu, 0)); mainMenuQuitItem->setActivatedCallback(std::bind(&Application::close, this, EXIT_SUCCESS)); @@ -1437,11 +1452,18 @@ void Game::setupUI() controlsMenuChangeToolItem->setActivatedCallback(std::bind(&Game::remapControl, this, &changeToolControl)); controlsMenuUseToolItem->setActivatedCallback(std::bind(&Game::remapControl, this, &useToolControl)); controlsMenuAdjustCameraItem->setActivatedCallback(std::bind(&Game::remapControl, this, &adjustCameraControl)); + controlsMenuPauseItem->setActivatedCallback(std::bind(&Game::remapControl, this, &pauseControl)); controlsMenuToggleFullscreenItem->setActivatedCallback(std::bind(&Game::remapControl, this, &toggleFullscreenControl)); controlsMenuTakeScreenshotItem->setActivatedCallback(std::bind(&Game::remapControl, this, &takeScreenshotControl)); controlsMenuResetToDefaultItem->setActivatedCallback(std::bind(&Game::resetControls, this)); controlsMenuBackItem->setActivatedCallback(std::bind(&Game::openMenu, this, settingsMenu, 0)); + // Setup pause menu callbacks + pauseMenuResumeItem->setActivatedCallback(std::bind(&Game::togglePause, this)); + pauseMenuSettingsItem->setActivatedCallback(std::bind(&Game::openMenu, this, settingsMenu, 0)); + pauseMenuMainMenuItem->setActivatedCallback(std::bind(&Game::returnToMainMenu, this)); + pauseMenuQuitItem->setActivatedCallback(std::bind(&Application::close, this, EXIT_SUCCESS)); + // Setup standard callbacks for all menu items for (std::size_t i = 0; i < mainMenu->getItems()->size(); ++i) { @@ -1470,10 +1492,20 @@ void Game::setupUI() item->getContainer()->setMousePressedCallback(std::bind(&Game::activateMenuItem, this)); } + for (std::size_t i = 0; i < pauseMenu->getItems()->size(); ++i) + { + MenuItem* item = (*pauseMenu->getItems())[i]; + item->getContainer()->setTintColor(menuItemInactiveColor); + item->getContainer()->setMouseOverCallback(std::bind(&Game::selectMenuItem, this, i, true)); + item->getContainer()->setMouseMovedCallback(std::bind(&Game::selectMenuItem, this, i, true)); + item->getContainer()->setMousePressedCallback(std::bind(&Game::activateMenuItem, this)); + } + // Set fonts for all menus mainMenu->setFonts(menuFont); settingsMenu->setFonts(menuFont); controlsMenu->setFonts(menuFont); + pauseMenu->setFonts(menuFont); AnimationChannel* channel; @@ -1542,6 +1574,11 @@ void Game::setupUI() channel->insertKeyframe(0.0f, 0.0f); channel->insertKeyframe(3.0f, 0.0f); channel->insertKeyframe(5.0f, 1.0f); + menuFadeOutClip.setInterpolator(easeOutCubic); + channel = menuFadeOutClip.addChannel(0); + channel->insertKeyframe(0.0f, 1.0f); + channel->insertKeyframe(0.125f, 0.0f); + menuFadeAnimation.setClip(&menuFadeInClip); menuFadeAnimation.setTimeFrame(menuFadeInClip.getTimeFrame()); menuFadeAnimation.setAnimateCallback @@ -1552,6 +1589,8 @@ void Game::setupUI() } ); + animator.addAnimation(&menuFadeAnimation); + // Menu selector animation menuSelectorSlideClip.setInterpolator(easeOutCubic); menuSelectorSlideAnimation.setClip(&menuSelectorSlideClip); @@ -1728,6 +1767,7 @@ void Game::setupControls() controls.addControl(&orbitCWControl); controls.addControl(&adjustCameraControl); controls.addControl(&dragCameraControl); + controls.addControl(&pauseControl); controls.addControl(&changeToolControl); controls.addControl(&useToolControl); controls.addControl(&toggleEditModeControl); @@ -1757,6 +1797,7 @@ void Game::setupControls() cameraControls.addControl(&orbitCWControl); cameraControls.addControl(&adjustCameraControl); cameraControls.addControl(&dragCameraControl); + cameraControls.addControl(&pauseControl); // Build the tool control set toolControls.addControl(&changeToolControl); @@ -1770,6 +1811,7 @@ void Game::setupControls() menuUpControl.setActivatedCallback(std::bind(&Game::selectPreviousMenuItem, this)); menuActivateControl.setActivatedCallback(std::bind(&Game::activateMenuItem, this)); menuBackControl.setActivatedCallback(std::bind(&Game::activateLastMenuItem, this)); + pauseControl.setActivatedCallback(std::bind(&Game::togglePause, this)); exitControl.setActivatedCallback(std::bind(&Application::close, this, EXIT_SUCCESS)); toggleFullscreenControl.setActivatedCallback(std::bind(&Game::toggleFullscreen, this)); takeScreenshotControl.setActivatedCallback(std::bind(&Game::queueScreenshot, this)); @@ -1795,6 +1837,7 @@ void Game::setupControls() controlNameMap["orbit-cw"] = &orbitCWControl; controlNameMap["adjust-camera"] = &adjustCameraControl; controlNameMap["drag-camera"] = &dragCameraControl; + controlNameMap["pause"] = &pauseControl; controlNameMap["change-tool"] = &changeToolControl; controlNameMap["use-tool"] = &useToolControl; controlNameMap["toggle-edit-mode"] = &toggleEditModeControl; @@ -1828,11 +1871,11 @@ void Game::setupGameplay() timestep = stepScheduler.getStepPeriod(); // Setup camera rigs - cameraRig = nullptr; orbitCam = new OrbitCam(); orbitCam->attachCamera(&camera); freeCam = new FreeCam(); freeCam->attachCamera(&camera); + cameraRig = orbitCam; } void Game::resetSettings() @@ -1869,22 +1912,19 @@ void Game::loadSettings() resetSettings(); // Load settings table - /* try { - settingsTable = resourceManager->load("settings.csv"); + settingsTable = resourceManager->load("settings.csv"); } catch (const std::exception& e) { - settingsTable = new CSVTable(); + settingsTable = new StringTable(); } - */ - settingsTable = new CSVTable(); // Build settings map for (std::size_t i = 0; i < settingsTable->size(); ++i) { - const CSVRow& row = (*settingsTable)[i]; + const StringTableRow& row = (*settingsTable)[i]; settingsMap[row[0]] = i; } @@ -1899,12 +1939,13 @@ void Game::loadSettings() } void Game::saveSettings() -{} +{ +} void Game::loadStrings() { // Read strings file - stringTable = resourceManager->load("strings.csv"); + stringTable = resourceManager->load("strings.csv"); // Build string map for (int row = 0; row < stringTable->size(); ++row) @@ -1943,7 +1984,7 @@ void Game::loadFonts() // Build character set for all strings in current language std::set characterSet; - for (const CSVRow& row: *stringTable) + for (const StringTableRow& row: *stringTable) { // Convert to UTF-8 string to UTF-32 std::u32string string = toUTF32(row[languageIndex + 2]); @@ -1963,9 +2004,9 @@ void Game::loadControlProfile(const std::string& profileName) { // Load control profile std::string controlProfilePath = profileName + ".csv"; - CSVTable* controlProfile = resourceManager->load(controlProfilePath); + StringTable* controlProfile = resourceManager->load(controlProfilePath); - for (const CSVRow& row: *controlProfile) + for (const StringTableRow& row: *controlProfile) { // Skip empty rows and comments if (row.empty() || row[0].empty() || row[0][0] == '#') @@ -2142,8 +2183,8 @@ void Game::loadControlProfile(const std::string& profileName) void Game::saveControlProfile(const std::string& profileName) { - // Build control profile CSV table - CSVTable* table = new CSVTable(); + // Build control profile string table + StringTable* table = new StringTable(); for (auto it = controlNameMap.begin(); it != controlNameMap.end(); ++it) { // Get control name @@ -2163,8 +2204,8 @@ void Game::saveControlProfile(const std::string& profileName) for (const InputMapping* mapping: *mappings) { // Add row to the table - table->push_back(CSVRow()); - CSVRow* row = &table->back(); + table->push_back(StringTableRow()); + StringTableRow* row = &table->back(); // Add control name column row->push_back(controlName); @@ -2304,9 +2345,9 @@ void Game::saveControlProfile(const std::string& profileName) std::string controlProfilePath = controlsPath + profileName + ".csv"; // Save control profile - resourceManager->save(table, controlProfilePath); + resourceManager->save(table, controlProfilePath); - // Free control profile CSV table + // Free control profile string table delete table; } @@ -2738,6 +2779,25 @@ void Game::resizeUI(int w, int h) controlsMenu->getContainer()->setAnchor(Anchor::BOTTOM_RIGHT); controlsMenu->resize(controlsMenuWidth, controlsMenuHeight); controlsMenu->getContainer()->setTranslation(Vector2(-controlsMenuPadding)); + + // Pause menu size + float pauseMenuWidth = 0.0f; + float pauseMenuHeight = 0.0f; + float pauseMenuSpacing = 0.5f * fontSizePX; + float pauseMenuPadding = fontSizePX * 4.0f; + + for (const MenuItem* item: *pauseMenu->getItems()) + { + + pauseMenuHeight += item->getNameLabel()->getFont()->getMetrics().getHeight(); + pauseMenuHeight += pauseMenuSpacing; + pauseMenuWidth = std::max(pauseMenuWidth, item->getNameLabel()->getDimensions().x); + } + pauseMenuHeight -= pauseMenuSpacing; + pauseMenu->getContainer()->setAnchor(Anchor::BOTTOM_RIGHT); + pauseMenu->resize(pauseMenuWidth, pauseMenuHeight); + pauseMenu->getContainer()->setTranslation(Vector2(-pauseMenuPadding)); + } void Game::restringUI() @@ -2746,6 +2806,7 @@ void Game::restringUI() mainMenu->setFonts(menuFont); settingsMenu->setFonts(menuFont); controlsMenu->setFonts(menuFont); + pauseMenu->setFonts(menuFont); // Get common strings std::string offString = getString("off"); @@ -2778,16 +2839,24 @@ void Game::restringUI() restringControlMenuItem(controlsMenuChangeToolItem, "change-tool"); restringControlMenuItem(controlsMenuUseToolItem, "use-tool"); restringControlMenuItem(controlsMenuAdjustCameraItem, "adjust-camera"); + restringControlMenuItem(controlsMenuPauseItem, "pause"); restringControlMenuItem(controlsMenuToggleFullscreenItem, "toggle-fullscreen"); restringControlMenuItem(controlsMenuTakeScreenshotItem, "take-screenshot"); controlsMenuResetToDefaultItem->setName(getString("reset-to-default")); controlsMenuBackItem->setName(backString); + // Pause menu strings + pauseMenuResumeItem->setName(getString("resume")); + pauseMenuSettingsItem->setName(getString("settings")); + pauseMenuMainMenuItem->setName(getString("main-menu")); + pauseMenuQuitItem->setName(getString("quit")); + // Reset menu tweens uiRootElement->update(); mainMenu->getContainer()->resetTweens(); settingsMenu->getContainer()->resetTweens(); controlsMenu->getContainer()->resetTweens(); + pauseMenu->getContainer()->resetTweens(); } void Game::restringControlMenuItem(MenuItem* item, const std::string& name) @@ -3030,9 +3099,18 @@ void Game::enterTitleState() antHillZoomAnimation.rewind(); antHillZoomAnimation.play(); - animator.addAnimation(&menuFadeAnimation); menuFadeAnimation.rewind(); menuFadeAnimation.play(); + menuFadeAnimation.setEndCallback(nullptr); + + // Disable play controls + cameraControls.setCallbacksEnabled(false); + + // Enable menu controls + menuControls.setCallbacksEnabled(true); + + // Change setting menu's back item to return to the main menu + settingsMenuBackItem->setActivatedCallback(std::bind(&Game::openMenu, this, mainMenu, 3)); // Open the main menu and select the first menu item openMenu(mainMenu, 0); @@ -3041,14 +3119,26 @@ void Game::enterTitleState() void Game::exitTitleState() { animator.removeAnimation(&antHillZoomAnimation); - animator.removeAnimation(&menuFadeAnimation); } void Game::enterPlayState() -{} +{ + // Disable menu controls + menuControls.setCallbacksEnabled(false); + + // Disable UI callbacks + uiRootElement->setCallbacksEnabled(false); + + // Enable play controls + cameraControls.setCallbacksEnabled(true); + + // Change setting menu's back item to return to the pause menu + settingsMenuBackItem->setActivatedCallback(std::bind(&Game::openMenu, this, pauseMenu, 1)); +} void Game::exitPlayState() -{} +{ +} void Game::skipSplash() { @@ -3058,6 +3148,92 @@ void Game::skipSplash() } } +void Game::togglePause() +{ + paused = !paused; + + if (paused) + { + openMenu(pauseMenu, 0); + + // Enable menu controls and UI callbacks + uiRootElement->setCallbacksEnabled(true); + menuControls.setCallbacksEnabled(true); + } + else + { + closeCurrentMenu(); + + // Disable menu controls and UI callbacks + uiRootElement->setCallbacksEnabled(false); + menuControls.setCallbacksEnabled(false); + } +} + +void Game::continueGame() +{ + // Disable play controls, menu controls, and UI callbacks + cameraControls.setCallbacksEnabled(false); + menuControls.setCallbacksEnabled(false); + uiRootElement->setCallbacksEnabled(false); + + // Start fading out main menu + menuFadeAnimation.setClip(&menuFadeOutClip); + menuFadeAnimation.setTimeFrame(menuFadeOutClip.getTimeFrame()); + menuFadeAnimation.rewind(); + menuFadeAnimation.play(); + + // Close menu and enter play state after it fades out + menuFadeAnimation.setEndCallback + ( + [this]() + { + closeCurrentMenu(); + StateMachine::changeState(&playState); + } + ); +} + +void Game::newGame() +{ + // Disable play controls, menu controls, and UI callbacks + cameraControls.setCallbacksEnabled(false); + menuControls.setCallbacksEnabled(false); + uiRootElement->setCallbacksEnabled(false); + + // Start fading out main menu + menuFadeAnimation.setClip(&menuFadeOutClip); + menuFadeAnimation.setTimeFrame(menuFadeOutClip.getTimeFrame()); + menuFadeAnimation.rewind(); + menuFadeAnimation.play(); + + // Close menu and enter play state after it fades out + menuFadeAnimation.setEndCallback + ( + [this]() + { + closeCurrentMenu(); + } + ); + + // Start to play state + fadeOut(3.0f, Vector3(0.0f), std::bind(&StateMachine::changeState, this, &playState)); +} + +void Game::returnToMainMenu() +{ + // Disable play controls, menu controls, and UI callbacks + cameraControls.setCallbacksEnabled(false); + menuControls.setCallbacksEnabled(false); + uiRootElement->setCallbacksEnabled(false); + + // Close pause menu + closeCurrentMenu(); + + // Fade to title state + fadeOut(3.0f, Vector3(0.0f), std::bind(&StateMachine::changeState, this, &titleState)); +} + void Game::boxSelect(float x, float y, float w, float h) { boxSelectionContainer->setTranslation(Vector2(x, y)); diff --git a/src/game.hpp b/src/game.hpp index 202b90d..69acf98 100644 --- a/src/game.hpp +++ b/src/game.hpp @@ -71,7 +71,7 @@ class ComponentBase; class Menu; class MenuItem; enum class ComponentType; -typedef std::vector> CSVTable; +typedef std::vector> StringTable; class Game: public Application, @@ -144,6 +144,8 @@ public: void selectTool(int toolIndex); + + private: virtual void setup(); virtual void input(); @@ -198,6 +200,12 @@ private: void skipSplash(); + void togglePause(); + + void continueGame(); + void newGame(); + void returnToMainMenu(); + public: EntityID createInstance(); EntityID createInstanceOf(const std::string& templateName); @@ -231,11 +239,11 @@ public: std::string controlsPath; // Settings - CSVTable* settingsTable; + StringTable* settingsTable; std::map settingsMap; // Localization - CSVTable* stringTable; + StringTable* stringTable; std::map stringMap; std::size_t languageCount; std::size_t languageIndex; @@ -280,6 +288,7 @@ public: Control orbitCWControl; Control adjustCameraControl; Control dragCameraControl; + Control pauseControl; // Tool control set ControlSet toolControls; @@ -409,11 +418,19 @@ public: MenuItem* controlsMenuChangeToolItem; MenuItem* controlsMenuUseToolItem; MenuItem* controlsMenuAdjustCameraItem; + MenuItem* controlsMenuPauseItem; MenuItem* controlsMenuToggleFullscreenItem; MenuItem* controlsMenuTakeScreenshotItem; MenuItem* controlsMenuResetToDefaultItem; MenuItem* controlsMenuBackItem; + // Pause menu + Menu* pauseMenu; + MenuItem* pauseMenuResumeItem; + MenuItem* pauseMenuSettingsItem; + MenuItem* pauseMenuMainMenuItem; + MenuItem* pauseMenuQuitItem; + // Rendering Renderer renderer; RenderTarget defaultRenderTarget; @@ -451,6 +468,7 @@ public: Animation menuFadeAnimation; AnimationClip menuFadeInClip; + AnimationClip menuFadeOutClip; Animation splashFadeInAnimation; Animation splashFadeOutAnimation; @@ -508,6 +526,7 @@ public: TerrainSystem* terrainSystem; bool screenshotQueued; + bool paused; // Settings std::string language; diff --git a/src/resources/entity-template-loader.cpp b/src/resources/entity-template-loader.cpp index 6ff7b20..13fa56e 100644 --- a/src/resources/entity-template-loader.cpp +++ b/src/resources/entity-template-loader.cpp @@ -19,7 +19,7 @@ #include "resource-loader.hpp" #include "resource-manager.hpp" -#include "csv-table.hpp" +#include "string-table.hpp" #include "../entity/components/ant-hill-component.hpp" #include "../entity/components/collision-component.hpp" #include "../entity/components/model-component.hpp" @@ -176,8 +176,8 @@ EntityTemplate* ResourceLoader::load(ResourceManager* resourceMa std::list components; EntityTemplate* entityTemplate = nullptr; - // Load CSV table from input stream - CSVTable* table = ResourceLoader::load(resourceManager, is); + // Load string table from input stream + StringTable* table = ResourceLoader::load(resourceManager, is); // Ensure table is not empty. if (!table || table->empty()) @@ -187,7 +187,7 @@ EntityTemplate* ResourceLoader::load(ResourceManager* resourceMa } // Load components from table rows - for (const CSVRow& row: *table) + for (const StringTableRow& row: *table) { // Skip empty rows and comments if (row.empty() || row[0].empty() || row[0][0] == '#') diff --git a/src/resources/csv-table-loader.cpp b/src/resources/string-table-loader.cpp similarity index 83% rename from src/resources/csv-table-loader.cpp rename to src/resources/string-table-loader.cpp index 404119e..a74c5c0 100644 --- a/src/resources/csv-table-loader.cpp +++ b/src/resources/string-table-loader.cpp @@ -18,9 +18,9 @@ */ #include "resource-loader.hpp" -#include "csv-table.hpp" +#include "string-table.hpp" -static CSVRow parseRow(const std::string& line) +static StringTableRow parseRow(const std::string& line) { std::vector row; std::string column; @@ -92,9 +92,9 @@ static CSVRow parseRow(const std::string& line) } template <> -CSVTable* ResourceLoader::load(ResourceManager* resourceManager, std::istream* is) +StringTable* ResourceLoader::load(ResourceManager* resourceManager, std::istream* is) { - CSVTable* table = new CSVTable(); + StringTable* table = new StringTable(); std::string line; while (!is->eof()) @@ -112,15 +112,15 @@ CSVTable* ResourceLoader::load(ResourceManager* resourceManager, std:: } template <> -void ResourceLoader::save(ResourceManager* resourceManager, std::ostream* os, const CSVTable* table) +void ResourceLoader::save(ResourceManager* resourceManager, std::ostream* os, const StringTable* table) { for (std::size_t i = 0; i < table->size(); ++i) { - const CSVRow& row = (*table)[i]; + const StringTableRow& row = (*table)[i]; for (std::size_t j = 0; j < row.size(); ++j) { - const CSVEntry& column = row[j]; + const std::string& column = row[j]; (*os) << column; diff --git a/src/resources/csv-table.hpp b/src/resources/string-table.cpp similarity index 78% rename from src/resources/csv-table.hpp rename to src/resources/string-table.cpp index e041e03..dc98334 100644 --- a/src/resources/csv-table.hpp +++ b/src/resources/string-table.cpp @@ -17,15 +17,17 @@ * along with Antkeeper Source Code. If not, see . */ -#ifndef CSV_TABLE_HPP -#define CSV_TABLE_HPP +#include "string-table.hpp" -#include -#include +StringTableIndex createIndex(const StringTable& table) +{ + StringTableIndex index; -typedef std::string CSVEntry; -typedef std::vector CSVRow; -typedef std::vector CSVTable; - -#endif // CSV_TABLE_HPP + for (std::size_t i = 0; i < table.size(); ++i) + { + index[table[i][0]] = i; + } + + return index; +} diff --git a/src/resources/string-table.hpp b/src/resources/string-table.hpp new file mode 100644 index 0000000..9961151 --- /dev/null +++ b/src/resources/string-table.hpp @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2017-2019 Christopher J. Howard + * + * This file is part of Antkeeper Source Code. + * + * Antkeeper Source Code is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Antkeeper Source Code is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Antkeeper Source Code. If not, see . + */ + +#ifndef STRING_TABLE_HPP +#define STRING_TABLE_HPP + +#include +#include +#include + +typedef std::vector StringTableRow; +typedef std::vector StringTable; + +typedef std::map StringTableIndex; + +/** + * Creates an index for a string table using strings in the first column as keys. + * + * @param table Table for which an index will be created. + */ +StringTableIndex createIndex(const StringTable& table); + +#endif // STRING_TABLE_HPP + diff --git a/src/states/sandbox-state.cpp b/src/states/sandbox-state.cpp index 21b4f29..d2ae446 100644 --- a/src/states/sandbox-state.cpp +++ b/src/states/sandbox-state.cpp @@ -323,8 +323,8 @@ void SandboxState::handleEvent(const MouseMovedEvent& event) { Vector2 selectorDirection = selectorVector / std::sqrt(lengthSquared); - float angle = std::atan2(-selectorDirection.y, selectorDirection.x) + twoPi(); - float sectorAngle = twoPi() / 8.0f; + float angle = std::atan2(-selectorDirection.y, selectorDirection.x) + twoPi; + float sectorAngle = twoPi / 8.0f; int sector = static_cast((angle + sectorAngle * 0.5f) / sectorAngle); game->radialMenuSelectorImage->setRotation(static_cast(sector) * sectorAngle); game->radialMenuImage->setRotation(static_cast(sector) * sectorAngle);