Skip to content

Commit

Permalink
Fix duplication of dropped items on mob death.
Browse files Browse the repository at this point in the history
 * The EntityDeathEvent handler contains a work-around for a vanilla Minecraft
   bug wherein mob equipment with a drop chance of 100% does not always drop.
 * Prior to Bukkit commit d611cff, the EntityDeathEvent did not include mob
   equipment in the list of drops, so it was safe for Doppelganger to simply
   strip the mob of its gear and add those items to the drops.
 * In newer versions of Bukkit, the equipment is present in the drops and is
   also still on the mob itself, so the Doppelganger work-around code leads
   to duplicate items in the drops.  This commit avoids adding equipment to the
   drops when an identical item is already present in the dropped item list.
 * This fix works for older Bukkit versions as well.
 * As described at Bukkit/CraftBukkit@fb58cc9
   the new Bukkit item dropping code is still reliant on vanilla code to drop
   items and that vanilla code still sometimes fails to drop items even though
   the drop probability is 100%.  The work-around code still corrects that issue.
  • Loading branch information
totemo committed May 28, 2014
1 parent b7d7866 commit 2f358f2
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 20 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>io.github.totemo</groupId>
<artifactId>Doppelganger</artifactId>
<version>0.9.0</version>
<version>0.9.1</version>
<packaging>jar</packaging>
<name>Doppelganger</name>
<properties>
Expand Down
64 changes: 45 additions & 19 deletions src/io/github/totemo/doppelganger/Doppelganger.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.github.totemo.doppelganger;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
Expand Down Expand Up @@ -170,10 +171,13 @@ public void onBlockPlace(BlockPlaceEvent event)

// --------------------------------------------------------------------------
/**
* Bukkit or vanilla Minecraft doesn't always drop equipment, when the drop
* chance is 1.0 (or more). Try to work around that by moving the equipment
* into the drops. Normally the equipment is not part of the drops. It is
* dropped by some other mechanism.
* Vanilla Minecraft doesn't always drop equipment when the drop chance is 1.0
* (or more). Try to work around that by moving the equipment into the drops
* if it is not already there.
*
* In Bukkit versions prior to 1.7.9, the equipment was not part of the drops
* list in the EntityDeathEvent. Bukkit fixed that issue with the API, but had
* to retain vanilla's handling of drop probabilities, which is still faulty.
*
* This handler will process any entity death, but naturally spawned monsters
* probably won't have a (near) 1.0 drop chance for the their equipment, and
Expand All @@ -182,39 +186,61 @@ public void onBlockPlace(BlockPlaceEvent event)
@EventHandler(ignoreCancelled = true)
public void onEntityDeath(EntityDeathEvent event)
{
final float NEAR_UNITY = 0.999f;
boolean forcedDrops = false;
if (event.getEntity() instanceof Creature)
{
EntityEquipment equipment = event.getEntity().getEquipment();
if (equipment.getHelmetDropChance() > 0.999f)
List<ItemStack> drops = event.getDrops();
if (equipment.getHelmetDropChance() > NEAR_UNITY)
{
event.getDrops().add(equipment.getHelmet());
equipment.setHelmet(null);
forcedDrops = true;
ItemStack helmet = equipment.getHelmet();
if (helmet != null && !drops.contains(helmet))
{
drops.add(helmet);
equipment.setHelmet(null);
}
}
if (equipment.getChestplateDropChance() > 0.999f)
if (equipment.getChestplateDropChance() > NEAR_UNITY)
{
event.getDrops().add(equipment.getChestplate());
equipment.setChestplate(null);
forcedDrops = true;
ItemStack chestplate = equipment.getChestplate();
if (chestplate != null && !drops.contains(chestplate))
{
drops.add(chestplate);
equipment.setChestplate(null);
}
}
if (equipment.getLeggingsDropChance() > 0.999f)
if (equipment.getLeggingsDropChance() > NEAR_UNITY)
{
event.getDrops().add(equipment.getLeggings());
equipment.setLeggings(null);
forcedDrops = true;
ItemStack leggings = equipment.getLeggings();
if (leggings != null && !drops.contains(leggings))
{
drops.add(leggings);
equipment.setLeggings(null);
}
}
if (equipment.getBootsDropChance() > 0.999f)
if (equipment.getBootsDropChance() > NEAR_UNITY)
{
event.getDrops().add(equipment.getBoots());
equipment.setBoots(null);
forcedDrops = true;
ItemStack boots = equipment.getBoots();
if (boots != null && !drops.contains(boots))
{
drops.add(boots);
equipment.setBoots(null);
}
}
if (equipment.getItemInHandDropChance() > 0.999f)
if (equipment.getItemInHandDropChance() > NEAR_UNITY)
{
event.getDrops().add(equipment.getItemInHand());
equipment.setItemInHand(null);
forcedDrops = true;
ItemStack itemInHand = equipment.getItemInHand();
if (itemInHand != null && !drops.contains(itemInHand))
{
drops.add(itemInHand);
equipment.setItemInHand(null);
}
}
}

Expand Down

0 comments on commit 2f358f2

Please sign in to comment.