Skip to content

Commit

Permalink
add blockstate data card to block breaker
Browse files Browse the repository at this point in the history
  • Loading branch information
Lothrazar committed Nov 2, 2024
1 parent 6984a35 commit 1b12224
Show file tree
Hide file tree
Showing 10 changed files with 121 additions and 61 deletions.
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ org.gradle.jvmargs=-Xmx3G
org.gradle.daemon=false

curse_id=239286
mod_version=1.5.24
mod_version=1.6.0

mc_version=1.16.5
forge_version=36.2.34
Expand Down
5 changes: 3 additions & 2 deletions src/main/java/com/lothrazar/cyclic/base/ScreenBase.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.lothrazar.cyclic.base;

import com.lothrazar.cyclic.ModCyclic;
import com.lothrazar.cyclic.data.Const;
import com.lothrazar.cyclic.gui.GuiSliderInteger;
import com.lothrazar.cyclic.gui.IHasTooltip;
import com.lothrazar.cyclic.gui.TextBoxAutosave;
Expand Down Expand Up @@ -54,7 +55,7 @@ public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
}

protected void drawSlot(MatrixStack ms, int x, int y, ResourceLocation texture) {
drawSlot(ms, x, y, texture, 18);
drawSlot(ms, x, y, texture, Const.SQ);
}

protected void drawSlot(MatrixStack ms, int x, int y, ResourceLocation texture, int size) {
Expand All @@ -63,7 +64,7 @@ protected void drawSlot(MatrixStack ms, int x, int y, ResourceLocation texture,
}

protected void drawSlot(MatrixStack ms, int x, int y) {
drawSlot(ms, x, y, TextureRegistry.SLOT, 18);
drawSlot(ms, x, y, TextureRegistry.SLOT, Const.SQ);
}

protected void drawSlotLarge(MatrixStack ms, int x, int y) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import net.minecraft.util.IWorldPosCallable;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.SlotItemHandler;

public class ContainerBreaker extends ContainerBase {

Expand All @@ -18,6 +20,10 @@ public ContainerBreaker(int windowId, World world, BlockPos pos, PlayerInventory
tile = (TileBreaker) world.getTileEntity(pos);
this.playerEntity = player;
this.playerInventory = playerInventory;
tile.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY).ifPresent(h -> {
this.endInv = h.getSlots();
addSlot(new SlotItemHandler(h, 0, 81, 31));
});
layoutPlayerInventorySlots(8, 84);
trackEnergy(tile);
this.trackAllIntFields(tile, TileBreaker.Fields.values().length);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,6 @@ protected void drawGuiContainerForegroundLayer(MatrixStack ms, int mouseX, int m
@Override
protected void drawGuiContainerBackgroundLayer(MatrixStack ms, float partialTicks, int mouseX, int mouseY) {
this.drawBackground(ms, TextureRegistry.INVENTORY);
this.drawSlot(ms, 80, 30, TextureRegistry.SLOT_BSDATA);
}
}
73 changes: 62 additions & 11 deletions src/main/java/com/lothrazar/cyclic/block/breaker/TileBreaker.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,30 @@
import com.lothrazar.cyclic.ModCyclic;
import com.lothrazar.cyclic.base.TileEntityBase;
import com.lothrazar.cyclic.data.DataTags;
import com.lothrazar.cyclic.item.datacard.BlockStateMatcher;
import com.lothrazar.cyclic.item.datacard.BlockstateCard;
import com.lothrazar.cyclic.registry.ItemRegistry;
import com.lothrazar.cyclic.registry.TileRegistry;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.container.Container;
import net.minecraft.inventory.container.INamedContainerProvider;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.tileentity.ITickableTileEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.StringTextComponent;
import net.minecraft.world.World;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.ItemStackHandler;

public class TileBreaker extends TileEntityBase implements INamedContainerProvider, ITickableTileEntity {

Expand All @@ -26,14 +36,32 @@ static enum Fields {

static final int MAX = 64000;
public static final int TIMER_FULL = 500;
// public static IntValue POWERCONF;
// private CustomEnergyStorage energy = new CustomEnergyStorage(MAX, MAX);
// private final LazyOptional<IEnergyStorage> energyCap = LazyOptional.of(() -> energy);
ItemStackHandler inventory = new ItemStackHandler() {

@Override
public int getSlotLimit(int slot) {
return 1;
}

@Override
public boolean isItemValid(int slot, ItemStack stack) {
return stack.getItem() == ItemRegistry.STATECARD.get();
}
};
private LazyOptional<IItemHandler> inventoryCap = LazyOptional.of(() -> inventory);

public TileBreaker() {
super(TileRegistry.breakerTile);
}

@Override
public <T> LazyOptional<T> getCapability(Capability<T> cap, Direction side) {
if (cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) {
return inventoryCap.cast();
}
return super.getCapability(cap, side);
}

@Override
public void tick() {
if (this.requiresRedstone() && !this.isPowered()) {
Expand All @@ -50,33 +78,56 @@ public void tick() {
}
}

@Override
public void invalidateCaps() {
inventoryCap.invalidate();
super.invalidateCaps();
}

/**
* Avoid mining source liquid blocks and unbreakable
*/
private boolean isTargetValid(BlockPos targetPos) {
World level = world;
BlockState state = level.getBlockState(targetPos);
if (state.getBlock() == Blocks.AIR) {
BlockState targetState = level.getBlockState(targetPos);
if (targetState.getBlock() == Blocks.AIR) {
return false;
}
if (state.getBlockHardness(level, targetPos) < 0) {
if (targetState.getBlockHardness(level, targetPos) < 0) {
return false;
}
//check the tag ignore list so modpack/datapack can filter this
if (state.isIn(DataTags.BREAKER_IGNORED)) {
if (targetState.isIn(DataTags.BREAKER_IGNORED)) {
ModCyclic.LOGGER.info("breaker/ignored tag skips " + targetPos);
return false;
}
if (state.getFluidState() != null && state.getFluidState().isEmpty() == false) {
if (targetState.getFluidState() != null && targetState.getFluidState().isEmpty() == false) {
//am i a solid waterlogged state block?
if (state.hasProperty(BlockStateProperties.WATERLOGGED) == false) {
if (targetState.hasProperty(BlockStateProperties.WATERLOGGED) == false) {
//pure liquid. but this will make canHarvestBlock go true
return false;
}
}
if (!this.isValidFromDatacard(targetState)) {
return false;
}
// else filter is empty
return true;
}

private boolean isValidFromDatacard(BlockState targetState) {
ItemStack filter = inventory.getStackInSlot(0);
if (filter.isEmpty()) {
return true; //ya go
}
for (BlockStateMatcher m : BlockstateCard.getSavedStates(filter)) {
if (m.doesMatch(targetState)) {
return true; // i am allowed to mine this
}
}
return false; //filter is my allow list, and you aint in it so not allowed
}

@Override
public ITextComponent getDisplayName() {
return new StringTextComponent(getType().getRegistryName().getPath());
Expand All @@ -89,13 +140,13 @@ public Container createMenu(int i, PlayerInventory playerInventory, PlayerEntity

@Override
public void read(BlockState bs, CompoundNBT tag) {
// energy.deserializeNBT(tag.getCompound(NBTENERGY));
inventory.deserializeNBT(tag.getCompound(NBTINV));
super.read(bs, tag);
}

@Override
public CompoundNBT write(CompoundNBT tag) {
// tag.put(NBTENERGY, energy.serializeNBT());
tag.put(NBTINV, inventory.serializeNBT());
return super.write(tag);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ protected void drawGuiContainerForegroundLayer(MatrixStack ms, int mouseX, int m
@Override
protected void drawGuiContainerBackgroundLayer(MatrixStack ms, float partialTicks, int mouseX, int mouseY) {
this.drawBackground(ms, TextureRegistry.INVENTORY);
// this.drawSlot(ms, 54, 34);
this.drawSlotLarge(ms, 70, 30);
energy.draw(ms, container.tile.getEnergy());
progress.max = container.tile.getField(TileGeneratorFood.Fields.BURNMAX.ordinal());
Expand Down
62 changes: 20 additions & 42 deletions src/main/java/com/lothrazar/cyclic/block/miner/TileMiner.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import net.minecraft.inventory.container.INamedContainerProvider;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.state.Property;
import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.tileentity.ITickableTileEntity;
import net.minecraft.tileentity.TileEntity;
Expand Down Expand Up @@ -221,40 +220,6 @@ private boolean updateMiningProgress(List<BlockPos> shape) {
return false;
}

private boolean isValidTarget(BlockState targetState) {
ItemStack filter = inventory.getStackInSlot(SLOT_FILTER);
if (filter.isEmpty()) {
return true; //ya go
}
for (BlockStateMatcher m : BlockstateCard.getSavedStates(filter)) {
BlockState st = m.getState();
if (targetState.getBlock() == st.getBlock()) {
if (m.isExactProperties() == false) {
// the blocks DO match, isExact is flagged as no, so we are good
return true;
}
//tag DOES want to match Exactly on Properties
return this.propertiesMatch(targetState, st);
}
}
return false;
}

private boolean propertiesMatch(BlockState targetState, BlockState st) {
try {
for (Property<?> p : st.getProperties()) {
if (!st.get(p).equals(targetState.get(p))) {
return false;
}
}
}
catch (Exception e) {
return false;
}
//none had a mismatch
return true;
}

/***
* Unbreakable blocks and fluid blocks are not valid. Otherwise checks if player:canHarvestBlock using its equipped item
*/
Expand All @@ -263,35 +228,48 @@ private boolean isTargetValid() {
return false; //dont mine air or liquid.
}
//is this valid
BlockState state = world.getBlockState(targetPos);
if (state.hardness < 0) {
BlockState targetState = world.getBlockState(targetPos);
if (targetState.hardness < 0) {
return false; //unbreakable
}
//check the tag ignore list so modpack/datapack can filter this
if (state.isIn(DataTags.MINER_IGNORED)) {
if (targetState.isIn(DataTags.MINER_IGNORED)) {
ModCyclic.LOGGER.info("miner/ignored tag skips " + targetPos);
return false;
}
//water logged is
if (state.getFluidState() != null && state.getFluidState().isEmpty() == false) {
if (targetState.getFluidState() != null && targetState.getFluidState().isEmpty() == false) {
//am i PURE liquid? or just a WATERLOGGED block
if (state.hasProperty(BlockStateProperties.WATERLOGGED) == false) {
if (targetState.hasProperty(BlockStateProperties.WATERLOGGED) == false) {
// ModCyclic.LOGGER.info(targetPos + " Mining FLUID is not valid " + blockSt);
//pure liquid. but this will make canHarvestBlock go true , which is a lie actually so, no. dont get stuck here
return false;
}
}
if (!this.isValidTarget(state)) {
if (!this.isValidFromDatacard(targetState)) {
return false;
}
//its a solid non-air, non-fluid block (but might be like waterlogged stairs or something)
boolean canHarvest = state.canHarvestBlock(world, targetPos, fakePlayer.get());
boolean canHarvest = targetState.canHarvestBlock(world, targetPos, fakePlayer.get());
if (!canHarvest) {
// ModCyclic.LOGGER.info(targetPos + " Mining target is not valid " + blockSt);
}
return canHarvest;
}

private boolean isValidFromDatacard(BlockState targetState) {
ItemStack filter = inventory.getStackInSlot(SLOT_FILTER);
if (filter.isEmpty()) {
return true; //ya go
}
for (BlockStateMatcher m : BlockstateCard.getSavedStates(filter)) {
if (m.doesMatch(targetState)) {
return true; // i am allowed to mine this
}
}
return false; //filter is my allow list, and you aint in it so not allowed
}

private void updateTargetPos(List<BlockPos> shape) {
shapeIndex++;
if (this.shapeIndex < 0 || this.shapeIndex >= shape.size()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,16 @@ public class BlockStateMatcher {
private BlockState state;
private boolean exactProperties = true;

public boolean doesMatch(BlockState other) {
// returns true if target state matches this
public boolean doesMatch(BlockState targetState) {
if (targetState.getBlock() == this.getState().getBlock()) {
if (this.isExactProperties() == false) {
// the blocks DO match, isExact is flagged as no, so we are good
return true;
}
//tag DOES want to match Exactly on Properties
return BlockstateCard.propertiesMatch(targetState, this.getState());
}
return false;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.nbt.ListNBT;
import net.minecraft.nbt.NBTUtil;
import net.minecraft.state.Property;
import net.minecraft.util.ActionResultType;
import net.minecraft.util.Hand;
import net.minecraft.util.math.BlockPos;
Expand Down Expand Up @@ -73,12 +74,26 @@ public static List<BlockStateMatcher> getSavedStates(ItemStack held) {
return st;
}

public static boolean propertiesMatch(BlockState targetState, BlockState st) {
try {
for (Property<?> p : st.getProperties()) {
if (!st.get(p).equals(targetState.get(p))) {
return false;
}
}
}
catch (Exception e) {
return false;
}
//none had a mismatch
return true;
}

@Override
public ActionResultType onItemUse(ItemUseContext context) {
PlayerEntity player = context.getPlayer();
Hand hand = context.getHand();
BlockPos pos = context.getPos();
// Direction side = context.getFace();
ItemStack held = player.getHeldItem(hand);
BlockState state = context.getWorld().getBlockState(pos);
CompoundNBT stateTag = NBTUtil.writeBlockState(state);
Expand Down
4 changes: 2 additions & 2 deletions update.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"homepage": "https://www.curseforge.com/minecraft/mc-mods/cyclic",
"promos": {
"1.16.5-latest": "1.5.24"
"1.16.5-latest": "1.6.0"
},
"1.16.5": {
"0.6.1": "Ported ",
Expand Down Expand Up @@ -81,6 +81,6 @@
,"1.5.22":"Fix #2351 advanced crafting stick not opening. "
,"1.5.23":"Growth enchantment now uses the same logic as Sprinkler & Terra Soil (only minecraft:crops or minecraft::saplings can grow, respect IGrowable::canUseBonemeal). New gloomIgnored config Gloom enchant (cyclic:curse) to ignore and not use these effects #2217 #2325. Fix Soundproofing block not muting Mekanism sounds #2389 (for example Precision Sawmill and others - you may need four or more soundproofing blocks for the desired effect). Patch an edge-case where User might drop items on the ground. New config [cyclic.blocks.soundproofing] radius = 6 to control the area. Fix item cable routing #2245 #2230. New config under [cyclic.blocks] wireless_transfer_dimensional = true allowing transfer nodes to connect across dimensions #1913. Balance recipe changes for #2372. Balance changes made for Excavate enchant it will no longer trigger if the tool is not 'mineable' effective for example axe on dirt. New feature for Excavate enchant #2116 it will not trigger on anything matching the block data-tag 'cyclic:ignored/excavate'. [Backported changes from mc1.20.1] #2182 candle model assets; Block Breaker no longer tries (and fails) to mine liquid source blocks; Block Randomizer use wireframe rendering only of non-air instead of solid shading; Glistering & Corrupted chorus only restores 1 food-unit down from 3; a few recipes tweaked/backported to match mc1.20.1+, ported crafttweaker zenscript support for generator_fluid and generator_item; backported item data tags for use in recipes for example forge:vines, forge:sandstone, forge:mushrooms "
,"1.5.24":"Fixed bug in the item cyclic:offset_scepter #2427. Tweaked block model visuals of the Transfer Nodes. Fix Mattock not saving contents of Shulker Boxes when mined #2411. "
,"":"Add new block data tags cyclic:ignored/breaker and cyclic:ignored/miner so that pack devs can customize these machines to not break certain blocks. Many blocks now allow minecraft:comparator to pull a redstone signal based on inventory contents. Fluid collector will now place air and scoop up the fluid if the itemslot is empty. New feature: some machines can now be placed facing Up or Down vertically for convenience (harvester, forester, miner, item collector, fluid collector, dropper). Backported machine feature 'Preview Outline' mode on machines that already have the button. Backported cable (fluid & energy) buffer and flow speed configs from 1.20.1 "
,"1.6.0":"Added an optional item slot in the Block Breaker using the BlockState Data Card so players have the option to limit the block breaker to only the targets listed in the data card. Add new block data tags cyclic:ignored/breaker and cyclic:ignored/miner so that pack devs can customize these machines to not break certain blocks (regardless of hardness). Many blocks now allow minecraft:comparator to pull a redstone signal based on inventory contents (most machines and blocks that have inventory). Fluid collector will now place air and scoop up the fluid if the itemslot is empty. New feature: some machines can now be placed facing Up or Down vertically for convenience (harvester, forester, miner, item collector, fluid collector, dropper). Backported machine feature 'Preview Outline' mode on machines that already have the button. Backported cable (fluid & energy) buffer and flow speed configs from 1.20.1 "
}
}

0 comments on commit 1b12224

Please sign in to comment.