Bukkit/CraftBukkit — pull request #1099 by EdGruberman (2013-03-26 05:33:09+00:00)
Title: Edgruberman/itemmerge

##### The Issue:
Minecraft 1.3 added a feature to automatically merge items close to each other. This event signals listening plugins when this occurs and allows for cancellation of the event if desired.

##### Justification for this PR:
The ability to cancel an item merge creates many new possibilities for entity item management. A single use case example is an item shop plugin that has an entity item on display to demonstrate what is available and then when an entity item is made available for pick up, it is made close to the display item but no merging should occur.

##### PR Breakdown:
Whenever the server normally detects two item entities in close proximity, it will assess if they are compatible enough to merge. If they pass the checks, they are merged. This PR changes this procedure to call ItemMergeEvent if the compatibility checks pass. Because the entities involved are mutable, after event processing completes, the two item entities are again passed through the compatibility checks to verify any changes made to them are still compatible. If they are still compatible, the items are merged. If they are no longer compatible, the items are not merged and the process is simple existed which allows the server to again initialize a merge assessment later as normal.

If this event is cancelled and the entity items remain in close proximity, the server will continually attempt to merge the items periodically as normal.

##### Testing Results and Materials:
[Test Plugin Source](https://github.com/EdGruberman/bukkit-test/blob/master/BUKKIT-1959/src/edgruberman/bukkit/bukkit_1959/Main.java) | [Compiled Test Plugin](https://github.com/EdGruberman/bukkit-test/blob/master/BUKKIT-1959/dist/BUKKIT-1959.jar?raw=true) | [Compiled CraftBukkit](http://mc.rjump.com/personal/EdGruberman/Bukkit/BUKKIT-1959/craftbukkit-1.5.1-R0.1-SNAPSHOT.jar)

I created a test plugin that logs all ItemMergeEvent occurrences and their results. It allows for configuration of cancellation or not and to set the entity or other ItemStack during the event processing. I ran through a variety of random tests that included:

max material size, over, under, equals
max stack size, over, under, equals
no meta, no data
no meta, same data
no meta, diff data
same meta, no data
same meta, same data
same meta, diff data
diff meta, no data
diff meta, same data
diff meta, diff data

All outcomes were as expected, including event cancellations.

##### Relevant PR(s):
https://github.com/Bukkit/Bukkit/pull/826 - API this implementation depends on

Alternate Solution: https://github.com/Bukkit/Bukkit/issues/759, https://github.com/Bukkit/CraftBukkit/pull/1001
The above solution is an alternate proposal for this same event and ticket, however that implementation is lacking in a few ways still. It makes needless copies of the involved entities and does not handle the situation where the two items are mutated beyond what the compatibility tests originally checked for. That solution also appears to be untested and it is not even clear that it works as expected.

##### JIRA Ticket:

[BUKKIT-1959](https://bukkit.atlassian.net/browse/BUKKIT-1959)

##### Pull Request Check List:

**General:**

- [x] Fits Bukkit's Goals
- [x] Leaky Ticket Ready
- [x] Code Meets Requirements
- [x] Code is Documented
- [x] Code Addresses Leaky Ticket
- [x] Followed Pull Request Format
- [x] Tested Code
- [x] Included Test Material and Source
- [x] Follows Minimal Diff Policy
- [x] Uses Proper CraftBukkit Comments
- [x] Imports Are Ordered, Separated and Organised Properly