block updates completely prohibitable

Man kann jetzt weder blöcke platzieren noch abbauen, sofern der denkmalblock ein redstone signal erhält. Block hat noch kein Interface und kann nciht verschoben werden
This commit is contained in:
Malte Reents 2024-04-07 17:29:37 +02:00
parent 7319724efa
commit a50d5f6cc7
8 changed files with 199 additions and 6 deletions

View File

@ -18,6 +18,9 @@ import net.minecraft.world.World;
import net.minecraft.world.WorldAccess; import net.minecraft.world.WorldAccess;
import net.minecraft.world.explosion.Explosion; import net.minecraft.world.explosion.Explosion;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mutable;
import org.spongepowered.asm.mixin.Shadow;
import static modchest.block.modBlocks.denk_mal_block_placeholder; import static modchest.block.modBlocks.denk_mal_block_placeholder;
@ -138,4 +141,10 @@ public class denkMalBlock extends BlockWithEntity { //Item soll nicht crafta
} }
} }
} }
@Mutable
@Final protected BlockPos worldPosition;
public void setCMPos(BlockPos newPos) {
worldPosition = newPos;
}
} }

View File

@ -0,0 +1,18 @@
package modchest.event;
import modchest.util.denkMalBlockUtil;
import net.fabricmc.fabric.api.event.player.PlayerBlockBreakEvents;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import org.jetbrains.annotations.Nullable;
public class playerBreakBlockEvents implements PlayerBlockBreakEvents.Before {
@Override
public boolean beforeBlockBreak(World world, PlayerEntity player, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity) {
denkMalBlockUtil util = new denkMalBlockUtil();
return util.allowBlocks(world, player, pos);
}
}

View File

@ -0,0 +1,41 @@
package modchest.mixin;
import modchest.REServerMod;
import modchest.util.denkMalBlockUtil;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.FlintAndSteelItem;
import net.minecraft.item.ItemUsageContext;
import net.minecraft.util.ActionResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(FlintAndSteelItem.class)
public class flintAndSteelItemMixin {
@Inject(method = "useOnBlock", at = @At("HEAD"), cancellable = true)
public void useOnBlock(ItemUsageContext context, CallbackInfoReturnable<ActionResult> cir) {
if(!callPlaceable(context)) {
cir.setReturnValue(ActionResult.FAIL);
}
}
@Unique
private boolean callPlaceable(ItemUsageContext context) {
try {
PlayerEntity player = context.getPlayer();
World world = context.getWorld();
BlockPos pos = context.getBlockPos();
denkMalBlockUtil util = new denkMalBlockUtil();
return util.allowBlocks(world, player, pos);
} catch (Exception e) {
REServerMod.LOGGER.info("Exception in variables: " + e.toString());
}
return false;
}
}

View File

@ -0,0 +1,41 @@
package modchest.mixin;
import modchest.REServerMod;
import modchest.util.denkMalBlockUtil;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemUsageContext;
import net.minecraft.util.ActionResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(Item.class)
public class itemMixin {
@Inject(method = "useOnBlock", at = @At("HEAD"), cancellable = true)
public void useOnBlock(ItemUsageContext context, CallbackInfoReturnable<ActionResult> cir) {
if(!callPlaceable(context)) {
cir.setReturnValue(ActionResult.FAIL);
}
}
@Unique
private boolean callPlaceable(ItemUsageContext context) {
try {
PlayerEntity player = context.getPlayer();
World world = context.getWorld();
BlockPos pos = context.getBlockPos();
denkMalBlockUtil util = new denkMalBlockUtil();
return util.allowBlocks(world, player, pos);
} catch (Exception e) {
REServerMod.LOGGER.info("Exception in variables: " + e.toString());
}
return false;
}
}

View File

@ -0,0 +1,34 @@
package modchest.mixin;
import modchest.util.denkMalBlockUtil;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.BlockItem;
import net.minecraft.item.ItemPlacementContext;
import net.minecraft.util.ActionResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(BlockItem.class)
public class playerPlaceBlockMixin {
@Inject(method = "place(Lnet/minecraft/item/ItemPlacementContext;)Lnet/minecraft/util/ActionResult;", at = @At("HEAD"), cancellable = true)
public void canPlace(ItemPlacementContext context, CallbackInfoReturnable<ActionResult> cir) {
if(!callPlaceable(context)) {
cir.setReturnValue(ActionResult.FAIL);
}
}
@Unique
private boolean callPlaceable(ItemPlacementContext context) {
PlayerEntity player = context.getPlayer();
World world = context.getWorld();
BlockPos pos = context.getBlockPos();
denkMalBlockUtil util = new denkMalBlockUtil();
return util.allowBlocks(world, player, pos);
}
}

View File

@ -1,31 +1,39 @@
package modchest.util; package modchest.util;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtCompound;
import net.minecraft.text.Text;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import java.util.Arrays; import java.util.Arrays;
import java.util.Set;
import static java.lang.Math.abs;
public class denkMalBlockUtil extends dataSaverIO{ public class denkMalBlockUtil extends dataSaverIO{
public denkMalBlockUtil() {} public denkMalBlockUtil() {}
public void addBlock(int[] pos, int[] range) { //fuegt bloecke der Liste an abbauverhindernden Bloecke hinzu public void addBlock(int[] pos, int[] range) { //fuegt bloecke der Liste an abbauverhindernden Bloecke hinzu
NbtCompound tempNbt = new NbtCompound(); //Nbt in dem die Lockdaten gespeichert werden NbtCompound tempNbt = new NbtCompound(); //Nbt in dem die Blockdaten gespeichert werden
NbtCompound nbt = returnLoadedNbt(); //holt sich den denkmalblock nbt
tempNbt.putIntArray("position", pos); tempNbt.putIntArray("position", pos);
tempNbt.putIntArray("range", range); tempNbt.putIntArray("range", range);
NbtCompound nbt = returnloadedNbt(); //holt sich den denkmalblock nbt
nbt.put(Arrays.toString(pos), tempNbt); //speichert die daten des neuen Blocks ab nbt.put(Arrays.toString(pos), tempNbt); //speichert die daten des neuen Blocks ab
saveInNbt(nbt); //speichert den editierten denkmalblock-nbt ab saveInNbt(nbt); //speichert den editierten denkmalblock-nbt ab
} }
public void removeBlock(int[] posString) { //loescht bloecke aus Liste an abbauverhindernden Bloecken public void removeBlock(int[] posString) { //loescht bloecke aus Liste an abbauverhindernden Bloecken
NbtCompound nbt = returnloadedNbt(); //holt sich den denkmalblock nbt NbtCompound nbt = returnLoadedNbt(); //holt sich den denkmalblock nbt
nbt.remove(Arrays.toString(posString)); //entfernt diesen block nbt.remove(Arrays.toString(posString)); //entfernt diesen block
saveInNbt(nbt); //speichert den editierten denkmalblock-nbt ab saveInNbt(nbt); //speichert den editierten denkmalblock-nbt ab
} }
private NbtCompound returnloadedNbt() { //gibt den denkmalblock nbt zurueck private NbtCompound returnLoadedNbt() { //gibt den denkmalblock nbt zurueck
NbtCompound nbt = getFromNbt(); //laedt den gesamten reServerNbt NbtCompound nbt = getFromNbt(); //laedt den gesamten reServerNbt
nbt = (NbtCompound) nbt.get("denkmalblock"); //nimmt den denkmalblocknbt und laedt diesen nbt = (NbtCompound) nbt.get("denkmalblock");//nimmt den denkmalblocknbt und laedt diesen
if (nbt == null) { //sollte der nbt noch nicht existieren wird er erstellt if (nbt == null) { //sollte der nbt noch nicht existieren wird er erstellt
nbt = new NbtCompound(); nbt = new NbtCompound();
} }
@ -37,4 +45,40 @@ public class denkMalBlockUtil extends dataSaverIO{
reServerNbt.put("denkmalblock", nbt); //schreibt den denkmalblock nbt ab reServerNbt.put("denkmalblock", nbt); //schreibt den denkmalblock nbt ab
writeToNbt(reServerNbt); //schreibt den editierten reServerNbt writeToNbt(reServerNbt); //schreibt den editierten reServerNbt
} }
public boolean allowBlocks(World world, PlayerEntity player, BlockPos pos) {
if (world.getRegistryKey() == World.OVERWORLD) {
if (!player.isCreative()) {
NbtCompound nbt = returnLoadedNbt();
Set<String> set = nbt.getKeys();
String[] keys = set.toArray(new String[0]);//erzeugt einen String-Array mit allen keys
for (String key : keys) {
if (inRange((NbtCompound) nbt.get(key), pos)) {
if (!world.isClient) {
player.sendMessage(Text.of("Can't change Blocks here! This area is protected!"));
}
return false;
}
}
}
}
return true;
}
private boolean inRange(NbtCompound nbt, BlockPos pos) {
int[] denkPos = nbt.getIntArray("position");
int[] denkRange = nbt.getIntArray("range");
int[] blockPos = new int[3];
blockPos[0] = pos.getX();
blockPos[1] = pos.getY();
blockPos[2] = pos.getZ();
for(int i = 0; i < 3; i++) {
int dif = (denkPos[i] - blockPos[i]);
if (abs(dif) > denkRange[i]) {
return false;
}
}
return true;
}
} }

View File

@ -3,10 +3,12 @@ package modchest.util;
import modchest.block.entity.modBlockEntities; import modchest.block.entity.modBlockEntities;
import modchest.block.modBlocks; import modchest.block.modBlocks;
import modchest.event.playerAfterRespawnEvent; import modchest.event.playerAfterRespawnEvent;
import modchest.event.playerBreakBlockEvents;
import modchest.item.modItemGroup; import modchest.item.modItemGroup;
import modchest.item.modItems; import modchest.item.modItems;
import modchest.networking.modNetworkingServer; import modchest.networking.modNetworkingServer;
import net.fabricmc.fabric.api.entity.event.v1.ServerPlayerEvents; import net.fabricmc.fabric.api.entity.event.v1.ServerPlayerEvents;
import net.fabricmc.fabric.api.event.player.PlayerBlockBreakEvents;
public class initializer { public class initializer {
public static void itemGroups() { public static void itemGroups() {
@ -22,6 +24,7 @@ public class initializer {
public static void events() { //Events, bei denen custom Code ausgefuehrt wird, werden eingefuehrt public static void events() { //Events, bei denen custom Code ausgefuehrt wird, werden eingefuehrt
ServerPlayerEvents.AFTER_RESPAWN.register(new playerAfterRespawnEvent()); ServerPlayerEvents.AFTER_RESPAWN.register(new playerAfterRespawnEvent());
PlayerBlockBreakEvents.BEFORE.register(new playerBreakBlockEvents());
} }
public static void networking() { //Identifier unter denen der Server zuhoert werden registriert public static void networking() { //Identifier unter denen der Server zuhoert werden registriert

View File

@ -4,8 +4,11 @@
"compatibilityLevel": "JAVA_17", "compatibilityLevel": "JAVA_17",
"mixins": [ "mixins": [
"bedBlockMixin", "bedBlockMixin",
"flintAndSteelItemMixin",
"itemMixin",
"LevelStorageMixin", "LevelStorageMixin",
"MinecraftServerMixin", "MinecraftServerMixin",
"playerPlaceBlockMixin",
"ServerPlayerEntityMixin" "ServerPlayerEntityMixin"
], ],
"injectors": { "injectors": {