more SQL
This commit is contained in:
@@ -47,11 +47,17 @@ FetchContent_Declare(
|
||||
GIT_TAG master
|
||||
)
|
||||
|
||||
FetchContent_Declare(
|
||||
nlohmann_json
|
||||
GIT_REPOSITORY https://github.com/nlohmann/json.git
|
||||
GIT_TAG master
|
||||
)
|
||||
|
||||
# Enable exceptions in rapidyaml
|
||||
set(RYML_DEFAULT_CALLBACK_USES_EXCEPTIONS ON CACHE BOOL "" FORCE)
|
||||
set(RYML_DBG OFF CACHE BOOL "" FORCE)
|
||||
|
||||
FetchContent_MakeAvailable(rapidyaml glm tinyxml2 sqlitecpp rapidjson)
|
||||
FetchContent_MakeAvailable(rapidyaml glm tinyxml2 sqlitecpp rapidjson nlohmann_json)
|
||||
|
||||
# Create the main executable
|
||||
add_executable(${PROJECT_NAME} ${SOURCES})
|
||||
@@ -60,6 +66,7 @@ add_executable(${PROJECT_NAME} ${SOURCES})
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC ryml::ryml)
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC tinyxml2::tinyxml2)
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC SQLiteCpp)
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC nlohmann_json::nlohmann_json)
|
||||
|
||||
# Add include directories for rapidyaml
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE ${rapidyaml_SOURCE_DIR}/src)
|
||||
|
||||
46
include/database_generation/populate_configs.h
Normal file
46
include/database_generation/populate_configs.h
Normal file
@@ -0,0 +1,46 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <SQLiteCpp/SQLiteCpp.h>
|
||||
|
||||
#include "configs/achievements.h"
|
||||
#include "configs/harvestables.h"
|
||||
#include "configs/items.h"
|
||||
#include "configs/loot.h"
|
||||
#include "configs/npcs.h"
|
||||
#include "configs/shops.h"
|
||||
|
||||
namespace cursebreaker {
|
||||
|
||||
// Items
|
||||
void CreateItemTables(SQLite::Database& db);
|
||||
void PopulateItemEntry(SQLite::Database& db, const Item& item);
|
||||
void PopulateItemDB(SQLite::Database& db, const std::vector<Item>& items);
|
||||
|
||||
// Achievements
|
||||
void CreateAchievementTables(SQLite::Database& db);
|
||||
void PopulateAchievementEntry(SQLite::Database& db, const Achievement& achievement);
|
||||
void PopulateAchievementDB(SQLite::Database& db, const std::vector<Achievement>& achievements);
|
||||
|
||||
// Harvestables
|
||||
void CreateHarvestableTables(SQLite::Database& db);
|
||||
void PopulateHarvestableEntry(SQLite::Database& db, const Harvestable& harvestable);
|
||||
void PopulateHarvestableDB(SQLite::Database& db, const std::vector<Harvestable>& harvestables);
|
||||
|
||||
// Loot
|
||||
void CreateLootTables(SQLite::Database& db);
|
||||
void PopulateLootTableEntry(SQLite::Database& db, const LootTable& lootTable);
|
||||
void PopulateLootDB(SQLite::Database& db, const std::vector<LootTable>& lootTables);
|
||||
|
||||
// NPCs
|
||||
void CreateNPCTables(SQLite::Database& db);
|
||||
void PopulateNPCEntry(SQLite::Database& db, const NPC& npc);
|
||||
void PopulateNPCDB(SQLite::Database& db, const std::vector<NPC>& npcs);
|
||||
|
||||
// Shops
|
||||
void CreateShopTables(SQLite::Database& db);
|
||||
void PopulateShopEntry(SQLite::Database& db, const Shop& shop);
|
||||
void PopulateShopDB(SQLite::Database& db, const std::vector<Shop>& shops);
|
||||
|
||||
} // namespace cursebreaker
|
||||
506
src/database_generation/populate_configs.cpp
Normal file
506
src/database_generation/populate_configs.cpp
Normal file
@@ -0,0 +1,506 @@
|
||||
#include "database_generation/populate_configs.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
namespace cursebreaker {
|
||||
|
||||
void CreateItemTables(SQLite::Database& db) {
|
||||
// Main items table
|
||||
std::string createItemsTableSQL = R"(
|
||||
CREATE TABLE IF NOT EXISTS items (
|
||||
id INTEGER PRIMARY KEY,
|
||||
price INTEGER,
|
||||
abilityid INTEGER,
|
||||
learnabilityid INTEGER,
|
||||
skill INTEGER,
|
||||
category INTEGER,
|
||||
slot INTEGER,
|
||||
tool INTEGER,
|
||||
generation INTEGER,
|
||||
level INTEGER,
|
||||
foodlevel INTEGER,
|
||||
foodamount INTEGER,
|
||||
foodfrequency INTEGER,
|
||||
foodtime INTEGER,
|
||||
maxstack INTEGER,
|
||||
book INTEGER,
|
||||
stackable BOOLEAN,
|
||||
twohanded BOOLEAN,
|
||||
undroppable BOOLEAN,
|
||||
hidemilestone BOOLEAN,
|
||||
name TEXT,
|
||||
description TEXT,
|
||||
comment TEXT
|
||||
);
|
||||
)";
|
||||
|
||||
// Item stats table
|
||||
std::string createItemStatsTableSQL = R"(
|
||||
CREATE TABLE IF NOT EXISTS item_stats (
|
||||
item_id INTEGER,
|
||||
stat_type INTEGER,
|
||||
value INTEGER,
|
||||
is_percentage BOOLEAN,
|
||||
FOREIGN KEY (item_id) REFERENCES items(id) ON DELETE CASCADE
|
||||
);
|
||||
)";
|
||||
|
||||
// Item craftings table
|
||||
std::string createItemCraftingsTableSQL = R"(
|
||||
CREATE TABLE IF NOT EXISTS item_craftings (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
item_id INTEGER,
|
||||
workbench INTEGER,
|
||||
crafting_skill INTEGER,
|
||||
checks TEXT,
|
||||
FOREIGN KEY (item_id) REFERENCES items(id) ON DELETE CASCADE
|
||||
);
|
||||
)";
|
||||
|
||||
// Crafting items table
|
||||
std::string createCraftingItemsTableSQL = R"(
|
||||
CREATE TABLE IF NOT EXISTS crafting_items (
|
||||
crafting_id INTEGER,
|
||||
required_item_id INTEGER,
|
||||
amount INTEGER,
|
||||
FOREIGN KEY (crafting_id) REFERENCES item_craftings(id) ON DELETE CASCADE
|
||||
);
|
||||
)";
|
||||
|
||||
db.exec(createItemsTableSQL);
|
||||
db.exec(createItemStatsTableSQL);// TODO: add indices
|
||||
db.exec(createItemCraftingsTableSQL);
|
||||
db.exec(createCraftingItemsTableSQL);
|
||||
std::cout << "Created items-related tables." << std::endl;
|
||||
}
|
||||
|
||||
void PopulateItemEntry(SQLite::Database& db, const Item& item) {
|
||||
// Insert into main items table
|
||||
SQLite::Statement insertItem(db, R"(
|
||||
INSERT INTO items (
|
||||
id, price, abilityid, learnabilityid, skill, category, slot, tool, generation,
|
||||
level, foodlevel, foodamount, foodfrequency, foodtime, maxstack, book,
|
||||
stackable, twohanded, undroppable, hidemilestone, name, description, comment
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);
|
||||
)");
|
||||
|
||||
insertItem.bind(1, item.id);
|
||||
insertItem.bind(2, item.price);
|
||||
insertItem.bind(3, item.abilityid);
|
||||
insertItem.bind(4, item.learnabilityid);
|
||||
insertItem.bind(5, static_cast<int>(item.skill));
|
||||
insertItem.bind(6, static_cast<int>(item.category));
|
||||
insertItem.bind(7, static_cast<int>(item.slot));
|
||||
insertItem.bind(8, static_cast<int>(item.tool));
|
||||
insertItem.bind(9, static_cast<int>(item.generation));
|
||||
insertItem.bind(10, item.level);
|
||||
insertItem.bind(11, item.foodlevel);
|
||||
insertItem.bind(12, item.foodamount);
|
||||
insertItem.bind(13, item.foodfrequency);
|
||||
insertItem.bind(14, item.foodtime);
|
||||
insertItem.bind(15, item.maxstack);
|
||||
insertItem.bind(16, item.book);
|
||||
insertItem.bind(17, item.stackable);
|
||||
insertItem.bind(18, item.twohanded);
|
||||
insertItem.bind(19, item.undroppable);
|
||||
insertItem.bind(20, item.hidemilestone);
|
||||
insertItem.bind(21, item.name);
|
||||
insertItem.bind(22, item.description);
|
||||
insertItem.bind(23, item.comment);
|
||||
|
||||
insertItem.exec();
|
||||
|
||||
// Insert stats
|
||||
SQLite::Statement insertStat(db, "INSERT INTO item_stats (item_id, stat_type, value, is_percentage) VALUES (?, ?, ?, ?);");
|
||||
for (const auto& stat : item.stats) {
|
||||
insertStat.bind(1, item.id);
|
||||
insertStat.bind(2, static_cast<int>(stat.type));
|
||||
insertStat.bind(3, stat.value);
|
||||
insertStat.bind(4, stat.isPercentage);
|
||||
insertStat.exec();
|
||||
insertStat.reset();
|
||||
}
|
||||
|
||||
// Insert craftings
|
||||
SQLite::Statement insertCrafting(db, "INSERT INTO item_craftings (item_id, workbench, crafting_skill, checks) VALUES (?, ?, ?, ?);");
|
||||
SQLite::Statement insertCraftingItem(db, "INSERT INTO crafting_items (crafting_id, required_item_id, amount) VALUES (?, ?, ?);");
|
||||
for (const auto& crafting : item.craftings) {
|
||||
insertCrafting.bind(1, item.id);
|
||||
insertCrafting.bind(2, static_cast<int>(crafting.workbench));
|
||||
insertCrafting.bind(3, static_cast<int>(crafting.craftingskill));
|
||||
insertCrafting.bind(4, crafting.checks);
|
||||
insertCrafting.exec();
|
||||
long long craftingId = db.getLastInsertRowid();
|
||||
insertCrafting.reset();
|
||||
|
||||
for (const auto& reqItem : crafting.craftingitems) {
|
||||
insertCraftingItem.bind(1, static_cast<int64_t>(craftingId));
|
||||
insertCraftingItem.bind(2, reqItem.itemId);
|
||||
insertCraftingItem.bind(3, reqItem.amount);
|
||||
insertCraftingItem.exec();
|
||||
insertCraftingItem.reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PopulateItemDB(SQLite::Database& db, const std::vector<Item>& items) {
|
||||
CreateItemTables(db);
|
||||
for (const auto& item : items) {
|
||||
PopulateItemEntry(db, item);
|
||||
}
|
||||
std::cout << "Populated " << items.size() << " items into the database." << std::endl;
|
||||
}
|
||||
|
||||
void CreateAchievementTables(SQLite::Database& db) {
|
||||
// Main achievements table
|
||||
std::string createAchievementsTableSQL = R"(
|
||||
CREATE TABLE IF NOT EXISTS achievements (
|
||||
id INTEGER PRIMARY KEY,
|
||||
points INTEGER,
|
||||
category INTEGER,
|
||||
name TEXT,
|
||||
description TEXT,
|
||||
icon TEXT
|
||||
);
|
||||
)";
|
||||
|
||||
// Achievement requirements table
|
||||
std::string createAchievementRequirementsTableSQL = R"(
|
||||
CREATE TABLE IF NOT EXISTS achievement_requirements (
|
||||
achievement_id INTEGER,
|
||||
action INTEGER,
|
||||
target_id INTEGER,
|
||||
count INTEGER,
|
||||
description TEXT,
|
||||
FOREIGN KEY (achievement_id) REFERENCES achievements(id) ON DELETE CASCADE
|
||||
);
|
||||
)";
|
||||
|
||||
db.exec(createAchievementsTableSQL);
|
||||
db.exec(createAchievementRequirementsTableSQL);
|
||||
std::cout << "Created achievement-related tables." << std::endl;
|
||||
}
|
||||
|
||||
void PopulateAchievementEntry(SQLite::Database& db, const Achievement& achievement) {
|
||||
// Insert into main achievements table
|
||||
SQLite::Statement insertAchievement(db, R"(
|
||||
INSERT INTO achievements (
|
||||
id, points, category, name, description, icon
|
||||
) VALUES (?, ?, ?, ?, ?, ?);
|
||||
)");
|
||||
|
||||
insertAchievement.bind(1, achievement.id);
|
||||
insertAchievement.bind(2, achievement.points);
|
||||
insertAchievement.bind(3, achievement.category);
|
||||
insertAchievement.bind(4, achievement.name);
|
||||
insertAchievement.bind(5, achievement.description);
|
||||
insertAchievement.bind(6, achievement.icon);
|
||||
|
||||
insertAchievement.exec();
|
||||
|
||||
// Insert requirements
|
||||
SQLite::Statement insertRequirement(db, "INSERT INTO achievement_requirements (achievement_id, action, target_id, count, description) VALUES (?, ?, ?, ?, ?);");
|
||||
for (const auto& req : achievement.requirements) {
|
||||
insertRequirement.bind(1, achievement.id);
|
||||
insertRequirement.bind(2, static_cast<int>(req.action));
|
||||
insertRequirement.bind(3, req.targetId);
|
||||
insertRequirement.bind(4, req.count);
|
||||
insertRequirement.bind(5, req.description);
|
||||
insertRequirement.exec();
|
||||
insertRequirement.reset();
|
||||
}
|
||||
}
|
||||
|
||||
void PopulateAchievementDB(SQLite::Database& db, const std::vector<Achievement>& achievements) {
|
||||
CreateAchievementTables(db);
|
||||
for (const auto& achievement : achievements) {
|
||||
PopulateAchievementEntry(db, achievement);
|
||||
}
|
||||
std::cout << "Populated " << achievements.size() << " achievements into the database." << std::endl;
|
||||
}
|
||||
|
||||
void CreateHarvestableTables(SQLite::Database& db) {
|
||||
// Main harvestables table
|
||||
std::string createHarvestablesTableSQL = R"(
|
||||
CREATE TABLE IF NOT EXISTS harvestables (
|
||||
id INTEGER PRIMARY KEY,
|
||||
level INTEGER,
|
||||
respawn_time INTEGER,
|
||||
skill INTEGER,
|
||||
name TEXT,
|
||||
description TEXT
|
||||
);
|
||||
)";
|
||||
|
||||
// Harvestable loot table
|
||||
std::string createHarvestableLootTableSQL = R"(
|
||||
CREATE TABLE IF NOT EXISTS harvestable_loot (
|
||||
harvestable_id INTEGER,
|
||||
item_id INTEGER,
|
||||
amount INTEGER,
|
||||
chance INTEGER,
|
||||
FOREIGN KEY (harvestable_id) REFERENCES harvestables(id) ON DELETE CASCADE
|
||||
);
|
||||
)";
|
||||
|
||||
db.exec(createHarvestablesTableSQL);
|
||||
db.exec(createHarvestableLootTableSQL);
|
||||
std::cout << "Created harvestable-related tables." << std::endl;
|
||||
}
|
||||
|
||||
void PopulateHarvestableEntry(SQLite::Database& db, const Harvestable& harvestable) {
|
||||
// Insert into main harvestables table
|
||||
SQLite::Statement insertHarvestable(db, R"(
|
||||
INSERT INTO harvestables (
|
||||
id, level, respawn_time, skill, name, description
|
||||
) VALUES (?, ?, ?, ?, ?, ?);
|
||||
)");
|
||||
|
||||
insertHarvestable.bind(1, harvestable.id);
|
||||
insertHarvestable.bind(2, harvestable.level);
|
||||
insertHarvestable.bind(3, harvestable.respawnTime);
|
||||
insertHarvestable.bind(4, static_cast<int>(harvestable.skill));
|
||||
insertHarvestable.bind(5, harvestable.name);
|
||||
insertHarvestable.bind(6, harvestable.description);
|
||||
|
||||
insertHarvestable.exec();
|
||||
|
||||
// Insert loot
|
||||
SQLite::Statement insertLoot(db, "INSERT INTO harvestable_loot (harvestable_id, item_id, amount, chance) VALUES (?, ?, ?, ?);");
|
||||
for (const auto& entry : harvestable.loot) {
|
||||
insertLoot.bind(1, harvestable.id);
|
||||
insertLoot.bind(2, entry.itemId);
|
||||
insertLoot.bind(3, entry.amount);
|
||||
insertLoot.bind(4, entry.chance);
|
||||
insertLoot.exec();
|
||||
insertLoot.reset();
|
||||
}
|
||||
}
|
||||
|
||||
void PopulateHarvestableDB(SQLite::Database& db, const std::vector<Harvestable>& harvestables) {
|
||||
CreateHarvestableTables(db);
|
||||
for (const auto& harvestable : harvestables) {
|
||||
PopulateHarvestableEntry(db, harvestable);
|
||||
}
|
||||
std::cout << "Populated " << harvestables.size() << " harvestables into the database." << std::endl;
|
||||
}
|
||||
|
||||
void CreateLootTables(SQLite::Database& db) {
|
||||
// Main loot_tables table
|
||||
std::string createLootTablesTableSQL = R"(
|
||||
CREATE TABLE IF NOT EXISTS loot_tables (
|
||||
id INTEGER PRIMARY KEY,
|
||||
name TEXT,
|
||||
description TEXT
|
||||
);
|
||||
)";
|
||||
|
||||
// Loot entries table
|
||||
std::string createLootEntriesTableSQL = R"(
|
||||
CREATE TABLE IF NOT EXISTS loot_entries (
|
||||
loot_table_id INTEGER,
|
||||
item_id INTEGER,
|
||||
min_amount INTEGER,
|
||||
max_amount INTEGER,
|
||||
chance INTEGER,
|
||||
level INTEGER,
|
||||
FOREIGN KEY (loot_table_id) REFERENCES loot_tables(id) ON DELETE CASCADE
|
||||
);
|
||||
)";
|
||||
|
||||
db.exec(createLootTablesTableSQL);
|
||||
db.exec(createLootEntriesTableSQL);
|
||||
std::cout << "Created loot-related tables." << std::endl;
|
||||
}
|
||||
|
||||
void PopulateLootTableEntry(SQLite::Database& db, const LootTable& lootTable) {
|
||||
// Insert into main loot_tables table
|
||||
SQLite::Statement insertLootTable(db, R"(
|
||||
INSERT INTO loot_tables (
|
||||
id, name, description
|
||||
) VALUES (?, ?, ?);
|
||||
)");
|
||||
|
||||
insertLootTable.bind(1, lootTable.id);
|
||||
insertLootTable.bind(2, lootTable.name);
|
||||
insertLootTable.bind(3, lootTable.description);
|
||||
|
||||
insertLootTable.exec();
|
||||
|
||||
// Insert entries
|
||||
SQLite::Statement insertEntry(db, "INSERT INTO loot_entries (loot_table_id, item_id, min_amount, max_amount, chance, level) VALUES (?, ?, ?, ?, ?, ?);");
|
||||
for (const auto& entry : lootTable.entries) {
|
||||
insertEntry.bind(1, lootTable.id);
|
||||
insertEntry.bind(2, entry.itemId);
|
||||
insertEntry.bind(3, entry.minAmount);
|
||||
insertEntry.bind(4, entry.maxAmount);
|
||||
insertEntry.bind(5, entry.chance);
|
||||
insertEntry.bind(6, entry.level);
|
||||
insertEntry.exec();
|
||||
insertEntry.reset();
|
||||
}
|
||||
}
|
||||
|
||||
void PopulateLootDB(SQLite::Database& db, const std::vector<LootTable>& lootTables) {
|
||||
CreateLootTables(db);
|
||||
for (const auto& lootTable : lootTables) {
|
||||
PopulateLootTableEntry(db, lootTable);
|
||||
}
|
||||
std::cout << "Populated " << lootTables.size() << " loot tables into the database." << std::endl;
|
||||
}
|
||||
|
||||
void CreateNPCTables(SQLite::Database& db) {
|
||||
// Main npcs table
|
||||
std::string createNPCsTableSQL = R"(
|
||||
CREATE TABLE IF NOT EXISTS npcs (
|
||||
id INTEGER PRIMARY KEY,
|
||||
level INTEGER,
|
||||
health INTEGER,
|
||||
mana INTEGER,
|
||||
experience INTEGER,
|
||||
loot_table_id INTEGER,
|
||||
name TEXT,
|
||||
description TEXT,
|
||||
faction TEXT
|
||||
);
|
||||
)";
|
||||
|
||||
// NPC stats table
|
||||
std::string createNPCStatsTableSQL = R"(
|
||||
CREATE TABLE IF NOT EXISTS npc_stats (
|
||||
npc_id INTEGER,
|
||||
stat_type INTEGER,
|
||||
value INTEGER,
|
||||
FOREIGN KEY (npc_id) REFERENCES npcs(id) ON DELETE CASCADE
|
||||
);
|
||||
)";
|
||||
|
||||
// NPC loot items table
|
||||
std::string createNPCLootItemsTableSQL = R"(
|
||||
CREATE TABLE IF NOT EXISTS npc_loot_items (
|
||||
npc_id INTEGER,
|
||||
item_id INTEGER,
|
||||
FOREIGN KEY (npc_id) REFERENCES npcs(id) ON DELETE CASCADE
|
||||
);
|
||||
)";
|
||||
|
||||
db.exec(createNPCsTableSQL);
|
||||
db.exec(createNPCStatsTableSQL);
|
||||
db.exec(createNPCLootItemsTableSQL);
|
||||
std::cout << "Created NPC-related tables." << std::endl;
|
||||
}
|
||||
|
||||
void PopulateNPCEntry(SQLite::Database& db, const NPC& npc) {
|
||||
// Insert into main npcs table
|
||||
SQLite::Statement insertNPC(db, R"(
|
||||
INSERT INTO npcs (
|
||||
id, level, health, mana, experience, loot_table_id, name, description, faction
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?);
|
||||
)");
|
||||
|
||||
insertNPC.bind(1, npc.id);
|
||||
insertNPC.bind(2, npc.level);
|
||||
insertNPC.bind(3, npc.health);
|
||||
insertNPC.bind(4, npc.mana);
|
||||
insertNPC.bind(5, npc.experience);
|
||||
insertNPC.bind(6, npc.lootTableId);
|
||||
insertNPC.bind(7, npc.name);
|
||||
insertNPC.bind(8, npc.description);
|
||||
insertNPC.bind(9, npc.faction);
|
||||
|
||||
insertNPC.exec();
|
||||
|
||||
// Insert stats
|
||||
SQLite::Statement insertStat(db, "INSERT INTO npc_stats (npc_id, stat_type, value) VALUES (?, ?, ?);");
|
||||
for (const auto& stat : npc.stats) {
|
||||
insertStat.bind(1, npc.id);
|
||||
insertStat.bind(2, static_cast<int>(stat.type));
|
||||
insertStat.bind(3, stat.value);
|
||||
insertStat.exec();
|
||||
insertStat.reset();
|
||||
}
|
||||
|
||||
// Insert loot items
|
||||
SQLite::Statement insertLootItem(db, "INSERT INTO npc_loot_items (npc_id, item_id) VALUES (?, ?);");
|
||||
for (const auto& itemId : npc.lootItems) {
|
||||
insertLootItem.bind(1, npc.id);
|
||||
insertLootItem.bind(2, itemId);
|
||||
insertLootItem.exec();
|
||||
insertLootItem.reset();
|
||||
}
|
||||
}
|
||||
|
||||
void PopulateNPCDB(SQLite::Database& db, const std::vector<NPC>& npcs) {
|
||||
CreateNPCTables(db);
|
||||
for (const auto& npc : npcs) {
|
||||
PopulateNPCEntry(db, npc);
|
||||
}
|
||||
std::cout << "Populated " << npcs.size() << " NPCs into the database." << std::endl;
|
||||
}
|
||||
|
||||
void CreateShopTables(SQLite::Database& db) {
|
||||
// Main shops table
|
||||
std::string createShopsTableSQL = R"(
|
||||
CREATE TABLE IF NOT EXISTS shops (
|
||||
id INTEGER PRIMARY KEY,
|
||||
name TEXT,
|
||||
description TEXT,
|
||||
location TEXT
|
||||
);
|
||||
)";
|
||||
|
||||
// Shop inventory table
|
||||
std::string createShopInventoryTableSQL = R"(
|
||||
CREATE TABLE IF NOT EXISTS shop_inventory (
|
||||
shop_id INTEGER,
|
||||
item_id INTEGER,
|
||||
price INTEGER,
|
||||
stock INTEGER,
|
||||
level_required INTEGER,
|
||||
FOREIGN KEY (shop_id) REFERENCES shops(id) ON DELETE CASCADE
|
||||
);
|
||||
)";
|
||||
|
||||
db.exec(createShopsTableSQL);
|
||||
db.exec(createShopInventoryTableSQL);
|
||||
std::cout << "Created shop-related tables." << std::endl;
|
||||
}
|
||||
|
||||
void PopulateShopEntry(SQLite::Database& db, const Shop& shop) {
|
||||
// Insert into main shops table
|
||||
SQLite::Statement insertShop(db, R"(
|
||||
INSERT INTO shops (
|
||||
id, name, description, location
|
||||
) VALUES (?, ?, ?, ?);
|
||||
)");
|
||||
|
||||
insertShop.bind(1, shop.id);
|
||||
insertShop.bind(2, shop.name);
|
||||
insertShop.bind(3, shop.description);
|
||||
insertShop.bind(4, shop.location);
|
||||
|
||||
insertShop.exec();
|
||||
|
||||
// Insert inventory
|
||||
SQLite::Statement insertItem(db, "INSERT INTO shop_inventory (shop_id, item_id, price, stock, level_required) VALUES (?, ?, ?, ?, ?);");
|
||||
for (const auto& item : shop.inventory) {
|
||||
insertItem.bind(1, shop.id);
|
||||
insertItem.bind(2, item.itemId);
|
||||
insertItem.bind(3, item.price);
|
||||
insertItem.bind(4, item.stock);
|
||||
insertItem.bind(5, item.levelRequired);
|
||||
insertItem.exec();
|
||||
insertItem.reset();
|
||||
}
|
||||
}
|
||||
|
||||
void PopulateShopDB(SQLite::Database& db, const std::vector<Shop>& shops) {
|
||||
CreateShopTables(db);
|
||||
for (const auto& shop : shops) {
|
||||
PopulateShopEntry(db, shop);
|
||||
}
|
||||
std::cout << "Populated " << shops.size() << " shops into the database." << std::endl;
|
||||
}
|
||||
|
||||
} // namespace cursebreaker
|
||||
73
src/main.cpp
73
src/main.cpp
@@ -1,11 +1,19 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
#include <sqlite3.h>
|
||||
#include <SQLiteCpp/SQLiteCpp.h>
|
||||
|
||||
#include "project_parser.h"
|
||||
#include "tree_builder.h"
|
||||
#include "assets/scene.hpp"
|
||||
#include "configs/items.h"
|
||||
#include "configs/achievements.h"
|
||||
#include "configs/harvestables.h"
|
||||
#include "configs/loot.h"
|
||||
#include "configs/npcs.h"
|
||||
#include "configs/shops.h"
|
||||
#include "database_generation/populate_configs.h"
|
||||
|
||||
using namespace cursebreaker;
|
||||
|
||||
@@ -19,5 +27,70 @@ int main() {
|
||||
BuildTree(scene);
|
||||
}
|
||||
|
||||
// Load configs from XML
|
||||
std::string configPath = "../../CBAssets/_GameAssets/";
|
||||
loadItemsFromXML(configPath + "items.xml");
|
||||
loadAchievementsFromXML(configPath + "achievements.xml");
|
||||
loadHarvestablesFromXML(configPath + "harvestables.xml");
|
||||
loadLootTablesFromXML(configPath + "loot.xml");
|
||||
loadNPCsFromXML(configPath + "npcs.xml");
|
||||
loadShopsFromXML(configPath + "shops.xml");
|
||||
|
||||
// Create in-memory database
|
||||
SQLite::Database memDB(":memory:", SQLite::OPEN_READWRITE | SQLite::OPEN_CREATE);
|
||||
|
||||
// Populate database with configs
|
||||
std::vector<Item> itemsVec;
|
||||
for (const auto& pair : getAllItems()) {
|
||||
itemsVec.push_back(pair.second);
|
||||
}
|
||||
PopulateItemDB(memDB, itemsVec);
|
||||
|
||||
std::vector<Achievement> achievementsVec;
|
||||
for (const auto& pair : getAllAchievements()) {
|
||||
achievementsVec.push_back(pair.second);
|
||||
}
|
||||
PopulateAchievementDB(memDB, achievementsVec);
|
||||
|
||||
std::vector<Harvestable> harvestablesVec;
|
||||
for (const auto& pair : getAllHarvestables()) {
|
||||
harvestablesVec.push_back(pair.second);
|
||||
}
|
||||
PopulateHarvestableDB(memDB, harvestablesVec);
|
||||
|
||||
std::vector<LootTable> lootVec;
|
||||
for (const auto& pair : getAllLootTables()) {
|
||||
lootVec.push_back(pair.second);
|
||||
}
|
||||
PopulateLootDB(memDB, lootVec);
|
||||
|
||||
std::vector<NPC> npcsVec;
|
||||
for (const auto& pair : getAllNPCs()) {
|
||||
npcsVec.push_back(pair.second);
|
||||
}
|
||||
PopulateNPCDB(memDB, npcsVec);
|
||||
|
||||
std::vector<Shop> shopsVec;
|
||||
for (const auto& pair : getAllShops()) {
|
||||
shopsVec.push_back(pair.second);
|
||||
}
|
||||
PopulateShopDB(memDB, shopsVec);
|
||||
|
||||
// Save to file
|
||||
{
|
||||
SQLite::Database fileDB("cursebreaker.db", SQLite::OPEN_READWRITE | SQLite::OPEN_CREATE);
|
||||
sqlite3* srcHandle = memDB.getHandle();
|
||||
sqlite3* dstHandle = fileDB.getHandle();
|
||||
sqlite3_backup* backup = sqlite3_backup_init(dstHandle, "main", srcHandle, "main");
|
||||
if (backup) {
|
||||
sqlite3_backup_step(backup, -1);
|
||||
sqlite3_backup_finish(backup);
|
||||
} else {
|
||||
std::cerr << "Failed to initialize backup" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "Database created and saved to cursebreaker.db" << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -462,4 +462,4 @@ void ParseProject(const std::filesystem::path& projectRoot)
|
||||
project.m_prefabAssets = ParsePrefabs(std::vector<AssetPath>(prefabFiles.begin(), prefabFiles.end()), project.m_prefabsMap);
|
||||
|
||||
project.m_sceneAssets = ParseScenes(std::vector<AssetPath>(tilesFiles.begin(), tilesFiles.end()));
|
||||
}
|
||||
}} // namespace cursebreaker
|
||||
|
||||
Reference in New Issue
Block a user