aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLoek Le Blansch <loek@pipeframe.xyz>2024-11-02 13:18:50 +0100
committerLoek Le Blansch <loek@pipeframe.xyz>2024-11-02 13:18:50 +0100
commit5a675c5e6833e98b92b55396594bc0d607b98903 (patch)
treeb252fafe921e7734a13d796b950e5ab817a22a1f
parent671a25463419691bc6c8d11bd57d932bdea9632b (diff)
clean up code + implement teleport consumable
-rw-r--r--backend/TeleportConsumableObject.cpp10
-rw-r--r--frontend/CMakeLists.txt1
-rw-r--r--frontend/GameData.cpp6
-rw-r--r--frontend/cmd/equip.cpp46
-rw-r--r--frontend/cmd/get.cpp5
-rw-r--r--frontend/cmd/hit.cpp25
-rw-r--r--frontend/cmd/put.cpp17
-rw-r--r--frontend/cmd/use.cpp4
-rw-r--r--frontend/cmd/view.cpp45
-rw-r--r--frontend/load_dungeon.cpp4
-rw-r--r--frontend/util.cpp7
-rw-r--r--frontend/util.h11
-rw-r--r--frontend/util.hpp17
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);
+}
+