Search in sources :

Example 6 with CauseStack

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

the class PlayerInteractionHandler method handleBrokenBlock.

private void handleBrokenBlock() {
    final Location<World> location = new Location<>(this.player.getWorld(), this.diggingBlock);
    final CauseStack causeStack = CauseStack.current();
    try (CauseStack.Frame frame = causeStack.pushCauseFrame()) {
        frame.pushCause(this.player);
        // Add context
        frame.addContext(EventContextKeys.PLAYER, this.player);
        frame.addContext(ContextKeys.INTERACTION_LOCATION, location);
        frame.addContext(ContextKeys.BLOCK_LOCATION, location);
        final BehaviorContextImpl context = new BehaviorContextImpl(causeStack);
        final BlockState blockState = location.getBlock();
        final LanternBlockType blockType = (LanternBlockType) blockState.getType();
        if (context.process(blockType.getPipeline().pipeline(BreakBlockBehavior.class), (ctx, behavior) -> behavior.tryBreak(blockType.getPipeline(), ctx)).isSuccess()) {
            context.accept();
            this.diggingBlock = null;
            this.diggingBlockType = null;
        } else {
            context.revert();
            // TODO: Resend tile entity data, action data, ... ???
            this.player.sendBlockChange(this.diggingBlock, blockState);
        }
        if (this.lastBreakState != -1) {
            sendBreakUpdate(-1);
        }
    }
}
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) BlockState(org.spongepowered.api.block.BlockState) LanternWorld(org.lanternpowered.server.world.LanternWorld) World(org.spongepowered.api.world.World) LanternBlockType(org.lanternpowered.server.block.LanternBlockType) Location(org.spongepowered.api.world.Location)

Example 7 with CauseStack

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

the class LanternPlayer method handleRespawn.

public void handleRespawn() {
    Transform<World> transform = getTransform();
    final LanternWorld world = (LanternWorld) transform.getExtent();
    if (isDead()) {
        // TODO: Get the proper spawn location
        final Transform<World> toTransform = new Transform<>(transform.getExtent(), new Vector3d(0, 100, 0));
        // Make the player less dead...
        setDead(false);
        // Reset player settings
        offer(Keys.HEALTH, get(Keys.MAX_HEALTH).get());
        offer(Keys.FOOD_LEVEL, get(LanternKeys.MAX_FOOD_LEVEL).get());
        offer(Keys.ABSORPTION, 0.0);
        offer(Keys.EXHAUSTION, DEFAULT_EXHAUSTION);
        offer(Keys.SATURATION, DEFAULT_SATURATION);
        offer(Keys.POTION_EFFECTS, new ArrayList<>());
        offer(LanternKeys.SCORE, 0);
        final CauseStack causeStack = CauseStack.current();
        try (CauseStack.Frame frame = causeStack.pushCauseFrame()) {
            frame.pushCause(this);
            frame.addContext(EventContextKeys.PLAYER, this);
            final RespawnPlayerEvent event = SpongeEventFactory.createRespawnPlayerEvent(causeStack.getCurrentCause(), transform, toTransform, this, this, false, true);
            Sponge.getEventManager().post(event);
            // Get the to transform, this can be overridden in the event
            transform = event.getToTransform();
        }
    }
    setWorld(world, (LanternWorld) transform.getExtent());
    setPosition(transform.getPosition());
}
Also used : CauseStack(org.lanternpowered.server.event.CauseStack) Vector3d(com.flowpowered.math.vector.Vector3d) LanternWorld(org.lanternpowered.server.world.LanternWorld) RespawnPlayerEvent(org.spongepowered.api.event.entity.living.humanoid.player.RespawnPlayerEvent) World(org.spongepowered.api.world.World) LanternWorld(org.lanternpowered.server.world.LanternWorld) Transform(org.spongepowered.api.entity.Transform)

Example 8 with CauseStack

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

the class LanternEntity method remove.

public void remove(RemoveState removeState) {
    checkNotNull(removeState, "removeState");
    if (this.removeState == removeState) {
        return;
    }
    this.removeState = removeState;
    if (removeState == RemoveState.DESTROYED) {
        setVehicle(null);
        clearPassengers();
        // don't do it if the entity is dead.
        if (!isDead()) {
            setDead(true);
            final CauseStack causeStack = CauseStack.current();
            // TODO: Message channel?
            final DestructEntityEvent event = SpongeEventFactory.createDestructEntityEvent(causeStack.getCurrentCause(), MessageChannel.TO_NONE, Optional.empty(), new MessageEvent.MessageFormatter(), this, false);
            postDestructEvent(event);
        }
    }
}
Also used : CauseStack(org.lanternpowered.server.event.CauseStack) DestructEntityEvent(org.spongepowered.api.event.entity.DestructEntityEvent) MessageEvent(org.spongepowered.api.event.message.MessageEvent)

Example 9 with CauseStack

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

the class LanternEntity method damage.

@Override
public boolean damage(double damage, DamageSource damageSource) {
    checkNotNull(damageSource, "damageSource");
    final Optional<Double> optHealth = get(Keys.HEALTH);
    if (!optHealth.isPresent()) {
        // entities without health, instantly destroying them.
        if (damageSource.getType() == DamageTypes.VOID) {
            remove(RemoveState.DESTROYED);
            return true;
        }
        return false;
    }
    // Always throw the event. Plugins may want to override
    // default checking behavior.
    boolean cancelled = false;
    // if the player is in creative mode
    if (!damageSource.doesAffectCreative() && get(Keys.GAME_MODE).orElse(null) == GameModes.CREATIVE) {
        cancelled = true;
    }
    final List<Tuple<DamageFunction, Consumer<DamageEntityEvent>>> damageFunctions = new ArrayList<>();
    // Only collect damage modifiers if the event isn't cancelled
    if (!cancelled) {
        collectDamageFunctions(damageFunctions);
    }
    // TODO: Damage modifiers, etc.
    final CauseStack causeStack = CauseStack.current();
    try (CauseStack.Frame frame = causeStack.pushCauseFrame()) {
        frame.pushCause(damageSource);
        frame.addContext(EventContextKeys.DAMAGE_TYPE, damageSource.getType());
        final DamageEntityEvent event = SpongeEventFactory.createDamageEntityEvent(frame.getCurrentCause(), damageFunctions.stream().map(Tuple::getFirst).collect(Collectors.toList()), this, damage);
        event.setCancelled(cancelled);
        Sponge.getEventManager().post(event);
        if (event.isCancelled()) {
            return false;
        }
        damageFunctions.forEach(tuple -> tuple.getSecond().accept(event));
        damage = event.getFinalDamage();
        if (damage > 0) {
            offer(Keys.HEALTH, Math.max(optHealth.get() - damage, 0));
        }
        final double exhaustion = damageSource.getExhaustion();
        getValue(Keys.EXHAUSTION).ifPresent(value -> offer(Keys.EXHAUSTION, Math.min(value.getMaxValue(), value.get() + exhaustion)));
    }
    triggerEvent(DamagedEntityEvent.of());
    return true;
}
Also used : DamageEntityEvent(org.spongepowered.api.event.entity.DamageEntityEvent) CauseStack(org.lanternpowered.server.event.CauseStack) ArrayList(java.util.ArrayList) Tuple(org.spongepowered.api.util.Tuple)

Example 10 with CauseStack

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

the class LanternItem method combineItemStacks.

@Nullable
private CombineData combineItemStacks(int pickupDelay, int despawnDelay) {
    // Remove items with no item stack
    final ItemStackSnapshot itemStackSnapshot1 = get(Keys.REPRESENTED_ITEM).orElse(null);
    if (itemStackSnapshot1 == null || itemStackSnapshot1.isEmpty()) {
        remove();
        return null;
    }
    final int max = itemStackSnapshot1.getType().getMaxStackQuantity();
    int quantity1 = itemStackSnapshot1.getQuantity();
    // Check if the stack is already at it's maximum size
    if (quantity1 >= max) {
        return null;
    }
    final CauseStack causeStack = CauseStack.current();
    final CauseStack.Frame frame = causeStack.pushCauseFrame();
    frame.pushCause(this);
    // Search for surrounding items
    final Set<Entity> entities = getWorld().getIntersectingEntities(getBoundingBox().get().expand(0.6, 0.0, 0.6), entity -> entity != this && entity instanceof LanternItem);
    ItemStack itemStack1 = null;
    for (Entity entity : entities) {
        final int pickupDelay1 = entity.get(Keys.PICKUP_DELAY).orElse(0);
        if (pickupDelay1 == NO_PICKUP_DELAY) {
            continue;
        }
        final ItemStackSnapshot itemStackSnapshot2 = entity.get(Keys.REPRESENTED_ITEM).get();
        int quantity2 = itemStackSnapshot2.getQuantity();
        // make sure that the stacks can be merged
        if (quantity2 >= max || !LanternItemStack.areSimilar(itemStackSnapshot1, itemStackSnapshot2)) {
            continue;
        }
        // Call the merge event
        final ItemMergeItemEvent event = SpongeEventFactory.createItemMergeItemEvent(causeStack.getCurrentCause(), (Item) entity, this);
        Sponge.getEventManager().post(event);
        if (event.isCancelled()) {
            continue;
        }
        // Merge the items
        quantity1 += quantity2;
        if (quantity1 > max) {
            quantity2 = quantity1 - max;
            quantity1 = max;
            // Create a new stack and offer it back the entity
            final ItemStack itemStack2 = itemStackSnapshot2.createStack();
            itemStack2.setQuantity(quantity2);
            // The snapshot can be wrapped
            entity.offer(Keys.REPRESENTED_ITEM, LanternItemStackSnapshot.wrap(itemStack2));
        } else {
            // The other entity is completely drained and will be removed
            entity.offer(Keys.REPRESENTED_ITEM, ItemStackSnapshot.NONE);
            entity.remove();
        }
        // The item stack has changed
        if (itemStack1 == null) {
            itemStack1 = itemStackSnapshot1.createStack();
        }
        itemStack1.setQuantity(quantity1);
        // When merging items, also merge the pickup and despawn delays
        pickupDelay = Math.max(pickupDelay, pickupDelay1);
        despawnDelay = Math.max(despawnDelay, entity.get(Keys.DESPAWN_DELAY).orElse(NO_DESPAWN_DELAY));
        // The stack is already full, stop here
        if (quantity1 == max) {
            break;
        }
    }
    causeStack.popCauseFrame(frame);
    if (itemStack1 != null) {
        offer(Keys.REPRESENTED_ITEM, LanternItemStackSnapshot.wrap(itemStack1));
        return new CombineData(pickupDelay, despawnDelay);
    }
    return null;
}
Also used : CauseStack(org.lanternpowered.server.event.CauseStack) Entity(org.spongepowered.api.entity.Entity) ItemMergeItemEvent(org.spongepowered.api.event.entity.item.ItemMergeItemEvent) ItemStackSnapshot(org.spongepowered.api.item.inventory.ItemStackSnapshot) LanternItemStackSnapshot(org.lanternpowered.server.inventory.LanternItemStackSnapshot) ItemStack(org.spongepowered.api.item.inventory.ItemStack) LanternItemStack(org.lanternpowered.server.inventory.LanternItemStack) Nullable(javax.annotation.Nullable)

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