From 239d480487e24294975f35ed55f210837ad1088e Mon Sep 17 00:00:00 2001 From: shennetsind Date: Mon, 3 Nov 2014 08:10:26 -0200 Subject: Introducing 2014-10-22, Roulette and Per-Char Gender! Details in http://hercules.ws/board/topic/7618-2014-10-22-roulette-and-per-char-gender/ Special Thanks to the all-mighty Yommy, Ziu and Haruna! Signed-off-by: shennetsind --- src/map/battle.c | 10 +- src/map/battle.h | 2 + src/map/clif.c | 348 +++++++++++++++++++++++++++++++++++++++++++++-- src/map/clif.h | 46 +++++++ src/map/itemdb.c | 4 + src/map/itemdb.h | 1 + src/map/packets.h | 90 ++++++++++++ src/map/packets_struct.h | 62 ++++++++- src/map/pc.h | 7 + 9 files changed, 555 insertions(+), 15 deletions(-) (limited to 'src/map') diff --git a/src/map/battle.c b/src/map/battle.c index 1b8e44cb3..8aeb22fc2 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -6837,7 +6837,8 @@ static const struct battle_data { { "song_timer_reset", &battle_config.song_timer_reset, 0, 0, 1, }, { "snap_dodge", &battle_config.snap_dodge, 0, 0, 1, }, { "monster_chase_refresh", &battle_config.mob_chase_refresh, 1, 0, 30, }, - { "icewall_walk_block", &battle_config.icewall_walk_block, 75, 0, 255, } + { "icewall_walk_block", &battle_config.icewall_walk_block, 75, 0, 255, }, + { "feature.roulette", &battle_config.feature_roulette, 1, 0, 1, } }; #ifndef STATS_OPT_OUT /** @@ -7088,6 +7089,13 @@ void battle_adjust_conf(void) { battle_config.feature_banking = 0; } #endif + +#if PACKETVER < 20141022 + if( battle_config.feature_roulette ) { + ShowWarning("conf/battle/feature.conf roulette is enabled but it requires PACKETVER 2014-10-22 or newer, disabling...\n"); + battle_config.feature_roulette = 0; + } +#endif #if PACKETVER > 20120000 && PACKETVER < 20130515 /* exact date (when it started) not known */ if( battle_config.feature_auction == 1 ) { diff --git a/src/map/battle.h b/src/map/battle.h index 6ac2df391..8164153da 100644 --- a/src/map/battle.h +++ b/src/map/battle.h @@ -479,6 +479,8 @@ struct Battle_Config { int song_timer_reset; // [csnv] int snap_dodge; // Enable or disable dodging damage snapping away [csnv] + + int feature_roulette; }; extern struct Battle_Config battle_config; diff --git a/src/map/clif.c b/src/map/clif.c index b9cd4cbaf..73fc387e3 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -619,7 +619,9 @@ void clif_authok(struct map_session_data *sd) #if PACKETVER >= 20080102 p.font = sd->status.font; #endif - +#if PACKETVER >= 20141016 + p.sex = sd->status.sex; +#endif clif->send(&p,sizeof(p),&sd->bl,SELF); } @@ -5580,6 +5582,7 @@ void clif_status_change(struct block_list *bl,int type,int flag,int tick,int val p.index = type; p.AID = bl->id; p.state = (unsigned char)flag; + #if PACKETVER >= 20120618 p.Total = tick; /* at this stage remain and total are the same value I believe */ #endif @@ -5600,6 +5603,11 @@ void clif_displaymessage(const int fd, const char* mes) { if( map->cpsd_active && fd == 0 ) { ShowInfo("HCP: %s\n",mes); } else if ( fd > 0 ) { + #if PACKETVER == 20141022 + /** for some reason game client crashes depending on message pattern (only for this packet) **/ + /** so we redirect to ZC_NPC_CHAT **/ + clif->colormes(fd,COLOR_DEFAULT,mes); + #else size_t len; if ( ( len = strnlen(mes, 255) ) > 0 ) { // don't send a void message (it's not displaying on the client chat). @help can send void line. @@ -5609,6 +5617,7 @@ void clif_displaymessage(const int fd, const char* mes) { safestrncpy((char *)WFIFOP(fd,4), mes, len + 1); WFIFOSET(fd, 5 + len); } + #endif } } void clif_displaymessage2(const int fd, const char* mes) { @@ -9651,18 +9660,22 @@ void clif_hotkeys_send(struct map_session_data *sd) { #ifdef HOTKEY_SAVING const int fd = sd->fd; int i; + int offset = 2; #if PACKETVER < 20090603 const int cmd = 0x2b9; -#else +#elif PACKETVER < 20141022 const int cmd = 0x7d9; +#else + const int cmd = 0xa00; + offset = 3; #endif if (!fd) return; - WFIFOHEAD(fd, 2+MAX_HOTKEYS*7); + WFIFOHEAD(fd, offset+MAX_HOTKEYS*7); WFIFOW(fd, 0) = cmd; for(i = 0; i < MAX_HOTKEYS; i++) { - WFIFOB(fd, 2 + 0 + i * 7) = sd->status.hotkeys[i].type; // type: 0: item, 1: skill - WFIFOL(fd, 2 + 1 + i * 7) = sd->status.hotkeys[i].id; // item or skill ID - WFIFOW(fd, 2 + 5 + i * 7) = sd->status.hotkeys[i].lv; // skill level + WFIFOB(fd, offset + 0 + i * 7) = sd->status.hotkeys[i].type; // type: 0: item, 1: skill + WFIFOL(fd, offset + 1 + i * 7) = sd->status.hotkeys[i].id; // item or skill ID + WFIFOW(fd, offset + 5 + i * 7) = sd->status.hotkeys[i].lv; // item qty or skill level } WFIFOSET(fd, packet_len(cmd)); #endif @@ -15799,19 +15812,34 @@ void clif_parse_PartyTick(int fd, struct map_session_data* sd) /// 02b1 .W .L { .L .B }*num void clif_quest_send_list(struct map_session_data *sd) { int fd = sd->fd; - int i; - int len = sd->avail_quests*5+8; - + int i; +#if PACKETVER >= 20141022 + int info_len = 15; + int len = sd->avail_quests*info_len+8; WFIFOHEAD(fd,len); - WFIFOW(fd, 0) = 0x2b1; + WFIFOW(fd, 0) = 0x97a; +#else + int info_len = 5; + int len = sd->avail_quests*info_len+8; + WFIFOHEAD(fd,len); + WFIFOW(fd, 0) = 0x2b1; +#endif WFIFOW(fd, 2) = len; WFIFOL(fd, 4) = sd->avail_quests; for( i = 0; i < sd->avail_quests; i++ ) { - WFIFOL(fd, i*5+8) = sd->quest_log[i].quest_id; - WFIFOB(fd, i*5+12) = sd->quest_log[i].state; + #if PACKETVER >= 20141022 + struct quest_db *qi = quest->db(sd->quest_log[i].quest_id); + #endif + WFIFOL(fd, i*info_len+8) = sd->quest_log[i].quest_id; + WFIFOB(fd, i*info_len+12) = sd->quest_log[i].state; + #if PACKETVER >= 20141022 + WFIFOL(fd, i*info_len+13) = sd->quest_log[i].time - qi->time; + WFIFOL(fd, i*info_len+17) = sd->quest_log[i].time; + WFIFOW(fd, i*info_len+21) = qi->num_objectives; + #endif } - + WFIFOSET(fd, len); } @@ -18270,7 +18298,285 @@ void clif_PartyLeaderChanged(struct map_session_data *sd, int prev_leader_aid, i clif->send(&p,sizeof(p),&sd->bl,PARTY); } + +/* Roulette System [Yommy/Hercules] */ +void clif_parse_RouletteOpen(int fd, struct map_session_data* sd) { + struct packet_roulette_open_ack p; + if( !battle_config.feature_roulette ) { + clif->message(fd,"Roulette is disabled"); + return; + } + + p.PacketType = 0xa1a; + p.Result = 0; + p.Serial = 0; + p.Step = sd->roulette.stage - 1; + p.Idx = sd->roulette.prizeIdx; + p.AdditionItemID = -1; /** TODO **/ + p.BronzePoint = pc_readglobalreg(sd, script->add_str("TmpRouletteBronze")); + p.GoldPoint = pc_readglobalreg(sd, script->add_str("TmpRouletteGold")); + p.SilverPoint = pc_readglobalreg(sd, script->add_str("TmpRouletteSilver")); + + clif->send(&p,sizeof(p), &sd->bl, SELF); +} +void clif_parse_RouletteInfo(int fd, struct map_session_data* sd) { + struct packet_roulette_info_ack p; + unsigned short i, j, count = 0; + + if( !battle_config.feature_roulette ) { + clif->message(fd,"Roulette is disabled"); + return; + } + + p.PacketType = rouletteinfoackType; + p.PacketLength = 8 + (42 * 8); + p.RouletteSerial = 1; + + for(i = 0; i < MAX_ROULETTE_LEVEL; i++) { + for(j = 0; j < MAX_ROULETTE_COLUMNS-i; j++) { + p.ItemInfo[count].Row = i; + p.ItemInfo[count].Position = j; + p.ItemInfo[count].ItemId = clif->rd.nameid[i][j]; + p.ItemInfo[count].Count = clif->rd.qty[i][j]; + count++; + } + } + + clif->send(&p,sizeof(p), &sd->bl, SELF); + return; +} +void clif_parse_RouletteClose(int fd, struct map_session_data* sd) { + + if( !battle_config.feature_roulette ) { + clif->message(fd,"Roulette is disabled"); + return; + } + + + /** What do we need this for? (other than state tracking), game client closes the window without our response. **/ + + //ShowDebug("clif_parse_RouletteClose\n"); + + return; +} +void clif_parse_RouletteGenerate(int fd, struct map_session_data* sd) { + unsigned char result = GENERATE_ROULETTE_SUCCESS; + short stage = sd->roulette.stage; + + if( !battle_config.feature_roulette ) { + clif->message(fd,"Roulette is disabled"); + return; + } + + if( sd->roulette.stage >= MAX_ROULETTE_LEVEL ) + stage = sd->roulette.stage = 0; + + if( stage <= 2 ) { + if( pc_readglobalreg(sd, script->add_str("TmpRouletteBronze")) <= 0 ) + result = GENERATE_ROULETTE_NO_ENOUGH_POINT; + } else if ( stage <= 4 ) { + if( pc_readglobalreg(sd, script->add_str("TmpRouletteSilver")) <= 0 ) + result = GENERATE_ROULETTE_NO_ENOUGH_POINT; + } else if ( stage <= 6 ) { + if( pc_readglobalreg(sd, script->add_str("TmpRouletteGold")) <= 0 ) + result = GENERATE_ROULETTE_NO_ENOUGH_POINT; + } + + if( result == GENERATE_ROULETTE_SUCCESS ) { + + if( stage <= 2 ) { + pc_setglobalreg(sd, script->add_str("TmpRouletteBronze"), pc_readglobalreg(sd, script->add_str("TmpRouletteBronze")) - 1); + } else if ( stage <= 4 ) { + pc_setglobalreg(sd, script->add_str("TmpRouletteSilver"), pc_readglobalreg(sd, script->add_str("TmpRouletteSilver")) - 1); + } else if ( stage <= 6 ) { + pc_setglobalreg(sd, script->add_str("TmpRouletteGold"), pc_readglobalreg(sd, script->add_str("TmpRouletteGold")) - 1); + } + + sd->roulette.prizeStage = stage; + sd->roulette.prizeIdx = rnd()%clif->rd.items[stage]; + if( sd->roulette.prizeIdx == 0 ) { + struct item it; + memset(&it, 0, sizeof(it)); + + it.nameid = clif->rd.nameid[stage][0]; + it.identify = 1; + + pc->additem(sd, &it, clif->rd.qty[stage][0], LOG_TYPE_OTHER);/** TODO maybe a new log type for roulette items? **/ + + sd->roulette.stage = 0; + result = GENERATE_ROULETTE_LOSING; + } else + sd->roulette.claimPrize = true; + } + + clif->roulette_generate_ack(sd,result,stage,sd->roulette.prizeIdx,0); + if( result == GENERATE_ROULETTE_SUCCESS ) + sd->roulette.stage++; +} +/** + * Request to cash in! + **/ +void clif_parse_RouletteRecvItem(int fd, struct map_session_data* sd) { + struct packet_roulette_itemrecv_ack p; + + if( !battle_config.feature_roulette ) { + clif->message(fd,"Roulette is disabled"); + return; + } + + p.PacketType = roulettercvitemackType; + p.AdditionItemID = 0;/** TODO **/ + + if( sd->roulette.claimPrize ) { + struct item it; + memset(&it, 0, sizeof(it)); + + it.nameid = clif->rd.nameid[sd->roulette.prizeStage][sd->roulette.prizeIdx]; + it.identify = 1; + + switch (pc->additem(sd, &it, clif->rd.qty[sd->roulette.prizeStage][sd->roulette.prizeIdx], LOG_TYPE_OTHER)) { + case 0: + p.Result = RECV_ITEM_SUCCESS; + sd->roulette.claimPrize = false; + sd->roulette.prizeStage = 0; + sd->roulette.prizeIdx = 0; + sd->roulette.stage = 0; + break; + case 1: + case 4: + case 5: + p.Result = RECV_ITEM_OVERCOUNT; + break; + case 2: + p.Result = RECV_ITEM_OVERWEIGHT; + break; + default: + case 7: + p.Result = RECV_ITEM_FAILED; + break; + } + } else + p.Result = RECV_ITEM_FAILED; + + clif->send(&p,sizeof(p), &sd->bl, SELF); + return; +} + +bool clif_parse_roulette_db(void) { + config_t roulette_conf; + config_setting_t *roulette = NULL, *levels = NULL; + const char *config_filename = "db/roulette_db.conf"; // FIXME hardcoded name + int i, j, item_count_t = 0; + + for( i = 0; i < MAX_ROULETTE_LEVEL; i++ ) { + clif->rd.items[i] = 0; + } + + if (libconfig->read_file(&roulette_conf, config_filename)) { + ShowError("can't read %s\n", config_filename); + return false; + } + + roulette = libconfig->lookup(&roulette_conf, "roulette"); + + if( roulette != NULL && (levels = libconfig->setting_get_elem(roulette, 0)) != NULL ) { + for(i = 0; i < MAX_ROULETTE_LEVEL; i++) { + config_setting_t *level; + char entry_name[10]; + + sprintf(entry_name,"level_%d",i+1); + + if( (level = libconfig->setting_get_member(levels, entry_name)) != NULL ) { + int k, item_count = libconfig->setting_length(level); + + for(k = 0; k < item_count; k++) { + config_setting_t *entry = libconfig->setting_get_elem(level,k); + const char *name = config_setting_name(entry); + int qty = libconfig->setting_get_int(entry); + struct item_data * data = NULL; + + if( qty < 1 ) { + ShowWarning("roulette_db: unsupported qty '%d' for entry named '%s' in category '%s'\n", qty, name, entry_name); + continue; + } + + if( name[0] == 'I' && name[1] == 'D' && strlen(name) <= 7 ) { + if( !( data = itemdb->exists(atoi(name+2))) ) { + ShowWarning("roulette_db: unknown item id '%s' in category '%s'\n", name+2, entry_name); + continue; + } + } else { + if( !( data = itemdb->search_name(name) ) ) { + ShowWarning("roulette_db: unknown item name '%s' in category '%s'\n", name, entry_name); + continue; + } + } + + j = clif->rd.items[i]; + RECREATE(clif->rd.nameid[i],int,++clif->rd.items[i]); + RECREATE(clif->rd.qty[i],int,clif->rd.items[i]); + + clif->rd.nameid[i][j] = data->nameid; + clif->rd.qty[i][j] = qty; + + item_count_t++; + } + } + } + + libconfig->destroy(&roulette_conf); + } + + for(i = 0; i < MAX_ROULETTE_LEVEL; i++) { + int limit = MAX_ROULETTE_COLUMNS-i; + if( clif->rd.items[i] == limit ) continue; + + if( clif->rd.items[i] > limit ) { + ShowWarning("roulette_db: level %d has %d items, only %d supported, capping...\n",i+1,clif->rd.items[i],limit); + clif->rd.items[i] = limit; + continue; + } + /** this scenario = clif->rd.items[i] < limit **/ + ShowWarning("roulette_db: level %d has %d items, %d are required. filling with apples\n",i+1,clif->rd.items[i],limit); + + clif->rd.items[i] = limit; + RECREATE(clif->rd.nameid[i],int,clif->rd.items[i]); + RECREATE(clif->rd.qty[i],int,clif->rd.items[i]); + + + for(j = 0; j < MAX_ROULETTE_COLUMNS-i; j++) { + if( clif->rd.qty[i][j] ) continue; + + clif->rd.nameid[i][j] = ITEMID_APPLE; + clif->rd.qty[i][j] = 1; + } + } + + + ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", item_count_t, config_filename); + + return true; +} + +/** + * + **/ +void clif_roulette_generate_ack(struct map_session_data *sd, unsigned char result, short stage, short prizeIdx, short bonusItemID) { + struct packet_roulette_generate_ack p; + + p.PacketType = roulettgenerateackType; + p.Result = result; + p.Step = stage; + p.Idx = prizeIdx; + p.AdditionItemID = bonusItemID; + p.RemainBronze = pc_readglobalreg(sd, script->add_str("TmpRouletteBronze")); + p.RemainGold = pc_readglobalreg(sd, script->add_str("TmpRouletteGold")); + p.RemainSilver = pc_readglobalreg(sd, script->add_str("TmpRouletteSilver")); + + clif->send(&p,sizeof(p), &sd->bl, SELF); +} + /* */ unsigned short clif_decrypt_cmd( int cmd, struct map_session_data *sd ) { if( sd ) { @@ -18587,6 +18893,13 @@ void do_final_clif(void) { } aFree(clif->cs.data[i]); } + + for(i = 0; i < MAX_ROULETTE_LEVEL; i++) { + if( clif->rd.nameid[i] ) + aFree(clif->rd.nameid[i]); + if( clif->rd.qty[i] ) + aFree(clif->rd.qty[i]); + } } void clif_defaults(void) { @@ -19088,6 +19401,9 @@ void clif_defaults(void) { /* NPC Market */ clif->npc_market_open = clif_npc_market_open; clif->npc_market_purchase_ack = clif_npc_market_purchase_ack; + /* */ + clif->parse_roulette_db = clif_parse_roulette_db; + clif->roulette_generate_ack = clif_roulette_generate_ack; /*------------------------ *- Parse Incoming Packet *------------------------*/ @@ -19317,6 +19633,12 @@ void clif_defaults(void) { clif->pBankCheck = clif_parse_BankCheck; clif->pBankOpen = clif_parse_BankOpen; clif->pBankClose = clif_parse_BankClose; + /* Roulette System [Yommy/Hercules] */ + clif->pRouletteOpen = clif_parse_RouletteOpen; + clif->pRouletteInfo = clif_parse_RouletteInfo; + clif->pRouletteClose = clif_parse_RouletteClose; + clif->pRouletteGenerate = clif_parse_RouletteGenerate; + clif->pRouletteRecvItem = clif_parse_RouletteRecvItem; /* */ clif->pNPCShopClosed = clif_parse_NPCShopClosed; /* NPC Market */ diff --git a/src/map/clif.h b/src/map/clif.h index 1013add85..17fda9a74 100644 --- a/src/map/clif.h +++ b/src/map/clif.h @@ -48,6 +48,8 @@ struct skill_cd; #define clif_disp_onlyself(sd,mes,len) clif->disp_message( &(sd)->bl, (mes), (len), SELF ) #define clif_viewequip_fail( sd ) clif_msg( (sd), 0x54d ); #define HCHSYS_NAME_LENGTH 20 +#define MAX_ROULETTE_LEVEL 7 /** client-defined value **/ +#define MAX_ROULETTE_COLUMNS 9 /** client-defined value **/ /** * Enumerations @@ -476,6 +478,35 @@ enum e_trade_item_ok { TIO_INDROCKS = 0x9, }; +enum RECV_ROULETTE_ITEM_REQ { + RECV_ITEM_SUCCESS = 0x0, + RECV_ITEM_FAILED = 0x1, + RECV_ITEM_OVERCOUNT = 0x2, + RECV_ITEM_OVERWEIGHT = 0x3, +}; + +enum RECV_ROULETTE_ITEM_ACK { + RECV_ITEM_NORMAL = 0x0, + RECV_ITEM_LOSING = 0x1, +}; + +enum GENERATE_ROULETTE_ACK { + GENERATE_ROULETTE_SUCCESS = 0x0, + GENERATE_ROULETTE_FAILED = 0x1, + GENERATE_ROULETTE_NO_ENOUGH_POINT = 0x2, + GENERATE_ROULETTE_LOSING = 0x3, +}; + +enum OPEN_ROULETTE_ACK{ + OPEN_ROULETTE_SUCCESS = 0x0, + OPEN_ROULETTE_FAILED = 0x1, +}; + +enum CLOSE_ROULETTE_ACK { + CLOSE_ROULETTE_SUCCESS = 0x0, + CLOSE_ROULETTE_FAILED = 0x1, +}; + /** * Structures **/ @@ -552,6 +583,12 @@ struct clif_interface { struct hCSData **data[CASHSHOP_TAB_MAX]; unsigned int item_count[CASHSHOP_TAB_MAX]; } cs; + /* roulette data */ + struct { + int *nameid[MAX_ROULETTE_LEVEL];//nameid + int *qty[MAX_ROULETTE_LEVEL];//qty of nameid + int items[MAX_ROULETTE_LEVEL];//number of items in the list for each + } rd; /* */ unsigned int cryptKey[3]; /* */ @@ -1051,6 +1088,9 @@ struct clif_interface { /* NPC Market */ void (*npc_market_open) (struct map_session_data *sd, struct npc_data *nd); void (*npc_market_purchase_ack) (struct map_session_data *sd, struct packet_npc_market_purchase *req, unsigned char response); + /* */ + bool (*parse_roulette_db) (void); + void (*roulette_generate_ack) (struct map_session_data *sd, unsigned char result, short stage, short prizeIdx, short bonusItemID); /*------------------------ *- Parse Incoming Packet *------------------------*/ @@ -1278,6 +1318,12 @@ struct clif_interface { void (*pBankCheck) (int fd, struct map_session_data *sd); void (*pBankOpen) (int fd, struct map_session_data *sd); void (*pBankClose) (int fd, struct map_session_data *sd); + /* Roulette System [Yommy/Hercules] */ + void (*pRouletteOpen) (int fd, struct map_session_data *sd); + void (*pRouletteInfo) (int fd, struct map_session_data *sd); + void (*pRouletteClose) (int fd, struct map_session_data *sd); + void (*pRouletteGenerate) (int fd, struct map_session_data *sd); + void (*pRouletteRecvItem) (int fd, struct map_session_data *sd); /* */ void (*pNPCShopClosed) (int fd, struct map_session_data *sd); /* NPC Market (by Ind after an extensive debugging of the packet, only possible thanks to Yommy <3) */ diff --git a/src/map/itemdb.c b/src/map/itemdb.c index e6210f871..41e0a5348 100644 --- a/src/map/itemdb.c +++ b/src/map/itemdb.c @@ -2248,6 +2248,10 @@ void do_init_itemdb(bool minimal) { return; clif->cashshop_load(); + + /** it failed? we disable it **/ + if( !clif->parse_roulette_db() ) + battle_config.feature_roulette = 0; } void itemdb_defaults(void) { itemdb = &itemdb_s; diff --git a/src/map/itemdb.h b/src/map/itemdb.h index 198d7a542..e8b8588e9 100644 --- a/src/map/itemdb.h +++ b/src/map/itemdb.h @@ -41,6 +41,7 @@ enum item_itemid { ITEMID_YELLOW_POTION = 503, ITEMID_WHITE_POTION = 504, ITEMID_BLUE_POTION = 505, + ITEMID_APPLE = 512, ITEMID_HOLY_WATER = 523, ITEMID_RED_SLIM_POTION = 545, ITEMID_YELLOW_SLIM_POTION = 546, diff --git a/src/map/packets.h b/src/map/packets.h index 699bb3fd2..3240a97a1 100644 --- a/src/map/packets.h +++ b/src/map/packets.h @@ -2800,6 +2800,88 @@ packet(0x020d,-1); packet(0x0438,36,clif->pStoragePassword,0); #endif +// 2014-10-16aRagexe - YomRawr +#if PACKETVER >= 20141016 + packet(0x0369,7,clif->pActionRequest,2,6); + packet(0x083C,10,clif->pUseSkillToId,2,4,6); + packet(0x0437,5,clif->pWalkToXY,2); + packet(0x035F,6,clif->pTickSend,2); + packet(0x0967,5,clif->pChangeDir,2,4); + packet(0x07E4,6,clif->pTakeItem,2); + packet(0x0362,6,clif->pDropItem,2,4); + packet(0x07EC,8,clif->pMoveToKafra,2,4); + packet(0x022D,8,clif->pMoveFromKafra,2,4); + packet(0x0438,10,clif->pUseSkillToPos,2,4,6,8); + packet(0x0366,90,clif->pUseSkillToPosMoreInfo,2,4,6,8,10); + packet(0x096A,6,clif->pGetCharNameRequest,2); + packet(0x0368,6,clif->pSolveCharName,2); + packet(0x0838,12,clif->pSearchStoreInfoListItemClick,2,6,10); + packet(0x0835,2,clif->pSearchStoreInfoNextPage,0); + packet(0x0819,-1,clif->pSearchStoreInfo,2,4,5,9,13,14,15); + packet(0x0811,-1,clif->pReqTradeBuyingStore,2,4,8,12); + packet(0x0360,6,clif->pReqClickBuyingStore,2); + packet(0x0817,2,clif->pReqCloseBuyingStore,0); + packet(0x0815,-1,clif->pReqOpenBuyingStore,2,4,8,9,89); + packet(0x0365,18,clif->pPartyBookingRegisterReq,2,4); + // packet(0x0363,8); // CZ_JOIN_BATTLE_FIELD + packet(0x0281,-1,clif->pItemListWindowSelected,2,4,8); + packet(0x086E,19,clif->pWantToConnection,2,6,10,14,18); + packet(0x0802,26,clif->pPartyInvite2,2); + // packet(0x0922,4); // CZ_GANGSI_RANK + packet(0x094B,26,clif->pFriendsListAdd,2); + packet(0x0364,5,clif->pHomMenu,2,4); + packet(0x0936,36,clif->pStoragePassword,0); + packet(0x09DF,7); + packet(0x0a00,269); +#endif + +// 2014-10-22bRagexe - YomRawr +#if PACKETVER >= 20141022 + packet(0x0369,7,clif->pActionRequest,2,6); + packet(0x083C,10,clif->pUseSkillToId,2,4,6); + packet(0x0437,5,clif->pWalkToXY,2); + packet(0x035F,6,clif->pTickSend,2); + packet(0x08AD,5,clif->pChangeDir,2,4); + packet(0x094E,6,clif->pTakeItem,2); + packet(0x087D,6,clif->pDropItem,2,4); + packet(0x0878,8,clif->pMoveToKafra,2,4); + packet(0x08AA,8,clif->pMoveFromKafra,2,4); + packet(0x023B,10,clif->pUseSkillToPos,2,4,6,8); + packet(0x0366,90,clif->pUseSkillToPosMoreInfo,2,4,6,8,10); + packet(0x096A,6,clif->pGetCharNameRequest,2); + packet(0x0368,6,clif->pSolveCharName,2); + packet(0x0835,12,clif->pSearchStoreInfoListItemClick,2,6,10); + packet(0x0940,2,clif->pSearchStoreInfoNextPage,0); + packet(0x0819,-1,clif->pSearchStoreInfo,2,4,5,9,13,14,15); + packet(0x0811,-1,clif->pReqTradeBuyingStore,2,4,8,12); + packet(0x0360,6,clif->pReqClickBuyingStore,2); + packet(0x0817,2,clif->pReqCloseBuyingStore,0); + packet(0x0815,-1,clif->pReqOpenBuyingStore,2,4,8,9,89); + packet(0x0955,18,clif->pPartyBookingRegisterReq,2,4); + // packet(0x092B,8); // CZ_JOIN_BATTLE_FIELD + packet(0x0281,-1,clif->pItemListWindowSelected,2,4,8); + packet(0x093B,19,clif->pWantToConnection,2,6,10,14,18); + packet(0x0896,26,clif->pPartyInvite2,2); + // packet(0x08AB,4); // CZ_GANGSI_RANK + packet(0x091A,26,clif->pFriendsListAdd,2); + packet(0x0899,5,clif->pHomMenu,2,4); + packet(0x0438,36,clif->pStoragePassword,0); +#endif + +/* Roulette System [Yommy/Hercules] */ +#if PACKETVER >= 20141016 + packet(0x0A19,2,clif->pRouletteOpen,0); // HEADER_CZ_REQ_OPEN_ROULETTE + packet(0x0A1A,23); // HEADER_ZC_ACK_OPEN_ROULETTE + packet(0x0A1B,2,clif->pRouletteInfo,0); // HEADER_CZ_REQ_ROULETTE_INFO + packet(0x0A1C,-1); // HEADER_ZC_ACK_ROULEITTE_INFO + packet(0x0A1D,2,clif->pRouletteClose,0); // HEADER_CZ_REQ_CLOSE_ROULETTE + packet(0x0A1E,3); // HEADER_ZC_ACK_CLOSE_ROULETTE + packet(0x0A1F,2,clif->pRouletteGenerate,0); // HEADER_CZ_REQ_GENERATE_ROULETTE + packet(0x0A20,21); // HEADER_ZC_ACK_GENERATE_ROULETTE + packet(0x0A21,3,clif->pRouletteRecvItem,2); // HEADER_CZ_RECV_ROULETTE_ITEM + packet(0x0A22,5); // HEADER_ZC_RECV_ROULETTE_ITEM +#endif + /* PacketKeys: http://hercules.ws/board/topic/1105-hercules-wpe-free-june-14th-patch/ */ #if PACKETVER >= 20110817 packetKeys(0x053D5CED,0x3DED6DED,0x6DED6DED); /* Thanks to Shakto */ @@ -3035,6 +3117,14 @@ packet(0x020d,-1); packetKeys(0x290551EA,0x2B952C75,0x2D67669B); /* YomRawr */ #endif +#if PACKETVER >= 20141016 + packetKeys(0x2DFF467C,0x444B37EE,0x2C1B634F); /* YomRawr */ +#endif + +#if PACKETVER >= 20141022 + packetKeys(0x290551EA,0x2B952C75,0x2D67669B); /* YomRawr */ +#endif + #if defined(OBFUSCATIONKEY1) && defined(OBFUSCATIONKEY2) && defined(OBFUSCATIONKEY3) packetKeys(OBFUSCATIONKEY1,OBFUSCATIONKEY2,OBFUSCATIONKEY3); #endif diff --git a/src/map/packets_struct.h b/src/map/packets_struct.h index 9f9349b88..1c6deab96 100644 --- a/src/map/packets_struct.h +++ b/src/map/packets_struct.h @@ -77,8 +77,10 @@ enum packet_headers { #endif #if PACKETVER < 20080102 authokType = 0x73, -#else +#elif PACKETVER < 20141022 authokType = 0x2eb, +#else + authokType = 0xa18, #endif script_clearType = 0x8d6, package_item_announceType = 0x7fd, @@ -210,6 +212,9 @@ enum packet_headers { wisendType = 0x98, #endif partyleaderchangedType = 0x7fc, + rouletteinfoackType = 0xa1c, + roulettgenerateackType = 0xA20, + roulettercvitemackType = 0xA22, }; #if !defined(sun) && (!defined(__NETBSD__) || __NetBSD_Version__ >= 600000000) // NetBSD 5 and Solaris don't like pragma pack but accept the packed attribute @@ -298,6 +303,9 @@ struct packet_authok { #if PACKETVER >= 20080102 short font; #endif +#if PACKETVER >= 20141022 + unsigned char sex; +#endif } __attribute__((packed)); struct packet_monster_hp { @@ -762,6 +770,58 @@ struct packet_banking_withdraw_ack { int Balance; } __attribute__((packed)); +/* Roulette System [Yommy/Hercules] */ +struct packet_roulette_open_ack { + short PacketType; + char Result; + int Serial; + char Step; + char Idx; + short AdditionItemID; + int GoldPoint; + int SilverPoint; + int BronzePoint; +} __attribute__((packed)); + +struct packet_roulette_info_ack { + short PacketType; + short PacketLength; + unsigned int RouletteSerial; + struct { + unsigned short Row; + unsigned short Position; + unsigned short ItemId; + unsigned short Count; + } ItemInfo[42]; +} __attribute__((packed)); + +struct packet_roulette_close_ack { + short PacketType; + unsigned char Result; +} __attribute__((packed)); + +struct packet_roulette_generate_ack { + short PacketType; + unsigned char Result; + unsigned short Step; + unsigned short Idx; + unsigned short AdditionItemID; + int RemainGold; + int RemainSilver; + int RemainBronze; +} __attribute__((packed)); + +struct packet_roulette_itemrecv_req { + short PacketType; + unsigned char Condition; +} __attribute__((packed)); + +struct packet_roulette_itemrecv_ack { + short PacketType; + unsigned char Result; + unsigned short AdditionItemID; +} __attribute__((packed)); + struct packet_itemlist_normal { short PacketType; short PacketLength; diff --git a/src/map/pc.h b/src/map/pc.h index 580908692..e613feec5 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -543,6 +543,13 @@ struct map_session_data { bool vars_ok; bool vars_dirty; + struct { + short stage; + short prizeIdx; + short prizeStage; + bool claimPrize; + } roulette; + // temporary debugging of bug #3504 const char* delunit_prevfile; int delunit_prevline; -- cgit v1.2.3-60-g2f50