Add configs, store blocks after being burned for queued restore later
This commit is contained in:
parent
0ab76914c4
commit
80e068c198
8 changed files with 403 additions and 68 deletions
|
@ -3,7 +3,7 @@
|
|||
org.gradle.jvmargs=-Xmx3G
|
||||
org.gradle.daemon=false
|
||||
|
||||
libzontreck=1.10.011624.1712
|
||||
libzontreck=1.10.012124.1709
|
||||
|
||||
## Environment Properties
|
||||
|
||||
|
@ -49,7 +49,7 @@ mod_name=Fire! Fire!
|
|||
# The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default.
|
||||
mod_license=GPLv3
|
||||
# The mod version. See https://semver.org/
|
||||
mod_version=1.0.012124.0305
|
||||
mod_version=1.0.012124.2105
|
||||
# The group ID for the mod. It is only important when publishing as an artifact to a Maven repository.
|
||||
# This should match the base package used for the mod sources.
|
||||
# See https://maven.apache.org/guides/mini/guide-naming-conventions.html
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
package dev.zontreck.fire;
|
||||
|
||||
import com.mojang.logging.LogUtils;
|
||||
import dev.zontreck.fire.config.server.FireServerConfig;
|
||||
import dev.zontreck.fire.data.BlockRestoreData;
|
||||
import dev.zontreck.fire.events.EventHandler;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.event.RegistryEvent;
|
||||
import net.minecraftforge.event.server.ServerStartedEvent;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.InterModComms;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
|
@ -26,41 +29,24 @@ public class FireMod
|
|||
|
||||
// Directly reference a slf4j logger
|
||||
public static final Logger LOGGER = LogUtils.getLogger();
|
||||
public static boolean ENABLED = false; // Turned to false when shutting down the server
|
||||
public static BlockRestoreData blockRestoreData;
|
||||
|
||||
public FireMod()
|
||||
{
|
||||
// Register the setup method for modloading
|
||||
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::setup);
|
||||
// Register the enqueueIMC method for modloading
|
||||
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::enqueueIMC);
|
||||
// Register the processIMC method for modloading
|
||||
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::processIMC);
|
||||
|
||||
FireServerConfig.load();
|
||||
|
||||
// Register ourselves for server and other game events we are interested in
|
||||
MinecraftForge.EVENT_BUS.register(this);
|
||||
MinecraftForge.EVENT_BUS.register(new EventHandler());
|
||||
|
||||
}
|
||||
|
||||
private void setup(final FMLCommonSetupEvent event)
|
||||
{
|
||||
// some preinit code
|
||||
LOGGER.info("HELLO FROM PREINIT");
|
||||
LOGGER.info("DIRT BLOCK >> {}", Blocks.DIRT.getRegistryName());
|
||||
}
|
||||
|
||||
private void enqueueIMC(final InterModEnqueueEvent event)
|
||||
{
|
||||
// Some example code to dispatch IMC to another mod
|
||||
//InterModComms.sendTo("fire", "helloworld", () -> { LOGGER.info("Hello world from the MDK"); return "Hello world";});
|
||||
}
|
||||
|
||||
private void processIMC(final InterModProcessEvent event)
|
||||
{
|
||||
// Some example code to receive and process InterModComms from other mods
|
||||
//LOGGER.info("Got IMC {}", event.getIMCStream().
|
||||
// map(m->m.messageSupplier().get()).
|
||||
// collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
// You can use SubscribeEvent and let the Event Bus discover methods to call
|
||||
|
@ -71,6 +57,15 @@ public class FireMod
|
|||
LOGGER.info("HELLO from server starting");
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onServerReady(ServerStartedEvent event)
|
||||
{
|
||||
ENABLED=true;
|
||||
blockRestoreData = BlockRestoreData.load(event.getServer());
|
||||
|
||||
MinecraftForge.EVENT_BUS.register(new EventHandler());
|
||||
}
|
||||
|
||||
// You can use EventBusSubscriber to automatically subscribe events on the contained class (this is subscribing to the MOD
|
||||
// Event bus for receiving Registry Events)
|
||||
@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD)
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
package dev.zontreck.fire.config.server;
|
||||
|
||||
import dev.zontreck.fire.config.server.sections.RestoreSection;
|
||||
import dev.zontreck.fire.data.FireDatastore;
|
||||
import dev.zontreck.libzontreck.util.SNbtIo;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
public class FireServerConfig
|
||||
{
|
||||
public static final Path FILE = FireDatastore.of("config.snbt", false);
|
||||
|
||||
public static RestoreSection restore;
|
||||
public static void load()
|
||||
{
|
||||
if(!FILE.toFile().exists())
|
||||
{
|
||||
initialize();
|
||||
}
|
||||
CompoundTag tag = SNbtIo.loadSnbt(FILE);
|
||||
|
||||
if(tag.contains(RestoreSection.TAG_NAME))
|
||||
{
|
||||
restore = RestoreSection.deserialize(tag.getCompound(RestoreSection.TAG_NAME));
|
||||
} else restore = new RestoreSection();
|
||||
}
|
||||
|
||||
private static void initialize()
|
||||
{
|
||||
restore = new RestoreSection();
|
||||
|
||||
save();
|
||||
}
|
||||
|
||||
public static void save()
|
||||
{
|
||||
CompoundTag tag = new CompoundTag();
|
||||
tag.put(RestoreSection.TAG_NAME, restore.serialize());
|
||||
|
||||
SNbtIo.writeSnbt(FILE, tag);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
package dev.zontreck.fire.config.server.sections;
|
||||
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
|
||||
public class RestoreSection
|
||||
{
|
||||
public static final String TAG_NAME = "restore";
|
||||
public static final String TAG_CONTAINERS = "containers";
|
||||
public static final String TAG_DELAY = "delay";
|
||||
|
||||
public boolean restoreContainers = false;
|
||||
public int delayForRestore = 120;
|
||||
|
||||
public static RestoreSection deserialize(CompoundTag tag)
|
||||
{
|
||||
RestoreSection sect = new RestoreSection();
|
||||
sect.restoreContainers = tag.getBoolean(TAG_CONTAINERS);
|
||||
sect.delayForRestore = tag.getInt(TAG_DELAY);
|
||||
|
||||
return sect;
|
||||
}
|
||||
|
||||
public CompoundTag serialize()
|
||||
{
|
||||
CompoundTag tag = new CompoundTag();
|
||||
tag.putBoolean(TAG_CONTAINERS, restoreContainers);
|
||||
tag.putInt(TAG_DELAY, delayForRestore);
|
||||
|
||||
return tag;
|
||||
}
|
||||
}
|
120
src/main/java/dev/zontreck/fire/data/BlockRestoreData.java
Normal file
120
src/main/java/dev/zontreck/fire/data/BlockRestoreData.java
Normal file
|
@ -0,0 +1,120 @@
|
|||
package dev.zontreck.fire.data;
|
||||
|
||||
import dev.zontreck.libzontreck.LibZontreck;
|
||||
import dev.zontreck.libzontreck.util.SNbtIo;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.ListTag;
|
||||
import net.minecraft.nbt.Tag;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
|
||||
public class BlockRestoreData
|
||||
{
|
||||
public static Path BASE;
|
||||
public Map<BlockPos, BlockSnapshot> snapshots = new HashMap<>();
|
||||
|
||||
private final ReadWriteLock lock = new ReentrantReadWriteLock();
|
||||
|
||||
|
||||
public static BlockRestoreData load(MinecraftServer server)
|
||||
{
|
||||
BASE = FireDatastore.of("restore_" + server.getWorldData().getLevelName() + ".snbt", false);
|
||||
if(!BASE.toFile().exists())
|
||||
{
|
||||
BlockRestoreData brd = new BlockRestoreData();
|
||||
brd.init();
|
||||
|
||||
return brd;
|
||||
}else {
|
||||
BlockRestoreData brd = new BlockRestoreData();
|
||||
brd.read();
|
||||
|
||||
return brd;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void init()
|
||||
{
|
||||
snapshots = new HashMap<>();
|
||||
}
|
||||
|
||||
private void read()
|
||||
{
|
||||
CompoundTag tag = new CompoundTag();
|
||||
CompoundTag blocks = tag.getCompound("queue");
|
||||
|
||||
int count = blocks.size();
|
||||
|
||||
for(int i=0;i<count;i++)
|
||||
{
|
||||
CompoundTag cTag = blocks.getCompound(String.valueOf(i));
|
||||
|
||||
BlockSnapshot snap = BlockSnapshot.deserialize(cTag);
|
||||
|
||||
add(snap);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void commit()
|
||||
{
|
||||
CompoundTag tag = new CompoundTag();
|
||||
CompoundTag lst = new CompoundTag();
|
||||
|
||||
|
||||
Lock lck = lock.readLock();
|
||||
lck.lock();
|
||||
try {
|
||||
|
||||
Iterator<Map.Entry<BlockPos, BlockSnapshot>> it = snapshots.entrySet().iterator();
|
||||
|
||||
int num=0;
|
||||
while(it.hasNext())
|
||||
{
|
||||
var entry = it.next();
|
||||
lst.put(String.valueOf(num), entry.getValue().serialize());
|
||||
num++;
|
||||
}
|
||||
} finally {
|
||||
lck.unlock();
|
||||
}
|
||||
|
||||
tag.putInt("version", 1);
|
||||
tag.put("queue", lst);
|
||||
SNbtIo.writeSnbt(BASE, tag);
|
||||
}
|
||||
|
||||
public void add(BlockSnapshot blockSnapshot) {
|
||||
if(snapshots.containsKey(blockSnapshot.position.Position.asBlockPos()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
Lock lck = lock.writeLock();
|
||||
lck.lock();
|
||||
try {
|
||||
snapshots.put(blockSnapshot.position.Position.asBlockPos(), blockSnapshot);
|
||||
}
|
||||
finally {
|
||||
lck.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public Lock acquireWriteLock()
|
||||
{
|
||||
return lock.writeLock();
|
||||
}
|
||||
|
||||
public Lock acquireReadLock()
|
||||
{
|
||||
return lock.readLock();
|
||||
}
|
||||
}
|
90
src/main/java/dev/zontreck/fire/data/BlockSnapshot.java
Normal file
90
src/main/java/dev/zontreck/fire/data/BlockSnapshot.java
Normal file
|
@ -0,0 +1,90 @@
|
|||
package dev.zontreck.fire.data;
|
||||
|
||||
|
||||
import dev.zontreck.libzontreck.exceptions.InvalidDeserialization;
|
||||
import dev.zontreck.libzontreck.vectors.Vector3;
|
||||
import dev.zontreck.libzontreck.vectors.WorldPosition;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.LongTag;
|
||||
import net.minecraft.nbt.NbtIo;
|
||||
import net.minecraft.nbt.NbtUtils;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.sounds.SoundEvents;
|
||||
import net.minecraft.sounds.SoundSource;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
public class BlockSnapshot {
|
||||
private final BlockState state;
|
||||
private CompoundTag blockEntity;
|
||||
protected final WorldPosition position;
|
||||
public final long burnTime;
|
||||
|
||||
public BlockSnapshot(Level world, BlockPos pos) {
|
||||
this.position = new WorldPosition(new Vector3(pos), (ServerLevel) world);
|
||||
this.state = world.getBlockState(pos);
|
||||
BlockEntity entity = world.getBlockEntity(pos);
|
||||
if(entity != null)
|
||||
this.blockEntity = world.getBlockEntity(pos).serializeNBT();
|
||||
this.burnTime = Instant.now().getEpochSecond();
|
||||
}
|
||||
|
||||
private BlockSnapshot(WorldPosition position, BlockState state, CompoundTag entity, long burn) {
|
||||
this.position = position;
|
||||
this.state = state;
|
||||
this.blockEntity = entity;
|
||||
this.burnTime = burn;
|
||||
}
|
||||
|
||||
public void restore() {
|
||||
Level world = position.getActualDimension();
|
||||
world.setBlockAndUpdate(position.Position.asBlockPos(), state);
|
||||
if (blockEntity != null) {
|
||||
BlockEntity entity = world.getBlockEntity(position.Position.asBlockPos());
|
||||
if(entity != null)
|
||||
{
|
||||
entity.load(blockEntity);
|
||||
}
|
||||
}
|
||||
|
||||
world.playSound(null, position.Position.asBlockPos(), SoundEvents.ITEM_PICKUP, SoundSource.NEUTRAL, world.random.nextFloat(0,1), world.random.nextFloat(0,1));
|
||||
}
|
||||
|
||||
public CompoundTag serialize()
|
||||
{
|
||||
CompoundTag tag = new CompoundTag();
|
||||
|
||||
tag.put("state", NbtUtils.writeBlockState(state));
|
||||
if(blockEntity!=null)
|
||||
tag.put("entity", blockEntity);
|
||||
tag.put("pos", position.serializePretty());
|
||||
tag.put("burnedAt", LongTag.valueOf(burnTime));
|
||||
|
||||
return tag;
|
||||
|
||||
}
|
||||
|
||||
public static BlockSnapshot deserialize(CompoundTag tag)
|
||||
{
|
||||
try {
|
||||
WorldPosition position = new WorldPosition(tag.getCompound("pos"), true);
|
||||
BlockState state = NbtUtils.readBlockState(tag.getCompound("state"));
|
||||
CompoundTag entity = null;
|
||||
if(tag.contains("entity"))
|
||||
entity = tag.getCompound("entity");
|
||||
long burn = tag.getLong("burnedAt");
|
||||
|
||||
|
||||
return new BlockSnapshot(position, state, entity, burn);
|
||||
|
||||
|
||||
} catch (InvalidDeserialization e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
30
src/main/java/dev/zontreck/fire/data/FireDatastore.java
Normal file
30
src/main/java/dev/zontreck/fire/data/FireDatastore.java
Normal file
|
@ -0,0 +1,30 @@
|
|||
package dev.zontreck.fire.data;
|
||||
|
||||
import dev.zontreck.libzontreck.util.FileTreeDatastore;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
public class FireDatastore extends FileTreeDatastore
|
||||
{
|
||||
public static final Path FBASE;
|
||||
static {
|
||||
FBASE = of("fire");
|
||||
if(!FBASE.toFile().exists())
|
||||
{
|
||||
FBASE.toFile().mkdirs();
|
||||
}
|
||||
}
|
||||
public static Path of(String nick, boolean directory)
|
||||
{
|
||||
Path nPath = FBASE.resolve(nick);
|
||||
if(directory)
|
||||
{
|
||||
if(!nPath.toFile().exists())
|
||||
{
|
||||
nPath.toFile().mkdir();
|
||||
}
|
||||
}
|
||||
|
||||
return nPath;
|
||||
}
|
||||
}
|
|
@ -1,20 +1,21 @@
|
|||
package dev.zontreck.fire.events;
|
||||
|
||||
import dev.zontreck.fire.FireMod;
|
||||
import dev.zontreck.fire.config.server.FireServerConfig;
|
||||
import dev.zontreck.fire.data.BlockSnapshot;
|
||||
import dev.zontreck.libzontreck.util.ServerUtilities;
|
||||
import dev.zontreck.libzontreck.vectors.Vector3;
|
||||
import dev.zontreck.libzontreck.vectors.WorldPosition;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.sounds.SoundEvents;
|
||||
import net.minecraft.sounds.SoundSource;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.ChestBlock;
|
||||
import net.minecraft.world.level.block.entity.BaseContainerBlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.event.TickEvent;
|
||||
import net.minecraftforge.event.server.ServerStoppingEvent;
|
||||
import net.minecraftforge.event.world.BlockEvent;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
|
||||
|
@ -22,17 +23,23 @@ import java.time.Instant;
|
|||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
|
||||
public class EventHandler {
|
||||
private static final Map<BlockPos, BlockSnapshot> burnedBlocks = new HashMap<>();
|
||||
|
||||
static {
|
||||
MinecraftForge.EVENT_BUS.register(EventHandler.class);
|
||||
}
|
||||
|
||||
private static final AtomicLong ALIVE_TICKS = new AtomicLong(0);
|
||||
|
||||
@SubscribeEvent
|
||||
public void onBlockBreak(BlockEvent.NeighborNotifyEvent event) {
|
||||
if (ServerUtilities.isClient()) return;
|
||||
if(!FireMod.ENABLED)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ServerLevel world = (ServerLevel) event.getWorld();
|
||||
BlockPos pos = event.getPos();
|
||||
|
@ -77,69 +84,88 @@ public class EventHandler {
|
|||
|
||||
blockState = world.getBlockState(pos);
|
||||
|
||||
if (blockState.is(Blocks.FIRE) || blockState.isAir()) {
|
||||
continue; // DO NOT CACHE FIRE OR AIR BLOCKS
|
||||
if (blockState.is(Blocks.FIRE) || blockState.isAir() || !blockState.isFlammable(world, pos, dir)) {
|
||||
continue; // DO NOT CACHE FIRE OR AIR BLOCKS, OR NON-FLAMMABLE BLOCKS
|
||||
}
|
||||
|
||||
// Do not cache containers and their inventories. This could be used as a duplication exploit in that case
|
||||
BlockEntity entity = world.getBlockEntity(pos);
|
||||
if(entity instanceof BaseContainerBlockEntity && FireServerConfig.restore.restoreContainers)
|
||||
{
|
||||
if(blockState.isFlammable(world, pos, dir))
|
||||
{
|
||||
// We're caching it, remove it from the world immediately to prevent a dupe. It will be restored afterwards
|
||||
|
||||
world.setBlock(pos, Blocks.AIR.defaultBlockState(), ChestBlock.UPDATE_ALL);
|
||||
}
|
||||
}
|
||||
|
||||
//FireMod.LOGGER.info("Fire detected");
|
||||
burnedBlocks.put(pos, new BlockSnapshot(world, pos));
|
||||
FireMod.blockRestoreData.add(new BlockSnapshot(world, pos));
|
||||
|
||||
}
|
||||
|
||||
FireMod.blockRestoreData.commit();
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onServerTick(TickEvent.WorldTickEvent event) {
|
||||
if(ServerUtilities.isClient()) return;
|
||||
if(!FireMod.ENABLED)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.phase == TickEvent.Phase.END) {
|
||||
restoreBurnedBlocks();
|
||||
if(ALIVE_TICKS.getAndIncrement() % 10 == 0)
|
||||
{
|
||||
|
||||
restoreBurnedBlocks();
|
||||
FireMod.blockRestoreData.commit();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onServerStopping(ServerStoppingEvent event)
|
||||
{
|
||||
if(ServerUtilities.isClient()) return;
|
||||
|
||||
FireMod.ENABLED=false;
|
||||
FireMod.blockRestoreData.commit();
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void restoreBurnedBlocks() {
|
||||
long currentTime = Instant.now().getEpochSecond();
|
||||
|
||||
// Restore one block per tick, after it hasnt burned for long enough
|
||||
Iterator<Map.Entry<BlockPos, BlockSnapshot>> it = burnedBlocks.entrySet().iterator();
|
||||
while(it.hasNext())
|
||||
{
|
||||
Lock lock = FireMod.blockRestoreData.acquireWriteLock();
|
||||
lock.lock();
|
||||
|
||||
var entry = it.next();
|
||||
|
||||
if((currentTime - entry.getValue().burnTime) >= 60 + (burnedBlocks.size()*2))
|
||||
try {
|
||||
// Restore one block per tick, after it hasnt burned for long enough
|
||||
Iterator<Map.Entry<BlockPos, BlockSnapshot>> it = FireMod.blockRestoreData.snapshots.entrySet().iterator();
|
||||
while(it.hasNext())
|
||||
{
|
||||
|
||||
it.remove();
|
||||
entry.getValue().restore();
|
||||
var entry = it.next();
|
||||
|
||||
//FireMod.LOGGER.info("Restoring burned block");
|
||||
if((currentTime - entry.getValue().burnTime) >= FireServerConfig.restore.delayForRestore + (FireMod.blockRestoreData.snapshots.size()))
|
||||
{
|
||||
it.remove();
|
||||
entry.getValue().restore();
|
||||
|
||||
return;
|
||||
//FireMod.LOGGER.info("Restoring burned block");
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}finally {
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class BlockSnapshot {
|
||||
private final BlockState state;
|
||||
private final BlockEntity blockEntity;
|
||||
private final WorldPosition position;
|
||||
public final long burnTime;
|
||||
|
||||
public BlockSnapshot(Level world, BlockPos pos) {
|
||||
this.position = new WorldPosition(new Vector3(pos), (ServerLevel) world);
|
||||
this.state = world.getBlockState(pos);
|
||||
this.blockEntity = world.getBlockEntity(pos);
|
||||
this.burnTime = Instant.now().getEpochSecond();
|
||||
}
|
||||
|
||||
public void restore() {
|
||||
Level world = position.getActualDimension();
|
||||
world.setBlockAndUpdate(position.Position.asBlockPos(), state);
|
||||
if (blockEntity != null) {
|
||||
world.setBlockEntity(blockEntity);
|
||||
}
|
||||
|
||||
world.playLocalSound(position.Position.x, position.Position.y, position.Position.z, SoundEvents.ITEM_PICKUP, SoundSource.NEUTRAL, world.random.nextFloat(0,1), world.random.nextFloat(0,1), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Reference in a new issue