mirror of
https://github.com/GTNewHorizons/StructureLib.git
synced 2026-11-12 16:27:36 +00:00
Add basic BlockChangeNotifier & BlockChangeListener
This commit is contained in:
1 parent
6867ed50e6
commit
61e0d4b7e7
5 files changed
+146
-6
No files matched your search
@@ -0,0 +1,11 @@
|
||||
package com.gtnewhorizon.structurelib.event;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.chunk.Chunk;
|
||||
|
||||
public interface BlockChangeListener {
|
||||
|
||||
void onBlockChange(World world, Chunk chunk, int x, int y, int z, Block oldBlock, Block newBlock, int oldMeta,
|
||||
int newMeta);
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.gtnewhorizon.structurelib.event;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.chunk.Chunk;
|
||||
|
||||
@SuppressWarnings("ForLoopReplaceableByForEach")
|
||||
public class BlockChangeNotifier {
|
||||
|
||||
private static final List<BlockChangeListener> listeners = new ArrayList<>();
|
||||
|
||||
public static synchronized void addListener(BlockChangeListener listener) {
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
public static void onBlockChange(World world, Chunk chunk, int x, int y, int z, Block oldBlock, Block newBlock,
|
||||
int oldMeta, int newMeta) {
|
||||
if (oldBlock == newBlock && oldMeta == newMeta) return;
|
||||
|
||||
if (chunk == null) {
|
||||
chunk = world.getChunkFromBlockCoords(x, z);
|
||||
}
|
||||
|
||||
final int numListeners = listeners.size();
|
||||
for (int i = 0; i < numListeners; i++) {
|
||||
final BlockChangeListener listener = listeners.get(i);
|
||||
listener.onBlockChange(world, chunk, x, y, z, oldBlock, newBlock, oldMeta, newMeta);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,12 +13,9 @@ import cpw.mods.fml.relauncher.FMLLaunchHandler;
|
||||
|
||||
public enum Mixins {
|
||||
|
||||
EMPTY(new Builder("Empty").setPhase(Phase.EARLY).addMixinClasses("com.gtnewhorizon.structurelib.mixins.EmptyMixin")
|
||||
.addTargetedMod(TargetedMod.VANILLA).setSide(Side.BOTH).setApplyIf(() -> false));
|
||||
// DISABLE_MODDED_CHUNK_POPULATION(new Builder("Disable all other mod chunk population (e.g. Natura clouds")
|
||||
// .setPhase(Phase.EARLY).addMixinClasses("minecraft.MixinChunkProviderServer_DisableModGeneration")
|
||||
// .addTargetedMod(TargetedMod.VANILLA).setSide(Side.BOTH)
|
||||
// .setApplyIf(() -> TweaksConfig.disableModdedChunkPopulation));
|
||||
BLOCK_CHANGE_NOTIFIER(new Builder("Block Change Notifier").setPhase(Phase.EARLY)
|
||||
.addMixinClasses("blockChangeNotifier.MixinForgeHooks", "blockChangeNotifier.MixinWorld")
|
||||
.addTargetedMod(TargetedMod.VANILLA).setSide(Side.BOTH).setApplyIf(() -> true));
|
||||
|
||||
private final List<String> mixinClasses;
|
||||
private final List<TargetedMod> targetedMods;
|
||||
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
package com.gtnewhorizon.structurelib.mixins.early.blockChangeNotifier;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.ForgeHooks;
|
||||
import net.minecraftforge.common.util.BlockSnapshot;
|
||||
|
||||
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 com.gtnewhorizon.structurelib.event.BlockChangeNotifier;
|
||||
import com.llamalad7.mixinextras.sugar.Local;
|
||||
|
||||
@Mixin(ForgeHooks.class)
|
||||
public class MixinForgeHooks {
|
||||
|
||||
@Inject(
|
||||
method = "onPlaceItemIntoWorld",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/world/World;markAndNotifyBlock(IIILnet/minecraft/world/chunk/Chunk;Lnet/minecraft/block/Block;Lnet/minecraft/block/Block;I)V",
|
||||
shift = At.Shift.AFTER),
|
||||
remap = false)
|
||||
private static void onBlockChange(ItemStack itemstack, EntityPlayer player, World world, int x, int y, int z,
|
||||
int side, float hitX, float hitY, float hitZ, CallbackInfoReturnable<Boolean> cir,
|
||||
@Local(name = "blocksnapshot") BlockSnapshot blocksnapshot, @Local(name = "newBlock") Block newBlock,
|
||||
@Local(name = "metadata") int newMetadata) {
|
||||
BlockChangeNotifier.onBlockChange(
|
||||
world,
|
||||
null,
|
||||
blocksnapshot.x,
|
||||
blocksnapshot.y,
|
||||
blocksnapshot.z,
|
||||
blocksnapshot.replacedBlock,
|
||||
newBlock,
|
||||
blocksnapshot.meta,
|
||||
newMetadata);
|
||||
}
|
||||
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
package com.gtnewhorizon.structurelib.mixins.early.blockChangeNotifier;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.chunk.Chunk;
|
||||
|
||||
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 com.gtnewhorizon.structurelib.event.BlockChangeNotifier;
|
||||
import com.llamalad7.mixinextras.sugar.Local;
|
||||
import com.llamalad7.mixinextras.sugar.Share;
|
||||
import com.llamalad7.mixinextras.sugar.ref.LocalIntRef;
|
||||
import com.llamalad7.mixinextras.sugar.ref.LocalRef;
|
||||
|
||||
@Mixin(World.class)
|
||||
public class MixinWorld {
|
||||
|
||||
@Inject(
|
||||
method = "Lnet/minecraft/world/World;setBlock(IIILnet/minecraft/block/Block;II)Z",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/world/World;markAndNotifyBlock(IIILnet/minecraft/world/chunk/Chunk;Lnet/minecraft/block/Block;Lnet/minecraft/block/Block;I)V",
|
||||
shift = At.Shift.AFTER,
|
||||
remap = false))
|
||||
public void setBlockObserve(int x, int y, int z, Block newBlock, int newMeta, int flags,
|
||||
CallbackInfoReturnable<Boolean> cir, @Local(name = "block1") Block originalBlock,
|
||||
@Share("originalMeta") LocalIntRef originalMeta, @Share("chunk") LocalRef<Chunk> chunkLocalRef) {
|
||||
BlockChangeNotifier.onBlockChange(
|
||||
(World) ((Object) (this)),
|
||||
chunkLocalRef.get(),
|
||||
x,
|
||||
y,
|
||||
z,
|
||||
originalBlock,
|
||||
newBlock,
|
||||
originalMeta.get(),
|
||||
newMeta);
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "Lnet/minecraft/world/World;setBlock(IIILnet/minecraft/block/Block;II)Z",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/world/chunk/Chunk;func_150807_a(IIILnet/minecraft/block/Block;I)Z",
|
||||
shift = At.Shift.BEFORE))
|
||||
public void captureChunkAndOriginalMetadata(int x, int y, int z, Block blockIn, int metadataIn, int flags,
|
||||
CallbackInfoReturnable<Boolean> cir, @Local(name = "chunk") Chunk chunk,
|
||||
@Share("originalMeta") LocalIntRef originalMeta, @Share("chunk") LocalRef<Chunk> chunkLocalRef) {
|
||||
chunkLocalRef.set(chunk);
|
||||
originalMeta.set(chunk.getBlockMetadata(x & 15, y, z & 15));
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user