aboutsummaryrefslogtreecommitdiff
path: root/frontend
diff options
context:
space:
mode:
authorLoek Le Blansch <loek@pipeframe.xyz>2024-10-30 12:24:43 +0100
committerLoek Le Blansch <loek@pipeframe.xyz>2024-10-30 12:24:43 +0100
commitb1d5d7936bed17a684daff15b0294ef70754e8b9 (patch)
tree85ee543a15b42c7f854e4ce403bcff3dff5a3bd4 /frontend
parent991c9aac53fa3562b0fdc03d74b398052b207d2c (diff)
more more WIP
Diffstat (limited to 'frontend')
-rw-r--r--frontend/DB.cpp24
-rw-r--r--frontend/DB.h4
-rw-r--r--frontend/GameData.cpp35
-rw-r--r--frontend/Player.h2
-rw-r--r--frontend/cmd/view.cpp7
-rw-r--r--frontend/load_dungeon.cpp10
6 files changed, 62 insertions, 20 deletions
diff --git a/frontend/DB.cpp b/frontend/DB.cpp
index 28fd164..d4527b8 100644
--- a/frontend/DB.cpp
+++ b/frontend/DB.cpp
@@ -51,7 +51,10 @@ DBStatement & DBStatement::bind(const int & number) {
return *this;
}
-DBStatement & DBStatement::unbind() {
+DBStatement & DBStatement::reset() {
+ int ret = sqlite3_reset(this->stmt.get());
+ if (ret != SQLITE_OK)
+ throw Exception("sqlite3_reset: %d", ret);
this->param_index = 1;
return *this;
}
@@ -64,7 +67,7 @@ void DBStatement::execute() {
DBQueryRow DBStatement::row() {
int ret = sqlite3_step(this->stmt.get());
- if (ret != SQLITE_ROW)
+ if (ret != SQLITE_ROW && ret != SQLITE_DONE)
throw Exception("sqlite3_step: %d", ret);
return { *this };
@@ -72,13 +75,26 @@ DBQueryRow DBStatement::row() {
DBQueryRow::DBQueryRow(DBStatement & parent) : parent(parent) { }
+
template <>
-const char * DBQueryRow::col<const char*>(int index) {
+const char * DBQueryRow::col<const char*>(int index, const char * const & default_value) {
+ int type = sqlite3_column_type(this->parent.stmt.get(), index);
+ if (type == SQLITE_NULL) return default_value;
return reinterpret_cast<const char *>(sqlite3_column_text(this->parent.stmt.get(), index));
}
+template <>
+const char * DBQueryRow::col<const char*>(int index) {
+ return this->col<const char *>(index, "");
+}
template <>
-int DBQueryRow::col<int>(int index) {
+int DBQueryRow::col<int>(int index, const int & default_value) {
+ int type = sqlite3_column_type(this->parent.stmt.get(), index);
+ if (type == SQLITE_NULL) return default_value;
return sqlite3_column_int(this->parent.stmt.get(), index);
}
+template <>
+int DBQueryRow::col<int>(int index) {
+ return this->col<int>(index, 0);
+}
diff --git a/frontend/DB.h b/frontend/DB.h
index 77b3f7a..f6907bc 100644
--- a/frontend/DB.h
+++ b/frontend/DB.h
@@ -13,6 +13,8 @@ public:
public:
template <typename T>
+ T col(int index, const T & default_value);
+ template <typename T>
T col(int index);
private:
@@ -52,7 +54,7 @@ public:
DBStatement(DB &, const std::string & query);
public:
- DBStatement & unbind();
+ DBStatement & reset();
DBStatement & bind(const std::string & text);
DBStatement & bind(const int & number);
public:
diff --git a/frontend/GameData.cpp b/frontend/GameData.cpp
index b036695..c8f47e3 100644
--- a/frontend/GameData.cpp
+++ b/frontend/GameData.cpp
@@ -34,24 +34,47 @@ static const unordered_map<string, ObjectType> type_map = {
};
Object * GameData::create_object(const string & name) {
- DBStatement query = this->db->prepare("select type, omschrijving from Objecten where naam = ?");
- query.bind(name);
+ static DBStatement query = this->db->prepare(R"(
+ select
+ type,
+ omschrijving,
+ minimumwaarde,
+ maximumwaarde,
+ bescherming
+ from Objecten
+ where lower(naam) = lower(?)
+ limit 1
+ )");
+ query.reset()
+ .bind(name)
+ ;
try {
auto row = query.row();
string type = row.col<const char *>(0);
- const char * description = row.col<const char *>(1);
if (!type_map.contains(type)) throw std::exception();
- return ObjectFactory::create_object(type_map.at(type), name.c_str(), description);
+ return ObjectFactory::create_object({
+ .name = name.c_str(),
+ .description = row.col<const char *>(1),
+ .type = type_map.at(type),
+ .min_value = row.col<int>(2),
+ .max_value = row.col<int>(3),
+ .protection = row.col<int>(4),
+ });
} catch (...) {
return ObjectFactory::create_object(name.c_str());
}
}
void GameData::leaderbord_add(const string & name, unsigned int gold) {
- this->db->prepare("insert into Leaderboard (naam, goudstukken) values (?, ?)")
+ static DBStatement stmt = this->db->prepare(R"(
+ insert into Leaderboard (naam, goudstukken)
+ values (?, ?)
+ )");
+ stmt.reset()
.bind(name)
.bind(gold)
- .execute();
+ ;
+ stmt.execute();
}
diff --git a/frontend/Player.h b/frontend/Player.h
index c590aa9..94ec6a3 100644
--- a/frontend/Player.h
+++ b/frontend/Player.h
@@ -22,8 +22,8 @@ private:
std::string name;
unsigned int health_points = 20;
float attack_chance = 0.4;
+ unsigned int gold = 0;
// TODO: WeaponObject[]
- // TODO: GoldObject[]
// TODO: ArmorObject[]
Location & location;
bool cheating = false;
diff --git a/frontend/cmd/view.cpp b/frontend/cmd/view.cpp
index 7998a4a..0636cac 100644
--- a/frontend/cmd/view.cpp
+++ b/frontend/cmd/view.cpp
@@ -1,5 +1,6 @@
#include "../print.h"
#include "../Player.h"
+#include "../strings.h"
FollowupAction Player::cmd_view(Argv argv) {
if (argv.size() == 0) {
@@ -7,12 +8,12 @@ FollowupAction Player::cmd_view(Argv argv) {
return FollowupAction::NONE;
}
- if (argv[0] == "Zelf") {
+ if (str_lower(argv[0]) == "zelf") {
lprtf("Je hebt %d levenspunten.\n", this->health_points);
- lprtf("Je hebt een aanvalskans van %.0f%%.\n", this->attack_chance * 100);
+ lprtf("Je hebt een aanvalskans van %.0f%%.\n", this->get_attack() * 100);
// TODO: weapon
// TODO: armor
- // TODO: gold
+ lprtf("Je hebt %u goundstuk%s.\n", this->gold, this->gold == 1 ? "" : "ken");
// TODO: inventory
}
diff --git a/frontend/load_dungeon.cpp b/frontend/load_dungeon.cpp
index 41c7fc4..23b4094 100644
--- a/frontend/load_dungeon.cpp
+++ b/frontend/load_dungeon.cpp
@@ -31,7 +31,7 @@ unique_ptr<Dungeon> load_dungeon(const string & filename) {
throw Exception("Kon bestand niet vinden");
}
- xml_parse_result result = doc.load_file(canonical.c_str());
+ xml_parse_result result = doc.load_file(canonical.c_str(), parse_default, encoding_latin1);
if (!result)
throw Exception("Kon XML-bestand niet lezen");
@@ -48,10 +48,10 @@ unique_ptr<Dungeon> load_dungeon(const string & filename) {
map<unsigned, TempData> temp_map;
for (xml_node & tag : locations) {
- const char * name = tag.text().as_string();
- const char * description = tag.child("beschrijving").text().as_string();
-
- Location * location = LocationFactory::create_location(name, description);
+ Location * location = LocationFactory::create_location(
+ tag.text().as_string(),
+ tag.child("beschrijving").text().as_string()
+ );
vector<string> objects_hidden = str_split(tag.attribute("objectenverborgen").as_string(), ";");
for (string & name : objects_hidden) {