From d88a6aca45a068a62a9cf768ee80b4437c67a3c5 Mon Sep 17 00:00:00 2001 From: aleos89 Date: Tue, 29 Mar 2016 13:30:27 -0400 Subject: [PATCH] Optimized Inventory, Cart Inventory, and Storage usage * These storage types now mimic Guild Storage and can be loaded/saved whenever needed. * Relieves mmo_charstatus from having to send storage types and lets the char-server handle it. * All storage types now have an increased max amount. * Fixes #441 - Players will no longer be required to log out to resync cart item data before opening a Vending Store. * Refactored player weight and cart weight calculations into their own functions. * Added script commands guildstoragecountitem[2] and guildstoragedelitem[2]. * Refactored several function return types as well as documentation. Thanks to @lighta and @cydh for their help with it! --- conf/msg_conf/map_msg.conf | 2 +- conf/msg_conf/map_msg_idn.conf | 2 +- doc/packet_interserv.txt | 55 ++++ doc/script_commands.txt | 46 ++- src/char/char.c | 126 ++------ src/char/char.h | 11 +- src/char/char_clif.c | 6 +- src/char/int_auction.c | 25 +- src/char/int_storage.c | 565 +++++++++++++++++++++++++-------- src/char/int_storage.h | 15 +- src/char/inter.c | 10 +- src/common/mmo.h | 33 +- src/login/account.c | 26 +- src/map/atcommand.c | 100 +++--- src/map/battle.c | 12 +- src/map/buyingstore.c | 8 +- src/map/chrif.c | 18 +- src/map/clif.c | 248 ++++++++------- src/map/clif.h | 3 +- src/map/guild.c | 42 +-- src/map/intif.c | 286 ++++++++++++++--- src/map/intif.h | 8 +- src/map/itemdb.c | 2 +- src/map/mail.c | 18 +- src/map/map.c | 5 +- src/map/npc.c | 26 +- src/map/party.c | 2 +- src/map/pc.c | 370 +++++++++++---------- src/map/pc.h | 16 +- src/map/pet.c | 13 +- src/map/script.c | 303 +++++++++++------- src/map/skill.c | 62 ++-- src/map/status.c | 167 ++++++---- src/map/status.h | 2 + src/map/storage.c | 309 +++++++++--------- src/map/storage.h | 33 +- src/map/trade.c | 18 +- src/map/unit.c | 2 +- src/map/vending.c | 48 ++- 39 files changed, 1820 insertions(+), 1223 deletions(-) diff --git a/conf/msg_conf/map_msg.conf b/conf/msg_conf/map_msg.conf index 78500e307e..742f964977 100644 --- a/conf/msg_conf/map_msg.conf +++ b/conf/msg_conf/map_msg.conf @@ -770,7 +770,7 @@ 732: Item cannot be opened when your inventory is full. -733: Item '%s' has not yet saved to your cart. Please re-log in order to correctly save your Vending information. +//733 free // @cloneequip/@clonestat 734: Cannot clone your own %s. diff --git a/conf/msg_conf/map_msg_idn.conf b/conf/msg_conf/map_msg_idn.conf index c36f114c3b..d4afc3fc23 100644 --- a/conf/msg_conf/map_msg_idn.conf +++ b/conf/msg_conf/map_msg_idn.conf @@ -769,7 +769,7 @@ 732: Item tidak dapat dibuka ketika inventory penuh. -733: Item '%s' belum tersimpan di gerobak. Harap masuk kembali untuk dapat menyimpan informasi vending dengan benar. +//733 free // @cloneequip/@clonestat 734: Tidak dapat mengkloning %s diri sendiri. diff --git a/doc/packet_interserv.txt b/doc/packet_interserv.txt index ed698e5f82..64d3fbd23b 100644 --- a/doc/packet_interserv.txt +++ b/doc/packet_interserv.txt @@ -1327,6 +1327,33 @@ Currently the max packet size is 0xFFFF (see 'WFIFOSET()' in 'src/common/socket. desc: - Delete pet data +0x308a + Type: ZI + Structure: .W .B .L .L + index: 0,2,3,7 + len: 11 + parameter: + - cmd : packet identification (0x308a) + - type : 0 - TABLE_INVENTORY, 1 - TABLE_CART, 2 - TABLE_STORAGE + - account_id + - char_id + desc: + - Request inventory/cart/storage data for a player/guild if type = 3 + +0x308b + Type: ZI + Structure: .W .B .L .L .?B + index: 0,2,4,5,9,13 + len: 11 + parameter: + - cmd : packet identification (0x308a) + - type : 0 - TABLE_INVENTORY, 1 - TABLE_CART, 2 - TABLE_STORAGE + - account_id + - char_id + - entries : Inventory/cart/storage entries that will be saved + desc: + - Request to save inventory/cart/storage entries + 0x3090: Type: ZI Structure: .W .W .L .?B @@ -2137,6 +2164,34 @@ Currently the max packet size is 0xFFFF (see 'WFIFOSET()' in 'src/common/socket. desc: - Send pet deletion status +0x388a + Type: IZ + Structure: .W .W .B .L .B .?B + index: 0,2,4,5,9 + len: 9+variable + parameter: + - cmd : packet identification (0x388a) + - size + - type : Storage type, 0 - TABLE_INVENTORY, 1 - TABLE_CART, 2 - TABLE_STORAGE + - account_id + - result : True if data loaded, false if failed + - entries : Inventory/cart/storage entries + desc: + - Process inventory/cart/storage entries for player from inter-server + +0x388b + Type: IZ + Structure: .W .L .B .B + index: 0,2,6,7 + len: 11 + parameter: + - cmd : packet identification (0x388b) + - account_id + - result : 1 - success, 0 - failed + - type : Storage type, 0 - TABLE_INVENTORY, 1 - TABLE_CART, 2 - TABLE_STORAGE + desc: + - Info about inventory/cart/storage data is saved + 0x3890 Type: IZ Structure: .W .W .L .B .?B diff --git a/doc/script_commands.txt b/doc/script_commands.txt index addfc4d95c..aab0f1efaf 100644 --- a/doc/script_commands.txt +++ b/doc/script_commands.txt @@ -3,7 +3,7 @@ //===== By: ================================================== //= rAthena Dev Team //===== Last Updated: ======================================== -//= 20150610 +//= 20160325 //===== Description: ========================================= //= A reference manual for the rAthena scripting language. //= Commands are sorted depending on their functionality. @@ -4572,9 +4572,14 @@ database. If the name is not found, nothing will be deleted. *cartdelitem "",{,}; *storagedelitem ,{,}; *storagedelitem "",{,}; +*guildstoragedelitem ,{,}; +*guildstoragedelitem "",{,}; This command behaves identically to 'delitem', but deletes items from the player's -cart or storage. If no cart is mounted, 'cartdelitem' will fail. +cart or storage. + +If no cart is mounted, 'cartdelitem' will return -1. +If player is not in a guild or storage is open, 'guildstoragedelitem' will return -1. --------------------------------------- @@ -4590,9 +4595,14 @@ See 'getitem2' for an explanation of the expanded parameters. *cartdelitem2 "",,,,,,,,{,}; *storagedelitem2 ,,,,,,,,{,}; *storagedelitem2 "",,,,,,,,{,}; +*guildstoragedelitem2 ,,,,,,,,{,}; +*guildstoragedelitem2 "",,,,,,,,{,}; This command behaves identically to 'delitem2', but deletes items from the player's -cart or storage. If no cart is mounted, 'cartdelitem2' will fail. +cart or storage. + +If no cart is mounted, 'cartdelitem2' will return -1. +If player is not in a guild or storage is open, 'guildstoragedelitem2' will return -1. --------------------------------------- @@ -4618,13 +4628,18 @@ adding up strings: --------------------------------------- -*cartcountitem() -*cartcountitem("") -*storagecountitem() -*storagecountitem("") +*cartcountitem({,}) +*cartcountitem(""{,}) +*storagecountitem({,}) +*storagecountitem(""{,}) +*guildstoragecountitem({,}) +*guildstoragecountitem(""{,}) This command behaves identically to 'countitem', but counts items from the player's -cart or storage. If no cart is mounted, 'cartcountitem' will return -1. +cart, storage or guild storage. + +If no cart is mounted, 'cartcountitem' will return -1. +If player is not in a guild or storage is open, 'guildstoragecountitem' will return -1. --------------------------------------- @@ -4639,13 +4654,18 @@ See 'getitem2' for an explanation of the expanded parameters. --------------------------------------- -*cartcountitem2(,,,,,,,) -*cartcountitem2("",,,,,,,) -*storagecountitem2(,,,,,,,) -*storagecountitem2("",,,,,,,) +*cartcountitem2(,,,,,,,{,}) +*cartcountitem2("",,,,,,,{,}) +*storagecountitem2(,,,,,,,{,}) +*storagecountitem2("",,,,,,,{,}) +*guildstoragecountitem2(,,,,,,,{,}) +*guildstoragecountitem2("",,,,,,,{,}) This command behaves identically to 'countitem2', but counts items from the player's -cart or storage. If no cart is mounted, 'cartcountitem2' will return -1. +cart, storage or guild storage. + +If no cart is mounted, 'cartcountitem2' will return -1. +If player is not in a guild or storage is open, 'guildstoragecountitem2' will return -1. --------------------------------------- diff --git a/src/char/char.c b/src/char/char.c index 0220063211..c50a3a1537 100644 --- a/src/char/char.c +++ b/src/char/char.c @@ -23,7 +23,6 @@ #include "int_mercenary.h" #include "int_elemental.h" #include "int_party.h" -#include "int_storage.h" #include "inter.h" #include "char_logif.h" #include "char_mapif.h" @@ -280,30 +279,6 @@ int char_mmo_char_tosql(uint32 char_id, struct mmo_charstatus* p){ StringBuf_Init(&buf); memset(save_status, 0, sizeof(save_status)); - //map inventory data - if( memcmp(p->inventory, cp->inventory, sizeof(p->inventory)) ) { - if (!char_inventory_to_sql(p->inventory, MAX_INVENTORY, p->char_id)) - strcat(save_status, " inventory"); - else - errors++; - } - - //map cart data - if( memcmp(p->cart, cp->cart, sizeof(p->cart)) ) { - if (!char_memitemdata_to_sql(p->cart, MAX_CART, p->char_id, TABLE_CART)) - strcat(save_status, " cart"); - else - errors++; - } - - //map storage data - if( memcmp(p->storage.items, cp->storage.items, sizeof(p->storage.items)) ) { - if (!char_memitemdata_to_sql(p->storage.items, MAX_STORAGE, p->account_id, TABLE_STORAGE)) - strcat(save_status, " storage"); - else - errors++; - } - if ( (p->base_exp != cp->base_exp) || (p->base_level != cp->base_level) || (p->job_level != cp->job_level) || (p->job_exp != cp->job_exp) || @@ -555,13 +530,12 @@ int char_memitemdata_to_sql(const struct item items[], int max, int id, int tabl int errors = 0; switch (tableswitch) { - case TABLE_INVENTORY: tablename = schema_config.inventory_db; selectoption = "char_id"; break; - case TABLE_CART: tablename = schema_config.cart_db; selectoption = "char_id"; break; - case TABLE_STORAGE: tablename = schema_config.storage_db; selectoption = "account_id"; break; - case TABLE_GUILD_STORAGE: tablename = schema_config.guild_storage_db; selectoption = "guild_id"; break; - default: - ShowError("Invalid table name!\n"); - return 1; + case TABLE_CART: tablename = schema_config.cart_db; selectoption = "char_id"; break; + case TABLE_STORAGE: tablename = schema_config.storage_db; selectoption = "account_id"; break; + case TABLE_GUILD_STORAGE: tablename = schema_config.guild_storage_db; selectoption = "guild_id"; break; + default: + ShowError("Invalid table name!\n"); + return 1; } @@ -692,6 +666,8 @@ int char_memitemdata_to_sql(const struct item items[], int max, int id, int tabl errors++; } + ShowInfo("Saved %s data for %s: %d\n", (tableswitch == TABLE_CART ? "Cart" : (tableswitch == TABLE_STORAGE ? "Storage" : "Guild Storage") ), selectoption, id); + StringBuf_Destroy(&buf); aFree(flag); @@ -699,7 +675,7 @@ int char_memitemdata_to_sql(const struct item items[], int max, int id, int tabl } /* pretty much a copy of memitemdata_to_sql except it handles inventory_db exclusively, * - this is required because inventory db is the only one with the 'favorite' column. */ -int char_inventory_to_sql(const struct item items[], int max, int id) { +int char_inventory_to_sql(const struct item items[], int max, int char_id) { StringBuf buf; SqlStmt* stmt; int i; @@ -719,11 +695,11 @@ int char_inventory_to_sql(const struct item items[], int max, int id) { StringBuf_AppendStr(&buf, "SELECT `id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`, `favorite`, `bound`, `unique_id`"); for( j = 0; j < MAX_SLOTS; ++j ) StringBuf_Printf(&buf, ", `card%d`", j); - StringBuf_Printf(&buf, " FROM `%s` WHERE `char_id`='%d'", schema_config.inventory_db, id); + StringBuf_Printf(&buf, " FROM `%s` WHERE `char_id`='%d'", schema_config.inventory_db, char_id); stmt = SqlStmt_Malloc(sql_handle); - if( SQL_ERROR == SqlStmt_PrepareStr(stmt, StringBuf_Value(&buf)) - || SQL_ERROR == SqlStmt_Execute(stmt) ) + if( SQL_ERROR == SqlStmt_PrepareStr(stmt, StringBuf_Value(&buf)) || + SQL_ERROR == SqlStmt_Execute(stmt) ) { SqlStmt_ShowDebug(stmt); SqlStmt_Free(stmt); @@ -820,7 +796,7 @@ int char_inventory_to_sql(const struct item items[], int max, int id) { found = true; StringBuf_Printf(&buf, "('%d', '%hu', '%d', '%d', '%d', '%d', '%d', '%u', '%d', '%d', '%"PRIu64"'", - 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].favorite, items[i].bound, items[i].unique_id); + char_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].favorite, items[i].bound, items[i].unique_id); for( j = 0; j < MAX_SLOTS; ++j ) StringBuf_Printf(&buf, ", '%hu'", items[i].card[j]); StringBuf_AppendStr(&buf, ")"); @@ -831,6 +807,8 @@ int char_inventory_to_sql(const struct item items[], int max, int id) { errors++; } + ShowInfo("Saved Inventory data for char_id: %d.\n", char_id); + StringBuf_Destroy(&buf); aFree(flag); @@ -989,15 +967,13 @@ int char_mmo_chars_fromsql(struct char_session_data* sd, uint8* buf) { //===================================================================================================== int char_mmo_char_fromsql(uint32 char_id, struct mmo_charstatus* p, bool load_everything) { - int i,j; + int i; struct mmo_charstatus* cp; - StringBuf buf; SqlStmt* stmt; char last_map[MAP_NAME_LENGTH_EXT]; char save_map[MAP_NAME_LENGTH_EXT]; char point_map[MAP_NAME_LENGTH_EXT]; struct point tmp_point; - struct item tmp_item; struct s_skill tmp_skill; uint16 skill_count = 0; struct s_friend tmp_friend; @@ -1144,72 +1120,6 @@ int char_mmo_char_fromsql(uint32 char_id, struct mmo_charstatus* p, bool load_ev } StringBuf_AppendStr(&msg_buf, " memo"); - //read inventory - //`inventory` (`id`,`char_id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `card0`, `card1`, `card2`, `card3`, `expire_time`, `favorite`, `unique_id`) - StringBuf_Init(&buf); - StringBuf_AppendStr(&buf, "SELECT `id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`, `favorite`, `bound`, `unique_id`"); - for( i = 0; i < MAX_SLOTS; ++i ) - StringBuf_Printf(&buf, ", `card%d`", i); - StringBuf_Printf(&buf, " FROM `%s` WHERE `char_id`=? LIMIT %d", schema_config.inventory_db, MAX_INVENTORY); - - if( SQL_ERROR == SqlStmt_PrepareStr(stmt, StringBuf_Value(&buf)) - || SQL_ERROR == SqlStmt_BindParam(stmt, 0, SQLDT_INT, &char_id, 0) - || SQL_ERROR == SqlStmt_Execute(stmt) - || SQL_ERROR == SqlStmt_BindColumn(stmt, 0, SQLDT_INT, &tmp_item.id, 0, NULL, NULL) - || SQL_ERROR == SqlStmt_BindColumn(stmt, 1, SQLDT_USHORT, &tmp_item.nameid, 0, NULL, NULL) - || SQL_ERROR == SqlStmt_BindColumn(stmt, 2, SQLDT_SHORT, &tmp_item.amount, 0, NULL, NULL) - || SQL_ERROR == SqlStmt_BindColumn(stmt, 3, SQLDT_UINT, &tmp_item.equip, 0, NULL, NULL) - || SQL_ERROR == SqlStmt_BindColumn(stmt, 4, SQLDT_CHAR, &tmp_item.identify, 0, NULL, NULL) - || SQL_ERROR == SqlStmt_BindColumn(stmt, 5, SQLDT_CHAR, &tmp_item.refine, 0, NULL, NULL) - || SQL_ERROR == SqlStmt_BindColumn(stmt, 6, SQLDT_CHAR, &tmp_item.attribute, 0, NULL, NULL) - || SQL_ERROR == SqlStmt_BindColumn(stmt, 7, SQLDT_UINT, &tmp_item.expire_time, 0, NULL, NULL) - || SQL_ERROR == SqlStmt_BindColumn(stmt, 8, SQLDT_CHAR, &tmp_item.favorite, 0, NULL, NULL) - || SQL_ERROR == SqlStmt_BindColumn(stmt, 9, SQLDT_CHAR, &tmp_item.bound, 0, NULL, NULL) - || SQL_ERROR == SqlStmt_BindColumn(stmt,10, SQLDT_UINT64, &tmp_item.unique_id, 0, NULL, NULL) ) - SqlStmt_ShowDebug(stmt); - for( i = 0; i < MAX_SLOTS; ++i ) - if( SQL_ERROR == SqlStmt_BindColumn(stmt, 11+i, SQLDT_USHORT, &tmp_item.card[i], 0, NULL, NULL) ) - SqlStmt_ShowDebug(stmt); - - for( i = 0; i < MAX_INVENTORY && SQL_SUCCESS == SqlStmt_NextRow(stmt); ++i ) - memcpy(&p->inventory[i], &tmp_item, sizeof(tmp_item)); - - StringBuf_AppendStr(&msg_buf, " inventory"); - - //read cart - //`cart_inventory` (`id`,`char_id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `card0`, `card1`, `card2`, `card3`, expire_time`, `unique_id`) - StringBuf_Clear(&buf); - StringBuf_AppendStr(&buf, "SELECT `id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`, `bound`, `unique_id`"); - for( j = 0; j < MAX_SLOTS; ++j ) - StringBuf_Printf(&buf, ", `card%d`", j); - StringBuf_Printf(&buf, " FROM `%s` WHERE `char_id`=? LIMIT %d", schema_config.cart_db, MAX_CART); - - if( SQL_ERROR == SqlStmt_PrepareStr(stmt, StringBuf_Value(&buf)) - || SQL_ERROR == SqlStmt_BindParam(stmt, 0, SQLDT_INT, &char_id, 0) - || SQL_ERROR == SqlStmt_Execute(stmt) - || SQL_ERROR == SqlStmt_BindColumn(stmt, 0, SQLDT_INT, &tmp_item.id, 0, NULL, NULL) - || SQL_ERROR == SqlStmt_BindColumn(stmt, 1, SQLDT_USHORT, &tmp_item.nameid, 0, NULL, NULL) - || SQL_ERROR == SqlStmt_BindColumn(stmt, 2, SQLDT_SHORT, &tmp_item.amount, 0, NULL, NULL) - || SQL_ERROR == SqlStmt_BindColumn(stmt, 3, SQLDT_UINT, &tmp_item.equip, 0, NULL, NULL) - || SQL_ERROR == SqlStmt_BindColumn(stmt, 4, SQLDT_CHAR, &tmp_item.identify, 0, NULL, NULL) - || SQL_ERROR == SqlStmt_BindColumn(stmt, 5, SQLDT_CHAR, &tmp_item.refine, 0, NULL, NULL) - || SQL_ERROR == SqlStmt_BindColumn(stmt, 6, SQLDT_CHAR, &tmp_item.attribute, 0, NULL, NULL) - || SQL_ERROR == SqlStmt_BindColumn(stmt, 7, SQLDT_UINT, &tmp_item.expire_time, 0, NULL, NULL) - || SQL_ERROR == SqlStmt_BindColumn(stmt, 8, SQLDT_CHAR, &tmp_item.bound, 0, NULL, NULL) - || SQL_ERROR == SqlStmt_BindColumn(stmt, 9, SQLDT_UINT64, &tmp_item.unique_id, 0, NULL, NULL) ) - SqlStmt_ShowDebug(stmt); - for( i = 0; i < MAX_SLOTS; ++i ) - if( SQL_ERROR == SqlStmt_BindColumn(stmt, 10+i, SQLDT_USHORT, &tmp_item.card[i], 0, NULL, NULL) ) - SqlStmt_ShowDebug(stmt); - - for( i = 0; i < MAX_CART && SQL_SUCCESS == SqlStmt_NextRow(stmt); ++i ) - memcpy(&p->cart[i], &tmp_item, sizeof(tmp_item)); - StringBuf_AppendStr(&msg_buf, " cart"); - - //read storage - storage_fromsql(p->account_id, &p->storage); - StringBuf_AppendStr(&msg_buf, " storage"); - //read skill //`skill` (`char_id`, `id`, `lv`) if( SQL_ERROR == SqlStmt_Prepare(stmt, "SELECT `id`, `lv`,`flag` FROM `%s` WHERE `char_id`=? LIMIT %d", schema_config.skill_db, MAX_SKILL) @@ -1274,9 +1184,9 @@ int char_mmo_char_fromsql(uint32 char_id, struct mmo_charstatus* p, bool load_ev StringBuf_AppendStr(&msg_buf, " mercenary"); - if (charserv_config.save_log) ShowInfo("Loaded char (%d - %s): %s\n", char_id, p->name, StringBuf_Value(&msg_buf)); //ok. all data load successfuly! + if (charserv_config.save_log) + ShowInfo("Loaded char (%d - %s): %s\n", char_id, p->name, StringBuf_Value(&msg_buf)); //ok. all data load successfully! SqlStmt_Free(stmt); - StringBuf_Destroy(&buf); cp = (struct mmo_charstatus *)idb_ensure(char_db_, char_id, char_create_charstatus); memcpy(cp, p, sizeof(struct mmo_charstatus)); diff --git a/src/char/char.h b/src/char/char.h index 1be94121db..13e197d825 100644 --- a/src/char/char.h +++ b/src/char/char.h @@ -25,13 +25,6 @@ enum E_CHARSERVER_ST { CHARSERVER_ST_LAST }; -enum { - TABLE_INVENTORY, - TABLE_CART, - TABLE_STORAGE, - TABLE_GUILD_STORAGE, -}; - struct Schema_Config { int db_use_sqldbs; char db_path[1024]; @@ -198,8 +191,7 @@ DBMap* char_get_onlinedb(); // uint32 account_id -> struct online_char_data* struct char_session_data { bool auth; // whether the session is authed or not - uint32 account_id, login_id1, login_id2; - int sex; + uint32 account_id, login_id1, login_id2, sex; int found_char[MAX_CHARS]; // ids of chars on this account char email[40]; // e-mail (default: a@a.com) by [Yor] time_t expiration_time; // # of seconds 1/1/1970 (timestamp): Validity limit of the account (0 = unlimited) @@ -260,6 +252,7 @@ int char_mmo_chars_fromsql(struct char_session_data* sd, uint8* buf); int char_delete_char_sql(uint32 char_id); int char_rename_char_sql(struct char_session_data *sd, uint32 char_id); int char_divorce_char_sql(int partner_id1, int partner_id2); +int char_inventory_to_sql(const struct item items[], int max, int char_id); int char_memitemdata_to_sql(const struct item items[], int max, int id, int tableswitch); void disconnect_player(uint32 account_id); diff --git a/src/char/char_clif.c b/src/char/char_clif.c index 1c4e96ef10..b98f6b8cad 100644 --- a/src/char/char_clif.c +++ b/src/char/char_clif.c @@ -528,8 +528,7 @@ int chclif_parse_char_delete2_accept(int fd, struct char_session_data* sd) { FIFOSD_CHECK(12) { char birthdate[8+1]; - uint32 char_id; - int i, k; + uint32 char_id, i, k; unsigned int base_level; char* data; time_t delete_date; @@ -604,8 +603,7 @@ int chclif_parse_char_delete2_accept(int fd, struct char_session_data* sd) { // CH: <082b>.W .L int chclif_parse_char_delete2_cancel(int fd, struct char_session_data* sd) { - uint32 char_id; - int i; + uint32 char_id, i; FIFOSD_CHECK(6) diff --git a/src/char/int_auction.c b/src/char/int_auction.c index 4c11fae321..0eb32e10eb 100644 --- a/src/char/int_auction.c +++ b/src/char/int_auction.c @@ -3,7 +3,6 @@ #include "../common/mmo.h" #include "../common/malloc.h" -#include "../common/db.h" #include "../common/showmsg.h" #include "../common/socket.h" #include "../common/strlib.h" @@ -15,8 +14,6 @@ #include "int_mail.h" #include "int_auction.h" -#include -#include #include static DBMap* auction_db_ = NULL; // int auction_id -> struct auction_data* @@ -24,7 +21,7 @@ static DBMap* auction_db_ = NULL; // int auction_id -> struct auction_data* void auction_delete(struct auction_data *auction); static int auction_end_timer(int tid, unsigned int tick, int id, intptr_t data); -static int auction_count(int char_id, bool buy) +static int auction_count(uint32 char_id, bool buy) { int i = 0; struct auction_data *auction; @@ -125,7 +122,7 @@ unsigned int auction_create(struct auction_data *auction) return auction->auction_id; } -static void mapif_Auction_message(int char_id, unsigned char result) +static void mapif_Auction_message(uint32 char_id, unsigned char result) { unsigned char buf[74]; @@ -237,7 +234,7 @@ void inter_auctions_fromsql(void) Sql_FreeResult(sql_handle); } -static void mapif_Auction_sendlist(int fd, int char_id, short count, short pages, unsigned char *buf) +static void mapif_Auction_sendlist(int fd, uint32 char_id, short count, short pages, unsigned char *buf) { int len = (sizeof(struct auction_data) * count) + 12; @@ -254,7 +251,7 @@ static void mapif_Auction_sendlist(int fd, int char_id, short count, short pages static void mapif_parse_Auction_requestlist(int fd) { char searchtext[NAME_LENGTH]; - int char_id = RFIFOL(fd,4), len = sizeof(struct auction_data); + uint32 char_id = RFIFOL(fd,4), len = sizeof(struct auction_data); int price = RFIFOL(fd,10); short type = RFIFOW(fd,8), page = max(1,RFIFOW(fd,14)); unsigned char buf[5 * sizeof(struct auction_data)]; @@ -318,7 +315,7 @@ static void mapif_parse_Auction_register(int fd) mapif_Auction_register(fd, &auction); } -static void mapif_Auction_cancel(int fd, int char_id, unsigned char result) +static void mapif_Auction_cancel(int fd, uint32 char_id, unsigned char result) { WFIFOHEAD(fd,7); WFIFOW(fd,0) = 0x3852; @@ -329,7 +326,7 @@ static void mapif_Auction_cancel(int fd, int char_id, unsigned char result) static void mapif_parse_Auction_cancel(int fd) { - int char_id = RFIFOL(fd,2), auction_id = RFIFOL(fd,6); + uint32 char_id = RFIFOL(fd,2), auction_id = RFIFOL(fd,6); struct auction_data *auction; if( (auction = (struct auction_data *)idb_get(auction_db_, auction_id)) == NULL ) @@ -356,7 +353,7 @@ static void mapif_parse_Auction_cancel(int fd) mapif_Auction_cancel(fd, char_id, 0); // The auction has been canceled } -static void mapif_Auction_close(int fd, int char_id, unsigned char result) +static void mapif_Auction_close(int fd, uint32 char_id, unsigned char result) { WFIFOHEAD(fd,7); WFIFOW(fd,0) = 0x3853; @@ -367,7 +364,7 @@ static void mapif_Auction_close(int fd, int char_id, unsigned char result) static void mapif_parse_Auction_close(int fd) { - int char_id = RFIFOL(fd,2), auction_id = RFIFOL(fd,6); + uint32 char_id = RFIFOL(fd,2), auction_id = RFIFOL(fd,6); struct auction_data *auction; if( (auction = (struct auction_data *)idb_get(auction_db_, auction_id)) == NULL ) @@ -398,7 +395,7 @@ static void mapif_parse_Auction_close(int fd) mapif_Auction_close(fd, char_id, 0); // You have ended the auction } -static void mapif_Auction_bid(int fd, int char_id, int bid, unsigned char result) +static void mapif_Auction_bid(int fd, uint32 char_id, int bid, unsigned char result) { WFIFOHEAD(fd,11); WFIFOW(fd,0) = 0x3855; @@ -410,8 +407,8 @@ static void mapif_Auction_bid(int fd, int char_id, int bid, unsigned char result static void mapif_parse_Auction_bid(int fd) { - int char_id = RFIFOL(fd,4), bid = RFIFOL(fd,12); - unsigned int auction_id = RFIFOL(fd,8); + uint32 char_id = RFIFOL(fd,4), auction_id = RFIFOL(fd,8); + int bid = RFIFOL(fd,12); struct auction_data *auction; if( (auction = (struct auction_data *)idb_get(auction_db_, auction_id)) == NULL || auction->price >= bid || auction->seller_id == char_id ) diff --git a/src/char/int_storage.c b/src/char/int_storage.c index 5be031ebe6..f9a43b1486 100644 --- a/src/char/int_storage.c +++ b/src/char/int_storage.c @@ -14,77 +14,262 @@ #define STORAGE_MEMINC 16 -/// Save storage data to sql -int storage_tosql(int account_id, struct storage_data* p) +/** + * Save inventory entries to SQL + * @param char_id: Character ID to save + * @param p: Inventory entries + * @return 0 if success, or error count + */ +static int inventory_tosql(uint32 char_id, struct s_storage* p) { - char_memitemdata_to_sql(p->items, MAX_STORAGE, account_id, TABLE_STORAGE); - return 0; + return char_inventory_to_sql(p->u.items_inventory, MAX_INVENTORY, char_id); } -/// Load storage data to mem -int storage_fromsql(uint32 account_id, struct storage_data* p) +/** + * Save storage entries to SQL + * @param char_id: Character ID to save + * @param p: Storage entries + * @return 0 if success, or error count + */ +static int storage_tosql(uint32 account_id, struct s_storage* p) { + return char_memitemdata_to_sql(p->u.items_storage, MAX_STORAGE, account_id, TABLE_STORAGE); +} + +/** + * Save cart entries to SQL + * @param char_id: Character ID to save + * @param p: Cart entries + * @return 0 if success, or error count + */ +static int cart_tosql(uint32 char_id, struct s_storage* p) +{ + return char_memitemdata_to_sql(p->u.items_cart, MAX_CART, char_id, TABLE_CART); +} + +/** + * Fetch inventory entries from table + * @param char_id: Character ID to fetch + * @param p: Inventory list to save the entries + * @return True if success, False if failed + */ +static bool inventory_fromsql(uint32 char_id, struct s_storage* p) +{ + int i; StringBuf buf; - int i, j; + SqlStmt* stmt; + struct item tmp_item; - memset(p, 0, sizeof(struct storage_data)); //clean up memory - p->storage_amount = 0; + memset(p, 0, sizeof(struct s_storage)); //clean up memory + p->amount = 0; - // storage {`account_id`/`id`/`nameid`/`amount`/`equip`/`identify`/`refine`/`attribute`/`card0`/`card1`/`card2`/`card3`} - StringBuf_Init(&buf); - StringBuf_AppendStr(&buf, "SELECT `id`,`nameid`,`amount`,`equip`,`identify`,`refine`,`attribute`,`expire_time`,`bound`,`unique_id`"); - for( j = 0; j < MAX_SLOTS; ++j ) - StringBuf_Printf(&buf, ",`card%d`", j); - StringBuf_Printf(&buf, " FROM `%s` WHERE `account_id`='%d' ORDER BY `nameid`", schema_config.storage_db, account_id); - - if( SQL_ERROR == Sql_Query(sql_handle, StringBuf_Value(&buf)) ) - Sql_ShowDebug(sql_handle); - - StringBuf_Destroy(&buf); - - for( i = 0; i < MAX_STORAGE && SQL_SUCCESS == Sql_NextRow(sql_handle); ++i ) - { - struct item* item; - char* data; - item = &p->items[i]; - Sql_GetData(sql_handle, 0, &data, NULL); item->id = atoi(data); - Sql_GetData(sql_handle, 1, &data, NULL); item->nameid = atoi(data); - Sql_GetData(sql_handle, 2, &data, NULL); item->amount = atoi(data); - Sql_GetData(sql_handle, 3, &data, NULL); item->equip = atoi(data); - Sql_GetData(sql_handle, 4, &data, NULL); item->identify = atoi(data); - Sql_GetData(sql_handle, 5, &data, NULL); item->refine = atoi(data); - Sql_GetData(sql_handle, 6, &data, NULL); item->attribute = atoi(data); - Sql_GetData(sql_handle, 7, &data, NULL); item->expire_time = (unsigned int)atoi(data); - Sql_GetData(sql_handle, 8, &data, NULL); item->bound = atoi(data); - Sql_GetData(sql_handle, 9, &data, NULL); item->unique_id = strtoull(data, NULL, 10); - for( j = 0; j < MAX_SLOTS; ++j ){ - Sql_GetData(sql_handle, 10+j, &data, NULL); item->card[j] = atoi(data); - } + stmt = SqlStmt_Malloc(sql_handle); + if (stmt == NULL) { + SqlStmt_ShowDebug(stmt); + return false; } - p->storage_amount = i; - Sql_FreeResult(sql_handle); - ShowInfo("storage load complete from DB - id: %d (total: %d)\n", account_id, p->storage_amount); - return 1; + StringBuf_Init(&buf); + StringBuf_AppendStr(&buf, "SELECT `id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`, `favorite`, `bound`, `unique_id`"); + for( i = 0; i < MAX_SLOTS; ++i ) + StringBuf_Printf(&buf, ", `card%d`", i); + StringBuf_Printf(&buf, " FROM `%s` WHERE `char_id`=? LIMIT %d", schema_config.inventory_db, MAX_INVENTORY); + + if( SQL_ERROR == SqlStmt_PrepareStr(stmt, StringBuf_Value(&buf)) + || SQL_ERROR == SqlStmt_BindParam(stmt, 0, SQLDT_INT, &char_id, 0) + || SQL_ERROR == SqlStmt_Execute(stmt) ) + { + SqlStmt_ShowDebug(stmt); + SqlStmt_Free(stmt); + StringBuf_Destroy(&buf); + return false; + } + + SqlStmt_BindColumn(stmt, 0, SQLDT_INT, &tmp_item.id, 0, NULL, NULL); + SqlStmt_BindColumn(stmt, 1, SQLDT_USHORT, &tmp_item.nameid, 0, NULL, NULL); + SqlStmt_BindColumn(stmt, 2, SQLDT_SHORT, &tmp_item.amount, 0, NULL, NULL); + SqlStmt_BindColumn(stmt, 3, SQLDT_UINT, &tmp_item.equip, 0, NULL, NULL); + SqlStmt_BindColumn(stmt, 4, SQLDT_CHAR, &tmp_item.identify, 0, NULL, NULL); + SqlStmt_BindColumn(stmt, 5, SQLDT_CHAR, &tmp_item.refine, 0, NULL, NULL); + SqlStmt_BindColumn(stmt, 6, SQLDT_CHAR, &tmp_item.attribute, 0, NULL, NULL); + SqlStmt_BindColumn(stmt, 7, SQLDT_UINT, &tmp_item.expire_time, 0, NULL, NULL); + SqlStmt_BindColumn(stmt, 8, SQLDT_CHAR, &tmp_item.favorite, 0, NULL, NULL); + SqlStmt_BindColumn(stmt, 9, SQLDT_CHAR, &tmp_item.bound, 0, NULL, NULL); + SqlStmt_BindColumn(stmt,10, SQLDT_ULONGLONG, &tmp_item.unique_id, 0, NULL, NULL); + for( i = 0; i < MAX_SLOTS; ++i ) + SqlStmt_BindColumn(stmt, 11+i, SQLDT_USHORT, &tmp_item.card[i], 0, NULL, NULL); + + for( i = 0; i < MAX_INVENTORY && SQL_SUCCESS == SqlStmt_NextRow(stmt); ++i ) + memcpy(&p->u.items_inventory[i], &tmp_item, sizeof(tmp_item)); + + p->amount = i; + ShowInfo("Loaded inventory data from DB - CID: %d (total: %d)\n", char_id, p->amount); + + SqlStmt_FreeResult(stmt); + SqlStmt_Free(stmt); + StringBuf_Destroy(&buf); + return true; } -/// Save guild_storage data to sql -int guild_storage_tosql(int guild_id, struct guild_storage* p) -{ - char_memitemdata_to_sql(p->items, MAX_GUILD_STORAGE, guild_id, TABLE_GUILD_STORAGE); - ShowInfo ("guild storage save to DB - guild: %d\n", guild_id); - return 0; -} - -/// Load guild_storage data to mem -int guild_storage_fromsql(int guild_id, struct guild_storage* p) +/** + * Fetch cart entries from table + * @param char_id: Character ID to fetch + * @param p: Cart list to save the entries + * @return True if success, False if failed + */ +static bool cart_fromsql(uint32 char_id, struct s_storage* p) { + int i,j; StringBuf buf; - int i, j; + SqlStmt* stmt; + struct item tmp_item; - memset(p, 0, sizeof(struct guild_storage)); //clean up memory - p->storage_amount = 0; - p->guild_id = guild_id; + memset(p, 0, sizeof(struct s_storage)); //clean up memory + p->amount = 0; + + stmt = SqlStmt_Malloc(sql_handle); + if (stmt == NULL) { + SqlStmt_ShowDebug(stmt); + return false; + } + + StringBuf_Init(&buf); + StringBuf_AppendStr(&buf, "SELECT `id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`, `bound`, `unique_id`"); + for( j = 0; j < MAX_SLOTS; ++j ) + StringBuf_Printf(&buf, ", `card%d`", j); + StringBuf_Printf(&buf, " FROM `%s` WHERE `char_id`=? LIMIT %d", schema_config.cart_db, MAX_CART); + + if( SQL_ERROR == SqlStmt_PrepareStr(stmt, StringBuf_Value(&buf)) + || SQL_ERROR == SqlStmt_BindParam(stmt, 0, SQLDT_INT, &char_id, 0) + || SQL_ERROR == SqlStmt_Execute(stmt) ) + { + SqlStmt_ShowDebug(stmt); + SqlStmt_Free(stmt); + StringBuf_Destroy(&buf); + return false; + } + + SqlStmt_BindColumn(stmt, 0, SQLDT_INT, &tmp_item.id, 0, NULL, NULL); + SqlStmt_BindColumn(stmt, 1, SQLDT_USHORT, &tmp_item.nameid, 0, NULL, NULL); + SqlStmt_BindColumn(stmt, 2, SQLDT_SHORT, &tmp_item.amount, 0, NULL, NULL); + SqlStmt_BindColumn(stmt, 3, SQLDT_UINT, &tmp_item.equip, 0, NULL, NULL); + SqlStmt_BindColumn(stmt, 4, SQLDT_CHAR, &tmp_item.identify, 0, NULL, NULL); + SqlStmt_BindColumn(stmt, 5, SQLDT_CHAR, &tmp_item.refine, 0, NULL, NULL); + SqlStmt_BindColumn(stmt, 6, SQLDT_CHAR, &tmp_item.attribute, 0, NULL, NULL); + SqlStmt_BindColumn(stmt, 7, SQLDT_UINT, &tmp_item.expire_time, 0, NULL, NULL); + SqlStmt_BindColumn(stmt, 8, SQLDT_CHAR, &tmp_item.bound, 0, NULL, NULL); + SqlStmt_BindColumn(stmt, 9, SQLDT_ULONGLONG, &tmp_item.unique_id, 0, NULL, NULL); + for( i = 0; i < MAX_SLOTS; ++i ) + SqlStmt_BindColumn(stmt, 10+i, SQLDT_USHORT, &tmp_item.card[i], 0, NULL, NULL); + + for( i = 0; i < MAX_CART && SQL_SUCCESS == SqlStmt_NextRow(stmt); ++i ) + memcpy(&p->u.items_cart[i], &tmp_item, sizeof(tmp_item)); + + p->amount = i; + ShowInfo("Loaded Cart data from DB - CID: %d (total: %d)\n", char_id, p->amount); + + SqlStmt_FreeResult(stmt); + SqlStmt_Free(stmt); + StringBuf_Destroy(&buf); + return true; +} + +/** + * Fetch storage entries from table + * @param char_id: Character ID to fetch + * @param p: Storage list to save the entries + * @return True if success, False if failed + */ +static bool storage_fromsql(uint32 account_id, struct s_storage* p) +{ + int i, j; + StringBuf buf; + SqlStmt* stmt; + struct item tmp_item; + + memset(p, 0, sizeof(struct s_storage)); //clean up memory + p->amount = 0; + + stmt = SqlStmt_Malloc(sql_handle); + if (stmt == NULL) { + SqlStmt_ShowDebug(stmt); + return false; + } + + StringBuf_Init(&buf); + StringBuf_AppendStr(&buf, "SELECT `id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`, `bound`, `unique_id`"); + for( j = 0; j < MAX_SLOTS; ++j ) + StringBuf_Printf(&buf, ", `card%d`", j); + StringBuf_Printf(&buf, " FROM `%s` WHERE `account_id`=? ORDER BY `nameid` LIMIT %d", schema_config.storage_db, account_id, MAX_STORAGE); + + if( SQL_ERROR == SqlStmt_PrepareStr(stmt, StringBuf_Value(&buf)) + || SQL_ERROR == SqlStmt_BindParam(stmt, 0, SQLDT_INT, &account_id, 0) + || SQL_ERROR == SqlStmt_Execute(stmt) ) + { + SqlStmt_ShowDebug(stmt); + SqlStmt_Free(stmt); + StringBuf_Destroy(&buf); + return false; + } + + SqlStmt_BindColumn(stmt, 0, SQLDT_INT, &tmp_item.id, 0, NULL, NULL); + SqlStmt_BindColumn(stmt, 1, SQLDT_USHORT, &tmp_item.nameid, 0, NULL, NULL); + SqlStmt_BindColumn(stmt, 2, SQLDT_SHORT, &tmp_item.amount, 0, NULL, NULL); + SqlStmt_BindColumn(stmt, 3, SQLDT_UINT, &tmp_item.equip, 0, NULL, NULL); + SqlStmt_BindColumn(stmt, 4, SQLDT_CHAR, &tmp_item.identify, 0, NULL, NULL); + SqlStmt_BindColumn(stmt, 5, SQLDT_CHAR, &tmp_item.refine, 0, NULL, NULL); + SqlStmt_BindColumn(stmt, 6, SQLDT_CHAR, &tmp_item.attribute, 0, NULL, NULL); + SqlStmt_BindColumn(stmt, 7, SQLDT_UINT, &tmp_item.expire_time, 0, NULL, NULL); + SqlStmt_BindColumn(stmt, 8, SQLDT_CHAR, &tmp_item.bound, 0, NULL, NULL); + SqlStmt_BindColumn(stmt, 9, SQLDT_ULONGLONG, &tmp_item.unique_id, 0, NULL, NULL); + for( i = 0; i < MAX_SLOTS; ++i ) + SqlStmt_BindColumn(stmt, 10+i, SQLDT_USHORT, &tmp_item.card[i], 0, NULL, NULL); + + for( i = 0; i < MAX_STORAGE && SQL_SUCCESS == SqlStmt_NextRow(stmt); ++i ) + memcpy(&p->u.items_storage[i], &tmp_item, sizeof(tmp_item)); + + p->amount = i; + ShowInfo("Loaded Storage data from DB - AID: %d (total: %d)\n", account_id, p->amount); + + SqlStmt_FreeResult(stmt); + SqlStmt_Free(stmt); + StringBuf_Destroy(&buf); + return true; +} + +/** + * Save guild_storage data to sql + * @param guild_id: Character ID to save + * @param p: Guild Storage list to save the entries + * @return 0 if success, or error count + */ +bool guild_storage_tosql(int guild_id, struct s_storage* p) +{ + //ShowInfo("Guild Storage has been saved (GID: %d)\n", guild_id); + return char_memitemdata_to_sql(p->u.items_guild, MAX_GUILD_STORAGE, guild_id, TABLE_GUILD_STORAGE); +} + +/** + * Fetch guild_storage entries from table + * @param char_id: Character ID to fetch + * @param p: Storage list to save the entries + * @return True if success, False if failed + */ +bool guild_storage_fromsql(int guild_id, struct s_storage* p) +{ + int i,j; + StringBuf buf; + SqlStmt* stmt; + struct item tmp_item; + + memset(p, 0, sizeof(struct s_storage)); //clean up memory + p->amount = 0; + + stmt = SqlStmt_Malloc(sql_handle); + if (stmt == NULL) { + SqlStmt_ShowDebug(stmt); + return false; + } // storage {`guild_id`/`id`/`nameid`/`amount`/`equip`/`identify`/`refine`/`attribute`/`card0`/`card1`/`card2`/`card3`} StringBuf_Init(&buf); @@ -93,43 +278,48 @@ int guild_storage_fromsql(int guild_id, struct guild_storage* p) StringBuf_Printf(&buf, ",`card%d`", j); StringBuf_Printf(&buf, " FROM `%s` WHERE `guild_id`='%d' ORDER BY `nameid`", schema_config.guild_storage_db, guild_id); - if( SQL_ERROR == Sql_Query(sql_handle, StringBuf_Value(&buf)) ) - Sql_ShowDebug(sql_handle); - - StringBuf_Destroy(&buf); - - for( i = 0; i < MAX_GUILD_STORAGE && SQL_SUCCESS == Sql_NextRow(sql_handle); ++i ) + if( SQL_ERROR == SqlStmt_PrepareStr(stmt, StringBuf_Value(&buf)) + || SQL_ERROR == SqlStmt_BindParam(stmt, 0, SQLDT_INT, &guild_id, 0) + || SQL_ERROR == SqlStmt_Execute(stmt) ) { - struct item* item; - char* data; - item = &p->items[i]; - Sql_GetData(sql_handle, 0, &data, NULL); item->id = atoi(data); - Sql_GetData(sql_handle, 1, &data, NULL); item->nameid = atoi(data); - Sql_GetData(sql_handle, 2, &data, NULL); item->amount = atoi(data); - Sql_GetData(sql_handle, 3, &data, NULL); item->equip = atoi(data); - Sql_GetData(sql_handle, 4, &data, NULL); item->identify = atoi(data); - Sql_GetData(sql_handle, 5, &data, NULL); item->refine = atoi(data); - Sql_GetData(sql_handle, 6, &data, NULL); item->attribute = atoi(data); - Sql_GetData(sql_handle, 7, &data, NULL); item->bound = atoi(data); - Sql_GetData(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(sql_handle, 9+j, &data, NULL); item->card[j] = atoi(data); - } + SqlStmt_ShowDebug(stmt); + SqlStmt_Free(stmt); + StringBuf_Destroy(&buf); + return false; } - p->storage_amount = i; - Sql_FreeResult(sql_handle); - ShowInfo("guild storage load complete from DB - id: %d (total: %d)\n", guild_id, p->storage_amount); - return 0; + SqlStmt_BindColumn(stmt, 0, SQLDT_INT, &tmp_item.id, 0, NULL, NULL); + SqlStmt_BindColumn(stmt, 1, SQLDT_USHORT, &tmp_item.nameid, 0, NULL, NULL); + SqlStmt_BindColumn(stmt, 2, SQLDT_SHORT, &tmp_item.amount, 0, NULL, NULL); + SqlStmt_BindColumn(stmt, 3, SQLDT_UINT, &tmp_item.equip, 0, NULL, NULL); + SqlStmt_BindColumn(stmt, 4, SQLDT_CHAR, &tmp_item.identify, 0, NULL, NULL); + SqlStmt_BindColumn(stmt, 5, SQLDT_CHAR, &tmp_item.refine, 0, NULL, NULL); + SqlStmt_BindColumn(stmt, 6, SQLDT_CHAR, &tmp_item.attribute, 0, NULL, NULL); + SqlStmt_BindColumn(stmt, 7, SQLDT_CHAR, &tmp_item.bound, 0, NULL, NULL); + SqlStmt_BindColumn(stmt, 8, SQLDT_ULONGLONG, &tmp_item.unique_id, 0, NULL, NULL); + tmp_item.expire_time = 0; + for( i = 0; i < MAX_SLOTS; ++i ) + SqlStmt_BindColumn(stmt, 9+i, SQLDT_USHORT, &tmp_item.card[i], 0, NULL, NULL); + + for( i = 0; i < MAX_GUILD_STORAGE && SQL_SUCCESS == SqlStmt_NextRow(stmt); ++i ) + memcpy(&p->u.items_guild[i], &tmp_item, sizeof(tmp_item)); + + p->amount = i; + ShowInfo("Loaded Guild Storage data from DB - GID: %d (total: %d)\n", guild_id, p->amount); + + SqlStmt_FreeResult(stmt); + SqlStmt_Free(stmt); + StringBuf_Destroy(&buf); + return true; } //--------------------------------------------------------- // storage data initialize -int inter_storage_sql_init(void) +void inter_storage_sql_init(void) { - return 1; + return; } + // storage data finalize void inter_storage_sql_final(void) { @@ -137,37 +327,36 @@ void inter_storage_sql_final(void) } // Delete char storage -int inter_storage_delete(uint32 account_id) +void inter_storage_delete(uint32 account_id) { if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `account_id`='%d'", schema_config.storage_db, account_id) ) Sql_ShowDebug(sql_handle); - return 0; } -int inter_guild_storage_delete(int guild_id) + +void inter_guild_storage_delete(int guild_id) { if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `guild_id`='%d'", schema_config.guild_storage_db, guild_id) ) Sql_ShowDebug(sql_handle); - return 0; } //--------------------------------------------------------- // packet from map server -int mapif_load_guild_storage(int fd,uint32 account_id,int guild_id, char flag) +bool mapif_load_guild_storage(int fd,uint32 account_id,int guild_id, char flag) { if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `guild_id` FROM `%s` WHERE `guild_id`='%d'", schema_config.guild_db, guild_id) ) Sql_ShowDebug(sql_handle); else if( Sql_NumRows(sql_handle) > 0 ) {// guild exists - WFIFOHEAD(fd, sizeof(struct guild_storage)+13); + WFIFOHEAD(fd, sizeof(struct s_storage)+13); WFIFOW(fd,0) = 0x3818; - WFIFOW(fd,2) = sizeof(struct guild_storage)+13; + WFIFOW(fd,2) = sizeof(struct s_storage)+13; WFIFOL(fd,4) = account_id; WFIFOL(fd,8) = guild_id; WFIFOB(fd,12) = flag; //1 open storage, 0 don't open - guild_storage_fromsql(guild_id, (struct guild_storage*)WFIFOP(fd,13)); + guild_storage_fromsql(guild_id, (struct s_storage*)WFIFOP(fd,13)); WFIFOSET(fd, WFIFOW(fd,2)); - return 0; + return false; } // guild does not exist Sql_FreeResult(sql_handle); @@ -177,9 +366,10 @@ int mapif_load_guild_storage(int fd,uint32 account_id,int guild_id, char flag) WFIFOL(fd,4) = account_id; WFIFOL(fd,8) = 0; WFIFOSET(fd, 12); - return 0; + return true; } -int mapif_save_guild_storage_ack(int fd,uint32 account_id,int guild_id,int fail) + +void mapif_save_guild_storage_ack(int fd,uint32 account_id,int guild_id,int fail) { WFIFOHEAD(fd,11); WFIFOW(fd,0)=0x3819; @@ -187,20 +377,18 @@ int mapif_save_guild_storage_ack(int fd,uint32 account_id,int guild_id,int fail) WFIFOL(fd,6)=guild_id; WFIFOB(fd,10)=fail; WFIFOSET(fd,11); - return 0; } //--------------------------------------------------------- // packet from map server -int mapif_parse_LoadGuildStorage(int fd) +void mapif_parse_LoadGuildStorage(int fd) { RFIFOHEAD(fd); mapif_load_guild_storage(fd,RFIFOL(fd,2),RFIFOL(fd,6),1); - return 0; } -int mapif_parse_SaveGuildStorage(int fd) +bool mapif_parse_SaveGuildStorage(int fd) { int guild_id; int len; @@ -209,9 +397,9 @@ int mapif_parse_SaveGuildStorage(int fd) guild_id = RFIFOL(fd,8); len = RFIFOW(fd,2); - if( sizeof(struct guild_storage) != len - 12 ) + if( sizeof(struct s_storage) != len - 12 ) { - ShowError("inter storage: data size error %d != %d\n", sizeof(struct guild_storage), len - 12); + ShowError("inter storage: data size error %d != %d\n", sizeof(struct s_storage), len - 12); } else { @@ -220,21 +408,21 @@ int mapif_parse_SaveGuildStorage(int fd) else if( Sql_NumRows(sql_handle) > 0 ) {// guild exists Sql_FreeResult(sql_handle); - guild_storage_tosql(guild_id, (struct guild_storage*)RFIFOP(fd,12)); + guild_storage_tosql(guild_id, (struct s_storage*)RFIFOP(fd,12)); mapif_save_guild_storage_ack(fd, RFIFOL(fd,4), guild_id, 0); - return 0; + return false; } Sql_FreeResult(sql_handle); } mapif_save_guild_storage_ack(fd, RFIFOL(fd,4), guild_id, 1); - return 0; + return true; } #ifdef BOUND_ITEMS /** -* IZ 0x3856 .L .W -* Tells map-server if the process if complete, unlock the guild storage -*/ + * IZ 0x3856 .L .W + * Tells map-server if the process if complete, unlock the guild storage + */ static void mapif_itembound_ack(int fd, int account_id, int guild_id) { WFIFOHEAD(fd,8); @@ -246,17 +434,17 @@ static void mapif_itembound_ack(int fd, int account_id, int guild_id) } /** -* IZ 0x3857 .W .W .W { .?B }.*MAX_INVENTORY -* Send the retrieved guild bound items to map-server, store them to guild storage. -* By using this method, stackable items will looks how it should be, and overflowed -* item's stack won't disturbs the guild storage table and the leftover items (when -* storage is full) will be discarded. -* @param fd -* @param guild_id -* @param items[] -* @param count -* @author [Cydh] -*/ + * IZ 0x3857 .W .W .W { .?B }.*MAX_INVENTORY + * Send the retrieved guild bound items to map-server, store them to guild storage. + * By using this method, stackable items will looks how it should be, and overflowed + * item's stack won't disturbs the guild storage table and the leftover items (when + * storage is full) will be discarded. + * @param fd + * @param guild_id + * @param items[] + * @param count + * @author [Cydh] + */ static void mapif_itembound_store2gstorage(int fd, int guild_id, struct item items[], unsigned short count) { int size = 8 + sizeof(struct item) * MAX_INVENTORY, i; @@ -274,11 +462,11 @@ static void mapif_itembound_store2gstorage(int fd, int guild_id, struct item ite } /** -* ZI 0x3056 .L .L .W -* Pulls guild bound items for offline characters -* @author [Akinari] -*/ -int mapif_parse_itembound_retrieve(int fd) + * ZI 0x3056 .L .L .W + * Pulls guild bound items for offline characters + * @author [Akinari] + */ +bool mapif_parse_itembound_retrieve(int fd) { StringBuf buf; SqlStmt* stmt; @@ -303,7 +491,7 @@ int mapif_parse_itembound_retrieve(int fd) SqlStmt_Free(stmt); StringBuf_Destroy(&buf); mapif_itembound_ack(fd,account_id,guild_id); - return 1; + return true; } SqlStmt_BindColumn(stmt, 0, SQLDT_INT, &item.id, 0, NULL, NULL); @@ -328,7 +516,7 @@ int mapif_parse_itembound_retrieve(int fd) StringBuf_Destroy(&buf); SqlStmt_Free(stmt); mapif_itembound_ack(fd,account_id,guild_id); - return 1; + return true; } char_set_session_flag(account_id, 1); @@ -343,7 +531,7 @@ int mapif_parse_itembound_retrieve(int fd) SqlStmt_Free(stmt); StringBuf_Destroy(&buf); mapif_itembound_ack(fd,account_id,guild_id); - return 1; + return true; } // Send the deleted items to map-server to store them in guild storage [Cydh] @@ -389,7 +577,7 @@ int mapif_parse_itembound_retrieve(int fd) StringBuf_Destroy(&buf); StringBuf_Destroy(&buf2); mapif_itembound_ack(fd,account_id,guild_id); - return 1; + return true; } StringBuf_Destroy(&buf2); } @@ -398,21 +586,126 @@ int mapif_parse_itembound_retrieve(int fd) SqlStmt_Free(stmt); char_unset_session_flag(account_id, 1); - return 0; + return false; } #endif -int inter_storage_parse_frommap(int fd) +/*========================================== + * Storages (Inventory/Storage/Cart) + *------------------------------------------*/ + +/** + * Sending inventory/cart/storage data to player + * IZ 0x388a .W .B .L .B .?B + * @param fd + * @param account_id + * @param type + * @param entries Inventory/cart/storage entries + * @param result + */ +static void mapif_storage_data_loaded(int fd, uint32 account_id, char type, struct s_storage entries, bool result) { + uint16 size = sizeof(struct s_storage) + 10; + + WFIFOHEAD(fd, size); + WFIFOW(fd, 0) = 0x388a; + WFIFOW(fd, 2) = size; + WFIFOB(fd, 4) = type; + WFIFOL(fd, 5) = account_id; + WFIFOB(fd, 9) = result; + memcpy(WFIFOP(fd, 10), &entries, sizeof(struct s_storage)); + WFIFOSET(fd, size); +} + +/** + * Tells player if inventory/cart/storage is saved + * IZ 0x388b .L .B .B + * @param fd + * @param account_id + * @param type + */ +void mapif_storage_saved(int fd, uint32 account_id, bool sucess, char type) { + WFIFOHEAD(fd,8); + WFIFOW(fd, 0) = 0x388b; + WFIFOL(fd, 2) = account_id; + WFIFOB(fd, 6) = sucess; + WFIFOB(fd, 7) = type; + WFIFOSET(fd,8); +} + +/** + * Requested inventory/cart/storage data for a player + * ZI 0x308a .B .L .L + * @param fd + */ +bool mapif_parse_StorageLoad(int fd) { + uint32 aid, cid; + int type; + struct s_storage stor; + bool res = true; + + RFIFOHEAD(fd); + type = RFIFOB(fd,2); + aid = RFIFOL(fd,3); + cid = RFIFOL(fd,7); + + memset(&stor, 0, sizeof(struct s_storage)); + + //ShowInfo("Loading storage for AID=%d.\n", aid); + switch (type) { + case TABLE_INVENTORY: res = inventory_fromsql(cid, &stor); break; + case TABLE_STORAGE: res = storage_fromsql(aid, &stor); break; + case TABLE_CART: res = cart_fromsql(cid, &stor); break; + default: return false; + } + mapif_storage_data_loaded(fd, aid, type, stor, res); + return true; +} + +/** + * Asking to save player's inventory/cart/storage data + * ZI 0x308b .W .B .L .L .?B + * @param fd + */ +bool mapif_parse_StorageSave(int fd) { + int aid, cid, type; + struct s_storage stor; + + RFIFOHEAD(fd); + type = RFIFOB(fd, 4); + aid = RFIFOL(fd, 5); + cid = RFIFOL(fd, 9); + + memset(&stor, 0, sizeof(struct s_storage)); + memcpy(&stor, RFIFOP(fd, 13), sizeof(struct s_storage)); + + //ShowInfo("Saving storage data for AID=%d.\n", aid); + switch(type){ + case TABLE_INVENTORY: inventory_tosql(cid, &stor); break; + case TABLE_STORAGE: storage_tosql(aid, &stor); break; + case TABLE_CART: cart_tosql(cid, &stor); break; + default: return false; + } + mapif_storage_saved(fd, aid, true, type); + return false; +} + + +/*========================================== + * Parse packet from map-server + *------------------------------------------*/ +bool inter_storage_parse_frommap(int fd) { RFIFOHEAD(fd); switch(RFIFOW(fd,0)){ - case 0x3018: mapif_parse_LoadGuildStorage(fd); break; - case 0x3019: mapif_parse_SaveGuildStorage(fd); break; + case 0x3018: mapif_parse_LoadGuildStorage(fd); break; + case 0x3019: mapif_parse_SaveGuildStorage(fd); break; #ifdef BOUND_ITEMS - case 0x3056: mapif_parse_itembound_retrieve(fd); break; + case 0x3056: mapif_parse_itembound_retrieve(fd); break; #endif - default: - return 0; + case 0x308a: mapif_parse_StorageLoad(fd); break; + case 0x308b: mapif_parse_StorageSave(fd); break; + default: + return false; } - return 1; + return true; } diff --git a/src/char/int_storage.h b/src/char/int_storage.h index a68c04d960..9c391e4b45 100644 --- a/src/char/int_storage.h +++ b/src/char/int_storage.h @@ -4,18 +4,15 @@ #ifndef _INT_STORAGE_SQL_H_ #define _INT_STORAGE_SQL_H_ -struct storage_data; -struct guild_storage; +struct s_storage; -int inter_storage_sql_init(void); +void inter_storage_sql_init(void); void inter_storage_sql_final(void); -int inter_storage_delete(uint32 account_id); -int inter_guild_storage_delete(int guild_id); +void inter_storage_delete(uint32 account_id); +void inter_guild_storage_delete(int guild_id); -int inter_storage_parse_frommap(int fd); +bool inter_storage_parse_frommap(int fd); -int storage_fromsql(uint32 account_id, struct storage_data* p); -int storage_tosql(uint32 account_id,struct storage_data *p); -int guild_storage_tosql(int guild_id, struct guild_storage *p); +bool guild_storage_tosql(int guild_id, struct s_storage *p); #endif /* _INT_STORAGE_SQL_H_ */ diff --git a/src/char/inter.c b/src/char/inter.c index e1304c2647..3e1716a958 100644 --- a/src/char/inter.c +++ b/src/char/inter.c @@ -42,7 +42,7 @@ char default_codepage[32] = ""; //Feature by irmin. unsigned int party_share_level = 10; -// recv. packet list +/// Received packet Lengths from map-server int inter_recv_packet_length[] = { -1,-1, 7,-1, -1,13,36, (2+4+4+4+1+NAME_LENGTH), 0,-1, 0, 0, 0, 0, 0, 0, // 3000- 6,-1, 0, 0, 0, 0, 0, 0, 10,-1, 0, 0, 0, 0, 0, 0, // 3010- @@ -52,7 +52,7 @@ int inter_recv_packet_length[] = { -1,-1,10,10, 0,-1,12, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3050- Auction System [Zephyrus] 6,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3060- Quest system [Kevin] [Inkfish] -1,10, 6,-1, 0, 0, 0, 0, 0, 0, 0, 0, -1,10, 6,-1, // 3070- Mercenary packets [Zephyrus], Elemental packets [pakpil] - 48,14,-1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3080- + 48,14,-1, 6, 0, 0, 0, 0, 0, 0,11,-1, 0, 0, 0, 0, // 3080- Pet System, Storage -1,10,-1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3090- Homunculus packets [albator] }; @@ -399,7 +399,7 @@ void mapif_parse_accinfo(int fd) { int u_fd = RFIFOL(fd,2), u_aid = RFIFOL(fd,6), u_group = RFIFOL(fd,10); char type= RFIFOB(fd,14); char query[NAME_LENGTH], query_esq[NAME_LENGTH*2+1]; - int account_id = 0; + uint32 account_id = 0; char *data; safestrncpy(query, (char*) RFIFOP(fd,15), NAME_LENGTH); @@ -492,7 +492,7 @@ void mapif_accinfo_ack(bool success, int map_fd, int u_fd, int u_aid, int accoun } } else { while ( SQL_SUCCESS == Sql_NextRow(sql_handle) ) { - int char_id, class_; + uint32 char_id, class_; short char_num, base_level, job_level, online; char name[NAME_LENGTH]; char *data; @@ -810,7 +810,7 @@ int inter_init_sql(const char *file) ShowInfo("Connect Character DB server.... (Character Server)\n"); if( SQL_ERROR == Sql_Connect(sql_handle, char_server_id, char_server_pw, char_server_ip, (uint16)char_server_port, char_server_db) ) { - ShowError("Couldn't connect with uname='%s',passwd='%s',host='%s',port='%d',database='%s'\n", + ShowError("Couldn't connect with username = '%s', password = '%s', host = '%s', port = '%d', database = '%s'\n", char_server_id, char_server_pw, char_server_ip, char_server_port, char_server_db); Sql_ShowDebug(sql_handle); Sql_Free(sql_handle); diff --git a/src/common/mmo.h b/src/common/mmo.h index f0dce7e232..3127b2dbd9 100644 --- a/src/common/mmo.h +++ b/src/common/mmo.h @@ -62,7 +62,7 @@ #define DEFAULT_WALK_SPEED 150 ///Default walk speed #define MIN_WALK_SPEED 20 ///Min walk speed #define MAX_WALK_SPEED 1000 ///Max walk speed -#define MAX_STORAGE 600 ///Max number of storage slots a player can have, (up to ~850 tested) +#define MAX_STORAGE 600 ///Max number of storage slots a player can have #define MAX_GUILD_STORAGE 600 ///Max number of storage slots a guild #define MAX_PARTY 12 ///Max party member #define MAX_GUILD 16+10*6 ///Increased max guild members +6 per 1 extension levels [Lupus] @@ -283,19 +283,26 @@ struct skill_cooldown_data { long tick; }; -struct storage_data { - int storage_amount; - struct item items[MAX_STORAGE]; +enum storage_type { + TABLE_INVENTORY, + TABLE_CART, + TABLE_STORAGE, + TABLE_GUILD_STORAGE, }; -/// Guild storgae struct -struct guild_storage { - bool dirty; ///< Dirty status, need to be saved - int guild_id; ///< Guild ID - short storage_amount; ///< Amount of item on storage - struct item items[MAX_GUILD_STORAGE]; ///< Item entries - bool locked; ///< If locked, can't use storage when item bound retrieval - uint32 opened; ///< Holds the char_id that open the storage +struct s_storage { + bool dirty; ///< Dirty status, data needs to be saved + bool status; ///< Current status of storage (opened or closed) + int amount; ///< Amount of items in storage + bool lock; ///< If locked, can't use storage when item bound retrieval + uint32 id; ///< Account ID / Character ID / Guild ID (owner of storage) + enum storage_type type; ///< Type of storage (inventory, cart, storage, guild storage) + union { // Max for inventory, storage, cart, and guild storage are 1637 each without changing this struct and struct item [2014/10/27] + struct item items_inventory[MAX_INVENTORY]; + struct item items_storage[MAX_STORAGE]; + struct item items_cart[MAX_CART]; + struct item items_guild[MAX_GUILD_STORAGE]; + } u; }; struct s_pet { @@ -418,8 +425,6 @@ struct mmo_charstatus { uint16 mapport; struct point last_point,save_point,memo_point[MAX_MEMOPOINTS]; - struct item inventory[MAX_INVENTORY],cart[MAX_CART]; - struct storage_data storage; struct s_skill skill[MAX_SKILL]; struct s_friend friends[MAX_FRIENDS]; //New friend system [Skotlex] diff --git a/src/login/account.c b/src/login/account.c index 1b3b172c3d..62e64f8aad 100644 --- a/src/login/account.c +++ b/src/login/account.c @@ -17,7 +17,6 @@ #include /// global defines -#define ACCOUNT_SQL_DB_VERSION 20140928 /// internal structure typedef struct AccountDB_SQL { @@ -117,15 +116,12 @@ static bool account_db_sql_init(AccountDB* self) { db->accounts = Sql_Malloc(); sql_handle = db->accounts; - if( db->db_hostname[0] != '\0' ) - {// local settings - username = db->db_username; - password = db->db_password; - hostname = db->db_hostname; - port = db->db_port; - database = db->db_database; - codepage = db->codepage; - } + username = db->db_username; + password = db->db_password; + hostname = db->db_hostname; + port = db->db_port; + database = db->db_database; + codepage = db->codepage; if( SQL_ERROR == Sql_Connect(sql_handle, username, password, hostname, port, database) ) { @@ -462,7 +458,7 @@ static void account_db_sql_iter_destroy(AccountDBIterator* self) { */ static bool account_db_sql_iter_next(AccountDBIterator* self, struct mmo_account* acc) { AccountDBIterator_SQL* iter = (AccountDBIterator_SQL*)self; - AccountDB_SQL* db = (AccountDB_SQL*)iter->db; + AccountDB_SQL* db = iter->db; Sql* sql_handle = db->accounts; char* data; @@ -526,15 +522,15 @@ static bool mmo_auth_fromsql(AccountDB_SQL* db, struct mmo_account* acc, uint32 Sql_GetData(sql_handle, 2, &data, NULL); safestrncpy(acc->pass, data, sizeof(acc->pass)); Sql_GetData(sql_handle, 3, &data, NULL); acc->sex = data[0]; Sql_GetData(sql_handle, 4, &data, NULL); safestrncpy(acc->email, data, sizeof(acc->email)); - Sql_GetData(sql_handle, 5, &data, NULL); acc->group_id = atoi(data); - Sql_GetData(sql_handle, 6, &data, NULL); acc->state = strtoul(data, NULL, 10); + Sql_GetData(sql_handle, 5, &data, NULL); acc->group_id = (unsigned int) atoi(data); + Sql_GetData(sql_handle, 6, &data, NULL); acc->state = (unsigned int) strtoul(data, NULL, 10); Sql_GetData(sql_handle, 7, &data, NULL); acc->unban_time = atol(data); Sql_GetData(sql_handle, 8, &data, NULL); acc->expiration_time = atol(data); - Sql_GetData(sql_handle, 9, &data, NULL); acc->logincount = strtoul(data, NULL, 10); + Sql_GetData(sql_handle, 9, &data, NULL); acc->logincount = (unsigned int) strtoul(data, NULL, 10); Sql_GetData(sql_handle, 10, &data, NULL); safestrncpy(acc->lastlogin, data, sizeof(acc->lastlogin)); Sql_GetData(sql_handle, 11, &data, NULL); safestrncpy(acc->last_ip, data, sizeof(acc->last_ip)); Sql_GetData(sql_handle, 12, &data, NULL); safestrncpy(acc->birthdate, data, sizeof(acc->birthdate)); - Sql_GetData(sql_handle, 13, &data, NULL); acc->char_slots = atoi(data); + Sql_GetData(sql_handle, 13, &data, NULL); acc->char_slots = (uint8) atoi(data); Sql_GetData(sql_handle, 14, &data, NULL); safestrncpy(acc->pincode, data, sizeof(acc->pincode)); Sql_GetData(sql_handle, 15, &data, NULL); acc->pincode_change = atol(data); #ifdef VIP_ENABLE diff --git a/src/map/atcommand.c b/src/map/atcommand.c index 860894f78a..4466b50e75 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -922,7 +922,7 @@ ACMD_FUNC(guildstorage) return -1; } - gstorage_storageopen(sd); + storage_guild_storageopen(sd); clif_displaymessage(fd, msg_txt(sd,920)); // Guild storage opened. return 0; } @@ -1374,8 +1374,8 @@ ACMD_FUNC(itemreset) nullpo_retr(-1, sd); for (i = 0; i < MAX_INVENTORY; i++) { - if (sd->status.inventory[i].amount && sd->status.inventory[i].equip == 0) { - pc_delitem(sd, i, sd->status.inventory[i].amount, 0, 0, LOG_TYPE_COMMAND); + if (sd->inventory.u.items_inventory[i].amount && sd->inventory.u.items_inventory[i].equip == 0) { + pc_delitem(sd, i, sd->inventory.u.items_inventory[i].amount, 0, 0, LOG_TYPE_COMMAND); } } clif_displaymessage(fd, msg_txt(sd,20)); // All of your items have been removed. @@ -2243,15 +2243,15 @@ ACMD_FUNC(refine) if (pc_is_same_equip_index((enum equip_index)j, sd->equip_index, i)) continue; - if(position && !(sd->status.inventory[i].equip & position)) + if(position && !(sd->inventory.u.items_inventory[i].equip & position)) continue; - final_refine = cap_value(sd->status.inventory[i].refine + refine, 0, MAX_REFINE); - if (sd->status.inventory[i].refine != final_refine) { - sd->status.inventory[i].refine = final_refine; - current_position = sd->status.inventory[i].equip; + final_refine = cap_value(sd->inventory.u.items_inventory[i].refine + refine, 0, MAX_REFINE); + if (sd->inventory.u.items_inventory[i].refine != final_refine) { + sd->inventory.u.items_inventory[i].refine = final_refine; + current_position = sd->inventory.u.items_inventory[i].equip; pc_unequipitem(sd, i, 3); - clif_refine(fd, 0, i, sd->status.inventory[i].refine); + clif_refine(fd, 0, i, sd->inventory.u.items_inventory[i].refine); clif_delitem(sd, i, 1, 3); clif_additem(sd, i, 1, 0); pc_equipitem(sd, i, current_position); @@ -4372,9 +4372,9 @@ ACMD_FUNC(repairall) count = 0; for (i = 0; i < MAX_INVENTORY; i++) { - if (sd->status.inventory[i].nameid && sd->status.inventory[i].attribute == 1) { - sd->status.inventory[i].attribute = 0; - clif_produceeffect(sd, 0, sd->status.inventory[i].nameid); + if (sd->inventory.u.items_inventory[i].nameid && sd->inventory.u.items_inventory[i].attribute == 1) { + sd->inventory.u.items_inventory[i].attribute = 0; + clif_produceeffect(sd, 0, sd->inventory.u.items_inventory[i].nameid); count++; } } @@ -5377,20 +5377,20 @@ ACMD_FUNC(dropall) } for( i = 0; i < MAX_INVENTORY; i++ ) { - if( sd->status.inventory[i].amount ) { - if( (item_data = itemdb_exists(sd->status.inventory[i].nameid)) == NULL ) { - ShowDebug("Non-existant item %d on dropall list (account_id: %d, char_id: %d)\n", sd->status.inventory[i].nameid, sd->status.account_id, sd->status.char_id); + if( sd->inventory.u.items_inventory[i].amount ) { + if( (item_data = itemdb_exists(sd->inventory.u.items_inventory[i].nameid)) == NULL ) { + ShowDebug("Non-existant item %d on dropall list (account_id: %d, char_id: %d)\n", sd->inventory.u.items_inventory[i].nameid, sd->status.account_id, sd->status.char_id); continue; } - if( !pc_candrop(sd,&sd->status.inventory[i]) ) + if( !pc_candrop(sd,&sd->inventory.u.items_inventory[i]) ) continue; if( type == -1 || type == (uint8)item_data->type ) { - if( sd->status.inventory[i].equip != 0 ) + if( sd->inventory.u.items_inventory[i].equip != 0 ) pc_unequipitem(sd, i, 3); - if(pc_dropitem(sd, i, sd->status.inventory[i].amount)) - count += sd->status.inventory[i].amount; - else count2 += sd->status.inventory[i].amount; + if(pc_dropitem(sd, i, sd->inventory.u.items_inventory[i].amount)) + count += sd->inventory.u.items_inventory[i].amount; + else count2 += sd->inventory.u.items_inventory[i].amount; } } } @@ -5417,10 +5417,10 @@ ACMD_FUNC(storeall) } for (i = 0; i < MAX_INVENTORY; i++) { - if (sd->status.inventory[i].amount) { - if(sd->status.inventory[i].equip != 0) + if (sd->inventory.u.items_inventory[i].amount) { + if(sd->inventory.u.items_inventory[i].equip != 0) pc_unequipitem(sd, i, 3); - storage_storageadd(sd, i, sd->status.inventory[i].amount); + storage_storageadd(sd, i, sd->inventory.u.items_inventory[i].amount); } } storage_storageclose(sd); @@ -5439,10 +5439,11 @@ ACMD_FUNC(clearstorage) return -1; } - j = sd->status.storage.storage_amount; + j = sd->storage.amount; for (i = 0; i < j; ++i) { - storage_delitem(sd, i, sd->status.storage.items[i].amount); + storage_delitem(sd, i, sd->storage.u.items_storage[i].amount); } + sd->state.storage_flag = 1; storage_storageclose(sd); clif_displaymessage(fd, msg_txt(sd,1394)); // Your storage was cleaned. @@ -5453,7 +5454,7 @@ ACMD_FUNC(cleargstorage) { int i, j; struct guild *g; - struct guild_storage *gstorage; + struct s_storage *gstorage; nullpo_retr(-1, sd); g = sd->guild; @@ -5473,24 +5474,18 @@ ACMD_FUNC(cleargstorage) return -1; } - gstorage = gstorage_get_storage(sd->status.guild_id); - if (gstorage == NULL) {// Doesn't have opened @gstorage yet, so we skip the deletion since *shouldn't* have any item there. + gstorage = guild2storage2(sd->status.guild_id); + if (gstorage == NULL) { // Doesn't have opened @gstorage yet, so we skip the deletion since *shouldn't* have any item there. return -1; } - if (gstorage->opened) { - struct map_session_data *tsd = map_charid2sd(gstorage->opened); - if (tsd) - gstorage_storageclose(tsd); - } - - j = gstorage->storage_amount; - gstorage->locked = true; // Lock @gstorage: do not allow any item to be retrieved or stored from any guild member + j = gstorage->amount; + gstorage->lock = true; // Lock @gstorage: do not allow any item to be retrieved or stored from any guild member for (i = 0; i < j; ++i) { - gstorage_delitem(sd, gstorage, i, gstorage->items[i].amount); + storage_guild_delitem(sd, gstorage, i, gstorage->u.items_guild[i].amount); } - gstorage_storageclose(sd); - gstorage->locked = false; // Cleaning done, release lock + storage_guild_storageclose(sd); + gstorage->lock = false; // Cleaning done, release lock clif_displaymessage(fd, msg_txt(sd,1395)); // Your guild storage was cleaned. return 0; @@ -5510,9 +5505,10 @@ ACMD_FUNC(clearcart) return -1; } - for( i = 0; i < MAX_CART; i++ ) - if(sd->status.cart[i].nameid > 0) - pc_cart_delitem(sd, i, sd->status.cart[i].amount, 1, LOG_TYPE_OTHER); + for (i = 0; i < MAX_CART; i++) { + if (sd->cart.u.items_cart[i].nameid > 0) + pc_cart_delitem(sd, i, sd->cart.u.items_cart[i].amount, 1, LOG_TYPE_OTHER); + } clif_clearcart(fd); clif_updatestatus(sd,SP_CARTINFO); @@ -6925,7 +6921,7 @@ ACMD_FUNC(identify) nullpo_retr(-1, sd); for(i=num=0;istatus.inventory[i].nameid > 0 && sd->status.inventory[i].identify!=1){ + if(sd->inventory.u.items_inventory[i].nameid > 0 && sd->inventory.u.items_inventory[i].identify != 1) { num++; } } @@ -6946,8 +6942,8 @@ ACMD_FUNC(identifyall) int i; nullpo_retr(-1, sd); for(i=0; istatus.inventory[i].nameid > 0 && sd->status.inventory[i].identify!=1) { - sd->status.inventory[i].identify=1; + if (sd->inventory.u.items_inventory[i].nameid > 0 && sd->inventory.u.items_inventory[i].identify != 1) { + sd->inventory.u.items_inventory[i].identify = 1; clif_item_identified(sd,i,0); } } @@ -8545,15 +8541,15 @@ ACMD_FUNC(itemlist) if( strcmp(parent_cmd, "storagelist") == 0 ) { location = "storage"; - items = sd->status.storage.items; + items = sd->storage.u.items_storage; size = sd->storage_size; } else if( strcmp(parent_cmd, "cartlist") == 0 ) { location = "cart"; - items = sd->status.cart; + items = sd->cart.u.items_cart; size = MAX_CART; } else if( strcmp(parent_cmd, "itemlist") == 0 ) { location = "inventory"; - items = sd->status.inventory; + items = sd->inventory.u.items_inventory; size = MAX_INVENTORY; } else return 1; @@ -8799,11 +8795,11 @@ ACMD_FUNC(delitem) // delete items while( amount && ( idx = pc_search_inventory(sd, nameid) ) != -1 ) { - int delamount = ( amount < sd->status.inventory[idx].amount ) ? amount : sd->status.inventory[idx].amount; + int delamount = ( amount < sd->inventory.u.items_inventory[idx].amount ) ? amount : sd->inventory.u.items_inventory[idx].amount; - if( sd->inventory_data[idx]->type == IT_PETEGG && sd->status.inventory[idx].card[0] == CARD0_PET ) + if( sd->inventory_data[idx]->type == IT_PETEGG && sd->inventory.u.items_inventory[idx].card[0] == CARD0_PET ) {// delete pet - intif_delete_petdata(MakeDWord(sd->status.inventory[idx].card[1], sd->status.inventory[idx].card[2])); + intif_delete_petdata(MakeDWord(sd->inventory.u.items_inventory[idx].card[1], sd->inventory.u.items_inventory[idx].card[2])); } pc_delitem(sd, idx, delamount, 0, 0, LOG_TYPE_COMMAND); @@ -9671,7 +9667,7 @@ ACMD_FUNC(cloneequip) { if (pc_is_same_equip_index((enum equip_index) i, pl_sd->equip_index, idx)) continue; - tmp_item = pl_sd->status.inventory[idx]; + tmp_item = pl_sd->inventory.u.items_inventory[idx]; if (itemdb_isspecial(tmp_item.card[0])) memset(tmp_item.card, 0, sizeof(tmp_item.card)); tmp_item.bound = 0; diff --git a/src/map/battle.c b/src/map/battle.c index 8bd97c2674..f8d34bfe06 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -3289,7 +3289,7 @@ static struct Damage battle_calc_multi_attack(struct Damage wd, struct block_lis sc_start(src,src,SC_QD_SHOT_READY,100,target->id,skill_get_time(RL_QD_SHOT,1)); } else if(sc && sc->data[SC_FEARBREEZE] && sd->weapontype1==W_BOW - && (i = sd->equip_index[EQI_AMMO]) >= 0 && sd->inventory_data[i] && sd->status.inventory[i].amount > 1) + && (i = sd->equip_index[EQI_AMMO]) >= 0 && sd->inventory_data[i] && sd->inventory.u.items_inventory[i].amount > 1) { int chance = rnd()%100; switch(sc->data[SC_FEARBREEZE]->val1) { @@ -3299,7 +3299,7 @@ static struct Damage battle_calc_multi_attack(struct Damage wd, struct block_lis case 2: case 1: if( chance < 13) { wd.div_ = 2; break; } // 12 % chance to attack 2 times. } - wd.div_ = min(wd.div_,sd->status.inventory[i].amount); + wd.div_ = min(wd.div_,sd->inventory.u.items_inventory[i].amount); sc->data[SC_FEARBREEZE]->val4 = wd.div_-1; if (wd.div_ > 1) wd.type = DMG_MULTI_HIT; @@ -3361,7 +3361,7 @@ static int battle_calc_attack_skill_ratio(struct Damage wd, struct block_list *s if (index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == IT_WEAPON) skillratio += -100 + sd->inventory_data[index]->weight / 10 + sstatus->rhw.atk + - 100 * sd->inventory_data[index]->wlv * (sd->status.inventory[index].refine + 6); + 100 * sd->inventory_data[index]->wlv * (sd->inventory.u.items_inventory[index].refine + 6); } status_change_end(src,SC_CRUSHSTRIKE,INVALID_TIMER); skill_break_equip(src,src,EQP_WEAPON,2000,BCT_SELF); @@ -4321,7 +4321,7 @@ static int64 battle_calc_skill_constant_addition(struct Damage wd, struct block_ short index = sd->equip_index[EQI_HAND_L]; if (index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == IT_ARMOR) - damagevalue = sstatus->vit * sd->status.inventory[index].refine; + damagevalue = sstatus->vit * sd->inventory.u.items_inventory[index].refine; atk = damagevalue; } break; @@ -5391,7 +5391,7 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src, struct bl short index = sd->equip_index[EQI_HAND_L]; if( index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == IT_ARMOR ) - ATK_ADD(wd.damage, wd.damage2, 10*sd->status.inventory[index].refine); + ATK_ADD(wd.damage, wd.damage2, 10*sd->inventory.u.items_inventory[index].refine); } #ifndef RENEWAL //Card Fix for attacker (sd), 2 is added to the "left" flag meaning "attacker cards only" @@ -7185,7 +7185,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t if( sd && battle_config.arrow_decrement && sc->data[SC_FEARBREEZE] && sc->data[SC_FEARBREEZE]->val4 > 0) { short idx = sd->equip_index[EQI_AMMO]; - if (idx >= 0 && sd->status.inventory[idx].amount >= sc->data[SC_FEARBREEZE]->val4) { + if (idx >= 0 && sd->inventory.u.items_inventory[idx].amount >= sc->data[SC_FEARBREEZE]->val4) { pc_delitem(sd,idx,sc->data[SC_FEARBREEZE]->val4,0,1,LOG_TYPE_CONSUME); sc->data[SC_FEARBREEZE]->val4 = 0; } diff --git a/src/map/buyingstore.c b/src/map/buyingstore.c index 910366c01d..ead241e1a9 100644 --- a/src/map/buyingstore.c +++ b/src/map/buyingstore.c @@ -182,7 +182,7 @@ int8 buyingstore_create(struct map_session_data* sd, int zenylimit, unsigned cha break; } - if( sd->status.inventory[idx].amount+amount > BUYINGSTORE_MAX_AMOUNT ) + if( sd->inventory.u.items_inventory[idx].amount + amount > BUYINGSTORE_MAX_AMOUNT ) {// too many items of same kind break; } @@ -386,13 +386,13 @@ void buyingstore_trade(struct map_session_data* sd, uint32 account_id, unsigned } } - if( index < 0 || index >= ARRAYLENGTH(sd->status.inventory) || sd->inventory_data[index] == NULL || sd->status.inventory[index].nameid != nameid || sd->status.inventory[index].amount < amount ) + if( index < 0 || index >= ARRAYLENGTH(sd->inventory.u.items_inventory) || sd->inventory_data[index] == NULL || sd->inventory.u.items_inventory[index].nameid != nameid || sd->inventory.u.items_inventory[index].amount < amount ) {// invalid input clif_buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_FAILED, nameid); return; } - if( sd->status.inventory[index].expire_time || (sd->status.inventory[index].bound && !pc_can_give_bounded_items(sd)) || !itemdb_cantrade(&sd->status.inventory[index], pc_get_group_level(sd), pc_get_group_level(pl_sd)) || memcmp(sd->status.inventory[index].card, buyingstore_blankslots, sizeof(buyingstore_blankslots)) ) + if( sd->inventory.u.items_inventory[index].expire_time || (sd->inventory.u.items_inventory[index].bound && !pc_can_give_bounded_items(sd)) || !itemdb_cantrade(&sd->inventory.u.items_inventory[index], pc_get_group_level(sd), pc_get_group_level(pl_sd)) || memcmp(sd->inventory.u.items_inventory[index].card, buyingstore_blankslots, sizeof(buyingstore_blankslots)) ) {// non-tradable item clif_buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_FAILED, nameid); return; @@ -447,7 +447,7 @@ void buyingstore_trade(struct map_session_data* sd, uint32 account_id, unsigned zeny = amount*pl_sd->buyingstore.items[listidx].price; // move item - pc_additem(pl_sd, &sd->status.inventory[index], amount, LOG_TYPE_BUYING_STORE); + pc_additem(pl_sd, &sd->inventory.u.items_inventory[index], amount, LOG_TYPE_BUYING_STORE); pc_delitem(sd, index, amount, 1, 0, LOG_TYPE_BUYING_STORE); pl_sd->buyingstore.items[listidx].amount-= amount; diff --git a/src/map/chrif.c b/src/map/chrif.c index 8e728fa7e9..51121f32e8 100644 --- a/src/map/chrif.c +++ b/src/map/chrif.c @@ -297,9 +297,14 @@ int chrif_save(struct map_session_data *sd, int flag) { chrif_bsdata_save(sd, (flag && (flag != 3))); + if (sd->state.storage_flag == 1) + intif_storage_save(sd,TABLE_STORAGE); + intif_storage_save(sd,TABLE_INVENTORY); + intif_storage_save(sd,TABLE_CART); + //For data sync if (sd->state.storage_flag == 2) - gstorage_storagesave(sd->status.account_id, sd->status.guild_id, flag); + storage_guild_storagesave(sd->status.account_id, sd->status.guild_id, flag); if (flag) sd->state.storage_flag = 0; //Force close it. @@ -1033,14 +1038,14 @@ int chrif_divorceack(uint32 char_id, int partner_id) { if( ( sd = map_charid2sd(char_id) ) != NULL && sd->status.partner_id == partner_id ) { sd->status.partner_id = 0; for(i = 0; i < MAX_INVENTORY; i++) - if (sd->status.inventory[i].nameid == WEDDING_RING_M || sd->status.inventory[i].nameid == WEDDING_RING_F) + if (sd->inventory.u.items_inventory[i].nameid == WEDDING_RING_M || sd->inventory.u.items_inventory[i].nameid == WEDDING_RING_F) pc_delitem(sd, i, 1, 0, 0, LOG_TYPE_OTHER); } if( ( sd = map_charid2sd(partner_id) ) != NULL && sd->status.partner_id == char_id ) { sd->status.partner_id = 0; for(i = 0; i < MAX_INVENTORY; i++) - if (sd->status.inventory[i].nameid == WEDDING_RING_M || sd->status.inventory[i].nameid == WEDDING_RING_F) + if (sd->inventory.u.items_inventory[i].nameid == WEDDING_RING_M || sd->inventory.u.items_inventory[i].nameid == WEDDING_RING_F) pc_delitem(sd, i, 1, 0, 0, LOG_TYPE_OTHER); } @@ -1975,7 +1980,7 @@ void do_final_chrif(void) { *------------------------------------------*/ void do_init_chrif(void) { if(sizeof(struct mmo_charstatus) > 0xFFFF){ - ShowError("mmo_charstatus size = %d is too big to be transmitted. (must be below 0xFFFF) \n", + ShowError("mmo_charstatus size = %d is too big to be transmitted. (must be below 0xFFFF)\n", sizeof(struct mmo_charstatus)); exit(EXIT_FAILURE); } @@ -1986,6 +1991,11 @@ void do_init_chrif(void) { exit(EXIT_FAILURE); } + if(sizeof(struct s_storage) > 0xFFFF) { + ShowError("s_storage size = %d is too big to be transmitted. (must be below 0xFFFF)\n", sizeof(struct s_storage)); + exit(EXIT_FAILURE); + } + auth_db = idb_alloc(DB_OPT_BASE); auth_db_ers = ers_new(sizeof(struct auth_node),"chrif.c::auth_db_ers",ERS_OPT_NONE); diff --git a/src/map/clif.c b/src/map/clif.c index f1e7911bf2..d7064904b1 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -1947,15 +1947,15 @@ void clif_selllist(struct map_session_data *sd) WFIFOW(fd,0)=0xc7; for( i = 0; i < MAX_INVENTORY; i++ ) { - if( sd->status.inventory[i].nameid > 0 && sd->inventory_data[i] ) + if( sd->inventory.u.items_inventory[i].nameid > 0 && sd->inventory_data[i] ) { - if( !itemdb_cansell(&sd->status.inventory[i], pc_get_group_level(sd)) ) + if( !itemdb_cansell(&sd->inventory.u.items_inventory[i], pc_get_group_level(sd)) ) continue; - if( sd->status.inventory[i].expire_time || (sd->status.inventory[i].bound && !pc_can_give_bounded_items(sd)) ) + if( sd->inventory.u.items_inventory[i].expire_time || (sd->inventory.u.items_inventory[i].bound && !pc_can_give_bounded_items(sd)) ) continue; // Cannot Sell Rental Items or Account Bounded Items - if( sd->status.inventory[i].bound && !pc_can_give_bounded_items(sd)) + if( sd->inventory.u.items_inventory[i].bound && !pc_can_give_bounded_items(sd)) continue; // Don't allow sale of bound items val=sd->inventory_data[i]->value_sell; @@ -2514,7 +2514,7 @@ void clif_additem(struct map_session_data *sd, int n, int amount, unsigned char } else { - if( n < 0 || n >= MAX_INVENTORY || sd->status.inventory[n].nameid <=0 || sd->inventory_data[n] == NULL ) + if( n < 0 || n >= MAX_INVENTORY || sd->inventory.u.items_inventory[n].nameid <=0 || sd->inventory_data[n] == NULL ) return; WFIFOW(fd,offs+0) = header; @@ -2523,11 +2523,11 @@ void clif_additem(struct map_session_data *sd, int n, int amount, unsigned char if (sd->inventory_data[n]->view_id > 0) WFIFOW(fd,offs+6) = sd->inventory_data[n]->view_id; else - WFIFOW(fd,offs+6) = sd->status.inventory[n].nameid; - WFIFOB(fd,offs+8) = sd->status.inventory[n].identify; - WFIFOB(fd,offs+9) = sd->status.inventory[n].attribute; - WFIFOB(fd,offs+10) = sd->status.inventory[n].refine; - clif_addcards(WFIFOP(fd,offs+11), &sd->status.inventory[n]); + WFIFOW(fd,offs+6)=sd->inventory.u.items_inventory[n].nameid; + WFIFOB(fd,offs+8)=sd->inventory.u.items_inventory[n].identify; + WFIFOB(fd,offs+9)=sd->inventory.u.items_inventory[n].attribute; + WFIFOB(fd,offs+10)=sd->inventory.u.items_inventory[n].refine; + clif_addcards(WFIFOP(fd,offs+11), &sd->inventory.u.items_inventory[n]); #if PACKETVER < 20120925 WFIFOW(fd,offs+19) = pc_equippoint(sd,n); #else @@ -2537,11 +2537,11 @@ void clif_additem(struct map_session_data *sd, int n, int amount, unsigned char WFIFOB(fd,offs+21) = itemtype(sd->inventory_data[n]->nameid); WFIFOB(fd,offs+22) = fail; #if PACKETVER >= 20061218 - WFIFOL(fd,offs+23) = sd->status.inventory[n].expire_time; + WFIFOL(fd,offs+23)=sd->inventory.u.items_inventory[n].expire_time; #endif #if PACKETVER >= 20071002 /* Yellow color only for non-stackable item */ - WFIFOW(fd,offs+27) = (sd->status.inventory[n].bound && !itemdb_isstackable(sd->status.inventory[n].nameid)) ? BOUND_DISPYELLOW : sd->inventory_data[n]->flag.bindOnEquip ? BOUND_ONEQUIP : 0; + WFIFOW(fd,offs+27)=(sd->inventory.u.items_inventory[n].bound && !itemdb_isstackable(sd->inventory.u.items_inventory[n].nameid)) ? BOUND_DISPYELLOW : sd->inventory_data[n]->flag.bindOnEquip ? BOUND_ONEQUIP : 0; #endif #if PACKETVER >= 20150226 clif_add_random_options(WFIFOP(fd,31), &sd->status.inventory[n]); @@ -2708,17 +2708,17 @@ void clif_inventorylist(struct map_session_data *sd) { for( i = 0, n = 0, ne = 0; i < MAX_INVENTORY; i++ ) { - if( sd->status.inventory[i].nameid <=0 || sd->inventory_data[i] == NULL ) + if( sd->inventory.u.items_inventory[i].nameid <=0 || sd->inventory_data[i] == NULL ) continue; if( !itemdb_isstackable2(sd->inventory_data[i]) ) { //Non-stackable (Equippable) - clif_item_sub(bufe, ne*se+4, i+2, &sd->status.inventory[i], sd->inventory_data[i], pc_equippoint(sd,i)); + clif_item_sub(bufe, ne*se+4, i+2, &sd->inventory.u.items_inventory[i], sd->inventory_data[i], pc_equippoint(sd,i)); ne++; } else { //Stackable. - clif_item_sub(buf, n*s+4,i+2, &sd->status.inventory[i], sd->inventory_data[i], -2); - if( sd->inventory_data[i]->equip == EQP_AMMO && sd->status.inventory[i].equip ) + clif_item_sub(buf, n*s+4,i+2, &sd->inventory.u.items_inventory[i], sd->inventory_data[i], -2); + if( sd->inventory_data[i]->equip == EQP_AMMO && sd->inventory.u.items_inventory[i].equip ) arrow=i; n++; } @@ -2755,9 +2755,9 @@ void clif_inventorylist(struct map_session_data *sd) { } #if PACKETVER >= 20111122 && PACKETVER < 20120925 for( i = 0; i < MAX_INVENTORY; i++ ) { - if( sd->status.inventory[i].nameid <= 0 || sd->inventory_data[i] == NULL ) + if( sd->inventory.u.items_inventory[i].nameid <= 0 || sd->inventory_data[i] == NULL ) continue; - if ( sd->status.inventory[i].favorite ) + if ( sd->inventory.u.items_inventory[i].favorite ) clif_favorite_item(sd, i); } #endif @@ -2787,13 +2787,13 @@ void clif_equiplist(struct map_session_data *sd) buf = WFIFOP(fd,0); for(i=0,n=0;istatus.inventory[i].nameid <=0 || sd->inventory_data[i] == NULL) + if (sd->inventory.u.items_inventory[i].nameid <=0 || sd->inventory_data[i] == NULL) continue; if(itemdb_isstackable2(sd->inventory_data[i])) continue; //Equippable - clif_item_sub(buf, n*cmd+4,i+2, &sd->status.inventory[i], sd->inventory_data[i], pc_equippoint(sd,i)); + clif_item_sub(buf, n*cmd+4,i+2, &sd->inventory.u.items_inventory[i], sd->inventory_data[i], pc_equippoint(sd,i)); n++; } if (n) { @@ -2935,15 +2935,15 @@ void clif_cartlist(struct map_session_data *sd) for( i = 0, n = 0, ne = 0; i < MAX_CART; i++ ) { - if( sd->status.cart[i].nameid <= 0 ) + if( sd->cart.u.items_cart[i].nameid <= 0 ) continue; - id = itemdb_search(sd->status.cart[i].nameid); + id = itemdb_search(sd->cart.u.items_cart[i].nameid); if( !itemdb_isstackable2(id) ) { //Equippable - clif_item_sub(bufe, ne*cmd+4,i+2, &sd->status.cart[i], id, id->equip); + clif_item_sub(bufe, ne*cmd+4,i+2, &sd->cart.u.items_cart[i], id, id->equip); ne++; } else { //Stackable - clif_item_sub(buf, n*s+4,i+2, &sd->status.cart[i], id,-1); + clif_item_sub(buf, n*s+4,i+2, &sd->cart.u.items_cart[i], id,-1); n++; } } @@ -3471,7 +3471,7 @@ void clif_changelook(struct block_list *bl, int type, int val) { if(sd->inventory_data[n]->view_id > 0) val = sd->inventory_data[n]->view_id; else - val = sd->status.inventory[n].nameid; + val = sd->inventory.u.items_inventory[n].nameid; } else val = 0; } @@ -3656,7 +3656,7 @@ void clif_arrow_create_list(struct map_session_data *sd) short j, nameid = skill_arrow_db[i].nameid; if (nameid > 0 && itemdb_exists(nameid) && (j = pc_search_inventory(sd, nameid)) >= 0 && - !sd->status.inventory[j].equip && sd->status.inventory[j].identify) + !sd->inventory.u.items_inventory[j].equip && sd->inventory.u.items_inventory[j].identify) { if ((j = itemdb_viewid(nameid)) > 0) WFIFOW(fd,c*2+4) = j; @@ -3923,7 +3923,7 @@ void clif_useitemack(struct map_session_data *sd,int index,int amount,bool ok) if(sd->inventory_data[index] && sd->inventory_data[index]->view_id > 0) WBUFW(buf,4)=sd->inventory_data[index]->view_id; else - WBUFW(buf,4)=sd->status.inventory[index].nameid; + WBUFW(buf,4)=sd->inventory.u.items_inventory[index].nameid; WBUFL(buf,6)=sd->bl.id; WBUFW(buf,10)=amount; WBUFB(buf,12)=ok; @@ -4277,20 +4277,20 @@ void clif_tradeadditem(struct map_session_data* sd, struct map_session_data* tsd if(sd->inventory_data[index] && sd->inventory_data[index]->view_id > 0) WBUFW(buf,6) = sd->inventory_data[index]->view_id; else - WBUFW(buf,6) = sd->status.inventory[index].nameid; // type id + WBUFW(buf,6) = sd->inventory.u.items_inventory[index].nameid; // type id #else if(sd->inventory_data[index] && sd->inventory_data[index]->view_id > 0) WBUFW(buf,2) = sd->inventory_data[index]->view_id; else - WBUFW(buf,2) = sd->status.inventory[index].nameid; // type id + WBUFW(buf,2) = sd->inventory.u.items_inventory[index].nameid; // type id WBUFB(buf,4) = sd->inventory_data[index]->type; // item type WBUFL(buf,5) = amount; // amount buf = WBUFP(buf,1); //Advance 1B #endif - WBUFB(buf,8) = sd->status.inventory[index].identify; //identify flag - WBUFB(buf,9) = sd->status.inventory[index].attribute; // attribute - WBUFB(buf,10)= sd->status.inventory[index].refine; //refine - clif_addcards(WBUFP(buf, 11), &sd->status.inventory[index]); + WBUFB(buf,8) = sd->inventory.u.items_inventory[index].identify; //identify flag + WBUFB(buf,9) = sd->inventory.u.items_inventory[index].attribute; // attribute + WBUFB(buf,10)= sd->inventory.u.items_inventory[index].refine; //refine + clif_addcards(WBUFP(buf, 11), &sd->inventory.u.items_inventory[index]); #if PACKETVER >= 20150226 clif_add_random_options(WBUFP(buf, 19), &sd->status.inventory[index]); #endif @@ -6356,10 +6356,10 @@ void clif_use_card(struct map_session_data *sd,int idx) continue; if(sd->inventory_data[i]->type!=IT_WEAPON && sd->inventory_data[i]->type!=IT_ARMOR) continue; - if(itemdb_isspecial(sd->status.inventory[i].card[0])) //Can't slot it + if(itemdb_isspecial(sd->inventory.u.items_inventory[i].card[0])) //Can't slot it continue; - if(sd->status.inventory[i].identify==0 ) //Not identified + if(sd->inventory.u.items_inventory[i].identify==0 ) //Not identified continue; if((sd->inventory_data[i]->equip&ep)==0) //Not equippable on this part. @@ -6368,11 +6368,11 @@ void clif_use_card(struct map_session_data *sd,int idx) if(sd->inventory_data[i]->type==IT_WEAPON && ep==EQP_SHIELD) //Shield card won't go on left weapon. continue; - ARR_FIND( 0, sd->inventory_data[i]->slot, j, sd->status.inventory[i].card[j] == 0 ); + ARR_FIND( 0, sd->inventory_data[i]->slot, j, sd->inventory.u.items_inventory[i].card[j] == 0 ); if( j == sd->inventory_data[i]->slot ) // No room continue; - if( sd->status.inventory[i].equip > 0 ) // Do not check items that are already equipped + if( sd->inventory.u.items_inventory[i].equip > 0 ) // Do not check items that are already equipped continue; WFIFOW(fd,4+c*2)=i+2; @@ -6421,7 +6421,7 @@ void clif_item_identify_list(struct map_session_data *sd) WFIFOHEAD(fd,MAX_INVENTORY * 2 + 4); WFIFOW(fd,0)=0x177; for(i=c=0;istatus.inventory[i].nameid > 0 && !sd->status.inventory[i].identify){ + if(sd->inventory.u.items_inventory[i].nameid > 0 && !sd->inventory.u.items_inventory[i].identify){ WFIFOW(fd,c*2+4)=i+2; c++; } @@ -6468,11 +6468,11 @@ void clif_item_repair_list(struct map_session_data *sd,struct map_session_data * WFIFOW(fd,0)=0x1fc; for(i=c=0;istatus.inventory[i].nameid) > 0 && dstsd->status.inventory[i].attribute!=0){// && skill_can_repair(sd,nameid)){ + if((nameid=dstsd->inventory.u.items_inventory[i].nameid) > 0 && dstsd->inventory.u.items_inventory[i].attribute!=0){// && skill_can_repair(sd,nameid)){ WFIFOW(fd,c*13+4) = i; WFIFOW(fd,c*13+6) = nameid; - WFIFOB(fd,c*13+8) = dstsd->status.inventory[i].refine; - clif_addcards(WFIFOP(fd,c*13+9), &dstsd->status.inventory[i]); + WFIFOB(fd,c*13+8) = dstsd->inventory.u.items_inventory[i].refine; + clif_addcards(WFIFOP(fd,c*13+9), &dstsd->inventory.u.items_inventory[i]); c++; } } @@ -6546,16 +6546,16 @@ void clif_item_refine_list(struct map_session_data *sd) refine_item[3] = refine_item[4] = pc_search_inventory(sd,ITEMID_ORIDECON); WFIFOHEAD(fd, MAX_INVENTORY * 13 + 4); - WFIFOW(fd,0)=0x221; - for(i=c=0;istatus.inventory[i].nameid > 0 && sd->status.inventory[i].refine < skill_lv && - sd->status.inventory[i].identify && (wlv=itemdb_wlv(sd->status.inventory[i].nameid)) >=1 && - refine_item[wlv]!=-1 && !(sd->status.inventory[i].equip&EQP_ARMS)){ + if(sd->inventory.u.items_inventory[i].nameid > 0 && sd->inventory.u.items_inventory[i].refine < skill_lv && + sd->inventory.u.items_inventory[i].identify && (wlv = itemdb_wlv(sd->inventory.u.items_inventory[i].nameid)) >=1 && + refine_item[wlv] != -1 && !(sd->inventory.u.items_inventory[i].equip&EQP_ARMS)){ WFIFOW(fd,c*13+ 4)=i+2; - WFIFOW(fd,c*13+ 6)=sd->status.inventory[i].nameid; - WFIFOB(fd,c*13+ 8)=sd->status.inventory[i].refine; - clif_addcards(WFIFOP(fd,c*13+9), &sd->status.inventory[i]); + WFIFOW(fd,c*13+ 6) = sd->inventory.u.items_inventory[i].nameid; + WFIFOB(fd,c*13+ 8) = sd->inventory.u.items_inventory[i].refine; + clif_addcards(WFIFOP(fd,c*13+9), &sd->inventory.u.items_inventory[i]); c++; } } @@ -6611,7 +6611,7 @@ void clif_cart_additem(struct map_session_data *sd,int n,int amount,int fail) nullpo_retv(sd); fd=sd->fd; - if(n<0 || n>=MAX_CART || sd->status.cart[n].nameid<=0) + if(n < 0 || n >= MAX_CART || sd->cart.u.items_cart[n].nameid <= 0) return; WFIFOHEAD(fd,packet_len(cmd)); @@ -6619,20 +6619,20 @@ void clif_cart_additem(struct map_session_data *sd,int n,int amount,int fail) WBUFW(buf,0)=cmd; WBUFW(buf,2)=n+2; WBUFL(buf,4)=amount; - if((view = itemdb_viewid(sd->status.cart[n].nameid)) > 0) + if((view = itemdb_viewid(sd->cart.u.items_cart[n].nameid)) > 0) WBUFW(buf,8)=view; else - WBUFW(buf,8)=sd->status.cart[n].nameid; + WBUFW(buf,8)=sd->cart.u.items_cart[n].nameid; #if PACKETVER >= 5 - WBUFB(buf,10)=itemdb_type(sd->status.cart[n].nameid); + WBUFB(buf,10)=itemdb_type(sd->cart.u.items_cart[n].nameid); offset += 1; #endif - WBUFB(buf,10+offset)=sd->status.cart[n].identify; - WBUFB(buf,11+offset)=sd->status.cart[n].attribute; - WBUFB(buf,12+offset)=sd->status.cart[n].refine; - clif_addcards(WBUFP(buf,13+offset), &sd->status.cart[n]); + WBUFB(buf,10+offset)=sd->cart.u.items_cart[n].identify; + WBUFB(buf,11+offset)=sd->cart.u.items_cart[n].attribute; + WBUFB(buf,12+offset)=sd->cart.u.items_cart[n].refine; + clif_addcards(WBUFP(buf,13+offset), &sd->cart.u.items_cart[n]); #if PACKETVER >= 20150226 - clif_add_random_options(WBUFP(buf,21+offset), &sd->status.cart[n]); + clif_add_random_options(WBUFP(buf,21+offset), &sd->cart.u.items_cart[n]); #endif WFIFOSET(fd,packet_len(cmd)); } @@ -6895,6 +6895,9 @@ void clif_openvendingreq(struct map_session_data* sd, int num) nullpo_retv(sd); + intif_storage_save(sd, TABLE_CART); // Save cart item data + intif_storage_request(sd, TABLE_CART); // Update cart item ID information + fd = sd->fd; WFIFOHEAD(fd,packet_len(0x12d)); WFIFOW(fd,0) = 0x12d; @@ -6985,18 +6988,18 @@ void clif_vendinglist(struct map_session_data* sd, int id, struct s_vending* ven for( i = 0; i < count; i++ ) { int index = vending[i].index; - struct item_data* data = itemdb_search(vsd->status.cart[index].nameid); + struct item_data* data = itemdb_search(vsd->cart.u.items_cart[index].nameid); WFIFOL(fd,offset+ 0+i*item_length) = vending[i].value; WFIFOW(fd,offset+ 4+i*item_length) = vending[i].amount; WFIFOW(fd,offset+ 6+i*item_length) = vending[i].index + 2; WFIFOB(fd,offset+ 8+i*item_length) = itemtype(data->nameid); - WFIFOW(fd,offset+ 9+i*item_length) = ( data->view_id > 0 ) ? data->view_id : vsd->status.cart[index].nameid; - WFIFOB(fd,offset+11+i*item_length) = vsd->status.cart[index].identify; - WFIFOB(fd,offset+12+i*item_length) = vsd->status.cart[index].attribute; - 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]); + WFIFOW(fd,offset+ 9+i*item_length) = ( data->view_id > 0 ) ? data->view_id : vsd->cart.u.items_cart[index].nameid; + WFIFOB(fd,offset+11+i*item_length) = vsd->cart.u.items_cart[index].identify; + WFIFOB(fd,offset+12+i*item_length) = vsd->cart.u.items_cart[index].attribute; + WFIFOB(fd,offset+13+i*item_length) = vsd->cart.u.items_cart[index].refine; + clif_addcards(WFIFOP(fd,offset+14+i*item_length), &vsd->cart.u.items_cart[index]); #if PACKETVER >= 20150226 - clif_add_random_options(WFIFOP(fd,offset+22+i*item_length), &vsd->status.cart[index]); + clif_add_random_options(WFIFOP(fd,offset+22+i*item_length), &vsd->cart.u.items_cart[index]); #endif } WFIFOSET(fd,WFIFOW(fd,2)); @@ -7070,18 +7073,18 @@ void clif_openvending(struct map_session_data* sd, int id, struct s_vending* ven WFIFOL(fd,4) = id; for( i = 0; i < count; i++ ) { int index = vending[i].index; - struct item_data* data = itemdb_search(sd->status.cart[index].nameid); + struct item_data* data = itemdb_search(sd->cart.u.items_cart[index].nameid); WFIFOL(fd, 8+i*item_length) = vending[i].value; WFIFOW(fd,12+i*item_length) = vending[i].index + 2; WFIFOW(fd,14+i*item_length) = vending[i].amount; WFIFOB(fd,16+i*item_length) = itemtype(data->nameid); - WFIFOW(fd,17+i*item_length) = ( data->view_id > 0 ) ? data->view_id : sd->status.cart[index].nameid; - WFIFOB(fd,19+i*item_length) = sd->status.cart[index].identify; - WFIFOB(fd,20+i*item_length) = sd->status.cart[index].attribute; - WFIFOB(fd,21+i*item_length) = sd->status.cart[index].refine; - clif_addcards(WFIFOP(fd,22+i*item_length), &sd->status.cart[index]); + WFIFOW(fd,17+i*item_length) = ( data->view_id > 0 ) ? data->view_id : sd->cart.u.items_cart[index].nameid; + WFIFOB(fd,19+i*item_length) = sd->cart.u.items_cart[index].identify; + WFIFOB(fd,20+i*item_length) = sd->cart.u.items_cart[index].attribute; + WFIFOB(fd,21+i*item_length) = sd->cart.u.items_cart[index].refine; + clif_addcards(WFIFOP(fd,22+i*item_length), &sd->cart.u.items_cart[index]); #if PACKETVER >= 20150226 - clif_add_random_options(WFIFOP(fd,30+i*item_length), &sd->status.cart[index]); + clif_add_random_options(WFIFOP(fd,30+i*item_length), &sd->cart.u.items_cart[index]); #endif } WFIFOSET(fd,WFIFOW(fd,2)); @@ -7601,9 +7604,9 @@ void clif_sendegg(struct map_session_data *sd) WFIFOHEAD(fd, MAX_INVENTORY * 2 + 4); WFIFOW(fd,0)=0x1a6; for(i=0,n=0;istatus.inventory[i].nameid<=0 || sd->inventory_data[i] == NULL || - sd->inventory_data[i]->type!=IT_PETEGG || - sd->status.inventory[i].amount<=0) + if(sd->inventory.u.items_inventory[i].nameid <= 0 || sd->inventory_data[i] == NULL || + sd->inventory_data[i]->type != IT_PETEGG || + sd->inventory.u.items_inventory[i].amount <= 0) continue; WFIFOW(fd,n*2+4)=i+2; n++; @@ -9126,21 +9129,21 @@ void clif_messagecolor2(struct map_session_data *sd, unsigned long color, const void clif_refresh_storagewindow(struct map_session_data *sd) { // Notify the client that the storage is open if( sd->state.storage_flag == 1 ) { - storage_sortitem(sd->status.storage.items, ARRAYLENGTH(sd->status.storage.items)); - clif_storagelist(sd, sd->status.storage.items, ARRAYLENGTH(sd->status.storage.items)); - clif_updatestorageamount(sd, sd->status.storage.storage_amount, MAX_STORAGE); + storage_sortitem(sd->storage.u.items_storage, ARRAYLENGTH(sd->storage.u.items_storage)); + clif_storagelist(sd, sd->storage.u.items_storage, ARRAYLENGTH(sd->storage.u.items_storage)); + clif_updatestorageamount(sd, sd->storage.amount, MAX_STORAGE); } // Notify the client that the gstorage is open otherwise it will // remain locked forever and nobody will be able to access it if( sd->state.storage_flag == 2 ) { - struct guild_storage *gstor = gstorage_get_storage(sd->status.guild_id); + struct s_storage *gstor = guild2storage2(sd->status.guild_id); if( !gstor ) // Shouldn't happen. The information should already be at the map-server intif_request_guild_storage(sd->status.account_id, sd->status.guild_id); else { - storage_sortitem(gstor->items, ARRAYLENGTH(gstor->items)); - clif_storagelist(sd, gstor->items, ARRAYLENGTH(gstor->items)); - clif_updatestorageamount(sd, gstor->storage_amount, MAX_GUILD_STORAGE); + storage_sortitem(gstor->u.items_guild, ARRAYLENGTH(gstor->u.items_guild)); + clif_storagelist(sd, gstor->u.items_guild, ARRAYLENGTH(gstor->u.items_guild)); + clif_updatestorageamount(sd, gstor->amount, MAX_GUILD_STORAGE); } } } @@ -9674,12 +9677,12 @@ void clif_viewequip_ack(struct map_session_data* sd, struct map_session_data* ts for(i=0,n=0; i < MAX_INVENTORY; i++) { - if (tsd->status.inventory[i].nameid <= 0 || tsd->inventory_data[i] == NULL) // Item doesn't exist + if (tsd->inventory.u.items_inventory[i].nameid <= 0 || tsd->inventory_data[i] == NULL) // Item doesn't exist continue; if (!itemdb_isequip2(tsd->inventory_data[i])) // Is not equippable continue; // Add item info : refine, identify flag, element, etc. - clif_item_sub(WBUFP(buf,0), n*s+43,i + 2, &tsd->status.inventory[i], tsd->inventory_data[i], pc_equippoint(tsd, i)); + clif_item_sub(WBUFP(buf,0), n*s+43,i + 2, &tsd->inventory.u.items_inventory[i], tsd->inventory_data[i], pc_equippoint(tsd, i)); n++; } @@ -11222,7 +11225,7 @@ void clif_parse_EquipItem(int fd,struct map_session_data *sd) else if (pc_cant_act2(sd)) return; - if(!sd->status.inventory[index].identify) { + if(!sd->inventory.u.items_inventory[index].identify) { clif_equipitemack(sd,index,0,ITEM_EQUIP_ACK_FAIL); // fail return; } @@ -12312,8 +12315,8 @@ void clif_parse_ItemIdentify(int fd,struct map_session_data *sd) { // - Invalid item ID or item doesn't exist // - Item is already identified if (idx < 0 || idx >= MAX_INVENTORY || - sd->status.inventory[idx].nameid <= 0 || sd->inventory_data[idx] == NULL || - sd->status.inventory[idx].identify) {// cancel pressed + sd->inventory.u.items_inventory[idx].nameid <= 0 || sd->inventory_data[idx] == NULL || + sd->inventory.u.items_inventory[idx].identify) {// cancel pressed clif_menuskill_clear(sd); return; } @@ -12457,7 +12460,7 @@ void clif_parse_MoveToKafra(int fd, struct map_session_data *sd) storage_storageadd(sd, item_index, item_amount); else if (sd->state.storage_flag == 2) - gstorage_storageadd(sd, item_index, item_amount); + storage_guild_storageadd(sd, item_index, item_amount); } @@ -12476,7 +12479,7 @@ void clif_parse_MoveFromKafra(int fd,struct map_session_data *sd) if (sd->state.storage_flag == 1) storage_storageget(sd, item_index, item_amount); else if(sd->state.storage_flag == 2) - gstorage_storageget(sd, item_index, item_amount); + storage_guild_storageget(sd, item_index, item_amount); } @@ -12496,7 +12499,7 @@ void clif_parse_MoveToKafraFromCart(int fd, struct map_session_data *sd){ if (sd->state.storage_flag == 1) storage_storageaddfromcart(sd, idx, amount); else if (sd->state.storage_flag == 2) - gstorage_storageaddfromcart(sd, idx, amount); + storage_guild_storageaddfromcart(sd, idx, amount); } @@ -12516,7 +12519,7 @@ void clif_parse_MoveFromKafraToCart(int fd, struct map_session_data *sd){ storage_storagegettocart(sd, idx, amount); else if (sd->state.storage_flag == 2) - gstorage_storagegettocart(sd, idx, amount); + storage_guild_storagegettocart(sd, idx, amount); } @@ -12528,7 +12531,7 @@ void clif_parse_CloseKafra(int fd, struct map_session_data *sd) storage_storageclose(sd); else if( sd->state.storage_flag == 2 ) - gstorage_storageclose(sd); + storage_guild_storageclose(sd); } @@ -13857,7 +13860,7 @@ void clif_account_name(int fd, uint32 account_id, const char* accname) //! TODO: Figure out how does this actually work void clif_parse_GMReqAccountName(int fd, struct map_session_data *sd) { - int account_id = RFIFOL(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0]); + uint32 account_id = RFIFOL(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0]); /* char query[30]; safesnprintf(query,sizeof(query),"%d", account_id); @@ -15303,23 +15306,22 @@ void clif_parse_Auction_setitem(int fd, struct map_session_data *sd){ return; } - if( amount != 1 || amount > sd->status.inventory[idx].amount ) { // By client, amount is always set to 1. Maybe this is a future implementation. + if( amount != 1 || amount > sd->inventory.u.items_inventory[idx].amount ) { // By client, amount is always set to 1. Maybe this is a future implementation. ShowWarning("Character %s trying to set invalid amount in auctions.\n", sd->status.name); return; } - if( (item = itemdb_exists(sd->status.inventory[idx].nameid)) != NULL && !(item->type == IT_ARMOR || item->type == IT_PETARMOR || item->type == IT_WEAPON || item->type == IT_CARD || item->type == IT_ETC || item->type == IT_SHADOWGEAR) ) + if( (item = itemdb_exists(sd->inventory.u.items_inventory[idx].nameid)) != NULL && !(item->type == IT_ARMOR || item->type == IT_PETARMOR || item->type == IT_WEAPON || item->type == IT_CARD || item->type == IT_ETC || item->type == IT_SHADOWGEAR) ) { // Consumable or pets are not allowed clif_Auction_setitem(sd->fd, idx, true); return; } - if( !pc_can_give_items(sd) || sd->status.inventory[idx].expire_time || - !sd->status.inventory[idx].identify || - (sd->status.inventory[idx].bound && !pc_can_give_bounded_items(sd)) || - !itemdb_available(sd->status.inventory[idx].nameid) || - !itemdb_canauction(&sd->status.inventory[idx],pc_get_group_level(sd)) // Quest Item or something else - ) { + if( !pc_can_give_items(sd) || sd->inventory.u.items_inventory[idx].expire_time || + !sd->inventory.u.items_inventory[idx].identify || + (sd->inventory.u.items_inventory[idx].bound && !pc_can_give_bounded_items(sd)) || + !itemdb_available(sd->inventory.u.items_inventory[idx].nameid) || + !itemdb_canauction(&sd->inventory.u.items_inventory[idx],pc_get_group_level(sd)) ) { // Quest Item or something else clif_Auction_setitem(sd->fd, idx, true); return; } @@ -15398,7 +15400,7 @@ void clif_parse_Auction_register(int fd, struct map_session_data *sd) } // Auction checks... - if( sd->status.inventory[sd->auction.index].bound && !pc_can_give_bounded_items(sd) ) { + if( sd->inventory.u.items_inventory[sd->auction.index].bound && !pc_can_give_bounded_items(sd) ) { clif_displaymessage(sd->fd, msg_txt(sd,293)); clif_Auction_message(fd, 2); // The auction has been canceled return; @@ -15420,13 +15422,13 @@ void clif_parse_Auction_register(int fd, struct map_session_data *sd) auction.buyer_id = 0; memset(auction.buyer_name, '\0', sizeof(auction.buyer_name)); - if( sd->status.inventory[sd->auction.index].nameid == 0 || sd->status.inventory[sd->auction.index].amount < sd->auction.amount ) + if( sd->inventory.u.items_inventory[sd->auction.index].nameid == 0 || sd->inventory.u.items_inventory[sd->auction.index].amount < sd->auction.amount ) { clif_Auction_message(fd, 2); // The auction has been canceled return; } - if( (item = itemdb_exists(sd->status.inventory[sd->auction.index].nameid)) == NULL ) + if( (item = itemdb_exists(sd->inventory.u.items_inventory[sd->auction.index].nameid)) == NULL ) { // Just in case clif_Auction_message(fd, 2); // The auction has been canceled return; @@ -15434,7 +15436,7 @@ void clif_parse_Auction_register(int fd, struct map_session_data *sd) safestrncpy(auction.item_name, item->jname, sizeof(auction.item_name)); auction.type = item->type; - memcpy(&auction.item, &sd->status.inventory[sd->auction.index], sizeof(struct item)); + memcpy(&auction.item, &sd->inventory.u.items_inventory[sd->auction.index], sizeof(struct item)); auction.item.amount = 1; auction.timestamp = 0; @@ -17426,9 +17428,9 @@ int clif_spellbook_list(struct map_session_data *sd) for( i = 0, c = 0; i < MAX_INVENTORY; i ++ ) { - if( itemdb_is_spellbook2(sd->status.inventory[i].nameid) ) + if( itemdb_is_spellbook2(sd->inventory.u.items_inventory[i].nameid) ) { - WFIFOW(fd, c * 2 + 4) = sd->status.inventory[i].nameid; + WFIFOW(fd, c * 2 + 4) = sd->inventory.u.items_inventory[i].nameid; c++; } } @@ -17464,8 +17466,8 @@ int clif_magicdecoy_list(struct map_session_data *sd, uint16 skill_lv, short x, WFIFOW(fd,0) = 0x1ad; // This is the official packet. [pakpil] for( i = 0, c = 0; i < MAX_INVENTORY; i ++ ) { - if( itemdb_is_element(sd->status.inventory[i].nameid) ) { - WFIFOW(fd, c * 2 + 4) = sd->status.inventory[i].nameid; + if( itemdb_is_element(sd->inventory.u.items_inventory[i].nameid) ) { + WFIFOW(fd, c * 2 + 4) = sd->inventory.u.items_inventory[i].nameid; c ++; } } @@ -17497,8 +17499,8 @@ int clif_poison_list(struct map_session_data *sd, uint16 skill_lv) { WFIFOW(fd,0) = 0x1ad; // This is the official packet. [pakpil] for( i = 0, c = 0; i < MAX_INVENTORY; i ++ ) { - if( itemdb_is_poison(sd->status.inventory[i].nameid) ) { - WFIFOW(fd, c * 2 + 4) = sd->status.inventory[i].nameid; + if( itemdb_is_poison(sd->inventory.u.items_inventory[i].nameid) ) { + WFIFOW(fd, c * 2 + 4) = sd->inventory.u.items_inventory[i].nameid; c ++; } } @@ -17638,10 +17640,10 @@ void clif_parse_MoveItem(int fd, struct map_session_data *sd) { if (index < 0 || index >= MAX_INVENTORY) return; - if ( sd->status.inventory[index].favorite && type == 1 ) - sd->status.inventory[index].favorite = 0; + if ( sd->inventory.u.items_inventory[index].favorite && type == 1 ) + sd->inventory.u.items_inventory[index].favorite = 0; else if( type == 0 ) - sd->status.inventory[index].favorite = 1; + sd->inventory.u.items_inventory[index].favorite = 1; else return;/* nothing to do. */ @@ -17658,7 +17660,7 @@ void clif_favorite_item(struct map_session_data* sd, unsigned short index) { WFIFOHEAD(fd,packet_len(0x908)); WFIFOW(fd,0) = 0x908; WFIFOW(fd,2) = index+2; - WFIFOL(fd,4) = (sd->status.inventory[index].favorite == 1) ? 0 : 1; + WFIFOL(fd,4) = (sd->inventory.u.items_inventory[index].favorite == 1) ? 0 : 1; WFIFOSET(fd,packet_len(0x908)); } @@ -18471,7 +18473,7 @@ static bool clif_merge_item_has_pair(struct map_session_data *sd, struct item *i nullpo_retr(false, sd); - ARR_FIND(0, MAX_INVENTORY, i, (it_ = &sd->status.inventory[i]) && it->nameid == it_->nameid && it->bound == it_->bound && memcmp(it_, it, sizeof(struct item)) != 0); + ARR_FIND(0, MAX_INVENTORY, i, (it_ = &sd->inventory.u.items_inventory[i]) && it->nameid == it_->nameid && it->bound == it_->bound && memcmp(it_, it, sizeof(struct item)) != 0); if (i < MAX_INVENTORY) return true; @@ -18521,7 +18523,7 @@ void clif_merge_item_open(struct map_session_data *sd) { // Get entries for (i = 0; i < MAX_INVENTORY; i++) { - if (!clif_merge_item_check(sd->inventory_data[i], (it = &sd->status.inventory[i]))) + if (!clif_merge_item_check(sd->inventory_data[i], (it = &sd->inventory.u.items_inventory[i]))) continue; if (clif_merge_item_has_pair(sd, it)) indexes[n++] = i; @@ -18568,14 +18570,14 @@ void clif_parse_merge_item_req(int fd, struct map_session_data* sd) { for (i = 0, j = 0; i < n; i++) { unsigned short idx = RFIFOW(fd, info->pos[1] + i*2) - 2; - if (!clif_merge_item_check((id = sd->inventory_data[idx]), &sd->status.inventory[idx])) + if (!clif_merge_item_check((id = sd->inventory_data[idx]), &sd->inventory.u.items_inventory[idx])) continue; indexes[j] = idx; if (j && id->nameid != sd->inventory_data[indexes[0]]->nameid) { // Only can merge 1 kind at once clif_merge_item_ack(sd, 0, 0, MERGE_ITEM_FAILED_NOT_MERGE); return; } - count += sd->status.inventory[idx].amount; + count += sd->inventory.u.items_inventory[idx].amount; j++; } @@ -18591,13 +18593,13 @@ void clif_parse_merge_item_req(int fd, struct map_session_data* sd) { // Merrrrge!!!! for (i = 1; i < n; i++) { - unsigned short idx = indexes[i], amt = sd->status.inventory[idx].amount; - log_pick_pc(sd, LOG_TYPE_MERGE_ITEM, -amt, &sd->status.inventory[idx]); - memset(&sd->status.inventory[idx], 0, sizeof(sd->status.inventory[0])); + unsigned short idx = indexes[i], amt = sd->inventory.u.items_inventory[idx].amount; + log_pick_pc(sd, LOG_TYPE_MERGE_ITEM, -amt, &sd->inventory.u.items_inventory[idx]); + memset(&sd->inventory.u.items_inventory[idx], 0, sizeof(sd->inventory.u.items_inventory[0])); sd->inventory_data[idx] = NULL; clif_delitem(sd, idx, amt, 0); } - sd->status.inventory[indexes[0]].amount = count; + sd->inventory.u.items_inventory[indexes[0]].amount = count; clif_merge_item_ack(sd, indexes[0]+2, count, MERGE_ITEM_SUCCESS); } diff --git a/src/map/clif.h b/src/map/clif.h index ab5e34b13e..ecd2e065c6 100644 --- a/src/map/clif.h +++ b/src/map/clif.h @@ -10,8 +10,7 @@ struct Channel; struct item; -struct storage_data; -struct guild_storage; +struct s_storage; //#include "map.h" struct block_list; struct unit_data; diff --git a/src/map/guild.c b/src/map/guild.c index f13faacb16..8aa30ad1be 100644 --- a/src/map/guild.c +++ b/src/map/guild.c @@ -853,7 +853,7 @@ int guild_member_withdraw(int guild_id, uint32 account_id, uint32 char_id, int f if(sd != NULL && sd->status.guild_id == guild_id) { // do stuff that needs the guild_id first, BEFORE we wipe it if (sd->state.storage_flag == 2) //Close the guild storage. - gstorage_storageclose(sd); + storage_guild_storageclose(sd); guild_send_dot_remove(sd); channel_pcquit(sd,3); //leave guild and ally chan sd->status.guild_id = 0; @@ -884,29 +884,35 @@ void guild_retrieveitembound(uint32 char_id, uint32 account_id, int guild_id) { int j; j = pc_bound_chk(sd,BOUND_GUILD,idxlist); if (j) { - struct guild_storage* stor = gstorage_guild2storage(sd->status.guild_id); + struct s_storage* stor = guild2storage(sd->status.guild_id); + struct guild *g = guild_search(guild_id); int i; - // Close the storage first if someone open it - if (stor && stor->opened) { - struct map_session_data *tsd = map_charid2sd(stor->opened); - if (tsd) - gstorage_storageclose(tsd); + if (stor && stor->status) { //Someone is in guild storage, close them + int i; + for (i = 0; i < g->max_member; i++) { + TBL_PC *pl_sd = g->member[i].sd; + if (pl_sd && pl_sd->state.storage_flag == 2) + storage_guild_storageclose(pl_sd); + } } for (i = 0; i < j; i++) { //Loop the matching items, gstorage_additem takes care of opening storage if (stor) - gstorage_additem(sd,stor,&sd->status.inventory[idxlist[i]],sd->status.inventory[idxlist[i]].amount); - pc_delitem(sd,idxlist[i],sd->status.inventory[idxlist[i]].amount,0,4,LOG_TYPE_GSTORAGE); + storage_guild_additem(sd,stor,&sd->inventory.u.items_inventory[idxlist[i]],sd->inventory.u.items_inventory[idxlist[i]].amount); + pc_delitem(sd,idxlist[i],sd->inventory.u.items_inventory[idxlist[i]].amount,0,4,LOG_TYPE_GSTORAGE); } - gstorage_storageclose(sd); //Close and save the storage + storage_guild_storageclose(sd); //Close and save the storage } } else { //Character is offline, ask char server to do the job - struct guild_storage* stor = gstorage_get_storage(guild_id); + struct s_storage* stor = guild2storage2(guild_id); struct guild *g = guild_search(guild_id); nullpo_retv(g); - if(stor && stor->opened) { //Someone is in guild storage, close them - struct map_session_data *tsd = map_charid2sd(stor->opened); - if (tsd) - gstorage_storageclose(tsd); + if (stor && stor->status) { //Someone is in guild storage, close them + int i; + for (i = 0; i < g->max_member; i++) { + TBL_PC *pl_sd = g->member[i].sd; + if (pl_sd && pl_sd->state.storage_flag == 2) + storage_guild_storageclose(pl_sd); + } } intif_itembound_guild_retrieve(char_id,account_id,guild_id); } @@ -1701,7 +1707,7 @@ int guild_broken(int guild_id,int flag) { struct map_session_data *sd = g->member[i].sd; if(sd != NULL){ if(sd->state.storage_flag == 2) - gstorage_storage_quit(sd,1); + storage_guild_storage_quit(sd,1); sd->status.guild_id=0; sd->guild = NULL; sd->state.gmaster_flag = 0; @@ -1716,7 +1722,7 @@ int guild_broken(int guild_id,int flag) { guild_db->foreach(guild_db,guild_broken_sub,guild_id); castle_db->foreach(castle_db,castle_guild_broken_sub,guild_id); - gstorage_delete(guild_id); + storage_guild_delete(guild_id); if( channel_config.ally_enable ) { channel_delete(g->channel); } @@ -1859,7 +1865,7 @@ int guild_break(struct map_session_data *sd,char *name) { //Guild bound item check - Removes the bound flag j = pc_bound_chk(sd,BOUND_GUILD,idxlist); for(i = 0; i < j; i++) - pc_delitem(sd,idxlist[i],sd->status.inventory[idxlist[i]].amount,0,1,LOG_TYPE_BOUND_REMOVAL); + pc_delitem(sd,idxlist[i],sd->inventory.u.items_inventory[idxlist[i]].amount,0,1,LOG_TYPE_BOUND_REMOVAL); #endif intif_guild_break(g->guild_id); diff --git a/src/map/intif.c b/src/map/intif.c index 5d0b30ddec..af1c2b361e 100644 --- a/src/map/intif.c +++ b/src/map/intif.c @@ -21,10 +21,12 @@ #include "elemental.h" #include "mail.h" #include "quest.h" +#include "status.h" #include -static const int packet_len_table[]={ +/// Received packet Lengths from inter-server +static const int packet_len_table[] = { -1,-1,27,-1, -1, 0,37,-1, 10+NAME_LENGTH,-1, 0, 0, 0, 0, 0, 0, //0x3800-0x380f 0, 0, 0, 0, 0, 0, 0, 0, -1,11, 0, 0, 0, 0, 0, 0, //0x3810 39,-1,15,15, 14,19, 7,-1, 0, 0, 0, 0, 0, 0, 0, 0, //0x3820 @@ -33,7 +35,7 @@ static const int packet_len_table[]={ -1,-1, 7, 7, 7,11, 8,-1, 0, 0, 0, 0, 0, 0, 0, 0, //0x3850 Auctions [Zephyrus] itembound[Akinari] -1, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3860 Quests [Kevin] [Inkfish] -1, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 3, 3, 0, //0x3870 Mercenaries [Zephyrus] / Elemental [pakpil] - 12,-1, 7, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3880 + 12,-1, 7, 3, 0, 0, 0, 0, 0, 0,-1, 8, 0, 0, 0, 0, //0x3880 Pet System, Storages -1,-1, 7, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3890 Homunculus [albator] }; @@ -52,6 +54,23 @@ int CheckForCharServer(void) return ((char_fd <= 0) || session[char_fd] == NULL || session[char_fd]->wdata == NULL); } +/** + * Get sd from pc_db (map_id2db) or auth_db (in case if parsing packet from inter-server when sd not added to pc_db yet) + * @param account_id + * @param char_id + * @return sd Found sd or NULL if not found + */ +struct map_session_data *inter_search_sd(uint32 account_id, uint32 char_id) +{ + struct map_session_data *sd = NULL; + struct auth_node *node = chrif_auth_check(account_id, char_id, ST_LOGIN); + if (node) + sd = node->sd; + else + sd = map_id2sd(account_id); + return sd; +} + /** * Request the char-serv to create a pet (to register it actually) * @param account_id @@ -493,40 +512,40 @@ int intif_request_registry(struct map_session_data *sd, int flag) /** * Request to load guild storage from char-serv - * @param account_id : Player account identification - * @param guild_id : Guild of player - * @return 0:error, 1=msg sent + * @param account_id: Player account identification + * @param guild_id: Guild of player + * @return false - error, true - message sent */ -int intif_request_guild_storage(uint32 account_id,int guild_id) +bool intif_request_guild_storage(uint32 account_id, int guild_id) { if (CheckForCharServer()) - return 0; + return false; WFIFOHEAD(inter_fd,10); WFIFOW(inter_fd,0) = 0x3018; WFIFOL(inter_fd,2) = account_id; WFIFOL(inter_fd,6) = guild_id; WFIFOSET(inter_fd,10); - return 1; + return true; } /** * Request to save guild storage - * @param account_id : account requesting the save - * @param gstor : Guild storage struct to save - * @return + * @param account_id: account requesting the save + * @param gstor: Guild storage struct to save + * @return false - error, true - message sent */ -int intif_send_guild_storage(uint32 account_id,struct guild_storage *gstor) +bool intif_send_guild_storage(uint32 account_id, struct s_storage *gstor) { if (CheckForCharServer()) - return 0; - WFIFOHEAD(inter_fd,sizeof(struct guild_storage)+12); + return false; + WFIFOHEAD(inter_fd,sizeof(struct s_storage)+12); WFIFOW(inter_fd,0) = 0x3019; - WFIFOW(inter_fd,2) = (unsigned short)sizeof(struct guild_storage)+12; + WFIFOW(inter_fd,2) = (unsigned short)sizeof(struct s_storage)+12; WFIFOL(inter_fd,4) = account_id; - WFIFOL(inter_fd,8) = gstor->guild_id; - memcpy( WFIFOP(inter_fd,12),gstor, sizeof(struct guild_storage) ); + WFIFOL(inter_fd,8) = gstor->id; + memcpy( WFIFOP(inter_fd,12),gstor, sizeof(struct s_storage) ); WFIFOSET(inter_fd,WFIFOW(inter_fd,2)); - return 1; + return true; } /** @@ -1410,7 +1429,7 @@ void intif_parse_Registers(int fd) */ int intif_parse_LoadGuildStorage(int fd) { - struct guild_storage *gstor; + struct s_storage *gstor; struct map_session_data *sd; int guild_id, flag; @@ -1426,12 +1445,12 @@ int intif_parse_LoadGuildStorage(int fd) return 0; } } - gstor = gstorage_guild2storage(guild_id); + gstor = guild2storage(guild_id); if (!gstor) { ShowWarning("intif_parse_LoadGuildStorage: error guild_id %d not exist\n",guild_id); return 0; } - if (gstor->opened) { // Already open.. lets ignore this update + if (gstor->status) { // Already open.. lets ignore this update ShowWarning("intif_parse_LoadGuildStorage: storage received for a client already open (User %d:%d)\n", flag?sd->status.account_id:1, flag?sd->status.char_id:1); return 0; } @@ -1439,15 +1458,15 @@ int intif_parse_LoadGuildStorage(int fd) ShowWarning("intif_parse_LoadGuildStorage: received storage for an already modified non-saved storage! (User %d:%d)\n", flag?sd->status.account_id:1, flag?sd->status.char_id:1); return 0; } - if( RFIFOW(fd,2)-13 != sizeof(struct guild_storage) ){ - ShowError("intif_parse_LoadGuildStorage: data size error %d %d\n",RFIFOW(fd,2)-13 , sizeof(struct guild_storage)); - gstor->opened = 0; + if (RFIFOW(fd,2)-13 != sizeof(struct s_storage)) { + ShowError("intif_parse_LoadGuildStorage: data size error %d %d\n",RFIFOW(fd,2)-13 , sizeof(struct s_storage)); + gstor->status = false; return 0; } - memcpy(gstor,RFIFOP(fd,13),sizeof(struct guild_storage)); + memcpy(gstor,RFIFOP(fd,13),sizeof(struct s_storage)); if( flag ) - gstorage_storageopen(sd); + storage_guild_storageopen(sd); return 1; } @@ -1459,7 +1478,7 @@ int intif_parse_LoadGuildStorage(int fd) */ int intif_parse_SaveGuildStorage(int fd) { - gstorage_storagesaved(/*RFIFOL(fd,2), */RFIFOL(fd,6)); + storage_guild_storagesaved(/*RFIFOL(fd,2), */RFIFOL(fd,6)); return 1; } @@ -3056,7 +3075,7 @@ void intif_parse_broadcast_obtain_special_item(int fd) { * @param guild_id : Guild of char */ void intif_itembound_guild_retrieve(uint32 char_id,uint32 account_id,int guild_id) { - struct guild_storage *gstor = gstorage_get_storage(guild_id); + struct s_storage *gstor = guild2storage2(guild_id); if( CheckForCharServer() ) return; @@ -3068,7 +3087,7 @@ void intif_itembound_guild_retrieve(uint32 char_id,uint32 account_id,int guild_i WFIFOW(inter_fd,10) = guild_id; WFIFOSET(inter_fd,12); if (gstor) - gstor->locked = true; //Lock for retrieval process + gstor->lock = true; //Lock for retrieval process ShowInfo("Request guild bound item(s) retrieval for CID = "CL_WHITE"%d"CL_RESET", AID = %d, Guild ID = "CL_WHITE"%d"CL_RESET".\n", char_id, account_id, guild_id); } @@ -3080,21 +3099,21 @@ void intif_itembound_guild_retrieve(uint32 char_id,uint32 account_id,int guild_i */ void intif_parse_itembound_ack(int fd) { int guild_id = RFIFOW(fd,6); - struct guild_storage *gstor = gstorage_get_storage(guild_id); + struct s_storage *gstor = guild2storage(guild_id); if (gstor) - gstor->locked = false; //Unlock now that operation is completed + gstor->lock = false; //Unlock now that operation is completed } /** -* IZ 0x3857 .W .W .W { .?B }.*MAX_INVENTORY -* Received the retrieved guild bound items from inter-server, store them to guild storage. -* @param fd -* @author [Cydh] -*/ + * IZ 0x3857 .W .W .W { .?B }.*MAX_INVENTORY + * Received the retrieved guild bound items from inter-server, store them to guild storage. + * @param fd + * @author [Cydh] + */ void intif_parse_itembound_store2gstorage(int fd) { unsigned short i, failed = 0; short count = RFIFOW(fd, 4), guild_id = RFIFOW(fd, 6); - struct guild_storage *gstor = gstorage_guild2storage(guild_id); + struct s_storage *gstor = guild2storage(guild_id); if (!gstor) { ShowError("intif_parse_itembound_store2gstorage: Guild '%d' not found.\n", guild_id); @@ -3106,16 +3125,193 @@ void intif_parse_itembound_store2gstorage(int fd) { struct item *item = (struct item*)RFIFOP(fd, 8 + i*sizeof(struct item)); if (!item) continue; - if (!gstorage_additem2(gstor, item, item->amount)) + if (!storage_guild_additem2(gstor, item, item->amount)) failed++; } ShowInfo("Retrieved '"CL_WHITE"%d"CL_RESET"' (failed: %d) guild bound item(s) for Guild ID = "CL_WHITE"%d"CL_RESET".\n", count, failed, guild_id); - gstor->locked = false; - gstor->opened = 0; + gstor->lock = false; + gstor->status = false; } #endif -//----------------------------------------------------------------- +/** + * Receive inventory/cart/storage data for player + * IZ 0x388a .W .B .L .B .?B + * @param fd + */ +static bool intif_parse_StorageReceived(int fd) +{ + char type = RFIFOB(fd,4); + uint32 account_id = RFIFOL(fd, 5); + struct map_session_data *sd = map_id2sd(account_id); + struct s_storage *stor; //storage + size_t sz_stor = sizeof(struct s_storage); + + if (!sd) { + ShowError("intif_parse_StorageReceived: No player online for receiving inventory/cart/storage data (AID: %d)\n", account_id); + return false; + } + + if (!RFIFOB(fd, 9)) { + ShowError("intif_parse_StorageReceived: Failed to load! (AID: %d, type: %d)\n", account_id, type); + return false; + } + + switch (type) { + case TABLE_INVENTORY: stor = &sd->inventory; break; + case TABLE_STORAGE: stor = &sd->storage; break; + case TABLE_CART: stor = &sd->cart; break; + default: return false; + } + + if (stor->status) { // Already open.. lets ignore this update + ShowWarning("intif_parse_StorageReceived: storage received for a client already open (User %d:%d)\n", sd->status.account_id, sd->status.char_id); + return false; + } + if (stor->dirty) { // Already have storage, and it has been modified and not saved yet! Exploit! + ShowWarning("intif_parse_StorageReceived: received storage for an already modified non-saved storage! (User %d:%d)\n", sd->status.account_id, sd->status.char_id); + return false; + } + if (RFIFOW(fd,2)-10 != sz_stor) { + ShowError("intif_parse_StorageReceived: data size error %d %d\n",RFIFOW(fd,2)-10 , sz_stor); + stor->status = false; + return false; + } + + memcpy(stor, RFIFOP(fd,10), sz_stor); //copy the items data to correct destination + + switch (type) { + case TABLE_INVENTORY: { +#ifdef BOUND_ITEMS + int j, idxlist[MAX_INVENTORY]; +#endif + pc_setinventorydata(sd); + pc_setequipindex(sd); + pc_check_expiration(sd); + pc_check_available_item(sd, ITMCHK_INVENTORY); + pc_itemcd_do(sd, true); +#ifdef BOUND_ITEMS + // Party bound item check + if (sd->status.party_id == 0 && (j = pc_bound_chk(sd, BOUND_PARTY, idxlist))) { // Party was deleted while character offline + int i; + for (i = 0; i < j; i++) + pc_delitem(sd, idxlist[i], sd->inventory.u.items_inventory[idxlist[i]].amount, 0, 1, LOG_TYPE_OTHER); + } +#endif + //Set here because we need the inventory data for weapon sprite parsing. + status_set_viewdata(&sd->bl, sd->status.class_); + pc_load_combo(sd); + status_calc_weight(sd, 1|2); // Refresh item weight data + break; + } + + case TABLE_CART: + pc_check_available_item(sd, ITMCHK_CART); + status_calc_cart_weight(sd, 1|2); + if (sd->state.autotrade) { + clif_parse_LoadEndAck(sd->fd, sd); + sd->autotrade_tid = add_timer(gettick() + battle_config.feature_autotrade_open_delay, pc_autotrade_timer, sd->bl.id, 0); + } + break; + + case TABLE_STORAGE: + pc_check_available_item(sd, ITMCHK_STORAGE); + break; + } + return true; +} + +/** + * Save inventory/cart/storage data for a player + * IZ 0x388b .L .B .B + * @param fd + */ +static void intif_parse_StorageSaved(int fd) +{ + TBL_PC *sd = map_id2sd(RFIFOL(fd,2)); + + if (RFIFOB(fd, 6)) { + switch (RFIFOB(fd, 7)) { + case TABLE_INVENTORY: //inventory + //ShowInfo("Inventory has been saved (AID: %d).\n", RFIFOL(fd, 2)); + break; + case TABLE_STORAGE: //storage + if (sd && sd->state.storage_flag == 1) + sd->state.storage_flag = 0; + //ShowInfo("Storage has been saved (AID: %d).\n", RFIFOL(fd, 2)); + break; + case TABLE_CART: // cart + //ShowInfo("Cart has been saved (AID: %d).\n", RFIFOL(fd, 2)); + break; + default: + break; + } + } else + ShowError("Failed to save inventory/cart/storage data (AID: %d, type: %d).\n", RFIFOL(fd, 2), RFIFOB(fd, 7)); +} + +/** + * Request inventory/cart/storage data for a player + * ZI 0x308a .B .L .L + * @param sd: Player data + * @param type: Storage type + * @return false - error, true - message sent + */ +bool intif_storage_request(struct map_session_data *sd, enum storage_type type) +{ + if (CheckForCharServer()) + return false; + + WFIFOHEAD(inter_fd, 11); + WFIFOW(inter_fd, 0) = 0x308a; + WFIFOB(inter_fd, 2) = type; + WFIFOL(inter_fd, 3) = sd->status.account_id; + WFIFOL(inter_fd, 7) = sd->status.char_id; + WFIFOSET(inter_fd, 11); + return true; +} + +/** + * Request to save inventory/cart/storage data from player + * ZI 0x308b .W .B .L .L .?B + * @param sd: Player data + * @param type: Storage type + * @ return false - error, true - message sent + */ +bool intif_storage_save(struct map_session_data *sd, enum storage_type type) +{ + int stor_size = sizeof(struct s_storage); + struct s_storage *stor; + + nullpo_retr(false, sd); + + if (CheckForCharServer()) + return false; + + switch(type) { + case TABLE_INVENTORY: + stor = &sd->inventory; + break; + case TABLE_STORAGE: + stor = &sd->storage; + break; + case TABLE_CART: + stor = &sd->cart; + break; + default: + return false; + } + + WFIFOHEAD(inter_fd, stor_size+13); + WFIFOW(inter_fd, 0) = 0x308b; + WFIFOW(inter_fd, 2) = stor_size+13; + WFIFOB(inter_fd, 4) = type; + WFIFOL(inter_fd, 5) = sd->status.account_id; + WFIFOL(inter_fd, 9) = sd->status.char_id; + memcpy(WFIFOP(inter_fd, 13), stor, stor_size); + WFIFOSET(inter_fd, stor_size+13); + return true; +} /** * Communication from the inter server, Main entry point interface (inter<=>map) @@ -3229,7 +3425,11 @@ int intif_parse(int fd) case 0x3882: intif_parse_SavePetOk(fd); break; case 0x3883: intif_parse_DeletePetOk(fd); break; - // Homunculus + // Storage + case 0x388a: intif_parse_StorageReceived(fd); break; + case 0x388b: intif_parse_StorageSaved(fd); break; + + // Homunculus System case 0x3890: intif_parse_CreateHomunculus(fd); break; case 0x3891: intif_parse_RecvHomunculusData(fd); break; case 0x3892: intif_parse_SaveHomunculusOk(fd); break; @@ -3239,7 +3439,9 @@ int intif_parse(int fd) ShowError("intif_parse : unknown packet %d %x\n",fd,RFIFOW(fd,0)); return 0; } + // Skip packet RFIFOSKIP(fd,packet_len); + return 1; } diff --git a/src/map/intif.h b/src/map/intif.h index 5026ba5ff8..a2d108a4db 100644 --- a/src/map/intif.h +++ b/src/map/intif.h @@ -29,8 +29,8 @@ int intif_wis_message_to_gm(char *Wisp_name, int permission, char *mes); int intif_saveregistry(struct map_session_data *sd); int intif_request_registry(struct map_session_data *sd, int flag); -int intif_request_guild_storage(uint32 account_id, int guild_id); -int intif_send_guild_storage(uint32 account_id, struct guild_storage *gstor); +bool intif_request_guild_storage(uint32 account_id, int guild_id); +bool intif_send_guild_storage(uint32 account_id, struct s_storage *gstor); int intif_create_party(struct party_member *member,char *name,int item,int item2); int intif_request_partyinfo(int party_id, uint32 char_id); @@ -110,6 +110,10 @@ int intif_elemental_save(struct s_elemental *ele); int intif_request_accinfo(int u_fd, int aid, int group_lv, char* query, char type); +// STORAGE +bool intif_storage_request(struct map_session_data *sd, enum storage_type type); +bool intif_storage_save(struct map_session_data *sd, enum storage_type type); + int CheckForCharServer(void); #endif /* _INTIF_H_ */ diff --git a/src/map/itemdb.c b/src/map/itemdb.c index 74e1fb8236..91a79da598 100644 --- a/src/map/itemdb.c +++ b/src/map/itemdb.c @@ -1743,7 +1743,7 @@ void itemdb_reload(void) { for( sd = (struct map_session_data*)mapit_first(iter); mapit_exists(iter); sd = (struct map_session_data*)mapit_next(iter) ) { memset(sd->item_delay, 0, sizeof(sd->item_delay)); // reset item delays pc_setinventorydata(sd); - pc_check_available_item(sd); // Check for invalid(ated) items. + pc_check_available_item(sd, ITMCHK_ALL); // Check for invalid(ated) items. /* clear combo bonuses */ if( sd->combos.count ) { aFree(sd->combos.bonus); diff --git a/src/map/mail.c b/src/map/mail.c index e6550eb440..dd7da22640 100644 --- a/src/map/mail.c +++ b/src/map/mail.c @@ -83,16 +83,16 @@ bool mail_setitem(struct map_session_data *sd, short idx, uint32 amount) { if( idx < 0 || idx >= MAX_INVENTORY ) return false; - if( amount > sd->status.inventory[idx].amount ) + if( amount > sd->inventory.u.items_inventory[idx].amount ) return false; - if( !pc_can_give_items(sd) || sd->status.inventory[idx].expire_time - || !itemdb_available(sd->status.inventory[idx].nameid) - || !itemdb_canmail(&sd->status.inventory[idx],pc_get_group_level(sd)) - || (sd->status.inventory[idx].bound && !pc_can_give_bounded_items(sd)) ) + if( !pc_can_give_items(sd) || sd->inventory.u.items_inventory[idx].expire_time + || !itemdb_available(sd->inventory.u.items_inventory[idx].nameid) + || !itemdb_canmail(&sd->inventory.u.items_inventory[idx],pc_get_group_level(sd)) + || (sd->inventory.u.items_inventory[idx].bound && !pc_can_give_bounded_items(sd)) ) return false; sd->mail.index = idx; - sd->mail.nameid = sd->status.inventory[idx].nameid; + sd->mail.nameid = sd->inventory.u.items_inventory[idx].nameid; sd->mail.amount = amount; return true; } @@ -111,16 +111,16 @@ bool mail_setattachment(struct map_session_data *sd, struct mail_message *msg) n = sd->mail.index; if( sd->mail.amount ) { - if( sd->status.inventory[n].nameid != sd->mail.nameid ) + if( sd->inventory.u.items_inventory[n].nameid != sd->mail.nameid ) return false; - if( sd->status.inventory[n].amount < sd->mail.amount ) + if( sd->inventory.u.items_inventory[n].amount < sd->mail.amount ) return false; if( sd->weight > sd->max_weight ) return false; - memcpy(&msg->item, &sd->status.inventory[n], sizeof(struct item)); + memcpy(&msg->item, &sd->inventory.u.items_inventory[n], sizeof(struct item)); msg->item.amount = sd->mail.amount; } else diff --git a/src/map/map.c b/src/map/map.c index 8afcea2bc5..c52a16ed82 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -2066,8 +2066,6 @@ int map_quit(struct map_session_data *sd) { if (sd->ed) // Remove effects here rather than unit_remove_map_pc so we don't clear on Teleport/map change. elemental_clean_effect(sd->ed); - if( sd->state.storage_flag == 1 ) sd->state.storage_flag = 0; // No need to Double Save Storage on Quit. - if (sd->state.permanent_speed == 1) sd->state.permanent_speed = 0; // Remove lock so speed is set back to normal at login. if( map[sd->bl.m].instance_id ) @@ -4654,6 +4652,9 @@ int do_init(int argc, char *argv[]) rnd_init(); map_config_read(MAP_CONF_NAME); + if (save_settings == CHARSAVE_NONE) + ShowWarning("Value of 'save_settings' is not set, player's data only will be saved every 'autosave_time' (%d seconds).\n", autosave_interval/1000); + // loads npcs map_reloadnpc(false); diff --git a/src/map/npc.c b/src/map/npc.c index 7f9f224799..c63bc28b78 100644 --- a/src/map/npc.c +++ b/src/map/npc.c @@ -1527,8 +1527,8 @@ void npc_shop_currency_type(struct map_session_data *sd, struct npc_data *nd, in } for (i = 0; i < MAX_INVENTORY; i++) { - if (sd->status.inventory[i].nameid == id->nameid) - total += sd->status.inventory[i].amount; + if (sd->inventory.u.items_inventory[i].nameid == id->nameid) + total += sd->inventory.u.items_inventory[i].amount; } } @@ -1858,19 +1858,19 @@ static int npc_selllist_sub(struct map_session_data* sd, int n, unsigned short* idx = item_list[i*2]-2; - script_setarray_pc(sd, "@sold_nameid", i, (void*)(intptr_t)sd->status.inventory[idx].nameid, &key_nameid); + script_setarray_pc(sd, "@sold_nameid", i, (void*)(intptr_t)sd->inventory.u.items_inventory[idx].nameid, &key_nameid); script_setarray_pc(sd, "@sold_quantity", i, (void*)(intptr_t)item_list[i*2+1], &key_amount); - if( itemdb_isequip(sd->status.inventory[idx].nameid) ) + if( itemdb_isequip(sd->inventory.u.items_inventory[idx].nameid) ) {// process equipment based information into the arrays - script_setarray_pc(sd, "@sold_refine", i, (void*)(intptr_t)sd->status.inventory[idx].refine, &key_refine); - script_setarray_pc(sd, "@sold_attribute", i, (void*)(intptr_t)sd->status.inventory[idx].attribute, &key_attribute); - script_setarray_pc(sd, "@sold_identify", i, (void*)(intptr_t)sd->status.inventory[idx].identify, &key_identify); + script_setarray_pc(sd, "@sold_refine", i, (void*)(intptr_t)sd->inventory.u.items_inventory[idx].refine, &key_refine); + script_setarray_pc(sd, "@sold_attribute", i, (void*)(intptr_t)sd->inventory.u.items_inventory[idx].attribute, &key_attribute); + script_setarray_pc(sd, "@sold_identify", i, (void*)(intptr_t)sd->inventory.u.items_inventory[idx].identify, &key_identify); for( j = 0; j < MAX_SLOTS; j++ ) {// store each of the cards from the equipment in the array snprintf(card_slot, sizeof(card_slot), "@sold_card%d", j + 1); - script_setarray_pc(sd, card_slot, i, (void*)(intptr_t)sd->status.inventory[idx].card[j], &key_card[j]); + script_setarray_pc(sd, card_slot, i, (void*)(intptr_t)sd->inventory.u.items_inventory[idx].card[j], &key_card[j]); } } } @@ -1916,9 +1916,9 @@ uint8 npc_selllist(struct map_session_data* sd, int n, unsigned short *item_list return 1; } - nameid = sd->status.inventory[idx].nameid; + nameid = sd->inventory.u.items_inventory[idx].nameid; - if( !nameid || !sd->inventory_data[idx] || sd->status.inventory[idx].amount < amount ) + if( !nameid || !sd->inventory_data[idx] || sd->inventory.u.items_inventory[idx].amount < amount ) { return 1; } @@ -1946,11 +1946,11 @@ uint8 npc_selllist(struct map_session_data* sd, int n, unsigned short *item_list idx = item_list[i*2]-2; amount = item_list[i*2+1]; - if( sd->inventory_data[idx]->type == IT_PETEGG && sd->status.inventory[idx].card[0] == CARD0_PET ) + if( sd->inventory_data[idx]->type == IT_PETEGG && sd->inventory.u.items_inventory[idx].card[0] == CARD0_PET ) { - if( search_petDB_index(sd->status.inventory[idx].nameid, PET_EGG) >= 0 ) + if( search_petDB_index(sd->inventory.u.items_inventory[idx].nameid, PET_EGG) >= 0 ) { - intif_delete_petdata(MakeDWord(sd->status.inventory[idx].card[1], sd->status.inventory[idx].card[2])); + intif_delete_petdata(MakeDWord(sd->inventory.u.items_inventory[idx].card[1], sd->inventory.u.items_inventory[idx].card[2])); } } diff --git a/src/map/party.c b/src/map/party.c index 0cf8b9f975..35a54395ac 100644 --- a/src/map/party.c +++ b/src/map/party.c @@ -626,7 +626,7 @@ int party_member_withdraw(int party_id, uint32 account_id, uint32 char_id) j = pc_bound_chk(sd,BOUND_PARTY,idxlist); for(i = 0; i < j; i++) - pc_delitem(sd,idxlist[i],sd->status.inventory[idxlist[i]].amount,0,1,LOG_TYPE_BOUND_REMOVAL); + pc_delitem(sd,idxlist[i],sd->inventory.u.items_inventory[idxlist[i]].amount,0,1,LOG_TYPE_BOUND_REMOVAL); #endif sd->status.party_id = 0; diff --git a/src/map/pc.c b/src/map/pc.c index 3969cdd42c..d51b35af5d 100755 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -475,18 +475,18 @@ void pc_inventory_rentals(struct map_session_data *sd) unsigned int expire_tick, next_tick = UINT_MAX; for( i = 0; i < MAX_INVENTORY; i++ ) { // Check for Rentals on Inventory - if( sd->status.inventory[i].nameid == 0 ) + if( sd->inventory.u.items_inventory[i].nameid == 0 ) continue; // Nothing here - if( sd->status.inventory[i].expire_time == 0 ) + if( sd->inventory.u.items_inventory[i].expire_time == 0 ) continue; - if( sd->status.inventory[i].expire_time <= time(NULL) ) { + if( sd->inventory.u.items_inventory[i].expire_time <= time(NULL) ) { if (sd->inventory_data[i]->unequip_script) run_script(sd->inventory_data[i]->unequip_script, 0, sd->bl.id, fake_nd->bl.id); - clif_rental_expired(sd->fd, i, sd->status.inventory[i].nameid); - pc_delitem(sd, i, sd->status.inventory[i].amount, 0, 0, LOG_TYPE_OTHER); + clif_rental_expired(sd->fd, i, sd->inventory.u.items_inventory[i].nameid); + pc_delitem(sd, i, sd->inventory.u.items_inventory[i].amount, 0, 0, LOG_TYPE_OTHER); } else { - expire_tick = (unsigned int)(sd->status.inventory[i].expire_time - time(NULL)) * 1000; - clif_rental_time(sd->fd, sd->status.inventory[i].nameid, (int)(expire_tick / 1000)); + expire_tick = (unsigned int)(sd->inventory.u.items_inventory[i].expire_time - time(NULL)) * 1000; + clif_rental_time(sd->fd, sd->inventory.u.items_inventory[i].nameid, (int)(expire_tick / 1000)); next_tick = umin(expire_tick, next_tick); c++; } @@ -646,14 +646,14 @@ void pc_setinventorydata(struct map_session_data *sd) nullpo_retv(sd); for(i = 0; i < MAX_INVENTORY; i++) { - unsigned short id = sd->status.inventory[i].nameid; + unsigned short id = sd->inventory.u.items_inventory[i].nameid; sd->inventory_data[i] = id?itemdb_search(id):NULL; } } /** * 'Calculates' weapon type -* @param sd : player +* @param sd : Player */ void pc_calcweapontype(struct map_session_data *sd) { @@ -711,22 +711,22 @@ void pc_setequipindex(struct map_session_data *sd) sd->equip_index[i] = -1; for (i = 0; i < MAX_INVENTORY; i++) { - if (sd->status.inventory[i].nameid <= 0) + if (sd->inventory.u.items_inventory[i].nameid <= 0) continue; - if (sd->status.inventory[i].equip) { + if (sd->inventory.u.items_inventory[i].equip) { uint8 j; for (j = 0; j < EQI_MAX; j++) - if (sd->status.inventory[i].equip & equip_pos[j]) + if (sd->inventory.u.items_inventory[i].equip & equip_pos[j]) sd->equip_index[j] = i; - if (sd->status.inventory[i].equip & EQP_HAND_R) { + if (sd->inventory.u.items_inventory[i].equip & EQP_HAND_R) { if (sd->inventory_data[i]) sd->weapontype1 = sd->inventory_data[i]->look; else sd->weapontype1 = 0; } - if( sd->status.inventory[i].equip & EQP_HAND_L ) { + if( sd->inventory.u.items_inventory[i].equip & EQP_HAND_L ) { if( sd->inventory_data[i] && sd->inventory_data[i]->type == IT_WEAPON ) sd->weapontype2 = sd->inventory_data[i]->look; else @@ -740,7 +740,7 @@ void pc_setequipindex(struct map_session_data *sd) //static int pc_isAllowedCardOn(struct map_session_data *sd,int s,int eqindex,int flag) //{ // int i; -// struct item *item = &sd->status.inventory[eqindex]; +// struct item *item = &sd->inventory.u.items_inventory[eqindex]; // struct item_data *data; // // //Crafted/made/hatched items. @@ -779,7 +779,7 @@ bool pc_isequipped(struct map_session_data *sd, unsigned short nameid) if( sd->inventory_data[index]->nameid == nameid ) return true; for( j = 0; j < sd->inventory_data[index]->slot; j++ ){ - if( sd->status.inventory[index].card[j] == nameid ) + if( sd->inventory.u.items_inventory[index].card[j] == nameid ) return true; } } @@ -1018,10 +1018,6 @@ uint8 pc_isequip(struct map_session_data *sd,int n) bool pc_authok(struct map_session_data *sd, uint32 login_id2, time_t expiration_time, int group_id, struct mmo_charstatus *st, bool changing_mapservers) { int i; -#ifdef BOUND_ITEMS - int j; - int idxlist[MAX_INVENTORY]; -#endif unsigned long tick = gettick(); uint32 ip = session[sd->fd]->client_addr; @@ -1056,7 +1052,8 @@ bool pc_authok(struct map_session_data *sd, uint32 login_id2, time_t expiration_ sd->status.body = cap_value(sd->status.body,MIN_BODY_STYLE,MAX_BODY_STYLE); //Initializations to null/0 unneeded since map_session_data was filled with 0 upon allocation. - if(!sd->status.hp) pc_setdead(sd); + if (!sd->status.hp) + pc_setdead(sd); sd->state.connect_new = 1; sd->followtimer = INVALID_TIMER; // [MouseJstr] @@ -1106,8 +1103,7 @@ bool pc_authok(struct map_session_data *sd, uint32 login_id2, time_t expiration_ if (!(battle_config.display_skill_fail&2)) sd->state.showdelay = 1; - pc_setinventorydata(sd); - pc_setequipindex(sd); + pc_setequipindex(sd); // required at the moment, to complete auth_ok [lighta] if( sd->status.option&OPTION_INVISIBLE && !pc_can_use_command( sd, "hide", COMMAND_ATCOMMAND ) ){ sd->status.option &= ~OPTION_INVISIBLE; @@ -1116,8 +1112,7 @@ bool pc_authok(struct map_session_data *sd, uint32 login_id2, time_t expiration_ status_change_init(&sd->bl); sd->sc.option = sd->status.option; //This is the actual option used in battle. - //Set here because we need the inventory data for weapon sprite parsing. - status_set_viewdata(&sd->bl, sd->status.class_); + unit_dataset(&sd->bl); sd->guild_x = -1; @@ -1198,20 +1193,8 @@ bool pc_authok(struct map_session_data *sd, uint32 login_id2, time_t expiration_ clif_changemap(sd,sd->bl.m,sd->bl.x,sd->bl.y); } - /** - * Check if player have any item cooldowns on - **/ - pc_itemcd_do(sd,true); pc_validate_skill(sd); -#ifdef BOUND_ITEMS - // Party bound item check - if(sd->status.party_id == 0 && (j = pc_bound_chk(sd,BOUND_PARTY,idxlist))) { // Party was deleted while character offline - for(i=0;istatus.inventory[idxlist[i]].amount,0,1,LOG_TYPE_OTHER); - } -#endif - /* [Ind] */ sd->sc_display = NULL; sd->sc_display_count = 0; @@ -1282,6 +1265,8 @@ bool pc_set_hate_mob(struct map_session_data *sd, int pos, struct block_list *bl /*========================================== * Invoked once after the char/account/account2 registry variables are received. [Skotlex] + * We didn't receive item information at this point so DO NOT attempt to do item operations here. + * See intif_parse_StorageReceived() for item operations [lighta] *------------------------------------------*/ void pc_reg_received(struct map_session_data *sd) { @@ -1418,12 +1403,9 @@ void pc_reg_received(struct map_session_data *sd) clif_changeoption( &sd->bl ); } - pc_check_expiration(sd); - - if( sd->state.autotrade ) { - clif_parse_LoadEndAck(sd->fd, sd); - sd->autotrade_tid = add_timer(gettick() + battle_config.feature_autotrade_open_delay, pc_autotrade_timer, sd->bl.id, 0); - } + intif_storage_request(sd,TABLE_STORAGE); // Request storage data + intif_storage_request(sd,TABLE_CART); // Request cart data + intif_storage_request(sd,TABLE_INVENTORY); // Request inventory data } static int pc_calc_skillpoint(struct map_session_data* sd) @@ -2209,7 +2191,7 @@ void pc_delautobonus(struct map_session_data* sd, struct s_autobonus *autobonus, //Create a list of all equipped positions to see if all items needed for the autobonus are still present [Playtester] for(j = 0; j < EQI_MAX; j++) { if(sd->equip_index[j] >= 0) - equip_pos_idx |= sd->status.inventory[sd->equip_index[j]].equip; + equip_pos_idx |= sd->inventory.u.items_inventory[sd->equip_index[j]].equip; } if((equip_pos_idx&autobonus[i].pos) == autobonus[i].pos) script_run_autobonus(autobonus[i].bonus_script,sd,autobonus[i].pos); @@ -2243,7 +2225,7 @@ void pc_exeautobonus(struct map_session_data *sd,struct s_autobonus *autobonus) //Create a list of all equipped positions to see if all items needed for the autobonus are still present [Playtester] for(j = 0; j < EQI_MAX; j++) { if(sd->equip_index[j] >= 0) - equip_pos_idx |= sd->status.inventory[sd->equip_index[j]].equip; + equip_pos_idx |= sd->inventory.u.items_inventory[sd->equip_index[j]].equip; } if((equip_pos_idx&autobonus->pos) == autobonus->pos) script_run_autobonus(autobonus->other_script,sd,autobonus->pos); @@ -3959,31 +3941,31 @@ int pc_insert_card(struct map_session_data* sd, int idx_card, int idx_equip) return 0; //Invalid item index. if( idx_card < 0 || idx_card >= MAX_INVENTORY || sd->inventory_data[idx_card] == NULL ) return 0; //Invalid card index. - if( sd->status.inventory[idx_equip].nameid <= 0 || sd->status.inventory[idx_equip].amount < 1 ) + if( sd->inventory.u.items_inventory[idx_equip].nameid <= 0 || sd->inventory.u.items_inventory[idx_equip].amount < 1 ) return 0; // target item missing - if( sd->status.inventory[idx_card].nameid <= 0 || sd->status.inventory[idx_card].amount < 1 ) + if( sd->inventory.u.items_inventory[idx_card].nameid <= 0 || sd->inventory.u.items_inventory[idx_card].amount < 1 ) return 0; // target card missing if( sd->inventory_data[idx_equip]->type != IT_WEAPON && sd->inventory_data[idx_equip]->type != IT_ARMOR ) return 0; // only weapons and armor are allowed if( sd->inventory_data[idx_card]->type != IT_CARD ) return 0; // must be a card - if( sd->status.inventory[idx_equip].identify == 0 ) + if( sd->inventory.u.items_inventory[idx_equip].identify == 0 ) return 0; // target must be identified - if( itemdb_isspecial(sd->status.inventory[idx_equip].card[0]) ) + if( itemdb_isspecial(sd->inventory.u.items_inventory[idx_equip].card[0]) ) return 0; // card slots reserved for other purposes if( (sd->inventory_data[idx_equip]->equip & sd->inventory_data[idx_card]->equip) == 0 ) return 0; // card cannot be compounded on this item type if( sd->inventory_data[idx_equip]->type == IT_WEAPON && sd->inventory_data[idx_card]->equip == EQP_SHIELD ) return 0; // attempted to place shield card on left-hand weapon. - if( sd->status.inventory[idx_equip].equip != 0 ) + if( sd->inventory.u.items_inventory[idx_equip].equip != 0 ) return 0; // item must be unequipped - ARR_FIND( 0, sd->inventory_data[idx_equip]->slot, i, sd->status.inventory[idx_equip].card[i] == 0 ); + ARR_FIND( 0, sd->inventory_data[idx_equip]->slot, i, sd->inventory.u.items_inventory[idx_equip].card[i] == 0 ); if( i == sd->inventory_data[idx_equip]->slot ) return 0; // no free slots // remember the card id to insert - nameid = sd->status.inventory[idx_card].nameid; + nameid = sd->inventory.u.items_inventory[idx_card].nameid; if( pc_delitem(sd,idx_card,1,1,0,LOG_TYPE_OTHER) == 1 ) {// failed @@ -3991,9 +3973,9 @@ int pc_insert_card(struct map_session_data* sd, int idx_card, int idx_equip) } else {// success - log_pick_pc(sd, LOG_TYPE_OTHER, -1, &sd->status.inventory[idx_equip]); - sd->status.inventory[idx_equip].card[i] = nameid; - log_pick_pc(sd, LOG_TYPE_OTHER, 1, &sd->status.inventory[idx_equip]); + log_pick_pc(sd, LOG_TYPE_OTHER, -1, &sd->inventory.u.items_inventory[idx_equip]); + sd->inventory.u.items_inventory[idx_equip].card[i] = nameid; + log_pick_pc(sd, LOG_TYPE_OTHER, 1, &sd->inventory.u.items_inventory[idx_equip]); clif_insert_card(sd,idx_equip,idx_card,0); } @@ -4067,8 +4049,8 @@ char pc_checkadditem(struct map_session_data *sd, unsigned short nameid, int amo for(i=0;istatus.inventory[i].nameid==nameid){ - if( amount > MAX_AMOUNT - sd->status.inventory[i].amount || ( data->stack.inventory && amount > data->stack.amount - sd->status.inventory[i].amount ) ) + if(sd->inventory.u.items_inventory[i].nameid == nameid){ + if( amount > MAX_AMOUNT - sd->inventory.u.items_inventory[i].amount || ( data->stack.inventory && amount > data->stack.amount - sd->inventory.u.items_inventory[i].amount ) ) return CHKADDITEM_OVERAMOUNT; return CHKADDITEM_EXIST; } @@ -4090,7 +4072,7 @@ uint8 pc_inventoryblank(struct map_session_data *sd) nullpo_ret(sd); for(i = 0, b = 0; i < MAX_INVENTORY; i++){ - if(sd->status.inventory[i].nameid==0) + if(sd->inventory.u.items_inventory[i].nameid == 0) b++; } @@ -4301,7 +4283,7 @@ short pc_search_inventory(struct map_session_data *sd, unsigned short nameid) { short i; nullpo_retr(-1, sd); - ARR_FIND( 0, MAX_INVENTORY, i, sd->status.inventory[i].nameid == nameid && (sd->status.inventory[i].amount > 0 || nameid == 0) ); + ARR_FIND( 0, MAX_INVENTORY, i, sd->inventory.u.items_inventory[i].nameid == nameid && (sd->inventory.u.items_inventory[i].amount > 0 || nameid == 0) ); return ( i < MAX_INVENTORY ) ? i : -1; } @@ -4352,16 +4334,14 @@ char pc_additem(struct map_session_data *sd,struct item *item,int amount,e_log_p // Stackable | Non Rental if( itemdb_isstackable2(id) && item->expire_time == 0 ) { for( i = 0; i < MAX_INVENTORY; i++ ) { - if( sd->status.inventory[i].nameid == item->nameid && - sd->status.inventory[i].bound == item->bound && - sd->status.inventory[i].expire_time == 0 && - sd->status.inventory[i].unique_id == item->unique_id && - memcmp(&sd->status.inventory[i].card, &item->card, sizeof(item->card)) == 0 - ) - { - if( amount > MAX_AMOUNT - sd->status.inventory[i].amount || ( id->stack.inventory && amount > id->stack.amount - sd->status.inventory[i].amount ) ) + if( sd->inventory.u.items_inventory[i].nameid == item->nameid && + sd->inventory.u.items_inventory[i].bound == item->bound && + sd->inventory.u.items_inventory[i].expire_time == 0 && + sd->inventory.u.items_inventory[i].unique_id == item->unique_id && + memcmp(&sd->inventory.u.items_inventory[i].card, &item->card, sizeof(item->card)) == 0 ) { + if( amount > MAX_AMOUNT - sd->inventory.u.items_inventory[i].amount || ( id->stack.inventory && amount > id->stack.amount - sd->inventory.u.items_inventory[i].amount ) ) return ADDITEM_OVERAMOUNT; - sd->status.inventory[i].amount += amount; + sd->inventory.u.items_inventory[i].amount += amount; clif_additem(sd,i,amount,0); break; } @@ -4373,24 +4353,24 @@ char pc_additem(struct map_session_data *sd,struct item *item,int amount,e_log_p if( i < 0 ) return ADDITEM_OVERITEM; - memcpy(&sd->status.inventory[i], item, sizeof(sd->status.inventory[0])); + memcpy(&sd->inventory.u.items_inventory[i], item, sizeof(sd->inventory.u.items_inventory[0])); // clear equip and favorite fields first, just in case if( item->equip ) - sd->status.inventory[i].equip = 0; + sd->inventory.u.items_inventory[i].equip = 0; if( item->favorite ) - sd->status.inventory[i].favorite = 0; + sd->inventory.u.items_inventory[i].favorite = 0; - sd->status.inventory[i].amount = amount; + sd->inventory.u.items_inventory[i].amount = amount; sd->inventory_data[i] = id; sd->last_addeditem_index = i; if (!itemdb_isstackable2(id) || id->flag.guid) - sd->status.inventory[i].unique_id = item->unique_id ? item->unique_id : pc_generate_unique_id(sd); + sd->inventory.u.items_inventory[i].unique_id = item->unique_id ? item->unique_id : pc_generate_unique_id(sd); clif_additem(sd,i,amount,0); } - log_pick_pc(sd, log_type, amount, &sd->status.inventory[i]); + log_pick_pc(sd, log_type, amount, &sd->inventory.u.items_inventory[i]); sd->weight += w; clif_updatestatus(sd,SP_WEIGHT); @@ -4401,11 +4381,11 @@ char pc_additem(struct map_session_data *sd,struct item *item,int amount,e_log_p /* rental item check */ if( item->expire_time ) { if( time(NULL) > item->expire_time ) { - clif_rental_expired(sd->fd, i, sd->status.inventory[i].nameid); - pc_delitem(sd, i, sd->status.inventory[i].amount, 1, 0, LOG_TYPE_OTHER); + clif_rental_expired(sd->fd, i, sd->inventory.u.items_inventory[i].nameid); + pc_delitem(sd, i, sd->inventory.u.items_inventory[i].amount, 1, 0, LOG_TYPE_OTHER); } else { unsigned int seconds = (unsigned int)( item->expire_time - time(NULL) ); - clif_rental_time(sd->fd, sd->status.inventory[i].nameid, seconds); + clif_rental_time(sd->fd, sd->inventory.u.items_inventory[i].nameid, seconds); pc_inventory_rental_add(sd, seconds); } } @@ -4427,17 +4407,17 @@ char pc_delitem(struct map_session_data *sd,int n,int amount,int type, short rea { nullpo_retr(1, sd); - if(n < 0 || sd->status.inventory[n].nameid==0 || amount <= 0 || sd->status.inventory[n].amountinventory_data[n] == NULL) + if(n < 0 || sd->inventory.u.items_inventory[n].nameid == 0 || amount <= 0 || sd->inventory.u.items_inventory[n].amountinventory_data[n] == NULL) return 1; - log_pick_pc(sd, log_type, -amount, &sd->status.inventory[n]); + log_pick_pc(sd, log_type, -amount, &sd->inventory.u.items_inventory[n]); - sd->status.inventory[n].amount -= amount; + sd->inventory.u.items_inventory[n].amount -= amount; sd->weight -= sd->inventory_data[n]->weight*amount ; - if( sd->status.inventory[n].amount <= 0 ){ - if(sd->status.inventory[n].equip) + if( sd->inventory.u.items_inventory[n].amount <= 0 ){ + if(sd->inventory.u.items_inventory[n].equip) pc_unequipitem(sd,n,3); - memset(&sd->status.inventory[n],0,sizeof(sd->status.inventory[0])); + memset(&sd->inventory.u.items_inventory[n],0,sizeof(sd->inventory.u.items_inventory[0])); sd->inventory_data[n] = NULL; } if(!(type&1)) @@ -4465,9 +4445,9 @@ bool pc_dropitem(struct map_session_data *sd,int n,int amount) if(amount <= 0) return false; - if(sd->status.inventory[n].nameid <= 0 || - sd->status.inventory[n].amount <= 0 || - sd->status.inventory[n].amount < amount || + if(sd->inventory.u.items_inventory[n].nameid <= 0 || + sd->inventory.u.items_inventory[n].amount <= 0 || + sd->inventory.u.items_inventory[n].amount < amount || sd->state.trading || sd->state.vending || !sd->inventory_data[n] //pc_delitem would fail on this case. ) @@ -4479,13 +4459,13 @@ bool pc_dropitem(struct map_session_data *sd,int n,int amount) return false; //Can't drop items in nodrop mapflag maps. } - if( !pc_candrop(sd,&sd->status.inventory[n]) ) + if( !pc_candrop(sd,&sd->inventory.u.items_inventory[n]) ) { clif_displaymessage (sd->fd, msg_txt(sd,263)); return false; } - if (!map_addflooritem(&sd->status.inventory[n], amount, sd->bl.m, sd->bl.x, sd->bl.y, 0, 0, 0, 2, 0)) + if (!map_addflooritem(&sd->inventory.u.items_inventory[n], amount, sd->bl.m, sd->bl.x, sd->bl.y, 0, 0, 0, 2, 0)) return false; pc_delitem(sd, n, amount, 1, 0, LOG_TYPE_PICKDROP_PLAYER); @@ -4582,7 +4562,7 @@ bool pc_isUseitem(struct map_session_data *sd,int n) nullpo_ret(sd); item = sd->inventory_data[n]; - nameid = sd->status.inventory[n].nameid; + nameid = sd->inventory.u.items_inventory[n].nameid; if( item == NULL ) return false; @@ -4775,7 +4755,7 @@ int pc_useitem(struct map_session_data *sd,int n) return 0; #endif } - item = sd->status.inventory[n]; + item = sd->inventory.u.items_inventory[n]; id = sd->inventory_data[n]; if (item.nameid == 0 || item.amount <= 0) @@ -4889,17 +4869,14 @@ unsigned char pc_cart_additem(struct map_session_data *sd,struct item *item,int if( (w = data->weight*amount) + sd->cart_weight > sd->cart_weight_max ) return 1; - // ID no longer points to inventory/kafra ID. While we get a new one we don't want to mess up vending creation. - item->id = 0; - i = MAX_CART; if( itemdb_isstackable2(data) && !item->expire_time ) { for (i = 0; i < MAX_CART; i++) { - if (sd->status.cart[i].nameid == item->nameid - && sd->status.cart[i].bound == item->bound - && sd->status.cart[i].unique_id == item->unique_id - && memcmp(sd->status.cart[i].card, item->card, sizeof(item->card)) == 0 + if (sd->cart.u.items_cart[i].nameid == item->nameid + && sd->cart.u.items_cart[i].bound == item->bound + && sd->cart.u.items_cart[i].unique_id == item->unique_id + && memcmp(sd->cart.u.items_cart[i].card, item->card, sizeof(item->card)) == 0 ) break; } @@ -4907,25 +4884,25 @@ unsigned char pc_cart_additem(struct map_session_data *sd,struct item *item,int if( i < MAX_CART ) {// item already in cart, stack it - if( amount > MAX_AMOUNT - sd->status.cart[i].amount || ( data->stack.cart && amount > data->stack.amount - sd->status.cart[i].amount ) ) + if( amount > MAX_AMOUNT - sd->cart.u.items_cart[i].amount || ( data->stack.cart && amount > data->stack.amount - sd->cart.u.items_cart[i].amount ) ) return 2; // no slot - sd->status.cart[i].amount+=amount; + sd->cart.u.items_cart[i].amount += amount; clif_cart_additem(sd,i,amount,0); } else {// item not stackable or not present, add it - ARR_FIND( 0, MAX_CART, i, sd->status.cart[i].nameid == 0 ); + ARR_FIND( 0, MAX_CART, i, sd->cart.u.items_cart[i].nameid == 0 ); if( i == MAX_CART ) return 2; // no slot - memcpy(&sd->status.cart[i],item,sizeof(sd->status.cart[0])); - sd->status.cart[i].amount=amount; + memcpy(&sd->cart.u.items_cart[i],item,sizeof(sd->cart.u.items_cart[0])); + sd->cart.u.items_cart[i].amount = amount; sd->cart_num++; clif_cart_additem(sd,i,amount,0); } - sd->status.cart[i].favorite = 0;/* clear */ - log_pick_pc(sd, log_type, amount, &sd->status.cart[i]); + sd->cart.u.items_cart[i].favorite = 0; // clear + log_pick_pc(sd, log_type, amount, &sd->cart.u.items_cart[i]); sd->cart_weight += w; clif_updatestatus(sd,SP_CARTINFO); @@ -4940,16 +4917,16 @@ void pc_cart_delitem(struct map_session_data *sd,int n,int amount,int type,e_log { nullpo_retv(sd); - if(sd->status.cart[n].nameid == 0 || - sd->status.cart[n].amountcart.u.items_cart[n].nameid == 0 || + sd->cart.u.items_cart[n].amount < amount) return; - log_pick_pc(sd, log_type, -amount, &sd->status.cart[n]); + log_pick_pc(sd, log_type, -amount, &sd->cart.u.items_cart[n]); - sd->status.cart[n].amount -= amount; - sd->cart_weight -= itemdb_weight(sd->status.cart[n].nameid)*amount ; - if(sd->status.cart[n].amount <= 0){ - memset(&sd->status.cart[n],0,sizeof(sd->status.cart[0])); + sd->cart.u.items_cart[n].amount -= amount; + sd->cart_weight -= itemdb_weight(sd->cart.u.items_cart[n].nameid) * amount; + if(sd->cart.u.items_cart[n].amount <= 0) { + memset(&sd->cart.u.items_cart[n],0,sizeof(sd->cart.u.items_cart[0])); sd->cart_num--; } if(!type) { @@ -4971,7 +4948,7 @@ void pc_putitemtocart(struct map_session_data *sd,int idx,int amount) if (idx < 0 || idx >= MAX_INVENTORY) //Invalid index check [Skotlex] return; - item_data = &sd->status.inventory[idx]; + item_data = &sd->inventory.u.items_inventory[idx]; if( item_data->nameid == 0 || amount < 1 || item_data->amount < amount || sd->state.vending ) return; @@ -4996,7 +4973,7 @@ int pc_cartitem_amount(struct map_session_data* sd, int idx, int amount) nullpo_retr(-1, sd); - item_data = &sd->status.cart[idx]; + item_data = &sd->cart.u.items_cart[idx]; if( item_data->nameid == 0 || item_data->amount == 0 ) return -1; @@ -5016,7 +4993,7 @@ void pc_getitemfromcart(struct map_session_data *sd,int idx,int amount) if (idx < 0 || idx >= MAX_CART) //Invalid index check [Skotlex] return; - item_data=&sd->status.cart[idx]; + item_data=&sd->cart.u.items_cart[idx]; if(item_data->nameid == 0 || amount < 1 || item_data->amount < amount || sd->state.vending ) return; @@ -5038,9 +5015,9 @@ void pc_getitemfromcart(struct map_session_data *sd,int idx,int amount) *------------------------------------------*/ int pc_bound_chk(TBL_PC *sd,enum bound_type type,int *idxlist) { - int i=0, j=0; - for(i=0;istatus.inventory[i].nameid > 0 && sd->status.inventory[i].amount > 0 && sd->status.inventory[i].bound == type) { + int i = 0, j = 0; + for(i = 0; i < MAX_INVENTORY; i++) { + if(sd->inventory.u.items_inventory[i].nameid > 0 && sd->inventory.u.items_inventory[i].amount > 0 && sd->inventory.u.items_inventory[i].bound == type) { idxlist[j] = i; j++; } @@ -5603,7 +5580,7 @@ bool pc_checkequip2(struct map_session_data *sd, unsigned short nameid, int min, if(equip_pos[i]) { int idx = sd->equip_index[i]; - if (sd->status.inventory[idx].nameid == nameid) + if (sd->inventory.u.items_inventory[idx].nameid == nameid) return true; } } @@ -7602,8 +7579,8 @@ int pc_dead(struct map_session_data *sd,struct block_list *src) int eq_num=0,eq_n[MAX_INVENTORY]; memset(eq_n,0,sizeof(eq_n)); for(i=0;istatus.inventory[i].equip) - || (type == 2 && sd->status.inventory[i].equip) + if( (type == 1 && !sd->inventory.u.items_inventory[i].equip) + || (type == 2 && sd->inventory.u.items_inventory[i].equip) || type == 3) { int l; @@ -7617,7 +7594,7 @@ int pc_dead(struct map_session_data *sd,struct block_list *src) if(eq_num > 0){ int n = eq_n[rnd()%eq_num]; if(rnd()%10000 < per) { - if(sd->status.inventory[n].equip) + if(sd->inventory.u.items_inventory[n].equip) pc_unequipitem(sd,n,3); pc_dropitem(sd,n,1); } @@ -7625,12 +7602,12 @@ int pc_dead(struct map_session_data *sd,struct block_list *src) } else if(id > 0) { for(i=0;istatus.inventory[i].nameid == id + if(sd->inventory.u.items_inventory[i].nameid == id && rnd()%10000 < per - && ((type == 1 && !sd->status.inventory[i].equip) - || (type == 2 && sd->status.inventory[i].equip) + && ((type == 1 && !sd->inventory.u.items_inventory[i].equip) + || (type == 2 && sd->inventory.u.items_inventory[i].equip) || type == 3) ){ - if(sd->status.inventory[i].equip) + if(sd->inventory.u.items_inventory[i].equip) pc_unequipitem(sd,i,3); pc_dropitem(sd,i,1); break; @@ -9216,16 +9193,16 @@ static int pc_checkcombo(struct map_session_data *sd, struct item_data *data) { continue; } combo_idx[j].idx = index; - pos |= sd->status.inventory[index].equip; + pos |= sd->inventory.u.items_inventory[index].equip; found = true; break; } else { //Cards uint16 z; - if ( sd->inventory_data[index]->slot == 0 || itemdb_isspecial(sd->status.inventory[index].card[0]) ) + if ( sd->inventory_data[index]->slot == 0 || itemdb_isspecial(sd->inventory.u.items_inventory[index].card[0]) ) continue; for (z = 0; z < sd->inventory_data[index]->slot; z++) { bool do_continue=false; - if (sd->status.inventory[index].card[z] != id) + if (sd->inventory.u.items_inventory[index].card[z] != id) continue; if(j>0){ int c1, c2; @@ -9244,7 +9221,7 @@ static int pc_checkcombo(struct map_session_data *sd, struct item_data *data) { continue; combo_idx[j].idx = index; combo_idx[j].card[z] = id; - pos |= sd->status.inventory[index].equip; + pos |= sd->inventory.u.items_inventory[index].equip; found = true; break; } @@ -9350,13 +9327,13 @@ int pc_load_combo(struct map_session_data *sd) { continue; if( id->combos_count ) ret += pc_checkcombo(sd,id); - if(!itemdb_isspecial(sd->status.inventory[idx].card[0])) { + if(!itemdb_isspecial(sd->inventory.u.items_inventory[idx].card[0])) { struct item_data *data; int j; for( j = 0; j < id->slot; j++ ) { - if (!sd->status.inventory[idx].card[j]) + if (!sd->inventory.u.items_inventory[idx].card[j]) continue; - if ( ( data = itemdb_exists(sd->status.inventory[idx].card[j]) ) != NULL ) { + if ( ( data = itemdb_exists(sd->inventory.u.items_inventory[idx].card[j]) ) != NULL ) { if( data->combos_count ) ret += pc_checkcombo(sd,data); } @@ -9391,14 +9368,14 @@ bool pc_equipitem(struct map_session_data *sd,short n,int req_pos) pos = pc_equippoint(sd,n); //With a few exceptions, item should go in all specified slots. if(battle_config.battle_log) - ShowInfo("equip %hu(%d) %x:%x\n",sd->status.inventory[n].nameid,n,id?id->equip:0,req_pos); + ShowInfo("equip %hu (%d) %x:%x\n",sd->inventory.u.items_inventory[n].nameid,n,id?id->equip:0,req_pos); if((res = pc_isequip(sd,n))) { clif_equipitemack(sd,n,0,res); // fail return false; } - if (!(pos&req_pos) || sd->status.inventory[n].equip != 0 || sd->status.inventory[n].attribute==1 ) { // [Valaris] + if (!(pos&req_pos) || sd->inventory.u.items_inventory[n].equip != 0 || sd->inventory.u.items_inventory[n].attribute==1 ) { // [Valaris] clif_equipitemack(sd,n,0,ITEM_EQUIP_ACK_FAIL); // fail return false; } @@ -9440,8 +9417,8 @@ bool pc_equipitem(struct map_session_data *sd,short n,int req_pos) } } - if (id->flag.bindOnEquip && !sd->status.inventory[n].bound) { - sd->status.inventory[n].bound = (char)battle_config.default_bind_on_equip; + if (id->flag.bindOnEquip && !sd->inventory.u.items_inventory[n].bound) { + sd->inventory.u.items_inventory[n].bound = (char)battle_config.default_bind_on_equip; clif_notify_bindOnEquip(sd,n); } @@ -9488,7 +9465,7 @@ bool pc_equipitem(struct map_session_data *sd,short n,int req_pos) else clif_equipitemack(sd,n,pos,ITEM_EQUIP_ACK_OK); - sd->status.inventory[n].equip=pos; + sd->inventory.u.items_inventory[n].equip = pos; if(pos & EQP_HAND_R) { if(id) @@ -9576,14 +9553,14 @@ bool pc_equipitem(struct map_session_data *sd,short n,int req_pos) /* check for combos (MUST be before status_calc_pc) */ if( id->combos_count ) pc_checkcombo(sd,id); - if(itemdb_isspecial(sd->status.inventory[n].card[0])) + if(itemdb_isspecial(sd->inventory.u.items_inventory[n].card[0])) ; //No cards else { for( i = 0; i < id->slot; i++ ) { struct item_data *data; - if (!sd->status.inventory[n].card[i]) + if (!sd->inventory.u.items_inventory[n].card[i]) continue; - if ( ( data = itemdb_exists(sd->status.inventory[n].card[i]) ) != NULL ) { + if ( ( data = itemdb_exists(sd->inventory.u.items_inventory[n].card[i]) ) != NULL ) { if( data->combos_count ) pc_checkcombo(sd,data); } @@ -9599,14 +9576,14 @@ bool pc_equipitem(struct map_session_data *sd,short n,int req_pos) //only run the script if item isn't restricted if (id->equip_script && (pc_has_permission(sd,PC_PERM_USE_ALL_EQUIPMENT) || !itemdb_isNoEquip(id,sd->bl.m))) run_script(id->equip_script,0,sd->bl.id,fake_nd->bl.id); - if(itemdb_isspecial(sd->status.inventory[n].card[0])) + if(itemdb_isspecial(sd->inventory.u.items_inventory[n].card[0])) ; //No cards else { for( i = 0; i < id->slot; i++ ) { struct item_data *data; - if (!sd->status.inventory[n].card[i]) + if (!sd->inventory.u.items_inventory[n].card[i]) continue; - if ( ( data = itemdb_exists(sd->status.inventory[n].card[i]) ) != NULL ) { + if ( ( data = itemdb_exists(sd->inventory.u.items_inventory[n].card[i]) ) != NULL ) { if (data->equip_script && (pc_has_permission(sd,PC_PERM_USE_ALL_EQUIPMENT) || !itemdb_isNoEquip(data,sd->bl.m))) run_script(data->equip_script,0,sd->bl.id,fake_nd->bl.id); } @@ -9636,7 +9613,7 @@ bool pc_unequipitem(struct map_session_data *sd, int n, int flag) { clif_unequipitemack(sd,0,0,0); return false; } - if (!sd->status.inventory[n].equip) { + if (!sd->inventory.u.items_inventory[n].equip) { clif_unequipitemack(sd,n,0,0); return false; //Nothing to unequip } @@ -9654,14 +9631,18 @@ bool pc_unequipitem(struct map_session_data *sd, int n, int flag) { } if (battle_config.battle_log) - ShowInfo("unequip %d %x:%x\n",n,pc_equippoint(sd,n),sd->status.inventory[n].equip); + ShowInfo("unequip %d %x:%x\n",n,pc_equippoint(sd,n),sd->inventory.u.items_inventory[n].equip); + if (!sd->inventory.u.items_inventory[n].equip) { //Nothing to unequip + clif_unequipitemack(sd, n, 0, 0); + return false; + } for(i = 0; i < EQI_MAX; i++) { - if (sd->status.inventory[n].equip & equip_pos[i]) + if (sd->inventory.u.items_inventory[n].equip & equip_pos[i]) sd->equip_index[i] = -1; } - if(sd->status.inventory[n].equip & EQP_HAND_R) { + if(sd->inventory.u.items_inventory[n].equip & EQP_HAND_R) { sd->weapontype1 = 0; sd->status.weapon = sd->weapontype2; pc_calcweapontype(sd); @@ -9669,57 +9650,57 @@ bool pc_unequipitem(struct map_session_data *sd, int n, int flag) { if( !battle_config.dancing_weaponswitch_fix ) status_change_end(&sd->bl, SC_DANCING, INVALID_TIMER); // Unequipping => stop dancing. } - if(sd->status.inventory[n].equip & EQP_HAND_L) { + if(sd->inventory.u.items_inventory[n].equip & EQP_HAND_L) { sd->status.shield = sd->weapontype2 = 0; pc_calcweapontype(sd); clif_changelook(&sd->bl,LOOK_SHIELD,sd->status.shield); } - if(sd->status.inventory[n].equip & EQP_HEAD_LOW && pc_checkequip(sd,EQP_COSTUME_HEAD_LOW) == -1 ) { + if(sd->inventory.u.items_inventory[n].equip & EQP_HEAD_LOW && pc_checkequip(sd,EQP_COSTUME_HEAD_LOW) == -1 ) { sd->status.head_bottom = 0; clif_changelook(&sd->bl,LOOK_HEAD_BOTTOM,sd->status.head_bottom); } - if(sd->status.inventory[n].equip & EQP_HEAD_TOP && pc_checkequip(sd,EQP_COSTUME_HEAD_TOP) == -1 ) { + if(sd->inventory.u.items_inventory[n].equip & EQP_HEAD_TOP && pc_checkequip(sd,EQP_COSTUME_HEAD_TOP) == -1 ) { sd->status.head_top = 0; clif_changelook(&sd->bl,LOOK_HEAD_TOP,sd->status.head_top); } - if(sd->status.inventory[n].equip & EQP_HEAD_MID && pc_checkequip(sd,EQP_COSTUME_HEAD_MID) == -1 ) { + if(sd->inventory.u.items_inventory[n].equip & EQP_HEAD_MID && pc_checkequip(sd,EQP_COSTUME_HEAD_MID) == -1 ) { sd->status.head_mid = 0; clif_changelook(&sd->bl,LOOK_HEAD_MID,sd->status.head_mid); } - if(sd->status.inventory[n].equip & EQP_COSTUME_HEAD_TOP) { + if(sd->inventory.u.items_inventory[n].equip & EQP_COSTUME_HEAD_TOP) { sd->status.head_top = ( pc_checkequip(sd,EQP_HEAD_TOP) >= 0 ) ? sd->inventory_data[pc_checkequip(sd,EQP_HEAD_TOP)]->look : 0; clif_changelook(&sd->bl,LOOK_HEAD_TOP,sd->status.head_top); } - if(sd->status.inventory[n].equip & EQP_COSTUME_HEAD_MID) { + if(sd->inventory.u.items_inventory[n].equip & EQP_COSTUME_HEAD_MID) { sd->status.head_mid = ( pc_checkequip(sd,EQP_HEAD_MID) >= 0 ) ? sd->inventory_data[pc_checkequip(sd,EQP_HEAD_MID)]->look : 0; clif_changelook(&sd->bl,LOOK_HEAD_MID,sd->status.head_mid); } - if(sd->status.inventory[n].equip & EQP_COSTUME_HEAD_LOW) { + if(sd->inventory.u.items_inventory[n].equip & EQP_COSTUME_HEAD_LOW) { sd->status.head_bottom = ( pc_checkequip(sd,EQP_HEAD_LOW) >= 0 ) ? sd->inventory_data[pc_checkequip(sd,EQP_HEAD_LOW)]->look : 0; clif_changelook(&sd->bl,LOOK_HEAD_BOTTOM,sd->status.head_bottom); } - if(sd->status.inventory[n].equip & EQP_SHOES) + if(sd->inventory.u.items_inventory[n].equip & EQP_SHOES) clif_changelook(&sd->bl,LOOK_SHOES,0); - if(sd->status.inventory[n].equip&EQP_GARMENT && pc_checkequip(sd,EQP_COSTUME_GARMENT) == -1) { + if(sd->inventory.u.items_inventory[n].equip&EQP_GARMENT && pc_checkequip(sd,EQP_COSTUME_GARMENT) == -1) { sd->status.robe = 0; clif_changelook(&sd->bl, LOOK_ROBE, 0); } - if(sd->status.inventory[n].equip & EQP_COSTUME_GARMENT) { + if(sd->inventory.u.items_inventory[n].equip & EQP_COSTUME_GARMENT) { sd->status.robe = ( pc_checkequip(sd,EQP_GARMENT) >= 0 ) ? sd->inventory_data[pc_checkequip(sd,EQP_GARMENT)]->look : 0; clif_changelook(&sd->bl,LOOK_ROBE,sd->status.robe); } - clif_unequipitemack(sd,n,sd->status.inventory[n].equip,1); + clif_unequipitemack(sd,n,sd->inventory.u.items_inventory[n].equip,1); status_change_end(&sd->bl,SC_HEAT_BARREL,INVALID_TIMER); // On weapon change (right and left hand) - if ((sd->status.inventory[n].equip & EQP_ARMS) && sd->inventory_data[n]->type == IT_WEAPON) { + if ((sd->inventory.u.items_inventory[n].equip & EQP_ARMS) && sd->inventory_data[n]->type == IT_WEAPON) { if (!sd->sc.data[SC_SEVENWIND] || sd->sc.data[SC_ASPERSIO]) //Check for seven wind (but not level seven!) skill_enchant_elemental_end(&sd->bl, SC_NONE); status_change_end(&sd->bl, SC_FEARBREEZE, INVALID_TIMER); @@ -9728,7 +9709,7 @@ bool pc_unequipitem(struct map_session_data *sd, int n, int flag) { } // On armor change - if (sd->status.inventory[n].equip & EQP_ARMOR) { + if (sd->inventory.u.items_inventory[n].equip & EQP_ARMOR) { if (sd->sc.data[SC_HOVERING] && sd->inventory_data[n]->nameid == ITEMID_HOVERING_BOOSTER) status_change_end(&sd->bl, SC_HOVERING, INVALID_TIMER); //status_change_end(&sd->bl, SC_BENEDICTIO, INVALID_TIMER); // No longer is removed? Need confirmation @@ -9739,10 +9720,10 @@ bool pc_unequipitem(struct map_session_data *sd, int n, int flag) { if (sd->inventory_data[n]->type == IT_AMMO) status_change_end(&sd->bl, SC_P_ALTER, INVALID_TIMER); - if( sd->state.autobonus&sd->status.inventory[n].equip ) - sd->state.autobonus &= ~sd->status.inventory[n].equip; //Check for activated autobonus [Inkfish] + if (sd->state.autobonus&sd->inventory.u.items_inventory[n].equip) + sd->state.autobonus &= ~sd->inventory.u.items_inventory[n].equip; //Check for activated autobonus [Inkfish] - sd->status.inventory[n].equip = 0; + sd->inventory.u.items_inventory[n].equip = 0; iflag = sd->npc_item_flag; /* check for combos (MUST be before status_calc_pc) */ @@ -9750,15 +9731,15 @@ bool pc_unequipitem(struct map_session_data *sd, int n, int flag) { if( sd->inventory_data[n]->combos_count ) { if( pc_removecombo(sd,sd->inventory_data[n]) ) status_cacl = true; - } if(itemdb_isspecial(sd->status.inventory[n].card[0])) + } if(itemdb_isspecial(sd->inventory.u.items_inventory[n].card[0])) ; //No cards else { for( i = 0; i < sd->inventory_data[n]->slot; i++ ) { struct item_data *data; - if (!sd->status.inventory[n].card[i]) + if (!sd->inventory.u.items_inventory[n].card[i]) continue; - if ( ( data = itemdb_exists(sd->status.inventory[n].card[i]) ) != NULL ) { + if ( ( data = itemdb_exists(sd->inventory.u.items_inventory[n].card[i]) ) != NULL ) { if( data->combos_count ) { if( pc_removecombo(sd,data) ) status_cacl = true; @@ -9780,15 +9761,15 @@ bool pc_unequipitem(struct map_session_data *sd, int n, int flag) { if (sd->inventory_data[n]) { if (sd->inventory_data[n]->unequip_script) run_script(sd->inventory_data[n]->unequip_script,0,sd->bl.id,fake_nd->bl.id); - if(itemdb_isspecial(sd->status.inventory[n].card[0])) + if(itemdb_isspecial(sd->inventory.u.items_inventory[n].card[0])) ; //No cards else { for( i = 0; i < sd->inventory_data[n]->slot; i++ ) { struct item_data *data; - if (!sd->status.inventory[n].card[i]) + if (!sd->inventory.u.items_inventory[n].card[i]) continue; - if ( ( data = itemdb_exists(sd->status.inventory[n].card[i]) ) != NULL ) { + if ( ( data = itemdb_exists(sd->inventory.u.items_inventory[n].card[i]) ) != NULL ) { if( data->unequip_script ) run_script(data->unequip_script,0,sd->bl.id,fake_nd->bl.id); } @@ -9814,10 +9795,10 @@ void pc_checkitem(struct map_session_data *sd) { if( sd->state.vending ) //Avoid reorganizing items when we are vending, as that leads to exploits (pointed out by End of Exam) return; - pc_check_available_item(sd); // Check for invalid(ated) items. + pc_check_available_item(sd, ITMCHK_NONE); // Check for invalid(ated) items. for( i = 0; i < MAX_INVENTORY; i++ ) { - it = sd->status.inventory[i]; + it = sd->inventory.u.items_inventory[i]; if( it.nameid == 0 ) continue; @@ -9844,8 +9825,13 @@ void pc_checkitem(struct map_session_data *sd) { /*========================================== * Checks for unavailable items and removes them. + * @param sd: Player data + * @param type Forced check: + * 1 - Inventory + * 2 - Cart + * 4 - Storage *------------------------------------------*/ -void pc_check_available_item(struct map_session_data *sd) +void pc_check_available_item(struct map_session_data *sd, uint8 type) { int i; unsigned short nameid; @@ -9853,57 +9839,57 @@ void pc_check_available_item(struct map_session_data *sd) nullpo_retv(sd); - if (battle_config.item_check&0x1) { // Check for invalid(ated) items in inventory. + if (battle_config.item_check&ITMCHK_INVENTORY || type&ITMCHK_INVENTORY) { // Check for invalid(ated) items in inventory. for(i = 0; i < MAX_INVENTORY; i++) { - nameid = sd->status.inventory[i].nameid; + nameid = sd->inventory.u.items_inventory[i].nameid; if (!nameid) continue; if (!itemdb_available(nameid)) { sprintf(output, msg_txt(sd, 709), nameid); // Item %hu has been removed from your inventory. clif_displaymessage(sd->fd, output); - ShowWarning("Removed invalid/disabled item id %hu from inventory (amount=%d, char_id=%d).\n", nameid, sd->status.inventory[i].amount, sd->status.char_id); - pc_delitem(sd, i, sd->status.inventory[i].amount, 0, 0, LOG_TYPE_OTHER); + ShowWarning("Removed invalid/disabled item (ID: %hu, amount: %d) from inventory (char_id: %d).\n", nameid, sd->inventory.u.items_inventory[i].amount, sd->status.char_id); + pc_delitem(sd, i, sd->inventory.u.items_inventory[i].amount, 0, 0, LOG_TYPE_OTHER); continue; } - if (!sd->status.inventory[i].unique_id && !itemdb_isstackable(nameid)) - sd->status.inventory[i].unique_id = pc_generate_unique_id(sd); + if (!sd->inventory.u.items_inventory[i].unique_id && !itemdb_isstackable(nameid)) + sd->inventory.u.items_inventory[i].unique_id = pc_generate_unique_id(sd); } } - if (battle_config.item_check&0x2) { // Check for invalid(ated) items in cart. + if (battle_config.item_check&ITMCHK_CART || type&ITMCHK_CART) { // Check for invalid(ated) items in cart. for(i = 0; i < MAX_CART; i++) { - nameid = sd->status.cart[i].nameid; + nameid = sd->cart.u.items_cart[i].nameid; if (!nameid) continue; if (!itemdb_available(nameid)) { sprintf(output, msg_txt(sd, 710), nameid); // Item %hu has been removed from your cart. clif_displaymessage(sd->fd, output); - ShowWarning("Removed invalid/disabled item id %hu from cart (amount=%d, char_id=%d).\n", nameid, sd->status.cart[i].amount, sd->status.char_id); - pc_cart_delitem(sd, i, sd->status.cart[i].amount, 0, LOG_TYPE_OTHER); + ShowWarning("Removed invalid/disabled item (ID: %hu, amount: %d) from cart (char_id: %d).\n", nameid, sd->cart.u.items_cart[i].amount, sd->status.char_id); + pc_cart_delitem(sd, i, sd->cart.u.items_cart[i].amount, 0, LOG_TYPE_OTHER); continue; } - if (!sd->status.cart[i].unique_id && !itemdb_isstackable(nameid)) - sd->status.cart[i].unique_id = pc_generate_unique_id(sd); + if (!sd->cart.u.items_cart[i].unique_id && !itemdb_isstackable(nameid)) + sd->cart.u.items_cart[i].unique_id = pc_generate_unique_id(sd); } } - if (battle_config.item_check&0x4) { // Check for invalid(ated) items in storage. + if (battle_config.item_check&ITMCHK_STORAGE || type&ITMCHK_STORAGE) { // Check for invalid(ated) items in storage. for(i = 0; i < sd->storage_size; i++) { - nameid = sd->status.storage.items[i].nameid; + nameid = sd->storage.u.items_storage[i].nameid; if (!nameid) continue; if (!itemdb_available(nameid)) { sprintf(output, msg_txt(sd, 711), nameid); // Item %hu has been removed from your storage. clif_displaymessage(sd->fd, output); - ShowWarning("Removed invalid/disabled item id %hu from storage (amount=%d, char_id=%d).\n", nameid, sd->status.storage.items[i].amount, sd->status.char_id); - storage_delitem(sd, i, sd->status.storage.items[i].amount); + ShowWarning("Removed invalid/disabled item (ID: %hu, amount: %d) from storage (char_id: %d).\n", nameid, sd->storage.u.items_storage[i].amount, sd->status.char_id); + storage_delitem(sd, i, sd->storage.u.items_storage[i].amount); continue; } - if (!sd->status.storage.items[i].unique_id && !itemdb_isstackable(nameid)) - sd->status.storage.items[i].unique_id = pc_generate_unique_id(sd); + if (!sd->storage.u.items_storage[i].unique_id && !itemdb_isstackable(nameid)) + sd->storage.u.items_storage[i].unique_id = pc_generate_unique_id(sd); } } } @@ -10026,9 +10012,9 @@ bool pc_divorce(struct map_session_data *sd) p_sd->status.partner_id = 0; for( i = 0; i < MAX_INVENTORY; i++ ) { - if( sd->status.inventory[i].nameid == WEDDING_RING_M || sd->status.inventory[i].nameid == WEDDING_RING_F ) + if( sd->inventory.u.items_inventory[i].nameid == WEDDING_RING_M || sd->inventory.u.items_inventory[i].nameid == WEDDING_RING_F ) pc_delitem(sd, i, 1, 0, 0, LOG_TYPE_OTHER); - if( p_sd->status.inventory[i].nameid == WEDDING_RING_M || p_sd->status.inventory[i].nameid == WEDDING_RING_F ) + if( p_sd->inventory.u.items_inventory[i].nameid == WEDDING_RING_M || p_sd->inventory.u.items_inventory[i].nameid == WEDDING_RING_F ) pc_delitem(p_sd, i, 1, 0, 0, LOG_TYPE_OTHER); } diff --git a/src/map/pc.h b/src/map/pc.h index e0dc493732..49b1e77887 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -267,6 +267,11 @@ struct map_session_data { uint32 packet_ver; // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 ... 18 struct mmo_charstatus status; + // Item Storages + struct s_storage storage; + struct s_storage inventory; + struct s_storage cart; + struct item_data* inventory_data[MAX_INVENTORY]; // direct pointers to itemdb entries (faster than doing item_id lookups) short equip_index[EQI_MAX]; unsigned int weight,max_weight; @@ -762,6 +767,14 @@ enum adopt_responses { ADOPT_MARRIED, }; +enum item_check { + ITMCHK_NONE = 0x0, + ITMCHK_INVENTORY = 0x1, + ITMCHK_CART = 0x2, + ITMCHK_STORAGE = 0x4, + ITMCHK_ALL = ITMCHK_INVENTORY|ITMCHK_CART|ITMCHK_STORAGE, +}; + struct { unsigned int base_hp[MAX_LEVEL], base_sp[MAX_LEVEL]; //Storage for the first calculation with hp/sp factor and multiplicator int hp_factor, hp_multiplicator, sp_factor; @@ -925,6 +938,7 @@ void pc_reg_received(struct map_session_data *sd); void pc_close_npc(struct map_session_data *sd,int flag); int pc_close_npc_timer(int tid, unsigned int tick, int id, intptr_t data); +void pc_setequipindex(struct map_session_data *sd); uint8 pc_isequip(struct map_session_data *sd,int n); int pc_equippoint(struct map_session_data *sd,int n); void pc_setinventorydata(struct map_session_data *sd); @@ -1041,7 +1055,7 @@ int pc_resethate(struct map_session_data*); bool pc_equipitem(struct map_session_data *sd, short n, int req_pos); bool pc_unequipitem(struct map_session_data*,int,int); void pc_checkitem(struct map_session_data*); -void pc_check_available_item(struct map_session_data *sd); +void pc_check_available_item(struct map_session_data *sd, uint8 type); int pc_useitem(struct map_session_data*,int); int pc_skillatk_bonus(struct map_session_data *sd, uint16 skill_id); diff --git a/src/map/pet.c b/src/map/pet.c index 9a45b8bfa4..1f372730fe 100644 --- a/src/map/pet.c +++ b/src/map/pet.c @@ -556,8 +556,8 @@ int pet_recv_petdata(uint32 account_id,struct s_pet *p,int flag) //Delete egg from inventory. [Skotlex] for (i = 0; i < MAX_INVENTORY; i++) { - if(sd->status.inventory[i].card[0] == CARD0_PET && - p->pet_id == MakeDWord(sd->status.inventory[i].card[1], sd->status.inventory[i].card[2])) + if(sd->inventory.u.items_inventory[i].card[0] == CARD0_PET && + p->pet_id == MakeDWord(sd->inventory.u.items_inventory[i].card[1], sd->inventory.u.items_inventory[i].card[2])) break; } @@ -601,8 +601,8 @@ int pet_select_egg(struct map_session_data *sd,short egg_index) if(egg_index < 0 || egg_index >= MAX_INVENTORY) return 0; //Forged packet! - if(sd->status.inventory[egg_index].card[0] == CARD0_PET) - intif_request_petdata(sd->status.account_id, sd->status.char_id, MakeDWord(sd->status.inventory[egg_index].card[1], sd->status.inventory[egg_index].card[2]) ); + if(sd->inventory.u.items_inventory[egg_index].card[0] == CARD0_PET) + intif_request_petdata(sd->status.account_id, sd->status.char_id, MakeDWord(sd->inventory.u.items_inventory[egg_index].card[1], sd->inventory.u.items_inventory[egg_index].card[2]) ); else ShowError("wrong egg item inventory %d\n",egg_index); @@ -861,10 +861,7 @@ int pet_equipitem(struct map_session_data *sd,int index) pd = sd->pd; - if (!pd) - return 1; - - nameid = sd->status.inventory[index].nameid; + nameid = sd->inventory.u.items_inventory[index].nameid; if(pd->petDB->AcceID == 0 || nameid != pd->petDB->AcceID || pd->pet.equip != 0) { clif_equipitemack(sd,0,0,ITEM_EQUIP_ACK_FAIL); diff --git a/src/map/script.c b/src/map/script.c index 9954498066..35af480020 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -45,13 +45,9 @@ #include "battleground.h" #include "party.h" #include "mail.h" -#include "script.h" #include "quest.h" #include "elemental.h" -#include -#include -#include #include #ifndef WIN32 #endif @@ -4223,7 +4219,7 @@ void script_run_autobonus(const char *autobonus, struct map_session_data *sd, un if( script ) { int j; - ARR_FIND( 0, EQI_MAX, j, sd->equip_index[j] >= 0 && sd->status.inventory[sd->equip_index[j]].equip == pos ); + ARR_FIND( 0, EQI_MAX, j, sd->equip_index[j] >= 0 && sd->inventory.u.items_inventory[sd->equip_index[j]].equip == pos ); if( j < EQI_MAX ) { //Single item autobonus current_equip_item_index = sd->equip_index[j]; @@ -6447,6 +6443,8 @@ BUILDIN_FUNC(viewpoint) /// cartcountitem2 ,,,,,,,{,}) /// storagecountitem {,}); /// storagecountitem2 ,,,,,,,{,}) +/// guildstoragecountitem {,}); +/// guildstoragecountitem2 ,,,,,,,{,}) BUILDIN_FUNC(countitem) { int i = 0, count = 0, aid = 3; @@ -6457,6 +6455,7 @@ BUILDIN_FUNC(countitem) uint16 size; struct item *items; TBL_PC *sd = NULL; + struct s_storage *gstor; if( command[strlen(command)-1] == '2' ) { i = 1; @@ -6478,17 +6477,28 @@ BUILDIN_FUNC(countitem) if( !strncmp(command, "cart", 4) ) { loc = 1; size = MAX_CART; - items = sd->status.cart; + items = sd->cart.u.items_cart; } else if( !strncmp(command, "storage", 7) ) { loc = 2; size = MAX_STORAGE; - items = sd->status.storage.items; + items = sd->storage.u.items_storage; + } + else if( !strncmp(command, "guildstorage", 12) ) { + gstor = guild2storage2(sd->status.guild_id); + + if (gstor && !sd->state.storage_flag) { + loc = 3; + size = MAX_GUILD_STORAGE; + items = gstor->u.items_guild; + } else { + script_pushint(st, -1); + return SCRIPT_CMD_SUCCESS; + } } - //TODO: 3 - Guild Storage else { size = MAX_INVENTORY; - items = sd->status.inventory; + items = sd->inventory.u.items_inventory; } if( loc == 1 && !pc_iscarton(sd) ) { @@ -6511,6 +6521,9 @@ BUILDIN_FUNC(countitem) return SCRIPT_CMD_FAILURE; } + if (loc == 3) + gstor->lock = true; + if( !i ) { // For count/cart/storagecountitem function unsigned short nameid = id->nameid; for( i = 0; i < size; i++ ) @@ -6541,6 +6554,11 @@ BUILDIN_FUNC(countitem) } } + if (loc == 3) { + storage_guild_storageclose(sd); + gstor->lock = false; + } + script_pushint(st, count); return SCRIPT_CMD_SUCCESS; } @@ -7312,16 +7330,24 @@ static void buildin_delitem_delete(struct map_session_data* sd, int idx, int* am { int delamount; struct item *itm = NULL; + struct s_storage *gstor; switch(loc) { case 1: // cart - itm = &sd->status.cart[idx]; + itm = &sd->cart.u.items_cart[idx]; break; case 2: // storage - itm = &sd->status.storage.items[idx]; + itm = &sd->storage.u.items_storage[idx]; + break; + case 3: // guild storage + { + gstor = guild2storage2(sd->status.guild_id); + + itm = &gstor->u.items_guild[idx]; + } break; default: //inventory - itm = &sd->status.inventory[idx]; + itm = &sd->inventory.u.items_inventory[idx]; break; } @@ -7341,6 +7367,13 @@ static void buildin_delitem_delete(struct map_session_data* sd, int idx, int* am storage_delitem(sd,idx,delamount); log_pick_pc(sd,LOG_TYPE_SCRIPT,-delamount,itm); break; + case 3: + gstor->lock = true; + storage_guild_delitem(sd, gstor, idx, delamount); + log_pick_pc(sd, LOG_TYPE_SCRIPT, -delamount, itm); + storage_guild_storageclose(sd); + gstor->lock = false; + break; default: pc_delitem(sd, idx, delamount, 0, 0, LOG_TYPE_SCRIPT); break; @@ -7377,15 +7410,23 @@ static bool buildin_delitem_search(struct map_session_data* sd, struct item* it, switch(loc) { case 1: // cart size = MAX_CART; - items = sd->status.cart; + items = sd->cart.u.items_cart; break; case 2: // storage size = MAX_STORAGE; - items = sd->status.storage.items; + items = sd->storage.u.items_storage; + break; + case 3: // guild storage + { + struct s_storage *gstor = guild2storage2(sd->status.guild_id); + + size = MAX_GUILD_STORAGE; + items = gstor->u.items_guild; + } break; default: //inventory size = MAX_INVENTORY; - items = sd->status.inventory; + items = sd->inventory.u.items_inventory; break; } @@ -7493,6 +7534,8 @@ static bool buildin_delitem_search(struct map_session_data* sd, struct item* it, /// cartdelitem "",{,} /// storagedelitem ,{,} /// storagedelitem "",{,} +/// guildstoragedelitem ,{,} +/// guildstoragedelitem "",{,} BUILDIN_FUNC(delitem) { TBL_PC *sd; @@ -7505,7 +7548,8 @@ BUILDIN_FUNC(delitem) loc = 1; else if(!strncmp(command, "storage", 7)) loc = 2; - //TODO: 3 - Guild Storage + else if(!strncmp(command, "guildstorage", 12)) + loc = 3; if( script_hasdata(st,4) ) { @@ -7527,8 +7571,17 @@ BUILDIN_FUNC(delitem) if (loc == 1 && !pc_iscarton(sd)) { ShowError("buildin_cartdelitem: player doesn't have cart (CID=%d).\n", sd->status.char_id); + script_pushint(st, -1); return SCRIPT_CMD_FAILURE; } + if (loc == 3) { + struct s_storage *gstor = guild2storage2(sd->status.guild_id); + + if (gstor == NULL || sd->state.storage_flag) { + script_pushint(st, -1); + return SCRIPT_CMD_FAILURE; + } + } data = script_getdata(st,2); get_val(st,data); @@ -7580,6 +7633,8 @@ BUILDIN_FUNC(delitem) /// cartdelitem2 "",,,,,,,,{,} /// storagedelitem2 ,,,,,,,,{,} /// storagedelitem2 "",,,,,,,,{,} +/// guildstoragedelitem2 ,,,,,,,,{,} +/// guildstoragedelitem2 "",,,,,,,,{,} BUILDIN_FUNC(delitem2) { TBL_PC *sd; @@ -7592,7 +7647,8 @@ BUILDIN_FUNC(delitem2) loc = 1; else if(!strncmp(command, "storage", 7)) loc = 2; - //TODO: 3 - Guild Storage + else if(!strncmp(command, "guildstorage", 12)) + loc = 3; if( script_hasdata(st,11) ) { @@ -7617,6 +7673,14 @@ BUILDIN_FUNC(delitem2) script_pushint(st,-1); return SCRIPT_CMD_FAILURE; } + if (loc == 3) { + struct s_storage *gstor = guild2storage2(sd->status.guild_id); + + if (gstor == NULL || sd->state.storage_flag) { + script_pushint(st, -1); + return SCRIPT_CMD_FAILURE; + } + } data = script_getdata(st,2); get_val(st,data); @@ -8158,7 +8222,7 @@ BUILDIN_FUNC(getequipuniqueid) return SCRIPT_CMD_FAILURE; } - item = &sd->status.inventory[i]; + item = &sd->inventory.u.items_inventory[i]; if (item != 0) { int maxlen = 256; char *buf = (char *)aMalloc(maxlen*sizeof(char)); @@ -8219,7 +8283,7 @@ BUILDIN_FUNC(getequipname) *------------------------------------------*/ BUILDIN_FUNC(getbrokenid) { - int i,num,id=0,brokencounter=0; + int i,num,id = 0,brokencounter = 0; TBL_PC *sd; if (!script_charid2sd(3, sd)) { @@ -8227,12 +8291,12 @@ BUILDIN_FUNC(getbrokenid) return SCRIPT_CMD_FAILURE; } - num=script_getnum(st,2); - for(i=0; istatus.inventory[i].attribute){ + num = script_getnum(st,2); + for(i = 0; i < MAX_INVENTORY; i++) { + if(sd->inventory.u.items_inventory[i].attribute) { brokencounter++; - if(num==brokencounter){ - id=sd->status.inventory[i].nameid; + if(num == brokencounter){ + id = sd->inventory.u.items_inventory[i].nameid; break; } } @@ -8250,20 +8314,20 @@ BUILDIN_FUNC(getbrokenid) BUILDIN_FUNC(repair) { int i,num; - int repaircounter=0; + int repaircounter = 0; TBL_PC *sd; if (!script_charid2sd(3,sd)) return SCRIPT_CMD_FAILURE; - num=script_getnum(st,2); - for(i=0; istatus.inventory[i].attribute){ + num = script_getnum(st,2); + for(i = 0; i < MAX_INVENTORY; i++) { + if(sd->inventory.u.items_inventory[i].attribute) { repaircounter++; - if(num==repaircounter){ - sd->status.inventory[i].attribute=0; + if(num == repaircounter) { + sd->inventory.u.items_inventory[i].attribute = 0; clif_equiplist(sd); - clif_produceeffect(sd, 0, sd->status.inventory[i].nameid); + clif_produceeffect(sd, 0, sd->inventory.u.items_inventory[i].nameid); clif_misceffect(&sd->bl, 3); break; } @@ -8286,10 +8350,10 @@ BUILDIN_FUNC(repairall) for(i = 0; i < MAX_INVENTORY; i++) { - if(sd->status.inventory[i].nameid && sd->status.inventory[i].attribute) + if(sd->inventory.u.items_inventory[i].nameid && sd->inventory.u.items_inventory[i].attribute) { - sd->status.inventory[i].attribute = 0; - clif_produceeffect(sd,0,sd->status.inventory[i].nameid); + sd->inventory.u.items_inventory[i].attribute = 0; + clif_produceeffect(sd,0,sd->inventory.u.items_inventory[i].nameid); repaircounter++; } } @@ -8349,7 +8413,7 @@ BUILDIN_FUNC(getequipisenableref) if( num > 0 && num <= ARRAYLENGTH(equip) ) i = pc_checkequip(sd,equip[num-1]); - if( i >= 0 && sd->inventory_data[i] && !sd->inventory_data[i]->flag.no_refine && !sd->status.inventory[i].expire_time ) + if( i >= 0 && sd->inventory_data[i] && !sd->inventory_data[i]->flag.no_refine && !sd->inventory.u.items_inventory[i].expire_time ) script_pushint(st,1); else script_pushint(st,0); @@ -8379,7 +8443,7 @@ BUILDIN_FUNC(getequiprefinerycnt) if (num > 0 && num <= ARRAYLENGTH(equip)) i=pc_checkequip(sd,equip[num-1]); if(i >= 0) - script_pushint(st,sd->status.inventory[i].refine); + script_pushint(st,sd->inventory.u.items_inventory[i].refine); else script_pushint(st,0); @@ -8437,8 +8501,8 @@ BUILDIN_FUNC(getequippercentrefinery) if (num > 0 && num <= ARRAYLENGTH(equip)) i = pc_checkequip(sd,equip[num-1]); - if(i >= 0 && sd->status.inventory[i].nameid && sd->status.inventory[i].refine < MAX_REFINE) - script_pushint(st,status_get_refine_chance((enum refine_type)itemdb_wlv(sd->status.inventory[i].nameid), (int)sd->status.inventory[i].refine)); + if(i >= 0 && sd->inventory.u.items_inventory[i].nameid && sd->inventory.u.items_inventory[i].refine < MAX_REFINE) + script_pushint(st,status_get_refine_chance((enum refine_type)itemdb_wlv(sd->inventory.u.items_inventory[i].nameid), (int)sd->inventory.u.items_inventory[i].refine)); else script_pushint(st,0); @@ -8467,32 +8531,32 @@ BUILDIN_FUNC(successrefitem) { if (pos > 0 && pos <= ARRAYLENGTH(equip)) i = pc_checkequip(sd,equip[pos-1]); if (i >= 0) { - unsigned int ep = sd->status.inventory[i].equip; + unsigned int ep = sd->inventory.u.items_inventory[i].equip; //Logs items, got from (N)PC scripts [Lupus] - log_pick_pc(sd, LOG_TYPE_SCRIPT, -1, &sd->status.inventory[i]); + log_pick_pc(sd, LOG_TYPE_SCRIPT, -1, &sd->inventory.u.items_inventory[i]); - if (sd->status.inventory[i].refine >= MAX_REFINE) { + if (sd->inventory.u.items_inventory[i].refine >= MAX_REFINE) { script_pushint(st, MAX_REFINE); return SCRIPT_CMD_SUCCESS; } - sd->status.inventory[i].refine += up; - sd->status.inventory[i].refine = cap_value( sd->status.inventory[i].refine, 0, MAX_REFINE); + sd->inventory.u.items_inventory[i].refine += up; + sd->inventory.u.items_inventory[i].refine = cap_value( sd->inventory.u.items_inventory[i].refine, 0, MAX_REFINE); pc_unequipitem(sd,i,2); // status calc will happen in pc_equipitem() below - clif_refine(sd->fd,0,i,sd->status.inventory[i].refine); + clif_refine(sd->fd,0,i,sd->inventory.u.items_inventory[i].refine); clif_delitem(sd,i,1,3); //Logs items, got from (N)PC scripts [Lupus] - log_pick_pc(sd, LOG_TYPE_SCRIPT, 1, &sd->status.inventory[i]); + log_pick_pc(sd, LOG_TYPE_SCRIPT, 1, &sd->inventory.u.items_inventory[i]); clif_additem(sd,i,1,0); pc_equipitem(sd,i,ep); clif_misceffect(&sd->bl,3); - if (sd->status.inventory[i].refine == MAX_REFINE && - sd->status.inventory[i].card[0] == CARD0_FORGE && - sd->status.char_id == (int)MakeDWord(sd->status.inventory[i].card[2],sd->status.inventory[i].card[3])) + if (sd->inventory.u.items_inventory[i].refine == MAX_REFINE && + sd->inventory.u.items_inventory[i].card[0] == CARD0_FORGE && + sd->status.char_id == (int)MakeDWord(sd->inventory.u.items_inventory[i].card[2],sd->inventory.u.items_inventory[i].card[3])) { // Fame point system [DracoRPG] switch (sd->inventory_data[i]->wlv){ case 1: @@ -8506,7 +8570,7 @@ BUILDIN_FUNC(successrefitem) { break; } } - script_pushint(st, sd->status.inventory[i].refine); + script_pushint(st, sd->inventory.u.items_inventory[i].refine); return SCRIPT_CMD_SUCCESS; } @@ -8534,9 +8598,9 @@ BUILDIN_FUNC(failedrefitem) { if (pos > 0 && pos <= ARRAYLENGTH(equip)) i = pc_checkequip(sd,equip[pos-1]); if (i >= 0) { - sd->status.inventory[i].refine = 0; + sd->inventory.u.items_inventory[i].refine = 0; pc_unequipitem(sd,i,3); //recalculate bonus - clif_refine(sd->fd,1,i,sd->status.inventory[i].refine); //notify client of failure + clif_refine(sd->fd,1,i,sd->inventory.u.items_inventory[i].refine); //notify client of failure pc_delitem(sd,i,1,0,2,LOG_TYPE_SCRIPT); clif_misceffect(&sd->bl,2); // display failure effect script_pushint(st, 1); @@ -8569,25 +8633,25 @@ BUILDIN_FUNC(downrefitem) { if (pos > 0 && pos <= ARRAYLENGTH(equip)) i = pc_checkequip(sd,equip[pos-1]); if (i >= 0) { - unsigned int ep = sd->status.inventory[i].equip; + unsigned int ep = sd->inventory.u.items_inventory[i].equip; //Logs items, got from (N)PC scripts [Lupus] - log_pick_pc(sd, LOG_TYPE_SCRIPT, -1, &sd->status.inventory[i]); + log_pick_pc(sd, LOG_TYPE_SCRIPT, -1, &sd->inventory.u.items_inventory[i]); pc_unequipitem(sd,i,2); // status calc will happen in pc_equipitem() below - sd->status.inventory[i].refine -= down; - sd->status.inventory[i].refine = cap_value( sd->status.inventory[i].refine, 0, MAX_REFINE); + sd->inventory.u.items_inventory[i].refine -= down; + sd->inventory.u.items_inventory[i].refine = cap_value( sd->inventory.u.items_inventory[i].refine, 0, MAX_REFINE); - clif_refine(sd->fd,2,i,sd->status.inventory[i].refine); + clif_refine(sd->fd,2,i,sd->inventory.u.items_inventory[i].refine); clif_delitem(sd,i,1,3); //Logs items, got from (N)PC scripts [Lupus] - log_pick_pc(sd, LOG_TYPE_SCRIPT, 1, &sd->status.inventory[i]); + log_pick_pc(sd, LOG_TYPE_SCRIPT, 1, &sd->inventory.u.items_inventory[i]); clif_additem(sd,i,1,0); pc_equipitem(sd,i,ep); clif_misceffect(&sd->bl,2); - script_pushint(st, sd->status.inventory[i].refine); + script_pushint(st, sd->inventory.u.items_inventory[i].refine); return SCRIPT_CMD_SUCCESS; } @@ -8644,7 +8708,7 @@ BUILDIN_FUNC(breakequip) { if (pos > 0 && pos <= ARRAYLENGTH(equip)) i = pc_checkequip(sd,equip[pos-1]); if (i >= 0) { - sd->status.inventory[i].attribute = 1; + sd->inventory.u.items_inventory[i].attribute = 1; pc_unequipitem(sd,i,3); clif_equiplist(sd); script_pushint(st,1); @@ -8805,7 +8869,7 @@ BUILDIN_FUNC(autobonus) if (current_equip_combo_pos) pos = current_equip_combo_pos; else - pos = sd->status.inventory[current_equip_item_index].equip; + pos = sd->inventory.u.items_inventory[current_equip_item_index].equip; if((sd->state.autobonus&pos) == pos) return SCRIPT_CMD_SUCCESS; @@ -8847,7 +8911,7 @@ BUILDIN_FUNC(autobonus2) if (current_equip_combo_pos) pos = current_equip_combo_pos; else - pos = sd->status.inventory[current_equip_item_index].equip; + pos = sd->inventory.u.items_inventory[current_equip_item_index].equip; if((sd->state.autobonus&pos) == pos) return SCRIPT_CMD_SUCCESS; @@ -8889,7 +8953,7 @@ BUILDIN_FUNC(autobonus3) if (current_equip_combo_pos) pos = current_equip_combo_pos; else - pos = sd->status.inventory[current_equip_item_index].equip; + pos = sd->inventory.u.items_inventory[current_equip_item_index].equip; if((sd->state.autobonus&pos) == pos) return SCRIPT_CMD_SUCCESS; @@ -9526,7 +9590,7 @@ BUILDIN_FUNC(guildopenstorage) if( sd == NULL ) return SCRIPT_CMD_SUCCESS; - ret = gstorage_storageopen(sd); + ret = storage_guild_storageopen(sd); script_pushint(st,ret); return SCRIPT_CMD_SUCCESS; } @@ -9958,9 +10022,9 @@ BUILDIN_FUNC(killmonsterall) BUILDIN_FUNC(clone) { TBL_PC *sd, *msd=NULL; - uint32 char_id; - int master_id=0,x,y, flag = 0, m; + uint32 char_id, master_id = 0, x, y, flag = 0, m; enum e_mode mode = 0; + unsigned int duration = 0; const char *mapname,*event; @@ -12449,7 +12513,7 @@ BUILDIN_FUNC(getequipcardcnt) return SCRIPT_CMD_SUCCESS; } - if(itemdb_isspecial(sd->status.inventory[i].card[0])) + if(itemdb_isspecial(sd->inventory.u.items_inventory[i].card[0])) { script_pushint(st,0); return SCRIPT_CMD_SUCCESS; @@ -12457,7 +12521,7 @@ BUILDIN_FUNC(getequipcardcnt) count = 0; for( j = 0; j < sd->inventory_data[i]->slot; j++ ) - if( sd->status.inventory[i].card[j] && itemdb_type(sd->status.inventory[i].card[j]) == IT_CARD ) + if( sd->inventory.u.items_inventory[i].card[j] && itemdb_type(sd->inventory.u.items_inventory[i].card[j]) == IT_CARD ) count++; script_pushint(st,count); @@ -12480,16 +12544,16 @@ BUILDIN_FUNC(successremovecards) { return SCRIPT_CMD_SUCCESS; } - if(itemdb_isspecial(sd->status.inventory[i].card[0])) + if(itemdb_isspecial(sd->inventory.u.items_inventory[i].card[0])) return SCRIPT_CMD_SUCCESS; for( c = sd->inventory_data[i]->slot - 1; c >= 0; --c ) { - if( sd->status.inventory[i].card[c] && itemdb_type(sd->status.inventory[i].card[c]) == IT_CARD ) {// extract this card from the item + if( sd->inventory.u.items_inventory[i].card[c] && itemdb_type(sd->inventory.u.items_inventory[i].card[c]) == IT_CARD ) {// extract this card from the item unsigned char flag = 0; struct item item_tmp; memset(&item_tmp,0,sizeof(item_tmp)); cardflag = 1; - item_tmp.nameid = sd->status.inventory[i].card[c]; + item_tmp.nameid = sd->inventory.u.items_inventory[i].card[c]; item_tmp.identify = 1; if((flag=pc_additem(sd,&item_tmp,1,LOG_TYPE_SCRIPT))){ // get back the cart in inventory @@ -12504,15 +12568,15 @@ BUILDIN_FUNC(successremovecards) { struct item item_tmp; memset(&item_tmp,0,sizeof(item_tmp)); - item_tmp.nameid = sd->status.inventory[i].nameid; + item_tmp.nameid = sd->inventory.u.items_inventory[i].nameid; item_tmp.identify = 1; - item_tmp.refine = sd->status.inventory[i].refine; - item_tmp.attribute = sd->status.inventory[i].attribute; - item_tmp.expire_time = sd->status.inventory[i].expire_time; - item_tmp.bound = sd->status.inventory[i].bound; + item_tmp.refine = sd->inventory.u.items_inventory[i].refine; + item_tmp.attribute = sd->inventory.u.items_inventory[i].attribute; + item_tmp.expire_time = sd->inventory.u.items_inventory[i].expire_time; + item_tmp.bound = sd->inventory.u.items_inventory[i].bound; for (j = sd->inventory_data[i]->slot; j < MAX_SLOTS; j++) - item_tmp.card[j]=sd->status.inventory[i].card[j]; + item_tmp.card[j]=sd->inventory.u.items_inventory[i].card[j]; pc_delitem(sd,i,1,0,3,LOG_TYPE_SCRIPT); if((flag=pc_additem(sd,&item_tmp,1,LOG_TYPE_SCRIPT))){ //chk if can be spawn in inventory otherwise put on floor @@ -12544,11 +12608,11 @@ BUILDIN_FUNC(failedremovecards) { if (i < 0 || !sd->inventory_data[i]) return SCRIPT_CMD_SUCCESS; - if(itemdb_isspecial(sd->status.inventory[i].card[0])) + if(itemdb_isspecial(sd->inventory.u.items_inventory[i].card[0])) return SCRIPT_CMD_SUCCESS; for( c = sd->inventory_data[i]->slot - 1; c >= 0; --c ) { - if( sd->status.inventory[i].card[c] && itemdb_type(sd->status.inventory[i].card[c]) == IT_CARD ) { + if( sd->inventory.u.items_inventory[i].card[c] && itemdb_type(sd->inventory.u.items_inventory[i].card[c]) == IT_CARD ) { cardflag = 1; if(typefail == 2) {// add cards to inventory, clear @@ -12557,7 +12621,7 @@ BUILDIN_FUNC(failedremovecards) { memset(&item_tmp,0,sizeof(item_tmp)); - item_tmp.nameid = sd->status.inventory[i].card[c]; + item_tmp.nameid = sd->inventory.u.items_inventory[i].card[c]; item_tmp.identify = 1; if((flag=pc_additem(sd,&item_tmp,1,LOG_TYPE_SCRIPT))){ @@ -12578,15 +12642,15 @@ BUILDIN_FUNC(failedremovecards) { memset(&item_tmp,0,sizeof(item_tmp)); - item_tmp.nameid = sd->status.inventory[i].nameid; + item_tmp.nameid = sd->inventory.u.items_inventory[i].nameid; item_tmp.identify = 1; - item_tmp.refine = sd->status.inventory[i].refine; - item_tmp.attribute = sd->status.inventory[i].attribute; - item_tmp.expire_time = sd->status.inventory[i].expire_time; - item_tmp.bound = sd->status.inventory[i].bound; + item_tmp.refine = sd->inventory.u.items_inventory[i].refine; + item_tmp.attribute = sd->inventory.u.items_inventory[i].attribute; + item_tmp.expire_time = sd->inventory.u.items_inventory[i].expire_time; + item_tmp.bound = sd->inventory.u.items_inventory[i].bound; for (j = sd->inventory_data[i]->slot; j < MAX_SLOTS; j++) - item_tmp.card[j]=sd->status.inventory[i].card[j]; + item_tmp.card[j]=sd->inventory.u.items_inventory[i].card[j]; pc_delitem(sd,i,1,0,2,LOG_TYPE_SCRIPT); @@ -13161,7 +13225,7 @@ BUILDIN_FUNC(getequipcardid) if (num > 0 && num <= ARRAYLENGTH(equip)) i=pc_checkequip(sd,equip[num-1]); if(i >= 0 && slot>=0 && slot<4) - script_pushint(st,sd->status.inventory[i].card[slot]); + script_pushint(st,sd->inventory.u.items_inventory[i].card[slot]); else script_pushint(st,0); return SCRIPT_CMD_SUCCESS; @@ -13253,20 +13317,20 @@ BUILDIN_FUNC(getinventorylist) if (!script_charid2sd(2,sd)) return SCRIPT_CMD_FAILURE; for(i=0;istatus.inventory[i].nameid > 0 && sd->status.inventory[i].amount > 0){ - pc_setreg(sd,reference_uid(add_str("@inventorylist_id"), j),sd->status.inventory[i].nameid); - pc_setreg(sd,reference_uid(add_str("@inventorylist_amount"), j),sd->status.inventory[i].amount); - pc_setreg(sd,reference_uid(add_str("@inventorylist_equip"), j),sd->status.inventory[i].equip); - pc_setreg(sd,reference_uid(add_str("@inventorylist_refine"), j),sd->status.inventory[i].refine); - pc_setreg(sd,reference_uid(add_str("@inventorylist_identify"), j),sd->status.inventory[i].identify); - pc_setreg(sd,reference_uid(add_str("@inventorylist_attribute"), j),sd->status.inventory[i].attribute); + if(sd->inventory.u.items_inventory[i].nameid > 0 && sd->inventory.u.items_inventory[i].amount > 0){ + pc_setreg(sd,reference_uid(add_str("@inventorylist_id"), j),sd->inventory.u.items_inventory[i].nameid); + pc_setreg(sd,reference_uid(add_str("@inventorylist_amount"), j),sd->inventory.u.items_inventory[i].amount); + pc_setreg(sd,reference_uid(add_str("@inventorylist_equip"), j),sd->inventory.u.items_inventory[i].equip); + pc_setreg(sd,reference_uid(add_str("@inventorylist_refine"), j),sd->inventory.u.items_inventory[i].refine); + pc_setreg(sd,reference_uid(add_str("@inventorylist_identify"), j),sd->inventory.u.items_inventory[i].identify); + pc_setreg(sd,reference_uid(add_str("@inventorylist_attribute"), j),sd->inventory.u.items_inventory[i].attribute); for (k = 0; k < MAX_SLOTS; k++) { sprintf(card_var, "@inventorylist_card%d",k+1); - pc_setreg(sd,reference_uid(add_str(card_var), j),sd->status.inventory[i].card[k]); + pc_setreg(sd,reference_uid(add_str(card_var), j),sd->inventory.u.items_inventory[i].card[k]); } - pc_setreg(sd,reference_uid(add_str("@inventorylist_expire"), j),sd->status.inventory[i].expire_time); - pc_setreg(sd,reference_uid(add_str("@inventorylist_bound"), j),sd->status.inventory[i].bound); + pc_setreg(sd,reference_uid(add_str("@inventorylist_expire"), j),sd->inventory.u.items_inventory[i].expire_time); + pc_setreg(sd,reference_uid(add_str("@inventorylist_bound"), j),sd->inventory.u.items_inventory[i].bound); j++; } } @@ -13308,8 +13372,8 @@ BUILDIN_FUNC(clearitem) return SCRIPT_CMD_FAILURE; for (i=0; istatus.inventory[i].amount) { - pc_delitem(sd, i, sd->status.inventory[i].amount, 0, 0, LOG_TYPE_SCRIPT); + if (sd->inventory.u.items_inventory[i].amount) { + pc_delitem(sd, i, sd->inventory.u.items_inventory[i].amount, 0, 0, LOG_TYPE_SCRIPT); } } return SCRIPT_CMD_SUCCESS; @@ -14127,7 +14191,7 @@ BUILDIN_FUNC(getmercinfo) if( script_hasdata(st,3) ) { - int char_id = script_getnum(st,3); + uint32 char_id = script_getnum(st,3); if( ( sd = map_charid2sd(char_id) ) == NULL ) { @@ -14186,11 +14250,11 @@ BUILDIN_FUNC(checkequipedcard) c=script_getnum(st,2); for(i=0;istatus.inventory[i].nameid > 0 && sd->status.inventory[i].amount && sd->inventory_data[i]){ - if (itemdb_isspecial(sd->status.inventory[i].card[0])) + if(sd->inventory.u.items_inventory[i].nameid > 0 && sd->inventory.u.items_inventory[i].amount && sd->inventory_data[i]){ + if (itemdb_isspecial(sd->inventory.u.items_inventory[i].card[0])) continue; for(n=0;ninventory_data[i]->slot;n++){ - if(sd->status.inventory[i].card[n]==c){ + if(sd->inventory.u.items_inventory[i].card[n] == c) { script_pushint(st,1); return SCRIPT_CMD_SUCCESS; } @@ -14687,13 +14751,13 @@ BUILDIN_FUNC(isequippedcnt) if (itemdb_type(id) != IT_CARD) { //No card. Count amount in inventory. if (sd->inventory_data[index]->nameid == id) - ret+= sd->status.inventory[index].amount; + ret+= sd->inventory.u.items_inventory[index].amount; } else { //Count cards. short k; - if (itemdb_isspecial(sd->status.inventory[index].card[0])) + if (itemdb_isspecial(sd->inventory.u.items_inventory[index].card[0])) continue; //No cards for(k=0; kinventory_data[index]->slot; k++) { - if (sd->status.inventory[index].card[k] == id) + if (sd->inventory.u.items_inventory[index].card[k] == id) ret++; //[Lupus] } } @@ -14751,13 +14815,13 @@ BUILDIN_FUNC(isequipped) } else { //Cards short k; if (sd->inventory_data[index]->slot == 0 || - itemdb_isspecial(sd->status.inventory[index].card[0])) + itemdb_isspecial(sd->inventory.u.items_inventory[index].card[0])) continue; for (k = 0; k < sd->inventory_data[index]->slot; k++) { //New hash system which should support up to 4 slots on any equipment. [Skotlex] unsigned int hash = 0; - if (sd->status.inventory[index].card[k] != id) + if (sd->inventory.u.items_inventory[index].card[k] != id) continue; hash = 1<<((j<5?j:j-5)*4 + k); @@ -14817,12 +14881,12 @@ BUILDIN_FUNC(cardscnt) if(itemdb_type(id) != IT_CARD) { if (sd->inventory_data[index]->nameid == id) - ret+= sd->status.inventory[index].amount; + ret+= sd->inventory.u.items_inventory[index].amount; } else { - if (itemdb_isspecial(sd->status.inventory[index].card[0])) + if (itemdb_isspecial(sd->inventory.u.items_inventory[index].card[0])) continue; for(k=0; kinventory_data[index]->slot; k++) { - if (sd->status.inventory[index].card[k] == id) + if (sd->inventory.u.items_inventory[index].card[k] == id) ret++; } } @@ -14840,7 +14904,7 @@ BUILDIN_FUNC(getrefine) { TBL_PC *sd; if ((sd = script_rid2sd(st))!= NULL) - script_pushint(st,sd->status.inventory[current_equip_item_index].refine); + script_pushint(st,sd->inventory.u.items_inventory[current_equip_item_index].refine); else script_pushint(st,0); return SCRIPT_CMD_SUCCESS; @@ -14900,7 +14964,7 @@ BUILDIN_FUNC(equip) { if ((item_data = itemdb_exists(nameid))) { int i; - ARR_FIND( 0, MAX_INVENTORY, i, sd->status.inventory[i].nameid == nameid ); + ARR_FIND( 0, MAX_INVENTORY, i, sd->inventory.u.items_inventory[i].nameid == nameid ); if (i < MAX_INVENTORY) { pc_equipitem(sd,i,item_data->equip); script_pushint(st,1); @@ -19998,13 +20062,13 @@ BUILDIN_FUNC(countbound) type = script_getnum(st,2); for( i = 0; i < MAX_INVENTORY; i ++ ) { - if( sd->status.inventory[i].nameid > 0 && ( - (!type && sd->status.inventory[i].bound) || (type && sd->status.inventory[i].bound == type) + if( sd->inventory.u.items_inventory[i].nameid > 0 && ( + (!type && sd->inventory.u.items_inventory[i].bound) || (type && sd->inventory.u.items_inventory[i].bound == type) )) { - pc_setreg(sd,reference_uid(add_str("@bound_items"), k),sd->status.inventory[i].nameid); + pc_setreg(sd,reference_uid(add_str("@bound_items"), k),sd->inventory.u.items_inventory[i].nameid); k++; - j += sd->status.inventory[i].amount; + j += sd->inventory.u.items_inventory[i].amount; } } @@ -20723,7 +20787,8 @@ BUILDIN_FUNC(mergeitem2) { } for (i = 0; i < MAX_INVENTORY; i++) { - struct item *it = &sd->status.inventory[i]; + struct item *it = &sd->inventory.u.items_inventory[i]; + if (!it || !it->unique_id || it->expire_time || !itemdb_isstackable(it->nameid)) continue; if ((!nameid || (nameid == it->nameid))) { @@ -21293,9 +21358,11 @@ struct script_function buildin_func[] = { BUILDIN_DEF(makeitem2,"visiiiiiiiii"), BUILDIN_DEF(delitem,"vi?"), BUILDIN_DEF2(delitem,"storagedelitem","vi?"), + BUILDIN_DEF2(delitem,"guildstoragedelitem","vi?"), BUILDIN_DEF2(delitem,"cartdelitem","vi?"), BUILDIN_DEF(delitem2,"viiiiiiii?"), BUILDIN_DEF2(delitem2,"storagedelitem2","viiiiiiii?"), + BUILDIN_DEF2(delitem2,"guildstoragedelitem2","viiiiiiii?"), BUILDIN_DEF2(delitem2,"cartdelitem2","viiiiiiii?"), BUILDIN_DEF2(enableitemuse,"enable_items",""), BUILDIN_DEF2(disableitemuse,"disable_items",""), @@ -21307,9 +21374,11 @@ struct script_function buildin_func[] = { BUILDIN_DEF(rand,"i?"), BUILDIN_DEF(countitem,"v?"), BUILDIN_DEF2(countitem,"storagecountitem","v?"), + BUILDIN_DEF2(countitem,"guildstoragecountitem","v?"), BUILDIN_DEF2(countitem,"cartcountitem","v?"), BUILDIN_DEF2(countitem,"countitem2","viiiiiii?"), BUILDIN_DEF2(countitem,"storagecountitem2","viiiiiii?"), + BUILDIN_DEF2(countitem,"guildstoragecountitem2","viiiiiii?"), BUILDIN_DEF2(countitem,"cartcountitem2","viiiiiii?"), BUILDIN_DEF(checkweight,"vi*"), BUILDIN_DEF(checkweight2,"rr"), diff --git a/src/map/skill.c b/src/map/skill.c index 03aa711b89..b26238b0c0 100755 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -2473,7 +2473,7 @@ int skill_break_equip(struct block_list *src, struct block_list *bl, unsigned sh if (sd) { for (i = 0; i < EQI_MAX; i++) { short j = sd->equip_index[i]; - if (j < 0 || sd->status.inventory[j].attribute == 1 || !sd->inventory_data[j]) + if (j < 0 || sd->inventory.u.items_inventory[j].attribute == 1 || !sd->inventory_data[j]) continue; switch(i) { @@ -2499,7 +2499,7 @@ int skill_break_equip(struct block_list *src, struct block_list *bl, unsigned sh continue; } if (flag) { - sd->status.inventory[j].attribute = 1; + sd->inventory.u.items_inventory[j].attribute = 1; pc_unequipitem(sd, j, 3); } } @@ -3809,7 +3809,7 @@ static int skill_check_condition_mercenary(struct block_list *bl, int skill, int index[i] = -1; if( itemid[i] < 1 ) continue; // No item index[i] = pc_search_inventory(sd, itemid[i]); - if( index[i] < 0 || sd->status.inventory[index[i]].amount < amount[i] ) + if( index[i] < 0 || sd->inventory.u.items_inventory[index[i]].amount < amount[i] ) { clif_skill_fail(sd, skill, USESKILL_FAIL_LEVEL, 0); return 0; @@ -7457,7 +7457,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui map_freeblock_unlock(); return 1; } - if (sd->inventory_data[j] == NULL || sd->status.inventory[j].amount < require.amount[x]) { + if (sd->inventory_data[j] == NULL || sd->inventory.u.items_inventory[j].amount < require.amount[x]) { clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); map_freeblock_unlock(); return 1; @@ -7597,7 +7597,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui int ebottle = pc_search_inventory(sd,ITEMID_EMPTY_BOTTLE); short alcohol_idx = -1, acid_idx = -1, fire_idx = -1; if( ebottle >= 0 ) - ebottle = sd->status.inventory[ebottle].amount; + ebottle = sd->inventory.u.items_inventory[ebottle].amount; //check if you can produce all three, if not, then fail: if (!(alcohol_idx = skill_can_produce_mix(sd,ITEMID_ALCOHOL,-1, 100)) //100 Alcohol || !(acid_idx = skill_can_produce_mix(sd,ITEMID_ACID_BOTTLE,-1, 50)) //50 Acid Bottle @@ -9607,7 +9607,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui else { shield_def = shield_data->def; shield_mdef = sd->bonus.shieldmdef; - shield_refine = sd->status.inventory[sd->equip_index[EQI_HAND_L]].refine; + shield_refine = sd->inventory.u.items_inventory[sd->equip_index[EQI_HAND_L]].refine; } if (flag&1) { sc_start(src,bl,SC_SILENCE,100,skill_lv,shield_mdef * 30000); @@ -11743,7 +11743,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui struct skill_condition require = skill_get_requirement(sd, skill_id, skill_lv); i_lv = skill_lv%11 - 1; j = pc_search_inventory(sd, require.itemid[i_lv]); - if (j < 0 || require.itemid[i_lv] <= 0 || sd->inventory_data[j] == NULL || sd->status.inventory[j].amount < require.amount[i_lv]) + if (j < 0 || require.itemid[i_lv] <= 0 || sd->inventory_data[j] == NULL || sd->inventory.u.items_inventory[j].amount < require.amount[i_lv]) { clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); return 1; @@ -14707,10 +14707,10 @@ bool skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_i else { // When a target was selected, consume items that were skipped in pc_use_item [Skotlex] if( (i = sd->itemindex) == -1 || - sd->status.inventory[i].nameid != sd->itemid || + sd->inventory.u.items_inventory[i].nameid != sd->itemid || sd->inventory_data[i] == NULL || !sd->inventory_data[i]->flag.delay_consume || - sd->status.inventory[i].amount < 1 + sd->inventory.u.items_inventory[i].amount < 1 ) { //Something went wrong, item exploit? sd->itemid = sd->itemindex = -1; @@ -14720,7 +14720,7 @@ bool skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_i sd->itemid = sd->itemindex = -1; if( skill_id == WZ_EARTHSPIKE && sc && sc->data[SC_EARTHSCROLL] && rnd()%100 > sc->data[SC_EARTHSCROLL]->val2 ) // [marquis007] ; //Do not consume item. - else if( sd->status.inventory[i].expire_time == 0 ) + else if( sd->inventory.u.items_inventory[i].expire_time == 0 ) pc_delitem(sd,i,1,0,0,LOG_TYPE_CONSUME); // Rental usable items are not consumed until expiration } return true; @@ -15101,8 +15101,8 @@ bool skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_i int count = 0; for( i = 0; i < MAX_INVENTORY; i++ ) - if( sd->status.inventory[i].nameid == ITEMID_ANCILLA ) - count += sd->status.inventory[i].amount; + if( sd->inventory.u.items_inventory[i].nameid == ITEMID_ANCILLA ) + count += sd->inventory.u.items_inventory[i].amount; if( count >= 3 ) { clif_skill_fail(sd, skill_id, USESKILL_FAIL_ANCILLA_NUMOVER, 0); return false; @@ -15126,7 +15126,7 @@ bool skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_i case WL_COMET: if( skill_check_pc_partner(sd,skill_id,&skill_lv,1,0) <= 0 && require.itemid[0] && sd->special_state.no_gemstone == 0 - && ((i = pc_search_inventory(sd,require.itemid[0])) < 0 || sd->status.inventory[i].amount < require.amount[0]) ) { + && ((i = pc_search_inventory(sd,require.itemid[0])) < 0 || sd->inventory.u.items_inventory[i].amount < require.amount[0]) ) { //clif_skill_fail(sd,skill_id,USESKILL_FAIL_NEED_ITEM,require.amount[0],require.itemid[0]); clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); return false; @@ -15647,7 +15647,7 @@ bool skill_check_condition_castend(struct map_session_data* sd, uint16 skill_id, if((i=sd->equip_index[EQI_AMMO]) < 0 || !sd->inventory_data[i] ) { clif_arrow_fail(sd,0); return false; - } else if( sd->status.inventory[i].amount < require.ammo_qty ) { + } else if( sd->inventory.u.items_inventory[i].amount < require.ammo_qty ) { char e_msg[100]; if (require.ammo&(1<status.inventory[i].nameid)); + itemdb_jname(sd->inventory.u.items_inventory[i].nameid)); clif_colormes(sd->fd,color_table[COLOR_RED],e_msg); return false; } @@ -15676,7 +15676,7 @@ bool skill_check_condition_castend(struct map_session_data* sd, uint16 skill_id, if( !require.itemid[i] ) continue; index[i] = pc_search_inventory(sd,require.itemid[i]); - if( index[i] < 0 || sd->status.inventory[index[i]].amount < require.amount[i] ) { + if( index[i] < 0 || sd->inventory.u.items_inventory[index[i]].amount < require.amount[i] ) { if( require.itemid[i] == ITEMID_HOLY_WATER ) clif_skill_fail(sd,skill_id,USESKILL_FAIL_HOLYWATER,0); //Holy water is required. else if( require.itemid[i] == ITEMID_RED_GEMSTONE ) @@ -15968,7 +15968,7 @@ struct skill_condition skill_get_requirement(struct map_session_data* sd, uint16 if ((skill_id >= HT_SKIDTRAP && skill_id <= HT_TALKIEBOX && pc_checkskill(sd, RA_RESEARCHTRAP) > 0) || skill_id == SC_ESCAPE) { int16 itIndex; - if ((itIndex = pc_search_inventory(sd,req.itemid[i])) < 0 || ( itIndex >= 0 && sd->status.inventory[itIndex].amount < req.amount[i])) { + if ((itIndex = pc_search_inventory(sd,req.itemid[i])) < 0 || ( itIndex >= 0 && sd->inventory.u.items_inventory[itIndex].amount < req.amount[i])) { if (skill_id == SC_ESCAPE) // Alloy Trap has priority over normal Trap req.itemid[i] = ITEMID_TRAP; else @@ -16459,7 +16459,7 @@ void skill_repairweapon(struct map_session_data *sd, int idx) { if( idx < 0 || idx >= MAX_INVENTORY ) return; //Invalid index?? - item = &target_sd->status.inventory[idx]; + item = &target_sd->inventory.u.items_inventory[idx]; if( !item->nameid || !item->attribute ) return; //Again invalid item.... @@ -16501,9 +16501,9 @@ void skill_identify(struct map_session_data *sd, int idx) nullpo_retv(sd); if(idx >= 0 && idx < MAX_INVENTORY) { - if(sd->status.inventory[idx].nameid > 0 && sd->status.inventory[idx].identify == 0 ){ + if(sd->inventory.u.items_inventory[idx].nameid > 0 && sd->inventory.u.items_inventory[idx].identify == 0 ){ flag=0; - sd->status.inventory[idx].identify=1; + sd->inventory.u.items_inventory[idx].identify = 1; } } clif_item_identified(sd,idx,flag); @@ -16520,7 +16520,7 @@ void skill_weaponrefine(struct map_session_data *sd, int idx) { struct item *item; struct item_data *ditem = sd->inventory_data[idx]; - item = &sd->status.inventory[idx]; + item = &sd->inventory.u.items_inventory[idx]; if(item->nameid > 0 && ditem->type == IT_WEAPON) { int i = 0, per; @@ -18606,8 +18606,8 @@ short skill_can_produce_mix(struct map_session_data *sd, unsigned short nameid, unsigned short idx, amt; for (idx = 0, amt = 0; idx < MAX_INVENTORY; idx++) - if (sd->status.inventory[idx].nameid == nameid_produce) - amt += sd->status.inventory[idx].amount; + if (sd->inventory.u.items_inventory[idx].nameid == nameid_produce) + amt += sd->inventory.u.items_inventory[idx].amount; if (amt < qty * skill_produce_db[i].mat_amount[j]) return 0; } @@ -18692,14 +18692,14 @@ bool skill_produce_mix(struct map_session_data *sd, uint16 skill_id, unsigned sh if (data->stack.inventory) { for (i = 0; i < MAX_INVENTORY; i++) { - if (sd->status.inventory[i].nameid == nameid) { - if (sd->status.inventory[i].amount >= data->stack.amount) { + if (sd->inventory.u.items_inventory[i].nameid == nameid) { + if (sd->inventory.u.items_inventory[i].amount >= data->stack.amount) { clif_msg(sd,RUNE_CANT_CREATE); return 0; } else { // The amount fits, say we got temp_qty 4 and 19 runes, we trim temp_qty to 1. - if (temp_qty + sd->status.inventory[i].amount >= data->stack.amount) - temp_qty = data->stack.amount - sd->status.inventory[i].amount; + if (temp_qty + sd->inventory.u.items_inventory[i].amount >= data->stack.amount) + temp_qty = data->stack.amount - sd->inventory.u.items_inventory[i].amount; } break; } @@ -18721,7 +18721,7 @@ bool skill_produce_mix(struct map_session_data *sd, uint16 skill_id, unsigned sh j = pc_search_inventory(sd,id); if (j >= 0) { - y = sd->status.inventory[j].amount; + y = sd->inventory.u.items_inventory[j].amount; if (y > x) y = x; pc_delitem(sd,j,y,0,0,LOG_TYPE_PRODUCE); @@ -19508,7 +19508,7 @@ int skill_elementalanalysis(struct map_session_data* sd, int n, uint16 skill_lv, del_amount -= (del_amount % 10); add_amount = (skill_lv == 1) ? del_amount * (5 + rnd()%5) : del_amount / 10 ; - if( (nameid = sd->status.inventory[idx].nameid) <= 0 || del_amount > sd->status.inventory[idx].amount ) { + if( (nameid = sd->inventory.u.items_inventory[idx].nameid) <= 0 || del_amount > sd->inventory.u.items_inventory[idx].amount ) { clif_skill_fail(sd,SO_EL_ANALYSIS,USESKILL_FAIL_LEVEL,0); return 1; } @@ -19575,9 +19575,9 @@ int skill_changematerial(struct map_session_data *sd, int n, unsigned short *ite if( skill_produce_db[i].mat_id[j] > 0 ) { for( k = 0; k < n; k++ ) { int idx = item_list[k*2+0]-2; - nameid = sd->status.inventory[idx].nameid; + nameid = sd->inventory.u.items_inventory[idx].nameid; amount = item_list[k*2+1]; - if( nameid > 0 && sd->status.inventory[idx].identify == 0 ){ + if( nameid > 0 && sd->inventory.u.items_inventory[idx].identify == 0 ){ clif_msg_skill(sd,GN_CHANGEMATERIAL,ITEM_UNIDENTIFIED); return 0; } diff --git a/src/map/status.c b/src/map/status.c index f151b513d6..904aab60b7 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -3010,6 +3010,101 @@ static unsigned int status_calc_maxhpsp_pc(struct map_session_data* sd, unsigned return cap_value((unsigned int)dmax,1,UINT_MAX); } +/** + * Calculates player's weight + * @param sd: Player object + * @param flag: Calculation type + * 1 - Item weight + * 2 - Skill/Status/Configuration max weight bonus + * @return false - failed, true - success + */ +bool status_calc_weight(struct map_session_data *sd, uint8 flag) +{ + int b_weight, b_max_weight, skill, i; + struct status_change *sc; + + nullpo_retr(false, sd); + + sc = &sd->sc; + b_max_weight = sd->max_weight; // Store max weight for later comparison + b_weight = sd->weight; // Store current weight for later comparison + sd->max_weight = job_info[pc_class2idx(sd->status.class_)].max_weight_base + sd->status.str * 300; // Recalculate max weight + + if (flag&1) { + sd->weight = 0; // Reset current weight + + for(i = 0; i < MAX_INVENTORY; i++) { + if (!sd->inventory.u.items_inventory[i].nameid || sd->inventory_data[i] == NULL) + continue; + sd->weight += sd->inventory_data[i]->weight * sd->inventory.u.items_inventory[i].amount; + } + } + + if (flag&2) { + // Skill/Status bonus weight increases + if ((skill = pc_checkskill(sd, MC_INCCARRY)) > 0) + sd->max_weight += 2000 * skill; + if (pc_isriding(sd) && pc_checkskill(sd, KN_RIDING) > 0) + sd->max_weight += 10000; + else if (pc_isridingdragon(sd)) + sd->max_weight += 5000 + 2000 * pc_checkskill(sd, RK_DRAGONTRAINING); + if (sc->data[SC_KNOWLEDGE]) + sd->max_weight += sd->max_weight * sc->data[SC_KNOWLEDGE]->val1 / 10; + if ((skill = pc_checkskill(sd, ALL_INCCARRY)) > 0) + sd->max_weight += 2000 * skill; + } + + // Update the client if the new weight calculations don't match + if (b_weight != sd->weight) + clif_updatestatus(sd, SP_WEIGHT); + if (b_max_weight != sd->max_weight) { + clif_updatestatus(sd, SP_MAXWEIGHT); + pc_updateweightstatus(sd); + } + + return true; +} + +/** + * Calculates player's cart weight + * @param sd: Player object + * @return false - failed, true - success + */ +bool status_calc_cart_weight(struct map_session_data *sd, uint8 flag) +{ + int b_cart_weight_max, i; + + nullpo_retr(false, sd); + + if (!pc_iscarton(sd)) + return false; + + b_cart_weight_max = sd->cart_weight_max; // Store cart max weight for later comparison + sd->cart_weight_max = battle_config.max_cart_weight; // Recalculate max weight + + if (flag&1) { + sd->cart_weight = 0; // Reset current cart weight + sd->cart_num = 0; // Reset current cart item count + + for(i = 0; i < MAX_CART; i++) { + if (!sd->cart.u.items_cart[i].nameid) + continue; + sd->cart_weight += itemdb_weight(sd->cart.u.items_cart[i].nameid) * sd->cart.u.items_cart[i].amount; // Recalculate current cart weight + sd->cart_num++; // Recalculate current cart item count + } + } + + // Skill bonus max weight increases + if (flag&2) + sd->cart_weight_max += (pc_checkskill(sd, GN_REMODELING_CART) * 5000); + + // Update the client if the new weight calculations don't match + if (b_cart_weight_max != sd->cart_weight_max) + clif_updatestatus(sd, SP_CARTINFO); + + return true; +} + /** * Calculates player data from scratch without counting SC adjustments * Should be invoked whenever players raise stats, learn passive skills or change equipment @@ -3023,8 +3118,7 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) struct status_data *base_status; ///< Pointer to the player's base status const struct status_change *sc = &sd->sc; struct s_skill b_skill[MAX_SKILL]; ///< Previous skill tree - int b_weight, b_max_weight, b_cart_weight_max, ///< Previous weight - i, skill,refinedef=0; + int i, skill, refinedef = 0; short index = -1; if (++calculating > 10) // Too many recursive calls! @@ -3032,34 +3126,18 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) // Remember player-specific values that are currently being shown to the client (for refresh purposes) memcpy(b_skill, &sd->status.skill, sizeof(b_skill)); - b_weight = sd->weight; - b_max_weight = sd->max_weight; - b_cart_weight_max = sd->cart_weight_max; pc_calc_skilltree(sd); // SkillTree calculation - sd->max_weight = job_info[pc_class2idx(sd->status.class_)].max_weight_base+sd->status.str*300; - if (opt&SCO_FIRST) { // Load Hp/SP from char-received data. sd->battle_status.hp = sd->status.hp; sd->battle_status.sp = sd->status.sp; sd->regen.sregen = &sd->sregen; sd->regen.ssregen = &sd->ssregen; - sd->weight=0; - for(i=0;istatus.inventory[i].nameid==0 || sd->inventory_data[i] == NULL) - continue; - sd->weight += sd->inventory_data[i]->weight*sd->status.inventory[i].amount; - } - sd->cart_weight=0; - sd->cart_num=0; - for(i=0;istatus.cart[i].nameid==0) - continue; - sd->cart_weight+=itemdb_weight(sd->status.cart[i].nameid)*sd->status.cart[i].amount; - sd->cart_num++; - } + + status_calc_weight(sd, 1); + status_calc_cart_weight(sd, 1); } base_status = &sd->base_status; @@ -3221,17 +3299,17 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) } // Sanitize the refine level in case someone decreased the value inbetween - if (sd->status.inventory[index].refine > MAX_REFINE) - sd->status.inventory[index].refine = MAX_REFINE; + if (sd->inventory.u.items_inventory[index].refine > MAX_REFINE) + sd->inventory.u.items_inventory[index].refine = MAX_REFINE; if (sd->inventory_data[index]->type == IT_WEAPON) { - int r = sd->status.inventory[index].refine, wlv = sd->inventory_data[index]->wlv; + int r = sd->inventory.u.items_inventory[index].refine, wlv = sd->inventory_data[index]->wlv; struct weapon_data *wd; struct weapon_atk *wa; if(wlv >= REFINE_TYPE_MAX) wlv = REFINE_TYPE_MAX - 1; - if(i == EQI_HAND_L && sd->status.inventory[index].equip == EQP_HAND_L) { + if(i == EQI_HAND_L && sd->inventory.u.items_inventory[index].equip == EQP_HAND_L) { wd = &sd->left_weapon; // Left-hand weapon wa = &base_status->lhw; } else { @@ -3260,18 +3338,18 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) if (!calculating) // Abort, run_script retriggered this. [Skotlex] return 1; } - if(sd->status.inventory[index].card[0]==CARD0_FORGE) { // Forged weapon - wd->star += (sd->status.inventory[index].card[1]>>8); + if(sd->inventory.u.items_inventory[index].card[0] == CARD0_FORGE) { // Forged weapon + wd->star += (sd->inventory.u.items_inventory[index].card[1]>>8); if(wd->star >= 15) wd->star = 40; // 3 Star Crumbs now give +40 dmg - if(pc_famerank(MakeDWord(sd->status.inventory[index].card[2],sd->status.inventory[index].card[3]) ,MAPID_BLACKSMITH)) + if(pc_famerank(MakeDWord(sd->inventory.u.items_inventory[index].card[2],sd->inventory.u.items_inventory[index].card[3]) ,MAPID_BLACKSMITH)) wd->star += 10; if (!wa->ele) // Do not overwrite element from previous bonuses. - wa->ele = (sd->status.inventory[index].card[1]&0x0f); + wa->ele = (sd->inventory.u.items_inventory[index].card[1]&0x0f); } } else if(sd->inventory_data[index]->type == IT_ARMOR) { int r; - if ( (r = sd->status.inventory[index].refine) ) + if ( (r = sd->inventory.u.items_inventory[index].refine) ) refinedef += refine_info[REFINE_TYPE_ARMOR].bonus[r-1]; if(sd->inventory_data[index]->script && (pc_has_permission(sd,PC_PERM_USE_ALL_EQUIPMENT) || !itemdb_isNoEquip(sd->inventory_data[index],sd->bl.m))) { if( i == EQI_HAND_L ) // Shield @@ -3356,10 +3434,10 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) struct item_data *data; // Card script execution. - if (itemdb_isspecial(sd->status.inventory[index].card[0])) + if (itemdb_isspecial(sd->inventory.u.items_inventory[index].card[0])) continue; for (j = 0; j < MAX_SLOTS; j++) { // Uses MAX_SLOTS to support Soul Bound system [Inkfish] - int c = sd->status.inventory[index].card[j]; + int c = sd->inventory.u.items_inventory[index].card[j]; current_equip_card_id= c; if(!c) continue; @@ -3375,7 +3453,7 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) continue; if(!pc_has_permission(sd,PC_PERM_USE_ALL_EQUIPMENT) && itemdb_isNoEquip(data,sd->bl.m)) // Card restriction checks. continue; - if(i == EQI_HAND_L && sd->status.inventory[index].equip == EQP_HAND_L) { // Left hand status. + if(i == EQI_HAND_L && sd->inventory.u.items_inventory[index].equip == EQP_HAND_L) { // Left hand status. sd->state.lr_flag = 1; run_script(data->script,0,sd->bl.id,0); sd->state.lr_flag = 0; @@ -3702,18 +3780,8 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) // ----- MISC CALCULATIONS ----- // Weight - if((skill=pc_checkskill(sd,MC_INCCARRY))>0) - sd->max_weight += 2000*skill; - if(pc_isriding(sd) && pc_checkskill(sd,KN_RIDING)>0) - sd->max_weight += 10000; - else if(pc_isridingdragon(sd)) - sd->max_weight += 5000+2000*pc_checkskill(sd,RK_DRAGONTRAINING); - if(sc->data[SC_KNOWLEDGE]) - sd->max_weight += sd->max_weight*sc->data[SC_KNOWLEDGE]->val1/10; - if((skill=pc_checkskill(sd,ALL_INCCARRY))>0) - sd->max_weight += 2000*skill; - - sd->cart_weight_max = battle_config.max_cart_weight + (pc_checkskill(sd, GN_REMODELING_CART)*5000); + status_calc_weight(sd, 2); + status_calc_cart_weight(sd, 2); if (pc_checkskill(sd,SM_MOVINGRECOVERY)>0) sd->regen.state.walk = 1; @@ -3847,15 +3915,6 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) } if(memcmp(b_skill,sd->status.skill,sizeof(sd->status.skill))) clif_skillinfoblock(sd); - if(b_weight != sd->weight) - clif_updatestatus(sd,SP_WEIGHT); - if(b_max_weight != sd->max_weight) { - clif_updatestatus(sd,SP_MAXWEIGHT); - pc_updateweightstatus(sd); - } - if( b_cart_weight_max != sd->cart_weight_max ) { - clif_updatestatus(sd,SP_CARTINFO); - } // If the skill is learned, the status is infinite. if( (skill = pc_checkskill(sd,SU_SPRITEMABLE)) > 0 ) diff --git a/src/map/status.h b/src/map/status.h index 0eab96e77a..795c187038 100644 --- a/src/map/status.h +++ b/src/map/status.h @@ -2208,6 +2208,8 @@ void status_change_clear_onChangeMap(struct block_list *bl, struct status_change #define status_calc_elemental(ed, opt) status_calc_bl_(&(ed)->bl, SCB_ALL, opt) #define status_calc_npc(nd, opt) status_calc_bl_(&(nd)->bl, SCB_ALL, opt) +bool status_calc_weight(struct map_session_data *sd, uint8 flag); +bool status_calc_cart_weight(struct map_session_data *sd, uint8 flag); void status_calc_bl_(struct block_list *bl, enum scb_flag flag, enum e_status_calc_opt opt); int status_calc_mob_(struct mob_data* md, enum e_status_calc_opt opt); void status_calc_pet_(struct pet_data* pd, enum e_status_calc_opt opt); diff --git a/src/map/storage.c b/src/map/storage.c index 4de0303222..e8a588bf9c 100644 --- a/src/map/storage.c +++ b/src/map/storage.c @@ -84,10 +84,10 @@ void do_final_storage(void) */ static int storage_reconnect_sub(DBKey key, DBData *data, va_list ap) { - struct guild_storage *stor = (struct guild_storage *)db_data2ptr(data); + struct s_storage *stor = db_data2ptr(data); - if (stor->dirty && stor->opened == 0) //Save closed storages. - gstorage_storagesave(0, stor->guild_id,0); + if (stor->dirty && stor->status == 0) //Save closed storages. + storage_guild_storagesave(0, stor->id, 0); return 0; } @@ -119,9 +119,9 @@ int storage_storageopen(struct map_session_data *sd) } sd->state.storage_flag = 1; - storage_sortitem(sd->status.storage.items, ARRAYLENGTH(sd->status.storage.items)); - clif_storagelist(sd, sd->status.storage.items, ARRAYLENGTH(sd->status.storage.items)); - clif_updatestorageamount(sd, sd->status.storage.storage_amount, sd->storage_size); + storage_sortitem(sd->storage.u.items_storage, ARRAYLENGTH(sd->storage.u.items_storage)); + clif_storagelist(sd, sd->storage.u.items_storage, ARRAYLENGTH(sd->storage.u.items_storage)); + clif_updatestorageamount(sd, sd->storage.amount, sd->storage_size); return 0; } @@ -162,7 +162,7 @@ int compare_item(struct item *a, struct item *b) */ static int storage_additem(struct map_session_data* sd, struct item* item_data, int amount) { - struct storage_data* stor = &sd->status.storage; + struct s_storage* stor = &sd->storage; struct item_data *data; int i; @@ -186,12 +186,12 @@ static int storage_additem(struct map_session_data* sd, struct item* item_data, if( itemdb_isstackable2(data) ) { // Stackable for( i = 0; i < sd->storage_size; i++ ) { - if( compare_item(&stor->items[i], item_data) ) { // existing items found, stack them - if( amount > MAX_AMOUNT - stor->items[i].amount || ( data->stack.storage && amount > data->stack.amount - stor->items[i].amount ) ) + if( compare_item(&stor->u.items_storage[i], item_data) ) { // existing items found, stack them + if( amount > MAX_AMOUNT - stor->u.items_storage[i].amount || ( data->stack.storage && amount > data->stack.amount - stor->u.items_storage[i].amount ) ) return 1; - stor->items[i].amount += amount; - clif_storageitemadded(sd,&stor->items[i],i,amount); + stor->u.items_storage[i].amount += amount; + clif_storageitemadded(sd,&stor->u.items_storage[i],i,amount); return 0; } @@ -199,16 +199,16 @@ static int storage_additem(struct map_session_data* sd, struct item* item_data, } // find free slot - ARR_FIND( 0, sd->storage_size, i, stor->items[i].nameid == 0 ); + ARR_FIND( 0, sd->storage_size, i, stor->u.items_storage[i].nameid == 0 ); if( i >= sd->storage_size ) return 1; // add item to slot - memcpy(&stor->items[i],item_data,sizeof(stor->items[0])); - stor->storage_amount++; - stor->items[i].amount = amount; - clif_storageitemadded(sd,&stor->items[i],i,amount); - clif_updatestorageamount(sd, stor->storage_amount, sd->storage_size); + memcpy(&stor->u.items_storage[i],item_data,sizeof(stor->u.items_storage[0])); + stor->amount++; + stor->u.items_storage[i].amount = amount; + clif_storageitemadded(sd,&stor->u.items_storage[i],i,amount); + clif_updatestorageamount(sd, stor->amount, sd->storage_size); return 0; } @@ -222,17 +222,16 @@ static int storage_additem(struct map_session_data* sd, struct item* item_data, */ int storage_delitem(struct map_session_data* sd, int n, int amount) { - if( sd->status.storage.items[n].nameid == 0 || sd->status.storage.items[n].amount < amount ) + if( sd->storage.u.items_storage[n].nameid == 0 || sd->storage.u.items_storage[n].amount < amount ) return 1; - sd->status.storage.items[n].amount -= amount; - - if( sd->status.storage.items[n].amount == 0 ) { - memset(&sd->status.storage.items[n],0,sizeof(sd->status.storage.items[0])); - sd->status.storage.storage_amount--; + sd->storage.u.items_storage[n].amount -= amount; + if( sd->storage.u.items_storage[n].amount == 0 ) { + memset(&sd->storage.u.items_storage[n],0,sizeof(sd->storage.u.items_storage[0])); + sd->storage.amount--; if( sd->state.storage_flag == 1 ) - clif_updatestorageamount(sd, sd->status.storage.storage_amount, sd->storage_size); + clif_updatestorageamount(sd, sd->storage.amount, sd->storage_size); } if( sd->state.storage_flag == 1 ) @@ -252,19 +251,19 @@ void storage_storageadd(struct map_session_data* sd, int index, int amount) { nullpo_retv(sd); - if( sd->status.storage.storage_amount > sd->storage_size ) + if( sd->storage.amount > sd->storage_size ) return; // storage full if( index < 0 || index >= MAX_INVENTORY ) return; - if( sd->status.inventory[index].nameid <= 0 ) + if( sd->inventory.u.items_inventory[index].nameid <= 0 ) return; // No item on that spot - if( amount < 1 || amount > sd->status.inventory[index].amount ) + if( amount < 1 || amount > sd->inventory.u.items_inventory[index].amount ) return; - if( storage_additem(sd,&sd->status.inventory[index],amount) == 0 ) + if( storage_additem(sd,&sd->inventory.u.items_inventory[index],amount) == 0 ) pc_delitem(sd,index,amount,0,4,LOG_TYPE_STORAGE); else { clif_storageitemremoved(sd,index,0); @@ -286,13 +285,13 @@ void storage_storageget(struct map_session_data* sd, int index, int amount) if( index < 0 || index >= sd->storage_size ) return; - if( sd->status.storage.items[index].nameid <= 0 ) + if( sd->storage.u.items_storage[index].nameid <= 0 ) return; //Nothing there - if( amount < 1 || amount > sd->status.storage.items[index].amount ) + if( amount < 1 || amount > sd->storage.u.items_storage[index].amount ) return; - if( (flag = pc_additem(sd,&sd->status.storage.items[index],amount,LOG_TYPE_STORAGE)) == 0 ) + if( (flag = pc_additem(sd,&sd->storage.u.items_storage[index],amount,LOG_TYPE_STORAGE)) == 0 ) storage_delitem(sd,index,amount); else { clif_storageitemremoved(sd,index,0); @@ -311,19 +310,19 @@ void storage_storageaddfromcart(struct map_session_data* sd, int index, int amou { nullpo_retv(sd); - if( sd->status.storage.storage_amount > sd->storage_size ) + if( sd->storage.amount > sd->storage_size ) return; // storage full / storage closed if( index < 0 || index >= MAX_CART ) return; - if( sd->status.cart[index].nameid <= 0 ) + if( sd->cart.u.items_cart[index].nameid <= 0 ) return; //No item there. - if( amount < 1 || amount > sd->status.cart[index].amount ) + if( amount < 1 || amount > sd->cart.u.items_cart[index].amount ) return; - if( storage_additem(sd,&sd->status.cart[index],amount) == 0 ) + if( storage_additem(sd,&sd->cart.u.items_cart[index],amount) == 0 ) pc_cart_delitem(sd,index,amount,0,LOG_TYPE_STORAGE); else { clif_storageitemremoved(sd,index,0); @@ -347,13 +346,13 @@ void storage_storagegettocart(struct map_session_data* sd, int index, int amount if( index < 0 || index >= sd->storage_size ) return; - if( sd->status.storage.items[index].nameid <= 0 ) + if( sd->storage.u.items_storage[index].nameid <= 0 ) return; //Nothing there. - if( amount < 1 || amount > sd->status.storage.items[index].amount ) + if( amount < 1 || amount > sd->storage.u.items_storage[index].amount ) return; - if( (flag = pc_cart_additem(sd,&sd->status.storage.items[index],amount,LOG_TYPE_STORAGE)) == 0 ) + if( (flag = pc_cart_additem(sd,&sd->storage.u.items_storage[index],amount,LOG_TYPE_STORAGE)) == 0 ) storage_delitem(sd,index,amount); else { clif_storageitemremoved(sd,index,0); @@ -373,15 +372,15 @@ void storage_storageclose(struct map_session_data* sd) clif_storageclose(sd); - if( save_settings&4 ) - chrif_save(sd,0); //Invokes the storage saving as well. + if (save_settings&CHARSAVE_STORAGE) + chrif_save(sd,0); sd->state.storage_flag = 0; } /** * Force closing the storage for player without displaying result - * (exemple when quitting the game) + * (example when quitting the game) * @param sd : player to close storage * @param flag : * 1: Character is quitting @@ -391,8 +390,8 @@ void storage_storage_quit(struct map_session_data* sd, int flag) { nullpo_retv(sd); - if (save_settings&4) - chrif_save(sd, flag); //Invokes the storage saving as well. + if (save_settings&CHARSAVE_STORAGE) + chrif_save(sd,0); sd->state.storage_flag = 0; } @@ -406,10 +405,11 @@ void storage_storage_quit(struct map_session_data* sd, int flag) */ static DBData create_guildstorage(DBKey key, va_list args) { - struct guild_storage *gs = NULL; + struct s_storage *gs = NULL; - gs = (struct guild_storage *) aCalloc(sizeof(struct guild_storage), 1); - gs->guild_id=key.i; + gs = (struct s_storage *) aCalloc(sizeof(struct s_storage), 1); + gs->type = TABLE_GUILD_STORAGE; + gs->id = key.i; return db_ptr2data(gs); } @@ -418,27 +418,27 @@ static DBData create_guildstorage(DBKey key, va_list args) * Retrieve the guild_storage of a guild * will create a new storage if none found for the guild * @param guild_id : id of the guild - * @return guild_storage + * @return s_storage */ -struct guild_storage *gstorage_guild2storage(int guild_id) +struct s_storage *guild2storage(int guild_id) { - struct guild_storage *gs = NULL; + struct s_storage *gs = NULL; if (guild_search(guild_id) != NULL) - gs = (struct guild_storage *)idb_ensure(guild_storage_db,guild_id,create_guildstorage); + gs = (struct s_storage *)idb_ensure(guild_storage_db,guild_id,create_guildstorage); return gs; } /** - * See if the guild_storage exist in db and fetch it if it,s the case + * See if the guild_storage exist in db and fetch it if it's the case * @author : [Skotlex] * @param guild_id : guild_id to search the storage - * @return guild_storage or NULL + * @return s_storage or NULL */ -struct guild_storage *gstorage_get_storage(int guild_id) +struct s_storage *guild2storage2(int guild_id) { - return (struct guild_storage*)idb_get(guild_storage_db,guild_id); + return (struct s_storage*)idb_get(guild_storage_db,guild_id); } /** @@ -446,7 +446,7 @@ struct guild_storage *gstorage_get_storage(int guild_id) * @param guild_id : guild to remove the storage from * @return 0 */ -void gstorage_delete(int guild_id) +void storage_guild_delete(int guild_id) { idb_remove(guild_storage_db,guild_id); } @@ -456,9 +456,9 @@ void gstorage_delete(int guild_id) * @param sd : player * @return 0 : success, 1 : fail, 2 : no guild found */ -char gstorage_storageopen(struct map_session_data* sd) +char storage_guild_storageopen(struct map_session_data* sd) { - struct guild_storage *gstor; + struct s_storage *gstor; nullpo_ret(sd); @@ -473,22 +473,22 @@ char gstorage_storageopen(struct map_session_data* sd) return 1; } - if((gstor = gstorage_get_storage(sd->status.guild_id)) == NULL) { + if((gstor = guild2storage2(sd->status.guild_id)) == NULL) { intif_request_guild_storage(sd->status.account_id,sd->status.guild_id); return 0; } - if(gstor->opened) + if(gstor->status) return 1; - if( gstor->locked ) + if( gstor->lock ) return 1; - gstor->opened = sd->status.char_id; + gstor->status = true; sd->state.storage_flag = 2; - storage_sortitem(gstor->items, ARRAYLENGTH(gstor->items)); - clif_storagelist(sd, gstor->items, ARRAYLENGTH(gstor->items)); - clif_updatestorageamount(sd, gstor->storage_amount, MAX_GUILD_STORAGE); + storage_sortitem(gstor->u.items_guild, ARRAYLENGTH(gstor->u.items_guild)); + clif_storagelist(sd, gstor->u.items_guild, ARRAYLENGTH(gstor->u.items_guild)); + clif_updatestorageamount(sd, gstor->amount, MAX_GUILD_STORAGE); return 0; } @@ -501,41 +501,41 @@ char gstorage_storageopen(struct map_session_data* sd) * @param amount : number of item to add * @return True : success, False : fail */ -bool gstorage_additem(struct map_session_data* sd, struct guild_storage* stor, struct item* item, int amount) +bool storage_guild_additem(struct map_session_data* sd, struct s_storage* stor, struct item* item_data, int amount) { struct item_data *id; int i; nullpo_ret(sd); nullpo_ret(stor); - nullpo_ret(item); + nullpo_ret(item_data); - if(item->nameid == 0 || amount <= 0) + if(item_data->nameid == 0 || amount <= 0) return false; - id = itemdb_search(item->nameid); + id = itemdb_search(item_data->nameid); if( id->stack.guildstorage && amount > id->stack.amount ) // item stack limitation return false; - if( !itemdb_canguildstore(item, pc_get_group_level(sd)) || item->expire_time ) { // Check if item is storable. [Skotlex] + if (!itemdb_canguildstore(item_data, pc_get_group_level(sd)) || item_data->expire_time) { // Check if item is storable. [Skotlex] clif_displaymessage (sd->fd, msg_txt(sd,264)); return false; } - if( (item->bound == BOUND_ACCOUNT || item->bound > BOUND_GUILD) && !pc_can_give_bounded_items(sd) ) { + if ((item_data->bound == BOUND_ACCOUNT || item_data->bound > BOUND_GUILD) && !pc_can_give_bounded_items(sd)) { clif_displaymessage(sd->fd, msg_txt(sd,294)); return false; } if(itemdb_isstackable2(id)) { //Stackable - for(i = 0; i < MAX_GUILD_STORAGE; i++){ - if(compare_item(&stor->items[i], item)) { - if( amount > MAX_AMOUNT - stor->items[i].amount || ( id->stack.guildstorage && amount > id->stack.amount - stor->items[i].amount ) ) + for(i = 0; i < MAX_GUILD_STORAGE; i++) { + if(compare_item(&stor->u.items_guild[i], item_data)) { + if( amount > MAX_AMOUNT - stor->u.items_guild[i].amount || ( id->stack.guildstorage && amount > id->stack.amount - stor->u.items_guild[i].amount ) ) return false; - - stor->items[i].amount+=amount; - clif_storageitemadded(sd,&stor->items[i],i,amount); + + stor->u.items_guild[i].amount += amount; + clif_storageitemadded(sd,&stor->u.items_guild[i],i,amount); stor->dirty = true; return true; } @@ -543,15 +543,15 @@ bool gstorage_additem(struct map_session_data* sd, struct guild_storage* stor, s } //Add item - for(i = 0; i < MAX_GUILD_STORAGE && stor->items[i].nameid; i++); + for(i = 0; i < MAX_GUILD_STORAGE && stor->u.items_guild[i].nameid; i++); if(i >= MAX_GUILD_STORAGE) return false; - memcpy(&stor->items[i],item,sizeof(stor->items[0])); - stor->items[i].amount = amount; - stor->storage_amount++; - clif_storageitemadded(sd,&stor->items[i],i,amount); - clif_updatestorageamount(sd, stor->storage_amount, MAX_GUILD_STORAGE); + memcpy(&stor->u.items_guild[i],item_data,sizeof(stor->u.items_guild[0])); + stor->u.items_guild[i].amount = amount; + stor->amount++; + clif_storageitemadded(sd,&stor->u.items_guild[i],i,amount); + clif_updatestorageamount(sd, stor->amount, MAX_GUILD_STORAGE); stor->dirty = true; return true; } @@ -563,7 +563,7 @@ bool gstorage_additem(struct map_session_data* sd, struct guild_storage* stor, s * @param amount : number of item to add * @return True : success, False : fail */ -bool gstorage_additem2(struct guild_storage* stor, struct item* item, int amount) { +bool storage_guild_additem2(struct s_storage* stor, struct item* item, int amount) { struct item_data *id; int i; @@ -578,13 +578,12 @@ bool gstorage_additem2(struct guild_storage* stor, struct item* item, int amount if (itemdb_isstackable2(id)) { // Stackable for (i = 0; i < MAX_GUILD_STORAGE; i++) { - if (compare_item(&stor->items[i], item)) { + if (compare_item(&stor->u.items_guild[i], item)) { // Set the amount, make it fit with max amount - int da = ((id->stack.guildstorage) ? id->stack.amount : MAX_AMOUNT) - stor->items[i].amount; - amount = min(amount, da); + amount = min(amount, ((id->stack.guildstorage) ? id->stack.amount : MAX_AMOUNT) - stor->u.items_guild[i].amount); if (amount != item->amount) - ShowWarning("gstorage_additem2: Stack limit reached! Altered amount of item \""CL_WHITE"%s"CL_RESET"\" (%d). '"CL_WHITE"%d"CL_RESET"' -> '"CL_WHITE"%d"CL_RESET"'.\n", id->name, id->nameid, item->amount, amount); - stor->items[i].amount += amount; + ShowWarning("storage_guild_additem2: Stack limit reached! Altered amount of item \""CL_WHITE"%s"CL_RESET"\" (%d). '"CL_WHITE"%d"CL_RESET"' -> '"CL_WHITE"%d"CL_RESET"'.\n", id->name, id->nameid, item->amount, amount); + stor->u.items_guild[i].amount += amount; stor->dirty = true; return true; } @@ -592,13 +591,13 @@ bool gstorage_additem2(struct guild_storage* stor, struct item* item, int amount } // Add the item - for (i = 0; i < MAX_GUILD_STORAGE && stor->items[i].nameid; i++); + for (i = 0; i < MAX_GUILD_STORAGE && stor->u.items_guild[i].nameid; i++); if (i >= MAX_GUILD_STORAGE) return false; - memcpy(&stor->items[i], item, sizeof(stor->items[0])); - stor->items[i].amount = amount; - stor->storage_amount++; + memcpy(&stor->u.items_guild[i], item, sizeof(stor->u.items_guild[0])); + stor->u.items_guild[i].amount = amount; + stor->amount++; stor->dirty = true; return true; } @@ -611,20 +610,20 @@ bool gstorage_additem2(struct guild_storage* stor, struct item* item, int amount * @param amount : number of item to delete * @return True : success, False : fail */ -bool gstorage_delitem(struct map_session_data* sd, struct guild_storage* stor, int n, int amount) +bool storage_guild_delitem(struct map_session_data* sd, struct s_storage* stor, int n, int amount) { nullpo_retr(1, sd); nullpo_retr(1, stor); - if(stor->items[n].nameid == 0 || stor->items[n].amount < amount) + if(!stor->u.items_guild[n].nameid || stor->u.items_guild[n].amount < amount) return false; - stor->items[n].amount -= amount; + stor->u.items_guild[n].amount -= amount; - if(stor->items[n].amount == 0) { - memset(&stor->items[n],0,sizeof(stor->items[0])); - stor->storage_amount--; - clif_updatestorageamount(sd, stor->storage_amount, MAX_GUILD_STORAGE); + if(!stor->u.items_guild[n].amount) { + memset(&stor->u.items_guild[n],0,sizeof(stor->u.items_guild[0])); + stor->amount--; + clif_updatestorageamount(sd, stor->amount, MAX_GUILD_STORAGE); } clif_storageitemremoved(sd,n,amount); @@ -637,31 +636,31 @@ bool gstorage_delitem(struct map_session_data* sd, struct guild_storage* stor, i * @param sd : player * @param amount : number of item to delete */ -void gstorage_storageadd(struct map_session_data* sd, int index, int amount) +void storage_guild_storageadd(struct map_session_data* sd, int index, int amount) { - struct guild_storage *stor; + struct s_storage *stor; nullpo_retv(sd); - nullpo_retv(stor = gstorage_get_storage(sd->status.guild_id)); + nullpo_retv(stor = guild2storage2(sd->status.guild_id)); - if( !stor->opened || stor->opened != sd->status.char_id || stor->storage_amount > MAX_GUILD_STORAGE ) + if( !stor->status || stor->amount > MAX_GUILD_STORAGE ) return; if( index < 0 || index >= MAX_INVENTORY ) return; - if( sd->status.inventory[index].nameid == 0 ) + if( sd->inventory.u.items_inventory[index].nameid == 0 ) return; - if( amount < 1 || amount > sd->status.inventory[index].amount ) + if( amount < 1 || amount > sd->inventory.u.items_inventory[index].amount ) return; - if( stor->locked ) { - gstorage_storageclose(sd); + if( stor->lock ) { + storage_guild_storageclose(sd); return; } - if(gstorage_additem(sd,stor,&sd->status.inventory[index],amount)) + if(!storage_guild_additem(sd,stor,&sd->inventory.u.items_inventory[index],amount)) pc_delitem(sd,index,amount,0,4,LOG_TYPE_GSTORAGE); else { clif_storageitemremoved(sd,index,0); @@ -676,33 +675,33 @@ void gstorage_storageadd(struct map_session_data* sd, int index, int amount) * @param amount : number of item to get * @return 1:success, 0:fail */ -void gstorage_storageget(struct map_session_data* sd, int index, int amount) +void storage_guild_storageget(struct map_session_data* sd, int index, int amount) { - struct guild_storage *stor; + struct s_storage *stor; unsigned char flag = 0; nullpo_retv(sd); - nullpo_retv(stor = gstorage_get_storage(sd->status.guild_id)); + nullpo_retv(stor = guild2storage2(sd->status.guild_id)); - if(!stor->opened || stor->opened != sd->status.char_id) + if(!stor->status) return; if(index < 0 || index >= MAX_GUILD_STORAGE) return; - if(stor->items[index].nameid == 0) + if(stor->u.items_guild[index].nameid == 0) return; - if(amount < 1 || amount > stor->items[index].amount) + if(amount < 1 || amount > stor->u.items_guild[index].amount) return; - if( stor->locked ) { - gstorage_storageclose(sd); + if( stor->lock ) { + storage_guild_storageclose(sd); return; } - if((flag = pc_additem(sd,&stor->items[index],amount,LOG_TYPE_GSTORAGE)) == 0) - gstorage_delitem(sd,stor,index,amount); + if((flag = pc_additem(sd,&stor->u.items_guild[index],amount,LOG_TYPE_GSTORAGE)) == 0) + storage_guild_delitem(sd,stor,index,amount); else { // inform fail clif_storageitemremoved(sd,index,0); clif_additem(sd,0,0,flag); @@ -715,26 +714,26 @@ void gstorage_storageget(struct map_session_data* sd, int index, int amount) * @param index : index of item in cart * @param amount : number of item to transfer */ -void gstorage_storageaddfromcart(struct map_session_data* sd, int index, int amount) +void storage_guild_storageaddfromcart(struct map_session_data* sd, int index, int amount) { - struct guild_storage *stor; + struct s_storage *stor; nullpo_retv(sd); - nullpo_retv(stor = gstorage_get_storage(sd->status.guild_id)); + nullpo_retv(stor = guild2storage2(sd->status.guild_id)); - if( !stor->opened || stor->opened != sd->status.char_id || stor->storage_amount > MAX_GUILD_STORAGE ) + if( !stor->status || stor->amount > MAX_GUILD_STORAGE ) return; if( index < 0 || index >= MAX_CART ) return; - if( sd->status.cart[index].nameid == 0 ) + if( sd->cart.u.items_cart[index].nameid == 0 ) return; - if( amount < 1 || amount > sd->status.cart[index].amount ) + if( amount < 1 || amount > sd->cart.u.items_cart[index].amount ) return; - if(gstorage_additem(sd,stor,&sd->status.cart[index],amount)) + if(!storage_guild_additem(sd,stor,&sd->cart.u.items_cart[index],amount)) pc_cart_delitem(sd,index,amount,0,LOG_TYPE_GSTORAGE); else { clif_storageitemremoved(sd,index,0); @@ -749,28 +748,28 @@ void gstorage_storageaddfromcart(struct map_session_data* sd, int index, int amo * @param amount : number of item to transfer * @return 1:fail, 0:success */ -void gstorage_storagegettocart(struct map_session_data* sd, int index, int amount) +void storage_guild_storagegettocart(struct map_session_data* sd, int index, int amount) { short flag; - struct guild_storage *stor; + struct s_storage *stor; nullpo_retv(sd); - nullpo_retv(stor = gstorage_get_storage(sd->status.guild_id)); + nullpo_retv(stor = guild2storage2(sd->status.guild_id)); - if(!stor->opened || stor->opened != sd->status.char_id) + if(!stor->status) return; if(index < 0 || index >= MAX_GUILD_STORAGE) return; - if(stor->items[index].nameid == 0) + if(stor->u.items_guild[index].nameid == 0) return; - if(amount < 1 || amount > stor->items[index].amount) + if(amount < 1 || amount > stor->u.items_guild[index].amount) return; - if((flag = pc_cart_additem(sd,&stor->items[index],amount,LOG_TYPE_GSTORAGE)) == 0) - gstorage_delitem(sd,stor,index,amount); + if((flag = pc_cart_additem(sd,&stor->u.items_guild[index],amount,LOG_TYPE_GSTORAGE)) == 0) + storage_guild_delitem(sd,stor,index,amount); else { clif_storageitemremoved(sd,index,0); clif_cart_additem_ack(sd,(flag == 1) ? ADDITEM_TO_CART_FAIL_WEIGHT:ADDITEM_TO_CART_FAIL_COUNT); @@ -784,13 +783,13 @@ void gstorage_storagegettocart(struct map_session_data* sd, int index, int amoun * @param flag : 1=char quitting, close the storage * @return False : fail (no storage), True : success (requested) */ -bool gstorage_storagesave(uint32 account_id, int guild_id, int flag) +bool storage_guild_storagesave(uint32 account_id, int guild_id, int flag) { - struct guild_storage *stor = gstorage_get_storage(guild_id); + struct s_storage *stor = guild2storage2(guild_id); if (stor) { if (flag) //Char quitting, close it. - stor->opened = 0; + stor->status = false; if (stor->dirty) intif_send_guild_storage(account_id,stor); @@ -805,12 +804,12 @@ bool gstorage_storagesave(uint32 account_id, int guild_id, int flag) * ACK save of guild storage * @param guild_id : guild to use the storage */ -void gstorage_storagesaved(int guild_id) +void storage_guild_storagesaved(int guild_id) { - struct guild_storage *stor; + struct s_storage *stor; - if ((stor = gstorage_get_storage(guild_id)) != NULL) { - if (stor->dirty && stor->opened == 0) // Storage has been correctly saved. + if ((stor = guild2storage2(guild_id)) != NULL) { + if (stor->dirty && !stor->status) // Storage has been correctly saved. stor->dirty = false; } } @@ -819,21 +818,21 @@ void gstorage_storagesaved(int guild_id) * Close storage for player then save it * @param sd : player */ -void gstorage_storageclose(struct map_session_data* sd) +void storage_guild_storageclose(struct map_session_data* sd) { - struct guild_storage *stor; + struct s_storage *stor; nullpo_retv(sd); - nullpo_retv(stor = gstorage_get_storage(sd->status.guild_id)); + nullpo_retv(stor = guild2storage2(sd->status.guild_id)); clif_storageclose(sd); - if (stor->opened) { + if (stor->status) { if (save_settings&CHARSAVE_STORAGE) chrif_save(sd, 0); //This one also saves the storage. [Skotlex] else - gstorage_storagesave(sd->status.account_id, sd->status.guild_id,0); + storage_guild_storagesave(sd->status.account_id, sd->status.guild_id,0); - stor->opened = 0; + stor->status = false; } sd->state.storage_flag = 0; @@ -844,31 +843,31 @@ void gstorage_storageclose(struct map_session_data* sd) * @param sd * @param flag */ -void gstorage_storage_quit(struct map_session_data* sd, int flag) +void storage_guild_storage_quit(struct map_session_data* sd, int flag) { - struct guild_storage *stor; + struct s_storage *stor; nullpo_retv(sd); - nullpo_retv(stor = gstorage_get_storage(sd->status.guild_id)); + nullpo_retv(stor = guild2storage2(sd->status.guild_id)); - if (flag) { // Only during a guild break flag is 1 (don't save storage) - sd->state.storage_flag = 0; - stor->opened = 0; + if (flag) { //Only during a guild break flag is 1 (don't save storage) clif_storageclose(sd); if (save_settings&CHARSAVE_STORAGE) chrif_save(sd,0); + sd->state.storage_flag = 0; + stor->status = false; return; } - if (stor->opened) { + if (stor->status) { if (save_settings&CHARSAVE_STORAGE) chrif_save(sd,0); else - gstorage_storagesave(sd->status.account_id,sd->status.guild_id,1); + storage_guild_storagesave(sd->status.account_id,sd->status.guild_id,1); } sd->state.storage_flag = 0; - stor->opened = 0; + stor->status = false; } diff --git a/src/map/storage.h b/src/map/storage.h index 112618d528..6ef94f5259 100644 --- a/src/map/storage.h +++ b/src/map/storage.h @@ -5,8 +5,7 @@ #define _STORAGE_H_ //#include "../common/mmo.h" -struct storage_data; -struct guild_storage; +struct s_storage; struct item; //#include "map.h" struct map_session_data; @@ -24,21 +23,21 @@ void do_final_storage(void); void do_reconnect_storage(void); void storage_storage_quit(struct map_session_data *sd, int flag); -struct guild_storage* gstorage_guild2storage(int guild_id); -struct guild_storage *gstorage_get_storage(int guild_id); -void gstorage_delete(int guild_id); -char gstorage_storageopen(struct map_session_data *sd); -bool gstorage_additem(struct map_session_data *sd,struct guild_storage *stor,struct item *item,int amount); -bool gstorage_additem2(struct guild_storage *stor, struct item *item, int amount); -bool gstorage_delitem(struct map_session_data *sd,struct guild_storage *stor,int n,int amount); -void gstorage_storageadd(struct map_session_data *sd,int index,int amount); -void gstorage_storageget(struct map_session_data *sd,int index,int amount); -void gstorage_storageaddfromcart(struct map_session_data *sd,int index,int amount); -void gstorage_storagegettocart(struct map_session_data *sd,int index,int amount); -void gstorage_storageclose(struct map_session_data *sd); -void gstorage_storage_quit(struct map_session_data *sd,int flag); -bool gstorage_storagesave(uint32 account_id, int guild_id, int flag); -void gstorage_storagesaved(int guild_id); +struct s_storage* guild2storage(int guild_id); +struct s_storage* guild2storage2(int guild_id); +void storage_guild_delete(int guild_id); +char storage_guild_storageopen(struct map_session_data *sd); +bool storage_guild_additem(struct map_session_data *sd,struct s_storage *stor,struct item *item_data,int amount); +bool storage_guild_additem2(struct s_storage* stor, struct item* item, int amount); +bool storage_guild_delitem(struct map_session_data *sd,struct s_storage *stor,int n,int amount); +void storage_guild_storageadd(struct map_session_data *sd,int index,int amount); +void storage_guild_storageget(struct map_session_data *sd,int index,int amount); +void storage_guild_storageaddfromcart(struct map_session_data *sd,int index,int amount); +void storage_guild_storagegettocart(struct map_session_data *sd,int index,int amount); +void storage_guild_storageclose(struct map_session_data *sd); +void storage_guild_storage_quit(struct map_session_data *sd,int flag); +bool storage_guild_storagesave(uint32 account_id, int guild_id, int flag); +void storage_guild_storagesaved(int guild_id); //Ack from char server that guild store was saved. int compare_item(struct item *a, struct item *b); diff --git a/src/map/trade.c b/src/map/trade.c index 4a4f80fe9e..1b4d8e37e6 100644 --- a/src/map/trade.c +++ b/src/map/trade.c @@ -182,7 +182,7 @@ int impossible_trade_check(struct map_session_data *sd) } // get inventory of player - memcpy(&inventory, &sd->status.inventory, sizeof(struct item) * MAX_INVENTORY); + memcpy(&inventory, &sd->inventory.u.items_inventory, sizeof(struct item) * MAX_INVENTORY); // remove this part: arrows can be trade and equipped // re-added! [celest] @@ -248,8 +248,8 @@ int trade_check(struct map_session_data *sd, struct map_session_data *tsd) return 0; // get inventory of player - memcpy(&inventory, &sd->status.inventory, sizeof(struct item) * MAX_INVENTORY); - memcpy(&inventory2, &tsd->status.inventory, sizeof(struct item) * MAX_INVENTORY); + memcpy(&inventory, &sd->inventory.u.items_inventory, sizeof(struct item) * MAX_INVENTORY); + memcpy(&inventory2, &tsd->inventory.u.items_inventory, sizeof(struct item) * MAX_INVENTORY); // check free slot in both inventory for(trade_i = 0; trade_i < 10; trade_i++) { @@ -365,10 +365,10 @@ void trade_tradeadditem(struct map_session_data *sd, short index, short amount) // Item checks... if( index < 0 || index >= MAX_INVENTORY ) return; - if( amount < 0 || amount > sd->status.inventory[index].amount ) + if( amount < 0 || amount > sd->inventory.u.items_inventory[index].amount ) return; - item = &sd->status.inventory[index]; + item = &sd->inventory.u.items_inventory[index]; src_lv = pc_get_group_level(sd); dst_lv = pc_get_group_level(target_sd); @@ -408,8 +408,8 @@ void trade_tradeadditem(struct map_session_data *sd, short index, short amount) } if( sd->deal.item[trade_i].index == index ) { // The same item as before is being readjusted. - if( sd->deal.item[trade_i].amount + amount > sd->status.inventory[index].amount ) { // packet deal exploit check - amount = sd->status.inventory[index].amount - sd->deal.item[trade_i].amount; + if( sd->deal.item[trade_i].amount + amount > sd->inventory.u.items_inventory[index].amount ) { // packet deal exploit check + amount = sd->inventory.u.items_inventory[index].amount - sd->deal.item[trade_i].amount; trade_weight = sd->inventory_data[index]->weight * amount; } @@ -594,7 +594,7 @@ void trade_tradecommit(struct map_session_data *sd) if (sd->deal.item[trade_i].amount) { n = sd->deal.item[trade_i].index; - flag = pc_additem(tsd, &sd->status.inventory[n], sd->deal.item[trade_i].amount,LOG_TYPE_TRADE); + flag = pc_additem(tsd, &sd->inventory.u.items_inventory[n], sd->deal.item[trade_i].amount,LOG_TYPE_TRADE); if (flag == 0) pc_delitem(sd, n, sd->deal.item[trade_i].amount, 1, 6, LOG_TYPE_TRADE); else @@ -606,7 +606,7 @@ void trade_tradecommit(struct map_session_data *sd) if (tsd->deal.item[trade_i].amount) { n = tsd->deal.item[trade_i].index; - flag = pc_additem(sd, &tsd->status.inventory[n], tsd->deal.item[trade_i].amount,LOG_TYPE_TRADE); + flag = pc_additem(sd, &tsd->inventory.u.items_inventory[n], tsd->deal.item[trade_i].amount,LOG_TYPE_TRADE); if (flag == 0) pc_delitem(tsd, n, tsd->deal.item[trade_i].amount, 1, 6, LOG_TYPE_TRADE); else diff --git a/src/map/unit.c b/src/map/unit.c index 0383bc7baa..0a8ad538ab 100644 --- a/src/map/unit.c +++ b/src/map/unit.c @@ -2913,7 +2913,7 @@ int unit_remove_map_(struct block_list *bl, clr_type clrtype, const char* file, if (sd->state.storage_flag == 1) storage_storage_quit(sd,0); else if (sd->state.storage_flag == 2) - gstorage_storage_quit(sd,0); + storage_guild_storage_quit(sd, 0); sd->state.storage_flag = 0; //Force close it when being warped. } diff --git a/src/map/vending.c b/src/map/vending.c index e297a87aad..529ef7cb0e 100755 --- a/src/map/vending.c +++ b/src/map/vending.c @@ -157,15 +157,15 @@ void vending_purchasereq(struct map_session_data* sd, int aid, int uid, const ui return; } - w += itemdb_weight(vsd->status.cart[idx].nameid) * amount; + w += itemdb_weight(vsd->cart.u.items_cart[idx].nameid) * amount; if( w + sd->weight > sd->max_weight ) { clif_buyvending(sd, idx, amount, 2); // you can not buy, because overweight return; } //Check to see if cart/vend info is in sync. - if( vending[j].amount > vsd->status.cart[idx].amount ) - vending[j].amount = vsd->status.cart[idx].amount; + if( vending[j].amount > vsd->cart.u.items_cart[idx].amount ) + vending[j].amount = vsd->cart.u.items_cart[idx].amount; // if they try to add packets (example: get twice or more 2 apples if marchand has only 3 apples). // here, we check cumulative amounts @@ -177,7 +177,7 @@ void vending_purchasereq(struct map_session_data* sd, int aid, int uid, const ui vending[j].amount -= amount; - switch( pc_checkadditem(sd, vsd->status.cart[idx].nameid, amount) ) { + switch( pc_checkadditem(sd, vsd->cart.u.items_cart[idx].nameid, amount) ) { case CHKADDITEM_EXIST: break; //We'd add this item to the existing one (in buyers inventory) case CHKADDITEM_NEW: @@ -202,16 +202,16 @@ void vending_purchasereq(struct map_session_data* sd, int aid, int uid, const ui z = 0.; // zeny counter // vending item - pc_additem(sd, &vsd->status.cart[idx], amount, LOG_TYPE_VENDING); + pc_additem(sd, &vsd->cart.u.items_cart[idx], amount, LOG_TYPE_VENDING); vsd->vending[vend_list[i]].amount -= amount; z += ((double)vsd->vending[i].value * (double)amount); if( vsd->vending[vend_list[i]].amount ) { - if( Sql_Query( mmysql_handle, "UPDATE `%s` SET `amount` = %d WHERE `vending_id` = %d and `cartinventory_id` = %d", vending_items_db, vsd->vending[vend_list[i]].amount, vsd->vender_id, vsd->status.cart[idx].id ) != SQL_SUCCESS ) { + if( Sql_Query( mmysql_handle, "UPDATE `%s` SET `amount` = %d WHERE `vending_id` = %d and `cartinventory_id` = %d", vending_items_db, vsd->vending[vend_list[i]].amount, vsd->vender_id, vsd->cart.u.items_cart[idx].id ) != SQL_SUCCESS ) { Sql_ShowDebug( mmysql_handle ); } } else { - if( Sql_Query( mmysql_handle, "DELETE FROM `%s` WHERE `vending_id` = %d and `cartinventory_id` = %d", vending_items_db, vsd->vender_id, vsd->status.cart[idx].id ) != SQL_SUCCESS ) { + if( Sql_Query( mmysql_handle, "DELETE FROM `%s` WHERE `vending_id` = %d and `cartinventory_id` = %d", vending_items_db, vsd->vender_id, vsd->cart.u.items_cart[idx].id ) != SQL_SUCCESS ) { Sql_ShowDebug( mmysql_handle ); } } @@ -315,28 +315,16 @@ int8 vending_openvending(struct map_session_data* sd, const char* message, const if( index < 0 || index >= MAX_CART // invalid position || pc_cartitem_amount(sd, index, amount) < 0 // invalid item or insufficient quantity //NOTE: official server does not do any of the following checks! - || !sd->status.cart[index].identify // unidentified item - || sd->status.cart[index].attribute == 1 // broken item - || sd->status.cart[index].expire_time // It should not be in the cart but just in case - || (sd->status.cart[index].bound && !pc_can_give_bounded_items(sd)) // can't trade account bound items and has no permission - || !itemdb_cantrade(&sd->status.cart[index], pc_get_group_level(sd), pc_get_group_level(sd)) ) // untradeable item + || !sd->cart.u.items_cart[index].identify // unidentified item + || sd->cart.u.items_cart[index].attribute == 1 // broken item + || sd->cart.u.items_cart[index].expire_time // It should not be in the cart but just in case + || (sd->cart.u.items_cart[index].bound && !pc_can_give_bounded_items(sd)) // can't trade account bound items and has no permission + || !itemdb_cantrade(&sd->cart.u.items_cart[index], pc_get_group_level(sd), pc_get_group_level(sd)) ) // untradeable item continue; sd->vending[i].index = index; sd->vending[i].amount = amount; sd->vending[i].value = min(value, (unsigned int)battle_config.vending_max_value); - - // Player just moved item to cart and we don't have the correct cart ID yet. - if (sd->status.cart[sd->vending[i].index].id == 0) { - struct item_data *idb = itemdb_search(sd->status.cart[index].nameid); - char msg[256]; - - sprintf(msg, msg_txt(sd, 733), idb->jname); - clif_displaymessage(sd->fd, msg); - clif_skill_fail(sd, MC_VENDING, USESKILL_FAIL_LEVEL, 0); - return 4; - } - i++; // item successfully added } @@ -365,7 +353,7 @@ int8 vending_openvending(struct map_session_data* sd, const char* message, const StringBuf_Init(&buf); StringBuf_Printf(&buf, "INSERT INTO `%s`(`vending_id`,`index`,`cartinventory_id`,`amount`,`price`) VALUES", vending_items_db); for (i = 0; i < count; i++) { - StringBuf_Printf(&buf, "(%d,%d,%d,%d,%d)", sd->vender_id, i, sd->status.cart[sd->vending[i].index].id, sd->vending[i].amount, sd->vending[i].value); + StringBuf_Printf(&buf, "(%d,%d,%d,%d,%d)", sd->vender_id, i, sd->cart.u.items_cart[sd->vending[i].index].id, sd->vending[i].amount, sd->vending[i].value); if (i < count-1) StringBuf_AppendStr(&buf, ","); } @@ -395,7 +383,7 @@ bool vending_search(struct map_session_data* sd, unsigned short nameid) return false; } - ARR_FIND( 0, sd->vend_num, i, sd->status.cart[sd->vending[i].index].nameid == (short)nameid ); + ARR_FIND( 0, sd->vend_num, i, sd->cart.u.items_cart[sd->vending[i].index].nameid == (short)nameid ); if( i == sd->vend_num ) { // not found return false; } @@ -419,11 +407,11 @@ bool vending_searchall(struct map_session_data* sd, const struct s_search_store_ return true; for( idx = 0; idx < s->item_count; idx++ ) { - ARR_FIND( 0, sd->vend_num, i, sd->status.cart[sd->vending[i].index].nameid == (short)s->itemlist[idx] ); + ARR_FIND( 0, sd->vend_num, i, sd->cart.u.items_cart[sd->vending[i].index].nameid == (short)s->itemlist[idx] ); if( i == sd->vend_num ) { // not found continue; } - it = &sd->status.cart[sd->vending[i].index]; + it = &sd->cart.u.items_cart[sd->vending[i].index]; if( s->min_price && s->min_price > sd->vending[i].value ) { // too low price continue; @@ -485,7 +473,7 @@ void vending_reopen( struct map_session_data* sd ) uint32 *value = (uint32*)(p + 4); // Find item position in cart - ARR_FIND(0, MAX_CART, entry->index, sd->status.cart[entry->index].id == entry->cartinventory_id); + ARR_FIND(0, MAX_CART, entry->index, sd->cart.u.items_cart[entry->index].id == entry->cartinventory_id); if (entry->index == MAX_CART) { count--; @@ -493,7 +481,7 @@ void vending_reopen( struct map_session_data* sd ) } *index = entry->index + 2; - *amount = itemdb_isstackable(sd->status.cart[entry->index].nameid) ? entry->amount : 1; + *amount = itemdb_isstackable(sd->cart.u.items_cart[entry->index].nameid) ? entry->amount : 1; *value = entry->price; p += 8;