summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/char/char.c97
-rw-r--r--src/char/char.h2
-rw-r--r--src/char/int_auction.c42
-rw-r--r--src/char/int_mail.c43
-rw-r--r--src/char/int_party.c36
-rw-r--r--src/char/int_storage.c71
-rw-r--r--src/common/HPMDataCheck.h3
-rw-r--r--src/common/core.c2
-rw-r--r--src/common/mmo.h22
-rw-r--r--src/common/strlib.c1
-rw-r--r--src/map/atcommand.c30
-rw-r--r--src/map/battle.c33
-rw-r--r--src/map/battle.h8
-rw-r--r--src/map/clif.c181
-rw-r--r--src/map/clif.h6
-rw-r--r--src/map/itemdb.c156
-rw-r--r--src/map/itemdb.h74
-rw-r--r--src/map/log.c13
-rw-r--r--src/map/map.h1
-rw-r--r--src/map/mob.c2
-rw-r--r--src/map/npc.c15
-rw-r--r--src/map/npc.h3
-rw-r--r--src/map/packets.h1740
-rw-r--r--src/map/packets_struct.h25
-rw-r--r--src/map/party.c42
-rw-r--r--src/map/pc.c54
-rw-r--r--src/map/pc.h8
-rw-r--r--src/map/script.c2835
-rw-r--r--src/map/script.h79
-rw-r--r--src/map/skill.c20
-rw-r--r--src/map/status.c37
-rw-r--r--src/map/status.h85
-rw-r--r--src/map/storage.c9
-rw-r--r--src/map/unit.c21
-rw-r--r--src/plugins/HPMHooking/HPMHooking.Defs.inc28
-rw-r--r--src/plugins/HPMHooking/HPMHooking_char.Hooks.inc12
-rw-r--r--src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc40
-rw-r--r--src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc10
-rw-r--r--src/plugins/HPMHooking/HPMHooking_map.Hooks.inc259
-rw-r--r--src/plugins/db2sql.c4
40 files changed, 5452 insertions, 697 deletions
diff --git a/src/char/char.c b/src/char/char.c
index 9314e8c81..93078f8ee 100644
--- a/src/char/char.c
+++ b/src/char/char.c
@@ -745,6 +745,9 @@ int char_memitemdata_to_sql(const struct item items[], int max, int id, int tabl
StrBuf->AppendStr(&buf, "SELECT `id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`, `bound`, `unique_id`");
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);
+
if (has_favorite)
StrBuf->AppendStr(&buf, ", `favorite`");
StrBuf->Printf(&buf, " FROM `%s` WHERE `%s`='%d'", tablename, selectoption, id);
@@ -769,9 +772,13 @@ int char_memitemdata_to_sql(const struct item items[], int max, int id, int tabl
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);
+ SQL->StmtBindColumn(stmt, 10 + j, SQLDT_SHORT, &item.card[j], 0, NULL, NULL);
+ 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);
+ }
if (has_favorite)
- SQL->StmtBindColumn(stmt, 10+MAX_SLOTS, SQLDT_UCHAR, &item.favorite, 0, NULL, NULL);
+ SQL->StmtBindColumn(stmt, 10 + MAX_SLOTS + MAX_ITEM_OPTIONS * 2, SQLDT_UCHAR, &item.favorite, 0, NULL, NULL);
// bit array indicating which inventory items have already been matched
flag = aCalloc(max, sizeof(bool));
@@ -790,9 +797,12 @@ int char_memitemdata_to_sql(const struct item items[], int max, int id, int tabl
&& items[i].card[2] == item.card[2]
&& items[i].card[3] == item.card[3]
) {
+ int k = 0;
// They are the same item.
ARR_FIND(0, MAX_SLOTS, j, items[i].card[j] != item.card[j]);
- if (j == MAX_SLOTS
+ ARR_FIND(0, MAX_ITEM_OPTIONS, k, items[i].option[k].index != item.option[k].index || items[i].option[k].value != item.option[k].value);
+
+ if (j == MAX_SLOTS && k == MAX_ITEM_OPTIONS
&& items[i].amount == item.amount
&& items[i].equip == item.equip
&& items[i].identify == item.identify
@@ -810,6 +820,8 @@ int char_memitemdata_to_sql(const struct item items[], int max, int id, int tabl
tablename, items[i].amount, items[i].equip, items[i].identify, items[i].refine, items[i].attribute, items[i].expire_time, items[i].bound);
for (j = 0; j < MAX_SLOTS; ++j)
StrBuf->Printf(&buf, ", `card%d`='%d'", j, items[i].card[j]);
+ for (j = 0; j < MAX_ITEM_OPTIONS; ++j)
+ StrBuf->Printf(&buf, ", `opt_idx%d`='%d', `opt_val%d`='%d'", j, items[i].option[j].index, j, items[i].option[j].value);
if (has_favorite)
StrBuf->Printf(&buf, ", `favorite`='%d'", items[i].favorite);
StrBuf->Printf(&buf, " WHERE `id`='%d' LIMIT 1", item.id);
@@ -838,6 +850,8 @@ int char_memitemdata_to_sql(const struct item items[], int max, int id, int tabl
StrBuf->Printf(&buf, "INSERT INTO `%s`(`%s`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`, `bound`, `unique_id`", tablename, selectoption);
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);
if (has_favorite)
StrBuf->AppendStr(&buf, ", `favorite`");
StrBuf->AppendStr(&buf, ") VALUES ");
@@ -858,6 +872,8 @@ int char_memitemdata_to_sql(const struct item items[], int max, int id, int tabl
id, items[i].nameid, items[i].amount, items[i].equip, items[i].identify, items[i].refine, items[i].attribute, items[i].expire_time, items[i].bound, items[i].unique_id);
for (j = 0; j < MAX_SLOTS; ++j)
StrBuf->Printf(&buf, ", '%d'", items[i].card[j]);
+ for (j = 0; j < MAX_ITEM_OPTIONS; ++j)
+ StrBuf->Printf(&buf, ", '%d', '%d'", items[i].option[j].index, items[i].option[j].value);
if (has_favorite)
StrBuf->Printf(&buf, ", '%d'", items[i].favorite);
StrBuf->AppendStr(&buf, ")");
@@ -1188,8 +1204,10 @@ int char_mmo_char_fromsql(int char_id, struct mmo_charstatus* p, bool load_every
//`inventory` (`id`,`char_id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `card0`, `card1`, `card2`, `card3`, `expire_time`, `favorite`, `bound`, `unique_id`)
StrBuf->Init(&buf);
StrBuf->AppendStr(&buf, "SELECT `id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`, `favorite`, `bound`, `unique_id`");
- for( i = 0; i < MAX_SLOTS; ++i )
+ 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);
StrBuf->Printf(&buf, " FROM `%s` WHERE `char_id`=? LIMIT %d", inventory_db, MAX_INVENTORY);
memset(&tmp_item, 0, sizeof(tmp_item));
@@ -1209,8 +1227,14 @@ int char_mmo_char_fromsql(int char_id, struct mmo_charstatus* p, bool load_every
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 10, SQLDT_UINT64, &tmp_item.unique_id, 0, NULL, NULL)
)
SqlStmt_ShowDebug(stmt);
- for( i = 0; i < MAX_SLOTS; ++i )
- if( SQL_ERROR == SQL->StmtBindColumn(stmt, 11+i, SQLDT_SHORT, &tmp_item.card[i], 0, NULL, NULL) )
+ /* Card Slots */
+ for (i = 0; i < MAX_SLOTS; ++i)
+ if (SQL_ERROR == SQL->StmtBindColumn(stmt, 11 + i, SQLDT_SHORT, &tmp_item.card[i], 0, NULL, NULL))
+ SqlStmt_ShowDebug(stmt);
+ /* Item Options */
+ for (i = 0; i < MAX_ITEM_OPTIONS; i++)
+ if (SQL_ERROR == SQL->StmtBindColumn(stmt, 11 + MAX_SLOTS + i * 2, SQLDT_INT16, &tmp_item.option[i].index, 0, NULL, NULL)
+ || SQL_ERROR == SQL->StmtBindColumn(stmt, 12 + MAX_SLOTS + i * 2, SQLDT_INT16, &tmp_item.option[i].value, 0, NULL, NULL))
SqlStmt_ShowDebug(stmt);
for( i = 0; i < MAX_INVENTORY && SQL_SUCCESS == SQL->StmtNextRow(stmt); ++i )
@@ -1222,8 +1246,10 @@ int char_mmo_char_fromsql(int char_id, struct mmo_charstatus* p, bool load_every
//`cart_inventory` (`id`,`char_id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `card0`, `card1`, `card2`, `card3`, expire_time`, `bound`, `unique_id`)
StrBuf->Clear(&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`=? LIMIT %d", cart_db, MAX_CART);
memset(&tmp_item, 0, sizeof(tmp_item));
@@ -1243,12 +1269,19 @@ int char_mmo_char_fromsql(int char_id, struct mmo_charstatus* p, bool load_every
) {
SqlStmt_ShowDebug(stmt);
}
- for( i = 0; i < MAX_SLOTS; ++i )
- if( SQL_ERROR == SQL->StmtBindColumn(stmt, 10+i, SQLDT_SHORT, &tmp_item.card[i], 0, NULL, NULL) )
+ /* Card Slots */
+ for (i = 0; i < MAX_SLOTS; ++i)
+ if( SQL_ERROR == SQL->StmtBindColumn(stmt, 10 + i, SQLDT_SHORT, &tmp_item.card[i], 0, NULL, NULL) )
+ SqlStmt_ShowDebug(stmt);
+ /* Item Options */
+ for (i = 0; i < MAX_ITEM_OPTIONS; ++i)
+ if (SQL_ERROR == SQL->StmtBindColumn(stmt, 10 + MAX_SLOTS + i * 2, SQLDT_INT16, &tmp_item.option[i].index, 0, NULL, NULL)
+ || SQL_ERROR == SQL->StmtBindColumn(stmt, 11 + MAX_SLOTS + i * 2, SQLDT_INT16, &tmp_item.option[i].value, 0, NULL, NULL))
SqlStmt_ShowDebug(stmt);
for( i = 0; i < MAX_CART && SQL_SUCCESS == SQL->StmtNextRow(stmt); ++i )
memcpy(&p->cart[i], &tmp_item, sizeof(tmp_item));
+
strcat(t_msg, " cart");
//read storage
@@ -1544,7 +1577,7 @@ int char_check_char_name(char * name, char * esc_name)
* -5: 'Symbols in Character Names are forbidden'
* char_id: Success
**/
-int char_make_new_char_sql(struct char_session_data *sd, const char *name_, int str, int agi, int vit, int int_, int dex, int luk, int slot, int hair_color, int hair_style, int16 starting_class)
+int char_make_new_char_sql(struct char_session_data *sd, const char *name_, int str, int agi, int vit, int int_, int dex, int luk, int slot, int hair_color, int hair_style, int16 starting_class, uint8 sex)
{
char name[NAME_LENGTH];
char esc_name[NAME_LENGTH*2+1];
@@ -1587,17 +1620,17 @@ int char_make_new_char_sql(struct char_session_data *sd, const char *name_, int
if( sd->found_char[slot] != -1 )
return -2; /* character account limit exceeded */
+
#if PACKETVER >= 20120307
// Insert the new char entry to the database
if (SQL_ERROR == SQL->Query(inter->sql_handle, "INSERT INTO `%s` (`account_id`, `char_num`, `name`, `class`, `zeny`, `status_point`,`str`, `agi`, `vit`, `int`, `dex`, `luk`, `max_hp`, `hp`,"
- "`max_sp`, `sp`, `hair`, `hair_color`, `last_map`, `last_x`, `last_y`, `save_map`, `save_x`, `save_y`) VALUES ("
- "'%d', '%d', '%s', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d','%d', '%d','%d', '%d', '%s', '%d', '%d', '%s', '%d', '%d')",
+ "`max_sp`, `sp`, `hair`, `hair_color`, `last_map`, `last_x`, `last_y`, `save_map`, `save_x`, `save_y`, `sex`) VALUES ("
+ "'%d', '%d', '%s', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d','%d', '%d','%d', '%d', '%s', '%d', '%d', '%s', '%d', '%d', '%c')",
char_db, sd->account_id , slot, esc_name, starting_class, start_zeny, 48, str, agi, vit, int_, dex, luk,
(40 * (100 + vit)/100) , (40 * (100 + vit)/100 ), (11 * (100 + int_)/100), (11 * (100 + int_)/100), hair_style, hair_color,
- mapindex_id2name(start_point.map), start_point.x, start_point.y, mapindex_id2name(start_point.map), start_point.x, start_point.y) )
- {
- Sql_ShowDebug(inter->sql_handle);
- return -2; //No, stop the procedure!
+ mapindex_id2name(start_point.map), start_point.x, start_point.y, mapindex_id2name(start_point.map), start_point.x, start_point.y, sex)) {
+ Sql_ShowDebug(inter->sql_handle);
+ return -2; //No, stop the procedure!
}
#else
//Insert the new char entry to the database
@@ -1647,7 +1680,7 @@ int char_make_new_char_sql(struct char_session_data *sd, const char *name_, int
}
}
- ShowInfo("Created char: account: %d, char: %d, slot: %d, name: %s\n", sd->account_id, char_id, slot, name);
+ ShowInfo("Created char: account: %d, char: %d, slot: %d, name: %s, sex: %c\n", sd->account_id, char_id, slot, name, sex);
return char_id;
}
@@ -4633,13 +4666,27 @@ void char_parse_char_create_new_char(int fd, struct char_session_data* sd)
//turn character creation on/off [Kevin]
result = -2;
} else {
- #if PACKETVER >= 20151001
- result = chr->make_new_char_sql(sd, RFIFOP(fd,2), 1, 1, 1, 1, 1, 1, RFIFOB(fd,26), RFIFOW(fd,27), RFIFOW(fd,29), RFIFOW(fd, 31));
- #elif PACKETVER >= 20120307
- result = chr->make_new_char_sql(sd, RFIFOP(fd,2), 1, 1, 1, 1, 1, 1, RFIFOB(fd,26), RFIFOW(fd,27), RFIFOW(fd,29), JOB_NOVICE);
- #else
- result = chr->make_new_char_sql(sd, RFIFOP(fd,2), RFIFOB(fd,26), RFIFOB(fd,27), RFIFOB(fd,28), RFIFOB(fd,29), RFIFOB(fd,30), RFIFOB(fd,31), RFIFOB(fd,32), RFIFOW(fd,33), RFIFOW(fd,35), JOB_NOVICE);
- #endif
+#if PACKETVER >= 20151001
+ uint8 sex = RFIFOB(fd, 35);
+
+ switch (sex) {
+ case SEX_FEMALE:
+ sex = 'F';
+ break;
+ case SEX_MALE:
+ sex = 'M';
+ break;
+ default:
+ chr->creation_failed(fd, -2); // Char Creation Denied
+ RFIFOSKIP(fd, 36);
+ return;
+ }
+ result = chr->make_new_char_sql(sd, RFIFOP(fd, 2), 1, 1, 1, 1, 1, 1, RFIFOB(fd, 26), RFIFOW(fd, 27), RFIFOW(fd, 29), RFIFOW(fd, 31), sex);
+#elif PACKETVER >= 20120307
+ result = chr->make_new_char_sql(sd, RFIFOP(fd, 2), 1, 1, 1, 1, 1, 1, RFIFOB(fd, 26), RFIFOW(fd, 27), RFIFOW(fd, 29), JOB_NOVICE, 'U');
+#else
+ result = chr->make_new_char_sql(sd, RFIFOP(fd, 2), RFIFOB(fd, 26), RFIFOB(fd, 27), RFIFOB(fd, 28), RFIFOB(fd, 29), RFIFOB(fd, 30), RFIFOB(fd, 31), RFIFOB(fd, 32), RFIFOW(fd, 33), RFIFOW(fd, 35), JOB_NOVICE, 'U');
+#endif
}
//'Charname already exists' (-1), 'Char creation denied' (-2) and 'You are underaged' (-3)
@@ -5042,7 +5089,7 @@ int char_parse_char(int fd)
// S 0a39 <name>.24B <slot>.B <hair color>.W <hair style>.W <starting job class ID>.W <Unknown>.(W or 2 B's)??? <sex>.B
case 0xa39:
{
- FIFOSD_CHECK(36);
+ FIFOSD_CHECK(36);
#elif PACKETVER >= 20120307
// S 0970 <name>.24B <slot>.B <hair color>.W <hair style>.W
case 0x970:
diff --git a/src/char/char.h b/src/char/char.h
index d7bc96e13..499b633f7 100644
--- a/src/char/char.h
+++ b/src/char/char.h
@@ -147,7 +147,7 @@ struct char_interface {
bool (*char_slotchange) (struct char_session_data *sd, int fd, unsigned short from, unsigned short to);
int (*rename_char_sql) (struct char_session_data *sd, int char_id);
int (*check_char_name) (char * name, char * esc_name);
- int (*make_new_char_sql) (struct char_session_data *sd, const char *name_, int str, int agi, int vit, int int_, int dex, int luk, int slot, int hair_color, int hair_style, short starting_job);
+ int (*make_new_char_sql) (struct char_session_data *sd, const char *name_, int str, int agi, int vit, int int_, int dex, int luk, int slot, int hair_color, int hair_style, short starting_job, uint8 sex);
int (*divorce_char_sql) (int partner_id1, int partner_id2);
int (*count_users) (void);
int (*mmo_char_tobuf) (uint8* buffer, struct mmo_charstatus* p);
diff --git a/src/char/int_auction.c b/src/char/int_auction.c
index bf690327c..2dd65f213 100644
--- a/src/char/int_auction.c
+++ b/src/char/int_auction.c
@@ -71,8 +71,10 @@ void inter_auction_save(struct auction_data *auction)
StrBuf->Init(&buf);
StrBuf->Printf(&buf, "UPDATE `%s` SET `seller_id` = '%d', `seller_name` = ?, `buyer_id` = '%d', `buyer_name` = ?, `price` = '%d', `buynow` = '%d', `hours` = '%d', `timestamp` = '%lu', `nameid` = '%d', `item_name` = ?, `type` = '%d', `refine` = '%d', `attribute` = '%d'",
auction_db, auction->seller_id, auction->buyer_id, auction->price, auction->buynow, auction->hours, (unsigned long)auction->timestamp, auction->item.nameid, auction->type, auction->item.refine, auction->item.attribute);
- for( j = 0; j < MAX_SLOTS; j++ )
+ for (j = 0; j < MAX_SLOTS; j++)
StrBuf->Printf(&buf, ", `card%d` = '%d'", j, auction->item.card[j]);
+ for (j = 0; j < MAX_ITEM_OPTIONS; j++)
+ StrBuf->Printf(&buf, ", `opt_idx%d` = '%d', `opt_val%d` = '%d'", j, auction->item.option[j].index, j, auction->item.option[j].value);
StrBuf->Printf(&buf, " WHERE `auction_id` = '%u'", auction->auction_id);
stmt = SQL->StmtMalloc(inter->sql_handle);
@@ -95,33 +97,35 @@ unsigned int inter_auction_create(struct auction_data *auction)
StringBuf buf;
struct SqlStmt *stmt;
- if( !auction )
- return false;
+ nullpo_ret(auction);
auction->timestamp = time(NULL) + (auction->hours * 3600);
StrBuf->Init(&buf);
StrBuf->Printf(&buf, "INSERT INTO `%s` (`seller_id`,`seller_name`,`buyer_id`,`buyer_name`,`price`,`buynow`,`hours`,`timestamp`,`nameid`,`item_name`,`type`,`refine`,`attribute`,`unique_id`", auction_db);
- 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, ") VALUES ('%d',?,'%d',?,'%d','%d','%d','%lu','%d',?,'%d','%d','%d','%"PRIu64"'",
auction->seller_id, auction->buyer_id, auction->price, auction->buynow, auction->hours, (unsigned long)auction->timestamp, auction->item.nameid, auction->type, auction->item.refine, auction->item.attribute, auction->item.unique_id);
- for( j = 0; j < MAX_SLOTS; j++ )
+ for (j = 0; j < MAX_SLOTS; j++)
StrBuf->Printf(&buf, ",'%d'", auction->item.card[j]);
+ for (j = 0; j < MAX_ITEM_OPTIONS; j++)
+ StrBuf->Printf(&buf, ",'%d','%d'", auction->item.option[j].index, auction->item.option[j].value);
+
StrBuf->AppendStr(&buf, ")");
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, auction->seller_name, strnlen(auction->seller_name, NAME_LENGTH))
|| SQL_SUCCESS != SQL->StmtBindParam(stmt, 1, SQLDT_STRING, auction->buyer_name, strnlen(auction->buyer_name, NAME_LENGTH))
|| SQL_SUCCESS != SQL->StmtBindParam(stmt, 2, SQLDT_STRING, auction->item_name, strnlen(auction->item_name, ITEM_NAME_LENGTH))
- || SQL_SUCCESS != SQL->StmtExecute(stmt) )
+ || SQL_SUCCESS != SQL->StmtExecute(stmt))
{
SqlStmt_ShowDebug(stmt);
auction->auction_id = 0;
- }
- else
- {
+ } else {
struct auction_data *auction_;
int64 tick = (int64)auction->hours * 3600000;
@@ -204,8 +208,10 @@ void inter_auctions_fromsql(void)
StrBuf->Init(&buf);
StrBuf->AppendStr(&buf, "SELECT `auction_id`,`seller_id`,`seller_name`,`buyer_id`,`buyer_name`,"
"`price`,`buynow`,`hours`,`timestamp`,`nameid`,`item_name`,`type`,`refine`,`attribute`,`unique_id`");
- for( i = 0; i < MAX_SLOTS; i++ )
+ 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);
StrBuf->Printf(&buf, " FROM `%s` ORDER BY `auction_id` DESC", auction_db);
if (SQL_ERROR == SQL->QueryStr(inter->sql_handle, StrBuf->Value(&buf)))
@@ -238,14 +244,20 @@ void inter_auctions_fromsql(void)
item->identify = 1;
item->amount = 1;
item->expire_time = 0;
-
- for( i = 0; i < MAX_SLOTS; i++ )
- {
+ /* Card Slots */
+ for (i = 0; i < MAX_SLOTS; i++) {
SQL->GetData(inter->sql_handle, 15 + i, &data, NULL);
item->card[i] = atoi(data);
}
+ /* Item Options */
+ for (i = 0; i < MAX_ITEM_OPTIONS; i++) {
+ SQL->GetData(inter->sql_handle, 15 + MAX_SLOTS + i * 2, &data, NULL);
+ item->option[i].index = atoi(data);
+ SQL->GetData(inter->sql_handle, 16 + MAX_SLOTS + i * 2, &data, NULL);
+ item->option[i].value = atoi(data);
+ }
- if( auction->timestamp > now )
+ if (auction->timestamp > now)
endtick = ((int64)(auction->timestamp - now) * 1000) + tick;
else
endtick = tick + 10000; // 10 seconds to process ended auctions
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))) {
diff --git a/src/char/int_party.c b/src/char/int_party.c
index 2fc39c328..4b6800699 100644
--- a/src/char/int_party.c
+++ b/src/char/int_party.c
@@ -633,31 +633,21 @@ int mapif_parse_PartyLeave(int fd, int party_id, int account_id, int char_id)
return 0; //Member not found?
mapif->party_withdraw(party_id, account_id, char_id);
-
- if (p->party.member[i].leader){
- p->party.member[i].account_id = 0;
- for (j = 0; j < MAX_PARTY; j++) {
- if (!p->party.member[j].account_id)
- continue;
- mapif->party_withdraw(party_id, p->party.member[j].account_id, p->party.member[j].char_id);
- p->party.member[j].account_id = 0;
- }
- //Party gets deleted on the check_empty call below.
- } else {
- inter_party->tosql(&p->party,PS_DELMEMBER,i);
- j = p->party.member[i].lv;
- if(p->party.member[i].online) p->party.count--;
- memset(&p->party.member[i], 0, sizeof(struct party_member));
- p->size--;
- if (j == p->min_lv || j == p->max_lv || p->family)
- {
- if(p->family) p->family = 0; //Family state broken.
- inter_party->check_lv(p);
- }
+
+ j = p->party.member[i].lv;
+ if (p->party.member[i].online > 0)
+ p->party.count--;
+ memset(&p->party.member[i], 0, sizeof(struct party_member));
+ p->size--;
+ if (j == p->min_lv || j == p->max_lv || p->family) {
+ if(p->family) p->family = 0; //Family state broken.
+ inter_party->check_lv(p);
}
- if (inter_party->check_empty(p) == 0)
+ if (inter_party->check_empty(p) == 0) {
+ inter_party->tosql(&p->party, PS_DELMEMBER, i);
mapif->party_info(-1, &p->party, 0);
+ }
return 0;
}
// When member goes to other map or levels up.
@@ -727,7 +717,7 @@ int mapif_parse_BreakParty(int fd, int party_id)
if(!p)
return 0;
inter_party->tosql(&p->party,PS_BREAK,0);
- mapif->party_broken(fd,party_id);
+ mapif->party_broken(party_id, 1);
return 0;
}
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);
diff --git a/src/common/HPMDataCheck.h b/src/common/HPMDataCheck.h
index 0a4af75dd..2a1c092b7 100644
--- a/src/common/HPMDataCheck.h
+++ b/src/common/HPMDataCheck.h
@@ -452,6 +452,7 @@ HPExport const struct s_HPMDataCheck HPMDataCheck[] = {
{ "item_combo", sizeof(struct item_combo), SERVER_TYPE_MAP },
{ "item_data", sizeof(struct item_data), SERVER_TYPE_MAP },
{ "item_group", sizeof(struct item_group), SERVER_TYPE_MAP },
+ { "item_option", sizeof(struct item_option), SERVER_TYPE_MAP },
{ "item_package", sizeof(struct item_package), SERVER_TYPE_MAP },
{ "item_package_must_entry", sizeof(struct item_package_must_entry), SERVER_TYPE_MAP },
{ "item_package_rand_entry", sizeof(struct item_package_rand_entry), SERVER_TYPE_MAP },
@@ -542,8 +543,8 @@ HPExport const struct s_HPMDataCheck HPMDataCheck[] = {
#ifdef MAP_PACKETS_STRUCT_H
{ "EQUIPITEM_INFO", sizeof(struct EQUIPITEM_INFO), SERVER_TYPE_MAP },
{ "EQUIPSLOTINFO", sizeof(struct EQUIPSLOTINFO), SERVER_TYPE_MAP },
+ { "ItemOptions", sizeof(struct ItemOptions), SERVER_TYPE_MAP },
{ "NORMALITEM_INFO", sizeof(struct NORMALITEM_INFO), SERVER_TYPE_MAP },
- { "RndOptions", sizeof(struct RndOptions), SERVER_TYPE_MAP },
{ "packet_additem", sizeof(struct packet_additem), SERVER_TYPE_MAP },
{ "packet_authok", sizeof(struct packet_authok), SERVER_TYPE_MAP },
{ "packet_banking_check", sizeof(struct packet_banking_check), SERVER_TYPE_MAP },
diff --git a/src/common/core.c b/src/common/core.c
index 74c63a6d6..9a131d042 100644
--- a/src/common/core.c
+++ b/src/common/core.c
@@ -404,6 +404,8 @@ int cmdline_exec(int argc, char **argv, unsigned int options)
struct CmdlineArgData *data = NULL;
const char *arg = argv[i];
if (arg[0] != '-') { // All arguments must begin with '-'
+ if ((options&(CMDLINE_OPT_SILENT|CMDLINE_OPT_PREINIT)) != 0)
+ continue;
ShowError("Invalid option '%s'.\n", argv[i]);
exit(EXIT_FAILURE);
}
diff --git a/src/common/mmo.h b/src/common/mmo.h
index 9c29b8a0e..b3069b27c 100644
--- a/src/common/mmo.h
+++ b/src/common/mmo.h
@@ -114,7 +114,15 @@
#define MAX_INVENTORY 100
//Max number of characters per account. Note that changing this setting alone is not enough if the client is not hexed to support more characters as well.
-#define MAX_CHARS 9
+#if PACKETVER >= 20100413
+#ifndef MAX_CHARS
+ #define MAX_CHARS 12
+#endif
+#else
+#ifndef MAX_CHARS
+ #define MAX_CHARS 9
+#endif
+#endif
//Number of slots carded equipment can have. Never set to less than 4 as they are also used to keep the data of forged items/equipment. [Skotlex]
//Note: The client seems unable to receive data for more than 4 slots due to all related packets having a fixed size.
#define MAX_SLOTS 4
@@ -256,6 +264,12 @@
#define MAX_ELESKILLTREE 3
#endif
+// Maximum item options [Smokexyz]
+#ifndef MAX_ITEM_OPTIONS
+#define MAX_ITEM_OPTIONS 5
+#endif
+STATIC_ASSERT(MAX_ITEM_OPTIONS <= 5, "This value is limited by the client and database layout and should only be increased if you know the consequences.");
+
// The following system marks a different job ID system used by the map server,
// which makes a lot more sense than the normal one. [Skotlex]
// These marks the "level" of the job.
@@ -326,6 +340,12 @@ struct item {
char favorite;
unsigned char bound;
uint64 unique_id;
+
+ struct {
+ int16 index;
+ int16 value;
+ uint8 param;
+ } option[MAX_ITEM_OPTIONS];
};
//Equip position constants
diff --git a/src/common/strlib.c b/src/common/strlib.c
index 75ce2a272..df8093456 100644
--- a/src/common/strlib.c
+++ b/src/common/strlib.c
@@ -344,6 +344,7 @@ int strlib_config_switch(const char *str) {
}
/// strncpy that always null-terminates the string
+/// @remark this function will read at most `n` - 1 bytes from `src` (from 0 to `n` - 2)
char *strlib_safestrncpy(char *dst, const char *src, size_t n)
{
if( n > 0 )
diff --git a/src/map/atcommand.c b/src/map/atcommand.c
index 2beb6c634..881e50497 100644
--- a/src/map/atcommand.c
+++ b/src/map/atcommand.c
@@ -8366,6 +8366,36 @@ void atcommand_commands_sub(struct map_session_data* sd, const int fd, AtCommand
dbi_destroy(iter);
clif->message(fd,line_buff);
+ if (atcommand->binding_count > 0) {
+ int i, count_bind = 0;
+ int gm_lvl = pc_get_group_level(sd);
+
+ for (i = 0; i < atcommand->binding_count; i++) {
+ if (gm_lvl >= ((type == COMMAND_ATCOMMAND) ? atcommand->binding[i]->group_lv : atcommand->binding[i]->group_lv_char)) {
+ size_t slen = strlen(atcommand->binding[i]->command);
+ if (count_bind == 0) {
+ cur = line_buff;
+ memset(line_buff, ' ', CHATBOX_SIZE);
+ line_buff[CHATBOX_SIZE - 1] = 0;
+ clif->message(fd, "------------------");
+ clif->message(fd, "Custom commands:");
+ }
+ if (slen + cur - line_buff >= CHATBOX_SIZE) {
+ clif->message(fd, line_buff);
+ cur = line_buff;
+ memset(line_buff, ' ', CHATBOX_SIZE);
+ line_buff[CHATBOX_SIZE - 1] = 0;
+ }
+ memcpy(cur, atcommand->binding[i]->command, slen);
+ cur += slen + (10 - slen % 10);
+ count_bind++;
+ }
+ }
+ if (count_bind > 0)
+ clif->message(fd, line_buff); // Last Line
+ count += count_bind;
+ }
+
safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,274), count); // "%d commands found."
clif->message(fd, atcmd_output);
diff --git a/src/map/battle.c b/src/map/battle.c
index bb20b94ff..fdea849fb 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -6814,14 +6814,23 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f
if( flag&(BCT_PARTY|BCT_ENEMY) ) {
int s_party = status->get_party_id(s_bl);
int s_guild = status->get_guild_id(s_bl);
+ int t_guild = status->get_guild_id(t_bl);
- if( s_party && s_party == status->get_party_id(t_bl)
- && !(map->list[m].flag.pvp && map->list[m].flag.pvp_noparty)
- && !(map_flag_gvg(m) && map->list[m].flag.gvg_noparty && !( s_guild && s_guild == status->get_guild_id(t_bl) ))
- && (!map->list[m].flag.battleground || sbg_id == tbg_id) )
- state |= BCT_PARTY;
- else
+ if (s_party != 0 && s_party == status->get_party_id(t_bl)) {
+ if (map_flag_gvg(m) && map->list[m].flag.gvg_noparty) {
+ if (s_guild != 0 && t_guild != 0 && (s_guild == t_guild || guild->isallied(s_guild, t_guild)))
+ state |= BCT_PARTY;
+ else
+ state |= flag&BCT_ENEMY ? BCT_ENEMY : BCT_PARTY;
+ } else if (!(map->list[m].flag.pvp && map->list[m].flag.pvp_noparty)
+ && (!map->list[m].flag.battleground || sbg_id == tbg_id)) {
+ state |= BCT_PARTY;
+ } else {
+ state |= BCT_ENEMY;
+ }
+ } else {
state |= BCT_ENEMY;
+ }
}
if( flag&(BCT_GUILD|BCT_ENEMY) ) {
int s_guild = status->get_guild_id(s_bl);
@@ -7167,6 +7176,7 @@ static const struct battle_data {
{ "castrate_dex_scale", &battle_config.castrate_dex_scale, 150, 1, INT_MAX, },
{ "vcast_stat_scale", &battle_config.vcast_stat_scale, 530, 1, INT_MAX, },
{ "area_size", &battle_config.area_size, 14, 0, INT_MAX, },
+ { "chat_area_size", &battle_config.chat_area_size, 9, 0, INT_MAX, },
{ "zeny_from_mobs", &battle_config.zeny_from_mobs, 0, 0, 1, },
{ "mobs_level_up", &battle_config.mobs_level_up, 0, 0, 1, },
{ "mobs_level_up_exp_rate", &battle_config.mobs_level_up_exp_rate, 1, 1, INT_MAX, },
@@ -7319,7 +7329,11 @@ static const struct battle_data {
{ "save_body_style", &battle_config.save_body_style, 0, 0, 1, },
{ "player_warp_keep_direction", &battle_config.player_warp_keep_direction, 0, 0, 1, },
{ "atcommand_levelup_events", &battle_config.atcommand_levelup_events, 0, 0, 1, },
+ { "bow_unequip_arrow", &battle_config.bow_unequip_arrow, 1, 0, 1, },
{ "max_summoner_parameter", &battle_config.max_summoner_parameter, 120, 10, 10000, },
+ { "mvp_exp_reward_message", &battle_config.mvp_exp_reward_message, 0, 0, 1, },
+ { "monster_eye_range_bonus", &battle_config.mob_eye_range_bonus, 0, 0, 10, },
+ { "prevent_logout_trigger", &battle_config.prevent_logout_trigger, 0xE, 0, 0xF, }
};
#ifndef STATS_OPT_OUT
/**
@@ -7598,6 +7612,13 @@ void battle_adjust_conf(void) {
}
#endif
+#if PACKETVER < 20131223
+ if (battle_config.mvp_exp_reward_message) {
+ ShowWarning("conf/map/battle/client.conf MVP EXP reward message is enabled but it requires PACKETVER 2013-12-23 or newer, disabling...\n");
+ battle_config.mvp_exp_reward_message = 0;
+ }
+#endif
+
#ifndef CELL_NOSTACK
if (battle_config.custom_cell_stack_limit != 1)
ShowWarning("Battle setting 'custom_cell_stack_limit' takes no effect as this server was compiled without Cell Stack Limit support.\n");
diff --git a/src/map/battle.h b/src/map/battle.h
index 7e7048a38..b5846e457 100644
--- a/src/map/battle.h
+++ b/src/map/battle.h
@@ -362,6 +362,7 @@ struct Battle_Config {
int castrate_dex_scale; // added by [MouseJstr]
int area_size; // added by [MouseJstr]
+ int chat_area_size; // added by [gumi]
int max_def, over_def_bonus; //added by [Skotlex]
@@ -544,8 +545,15 @@ struct Battle_Config {
int player_warp_keep_direction;
int atcommand_levelup_events; // Enable atcommands trigger level up events for NPCs
+
+ int bow_unequip_arrow;
int max_summoner_parameter; // Summoner Max Stats
+ int mvp_exp_reward_message;
+
+ int mob_eye_range_bonus; //Vulture's Eye and Snake's Eye range bonus
+
+ int prevent_logout_trigger;
};
/* criteria for battle_config.idletime_critera */
diff --git a/src/map/clif.c b/src/map/clif.c
index 887fa9d64..8ab6e71a4 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -451,8 +451,8 @@ bool clif_send(const void* buf, int len, struct block_list* bl, enum send_target
break;
case AREA_CHAT_WOC:
nullpo_retr(true, bl);
- map->foreachinarea(clif->send_sub, bl->m, bl->x-(AREA_SIZE-5), bl->y-(AREA_SIZE-5),
- bl->x+(AREA_SIZE-5), bl->y+(AREA_SIZE-5), BL_PC, buf, len, bl, AREA_WOC);
+ map->foreachinarea(clif->send_sub, bl->m, bl->x-CHAT_AREA_SIZE, bl->y-CHAT_AREA_SIZE,
+ bl->x+CHAT_AREA_SIZE, bl->y+CHAT_AREA_SIZE, BL_PC, buf, len, bl, AREA_WOC);
break;
case CHAT:
@@ -677,7 +677,8 @@ void clif_authok(struct map_session_data *sd)
#if PACKETVER >= 20080102
p.font = sd->status.font;
#endif
-#if PACKETVER >= 20141016
+// Some clients smaller than 20160330 cant be tested [4144]
+#if PACKETVER >= 20141016 && PACKETVER < 20160330
p.sex = sd->status.sex;
#endif
clif->send(&p,sizeof(p),&sd->bl,SELF);
@@ -1077,15 +1078,21 @@ void clif_set_unit_idle(struct block_list* bl, struct map_session_data *tsd, enu
#endif
#if PACKETVER >= 20150513
p.body = vd->body_style;
+#endif
+/* Might be earlier, this is when the named item bug began */
+#if PACKETVER >= 20131223
safestrncpy(p.name, clif->get_bl_name(bl), NAME_LENGTH);
#endif
-
clif->send(&p,sizeof(p),tsd?&tsd->bl:bl,target);
if (clif->isdisguised(bl)) {
#if PACKETVER >= 20091103
p.objecttype = pc->db_checkid(status->get_viewdata(bl)->class) ? 0x0 : 0x5; //PC_TYPE : NPC_MOB_TYPE
+#if PACKETVER >= 20131223
+ p.AID = -bl->id;
+#else
p.GID = -bl->id;
+#endif
#else
p.GID = -bl->id;
#endif
@@ -1220,6 +1227,9 @@ void clif_spawn_unit(struct block_list* bl, enum send_target target) {
#endif
#if PACKETVER >= 20150513
p.body = vd->body_style;
+#endif
+/* Might be earlier, this is when the named item bug began */
+#if PACKETVER >= 20131223
safestrncpy(p.name, clif->get_bl_name(bl), NAME_LENGTH);
#endif
if (clif->isdisguised(bl)) {
@@ -1228,7 +1238,11 @@ void clif_spawn_unit(struct block_list* bl, enum send_target target) {
clif->send(&p,sizeof(p),bl,target);
#if PACKETVER >= 20091103
p.objecttype = pc->db_checkid(status->get_viewdata(bl)->class) ? 0x0 : 0x5; //PC_TYPE : NPC_MOB_TYPE
+#if PACKETVER >= 20131223
+ p.AID = -bl->id;
+#else
p.GID = -bl->id;
+#endif
#else
p.GID = -bl->id;
#endif
@@ -1262,7 +1276,7 @@ void clif_set_unit_walking(struct block_list* bl, struct map_session_data *tsd,
#endif
#if PACKETVER >= 20131223
p.AID = bl->id;
- p.GID = (tsd) ? tsd->status.char_id : 0; // CCODE
+ p.GID = (sd) ? sd->status.char_id : 0; // CCODE
#else
p.GID = bl->id;
#endif
@@ -1312,6 +1326,9 @@ void clif_set_unit_walking(struct block_list* bl, struct map_session_data *tsd,
#endif
#if PACKETVER >= 20150513
p.body = vd->body_style;
+#endif
+/* Might be earlier, this is when the named item bug began */
+#if PACKETVER >= 20131223
safestrncpy(p.name, clif->get_bl_name(bl), NAME_LENGTH);
#endif
@@ -1320,7 +1337,11 @@ void clif_set_unit_walking(struct block_list* bl, struct map_session_data *tsd,
if (clif->isdisguised(bl)) {
#if PACKETVER >= 20091103
p.objecttype = pc->db_checkid(status->get_viewdata(bl)->class) ? 0x0 : 0x5; //PC_TYPE : NPC_MOB_TYPE
+#if PACKETVER >= 20131223
+ p.AID = -bl->id;
+#else
p.GID = -bl->id;
+#endif
#else
p.GID = -bl->id;
#endif
@@ -1332,7 +1353,7 @@ void clif_set_unit_walking(struct block_list* bl, struct map_session_data *tsd,
/// 01b0 <id>.L <type>.B <value>.L
/// type:
/// unused
-void clif_class_change(struct block_list *bl, int class_, int type)
+void clif_class_change(struct block_list *bl, int class_, int type, struct map_session_data *sd)
{
nullpo_retv(bl);
@@ -1343,7 +1364,11 @@ void clif_class_change(struct block_list *bl, int class_, int type)
WBUFL(buf,2)=bl->id;
WBUFB(buf,6)=type;
WBUFL(buf,7)=class_;
- clif->send(buf,packet_len(0x1b0),bl,AREA);
+
+ if (sd == NULL)
+ clif->send(buf, packet_len(0x1b0), bl, AREA);
+ else
+ clif->send(buf, packet_len(0x1b0), &sd->bl, SELF);
}
}
@@ -2378,23 +2403,37 @@ void clif_addcards2(unsigned short *cards, struct item* item) {
}
/**
- * Fills in RandomOptions(Bonuses) of items into the buffer
+ * Fills in ItemOptions(Bonuses) of items into the buffer
*
- * Dummy datais used since this feature isn't supported yet (ITEM_RDM_OPT).
- * A maximum of 5 random options can be supported.
+ * A maximum of 5 item options can be supported.
*
* @param buf[in,out] The buffer to write to. The pointer must be valid and initialized.
* @param item[in] The source item.
*/
-void clif_add_random_options(unsigned char* buf, struct item* item)
-{
- int i;
- nullpo_retv(buf);
- for (i = 0; i < 5; i++){
- WBUFW(buf,i*5+0) = 0; // OptIndex
- WBUFW(buf,i*5+2) = 0; // Value
- WBUFB(buf,i*5+4) = 0; // Param1
+ int clif_add_item_options(struct ItemOptions *buf, const struct item *it)
+{
+ int i = 0, j = 0, total_options = 0;
+
+ nullpo_ret(buf);
+
+ // Append the buffer with existing options first.
+ for (i = 0; i < MAX_ITEM_OPTIONS; i++) {
+ if (it->option[i].index) {
+ WBUFW(buf, j * 5 + 0) = it->option[i].index; // OptIndex
+ WBUFW(buf, j * 5 + 2) = it->option[i].value; // Value
+ WBUFB(buf, j * 5 + 4) = it->option[i].param; // Param1
+ total_options++;
+ j++;
+ }
+ }
+ // Append the remaining buffer with no values;
+ for (; j < MAX_ITEM_OPTIONS || j < 5; j++) {
+ WBUFW(buf, j * 5 + 0) = 0;
+ WBUFW(buf, j * 5 + 2) = 0;
+ WBUFB(buf, j * 5 + 4) = 0;
}
+
+ return total_options;
}
/// Notifies the client, about a received inventory item or the result of a pick-up request.
@@ -2418,9 +2457,6 @@ void clif_additem(struct map_session_data *sd, int n, int amount, int fail) {
p.count = amount;
if( !fail ) {
-#if PACKETVER >= 20150226
- int i;
-#endif
if( n < 0 || n >= MAX_INVENTORY || sd->status.inventory[n].nameid <=0 || sd->inventory_data[n] == NULL )
return;
@@ -2445,11 +2481,7 @@ void clif_additem(struct map_session_data *sd, int n, int amount, int fail) {
p.bindOnEquipType = sd->status.inventory[n].bound && !itemdb->isstackable2(sd->inventory_data[n]) ? 2 : sd->inventory_data[n]->flag.bindonequip ? 1 : 0;
#endif
#if PACKETVER >= 20150226
- for (i=0; i<5; i++){
- p.option_data[i].index = 0;
- p.option_data[i].value = 0;
- p.option_data[i].param = 0;
- }
+ clif->add_item_options(&p.option_data[0], &sd->status.inventory[n]);
#endif
}
p.result = (unsigned char)fail;
@@ -2522,41 +2554,39 @@ void clif_item_sub(unsigned char *buf, int n, struct item *i, struct item_data *
}
-void clif_item_equip(short idx, struct EQUIPITEM_INFO *p, struct item *i, struct item_data *id, int eqp_pos) {
-#if PACKETVER >= 20150226
- int j;
-#endif
+void clif_item_equip(short idx, struct EQUIPITEM_INFO *p, struct item *it, struct item_data *id, int eqp_pos)
+{
nullpo_retv(p);
- nullpo_retv(i);
+ nullpo_retv(it);
nullpo_retv(id);
p->index = idx;
if (id->view_id > 0)
p->ITID = id->view_id;
else
- p->ITID = i->nameid;
+ p->ITID = it->nameid;
p->type = itemtype(id->type);
#if PACKETVER < 20120925
- p->IsIdentified = i->identify ? 1 : 0;
+ p->IsIdentified = it->identify ? 1 : 0;
#endif
p->location = eqp_pos;
- p->WearState = i->equip;
+ p->WearState = it->equip;
#if PACKETVER < 20120925
- p->IsDamaged = (i->attribute & ATTR_BROKEN) != 0 ? 1 : 0;
+ p->IsDamaged = (it->attribute & ATTR_BROKEN) != 0 ? 1 : 0;
#endif
- p->RefiningLevel = i->refine;
+ p->RefiningLevel = it->refine;
- clif->addcards2(&p->slot.card[0], i);
+ clif->addcards2(&p->slot.card[0], it);
#if PACKETVER >= 20071002
- p->HireExpireDate = i->expire_time;
+ p->HireExpireDate = it->expire_time;
#endif
#if PACKETVER >= 20080102
- p->bindOnEquipType = i->bound ? 2 : id->flag.bindonequip ? 1 : 0;
+ p->bindOnEquipType = it->bound ? 2 : id->flag.bindonequip ? 1 : 0;
#endif
#if PACKETVER >= 20100629
@@ -2564,19 +2594,14 @@ void clif_item_equip(short idx, struct EQUIPITEM_INFO *p, struct item *i, struct
#endif
#if PACKETVER >= 20120925
- p->Flag.IsIdentified = i->identify ? 1 : 0;
- p->Flag.IsDamaged = (i->attribute & ATTR_BROKEN) != 0 ? 1 : 0;
- p->Flag.PlaceETCTab = i->favorite ? 1 : 0;
+ p->Flag.IsIdentified = it->identify ? 1 : 0;
+ p->Flag.IsDamaged = (it->attribute & ATTR_BROKEN) != 0 ? 1 : 0;
+ p->Flag.PlaceETCTab = it->favorite ? 1 : 0;
p->Flag.SpareBits = 0;
#endif
#if PACKETVER >= 20150226
- p->option_count = 0;
- for (j=0; j<5; j++){
- p->option_data[j].index = 0;
- p->option_data[j].value = 0;
- p->option_data[j].param = 0;
- }
+ p->option_count = clif->add_item_options(p->option_data, it);
#endif
}
@@ -3992,7 +4017,7 @@ void clif_tradeadditem(struct map_session_data* sd, struct map_session_data* tsd
WBUFW(buf,15)= 0; //card (4w)
WBUFW(buf,17)= 0; //card (4w)
#if PACKETVER >= 20150226
- clif->add_random_options(WBUFP(buf, 19), &sd->status.inventory[index]);
+ clif->add_item_options(WBUFP(buf, 19), &sd->status.inventory[index]);
#endif
}
else
@@ -4018,7 +4043,7 @@ void clif_tradeadditem(struct map_session_data* sd, struct map_session_data* tsd
WBUFB(buf,10)= sd->status.inventory[index].refine; //refine
clif->addcards(WBUFP(buf, 11), &sd->status.inventory[index]);
#if PACKETVER >= 20150226
- clif->add_random_options(WBUFP(buf, 19), &sd->status.inventory[index]);
+ clif->add_item_options(WBUFP(buf, 19), &sd->status.inventory[index]);
#endif
}
WFIFOSET(fd,packet_len(tradeaddType));
@@ -4149,7 +4174,7 @@ void clif_storageitemadded(struct map_session_data* sd, struct item* i, int inde
WFIFOB(fd,12+offset) = i->refine; //refine
clif->addcards(WFIFOP(fd,13+offset), i);
#if PACKETVER >= 20150226
- clif->add_random_options(WFIFOP(fd,21+offset), i);
+ clif->add_item_options(WFIFOP(fd,21+offset), i);
#endif
WFIFOSET(fd,packet_len(storageaddType));
}
@@ -6223,7 +6248,7 @@ void clif_cart_additem(struct map_session_data *sd,int n,int amount,int fail)
WBUFB(buf,12+offset)=sd->status.cart[n].refine;
clif->addcards(WBUFP(buf,13+offset), &sd->status.cart[n]);
#if PACKETVER >= 20150226
- clif->add_random_options(WBUFP(buf,21+offset), &sd->status.cart[n]);
+ clif->add_item_options(WBUFP(buf,21+offset), &sd->status.cart[n]);
#endif
WFIFOSET(fd,packet_len(cartaddType));
}
@@ -6351,7 +6376,7 @@ void clif_vendinglist(struct map_session_data* sd, unsigned int id, struct s_ven
WFIFOB(fd,offset+13+i*item_length) = vsd->status.cart[index].refine;
clif->addcards(WFIFOP(fd,offset+14+i*item_length), &vsd->status.cart[index]);
#if PACKETVER >= 20150226
- clif->add_random_options(WFIFOP(fd,offset+22+i*item_length), &vsd->status.cart[index]);
+ clif->add_item_options(WFIFOP(fd,offset+22+i*item_length), &vsd->status.cart[index]);
#endif
}
WFIFOSET(fd,WFIFOW(fd,2));
@@ -6417,7 +6442,7 @@ void clif_openvending(struct map_session_data* sd, int id, struct s_vending* ven
WFIFOB(fd,21+i*item_length) = sd->status.cart[index].refine;
clif->addcards(WFIFOP(fd,22+i*item_length), &sd->status.cart[index]);
#if PACKETVER >= 20150226
- clif->add_random_options(WFIFOP(fd,30+22+i*item_length), &sd->status.cart[index]);
+ clif->add_item_options(WFIFOP(fd,30+22+i*item_length), &sd->status.cart[index]);
#endif
}
WFIFOSET(fd,WFIFOW(fd,2));
@@ -7232,6 +7257,13 @@ void clif_mvp_item(struct map_session_data *sd,int nameid)
/// 010b <exp>.L
void clif_mvp_exp(struct map_session_data *sd, unsigned int exp)
{
+#if PACKETVER >= 20131223 // Kro removed this packet [Napster]
+ if (battle_config.mvp_exp_reward_message) {
+ char e_msg[CHAT_SIZE_MAX];
+ sprintf(e_msg, msg_txt(855), exp);
+ clif->messagecolor_self(sd->fd, COLOR_CYAN, e_msg); // Congratulations! You are the MVP! Your reward EXP Points are %u !!
+ }
+#else
int fd;
nullpo_retv(sd);
@@ -7241,6 +7273,7 @@ void clif_mvp_exp(struct map_session_data *sd, unsigned int exp)
WFIFOW(fd,0)=0x10b;
WFIFOL(fd,2)=cap_value(exp,0,INT32_MAX);
WFIFOSET(fd,packet_len(0x10b));
+#endif
}
/// Dropped MVP item reward message (ZC_THROW_MVPITEM).
@@ -10992,39 +11025,36 @@ void clif_parse_RemoveOption(int fd,struct map_session_data *sd)
void clif_parse_ChangeCart(int fd,struct map_session_data *sd) __attribute__((nonnull (2)));
/// Request to change cart's visual look (CZ_REQ_CHANGECART).
/// 01af <num>.W
-void clif_parse_ChangeCart(int fd,struct map_session_data *sd)
+void clif_parse_ChangeCart(int fd, struct map_session_data *sd)
{// TODO: State tracking?
int type;
- if( pc->checkskill(sd, MC_CHANGECART) < 1 )
+ if (pc->checkskill(sd, MC_CHANGECART) == 0)
return;
#ifdef RENEWAL
- if( sd->npc_id || sd->state.workinprogress&1 ){
+ if (sd->npc_id || sd->state.workinprogress&1) {
clif->msgtable(sd, MSG_NPC_WORK_IN_PROGRESS);
return;
}
#endif
- type = RFIFOW(fd,2);
+ type = RFIFOW(fd, 2);
+
+ if (
#ifdef NEW_CARTS
- if( (type == 9 && sd->status.base_level > 131) ||
- (type == 8 && sd->status.base_level > 121) ||
- (type == 7 && sd->status.base_level > 111) ||
- (type == 6 && sd->status.base_level > 101) ||
+ (type == 9 && sd->status.base_level > 130) ||
+ (type == 8 && sd->status.base_level > 120) ||
+ (type == 7 && sd->status.base_level > 110) ||
+ (type == 6 && sd->status.base_level > 100) ||
+#endif
(type == 5 && sd->status.base_level > 90) ||
(type == 4 && sd->status.base_level > 80) ||
(type == 3 && sd->status.base_level > 65) ||
(type == 2 && sd->status.base_level > 40) ||
(type == 1))
-#else
- if( (type == 5 && sd->status.base_level > 90) ||
- (type == 4 && sd->status.base_level > 80) ||
- (type == 3 && sd->status.base_level > 65) ||
- (type == 2 && sd->status.base_level > 40) ||
- (type == 1))
-#endif
- pc->setcart(sd,type);
+
+ pc->setcart(sd, type);
}
/// Request to select cart's visual look for new cart design (CZ_SELECTCART).
@@ -11594,7 +11624,12 @@ void clif_parse_NpcStringInput(int fd, struct map_session_data* sd) __attribute_
/// 01d5 <packet len>.W <npc id>.L <string>.?B
void clif_parse_NpcStringInput(int fd, struct map_session_data* sd)
{
- int message_len = RFIFOW(fd,2)-8;
+// [4144] can't confirm exact client version. At least >= correct for 20150513
+#if PACKETVER >= 20151029
+ int message_len = RFIFOW(fd, 2) - 7;
+#else
+ int message_len = RFIFOW(fd, 2) - 8;
+#endif
int npcid = RFIFOL(fd,4);
const char *message = RFIFOP(fd,8);
@@ -16201,7 +16236,7 @@ void clif_bg_hp(struct map_session_data *sd)
{
unsigned char buf[34];
-// packet version can be wrong, because inconsistend data in other servers.
+// packet version can be wrong, because inconsistend data in other servers. From packets table it start from 20140312 [4144]
#if PACKETVER < 20140613
const int cmd = 0x2e0;
nullpo_retv(sd);
@@ -20092,7 +20127,7 @@ void clif_defaults(void) {
clif->pNPCMarketClosed = clif_parse_NPCMarketClosed;
clif->pNPCMarketPurchase = clif_parse_NPCMarketPurchase;
/* */
- clif->add_random_options = clif_add_random_options;
+ clif->add_item_options = clif_add_item_options;
clif->pHotkeyRowShift = clif_parse_HotkeyRowShift;
clif->dressroom_open = clif_dressroom_open;
clif->pOneClick_ItemIdentify = clif_parse_OneClick_ItemIdentify;
diff --git a/src/map/clif.h b/src/map/clif.h
index b27adb5be..6b5fb8dca 100644
--- a/src/map/clif.h
+++ b/src/map/clif.h
@@ -65,9 +65,11 @@ struct view_data;
#define MAX_ROULETTE_COLUMNS 9 /** client-defined value **/
#define RGB2BGR(c) (((c) & 0x0000FF) << 16 | ((c) & 0x00FF00) | ((c) & 0xFF0000) >> 16)
+#define COLOR_CYAN 0x00ffffU
#define COLOR_RED 0xff0000U
#define COLOR_GREEN 0x00ff00U
#define COLOR_WHITE 0xffffffU
+#define COLOR_YELLOW 0xffff00U
#define COLOR_DEFAULT COLOR_GREEN
/**
@@ -671,7 +673,7 @@ struct clif_interface {
void (*changetraplook) (struct block_list *bl,int val);
void (*refreshlook) (struct block_list *bl,int id,int type,int val,enum send_target target);
void (*sendlook) (struct block_list *bl, int id, int type, int val, int val2, enum send_target target);
- void (*class_change) (struct block_list *bl,int class_,int type);
+ void (*class_change) (struct block_list *bl,int class_,int type, struct map_session_data *sd);
void (*skill_delunit) (struct skill_unit *su);
void (*skillunit_update) (struct block_list* bl);
int (*clearunit_delayed_sub) (int tid, int64 tick, int id, intptr_t data);
@@ -1351,7 +1353,7 @@ struct clif_interface {
void (*pNPCMarketClosed) (int fd, struct map_session_data *sd);
void (*pNPCMarketPurchase) (int fd, struct map_session_data *sd);
/* */
- void (*add_random_options) (unsigned char* buf, struct item* item);
+ int (*add_item_options) (struct ItemOptions *buf, const struct item *it);
void (*pHotkeyRowShift) (int fd, struct map_session_data *sd);
void (*dressroom_open) (struct map_session_data *sd, int view);
void (*pOneClick_ItemIdentify) (int fd,struct map_session_data *sd);
diff --git a/src/map/itemdb.c b/src/map/itemdb.c
index 445307aeb..a35aa67f1 100644
--- a/src/map/itemdb.c
+++ b/src/map/itemdb.c
@@ -321,6 +321,16 @@ struct item_data* itemdb_exists(int nameid)
return item;
}
+/**
+ * Searches for the item_option data.
+ * @param option_index as the index of the item option (client side).
+ * @return pointer to struct item_option data or NULL.
+ */
+struct item_option *itemdb_option_exists(int idx)
+{
+ return (struct item_option *)idb_get(itemdb->options, idx);
+}
+
/// Returns human readable name for given item type.
/// @param type Type id to retrieve name for ( IT_* ).
const char* itemdb_typename(int type)
@@ -1299,6 +1309,125 @@ void itemdb_read_packages(void) {
ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", count, config_filename);
}
+/**
+ * Processes any (plugin-defined) additional fields for a itemdb_options entry.
+ *
+ * @param[in,out] entry The destination ito entry, already initialized
+ * (item_opt.index, status.mode are expected to be already set).
+ * @param[in] t The libconfig entry.
+ * @param[in] source Source of the entry (file name), to be displayed in
+ * case of validation errors.
+ */
+void itemdb_readdb_options_additional_fields(struct item_option *ito, struct config_setting_t *t, const char *source)
+{
+ // do nothing. plugins can do their own work
+}
+
+/**
+ * Reads the Item Options configuration file.
+ */
+void itemdb_read_options(void)
+{
+ struct config_t item_options_db;
+ struct config_setting_t *ito = NULL, *conf = NULL;
+ int index = 0, count = 0;
+ const char *filepath = "db/item_options.conf";
+ VECTOR_DECL(int) duplicate_id;
+
+ if (!libconfig->load_file(&item_options_db, filepath))
+ return;
+
+#ifdef ENABLE_CASE_CHECK
+ script->parser_current_file = filepath;
+#endif // ENABLE_CASE_CHECK
+
+ if ((ito=libconfig->setting_get_member(item_options_db.root, "item_options_db")) == NULL) {
+ ShowError("itemdb_read_options: '%s' could not be loaded.\n", filepath);
+ libconfig->destroy(&item_options_db);
+ return;
+ }
+
+ VECTOR_INIT(duplicate_id);
+
+ VECTOR_ENSURE(duplicate_id, libconfig->setting_length(ito), 1);
+
+ while ((conf = libconfig->setting_get_elem(ito, index++))) {
+ struct item_option t_opt = { 0 }, *s_opt = NULL;
+ const char *str = NULL;
+ int i = 0;
+
+ /* Id Lookup */
+ if (!libconfig->setting_lookup_int16(conf, "Id", &t_opt.index) || t_opt.index <= 0) {
+ ShowError("itemdb_read_options: Invalid Option Id provided for entry %d in '%s', skipping...\n", t_opt.index, filepath);
+ continue;
+ }
+
+ /* Checking for duplicate entries. */
+ ARR_FIND(0, VECTOR_LENGTH(duplicate_id), i, VECTOR_INDEX(duplicate_id, i) == t_opt.index);
+
+ if (i != VECTOR_LENGTH(duplicate_id)) {
+ ShowError("itemdb_read_options: Duplicate entry for Option Id %d in '%s', skipping...\n", t_opt.index, filepath);
+ continue;
+ }
+
+ VECTOR_PUSH(duplicate_id, t_opt.index);
+
+ /* Name Lookup */
+ if (!libconfig->setting_lookup_string(conf, "Name", &str)) {
+ ShowError("itemdb_read_options: Invalid Option Name '%s' provided for Id %d in '%s', skipping...\n", str, t_opt.index, filepath);
+ continue;
+ }
+
+ /* check for illegal characters in the constant. */
+ {
+ const char *c = str;
+
+ while (ISALNUM(*c) || *c == '_')
+ ++c;
+
+ if (*c != '\0') {
+ ShowError("itemdb_read_options: Invalid characters in Option Name '%s' for Id %d in '%s', skipping...\n", str, t_opt.index, filepath);
+ continue;
+ }
+ }
+
+ /* Set name as a script constant with index as value. */
+ script->set_constant2(str, t_opt.index, false, false);
+
+ /* Script Code Lookup */
+ if (!libconfig->setting_lookup_string(conf, "Script", &str)) {
+ ShowError("itemdb_read_options: Script code not found for entry %s (Id: %d) in '%s', skipping...\n", str, t_opt.index, filepath);
+ continue;
+ }
+
+ /* Set Script */
+ t_opt.script = *str ? script->parse(str, filepath, t_opt.index, SCRIPT_IGNORE_EXTERNAL_BRACKETS, NULL) : NULL;
+
+ /* Additional fields through plugins */
+ itemdb->readdb_options_additional_fields(&t_opt, ito, filepath);
+
+ /* Allocate memory and copy contents */
+ CREATE(s_opt, struct item_option, 1);
+
+ *s_opt = t_opt;
+
+ /* Store ptr in the database */
+ idb_put(itemdb->options, t_opt.index, s_opt);
+
+ count++;
+ }
+
+#ifdef ENABLE_CASE_CHECK
+ script->parser_current_file = NULL;
+#endif // ENABLE_CASE_CHECK
+
+ libconfig->destroy(&item_options_db);
+
+ VECTOR_CLEAR(duplicate_id);
+
+ ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", count, filepath);
+}
+
void itemdb_read_chains(void) {
struct config_t item_chain_conf;
struct config_setting_t *itc = NULL;
@@ -1674,7 +1803,10 @@ int itemdb_validate_entry(struct item_data *entry, int n, const char *source) {
if( entry->type != IT_ARMOR && entry->type != IT_WEAPON && !entry->flag.no_refine )
entry->flag.no_refine = 1;
-
+
+ if (entry->type != IT_ARMOR && entry->type != IT_WEAPON && !entry->flag.no_options)
+ entry->flag.no_options = 1;
+
if (entry->flag.available != 1) {
entry->flag.available = 1;
entry->view_id = 0;
@@ -1922,6 +2054,9 @@ int itemdb_readdb_libconfig_sub(struct config_setting_t *it, int n, const char *
if( (t = libconfig->setting_get_member(it, "Refine")) )
id.flag.no_refine = libconfig->setting_get_bool(t) ? 0 : 1;
+
+ if ((t = libconfig->setting_get_member(it, "DisableOptions")))
+ id.flag.no_options = libconfig->setting_get_bool(t) ? 1 : 0;
if( itemdb->lookup_const(it, "View", &i32) && i32 >= 0 )
id.look = i32;
@@ -2165,6 +2300,7 @@ void itemdb_read(bool minimal) {
itemdb->read_groups();
itemdb->read_chains();
itemdb->read_packages();
+ itemdb->read_options();
}
@@ -2226,6 +2362,17 @@ int itemdb_final_sub(union DBKey key, struct DBData *data, va_list ap)
return 0;
}
+
+int itemdb_options_final_sub(union DBKey key, struct DBData *data, va_list ap)
+{
+ struct item_option *ito = DB->data2ptr(data);
+
+ if (ito->script != NULL)
+ script->free_code(ito->script);
+
+ return 0;
+}
+
void itemdb_clear(bool total) {
int i;
// clear the previous itemdb data
@@ -2289,6 +2436,7 @@ void itemdb_clear(bool total) {
return;
itemdb->other->clear(itemdb->other, itemdb->final_sub);
+ itemdb->options->clear(itemdb->options, itemdb->options_final_sub);
memset(itemdb->array, 0, sizeof(itemdb->array));
@@ -2373,6 +2521,7 @@ void do_final_itemdb(void) {
itemdb->clear(true);
itemdb->other->destroy(itemdb->other, itemdb->final_sub);
+ itemdb->options->destroy(itemdb->options, itemdb->options_final_sub);
itemdb->destroy_item_data(&itemdb->dummy, 0);
db_destroy(itemdb->names);
}
@@ -2380,6 +2529,7 @@ void do_final_itemdb(void) {
void do_init_itemdb(bool minimal) {
memset(itemdb->array, 0, sizeof(itemdb->array));
itemdb->other = idb_alloc(DB_OPT_BASE);
+ itemdb->options = idb_alloc(DB_OPT_RELEASE_DATA);
itemdb->names = strdb_alloc(DB_OPT_BASE,ITEM_NAME_LENGTH);
itemdb->create_dummy_data(); //Dummy data item.
itemdb->read(minimal);
@@ -2422,6 +2572,7 @@ void itemdb_defaults(void) {
itemdb->read_groups = itemdb_read_groups;
itemdb->read_chains = itemdb_read_chains;
itemdb->read_packages = itemdb_read_packages;
+ itemdb->read_options = itemdb_read_options;
/* */
itemdb->write_cached_packages = itemdb_write_cached_packages;
itemdb->read_cached_packages = itemdb_read_cached_packages;
@@ -2432,6 +2583,7 @@ void itemdb_defaults(void) {
itemdb->load = itemdb_load;
itemdb->search = itemdb_search;
itemdb->exists = itemdb_exists;
+ itemdb->option_exists = itemdb_option_exists;
itemdb->in_group = itemdb_in_group;
itemdb->group_item = itemdb_searchrandomid;
itemdb->chain_item = itemdb_chain_item;
@@ -2464,6 +2616,7 @@ void itemdb_defaults(void) {
itemdb->read_combos = itemdb_read_combos;
itemdb->gendercheck = itemdb_gendercheck;
itemdb->validate_entry = itemdb_validate_entry;
+ itemdb->readdb_options_additional_fields = itemdb_readdb_options_additional_fields;
itemdb->readdb_additional_fields = itemdb_readdb_additional_fields;
itemdb->readdb_job_sub = itemdb_readdb_job_sub;
itemdb->readdb_libconfig_sub = itemdb_readdb_libconfig_sub;
@@ -2472,6 +2625,7 @@ void itemdb_defaults(void) {
itemdb->read = itemdb_read;
itemdb->destroy_item_data = destroy_item_data;
itemdb->final_sub = itemdb_final_sub;
+ itemdb->options_final_sub = itemdb_options_final_sub;
itemdb->clear = itemdb_clear;
itemdb->id2combo = itemdb_id2combo;
itemdb->is_item_usable = itemdb_is_item_usable;
diff --git a/src/map/itemdb.h b/src/map/itemdb.h
index 571512e49..138a783ae 100644
--- a/src/map/itemdb.h
+++ b/src/map/itemdb.h
@@ -147,6 +147,23 @@ enum item_itemid {
ITEMID_BLACK_THING = 12435,
ITEMID_BOARDING_HALTER = 12622,
ITEMID_NOBLE_NAMEPLATE = 12705,
+ ITEMID_POISON_PARALYSIS = 12717,
+ ITEMID_POISON_LEECH = 12718,
+ ITEMID_POISON_OBLIVION = 12719,
+ ITEMID_POISON_CONTAMINATION = 12720,
+ ITEMID_POISON_NUMB = 12721,
+ ITEMID_POISON_FEVER = 12722,
+ ITEMID_POISON_LAUGHING = 12723,
+ ITEMID_POISON_FATIGUE = 12724,
+ ITEMID_NAUTHIZ = 12725,
+ ITEMID_RAIDO = 12726,
+ ITEMID_BERKANA = 12727,
+ ITEMID_ISA = 12728,
+ ITEMID_OTHILA = 12729,
+ ITEMID_URUZ = 12730,
+ ITEMID_THURISAZ = 12731,
+ ITEMID_WYRD = 12732,
+ ITEMID_HAGALAZ = 12733,
ITEMID_DUN_TELE_SCROLL1 = 14527,
ITEMID_BATTLE_MANUAL25 = 14532,
ITEMID_BATTLE_MANUAL100 = 14533,
@@ -161,6 +178,7 @@ enum item_itemid {
ITEMID_PILEBUNCKER_S = 16030,
ITEMID_PILEBUNCKER_P = 16031,
ITEMID_PILEBUNCKER_T = 16032,
+ ITEMID_LUX_ANIMA = 22540,
};
enum cards_item_list {
@@ -262,37 +280,6 @@ enum cash_food_item_list {
};
/**
- * GC Poison
- */
-enum poison_item_list {
- ITEMID_POISON_PARALYSIS = 12717,
- ITEMID_POISON_LEECH, // 12718
- ITEMID_POISON_OBLIVION, // 12719
- ITEMID_POISON_CONTAMINATION, // 12720
- ITEMID_POISON_NUMB, // 12721
- ITEMID_POISON_FEVER, // 12722
- ITEMID_POISON_LAUGHING, // 12723
- ITEMID_POISON_FATIGUE, // 12724
-};
-
-
-/**
- * Rune Knight
- **/
-enum rune_item_list {
- ITEMID_NAUTHIZ = 12725,
- ITEMID_RAIDO, // 12726
- ITEMID_BERKANA, // 12727
- ITEMID_ISA, // 12728
- ITEMID_OTHILA, // 12729
- ITEMID_URUZ, // 12730
- ITEMID_THURISAZ, // 12731
- ITEMID_WYRD, // 12732
- ITEMID_HAGALAZ, // 12733
- ITEMID_LUX_ANIMA = 22540,
-};
-
-/**
* Geneticist
*/
enum geneticist_item_list {
@@ -388,7 +375,7 @@ enum ItemTradeRestrictions {
};
/**
- * Iten No-use restrictions
+ * Item No-use restrictions
*/
enum ItemNouseRestrictions {
INR_NONE = 0x0, ///< No restrictions
@@ -397,6 +384,16 @@ enum ItemNouseRestrictions {
INR_ALL = 0x1 ///< Sum of all the above values
};
+/**
+ * Item Option Types
+ */
+enum ItemOptionTypes {
+ IT_OPT_INDEX = 0,
+ IT_OPT_VALUE,
+ IT_OPT_PARAM,
+ IT_OPT_MAX
+};
+
/** Convenience item list (entry) used in various functions */
struct itemlist_entry {
int id; ///< Item ID or (inventory) index
@@ -462,6 +459,11 @@ struct item_package {
unsigned short must_qty;
};
+struct item_option {
+ int16 index;
+ struct script_code *script;
+};
+
struct item_data {
uint16 nameid;
char name[ITEM_NAME_LENGTH],jname[ITEM_NAME_LENGTH];
@@ -507,6 +509,7 @@ struct item_data {
unsigned bindonequip : 1;
unsigned keepafteruse : 1;
unsigned force_serial : 1;
+ unsigned no_options: 1; // < disallows use of item options on the item. (non-equippable items are automatically flagged) [Smokexyz]
} flag;
struct {// item stacking limitation
unsigned short amount;
@@ -548,8 +551,8 @@ struct item_data {
#define itemdb_value_buy(n) (itemdb->search(n)->value_buy)
#define itemdb_value_sell(n) (itemdb->search(n)->value_sell)
#define itemdb_canrefine(n) (!itemdb->search(n)->flag.no_refine)
+#define itemdb_allowoption(n) (!itemdb->search(n)->flag.no_options)
-#define itemdb_is_rune(n) (((n) >= ITEMID_NAUTHIZ && (n) <= ITEMID_HAGALAZ) || (n) == ITEMID_LUX_ANIMA)
#define itemdb_is_element(n) ((n) >= ITEMID_SCARLET_PTS && (n) <= ITEMID_LIME_GREEN_PTS)
#define itemdb_is_spellbook(n) ((n) >= ITEMID_MAGIC_BOOK_FB && (n) <= ITEMID_MAGIC_BOOK_DL)
#define itemdb_is_poison(n) ((n) >= ITEMID_POISON_PARALYSIS && (n) <= ITEMID_POISON_FATIGUE)
@@ -595,11 +598,13 @@ struct itemdb_interface {
/* */
struct item_data *array[MAX_ITEMDB];
struct DBMap *other;// int nameid -> struct item_data*
+ struct DBMap *options; // int opt_id -> struct item_option*
struct item_data dummy; //This is the default dummy item used for non-existant items. [Skotlex]
/* */
void (*read_groups) (void);
void (*read_chains) (void);
void (*read_packages) (void);
+ void (*read_options) (void);
/* */
void (*write_cached_packages) (const char *config_filename);
bool (*read_cached_packages) (const char *config_filename);
@@ -610,6 +615,7 @@ struct itemdb_interface {
struct item_data* (*load)(int nameid);
struct item_data* (*search)(int nameid);
struct item_data* (*exists) (int nameid);
+ struct item_option* (*option_exists) (int idx);
bool (*in_group) (struct item_group *group, int nameid);
int (*group_item) (struct item_group *group);
int (*chain_item) (unsigned short chain_id, int *rate);
@@ -642,6 +648,7 @@ struct itemdb_interface {
void (*read_combos) (void);
int (*gendercheck) (struct item_data *id);
int (*validate_entry) (struct item_data *entry, int n, const char *source);
+ void (*readdb_options_additional_fields) (struct item_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_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);
@@ -650,6 +657,7 @@ struct itemdb_interface {
void (*read) (bool minimal);
void (*destroy_item_data) (struct item_data *self, int free_self);
int (*final_sub) (union DBKey key, struct DBData *data, va_list ap);
+ int (*options_final_sub) (union DBKey key, struct DBData *data, va_list ap);
void (*clear) (bool total);
struct item_combo * (*id2combo) (unsigned short id);
bool (*is_item_usable) (struct item_data *item);
diff --git a/src/map/log.c b/src/map/log.c
index 902d428a7..6419c4766 100644
--- a/src/map/log.c
+++ b/src/map/log.c
@@ -161,12 +161,15 @@ void log_branch(struct map_session_data* sd) {
}
void log_pick_sub_sql(int id, int16 m, e_log_pick_type type, int amount, struct item* itm, struct item_data *data) {
nullpo_retv(itm);
- if( SQL_ERROR == SQL->Query(logs->mysql_handle,
- LOG_QUERY " INTO `%s` (`time`, `char_id`, `type`, `nameid`, `amount`, `refine`, `card0`, `card1`, `card2`, `card3`, `map`, `unique_id`) "
- "VALUES (NOW(), '%d', '%c', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%s', '%"PRIu64"')",
+ if (SQL_ERROR == SQL->Query(logs->mysql_handle,
+ LOG_QUERY " INTO `%s` (`time`, `char_id`, `type`, `nameid`, `amount`, `refine`, `card0`, `card1`, `card2`, `card3`, "
+ "`opt_idx0`, `opt_val0`, `opt_idx1`, `opt_val1`, `opt_idx2`, `opt_val2`, `opt_idx3`, `opt_val3`, `opt_idx4`, `opt_val4`, `map`, `unique_id`) "
+ "VALUES (NOW(), '%d', '%c', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%s', '%"PRIu64"')",
logs->config.log_pick, id, logs->picktype2char(type), itm->nameid, amount, itm->refine, itm->card[0], itm->card[1], itm->card[2], itm->card[3],
- map->list[m].name, itm->unique_id)
- ) {
+ itm->option[0].index, itm->option[0].value, itm->option[1].index, itm->option[1].value, itm->option[2].index, itm->option[2].value,
+ itm->option[3].index, itm->option[3].value, itm->option[4].index, itm->option[4].value,
+ map->list[m].name, itm->unique_id))
+ {
Sql_ShowDebug(logs->mysql_handle);
return;
}
diff --git a/src/map/map.h b/src/map/map.h
index b76128762..8c5372093 100644
--- a/src/map/map.h
+++ b/src/map/map.h
@@ -47,6 +47,7 @@ enum E_MAPSERVER_ST {
#define MAX_NPC_PER_MAP 512
#define AREA_SIZE (battle->bc->area_size)
+#define CHAT_AREA_SIZE (battle->bc->chat_area_size)
#define DAMAGELOG_SIZE 30
#define LOOTITEM_SIZE 10
#define MAX_MOBSKILL 50
diff --git a/src/map/mob.c b/src/map/mob.c
index d5932f195..74d25b805 100644
--- a/src/map/mob.c
+++ b/src/map/mob.c
@@ -2832,7 +2832,7 @@ int mob_class_change (struct mob_data *md, int class_) {
mob_stop_walking(md, STOPWALKING_FLAG_NONE);
unit->skillcastcancel(&md->bl, 0);
status->set_viewdata(&md->bl, class_);
- clif->class_change(&md->bl, md->vd->class, 1);
+ clif->class_change(&md->bl, md->vd->class, 1, NULL);
status_calc_mob(md, SCO_FIRST);
md->ud.state.speed_changed = 1; //Speed change update.
diff --git a/src/map/npc.c b/src/map/npc.c
index a824d4216..2876ea595 100644
--- a/src/map/npc.c
+++ b/src/map/npc.c
@@ -2089,6 +2089,8 @@ int npc_selllist_sub(struct map_session_data *sd, struct itemlist *item_list, st
{
char npc_ev[EVENT_NAME_LENGTH];
char card_slot[NAME_LENGTH];
+ char opt_index_str[NAME_LENGTH];
+ char opt_value_str[NAME_LENGTH];
int i, j;
int key_nameid = 0;
int key_amount = 0;
@@ -2096,6 +2098,8 @@ int npc_selllist_sub(struct map_session_data *sd, struct itemlist *item_list, st
int key_attribute = 0;
int key_identify = 0;
int key_card[MAX_SLOTS];
+ int key_opt_idx[MAX_ITEM_OPTIONS];
+ int key_opt_value[MAX_ITEM_OPTIONS];
nullpo_ret(sd);
nullpo_ret(item_list);
@@ -2140,6 +2144,17 @@ int npc_selllist_sub(struct map_session_data *sd, struct itemlist *item_list, st
script->setarray_pc(sd, card_slot, i, (void*)card, &key_card[j]);
}
+ for (j = 0; j < MAX_ITEM_OPTIONS; j++) {
+ intptr_t opt_idx = item->option[j].index;
+ intptr_t opt_value = item->option[j].value;
+
+ snprintf(opt_index_str, sizeof(opt_index_str), "@slot_opt_idx%d", j + 1);
+ script->setarray_pc(sd, opt_index_str, i, (void*)opt_idx, &key_opt_idx[j]);
+
+ snprintf(opt_value_str, sizeof(opt_value_str), "@slot_opt_val%d", j + 1);
+ script->setarray_pc(sd, opt_value_str, i, (void*)opt_value, &key_opt_value[j]);
+ }
+
}
// invoke event
diff --git a/src/map/npc.h b/src/map/npc.h
index 6180e9765..3bd11d536 100644
--- a/src/map/npc.h
+++ b/src/map/npc.h
@@ -125,7 +125,6 @@ struct npc_data {
struct hplugin_data_store *hdata; ///< HPM Plugin Data Store
};
-
#define START_NPC_NUM 110000000
enum actor_classes {
@@ -142,7 +141,7 @@ enum actor_classes {
#define MAX_NPC_CLASS 1000
// New NPC range
#define MAX_NPC_CLASS2_START 10001
-#define MAX_NPC_CLASS2_END 10203
+#define MAX_NPC_CLASS2_END 10248
//Script NPC events.
enum npce_event {
diff --git a/src/map/packets.h b/src/map/packets.h
index c622cb89d..cc2312356 100644
--- a/src/map/packets.h
+++ b/src/map/packets.h
@@ -2146,6 +2146,8 @@ packet(0x96e,-1,clif->ackmergeitems);
// shuffle packets not added
packet(0x097d,288); // ZC_ACK_RANKING
packet(0x097e,12); // ZC_UPDATE_RANKING_POINT
+ packet(0x097f,-1); // ZC_SELECTCART
+ packet(0x0980,7,clif->pSelectCart); // CZ_SELECTCART
#endif
#ifndef PACKETVER_RE
@@ -2220,6 +2222,44 @@ packet(0x96e,-1,clif->ackmergeitems);
packet(0x0436,4,clif->pDull); // CZ_GANGSI_RANK
#endif
+// 2012-09-25aRagexe
+#if PACKETVER >= 20120925
+// new packets (not all)
+ packet(0x0998,8,clif->pEquipItem,2,4);
+#endif
+
+// 2013-02-06aRagexe
+#if PACKETVER >= 20130206
+// new packets
+ packet(0x09a4,18); // ZC_DISPATCH_TIMING_INFO_CHN
+// changed packet sizes
+#endif
+
+// 2013-03-06aRagexe
+#if PACKETVER >= 20130306
+// new packets
+ packet(0x09a6,12); // ZC_BANKING_CHECK
+ packet(0x09a7,14,clif->pDull/*,XXX*/); // CZ_REQ_BANKING_DEPOSIT
+ packet(0x09a8,4); // ZC_ACK_BANKING_DEPOSIT
+ packet(0x09a9,14,clif->pDull/*,XXX*/); // CZ_REQ_BANKING_WITHDRAW
+ packet(0x09aa,4); // ZC_ACK_BANKING_WITHDRAW
+// changed packet sizes
+#endif
+
+// 2013-03-13aRagexe
+#if PACKETVER >= 20130313
+// new packets
+ packet(0x09ab,-1,clif->pDull/*,XXX*/); // CZ_REQ_BANKING_CHECK
+ packet(0x09ac,20,clif->pDull/*,XXX*/); // CZ_REQ_CASH_BARGAIN_SALE_ITEM_INFO
+ packet(0x09ad,6); // ZC_ACK_CASH_BARGAIN_SALE_ITEM_INFO
+ packet(0x09ae,-1,clif->pDull/*,XXX*/); // CZ_REQ_APPLY_BARGAIN_SALE_ITEM
+ packet(0x09af,-1); // ZC_ACK_APPLY_BARGAIN_SALE_ITEM
+ packet(0x09b0,8,clif->pDull/*,XXX*/); // CZ_REQ_REMOVE_BARGAIN_SALE_ITEM
+ packet(0x09b1,6); // ZC_ACK_REMOVE_BARGAIN_SALE_ITEM
+ packet(0x09b2,-1); // ZC_NOTIFY_BARGAIN_SALE_SELLING
+// changed packet sizes
+#endif
+
//2013-03-20Ragexe (Judas + Yommy)
#if PACKETVER >= 20130320
// Shuffle Start
@@ -2258,13 +2298,36 @@ packet(0x96e,-1,clif->ackmergeitems);
packet(0x095a,8,clif->pDull); // CZ_JOIN_BATTLE_FIELD
// Shuffle End
- // New Packets
- packet(0x0998,8,clif->pEquipItem,2,4);
+ // New Packets (wrong version or packet not exists)
packet(0x0447,2); // PACKET_CZ_BLOCKING_PLAY_CANCEL
packet(0x099f,24);
// New Packets End
#endif
+#if PACKETVER >= 20130320
+// new packets
+// changed packet sizes
+ packet(0x09a7,10,clif->pBankDeposit,2,4,6); // CZ_REQ_BANKING_DEPOSIT
+ packet(0x09a8,12); // ZC_ACK_BANKING_DEPOSIT
+ packet(0x09a9,10,clif->pBankWithdraw,2,4,6); // CZ_REQ_BANKING_WITHDRAW
+ packet(0x09aa,12); // ZC_ACK_BANKING_WITHDRAW
+ packet(0x09ab,6,clif->pBankCheck,2,4); // CZ_REQ_BANKING_CHECK
+#endif
+
+// 2013-03-27bRagexe
+#if PACKETVER >= 20130327
+// new packets
+ packet(0x09ac,-1,clif->pDull/*,XXX*/); // CZ_REQ_CASH_BARGAIN_SALE_ITEM_INFO
+ packet(0x09ad,10); // ZC_ACK_CASH_BARGAIN_SALE_ITEM_INFO
+ packet(0x09ae,17,clif->pDull/*,XXX*/); // CZ_REQ_APPLY_BARGAIN_SALE_ITEM
+ packet(0x09af,4); // ZC_ACK_APPLY_BARGAIN_SALE_ITEM
+ packet(0x09b0,8,clif->pDull/*,XXX*/); // CZ_REQ_REMOVE_BARGAIN_SALE_ITEM
+ packet(0x09b1,4); // ZC_ACK_REMOVE_BARGAIN_SALE_ITEM
+ packet(0x09b2,6); // ZC_NOTIFY_BARGAIN_SALE_SELLING
+ packet(0x09b3,6); // ZC_NOTIFY_BARGAIN_SALE_CLOSE
+// changed packet sizes
+#endif
+
//2013-05-15aRagexe (Shakto)
#if PACKETVER >= 20130515
// Shuffle Start
@@ -2527,20 +2590,74 @@ packet(0x96e,-1,clif->ackmergeitems);
packet(0x0436,4,clif->pDull); // CZ_GANGSI_RANK
#endif
-/* Bank System [Yommy/Hercules] */
-#if PACKETVER >= 20130724
-// shuffle packets not added
- packet(0x09A6,12); // ZC_BANKING_CHECK
- packet(0x09A7,10,clif->pBankDeposit,2,4,6);
- packet(0x09A8,16); // ZC_ACK_BANKING_DEPOSIT
- packet(0x09A9,10,clif->pBankWithdraw,2,4,6);
- packet(0x09AA,16); // ZC_ACK_BANKING_WITHDRAW
- packet(0x09AB,6,clif->pBankCheck,2,4);
- ////
- packet(0x09B6,6,clif->pBankOpen,2,4);
- packet(0x09B7,4); // ZC_ACK_OPEN_BANKING
- packet(0x09B8,6,clif->pBankClose,2,4);
- packet(0x09B9,4); // ZC_ACK_CLOSE_BANKING
+// 2013-04-17aRagexe
+#if PACKETVER >= 20130417
+// new packets
+ packet(0x09b4,6,clif->pDull/*,XXX*/); // CZ_OPEN_BARGAIN_SALE_TOOL
+ packet(0x09b5,2); // ZC_OPEN_BARGAIN_SALE_TOOL
+ packet(0x09b6,6,clif->pBankOpen,2,4); // CZ_REQ_OPEN_BANKING
+ packet(0x09b7,4); // ZC_ACK_OPEN_BANKING
+ packet(0x09b8,6,clif->pBankClose,2,4); // CZ_REQ_CLOSE_BANKING
+ packet(0x09b9,4); // ZC_ACK_CLOSE_BANKING
+// changed packet sizes
+#endif
+
+// 2013-04-24aRagexe
+#if PACKETVER >= 20130424
+// new packets
+ packet(0x09ba,6,clif->pDull/*,XXX*/); // CZ_REQ_OPEN_GUILD_STORAGE
+ packet(0x09bb,4); // ZC_ACK_OPEN_GUILD_STORAGE
+ packet(0x09bc,6,clif->pDull/*,XXX*/); // CZ_CLOSE_BARGAIN_SALE_TOOL
+ packet(0x09bd,2); // ZC_CLOSE_BARGAIN_SALE_TOOL
+// changed packet sizes
+#endif
+
+// 2013-05-02aRagexe
+#if PACKETVER >= 20130502
+// new packets
+ packet(0x09be,6,clif->pDull/*,XXX*/); // CZ_REQ_CLOSE_GUILD_STORAGE
+ packet(0x09bf,4); // ZC_ACK_CLOSE_GUILD_STORAGE
+// changed packet sizes
+ packet(0x09bb,6); // ZC_ACK_OPEN_GUILD_STORAGE
+#endif
+
+// 2013-05-15aRagexe
+#if PACKETVER >= 20130515
+// new packets
+ packet(0x09c0,11); // ZC_ACTION_MOVE
+ packet(0x09c1,11); // ZC_C_MARKERINFO
+// changed packet sizes
+ packet(0x09a8,16); // ZC_ACK_BANKING_DEPOSIT
+ packet(0x09aa,16); // ZC_ACK_BANKING_WITHDRAW
+#endif
+
+// 2013-05-29Ragexe
+#if PACKETVER >= 20130529
+// new packets
+ packet(0x09c3,8,clif->pDull/*,XXX*/); // CZ_REQ_COUNT_BARGAIN_SALE_ITEM
+// changed packet sizes
+#endif
+
+// 2013-06-05Ragexe
+#if PACKETVER >= 20130605
+// new packets
+ packet(0x09c4,8); // ZC_ACK_COUNT_BARGAIN_SALE_ITEM
+#endif
+
+// 2013-06-18aRagexe
+#if PACKETVER >= 20130618
+// new packets
+ packet(0x09ca,23); // ZC_SKILL_ENTRY5
+// changed packet sizes
+#endif
+
+// 2013-07-17cRagexe
+#if PACKETVER >= 20130717
+// new packets
+ packet(0x09cb,17); // ZC_USE_SKILL2
+ packet(0x09cc,-1); // ZC_SECRETSCAN_DATA
+// changed packet sizes
+ packet(0x09c1,10); // ZC_C_MARKERINFO
#endif
//2013-08-07Ragexe (Shakto)
@@ -2580,6 +2697,13 @@ packet(0x96e,-1,clif->ackmergeitems);
packet(0x0436,4,clif->pDull); // CZ_GANGSI_RANK
#endif
+// 2013-08-07aRagexe
+#if PACKETVER >= 20130807
+// new packets
+ packet(0x09cd,8); // ZC_MSG_COLOR
+// changed packet sizes
+#endif
+
//2013-08-14aRagexe - Themon
#if PACKETVER >= 20130814
packet(0x0874,7,clif->pActionRequest,2,6);
@@ -2617,6 +2741,129 @@ packet(0x96e,-1,clif->ackmergeitems);
packet(0x0896,8,clif->pDull); // CZ_JOIN_BATTLE_FIELD
#endif
+// 2013-08-14aRagexe
+#if PACKETVER >= 20130814
+// new packets
+ packet(0x09ce,102,clif->pGM_Monster_Item,2); // CZ_ITEM_CREATE_EX
+ packet(0x09cf,-1); // ZC_NPROTECTGAMEGUARDCSAUTH
+ packet(0x09d0,-1,clif->pDull/*,XXX*/); // CZ_NPROTECTGAMEGUARDCSAUTH
+// changed packet sizes
+#endif
+
+// 2013-08-21bRagexe
+#if PACKETVER >= 20130821
+// new packets
+ packet(0x09d1,14); // ZC_PROGRESS_ACTOR
+// changed packet sizes
+#endif
+
+// 2013-08-28bRagexe
+#if PACKETVER >= 20130828
+// new packets
+ packet(0x09d2,-1); // ZC_GUILDSTORAGE_ITEMLIST_NORMAL_V5
+ packet(0x09d3,-1); // ZC_GUILDSTORAGE_ITEMLIST_EQUIP_V5
+// changed packet sizes
+ packet(0x09ba,2,clif->pDull/*,XXX*/); // CZ_REQ_OPEN_GUILD_STORAGE
+ packet(0x09be,2,clif->pDull/*,XXX*/); // CZ_REQ_CLOSE_GUILD_STORAGE
+#endif
+
+// 2013-09-04aRagexe
+#if PACKETVER >= 20130904
+// new packets
+// changed packet sizes
+ packet(0x09ca,-1); // ZC_SKILL_ENTRY5
+#endif
+
+// 2013-09-11aRagexe
+#if PACKETVER >= 20130911
+// new packets
+ packet(0x09d4,2,clif->pNPCShopClosed); // CZ_NPC_TRADE_QUIT
+ packet(0x09d5,-1); // ZC_NPC_MARKET_OPEN
+ packet(0x09d6,-1,clif->pNPCMarketPurchase); // CZ_NPC_MARKET_PURCHASE
+ packet(0x09d7,-1); // ZC_NPC_MARKET_PURCHASE_RESULT
+ packet(0x09d8,2,clif->pNPCMarketClosed); // CZ_NPC_MARKET_CLOSE
+ packet(0x09d9,2,clif->pDull/*,XXX*/); // CZ_REQ_GUILDSTORAGE_LOG
+ packet(0x09da,2); // ZC_ACK_GUILDSTORAGE_LOG
+// changed packet sizes
+#endif
+
+// 2013-09-25aRagexe
+#if PACKETVER >= 20130925
+// new packets
+// changed packet sizes
+ packet(0x09da,10); // ZC_ACK_GUILDSTORAGE_LOG
+#endif
+
+// 2013-10-02aRagexe
+#if PACKETVER >= 20131002
+// new packets
+// changed packet sizes
+ packet(0x09d9,4,clif->pDull/*,XXX*/); // CZ_REQ_GUILDSTORAGE_LOG
+ packet(0x09da,-1); // ZC_ACK_GUILDSTORAGE_LOG
+#endif
+
+// 2013-10-16aRagexe
+#if PACKETVER >= 20131016
+// new packets
+// changed packet sizes
+ packet(0x09d9,6,clif->pDull/*,XXX*/); // CZ_REQ_GUILDSTORAGE_LOG
+#endif
+
+// 2013-10-23aRagexe
+#if PACKETVER >= 20131023
+// new packets
+ packet(0x09db,-1); // ZC_NOTIFY_MOVEENTRY10
+ packet(0x09dc,-1); // ZC_NOTIFY_NEWENTRY10
+ packet(0x09dd,-1); // ZC_NOTIFY_STANDENTRY10
+// changed packet sizes
+ packet(0x09d9,4,clif->pDull/*,XXX*/); // CZ_REQ_GUILDSTORAGE_LOG
+#endif
+
+// 2013-10-30aRagexe
+#if PACKETVER >= 20131030
+// new packets
+ packet(0x09de,-1); // ZC_WHISPER02
+ packet(0x09df,7); // ZC_ACK_WHISPER02
+ packet(0x09e0,-1); // SC_LOGIN_ANSWER_WITH_ID
+#endif
+
+// 2013-11-06aRagexe
+#if PACKETVER >= 20131106
+// new packets
+ packet(0x09e1,8,clif->pDull/*,XXX*/); // CZ_MOVE_ITEM_FROM_BODY_TO_GUILDSTORAGE
+ packet(0x09e2,8,clif->pDull/*,XXX*/); // CZ_MOVE_ITEM_FROM_GUILDSTORAGE_TO_BODY
+ packet(0x09e3,8,clif->pDull/*,XXX*/); // CZ_MOVE_ITEM_FROM_CART_TO_GUILDSTORAGE
+ packet(0x09e4,8,clif->pDull/*,XXX*/); // CZ_MOVE_ITEM_FROM_GUILDSTORAGE_TO_CART
+// changed packet sizes
+#endif
+
+// 2013-11-20dRagexe
+#if PACKETVER >= 20131120
+// new packets
+ packet(0x09e5,14); // ZC_DELETEITEM_FROM_MCSTORE2
+ packet(0x09e6,18); // ZC_UPDATE_ITEM_FROM_BUYING_STORE2
+// changed packet sizes
+#endif
+
+// 2013-11-27bRagexe
+#if PACKETVER >= 20131127
+// new packets
+// changed packet sizes
+ packet(0x09e5,18); // ZC_DELETEITEM_FROM_MCSTORE2
+ packet(0x09e6,22); // ZC_UPDATE_ITEM_FROM_BUYING_STORE2
+#endif
+
+// 2013-12-11dRagexe
+#if PACKETVER >= 20131211
+// new packets
+ packet(0x09e7,2); // ZC_NOTIFY_UNREAD_RODEX
+ packet(0x09e8,18,clif->pDull/*,XXX*/); // CZ_OPEN_RODEXBOX
+ packet(0x09e9,2,clif->pDull/*,XXX*/); // CZ_CLOSE_RODEXBOX
+ packet(0x09ed,-1); // ZC_ACK_SEND_RODEX
+ packet(0x09ee,-1,clif->pDull/*,XXX*/); // CZ_REQ_NEXT_RODEX
+// changed packet sizes
+#endif
+
// 2013-12-18bRagexe - Yommy
#if PACKETVER >= 20131218
packet(0x0369,7,clif->pActionRequest,2,6);
@@ -2648,12 +2895,20 @@ packet(0x96e,-1,clif->ackmergeitems);
packet(0x085C,36,clif->pStoragePassword,0);
packet(0x0363,8,clif->pDull); // CZ_JOIN_BATTLE_FIELD
packet(0x087b,4,clif->pDull); // CZ_GANGSI_RANK
- /* New */
- packet(0x09d4,2,clif->pNPCShopClosed);
- packet(0x09ce,102,clif->pGM_Monster_Item,2);
- /* NPC Market */
- packet(0x09d8,2,clif->pNPCMarketClosed);
- packet(0x09d6,-1,clif->pNPCMarketPurchase);
+#endif
+
+// 2013-12-18bRagexe
+#if PACKETVER >= 20131218
+// new packets
+ packet(0x09ea,10,clif->pDull/*,XXX*/); // CZ_REQ_READ_RODEX
+ packet(0x09eb,14); // ZC_ACK_READ_RODEX
+ packet(0x09ef,11,clif->pDull/*,XXX*/); // CZ_REQ_REFRESH_RODEX
+ packet(0x09f0,-1); // ZC_ACK_RODEX_LIST
+ packet(0x09f5,11,clif->pDull/*,XXX*/); // CZ_REQ_DELETE_RODEX
+ packet(0x09f6,11); // ZC_ACK_DELETE_RODEX
+// changed packet sizes
+ packet(0x09e8,10,clif->pDull/*,XXX*/); // CZ_OPEN_RODEXBOX
+ packet(0x09ee,11,clif->pDull/*,XXX*/); // CZ_REQ_NEXT_RODEX
#endif
// 2013-12-23cRagexe - Yommy
@@ -2687,8 +2942,14 @@ packet(0x96e,-1,clif->ackmergeitems);
packet(0x08A4,36,clif->pStoragePassword,0);
packet(0x0363,8,clif->pDull); // CZ_JOIN_BATTLE_FIELD
packet(0x0436,4,clif->pDull); // CZ_GANGSI_RANK
- packet(0x09df,7);
- packet(0x09cb,17);
+#endif
+
+// 2013-12-23bRagexe
+#if PACKETVER >= 20131223
+// new packets
+// changed packet sizes
+ packet(0x09ea,11,clif->pDull/*,XXX*/); // CZ_REQ_READ_RODEX
+ packet(0x09eb,24); // ZC_ACK_READ_RODEX
#endif
// 2013-12-30aRagexe - Yommy
@@ -2724,40 +2985,91 @@ packet(0x96e,-1,clif->ackmergeitems);
packet(0x093e,8,clif->pDull); // CZ_JOIN_BATTLE_FIELD
#endif
+// 2013-12-30aRagexe
+#if PACKETVER >= 20131230
+// new packets
+ packet(0x09ec,-1,clif->pDull/*,XXX*/); // CZ_REQ_SEND_RODEX
+ packet(0x09ed,3); // ZC_ACK_SEND_RODEX
+ packet(0x09f7,75); // ZC_PROPERTY_HOMUN_2
+// changed packet sizes
+ packet(0x09eb,23); // ZC_ACK_READ_RODEX
+#endif
+
// 2014 Packet Data
-// 2014-01-15eRagexe - YomRawr
+// 2014-01-15eRagexe
+#if PACKETVER == 20140115
+// shuffle packets
+ packet(0x035f,6,clif->pTickSend,2); // CZ_REQUEST_MOVE2
+ packet(0x0360,6,clif->pReqClickBuyingStore,2); // CZ_REQUEST_TIME2
+ packet(0x0361,6,clif->pDropItem,2,4); // CZ_CHANGE_DIRECTION2
+ packet(0x0366,90,clif->pUseSkillToPosMoreInfo,2,4,6,8,10); // CZ_USE_SKILL_TOGROUND2
+ packet(0x0367,8,clif->pMoveFromKafra,2,4); // CZ_USE_SKILL_TOGROUND_WITHTALKBOX2
+ packet(0x0368,6,clif->pSolveCharName,2); // CZ_REQNAME2
+ packet(0x0369,7,clif->pActionRequest,2,6); // CZ_REQNAME_BYGID2
+ packet(0x0437,5,clif->pWalkToXY,2); // CZ_REQUEST_ACT2
+ packet(0x0438,10,clif->pUseSkillToPos,2,4,6,8); // CZ_USE_SKILL2
+ packet(0x0802,6,clif->pGetCharNameRequest,2); // CZ_PARTY_BOOKING_REQ_REGISTER
+ packet(0x0815,-1,clif->pReqOpenBuyingStore,2,4,8,9,89); // CZ_REQ_CLOSE_BUYING_STORE
+ packet(0x0817,2,clif->pReqCloseBuyingStore,0); // CZ_REQ_CLICK_TO_BUYING_STORE
+ packet(0x0819,-1,clif->pSearchStoreInfo,2,4,5,9,13,14,15); // CZ_REQ_TRADE_BUYING_STORE
+ packet(0x0835,2,clif->pSearchStoreInfoNextPage,0); // CZ_SEARCH_STORE_INFO
+ packet(0x0838,12,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SEARCH_STORE_INFO_NEXT_PAGE
+ packet(0x083c,10,clif->pUseSkillToId,2,4,6); // CZ_SSILIST_ITEM_CLICK
+ packet(0x0865,36,clif->pStoragePassword,0); // ZC_REASSEMBLY_AUTH12
+ packet(0x0887,-1,clif->pReqTradeBuyingStore,2,4,8,12); // CZ_REASSEMBLY_AUTH04
+ packet(0x088a,8,clif->pDull/*,XXX*/); // CZ_REASSEMBLY_AUTH07
+ packet(0x088e,8,clif->pMoveToKafra,2,4); // CZ_REASSEMBLY_AUTH11
+ packet(0x089b,26,clif->pFriendsListAdd,2); // CZ_REASSEMBLY_AUTH24
+ packet(0x08a7,5,clif->pChangeDir,2,4); // CZ_REASSEMBLY_AUTH36
+ packet(0x092d,5,clif->pHomMenu,2,4); // ZC_REASSEMBLY_AUTH65
+ packet(0x0940,6,clif->pTakeItem,2); // ZC_REASSEMBLY_AUTH84
+ packet(0x095b,4,clif->pDull/*,XXX*/); // CZ_REASSEMBLY_AUTH69
+ packet(0x095d,26,clif->pPartyInvite2,2); // CZ_REASSEMBLY_AUTH71
+ packet(0x0965,-1,clif->pItemListWindowSelected,2,4,8); // CZ_REASSEMBLY_AUTH79
+ packet(0x0966,19,clif->pWantToConnection,2,6,10,14,18); // CZ_REASSEMBLY_AUTH80
+ packet(0x096a,18,clif->pPartyBookingRegisterReq,2,4); // CZ_REASSEMBLY_AUTH84
+#endif
+
+// 2014-01-15cRagexeRE
#if PACKETVER >= 20140115
-// probably for some shuffle packets used wrong id
- packet(0x0369,7,clif->pActionRequest,2,6);
- packet(0x083C,10,clif->pUseSkillToId,2,4,6);
- packet(0x0437,5,clif->pWalkToXY,2);
- packet(0x035F,6,clif->pTickSend,2);
- packet(0x08A7,5,clif->pChangeDir,2,4);
- packet(0x0940,6,clif->pTakeItem,2);
- packet(0x0361,6,clif->pDropItem,2,4);
- packet(0x088E,8,clif->pMoveToKafra,2,4);
- packet(0x0367,8,clif->pMoveFromKafra,2,4);
- packet(0x0438,10,clif->pUseSkillToPos,2,4,6,8);
- packet(0x0366,90,clif->pUseSkillToPosMoreInfo,2,4,6,8,10);
- packet(0x0802,6,clif->pGetCharNameRequest,2);
- packet(0x0368,6,clif->pSolveCharName,2);
- packet(0x0360,12,clif->pSearchStoreInfoListItemClick,2,6,10);
- packet(0x0817,2,clif->pSearchStoreInfoNextPage,0);
- packet(0x0815,-1,clif->pSearchStoreInfo,2,4,5,9,13,14,15);
- packet(0x096A,-1,clif->pReqTradeBuyingStore,2,4,8,12);
- packet(0x088A,6,clif->pReqClickBuyingStore,2);
- packet(0x0965,2,clif->pReqCloseBuyingStore,0);
- packet(0x0815,-1,clif->pReqOpenBuyingStore,2,4,8,9,89);
- packet(0x096A,18,clif->pPartyBookingRegisterReq,2,4);
- // packet(0x088A,8,clif->pDull); // CZ_JOIN_BATTLE_FIELD
- packet(0x0965,-1,clif->pItemListWindowSelected,2,4,8);
- packet(0x0966,19,clif->pWantToConnection,2,6,10,14,18);
- packet(0x095D,26,clif->pPartyInvite2,2);
- // packet(0x095B,4,clif->pDull); // CZ_GANGSI_RANK
- packet(0x089B,26,clif->pFriendsListAdd,2);
- packet(0x092D,5,clif->pHomMenu,2,4);
- packet(0x0865,36,clif->pStoragePassword,0);
+// new packets
+ packet(0x09f1,10,clif->pDull/*,XXX*/); // CZ_REQ_ZENY_FROM_RODEX
+ packet(0x09f2,3); // ZC_ACK_ZENY_FROM_RODEX
+ packet(0x09f3,15,clif->pDull/*,XXX*/); // CZ_REQ_ITEM_FROM_RODEX
+ packet(0x09f4,12); // ZC_ACK_ITEM_FROM_RODEX
+ packet(0x09f8,-1); // ZC_ALL_QUEST_LIST3
+ packet(0x09f9,131); // ZC_ADD_QUEST_EX
+ packet(0x09fa,-1); // ZC_UPDATE_MISSION_HUNT_EX
+// changed packet sizes
+ packet(0x09eb,-1); // ZC_ACK_READ_RODEX
+#endif
+
+// 2014-01-22aRagexeRE
+#if PACKETVER >= 20140122
+// new packets
+ packet(0x09fb,-1,clif->pDull/*,XXX*/); // CZ_PET_EVOLUTION
+ packet(0x09fc,6); // ZC_PET_EVOLUTION_RESULT
+ packet(0x09fd,-1); // ZC_NOTIFY_MOVEENTRY11
+ packet(0x09fe,-1); // ZC_NOTIFY_NEWENTRY11
+ packet(0x09ff,-1); // ZC_NOTIFY_STANDENTRY11
+// changed packet sizes
+ packet(0x09f9,143); // ZC_ADD_QUEST_EX
+#endif
+
+// 2014-01-29bRagexeRE
+#if PACKETVER >= 20140129
+// new packets
+ packet(0x0a00,269); // ZC_SHORTCUT_KEY_LIST_V3
+ packet(0x0a01,3,clif->pHotkeyRowShift,2); // CZ_SHORTCUTKEYBAR_ROTATE
+// Warning hercules using this packets for items manipulation. In RagexeRE from 20140129 and before 20140305, this actions broken.
+#ifdef PACKETVER_RE
+// changed packet sizes
+ packet(0x01c4,43); // ZC_ADD_ITEM_TO_STORE2
+ packet(0x01c5,43); // ZC_ADD_ITEM_TO_CART2
+ packet(0x080f,41); // ZC_ADD_EXCHANGE_ITEM2
+ packet(0x0990,52); // ZC_ITEM_PICKUP_ACK_V5
+#endif // PACKETVER_RE
#endif
// 2014-02-05bRagexe - Themon
@@ -2791,7 +3103,36 @@ packet(0x96e,-1,clif->ackmergeitems);
packet(0x0938,36,clif->pStoragePassword,0);
packet(0x0363,8,clif->pDull); // CZ_JOIN_BATTLE_FIELD
packet(0x0436,4,clif->pDull); // CZ_GANGSI_RANK
- packet(0x09DF,7);
+#endif
+
+// 2014-02-12aRagexeRE
+#if PACKETVER >= 20140212
+// new packets
+ packet(0x0a02,4); // ZC_DRESSROOM_OPEN
+// changed packet sizes
+ packet(0x09e8,11,clif->pDull/*,XXX*/); // CZ_OPEN_RODEXBOX
+#endif
+
+// 2014-02-19aRagexeRE
+#if PACKETVER >= 20140219
+// Warning hercules using this packets for items manipulation. In RagexeRE from 20140129 and before 20140305, this actions broken.
+#ifdef PACKETVER_RE
+// changed packet sizes
+ packet(0x01c4,53); // ZC_ADD_ITEM_TO_STORE2
+ packet(0x01c5,53); // ZC_ADD_ITEM_TO_CART2
+ packet(0x080f,51); // ZC_ADD_EXCHANGE_ITEM2
+ packet(0x0990,62); // ZC_ITEM_PICKUP_ACK_V5
+#endif // PACKETVER_RE
+#endif
+
+// 2014-02-26aRagexeRE
+#if PACKETVER >= 20140226
+// new packets
+ packet(0x0a03,14,clif->pDull/*,XXX*/); // CZ_REQ_CANCEL_WRITE_RODEX
+ packet(0x0a04,11,clif->pDull/*,XXX*/); // CZ_REQ_ADD_ITEM_RODEX
+ packet(0x0a05,6); // ZC_ACK_ADD_ITEM_RODEX
+ packet(0x0a06,5,clif->pDull/*,XXX*/); // CZ_REQ_REMOVE_RODEX_ITEM
+// changed packet sizes
#endif
// 2014-03-05bRagexe - Themon
@@ -2825,7 +3166,51 @@ packet(0x96e,-1,clif->ackmergeitems);
packet(0x095e,36,clif->pStoragePassword,0);
packet(0x0363,8,clif->pDull); // CZ_JOIN_BATTLE_FIELD
packet(0x0878,4,clif->pDull); // CZ_GANGSI_RANK
- packet(0x09DF,7);
+#endif
+
+// 2014-03-05aRagexeRE
+#if PACKETVER >= 20140305
+// new packets
+ packet(0x0a07,4); // ZC_ACK_REMOVE_RODEX_ITEM
+ packet(0x0a08,5,clif->pDull/*,XXX*/); // CZ_REQ_OPEN_WRITE_RODEX
+ packet(0x0a09,50); // ZC_ADD_EXCHANGE_ITEM3
+ packet(0x0a0a,52); // ZC_ADD_ITEM_TO_STORE3
+ packet(0x0a0b,52); // ZC_ADD_ITEM_TO_CART3
+ packet(0x0a0c,61); // ZC_ITEM_PICKUP_ACK_V6
+ packet(0x0a0d,4); // ZC_INVENTORY_ITEMLIST_EQUIP_V6
+// changed packet sizes
+#ifdef PACKETVER_RE
+ packet(0x01c4,22); // ZC_ADD_ITEM_TO_STORE2
+ packet(0x01c5,22); // ZC_ADD_ITEM_TO_CART2
+ packet(0x080f,20); // ZC_ADD_EXCHANGE_ITEM2
+ packet(0x0990,31); // ZC_ITEM_PICKUP_ACK_V5
+#endif // PACKETVER_RE
+ packet(0x09f3,10,clif->pDull/*,XXX*/); // CZ_REQ_ITEM_FROM_RODEX
+ packet(0x09f4,3); // ZC_ACK_ITEM_FROM_RODEX
+#endif
+
+// 2014-03-12bRagexeRE
+#if PACKETVER >= 20140312
+// new packets
+ packet(0x0a0e,14); // ZC_BATTLEFIELD_NOTIFY_HP2
+// changed packet sizes
+ packet(0x0a09,45); // ZC_ADD_EXCHANGE_ITEM3
+ packet(0x0a0a,47); // ZC_ADD_ITEM_TO_STORE3
+ packet(0x0a0b,47); // ZC_ADD_ITEM_TO_CART3
+ packet(0x0a0c,56); // ZC_ITEM_PICKUP_ACK_V6
+ packet(0x0a0d,-1); // ZC_INVENTORY_ITEMLIST_EQUIP_V6
+#endif
+
+// 2014-03-26cRagexeRE
+#if PACKETVER >= 20140326
+// changed packet sizes
+ packet(0x09f1,11,clif->pDull/*,XXX*/); // CZ_REQ_ZENY_FROM_RODEX
+ packet(0x09f2,4); // ZC_ACK_ZENY_FROM_RODEX
+ packet(0x09f3,11,clif->pDull/*,XXX*/); // CZ_REQ_ITEM_FROM_RODEX
+ packet(0x09f4,4); // ZC_ACK_ITEM_FROM_RODEX
+ packet(0x0a03,2,clif->pDull/*,XXX*/); // CZ_REQ_CANCEL_WRITE_RODEX
+ packet(0x0a07,6); // ZC_ACK_REMOVE_RODEX_ITEM
+ packet(0x0a08,7,clif->pDull/*,XXX*/); // CZ_REQ_OPEN_WRITE_RODEX
#endif
// 2014-04-02gRagexe - Themon
@@ -2859,7 +3244,22 @@ packet(0x96e,-1,clif->ackmergeitems);
packet(0x0926,36,clif->pStoragePassword,0);
packet(0x088c,4,clif->pDull); // CZ_GANGSI_RANK
packet(0x094c,8,clif->pDull); // CZ_JOIN_BATTLE_FIELD
- packet(0x09DF,7);
+#endif
+
+// 2014-04-02eRagexeRE
+#if PACKETVER >= 20140402
+// new packets
+ packet(0x0a0f,-1); // ZC_CART_ITEMLIST_EQUIP_V6
+ packet(0x0a10,-1); // ZC_STORE_ITEMLIST_EQUIP_V6
+ packet(0x0a11,-1); // ZC_GUILDSTORAGE_ITEMLIST_EQUIP_V6
+// changed packet sizes
+#endif
+
+// 2014-04-09aRagexeRE
+#if PACKETVER >= 20140409
+// changed packet sizes
+ packet(0x09f2,12); // ZC_ACK_ZENY_FROM_RODEX
+ packet(0x09f4,12); // ZC_ACK_ITEM_FROM_RODEX
#endif
// 2014-04-16aRagexe - Themon
@@ -2893,18 +3293,155 @@ packet(0x96e,-1,clif->ackmergeitems);
packet(0x095C,36,clif->pStoragePassword,0);
packet(0x0363,8,clif->pDull); // CZ_JOIN_BATTLE_FIELD
packet(0x0436,4,clif->pDull); // CZ_GANGSI_RANK
- packet(0x09DF,7);
#endif
-#if PACKETVER >= 20140613
-// no shuffle packets
- packet(0x0a0e,14);
+// 2014-04-16aRagexeRE
+#if PACKETVER >= 20140416
+// new packets
+ packet(0x0a04,6,clif->pDull/*,XXX*/); // CZ_REQ_ADD_ITEM_RODEX
+ packet(0x0a12,27); // ZC_ACK_OPEN_WRITE_RODEX
+ packet(0x0a13,2,clif->pDull/*,XXX*/); // CZ_CHECK_RECEIVE_CHARACTER_NAME
+// changed packet sizes
+ packet(0x0a05,48); // ZC_ACK_ADD_ITEM_RODEX
+ packet(0x0a06,6,clif->pDull/*,XXX*/); // CZ_REQ_REMOVE_RODEX_ITEM
+ packet(0x0a07,7); // ZC_ACK_REMOVE_RODEX_ITEM
+ packet(0x0a08,26,clif->pDull/*,XXX*/); // CZ_REQ_OPEN_WRITE_RODEX
+#endif
+
+// 2014-04-23aRagexeRE
+#if PACKETVER >= 20140423
+// new packets
+ packet(0x0a14,6); // ZC_CHECK_RECEIVE_CHARACTER_NAME
+// changed packet sizes
+ packet(0x0a13,26,clif->pDull/*,XXX*/); // CZ_CHECK_RECEIVE_CHARACTER_NAME
+#endif
+
+// 2014-04-30aRagexeRE
+#if PACKETVER >= 20140430
+// new packets
+ packet(0x0a15,11); // ZC_GOLDPCCAFE_POINT
+ packet(0x0a16,26,clif->pDull/*,XXX*/); // CZ_DYNAMICNPC_CREATE_REQUEST
+ packet(0x0a17,6); // ZC_DYNAMICNPC_CREATE_RESULT
+#endif
+
+// 2014-05-08bRagexeRE
+#if PACKETVER >= 20140508
+// changed packet sizes
+ packet(0x0a15,12); // ZC_GOLDPCCAFE_POINT
+#endif
+
+// 2014-05-21aRagexeRE
+#if PACKETVER >= 20140521
+// changed packet sizes
+ packet(0x0a07,9); // ZC_ACK_REMOVE_RODEX_ITEM
+ packet(0x0a14,10); // ZC_CHECK_RECEIVE_CHARACTER_NAME
+#endif
+
+/* Roulette System [Yommy/Hercules] */
+// 2014-06-05aRagexe
+#if PACKETVER >= 20140605
+// new packets
+ packet(0x0a18,2); // ZC_ACCEPT_ENTER3
+ packet(0x0a19,-1,clif->pDull/*,XXX*/); // CZ_REQ_OPEN_ROULETTE
+ packet(0x0a1a,10); // ZC_ACK_OPEN_ROULETTE
+ packet(0x0A1B,2,clif->pRouletteInfo,0); // HEADER_CZ_REQ_ROULETTE_INFO
+ packet(0x0a1c,6); // ZC_ACK_ROULEITTE_INFO
+ packet(0x0a1d,14,clif->pDull/*,XXX*/); // CZ_REQ_CLOSE_ROULETTE
+#endif
+
+/* Roulette System [Yommy/Hercules] */
+// 2014-06-11bRagexe / RE. moved by 4144
+#if PACKETVER >= 20140611
+// new packets
+ packet(0x0a1e,3); // ZC_ACK_CLOSE_ROULETTE
+ packet(0x0a1f,2,clif->pRouletteGenerate,0); // CZ_REQ_GENERATE_ROULETTE
+ packet(0x0a20,21); // ZC_ACK_GENERATE_ROULETTE
+ packet(0x0a21,6,clif->pDull/*,XXX*/); // CZ_RECV_ROULETTE_ITEM
+ packet(0x0a22,3); // ZC_RECV_ROULETTE_ITEM
+ packet(0x0a23,-1); // ZC_ALL_ACH_LIST
+ packet(0x0a24,35); // ZC_ACH_UPDATE
+ packet(0x0a25,6,clif->pDull/*,XXX*/); // CZ_REQ_ACH_REWARD
+ packet(0x0a26,7); // ZC_REQ_ACH_REWARD_ACK
+// changed packet sizes
+ packet(0x0a18,14); // ZC_ACCEPT_ENTER3
+ packet(0x0a19,2,clif->pRouletteOpen,0); // CZ_REQ_OPEN_ROULETTE
+ packet(0x0a1a,23); // ZC_ACK_OPEN_ROULETTE
+ packet(0x0a1c,-1); // ZC_ACK_ROULEITTE_INFO
+ packet(0x0a1d,2,clif->pRouletteClose,0); // CZ_REQ_CLOSE_ROULETTE
+#endif
+
+// 2014-06-18cRagexeRE
+#if PACKETVER >= 20140618
+// changed packet sizes
+ packet(0x0a21,3,clif->pRouletteRecvItem,2); // CZ_RECV_ROULETTE_ITEM
+ packet(0x0a22,5); // ZC_RECV_ROULETTE_ITEM
#endif
// 2014-06-25aRagexeRE
#if PACKETVER >= 20140625
-// no shuffle packets
+// new packets
+ packet(0x0a27,8); // ZC_RECOVERY2
packet(0x0a28,3); // ZC_ACK_OPENSTORE2
+// changed packet sizes
+ packet(0x0a24,36); // ZC_ACH_UPDATE
+#endif
+
+// 2014-07-02aRagexeRE
+#if PACKETVER >= 20140702
+// new packets
+ packet(0x0a29,6); // ZC_REQ_AU_BOT
+ packet(0x0a2a,6,clif->pDull/*,XXX*/); // CZ_ACK_AU_BOT
+#endif
+
+// 2014-07-16aRagexeRE
+#if PACKETVER >= 20140716
+// changed packet sizes
+ packet(0x09e7,3); // ZC_NOTIFY_UNREAD_RODEX
+#endif
+
+// 2014-07-23aRagexeRE
+#if PACKETVER >= 20140723
+// new packets
+ packet(0x0a2b,14); // ZC_SE_CASHSHOP_OPEN2
+ packet(0x0a2c,12); // ZC_SE_PC_BUY_TAIWANCASHITEM_RESULT
+// changed packet sizes
+ packet(0x0a24,56); // ZC_ACH_UPDATE
+#endif
+
+// 2014-08-20aRagexeRE
+#if PACKETVER >= 20140820
+// new packets
+ packet(0x0a2d,-1); // ZC_EQUIPWIN_MICROSCOPE_V6
+#endif
+
+// 2014-09-03aRagexeRE
+#if PACKETVER >= 20140903
+// new packets
+ packet(0x0a2e,6,clif->pDull/*,XXX*/); // CZ_REQ_CHANGE_TITLE
+ packet(0x0a2f,7); // ZC_ACK_CHANGE_TITLE
+// changed packet sizes
+#endif
+
+// 2014-09-24bRagexeRE
+#if PACKETVER >= 20140924
+// new packets
+ packet(0x0a30,106); // ZC_ACK_REQNAMEALL2
+ packet(0x0a31,-1); // ZC_RESULT_PACKAGE_ITEM_TEST
+ packet(0x0a32,2); // ZC_OPEN_RODEX_THROUGH_NPC_ONLY
+ packet(0x0a33,7); // ZC_UPDATE_ROULETTE_COIN
+ packet(0x0a34,6); // ZC_UPDATE_TAIWANCASH
+#endif
+
+// 2014-10-01bRagexeRE
+#if PACKETVER >= 20141001
+// changed packet sizes
+ packet(0x0a24,66); // ZC_ACH_UPDATE
+#endif
+
+// 2014-10-08bRagexeRE
+#if PACKETVER >= 20141008
+// changed packet sizes
+ packet(0x0a05,49); // ZC_ACK_ADD_ITEM_RODEX
#endif
// 2014-10-16aRagexe - YomRawr
@@ -2938,24 +3475,6 @@ packet(0x96e,-1,clif->ackmergeitems);
packet(0x0936,36,clif->pStoragePassword,0);
packet(0x0363,8,clif->pDull); // CZ_JOIN_BATTLE_FIELD
packet(0x0922,4,clif->pDull); // CZ_GANGSI_RANK
- packet(0x09DF,7);
- packet(0x0a00,269);
- packet(0x09e5,18); // ZC_DELETEITEM_FROM_MCSTORE2
- packet(0x09e6,22); // ZC_UPDATE_ITEM_FROM_BUYING_STORE2
-#endif
-
-/* Roulette System [Yommy/Hercules] */
-#if PACKETVER >= 20141016
- packet(0x0A19,2,clif->pRouletteOpen,0); // HEADER_CZ_REQ_OPEN_ROULETTE
- packet(0x0A1A,23); // HEADER_ZC_ACK_OPEN_ROULETTE
- packet(0x0A1B,2,clif->pRouletteInfo,0); // HEADER_CZ_REQ_ROULETTE_INFO
- packet(0x0A1C,-1); // HEADER_ZC_ACK_ROULEITTE_INFO
- packet(0x0A1D,2,clif->pRouletteClose,0); // HEADER_CZ_REQ_CLOSE_ROULETTE
- packet(0x0A1E,3); // HEADER_ZC_ACK_CLOSE_ROULETTE
- packet(0x0A1F,2,clif->pRouletteGenerate,0); // HEADER_CZ_REQ_GENERATE_ROULETTE
- packet(0x0A20,21); // HEADER_ZC_ACK_GENERATE_ROULETTE
- packet(0x0A21,3,clif->pRouletteRecvItem,2); // HEADER_CZ_RECV_ROULETTE_ITEM
- packet(0x0A22,5); // HEADER_ZC_RECV_ROULETTE_ITEM
#endif
// 2014-10-22bRagexe - YomRawr
@@ -2987,20 +3506,456 @@ packet(0x96e,-1,clif->ackmergeitems);
packet(0x091A,26,clif->pFriendsListAdd,2);
packet(0x0899,5,clif->pHomMenu,2,4);
packet(0x0438,36,clif->pStoragePassword,0);
- packet(0x0A01,3,clif->pHotkeyRowShift,2);
packet(0x08ab,4,clif->pDull); // CZ_GANGSI_RANK
packet(0x092b,8,clif->pDull); // CZ_JOIN_BATTLE_FIELD
#endif
-#if PACKETVER >= 20150226
-// shuffle packets not added
- packet(0x0A09,45);
- packet(0x0A0A,47);
- packet(0x0A0B,47);
- packet(0x0A0C,56);
- packet(0x0A0D,-1);
- packet(0x0A0F,-1);
- packet(0x0A10,-1);
+// 2014-11-19bRagexeRE
+#if PACKETVER >= 20141119
+// new packets
+ packet(0x0A35,4,clif->pOneClick_ItemIdentify,2);
+// changed packet sizes
+ packet(0x0a05,53); // ZC_ACK_ADD_ITEM_RODEX
+#endif
+
+// 2014-11-26aRagexeRE
+#if PACKETVER >= 20141126
+// new packets
+ packet(0x0a36,7); // ZC_HP_INFO_TINY
+ packet(0x0a37,57); // ZC_ITEM_PICKUP_ACK_V7
+#endif
+
+// 2015-01-07aRagexeRE
+#if PACKETVER == 20150107
+// shuffle packets
+ packet(0x0281,-1,clif->pItemListWindowSelected,2,4,8); // CZ_ITEMLISTWIN_RES
+ packet(0x035f,6,clif->pTickSend,2); // CZ_REQUEST_TIME
+ packet(0x0360,6,clif->pReqClickBuyingStore,2); // CZ_REQ_CLICK_TO_BUYING_STORE
+ packet(0x0362,6,clif->pDropItem,2,4); // CZ_ITEM_THROW
+ packet(0x0363,8,clif->pDull/*,XXX*/); // CZ_JOIN_BATTLE_FIELD
+ packet(0x0364,8,clif->pMoveFromKafra,2,4); // CZ_MOVE_ITEM_FROM_STORE_TO_BODY
+ packet(0x0365,18,clif->pPartyBookingRegisterReq,2,4); // CZ_PARTY_BOOKING_REQ_REGISTER
+ packet(0x0366,90,clif->pUseSkillToPosMoreInfo,2,4,6,8,10); // CZ_USE_SKILL_TOGROUND_WITHTALKBOX
+ packet(0x0368,6,clif->pSolveCharName,2); // CZ_REQNAME_BYGID
+ packet(0x0369,7,clif->pActionRequest,2,6); // CZ_REQUEST_ACT
+ packet(0x0436,4,clif->pDull/*,XXX*/); // CZ_GANGSI_RANK
+ packet(0x0437,5,clif->pWalkToXY,2); // CZ_REQUEST_MOVE
+ packet(0x0438,10,clif->pUseSkillToPos,2,4,6,8); // CZ_USE_SKILL_TOGROUND
+ packet(0x07e4,6,clif->pTakeItem,2); // CZ_ITEM_PICKUP
+ packet(0x07ec,8,clif->pMoveToKafra,2,4); // CZ_MOVE_ITEM_FROM_BODY_TO_STORE
+ packet(0x0802,26,clif->pPartyInvite2,2); // CZ_PARTY_JOIN_REQ
+ packet(0x0811,-1,clif->pReqTradeBuyingStore,2,4,8,12); // CZ_REQ_TRADE_BUYING_STORE
+ packet(0x0815,-1,clif->pReqOpenBuyingStore,2,4,8,9,89); // CZ_REQ_OPEN_BUYING_STORE
+ packet(0x0817,2,clif->pReqCloseBuyingStore,0); // CZ_REQ_CLOSE_BUYING_STORE
+ packet(0x0819,-1,clif->pSearchStoreInfo,2,4,5,9,13,14,15); // CZ_SEARCH_STORE_INFO
+ packet(0x0835,2,clif->pSearchStoreInfoNextPage,0); // CZ_SEARCH_STORE_INFO_NEXT_PAGE
+ packet(0x0838,12,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SSILIST_ITEM_CLICK
+ packet(0x083c,10,clif->pUseSkillToId,2,4,6); // CZ_USE_SKILL
+ packet(0x087c,26,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS
+ packet(0x0895,36,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD
+ packet(0x092d,5,clif->pHomMenu,2,4); // CZ_COMMAND_MER
+ packet(0x0943,5,clif->pChangeDir,2,4); // CZ_CHANGE_DIRECTION
+ packet(0x0947,19,clif->pWantToConnection,2,6,10,14,18); // CZ_ENTER
+ packet(0x096a,6,clif->pGetCharNameRequest,2); // CZ_REQNAME
+#endif
+
+// 2015-01-14aRagexe
+#if PACKETVER == 20150114
+// shuffle packets
+ packet(0x0281,-1,clif->pItemListWindowSelected,2,4,8); // CZ_ITEMLISTWIN_RES
+ packet(0x035f,6,clif->pTickSend,2); // CZ_REQUEST_TIME
+ packet(0x0360,6,clif->pReqClickBuyingStore,2); // CZ_REQ_CLICK_TO_BUYING_STORE
+ packet(0x0362,6,clif->pDropItem,2,4); // CZ_ITEM_THROW
+ packet(0x0363,8,clif->pDull/*,XXX*/); // CZ_JOIN_BATTLE_FIELD
+ packet(0x0364,8,clif->pMoveFromKafra,2,4); // CZ_MOVE_ITEM_FROM_STORE_TO_BODY
+ packet(0x0365,18,clif->pPartyBookingRegisterReq,2,4); // CZ_PARTY_BOOKING_REQ_REGISTER
+ packet(0x0366,90,clif->pUseSkillToPosMoreInfo,2,4,6,8,10); // CZ_USE_SKILL_TOGROUND_WITHTALKBOX
+ packet(0x0368,6,clif->pSolveCharName,2); // CZ_REQNAME_BYGID
+ packet(0x0369,7,clif->pActionRequest,2,6); // CZ_REQUEST_ACT
+ packet(0x0436,10,clif->pUseSkillToId,2,4,6); // CZ_USE_SKILL
+ packet(0x0437,5,clif->pWalkToXY,2); // CZ_REQUEST_MOVE
+ packet(0x0438,10,clif->pUseSkillToPos,2,4,6,8); // CZ_USE_SKILL_TOGROUND
+ packet(0x07e4,6,clif->pTakeItem,2); // CZ_ITEM_PICKUP
+ packet(0x07ec,8,clif->pMoveToKafra,2,4); // CZ_MOVE_ITEM_FROM_BODY_TO_STORE
+ packet(0x0802,26,clif->pPartyInvite2,2); // CZ_PARTY_JOIN_REQ
+ packet(0x0811,-1,clif->pReqTradeBuyingStore,2,4,8,12); // CZ_REQ_TRADE_BUYING_STORE
+ packet(0x0815,-1,clif->pReqOpenBuyingStore,2,4,8,9,89); // CZ_REQ_OPEN_BUYING_STORE
+ packet(0x0817,2,clif->pReqCloseBuyingStore,0); // CZ_REQ_CLOSE_BUYING_STORE
+ packet(0x0819,-1,clif->pSearchStoreInfo,2,4,5,9,13,14,15); // CZ_SEARCH_STORE_INFO
+ packet(0x0835,2,clif->pSearchStoreInfoNextPage,0); // CZ_SEARCH_STORE_INFO_NEXT_PAGE
+ packet(0x0838,12,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SSILIST_ITEM_CLICK
+ packet(0x083c,19,clif->pWantToConnection,2,6,10,14,18); // CZ_ENTER
+ packet(0x0868,26,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS
+ packet(0x0899,5,clif->pHomMenu,2,4); // CZ_COMMAND_MER
+ packet(0x0946,36,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD
+ packet(0x0955,4,clif->pDull/*,XXX*/); // CZ_GANGSI_RANK
+ packet(0x0957,5,clif->pChangeDir,2,4); // CZ_CHANGE_DIRECTION
+ packet(0x096a,6,clif->pGetCharNameRequest,2); // CZ_REQNAME
+#endif
+
+// 2015-01-28aRagexe
+#if PACKETVER == 20150128
+// shuffle packets
+ packet(0x0202,12,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SSILIST_ITEM_CLICK
+ packet(0x023b,5,clif->pChangeDir,2,4); // CZ_CHANGE_DIRECTION
+ packet(0x035f,6,clif->pReqClickBuyingStore,2); // CZ_REQ_CLICK_TO_BUYING_STORE
+ packet(0x0365,-1,clif->pSearchStoreInfo,2,4,5,9,13,14,15); // CZ_SEARCH_STORE_INFO
+ packet(0x0368,8,clif->pDull/*,XXX*/); // CZ_JOIN_BATTLE_FIELD
+ packet(0x0838,7,clif->pActionRequest,2,6); // CZ_REQUEST_ACT
+ packet(0x085a,-1,clif->pReqOpenBuyingStore,2,4,8,9,89); // CZ_REQ_OPEN_BUYING_STORE
+ packet(0x0864,10,clif->pUseSkillToPos,2,4,6,8); // CZ_USE_SKILL_TOGROUND
+ packet(0x086d,8,clif->pMoveToKafra,2,4); // CZ_MOVE_ITEM_FROM_BODY_TO_STORE
+ packet(0x0870,5,clif->pWalkToXY,2); // CZ_REQUEST_MOVE
+ packet(0x0874,6,clif->pGetCharNameRequest,2); // CZ_REQNAME
+ packet(0x0875,-1,clif->pReqTradeBuyingStore,2,4,8,12); // CZ_REQ_TRADE_BUYING_STORE
+ packet(0x0876,5,clif->pHomMenu,2,4); // CZ_COMMAND_MER
+ packet(0x087d,6,clif->pSolveCharName,2); // CZ_REQNAME_BYGID
+ packet(0x0888,-1,clif->pItemListWindowSelected,2,4,8); // CZ_ITEMLISTWIN_RES
+ packet(0x089a,18,clif->pPartyBookingRegisterReq,2,4); // CZ_PARTY_BOOKING_REQ_REGISTER
+ packet(0x08ab,6,clif->pTakeItem,2); // CZ_ITEM_PICKUP
+ packet(0x091f,6,clif->pTickSend,2); // CZ_REQUEST_TIME
+ packet(0x0927,26,clif->pPartyInvite2,2); // CZ_PARTY_JOIN_REQ
+ packet(0x0929,36,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD
+ packet(0x092d,2,clif->pSearchStoreInfoNextPage,0); // CZ_SEARCH_STORE_INFO_NEXT_PAGE
+ packet(0x0938,4,clif->pDull/*,XXX*/); // CZ_GANGSI_RANK
+ packet(0x093a,10,clif->pUseSkillToId,2,4,6); // CZ_USE_SKILL
+ packet(0x0944,19,clif->pWantToConnection,2,6,10,14,18); // CZ_ENTER
+ packet(0x094d,2,clif->pReqCloseBuyingStore,0); // CZ_REQ_CLOSE_BUYING_STORE
+ packet(0x094e,8,clif->pMoveFromKafra,2,4); // CZ_MOVE_ITEM_FROM_STORE_TO_BODY
+ packet(0x0952,90,clif->pUseSkillToPosMoreInfo,2,4,6,8,10); // CZ_USE_SKILL_TOGROUND_WITHTALKBOX
+ packet(0x0963,26,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS
+ packet(0x0968,6,clif->pDropItem,2,4); // CZ_ITEM_THROW
+#endif
+// 2015-01-28aRagexeRE
+#if PACKETVER >= 20150128
+// new packets
+ packet(0x0a38,3);
+#endif
+
+// 2015-02-04aRagexe
+#if PACKETVER == 20150204
+// shuffle packets
+ packet(0x0202,5,clif->pChangeDir,2,4); // CZ_CHANGE_DIRECTION
+ packet(0x022d,19,clif->pWantToConnection,2,6,10,14,18); // CZ_ENTER
+ packet(0x023b,26,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS
+ packet(0x0281,-1,clif->pItemListWindowSelected,2,4,8); // CZ_ITEMLISTWIN_RES
+ packet(0x035f,6,clif->pTickSend,2); // CZ_REQUEST_TIME
+ packet(0x0360,6,clif->pReqClickBuyingStore,2); // CZ_REQ_CLICK_TO_BUYING_STORE
+ packet(0x0361,5,clif->pHomMenu,2,4); // CZ_COMMAND_MER
+ packet(0x0362,6,clif->pDropItem,2,4); // CZ_ITEM_THROW
+ packet(0x0363,8,clif->pDull/*,XXX*/); // CZ_JOIN_BATTLE_FIELD
+ packet(0x0364,8,clif->pMoveFromKafra,2,4); // CZ_MOVE_ITEM_FROM_STORE_TO_BODY
+ packet(0x0365,18,clif->pPartyBookingRegisterReq,2,4); // CZ_PARTY_BOOKING_REQ_REGISTER
+ packet(0x0366,90,clif->pUseSkillToPosMoreInfo,2,4,6,8,10); // CZ_USE_SKILL_TOGROUND_WITHTALKBOX
+ packet(0x0368,6,clif->pSolveCharName,2); // CZ_REQNAME_BYGID
+ packet(0x0369,7,clif->pActionRequest,2,6); // CZ_REQUEST_ACT
+ packet(0x0436,4,clif->pDull/*,XXX*/); // CZ_GANGSI_RANK
+ packet(0x0437,5,clif->pWalkToXY,2); // CZ_REQUEST_MOVE
+ packet(0x0438,10,clif->pUseSkillToPos,2,4,6,8); // CZ_USE_SKILL_TOGROUND
+ packet(0x07e4,6,clif->pTakeItem,2); // CZ_ITEM_PICKUP
+ packet(0x07ec,8,clif->pMoveToKafra,2,4); // CZ_MOVE_ITEM_FROM_BODY_TO_STORE
+ packet(0x0802,26,clif->pPartyInvite2,2); // CZ_PARTY_JOIN_REQ
+ packet(0x0811,-1,clif->pReqTradeBuyingStore,2,4,8,12); // CZ_REQ_TRADE_BUYING_STORE
+ packet(0x0815,-1,clif->pReqOpenBuyingStore,2,4,8,9,89); // CZ_REQ_OPEN_BUYING_STORE
+ packet(0x0817,2,clif->pReqCloseBuyingStore,0); // CZ_REQ_CLOSE_BUYING_STORE
+ packet(0x0819,-1,clif->pSearchStoreInfo,2,4,5,9,13,14,15); // CZ_SEARCH_STORE_INFO
+ packet(0x0835,2,clif->pSearchStoreInfoNextPage,0); // CZ_SEARCH_STORE_INFO_NEXT_PAGE
+ packet(0x0838,12,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SSILIST_ITEM_CLICK
+ packet(0x083c,10,clif->pUseSkillToId,2,4,6); // CZ_USE_SKILL
+ packet(0x0966,36,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD
+ packet(0x096a,6,clif->pGetCharNameRequest,2); // CZ_REQNAME
+#endif
+
+// 2015-02-25aRagexeRE
+#if PACKETVER == 20150225
+// shuffle packets
+ packet(0x02c4,6,clif->pReqClickBuyingStore,2); // CZ_REQ_CLICK_TO_BUYING_STORE
+ packet(0x035f,6,clif->pTickSend,2); // CZ_REQUEST_TIME
+ packet(0x0360,26,clif->pPartyInvite2,2); // CZ_PARTY_JOIN_REQ
+ packet(0x0362,2,clif->pReqCloseBuyingStore,0); // CZ_REQ_CLOSE_BUYING_STORE
+ packet(0x0366,90,clif->pUseSkillToPosMoreInfo,2,4,6,8,10); // CZ_USE_SKILL_TOGROUND_WITHTALKBOX
+ packet(0x0368,6,clif->pSolveCharName,2); // CZ_REQNAME_BYGID
+ packet(0x0369,7,clif->pActionRequest,2,6); // CZ_REQUEST_ACT
+ packet(0x0436,6,clif->pGetCharNameRequest,2); // CZ_REQNAME
+ packet(0x0437,5,clif->pWalkToXY,2); // CZ_REQUEST_MOVE
+ packet(0x0438,10,clif->pUseSkillToPos,2,4,6,8); // CZ_USE_SKILL_TOGROUND
+ packet(0x0811,-1,clif->pReqTradeBuyingStore,2,4,8,12); // CZ_REQ_TRADE_BUYING_STORE
+ packet(0x0815,-1,clif->pReqOpenBuyingStore,2,4,8,9,89); // CZ_REQ_OPEN_BUYING_STORE
+ packet(0x0817,6,clif->pTakeItem,2); // CZ_ITEM_PICKUP
+ packet(0x0819,2,clif->pSearchStoreInfoNextPage,0); // CZ_SEARCH_STORE_INFO_NEXT_PAGE
+ packet(0x0838,12,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SSILIST_ITEM_CLICK
+ packet(0x083c,10,clif->pUseSkillToId,2,4,6); // CZ_USE_SKILL
+ packet(0x0867,18,clif->pPartyBookingRegisterReq,2,4); // CZ_PARTY_BOOKING_REQ_REGISTER
+ packet(0x0885,4,clif->pDull/*,XXX*/); // CZ_GANGSI_RANK
+ packet(0x0896,-1,clif->pItemListWindowSelected,2,4,8); // CZ_ITEMLISTWIN_RES
+ packet(0x089b,8,clif->pDull/*,XXX*/); // CZ_JOIN_BATTLE_FIELD
+ packet(0x089c,8,clif->pMoveToKafra,2,4); // CZ_MOVE_ITEM_FROM_BODY_TO_STORE
+ packet(0x08a4,36,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD
+ packet(0x0940,-1,clif->pSearchStoreInfo,2,4,5,9,13,14,15); // CZ_SEARCH_STORE_INFO
+ packet(0x0946,26,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS
+ packet(0x0948,6,clif->pDropItem,2,4); // CZ_ITEM_THROW
+ packet(0x094f,5,clif->pHomMenu,2,4); // CZ_COMMAND_MER
+ packet(0x0952,8,clif->pMoveFromKafra,2,4); // CZ_MOVE_ITEM_FROM_STORE_TO_BODY
+ packet(0x0955,5,clif->pChangeDir,2,4); // CZ_CHANGE_DIRECTION
+ packet(0x096a,19,clif->pWantToConnection,2,6,10,14,18); // CZ_ENTER
+#endif
+
+// 2015-02-26aRagexeRE
+#if PACKETVER == 20150226
+// shuffle packets
+ packet(0x02c4,6,clif->pReqClickBuyingStore,2); // CZ_REQ_CLICK_TO_BUYING_STORE
+ packet(0x035f,6,clif->pTickSend,2); // CZ_REQUEST_TIME
+ packet(0x0360,26,clif->pPartyInvite2,2); // CZ_PARTY_JOIN_REQ
+ packet(0x0362,2,clif->pReqCloseBuyingStore,0); // CZ_REQ_CLOSE_BUYING_STORE
+ packet(0x0366,90,clif->pUseSkillToPosMoreInfo,2,4,6,8,10); // CZ_USE_SKILL_TOGROUND_WITHTALKBOX
+ packet(0x0368,6,clif->pSolveCharName,2); // CZ_REQNAME_BYGID
+ packet(0x0369,7,clif->pActionRequest,2,6); // CZ_REQUEST_ACT
+ packet(0x0436,6,clif->pGetCharNameRequest,2); // CZ_REQNAME
+ packet(0x0437,5,clif->pWalkToXY,2); // CZ_REQUEST_MOVE
+ packet(0x0438,10,clif->pUseSkillToPos,2,4,6,8); // CZ_USE_SKILL_TOGROUND
+ packet(0x0811,-1,clif->pReqTradeBuyingStore,2,4,8,12); // CZ_REQ_TRADE_BUYING_STORE
+ packet(0x0815,-1,clif->pReqOpenBuyingStore,2,4,8,9,89); // CZ_REQ_OPEN_BUYING_STORE
+ packet(0x0817,6,clif->pTakeItem,2); // CZ_ITEM_PICKUP
+ packet(0x0819,2,clif->pSearchStoreInfoNextPage,0); // CZ_SEARCH_STORE_INFO_NEXT_PAGE
+ packet(0x0838,12,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SSILIST_ITEM_CLICK
+ packet(0x083c,10,clif->pUseSkillToId,2,4,6); // CZ_USE_SKILL
+ packet(0x0867,18,clif->pPartyBookingRegisterReq,2,4); // CZ_PARTY_BOOKING_REQ_REGISTER
+ packet(0x0885,4,clif->pDull/*,XXX*/); // CZ_GANGSI_RANK
+ packet(0x0896,-1,clif->pItemListWindowSelected,2,4,8); // CZ_ITEMLISTWIN_RES
+ packet(0x089b,8,clif->pDull/*,XXX*/); // CZ_JOIN_BATTLE_FIELD
+ packet(0x089c,8,clif->pMoveToKafra,2,4); // CZ_MOVE_ITEM_FROM_BODY_TO_STORE
+ packet(0x08a4,36,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD
+ packet(0x0940,-1,clif->pSearchStoreInfo,2,4,5,9,13,14,15); // CZ_SEARCH_STORE_INFO
+ packet(0x0946,26,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS
+ packet(0x0948,6,clif->pDropItem,2,4); // CZ_ITEM_THROW
+ packet(0x094f,5,clif->pHomMenu,2,4); // CZ_COMMAND_MER
+ packet(0x0952,8,clif->pMoveFromKafra,2,4); // CZ_MOVE_ITEM_FROM_STORE_TO_BODY
+ packet(0x0955,5,clif->pChangeDir,2,4); // CZ_CHANGE_DIRECTION
+ packet(0x096a,19,clif->pWantToConnection,2,6,10,14,18); // CZ_ENTER
+#endif
+
+// 2015-03-11aRagexeRE
+#if PACKETVER == 20150311
+// shuffle packets
+ packet(0x023b,5,clif->pHomMenu,2,4); // CZ_COMMAND_MER
+ packet(0x0360,2,clif->pReqCloseBuyingStore,0); // CZ_REQ_CLOSE_BUYING_STORE
+ packet(0x0436,-1,clif->pSearchStoreInfo,2,4,5,9,13,14,15); // CZ_SEARCH_STORE_INFO
+ packet(0x0438,-1,clif->pReqTradeBuyingStore,2,4,8,12); // CZ_REQ_TRADE_BUYING_STORE
+ packet(0x0815,19,clif->pWantToConnection,2,6,10,14,18); // CZ_ENTER
+ packet(0x0838,10,clif->pUseSkillToPos,2,4,6,8); // CZ_USE_SKILL_TOGROUND
+ packet(0x086a,6,clif->pGetCharNameRequest,2); // CZ_REQNAME
+ packet(0x086c,36,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD
+ packet(0x087b,18,clif->pPartyBookingRegisterReq,2,4); // CZ_PARTY_BOOKING_REQ_REGISTER
+ packet(0x0883,-1,clif->pItemListWindowSelected,2,4,8); // CZ_ITEMLISTWIN_RES
+ packet(0x0886,5,clif->pWalkToXY,2); // CZ_REQUEST_MOVE
+ packet(0x0888,2,clif->pSearchStoreInfoNextPage,0); // CZ_SEARCH_STORE_INFO_NEXT_PAGE
+ packet(0x0896,7,clif->pActionRequest,2,6); // CZ_REQUEST_ACT
+ packet(0x08a1,10,clif->pUseSkillToId,2,4,6); // CZ_USE_SKILL
+ packet(0x08a3,6,clif->pTakeItem,2); // CZ_ITEM_PICKUP
+ packet(0x08a5,12,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SSILIST_ITEM_CLICK
+ packet(0x08a6,26,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS
+ packet(0x091c,90,clif->pUseSkillToPosMoreInfo,2,4,6,8,10); // CZ_USE_SKILL_TOGROUND_WITHTALKBOX
+ packet(0x0928,5,clif->pChangeDir,2,4); // CZ_CHANGE_DIRECTION
+ packet(0x092a,8,clif->pDull/*,XXX*/); // CZ_JOIN_BATTLE_FIELD
+ packet(0x092e,8,clif->pMoveFromKafra,2,4); // CZ_MOVE_ITEM_FROM_STORE_TO_BODY
+ packet(0x093b,26,clif->pPartyInvite2,2); // CZ_PARTY_JOIN_REQ
+ packet(0x0943,6,clif->pSolveCharName,2); // CZ_REQNAME_BYGID
+ packet(0x0946,4,clif->pDull/*,XXX*/); // CZ_GANGSI_RANK
+ packet(0x0957,6,clif->pReqClickBuyingStore,2); // CZ_REQ_CLICK_TO_BUYING_STORE
+ packet(0x0958,6,clif->pTickSend,2); // CZ_REQUEST_TIME
+ packet(0x095b,-1,clif->pReqOpenBuyingStore,2,4,8,9,89); // CZ_REQ_OPEN_BUYING_STORE
+ packet(0x0963,6,clif->pDropItem,2,4); // CZ_ITEM_THROW
+ packet(0x0964,8,clif->pMoveToKafra,2,4); // CZ_MOVE_ITEM_FROM_BODY_TO_STORE
+#endif
+
+// 2015-03-11aRagexeRE
+#if PACKETVER >= 20150311
+// new packets
+ packet(0x0a3a,12);
+// changed packet sizes
+#endif
+
+// 2015-03-25aRagexe
+#if PACKETVER == 20150325
+// shuffle packets
+ packet(0x0202,26,clif->pPartyInvite2,2); // CZ_PARTY_JOIN_REQ
+ packet(0x0363,6,clif->pDropItem,2,4); // CZ_ITEM_THROW
+ packet(0x0365,10,clif->pUseSkillToId,2,4,6); // CZ_USE_SKILL
+ packet(0x0438,2,clif->pSearchStoreInfoNextPage,0); // CZ_SEARCH_STORE_INFO_NEXT_PAGE
+ packet(0x0802,4,clif->pDull/*,XXX*/); // CZ_GANGSI_RANK
+ packet(0x0819,6,clif->pReqClickBuyingStore,2); // CZ_REQ_CLICK_TO_BUYING_STORE
+ packet(0x085d,6,clif->pSolveCharName,2); // CZ_REQNAME_BYGID
+ packet(0x086f,-1,clif->pReqOpenBuyingStore,2,4,8,9,89); // CZ_REQ_OPEN_BUYING_STORE
+ packet(0x087c,8,clif->pMoveToKafra,2,4); // CZ_MOVE_ITEM_FROM_BODY_TO_STORE
+ packet(0x087e,5,clif->pChangeDir,2,4); // CZ_CHANGE_DIRECTION
+ packet(0x0883,12,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SSILIST_ITEM_CLICK
+ packet(0x0885,10,clif->pUseSkillToPos,2,4,6,8); // CZ_USE_SKILL_TOGROUND
+ packet(0x0891,6,clif->pGetCharNameRequest,2); // CZ_REQNAME
+ packet(0x0893,8,clif->pDull/*,XXX*/); // CZ_JOIN_BATTLE_FIELD
+ packet(0x0897,-1,clif->pReqTradeBuyingStore,2,4,8,12); // CZ_REQ_TRADE_BUYING_STORE
+ packet(0x0899,18,clif->pPartyBookingRegisterReq,2,4); // CZ_PARTY_BOOKING_REQ_REGISTER
+ packet(0x08a1,7,clif->pActionRequest,2,6); // CZ_REQUEST_ACT
+ packet(0x08a7,90,clif->pUseSkillToPosMoreInfo,2,4,6,8,10); // CZ_USE_SKILL_TOGROUND_WITHTALKBOX
+ packet(0x0919,36,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD
+ packet(0x092c,6,clif->pTakeItem,2); // CZ_ITEM_PICKUP
+ packet(0x0931,-1,clif->pSearchStoreInfo,2,4,5,9,13,14,15); // CZ_SEARCH_STORE_INFO
+ packet(0x0932,5,clif->pWalkToXY,2); // CZ_REQUEST_MOVE
+ packet(0x0938,5,clif->pHomMenu,2,4); // CZ_COMMAND_MER
+ packet(0x0940,26,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS
+ packet(0x0947,2,clif->pReqCloseBuyingStore,0); // CZ_REQ_CLOSE_BUYING_STORE
+ packet(0x094a,19,clif->pWantToConnection,2,6,10,14,18); // CZ_ENTER
+ packet(0x0950,-1,clif->pItemListWindowSelected,2,4,8); // CZ_ITEMLISTWIN_RES
+ packet(0x0954,6,clif->pTickSend,2); // CZ_REQUEST_TIME
+ packet(0x0969,8,clif->pMoveFromKafra,2,4); // CZ_MOVE_ITEM_FROM_STORE_TO_BODY
+#endif
+
+// 2015-04-01aRagexe
+#if PACKETVER == 20150401
+// shuffle packets
+ packet(0x0362,7,clif->pActionRequest,2,6); // CZ_REQUEST_ACT
+ packet(0x0367,6,clif->pGetCharNameRequest,2); // CZ_REQNAME
+ packet(0x0437,6,clif->pReqClickBuyingStore,2); // CZ_REQ_CLICK_TO_BUYING_STORE
+ packet(0x083c,-1,clif->pSearchStoreInfo,2,4,5,9,13,14,15); // CZ_SEARCH_STORE_INFO
+ packet(0x085e,12,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SSILIST_ITEM_CLICK
+ packet(0x086f,5,clif->pWalkToXY,2); // CZ_REQUEST_MOVE
+ packet(0x0875,-1,clif->pItemListWindowSelected,2,4,8); // CZ_ITEMLISTWIN_RES
+ packet(0x087e,8,clif->pDull/*,XXX*/); // CZ_JOIN_BATTLE_FIELD
+ packet(0x088c,6,clif->pDropItem,2,4); // CZ_ITEM_THROW
+ packet(0x088f,6,clif->pTickSend,2); // CZ_REQUEST_TIME
+ packet(0x0895,8,clif->pMoveFromKafra,2,4); // CZ_MOVE_ITEM_FROM_STORE_TO_BODY
+ packet(0x0898,5,clif->pHomMenu,2,4); // CZ_COMMAND_MER
+ packet(0x089c,36,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD
+ packet(0x08a5,8,clif->pMoveToKafra,2,4); // CZ_MOVE_ITEM_FROM_BODY_TO_STORE
+ packet(0x091b,26,clif->pPartyInvite2,2); // CZ_PARTY_JOIN_REQ
+ packet(0x091c,90,clif->pUseSkillToPosMoreInfo,2,4,6,8,10); // CZ_USE_SKILL_TOGROUND_WITHTALKBOX
+ packet(0x0922,-1,clif->pReqOpenBuyingStore,2,4,8,9,89); // CZ_REQ_OPEN_BUYING_STORE
+ packet(0x0924,18,clif->pPartyBookingRegisterReq,2,4); // CZ_PARTY_BOOKING_REQ_REGISTER
+ packet(0x0938,2,clif->pReqCloseBuyingStore,0); // CZ_REQ_CLOSE_BUYING_STORE
+ packet(0x0939,19,clif->pWantToConnection,2,6,10,14,18); // CZ_ENTER
+ packet(0x093a,10,clif->pUseSkillToPos,2,4,6,8); // CZ_USE_SKILL_TOGROUND
+ packet(0x093b,-1,clif->pReqTradeBuyingStore,2,4,8,12); // CZ_REQ_TRADE_BUYING_STORE
+ packet(0x093e,2,clif->pSearchStoreInfoNextPage,0); // CZ_SEARCH_STORE_INFO_NEXT_PAGE
+ packet(0x0946,4,clif->pDull/*,XXX*/); // CZ_GANGSI_RANK
+ packet(0x0949,6,clif->pTakeItem,2); // CZ_ITEM_PICKUP
+ packet(0x094b,10,clif->pUseSkillToId,2,4,6); // CZ_USE_SKILL
+ packet(0x0953,26,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS
+ packet(0x095f,6,clif->pSolveCharName,2); // CZ_REQNAME_BYGID
+ packet(0x0964,5,clif->pChangeDir,2,4); // CZ_CHANGE_DIRECTION
+#endif
+
+// 2015-04-15aRagexeRE
+#if PACKETVER >= 20150415
+// changed packet sizes
+ packet(0x0a39,36); // CH_UNKNOWN_MAKE_CHAR // in char server used from 20151001. is this correct?
+#endif
+
+// 2015-04-22aRagexeRE
+#if PACKETVER == 20150422
+// shuffle packets
+ packet(0x0202,5,clif->pChangeDir,2,4); // CZ_CHANGE_DIRECTION
+ packet(0x022d,19,clif->pWantToConnection,2,6,10,14,18); // CZ_ENTER
+ packet(0x023b,26,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS
+ packet(0x0281,-1,clif->pItemListWindowSelected,2,4,8); // CZ_ITEMLISTWIN_RES
+ packet(0x035f,6,clif->pTickSend,2); // CZ_REQUEST_TIME
+ packet(0x0360,6,clif->pReqClickBuyingStore,2); // CZ_REQ_CLICK_TO_BUYING_STORE
+ packet(0x0361,5,clif->pHomMenu,2,4); // CZ_COMMAND_MER
+ packet(0x0362,6,clif->pDropItem,2,4); // CZ_ITEM_THROW
+ packet(0x0363,8,clif->pDull/*,XXX*/); // CZ_JOIN_BATTLE_FIELD
+ packet(0x0364,8,clif->pMoveFromKafra,2,4); // CZ_MOVE_ITEM_FROM_STORE_TO_BODY
+ packet(0x0365,18,clif->pPartyBookingRegisterReq,2,4); // CZ_PARTY_BOOKING_REQ_REGISTER
+ packet(0x0366,90,clif->pUseSkillToPosMoreInfo,2,4,6,8,10); // CZ_USE_SKILL_TOGROUND_WITHTALKBOX
+ packet(0x0368,6,clif->pSolveCharName,2); // CZ_REQNAME_BYGID
+ packet(0x0369,7,clif->pActionRequest,2,6); // CZ_REQUEST_ACT
+ packet(0x0436,4,clif->pDull/*,XXX*/); // CZ_GANGSI_RANK
+ packet(0x0437,5,clif->pWalkToXY,2); // CZ_REQUEST_MOVE
+ packet(0x0438,10,clif->pUseSkillToPos,2,4,6,8); // CZ_USE_SKILL_TOGROUND
+ packet(0x07e4,6,clif->pTakeItem,2); // CZ_ITEM_PICKUP
+ packet(0x07ec,8,clif->pMoveToKafra,2,4); // CZ_MOVE_ITEM_FROM_BODY_TO_STORE
+ packet(0x0802,26,clif->pPartyInvite2,2); // CZ_PARTY_JOIN_REQ
+ packet(0x0811,-1,clif->pReqTradeBuyingStore,2,4,8,12); // CZ_REQ_TRADE_BUYING_STORE
+ packet(0x0815,-1,clif->pReqOpenBuyingStore,2,4,8,9,89); // CZ_REQ_OPEN_BUYING_STORE
+ packet(0x0817,2,clif->pReqCloseBuyingStore,0); // CZ_REQ_CLOSE_BUYING_STORE
+ packet(0x0819,-1,clif->pSearchStoreInfo,2,4,5,9,13,14,15); // CZ_SEARCH_STORE_INFO
+ packet(0x0835,2,clif->pSearchStoreInfoNextPage,0); // CZ_SEARCH_STORE_INFO_NEXT_PAGE
+ packet(0x0838,12,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SSILIST_ITEM_CLICK
+ packet(0x083c,10,clif->pUseSkillToId,2,4,6); // CZ_USE_SKILL
+ packet(0x0955,36,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD
+ packet(0x096a,6,clif->pGetCharNameRequest,2); // CZ_REQNAME
+#endif
+
+// 2015-04-22aRagexeRE
+#if PACKETVER >= 20150422
+// new packets
+ packet(0x0a3b,-1);
+// changed packet sizes
+#endif
+
+// 2015-04-29aRagexe
+#if PACKETVER == 20150429
+// shuffle packets
+ packet(0x035f,6,clif->pTickSend,2); // CZ_REQUEST_TIME
+ packet(0x0360,6,clif->pReqClickBuyingStore,2); // CZ_REQ_CLICK_TO_BUYING_STORE
+ packet(0x0363,5,clif->pChangeDir,2,4); // CZ_CHANGE_DIRECTION
+ packet(0x0366,90,clif->pUseSkillToPosMoreInfo,2,4,6,8,10); // CZ_USE_SKILL_TOGROUND_WITHTALKBOX
+ packet(0x0368,6,clif->pSolveCharName,2); // CZ_REQNAME_BYGID
+ packet(0x0369,7,clif->pActionRequest,2,6); // CZ_REQUEST_ACT
+ packet(0x0437,5,clif->pWalkToXY,2); // CZ_REQUEST_MOVE
+ packet(0x0438,10,clif->pUseSkillToPos,2,4,6,8); // CZ_USE_SKILL_TOGROUND
+ packet(0x0811,-1,clif->pReqTradeBuyingStore,2,4,8,12); // CZ_REQ_TRADE_BUYING_STORE
+ packet(0x0815,-1,clif->pReqOpenBuyingStore,2,4,8,9,89); // CZ_REQ_OPEN_BUYING_STORE
+ packet(0x0817,2,clif->pReqCloseBuyingStore,0); // CZ_REQ_CLOSE_BUYING_STORE
+ packet(0x0819,-1,clif->pSearchStoreInfo,2,4,5,9,13,14,15); // CZ_SEARCH_STORE_INFO
+ packet(0x0835,2,clif->pSearchStoreInfoNextPage,0); // CZ_SEARCH_STORE_INFO_NEXT_PAGE
+ packet(0x0838,12,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SSILIST_ITEM_CLICK
+ packet(0x083c,10,clif->pUseSkillToId,2,4,6); // CZ_USE_SKILL
+ packet(0x0867,36,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD
+ packet(0x086a,19,clif->pWantToConnection,2,6,10,14,18); // CZ_ENTER
+ packet(0x0886,26,clif->pPartyInvite2,2); // CZ_PARTY_JOIN_REQ
+ packet(0x088f,5,clif->pHomMenu,2,4); // CZ_COMMAND_MER
+ packet(0x0894,6,clif->pDropItem,2,4); // CZ_ITEM_THROW
+ packet(0x0899,8,clif->pMoveToKafra,2,4); // CZ_MOVE_ITEM_FROM_BODY_TO_STORE
+ packet(0x089f,-1,clif->pItemListWindowSelected,2,4,8); // CZ_ITEMLISTWIN_RES
+ packet(0x08a6,8,clif->pDull/*,XXX*/); // CZ_JOIN_BATTLE_FIELD
+ packet(0x08a8,4,clif->pDull/*,XXX*/); // CZ_GANGSI_RANK
+ packet(0x08ad,18,clif->pPartyBookingRegisterReq,2,4); // CZ_PARTY_BOOKING_REQ_REGISTER
+ packet(0x0929,8,clif->pMoveFromKafra,2,4); // CZ_MOVE_ITEM_FROM_STORE_TO_BODY
+ packet(0x093d,26,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS
+ packet(0x0943,6,clif->pTakeItem,2); // CZ_ITEM_PICKUP
+ packet(0x096a,6,clif->pGetCharNameRequest,2); // CZ_REQNAME
+#endif
+
+// 2015-05-07bRagexe
+#if PACKETVER == 20150507
+// shuffle packets
+ packet(0x023b,5,clif->pHomMenu,2,4); // CZ_COMMAND_MER
+ packet(0x035f,6,clif->pTickSend,2); // CZ_REQUEST_TIME
+ packet(0x0360,6,clif->pReqClickBuyingStore,2); // CZ_REQ_CLICK_TO_BUYING_STORE
+ packet(0x0362,2,clif->pReqCloseBuyingStore,0); // CZ_REQ_CLOSE_BUYING_STORE
+ packet(0x0366,90,clif->pUseSkillToPosMoreInfo,2,4,6,8,10); // CZ_USE_SKILL_TOGROUND_WITHTALKBOX
+ packet(0x0368,6,clif->pSolveCharName,2); // CZ_REQNAME_BYGID
+ packet(0x0369,7,clif->pActionRequest,2,6); // CZ_REQUEST_ACT
+ packet(0x0437,5,clif->pWalkToXY,2); // CZ_REQUEST_MOVE
+ packet(0x0438,10,clif->pUseSkillToPos,2,4,6,8); // CZ_USE_SKILL_TOGROUND
+ packet(0x0811,-1,clif->pReqTradeBuyingStore,2,4,8,12); // CZ_REQ_TRADE_BUYING_STORE
+ packet(0x0815,-1,clif->pReqOpenBuyingStore,2,4,8,9,89); // CZ_REQ_OPEN_BUYING_STORE
+ packet(0x0817,6,clif->pTakeItem,2); // CZ_ITEM_PICKUP
+ packet(0x0819,-1,clif->pSearchStoreInfo,2,4,5,9,13,14,15); // CZ_SEARCH_STORE_INFO
+ packet(0x0835,2,clif->pSearchStoreInfoNextPage,0); // CZ_SEARCH_STORE_INFO_NEXT_PAGE
+ packet(0x0838,12,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SSILIST_ITEM_CLICK
+ packet(0x083c,10,clif->pUseSkillToId,2,4,6); // CZ_USE_SKILL
+ packet(0x085a,8,clif->pMoveToKafra,2,4); // CZ_MOVE_ITEM_FROM_BODY_TO_STORE
+ packet(0x0864,26,clif->pPartyInvite2,2); // CZ_PARTY_JOIN_REQ
+ packet(0x0887,8,clif->pDull/*,XXX*/); // CZ_JOIN_BATTLE_FIELD
+ packet(0x0889,18,clif->pPartyBookingRegisterReq,2,4); // CZ_PARTY_BOOKING_REQ_REGISTER
+ packet(0x0924,19,clif->pWantToConnection,2,6,10,14,18); // CZ_ENTER
+ packet(0x092e,-1,clif->pItemListWindowSelected,2,4,8); // CZ_ITEMLISTWIN_RES
+ packet(0x093b,5,clif->pChangeDir,2,4); // CZ_CHANGE_DIRECTION
+ packet(0x0941,8,clif->pMoveFromKafra,2,4); // CZ_MOVE_ITEM_FROM_STORE_TO_BODY
+ packet(0x0942,4,clif->pDull/*,XXX*/); // CZ_GANGSI_RANK
+ packet(0x0953,36,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD
+ packet(0x0955,6,clif->pDropItem,2,4); // CZ_ITEM_THROW
+ packet(0x0958,26,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS
+ packet(0x096a,6,clif->pGetCharNameRequest,2); // CZ_REQNAME
#endif
// 2015-05-13aRagexe
@@ -3034,51 +3989,363 @@ packet(0x96e,-1,clif->ackmergeitems);
packet(0x08A8,26,clif->pFriendsListAdd,2);
packet(0x0817,5,clif->pHomMenu,2,4);
packet(0x0923,36,clif->pStoragePassword,0);
- packet(0x09E8,11,clif->pDull); // CZ_OPEN_MAILBOX
- packet(0x0A2E,6,clif->pDull); // TITLE
- packet(0x0A02,4); // ZC_DRESSROOM_OPEN
- packet(0x0A35,4,clif->pOneClick_ItemIdentify,2);
packet(0x0a27,8); // ZC_RECOVERY2
- packet(0x09f7,75); // ZC_PROPERTY_HOMUN_2
#endif
-#if PACKETVER >= 20150805 // RagexeRE
-// shuffle packets not added
- packet(0x097f,-1); // ZC_SELECTCART
- packet(0x0980,7,clif->pSelectCart); // CZ_SELECTCART
+// 2015-05-20aRagexeRE
+#if PACKETVER >= 20150520
+// new packets
+ packet(0x0a3c,-1);
+ packet(0x0a3d,18,clif->pDull/*,XXX*/);
+#endif
+
+// 2015-05-27aRagexe
+#if PACKETVER == 20150527
+// shuffle packets
+ packet(0x0202,5,clif->pChangeDir,2,4); // CZ_CHANGE_DIRECTION
+ packet(0x022d,19,clif->pWantToConnection,2,6,10,14,18); // CZ_ENTER
+ packet(0x023b,26,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS
+ packet(0x0281,-1,clif->pItemListWindowSelected,2,4,8); // CZ_ITEMLISTWIN_RES
+ packet(0x035f,6,clif->pTickSend,2); // CZ_REQUEST_TIME
+ packet(0x0360,6,clif->pReqClickBuyingStore,2); // CZ_REQ_CLICK_TO_BUYING_STORE
+ packet(0x0361,5,clif->pHomMenu,2,4); // CZ_COMMAND_MER
+ packet(0x0362,6,clif->pDropItem,2,4); // CZ_ITEM_THROW
+ packet(0x0363,8,clif->pDull/*,XXX*/); // CZ_JOIN_BATTLE_FIELD
+ packet(0x0364,8,clif->pMoveFromKafra,2,4); // CZ_MOVE_ITEM_FROM_STORE_TO_BODY
+ packet(0x0365,18,clif->pPartyBookingRegisterReq,2,4); // CZ_PARTY_BOOKING_REQ_REGISTER
+ packet(0x0366,90,clif->pUseSkillToPosMoreInfo,2,4,6,8,10); // CZ_USE_SKILL_TOGROUND_WITHTALKBOX
+ packet(0x0368,6,clif->pSolveCharName,2); // CZ_REQNAME_BYGID
+ packet(0x0369,7,clif->pActionRequest,2,6); // CZ_REQUEST_ACT
+ packet(0x0436,4,clif->pDull/*,XXX*/); // CZ_GANGSI_RANK
+ packet(0x0437,5,clif->pWalkToXY,2); // CZ_REQUEST_MOVE
+ packet(0x0438,10,clif->pUseSkillToPos,2,4,6,8); // CZ_USE_SKILL_TOGROUND
+ packet(0x07e4,6,clif->pTakeItem,2); // CZ_ITEM_PICKUP
+ packet(0x07ec,8,clif->pMoveToKafra,2,4); // CZ_MOVE_ITEM_FROM_BODY_TO_STORE
+ packet(0x0802,26,clif->pPartyInvite2,2); // CZ_PARTY_JOIN_REQ
+ packet(0x0811,-1,clif->pReqTradeBuyingStore,2,4,8,12); // CZ_REQ_TRADE_BUYING_STORE
+ packet(0x0815,-1,clif->pReqOpenBuyingStore,2,4,8,9,89); // CZ_REQ_OPEN_BUYING_STORE
+ packet(0x0817,2,clif->pReqCloseBuyingStore,0); // CZ_REQ_CLOSE_BUYING_STORE
+ packet(0x0819,-1,clif->pSearchStoreInfo,2,4,5,9,13,14,15); // CZ_SEARCH_STORE_INFO
+ packet(0x0835,2,clif->pSearchStoreInfoNextPage,0); // CZ_SEARCH_STORE_INFO_NEXT_PAGE
+ packet(0x0838,10,clif->pUseSkillToId,2,4,6); // CZ_USE_SKILL
+ packet(0x083c,36,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD
+ packet(0x0940,12,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SSILIST_ITEM_CLICK
+ packet(0x096a,6,clif->pGetCharNameRequest,2); // CZ_REQNAME
+#endif
+
+// 2015-06-03bRagexeRE
+#if PACKETVER >= 20150603
+// new packets
+ packet(0x0a3e,-1);
+#endif
+
+// 2015-06-17aRagexeRE
+#if PACKETVER == 20150617
+// shuffle packets
+ packet(0x035f,6,clif->pTickSend,2); // CZ_REQUEST_TIME
+ packet(0x0360,6,clif->pTakeItem,2); // CZ_ITEM_PICKUP
+ packet(0x0362,6,clif->pReqClickBuyingStore,2); // CZ_REQ_CLICK_TO_BUYING_STORE
+ packet(0x0363,36,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD
+ packet(0x0365,-1,clif->pItemListWindowSelected,2,4,8); // CZ_ITEMLISTWIN_RES
+ packet(0x0366,90,clif->pUseSkillToPosMoreInfo,2,4,6,8,10); // CZ_USE_SKILL_TOGROUND_WITHTALKBOX
+ packet(0x0368,6,clif->pSolveCharName,2); // CZ_REQNAME_BYGID
+ packet(0x0369,7,clif->pActionRequest,2,6); // CZ_REQUEST_ACT
+ packet(0x0436,19,clif->pWantToConnection,2,6,10,14,18); // CZ_ENTER
+ packet(0x0437,5,clif->pWalkToXY,2); // CZ_REQUEST_MOVE
+ packet(0x0438,10,clif->pUseSkillToPos,2,4,6,8); // CZ_USE_SKILL_TOGROUND
+ packet(0x07ec,-1,clif->pReqTradeBuyingStore,2,4,8,12); // CZ_REQ_TRADE_BUYING_STORE
+ packet(0x0811,8,clif->pDull/*,XXX*/); // CZ_JOIN_BATTLE_FIELD
+ packet(0x0815,-1,clif->pReqOpenBuyingStore,2,4,8,9,89); // CZ_REQ_OPEN_BUYING_STORE
+ packet(0x0817,2,clif->pReqCloseBuyingStore,0); // CZ_REQ_CLOSE_BUYING_STORE
+ packet(0x0819,-1,clif->pSearchStoreInfo,2,4,5,9,13,14,15); // CZ_SEARCH_STORE_INFO
+ packet(0x0835,2,clif->pSearchStoreInfoNextPage,0); // CZ_SEARCH_STORE_INFO_NEXT_PAGE
+ packet(0x0838,12,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SSILIST_ITEM_CLICK
+ packet(0x083c,10,clif->pUseSkillToId,2,4,6); // CZ_USE_SKILL
+ packet(0x0869,8,clif->pMoveFromKafra,2,4); // CZ_MOVE_ITEM_FROM_STORE_TO_BODY
+ packet(0x086a,18,clif->pPartyBookingRegisterReq,2,4); // CZ_PARTY_BOOKING_REQ_REGISTER
+ packet(0x086b,5,clif->pChangeDir,2,4); // CZ_CHANGE_DIRECTION
+ packet(0x0870,26,clif->pPartyInvite2,2); // CZ_PARTY_JOIN_REQ
+ packet(0x087a,8,clif->pMoveToKafra,2,4); // CZ_MOVE_ITEM_FROM_BODY_TO_STORE
+ packet(0x0886,5,clif->pHomMenu,2,4); // CZ_COMMAND_MER
+ packet(0x0894,4,clif->pDull/*,XXX*/); // CZ_GANGSI_RANK
+ packet(0x0940,6,clif->pDropItem,2,4); // CZ_ITEM_THROW
+ packet(0x094e,26,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS
+ packet(0x096a,6,clif->pGetCharNameRequest,2); // CZ_REQNAME
+#endif
+
+// 2015-06-18aRagexeRE
+#if PACKETVER == 20150618
+// shuffle packets
+ packet(0x035f,6,clif->pTickSend,2); // CZ_REQUEST_TIME
+ packet(0x0360,6,clif->pTakeItem,2); // CZ_ITEM_PICKUP
+ packet(0x0362,6,clif->pReqClickBuyingStore,2); // CZ_REQ_CLICK_TO_BUYING_STORE
+ packet(0x0363,36,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD
+ packet(0x0365,-1,clif->pItemListWindowSelected,2,4,8); // CZ_ITEMLISTWIN_RES
+ packet(0x0366,90,clif->pUseSkillToPosMoreInfo,2,4,6,8,10); // CZ_USE_SKILL_TOGROUND_WITHTALKBOX
+ packet(0x0368,6,clif->pSolveCharName,2); // CZ_REQNAME_BYGID
+ packet(0x0369,7,clif->pActionRequest,2,6); // CZ_REQUEST_ACT
+ packet(0x0436,19,clif->pWantToConnection,2,6,10,14,18); // CZ_ENTER
+ packet(0x0437,5,clif->pWalkToXY,2); // CZ_REQUEST_MOVE
+ packet(0x0438,10,clif->pUseSkillToPos,2,4,6,8); // CZ_USE_SKILL_TOGROUND
+ packet(0x07ec,-1,clif->pReqTradeBuyingStore,2,4,8,12); // CZ_REQ_TRADE_BUYING_STORE
+ packet(0x0811,8,clif->pDull/*,XXX*/); // CZ_JOIN_BATTLE_FIELD
+ packet(0x0815,-1,clif->pReqOpenBuyingStore,2,4,8,9,89); // CZ_REQ_OPEN_BUYING_STORE
+ packet(0x0817,2,clif->pReqCloseBuyingStore,0); // CZ_REQ_CLOSE_BUYING_STORE
+ packet(0x0819,-1,clif->pSearchStoreInfo,2,4,5,9,13,14,15); // CZ_SEARCH_STORE_INFO
+ packet(0x0835,2,clif->pSearchStoreInfoNextPage,0); // CZ_SEARCH_STORE_INFO_NEXT_PAGE
+ packet(0x0838,12,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SSILIST_ITEM_CLICK
+ packet(0x083c,10,clif->pUseSkillToId,2,4,6); // CZ_USE_SKILL
+ packet(0x0869,8,clif->pMoveFromKafra,2,4); // CZ_MOVE_ITEM_FROM_STORE_TO_BODY
+ packet(0x086a,18,clif->pPartyBookingRegisterReq,2,4); // CZ_PARTY_BOOKING_REQ_REGISTER
+ packet(0x086b,5,clif->pChangeDir,2,4); // CZ_CHANGE_DIRECTION
+ packet(0x0870,26,clif->pPartyInvite2,2); // CZ_PARTY_JOIN_REQ
+ packet(0x087a,8,clif->pMoveToKafra,2,4); // CZ_MOVE_ITEM_FROM_BODY_TO_STORE
+ packet(0x0886,5,clif->pHomMenu,2,4); // CZ_COMMAND_MER
+ packet(0x0894,4,clif->pDull/*,XXX*/); // CZ_GANGSI_RANK
+ packet(0x0940,6,clif->pDropItem,2,4); // CZ_ITEM_THROW
+ packet(0x094e,26,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS
+ packet(0x096a,6,clif->pGetCharNameRequest,2); // CZ_REQNAME
+#endif
+
+// 2015-06-24aRagexeRE
+#if PACKETVER >= 20150624
+// new packets
+ packet(0x0a3f,9);
#endif
-// 2015-10-01bRagexeRE
-#if PACKETVER >= 20151001
- packet(0x0369,7,clif->pActionRequest,2,6);
- packet(0x083C,10,clif->pUseSkillToId,2,4,6);
- packet(0x0437,5,clif->pWalkToXY,2);
- packet(0x035F,6,clif->pTickSend,2);
- packet(0x0202,5,clif->pChangeDir,2,4);
- packet(0x07E4,6,clif->pTakeItem,2);
- packet(0x0362,6,clif->pDropItem,2,4);
- packet(0x07EC,8,clif->pMoveToKafra,2,4);
- packet(0x0364,8,clif->pMoveFromKafra,2,4);
- packet(0x0438,10,clif->pUseSkillToPos,2,4,6,8);
- packet(0x0366,90,clif->pUseSkillToPosMoreInfo,2,4,6,8,10);
- packet(0x096A,6,clif->pGetCharNameRequest,2);
- packet(0x0368,6,clif->pSolveCharName,2);
- packet(0x0838,12,clif->pSearchStoreInfoListItemClick,2,6,10);
- packet(0x0835,2,clif->pSearchStoreInfoNextPage,0);
- packet(0x0819,-1,clif->pSearchStoreInfo,2,4,5,9,13,14,15);
- packet(0x0811,-1,clif->pReqTradeBuyingStore,2,4,8,12);
- packet(0x0360,6,clif->pReqClickBuyingStore,2);
- packet(0x0817,2,clif->pReqCloseBuyingStore,0);
- packet(0x0815,-1,clif->pReqOpenBuyingStore,2,4,8,9,89);
- packet(0x0365,18,clif->pPartyBookingRegisterReq,2,4);
- packet(0x0281,-1,clif->pItemListWindowSelected,2,4,8);
- packet(0x022D,19,clif->pWantToConnection,2,6,10,14,18);
- packet(0x0802,26,clif->pPartyInvite2,2);
- packet(0x023B,26,clif->pFriendsListAdd,2);
- packet(0x0361,5,clif->pHomMenu,2,4);
- packet(0x0860,36,clif->pStoragePassword,0);
- packet(0x0363,8,clif->pDull); // CZ_JOIN_BATTLE_FIELD
- packet(0x0436,4,clif->pDull); // CZ_GANGSI_RANK
+// 2015-08-12aRagexeRE
+#if PACKETVER >= 20150812
+// new packets
+ packet(0x0a40,11);
+#endif
+
+// 2015-08-19aRagexeRE
+#if PACKETVER == 20150819
+// shuffle packets
+ packet(0x0202,-1,clif->pItemListWindowSelected,2,4,8); // CZ_ITEMLISTWIN_RES
+ packet(0x022d,10,clif->pUseSkillToId,2,4,6); // CZ_USE_SKILL
+ packet(0x0281,6,clif->pTakeItem,2); // CZ_ITEM_PICKUP
+ packet(0x035f,6,clif->pTickSend,2); // CZ_REQUEST_TIME
+ packet(0x0360,6,clif->pReqClickBuyingStore,2); // CZ_REQ_CLICK_TO_BUYING_STORE
+ packet(0x0366,90,clif->pUseSkillToPosMoreInfo,2,4,6,8,10); // CZ_USE_SKILL_TOGROUND_WITHTALKBOX
+ packet(0x0368,6,clif->pSolveCharName,2); // CZ_REQNAME_BYGID
+ packet(0x0369,7,clif->pActionRequest,2,6); // CZ_REQUEST_ACT
+ packet(0x0436,4,clif->pDull/*,XXX*/); // CZ_GANGSI_RANK
+ packet(0x0437,5,clif->pWalkToXY,2); // CZ_REQUEST_MOVE
+ packet(0x0438,10,clif->pUseSkillToPos,2,4,6,8); // CZ_USE_SKILL_TOGROUND
+ packet(0x0811,-1,clif->pReqTradeBuyingStore,2,4,8,12); // CZ_REQ_TRADE_BUYING_STORE
+ packet(0x0815,-1,clif->pReqOpenBuyingStore,2,4,8,9,89); // CZ_REQ_OPEN_BUYING_STORE
+ packet(0x0817,2,clif->pReqCloseBuyingStore,0); // CZ_REQ_CLOSE_BUYING_STORE
+ packet(0x0819,-1,clif->pSearchStoreInfo,2,4,5,9,13,14,15); // CZ_SEARCH_STORE_INFO
+ packet(0x0835,2,clif->pSearchStoreInfoNextPage,0); // CZ_SEARCH_STORE_INFO_NEXT_PAGE
+ packet(0x0838,12,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SSILIST_ITEM_CLICK
+ packet(0x085d,8,clif->pMoveFromKafra,2,4); // CZ_MOVE_ITEM_FROM_STORE_TO_BODY
+ packet(0x0862,8,clif->pDull/*,XXX*/); // CZ_JOIN_BATTLE_FIELD
+ packet(0x0865,26,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS
+ packet(0x0871,18,clif->pPartyBookingRegisterReq,2,4); // CZ_PARTY_BOOKING_REQ_REGISTER
+ packet(0x0888,5,clif->pHomMenu,2,4); // CZ_COMMAND_MER
+ packet(0x0919,8,clif->pMoveToKafra,2,4); // CZ_MOVE_ITEM_FROM_BODY_TO_STORE
+ packet(0x091e,36,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD
+ packet(0x0927,19,clif->pWantToConnection,2,6,10,14,18); // CZ_ENTER
+ packet(0x0940,6,clif->pDropItem,2,4); // CZ_ITEM_THROW
+ packet(0x0961,26,clif->pPartyInvite2,2); // CZ_PARTY_JOIN_REQ
+ packet(0x0967,5,clif->pChangeDir,2,4); // CZ_CHANGE_DIRECTION
+ packet(0x096a,6,clif->pGetCharNameRequest,2); // CZ_REQNAME
+#endif
+
+// 2015-08-26aRagexeRE
+#if PACKETVER == 20150826
+// shuffle packets
+ packet(0x0362,36,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD
+ packet(0x0368,8,clif->pMoveFromKafra,2,4); // CZ_MOVE_ITEM_FROM_STORE_TO_BODY
+ packet(0x0436,18,clif->pPartyBookingRegisterReq,2,4); // CZ_PARTY_BOOKING_REQ_REGISTER
+ packet(0x07ec,7,clif->pActionRequest,2,6); // CZ_REQUEST_ACT
+ packet(0x0819,6,clif->pReqClickBuyingStore,2); // CZ_REQ_CLICK_TO_BUYING_STORE
+ packet(0x0861,8,clif->pDull/*,XXX*/); // CZ_JOIN_BATTLE_FIELD
+ packet(0x0865,5,clif->pWalkToXY,2); // CZ_REQUEST_MOVE
+ packet(0x086b,10,clif->pUseSkillToPos,2,4,6,8); // CZ_USE_SKILL_TOGROUND
+ packet(0x0870,-1,clif->pReqOpenBuyingStore,2,4,8,9,89); // CZ_REQ_OPEN_BUYING_STORE
+ packet(0x087b,6,clif->pSolveCharName,2); // CZ_REQNAME_BYGID
+ packet(0x088b,26,clif->pPartyInvite2,2); // CZ_PARTY_JOIN_REQ
+ packet(0x088d,26,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS
+ packet(0x0890,2,clif->pSearchStoreInfoNextPage,0); // CZ_SEARCH_STORE_INFO_NEXT_PAGE
+ packet(0x0891,10,clif->pUseSkillToId,2,4,6); // CZ_USE_SKILL
+ packet(0x08a0,12,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SSILIST_ITEM_CLICK
+ packet(0x08a1,8,clif->pMoveToKafra,2,4); // CZ_MOVE_ITEM_FROM_BODY_TO_STORE
+ packet(0x08a4,6,clif->pTakeItem,2); // CZ_ITEM_PICKUP
+ packet(0x08a8,-1,clif->pReqTradeBuyingStore,2,4,8,12); // CZ_REQ_TRADE_BUYING_STORE
+ packet(0x0924,6,clif->pDropItem,2,4); // CZ_ITEM_THROW
+ packet(0x0928,2,clif->pReqCloseBuyingStore,0); // CZ_REQ_CLOSE_BUYING_STORE
+ packet(0x092e,90,clif->pUseSkillToPosMoreInfo,2,4,6,8,10); // CZ_USE_SKILL_TOGROUND_WITHTALKBOX
+ packet(0x093b,6,clif->pGetCharNameRequest,2); // CZ_REQNAME
+ packet(0x0945,5,clif->pHomMenu,2,4); // CZ_COMMAND_MER
+ packet(0x094f,5,clif->pChangeDir,2,4); // CZ_CHANGE_DIRECTION
+ packet(0x0951,6,clif->pTickSend,2); // CZ_REQUEST_TIME
+ packet(0x0959,-1,clif->pItemListWindowSelected,2,4,8); // CZ_ITEMLISTWIN_RES
+ packet(0x0964,19,clif->pWantToConnection,2,6,10,14,18); // CZ_ENTER
+ packet(0x0968,4,clif->pDull/*,XXX*/); // CZ_GANGSI_RANK
+ packet(0x0969,-1,clif->pSearchStoreInfo,2,4,5,9,13,14,15); // CZ_SEARCH_STORE_INFO
+#endif
+
+// 2015-09-09aRagexeRE
+#if PACKETVER >= 20150909
+// new packets
+ packet(0x0a41,18);
+#endif
+
+// 2015-09-16aRagexeRE
+#if PACKETVER >= 20150916
+// new packets
+ packet(0x0a42,43);
+#endif
+
+// 2015-10-01aRagexe
+#if PACKETVER == 20151001
+// shuffle packets
+ packet(0x0202,5,clif->pChangeDir,2,4); // CZ_CHANGE_DIRECTION
+ packet(0x022d,19,clif->pWantToConnection,2,6,10,14,18); // CZ_ENTER
+ packet(0x023b,26,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS
+ packet(0x0281,-1,clif->pItemListWindowSelected,2,4,8); // CZ_ITEMLISTWIN_RES
+ packet(0x035f,6,clif->pTickSend,2); // CZ_REQUEST_TIME
+ packet(0x0360,6,clif->pReqClickBuyingStore,2); // CZ_REQ_CLICK_TO_BUYING_STORE
+ packet(0x0361,5,clif->pHomMenu,2,4); // CZ_COMMAND_MER
+ packet(0x0362,6,clif->pDropItem,2,4); // CZ_ITEM_THROW
+ packet(0x0363,8,clif->pDull/*,XXX*/); // CZ_JOIN_BATTLE_FIELD
+ packet(0x0364,8,clif->pMoveFromKafra,2,4); // CZ_MOVE_ITEM_FROM_STORE_TO_BODY
+ packet(0x0365,18,clif->pPartyBookingRegisterReq,2,4); // CZ_PARTY_BOOKING_REQ_REGISTER
+ packet(0x0366,90,clif->pUseSkillToPosMoreInfo,2,4,6,8,10); // CZ_USE_SKILL_TOGROUND_WITHTALKBOX
+ packet(0x0368,6,clif->pSolveCharName,2); // CZ_REQNAME_BYGID
+ packet(0x0369,7,clif->pActionRequest,2,6); // CZ_REQUEST_ACT
+ packet(0x0436,4,clif->pDull/*,XXX*/); // CZ_GANGSI_RANK
+ packet(0x0437,5,clif->pWalkToXY,2); // CZ_REQUEST_MOVE
+ packet(0x0438,10,clif->pUseSkillToPos,2,4,6,8); // CZ_USE_SKILL_TOGROUND
+ packet(0x07e4,6,clif->pTakeItem,2); // CZ_ITEM_PICKUP
+ packet(0x07ec,8,clif->pMoveToKafra,2,4); // CZ_MOVE_ITEM_FROM_BODY_TO_STORE
+ packet(0x0802,26,clif->pPartyInvite2,2); // CZ_PARTY_JOIN_REQ
+ packet(0x0811,-1,clif->pReqTradeBuyingStore,2,4,8,12); // CZ_REQ_TRADE_BUYING_STORE
+ packet(0x0815,-1,clif->pReqOpenBuyingStore,2,4,8,9,89); // CZ_REQ_OPEN_BUYING_STORE
+ packet(0x0817,2,clif->pReqCloseBuyingStore,0); // CZ_REQ_CLOSE_BUYING_STORE
+ packet(0x0819,-1,clif->pSearchStoreInfo,2,4,5,9,13,14,15); // CZ_SEARCH_STORE_INFO
+ packet(0x0835,2,clif->pSearchStoreInfoNextPage,0); // CZ_SEARCH_STORE_INFO_NEXT_PAGE
+ packet(0x0838,12,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SSILIST_ITEM_CLICK
+ packet(0x083c,10,clif->pUseSkillToId,2,4,6); // CZ_USE_SKILL
+ packet(0x0960,36,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD
+ packet(0x096a,6,clif->pGetCharNameRequest,2); // CZ_REQNAME
+#endif
+
+// 2015-10-07aRagexeRE
+#if PACKETVER == 20151007
+// shuffle packets
+ packet(0x0202,-1,clif->pReqTradeBuyingStore,2,4,8,12); // CZ_REQ_TRADE_BUYING_STORE
+ packet(0x0281,-1,clif->pItemListWindowSelected,2,4,8); // CZ_ITEMLISTWIN_RES
+ packet(0x035f,6,clif->pTickSend,2); // CZ_REQUEST_TIME
+ packet(0x0360,6,clif->pReqClickBuyingStore,2); // CZ_REQ_CLICK_TO_BUYING_STORE
+ packet(0x0362,6,clif->pDropItem,2,4); // CZ_ITEM_THROW
+ packet(0x0363,8,clif->pDull/*,XXX*/); // CZ_JOIN_BATTLE_FIELD
+ packet(0x0364,8,clif->pMoveFromKafra,2,4); // CZ_MOVE_ITEM_FROM_STORE_TO_BODY
+ packet(0x0365,18,clif->pPartyBookingRegisterReq,2,4); // CZ_PARTY_BOOKING_REQ_REGISTER
+ packet(0x0366,90,clif->pUseSkillToPosMoreInfo,2,4,6,8,10); // CZ_USE_SKILL_TOGROUND_WITHTALKBOX
+ packet(0x0368,6,clif->pSolveCharName,2); // CZ_REQNAME_BYGID
+ packet(0x0369,7,clif->pActionRequest,2,6); // CZ_REQUEST_ACT
+ packet(0x0437,5,clif->pWalkToXY,2); // CZ_REQUEST_MOVE
+ packet(0x0438,10,clif->pUseSkillToPos,2,4,6,8); // CZ_USE_SKILL_TOGROUND
+ packet(0x07e4,6,clif->pTakeItem,2); // CZ_ITEM_PICKUP
+ packet(0x07ec,8,clif->pMoveToKafra,2,4); // CZ_MOVE_ITEM_FROM_BODY_TO_STORE
+ packet(0x0802,26,clif->pPartyInvite2,2); // CZ_PARTY_JOIN_REQ
+ packet(0x0811,26,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS
+ packet(0x0815,-1,clif->pReqOpenBuyingStore,2,4,8,9,89); // CZ_REQ_OPEN_BUYING_STORE
+ packet(0x0817,2,clif->pReqCloseBuyingStore,0); // CZ_REQ_CLOSE_BUYING_STORE
+ packet(0x0819,-1,clif->pSearchStoreInfo,2,4,5,9,13,14,15); // CZ_SEARCH_STORE_INFO
+ packet(0x0835,2,clif->pSearchStoreInfoNextPage,0); // CZ_SEARCH_STORE_INFO_NEXT_PAGE
+ packet(0x0838,12,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SSILIST_ITEM_CLICK
+ packet(0x083c,10,clif->pUseSkillToId,2,4,6); // CZ_USE_SKILL
+ packet(0x0862,4,clif->pDull/*,XXX*/); // CZ_GANGSI_RANK
+ packet(0x093f,5,clif->pHomMenu,2,4); // CZ_COMMAND_MER
+ packet(0x095f,5,clif->pChangeDir,2,4); // CZ_CHANGE_DIRECTION
+ packet(0x0961,19,clif->pWantToConnection,2,6,10,14,18); // CZ_ENTER
+ packet(0x0967,36,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD
+ packet(0x096a,6,clif->pGetCharNameRequest,2); // CZ_REQNAME
+#endif
+
+// 2015-10-07aRagexeRE
+#if PACKETVER >= 20151007
+// new packets
+ packet(0x0a43,85);
+ packet(0x0a44,-1);
+#endif
+
+// 2015-10-14bRagexeRE
+#if PACKETVER == 20151014
+// shuffle packets
+ packet(0x0202,18,clif->pPartyBookingRegisterReq,2,4); // CZ_PARTY_BOOKING_REQ_REGISTER
+ packet(0x0817,26,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS
+ packet(0x0838,-1,clif->pSearchStoreInfo,2,4,5,9,13,14,15); // CZ_SEARCH_STORE_INFO
+ packet(0x085a,10,clif->pUseSkillToId,2,4,6); // CZ_USE_SKILL
+ packet(0x085c,7,clif->pActionRequest,2,6); // CZ_REQUEST_ACT
+ packet(0x0860,6,clif->pDropItem,2,4); // CZ_ITEM_THROW
+ packet(0x0863,5,clif->pChangeDir,2,4); // CZ_CHANGE_DIRECTION
+ packet(0x0867,-1,clif->pReqTradeBuyingStore,2,4,8,12); // CZ_REQ_TRADE_BUYING_STORE
+ packet(0x0872,5,clif->pHomMenu,2,4); // CZ_COMMAND_MER
+ packet(0x0874,10,clif->pUseSkillToPos,2,4,6,8); // CZ_USE_SKILL_TOGROUND
+ packet(0x0881,8,clif->pMoveFromKafra,2,4); // CZ_MOVE_ITEM_FROM_STORE_TO_BODY
+ packet(0x0883,6,clif->pTickSend,2); // CZ_REQUEST_TIME
+ packet(0x0884,-1,clif->pItemListWindowSelected,2,4,8); // CZ_ITEMLISTWIN_RES
+ packet(0x0889,6,clif->pReqClickBuyingStore,2); // CZ_REQ_CLICK_TO_BUYING_STORE
+ packet(0x088e,8,clif->pDull/*,XXX*/); // CZ_JOIN_BATTLE_FIELD
+ packet(0x089a,4,clif->pDull/*,XXX*/); // CZ_GANGSI_RANK
+ packet(0x089b,2,clif->pReqCloseBuyingStore,0); // CZ_REQ_CLOSE_BUYING_STORE
+ packet(0x089f,5,clif->pWalkToXY,2); // CZ_REQUEST_MOVE
+ packet(0x08aa,6,clif->pTakeItem,2); // CZ_ITEM_PICKUP
+ packet(0x091c,26,clif->pPartyInvite2,2); // CZ_PARTY_JOIN_REQ
+ packet(0x091d,36,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD
+ packet(0x0930,90,clif->pUseSkillToPosMoreInfo,2,4,6,8,10); // CZ_USE_SKILL_TOGROUND_WITHTALKBOX
+ packet(0x0934,-1,clif->pReqOpenBuyingStore,2,4,8,9,89); // CZ_REQ_OPEN_BUYING_STORE
+ packet(0x0944,12,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SSILIST_ITEM_CLICK
+ packet(0x094f,2,clif->pSearchStoreInfoNextPage,0); // CZ_SEARCH_STORE_INFO_NEXT_PAGE
+ packet(0x0956,6,clif->pSolveCharName,2); // CZ_REQNAME_BYGID
+ packet(0x095e,8,clif->pMoveToKafra,2,4); // CZ_MOVE_ITEM_FROM_BODY_TO_STORE
+ packet(0x0961,6,clif->pGetCharNameRequest,2); // CZ_REQNAME
+ packet(0x0964,19,clif->pWantToConnection,2,6,10,14,18); // CZ_ENTER
+#endif
+
+// 2015-10-28cRagexeRE
+#if PACKETVER == 20151028
+// shuffle packets
+ packet(0x0202,5,clif->pChangeDir,2,4); // CZ_CHANGE_DIRECTION
+ packet(0x022d,19,clif->pWantToConnection,2,6,10,14,18); // CZ_ENTER
+ packet(0x023b,26,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS
+ packet(0x0281,-1,clif->pItemListWindowSelected,2,4,8); // CZ_ITEMLISTWIN_RES
+ packet(0x035f,6,clif->pTickSend,2); // CZ_REQUEST_TIME
+ packet(0x0360,6,clif->pReqClickBuyingStore,2); // CZ_REQ_CLICK_TO_BUYING_STORE
+ packet(0x0361,5,clif->pHomMenu,2,4); // CZ_COMMAND_MER
+ packet(0x0362,6,clif->pDropItem,2,4); // CZ_ITEM_THROW
+ packet(0x0363,8,clif->pDull/*,XXX*/); // CZ_JOIN_BATTLE_FIELD
+ packet(0x0364,8,clif->pMoveFromKafra,2,4); // CZ_MOVE_ITEM_FROM_STORE_TO_BODY
+ packet(0x0365,18,clif->pPartyBookingRegisterReq,2,4); // CZ_PARTY_BOOKING_REQ_REGISTER
+ packet(0x0366,90,clif->pUseSkillToPosMoreInfo,2,4,6,8,10); // CZ_USE_SKILL_TOGROUND_WITHTALKBOX
+ packet(0x0368,6,clif->pSolveCharName,2); // CZ_REQNAME_BYGID
+ packet(0x0369,7,clif->pActionRequest,2,6); // CZ_REQUEST_ACT
+ packet(0x0436,4,clif->pDull/*,XXX*/); // CZ_GANGSI_RANK
+ packet(0x0437,5,clif->pWalkToXY,2); // CZ_REQUEST_MOVE
+ packet(0x0438,10,clif->pUseSkillToPos,2,4,6,8); // CZ_USE_SKILL_TOGROUND
+ packet(0x07e4,6,clif->pTakeItem,2); // CZ_ITEM_PICKUP
+ packet(0x07ec,8,clif->pMoveToKafra,2,4); // CZ_MOVE_ITEM_FROM_BODY_TO_STORE
+ packet(0x0802,26,clif->pPartyInvite2,2); // CZ_PARTY_JOIN_REQ
+ packet(0x0811,-1,clif->pReqTradeBuyingStore,2,4,8,12); // CZ_REQ_TRADE_BUYING_STORE
+ packet(0x0815,-1,clif->pReqOpenBuyingStore,2,4,8,9,89); // CZ_REQ_OPEN_BUYING_STORE
+ packet(0x0817,2,clif->pReqCloseBuyingStore,0); // CZ_REQ_CLOSE_BUYING_STORE
+ packet(0x0819,-1,clif->pSearchStoreInfo,2,4,5,9,13,14,15); // CZ_SEARCH_STORE_INFO
+ packet(0x0835,2,clif->pSearchStoreInfoNextPage,0); // CZ_SEARCH_STORE_INFO_NEXT_PAGE
+ packet(0x0838,12,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SSILIST_ITEM_CLICK
+ packet(0x083c,10,clif->pUseSkillToId,2,4,6); // CZ_USE_SKILL
+ packet(0x0860,36,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD
+ packet(0x096a,6,clif->pGetCharNameRequest,2); // CZ_REQNAME
+#endif
+
+// 2015-10-28cRagexeRE
+#if PACKETVER >= 20151028
+// new packets
+ packet(0x0a45,-1);
#endif
// 2015-10-29aRagexe
@@ -3112,7 +4379,6 @@ packet(0x96e,-1,clif->ackmergeitems);
packet(0x0860,36,clif->pStoragePassword,0);
packet(0x0363,8,clif->pDull); // CZ_JOIN_BATTLE_FIELD
packet(0x0436,4,clif->pDull); // CZ_GANGSI_RANK
- packet(0x0a39,36);
#endif
// 2015-11-04aRagexe
@@ -3146,7 +4412,89 @@ packet(0x96e,-1,clif->ackmergeitems);
packet(0x0940,36,clif->pStoragePassword,2,4,20);
packet(0x08a3,4,clif->pDull); // CZ_GANGSI_RANK
packet(0x0939,8,clif->pDull); // CZ_JOIN_BATTLE_FIELD
- packet(0x0a39,36);
+// new packets
+ packet(0x0a46,14,clif->pDull/*,XXX*/);
+ packet(0x0a47,3);
+ packet(0x0a48,2,clif->pDull/*,XXX*/);
+// changed packet sizes
+ packet(0x0a45,2);
+#endif
+
+// 2015-11-18aRagexeRE
+#if PACKETVER == 20151118
+// shuffle packets
+ packet(0x022d,6,clif->pTickSend,2); // CZ_REQUEST_TIME
+ packet(0x035f,5,clif->pHomMenu,2,4); // CZ_COMMAND_MER
+ packet(0x0360,6,clif->pReqClickBuyingStore,2); // CZ_REQ_CLICK_TO_BUYING_STORE
+ packet(0x0365,26,clif->pPartyInvite2,2); // CZ_PARTY_JOIN_REQ
+ packet(0x0366,90,clif->pUseSkillToPosMoreInfo,2,4,6,8,10); // CZ_USE_SKILL_TOGROUND_WITHTALKBOX
+ packet(0x0368,6,clif->pSolveCharName,2); // CZ_REQNAME_BYGID
+ packet(0x0369,7,clif->pActionRequest,2,6); // CZ_REQUEST_ACT
+ packet(0x0437,5,clif->pWalkToXY,2); // CZ_REQUEST_MOVE
+ packet(0x0438,10,clif->pUseSkillToPos,2,4,6,8); // CZ_USE_SKILL_TOGROUND
+ packet(0x0811,-1,clif->pReqTradeBuyingStore,2,4,8,12); // CZ_REQ_TRADE_BUYING_STORE
+ packet(0x0815,-1,clif->pReqOpenBuyingStore,2,4,8,9,89); // CZ_REQ_OPEN_BUYING_STORE
+ packet(0x0817,2,clif->pReqCloseBuyingStore,0); // CZ_REQ_CLOSE_BUYING_STORE
+ packet(0x0819,-1,clif->pSearchStoreInfo,2,4,5,9,13,14,15); // CZ_SEARCH_STORE_INFO
+ packet(0x0835,2,clif->pSearchStoreInfoNextPage,0); // CZ_SEARCH_STORE_INFO_NEXT_PAGE
+ packet(0x0838,12,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SSILIST_ITEM_CLICK
+ packet(0x083c,10,clif->pUseSkillToId,2,4,6); // CZ_USE_SKILL
+ packet(0x086b,8,clif->pMoveToKafra,2,4); // CZ_MOVE_ITEM_FROM_BODY_TO_STORE
+ packet(0x088b,36,clif->pStoragePassword,2,4,20); // CZ_ACK_STORE_PASSWORD
+ packet(0x08ab,8,clif->pMoveFromKafra,2,4); // CZ_MOVE_ITEM_FROM_STORE_TO_BODY
+ packet(0x0921,26,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS
+ packet(0x0925,19,clif->pWantToConnection,2,6,10,14,18); // CZ_ENTER
+ packet(0x092e,5,clif->pChangeDir,2,4); // CZ_CHANGE_DIRECTION
+ packet(0x092f,8,clif->pDull/*,XXX*/); // CZ_JOIN_BATTLE_FIELD
+ packet(0x093c,6,clif->pDropItem,2,4); // CZ_ITEM_THROW
+ packet(0x0943,6,clif->pTakeItem,2); // CZ_ITEM_PICKUP
+ packet(0x0946,-1,clif->pItemListWindowSelected,2,4,8,12); // CZ_ITEMLISTWIN_RES
+ packet(0x0957,4,clif->pDull/*,XXX*/); // CZ_GANGSI_RANK
+ packet(0x095c,18,clif->pPartyBookingRegisterReq,2,4,6); // CZ_PARTY_BOOKING_REQ_REGISTER
+ packet(0x096a,6,clif->pGetCharNameRequest,2); // CZ_REQNAME
+#endif
+
+// 2015-11-18aRagexeRE
+#if PACKETVER >= 20151118
+// new packets
+ packet(0x0a49,22);
+ packet(0x0a4a,6);
+ packet(0x0a4b,22);
+ packet(0x0a4c,28);
+#endif
+
+// 2015-12-02bRagexeRE
+#if PACKETVER == 20151202
+// shuffle packets
+ packet(0x0202,5,clif->pChangeDir,2,4); // CZ_CHANGE_DIRECTION
+ packet(0x022d,19,clif->pWantToConnection,2,6,10,14,18); // CZ_ENTER
+ packet(0x023b,26,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS
+ packet(0x0281,-1,clif->pItemListWindowSelected,2,4,8,12); // CZ_ITEMLISTWIN_RES
+ packet(0x035f,6,clif->pTickSend,2); // CZ_REQUEST_TIME
+ packet(0x0360,6,clif->pReqClickBuyingStore,2); // CZ_REQ_CLICK_TO_BUYING_STORE
+ packet(0x0361,5,clif->pHomMenu,2,4); // CZ_COMMAND_MER
+ packet(0x0362,6,clif->pDropItem,2,4); // CZ_ITEM_THROW
+ packet(0x0363,8,clif->pDull/*,XXX*/); // CZ_JOIN_BATTLE_FIELD
+ packet(0x0364,8,clif->pMoveFromKafra,2,4); // CZ_MOVE_ITEM_FROM_STORE_TO_BODY
+ packet(0x0365,18,clif->pPartyBookingRegisterReq,2,4,6); // CZ_PARTY_BOOKING_REQ_REGISTER
+ packet(0x0366,90,clif->pUseSkillToPosMoreInfo,2,4,6,8,10); // CZ_USE_SKILL_TOGROUND_WITHTALKBOX
+ packet(0x0368,6,clif->pSolveCharName,2); // CZ_REQNAME_BYGID
+ packet(0x0369,7,clif->pActionRequest,2,6); // CZ_REQUEST_ACT
+ packet(0x0436,4,clif->pDull/*,XXX*/); // CZ_GANGSI_RANK
+ packet(0x0437,5,clif->pWalkToXY,2); // CZ_REQUEST_MOVE
+ packet(0x0438,10,clif->pUseSkillToPos,2,4,6,8); // CZ_USE_SKILL_TOGROUND
+ packet(0x07e4,6,clif->pTakeItem,2); // CZ_ITEM_PICKUP
+ packet(0x07ec,8,clif->pMoveToKafra,2,4); // CZ_MOVE_ITEM_FROM_BODY_TO_STORE
+ packet(0x0802,26,clif->pPartyInvite2,2); // CZ_PARTY_JOIN_REQ
+ packet(0x0811,-1,clif->pReqTradeBuyingStore,2,4,8,12); // CZ_REQ_TRADE_BUYING_STORE
+ packet(0x0815,-1,clif->pReqOpenBuyingStore,2,4,8,9,89); // CZ_REQ_OPEN_BUYING_STORE
+ packet(0x0817,2,clif->pReqCloseBuyingStore,0); // CZ_REQ_CLOSE_BUYING_STORE
+ packet(0x0819,-1,clif->pSearchStoreInfo,2,4,5,9,13,14,15); // CZ_SEARCH_STORE_INFO
+ packet(0x0835,2,clif->pSearchStoreInfoNextPage,0); // CZ_SEARCH_STORE_INFO_NEXT_PAGE
+ packet(0x0838,12,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SSILIST_ITEM_CLICK
+ packet(0x083c,10,clif->pUseSkillToId,2,4,6); // CZ_USE_SKILL
+ packet(0x0870,36,clif->pStoragePassword,2,4,20); // CZ_ACK_STORE_PASSWORD
+ packet(0x096a,6,clif->pGetCharNameRequest,2); // CZ_REQNAME
#endif
// 2015-12-16aRagexe
@@ -3182,6 +4530,40 @@ packet(0x96e,-1,clif->ackmergeitems);
packet(0x086a,8,clif->pDull); // CZ_JOIN_BATTLE_FIELD
#endif
+// 2015-12-23bRagexeRE
+#if PACKETVER == 20151223
+// shuffle packets
+ packet(0x02c4,8,clif->pMoveToKafra,2,4); // CZ_MOVE_ITEM_FROM_BODY_TO_STORE
+ packet(0x0362,8,clif->pDull/*,XXX*/); // CZ_JOIN_BATTLE_FIELD
+ packet(0x0364,6,clif->pTakeItem,2); // CZ_ITEM_PICKUP
+ packet(0x0802,4,clif->pDull/*,XXX*/); // CZ_GANGSI_RANK
+ packet(0x0815,-1,clif->pSearchStoreInfo,2,4,5,9,13,14,15); // CZ_SEARCH_STORE_INFO
+ packet(0x0864,6,clif->pGetCharNameRequest,2); // CZ_REQNAME
+ packet(0x0866,19,clif->pWantToConnection,2,6,10,14,18); // CZ_ENTER
+ packet(0x086e,10,clif->pUseSkillToPos,2,4,6,8); // CZ_USE_SKILL_TOGROUND
+ packet(0x0872,18,clif->pPartyBookingRegisterReq,2,4); // CZ_PARTY_BOOKING_REQ_REGISTER
+ packet(0x0875,10,clif->pUseSkillToId,2,4,6); // CZ_USE_SKILL
+ packet(0x0876,6,clif->pDropItem,2,4); // CZ_ITEM_THROW
+ packet(0x0881,7,clif->pActionRequest,2,6); // CZ_REQUEST_ACT
+ packet(0x0884,8,clif->pMoveFromKafra,2,4); // CZ_MOVE_ITEM_FROM_STORE_TO_BODY
+ packet(0x0886,-1,clif->pReqTradeBuyingStore,2,4,8,12); // CZ_REQ_TRADE_BUYING_STORE
+ packet(0x088d,5,clif->pHomMenu,2,4); // CZ_COMMAND_MER
+ packet(0x0890,-1,clif->pItemListWindowSelected,2,4,8); // CZ_ITEMLISTWIN_RES
+ packet(0x0891,-1,clif->pReqOpenBuyingStore,2,4,8,9,89); // CZ_REQ_OPEN_BUYING_STORE
+ packet(0x0898,90,clif->pUseSkillToPosMoreInfo,2,4,6,8,10); // CZ_USE_SKILL_TOGROUND_WITHTALKBOX
+ packet(0x08aa,26,clif->pPartyInvite2,2); // CZ_PARTY_JOIN_REQ
+ packet(0x0918,2,clif->pSearchStoreInfoNextPage,0); // CZ_SEARCH_STORE_INFO_NEXT_PAGE
+ packet(0x091a,6,clif->pReqClickBuyingStore,2); // CZ_REQ_CLICK_TO_BUYING_STORE
+ packet(0x091b,26,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS
+ packet(0x0920,5,clif->pWalkToXY,2); // CZ_REQUEST_MOVE
+ packet(0x0923,5,clif->pChangeDir,2,4); // CZ_CHANGE_DIRECTION
+ packet(0x0924,6,clif->pTickSend,2); // CZ_REQUEST_TIME
+ packet(0x095e,6,clif->pSolveCharName,2); // CZ_REQNAME_BYGID
+ packet(0x095f,2,clif->pReqCloseBuyingStore,0); // CZ_REQ_CLOSE_BUYING_STORE
+ packet(0x0965,36,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD
+ packet(0x0967,12,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SSILIST_ITEM_CLICK
+#endif
+
/* PacketKeys: http://herc.ws/board/topic/1105-hercules-wpe-free-june-14th-patch/ */
#if PACKETVER >= 20110817
packetKeys(0x053D5CED,0x3DED6DED,0x6DED6DED); /* Thanks to Shakto */
@@ -3423,14 +4805,94 @@ packet(0x96e,-1,clif->ackmergeitems);
// 2015 Packet Keys
+#if PACKETVER == 20150107
+ packetKeys(0x6C494A14,0x4DDB6427,0x3E6D7B65); /* 4144 */
+#endif
+
+#if PACKETVER == 20150114
+ packetKeys(0x21C96102,0x13142934,0x1ABF4EA3); /* 4144 */
+#endif
+
+#if PACKETVER == 20150128
+ packetKeys(0x77CA2D55,0x28B608F0,0x75B47957); /* 4144 */
+#endif
+
+#if PACKETVER == 20150204
+ packetKeys(0x134529DB,0x5B4F6CEF,0x29EF11EF); /* 4144 */
+#endif
+
+#if PACKETVER == 20150225
+ packetKeys(0x57FD4B7B,0x19CC16FB,0x0D255D72); /* 4144 */
+#endif
+
+#if PACKETVER == 20150226
+ packetKeys(0x57FD4B7B,0x19CC16FB,0x0D255D72); /* 4144 */
+#endif
+
+#if PACKETVER == 20150311
+ packetKeys(0x48C45D97,0x06CE09B0,0x5836642F); /* 4144 */
+#endif
+
+#if PACKETVER == 20150325
+ packetKeys(0x68F62B8C,0x337C3468,0x38FC0AC7); /* 4144 */
+#endif
+
+#if PACKETVER == 20150401
+ packetKeys(0x207F3A08,0x57E6160C,0x02A60382); /* 4144 */
+#endif
+
+#if PACKETVER == 20150422
+ packetKeys(0x10D22CE2,0x69E279E2,0x79E279E2); /* 4144 */
+#endif
+
+#if PACKETVER == 20150429
+ packetKeys(0x2BF61A71,0x565D5DDF,0x0FB90019); /* 4144 */
+#endif
+
+#if PACKETVER == 20150507
+ packetKeys(0x55B54373,0x58967821,0x67F41832); /* 4144 */
+#endif
+
#if PACKETVER >= 20150513
packetKeys(0x62C86D09,0x75944F17,0x112C133D); /* Dastgir */
#endif
+#if PACKETVER == 20150527
+ packetKeys(0x35AE7BAE,0x3BAE3BAE,0x3BAE3BAE); /* 4144 */
+#endif
+
+#if PACKETVER == 20150617
+ packetKeys(0x250F7E09,0x25416076,0x029A780E); /* 4144 */
+#endif
+
+#if PACKETVER == 20150618
+ packetKeys(0x250F7E09,0x25416076,0x029A780E); /* 4144 */
+#endif
+
+#if PACKETVER == 20150819
+ packetKeys(0x1A2400E0,0x736E5686,0x10F315D5); /* 4144 */
+#endif
+
+#if PACKETVER == 20150826
+ packetKeys(0x77883C56,0x1829359F,0x0DE635B6); /* 4144 */
+#endif
+
#if PACKETVER >= 20151001
packetKeys(0x5CFF4561,0x32514AD1,0x06D126D1); /* Dastgir */
#endif
+#if PACKETVER == 20151007
+ packetKeys(0x3C6447A8,0x032170D7,0x6490476C); /* 4144 */
+#endif
+
+#if PACKETVER == 20151014
+ packetKeys(0x402728A8,0x5D0E309F,0x240018FD); /* 4144 */
+#endif
+
+#if PACKETVER == 20151028
+ packetKeys(0x45B945B9,0x45B945B9,0x45B945B9); /* 4144 */
+#endif
+
#if PACKETVER >= 20151029
packetKeys(0x45B945B9,0x45B945B9,0x45B945B9); /* Dastgir */
#endif
@@ -3439,10 +4901,22 @@ packet(0x96e,-1,clif->ackmergeitems);
packetKeys(0x4C17382A,0x7ED174C9,0x29961E4F); /* ossi0110 */
#endif
+#if PACKETVER == 20151118
+ packetKeys(0x734C3241,0x6E846F34,0x731C06D6); /* 4144 */
+#endif
+
+#if PACKETVER == 20151202
+ packetKeys(0x4EDE52DE,0x52DE52DE,0x52DE52DE); /* 4144 */
+#endif
+
#if PACKETVER >= 20151216
packetKeys(0x25DD643D,0x61AC39DE,0x77A8206D); /* Dastgir */
#endif
+#if PACKETVER == 20151223
+ packetKeys(0x347D68D0,0x2C705320,0x7B4A199D); /* 4144 */
+#endif
+
#if defined(OBFUSCATIONKEY1) && defined(OBFUSCATIONKEY2) && defined(OBFUSCATIONKEY3)
packetKeys(OBFUSCATIONKEY1,OBFUSCATIONKEY2,OBFUSCATIONKEY3);
#endif
diff --git a/src/map/packets_struct.h b/src/map/packets_struct.h
index e461eebe9..0bd85db7f 100644
--- a/src/map/packets_struct.h
+++ b/src/map/packets_struct.h
@@ -141,8 +141,11 @@ enum packet_headers {
authokType = 0x73,
#elif PACKETVER < 20141022
authokType = 0x2eb,
-#else
+// Some clients smaller than 20160330 cant be tested [4144]
+#elif PACKETVER < 20160330
authokType = 0xa18,
+#else
+ authokType = 0x2eb,
#endif
script_clearType = 0x8d6,
package_item_announceType = 0x7fd,
@@ -286,7 +289,7 @@ enum packet_headers {
maptypeproperty2Type = 0x99b,
npcmarketresultackType = 0x9d7,
npcmarketopenType = 0x9d5,
-#if PACKETVER >= 20131223
+#if PACKETVER >= 20131223 // version probably can be 20131030 [4144]
wisendType = 0x9df,
#else
wisendType = 0x98,
@@ -343,7 +346,7 @@ struct NORMALITEM_INFO {
#endif
} __attribute__((packed));
-struct RndOptions {
+struct ItemOptions {
int16 index;
int16 value;
uint8 param;
@@ -379,7 +382,7 @@ struct EQUIPITEM_INFO {
#endif
#if PACKETVER >= 20150226
uint8 option_count;
- struct RndOptions option_data[5];
+ struct ItemOptions option_data[MAX_ITEM_OPTIONS];
#endif
#if PACKETVER >= 20120925
struct {
@@ -400,7 +403,8 @@ struct packet_authok {
#if PACKETVER >= 20080102
int16 font;
#endif
-#if PACKETVER >= 20141022
+// Some clients smaller than 20160330 cant be tested [4144]
+#if PACKETVER >= 20141022 && PACKETVER < 20160330
uint8 sex;
#endif
} __attribute__((packed));
@@ -442,7 +446,7 @@ struct packet_additem {
uint16 bindOnEquipType;
#endif
#if PACKETVER >= 20150226
- struct RndOptions option_data[5];
+ struct ItemOptions option_data[MAX_ITEM_OPTIONS];
#endif
} __attribute__((packed));
@@ -589,6 +593,9 @@ struct packet_spawn_unit {
#endif
#if PACKETVER >= 20150513
int16 body;
+#endif
+/* Might be earlier, this is when the named item bug began */
+#if PACKETVER >= 20131223
char name[NAME_LENGTH];
#endif
} __attribute__((packed));
@@ -657,6 +664,9 @@ struct packet_unit_walking {
#endif
#if PACKETVER >= 20150513
int16 body;
+#endif
+/* Might be earlier, this is when the named item bug began */
+#if PACKETVER >= 20131223
char name[NAME_LENGTH];
#endif
} __attribute__((packed));
@@ -723,6 +733,9 @@ struct packet_idle_unit {
#endif
#if PACKETVER >= 20150513
int16 body;
+#endif
+/* Might be earlier, this is when the named item bug began */
+#if PACKETVER >= 20131223
char name[NAME_LENGTH];
#endif
} __attribute__((packed));
diff --git a/src/map/party.c b/src/map/party.c
index 3bf9542c7..26b4bae8b 100644
--- a/src/map/party.c
+++ b/src/map/party.c
@@ -274,6 +274,7 @@ int party_recv_info(const struct party *sp, int char_id)
int added_count = 0;
int j;
int member_id;
+ int leader_account_id = 0, leader_char_id = 0;
nullpo_ret(sp);
@@ -287,8 +288,12 @@ int party_recv_info(const struct party *sp, int char_id)
ARR_FIND(0, MAX_PARTY, i,
sp->member[i].account_id == member->account_id &&
sp->member[i].char_id == member->char_id);
- if (i == MAX_PARTY)
+ if (i == MAX_PARTY) {
removed[removed_count++] = member_id;
+ } else if (member->leader != 0) {
+ leader_account_id = member->account_id;
+ leader_char_id = member->char_id;
+ }
}
for (member_id = 0; member_id < MAX_PARTY; ++member_id) {
member = &sp->member[member_id];
@@ -316,6 +321,7 @@ int party_recv_info(const struct party *sp, int char_id)
continue;// not online
party->member_withdraw(sp->party_id, sd->status.account_id, sd->status.char_id);
}
+
memcpy(&p->party, sp, sizeof(struct party));
memset(&p->state, 0, sizeof(p->state));
memset(&p->data, 0, sizeof(p->data));
@@ -324,6 +330,8 @@ int party_recv_info(const struct party *sp, int char_id)
if ( member->char_id == 0 )
continue;// empty
p->data[member_id].sd = party->sd_check(sp->party_id, member->account_id, member->char_id);
+ if (member->account_id == leader_account_id && member->char_id == leader_char_id)
+ p->party.member[member_id].leader = 1;
}
party->check_state(p);
while( added_count > 0 ) { // new in party
@@ -591,11 +599,43 @@ int party_member_withdraw(int party_id, int account_id, int char_id)
int i;
ARR_FIND( 0, MAX_PARTY, i, p->party.member[i].account_id == account_id && p->party.member[i].char_id == char_id );
if( i < MAX_PARTY ) {
+ bool was_leader = false;
+ int prev_leader_accountId = 0;
+ if (p->party.member[i].leader != 0) {
+ was_leader = true;
+ prev_leader_accountId = p->party.member[i].account_id;
+ }
+
clif->party_withdraw(p,sd,account_id,p->party.member[i].name,0x0);
memset(&p->party.member[i], 0, sizeof(p->party.member[0]));
memset(&p->data[i], 0, sizeof(p->data[0]));
p->party.count--;
party->check_state(p);
+
+ if (was_leader) {
+ int k;
+ // Member was party leader, try to pick a new leader from online members
+ ARR_FIND(0, MAX_PARTY, k, p->party.member[k].account_id != 0 && p->party.member[k].online == 1);
+
+ if (k == MAX_PARTY) {
+ // No online members, get an offline one
+ ARR_FIND(0, MAX_PARTY, k, p->party.member[k].account_id != 0);
+ }
+
+ if (k < MAX_PARTY) {
+ // Update party's leader
+ p->party.member[k].leader = 1;
+
+ if (p->data[k].sd != NULL) {
+ /** update members **/
+ clif->PartyLeaderChanged(p->data[k].sd, prev_leader_accountId, p->data[k].sd->status.account_id);
+ }
+
+ //Update info.
+ intif->party_leaderchange(p->party.party_id, p->party.member[k].account_id, p->party.member[k].char_id);
+ clif->party_info(p, NULL);
+ }
+ }
}
}
diff --git a/src/map/pc.c b/src/map/pc.c
index 2cf5d75b4..2887942db 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -387,7 +387,6 @@ int pc_banding(struct map_session_data *sd, uint16 skill_lv) {
return c;
}
-// Increases a player's fame points and displays a notice to him
/**
* Increases a player's fame points and displays a notice to them.
*
@@ -742,7 +741,8 @@ int pc_setnewpc(struct map_session_data *sd, int account_id, int char_id, int lo
sd->client_tick = client_tick;
sd->state.active = 0; //to be set to 1 after player is fully authed and loaded.
sd->bl.type = BL_PC;
- sd->canlog_tick = timer->gettick();
+ if (battle_config.prevent_logout_trigger & PLT_LOGIN)
+ sd->canlog_tick = timer->gettick();
//Required to prevent homunculus copuing a base speed of 0.
sd->battle_status.speed = sd->base_status.speed = DEFAULT_WALK_SPEED;
sd->state.warp_clean = 1;
@@ -4841,11 +4841,7 @@ int pc_isUseitem(struct map_session_data *sd,int n)
switch( nameid ) { // TODO: Is there no better way to handle this, other than hardcoding item IDs?
case ITEMID_ANODYNE:
- if( map_flag_gvg2(sd->bl.m) )
- return 0;
- /* Fall through */
- case ITEMID_ALOEBERA:
- if( pc_issit(sd) )
+ if (map_flag_gvg2(sd->bl.m))
return 0;
break;
case ITEMID_WING_OF_FLY:
@@ -4922,17 +4918,6 @@ int pc_isUseitem(struct map_session_data *sd,int n)
if( nameid >= ITEMID_BOW_MERCENARY_SCROLL1 && nameid <= ITEMID_SPEARMERCENARY_SCROLL10 && sd->md != NULL ) // Mercenary Scrolls
return 0;
- /**
- * Only Rune Knights may use runes
- **/
- if (itemdb_is_rune(nameid) && (sd->job & MAPID_THIRDMASK) != MAPID_RUNE_KNIGHT)
- return 0;
- /**
- * Only GCross may use poisons
- **/
- else if (itemdb_is_poison(nameid) && (sd->job & MAPID_THIRDMASK) != MAPID_GUILLOTINE_CROSS)
- return 0;
-
if( item->package || item->group ) {
if (pc_is90overweight(sd)) {
clif->msgtable(sd, MSG_ITEM_CANT_OBTAIN_WEIGHT);
@@ -5079,15 +5064,22 @@ int pc_useitem(struct map_session_data *sd,int n) {
if( sd->inventory_data[n]->flag.delay_consume && ( sd->ud.skilltimer != INVALID_TIMER /*|| !status->check_skilluse(&sd->bl, &sd->bl, ALL_RESURRECTION, 0)*/ ) )
return 0;
- if( sd->inventory_data[n]->delay > 0 ) {
- ARR_FIND(0, MAX_ITEMDELAYS, i, sd->item_delay[i].nameid == nameid );
- if( i == MAX_ITEMDELAYS ) /* item not found. try first empty now */
- ARR_FIND(0, MAX_ITEMDELAYS, i, !sd->item_delay[i].nameid );
- if( i < MAX_ITEMDELAYS ) {
- if( sd->item_delay[i].nameid ) {// found
- if( DIFF_TICK(sd->item_delay[i].tick, tick) > 0 ) {
- int e_tick = (int)(DIFF_TICK(sd->item_delay[i].tick, tick)/1000);
- clif->msgtable_num(sd, MSG_SECONDS_UNTIL_USE, e_tick + 1); // [%d] seconds left until you can use
+ if (sd->inventory_data[n]->delay > 0) {
+ ARR_FIND(0, MAX_ITEMDELAYS, i, sd->item_delay[i].nameid == nameid);
+ if (i == MAX_ITEMDELAYS) /* item not found. try first empty now */
+ ARR_FIND(0, MAX_ITEMDELAYS, i, sd->item_delay[i].nameid == 0);
+ if (i < MAX_ITEMDELAYS) {
+ if (sd->item_delay[i].nameid != 0) {// found
+ if (DIFF_TICK(sd->item_delay[i].tick, tick) > 0) {
+ int delay_tick = (int)(DIFF_TICK(sd->item_delay[i].tick, tick) / 1000);
+#if PACKETVER >= 20101123
+ clif->msgtable_num(sd, MSG_SECONDS_UNTIL_USE, delay_tick + 1); // [%d] seconds left until you can use
+#else
+ char delay_msg[100];
+ clif->msgtable_num(sd, MSG_SECONDS_UNTIL_USE, delay_tick + 1); // [%d] seconds left until you can use
+ sprintf(delay_msg, msg_sd(sd, 26), delay_tick + 1);
+ clif->messagecolor_self(sd->fd, COLOR_YELLOW, delay_msg);
+#endif
return 0; // Delay has not expired yet
}
} else {// not yet used item (all slots are initially empty)
@@ -7704,7 +7696,8 @@ void pc_damage(struct map_session_data *sd,struct block_list *src,unsigned int h
if( sd->status.ele_id > 0 )
elemental->set_target(sd,src);
- sd->canlog_tick = timer->gettick();
+ if (battle_config.prevent_logout_trigger & PLT_DAMAGE)
+ sd->canlog_tick = timer->gettick();
}
/*==========================================
@@ -10036,6 +10029,11 @@ int pc_unequipitem(struct map_session_data *sd,int n,int flag)
status_change_end(&sd->bl, SC_ARMOR_RESIST, INVALID_TIMER);
}
+#ifdef RENEWAL
+ if (battle->bc->bow_unequip_arrow && pos&EQP_ARMS && sd->equip_index[EQI_AMMO] > 0)
+ pc->unequipitem(sd, sd->equip_index[EQI_AMMO], PCUNEQUIPITEM_FORCE);
+#endif
+
if( sd->state.autobonus&pos )
sd->state.autobonus &= ~sd->status.inventory[n].equip; //Check for activated autobonus [Inkfish]
diff --git a/src/map/pc.h b/src/map/pc.h
index 0e4f1affd..482e30c41 100644
--- a/src/map/pc.h
+++ b/src/map/pc.h
@@ -73,6 +73,14 @@ enum equip_index {
EQI_MAX
};
+enum prevent_logout_trigger {
+ PLT_NONE = 0x0,
+ PLT_LOGIN = 0x1,
+ PLT_ATTACK = 0x2,
+ PLT_SKILL = 0x4,
+ PLT_DAMAGE = 0x8
+};
+
enum pc_unequipitem_flag {
PCUNEQUIPITEM_NONE = 0x0, ///< Just unequip
PCUNEQUIPITEM_RECALC = 0x1, ///< Recalculate status after unequipping
diff --git a/src/map/script.c b/src/map/script.c
index 38931bd11..f63dd2097 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -2786,6 +2786,14 @@ char *get_val_npcscope_str(struct script_state* st, struct reg_db *n, struct scr
return NULL;
}
+char *get_val_pc_ref_str(struct script_state *st, struct reg_db *n, struct script_data *data) {
+ struct script_reg_str *p = NULL;
+ nullpo_retr(NULL, n);
+
+ p = i64db_get(n->vars, reference_getuid(data));
+ return p ? p->value : NULL;
+}
+
char *get_val_instance_str(struct script_state* st, const char* name, struct script_data* data) {
nullpo_retr(NULL, st);
if (st->instance_id >= 0) {
@@ -2803,6 +2811,14 @@ int get_val_npcscope_num(struct script_state* st, struct reg_db *n, struct scrip
return 0;
}
+int get_val_pc_ref_num(struct script_state *st, struct reg_db *n, struct script_data *data) {
+ struct script_reg_num *p = NULL;
+ nullpo_retr(0, n);
+
+ p = i64db_get(n->vars, reference_getuid(data));
+ return p ? p->value : 0;
+}
+
int get_val_instance_num(struct script_state* st, const char* name, struct script_data* data) {
if (st->instance_id >= 0)
return (int)i64db_iget(instance->list[st->instance_id].regs.vars, reference_getuid(data));
@@ -2825,7 +2841,7 @@ struct script_data *get_val(struct script_state* st, struct script_data* data) {
char postfix;
struct map_session_data *sd = NULL;
- if( !data_isreference(data) )
+ if (!data_isreference(data))
return data;// not a variable/constant
name = reference_getname(data);
@@ -2840,10 +2856,10 @@ struct script_data *get_val(struct script_state* st, struct script_data* data) {
}
//##TODO use reference_tovariable(data) when it's confirmed that it works [FlavioJS]
- if( !reference_toconstant(data) && not_server_variable(prefix) ) {
+ if (!reference_toconstant(data) && not_server_variable(prefix) && reference_getref(data) == NULL) {
sd = script->rid2sd(st);
- if( sd == NULL ) {// needs player attached
- if( postfix == '$' ) {// string variable
+ if (sd == NULL) {// needs player attached
+ if (postfix == '$') {// string variable
ShowWarning("script_get_val: cannot access player variable '%s', defaulting to \"\"\n", name);
data->type = C_CONSTSTR;
data->u.str = "";
@@ -2861,32 +2877,44 @@ struct script_data *get_val(struct script_state* st, struct script_data* data) {
const char *str = NULL;
switch (prefix) {
- case '@':
+ case '@':
+ if (data->ref) {
+ str = script->get_val_ref_str(st, data->ref, data);
+ } else {
str = pc->readregstr(sd, data->u.num);
- break;
- case '$':
- str = mapreg->readregstr(data->u.num);
- break;
- case '#':
- if (name[1] == '#')
- str = pc_readaccountreg2str(sd, data->u.num);// global
- else
- str = pc_readaccountregstr(sd, data->u.num);// local
- break;
- case '.':
- if (data->ref)
- str = script->get_val_ref_str(st, data->ref, data);
- else if (name[1] == '@')
- str = script->get_val_scope_str(st, &st->stack->scope, data);
- else
- str = script->get_val_npc_str(st, &st->script->local, data);
- break;
- case '\'':
- str = script->get_val_instance_str(st, name, data);
- break;
- default:
+ }
+ break;
+ case '$':
+ str = mapreg->readregstr(data->u.num);
+ break;
+ case '#':
+ if (data->ref) {
+ str = script->get_val_pc_ref_str(st, data->ref, data);
+ } else if (name[1] == '#') {
+ str = pc_readaccountreg2str(sd, data->u.num);// global
+ } else {
+ str = pc_readaccountregstr(sd, data->u.num);// local
+ }
+ break;
+ case '.':
+ if (data->ref) {
+ str = script->get_val_ref_str(st, data->ref, data);
+ } else if (name[1] == '@') {
+ str = script->get_val_scope_str(st, &st->stack->scope, data);
+ } else {
+ str = script->get_val_npc_str(st, &st->script->local, data);
+ }
+ break;
+ case '\'':
+ str = script->get_val_instance_str(st, name, data);
+ break;
+ default:
+ if (data->ref) {
+ str = script->get_val_pc_ref_str(st, data->ref, data);
+ } else {
str = pc_readglobalreg_str(sd, data->u.num);
- break;
+ }
+ break;
}
if (str == NULL || str[0] == '\0') {
@@ -2906,36 +2934,48 @@ struct script_data *get_val(struct script_state* st, struct script_data* data) {
data->u.num = reference_getconstant(data);
} else if( reference_toparam(data) ) {
data->u.num = pc->readparam(sd, reference_getparamtype(data));
- } else
- switch( prefix ) {
- case '@':
+ } else {
+ switch (prefix) {
+ case '@':
+ if (data->ref) {
+ data->u.num = script->get_val_ref_num(st, data->ref, data);
+ } else {
data->u.num = pc->readreg(sd, data->u.num);
- break;
- case '$':
- data->u.num = mapreg->readreg(data->u.num);
- break;
- case '#':
- if( name[1] == '#' )
- data->u.num = pc_readaccountreg2(sd, data->u.num);// global
- else
- data->u.num = pc_readaccountreg(sd, data->u.num);// local
- break;
- case '.':
- if (data->ref)
- data->u.num = script->get_val_ref_num(st, data->ref, data);
- else if (name[1] == '@')
- data->u.num = script->get_val_scope_num(st, &st->stack->scope, data);
- else
- data->u.num = script->get_val_npc_num(st, &st->script->local, data);
- break;
- case '\'':
- data->u.num = script->get_val_instance_num(st, name, data);
- break;
- default:
+ }
+ break;
+ case '$':
+ data->u.num = mapreg->readreg(data->u.num);
+ break;
+ case '#':
+ if (data->ref) {
+ data->u.num = script->get_val_pc_ref_num(st, data->ref, data);
+ } else if (name[1] == '#') {
+ data->u.num = pc_readaccountreg2(sd, data->u.num);// global
+ } else {
+ data->u.num = pc_readaccountreg(sd, data->u.num);// local
+ }
+ break;
+ case '.':
+ if (data->ref) {
+ data->u.num = script->get_val_ref_num(st, data->ref, data);
+ } else if (name[1] == '@') {
+ data->u.num = script->get_val_scope_num(st, &st->stack->scope, data);
+ } else {
+ data->u.num = script->get_val_npc_num(st, &st->script->local, data);
+ }
+ break;
+ case '\'':
+ data->u.num = script->get_val_instance_num(st, name, data);
+ break;
+ default:
+ if (data->ref) {
+ data->u.num = script->get_val_pc_ref_num(st, data->ref, data);
+ } else {
data->u.num = pc_readglobalreg(sd, data->u.num);
- break;
+ }
+ break;
}
-
+ }
}
data->ref = NULL;
@@ -3108,38 +3148,43 @@ void script_array_add_member(struct script_array *sa, unsigned int idx) {
**/
struct reg_db *script_array_src(struct script_state *st, struct map_session_data *sd, const char *name, struct reg_db *ref) {
struct reg_db *src = NULL;
-
nullpo_retr(NULL, name);
- switch( name[0] ) {
+
+ switch (name[0]) {
/* from player */
- default: /* char reg */
- case '@':/* temp char reg */
- case '#':/* account reg */
+ default: /* char reg */
+ case '@':/* temp char reg */
+ case '#':/* account reg */
+ if (ref != NULL) {
+ src = ref;
+ } else {
nullpo_retr(NULL, sd);
src = &sd->regs;
- break;
- case '$':/* map reg */
- src = &mapreg->regs;
- break;
- case '.':/* npc/script */
- if (ref != NULL) {
- src = ref;
- } else {
- nullpo_retr(NULL, st);
- src = (name[1] == '@') ? &st->stack->scope : &st->script->local;
- }
- break;
- case '\'':/* instance */
+ }
+ break;
+ case '$':/* map reg */
+ src = &mapreg->regs;
+ break;
+ case '.':/* npc/script */
+ if (ref != NULL) {
+ src = ref;
+ } else {
nullpo_retr(NULL, st);
- if( st->instance_id >= 0 ) {
- src = &instance->list[st->instance_id].regs;
- }
- break;
+ src = (name[1] == '@') ? &st->stack->scope : &st->script->local;
+ }
+ break;
+ case '\'':/* instance */
+ nullpo_retr(NULL, st);
+ if (st->instance_id >= 0) {
+ src = &instance->list[st->instance_id].regs;
+ }
+ break;
}
- if( src ) {
- if( !src->arrays )
+ if (src) {
+ if (!src->arrays) {
src->arrays = idb_alloc(DB_OPT_BASE);
+ }
return src;
}
return NULL;
@@ -3210,6 +3255,99 @@ void set_reg_npcscope_str(struct script_state* st, struct reg_db *n, int64 num,
}
}
+void set_reg_pc_ref_str(struct script_state *st, struct reg_db *n, int64 num, const char *name, const char *str)
+{
+ struct script_reg_str *p = NULL;
+ unsigned int index = script_getvaridx(num);
+
+ nullpo_retv(n);
+
+ if ((p = i64db_get(n->vars, num)) != NULL) {
+ if (str[0]) {
+ if (p->value) {
+ aFree(p->value);
+ } else if (index) {
+ script->array_update(n, num, false);
+ }
+ p->value = aStrdup(str);
+ } else {
+ p->value = NULL;
+ if (index) {
+ script->array_update(n, num, true);
+ }
+ }
+
+ if (!pc->reg_load) {
+ p->flag.update = 1;
+ }
+ } else if (str[0]) {
+ struct DBData prev;
+ if (index) {
+ script->array_update(n, num, false);
+ }
+
+ p = ers_alloc(pc->str_reg_ers, struct script_reg_str);
+ p->value = aStrdup(str);
+
+ if (!pc->reg_load) {
+ p->flag.update = 1;
+ }
+ p->flag.type = 1;
+
+ if(n->vars->put(n->vars, DB->i642key(num), DB->ptr2data(p), &prev)) {
+ p = DB->data2ptr(&prev);
+ if (p->value) {
+ aFree(p->value);
+ }
+ ers_free(pc->str_reg_ers, p);
+ }
+ }
+}
+
+void set_reg_pc_ref_num(struct script_state *st, struct reg_db *n, int64 num, const char *name, int val)
+{
+ struct script_reg_num *p = NULL;
+ unsigned int index = script_getvaridx(num);
+
+ nullpo_retv(n);
+
+ if ((p = i64db_get(n->vars, num)) != NULL) {
+ if (val) {
+ if (!p->value && index) {
+ script->array_update(n, num, false);
+ }
+ p->value = val;
+ } else {
+ p->value = 0;
+ if (index) {
+ script->array_update(n, num, true);
+ }
+ }
+
+ if (!pc->reg_load) {
+ p->flag.update = 1;
+ }
+ } else if (val) {
+ struct DBData prev;
+ if (index) {
+ script->array_update(n, num, false);
+ }
+
+ p = ers_alloc(pc->num_reg_ers, struct script_reg_num);
+ p->value = val;
+
+ if (!pc->reg_load) {
+ p->flag.update = 1;
+ }
+ p->flag.type = 1;
+
+ if(n->vars->put(n->vars, DB->i642key(num), DB->ptr2data(p), &prev)) {
+ p = DB->data2ptr(&prev);
+ ers_free(pc->num_reg_ers, p);
+ }
+ }
+}
+
void set_reg_npcscope_num(struct script_state* st, struct reg_db *n, int64 num, const char* name, int val)
{
if (n) {
@@ -3292,48 +3430,65 @@ int set_reg(struct script_state *st, struct map_session_data *sd, int64 num, con
return 0;
}
- if( is_string_variable(name) ) {// string variable
+ if (is_string_variable(name)) {// string variable
const char *str = (const char*)value;
switch (prefix) {
- case '@':
+ case '@':
+ if (ref) {
+ script->set_reg_ref_str(st, ref, num, name, str);
+ } else {
pc->setregstr(sd, num, str);
- return 1;
- case '$':
- return mapreg->setregstr(num, str);
- case '#':
- return (name[1] == '#') ?
- pc_setaccountreg2str(sd, num, str) :
- pc_setaccountregstr(sd, num, str);
- case '.':
- if (ref)
- script->set_reg_ref_str(st, ref, num, name, str);
- else if (name[1] == '@')
- script->set_reg_scope_str(st, &st->stack->scope, num, name, str);
- else
- script->set_reg_npc_str(st, &st->script->local, num, name, str);
- return 1;
- case '\'':
- set_reg_instance_str(st, num, name, str);
- return 1;
- default:
- return pc_setglobalreg_str(sd, num, str);
+ }
+ return 1;
+ case '$':
+ mapreg->setregstr(num, str);
+ return 1;
+ case '#':
+ if (ref) {
+ script->set_reg_pc_ref_str(st, ref, num, name, str);
+ } else if (name[1] == '#') {
+ pc_setaccountreg2str(sd, num, str);
+ } else {
+ pc_setaccountregstr(sd, num, str);
+ }
+ return 1;
+ case '.':
+ if (ref) {
+ script->set_reg_ref_str(st, ref, num, name, str);
+ } else if (name[1] == '@') {
+ script->set_reg_scope_str(st, &st->stack->scope, num, name, str);
+ } else {
+ script->set_reg_npc_str(st, &st->script->local, num, name, str);
+ }
+ return 1;
+ case '\'':
+ set_reg_instance_str(st, num, name, str);
+ return 1;
+ default:
+ if (ref) {
+ script->set_reg_pc_ref_str(st, ref, num, name, str);
+ } else {
+ pc_setglobalreg_str(sd, num, str);
+ }
+ return 1;
}
} else {// integer variable
// FIXME: This isn't safe, in 32bits systems we're converting a 64bit pointer
// to a 32bit int, this will lead to overflows! [Panikon]
int val = (int)h64BPTRSIZE(value);
- if(script->str_data[script_getvarid(num)].type == C_PARAM) {
- if( pc->setparam(sd, script->str_data[script_getvarid(num)].val, val) == 0 ) {
- if( st != NULL ) {
+ if (script->str_data[script_getvarid(num)].type == C_PARAM) {
+ if (pc->setparam(sd, script->str_data[script_getvarid(num)].val, val) == 0) {
+ if (st != NULL) {
ShowError("script:set_reg: failed to set param '%s' to %d.\n", name, val);
script->reportsrc(st);
// Instead of just stop the script execution we let the character close
// the window if it was open.
st->state = (sd->state.dialog) ? CLOSE : END;
- if( st->state == CLOSE )
+ if(st->state == CLOSE) {
clif->scriptclose(sd, st->oid);
+ }
}
return 0;
}
@@ -3341,28 +3496,44 @@ int set_reg(struct script_state *st, struct map_session_data *sd, int64 num, con
}
switch (prefix) {
- case '@':
+ case '@':
+ if (ref) {
+ script->set_reg_ref_num(st, ref, num, name, val);
+ } else {
pc->setreg(sd, num, val);
- return 1;
- case '$':
- return mapreg->setreg(num, val);
- case '#':
- return (name[1] == '#') ?
- pc_setaccountreg2(sd, num, val) :
- pc_setaccountreg(sd, num, val);
- case '.':
- if (ref)
- script->set_reg_ref_num(st, ref, num, name, val);
- else if (name[1] == '@')
- script->set_reg_scope_num(st, &st->stack->scope, num, name, val);
- else
- script->set_reg_npc_num(st, &st->script->local, num, name, val);
- return 1;
- case '\'':
- set_reg_instance_num(st, num, name, val);
- return 1;
- default:
- return pc_setglobalreg(sd, num, val);
+ }
+ return 1;
+ case '$':
+ mapreg->setreg(num, val);
+ return 1;
+ case '#':
+ if (ref) {
+ script->set_reg_pc_ref_num(st, ref, num, name, val);
+ } else if (name[1] == '#') {
+ pc_setaccountreg2(sd, num, val);
+ } else {
+ pc_setaccountreg(sd, num, val);
+ }
+ return 1;
+ case '.':
+ if (ref) {
+ script->set_reg_ref_num(st, ref, num, name, val);
+ } else if (name[1] == '@') {
+ script->set_reg_scope_num(st, &st->stack->scope, num, name, val);
+ } else {
+ script->set_reg_npc_num(st, &st->script->local, num, name, val);
+ }
+ return 1;
+ case '\'':
+ set_reg_instance_num(st, num, name, val);
+ return 1;
+ default:
+ if (ref) {
+ script->set_reg_pc_ref_num(st, ref, num, name, val);
+ } else {
+ pc_setglobalreg(sd, num, val);
+ }
+ return 1;
}
}
}
@@ -5197,7 +5368,7 @@ int script_load_translation(const char *file, uint8 lang_id)
VECTOR_TRUNCATE(msgstr);
continue;
}
-
+
if (strncasecmp(line, "msgid \"", 7) == 0) {
VECTOR_TRUNCATE(msgid);
for (i = 7; i < len - 2; i++) {
@@ -6610,61 +6781,67 @@ BUILDIN(warpparty)
}
/*==========================================
* Warpguild - [Fredzilla]
- * Syntax: warpguild "mapname",x,y,Guild_ID;
+ * Syntax: warpguild "mapname",x,y,Guild_ID,{"from_mapname"};
*------------------------------------------*/
BUILDIN(warpguild)
{
struct map_session_data *sd = NULL;
- struct map_session_data *pl_sd;
struct guild* g;
- struct s_mapiterator* iter;
int type;
+ int i;
+ int16 map_id = -1;
- const char* str = script_getstr(st,2);
- int x = script_getnum(st,3);
- int y = script_getnum(st,4);
- int gid = script_getnum(st,5);
+ const char *str = script_getstr(st, 2);
+ int x = script_getnum(st, 3);
+ int y = script_getnum(st, 4);
+ int gid = script_getnum(st, 5);
+
+ if (script_hasdata(st, 6)) {
+ map_id = map->mapname2mapid(script_getstr(st, 6));
+ }
g = guild->search(gid);
- if( g == NULL )
+ if (g == NULL)
return true;
- type = ( strcmp(str,"Random")==0 ) ? 0
- : ( strcmp(str,"SavePointAll")==0 ) ? 1
- : ( strcmp(str,"SavePoint")==0 ) ? 2
+ type = (strcmp(str, "Random") == 0) ? 0
+ : (strcmp(str, "SavePointAll") == 0) ? 1
+ : (strcmp(str, "SavePoint") == 0) ? 2
: 3;
- if( type == 2 && ( sd = script->rid2sd(st) ) == NULL )
+ if (type == 2 && (sd = script->rid2sd(st)) == NULL)
{// "SavePoint" uses save point of the currently attached player
return true;
}
- iter = mapit_getallusers();
- for (pl_sd = BL_UCAST(BL_PC, mapit->first(iter)); mapit->exists(iter); pl_sd = BL_UCAST(BL_PC, mapit->next(iter))) {
- if( pl_sd->status.guild_id != gid )
- continue;
+ for (i = 0; i < MAX_GUILD; i++) {
+ if (g->member[i].online && g->member[i].sd != NULL) {
+ struct map_session_data *pl_sd = g->member[i].sd;
- switch( type )
- {
+ if (map_id >= 0 && map_id != pl_sd->bl.m)
+ continue;
+
+ switch (type)
+ {
case 0: // Random
- if(!map->list[pl_sd->bl.m].flag.nowarp)
- pc->randomwarp(pl_sd,CLR_TELEPORT);
+ if (!map->list[pl_sd->bl.m].flag.nowarp)
+ pc->randomwarp(pl_sd, CLR_TELEPORT);
break;
case 1: // SavePointAll
- if(!map->list[pl_sd->bl.m].flag.noreturn)
- pc->setpos(pl_sd,pl_sd->status.save_point.map,pl_sd->status.save_point.x,pl_sd->status.save_point.y,CLR_TELEPORT);
+ if (!map->list[pl_sd->bl.m].flag.noreturn)
+ pc->setpos(pl_sd, pl_sd->status.save_point.map, pl_sd->status.save_point.x, pl_sd->status.save_point.y, CLR_TELEPORT);
break;
case 2: // SavePoint
- if(!map->list[pl_sd->bl.m].flag.noreturn)
- pc->setpos(pl_sd,sd->status.save_point.map,sd->status.save_point.x,sd->status.save_point.y,CLR_TELEPORT);
+ if (!map->list[pl_sd->bl.m].flag.noreturn)
+ pc->setpos(pl_sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, CLR_TELEPORT);
break;
case 3: // m,x,y
- if(!map->list[pl_sd->bl.m].flag.noreturn && !map->list[pl_sd->bl.m].flag.nowarp)
- pc->setpos(pl_sd,script->mapindexname2id(st,str),x,y,CLR_TELEPORT);
+ if (!map->list[pl_sd->bl.m].flag.noreturn && !map->list[pl_sd->bl.m].flag.nowarp)
+ pc->setpos(pl_sd, script->mapindexname2id(st, str), x, y, CLR_TELEPORT);
break;
+ }
}
}
- mapit->free(iter);
return true;
}
@@ -8685,39 +8862,48 @@ BUILDIN(getguildmember)
*------------------------------------------*/
BUILDIN(strcharinfo)
{
- int num;
struct guild* g;
struct party_data* p;
- struct map_session_data *sd = script->rid2sd(st);
- if (sd == NULL) //Avoid crashing....
+ struct map_session_data *sd;
+
+ if (script_hasdata(st, 4))
+ sd = map->id2sd(script_getnum(st, 4));
+ else
+ sd = script->rid2sd(st);
+
+ if (sd == NULL) {
+ if(script_hasdata(st, 3)) {
+ script_pushcopy(st, 3);
+ } else {
+ script_pushconststr(st, "");
+ }
return true;
+ }
- num=script_getnum(st,2);
- switch(num) {
- case 0:
- script_pushstrcopy(st,sd->status.name);
- break;
- case 1:
- if( ( p = party->search(sd->status.party_id) ) != NULL ) {
- script_pushstrcopy(st,p->party.name);
- } else {
- script_pushconststr(st,"");
- }
- break;
- case 2:
- if( ( g = sd->guild ) != NULL ) {
- script_pushstrcopy(st,g->name);
- } else {
- script_pushconststr(st,"");
- }
- break;
- case 3:
- script_pushconststr(st,map->list[sd->bl.m].name);
- break;
- default:
- ShowWarning("buildin_strcharinfo: unknown parameter.\n");
- script_pushconststr(st,"");
- break;
+ switch (script_getnum(st, 2)) {
+ case 0:
+ script_pushstrcopy(st, sd->status.name);
+ break;
+ case 1:
+ if ((p = party->search(sd->status.party_id)) != NULL) {
+ script_pushstrcopy(st, p->party.name);
+ } else {
+ script_pushconststr(st, "");
+ }
+ break;
+ case 2:
+ if ((g = sd->guild) != NULL) {
+ script_pushstrcopy(st, g->name);
+ } else {
+ script_pushconststr(st, "");
+ }
+ break;
+ case 3:
+ script_pushconststr(st, map->list[sd->bl.m].name);
+ break;
+ default:
+ ShowWarning("script:strcharinfo: unknown parameter.\n");
+ script_pushconststr(st, "");
}
return true;
@@ -8734,41 +8920,51 @@ BUILDIN(strcharinfo)
*------------------------------------------*/
BUILDIN(strnpcinfo)
{
- int num;
char *buf,*name=NULL;
- struct npc_data *nd = map->id2nd(st->oid);
+ struct npc_data *nd;
+
+ if (script_hasdata(st, 4))
+ nd = map->id2nd(script_getnum(st, 4));
+ else
+ nd = map->id2nd(st->oid);
+
if (nd == NULL) {
- script_pushconststr(st, "");
+ if (script_hasdata(st, 3)) {
+ script_pushcopy(st, 3);
+ } else {
+ script_pushconststr(st, "");
+ }
return true;
}
- num = script_getnum(st,2);
- switch(num) {
- case 0: // display name
+ switch (script_getnum(st,2)) {
+ case 0: // display name
+ name = aStrdup(nd->name);
+ break;
+ case 1: // visible part of display name
+ if ((buf = strchr(nd->name,'#')) != NULL) {
name = aStrdup(nd->name);
- break;
- case 1: // visible part of display name
- if((buf = strchr(nd->name,'#')) != NULL)
- {
- name = aStrdup(nd->name);
- name[buf - nd->name] = 0;
- } else // Return the name, there is no '#' present
- name = aStrdup(nd->name);
- break;
- case 2: // # fragment
- if((buf = strchr(nd->name,'#')) != NULL)
- name = aStrdup(buf+1);
- break;
- case 3: // unique name
- name = aStrdup(nd->exname);
- break;
- case 4: // map name
- if( nd->bl.m >= 0 ) // Only valid map indexes allowed (issue:8034)
- name = aStrdup(map->list[nd->bl.m].name);
- break;
+ name[buf - nd->name] = 0;
+ } else { // Return the name, there is no '#' present
+ name = aStrdup(nd->name);
+ }
+ break;
+ case 2: // # fragment
+ if ((buf = strchr(nd->name,'#')) != NULL) {
+ name = aStrdup(buf+1);
+ }
+ break;
+ case 3: // unique name
+ name = aStrdup(nd->exname);
+ break;
+ case 4: // map name
+ if (nd->bl.m >= 0) { // Only valid map indexes allowed (issue:8034)
+ name = aStrdup(map->list[nd->bl.m].name);
+ }
+ break;
}
- if(name)
+ if (name)
script_pushstr(st, name);
else
script_pushconststr(st, "");
@@ -9019,6 +9215,35 @@ BUILDIN(getequipisenableref)
return true;
}
+/**
+ * Checks if the equipped item allows options.
+ * *getequipisenableopt(<equipment_index>);
+ *
+ * @param equipment_index as the inventory index of the equipment.
+ * @return 1 on enabled 0 on disabled.
+ */
+BUILDIN(getequipisenableopt)
+{
+ int i = -1, index = script_getnum(st, 2);
+ struct map_session_data *sd = script->rid2sd(st);
+
+ if (sd == NULL) {
+ script_pushint(st, -1);
+ ShowError("buildin_getequipisenableopt: player is not attached!");
+ return false;
+ }
+
+ if (index > 0 && index <= ARRAYLENGTH(script->equip))
+ i = pc->checkequip(sd, script->equip[index - 1]);
+
+ if (i >=0 && sd->inventory_data[i] && !sd->inventory_data[i]->flag.no_options && !sd->status.inventory[i].expire_time)
+ script_pushint(st, 1);
+ else
+ script_pushint(st, 0);
+
+ return true;
+}
+
/*==========================================
* Chk if the item equiped at pos is identify (huh ?)
* return (npc)
@@ -10704,19 +10929,29 @@ BUILDIN(donpcevent)
*------------------------------------------*/
BUILDIN(addtimer)
{
- int tick = script_getnum(st,2);
+ int tick = script_getnum(st, 2);
const char* event = script_getstr(st, 3);
struct map_session_data *sd;
script->check_event(st, event);
- sd = script->rid2sd(st);
- if( sd == NULL )
- return true;
- if (!pc->addeventtimer(sd,tick,event)) {
- ShowWarning("buildin_addtimer: Event timer is full, can't add new event timer. (cid:%d timer:%s)\n",sd->status.char_id,event);
+ if (script_hasdata(st, 4))
+ sd = map->id2sd(script_getnum(st, 4));
+ else
+ sd = script->rid2sd(st);
+
+ if (sd == NULL) {
+ script_pushint(st, 0);
+ return false;
+ }
+
+ if (!pc->addeventtimer(sd, tick, event)) {
+ ShowWarning("script:addtimer: Event timer is full, can't add new event timer. (cid:%d timer:%s)\n", sd->status.char_id, event);
+ script_pushint(st, 0);
return false;
}
+
+ script_pushint(st, 1);
return true;
}
/*==========================================
@@ -10727,12 +10962,17 @@ BUILDIN(deltimer)
struct map_session_data *sd;
event=script_getstr(st, 2);
- sd = script->rid2sd(st);
- if( sd == NULL )
+
+ if (script_hasdata(st, 3))
+ sd = map->id2sd(script_getnum(st, 3));
+ else
+ sd = script->rid2sd(st);
+
+ if (sd == NULL)
return true;
script->check_event(st, event);
- pc->deleventtimer(sd,event);
+ pc->deleventtimer(sd, event);
return true;
}
/*==========================================
@@ -10743,14 +10983,198 @@ BUILDIN(addtimercount)
int tick;
struct map_session_data *sd;
- event=script_getstr(st, 2);
- tick=script_getnum(st,3);
- sd = script->rid2sd(st);
- if( sd == NULL )
+ event = script_getstr(st, 2);
+ tick = script_getnum(st, 3);
+
+ if (script_hasdata(st, 4))
+ sd = map->id2sd(script_getnum(st, 4));
+ else
+ sd = script->rid2sd(st);
+
+ if (sd == NULL)
return true;
script->check_event(st, event);
- pc->addeventtimercount(sd,event,tick);
+ pc->addeventtimercount(sd, event, tick);
+ return true;
+}
+
+enum gettimer_mode {
+ GETTIMER_COUNT = 0,
+ GETTIMER_TICK_NEXT = 1,
+ GETTIMER_TICK_LAST = 2,
+};
+
+BUILDIN(gettimer)
+{
+ struct map_session_data *sd;
+ const struct TimerData *td;
+ int i;
+ int tick;
+ const char *event = NULL;
+ int val = 0;
+ bool first = true;
+ short mode = script_getnum(st, 2);
+
+ if (script_hasdata(st, 3))
+ sd = map->id2sd(script_getnum(st, 3));
+ else
+ sd = script->rid2sd(st);
+
+ if (script_hasdata(st, 4)) {
+ event = script_getstr(st, 4);
+ script->check_event(st, event);
+ }
+
+ if (sd == NULL) {
+ script_pushint(st, -1);
+ return true;
+ }
+
+ switch (mode) {
+ case GETTIMER_COUNT:
+ // get number of timers
+ for (i = 0; i < MAX_EVENTTIMER; i++) {
+ if (sd->eventtimer[i] != INVALID_TIMER) {
+ if (event != NULL) {
+ td = timer->get(sd->eventtimer[i]);
+ Assert_retr(false, td != NULL);
+
+ if (strcmp((char *)(td->data), event) == 0) {
+ val++;
+ }
+ } else {
+ val++;
+ }
+ }
+ }
+ break;
+ case GETTIMER_TICK_NEXT:
+ // get the number of tick before the next timer runs
+ for (i = 0; i < MAX_EVENTTIMER; i++) {
+ if (sd->eventtimer[i] != INVALID_TIMER) {
+ td = timer->get(sd->eventtimer[i]);
+ Assert_retr(false, td != NULL);
+ tick = max(0, DIFF_TICK32(td->tick, timer->gettick()));
+
+ if (event != NULL) {
+ if ((first == true || tick < val) && strcmp((char *)(td->data), event) == 0) {
+ val = tick;
+ first = false;
+ }
+ } else if (first == true || tick < val) {
+ val = tick;
+ first = false;
+ }
+ }
+ }
+ break;
+ case GETTIMER_TICK_LAST:
+ // get the number of ticks before the last timer runs
+ for (i = MAX_EVENTTIMER - 1; i >= 0; i--) {
+ if (sd->eventtimer[i] != INVALID_TIMER) {
+ td = timer->get(sd->eventtimer[i]);
+ Assert_retr(false, td != NULL);
+ tick = max(0, DIFF_TICK32(td->tick, timer->gettick()));
+
+ if (event != NULL) {
+ if (strcmp((char *)(td->data), event) == 0) {
+ val = max(val, tick);
+ }
+ } else {
+ val = max(val, tick);
+ }
+ }
+ }
+ break;
+ }
+
+ script_pushint(st, val);
+ return true;
+}
+
+int buildin_getunits_sub(struct block_list *bl, va_list ap)
+{
+ struct script_state *st = va_arg(ap, struct script_state *);
+ struct map_session_data *sd = va_arg(ap, struct map_session_data *);
+ int32 id = va_arg(ap, int32);
+ uint32 start = va_arg(ap, uint32);
+ uint32 *count = va_arg(ap, uint32 *);
+ uint32 limit = va_arg(ap, uint32);
+ const char *name = va_arg(ap, const char *);
+ struct reg_db *ref = va_arg(ap, struct reg_db *);
+ uint32 index = start + *count;
+
+ if (index >= SCRIPT_MAX_ARRAYSIZE || *count > limit) {
+ return 1;
+ }
+
+ script->set_reg(st, sd, reference_uid(id, index), name,
+ (const void *)h64BPTRSIZE(bl->id), ref);
+
+ (*count)++;
+ return 0;
+}
+
+BUILDIN(getunits)
+{
+ const char *mapname, *name;
+ int16 m, x1, y1, x2, y2;
+ int32 id;
+ uint32 start;
+ struct reg_db *ref;
+ enum bl_type type = script_getnum(st, 2);
+ struct script_data *data = script_getdata(st, 3);
+ uint32 count = 0, limit = script_getnum(st, 4);
+ struct map_session_data *sd = NULL;
+
+ if (!data_isreference(data) || reference_toconstant(data)) {
+ ShowError("script:getunits: second argument must be a variable\n");
+ script->reportdata(data);
+ st->state = END;
+ return false;
+ }
+
+ id = reference_getid(data);
+ start = reference_getindex(data);
+ name = reference_getname(data);
+ ref = reference_getref(data);
+
+ if (not_server_variable(*name)) {
+ sd = script->rid2sd(st);
+ if (sd == NULL) {
+ return true; // player variable but no player attached
+ }
+ }
+
+ if (is_string_variable(name)) {
+ ShowError("script:getunits: second argument must be an integer variable\n");
+ script->reportdata(data);
+ st->state = END;
+ return false;
+ }
+
+ if (limit < 1 || limit > SCRIPT_MAX_ARRAYSIZE) {
+ limit = SCRIPT_MAX_ARRAYSIZE;
+ }
+
+ mapname = script_getstr(st, 5);
+ m = map->mapname2mapid(mapname);
+
+ if (script_hasdata(st, 9)) {
+ x1 = script_getnum(st, 6);
+ y1 = script_getnum(st, 7);
+ x2 = script_getnum(st, 8);
+ y2 = script_getnum(st, 9);
+
+ map->foreachinarea(buildin_getunits_sub, m, x1, y1, x2, y2, type,
+ st, sd, id, start, &count, limit, name, ref);
+ } else {
+ map->foreachinmap(buildin_getunits_sub, m, type,
+ st, sd, id, start, &count, limit, name, ref);
+ }
+
+ script_pushint(st, count);
return true;
}
@@ -11591,14 +12015,16 @@ BUILDIN(getstatus)
case 3: script_pushint(st, sd->sc.data[id]->val3); break;
case 4: script_pushint(st, sd->sc.data[id]->val4); break;
case 5:
- {
- const struct TimerData *td = timer->get(sd->sc.data[id]->timer);
+ if (sd->sc.data[id]->infinite_duration) {
+ script_pushint(st, INFINITE_DURATION);
+ } else {
+ const struct TimerData *td = timer->get(sd->sc.data[id]->timer);
- if (td != NULL) {
- // return the amount of time remaining
- script_pushint(st, (int)(td->tick - timer->gettick())); // TODO: change this to int64 when we'll support 64 bit script values
+ if (td != NULL) {
+ // return the amount of time remaining
+ script_pushint(st, (int)(td->tick - timer->gettick())); // TODO: change this to int64 when we'll support 64 bit script values
+ }
}
- }
break;
default: script_pushint(st, 1); break;
}
@@ -13546,6 +13972,190 @@ BUILDIN(getiteminfo)
return true;
}
+/**
+ * Returns the value of the current equipment being parsed using static variables -
+ * current_equip_item_index and current_equip_option_index.
+ * !!Designed to be used with item_options.conf only!!
+ * *getequippedoptioninfo(<info_type>);
+ *
+ * @param (int) Types -
+ * IT_OPT_INDEX ID of the item option.
+ * IT_OPT_VALUE Amount of the bonus to be added.
+ * @return value of the type or -1.
+ */
+BUILDIN(getequippedoptioninfo)
+{
+ int val = 0, type = script_getnum(st, 2);
+ struct map_session_data *sd = NULL;
+
+ if ((sd = script->rid2sd(st)) == NULL || status->current_equip_item_index == -1 || status->current_equip_option_index == -1
+ || !sd->status.inventory[status->current_equip_item_index].option[status->current_equip_option_index].index) {
+ script_pushint(st, -1);
+ return false;
+ }
+
+ switch (type) {
+ case IT_OPT_INDEX:
+ val = sd->status.inventory[status->current_equip_item_index].option[status->current_equip_option_index].index;
+ break;
+ case IT_OPT_VALUE:
+ val = sd->status.inventory[status->current_equip_item_index].option[status->current_equip_option_index].value;
+ break;
+ default:
+ ShowError("buildin_getequippedoptioninfo: Invalid option data type %d (Max %d).\n", type, IT_OPT_MAX-1);
+ script_pushint(st, -1);
+ return false;
+ }
+
+ script_pushint(st, val);
+
+ return true;
+}
+
+/**
+ * Gets the option information of an equipment.
+ * *getequipoptioninfo(<equip_index>,<slot>,<type>);
+ *
+ * @param equip_index as the Index of the Equipment.
+ * @param slot as the slot# of the Item Option (1 to MAX_ITEM_OPTIONS)
+ * @param type IT_OPT_INDEX or IT_OPT_VALUE.
+ * @return (int) value or -1 on failure.
+ */
+BUILDIN(getequipoption)
+{
+ int val = 0, equip_index = script_getnum(st, 2);
+ int slot = script_getnum(st, 3);
+ int opt_type = script_getnum(st, 4);
+ int i = -1;
+ struct map_session_data *sd = script->rid2sd(st);
+
+ if (sd == NULL) {
+ script_pushint(st, -1);
+ ShowError("buildin_getequipoptioninfo: Player not attached!\n");
+ return false;
+ }
+
+ if (slot <= 0 || slot > MAX_ITEM_OPTIONS) {
+ script_pushint(st, -1);
+ ShowError("buildin_getequipoptioninfo: Invalid option slot %d (Min: 1, Max: %d) provided.\n", slot, MAX_ITEM_OPTIONS);
+ return false;
+ }
+
+ if (equip_index > 0 && equip_index <= ARRAYLENGTH(script->equip)) {
+ if ((i = pc->checkequip(sd, script->equip[equip_index - 1])) == -1) {
+ ShowError("buildin_getequipoptioninfo: No equipment is equipped in the given index %d.\n", equip_index);
+ script_pushint(st, -1);
+ return false;
+ }
+ } else {
+ ShowError("buildin_getequipoptioninfo: Invalid equipment index %d provided.\n", equip_index);
+ script_pushint(st, 0);
+ return false;
+ }
+
+ if (sd->status.inventory[i].nameid != 0) {
+ switch (opt_type) {
+ case IT_OPT_INDEX:
+ val = sd->status.inventory[i].option[slot-1].index;
+ break;
+ case IT_OPT_VALUE:
+ val = sd->status.inventory[i].option[slot-1].value;
+ break;
+ default:
+ ShowError("buildin_geteqiupoptioninfo: Invalid option data type %d provided.\n", opt_type);
+ script_pushint(st, -1);
+ break;
+ }
+ }
+
+ script_pushint(st, val);
+
+ return true;
+}
+
+/**
+ * Set an equipment's option value.
+ * *setequipoption(<equip_index>,<slot>,<opt_index>,<value>);
+ *
+ * @param equip_index as the inventory index of the equipment.
+ * @param slot as the slot of the item option (1 to MAX_ITEM_OPTIONS)
+ * @param opt_index as the index of the option available as "Id" in db/item_options.conf.
+ * @param value as the value of the option type.
+ * For IT_OPT_INDEX see "Name" in item_options.conf
+ * For IT_OPT_VALUE, the value of the script bonus.
+ * @return 0 on failure, 1 on success.
+ */
+BUILDIN(setequipoption)
+{
+ int equip_index = script_getnum(st, 2);
+ int slot = script_getnum(st, 3);
+ int opt_index = script_getnum(st, 4);
+ int value = script_getnum(st, 5);
+ int i = -1;
+
+ struct map_session_data *sd = script->rid2sd(st);
+ struct item_option *ito = NULL;
+
+ if (sd == NULL) {
+ script_pushint(st, 0);
+ ShowError("buildin_setequipoption: Player not attached!\n");
+ return false;
+ }
+
+ if (slot <= 0 || slot > MAX_ITEM_OPTIONS) {
+ script_pushint(st, 0);
+ ShowError("buildin_setequipoption: Invalid option index %d (Min: 1, Max: %d) provided.\n", slot, MAX_ITEM_OPTIONS);
+ return false;
+ }
+
+ if (equip_index > 0 && equip_index <= ARRAYLENGTH(script->equip)) {
+ if ((i = pc->checkequip(sd, script->equip[equip_index - 1])) == -1) {
+ ShowError("buildin_setequipoptioninfo: No equipment is equipped in the given index %d.\n", equip_index);
+ script_pushint(st, 0);
+ return false;
+ }
+ } else {
+ ShowError("buildin_setequipoptioninfo: Invalid equipment index %d provided.\n", equip_index);
+ script_pushint(st, 0);
+ return false;
+ }
+
+ if (sd->status.inventory[i].nameid != 0) {
+
+ if ((ito = itemdb->option_exists(opt_index)) == NULL) {
+ script_pushint(st, 0);
+ ShowError("buildin_setequipotion: Option index %d does not exist!\n", opt_index);
+ return false;
+ } else if (value < -INT16_MAX || value > INT16_MAX) {
+ script_pushint(st, 0);
+ ShowError("buildin_setequipotion: Option value %d exceeds maximum limit (%d to %d) for type!\n", value, -INT16_MAX, INT16_MAX);
+ return false;
+ }
+ /* Add Option Index */
+ sd->status.inventory[i].option[slot-1].index = ito->index;
+ /* Add Option Value */
+ sd->status.inventory[i].option[slot-1].value = value;
+
+ /* Unequip and simulate deletion of the item. */
+ pc->unequipitem(sd, i, PCUNEQUIPITEM_FORCE); // status calc will happen in pc->equipitem() below
+ clif->refine(sd->fd, 0, i, sd->status.inventory[i].refine); // notify client of a refine.
+ clif->delitem(sd, i, 1, DELITEM_MATERIALCHANGE); // notify client to simulate item deletion.
+ /* Log deletion of the item. */
+ logs->pick_pc(sd, LOG_TYPE_SCRIPT, -1, &sd->status.inventory[i],sd->inventory_data[i]);
+ /* Equip and simulate addition of the item. */
+ clif->additem(sd, i, 1, 0); // notify client to simulate item addition.
+ /* Log addition of the item. */
+ logs->pick_pc(sd, LOG_TYPE_SCRIPT, 1, &sd->status.inventory[i], sd->inventory_data[i]);
+ pc->equipitem(sd, i, sd->status.inventory[i].equip); // force equip the item at the original position.
+ clif->misceffect(&sd->bl, 2); // show effect
+ }
+
+ script_pushint(st, 1);
+
+ return true;
+
+}
+
/*==========================================
* Set some values of an item [Lupus]
* Price, Weight, etc...
@@ -13706,7 +14316,7 @@ BUILDIN(petloot)
BUILDIN(getinventorylist)
{
struct map_session_data *sd = script->rid2sd(st);
- char card_var[NAME_LENGTH];
+ char card_var[SCRIPT_VARNAME_LENGTH];
int i,j=0,k;
if(!sd) return true;
@@ -13727,6 +14337,14 @@ BUILDIN(getinventorylist)
sprintf(card_var, "@inventorylist_card%d",k+1);
pc->setreg(sd,reference_uid(script->add_str(card_var), j),sd->status.inventory[i].card[k]);
}
+ for (k = 0; k < MAX_ITEM_OPTIONS; k++) {
+ sprintf(card_var, "@inventorylist_opt_id%d", k + 1);
+ pc->setreg(sd, reference_uid(script->add_str(card_var), j), sd->status.inventory[i].option[k].index);
+ sprintf(card_var, "@inventorylist_opt_val%d", k + 1);
+ pc->setreg(sd, reference_uid(script->add_str(card_var), j), sd->status.inventory[i].option[k].value);
+ sprintf(card_var, "@inventorylist_opt_param%d", k + 1);
+ pc->setreg(sd, reference_uid(script->add_str(card_var), j), sd->status.inventory[i].option[k].param);
+ }
pc->setreg(sd,reference_uid(script->add_str("@inventorylist_expire"), j),sd->status.inventory[i].expire_time);
pc->setreg(sd,reference_uid(script->add_str("@inventorylist_bound"), j),sd->status.inventory[i].bound);
j++;
@@ -13739,7 +14357,7 @@ BUILDIN(getinventorylist)
BUILDIN(getcartinventorylist)
{
struct map_session_data *sd = script->rid2sd(st);
- char card_var[26];
+ char card_var[SCRIPT_VARNAME_LENGTH];
int i,j=0,k;
if(!sd) return true;
@@ -13756,6 +14374,14 @@ BUILDIN(getcartinventorylist)
sprintf(card_var, "@cartinventorylist_card%d",k+1);
pc->setreg(sd,reference_uid(script->add_str(card_var), j),sd->status.cart[i].card[k]);
}
+ for (k = 0; k < MAX_ITEM_OPTIONS; k++) {
+ sprintf(card_var, "@cartinventorylist_opt_id%d", k + 1);
+ pc->setreg(sd, reference_uid(script->add_str(card_var), j), sd->status.cart[i].option[k].index);
+ sprintf(card_var, "@cartinventorylist_opt_val%d", k + 1);
+ pc->setreg(sd, reference_uid(script->add_str(card_var), j), sd->status.cart[i].option[k].value);
+ sprintf(card_var, "@cartinventorylist_opt_param%d", k + 1);
+ pc->setreg(sd, reference_uid(script->add_str(card_var), j), sd->status.cart[i].option[k].param);
+ }
pc->setreg(sd,reference_uid(script->add_str("@cartinventorylist_expire"), j),sd->status.cart[i].expire_time);
pc->setreg(sd,reference_uid(script->add_str("@cartinventorylist_bound"), j),sd->status.cart[i].bound);
j++;
@@ -13840,15 +14466,26 @@ BUILDIN(undisguise)
* Transform a bl to another class,
* @type unused
*------------------------------------------*/
-BUILDIN(classchange) {
- int class, type;
- struct block_list *bl=map->id2bl(st->oid);
+BUILDIN(classchange)
+{
+ int class, type, target;
+ struct block_list *bl = map->id2bl(st->oid);
+
+ if (bl == NULL)
+ return true;
- if(bl==NULL) return true;
+ class = script_getnum(st, 2);
+ type = script_getnum(st, 3);
+ target = script_hasdata(st, 4) ? script_getnum(st, 4) : 0;
- class = script_getnum(st,2);
- type=script_getnum(st,3);
- clif->class_change(bl, class, type);
+ if (target > 0) {
+ struct map_session_data *sd = script->charid2sd(st, target);
+ if (sd != NULL) {
+ clif->class_change(bl, class, type, sd);
+ }
+ } else {
+ clif->class_change(bl, class, type, NULL);
+ }
return true;
}
@@ -15455,6 +16092,29 @@ BUILDIN(charat) {
}
//=======================================================
+// chr <int>
+//-------------------------------------------------------
+BUILDIN(chr)
+{
+ char output[2];
+ output[0] = script_getnum(st, 2);
+ output[1] = '\0';
+
+ script_pushstrcopy(st, output);
+ return true;
+}
+
+//=======================================================
+// ord <chr>
+//-------------------------------------------------------
+BUILDIN(ord)
+{
+ const char *chr = script_getstr(st, 2);
+ script_pushint(st, *chr);
+ return true;
+}
+
+//=======================================================
// setchar <string>, <char>, <index>
//-------------------------------------------------------
BUILDIN(setchar)
@@ -17084,6 +17744,1601 @@ BUILDIN(getunittype) {
return true;
}
+/**
+ * Sets real-time unit data for a game object.
+ * Setunitdata <GUID>,<DataType>,<Val1>{,<Val2>,<Val3>}
+ * @param1 GUID GID of the unit.
+ * @param2 DataType Type of Data to be set for the unit.
+ * @param3 Value#1 Value to be passed as change in data.
+ * @param4 Value#2 Optional int value to be passed for certain data types.
+ * @param5 Value#3 Optional int value to be passed for certain data types.
+ * @return 1 on success, 0 on failure.
+ */
+BUILDIN(setunitdata)
+{
+ struct block_list *bl = NULL;
+ const char *mapname = NULL, *udtype = NULL;
+ int type = 0, val = 0, val2 = 0, val3 = 0;
+ struct map_session_data *tsd = NULL;
+
+ bl = map->id2bl(script_getnum(st, 2));
+
+ if (bl == NULL) {
+ ShowWarning("buildin_setunitdata: Error in finding object with given GID %d!\n", script_getnum(st, 2));
+ script_pushint(st, 0);
+ return false;
+ }
+
+ type = script_getnum(st, 3);
+
+ /* type bounds */
+ if (type < UDT_SIZE || type >= UDT_MAX) {
+ ShowError("buildin_setunitdata: Invalid unit data type %d provided.\n", type);
+ script_pushint(st, 0);
+ return false;
+ }
+
+ /* Mandatory Argument 3 */
+ if (type == UDT_MAPIDXY) {
+ if (!script_isstringtype(st, 4)) {
+ ShowError("buildin_setunitdata: Invalid data type for argument #3.\n");
+ script_pushint(st, 0);
+ return false;
+ }
+ mapname = script_getstr(st, 4);
+ } else {
+ if (script_isstringtype(st, 4)) {
+ ShowError("buildin_setunitdata: Invalid data type for argument #3.\n");
+ script_pushint(st, 0);
+ return false;
+ }
+ val = script_getnum(st, 4);
+ }
+/* checks if value is out of bounds. */
+#define setunitdata_check_bounds(arg, min, max) \
+ do { \
+ if (script_getnum(st, arg) < min || script_getnum(st, arg) > max) { \
+ ShowError("buildin_setunitdata: Invalid value %d for argument #%d. (min: %d, max: %d)\n", script_getnum(st, arg), arg-1, min, max); \
+ script_pushint(st, 0); \
+ return false; \
+ } \
+ } while(0);
+/* checks if value is out of bounds. */
+#define setunitdata_check_unsigned(arg, max) \
+ do { \
+ if (script_getnum(st, arg) < 0 || script_getnum(st, arg) > max) { \
+ ShowError("buildin_setunitdata: Invalid value %d for argument #%d. (min: 0, max: %u)\n", script_getnum(st, arg), arg-1, max); \
+ script_pushint(st, 0); \
+ return false; \
+ } \
+ } while(0);
+/* checks if uint64 value is out of bounds. */
+#define setunitdata_check_uint64(arg, min, max) \
+ do { \
+ if (script_getnum(st, arg) < min || script_getnum(st, arg) > max) { \
+ ShowError("buildin_setunitdata: Invalid value %d for argument #%d. (min: %d, max: %"PRIu64")\n", script_getnum(st, arg), arg-1, min, max); \
+ script_pushint(st, 0); \
+ return false; \
+ } \
+ } while(0);
+/* checks if the argument doesn't exist, if required.
+ * also checks if the argument exists, if not required. */
+#define setunitdata_assert_arg(arg, required) \
+ do { \
+ if (required && !script_hasdata(st, arg)) { \
+ ShowError("buildin_setunitdata: Type %d reqires argument #%d.\n", type, arg-1); \
+ script_pushint(st, 0); \
+ return false; \
+ } else if (!required && script_hasdata(st, arg)) { \
+ ShowError("buildin_setunitdata: Argument %d is not required for type %d.\n", arg-1, type); \
+ script_pushint(st, 0); \
+ return false; \
+ } \
+ } while (0);
+/* checks if the data is an integer. */
+#define setunitdata_check_int(arg) \
+ do { \
+ setunitdata_assert_arg(arg, true); \
+ if (script_isstringtype(st, arg)) { \
+ ShowError("buildin_setunitdata: Argument #%d expects integer, string given.\n", arg-1); \
+ script_pushint(st, 0); \
+ return false; \
+ } \
+ } while(0);
+/* checks if the data is a string. */
+#define setunitdata_check_string(arg) \
+ do { \
+ setunitdata_assert_arg(arg, true); \
+ if (script_isinttype(st, arg)) { \
+ ShowError("buildin_setunitdata: Argument #%d expects string, integer given.\n", arg-1); \
+ script_pushint(st, 0); \
+ return false; \
+ } \
+ } while(0);
+
+ if (type != UDT_MAPIDXY && type != UDT_WALKTOXY) {
+ setunitdata_assert_arg(5, false);
+ setunitdata_assert_arg(6, false);
+ }
+
+ switch (type)
+ {
+ case UDT_SIZE:
+ setunitdata_check_bounds(4, SZ_SMALL, SZ_BIG);
+ break;
+ case UDT_LEVEL:
+ case UDT_HP:
+ case UDT_MAXHP:
+ case UDT_SP:
+ case UDT_MAXSP:
+ case UDT_CLASS:
+ case UDT_HEADBOTTOM:
+ case UDT_HEADMIDDLE:
+ case UDT_HEADTOP:
+ case UDT_CLOTHCOLOR:
+ case UDT_SHIELD:
+ case UDT_WEAPON:
+ case UDT_INTIMACY:
+ case UDT_LIFETIME:
+ case UDT_MERC_KILLCOUNT:
+ setunitdata_check_unsigned(4, UINT_MAX);
+ break;
+ case UDT_MASTERAID:
+ setunitdata_check_unsigned(4, UINT_MAX);
+ tsd = map->id2sd(val);
+ if (tsd == NULL) {
+ ShowWarning("buildin_setunitdata: Account ID %d not found for master change!\n",val);
+ script_pushint(st, 0);
+ return false;
+ }
+ break;
+ case UDT_MASTERCID:
+ setunitdata_check_unsigned(4, UINT_MAX);
+ tsd = map->charid2sd((uint32) val);
+ if (tsd == NULL) {
+ ShowWarning("buildin_setunitdata: Character ID %d not found for master change!\n",val);
+ script_pushint(st, 0);
+ return false;
+ }
+ break;
+ case UDT_MAPIDXY:
+ if ((val = map->mapname2mapid(mapname)) == -1) {
+ ShowError("buildin_setunitdata: Non-existent map %s provided.\n", mapname);
+ return false;
+ }
+ setunitdata_check_int(5);
+ setunitdata_check_int(6);
+ setunitdata_check_bounds(5, 0, MAX_MAP_SIZE/2);
+ setunitdata_check_bounds(6, 0, MAX_MAP_SIZE/2);
+ val2 = script_getnum(st, 5);
+ val3 = script_getnum(st, 6);
+ break;
+ case UDT_WALKTOXY:
+ setunitdata_assert_arg(6, false);
+ setunitdata_check_int(5);
+ val2 = script_getnum(st, 5);
+ setunitdata_check_bounds(4, 0, MAX_MAP_SIZE/2);
+ setunitdata_check_bounds(5, 0, MAX_MAP_SIZE/2);
+ break;
+ case UDT_SPEED:
+ setunitdata_check_bounds(4, 0, MAX_WALK_SPEED);
+ break;
+ case UDT_MODE:
+ setunitdata_check_bounds(4, MD_NONE, MD_MASK);
+ break;
+ case UDT_AI:
+ setunitdata_check_bounds(4, AI_NONE, AI_MAX-1);
+ break;
+ case UDT_SCOPTION:
+ setunitdata_check_bounds(4, OPTION_NOTHING, OPTION_COSTUME);
+ break;
+ case UDT_SEX:
+ setunitdata_check_bounds(4, SEX_FEMALE, SEX_MALE);
+ break;
+ case UDT_HAIRSTYLE:
+ setunitdata_check_bounds(4, 0, battle->bc->max_hair_style);
+ break;
+ case UDT_HAIRCOLOR:
+ setunitdata_check_bounds(4, 0, battle->bc->max_hair_color);
+ break;
+ case UDT_LOOKDIR:
+ setunitdata_check_bounds(4, 0, 7);
+ break;
+ case UDT_CANMOVETICK:
+ setunitdata_check_uint64(4, 0, UINT64_MAX);
+ break;
+ case UDT_STR:
+ case UDT_AGI:
+ case UDT_VIT:
+ case UDT_INT:
+ case UDT_DEX:
+ case UDT_LUK:
+ case UDT_STATPOINT:
+ case UDT_ATKRANGE:
+ case UDT_ATKMIN:
+ case UDT_ATKMAX:
+ case UDT_MATKMIN:
+ case UDT_MATKMAX:
+ case UDT_AMOTION:
+ case UDT_ADELAY:
+ case UDT_DMOTION:
+ setunitdata_check_bounds(4, 0, USHRT_MAX);
+ break;
+ case UDT_DEF:
+ case UDT_MDEF:
+ case UDT_HIT:
+ case UDT_FLEE:
+ case UDT_PDODGE:
+ case UDT_CRIT:
+ setunitdata_check_bounds(4, 0, SHRT_MAX);
+ break;
+ case UDT_HUNGER:
+ setunitdata_check_bounds(4, 0, 99);
+ break;
+ case UDT_RACE:
+ case UDT_ELETYPE:
+ case UDT_ELELEVEL:
+ setunitdata_check_bounds(4, 0, CHAR_MAX);
+ break;
+ default:
+ break;
+ }
+
+#undef setunitdata_check_bounds
+#undef setunitdata_check_uint64
+#undef setunitdata_assert_arg
+#undef setunitdata_check_int
+#undef setunitdata_check_string
+
+ /* Set the values */
+ switch (bl->type) {
+ case BL_MOB:
+ {
+ struct mob_data *md = BL_UCAST(BL_MOB, bl);
+ nullpo_retr(false, md);
+
+ switch (type)
+ {
+ case UDT_SIZE:
+ md->status.size = (unsigned char) val;
+ break;
+ case UDT_LEVEL:
+ md->level = val;
+ break;
+ case UDT_HP:
+ status->set_hp(bl, (unsigned int) val, 0);
+ clif->charnameack(0, &md->bl);
+ break;
+ case UDT_MAXHP:
+ md->status.max_hp = (unsigned int) val;
+ clif->charnameack(0, &md->bl);
+ break;
+ case UDT_SP:
+ status->set_sp(bl, (unsigned int) val, 0);
+ break;
+ case UDT_MAXSP:
+ md->status.max_sp = (unsigned int) val;
+ break;
+ case UDT_MASTERAID:
+ md->master_id = val;
+ break;
+ case UDT_MAPIDXY:
+ unit->warp(bl, (short) val, (short) val2, (short) val3, CLR_TELEPORT);
+ break;
+ case UDT_WALKTOXY:
+ if (!unit->walktoxy(bl, (short) val, (short) val2, 2))
+ unit->movepos(bl, (short) val, (short) val2, 0, 0);
+ break;
+ case UDT_SPEED:
+ md->status.speed = (unsigned short) val;
+ status->calc_misc(bl, &md->status, md->level);
+ break;
+ case UDT_MODE:
+ md->status.mode = (enum e_mode) val;
+ break;
+ case UDT_AI:
+ md->special_state.ai = (enum ai) val;
+ break;
+ case UDT_SCOPTION:
+ md->sc.option = (char) val;
+ break;
+ case UDT_SEX:
+ md->vd->sex = (char) val;
+ break;
+ case UDT_CLASS:
+ mob->class_change(md, val);
+ break;
+ case UDT_HAIRSTYLE:
+ clif->changelook(bl, LOOK_HAIR, (unsigned short) val);
+ break;
+ case UDT_HAIRCOLOR:
+ clif->changelook(bl, LOOK_HAIR_COLOR, (unsigned short) val);
+ break;
+ case UDT_HEADBOTTOM:
+ clif->changelook(bl, LOOK_HEAD_BOTTOM, (unsigned short) val);
+ break;
+ case UDT_HEADMIDDLE:
+ clif->changelook(bl, LOOK_HEAD_MID, (unsigned short) val);
+ break;
+ case UDT_HEADTOP:
+ clif->changelook(bl, LOOK_HEAD_TOP, (unsigned short) val);
+ break;
+ case UDT_CLOTHCOLOR:
+ clif->changelook(bl, LOOK_CLOTHES_COLOR, (unsigned short) val);
+ break;
+ case UDT_SHIELD:
+ clif->changelook(bl, LOOK_SHIELD, (unsigned short) val);
+ break;
+ case UDT_WEAPON:
+ clif->changelook(bl, LOOK_WEAPON, (unsigned short) val);
+ break;
+ case UDT_LOOKDIR:
+ unit->setdir(bl, (uint8) val);
+ break;
+ case UDT_CANMOVETICK:
+ md->ud.canmove_tick = (int64) val;
+ break;
+ case UDT_STR:
+ md->status.str = (unsigned short) val;
+ status->calc_misc(bl, &md->status, md->level);
+ break;
+ case UDT_AGI:
+ md->status.agi = (unsigned short) val;
+ status->calc_misc(bl, &md->status, md->level);
+ break;
+ case UDT_VIT:
+ md->status.vit = (unsigned short) val;
+ status->calc_misc(bl, &md->status, md->level);
+ break;
+ case UDT_INT:
+ md->status.int_ = (unsigned short) val;
+ status->calc_misc(bl, &md->status, md->level);
+ break;
+ case UDT_DEX:
+ md->status.dex = (unsigned short) val;
+ status->calc_misc(bl, &md->status, md->level);
+ break;
+ case UDT_LUK:
+ md->status.luk = (unsigned short) val;
+ status->calc_misc(bl, &md->status, md->level);
+ break;
+ case UDT_ATKRANGE:
+ md->status.rhw.range = (unsigned short) val;
+ break;
+ case UDT_ATKMIN:
+ md->status.rhw.atk = (unsigned short) val;
+ break;
+ case UDT_ATKMAX:
+ md->status.rhw.atk2 = (unsigned short) val;
+ break;
+ case UDT_MATKMIN:
+ md->status.matk_min = (unsigned short) val;
+ break;
+ case UDT_MATKMAX:
+ md->status.matk_max = (unsigned short) val;
+ break;
+ case UDT_DEF:
+ md->status.def = (defType) val;
+ break;
+ case UDT_MDEF:
+ md->status.mdef = (defType) val;
+ break;
+ case UDT_HIT:
+ md->status.hit = (short) val;
+ break;
+ case UDT_FLEE:
+ md->status.flee = (short) val;
+ break;
+ case UDT_PDODGE:
+ md->status.flee2 = (short) val;
+ break;
+ case UDT_CRIT:
+ md->status.cri = (short) val;
+ break;
+ case UDT_RACE:
+ md->status.race = (unsigned char) val;
+ break;
+ case UDT_ELETYPE:
+ md->status.def_ele = (unsigned char) val;
+ break;
+ case UDT_ELELEVEL:
+ md->status.ele_lv = (unsigned char) val;
+ break;
+ case UDT_AMOTION:
+ md->status.amotion = (unsigned short) val;
+ break;
+ case UDT_ADELAY:
+ md->status.adelay = (unsigned short) val;
+ break;
+ case UDT_DMOTION:
+ md->status.dmotion = (unsigned short) val;
+ break;
+ default:
+ ShowWarning("buildin_setunitdata: Invalid data type '%s' for mob unit.\n", udtype);
+ script_pushint(st, 0);
+ return false;
+ }
+ }
+ break;
+ case BL_HOM:
+ {
+ struct homun_data *hd = BL_UCAST(BL_HOM, bl);
+
+ nullpo_retr(false, hd);
+
+ switch (type)
+ {
+ case UDT_SIZE:
+ hd->base_status.size = (unsigned char) val;
+ break;
+ case UDT_LEVEL:
+ hd->homunculus.level = (short) val;
+ break;
+ case UDT_HP:
+ status->set_hp(bl, (unsigned int) val, 0);
+ break;
+ case UDT_MAXHP:
+ hd->homunculus.max_hp = val;
+ break;
+ case UDT_SP:
+ status->set_sp(bl, (unsigned int) val, 0);
+ break;
+ case UDT_MAXSP:
+ hd->homunculus.max_sp = val;
+ break;
+ case UDT_MASTERCID:
+ hd->homunculus.char_id = val;
+ hd->master = tsd;
+ break;
+ case UDT_MAPIDXY:
+ unit->warp(bl, (short) val, (short) val2, (short) val3, CLR_TELEPORT);
+ break;
+ case UDT_WALKTOXY:
+ if (!unit->walktoxy(bl, (short) val, (short) val2, 2))
+ unit->movepos(bl, (short) val, (short) val2, 0, 0);
+ break;
+ case UDT_SPEED:
+ hd->base_status.speed = (unsigned short) val;
+ status->calc_misc(bl, &hd->base_status, hd->homunculus.level);
+ break;
+ case UDT_LOOKDIR:
+ unit->setdir(bl, (unsigned char) val);
+ break;
+ case UDT_CANMOVETICK:
+ hd->ud.canmove_tick = (int64) val;
+ break;
+ case UDT_STR:
+ hd->base_status.str = (unsigned short) val;
+ status->calc_misc(bl, &hd->base_status, hd->homunculus.level);
+ break;
+ case UDT_AGI:
+ hd->base_status.agi = (unsigned short) val;
+ status->calc_misc(bl, &hd->base_status, hd->homunculus.level);
+ break;
+ case UDT_VIT:
+ hd->base_status.vit = (unsigned short) val;
+ status->calc_misc(bl, &hd->base_status, hd->homunculus.level);
+ break;
+ case UDT_INT:
+ hd->base_status.int_ = (unsigned short) val;
+ status->calc_misc(bl, &hd->base_status, hd->homunculus.level);
+ break;
+ case UDT_DEX:
+ hd->base_status.dex = (unsigned short) val;
+ status->calc_misc(bl, &hd->base_status, hd->homunculus.level);
+ break;
+ case UDT_LUK:
+ hd->base_status.luk = (unsigned short) val;
+ status->calc_misc(bl, &hd->base_status, hd->homunculus.level);
+ break;
+ case UDT_ATKRANGE:
+ hd->base_status.rhw.range = (unsigned short) val;
+ break;
+ case UDT_ATKMIN:
+ hd->base_status.rhw.atk = (unsigned short) val;
+ break;
+ case UDT_ATKMAX:
+ hd->base_status.rhw.atk2 = (unsigned short) val;
+ break;
+ case UDT_MATKMIN:
+ hd->base_status.matk_min = (unsigned short) val;
+ break;
+ case UDT_MATKMAX:
+ hd->base_status.matk_max = (unsigned short) val;
+ break;
+ case UDT_DEF:
+ hd->base_status.def = (defType) val;
+ break;
+ case UDT_MDEF:
+ hd->base_status.mdef = (defType) val;
+ break;
+ case UDT_HIT:
+ hd->base_status.hit = (short) val;
+ break;
+ case UDT_FLEE:
+ hd->base_status.flee = (short) val;
+ break;
+ case UDT_PDODGE:
+ hd->base_status.flee2 = (short) val;
+ break;
+ case UDT_CRIT:
+ hd->base_status.cri = (short) val;
+ break;
+ case UDT_RACE:
+ hd->base_status.race = (unsigned char) val;
+ break;
+ case UDT_ELETYPE:
+ hd->base_status.def_ele = (unsigned char) val;
+ break;
+ case UDT_ELELEVEL:
+ hd->base_status.ele_lv = (unsigned char) val;
+ break;
+ case UDT_AMOTION:
+ hd->base_status.amotion = (unsigned short) val;
+ break;
+ case UDT_ADELAY:
+ hd->base_status.adelay = (unsigned short) val;
+ break;
+ case UDT_DMOTION:
+ hd->base_status.dmotion = (unsigned short) val;
+ break;
+ case UDT_HUNGER:
+ hd->homunculus.hunger = (short) val;
+ clif->send_homdata(hd->master, SP_HUNGRY, hd->homunculus.hunger);
+ break;
+ case UDT_INTIMACY:
+ homun->add_intimacy(hd, (unsigned int) val);
+ clif->send_homdata(hd->master, SP_INTIMATE, hd->homunculus.intimacy / 100);
+ break;
+ default:
+ ShowWarning("buildin_setunitdata: Invalid data type '%s' for homunculus unit.\n", udtype);
+ script_pushint(st, 0);
+ return false;
+ }
+
+ clif->send_homdata(hd->master, SP_ACK, 0); // send homun data
+ }
+ break;
+ case BL_PET:
+ {
+ struct pet_data *pd = BL_UCAST(BL_PET, bl);
+
+ nullpo_retr(false, pd);
+
+ switch (type)
+ {
+ case UDT_SIZE:
+ pd->status.size = (unsigned char) val;
+ break;
+ case UDT_LEVEL:
+ pd->pet.level = (short) val;
+ break;
+ case UDT_HP:
+ status->set_hp(bl, (unsigned int) val, 0);
+ break;
+ case UDT_MAXHP:
+ pd->status.max_hp = (unsigned int) val;
+ break;
+ case UDT_SP:
+ status->set_sp(bl, (unsigned int) val, 0);
+ break;
+ case UDT_MAXSP:
+ pd->status.max_sp = (unsigned int) val;
+ break;
+ case UDT_MASTERAID:
+ pd->pet.account_id = (int) val;
+ pd->msd = tsd;
+ break;
+ case UDT_MAPIDXY:
+ unit->warp(bl, (short) val, (short) val2, (short) val3, CLR_TELEPORT);
+ break;
+ case UDT_WALKTOXY:
+ if (!unit->walktoxy(bl, (short) val, (short) val2, 2))
+ unit->movepos(bl, (short) val, (short) val2, 0, 0);
+ break;
+ case UDT_SPEED:
+ pd->status.speed = (unsigned short) val;
+ status->calc_misc(bl, &pd->status, pd->pet.level);
+ break;
+ case UDT_LOOKDIR:
+ unit->setdir(bl, (unsigned char) val);
+ break;
+ case UDT_CANMOVETICK:
+ pd->ud.canmove_tick = (int64) val;
+ break;
+ case UDT_STR:
+ pd->status.str = (unsigned short) val;
+ status->calc_misc(bl, &pd->status, pd->pet.level);
+ break;
+ case UDT_AGI:
+ pd->status.agi = (unsigned short) val;
+ status->calc_misc(bl, &pd->status, pd->pet.level);
+ break;
+ case UDT_VIT:
+ pd->status.vit = (unsigned short) val;
+ status->calc_misc(bl, &pd->status, pd->pet.level);
+ break;
+ case UDT_INT:
+ pd->status.int_ = (unsigned short) val;
+ status->calc_misc(bl, &pd->status, pd->pet.level);
+ break;
+ case UDT_DEX:
+ pd->status.dex = (unsigned short) val;
+ status->calc_misc(bl, &pd->status, pd->pet.level);
+ break;
+ case UDT_LUK:
+ pd->status.luk = (unsigned short) val;
+ status->calc_misc(bl, &pd->status, pd->pet.level);
+ break;
+ case UDT_ATKRANGE:
+ pd->status.rhw.range = (unsigned short) val;
+ break;
+ case UDT_ATKMIN:
+ pd->status.rhw.atk = (unsigned short) val;
+ break;
+ case UDT_ATKMAX:
+ pd->status.rhw.atk2 = (unsigned short) val;
+ break;
+ case UDT_MATKMIN:
+ pd->status.matk_min = (unsigned short) val;
+ break;
+ case UDT_MATKMAX:
+ pd->status.matk_max = (unsigned short) val;
+ break;
+ case UDT_DEF:
+ pd->status.def = (defType) val;
+ break;
+ case UDT_MDEF:
+ pd->status.mdef = (defType) val;
+ break;
+ case UDT_HIT:
+ pd->status.hit = (short) val;
+ break;
+ case UDT_FLEE:
+ pd->status.flee = (short) val;
+ break;
+ case UDT_PDODGE:
+ pd->status.flee2 = (short) val;
+ break;
+ case UDT_CRIT:
+ pd->status.cri = (short) val;
+ break;
+ case UDT_RACE:
+ pd->status.race = (unsigned char) val;
+ break;
+ case UDT_ELETYPE:
+ pd->status.def_ele = (unsigned char) val;
+ break;
+ case UDT_ELELEVEL:
+ pd->status.ele_lv = (unsigned char) val;
+ break;
+ case UDT_AMOTION:
+ pd->status.amotion = (unsigned short) val;
+ break;
+ case UDT_ADELAY:
+ pd->status.adelay = (unsigned short) val;
+ break;
+ case UDT_DMOTION:
+ pd->status.dmotion = (unsigned short) val;
+ break;
+ case UDT_INTIMACY:
+ pet->set_intimate(pd, val);
+ clif->send_petdata(pd->msd,pd,1,pd->pet.intimate);
+ break;
+ case UDT_HUNGER: pd->pet.hungry = (short) val;
+ break;
+ default:
+ ShowWarning("buildin_setunitdata: Invalid data type '%s' for pet unit.\n", udtype);
+ script_pushint(st, 0);
+ return false;
+ }
+ clif->send_petstatus(pd->msd); // send pet data
+ }
+ break;
+ case BL_MER:
+ {
+ struct mercenary_data *mc = BL_UCAST(BL_MER, bl);
+
+ nullpo_retr(false, mc);
+
+ switch (type)
+ {
+ case UDT_SIZE:
+ mc->base_status.size = (unsigned char) val;
+ break;
+ case UDT_HP:
+ status->set_hp(bl, (unsigned int) val, 0);
+ break;
+ case UDT_MAXHP:
+ mc->base_status.max_hp = (unsigned int) val;
+ break;
+ case UDT_SP:
+ status->set_sp(bl, (unsigned int) val, 0);
+ break;
+ case UDT_MAXSP:
+ mc->base_status.max_sp = (unsigned int) val;
+ break;
+ case UDT_MASTERCID:
+ mc->mercenary.char_id = (uint32) val;
+ break;
+ case UDT_MAPIDXY:
+ unit->warp(bl, (short) val, (short) val2, (short) val3, CLR_TELEPORT);
+ break;
+ case UDT_WALKTOXY:
+ if (!unit->walktoxy(bl, (short) val, (short) val2, 2))
+ unit->movepos(bl, (short) val, (short) val2, 0, 0);
+ break;
+ case UDT_SPEED:
+ mc->base_status.size = (unsigned char) val;
+ status->calc_misc(bl, &mc->base_status, mc->db->lv);
+ break;
+ case UDT_LOOKDIR:
+ unit->setdir(bl, (unsigned char) val);
+ break;
+ case UDT_CANMOVETICK:
+ mc->ud.canmove_tick = (int64) val;
+ break;
+ case UDT_STR:
+ mc->base_status.str = (unsigned short) val;
+ status->calc_misc(bl, &mc->base_status, mc->db->lv);
+ break;
+ case UDT_AGI:
+ mc->base_status.agi = (unsigned short) val;
+ status->calc_misc(bl, &mc->base_status, mc->db->lv);
+ break;
+ case UDT_VIT:
+ mc->base_status.vit = (unsigned short) val;
+ status->calc_misc(bl, &mc->base_status, mc->db->lv);
+ break;
+ case UDT_INT:
+ mc->base_status.int_ = (unsigned short) val;
+ status->calc_misc(bl, &mc->base_status, mc->db->lv);
+ break;
+ case UDT_DEX:
+ mc->base_status.dex = (unsigned short) val;
+ status->calc_misc(bl, &mc->base_status, mc->db->lv);
+ break;
+ case UDT_LUK:
+ mc->base_status.luk = (unsigned short) val;
+ status->calc_misc(bl, &mc->base_status, mc->db->lv);
+ break;
+ case UDT_ATKRANGE:
+ mc->base_status.rhw.range = (unsigned short) val;
+ break;
+ case UDT_ATKMIN:
+ mc->base_status.rhw.atk = (unsigned short) val;
+ break;
+ case UDT_ATKMAX:
+ mc->base_status.rhw.atk2 = (unsigned short) val;
+ break;
+ case UDT_MATKMIN:
+ mc->base_status.matk_min = (unsigned short) val;
+ break;
+ case UDT_MATKMAX:
+ mc->base_status.matk_max = (unsigned short) val;
+ break;
+ case UDT_DEF:
+ mc->base_status.def = (defType) val;
+ break;
+ case UDT_MDEF:
+ mc->base_status.mdef = (defType) val;
+ break;
+ case UDT_HIT:
+ mc->base_status.hit = (short) val;
+ break;
+ case UDT_FLEE:
+ mc->base_status.flee = (short) val;
+ break;
+ case UDT_PDODGE:
+ mc->base_status.flee2 = (short) val;
+ break;
+ case UDT_CRIT:
+ mc->base_status.cri = (short) val;
+ break;
+ case UDT_RACE:
+ mc->base_status.race = (unsigned char) val;
+ break;
+ case UDT_ELETYPE:
+ mc->base_status.def_ele = (unsigned char) val;
+ break;
+ case UDT_ELELEVEL:
+ mc->base_status.ele_lv = (unsigned char) val;
+ break;
+ case UDT_AMOTION:
+ mc->base_status.amotion = (unsigned short) val;
+ break;
+ case UDT_ADELAY:
+ mc->base_status.adelay = (unsigned short) val;
+ break;
+ case UDT_DMOTION:
+ mc->base_status.dmotion = (unsigned short) val;
+ break;
+ case UDT_MERC_KILLCOUNT:
+ mc->mercenary.kill_count = (unsigned int) val;
+ break;
+ case UDT_LIFETIME:
+ mc->mercenary.life_time = (unsigned int) val;
+ break;
+ default:
+ ShowWarning("buildin_setunitdata: Invalid data type '%s' for mercenary unit.\n", udtype);
+ script_pushint(st, 0);
+ return false;
+ }
+
+ clif->mercenary_info(map->charid2sd(mc->mercenary.char_id));
+ clif->mercenary_skillblock(map->charid2sd(mc->mercenary.char_id));
+ }
+ break;
+ case BL_ELEM:
+ {
+ struct elemental_data *ed = BL_UCAST(BL_ELEM, bl);
+
+ nullpo_retr(false, ed);
+
+ switch (type)
+ {
+ case UDT_SIZE:
+ ed->base_status.size = (unsigned char) val;
+ break;
+ case UDT_HP:
+ status->set_hp(bl, (unsigned int) val, 0);
+ break;
+ case UDT_MAXHP:
+ ed->base_status.max_hp = (unsigned int) val;
+ break;
+ case UDT_SP:
+ status->set_sp(bl, (unsigned int) val, 0);
+ break;
+ case UDT_MAXSP:
+ ed->base_status.max_sp = (unsigned int) val;
+ break;
+ case UDT_MASTERCID:
+ ed->elemental.char_id = val;
+ break;
+ case UDT_MAPIDXY:
+ unit->warp(bl, (short) val, (short) val2, (short) val3, CLR_TELEPORT);
+ break;
+ case UDT_WALKTOXY:
+ if (!unit->walktoxy(bl, (short) val, (short) val2, 2))
+ unit->movepos(bl, (short) val, (short) val2, 0, 0);
+ break;
+ case UDT_SPEED:
+ ed->base_status.speed = (unsigned short) val;
+ status->calc_misc(bl, &ed->base_status, ed->db->lv);
+ break;
+ case UDT_LOOKDIR:
+ unit->setdir(bl, (unsigned char) val);
+ break;
+ case UDT_CANMOVETICK:
+ ed->ud.canmove_tick = (int64) val;
+ break;
+ case UDT_STR:
+ ed->base_status.str = (unsigned short) val;
+ status->calc_misc(bl, &ed->base_status, ed->db->lv);
+ break;
+ case UDT_AGI:
+ ed->base_status.agi = (unsigned short) val;
+ status->calc_misc(bl, &ed->base_status, ed->db->lv);
+ break;
+ case UDT_VIT:
+ ed->base_status.vit = (unsigned short) val;
+ status->calc_misc(bl, &ed->base_status, ed->db->lv);
+ break;
+ case UDT_INT:
+ ed->base_status.int_ = (unsigned short) val;
+ status->calc_misc(bl, &ed->base_status, ed->db->lv);
+ break;
+ case UDT_DEX:
+ ed->base_status.dex = (unsigned short) val;
+ status->calc_misc(bl, &ed->base_status, ed->db->lv);
+ break;
+ case UDT_LUK:
+ ed->base_status.luk = (unsigned short) val;
+ status->calc_misc(bl, &ed->base_status, ed->db->lv);
+ break;
+ case UDT_ATKRANGE:
+ ed->base_status.rhw.range = (unsigned short) val;
+ break;
+ case UDT_ATKMIN:
+ ed->base_status.rhw.atk = (unsigned short) val;
+ break;
+ case UDT_ATKMAX:
+ ed->base_status.rhw.atk2 = (unsigned short) val;
+ break;
+ case UDT_MATKMIN:
+ ed->base_status.matk_min = (unsigned short) val;
+ break;
+ case UDT_MATKMAX:
+ ed->base_status.matk_max = (unsigned short) val;
+ break;
+ case UDT_DEF:
+ ed->base_status.def = (defType) val;
+ break;
+ case UDT_MDEF:
+ ed->base_status.mdef = (defType) val;
+ break;
+ case UDT_HIT:
+ ed->base_status.hit = (short) val;
+ break;
+ case UDT_FLEE:
+ ed->base_status.flee = (short) val;
+ break;
+ case UDT_PDODGE:
+ ed->base_status.flee2 = (short) val;
+ break;
+ case UDT_CRIT:
+ ed->base_status.cri = (short) val;
+ break;
+ case UDT_RACE:
+ ed->base_status.race = (unsigned char) val;
+ break;
+ case UDT_ELETYPE:
+ ed->base_status.def_ele = (unsigned char) val;
+ break;
+ case UDT_ELELEVEL:
+ ed->base_status.ele_lv = (unsigned char) val;
+ break;
+ case UDT_AMOTION:
+ ed->base_status.amotion = (unsigned short) val;
+ break;
+ case UDT_ADELAY:
+ ed->base_status.adelay = (unsigned short) val;
+ break;
+ case UDT_DMOTION:
+ ed->base_status.dmotion = (unsigned short) val;
+ break;
+ case UDT_LIFETIME:
+ ed->elemental.life_time = (int) val;
+ break;
+ default:
+ ShowWarning("buildin_setunitdata: Invalid data type '%s' for elemental unit.\n", udtype);
+ script_pushint(st, 0);
+ return false;
+ }
+ clif->elemental_info(ed->master);
+ }
+ break;
+ case BL_NPC:
+ {
+ struct npc_data *nd = BL_UCAST(BL_NPC, bl);
+
+ nullpo_retr(false, nd);
+
+ switch (type)
+ {
+ case UDT_SIZE:
+ nd->status.size = (unsigned char) val;
+ break;
+ case UDT_LEVEL:
+ nd->level = (unsigned short) val;
+ break;
+ case UDT_HP:
+ status->set_hp(bl, (unsigned int) val, 0);
+ break;
+ case UDT_MAXHP:
+ nd->status.max_hp = (unsigned int) val;
+ break;
+ case UDT_SP:
+ status->set_sp(bl, (unsigned int) val, 0);
+ break;
+ case UDT_MAXSP:
+ nd->status.max_sp = (unsigned int) val;
+ break;
+ case UDT_MAPIDXY:
+ unit->warp(bl, (short) val, (short) val2, (short) val3, CLR_TELEPORT);
+ break;
+ case UDT_WALKTOXY:
+ if (!unit->walktoxy(bl, (short) val, (short) val2, 2))
+ unit->movepos(bl, (short) val, (short) val2, 0, 0);
+ break;
+ case UDT_CLASS:
+ npc->setclass(nd, (short) val);
+ break;
+ case UDT_SPEED:
+ nd->speed = (short) val;
+ status->calc_misc(bl, &nd->status, nd->level);
+ break;
+ case UDT_LOOKDIR:
+ unit->setdir(bl, (unsigned char) val);
+ break;
+ case UDT_STR:
+ nd->status.str = (unsigned short) val;
+ status->calc_misc(bl, &nd->status, nd->level);
+ break;
+ case UDT_AGI:
+ nd->status.agi = (unsigned short) val;
+ status->calc_misc(bl, &nd->status, nd->level);
+ break;
+ case UDT_VIT:
+ nd->status.vit = (unsigned short) val;
+ status->calc_misc(bl, &nd->status, nd->level);
+ break;
+ case UDT_INT:
+ nd->status.int_ = (unsigned short) val;
+ status->calc_misc(bl, &nd->status, nd->level);
+ break;
+ case UDT_DEX:
+ nd->status.dex = (unsigned short) val;
+ status->calc_misc(bl, &nd->status, nd->level);
+ break;
+ case UDT_LUK:
+ nd->status.luk = (unsigned short) val;
+ status->calc_misc(bl, &nd->status, nd->level);
+ break;
+ case UDT_STATPOINT:
+ nd->stat_point = (unsigned short) val;
+ break;
+ case UDT_ATKRANGE:
+ nd->status.rhw.range = (unsigned short) val;
+ break;
+ case UDT_ATKMIN:
+ nd->status.rhw.atk = (unsigned short) val;
+ break;
+ case UDT_ATKMAX:
+ nd->status.rhw.atk2 = (unsigned short) val;
+ break;
+ case UDT_MATKMIN:
+ nd->status.matk_min = (unsigned short) val;
+ break;
+ case UDT_MATKMAX:
+ nd->status.matk_max = (unsigned short) val;
+ break;
+ case UDT_DEF:
+ nd->status.def = (defType) val;
+ break;
+ case UDT_MDEF:
+ nd->status.mdef = (defType) val;
+ break;
+ case UDT_HIT:
+ nd->status.hit = (short) val;
+ break;
+ case UDT_FLEE:
+ nd->status.flee = (short) val;
+ break;
+ case UDT_PDODGE:
+ nd->status.flee2 = (short) val;
+ break;
+ case UDT_CRIT:
+ nd->status.cri = (short) val;
+ break;
+ case UDT_RACE:
+ nd->status.race = (unsigned char) val;
+ break;
+ case UDT_ELETYPE:
+ nd->status.def_ele = (unsigned char) val;
+ break;
+ case UDT_ELELEVEL:
+ nd->status.ele_lv = (unsigned char) val;
+ break;
+ case UDT_AMOTION:
+ nd->status.amotion = (unsigned short) val;
+ break;
+ case UDT_ADELAY:
+ nd->status.adelay = (unsigned short) val;
+ break;
+ case UDT_DMOTION:
+ nd->status.dmotion = (unsigned short) val;
+ break;
+ default:
+ ShowWarning("buildin_setunitdata: Invalid data type '%s' for NPC unit.\n", udtype);
+ script_pushint(st, 0);
+ return false;
+ }
+ }
+ break;
+ default:
+ ShowError("buildin_setunitdata: Unknown object!\n");
+ script_pushint(st, 0);
+ return false;
+ } // end of bl->type switch
+
+ script_pushint(st, 1);
+ return true;
+}
+
+/**
+ * Retrieves real-time data for a game object.
+ * Getunitdata <GUID>,<DataType>{,<Variable>}
+ * @param1 GUID Game object unique Id.
+ * @param2 DataType Type of Data to be set for the unit.
+ * @param3 Variable array reference to store data into. (used for UDT_MAPIDXY)
+ * @return 0 on failure, <value> on success
+ */
+BUILDIN(getunitdata)
+{
+ struct block_list *bl;
+ const char *udtype = NULL;
+ const struct map_session_data *sd = NULL;
+ int type = 0;
+ char* name = NULL;
+ struct script_data *data = script_hasdata(st,4)?script_getdata(st, 4):NULL;
+
+ bl = map->id2bl(script_getnum(st, 2));
+
+ if (bl == NULL) {
+ ShowWarning("buildin_getunitdata: Error in finding object with given GID %d!\n", script_getnum(st, 2));
+ script_pushint(st, 0);
+ return false;
+ }
+
+ type = script_getnum(st, 3);
+
+ /* Type check */
+ if (type < UDT_SIZE || type >= UDT_MAX) {
+ ShowError("buildin_getunitdata: Invalid unit data type %d provided.\n", type);
+ script_pushint(st, 0);
+ return false;
+ }
+
+ /* Argument checks */
+ if (type == UDT_MAPIDXY) {
+ if (data == NULL || !data_isreference(data)) {
+ ShowWarning("buildin_getunitdata: Error in argument 3. Please provide a reference variable to store values in.\n");
+ script_pushint(st, 0);
+ return false;
+ }
+
+ name = reference_getname(data);
+
+ if (not_server_variable(*name)) {
+ sd = script->rid2sd(st);
+ if (sd == NULL) {
+ ShowWarning("buildin_getunitdata: Player not attached! Cannot use player variable %s.\n",name);
+ script_pushint(st, 0);
+ return true;// no player attached
+ }
+ }
+ }
+
+#define getunitdata_sub(idx__,var__) script->setd_sub(st,NULL,name,(idx__),(void *)h64BPTRSIZE((int)(var__)),data->ref);
+
+ switch (bl->type) {
+ case BL_MOB:
+ {
+ const struct mob_data *md = BL_UCAST(BL_MOB, bl);
+
+ nullpo_retr(false, md);
+
+ switch (type)
+ {
+ case UDT_TYPE: script_pushint(st, BL_MOB); break;
+ case UDT_SIZE: script_pushint(st, md->status.size); break;
+ case UDT_LEVEL: script_pushint(st, md->level); break;
+ case UDT_HP: script_pushint(st, md->status.hp); break;
+ case UDT_MAXHP: script_pushint(st, md->status.max_hp); break;
+ case UDT_SP: script_pushint(st, md->status.sp); break;
+ case UDT_MAXSP: script_pushint(st, md->status.max_sp); break;
+ case UDT_MAPIDXY:
+ getunitdata_sub(0, md->bl.m);
+ getunitdata_sub(1, md->bl.x);
+ getunitdata_sub(2, md->bl.y);
+ break;
+ case UDT_SPEED: script_pushint(st, md->status.speed); break;
+ case UDT_MODE: script_pushint(st, md->status.mode); break;
+ case UDT_AI: script_pushint(st, md->special_state.ai); break;
+ case UDT_SCOPTION: script_pushint(st, md->sc.option); break;
+ case UDT_SEX: script_pushint(st, md->vd->sex); break;
+ case UDT_CLASS: script_pushint(st, md->vd->class); break;
+ case UDT_HAIRSTYLE: script_pushint(st, md->vd->hair_style); break;
+ case UDT_HAIRCOLOR: script_pushint(st, md->vd->hair_color); break;
+ case UDT_HEADBOTTOM: script_pushint(st, md->vd->head_bottom); break;
+ case UDT_HEADMIDDLE: script_pushint(st, md->vd->head_mid); break;
+ case UDT_HEADTOP: script_pushint(st, md->vd->head_top); break;
+ case UDT_CLOTHCOLOR: script_pushint(st, md->vd->cloth_color); break;
+ case UDT_SHIELD: script_pushint(st, md->vd->shield); break;
+ case UDT_WEAPON: script_pushint(st, md->vd->weapon); break;
+ case UDT_LOOKDIR: script_pushint(st, md->ud.dir); break;
+ case UDT_CANMOVETICK: script_pushint(st, md->ud.canmove_tick); break;
+ case UDT_STR: script_pushint(st, md->status.str); break;
+ case UDT_AGI: script_pushint(st, md->status.agi); break;
+ case UDT_VIT: script_pushint(st, md->status.vit); break;
+ case UDT_INT: script_pushint(st, md->status.int_); break;
+ case UDT_DEX: script_pushint(st, md->status.dex); break;
+ case UDT_LUK: script_pushint(st, md->status.luk); break;
+ case UDT_ATKRANGE: script_pushint(st, md->status.rhw.range); break;
+ case UDT_ATKMIN: script_pushint(st, md->status.rhw.atk); break;
+ case UDT_ATKMAX: script_pushint(st, md->status.rhw.atk2); break;
+ case UDT_MATKMIN: script_pushint(st, md->status.matk_min); break;
+ case UDT_MATKMAX: script_pushint(st, md->status.matk_max); break;
+ case UDT_DEF: script_pushint(st, md->status.def); break;
+ case UDT_MDEF: script_pushint(st, md->status.mdef); break;
+ case UDT_HIT: script_pushint(st, md->status.hit); break;
+ case UDT_FLEE: script_pushint(st, md->status.flee); break;
+ case UDT_PDODGE: script_pushint(st, md->status.flee2); break;
+ case UDT_CRIT: script_pushint(st, md->status.cri); break;
+ case UDT_RACE: script_pushint(st, md->status.race); break;
+ case UDT_ELETYPE: script_pushint(st, md->status.def_ele); break;
+ case UDT_ELELEVEL: script_pushint(st, md->status.ele_lv); break;
+ case UDT_AMOTION: script_pushint(st, md->status.amotion); break;
+ case UDT_ADELAY: script_pushint(st, md->status.adelay); break;
+ case UDT_DMOTION: script_pushint(st, md->status.dmotion); break;
+ default:
+ ShowWarning("buildin_getunitdata: Invalid data type '%s' for Mob unit.\n", udtype);
+ script_pushint(st, 0);
+ return false;
+ }
+ }
+ break;
+ case BL_HOM:
+ {
+ const struct homun_data *hd = BL_UCAST(BL_HOM, bl);
+
+ nullpo_retr(false, hd);
+
+ switch (type)
+ {
+ case UDT_TYPE: script_pushint(st, BL_HOM); break;
+ case UDT_SIZE: script_pushint(st, hd->base_status.size); break;
+ case UDT_LEVEL: script_pushint(st, hd->homunculus.level); break;
+ case UDT_HP: script_pushint(st, hd->base_status.hp); break;
+ case UDT_MAXHP: script_pushint(st, hd->base_status.max_hp); break;
+ case UDT_SP: script_pushint(st, hd->base_status.sp); break;
+ case UDT_MAXSP: script_pushint(st, hd->base_status.max_sp); break;
+ case UDT_MAPIDXY:
+ getunitdata_sub(0, hd->bl.m);
+ getunitdata_sub(1, hd->bl.x);
+ getunitdata_sub(2, hd->bl.y);
+ break;
+ case UDT_SPEED: script_pushint(st, hd->base_status.speed); break;
+ case UDT_LOOKDIR: script_pushint(st, hd->ud.dir); break;
+ case UDT_CANMOVETICK: script_pushint(st, hd->ud.canmove_tick); break;
+ case UDT_MODE: script_pushint(st, hd->base_status.mode); break;
+ case UDT_STR: script_pushint(st, hd->base_status.str); break;
+ case UDT_AGI: script_pushint(st, hd->base_status.agi); break;
+ case UDT_VIT: script_pushint(st, hd->base_status.vit); break;
+ case UDT_INT: script_pushint(st, hd->base_status.int_); break;
+ case UDT_DEX: script_pushint(st, hd->base_status.dex); break;
+ case UDT_LUK: script_pushint(st, hd->base_status.luk); break;
+ case UDT_ATKRANGE: script_pushint(st, hd->base_status.rhw.range); break;
+ case UDT_ATKMIN: script_pushint(st, hd->base_status.rhw.atk); break;
+ case UDT_ATKMAX: script_pushint(st, hd->base_status.rhw.atk2); break;
+ case UDT_MATKMIN: script_pushint(st, hd->base_status.matk_min); break;
+ case UDT_MATKMAX: script_pushint(st, hd->base_status.matk_max); break;
+ case UDT_DEF: script_pushint(st, hd->base_status.def); break;
+ case UDT_MDEF: script_pushint(st, hd->base_status.mdef); break;
+ case UDT_HIT: script_pushint(st, hd->base_status.hit); break;
+ case UDT_FLEE: script_pushint(st, hd->base_status.flee); break;
+ case UDT_PDODGE: script_pushint(st, hd->base_status.flee2); break;
+ case UDT_CRIT: script_pushint(st, hd->base_status.cri); break;
+ case UDT_RACE: script_pushint(st, hd->base_status.race); break;
+ case UDT_ELETYPE: script_pushint(st, hd->base_status.def_ele); break;
+ case UDT_ELELEVEL: script_pushint(st, hd->base_status.ele_lv); break;
+ case UDT_AMOTION: script_pushint(st, hd->base_status.amotion); break;
+ case UDT_ADELAY: script_pushint(st, hd->base_status.adelay); break;
+ case UDT_DMOTION: script_pushint(st, hd->base_status.dmotion); break;
+ case UDT_MASTERCID: script_pushint(st, hd->homunculus.char_id); break;
+ case UDT_HUNGER: script_pushint(st, hd->homunculus.hunger); break;
+ case UDT_INTIMACY: script_pushint(st, hd->homunculus.intimacy); break;
+ default:
+ ShowWarning("buildin_getunitdata: Invalid data type '%s' for Homunculus unit.\n", udtype);
+ script_pushint(st, 0);
+ return false;
+ }
+ }
+ break;
+ case BL_PET:
+ {
+ const struct pet_data *pd = BL_UCAST(BL_PET, bl);
+
+ nullpo_retr(false, pd);
+
+ switch (type)
+ {
+ case UDT_TYPE: script_pushint(st, BL_PET); break;
+ case UDT_SIZE: script_pushint(st, pd->status.size); break;
+ case UDT_LEVEL: script_pushint(st, pd->pet.level); break;
+ case UDT_HP: script_pushint(st, pd->status.hp); break;
+ case UDT_MAXHP: script_pushint(st, pd->status.max_hp); break;
+ case UDT_SP: script_pushint(st, pd->status.sp); break;
+ case UDT_MAXSP: script_pushint(st, pd->status.max_sp); break;
+ case UDT_MAPIDXY:
+ getunitdata_sub(0, pd->bl.m);
+ getunitdata_sub(1, pd->bl.x);
+ getunitdata_sub(2, pd->bl.y);
+ break;
+ case UDT_SPEED: script_pushint(st, pd->status.speed); break;
+ case UDT_LOOKDIR: script_pushint(st, pd->ud.dir); break;
+ case UDT_CANMOVETICK: script_pushint(st, pd->ud.canmove_tick); break;
+ case UDT_MODE: script_pushint(st, pd->status.mode); break;
+ case UDT_STR: script_pushint(st, pd->status.str); break;
+ case UDT_AGI: script_pushint(st, pd->status.agi); break;
+ case UDT_VIT: script_pushint(st, pd->status.vit); break;
+ case UDT_INT: script_pushint(st, pd->status.int_); break;
+ case UDT_DEX: script_pushint(st, pd->status.dex); break;
+ case UDT_LUK: script_pushint(st, pd->status.luk); break;
+ case UDT_ATKRANGE: script_pushint(st, pd->status.rhw.range); break;
+ case UDT_ATKMIN: script_pushint(st, pd->status.rhw.atk); break;
+ case UDT_ATKMAX: script_pushint(st, pd->status.rhw.atk2); break;
+ case UDT_MATKMIN: script_pushint(st, pd->status.matk_min); break;
+ case UDT_MATKMAX: script_pushint(st, pd->status.matk_max); break;
+ case UDT_DEF: script_pushint(st, pd->status.def); break;
+ case UDT_MDEF: script_pushint(st, pd->status.mdef); break;
+ case UDT_HIT: script_pushint(st, pd->status.hit); break;
+ case UDT_FLEE: script_pushint(st, pd->status.flee); break;
+ case UDT_PDODGE: script_pushint(st, pd->status.flee2); break;
+ case UDT_CRIT: script_pushint(st, pd->status.cri); break;
+ case UDT_RACE: script_pushint(st, pd->status.race); break;
+ case UDT_ELETYPE: script_pushint(st, pd->status.def_ele); break;
+ case UDT_ELELEVEL: script_pushint(st, pd->status.ele_lv); break;
+ case UDT_AMOTION: script_pushint(st, pd->status.amotion); break;
+ case UDT_ADELAY: script_pushint(st, pd->status.adelay); break;
+ case UDT_DMOTION: script_pushint(st, pd->status.dmotion); break;
+ case UDT_MASTERAID: script_pushint(st, pd->pet.account_id); break;
+ case UDT_HUNGER: script_pushint(st, pd->pet.hungry); break;
+ case UDT_INTIMACY: script_pushint(st, pd->pet.intimate); break;
+ default:
+ ShowWarning("buildin_getunitdata: Invalid data type '%s' for Pet unit.\n", udtype);
+ script_pushint(st, 0);
+ return false;
+ }
+ }
+ break;
+ case BL_MER:
+ {
+ const struct mercenary_data *mc = BL_UCAST(BL_MER, bl);
+
+ nullpo_retr(false, mc);
+
+ switch (type)
+ {
+ case UDT_TYPE: script_pushint(st, BL_MER); break;
+ case UDT_SIZE: script_pushint(st, mc->base_status.size); break;
+ case UDT_HP: script_pushint(st, mc->base_status.hp); break;
+ case UDT_MAXHP: script_pushint(st, mc->base_status.max_hp); break;
+ case UDT_SP: script_pushint(st, mc->base_status.sp); break;
+ case UDT_MAXSP: script_pushint(st, mc->base_status.max_sp); break;
+ case UDT_MAPIDXY:
+ getunitdata_sub(0, mc->bl.m);
+ getunitdata_sub(1, mc->bl.x);
+ getunitdata_sub(2, mc->bl.y);
+ break;
+ case UDT_SPEED: script_pushint(st, mc->base_status.speed); break;
+ case UDT_LOOKDIR: script_pushint(st, mc->ud.dir); break;
+ case UDT_CANMOVETICK: script_pushint(st, mc->ud.canmove_tick); break;
+ case UDT_MODE: script_pushint(st, mc->base_status.mode); break;
+ case UDT_STR: script_pushint(st, mc->base_status.str); break;
+ case UDT_AGI: script_pushint(st, mc->base_status.agi); break;
+ case UDT_VIT: script_pushint(st, mc->base_status.vit); break;
+ case UDT_INT: script_pushint(st, mc->base_status.int_); break;
+ case UDT_DEX: script_pushint(st, mc->base_status.dex); break;
+ case UDT_LUK: script_pushint(st, mc->base_status.luk); break;
+ case UDT_ATKRANGE: script_pushint(st, mc->base_status.rhw.range); break;
+ case UDT_ATKMIN: script_pushint(st, mc->base_status.rhw.atk); break;
+ case UDT_ATKMAX: script_pushint(st, mc->base_status.rhw.atk2); break;
+ case UDT_MATKMIN: script_pushint(st, mc->base_status.matk_min); break;
+ case UDT_MATKMAX: script_pushint(st, mc->base_status.matk_max); break;
+ case UDT_DEF: script_pushint(st, mc->base_status.def); break;
+ case UDT_MDEF: script_pushint(st, mc->base_status.mdef); break;
+ case UDT_HIT: script_pushint(st, mc->base_status.hit); break;
+ case UDT_FLEE: script_pushint(st, mc->base_status.flee); break;
+ case UDT_PDODGE: script_pushint(st, mc->base_status.flee2); break;
+ case UDT_CRIT: script_pushint(st, mc->base_status.cri); break;
+ case UDT_RACE: script_pushint(st, mc->base_status.race); break;
+ case UDT_ELETYPE: script_pushint(st, mc->base_status.def_ele); break;
+ case UDT_ELELEVEL: script_pushint(st, mc->base_status.ele_lv); break;
+ case UDT_AMOTION: script_pushint(st, mc->base_status.amotion); break;
+ case UDT_ADELAY: script_pushint(st, mc->base_status.adelay); break;
+ case UDT_DMOTION: script_pushint(st, mc->base_status.dmotion); break;
+ case UDT_MASTERCID: script_pushint(st, mc->mercenary.char_id); break;
+ case UDT_MERC_KILLCOUNT: script_pushint(st, mc->mercenary.kill_count); break;
+ case UDT_LIFETIME: script_pushint(st, mc->mercenary.life_time); break;
+ default:
+ ShowWarning("buildin_getunitdata: Invalid data type '%s' for Mercenary unit.\n", udtype);
+ script_pushint(st, 0);
+ return false;
+ }
+ }
+ break;
+ case BL_ELEM:
+ {
+ const struct elemental_data *ed = BL_UCAST(BL_ELEM, bl);
+
+ nullpo_retr(false, ed);
+
+ switch (type)
+ {
+ case UDT_TYPE: script_pushint(st, BL_ELEM); break;
+ case UDT_SIZE: script_pushint(st, ed->base_status.size); break;
+ case UDT_HP: script_pushint(st, ed->base_status.hp); break;
+ case UDT_MAXHP: script_pushint(st, ed->base_status.max_hp); break;
+ case UDT_SP: script_pushint(st, ed->base_status.sp); break;
+ case UDT_MAXSP: script_pushint(st, ed->base_status.max_sp); break;
+ case UDT_MAPIDXY:
+ getunitdata_sub(0, ed->bl.m);
+ getunitdata_sub(1, ed->bl.x);
+ getunitdata_sub(2, ed->bl.y);
+ break;
+ case UDT_SPEED: script_pushint(st, ed->base_status.speed); break;
+ case UDT_LOOKDIR: script_pushint(st, ed->ud.dir); break;
+ case UDT_CANMOVETICK: script_pushint(st, ed->ud.canmove_tick); break;
+ case UDT_MODE: script_pushint(st, ed->base_status.mode); break;
+ case UDT_STR: script_pushint(st, ed->base_status.str); break;
+ case UDT_AGI: script_pushint(st, ed->base_status.agi); break;
+ case UDT_VIT: script_pushint(st, ed->base_status.vit); break;
+ case UDT_INT: script_pushint(st, ed->base_status.int_); break;
+ case UDT_DEX: script_pushint(st, ed->base_status.dex); break;
+ case UDT_LUK: script_pushint(st, ed->base_status.luk); break;
+ case UDT_ATKRANGE: script_pushint(st, ed->base_status.rhw.range); break;
+ case UDT_ATKMIN: script_pushint(st, ed->base_status.rhw.atk); break;
+ case UDT_ATKMAX: script_pushint(st, ed->base_status.rhw.atk2); break;
+ case UDT_MATKMIN: script_pushint(st, ed->base_status.matk_min); break;
+ case UDT_MATKMAX: script_pushint(st, ed->base_status.matk_max); break;
+ case UDT_DEF: script_pushint(st, ed->base_status.def); break;
+ case UDT_MDEF: script_pushint(st, ed->base_status.mdef); break;
+ case UDT_HIT: script_pushint(st, ed->base_status.hit); break;
+ case UDT_FLEE: script_pushint(st, ed->base_status.flee); break;
+ case UDT_PDODGE: script_pushint(st, ed->base_status.flee2); break;
+ case UDT_CRIT: script_pushint(st, ed->base_status.cri); break;
+ case UDT_RACE: script_pushint(st, ed->base_status.race); break;
+ case UDT_ELETYPE: script_pushint(st, ed->base_status.def_ele); break;
+ case UDT_ELELEVEL: script_pushint(st, ed->base_status.ele_lv); break;
+ case UDT_AMOTION: script_pushint(st, ed->base_status.amotion); break;
+ case UDT_ADELAY: script_pushint(st, ed->base_status.adelay); break;
+ case UDT_DMOTION: script_pushint(st, ed->base_status.dmotion); break;
+ case UDT_MASTERCID: script_pushint(st, ed->elemental.char_id); break;
+ default:
+ ShowWarning("buildin_getunitdata: Invalid data type '%s' for Elemental unit.\n", udtype);
+ script_pushint(st, 0);
+ return false;
+ }
+ }
+ break;
+ case BL_NPC:
+ {
+ const struct npc_data *nd = BL_UCAST(BL_NPC, bl);
+
+ nullpo_retr(false, nd);
+
+ switch (type)
+ {
+ case UDT_TYPE: script_pushint(st, BL_NPC); break;
+ case UDT_SIZE: script_pushint(st, nd->status.size); break;
+ case UDT_HP: script_pushint(st, nd->status.hp); break;
+ case UDT_MAXHP: script_pushint(st, nd->status.max_hp); break;
+ case UDT_SP: script_pushint(st, nd->status.sp); break;
+ case UDT_MAXSP: script_pushint(st, nd->status.max_sp); break;
+ case UDT_MAPIDXY:
+ getunitdata_sub(0, bl->m);
+ getunitdata_sub(1, bl->x);
+ getunitdata_sub(2, bl->y);
+ break;
+ case UDT_SPEED: script_pushint(st, nd->status.speed); break;
+ case UDT_LOOKDIR: script_pushint(st, nd->ud->dir); break;
+ case UDT_CANMOVETICK: script_pushint(st, nd->ud->canmove_tick); break;
+ case UDT_MODE: script_pushint(st, nd->status.mode); break;
+ case UDT_STR: script_pushint(st, nd->status.str); break;
+ case UDT_AGI: script_pushint(st, nd->status.agi); break;
+ case UDT_VIT: script_pushint(st, nd->status.vit); break;
+ case UDT_INT: script_pushint(st, nd->status.int_); break;
+ case UDT_DEX: script_pushint(st, nd->status.dex); break;
+ case UDT_LUK: script_pushint(st, nd->status.luk); break;
+ case UDT_ATKRANGE: script_pushint(st, nd->status.rhw.range); break;
+ case UDT_ATKMIN: script_pushint(st, nd->status.rhw.atk); break;
+ case UDT_ATKMAX: script_pushint(st, nd->status.rhw.atk2); break;
+ case UDT_MATKMIN: script_pushint(st, nd->status.matk_min); break;
+ case UDT_MATKMAX: script_pushint(st, nd->status.matk_max); break;
+ case UDT_DEF: script_pushint(st, nd->status.def); break;
+ case UDT_MDEF: script_pushint(st, nd->status.mdef); break;
+ case UDT_HIT: script_pushint(st, nd->status.hit); break;
+ case UDT_FLEE: script_pushint(st, nd->status.flee); break;
+ case UDT_PDODGE: script_pushint(st, nd->status.flee2); break;
+ case UDT_CRIT: script_pushint(st, nd->status.cri); break;
+ case UDT_RACE: script_pushint(st, nd->status.race); break;
+ case UDT_ELETYPE: script_pushint(st, nd->status.def_ele); break;
+ case UDT_ELELEVEL: script_pushint(st, nd->status.ele_lv); break;
+ case UDT_AMOTION: script_pushint(st, nd->status.amotion); break;
+ case UDT_ADELAY: script_pushint(st, nd->status.adelay); break;
+ case UDT_DMOTION: script_pushint(st, nd->status.dmotion); break;
+ default:
+ ShowWarning("buildin_getunitdata: Invalid data type '%s' for NPC unit.\n", udtype);
+ script_pushint(st, 0);
+ return false;
+ }
+ }
+ break;
+ default:
+ ShowError("buildin_getunitdata: Unknown object!\n");
+ script_pushint(st, 0);
+ return false;
+ } // end of bl->type switch
+
+#undef getunitdata_sub
+
+ return false;
+}
+
+/**
+ * Gets the name of a Unit.
+ * Supported types are [MOB|HOM|PET|NPC].
+ * MER and ELEM don't support custom names.
+ *
+ * @command getunitname <GUID>;
+ * @param GUID Game Object Unique ID.
+ * @return boolean or Name of the game object.
+ */
+BUILDIN(getunitname)
+{
+ const struct block_list* bl = NULL;
+
+ bl = map->id2bl(script_getnum(st, 2));
+
+ if (bl == NULL) {
+ ShowWarning("buildin_getunitname: Error in finding object with given game ID %d!\n", script_getnum(st, 2));
+ script_pushconststr(st, "Unknown");
+ return false;
+ }
+
+ script_pushstrcopy(st, status->get_name(bl));
+
+ return true;
+}
+
+/**
+ * Changes the name of a bl.
+ * Supported types are [MOB|HOM|PET].
+ * For NPC see 'setnpcdisplay', MER and ELEM don't support custom names.
+ *
+ * @command setunitname <GUID>,<name>;
+ * @param GUID Game object unique ID.
+ * @param Name as string.
+ * @return boolean.
+ */
+BUILDIN(setunitname)
+{
+ struct block_list* bl = map->id2bl(script_getnum(st, 2));
+
+ if (bl == NULL) {
+ ShowWarning("buildin_setunitname: Game object with ID %d was not found!\n", script_getnum(st, 2));
+ script_pushint(st, 0);
+ return false;
+ }
+
+ switch (bl->type) {
+ case BL_MOB:
+ {
+ struct mob_data *md = BL_UCAST(BL_MOB, bl);
+ if (md == NULL) {
+ ShowWarning("buildin_setunitname: Error in finding object BL_MOB!\n");
+ script_pushint(st, 0);
+ return false;
+ }
+ safestrncpy(md->name, script_getstr(st, 3), NAME_LENGTH);
+ }
+ break;
+ case BL_HOM:
+ {
+ struct homun_data *hd = BL_UCAST(BL_HOM, bl);
+ if (hd == NULL) {
+ ShowWarning("buildin_setunitname: Error in finding object BL_HOM!\n");
+ script_pushint(st, 0);
+ return false;
+ }
+ safestrncpy(hd->homunculus.name, script_getstr(st, 3), NAME_LENGTH);
+ }
+ break;
+ case BL_PET:
+ {
+ struct pet_data *pd = BL_UCAST(BL_PET, bl);
+ if (pd == NULL) {
+ ShowWarning("buildin_setunitname: Error in finding object BL_PET!\n");
+ script_pushint(st, 0);
+ return false;
+ }
+ safestrncpy(pd->pet.name, script_getstr(st, 3), NAME_LENGTH);
+ }
+ break;
+ default:
+ script_pushint(st, 0);
+ ShowWarning("buildin_setunitname: Unknown object type!\n");
+ return false;
+ }
+
+ script_pushint(st, 1);
+ clif->charnameack(0, bl); // Send update to client.
+
+ return true;
+}
+
/// Makes the unit walk to target position or target id
/// Returns if it was successfull
///
@@ -17498,6 +19753,54 @@ BUILDIN(getvariableofnpc)
return true;
}
+BUILDIN(getvariableofpc)
+{
+ const char* name;
+ struct script_data* data = script_getdata(st, 2);
+ struct map_session_data *sd = map->id2sd(script_getnum(st, 3));
+
+ if (!data_isreference(data)) {
+ ShowError("script:getvariableofpc: not a variable\n");
+ script->reportdata(data);
+ script_pushnil(st);
+ st->state = END;
+ return false;
+ }
+
+ name = reference_getname(data);
+
+ switch (*name)
+ {
+ case '$':
+ case '.':
+ case '\'':
+ ShowError("script:getvariableofpc: illegal scope (not pc variable)\n");
+ script->reportdata(data);
+ script_pushnil(st);
+ st->state = END;
+ return false;
+ }
+
+ if (sd == NULL)
+ {
+ // player not found, return default value
+ if (script_hasdata(st, 4)) {
+ script_pushcopy(st, 4);
+ } else if (is_string_variable(name)) {
+ script_pushconststr(st, "");
+ } else {
+ script_pushint(st, 0);
+ }
+ return true;
+ }
+
+ if (!sd->regs.vars)
+ sd->regs.vars = i64db_alloc(DB_OPT_RELEASE_DATA);
+
+ script->push_val(st->stack, C_NAME, reference_getuid(data), &sd->regs);
+ return true;
+}
+
/// Opens a warp portal.
/// Has no "portal opening" effect/sound, it opens the portal immediately.
///
@@ -20817,7 +23120,7 @@ void script_parse_builtin(void) {
BUILDIN_DEF(areawarp,"siiiisii??"),
BUILDIN_DEF(warpchar,"siii"), // [LuzZza]
BUILDIN_DEF(warpparty,"siii?"), // [Fredzilla] [Paradox924X]
- BUILDIN_DEF(warpguild,"siii"), // [Fredzilla]
+ BUILDIN_DEF(warpguild,"siii?"), // [Fredzilla]
BUILDIN_DEF(setlook,"ii"),
BUILDIN_DEF(changelook,"ii"), // Simulates but don't Store it
BUILDIN_DEF2(__setr,"set","rv"),
@@ -20858,8 +23161,8 @@ void script_parse_builtin(void) {
BUILDIN_DEF(getguildmaster,"i"),
BUILDIN_DEF(getguildmasterid,"i"),
BUILDIN_DEF(getguildmember,"i?"),
- BUILDIN_DEF(strcharinfo,"i"),
- BUILDIN_DEF(strnpcinfo,"i"),
+ BUILDIN_DEF(strcharinfo,"i??"),
+ BUILDIN_DEF(strnpcinfo,"i??"),
BUILDIN_DEF(charid2rid,"i"),
BUILDIN_DEF(getequipid,"i"),
BUILDIN_DEF(getequipname,"i"),
@@ -20922,9 +23225,11 @@ void script_parse_builtin(void) {
BUILDIN_DEF(clone,"siisi????"),
BUILDIN_DEF(doevent,"s"),
BUILDIN_DEF(donpcevent,"s"),
- BUILDIN_DEF(addtimer,"is"),
- BUILDIN_DEF(deltimer,"s"),
- BUILDIN_DEF(addtimercount,"si"),
+ BUILDIN_DEF(addtimer,"is?"),
+ BUILDIN_DEF(deltimer,"s?"),
+ BUILDIN_DEF(addtimercount,"si?"),
+ BUILDIN_DEF(gettimer,"i??"),
+ BUILDIN_DEF(getunits,"iris????"),
BUILDIN_DEF(initnpctimer,"??"),
BUILDIN_DEF(stopnpctimer,"??"),
BUILDIN_DEF(startnpctimer,"??"),
@@ -21009,7 +23314,7 @@ void script_parse_builtin(void) {
BUILDIN_DEF(getcartinventorylist,""),
BUILDIN_DEF(getskilllist,""),
BUILDIN_DEF(clearitem,""),
- BUILDIN_DEF(classchange,"ii"),
+ BUILDIN_DEF(classchange,"ii?"),
BUILDIN_DEF(misceffect,"i"),
BUILDIN_DEF(playbgm,"s"),
BUILDIN_DEF(playbgmall,"s?????"),
@@ -21075,6 +23380,8 @@ void script_parse_builtin(void) {
BUILDIN_DEF(getstrlen,"s"), //strlen [Valaris]
BUILDIN_DEF(charisalpha,"si"), //isalpha [Valaris]
BUILDIN_DEF(charat,"si"),
+ BUILDIN_DEF(chr,"i"),
+ BUILDIN_DEF(ord,"s"),
BUILDIN_DEF(setchar,"ssi"),
BUILDIN_DEF(insertchar,"ssi"),
BUILDIN_DEF(delchar,"si"),
@@ -21096,6 +23403,10 @@ void script_parse_builtin(void) {
BUILDIN_DEF(getiteminfo,"ii"), //[Lupus] returns Items Buy / sell Price, etc info
BUILDIN_DEF(setiteminfo,"iii"), //[Lupus] set Items Buy / sell Price, etc info
BUILDIN_DEF(getequipcardid,"ii"), //[Lupus] returns CARD ID or other info from CARD slot N of equipped item
+ BUILDIN_DEF(getequippedoptioninfo, "i"),
+ BUILDIN_DEF(getequipoption, "iii"),
+ BUILDIN_DEF(setequipoption, "iiii"),
+ BUILDIN_DEF(getequipisenableopt, "i"),
// List of mathematics commands --->
BUILDIN_DEF(log10,"i"),
BUILDIN_DEF(sqrt,"i"), //[zBuffer]
@@ -21141,6 +23452,11 @@ void script_parse_builtin(void) {
// <--- [zBuffer] List of player cont commands
// [zBuffer] List of mob control commands --->
BUILDIN_DEF(getunittype,"i"),
+ /* Unit Data */
+ BUILDIN_DEF(setunitdata,"iiv??"),
+ BUILDIN_DEF(getunitdata,"ii?"),
+ BUILDIN_DEF(getunitname,"i"),
+ BUILDIN_DEF(setunitname,"is"),
BUILDIN_DEF(unitwalk,"ii?"),
BUILDIN_DEF(unitkill,"i"),
BUILDIN_DEF(unitwarp,"isii"),
@@ -21155,6 +23471,7 @@ void script_parse_builtin(void) {
BUILDIN_DEF(sleep2,"i"),
BUILDIN_DEF(awake,"s"),
BUILDIN_DEF(getvariableofnpc,"rs"),
+ BUILDIN_DEF(getvariableofpc,"ri?"),
BUILDIN_DEF(warpportal,"iisii"),
BUILDIN_DEF2(homunculus_evolution,"homevolution",""), //[orn]
BUILDIN_DEF2(homunculus_mutate,"hommutate","?"),
@@ -21463,6 +23780,14 @@ void script_hardcoded_constants(void)
script->set_constant("EQP_SHADOW_ACC_R", EQP_SHADOW_ACC_R, false, false);
script->set_constant("EQP_SHADOW_ACC_L", EQP_SHADOW_ACC_L, false, false);
+ script->constdb_comment("Item Option Types");
+ script->set_constant("IT_OPT_INDEX", IT_OPT_INDEX, false, false);
+ script->set_constant("IT_OPT_VALUE", IT_OPT_VALUE, false, false);
+ script->set_constant("IT_OPT_PARAM", IT_OPT_PARAM, false, false);
+
+ script->constdb_comment("Maximum Item Options");
+ script->set_constant("MAX_ITEM_OPTIONS", MAX_ITEM_OPTIONS, false, false);
+
script->constdb_comment("Navigation constants, use with *navigateto*");
script->set_constant("NAV_NONE", NAV_NONE, false, false);
script->set_constant("NAV_AIRSHIP_ONLY", NAV_AIRSHIP_ONLY, false, false);
@@ -21473,6 +23798,20 @@ void script_hardcoded_constants(void)
script->set_constant("NAV_KAFRA_AND_SCROLL", NAV_KAFRA_AND_SCROLL, false, false);
script->set_constant("NAV_ALL", NAV_ALL, false, false);
+ script->constdb_comment("BL types");
+ script->set_constant("BL_PC",BL_PC,false, false);
+ script->set_constant("BL_MOB",BL_MOB,false, false);
+ script->set_constant("BL_PET",BL_PET,false, false);
+ script->set_constant("BL_HOM",BL_HOM,false, false);
+ script->set_constant("BL_MER",BL_MER,false, false);
+ script->set_constant("BL_ITEM",BL_ITEM,false, false);
+ script->set_constant("BL_SKILL",BL_SKILL,false, false);
+ script->set_constant("BL_NPC",BL_NPC,false, false);
+ script->set_constant("BL_CHAT",BL_CHAT,false, false);
+ script->set_constant("BL_ELEM",BL_ELEM,false, false);
+ script->set_constant("BL_CHAR",BL_CHAR,false, false);
+ script->set_constant("BL_ALL",BL_ALL,false, false);
+
script->constdb_comment("Renewal");
#ifdef RENEWAL
script->set_constant("RENEWAL", 1, false, false);
@@ -21619,10 +23958,12 @@ void script_defaults(void)
script->get_val = get_val;
script->get_val2 = get_val2;
script->get_val_ref_str = get_val_npcscope_str;
+ script->get_val_pc_ref_str = get_val_pc_ref_str;
script->get_val_scope_str = get_val_npcscope_str;
script->get_val_npc_str = get_val_npcscope_str;
script->get_val_instance_str = get_val_instance_str;
script->get_val_ref_num = get_val_npcscope_num;
+ script->get_val_pc_ref_num = get_val_pc_ref_num;
script->get_val_scope_num = get_val_npcscope_num;
script->get_val_npc_num = get_val_npcscope_num;
script->get_val_instance_num = get_val_instance_num;
@@ -21701,10 +24042,12 @@ void script_defaults(void)
script->errorwarning_sub = script_errorwarning_sub;
script->set_reg = set_reg;
script->set_reg_ref_str = set_reg_npcscope_str;
+ script->set_reg_pc_ref_str = set_reg_pc_ref_str;
script->set_reg_scope_str = set_reg_npcscope_str;
script->set_reg_npc_str = set_reg_npcscope_str;
script->set_reg_instance_str = set_reg_instance_str;
script->set_reg_ref_num = set_reg_npcscope_num;
+ script->set_reg_pc_ref_num = set_reg_pc_ref_num;
script->set_reg_scope_num = set_reg_npcscope_num;
script->set_reg_npc_num = set_reg_npcscope_num;
script->set_reg_instance_num = set_reg_instance_num;
diff --git a/src/map/script.h b/src/map/script.h
index a69000991..8caec961a 100644
--- a/src/map/script.h
+++ b/src/map/script.h
@@ -350,6 +350,81 @@ enum navigation_service {
};
/**
+ * Unit Types for script handling.
+ */
+enum script_unit_types {
+ UNIT_PC = 0,
+ UNIT_NPC,
+ UNIT_PET,
+ UNIT_MOB,
+ UNIT_HOM,
+ UNIT_MER,
+ UNIT_ELEM,
+};
+
+/**
+ * Unit Data Types for script handling.
+ */
+enum script_unit_data_types {
+ UDT_TYPE = 0,
+ UDT_SIZE,
+ UDT_LEVEL,
+ UDT_HP,
+ UDT_MAXHP,
+ UDT_SP,
+ UDT_MAXSP,
+ UDT_MASTERAID,
+ UDT_MASTERCID,
+ UDT_MAPIDXY,
+ UDT_WALKTOXY,
+ UDT_SPEED,
+ UDT_MODE,
+ UDT_AI,
+ UDT_SCOPTION,
+ UDT_SEX,
+ UDT_CLASS,
+ UDT_HAIRSTYLE,
+ UDT_HAIRCOLOR,
+ UDT_HEADBOTTOM,
+ UDT_HEADMIDDLE,
+ UDT_HEADTOP,
+ UDT_CLOTHCOLOR,
+ UDT_SHIELD,
+ UDT_WEAPON,
+ UDT_LOOKDIR,
+ UDT_CANMOVETICK,
+ UDT_STR,
+ UDT_AGI,
+ UDT_VIT,
+ UDT_INT,
+ UDT_DEX,
+ UDT_LUK,
+ UDT_ATKRANGE,
+ UDT_ATKMIN,
+ UDT_ATKMAX,
+ UDT_MATKMIN,
+ UDT_MATKMAX,
+ UDT_DEF,
+ UDT_MDEF,
+ UDT_HIT,
+ UDT_FLEE,
+ UDT_PDODGE,
+ UDT_CRIT,
+ UDT_RACE,
+ UDT_ELETYPE,
+ UDT_ELELEVEL,
+ UDT_AMOTION,
+ UDT_ADELAY,
+ UDT_DMOTION,
+ UDT_HUNGER,
+ UDT_INTIMACY,
+ UDT_LIFETIME,
+ UDT_MERC_KILLCOUNT,
+ UDT_STATPOINT,
+ UDT_MAX
+};
+
+/**
* Structures
**/
@@ -672,10 +747,12 @@ struct script_interface {
struct script_data* (*push_val)(struct script_stack* stack, enum c_op type, int64 val, struct reg_db *ref);
struct script_data *(*get_val) (struct script_state* st, struct script_data* data);
char* (*get_val_ref_str) (struct script_state* st, struct reg_db *n, struct script_data* data);
+ char* (*get_val_pc_ref_str) (struct script_state* st, struct reg_db *n, struct script_data* data);
char* (*get_val_scope_str) (struct script_state* st, struct reg_db *n, struct script_data* data);
char* (*get_val_npc_str) (struct script_state* st, struct reg_db *n, struct script_data* data);
char* (*get_val_instance_str) (struct script_state* st, const char* name, struct script_data* data);
int (*get_val_ref_num) (struct script_state* st, struct reg_db *n, struct script_data* data);
+ int (*get_val_pc_ref_num) (struct script_state* st, struct reg_db *n, struct script_data* data);
int (*get_val_scope_num) (struct script_state* st, struct reg_db *n, struct script_data* data);
int (*get_val_npc_num) (struct script_state* st, struct reg_db *n, struct script_data* data);
int (*get_val_instance_num) (struct script_state* st, const char* name, struct script_data* data);
@@ -755,10 +832,12 @@ struct script_interface {
void (*errorwarning_sub) (StringBuf *buf, const char *src, const char *file, int start_line, const char *error_msg, const char *error_pos);
int (*set_reg) (struct script_state *st, struct map_session_data *sd, int64 num, const char *name, const void *value, struct reg_db *ref);
void (*set_reg_ref_str) (struct script_state* st, struct reg_db *n, int64 num, const char* name, const char *str);
+ void (*set_reg_pc_ref_str) (struct script_state* st, struct reg_db *n, int64 num, const char* name, const char *str);
void (*set_reg_scope_str) (struct script_state* st, struct reg_db *n, int64 num, const char* name, const char *str);
void (*set_reg_npc_str) (struct script_state* st, struct reg_db *n, int64 num, const char* name, const char *str);
void (*set_reg_instance_str) (struct script_state* st, int64 num, const char* name, const char *str);
void (*set_reg_ref_num) (struct script_state* st, struct reg_db *n, int64 num, const char* name, int val);
+ void (*set_reg_pc_ref_num) (struct script_state* st, struct reg_db *n, int64 num, const char* name, int val);
void (*set_reg_scope_num) (struct script_state* st, struct reg_db *n, int64 num, const char* name, int val);
void (*set_reg_npc_num) (struct script_state* st, struct reg_db *n, int64 num, const char* name, int val);
void (*set_reg_instance_num) (struct script_state* st, int64 num, const char* name, int val);
diff --git a/src/map/skill.c b/src/map/skill.c
index 51a8a28e7..714c2aa71 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -2,7 +2,7 @@
* This file is part of Hercules.
* http://herc.ws - http://github.com/HerculesWS/Hercules
*
- * Copyright (C) 2012-2016 Hercules Dev Team
+ * Copyright (C) 2012-2017 Hercules Dev Team
* Copyright (C) Athena Dev Teams
*
* Hercules is free software: you can redistribute it and/or modify
@@ -303,7 +303,7 @@ int skill_get_range2(struct block_list *bl, uint16 skill_id, uint16 skill_lv)
if (sd != NULL)
range += pc->checkskill(sd, AC_VULTURE);
else
- range += 10; //Assume level 10?
+ range += battle->bc->mob_eye_range_bonus;
break;
// added to allow GS skills to be effected by the range of Snake Eyes [Reddozen]
case GS_RAPIDSHOWER:
@@ -314,7 +314,7 @@ int skill_get_range2(struct block_list *bl, uint16 skill_id, uint16 skill_lv)
if (sd != NULL)
range += pc->checkskill(sd, GS_SNAKEEYE);
else
- range += 10; //Assume level 10?
+ range += battle->bc->mob_eye_range_bonus;
break;
case NJ_KIRIKAGE:
if (sd != NULL)
@@ -7470,8 +7470,8 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
case NPC_LICK:
status_zap(bl, 0, 100);
- clif->skill_nodamage(src,bl,skill_id,skill_lv,
- sc_start(src,bl,type,(skill_lv*5),skill_lv,skill->get_time2(skill_id,skill_lv)));
+ clif->skill_nodamage(src, bl, skill_id, skill_lv,
+ sc_start(src, bl, type, (skill_lv * 20), skill_lv, skill->get_time2(skill_id, skill_lv)));
break;
case NPC_SUICIDE:
@@ -8181,8 +8181,14 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
int x,y;
x = src->x;
y = src->y;
- if (hd)
- skill->blockhomun_start(hd, skill_id, skill->get_time2(skill_id,skill_lv));
+ if (hd) {
+#ifdef RENEWAL
+ skill->blockhomun_start(hd, skill_id, skill->get_cooldown(skill_id, skill_lv));
+#else
+ skill->blockhomun_start(hd, skill_id, skill->get_time2(skill_id, skill_lv));
+#endif
+ }
+
if (unit->movepos(src,bl->x,bl->y,0,0)) {
clif->skill_nodamage(src,src,skill_id,skill_lv,1); // Homun
diff --git a/src/map/status.c b/src/map/status.c
index 78c11899b..d8fb9a350 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -2400,8 +2400,8 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt)
bstatus->speed = pSpeed;
}
- //FIXME: Most of these stuff should be calculated once, but how do I fix the memset above to do that? [Skotlex]
- //Give them all modes except these (useful for clones)
+ // FIXME: Most of these stuff should be calculated once, but how do I fix the memset above to do that? [Skotlex]
+ // Give them all modes except these (useful for clones)
bstatus->mode = MD_MASK&~(MD_BOSS|MD_PLANT|MD_DETECTOR|MD_ANGRY|MD_TARGETWEAK);
bstatus->size = ((sd->job & JOBL_BABY) != 0 || (sd->job & MAPID_BASEMASK) == MAPID_SUMMONER)?SZ_SMALL:SZ_MEDIUM;
@@ -2646,6 +2646,39 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt)
}
}
}
+
+ /* parse item options [Smokexyz] */
+ for (i = 0; i < EQI_MAX; i++) {
+ status->current_equip_item_index = index = sd->equip_index[i];
+ status->current_equip_option_index = -1;
+
+ if (i == EQI_HAND_R && sd->equip_index[EQI_HAND_L] == index)
+ continue;
+ else if (i == EQI_HEAD_MID && sd->equip_index[EQI_HEAD_LOW] == index)
+ continue;
+ else if (i == EQI_HEAD_TOP && (sd->equip_index[EQI_HEAD_MID] == index || sd->equip_index[EQI_HEAD_LOW] == index))
+ continue;
+
+ if (index >= 0 && sd->inventory_data[index]) {
+ int j = 0;
+ for (j = 0; j < MAX_ITEM_OPTIONS; j++) {
+ int16 option_index = sd->status.inventory[index].option[j].index;
+ struct item_option *ito = NULL;
+
+ if (option_index == 0 || (ito = itemdb->option_exists(option_index)) == NULL || ito->script == NULL)
+ continue;
+
+ status->current_equip_option_index = j;
+ script->run(ito->script, 0, sd->bl.id, 0);
+
+ if (calculating == 0) //Abort, script->run his function. [Skotlex]
+ return 1;
+ }
+ }
+ }
+
+ status->current_equip_option_index = -1;
+ status->current_equip_item_index = -1;
status->calc_pc_additional(sd, opt);
diff --git a/src/map/status.h b/src/map/status.h
index e6c205b1d..06e7e07b8 100644
--- a/src/map/status.h
+++ b/src/map/status.h
@@ -1759,10 +1759,10 @@ enum si_type {
//SI_HEALTHSTATE_HEAVYPOISON = 890,
//SI_HEALTHSTATE_FEAR = 891,
//SI_CHERRY_BLOSSOM_CAKE = 892,
- SI_SU_STOOP = 893,
- SI_CATNIPPOWDER = 894,
+ SI_SU_STOOP = 893,
+ SI_CATNIPPOWDER = 894,
SI_BLOSSOM_FLUTTERING = 895,
- SI_SV_ROOTTWIST = 896,
+ SI_SV_ROOTTWIST = 896,
//SI_ATTACK_PROPERTY_NOTHING = 897,
//SI_ATTACK_PROPERTY_WATER = 898,
//SI_ATTACK_PROPERTY_GROUND = 899,
@@ -1784,11 +1784,11 @@ enum si_type {
//SI_RESIST_PROPERTY_DARKNESS = 914,
//SI_RESIST_PROPERTY_TELEKINESIS = 915,
//SI_RESIST_PROPERTY_UNDEAD = 916,
- SI_BITESCAR = 917,
- SI_ARCLOUSEDASH = 918,
- SI_TUNAPARTY = 919,
- SI_SHRIMP = 920,
- SI_FRESHSHRIMP = 921,
+ SI_BITESCAR = 917,
+ SI_ARCLOUSEDASH = 918,
+ SI_TUNAPARTY = 919,
+ SI_SHRIMP = 920,
+ SI_FRESHSHRIMP = 921,
//SI_PERIOD_RECEIVEITEM = 922,
//SI_PERIOD_PLUSEXP = 923,
//SI_PERIOD_PLUSJOBEXP = 924,
@@ -1800,14 +1800,78 @@ enum si_type {
//SI_HELM_ISIA = 930,
//SI_HELM_ASIR = 931,
//SI_HELM_URJ = 932,
- SI_SUHIDE = 933,
+ SI_SUHIDE = 933,
//SI_ = 934,
//SI_DORAM_BUF_01 = 935,
//SI_DORAM_BUF_02 = 936,
- SI_SPRITEMABLE = 937,
+ SI_SPRITEMABLE = 937,
+ //SI_AID_PERIOD_RECEIVEITEM = 938,
+ //SI_AID_PERIOD_PLUSEXP = 939,
+ //SI_AID_PERIOD_PLUSJOBEXP = 940,
+ //SI_AID_PERIOD_DEADPENALTY = 941,
+ //SI_AID_PERIOD_ADDSTOREITEMCOUNT = 942,
+ //SI_ = 943,
+ //SI_ = 944,
+ //SI_ = 945,
+ //SI_ = 946,
+ //SI_ = 947,
+ //SI_ = 948,
+ //SI_ = 949,
+ //SI_HISS = 950,
+ //SI_ = 951,
+ //SI_NYANGGRASS = 952,
+ //SI_CHATTERING = 953,
+ //SI_ = 954,
+ //SI_ = 955,
+ //SI_ = 956,
+ //SI_ = 957,
+ //SI_ = 958,
+ //SI_ = 959,
+ //SI_ = 960,
+ //SI_GROOMING = 961,
+ //SI_PROTECTIONOFSHRIMP = 962,
//SI_EP16_2_BUFF_SS = 963,
//SI_EP16_2_BUFF_SC = 964,
//SI_EP16_2_BUFF_AC = 965,
+ //SI_GS_MAGICAL_BULLET = 966,
+ //SI_ = 967,
+ //SI_ = 968,
+ //SI_ = 969,
+ //SI_ = 970,
+ //SI_ = 971,
+ //SI_ = 972,
+ //SI_ = 973,
+ //SI_ = 974,
+ //SI_ = 975,
+ //SI_FALLEN_ANGEL = 976,
+ //SI_ = 977,
+ //SI_ = 978,
+ //SI_BLAZE_BEAD = 979,
+ //SI_FROZEN_BEAD = 980,
+ //SI_BREEZE_BEAD = 981,
+ //SI_ = 982,
+ //SI_AID_PERIOD_RECEIVEITEM_2ND = 983,
+ //SI_AID_PERIOD_PLUSEXP_2ND = 984,
+ //SI_AID_PERIOD_PLUSJOBEXP_2ND = 985,
+ //SI_PRONTERA_JP = 986,
+ //SI_ = 987,
+ //SI_GLOOM_CARD = 988,
+ //SI_PHARAOH_CARD = 989,
+ //SI_KIEL_CARD = 990,
+ //SI_ = 991,
+ //SI_CHEERUP = 992,
+ //SI_ = 993,
+ //SI_ = 994,
+ //SI_S_MANAPOTION = 995,
+ //SI_M_DEFSCROLL = 996,
+ //SI_ = 997,
+ //SI_ = 998,
+ //SI_ = 999,
+ //SI_AS_RAGGED_GOLEM_CARD = 1000,
+ //SI_LHZ_DUN_N1 = 1001,
+ //SI_LHZ_DUN_N2 = 1002,
+ //SI_LHZ_DUN_N3 = 1003,
+ //SI_LHZ_DUN_N4 = 1004,
#ifndef SI_MAX
SI_MAX,
#endif
@@ -2205,6 +2269,7 @@ struct status_interface {
/* vars */
int current_equip_item_index;
int current_equip_card_id;
+ int current_equip_option_index;
struct s_status_dbs *dbs;
diff --git a/src/map/storage.c b/src/map/storage.c
index acb72be81..aacc7c053 100644
--- a/src/map/storage.c
+++ b/src/map/storage.c
@@ -133,9 +133,12 @@ int compare_item(struct item *a, struct item *b)
a->bound == b->bound &&
a->unique_id == b->unique_id)
{
- int i;
- for (i = 0; i < MAX_SLOTS && (a->card[i] == b->card[i]); i++);
- return (i == MAX_SLOTS);
+ int i = 0, k = 0;
+ ARR_FIND(0, MAX_SLOTS, i, a->card[i] != b->card[i]);
+ ARR_FIND(0, MAX_ITEM_OPTIONS, k, a->option[k].index != b->option[k].index || a->option[k].value != b->option[k].value);
+
+ if (i == MAX_SLOTS && k == MAX_ITEM_OPTIONS)
+ return 1;
}
return 0;
}
diff --git a/src/map/unit.c b/src/map/unit.c
index 739a369a6..79abb8c6a 100644
--- a/src/map/unit.c
+++ b/src/map/unit.c
@@ -668,11 +668,12 @@ void unit_run_hit(struct block_list *bl, struct status_change *sc, struct map_se
ud->state.running = 0;
status_change_end(bl, type, INVALID_TIMER);
- if( type == SC_RUN ) {
- skill->blown(bl,bl,skill->get_blewcount(TK_RUN,lv),unit->getdir(bl),0);
+ if (type == SC_RUN) {
+ if (lv > 0)
+ skill->blown(bl, bl, skill->get_blewcount(TK_RUN, lv), unit->getdir(bl), 0);
clif->fixpos(bl); //Why is a clif->slide (skill->blown) AND a fixpos needed? Ask Aegis.
- clif->sc_end(bl,bl->id,AREA,SI_TING);
- } else if( sd ) {
+ clif->sc_end(bl, bl->id, AREA, SI_TING);
+ } else if (sd) {
clif->fixpos(bl);
skill->castend_damage_id(bl, &sd->bl, RA_WUGDASH, lv, timer->gettick(), SD_LEVEL);
}
@@ -1461,7 +1462,7 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui
} else if( src->type == BL_MER && skill_id == MA_REMOVETRAP ) {
if( !battle->check_range(battle->get_master(src), target, range + 1) )
return 0; // Aegis calc remove trap based on Master position, ignoring mercenary O.O
- } else if( !battle->check_range(src, target, range + (skill_id == RG_CLOSECONFINE?0:2)) ) {
+ } else if (!battle->check_range(src, target, range)) {
return 0; // Arrow-path check failed.
}
}
@@ -1666,6 +1667,9 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui
} else
skill->castend_id(ud->skilltimer,tick,src->id,0);
+ if (sd != NULL && battle_config.prevent_logout_trigger & PLT_SKILL)
+ sd->canlog_tick = timer->gettick();
+
return 1;
}
@@ -1812,6 +1816,10 @@ int unit_skilluse_pos2( struct block_list *src, short skill_x, short skill_y, ui
ud->skilltimer = INVALID_TIMER;
skill->castend_pos(ud->skilltimer,tick,src->id,0);
}
+
+ if (sd != NULL && battle_config.prevent_logout_trigger & PLT_SKILL)
+ sd->canlog_tick = timer->gettick();
+
return 1;
}
@@ -2252,6 +2260,9 @@ int unit_attack_timer_sub(struct block_list* src, int tid, int64 tick)
ud->attacktimer = timer->add(ud->attackabletime,unit->attack_timer,src->id,0);
}
+ if (sd != NULL && battle_config.prevent_logout_trigger & PLT_ATTACK)
+ sd->canlog_tick = timer->gettick();
+
return 1;
}
diff --git a/src/plugins/HPMHooking/HPMHooking.Defs.inc b/src/plugins/HPMHooking/HPMHooking.Defs.inc
index 57abf25e0..7042a43a7 100644
--- a/src/plugins/HPMHooking/HPMHooking.Defs.inc
+++ b/src/plugins/HPMHooking/HPMHooking.Defs.inc
@@ -396,8 +396,8 @@ typedef int (*HPMHOOK_pre_chr_rename_char_sql) (struct char_session_data **sd, i
typedef int (*HPMHOOK_post_chr_rename_char_sql) (int retVal___, struct char_session_data *sd, int char_id);
typedef int (*HPMHOOK_pre_chr_check_char_name) (char **name, char **esc_name);
typedef int (*HPMHOOK_post_chr_check_char_name) (int retVal___, char *name, char *esc_name);
-typedef int (*HPMHOOK_pre_chr_make_new_char_sql) (struct char_session_data **sd, const char **name_, int *str, int *agi, int *vit, int *int_, int *dex, int *luk, int *slot, int *hair_color, int *hair_style, short *starting_job);
-typedef int (*HPMHOOK_post_chr_make_new_char_sql) (int retVal___, struct char_session_data *sd, const char *name_, int str, int agi, int vit, int int_, int dex, int luk, int slot, int hair_color, int hair_style, short starting_job);
+typedef int (*HPMHOOK_pre_chr_make_new_char_sql) (struct char_session_data **sd, const char **name_, int *str, int *agi, int *vit, int *int_, int *dex, int *luk, int *slot, int *hair_color, int *hair_style, short *starting_job, uint8 *sex);
+typedef int (*HPMHOOK_post_chr_make_new_char_sql) (int retVal___, struct char_session_data *sd, const char *name_, int str, int agi, int vit, int int_, int dex, int luk, int slot, int hair_color, int hair_style, short starting_job, uint8 sex);
typedef int (*HPMHOOK_pre_chr_divorce_char_sql) (int *partner_id1, int *partner_id2);
typedef int (*HPMHOOK_post_chr_divorce_char_sql) (int retVal___, int partner_id1, int partner_id2);
typedef int (*HPMHOOK_pre_chr_count_users) (void);
@@ -974,8 +974,8 @@ typedef void (*HPMHOOK_pre_clif_refreshlook) (struct block_list **bl, int *id, i
typedef void (*HPMHOOK_post_clif_refreshlook) (struct block_list *bl, int id, int type, int val, enum send_target target);
typedef void (*HPMHOOK_pre_clif_sendlook) (struct block_list **bl, int *id, int *type, int *val, int *val2, enum send_target *target);
typedef void (*HPMHOOK_post_clif_sendlook) (struct block_list *bl, int id, int type, int val, int val2, enum send_target target);
-typedef void (*HPMHOOK_pre_clif_class_change) (struct block_list **bl, int *class_, int *type);
-typedef void (*HPMHOOK_post_clif_class_change) (struct block_list *bl, int class_, int type);
+typedef void (*HPMHOOK_pre_clif_class_change) (struct block_list **bl, int *class_, int *type, struct map_session_data **sd);
+typedef void (*HPMHOOK_post_clif_class_change) (struct block_list *bl, int class_, int type, struct map_session_data *sd);
typedef void (*HPMHOOK_pre_clif_skill_delunit) (struct skill_unit **su);
typedef void (*HPMHOOK_post_clif_skill_delunit) (struct skill_unit *su);
typedef void (*HPMHOOK_pre_clif_skillunit_update) (struct block_list **bl);
@@ -2222,8 +2222,8 @@ typedef void (*HPMHOOK_pre_clif_pNPCMarketClosed) (int *fd, struct map_session_d
typedef void (*HPMHOOK_post_clif_pNPCMarketClosed) (int fd, struct map_session_data *sd);
typedef void (*HPMHOOK_pre_clif_pNPCMarketPurchase) (int *fd, struct map_session_data **sd);
typedef void (*HPMHOOK_post_clif_pNPCMarketPurchase) (int fd, struct map_session_data *sd);
-typedef void (*HPMHOOK_pre_clif_add_random_options) (unsigned char **buf, struct item **item);
-typedef void (*HPMHOOK_post_clif_add_random_options) (unsigned char *buf, struct item *item);
+typedef int (*HPMHOOK_pre_clif_add_item_options) (struct ItemOptions **buf, const struct item **it);
+typedef int (*HPMHOOK_post_clif_add_item_options) (int retVal___, struct ItemOptions *buf, const struct item *it);
typedef void (*HPMHOOK_pre_clif_pHotkeyRowShift) (int *fd, struct map_session_data **sd);
typedef void (*HPMHOOK_post_clif_pHotkeyRowShift) (int fd, struct map_session_data *sd);
typedef void (*HPMHOOK_pre_clif_dressroom_open) (struct map_session_data **sd, int *view);
@@ -3300,6 +3300,8 @@ typedef void (*HPMHOOK_pre_itemdb_read_chains) (void);
typedef void (*HPMHOOK_post_itemdb_read_chains) (void);
typedef void (*HPMHOOK_pre_itemdb_read_packages) (void);
typedef void (*HPMHOOK_post_itemdb_read_packages) (void);
+typedef void (*HPMHOOK_pre_itemdb_read_options) (void);
+typedef void (*HPMHOOK_post_itemdb_read_options) (void);
typedef void (*HPMHOOK_pre_itemdb_write_cached_packages) (const char **config_filename);
typedef void (*HPMHOOK_post_itemdb_write_cached_packages) (const char *config_filename);
typedef bool (*HPMHOOK_pre_itemdb_read_cached_packages) (const char **config_filename);
@@ -3316,6 +3318,8 @@ typedef struct item_data* (*HPMHOOK_pre_itemdb_search) (int *nameid);
typedef struct item_data* (*HPMHOOK_post_itemdb_search) (struct item_data* retVal___, int nameid);
typedef struct item_data* (*HPMHOOK_pre_itemdb_exists) (int *nameid);
typedef struct item_data* (*HPMHOOK_post_itemdb_exists) (struct item_data* retVal___, int nameid);
+typedef struct item_option* (*HPMHOOK_pre_itemdb_option_exists) (int *idx);
+typedef struct item_option* (*HPMHOOK_post_itemdb_option_exists) (struct item_option* retVal___, int idx);
typedef bool (*HPMHOOK_pre_itemdb_in_group) (struct item_group **group, int *nameid);
typedef bool (*HPMHOOK_post_itemdb_in_group) (bool retVal___, struct item_group *group, int nameid);
typedef int (*HPMHOOK_pre_itemdb_group_item) (struct item_group **group);
@@ -3380,6 +3384,8 @@ typedef int (*HPMHOOK_pre_itemdb_gendercheck) (struct item_data **id);
typedef int (*HPMHOOK_post_itemdb_gendercheck) (int retVal___, struct item_data *id);
typedef int (*HPMHOOK_pre_itemdb_validate_entry) (struct item_data **entry, int *n, const char **source);
typedef int (*HPMHOOK_post_itemdb_validate_entry) (int retVal___, struct item_data *entry, int n, const char *source);
+typedef void (*HPMHOOK_pre_itemdb_readdb_options_additional_fields) (struct item_option **ito, struct config_setting_t **t, const char **source);
+typedef void (*HPMHOOK_post_itemdb_readdb_options_additional_fields) (struct item_option *ito, struct config_setting_t *t, const char *source);
typedef void (*HPMHOOK_pre_itemdb_readdb_additional_fields) (int *itemid, struct config_setting_t **it, int *n, const char **source);
typedef void (*HPMHOOK_post_itemdb_readdb_additional_fields) (int itemid, struct config_setting_t *it, int n, const char *source);
typedef void (*HPMHOOK_pre_itemdb_readdb_job_sub) (struct item_data **id, struct config_setting_t **t);
@@ -3396,6 +3402,8 @@ typedef void (*HPMHOOK_pre_itemdb_destroy_item_data) (struct item_data **self, i
typedef void (*HPMHOOK_post_itemdb_destroy_item_data) (struct item_data *self, int free_self);
typedef int (*HPMHOOK_pre_itemdb_final_sub) (union DBKey *key, struct DBData **data, va_list ap);
typedef int (*HPMHOOK_post_itemdb_final_sub) (int retVal___, union DBKey key, struct DBData *data, va_list ap);
+typedef int (*HPMHOOK_pre_itemdb_options_final_sub) (union DBKey *key, struct DBData **data, va_list ap);
+typedef int (*HPMHOOK_post_itemdb_options_final_sub) (int retVal___, union DBKey key, struct DBData *data, va_list ap);
typedef void (*HPMHOOK_pre_itemdb_clear) (bool *total);
typedef void (*HPMHOOK_post_itemdb_clear) (bool total);
typedef struct item_combo* (*HPMHOOK_pre_itemdb_id2combo) (unsigned short *id);
@@ -5790,6 +5798,8 @@ typedef struct script_data* (*HPMHOOK_pre_script_get_val) (struct script_state *
typedef struct script_data* (*HPMHOOK_post_script_get_val) (struct script_data* retVal___, struct script_state *st, struct script_data *data);
typedef char* (*HPMHOOK_pre_script_get_val_ref_str) (struct script_state **st, struct reg_db **n, struct script_data **data);
typedef char* (*HPMHOOK_post_script_get_val_ref_str) (char* retVal___, struct script_state *st, struct reg_db *n, struct script_data *data);
+typedef char* (*HPMHOOK_pre_script_get_val_pc_ref_str) (struct script_state **st, struct reg_db **n, struct script_data **data);
+typedef char* (*HPMHOOK_post_script_get_val_pc_ref_str) (char* retVal___, struct script_state *st, struct reg_db *n, struct script_data *data);
typedef char* (*HPMHOOK_pre_script_get_val_scope_str) (struct script_state **st, struct reg_db **n, struct script_data **data);
typedef char* (*HPMHOOK_post_script_get_val_scope_str) (char* retVal___, struct script_state *st, struct reg_db *n, struct script_data *data);
typedef char* (*HPMHOOK_pre_script_get_val_npc_str) (struct script_state **st, struct reg_db **n, struct script_data **data);
@@ -5798,6 +5808,8 @@ typedef char* (*HPMHOOK_pre_script_get_val_instance_str) (struct script_state **
typedef char* (*HPMHOOK_post_script_get_val_instance_str) (char* retVal___, struct script_state *st, const char *name, struct script_data *data);
typedef int (*HPMHOOK_pre_script_get_val_ref_num) (struct script_state **st, struct reg_db **n, struct script_data **data);
typedef int (*HPMHOOK_post_script_get_val_ref_num) (int retVal___, struct script_state *st, struct reg_db *n, struct script_data *data);
+typedef int (*HPMHOOK_pre_script_get_val_pc_ref_num) (struct script_state **st, struct reg_db **n, struct script_data **data);
+typedef int (*HPMHOOK_post_script_get_val_pc_ref_num) (int retVal___, struct script_state *st, struct reg_db *n, struct script_data *data);
typedef int (*HPMHOOK_pre_script_get_val_scope_num) (struct script_state **st, struct reg_db **n, struct script_data **data);
typedef int (*HPMHOOK_post_script_get_val_scope_num) (int retVal___, struct script_state *st, struct reg_db *n, struct script_data *data);
typedef int (*HPMHOOK_pre_script_get_val_npc_num) (struct script_state **st, struct reg_db **n, struct script_data **data);
@@ -5952,6 +5964,8 @@ typedef int (*HPMHOOK_pre_script_set_reg) (struct script_state **st, struct map_
typedef int (*HPMHOOK_post_script_set_reg) (int retVal___, struct script_state *st, struct map_session_data *sd, int64 num, const char *name, const void *value, struct reg_db *ref);
typedef void (*HPMHOOK_pre_script_set_reg_ref_str) (struct script_state **st, struct reg_db **n, int64 *num, const char **name, const char **str);
typedef void (*HPMHOOK_post_script_set_reg_ref_str) (struct script_state *st, struct reg_db *n, int64 num, const char *name, const char *str);
+typedef void (*HPMHOOK_pre_script_set_reg_pc_ref_str) (struct script_state **st, struct reg_db **n, int64 *num, const char **name, const char **str);
+typedef void (*HPMHOOK_post_script_set_reg_pc_ref_str) (struct script_state *st, struct reg_db *n, int64 num, const char *name, const char *str);
typedef void (*HPMHOOK_pre_script_set_reg_scope_str) (struct script_state **st, struct reg_db **n, int64 *num, const char **name, const char **str);
typedef void (*HPMHOOK_post_script_set_reg_scope_str) (struct script_state *st, struct reg_db *n, int64 num, const char *name, const char *str);
typedef void (*HPMHOOK_pre_script_set_reg_npc_str) (struct script_state **st, struct reg_db **n, int64 *num, const char **name, const char **str);
@@ -5960,6 +5974,8 @@ typedef void (*HPMHOOK_pre_script_set_reg_instance_str) (struct script_state **s
typedef void (*HPMHOOK_post_script_set_reg_instance_str) (struct script_state *st, int64 num, const char *name, const char *str);
typedef void (*HPMHOOK_pre_script_set_reg_ref_num) (struct script_state **st, struct reg_db **n, int64 *num, const char **name, int *val);
typedef void (*HPMHOOK_post_script_set_reg_ref_num) (struct script_state *st, struct reg_db *n, int64 num, const char *name, int val);
+typedef void (*HPMHOOK_pre_script_set_reg_pc_ref_num) (struct script_state **st, struct reg_db **n, int64 *num, const char **name, int *val);
+typedef void (*HPMHOOK_post_script_set_reg_pc_ref_num) (struct script_state *st, struct reg_db *n, int64 num, const char *name, int val);
typedef void (*HPMHOOK_pre_script_set_reg_scope_num) (struct script_state **st, struct reg_db **n, int64 *num, const char **name, int *val);
typedef void (*HPMHOOK_post_script_set_reg_scope_num) (struct script_state *st, struct reg_db *n, int64 num, const char *name, int val);
typedef void (*HPMHOOK_pre_script_set_reg_npc_num) (struct script_state **st, struct reg_db **n, int64 *num, const char **name, int *val);
diff --git a/src/plugins/HPMHooking/HPMHooking_char.Hooks.inc b/src/plugins/HPMHooking/HPMHooking_char.Hooks.inc
index e2108c8f8..3942693da 100644
--- a/src/plugins/HPMHooking/HPMHooking_char.Hooks.inc
+++ b/src/plugins/HPMHooking/HPMHooking_char.Hooks.inc
@@ -744,15 +744,15 @@ int HP_chr_check_char_name(char *name, char *esc_name) {
}
return retVal___;
}
-int HP_chr_make_new_char_sql(struct char_session_data *sd, const char *name_, int str, int agi, int vit, int int_, int dex, int luk, int slot, int hair_color, int hair_style, short starting_job) {
+int HP_chr_make_new_char_sql(struct char_session_data *sd, const char *name_, int str, int agi, int vit, int int_, int dex, int luk, int slot, int hair_color, int hair_style, short starting_job, uint8 sex) {
int hIndex = 0;
int retVal___ = 0;
if( HPMHooks.count.HP_chr_make_new_char_sql_pre ) {
- int (*preHookFunc) (struct char_session_data **sd, const char **name_, int *str, int *agi, int *vit, int *int_, int *dex, int *luk, int *slot, int *hair_color, int *hair_style, short *starting_job);
+ int (*preHookFunc) (struct char_session_data **sd, const char **name_, int *str, int *agi, int *vit, int *int_, int *dex, int *luk, int *slot, int *hair_color, int *hair_style, short *starting_job, uint8 *sex);
*HPMforce_return = false;
for(hIndex = 0; hIndex < HPMHooks.count.HP_chr_make_new_char_sql_pre; hIndex++ ) {
preHookFunc = HPMHooks.list.HP_chr_make_new_char_sql_pre[hIndex].func;
- retVal___ = preHookFunc(&sd, &name_, &str, &agi, &vit, &int_, &dex, &luk, &slot, &hair_color, &hair_style, &starting_job);
+ retVal___ = preHookFunc(&sd, &name_, &str, &agi, &vit, &int_, &dex, &luk, &slot, &hair_color, &hair_style, &starting_job, &sex);
}
if( *HPMforce_return ) {
*HPMforce_return = false;
@@ -760,13 +760,13 @@ int HP_chr_make_new_char_sql(struct char_session_data *sd, const char *name_, in
}
}
{
- retVal___ = HPMHooks.source.chr.make_new_char_sql(sd, name_, str, agi, vit, int_, dex, luk, slot, hair_color, hair_style, starting_job);
+ retVal___ = HPMHooks.source.chr.make_new_char_sql(sd, name_, str, agi, vit, int_, dex, luk, slot, hair_color, hair_style, starting_job, sex);
}
if( HPMHooks.count.HP_chr_make_new_char_sql_post ) {
- int (*postHookFunc) (int retVal___, struct char_session_data *sd, const char *name_, int str, int agi, int vit, int int_, int dex, int luk, int slot, int hair_color, int hair_style, short starting_job);
+ int (*postHookFunc) (int retVal___, struct char_session_data *sd, const char *name_, int str, int agi, int vit, int int_, int dex, int luk, int slot, int hair_color, int hair_style, short starting_job, uint8 sex);
for(hIndex = 0; hIndex < HPMHooks.count.HP_chr_make_new_char_sql_post; hIndex++ ) {
postHookFunc = HPMHooks.list.HP_chr_make_new_char_sql_post[hIndex].func;
- retVal___ = postHookFunc(retVal___, sd, name_, str, agi, vit, int_, dex, luk, slot, hair_color, hair_style, starting_job);
+ retVal___ = postHookFunc(retVal___, sd, name_, str, agi, vit, int_, dex, luk, slot, hair_color, hair_style, starting_job, sex);
}
}
return retVal___;
diff --git a/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc b/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc
index bd055cac2..762acb747 100644
--- a/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc
+++ b/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc
@@ -1860,8 +1860,8 @@ struct {
struct HPMHookPoint *HP_clif_pNPCMarketClosed_post;
struct HPMHookPoint *HP_clif_pNPCMarketPurchase_pre;
struct HPMHookPoint *HP_clif_pNPCMarketPurchase_post;
- struct HPMHookPoint *HP_clif_add_random_options_pre;
- struct HPMHookPoint *HP_clif_add_random_options_post;
+ struct HPMHookPoint *HP_clif_add_item_options_pre;
+ struct HPMHookPoint *HP_clif_add_item_options_post;
struct HPMHookPoint *HP_clif_pHotkeyRowShift_pre;
struct HPMHookPoint *HP_clif_pHotkeyRowShift_post;
struct HPMHookPoint *HP_clif_dressroom_open_pre;
@@ -2682,6 +2682,8 @@ struct {
struct HPMHookPoint *HP_itemdb_read_chains_post;
struct HPMHookPoint *HP_itemdb_read_packages_pre;
struct HPMHookPoint *HP_itemdb_read_packages_post;
+ struct HPMHookPoint *HP_itemdb_read_options_pre;
+ struct HPMHookPoint *HP_itemdb_read_options_post;
struct HPMHookPoint *HP_itemdb_write_cached_packages_pre;
struct HPMHookPoint *HP_itemdb_write_cached_packages_post;
struct HPMHookPoint *HP_itemdb_read_cached_packages_pre;
@@ -2698,6 +2700,8 @@ struct {
struct HPMHookPoint *HP_itemdb_search_post;
struct HPMHookPoint *HP_itemdb_exists_pre;
struct HPMHookPoint *HP_itemdb_exists_post;
+ struct HPMHookPoint *HP_itemdb_option_exists_pre;
+ struct HPMHookPoint *HP_itemdb_option_exists_post;
struct HPMHookPoint *HP_itemdb_in_group_pre;
struct HPMHookPoint *HP_itemdb_in_group_post;
struct HPMHookPoint *HP_itemdb_group_item_pre;
@@ -2762,6 +2766,8 @@ struct {
struct HPMHookPoint *HP_itemdb_gendercheck_post;
struct HPMHookPoint *HP_itemdb_validate_entry_pre;
struct HPMHookPoint *HP_itemdb_validate_entry_post;
+ struct HPMHookPoint *HP_itemdb_readdb_options_additional_fields_pre;
+ struct HPMHookPoint *HP_itemdb_readdb_options_additional_fields_post;
struct HPMHookPoint *HP_itemdb_readdb_additional_fields_pre;
struct HPMHookPoint *HP_itemdb_readdb_additional_fields_post;
struct HPMHookPoint *HP_itemdb_readdb_job_sub_pre;
@@ -2778,6 +2784,8 @@ struct {
struct HPMHookPoint *HP_itemdb_destroy_item_data_post;
struct HPMHookPoint *HP_itemdb_final_sub_pre;
struct HPMHookPoint *HP_itemdb_final_sub_post;
+ struct HPMHookPoint *HP_itemdb_options_final_sub_pre;
+ struct HPMHookPoint *HP_itemdb_options_final_sub_post;
struct HPMHookPoint *HP_itemdb_clear_pre;
struct HPMHookPoint *HP_itemdb_clear_post;
struct HPMHookPoint *HP_itemdb_id2combo_pre;
@@ -4586,6 +4594,8 @@ struct {
struct HPMHookPoint *HP_script_get_val_post;
struct HPMHookPoint *HP_script_get_val_ref_str_pre;
struct HPMHookPoint *HP_script_get_val_ref_str_post;
+ struct HPMHookPoint *HP_script_get_val_pc_ref_str_pre;
+ struct HPMHookPoint *HP_script_get_val_pc_ref_str_post;
struct HPMHookPoint *HP_script_get_val_scope_str_pre;
struct HPMHookPoint *HP_script_get_val_scope_str_post;
struct HPMHookPoint *HP_script_get_val_npc_str_pre;
@@ -4594,6 +4604,8 @@ struct {
struct HPMHookPoint *HP_script_get_val_instance_str_post;
struct HPMHookPoint *HP_script_get_val_ref_num_pre;
struct HPMHookPoint *HP_script_get_val_ref_num_post;
+ struct HPMHookPoint *HP_script_get_val_pc_ref_num_pre;
+ struct HPMHookPoint *HP_script_get_val_pc_ref_num_post;
struct HPMHookPoint *HP_script_get_val_scope_num_pre;
struct HPMHookPoint *HP_script_get_val_scope_num_post;
struct HPMHookPoint *HP_script_get_val_npc_num_pre;
@@ -4748,6 +4760,8 @@ struct {
struct HPMHookPoint *HP_script_set_reg_post;
struct HPMHookPoint *HP_script_set_reg_ref_str_pre;
struct HPMHookPoint *HP_script_set_reg_ref_str_post;
+ struct HPMHookPoint *HP_script_set_reg_pc_ref_str_pre;
+ struct HPMHookPoint *HP_script_set_reg_pc_ref_str_post;
struct HPMHookPoint *HP_script_set_reg_scope_str_pre;
struct HPMHookPoint *HP_script_set_reg_scope_str_post;
struct HPMHookPoint *HP_script_set_reg_npc_str_pre;
@@ -4756,6 +4770,8 @@ struct {
struct HPMHookPoint *HP_script_set_reg_instance_str_post;
struct HPMHookPoint *HP_script_set_reg_ref_num_pre;
struct HPMHookPoint *HP_script_set_reg_ref_num_post;
+ struct HPMHookPoint *HP_script_set_reg_pc_ref_num_pre;
+ struct HPMHookPoint *HP_script_set_reg_pc_ref_num_post;
struct HPMHookPoint *HP_script_set_reg_scope_num_pre;
struct HPMHookPoint *HP_script_set_reg_scope_num_post;
struct HPMHookPoint *HP_script_set_reg_npc_num_pre;
@@ -7899,8 +7915,8 @@ struct {
int HP_clif_pNPCMarketClosed_post;
int HP_clif_pNPCMarketPurchase_pre;
int HP_clif_pNPCMarketPurchase_post;
- int HP_clif_add_random_options_pre;
- int HP_clif_add_random_options_post;
+ int HP_clif_add_item_options_pre;
+ int HP_clif_add_item_options_post;
int HP_clif_pHotkeyRowShift_pre;
int HP_clif_pHotkeyRowShift_post;
int HP_clif_dressroom_open_pre;
@@ -8721,6 +8737,8 @@ struct {
int HP_itemdb_read_chains_post;
int HP_itemdb_read_packages_pre;
int HP_itemdb_read_packages_post;
+ int HP_itemdb_read_options_pre;
+ int HP_itemdb_read_options_post;
int HP_itemdb_write_cached_packages_pre;
int HP_itemdb_write_cached_packages_post;
int HP_itemdb_read_cached_packages_pre;
@@ -8737,6 +8755,8 @@ struct {
int HP_itemdb_search_post;
int HP_itemdb_exists_pre;
int HP_itemdb_exists_post;
+ int HP_itemdb_option_exists_pre;
+ int HP_itemdb_option_exists_post;
int HP_itemdb_in_group_pre;
int HP_itemdb_in_group_post;
int HP_itemdb_group_item_pre;
@@ -8801,6 +8821,8 @@ struct {
int HP_itemdb_gendercheck_post;
int HP_itemdb_validate_entry_pre;
int HP_itemdb_validate_entry_post;
+ int HP_itemdb_readdb_options_additional_fields_pre;
+ int HP_itemdb_readdb_options_additional_fields_post;
int HP_itemdb_readdb_additional_fields_pre;
int HP_itemdb_readdb_additional_fields_post;
int HP_itemdb_readdb_job_sub_pre;
@@ -8817,6 +8839,8 @@ struct {
int HP_itemdb_destroy_item_data_post;
int HP_itemdb_final_sub_pre;
int HP_itemdb_final_sub_post;
+ int HP_itemdb_options_final_sub_pre;
+ int HP_itemdb_options_final_sub_post;
int HP_itemdb_clear_pre;
int HP_itemdb_clear_post;
int HP_itemdb_id2combo_pre;
@@ -10625,6 +10649,8 @@ struct {
int HP_script_get_val_post;
int HP_script_get_val_ref_str_pre;
int HP_script_get_val_ref_str_post;
+ int HP_script_get_val_pc_ref_str_pre;
+ int HP_script_get_val_pc_ref_str_post;
int HP_script_get_val_scope_str_pre;
int HP_script_get_val_scope_str_post;
int HP_script_get_val_npc_str_pre;
@@ -10633,6 +10659,8 @@ struct {
int HP_script_get_val_instance_str_post;
int HP_script_get_val_ref_num_pre;
int HP_script_get_val_ref_num_post;
+ int HP_script_get_val_pc_ref_num_pre;
+ int HP_script_get_val_pc_ref_num_post;
int HP_script_get_val_scope_num_pre;
int HP_script_get_val_scope_num_post;
int HP_script_get_val_npc_num_pre;
@@ -10787,6 +10815,8 @@ struct {
int HP_script_set_reg_post;
int HP_script_set_reg_ref_str_pre;
int HP_script_set_reg_ref_str_post;
+ int HP_script_set_reg_pc_ref_str_pre;
+ int HP_script_set_reg_pc_ref_str_post;
int HP_script_set_reg_scope_str_pre;
int HP_script_set_reg_scope_str_post;
int HP_script_set_reg_npc_str_pre;
@@ -10795,6 +10825,8 @@ struct {
int HP_script_set_reg_instance_str_post;
int HP_script_set_reg_ref_num_pre;
int HP_script_set_reg_ref_num_post;
+ int HP_script_set_reg_pc_ref_num_pre;
+ int HP_script_set_reg_pc_ref_num_post;
int HP_script_set_reg_scope_num_pre;
int HP_script_set_reg_scope_num_post;
int HP_script_set_reg_npc_num_pre;
diff --git a/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc b/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc
index 53f65bcd3..65cd9ea82 100644
--- a/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc
+++ b/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc
@@ -952,7 +952,7 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(clif->pNPCShopClosed, HP_clif_pNPCShopClosed) },
{ HP_POP(clif->pNPCMarketClosed, HP_clif_pNPCMarketClosed) },
{ HP_POP(clif->pNPCMarketPurchase, HP_clif_pNPCMarketPurchase) },
- { HP_POP(clif->add_random_options, HP_clif_add_random_options) },
+ { HP_POP(clif->add_item_options, HP_clif_add_item_options) },
{ HP_POP(clif->pHotkeyRowShift, HP_clif_pHotkeyRowShift) },
{ HP_POP(clif->dressroom_open, HP_clif_dressroom_open) },
{ HP_POP(clif->pOneClick_ItemIdentify, HP_clif_pOneClick_ItemIdentify) },
@@ -1378,6 +1378,7 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(itemdb->read_groups, HP_itemdb_read_groups) },
{ HP_POP(itemdb->read_chains, HP_itemdb_read_chains) },
{ HP_POP(itemdb->read_packages, HP_itemdb_read_packages) },
+ { HP_POP(itemdb->read_options, HP_itemdb_read_options) },
{ HP_POP(itemdb->write_cached_packages, HP_itemdb_write_cached_packages) },
{ HP_POP(itemdb->read_cached_packages, HP_itemdb_read_cached_packages) },
{ HP_POP(itemdb->name2id, HP_itemdb_name2id) },
@@ -1386,6 +1387,7 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(itemdb->load, HP_itemdb_load) },
{ HP_POP(itemdb->search, HP_itemdb_search) },
{ HP_POP(itemdb->exists, HP_itemdb_exists) },
+ { HP_POP(itemdb->option_exists, HP_itemdb_option_exists) },
{ HP_POP(itemdb->in_group, HP_itemdb_in_group) },
{ HP_POP(itemdb->group_item, HP_itemdb_group_item) },
{ HP_POP(itemdb->chain_item, HP_itemdb_chain_item) },
@@ -1418,6 +1420,7 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(itemdb->read_combos, HP_itemdb_read_combos) },
{ HP_POP(itemdb->gendercheck, HP_itemdb_gendercheck) },
{ HP_POP(itemdb->validate_entry, HP_itemdb_validate_entry) },
+ { HP_POP(itemdb->readdb_options_additional_fields, HP_itemdb_readdb_options_additional_fields) },
{ HP_POP(itemdb->readdb_additional_fields, HP_itemdb_readdb_additional_fields) },
{ HP_POP(itemdb->readdb_job_sub, HP_itemdb_readdb_job_sub) },
{ HP_POP(itemdb->readdb_libconfig_sub, HP_itemdb_readdb_libconfig_sub) },
@@ -1426,6 +1429,7 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(itemdb->read, HP_itemdb_read) },
{ HP_POP(itemdb->destroy_item_data, HP_itemdb_destroy_item_data) },
{ HP_POP(itemdb->final_sub, HP_itemdb_final_sub) },
+ { HP_POP(itemdb->options_final_sub, HP_itemdb_options_final_sub) },
{ HP_POP(itemdb->clear, HP_itemdb_clear) },
{ HP_POP(itemdb->id2combo, HP_itemdb_id2combo) },
{ HP_POP(itemdb->is_item_usable, HP_itemdb_is_item_usable) },
@@ -2353,10 +2357,12 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(script->push_val, HP_script_push_val) },
{ HP_POP(script->get_val, HP_script_get_val) },
{ HP_POP(script->get_val_ref_str, HP_script_get_val_ref_str) },
+ { HP_POP(script->get_val_pc_ref_str, HP_script_get_val_pc_ref_str) },
{ HP_POP(script->get_val_scope_str, HP_script_get_val_scope_str) },
{ HP_POP(script->get_val_npc_str, HP_script_get_val_npc_str) },
{ HP_POP(script->get_val_instance_str, HP_script_get_val_instance_str) },
{ HP_POP(script->get_val_ref_num, HP_script_get_val_ref_num) },
+ { HP_POP(script->get_val_pc_ref_num, HP_script_get_val_pc_ref_num) },
{ HP_POP(script->get_val_scope_num, HP_script_get_val_scope_num) },
{ HP_POP(script->get_val_npc_num, HP_script_get_val_npc_num) },
{ HP_POP(script->get_val_instance_num, HP_script_get_val_instance_num) },
@@ -2434,10 +2440,12 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(script->errorwarning_sub, HP_script_errorwarning_sub) },
{ HP_POP(script->set_reg, HP_script_set_reg) },
{ HP_POP(script->set_reg_ref_str, HP_script_set_reg_ref_str) },
+ { HP_POP(script->set_reg_pc_ref_str, HP_script_set_reg_pc_ref_str) },
{ HP_POP(script->set_reg_scope_str, HP_script_set_reg_scope_str) },
{ HP_POP(script->set_reg_npc_str, HP_script_set_reg_npc_str) },
{ HP_POP(script->set_reg_instance_str, HP_script_set_reg_instance_str) },
{ HP_POP(script->set_reg_ref_num, HP_script_set_reg_ref_num) },
+ { HP_POP(script->set_reg_pc_ref_num, HP_script_set_reg_pc_ref_num) },
{ HP_POP(script->set_reg_scope_num, HP_script_set_reg_scope_num) },
{ HP_POP(script->set_reg_npc_num, HP_script_set_reg_npc_num) },
{ HP_POP(script->set_reg_instance_num, HP_script_set_reg_instance_num) },
diff --git a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc
index 654c902d8..3175bab5e 100644
--- a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc
+++ b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc
@@ -7917,14 +7917,14 @@ void HP_clif_sendlook(struct block_list *bl, int id, int type, int val, int val2
}
return;
}
-void HP_clif_class_change(struct block_list *bl, int class_, int type) {
+void HP_clif_class_change(struct block_list *bl, int class_, int type, struct map_session_data *sd) {
int hIndex = 0;
if( HPMHooks.count.HP_clif_class_change_pre ) {
- void (*preHookFunc) (struct block_list **bl, int *class_, int *type);
+ void (*preHookFunc) (struct block_list **bl, int *class_, int *type, struct map_session_data **sd);
*HPMforce_return = false;
for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_class_change_pre; hIndex++ ) {
preHookFunc = HPMHooks.list.HP_clif_class_change_pre[hIndex].func;
- preHookFunc(&bl, &class_, &type);
+ preHookFunc(&bl, &class_, &type, &sd);
}
if( *HPMforce_return ) {
*HPMforce_return = false;
@@ -7932,13 +7932,13 @@ void HP_clif_class_change(struct block_list *bl, int class_, int type) {
}
}
{
- HPMHooks.source.clif.class_change(bl, class_, type);
+ HPMHooks.source.clif.class_change(bl, class_, type, sd);
}
if( HPMHooks.count.HP_clif_class_change_post ) {
- void (*postHookFunc) (struct block_list *bl, int class_, int type);
+ void (*postHookFunc) (struct block_list *bl, int class_, int type, struct map_session_data *sd);
for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_class_change_post; hIndex++ ) {
postHookFunc = HPMHooks.list.HP_clif_class_change_post[hIndex].func;
- postHookFunc(bl, class_, type);
+ postHookFunc(bl, class_, type, sd);
}
}
return;
@@ -24201,31 +24201,32 @@ void HP_clif_pNPCMarketPurchase(int fd, struct map_session_data *sd) {
}
return;
}
-void HP_clif_add_random_options(unsigned char *buf, struct item *item) {
+int HP_clif_add_item_options(struct ItemOptions *buf, const struct item *it) {
int hIndex = 0;
- if( HPMHooks.count.HP_clif_add_random_options_pre ) {
- void (*preHookFunc) (unsigned char **buf, struct item **item);
+ int retVal___ = 0;
+ if( HPMHooks.count.HP_clif_add_item_options_pre ) {
+ int (*preHookFunc) (struct ItemOptions **buf, const struct item **it);
*HPMforce_return = false;
- for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_add_random_options_pre; hIndex++ ) {
- preHookFunc = HPMHooks.list.HP_clif_add_random_options_pre[hIndex].func;
- preHookFunc(&buf, &item);
+ for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_add_item_options_pre; hIndex++ ) {
+ preHookFunc = HPMHooks.list.HP_clif_add_item_options_pre[hIndex].func;
+ retVal___ = preHookFunc(&buf, &it);
}
if( *HPMforce_return ) {
*HPMforce_return = false;
- return;
+ return retVal___;
}
}
{
- HPMHooks.source.clif.add_random_options(buf, item);
+ retVal___ = HPMHooks.source.clif.add_item_options(buf, it);
}
- if( HPMHooks.count.HP_clif_add_random_options_post ) {
- void (*postHookFunc) (unsigned char *buf, struct item *item);
- for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_add_random_options_post; hIndex++ ) {
- postHookFunc = HPMHooks.list.HP_clif_add_random_options_post[hIndex].func;
- postHookFunc(buf, item);
+ if( HPMHooks.count.HP_clif_add_item_options_post ) {
+ int (*postHookFunc) (int retVal___, struct ItemOptions *buf, const struct item *it);
+ for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_add_item_options_post; hIndex++ ) {
+ postHookFunc = HPMHooks.list.HP_clif_add_item_options_post[hIndex].func;
+ retVal___ = postHookFunc(retVal___, buf, it);
}
}
- return;
+ return retVal___;
}
void HP_clif_pHotkeyRowShift(int fd, struct map_session_data *sd) {
int hIndex = 0;
@@ -35242,6 +35243,32 @@ void HP_itemdb_read_packages(void) {
}
return;
}
+void HP_itemdb_read_options(void) {
+ int hIndex = 0;
+ if( HPMHooks.count.HP_itemdb_read_options_pre ) {
+ void (*preHookFunc) (void);
+ *HPMforce_return = false;
+ for(hIndex = 0; hIndex < HPMHooks.count.HP_itemdb_read_options_pre; hIndex++ ) {
+ preHookFunc = HPMHooks.list.HP_itemdb_read_options_pre[hIndex].func;
+ preHookFunc();
+ }
+ if( *HPMforce_return ) {
+ *HPMforce_return = false;
+ return;
+ }
+ }
+ {
+ HPMHooks.source.itemdb.read_options();
+ }
+ if( HPMHooks.count.HP_itemdb_read_options_post ) {
+ void (*postHookFunc) (void);
+ for(hIndex = 0; hIndex < HPMHooks.count.HP_itemdb_read_options_post; hIndex++ ) {
+ postHookFunc = HPMHooks.list.HP_itemdb_read_options_post[hIndex].func;
+ postHookFunc();
+ }
+ }
+ return;
+}
void HP_itemdb_write_cached_packages(const char *config_filename) {
int hIndex = 0;
if( HPMHooks.count.HP_itemdb_write_cached_packages_pre ) {
@@ -35457,6 +35484,33 @@ struct item_data* HP_itemdb_exists(int nameid) {
}
return retVal___;
}
+struct item_option* HP_itemdb_option_exists(int idx) {
+ int hIndex = 0;
+ struct item_option* retVal___ = NULL;
+ if( HPMHooks.count.HP_itemdb_option_exists_pre ) {
+ struct item_option* (*preHookFunc) (int *idx);
+ *HPMforce_return = false;
+ for(hIndex = 0; hIndex < HPMHooks.count.HP_itemdb_option_exists_pre; hIndex++ ) {
+ preHookFunc = HPMHooks.list.HP_itemdb_option_exists_pre[hIndex].func;
+ retVal___ = preHookFunc(&idx);
+ }
+ if( *HPMforce_return ) {
+ *HPMforce_return = false;
+ return retVal___;
+ }
+ }
+ {
+ retVal___ = HPMHooks.source.itemdb.option_exists(idx);
+ }
+ if( HPMHooks.count.HP_itemdb_option_exists_post ) {
+ struct item_option* (*postHookFunc) (struct item_option* retVal___, int idx);
+ for(hIndex = 0; hIndex < HPMHooks.count.HP_itemdb_option_exists_post; hIndex++ ) {
+ postHookFunc = HPMHooks.list.HP_itemdb_option_exists_post[hIndex].func;
+ retVal___ = postHookFunc(retVal___, idx);
+ }
+ }
+ return retVal___;
+}
bool HP_itemdb_in_group(struct item_group *group, int nameid) {
int hIndex = 0;
bool retVal___ = false;
@@ -36328,6 +36382,32 @@ int HP_itemdb_validate_entry(struct item_data *entry, int n, const char *source)
}
return retVal___;
}
+void HP_itemdb_readdb_options_additional_fields(struct item_option *ito, struct config_setting_t *t, const char *source) {
+ int hIndex = 0;
+ if( HPMHooks.count.HP_itemdb_readdb_options_additional_fields_pre ) {
+ void (*preHookFunc) (struct item_option **ito, struct config_setting_t **t, const char **source);
+ *HPMforce_return = false;
+ for(hIndex = 0; hIndex < HPMHooks.count.HP_itemdb_readdb_options_additional_fields_pre; hIndex++ ) {
+ preHookFunc = HPMHooks.list.HP_itemdb_readdb_options_additional_fields_pre[hIndex].func;
+ preHookFunc(&ito, &t, &source);
+ }
+ if( *HPMforce_return ) {
+ *HPMforce_return = false;
+ return;
+ }
+ }
+ {
+ HPMHooks.source.itemdb.readdb_options_additional_fields(ito, t, source);
+ }
+ if( HPMHooks.count.HP_itemdb_readdb_options_additional_fields_post ) {
+ void (*postHookFunc) (struct item_option *ito, struct config_setting_t *t, const char *source);
+ for(hIndex = 0; hIndex < HPMHooks.count.HP_itemdb_readdb_options_additional_fields_post; hIndex++ ) {
+ postHookFunc = HPMHooks.list.HP_itemdb_readdb_options_additional_fields_post[hIndex].func;
+ postHookFunc(ito, t, source);
+ }
+ }
+ return;
+}
void HP_itemdb_readdb_additional_fields(int itemid, struct config_setting_t *it, int n, const char *source) {
int hIndex = 0;
if( HPMHooks.count.HP_itemdb_readdb_additional_fields_pre ) {
@@ -36546,6 +36626,39 @@ int HP_itemdb_final_sub(union DBKey key, struct DBData *data, va_list ap) {
}
return retVal___;
}
+int HP_itemdb_options_final_sub(union DBKey key, struct DBData *data, va_list ap) {
+ int hIndex = 0;
+ int retVal___ = 0;
+ if( HPMHooks.count.HP_itemdb_options_final_sub_pre ) {
+ int (*preHookFunc) (union DBKey *key, struct DBData **data, va_list ap);
+ *HPMforce_return = false;
+ for(hIndex = 0; hIndex < HPMHooks.count.HP_itemdb_options_final_sub_pre; hIndex++ ) {
+ va_list ap___copy; va_copy(ap___copy, ap);
+ preHookFunc = HPMHooks.list.HP_itemdb_options_final_sub_pre[hIndex].func;
+ retVal___ = preHookFunc(&key, &data, ap___copy);
+ va_end(ap___copy);
+ }
+ if( *HPMforce_return ) {
+ *HPMforce_return = false;
+ return retVal___;
+ }
+ }
+ {
+ va_list ap___copy; va_copy(ap___copy, ap);
+ retVal___ = HPMHooks.source.itemdb.options_final_sub(key, data, ap___copy);
+ va_end(ap___copy);
+ }
+ if( HPMHooks.count.HP_itemdb_options_final_sub_post ) {
+ int (*postHookFunc) (int retVal___, union DBKey key, struct DBData *data, va_list ap);
+ for(hIndex = 0; hIndex < HPMHooks.count.HP_itemdb_options_final_sub_post; hIndex++ ) {
+ va_list ap___copy; va_copy(ap___copy, ap);
+ postHookFunc = HPMHooks.list.HP_itemdb_options_final_sub_post[hIndex].func;
+ retVal___ = postHookFunc(retVal___, key, data, ap___copy);
+ va_end(ap___copy);
+ }
+ }
+ return retVal___;
+}
void HP_itemdb_clear(bool total) {
int hIndex = 0;
if( HPMHooks.count.HP_itemdb_clear_pre ) {
@@ -61137,6 +61250,33 @@ char* HP_script_get_val_ref_str(struct script_state *st, struct reg_db *n, struc
}
return retVal___;
}
+char* HP_script_get_val_pc_ref_str(struct script_state *st, struct reg_db *n, struct script_data *data) {
+ int hIndex = 0;
+ char* retVal___ = NULL;
+ if( HPMHooks.count.HP_script_get_val_pc_ref_str_pre ) {
+ char* (*preHookFunc) (struct script_state **st, struct reg_db **n, struct script_data **data);
+ *HPMforce_return = false;
+ for(hIndex = 0; hIndex < HPMHooks.count.HP_script_get_val_pc_ref_str_pre; hIndex++ ) {
+ preHookFunc = HPMHooks.list.HP_script_get_val_pc_ref_str_pre[hIndex].func;
+ retVal___ = preHookFunc(&st, &n, &data);
+ }
+ if( *HPMforce_return ) {
+ *HPMforce_return = false;
+ return retVal___;
+ }
+ }
+ {
+ retVal___ = HPMHooks.source.script.get_val_pc_ref_str(st, n, data);
+ }
+ if( HPMHooks.count.HP_script_get_val_pc_ref_str_post ) {
+ char* (*postHookFunc) (char* retVal___, struct script_state *st, struct reg_db *n, struct script_data *data);
+ for(hIndex = 0; hIndex < HPMHooks.count.HP_script_get_val_pc_ref_str_post; hIndex++ ) {
+ postHookFunc = HPMHooks.list.HP_script_get_val_pc_ref_str_post[hIndex].func;
+ retVal___ = postHookFunc(retVal___, st, n, data);
+ }
+ }
+ return retVal___;
+}
char* HP_script_get_val_scope_str(struct script_state *st, struct reg_db *n, struct script_data *data) {
int hIndex = 0;
char* retVal___ = NULL;
@@ -61245,6 +61385,33 @@ int HP_script_get_val_ref_num(struct script_state *st, struct reg_db *n, struct
}
return retVal___;
}
+int HP_script_get_val_pc_ref_num(struct script_state *st, struct reg_db *n, struct script_data *data) {
+ int hIndex = 0;
+ int retVal___ = 0;
+ if( HPMHooks.count.HP_script_get_val_pc_ref_num_pre ) {
+ int (*preHookFunc) (struct script_state **st, struct reg_db **n, struct script_data **data);
+ *HPMforce_return = false;
+ for(hIndex = 0; hIndex < HPMHooks.count.HP_script_get_val_pc_ref_num_pre; hIndex++ ) {
+ preHookFunc = HPMHooks.list.HP_script_get_val_pc_ref_num_pre[hIndex].func;
+ retVal___ = preHookFunc(&st, &n, &data);
+ }
+ if( *HPMforce_return ) {
+ *HPMforce_return = false;
+ return retVal___;
+ }
+ }
+ {
+ retVal___ = HPMHooks.source.script.get_val_pc_ref_num(st, n, data);
+ }
+ if( HPMHooks.count.HP_script_get_val_pc_ref_num_post ) {
+ int (*postHookFunc) (int retVal___, struct script_state *st, struct reg_db *n, struct script_data *data);
+ for(hIndex = 0; hIndex < HPMHooks.count.HP_script_get_val_pc_ref_num_post; hIndex++ ) {
+ postHookFunc = HPMHooks.list.HP_script_get_val_pc_ref_num_post[hIndex].func;
+ retVal___ = postHookFunc(retVal___, st, n, data);
+ }
+ }
+ return retVal___;
+}
int HP_script_get_val_scope_num(struct script_state *st, struct reg_db *n, struct script_data *data) {
int hIndex = 0;
int retVal___ = 0;
@@ -63289,6 +63456,32 @@ void HP_script_set_reg_ref_str(struct script_state *st, struct reg_db *n, int64
}
return;
}
+void HP_script_set_reg_pc_ref_str(struct script_state *st, struct reg_db *n, int64 num, const char *name, const char *str) {
+ int hIndex = 0;
+ if( HPMHooks.count.HP_script_set_reg_pc_ref_str_pre ) {
+ void (*preHookFunc) (struct script_state **st, struct reg_db **n, int64 *num, const char **name, const char **str);
+ *HPMforce_return = false;
+ for(hIndex = 0; hIndex < HPMHooks.count.HP_script_set_reg_pc_ref_str_pre; hIndex++ ) {
+ preHookFunc = HPMHooks.list.HP_script_set_reg_pc_ref_str_pre[hIndex].func;
+ preHookFunc(&st, &n, &num, &name, &str);
+ }
+ if( *HPMforce_return ) {
+ *HPMforce_return = false;
+ return;
+ }
+ }
+ {
+ HPMHooks.source.script.set_reg_pc_ref_str(st, n, num, name, str);
+ }
+ if( HPMHooks.count.HP_script_set_reg_pc_ref_str_post ) {
+ void (*postHookFunc) (struct script_state *st, struct reg_db *n, int64 num, const char *name, const char *str);
+ for(hIndex = 0; hIndex < HPMHooks.count.HP_script_set_reg_pc_ref_str_post; hIndex++ ) {
+ postHookFunc = HPMHooks.list.HP_script_set_reg_pc_ref_str_post[hIndex].func;
+ postHookFunc(st, n, num, name, str);
+ }
+ }
+ return;
+}
void HP_script_set_reg_scope_str(struct script_state *st, struct reg_db *n, int64 num, const char *name, const char *str) {
int hIndex = 0;
if( HPMHooks.count.HP_script_set_reg_scope_str_pre ) {
@@ -63393,6 +63586,32 @@ void HP_script_set_reg_ref_num(struct script_state *st, struct reg_db *n, int64
}
return;
}
+void HP_script_set_reg_pc_ref_num(struct script_state *st, struct reg_db *n, int64 num, const char *name, int val) {
+ int hIndex = 0;
+ if( HPMHooks.count.HP_script_set_reg_pc_ref_num_pre ) {
+ void (*preHookFunc) (struct script_state **st, struct reg_db **n, int64 *num, const char **name, int *val);
+ *HPMforce_return = false;
+ for(hIndex = 0; hIndex < HPMHooks.count.HP_script_set_reg_pc_ref_num_pre; hIndex++ ) {
+ preHookFunc = HPMHooks.list.HP_script_set_reg_pc_ref_num_pre[hIndex].func;
+ preHookFunc(&st, &n, &num, &name, &val);
+ }
+ if( *HPMforce_return ) {
+ *HPMforce_return = false;
+ return;
+ }
+ }
+ {
+ HPMHooks.source.script.set_reg_pc_ref_num(st, n, num, name, val);
+ }
+ if( HPMHooks.count.HP_script_set_reg_pc_ref_num_post ) {
+ void (*postHookFunc) (struct script_state *st, struct reg_db *n, int64 num, const char *name, int val);
+ for(hIndex = 0; hIndex < HPMHooks.count.HP_script_set_reg_pc_ref_num_post; hIndex++ ) {
+ postHookFunc = HPMHooks.list.HP_script_set_reg_pc_ref_num_post[hIndex].func;
+ postHookFunc(st, n, num, name, val);
+ }
+ }
+ return;
+}
void HP_script_set_reg_scope_num(struct script_state *st, struct reg_db *n, int64 num, const char *name, int val) {
int hIndex = 0;
if( HPMHooks.count.HP_script_set_reg_scope_num_pre ) {
diff --git a/src/plugins/db2sql.c b/src/plugins/db2sql.c
index f801e4147..33a62757a 100644
--- a/src/plugins/db2sql.c
+++ b/src/plugins/db2sql.c
@@ -320,6 +320,9 @@ int itemdb2sql_sub(struct config_setting_t *entry, int n, const char *source)
// refineable
StrBuf->Printf(&buf, "'%d',", it->flag.no_refine?0:1);
+
+ // disable_options
+ StrBuf->Printf(&buf, "'%d',", it->flag.no_options?1:0);
// view
StrBuf->Printf(&buf, "'%d',", it->look);
@@ -462,6 +465,7 @@ void itemdb2sql_tableheader(void)
" `equip_level_min` smallint(5) UNSIGNED DEFAULT NULL,\n"
" `equip_level_max` smallint(5) UNSIGNED DEFAULT NULL,\n"
" `refineable` tinyint(1) UNSIGNED DEFAULT NULL,\n"
+ " `disable_options` tinyint(1) UNSIGNED DEFAULT NULL,\n"
" `view` smallint(3) UNSIGNED DEFAULT NULL,\n"
" `bindonequip` tinyint(1) UNSIGNED DEFAULT NULL,\n"
" `forceserial` tinyint(1) UNSIGNED DEFAULT NULL,\n"