mirror of
https://github.com/GTNewHorizons/StructureLib.git
synced 2026-11-13 00:37:55 +00:00
Roll a placement back to what was there rather than to air
This commit is contained in:
1 parent
6209d67ba7
commit
6bc8cea2bf
3 files changed
+36
-8
No files matched your search
@@ -2,6 +2,8 @@ package com.gtnewhorizon.structurelib;
|
||||
|
||||
import static com.gtnewhorizon.structurelib.StructureLib.proxy;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
@@ -328,6 +330,26 @@ public class StructureLibAPI {
|
||||
return block.isAir(w, x, y, z) || block.isReplaceable(w, x, y, z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Put back the block that was at a position, which is what a placement that could not be paid for should roll back
|
||||
* to.
|
||||
* <p>
|
||||
* Restoring the previous state instead of clearing the position matters whenever the position held something
|
||||
* autoplace is allowed to replace, e.g. a fluid that is not a source block: the player would otherwise be left with
|
||||
* a hole where their fluid used to be.
|
||||
*
|
||||
* @param world world to write to
|
||||
* @param x x coord
|
||||
* @param y y coord
|
||||
* @param z z coord
|
||||
* @param block the block that was there, or null for air
|
||||
* @param meta the meta that was there
|
||||
*/
|
||||
public static void restoreBlock(World world, int x, int y, int z, @Nullable Block block, int meta) {
|
||||
if (block == null || block.isAir(world, x, y, z)) world.setBlockToAir(x, y, z);
|
||||
else world.setBlock(x, y, z, block, meta, 3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send chat to player, but throttled.
|
||||
*
|
||||
|
||||
@@ -319,8 +319,7 @@ public class FluidAutoplace {
|
||||
}
|
||||
|
||||
private static void restore(World world, int x, int y, int z, Block block, int meta) {
|
||||
if (block == null || block.isAir(world, x, y, z)) world.setBlockToAir(x, y, z);
|
||||
else world.setBlock(x, y, z, block, meta, 3);
|
||||
StructureLibAPI.restoreBlock(world, x, y, z, block, meta);
|
||||
}
|
||||
|
||||
private static void reportMissingFluid(AutoPlaceEnvironment env, FluidBlockRequirement requirement, int missing) {
|
||||
|
||||
@@ -194,7 +194,7 @@ public class StructureUtility {
|
||||
|
||||
@Override
|
||||
public boolean placeBlock(Object o, World world, int x, int y, int z, ItemStack trigger) {
|
||||
world.setBlock(x, y, z, Blocks.air, 0, 2);
|
||||
world.setBlock(x, y, z, Blocks.air, 0, 3);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -204,7 +204,8 @@ public class StructureUtility {
|
||||
AutoPlaceEnvironment env) {
|
||||
if (check(o, world, x, y, z)) return PlaceResult.SKIP;
|
||||
if (!StructureLibAPI.isBlockTriviallyReplaceable(world, x, y, z, env.getActor())) return PlaceResult.REJECT;
|
||||
world.setBlock(x, y, z, Blocks.air, 0, 2);
|
||||
// Notify the neighbours, so that e.g. a fluid next to a position that had to be emptied flows back into it.
|
||||
world.setBlock(x, y, z, Blocks.air, 0, 3);
|
||||
return PlaceResult.ACCEPT;
|
||||
}
|
||||
};
|
||||
@@ -494,6 +495,8 @@ public class StructureUtility {
|
||||
new ChatComponentTranslation("structurelib.autoplace.missing_block", getStackChatName(stack)));
|
||||
return PlaceResult.REJECT;
|
||||
}
|
||||
Block previousBlock = world.getBlock(x, y, z);
|
||||
int previousMeta = world.getBlockMetadata(x, y, z);
|
||||
if (block instanceof ICustomBlockSetting blockCustom) {
|
||||
blockCustom.setBlock(world, x, y, z, meta);
|
||||
} else if (!stack.copy()
|
||||
@@ -501,8 +504,9 @@ public class StructureUtility {
|
||||
return PlaceResult.REJECT;
|
||||
}
|
||||
if (!s.takeOne(stack, false)) {
|
||||
// rollback
|
||||
world.setBlockToAir(x, y, z);
|
||||
// Roll back to what was there before, which is often a fluid that this block was placed over, so that a
|
||||
// position is never left empty by a placement that was not paid for.
|
||||
StructureLibAPI.restoreBlock(world, x, y, z, previousBlock, previousMeta);
|
||||
}
|
||||
return PlaceResult.ACCEPT;
|
||||
}
|
||||
@@ -600,11 +604,14 @@ public class StructureUtility {
|
||||
new ChatComponentTranslation("structurelib.autoplace.missing_block", getStackChatName(stack)));
|
||||
return PlaceResult.REJECT;
|
||||
}
|
||||
Block previousBlock = world.getBlock(x, y, z);
|
||||
int previousMeta = world.getBlockMetadata(x, y, z);
|
||||
if (!stack.copy().tryPlaceItemIntoWorld(actor, world, x, y, z, ForgeDirection.UP.ordinal(), 0.5f, 0.5f, 0.5f))
|
||||
return PlaceResult.REJECT;
|
||||
if (!s.takeOne(stack, false))
|
||||
// this is bad! probably an exploit somehow. Let's nullify the block we just placed instead
|
||||
world.setBlockToAir(x, y, z);
|
||||
// this is bad! probably an exploit somehow. Put back what was there instead of clearing the position, as
|
||||
// that would destroy the fluid this block was placed over.
|
||||
StructureLibAPI.restoreBlock(world, x, y, z, previousBlock, previousMeta);
|
||||
return PlaceResult.ACCEPT;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user