Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BlockDropItemEvent #7075

Merged
merged 20 commits into from
Oct 13, 2024
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions src/main/java/ch/njol/skript/classes/data/BukkitEventValues.java
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
import org.bukkit.block.BlockFace;
import org.bukkit.block.BlockState;
import org.bukkit.block.data.BlockData;
import org.bukkit.event.block.BlockDropItemEvent;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.AbstractVillager;
import org.bukkit.entity.AreaEffectCloud;
Expand Down Expand Up @@ -1935,5 +1936,31 @@ public RegainReason get(EntityRegainHealthEvent event) {
return event.getRegainReason();
}
}, EventValues.TIME_NOW);

// BlockDropItemEvent
EventValues.registerEventValue(BlockDropItemEvent.class, Block.class, new Getter<Block, BlockDropItemEvent>() {
@Override
public @Nullable Block get(BlockDropItemEvent event) {
return new BlockStateBlock(event.getBlockState());
}
TheAbsolutionism marked this conversation as resolved.
Show resolved Hide resolved
}, EventValues.TIME_PAST);
EventValues.registerEventValue(BlockDropItemEvent.class, Player.class, new Getter<Player, BlockDropItemEvent>() {
@Override
public @Nullable Player get(BlockDropItemEvent event) {
return event.getPlayer();
}
}, EventValues.TIME_NOW);
EventValues.registerEventValue(BlockDropItemEvent.class, ItemStack[].class, new Getter<ItemStack[], BlockDropItemEvent>() {
@Override
public @Nullable ItemStack[] get(BlockDropItemEvent event) {
return event.getItems().stream().map(Item::getItemStack).toArray(ItemStack[]::new);
}
}, EventValues.TIME_NOW);
EventValues.registerEventValue(BlockDropItemEvent.class, Entity[].class, new Getter<Entity[], BlockDropItemEvent>() {
@Override
public @Nullable Entity[] get(BlockDropItemEvent event) {
return event.getItems().toArray(Entity[]::new);
}
TheAbsolutionism marked this conversation as resolved.
Show resolved Hide resolved
}, EventValues.TIME_NOW);
}
}
48 changes: 30 additions & 18 deletions src/main/java/ch/njol/skript/events/EvtBlock.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,7 @@
import org.bukkit.block.BlockState;
import org.bukkit.block.data.BlockData;
import org.bukkit.event.Event;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockBurnEvent;
import org.bukkit.event.block.BlockEvent;
import org.bukkit.event.block.BlockFadeEvent;
import org.bukkit.event.block.BlockFormEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.block.*;
import org.bukkit.event.hanging.HangingBreakEvent;
import org.bukkit.event.hanging.HangingEvent;
import org.bukkit.event.hanging.HangingPlaceEvent;
Expand All @@ -37,6 +32,7 @@

import ch.njol.skript.Skript;
import ch.njol.skript.aliases.ItemType;
import org.jetbrains.annotations.NotNull;
import org.skriptlang.skript.lang.comparator.Relation;
import ch.njol.skript.classes.data.DefaultComparators;
import ch.njol.skript.entity.EntityData;
Expand Down Expand Up @@ -74,6 +70,22 @@ public class EvtBlock extends SkriptEvent {
.description("Called when a block is created, but not by a player, e.g. snow forms due to snowfall, water freezes in cold biomes. This isn't called when block spreads (mushroom growth, water physics etc.), as it has its own event (see <a href='#spread'>spread event</a>).")
.examples("on form of snow:", "on form of a mushroom:")
.since("1.0, 2.6 (BlockData support)");
Skript.registerEvent("Block Drop", EvtBlock.class, BlockDropItemEvent.class, "block drop[ping] [[of] %-itemtypes/blockdatas%]")
.description(
"Called when a block broken by a player drops items",
TheAbsolutionism marked this conversation as resolved.
Show resolved Hide resolved
"<ul>",
"<li>event-player : The player that broke the block</li>",
"<li>past event-block : The block that was broken</li>",
"<li>event-block : The block after being broken</li>",
"<li>event-items (or drops) : The drops of the block</li>",
"<li>event-entities : The entities of the dropped items</li>",
TheAbsolutionism marked this conversation as resolved.
Show resolved Hide resolved
"</ul>",
TheAbsolutionism marked this conversation as resolved.
Show resolved Hide resolved
"",
"If the breaking of the block leads to others being broken, such as torches, they will appear",
TheAbsolutionism marked this conversation as resolved.
Show resolved Hide resolved
"in \"event-items\" and \"event-entities\"."
)
.examples("on block drop:", "on block drop of oak log:")
TheAbsolutionism marked this conversation as resolved.
Show resolved Hide resolved
.since("INSERT VERSION");
}

@Nullable
Expand Down Expand Up @@ -101,26 +113,26 @@ public boolean check(final Event event) {
ItemType item;
BlockData blockData = null;

if (event instanceof BlockFormEvent) {
BlockFormEvent blockFormEvent = (BlockFormEvent) event;
if (event instanceof BlockFormEvent blockFormEvent) {
BlockState newState = blockFormEvent.getNewState();
item = new ItemType(newState.getBlockData());
blockData = newState.getBlockData();
} else if (event instanceof BlockEvent) {
BlockEvent blockEvent = (BlockEvent) event;
} else if (event instanceof BlockDropItemEvent blockDropItemEvent) {
Block block = blockDropItemEvent.getBlock();
item = new ItemType(block);
blockData = block.getBlockData();
} else if (event instanceof BlockEvent blockEvent) {
Block block = blockEvent.getBlock();
item = new ItemType(block);
blockData = block.getBlockData();
} else if (event instanceof PlayerBucketFillEvent) {
PlayerBucketFillEvent playerBucketFillEvent = ((PlayerBucketFillEvent) event);
} else if (event instanceof PlayerBucketFillEvent playerBucketFillEvent) {
Block block = playerBucketFillEvent.getBlockClicked();
item = new ItemType(block);
blockData = block.getBlockData();
} else if (event instanceof PlayerBucketEmptyEvent) {
PlayerBucketEmptyEvent playerBucketEmptyEvent = ((PlayerBucketEmptyEvent) event);
} else if (event instanceof PlayerBucketEmptyEvent playerBucketEmptyEvent) {
item = new ItemType(playerBucketEmptyEvent.getItemStack());
} else if (event instanceof HangingEvent) {
final EntityData<?> d = EntityData.fromEntity(((HangingEvent) event).getEntity());
} else if (event instanceof HangingEvent hangingEvent) {
final EntityData<?> d = EntityData.fromEntity((hangingEvent.getEntity()));
return types.check(event, o -> {
if (o instanceof ItemType)
return Relation.EQUAL.isImpliedBy(DefaultComparators.entityItemComparator.compare(d, ((ItemType) o)));
Expand All @@ -144,8 +156,8 @@ else if (o instanceof BlockData && finalBlockData != null)
}

@Override
public String toString(final @Nullable Event e, final boolean debug) {
return "break/place/burn/fade/form of " + Classes.toString(types);
public @NotNull String toString(@Nullable Event event, boolean debug) {
TheAbsolutionism marked this conversation as resolved.
Show resolved Hide resolved
return "break/place/burn/fade/form/drop of " + Classes.toString(types);
}

}
61 changes: 39 additions & 22 deletions src/main/java/ch/njol/skript/expressions/ExprDrops.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@
import ch.njol.skript.util.Experience;
import ch.njol.util.Kleenean;
import ch.njol.util.coll.CollectionUtils;
import org.bukkit.entity.Item;
import org.bukkit.event.Event;
import org.bukkit.event.block.BlockDropItemEvent;
import org.bukkit.event.block.BlockEvent;
import org.bukkit.event.entity.EntityDeathEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
Expand All @@ -61,28 +64,32 @@ public class ExprDrops extends SimpleExpression<ItemType> {

@Override
public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) {
if (!getParser().isCurrentEvent(EntityDeathEvent.class)) {
Skript.error("The expression 'drops' can only be used in death events", ErrorQuality.SEMANTIC_ERROR);
if (!getParser().isCurrentEvent(EntityDeathEvent.class, BlockDropItemEvent.class)) {
Skript.error("The expression 'drops' can only be used in death events and block drop events", ErrorQuality.SEMANTIC_ERROR);
TheAbsolutionism marked this conversation as resolved.
Show resolved Hide resolved
return false;
}
return true;
}

@Override
@Nullable
protected ItemType[] get(Event e) {
if (!(e instanceof EntityDeathEvent))
return null;

return ((EntityDeathEvent) e).getDrops()
.stream()
.map(ItemType::new)
.toArray(ItemType[]::new);
protected @Nullable ItemType[] get(Event event) {
TheAbsolutionism marked this conversation as resolved.
Show resolved Hide resolved
if (event instanceof EntityDeathEvent entityDeathEvent) {
return entityDeathEvent.getDrops()
.stream()
.map(ItemType::new)
.toArray(ItemType[]::new);
} else if (event instanceof BlockDropItemEvent blockDropItemEvent) {
return blockDropItemEvent.getItems()
.stream()
.map(Item::getItemStack)
.map(ItemType::new)
.toArray(ItemType[]::new);
}
TheAbsolutionism marked this conversation as resolved.
Show resolved Hide resolved
return new ItemType[0];
}

@Override
@Nullable
public Class<?>[] acceptChange(ChangeMode mode) {
public Class<?> @Nullable [] acceptChange(ChangeMode mode) {
if (getParser().getHasDelayBefore().isTrue()) {
Skript.error("Can't change the drops after the event has already passed");
return null;
Expand All @@ -101,12 +108,22 @@ public Class<?>[] acceptChange(ChangeMode mode) {
}

@Override
public void change(Event event, @Nullable Object[] delta, ChangeMode mode) {
if (!(event instanceof EntityDeathEvent))
public void change(Event event, Object @Nullable [] delta, ChangeMode mode) {

TheAbsolutionism marked this conversation as resolved.
Show resolved Hide resolved
List<ItemStack> drops = null;
int originalExperience = 0;
if (event instanceof EntityDeathEvent entityDeathEvent) {
drops = entityDeathEvent.getDrops();
originalExperience = entityDeathEvent.getDroppedExp();
} else if (event instanceof BlockDropItemEvent blockDropItemEvent) {
drops = blockDropItemEvent.getItems()
.stream()
.map(Item::getItemStack)
.toList();
} else {
return;
}

List<ItemStack> drops = ((EntityDeathEvent) event).getDrops();
int originalExperience = ((EntityDeathEvent) event).getDroppedExp();
assert delta != null;

// separate the delta into experience and drops to make it easier to handle
Expand Down Expand Up @@ -144,20 +161,20 @@ public void change(Event event, @Nullable Object[] delta, ChangeMode mode) {
// todo: All the experience stuff should be removed from this class for 2.8 and given to ExprExperience

// handle experience
if (deltaExperience > -1) {
if (deltaExperience > -1 && event instanceof EntityDeathEvent entityDeathEvent) {
switch (mode) {
TheAbsolutionism marked this conversation as resolved.
Show resolved Hide resolved
case SET:
((EntityDeathEvent) event).setDroppedExp(deltaExperience);
entityDeathEvent.setDroppedExp(deltaExperience);
break;
case ADD:
((EntityDeathEvent) event).setDroppedExp(originalExperience + deltaExperience);
entityDeathEvent.setDroppedExp(originalExperience + deltaExperience);
break;
case REMOVE:
((EntityDeathEvent) event).setDroppedExp(originalExperience - deltaExperience);
entityDeathEvent.setDroppedExp(originalExperience - deltaExperience);
// fallthrough to check for removeAllExperience
case REMOVE_ALL:
if (removeAllExperience)
((EntityDeathEvent) event).setDroppedExp(0);
entityDeathEvent.setDroppedExp(0);
break;
case DELETE:
case RESET:
Expand Down