diff --git a/src/main/java/org/spongepowered/common/bridge/explosives/FusedExplosiveBridge.java b/src/main/java/org/spongepowered/common/bridge/explosives/FusedExplosiveBridge.java index 659d4eb9137..e0625b4da19 100644 --- a/src/main/java/org/spongepowered/common/bridge/explosives/FusedExplosiveBridge.java +++ b/src/main/java/org/spongepowered/common/bridge/explosives/FusedExplosiveBridge.java @@ -34,6 +34,8 @@ public interface FusedExplosiveBridge { + boolean bridge$isPrimed(); + int bridge$getFuseDuration(); void bridge$setFuseDuration(int fuseTicks); diff --git a/src/main/java/org/spongepowered/common/data/provider/entity/FireworkRocketData.java b/src/main/java/org/spongepowered/common/data/provider/entity/FireworkRocketData.java index 840d8545845..1164c43f07e 100644 --- a/src/main/java/org/spongepowered/common/data/provider/entity/FireworkRocketData.java +++ b/src/main/java/org/spongepowered/common/data/provider/entity/FireworkRocketData.java @@ -24,18 +24,14 @@ */ package org.spongepowered.common.data.provider.entity; -import com.google.common.collect.ImmutableList; -import net.minecraft.core.component.DataComponents; import net.minecraft.world.entity.projectile.FireworkRocketEntity; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.component.Fireworks; import org.spongepowered.api.data.Keys; -import org.spongepowered.common.accessor.world.entity.EntityAccessor; -import org.spongepowered.common.accessor.world.entity.projectile.FireworkRocketEntityAccessor; import org.spongepowered.common.data.provider.DataProviderRegistrator; import org.spongepowered.common.util.FireworkUtil; import org.spongepowered.common.util.SpongeTicks; +import java.util.OptionalInt; + public final class FireworkRocketData { private FireworkRocketData() { @@ -47,27 +43,22 @@ public static void register(final DataProviderRegistrator registrator) { .asMutable(FireworkRocketEntity.class) .create(Keys.FIREWORK_EFFECTS) .get(h -> FireworkUtil.getFireworkEffects(h).orElse(null)) - .set(FireworkUtil::setFireworkEffects) - .resetOnDelete(ImmutableList.of()) + .setAnd(FireworkUtil::setFireworkEffects) + .deleteAnd(FireworkUtil::removeFireworkEffects) .create(Keys.FIREWORK_FLIGHT_MODIFIER) .get(h -> { - final ItemStack item = FireworkUtil.getItem(h); - final Fireworks fireworks = item.get(DataComponents.FIREWORKS); - if (fireworks == null) { + final OptionalInt modifier = FireworkUtil.getFlightModifier(h); + if (modifier.isEmpty()) { return null; } - return new SpongeTicks(fireworks.flightDuration()); + return new SpongeTicks(modifier.getAsInt()); }) .setAnd((h, v) -> { final int ticks = SpongeTicks.toSaturatedIntOrInfinite(v); if (v.isInfinite() || ticks < 0 || ticks > Byte.MAX_VALUE) { return false; } - final ItemStack item = FireworkUtil.getItem(h); - final Fireworks fireworks = item.get(DataComponents.FIREWORKS); - item.set(DataComponents.FIREWORKS, new Fireworks((int) v.ticks(), fireworks.explosions())); - ((FireworkRocketEntityAccessor) h).accessor$lifetime(10 * ticks + ((EntityAccessor) h).accessor$random().nextInt(6) + ((EntityAccessor) h).accessor$random().nextInt(7)); - return true; + return FireworkUtil.setFlightModifier(h, ticks); }); } // @formatter:on diff --git a/src/main/java/org/spongepowered/common/data/provider/entity/FusedExplosiveData.java b/src/main/java/org/spongepowered/common/data/provider/entity/FusedExplosiveData.java index a320ae9d0a8..0444c5e2d14 100644 --- a/src/main/java/org/spongepowered/common/data/provider/entity/FusedExplosiveData.java +++ b/src/main/java/org/spongepowered/common/data/provider/entity/FusedExplosiveData.java @@ -39,11 +39,13 @@ private FusedExplosiveData() { public static void register(final DataProviderRegistrator registrator) { registrator .asMutable(FusedExplosive.class) + .create(Keys.IS_PRIMED) + .get(h -> ((FusedExplosiveBridge) h).bridge$isPrimed()) .create(Keys.FUSE_DURATION) .get(h -> new SpongeTicks(((FusedExplosiveBridge) h).bridge$getFuseDuration())) .setAnd((h, v) -> { final int ticks = SpongeTicks.toSaturatedIntOrInfinite(v); - if (!v.isInfinite() || ticks < 0) { + if (v.isInfinite() || ticks < 0) { return false; } ((FusedExplosiveBridge) h).bridge$setFuseDuration(ticks); @@ -56,8 +58,7 @@ public static void register(final DataProviderRegistrator registrator) { if (v.isInfinite() || ticks < 0) { return false; } - // TODO isPrimed on bridge? - if (h.primed().get()) { + if (((FusedExplosiveBridge) h).bridge$isPrimed()) { ((FusedExplosiveBridge) h).bridge$setFuseTicksRemaining(ticks); } return true; diff --git a/src/main/java/org/spongepowered/common/data/provider/entity/TNTData.java b/src/main/java/org/spongepowered/common/data/provider/entity/TNTData.java index f17a33c896b..cac00f141a5 100644 --- a/src/main/java/org/spongepowered/common/data/provider/entity/TNTData.java +++ b/src/main/java/org/spongepowered/common/data/provider/entity/TNTData.java @@ -44,8 +44,6 @@ public static void register(final DataProviderRegistrator registrator) { .create(Keys.DETONATOR) .get(h -> (Living) h.getOwner()) .set((h, v) -> ((PrimedTntAccessor) h).accessor$owner((LivingEntity) v)) - .create(Keys.IS_PRIMED) - .get(h -> !h.isRemoved() && h.getFuse() > 0) .create(Keys.BLOCK_STATE) .get(h -> (BlockState) h.getBlockState()) .set((h, v) -> h.setBlockState((net.minecraft.world.level.block.state.BlockState) v)); diff --git a/src/main/java/org/spongepowered/common/data/provider/item/stack/FireworkItemStackData.java b/src/main/java/org/spongepowered/common/data/provider/item/stack/FireworkItemStackData.java index ad70e17c417..1c8fa062d82 100644 --- a/src/main/java/org/spongepowered/common/data/provider/item/stack/FireworkItemStackData.java +++ b/src/main/java/org/spongepowered/common/data/provider/item/stack/FireworkItemStackData.java @@ -29,6 +29,9 @@ import org.spongepowered.api.data.Keys; import org.spongepowered.common.data.provider.DataProviderRegistrator; import org.spongepowered.common.util.FireworkUtil; +import org.spongepowered.common.util.SpongeTicks; + +import java.util.OptionalInt; public final class FireworkItemStackData { @@ -37,14 +40,29 @@ private FireworkItemStackData() { // @formatter:off public static void register(final DataProviderRegistrator registrator) { - // TODO DataComponents.FIREWORKS - flight_duration registrator .asMutable(ItemStack.class) .create(Keys.FIREWORK_EFFECTS) .get(h -> FireworkUtil.getFireworkEffects(h).orElse(null)) - .set(FireworkUtil::setFireworkEffects) - .delete(FireworkUtil::removeFireworkEffects) - .supports(h -> h.getItem() == Items.FIREWORK_ROCKET || h.getItem() == Items.FIREWORK_STAR); + .setAnd(FireworkUtil::setFireworkEffects) + .deleteAnd(FireworkUtil::removeFireworkEffects) + .supports(h -> h.getItem() == Items.FIREWORK_ROCKET || h.getItem() == Items.FIREWORK_STAR) + .create(Keys.FIREWORK_FLIGHT_MODIFIER) + .get(h -> { + final OptionalInt modifier = FireworkUtil.getFlightModifier(h); + if (modifier.isEmpty()) { + return null; + } + return new SpongeTicks(modifier.getAsInt()); + }) + .setAnd((h, v) -> { + final int ticks = SpongeTicks.toSaturatedIntOrInfinite(v); + if (v.isInfinite() || ticks < 0 || ticks > Byte.MAX_VALUE) { + return false; + } + return FireworkUtil.setFlightModifier(h, ticks); + }) + .supports(h -> h.getItem() == Items.FIREWORK_ROCKET); } // @formatter:on } diff --git a/src/main/java/org/spongepowered/common/util/FireworkUtil.java b/src/main/java/org/spongepowered/common/util/FireworkUtil.java index 173abfa996c..eaec6d9ee22 100644 --- a/src/main/java/org/spongepowered/common/util/FireworkUtil.java +++ b/src/main/java/org/spongepowered/common/util/FireworkUtil.java @@ -32,37 +32,47 @@ import net.minecraft.world.item.component.Fireworks; import org.spongepowered.api.item.FireworkEffect; import org.spongepowered.api.item.ItemTypes; +import org.spongepowered.common.accessor.world.entity.EntityAccessor; import org.spongepowered.common.accessor.world.entity.projectile.FireworkRocketEntityAccessor; import org.spongepowered.common.item.SpongeItemStack; import java.util.Collections; import java.util.List; import java.util.Optional; +import java.util.OptionalInt; +import java.util.function.Function; public final class FireworkUtil { + public static boolean setFireworkEffects(final FireworkRocketEntity firework, final List effects) { + return FireworkUtil.updateFireworkRocketItem(firework, item -> FireworkUtil.setFireworkEffects(item, effects)); + } - public static boolean setFireworkEffects(final Object object, final List effects) { + public static boolean setFireworkEffects(final ItemStack item, final List effects) { if (effects.isEmpty()) { - return FireworkUtil.removeFireworkEffects(object); + return FireworkUtil.removeFireworkEffects(item); } - final ItemStack item = FireworkUtil.getItem(object); + if (item.isEmpty()) { return false; } if (item.getItem() == Items.FIREWORK_STAR) { - item.set(DataComponents.FIREWORK_EXPLOSION, (FireworkExplosion) (Object) effects.get(0)); + item.set(DataComponents.FIREWORK_EXPLOSION, (FireworkExplosion) (Object) effects.getFirst()); return true; } else if (item.getItem() == Items.FIREWORK_ROCKET) { final List mcEffects = effects.stream().map(FireworkExplosion.class::cast).toList(); item.update(DataComponents.FIREWORKS, new Fireworks(1, Collections.emptyList()), p -> new Fireworks(p.flightDuration(), mcEffects)); return true; } + return false; } - public static Optional> getFireworkEffects(final Object object) { - final ItemStack item = FireworkUtil.getItem(object); + public static Optional> getFireworkEffects(final FireworkRocketEntity firework) { + return FireworkUtil.getFireworkEffects(FireworkUtil.getItem(firework)); + } + + public static Optional> getFireworkEffects(final ItemStack item) { if (item.isEmpty()) { return Optional.empty(); } @@ -83,8 +93,11 @@ public static Optional> getFireworkEffects(final Object obj return Optional.of(List.of((FireworkEffect) (Object) fireworkExplosion)); } - public static boolean removeFireworkEffects(final Object object) { - final ItemStack item = FireworkUtil.getItem(object); + public static boolean removeFireworkEffects(final FireworkRocketEntity firework) { + return FireworkUtil.updateFireworkRocketItem(firework, FireworkUtil::removeFireworkEffects); + } + + public static boolean removeFireworkEffects(final ItemStack item) { if (item.isEmpty()) { return false; } @@ -103,23 +116,51 @@ public static boolean removeFireworkEffects(final Object object) { return false; } - public static ItemStack getItem(final FireworkRocketEntity firework) { - ItemStack item = firework.getEntityData().get(FireworkRocketEntityAccessor.accessor$DATA_ID_FIREWORKS_ITEM()); + public static boolean setFlightModifier(final FireworkRocketEntity firework, final int modifier) { + int lifetime = 10 * modifier + ((EntityAccessor) firework).accessor$random().nextInt(6) + ((EntityAccessor) firework).accessor$random().nextInt(7); + ((FireworkRocketEntityAccessor) firework).accessor$lifetime(lifetime); + return true; + } + + public static boolean setFlightModifier(final ItemStack item, final int modifier) { if (item.isEmpty()) { - item = (ItemStack) (Object) new SpongeItemStack.BuilderImpl().itemType(ItemTypes.FIREWORK_ROCKET).build(); - firework.getEntityData().set(FireworkRocketEntityAccessor.accessor$DATA_ID_FIREWORKS_ITEM(), item); + return false; } - return item; + + if (item.getItem() == Items.FIREWORK_ROCKET) { + item.update(DataComponents.FIREWORKS, new Fireworks(1, Collections.emptyList()), p -> new Fireworks(modifier, p.explosions())); + return true; + } + return false; + } + + public static OptionalInt getFlightModifier(final FireworkRocketEntity firework) { + return FireworkUtil.getFlightModifier(FireworkUtil.getItem(firework)); } - private static ItemStack getItem(final Object object) { - if (object instanceof ItemStack) { - return (ItemStack) object; + public static OptionalInt getFlightModifier(final ItemStack item) { + final Fireworks fireworks = item.get(DataComponents.FIREWORKS); + if (fireworks == null) { + return OptionalInt.empty(); + } + return OptionalInt.of(fireworks.flightDuration()); + } + + public static boolean updateFireworkRocketItem(final FireworkRocketEntity firework, final Function function) { + final ItemStack item = FireworkUtil.getItem(firework).copy(); + if (function.apply(item)) { + firework.getEntityData().set(FireworkRocketEntityAccessor.accessor$DATA_ID_FIREWORKS_ITEM(), item); + return true; } - if (object instanceof FireworkRocketEntity) { - return FireworkUtil.getItem((FireworkRocketEntity) object); + return false; + } + + public static ItemStack getItem(final FireworkRocketEntity firework) { + ItemStack item = firework.getEntityData().get(FireworkRocketEntityAccessor.accessor$DATA_ID_FIREWORKS_ITEM()); + if (item.isEmpty()) { + return (ItemStack) (Object) new SpongeItemStack.BuilderImpl().itemType(ItemTypes.FIREWORK_ROCKET).build(); } - return ItemStack.EMPTY; + return item; } private FireworkUtil() { diff --git a/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/entity/item/PrimedTntMixin_API.java b/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/entity/item/PrimedTntMixin_API.java index 4c2d9b2b75d..393c3a41755 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/entity/item/PrimedTntMixin_API.java +++ b/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/entity/item/PrimedTntMixin_API.java @@ -43,8 +43,8 @@ public abstract class PrimedTntMixin_API extends EntityMixin_API implements Prim @Override public void detonate() { - this.shadow$discard(); this.shadow$explode(); + this.shadow$discard(); } @Override diff --git a/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/entity/monster/CreeperMixin_API.java b/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/entity/monster/CreeperMixin_API.java index 6c9f31e89d2..7d38578ce20 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/entity/monster/CreeperMixin_API.java +++ b/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/entity/monster/CreeperMixin_API.java @@ -49,6 +49,7 @@ public void detonate() { final Set> values = super.api$getVanillaValues(); values.add(this.requireValue(Keys.FUSE_DURATION).asImmutable()); + values.add(this.requireValue(Keys.IS_PRIMED).asImmutable()); values.add(this.requireValue(Keys.IS_CHARGED).asImmutable()); values.add(this.requireValue(Keys.TICKS_REMAINING).asImmutable()); diff --git a/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/entity/projectile/FireworkRocketEntityMixin_API.java b/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/entity/projectile/FireworkRocketEntityMixin_API.java index ac21fff7c71..304d79b2767 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/entity/projectile/FireworkRocketEntityMixin_API.java +++ b/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/entity/projectile/FireworkRocketEntityMixin_API.java @@ -37,14 +37,11 @@ public abstract class FireworkRocketEntityMixin_API extends ProjectileMixin_API implements FireworkRocket { // @formatter:off - @Shadow private int life; - @Shadow private int lifetime; @Shadow protected abstract void shadow$explode(); // @formatter:on @Override public void detonate() { - this.life = this.lifetime + 1; this.shadow$explode(); } @@ -53,6 +50,7 @@ public void detonate() { final Set> values = super.api$getVanillaValues(); values.add(this.requireValue(Keys.FUSE_DURATION).asImmutable()); + values.add(this.requireValue(Keys.IS_PRIMED).asImmutable()); values.add(this.requireValue(Keys.TICKS_REMAINING).asImmutable()); this.getValue(Keys.EXPLOSION_RADIUS).map(Value::asImmutable).ifPresent(values::add); diff --git a/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/entity/vehicle/MinecartTNTMixin_API.java b/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/entity/vehicle/MinecartTNTMixin_API.java index ee926309b45..5ed1652b6e3 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/entity/vehicle/MinecartTNTMixin_API.java +++ b/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/entity/vehicle/MinecartTNTMixin_API.java @@ -46,6 +46,7 @@ public void detonate() { final Set> values = super.api$getVanillaValues(); values.add(this.requireValue(Keys.FUSE_DURATION).asImmutable()); + values.add(this.requireValue(Keys.IS_PRIMED).asImmutable()); values.add(this.requireValue(Keys.TICKS_REMAINING).asImmutable()); this.getValue(Keys.EXPLOSION_RADIUS).map(Value::asImmutable).ifPresent(values::add); diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/item/PrimedTntMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/item/PrimedTntMixin.java index 7e3354ea434..073e73fdac7 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/item/PrimedTntMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/item/PrimedTntMixin.java @@ -63,6 +63,7 @@ public abstract class PrimedTntMixin extends EntityMixin implements PrimedTntBri @Nullable private LivingEntity impl$detonator; private int bridge$explosionRadius = Constants.Entity.PrimedTNT.DEFAULT_EXPLOSION_RADIUS; private int bridge$fuseDuration = Constants.Entity.PrimedTNT.DEFAULT_FUSE_DURATION; + private boolean impl$postPrimeTriggered = false; @Override public void bridge$setDetonator(final LivingEntity detonator) { @@ -84,6 +85,11 @@ public abstract class PrimedTntMixin extends EntityMixin implements PrimedTntBri this.bridge$explosionRadius = radius == null ? Constants.Entity.PrimedTNT.DEFAULT_EXPLOSION_RADIUS : radius; } + @Override + public boolean bridge$isPrimed() { + return true; + } + @Override public int bridge$getFuseDuration() { return this.bridge$fuseDuration; @@ -91,6 +97,7 @@ public abstract class PrimedTntMixin extends EntityMixin implements PrimedTntBri @Override public void bridge$setFuseDuration(final int fuseTicks) { + this.shadow$setFuse(Math.max(this.shadow$getFuse() + fuseTicks - this.bridge$fuseDuration, 0)); this.bridge$fuseDuration = fuseTicks; } @@ -129,7 +136,8 @@ public abstract class PrimedTntMixin extends EntityMixin implements PrimedTntBri @Inject(method = "tick()V", at = @At("RETURN")) private void impl$updateTNTPushPrime(final CallbackInfo ci) { - if (this.shadow$getFuse() == this.bridge$fuseDuration - 1 && !this.shadow$level().isClientSide) { + if (!this.impl$postPrimeTriggered && !this.shadow$level().isClientSide) { + this.impl$postPrimeTriggered = true; try (final CauseStackManager.StackFrame frame = PhaseTracker.getCauseStackManager().pushCauseFrame()) { if (this.impl$detonator != null) { frame.pushCause(this.impl$detonator); @@ -139,5 +147,4 @@ public abstract class PrimedTntMixin extends EntityMixin implements PrimedTntBri } } } - } diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/monster/CreeperMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/monster/CreeperMixin.java index 76bdff39e87..d836d7e70dc 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/monster/CreeperMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/monster/CreeperMixin.java @@ -57,10 +57,10 @@ public abstract class CreeperMixin extends MonsterMixin implements FusedExplosiv @Shadow private int explosionRadius; @Shadow public abstract void shadow$ignite(); + @Shadow public abstract boolean shadow$isIgnited(); @Shadow public abstract int shadow$getSwellDir(); // @formatter:on - private int impl$fuseDuration = Constants.Entity.Creeper.FUSE_DURATION; private boolean impl$interactPrimeCancelled; private boolean impl$stateDirty; private boolean impl$detonationCancelled; @@ -77,14 +77,19 @@ public abstract class CreeperMixin extends MonsterMixin implements FusedExplosiv this.explosionRadius = radius == null ? Constants.Entity.Creeper.DEFAULT_EXPLOSION_RADIUS : radius; } + @Override + public boolean bridge$isPrimed() { + return this.shadow$isIgnited() || this.shadow$getSwellDir() == Constants.Entity.Creeper.STATE_PRIMED; + } + @Override public int bridge$getFuseDuration() { - return this.impl$fuseDuration; + return this.maxSwell; } @Override public void bridge$setFuseDuration(final int fuseTicks) { - this.impl$fuseDuration = fuseTicks; + this.maxSwell = fuseTicks; } @Override @@ -107,9 +112,8 @@ public abstract class CreeperMixin extends MonsterMixin implements FusedExplosiv if (this.shadow$level().isClientSide) { return; } - this.bridge$setFuseDuration(this.impl$fuseDuration); - final boolean isPrimed = this.shadow$getSwellDir() == Constants.Entity.Creeper.STATE_PRIMED; + final boolean isPrimed = this.bridge$isPrimed(); if (!isPrimed && state == Constants.Entity.Creeper.STATE_PRIMED && !this.bridge$shouldPrime()) { ci.cancel(); diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/projectile/FireworkRocketEntityMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/projectile/FireworkRocketEntityMixin.java index 221f8b7917b..9fb3c57f3c8 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/projectile/FireworkRocketEntityMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/projectile/FireworkRocketEntityMixin.java @@ -56,6 +56,11 @@ public abstract class FireworkRocketEntityMixin extends ProjectileMixin implemen private int impl$explosionRadius = Constants.Entity.Firework.DEFAULT_EXPLOSION_RADIUS; + @Override + public boolean bridge$isPrimed() { + return true; + } + @Override public int bridge$getFuseDuration() { return this.lifetime; diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/vehicle/MinecartTNTMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/vehicle/MinecartTNTMixin.java index 9a73dfd65c5..6c792215396 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/vehicle/MinecartTNTMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/vehicle/MinecartTNTMixin.java @@ -61,6 +61,8 @@ public abstract class MinecartTNTMixin extends AbstractMinecartMixin implements // @formatter:off @Shadow private int fuse; + @Shadow public abstract boolean shadow$isPrimed(); + @Shadow public abstract void shadow$primeFuse(); // @formatter:on @Nullable private Integer impl$explosionRadius = null; @@ -78,6 +80,11 @@ public abstract class MinecartTNTMixin extends AbstractMinecartMixin implements this.impl$explosionRadius = radius; } + @Override + public boolean bridge$isPrimed() { + return this.shadow$isPrimed(); + } + @Override public int bridge$getFuseDuration() { return this.impl$fuseDuration; @@ -85,6 +92,9 @@ public abstract class MinecartTNTMixin extends AbstractMinecartMixin implements @Override public void bridge$setFuseDuration(final int fuseTicks) { + if (this.shadow$isPrimed()) { + this.fuse = Math.max(this.fuse + fuseTicks - this.impl$fuseDuration, 0); + } this.impl$fuseDuration = fuseTicks; }