Can anyone help me? I fixed all the roulette logic and it is fully functional, but I added a bonus item that is not in the roulette rows and columns, the chance of the bonus coming is 0.05%, it is working, but the item does not appear in the window of roulette, only when you win directly from the inventory.
void roulette_generate_bonus( map_session_data& sd ){
if( battle_config.feature_roulette_bonus_reward && sd.roulette.bonusItemID == 0 ){
int next_stage = 0;
if( sd.roulette_point.bronze >= 0 ){
next_stage = 0;
}else if( sd.roulette_point.silver >= 0 ){
next_stage = 2;
}else if( sd.roulette_point.gold >= 0 ){
next_stage = 5;
}
// Get bonus item stage only from current stage or higher
sd.roulette.bonusItemID = 2202;
}else{
sd.roulette.bonusItemID = 0;
}
}
/// 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( map_session_data* sd ){
nullpo_retv( sd );
roulette_generate_bonus( *sd );
struct packet_roulette_open_ack p;
p.PacketType = 0xa1a;
p.Result = 0; // result
p.Serial = 0; // serial
p.Step = (sd->roulette.claimPrize) ? sd->roulette.stage - 1 : 0;
p.Idx = (sd->roulette.claimPrize) ? sd->roulette.prizeIdx : -1;
p.AdditionItemID = sd->roulette.bonusItemID;
p.GoldPoint = sd->roulette_point.gold;
p.SilverPoint = sd->roulette_point.silver;
p.BronzePoint = sd->roulette_point.bronze;
sd->state.roulette_open = true;
clif_send( &p, sizeof( p ), &sd->bl, SELF );
}
/// Request to open the roulette window
/// 0A19 (CZ_REQ_OPEN_ROULETTE)
void clif_parse_roulette_open( int fd, 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;
}
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( map_session_data* sd ){
nullpo_retv(sd);
struct packet_roulette_info_ack p;
p.PacketType = rouletteinfoackType;
p.PacketLength = sizeof(p);
p.RouletteSerial = 1;
for( int i = 0, count = 0; i < MAX_ROULETTE_LEVEL; i++ ){
for( int j = 0; j < MAX_ROULETTE_COLUMNS - i; j++ ){
p.ItemInfo[count].Row = i;
p.ItemInfo[count].Position = j;
p.ItemInfo[count].ItemId = client_nameid( rd.nameid[i][j] );
p.ItemInfo[count].Count = rd.qty[i][j];
#if PACKETVER >= 20180511
p.ItemInfo[count].unused = 0;
#endif
count++;
}
}
clif_send( &p, sizeof(p), &sd->bl, SELF );
}
/// Request the roulette reward data
/// 0A1B (CZ_REQ_ROULETTE_INFO)
void clif_parse_roulette_info( int fd, 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;
}
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, 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;
}
sd->state.roulette_open = false;
}
/// Response to a item reward request
/// 0A22 <type>.B <bonus item>.W (ZC_RECV_ROULETTE_ITEM)
static void clif_roulette_recvitem_ack(map_session_data *sd, enum RECV_ROULETTE_ITEM_REQ type) {
#if PACKETVER >= 20141016
nullpo_retv(sd);
struct packet_roulette_itemrecv_ack p;
p.PacketType = roulettercvitemackType;
p.Result = type;
p.AdditionItemID = sd->roulette.bonusItemID;
clif_send( &p, sizeof( p ), &sd->bl, SELF );
#endif
}
/**
* Claim roulette reward
* @param sd Player
* @return 0:Success
**/
static uint8 clif_roulette_getitem(map_session_data *sd) {
struct item it;
struct item bonus;
uint8 res = 1;
nullpo_retr(1, sd);
if (sd->roulette.prizeIdx < 0)
return RECV_ITEM_FAILED;
memset(&it, 0, sizeof(it));
memset(&bonus, 0, sizeof(bonus));
it.nameid = rd.nameid[sd->roulette.prizeStage][sd->roulette.prizeIdx];
it.identify = 1;
bonus.nameid = 2202;
bonus.identify = 1;
if ((res = pc_additem(sd, &it, rd.qty[sd->roulette.prizeStage][sd->roulette.prizeIdx], LOG_TYPE_ROULETTE)) == 0) {
int8 rchance = rnd() % 10000;
if(rchance > 9995 && (res = pc_additem(sd, &bonus, 1, LOG_TYPE_ROULETTE) == 0))
; // onSuccess
}
if( sd->roulette.bonusItemID == 0 ){
roulette_generate_bonus( *sd );
}
sd->roulette.claimPrize = false;
sd->roulette.prizeStage = 0;
sd->roulette.prizeIdx = -1;
sd->roulette.stage = 0;
return res;
}
/// 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( map_session_data *sd, unsigned char result, short stage, short prizeIdx, t_itemid bonusItemID ){
nullpo_retv( sd );
struct packet_roulette_generate_ack p;
p.PacketType = roulettgenerateackType;
p.Result = result;
p.Step = stage;
p.Idx = prizeIdx;
p.AdditionItemID = battle_config.feature_roulette_bonus_reward ? bonusItemID : 0;
p.RemainGold = sd->roulette_point.gold;
p.RemainSilver = sd->roulette_point.silver;
p.RemainBronze = sd->roulette_point.bronze;
clif_send( &p, sizeof( p ), &sd->bl, SELF );
}
and i tried add the sunglasses in db_roulete like this:
INSERT INTO `ragnarok`.`db_roulette` (`index`, `level`, `item_id`, `amount`, `flag`) VALUES ('42', '8', '2202', '1', '0');
and i make this implementations:
void roulette_generate_bonus( map_session_data& sd ){
if( battle_config.feature_roulette_bonus_reward && sd.roulette.bonusItemID == 0 ){
int next_stage = 0;
if( sd.roulette_point.bronze >= 0 ){
next_stage = 0;
}else if( sd.roulette_point.silver >= 0 ){
next_stage = 2;
}else if( sd.roulette_point.gold >= 0 ){
next_stage = 5;
}
// Get bonus item stage only from current stage or higher
sd.roulette.bonusItemID = rd.nameid[8][0];
}else{
sd.roulette.bonusItemID = 0;
}
}
/// 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( map_session_data* sd ){
nullpo_retv( sd );
roulette_generate_bonus( *sd );
struct packet_roulette_open_ack p;
p.PacketType = 0xa1a;
p.Result = 0; // result
p.Serial = 0; // serial
p.Step = (sd->roulette.claimPrize) ? sd->roulette.stage - 1 : 0;
p.Idx = (sd->roulette.claimPrize) ? sd->roulette.prizeIdx : -1;
p.AdditionItemID = sd->roulette.bonusItemID;
p.GoldPoint = sd->roulette_point.gold;
p.SilverPoint = sd->roulette_point.silver;
p.BronzePoint = sd->roulette_point.bronze;
sd->state.roulette_open = true;
clif_send( &p, sizeof( p ), &sd->bl, SELF );
}
/// Request to open the roulette window
/// 0A19 (CZ_REQ_OPEN_ROULETTE)
void clif_parse_roulette_open( int fd, 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;
}
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( map_session_data* sd ){
nullpo_retv(sd);
struct packet_roulette_info_ack p;
p.PacketType = rouletteinfoackType;
p.PacketLength = sizeof(p);
p.RouletteSerial = 1;
for( int i = 0, count = 0; i < MAX_ROULETTE_LEVEL; i++ ){
for( int j = 0; j < MAX_ROULETTE_COLUMNS - i; j++ ){
p.ItemInfo[count].Row = i;
p.ItemInfo[count].Position = j;
p.ItemInfo[count].ItemId = client_nameid( rd.nameid[i][j] );
p.ItemInfo[count].Count = rd.qty[i][j];
#if PACKETVER >= 20180511
p.ItemInfo[count].unused = 0;
#endif
count++;
}
}
if (sd->roulette.bonusItemID != 0) {
p.ItemInfo[42].ItemId = client_nameid(rd.nameid[8][0]);
p.ItemInfo[42].Count = rd.qty[8][0];
}
clif_send( &p, sizeof(p), &sd->bl, SELF );
}
/// Request the roulette reward data
/// 0A1B (CZ_REQ_ROULETTE_INFO)
void clif_parse_roulette_info( int fd, 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;
}
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, 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;
}
sd->state.roulette_open = false;
}
/// Response to a item reward request
/// 0A22 <type>.B <bonus item>.W (ZC_RECV_ROULETTE_ITEM)
static void clif_roulette_recvitem_ack(map_session_data *sd, enum RECV_ROULETTE_ITEM_REQ type) {
#if PACKETVER >= 20141016
nullpo_retv(sd);
struct packet_roulette_itemrecv_ack p;
p.PacketType = roulettercvitemackType;
p.Result = type;
p.AdditionItemID = sd->roulette.bonusItemID;
clif_send( &p, sizeof( p ), &sd->bl, SELF );
#endif
}
/**
* Claim roulette reward
* @param sd Player
* @return 0:Success
**/
static uint8 clif_roulette_getitem(map_session_data *sd) {
struct item it;
struct item bonus;
uint8 res = 1;
nullpo_retr(1, sd);
if (sd->roulette.prizeIdx < 0)
return RECV_ITEM_FAILED;
memset(&it, 0, sizeof(it));
memset(&bonus, 0, sizeof(bonus));
it.nameid = rd.nameid[sd->roulette.prizeStage][sd->roulette.prizeIdx];
it.identify = 1;
bonus.nameid = rd.nameid[8][0];
bonus.identify = 1;
if ((res = pc_additem(sd, &it, rd.qty[sd->roulette.prizeStage][sd->roulette.prizeIdx], LOG_TYPE_ROULETTE)) == 0) {
int8 rchance = rnd() % 10000;
if(rchance > 9995 && (res = pc_additem(sd, &bonus, 1, LOG_TYPE_ROULETTE) == 0))
; // onSuccess
}
if( sd->roulette.bonusItemID == 0 ){
roulette_generate_bonus( *sd );
}
sd->roulette.claimPrize = false;
sd->roulette.prizeStage = 0;
sd->roulette.prizeIdx = -1;
sd->roulette.stage = 0;
return res;
}
/// 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( map_session_data *sd, unsigned char result, short stage, short prizeIdx, t_itemid bonusItemID ){
nullpo_retv( sd );
struct packet_roulette_generate_ack p;
p.PacketType = roulettgenerateackType;
p.Result = result;
p.Step = stage;
p.Idx = prizeIdx;
p.AdditionItemID = battle_config.feature_roulette_bonus_reward ? bonusItemID : 0;
p.RemainGold = sd->roulette_point.gold;
p.RemainSilver = sd->roulette_point.silver;
p.RemainBronze = sd->roulette_point.bronze;
clif_send( &p, sizeof( p ), &sd->bl, SELF );
}
This way, when he tries to run the roulette wheel, a serious error occurs, and in the server log it appears that he tried to look for item 62553 in item_db and the item does not exist...
someone to give me some help?