diff options
Diffstat (limited to 'frontend')
-rw-r--r-- | frontend/GameController.cpp | 68 | ||||
-rw-r--r-- | frontend/GameController.h | 31 | ||||
-rw-r--r-- | frontend/cmd/cheat.cpp | 9 | ||||
-rw-r--r-- | frontend/cmd/equip.cpp | 28 | ||||
-rw-r--r-- | frontend/cmd/get.cpp | 20 | ||||
-rw-r--r-- | frontend/cmd/go.cpp | 25 | ||||
-rw-r--r-- | frontend/cmd/help.cpp | 3 | ||||
-rw-r--r-- | frontend/cmd/hit.cpp | 18 | ||||
-rw-r--r-- | frontend/cmd/put.cpp | 17 | ||||
-rw-r--r-- | frontend/cmd/query.cpp | 9 | ||||
-rw-r--r-- | frontend/cmd/quit.cpp | 5 | ||||
-rw-r--r-- | frontend/cmd/restart.cpp | 5 | ||||
-rw-r--r-- | frontend/cmd/search.cpp | 8 | ||||
-rw-r--r-- | frontend/cmd/use.cpp | 3 | ||||
-rw-r--r-- | frontend/cmd/view.cpp | 45 | ||||
-rw-r--r-- | frontend/cmd/wait.cpp | 6 | ||||
-rw-r--r-- | frontend/main.cpp | 57 |
17 files changed, 187 insertions, 170 deletions
diff --git a/frontend/GameController.cpp b/frontend/GameController.cpp index a75767c..bbdd0c1 100644 --- a/frontend/GameController.cpp +++ b/frontend/GameController.cpp @@ -1,7 +1,10 @@ +#include "generate_dungeon.h" +#include "load_dungeon.h" #include "rl.h" #include "GameData.h" #include "strings.h" #include "GameController.h" +#include "Exception.h" #include "backend/print.h" #include "backend/WeaponObject.h" @@ -9,16 +12,13 @@ using namespace std; -GameController::GameController(Dungeon & dungeon) : dungeon(dungeon), player(dungeon.get_player()) { - lprtf("Wat is de naam van je karakter?\n"); - string name = rl(); - player.name = name.c_str(); - cmdset_default(); - player.set_location(dungeon.get_start_location()); - player.equip(static_cast<WeaponObject *>(GameData::get_instance().create_object("Dolk"))); +GameController::GameController() { + // Ensure DB is accessible + GameData::get_instance(); } void GameController::cmdset_default() { + this->cmds.clear(); this->cmds["Kijk"] = &GameController::cmd_query; this->cmds["Zoek"] = &GameController::cmd_search; this->cmds["Ga"] = &GameController::cmd_go; @@ -35,20 +35,68 @@ void GameController::cmdset_default() { } void GameController::cmdset_death() { + this->cmds.clear(); this->cmds["Help"] = &GameController::cmd_help; this->cmds["Quit"] = &GameController::cmd_quit; this->cmds["Opnieuw"] = &GameController::cmd_restart; } -FollowupAction GameController::cmd(string & argv) { - if (argv.size() == 0) return FollowupAction::NONE; +void GameController::cmd(string & argv) { + if (argv.size() == 0) return; string cmd = str_title(str_consume_arg(argv)); if (this->cmds.contains(cmd)) return (this->*cmds.at(cmd))(argv); str_print(strings::UNKNOWN_CMD); +} + +unique_ptr<Dungeon> GameController::make_dungeon() noexcept { + while (1) { + str_print(strings::INTRO); + string filename = rl(); + try { + if (filename.size() == 0) { + return generate_dungeon(); + } else { + return load_dungeon(filename); + } + } catch (Exception & e) { + lprtf("FOUT: %s\n", e.what()); + } + } +} + +void GameController::gameloop() { + this->dungeon = make_dungeon(); + Player & player = this->dungeon->get_player(); + + lprtf("Wat is de naam van je karakter?\n"); + player.name = rl().c_str(); + player.set_location(dungeon->get_start_location()); + player.equip(static_cast<WeaponObject *>(GameData::get_instance().create_object("Dolk"))); + + cmdset_default(); + + this->playing = true; + while (this->playing) { + string line = rl(); + if (line.length() == 0) continue; + try { + this->cmd(line); + } catch (Exception & e) { + lprtf("FOUT: %s\n", e.what()); + } + + if (player.is_dead()) + cmdset_death(); + } +} - return FollowupAction::NONE; +int GameController::main() { + while (!this->quit) { + this->gameloop(); + } + return EXIT_SUCCESS; } diff --git a/frontend/GameController.h b/frontend/GameController.h index afcb5b8..9f0d6ee 100644 --- a/frontend/GameController.h +++ b/frontend/GameController.h @@ -2,35 +2,37 @@ #include <unordered_map> #include <string> +#include <memory> +#include "backend/Dungeon.h" #include "backend/Player.h" -class Dungeon; class Location; -enum FollowupAction { - NONE, - UPDATE, - EXIT, - RESTART, -}; - class GameController { - typedef FollowupAction Cmd(std::string &); + typedef void Cmd(std::string &); public: - GameController(Dungeon & dungeon); + GameController(); virtual ~GameController() = default; +private: + void gameloop(); public: - FollowupAction cmd(std::string &); + int main(); + +private: + void cmd(std::string &); + +private: + std::unique_ptr<Dungeon> make_dungeon() noexcept; private: void cmdset_default(); void cmdset_death(); private: - std::unordered_map<std::string, FollowupAction(GameController::*)(std::string &)> cmds; + std::unordered_map<std::string, void(GameController::*)(std::string &)> cmds; Cmd cmd_query; Cmd cmd_search; Cmd cmd_go; @@ -47,7 +49,8 @@ private: Cmd cmd_restart; private: - Player & player; - Dungeon & dungeon; + std::unique_ptr<Dungeon> dungeon = nullptr; + bool playing = true; + bool quit = false; }; diff --git a/frontend/cmd/cheat.cpp b/frontend/cmd/cheat.cpp index ac392d6..8c0af8d 100644 --- a/frontend/cmd/cheat.cpp +++ b/frontend/cmd/cheat.cpp @@ -1,12 +1,13 @@ #include "backend/print.h" +#include "backend/Dungeon.h" #include "../GameController.h" using namespace std; -FollowupAction GameController::cmd_cheat(string &) { - this->player.cheating = !this->player.cheating; - lprtf("Cheats staan nu %s.\n", this->player.cheating ? "aan" : "uit"); - return FollowupAction::NONE; +void GameController::cmd_cheat(string &) { + Player & player = this->dungeon->get_player(); + player.cheating = !player.cheating; + lprtf("Cheats staan nu %s.\n", player.cheating ? "aan" : "uit"); } diff --git a/frontend/cmd/equip.cpp b/frontend/cmd/equip.cpp index 25a375f..578db0e 100644 --- a/frontend/cmd/equip.cpp +++ b/frontend/cmd/equip.cpp @@ -1,33 +1,35 @@ -#include "backend/print.h" #include "backend/ListIterator.h" +#include "backend/Dungeon.h" #include "../GameController.h" #include "../strings.h" +#include "../Exception.h" using namespace std; -FollowupAction GameController::cmd_equip(string & target_name) { - for (Object * object : this->player.inventory) { +void GameController::cmd_equip(string & target_name) { + Player & player = this->dungeon->get_player(); + for (Object * object : player.inventory) { if (str_lower(object->get_name().c_str()) != str_lower(target_name)) continue; WeaponObject * weapon = dynamic_cast<WeaponObject *>(object); if (weapon != nullptr) { - this->player.inventory.remove(weapon); - this->player.equip(weapon); - return FollowupAction::UPDATE; + player.inventory.remove(weapon); + player.equip(weapon); + this->dungeon->update(); + return; } ArmorObject * armor = dynamic_cast<ArmorObject *>(object); if (armor != nullptr) { - this->player.inventory.remove(armor); - this->player.equip(armor); - return FollowupAction::UPDATE; + player.inventory.remove(armor); + player.equip(armor); + this->dungeon->update(); + return; } - lprtf("Object %s is niet draagbaar.\n", target_name.c_str()); - return FollowupAction::NONE; + throw Exception("Object \"%s\" is niet draagbaar.", target_name.c_str()); } - lprtf("Object \"%s\" niet gevonden.\n", target_name.c_str()); - return FollowupAction::NONE; + throw Exception("Object \"%s\" niet gevonden.", target_name.c_str()); } diff --git a/frontend/cmd/get.cpp b/frontend/cmd/get.cpp index 652e989..358bf1f 100644 --- a/frontend/cmd/get.cpp +++ b/frontend/cmd/get.cpp @@ -2,15 +2,18 @@ #include "../GameController.h" #include "../strings.h" +#include "../Exception.h" #include "backend/print.h" #include "backend/GoldObject.h" #include "backend/Location.h" +#include "backend/Dungeon.h" using namespace std; -FollowupAction GameController::cmd_get(string & target_name) { - Location & location = this->player.get_location(); +void GameController::cmd_get(string & target_name) { + Player & player = this->dungeon->get_player(); + Location & location = player.get_location(); unique_ptr<Object> target = nullptr; for (Object * object : location.get_visible_objects()) { @@ -19,23 +22,20 @@ FollowupAction GameController::cmd_get(string & target_name) { location.remove_visible_object(object); break; } - if (target == nullptr) { - lprtf("Object \"%s\" niet gevonden.\n", target_name.c_str()); - return FollowupAction::NONE; - } + if (target == nullptr) + throw Exception("Object \"%s\" niet gevonden.", target_name.c_str()); // gold objects are collected and (implicitly) destroyed GoldObject * gold = dynamic_cast<GoldObject *>(target.get()); if (gold != nullptr) { int count = gold->get_count(); - this->player.gold += count; + player.gold += count; lprtf("Je bent %d goudstuk%s rijker.\n", count, count == 1 ? "" : "ken"); - return FollowupAction::NONE; + return; } // other objects go in the inventory lprtf("Je voegt %s toe aan je bezit.\n", target->get_name().c_str()); - this->player.inventory.push_back(target.release()); - return FollowupAction::NONE; + player.inventory.push_back(target.release()); } diff --git a/frontend/cmd/go.cpp b/frontend/cmd/go.cpp index 6a5f3b2..5fd7c93 100644 --- a/frontend/cmd/go.cpp +++ b/frontend/cmd/go.cpp @@ -1,8 +1,10 @@ #include "backend/Location.h" #include "backend/print.h" +#include "backend/Dungeon.h" #include "../GameController.h" #include "../strings.h" +#include "../Exception.h" using namespace std; @@ -13,21 +15,20 @@ static const unordered_map<string, Direction> direction_map = { { "west", Direction::WEST }, }; -FollowupAction GameController::cmd_go(string & argv) { +void GameController::cmd_go(string & argv) { string direction_str = str_consume_arg(argv); - if (direction_str.size() == 0 || !direction_map.contains(direction_str)) { - lprtf("Fout, gebruik: Ga <noord|zuid|oost|west>\n"); - return FollowupAction::NONE; - } + if (direction_str.size() == 0) + throw Exception("Dit commando heeft nog een argument met een richting nodig"); + if (!direction_map.contains(direction_str)) + throw Exception("Onbekende richting \"%s\", probeer noord|zuid|oost|west", direction_str.c_str()); + Player & player = this->dungeon->get_player(); Direction direction = direction_map.at(direction_str); - Location * next_location = this->player.get_location().get_exit(direction); - if (next_location == nullptr) { - lprtf("Er is geen uitgang in deze richting!\n"); - return FollowupAction::NONE; - } + Location * next_location = player.get_location().get_exit(direction); + if (next_location == nullptr) + throw Exception("Er is geen uitgang in deze richting"); - this->player.set_location(*next_location); - return FollowupAction::UPDATE; + player.set_location(*next_location); + this->dungeon->update(); } diff --git a/frontend/cmd/help.cpp b/frontend/cmd/help.cpp index e4425be..c9e1113 100644 --- a/frontend/cmd/help.cpp +++ b/frontend/cmd/help.cpp @@ -4,7 +4,7 @@ using namespace std; -FollowupAction GameController::cmd_help(string &) { +void GameController::cmd_help(string &) { lprtf("De beschikbare commando's zijn: "); bool first = true; for (auto & [ key, _ ] : this->cmds) { @@ -13,6 +13,5 @@ FollowupAction GameController::cmd_help(string &) { first = false; } lprtf(".\n"); - return FollowupAction::NONE; } diff --git a/frontend/cmd/hit.cpp b/frontend/cmd/hit.cpp index 2f39e8a..677bf4e 100644 --- a/frontend/cmd/hit.cpp +++ b/frontend/cmd/hit.cpp @@ -2,28 +2,32 @@ #include "backend/Location.h" #include "backend/RNG.h" #include "backend/print.h" +#include "backend/Dungeon.h" #include "../GameController.h" #include "../strings.h" +#include "../Exception.h" using namespace std; -FollowupAction GameController::cmd_hit(string & target_name) { +void GameController::cmd_hit(string & target_name) { RNG & rng = RNG::get(); - for (Enemy * enemy : this->player.get_location().get_enemies()) { + Player & player = this->dungeon->get_player(); + for (Enemy * enemy : player.get_location().get_enemies()) { if (str_lower(enemy->get_name().c_str()) != str_lower(target_name)) continue; - if (rng.rand_double() > this->player.get_attack()) { + if (rng.rand_double() > player.get_attack()) { lprtf("Je hebt gemist!\n"); } else { - unsigned damage = rng.rand_int(this->player.weapon->get_damage_min(), this->player.weapon->get_damage_max() + 1); + unsigned damage = rng.rand_int(player.weapon->get_damage_min(), player.weapon->get_damage_max() + 1); enemy->take_damage(damage); lprtf("Je hebt %s geraakt en %d schade aangericht!\n", enemy->get_displayname().c_str(), damage); } - return FollowupAction::UPDATE; + + this->dungeon->update(); + return; } - lprtf("Vijand \"%s\" niet gevonden.\n", target_name.c_str()); - return FollowupAction::NONE; + throw Exception("Vijand \"%s\" niet gevonden.", target_name.c_str()); } diff --git a/frontend/cmd/put.cpp b/frontend/cmd/put.cpp index dabac19..35de352 100644 --- a/frontend/cmd/put.cpp +++ b/frontend/cmd/put.cpp @@ -1,22 +1,25 @@ #include "../GameController.h" #include "../strings.h" +#include "../Exception.h" #include "backend/print.h" #include "backend/Location.h" +#include "backend/Dungeon.h" using namespace std; -FollowupAction GameController::cmd_put(string & target_name) { - Location & location = this->player.get_location(); - for (Object * object : this->player.inventory) { +void GameController::cmd_put(string & target_name) { + Player & player = this->dungeon->get_player(); + Location & location = player.get_location(); + for (Object * object : player.inventory) { if (str_lower(object->get_name().c_str()) != str_lower(target_name)) continue; lprtf("Je legt %s neer op de locatie %s.\n", object->get_displayname().c_str(), location.get_name().c_str()); - this->player.inventory.remove(object); + player.inventory.remove(object); location.add_visible_object(object); - return FollowupAction::NONE; + return; } - lprtf("Object \"%s\" niet gevonden.\n", target_name.c_str()); - return FollowupAction::NONE; + + throw Exception("Object \"%s\" niet gevonden.", target_name.c_str()); } diff --git a/frontend/cmd/query.cpp b/frontend/cmd/query.cpp index 2a62b45..6de7f56 100644 --- a/frontend/cmd/query.cpp +++ b/frontend/cmd/query.cpp @@ -2,6 +2,7 @@ #include "backend/Object.h" #include "backend/Enemy.h" #include "backend/print.h" +#include "backend/Dungeon.h" #include "../GameController.h" @@ -14,8 +15,10 @@ static const unordered_map<Direction, string> direction_map = { { Direction::WEST, "West" }, }; -FollowupAction GameController::cmd_query(string &) { - Location & location = this->player.get_location(); +void GameController::cmd_query(string &) { + Player & player = this->dungeon->get_player(); + Location & location = player.get_location(); + lprtf("Je staat bij de locatie %s.\n", location.get_name().c_str()); lprtf("%s\n", location.get_description().c_str()); @@ -56,7 +59,5 @@ FollowupAction GameController::cmd_query(string &) { lprtf("(geen)"); lprtf("\n"); } - - return FollowupAction::NONE; } diff --git a/frontend/cmd/quit.cpp b/frontend/cmd/quit.cpp index b3a6e80..7bc1b72 100644 --- a/frontend/cmd/quit.cpp +++ b/frontend/cmd/quit.cpp @@ -2,7 +2,8 @@ using namespace std; -FollowupAction GameController::cmd_quit(string &) { - return FollowupAction::EXIT; +void GameController::cmd_quit(string &) { + this->playing = false; + this->quit = true; } diff --git a/frontend/cmd/restart.cpp b/frontend/cmd/restart.cpp index 0ecb747..ed8d019 100644 --- a/frontend/cmd/restart.cpp +++ b/frontend/cmd/restart.cpp @@ -2,7 +2,8 @@ using namespace std; -FollowupAction GameController::cmd_restart(string &) { - return FollowupAction::RESTART; +void GameController::cmd_restart(string &) { + this->playing = false; + this->quit = false; } diff --git a/frontend/cmd/search.cpp b/frontend/cmd/search.cpp index f7fb528..c11c939 100644 --- a/frontend/cmd/search.cpp +++ b/frontend/cmd/search.cpp @@ -2,11 +2,12 @@ #include "backend/print.h" #include "backend/Location.h" +#include "backend/Dungeon.h" using namespace std; -FollowupAction GameController::cmd_search(string &) { - Location & location = this->player.get_location(); +void GameController::cmd_search(string &) { + Location & location = this->dungeon->get_player().get_location(); bool found = false; for (Object * object : location.get_hidden_objects()) { @@ -17,6 +18,7 @@ FollowupAction GameController::cmd_search(string &) { } if (!found) lprtf("Je hebt niks gevonden.\n"); - return FollowupAction::UPDATE; + + this->dungeon->update(); } diff --git a/frontend/cmd/use.cpp b/frontend/cmd/use.cpp index d83f67c..badab10 100644 --- a/frontend/cmd/use.cpp +++ b/frontend/cmd/use.cpp @@ -2,8 +2,7 @@ using namespace std; -FollowupAction GameController::cmd_use(string & argv) { +void GameController::cmd_use(string & argv) { // TODO - return FollowupAction::NONE; } diff --git a/frontend/cmd/view.cpp b/frontend/cmd/view.cpp index 04ad6aa..0f4f3d1 100644 --- a/frontend/cmd/view.cpp +++ b/frontend/cmd/view.cpp @@ -1,44 +1,46 @@ #include "../GameController.h" #include "../strings.h" +#include "../Exception.h" #include "backend/print.h" #include "backend/Location.h" +#include "backend/Dungeon.h" using namespace std; -FollowupAction GameController::cmd_view(string & target) { +void GameController::cmd_view(string & target) { if (target.size() == 0) { - lprtf("Fout, gebruik: Bekijk <Zelf|VIJHAND|OBJECT>\n"); - return FollowupAction::NONE; + throw Exception("gebruik: Bekijk <Zelf|VIJHAND|OBJECT>"); } - Location & location = this->player.get_location(); + Player & player = this->dungeon->get_player(); + Location & location = player.get_location(); // view self if (str_lower(target) == "zelf") { - lprtf("Je hebt %d levenspunten.\n", this->player.get_health()); + lprtf("Je hebt %d levenspunten.\n", player.get_health()); - lprtf("Je hebt een aanvalskans van %.0f%%.\n", this->player.get_attack() * 100); + lprtf("Je hebt een aanvalskans van %.0f%%.\n", player.get_attack() * 100); - if (this->player.weapon == nullptr) + if (player.weapon == nullptr) lprtf("Je hebt geen wapen vast.\n"); else - lprtf("Je hebt het volgende wapen vast: %s.\n", this->player.weapon->get_displayname().c_str()); + lprtf("Je hebt het volgende wapen vast: %s.\n", player.weapon->get_displayname().c_str()); - if (this->player.armor == nullptr) + if (player.armor == nullptr) lprtf("Je draagt geen wapenrusting.\n"); else - lprtf("Je draagt de volgende wapenrusting: %s.\n", this->player.armor->get_displayname().c_str()); + lprtf("Je draagt de volgende wapenrusting: %s.\n", player.armor->get_displayname().c_str()); - lprtf("Je hebt %u goundstuk%s.\n", this->player.gold, this->player.gold == 1 ? "" : "ken"); + lprtf("Je hebt %u goundstuk%s.\n", player.gold, player.gold == 1 ? "" : "ken"); - size_t items = this->player.inventory.size(); + size_t items = player.inventory.size(); lprtf("Je hebt %d %s%s\n", items, items == 1 ? "overig object" : "overige objecten", items > 0 ? ":" : "."); - for (auto & object : this->player.inventory) { + for (auto & object : player.inventory) { lprtf("- %s\n", object->get_displayname().c_str()); } - return FollowupAction::NONE; + return; } // try to find visible object in location @@ -46,15 +48,15 @@ FollowupAction GameController::cmd_view(string & target) { if (str_lower(object->get_name().c_str()) != str_lower(target)) continue; lprtf("%s\n", object->get_description().c_str()); - return FollowupAction::NONE; + return; } // try to find object in inventory - for (auto & object : this->player.inventory) { + for (auto & object : player.inventory) { if (str_lower(object->get_name().c_str()) != str_lower(target)) continue; lprtf("%s\n", object->get_description().c_str()); - return FollowupAction::NONE; + return; } // try to find enemy by name @@ -65,7 +67,9 @@ FollowupAction GameController::cmd_view(string & target) { unsigned enemy_health = enemy->get_health(); lprtf("%s heeft %s levenspunten.\n", enemy->get_name().c_str(), enemy_health); - if (!enemy->is_dead()) return FollowupAction::NONE; + if (!enemy->is_dead()) + return; + bool snatched = false; for (Object * object : enemy->get_hidden_objects()) { if (!snatched) lprtf("%s had de volgende voorwerpen:\n", enemy->get_displayname().c_str()); @@ -74,10 +78,9 @@ FollowupAction GameController::cmd_view(string & target) { location.add_visible_object(object); snatched = true; } - return FollowupAction::NONE; + return; } - lprtf("Fout, geen entiteit met naam \"%s\" gevonden.\n", target.c_str()); - return FollowupAction::NONE; + throw Exception("geen entiteit met naam \"%s\" gevonden.", target.c_str()); } diff --git a/frontend/cmd/wait.cpp b/frontend/cmd/wait.cpp index 0911d72..1a53d01 100644 --- a/frontend/cmd/wait.cpp +++ b/frontend/cmd/wait.cpp @@ -1,8 +1,10 @@ +#include "backend/Dungeon.h" + #include "../GameController.h" using namespace std; -FollowupAction GameController::cmd_wait(string &) { - return FollowupAction::UPDATE; +void GameController::cmd_wait(string &) { + this->dungeon->update(); } diff --git a/frontend/main.cpp b/frontend/main.cpp index f8e2526..64b4474 100644 --- a/frontend/main.cpp +++ b/frontend/main.cpp @@ -1,70 +1,17 @@ -#include <cstdlib> -#include <cstdio> -#include <memory> - #include "backend/print.h" -#include "backend/Dungeon.h" -#include "GameData.h" #include "GameController.h" #include "Exception.h" -#include "load_dungeon.h" -#include "generate_dungeon.h" -#include "rl.h" -#include "strings.h" using namespace std; -static unique_ptr<Dungeon> make_dungeon() noexcept { - while (1) { - str_print(strings::INTRO); - string filename = rl(); - try { - if (filename.size() == 0) { - return generate_dungeon(); - } else { - return load_dungeon(filename); - } - } catch (Exception & e) { - lprtf("FOUT: %s\n", e.what()); - } - } -} - -FollowupAction game_main() { - unique_ptr<Dungeon> dungeon = make_dungeon(); - GameController game { *dungeon }; - - while (1) { - string line = rl(); - if (line.length() == 0) continue; - FollowupAction action = game.cmd(line); - - switch (action) { - case NONE: break; - case UPDATE: { - dungeon->update(); - break; - } - default: return action; - } - } -} - int main() { try { - GameData::get_instance(); // pre-load DB + GameController game; + return game.main(); } catch (Exception & e) { lprtf("FOUT: %s\n", e.what()); return EXIT_FAILURE; } - - FollowupAction action; - do { - action = game_main(); - if (action == EXIT) break; - } while (action == RESTART); - - return EXIT_SUCCESS; } |