瀏覽代碼

feat(drops): Added config for multiple group rolls

Multiple group rolls can now be activated when PreciseDropCalculation is true.
Added a config option to aggregate the results.
Noe Caratini 3 年之前
父節點
當前提交
57baacfb99

+ 6 - 0
src/main/java/com/l2jserver/gameserver/config/GeneralConfiguration.java

@@ -257,6 +257,12 @@ public interface GeneralConfiguration extends Mutable, Reloadable {
 	
 	@Key("PreciseDropCalculation")
 	Boolean preciseDropCalculation();
+
+	@Key("PreciseDropMultipleGroupRolls")
+	Boolean preciseDropMultipleGroupRolls();
+
+	@Key("PreciseDropMultipleRollsAggregateDrops")
+	Boolean preciseDropMultipleRollsAggregateDrops();
 	
 	@Key("MultipleItemDrop")
 	Boolean multipleItemDrop();

+ 5 - 1
src/main/java/com/l2jserver/gameserver/model/drops/GroupedGeneralDropItem.java

@@ -18,6 +18,7 @@
  */
 package com.l2jserver.gameserver.model.drops;
 
+import static com.l2jserver.gameserver.config.Configuration.general;
 import static com.l2jserver.gameserver.model.drops.strategy.IKillerChanceModifierStrategy.NO_RULES;
 
 import java.util.ArrayList;
@@ -47,7 +48,10 @@ public final class GroupedGeneralDropItem implements IDropItem {
 	 * @param chance the chance of this drop item.
 	 */
 	public GroupedGeneralDropItem(double chance) {
-		this(chance, IGroupedItemDropCalculationStrategy.DEFAULT_STRATEGY, IKillerChanceModifierStrategy.DEFAULT_STRATEGY, IPreciseDeterminationStrategy.DEFAULT);
+		this(chance,
+				general().preciseDropMultipleGroupRolls() ? IGroupedItemDropCalculationStrategy.PRECISE_MULTIPLE_GROUP_ROLLS : IGroupedItemDropCalculationStrategy.DEFAULT_STRATEGY,
+				IKillerChanceModifierStrategy.DEFAULT_STRATEGY,
+				IPreciseDeterminationStrategy.DEFAULT);
 	}
 	
 	/**

+ 31 - 7
src/main/java/com/l2jserver/gameserver/model/drops/strategy/IGroupedItemDropCalculationStrategy.java

@@ -18,23 +18,29 @@
  */
 package com.l2jserver.gameserver.model.drops.strategy;
 
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
 import com.l2jserver.commons.util.Rnd;
 import com.l2jserver.gameserver.model.actor.L2Character;
 import com.l2jserver.gameserver.model.drops.GeneralDropItem;
 import com.l2jserver.gameserver.model.drops.GroupedGeneralDropItem;
 import com.l2jserver.gameserver.model.drops.IDropItem;
 import com.l2jserver.gameserver.model.holders.ItemHolder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import static com.l2jserver.gameserver.config.Configuration.general;
 
 /**
  * @author Battlecruiser
  */
 public interface IGroupedItemDropCalculationStrategy {
+	Logger LOG = LoggerFactory.getLogger(IGroupedItemDropCalculationStrategy.class);
 	/**
 	 * The default strategy used in L2J to calculate drops. When the group's chance raises over 100% and group has precise calculation, the dropped item's amount increases.
 	 */
@@ -105,11 +111,29 @@ public interface IGroupedItemDropCalculationStrategy {
 		if ((Rnd.nextDouble() * 100) < (normalized.getChance() % 100)) {
 			rolls++;
 		}
+
 		List<ItemHolder> dropped = new ArrayList<>(rolls);
 		for (int i = 0; i < rolls; i++) {
 			// As further normalizing on already normalized drop group does nothing, we can just pass the calculation to DEFAULT_STRATEGY with precise calculation disabled as we handle it.
-			dropped.addAll(normalized.calculateDrops(victim, killer));
+			List<ItemHolder> drops = normalized.calculateDrops(victim, killer);
+			if (drops != null) {
+				dropped.addAll(drops);
+			}
+		}
+
+		if (general().preciseDropMultipleRollsAggregateDrops()) {
+			Map<Integer, Long> countByItemId = new HashMap<>();
+			for (ItemHolder drop : dropped) {
+				Long currentCount = countByItemId.getOrDefault(drop.getId(), 0L);
+				countByItemId.put(drop.getId(), currentCount + drop.getCount());
+			}
+
+			dropped.clear();
+			for (Map.Entry<Integer, Long> entry : countByItemId.entrySet()) {
+				dropped.add(new ItemHolder(entry.getKey(), entry.getValue()));
+			}
 		}
+
 		return dropped.isEmpty() ? null : dropped;
 	};
 	

+ 9 - 0
src/main/resources/config/general.properties

@@ -339,6 +339,15 @@ AutoDeleteInvalidQuestData = False
 # Default: True
 PreciseDropCalculation = True
 
+# How to handle grouped drops when PreciseDropCalculation = True
+# If True, grouped drops will make another roll for a drop in the group instead of just increasing the amount of dropped items.
+# Default: False
+PreciseDropMultipleGroupRolls = False
+# If True, aggregates the results of multiple rolls on the same group.
+# e.g. A mob will drop 100 Adena instead of 10 times 10 Adena.
+# Default: False
+PreciseDropMultipleRollsAggregateDrops = False
+
 # Allow creating multiple non-stackable items at one time?
 # Default: True
 MultipleItemDrop = True