Some have requested help for this so I hope this helps some. Note this was adapted to a similar free wrapper made for Torque Game Engine just rewrote a few lines for the Unreal Adaptation.
First Download the SQLite C++ files here: MEGA
PasteBin Usage:
Next Extract the Classes and RPG_Database.h and .cpp Folder into your project’s source folder: Source[Gamename]\
Include the Class Folder Directory to your C++ Project.
Include the RPGDatabase files to the main code.
The RPG Database object is the BP instancing object. Because it uses a local database I placed all my interaction for the database in the Gamestate Object. All interactions with the actual database happens in sequence and through the one object. I am unsure if SQLite supports multi threaded interactions. So far what I needed for works without issues.
//Note - The database file I originally saved in the save directory but I recently moved them to the game content folder. I hope that this makes the engine package the files during the baking process when making a deployment package. I have not tested this but hopefully this will work. I will also have to make it where the current database will be copied to the save directory to simulate the real world usage for database/save file data.
//Initializing the Database file. - This is just what I use to copy a fresh database file from the source and make it my currently active one. This is so that updates can be made to the source and all activities saved to the current will only be in a copied database. Also are a few functions that I use to help keep the SQL statements clean.
URPG_Party::URPG_Party(const class FPostConstructInitializeProperties& PCIP)
: Super(PCIP)
{
ItemInv = PCIP.CreateDefaultSubobject<URPG_Inventory>(this, TEXT("ItemInv"));
ArmorInv = PCIP.CreateDefaultSubobject<URPG_Armor>(this, TEXT("ArmorInv"));
PartyMem = PCIP.CreateDefaultSubobject<URPG_PartyMembers>(this, TEXT("PartyMem"));
CurrentFieldPlayer = 0;
Money = 5000;
CurrentFieldPlayerHandel = 0;
PartyLeaderIndex = 0;
TimePlayed = 0;
CurrentMap = "";
DB_SOURCE_PATH = FPaths::GameContentDir()+"RPG_SYSTEM/datafiles/datastore/";
DB_ACTIVE_PATH = FPaths::GameContentDir() + "RPG_SYSTEM/datafiles/";
DB_SAVE_PATH = FPaths::GameContentDir() + "RPG_SYSTEM/datafiles/datasect/";
DB_SOURCE = "source.dat";
DB_ACTIVE = "active.dat";
DB_SAVESLOT1 = "save1.dat";
DB_SAVESLOT2 = "save2.dat";
DB_SAVESLOT3 = "save3.dat";
SourceDataBase = DB_SOURCE_PATH + DB_SOURCE;
CurrentDataBase = DB_ACTIVE_PATH + DB_ACTIVE;
}
bool URPG_Party::initalizeDataBaseFile(){
//Check File
if (FPlatformFileManager::Get().GetPlatformFile().FileExists(*CurrentDataBase))
{
echo("ActiveDB Found will use the active one");
return true;
}
if (!FPlatformFileManager::Get().GetPlatformFile().FileExists(*SourceDataBase))
{
error("SourceDB NOT Found Opening the database will create a blank database!");
return false;
}
if (!FPlatformFileManager::Get().GetPlatformFile().CopyFile(*CurrentDataBase, *SourceDataBase))
{
error("Could NOT copy Source Database");
return false;
}
return true;
}
void URPG_Party::initalizeDataBasePtr(URPG_Database* RPG_DATABASE){
RPG_DATABASE_CONTROLLER = RPG_DATABASE;
}
bool URPG_Party::CHECK_DATABASE_PTR(){
if (RPG_DATABASE_CONTROLLER == nullptr){
echo("RPG_DATABASE_CONTROLLER Not initalized");
return false;
}
return true;
}
bool URPG_Party::OpenDatabase(FString _DataBase){
if (!CHECK_DATABASE_PTR())return false;
if (RPG_DATABASE_CONTROLLER->OpenDatabase(TCHAR_TO_ANSI(*_DataBase)) == 0)
{
echo(FString("ERROR: Failed to open database: ") + _DataBase);
echo((" Ensure that the disk is not full or write protected. sqliteTest aborted."));
return false;
}
return true;
}
// RPG_SYSTEM
bool URPG_Party::StartUpGameData(FString CurrentMapName,bool IsNewGame){
if (!CHECK_DATABASE_PTR())return false;
//LevelType = GAME_LEVEL;
//Init New Database Files
if (IsNewGame){
if (FPlatformFileManager::Get().GetPlatformFile().FileExists(*CurrentDataBase))
{
if (!FPlatformFileManager::Get().GetPlatformFile().DeleteFile(*CurrentDataBase))
{
error("Could Not Delete Active Database");
return false;
}
}
}
//Sleep needed for the deletion process.
Sleep(1000);
if(!initalizeDataBaseFile())return false;
//Sleep needed for deletion and/or copy process
Sleep(1000);
//Create System Structures
initalizePlayerSystem();
InitalizeInventory();
populateArmorData();
//Initalize starting variables
TimePlayed = 0;
Money = 5000;
CurrentMap = CurrentMapName;
return true;
}
The code above shows some function called used to start my system. Take from it what you need.
//Reading Data VIA SQL
void URPG_Party::loadArmorPlayerType(int PlayerID, int type){
if (!OpenDatabase(CurrentDataBase))return;
FString SQLQuery = FString("select Armors.ArmorID,Name,ATK,DEF,MATK,MDEF,VIT,MAG,EVA,ACC,ICON,MESHSKIN,DESC,FIRE_RES,WATER_RES,EARTH_RES,WIND_RES,ICE_RES,LIGHTENING_RES,LIGHT_RES,DARK_RES,METAL_RES,CLASSES from armors join EquippedArmors on armors.ArmorID=EquippedArmors.ArmorID where playerid=")
+ FString::FromInt(PlayerID)
+" and EquippedArmors.ArmorTypeID="
+ FString::FromInt(type)
+ ";";
int32 result = RPG_DATABASE_CONTROLLER->BP_Query(SQLQuery);
if (result == 0 || RPG_DATABASE_CONTROLLER->EndOfResult(result))
{
echo("Failed to find initial Armor");
if (result)RPG_DATABASE_CONTROLLER->BP_ClearResult(result);
RPG_DATABASE_CONTROLLER->BP_CloseDatabase();
return;
}
else{
int32 ID = FCString::Atoi(*RPG_DATABASE_CONTROLLER->BP_GetColumn(result, "Armors.ArmorID"));
FString Name = RPG_DATABASE_CONTROLLER->BP_GetColumn(result, "Name");
int32 ATK = FCString::Atoi(*RPG_DATABASE_CONTROLLER->BP_GetColumn(result, "ATK"));
int32 DEF = FCString::Atoi(*RPG_DATABASE_CONTROLLER->BP_GetColumn(result, "DEF"));
int32 MATK = FCString::Atoi(*RPG_DATABASE_CONTROLLER->BP_GetColumn(result, "MATK"));
int32 MDEF = FCString::Atoi(*RPG_DATABASE_CONTROLLER->BP_GetColumn(result, "MDEF"));
int32 VIT = FCString::Atoi(*RPG_DATABASE_CONTROLLER->BP_GetColumn(result, "VIT"));
int32 MAG = FCString::Atoi(*RPG_DATABASE_CONTROLLER->BP_GetColumn(result, "MAG"));
int32 EVA = FCString::Atoi(*RPG_DATABASE_CONTROLLER->BP_GetColumn(result, "EVA"));
int32 ACC = FCString::Atoi(*RPG_DATABASE_CONTROLLER->BP_GetColumn(result, "ACC"));
int32 ARMORTYPE = FCString::Atoi(*RPG_DATABASE_CONTROLLER->BP_GetColumn(result, "ARMORTYPE"));
FString MESHSKIN = RPG_DATABASE_CONTROLLER->BP_GetColumn(result, "MESHSKIN");
FString DESC = RPG_DATABASE_CONTROLLER->BP_GetColumn(result, "DESC");
int32 FIRE_RES = FCString::Atoi(*RPG_DATABASE_CONTROLLER->BP_GetColumn(result, "FIRE_RES"));
int32 WATER_RES = FCString::Atoi(*RPG_DATABASE_CONTROLLER->BP_GetColumn(result, "WATER_RES"));
int32 EARTH_RES = FCString::Atoi(*RPG_DATABASE_CONTROLLER->BP_GetColumn(result, "EARTH_RES"));
int32 WIND_RES = FCString::Atoi(*RPG_DATABASE_CONTROLLER->BP_GetColumn(result, "WIND_RES"));
int32 ICE_RES = FCString::Atoi(*RPG_DATABASE_CONTROLLER->BP_GetColumn(result, "ICE_RES"));
int32 LIGHTENING_RES = FCString::Atoi(*RPG_DATABASE_CONTROLLER->BP_GetColumn(result, "LIGHTENING_RES"));
int32 LIGHT_RES = FCString::Atoi(*RPG_DATABASE_CONTROLLER->BP_GetColumn(result, "LIGHT_RES"));
int32 DARK_RES = FCString::Atoi(*RPG_DATABASE_CONTROLLER->BP_GetColumn(result, "DARK_RES"));
int32 METAL_RES = FCString::Atoi(*RPG_DATABASE_CONTROLLER->BP_GetColumn(result, "METAL_RES"));
FString CLASSES = RPG_DATABASE_CONTROLLER->BP_GetColumn(result, "CLASSES");
PartyMem->equipArmorStats(PlayerID, type, Name, ATK, DEF, MATK, MDEF, VIT, MAG, EVA, ACC);
PartyMem->equipPlayerRes(PlayerID, type, FIRE_RES, WATER_RES, EARTH_RES, WIND_RES, ICE_RES, LIGHTENING_RES, LIGHT_RES, DARK_RES, METAL_RES);
}
if (result)RPG_DATABASE_CONTROLLER->BP_ClearResult(result);
RPG_DATABASE_CONTROLLER->BP_CloseDatabase();
}
Hope this helps some people…