aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLoek Le Blansch <loek@pipeframe.xyz>2024-10-30 01:29:58 +0100
committerLoek Le Blansch <loek@pipeframe.xyz>2024-10-30 01:29:58 +0100
commitb9e738502260b8f448289c9888203971c7749c76 (patch)
tree09477251ba49307173a112e0cd5dbdd3633346ce
parente4261302944303781c952943e3290c99e2cabc52 (diff)
WIP SQL gedoe
-rw-r--r--backend/ArmorObject.h2
-rw-r--r--backend/ConsumableObject.h2
-rw-r--r--backend/Enemy.h4
-rw-r--r--backend/GoldObject.h2
-rw-r--r--backend/Location.cpp10
-rw-r--r--backend/Location.h5
-rw-r--r--backend/LocationFactory.h2
-rw-r--r--backend/ObjectFactory.cpp19
-rw-r--r--backend/ObjectFactory.h10
-rw-r--r--backend/WeaponObject.h2
-rw-r--r--frontend/DB.cpp50
-rw-r--r--frontend/DB.h26
-rw-r--r--frontend/GameData.cpp26
-rw-r--r--frontend/GameData.h8
-rw-r--r--frontend/Player.cpp4
-rw-r--r--frontend/load_dungeon.cpp34
-rw-r--r--frontend/main.cpp4
-rw-r--r--frontend/strings.cpp24
-rw-r--r--frontend/strings.h9
19 files changed, 207 insertions, 36 deletions
diff --git a/backend/ArmorObject.h b/backend/ArmorObject.h
index e9c02d2..112997b 100644
--- a/backend/ArmorObject.h
+++ b/backend/ArmorObject.h
@@ -3,6 +3,8 @@
#include "Object.h"
class ArmorObject : public Object {
+ using Object::Object;
+
private:
int protection = 0;
diff --git a/backend/ConsumableObject.h b/backend/ConsumableObject.h
index 0e98674..3b4a2ce 100644
--- a/backend/ConsumableObject.h
+++ b/backend/ConsumableObject.h
@@ -3,5 +3,7 @@
#include "Object.h"
class ConsumableObject : public Object {
+ using Object::Object;
+
};
diff --git a/backend/Enemy.h b/backend/Enemy.h
index dd33090..fb04472 100644
--- a/backend/Enemy.h
+++ b/backend/Enemy.h
@@ -1,5 +1,9 @@
#pragma once
class Enemy {
+private:
+ Enemy() = default;
+ virtual ~Enemy() = default;
+ friend class EnemyFactory;
};
diff --git a/backend/GoldObject.h b/backend/GoldObject.h
index f37b7d9..6f65c1d 100644
--- a/backend/GoldObject.h
+++ b/backend/GoldObject.h
@@ -3,6 +3,8 @@
#include "Object.h"
class GoldObject : public Object {
+ using Object::Object;
+
private:
int count = 0;
};
diff --git a/backend/Location.cpp b/backend/Location.cpp
index 96d06ca..a26d530 100644
--- a/backend/Location.cpp
+++ b/backend/Location.cpp
@@ -37,7 +37,17 @@ Location * Location::get_exit(Direction dir) {
return this->edges[dir];
}
+void Location::add_object(Object * object) {
+ this->objects.push_back(object);
+}
ListRange<Object *> Location::get_objects() {
return this->objects.range();
}
+void Location::add_enemy(Enemy * enemy) {
+ this->enemies.push_back(enemy);
+}
+ListRange<Enemy *> Location::get_enemies() {
+ return this->enemies.range();
+}
+
diff --git a/backend/Location.h b/backend/Location.h
index 8b600bb..4ce2349 100644
--- a/backend/Location.h
+++ b/backend/Location.h
@@ -22,9 +22,12 @@ public:
const char * get_description();
void set_exit(Direction dir, Location * location = nullptr);
Location * get_exit(Direction dir);
+ void add_object(Object *);
ListRange<Object *> get_objects();
+ void add_enemy(Enemy *);
+ ListRange<Enemy *> get_enemies();
-protected:
+private:
Location(const char * name = "", const char * description = "");
virtual ~Location();
friend class LocationFactory;
diff --git a/backend/LocationFactory.h b/backend/LocationFactory.h
index a12bb0e..ba34ff3 100644
--- a/backend/LocationFactory.h
+++ b/backend/LocationFactory.h
@@ -4,6 +4,6 @@
class LocationFactory {
public:
- Location * create_location(const char * name, const char * description);
+ static Location * create_location(const char * name, const char * description);
};
diff --git a/backend/ObjectFactory.cpp b/backend/ObjectFactory.cpp
index efb7742..4a0642b 100644
--- a/backend/ObjectFactory.cpp
+++ b/backend/ObjectFactory.cpp
@@ -1,6 +1,21 @@
#include "ObjectFactory.h"
-Object * ObjectFactory::create_object() {
- return new Object();
+#include "ArmorObject.h"
+#include "ConsumableObject.h"
+#include "GoldObject.h"
+#include "WeaponObject.h"
+
+Object * ObjectFactory::create_object(ObjectType type, const char * name, const char * description) {
+ switch (type) {
+ case ARMOR: return new ArmorObject(name, description);
+ case CONSUMABLE: return new ConsumableObject(name, description);
+ case GOLD: return new GoldObject(name, description);
+ case WEAPON: return new WeaponObject(name, description);
+ }
+ return ObjectFactory::create_object(name, description);
+}
+
+Object * ObjectFactory::create_object(const char * name, const char * description) {
+ return new Object(name, description);
}
diff --git a/backend/ObjectFactory.h b/backend/ObjectFactory.h
index f9a7301..adf960b 100644
--- a/backend/ObjectFactory.h
+++ b/backend/ObjectFactory.h
@@ -2,9 +2,17 @@
#include "Object.h"
+enum ObjectType {
+ ARMOR,
+ CONSUMABLE,
+ GOLD,
+ WEAPON,
+};
+
class ObjectFactory {
public:
- static Object * create_object();
+ static Object * create_object(ObjectType type, const char * name = "", const char * description = "");
+ static Object * create_object(const char * name = "", const char * description = "");
private:
ObjectFactory() = delete;
diff --git a/backend/WeaponObject.h b/backend/WeaponObject.h
index e9ce261..8b1bc58 100644
--- a/backend/WeaponObject.h
+++ b/backend/WeaponObject.h
@@ -3,6 +3,8 @@
#include "Object.h"
class WeaponObject : public Object {
+ using Object::Object;
+
private:
int damage_min;
int damage_max;
diff --git a/frontend/DB.cpp b/frontend/DB.cpp
index 82933b8..d51601e 100644
--- a/frontend/DB.cpp
+++ b/frontend/DB.cpp
@@ -1,9 +1,11 @@
#include "DB.h"
#include "Exception.h"
-DB::DB(const std::string & path) {
+using namespace std;
+
+DB::DB(const string & path) {
sqlite3 * db = NULL;
- int ret = sqlite3_open_v2(path.c_str(), &db, SQLITE_OPEN_READONLY, NULL);
+ int ret = sqlite3_open_v2(path.c_str(), &db, SQLITE_OPEN_READWRITE, NULL);
this->db = {
db,
[] (sqlite3 * db) {
@@ -11,20 +13,52 @@ DB::DB(const std::string & path) {
},
};
if (ret != SQLITE_OK)
- throw Exception("sqlite3_open_v2");
+ throw Exception("sqlite3_open_v2: %d", ret);
+}
+
+DBStatement DB::prepare(const string & query) {
+ return DBStatement(*this, query);
}
-DB::unique_sqlite3_stmt DB::prepare(const std::string & query) {
+DBStatement::DBStatement(DB & db, const string & query) : db(db) {
sqlite3_stmt * stmt = NULL;
- int ret = sqlite3_prepare_v2(this->db.get(), query.c_str(), query.size(), &stmt, NULL);
- unique_sqlite3_stmt uniq_stmt = {
+ int ret = sqlite3_prepare_v2(this->db.db.get(), query.c_str(), query.size(), &stmt, NULL);
+ this->stmt = {
stmt,
[] (sqlite3_stmt * stmt) {
sqlite3_finalize(stmt);
},
};
if (ret != SQLITE_OK)
- throw Exception("sqlite3_prepare_v2");
- return uniq_stmt;
+ throw Exception("sqlite3_prepare_v2: %d", ret);
+}
+
+DBStatement & DBStatement::bind(const string & text) {
+ int ret = sqlite3_bind_text(this->stmt.get(), this->param_index, text.data(), text.size(), NULL);
+ if (ret != SQLITE_OK)
+ throw Exception("sqlite3_bind_text: %d", ret);
+
+ this->param_index++;
+ return *this;
+}
+
+DBStatement & DBStatement::bind(const int & number) {
+ int ret = sqlite3_bind_int(this->stmt.get(), this->param_index, number);
+ if (ret != SQLITE_OK)
+ throw Exception("sqlite3_bind_int: %d", ret);
+
+ this->param_index++;
+ return *this;
+}
+
+DBStatement & DBStatement::unbind() {
+ this->param_index = 1;
+ return *this;
+}
+
+void DBStatement::execute() {
+ int ret = sqlite3_step(this->stmt.get());
+ if (ret != SQLITE_DONE)
+ throw Exception("sqlite3_step: %d", ret);
}
diff --git a/frontend/DB.h b/frontend/DB.h
index b464f9f..5c88940 100644
--- a/frontend/DB.h
+++ b/frontend/DB.h
@@ -4,15 +4,33 @@
#include <functional>
#include <sqlite3.h>
+class DB;
+
+class DBStatement {
+ std::unique_ptr<sqlite3_stmt, std::function<void(sqlite3_stmt*)>> stmt;
+public:
+ DBStatement(DB &, const std::string & query);
+
+public:
+ DBStatement & unbind();
+ DBStatement & bind(const std::string & text);
+ DBStatement & bind(const int & number);
+public:
+ void execute();
+
+private:
+ int param_index = 1;
+ DB & db;
+};
+
class DB {
- typedef std::unique_ptr<sqlite3, std::function<void(sqlite3*)>> unique_sqlite3;
- typedef std::unique_ptr<sqlite3_stmt, std::function<void(sqlite3_stmt*)>> unique_sqlite3_stmt;
+ friend class DBStatement;
public:
DB(const std::string & path);
- unique_sqlite3_stmt prepare(const std::string & query);
+ DBStatement prepare(const std::string & query);
private:
- unique_sqlite3 db = NULL;
+ std::unique_ptr<sqlite3, std::function<void(sqlite3*)>> db = NULL;
};
diff --git a/frontend/GameData.cpp b/frontend/GameData.cpp
index ad22aa0..0cf6a1d 100644
--- a/frontend/GameData.cpp
+++ b/frontend/GameData.cpp
@@ -1,5 +1,10 @@
#include <memory>
+#include "backend/Enemy.h"
+#include "backend/EnemyFactory.h"
+#include "backend/Object.h"
+#include "backend/ObjectFactory.h"
+
#include "GameData.h"
using namespace std;
@@ -13,3 +18,24 @@ GameData::GameData() {
this->db = make_unique<DB>("kerkersendraken.db");
}
+Enemy * GameData::create_enemy(const string & name) {
+ Enemy * enemy = EnemyFactory::create_enemy();
+ return enemy;
+}
+
+Object * GameData::create_object(const string & name) {
+ DBStatement query = this->db->prepare("select type from Objecten where naam = ?");
+ query.bind(name);
+ // TODO: uhhhhhhhhh data ophalen
+
+ Object * object = ObjectFactory::create_object();
+ return object;
+}
+
+void GameData::leaderbord_add(const string & name, unsigned int gold) {
+ this->db->prepare("insert into Leaderboard (naam, goudstukken) values (?, ?)")
+ .bind(name)
+ .bind(gold)
+ .execute();
+}
+
diff --git a/frontend/GameData.h b/frontend/GameData.h
index d4c3712..383de00 100644
--- a/frontend/GameData.h
+++ b/frontend/GameData.h
@@ -4,10 +4,18 @@
#include "DB.h"
+class Enemy;
+class Object;
+
class GameData {
public:
static GameData & get_instance();
+public:
+ Enemy * create_enemy(const std::string & name);
+ Object * create_object(const std::string & name);
+ void leaderbord_add(const std::string & name, unsigned int gold);
+
private:
GameData();
virtual ~GameData() = default;
diff --git a/frontend/Player.cpp b/frontend/Player.cpp
index 9ecbd08..d9974f7 100644
--- a/frontend/Player.cpp
+++ b/frontend/Player.cpp
@@ -43,12 +43,12 @@ void Player::cmdset_death() {
FollowupAction Player::cmd(Argv argv) {
if (argv.size() == 0) return FollowupAction::NONE;
- string cmd = argv_pop(argv);
+ string cmd = str_title(argv_pop(argv));
if (this->cmds.contains(cmd))
return (this->*cmds.at(cmd))(argv);
- print_string(strings::UNKNOWN_CMD);
+ str_print(strings::UNKNOWN_CMD);
return FollowupAction::NONE;
}
diff --git a/frontend/load_dungeon.cpp b/frontend/load_dungeon.cpp
index ff68109..41c7fc4 100644
--- a/frontend/load_dungeon.cpp
+++ b/frontend/load_dungeon.cpp
@@ -10,6 +10,8 @@
#include "load_dungeon.h"
#include "Exception.h"
+#include "GameData.h"
+#include "backend/Object.h"
#include "strings.h"
using namespace std;
@@ -37,28 +39,46 @@ unique_ptr<Dungeon> load_dungeon(const string & filename) {
if (!locations)
throw Exception("XML-bestand mist een <locaties> tag");
- LocationFactory factory;
+ GameData & gamedata = GameData::get_instance();
+
struct TempData {
Location * location;
unsigned edges[4];
};
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();
- // vector<string> objects_hidden = split_string(tag.attribute("objectenverborgen").as_string(), ";");
- // vector<string> objects_visible = split_string(tag.attribute("objectenzichtbaar").as_string(), ";");
- // vector<string> enemies = split_string(tag.attribute("vijand").as_string(), ";");
+ Location * location = LocationFactory::create_location(name, description);
- Location * location = factory.create_location(name, description);
+ vector<string> objects_hidden = str_split(tag.attribute("objectenverborgen").as_string(), ";");
+ for (string & name : objects_hidden) {
+ Object * object = gamedata.create_object(name);
+ object->set_hidden(true);
+ location->add_object(object);
+ }
+ vector<string> objects_visible = str_split(tag.attribute("objectenzichtbaar").as_string(), ";");
+ for (string & name : objects_visible) {
+ Object * object = gamedata.create_object(name);
+ object->set_hidden(false);
+ location->add_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 = {
[Direction::NORTH] = tag.attribute("noord").as_uint(0),
- [Direction::EAST] = tag.attribute("oost").as_uint(0),
+ [Direction::EAST] = tag.attribute("oost").as_uint(0),
[Direction::SOUTH] = tag.attribute("zuid").as_uint(0),
- [Direction::WEST] = tag.attribute("west").as_uint(0),
+ [Direction::WEST] = tag.attribute("west").as_uint(0),
},
};
dungeon->add_location(location);
diff --git a/frontend/main.cpp b/frontend/main.cpp
index a5514bd..deacdc5 100644
--- a/frontend/main.cpp
+++ b/frontend/main.cpp
@@ -16,7 +16,7 @@ using namespace std;
static unique_ptr<Dungeon> make_dungeon() noexcept {
while (1) {
- print_string(strings::INTRO);
+ str_print(strings::INTRO);
string filename = rl();
try {
if (filename.size() == 0) {
@@ -37,7 +37,7 @@ FollowupAction game_main() {
while (1) {
string line = rl();
if (line.length() == 0) continue;
- vector<string> argv = split_string(line, " ");
+ vector<string> argv = str_split(line, " ");
FollowupAction action = player.cmd(argv);
switch (action) {
diff --git a/frontend/strings.cpp b/frontend/strings.cpp
index bb4a419..70fed85 100644
--- a/frontend/strings.cpp
+++ b/frontend/strings.cpp
@@ -1,13 +1,15 @@
+#include <algorithm>
+
#include "strings.h"
#include "print.h"
using namespace std;
-void print_string(const char * str) {
- lprtf("%s\n", wrap_string(str).c_str());
+void str_print(const char * str) {
+ lprtf("%s\n", str_wrap(str).c_str());
}
-string wrap_string(const char * str) {
+string str_wrap(const char * str) {
string out;
for (; *str != '\0'; str++) {
@@ -27,7 +29,8 @@ string wrap_string(const char * str) {
return out;
}
-vector<string> split_string(const string & src, const string & delim) {
+vector<string> str_split(const string & src, const string & delim) {
+ if (src.size() == 0) return {};
vector<string> out;
size_t start = 0;
size_t end = src.find(delim);
@@ -42,3 +45,16 @@ vector<string> split_string(const string & src, const string & delim) {
return out;
}
+string str_lower(const string & input) {
+ string out = input;
+ transform(out.begin(), out.end(), out.begin(), [](unsigned char c){ return tolower(c); });
+ return out;
+}
+
+string str_title(const string & input) {
+ if (input.size() == 0) return "";
+ string out = str_lower(input);
+ out[0] = toupper(out[0]);
+ return out;
+}
+
diff --git a/frontend/strings.h b/frontend/strings.h
index 678667e..affc835 100644
--- a/frontend/strings.h
+++ b/frontend/strings.h
@@ -15,9 +15,10 @@ bestaande acties te zien.)";
}
-void print_string(const char *);
+void str_print(const char *);
-std::string wrap_string(const char *);
-
-std::vector<std::string> split_string(const std::string & src, const std::string & delim);
+std::string str_wrap(const char *);
+std::vector<std::string> str_split(const std::string & src, const std::string & delim);
+std::string str_lower(const std::string & input);
+std::string str_title(const std::string & input);