summaryrefslogtreecommitdiff
path: root/src/map/clif.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/map/clif.c')
-rw-r--r--src/map/clif.c417
1 files changed, 379 insertions, 38 deletions
diff --git a/src/map/clif.c b/src/map/clif.c
index 018087000..169f30793 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);
}
@@ -2703,14 +2705,15 @@ void read_channels_config(void) {
} else {
unsigned char d = 0, dlen = strlen(irc_server);
char server[40];
-
+ if (dlen > 39)
+ dlen = 39;
memset(server, '\0', sizeof(server));
for(d = 0; d < dlen; d++) {
if(irc_server[d] == ':') {
memcpy(server, irc_server, d);
safestrncpy(hChSys.irc_server, server, 40);
- memcpy(server, &irc_server[d+1], dlen);
+ memcpy(server, &irc_server[d+1], dlen - d - 1);
hChSys.irc_server_port = atoi(server);
break;
}
@@ -3432,7 +3435,6 @@ void clif_arrowequip(struct map_session_data *sd,int val)
nullpo_retv(sd);
- pc_stop_attack(sd); // [Valaris]
#if PACKETVER >= 20121128
clif->status_change(&sd->bl, SI_CLIENT_ONLY_EQUIP_ARROW, 1, INVALID_TIMER, 0, 0, 0);
#endif
@@ -4786,7 +4788,9 @@ int clif_outsight(struct block_list *bl,va_list ap)
}
if (sd && sd->fd) { //sd is watching tbl go out of view.
nullpo_ret(tbl);
- if (((vd=status->get_viewdata(tbl)) && vd->class_ != INVISIBLE_CLASS) &&
+ if(tbl->type == BL_SKILL) //Trap knocked out of sight
+ clif->clearchar_skillunit((struct skill_unit *)tbl,sd->fd);
+ else if (((vd=status->get_viewdata(tbl)) && vd->class_ != INVISIBLE_CLASS) &&
!(tbl->type == BL_NPC && (((TBL_NPC*)tbl)->option&OPTION_INVISIBLE)))
clif->clearunit_single(tbl->id,CLR_OUTSIGHT,sd->fd);
}
@@ -5579,6 +5583,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
@@ -5599,6 +5604,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.
@@ -5608,6 +5618,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) {
@@ -5832,12 +5843,12 @@ void clif_pvpset(struct map_session_data *sd,int pvprank,int pvpnum,int type)
unsigned char buf[32];
WBUFW(buf,0) = 0x19a;
WBUFL(buf,2) = sd->bl.id;
- if(sd->sc.option&(OPTION_HIDE|OPTION_CLOAK))
+ if (sd->sc.option&(OPTION_HIDE|OPTION_CLOAK)) // TODO[Haru] Should this be pc_ishiding(sd)? (i.e. include Chase Walk and any new options)
WBUFL(buf,6) = UINT32_MAX; //On client displays as --
else
WBUFL(buf,6) = pvprank;
WBUFL(buf,10) = pvpnum;
- if(sd->sc.option&OPTION_INVISIBLE || sd->disguise != -1) //Causes crashes when a 'mob' with pvp info dies.
+ if (pc_isinvisible(sd) || sd->disguise != -1) //Causes crashes when a 'mob' with pvp info dies.
clif->send(buf,packet_len(0x19a),&sd->bl,SELF);
else if(!type)
clif->send(buf,packet_len(0x19a),&sd->bl,AREA);
@@ -8444,7 +8455,7 @@ void clif_refresh_storagewindow( struct map_session_data *sd ) {
// remain locked forever and nobody will be able to access it
if( sd->state.storage_flag == 2 ) {
struct guild_storage *gstor;
- if( (gstor = gstorage->id2storage2(sd->status.guild_id)) == NULL) {
+ if( (gstor = idb_get(gstorage->db,sd->status.guild_id)) == NULL) {
// Shouldn't happen... The information should already be at the map-server
intif->request_guild_storage(sd->status.account_id,sd->status.guild_id);
} else {
@@ -9339,7 +9350,7 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) {
sd->state.hpmeter_visible = 1;
}
- if( !(sd->sc.option&OPTION_INVISIBLE) ) { // increment the number of pvp players on the map
+ if (!pc_isinvisible(sd)) { // increment the number of pvp players on the map
map->list[sd->bl.m].users_pvp++;
}
@@ -9360,7 +9371,7 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) {
if( sd->bg_id ) clif->bg_hp(sd); // BattleGround System
- if(map->list[sd->bl.m].flag.pvp && !(sd->sc.option&OPTION_INVISIBLE)) {
+ if (map->list[sd->bl.m].flag.pvp && !pc_isinvisible(sd)) {
if(!battle_config.pk_mode) { // remove pvp stuff for pk_mode [Valaris]
if (!map->list[sd->bl.m].flag.pvp_nocalcrank)
sd->pvp_timer = timer->add(timer->gettick()+200, pc->calc_pvprank_timer, sd->bl.id, 0);
@@ -9445,11 +9456,11 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) {
clif->updatestatus(sd,SP_SKILLPOINT);
clif->initialstatus(sd);
- if (sd->sc.option&OPTION_FALCON)
+ if (pc_isfalcon(sd))
clif->status_change(&sd->bl, SI_FALCON, 1, 0, 0, 0, 0);
- if (sd->sc.option&(OPTION_RIDING|OPTION_DRAGON))
+ if (pc_isridingpeco(sd) || pc_isridingdragon(sd))
clif->status_change(&sd->bl, SI_RIDING, 1, 0, 0, 0, 0);
- else if (sd->sc.option&OPTION_WUGRIDER)
+ else if (pc_isridingwug(sd))
clif->status_change(&sd->bl, SI_WUGRIDER, 1, 0, 0, 0, 0);
if(sd->status.manner < 0)
@@ -9650,18 +9661,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
@@ -10122,7 +10137,8 @@ void clif_parse_ActionRequest_sub(struct map_session_data *sd, int action_type,
)
return;
- pc_stop_walking(sd, 1);
+ if(action_type != 0x00 && action_type != 0x07)
+ pc_stop_walking(sd, 1);
pc_stop_attack(sd);
if(target_id<0 && -target_id == sd->bl.id) // for disguises [Valaris]
@@ -10488,7 +10504,7 @@ void clif_parse_WisMessage(int fd, struct map_session_data* sd)
// if player ignores everyone
if (dstsd->state.ignoreAll && pc_get_group_level(sd) <= pc_get_group_level(dstsd)) {
- if (dstsd->sc.option & OPTION_INVISIBLE && pc_get_group_level(sd) < pc_get_group_level(dstsd))
+ if (pc_isinvisible(dstsd) && pc_get_group_level(sd) < pc_get_group_level(dstsd))
clif->wis_end(fd, 1); // 1: target character is not logged in
else
clif->wis_end(fd, 3); // 3: everyone ignored by target
@@ -11162,16 +11178,17 @@ void clif_parse_GetItemFromCart(int fd,struct map_session_data *sd)
/// 012a
void clif_parse_RemoveOption(int fd,struct map_session_data *sd)
{
- if( !(sd->sc.option&(OPTION_RIDING|OPTION_FALCON|OPTION_DRAGON|OPTION_MADOGEAR))
+ if (pc_isridingpeco(sd) || pc_isfalcon(sd) || pc_isridingdragon(sd) || pc_ismadogear(sd)) {
+ // priority to remove this option before we can clear cart
+ pc->setoption(sd,sd->sc.option&~(OPTION_RIDING|OPTION_FALCON|OPTION_DRAGON|OPTION_MADOGEAR));
+ } else {
#ifdef NEW_CARTS
- && sd->sc.data[SC_PUSH_CART] ){
- pc->setcart(sd,0);
-#else
- ){
+ if (sd->sc.data[SC_PUSH_CART])
+ pc->setcart(sd,0);
+#else // not NEW_CARTS
pc->setoption(sd,sd->sc.option&~OPTION_CART);
-#endif
- }else // priority to remove this option before we can clear cart
- pc->setoption(sd,sd->sc.option&~(OPTION_RIDING|OPTION_FALCON|OPTION_DRAGON|OPTION_MADOGEAR));
+#endif // NEW_CARTS
+ }
}
@@ -12234,7 +12251,7 @@ void clif_parse_PartyMessage(int fd, struct map_session_data* sd)
void clif_parse_PartyChangeLeader(int fd, struct map_session_data* sd) {
party->changeleader(sd, map->id2sd(RFIFOL(fd,2)));
}
-
+
/// Party Booking in KRO [Spiria]
///
@@ -15116,7 +15133,8 @@ void clif_parse_Mail_send(int fd, struct map_session_data *sd)
if (body_len > MAIL_BODY_LENGTH)
body_len = MAIL_BODY_LENGTH;
- if( !mail->setattachment(sd, &msg) ) { // Invalid Append condition
+ memset(&msg, 0, sizeof(msg));
+ if (!mail->setattachment(sd, &msg)) { // Invalid Append condition
clif->mail_send(sd->fd, true); // fail
mail->removeitem(sd,0);
mail->removezeny(sd,0);
@@ -15334,9 +15352,10 @@ void clif_parse_Auction_register(int fd, struct map_session_data *sd)
struct auction_data auction;
struct item_data *item;
- if( !battle_config.feature_auction )
+ if (!battle_config.feature_auction)
return;
+ memset(&auction, 0, sizeof(auction));
auction.price = RFIFOL(fd,2);
auction.buynow = RFIFOL(fd,6);
auction.hours = RFIFOW(fd,10);
@@ -15794,19 +15813,34 @@ void clif_parse_PartyTick(int fd, struct map_session_data* sd)
/// 02b1 <packet len>.W <num>.L { <quest id>.L <active>.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);
}
@@ -18254,6 +18288,296 @@ void clif_parse_NPCMarketPurchase(int fd, struct map_session_data *sd) {
clif->npc_market_purchase_ack(sd,p,npc->market_buylist(sd,(p->PacketLength - 4) / sizeof(p->list[0]),p));
#endif
}
+
+void clif_PartyLeaderChanged(struct map_session_data *sd, int prev_leader_aid, int new_leader_aid) {
+ struct packet_party_leader_changed p;
+
+ p.PacketType = partyleaderchangedType;
+
+ p.prev_leader_aid = prev_leader_aid;
+ p.new_leader_aid = new_leader_aid;
+
+ 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 == 0 ) {
+ if( pc_readglobalreg(sd, script->add_str("TmpRouletteBronze")) <= 0 &&
+ pc_readglobalreg(sd, script->add_str("TmpRouletteSilver")) < 10 &&
+ pc_readglobalreg(sd, script->add_str("TmpRouletteGold")) < 10 )
+ result = GENERATE_ROULETTE_NO_ENOUGH_POINT;
+ }
+
+ if( result == GENERATE_ROULETTE_SUCCESS ) {
+
+ if( stage == 0 ) {
+ if( pc_readglobalreg(sd, script->add_str("TmpRouletteBronze")) > 0 ) {
+ pc_setglobalreg(sd, script->add_str("TmpRouletteBronze"), pc_readglobalreg(sd, script->add_str("TmpRouletteBronze")) - 1);
+ } else if( pc_readglobalreg(sd, script->add_str("TmpRouletteSilver")) > 9 ) {
+ pc_setglobalreg(sd, script->add_str("TmpRouletteSilver"), pc_readglobalreg(sd, script->add_str("TmpRouletteSilver")) - 10);
+ stage = sd->roulette.stage = 2;
+ } else if( pc_readglobalreg(sd, script->add_str("TmpRouletteGold")) > 9 ) {
+ pc_setglobalreg(sd, script->add_str("TmpRouletteGold"), pc_readglobalreg(sd, script->add_str("TmpRouletteGold")) - 10);
+ stage = sd->roulette.stage = 4;
+ }
+ }
+
+ 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 ) {
@@ -18570,6 +18894,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) {
@@ -18884,6 +19215,7 @@ void clif_defaults(void) {
clif->party_xy_remove = clif_party_xy_remove;
clif->party_show_picker = clif_party_show_picker;
clif->partyinvitationstate = clif_partyinvitationstate;
+ clif->PartyLeaderChanged = clif_PartyLeaderChanged;
/* guild-specific */
clif->guild_created = clif_guild_created;
clif->guild_belonginfo = clif_guild_belonginfo;
@@ -19070,6 +19402,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
*------------------------*/
@@ -19299,6 +19634,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 */