Search in sources :

Example 1 with BehaviorResult

use of org.lanternpowered.server.behavior.BehaviorResult in project LanternServer by LanternPowered.

the class OpenableDoorInteractionBehavior method tryInteract.

@Override
public BehaviorResult tryInteract(BehaviorPipeline<Behavior> pipeline, BehaviorContext context) {
    BehaviorResult result = super.tryInteract(pipeline, context);
    if (result != BehaviorResult.SUCCESS && result != BehaviorResult.CONTINUE) {
        return result;
    }
    final Location<World> location = context.requireContext(ContextKeys.BLOCK_LOCATION);
    final BlockState baseState = location.getBlock();
    final LanternDoorHalf half = baseState.get(LanternKeys.DOOR_HALF).orElse(null);
    if (half == null) {
        return result;
    }
    final Direction dir = half == LanternDoorHalf.LOWER ? Direction.UP : Direction.DOWN;
    final LanternDoorHalf other = half == LanternDoorHalf.LOWER ? LanternDoorHalf.UPPER : LanternDoorHalf.LOWER;
    final Location<World> loc = location.getBlockRelative(dir);
    BlockState otherState = loc.getBlock();
    if (otherState.get(LanternKeys.DOOR_HALF).orElse(null) == other && otherState.with(LanternKeys.DOOR_HALF, half).orElse(null) == baseState) {
        result = super.tryInteract(pipeline, context);
    }
    return result;
}
Also used : LanternDoorHalf(org.lanternpowered.server.data.type.LanternDoorHalf) BlockState(org.spongepowered.api.block.BlockState) BehaviorResult(org.lanternpowered.server.behavior.BehaviorResult) World(org.spongepowered.api.world.World) Direction(org.spongepowered.api.util.Direction)

Example 2 with BehaviorResult

use of org.lanternpowered.server.behavior.BehaviorResult in project LanternServer by LanternPowered.

the class PlayerInteractionHandler method handleHandItemInteraction.

private boolean handleHandItemInteraction(BehaviorContextImpl context, HandType handType, AbstractSlot slot, @Nullable BehaviorContext.Snapshot snapshot) {
    final Optional<HandType> activeHand = this.player.get(LanternKeys.ACTIVE_HAND).orElse(Optional.empty());
    // The player is already interacting
    if (activeHand.isPresent()) {
        return true;
    }
    final Optional<ItemStack> handItem = slot.peek();
    if (handItem.isPresent()) {
        final LanternItemType itemType = (LanternItemType) handItem.get().getType();
        context.addContext(ContextKeys.USED_ITEM_STACK, handItem.get());
        context.addContext(ContextKeys.USED_SLOT, slot);
        context.addContext(ContextKeys.INTERACTION_HAND, handType);
        context.addContext(ContextKeys.ITEM_TYPE, itemType);
        final BehaviorResult result = context.process(itemType.getPipeline().pipeline(InteractWithItemBehavior.class), (ctx, behavior) -> behavior.tryInteract(itemType.getPipeline(), ctx));
        if (result.isSuccess()) {
            return true;
        }
        if (snapshot != null) {
            context.popSnapshot(snapshot);
        }
    }
    return false;
}
Also used : InteractWithItemBehavior(org.lanternpowered.server.item.behavior.types.InteractWithItemBehavior) HandType(org.spongepowered.api.data.type.HandType) BehaviorResult(org.lanternpowered.server.behavior.BehaviorResult) LanternItemType(org.lanternpowered.server.item.LanternItemType) ItemStack(org.spongepowered.api.item.inventory.ItemStack)

Example 3 with BehaviorResult

use of org.lanternpowered.server.behavior.BehaviorResult in project LanternServer by LanternPowered.

the class InteractWithBlockItemBehavior method tryInteract.

@Override
public BehaviorResult tryInteract(BehaviorPipeline<Behavior> pipeline, BehaviorContext context) {
    final Optional<Location<World>> optLocation = context.getContext(ContextKeys.INTERACTION_LOCATION);
    if (!optLocation.isPresent()) {
        return BehaviorResult.CONTINUE;
    }
    final Direction blockFace = context.getContext(ContextKeys.INTERACTION_FACE).get();
    Location<World> location = optLocation.get();
    if (!location.getProperty(ReplaceableProperty.class).get().getValue()) {
        location = location.add(blockFace.asBlockOffset());
    }
    context.addContext(ContextKeys.BLOCK_LOCATION, location);
    final LanternBlockType blockType = (LanternBlockType) context.getContext(ContextKeys.ITEM_TYPE).get().getBlock().get();
    context.addContext(ContextKeys.BLOCK_TYPE, blockType);
    final BehaviorContext.Snapshot snapshot = context.pushSnapshot();
    // Continue processing through the placement pipeline
    final boolean success = context.process(blockType.getPipeline().pipeline(PlaceBlockBehavior.class), (context1, behavior1) -> behavior1.tryPlace(pipeline, context1)).isSuccess();
    if (success) {
        for (BlockSnapshot blockSnapshot : context.getBlockSnapshots()) {
            final Location<World> location1 = blockSnapshot.getLocation().get();
            final int buildHeight = location1.getExtent().getDimension().getBuildHeight();
            // Check if the block is placed within the building limits
            if (location1.getBlockY() >= buildHeight) {
                context.popSnapshot(snapshot);
                context.getContext(ContextKeys.PLAYER).ifPresent(player -> player.sendMessage(ChatTypes.ACTION_BAR, t("build.tooHigh", buildHeight)));
                return BehaviorResult.FAIL;
            }
        }
        context.getContext(ContextKeys.PLAYER).ifPresent(player -> {
            if (!player.get(Keys.GAME_MODE).orElse(GameModes.NOT_SET).equals(GameModes.CREATIVE)) {
                context.requireContext(ContextKeys.USED_SLOT).poll(1);
            }
        });
        return BehaviorResult.SUCCESS;
    }
    return BehaviorResult.PASS;
}
Also used : ContextKeys(org.lanternpowered.server.behavior.ContextKeys) ChatTypes(org.spongepowered.api.text.chat.ChatTypes) Location(org.spongepowered.api.world.Location) Keys(org.spongepowered.api.data.key.Keys) TranslationHelper.t(org.lanternpowered.server.text.translation.TranslationHelper.t) LanternBlockType(org.lanternpowered.server.block.LanternBlockType) BehaviorPipeline(org.lanternpowered.server.behavior.pipeline.BehaviorPipeline) Behavior(org.lanternpowered.server.behavior.Behavior) GameModes(org.spongepowered.api.entity.living.player.gamemode.GameModes) Direction(org.spongepowered.api.util.Direction) BehaviorContext(org.lanternpowered.server.behavior.BehaviorContext) InteractWithItemBehavior(org.lanternpowered.server.item.behavior.types.InteractWithItemBehavior) PlaceBlockBehavior(org.lanternpowered.server.block.behavior.types.PlaceBlockBehavior) World(org.spongepowered.api.world.World) BehaviorResult(org.lanternpowered.server.behavior.BehaviorResult) Optional(java.util.Optional) BlockSnapshot(org.spongepowered.api.block.BlockSnapshot) ReplaceableProperty(org.spongepowered.api.data.property.block.ReplaceableProperty) BlockSnapshot(org.spongepowered.api.block.BlockSnapshot) World(org.spongepowered.api.world.World) Direction(org.spongepowered.api.util.Direction) LanternBlockType(org.lanternpowered.server.block.LanternBlockType) ReplaceableProperty(org.spongepowered.api.data.property.block.ReplaceableProperty) BehaviorContext(org.lanternpowered.server.behavior.BehaviorContext) Location(org.spongepowered.api.world.Location)

Example 4 with BehaviorResult

use of org.lanternpowered.server.behavior.BehaviorResult in project LanternServer by LanternPowered.

the class SlabItemInteractionBehavior method tryInteract.

@Override
public BehaviorResult tryInteract(BehaviorPipeline<Behavior> pipeline, BehaviorContext context) {
    final Optional<Location<World>> optLocation = context.getContext(ContextKeys.INTERACTION_LOCATION);
    if (!optLocation.isPresent()) {
        return BehaviorResult.CONTINUE;
    }
    final BlockType halfSlabType = this.halfSlabType.get();
    final BlockType doubleSlabType = this.doubleSlabType.get();
    Location<World> location = optLocation.get();
    final Direction blockFace = context.getContext(ContextKeys.INTERACTION_FACE).get().getOpposite();
    final LanternBlockType blockType = (LanternBlockType) context.getContext(ContextKeys.ITEM_TYPE).get().getBlock().get();
    if (blockType != halfSlabType) {
        return BehaviorResult.PASS;
    }
    BlockState state = location.getBlock();
    final BlockState.Builder stateBuilder = BlockState.builder();
    stateBuilder.blockType(blockType);
    context.getContext(ContextKeys.USED_ITEM_STACK).ifPresent(itemStack -> itemStack.getValues().forEach(value -> stateBuilder.add((Key) value.getKey(), value.get())));
    BlockState blockState = stateBuilder.build();
    BlockSnapshotBuilder snapshotBuilder = null;
    boolean success = false;
    if (state.getType() == blockType) {
        if (state.getTraitValue(this.variantTrait).get().equals(blockState.getTraitValue(this.variantTrait).get())) {
            final PortionType portionType = state.getTraitValue(LanternEnumTraits.PORTION_TYPE).get();
            if ((blockFace == Direction.DOWN && portionType == PortionTypes.BOTTOM) || (blockFace == Direction.UP && portionType == PortionTypes.TOP)) {
                snapshotBuilder = BlockSnapshotBuilder.create().blockState(doubleSlabType.getDefaultState());
                success = true;
            }
        }
    } else if (location.getProperty(ReplaceableProperty.class).get().getValue()) {
        success = true;
    }
    if (!success) {
        location = location.add(blockFace.getOpposite().asBlockOffset());
        state = location.getBlock();
        if (state.getType() == blockType) {
            if (state.getTraitValue(this.variantTrait).get().equals(blockState.getTraitValue(this.variantTrait).get())) {
                final PortionType portionType = state.getTraitValue(LanternEnumTraits.PORTION_TYPE).get();
                if ((blockFace == Direction.DOWN && portionType == PortionTypes.TOP) || (blockFace == Direction.UP && portionType == PortionTypes.BOTTOM)) {
                    snapshotBuilder = BlockSnapshotBuilder.create().blockState(doubleSlabType.getDefaultState());
                    success = true;
                }
            }
        } else if (location.getProperty(ReplaceableProperty.class).get().getValue()) {
            success = true;
        }
    }
    if (success) {
        if (snapshotBuilder == null) {
            PortionType portionType;
            if (blockFace == Direction.UP) {
                portionType = PortionTypes.TOP;
            } else if (blockFace == Direction.DOWN) {
                portionType = PortionTypes.BOTTOM;
            } else {
                final double y = location.getY() - location.getBlockY();
                if (y >= 0.5) {
                    portionType = PortionTypes.TOP;
                } else {
                    portionType = PortionTypes.BOTTOM;
                }
            }
            snapshotBuilder = BlockSnapshotBuilder.create().blockState(halfSlabType.getDefaultState()).add(Keys.PORTION_TYPE, portionType);
        }
        final BlockSnapshotBuilder snapshotBuilder1 = snapshotBuilder;
        snapshotBuilder1.location(location);
        context.getContext(ContextKeys.USED_ITEM_STACK).ifPresent(itemStack -> itemStack.getValues().forEach(value -> snapshotBuilder1.add((Key) value.getKey(), value.get())));
        context.addBlockChange(snapshotBuilder1.build());
        context.getContext(ContextKeys.PLAYER).ifPresent(player -> {
            if (!player.get(Keys.GAME_MODE).orElse(GameModes.NOT_SET).equals(GameModes.CREATIVE)) {
                context.requireContext(ContextKeys.USED_SLOT).poll(1);
            }
        });
        return BehaviorResult.SUCCESS;
    }
    return BehaviorResult.FAIL;
}
Also used : ContextKeys(org.lanternpowered.server.behavior.ContextKeys) PortionTypes(org.spongepowered.api.data.type.PortionTypes) Location(org.spongepowered.api.world.Location) Keys(org.spongepowered.api.data.key.Keys) PortionType(org.spongepowered.api.data.type.PortionType) LanternBlockType(org.lanternpowered.server.block.LanternBlockType) BehaviorPipeline(org.lanternpowered.server.behavior.pipeline.BehaviorPipeline) EnumTrait(org.spongepowered.api.block.trait.EnumTrait) Behavior(org.lanternpowered.server.behavior.Behavior) GameModes(org.spongepowered.api.entity.living.player.gamemode.GameModes) Supplier(java.util.function.Supplier) Key(org.spongepowered.api.data.key.Key) BlockState(org.spongepowered.api.block.BlockState) Direction(org.spongepowered.api.util.Direction) BehaviorContext(org.lanternpowered.server.behavior.BehaviorContext) BlockSnapshotBuilder(org.lanternpowered.server.block.BlockSnapshotBuilder) InteractWithItemBehavior(org.lanternpowered.server.item.behavior.types.InteractWithItemBehavior) World(org.spongepowered.api.world.World) BehaviorResult(org.lanternpowered.server.behavior.BehaviorResult) BlockType(org.spongepowered.api.block.BlockType) Optional(java.util.Optional) LanternEnumTraits(org.lanternpowered.server.block.trait.LanternEnumTraits) ReplaceableProperty(org.spongepowered.api.data.property.block.ReplaceableProperty) PortionType(org.spongepowered.api.data.type.PortionType) World(org.spongepowered.api.world.World) Direction(org.spongepowered.api.util.Direction) LanternBlockType(org.lanternpowered.server.block.LanternBlockType) BlockState(org.spongepowered.api.block.BlockState) LanternBlockType(org.lanternpowered.server.block.LanternBlockType) BlockType(org.spongepowered.api.block.BlockType) ReplaceableProperty(org.spongepowered.api.data.property.block.ReplaceableProperty) Location(org.spongepowered.api.world.Location) BlockSnapshotBuilder(org.lanternpowered.server.block.BlockSnapshotBuilder)

Example 5 with BehaviorResult

use of org.lanternpowered.server.behavior.BehaviorResult in project LanternServer by LanternPowered.

the class PlayerInteractionHandler method handleBlockPlacing.

public void handleBlockPlacing(MessagePlayInPlayerBlockPlacement message) {
    final HandType handType = message.getHandType();
    // the main hand message.
    if (handType == HandTypes.OFF_HAND) {
        return;
    }
    // Try the action of the hotbar item first
    final AbstractSlot hotbarSlot = this.player.getInventory().getHotbar().getSelectedSlot();
    final AbstractSlot offHandSlot = this.player.getInventory().getOffhand();
    // The offset can round up to 1, causing
    // an incorrect clicked block location
    final Vector3d pos2 = message.getClickOffset();
    final double dx = Math.min(pos2.getX(), 0.999);
    final double dy = Math.min(pos2.getY(), 0.999);
    final double dz = Math.min(pos2.getZ(), 0.999);
    final Location<World> clickedLocation = new Location<>(this.player.getWorld(), message.getPosition().toDouble().add(dx, dy, dz));
    final Direction face = message.getFace();
    final CauseStack causeStack = CauseStack.current();
    try (CauseStack.Frame frame = causeStack.pushCauseFrame()) {
        frame.pushCause(this.player);
        // Add context
        frame.addContext(ContextKeys.INTERACTION_FACE, face);
        frame.addContext(ContextKeys.INTERACTION_LOCATION, clickedLocation);
        frame.addContext(ContextKeys.BLOCK_LOCATION, new Location<>(clickedLocation.getExtent(), message.getPosition()));
        frame.addContext(ContextKeys.PLAYER, this.player);
        final BehaviorContextImpl context = new BehaviorContextImpl(causeStack);
        final BehaviorContext.Snapshot snapshot = context.pushSnapshot();
        if (!this.player.get(Keys.IS_SNEAKING).orElse(false)) {
            final BlockState blockState = this.player.getWorld().getBlock(message.getPosition());
            final LanternBlockType blockType = (LanternBlockType) blockState.getType();
            frame.addContext(ContextKeys.BLOCK_TYPE, blockState.getType());
            frame.addContext(ContextKeys.USED_BLOCK_STATE, blockState);
            BehaviorContext.Snapshot snapshot1 = context.pushSnapshot();
            // Try first with the main hand
            hotbarSlot.peek().ifPresent(stack -> frame.addContext(ContextKeys.USED_ITEM_STACK, stack));
            frame.addContext(ContextKeys.USED_SLOT, hotbarSlot);
            frame.addContext(ContextKeys.INTERACTION_HAND, HandTypes.MAIN_HAND);
            BehaviorResult result = context.process(blockType.getPipeline().pipeline(InteractWithBlockBehavior.class), (ctx, behavior) -> behavior.tryInteract(blockType.getPipeline(), ctx));
            if (!result.isSuccess()) {
                context.popSnapshot(snapshot1);
                snapshot1 = context.pushSnapshot();
                // Try again with the off hand
                offHandSlot.peek().ifPresent(stack -> frame.addContext(ContextKeys.USED_ITEM_STACK, stack));
                frame.addContext(ContextKeys.USED_SLOT, offHandSlot);
                frame.addContext(ContextKeys.INTERACTION_HAND, HandTypes.OFF_HAND);
                result = context.process(blockType.getPipeline().pipeline(InteractWithBlockBehavior.class), (ctx, behavior) -> behavior.tryInteract(blockType.getPipeline(), ctx));
            }
            if (result.isSuccess()) {
                snapshot1 = context.pushSnapshot();
                // We can still continue, doing other operations
                if (result == BehaviorResult.CONTINUE) {
                    handleMainHandItemInteraction(context, snapshot1);
                }
                context.accept();
                return;
            }
            context.popSnapshot(snapshot1);
            snapshot1 = context.pushSnapshot();
            if (result.isSuccess()) {
                snapshot1 = context.pushSnapshot();
                // We can still continue, doing other operations
                if (result == BehaviorResult.CONTINUE) {
                    handleOffHandItemInteraction(context, snapshot1);
                }
                context.accept();
                return;
            }
            context.popSnapshot(snapshot1);
        }
        handleItemInteraction(context, snapshot);
    }
}
Also used : MessagePlayOutEntityAnimation(org.lanternpowered.server.network.vanilla.message.type.play.MessagePlayOutEntityAnimation) LanternKeys(org.lanternpowered.server.data.key.LanternKeys) Keys(org.spongepowered.api.data.key.Keys) EventContextKeys(org.spongepowered.api.event.cause.EventContextKeys) LanternBlockType(org.lanternpowered.server.block.LanternBlockType) MessagePlayInPlayerSwingArm(org.lanternpowered.server.network.vanilla.message.type.play.MessagePlayInPlayerSwingArm) BehaviorContextImpl(org.lanternpowered.server.behavior.BehaviorContextImpl) Vector3d(com.flowpowered.math.vector.Vector3d) MessagePlayInOutFinishUsingItem(org.lanternpowered.server.network.vanilla.message.type.play.MessagePlayInOutFinishUsingItem) MessagePlayInPlayerDigging(org.lanternpowered.server.network.vanilla.message.type.play.MessagePlayInPlayerDigging) HandType(org.spongepowered.api.data.type.HandType) MinimumUseDurationProperty(org.lanternpowered.server.item.property.MinimumUseDurationProperty) GameModes(org.spongepowered.api.entity.living.player.gamemode.GameModes) BreakBlockBehavior(org.lanternpowered.server.block.behavior.types.BreakBlockBehavior) ItemStack(org.spongepowered.api.item.inventory.ItemStack) BehaviorContext(org.lanternpowered.server.behavior.BehaviorContext) CauseStack(org.lanternpowered.server.event.CauseStack) InteractWithItemBehavior(org.lanternpowered.server.item.behavior.types.InteractWithItemBehavior) MessagePlayOutBlockBreakAnimation(org.lanternpowered.server.network.vanilla.message.type.play.MessagePlayOutBlockBreakAnimation) BehaviorResult(org.lanternpowered.server.behavior.BehaviorResult) LanternWorld(org.lanternpowered.server.world.LanternWorld) InteractWithBlockBehavior(org.lanternpowered.server.block.behavior.types.InteractWithBlockBehavior) Nullable(javax.annotation.Nullable) ContextKeys(org.lanternpowered.server.behavior.ContextKeys) FinishUsingItemBehavior(org.lanternpowered.server.item.behavior.types.FinishUsingItemBehavior) Location(org.spongepowered.api.world.Location) MaximumUseDurationProperty(org.lanternpowered.server.item.property.MaximumUseDurationProperty) LanternItemType(org.lanternpowered.server.item.LanternItemType) MessagePlayInPlayerUseItem(org.lanternpowered.server.network.vanilla.message.type.play.MessagePlayInPlayerUseItem) AbstractSlot(org.lanternpowered.server.inventory.AbstractSlot) BlockTypes(org.spongepowered.api.block.BlockTypes) SwingHandEntityEvent(org.lanternpowered.server.entity.event.SwingHandEntityEvent) Set(java.util.Set) LanternGame(org.lanternpowered.server.game.LanternGame) BlockState(org.spongepowered.api.block.BlockState) Objects(java.util.Objects) Direction(org.spongepowered.api.util.Direction) DualWieldProperty(org.lanternpowered.server.item.property.DualWieldProperty) Lantern(org.lanternpowered.server.game.Lantern) Vector3i(com.flowpowered.math.vector.Vector3i) World(org.spongepowered.api.world.World) BlockType(org.spongepowered.api.block.BlockType) HandTypes(org.spongepowered.api.data.type.HandTypes) Optional(java.util.Optional) MessagePlayInPlayerBlockPlacement(org.lanternpowered.server.network.vanilla.message.type.play.MessagePlayInPlayerBlockPlacement) CauseStack(org.lanternpowered.server.event.CauseStack) AbstractSlot(org.lanternpowered.server.inventory.AbstractSlot) HandType(org.spongepowered.api.data.type.HandType) LanternWorld(org.lanternpowered.server.world.LanternWorld) World(org.spongepowered.api.world.World) Direction(org.spongepowered.api.util.Direction) LanternBlockType(org.lanternpowered.server.block.LanternBlockType) BehaviorContextImpl(org.lanternpowered.server.behavior.BehaviorContextImpl) BlockState(org.spongepowered.api.block.BlockState) Vector3d(com.flowpowered.math.vector.Vector3d) BehaviorResult(org.lanternpowered.server.behavior.BehaviorResult) BehaviorContext(org.lanternpowered.server.behavior.BehaviorContext) Location(org.spongepowered.api.world.Location) InteractWithBlockBehavior(org.lanternpowered.server.block.behavior.types.InteractWithBlockBehavior)

Aggregations

BehaviorResult (org.lanternpowered.server.behavior.BehaviorResult)6 BehaviorContext (org.lanternpowered.server.behavior.BehaviorContext)4 ContextKeys (org.lanternpowered.server.behavior.ContextKeys)4 InteractWithItemBehavior (org.lanternpowered.server.item.behavior.types.InteractWithItemBehavior)4 Keys (org.spongepowered.api.data.key.Keys)4 Direction (org.spongepowered.api.util.Direction)4 World (org.spongepowered.api.world.World)4 Optional (java.util.Optional)3 Behavior (org.lanternpowered.server.behavior.Behavior)3 BehaviorPipeline (org.lanternpowered.server.behavior.pipeline.BehaviorPipeline)3 LanternBlockType (org.lanternpowered.server.block.LanternBlockType)3 BlockState (org.spongepowered.api.block.BlockState)3 GameModes (org.spongepowered.api.entity.living.player.gamemode.GameModes)3 Location (org.spongepowered.api.world.Location)3 BlockSnapshotBuilder (org.lanternpowered.server.block.BlockSnapshotBuilder)2 BreakBlockBehavior (org.lanternpowered.server.block.behavior.types.BreakBlockBehavior)2 LanternItemType (org.lanternpowered.server.item.LanternItemType)2 BlockType (org.spongepowered.api.block.BlockType)2 BlockTypes (org.spongepowered.api.block.BlockTypes)2 ReplaceableProperty (org.spongepowered.api.data.property.block.ReplaceableProperty)2