Skip to content

Commit

Permalink
Add fix_drop_chance_bug configuration option.
Browse files Browse the repository at this point in the history
This setting (default false) enables special handling of
mob drops with near-unity (> 0.999) drop chance; on mob
death, they are taken from the mob inventory and added to
the drops collection, bypassing vanilla/Spigot/PaperSpigot
drop code which has been buggy in the past. See:
https://hub.spigotmc.org/jira/browse/SPIGOT-5298

Unfortunately, in fixing a bug in skull comparison
(https://hub.spigotmc.org/jira/browse/SPIGOT-5403:
ItemStack.isSimilar() returned true for different skulls),
Spigot managed to introduce the opposite bug: isSimilar()
returning false for identical skulls. That breaks this
drop chance bug fix. That new Spigot bug persisted for
a few days after Dec 6, 2019, before it was fixed by the
Spigot project. During that small window, the PaperSpigot
project pulled the buggy Spigot code and consequently
ItemStack.isSimilar() is wrong for skulls in PaperSpigot
builds 234 through 243. PaperSpigot has ceased development
of 1.14.4 builds, meaning that the last ten PaperSpigot
builds for 1.14.4 are not useable with this option enabled.
  • Loading branch information
totemo committed Feb 24, 2020
1 parent 658ebb9 commit cf194b9
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 6 deletions.
2 changes: 2 additions & 0 deletions config.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
allow_arbitrary_names: false
warn_on_invalid_name: false
fix_drop_chance_bug: false

shapes:

Expand Down
34 changes: 34 additions & 0 deletions src/io/github/totemo/doppelganger/Configuration.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ public void load() {
_creatureFactory.load(_plugin.getConfig(), _plugin.getLogger());
_arbitraryNameAllowed = _plugin.getConfig().getBoolean("allow_arbitrary_names", false);
_warnOnInvalidName = _plugin.getConfig().getBoolean("warn_on_invalid_name", false);
_fixDropChanceBug = _plugin.getConfig().getBoolean("fix_drop_chance_bug", false);
}

// ------------------------------------------------------------------------
Expand All @@ -58,6 +59,32 @@ public boolean warnOnInvalidName() {
return _warnOnInvalidName;
}

// ------------------------------------------------------------------------
/**
* If true, when a mob dies and the drop chance of some piece of its
* equipment is greater than 0.999, force that item to drop; don't rely on
* vanilla code, Spigot or PaperSpigot getting it right.
*
* See: {@link https://hub.spigotmc.org/jira/browse/SPIGOT-5298}
*
* Unfortunately, the fix can go wrong because of a Spigot bug where
* identical (stackable) skulls are treated as dissimilar, so allow the fix
* to be disabled by configuration.
*
* See: {@link https://hub.spigotmc.org/jira/browse/SPIGOT-5403)}
*
* The PaperSpigot project managed to pull the botched resolution of
* SPIGOT-5403 at just the right time to enshrine the buggy behaviour in
* last 10 PaperSpigot builds for 1.14.4. PaperSpigot builds 234-243 for
* 1.14.4 are bad. Use build 233 or disable the fix.
*
* @return true if a drop chance of 0.999 or greater should force a drop by
* bypassing vanilla/Spigot/PaperSpigot code.
*/
public boolean fixDropChanceBug() {
return _fixDropChanceBug;
}

// ------------------------------------------------------------------------
/**
* Reference to the plugin instance.
Expand All @@ -81,4 +108,11 @@ public boolean warnOnInvalidName() {
* placing is not allowed.
*/
protected boolean _warnOnInvalidName;

/**
* If true, when a mob dies and the drop chance of some piece of its
* equipment is greater than 0.999, force that item to drop; don't rely on
* Spigot getting it right.
*/
protected boolean _fixDropChanceBug;
} // class Configuration
13 changes: 7 additions & 6 deletions src/io/github/totemo/doppelganger/Doppelganger.java
Original file line number Diff line number Diff line change
Expand Up @@ -168,45 +168,46 @@ public void onBlockPlace(BlockPlaceEvent event) {
public void onEntityDeath(EntityDeathEvent event) {
final float NEAR_UNITY = 0.999f;
boolean forcedDrops = false;
boolean fixDropChanceBug = getConfiguration().fixDropChanceBug();
if (event.getEntity() instanceof Creature) {
EntityEquipment equipment = event.getEntity().getEquipment();
List<ItemStack> drops = event.getDrops();
if (equipment.getHelmetDropChance() > NEAR_UNITY) {
forcedDrops = true;
ItemStack helmet = equipment.getHelmet();
if (helmet != null && !drops.contains(helmet)) {
if (fixDropChanceBug && helmet != null && !drops.contains(helmet)) {
drops.add(helmet);
equipment.setHelmet(null);
}
}
if (equipment.getChestplateDropChance() > NEAR_UNITY) {
forcedDrops = true;
ItemStack chestplate = equipment.getChestplate();
if (chestplate != null && !drops.contains(chestplate)) {
if (fixDropChanceBug && chestplate != null && !drops.contains(chestplate)) {
drops.add(chestplate);
equipment.setChestplate(null);
}
}
if (equipment.getLeggingsDropChance() > NEAR_UNITY) {
forcedDrops = true;
ItemStack leggings = equipment.getLeggings();
if (leggings != null && !drops.contains(leggings)) {
if (fixDropChanceBug && leggings != null && !drops.contains(leggings)) {
drops.add(leggings);
equipment.setLeggings(null);
}
}
if (equipment.getBootsDropChance() > NEAR_UNITY) {
forcedDrops = true;
ItemStack boots = equipment.getBoots();
if (boots != null && !drops.contains(boots)) {
if (fixDropChanceBug && boots != null && !drops.contains(boots)) {
drops.add(boots);
equipment.setBoots(null);
}
}
if (equipment.getItemInHandDropChance() > NEAR_UNITY) {
if (equipment.getItemInMainHandDropChance() > NEAR_UNITY) {
forcedDrops = true;
ItemStack itemInHand = equipment.getItemInMainHand();
if (itemInHand != null && !drops.contains(itemInHand)) {
if (fixDropChanceBug && itemInHand != null && !drops.contains(itemInHand)) {
drops.add(itemInHand);
equipment.setItemInMainHand(null);
}
Expand Down

0 comments on commit cf194b9

Please sign in to comment.