* Add a new resource type (for use with .wrf files): DBBRAIN which is similar to SBRAIN, with as difference that instead of a CSV file it specifies an SQLite database file to load from

* Add the code to load brains from the brain table of the given database file (function `loadBrainStatsFromDB`)
  * This code will make sure to load the brain stats-data in a similar manner (i.e. the resulting data in-memory should be the same) to the brain.txt loading code

This addresses #2 ( http://trac.wz2100.net/ticket/2 )


git-svn-id: svn+ssh://svn.gna.org/svn/warzone/trunk@4082 4a71c877-e1ca-e34f-864e-861f7616d084
master
Giel van Schijndel 2008-03-15 23:56:08 +00:00
parent 1be90e0811
commit d72edf6dee
3 changed files with 135 additions and 0 deletions

View File

@ -237,6 +237,19 @@ static BOOL bufferSBRAINLoad(const char *pBuffer, UDWORD size, void **ppData)
return TRUE;
}
static BOOL dataDBBRAINLoad(const char* filename, void** ppData)
{
if (!loadBrainStatsFromDB(filename)
|| !allocComponentList(COMP_BRAIN, numBrainStats))
{
return FALSE;
}
//not interested in this value
*ppData = NULL;
return TRUE;
}
/* Load the PropulsionType stats */
static BOOL bufferSPROPTYPESLoad(const char *pBuffer, UDWORD size, void **ppData)
{
@ -976,6 +989,7 @@ static const RES_TYPE_MIN_FILE FileResourceTypes[] =
{
{"DBWEAPON", dataDBWEAPONLoad, NULL},
{"DBBODY", dataDBBODYLoad, dataReleaseStats},
{"DBBRAIN", dataDBBRAINLoad, NULL},
{"WAV", dataAudioLoad, (RES_FREE)sound_ReleaseTrack},
{"AUDIOCFG", dataAudioCfgLoad, NULL},
{"ANI", dataAnimLoad, dataAnimRelease},

View File

@ -738,3 +738,123 @@ in_db_err:
return retval;
}
/** Load the brain stats from the given SQLite database file
* \param filename name of the database file to load the brain stats from.
*/
bool loadBrainStatsFromDB(const char* filename)
{
bool retval = false;
sqlite3* db;
sqlite3_stmt* stmt;
int rc;
if (!openDB(filename, &db))
goto in_db_err;
// Prepare this SQL statement for execution
if (!prepareStatement(db, "SELECT MAX(id) FROM `brain`;", &stmt))
goto in_db_err;
/* Execute and process the results of the above SQL statement to
* determine the amount of brains we're about to fetch. Then make sure
* to allocate memory for that amount of brains. */
rc = sqlite3_step(stmt);
if (rc != SQLITE_ROW
|| sqlite3_data_count(stmt) != 1
|| !statsAllocBrain(sqlite3_column_int(stmt, 0)))
{
goto in_statement_err;
}
sqlite3_finalize(stmt);
if (!prepareStatement(db, "SELECT `id`,"
"`name`,"
"`techlevel`,"
"`buildPower`,"
"`buildPoints`,"
"`weight`,"
"`hitpoints`,"
"`systempoints`,"
"`weapon`,"
"`program_capacity`"
"FROM `brain`;", &stmt))
goto in_db_err;
while ((rc = sqlite3_step(stmt)) == SQLITE_ROW)
{
BRAIN_STATS sStats, * const stats = &sStats;
unsigned int colnum = 0;
const unsigned int brain_id = sqlite3_column_int(stmt, colnum++);
memset(stats, 0, sizeof(*stats));
stats->ref = REF_BRAIN_START + brain_id - 1;
// name TEXT NOT NULL, -- Text id name (short language independant name)
if (!allocateStatName((BASE_STATS *)stats, (const char*)sqlite3_column_text(stmt, colnum++)))
{
goto in_statement_err;
}
// techlevel TEXT NOT NULL, -- Technology level of this component
if (!setTechLevel((BASE_STATS *)stats, (const char*)sqlite3_column_text(stmt, colnum++)))
{
goto in_statement_err;
}
// buildPower NUMERIC NOT NULL, -- Power required to build this component
stats->buildPower = sqlite3_column_double(stmt, colnum++);
// buildPoints NUMERIC NOT NULL, -- Time required to build this component
stats->buildPoints = sqlite3_column_double(stmt, colnum++);
// weight NUMERIC NOT NULL, -- Component's weight (mass?)
stats->weight = sqlite3_column_double(stmt, colnum++);
// hitpoints NUMERIC NOT NULL, -- Component's hitpoints - SEEMS TO BE UNUSED
stats->hitPoints = sqlite3_column_double(stmt, colnum++);
// systempoints NUMERIC NOT NULL, -- Space the component takes in the droid - SEEMS TO BE UNUSED
stats->systemPoints = sqlite3_column_double(stmt, colnum++);
// weapon INTEGER, -- A reference to `weapons`.`id`, refers to the weapon stats associated with this brain (can be NULL for none) - for Command Droids
// Check whether a weapon is attached
if (sqlite3_column_type(stmt, colnum) != SQLITE_NULL)
{
const unsigned int weapon_id = sqlite3_column_int(stmt, colnum++);
//get the weapon stat
stats->psWeaponStat = statsGetWeapon(REF_WEAPON_START + weapon_id - 1);
//if weapon not found - error
if (stats->psWeaponStat == NULL)
{
debug(LOG_ERROR, "Unable to find weapon %u for brain %s", weapon_id, stats->pName);
abort();
goto in_statement_err;
}
}
else
{
stats->psWeaponStat = NULL;
++colnum;
}
// program_capacity INTEGER NOT NULL -- Program's capacity
stats->progCap = sqlite3_column_int(stmt, colnum++);
// All brains except ZNULLBRAIN available in design screen
stats->design = strcmp(stats->pName, "ZNULLBRAIN") ? TRUE : FALSE;
// save the stats
statsSetBrain(stats, brain_id - 1);
}
retval = true;
in_statement_err:
sqlite3_finalize(stmt);
in_db_err:
sqlite3_close(db);
return retval;
}

View File

@ -29,5 +29,6 @@
extern bool loadWeaponStatsFromDB(const char* filename);
extern bool loadBodyStatsFromDB(const char* filename);
extern bool loadBrainStatsFromDB(const char* filename);
#endif // __INCLUDED_STATS_DB_H__