diff --git a/CMakeLists.txt b/CMakeLists.txt index 235d271597a8f580f9abbf5d07a98e8439ca7124..a4d8044499cc44dc13a6d31a7b8e896efd83b633 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -78,6 +78,8 @@ add_executable(advanced_wars ${ADVANCED_WARS_SOURCES}) set(CMAKE_MODULE_PATH ${ADVANCED_WARS_SOURCE_DIR}/cmake/ ${CMAKE_MODULE_PATH}) +find_package(Qt6 REQUIRED COMPONENTS Widgets) + # Plattform-spezifische Konfiguration if(APPLE) # SDL2 Frameworks für macOS @@ -96,6 +98,7 @@ if(APPLE) ${SDL2_PATH}/SDL2.framework/SDL2 ${SDL2_PATH}/SDL2_image.framework/SDL2_image ${SDL2_PATH}/SDL2_ttf.framework/SDL2_ttf + Qt6::Core Boost::graph box2d ) @@ -127,6 +130,7 @@ else() target_link_libraries(advanced_wars ${HDF5_LIBRARIES} + Qt6::Core -lSDL2 -lSDL2_image -lSDL2_ttf @@ -138,7 +142,6 @@ endif() # leveleditor # Find Qt -find_package(Qt6 REQUIRED COMPONENTS Widgets) file(GLOB_RECURSE LEVELEDITOR_SOURCES "${PROJECT_SOURCE_DIR}/src/editor/*.cpp" diff --git a/src/game/level/Level.cpp b/src/game/level/Level.cpp index 70661db684645584787a1de9b6edbcf4ec24a22f..0527b9374367217627ae511e1ccb2efa46bb3093 100644 --- a/src/game/level/Level.cpp +++ b/src/game/level/Level.cpp @@ -82,22 +82,22 @@ std::shared_ptr<Level> Level::loadLevel(const std::string& path, Engine& engine) // if level is smaler than 20x20 surround with water tiles if (width < 20 || height < 20) { - int w_start = (20 - width) / 2; - int h_start = (20 - height) / 2; + int x_start = (20 - width) / 2; + int y_start = (20 - height) / 2; std::vector<uint8_t> transformed_tiles_array; transformed_tiles_array.reserve(20 * 20); for (int y = 0; y < 20; y++) { for (int x = 0; x < 20; x++) { - if (x < w_start || y < h_start || x >= w_start + width || y >= h_start + height) + if (x < x_start || y < y_start || x >= x_start + width || y >= y_start + height) { transformed_tiles_array.push_back(1); } else { transformed_tiles_array.push_back( - level_tilesarray[x - w_start + (y - h_start) * width]); + level_tilesarray[x - x_start + (y - y_start) * width]); } } } @@ -112,31 +112,31 @@ std::shared_ptr<Level> Level::loadLevel(const std::string& path, Engine& engine) std::vector<Unit> units; tiles.reserve(width * height); bool has_factions[] = {false, false, false, false, false}; - for (int i = 0; i < level_tilesarray.size(); i++) + for (size_t i = 0; i < level_tilesarray.size(); i++) { int x = i % width; int y = i / width; if (level_tilesarray[i] >= 50) { + // tile id >= 50 -> building -> have to add Plain Tile and Building tiles.push_back(Tile(TileId(TileId::PLAIN), x, y)); BuildingId building_id = static_cast<BuildingId>((level_tilesarray[i] - 50) % 5); BuildingFaction faction_id = static_cast<BuildingFaction>((level_tilesarray[i] - 50) / 5); if (building_id == BuildingId::HEADQUARTER) { - int index = static_cast<int>(faction_id); - if (!has_factions[index]) - { - units.push_back(Unit( - x, y, static_cast<UnitFaction>(faction_id), UnitId::INFANTERY, - UnitState::UNAVAILABLE, engine.getUnitConfig())); - } - has_factions[static_cast<int>(faction_id)] = true; + // an infantery unit should be added onto every HQ + units.push_back(Unit( + x, y, static_cast<UnitFaction>(faction_id), UnitId::INFANTERY, + UnitState::UNAVAILABLE, engine.getUnitConfig())); + has_factions[static_cast<int>(faction_id)] = true; // collect existing factions + // for later building turnQ } buildings.push_back(Building(x, y, building_id, faction_id)); } else { + // if tile id belongs to terrain tile, just a tile needs to added TileId tile_id = static_cast<TileId>(level_tilesarray[i]); tiles.push_back(Tile(tile_id, x, y)); } @@ -155,7 +155,6 @@ std::shared_ptr<Level> Level::loadLevel(const std::string& path, Engine& engine) Level level(name, width, height, tiles, buildings, units, std::vector<Effect>{}, turnQ); level.m_turnQ.front().startTurn(level.m_units, level.m_buildings); - std::cout << "exiting" << std::endl; return std::make_shared<Level>(level); } diff --git a/src/game/main.cpp b/src/game/main.cpp index 6c65d17a726da0e52c41f7dc931600aa3b399a74..32481dc6411566e20e1c0dde4ac24ccbd0096c6c 100644 --- a/src/game/main.cpp +++ b/src/game/main.cpp @@ -6,20 +6,49 @@ #include <SDL2/SDL.h> #include <SDL_image.h> +#include <QCoreApplication> +#include <QCommandLineParser> #include <iostream> #include <memory> #include <stdexcept> #include <vector> +#include <string> +#include <optional> +#include <filesystem> using namespace advanced_wars; +std::optional<std::string> get_level_filepath(int argc, char* argv[]) +{ + QCoreApplication app(argc, argv); + QCoreApplication::setApplicationVersion("1.0.0"); + QCommandLineParser parser; + + parser.addVersionOption(); + parser.addHelpOption(); + parser.setApplicationDescription("Advanced Wars is a multi player strategy game.\nCapture citys, build units and defeat your opponents. No mercy!"); + parser.addPositionalArgument("path", "The path to the HDF5 level file from which the level should be loaded.", "<path>"); + parser.process(app); + if (parser.positionalArguments().size() != 1) + { + std::cerr << "Command not recognized." << std::endl; + parser.showHelp(); + return std::nullopt; + } + std::string filepath = parser.positionalArguments()[0].toStdString(); + if (!std::filesystem::exists(filepath)) + { + std::cerr << "The hdf5 level file path: '" << filepath <<"' does not exist." << std::endl; + return std::nullopt; + } + return parser.positionalArguments()[0].toStdString(); +} + int main(int argc, char* argv[]) { - if (argc <= 1) + std::optional<std::string> level_filepath = get_level_filepath(argc, argv); + if (!level_filepath.has_value()) { - std::cerr << "Please provide the path to the level that you want to play as a command line " - "argument." - << std::endl; return 1; } @@ -43,7 +72,7 @@ int main(int argc, char* argv[]) engine.setSpritesheet(spritesheet); - std::shared_ptr<Menu> menu = std::make_shared<Menu>(0, argv[1]); + std::shared_ptr<Menu> menu = std::make_shared<Menu>(0, level_filepath.value()); std::shared_ptr<ContextMenu> context_menu = std::make_shared<ContextMenu>(); context_menu->setOptions({"Move", "Info", "Wait"});