Search in sources :

Example 31 with CauseStack

use of org.lanternpowered.server.event.CauseStack 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)

Example 32 with CauseStack

use of org.lanternpowered.server.event.CauseStack in project LanternServer by LanternPowered.

the class PlayerInteractionHandler method handleFinishItemInteraction0.

private void handleFinishItemInteraction0(AbstractSlot slot, HandType handType) {
    final Optional<ItemStack> handItem = slot.peek();
    if (handItem.isPresent()) {
        final CauseStack causeStack = CauseStack.current();
        try (CauseStack.Frame frame = causeStack.pushCauseFrame()) {
            frame.pushCause(this.player);
            frame.addContext(ContextKeys.PLAYER, this.player);
            if (handItem.isPresent()) {
                final LanternItemType itemType = (LanternItemType) handItem.get().getType();
                frame.addContext(ContextKeys.USED_ITEM_STACK, handItem.get());
                frame.addContext(ContextKeys.USED_SLOT, slot);
                frame.addContext(ContextKeys.INTERACTION_HAND, handType);
                frame.addContext(ContextKeys.ITEM_TYPE, itemType);
                final BehaviorContextImpl context = new BehaviorContextImpl(causeStack);
                if (context.process(itemType.getPipeline().pipeline(FinishUsingItemBehavior.class), (ctx, behavior) -> behavior.tryUse(itemType.getPipeline(), ctx)).isSuccess()) {
                    context.accept();
                }
            }
        }
    }
    resetItemUseTime();
}
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) BehaviorContextImpl(org.lanternpowered.server.behavior.BehaviorContextImpl) LanternItemType(org.lanternpowered.server.item.LanternItemType) ItemStack(org.spongepowered.api.item.inventory.ItemStack)

Example 33 with CauseStack

use of org.lanternpowered.server.event.CauseStack in project LanternServer by LanternPowered.

the class PlayerInteractionHandler method handleItemInteraction.

public void handleItemInteraction(MessagePlayInPlayerUseItem message) {
    // Prevent duplicate messages
    final long time = System.currentTimeMillis();
    if (this.lastInteractionTime != -1L && time - this.lastInteractionTime < 40) {
        return;
    }
    this.lastInteractionTime = time;
    final CauseStack causeStack = CauseStack.current();
    try (CauseStack.Frame frame = causeStack.pushCauseFrame()) {
        final BehaviorContextImpl context = new BehaviorContextImpl(causeStack);
        frame.pushCause(this.player);
        frame.addContext(ContextKeys.PLAYER, this.player);
        final BehaviorContext.Snapshot snapshot = context.pushSnapshot();
        if (!handleItemInteraction(context, snapshot)) {
            if (!this.player.get(LanternKeys.CAN_DUAL_WIELD).orElse(false)) {
                return;
            }
            final AbstractSlot offHandSlot = this.player.getInventory().getOffhand();
            final Optional<ItemStack> handItem = offHandSlot.peek();
            if (handItem.isPresent()) {
                final DualWieldProperty property = handItem.get().getProperty(DualWieldProperty.class).orElse(null);
                // noinspection ConstantConditions
                if (property != null && property.getValue()) {
                    /*
                    final Vector3d position = this.player.getPosition().add(0, this.player.get(Keys.IS_SNEAKING).get() ? 1.54 : 1.62, 0);
                    final Optional<BlockRayHit<LanternWorld>> hit = BlockRay.from(this.player.getWorld(), position)
                            .direction(this.player.getDirectionVector())
                            .distanceLimit(5)
                            // Is this supposed to be inverted?
                            .skipFilter(Predicates.not(BlockRay.onlyAirFilter()))
                            .build()
                            .end();
                    if (hit.isPresent() && hit.get().getLocation().getBlock().getType() != BlockTypes.AIR) {
                        return;
                    }
                    */
                    this.player.getConnection().send(new MessagePlayOutEntityAnimation(this.player.getNetworkId(), 3));
                    this.player.triggerEvent(SwingHandEntityEvent.of(HandTypes.OFF_HAND));
                /*
                    final CooldownTracker cooldownTracker = this.player.getCooldownTracker();
                    cooldownTracker.set(handItem.get().getType(), 15);
                    */
                }
            }
        }
    }
}
Also used : CauseStack(org.lanternpowered.server.event.CauseStack) BehaviorContextImpl(org.lanternpowered.server.behavior.BehaviorContextImpl) AbstractSlot(org.lanternpowered.server.inventory.AbstractSlot) MessagePlayOutEntityAnimation(org.lanternpowered.server.network.vanilla.message.type.play.MessagePlayOutEntityAnimation) BehaviorContext(org.lanternpowered.server.behavior.BehaviorContext) ItemStack(org.spongepowered.api.item.inventory.ItemStack) DualWieldProperty(org.lanternpowered.server.item.property.DualWieldProperty)

Example 34 with CauseStack

use of org.lanternpowered.server.event.CauseStack in project LanternServer by LanternPowered.

the class LanternEntity method heal.

/**
 * Heals the entity for the specified amount.
 *
 * <p>Will not heal them if they are dead and will not set
 * them above their maximum health.</p>
 *
 * @param amount The amount to heal for
 * @param source The healing source
 */
public boolean heal(double amount, HealingSource source) {
    if (isDead()) {
        return false;
    }
    final MutableBoundedValue<Double> health = getValue(Keys.HEALTH).orElse(null);
    if (health == null || health.get() >= health.getMaxValue()) {
        return false;
    }
    final CauseStack causeStack = CauseStack.current();
    try (CauseStack.Frame frame = causeStack.pushCauseFrame()) {
        frame.pushCause(source);
        frame.addContext(LanternEventContextKeys.HEALING_TYPE, source.getHealingType());
        final HealEntityEvent event = SpongeEventFactory.createHealEntityEvent(frame.getCurrentCause(), new ArrayList<>(), this, amount);
        Sponge.getEventManager().post(event);
        if (event.isCancelled()) {
            return false;
        }
        amount = event.getFinalHealAmount();
        if (amount > 0) {
            offer(Keys.HEALTH, Math.min(health.get() + amount, health.getMaxValue()));
        }
    }
    return true;
}
Also used : CauseStack(org.lanternpowered.server.event.CauseStack) HealEntityEvent(org.spongepowered.api.event.entity.HealEntityEvent)

Example 35 with CauseStack

use of org.lanternpowered.server.event.CauseStack in project LanternServer by LanternPowered.

the class LanternItem method pulse.

@Override
public void pulse(int deltaTicks) {
    super.pulse(deltaTicks);
    int pickupDelay = get(Keys.PICKUP_DELAY).orElse(0);
    int despawnDelay = get(Keys.DESPAWN_DELAY).orElse(NO_DESPAWN_DELAY);
    final int oldPickupDelay = pickupDelay;
    final int oldDespawnDelay = despawnDelay;
    if (pickupDelay != NO_PICKUP_DELAY && pickupDelay > 0) {
        pickupDelay--;
    }
    if (despawnDelay != NO_DESPAWN_DELAY && despawnDelay > 0) {
        despawnDelay--;
    }
    if (this.counter++ % 20 == 0) {
        final CombineData data = combineItemStacks(pickupDelay, despawnDelay);
        if (data != null) {
            pickupDelay = data.pickupDelay;
            despawnDelay = data.despawnDelay;
        }
    }
    if (this.counter % 10 == 0 && pickupDelay != NO_PICKUP_DELAY && pickupDelay <= 0) {
        tryToPickupItems();
    }
    if (pickupDelay != oldPickupDelay) {
        offer(Keys.PICKUP_DELAY, pickupDelay);
    }
    if (despawnDelay != oldDespawnDelay) {
        offer(Keys.DESPAWN_DELAY, despawnDelay);
    }
    if (despawnDelay <= 0) {
        final CauseStack causeStack = CauseStack.current();
        try (CauseStack.Frame frame = causeStack.pushCauseFrame()) {
            frame.pushCause(this);
            // Throw the expire entity event
            final ExpireEntityEvent.TargetItem event = SpongeEventFactory.createExpireEntityEventTargetItem(causeStack.getCurrentCause(), this);
            Sponge.getEventManager().post(event);
            // Remove the item, also within this context
            remove();
        }
        // A death animation/particle?
        getWorld().spawnParticles(EffectHolder.DEATH_EFFECT, getBoundingBox().get().getCenter());
    } else {
        pulsePhysics();
    }
}
Also used : CauseStack(org.lanternpowered.server.event.CauseStack) ExpireEntityEvent(org.spongepowered.api.event.entity.ExpireEntityEvent)

Aggregations

CauseStack (org.lanternpowered.server.event.CauseStack)54 ItemStack (org.spongepowered.api.item.inventory.ItemStack)18 Entity (org.spongepowered.api.entity.Entity)16 ArrayList (java.util.ArrayList)15 Nullable (javax.annotation.Nullable)15 World (org.spongepowered.api.world.World)15 Optional (java.util.Optional)14 Lantern (org.lanternpowered.server.game.Lantern)13 AbstractSlot (org.lanternpowered.server.inventory.AbstractSlot)13 LanternWorld (org.lanternpowered.server.world.LanternWorld)13 SpawnEntityEvent (org.spongepowered.api.event.entity.SpawnEntityEvent)13 Vector3i (com.flowpowered.math.vector.Vector3i)12 List (java.util.List)12 LanternPlayer (org.lanternpowered.server.entity.living.player.LanternPlayer)12 Keys (org.spongepowered.api.data.key.Keys)12 EventContextKeys (org.spongepowered.api.event.cause.EventContextKeys)12 Sponge (org.spongepowered.api.Sponge)11 Transform (org.spongepowered.api.entity.Transform)11 Player (org.spongepowered.api.entity.living.player.Player)11 SpongeEventFactory (org.spongepowered.api.event.SpongeEventFactory)11