Skip to content

Commit

Permalink
feat(trigger): drop item when isn't block
Browse files Browse the repository at this point in the history
Signed-off-by: SettingDust <settingdust@gmail.com>
  • Loading branch information
SettingDust committed Jun 5, 2022
1 parent 0d199c2 commit f155c90
Show file tree
Hide file tree
Showing 17 changed files with 142 additions and 182 deletions.
36 changes: 14 additions & 22 deletions src/main/java/team/ebi/epicbanitem/EBICommands.java
Expand Up @@ -16,8 +16,6 @@
import org.spongepowered.api.ResourceKey;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.block.BlockSnapshot;
import org.spongepowered.api.block.BlockState;
import org.spongepowered.api.block.BlockType;
import org.spongepowered.api.block.entity.carrier.CarrierBlockEntity;
import org.spongepowered.api.command.Command;
import org.spongepowered.api.command.CommandResult;
Expand Down Expand Up @@ -62,6 +60,7 @@
import team.ebi.epicbanitem.api.trigger.RestrictionTriggers;
import team.ebi.epicbanitem.expression.RootQueryExpression;
import team.ebi.epicbanitem.rule.RestrictionRuleImpl;
import team.ebi.epicbanitem.util.ItemUtils;
import team.ebi.epicbanitem.util.RestrictionRuleRenderer;
import team.ebi.epicbanitem.util.command.Flags;
import team.ebi.epicbanitem.util.command.Parameters;
Expand Down Expand Up @@ -517,11 +516,11 @@ public final class EBICommands {
if (!(context.cause().root() instanceof final Player player)) {
return CommandResult.error(NEED_PLAYER);
}
boolean isBlock = context.hasFlag("block");
final var isBlock = context.hasFlag("block");
UUID uuid = player.identity().uuid();
// Last > Empty
var queryExpression = Objects.requireNonNull(usedQuery.get(uuid, it -> new RootQueryExpression()));
var updateExpression = context.requireOne(keys.update);
final var queryExpression = Objects.requireNonNull(usedQuery.get(uuid, it -> new RootQueryExpression()));
final var updateExpression = context.requireOne(keys.update);
ItemStack targetObject;
EquipmentType hand = null;
BlockSnapshot block = null;
Expand All @@ -532,31 +531,24 @@ public final class EBICommands {
hand = heldHand(player).orElseThrow(() -> new CommandException(NEED_ITEM));
targetObject = equipped(player, hand).orElseThrow(() -> new CommandException(NEED_ITEM));
}
var container = targetObject.toContainer();
var cleaned = ExpressionService.cleanup(container);
var result = queryExpression.query(cleaned).orElse(QueryResult.success());
var operation = updateExpression.update(result, cleaned);
var processed = operation.process(cleaned);
final var container = targetObject.toContainer();
final var cleaned = ExpressionService.cleanup(container);
final var result = queryExpression.query(cleaned).orElse(QueryResult.success());
final var operation = updateExpression.update(result, cleaned);
final var processed = operation.process(cleaned);
processed.values(false).forEach((query, o) -> {
container.remove(query);
container.set(query, o);
});
var dataManager = Sponge.dataManager();
var deserialized = dataManager.deserialize(ItemStack.class, container).orElseThrow();
final var dataManager = Sponge.dataManager();
final var deserialized =
dataManager.deserialize(ItemStack.class, container).orElseThrow();
if (deserialized.quantity() > deserialized.maxStackQuantity()) {
deserialized.setQuantity(deserialized.maxStackQuantity());
}
if (isBlock) {
BlockType blockType = deserialized.type().block().orElseThrow();
BlockState oldState = block.state();
BlockState newState = BlockState.builder()
.blockType(blockType)
.addFrom(blockType.defaultState())
.addFrom(oldState)
.build();
BlockSnapshot newSnapshot =
BlockSnapshot.builder().from(block).blockState(newState).build();
newSnapshot.restore(true, BlockChangeFlags.DEFAULT_PLACEMENT);
ItemUtils.toBlock(deserialized.createSnapshot(), block.location().get(), block.state())
.ifPresent(it -> it.restore(true, BlockChangeFlags.DEFAULT_PLACEMENT));
} else {
player.equip(hand, deserialized);
}
Expand Down
Expand Up @@ -14,12 +14,12 @@
import org.spongepowered.api.ResourceKey;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.block.BlockSnapshot;
import org.spongepowered.api.data.persistence.DataSerializable;
import org.spongepowered.api.data.persistence.DataView;
import org.spongepowered.api.data.type.HandType;
import org.spongepowered.api.entity.living.player.server.ServerPlayer;
import org.spongepowered.api.event.Event;
import org.spongepowered.api.item.inventory.Equipable;
import org.spongepowered.api.item.inventory.ItemStack;
import org.spongepowered.api.item.inventory.ItemStackSnapshot;
import org.spongepowered.api.item.inventory.Slot;
import org.spongepowered.api.item.inventory.equipment.EquipmentType;
Expand Down Expand Up @@ -69,52 +69,46 @@ public Component description() {
return Component.translatable(EpicBanItem.NAMESPACE + ".trigger." + key() + ".description");
}

protected Optional<BlockSnapshot> processCancellable(
protected Optional<ItemStackSnapshot> processBlockCancellable(
final Event event,
final ServerWorld world,
final @Nullable Subject subject,
final @Nullable Audience audience,
final BlockSnapshot block) {
return this.processCancellable(
return this.processBlockCancellable(
event, world, subject, audience, block, ProcessHandler.CancellableHandler.CANCEL_EVENT);
}

protected Optional<ItemStackSnapshot> processCancellable(
protected Optional<ItemStackSnapshot> processItemCancellable(
final Event event,
final ServerWorld world,
final @Nullable Subject subject,
final @Nullable Audience audience,
final ItemStackSnapshot item) {
return this.processCancellable(
return this.processItemCancellable(
event, world, subject, audience, item, ProcessHandler.CancellableHandler.CANCEL_EVENT);
}

protected Optional<BlockSnapshot> processCancellable(
protected Optional<ItemStackSnapshot> processBlockCancellable(
final Event event,
final ServerWorld world,
final @Nullable Subject subject,
final @Nullable Audience audience,
final BlockSnapshot block,
final ProcessHandler.CancellableHandler cancellable) {
return this.process(
event,
world,
subject,
audience,
block,
Objects.isNull(audience)
? new ProcessHandler.Block.Cancellable(cancellable)
: new ProcessHandler.Block.MessageCancellable(block, this, cancellable));
return ItemUtils.fromBlock(block)
.map(ItemStack::createSnapshot)
.flatMap(it -> this.processItemCancellable(event, world, subject, audience, it, cancellable));
}

protected Optional<ItemStackSnapshot> processCancellable(
protected Optional<ItemStackSnapshot> processItemCancellable(
final Event event,
final ServerWorld world,
final @Nullable Subject subject,
final @Nullable Audience audience,
final ItemStackSnapshot item,
final ProcessHandler.CancellableHandler cancellable) {
return this.process(
return this.processItem(
event,
world,
subject,
Expand All @@ -125,30 +119,13 @@ protected Optional<ItemStackSnapshot> processCancellable(
: new ProcessHandler.Item.MessageCancellable(item, this, cancellable));
}

protected Optional<BlockSnapshot> process(
final Event event,
final ServerWorld world,
final @Nullable Subject subject,
final @Nullable Audience audience,
final BlockSnapshot block) {
return this.process(
event,
world,
subject,
audience,
block,
Objects.isNull(audience)
? new ProcessHandler.Block.Impl()
: new ProcessHandler.Block.Message(block, this));
}

protected Optional<ItemStackSnapshot> process(
protected Optional<ItemStackSnapshot> processItem(
final Event event,
final ServerWorld world,
final @Nullable Subject subject,
final @Nullable Audience audience,
final ItemStackSnapshot item) {
return this.process(
return this.processItem(
event,
world,
subject,
Expand All @@ -159,43 +136,19 @@ protected Optional<ItemStackSnapshot> process(
: new ProcessHandler.Item.Message(item, this));
}

protected Optional<BlockSnapshot> process(
final Event event,
final ServerWorld world,
final @Nullable Subject subject,
final @Nullable Audience audience,
final BlockSnapshot block,
final ProcessHandler.Block handler) {
final var processed = this.process(event, world, subject, block, handler);
if (Objects.nonNull(audience) && handler instanceof ProcessHandler.Message message) message.sendTo(audience);
return processed;
}

protected Optional<ItemStackSnapshot> process(
protected Optional<ItemStackSnapshot> processItem(
final Event event,
final ServerWorld world,
final @Nullable Subject subject,
final @Nullable Audience audience,
final ItemStackSnapshot item,
final ProcessHandler.Item handler) {
final var processed = this.process(event, world, subject, item, handler);
final var processed = this.processItem(event, world, subject, item, handler);
if (Objects.nonNull(audience) && handler instanceof ProcessHandler.Message message) message.sendTo(audience);
return processed;
}

protected Optional<BlockSnapshot> process(
final Event event,
final ServerWorld world,
final @Nullable Subject subject,
final BlockSnapshot block,
final ProcessHandler.Block handler) {
return ItemUtils.fromBlock(block)
.map(DataSerializable::toContainer)
.flatMap(view -> this.process(
event, world, subject, block.state().type().key(RegistryTypes.BLOCK_TYPE), view, handler));
}

protected Optional<ItemStackSnapshot> process(
protected Optional<ItemStackSnapshot> processItem(
final Event event,
final ServerWorld world,
final @Nullable Subject subject,
Expand All @@ -205,16 +158,6 @@ protected Optional<ItemStackSnapshot> process(
event, world, subject, item.type().key(RegistryTypes.ITEM_TYPE), item.toContainer(), handler);
}

protected <T> Optional<T> process(
final Event event,
final ServerWorld world,
final @Nullable Subject subject,
final ResourceKey objectType,
final DataView view,
final ProcessHandler.Message<T> handler) {
return this.process(event, world, subject, objectType, view, (ProcessHandler<T>) handler);
}

protected <T> Optional<T> process(
final Event event,
final ServerWorld world,
Expand Down
56 changes: 0 additions & 56 deletions src/main/java/team/ebi/epicbanitem/api/trigger/ProcessHandler.java
Expand Up @@ -9,8 +9,6 @@
import java.util.Optional;

import org.spongepowered.api.Sponge;
import org.spongepowered.api.block.BlockSnapshot;
import org.spongepowered.api.block.BlockState;
import org.spongepowered.api.data.persistence.DataView;
import org.spongepowered.api.event.Cancellable;
import org.spongepowered.api.event.Event;
Expand Down Expand Up @@ -88,60 +86,6 @@ public void cancel(Event event) {
}
}

interface Block extends ProcessHandler<BlockSnapshot> {
@Override
default Optional<BlockSnapshot> translate(DataView view) {
return Sponge.dataManager()
.deserialize(ItemStackSnapshot.class, view)
.map(item -> BlockSnapshot.builder()
.blockState(BlockState.builder()
.blockType(item.type().block().orElseThrow())
.build())
.build());
}

class Impl implements Block {}

class Cancellable implements CancellableHandler, Block {
private final CancellableHandler handler;

public Cancellable(CancellableHandler handler) {
this.handler = handler;
}

@Override
public void cancel(Event event) {
handler.cancel(event);
}
}

class Message extends ProcessHandler.Message<BlockSnapshot> implements Block {
public Message(BlockSnapshot originObject, RestrictionTrigger trigger) {
super(originObject, trigger);
}

@Override
protected ComponentLike component(BlockSnapshot obj) {
return obj.state().type();
}
}

class MessageCancellable extends Message implements Block, CancellableHandler {
private final CancellableHandler handler;

public MessageCancellable(
BlockSnapshot originObject, RestrictionTrigger trigger, ProcessHandler.CancellableHandler handler) {
super(originObject, trigger);
this.handler = handler;
}

@Override
public void cancel(Event event) {
handler.cancel(event);
}
}
}

abstract class Message<T> implements ProcessHandler<T>, ComponentLike {
protected final ComponentLike originComponent;
protected final RestrictionTrigger trigger;
Expand Down
Expand Up @@ -52,7 +52,7 @@ public void onChangeEntityEquipment(
if (item.isEmpty()) return;
// TODO Use click rewrite
final var cancelled = new AtomicBoolean(false);
final var processed = this.processCancellable(
final var processed = this.processItemCancellable(
event,
entity.serverLocation().world(),
cause.first(Subject.class).orElse(null),
Expand Down
Expand Up @@ -6,16 +6,21 @@
package team.ebi.epicbanitem.trigger;

import org.spongepowered.api.block.BlockSnapshot;
import org.spongepowered.api.data.Keys;
import org.spongepowered.api.data.value.Value;
import org.spongepowered.api.entity.EntityTypes;
import org.spongepowered.api.event.Listener;
import org.spongepowered.api.event.block.InteractBlockEvent;
import org.spongepowered.api.event.filter.Getter;
import org.spongepowered.api.event.filter.type.Include;
import org.spongepowered.api.service.permission.Subject;
import org.spongepowered.api.util.Ticks;
import org.spongepowered.api.world.BlockChangeFlags;
import org.spongepowered.api.world.server.ServerLocation;

import net.kyori.adventure.audience.Audience;
import team.ebi.epicbanitem.EpicBanItem;
import team.ebi.epicbanitem.util.ItemUtils;

public class BeInteractedRestrictionTrigger extends EBIRestrictionTrigger {
public BeInteractedRestrictionTrigger() {
Expand All @@ -27,12 +32,21 @@ public BeInteractedRestrictionTrigger() {
public void onInteractBlock(InteractBlockEvent event, @Getter("block") BlockSnapshot block) {
// Will trigger on both hands
final var cause = event.cause();
this.processCancellable(
event,
block.location().map(ServerLocation::world).orElseThrow(),
cause.first(Subject.class).orElse(null),
cause.first(Audience.class).orElse(null),
block)
.ifPresent(it -> it.restore(true, BlockChangeFlags.NONE));
final var location = block.location().orElseThrow();
final var processed = this.processBlockCancellable(
event,
block.location().map(ServerLocation::world).orElseThrow(),
cause.first(Subject.class).orElse(null),
cause.first(Audience.class).orElse(null),
block);
if (processed.isPresent())
processed
.flatMap(it -> ItemUtils.toBlock(it, location, block.state()))
.ifPresentOrElse(it -> it.restore(true, BlockChangeFlags.NONE), () -> {
final var item = location.createEntity(EntityTypes.ITEM.get());
item.offer(Value.mutableOf(Keys.ITEM_STACK_SNAPSHOT, processed.get()));
item.offer(Value.mutableOf(Keys.PICKUP_DELAY, Ticks.of(40L)));
location.spawnEntity(item);
});
}
}

0 comments on commit f155c90

Please sign in to comment.