diff --git a/CMakeLists.txt b/CMakeLists.txt index c4cf22e..2c09d02 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.4) -set(CMAKE_DISABLE_SOURCE_CHANGES ON) +#set(CMAKE_DISABLE_SOURCE_CHANGES ON) set(CMAKE_DISABLE_IN_SOURCE_BUILD ON) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/") @@ -12,7 +12,7 @@ execute_process( file(WRITE "src/gitparams.h" "#define GIT_CUR_COMMIT ${GIT_COMMIT}") set(CMAKE_CXX_STANDARD 11) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libgcc -static-libstdc++") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -g -static-libgcc -static-libstdc++") project(dungeon LANGUAGES CXX) diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..de64bf7 --- /dev/null +++ b/build.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +cd build +cmake .. && make -j4 && mv dungeon .. +cd .. diff --git a/dungeon b/dungeon new file mode 100755 index 0000000..cee02c7 Binary files /dev/null and b/dungeon differ diff --git a/src/App.cpp b/src/App.cpp index d02215f..cc19912 100644 --- a/src/App.cpp +++ b/src/App.cpp @@ -102,10 +102,6 @@ bool App::init() { } int App::start() { - current = new PlayState(); - current->init(this); - current->load(); - double dt = 1.0/30; double currentTime = currTime(); double accumulator = dt; @@ -114,6 +110,10 @@ int App::start() { bool running = true; Gamestate* nextstate = nullptr; + current = new PlayState(); + current->init(this); + current->load(); + while (running) { double newTime = currTime(); double frametime = newTime - currentTime; @@ -136,7 +136,7 @@ int App::start() { ImGuiIO &io = ImGui::GetIO(); renderer->ImguiNewFrame(); while (SDL_PollEvent(&ev)) { - renderer->ImguiProcessEvents(&ev); + //renderer->ImguiProcessEvents(&ev); switch (ev.type) { case SDL_WINDOWEVENT: switch (ev.window.event) { @@ -199,7 +199,7 @@ int App::start() { SDL_Delay(1); } delete renderer; - ImGui::Shutdown(); + //ImGui::Shutdown(); SDL_Quit(); SDL_LogVerbose(SDL_LOG_CATEGORY_SYSTEM, "Quit."); diff --git a/src/FieldOfView.cpp b/src/FieldOfView.cpp index 1387713..3a16648 100644 --- a/src/FieldOfView.cpp +++ b/src/FieldOfView.cpp @@ -5,6 +5,10 @@ #include #include "FieldOfView.h" #include "Tilemap.h" +#include + +FieldOfView::FieldOfView() { +} FieldOfView::FieldOfView(Tilemap *map) { this->map = map; @@ -20,14 +24,19 @@ void FieldOfView::calc(vec2i pos, float range) { counter++; seen->set_tile(pos.x, pos.y, counter); // Once for each octant - cast_light(1, 1.0f, 0.0f, 0, -1, -1, 0, pos.x, pos.y, range); - cast_light(1, 1.0f, 0.0f, -1, 0, 0, -1, pos.x, pos.y, range); - cast_light(1, 1.0f, 0.0f, 0, 1, -1, 0, pos.x, pos.y, range); - cast_light(1, 1.0f, 0.0f, 1, 0, 0, -1, pos.x, pos.y, range); - cast_light(1, 1.0f, 0.0f, 0, -1, 1, 0, pos.x, pos.y, range); - cast_light(1, 1.0f, 0.0f, -1, 0, 0, 1, pos.x, pos.y, range); - cast_light(1, 1.0f, 0.0f, 0, 1, 1, 0, pos.x, pos.y, range); - cast_light(1, 1.0f, 0.0f, 1, 0, 0, 1, pos.x, pos.y, range); + if (map != nullptr) { + cast_light(1, 1.0f, 0.0f, 0, -1, -1, 0, pos.x, pos.y, range); + cast_light(1, 1.0f, 0.0f, -1, 0, 0, -1, pos.x, pos.y, range); + cast_light(1, 1.0f, 0.0f, 0, 1, -1, 0, pos.x, pos.y, range); + cast_light(1, 1.0f, 0.0f, 1, 0, 0, -1, pos.x, pos.y, range); + cast_light(1, 1.0f, 0.0f, 0, -1, 1, 0, pos.x, pos.y, range); + cast_light(1, 1.0f, 0.0f, -1, 0, 0, 1, pos.x, pos.y, range); + cast_light(1, 1.0f, 0.0f, 0, 1, 1, 0, pos.x, pos.y, range); + cast_light(1, 1.0f, 0.0f, 1, 0, 0, 1, pos.x, pos.y, range); + } + else { + SDL_LogError(SDL_LOG_CATEGORY_SYSTEM, "Tried to calc fov with a null tilemap!\n"); + } } bool FieldOfView::can_see(vec2i pos) { diff --git a/src/FieldOfView.h b/src/FieldOfView.h index ea2175d..b39ae02 100644 --- a/src/FieldOfView.h +++ b/src/FieldOfView.h @@ -16,7 +16,8 @@ class FieldOfView { void cast_light(int row, float start, float end, int xx, int xy, int yx, int yy, int startX, int startY, float radius); public: Tilemap* seen; - explicit FieldOfView(Tilemap* map); + FieldOfView(); + FieldOfView(Tilemap* map); ~FieldOfView(); void calc(vec2i pos, float range); bool can_see(vec2i pos); diff --git a/src/Gamestate.h b/src/Gamestate.h index 6bb8beb..69c0211 100644 --- a/src/Gamestate.h +++ b/src/Gamestate.h @@ -12,6 +12,7 @@ class Gamestate { protected: App* app; public: + //virtual ~Gamestate() {}; void init(App* app); virtual void load() = 0; virtual Gamestate* update(double delta) = 0; diff --git a/src/Mapgen.cpp b/src/Mapgen.cpp new file mode 100644 index 0000000..d2cbfaf --- /dev/null +++ b/src/Mapgen.cpp @@ -0,0 +1,18 @@ +#include "Mapgen.h" + +Tilemap generate_level(int seed, int width, int height) { + Tilemap map = Tilemap(width, height); + + for (int y = 0; y < height; ++y) { + for (int x = 0; x < width; ++x) { + if (x == 0 || x == width || y == 0 || y == height) { + map.set_tile(x,y, '#'); + } + else { + map.set_tile(x,y, '.'); + } + } + } + + return map; +} diff --git a/src/Mapgen.h b/src/Mapgen.h new file mode 100644 index 0000000..510e753 --- /dev/null +++ b/src/Mapgen.h @@ -0,0 +1,4 @@ +#pragma once +#include "Tilemap.h" + +Tilemap generate_level(int seed, int width, int height); diff --git a/src/PlayState.cpp b/src/PlayState.cpp index bb37b6d..1a9385e 100644 --- a/src/PlayState.cpp +++ b/src/PlayState.cpp @@ -8,7 +8,7 @@ #include "Actor.h" #include "App.h" #include "Tileset.h" -#include "Tilemap.h" +#include "Mapgen.h" #include "FieldOfView.h" #include "imgui.h" #include "Hero.h" @@ -25,6 +25,8 @@ void PlayState::load() { SDL_LogVerbose(SDL_LOG_CATEGORY_SYSTEM, "Created ascii tileset.\n"); app->input->bind_key(SDLK_ESCAPE, ACTION_ESCAPE_MENU); + + // Movement: keypad app->input->bind_key(SDLK_KP_8, ACTION_MOVE_NORTH); app->input->bind_key(SDLK_KP_7, ACTION_MOVE_NORTHWEST); app->input->bind_key(SDLK_KP_9, ACTION_MOVE_NORTHEAST); @@ -34,11 +36,14 @@ void PlayState::load() { app->input->bind_key(SDLK_KP_1, ACTION_MOVE_SOUTHWEST); app->input->bind_key(SDLK_KP_3, ACTION_MOVE_SOUTHEAST); app->input->bind_key(SDLK_KP_5, ACTION_WAIT); + + // Movement: arrow-keys app->input->bind_key(SDLK_UP, ACTION_MOVE_NORTH); app->input->bind_key(SDLK_DOWN, ACTION_MOVE_SOUTH); app->input->bind_key(SDLK_LEFT, ACTION_MOVE_WEST); app->input->bind_key(SDLK_RIGHT, ACTION_MOVE_EAST); + // Movement: vim-keys app->input->bind_key(SDLK_k, ACTION_MOVE_NORTH); app->input->bind_key(SDLK_y, ACTION_MOVE_NORTHWEST); app->input->bind_key(SDLK_u, ACTION_MOVE_NORTHEAST); @@ -48,9 +53,10 @@ void PlayState::load() { app->input->bind_key(SDLK_n, ACTION_MOVE_SOUTHWEST); app->input->bind_key(SDLK_m, ACTION_MOVE_SOUTHEAST); + // debug app->input->bind_key(SDLK_F1, ACTION_TOGGLE_DEBUG); - app->input->bind_key(SDLK_r, ACTION_RESET); + SDL_LogVerbose(SDL_LOG_CATEGORY_SYSTEM, "Keybinds bound.\n"); new_game(); } @@ -58,22 +64,11 @@ void PlayState::load() { void PlayState::new_game() { action = ACTION_NONE; - if (tilemap != nullptr) { - delete tilemap; - tilemap = nullptr; - hero = nullptr; - } - if (hero != nullptr) { delete hero; hero = nullptr; } - if (fov != nullptr) { - delete fov; - fov = nullptr; - } - std::string map = "# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #" "# @ . . . # # # # # # # # . . . . . . . . . . . . . . . . . # #" @@ -110,6 +105,7 @@ void PlayState::new_game() { "# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #"; SDL_LogVerbose(SDL_LOG_CATEGORY_SYSTEM, "Creating tilemap...\n"); + /* tilemap = new Tilemap(32, 32); int y = 0; int x = 0; @@ -128,31 +124,36 @@ void PlayState::new_game() { if (i == '@') { hero = new Hero(tilemap, vec2i(x, y)); - tilemap->add_entity(hero); - tilemap->set_tile(x, y, '.'); + tilemap.add_entity(hero); + tilemap.set_tile(x, y, '.'); } else if (i == 'g') { - tilemap->add_entity(new Goblin(tilemap, vec2i(x, y))); - tilemap->set_tile(x, y, '.'); + tilemap.add_entity(new Goblin(tilemap, vec2i(x, y))); + tilemap.set_tile(x, y, '.'); } else if (i == 's') { - tilemap->add_entity(new Shaman(tilemap, vec2i(x, y))); - tilemap->set_tile(x, y, '.'); + tilemap.add_entity(new Shaman(tilemap, vec2i(x, y))); + tilemap.set_tile(x, y, '.'); } else { - tilemap->set_tile(x, y, i); + tilemap.set_tile(x, y, i); } x++; } + */ + tilemap = generate_level(1, 32, 32); + hero = new Hero(&tilemap, vec2i(4,4)); + tilemap.add_entity(hero); SDL_LogVerbose(SDL_LOG_CATEGORY_SYSTEM, "Done.\n"); SDL_LogVerbose(SDL_LOG_CATEGORY_SYSTEM, "Calculating initial FOV...\n"); - fov = new FieldOfView(tilemap); - fov->calc(hero->get_position(), 6); + fov = FieldOfView(&tilemap); + fov.calc(hero->get_position(), 6); SDL_LogVerbose(SDL_LOG_CATEGORY_SYSTEM, "Done.\n"); } Gamestate *PlayState::update(double delta) { if (action != ACTION_NONE) { + SDL_LogVerbose(SDL_LOG_CATEGORY_SYSTEM, "Starting turn...\n"); if (hero && hero->is_alive()) { vec2i dir; switch (action) { @@ -165,13 +166,14 @@ Gamestate *PlayState::update(double delta) { case ACTION_MOVE_SOUTHWEST: dir = {-1, 1}; break; case ACTION_MOVE_SOUTHEAST: dir = {1, 1}; break; case ACTION_WAIT: dir = {0, 0}; break; - default: action = ACTION_NONE; return nullptr; // abort turn + default: action = ACTION_NONE; SDL_LogVerbose(SDL_LOG_CATEGORY_SYSTEM, "Turn aborted: no player action.\n"); return nullptr; // abort turn } if (dir != vec2i(0,0)) { if (!hero->move(dir.x, dir.y)) { vec2i heropos = hero->get_position(); - auto acts = tilemap->get_entities(heropos.x + dir.x, heropos.y + dir.y, 0, ENTITY_ACTOR); + auto acts = tilemap.get_entities(heropos.x + dir.x, heropos.y + dir.y, 0, ENTITY_ACTOR); if(acts.empty()) { + SDL_LogVerbose(SDL_LOG_CATEGORY_SYSTEM, "Turn aborted: invalid player action.\n"); return nullptr; // unable to move and nothing to attack == abort turn } for (auto ent : acts) { @@ -184,10 +186,10 @@ Gamestate *PlayState::update(double delta) { } } hero->update(); - fov->calc(hero->get_position(), 6); + fov.calc(hero->get_position(), 6); } - auto actors = tilemap->get_entity_list(); + auto actors = tilemap.get_entity_list(); for (Entity* var : *actors) { if (var == hero) continue; if (var->entity_type() == ENTITY_ACTOR) { @@ -207,6 +209,7 @@ Gamestate *PlayState::update(double delta) { } */ action = ACTION_NONE; + SDL_LogVerbose(SDL_LOG_CATEGORY_SYSTEM, "Turn finished.\n"); } return nullptr; } @@ -242,7 +245,7 @@ void PlayState::draw(double delta) { if (debug_actors) { ImGui::Begin("Actors", &debug_actors); - auto actors = tilemap->get_entity_list(); + auto actors = tilemap.get_entity_list(); const char* headers[] { "id", "name", "health", "strength" }; @@ -283,17 +286,16 @@ void PlayState::draw(double delta) { (tilesize.x/2-heropos.x), (tilesize.y/2-heropos.y), }; + tilemap.draw(app->renderer, ascii, margin.x, margin.y, -offset.x, -offset.y, tilesize.x, tilesize.y, &fov); - tilemap->draw(app->renderer, ascii, margin.x, margin.y, -offset.x, -offset.y, tilesize.x, tilesize.y, fov); - - auto entities = tilemap->get_entity_list(); + auto entities = tilemap.get_entity_list(); // Draw dead actors for (Entity* var : *entities) { if (var->entity_type() == ENTITY_ACTOR && ((Actor*)var)->is_alive()) continue; vec2i pos = var->get_position(); - if ((fov == nullptr || fov->can_see(pos))) { + if (fov.can_see(pos)) { app->renderer->set_color(0, 0, 0, 1); app->renderer->draw_sprite(ascii->get_sprite(219), margin.x + (offset.x + pos.x) * asciisize.x, margin.y + (offset.y + pos.y) * asciisize.y); @@ -311,7 +313,7 @@ void PlayState::draw(double delta) { if (var->entity_type() == ENTITY_ACTOR && !((Actor*)var)->is_alive()) continue; vec2i pos = var->get_position(); - if ((fov == nullptr || fov->can_see(pos))) { + if (fov.can_see(pos)) { app->renderer->set_color(0, 0, 0, 1); app->renderer->draw_sprite(ascii->get_sprite(219), margin.x + (offset.x + pos.x) * asciisize.x, margin.y + (offset.y + pos.y) * asciisize.y); @@ -335,21 +337,6 @@ void PlayState::draw(double delta) { } void PlayState::quit() { - if (tilemap != nullptr) { - delete tilemap; - tilemap = nullptr; - hero = nullptr; - } - - if (hero != nullptr) { - delete hero; - hero = nullptr; - } - - if (fov != nullptr) { - delete fov; - fov = nullptr; - } } void PlayState::inputevent(InputEvent *event) { diff --git a/src/PlayState.h b/src/PlayState.h index 5ad882d..9cfab04 100644 --- a/src/PlayState.h +++ b/src/PlayState.h @@ -7,17 +7,17 @@ #include "Gamestate.h" +#include "Tilemap.h" +#include "FieldOfView.h" class Tileset; -class Tilemap; class Actor; -class FieldOfView; class PlayState : public Gamestate { Tileset* ascii; - Tilemap* tilemap; + Tilemap tilemap; Actor * hero; - FieldOfView *fov; + FieldOfView fov; bool debug; public: