Skip to content

Commit

Permalink
allow use of item constants in CloneItem field
Browse files Browse the repository at this point in the history
  • Loading branch information
guilherme-gm committed May 1, 2023
1 parent 6b033b6 commit a756b46
Show file tree
Hide file tree
Showing 7 changed files with 45 additions and 19 deletions.
2 changes: 1 addition & 1 deletion db/item_db2.conf
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ item_db: (
AegisName: "Aegis_Name" (string, optional if Inherit: true)
Name: "Item Name" (string, optional if Inherit: true)
// ================ Optional fields ===============================
CloneItem: ID (int, if specified, copies fields from
CloneItem: ID or "Aegis_Name" (int or string, if specified, copies fields from
the other item and overrides with the values
specified in this one)
Type: Item Type (string, defaults to "IT_ETC")
Expand Down
2 changes: 1 addition & 1 deletion db/pre-re/item_db.conf
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ item_db: (
AegisName: "Aegis_Name" (string)
Name: "Item Name" (string)
// ================ Optional fields ===============================
CloneItem: ID (int, if specified, copies fields from
CloneItem: ID or "Aegis_Name" (int or string, if specified, copies fields from
the other item and overrides with the values
specified in this one)
Type: Item Type (string, defaults to "IT_ETC")
Expand Down
2 changes: 1 addition & 1 deletion db/re/item_db.conf
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ item_db: (
AegisName: "Aegis_Name" (string)
Name: "Item Name" (string)
// ================ Optional fields ===============================
CloneItem: ID (int, if specified, copies fields from
CloneItem: ID or "Aegis_Name" (int or string, if specified, copies fields from
the other item and overrides with the values
specified in this one)
Type: Item Type (string, defaults to "IT_ETC")
Expand Down
2 changes: 1 addition & 1 deletion doc/item_db.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ item_db: (
AegisName: "Aegis_Name" (string, optional if Inherit: true)
Name: "Item Name" (string, optional if Inherit: true)
// =================== Optional fields ================================
CloneItem: ID (int, if specified, copies fields from
CloneItem: ID or "Aegis_Name" (int or string, if specified, copies fields from
the other item and overrides with the values
specified in this one)
Type: Item Type (string, defaults to "IT_ETC")
Expand Down
36 changes: 29 additions & 7 deletions src/map/itemdb.c
Original file line number Diff line number Diff line change
Expand Up @@ -1970,7 +1970,7 @@ static int itemdb_validate_entry(struct item_data *entry, int n, const char *sou
return item->nameid;
}

static void itemdb_readdb_additional_fields(int itemid, struct config_setting_t *it, int n, const char *source)
static void itemdb_readdb_additional_fields(int itemid, struct config_setting_t *it, int n, const char *source, struct DBMap *itemconst_db)
{
// do nothing. plugins can do own work
}
Expand Down Expand Up @@ -2021,7 +2021,7 @@ static void itemdb_readdb_job_sub(struct item_data *id, struct config_setting_t
* validation errors.
* @return Nameid of the validated entry, or 0 in case of failure.
*/
static int itemdb_readdb_libconfig_sub(struct config_setting_t *it, int n, const char *source)
static int itemdb_readdb_libconfig_sub(struct config_setting_t *it, int n, const char *source, struct DBMap *itemconst_db)
{
struct item_data id = { 0 };
struct config_setting_t *t = NULL;
Expand All @@ -2030,6 +2030,7 @@ static int itemdb_readdb_libconfig_sub(struct config_setting_t *it, int n, const
bool inherit = false;

nullpo_ret(it);
nullpo_ret(itemconst_db);
/*
* // Mandatory fields
* Id: ID
Expand Down Expand Up @@ -2105,7 +2106,19 @@ static int itemdb_readdb_libconfig_sub(struct config_setting_t *it, int n, const

bool clone = false;
if ((t = libconfig->setting_get_member(it, "CloneItem")) != NULL) {
int clone_id = libconfig->setting_get_int(t);
int clone_id;

if (t->type == CONFIG_TYPE_STRING) {
const char *clone_name = libconfig->setting_get_string(t);
clone_id = strdb_iget(itemconst_db, clone_name);

if (clone_id == 0) {
ShowWarning("%s: Could not find item \"%s\" to clone in item %d of \"%s\". Skipping.\n", __func__, clone_name, id.nameid, source);
return 0;
}
} else {
clone_id = libconfig->setting_get_int(t);
}

struct item_data *base_entry = itemdb->exists(clone_id);
if (base_entry == NULL) {
Expand Down Expand Up @@ -2403,7 +2416,7 @@ static int itemdb_readdb_libconfig_sub(struct config_setting_t *it, int n, const
* @param filename File name, relative to the database path.
* @return The number of found entries.
*/
static int itemdb_readdb_libconfig(const char *filename)
static int itemdb_readdb_libconfig(const char *filename, struct DBMap *itemconst_db)
{
bool duplicate[MAX_ITEMDB];
struct DBMap *duplicate_db;
Expand All @@ -2413,6 +2426,7 @@ static int itemdb_readdb_libconfig(const char *filename)
int i = 0, count = 0;

nullpo_ret(filename);
nullpo_ret(itemconst_db);

snprintf(filepath, sizeof(filepath), "%s/%s", map->db_path, filename);
if (!libconfig->load_file(&item_db_conf, filepath))
Expand All @@ -2428,14 +2442,16 @@ static int itemdb_readdb_libconfig(const char *filename)
duplicate_db = idb_alloc(DB_OPT_BASE);

while( (it = libconfig->setting_get_elem(itdb,i++)) ) {
int nameid = itemdb->readdb_libconfig_sub(it, i-1, filename);
int nameid = itemdb->readdb_libconfig_sub(it, i-1, filename, itemconst_db);

if (nameid <= 0 || nameid > MAX_ITEM_ID)
continue;

itemdb->readdb_additional_fields(nameid, it, i - 1, filename);
itemdb->readdb_additional_fields(nameid, it, i - 1, filename, itemconst_db);
count++;

strdb_iput(itemconst_db, itemdb_name(nameid), nameid);

if (nameid < MAX_ITEMDB) {
if (duplicate[nameid]) {
ShowWarning("itemdb_readdb:%s: duplicate entry of ID #%d (%s/%s)\n",
Expand Down Expand Up @@ -2962,8 +2978,14 @@ static void itemdb_read(bool minimal)
DBPATH"item_db.conf",
"item_db2.conf",
};

// temporary itemconst db for item cloning because it happens before itemdb->name_constants()
struct DBMap *itemconst_db = strdb_alloc(DB_OPT_BASE, ITEM_NAME_LENGTH);

for (i = 0; i < ARRAYLENGTH(filename); i++)
itemdb->readdb_libconfig(filename[i]);
itemdb->readdb_libconfig(filename[i], itemconst_db);

db_destroy(itemconst_db);

// TODO check duplicate names also in itemdb->other
for( i = 0; i < ARRAYLENGTH(itemdb->array); ++i ) {
Expand Down
6 changes: 3 additions & 3 deletions src/map/itemdb.h
Original file line number Diff line number Diff line change
Expand Up @@ -740,10 +740,10 @@ struct itemdb_interface {
int (*gendercheck) (struct item_data *id);
int (*validate_entry) (struct item_data *entry, int n, const char *source);
void (*readdb_options_additional_fields) (struct itemdb_option *ito, struct config_setting_t *t, const char *source);
void (*readdb_additional_fields) (int itemid, struct config_setting_t *it, int n, const char *source);
void (*readdb_additional_fields) (int itemid, struct config_setting_t *it, int n, const char *source, struct DBMap *itemconst_db);
void (*readdb_job_sub) (struct item_data *id, struct config_setting_t *t);
int (*readdb_libconfig_sub) (struct config_setting_t *it, int n, const char *source);
int (*readdb_libconfig) (const char *filename);
int (*readdb_libconfig_sub) (struct config_setting_t *it, int n, const char *source, struct DBMap *itemconst_db);
int (*readdb_libconfig) (const char *filename, struct DBMap *itemconst_db);
uint64 (*unique_id) (struct map_session_data *sd);
void (*read) (bool minimal);
void (*destroy_item_data) (struct item_data *self, int free_self);
Expand Down
14 changes: 9 additions & 5 deletions src/plugins/db2sql.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ bool mobdb2sql_torun = false;
static struct Sql *sql_handle = NULL;

/// Backup of the original item_db parser function pointer.
int (*itemdb_readdb_libconfig_sub) (struct config_setting_t *it, int n, const char *source);
int (*itemdb_readdb_libconfig_sub) (struct config_setting_t *it, int n, const char *source, struct DBMap *itemconst_db);
/// Backup of the original mob_db parser function pointer.
int (*mob_read_db_sub) (struct config_setting_t *it, int n, const char *source);
bool (*mob_skill_db_libconfig_sub_skill) (struct config_setting_t *it, int n, int mob_id);
Expand Down Expand Up @@ -232,11 +232,11 @@ uint64 itemdb2sql_readdb_job_sub(struct config_setting_t *t)
*
* @see itemdb_readdb_libconfig_sub.
*/
int itemdb2sql_sub(struct config_setting_t *entry, int n, const char *source)
int itemdb2sql_sub(struct config_setting_t *entry, int n, const char *source, struct DBMap *itemconst_db)
{
struct item_data *it = NULL;

if ((it = itemdb->exists(itemdb_readdb_libconfig_sub(entry,n,source)))) {
if ((it = itemdb->exists(itemdb_readdb_libconfig_sub(entry, n, source, itemconst_db)))) {
char e_name[ITEM_NAME_LENGTH*2+1];
const char *bonus = NULL;
char *str;
Expand Down Expand Up @@ -470,7 +470,7 @@ int itemdb2sql_sub(struct config_setting_t *entry, int n, const char *source)
} else {
StrBuf->AppendStr(&buf, "'',");
}

// rental_unequip_script
if (it->rental_end_script && libconfig->setting_lookup_string(entry, "OnRentalEndScript", &bonus)) {
hstr(bonus);
Expand Down Expand Up @@ -582,6 +582,8 @@ void do_itemdb2sql(void)
memset(&tosql.buf, 0, sizeof(tosql.buf));
itemdb->clear(false);

struct DBMap *itemconst_db = strdb_alloc(DB_OPT_BASE, ITEM_NAME_LENGTH);

for (i = 0; i < ARRAYLENGTH(files); i++) {
if ((tosql.fp = fopen(files[i].destination, "wt+")) == NULL) {
ShowError("itemdb_tosql: File not found \"%s\".\n", files[i].destination);
Expand All @@ -591,11 +593,13 @@ void do_itemdb2sql(void)
tosql.db_name = files[i].name;
itemdb2sql_tableheader();

itemdb->readdb_libconfig(files[i].source);
itemdb->readdb_libconfig(files[i].source, itemconst_db);

fclose(tosql.fp);
}

db_destroy(itemconst_db);

/* unlink */
itemdb->readdb_libconfig_sub = itemdb_readdb_libconfig_sub;

Expand Down

0 comments on commit a756b46

Please sign in to comment.