Browse Source

MVP item drop mode setting added
- Added a new configuration setting "item_drop_mvp_mode"
* By default "item_drop_mvp_mode" is set to official order (0) which is always starting at first, then going to the second if the first didn't drop and only checking the third if the second didn't drop either
* @mobinfo will now properly consider this and display the effective chance, so if the MVP has 3 MVP item drops at 50%, the first item will display the chance 50%, the second 25% and the third 12.5%, this should help a lot against drop rate confusion (e.g. players wondering why always only the first item drops when all three are displayed at 100%); this only applies to official order (0)
* When "item_drop_mvp_mode" is set to random order (1), MVP item drops are checked in random order, but if one MVP item drops, the process will be canceled, so you will never get more than one MVP item no matter how high the drop rate is
* When "item_drop_mvp_mode" is set to all items (2), all MVP item drops are checked and have a chance to drop, regardless of other MVP items already being dropped or not (i.e. there is a chance that the player gets all 3 MVP items)

Playtester 10 years ago
parent
commit
5110ddbaf4
5 changed files with 44 additions and 18 deletions
  1. 2 0
      conf/battle/drops.conf
  2. 12 5
      src/map/atcommand.c
  3. 1 0
      src/map/battle.c
  4. 1 0
      src/map/battle.h
  5. 28 13
      src/map/mob.c

+ 2 - 0
conf/battle/drops.conf

@@ -68,9 +68,11 @@ item_drop_card_min: 1
 item_drop_card_max: 10000
 item_drop_card_max: 10000
 
 
 // The rate adjustment for the MVP items that the MVP gets directly in their inventory
 // The rate adjustment for the MVP items that the MVP gets directly in their inventory
+// Mode: 0 - official order, 1 - random order, 2 - all items
 item_rate_mvp: 100
 item_rate_mvp: 100
 item_drop_mvp_min: 1
 item_drop_mvp_min: 1
 item_drop_mvp_max: 10000
 item_drop_mvp_max: 10000
+item_drop_mvp_mode: 0
 
 
 // The rate adjustment for card-granted item drops.
 // The rate adjustment for card-granted item drops.
 item_rate_adddrop: 100
 item_rate_adddrop: 100

+ 12 - 5
src/map/atcommand.c

@@ -7047,25 +7047,32 @@ ACMD_FUNC(mobinfo)
 			clif_displaymessage(fd, atcmd_output);
 			clif_displaymessage(fd, atcmd_output);
 		// mvp
 		// mvp
 		if (mob->mexp) {
 		if (mob->mexp) {
+			float mvppercent, mvpremain;
 			sprintf(atcmd_output, msg_txt(sd,1247), mob->mexp); //  MVP Bonus EXP:%u
 			sprintf(atcmd_output, msg_txt(sd,1247), mob->mexp); //  MVP Bonus EXP:%u
 			clif_displaymessage(fd, atcmd_output);
 			clif_displaymessage(fd, atcmd_output);
 			strcpy(atcmd_output, msg_txt(sd,1248)); //  MVP Items:
 			strcpy(atcmd_output, msg_txt(sd,1248)); //  MVP Items:
+			mvpremain = 100.0; //Remaining drop chance for official mvp drop mode
 			j = 0;
 			j = 0;
 			for (i = 0; i < MAX_MVP_DROP; i++) {
 			for (i = 0; i < MAX_MVP_DROP; i++) {
 				if (mob->mvpitem[i].nameid <= 0 || (item_data = itemdb_exists(mob->mvpitem[i].nameid)) == NULL)
 				if (mob->mvpitem[i].nameid <= 0 || (item_data = itemdb_exists(mob->mvpitem[i].nameid)) == NULL)
 					continue;
 					continue;
-				if (mob->mvpitem[i].p > 0) {
+				//Because if there are 3 MVP drops at 50%, the first has a chance of 50%, the second 25% and the third 12.5%
+				mvppercent = (float)mob->mvpitem[i].p * mvpremain / 10000.0;
+				if(battle_config.item_drop_mvp_mode == 0) {
+					mvpremain -= mvppercent;
+				}
+				if (mvppercent > 0) {
 					j++;
 					j++;
 					if (j == 1) {
 					if (j == 1) {
 						if (item_data->slot)
 						if (item_data->slot)
-							sprintf(atcmd_output2, " %s[%d]  %02.02f%%", item_data->jname, item_data->slot, (float)mob->mvpitem[i].p / 100);
+							sprintf(atcmd_output2, " %s[%d]  %02.02f%%", item_data->jname, item_data->slot, mvppercent);
 						else
 						else
-							sprintf(atcmd_output2, " %s  %02.02f%%", item_data->jname, (float)mob->mvpitem[i].p / 100);
+							sprintf(atcmd_output2, " %s  %02.02f%%", item_data->jname, mvppercent);
 					} else {
 					} else {
 						if (item_data->slot)
 						if (item_data->slot)
-							sprintf(atcmd_output2, " - %s[%d]  %02.02f%%", item_data->jname, item_data->slot, (float)mob->mvpitem[i].p / 100);
+							sprintf(atcmd_output2, " - %s[%d]  %02.02f%%", item_data->jname, item_data->slot, mvppercent);
 						else
 						else
-							sprintf(atcmd_output2, " - %s  %02.02f%%", item_data->jname, (float)mob->mvpitem[i].p / 100);
+							sprintf(atcmd_output2, " - %s  %02.02f%%", item_data->jname, mvppercent);
 					}
 					}
 					strcat(atcmd_output, atcmd_output2);
 					strcat(atcmd_output, atcmd_output2);
 				}
 				}

+ 1 - 0
src/map/battle.c

@@ -7667,6 +7667,7 @@ static const struct _battle_data {
 	{ "item_drop_card_max",                 &battle_config.item_drop_card_max,              10000,  1,      10000,          },
 	{ "item_drop_card_max",                 &battle_config.item_drop_card_max,              10000,  1,      10000,          },
 	{ "item_drop_mvp_min",                  &battle_config.item_drop_mvp_min,               1,      1,      10000,          },
 	{ "item_drop_mvp_min",                  &battle_config.item_drop_mvp_min,               1,      1,      10000,          },
 	{ "item_drop_mvp_max",                  &battle_config.item_drop_mvp_max,               10000,  1,      10000,          },
 	{ "item_drop_mvp_max",                  &battle_config.item_drop_mvp_max,               10000,  1,      10000,          },
+	{ "item_drop_mvp_mode",                 &battle_config.item_drop_mvp_mode,              0,      0,      2,              },
 	{ "item_drop_heal_min",                 &battle_config.item_drop_heal_min,              1,      1,      10000,          },
 	{ "item_drop_heal_min",                 &battle_config.item_drop_heal_min,              1,      1,      10000,          },
 	{ "item_drop_heal_max",                 &battle_config.item_drop_heal_max,              10000,  1,      10000,          },
 	{ "item_drop_heal_max",                 &battle_config.item_drop_heal_max,              10000,  1,      10000,          },
 	{ "item_drop_use_min",                  &battle_config.item_drop_use_min,               1,      1,      10000,          },
 	{ "item_drop_use_min",                  &battle_config.item_drop_use_min,               1,      1,      10000,          },

+ 1 - 0
src/map/battle.h

@@ -314,6 +314,7 @@ extern struct Battle_Config
 	int item_drop_card_min,item_drop_card_max;
 	int item_drop_card_min,item_drop_card_max;
 	int item_drop_equip_min,item_drop_equip_max;
 	int item_drop_equip_min,item_drop_equip_max;
 	int item_drop_mvp_min,item_drop_mvp_max;	// End Addition
 	int item_drop_mvp_min,item_drop_mvp_max;	// End Addition
+	int item_drop_mvp_mode; //rAthena addition [Playtester]
 	int item_drop_heal_min,item_drop_heal_max;	// Added by Valatris
 	int item_drop_heal_min,item_drop_heal_max;	// Added by Valatris
 	int item_drop_use_min,item_drop_use_max;	//End
 	int item_drop_use_min,item_drop_use_max;	//End
 	int item_drop_treasure_min,item_drop_treasure_max; //by [Skotlex]
 	int item_drop_treasure_min,item_drop_treasure_max; //by [Skotlex]

+ 28 - 13
src/map/mob.c

@@ -2531,27 +2531,39 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
 		log_mvp[1] = mexp;
 		log_mvp[1] = mexp;
 
 
 		if( !(map[m].flag.nomvploot || type&1) ) {
 		if( !(map[m].flag.nomvploot || type&1) ) {
-			/* pose them randomly in the list -- so on 100% drop servers it wont always drop the same item */
+			//Order might be random depending on item_drop_mvp_mode config setting
 			int mdrop_id[MAX_MVP_DROP];
 			int mdrop_id[MAX_MVP_DROP];
 			int mdrop_p[MAX_MVP_DROP];
 			int mdrop_p[MAX_MVP_DROP];
 
 
 			memset(mdrop_id,0,MAX_MVP_DROP*sizeof(int));
 			memset(mdrop_id,0,MAX_MVP_DROP*sizeof(int));
 			memset(mdrop_p,0,MAX_MVP_DROP*sizeof(int));
 			memset(mdrop_p,0,MAX_MVP_DROP*sizeof(int));
 
 
-			//Make random order
-			for(i = 0; i < MAX_MVP_DROP; i++) {
-				while( 1 ) {
-					uint8 va = rnd()%MAX_MVP_DROP;
-					if (mdrop_id[va] == 0) {
-						if (md->db->mvpitem[i].nameid > 0) {
-							mdrop_id[va] = md->db->mvpitem[i].nameid;
-							mdrop_p[va] = md->db->mvpitem[i].p;
+			if(battle_config.item_drop_mvp_mode == 1) {
+				//Random order
+				for(i = 0; i < MAX_MVP_DROP; i++) {
+					while( 1 ) {
+						uint8 va = rnd()%MAX_MVP_DROP;
+						if (mdrop_id[va] == 0) {
+							if (md->db->mvpitem[i].nameid > 0) {
+								mdrop_id[va] = md->db->mvpitem[i].nameid;
+								mdrop_p[va] = md->db->mvpitem[i].p;
+							}
+							else
+								mdrop_id[va] = -1;
+							break;
 						}
 						}
-						else
-							mdrop_id[va] = -1;
-						break;
 					}
 					}
 				}
 				}
+			} else {
+				//Normal order
+				for(i = 0; i < MAX_MVP_DROP; i++) {
+					if (md->db->mvpitem[i].nameid > 0) {
+						mdrop_id[i] = md->db->mvpitem[i].nameid;
+						mdrop_p[i] = md->db->mvpitem[i].p;
+					}
+					else
+						mdrop_id[i] = -1;
+				}
 			}
 			}
 
 
 			for(i = 0; i < MAX_MVP_DROP; i++) {
 			for(i = 0; i < MAX_MVP_DROP; i++) {
@@ -2589,7 +2601,10 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
 
 
 				//Logs items, MVP prizes [Lupus]
 				//Logs items, MVP prizes [Lupus]
 				log_pick_mob(md, LOG_TYPE_MVP, -1, &item);
 				log_pick_mob(md, LOG_TYPE_MVP, -1, &item);
-				break;
+				//If item_drop_mvp_mode is not 2, then only one item should be granted
+				if(battle_config.item_drop_mvp_mode != 2) {
+					break;
+				}
 			}
 			}
 		}
 		}