summaryrefslogtreecommitdiff
path: root/src/char/int_storage.c
diff options
context:
space:
mode:
authorSmokexyz <sagunkho@hotmail.com>2017-03-02 19:24:48 +0800
committerSmokexyz <sagunkho@hotmail.com>2017-04-04 13:38:16 +0800
commit974222a8d3f189083205bf5d330de04a43226ad3 (patch)
treeb78280b9dad90616196ee37c3992c3e46962b906 /src/char/int_storage.c
parent20145c61053479b9acd8ed50c75a80c2a861e349 (diff)
downloadhercules-974222a8d3f189083205bf5d330de04a43226ad3.tar.gz
hercules-974222a8d3f189083205bf5d330de04a43226ad3.tar.bz2
hercules-974222a8d3f189083205bf5d330de04a43226ad3.tar.xz
hercules-974222a8d3f189083205bf5d330de04a43226ad3.zip
Implementation of Item Options System.
Allows the infusing of equipments with bonus item options. This feature is constrained to clients of packet versions greater than or equal to `20150226`. Item Options and their effects are defined server-side in `db/item_options.conf` and client side in `data/luafiles514/lua files/datainfo/addrandomoptionnametable.lub` The ID of the option must tally with the correct index of the description provided in the client side lua file to avoid bugs. IT_OPT_* keys and MAX_ITEM_OPTIONS macro are also exported from the source as constants. An additional flag `disable_options` has been added to sql, and as `DisableOptions: true/false (boolean, defaults to false !!for equipments only!!)` to item_db.conf files. Script commands documentation is also included. SQL file updates are included. Credits: [Smokexyz](https://github.com/Smokexyz) Style and Script Fixes by [Asheraf](https://github.com/Asheraf) Initial design Idea by [secretdataz](https://github.com/secretdataz)
Diffstat (limited to 'src/char/int_storage.c')
-rw-r--r--src/char/int_storage.c71
1 files changed, 51 insertions, 20 deletions
diff --git a/src/char/int_storage.c b/src/char/int_storage.c
index 8e3ebdff3..b78ad9f0e 100644
--- a/src/char/int_storage.c
+++ b/src/char/int_storage.c
@@ -63,8 +63,10 @@ int inter_storage_fromsql(int account_id, struct storage_data* p)
// storage {`account_id`/`id`/`nameid`/`amount`/`equip`/`identify`/`refine`/`attribute`/`card0`/`card1`/`card2`/`card3`}
StrBuf->Init(&buf);
StrBuf->AppendStr(&buf, "SELECT `id`,`nameid`,`amount`,`equip`,`identify`,`refine`,`attribute`,`expire_time`,`bound`,`unique_id`");
- for( j = 0; j < MAX_SLOTS; ++j )
+ for (j = 0; j < MAX_SLOTS; ++j)
StrBuf->Printf(&buf, ",`card%d`", j);
+ for (j = 0; j < MAX_ITEM_OPTIONS; ++j)
+ StrBuf->Printf(&buf, ",`opt_idx%d`,`opt_val%d`", j, j);
StrBuf->Printf(&buf, " FROM `%s` WHERE `account_id`='%d' ORDER BY `nameid`", storage_db, account_id);
if (SQL_ERROR == SQL->QueryStr(inter->sql_handle, StrBuf->Value(&buf)))
@@ -84,9 +86,17 @@ int inter_storage_fromsql(int account_id, struct storage_data* p)
SQL->GetData(inter->sql_handle, 7, &data, NULL); item->expire_time = (unsigned int)atoi(data);
SQL->GetData(inter->sql_handle, 8, &data, NULL); item->bound = atoi(data);
SQL->GetData(inter->sql_handle, 9, &data, NULL); item->unique_id = strtoull(data, NULL, 10);
- for( j = 0; j < MAX_SLOTS; ++j )
- {
- SQL->GetData(inter->sql_handle, 10+j, &data, NULL); item->card[j] = atoi(data);
+ /* Card Slots */
+ for (j = 0; j < MAX_SLOTS; ++j) {
+ SQL->GetData(inter->sql_handle, 10 + j, &data, NULL);
+ item->card[j] = atoi(data);
+ }
+ /* Item Options */
+ for (j = 0; j < MAX_ITEM_OPTIONS; ++j) {
+ SQL->GetData(inter->sql_handle, 10 + MAX_SLOTS + j * 2, &data, NULL);
+ item->option[j].index = atoi(data);
+ SQL->GetData(inter->sql_handle, 11 + MAX_SLOTS + j * 2, &data, NULL);
+ item->option[j].value = atoi(data);
}
}
p->storage_amount = i;
@@ -121,8 +131,10 @@ int inter_storage_guild_storage_fromsql(int guild_id, struct guild_storage* p)
// storage {`guild_id`/`id`/`nameid`/`amount`/`equip`/`identify`/`refine`/`attribute`/`card0`/`card1`/`card2`/`card3`}
StrBuf->Init(&buf);
StrBuf->AppendStr(&buf, "SELECT `id`,`nameid`,`amount`,`equip`,`identify`,`refine`,`attribute`,`bound`,`unique_id`");
- for( j = 0; j < MAX_SLOTS; ++j )
+ for (j = 0; j < MAX_SLOTS; ++j)
StrBuf->Printf(&buf, ",`card%d`", j);
+ for (j = 0; j < MAX_ITEM_OPTIONS; ++j)
+ StrBuf->Printf(&buf, ", `opt_idx%d`, `opt_val%d`", j, j);
StrBuf->Printf(&buf, " FROM `%s` WHERE `guild_id`='%d' ORDER BY `nameid`", guild_storage_db, guild_id);
if( SQL_ERROR == SQL->QueryStr(inter->sql_handle, StrBuf->Value(&buf)))
@@ -142,9 +154,17 @@ int inter_storage_guild_storage_fromsql(int guild_id, struct guild_storage* p)
SQL->GetData(inter->sql_handle, 7, &data, NULL); item->bound = atoi(data);
SQL->GetData(inter->sql_handle, 8, &data, NULL); item->unique_id = strtoull(data, NULL, 10);
item->expire_time = 0;
-
- for( j = 0; j < MAX_SLOTS; ++j ) {
- SQL->GetData(inter->sql_handle, 9+j, &data, NULL); item->card[j] = atoi(data);
+ /* Card Slots */
+ for (j = 0; j < MAX_SLOTS; ++j) {
+ SQL->GetData(inter->sql_handle, 9 + j, &data, NULL);
+ item->card[j] = atoi(data);
+ }
+ /* Item Options */
+ for (j = 0; j < MAX_ITEM_OPTIONS; ++j) {
+ SQL->GetData(inter->sql_handle, 9 + MAX_SLOTS + j * 2, &data, NULL);
+ item->option[j].index = atoi(data);
+ SQL->GetData(inter->sql_handle, 10 + MAX_SLOTS + j * 2, &data, NULL);
+ item->option[j].value = atoi(data);
}
}
p->storage_amount = i;
@@ -288,8 +308,10 @@ int mapif_parse_ItemBoundRetrieve_sub(int fd)
StrBuf->Init(&buf);
StrBuf->AppendStr(&buf, "SELECT `id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`, `bound`, `unique_id`");
- for( j = 0; j < MAX_SLOTS; ++j )
+ for (j = 0; j < MAX_SLOTS; ++j)
StrBuf->Printf(&buf, ", `card%d`", j);
+ for (j = 0; j < MAX_ITEM_OPTIONS; ++j)
+ StrBuf->Printf(&buf, ", `opt_idx%d`, `opt_val%d`", j, j);
StrBuf->Printf(&buf, " FROM `%s` WHERE `char_id`='%d' AND `bound` = '%d'",inventory_db,char_id,IBT_GUILD);
stmt = SQL->StmtMalloc(inter->sql_handle);
@@ -313,17 +335,22 @@ int mapif_parse_ItemBoundRetrieve_sub(int fd)
SQL->StmtBindColumn(stmt, 7, SQLDT_UINT, &item.expire_time, 0, NULL, NULL);
SQL->StmtBindColumn(stmt, 8, SQLDT_UCHAR, &item.bound, 0, NULL, NULL);
SQL->StmtBindColumn(stmt, 9, SQLDT_UINT64, &item.unique_id, 0, NULL, NULL);
- for( j = 0; j < MAX_SLOTS; ++j )
- SQL->StmtBindColumn(stmt, 10+j, SQLDT_SHORT, &item.card[j], 0, NULL, NULL);
-
- while( SQL_SUCCESS == SQL->StmtNextRow(stmt)) {
+ /* Card Slots */
+ for (j = 0; j < MAX_SLOTS; ++j)
+ SQL->StmtBindColumn(stmt, 10 + j, SQLDT_SHORT, &item.card[j], 0, NULL, NULL);
+ /* Item Options */
+ for (j = 0; j < MAX_ITEM_OPTIONS; ++j) {
+ SQL->StmtBindColumn(stmt, 10 + MAX_SLOTS + j * 2, SQLDT_INT16, &item.option[j].index, 0, NULL, NULL);
+ SQL->StmtBindColumn(stmt, 11 + MAX_SLOTS + j * 2, SQLDT_INT16, &item.option[j].value, 0, NULL, NULL);
+ }
+ while (SQL_SUCCESS == SQL->StmtNextRow(stmt)) {
Assert_retb(i < MAX_INVENTORY);
memcpy(&items[i],&item,sizeof(struct item));
i++;
}
SQL->FreeResult(inter->sql_handle);
- if(!i) { //No items found - No need to continue
+ if (i == 0) { //No items found - No need to continue
StrBuf->Destroy(&buf);
SQL->StmtFree(stmt);
return 0;
@@ -408,24 +435,28 @@ int mapif_parse_ItemBoundRetrieve_sub(int fd)
StrBuf->Printf(&buf,"INSERT INTO `%s` (`guild_id`,`nameid`,`amount`,`equip`,`identify`,`refine`,"
"`attribute`,`expire_time`,`bound`,`unique_id`",
guild_storage_db);
- for( s = 0; s < MAX_SLOTS; ++s )
+ for (s = 0; s < MAX_SLOTS; ++s)
StrBuf->Printf(&buf, ", `card%d`", s);
+ for (s = 0; s < MAX_ITEM_OPTIONS; ++s)
+ StrBuf->Printf(&buf, ", `opt_idx%d`, `opt_val%d`", s, s);
StrBuf->AppendStr(&buf," ) VALUES ");
- for( j = 0; j < i; ++j ) {
- if( j )
+ for (j = 0; j < i; ++j) {
+ if (j != 0)
StrBuf->AppendStr(&buf, ",");
StrBuf->Printf(&buf, "('%d', '%d', '%d', '%u', '%d', '%d', '%d', '%u', '%d', '%"PRIu64"'",
guild_id, items[j].nameid, items[j].amount, items[j].equip, items[j].identify, items[j].refine,
items[j].attribute, items[j].expire_time, items[j].bound, items[j].unique_id);
- for( s = 0; s < MAX_SLOTS; ++s )
+ for (s = 0; s < MAX_SLOTS; ++s)
StrBuf->Printf(&buf, ", '%d'", items[j].card[s]);
+ for (s = 0; s < MAX_ITEM_OPTIONS; ++s)
+ StrBuf->Printf(&buf, ", '%d', '%d'", items[j].option[s].index, items[j].option[s].value);
StrBuf->AppendStr(&buf, ")");
}
- if( SQL_ERROR == SQL->StmtPrepareStr(stmt, StrBuf->Value(&buf))
- || SQL_ERROR == SQL->StmtExecute(stmt) )
+ if (SQL_ERROR == SQL->StmtPrepareStr(stmt, StrBuf->Value(&buf))
+ || SQL_ERROR == SQL->StmtExecute(stmt))
{
Sql_ShowDebug(inter->sql_handle);
SQL->StmtFree(stmt);