diff options
author | Loek Le Blansch <loek@pipeframe.xyz> | 2024-11-02 13:18:50 +0100 |
---|---|---|
committer | Loek Le Blansch <loek@pipeframe.xyz> | 2024-11-02 13:18:50 +0100 |
commit | 5a675c5e6833e98b92b55396594bc0d607b98903 (patch) | |
tree | b252fafe921e7734a13d796b950e5ab817a22a1f | |
parent | 671a25463419691bc6c8d11bd57d932bdea9632b (diff) |
clean up code + implement teleport consumable
-rw-r--r-- | backend/TeleportConsumableObject.cpp | 10 | ||||
-rw-r--r-- | frontend/CMakeLists.txt | 1 | ||||
-rw-r--r-- | frontend/GameData.cpp | 6 | ||||
-rw-r--r-- | frontend/cmd/equip.cpp | 46 | ||||
-rw-r--r-- | frontend/cmd/get.cpp | 5 | ||||
-rw-r--r-- | frontend/cmd/hit.cpp | 25 | ||||
-rw-r--r-- | frontend/cmd/put.cpp | 17 | ||||
-rw-r--r-- | frontend/cmd/use.cpp | 4 | ||||
-rw-r--r-- | frontend/cmd/view.cpp | 45 | ||||
-rw-r--r-- | frontend/load_dungeon.cpp | 4 | ||||
-rw-r--r-- | frontend/util.cpp | 7 | ||||
-rw-r--r-- | frontend/util.h | 11 | ||||
-rw-r--r-- | frontend/util.hpp | 17 |
13 files changed, 106 insertions, 92 deletions
diff --git a/backend/TeleportConsumableObject.cpp b/backend/TeleportConsumableObject.cpp index 5fd4459..7d1803f 100644 --- a/backend/TeleportConsumableObject.cpp +++ b/backend/TeleportConsumableObject.cpp @@ -1,6 +1,14 @@ +#include "RNG.h" #include "TeleportConsumableObject.h" +#include "Player.h" +#include "Location.h" void TeleportConsumableObject::consume(Player & player) { - // TODO + unsigned hops = RNG::get().rand_int(this->get_potency()); + Location * location = &player.get_location(); + for (size_t i = 0; i < hops; i++) { + location = location->get_exit(random_direction(*location)); + } + player.set_location(*location); } diff --git a/frontend/CMakeLists.txt b/frontend/CMakeLists.txt index 03191dd..8f086d3 100644 --- a/frontend/CMakeLists.txt +++ b/frontend/CMakeLists.txt @@ -7,7 +7,6 @@ target_sources(main PUBLIC generate_dungeon.cpp DB.cpp GameData.cpp - util.cpp ) add_subdirectory(cmd) diff --git a/frontend/GameData.cpp b/frontend/GameData.cpp index 3b9046d..1b7c548 100644 --- a/frontend/GameData.cpp +++ b/frontend/GameData.cpp @@ -37,7 +37,7 @@ Enemy * GameData::create_enemy(const string & name) const { query.reset() .bind(name) ; - + try { auto row = query.row(); auto enemy = unique_ptr<Enemy>{ EnemyFactory::create_enemy(row.col<const char *>(0), row.col<const char *>(1)) }; @@ -69,7 +69,7 @@ Object * GameData::create_object(const string & name) const { query.reset() .bind(name) ; - + try { auto row = query.row(); return ObjectFactory::create_object({ @@ -96,7 +96,7 @@ Location * GameData::create_location(const string & name) const{ query.reset() .bind(name) ; - + try { auto row = query.row(); return LocationFactory::create_location(row.col<const char *>(0), row.col<const char *>(1)); diff --git a/frontend/cmd/equip.cpp b/frontend/cmd/equip.cpp index 9d2a006..fe951b1 100644 --- a/frontend/cmd/equip.cpp +++ b/frontend/cmd/equip.cpp @@ -3,33 +3,35 @@ #include "backend/Exception.h" #include "../GameController.h" -#include "../strings.h" +#include "../util.h" using namespace std; 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) { - player.inventory.remove(weapon); - player.equip(weapon); - this->dungeon->update(); - return; - } - - ArmorObject * armor = dynamic_cast<ArmorObject *>(object); - if (armor != nullptr) { - player.inventory.remove(armor); - player.equip(armor); - this->dungeon->update(); - return; - } - - throw Exception("object \"%s\" is niet draagbaar", target_name.c_str()); + + auto it = find_if_range(player.inventory.range(), by_name_case_insensitive(target_name)); + if (!it) + throw Exception("object \"%s\" niet gevonden", target_name.c_str()); + + Object & object = **it; + + WeaponObject * weapon = dynamic_cast<WeaponObject *>(&object); + if (weapon != nullptr) { + player.inventory.remove(weapon); + player.equip(weapon); + this->dungeon->update(); + return; } - throw Exception("object \"%s\" niet gevonden", target_name.c_str()); + + ArmorObject * armor = dynamic_cast<ArmorObject *>(&object); + if (armor != nullptr) { + player.inventory.remove(armor); + player.equip(armor); + this->dungeon->update(); + return; + } + + throw Exception("object \"%s\" is niet draagbaar", target_name.c_str()); } diff --git a/frontend/cmd/get.cpp b/frontend/cmd/get.cpp index 362830e..e774168 100644 --- a/frontend/cmd/get.cpp +++ b/frontend/cmd/get.cpp @@ -1,8 +1,6 @@ -#include <algorithm> #include <memory> #include "../GameController.h" -#include "../strings.h" #include "../util.h" #include "backend/Exception.h" @@ -17,8 +15,7 @@ void GameController::cmd_get(string & target_name) { Player & player = this->dungeon->get_player(); Location & location = player.get_location(); - auto range = location.get_visible_objects(); - auto it = find_if(range.begin(), range.end(), by_name_case_insensitive(target_name)); + auto it = find_if_range(location.get_visible_objects(), by_name_case_insensitive(target_name)); if (!it) throw Exception("object \"%s\" niet gevonden", target_name.c_str()); auto object = unique_ptr<Object>(*it); diff --git a/frontend/cmd/hit.cpp b/frontend/cmd/hit.cpp index 94bde03..cb5c56e 100644 --- a/frontend/cmd/hit.cpp +++ b/frontend/cmd/hit.cpp @@ -6,28 +6,27 @@ #include "backend/Exception.h" #include "../GameController.h" -#include "../strings.h" +#include "../util.h" using namespace std; void GameController::cmd_hit(string & target_name) { RNG & rng = RNG::get(); 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() > player.get_attack()) { - lprtf("Je hebt gemist!\n"); - } else { - unsigned damage = rng.rand_int(player.weapon->get_damage()); - enemy->take_damage(damage); - lprtf("Je hebt %s geraakt en %d schade aangericht!\n", enemy->get_displayname().c_str(), damage); - } + auto it = find_if_range(player.get_location().get_enemies(), by_name_case_insensitive(target_name)); + if (!it) + throw Exception("vijand \"%s\" niet gevonden", target_name.c_str()); + Enemy & enemy = **it; - this->dungeon->update(); - return; + if (rng.rand_double() > player.get_attack()) { + lprtf("Je hebt gemist!\n"); + } else { + unsigned damage = rng.rand_int(player.weapon->get_damage()); + enemy.take_damage(damage); + lprtf("Je hebt %s geraakt en %d schade aangericht!\n", enemy.get_displayname().c_str(), damage); } - throw Exception("vijand \"%s\" niet gevonden", target_name.c_str()); + this->dungeon->update(); } diff --git a/frontend/cmd/put.cpp b/frontend/cmd/put.cpp index 7f54c3b..acd4981 100644 --- a/frontend/cmd/put.cpp +++ b/frontend/cmd/put.cpp @@ -1,5 +1,5 @@ #include "../GameController.h" -#include "../strings.h" +#include "../util.h" #include "backend/Exception.h" #include "backend/print.h" @@ -11,15 +11,14 @@ using namespace std; 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()); - player.inventory.remove(object); - location.add_visible_object(object); - return; - } + auto it = find_if_range(player.inventory.range(), by_name_case_insensitive(target_name)); + if (!it) + throw Exception("object \"%s\" niet gevonden", target_name.c_str()); + Object & object = **it; - throw Exception("object \"%s\" niet gevonden", target_name.c_str()); + lprtf("Je legt %s neer op de locatie %s.\n", object.get_displayname().c_str(), location.get_name().c_str()); + player.inventory.remove(&object); + location.add_visible_object(&object); } diff --git a/frontend/cmd/use.cpp b/frontend/cmd/use.cpp index 002255a..3134210 100644 --- a/frontend/cmd/use.cpp +++ b/frontend/cmd/use.cpp @@ -12,8 +12,8 @@ using namespace std; void GameController::cmd_use(string & target_name) { Player & player = this->dungeon->get_player(); Location & location = player.get_location(); - - auto it = find_if(player.inventory.begin(), player.inventory.end(), by_name_case_insensitive(target_name)); + + auto it = find_if_range(player.inventory.range(), by_name_case_insensitive(target_name)); if (!it) throw Exception("object \"%s\" niet gevonden", target_name.c_str()); diff --git a/frontend/cmd/view.cpp b/frontend/cmd/view.cpp index 91eaf94..bd87227 100644 --- a/frontend/cmd/view.cpp +++ b/frontend/cmd/view.cpp @@ -1,5 +1,6 @@ #include "../GameController.h" #include "../strings.h" +#include "../util.h" #include "backend/Exception.h" #include "backend/print.h" @@ -9,9 +10,8 @@ using namespace std; void GameController::cmd_view(string & target) { - if (target.size() == 0) { + if (target.size() == 0) throw Exception("gebruik: Bekijk <Zelf|VIJHAND|OBJECT>"); - } Player & player = this->dungeon->get_player(); Location & location = player.get_location(); @@ -43,38 +43,31 @@ void GameController::cmd_view(string & target) { return; } - // try to find visible object in location - for (Object * object : location.get_visible_objects()) { - if (str_lower(object->get_name().c_str()) != str_lower(target)) continue; - - lprtf("%s\n", object->get_description().c_str()); - return; - } - - // try to find object in 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()); + // try to find visible object in location or inventory + auto object_it = find_if_range(location.get_visible_objects(), by_name_case_insensitive(target)); + if (!object_it) object_it = find_if_range(player.inventory.range(), by_name_case_insensitive(target)); + if (!!object_it) { + Object & object = **object_it; + lprtf("%s\n", object.get_description().c_str()); return; } // try to find enemy by name - for (Enemy * enemy : location.get_enemies()) { - if (str_lower(enemy->get_name().c_str()) != str_lower(target)) continue; - - lprtf("%s\n", enemy->get_description().c_str()); - unsigned enemy_health = enemy->get_health(); - lprtf("%s heeft %u levenspunten.\n", enemy->get_name().c_str(), enemy_health); - - if (!enemy->is_dead()) + auto enemy_it = find_if_range(location.get_enemies(), by_name_case_insensitive(target)); + if (!!enemy_it) { + Enemy & enemy = **enemy_it; + lprtf("%s\n", enemy.get_description().c_str()); + unsigned enemy_health = enemy.get_health(); + lprtf("%s heeft %u levenspunten.\n", enemy.get_name().c_str(), enemy_health); + + 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()); + for (Object * object : enemy.get_hidden_objects()) { + if (!snatched) lprtf("%s had de volgende voorwerpen:\n", enemy.get_displayname().c_str()); lprtf("- %s\n", object->get_displayname().c_str()); - enemy->remove_hidden_object(object); + enemy.remove_hidden_object(object); location.add_visible_object(object); snatched = true; } diff --git a/frontend/load_dungeon.cpp b/frontend/load_dungeon.cpp index 75edf16..e5a1e82 100644 --- a/frontend/load_dungeon.cpp +++ b/frontend/load_dungeon.cpp @@ -63,13 +63,13 @@ unique_ptr<Dungeon> load_dungeon(const string & filename) { Object * object = gamedata.create_object(name); location->add_visible_object(object); } - + vector<string> enemies = str_split(tag.attribute("vijand").as_string(), ";"); for (string & name : enemies) { Enemy * enemy = gamedata.create_enemy(name); location->add_enemy(enemy); } - + temp_map[tag.attribute("id").as_uint()] = { .location = location, .edges = { diff --git a/frontend/util.cpp b/frontend/util.cpp deleted file mode 100644 index afff38f..0000000 --- a/frontend/util.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#include "util.h" -#include "strings.h" - -bool by_name_case_insensitive::operator () (Object * object) { - return str_lower(object->get_name().c_str()) == str_lower(this->target_name); -} - diff --git a/frontend/util.h b/frontend/util.h index 946539f..a32e4c9 100644 --- a/frontend/util.h +++ b/frontend/util.h @@ -2,11 +2,18 @@ #include <string> -#include "backend/Object.h" +#include "backend/ListIterator.h" struct by_name_case_insensitive { by_name_case_insensitive(const std::string & target_name) : target_name(target_name) {} std::string target_name; - bool operator () (Object * object); + + template <typename T> + bool operator () (T * object); }; +template <typename T, class Predicate> +ListIterator<T> find_if_range(ListRange<T>, Predicate); + +#include "util.hpp" + diff --git a/frontend/util.hpp b/frontend/util.hpp new file mode 100644 index 0000000..c737b2a --- /dev/null +++ b/frontend/util.hpp @@ -0,0 +1,17 @@ +#pragma once + +#include <algorithm> + +#include "util.h" +#include "strings.h" + +template <typename T, class Predicate> +ListIterator<T> find_if_range(ListRange<T> range, Predicate pred) { + return std::find_if(range.begin(), range.end(), pred); +} + +template <typename T> +bool by_name_case_insensitive::operator () (T * object) { + return str_lower(object->get_name().c_str()) == str_lower(this->target_name); +} + |