From 5b0b9ba3c5ebdd017e7a9d4fe3f9a721a1be519f Mon Sep 17 00:00:00 2001 From: reign Date: Wed, 9 Apr 2025 21:35:01 -0400 Subject: [PATCH] Streamline codepaths and add SU compat for permission checking --- dependencies.gradle | 2 + .../item/ItemConstructableTrigger.java | 35 +-- .../structure/IStructureElement.java | 35 ++- .../structure/StructureUtility.java | 269 ++++++++++-------- .../xmod/ServerUtilitiesCompat.java | 24 ++ 5 files changed, 211 insertions(+), 154 deletions(-) create mode 100644 src/main/java/com/gtnewhorizon/structurelib/xmod/ServerUtilitiesCompat.java diff --git a/dependencies.gradle b/dependencies.gradle index 559dd6e8..085cf9e1 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -4,6 +4,8 @@ dependencies { api("com.github.GTNewHorizons:GTNHLib:0.6.13:dev") runtimeOnly("com.github.GTNewHorizons:NotEnoughItems:2.7.29-GTNH:dev") + compileOnly("com.github.GTNewHorizons:ServerUtilities:2.1.41-pre") + testImplementation(platform('org.junit:junit-bom:5.9.2')) testImplementation('org.junit.jupiter:junit-jupiter') diff --git a/src/main/java/com/gtnewhorizon/structurelib/item/ItemConstructableTrigger.java b/src/main/java/com/gtnewhorizon/structurelib/item/ItemConstructableTrigger.java index d2bebe78..a93ac7c5 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/item/ItemConstructableTrigger.java +++ b/src/main/java/com/gtnewhorizon/structurelib/item/ItemConstructableTrigger.java @@ -1,12 +1,10 @@ package com.gtnewhorizon.structurelib.item; -import static com.gtnewhorizon.structurelib.StructureLibAPI.MOD_ID; -import static net.minecraft.util.EnumChatFormatting.BLUE; -import static net.minecraft.util.StatCollector.translateToLocal; -import static net.minecraft.util.StatCollector.translateToLocalFormatted; - -import java.util.List; - +import com.gtnewhorizon.structurelib.StructureLib; +import com.gtnewhorizon.structurelib.alignment.constructable.ChannelDataAccessor; +import com.gtnewhorizon.structurelib.alignment.constructable.ConstructableUtility; +import com.gtnewhorizon.structurelib.gui.GuiScreenConfigureChannels; +import cpw.mods.fml.common.FMLCommonHandler; import net.minecraft.client.renderer.texture.IIconRegister; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.Item; @@ -16,15 +14,14 @@ import net.minecraft.nbt.NBTTagInt; import net.minecraft.util.IIcon; import net.minecraft.util.StatCollector; import net.minecraft.world.World; - import org.lwjgl.input.Keyboard; -import com.gtnewhorizon.structurelib.StructureLib; -import com.gtnewhorizon.structurelib.alignment.constructable.ChannelDataAccessor; -import com.gtnewhorizon.structurelib.alignment.constructable.ConstructableUtility; -import com.gtnewhorizon.structurelib.gui.GuiScreenConfigureChannels; +import java.util.List; -import cpw.mods.fml.common.FMLCommonHandler; +import static com.gtnewhorizon.structurelib.StructureLibAPI.MOD_ID; +import static net.minecraft.util.EnumChatFormatting.BLUE; +import static net.minecraft.util.StatCollector.translateToLocal; +import static net.minecraft.util.StatCollector.translateToLocalFormatted; public class ItemConstructableTrigger extends Item { @@ -32,6 +29,12 @@ public class ItemConstructableTrigger extends Item { private static final IIcon[] textures = new IIcon[3]; + public enum TriggerMode { + BUILDING, + UPDATING, + REMOVING + } + public ItemConstructableTrigger() { setUnlocalizedName("structurelib.constructableTrigger"); setCreativeTab(StructureLib.creativeTab); @@ -86,13 +89,13 @@ public class ItemConstructableTrigger extends Item { + StatCollector.translateToLocal("item.structurelib.constructableTrigger.modes." + mode); } - public static int getMode(ItemStack held) { + public static TriggerMode getMode(ItemStack held) { if (held == null || !held.hasTagCompound() || !held.getTagCompound().hasKey(TAG_MODE)) { // default behavior - return 0; + return TriggerMode.BUILDING; } // get user-defined mode - return held.getTagCompound().getInteger(TAG_MODE); + return TriggerMode.values()[held.getTagCompound().getInteger(TAG_MODE)]; } @Override diff --git a/src/main/java/com/gtnewhorizon/structurelib/structure/IStructureElement.java b/src/main/java/com/gtnewhorizon/structurelib/structure/IStructureElement.java index f7361eb1..f95fa27e 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/structure/IStructureElement.java +++ b/src/main/java/com/gtnewhorizon/structurelib/structure/IStructureElement.java @@ -1,16 +1,9 @@ package com.gtnewhorizon.structurelib.structure; -import static com.gtnewhorizon.structurelib.StructureLib.LOGGER; -import static com.gtnewhorizon.structurelib.StructureLib.PANIC_MODE; - -import java.util.Arrays; -import java.util.Collections; -import java.util.function.Consumer; -import java.util.function.Predicate; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - +import com.gtnewhorizon.structurelib.StructureLibAPI; +import com.gtnewhorizon.structurelib.item.ItemConstructableTrigger; +import com.gtnewhorizon.structurelib.util.ItemStackPredicate; +import com.gtnewhorizon.structurelib.util.ItemStackPredicate.NBTMode; import net.minecraft.block.Block; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; @@ -20,10 +13,16 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.IChatComponent; import net.minecraft.world.World; -import com.gtnewhorizon.structurelib.StructureLibAPI; -import com.gtnewhorizon.structurelib.item.ItemConstructableTrigger; -import com.gtnewhorizon.structurelib.util.ItemStackPredicate; -import com.gtnewhorizon.structurelib.util.ItemStackPredicate.NBTMode; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.Arrays; +import java.util.Collections; +import java.util.function.Consumer; +import java.util.function.Predicate; + +import static com.gtnewhorizon.structurelib.StructureLib.LOGGER; +import static com.gtnewhorizon.structurelib.StructureLib.PANIC_MODE; +import static com.gtnewhorizon.structurelib.item.ItemConstructableTrigger.TriggerMode.REMOVING; /** * Use StructureUtility to instantiate. These are the building blocks for your {@link IStructureDefinition}. It @@ -138,13 +137,13 @@ public interface IStructureElement { */ default PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { - int mode = ItemConstructableTrigger.getMode(trigger); + ItemConstructableTrigger.TriggerMode mode = ItemConstructableTrigger.getMode(trigger); BlocksToPlace e = getBlocksToPlace(t, world, x, y, z, trigger, env); IItemSource source = env.getSource(); EntityPlayer actor = env.getActor(); Consumer chatter = env.getChatter(); if (e != null) { - if (mode < 2 && check(t, world, x, y, z)) return PlaceResult.SKIP; + if (mode != REMOVING && check(t, world, x, y, z)) return PlaceResult.SKIP; if (e.getStacks() == null) { ItemStack taken = source.takeOne(e.getPredicate(), true); return StructureUtility.survivalPlaceBlock( @@ -161,7 +160,7 @@ public interface IStructureElement { chatter); } for (ItemStack stack : e.getStacks()) { - if (mode < 2 && !source.takeOne(stack, true)) continue; + if (mode != REMOVING && !source.takeOne(stack, true)) continue; return StructureUtility.survivalPlaceBlock( stack, NBTMode.EXACT, diff --git a/src/main/java/com/gtnewhorizon/structurelib/structure/StructureUtility.java b/src/main/java/com/gtnewhorizon/structurelib/structure/StructureUtility.java index 8b5c50a3..56faaf22 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/structure/StructureUtility.java +++ b/src/main/java/com/gtnewhorizon/structurelib/structure/StructureUtility.java @@ -1,9 +1,40 @@ package com.gtnewhorizon.structurelib.structure; -import static com.gtnewhorizon.structurelib.StructureLib.LOGGER; -import static com.gtnewhorizon.structurelib.StructureLib.PANIC_MODE; -import static java.lang.Integer.MIN_VALUE; +import com.google.common.collect.ImmutableList; +import com.gtnewhorizon.structurelib.StructureEvent.StructureElementVisitedEvent; +import com.gtnewhorizon.structurelib.StructureLib; +import com.gtnewhorizon.structurelib.StructureLibAPI; +import com.gtnewhorizon.structurelib.alignment.constructable.ChannelDataAccessor; +import com.gtnewhorizon.structurelib.alignment.enumerable.ExtendedFacing; +import com.gtnewhorizon.structurelib.item.ItemConstructableTrigger; +import com.gtnewhorizon.structurelib.structure.IStructureElement.PlaceResult; +import com.gtnewhorizon.structurelib.structure.adders.IBlockAdder; +import com.gtnewhorizon.structurelib.structure.adders.ITileAdder; +import com.gtnewhorizon.structurelib.util.ItemStackPredicate; +import com.gtnewhorizon.structurelib.util.ItemStackPredicate.NBTMode; +import com.gtnewhorizon.structurelib.util.Vec3Impl; +import com.gtnewhorizon.structurelib.xmod.ServerUtilitiesCompat; +import cpw.mods.fml.common.Loader; +import cpw.mods.fml.common.registry.GameRegistry; +import net.minecraft.block.Block; +import net.minecraft.entity.item.EntityItem; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.init.Blocks; +import net.minecraft.item.Item; +import net.minecraft.item.ItemBlock; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.ChatComponentTranslation; +import net.minecraft.util.IChatComponent; +import net.minecraft.util.IIcon; +import net.minecraft.world.World; +import net.minecraftforge.common.util.ForgeDirection; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.tuple.Pair; +import javax.annotation.Nullable; import java.util.Arrays; import java.util.Collection; import java.util.Collections; @@ -25,42 +56,12 @@ import java.util.function.Function; import java.util.function.Predicate; import java.util.function.Supplier; -import javax.annotation.Nullable; - -import net.minecraft.block.Block; -import net.minecraft.entity.item.EntityItem; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.init.Blocks; -import net.minecraft.item.Item; -import net.minecraft.item.ItemBlock; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.ChatComponentTranslation; -import net.minecraft.util.IChatComponent; -import net.minecraft.util.IIcon; -import net.minecraft.world.World; -import net.minecraftforge.common.util.ForgeDirection; - -import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.tuple.Pair; - -import com.google.common.collect.ImmutableList; -import com.gtnewhorizon.structurelib.StructureEvent.StructureElementVisitedEvent; -import com.gtnewhorizon.structurelib.StructureLib; -import com.gtnewhorizon.structurelib.StructureLibAPI; -import com.gtnewhorizon.structurelib.alignment.constructable.ChannelDataAccessor; -import com.gtnewhorizon.structurelib.alignment.enumerable.ExtendedFacing; -import com.gtnewhorizon.structurelib.item.ItemConstructableTrigger; -import com.gtnewhorizon.structurelib.structure.IStructureElement.PlaceResult; -import com.gtnewhorizon.structurelib.structure.adders.IBlockAdder; -import com.gtnewhorizon.structurelib.structure.adders.ITileAdder; -import com.gtnewhorizon.structurelib.util.ItemStackPredicate; -import com.gtnewhorizon.structurelib.util.ItemStackPredicate.NBTMode; -import com.gtnewhorizon.structurelib.util.Vec3Impl; - -import cpw.mods.fml.common.registry.GameRegistry; +import static com.gtnewhorizon.structurelib.StructureLib.LOGGER; +import static com.gtnewhorizon.structurelib.StructureLib.PANIC_MODE; +import static com.gtnewhorizon.structurelib.item.ItemConstructableTrigger.TriggerMode.BUILDING; +import static com.gtnewhorizon.structurelib.item.ItemConstructableTrigger.TriggerMode.REMOVING; +import static com.gtnewhorizon.structurelib.item.ItemConstructableTrigger.TriggerMode.UPDATING; +import static java.lang.Integer.MIN_VALUE; /** * A brief index of everything contained @@ -148,6 +149,8 @@ public class StructureUtility { private static final String NICE_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz=|!@#$%&()[]{};:<>/?_,.*^'`"; + private static final boolean isSULoaded = Loader.isModLoaded("serverutilities"); + @SuppressWarnings("rawtypes") private static final Map STEP = new HashMap<>(); @@ -225,8 +228,8 @@ public class StructureUtility { @Override public PlaceResult survivalPlaceBlock(Object o, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { - int mode = ItemConstructableTrigger.getMode(trigger); - if (mode < 2 && check(o, world, x, y, z)) return PlaceResult.SKIP; + ItemConstructableTrigger.TriggerMode mode = ItemConstructableTrigger.getMode(trigger); + if (mode != REMOVING && check(o, world, x, y, z)) return PlaceResult.SKIP; // user should place anything here. // maybe make this configurable, but for now we try to take some cobble from user if (env.getSource().takeOne(new ItemStack(Blocks.cobblestone), false)) { @@ -341,43 +344,45 @@ public class StructureUtility { public static PlaceResult survivalPlaceBlock(Block block, int meta, World world, int x, int y, int z, IItemSource s, EntityPlayer actor, Consumer chatter) { if (block == null) throw new NullPointerException(); - int mode = 0; + ItemConstructableTrigger.TriggerMode mode = BUILDING; if (actor.getHeldItem() != null && actor.getHeldItem().getItem() instanceof ItemConstructableTrigger) { // best effort lookup if the item in the player's hand is a trigger, and if it is, get the mode from the // ...trigger instead of assuming default behavior mode = ItemConstructableTrigger.getMode(actor.getHeldItem()); } - if (mode == 0 && !StructureLibAPI.isBlockTriviallyReplaceable(world, x, y, z, actor)) return PlaceResult.REJECT; - if (mode == 1 && world.getTileEntity(x, y, z) instanceof TileEntity) { - // We're in updating mode and the block we're looking at might be important, so let's just leave it alone - // since it's probably not something we want to replace with something else - return PlaceResult.SKIP; + if (mode == BUILDING && !StructureLibAPI.isBlockTriviallyReplaceable(world, x, y, z, actor)) return PlaceResult.REJECT; + if (mode == UPDATING) { + if (!world.isAirBlock(x, y, z)) { + if (world.getTileEntity(x, y, z) instanceof TileEntity) { + // We're in updating mode and the block we're looking at might be important, so let's just leave it alone + // since it's probably not something we want to replace with something else + return PlaceResult.SKIP; + } + Block blockInWorld = world.getBlock(x, y, z); + if (blockInWorld.isAssociatedBlock(block) && blockInWorld.getDamageValue(world, x, y, z) == meta) { + // This is the block we are looking for, move along + return PlaceResult.SKIP; + } + } } Item itemBlock = Item.getItemFromBlock(block); int itemMeta = itemBlock instanceof ISpecialItemBlock - ? ((ISpecialItemBlock) itemBlock).getItemMetaFromBlockMeta(block, meta) - : meta; + ? ((ISpecialItemBlock) itemBlock).getItemMetaFromBlockMeta(block, meta) + : meta; ItemStack stack = new ItemStack(itemBlock, 1, itemMeta); - if (mode == 1 && !world.isAirBlock(x, y, z)) { - Block blockInWorld = world.getBlock(x, y, z); - if (blockInWorld.isAssociatedBlock(block) && blockInWorld.getDamageValue(world, x, y, z) == meta) { - // This is the block we are looking for, move along - return PlaceResult.SKIP; - } - } - if (mode < 2 && !s.takeOne(stack, true)) { - if (chatter != null) chatter.accept( + if (mode != REMOVING) { + if (!s.takeOne(stack, true)) { + if (chatter != null) chatter.accept( new ChatComponentTranslation( - "structurelib.autoplace.error.no_simple_block", - stack.func_151000_E())); - return PlaceResult.REJECT; - } - if (mode < 2) { + "structurelib.autoplace.error.no_simple_block", + stack.func_151000_E())); + return PlaceResult.REJECT; + } if (block instanceof ICustomBlockSetting) { ICustomBlockSetting blockCustom = (ICustomBlockSetting) block; blockCustom.setBlock(world, x, y, z, meta); } else { - if (mode == 1 && !world.isAirBlock(x, y, z)) { + if (mode == UPDATING && !world.isAirBlock(x, y, z) && checkPermission(world, actor, x, y, z)) { // We're in updating mode and there's a block in our way (grr), so let's remove whatever is there // ...and drop it to the player ItemStack toGive = new ItemStack(world.getBlock(x, y, z)); @@ -393,21 +398,24 @@ public class StructureUtility { } } if (!stack.copy() - .tryPlaceItemIntoWorld(actor, world, x, y, z, ForgeDirection.UP.ordinal(), 0.5f, 0.5f, 0.5f)) { + .tryPlaceItemIntoWorld(actor, world, x, y, z, ForgeDirection.UP.ordinal(), 0.5f, 0.5f, 0.5f)) { return PlaceResult.REJECT; } } } - if (mode == 2 && world.isAirBlock(x, y, z)) { - return PlaceResult.SKIP; - } - if (mode == 2 || !s.takeOne(stack, false)) { - // If the user didn't have the item in their inventory, or we're in removing mode, we set it to air + if (mode == REMOVING || !s.takeOne(stack, true)) { + // If we're in removing mode, or if the user didn't have the block in their inventory, and we're in some other mode, let's check some stuff + if(world.isAirBlock(x, y, z)) { + return PlaceResult.SKIP; + } ItemStack toGive = new ItemStack(world.getBlock(x, y, z)); toGive.setItemDamage(world.getBlock(x, y, z).getDamageValue(world, x, y, z)); + if(mode == REMOVING && !checkPermission(world, actor, x, y, z)) { + return PlaceResult.REJECT; + } world.setBlockToAir(x, y, z); - if (mode == 2 && !tryGiveOrDropItem(world, actor, toGive)) { - // Something went wrong while trying to give the player the block we removed, let's just fail for now + if (mode == REMOVING && !tryGiveOrDropItem(world, actor, toGive)) { + // We're in removing mode and something went wrong while trying to give the player the block we removed, let's just fail for now return PlaceResult.REJECT; } } @@ -501,35 +509,38 @@ public class StructureUtility { if (stack == null) throw new NullPointerException(); if (stack.stackSize != 1) throw new IllegalArgumentException(); if (!(stack.getItem() instanceof ItemBlock)) throw new IllegalArgumentException(); - int mode = 0; + ItemConstructableTrigger.TriggerMode mode = BUILDING; if (actor.getHeldItem() != null && actor.getHeldItem().getItem() instanceof ItemConstructableTrigger) { // best effort lookup if the item in the player's hand is a trigger, and if it is, get the mode from the // ...trigger instead of assuming default behavior mode = ItemConstructableTrigger.getMode(actor.getHeldItem()); } - if (mode == 1 && !world.isAirBlock(x, y, z)) { - if (world.getTileEntity(x, y, z) instanceof TileEntity) { - // We're in updating mode and the block we're looking at might be important, so let's just leave it - // alone - // since it's probably not something we want to replace with something else - return PlaceResult.SKIP; + if (mode != REMOVING) { + if (mode == BUILDING) { + if(!StructureLibAPI.isBlockTriviallyReplaceable(world, x, y, z, actor)) { + return PlaceResult.SKIP; + } } - Block blockInWorld = world.getBlock(x, y, z); - ItemStack blockInWorldItem = new ItemStack(blockInWorld); - blockInWorldItem.setItemDamage(blockInWorld.getDamageValue(world, x, y, z)); - if (blockInWorldItem.isItemEqual(stack)) { - // This is the block we are looking for, move along - return PlaceResult.SKIP; + if (mode == UPDATING) { + if (!world.isAirBlock(x, y, z)) { + if (world.getTileEntity(x, y, z) instanceof TileEntity) { + return PlaceResult.SKIP; + } + Block blockInWorld = world.getBlock(x, y, z); + ItemStack blockInWorldItem = new ItemStack(blockInWorld); + blockInWorldItem.setItemDamage(blockInWorld.getDamageValue(world, x, y, z)); + if (blockInWorldItem.isItemEqual(stack)) { + // This is the block we are looking for, move along + return PlaceResult.SKIP; + } + } } - } - if (mode == 0 && !StructureLibAPI.isBlockTriviallyReplaceable(world, x, y, z, actor)) return PlaceResult.REJECT; - if (mode < 2 && !assumeStackPresent && !s.takeOne(stack, true)) { - if (chatter != null) chatter.accept( + if (!assumeStackPresent && !s.takeOne(stack, true)) { + if (chatter != null) chatter.accept( new ChatComponentTranslation("structurelib.autoplace.error.no_item_stack", stack.func_151000_E())); - return PlaceResult.REJECT; - } - if (mode < 2) { - if (mode == 1 && !world.isAirBlock(x, y, z)) { + return PlaceResult.REJECT; + } + if (mode == UPDATING && !world.isAirBlock(x, y, z) && checkPermission(world, actor, x, y, z)) { // We're in updating mode and there's a block in our way (grr), so let's remove whatever is there // ...and drop it to the player ItemStack toGive = new ItemStack(world.getBlock(x, y, z)); @@ -544,19 +555,22 @@ public class StructureUtility { } } if (!stack.copy() - .tryPlaceItemIntoWorld(actor, world, x, y, z, ForgeDirection.UP.ordinal(), 0.5f, 0.5f, 0.5f)) { + .tryPlaceItemIntoWorld(actor, world, x, y, z, ForgeDirection.UP.ordinal(), 0.5f, 0.5f, 0.5f)) { return PlaceResult.REJECT; } } - if (mode == 2 && world.isAirBlock(x, y, z)) { - return PlaceResult.SKIP; - } - if (mode == 2 || !s.takeOne(stack, false)) { + if (mode == REMOVING || !s.takeOne(stack, false)) { + if (world.isAirBlock(x, y, z)) { + return PlaceResult.SKIP; + } // If the user didn't have the item in their inventory, or we're in removing mode, we set it to air ItemStack toGive = new ItemStack(world.getBlock(x, y, z)); toGive.setItemDamage(world.getBlock(x, y, z).getDamageValue(world, x, y, z)); + if(mode == REMOVING && !checkPermission(world, actor, x, y, z)) { + return PlaceResult.REJECT; + } world.setBlockToAir(x, y, z); - if (mode == 2 && !tryGiveOrDropItem(world, actor, toGive)) { + if (mode == REMOVING && !tryGiveOrDropItem(world, actor, toGive)) { // We were in removing mode and something went wrong while trying to give the player the block we // ...removed, let's just fail for now return PlaceResult.REJECT; @@ -861,13 +875,13 @@ public class StructureUtility { @Override public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { - int mode = ItemConstructableTrigger.getMode(trigger); + ItemConstructableTrigger.TriggerMode mode = ItemConstructableTrigger.getMode(trigger); Pair hint = getHint(trigger); if (hint == null) return PlaceResult.REJECT; // TODO or SKIP? Block block = world.getBlock(x, y, z); int meta = world.getBlockMetadata(x, y, z); TIER tier = tierExtractor.convert(block, meta); - if (mode < 2 && Objects.equals(tier, tierExtractor.convert(hint.getKey(), hint.getValue()))) + if (mode != REMOVING && Objects.equals(tier, tierExtractor.convert(hint.getKey(), hint.getValue()))) return PlaceResult.SKIP; return StructureUtility.survivalPlaceBlock( hint.getKey(), @@ -957,8 +971,8 @@ public class StructureUtility { @Override public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { - int mode = ItemConstructableTrigger.getMode(trigger); - if (mode < 2 && check(t, world, x, y, z)) return PlaceResult.SKIP; + ItemConstructableTrigger.TriggerMode mode = ItemConstructableTrigger.getMode(trigger); + if (mode != REMOVING && check(t, world, x, y, z)) return PlaceResult.SKIP; if (getBlock() == null) return PlaceResult.REJECT; return StructureUtility.survivalPlaceBlock( getBlock(), @@ -1045,8 +1059,8 @@ public class StructureUtility { @Deprecated public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, IItemSource s, EntityPlayerMP actor, Consumer chatter) { - int mode = ItemConstructableTrigger.getMode(trigger); - if (mode < 2 && check(t, world, x, y, z)) return PlaceResult.SKIP; + ItemConstructableTrigger.TriggerMode mode = ItemConstructableTrigger.getMode(trigger); + if (mode != REMOVING && check(t, world, x, y, z)) return PlaceResult.SKIP; if (init()) return StructureUtility.survivalPlaceBlock(block, meta, world, x, y, z, s, actor, chatter); return fallback.survivalPlaceBlock(t, world, x, y, z, trigger, s, actor, chatter); } @@ -1054,8 +1068,8 @@ public class StructureUtility { @Override public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { - int mode = ItemConstructableTrigger.getMode(trigger); - if (mode < 2 && check(t, world, x, y, z)) return PlaceResult.SKIP; + ItemConstructableTrigger.TriggerMode mode = ItemConstructableTrigger.getMode(trigger); + if (mode != REMOVING && check(t, world, x, y, z)) return PlaceResult.SKIP; if (init()) return StructureUtility.survivalPlaceBlock( block, meta, @@ -1683,8 +1697,8 @@ public class StructureUtility { @Deprecated public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { - int mode = ItemConstructableTrigger.getMode(trigger); - if (mode < 2 && world.getBlock(x, y, z) == defaultBlock + ItemConstructableTrigger.TriggerMode mode = ItemConstructableTrigger.getMode(trigger); + if (mode != REMOVING && world.getBlock(x, y, z) == defaultBlock && world.getBlockMetadata(x, y, z) == defaultMeta) return PlaceResult.SKIP; return StructureUtility.survivalPlaceBlock( @@ -1731,8 +1745,8 @@ public class StructureUtility { @Deprecated public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { - int mode = ItemConstructableTrigger.getMode(trigger); - if (mode < 2 && world.getBlock(x, y, z) == defaultBlock + ItemConstructableTrigger.TriggerMode mode = ItemConstructableTrigger.getMode(trigger); + if (mode != REMOVING && world.getBlock(x, y, z) == defaultBlock && world.getBlockMetadata(x, y, z) == defaultMeta) return PlaceResult.SKIP; return StructureUtility.survivalPlaceBlock( @@ -1993,8 +2007,8 @@ public class StructureUtility { @Deprecated public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, IItemSource s, EntityPlayerMP actor, Consumer chatter) { - int mode = ItemConstructableTrigger.getMode(trigger); - if (mode == 2 || predicate.test(t)) + ItemConstructableTrigger.TriggerMode mode = ItemConstructableTrigger.getMode(trigger); + if (mode == REMOVING || predicate.test(t)) return downstream.survivalPlaceBlock(t, world, x, y, z, trigger, s, actor, chatter); return placeResultWhenDisabled; } @@ -2002,8 +2016,8 @@ public class StructureUtility { @Override public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { - int mode = ItemConstructableTrigger.getMode(trigger); - if (mode == 2 || predicate.test(t)) + ItemConstructableTrigger.TriggerMode mode = ItemConstructableTrigger.getMode(trigger); + if (mode == REMOVING || predicate.test(t)) return downstream.survivalPlaceBlock(t, world, x, y, z, trigger, env); return placeResultWhenDisabled; } @@ -3381,15 +3395,15 @@ public class StructureUtility { * @param onRemove Operation to be performed when the mode of the trigger is set to removing mode */ public static void placeRemoveOrUpdate(ItemStack trigger, Runnable onCreate, Runnable onUpdate, Runnable onRemove) { - int mode = ItemConstructableTrigger.getMode(trigger); + ItemConstructableTrigger.TriggerMode mode = ItemConstructableTrigger.getMode(trigger); switch (mode) { - case 0: + case BUILDING: onCreate.run(); break; - case 1: + case UPDATING: onUpdate.run(); break; - case 2: + case REMOVING: onRemove.run(); break; } @@ -3400,6 +3414,21 @@ public class StructureUtility { actor.inventoryContainer.detectAndSendChanges(); return true; } - return world.spawnEntityInWorld(new EntityItem(world, actor.posX, actor.posY, actor.posZ, stack)); + EntityItem toSpawn = new EntityItem(world, actor.posX, actor.posY, actor.posZ, stack); + // For some reason these things sometimes spawn with the velocity of an F1 car, so let's prevent that + toSpawn.motionX = 0; + toSpawn.motionY = 0; + toSpawn.motionZ = 0; + return world.spawnEntityInWorld(toSpawn); + } + + public static boolean checkPermission(World world, EntityPlayer actor, int x, int y, int z) { + boolean res = true; + if(isSULoaded) { + res = ServerUtilitiesCompat.checkPermission(world, actor, x, z); + } + res = res && !world.getBlock(x, y, z).isAssociatedBlock(Blocks.bedrock); + // maybe check mining level who knows :shrug: + return res; } } diff --git a/src/main/java/com/gtnewhorizon/structurelib/xmod/ServerUtilitiesCompat.java b/src/main/java/com/gtnewhorizon/structurelib/xmod/ServerUtilitiesCompat.java new file mode 100644 index 00000000..843c1764 --- /dev/null +++ b/src/main/java/com/gtnewhorizon/structurelib/xmod/ServerUtilitiesCompat.java @@ -0,0 +1,24 @@ +package com.gtnewhorizon.structurelib.xmod; + +import cpw.mods.fml.common.Optional; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.world.World; +import serverutils.data.ClaimedChunks; +import serverutils.lib.data.ForgePlayer; +import serverutils.lib.data.ForgeTeam; +import serverutils.lib.data.Universe; +import serverutils.lib.math.ChunkDimPos; + +public class ServerUtilitiesCompat { + + @Optional.Method(modid = "serverutilities") + public static boolean checkPermission(World world, EntityPlayer actor, int x, int z) { + final ForgeTeam owningTeam = ClaimedChunks.instance.getChunkTeam(new ChunkDimPos(x >> 4, z >> 4, world.provider.dimensionId)); + if (owningTeam == null) { + return true; + } + final ForgePlayer currentPlayer = new ForgePlayer(Universe.get(), actor.getUniqueID(), actor.getCommandSenderName()); + return owningTeam.isAlly(currentPlayer) || owningTeam.isMember(currentPlayer); + } + +}