Merge branch '1.15' of file://D:/Arclight into refactor/1.15

This commit is contained in:
IzzelAliz 2020-06-13 14:23:25 +08:00
commit 7591d9a7c0
159 changed files with 3656 additions and 626 deletions

View File

@ -0,0 +1,59 @@
package io.izzel.arclight.api;
import java.util.Objects;
public class ArclightVersion {
public static final ArclightVersion v1_14 = new ArclightVersion("1.14.4", 1140);
public static final ArclightVersion v1_15 = new ArclightVersion("1.15.2", 1152);
private final String name;
private final int num;
public ArclightVersion(String name, int num) {
this.name = name;
this.num = num;
}
public String getName() {
return name;
}
@Override
public String toString() {
return "ArclightVersion{" +
"name='" + name + '\'' +
", num=" + num +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ArclightVersion that = (ArclightVersion) o;
return num == that.num &&
Objects.equals(name, that.name);
}
@Override
public int hashCode() {
return Objects.hash(name, num);
}
private static ArclightVersion version;
public static void setVersion(ArclightVersion version) {
if (ArclightVersion.version != null) throw new IllegalStateException("Version is already set!");
if (version == null) throw new IllegalArgumentException("Version cannot be null!");
ArclightVersion.version = version;
}
public static boolean atLeast(ArclightVersion v) {
return v.num <= version.num;
}
public static boolean lesserThan(ArclightVersion v) {
return v.num > version.num;
}
}

View File

@ -20,14 +20,14 @@ apply plugin: 'idea'
apply plugin: 'io.izzel.arclight' apply plugin: 'io.izzel.arclight'
ext { ext {
minecraftVersion = '1.14.4' minecraftVersion = '1.15.2'
forgeVersion = '28.2.0' forgeVersion = '31.2.0'
} }
arclight { arclight {
mcVersion = minecraftVersion mcVersion = minecraftVersion
forgeVersion = project.ext.forgeVersion forgeVersion = project.ext.forgeVersion
bukkitVersion = 'v1_14_R1' bukkitVersion = 'v1_15_R1'
wipeVersion = true wipeVersion = true
reobfVersion = false reobfVersion = false
} }
@ -35,7 +35,7 @@ arclight {
sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = '1.8' sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = '1.8'
minecraft { minecraft {
mappings channel: 'stable', version: "58-$minecraftVersion" mappings channel: 'snapshot', version: "20200530-1.15.1"
accessTransformer = project.file('src/main/resources/META-INF/accesstransformer.cfg') accessTransformer = project.file('src/main/resources/META-INF/accesstransformer.cfg')
} }

View File

@ -0,0 +1,6 @@
package io.izzel.arclight.common.bridge.command;
public interface CommandNodeBridge {
void bridge$removeCommand(String name);
}

View File

@ -1,6 +1,7 @@
package io.izzel.arclight.common.bridge.command; package io.izzel.arclight.common.bridge.command;
import com.mojang.brigadier.tree.CommandNode; import com.mojang.brigadier.tree.CommandNode;
import org.bukkit.command.CommandSender;
public interface CommandSourceBridge { public interface CommandSourceBridge {
@ -9,4 +10,6 @@ public interface CommandSourceBridge {
void bridge$setCurrentCommand(CommandNode<?> node); void bridge$setCurrentCommand(CommandNode<?> node);
boolean bridge$hasPermission(int i, String bukkitPermission); boolean bridge$hasPermission(int i, String bukkitPermission);
CommandSender bridge$getBukkitSender();
} }

View File

@ -1,8 +1,11 @@
package io.izzel.arclight.common.bridge.entity; package io.izzel.arclight.common.bridge.entity;
import net.minecraft.util.math.BlockPos;
import org.bukkit.craftbukkit.v.entity.CraftEntity; import org.bukkit.craftbukkit.v.entity.CraftEntity;
public interface InternalEntityBridge { public interface InternalEntityBridge {
CraftEntity internal$getBukkitEntity(); CraftEntity internal$getBukkitEntity();
BlockPos internal$capturedPos();
} }

View File

@ -0,0 +1,6 @@
package io.izzel.arclight.common.bridge.inventory.container;
public interface SlotBridge {
void bridge$onSwapCraft(int numItemsCrafted);
}

View File

@ -1,5 +1,7 @@
package io.izzel.arclight.common.bridge.world; package io.izzel.arclight.common.bridge.world;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos;
import org.bukkit.craftbukkit.v.CraftServer; import org.bukkit.craftbukkit.v.CraftServer;
import org.bukkit.craftbukkit.v.CraftWorld; import org.bukkit.craftbukkit.v.CraftWorld;
import org.bukkit.generator.ChunkGenerator; import org.bukkit.generator.ChunkGenerator;
@ -19,4 +21,6 @@ public interface WorldBridge extends IWorldWriterBridge {
void bridge$setPopulating(boolean populating); void bridge$setPopulating(boolean populating);
ChunkGenerator bridge$getGenerator(); ChunkGenerator bridge$getGenerator();
TileEntity bridge$getTileEntity(BlockPos pos, boolean validate);
} }

View File

@ -8,6 +8,8 @@ public interface ChunkBridge {
Chunk bridge$getBukkitChunk(); Chunk bridge$getBukkitChunk();
void bridge$setBukkitChunk(Chunk chunk);
BlockState bridge$setType(BlockPos pos, BlockState state, boolean isMoving, boolean doPlace); BlockState bridge$setType(BlockPos pos, BlockState state, boolean isMoving, boolean doPlace);
boolean bridge$isMustNotSave(); boolean bridge$isMustNotSave();

View File

@ -1,7 +1,5 @@
package io.izzel.arclight.common.bridge.world.server; package io.izzel.arclight.common.bridge.world.server;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.objects.ObjectSortedSet;
import net.minecraft.util.math.ChunkPos; import net.minecraft.util.math.ChunkPos;
import net.minecraft.world.server.Ticket; import net.minecraft.world.server.Ticket;
import net.minecraft.world.server.TicketType; import net.minecraft.world.server.TicketType;
@ -18,7 +16,5 @@ public interface TicketManagerBridge {
void bridge$tick(); void bridge$tick();
Long2ObjectOpenHashMap<ObjectSortedSet<Ticket<?>>> bridge$getTickets();
<T> void bridge$removeAllTicketsFor(TicketType<T> ticketType, int ticketLevel, T ticketIdentifier); <T> void bridge$removeAllTicketsFor(TicketType<T> ticketType, int ticketLevel, T ticketIdentifier);
} }

View File

@ -5,6 +5,7 @@ import net.minecraft.block.AbstractButtonBlock;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.state.BooleanProperty;
import net.minecraft.util.Hand; import net.minecraft.util.Hand;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockRayTraceResult; import net.minecraft.util.math.BlockRayTraceResult;
@ -14,7 +15,9 @@ import org.bukkit.block.Block;
import org.bukkit.craftbukkit.v.block.CraftBlock; import org.bukkit.craftbukkit.v.block.CraftBlock;
import org.bukkit.event.block.BlockRedstoneEvent; import org.bukkit.event.block.BlockRedstoneEvent;
import org.bukkit.event.entity.EntityInteractEvent; import org.bukkit.event.entity.EntityInteractEvent;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@ -22,14 +25,18 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture; import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
import java.util.List; import java.util.List;
import java.util.Random;
@Mixin(AbstractButtonBlock.class) @Mixin(AbstractButtonBlock.class)
public class AbstractButtonBlockMixin { public class AbstractButtonBlockMixin {
@Inject(method = "onBlockActivated", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;I)Z")) // @formatter:off
@Shadow @Final public static BooleanProperty POWERED;
// @formatter:on
@Inject(method = "onBlockActivated", cancellable = true, at = @At(value = "HEAD"))
public void arclight$blockRedstone1(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn, BlockRayTraceResult hit, CallbackInfoReturnable<Boolean> cir) { public void arclight$blockRedstone1(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn, BlockRayTraceResult hit, CallbackInfoReturnable<Boolean> cir) {
boolean powered = state.get(AbstractButtonBlock.POWERED); if (!state.get(POWERED)) {
boolean powered = state.get(POWERED);
Block block = CraftBlock.at(worldIn, pos); Block block = CraftBlock.at(worldIn, pos);
int old = (powered) ? 15 : 0; int old = (powered) ? 15 : 0;
int current = (!powered) ? 15 : 0; int current = (!powered) ? 15 : 0;
@ -41,17 +48,6 @@ public class AbstractButtonBlockMixin {
cir.setReturnValue(true); cir.setReturnValue(true);
} }
} }
@Inject(method = "tick", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;I)Z"))
public void arclight$blockRedstone2(BlockState state, World worldIn, BlockPos pos, Random random, CallbackInfo ci) {
Block block = CraftBlock.at(worldIn, pos);
BlockRedstoneEvent event = new BlockRedstoneEvent(block, 15, 0);
Bukkit.getPluginManager().callEvent(event);
if (event.getNewCurrent() > 0) {
ci.cancel();
}
} }
@Inject(method = "checkPressed", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD, @Inject(method = "checkPressed", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD,

View File

@ -3,6 +3,8 @@ package io.izzel.arclight.common.mixin.core.block;
import io.izzel.arclight.common.bridge.block.BlockBridge; import io.izzel.arclight.common.bridge.block.BlockBridge;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.enchantment.Enchantments;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.item.ItemEntity; import net.minecraft.entity.item.ItemEntity;
import net.minecraft.item.BlockItemUseContext; import net.minecraft.item.BlockItemUseContext;
@ -17,6 +19,7 @@ import net.minecraft.world.World;
import net.minecraft.world.server.ServerWorld; import net.minecraft.world.server.ServerWorld;
import net.minecraft.world.storage.loot.LootContext; import net.minecraft.world.storage.loot.LootContext;
import net.minecraft.world.storage.loot.LootParameters; import net.minecraft.world.storage.loot.LootParameters;
import net.minecraftforge.common.extensions.IForgeBlock;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite; import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
@ -62,13 +65,15 @@ public abstract class BlockMixin implements BlockBridge {
* @reason * @reason
*/ */
@Overwrite @Overwrite
public static List<ItemStack> func_220077_a(BlockState state, ServerWorld worldIn, BlockPos pos, @Nullable TileEntity tileEntityIn, Entity entityIn, ItemStack stack) { public static List<ItemStack> getDrops(BlockState state, ServerWorld worldIn, BlockPos pos, @Nullable TileEntity tileEntityIn, Entity entityIn, ItemStack stack) {
LootContext.Builder lootcontext$builder = (new LootContext.Builder(worldIn)).withRandom(worldIn.rand).withParameter(LootParameters.POSITION, pos).withParameter(LootParameters.TOOL, stack).withNullableParameter(LootParameters.THIS_ENTITY, entityIn).withNullableParameter(LootParameters.BLOCK_ENTITY, tileEntityIn); LootContext.Builder lootcontext$builder = (new LootContext.Builder(worldIn)).withRandom(worldIn.rand).withParameter(LootParameters.POSITION, pos).withParameter(LootParameters.TOOL, stack).withNullableParameter(LootParameters.THIS_ENTITY, entityIn).withNullableParameter(LootParameters.BLOCK_ENTITY, tileEntityIn);
return state.getDrops(lootcontext$builder); return state.getDrops(lootcontext$builder);
} }
public int getExpDrop(BlockState blockState, World world, BlockPos blockPos, ItemStack itemStack) { public int getExpDrop(BlockState blockState, World world, BlockPos blockPos, ItemStack itemStack) {
return 0; int silkTouch = EnchantmentHelper.getEnchantmentLevel(Enchantments.SILK_TOUCH, itemStack);
int fortune = EnchantmentHelper.getEnchantmentLevel(Enchantments.FORTUNE, itemStack);
return ((IForgeBlock) this).getExpDrop(blockState, world, blockPos, fortune, silkTouch);
} }
@Override @Override

View File

@ -10,17 +10,11 @@ import org.bukkit.craftbukkit.v.event.CraftEventFactory;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(CactusBlock.class) @Mixin(CactusBlock.class)
public class CactusBlockMixin { public class CactusBlockMixin {
@Redirect(method = "tick", at = @At(value = "INVOKE", ordinal = 0, target = "Lnet/minecraft/world/World;setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;)Z"))
public boolean arclight$blockGrow(World world, BlockPos pos, BlockState state) {
return CraftEventFactory.handleBlockGrowEvent(world, pos, state);
}
@Inject(method = "onEntityCollision", at = @At("HEAD")) @Inject(method = "onEntityCollision", at = @At("HEAD"))
private void arclight$cactusDamage1(BlockState state, World worldIn, BlockPos pos, Entity entityIn, CallbackInfo ci) { private void arclight$cactusDamage1(BlockState state, World worldIn, BlockPos pos, Entity entityIn, CallbackInfo ci) {
CraftEventFactory.blockDamage = CraftBlock.at(worldIn, pos); CraftEventFactory.blockDamage = CraftBlock.at(worldIn, pos);

View File

@ -1,116 +0,0 @@
package io.izzel.arclight.common.mixin.core.block;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.ChorusFlowerBlock;
import net.minecraft.block.ChorusPlantBlock;
import net.minecraft.state.IntegerProperty;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IWorldReader;
import net.minecraft.world.World;
import net.minecraftforge.common.ForgeHooks;
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.Shadow;
import javax.annotation.Nullable;
import java.util.Random;
@Mixin(ChorusFlowerBlock.class)
public abstract class ChorusFlowerBlockMixin extends BlockMixin {
// @formatter:off
@Shadow @Final public static IntegerProperty AGE;
@Shadow @Final private ChorusPlantBlock field_196405_b;
@Shadow private static boolean areAllNeighborsEmpty(IWorldReader worldIn, BlockPos pos, @Nullable Direction excludingSide) { return false; }
@Shadow protected abstract void placeGrownFlower(World worldIn, BlockPos pos, int age);
@Shadow protected abstract void placeDeadFlower(World worldIn, BlockPos pos);
// @formatter:on
/**
* @author IzzelAliz
* @reason
*/
@Overwrite
public void tick(BlockState state, World worldIn, BlockPos pos, Random random) {
if (!state.isValidPosition(worldIn, pos)) {
worldIn.destroyBlock(pos, true);
} else {
BlockPos blockpos = pos.up();
if (worldIn.isAirBlock(blockpos) && blockpos.getY() < worldIn.getDimension().getHeight()) {
int i = state.get(AGE);
if (i < 5 && ForgeHooks.onCropsGrowPre(worldIn, blockpos, state, true)) {
boolean flag = false;
boolean flag1 = false;
BlockState blockstate = worldIn.getBlockState(pos.down());
Block block = blockstate.getBlock();
if (block == Blocks.END_STONE) {
flag = true;
} else if (block == this.field_196405_b) {
int j = 1;
for (int k = 0; k < 4; ++k) {
Block block1 = worldIn.getBlockState(pos.down(j + 1)).getBlock();
if (block1 != this.field_196405_b) {
if (block1 == Blocks.END_STONE) {
flag1 = true;
}
break;
}
++j;
}
if (j < 2 || j <= random.nextInt(flag1 ? 5 : 4)) {
flag = true;
}
} else if (blockstate.isAir(worldIn, pos.down())) {
flag = true;
}
if (flag && areAllNeighborsEmpty(worldIn, blockpos, (Direction) null) && worldIn.isAirBlock(pos.up(2))) {
if (CraftEventFactory.handleBlockSpreadEvent(worldIn, pos, pos.up(), state.with(ChorusFlowerBlock.AGE, i), 2)) {
worldIn.setBlockState(pos, this.field_196405_b.makeConnections(worldIn, pos), 2);
this.placeGrownFlower(worldIn, blockpos, i);
}
} else if (i < 4) {
int l = random.nextInt(4);
if (flag1) {
++l;
}
boolean flag2 = false;
for (int i1 = 0; i1 < l; ++i1) {
Direction direction = Direction.Plane.HORIZONTAL.random(random);
BlockPos blockpos1 = pos.offset(direction);
if (worldIn.isAirBlock(blockpos1) && worldIn.isAirBlock(blockpos1.down()) && areAllNeighborsEmpty(worldIn, blockpos1, direction.getOpposite())) {
if (CraftEventFactory.handleBlockSpreadEvent(worldIn, pos, blockpos1, state.with(ChorusFlowerBlock.AGE, i + 1), 2)) {
this.placeGrownFlower(worldIn, blockpos1, i + 1);
flag2 = true;
}
}
}
if (flag2) {
worldIn.setBlockState(pos, this.field_196405_b.makeConnections(worldIn, pos), 2);
} else {
if (CraftEventFactory.handleBlockGrowEvent(worldIn, pos, this.getDefaultState().with(ChorusFlowerBlock.AGE, 5), 2)) {
this.placeDeadFlower(worldIn, pos);
}
}
} else {
if (CraftEventFactory.handleBlockGrowEvent(worldIn, pos, this.getDefaultState().with(ChorusFlowerBlock.AGE, 5), 2)) {
this.placeDeadFlower(worldIn, pos);
}
}
ForgeHooks.onCropsGrowPost(worldIn, pos, state);
}
}
}
}
}

View File

@ -2,11 +2,15 @@ package io.izzel.arclight.common.mixin.core.block;
import io.izzel.arclight.common.mixin.core.inventory.InventoryMixin; import io.izzel.arclight.common.mixin.core.inventory.InventoryMixin;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.ComposterBlock;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IWorld; import net.minecraft.world.IWorld;
import org.bukkit.craftbukkit.v.inventory.CraftBlockInventoryHolder; import org.bukkit.craftbukkit.v.inventory.CraftBlockInventoryHolder;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@ -14,8 +18,30 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(targets = "net.minecraft.block.ComposterBlock$FullInventory") @Mixin(targets = "net.minecraft.block.ComposterBlock$FullInventory")
public abstract class ComposterBlock_FullInventoryMixin extends InventoryMixin { public abstract class ComposterBlock_FullInventoryMixin extends InventoryMixin {
// @formatter:off
@Shadow @Final private BlockState state;
@Shadow @Final private IWorld world;
@Shadow @Final private BlockPos pos;
@Shadow private boolean extracted;
// @formatter:on
@Inject(method = "<init>(Lnet/minecraft/block/BlockState;Lnet/minecraft/world/IWorld;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/item/ItemStack;)V", at = @At("RETURN")) @Inject(method = "<init>(Lnet/minecraft/block/BlockState;Lnet/minecraft/world/IWorld;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/item/ItemStack;)V", at = @At("RETURN"))
public void arclight$setOwner(BlockState blockState, IWorld world, BlockPos blockPos, ItemStack itemStack, CallbackInfo ci) { public void arclight$setOwner(BlockState blockState, IWorld world, BlockPos blockPos, ItemStack itemStack, CallbackInfo ci) {
this.setOwner(new CraftBlockInventoryHolder(world, blockPos, this)); this.setOwner(new CraftBlockInventoryHolder(world, blockPos, this));
} }
/**
* @author IzzelAliz
* @reason
*/
@Overwrite
public void markDirty() {
if (this.isEmpty()) {
ComposterBlock.clear(this.state, this.world, this.pos);
this.extracted = true;
} else {
this.world.setBlockState(this.pos, this.state, 3);
this.extracted = false;
}
}
} }

View File

@ -15,11 +15,6 @@ import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(CropsBlock.class) @Mixin(CropsBlock.class)
public class CropsBlockMixin { public class CropsBlockMixin {
@Redirect(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;I)Z"))
public boolean arclight$blockGrowTick(World world, BlockPos pos, BlockState newState, int flags) {
return CraftEventFactory.handleBlockGrowEvent(world, pos, newState, flags);
}
@Redirect(method = "grow(Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;)V", @Redirect(method = "grow(Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;)V",
at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;I)Z")) at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;I)Z"))
public boolean arclight$blockGrowGrow(World world, BlockPos pos, BlockState newState, int flags) { public boolean arclight$blockGrowGrow(World world, BlockPos pos, BlockState newState, int flags) {

View File

@ -9,17 +9,11 @@ import org.bukkit.craftbukkit.v.event.CraftEventFactory;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(FarmlandBlock.class) @Mixin(FarmlandBlock.class)
public abstract class FarmlandBlockMixin extends BlockMixin { public abstract class FarmlandBlockMixin extends BlockMixin {
@Redirect(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;I)Z"))
public boolean arclight$moistureChange(World world, BlockPos pos, BlockState newState, int flags) {
return CraftEventFactory.handleMoistureChangeEvent(world, pos, newState, flags);
}
@Inject(method = "turnToDirt", cancellable = true, at = @At("HEAD")) @Inject(method = "turnToDirt", cancellable = true, at = @At("HEAD"))
private static void arclight$blockFade(BlockState state, World worldIn, BlockPos pos, CallbackInfo ci) { private static void arclight$blockFade(BlockState state, World worldIn, BlockPos pos, CallbackInfo ci) {
if (CraftEventFactory.callBlockFadeEvent(worldIn, pos, Blocks.DIRT.getDefaultState()).isCancelled()) { if (CraftEventFactory.callBlockFadeEvent(worldIn, pos, Blocks.DIRT.getDefaultState()).isCancelled()) {

View File

@ -0,0 +1,39 @@
package io.izzel.arclight.common.mixin.core.block;
import net.minecraft.block.BlockState;
import net.minecraft.block.FenceGateBlock;
import net.minecraft.state.BooleanProperty;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import org.bukkit.Bukkit;
import org.bukkit.block.Block;
import org.bukkit.craftbukkit.v.block.CraftBlock;
import org.bukkit.event.block.BlockRedstoneEvent;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(FenceGateBlock.class)
public class FenceGateBlockMixin {
// @formatter:off
@Shadow @Final public static BooleanProperty POWERED;
// @formatter:on
@Redirect(method = "neighborChanged", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;isBlockPowered(Lnet/minecraft/util/math/BlockPos;)Z"))
private boolean arclight$blockRedstone(World world, BlockPos pos, BlockState state) {
boolean powered = world.isBlockPowered(pos);
boolean oldPowered = state.get(POWERED);
if (oldPowered != powered) {
int newPower = powered ? 15 : 0;
int oldPower = oldPowered ? 15 : 0;
Block bukkitBlock = CraftBlock.at(world, pos);
BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(bukkitBlock, oldPower, newPower);
Bukkit.getPluginManager().callEvent(eventRedstone);
return eventRedstone.getNewCurrent() > 0;
}
return powered;
}
}

View File

@ -55,25 +55,6 @@ public abstract class FireBlockMixin {
} }
} }
@Redirect(method = "tick", at = @At(value = "INVOKE", ordinal = 1, target = "Lnet/minecraft/world/World;setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;I)Z"))
public boolean arclight$fireSpread(World world, BlockPos mutablePos, BlockState newState, int flags,
BlockState state, World worldIn, BlockPos pos) {
if (world.getBlockState(mutablePos).getBlock() != Blocks.FIRE) {
if (!CraftEventFactory.callBlockIgniteEvent(world, mutablePos, pos).isCancelled()) {
return CraftEventFactory.handleBlockSpreadEvent(world, pos, mutablePos, newState, flags);
}
}
return false;
}
@Redirect(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;removeBlock(Lnet/minecraft/util/math/BlockPos;Z)Z"))
public boolean arclight$extinguish1(World world, BlockPos pos, boolean isMoving) {
if (!CraftEventFactory.callBlockFadeEvent(world, pos, Blocks.AIR.getDefaultState()).isCancelled()) {
world.removeBlock(pos, isMoving);
}
return false;
}
@Redirect(method = "onBlockAdded", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;removeBlock(Lnet/minecraft/util/math/BlockPos;Z)Z")) @Redirect(method = "onBlockAdded", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;removeBlock(Lnet/minecraft/util/math/BlockPos;Z)Z"))
public boolean arclight$extinguish2(World world, BlockPos pos, boolean isMoving) { public boolean arclight$extinguish2(World world, BlockPos pos, boolean isMoving) {
if (!CraftEventFactory.callBlockFadeEvent(world, pos, Blocks.AIR.getDefaultState()).isCancelled()) { if (!CraftEventFactory.callBlockFadeEvent(world, pos, Blocks.AIR.getDefaultState()).isCancelled()) {

View File

@ -0,0 +1,19 @@
package io.izzel.arclight.common.mixin.core.block;
import net.minecraft.block.JukeboxBlock;
import net.minecraft.item.ItemStack;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.ModifyArg;
@Mixin(JukeboxBlock.class)
public class JukeBoxBlockMixin {
@ModifyArg(method = "insertRecord", index = 1, at = @At(value = "INVOKE", target = "Lnet/minecraft/tileentity/JukeboxTileEntity;setRecord(Lnet/minecraft/item/ItemStack;)V"))
private ItemStack arclight$oneItem(ItemStack stack) {
if (!stack.isEmpty()) {
stack.setCount(1);
}
return stack;
}
}

View File

@ -0,0 +1,31 @@
package io.izzel.arclight.common.mixin.core.block;
import io.izzel.arclight.common.bridge.world.WorldBridge;
import net.minecraft.block.BlockState;
import net.minecraft.block.LecternBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.LecternTileEntity;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
@Mixin(LecternBlock.class)
public class LecternBlockMixin {
@Redirect(method = "dropBook", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;getTileEntity(Lnet/minecraft/util/math/BlockPos;)Lnet/minecraft/tileentity/TileEntity;"))
private TileEntity arclight$noValidate(World world, BlockPos pos) {
return ((WorldBridge) world).bridge$getTileEntity(pos, false);
}
@Inject(method = "dropBook", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", target = "Lnet/minecraft/util/Direction;getXOffset()I"))
private void arclight$returnIfEmpty(BlockState state, World worldIn, BlockPos pos, CallbackInfo ci, TileEntity tileEntity, LecternTileEntity lecternTileEntity, Direction direction, ItemStack itemStack) {
if (itemStack.isEmpty()) ci.cancel();
}
}

View File

@ -2,27 +2,19 @@ package io.izzel.arclight.common.mixin.core.block;
import io.izzel.arclight.common.bridge.block.NetherPortalBlockBridge; import io.izzel.arclight.common.bridge.block.NetherPortalBlockBridge;
import io.izzel.arclight.common.bridge.entity.EntityBridge; import io.izzel.arclight.common.bridge.entity.EntityBridge;
import io.izzel.arclight.common.bridge.entity.EntityTypeBridge;
import io.izzel.arclight.common.bridge.world.WorldBridge; import io.izzel.arclight.common.bridge.world.WorldBridge;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.NetherPortalBlock; import net.minecraft.block.NetherPortalBlock;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.SpawnReason;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.world.IWorld; import net.minecraft.world.IWorld;
import net.minecraft.world.World; import net.minecraft.world.World;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.event.entity.CreatureSpawnEvent;
import org.bukkit.event.entity.EntityPortalEnterEvent; import org.bukkit.event.entity.EntityPortalEnterEvent;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture; import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
@ -30,11 +22,6 @@ import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
@Mixin(NetherPortalBlock.class) @Mixin(NetherPortalBlock.class)
public class NetherPortalBlockMixin { public class NetherPortalBlockMixin {
@Redirect(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/EntityType;spawn(Lnet/minecraft/world/World;Lnet/minecraft/nbt/CompoundNBT;Lnet/minecraft/util/text/ITextComponent;Lnet/minecraft/entity/player/PlayerEntity;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/entity/SpawnReason;ZZ)Lnet/minecraft/entity/Entity;"))
public Entity arclight$spawn(EntityType<?> entityType, World worldIn, CompoundNBT compound, ITextComponent customName, PlayerEntity playerIn, BlockPos pos, SpawnReason reason, boolean flag, boolean flag1) {
return ((EntityTypeBridge<?>) entityType).bridge$spawnCreature(worldIn, compound, customName, playerIn, pos, reason, flag, flag1, CreatureSpawnEvent.SpawnReason.NETHER_PORTAL);
}
@Inject(method = "trySpawnPortal", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD, @Inject(method = "trySpawnPortal", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD,
at = @At(value = "INVOKE", target = "Lnet/minecraft/block/NetherPortalBlock$Size;placePortalBlocks()V")) at = @At(value = "INVOKE", target = "Lnet/minecraft/block/NetherPortalBlock$Size;placePortalBlocks()V"))
public void arclight$spawnPortal(IWorld worldIn, BlockPos pos, CallbackInfoReturnable<Boolean> cir, NetherPortalBlock.Size size) { public void arclight$spawnPortal(IWorld worldIn, BlockPos pos, CallbackInfoReturnable<Boolean> cir, NetherPortalBlock.Size size) {

View File

@ -22,22 +22,22 @@ public abstract class NoteBlockMixin {
@Redirect(method = "neighborChanged", at = @At(value = "INVOKE", target = "Lnet/minecraft/block/NoteBlock;triggerNote(Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;)V")) @Redirect(method = "neighborChanged", at = @At(value = "INVOKE", target = "Lnet/minecraft/block/NoteBlock;triggerNote(Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;)V"))
public void arclight$callNote1(NoteBlock noteBlock, World worldIn, BlockPos pos, BlockState blockState) { public void arclight$callNote1(NoteBlock noteBlock, World worldIn, BlockPos pos, BlockState blockState) {
this.triggerNote(worldIn, pos, blockState); this.play(worldIn, pos, blockState);
} }
@Redirect(method = "onBlockActivated", at = @At(value = "INVOKE", target = "Lnet/minecraft/block/NoteBlock;triggerNote(Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;)V")) @Redirect(method = "onBlockActivated", at = @At(value = "INVOKE", target = "Lnet/minecraft/block/NoteBlock;triggerNote(Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;)V"))
public void arclight$callNote2(NoteBlock noteBlock, World worldIn, BlockPos pos, BlockState blockState) { public void arclight$callNote2(NoteBlock noteBlock, World worldIn, BlockPos pos, BlockState blockState) {
this.triggerNote(worldIn, pos, blockState); this.play(worldIn, pos, blockState);
} }
@Redirect(method = "onBlockClicked", at = @At(value = "INVOKE", target = "Lnet/minecraft/block/NoteBlock;triggerNote(Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;)V")) @Redirect(method = "onBlockClicked", at = @At(value = "INVOKE", target = "Lnet/minecraft/block/NoteBlock;triggerNote(Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;)V"))
public void arclight$callNote3(NoteBlock noteBlock, World worldIn, BlockPos pos, BlockState blockState) { public void arclight$callNote3(NoteBlock noteBlock, World worldIn, BlockPos pos, BlockState blockState) {
this.triggerNote(worldIn, pos, blockState); this.play(worldIn, pos, blockState);
} }
private transient BlockState arclight$state; private transient BlockState arclight$state;
private void triggerNote(World worldIn, BlockPos pos, BlockState state) { private void play(World worldIn, BlockPos pos, BlockState state) {
arclight$state = state; arclight$state = state;
this.triggerNote(worldIn, pos); this.triggerNote(worldIn, pos);
arclight$state = null; arclight$state = null;

View File

@ -2,17 +2,13 @@ package io.izzel.arclight.common.mixin.core.block;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.PistonBlock; import net.minecraft.block.PistonBlock;
import net.minecraft.block.state.PistonBlockStructureHelper;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World; import net.minecraft.world.World;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.craftbukkit.v.block.CraftBlock; import org.bukkit.craftbukkit.v.block.CraftBlock;
import org.bukkit.event.block.BlockPistonEvent;
import org.bukkit.event.block.BlockPistonExtendEvent;
import org.bukkit.event.block.BlockPistonRetractEvent; import org.bukkit.event.block.BlockPistonRetractEvent;
import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
@ -20,12 +16,8 @@ import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture; import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
import java.util.AbstractList;
import java.util.List;
@Mixin(PistonBlock.class) @Mixin(PistonBlock.class)
public class PistonBlockMixin { public class PistonBlockMixin {
@ -44,54 +36,4 @@ public class PistonBlockMixin {
} }
} }
} }
@Inject(method = "doMove", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD,
at = @At(value = "INVOKE_ASSIGN", remap = false, target = "Lcom/google/common/collect/Sets;newHashSet(Ljava/lang/Iterable;)Ljava/util/HashSet;"))
public void arclight$pistonAction(World worldIn, BlockPos pos, Direction directionIn, boolean extending, CallbackInfoReturnable<Boolean> cir,
BlockPos blockPos, PistonBlockStructureHelper helper) {
final Block craftBlock = CraftBlock.at(worldIn, pos);
final List<BlockPos> moved = helper.getBlocksToMove();
final List<BlockPos> broken = helper.getBlocksToDestroy();
class BlockList extends AbstractList<Block> {
@Override
public int size() {
return moved.size() + broken.size();
}
@Override
public org.bukkit.block.Block get(int index) {
if (index >= size() || index < 0) {
throw new ArrayIndexOutOfBoundsException(index);
}
BlockPos pos = index < moved.size() ? moved.get(index) : broken.get(index - moved.size());
return craftBlock.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ());
}
}
List<Block> blocks = new BlockList();
Direction direction = extending ? directionIn : directionIn.getOpposite();
BlockPistonEvent event;
if (extending) {
event = new BlockPistonExtendEvent(craftBlock, blocks, CraftBlock.notchToBlockFace(direction));
} else {
event = new BlockPistonRetractEvent(craftBlock, blocks, CraftBlock.notchToBlockFace(direction));
}
Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) {
for (BlockPos b : broken) {
worldIn.notifyBlockUpdate(b, Blocks.AIR.getDefaultState(), worldIn.getBlockState(b), 3);
}
for (BlockPos b : moved) {
worldIn.notifyBlockUpdate(b, Blocks.AIR.getDefaultState(), worldIn.getBlockState(b), 3);
b = b.offset(direction);
worldIn.notifyBlockUpdate(b, Blocks.AIR.getDefaultState(), worldIn.getBlockState(b), 3);
}
cir.setReturnValue(false);
}
}
} }

View File

@ -15,7 +15,7 @@ import org.spongepowered.asm.mixin.injection.ModifyVariable;
@Mixin(RedstoneWireBlock.class) @Mixin(RedstoneWireBlock.class)
public class RedstoneWireBlockMixin { public class RedstoneWireBlockMixin {
@ModifyVariable(method = "func_212568_b", name = "l", index = 8, at = @At(value = "JUMP", ordinal = 0, opcode = Opcodes.IF_ICMPEQ)) @ModifyVariable(method = "updatePower", name = "l", index = 8, at = @At(value = "JUMP", ordinal = 0, opcode = Opcodes.IF_ICMPEQ))
public int arclight$blockRedstone(int l, World world, BlockPos pos, BlockState state) { public int arclight$blockRedstone(int l, World world, BlockPos pos, BlockState state) {
int i = state.get(RedstoneWireBlock.POWER); int i = state.get(RedstoneWireBlock.POWER);
if (i != l) { if (i != l) {

View File

@ -1,33 +1,18 @@
package io.izzel.arclight.common.mixin.core.block; package io.izzel.arclight.common.mixin.core.block;
import net.minecraft.block.BlockState;
import net.minecraft.block.SaplingBlock; import net.minecraft.block.SaplingBlock;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IWorld;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.TreeType;
import org.bukkit.craftbukkit.v.block.CraftBlock;
import org.bukkit.craftbukkit.v.util.BlockStateListPopulator;
import org.bukkit.event.world.StructureGrowEvent;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import io.izzel.arclight.common.mod.util.ArclightBlockPopulator;
import io.izzel.arclight.common.mod.util.ArclightCaptures;
import java.util.List;
import java.util.Random;
// todo Re-implement this
@Mixin(SaplingBlock.class) @Mixin(SaplingBlock.class)
public abstract class SaplingBlockMixin { public abstract class SaplingBlockMixin {
// @formatter:off // @formatter:off
@Shadow public abstract void grow(IWorld worldIn, BlockPos pos, BlockState state, Random rand); //@Shadow public abstract void grow(IWorld worldIn, BlockPos pos, BlockState state, Random rand);
// @formatter:on // @formatter:on
@SuppressWarnings("unchecked") // @SuppressWarnings("unchecked")
/*
@Redirect(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/block/SaplingBlock;grow(Lnet/minecraft/world/IWorld;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;Ljava/util/Random;)V")) @Redirect(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/block/SaplingBlock;grow(Lnet/minecraft/world/IWorld;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;Ljava/util/Random;)V"))
public void arclight$treeGrow(SaplingBlock saplingBlock, IWorld worldIn, BlockPos pos, BlockState state, Random rand) { public void arclight$treeGrow(SaplingBlock saplingBlock, IWorld worldIn, BlockPos pos, BlockState state, Random rand) {
BlockStateListPopulator populator = new ArclightBlockPopulator(worldIn.getWorld()); BlockStateListPopulator populator = new ArclightBlockPopulator(worldIn.getWorld());
@ -41,5 +26,5 @@ public abstract class SaplingBlockMixin {
populator.updateList(); populator.updateList();
} }
} }
} }*/
} }

View File

@ -1,8 +1,9 @@
package io.izzel.arclight.common.mixin.bukkit; package io.izzel.arclight.common.mixin.core.command;
import com.mojang.brigadier.tree.ArgumentCommandNode; import com.mojang.brigadier.tree.ArgumentCommandNode;
import com.mojang.brigadier.tree.CommandNode; import com.mojang.brigadier.tree.CommandNode;
import com.mojang.brigadier.tree.LiteralCommandNode; import com.mojang.brigadier.tree.LiteralCommandNode;
import io.izzel.arclight.common.bridge.command.CommandNodeBridge;
import io.izzel.arclight.common.bridge.command.CommandSourceBridge; import io.izzel.arclight.common.bridge.command.CommandSourceBridge;
import net.minecraft.command.CommandSource; import net.minecraft.command.CommandSource;
import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Final;
@ -15,14 +16,14 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.Map; import java.util.Map;
import java.util.function.Predicate; import java.util.function.Predicate;
@Mixin(CommandNode.class) @Mixin(value = CommandNode.class, remap = false)
public class CommandNodeMixin<S> { public class CommandNodeMixin<S> implements CommandNodeBridge {
// @formatter:off // @formatter:off
@Shadow(remap = false) private Map<String, CommandNode<S>> children; @Shadow private Map<String, CommandNode<S>> children;
@Shadow(remap = false) private Map<String, LiteralCommandNode<S>> literals; @Shadow private Map<String, LiteralCommandNode<S>> literals;
@Shadow(remap = false) private Map<String, ArgumentCommandNode<S, ?>> arguments; @Shadow private Map<String, ArgumentCommandNode<S, ?>> arguments;
@Shadow(remap = false) @Final private Predicate<S> requirement; @Shadow @Final private Predicate<S> requirement;
// @formatter:on // @formatter:on
public void removeCommand(String name) { public void removeCommand(String name) {
@ -31,7 +32,12 @@ public class CommandNodeMixin<S> {
arguments.remove(name); arguments.remove(name);
} }
@Inject(method = "canUse", remap = false, cancellable = true, at = @At("HEAD")) @Override
public void bridge$removeCommand(String name) {
removeCommand(name);
}
@Inject(method = "canUse", cancellable = true, at = @At("HEAD"))
public void on(S source, CallbackInfoReturnable<Boolean> cir) { public void on(S source, CallbackInfoReturnable<Boolean> cir) {
if (source instanceof CommandSource) { if (source instanceof CommandSource) {
try { try {

View File

@ -22,7 +22,7 @@ public abstract class CommandSourceMixin implements CommandSourceBridge {
// @formatter:off // @formatter:off
@Shadow @Final public ICommandSource source; @Shadow @Final public ICommandSource source;
@Shadow public abstract ServerWorld func_197023_e(); @Shadow public abstract ServerWorld getWorld();
@Shadow @Final private int permissionLevel; @Shadow @Final private int permissionLevel;
// @formatter:on // @formatter:on
@ -37,7 +37,7 @@ public abstract class CommandSourceMixin implements CommandSourceBridge {
public boolean hasPermission(int i, String bukkitPermission) { public boolean hasPermission(int i, String bukkitPermission) {
// World is null when loading functions // World is null when loading functions
return ((func_197023_e() == null || !((CraftServer) Bukkit.getServer()).ignoreVanillaPermissions) && this.permissionLevel >= i) || getBukkitSender().hasPermission(bukkitPermission); return ((getWorld() == null || !((CraftServer) Bukkit.getServer()).ignoreVanillaPermissions) && this.permissionLevel >= i) || getBukkitSender().hasPermission(bukkitPermission);
} }
@Override @Override
@ -58,4 +58,9 @@ public abstract class CommandSourceMixin implements CommandSourceBridge {
public CommandSender getBukkitSender() { public CommandSender getBukkitSender() {
return ((ICommandSourceBridge) this.source).bridge$getBukkitSender((CommandSource) (Object) this); return ((ICommandSourceBridge) this.source).bridge$getBukkitSender((CommandSource) (Object) this);
} }
@Override
public CommandSender bridge$getBukkitSender() {
return getBukkitSender();
}
} }

View File

@ -0,0 +1,39 @@
package io.izzel.arclight.common.mixin.core.command;
import com.mojang.brigadier.tree.CommandNode;
import com.mojang.brigadier.tree.RootCommandNode;
import io.izzel.arclight.common.bridge.command.CommandNodeBridge;
import io.izzel.arclight.common.bridge.entity.player.ServerPlayerEntityBridge;
import net.minecraft.command.CommandSource;
import net.minecraft.command.Commands;
import net.minecraft.command.ISuggestionProvider;
import net.minecraft.entity.player.ServerPlayerEntity;
import org.bukkit.Bukkit;
import org.bukkit.event.player.PlayerCommandSendEvent;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
import java.util.LinkedHashSet;
import java.util.Map;
@Mixin(Commands.class)
public class CommandsMixin {
@Inject(method = "send", locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", shift = At.Shift.AFTER, target = "Lnet/minecraft/command/Commands;commandSourceNodesToSuggestionNodes(Lcom/mojang/brigadier/tree/CommandNode;Lcom/mojang/brigadier/tree/CommandNode;Lnet/minecraft/command/CommandSource;Ljava/util/Map;)V"))
private void arclight$playerCommandSend(ServerPlayerEntity player, CallbackInfo ci, Map<CommandNode<CommandSource>, CommandNode<ISuggestionProvider>> map , RootCommandNode<ISuggestionProvider> node) {
LinkedHashSet<String> set = new LinkedHashSet<>();
for (CommandNode<ISuggestionProvider> child : node.getChildren()) {
set.add(child.getName());
}
PlayerCommandSendEvent event = new PlayerCommandSendEvent(((ServerPlayerEntityBridge) player).bridge$getBukkitEntity(), new LinkedHashSet<>(set));
Bukkit.getPluginManager().callEvent(event);
for (String s : set) {
if (!event.getCommands().contains(s)) {
((CommandNodeBridge) node).bridge$removeCommand(s);
}
}
}
}

View File

@ -0,0 +1,28 @@
package io.izzel.arclight.common.mixin.core.command.arguments;
import com.mojang.brigadier.StringReader;
import net.minecraft.command.arguments.BlockStateParser;
import net.minecraft.state.IProperty;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Mutable;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.LinkedHashMap;
import java.util.Map;
@Mixin(BlockStateParser.class)
public class BlockStateParserMixin {
// @formatter:off
@Shadow @Final @Mutable private Map<IProperty<?>, Comparable<?>> properties;
// @formatter:on
@Inject(method = "<init>", at = @At("RETURN"))
private void arclight$init(StringReader readerIn, boolean allowTags, CallbackInfo ci) {
this.properties = new LinkedHashMap<>(properties);
}
}

View File

@ -17,6 +17,6 @@ public class SummonCommandMixin {
@Inject(method = "summonEntity", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/server/ServerWorld;addLightningBolt(Lnet/minecraft/entity/effect/LightningBoltEntity;)V")) @Inject(method = "summonEntity", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/server/ServerWorld;addLightningBolt(Lnet/minecraft/entity/effect/LightningBoltEntity;)V"))
private static void arclight$strikeReason(CommandSource source, ResourceLocation type, Vec3d pos, CompoundNBT nbt, boolean randomizeProperties, CallbackInfoReturnable<Integer> cir) { private static void arclight$strikeReason(CommandSource source, ResourceLocation type, Vec3d pos, CompoundNBT nbt, boolean randomizeProperties, CallbackInfoReturnable<Integer> cir) {
((ServerWorldBridge) source.func_197023_e()).bridge$pushStrikeLightningCause(LightningStrikeEvent.Cause.COMMAND); ((ServerWorldBridge) source.getWorld()).bridge$pushStrikeLightningCause(LightningStrikeEvent.Cause.COMMAND);
} }
} }

View File

@ -7,10 +7,8 @@ import io.izzel.arclight.common.bridge.entity.LivingEntityBridge;
import io.izzel.arclight.common.bridge.entity.MobEntityBridge; import io.izzel.arclight.common.bridge.entity.MobEntityBridge;
import io.izzel.arclight.common.bridge.entity.player.ServerPlayerEntityBridge; import io.izzel.arclight.common.bridge.entity.player.ServerPlayerEntityBridge;
import io.izzel.arclight.common.bridge.world.WorldBridge; import io.izzel.arclight.common.bridge.world.WorldBridge;
import io.izzel.arclight.common.bridge.world.server.ServerWorldBridge;
import io.izzel.arclight.common.bridge.world.storage.SaveHandlerBridge; import io.izzel.arclight.common.bridge.world.storage.SaveHandlerBridge;
import io.izzel.arclight.common.mod.util.ArclightCaptures; import io.izzel.arclight.common.mod.util.ArclightCaptures;
import net.minecraft.block.pattern.BlockPattern;
import net.minecraft.command.CommandSource; import net.minecraft.command.CommandSource;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType; import net.minecraft.entity.EntityType;
@ -29,7 +27,6 @@ import net.minecraft.network.datasync.EntityDataManager;
import net.minecraft.scoreboard.Team; import net.minecraft.scoreboard.Team;
import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;
import net.minecraft.util.DamageSource; import net.minecraft.util.DamageSource;
import net.minecraft.util.Direction;
import net.minecraft.util.SoundEvent; import net.minecraft.util.SoundEvent;
import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
@ -38,11 +35,8 @@ import net.minecraft.util.math.Vec3d;
import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.ITextComponent;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraft.world.dimension.DimensionType; import net.minecraft.world.dimension.DimensionType;
import net.minecraft.world.gen.Heightmap;
import net.minecraft.world.server.ServerWorld; import net.minecraft.world.server.ServerWorld;
import net.minecraftforge.common.ForgeHooks;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Server; import org.bukkit.Server;
import org.bukkit.block.BlockFace; import org.bukkit.block.BlockFace;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
@ -58,7 +52,6 @@ import org.bukkit.event.entity.EntityCombustByBlockEvent;
import org.bukkit.event.entity.EntityCombustByEntityEvent; import org.bukkit.event.entity.EntityCombustByEntityEvent;
import org.bukkit.event.entity.EntityCombustEvent; import org.bukkit.event.entity.EntityCombustEvent;
import org.bukkit.event.entity.EntityDropItemEvent; import org.bukkit.event.entity.EntityDropItemEvent;
import org.bukkit.event.entity.EntityPortalEvent;
import org.bukkit.event.entity.EntityPoseChangeEvent; import org.bukkit.event.entity.EntityPoseChangeEvent;
import org.bukkit.event.hanging.HangingBreakByEntityEvent; import org.bukkit.event.hanging.HangingBreakByEntityEvent;
import org.bukkit.event.player.PlayerTeleportEvent; import org.bukkit.event.player.PlayerTeleportEvent;
@ -69,7 +62,6 @@ import org.bukkit.plugin.PluginManager;
import org.bukkit.projectiles.ProjectileSource; import org.bukkit.projectiles.ProjectileSource;
import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
@ -121,8 +113,6 @@ public abstract class EntityMixin implements InternalEntityBridge, EntityBridge,
@Shadow @Deprecated public boolean removed; @Shadow @Deprecated public boolean removed;
@Shadow @Nullable public abstract MinecraftServer getServer(); @Shadow @Nullable public abstract MinecraftServer getServer();
@Shadow public abstract Vec3d getMotion(); @Shadow public abstract Vec3d getMotion();
@Shadow public abstract Vec3d getLastPortalVec();
@Shadow public abstract Direction getTeleportDirection();
@Shadow public abstract EntityType<?> getType(); @Shadow public abstract EntityType<?> getType();
@Shadow public abstract void remove(boolean keepData); @Shadow public abstract void remove(boolean keepData);
@Shadow @Final protected Random rand; @Shadow @Final protected Random rand;
@ -176,11 +166,10 @@ public abstract class EntityMixin implements InternalEntityBridge, EntityBridge,
@Shadow public abstract int getEntityId(); @Shadow public abstract int getEntityId();
@Shadow @Nullable public abstract ITextComponent getCustomName(); @Shadow @Nullable public abstract ITextComponent getCustomName();
@Shadow protected abstract void applyEnchantments(LivingEntity entityLivingBaseIn, Entity entityIn); @Shadow protected abstract void applyEnchantments(LivingEntity entityLivingBaseIn, Entity entityIn);
@Shadow public abstract float getEyeHeight();
@Shadow @Nullable public abstract Entity changeDimension(DimensionType destination);
// @formatter:on // @formatter:on
@Shadow
public abstract float getEyeHeight();
private static final int CURRENT_LEVEL = 2; private static final int CURRENT_LEVEL = 2;
public boolean persist; public boolean persist;
public boolean valid; public boolean valid;
@ -452,6 +441,11 @@ public abstract class EntityMixin implements InternalEntityBridge, EntityBridge,
} }
} }
@Inject(method = "setPositionAndRotation", at = @At("RETURN"))
private void arclight$loadChunk(double x, double y, double z, float yaw, float pitch, CallbackInfo ci) {
this.world.getChunk((int)Math.floor(this.posX) >> 4, (int)Math.floor(this.posZ) >> 4);
}
@Inject(method = "writeUnlessRemoved", cancellable = true, at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/entity/Entity;getEntityString()Ljava/lang/String;")) @Inject(method = "writeUnlessRemoved", cancellable = true, at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/entity/Entity;getEntityString()Ljava/lang/String;"))
public void arclight$writeUnlessRemoved$persistCheck(CompoundNBT compound, CallbackInfoReturnable<Boolean> cir) { public void arclight$writeUnlessRemoved$persistCheck(CompoundNBT compound, CallbackInfoReturnable<Boolean> cir) {
if (!this.persist) if (!this.persist)
@ -520,7 +514,7 @@ public abstract class EntityMixin implements InternalEntityBridge, EntityBridge,
} }
if (bworld == null) { if (bworld == null) {
bworld = ((WorldBridge) ((CraftServer) server).getServer().func_71218_a(DimensionType.OVERWORLD)).bridge$getWorld(); bworld = ((WorldBridge) ((CraftServer) server).getServer().getWorld(DimensionType.OVERWORLD)).bridge$getWorld();
} }
setWorld(bworld == null ? null : ((CraftWorld) bworld).getHandle()); setWorld(bworld == null ? null : ((CraftWorld) bworld).getHandle());
@ -741,6 +735,15 @@ public abstract class EntityMixin implements InternalEntityBridge, EntityBridge,
private transient BlockPos arclight$tpPos; private transient BlockPos arclight$tpPos;
@Override
public BlockPos internal$capturedPos() {
try {
return arclight$tpPos;
} finally {
arclight$tpPos = null;
}
}
public Entity teleportTo(DimensionType type, BlockPos blockPos) { public Entity teleportTo(DimensionType type, BlockPos blockPos) {
arclight$tpPos = blockPos; arclight$tpPos = blockPos;
return changeDimension(type); return changeDimension(type);
@ -751,101 +754,4 @@ public abstract class EntityMixin implements InternalEntityBridge, EntityBridge,
return teleportTo(type, blockPos); return teleportTo(type, blockPos);
} }
/**
* @author IzzelAliz
* @reason
*/
@Overwrite
@Nullable
public Entity changeDimension(DimensionType destination) {
BlockPos location = arclight$tpPos;
arclight$tpPos = null;
if (!ForgeHooks.onTravelToDimension((Entity) (Object) this, destination)) return null;
if (!this.world.isRemote && !this.removed) {
this.world.getProfiler().startSection("changeDimension");
MinecraftServer minecraftserver = this.getServer();
DimensionType dimensiontype = this.dimension;
ServerWorld serverworld = minecraftserver.func_71218_a(dimensiontype);
ServerWorld serverworld1 = minecraftserver.func_71218_a(destination);
if (serverworld1 == null) {
return null;
}
// this.dimension = destination;
// this.detach();
this.world.getProfiler().startSection("reposition");
Vec3d vec3d = this.getMotion();
float f = 0.0F;
BlockPos blockpos = location;
if (blockpos == null) {
if (dimensiontype == DimensionType.THE_END && destination == DimensionType.OVERWORLD) {
blockpos = serverworld1.getHeight(Heightmap.Type.MOTION_BLOCKING_NO_LEAVES, serverworld1.getSpawnPoint());
} else if (destination == DimensionType.THE_END) {
blockpos = serverworld1.getSpawnCoordinate();
} else {
double movementFactor = serverworld.getDimension().getMovementFactor() / serverworld1.getDimension().getMovementFactor();
double d0 = this.posX * movementFactor;
double d1 = this.posZ * movementFactor;
double d3 = Math.min(-2.9999872E7D, serverworld1.getWorldBorder().minX() + 16.0D);
double d4 = Math.min(-2.9999872E7D, serverworld1.getWorldBorder().minZ() + 16.0D);
double d5 = Math.min(2.9999872E7D, serverworld1.getWorldBorder().maxX() - 16.0D);
double d6 = Math.min(2.9999872E7D, serverworld1.getWorldBorder().maxZ() - 16.0D);
d0 = MathHelper.clamp(d0, d3, d5);
d1 = MathHelper.clamp(d1, d4, d6);
Vec3d vec3d1 = this.getLastPortalVec();
blockpos = new BlockPos(d0, this.posY, d1);
BlockPattern.PortalInfo blockpattern$portalinfo = serverworld1.getDefaultTeleporter().placeInExistingPortal(blockpos, vec3d, this.getTeleportDirection(), vec3d1.x, vec3d1.y, (Object) this instanceof PlayerEntity);
if (blockpattern$portalinfo == null) {
return null;
}
blockpos = new BlockPos(blockpattern$portalinfo.pos);
vec3d = blockpattern$portalinfo.motion;
f = (float) blockpattern$portalinfo.rotation;
}
}
if (location == null) {
Location enter = this.getBukkitEntity().getLocation();
Location exit = new Location(((ServerWorldBridge) serverworld1).bridge$getWorld(), blockpos.getX(), blockpos.getY(), blockpos.getZ());
EntityPortalEvent event = new EntityPortalEvent(this.getBukkitEntity(), enter, exit);
event.getEntity().getServer().getPluginManager().callEvent(event);
if (event.isCancelled() || event.getTo() == null || event.getTo().getWorld() == null || !this.isAlive()) {
return null;
}
exit = event.getTo();
serverworld1 = ((CraftWorld) exit.getWorld()).getHandle();
blockpos = new BlockPos(exit.getX(), exit.getY(), exit.getZ());
}
this.dimension = destination;
this.detach();
this.world.getProfiler().endStartSection("reloading");
Entity entity = this.getType().create(serverworld1);
if (entity != null) {
entity.copyDataFromOld((Entity) (Object) this);
entity.moveToBlockPosAndAngles(blockpos, entity.rotationYaw + f, entity.rotationPitch);
entity.setMotion(vec3d);
serverworld1.func_217460_e(entity);
this.getBukkitEntity().setHandle(entity);
((EntityBridge) entity).bridge$setBukkitEntity(getBukkitEntity());
if ((Object) this instanceof MobEntity) {
((MobEntity) (Object) this).clearLeashed(true, false);
}
}
this.remove(false);
this.world.getProfiler().endSection();
serverworld.resetUpdateEntityTick();
serverworld1.resetUpdateEntityTick();
this.world.getProfiler().endSection();
return entity;
} else {
return null;
}
}
} }

View File

@ -0,0 +1,32 @@
package io.izzel.arclight.common.mixin.core.entity.ai.attributes;
import io.izzel.arclight.common.bridge.entity.ai.attributes.RangedAttributeBridge;
import net.minecraft.entity.ai.attributes.Attribute;
import net.minecraft.entity.ai.attributes.IAttribute;
import net.minecraft.entity.ai.attributes.RangedAttribute;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import javax.annotation.Nullable;
@Mixin(RangedAttribute.class)
public abstract class RangedAttributeMixin extends Attribute implements RangedAttributeBridge {
protected RangedAttributeMixin(@Nullable IAttribute parentIn, String unlocalizedNameIn, double defaultValueIn) {
super(parentIn, unlocalizedNameIn, defaultValueIn);
}
// @formatter:off
@Override @Accessor("maximumValue") public abstract void bridge$setMaximumValue(double maximumValue);
// @formatter:on
@Inject(method = "clampValue", cancellable = true, at = @At("HEAD"))
private void arclight$notNan(double value, CallbackInfoReturnable<Double> cir) {
if (Double.isNaN(value)) {
cir.setReturnValue(this.getDefaultValue());
}
}
}

View File

@ -1,13 +0,0 @@
package io.izzel.arclight.common.mixin.core.entity.ai.attributes;
import io.izzel.arclight.common.bridge.entity.ai.attributes.RangedAttributeBridge;
import net.minecraft.entity.ai.attributes.RangedAttribute;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(RangedAttribute.class)
public abstract class RangedAttributeMixin_Accessor implements RangedAttributeBridge {
@Override @Accessor("maximumValue")
public abstract void bridge$setMaximumValue(double maximumValue);
}

View File

@ -0,0 +1,18 @@
package io.izzel.arclight.common.mixin.core.entity.ai.brain;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.ai.brain.BrainUtil;
import net.minecraft.item.ItemStack;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(BrainUtil.class)
public class BrainUtilMixin {
@Inject(method = "throwItemAt", cancellable = true, at = @At("HEAD"))
private static void arclight$noEmptyLoot(LivingEntity from, ItemStack stack, LivingEntity to, CallbackInfo ci) {
if (stack.isEmpty()) ci.cancel();
}
}

View File

@ -14,7 +14,7 @@ import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(AssignProfessionTask.class) @Mixin(AssignProfessionTask.class)
public class AssignProfessionTaskMixin { public class AssignProfessionTaskMixin {
@Redirect(method = "func_212831_a_", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/merchant/villager/VillagerEntity;setVillagerData(Lnet/minecraft/entity/merchant/villager/VillagerData;)V")) @Redirect(method = "startExecuting", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/merchant/villager/VillagerEntity;setVillagerData(Lnet/minecraft/entity/merchant/villager/VillagerData;)V"))
private void arclight$careerChangeHook(VillagerEntity villagerEntity, VillagerData villagerData) { private void arclight$careerChangeHook(VillagerEntity villagerEntity, VillagerData villagerData) {
VillagerProfession profession = villagerData.getProfession(); VillagerProfession profession = villagerData.getProfession();
VillagerCareerChangeEvent event = CraftEventFactory.callVillagerCareerChangeEvent(villagerEntity, CraftVillager.nmsToBukkitProfession(profession), VillagerCareerChangeEvent.ChangeReason.EMPLOYED); VillagerCareerChangeEvent event = CraftEventFactory.callVillagerCareerChangeEvent(villagerEntity, CraftVillager.nmsToBukkitProfession(profession), VillagerCareerChangeEvent.ChangeReason.EMPLOYED);
@ -22,6 +22,5 @@ public class AssignProfessionTaskMixin {
VillagerData newData = villagerEntity.getVillagerData().withProfession(CraftVillager.bukkitToNmsProfession(event.getProfession())); VillagerData newData = villagerEntity.getVillagerData().withProfession(CraftVillager.bukkitToNmsProfession(event.getProfession()));
villagerEntity.setVillagerData(newData); villagerEntity.setVillagerData(newData);
} }
} }
} }

View File

@ -14,7 +14,7 @@ import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(ChangeJobTask.class) @Mixin(ChangeJobTask.class)
public class ChangeJobTaskMixin { public class ChangeJobTaskMixin {
@Redirect(method = "func_212831_a_", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/merchant/villager/VillagerEntity;setVillagerData(Lnet/minecraft/entity/merchant/villager/VillagerData;)V")) @Redirect(method = "startExecuting", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/merchant/villager/VillagerEntity;setVillagerData(Lnet/minecraft/entity/merchant/villager/VillagerData;)V"))
private void arclight$careerChangeHook(VillagerEntity villagerEntity, VillagerData villagerData) { private void arclight$careerChangeHook(VillagerEntity villagerEntity, VillagerData villagerData) {
VillagerCareerChangeEvent event = CraftEventFactory.callVillagerCareerChangeEvent(villagerEntity, VillagerCareerChangeEvent event = CraftEventFactory.callVillagerCareerChangeEvent(villagerEntity,
CraftVillager.nmsToBukkitProfession(VillagerProfession.NONE), CraftVillager.nmsToBukkitProfession(VillagerProfession.NONE),

View File

@ -1,38 +1,29 @@
package io.izzel.arclight.common.mixin.core.entity.ai.brain.task; package io.izzel.arclight.common.mixin.core.entity.ai.brain.task;
import io.izzel.arclight.common.bridge.world.WorldBridge;
import net.minecraft.entity.ai.brain.task.CreateBabyVillagerTask; import net.minecraft.entity.ai.brain.task.CreateBabyVillagerTask;
import net.minecraft.entity.merchant.villager.VillagerEntity; import net.minecraft.entity.merchant.villager.VillagerEntity;
import org.bukkit.craftbukkit.v.event.CraftEventFactory; import org.bukkit.craftbukkit.v.event.CraftEventFactory;
import org.bukkit.event.entity.CreatureSpawnEvent;
import org.objectweb.asm.Opcodes;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
import java.util.Optional; import java.util.Optional;
@Mixin(CreateBabyVillagerTask.class) @Mixin(CreateBabyVillagerTask.class)
public class CreateBabyVillagerTaskMixin { public class CreateBabyVillagerTaskMixin {
/** @Inject(method = "func_220480_a", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD,
* @author IzzelAliz at = @At(value = "JUMP", ordinal = 0, opcode = Opcodes.IFNONNULL))
* @reason private void arclight$entityBreed(VillagerEntity lona, VillagerEntity anonymous, CallbackInfoReturnable<Optional<VillagerEntity>> cir, VillagerEntity child) {
*/ if (CraftEventFactory.callEntityBreedEvent(child, lona, anonymous, null, null, 0).isCancelled()) {
@Overwrite cir.setReturnValue(Optional.empty());
private Optional<VillagerEntity> func_220480_a(VillagerEntity lona, VillagerEntity anonymous) { } else if (child != null) {
VillagerEntity villager = lona.createChild(anonymous); ((WorldBridge) lona.world).bridge$pushAddEntityReason(CreatureSpawnEvent.SpawnReason.BREEDING);
if (CraftEventFactory.callEntityBreedEvent(villager, lona, anonymous, null, null, 0).isCancelled()) {
return Optional.empty();
}
if (villager == null) {
return Optional.empty();
} else {
lona.setGrowingAge(6000);
anonymous.setGrowingAge(6000);
villager.setGrowingAge(-24000);
villager.setLocationAndAngles(lona.posX, lona.posY, lona.posZ, 0.0F, 0.0F);
lona.world.addEntity(villager);
lona.world.setEntityState(villager, (byte) 12);
return Optional.of(villager);
} }
} }
} }

View File

@ -12,7 +12,7 @@ import io.izzel.arclight.common.mod.util.ArclightCaptures;
@Mixin(FarmTask.class) @Mixin(FarmTask.class)
public abstract class FarmTaskMixin { public abstract class FarmTaskMixin {
@Inject(method = "func_212833_d_", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/server/ServerWorld;setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;I)Z")) @Inject(method = "updateTask", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/server/ServerWorld;setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;I)Z"))
private void on(ServerWorld worldIn, VillagerEntity owner, long gameTime, CallbackInfo ci) { private void on(ServerWorld worldIn, VillagerEntity owner, long gameTime, CallbackInfo ci) {
ArclightCaptures.captureEntityChangeBlock(owner); ArclightCaptures.captureEntityChangeBlock(owner);
} }

View File

@ -13,8 +13,12 @@ public abstract class MinecartCommandBlockEntity_MinecartCommandLogicMixin imple
@Shadow(aliases = {"this$0", "field_210168_a"}) private MinecartCommandBlockEntity outerThis; @Shadow(aliases = {"this$0", "field_210168_a"}) private MinecartCommandBlockEntity outerThis;
@Override public CommandSender getBukkitSender(CommandSource wrapper) {
public CommandSender bridge$getBukkitSender(CommandSource wrapper) {
return ((EntityBridge) outerThis).bridge$getBukkitEntity(); return ((EntityBridge) outerThis).bridge$getBukkitEntity();
} }
@Override
public CommandSender bridge$getBukkitSender(CommandSource wrapper) {
return getBukkitSender(wrapper);
}
} }

View File

@ -22,7 +22,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(AbstractFurnaceContainer.class) @Mixin(AbstractFurnaceContainer.class)
public class AbstractFurnaceContainerMixin extends ContainerMixin { public abstract class AbstractFurnaceContainerMixin extends ContainerMixin {
// @formatter:off // @formatter:off
@Shadow @Final private IInventory furnaceInventory; @Shadow @Final private IInventory furnaceInventory;

View File

@ -20,7 +20,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(BeaconContainer.class) @Mixin(BeaconContainer.class)
public class BeaconContainerMixin extends ContainerMixin { public abstract class BeaconContainerMixin extends ContainerMixin {
// @formatter:off // @formatter:off
@Shadow @Final private IInventory tileBeacon; @Shadow @Final private IInventory tileBeacon;

View File

@ -18,7 +18,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(BrewingStandContainer.class) @Mixin(BrewingStandContainer.class)
public class BrewingStandContainerMixin extends ContainerMixin { public abstract class BrewingStandContainerMixin extends ContainerMixin {
// @formatter:off // @formatter:off
@Shadow @Final private IInventory tileBrewingStand; @Shadow @Final private IInventory tileBrewingStand;

View File

@ -21,11 +21,11 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(CartographyContainer.class) @Mixin(CartographyContainer.class)
public class CartographyContainerMixin extends ContainerMixin implements CartographyContainerBridge { public abstract class CartographyContainerMixin extends ContainerMixin implements CartographyContainerBridge {
// @formatter:off // @formatter:off
@Shadow @Final private IWorldPosCallable field_216999_d; @Shadow @Final private IWorldPosCallable worldPosCallable;
@Shadow @Final public IInventory field_216998_c; @Shadow @Final public IInventory tableInventory;
@Shadow @Final private CraftResultInventory field_217001_f; @Shadow @Final private CraftResultInventory field_217001_f;
// @formatter:on // @formatter:on
@ -48,13 +48,13 @@ public class CartographyContainerMixin extends ContainerMixin implements Cartogr
return bukkitEntity; return bukkitEntity;
} }
CraftInventoryCartography inventory = new CraftInventoryCartography(this.field_216998_c, this.field_217001_f); CraftInventoryCartography inventory = new CraftInventoryCartography(this.tableInventory, this.field_217001_f);
bukkitEntity = new CraftInventoryView(this.player, inventory, (Container) (Object) this); bukkitEntity = new CraftInventoryView(this.player, inventory, (Container) (Object) this);
return bukkitEntity; return bukkitEntity;
} }
@Override @Override
public IWorldPosCallable bridge$getContainerAccess() { public IWorldPosCallable bridge$getContainerAccess() {
return this.field_216999_d; return this.worldPosCallable;
} }
} }

View File

@ -21,7 +21,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(ChestContainer.class) @Mixin(ChestContainer.class)
public class ChestContainerMixin extends ContainerMixin { public abstract class ChestContainerMixin extends ContainerMixin {
// @formatter:off // @formatter:off
@Shadow @Final private IInventory lowerChestInventory; @Shadow @Final private IInventory lowerChestInventory;

View File

@ -3,19 +3,54 @@ package io.izzel.arclight.common.mixin.core.inventory.container;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import io.izzel.arclight.common.bridge.inventory.IInventoryBridge; import io.izzel.arclight.common.bridge.inventory.IInventoryBridge;
import io.izzel.arclight.common.bridge.inventory.container.ContainerBridge; import io.izzel.arclight.common.bridge.inventory.container.ContainerBridge;
import io.izzel.arclight.common.bridge.inventory.container.SlotBridge;
import net.minecraft.entity.item.ItemEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.entity.player.ServerPlayerEntity;
import net.minecraft.inventory.container.ClickType;
import net.minecraft.inventory.container.Container; import net.minecraft.inventory.container.Container;
import net.minecraft.inventory.container.Slot;
import net.minecraft.item.ItemStack;
import net.minecraft.network.play.server.SSetSlotPacket;
import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.ITextComponent;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.craftbukkit.v.entity.CraftHumanEntity; import org.bukkit.craftbukkit.v.entity.CraftHumanEntity;
import org.bukkit.craftbukkit.v.inventory.CraftInventory; import org.bukkit.craftbukkit.v.inventory.CraftInventory;
import org.bukkit.craftbukkit.v.inventory.CraftItemStack;
import org.bukkit.event.Event;
import org.bukkit.event.inventory.InventoryDragEvent;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.inventory.InventoryView; import org.bukkit.inventory.InventoryView;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
@Mixin(Container.class) @Mixin(Container.class)
public abstract class ContainerMixin implements ContainerBridge { public abstract class ContainerMixin implements ContainerBridge {
// @formatter:off // @formatter:off
@Shadow public void detectAndSendChanges() {} @Shadow public void detectAndSendChanges() {}
@Shadow private int dragEvent;
@Shadow protected abstract void resetDrag();
@Shadow private int dragMode;
@Shadow @Final private Set<Slot> dragSlots;
@Shadow public List<Slot> inventorySlots;
@Shadow public abstract boolean canDragIntoSlot(Slot slotIn);
@Shadow public abstract ItemStack transferStackInSlot(PlayerEntity playerIn, int index);
@Shadow public abstract boolean canMergeSlot(ItemStack stack, Slot slotIn);
@Shadow @Final public int windowId;
@Shadow public abstract Slot getSlot(int slotId);
// @formatter:on // @formatter:on
public boolean checkReachable = true; public boolean checkReachable = true;
@ -43,6 +78,269 @@ public abstract class ContainerMixin implements ContainerBridge {
this.title = title; this.title = title;
} }
@Redirect(method = "onContainerClosed", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/player/PlayerEntity;dropItem(Lnet/minecraft/item/ItemStack;Z)Lnet/minecraft/entity/item/ItemEntity;"))
private ItemEntity arclight$cleanBeforeDrop(PlayerEntity playerEntity, ItemStack itemStackIn, boolean unused) {
playerEntity.inventory.setItemStack(ItemStack.EMPTY);
return playerEntity.dropItem(itemStackIn, unused);
}
/**
* @author IzzelAliz
* @reason
*/
@Overwrite
public ItemStack slotClick(int i, int j, ClickType clickType, PlayerEntity entity) {
ItemStack itemstack = ItemStack.EMPTY;
PlayerInventory playerinventory = entity.inventory;
if (clickType == ClickType.QUICK_CRAFT) {
int i2 = this.dragEvent;
this.dragEvent = Container.getDragEvent(j);
if ((i2 != 1 || this.dragEvent != 2) && i2 != this.dragEvent) {
this.resetDrag();
} else if (playerinventory.getItemStack().isEmpty()) {
this.resetDrag();
} else if (this.dragEvent == 0) {
this.dragMode = Container.extractDragMode(j);
if (Container.isValidDragMode(this.dragMode, entity)) {
this.dragEvent = 1;
this.dragSlots.clear();
} else {
this.resetDrag();
}
} else if (this.dragEvent == 1) {
Slot slot = this.inventorySlots.get(i);
ItemStack itemstack2 = playerinventory.getItemStack();
if (slot != null && Container.canAddItemToSlot(slot, itemstack2, true) && slot.isItemValid(itemstack2) && (this.dragMode == 2 || itemstack2.getCount() > this.dragSlots.size()) && this.canDragIntoSlot(slot)) {
this.dragSlots.add(slot);
}
} else if (this.dragEvent == 2) {
if (!this.dragSlots.isEmpty()) {
ItemStack itemstack3 = playerinventory.getItemStack().copy();
int k = playerinventory.getItemStack().getCount();
Iterator<Slot> iterator = this.dragSlots.iterator();
Map<Integer, ItemStack> draggedSlots = new HashMap<>();
while (iterator.hasNext()) {
Slot slot2 = iterator.next();
ItemStack itemstack4 = playerinventory.getItemStack();
if (slot2 != null && Container.canAddItemToSlot(slot2, itemstack4, true) && slot2.isItemValid(itemstack4) && (this.dragMode == 2 || itemstack4.getCount() >= this.dragSlots.size()) && this.canDragIntoSlot(slot2)) {
ItemStack itemstack5 = itemstack3.copy();
int j2 = slot2.getHasStack() ? slot2.getStack().getCount() : 0;
Container.computeStackSize(this.dragSlots, this.dragMode, itemstack5, j2);
int l = Math.min(itemstack5.getMaxStackSize(), slot2.getItemStackLimit(itemstack5));
if (itemstack5.getCount() > l) {
itemstack5.setCount(l);
}
k -= itemstack5.getCount() - j2;
draggedSlots.put(slot2.slotNumber, itemstack5);
}
}
InventoryView view = this.getBukkitView();
org.bukkit.inventory.ItemStack newcursor = CraftItemStack.asCraftMirror(itemstack3);
newcursor.setAmount(k);
Map<Integer, org.bukkit.inventory.ItemStack> eventmap = new HashMap<>();
for (Map.Entry<Integer, ItemStack> ditem : draggedSlots.entrySet()) {
eventmap.put(ditem.getKey(), CraftItemStack.asBukkitCopy(ditem.getValue()));
}
ItemStack oldCursor = playerinventory.getItemStack();
playerinventory.setItemStack(CraftItemStack.asNMSCopy(newcursor));
InventoryDragEvent event = new InventoryDragEvent(view, (newcursor.getType() != Material.AIR) ? newcursor : null, CraftItemStack.asBukkitCopy(oldCursor), this.dragMode == 1, eventmap);
Bukkit.getPluginManager().callEvent(event);
boolean needsUpdate = event.getResult() != Event.Result.DEFAULT;
if (event.getResult() != Event.Result.DENY) {
for (Map.Entry<Integer, ItemStack> dslot : draggedSlots.entrySet()) {
view.setItem(dslot.getKey(), CraftItemStack.asBukkitCopy(dslot.getValue()));
}
if (playerinventory.getItemStack() != null) {
playerinventory.setItemStack(CraftItemStack.asNMSCopy(event.getCursor()));
needsUpdate = true;
}
} else {
playerinventory.setItemStack(oldCursor);
}
if (needsUpdate && entity instanceof ServerPlayerEntity) {
((ServerPlayerEntity) entity).sendContainerToPlayer((Container) (Object) this);
}
}
this.resetDrag();
} else {
this.resetDrag();
}
} else if (this.dragEvent != 0) {
this.resetDrag();
} else if ((clickType == ClickType.PICKUP || clickType == ClickType.QUICK_MOVE) && (j == 0 || j == 1)) {
if (i == -999) {
if (!playerinventory.getItemStack().isEmpty()) {
if (j == 0) {
ItemStack carried = playerinventory.getItemStack();
playerinventory.setItemStack(ItemStack.EMPTY);
entity.dropItem(carried, true);
}
if (j == 1) {
entity.dropItem(playerinventory.getItemStack().split(1), true);
}
}
} else if (clickType == ClickType.QUICK_MOVE) {
if (i < 0) {
return ItemStack.EMPTY;
}
Slot slot3 = this.inventorySlots.get(i);
if (slot3 == null || !slot3.canTakeStack(entity)) {
return ItemStack.EMPTY;
}
for (ItemStack itemstack3 = this.transferStackInSlot(entity, i); !itemstack3.isEmpty(); itemstack3 = this.transferStackInSlot(entity, i)) {
if (!ItemStack.areItemsEqual(slot3.getStack(), itemstack3)) {
break;
}
itemstack = itemstack3.copy();
}
} else {
if (i < 0) {
return ItemStack.EMPTY;
}
Slot slot3 = this.inventorySlots.get(i);
if (slot3 != null) {
ItemStack itemstack3 = slot3.getStack();
ItemStack itemstack2 = playerinventory.getItemStack();
if (!itemstack3.isEmpty()) {
itemstack = itemstack3.copy();
}
if (itemstack3.isEmpty()) {
if (!itemstack2.isEmpty() && slot3.isItemValid(itemstack2)) {
int k2 = (j == 0) ? itemstack2.getCount() : 1;
if (k2 > slot3.getItemStackLimit(itemstack2)) {
k2 = slot3.getItemStackLimit(itemstack2);
}
slot3.putStack(itemstack2.split(k2));
}
} else if (slot3.canTakeStack(entity)) {
if (itemstack2.isEmpty()) {
if (itemstack3.isEmpty()) {
slot3.putStack(ItemStack.EMPTY);
playerinventory.setItemStack(ItemStack.EMPTY);
} else {
int k2 = (j == 0) ? itemstack3.getCount() : ((itemstack3.getCount() + 1) / 2);
playerinventory.setItemStack(slot3.decrStackSize(k2));
if (itemstack3.isEmpty()) {
slot3.putStack(ItemStack.EMPTY);
}
slot3.onTake(entity, playerinventory.getItemStack());
}
} else if (slot3.isItemValid(itemstack2)) {
if (Container.areItemsAndTagsEqual(itemstack3, itemstack2)) {
int k2 = (j == 0) ? itemstack2.getCount() : 1;
if (k2 > slot3.getItemStackLimit(itemstack2) - itemstack3.getCount()) {
k2 = slot3.getItemStackLimit(itemstack2) - itemstack3.getCount();
}
if (k2 > itemstack2.getMaxStackSize() - itemstack3.getCount()) {
k2 = itemstack2.getMaxStackSize() - itemstack3.getCount();
}
itemstack2.shrink(k2);
itemstack3.grow(k2);
} else if (itemstack2.getCount() <= slot3.getItemStackLimit(itemstack2)) {
slot3.putStack(itemstack2);
playerinventory.setItemStack(itemstack3);
}
} else if (itemstack2.getMaxStackSize() > 1 && Container.areItemsAndTagsEqual(itemstack3, itemstack2) && !itemstack3.isEmpty()) {
int k2 = itemstack3.getCount();
if (k2 + itemstack2.getCount() <= itemstack2.getMaxStackSize()) {
itemstack2.grow(k2);
itemstack3 = slot3.decrStackSize(k2);
if (itemstack3.isEmpty()) {
slot3.putStack(ItemStack.EMPTY);
}
slot3.onTake(entity, playerinventory.getItemStack());
}
}
}
slot3.onSlotChanged();
if (entity instanceof ServerPlayerEntity && slot3.getSlotStackLimit() != 64) {
((ServerPlayerEntity) entity).connection.sendPacket(new SSetSlotPacket(this.windowId, slot3.slotNumber, slot3.getStack()));
if (this.getBukkitView().getType() == InventoryType.WORKBENCH || this.getBukkitView().getType() == InventoryType.CRAFTING) {
((ServerPlayerEntity) entity).connection.sendPacket(new SSetSlotPacket(this.windowId, 0, this.getSlot(0).getStack()));
}
}
}
}
} else if (clickType == ClickType.SWAP && j >= 0 && j < 9) {
Slot slot3 = this.inventorySlots.get(i);
ItemStack itemstack3 = playerinventory.getStackInSlot(j);
ItemStack itemstack2 = slot3.getStack();
if (!itemstack3.isEmpty() || !itemstack2.isEmpty()) {
if (itemstack3.isEmpty()) {
if (slot3.canTakeStack(entity)) {
playerinventory.setInventorySlotContents(j, itemstack2);
((SlotBridge) slot3).bridge$onSwapCraft(itemstack2.getCount());
slot3.putStack(ItemStack.EMPTY);
slot3.onTake(entity, itemstack2);
}
} else if (itemstack2.isEmpty()) {
if (slot3.isItemValid(itemstack3)) {
int k2 = slot3.getItemStackLimit(itemstack3);
if (itemstack3.getCount() > k2) {
slot3.putStack(itemstack3.split(k2));
} else {
slot3.putStack(itemstack3);
playerinventory.setInventorySlotContents(j, ItemStack.EMPTY);
}
}
} else if (slot3.canTakeStack(entity) && slot3.isItemValid(itemstack3)) {
int k2 = slot3.getItemStackLimit(itemstack3);
if (itemstack3.getCount() > k2) {
slot3.putStack(itemstack3.split(k2));
slot3.onTake(entity, itemstack2);
if (!playerinventory.addItemStackToInventory(itemstack2)) {
entity.dropItem(itemstack2, true);
}
} else {
slot3.putStack(itemstack3);
playerinventory.setInventorySlotContents(j, itemstack2);
slot3.onTake(entity, itemstack2);
}
}
}
} else if (clickType == ClickType.CLONE && entity.abilities.isCreativeMode && playerinventory.getItemStack().isEmpty() && i >= 0) {
Slot slot3 = this.inventorySlots.get(i);
if (slot3 != null && slot3.getHasStack()) {
ItemStack itemstack3 = slot3.getStack().copy();
itemstack3.setCount(itemstack3.getMaxStackSize());
playerinventory.setItemStack(itemstack3);
}
} else if (clickType == ClickType.THROW && playerinventory.getItemStack().isEmpty() && i >= 0) {
Slot slot3 = this.inventorySlots.get(i);
if (slot3 != null && slot3.getHasStack() && slot3.canTakeStack(entity)) {
ItemStack itemstack3 = slot3.decrStackSize((j == 0) ? 1 : slot3.getStack().getCount());
slot3.onTake(entity, itemstack3);
entity.dropItem(itemstack3, true);
}
} else if (clickType == ClickType.PICKUP_ALL && i >= 0) {
Slot slot3 = this.inventorySlots.get(i);
ItemStack itemstack3 = playerinventory.getItemStack();
if (!itemstack3.isEmpty() && (slot3 == null || !slot3.getHasStack() || !slot3.canTakeStack(entity))) {
int k = (j == 0) ? 0 : (this.inventorySlots.size() - 1);
int k2 = (j == 0) ? 1 : -1;
for (int l2 = 0; l2 < 2; ++l2) {
for (int i3 = k; i3 >= 0 && i3 < this.inventorySlots.size() && itemstack3.getCount() < itemstack3.getMaxStackSize(); i3 += k2) {
Slot slot4 = this.inventorySlots.get(i3);
if (slot4.getHasStack() && Container.canAddItemToSlot(slot4, itemstack3, true) && slot4.canTakeStack(entity) && this.canMergeSlot(itemstack3, slot4)) {
ItemStack itemstack6 = slot4.getStack();
if (l2 != 0 || itemstack6.getCount() != itemstack6.getMaxStackSize()) {
int l = Math.min(itemstack3.getMaxStackSize() - itemstack3.getCount(), itemstack6.getCount());
ItemStack itemstack7 = slot4.decrStackSize(l);
itemstack3.grow(l);
if (itemstack7.isEmpty()) {
slot4.putStack(ItemStack.EMPTY);
}
slot4.onTake(entity, itemstack7);
}
}
}
}
}
this.detectAndSendChanges();
}
return itemstack;
}
@Override @Override
public boolean bridge$isCheckReachable() { public boolean bridge$isCheckReachable() {
return checkReachable; return checkReachable;

View File

@ -17,7 +17,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(DispenserContainer.class) @Mixin(DispenserContainer.class)
public class DispenserContainerMixin extends ContainerMixin { public abstract class DispenserContainerMixin extends ContainerMixin {
// @formatter:off // @formatter:off
@Shadow @Final public IInventory dispenserInventory; @Shadow @Final public IInventory dispenserInventory;

View File

@ -54,7 +54,7 @@ public abstract class EnchantmentContainerMixin extends ContainerMixin implement
// @formatter:off // @formatter:off
@Shadow @Final private IInventory tableInventory; @Shadow @Final private IInventory tableInventory;
@Shadow @Final private IWorldPosCallable field_217006_g; @Shadow @Final private IWorldPosCallable worldPosCallable;
@Shadow protected abstract float getPower(World world, BlockPos pos); @Shadow protected abstract float getPower(World world, BlockPos pos);
@Shadow @Final private Random rand; @Shadow @Final private Random rand;
@Shadow @Final private IntReferenceHolder xpSeed; @Shadow @Final private IntReferenceHolder xpSeed;
@ -86,7 +86,7 @@ public abstract class EnchantmentContainerMixin extends ContainerMixin implement
if (inventoryIn == this.tableInventory) { if (inventoryIn == this.tableInventory) {
ItemStack itemstack = inventoryIn.getStackInSlot(0); ItemStack itemstack = inventoryIn.getStackInSlot(0);
if (!itemstack.isEmpty()) { if (!itemstack.isEmpty()) {
this.field_217006_g.consume((p_217002_2_, p_217002_3_) -> { this.worldPosCallable.consume((p_217002_2_, p_217002_3_) -> {
float power = 0; float power = 0;
for (int k = -1; k <= 1; ++k) { for (int k = -1; k <= 1; ++k) {
@ -136,7 +136,7 @@ public abstract class EnchantmentContainerMixin extends ContainerMixin implement
offers[j] = (enchantment != null) ? new EnchantmentOffer(enchantment, this.worldClue[j], this.enchantLevels[j]) : null; offers[j] = (enchantment != null) ? new EnchantmentOffer(enchantment, this.worldClue[j], this.enchantLevels[j]) : null;
} }
PrepareItemEnchantEvent event = new PrepareItemEnchantEvent(player, this.getBukkitView(), ((IWorldPosCallableBridge) this.field_217006_g).bridge$getLocation().getBlock(), item, offers, (int) power); PrepareItemEnchantEvent event = new PrepareItemEnchantEvent(player, this.getBukkitView(), ((IWorldPosCallableBridge) this.worldPosCallable).bridge$getLocation().getBlock(), item, offers, (int) power);
event.setCancelled(!itemstack.isEnchantable()); event.setCancelled(!itemstack.isEnchantable());
Bukkit.getPluginManager().callEvent(event); Bukkit.getPluginManager().callEvent(event);
@ -189,7 +189,7 @@ public abstract class EnchantmentContainerMixin extends ContainerMixin implement
} else if (this.enchantLevels[id] <= 0 || itemstack.isEmpty() || (playerIn.experienceLevel < i || playerIn.experienceLevel < this.enchantLevels[id]) && !playerIn.abilities.isCreativeMode) { } else if (this.enchantLevels[id] <= 0 || itemstack.isEmpty() || (playerIn.experienceLevel < i || playerIn.experienceLevel < this.enchantLevels[id]) && !playerIn.abilities.isCreativeMode) {
return false; return false;
} else { } else {
this.field_217006_g.consume((p_217003_6_, p_217003_7_) -> { this.worldPosCallable.consume((p_217003_6_, p_217003_7_) -> {
ItemStack itemstack2 = itemstack; ItemStack itemstack2 = itemstack;
List<EnchantmentData> list = this.getEnchantmentList(itemstack, id, this.enchantLevels[id]); List<EnchantmentData> list = this.getEnchantmentList(itemstack, id, this.enchantLevels[id]);
if (true || !list.isEmpty()) { if (true || !list.isEmpty()) {
@ -202,7 +202,7 @@ public abstract class EnchantmentContainerMixin extends ContainerMixin implement
} }
CraftItemStack item = CraftItemStack.asCraftMirror(itemstack2); CraftItemStack item = CraftItemStack.asCraftMirror(itemstack2);
EnchantItemEvent event = new EnchantItemEvent(((Player) ((PlayerEntityBridge) playerIn).bridge$getBukkitEntity()), this.getBukkitView(), ((IWorldPosCallableBridge) this.field_217006_g).bridge$getLocation().getBlock(), item, this.enchantLevels[i], enchants, i); EnchantItemEvent event = new EnchantItemEvent(((Player) ((PlayerEntityBridge) playerIn).bridge$getBukkitEntity()), this.getBukkitView(), ((IWorldPosCallableBridge) this.worldPosCallable).bridge$getLocation().getBlock(), item, this.enchantLevels[i], enchants, i);
Bukkit.getPluginManager().callEvent(event); Bukkit.getPluginManager().callEvent(event);
int level = event.getExpLevelCost(); int level = event.getExpLevelCost();
@ -271,6 +271,6 @@ public abstract class EnchantmentContainerMixin extends ContainerMixin implement
@Override @Override
public IWorldPosCallable bridge$getContainerAccess() { public IWorldPosCallable bridge$getContainerAccess() {
return this.field_217006_g; return this.worldPosCallable;
} }
} }

View File

@ -18,7 +18,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import io.izzel.arclight.common.bridge.inventory.container.GrindstoneContainerBridge; import io.izzel.arclight.common.bridge.inventory.container.GrindstoneContainerBridge;
@Mixin(GrindstoneContainer.class) @Mixin(GrindstoneContainer.class)
public class GrindstoneContainerMixin extends ContainerMixin implements GrindstoneContainerBridge { public abstract class GrindstoneContainerMixin extends ContainerMixin implements GrindstoneContainerBridge {
@Shadow @Final private IInventory inputInventory; @Shadow @Final private IInventory inputInventory;
@Shadow @Final private IInventory outputInventory; @Shadow @Final private IInventory outputInventory;

View File

@ -17,7 +17,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(HopperContainer.class) @Mixin(HopperContainer.class)
public class HopperContainerMixin extends ContainerMixin { public abstract class HopperContainerMixin extends ContainerMixin {
// @formatter:off // @formatter:off
@Shadow @Final private IInventory hopperInventory; @Shadow @Final private IInventory hopperInventory;

View File

@ -17,7 +17,7 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(HorseInventoryContainer.class) @Mixin(HorseInventoryContainer.class)
public class HorseInventoryContainerMixin extends ContainerMixin { public abstract class HorseInventoryContainerMixin extends ContainerMixin {
// @formatter:off // @formatter:off
@Shadow @Final private IInventory horseInventory; @Shadow @Final private IInventory horseInventory;

View File

@ -21,10 +21,10 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(LecternContainer.class) @Mixin(LecternContainer.class)
public class LecternContainerMixin extends ContainerMixin implements LecternContainerBridge { public abstract class LecternContainerMixin extends ContainerMixin implements LecternContainerBridge {
// @formatter:off // @formatter:off
@Shadow @Final private IInventory field_217018_c; @Shadow @Final private IInventory lecternInventory;
// @formatter:on // @formatter:on
private CraftInventoryView bukkitEntity; private CraftInventoryView bukkitEntity;
@ -67,7 +67,7 @@ public class LecternContainerMixin extends ContainerMixin implements LecternCont
if (bukkitEntity != null) { if (bukkitEntity != null) {
return bukkitEntity; return bukkitEntity;
} }
CraftInventoryLectern inventory = new CraftInventoryLectern(this.field_217018_c); CraftInventoryLectern inventory = new CraftInventoryLectern(this.lecternInventory);
bukkitEntity = new CraftInventoryView(this.player, inventory, (Container) (Object) this); bukkitEntity = new CraftInventoryView(this.player, inventory, (Container) (Object) this);
return bukkitEntity; return bukkitEntity;
} }

View File

@ -21,11 +21,11 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import io.izzel.arclight.common.bridge.inventory.container.LoomContainerBridge; import io.izzel.arclight.common.bridge.inventory.container.LoomContainerBridge;
@Mixin(LoomContainer.class) @Mixin(LoomContainer.class)
public class LoomContainerMixin extends ContainerMixin implements LoomContainerBridge { public abstract class LoomContainerMixin extends ContainerMixin implements LoomContainerBridge {
// @formatter:off // @formatter:off
@Shadow @Final private IInventory field_217040_j; // crafting @Shadow @Final private IInventory inputInventory;
@Shadow @Final private IInventory field_217041_k; // result @Shadow @Final private IInventory outputInventory;
@Shadow @Final private IWorldPosCallable worldPos; @Shadow @Final private IWorldPosCallable worldPos;
// @formatter:on // @formatter:on
@ -50,7 +50,7 @@ public class LoomContainerMixin extends ContainerMixin implements LoomContainerB
return bukkitEntity; return bukkitEntity;
} }
CraftInventoryLoom inventory = new CraftInventoryLoom(this.field_217040_j, this.field_217041_k); CraftInventoryLoom inventory = new CraftInventoryLoom(this.inputInventory, this.outputInventory);
bukkitEntity = new CraftInventoryView(this.player, inventory, (Container) (Object) this); bukkitEntity = new CraftInventoryView(this.player, inventory, (Container) (Object) this);
return bukkitEntity; return bukkitEntity;
} }

View File

@ -18,7 +18,7 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(MerchantContainer.class) @Mixin(MerchantContainer.class)
public class MerchantContainerMixin extends ContainerMixin { public abstract class MerchantContainerMixin extends ContainerMixin {
// @formatter:off // @formatter:off
@Shadow @Final private IMerchant merchant; @Shadow @Final private IMerchant merchant;

View File

@ -22,11 +22,11 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(PlayerContainer.class) @Mixin(PlayerContainer.class)
public class PlayerContainerMixin extends ContainerMixin { public abstract class PlayerContainerMixin extends ContainerMixin {
// @formatter:off // @formatter:off
@Shadow @Final private CraftingInventory field_75181_e; @Shadow @Final private CraftingInventory craftMatrix;
@Shadow @Final private CraftResultInventory field_75179_f; @Shadow @Final private CraftResultInventory craftResult;
// @formatter:on // @formatter:on
private CraftInventoryView bukkitEntity; private CraftInventoryView bukkitEntity;
@ -35,8 +35,8 @@ public class PlayerContainerMixin extends ContainerMixin {
@Inject(method = "<init>", at = @At("RETURN")) @Inject(method = "<init>", at = @At("RETURN"))
public void arclight$init(PlayerInventory playerInventory, boolean localWorld, PlayerEntity playerIn, CallbackInfo ci) { public void arclight$init(PlayerInventory playerInventory, boolean localWorld, PlayerEntity playerIn, CallbackInfo ci) {
this.player = playerInventory; this.player = playerInventory;
((CraftingInventoryBridge) this.field_75181_e).bridge$setOwner(playerInventory.player); ((CraftingInventoryBridge) this.craftMatrix).bridge$setOwner(playerInventory.player);
((CraftingInventoryBridge) this.field_75181_e).bridge$setResultInventory(this.field_75179_f); ((CraftingInventoryBridge) this.craftMatrix).bridge$setResultInventory(this.craftResult);
this.setTitle(new TranslationTextComponent("container.crafting")); this.setTitle(new TranslationTextComponent("container.crafting"));
} }
@ -51,7 +51,7 @@ public class PlayerContainerMixin extends ContainerMixin {
return bukkitEntity; return bukkitEntity;
} }
CraftInventoryCrafting inventory = new CraftInventoryCrafting(this.field_75181_e, this.field_75179_f); CraftInventoryCrafting inventory = new CraftInventoryCrafting(this.craftMatrix, this.craftResult);
bukkitEntity = new CraftInventoryView(((PlayerEntityBridge) this.player.player).bridge$getBukkitEntity(), inventory, (Container) (Object) this); bukkitEntity = new CraftInventoryView(((PlayerEntityBridge) this.player.player).bridge$getBukkitEntity(), inventory, (Container) (Object) this);
return bukkitEntity; return bukkitEntity;
} }

View File

@ -36,7 +36,7 @@ import java.util.Map;
public abstract class RepairContainerMixin extends ContainerMixin { public abstract class RepairContainerMixin extends ContainerMixin {
// @formatter:off // @formatter:off
@Shadow @Final private IWorldPosCallable field_216980_g; @Shadow @Final private IWorldPosCallable worldPosCallable;
@Shadow @Final private IInventory inputSlots; @Shadow @Final private IInventory inputSlots;
@Shadow @Final private IInventory outputSlot; @Shadow @Final private IInventory outputSlot;
@Shadow @Final private PlayerEntity player; @Shadow @Final private PlayerEntity player;
@ -249,7 +249,7 @@ public abstract class RepairContainerMixin extends ContainerMixin {
} }
CraftInventory inventory = new CraftInventoryAnvil( CraftInventory inventory = new CraftInventoryAnvil(
((IWorldPosCallableBridge) this.field_216980_g).bridge$getLocation(), this.inputSlots, this.outputSlot, (RepairContainer) (Object) this); ((IWorldPosCallableBridge) this.worldPosCallable).bridge$getLocation(), this.inputSlots, this.outputSlot, (RepairContainer) (Object) this);
bukkitEntity = new CraftInventoryView(((PlayerEntityBridge) this.player).bridge$getBukkitEntity(), inventory, (Container) (Object) this); bukkitEntity = new CraftInventoryView(((PlayerEntityBridge) this.player).bridge$getBukkitEntity(), inventory, (Container) (Object) this);
return bukkitEntity; return bukkitEntity;
} }

View File

@ -16,7 +16,7 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(ShulkerBoxContainer.class) @Mixin(ShulkerBoxContainer.class)
public class ShulkerBoxContainerMixin extends ContainerMixin { public abstract class ShulkerBoxContainerMixin extends ContainerMixin {
// @formatter:off // @formatter:off
@Shadow @Final private IInventory inventory; @Shadow @Final private IInventory inventory;

View File

@ -0,0 +1,19 @@
package io.izzel.arclight.common.mixin.core.inventory.container;
import io.izzel.arclight.common.bridge.inventory.container.SlotBridge;
import net.minecraft.inventory.container.Slot;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
@Mixin(Slot.class)
public abstract class SlotMixin implements SlotBridge {
// @formatter:off
@Shadow protected abstract void onSwapCraft(int numItemsCrafted);
// @formatter:on
@Override
public void bridge$onSwapCraft(int numItemsCrafted) {
onSwapCraft(numItemsCrafted);
}
}

View File

@ -19,7 +19,7 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(StonecutterContainer.class) @Mixin(StonecutterContainer.class)
public class StonecutterContainerMixin extends ContainerMixin { public abstract class StonecutterContainerMixin extends ContainerMixin {
// @formatter:off // @formatter:off
@Shadow @Final public IInventory inputInventory; @Shadow @Final public IInventory inputInventory;

View File

@ -40,9 +40,9 @@ import java.util.Optional;
public abstract class WorkbenchContainerMixin extends ContainerMixin implements WorkbenchContainerBridge { public abstract class WorkbenchContainerMixin extends ContainerMixin implements WorkbenchContainerBridge {
// @formatter:off // @formatter:off
@Mutable @Shadow @Final private CraftingInventory field_75162_e; @Mutable @Shadow @Final private CraftingInventory craftMatrix;
@Shadow @Final private CraftResultInventory field_75160_f; @Shadow @Final private CraftResultInventory craftResult;
@Accessor("field_217070_e") public abstract IWorldPosCallable bridge$getContainerAccess(); @Accessor("worldPosCallable") public abstract IWorldPosCallable bridge$getContainerAccess();
// @formatter:on // @formatter:on
private CraftInventoryView bukkitEntity; private CraftInventoryView bukkitEntity;
@ -55,7 +55,7 @@ public abstract class WorkbenchContainerMixin extends ContainerMixin implements
private static void a(int p_217066_0_, World p_217066_1_, PlayerEntity p_217066_2_, CraftingInventory p_217066_3_, CraftResultInventory p_217066_4_, Container container) { private static void a(int p_217066_0_, World p_217066_1_, PlayerEntity p_217066_2_, CraftingInventory p_217066_3_, CraftResultInventory p_217066_4_, Container container) {
ArclightCaptures.captureWorkbenchContainer(container); ArclightCaptures.captureWorkbenchContainer(container);
func_217066_a(p_217066_0_, p_217066_1_, p_217066_2_, p_217066_3_, p_217066_4_); updateCraftingResult(p_217066_0_, p_217066_1_, p_217066_2_, p_217066_3_, p_217066_4_);
} }
@Inject(method = "onCraftMatrixChanged", at = @At("HEAD")) @Inject(method = "onCraftMatrixChanged", at = @At("HEAD"))
@ -68,7 +68,7 @@ public abstract class WorkbenchContainerMixin extends ContainerMixin implements
* @reason * @reason
*/ */
@Overwrite @Overwrite
protected static void func_217066_a(int i, World world, PlayerEntity playerEntity, CraftingInventory inventory, CraftResultInventory resultInventory) { protected static void updateCraftingResult(int i, World world, PlayerEntity playerEntity, CraftingInventory inventory, CraftResultInventory resultInventory) {
Container container = ArclightCaptures.getWorkbenchContainer(); Container container = ArclightCaptures.getWorkbenchContainer();
if (!world.isRemote) { if (!world.isRemote) {
ServerPlayerEntity serverplayerentity = (ServerPlayerEntity) playerEntity; ServerPlayerEntity serverplayerentity = (ServerPlayerEntity) playerEntity;
@ -90,8 +90,8 @@ public abstract class WorkbenchContainerMixin extends ContainerMixin implements
@Inject(method = "<init>(ILnet/minecraft/entity/player/PlayerInventory;Lnet/minecraft/util/IWorldPosCallable;)V", at = @At("RETURN")) @Inject(method = "<init>(ILnet/minecraft/entity/player/PlayerInventory;Lnet/minecraft/util/IWorldPosCallable;)V", at = @At("RETURN"))
public void arclight$init(int i, PlayerInventory playerInventory, IWorldPosCallable callable, CallbackInfo ci) { public void arclight$init(int i, PlayerInventory playerInventory, IWorldPosCallable callable, CallbackInfo ci) {
((CraftingInventoryBridge) this.field_75162_e).bridge$setOwner(playerInventory.player); ((CraftingInventoryBridge) this.craftMatrix).bridge$setOwner(playerInventory.player);
((CraftingInventoryBridge) this.field_75162_e).bridge$setResultInventory(this.field_75160_f); ((CraftingInventoryBridge) this.craftMatrix).bridge$setResultInventory(this.craftResult);
this.player = playerInventory; this.player = playerInventory;
} }
@ -101,7 +101,7 @@ public abstract class WorkbenchContainerMixin extends ContainerMixin implements
return bukkitEntity; return bukkitEntity;
} }
CraftInventoryCrafting inventory = new CraftInventoryCrafting(this.field_75162_e, this.field_75160_f); CraftInventoryCrafting inventory = new CraftInventoryCrafting(this.craftMatrix, this.craftResult);
bukkitEntity = new CraftInventoryView(((PlayerEntityBridge) this.player.player).bridge$getBukkitEntity(), inventory, (Container) (Object) this); bukkitEntity = new CraftInventoryView(((PlayerEntityBridge) this.player.player).bridge$getBukkitEntity(), inventory, (Container) (Object) this);
return bukkitEntity; return bukkitEntity;
} }

View File

@ -49,6 +49,10 @@ public abstract class RecipeManagerMixin implements RecipeManagerBridge {
this.someRecipesErrored = false; this.someRecipesErrored = false;
Map<IRecipeType<?>, Object2ObjectLinkedOpenHashMap<ResourceLocation, IRecipe<?>>> map = Maps.newHashMap(); Map<IRecipeType<?>, Object2ObjectLinkedOpenHashMap<ResourceLocation, IRecipe<?>>> map = Maps.newHashMap();
for (IRecipeType<?> type : Registry.RECIPE_TYPE) {
map.put(type, new Object2ObjectLinkedOpenHashMap<>());
}
for (Map.Entry<ResourceLocation, JsonObject> entry : splashList.entrySet()) { for (Map.Entry<ResourceLocation, JsonObject> entry : splashList.entrySet()) {
ResourceLocation resourcelocation = entry.getKey(); ResourceLocation resourcelocation = entry.getKey();
if (resourcelocation.getPath().startsWith("_")) if (resourcelocation.getPath().startsWith("_"))

View File

@ -24,6 +24,8 @@ import net.minecraft.server.MinecraftServer;
import net.minecraft.server.management.PlayerProfileCache; import net.minecraft.server.management.PlayerProfileCache;
import net.minecraft.util.SharedConstants; import net.minecraft.util.SharedConstants;
import net.minecraft.util.Util; import net.minecraft.util.Util;
import net.minecraft.util.concurrent.RecursiveEventLoop;
import net.minecraft.util.concurrent.TickDelayedTask;
import net.minecraft.util.text.StringTextComponent; import net.minecraft.util.text.StringTextComponent;
import net.minecraft.world.WorldSettings; import net.minecraft.world.WorldSettings;
import net.minecraft.world.WorldType; import net.minecraft.world.WorldType;
@ -65,7 +67,7 @@ import java.util.Date;
import java.util.function.BooleanSupplier; import java.util.function.BooleanSupplier;
@Mixin(MinecraftServer.class) @Mixin(MinecraftServer.class)
public abstract class MinecraftServerMixin implements MinecraftServerBridge, ICommandSourceBridge { public abstract class MinecraftServerMixin extends RecursiveEventLoop<TickDelayedTask> implements MinecraftServerBridge, ICommandSourceBridge {
// @formatter:off // @formatter:off
@Shadow private int tickCounter; @Shadow private int tickCounter;
@ -91,8 +93,13 @@ public abstract class MinecraftServerMixin implements MinecraftServerBridge, ICo
@Shadow private boolean serverStopped; @Shadow private boolean serverStopped;
@Shadow protected abstract void stopServer(); @Shadow protected abstract void stopServer();
@Shadow protected abstract void systemExitNow(); @Shadow protected abstract void systemExitNow();
@Shadow public abstract Commands getCommandManager();
// @formatter:on // @formatter:on
public MinecraftServerMixin(String name) {
super(name);
}
public CraftServer server; public CraftServer server;
public OptionSet options; public OptionSet options;
public ConsoleCommandSender console; public ConsoleCommandSender console;
@ -169,7 +176,7 @@ public abstract class MinecraftServerMixin implements MinecraftServerBridge, ICo
this.serverTime += 50L; this.serverTime += 50L;
if (this.startProfiling) { if (this.startProfiling) {
this.startProfiling = false; this.startProfiling = false;
this.profiler.func_219899_d().func_219939_d(); this.profiler.getFixedProfiler().enable();
} }
this.profiler.startTick(); this.profiler.startTick();
@ -319,9 +326,13 @@ public abstract class MinecraftServerMixin implements MinecraftServerBridge, ICo
processQueue.add(runnable); processQueue.add(runnable);
} }
public CommandSender getBukkitSender(CommandSource wrapper) {
return console;
}
@Override @Override
public CommandSender bridge$getBukkitSender(CommandSource wrapper) { public CommandSender bridge$getBukkitSender(CommandSource wrapper) {
return console; return getBukkitSender(wrapper);
} }
private static MinecraftServer getServer() { private static MinecraftServer getServer() {

View File

@ -2,18 +2,23 @@ package io.izzel.arclight.common.mixin.core.server.dedicated;
import io.izzel.arclight.common.mixin.core.server.MinecraftServerMixin; import io.izzel.arclight.common.mixin.core.server.MinecraftServerMixin;
import io.izzel.arclight.common.mod.server.BukkitRegistry; import io.izzel.arclight.common.mod.server.BukkitRegistry;
import net.minecraft.command.CommandSource;
import net.minecraft.command.Commands;
import net.minecraft.network.rcon.RConConsoleSource; import net.minecraft.network.rcon.RConConsoleSource;
import net.minecraft.server.dedicated.DedicatedServer; import net.minecraft.server.dedicated.DedicatedServer;
import net.minecraft.util.text.ITextComponent;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v.CraftServer; import org.bukkit.craftbukkit.v.CraftServer;
import org.bukkit.craftbukkit.v.command.CraftRemoteConsoleCommandSender; import org.bukkit.craftbukkit.v.command.CraftRemoteConsoleCommandSender;
import org.bukkit.event.server.RemoteServerCommandEvent;
import org.bukkit.event.server.ServerCommandEvent;
import org.bukkit.plugin.PluginLoadOrder; import org.bukkit.plugin.PluginLoadOrder;
import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@ -24,6 +29,10 @@ public abstract class DedicatedServerMixin extends MinecraftServerMixin {
@Shadow @Final public RConConsoleSource rconConsoleSource; @Shadow @Final public RConConsoleSource rconConsoleSource;
// @formatter:on // @formatter:on
public DedicatedServerMixin(String name) {
super(name);
}
@Inject(method = "init", at = @At(value = "INVOKE", shift = At.Shift.AFTER, target = "Lnet/minecraft/server/dedicated/DedicatedServer;setPlayerList(Lnet/minecraft/server/management/PlayerList;)V")) @Inject(method = "init", at = @At(value = "INVOKE", shift = At.Shift.AFTER, target = "Lnet/minecraft/server/dedicated/DedicatedServer;setPlayerList(Lnet/minecraft/server/management/PlayerList;)V"))
public void arclight$loadPlugins(CallbackInfoReturnable<Boolean> cir) { public void arclight$loadPlugins(CallbackInfoReturnable<Boolean> cir) {
BukkitRegistry.unlockRegistries(); BukkitRegistry.unlockRegistries();
@ -37,10 +46,37 @@ public abstract class DedicatedServerMixin extends MinecraftServerMixin {
this.remoteConsole = new CraftRemoteConsoleCommandSender(this.rconConsoleSource); this.remoteConsole = new CraftRemoteConsoleCommandSender(this.rconConsoleSource);
} }
@Inject(method = "sendMessage", cancellable = true, at = @At("HEAD")) @Redirect(method = "executePendingCommands", at = @At(value = "INVOKE", target = "Lnet/minecraft/command/Commands;handleCommand(Lnet/minecraft/command/CommandSource;Ljava/lang/String;)I"))
public void arclight$consoleLog(ITextComponent message, CallbackInfo ci) { private int arclight$serverCommandEvent(Commands commands, CommandSource source, String command) {
Bukkit.getConsoleSender().sendMessage(message.getFormattedText()); ServerCommandEvent event = new ServerCommandEvent(console, command);
ci.cancel(); Bukkit.getPluginManager().callEvent(event);
if (!event.isCancelled()) {
return commands.handleCommand(source, event.getCommand());
}
return 0;
}
/**
* @author IzzelAliz
* @reason
*/
@Overwrite
public String handleRConCommand(String command) {
this.rconConsoleSource.resetLog();
this.runImmediately(() -> {
RemoteServerCommandEvent event = new RemoteServerCommandEvent(remoteConsole, command);
Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) {
return;
}
ServerCommandEvent event2 = new ServerCommandEvent(console, event.getCommand());
Bukkit.getPluginManager().callEvent(event2);
if (event2.isCancelled()) {
return;
}
this.getCommandManager().handleCommand(this.rconConsoleSource.getCommandSource(), event2.getCommand());
});
return this.rconConsoleSource.getLogContents();
} }
@Inject(method = "systemExitNow", at = @At("RETURN")) @Inject(method = "systemExitNow", at = @At("RETURN"))

View File

@ -1,12 +1,20 @@
package io.izzel.arclight.common.mixin.core.tileentity; package io.izzel.arclight.common.mixin.core.tileentity;
import com.google.common.base.Joiner;
import io.izzel.arclight.common.bridge.command.CommandSourceBridge;
import net.minecraft.command.CommandSource;
import net.minecraft.command.Commands;
import net.minecraft.tileentity.CommandBlockLogic; import net.minecraft.tileentity.CommandBlockLogic;
import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.StringTextComponent; import net.minecraft.util.text.StringTextComponent;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v.CraftServer;
import org.bukkit.event.server.ServerCommandEvent;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(CommandBlockLogic.class) @Mixin(CommandBlockLogic.class)
@ -16,11 +24,43 @@ public class CommandBlockLogicMixin {
@Shadow private ITextComponent customName; @Shadow private ITextComponent customName;
// @formatter:on // @formatter:on
@Inject(method = "setName", cancellable = true, at = @At("HEAD")) @Redirect(method = "trigger", at = @At(value = "INVOKE", target = "Lnet/minecraft/command/Commands;handleCommand(Lnet/minecraft/command/CommandSource;Ljava/lang/String;)I"))
private int arclight$serverCommand(Commands commands, CommandSource sender, String command) {
Joiner joiner = Joiner.on(" ");
if (command.startsWith("/")) {
command = command.substring(1);
}
ServerCommandEvent event = new ServerCommandEvent(((CommandSourceBridge) sender).bridge$getBukkitSender(), command);
Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) {
return 0;
}
command = event.getCommand();
String[] args = command.split(" ");
String cmd = args[0];
if (cmd.startsWith("minecraft:")) cmd = cmd.substring("minecraft:".length());
if (cmd.startsWith("bukkit:")) cmd = cmd.substring("bukkit:".length());
if (cmd.equalsIgnoreCase("stop") || cmd.equalsIgnoreCase("kick") || cmd.equalsIgnoreCase("op")
|| cmd.equalsIgnoreCase("deop") || cmd.equalsIgnoreCase("ban") || cmd.equalsIgnoreCase("ban-ip")
|| cmd.equalsIgnoreCase("pardon") || cmd.equalsIgnoreCase("pardon-ip") || cmd.equalsIgnoreCase("reload")) {
return 0;
}
if (((CraftServer) Bukkit.getServer()).getCommandBlockOverride(args[0])) {
args[0] = "minecraft:" + args[0];
}
return commands.handleCommand(sender, joiner.join(args));
}
@Inject(method = "setName", at = @At("RETURN"))
public void arclight$setName(ITextComponent nameIn, CallbackInfo ci) { public void arclight$setName(ITextComponent nameIn, CallbackInfo ci) {
if (nameIn == null) { if (this.customName == null) {
this.customName = new StringTextComponent("@"); this.customName = new StringTextComponent("@");
ci.cancel();
} }
} }
} }

View File

@ -13,8 +13,12 @@ public class CommandBlockTileEntity1Mixin implements ICommandSourceBridge {
@Shadow(aliases = {"this$0", "field_145767_a"}, remap = false) private CommandBlockTileEntity outerThis; @Shadow(aliases = {"this$0", "field_145767_a"}, remap = false) private CommandBlockTileEntity outerThis;
@Override public CommandSender getBukkitSender(CommandSource wrapper) {
public CommandSender bridge$getBukkitSender(CommandSource wrapper) {
return new CraftBlockCommandSender(wrapper, outerThis); return new CraftBlockCommandSender(wrapper, outerThis);
} }
@Override
public CommandSender bridge$getBukkitSender(CommandSource wrapper) {
return getBukkitSender(wrapper);
}
} }

View File

@ -73,8 +73,12 @@ public abstract class LecternTileEntityMixin extends TileEntityMixin implements
return false; return false;
} }
@Override public CommandSender getBukkitSender(CommandSource wrapper) {
public CommandSender bridge$getBukkitSender(CommandSource wrapper) {
return wrapper.getEntity() != null ? ((EntityBridge) wrapper.getEntity()).bridge$getBukkitSender(wrapper) : new CraftBlockCommandSender(wrapper, (TileEntity) (Object) this); return wrapper.getEntity() != null ? ((EntityBridge) wrapper.getEntity()).bridge$getBukkitSender(wrapper) : new CraftBlockCommandSender(wrapper, (TileEntity) (Object) this);
} }
@Override
public CommandSender bridge$getBukkitSender(CommandSource wrapper) {
return getBukkitSender(wrapper);
}
} }

View File

@ -63,8 +63,12 @@ public abstract class SignTileEntityMixin extends TileEntityMixin implements Sig
return false; return false;
} }
@Override public CommandSender getBukkitSender(CommandSource wrapper) {
public CommandSender bridge$getBukkitSender(CommandSource wrapper) {
return wrapper.getEntity() != null ? ((EntityBridge) wrapper.getEntity()).bridge$getBukkitSender(wrapper) : new CraftBlockCommandSender(wrapper, (TileEntity) (Object) this); return wrapper.getEntity() != null ? ((EntityBridge) wrapper.getEntity()).bridge$getBukkitSender(wrapper) : new CraftBlockCommandSender(wrapper, (TileEntity) (Object) this);
} }
@Override
public CommandSender bridge$getBukkitSender(CommandSource wrapper) {
return getBukkitSender(wrapper);
}
} }

View File

@ -147,6 +147,15 @@ public abstract class WorldMixin implements WorldBridge {
return this.world; return this.world;
} }
public TileEntity getTileEntity(BlockPos pos, boolean validate) {
return getTileEntity(pos);
}
@Override
public TileEntity bridge$getTileEntity(BlockPos pos, boolean validate) {
return getTileEntity(pos, validate);
}
@Override @Override
public CraftServer bridge$getServer() { public CraftServer bridge$getServer() {
return (CraftServer) Bukkit.getServer(); return (CraftServer) Bukkit.getServer();

View File

@ -2,20 +2,13 @@ package io.izzel.arclight.common.mixin.core.world.chunk;
import io.izzel.arclight.common.bridge.world.WorldBridge; import io.izzel.arclight.common.bridge.world.WorldBridge;
import io.izzel.arclight.common.bridge.world.chunk.ChunkBridge; import io.izzel.arclight.common.bridge.world.chunk.ChunkBridge;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.fluid.Fluid;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos; import net.minecraft.util.math.ChunkPos;
import net.minecraft.world.ITickList;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.chunk.Chunk; import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.ChunkPrimer; import net.minecraft.world.chunk.ChunkPrimer;
import net.minecraft.world.chunk.ChunkSection;
import net.minecraft.world.chunk.UpgradeData;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v.CraftChunk;
import org.bukkit.event.world.ChunkLoadEvent; import org.bukkit.event.world.ChunkLoadEvent;
import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
@ -27,7 +20,6 @@ import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.function.Consumer;
@Mixin(Chunk.class) @Mixin(Chunk.class)
public abstract class ChunkMixin implements ChunkBridge { public abstract class ChunkMixin implements ChunkBridge {
@ -136,12 +128,6 @@ public abstract class ChunkMixin implements ChunkBridge {
this.mustNotSave = !unloadEvent.isSaveChunk(); this.mustNotSave = !unloadEvent.isSaveChunk();
} }
@Inject(method = "<init>(Lnet/minecraft/world/World;Lnet/minecraft/util/math/ChunkPos;[Lnet/minecraft/world/biome/Biome;Lnet/minecraft/world/chunk/UpgradeData;Lnet/minecraft/world/ITickList;Lnet/minecraft/world/ITickList;J[Lnet/minecraft/world/chunk/ChunkSection;Ljava/util/function/Consumer;)V",
at = @At("RETURN"))
public void arclight$setBukkitChunk(World worldIn, ChunkPos p_i49946_2_, Biome[] p_i49946_3_, UpgradeData p_i49946_4_, ITickList<Block> p_i49946_5_, ITickList<Fluid> p_i49946_6_, long p_i49946_7_, ChunkSection[] p_i49946_9_, Consumer<Chunk> p_i49946_10_, CallbackInfo ci) {
this.bukkitChunk = new CraftChunk((Chunk) (Object) this);
}
@Inject(method = "<init>(Lnet/minecraft/world/World;Lnet/minecraft/world/chunk/ChunkPrimer;)V", @Inject(method = "<init>(Lnet/minecraft/world/World;Lnet/minecraft/world/chunk/ChunkPrimer;)V",
at = @At("RETURN")) at = @At("RETURN"))
public void arclight$setNeedsDecoration(World worldIn, ChunkPrimer p_i49947_2_, CallbackInfo ci) { public void arclight$setNeedsDecoration(World worldIn, ChunkPrimer p_i49947_2_, CallbackInfo ci) {

View File

@ -41,6 +41,7 @@ public abstract class ServerChunkProviderMixin implements ServerChunkProviderBri
@Shadow protected abstract void invalidateCaches(); @Shadow protected abstract void invalidateCaches();
@Shadow @Nullable protected abstract ChunkHolder func_217213_a(long chunkPosIn); @Shadow @Nullable protected abstract ChunkHolder func_217213_a(long chunkPosIn);
@Shadow protected abstract boolean func_217235_l(); @Shadow protected abstract boolean func_217235_l();
@Shadow protected abstract boolean func_217224_a(@Nullable ChunkHolder chunkHolderIn, int p_217224_2_);
@Invoker("func_217235_l") public abstract boolean bridge$tickDistanceManager(); @Invoker("func_217235_l") public abstract boolean bridge$tickDistanceManager();
@Accessor("lightManager") public abstract ServerWorldLightManager bridge$getLightManager(); @Accessor("lightManager") public abstract ServerWorldLightManager bridge$getLightManager();
// @formatter:on // @formatter:on
@ -57,12 +58,12 @@ public abstract class ServerChunkProviderMixin implements ServerChunkProviderBri
ChunkHolder chunkholder = this.func_217213_a(i); ChunkHolder chunkholder = this.func_217213_a(i);
boolean unloading = false; boolean unloading = false;
if (chunkholder != null) { if (chunkholder != null) {
ChunkHolder.LocationType chunkStatus = ChunkHolder.func_219286_c(((ChunkHolderBridge) chunkholder).bridge$getOldTicketLevel()); ChunkHolder.LocationType chunkStatus = ChunkHolder.getLocationTypeFromLevel(((ChunkHolderBridge) chunkholder).bridge$getOldTicketLevel());
ChunkHolder.LocationType currentStatus = ChunkHolder.func_219286_c(chunkholder.func_219299_i()); ChunkHolder.LocationType currentStatus = ChunkHolder.getLocationTypeFromLevel(chunkholder.getChunkLevel());
unloading = chunkStatus.func_219065_a(ChunkHolder.LocationType.BORDER) && !currentStatus.func_219065_a(ChunkHolder.LocationType.BORDER); unloading = chunkStatus.isAtLeast(ChunkHolder.LocationType.BORDER) && !currentStatus.isAtLeast(ChunkHolder.LocationType.BORDER);
} }
if (load && !unloading) { if (load && !unloading) {
this.ticketManager.func_219356_a(TicketType.UNKNOWN, chunkpos, j, chunkpos); this.ticketManager.registerWithLevel(TicketType.UNKNOWN, chunkpos, j, chunkpos);
if (this.func_217224_a(chunkholder, j)) { if (this.func_217224_a(chunkholder, j)) {
IProfiler iprofiler = this.world.getProfiler(); IProfiler iprofiler = this.world.getProfiler();
iprofiler.startSection("chunkLoad"); iprofiler.startSection("chunkLoad");
@ -78,15 +79,6 @@ public abstract class ServerChunkProviderMixin implements ServerChunkProviderBri
return this.func_217224_a(chunkholder, j) ? ChunkHolder.MISSING_CHUNK_FUTURE : chunkholder.func_219276_a(requiredStatus, this.chunkManager); return this.func_217224_a(chunkholder, j) ? ChunkHolder.MISSING_CHUNK_FUTURE : chunkholder.func_219276_a(requiredStatus, this.chunkManager);
} }
/**
* @author IzzelAliz
* @reason
*/
@Overwrite
private boolean func_217224_a(@Nullable ChunkHolder chunkHolderIn, int p_217224_2_) {
return chunkHolderIn == null || ((ChunkHolderBridge) chunkHolderIn).bridge$getOldTicketLevel() > p_217224_2_;
}
public void close(boolean save) throws IOException { public void close(boolean save) throws IOException {
if (save) { if (save) {
this.save(true); this.save(true);
@ -115,7 +107,7 @@ public abstract class ServerChunkProviderMixin implements ServerChunkProviderBri
this.purgeUnload(); this.purgeUnload();
} }
@Redirect(method = "func_217224_a", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/server/ChunkHolder;func_219299_i()I")) @Redirect(method = "func_217224_a", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/server/ChunkHolder;getChunkLevel()I"))
public int arclight$useOldTicketLevel(ChunkHolder chunkHolder) { public int arclight$useOldTicketLevel(ChunkHolder chunkHolder) {
return ((ChunkHolderBridge) chunkHolder).bridge$getOldTicketLevel(); return ((ChunkHolderBridge) chunkHolder).bridge$getOldTicketLevel();
} }

View File

@ -153,7 +153,7 @@ public abstract class ServerWorldMixin extends WorldMixin implements ServerWorld
@Overwrite @Overwrite
@Nullable @Nullable
public MapData getMapData(String mapName) { public MapData getMapData(String mapName) {
return this.shadow$getServer().func_71218_a(DimensionType.OVERWORLD).getSavedData().get(() -> { return this.shadow$getServer().getWorld(DimensionType.OVERWORLD).getSavedData().get(() -> {
MapData newMap = new MapData(mapName); MapData newMap = new MapData(mapName);
MapInitializeEvent event = new MapInitializeEvent(((MapDataBridge) newMap).bridge$getMapView()); MapInitializeEvent event = new MapInitializeEvent(((MapDataBridge) newMap).bridge$getMapView());
Bukkit.getServer().getPluginManager().callEvent(event); Bukkit.getServer().getPluginManager().callEvent(event);
@ -273,8 +273,13 @@ public abstract class ServerWorldMixin extends WorldMixin implements ServerWorld
@Override @Override
public TileEntity getTileEntity(BlockPos pos) { public TileEntity getTileEntity(BlockPos pos) {
return getTileEntity(pos, true);
}
@Override
public TileEntity getTileEntity(BlockPos pos, boolean validate) {
TileEntity result = super.getTileEntity(pos); TileEntity result = super.getTileEntity(pos);
if (Thread.currentThread() != arclight$getMainThread()) { if (!validate || Thread.currentThread() != arclight$getMainThread()) {
return result; return result;
} }
@ -301,7 +306,7 @@ public abstract class ServerWorldMixin extends WorldMixin implements ServerWorld
if (type.hasTileEntity(state)) { if (type.hasTileEntity(state)) {
TileEntity replacement = type.createTileEntity(state, (IBlockReader) this); TileEntity replacement = type.createTileEntity(state, (IBlockReader) this);
if (replacement == null) return found; if (replacement == null) return found;
replacement.setWorld((World) (Object) this); replacement.world = ((World) (Object) this);
this.setTileEntity(pos, replacement); this.setTileEntity(pos, replacement);
return replacement; return replacement;
} else { } else {

View File

@ -0,0 +1,32 @@
package io.izzel.arclight.common.mixin.v1_15.block;
import net.minecraft.block.AbstractButtonBlock;
import net.minecraft.block.BlockState;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.server.ServerWorld;
import org.bukkit.Bukkit;
import org.bukkit.block.Block;
import org.bukkit.craftbukkit.v.block.CraftBlock;
import org.bukkit.event.block.BlockRedstoneEvent;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.Random;
@Mixin(AbstractButtonBlock.class)
public class AbstractButtonBlockMixin_1_15 {
@Inject(method = "tick", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/server/ServerWorld;setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;I)Z"))
private void arclight$blockRedstone2(BlockState state, ServerWorld worldIn, BlockPos pos, Random rand, CallbackInfo ci) {
Block block = CraftBlock.at(worldIn, pos);
BlockRedstoneEvent event = new BlockRedstoneEvent(block, 15, 0);
Bukkit.getPluginManager().callEvent(event);
if (event.getNewCurrent() > 0) {
ci.cancel();
}
}
}

View File

@ -0,0 +1,19 @@
package io.izzel.arclight.common.mixin.v1_15.block;
import net.minecraft.block.BlockState;
import net.minecraft.block.CactusBlock;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.server.ServerWorld;
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(CactusBlock.class)
public class CactusBlockMixin_1_15 {
@Redirect(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/server/ServerWorld;setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;)Z"))
private boolean arclight$blockGrow(ServerWorld serverWorld, BlockPos pos, BlockState state) {
return CraftEventFactory.handleBlockGrowEvent(serverWorld, pos, state);
}
}

View File

@ -0,0 +1,28 @@
package io.izzel.arclight.common.mixin.v1_15.block;
import io.izzel.arclight.common.bridge.entity.player.ServerPlayerEntityBridge;
import net.minecraft.block.BlockState;
import net.minecraft.block.CakeBlock;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.FoodStats;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IWorld;
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
import org.bukkit.event.entity.FoodLevelChangeEvent;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(CakeBlock.class)
public class CakeBlockMixin_1_15 {
@Redirect(method = "func_226911_a_", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/FoodStats;addStats(IF)V"))
private void arclight$eatCake(FoodStats foodStats, int foodLevelIn, float foodSaturationModifier, IWorld worldIn, BlockPos pos, BlockState state, PlayerEntity player) {
int old = foodStats.getFoodLevel();
FoodLevelChangeEvent event = CraftEventFactory.callFoodLevelChangeEvent(player, old + foodLevelIn);
if (!event.isCancelled()) {
foodStats.addStats(event.getFoodLevel() - old, foodSaturationModifier);
}
((ServerPlayerEntityBridge) player).bridge$getBukkitEntity().sendHealthUpdate();
}
}

View File

@ -0,0 +1,103 @@
package io.izzel.arclight.common.mixin.v1_15.block;
import io.izzel.arclight.common.bridge.entity.EntityBridge;
import net.minecraft.block.BlockState;
import net.minecraft.block.CauldronBlock;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.potion.PotionUtils;
import net.minecraft.potion.Potions;
import net.minecraft.util.ActionResultType;
import net.minecraft.util.Hand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.World;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v.block.CraftBlock;
import org.bukkit.event.block.CauldronLevelChangeEvent;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(CauldronBlock.class)
public class CauldronBlockMixin_1_15 {
@Inject(method = "onEntityCollision", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;extinguish()V"))
public void arclight$extinguish(BlockState state, World worldIn, BlockPos pos, Entity entityIn, CallbackInfo ci) {
int i = state.get(CauldronBlock.LEVEL);
if (!changeLevel(worldIn, pos, state, i - 1, entityIn, CauldronLevelChangeEvent.ChangeReason.EXTINGUISH)) {
ci.cancel();
}
}
@Inject(method = "onBlockActivated", cancellable = true, at = @At(value = "FIELD", target = "Lnet/minecraft/entity/player/PlayerEntity;abilities:Lnet/minecraft/entity/player/PlayerAbilities;"))
public void arclight$levelChange(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn, BlockRayTraceResult hit, CallbackInfoReturnable<ActionResultType> cir) {
ItemStack itemStack = player.getHeldItem(handIn);
Item item = itemStack.getItem();
int i = state.get(CauldronBlock.LEVEL);
int newLevel;
CauldronLevelChangeEvent.ChangeReason reason;
if (item == Items.WATER_BUCKET) {
reason = CauldronLevelChangeEvent.ChangeReason.BUCKET_EMPTY;
newLevel = 3;
} else if (item == Items.BUCKET) {
reason = CauldronLevelChangeEvent.ChangeReason.BUCKET_FILL;
newLevel = 0;
} else if (item == Items.GLASS_BOTTLE) {
reason = CauldronLevelChangeEvent.ChangeReason.BOTTLE_FILL;
newLevel = i - 1;
} else if (item == Items.POTION && PotionUtils.getPotionFromItem(itemStack) == Potions.WATER) {
reason = CauldronLevelChangeEvent.ChangeReason.BOTTLE_EMPTY;
newLevel = i + 1;
} else {
reason = null;
newLevel = 0;
}
if (reason != null && !changeLevel(worldIn, pos, state, newLevel, player, reason)) {
cir.setReturnValue(ActionResultType.SUCCESS);
}
}
@Inject(method = "onBlockActivated", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/item/IDyeableArmorItem;removeColor(Lnet/minecraft/item/ItemStack;)V"))
public void arclight$removeColor(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn, BlockRayTraceResult hit, CallbackInfoReturnable<ActionResultType> cir) {
int i = state.get(CauldronBlock.LEVEL);
if (!changeLevel(worldIn, pos, state, i - 1, player, CauldronLevelChangeEvent.ChangeReason.ARMOR_WASH)) {
cir.setReturnValue(ActionResultType.SUCCESS);
}
}
@Inject(method = "onBlockActivated", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/tileentity/BannerTileEntity;removeBannerData(Lnet/minecraft/item/ItemStack;)V"))
public void arclight$removeBanner(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn, BlockRayTraceResult hit, CallbackInfoReturnable<ActionResultType> cir) {
int i = state.get(CauldronBlock.LEVEL);
if (!changeLevel(worldIn, pos, state, i - 1, player, CauldronLevelChangeEvent.ChangeReason.BANNER_WASH)) {
cir.setReturnValue(ActionResultType.SUCCESS);
}
}
@Inject(method = "fillWithRain", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;I)Z"))
public void arclight$fillRain(World worldIn, BlockPos pos, CallbackInfo ci) {
BlockState state = worldIn.getBlockState(pos);
BlockState cycle = state.cycle(CauldronBlock.LEVEL);
int newLevel = cycle.get(CauldronBlock.LEVEL);
if (!changeLevel(worldIn, pos, state, newLevel, null, CauldronLevelChangeEvent.ChangeReason.UNKNOWN)) {
ci.cancel();
}
}
private boolean changeLevel(World world, BlockPos pos, BlockState state, int i, Entity entity, CauldronLevelChangeEvent.ChangeReason reason) {
int newLevel = MathHelper.clamp(i, 0, 3);
CauldronLevelChangeEvent event = new CauldronLevelChangeEvent(
CraftBlock.at(world, pos),
(entity == null) ? null : ((EntityBridge) entity).bridge$getBukkitEntity(),
reason, state.get(CauldronBlock.LEVEL), newLevel
);
Bukkit.getPluginManager().callEvent(event);
return !event.isCancelled();
}
}

View File

@ -0,0 +1,24 @@
package io.izzel.arclight.common.mixin.v1_15.block;
import io.izzel.arclight.common.mod.util.ChestBlockDoubleInventoryHacks;
import net.minecraft.inventory.DoubleSidedInventory;
import net.minecraft.inventory.container.INamedContainerProvider;
import net.minecraft.tileentity.ChestTileEntity;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
import java.util.Optional;
@Mixin(targets = "net/minecraft/block/ChestBlock$2")
public class ChestBlock2Mixin_1_15 {
/**
* @author IzzelAliz
* @reason
*/
@Overwrite
public Optional<INamedContainerProvider> func_225539_a_(final ChestTileEntity p_225539_1_, final ChestTileEntity p_225539_2_) {
final DoubleSidedInventory iinventory = new DoubleSidedInventory(p_225539_1_, p_225539_2_);
return Optional.ofNullable(ChestBlockDoubleInventoryHacks.create(p_225539_1_, p_225539_2_, iinventory));
}
}

View File

@ -0,0 +1,118 @@
package io.izzel.arclight.common.mixin.v1_15.block;
import io.izzel.arclight.common.mixin.core.block.BlockMixin;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.ChorusFlowerBlock;
import net.minecraft.block.ChorusPlantBlock;
import net.minecraft.state.IntegerProperty;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IWorldReader;
import net.minecraft.world.World;
import net.minecraft.world.server.ServerWorld;
import net.minecraftforge.common.ForgeHooks;
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.Shadow;
import javax.annotation.Nullable;
import java.util.Random;
@Mixin(ChorusFlowerBlock.class)
public abstract class ChorusFlowerBlockMixin_1_15 extends BlockMixin {
// @formatter:off
@Shadow @Final public static IntegerProperty AGE;
@Shadow @Final private ChorusPlantBlock field_196405_b;
@Shadow private static boolean areAllNeighborsEmpty(IWorldReader worldIn, BlockPos pos, @Nullable Direction excludingSide) { return false; }
@Shadow protected abstract void placeGrownFlower(World worldIn, BlockPos pos, int age);
@Shadow protected abstract void placeDeadFlower(World worldIn, BlockPos pos);
// @formatter:on
/**
* @author IzzelAliz
* @reason
*/
@Overwrite
public void tick(BlockState state, ServerWorld worldIn, BlockPos pos, Random random) {
if (!state.isValidPosition(worldIn, pos)) {
worldIn.destroyBlock(pos, true);
} else {
BlockPos blockpos = pos.up();
if (worldIn.isAirBlock(blockpos) && blockpos.getY() < worldIn.getDimension().getHeight()) {
int i = state.get(AGE);
if (i < 5 && ForgeHooks.onCropsGrowPre(worldIn, blockpos, state, true)) {
boolean flag = false;
boolean flag1 = false;
BlockState blockstate = worldIn.getBlockState(pos.down());
Block block = blockstate.getBlock();
if (block == Blocks.END_STONE) {
flag = true;
} else if (block == this.field_196405_b) {
int j = 1;
for (int k = 0; k < 4; ++k) {
Block block1 = worldIn.getBlockState(pos.down(j + 1)).getBlock();
if (block1 != this.field_196405_b) {
if (block1 == Blocks.END_STONE) {
flag1 = true;
}
break;
}
++j;
}
if (j < 2 || j <= random.nextInt(flag1 ? 5 : 4)) {
flag = true;
}
} else if (blockstate.isAir(worldIn, pos.down())) {
flag = true;
}
if (flag && areAllNeighborsEmpty(worldIn, blockpos, (Direction) null) && worldIn.isAirBlock(pos.up(2))) {
if (CraftEventFactory.handleBlockSpreadEvent(worldIn, pos, pos.up(), state.with(ChorusFlowerBlock.AGE, i), 2)) {
worldIn.setBlockState(pos, this.field_196405_b.makeConnections(worldIn, pos), 2);
this.placeGrownFlower(worldIn, blockpos, i);
}
} else if (i < 4) {
int l = random.nextInt(4);
if (flag1) {
++l;
}
boolean flag2 = false;
for (int i1 = 0; i1 < l; ++i1) {
Direction direction = Direction.Plane.HORIZONTAL.random(random);
BlockPos blockpos1 = pos.offset(direction);
if (worldIn.isAirBlock(blockpos1) && worldIn.isAirBlock(blockpos1.down()) && areAllNeighborsEmpty(worldIn, blockpos1, direction.getOpposite())) {
if (CraftEventFactory.handleBlockSpreadEvent(worldIn, pos, blockpos1, state.with(ChorusFlowerBlock.AGE, i + 1), 2)) {
this.placeGrownFlower(worldIn, blockpos1, i + 1);
flag2 = true;
}
}
}
if (flag2) {
worldIn.setBlockState(pos, this.field_196405_b.makeConnections(worldIn, pos), 2);
} else {
if (CraftEventFactory.handleBlockGrowEvent(worldIn, pos, this.getDefaultState().with(ChorusFlowerBlock.AGE, 5), 2)) {
this.placeDeadFlower(worldIn, pos);
}
}
} else {
if (CraftEventFactory.handleBlockGrowEvent(worldIn, pos, this.getDefaultState().with(ChorusFlowerBlock.AGE, 5), 2)) {
this.placeDeadFlower(worldIn, pos);
}
}
ForgeHooks.onCropsGrowPost(worldIn, pos, state);
}
}
}
}
}

View File

@ -0,0 +1,19 @@
package io.izzel.arclight.common.mixin.v1_15.block;
import net.minecraft.block.BlockState;
import net.minecraft.block.CocoaBlock;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.server.ServerWorld;
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(CocoaBlock.class)
public class CocoaBlockMixin_1_15 {
@Redirect(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/server/ServerWorld;setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;I)Z"))
public boolean arclight$blockGrow(ServerWorld world, BlockPos pos, BlockState newState, int flags) {
return CraftEventFactory.handleBlockGrowEvent(world, pos, newState, flags);
}
}

View File

@ -0,0 +1,31 @@
package io.izzel.arclight.common.mixin.v1_15.block;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.CoralBlock;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.server.ServerWorld;
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.Random;
@Mixin(CoralBlock.class)
public class CoralBlockMixin_1_15 {
// @formatter:off
@Shadow @Final private Block deadBlock;
// @formatter:on
@Inject(method = "tick", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/server/ServerWorld;setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;I)Z"))
public void arclight$blockFade(BlockState state, ServerWorld worldIn, BlockPos pos, Random random, CallbackInfo ci) {
if (CraftEventFactory.callBlockFadeEvent(worldIn, pos, this.deadBlock.getDefaultState()).isCancelled()) {
ci.cancel();
}
}
}

View File

@ -0,0 +1,32 @@
package io.izzel.arclight.common.mixin.v1_15.block;
import net.minecraft.block.AbstractCoralPlantBlock;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.CoralFinBlock;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.server.ServerWorld;
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.Random;
@Mixin(CoralFinBlock.class)
public class CoralFinBlockMixin_1_15 {
// @formatter:off
@Shadow @Final private Block deadBlock;
// @formatter:on
@Inject(method = "tick", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/server/ServerWorld;setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;I)Z"))
public void arclight$blockFade(BlockState state, ServerWorld worldIn, BlockPos pos, Random random, CallbackInfo ci) {
if (CraftEventFactory.callBlockFadeEvent(worldIn, pos, this.deadBlock.getDefaultState().with(AbstractCoralPlantBlock.WATERLOGGED, false)).isCancelled()) {
ci.cancel();
}
}
}

View File

@ -0,0 +1,32 @@
package io.izzel.arclight.common.mixin.v1_15.block;
import net.minecraft.block.AbstractCoralPlantBlock;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.CoralPlantBlock;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.server.ServerWorld;
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.Random;
@Mixin(CoralPlantBlock.class)
public class CoralPlantBlockMixin_1_15 {
// @formatter:off
@Shadow @Final private Block deadBlock;
// @formatter:on
@Inject(method = "tick", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/server/ServerWorld;setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;I)Z"))
public void arclight$blockFade(BlockState state, ServerWorld worldIn, BlockPos pos, Random random, CallbackInfo ci) {
if (CraftEventFactory.callBlockFadeEvent(worldIn, pos, this.deadBlock.getDefaultState().with(AbstractCoralPlantBlock.WATERLOGGED, false)).isCancelled()) {
ci.cancel();
}
}
}

View File

@ -0,0 +1,35 @@
package io.izzel.arclight.common.mixin.v1_15.block;
import net.minecraft.block.AbstractCoralPlantBlock;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.CoralWallFanBlock;
import net.minecraft.block.DeadCoralWallFanBlock;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.server.ServerWorld;
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.Random;
@Mixin(CoralWallFanBlock.class)
public class CoralWallFanBlockMixin_1_15 {
// @formatter:off
@Shadow @Final private Block deadBlock;
// @formatter:on
@Inject(method = "tick", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/server/ServerWorld;setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;I)Z"))
public void arclight$blockFade(BlockState state, ServerWorld worldIn, BlockPos pos, Random random, CallbackInfo ci) {
if (CraftEventFactory.callBlockFadeEvent(worldIn, pos, this.deadBlock.getDefaultState()
.with(AbstractCoralPlantBlock.WATERLOGGED, Boolean.FALSE)
.with(DeadCoralWallFanBlock.FACING, state.get(DeadCoralWallFanBlock.FACING))).isCancelled()) {
ci.cancel();
}
}
}

View File

@ -0,0 +1,19 @@
package io.izzel.arclight.common.mixin.v1_15.block;
import net.minecraft.block.BlockState;
import net.minecraft.block.CropsBlock;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.server.ServerWorld;
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(CropsBlock.class)
public class CropsBlockMixin_1_15 {
@Redirect(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/server/ServerWorld;setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;I)Z"))
public boolean arclight$blockGrowTick(ServerWorld world, BlockPos pos, BlockState newState, int flags) {
return CraftEventFactory.handleBlockGrowEvent(world, pos, newState, flags);
}
}

View File

@ -0,0 +1,19 @@
package io.izzel.arclight.common.mixin.v1_15.block;
import net.minecraft.block.BlockState;
import net.minecraft.block.FarmlandBlock;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.server.ServerWorld;
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(FarmlandBlock.class)
public class FarmlandBlockMixin_1_15 {
@Redirect(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/server/ServerWorld;setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;I)Z"))
public boolean arclight$moistureChange(ServerWorld world, BlockPos pos, BlockState newState, int flags) {
return CraftEventFactory.handleMoistureChangeEvent(world, pos, newState, flags);
}
}

View File

@ -0,0 +1,34 @@
package io.izzel.arclight.common.mixin.v1_15.block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.FireBlock;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.server.ServerWorld;
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(FireBlock.class)
public class FireBlockMixin_1_15 {
@Redirect(method = "tick", at = @At(value = "INVOKE", ordinal = 1, target = "Lnet/minecraft/world/server/ServerWorld;setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;I)Z"))
public boolean arclight$fireSpread(ServerWorld world, BlockPos mutablePos, BlockState newState, int flags,
BlockState state, ServerWorld worldIn, BlockPos pos) {
if (world.getBlockState(mutablePos).getBlock() != Blocks.FIRE) {
if (!CraftEventFactory.callBlockIgniteEvent(world, mutablePos, pos).isCancelled()) {
return CraftEventFactory.handleBlockSpreadEvent(world, pos, mutablePos, newState, flags);
}
}
return false;
}
@Redirect(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/server/ServerWorld;removeBlock(Lnet/minecraft/util/math/BlockPos;Z)Z"))
public boolean arclight$extinguish1(ServerWorld world, BlockPos pos, boolean isMoving) {
if (!CraftEventFactory.callBlockFadeEvent(world, pos, Blocks.AIR.getDefaultState()).isCancelled()) {
world.removeBlock(pos, isMoving);
}
return false;
}
}

View File

@ -0,0 +1,19 @@
package io.izzel.arclight.common.mixin.v1_15.block;
import net.minecraft.block.BlockState;
import net.minecraft.block.GrassBlock;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.server.ServerWorld;
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(GrassBlock.class)
public class GrassBlockMixin_1_15 {
@Redirect(method = "grow", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/server/ServerWorld;setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;I)Z"))
public boolean arclight$blockGrow(ServerWorld world, BlockPos pos, BlockState newState, int flags) {
return CraftEventFactory.handleBlockGrowEvent(world, pos, newState, flags);
}
}

View File

@ -0,0 +1,19 @@
package io.izzel.arclight.common.mixin.v1_15.block;
import net.minecraft.block.BlockState;
import net.minecraft.block.KelpTopBlock;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.server.ServerWorld;
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(KelpTopBlock.class)
public class KelpTopBlockMixin_1_15 {
@Redirect(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/server/ServerWorld;setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;)Z"))
public boolean arclight$blockGrow(ServerWorld world, BlockPos pos, BlockState state) {
return CraftEventFactory.handleBlockGrowEvent(world, pos, state);
}
}

View File

@ -0,0 +1,28 @@
package io.izzel.arclight.common.mixin.v1_15.block;
import net.minecraft.block.BlockState;
import net.minecraft.block.LeavesBlock;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.server.ServerWorld;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v.block.CraftBlock;
import org.bukkit.event.block.LeavesDecayEvent;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.Random;
@Mixin(LeavesBlock.class)
public class LeavesBlockMixin_1_15 {
@Inject(method = "randomTick", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/block/LeavesBlock;spawnDrops(Lnet/minecraft/block/BlockState;Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;)V"))
public void arclight$leavesDecay(BlockState state, ServerWorld worldIn, BlockPos pos, Random random, CallbackInfo ci) {
LeavesDecayEvent event = new LeavesDecayEvent(CraftBlock.at(worldIn, pos));
Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled() || worldIn.getBlockState(pos).getBlock() != (Object) this) {
ci.cancel();
}
}
}

View File

@ -0,0 +1,38 @@
package io.izzel.arclight.common.mixin.v1_15.block;
import net.minecraft.block.BlockState;
import net.minecraft.block.LeverBlock;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.Hand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.world.World;
import org.bukkit.Bukkit;
import org.bukkit.block.Block;
import org.bukkit.craftbukkit.v.block.CraftBlock;
import org.bukkit.event.block.BlockRedstoneEvent;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
@Mixin(LeverBlock.class)
public class LeverBlockMixin_1_15 {
@Inject(method = "onBlockActivated", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD
, at = @At(value = "INVOKE", target = "Lnet/minecraft/block/LeverBlock;setPowered(Lnet/minecraft/block/BlockState;Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;)Lnet/minecraft/block/BlockState;"))
public void arclight$blockRedstone(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn, BlockRayTraceResult hit, CallbackInfoReturnable<Boolean> cir,
boolean flag) {
Block block = CraftBlock.at(worldIn, pos);
int old = (flag) ? 15 : 0;
int current = (!flag) ? 15 : 0;
BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(block, old, current);
Bukkit.getPluginManager().callEvent(eventRedstone);
if ((eventRedstone.getNewCurrent() > 0) == flag) {
cir.setReturnValue(true);
}
}
}

View File

@ -0,0 +1,20 @@
package io.izzel.arclight.common.mixin.v1_15.block;
import net.minecraft.block.BlockState;
import net.minecraft.block.MushroomBlock;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.server.ServerWorld;
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(MushroomBlock.class)
public class MushroomBlockMixin_1_15 {
@Redirect(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/server/ServerWorld;setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;I)Z"))
public boolean arclight$blockSpread(ServerWorld world, BlockPos toPos, BlockState newState, int flags, BlockState state, World worldIn, BlockPos fromPos) {
return CraftEventFactory.handleBlockSpreadEvent(world, fromPos, toPos, newState, flags);
}
}

View File

@ -0,0 +1,25 @@
package io.izzel.arclight.common.mixin.v1_15.block;
import io.izzel.arclight.common.bridge.entity.EntityTypeBridge;
import net.minecraft.block.NetherPortalBlock;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.SpawnReason;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.world.World;
import org.bukkit.event.entity.CreatureSpawnEvent;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(NetherPortalBlock.class)
public class NetherPortalBlockMixin_1_15 {
@Redirect(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/EntityType;spawn(Lnet/minecraft/world/World;Lnet/minecraft/nbt/CompoundNBT;Lnet/minecraft/util/text/ITextComponent;Lnet/minecraft/entity/player/PlayerEntity;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/entity/SpawnReason;ZZ)Lnet/minecraft/entity/Entity;"))
public Entity arclight$spawn(EntityType<?> entityType, World worldIn, CompoundNBT compound, ITextComponent customName, PlayerEntity playerIn, BlockPos pos, SpawnReason reason, boolean flag, boolean flag1) {
return ((EntityTypeBridge<?>) entityType).bridge$spawnCreature(worldIn, compound, customName, playerIn, pos, reason, flag, flag1, CreatureSpawnEvent.SpawnReason.NETHER_PORTAL);
}
}

View File

@ -0,0 +1,19 @@
package io.izzel.arclight.common.mixin.v1_15.block;
import net.minecraft.block.BlockState;
import net.minecraft.block.NetherWartBlock;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.server.ServerWorld;
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(NetherWartBlock.class)
public class NetherWartBlockMixin_1_15 {
@Redirect(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/server/ServerWorld;setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;I)Z"))
public boolean arclight$cropGrow(ServerWorld world, BlockPos pos, BlockState newState, int flags) {
return CraftEventFactory.handleBlockGrowEvent(world, pos, newState, flags);
}
}

View File

@ -0,0 +1,31 @@
package io.izzel.arclight.common.mixin.v1_15.block;
import net.minecraft.block.BlockState;
import net.minecraft.block.ObserverBlock;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.server.ServerWorld;
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.Random;
@Mixin(ObserverBlock.class)
public class ObserverBlockMixin_1_15 {
@Inject(method = "tick", cancellable = true, at = @At(value = "INVOKE", ordinal = 0, target = "Lnet/minecraft/world/server/ServerWorld;setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;I)Z"))
public void arclight$redstoneChange1(BlockState state, ServerWorld worldIn, BlockPos pos, Random random, CallbackInfo ci) {
if (CraftEventFactory.callRedstoneChange(worldIn, pos, 15, 0).getNewCurrent() != 0) {
ci.cancel();
}
}
@Inject(method = "tick", cancellable = true, at = @At(value = "INVOKE", ordinal = 1, target = "Lnet/minecraft/world/server/ServerWorld;setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;I)Z"))
public void arclight$redstoneChange2(BlockState state, ServerWorld worldIn, BlockPos pos, Random random, CallbackInfo ci) {
if (CraftEventFactory.callRedstoneChange(worldIn, pos, 0, 15).getNewCurrent() != 15) {
ci.cancel();
}
}
}

View File

@ -0,0 +1,76 @@
package io.izzel.arclight.common.mixin.v1_15.block;
import net.minecraft.block.Blocks;
import net.minecraft.block.PistonBlock;
import net.minecraft.block.PistonBlockStructureHelper;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import org.bukkit.Bukkit;
import org.bukkit.block.Block;
import org.bukkit.craftbukkit.v.block.CraftBlock;
import org.bukkit.event.block.BlockPistonEvent;
import org.bukkit.event.block.BlockPistonExtendEvent;
import org.bukkit.event.block.BlockPistonRetractEvent;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
import java.util.AbstractList;
import java.util.List;
@Mixin(PistonBlock.class)
public class PistonBlockMixin_1_15 {
@Inject(method = "doMove", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD,
at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/block/PistonBlockStructureHelper;getBlocksToDestroy()Ljava/util/List;"))
public void arclight$pistonAction(World worldIn, BlockPos pos, Direction directionIn, boolean extending, CallbackInfoReturnable<Boolean> cir,
BlockPos blockPos, PistonBlockStructureHelper helper) {
final Block craftBlock = CraftBlock.at(worldIn, pos);
final List<BlockPos> moved = helper.getBlocksToMove();
final List<BlockPos> broken = helper.getBlocksToDestroy();
class BlockList extends AbstractList<Block> {
@Override
public int size() {
return moved.size() + broken.size();
}
@Override
public org.bukkit.block.Block get(int index) {
if (index >= size() || index < 0) {
throw new ArrayIndexOutOfBoundsException(index);
}
BlockPos pos = index < moved.size() ? moved.get(index) : broken.get(index - moved.size());
return craftBlock.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ());
}
}
List<Block> blocks = new BlockList();
Direction direction = extending ? directionIn : directionIn.getOpposite();
BlockPistonEvent event;
if (extending) {
event = new BlockPistonExtendEvent(craftBlock, blocks, CraftBlock.notchToBlockFace(direction));
} else {
event = new BlockPistonRetractEvent(craftBlock, blocks, CraftBlock.notchToBlockFace(direction));
}
Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) {
for (BlockPos b : broken) {
worldIn.notifyBlockUpdate(b, Blocks.AIR.getDefaultState(), worldIn.getBlockState(b), 3);
}
for (BlockPos b : moved) {
worldIn.notifyBlockUpdate(b, Blocks.AIR.getDefaultState(), worldIn.getBlockState(b), 3);
b = b.offset(direction);
worldIn.notifyBlockUpdate(b, Blocks.AIR.getDefaultState(), worldIn.getBlockState(b), 3);
}
cir.setReturnValue(false);
}
}
}

View File

@ -0,0 +1,31 @@
package io.izzel.arclight.common.mixin.v1_15.block;
import net.minecraft.block.BlockState;
import net.minecraft.block.RedstoneDiodeBlock;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.server.ServerWorld;
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.Random;
@Mixin(RedstoneDiodeBlock.class)
public class RedstoneDiodeBlockMixin_1_15 {
@Inject(method = "tick", cancellable = true, at = @At(value = "INVOKE", ordinal = 0, target = "Lnet/minecraft/world/server/ServerWorld;setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;I)Z"))
public void arclight$turnOff(BlockState state, ServerWorld worldIn, BlockPos pos, Random random, CallbackInfo ci) {
if (CraftEventFactory.callRedstoneChange(worldIn, pos, 15, 0).getNewCurrent() != 0) {
ci.cancel();
}
}
@Inject(method = "tick", cancellable = true, at = @At(value = "INVOKE", ordinal = 1, target = "Lnet/minecraft/world/server/ServerWorld;setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;I)Z"))
public void arclight$turnOn(BlockState state, ServerWorld worldIn, BlockPos pos, Random random, CallbackInfo ci) {
if (CraftEventFactory.callRedstoneChange(worldIn, pos, 0, 15).getNewCurrent() != 15) {
ci.cancel();
}
}
}

View File

@ -0,0 +1,24 @@
package io.izzel.arclight.common.mixin.v1_15.block;
import net.minecraft.block.BlockState;
import net.minecraft.block.RedstoneLampBlock;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.server.ServerWorld;
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.Random;
@Mixin(RedstoneLampBlock.class)
public class RedstoneLampBlockMixin_1_15 {
@Inject(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/server/ServerWorld;setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;I)Z"))
private void arclight$redstoneChange(BlockState state, ServerWorld worldIn, BlockPos pos, Random rand, CallbackInfo ci) {
if (CraftEventFactory.callRedstoneChange(worldIn, pos, 15, 0).getNewCurrent() != 0) {
ci.cancel();
}
}
}

View File

@ -0,0 +1,85 @@
package io.izzel.arclight.common.mixin.v1_15.block;
import io.izzel.arclight.common.bridge.entity.EntityBridge;
import net.minecraft.block.BlockState;
import net.minecraft.block.RedstoneOreBlock;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.Hand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.world.World;
import net.minecraft.world.server.ServerWorld;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v.block.CraftBlock;
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
import org.bukkit.event.block.Action;
import org.bukkit.event.entity.EntityInteractEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.Random;
@Mixin(RedstoneOreBlock.class)
public abstract class RedstoneOreBlockMixin_1_15 {
// @formatter:off
@Shadow private static void activate(BlockState p_196500_0_, World p_196500_1_, BlockPos p_196500_2_) { }
// @formatter:on
private static transient Entity arclight$entity;
@Inject(method = "onBlockClicked", at = @At(value = "HEAD"))
public void arclight$interact1(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, CallbackInfo ci) {
arclight$entity = player;
}
@Inject(method = "onEntityWalk", at = @At(value = "HEAD"))
public void arclight$entityInteract(World worldIn, BlockPos pos, Entity entityIn, CallbackInfo ci) {
if (entityIn instanceof PlayerEntity) {
PlayerInteractEvent event = CraftEventFactory.callPlayerInteractEvent(((PlayerEntity) entityIn), Action.PHYSICAL, pos, null, null, null);
if (event.isCancelled()) {
ci.cancel();
return;
}
} else {
EntityInteractEvent event = new EntityInteractEvent(((EntityBridge) entityIn).bridge$getBukkitEntity(), CraftBlock.at(worldIn, pos));
Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) {
ci.cancel();
return;
}
}
arclight$entity = entityIn;
}
@Inject(method = "onBlockActivated", at = @At(value = "HEAD"))
public void arclight$interact3(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn, BlockRayTraceResult hit, CallbackInfoReturnable<Boolean> cir) {
arclight$entity = player;
}
@Inject(method = "tick", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/server/ServerWorld;setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;I)Z"))
private void arclight$blockFade(BlockState state, ServerWorld worldIn, BlockPos pos, Random random, CallbackInfo ci) {
if (CraftEventFactory.callBlockFadeEvent(worldIn, pos, state.with(RedstoneOreBlock.LIT, false)).isCancelled()) {
ci.cancel();
}
}
private static void interact(BlockState blockState, World world, BlockPos blockPos, Entity entity) {
arclight$entity = entity;
activate(blockState, world, blockPos);
}
@Inject(method = "activate", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;I)Z"))
private static void arclight$entityChangeBlock(BlockState blockState, World world, BlockPos blockPos, CallbackInfo ci) {
if (CraftEventFactory.callEntityChangeBlockEvent(arclight$entity, blockPos, blockState.with(RedstoneOreBlock.LIT, true)).isCancelled()) {
ci.cancel();
}
arclight$entity = null;
}
}

View File

@ -0,0 +1,32 @@
package io.izzel.arclight.common.mixin.v1_15.block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.ScaffoldingBlock;
import net.minecraft.state.IProperty;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.server.ServerWorld;
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import java.util.Random;
@Mixin(ScaffoldingBlock.class)
public class ScaffoldingBlockMixin_1_15 {
@Redirect(method = "tick", at = @At(value = "INVOKE", ordinal = 0, target = "Lnet/minecraft/block/BlockState;get(Lnet/minecraft/state/IProperty;)Ljava/lang/Comparable;"))
public Comparable<Integer> arclight$blockFade(BlockState state, IProperty<Integer> property, BlockState blockState, ServerWorld worldIn, BlockPos pos, Random random) {
Integer integer = state.get(property);
if (integer == 7) {
if (CraftEventFactory.callBlockFadeEvent(worldIn, pos, Blocks.AIR.getDefaultState()).isCancelled()) {
return 6;
} else {
return integer;
}
} else {
return integer;
}
}
}

View File

@ -0,0 +1,25 @@
package io.izzel.arclight.common.mixin.v1_15.block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.SnowBlock;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.server.ServerWorld;
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.Random;
@Mixin(SnowBlock.class)
public class SnowBlockMixin_1_15 {
@Inject(method = "tick", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/block/SnowBlock;spawnDrops(Lnet/minecraft/block/BlockState;Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;)V"))
public void arclight$blockFade(BlockState state, ServerWorld worldIn, BlockPos pos, Random random, CallbackInfo ci) {
if (CraftEventFactory.callBlockFadeEvent(worldIn, pos, Blocks.AIR.getDefaultState()).isCancelled()) {
ci.cancel();
}
}
}

View File

@ -0,0 +1,32 @@
package io.izzel.arclight.common.mixin.v1_15.block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.SpreadableSnowyDirtBlock;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.server.ServerWorld;
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.Random;
@Mixin(SpreadableSnowyDirtBlock.class)
public class SpreadableSnowyDirtBlockMixin_1_15 {
@Inject(method = "tick", cancellable = true, at = @At(value = "INVOKE", ordinal = 0, target = "Lnet/minecraft/world/server/ServerWorld;setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;)Z"))
public void arclight$blockFade(BlockState state, ServerWorld worldIn, BlockPos pos, Random random, CallbackInfo ci) {
if (CraftEventFactory.callBlockFadeEvent(worldIn, pos, Blocks.DIRT.getDefaultState()).isCancelled()) {
ci.cancel();
}
}
@Redirect(method = "tick", at = @At(value = "INVOKE", ordinal = 1, target = "Lnet/minecraft/world/server/ServerWorld;setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;)Z"))
public boolean arclight$blockSpread(ServerWorld world, BlockPos to, BlockState state, BlockState state1, World worldIn, BlockPos from) {
return CraftEventFactory.handleBlockSpreadEvent(world, from, to, state);
}
}

View File

@ -0,0 +1,43 @@
package io.izzel.arclight.common.mixin.v1_15.block;
import net.minecraft.block.BlockState;
import net.minecraft.block.StemBlock;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.server.ServerWorld;
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.Random;
@Mixin(StemBlock.class)
public class StemBlockMixin_1_15 {
private transient boolean arclight$success = false;
@Redirect(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/server/ServerWorld;setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;I)Z"))
public boolean arclight$cropGrow1(ServerWorld world, BlockPos pos, BlockState newState, int flags) {
return CraftEventFactory.handleBlockGrowEvent(world, pos, newState, flags);
}
@Inject(method = "tick", cancellable = true, at = @At(value = "INVOKE", ordinal = 1, target = "Lnet/minecraft/world/server/ServerWorld;setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;)Z"))
public void arclight$returnIfFail(BlockState state, ServerWorld worldIn, BlockPos pos, Random random, CallbackInfo ci) {
if (!arclight$success) {
ci.cancel();
}
arclight$success = false;
}
@Redirect(method = "tick", at = @At(value = "INVOKE", ordinal = 0, target = "Lnet/minecraft/world/server/ServerWorld;setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;)Z"))
public boolean arclight$cropGrow2(ServerWorld world, BlockPos pos, BlockState state) {
return arclight$success = CraftEventFactory.handleBlockGrowEvent(world, pos, state);
}
@Redirect(method = "grow", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/server/ServerWorld;setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;I)Z"))
public boolean arclight$cropGrow3(ServerWorld world, BlockPos pos, BlockState newState, int flags) {
return CraftEventFactory.handleBlockGrowEvent(world, pos, newState, flags);
}
}

Some files were not shown because too many files have changed in this diff Show More