//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
\\########################################################################################//
//###################################### CaaliSoft-Rose ######################################\\
\\########################################################################################//
//##################################### (c)2006 by Caali #####################################\\
\\########################################################################################//
//########################################################################################\\
\\####################### Description: "This file adds the full support of [MyStorage]." #########################//
//########################################################################################\\
\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//
// -----------------------------------------------------------------------------
// in worldpackets.cpp, add
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// Open [MyStorage] (c)2006 by Caali
// -----------------------------------------------------------------------------
bool CWorldServer::pakOpenStorage(CWorldClient* thisclient, CPacket* P)
{
unsigned itemcount = 0;
for(unsigned i=0;i<160;i++){ if( thisclient->storage.items[i].count > 0 ) { itemcount++; } }
BEGINPACKET( pak, 0x7ad );
ADDBYTE( pak, 0x00 ); //dunno
ADDBYTE( pak, itemcount ); //itemcount
for(unsigned i=0;i<160;i++)
{
if( thisclient->storage.items[i].count>0 )
{
ADDBYTE( pak, i ); //slot
ADDDWORD( pak, BuildItemHead( thisclient->storage.items[i] ) ); //head
ADDDWORD( pak, BuildItemData( thisclient->storage.items[i] ) ); //data
}
}
ADDQWORD( pak, thisclient->storage.zuly ); //zuly
thisclient->SendPacket( &pak );
return true;
}
// -----------------------------------------------------------------------------
// Zuly at [MyStorage] (c)2006 by Caali
// -----------------------------------------------------------------------------
bool CWorldServer::pakStorageZuly(CWorldClient* thisclient, CPacket* P)
{
unsigned char mode = GETBYTE( (*P), 0x00 );
switch( mode )
{
case 0x10: //Deposit Zuly
{
long long amount = GETQWORD( (*P), 0x01 );
if( amount > thisclient->c_zuly ) return true;
thisclient->c_zuly -= amount;
thisclient->storage.zuly += amount;
BEGINPACKET( pak, 0x7da );
ADDQWORD( pak, thisclient->c_zuly );
ADDQWORD( pak, thisclient->storage.zuly );
thisclient->SendPacket( &pak );
}
break;
case 0x11: //Withdraw Zuly
{
long long amount = GETQWORD( (*P), 0x01 );
if( amount > thisclient->storage.zuly ) return true;
thisclient->c_zuly += amount;
thisclient->storage.zuly -= amount;
BEGINPACKET( pak, 0x7da );
ADDQWORD( pak, thisclient->c_zuly );
ADDQWORD( pak, thisclient->storage.zuly );
thisclient->SendPacket( &pak );
}
break;
}
return true;
}
// -----------------------------------------------------------------------------
// Item at [MyStorage] (c)2006 by Caali
// -----------------------------------------------------------------------------
bool CWorldServer::pakStorageItem(CWorldClient* thisclient, CPacket* P)
{
unsigned char mode = GETBYTE( (*P), 0x00 ); //00: Deposit 01: Withdraw
switch( mode )
{
case 0x00: //Deposit an item
{
unsigned char inventoryslot = GETBYTE( (*P), 0x01 );
unsigned char storageslot = thisclient->GetNewStorageItemSlot( thisclient->items[inventoryslot] );
unsigned amount;
if( thisclient->items[inventoryslot].itemtype < 10 && thisclient->items[inventoryslot].itemtype > 12 )
{
amount = 1;
}
else
{
amount = GETDWORD( (*P), 0x06 );
}
if( amount <= 0 ) return true;
if( amount > 999 ) amount = 1;
long long storagefee = STB_ITEM[thisclient->items[inventoryslot].itemtype-1].rows[thisclient->items[inventoryslot].itemnum][5]*amount/200;
if( storagefee > thisclient->c_zuly ) return true;
if( storageslot == 0xffff ) return true;
if( thisclient->items[inventoryslot].itemtype >= 10 && thisclient->items[inventoryslot].itemtype <= 12 )
{
if( thisclient->storage.items[storageslot].count > 0 )
{
thisclient->storage.items[storageslot].count += amount;
}
else
{
thisclient->storage.items[storageslot] = thisclient->items[inventoryslot];
thisclient->storage.items[storageslot].count = amount;
}
unsigned tmpcount;
if( thisclient->storage.items[storageslot].count > 999 )
{
tmpcount = thisclient->storage.items[storageslot].count-999;
thisclient->storage.items[storageslot].count = 999;
}
else
{
tmpcount = 0;
}
thisclient->items[inventoryslot].count -= (amount-tmpcount);
}
else
{
thisclient->storage.items[storageslot] = thisclient->items[inventoryslot];
thisclient->storage.items[storageslot].count = 1;
thisclient->items[inventoryslot].count = 0;
}
if(thisclient->items[inventoryslot].count <= 0) ClearItem(thisclient->items[inventoryslot]);
thisclient->c_zuly -= storagefee;
BEGINPACKET( pak, 0x7ae );
ADDBYTE( pak, inventoryslot ); //inventory-slot
ADDBYTE( pak, 0x00 ); //??
ADDBYTE( pak, storageslot ); //storage-slot
ADDBYTE( pak, 0x00 ); //??
ADDDWORD( pak, BuildItemHead( thisclient->items[inventoryslot] ) ); //inventory-itemhead
ADDDWORD( pak, BuildItemData( thisclient->items[inventoryslot] ) ); //inventory-amount
ADDDWORD( pak, BuildItemHead( thisclient->storage.items[storageslot] ) ); //storage-itemhead
ADDDWORD( pak, BuildItemData( thisclient->storage.items[storageslot] ) ); //storage-amount
ADDQWORD( pak, thisclient->c_zuly ); //zuly
thisclient->SendPacket( &pak );
}
break;
case 0x01: //Withdraw an item
{
unsigned char storageslot = GETBYTE( (*P), 0x01 );
unsigned char inventoryslot = thisclient->GetNewItemSlot( thisclient->storage.items[storageslot] );
if(inventoryslot == 0xffff) return true;
unsigned amount;
if( thisclient->storage.items[storageslot].itemtype < 10 && thisclient->storage.items[storageslot].itemtype > 12 )
{
amount = 1;
}
else
{
amount = GETDWORD( (*P), 0x06 );
}
if( amount <= 0 ) return true;
if( amount > 999 ) amount = 1;
if( thisclient->storage.items[storageslot].itemtype >= 10 && thisclient->storage.items[storageslot].itemtype <= 12 )
{
if( thisclient->items[inventoryslot].count > 0 )
{
thisclient->items[inventoryslot].count += amount;
}
else
{
thisclient->items[inventoryslot] = thisclient->storage.items[storageslot];
thisclient->items[inventoryslot].count = amount;
}
unsigned tmpcount;
if( thisclient->items[inventoryslot].count > 999 )
{
tmpcount = thisclient->items[inventoryslot].count-999;
thisclient->items[inventoryslot].count = 999;
}
else
{
tmpcount = 0;
}
thisclient->storage.items[storageslot].count -= (amount-tmpcount);
}
else
{
thisclient->items[inventoryslot] = thisclient->storage.items[storageslot];
thisclient->items[inventoryslot].count = 1;
thisclient->storage.items[storageslot].count = 0;
}
if(thisclient->items[inventoryslot].count > 999) thisclient->items[inventoryslot].count = 999;
if(thisclient->storage.items[storageslot].count <= 0) ClearItem(thisclient->storage.items[storageslot]);
BEGINPACKET( pak, 0x7ae );
ADDBYTE( pak, inventoryslot ); //inventory-slot
ADDBYTE( pak, 0x00 ); //??
ADDBYTE( pak, storageslot ); //storage-slot
ADDBYTE( pak, 0x00 ); //??
ADDDWORD( pak, BuildItemHead( thisclient->items[inventoryslot] ) ); //inventory-itemhead
ADDDWORD( pak, BuildItemData( thisclient->items[inventoryslot] ) ); //inventory-amount
ADDDWORD( pak, BuildItemHead( thisclient->storage.items[storageslot] ) ); //storage-itemhead
ADDDWORD( pak, BuildItemData( thisclient->storage.items[storageslot] ) ); //storage-amount
ADDQWORD( pak, thisclient->c_zuly ); //zuly
thisclient->SendPacket( &pak );
}
break;
}
return true;
}
// -----------------------------------------------------------------------------
// in datatypes.h, add
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// A player-storage (c)2006 by Caali
// -----------------------------------------------------------------------------
struct CStorage {
long long zuly;
CItem items[160]; //40 per page
};
// -----------------------------------------------------------------------------
// in WorldServer.cpp, at OnRecievePacket, add
// -----------------------------------------------------------------------------
case 0x07ad: return pakOpenStorage ((CWorldClient*)thisclient, P);
case 0x07ae: return pakStorageItem ((CWorldClient*)thisclient, P);
case 0x07da: return pakStorageZuly ((CWorldClient*)thisclient, P);
// -----------------------------------------------------------------------------
// in worldsockets.h, find
// -----------------------------------------------------------------------------
unsigned GetNewItemSlot( CItem thisitem );
// -----------------------------------------------------------------------------
// after, add
// -----------------------------------------------------------------------------
unsigned GetNewStorageItemSlot( CItem thisitem );
bool platinum;
CStorage storage;
// -----------------------------------------------------------------------------
// in worldsockets.h, find
// -----------------------------------------------------------------------------
void pakCreate71b ( CWorldClient *thisclient );
// -----------------------------------------------------------------------------
// after, add
// -----------------------------------------------------------------------------
bool pakOpenStorage ( CWorldClient* thisclient, CPacket* P );
bool pakStorageZuly ( CWorldClient* thisclient, CPacket* P );
bool pakStorageItem ( CWorldClient* thisclient, CPacket* P );
// -----------------------------------------------------------------------------
// in worldclient.cpp, go to CWorldClient::loaddata()
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// at the functions bottom, add
// -----------------------------------------------------------------------------
ParentServer->DoSQL("SELECT storage_zuly,platinum FROM accounts WHERE id=%i", userid );
result = mysql_store_result( ParentServer->mysql );
row = mysql_fetch_row( result );
storage.zuly = atoi( row[0] );
switch(atoi(row[1]))
{
case 0: platinum = false;
case 1: platinum = true;
default: platinum = false;
}
mysql_free_result(result);
ParentServer->DoSQL("SELECT slotnum, itemnum, itemtype, refine, durability, lifespan, count, stats, socketed, appraised FROM storage WHERE accountid=%i", userid );
result = mysql_store_result( ParentServer->mysql );
while(row = mysql_fetch_row(result)) {
unsigned slotnum = atoi(row[0]);
storage.items[slotnum].itemnum = atoi(row[1]);
storage.items[slotnum].itemtype = atoi(row[2]);
storage.items[slotnum].refine = atoi(row[3]);
storage.items[slotnum].durability = atoi(row[4]);
storage.items[slotnum].lifespan = atoi(row[5]);
storage.items[slotnum].count = atoi(row[6]);
storage.items[slotnum].stats = atoi(row[7]);
storage.items[slotnum].socketed = (atoi(row[8])==1)?true:false;
storage.items[slotnum].appraised = (atoi(row[9])==1)?true:false;
}
mysql_free_result(result);
// -----------------------------------------------------------------------------
// in worldclient.cpp, go to CWorldClient::savedata()
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// at the functions bottom, add
// -----------------------------------------------------------------------------
ParentServer->DoSQL("UPDATE accounts SET storage_zuly=%llu WHERE id=%i", this->storage.zuly, this->userid );
ParentServer->DoSQL("DELETE FROM storage WHERE accountid=%i", this->userid );
for(unsigned i=0;i<160;i++) {
if (this->storage.items[i].itemtype != 0) {
ParentServer->DoSQL("INSERT INTO storage (accountid,itemnum,itemtype,refine,durability,lifespan, \
slotnum,count,stats,socketed,appraised) VALUES(%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i)", \
this->userid, this->storage.items[i].itemnum, this->storage.items[i].itemtype,this->storage.items[i].refine, this->storage.items[i].durability, \
this->storage.items[i].lifespan, i, this->storage.items[i].count, this->storage.items[i].stats, (this->storage.items[i].socketed?1:0), (this->storage.items[i].appraised?1:0));
}
}
// -----------------------------------------------------------------------------
// in worldclient.cpp, go to the end of file and add
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// Returns the id of an empty storage slot based on item type, 0xffff if no such slot exists (c)2006 by Caali
// -----------------------------------------------------------------------------
unsigned CWorldClient::GetNewStorageItemSlot(CItem thisitem)
{
char itemtypes[15] = {4,0,0,0,0,0,0,0,0,0,1,2,2,4,3};
unsigned char itemtab = itemtypes[thisitem.itemtype];
if (itemtab >= 4) return 0xffff;
if (thisitem.itemtype >= 10 && thisitem.itemtype <= 13) //Stackable
{
for(unsigned j = 0; j < 160; j++)
{
if ((storage.items[j].itemnum == thisitem.itemnum && storage.items[j].itemtype == thisitem.itemtype && storage.items[j].count < 999))
{
if( j < 120 || (j > 119 && platinum) )
return j;
}
}
}
for(unsigned j = 0; j < 160; j++)
{
if (storage.items[j].itemnum == 0)
{
if( j < 120 || (j > 119 && platinum) )
return j;
}
}
return 0xffff;
}