Compare commits
5 Commits
ee448ae34d
...
151fd022c4
Author | SHA1 | Date | |
---|---|---|---|
151fd022c4 | |||
deb338f2c8 | |||
61d2a0b137 | |||
35148c2159 | |||
ef29652e07 |
14
README.md
14
README.md
@ -29,6 +29,7 @@ As a challenge I'm trying to make it as user-friendly as possible.
|
|||||||
- Open/close EC block while opening/closing SEC
|
- Open/close EC block while opening/closing SEC
|
||||||
- Play open & close sounds
|
- Play open & close sounds
|
||||||
- Vein miner
|
- Vein miner
|
||||||
|
Code inspired by Inferis!
|
||||||

|

|
||||||
- Chat Calculator
|
- Chat Calculator
|
||||||
|
|
||||||
@ -51,6 +52,15 @@ As a challenge I'm trying to make it as user-friendly as possible.
|
|||||||
|
|
||||||
# Currently working on
|
# Currently working on
|
||||||
|
|
||||||
|
## Server Side
|
||||||
|
- [x] Chat Calculator
|
||||||
|
- [x] Check if operator is present before calculating
|
||||||
|
- Vein Miner
|
||||||
|
- [x] Configurable animation (tick delay)
|
||||||
|
- [x] Leaves veinmineable using shears
|
||||||
|
- [x] Replenish
|
||||||
|
|
||||||
|
|
||||||
## Client Side
|
## Client Side
|
||||||
|
|
||||||
- [x] Render block entities from a longer range
|
- [x] Render block entities from a longer range
|
||||||
@ -63,8 +73,6 @@ As a challenge I'm trying to make it as user-friendly as possible.
|
|||||||
- Boolean
|
- Boolean
|
||||||
- Float
|
- Float
|
||||||
- Integer
|
- Integer
|
||||||
- [x] Chat Calculator
|
|
||||||
- [x] Check if operator is present before calculating
|
|
||||||
- [x] Zoom
|
- [x] Zoom
|
||||||
- [ ] Configurable
|
- [ ] Configurable
|
||||||
|
|
||||||
@ -72,7 +80,7 @@ As a challenge I'm trying to make it as user-friendly as possible.
|
|||||||
|
|
||||||
## General
|
## General
|
||||||
- Rework config system
|
- Rework config system
|
||||||
- Store server settings in world folder for better singleplayer use
|
- Store server settings in world folder for better singleplayer use
|
||||||
|
|
||||||
## Client side
|
## Client side
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@ import wtf.hak.survivalfabric.commands.SlimeChunkCommand;
|
|||||||
import wtf.hak.survivalfabric.commands.SpectatorCommand;
|
import wtf.hak.survivalfabric.commands.SpectatorCommand;
|
||||||
import wtf.hak.survivalfabric.features.sharedenderchest.SharedEnderChest;
|
import wtf.hak.survivalfabric.features.sharedenderchest.SharedEnderChest;
|
||||||
import wtf.hak.survivalfabric.features.veinminer.VeinMinerEvents;
|
import wtf.hak.survivalfabric.features.veinminer.VeinMinerEvents;
|
||||||
|
import wtf.hak.survivalfabric.utils.Scheduler;
|
||||||
|
|
||||||
import static wtf.hak.survivalfabric.config.ConfigManager.getConfig;
|
import static wtf.hak.survivalfabric.config.ConfigManager.getConfig;
|
||||||
|
|
||||||
@ -23,6 +24,7 @@ public class SurvivalFabric implements ModInitializer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onInitialize() {
|
public void onInitialize() {
|
||||||
|
Scheduler.initialize();
|
||||||
CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> SpectatorCommand.register(dispatcher, "spectator", "s", "S", "camera", "c", "C"));
|
CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> SpectatorCommand.register(dispatcher, "spectator", "s", "S", "camera", "c", "C"));
|
||||||
CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> ReloadConfigCommand.register(dispatcher, "reloadsurvivalconfig"));
|
CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> ReloadConfigCommand.register(dispatcher, "reloadsurvivalconfig"));
|
||||||
CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> SlimeChunkCommand.register(dispatcher, "slimechunk", "sc"));
|
CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> SlimeChunkCommand.register(dispatcher, "slimechunk", "sc"));
|
||||||
|
@ -8,7 +8,7 @@ import java.util.List;
|
|||||||
|
|
||||||
public class Config {
|
public class Config {
|
||||||
|
|
||||||
public String configVersion = "1.0";
|
public String configVersion = "1.1";
|
||||||
|
|
||||||
public boolean joinMessageEnabled = true;
|
public boolean joinMessageEnabled = true;
|
||||||
public String joinMessage = "§8[§a+§8] §7%s";
|
public String joinMessage = "§8[§a+§8] §7%s";
|
||||||
@ -37,9 +37,12 @@ public class Config {
|
|||||||
|
|
||||||
public boolean veinMinerEnabled = true;
|
public boolean veinMinerEnabled = true;
|
||||||
public int maxVeinSize = 99999;
|
public int maxVeinSize = 99999;
|
||||||
|
public long veinAnimationTicks = 0;
|
||||||
|
|
||||||
public boolean chatCalcEnabled = true;
|
public boolean chatCalcEnabled = true;
|
||||||
|
|
||||||
|
public boolean replenishEnabled = false;
|
||||||
|
|
||||||
public ScreenHandlerType<GenericContainerScreenHandler> screenHandlerType() {
|
public ScreenHandlerType<GenericContainerScreenHandler> screenHandlerType() {
|
||||||
return switch (sharedEnderChestRows) {
|
return switch (sharedEnderChestRows) {
|
||||||
case 1 -> ScreenHandlerType.GENERIC_9X1;
|
case 1 -> ScreenHandlerType.GENERIC_9X1;
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package wtf.hak.survivalfabric.features.veinminer.drills;
|
package wtf.hak.survivalfabric.features.veinminer.drills;
|
||||||
|
|
||||||
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.registry.tag.TagKey;
|
||||||
import net.minecraft.server.network.ServerPlayerEntity;
|
import net.minecraft.server.network.ServerPlayerEntity;
|
||||||
import net.minecraft.text.MutableText;
|
import net.minecraft.text.MutableText;
|
||||||
import net.minecraft.text.PlainTextContent;
|
import net.minecraft.text.PlainTextContent;
|
||||||
@ -8,27 +10,66 @@ import net.minecraft.text.Text;
|
|||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import wtf.hak.survivalfabric.features.veinminer.Drill;
|
import wtf.hak.survivalfabric.features.veinminer.Drill;
|
||||||
import wtf.hak.survivalfabric.features.veinminer.VeinMinerSession;
|
import wtf.hak.survivalfabric.features.veinminer.VeinMinerSession;
|
||||||
|
import wtf.hak.survivalfabric.utils.Scheduler;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import static wtf.hak.survivalfabric.SurvivalFabric.LOGGER;
|
import static wtf.hak.survivalfabric.SurvivalFabric.LOGGER;
|
||||||
|
import static wtf.hak.survivalfabric.config.ConfigManager.getConfig;
|
||||||
|
|
||||||
public class DrillBase implements Drill {
|
public class DrillBase implements Drill {
|
||||||
|
|
||||||
protected VeinMinerSession session;
|
protected VeinMinerSession session;
|
||||||
|
|
||||||
public DrillBase(VeinMinerSession session) {
|
protected TagKey<Block> tag;
|
||||||
|
|
||||||
|
public DrillBase(VeinMinerSession session, TagKey<Block> tag) {
|
||||||
this.session = session;
|
this.session = session;
|
||||||
|
this.tag = tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canHandle(BlockState blockId) {
|
public boolean canHandle(BlockState blockState) {
|
||||||
return false;
|
return blockState.isIn(tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean drill(BlockPos blockPos) {
|
public boolean drill(BlockPos startPos) {
|
||||||
return false;
|
handleBlock(session.world.getBlockState(startPos).getBlock(), new ArrayList<>(), startPos, 0);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleBlock(Block initialBlock, List<BlockPos> history, BlockPos pos, int brokenBlocks) {
|
||||||
|
if (brokenBlocks < getConfig().maxVeinSize) {
|
||||||
|
history.add(pos);
|
||||||
|
if (tryBreakBlock(pos)) {
|
||||||
|
brokenBlocks++;
|
||||||
|
int finalBrokenBlocks = brokenBlocks;
|
||||||
|
|
||||||
|
// Put everything in a list to avoid scheduling a lot of tasks.
|
||||||
|
// Has the added benefit of only playing one sound
|
||||||
|
|
||||||
|
List<BlockPos> toBreak = new ArrayList<>();
|
||||||
|
forXYZ(pos, 1, newPos -> {
|
||||||
|
if (!history.contains(newPos) && session.world.getBlockState(newPos).getBlock() == initialBlock) {
|
||||||
|
toBreak.add(newPos);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
long delay = getConfig().veinAnimationTicks;
|
||||||
|
if (delay <= 0)
|
||||||
|
for (BlockPos newPos : toBreak)
|
||||||
|
handleBlock(initialBlock, history, newPos, finalBrokenBlocks);
|
||||||
|
else {
|
||||||
|
Scheduler.get().scheduleTask(() -> {
|
||||||
|
for (BlockPos newPos : toBreak)
|
||||||
|
handleBlock(initialBlock, history, newPos, finalBrokenBlocks);
|
||||||
|
}, delay);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1,62 +1,22 @@
|
|||||||
package wtf.hak.survivalfabric.features.veinminer.drills;
|
package wtf.hak.survivalfabric.features.veinminer.drills;
|
||||||
|
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.item.Items;
|
||||||
import net.minecraft.block.BlockState;
|
|
||||||
import net.minecraft.registry.RegistryKeys;
|
import net.minecraft.registry.RegistryKeys;
|
||||||
import net.minecraft.registry.tag.TagKey;
|
import net.minecraft.registry.tag.TagKey;
|
||||||
import net.minecraft.server.world.ServerWorld;
|
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import wtf.hak.survivalfabric.features.veinminer.VeinMinerSession;
|
import wtf.hak.survivalfabric.features.veinminer.VeinMinerSession;
|
||||||
|
|
||||||
import java.util.ArrayDeque;
|
|
||||||
|
|
||||||
import static wtf.hak.survivalfabric.config.ConfigManager.getConfig;
|
|
||||||
|
|
||||||
public class LeavesDrill extends DrillBase {
|
public class LeavesDrill extends DrillBase {
|
||||||
|
|
||||||
public static final TagKey<Block> leavesTag = TagKey.of(RegistryKeys.BLOCK, Identifier.of("survivalfabric", "leaves"));
|
|
||||||
|
|
||||||
public LeavesDrill(VeinMinerSession session) {
|
public LeavesDrill(VeinMinerSession session) {
|
||||||
super(session);
|
super(session, TagKey.of(RegistryKeys.BLOCK, Identifier.of("survivalfabric", "leaves")));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canHandle(BlockState blockState) {
|
public boolean isRightTool(BlockPos pos) {
|
||||||
return blockState.isIn(leavesTag);
|
var blockState = session.world.getBlockState(pos);
|
||||||
}
|
return session.player.getMainHandStack().isSuitableFor(blockState) || session.player.getMainHandStack().getItem() == Items.SHEARS;
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean drill(BlockPos startPos) {
|
|
||||||
ServerWorld world = session.world;
|
|
||||||
Block initialBlock = world.getBlockState(startPos).getBlock();
|
|
||||||
int brokenLeaves = 0;
|
|
||||||
ArrayDeque<BlockPos> pending = new ArrayDeque<BlockPos>();
|
|
||||||
pending.add(startPos);
|
|
||||||
|
|
||||||
while (!pending.isEmpty() && brokenLeaves < getConfig().maxVeinSize) {
|
|
||||||
BlockPos leavesPos = pending.remove();
|
|
||||||
Block leavesBlock = world.getBlockState(leavesPos).getBlock();
|
|
||||||
if (tryBreakBlock(leavesPos)) {
|
|
||||||
if (leavesBlock == initialBlock) {
|
|
||||||
brokenLeaves += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (leavesBlock == initialBlock) {
|
|
||||||
// look around current block
|
|
||||||
forXYZ(leavesPos, 1, newPos -> {
|
|
||||||
BlockState newBlockState = world.getBlockState(newPos);
|
|
||||||
Block newBlock = newBlockState.getBlock();
|
|
||||||
boolean isSameOreBlock = newBlock == leavesBlock;
|
|
||||||
if (!pending.contains(newPos) && isSameOreBlock) {
|
|
||||||
pending.add(newPos);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,62 +1,14 @@
|
|||||||
package wtf.hak.survivalfabric.features.veinminer.drills;
|
package wtf.hak.survivalfabric.features.veinminer.drills;
|
||||||
|
|
||||||
import net.minecraft.block.Block;
|
|
||||||
import net.minecraft.block.BlockState;
|
|
||||||
import net.minecraft.registry.RegistryKeys;
|
import net.minecraft.registry.RegistryKeys;
|
||||||
import net.minecraft.registry.tag.TagKey;
|
import net.minecraft.registry.tag.TagKey;
|
||||||
import net.minecraft.server.world.ServerWorld;
|
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import wtf.hak.survivalfabric.features.veinminer.VeinMinerSession;
|
import wtf.hak.survivalfabric.features.veinminer.VeinMinerSession;
|
||||||
|
|
||||||
import java.util.ArrayDeque;
|
|
||||||
|
|
||||||
import static wtf.hak.survivalfabric.config.ConfigManager.getConfig;
|
|
||||||
|
|
||||||
public class OreDrill extends DrillBase {
|
public class OreDrill extends DrillBase {
|
||||||
|
|
||||||
public static final TagKey<Block> oreTag = TagKey.of(RegistryKeys.BLOCK, Identifier.of("survivalfabric", "ore"));
|
|
||||||
|
|
||||||
public OreDrill(VeinMinerSession session) {
|
public OreDrill(VeinMinerSession session) {
|
||||||
super(session);
|
super(session, TagKey.of(RegistryKeys.BLOCK, Identifier.of("survivalfabric", "ore")));
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canHandle(BlockState blockState) {
|
|
||||||
return blockState.isIn(oreTag);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean drill(BlockPos startPos) {
|
|
||||||
ServerWorld world = session.world;
|
|
||||||
Block initialBlock = world.getBlockState(startPos).getBlock();
|
|
||||||
int brokenOre = 0;
|
|
||||||
ArrayDeque<BlockPos> pending = new ArrayDeque<BlockPos>();
|
|
||||||
pending.add(startPos);
|
|
||||||
|
|
||||||
while (!pending.isEmpty() && brokenOre < getConfig().maxVeinSize) {
|
|
||||||
BlockPos orePos = pending.remove();
|
|
||||||
Block oreBlock = world.getBlockState(orePos).getBlock();
|
|
||||||
if (tryBreakBlock(orePos)) {
|
|
||||||
if (oreBlock == initialBlock) {
|
|
||||||
brokenOre += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (oreBlock == initialBlock) {
|
|
||||||
// look around current block
|
|
||||||
forXYZ(orePos, 1, newPos -> {
|
|
||||||
BlockState newBlockState = world.getBlockState(newPos);
|
|
||||||
Block newBlock = newBlockState.getBlock();
|
|
||||||
boolean isSameOreBlock = newBlock == oreBlock;
|
|
||||||
if (!pending.contains(newPos) && isSameOreBlock) {
|
|
||||||
pending.add(newPos);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,80 +1,14 @@
|
|||||||
package wtf.hak.survivalfabric.features.veinminer.drills;
|
package wtf.hak.survivalfabric.features.veinminer.drills;
|
||||||
|
|
||||||
import net.minecraft.block.Block;
|
|
||||||
import net.minecraft.block.BlockState;
|
|
||||||
import net.minecraft.registry.Registries;
|
|
||||||
import net.minecraft.registry.RegistryKeys;
|
import net.minecraft.registry.RegistryKeys;
|
||||||
import net.minecraft.registry.tag.TagKey;
|
import net.minecraft.registry.tag.TagKey;
|
||||||
import net.minecraft.server.world.ServerWorld;
|
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import wtf.hak.survivalfabric.features.veinminer.VeinMinerSession;
|
import wtf.hak.survivalfabric.features.veinminer.VeinMinerSession;
|
||||||
|
|
||||||
import java.util.ArrayDeque;
|
|
||||||
|
|
||||||
import static wtf.hak.survivalfabric.config.ConfigManager.getConfig;
|
|
||||||
|
|
||||||
public class WoodDrill extends DrillBase {
|
public class WoodDrill extends DrillBase {
|
||||||
|
|
||||||
public static final TagKey<Block> woodTag = TagKey.of(RegistryKeys.BLOCK, Identifier.of("survivalfabric", "wood"));
|
|
||||||
|
|
||||||
public WoodDrill(VeinMinerSession session) {
|
public WoodDrill(VeinMinerSession session) {
|
||||||
super(session);
|
super(session, TagKey.of(RegistryKeys.BLOCK, Identifier.of("survivalfabric", "wood")));
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canHandle(BlockState blockState) {
|
|
||||||
return blockState.isIn(woodTag);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean drill(BlockPos startPos) {
|
|
||||||
ServerWorld world = session.world;
|
|
||||||
int broken = 0;
|
|
||||||
ArrayDeque<BlockPos> pendingLogs = new ArrayDeque<>();
|
|
||||||
ArrayDeque<BlockPos> logBlocks = new ArrayDeque<>();
|
|
||||||
pendingLogs.add(startPos);
|
|
||||||
|
|
||||||
String leavesBlockId = Registries.BLOCK.getId(world.getBlockState(startPos).getBlock()).toString().replace("_log", "_leaves");
|
|
||||||
|
|
||||||
while (!pendingLogs.isEmpty() && broken < getConfig().maxVeinSize) {
|
|
||||||
BlockPos woodPos = pendingLogs.remove();
|
|
||||||
Block woodBlock = world.getBlockState(woodPos).getBlock();
|
|
||||||
|
|
||||||
if (tryBreakBlock(woodPos)) {
|
|
||||||
logBlocks.add(woodPos);
|
|
||||||
broken += 1;
|
|
||||||
|
|
||||||
// look around current block
|
|
||||||
forXYZ(woodPos, 1, newPos -> {
|
|
||||||
Block newBlock = world.getBlockState(newPos).getBlock();
|
|
||||||
if (newBlock == woodBlock && !pendingLogs.contains(newPos)) {
|
|
||||||
pendingLogs.add(newPos);
|
|
||||||
}
|
|
||||||
}, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ArrayDeque<BlockPos> pendingLeaves = logBlocks;
|
|
||||||
while (!pendingLeaves.isEmpty() && broken < getConfig().maxVeinSize) {
|
|
||||||
broken += forXYZ(pendingLeaves.remove(), 1, newPos -> {
|
|
||||||
int brokenLeaves = 0;
|
|
||||||
Block newBlock = world.getBlockState(newPos).getBlock();
|
|
||||||
String newBlockId = Registries.BLOCK.getId(newBlock).toString();
|
|
||||||
if (newBlockId.equals(leavesBlockId)) {
|
|
||||||
if (tryBreakBlock(newPos)) {
|
|
||||||
brokenLeaves += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return brokenLeaves;
|
|
||||||
}, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isLeaf(Block block) {
|
|
||||||
return Registries.BLOCK.getId(block).toString().endsWith("_leaves");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
60
src/main/java/wtf/hak/survivalfabric/mixin/BlockMixin.java
Normal file
60
src/main/java/wtf/hak/survivalfabric/mixin/BlockMixin.java
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
package wtf.hak.survivalfabric.mixin;
|
||||||
|
|
||||||
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.block.CropBlock;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.item.HoeItem;
|
||||||
|
import net.minecraft.item.Item;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.server.world.ServerWorld;
|
||||||
|
import net.minecraft.stat.Stats;
|
||||||
|
import net.minecraft.util.Hand;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.GameMode;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
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 wtf.hak.survivalfabric.config.ConfigManager;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Mixin(Block.class)
|
||||||
|
public abstract class BlockMixin {
|
||||||
|
|
||||||
|
@Inject(method = "onBreak", at = @At("HEAD"), cancellable = true)
|
||||||
|
public void onBreak(World world, BlockPos pos, BlockState state, PlayerEntity player, CallbackInfoReturnable<BlockState> cir) {
|
||||||
|
if (world.isClient()) return;
|
||||||
|
|
||||||
|
if (state.getBlock() instanceof CropBlock && ConfigManager.getConfig().replenishEnabled) {
|
||||||
|
ItemStack mainHand = player.getStackInHand(Hand.MAIN_HAND);
|
||||||
|
if (mainHand.getItem() instanceof HoeItem) {
|
||||||
|
Item seedItem = state.getBlock().asItem();
|
||||||
|
Block seedBlock = state.getBlock();
|
||||||
|
List<ItemStack> drops = Block.getDroppedStacks(state, (ServerWorld) world, pos, null, player, mainHand);
|
||||||
|
if (removeIfAvailable(drops, seedItem)) {
|
||||||
|
if (player.getGameMode() != GameMode.CREATIVE) {
|
||||||
|
for (ItemStack drop : drops) {
|
||||||
|
Block.dropStack(world, pos, drop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
world.getServer().executeSync(() -> world.setBlockState(pos, seedBlock.getDefaultState()));
|
||||||
|
player.incrementStat(Stats.USED.getOrCreateStat(seedItem));
|
||||||
|
cir.cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean removeIfAvailable(List<ItemStack> drops, Item item) {
|
||||||
|
for (ItemStack drop : drops) {
|
||||||
|
if (drop.getItem() == item) {
|
||||||
|
drop.decrement(1);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
45
src/main/java/wtf/hak/survivalfabric/utils/Scheduler.java
Normal file
45
src/main/java/wtf/hak/survivalfabric/utils/Scheduler.java
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
package wtf.hak.survivalfabric.utils;
|
||||||
|
|
||||||
|
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
public class Scheduler {
|
||||||
|
|
||||||
|
private static Scheduler INSTANCE;
|
||||||
|
|
||||||
|
private final Map<Runnable, Long> tasks = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
public Scheduler() {
|
||||||
|
ServerTickEvents.END_SERVER_TICK.register((server) -> {
|
||||||
|
for(Runnable task : tasks.keySet()) {
|
||||||
|
long delay = tasks.get(task);
|
||||||
|
if(delay <= 0) {
|
||||||
|
task.run();
|
||||||
|
tasks.remove(task);
|
||||||
|
} else {
|
||||||
|
tasks.put(task, delay-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void scheduleTask(Runnable task) {
|
||||||
|
scheduleTask(task, 0L);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void scheduleTask(Runnable task, long delay) {
|
||||||
|
tasks.put(task, delay);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Scheduler get() {
|
||||||
|
return INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Scheduler initialize() {
|
||||||
|
INSTANCE = new Scheduler();
|
||||||
|
return INSTANCE;
|
||||||
|
}
|
||||||
|
}
|
@ -3,6 +3,7 @@
|
|||||||
"package": "wtf.hak.survivalfabric.mixin",
|
"package": "wtf.hak.survivalfabric.mixin",
|
||||||
"compatibilityLevel": "JAVA_21",
|
"compatibilityLevel": "JAVA_21",
|
||||||
"mixins": [
|
"mixins": [
|
||||||
|
"BlockMixin",
|
||||||
"PlayerManagerMixin",
|
"PlayerManagerMixin",
|
||||||
"ServerPlayerEntityMixin",
|
"ServerPlayerEntityMixin",
|
||||||
"ServerPlayNetworkHandlerMixin",
|
"ServerPlayNetworkHandlerMixin",
|
||||||
|
Reference in New Issue
Block a user