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!
This commit is contained in:
aleos89 2016-03-29 13:30:27 -04:00
parent fe97051adf
commit d88a6aca45
39 changed files with 1820 additions and 1223 deletions

View File

@ -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.

View File

@ -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.

View File

@ -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: <cmd>.W <type>.B <account_id>.L <char_id>.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: <size>.W <type>.B <account_id>.L <char_id>.L <entries>.?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: <cmd>.W <s_homunculus>.W <aid>.L <sh>.?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: <cmd>.W <size>.W <type>.B <account_id>.L <result>.B <entries>.?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: <cmd>.W <account_id>.L <result>.B <type>.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: <cmd>.W <size>.W <account_id>.L <flag>.B <s_homunculus>.?B

View File

@ -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 "<item name>",<amount>{,<account ID>};
*storagedelitem <item id>,<amount>{,<account ID>};
*storagedelitem "<item name>",<amount>{,<account ID>};
*guildstoragedelitem <item id>,<amount>{,<account ID>};
*guildstoragedelitem "<item name>",<amount>{,<account ID>};
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 "<item name>",<amount>,<identify>,<refine>,<attribute>,<card1>,<card2>,<card3>,<card4>{,<account ID>};
*storagedelitem2 <item id>,<amount>,<identify>,<refine>,<attribute>,<card1>,<card2>,<card3>,<card4>{,<account ID>};
*storagedelitem2 "<item name>",<amount>,<identify>,<refine>,<attribute>,<card1>,<card2>,<card3>,<card4>{,<account ID>};
*guildstoragedelitem2 <item id>,<amount>,<identify>,<refine>,<attribute>,<card1>,<card2>,<card3>,<card4>{,<account ID>};
*guildstoragedelitem2 "<item name>",<amount>,<identify>,<refine>,<attribute>,<card1>,<card2>,<card3>,<card4>{,<account ID>};
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(<item id>)
*cartcountitem("<item name>")
*storagecountitem(<item id>)
*storagecountitem("<item name>")
*cartcountitem(<item id>{,<accountID>})
*cartcountitem("<item name>"{,<accountID>})
*storagecountitem(<item id>{,<accountID>})
*storagecountitem("<item name>"{,<accountID>})
*guildstoragecountitem(<nameID>{,<accountID>})
*guildstoragecountitem("<item name>"{,<accountID>})
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(<item id>,<identify>,<refine>,<attribute>,<card1>,<card2>,<card3>,<card4>)
*cartcountitem2("<item name>",<identify>,<refine>,<attribute>,<card1>,<card2>,<card3>,<card4>)
*storagecountitem2(<item id>,<identify>,<refine>,<attribute>,<card1>,<card2>,<card3>,<card4>)
*storagecountitem2("<item name>",<identify>,<refine>,<attribute>,<card1>,<card2>,<card3>,<card4>)
*cartcountitem2(<item id>,<identify>,<refine>,<attribute>,<card1>,<card2>,<card3>,<card4>{,<accountID>})
*cartcountitem2("<item name>",<identify>,<refine>,<attribute>,<card1>,<card2>,<card3>,<card4>{,<accountID>})
*storagecountitem2(<item id>,<identify>,<refine>,<attribute>,<card1>,<card2>,<card3>,<card4>{,<accountID>})
*storagecountitem2("<item name>",<identify>,<refine>,<attribute>,<card1>,<card2>,<card3>,<card4>{,<accountID>})
*guildstoragecountitem2(<nameID>,<Identified>,<Refine>,<Attribute>,<Card0>,<Card1>,<Card2>,<Card3>{,<accountID>})
*guildstoragecountitem2("<item name>",<Identified>,<Refine>,<Attribute>,<Card0>,<Card1>,<Card2>,<Card3>{,<accountID>})
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.
---------------------------------------

View File

@ -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));

View File

@ -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);

View File

@ -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 <char id>.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)

View File

@ -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 <stdio.h>
#include <string.h>
#include <stdlib.h>
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 )

View File

@ -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 <account_id>.L <guild_id>.W
* Tells map-server if the process if complete, unlock the guild storage
*/
* IZ 0x3856 <account_id>.L <guild_id>.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 <size>.W <count>.W <guild_id>.W { <item>.?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 <size>.W <count>.W <guild_id>.W { <item>.?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 <char_id>.L <account_id>.L <guild_id>.W
* Pulls guild bound items for offline characters
* @author [Akinari]
*/
int mapif_parse_itembound_retrieve(int fd)
* ZI 0x3056 <char_id>.L <account_id>.L <guild_id>.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 <size>.W <type>.B <account_id>.L <result>.B <inventory>.?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 <account_id>.L <result>.B <type>.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 <type>.B <account_id>.L <char_id>.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 <size>.W <type>.B <account_id>.L <char_id>.L <entries>.?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;
}

View File

@ -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_ */

View File

@ -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);

View File

@ -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]

View File

@ -17,7 +17,6 @@
#include <stdlib.h>
/// 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

View File

@ -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;i<MAX_INVENTORY;i++){
if(sd->status.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; i<MAX_INVENTORY; i++) {
if (sd->status.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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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);

View File

@ -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;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]))
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;i<MAX_INVENTORY;i++){
if(sd->status.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;i<MAX_INVENTORY;i++){
unsigned short nameid;
if((nameid=dstsd->status.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;i<MAX_INVENTORY;i++){
WFIFOW(fd,0) = 0x221;
for(i = c = 0; i < MAX_INVENTORY; i++) {
unsigned char wlv;
if(sd->status.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;i<MAX_INVENTORY;i++){
if(sd->status.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);
}

View File

@ -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;

View File

@ -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);

View File

@ -21,10 +21,12 @@
#include "elemental.h"
#include "mail.h"
#include "quest.h"
#include "status.h"
#include <stdlib.h>
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 <size>.W <count>.W <guild_id>.W { <item>.?B }.*MAX_INVENTORY
* Received the retrieved guild bound items from inter-server, store them to guild storage.
* @param fd
* @author [Cydh]
*/
* IZ 0x3857 <size>.W <count>.W <guild_id>.W { <item>.?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 <size>.W <type>.B <account_id>.L <result>.B <storage>.?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 <account_id>.L <result>.B <type>.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 <type>.B <account_id>.L <char_id>.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 <size>.W <type>.B <account_id>.L <char_id>.L <entries>.?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;
}

View File

@ -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_ */

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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]));
}
}

View File

@ -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;

View File

@ -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;i<j;i++)
pc_delitem(sd,idxlist[i],sd->status.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;i<MAX_INVENTORY;i++){
// FIXME: This does not consider the checked item's cards, thus could check a wrong slot for stackability.
if(sd->status.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].amount<amount || sd->inventory_data[n] == NULL)
if(n < 0 || sd->inventory.u.items_inventory[n].nameid == 0 || amount <= 0 || sd->inventory.u.items_inventory[n].amount<amount || sd->inventory_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].amount<amount)
if(sd->cart.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;i<MAX_INVENTORY;i++){
if(sd->status.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;i<MAX_INVENTORY;i++) {
if( (type == 1 && !sd->status.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;i<MAX_INVENTORY;i++){
if(sd->status.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);
}

View File

@ -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);

View File

@ -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);

View File

@ -45,13 +45,9 @@
#include "battleground.h"
#include "party.h"
#include "mail.h"
#include "script.h"
#include "quest.h"
#include "elemental.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#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 <nameID>,<Identified>,<Refine>,<Attribute>,<Card0>,<Card1>,<Card2>,<Card3>{,<accountID>})
/// storagecountitem <nameID>{,<accountID>});
/// storagecountitem2 <nameID>,<Identified>,<Refine>,<Attribute>,<Card0>,<Card1>,<Card2>,<Card3>{,<accountID>})
/// guildstoragecountitem <nameID>{,<accountID>});
/// guildstoragecountitem2 <nameID>,<Identified>,<Refine>,<Attribute>,<Card0>,<Card1>,<Card2>,<Card3>{,<accountID>})
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 "<item name>",<amount>{,<account id>}
/// storagedelitem <item id>,<amount>{,<account id>}
/// storagedelitem "<item name>",<amount>{,<account id>}
/// guildstoragedelitem <item id>,<amount>{,<account id>}
/// guildstoragedelitem "<item name>",<amount>{,<account id>}
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 "<Item name>",<amount>,<identify>,<refine>,<attribute>,<card1>,<card2>,<card3>,<card4>{,<account ID>}
/// storagedelitem2 <item id>,<amount>,<identify>,<refine>,<attribute>,<card1>,<card2>,<card3>,<card4>{,<account ID>}
/// storagedelitem2 "<Item name>",<amount>,<identify>,<refine>,<attribute>,<card1>,<card2>,<card3>,<card4>{,<account ID>}
/// guildstoragedelitem2 <item id>,<amount>,<identify>,<refine>,<attribute>,<card1>,<card2>,<card3>,<card4>{,<account ID>}
/// guildstoragedelitem2 "<Item name>",<amount>,<identify>,<refine>,<attribute>,<card1>,<card2>,<card3>,<card4>{,<account ID>}
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; i<MAX_INVENTORY; i++) {
if(sd->status.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; i<MAX_INVENTORY; i++) {
if(sd->status.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;i<MAX_INVENTORY;i++){
if(sd->status.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; i<MAX_INVENTORY; i++) {
if (sd->status.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;i<MAX_INVENTORY;i++){
if(sd->status.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;n<sd->inventory_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; k<sd->inventory_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; k<sd->inventory_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"),

View File

@ -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<<AMMO_BULLET|1<<AMMO_GRENADE|1<<AMMO_SHELL)) {
clif_skill_fail(sd,skill_id,USESKILL_FAIL_NEED_MORE_BULLET,0);
@ -15660,7 +15660,7 @@ bool skill_check_condition_castend(struct map_session_data* sd, uint16 skill_id,
sprintf(e_msg,msg_txt(sd,381), //Skill Failed. [%s] requires %dx %s.
skill_get_desc(skill_id),
require.ammo_qty,
itemdb_jname(sd->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;
}

View File

@ -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;i<MAX_INVENTORY;i++) {
if(sd->status.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;i<MAX_CART;i++) {
if(sd->status.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 )

View File

@ -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);

View File

@ -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;
}

View File

@ -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);

View File

@ -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

View File

@ -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.
}

View File

@ -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;