Drop calculation related cleanup.
This commit is contained in:
@@ -204,10 +204,10 @@ public class NpcData implements IXmlReader
|
||||
}
|
||||
case "attribute":
|
||||
{
|
||||
for (Node attribute_node = statsNode.getFirstChild(); attribute_node != null; attribute_node = attribute_node.getNextSibling())
|
||||
for (Node attributeNode = statsNode.getFirstChild(); attributeNode != null; attributeNode = attributeNode.getNextSibling())
|
||||
{
|
||||
attrs = attribute_node.getAttributes();
|
||||
switch (attribute_node.getNodeName().toLowerCase())
|
||||
attrs = attributeNode.getAttributes();
|
||||
switch (attributeNode.getNodeName().toLowerCase())
|
||||
{
|
||||
case "attack":
|
||||
{
|
||||
@@ -614,12 +614,13 @@ public class NpcData implements IXmlReader
|
||||
|
||||
if (dropLists != null)
|
||||
{
|
||||
Collections.shuffle(dropLists);
|
||||
for (DropHolder dropHolder : dropLists)
|
||||
{
|
||||
switch (dropHolder.getDropType())
|
||||
{
|
||||
case DROP:
|
||||
case LUCKY: // Lucky drops are added to normal drops and calculated later
|
||||
case LUCKY: // Lucky drops are added to normal drops and calculated later.
|
||||
{
|
||||
template.addDrop(dropHolder);
|
||||
break;
|
||||
|
@@ -1100,6 +1100,7 @@ public class Attackable extends Npc
|
||||
}
|
||||
}
|
||||
}
|
||||
deathItems.clear();
|
||||
}
|
||||
}
|
||||
return;
|
||||
@@ -1137,6 +1138,7 @@ public class Attackable extends Npc
|
||||
broadcastPacket(sm);
|
||||
}
|
||||
}
|
||||
deathItems.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -17,7 +17,6 @@
|
||||
package org.l2jmobius.gameserver.model.actor.templates;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -668,82 +667,89 @@ public class NpcTemplate extends CreatureTemplate implements IIdentifiable
|
||||
_dropListSpoil.add(dropHolder);
|
||||
}
|
||||
|
||||
public List<DropHolder> getDropList(DropType dropType)
|
||||
public List<DropHolder> getDropList()
|
||||
{
|
||||
switch (dropType)
|
||||
{
|
||||
case DROP:
|
||||
case LUCKY: // never happens
|
||||
{
|
||||
return _dropListDeath;
|
||||
}
|
||||
case SPOIL:
|
||||
{
|
||||
return _dropListSpoil;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return _dropListDeath;
|
||||
}
|
||||
|
||||
public Collection<ItemHolder> calculateDrops(DropType dropType, Creature victim, Creature killer)
|
||||
public List<DropHolder> getSpoilList()
|
||||
{
|
||||
final List<DropHolder> templateList = getDropList(dropType);
|
||||
if (templateList == null)
|
||||
return _dropListSpoil;
|
||||
}
|
||||
|
||||
public List<ItemHolder> calculateDrops(DropType dropType, Creature victim, Creature killer)
|
||||
{
|
||||
final List<DropHolder> dropList = dropType == DropType.SPOIL ? _dropListSpoil : _dropListDeath;
|
||||
if (dropList == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
final List<DropHolder> dropList = new ArrayList<>(templateList);
|
||||
|
||||
// randomize drop order
|
||||
Collections.shuffle(dropList);
|
||||
|
||||
// level difference calculations
|
||||
final int levelDifference = victim.getLevel() - killer.getLevel();
|
||||
final double levelGapChanceToDropAdena = Util.map(levelDifference, -Config.DROP_ADENA_MAX_LEVEL_DIFFERENCE, -Config.DROP_ADENA_MIN_LEVEL_DIFFERENCE, Config.DROP_ADENA_MIN_LEVEL_GAP_CHANCE, 100d);
|
||||
final double levelGapChanceToDrop = Util.map(levelDifference, -Config.DROP_ITEM_MAX_LEVEL_DIFFERENCE, -Config.DROP_ITEM_MIN_LEVEL_DIFFERENCE, Config.DROP_ITEM_MIN_LEVEL_GAP_CHANCE, 100d);
|
||||
|
||||
int dropOccurrenceCounter = victim.isRaid() ? Config.DROP_MAX_OCCURRENCES_RAIDBOSS : Config.DROP_MAX_OCCURRENCES_NORMAL;
|
||||
Collection<ItemHolder> calculatedDrops = null;
|
||||
for (DropHolder dropItem : dropList)
|
||||
List<ItemHolder> calculatedDrops = null;
|
||||
List<ItemHolder> randomDrops = null;
|
||||
ItemHolder replacedItem = null;
|
||||
if (dropOccurrenceCounter > 0)
|
||||
{
|
||||
// check if maximum drop occurrences have been reached
|
||||
// items that have 100% drop chance without server rate multipliers drop normally
|
||||
if ((dropOccurrenceCounter == 0) && (dropItem.getChance() < 100))
|
||||
for (DropHolder dropItem : dropList)
|
||||
{
|
||||
continue;
|
||||
// check if maximum drop occurrences have been reached
|
||||
// items that have 100% drop chance without server rate multipliers drop normally
|
||||
if ((dropOccurrenceCounter == 0) && (dropItem.getChance() < 100) && (randomDrops != null) && (calculatedDrops != null))
|
||||
{
|
||||
// remove a random existing drop (temporarily if not other item replaces it)
|
||||
dropOccurrenceCounter++;
|
||||
replacedItem = randomDrops.remove(Rnd.get(randomDrops.size()));
|
||||
calculatedDrops.remove(replacedItem);
|
||||
}
|
||||
|
||||
// check level gap that may prevent to drop item
|
||||
if ((Rnd.nextDouble() * 100) > (dropItem.getItemId() == Inventory.ADENA_ID ? levelGapChanceToDropAdena : levelGapChanceToDrop))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// calculate chances
|
||||
final ItemHolder drop = calculateDrop(dropItem, victim, killer);
|
||||
if (drop == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// create lists
|
||||
if (randomDrops == null)
|
||||
{
|
||||
randomDrops = new ArrayList<>(dropOccurrenceCounter);
|
||||
}
|
||||
if (calculatedDrops == null)
|
||||
{
|
||||
calculatedDrops = new ArrayList<>(dropOccurrenceCounter);
|
||||
}
|
||||
|
||||
// finally
|
||||
if (dropItem.getChance() < 100)
|
||||
{
|
||||
dropOccurrenceCounter--;
|
||||
randomDrops.add(drop);
|
||||
}
|
||||
calculatedDrops.add(drop);
|
||||
}
|
||||
|
||||
// check level gap that may prevent drop this item
|
||||
final double levelGapChanceToDrop;
|
||||
if (dropItem.getItemId() == Inventory.ADENA_ID)
|
||||
{
|
||||
levelGapChanceToDrop = Util.map(levelDifference, -Config.DROP_ADENA_MAX_LEVEL_DIFFERENCE, -Config.DROP_ADENA_MIN_LEVEL_DIFFERENCE, Config.DROP_ADENA_MIN_LEVEL_GAP_CHANCE, 100.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
levelGapChanceToDrop = Util.map(levelDifference, -Config.DROP_ITEM_MAX_LEVEL_DIFFERENCE, -Config.DROP_ITEM_MIN_LEVEL_DIFFERENCE, Config.DROP_ITEM_MIN_LEVEL_GAP_CHANCE, 100.0);
|
||||
}
|
||||
if ((Rnd.nextDouble() * 100) > levelGapChanceToDrop)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// calculate chances
|
||||
final ItemHolder drop = calculateDrop(dropItem, victim, killer);
|
||||
if (drop == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// create list
|
||||
if (calculatedDrops == null)
|
||||
{
|
||||
calculatedDrops = new ArrayList<>();
|
||||
}
|
||||
|
||||
// finally
|
||||
if (dropItem.getChance() < 100)
|
||||
{
|
||||
dropOccurrenceCounter--;
|
||||
}
|
||||
calculatedDrops.add(drop);
|
||||
}
|
||||
// add temporarily removed item when not replaced
|
||||
if ((dropOccurrenceCounter > 0) && (replacedItem != null) && (calculatedDrops != null))
|
||||
{
|
||||
calculatedDrops.add(replacedItem);
|
||||
}
|
||||
// clear random drops
|
||||
if (randomDrops != null)
|
||||
{
|
||||
randomDrops.clear();
|
||||
randomDrops = null;
|
||||
}
|
||||
|
||||
// champion extra drop
|
||||
|
Reference in New Issue
Block a user