|
36 | 36 | import org.bukkit.event.block.BlockFromToEvent; |
37 | 37 | import org.bukkit.event.entity.EntityInteractEvent; |
38 | 38 | import org.bukkit.event.entity.EntitySpawnEvent; |
| 39 | +import org.bukkit.event.entity.ItemSpawnEvent; |
39 | 40 | import org.bukkit.event.player.PlayerBucketFillEvent; |
40 | 41 | import org.bukkit.event.player.PlayerInteractEvent; |
41 | 42 | import org.bukkit.inventory.EquipmentSlot; |
@@ -260,38 +261,61 @@ public void onBlockBreak(final PlayerBucketFillEvent e) { |
260 | 261 | } |
261 | 262 | } |
262 | 263 |
|
| 264 | + |
263 | 265 | /** |
264 | | - * Drop items at the top of the block. |
265 | | - * |
266 | | - * @param event EntitySpawnEvent object. |
| 266 | + * This handler listens for items spawning. |
| 267 | + * If an item spawns exactly at an island's center block, |
| 268 | + * it cancels the spawn and re-drops the item 1 block higher |
| 269 | + * (at the center of that block) to stack it neatly. |
267 | 270 | */ |
268 | 271 | @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) |
269 | | - public void onItemStackSpawn(EntitySpawnEvent event) { |
| 272 | + public void onItemSpawn(ItemSpawnEvent event) { |
| 273 | + // --- Guard Clauses: Exit early if conditions aren't met --- |
| 274 | + |
| 275 | + // 1. Check if the "drop on top" feature is enabled. |
270 | 276 | if (!this.addon.getSettings().isDropOnTop()) { |
271 | | - // Do nothing as item spawning is not interested in this case. |
| 277 | + // Feature is disabled, so we don't need to do anything. |
272 | 278 | return; |
273 | 279 | } |
274 | 280 |
|
275 | | - if (!EntityType.ITEM.equals(event.getEntityType())) { |
276 | | - // We are interested only in dropped item entities. |
277 | | - return; |
278 | | - } |
| 281 | + // Get the spawn location once. |
| 282 | + Location spawnLocation = event.getLocation(); |
279 | 283 |
|
280 | | - if (!this.addon.inWorld(event.getLocation().getWorld())) { |
281 | | - // Not correct world |
| 284 | + // 2. Check if the spawn is happening in a world managed by the addon. |
| 285 | + if (!this.addon.inWorld(spawnLocation.getWorld())) { |
| 286 | + // Not a relevant world, ignore this event. |
282 | 287 | return; |
283 | 288 | } |
284 | 289 |
|
285 | | - Entity entity = event.getEntity(); |
286 | | - Location location = event.getLocation(); |
287 | | - |
288 | | - Optional<Island> optionalIsland = this.addon.getIslands().getIslandAt(location) |
289 | | - .filter(island -> location.getBlock().getLocation().equals(island.getCenter())); |
| 290 | + // Find an island at the spawn location. |
| 291 | + Optional<Island> optionalIsland = this.addon.getIslands().getIslandAt(spawnLocation) |
| 292 | + // Chained to the Optional: Filter the island. |
| 293 | + // Only keep it if the block the item spawned in |
| 294 | + // is *exactly* the island's center. |
| 295 | + .filter(island -> { |
| 296 | + // .getBlock().getLocation() converts a precise location |
| 297 | + // (e.g., 10.2, 64.5, 12.8) to its block's location (10.0, 64.0, 12.0). |
| 298 | + Location blockLocation = spawnLocation.getBlock().getLocation(); |
| 299 | + return blockLocation.equals(island.getCenter()); |
| 300 | + }); |
290 | 301 |
|
| 302 | + // If we found an island AND it passed the filter (spawned at center)... |
291 | 303 | if (optionalIsland.isPresent()) { |
292 | | - // Teleport entity to the top of magic block. |
293 | | - entity.teleport(optionalIsland.get().getCenter().add(0.5, 1, 0.5)); |
294 | | - entity.setVelocity(new Vector(0, 0, 0)); |
| 304 | + // 1. Cancel the original item spawn. |
| 305 | + event.setCancelled(true); |
| 306 | + |
| 307 | + // 2. Get the island and the item stack that was supposed to spawn. |
| 308 | + Island island = optionalIsland.get(); |
| 309 | + // We use event.getEntity() which is guaranteed to be an Item. |
| 310 | + ItemStack itemStack = event.getEntity().getItemStack(); |
| 311 | + |
| 312 | + // 3. Calculate the new, clean drop location. |
| 313 | + // .add(0.5, 1, 0.5) moves it to the center of the block (0.5) |
| 314 | + // and one block up (1.0) so it sits on top. |
| 315 | + Location newDropLocation = island.getCenter().add(0.5, 1, 0.5); |
| 316 | + |
| 317 | + // 4. Drop the item stack at the new location. |
| 318 | + spawnLocation.getWorld().dropItem(newDropLocation, itemStack); |
295 | 319 | } |
296 | 320 | } |
297 | 321 |
|
|
0 commit comments