Initial support for newer packet versions (#4944)
Basic support for packets up to April 2020 Changing the default packet version to 2020-04-01 Thanks to everyone involved!
This commit is contained in:
parent
929c30c414
commit
45cd5808b7
@ -138,3 +138,10 @@ spawn_direction: no
|
||||
// kRO removed the packet and this re-enables the message.
|
||||
// Official: Disabled.
|
||||
mvp_exp_reward_message: no
|
||||
|
||||
// Send ping timer
|
||||
// Interval in seconds for each timer invoke.
|
||||
ping_timer_inverval: 30
|
||||
|
||||
// Send packets timeout in seconds before ping packet can be sent.
|
||||
ping_time: 20
|
||||
|
@ -254,6 +254,7 @@ CREATE TABLE IF NOT EXISTS `char` (
|
||||
`uniqueitem_counter` int(11) unsigned NOT NULL default '0',
|
||||
`sex` ENUM('M','F','U') NOT NULL default 'U',
|
||||
`hotkey_rowshift` tinyint(3) unsigned NOT NULL default '0',
|
||||
`hotkey_rowshift2` tinyint(3) unsigned NOT NULL default '0',
|
||||
`clan_id` int(11) unsigned NOT NULL default '0',
|
||||
`last_login` datetime DEFAULT NULL,
|
||||
`title_id` INT(11) unsigned NOT NULL default '0',
|
||||
|
1
sql-files/upgrades/upgrade_20200603.sql
Normal file
1
sql-files/upgrades/upgrade_20200603.sql
Normal file
@ -0,0 +1 @@
|
||||
ALTER TABLE `char` ADD COLUMN `hotkey_rowshift2` TINYINT(3) UNSIGNED NOT NULL DEFAULT '0' AFTER `hotkey_rowshift`;
|
@ -299,7 +299,7 @@ int char_mmo_char_tosql(uint32 char_id, struct mmo_charstatus* p){
|
||||
(p->rename != cp->rename) || (p->robe != cp->robe) || (p->character_moves != cp->character_moves) ||
|
||||
(p->unban_time != cp->unban_time) || (p->font != cp->font) || (p->uniqueitem_counter != cp->uniqueitem_counter) ||
|
||||
(p->hotkey_rowshift != cp->hotkey_rowshift) || (p->clan_id != cp->clan_id ) || (p->title_id != cp->title_id) ||
|
||||
(p->show_equip != cp->show_equip)
|
||||
(p->show_equip != cp->show_equip) || (p->hotkey_rowshift2 != cp->hotkey_rowshift2)
|
||||
)
|
||||
{ //Save status
|
||||
if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `base_level`='%d', `job_level`='%d',"
|
||||
@ -310,7 +310,7 @@ int char_mmo_char_tosql(uint32 char_id, struct mmo_charstatus* p){
|
||||
"`weapon`='%d',`shield`='%d',`head_top`='%d',`head_mid`='%d',`head_bottom`='%d',"
|
||||
"`last_map`='%s',`last_x`='%d',`last_y`='%d',`save_map`='%s',`save_x`='%d',`save_y`='%d', `rename`='%d',"
|
||||
"`delete_date`='%lu',`robe`='%d',`moves`='%d',`font`='%u',`uniqueitem_counter`='%u',"
|
||||
"`hotkey_rowshift`='%d', `clan_id`='%d', `title_id`='%lu', `show_equip`='%d'"
|
||||
"`hotkey_rowshift`='%d', `clan_id`='%d', `title_id`='%lu', `show_equip`='%d', `hotkey_rowshift2`='%d'"
|
||||
" WHERE `account_id`='%d' AND `char_id` = '%d'",
|
||||
schema_config.char_db, p->base_level, p->job_level,
|
||||
p->base_exp, p->job_exp, p->zeny,
|
||||
@ -322,7 +322,7 @@ int char_mmo_char_tosql(uint32 char_id, struct mmo_charstatus* p){
|
||||
mapindex_id2name(p->save_point.map), p->save_point.x, p->save_point.y, p->rename,
|
||||
(unsigned long)p->delete_date, // FIXME: platform-dependent size
|
||||
p->robe, p->character_moves, p->font, p->uniqueitem_counter,
|
||||
p->hotkey_rowshift, p->clan_id, p->title_id, p->show_equip,
|
||||
p->hotkey_rowshift, p->clan_id, p->title_id, p->show_equip, p->hotkey_rowshift2,
|
||||
p->account_id, p->char_id) )
|
||||
{
|
||||
Sql_ShowDebug(sql_handle);
|
||||
@ -924,7 +924,8 @@ int char_mmo_chars_fromsql(struct char_session_data* sd, uint8* buf, uint8* coun
|
||||
"`str`,`agi`,`vit`,`int`,`dex`,`luk`,`max_hp`,`hp`,`max_sp`,`sp`,"
|
||||
"`status_point`,`skill_point`,`option`,`karma`,`manner`,`hair`,`hair_color`,"
|
||||
"`clothes_color`,`body`,`weapon`,`shield`,`head_top`,`head_mid`,`head_bottom`,`last_map`,`rename`,`delete_date`,"
|
||||
"`robe`,`moves`,`unban_time`,`font`,`uniqueitem_counter`,`sex`,`hotkey_rowshift`,`title_id`,`show_equip`"
|
||||
"`robe`,`moves`,`unban_time`,`font`,`uniqueitem_counter`,`sex`,`hotkey_rowshift`,`title_id`,`show_equip`,"
|
||||
"`hotkey_rowshift2`"
|
||||
" FROM `%s` WHERE `account_id`='%d' AND `char_num` < '%d'", schema_config.char_db, sd->account_id, MAX_CHARS)
|
||||
|| SQL_ERROR == SqlStmt_Execute(stmt)
|
||||
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 0, SQLDT_INT, &p.char_id, 0, NULL, NULL)
|
||||
@ -972,6 +973,7 @@ int char_mmo_chars_fromsql(struct char_session_data* sd, uint8* buf, uint8* coun
|
||||
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 42, SQLDT_UCHAR, &p.hotkey_rowshift, 0, NULL, NULL)
|
||||
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 43, SQLDT_ULONG, &p.title_id, 0, NULL, NULL)
|
||||
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 44, SQLDT_UINT16, &p.show_equip, 0, NULL, NULL)
|
||||
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 45, SQLDT_UCHAR, &p.hotkey_rowshift2, 0, NULL, NULL)
|
||||
)
|
||||
{
|
||||
SqlStmt_ShowDebug(stmt);
|
||||
@ -1039,7 +1041,7 @@ int char_mmo_char_fromsql(uint32 char_id, struct mmo_charstatus* p, bool load_ev
|
||||
"`status_point`,`skill_point`,`option`,`karma`,`manner`,`party_id`,`guild_id`,`pet_id`,`homun_id`,`elemental_id`,`hair`,"
|
||||
"`hair_color`,`clothes_color`,`body`,`weapon`,`shield`,`head_top`,`head_mid`,`head_bottom`,`last_map`,`last_x`,`last_y`,"
|
||||
"`save_map`,`save_x`,`save_y`,`partner_id`,`father`,`mother`,`child`,`fame`,`rename`,`delete_date`,`robe`, `moves`,"
|
||||
"`unban_time`,`font`,`uniqueitem_counter`,`sex`,`hotkey_rowshift`,`clan_id`,`title_id`,`show_equip`"
|
||||
"`unban_time`,`font`,`uniqueitem_counter`,`sex`,`hotkey_rowshift`,`clan_id`,`title_id`,`show_equip`,`hotkey_rowshift2`"
|
||||
" FROM `%s` WHERE `char_id`=? LIMIT 1", schema_config.char_db)
|
||||
|| SQL_ERROR == SqlStmt_BindParam(stmt, 0, SQLDT_INT, &char_id, 0)
|
||||
|| SQL_ERROR == SqlStmt_Execute(stmt)
|
||||
@ -1105,6 +1107,7 @@ int char_mmo_char_fromsql(uint32 char_id, struct mmo_charstatus* p, bool load_ev
|
||||
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 59, SQLDT_INT, &p->clan_id, 0, NULL, NULL)
|
||||
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 60, SQLDT_ULONG, &p->title_id, 0, NULL, NULL)
|
||||
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 61, SQLDT_UINT16, &p->show_equip, 0, NULL, NULL)
|
||||
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 62, SQLDT_UCHAR, &p->hotkey_rowshift2, 0, NULL, NULL)
|
||||
)
|
||||
{
|
||||
SqlStmt_ShowDebug(stmt);
|
||||
@ -1211,7 +1214,7 @@ int char_mmo_char_fromsql(uint32 char_id, struct mmo_charstatus* p, bool load_ev
|
||||
|
||||
while( SQL_SUCCESS == SqlStmt_NextRow(stmt) )
|
||||
{
|
||||
if( hotkey_num >= 0 && hotkey_num < MAX_HOTKEYS )
|
||||
if( hotkey_num >= 0 && hotkey_num < MAX_HOTKEYS_DB )
|
||||
memcpy(&p->hotkeys[hotkey_num], &tmp_hotkey, sizeof(tmp_hotkey));
|
||||
else
|
||||
ShowWarning("mmo_char_fromsql: ignoring invalid hotkey (hotkey=%d,type=%u,id=%u,lv=%u) of character %s (AID=%d,CID=%d)\n", hotkey_num, tmp_hotkey.type, tmp_hotkey.id, tmp_hotkey.lv, p->name, p->account_id, p->char_id);
|
||||
@ -2318,7 +2321,8 @@ bool char_checkdb(void){
|
||||
"`guild_id`,`pet_id`,`homun_id`,`elemental_id`,`hair`,`hair_color`,`clothes_color`,`weapon`,"
|
||||
"`shield`,`head_top`,`head_mid`,`head_bottom`,`robe`,`last_map`,`last_x`,`last_y`,`save_map`,"
|
||||
"`save_x`,`save_y`,`partner_id`,`online`,`father`,`mother`,`child`,`fame`,`rename`,`delete_date`,"
|
||||
"`moves`,`unban_time`,`font`,`sex`,`hotkey_rowshift`,`clan_id`,`last_login`,`title_id`,`show_equip`"
|
||||
"`moves`,`unban_time`,`font`,`sex`,`hotkey_rowshift`,`clan_id`,`last_login`,`title_id`,`show_equip`,"
|
||||
"`hotkey_rowshift2`"
|
||||
" FROM `%s` LIMIT 1;", schema_config.char_db) ){
|
||||
Sql_ShowDebug(sql_handle);
|
||||
return false;
|
||||
|
@ -33,6 +33,12 @@
|
||||
#define MAX_HOTKEYS 38
|
||||
#endif
|
||||
|
||||
#if PACKETVER_MAIN_NUM >= 20190522 || PACKETVER_RE_NUM >= 20190508 || PACKETVER_ZERO_NUM >= 20190605
|
||||
#define MAX_HOTKEYS_DB ((MAX_HOTKEYS) * 2)
|
||||
#else
|
||||
#define MAX_HOTKEYS_DB MAX_HOTKEYS
|
||||
#endif
|
||||
|
||||
#define MAX_MAP_PER_SERVER 1500 /// Maximum amount of maps available on a server
|
||||
#define MAX_INVENTORY 100 ///Maximum items in player inventory
|
||||
/** Max number of characters per account. Note that changing this setting alone is not enough if the client is not hexed to support more characters as well.
|
||||
@ -518,7 +524,7 @@ struct mmo_charstatus {
|
||||
|
||||
struct s_friend friends[MAX_FRIENDS]; //New friend system [Skotlex]
|
||||
#ifdef HOTKEY_SAVING
|
||||
struct hotkey hotkeys[MAX_HOTKEYS];
|
||||
struct hotkey hotkeys[MAX_HOTKEYS_DB];
|
||||
#endif
|
||||
bool show_equip,allow_party;
|
||||
short rename;
|
||||
@ -536,6 +542,7 @@ struct mmo_charstatus {
|
||||
uint32 uniqueitem_counter;
|
||||
|
||||
unsigned char hotkey_rowshift;
|
||||
unsigned char hotkey_rowshift2;
|
||||
unsigned long title_id;
|
||||
};
|
||||
|
||||
|
@ -428,6 +428,8 @@ int send_from_fifo(int fd)
|
||||
|
||||
if( len > 0 )
|
||||
{
|
||||
session[fd]->wdata_tick = last_tick;
|
||||
|
||||
// some data could not be transferred?
|
||||
// shift unsent data to the beginning of the queue
|
||||
if( (size_t)len < session[fd]->wdata_size )
|
||||
@ -587,6 +589,7 @@ int make_listen_bind(uint32 ip, uint16 port)
|
||||
create_session(fd, connect_client, null_send, null_parse);
|
||||
session[fd]->client_addr = 0; // just listens
|
||||
session[fd]->rdata_tick = 0; // disable timeouts on this socket
|
||||
session[fd]->wdata_tick = 0;
|
||||
|
||||
return fd;
|
||||
}
|
||||
@ -727,6 +730,7 @@ static int create_session(int fd, RecvFunc func_recv, SendFunc func_send, ParseF
|
||||
session[fd]->func_send = func_send;
|
||||
session[fd]->func_parse = func_parse;
|
||||
session[fd]->rdata_tick = last_tick;
|
||||
session[fd]->wdata_tick = last_tick;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -98,6 +98,7 @@ struct socket_data
|
||||
size_t rdata_size, wdata_size;
|
||||
size_t rdata_pos;
|
||||
time_t rdata_tick; // time of last recv (for detecting timeouts); zero when timeout is disabled
|
||||
time_t wdata_tick; // time of last send (for detecting timeouts);
|
||||
|
||||
RecvFunc func_recv;
|
||||
SendFunc func_send;
|
||||
|
@ -13,7 +13,7 @@
|
||||
/// Do NOT edit this line! To set your client version, please do this instead:
|
||||
/// In Windows: Add this line in your src\custom\defines_pre.hpp file: #define PACKETVER YYYYMMDD
|
||||
/// In Linux: The same as above or run the following command: ./configure --enable-packetver=YYYYMMDD
|
||||
#define PACKETVER 20180620
|
||||
#define PACKETVER 20200401
|
||||
#endif
|
||||
|
||||
#ifndef PACKETVER_RE
|
||||
@ -24,6 +24,23 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef PACKETVER_RE
|
||||
#define PACKETVER_MAIN_NUM PACKETVER
|
||||
|
||||
// Undefine all sakray server definitions
|
||||
#undef PACKETVER_RE
|
||||
#undef PACKETVER_RE_NUM
|
||||
#else
|
||||
// Undefine existing definition
|
||||
#undef PACKETVER_RE
|
||||
|
||||
#define PACKETVER_RE PACKETVER
|
||||
#define PACKETVER_RE_NUM PACKETVER
|
||||
|
||||
// Undefine all main server definitions
|
||||
#undef PACKETVER_MAIN_NUM
|
||||
#endif
|
||||
|
||||
#if PACKETVER >= 20110817
|
||||
/// Comment to disable the official packet obfuscation support.
|
||||
/// This requires PACKETVER 2011-08-17 or newer.
|
||||
|
@ -457,6 +457,20 @@ static int logclif_parse_reqcharconnec(int fd, struct login_session_data *sd, ch
|
||||
return 1;
|
||||
}
|
||||
|
||||
int logclif_parse_otp_login( int fd, struct login_session_data* sd ){
|
||||
RFIFOSKIP( fd, 68 );
|
||||
|
||||
WFIFOHEAD( fd, 34 );
|
||||
WFIFOW( fd, 0 ) = 0xae3;
|
||||
WFIFOW( fd, 2 ) = 34;
|
||||
WFIFOL( fd, 4 ) = 0; // normal login
|
||||
safestrncpy( WFIFOCP( fd, 8 ), "S1000", 6 );
|
||||
safestrncpy( WFIFOCP( fd, 28 ), "token", 6 );
|
||||
WFIFOSET( fd, 34 );
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Entry point from client to log-server.
|
||||
* Function that checks incoming command, then splits it to the correct handler.
|
||||
@ -521,6 +535,10 @@ int logclif_parse(int fd) {
|
||||
break;
|
||||
// Sending request of the coding key
|
||||
case 0x01db: next = logclif_parse_reqkey(fd, sd); break;
|
||||
// OTP token login
|
||||
case 0x0acf:
|
||||
next = logclif_parse_otp_login( fd, sd );
|
||||
break;
|
||||
// Connection request of a char-server
|
||||
case 0x2710: logclif_parse_reqcharconnec(fd,sd, ip); return 0; // processing will continue elsewhere
|
||||
default:
|
||||
|
@ -8954,6 +8954,8 @@ static const struct _battle_data {
|
||||
{ "bgqueue_nowarp_mapflag", &battle_config.bgqueue_nowarp_mapflag, 0, 0, 1, },
|
||||
{ "homunculus_exp_gain", &battle_config.homunculus_exp_gain, 10, 0, 100, },
|
||||
{ "rental_item_novalue", &battle_config.rental_item_novalue, 1, 0, 1, },
|
||||
{ "ping_timer_inverval", &battle_config.ping_timer_interval, 30, 0, 99999999, },
|
||||
{ "ping_time", &battle_config.ping_time, 20, 0, 99999999, },
|
||||
|
||||
#include "../custom/battle_config_init.inc"
|
||||
};
|
||||
|
@ -678,6 +678,8 @@ struct Battle_Config
|
||||
int bgqueue_nowarp_mapflag;
|
||||
int homunculus_exp_gain;
|
||||
int rental_item_novalue;
|
||||
int ping_timer_interval;
|
||||
int ping_time;
|
||||
|
||||
#include "../custom/battle_config_struct.inc"
|
||||
};
|
||||
|
@ -113,8 +113,7 @@ int8 buyingstore_setup(struct map_session_data* sd, unsigned char slots){
|
||||
* @param at Autotrader info, or NULL if requetsed not from autotrade persistance
|
||||
* @return 0 If success, 1 - Cannot open, 2 - Manner penalty, 3 - Mapflag restiction, 4 - Cell restriction, 5 - Invalid count/result, 6 - Cannot give item, 7 - Will be overweight
|
||||
*/
|
||||
int8 buyingstore_create(struct map_session_data* sd, int zenylimit, unsigned char result, const char* storename, const uint8* itemlist, unsigned int count, struct s_autotrader *at)
|
||||
{
|
||||
int8 buyingstore_create( struct map_session_data* sd, int zenylimit, unsigned char result, const char* storename, const struct PACKET_CZ_REQ_OPEN_BUYING_STORE_sub* itemlist, unsigned int count, struct s_autotrader *at ){
|
||||
unsigned int i, weight, listidx;
|
||||
char message_sql[MESSAGE_SIZE*2];
|
||||
StringBuf buf;
|
||||
@ -161,50 +160,53 @@ int8 buyingstore_create(struct map_session_data* sd, int zenylimit, unsigned cha
|
||||
weight = sd->weight;
|
||||
|
||||
// check item list
|
||||
for( i = 0; i < count; i++ )
|
||||
{// itemlist: <name id>.W <amount>.W <price>.L
|
||||
unsigned short nameid, amount;
|
||||
int price, idx;
|
||||
struct item_data* id;
|
||||
for( i = 0; i < count; i++ ){
|
||||
const struct PACKET_CZ_REQ_OPEN_BUYING_STORE_sub *item = &itemlist[i];
|
||||
|
||||
nameid = RBUFW(itemlist,i*8+0);
|
||||
amount = RBUFW(itemlist,i*8+2);
|
||||
price = RBUFL(itemlist,i*8+4);
|
||||
struct item_data* id = itemdb_exists( item->itemId );
|
||||
|
||||
if( ( id = itemdb_exists(nameid) ) == NULL || amount == 0 )
|
||||
{// invalid input
|
||||
// invalid input
|
||||
if( id == NULL || item->amount == 0 ){
|
||||
break;
|
||||
}
|
||||
|
||||
if( price <= 0 || price > BUYINGSTORE_MAX_PRICE )
|
||||
{// invalid price: unlike vending, items cannot be bought at 0 Zeny
|
||||
// invalid price: unlike vending, items cannot be bought at 0 Zeny
|
||||
if( item->price <= 0 || item->price > BUYINGSTORE_MAX_PRICE ){
|
||||
break;
|
||||
}
|
||||
|
||||
if( !id->flag.buyingstore || !itemdb_cantrade_sub(id, pc_get_group_level(sd), pc_get_group_level(sd)) || ( idx = pc_search_inventory(sd, nameid) ) == -1 )
|
||||
{// restrictions: allowed, no character-bound items and at least one must be owned
|
||||
// restrictions: allowed and no character-bound items
|
||||
if( !id->flag.buyingstore || !itemdb_cantrade_sub( id, pc_get_group_level( sd ), pc_get_group_level( sd ) ) ){
|
||||
break;
|
||||
}
|
||||
|
||||
if( sd->inventory.u.items_inventory[idx].amount + amount > BUYINGSTORE_MAX_AMOUNT )
|
||||
{// too many items of same kind
|
||||
int idx = pc_search_inventory( sd, item->itemId );
|
||||
|
||||
// At least one must be owned
|
||||
if( idx < 0 ){
|
||||
break;
|
||||
}
|
||||
|
||||
if( i )
|
||||
{// duplicate check. as the client does this too, only malicious intent should be caught here
|
||||
ARR_FIND( 0, i, listidx, sd->buyingstore.items[listidx].nameid == nameid );
|
||||
if( listidx != i )
|
||||
{// duplicate
|
||||
ShowWarning("buyingstore_create: Found duplicate item on buying list (nameid=%hu, amount=%hu, account_id=%d, char_id=%d).\n", nameid, amount, sd->status.account_id, sd->status.char_id);
|
||||
// too many items of same kind
|
||||
if( sd->inventory.u.items_inventory[idx].amount + item->amount > BUYINGSTORE_MAX_AMOUNT ){
|
||||
break;
|
||||
}
|
||||
|
||||
// duplicate check. as the client does this too, only malicious intent should be caught here
|
||||
if( i ){
|
||||
ARR_FIND( 0, i, listidx, sd->buyingstore.items[listidx].nameid == item->itemId );
|
||||
|
||||
// duplicate
|
||||
if( listidx != i ){
|
||||
ShowWarning( "buyingstore_create: Found duplicate item on buying list (nameid=%hu, amount=%hu, account_id=%d, char_id=%d).\n", item->itemId, item->amount, sd->status.account_id, sd->status.char_id );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
weight+= id->weight*amount;
|
||||
sd->buyingstore.items[i].nameid = nameid;
|
||||
sd->buyingstore.items[i].amount = amount;
|
||||
sd->buyingstore.items[i].price = price;
|
||||
weight+= id->weight*item->amount;
|
||||
sd->buyingstore.items[i].nameid = item->itemId;
|
||||
sd->buyingstore.items[i].amount = item->amount;
|
||||
sd->buyingstore.items[i].price = item->price;
|
||||
}
|
||||
|
||||
if( i != count )
|
||||
@ -322,10 +324,9 @@ void buyingstore_open(struct map_session_data* sd, uint32 account_id)
|
||||
* @param *itemlist List of sold items { <index>.W, <nameid>.W, <amount>.W }*
|
||||
* @param count Number of item on the itemlist
|
||||
*/
|
||||
void buyingstore_trade(struct map_session_data* sd, uint32 account_id, unsigned int buyer_id, const uint8* itemlist, unsigned int count)
|
||||
{
|
||||
void buyingstore_trade( struct map_session_data* sd, uint32 account_id, unsigned int buyer_id, const struct PACKET_CZ_REQ_TRADE_BUYING_STORE_sub* itemlist, unsigned int count ){
|
||||
int zeny = 0;
|
||||
unsigned int i, weight, listidx, k;
|
||||
unsigned int weight;
|
||||
struct map_session_data* pl_sd;
|
||||
|
||||
nullpo_retv(sd);
|
||||
@ -362,98 +363,94 @@ void buyingstore_trade(struct map_session_data* sd, uint32 account_id, unsigned
|
||||
|
||||
searchstore_clearremote(sd);
|
||||
|
||||
if( pl_sd->status.zeny < pl_sd->buyingstore.zenylimit )
|
||||
{// buyer lost zeny in the mean time? fix the limit
|
||||
// buyer lost zeny in the mean time? fix the limit
|
||||
if( pl_sd->status.zeny < pl_sd->buyingstore.zenylimit ){
|
||||
pl_sd->buyingstore.zenylimit = pl_sd->status.zeny;
|
||||
}
|
||||
weight = pl_sd->weight;
|
||||
|
||||
// check item list
|
||||
for( i = 0; i < count; i++ )
|
||||
{// itemlist: <index>.W <name id>.W <amount>.W
|
||||
unsigned short nameid, amount;
|
||||
int index;
|
||||
for( int i = 0; i < count; i++ ){
|
||||
const struct PACKET_CZ_REQ_TRADE_BUYING_STORE_sub* item = &itemlist[i];
|
||||
|
||||
index = RBUFW(itemlist,i*6+0)-2;
|
||||
nameid = RBUFW(itemlist,i*6+2);
|
||||
amount = RBUFW(itemlist,i*6+4);
|
||||
|
||||
if( i )
|
||||
{// duplicate check. as the client does this too, only malicious intent should be caught here
|
||||
ARR_FIND( 0, i, k, RBUFW(itemlist,k*6+0)-2 == index );
|
||||
if( k != i )
|
||||
{// duplicate
|
||||
ShowWarning("buyingstore_trade: Found duplicate item on selling list (prevnameid=%hu, prevamount=%hu, nameid=%hu, amount=%hu, account_id=%d, char_id=%d).\n",
|
||||
RBUFW(itemlist,k*6+2), RBUFW(itemlist,k*6+4), nameid, amount, sd->status.account_id, sd->status.char_id);
|
||||
clif_buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_FAILED, nameid);
|
||||
// duplicate check. as the client does this too, only malicious intent should be caught here
|
||||
for( int k = 0; k < i; k++ ){
|
||||
// duplicate
|
||||
if( itemlist[k].index == item->index && k != i ){
|
||||
ShowWarning( "buyingstore_trade: Found duplicate item on selling list (prevnameid=%hu, prevamount=%hu, nameid=%hu, amount=%hu, account_id=%d, char_id=%d).\n", itemlist[k].itemId, itemlist[k].amount, item->itemId, item->amount, sd->status.account_id, sd->status.char_id );
|
||||
clif_buyingstore_trade_failed_seller( sd, BUYINGSTORE_TRADE_SELLER_FAILED, item->itemId );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
int index = item->index - 2; // TODO: clif::server_index
|
||||
|
||||
// invalid input
|
||||
if( index < 0 || index >= ARRAYLENGTH( sd->inventory.u.items_inventory ) || sd->inventory_data[index] == NULL || sd->inventory.u.items_inventory[index].nameid != item->itemId || sd->inventory.u.items_inventory[index].amount < item->amount ){
|
||||
clif_buyingstore_trade_failed_seller( sd, BUYINGSTORE_TRADE_SELLER_FAILED, item->itemId );
|
||||
return;
|
||||
}
|
||||
|
||||
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);
|
||||
// non-tradable item
|
||||
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 ) ) ){
|
||||
clif_buyingstore_trade_failed_seller( sd, BUYINGSTORE_TRADE_SELLER_FAILED, item->itemId );
|
||||
return;
|
||||
}
|
||||
|
||||
ARR_FIND( 0, pl_sd->buyingstore.slots, listidx, pl_sd->buyingstore.items[listidx].nameid == nameid );
|
||||
if( listidx == pl_sd->buyingstore.slots || pl_sd->buyingstore.items[listidx].amount == 0 )
|
||||
{// there is no such item or the buyer has already bought all of them
|
||||
clif_buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_FAILED, nameid);
|
||||
int listidx;
|
||||
|
||||
ARR_FIND( 0, pl_sd->buyingstore.slots, listidx, pl_sd->buyingstore.items[listidx].nameid == item->itemId );
|
||||
|
||||
// there is no such item or the buyer has already bought all of them
|
||||
if( listidx == pl_sd->buyingstore.slots || pl_sd->buyingstore.items[listidx].amount == 0 ){
|
||||
clif_buyingstore_trade_failed_seller( sd, BUYINGSTORE_TRADE_SELLER_FAILED, item->itemId );
|
||||
return;
|
||||
}
|
||||
|
||||
if( pl_sd->buyingstore.items[listidx].amount < amount )
|
||||
{// buyer does not need that much of the item
|
||||
clif_buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_COUNT, nameid);
|
||||
// buyer does not need that much of the item
|
||||
if( pl_sd->buyingstore.items[listidx].amount < item->amount ){
|
||||
clif_buyingstore_trade_failed_seller( sd, BUYINGSTORE_TRADE_SELLER_COUNT, item->itemId );
|
||||
return;
|
||||
}
|
||||
|
||||
if( pc_checkadditem(pl_sd, nameid, amount) == CHKADDITEM_OVERAMOUNT )
|
||||
{// buyer does not have enough space for this item
|
||||
clif_buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_FAILED, nameid);
|
||||
// buyer does not have enough space for this item
|
||||
if( pc_checkadditem( pl_sd, item->itemId, item->amount ) == CHKADDITEM_OVERAMOUNT ){
|
||||
clif_buyingstore_trade_failed_seller( sd, BUYINGSTORE_TRADE_SELLER_FAILED, item->itemId );
|
||||
return;
|
||||
}
|
||||
|
||||
if( amount*(unsigned int)sd->inventory_data[index]->weight > pl_sd->max_weight-weight )
|
||||
{// normally this is not supposed to happen, as the total weight is
|
||||
// checked upon creation, but the buyer could have gained items
|
||||
clif_buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_FAILED, nameid);
|
||||
// normally this is not supposed to happen, as the total weight is
|
||||
// checked upon creation, but the buyer could have gained items
|
||||
if( item->amount * (unsigned int)sd->inventory_data[index]->weight > pl_sd->max_weight - weight ){
|
||||
clif_buyingstore_trade_failed_seller( sd, BUYINGSTORE_TRADE_SELLER_FAILED, item->itemId );
|
||||
return;
|
||||
}
|
||||
weight+= amount*sd->inventory_data[index]->weight;
|
||||
|
||||
if( amount*pl_sd->buyingstore.items[listidx].price > pl_sd->buyingstore.zenylimit-zeny )
|
||||
{// buyer does not have enough zeny
|
||||
clif_buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_ZENY, nameid);
|
||||
weight += item->amount * sd->inventory_data[index]->weight;
|
||||
|
||||
// buyer does not have enough zeny
|
||||
if( item->amount * pl_sd->buyingstore.items[listidx].price > pl_sd->buyingstore.zenylimit - zeny ){
|
||||
clif_buyingstore_trade_failed_seller( sd, BUYINGSTORE_TRADE_SELLER_ZENY, item->itemId );
|
||||
return;
|
||||
}
|
||||
zeny+= amount*pl_sd->buyingstore.items[listidx].price;
|
||||
|
||||
zeny += item->amount * pl_sd->buyingstore.items[listidx].price;
|
||||
}
|
||||
|
||||
// process item list
|
||||
for( i = 0; i < count; i++ )
|
||||
{// itemlist: <index>.W <name id>.W <amount>.W
|
||||
unsigned short nameid, amount;
|
||||
int index;
|
||||
for( int i = 0; i < count; i++ ){
|
||||
const struct PACKET_CZ_REQ_TRADE_BUYING_STORE_sub* item = &itemlist[i];
|
||||
int listidx;
|
||||
|
||||
index = RBUFW(itemlist,i*6+0)-2;
|
||||
nameid = RBUFW(itemlist,i*6+2);
|
||||
amount = RBUFW(itemlist,i*6+4);
|
||||
ARR_FIND( 0, pl_sd->buyingstore.slots, listidx, pl_sd->buyingstore.items[listidx].nameid == item->itemId );
|
||||
zeny = item->amount * pl_sd->buyingstore.items[listidx].price;
|
||||
|
||||
ARR_FIND( 0, pl_sd->buyingstore.slots, listidx, pl_sd->buyingstore.items[listidx].nameid == nameid );
|
||||
zeny = amount*pl_sd->buyingstore.items[listidx].price;
|
||||
int index = item->index - 2; // TODO: clif::server_index
|
||||
|
||||
// move item
|
||||
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;
|
||||
pc_additem(pl_sd, &sd->inventory.u.items_inventory[index], item->amount, LOG_TYPE_BUYING_STORE);
|
||||
pc_delitem(sd, index, item->amount, 1, 0, LOG_TYPE_BUYING_STORE);
|
||||
pl_sd->buyingstore.items[listidx].amount -= item->amount;
|
||||
|
||||
if( pl_sd->buyingstore.items[listidx].amount > 0 ){
|
||||
if( Sql_Query( mmysql_handle, "UPDATE `%s` SET `amount` = %d WHERE `buyingstore_id` = %d AND `index` = %d;", buyingstore_items_table, pl_sd->buyingstore.items[listidx].amount, pl_sd->buyer_id, listidx ) != SQL_SUCCESS ){
|
||||
@ -471,8 +468,8 @@ void buyingstore_trade(struct map_session_data* sd, uint32 account_id, unsigned
|
||||
pl_sd->buyingstore.zenylimit-= zeny;
|
||||
|
||||
// notify clients
|
||||
clif_buyingstore_delete_item(sd, index, amount, pl_sd->buyingstore.items[listidx].price);
|
||||
clif_buyingstore_update_item(pl_sd, nameid, amount, sd->status.char_id, zeny);
|
||||
clif_buyingstore_delete_item(sd, index, item->amount, pl_sd->buyingstore.items[listidx].price);
|
||||
clif_buyingstore_update_item(pl_sd, item->itemId, item->amount, sd->status.char_id, zeny);
|
||||
}
|
||||
|
||||
if( save_settings&CHARSAVE_VENDING ) {
|
||||
@ -481,6 +478,7 @@ void buyingstore_trade(struct map_session_data* sd, uint32 account_id, unsigned
|
||||
}
|
||||
|
||||
// check whether or not there is still something to buy
|
||||
int i;
|
||||
ARR_FIND( 0, pl_sd->buyingstore.slots, i, pl_sd->buyingstore.items[i].amount != 0 );
|
||||
if( i == pl_sd->buyingstore.slots )
|
||||
{// everything was bought
|
||||
@ -548,7 +546,7 @@ bool buyingstore_searchall(struct map_session_data* sd, const struct s_search_st
|
||||
|
||||
for( idx = 0; idx < s->item_count; idx++ )
|
||||
{
|
||||
ARR_FIND( 0, sd->buyingstore.slots, i, sd->buyingstore.items[i].nameid == s->itemlist[idx] && sd->buyingstore.items[i].amount );
|
||||
ARR_FIND( 0, sd->buyingstore.slots, i, sd->buyingstore.items[i].nameid == s->itemlist[idx].itemId && sd->buyingstore.items[i].amount );
|
||||
if( i == sd->buyingstore.slots )
|
||||
{// not found
|
||||
continue;
|
||||
@ -591,23 +589,15 @@ void buyingstore_reopen( struct map_session_data* sd ){
|
||||
|
||||
// Ready to open buyingstore for this char
|
||||
if ((at = (struct s_autotrader *)uidb_get(buyingstore_autotrader_db, sd->status.char_id)) && at->count && at->entries) {
|
||||
uint8 *data, *p;
|
||||
uint16 j, count;
|
||||
struct PACKET_CZ_REQ_OPEN_BUYING_STORE_sub* data;
|
||||
|
||||
// Init buyingstore data for autotrader
|
||||
CREATE(data, uint8, at->count * 8);
|
||||
CREATE(data, struct PACKET_CZ_REQ_OPEN_BUYING_STORE_sub, at->count );
|
||||
|
||||
for (j = 0, p = data, count = at->count; j < at->count; j++) {
|
||||
struct s_autotrade_entry *entry = at->entries[j];
|
||||
unsigned short *item_id = (uint16*)(p + 0);
|
||||
uint16 *amount = (uint16*)(p + 2);
|
||||
uint32 *price = (uint32*)(p + 4);
|
||||
|
||||
*item_id = entry->item_id;
|
||||
*amount = entry->amount;
|
||||
*price = entry->price;
|
||||
|
||||
p += 8;
|
||||
for( int j = 0; j < at->count; j++) {
|
||||
data[j].itemId = at->entries[j]->item_id;
|
||||
data[j].amount = at->entries[j]->amount;
|
||||
data[j].price = at->entries[j]->price;
|
||||
}
|
||||
|
||||
sd->state.autotrade = 1;
|
||||
@ -633,7 +623,7 @@ void buyingstore_reopen( struct map_session_data* sd ){
|
||||
chrif_save(sd, CSAVE_AUTOTRADE);
|
||||
|
||||
ShowInfo("Buyingstore loaded for '" CL_WHITE "%s" CL_RESET "' with '" CL_WHITE "%d" CL_RESET "' items at " CL_WHITE "%s (%d,%d)" CL_RESET "\n",
|
||||
sd->status.name, count, mapindex_id2name(sd->mapindex), sd->bl.x, sd->bl.y);
|
||||
sd->status.name, at->count, mapindex_id2name(sd->mapindex), sd->bl.x, sd->bl.y);
|
||||
}
|
||||
aFree(data);
|
||||
}
|
||||
|
@ -56,10 +56,10 @@ struct s_autotrader {
|
||||
};
|
||||
|
||||
int8 buyingstore_setup(struct map_session_data* sd, unsigned char slots);
|
||||
int8 buyingstore_create(struct map_session_data* sd, int zenylimit, unsigned char result, const char* storename, const uint8* itemlist, unsigned int count, struct s_autotrader *at);
|
||||
int8 buyingstore_create(struct map_session_data* sd, int zenylimit, unsigned char result, const char* storename, const struct PACKET_CZ_REQ_OPEN_BUYING_STORE_sub* itemlist, unsigned int count, struct s_autotrader *at);
|
||||
void buyingstore_close(struct map_session_data* sd);
|
||||
void buyingstore_open(struct map_session_data* sd, uint32 account_id);
|
||||
void buyingstore_trade(struct map_session_data* sd, uint32 account_id, unsigned int buyer_id, const uint8* itemlist, unsigned int count);
|
||||
void buyingstore_trade(struct map_session_data* sd, uint32 account_id, unsigned int buyer_id, const struct PACKET_CZ_REQ_TRADE_BUYING_STORE_sub* itemlist, unsigned int count);
|
||||
bool buyingstore_search(struct map_session_data* sd, unsigned short nameid);
|
||||
bool buyingstore_searchall(struct map_session_data* sd, const struct s_search_store_search* s);
|
||||
DBMap *buyingstore_getdb(void);
|
||||
|
@ -467,7 +467,7 @@ static void cashshop_read_db( void ){
|
||||
* @param item_list Array of item ID
|
||||
* @return true: success, false: fail
|
||||
*/
|
||||
bool cashshop_buylist( struct map_session_data* sd, uint32 kafrapoints, int n, uint16* item_list ){
|
||||
bool cashshop_buylist( struct map_session_data* sd, uint32 kafrapoints, int n, struct PACKET_CZ_SE_PC_BUY_CASHITEM_LIST_sub* item_list ){
|
||||
uint32 totalcash = 0;
|
||||
uint32 totalweight = 0;
|
||||
int i,new_;
|
||||
@ -487,9 +487,9 @@ bool cashshop_buylist( struct map_session_data* sd, uint32 kafrapoints, int n, u
|
||||
new_ = 0;
|
||||
|
||||
for( i = 0; i < n; ++i ){
|
||||
unsigned short nameid = *( item_list + i * 5 );
|
||||
uint32 quantity = *( item_list + i * 5 + 2 );
|
||||
uint8 tab = (uint8)*( item_list + i * 5 + 4 );
|
||||
unsigned short nameid = item_list[i].itemId;
|
||||
uint32 quantity = item_list[i].amount;
|
||||
uint16 tab = item_list[i].tab;
|
||||
int j;
|
||||
|
||||
if( tab >= CASHSHOP_TAB_MAX ){
|
||||
@ -504,7 +504,7 @@ bool cashshop_buylist( struct map_session_data* sd, uint32 kafrapoints, int n, u
|
||||
return false;
|
||||
}
|
||||
|
||||
nameid = *( item_list + i * 5 ) = cash_shop_items[tab].item[j]->nameid; //item_avail replacement
|
||||
nameid = item_list[i].itemId = cash_shop_items[tab].item[j]->nameid; //item_avail replacement
|
||||
id = itemdb_exists(nameid);
|
||||
|
||||
if( !id ){
|
||||
@ -569,10 +569,10 @@ bool cashshop_buylist( struct map_session_data* sd, uint32 kafrapoints, int n, u
|
||||
}
|
||||
|
||||
for( i = 0; i < n; ++i ){
|
||||
unsigned short nameid = *( item_list + i * 5 );
|
||||
uint32 quantity = *( item_list + i * 5 + 2 );
|
||||
unsigned short nameid = item_list[i].itemId;
|
||||
uint32 quantity = item_list[i].amount;
|
||||
#if PACKETVER_SUPPORTS_SALES
|
||||
uint16 tab = *(item_list + i * 5 + 4);
|
||||
uint16 tab = item_list[i].tab;
|
||||
#endif
|
||||
struct item_data *id = itemdb_search(nameid);
|
||||
|
||||
@ -580,12 +580,12 @@ bool cashshop_buylist( struct map_session_data* sd, uint32 kafrapoints, int n, u
|
||||
continue;
|
||||
|
||||
if (!pet_create_egg(sd, nameid)) {
|
||||
unsigned short get_amt = quantity, j;
|
||||
unsigned short get_amt = quantity;
|
||||
|
||||
if (id->flag.guid || !itemdb_isstackable2(id))
|
||||
get_amt = 1;
|
||||
|
||||
for (j = 0; j < quantity; j += get_amt) {
|
||||
for (uint32 j = 0; j < quantity; j += get_amt) {
|
||||
struct item item_tmp = { 0 };
|
||||
|
||||
item_tmp.nameid = nameid;
|
||||
@ -606,6 +606,8 @@ bool cashshop_buylist( struct map_session_data* sd, uint32 kafrapoints, int n, u
|
||||
return false;
|
||||
}
|
||||
|
||||
clif_cashshop_result( sd, nameid, CASHSHOP_RESULT_SUCCESS );
|
||||
|
||||
#if PACKETVER_SUPPORTS_SALES
|
||||
if( tab == CASHSHOP_TAB_SALE ){
|
||||
uint32 new_amount = sale->amount - get_amt;
|
||||
@ -627,7 +629,6 @@ bool cashshop_buylist( struct map_session_data* sd, uint32 kafrapoints, int n, u
|
||||
}
|
||||
}
|
||||
|
||||
clif_cashshop_result( sd, 0, CASHSHOP_RESULT_SUCCESS ); //Doesn't show any message?
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,7 @@ struct map_session_data;
|
||||
void do_init_cashshop( void );
|
||||
void do_final_cashshop( void );
|
||||
void cashshop_reloaddb( void );
|
||||
bool cashshop_buylist( struct map_session_data* sd, uint32 kafrapoints, int n, uint16* item_list );
|
||||
bool cashshop_buylist( struct map_session_data* sd, uint32 kafrapoints, int n, struct PACKET_CZ_SE_PC_BUY_CASHITEM_LIST_sub* item_list );
|
||||
|
||||
// Taken from AEGIS
|
||||
enum CASH_SHOP_TAB_CODE
|
||||
|
4785
src/map/clif.cpp
4785
src/map/clif.cpp
File diff suppressed because it is too large
Load Diff
@ -13,6 +13,7 @@
|
||||
#include "../common/mmo.hpp"
|
||||
#include "../common/timer.hpp" // t_tick
|
||||
|
||||
#include "packets.hpp"
|
||||
#include "script.hpp"
|
||||
|
||||
struct Channel;
|
||||
@ -47,8 +48,10 @@ enum e_instance_notify : uint8;
|
||||
|
||||
enum e_PacketDBVersion { // packet DB
|
||||
MIN_PACKET_DB = 0x064,
|
||||
MAX_PACKET_DB = 0xAFF,
|
||||
MAX_PACKET_DB = 0xBFF,
|
||||
#if !defined(MAX_PACKET_POS)
|
||||
MAX_PACKET_POS = 20,
|
||||
#endif
|
||||
};
|
||||
|
||||
enum e_packet_ack : uint8_t{
|
||||
@ -659,7 +662,7 @@ void clif_soundeffect(struct map_session_data* sd, struct block_list* bl, const
|
||||
void clif_soundeffectall(struct block_list* bl, const char* name, int type, enum send_target coverage);
|
||||
void clif_parse_ActionRequest_sub(struct map_session_data *sd, int action_type, int target_id, t_tick tick);
|
||||
void clif_parse_LoadEndAck(int fd,struct map_session_data *sd);
|
||||
void clif_hotkeys_send(struct map_session_data *sd);
|
||||
void clif_hotkeys_send(struct map_session_data *sd, int tab);
|
||||
|
||||
// trade
|
||||
void clif_traderequest(struct map_session_data* sd, const char* name);
|
||||
@ -693,7 +696,7 @@ void clif_deleteskill(struct map_session_data *sd, int skill_id);
|
||||
|
||||
void clif_skillcasting(struct block_list* bl, int src_id, int dst_id, int dst_x, int dst_y, uint16 skill_id, int property, int casttime);
|
||||
void clif_skillcastcancel(struct block_list* bl);
|
||||
void clif_skill_fail(struct map_session_data *sd,uint16 skill_id,enum useskill_fail_cause cause,int btype);
|
||||
void clif_skill_fail(struct map_session_data *sd,uint16 skill_id,enum useskill_fail_cause cause,int btype, int itemId = 0);
|
||||
void clif_skill_cooldown(struct map_session_data *sd, uint16 skill_id, t_tick tick);
|
||||
int clif_skill_damage(struct block_list *src,struct block_list *dst,t_tick tick,int sdelay,int ddelay,int64 sdamage,int div,uint16 skill_id,uint16 skill_lv,enum e_damage_type type);
|
||||
//int clif_skill_damage2(struct block_list *src,struct block_list *dst,t_tick tick,int sdelay,int ddelay,int damage,int div,uint16 skill_id,uint16 skill_lv,enum e_damage_type type);
|
||||
@ -739,7 +742,7 @@ void clif_insert_card(struct map_session_data *sd,int idx_equip,int idx_card,int
|
||||
void clif_inventorylist(struct map_session_data *sd);
|
||||
void clif_equiplist(struct map_session_data *sd);
|
||||
|
||||
void clif_cart_additem(struct map_session_data *sd,int n,int amount,int fail);
|
||||
void clif_cart_additem(struct map_session_data *sd,int n,int amount);
|
||||
void clif_cart_additem_ack(struct map_session_data *sd, uint8 flag);
|
||||
void clif_cart_delitem(struct map_session_data *sd,int n,int amount);
|
||||
void clif_cartlist(struct map_session_data *sd);
|
||||
@ -766,7 +769,7 @@ void clif_changed_dir(struct block_list *bl, enum send_target target);
|
||||
void clif_openvendingreq(struct map_session_data* sd, int num);
|
||||
void clif_showvendingboard(struct block_list* bl, const char* message, int fd);
|
||||
void clif_closevendingboard(struct block_list* bl, int fd);
|
||||
void clif_vendinglist(struct map_session_data* sd, int id, struct s_vending* vending);
|
||||
void clif_vendinglist( struct map_session_data* sd, struct map_session_data* vsd );
|
||||
void clif_buyvending(struct map_session_data* sd, int index, int amount, int fail);
|
||||
void clif_openvending(struct map_session_data* sd, int id, struct s_vending* vending);
|
||||
void clif_vendingreport(struct map_session_data* sd, int index, int amount, uint32 char_id, int zeny);
|
||||
@ -855,7 +858,7 @@ void clif_map_property(struct block_list *bl, enum map_property property, enum s
|
||||
void clif_pvpset(struct map_session_data *sd, int pvprank, int pvpnum,int type);
|
||||
void clif_map_property_mapall(int map, enum map_property property);
|
||||
void clif_refine(int fd, int fail, int index, int val);
|
||||
void clif_upgrademessage(int fd, int result, unsigned short item_id);
|
||||
void clif_upgrademessage( struct map_session_data* sd, int result, unsigned short item_id );
|
||||
|
||||
//petsystem
|
||||
void clif_catch_process(struct map_session_data *sd);
|
||||
@ -904,7 +907,7 @@ void clif_feel_hate_reset(struct map_session_data *sd);
|
||||
void clif_hominfo(struct map_session_data *sd, struct homun_data *hd, int flag);
|
||||
int clif_homskillinfoblock(struct map_session_data *sd);
|
||||
void clif_homskillup(struct map_session_data *sd, uint16 skill_id); //[orn]
|
||||
int clif_hom_food(struct map_session_data *sd,int foodid,int fail); //[orn]
|
||||
void clif_hom_food(struct map_session_data *sd,int foodid,int fail); //[orn]
|
||||
void clif_send_homdata(struct map_session_data *sd, int state, int param); //[orn]
|
||||
|
||||
void clif_configuration( struct map_session_data* sd, enum e_config_type type, bool enabled );
|
||||
@ -926,7 +929,7 @@ void clif_quest_update_objective(struct map_session_data * sd, struct quest * qd
|
||||
void clif_quest_show_event(struct map_session_data *sd, struct block_list *bl, e_questinfo_types effect, e_questinfo_markcolor color);
|
||||
void clif_displayexp(struct map_session_data *sd, unsigned int exp, char type, bool quest, bool lost);
|
||||
|
||||
int clif_send(const uint8* buf, int len, struct block_list* bl, enum send_target type);
|
||||
int clif_send(const void* buf, int len, struct block_list* bl, enum send_target type);
|
||||
void do_init_clif(void);
|
||||
void do_final_clif(void);
|
||||
|
||||
@ -971,8 +974,8 @@ void clif_mercenary_message(struct map_session_data* sd, int message);
|
||||
void clif_mercenary_updatestatus(struct map_session_data *sd, int type);
|
||||
|
||||
// RENTAL SYSTEM
|
||||
void clif_rental_time(int fd, unsigned short nameid, int seconds);
|
||||
void clif_rental_expired(int fd, int index, unsigned short nameid);
|
||||
void clif_rental_time( struct map_session_data* sd, unsigned short nameid, int seconds );
|
||||
void clif_rental_expired( struct map_session_data* sd, int index, unsigned short nameid );
|
||||
|
||||
// BOOK READING
|
||||
void clif_readbook(int fd, int book_id, int page);
|
||||
@ -1026,7 +1029,7 @@ void clif_search_store_info_click_ack(struct map_session_data* sd, short x, shor
|
||||
|
||||
/// Cash Shop
|
||||
void clif_cashshop_result( struct map_session_data* sd, unsigned short item_id, uint16 result );
|
||||
void clif_cashshop_open( struct map_session_data* sd );
|
||||
void clif_cashshop_open( struct map_session_data* sd, int tab );
|
||||
|
||||
void clif_display_pinfo(struct map_session_data *sd, int type);
|
||||
|
||||
@ -1038,15 +1041,15 @@ void clif_parse_roulette_close(int fd, struct map_session_data *sd);
|
||||
void clif_parse_roulette_generate(int fd, struct map_session_data *sd);
|
||||
void clif_parse_roulette_item(int fd, struct map_session_data *sd);
|
||||
|
||||
int clif_elementalconverter_list(struct map_session_data *sd);
|
||||
void clif_elementalconverter_list(struct map_session_data *sd);
|
||||
|
||||
void clif_millenniumshield(struct block_list *bl, short shields);
|
||||
|
||||
int clif_spellbook_list(struct map_session_data *sd);
|
||||
void clif_spellbook_list(struct map_session_data *sd);
|
||||
|
||||
int clif_magicdecoy_list(struct map_session_data *sd, uint16 skill_lv, short x, short y);
|
||||
void clif_magicdecoy_list(struct map_session_data *sd, uint16 skill_lv, short x, short y);
|
||||
|
||||
int clif_poison_list(struct map_session_data *sd, uint16 skill_lv);
|
||||
void clif_poison_list(struct map_session_data *sd, uint16 skill_lv);
|
||||
|
||||
int clif_autoshadowspell_list(struct map_session_data *sd);
|
||||
|
||||
@ -1140,4 +1143,6 @@ void clif_equipswitch_reply( struct map_session_data* sd, bool failed );
|
||||
/// Pet evolution
|
||||
void clif_pet_evolution_result( struct map_session_data* sd, e_pet_evolution_result result );
|
||||
|
||||
void clif_parse_skill_toid( struct map_session_data* sd, uint16 skill_id, uint16 skill_lv, int target_id );
|
||||
|
||||
#endif /* CLIF_HPP */
|
||||
|
@ -311,7 +311,7 @@
|
||||
parseable_packet(0x018e,10,clif_parse_ProduceMix,2,4,6,8);
|
||||
packet(0x018f,6);
|
||||
parseable_packet(0x0190,90,clif_parse_UseSkillToPosMoreInfo,2,4,6,8,10);
|
||||
packet(0x0191,86);
|
||||
packet( HEADER_ZC_TALKBOX_CHATCONTENTS, sizeof( struct PACKET_ZC_TALKBOX_CHATCONTENTS ) );
|
||||
packet(0x0192,24);
|
||||
parseable_packet(0x0193,6,clif_parse_SolveCharName,2);
|
||||
packet(0x0194,30);
|
||||
@ -419,7 +419,7 @@
|
||||
packet(0x01fa,48);
|
||||
packet(0x01fb,56);
|
||||
packet(0x01fc,-1);
|
||||
parseable_packet(0x01fd,4,clif_parse_RepairItem,2);
|
||||
parseable_packet(0x01fd,4,clif_parse_RepairItem,0);
|
||||
packet(0x01fe,5);
|
||||
packet(0x01ff,10);
|
||||
packet(0x0200,26);
|
||||
@ -1074,12 +1074,12 @@
|
||||
|
||||
// 2007-05-07aSakexe
|
||||
#if PACKETVER >= 20070507
|
||||
parseable_packet(0x01fd,15,clif_parse_RepairItem,2,4,6,7,9,11,13);
|
||||
parseable_packet(0x01fd,15,clif_parse_RepairItem,0);
|
||||
#endif
|
||||
|
||||
// 2007-02-27aSakexe to 2007-10-02aSakexe
|
||||
#if PACKETVER >= 20070227
|
||||
parseable_packet(0x0288,10,clif_parse_cashshop_buy,2,4,6);
|
||||
parseable_packet(0x0288,10,clif_parse_npccashshop_buy,2,4,6);
|
||||
packet(0x0289,12);
|
||||
packet(0x02a6,22);
|
||||
packet(0x02a7,22);
|
||||
@ -1505,7 +1505,7 @@
|
||||
//packet(0x07d4,4);
|
||||
//packet(0x07d5,4);
|
||||
//packet(0x07d6,4);
|
||||
//packet(0x0447,2);
|
||||
parseable_packet( 0x0447, 2, clif_parse_blocking_playcancel, 0 );
|
||||
#endif
|
||||
|
||||
// 2009-06-03aRagexeRE
|
||||
@ -1815,7 +1815,7 @@
|
||||
|
||||
// 2010-11-24aRagexeRE
|
||||
#if PACKETVER >= 20101124
|
||||
parseable_packet(0x0288,-1,clif_parse_cashshop_buy,2,4,8,10);
|
||||
parseable_packet(0x0288,-1,clif_parse_npccashshop_buy,2,4,8,10);
|
||||
parseable_packet(0x0436,19,clif_parse_WantToConnection,2,6,10,14,18);
|
||||
parseable_packet(0x035f,5,clif_parse_WalkToXY,2);
|
||||
parseable_packet(0x0360,6,clif_parse_TickSend,2);
|
||||
@ -1915,11 +1915,11 @@
|
||||
|
||||
// 2012-04-10aRagexeRE
|
||||
#if PACKETVER >= 20120410
|
||||
parseable_packet(0x01fd,15,clif_parse_RepairItem,2,4,6,7,9,11,13);
|
||||
parseable_packet(0x01fd,15,clif_parse_RepairItem,0);
|
||||
parseable_packet(0x089c,26,clif_parse_FriendsListAdd,2);
|
||||
parseable_packet(0x0885,5,clif_parse_HomMenu,2,4);
|
||||
parseable_packet(0x0961,36,clif_parse_StoragePassword,2,4,20);
|
||||
parseable_packet(0x0288,-1,clif_parse_cashshop_buy,2,4,8,10);
|
||||
parseable_packet(0x0288,-1,clif_parse_npccashshop_buy,2,4,8,10);
|
||||
parseable_packet(0x091c,26,clif_parse_PartyInvite2,2);
|
||||
parseable_packet(0x094b,19,clif_parse_WantToConnection,2,6,10,14,18);
|
||||
parseable_packet(0x0369,7,clif_parse_ActionRequest,2,6);
|
||||
@ -2049,7 +2049,7 @@
|
||||
// 2013-03-20Ragexe (Judas)
|
||||
#if PACKETVER >= 20130320
|
||||
parseable_packet(0x014f,6,clif_parse_GuildRequestInfo,2);
|
||||
parseable_packet(0x01fd,15,clif_parse_RepairItem,2,4,6,7,9,11,13);
|
||||
parseable_packet(0x01fd,15,clif_parse_RepairItem,0);
|
||||
//parseable_packet(0x0281,-1,clif_parse_ItemListWindowSelected,2,4,8,12);
|
||||
parseable_packet(0x035f,6,clif_parse_ReqClickBuyingStore,2);
|
||||
parseable_packet(0x0363,6,clif_parse_TickSend,2);
|
||||
@ -2180,18 +2180,18 @@
|
||||
parseable_packet(0x098D,-1,clif_parse_clan_chat,2,4);
|
||||
packet(0x098E,-1);
|
||||
// Sale
|
||||
parseable_packet(0x09AC,-1,clif_parse_sale_search,2,4,8);
|
||||
packet(0x09AD,8);
|
||||
parseable_packet(0x09AE,17,clif_parse_sale_add,2,6,8,12,16);
|
||||
parseable_packet( HEADER_CZ_REQ_CASH_BARGAIN_SALE_ITEM_INFO, -1, clif_parse_sale_search, 0 );
|
||||
packet( HEADER_ZC_ACK_CASH_BARGAIN_SALE_ITEM_INFO, sizeof( PACKET_ZC_ACK_CASH_BARGAIN_SALE_ITEM_INFO ) );
|
||||
parseable_packet( HEADER_CZ_REQ_APPLY_BARGAIN_SALE_ITEM, sizeof( PACKET_CZ_REQ_APPLY_BARGAIN_SALE_ITEM ), clif_parse_sale_add, 0 );
|
||||
packet(0x09AF,4);
|
||||
parseable_packet(0x09B0,8,clif_parse_sale_remove,2,6);
|
||||
parseable_packet( HEADER_CZ_REQ_REMOVE_BARGAIN_SALE_ITEM, sizeof( PACKET_CZ_REQ_REMOVE_BARGAIN_SALE_ITEM ), clif_parse_sale_remove, 0 );
|
||||
packet(0x09B1,4);
|
||||
packet(0x09B2,8);
|
||||
packet(0x09B3,4);
|
||||
packet( HEADER_ZC_NOTIFY_BARGAIN_SALE_SELLING, sizeof( PACKET_ZC_NOTIFY_BARGAIN_SALE_SELLING ) );
|
||||
packet( HEADER_ZC_NOTIFY_BARGAIN_SALE_CLOSE, sizeof( PACKET_ZC_NOTIFY_BARGAIN_SALE_CLOSE ) );
|
||||
parseable_packet(0x09B4,6,clif_parse_sale_open,2);
|
||||
parseable_packet(0x09BC,6,clif_parse_sale_close,2);
|
||||
parseable_packet(0x09C3,8,clif_parse_sale_refresh,2,6);
|
||||
packet(0x09C4,8);
|
||||
packet( HEADER_ZC_ACK_COUNT_BARGAIN_SALE_ITEM, sizeof( PACKET_ZC_ACK_COUNT_BARGAIN_SALE_ITEM ) );
|
||||
// New Packet
|
||||
packet(0x097A,-1); // ZC_ALL_QUEST_LIST2
|
||||
packet(0x09DB,-1); // ZC_NOTIFY_MOVEENTRY10
|
||||
@ -2312,7 +2312,7 @@
|
||||
|
||||
// 2015-05-20aRagexe
|
||||
#if PACKETVER >= 20150520
|
||||
parseable_packet(0x0A3D,18,clif_parse_sale_add,2,6,8,12,16);
|
||||
parseable_packet( HEADER_CZ_REQ_APPLY_BARGAIN_SALE_ITEM2, sizeof( PACKET_CZ_REQ_APPLY_BARGAIN_SALE_ITEM ), clif_parse_sale_add, 0 );
|
||||
#endif
|
||||
|
||||
// 2015-09-16Ragexe
|
||||
@ -2439,4 +2439,46 @@
|
||||
packet(0x0ADD, 22);
|
||||
#endif
|
||||
|
||||
#if PACKETVER >= 20180704
|
||||
parseable_packet( 0x018e, sizeof( struct PACKET_CZ_REQMAKINGITEM ), clif_parse_ProduceMix, 0 );
|
||||
parseable_packet( 0x01ae, 6, clif_parse_SelectArrow, 0 );
|
||||
parseable_packet( 0x01fd, sizeof( struct PACKET_CZ_REQ_ITEMREPAIR ), clif_parse_RepairItem, 0 );
|
||||
parseable_packet( 0x025b, sizeof( struct PACKET_CZ_REQ_MAKINGITEM ), clif_parse_Cooking, 0 );
|
||||
// this is done in clif_shuffle
|
||||
//parseable_packet( 0x083C, sizeof( struct PACKET_CZ_SSILIST_ITEM_CLICK ), clif_parse_SearchStoreInfoListItemClick, 0 );
|
||||
parseable_packet( 0x0A49, sizeof( struct PACKET_CZ_PRIVATE_AIRSHIP_REQUEST ), clif_parse_private_airship_request, 0 );
|
||||
#endif
|
||||
|
||||
#if PACKETVER_MAIN_NUM >= 20181002 || PACKETVER_RE_NUM >= 20181002 || PACKETVER_ZERO_NUM >= 20181010
|
||||
parseable_packet( 0x0B10, sizeof( struct PACKET_CZ_START_USE_SKILL ), clif_parse_StartUseSkillToId, 0 );
|
||||
parseable_packet( 0x0B11, sizeof( struct PACKET_CZ_STOP_USE_SKILL ), clif_parse_StopUseSkillToId, 0 );
|
||||
#endif
|
||||
|
||||
#if PACKETVER_MAIN_NUM >= 20181031 || PACKETVER_RE_NUM >= 20181031 || PACKETVER_ZERO_NUM >= 20181114
|
||||
parseable_packet( 0x0B14, sizeof( struct PACKET_CZ_INVENTORY_EXPAND ), clif_parse_dull, 0 );
|
||||
parseable_packet( 0x0B16, sizeof( struct PACKET_CZ_INVENTORY_EXPAND_CONFIRMED ), clif_parse_dull, 0 );
|
||||
parseable_packet( 0x0B19, sizeof( struct PACKET_CZ_INVENTORY_EXPAND_REJECTED ), clif_parse_dull, 0 );
|
||||
#endif
|
||||
|
||||
#if PACKETVER_MAIN_NUM >= 20190227 || PACKETVER_RE_NUM >= 20190220 || PACKETVER_ZERO_NUM >= 20190220
|
||||
parseable_packet( 0x0B1C, sizeof( struct PACKET_CZ_PING ), clif_parse_dull, 0 );
|
||||
#endif
|
||||
|
||||
#if PACKETVER_MAIN_NUM >= 20190522 || PACKETVER_RE_NUM >= 20190508 || PACKETVER_ZERO_NUM >= 20190605
|
||||
parseable_packet( 0x0B21, sizeof( struct PACKET_CZ_SHORTCUT_KEY_CHANGE2 ), clif_parse_Hotkey, 0 );
|
||||
parseable_packet( 0x0B22, sizeof( struct PACKET_CZ_SHORTCUTKEYBAR_ROTATE2 ), clif_parse_HotkeyRowShift, 0 );
|
||||
#endif
|
||||
|
||||
#if PACKETVER_MAIN_NUM >= 20190703 || PACKETVER_RE_NUM >= 20190703 || PACKETVER_ZERO_NUM >= 20190709
|
||||
parseable_packet( HEADER_CZ_REQ_MOUNTOFF, sizeof( PACKET_CZ_REQ_MOUNTOFF ), clif_parse_RemoveOption, 0 );
|
||||
#endif
|
||||
|
||||
#if PACKETVER >= 20190724
|
||||
parseable_packet( 0x0b4c, 2, clif_parse_dull, 0 );
|
||||
#endif
|
||||
|
||||
#if PACKETVER >= 20191224
|
||||
parseable_packet( HEADER_CZ_SE_CASHSHOP_OPEN2, sizeof( struct PACKET_CZ_SE_CASHSHOP_OPEN2 ), clif_parse_cashshop_open_request, 0 );
|
||||
#endif
|
||||
|
||||
#endif /* CLIF_PACKETDB_HPP */
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -95,7 +95,8 @@
|
||||
<PreprocessorDefinitions>$(DefineConstants);WIN32;FD_SETSIZE=4096;PCRE_SUPPORT;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_WINSOCK_DEPRECATED_NO_WARNINGS;LIBCONFIG_STATIC;YY_USE_CONST;_DEBUG;_CONSOLE;_LIB;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\yaml-cpp\include\</AdditionalIncludeDirectories>
|
||||
<DisableSpecificWarnings>4018</DisableSpecificWarnings>
|
||||
<DisableSpecificWarnings>4018;4200</DisableSpecificWarnings>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
@ -192,6 +193,8 @@
|
||||
<ClInclude Include="mercenary.hpp" />
|
||||
<ClInclude Include="mob.hpp" />
|
||||
<ClInclude Include="npc.hpp" />
|
||||
<ClInclude Include="packets.hpp" />
|
||||
<ClInclude Include="packets_struct.hpp" />
|
||||
<ClInclude Include="party.hpp" />
|
||||
<ClInclude Include="path.hpp" />
|
||||
<ClInclude Include="pc.hpp" />
|
||||
@ -369,4 +372,3 @@
|
||||
<Copy SourceFiles="$(SolutionDir)db\import-tmpl\status_disabled.txt" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\status_disabled.txt')" />
|
||||
</Target>
|
||||
</Project>
|
||||
|
||||
|
@ -98,6 +98,12 @@
|
||||
<ClInclude Include="npc.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="packets.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="packets_struct.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="party.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
|
@ -223,6 +223,12 @@ enum e_mapid {
|
||||
|
||||
//Max size for inputs to Graffiti, Talkie Box and Vending text prompts
|
||||
#define MESSAGE_SIZE (79 + 1)
|
||||
// Max size for inputs to Graffiti, Talkie Box text prompts
|
||||
#if PACKETVER_MAIN_NUM >= 20190904 || PACKETVER_RE_NUM >= 20190904 || PACKETVER_ZERO_NUM >= 20190828
|
||||
#define TALKBOX_MESSAGE_SIZE 21
|
||||
#else
|
||||
#define TALKBOX_MESSAGE_SIZE (79 + 1)
|
||||
#endif
|
||||
//String length you can write in the 'talking box'
|
||||
#define CHATBOX_SIZE (70 + 1)
|
||||
//Chatroom-related string sizes
|
||||
|
@ -1682,7 +1682,7 @@ static enum e_CASHSHOP_ACK npc_cashshop_process_payment(struct npc_data *nd, int
|
||||
* @param item_list: List of items to purchase
|
||||
* @return clif_cashshop_ack value to display
|
||||
*/
|
||||
int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, unsigned short* item_list)
|
||||
int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, struct PACKET_CZ_PC_BUY_CASH_POINT_ITEM_sub* item_list)
|
||||
{
|
||||
int i, j, amount, new_, w, vt;
|
||||
unsigned short nameid;
|
||||
@ -1702,8 +1702,8 @@ int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, uns
|
||||
// Validating Process ----------------------------------------------------
|
||||
for( i = 0; i < count; i++ )
|
||||
{
|
||||
nameid = item_list[i*2+1];
|
||||
amount = item_list[i*2+0];
|
||||
nameid = item_list[i].itemId;
|
||||
amount = item_list[i].amount;
|
||||
id = itemdb_exists(nameid);
|
||||
|
||||
if( !id || amount <= 0 )
|
||||
@ -1713,12 +1713,12 @@ int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, uns
|
||||
if( j == nd->u.shop.count || nd->u.shop.shop_item[j].value <= 0 )
|
||||
return ERROR_TYPE_ITEM_ID;
|
||||
|
||||
nameid = item_list[i*2+1] = nd->u.shop.shop_item[j].nameid; //item_avail replacement
|
||||
nameid = item_list[i].itemId = nd->u.shop.shop_item[j].nameid; //item_avail replacement
|
||||
|
||||
if( !itemdb_isstackable2(id) && amount > 1 )
|
||||
{
|
||||
ShowWarning("Player %s (%d:%d) sent a hexed packet trying to buy %d of nonstackable item %hu!\n", sd->status.name, sd->status.account_id, sd->status.char_id, amount, nameid);
|
||||
amount = item_list[i*2+0] = 1;
|
||||
amount = item_list[i].amount = 1;
|
||||
}
|
||||
|
||||
switch( pc_checkadditem(sd,nameid,amount) )
|
||||
@ -1745,8 +1745,8 @@ int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, uns
|
||||
|
||||
// Delivery Process ----------------------------------------------------
|
||||
for( i = 0; i < count; i++ ) {
|
||||
nameid = item_list[i*2+1];
|
||||
amount = item_list[i*2+0];
|
||||
nameid = item_list[i].itemId;
|
||||
amount = item_list[i].amount;
|
||||
|
||||
if( !pet_create_egg(sd,nameid) ) {
|
||||
struct item item_tmp;
|
||||
@ -3040,7 +3040,7 @@ static const char* npc_parse_shop(char* w1, char* w2, char* w3, char* w4, const
|
||||
nd->u.shop.shop_item[nd->u.shop.count].value = value;
|
||||
#if PACKETVER >= 20131223
|
||||
nd->u.shop.shop_item[nd->u.shop.count].flag = 0;
|
||||
if (type == NPCTYPE_MARKETSHOP)
|
||||
if (type == NPCTYPE_MARKETSHOP )
|
||||
nd->u.shop.shop_item[nd->u.shop.count].qty = qty;
|
||||
#endif
|
||||
nd->u.shop.count++;
|
||||
|
@ -33,11 +33,23 @@ struct npc_item_list {
|
||||
#endif
|
||||
};
|
||||
|
||||
#if !defined(sun) && (!defined(__NETBSD__) || __NetBSD_Version__ >= 600000000) // NetBSD 5 and Solaris don't like pragma pack but accept the packed attribute
|
||||
#pragma pack(push, 1)
|
||||
#endif // not NetBSD < 6 / Solaris
|
||||
|
||||
/// List of bought/sold item for NPC shops
|
||||
struct s_npc_buy_list {
|
||||
unsigned short qty; ///< Amount of item will be bought
|
||||
unsigned short nameid; ///< ID of item will be bought
|
||||
};
|
||||
#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
|
||||
uint32 nameid; ///< ID of item will be bought
|
||||
#else
|
||||
uint16 nameid; ///< ID of item will be bought
|
||||
#endif
|
||||
} __attribute__((packed));
|
||||
|
||||
#if !defined(sun) && (!defined(__NETBSD__) || __NetBSD_Version__ >= 600000000) // NetBSD 5 and Solaris don't like pragma pack but accept the packed attribute
|
||||
#pragma pack(pop)
|
||||
#endif // not NetBSD < 6 / Solaris
|
||||
|
||||
struct npc_data {
|
||||
struct block_list bl;
|
||||
@ -1266,7 +1278,7 @@ void npc_shop_currency_type(struct map_session_data *sd, struct npc_data *nd, in
|
||||
|
||||
extern struct npc_data* fake_nd;
|
||||
|
||||
int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, unsigned short* item_list);
|
||||
int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, struct PACKET_CZ_PC_BUY_CASH_POINT_ITEM_sub* item_list);
|
||||
bool npc_shop_discount(struct npc_data* nd);
|
||||
|
||||
#if PACKETVER >= 20131223
|
||||
|
178
src/map/packets.hpp
Normal file
178
src/map/packets.hpp
Normal file
@ -0,0 +1,178 @@
|
||||
// Copyright (c) rAthena Dev Teams - Licensed under GNU GPL
|
||||
// For more information, see LICENCE in the main folder
|
||||
|
||||
#ifndef PACKETS_HPP
|
||||
#define PACKETS_HPP
|
||||
|
||||
#pragma warning( push )
|
||||
#pragma warning( disable : 4200 )
|
||||
|
||||
// Required for MESSAGE_SIZE, TALKBOX_MESSAGE_SIZE
|
||||
#include "map.hpp"
|
||||
|
||||
#define MAX_ITEM_OPTIONS MAX_ITEM_RDM_OPT
|
||||
#define UNAVAILABLE_STRUCT int8 _____unavailable
|
||||
/* packet size constant for itemlist */
|
||||
#if MAX_INVENTORY > MAX_STORAGE && MAX_INVENTORY > MAX_CART
|
||||
#define MAX_ITEMLIST MAX_INVENTORY
|
||||
#elif MAX_CART > MAX_INVENTORY && MAX_CART > MAX_STORAGE
|
||||
#define MAX_ITEMLIST MAX_CART
|
||||
#else
|
||||
#define MAX_ITEMLIST MAX_STORAGE
|
||||
#endif
|
||||
#define MAX_ACHIEVEMENT_DB MAX_ACHIEVEMENT_OBJECTIVES
|
||||
|
||||
#define DEFINE_PACKET_HEADER(name, id) const uint16 HEADER_##name = id;
|
||||
|
||||
#include "packets_struct.hpp"
|
||||
|
||||
#undef MAX_ITEM_OPTIONS
|
||||
#undef UNAVAILABLE_STRUCT
|
||||
#undef MAX_ITEMLIST
|
||||
#undef MAX_ACHIEVEMENT_DB
|
||||
#undef MAX_PACKET_POS
|
||||
|
||||
#undef DEFINE_PACKET_HEADER
|
||||
|
||||
// NetBSD 5 and Solaris don't like pragma pack but accept the packed attribute
|
||||
#if !defined( sun ) && ( !defined( __NETBSD__ ) || __NetBSD_Version__ >= 600000000 )
|
||||
#pragma pack( push, 1 )
|
||||
#endif
|
||||
|
||||
struct PACKET_CZ_SE_PC_BUY_CASHITEM_LIST_sub{
|
||||
uint32 itemId;
|
||||
uint32 amount;
|
||||
uint16 tab;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct PACKET_CZ_SE_PC_BUY_CASHITEM_LIST{
|
||||
int16 packetType;
|
||||
int16 packetLength;
|
||||
uint16 count;
|
||||
uint32 kafraPoints;
|
||||
struct PACKET_CZ_SE_PC_BUY_CASHITEM_LIST_sub items[];
|
||||
} __attribute__((packed));
|
||||
|
||||
struct PACKET_CZ_REQ_CASH_BARGAIN_SALE_ITEM_INFO{
|
||||
int16 packetType;
|
||||
int16 packetLength;
|
||||
uint32 AID;
|
||||
#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
|
||||
uint32 itemId;
|
||||
#else
|
||||
uint16 itemId;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct PACKET_ZC_ACK_CASH_BARGAIN_SALE_ITEM_INFO{
|
||||
int16 packetType;
|
||||
uint16 result;
|
||||
#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
|
||||
uint32 itemId;
|
||||
#else
|
||||
uint16 itemId;
|
||||
#endif
|
||||
uint32 price;
|
||||
};
|
||||
|
||||
struct PACKET_CZ_REQ_APPLY_BARGAIN_SALE_ITEM{
|
||||
int16 packetType;
|
||||
uint32 AID;
|
||||
#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
|
||||
uint32 itemId;
|
||||
#else
|
||||
uint16 itemId;
|
||||
#endif
|
||||
uint32 amount;
|
||||
uint32 startTime;
|
||||
#if PACKETVER >= 20150520
|
||||
uint16 hours;
|
||||
#else
|
||||
uint8 hours;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct PACKET_CZ_REQ_REMOVE_BARGAIN_SALE_ITEM{
|
||||
int16 packetType;
|
||||
uint32 AID;
|
||||
#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
|
||||
uint32 itemId;
|
||||
#else
|
||||
uint16 itemId;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct PACKET_ZC_NOTIFY_BARGAIN_SALE_SELLING{
|
||||
int16 packetType;
|
||||
#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
|
||||
uint32 itemId;
|
||||
#else
|
||||
uint16 itemId;
|
||||
#endif
|
||||
uint32 remainingTime;
|
||||
};
|
||||
|
||||
struct PACKET_ZC_NOTIFY_BARGAIN_SALE_CLOSE{
|
||||
int16 packetType;
|
||||
#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
|
||||
uint32 itemId;
|
||||
#else
|
||||
uint16 itemId;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct PACKET_ZC_ACK_COUNT_BARGAIN_SALE_ITEM{
|
||||
int16 packetType;
|
||||
#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
|
||||
uint32 itemId;
|
||||
#else
|
||||
uint16 itemId;
|
||||
#endif
|
||||
uint32 amount;
|
||||
};
|
||||
|
||||
struct PACKET_ZC_ACK_GUILDSTORAGE_LOG_sub{
|
||||
uint32 id;
|
||||
#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
|
||||
uint32 itemId;
|
||||
#else
|
||||
uint16 itemId;
|
||||
#endif
|
||||
int32 amount;
|
||||
uint8 action;
|
||||
int32 refine;
|
||||
int64 uniqueId;
|
||||
uint8 IsIdentified;
|
||||
uint16 itemType;
|
||||
struct EQUIPSLOTINFO slot;
|
||||
char name[NAME_LENGTH];
|
||||
char time[NAME_LENGTH];
|
||||
uint8 attribute;
|
||||
};
|
||||
|
||||
struct PACKET_ZC_ACK_GUILDSTORAGE_LOG{
|
||||
int16 packetType;
|
||||
int16 PacketLength;
|
||||
uint16 result;
|
||||
uint16 amount;
|
||||
struct PACKET_ZC_ACK_GUILDSTORAGE_LOG_sub items[];
|
||||
};
|
||||
|
||||
// NetBSD 5 and Solaris don't like pragma pack but accept the packed attribute
|
||||
#if !defined( sun ) && ( !defined( __NETBSD__ ) || __NetBSD_Version__ >= 600000000 )
|
||||
#pragma pack( pop )
|
||||
#endif
|
||||
|
||||
const uint16 HEADER_CZ_REQ_CASH_BARGAIN_SALE_ITEM_INFO = 0x9ac;
|
||||
const uint16 HEADER_ZC_ACK_CASH_BARGAIN_SALE_ITEM_INFO = 0x9ad;
|
||||
const uint16 HEADER_CZ_REQ_APPLY_BARGAIN_SALE_ITEM = 0x9ae;
|
||||
const uint16 HEADER_CZ_REQ_REMOVE_BARGAIN_SALE_ITEM = 0x9b0;
|
||||
const uint16 HEADER_ZC_NOTIFY_BARGAIN_SALE_SELLING = 0x9b2;
|
||||
const uint16 HEADER_ZC_NOTIFY_BARGAIN_SALE_CLOSE = 0x9b3;
|
||||
const uint16 HEADER_ZC_ACK_COUNT_BARGAIN_SALE_ITEM = 0x9c4;
|
||||
const uint16 HEADER_PACKET_ZC_ACK_GUILDSTORAGE_LOG = 0x9da;
|
||||
const uint16 HEADER_CZ_REQ_APPLY_BARGAIN_SALE_ITEM2 = 0xa3d;
|
||||
|
||||
#pragma warning( pop )
|
||||
|
||||
#endif /* PACKETS_HPP */
|
3877
src/map/packets_struct.hpp
Normal file
3877
src/map/packets_struct.hpp
Normal file
File diff suppressed because it is too large
Load Diff
@ -800,12 +800,12 @@ void pc_inventory_rentals(struct map_session_data *sd)
|
||||
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->inventory.u.items_inventory[i].nameid);
|
||||
clif_rental_expired(sd, 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 {
|
||||
unsigned int expire_tick = (unsigned int)(sd->inventory.u.items_inventory[i].expire_time - time(NULL));
|
||||
|
||||
clif_rental_time(sd->fd, sd->inventory.u.items_inventory[i].nameid, (int)expire_tick);
|
||||
clif_rental_time(sd, sd->inventory.u.items_inventory[i].nameid, (int)expire_tick);
|
||||
next_tick = umin(expire_tick * 1000U, next_tick);
|
||||
c++;
|
||||
}
|
||||
@ -1539,6 +1539,11 @@ bool pc_authok(struct map_session_data *sd, uint32 login_id2, time_t expiration_
|
||||
sd->respawn_tid = INVALID_TIMER;
|
||||
sd->tid_queue_active = INVALID_TIMER;
|
||||
|
||||
sd->skill_keep_using.tid = INVALID_TIMER;
|
||||
sd->skill_keep_using.skill_id = 0;
|
||||
sd->skill_keep_using.level = 0;
|
||||
sd->skill_keep_using.target = 0;
|
||||
|
||||
#ifdef SECURE_NPCTIMEOUT
|
||||
// Initialize to defaults/expected
|
||||
sd->npc_idle_timer = INVALID_TIMER;
|
||||
@ -5055,11 +5060,11 @@ enum e_additem_result pc_additem(struct map_session_data *sd,struct item *item,i
|
||||
/* rental item check */
|
||||
if( item->expire_time ) {
|
||||
if( time(NULL) > item->expire_time ) {
|
||||
clif_rental_expired(sd->fd, i, sd->inventory.u.items_inventory[i].nameid);
|
||||
clif_rental_expired(sd, 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->inventory.u.items_inventory[i].nameid, seconds);
|
||||
clif_rental_time(sd, sd->inventory.u.items_inventory[i].nameid, seconds);
|
||||
pc_inventory_rental_add(sd, seconds);
|
||||
}
|
||||
}
|
||||
@ -5567,7 +5572,7 @@ enum e_additem_result pc_cart_additem(struct map_session_data *sd,struct item *i
|
||||
return ADDITEM_OVERAMOUNT; // no slot
|
||||
|
||||
sd->cart.u.items_cart[i].amount += amount;
|
||||
clif_cart_additem(sd,i,amount,0);
|
||||
clif_cart_additem(sd,i,amount);
|
||||
}
|
||||
else
|
||||
{// item not stackable or not present, add it
|
||||
@ -5579,7 +5584,7 @@ enum e_additem_result pc_cart_additem(struct map_session_data *sd,struct item *i
|
||||
sd->cart.u.items_cart[i].id = 0;
|
||||
sd->cart.u.items_cart[i].amount = amount;
|
||||
sd->cart_num++;
|
||||
clif_cart_additem(sd,i,amount,0);
|
||||
clif_cart_additem(sd,i,amount);
|
||||
}
|
||||
sd->cart.u.items_cart[i].favorite = 0; // clear
|
||||
sd->cart.u.items_cart[i].equipSwitch = 0;
|
||||
@ -5688,7 +5693,7 @@ void pc_getitemfromcart(struct map_session_data *sd,int idx,int amount)
|
||||
else {
|
||||
clif_cart_delitem(sd, idx, amount);
|
||||
clif_additem(sd, idx, amount, flag);
|
||||
clif_cart_additem(sd, idx, amount, 0);
|
||||
clif_cart_additem(sd, idx, amount);
|
||||
}
|
||||
}
|
||||
|
||||
@ -9509,6 +9514,10 @@ void pc_setoption(struct map_session_data *sd,int type)
|
||||
status_change_end(&sd->bl,statuses[i],INVALID_TIMER);
|
||||
}
|
||||
pc_bonus_script_clear(sd,BSF_REM_ON_MADOGEAR);
|
||||
|
||||
#if PACKETVER_MAIN_NUM >= 20191120 || PACKETVER_RE_NUM >= 20191106
|
||||
clif_status_load( &sd->bl, EFST_MADOGEAR, 1 );
|
||||
#endif
|
||||
} else if( !(type&OPTION_MADOGEAR) && p_type&OPTION_MADOGEAR ) {
|
||||
status_calc_pc(sd,SCO_NONE);
|
||||
status_change_end(&sd->bl,SC_SHAPESHIFT,INVALID_TIMER);
|
||||
@ -9520,6 +9529,10 @@ void pc_setoption(struct map_session_data *sd,int type)
|
||||
status_change_end(&sd->bl,SC_NEUTRALBARRIER_MASTER,INVALID_TIMER);
|
||||
status_change_end(&sd->bl,SC_STEALTHFIELD_MASTER,INVALID_TIMER);
|
||||
pc_bonus_script_clear(sd,BSF_REM_ON_MADOGEAR);
|
||||
|
||||
#if PACKETVER_MAIN_NUM >= 20191120 || PACKETVER_RE_NUM >= 20191106
|
||||
clif_status_load( &sd->bl, EFST_MADOGEAR, 0 );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -769,6 +769,13 @@ struct map_session_data {
|
||||
uint32* hatEffectIDs;
|
||||
uint8 hatEffectCount;
|
||||
#endif
|
||||
|
||||
struct{
|
||||
int tid;
|
||||
uint16 skill_id;
|
||||
uint16 level;
|
||||
int target;
|
||||
} skill_keep_using;
|
||||
};
|
||||
|
||||
extern struct eri *pc_sc_display_ers; /// Player's SC display table
|
||||
|
@ -138,7 +138,7 @@ bool searchstore_open(struct map_session_data* sd, unsigned int uses, unsigned s
|
||||
* @param cardlist : list with stored cards (cards attached to items)
|
||||
* @param card_count : amount of items in cardlist
|
||||
*/
|
||||
void searchstore_query(struct map_session_data* sd, unsigned char type, unsigned int min_price, unsigned int max_price, const unsigned short* itemlist, unsigned int item_count, const unsigned short* cardlist, unsigned int card_count)
|
||||
void searchstore_query(struct map_session_data* sd, unsigned char type, unsigned int min_price, unsigned int max_price, const struct PACKET_CZ_SEARCH_STORE_INFO_item* itemlist, unsigned int item_count, const struct PACKET_CZ_SEARCH_STORE_INFO_item* cardlist, unsigned int card_count)
|
||||
{
|
||||
unsigned int i;
|
||||
struct map_session_data* pl_sd;
|
||||
@ -172,15 +172,15 @@ void searchstore_query(struct map_session_data* sd, unsigned char type, unsigned
|
||||
|
||||
// validate lists
|
||||
for( i = 0; i < item_count; i++ ) {
|
||||
if( !itemdb_exists(itemlist[i]) ) {
|
||||
ShowWarning("searchstore_query: Client resolved item %hu is not known.\n", itemlist[i]);
|
||||
if( !itemdb_exists(itemlist[i].itemId) ) {
|
||||
ShowWarning("searchstore_query: Client resolved item %hu is not known.\n", itemlist[i].itemId);
|
||||
clif_search_store_info_failed(sd, SSI_FAILED_NOTHING_SEARCH_ITEM);
|
||||
return;
|
||||
}
|
||||
}
|
||||
for( i = 0; i < card_count; i++ ) {
|
||||
if( !itemdb_exists(cardlist[i]) ) {
|
||||
ShowWarning("searchstore_query: Client resolved card %hu is not known.\n", cardlist[i]);
|
||||
if( !itemdb_exists(cardlist[i].itemId) ) {
|
||||
ShowWarning("searchstore_query: Client resolved card %hu is not known.\n", cardlist[i].itemId);
|
||||
clif_search_store_info_failed(sd, SSI_FAILED_NOTHING_SEARCH_ITEM);
|
||||
return;
|
||||
}
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "../common/cbasetypes.hpp"
|
||||
#include "../common/mmo.hpp"
|
||||
|
||||
#include "clif.hpp"
|
||||
#include "map.hpp"
|
||||
|
||||
#define SEARCHSTORE_RESULTS_PER_PAGE 10
|
||||
@ -14,8 +15,8 @@
|
||||
/// information about the search being performed
|
||||
struct s_search_store_search {
|
||||
struct map_session_data* search_sd; // sd of the searching player
|
||||
const unsigned short* itemlist;
|
||||
const unsigned short* cardlist;
|
||||
const struct PACKET_CZ_SEARCH_STORE_INFO_item* itemlist;
|
||||
const struct PACKET_CZ_SEARCH_STORE_INFO_item* cardlist;
|
||||
unsigned int item_count;
|
||||
unsigned int card_count;
|
||||
unsigned int min_price;
|
||||
@ -46,7 +47,7 @@ struct s_search_store_info {
|
||||
};
|
||||
|
||||
bool searchstore_open(struct map_session_data* sd, unsigned int uses, unsigned short effect);
|
||||
void searchstore_query(struct map_session_data* sd, unsigned char type, unsigned int min_price, unsigned int max_price, const unsigned short* itemlist, unsigned int item_count, const unsigned short* cardlist, unsigned int card_count);
|
||||
void searchstore_query(struct map_session_data* sd, unsigned char type, unsigned int min_price, unsigned int max_price, const struct PACKET_CZ_SEARCH_STORE_INFO_item* itemlist, unsigned int item_count, const struct PACKET_CZ_SEARCH_STORE_INFO_item* cardlist, unsigned int card_count);
|
||||
bool searchstore_querynext(struct map_session_data* sd);
|
||||
void searchstore_next(struct map_session_data* sd);
|
||||
void searchstore_clear(struct map_session_data* sd);
|
||||
|
@ -11733,6 +11733,16 @@ static int8 skill_castend_id_check(struct block_list *src, struct block_list *ta
|
||||
return -1;
|
||||
}
|
||||
|
||||
TIMER_FUNC( skill_keep_using ){
|
||||
struct map_session_data* sd = map_id2sd( id );
|
||||
|
||||
if( sd && sd->skill_keep_using.skill_id ){
|
||||
clif_parse_skill_toid( sd, sd->skill_keep_using.skill_id, sd->skill_keep_using.level, sd->skill_keep_using.target );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check & process skill to target on castend. Determines if skill is 'damage' or 'nodamage'
|
||||
* @param tid
|
||||
@ -11959,6 +11969,10 @@ TIMER_FUNC(skill_castend_id){
|
||||
else
|
||||
skill_castend_damage_id(src,target,ud->skill_id,ud->skill_lv,tick,flag);
|
||||
|
||||
if( sd && sd->skill_keep_using.skill_id == ud->skill_id ){
|
||||
sd->skill_keep_using.tid = add_timer( sd->ud.canact_tick + 100, skill_keep_using, sd->bl.id, 0 );
|
||||
}
|
||||
|
||||
sc = status_get_sc(src);
|
||||
if(sc && sc->count) {
|
||||
if (ud->skill_id != RA_CAMOUFLAGE)
|
||||
@ -12034,7 +12048,7 @@ TIMER_FUNC(skill_castend_id){
|
||||
//sent in ALL cases, even cases where skill_check_condition fails
|
||||
//which would lead to double 'skill failed' messages u.u [Skotlex]
|
||||
if(sd)
|
||||
sd->skillitem = sd->skillitemlv = sd->skillitem_keep_requirement = 0;
|
||||
sd->skillitem = sd->skillitemlv = sd->skillitem_keep_requirement = sd->skill_keep_using.skill_id = 0;
|
||||
else if(md)
|
||||
md->skill_idx = -1;
|
||||
return 0;
|
||||
@ -16637,7 +16651,7 @@ bool skill_check_condition_castend(struct map_session_data* sd, uint16 skill_id,
|
||||
else if( require.itemid[i] == ITEMID_ANCILLA )
|
||||
clif_skill_fail(sd,skill_id,USESKILL_FAIL_ANCILLA,0); //Ancilla is required.
|
||||
else
|
||||
clif_skill_fail( sd, skill_id, USESKILL_FAIL_NEED_ITEM, ( require.itemid[i] << 16 ) | require.amount[i] ); // [%s] required '%d' amount.
|
||||
clif_skill_fail( sd, skill_id, USESKILL_FAIL_NEED_ITEM, require.amount[i], require.itemid[i] ); // [%s] required '%d' amount.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -17572,11 +17586,11 @@ void skill_weaponrefine(struct map_session_data *sd, int idx)
|
||||
return;
|
||||
}
|
||||
if( item->refine >= sd->menuskill_val || item->refine >= 10 ) {
|
||||
clif_upgrademessage(sd->fd, 2, item->nameid);
|
||||
clif_upgrademessage(sd, 2, item->nameid);
|
||||
return;
|
||||
}
|
||||
if( (i = pc_search_inventory(sd, material [ditem->wlv])) < 0 ) {
|
||||
clif_upgrademessage(sd->fd, 3, material[ditem->wlv]);
|
||||
clif_upgrademessage(sd, 3, material[ditem->wlv]);
|
||||
return;
|
||||
}
|
||||
per = status_get_refine_chance(static_cast<refine_type>(ditem->wlv), (int)item->refine, false);
|
||||
@ -17596,7 +17610,7 @@ void skill_weaponrefine(struct map_session_data *sd, int idx)
|
||||
pc_unequipitem(sd,idx,3);
|
||||
}
|
||||
clif_delitem(sd,idx,1,3);
|
||||
clif_upgrademessage(sd->fd, 0, item->nameid);
|
||||
clif_upgrademessage(sd, 0, item->nameid);
|
||||
clif_inventorylist(sd);
|
||||
clif_refine(sd->fd,0,idx,item->refine);
|
||||
achievement_update_objective(sd, AG_REFINE_SUCCESS, 2, ditem->wlv, item->refine);
|
||||
@ -17623,7 +17637,7 @@ void skill_weaponrefine(struct map_session_data *sd, int idx)
|
||||
item->refine = 0;
|
||||
if(item->equip)
|
||||
pc_unequipitem(sd,idx,3);
|
||||
clif_upgrademessage(sd->fd, 1, item->nameid);
|
||||
clif_upgrademessage(sd, 1, item->nameid);
|
||||
clif_refine(sd->fd,1,idx,item->refine);
|
||||
achievement_update_objective(sd, AG_REFINE_FAIL, 1, 1);
|
||||
pc_delitem(sd,idx,1,0,2, LOG_TYPE_OTHER);
|
||||
|
@ -530,6 +530,7 @@ uint16 SKILL_MAX_DB(void);
|
||||
int skill_isammotype(struct map_session_data *sd, unsigned short skill_id);
|
||||
TIMER_FUNC(skill_castend_id);
|
||||
TIMER_FUNC(skill_castend_pos);
|
||||
TIMER_FUNC( skill_keep_using );
|
||||
int skill_castend_map( struct map_session_data *sd,uint16 skill_id, const char *map);
|
||||
|
||||
int skill_cleartimerskill(struct block_list *src);
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "itemdb.hpp"
|
||||
#include "log.hpp"
|
||||
#include "map.hpp" // struct map_session_data
|
||||
#include "packets.hpp"
|
||||
#include "pc.hpp"
|
||||
#include "pc_groups.hpp"
|
||||
|
||||
@ -741,8 +742,8 @@ enum e_guild_storage_log storage_guild_log_read_sub( struct map_session_data* sd
|
||||
enum e_guild_storage_log storage_guild_log_read( struct map_session_data* sd ){
|
||||
std::vector<struct guild_log_entry> log;
|
||||
|
||||
// ( 65535(maximum packet size) - 8(header) ) / 83 (entry size) = 789 (-1 for safety)
|
||||
enum e_guild_storage_log ret = storage_guild_log_read_sub( sd, log, 788 );
|
||||
// ( maximum packet size - header size ) / entry size ) - 1 (for safety)
|
||||
enum e_guild_storage_log ret = storage_guild_log_read_sub( sd, log, ( ( UINT16_MAX - sizeof( struct PACKET_ZC_ACK_GUILDSTORAGE_LOG ) ) / sizeof( struct PACKET_ZC_ACK_GUILDSTORAGE_LOG_sub ) ) - 1 );
|
||||
|
||||
clif_guild_storage_log( sd, log, ret );
|
||||
|
||||
|
@ -94,7 +94,7 @@ void vending_vendinglistreq(struct map_session_data* sd, int id)
|
||||
|
||||
sd->vended_id = vsd->vender_id; // register vending uid
|
||||
|
||||
clif_vendinglist(sd, id, vsd->vending);
|
||||
clif_vendinglist( sd, vsd );
|
||||
}
|
||||
|
||||
/**
|
||||
@ -433,7 +433,7 @@ 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->cart.u.items_cart[sd->vending[i].index].nameid == s->itemlist[idx] );
|
||||
ARR_FIND( 0, sd->vend_num, i, sd->cart.u.items_cart[sd->vending[i].index].nameid == s->itemlist[idx].itemId );
|
||||
if( i == sd->vend_num ) { // not found
|
||||
continue;
|
||||
}
|
||||
@ -454,7 +454,7 @@ bool vending_searchall(struct map_session_data* sd, const struct s_search_store_
|
||||
slot = itemdb_slot(it->nameid);
|
||||
|
||||
for( c = 0; c < slot && it->card[c]; c ++ ) {
|
||||
ARR_FIND( 0, s->card_count, cidx, s->cardlist[cidx] == it->card[c] );
|
||||
ARR_FIND( 0, s->card_count, cidx, s->cardlist[cidx].itemId == it->card[c] );
|
||||
if( cidx != s->card_count ) { // found
|
||||
break;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user