And that's why I told you guys to always keep backups... The Drop quantity multiplier mod was kinda messy and didn't worked as intended. I removed it from first post and below you'll find fixed and expanded version.
6. Drop quantity multiplier
This config allows to change the quantity of stacks that drop from monsters and while gathering. This is a bit complicated, though. Since I didn’t like to always pick up exactly same number of items in the stack this multiplier is actually randomized. You can provide a range and the code will select a number from that range and multiply the stack quantity by that number. In config file you set low end of the range and high end of the range separated by a comma.
How the math works is as follows - when you're about to pick up any kind of random loot the game will set the default quantity. Then this will be MULTIPLIED by General Drop Multiplier. In next step a handler for different type of loot will take over - gathering, fishing, stealing, moster drop - you name it. In there it will by MULTIPLIED again by proper multiplier.
Example:
Assume you'll set following values:
Code:
rate.general.drop.multiplier = 5, 15
rate.collection.drop.multiplier = 7, 13
While cutting a tree you would by default get 2 logs. Server will pick a random multiplier from <5,15> range (let's say 7) and calculate then number of logs as 14. Then it will sent those 14 logs to collection handler, which will select its own random multiplier from <7,13> range (let's say 10) and calculate number of logs as 140 (2 * 7 * 10). This number of logs will be sent to the client.
In a nutshell, rate.general.drop.multiplier is used to bump drop across the entire game and then all other settings can additionally rise drop in specific type of loot. It's a bit convoluted, but I hope I explained it well enough.
Implementation:
RateConfig.java:
Code:
/* add following entries */
@ConfigComments(comment = {"General drop count random multiplier range", "Default: 5, 15"})
@ConfigProperty(name = "rate.general.drop.multiplier", value = "5, 15")
public static int[] GENERAL_DROP_MULTIPLIER;
@ConfigComments(comment = {"Monster drop count random multiplier range", "Default: 5, 15"})
@ConfigProperty(name = "rate.monster.drop.multiplier", value = "5, 15")
public static int[] MONSTER_DROP_MULTIPLIER;
@ConfigComments(comment = {"Collection drop count random multiplayer range", "Default: 5, 15"})
@ConfigProperty(name = "rate.collection.drop.multiplier", value = "5, 15")
public static int[] COLLECTION_DROP_MULTIPLIER;
@ConfigComments(comment = {"Fishing drop count random multiplayer range", "Default: 5, 15"})
@ConfigProperty(name = "rate.fishing.drop.multiplier", value = "5, 15")
public static int[] FISHING_DROP_MULTIPLIER;
@ConfigComments(comment = {"Fishing drop count random multiplayer range", "Default: 5, 15"})
@ConfigProperty(name = "rate.steal.drop.multiplier", value = "5, 15")
public static int[] STEAL_DROP_MULTIPLIER;
ItemMainGroupService.java (line 81):
Code:
/* you need to replace existing if() statement. In the snippet you’ll find the original code in // comments and the code to replace it with is below that */
//if (itemTemplate.isStack() && Rnd.getChance(killer.getGameStats().getDoubleDropItemLuck().getIntValue() / 10000)) {
// itemCount *= 2;
//}
if (itemTemplate.isStack()){
itemCount *= ThreadLocalRandom.current ().nextInt(RateConfig.GENERAL_DROP_MULTIPLIER[0], RateConfig.GENERAL_DROP_MULTIPLIER[1] + 1);
if(Rnd.getChance(killer.getGameStats().getDoubleDropItemLuck().getIntValue() / 10000)){
itemCount *= 2;
}
}
DeadBody.java (lines 53 and 87):
Code:
/* you need to add a loop to iterate through all items in created drop bag and, if item is stackable, apply multiplier */
/* line 53 */
this.dropBag = ItemMainGroupService.getDropBag(dropId, (Player) killer, this.getGameObjectId(), this.getCreatureId(), EDropBagType.DeadBody, RateConfig.MONSTER_DROP_RATE);
if(this.dropBag != null) {
for (final Item droppedItem : this.dropBag.getDropMap().values()) {
if(droppedItem.getTemplate().isStack()) {
droppedItem.setCount(droppedItem.getCount() * ThreadLocalRandom.current ().nextInt(RateConfig.MONSTER_DROP_MULTIPLIER[0], RateConfig.MONSTER_DROP_MULTIPLIER[1] + 1));
}
}
}
this.winnerGameObjId = aggroInfo.getKillerSession();
/* line 87 */
this.dropBag = ItemMainGroupService.getDropBag(dropId, (Player) killer, this.getGameObjectId(), this.getCreatureId(), EDropBagType.DeadBody, RateConfig.MONSTER_DROP_RATE);
if(this.dropBag != null) {
for (final Item droppedItem : this.dropBag.getDropMap().values()) {
if(droppedItem.getTemplate().isStack()) {
droppedItem.setCount(droppedItem.getCount() * ThreadLocalRandom.current ().nextInt(RateConfig.MONSTER_DROP_MULTIPLIER[0], RateConfig.MONSTER_DROP_MULTIPLIER[1] + 1));
}
}
}
this.winnerGameObjId = aggroInfo.getKillerSession();
FrameEventCollect.java (line 66):
Code:
/* you need to add the item.setCount() line. For clarity I’m adding entire for loop in the snippet */
for (final Item item : dropBag.getDropMap().values()) {
item.setCount(item.getCount() * ThreadLocalRandom.current ().nextInt(RateConfig.COLLECTION_DROP_MULTIPLIER[0], RateConfig.COLLECTION_DROP_MULTIPLIER[1] + 1));
LifeActionEXPData.getInstance().reward(player, item.getItemId(), (dropBagType == EDropBagType.CollectTentInstallation) ? ELifeExpType.Farming : ELifeExpType.Gather);
player.getObserveController().notifyObserver(EObserveType.gatherItem, item.getItemId(), item.getEnchantLevel(), item.getCount(), player.getObjectId());
}
AFishingAction.java (line 110):
Code:
/* apply multiplier just before sending drop bag to player */
dropBag.setValidityTime(startTime);
for (final Item droppedItem : dropBag.getDropMap().values()) {
if (droppedItem.getTemplate().isStack()) {
droppedItem.setCount(droppedItem.getCount() * ThreadLocalRandom.current ().nextInt(RateConfig.FISHING_DROP_MULTIPLIER[0], RateConfig.FISHING_DROP_MULTIPLIER[1] + 1));
}
}
player.getPlayerBag().setDropBag(dropBag);
FrameEventSteal.java (line 71):
Code:
/* apply multiplier just before sending drop bag to player */
if (dropBag != null) {
for (final Item droppedItem : dropBag.getDropMap().values()) {
if(droppedItem.getTemplate().isStack()) {
droppedItem.setCount(droppedItem.getCount() * ThreadLocalRandom.current ().nextInt(RateConfig.STEAL_DROP_MULTIPLIER[0], RateConfig.STEAL_DROP_MULTIPLIER[1] + 1));
}
}
player.getPlayerBag().setDropBag(dropBag);
player.sendPacket(new SMGetDroppedItems(npcGameObjId, dropBag));
} else {
rate.properties:
Code:
# add entries. To disable particular multiplier set its value to "1, 1" (without quotation marks)
# General drop count random multiplier range
# Default: 5, 15
rate.general.drop.multiplier = 5, 15
# Monster drop count random multiplier range
# Default: 5, 15
rate.monster.drop.multiplier = 5, 15
# Collection drop count random multiplayer range
# Default: 5, 15
rate.collection.drop.multiplier = 5, 15
# Fishing drop count random multiplayer range
# Default: 5, 15
rate.fishing.drop.multiplier = 5, 15
# Fishing drop count random multiplayer range
# Default: 5, 15
rate.steal.drop.multiplier = 5, 15
There... Now it should work :)