|
@@ -19260,19 +19260,12 @@ void DumpUnknown(int fd,TBL_PC *sd,int cmd,int packet_len)
|
|
|
/// Roulette System
|
|
|
/// Author: Yommy
|
|
|
|
|
|
-/**
|
|
|
- * Opens Roulette window
|
|
|
- * @param fd
|
|
|
- * @param sd
|
|
|
- */
|
|
|
-void clif_parse_RouletteOpen(int fd, struct map_session_data* sd)
|
|
|
-{
|
|
|
+/// Opens the roulette window
|
|
|
+/// 0A1A <result>.B <serial>.L <stage>.B <price index>.B <additional item id>.W <gold>.L <silver>.L <bronze>.L (ZC_ACK_OPEN_ROULETTE)
|
|
|
+void clif_roulette_open( struct map_session_data* sd ){
|
|
|
nullpo_retv(sd);
|
|
|
|
|
|
- if (!battle_config.feature_roulette) {
|
|
|
- clif_messagecolor(&sd->bl,color_table[COLOR_RED],msg_txt(sd,1497),false,SELF); //Roulette is disabled
|
|
|
- return;
|
|
|
- }
|
|
|
+ int fd = sd->fd;
|
|
|
|
|
|
WFIFOHEAD(fd,packet_len(0xa1a));
|
|
|
WFIFOW(fd,0) = 0xa1a;
|
|
@@ -19287,16 +19280,9 @@ void clif_parse_RouletteOpen(int fd, struct map_session_data* sd)
|
|
|
WFIFOSET(fd,packet_len(0xa1a));
|
|
|
}
|
|
|
|
|
|
-/**
|
|
|
- * Generates information to be displayed
|
|
|
- * @param fd
|
|
|
- * @param sd
|
|
|
- */
|
|
|
-void clif_parse_RouletteInfo(int fd, struct map_session_data* sd)
|
|
|
-{
|
|
|
- unsigned short i, j, count = 0;
|
|
|
- int len = 8 + (42 * 8);
|
|
|
-
|
|
|
+/// Request to open the roulette window
|
|
|
+/// 0A19 (CZ_REQ_OPEN_ROULETTE)
|
|
|
+void clif_parse_roulette_open( int fd, struct map_session_data* sd ){
|
|
|
nullpo_retv(sd);
|
|
|
|
|
|
if (!battle_config.feature_roulette) {
|
|
@@ -19304,32 +19290,53 @@ void clif_parse_RouletteInfo(int fd, struct map_session_data* sd)
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
+ clif_roulette_open(sd);
|
|
|
+}
|
|
|
+
|
|
|
+/// Sends the info about the available roulette rewards to the client
|
|
|
+/// 0A1C <length>.W <serial>.L { { <level>.W <column>.W <item>.W <amount>.W } * MAX_ROULETTE_COLUMNS } * MAX_ROULETTE_LEVEL (ZC_ACK_ROULEITTE_INFO)
|
|
|
+/// 0A1C <length>.W <serial>.L { { <level>.W <column>.W <item>.L <amount>.L } * MAX_ROULETTE_COLUMNS } * MAX_ROULETTE_LEVEL (ZC_ACK_ROULEITTE_INFO) >= 20180516
|
|
|
+void clif_roulette_info( struct map_session_data* sd ){
|
|
|
+ nullpo_retv(sd);
|
|
|
+
|
|
|
+ int fd = sd->fd;
|
|
|
+ int len = 8; // Initialize to header size
|
|
|
+#if PACKETVER < 20180516
|
|
|
+ int size = 8;
|
|
|
+#else
|
|
|
+ int size = 12;
|
|
|
+#endif
|
|
|
+
|
|
|
+ for( int i = 0; i < MAX_ROULETTE_LEVEL; i++ ){
|
|
|
+ len += (MAX_ROULETTE_COLUMNS - i) * size;
|
|
|
+ }
|
|
|
+
|
|
|
WFIFOHEAD(fd,len);
|
|
|
WFIFOW(fd,0) = 0xa1c;
|
|
|
WFIFOW(fd,2) = len;
|
|
|
WFIFOL(fd,4) = 1; // serial
|
|
|
|
|
|
- for(i = 0; i < MAX_ROULETTE_LEVEL; i++) {
|
|
|
- for(j = 0; j < MAX_ROULETTE_COLUMNS - i; j++) {
|
|
|
- WFIFOW(fd,8 * count + 8) = i;
|
|
|
- WFIFOW(fd,8 * count + 10) = j;
|
|
|
- WFIFOW(fd,8 * count + 12) = rd.nameid[i][j];
|
|
|
- WFIFOW(fd,8 * count + 14) = rd.qty[i][j];
|
|
|
- count++;
|
|
|
+ for(int i = 0, offset = 8; i < MAX_ROULETTE_LEVEL; i++) {
|
|
|
+ for(int j = 0; j < MAX_ROULETTE_COLUMNS - i; j++) {
|
|
|
+ WFIFOW(fd,offset + 0) = i;
|
|
|
+ WFIFOW(fd,offset + 2) = j;
|
|
|
+#if PACKETVER < 20180516
|
|
|
+ WFIFOW(fd,offset + 4) = rd.nameid[i][j];
|
|
|
+ WFIFOW(fd,offset + 6) = rd.qty[i][j];
|
|
|
+#else
|
|
|
+ WFIFOL(fd,offset + 4) = rd.nameid[i][j];
|
|
|
+ WFIFOL(fd,offset + 8) = rd.qty[i][j];
|
|
|
+#endif
|
|
|
+ offset += size;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
WFIFOSET(fd,len);
|
|
|
- return;
|
|
|
}
|
|
|
|
|
|
-/**
|
|
|
- * Closes Roulette window
|
|
|
- * @param fd
|
|
|
- * @param sd
|
|
|
- */
|
|
|
-void clif_parse_RouletteClose(int fd, struct map_session_data* sd)
|
|
|
-{
|
|
|
+/// Request the roulette reward data
|
|
|
+/// 0A1B (CZ_REQ_ROULETTE_INFO)
|
|
|
+void clif_parse_roulette_info( int fd, struct map_session_data* sd ){
|
|
|
nullpo_retv(sd);
|
|
|
|
|
|
if (!battle_config.feature_roulette) {
|
|
@@ -19337,27 +19344,35 @@ void clif_parse_RouletteClose(int fd, struct map_session_data* sd)
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- /** What do we need this for? (other than state tracking), game client closes the window without our response. **/
|
|
|
- return;
|
|
|
+ clif_roulette_info(sd);
|
|
|
}
|
|
|
|
|
|
-/**
|
|
|
- *
|
|
|
- **/
|
|
|
+/// Notification of the client that the roulette window was closed
|
|
|
+/// 0A1D (CZ_REQ_CLOSE_ROULETTE)
|
|
|
+void clif_parse_roulette_close( int fd, struct map_session_data* sd ){
|
|
|
+ nullpo_retv(sd);
|
|
|
+
|
|
|
+ if (!battle_config.feature_roulette) {
|
|
|
+ clif_messagecolor(&sd->bl,color_table[COLOR_RED],msg_txt(sd,1497),false,SELF); //Roulette is disabled
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // What do we need this for? (other than state tracking), game client closes the window without our response.
|
|
|
+}
|
|
|
+
|
|
|
+/// Response to a item reward request
|
|
|
+/// 0A22 <type>.B <bonus item>.W (ZC_RECV_ROULETTE_ITEM)
|
|
|
static void clif_roulette_recvitem_ack(struct map_session_data *sd, enum RECV_ROULETTE_ITEM_REQ type) {
|
|
|
#if PACKETVER >= 20141016
|
|
|
- uint16 cmd = 0xa22;
|
|
|
- unsigned char buf[5];
|
|
|
-
|
|
|
nullpo_retv(sd);
|
|
|
|
|
|
- if (packet_db[cmd].len == 0)
|
|
|
- return;
|
|
|
+ int fd = sd->fd;
|
|
|
|
|
|
- WBUFW(buf,0) = cmd;
|
|
|
- WBUFB(buf,2) = type;
|
|
|
- WBUFW(buf,3) = 0; //! TODO: Additional item
|
|
|
- clif_send(buf, sizeof(buf), &sd->bl, SELF);
|
|
|
+ WFIFOHEAD(fd,packet_len(0xa22));
|
|
|
+ WFIFOW(fd,0) = 0xa22;
|
|
|
+ WFIFOB(fd,2) = type;
|
|
|
+ WFIFOW(fd,3) = 0; //! TODO: Additional item
|
|
|
+ WFIFOSET(fd,packet_len(0xa22));
|
|
|
#endif
|
|
|
}
|
|
|
|
|
@@ -19391,15 +19406,29 @@ static uint8 clif_roulette_getitem(struct map_session_data *sd) {
|
|
|
return res;
|
|
|
}
|
|
|
|
|
|
-/**
|
|
|
- * Process the stage and attempt to give a prize
|
|
|
- * @param fd
|
|
|
- * @param sd
|
|
|
- */
|
|
|
-void clif_parse_RouletteGenerate(int fd, struct map_session_data* sd)
|
|
|
-{
|
|
|
- enum GENERATE_ROULETTE_ACK result = GENERATE_ROULETTE_SUCCESS;
|
|
|
- short stage = sd->roulette.stage;
|
|
|
+/// Update Roulette window with current stats
|
|
|
+/// 0A20 <result>.B <stage>.W <price index>.W <bonus item>.W <gold>.L <silver>.L <bronze>.L (ZC_ACK_GENERATE_ROULETTE)
|
|
|
+void clif_roulette_generate( struct map_session_data *sd, unsigned char result, short stage, short prizeIdx, short bonusItemID ){
|
|
|
+ nullpo_retv(sd);
|
|
|
+
|
|
|
+ int fd = sd->fd;
|
|
|
+
|
|
|
+ WFIFOHEAD(fd,packet_len(0xa20));
|
|
|
+ WFIFOW(fd,0) = 0xa20;
|
|
|
+ WFIFOB(fd,2) = result;
|
|
|
+ WFIFOW(fd,3) = stage;
|
|
|
+ WFIFOW(fd,5) = prizeIdx;
|
|
|
+ WFIFOW(fd,7) = bonusItemID;
|
|
|
+ WFIFOL(fd,9) = sd->roulette_point.gold;
|
|
|
+ WFIFOL(fd,13) = sd->roulette_point.silver;
|
|
|
+ WFIFOL(fd,17) = sd->roulette_point.bronze;
|
|
|
+ WFIFOSET(fd,packet_len(0xa20));
|
|
|
+}
|
|
|
+
|
|
|
+/// Request to start the roulette
|
|
|
+/// 0A1F (CZ_REQ_GENERATE_ROULETTE)
|
|
|
+void clif_parse_roulette_generate( int fd, struct map_session_data* sd ){
|
|
|
+ enum GENERATE_ROULETTE_ACK result;
|
|
|
|
|
|
nullpo_retv(sd);
|
|
|
|
|
@@ -19408,55 +19437,55 @@ void clif_parse_RouletteGenerate(int fd, struct map_session_data* sd)
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- if (sd->roulette.stage >= MAX_ROULETTE_LEVEL)
|
|
|
- stage = sd->roulette.stage = 0;
|
|
|
+ if( sd->roulette.tick && DIFF_TICK( sd->roulette.tick, gettick() ) > 0 ){
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
- if (!stage) {
|
|
|
- if (sd->roulette_point.bronze <= 0 && sd->roulette_point.silver < 10 && sd->roulette_point.gold < 10)
|
|
|
- result = GENERATE_ROULETTE_NO_ENOUGH_POINT;
|
|
|
+ if (sd->roulette.stage >= MAX_ROULETTE_LEVEL){
|
|
|
+ sd->roulette.stage = 0;
|
|
|
+ sd->roulette.claimPrize = false;
|
|
|
+ sd->roulette.prizeStage = 0;
|
|
|
+ sd->roulette.prizeIdx = -1;
|
|
|
}
|
|
|
|
|
|
- if (result == GENERATE_ROULETTE_SUCCESS) {
|
|
|
- if (!stage) {
|
|
|
+ if( !sd->roulette.stage && sd->roulette_point.bronze <= 0 && sd->roulette_point.silver < 10 && sd->roulette_point.gold < 10 ){
|
|
|
+ result = GENERATE_ROULETTE_NO_ENOUGH_POINT;
|
|
|
+ }else{
|
|
|
+ if (!sd->roulette.stage) {
|
|
|
if (sd->roulette_point.bronze > 0) {
|
|
|
sd->roulette_point.bronze -= 1;
|
|
|
pc_setreg2(sd, ROULETTE_BRONZE_VAR, sd->roulette_point.bronze);
|
|
|
} else if (sd->roulette_point.silver > 9) {
|
|
|
sd->roulette_point.silver -= 10;
|
|
|
- stage = sd->roulette.stage = 2;
|
|
|
+ sd->roulette.stage = 2;
|
|
|
pc_setreg2(sd, ROULETTE_SILVER_VAR, sd->roulette_point.silver);
|
|
|
} else if (sd->roulette_point.gold > 9) {
|
|
|
sd->roulette_point.gold -= 10;
|
|
|
- stage = sd->roulette.stage = 4;
|
|
|
+ sd->roulette.stage = 4;
|
|
|
pc_setreg2(sd, ROULETTE_GOLD_VAR, sd->roulette_point.gold);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- sd->roulette.prizeStage = stage;
|
|
|
- sd->roulette.prizeIdx = rnd()%rd.items[stage];
|
|
|
+ sd->roulette.prizeStage = sd->roulette.stage;
|
|
|
+ sd->roulette.prizeIdx = rnd()%rd.items[sd->roulette.stage];
|
|
|
+ sd->roulette.claimPrize = true;
|
|
|
+ sd->roulette.tick = gettick() + max( 1, ( MAX_ROULETTE_COLUMNS - sd->roulette.prizeStage - 3 ) ) * 1000;
|
|
|
|
|
|
- if (rd.flag[stage][sd->roulette.prizeIdx]&1) {
|
|
|
- clif_roulette_generate_ack(sd,GENERATE_ROULETTE_LOSING,stage,sd->roulette.prizeIdx,0);
|
|
|
- clif_roulette_getitem(sd);
|
|
|
- clif_roulette_recvitem_ack(sd, RECV_ITEM_SUCCESS);
|
|
|
- return;
|
|
|
- }
|
|
|
- else {
|
|
|
- sd->roulette.claimPrize = true;
|
|
|
+ if( rd.flag[sd->roulette.stage][sd->roulette.prizeIdx]&1 ){
|
|
|
+ result = GENERATE_ROULETTE_LOSING;
|
|
|
+ sd->roulette.stage = 0;
|
|
|
+ }else{
|
|
|
+ result = GENERATE_ROULETTE_SUCCESS;
|
|
|
sd->roulette.stage++;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- clif_roulette_generate_ack(sd,result,stage,(sd->roulette.prizeIdx == -1 ? 0 : sd->roulette.prizeIdx),0);
|
|
|
+ clif_roulette_generate(sd,result,sd->roulette.prizeStage,(sd->roulette.prizeIdx == -1 ? 0 : sd->roulette.prizeIdx),0);
|
|
|
}
|
|
|
|
|
|
-/**
|
|
|
- * Request to cash in prize
|
|
|
- * @param fd
|
|
|
- * @param sd
|
|
|
- */
|
|
|
-void clif_parse_RouletteRecvItem(int fd, struct map_session_data* sd)
|
|
|
-{
|
|
|
+/// Request to claim a prize
|
|
|
+/// 0A21 (CZ_RECV_ROULETTE_ITEM)
|
|
|
+void clif_parse_roulette_item( int fd, struct map_session_data* sd ){
|
|
|
enum RECV_ROULETTE_ITEM_REQ type = RECV_ITEM_FAILED;
|
|
|
nullpo_retv(sd);
|
|
|
|
|
@@ -19465,20 +19494,24 @@ void clif_parse_RouletteRecvItem(int fd, struct map_session_data* sd)
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
+ if( sd->roulette.tick && DIFF_TICK( sd->roulette.tick, gettick() ) > 0 ){
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
if (sd->roulette.claimPrize && sd->roulette.prizeIdx != -1) {
|
|
|
switch (clif_roulette_getitem(sd)) {
|
|
|
- case 0:
|
|
|
+ case ADDITEM_SUCCESS:
|
|
|
type = RECV_ITEM_SUCCESS;
|
|
|
break;
|
|
|
- case 1:
|
|
|
- case 4:
|
|
|
- case 5:
|
|
|
+ case ADDITEM_INVALID:
|
|
|
+ case ADDITEM_OVERITEM:
|
|
|
+ case ADDITEM_OVERAMOUNT:
|
|
|
type = RECV_ITEM_OVERCOUNT;
|
|
|
break;
|
|
|
- case 2:
|
|
|
+ case ADDITEM_OVERWEIGHT:
|
|
|
type = RECV_ITEM_OVERWEIGHT;
|
|
|
break;
|
|
|
- case 7:
|
|
|
+ case ADDITEM_STACKLIMIT:
|
|
|
default:
|
|
|
type = RECV_ITEM_FAILED;
|
|
|
break;
|
|
@@ -19486,33 +19519,6 @@ void clif_parse_RouletteRecvItem(int fd, struct map_session_data* sd)
|
|
|
}
|
|
|
|
|
|
clif_roulette_recvitem_ack(sd,type);
|
|
|
- return;
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- * Update Roulette window with current stats
|
|
|
- * @param sd
|
|
|
- * @param result
|
|
|
- * @param stage
|
|
|
- * @param prizeIdx
|
|
|
- * @param bonusItemID
|
|
|
- */
|
|
|
-void clif_roulette_generate_ack(struct map_session_data *sd, unsigned char result, short stage, short prizeIdx, short bonusItemID)
|
|
|
-{
|
|
|
- int fd = sd->fd;
|
|
|
-
|
|
|
- nullpo_retv(sd);
|
|
|
-
|
|
|
- WFIFOHEAD(fd,packet_len(0xa20));
|
|
|
- WFIFOW(fd,0) = 0xa20;
|
|
|
- WFIFOB(fd,2) = result;
|
|
|
- WFIFOW(fd,3) = stage;
|
|
|
- WFIFOW(fd,5) = prizeIdx;
|
|
|
- WFIFOW(fd,7) = bonusItemID;
|
|
|
- WFIFOL(fd,9) = sd->roulette_point.gold;
|
|
|
- WFIFOL(fd,13) = sd->roulette_point.silver;
|
|
|
- WFIFOL(fd,17) = sd->roulette_point.bronze;
|
|
|
- WFIFOSET(fd,packet_len(0xa20));
|
|
|
}
|
|
|
|
|
|
/// MERGE ITEM
|