use of org.spongepowered.asm.mixin.injection.Redirect in project SpongeCommon by SpongePowered.
the class EnderMan_EndermanLeaveBlockGoalMixin method impl$onPlaceBlockCancel.
/**
* @reason Makes Endermen check for block changes before they can place their blocks.
* This allows plugins to cancel the event regardless without issue.
*/
@Redirect(method = "canPlaceBlock(Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/core/BlockPos;)Z", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/state/BlockState;isCollisionShapeFullBlock(Lnet/minecraft/world/level/BlockGetter;Lnet/minecraft/core/BlockPos;)Z"))
private boolean impl$onPlaceBlockCancel(BlockState blockState, BlockGetter blockReaderIn, BlockPos blockPosIn) {
if (blockState.isCollisionShapeFullBlock(blockReaderIn, blockPosIn)) {
// Sponge start
if (ShouldFire.CHANGE_BLOCK_EVENT_PRE) {
final ServerLocation location = ServerLocation.of((ServerWorld) blockReaderIn, blockPosIn.getX(), blockPosIn.getY(), blockPosIn.getZ());
final List<ServerLocation> list = new ArrayList<>(1);
list.add(location);
final Cause cause = PhaseTracker.getCauseStackManager().currentCause();
final ChangeBlockEvent.Pre event = SpongeEventFactory.createChangeBlockEventPre(cause, list, ((ServerWorld) this.enderman.level));
return !SpongeCommon.post(event);
}
// Sponge end
return true;
}
return false;
}
use of org.spongepowered.asm.mixin.injection.Redirect in project SpongeCommon by SpongePowered.
the class AbstractFurnaceBlockEntityMixin method impl$throwFuelEventIfOrShrink.
// @Formatter:on
// Shrink Fuel
@Redirect(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/item/ItemStack;shrink(I)V"))
private void impl$throwFuelEventIfOrShrink(final ItemStack itemStack, final int quantity) {
final Cause cause = PhaseTracker.getCauseStackManager().currentCause();
final ItemStackSnapshot fuel = ItemStackUtil.snapshotOf(itemStack);
final ItemStackSnapshot shrinkedFuel = ItemStackUtil.snapshotOf(ItemStackUtil.cloneDefensive(itemStack, itemStack.getCount() - 1));
final Transaction<ItemStackSnapshot> transaction = new Transaction<>(fuel, shrinkedFuel);
final AbstractCookingRecipe recipe = this.impl$getCurrentRecipe();
final CookingEvent.ConsumeFuel event = SpongeEventFactory.createCookingEventConsumeFuel(cause, (FurnaceBlockEntity) this, Optional.of(fuel), Optional.of((CookingRecipe) recipe), Collections.singletonList(transaction));
SpongeCommon.post(event);
if (event.isCancelled()) {
this.cookingTotalTime = 0;
return;
}
if (!transaction.isValid()) {
return;
}
if (transaction.custom().isPresent()) {
this.items.set(1, ItemStackUtil.fromSnapshotToNative(transaction.finalReplacement()));
} else {
// vanilla
itemStack.shrink(quantity);
}
}
use of org.spongepowered.asm.mixin.injection.Redirect in project SpongeCommon by SpongePowered.
the class CactusBlockMixin method impl$reAssignForBlockDamageSource.
@Redirect(method = "entityInside", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Entity;hurt(Lnet/minecraft/world/damagesource/DamageSource;F)Z"))
private boolean impl$reAssignForBlockDamageSource(final Entity self, final DamageSource source, float damage, final net.minecraft.world.level.block.state.BlockState state, final net.minecraft.world.level.Level world, final BlockPos pos, final Entity entity) {
if (world.isClientSide()) {
return entity.hurt(source, damage);
}
try {
final ServerLocation location = ServerLocation.of((ServerWorld) world, pos.getX(), pos.getY(), pos.getZ());
final MinecraftBlockDamageSource cactus = new MinecraftBlockDamageSource("cactus", location);
((DamageSourceBridge) (Object) cactus).bridge$setCactusSource();
return entity.hurt(DamageSource.CACTUS, damage);
} finally {
((DamageSourceBridge) source).bridge$setCactusSource();
}
}
use of org.spongepowered.asm.mixin.injection.Redirect in project SpongeCommon by SpongePowered.
the class FishingRodItemMixin method onNewEntityFishHook.
@Redirect(method = "use", at = @At(value = "NEW", target = "net/minecraft/world/entity/projectile/FishingHook"))
private FishingHook onNewEntityFishHook(Player p_i50220_1_, Level p_i50220_2_, int p_i50220_3_, int p_i50220_4_) {
// Use the fish hook we created for the event
FishingHook fishHook = this.impl$fishHook;
this.impl$fishHook = null;
return fishHook;
}
use of org.spongepowered.asm.mixin.injection.Redirect in project SpongeCommon by SpongePowered.
the class BoneMealItemMixin_Tracker method tracker$wrapGrowWithPhaseEntry.
/**
* @author gabizou - March 20th, 2019 - 1.12.2
* @reason To allow growing to be captured via bonemeal without
* explicitly attempting to capture the growth, we can enter an
* alternate phase blockState that will specifically track the block
* changes as growth, and therefor will be able to throw
* {@link ChangeBlockEvent.Grow} without specifying the cases
* where the phase blockState needs to throw the event during another
* phases's capturing.
*/
@SuppressWarnings({ "Duplicates" })
// @Group(name = "org.spongepowered.tracker:bonemeal", min = 1, max = 1)
@Redirect(method = "growCrop", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/BonemealableBlock;performBonemeal(Lnet/minecraft/server/level/ServerLevel;Ljava/util/Random;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;)V"), // Will be removed once the above github issue is resolved with a proper solution
require = 0, // Even though we're in a group, expecting this to succeed in forge environments will not work since there is a different mixin
expect = 0)
private static void tracker$wrapGrowWithPhaseEntry(final BonemealableBlock iGrowable, final ServerLevel worldIn, final Random rand, final BlockPos pos, final BlockState state, final ItemStack stack) {
if (((LevelBridge) worldIn).bridge$isFake() || !ShouldFire.CHANGE_BLOCK_EVENT_ALL) {
iGrowable.performBonemeal(worldIn, rand, pos, state);
return;
}
final PhaseContext<@NonNull ?> current = PhaseTracker.getInstance().getPhaseContext();
final boolean doesEvent = current.doesBlockEventTracking();
if (doesEvent) {
// We can enter the new phase state.
try (final GrowablePhaseContext context = BlockPhase.State.GROWING.createPhaseContext(PhaseTracker.SERVER).provideItem(stack).world(worldIn).block(state).pos(pos)) {
context.buildAndSwitch();
iGrowable.performBonemeal(worldIn, rand, pos, state);
}
}
}
Aggregations