Search in sources :

Example 1 with Ticks

use of org.spongepowered.api.util.Ticks in project SpongeCommon by SpongePowered.

the class LivingEntityMixin method impl$onSetActiveItemStack.

// Data delegated methods
// Start implementation of UseItemstackEvent
@Inject(method = "startUsingItem", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "FIELD", target = "Lnet/minecraft/world/entity/LivingEntity;useItem:Lnet/minecraft/world/item/ItemStack;"))
private void impl$onSetActiveItemStack(final InteractionHand hand, final CallbackInfo ci, final ItemStack stack) {
    if (this.level.isClientSide) {
        return;
    }
    final UseItemStackEvent.Start event;
    try (final CauseStackManager.StackFrame frame = PhaseTracker.getCauseStackManager().pushCauseFrame()) {
        final ItemStackSnapshot snapshot = ItemStackUtil.snapshotOf(stack);
        final HandType handType = (HandType) (Object) hand;
        this.impl$addSelfToFrame(frame, snapshot, handType);
        final Ticks useDuration = Ticks.of(stack.getUseDuration());
        event = SpongeEventFactory.createUseItemStackEventStart(PhaseTracker.getCauseStackManager().currentCause(), useDuration, useDuration, snapshot);
    }
    if (SpongeCommon.post(event)) {
        ci.cancel();
    } else {
        this.useItemRemaining = (int) event.remainingDuration().ticks();
    }
}
Also used : UseItemStackEvent(org.spongepowered.api.event.item.inventory.UseItemStackEvent) CauseStackManager(org.spongepowered.api.event.CauseStackManager) HandType(org.spongepowered.api.data.type.HandType) Ticks(org.spongepowered.api.util.Ticks) ItemStackSnapshot(org.spongepowered.api.item.inventory.ItemStackSnapshot) Inject(org.spongepowered.asm.mixin.injection.Inject)

Example 2 with Ticks

use of org.spongepowered.api.util.Ticks in project SpongeCommon by SpongePowered.

the class LivingEntityMixin method impl$onUpdateItemUse.

@SuppressWarnings("ConstantConditions")
@Inject(method = "completeUsingItem", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/LivingEntity;triggerItemUseEffects(Lnet/minecraft/world/item/ItemStack;I)V"))
private void impl$onUpdateItemUse(final CallbackInfo ci) {
    if (this.level.isClientSide) {
        return;
    }
    final UseItemStackEvent.Finish event;
    try (final CauseStackManager.StackFrame frame = PhaseTracker.getCauseStackManager().pushCauseFrame()) {
        final ItemStackSnapshot snapshot = ItemStackUtil.snapshotOf(this.useItem);
        final HandType handType = (HandType) (Object) this.shadow$getUsedItemHand();
        this.impl$addSelfToFrame(frame, snapshot, handType);
        final Ticks useItemRemainingTicks = Ticks.of(this.useItemRemaining);
        event = SpongeEventFactory.createUseItemStackEventFinish(PhaseTracker.getCauseStackManager().currentCause(), useItemRemainingTicks, useItemRemainingTicks, snapshot);
    }
    SpongeCommon.post(event);
    if (event.remainingDuration().ticks() > 0) {
        this.useItemRemaining = (int) event.remainingDuration().ticks();
        ci.cancel();
    } else if (event.isCancelled()) {
        this.shadow$stopUsingItem();
        ci.cancel();
    } else {
        this.impl$activeItemStackCopy = this.useItem.copy();
    }
}
Also used : UseItemStackEvent(org.spongepowered.api.event.item.inventory.UseItemStackEvent) CauseStackManager(org.spongepowered.api.event.CauseStackManager) HandType(org.spongepowered.api.data.type.HandType) Ticks(org.spongepowered.api.util.Ticks) ItemStackSnapshot(org.spongepowered.api.item.inventory.ItemStackSnapshot) Inject(org.spongepowered.asm.mixin.injection.Inject)

Example 3 with Ticks

use of org.spongepowered.api.util.Ticks in project SpongeCommon by SpongePowered.

the class LivingEntityMixin method impl$onSetHeldItem.

@Redirect(method = "completeUsingItem", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/LivingEntity;setItemInHand(Lnet/minecraft/world/InteractionHand;Lnet/minecraft/world/item/ItemStack;)V"))
private void impl$onSetHeldItem(final LivingEntity self, final InteractionHand hand, final ItemStack stack) {
    if (this.level.isClientSide) {
        self.setItemInHand(hand, stack);
        return;
    }
    // Unforunately, ItemFood calls ItemStack#shrink in Item#onItemUseFinish.
    // To ensure that we provide the original ItemStack in the event,
    // we make a copy of in our onUpdateItemUse redirect
    // If the event or transaction is cancelled, we make sure to explicitly
    // set the copy back in the player's hand, since it may have been already
    // modified if an ItemFood is being used.
    final ItemStackSnapshot activeItemStackSnapshot = ItemStackUtil.snapshotOf(this.impl$activeItemStackCopy == null ? ItemStack.EMPTY : this.impl$activeItemStackCopy);
    final UseItemStackEvent.Replace event;
    try (final CauseStackManager.StackFrame frame = PhaseTracker.getCauseStackManager().pushCauseFrame()) {
        final ItemStackSnapshot snapshot = ItemStackUtil.snapshotOf(stack == null ? ItemStack.EMPTY : stack);
        final HandType handType = (HandType) (Object) hand;
        this.impl$addSelfToFrame(frame, activeItemStackSnapshot, handType);
        final Ticks useItemRemainingTicks = Ticks.of(this.useItemRemaining);
        event = SpongeEventFactory.createUseItemStackEventReplace(PhaseTracker.getCauseStackManager().currentCause(), useItemRemainingTicks, useItemRemainingTicks, activeItemStackSnapshot, new Transaction<>(ItemStackUtil.snapshotOf(this.impl$activeItemStackCopy), snapshot));
    }
    if (SpongeCommon.post(event)) {
        this.shadow$setItemInHand(hand, this.impl$activeItemStackCopy.copy());
        return;
    }
    if (!event.itemStackResult().isValid()) {
        this.shadow$setItemInHand(hand, this.impl$activeItemStackCopy.copy());
        return;
    }
    this.shadow$setItemInHand(hand, ItemStackUtil.fromSnapshotToNative(event.itemStackResult().finalReplacement()));
}
Also used : PlayerInventoryTransaction(org.spongepowered.common.event.tracking.context.transaction.inventory.PlayerInventoryTransaction) Transaction(org.spongepowered.api.data.Transaction) UseItemStackEvent(org.spongepowered.api.event.item.inventory.UseItemStackEvent) CauseStackManager(org.spongepowered.api.event.CauseStackManager) HandType(org.spongepowered.api.data.type.HandType) Ticks(org.spongepowered.api.util.Ticks) ItemStackSnapshot(org.spongepowered.api.item.inventory.ItemStackSnapshot) Redirect(org.spongepowered.asm.mixin.injection.Redirect)

Example 4 with Ticks

use of org.spongepowered.api.util.Ticks in project SpongeCommon by SpongePowered.

the class EntityData method register.

// @formatter:off
public static void register(final DataProviderRegistrator registrator) {
    registrator.asMutable(Entity.class).create(Keys.AGE).get(h -> h.tickCount).setAnd((h, v) -> {
        if (v < 0) {
            return false;
        }
        h.tickCount = v;
        return true;
    }).create(Keys.BASE_SIZE).get(h -> (double) h.getBbWidth()).create(Keys.BASE_VEHICLE).get(h -> {
        final Entity rootVehicle = h.getRootVehicle();
        if (rootVehicle == h) {
            return null;
        }
        return (org.spongepowered.api.entity.Entity) rootVehicle;
    }).create(Keys.CUSTOM_NAME).get(h -> h.hasCustomName() ? SpongeAdventure.asAdventure(h.getCustomName()) : null).set((h, v) -> h.setCustomName(SpongeAdventure.asVanilla(v))).delete(h -> {
        h.setCustomName(null);
        h.setCustomNameVisible(false);
    }).create(Keys.DISPLAY_NAME).get(h -> SpongeAdventure.asAdventure(h.getDisplayName())).create(Keys.EYE_HEIGHT).get(h -> (double) h.getEyeHeight()).create(Keys.EYE_POSITION).get(h -> VecHelper.toVector3d(h.getEyePosition(1f))).create(Keys.FALL_DISTANCE).get(h -> (double) h.fallDistance).setAnd((h, v) -> {
        if (v < 0) {
            return false;
        }
        h.fallDistance = v.floatValue();
        return true;
    }).create(Keys.FIRE_DAMAGE_DELAY).get(h -> new SpongeTicks(((EntityAccessor) h).invoker$getFireImmuneTicks())).setAnd((h, v) -> {
        final int ticks = (int) v.ticks();
        if (ticks < 1 || ticks > Short.MAX_VALUE) {
            return false;
        }
        ((EntityBridge) h).bridge$setFireImmuneTicks(ticks);
        return ((EntityAccessor) h).invoker$getFireImmuneTicks() == ticks;
    }).create(Keys.FIRE_TICKS).get(h -> ((EntityAccessor) h).accessor$remainingFireTicks() > 0 ? Ticks.of(((EntityAccessor) h).accessor$remainingFireTicks()) : null).set((h, v) -> {
        final int ticks = (int) v.ticks();
        ((EntityAccessor) h).accessor$remainingFireTicks(Math.max(ticks, Constants.Entity.MINIMUM_FIRE_TICKS));
    }).deleteAndGet(h -> {
        final EntityAccessor accessor = (EntityAccessor) h;
        final int ticks = accessor.accessor$remainingFireTicks();
        if (ticks < Constants.Entity.MINIMUM_FIRE_TICKS) {
            return DataTransactionResult.failNoData();
        }
        final DataTransactionResult.Builder dtrBuilder = DataTransactionResult.builder();
        dtrBuilder.replace(Value.immutableOf(Keys.FIRE_TICKS, new SpongeTicks(ticks)));
        dtrBuilder.replace(Value.immutableOf(Keys.FIRE_DAMAGE_DELAY, new SpongeTicks(((EntityAccessor) h).invoker$getFireImmuneTicks())));
        h.clearFire();
        return dtrBuilder.result(DataTransactionResult.Type.SUCCESS).build();
    }).create(Keys.HEIGHT).get(h -> (double) h.getBbHeight()).create(Keys.INVULNERABILITY_TICKS).get(h -> new SpongeTicks(h.invulnerableTime)).setAnd((h, v) -> {
        final int ticks = (int) v.ticks();
        if (ticks < 0) {
            return false;
        }
        h.invulnerableTime = ticks;
        if (h instanceof LivingEntity) {
            ((LivingEntity) h).hurtTime = ticks;
        }
        return true;
    }).create(Keys.IS_CUSTOM_NAME_VISIBLE).get(Entity::isCustomNameVisible).set(Entity::setCustomNameVisible).create(Keys.IS_FLYING).get(h -> h.hasImpulse).set((h, v) -> h.hasImpulse = v).supports(h -> !(h instanceof Player)).create(Keys.IS_GLOWING).get(Entity::isGlowing).set(Entity::setGlowing).create(Keys.IS_GRAVITY_AFFECTED).get(h -> !h.isNoGravity()).set((h, v) -> h.setNoGravity(!v)).create(Keys.IS_SNEAKING).get(Entity::isShiftKeyDown).set(Entity::setShiftKeyDown).create(Keys.IS_SPRINTING).get(Entity::isSprinting).set(Entity::setSprinting).create(Keys.IS_SILENT).get(Entity::isSilent).set(Entity::setSilent).create(Keys.IS_WET).get(Entity::isInWaterOrRain).create(Keys.ON_GROUND).get(Entity::isOnGround).create(Keys.PASSENGERS).get(h -> h.getPassengers().stream().map(org.spongepowered.api.entity.Entity.class::cast).collect(Collectors.toList())).set((h, v) -> {
        h.ejectPassengers();
        v.forEach(v1 -> ((Entity) v1).startRiding(h, true));
    }).create(Keys.REMAINING_AIR).get(h -> Math.max(0, h.getAirSupply())).setAnd((h, v) -> {
        if (v < 0 || v > h.getMaxAirSupply()) {
            return false;
        }
        if (v == 0 && h.getAirSupply() < 0) {
            return false;
        }
        h.setAirSupply(v);
        return true;
    }).create(Keys.SCALE).get(h -> 1d).create(Keys.SCOREBOARD_TAGS).get(Entity::getTags).set((h, v) -> {
        h.getTags().clear();
        h.getTags().addAll(v);
    }).create(Keys.TRANSIENT).get(h -> ((EntityAccessor) h).invoker$getEncodeId() == null).set((h, v) -> ((EntityBridge) h).bridge$setTransient(v)).create(Keys.VEHICLE).get(h -> (org.spongepowered.api.entity.Entity) h.getVehicle()).set((h, v) -> h.startRiding((Entity) v, true)).create(Keys.VELOCITY).get(h -> VecHelper.toVector3d(h.getDeltaMovement())).set((h, v) -> h.setDeltaMovement(VecHelper.toVanillaVector3d(v))).create(Keys.SWIFTNESS).get(m -> m.getDeltaMovement().length()).set((m, v) -> m.setDeltaMovement(m.getDeltaMovement().normalize().scale(v))).supports(m -> m.getDeltaMovement().lengthSqr() > 0).asMutable(EntityMaxAirBridge.class).create(Keys.MAX_AIR).get(EntityMaxAirBridge::bridge$getMaxAir).set(EntityMaxAirBridge::bridge$setMaxAir);
    registrator.spongeDataStore(ResourceKey.sponge("max_air"), EntityMaxAirBridge.class, Keys.MAX_AIR);
    registrator.newDataStore(SpongeEntitySnapshot.class, SpongeEntityArchetype.class).dataStore(Keys.CUSTOM_NAME, (dv, v) -> dv.set(Constants.Entity.CUSTOM_NAME, GsonComponentSerializer.gson().serialize(v)), dv -> dv.getString(Constants.Entity.CUSTOM_NAME).map(GsonComponentSerializer.gson()::deserialize));
// @formatter:on
}
Also used : GsonComponentSerializer(net.kyori.adventure.text.serializer.gson.GsonComponentSerializer) Ticks(org.spongepowered.api.util.Ticks) LivingEntity(net.minecraft.world.entity.LivingEntity) EntityMaxAirBridge(org.spongepowered.common.bridge.world.entity.EntityMaxAirBridge) Constants(org.spongepowered.common.util.Constants) SpongeEntityArchetype(org.spongepowered.common.entity.SpongeEntityArchetype) SpongeAdventure(org.spongepowered.common.adventure.SpongeAdventure) DataTransactionResult(org.spongepowered.api.data.DataTransactionResult) Collectors(java.util.stream.Collectors) Value(org.spongepowered.api.data.value.Value) SpongeEntitySnapshot(org.spongepowered.common.entity.SpongeEntitySnapshot) Player(net.minecraft.world.entity.player.Player) EntityBridge(org.spongepowered.common.bridge.world.entity.EntityBridge) Keys(org.spongepowered.api.data.Keys) Entity(net.minecraft.world.entity.Entity) DataProviderRegistrator(org.spongepowered.common.data.provider.DataProviderRegistrator) EntityAccessor(org.spongepowered.common.accessor.world.entity.EntityAccessor) VecHelper(org.spongepowered.common.util.VecHelper) ResourceKey(org.spongepowered.api.ResourceKey) SpongeTicks(org.spongepowered.common.util.SpongeTicks) EntityAccessor(org.spongepowered.common.accessor.world.entity.EntityAccessor) LivingEntity(net.minecraft.world.entity.LivingEntity) Entity(net.minecraft.world.entity.Entity) Player(net.minecraft.world.entity.player.Player) EntityMaxAirBridge(org.spongepowered.common.bridge.world.entity.EntityMaxAirBridge) SpongeEntityArchetype(org.spongepowered.common.entity.SpongeEntityArchetype) LivingEntity(net.minecraft.world.entity.LivingEntity) SpongeEntitySnapshot(org.spongepowered.common.entity.SpongeEntitySnapshot) SpongeTicks(org.spongepowered.common.util.SpongeTicks)

Example 5 with Ticks

use of org.spongepowered.api.util.Ticks in project SpongeCommon by SpongePowered.

the class SpongePotionBuilder method buildContent.

@Override
protected Optional<PotionEffect> buildContent(final DataView container) throws InvalidDataException {
    checkNotNull(container);
    if (!container.contains(Constants.Item.Potions.POTION_TYPE) || !container.contains(Constants.Item.Potions.POTION_DURATION) || !container.contains(Constants.Item.Potions.POTION_AMPLIFIER) || !container.contains(Constants.Item.Potions.POTION_AMBIANCE) || !container.contains(Constants.Item.Potions.POTION_SHOWS_PARTICLES)) {
        return Optional.empty();
    }
    final String effectName = container.getString(Constants.Item.Potions.POTION_TYPE).get();
    final Optional<PotionEffectType> optional = Sponge.game().registry(RegistryTypes.POTION_EFFECT_TYPE).findValue(ResourceKey.resolve(effectName));
    if (!optional.isPresent()) {
        throw new InvalidDataException("The container has an invalid potion type name: " + effectName);
    }
    final Ticks duration = Ticks.of(container.getInt(Constants.Item.Potions.POTION_DURATION).get());
    final int amplifier = container.getInt(Constants.Item.Potions.POTION_AMPLIFIER).get();
    final boolean ambience = container.getBoolean(Constants.Item.Potions.POTION_AMBIANCE).get();
    final boolean particles = container.getBoolean(Constants.Item.Potions.POTION_SHOWS_PARTICLES).get();
    final PotionEffect.Builder builder = new SpongePotionBuilder();
    return Optional.of(builder.potionType(optional.get()).showParticles(particles).duration(duration).amplifier(amplifier).ambient(ambience).build());
}
Also used : PotionEffect(org.spongepowered.api.effect.potion.PotionEffect) PotionEffectType(org.spongepowered.api.effect.potion.PotionEffectType) Ticks(org.spongepowered.api.util.Ticks) InvalidDataException(org.spongepowered.api.data.persistence.InvalidDataException)

Aggregations

Ticks (org.spongepowered.api.util.Ticks)8 CauseStackManager (org.spongepowered.api.event.CauseStackManager)6 ItemStackSnapshot (org.spongepowered.api.item.inventory.ItemStackSnapshot)6 HandType (org.spongepowered.api.data.type.HandType)5 UseItemStackEvent (org.spongepowered.api.event.item.inventory.UseItemStackEvent)4 Inject (org.spongepowered.asm.mixin.injection.Inject)3 Redirect (org.spongepowered.asm.mixin.injection.Redirect)3 Collectors (java.util.stream.Collectors)1 GsonComponentSerializer (net.kyori.adventure.text.serializer.gson.GsonComponentSerializer)1 Entity (net.minecraft.world.entity.Entity)1 LivingEntity (net.minecraft.world.entity.LivingEntity)1 Player (net.minecraft.world.entity.player.Player)1 ResourceKey (org.spongepowered.api.ResourceKey)1 DataTransactionResult (org.spongepowered.api.data.DataTransactionResult)1 Keys (org.spongepowered.api.data.Keys)1 Transaction (org.spongepowered.api.data.Transaction)1 InvalidDataException (org.spongepowered.api.data.persistence.InvalidDataException)1 Value (org.spongepowered.api.data.value.Value)1 PotionEffect (org.spongepowered.api.effect.potion.PotionEffect)1 PotionEffectType (org.spongepowered.api.effect.potion.PotionEffectType)1