- Implemented new packets for rental items (from Jobbie and Natz and fixed by me).

- Rental items now can be moved to storage and cart.
- Autotrade cannot be used when user is dead, and it's not dispelled if user dies to prevent abuse.
- Fixed pc_checkitem to do a proper item check and remove.

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@14082 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
zephyrus 2009-10-04 21:42:15 +00:00
parent ebc71ca92f
commit 115d6a3fd0
7 changed files with 291 additions and 152 deletions

View File

@ -39,7 +39,7 @@ int storage_fromsql(int account_id, struct storage_data* p)
// storage {`account_id`/`id`/`nameid`/`amount`/`equip`/`identify`/`refine`/`attribute`/`card0`/`card1`/`card2`/`card3`} // storage {`account_id`/`id`/`nameid`/`amount`/`equip`/`identify`/`refine`/`attribute`/`card0`/`card1`/`card2`/`card3`}
StringBuf_Init(&buf); StringBuf_Init(&buf);
StringBuf_AppendStr(&buf, "SELECT `id`,`nameid`,`amount`,`equip`,`identify`,`refine`,`attribute`"); StringBuf_AppendStr(&buf, "SELECT `id`,`nameid`,`amount`,`equip`,`identify`,`refine`,`attribute`,`expire_time`");
for( j = 0; j < MAX_SLOTS; ++j ) for( j = 0; j < MAX_SLOTS; ++j )
StringBuf_Printf(&buf, ",`card%d`", j); StringBuf_Printf(&buf, ",`card%d`", j);
StringBuf_Printf(&buf, " FROM `%s` WHERE `account_id`='%d' ORDER BY `nameid`", storage_db, account_id); StringBuf_Printf(&buf, " FROM `%s` WHERE `account_id`='%d' ORDER BY `nameid`", storage_db, account_id);
@ -59,10 +59,10 @@ int storage_fromsql(int account_id, struct storage_data* p)
Sql_GetData(sql_handle, 4, &data, NULL); item->identify = 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, 5, &data, NULL); item->refine = atoi(data);
Sql_GetData(sql_handle, 6, &data, NULL); item->attribute = atoi(data); Sql_GetData(sql_handle, 6, &data, NULL); item->attribute = atoi(data);
item->expire_time = 0; Sql_GetData(sql_handle, 7, &data, NULL); item->expire_time = (unsigned int)atoi(data);
for( j = 0; j < MAX_SLOTS; ++j ) for( j = 0; j < MAX_SLOTS; ++j )
{ {
Sql_GetData(sql_handle, 7+j, &data, NULL); item->card[j] = atoi(data); Sql_GetData(sql_handle, 8+j, &data, NULL); item->card[j] = atoi(data);
} }
} }
p->storage_amount = i; p->storage_amount = i;

View File

@ -5870,6 +5870,12 @@ int atcommand_autotrade(const int fd, struct map_session_data* sd, const char* c
nullpo_retr(-1, sd); nullpo_retr(-1, sd);
if( sd->vender_id ) //check if player's vending if( sd->vender_id ) //check if player's vending
{ {
if( pc_isdead(sd) )
{
clif_displaymessage(fd, "Cannot Autotrade if you are dead.");
return -1;
}
if( map[sd->bl.m].flag.autotrade == battle_config.autotrade_mapflag ) if( map[sd->bl.m].flag.autotrade == battle_config.autotrade_mapflag )
{ {
sd->state.autotrade = 1; sd->state.autotrade = 1;

View File

@ -1795,15 +1795,17 @@ static void clif_addcards(unsigned char* buf, struct item* item)
int clif_additem(struct map_session_data *sd, int n, int amount, int fail) int clif_additem(struct map_session_data *sd, int n, int amount, int fail)
{ {
int fd; int fd;
int cmd = ((PACKETVER < 20071002) ? 0xa0 : 0x2d4);
nullpo_retr(0, sd); nullpo_retr(0, sd);
fd = sd->fd; fd = sd->fd;
if (!session_isActive(fd)) //Sasuke- if( !session_isActive(fd) ) //Sasuke-
return 0; return 0;
WFIFOHEAD(fd,packet_len(0xa0)); WFIFOHEAD(fd,packet_len(cmd));
if(fail) { if( fail )
WFIFOW(fd,0)=0xa0; {
WFIFOW(fd,0)=cmd;
WFIFOW(fd,2)=n+2; WFIFOW(fd,2)=n+2;
WFIFOW(fd,4)=amount; WFIFOW(fd,4)=amount;
WFIFOW(fd,6)=0; WFIFOW(fd,6)=0;
@ -1817,11 +1819,18 @@ int clif_additem(struct map_session_data *sd, int n, int amount, int fail)
WFIFOW(fd,19)=0; WFIFOW(fd,19)=0;
WFIFOB(fd,21)=0; WFIFOB(fd,21)=0;
WFIFOB(fd,22)=fail; WFIFOB(fd,22)=fail;
} else { #if PACKETVER >= 20071002
if (n<0 || n>=MAX_INVENTORY || sd->status.inventory[n].nameid <=0 || sd->inventory_data[n] == NULL) WFIFOW(fd,23)=0;
WFIFOW(fd,25)=0;
WFIFOW(fd,27)=0;
#endif
}
else
{
if( n < 0 || n >= MAX_INVENTORY || sd->status.inventory[n].nameid <=0 || sd->inventory_data[n] == NULL )
return 1; return 1;
WFIFOW(fd,0)=0xa0; WFIFOW(fd,0)=cmd;
WFIFOW(fd,2)=n+2; WFIFOW(fd,2)=n+2;
WFIFOW(fd,4)=amount; WFIFOW(fd,4)=amount;
if (sd->inventory_data[n]->view_id > 0) if (sd->inventory_data[n]->view_id > 0)
@ -1835,9 +1844,13 @@ int clif_additem(struct map_session_data *sd, int n, int amount, int fail)
WFIFOW(fd,19)=pc_equippoint(sd,n); WFIFOW(fd,19)=pc_equippoint(sd,n);
WFIFOB(fd,21)=itemtype(sd->inventory_data[n]->type); WFIFOB(fd,21)=itemtype(sd->inventory_data[n]->type);
WFIFOB(fd,22)=fail; WFIFOB(fd,22)=fail;
#if PACKETVER >= 20071002
WFIFOL(fd,23)=sd->status.inventory[n].expire_time;
WFIFOW(fd,27)=0;
#endif
} }
WFIFOSET(fd,packet_len(0xa0)); WFIFOSET(fd,packet_len(cmd));
return 0; return 0;
} }
@ -1889,57 +1902,74 @@ void clif_item_sub(unsigned char *buf, int n, struct item *i, struct item_data *
//Unified inventory function which sends all of the inventory (requires two packets, one for equipable items and one for stackable ones. [Skotlex] //Unified inventory function which sends all of the inventory (requires two packets, one for equipable items and one for stackable ones. [Skotlex]
void clif_inventorylist(struct map_session_data *sd) void clif_inventorylist(struct map_session_data *sd)
{ {
int i,n,ne,fd = sd->fd,arrow=-1; int i,n,ne,arrow=-1;
unsigned char *buf; unsigned char *buf;
unsigned char bufe[MAX_INVENTORY*20+4]; unsigned char *bufe;
#if PACKETVER < 5 #if PACKETVER < 5
const int s = 10; //Entry size. const int s = 10; //Entry size.
#else #else
const int s = 18; const int s = ((PACKETVER < 20080102) ? 18 : 22);
#endif #endif
WFIFOHEAD(fd, MAX_INVENTORY * s + 4);
buf = WFIFOP(fd,0);
for(i=0,n=0,ne=0;i<MAX_INVENTORY;i++){ const int se = ((PACKETVER < 20071002) ? 20 : 26);
if (sd->status.inventory[i].nameid <=0 || sd->inventory_data[i] == NULL) buf = (unsigned char*)aMallocA(MAX_INVENTORY * s + 4);
bufe = (unsigned char*)aMallocA(MAX_INVENTORY * se + 4);
for( i = 0, n = 0, ne = 0; i < MAX_INVENTORY; i++ )
{
if( sd->status.inventory[i].nameid <=0 || sd->inventory_data[i] == NULL )
continue; continue;
if(!itemdb_isstackable2(sd->inventory_data[i])) if( !itemdb_isstackable2(sd->inventory_data[i]) )
{ //Non-stackable (Equippable) { //Non-stackable (Equippable)
WBUFW(bufe,ne*20+4)=i+2; WBUFW(bufe,ne*se+4)=i+2;
clif_item_sub(bufe, ne*20+6, &sd->status.inventory[i], sd->inventory_data[i], pc_equippoint(sd,i)); clif_item_sub(bufe, ne*se+6, &sd->status.inventory[i], sd->inventory_data[i], pc_equippoint(sd,i));
clif_addcards(WBUFP(bufe, ne*20+16), &sd->status.inventory[i]); clif_addcards(WBUFP(bufe, ne*se+16), &sd->status.inventory[i]);
if( PACKETVER >= 20071002 )
{
WBUFL(bufe,ne*se+24)=sd->status.inventory[i].expire_time;
WBUFW(bufe,ne*se+28)=0; //Unknown
}
ne++; ne++;
} else { //Stackable. }
else
{ //Stackable.
WBUFW(buf,n*s+4)=i+2; WBUFW(buf,n*s+4)=i+2;
clif_item_sub(buf, n*s+6, &sd->status.inventory[i], sd->inventory_data[i], -2); clif_item_sub(buf, n*s+6, &sd->status.inventory[i], sd->inventory_data[i], -2);
if (sd->inventory_data[i]->equip == EQP_AMMO && if( sd->inventory_data[i]->equip == EQP_AMMO && sd->status.inventory[i].equip )
sd->status.inventory[i].equip)
arrow=i; arrow=i;
#if PACKETVER >= 5 #if PACKETVER >= 5
clif_addcards(WBUFP(buf, n*s+14), &sd->status.inventory[i]); clif_addcards(WBUFP(buf, n*s+14), &sd->status.inventory[i]);
#endif
#if PACKETVER >= 20080102
WBUFL(buf,n*s+22)=sd->status.inventory[i].expire_time;
#endif #endif
n++; n++;
} }
} }
if (n) { if( n )
{
#if PACKETVER < 5 #if PACKETVER < 5
WBUFW(buf,0)=0xa3; WBUFW(buf,0)=0xa3;
#else #else
WBUFW(buf,0)=0x1ee; WBUFW(buf,0)=((PACKETVER < 20080102) ? 0x1ee : 0x2e8);
#endif #endif
WBUFW(buf,2)=4+n*s; WBUFW(buf,2)=4+n*s;
WFIFOSET(fd,WFIFOW(fd,2)); clif_send(buf, WBUFW(buf,2), &sd->bl, SELF);
} }
if(arrow >= 0) if( arrow >= 0 )
clif_arrowequip(sd,arrow); clif_arrowequip(sd,arrow);
if(ne){ if( ne )
WBUFW(bufe,0)=0xa4; {
WBUFW(bufe,2)=4+ne*20; WBUFW(bufe,0)=((PACKETVER < 20071002) ? 0xa4 : 0x2d0);
WBUFW(bufe,2)=4+ne*se;
clif_send(bufe, WBUFW(bufe,2), &sd->bl, SELF); clif_send(bufe, WBUFW(bufe,2), &sd->bl, SELF);
} }
if( buf ) aFree(buf);
if( bufe ) aFree(bufe);
} }
//Required when items break/get-repaired. Only sends equippable item list. //Required when items break/get-repaired. Only sends equippable item list.
@ -1947,7 +1977,8 @@ void clif_equiplist(struct map_session_data *sd)
{ {
int i,n,fd = sd->fd; int i,n,fd = sd->fd;
unsigned char *buf; unsigned char *buf;
WFIFOHEAD(fd, MAX_INVENTORY * 20 + 4); const int cmd = ((PACKETVER < 20071002) ? 20 : 26);
WFIFOHEAD(fd, MAX_INVENTORY * cmd + 4);
buf = WFIFOP(fd,0); buf = WFIFOP(fd,0);
for(i=0,n=0;i<MAX_INVENTORY;i++){ for(i=0,n=0;i<MAX_INVENTORY;i++){
@ -1957,14 +1988,19 @@ void clif_equiplist(struct map_session_data *sd)
if(itemdb_isstackable2(sd->inventory_data[i])) if(itemdb_isstackable2(sd->inventory_data[i]))
continue; continue;
//Equippable //Equippable
WBUFW(buf,n*20+4)=i+2; WBUFW(buf,n*cmd+4)=i+2;
clif_item_sub(buf, n*20+6, &sd->status.inventory[i], sd->inventory_data[i], pc_equippoint(sd,i)); clif_item_sub(buf, n*cmd+6, &sd->status.inventory[i], sd->inventory_data[i], pc_equippoint(sd,i));
clif_addcards(WBUFP(buf, n*20+16), &sd->status.inventory[i]); clif_addcards(WBUFP(buf, n*cmd+16), &sd->status.inventory[i]);
if(PACKETVER >= 20071002)
{
WBUFL(buf,n*cmd+24)=sd->status.inventory[i].expire_time;
WBUFW(buf,n*cmd+28)=0; //Unknown
}
n++; n++;
} }
if (n) { if (n) {
WBUFW(buf,0)=0xa4; WBUFW(buf,0)=((PACKETVER < 20071002) ? 0xa4 : 0x2d0);
WBUFW(buf,2)=4+n*20; WBUFW(buf,2)=4+n*cmd;
WFIFOSET(fd,WFIFOW(fd,2)); WFIFOSET(fd,WFIFOW(fd,2));
} }
} }
@ -1972,150 +2008,203 @@ void clif_equiplist(struct map_session_data *sd)
void clif_storagelist(struct map_session_data* sd, struct storage_data* stor) void clif_storagelist(struct map_session_data* sd, struct storage_data* stor)
{ {
struct item_data *id; struct item_data *id;
int i,n,ne,fd=sd->fd; int i,n,ne;
unsigned char *buf; unsigned char *buf;
unsigned char bufe[MAX_STORAGE*20+4]; unsigned char *bufe;
#if PACKETVER < 5 #if PACKETVER < 5
const int s = 10; //Entry size. const int s = 10; //Entry size.
#else #else
const int s = 18; const int s = ((PACKETVER < 20080102) ? 18 : 22);
#endif #endif
WFIFOHEAD(fd,MAX_STORAGE * s + 4);
buf = WFIFOP(fd,0);
for(i=0,n=0,ne=0;i<MAX_STORAGE;i++){ const int cmd = ((PACKETVER < 20071002) ? 20 : 26);
if(stor->items[i].nameid<=0) buf = (unsigned char*)aMallocA(MAX_STORAGE * s + 4);
bufe = (unsigned char*)aMallocA(MAX_STORAGE * cmd + 4);
for( i = 0, n = 0, ne = 0; i < MAX_STORAGE; i++ )
{
if( stor->items[i].nameid <= 0 )
continue; continue;
id = itemdb_search(stor->items[i].nameid); id = itemdb_search(stor->items[i].nameid);
if(!itemdb_isstackable2(id)) if( !itemdb_isstackable2(id) )
{ //Equippable { //Equippable
WBUFW(bufe,ne*20+4)=i+1; WBUFW(bufe,ne*cmd+4)=i+1;
clif_item_sub(bufe, ne*20+6, &stor->items[i], id, id->equip); clif_item_sub(bufe, ne*cmd+6, &stor->items[i], id, id->equip);
clif_addcards(WBUFP(bufe, ne*20+16), &stor->items[i]); clif_addcards(WBUFP(bufe, ne*cmd+16), &stor->items[i]);
if( PACKETVER >= 20071002 )
{
WBUFL(bufe,ne*cmd+24)=stor->items[i].expire_time;
WBUFW(bufe,ne*cmd+28)=0; //Unknown
}
ne++; ne++;
} else { //Stackable }
else
{ //Stackable
WBUFW(buf,n*s+4)=i+1; WBUFW(buf,n*s+4)=i+1;
clif_item_sub(buf, n*s+6, &stor->items[i], id,-1); clif_item_sub(buf, n*s+6, &stor->items[i], id,-1);
#if PACKETVER >= 5 #if PACKETVER >= 5
clif_addcards(WBUFP(buf,n*s+14), &stor->items[i]); clif_addcards(WBUFP(buf,n*s+14), &stor->items[i]);
#endif
#if PACKETVER >= 20080102
WBUFL(buf,n*s+22)=stor->items[i].expire_time;
#endif #endif
n++; n++;
} }
} }
if(n){ if( n )
{
#if PACKETVER < 5 #if PACKETVER < 5
WBUFW(buf,0)=0xa5; WBUFW(buf,0)=0xa5;
#else #else
WBUFW(buf,0)=0x1f0; WBUFW(buf,0)=((PACKETVER < 20080102) ? 0x1f0 : 0x2ea);
#endif #endif
WBUFW(buf,2)=4+n*s; WBUFW(buf,2)=4+n*s;
WFIFOSET(fd,WFIFOW(fd,2)); clif_send(buf, WBUFW(buf,2), &sd->bl, SELF);
} }
if(ne){ if( ne )
WBUFW(bufe,0)=0xa6; {
WBUFW(bufe,2)=4+ne*20; WBUFW(bufe,0)=((PACKETVER < 20071002) ? 0xa6 : 0x2d1);
WBUFW(bufe,2)=4+ne*cmd;
clif_send(bufe, WBUFW(bufe,2), &sd->bl, SELF); clif_send(bufe, WBUFW(bufe,2), &sd->bl, SELF);
} }
if( buf ) aFree(buf);
if( bufe ) aFree(bufe);
} }
//Unified storage function which sends all of the storage (requires two packets, one for equipable items and one for stackable ones. [Skotlex] //Unified storage function which sends all of the storage (requires two packets, one for equipable items and one for stackable ones. [Skotlex]
void clif_guildstoragelist(struct map_session_data *sd,struct guild_storage *stor) void clif_guildstoragelist(struct map_session_data *sd,struct guild_storage *stor)
{ {
struct item_data *id; struct item_data *id;
int i,n,ne,fd=sd->fd; int i,n,ne;
unsigned char *buf; unsigned char *buf;
unsigned char bufe[MAX_GUILD_STORAGE*20+4]; unsigned char *bufe;
#if PACKETVER < 5 #if PACKETVER < 5
const int s = 10; //Entry size. const int s = 10; //Entry size.
#else #else
const int s = 18; const int s = ((PACKETVER < 20080102) ? 18 : 22);
#endif #endif
WFIFOHEAD(fd,MAX_GUILD_STORAGE * s + 4);
buf = WFIFOP(fd,0);
for(i=0,n=0,ne=0;i<MAX_GUILD_STORAGE;i++){ const int cmd = ((PACKETVER < 20071002) ? 20 : 26);
if(stor->storage_[i].nameid<=0) buf = (unsigned char*)aMallocA(MAX_GUILD_STORAGE * s + 4);
bufe = (unsigned char*)aMallocA(MAX_GUILD_STORAGE * cmd + 4);
for( i = 0, n = 0, ne = 0; i < MAX_GUILD_STORAGE; i++ )
{
if( stor->storage_[i].nameid <= 0 )
continue; continue;
id = itemdb_search(stor->storage_[i].nameid); id = itemdb_search(stor->storage_[i].nameid);
if(!itemdb_isstackable2(id)) if( !itemdb_isstackable2(id) )
{ //Equippable { //Equippable
WBUFW(bufe,ne*20+4)=i+1; WBUFW(bufe,ne*cmd+4)=i+1;
clif_item_sub(bufe, ne*20+6, &stor->storage_[i], id, id->equip); clif_item_sub(bufe, ne*cmd+6, &stor->storage_[i], id, id->equip);
clif_addcards(WBUFP(bufe, ne*20+16), &stor->storage_[i]); clif_addcards(WBUFP(bufe, ne*cmd+16), &stor->storage_[i]);
if( PACKETVER >= 20071002 )
{
WBUFL(bufe,ne*cmd+24)=stor->storage_[i].expire_time;
WBUFW(bufe,ne*cmd+28)=0; //Unknown
}
ne++; ne++;
} else { //Stackable }
else
{ //Stackable
WBUFW(buf,n*s+4)=i+1; WBUFW(buf,n*s+4)=i+1;
clif_item_sub(buf, n*s+6, &stor->storage_[i], id,-1); clif_item_sub(buf, n*s+6, &stor->storage_[i], id,-1);
#if PACKETVER >= 5 #if PACKETVER >= 5
clif_addcards(WBUFP(buf,n*s+14), &stor->storage_[i]); clif_addcards(WBUFP(buf,n*s+14), &stor->storage_[i]);
#endif
#if PACKETVER >= 20080102
WBUFL(buf,n*s+22)=stor->storage_[i].expire_time;
#endif #endif
n++; n++;
} }
} }
if(n){ if( n )
{
#if PACKETVER < 5 #if PACKETVER < 5
WBUFW(buf,0)=0xa5; WBUFW(buf,0)=0xa5;
#else #else
WBUFW(buf,0)=0x1f0; WBUFW(buf,0)=((PACKETVER < 20080102) ? 0x1f0 : 0x2ea);
#endif #endif
WBUFW(buf,2)=4+n*s; WBUFW(buf,2)=4+n*s;
WFIFOSET(fd,WFIFOW(fd,2)); clif_send(buf, WBUFW(buf,2), &sd->bl, SELF);
} }
if(ne){ if( ne )
WBUFW(bufe,0)=0xa6; {
WBUFW(bufe,2)=4+ne*20; WBUFW(bufe,0)=((PACKETVER < 20071002) ? 0xa6 : 0x2d1);
WBUFW(bufe,2)=4+ne*cmd;
clif_send(bufe, WBUFW(bufe,2), &sd->bl, SELF); clif_send(bufe, WBUFW(bufe,2), &sd->bl, SELF);
} }
if( buf ) aFree(buf);
if( bufe ) aFree(bufe);
} }
void clif_cartlist(struct map_session_data *sd) void clif_cartlist(struct map_session_data *sd)
{ {
struct item_data *id; struct item_data *id;
int i,n,ne,fd=sd->fd; int i,n,ne;
unsigned char *buf; unsigned char *buf;
unsigned char bufe[MAX_CART*20+4]; unsigned char *bufe;
#if PACKETVER < 5 #if PACKETVER < 5
const int s = 10; //Entry size. const int s = 10; //Entry size.
#else #else
const int s = 18; const int s = ((PACKETVER < 20080102) ? 18 : 22);
#endif #endif
WFIFOHEAD(fd, MAX_CART * s + 4);
buf = WFIFOP(fd,0);
for(i=0,n=0,ne=0;i<MAX_CART;i++){ const int cmd = ((PACKETVER<20071002)?20:26);
if(sd->status.cart[i].nameid<=0) buf = (unsigned char*)aMallocA(MAX_CART * s + 4);
bufe = (unsigned char*)aMallocA(MAX_CART * cmd + 4);
for( i = 0, n = 0, ne = 0; i < MAX_CART; i++ )
{
if( sd->status.cart[i].nameid <= 0 )
continue; continue;
id = itemdb_search(sd->status.cart[i].nameid); id = itemdb_search(sd->status.cart[i].nameid);
if(!itemdb_isstackable2(id)) if( !itemdb_isstackable2(id) )
{ //Equippable { //Equippable
WBUFW(bufe,ne*20+4)=i+2; WBUFW(bufe,ne*cmd+4)=i+2;
clif_item_sub(bufe, ne*20+6, &sd->status.cart[i], id, id->equip); clif_item_sub(bufe, ne*cmd+6, &sd->status.cart[i], id, id->equip);
clif_addcards(WBUFP(bufe, ne*20+16), &sd->status.cart[i]); clif_addcards(WBUFP(bufe, ne*cmd+16), &sd->status.cart[i]);
if(PACKETVER >= 20071002)
{
WBUFL(bufe,ne*cmd+24)=sd->status.cart[i].expire_time;
WBUFW(bufe,ne*cmd+28)=0; //Unknown
}
ne++; ne++;
} else { //Stackable }
else
{ //Stackable
WBUFW(buf,n*s+4)=i+2; WBUFW(buf,n*s+4)=i+2;
clif_item_sub(buf, n*s+6, &sd->status.cart[i], id,-1); clif_item_sub(buf, n*s+6, &sd->status.cart[i], id,-1);
#if PACKETVER >= 5 #if PACKETVER >= 5
clif_addcards(WBUFP(buf,n*s+14), &sd->status.cart[i]); clif_addcards(WBUFP(buf,n*s+14), &sd->status.cart[i]);
#endif
#if PACKETVER >= 20080102
WBUFL(buf,n*s+22)=sd->status.cart[i].expire_time;
#endif #endif
n++; n++;
} }
} }
if(n){ if( n )
{
#if PACKETVER < 5 #if PACKETVER < 5
WBUFW(buf,0)=0x123; WBUFW(buf,0)=0x123;
#else #else
WBUFW(buf,0)=0x1ef; WBUFW(buf,0)=((PACKETVER < 20080102) ? 0x1ef : 0x2e9);
#endif #endif
WBUFW(buf,2)=4+n*s; WBUFW(buf,2)=4+n*s;
WFIFOSET(fd,WFIFOW(fd,2)); clif_send(buf, WBUFW(buf,2), &sd->bl, SELF);
} }
if(ne){ if( ne )
WBUFW(bufe,0)=0x122; {
WBUFW(bufe,2)=4+ne*20; WBUFW(bufe,0)=((PACKETVER < 20071002) ? 0x122 : 0x2d2);
WBUFW(bufe,2)=4+ne*cmd;
clif_send(bufe, WBUFW(bufe,2), &sd->bl, SELF); clif_send(bufe, WBUFW(bufe,2), &sd->bl, SELF);
} }
return;
if( buf ) aFree(buf);
if( bufe ) aFree(bufe);
} }
/// Client behaviour: /// Client behaviour:
@ -7652,8 +7741,8 @@ void clif_viewequip_ack(struct map_session_data* sd, struct map_session_data* ts
// Add cards // Add cards
clif_addcards(WFIFOP(fd, n*26+55), &tsd->status.inventory[i]); clif_addcards(WFIFOP(fd, n*26+55), &tsd->status.inventory[i]);
// Expiration date stuff, if all of those are set to 0 then the client doesn't show anything related (6 bytes) // Expiration date stuff, if all of those are set to 0 then the client doesn't show anything related (6 bytes)
memset(WFIFOP(fd, n*26+63), 0, 6); WFIFOL(fd, n*26+63) = tsd->status.inventory[i].expire_time;
WFIFOW(fd, n*26+67) = 0;
n++; n++;
} }
@ -8276,20 +8365,20 @@ void clif_progressbar(struct map_session_data * sd, unsigned long color, unsigne
{ {
int fd = sd->fd; int fd = sd->fd;
WFIFOHEAD(fd,packet_len(0x2f0)); WFIFOHEAD(fd,packet_len(0x2f0));
WFIFOW(fd,0) = 0x2f0; WFIFOW(fd,0) = 0x2f0;
WFIFOL(fd,2) = color; WFIFOL(fd,2) = color;
WFIFOL(fd,6) = second; WFIFOL(fd,6) = second;
WFIFOSET(fd,packet_len(0x2f0)); WFIFOSET(fd,packet_len(0x2f0));
} }
void clif_progressbar_abort(struct map_session_data * sd) void clif_progressbar_abort(struct map_session_data * sd)
{ {
int fd = sd->fd; int fd = sd->fd;
WFIFOHEAD(fd,packet_len(0x2f2)); WFIFOHEAD(fd,packet_len(0x2f2));
WFIFOW(fd,0) = 0x2f2; WFIFOW(fd,0) = 0x2f2;
WFIFOSET(fd,packet_len(0x2f2)); WFIFOSET(fd,packet_len(0x2f2));
} }
void clif_parse_progressbar(int fd, struct map_session_data * sd) void clif_parse_progressbar(int fd, struct map_session_data * sd)
@ -13490,7 +13579,7 @@ static int packetdb_readdb(void)
0, 0, 0,107, 6, 0, 7, 7, 22,191, 0, 0, 0, 0, 0, 0, 0, 0, 0,107, 6, 0, 7, 7, 22,191, 0, 0, 0, 0, 0, 0,
//#0x02C0 //#0x02C0
0, 0, 0, 0, 0, 30, 0, 0, 0, 3, 0, 65, 4, 71, 10, 0, 0, 0, 0, 0, 0, 30, 0, 0, 0, 3, 0, 65, 4, 71, 10, 0,
0, 0, 0, 0, 0, 0, 6, -1, 10, 10, 3, 0, -1, 32, 6, 0, 0, 0, 0, 0, 29, 0, 6, -1, 10, 10, 3, 0, -1, 32, 6, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8,
10, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
//#0x0300 //#0x0300

View File

@ -330,7 +330,7 @@ void pc_inventory_rentals(struct map_session_data *sd)
unsigned int expire_tick, next_tick = UINT_MAX; unsigned int expire_tick, next_tick = UINT_MAX;
for( i = 0; i < MAX_INVENTORY; i++ ) for( i = 0; i < MAX_INVENTORY; i++ )
{ { // Check for Rentals on Inventory
if( sd->status.inventory[i].nameid == 0 ) if( sd->status.inventory[i].nameid == 0 )
continue; // Nothing here continue; // Nothing here
if( sd->status.inventory[i].expire_time == 0 ) if( sd->status.inventory[i].expire_time == 0 )
@ -350,6 +350,48 @@ void pc_inventory_rentals(struct map_session_data *sd)
} }
} }
for( i = 0; i < MAX_CART; i++ )
{ // Check for Rentals on Cart
if( sd->status.cart[i].nameid == 0 )
continue; // Nothing here
if( sd->status.cart[i].expire_time == 0 )
continue;
if( sd->status.cart[i].expire_time <= time(NULL) )
{
clif_rental_expired(sd->fd, sd->status.cart[i].nameid);
pc_cart_delitem(sd, i, 1, 0);
}
else
{
expire_tick = (unsigned int)(sd->status.cart[i].expire_time - time(NULL)) * 1000;
clif_rental_time(sd->fd, sd->status.cart[i].nameid, (int)(expire_tick / 1000));
next_tick = min(expire_tick, next_tick);
c++;
}
}
for( i = 0; i < MAX_STORAGE; i++ )
{ // Check for Rentals on Storage
if( sd->status.storage.items[i].nameid == 0 )
continue;
if( sd->status.storage.items[i].expire_time == 0 )
continue;
if( sd->status.storage.items[i].expire_time <= time(NULL) )
{
clif_rental_expired(sd->fd, sd->status.storage.items[i].nameid);
storage_delitem(sd, i, 1);
}
else
{
expire_tick = (unsigned int)(sd->status.storage.items[i].expire_time - time(NULL)) * 1000;
clif_rental_time(sd->fd, sd->status.storage.items[i].nameid, (int)(expire_tick / 1000));
next_tick = min(expire_tick, next_tick);
c++;
}
}
if( c > 0 ) // min(next_tick,3600000) 1 hour each timer to keep announcing to the owner, and to avoid a but with rental time > 15 days if( c > 0 ) // min(next_tick,3600000) 1 hour each timer to keep announcing to the owner, and to avoid a but with rental time > 15 days
sd->rental_timer = add_timer(gettick() + min(next_tick,3600000), pc_inventory_rental_end, sd->bl.id, 0); sd->rental_timer = add_timer(gettick() + min(next_tick,3600000), pc_inventory_rental_end, sd->bl.id, 0);
else else
@ -374,7 +416,7 @@ void pc_inventory_rental_add(struct map_session_data *sd, int seconds)
} }
} }
else else
sd->rental_timer = add_timer(gettick() + tick, pc_inventory_rental_end, sd->bl.id, 0); sd->rental_timer = add_timer(gettick() + min(tick,3600000), pc_inventory_rental_end, sd->bl.id, 0);
} }
/*========================================== /*==========================================
@ -3603,7 +3645,7 @@ int pc_cart_additem(struct map_session_data *sd,struct item *item_data,int amoun
return 1; return 1;
data = itemdb_search(item_data->nameid); data = itemdb_search(item_data->nameid);
if( item_data->expire_time || !itemdb_cancartstore(item_data, pc_isGM(sd)) ) if( !itemdb_cancartstore(item_data, pc_isGM(sd)) )
{ // Check item trade restrictions [Skotlex] { // Check item trade restrictions [Skotlex]
clif_displaymessage (sd->fd, msg_txt(264)); clif_displaymessage (sd->fd, msg_txt(264));
return 1; return 1;
@ -3686,7 +3728,7 @@ int pc_putitemtocart(struct map_session_data *sd,int idx,int amount)
item_data = &sd->status.inventory[idx]; item_data = &sd->status.inventory[idx];
if( item_data->nameid == 0 || amount < 1 || item_data->amount < amount || sd->vender_id || item_data->expire_time ) if( item_data->nameid == 0 || amount < 1 || item_data->amount < amount || sd->vender_id )
return 1; return 1;
if( pc_cart_additem(sd,item_data,amount) == 0 ) if( pc_cart_additem(sd,item_data,amount) == 0 )
@ -7072,83 +7114,89 @@ int pc_checkitem(struct map_session_data *sd)
nullpo_retr(0, sd); nullpo_retr(0, sd);
if (sd->vender_id) //Avoid reorganizing items when we are vending, as that leads to exploits (pointed out by End of Exam) if( sd->vender_id ) //Avoid reorganizing items when we are vending, as that leads to exploits (pointed out by End of Exam)
return 0; return 0;
// 所持品空き詰め for( i = j = 0; i < MAX_INVENTORY; i++ )
for(i=j=0;i<MAX_INVENTORY;i++){ {
if( (id=sd->status.inventory[i].nameid)==0) if( (id = sd->status.inventory[i].nameid) == 0 )
continue; continue;
if( battle_config.item_check && !itemdb_available(id) ){
if( battle_config.item_check && !itemdb_available(id) )
{
ShowWarning("illegal item id %d in %d[%s] inventory.\n",id,sd->bl.id,sd->status.name); ShowWarning("illegal item id %d in %d[%s] inventory.\n",id,sd->bl.id,sd->status.name);
pc_delitem(sd,i,sd->status.inventory[i].amount,3); pc_delitem(sd,i,sd->status.inventory[i].amount,3);
continue; continue;
} }
if(i>j){ if( i > j )
memcpy(&sd->status.inventory[j],&sd->status.inventory[i],sizeof(struct item)); {
memcpy(&sd->status.inventory[j], &sd->status.inventory[i], sizeof(struct item));
sd->inventory_data[j] = sd->inventory_data[i]; sd->inventory_data[j] = sd->inventory_data[i];
} }
j++; j++;
} }
if(j < MAX_INVENTORY)
memset(&sd->status.inventory[j],0,sizeof(struct item)*(MAX_INVENTORY-j)); if( j < MAX_INVENTORY )
for(k=j;k<MAX_INVENTORY;k++) memset(&sd->status.inventory[j], 0, sizeof(struct item)*(MAX_INVENTORY-j));
for( k = j ; k < MAX_INVENTORY; k++ )
sd->inventory_data[k] = NULL; sd->inventory_data[k] = NULL;
// カ?ト?空き詰め for( i = j = 0; i < MAX_CART; i++ )
for(i=j=0;i<MAX_CART;i++){ {
if( (id=sd->status.cart[i].nameid)==0 ) if( (id=sd->status.cart[i].nameid) == 0 )
continue; continue;
if( battle_config.item_check && !itemdb_available(id) ){ if( battle_config.item_check && !itemdb_available(id) ){
ShowWarning("illegal item id %d in %d[%s] cart.\n",id,sd->bl.id,sd->status.name); ShowWarning("illegal item id %d in %d[%s] cart.\n",id,sd->bl.id,sd->status.name);
pc_cart_delitem(sd,i,sd->status.cart[i].amount,1); pc_cart_delitem(sd,i,sd->status.cart[i].amount,1);
continue; continue;
} }
if(i>j){ if( i > j )
{
memcpy(&sd->status.cart[j],&sd->status.cart[i],sizeof(struct item)); memcpy(&sd->status.cart[j],&sd->status.cart[i],sizeof(struct item));
} }
j++; j++;
} }
if(j < MAX_CART) if( j < MAX_CART )
memset(&sd->status.cart[j],0,sizeof(struct item)*(MAX_CART-j)); memset(&sd->status.cart[j],0,sizeof(struct item)*(MAX_CART-j));
// ? 備位置チェック for( i = 0; i < MAX_INVENTORY; i++)
{
it = sd->inventory_data[i];
for(i=0;i<MAX_INVENTORY;i++){ if( sd->status.inventory[i].nameid == 0 )
it=sd->inventory_data[i];
if(sd->status.inventory[i].nameid==0)
continue; continue;
if(!sd->status.inventory[i].equip) if( !sd->status.inventory[i].equip )
continue; continue;
if(sd->status.inventory[i].equip&~pc_equippoint(sd,i)) { if( sd->status.inventory[i].equip&~pc_equippoint(sd,i) )
sd->status.inventory[i].equip=0; {
pc_unequipitem(sd, i, 2);
calc_flag = 1; calc_flag = 1;
continue; continue;
} }
if(it) {
//check for forbiden items. if( it )
{ // check for forbiden items.
int flag = int flag =
(map[sd->bl.m].flag.restricted?map[sd->bl.m].zone:0) (map[sd->bl.m].flag.restricted?map[sd->bl.m].zone:0)
| (map[sd->bl.m].flag.pvp?1:0) | (map[sd->bl.m].flag.pvp?1:0)
| (map_flag_gvg(sd->bl.m)?2:0); | (map_flag_gvg(sd->bl.m)?2:0);
if (flag && (it->flag.no_equip&flag || !pc_isAllowedCardOn(sd,it->slot,i,flag))) if( flag && (it->flag.no_equip&flag || !pc_isAllowedCardOn(sd,it->slot,i,flag)) )
{ {
sd->status.inventory[i].equip=0; pc_unequipitem(sd, i, 2);
calc_flag = 1; calc_flag = 1;
} }
} }
} }
pc_setequipindex(sd); pc_setequipindex(sd);
if(calc_flag && sd->state.active) if( calc_flag && sd->state.active )
{ {
pc_checkallowskill(sd);
status_calc_pc(sd,0); status_calc_pc(sd,0);
pc_equiplookall(sd);
} }
return 0; return 0;
} }

View File

@ -6246,6 +6246,7 @@ int status_change_clear(struct block_list* bl, int type)
case SC_ITEMBOOST: case SC_ITEMBOOST:
case SC_HELLPOWER: case SC_HELLPOWER:
case SC_JEXPBOOST: case SC_JEXPBOOST:
case SC_AUTOTRADE:
continue; continue;
} }

View File

@ -182,7 +182,7 @@ static int storage_additem(struct map_session_data* sd, struct item* item_data,
/*========================================== /*==========================================
* Internal del-item function * Internal del-item function
*------------------------------------------*/ *------------------------------------------*/
static int storage_delitem(struct map_session_data* sd, int n, int amount) 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->status.storage.items[n].nameid == 0 || sd->status.storage.items[n].amount < amount )
return 1; return 1;
@ -196,9 +196,9 @@ static int storage_delitem(struct map_session_data* sd, int n, int amount)
{ {
memset(&sd->status.storage.items[n],0,sizeof(sd->status.storage.items[0])); memset(&sd->status.storage.items[n],0,sizeof(sd->status.storage.items[0]));
sd->status.storage.storage_amount--; sd->status.storage.storage_amount--;
clif_updatestorageamount(sd,sd->status.storage.storage_amount); if( sd->state.storage_flag == 1 ) clif_updatestorageamount(sd,sd->status.storage.storage_amount);
} }
clif_storageitemremoved(sd,n,amount); if( sd->state.storage_flag == 1 ) clif_storageitemremoved(sd,n,amount);
return 0; return 0;
} }
@ -218,9 +218,6 @@ int storage_storageadd(struct map_session_data* sd, int index, int amount)
if( sd->status.inventory[index].nameid <= 0 ) if( sd->status.inventory[index].nameid <= 0 )
return 0; // No item on that spot return 0; // No item on that spot
if( sd->status.inventory[index].expire_time )
return 0; // Cannot Store Rental Items
if( amount < 1 || amount > sd->status.inventory[index].amount ) if( amount < 1 || amount > sd->status.inventory[index].amount )
return 0; return 0;
@ -270,9 +267,6 @@ int storage_storageaddfromcart(struct map_session_data* sd, int index, int amoun
if( sd->status.cart[index].nameid <= 0 ) if( sd->status.cart[index].nameid <= 0 )
return 0; //No item there. return 0; //No item there.
if( sd->status.inventory[index].expire_time )
return 0; // Cannot Store Rental Items
if( amount < 1 || amount > sd->status.cart[index].amount ) if( amount < 1 || amount > sd->status.cart[index].amount )
return 0; return 0;

View File

@ -11,6 +11,7 @@ struct item;
//#include "map.h" //#include "map.h"
struct map_session_data; struct map_session_data;
int storage_delitem(struct map_session_data* sd, int n, int amount);
int storage_storageopen(struct map_session_data *sd); int storage_storageopen(struct map_session_data *sd);
int storage_storageadd(struct map_session_data *sd,int index,int amount); int storage_storageadd(struct map_session_data *sd,int index,int amount);
int storage_storageget(struct map_session_data *sd,int index,int amount); int storage_storageget(struct map_session_data *sd,int index,int amount);