From 974222a8d3f189083205bf5d330de04a43226ad3 Mon Sep 17 00:00:00 2001 From: Smokexyz Date: Thu, 2 Mar 2017 19:24:48 +0800 Subject: 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) --- src/char/int_mail.c | 43 +++++++++++++++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 10 deletions(-) (limited to 'src/char/int_mail.c') diff --git a/src/char/int_mail.c b/src/char/int_mail.c index 10f905a0d..1d00b0fdf 100644 --- a/src/char/int_mail.c +++ b/src/char/int_mail.c @@ -57,6 +57,8 @@ static int inter_mail_fromsql(int char_id, struct mail_data* md) "`zeny`,`amount`,`nameid`,`refine`,`attribute`,`identify`,`unique_id`"); for (i = 0; i < MAX_SLOTS; i++) StrBuf->Printf(&buf, ",`card%d`", i); + for (i = 0; i < MAX_ITEM_OPTIONS; i++) + StrBuf->Printf(&buf, ", `opt_idx%d`, `opt_val%d`", i, i); // I keep the `status` < 3 just in case someone forget to apply the sqlfix StrBuf->Printf(&buf, " FROM `%s` WHERE `dest_id`='%d' AND `status` < 3 ORDER BY `id` LIMIT %d", @@ -90,12 +92,18 @@ static int inter_mail_fromsql(int char_id, struct mail_data* md) SQL->GetData(inter->sql_handle,15, &data, NULL); item->unique_id = strtoull(data, NULL, 10); item->expire_time = 0; item->bound = 0; - - for (j = 0; j < MAX_SLOTS; j++) - { + /* Card Slots */ + for (j = 0; j < MAX_SLOTS; j++) { SQL->GetData(inter->sql_handle, 16 + j, &data, NULL); item->card[j] = atoi(data); } + /* Item Options */ + for (j = 0; j < MAX_ITEM_OPTIONS; j++) { + SQL->GetData(inter->sql_handle, 16 + MAX_SLOTS + j * 2, &data, NULL); + item->option[j].index = atoi(data); + SQL->GetData(inter->sql_handle, 17 + MAX_SLOTS + j * 2, &data, NULL); + item->option[j].value = atoi(data); + } } md->full = ( SQL->NumRows(inter->sql_handle) > MAIL_MAX_INBOX ); @@ -138,25 +146,30 @@ int inter_mail_savemessage(struct mail_message* msg) StrBuf->Printf(&buf, "INSERT INTO `%s` (`send_name`, `send_id`, `dest_name`, `dest_id`, `title`, `message`, `time`, `status`, `zeny`, `amount`, `nameid`, `refine`, `attribute`, `identify`, `unique_id`", mail_db); 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, ") VALUES (?, '%d', ?, '%d', ?, ?, '%lu', '%u', '%d', '%d', '%d', '%d', '%d', '%d', '%"PRIu64"'", msg->send_id, msg->dest_id, (unsigned long)msg->timestamp, msg->status, msg->zeny, msg->item.amount, msg->item.nameid, msg->item.refine, msg->item.attribute, msg->item.identify, msg->item.unique_id); for (j = 0; j < MAX_SLOTS; j++) StrBuf->Printf(&buf, ", '%d'", msg->item.card[j]); + for (j = 0; j < MAX_ITEM_OPTIONS; j++) + StrBuf->Printf(&buf, ", '%d', '%d'", msg->item.option[j].index, msg->item.option[j].value); StrBuf->AppendStr(&buf, ")"); // prepare and execute query stmt = SQL->StmtMalloc(inter->sql_handle); - if( SQL_SUCCESS != SQL->StmtPrepareStr(stmt, StrBuf->Value(&buf)) + if (SQL_SUCCESS != SQL->StmtPrepareStr(stmt, StrBuf->Value(&buf)) || SQL_SUCCESS != SQL->StmtBindParam(stmt, 0, SQLDT_STRING, msg->send_name, strnlen(msg->send_name, NAME_LENGTH)) || SQL_SUCCESS != SQL->StmtBindParam(stmt, 1, SQLDT_STRING, msg->dest_name, strnlen(msg->dest_name, NAME_LENGTH)) || SQL_SUCCESS != SQL->StmtBindParam(stmt, 2, SQLDT_STRING, msg->title, strnlen(msg->title, MAIL_TITLE_LENGTH)) || SQL_SUCCESS != SQL->StmtBindParam(stmt, 3, SQLDT_STRING, msg->body, strnlen(msg->body, MAIL_BODY_LENGTH)) - || SQL_SUCCESS != SQL->StmtExecute(stmt) ) + || SQL_SUCCESS != SQL->StmtExecute(stmt)) { SqlStmt_ShowDebug(stmt); msg->id = 0; - } else + } else { msg->id = (int)SQL->StmtLastInsertId(stmt); + } SQL->StmtFree(stmt); StrBuf->Destroy(&buf); @@ -176,8 +189,10 @@ static bool inter_mail_loadmessage(int mail_id, struct mail_message* msg) StrBuf->Init(&buf); StrBuf->AppendStr(&buf, "SELECT `id`,`send_name`,`send_id`,`dest_name`,`dest_id`,`title`,`message`,`time`,`status`," "`zeny`,`amount`,`nameid`,`refine`,`attribute`,`identify`,`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 `id` = '%d'", mail_db, mail_id); if (SQL_ERROR == SQL->QueryStr(inter->sql_handle, StrBuf->Value(&buf)) @@ -207,12 +222,18 @@ static bool inter_mail_loadmessage(int mail_id, struct mail_message* msg) SQL->GetData(inter->sql_handle,15, &data, NULL); msg->item.unique_id = strtoull(data, NULL, 10); msg->item.expire_time = 0; msg->item.bound = 0; - - for( j = 0; j < MAX_SLOTS; j++ ) - { + /* Card Slots */ + for (j = 0; j < MAX_SLOTS; j++) { SQL->GetData(inter->sql_handle,16 + j, &data, NULL); msg->item.card[j] = atoi(data); } + /* Item Options */ + for (j = 0 ; j < MAX_ITEM_OPTIONS; j++) { + SQL->GetData(inter->sql_handle, 16 + MAX_SLOTS + j * 2, &data, NULL); + msg->item.option[j].index = atoi(data); + SQL->GetData(inter->sql_handle, 17 + MAX_SLOTS + j * 2, &data, NULL); + msg->item.option[j].value = atoi(data); + } } StrBuf->Destroy(&buf); @@ -269,6 +290,8 @@ static bool inter_mail_DeleteAttach(int mail_id) StrBuf->Printf(&buf, "UPDATE `%s` SET `zeny` = '0', `nameid` = '0', `amount` = '0', `refine` = '0', `attribute` = '0', `identify` = '0'", mail_db); for (i = 0; i < MAX_SLOTS; i++) StrBuf->Printf(&buf, ", `card%d` = '0'", i); + for (i = 0; i < MAX_ITEM_OPTIONS; i++) + StrBuf->Printf(&buf, ", `opt_idx%d` = '0', `opt_val%d` = '0'", i, i); StrBuf->Printf(&buf, " WHERE `id` = '%d'", mail_id); if (SQL_ERROR == SQL->QueryStr(inter->sql_handle, StrBuf->Value(&buf))) { -- cgit v1.2.3-70-g09d2