diff --git a/checkstyle.xml b/.eclipse/checkstyle.xml similarity index 100% rename from checkstyle.xml rename to .eclipse/checkstyle.xml diff --git a/build.gradle b/build.gradle index eeed3542a..43e536690 100644 --- a/build.gradle +++ b/build.gradle @@ -128,6 +128,7 @@ repositories { maven { url = 'https://modmaven.dev' } maven { url = 'https://www.cursemaven.com' } + } dependencies { diff --git a/examples/config/cyclic.toml b/examples/config/cyclic.toml index 69d7cdfd4..f6bf344cb 100644 --- a/examples/config/cyclic.toml +++ b/examples/config/cyclic.toml @@ -156,6 +156,8 @@ enabled = true [cyclic.enchantment.curse] + #Set list of effects for Gloom enchant (cyclic:curse) to ignore and not use these + ignored = ["minecraft:bad_omen", "minecraft:nausea", "botania:clear"] #(Gloom) Set false to stop enchantment from working enabled = true @@ -208,6 +210,8 @@ # Block specific configs ##################################################################################### [cyclic.blocks] + # Allows the dimensional Transfer Nodes to cross dimensions (no chunk loading is done, you have to do that on your own); This affects blocks cyclic:wireless_energy, cyclic:wireless_item, cyclic:wireless_fluid, cyclic:wireless_transmitter; If you change it to false it will only work if the target is in the same dimension. + wireless_transfer_dimensional = true #If true, then all potions marked as harmful/negative will be used in addition to the 'anti_beacon.potion_list' for cures and immunities (used by both sponge and artemisbeacon). harmful_potions = true @@ -370,15 +374,25 @@ #Range: 0 ~ 1000 water = 5 + #terra_glass settings + [cyclic.blocks.terra_glass] + #ticks between growth cycles + #Range: 1 ~ 10000 + timer = 100 + #growth height below the glass + #Range: 0 ~ 32 + height = 8 + #experience_pylon settings [cyclic.blocks.experience_pylon] #Radius to pickup xp orbs #Range: 1 ~ 64 radius = 16 + #soundproofing settings [cyclic.blocks.soundproofing] - #Radius to find and muffle sounds. - #Range: 1 ~ 128 + #Radius of sound proofing (distance from each block that it will listen) + #Range: 1 ~ 16 radius = 6 [cyclic.blocks.cables] @@ -427,6 +441,7 @@ #Range: 0 ~ 64000 energy_cost = 10 + #Ender shelf settings [cyclic.blocks.ender_shelf] #Controller Max distance to search (using manhattan distance) #Range: 1 ~ 256 @@ -459,12 +474,15 @@ fluid_cost = 100 [cyclic.blocks.terra_preta] - #Growth interval in ticks (100 would be every 5 seconds). Also affects terra glass + #Growth interval in ticks (100 would be every 5 seconds). #Range: 1 ~ 64000 growth_interval = 100 #Chance that the crop will grow after the interval #Range: 0.0 ~ 1.0 growth_chance = 0.5 + #growth height above the soil + #Range: 2 ~ 32 + height = 8 [cyclic.blocks.uncrafter] #When searching for a recipe, does it ignore all NBT values (such as enchantments, RepairCost, Damage, etc). For example, if false it will not uncraft damaged or enchanted items diff --git a/examples/scripts/crusher.zs b/examples/scripts/crusher.zs index c6fad7d51..f7b65941c 100644 --- a/examples/scripts/crusher.zs +++ b/examples/scripts/crusher.zs @@ -13,5 +13,3 @@ crusher.addRecipe("castlevania", ,,*2, 500, 300); - - diff --git a/examples/scripts/durability.zs b/examples/scripts/durability.zs new file mode 100644 index 000000000..4c5258d03 --- /dev/null +++ b/examples/scripts/durability.zs @@ -0,0 +1,10 @@ + + +// change max damage aka durability aka number of tool uses like this + +val glove = ; +glove.maxDamage = 64; + + +val wand = ; +wand.maxDamage = 16; diff --git a/examples/scripts/generator_fluid.zs b/examples/scripts/generator_fluid.zs index 6e6075651..ab49af8dc 100644 --- a/examples/scripts/generator_fluid.zs +++ b/examples/scripts/generator_fluid.zs @@ -4,6 +4,7 @@ var generator = ; + // recipe IDS, not item ids // see datapack inside the jar file or see https://github.com/Lothrazar/Cyclic/tree/trunk/1.20/src/main/resources/data/cyclic/recipes/generator @@ -11,8 +12,8 @@ generator.removeRecipe("cyclic:generator/generate_xp","cyclic:generator/generate + generator.addRecipe("zoldo", *250, 5, 10); generator.addRecipe("lava_tag", "minecraft:lava", 1000, 200, 500); - diff --git a/examples/scripts/melter.zs b/examples/scripts/melter.zs index ce1b984f3..cd2c9d92b 100644 --- a/examples/scripts/melter.zs +++ b/examples/scripts/melter.zs @@ -7,5 +7,6 @@ var melter = ; melter.removeRecipe("cyclic:melter/melter_snowwater"); melter.removeRecipe("cyclic:melter/melter_expflesh", "cyclic:melter/melter_expblaze"); + melter.addRecipe("spruce_wayne", [,], *75, 500, 3); diff --git a/examples/scripts/remove_by_modid.zs b/examples/scripts/remove_by_modid.zs new file mode 100644 index 000000000..9954e0cad --- /dev/null +++ b/examples/scripts/remove_by_modid.zs @@ -0,0 +1,2 @@ + +craftingTable.removeByModid("cyclic"); diff --git a/gradle.properties b/gradle.properties index 22c7f8180..32a46762d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,7 +7,8 @@ org.gradle.daemon=false mod_id=cyclic curse_id=239286 -mod_version=1.12.7 +mod_version=1.12.8-SNAPSHOT + # NEO FORGED forge_version=47.1.65 @@ -33,13 +34,20 @@ mc_version=1.20.1 -flib_version=0.0.10 +flib_version=0.0.11 flib_file=4718037 patchouli_version=81 jei_version=15.0.0.12 curios_version=5.2.0-beta.3+1.20.1 crafttweaker_version=14.0.12 + + +botania_version=443 +crafttweaker_version=14.0.38 +# https://www.curseforge.com/minecraft/mc-mods/crafttweaker/files/5210437 +#https://www.curseforge.com/minecraft/mc-mods/botania/files/4557912 + # for eclipse.ini if needed #-vm #C:\Program Files\AdoptOpenJDK\jdk-16.0.1.9-hotspot\bin\javaw.exe diff --git a/scripts/clean_config.sh b/scripts/clean_config.sh new file mode 100644 index 000000000..fb8a1e434 --- /dev/null +++ b/scripts/clean_config.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +rm run/config/cyclic.toml +rm run/config/cyclic-client.toml + +echo "configs reset" diff --git a/scripts/example_config.sh b/scripts/example_config.sh new file mode 100644 index 000000000..23ecdd889 --- /dev/null +++ b/scripts/example_config.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +cp run/config/cyclic.toml examples/config/cyclic.toml +cp run/config/cyclic-client.toml examples/config/cyclic-client.toml diff --git a/src/main/java/com/lothrazar/cyclic/block/BlockCyclic.java b/src/main/java/com/lothrazar/cyclic/block/BlockCyclic.java index 1b171ad30..713e84b02 100644 --- a/src/main/java/com/lothrazar/cyclic/block/BlockCyclic.java +++ b/src/main/java/com/lothrazar/cyclic/block/BlockCyclic.java @@ -85,7 +85,7 @@ public BlockState rotate(BlockState state, LevelAccessor world, BlockPos pos, Ro @Override public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) { - if (hasFluidInteract) { + if (hasFluidInteract && player.getItemInHand(hand).isEmpty()) { if (!world.isClientSide) { BlockEntity tankHere = world.getBlockEntity(pos); if (tankHere != null) { diff --git a/src/main/java/com/lothrazar/cyclic/block/TileBlockEntityCyclic.java b/src/main/java/com/lothrazar/cyclic/block/TileBlockEntityCyclic.java index ba359c9f2..1b4547121 100644 --- a/src/main/java/com/lothrazar/cyclic/block/TileBlockEntityCyclic.java +++ b/src/main/java/com/lothrazar/cyclic/block/TileBlockEntityCyclic.java @@ -15,6 +15,7 @@ import com.lothrazar.cyclic.registry.PacketRegistry; import com.lothrazar.cyclic.util.FluidHelpers; import com.lothrazar.library.cap.CustomEnergyStorage; +import com.lothrazar.library.core.BlockPosDim; import com.lothrazar.library.core.IHasEnergy; import com.lothrazar.library.core.IHasFluid; import com.lothrazar.library.packet.PacketSyncEnergy; @@ -100,7 +101,8 @@ protected Player getLookingPlayer(int maxRange, boolean mustCrouch) { return null; } - public void tryDumpFakePlayerInvo(WeakReference fp, ItemStackHandler out, boolean onGround) { + // TODO: this could use a refactor + public void tryDumpFakePlayerInvo(WeakReference fp, ItemStackHandler out, boolean dropItemsOnGround) { if (out == null) { return; } @@ -111,23 +113,20 @@ public void tryDumpFakePlayerInvo(WeakReference fp, ItemStackHandler if (fpItem.isEmpty()) { continue; } - ModCyclic.LOGGER.info("NONEMPTY itemstack found what do we do"); if (fpItem == fp.get().getMainHandItem()) { - ModCyclic.LOGGER.info("aha continue main hand item dont doump it"); continue; } for (int j = 0; j < out.getSlots(); j++) { - ModCyclic.LOGGER.info(fpItem + "insert itit here" + j); fpItem = out.insertItem(j, fpItem, false); } - if (onGround) { + if (dropItemsOnGround) { toDrop.add(fpItem); } else { fp.get().getInventory().items.set(i, fpItem); } } - if (onGround) { + if (dropItemsOnGround) { ItemStackUtil.drop(this.level, this.worldPosition.above(), toDrop); } } @@ -283,20 +282,23 @@ public boolean requiresRedstone() { return this.needsRedstone == 1; } - public void moveFluids(Direction myFacingDir, BlockPos posTarget, int toFlow, IFluidHandler tank) { - // posTarget = pos.offset(myFacingDir); - if (tank == null || tank.getFluidInTank(0).getAmount() <= 0) { + protected void moveFluidsDimensional(BlockPosDim loc, int toFlow, IFluidHandler tank) { + Direction myFacingDir = loc.getSide(); + final Direction themFacingMe = myFacingDir.getOpposite(); + // moveFluidsInternal is just util tryFillPositionFromTank + FluidHelpers.tryFillPositionFromTank(loc.getTargetLevel(level), loc.getPos(), themFacingMe, tank, toFlow); + } + + protected void moveFluids(Direction myFacingDir, BlockPos posTarget, int toFlow, IFluidHandler tank) { + if (tank == null || tank.getFluidInTank(0).isEmpty()) { return; } - Direction themFacingMe = myFacingDir.getOpposite(); + final Direction themFacingMe = myFacingDir.getOpposite(); FluidHelpers.tryFillPositionFromTank(level, posTarget, themFacingMe, tank, toFlow); } public void tryExtract(IItemHandler myself, Direction extractSide, int qty, ItemStackHandler nullableFilter) { - if (extractSide == null) { - return; - } - if (extractSide == null || !myself.getStackInSlot(0).isEmpty()) { + if (myself == null || extractSide == null || !myself.getStackInSlot(0).isEmpty()) { return; } BlockPos posTarget = worldPosition.relative(extractSide); @@ -347,29 +349,46 @@ public boolean moveItemToCompost(Direction exportToSide, ItemStackHandler invent } return false; } + // + // + // public boolean moveItems(Direction myFacingDir, int max, IItemHandler handlerHere) { - return moveItems(myFacingDir, worldPosition.relative(myFacingDir), max, handlerHere, 0); + return moveItems(myFacingDir, this.worldPosition.relative(myFacingDir), max, handlerHere, 0); + } + + public boolean moveItemsDimensional(BlockPosDim loc, int max, IItemHandler handlerHere, int theslot) { + Direction myFacingDir = loc.getSide(); + final Direction themFacingMe = myFacingDir.getOpposite(); + ServerLevel serverWorld = loc.getTargetLevel(level); + return moveItemsInternal(max, handlerHere, theslot, themFacingMe, serverWorld.getBlockEntity(loc.getPos())); } public boolean moveItems(Direction myFacingDir, BlockPos posTarget, int max, IItemHandler handlerHere, int theslot) { - if (this.level.isClientSide()) { + if (max <= 0 || this.level.isClientSide()) { return false; } - if (handlerHere == null) { + //first get the original ItemStack as creating new ones is expensive + final Direction themFacingMe = myFacingDir.getOpposite(); + final BlockEntity tileTarget = level.getBlockEntity(posTarget); + return moveItemsInternal(max, handlerHere, theslot, themFacingMe, tileTarget); + } + + private static boolean moveItemsInternal(int max, IItemHandler handlerHere, int theslot, final Direction themFacingMe, final BlockEntity tileTarget) { + if (max <= 0 || tileTarget == null || handlerHere == null) { return false; } - Direction themFacingMe = myFacingDir.getOpposite(); - BlockEntity tileTarget = level.getBlockEntity(posTarget); - if (tileTarget == null) { + final ItemStack originalItemStack = handlerHere.getStackInSlot(theslot); + if (originalItemStack.isEmpty()) { return false; } - IItemHandler handlerOutput = tileTarget.getCapability(ForgeCapabilities.ITEM_HANDLER, themFacingMe).orElse(null); + // IItemHandler handlerOutput = tileTarget.getCapability(ForgeCapabilities.ITEM_HANDLER, themFacingMe).orElse(null); + final IItemHandler handlerOutput = tileTarget.getCapability(ForgeCapabilities.ITEM_HANDLER, themFacingMe).orElse(null); if (handlerOutput == null) { return false; } //first simulate - ItemStack drain = handlerHere.extractItem(theslot, max, true); // handlerHere.getStackInSlot(theslot).copy(); + ItemStack drain = handlerHere.extractItem(theslot, max, true); int sizeStarted = drain.getCount(); if (!drain.isEmpty()) { //now push it into output, but find out what was ACTUALLY taken @@ -386,49 +405,86 @@ public boolean moveItems(Direction myFacingDir, BlockPos posTarget, int max, IIt } return sizeAfter > 0; } + // + // + // + // + // + // protected boolean moveEnergy(Direction myFacingDir, int quantity) { - return moveEnergy(myFacingDir, worldPosition.relative(myFacingDir), quantity); + return moveEnergy(myFacingDir, this.worldPosition.relative(myFacingDir), quantity); } - protected boolean moveEnergy(Direction myFacingDir, BlockPos posTarget, int quantity) { + protected boolean moveEnergyDimensional(final BlockPosDim loc, final int quantity) { + //validation pre-move + if (quantity <= 0) { + return false; + } if (this.level.isClientSide) { - return false; //important to not desync cables + return false; //important to not desync cables } - IEnergyStorage handlerHere = this.getCapability(ForgeCapabilities.ENERGY, myFacingDir).orElse(null); - if (handlerHere == null || handlerHere.getEnergyStored() == 0) { + Direction myFacingDir = loc.getSide(); + final IEnergyStorage handlerHere = this.getCapability(ForgeCapabilities.ENERGY, myFacingDir).orElse(null); + ServerLevel serverWorld = loc.getTargetLevel(level); + final BlockEntity tileTarget = serverWorld.getBlockEntity(loc.getPos()); + final Direction themFacingMe = myFacingDir.getOpposite(); + return moveEnergyInternal(quantity, handlerHere, themFacingMe, tileTarget); + } + + //assums posTarget is in the same dimension as this.world + protected boolean moveEnergy(final Direction myFacingDir, final BlockPos posTarget, final int quantity) { + //validation pre-move + if (quantity <= 0) { return false; } - if (myFacingDir == null) { - myFacingDir = Direction.UP; + if (this.level.isClientSide) { + return false; //important to not desync cables + } + final IEnergyStorage handlerHere = this.getCapability(ForgeCapabilities.ENERGY, myFacingDir).orElse(null); + final Direction themFacingMe = myFacingDir.getOpposite(); + final BlockEntity tileTarget = level.getBlockEntity(posTarget); + return moveEnergyInternal(quantity, handlerHere, themFacingMe, tileTarget); + } + + private static boolean moveEnergyInternal(final int quantity, final IEnergyStorage handlerHere, final Direction themFacingMe, final BlockEntity tileTarget) { + if (handlerHere == null) { + return false; } - Direction themFacingMe = myFacingDir.getOpposite(); - BlockEntity tileTarget = level.getBlockEntity(posTarget); if (tileTarget == null) { return false; } - IEnergyStorage handlerOutput = tileTarget.getCapability(ForgeCapabilities.ENERGY, themFacingMe).orElse(null); + final IEnergyStorage handlerOutput = tileTarget.getCapability(ForgeCapabilities.ENERGY, themFacingMe).orElse(null); if (handlerOutput == null) { return false; } - if (handlerHere != null && handlerOutput != null - && handlerHere.canExtract() && handlerOutput.canReceive()) { - //first simulate - int drain = handlerHere.extractEnergy(quantity, true); - if (drain > 0) { - //now push it into output, but find out what was ACTUALLY taken - int filled = handlerOutput.receiveEnergy(drain, false); - //now actually drain that much from here - handlerHere.extractEnergy(filled, false); - if (filled > 0 && tileTarget instanceof TileCableEnergy) { - // not so compatible with other fluid systems. itl do i guess - TileCableEnergy cable = (TileCableEnergy) tileTarget; - cable.updateIncomingEnergyFace(themFacingMe); - } - return filled > 0; - } + final int capacity = handlerOutput.getMaxEnergyStored() - handlerOutput.getEnergyStored(); + if (capacity <= 0) { + return false; } - return false; + //validation is done + //next, simulate + final int drain = handlerHere.extractEnergy(Math.min(quantity, capacity), true); + if (drain <= 0) { + return false; + } + //now push it into output, but find out what was ACTUALLY taken + final int filled = handlerOutput.receiveEnergy(drain, false); + if (filled <= 0) { + return false; + } + //now actually drain that much from here + final int drained = handlerHere.extractEnergy(filled, false); + //sanity check + if (drained != filled) { + ModCyclic.LOGGER.error("Imbalance moving energy, extracted " + drained + " received " + filled); + } + if (tileTarget instanceof TileCableEnergy) { + // not so compatible with other fluid systems. it will do i guess + TileCableEnergy cable = (TileCableEnergy) tileTarget; + cable.updateIncomingEnergyFace(themFacingMe); + } + return true; } @Override @@ -457,10 +513,12 @@ public void setNeedsRedstone(int value) { this.needsRedstone = value % 2; } + @Override public FluidStack getFluid() { return FluidStack.EMPTY; } + @Override public void setFluid(FluidStack fluid) {} /************************** IInventory needed for IRecipe **********************************/ @@ -517,10 +575,12 @@ public String getFieldString(int field) { return null; } + @Override public int getEnergy() { return this.getCapability(ForgeCapabilities.ENERGY).map(IEnergyStorage::getEnergyStored).orElse(0); } + @Override public void setEnergy(int value) { IEnergyStorage energ = this.getCapability(ForgeCapabilities.ENERGY).orElse(null); if (energ != null && energ instanceof CustomEnergyStorage) { diff --git a/src/main/java/com/lothrazar/cyclic/block/antipotion/BlockAntiBeacon.java b/src/main/java/com/lothrazar/cyclic/block/antipotion/BlockAntiBeacon.java index be55e63d5..9d7c567be 100644 --- a/src/main/java/com/lothrazar/cyclic/block/antipotion/BlockAntiBeacon.java +++ b/src/main/java/com/lothrazar/cyclic/block/antipotion/BlockAntiBeacon.java @@ -1,5 +1,7 @@ package com.lothrazar.cyclic.block.antipotion; +import java.util.ArrayList; +import java.util.List; import com.lothrazar.cyclic.ModCyclic; import com.lothrazar.cyclic.block.BlockCyclic; import com.lothrazar.cyclic.capabilities.livingentity.LivingEntityCapProvider; @@ -27,9 +29,6 @@ import net.minecraftforge.eventbus.api.Event.Result; import net.minecraftforge.registries.ForgeRegistries; -import java.util.ArrayList; -import java.util.List; - public class BlockAntiBeacon extends BlockCyclic { private static final float[] COLOR = new float[] { 1, 1, 1 }; @@ -85,12 +84,10 @@ public static void markNearbyEntitiesWithAntiBeaconPosition(Level world, BlockPo if (livingEntityData == null) { continue; } - BlockPos oldPosition = livingEntityData.getClosestAntiBeaconPosition(); if (oldPosition != null && world.getBlockState(oldPosition).is(BlockRegistry.ANTI_BEACON.get())) { int oldDistance = e.blockPosition().distManhattan(oldPosition); int newDistance = e.blockPosition().distManhattan(pos); - if (newDistance < oldDistance) { livingEntityData.setClosestAntiBeaconPosition(pos); } @@ -128,38 +125,31 @@ public void isPotionApplicable(MobEffectEvent.Applicable event) { if (event.getEffectInstance() == null) { return; } - //this will cancel it LivingEntity livingEntity = event.getEntity(); if (BlockAntiBeacon.doesConfigBlockEffect(event.getEffectInstance().getEffect()) && - livingEntity.getCommandSenderWorld() instanceof ServerLevel serverLevel && - serverLevel.isLoaded(livingEntity.blockPosition())) { - + livingEntity.getCommandSenderWorld() instanceof ServerLevel serverLevel && + serverLevel.isLoaded(livingEntity.blockPosition())) { LivingEntityCapabilityStorage livingEntityData = livingEntity.getCapability(LivingEntityCapProvider.CYCLIC_LIVING_ENTITY).orElse(null); if (livingEntityData == null) { return; } - BlockPos closestAntiBeacon = livingEntityData.getClosestAntiBeaconPosition(); if (closestAntiBeacon == null) { return; } - if (livingEntity.blockPosition().distManhattan(closestAntiBeacon) > TileAntiBeacon.RADIUS.get()) { livingEntityData.setClosestAntiBeaconPosition(null); return; } - if (!serverLevel.getBlockState(closestAntiBeacon).getBlock().equals(this)) { livingEntityData.setClosestAntiBeaconPosition(null); return; } - final boolean isPowered = false; // if im NOT powered, im running if (serverLevel.hasNeighborSignal(closestAntiBeacon) != isPowered) { return; } - //can ModCyclic.LOGGER.info("[potion blocked] " + event.getEffectInstance()); event.setResult(Result.DENY); diff --git a/src/main/java/com/lothrazar/cyclic/block/apple/AppleCropBlock.java b/src/main/java/com/lothrazar/cyclic/block/apple/AppleCropBlock.java index 0c88ee89d..66b2bd83d 100644 --- a/src/main/java/com/lothrazar/cyclic/block/apple/AppleCropBlock.java +++ b/src/main/java/com/lothrazar/cyclic/block/apple/AppleCropBlock.java @@ -72,6 +72,7 @@ public void randomTick(BlockState state, ServerLevel worldIn, BlockPos pos, Rand int age = state.getValue(AGE); if (age < MAX_AGE && net.minecraftforge.common.ForgeHooks.onCropsGrowPre(worldIn, pos, state, worldIn.random.nextInt(5) == 0)) { worldIn.setBlock(pos, state.setValue(AGE, Integer.valueOf(age + 1)), 2); + // this.grow(worldIn, random, pos, state); ForgeHooks.onCropsGrowPost(worldIn, pos, state); } } diff --git a/src/main/java/com/lothrazar/cyclic/block/breaker/TileBreaker.java b/src/main/java/com/lothrazar/cyclic/block/breaker/TileBreaker.java index ec121fd39..c21fcd4c7 100644 --- a/src/main/java/com/lothrazar/cyclic/block/breaker/TileBreaker.java +++ b/src/main/java/com/lothrazar/cyclic/block/breaker/TileBreaker.java @@ -46,10 +46,9 @@ public void tick() { } BlockPos target = worldPosition.relative(this.getCurrentFacing()); if (this.isValid(target)) { - //old way would pass thru here and try to mine minecraft:water + //old way would pass thru here and try to mine minecraft:water this.level.destroyBlock(target, true); } - //else unbreakable } /** diff --git a/src/main/java/com/lothrazar/cyclic/block/cable/CableBase.java b/src/main/java/com/lothrazar/cyclic/block/cable/CableBase.java index fcf467b9b..79a07e708 100644 --- a/src/main/java/com/lothrazar/cyclic/block/cable/CableBase.java +++ b/src/main/java/com/lothrazar/cyclic/block/cable/CableBase.java @@ -161,26 +161,7 @@ public InteractionResult use(BlockState state, Level world, BlockPos pos, Player } public static void crouchClick(RightClickBlock event, BlockState state) { - // Direction sideToToggle = event.getFace(); // no rotateFromWrench(state, event.getLevel(), event.getPos(), event.getEntity(), event.getHitVec()); - // EnumProperty prop = CableBase.FACING_TO_PROPERTY_MAP.get(sideToToggle); - // if (state.hasProperty(prop)) { - // EnumConnectType status = state.getValue(prop); - // BlockState newState = state; - // switch (status) { - // case BLOCKED: - // newState = state.setValue(prop, EnumConnectType.NONE); - // break; - // case NONE: // no connection - // case INVENTORY: // inventory connection or - // case CABLE: // extract - // // extract to blocked - // newState = state.setValue(prop, EnumConnectType.BLOCKED); - // break; - // } - // event.getWorld().setBlock(event.getPos(), newState, 3); - // // newState.updateShape(sideToToggle, world.getBlockState(pos.relative(sideToToggle)), world, pos, pos.relative(sideToToggle)); - // } } private static void rotateFromWrench(BlockState state, Level world, BlockPos pos, Player player, BlockHitResult hit) { @@ -228,7 +209,7 @@ else if (hitZ > 1 - hitLimit) { break; } } - else { + else { // non-crouching flow switch (status) { case BLOCKED: newState = state.setValue(prop, EnumConnectType.NONE); @@ -247,7 +228,6 @@ else if (hitZ > 1 - hitLimit) { } } // - // if (world.getBlockState(pos).getBlock() instanceof CableBase && world.setBlockAndUpdate(pos, newState)) { if (updatePost) { newState.updateShape(sideToToggle, world.getBlockState(pos.relative(sideToToggle)), world, pos, pos.relative(sideToToggle)); @@ -275,10 +255,4 @@ public static boolean isCableBlocked(BlockState blockState, Direction side) { && blockState.hasProperty(property) && blockState.getValue(property).isUnBlocked() == false; } - // protected void updateConnection(final IWorld world, final BlockPos blockPos, final Direction side, final EnumConnectType connectType) { - // final TileEntity tileEntity = world.getTileEntity(blockPos); - // if (tileEntity instanceof TileCableBase) { - // ((TileCableBase) tileEntity).updateConnection(side, connectType); - // } - // } } diff --git a/src/main/java/com/lothrazar/cyclic/block/cable/item/ContainerCableItem.java b/src/main/java/com/lothrazar/cyclic/block/cable/item/ContainerCableItem.java index bc968f59c..c68b26f7d 100644 --- a/src/main/java/com/lothrazar/cyclic/block/cable/item/ContainerCableItem.java +++ b/src/main/java/com/lothrazar/cyclic/block/cable/item/ContainerCableItem.java @@ -19,9 +19,8 @@ public ContainerCableItem(int windowId, Level world, BlockPos pos, Inventory pla tile = (TileCableItem) world.getBlockEntity(pos); this.playerEntity = player; this.playerInventory = playerInventory; - // tile.getCapability(ForgeCapabilities.ITEM_HANDLER).ifPresent(h -> { this.endInv = tile.filter.getSlots(); - //dont show 0 thats the actual thing in the slot + //dont show 0 thats the actual thing in the slot addSlot(new SlotItemHandler(tile.filter, 0, 80, 29) { @Override @@ -29,7 +28,7 @@ public void setChanged() { tile.setChanged(); } }); - // }); + addSlot(new SlotItemHandler(tile.filter, 0, 80, 29)); layoutPlayerInventorySlots(8, 84); this.trackEnergy(tile); } diff --git a/src/main/java/com/lothrazar/cyclic/block/cable/item/ScreenCableItem.java b/src/main/java/com/lothrazar/cyclic/block/cable/item/ScreenCableItem.java index 09fed9fee..1ebe865f7 100644 --- a/src/main/java/com/lothrazar/cyclic/block/cable/item/ScreenCableItem.java +++ b/src/main/java/com/lothrazar/cyclic/block/cable/item/ScreenCableItem.java @@ -10,39 +10,11 @@ public class ScreenCableItem extends ScreenBase { public ScreenCableItem(ContainerCableItem screenContainer, Inventory inv, Component titleIn) { super(screenContainer, inv, titleIn); - // fluid = new FluidBar(this, TileFluidCollect.CAPACITY); - // energy = new EnergyBar(this, TileFluidCollect.MAX); } @Override public void init() { super.init(); - // energy.guiLeft = fluid.guiLeft = guiLeft; - // energy.guiTop = fluid.guiTop = guiTop; - // energy.visible = TileFluidCollect.POWERCONF.get() > 0; - // int x, y; - // x = guiLeft + 8; - // y = guiTop + 8; - // btnRedstone = addButton(new ButtonMachineRedstone(x, y, TileFluidCollect.Fields.REDSTONE.ordinal(), container.tile.getPos())); - // btnRender = addButton(new ButtonMachineRedstone(x, y + 20, TileFluidCollect.Fields.RENDER.ordinal(), - // container.tile.getPos(), TextureEnum.RENDER_HIDE, TextureEnum.RENDER_SHOW, "gui.cyclic.render")); - // // - // // - // int w = 96; - // int h = 20; - // x = guiLeft + 32; - // y += h + 1; - // int f = TileFluidCollect.Fields.HEIGHT.ordinal(); - // GuiSliderInteger height = this.addButton(new GuiSliderInteger(x, y, w, h, f, container.tile.getPos(), - // 0, TileFluidCollect.MAX_HEIGHT, container.tile.getField(f))); - // height.setTooltip("buildertype.height.tooltip"); - // y += h + 1; - // // - // // - // f = TileFluidCollect.Fields.SIZE.ordinal(); - // GuiSliderInteger size = this.addButton(new GuiSliderInteger(x, y, w, h, f, container.tile.getPos(), - // 0, TileMiner.MAX_SIZE, container.tile.getField(f))); - // size.setTooltip("buildertype.size.tooltip"); } @Override diff --git a/src/main/java/com/lothrazar/cyclic/block/soundmuff/SoundmufflerBlock.java b/src/main/java/com/lothrazar/cyclic/block/soundmuff/SoundmufflerBlock.java index 8571d3845..01710a693 100644 --- a/src/main/java/com/lothrazar/cyclic/block/soundmuff/SoundmufflerBlock.java +++ b/src/main/java/com/lothrazar/cyclic/block/soundmuff/SoundmufflerBlock.java @@ -3,24 +3,22 @@ import java.util.List; import com.lothrazar.cyclic.ModCyclic; import com.lothrazar.cyclic.block.BlockCyclic; +import com.lothrazar.cyclic.config.ConfigRegistry; import com.lothrazar.library.util.BlockstatesUtil; import net.minecraft.client.Minecraft; import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.resources.sounds.SoundInstance; -import net.minecraft.client.resources.sounds.TickableSoundInstance; import net.minecraft.core.BlockPos; import net.minecraft.world.level.block.SoundType; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.client.event.sound.PlaySoundEvent; -import net.minecraftforge.common.ForgeConfigSpec.IntValue; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.eventbus.api.SubscribeEvent; public class SoundmufflerBlock extends BlockCyclic { private static final int VOL_REDUCE_PER_BLOCK = 2; - public static IntValue RADIUS; // 6 public SoundmufflerBlock(Properties properties) { super(properties.strength(1F).sound(SoundType.SCAFFOLDING)); @@ -31,31 +29,33 @@ public SoundmufflerBlock(Properties properties) { @SubscribeEvent public void onPlaySound(PlaySoundEvent event) { ClientLevel clientWorld = Minecraft.getInstance().level; - if (event.getSound() == null || event.getSound() instanceof TickableSoundInstance || clientWorld == null) { + if (event.getSound() == null || clientWorld == null) { return; - } //long term/repeating/music + } SoundInstance sound = event.getSound(); - // if (tile.isPowered()) { - // return; // redstone power = not running - // } final boolean isPowered = false; // if im NOT powered, im running List blocks = BlockstatesUtil.findBlocks(clientWorld, new BlockPos((int) sound.getX(), (int) sound.getY(), (int) sound.getZ()), this, - RADIUS.get(), + ConfigRegistry.SOUND_RADIUS.get(), isPowered); if (blocks == null || blocks.size() == 0) { return; } + float reduce = VOL_REDUCE_PER_BLOCK; + float radius = ConfigRegistry.SOUND_RADIUS.get(); + //the number of nearby blocks informs how much we muffle the sound by + //at 6 blocks, it caps off the reduction + float volume = (float) (Math.min(reduce / radius, 1.0) / blocks.size()); + rebuildSoundWithVolume(event, sound, volume); + } + + @OnlyIn(Dist.CLIENT) + private static void rebuildSoundWithVolume(PlaySoundEvent event, SoundInstance sound, float newVolume) { try { //WARNING": DO NOT USE getVolume anywhere here it just crashes - //we do use it inside the sound class, but the engine callss tat later on, and our factor is tacked in + //we do use it inside the sound class, but the engine calls that later on, and our factor is tacked in SoundVolumeControlled newSound = new SoundVolumeControlled(sound); - //the number of nearby blocks informs how much we muffle the sound by - final float pct = VOL_REDUCE_PER_BLOCK / 6F; - //at 6 blocks, it caps off the reduction - final float newVolume = (float) (Math.min(pct, 1.0) / blocks.size()); newSound.setVolume(newVolume); event.setSound(newSound); - ModCyclic.LOGGER.info("sound muffled; size= " + blocks.size()); } catch (Exception e) { ModCyclic.LOGGER.error("Error trying to detect volume of sound " + sound, e); diff --git a/src/main/java/com/lothrazar/cyclic/block/soundrecord/BlockSoundRecorder.java b/src/main/java/com/lothrazar/cyclic/block/soundrecord/BlockSoundRecorder.java index fb4f1fe05..7e9598568 100644 --- a/src/main/java/com/lothrazar/cyclic/block/soundrecord/BlockSoundRecorder.java +++ b/src/main/java/com/lothrazar/cyclic/block/soundrecord/BlockSoundRecorder.java @@ -2,6 +2,7 @@ import java.util.List; import com.lothrazar.cyclic.block.BlockCyclic; +import com.lothrazar.cyclic.config.ConfigRegistry; import com.lothrazar.cyclic.net.PacketRecordSound; import com.lothrazar.cyclic.registry.MenuTypeRegistry; import com.lothrazar.cyclic.registry.PacketRegistry; @@ -17,14 +18,11 @@ import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.client.event.sound.PlaySoundEvent; -import net.minecraftforge.common.ForgeConfigSpec.IntValue; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.eventbus.api.SubscribeEvent; public class BlockSoundRecorder extends BlockCyclic { - public static IntValue RADIUS; - public BlockSoundRecorder(Properties properties) { super(properties.strength(1F).sound(SoundType.SCAFFOLDING)); MinecraftForge.EVENT_BUS.register(this); @@ -50,8 +48,8 @@ public void onPlaySound(PlaySoundEvent event) { } //long term/repeating/music final boolean isPowered = false; // if im NOT powered, im running List blocks = BlockstatesUtil.findBlocks(clientWorld, - new BlockPos((int) event.getSound().getX(), (int) event.getSound().getY(), (int) event.getSound().getZ()), - this, RADIUS.get(), isPowered); + new BlockPos((int) event.getSound().getX(), (int) event.getSound().getY(), (int) event.getSound().getZ()), this, + ConfigRegistry.RECORDER_RADIUS.get(), isPowered); for (BlockPos nearby : blocks) { String sid = event.getSound().getLocation().toString(); PacketRegistry.INSTANCE.sendToServer(new PacketRecordSound(sid, nearby)); diff --git a/src/main/java/com/lothrazar/cyclic/block/spikes/TileDiamondSpikes.java b/src/main/java/com/lothrazar/cyclic/block/spikes/TileDiamondSpikes.java index e1b4a8374..fb58ee974 100644 --- a/src/main/java/com/lothrazar/cyclic/block/spikes/TileDiamondSpikes.java +++ b/src/main/java/com/lothrazar/cyclic/block/spikes/TileDiamondSpikes.java @@ -22,6 +22,7 @@ public class TileDiamondSpikes extends TileBlockEntityCyclic { WeakReference fakePlayer; + final static boolean dropItemsOnGround = true; public TileDiamondSpikes(BlockPos pos, BlockState state) { super(TileRegistry.SPIKES_DIAMOND.get(), pos, state); @@ -63,7 +64,7 @@ public void tick() { fakePlayer.get().setItemInHand(InteractionHand.MAIN_HAND, sword); } if (level.random.nextDouble() < 0.001F) { - tryDumpFakePlayerInvo(fakePlayer, null, true); + tryDumpFakePlayerInvo(fakePlayer, null, dropItemsOnGround); } } } diff --git a/src/main/java/com/lothrazar/cyclic/block/sprinkler/TileSprinkler.java b/src/main/java/com/lothrazar/cyclic/block/sprinkler/TileSprinkler.java index 2964f30b1..e76bd180c 100644 --- a/src/main/java/com/lothrazar/cyclic/block/sprinkler/TileSprinkler.java +++ b/src/main/java/com/lothrazar/cyclic/block/sprinkler/TileSprinkler.java @@ -2,16 +2,17 @@ import java.util.List; import com.lothrazar.cyclic.block.TileBlockEntityCyclic; -import com.lothrazar.cyclic.block.terrasoil.TileTerraPreta; import com.lothrazar.cyclic.capabilities.block.FluidTankBase; import com.lothrazar.cyclic.registry.TileRegistry; import com.lothrazar.cyclic.util.FluidHelpers; +import com.lothrazar.cyclic.util.GrowthUtil; import com.lothrazar.library.util.ParticleUtil; import com.lothrazar.library.util.ShapeUtil; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.core.particles.ParticleTypes; import net.minecraft.nbt.CompoundTag; +import net.minecraft.server.level.ServerLevel; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.entity.BlockEntity; @@ -63,14 +64,16 @@ public void tick() { if (shapeIndex >= shape.size()) { shapeIndex = 0; } - if (level.isClientSide && TileTerraPreta.isValidGrow(level, shape.get(shapeIndex))) { + if (level.isClientSide && GrowthUtil.isValidGrow(level, shape.get(shapeIndex))) { ParticleUtil.spawnParticle(level, ParticleTypes.FALLING_WATER, shape.get(shapeIndex), 9); } - if (TileTerraPreta.grow(level, shape.get(shapeIndex), 1)) { - //it worked, so double drain - tank.drain(WATERCOST.get(), FluidAction.EXECUTE); - //run it again since sprinkler costs fluid and therefore should double what the glass and soil do - TileTerraPreta.grow(level, shape.get(shapeIndex), 1); + if (level instanceof ServerLevel sl) { + if (GrowthUtil.tryGrow(sl, shape.get(shapeIndex), 1)) { + //it worked so pay + tank.drain(WATERCOST.get(), FluidAction.EXECUTE); + //run it again since sprinkler costs fluid and therefore should double what the glass and soil do + GrowthUtil.tryGrow(sl, shape.get(shapeIndex), 1); + } } } diff --git a/src/main/java/com/lothrazar/cyclic/block/terraglass/BlockTerraGlass.java b/src/main/java/com/lothrazar/cyclic/block/terraglass/BlockTerraGlass.java index 7e43044be..efc7b886d 100644 --- a/src/main/java/com/lothrazar/cyclic/block/terraglass/BlockTerraGlass.java +++ b/src/main/java/com/lothrazar/cyclic/block/terraglass/BlockTerraGlass.java @@ -67,7 +67,7 @@ public BlockEntity newBlockEntity(BlockPos pos, BlockState state) { @Override public BlockEntityTicker getTicker(Level world, BlockState state, BlockEntityType type) { - return createTickerHelper(type, TileRegistry.TERRAGLASS.get(), world.isClientSide ? TileTerraGlass::clientTick : TileTerraGlass::serverTick); + return createTickerHelper(type, TileRegistry.TERRA_GLASS.get(), world.isClientSide ? TileTerraGlass::clientTick : TileTerraGlass::serverTick); } @Override diff --git a/src/main/java/com/lothrazar/cyclic/block/terraglass/TileTerraGlass.java b/src/main/java/com/lothrazar/cyclic/block/terraglass/TileTerraGlass.java index 8a890cce2..de7b163e3 100644 --- a/src/main/java/com/lothrazar/cyclic/block/terraglass/TileTerraGlass.java +++ b/src/main/java/com/lothrazar/cyclic/block/terraglass/TileTerraGlass.java @@ -2,20 +2,22 @@ import com.lothrazar.cyclic.block.BlockCyclic; import com.lothrazar.cyclic.block.TileBlockEntityCyclic; -import com.lothrazar.cyclic.block.terrasoil.TileTerraPreta; import com.lothrazar.cyclic.registry.TileRegistry; +import com.lothrazar.cyclic.util.GrowthUtil; import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; +import net.minecraftforge.common.ForgeConfigSpec.IntValue; public class TileTerraGlass extends TileBlockEntityCyclic { - private static final int TIMER_FULL = TileTerraPreta.TIMER_FULL.get() / 2; - private static final int DISTANCE = TileTerraPreta.HEIGHT / 2; + public static IntValue TIMER_FULL; + public static IntValue HEIGHT; public TileTerraGlass(BlockPos pos, BlockState state) { - super(TileRegistry.TERRAGLASS.get(), pos, state); + super(TileRegistry.TERRA_GLASS.get(), pos, state); } public static void serverTick(Level level, BlockPos blockPos, BlockState blockState, TileTerraGlass e) { @@ -35,7 +37,7 @@ public void tick() { if (timer > 0) { return; } - timer = TIMER_FULL; + timer = TIMER_FULL.get(); boolean lit = this.getBlockState().getValue(BlockCyclic.LIT); boolean newLit = canBlockSeeSky(level, worldPosition); if (lit != newLit) { @@ -45,9 +47,11 @@ public void tick() { if (!newLit) { return; } - for (int h = 0; h < DISTANCE; h++) { - BlockPos current = worldPosition.below(h); - TileTerraPreta.grow(level, current, 0.25); + if (level instanceof ServerLevel sl) { + for (int h = 0; h < HEIGHT.get(); h++) { + BlockPos current = worldPosition.below(h); + GrowthUtil.tryGrow(sl, current, 0.25); + } } } @@ -56,8 +60,6 @@ private boolean canBlockSeeSky(Level world, BlockPos pos) { if (world.canSeeSky(pos)) { return true; } - // world.isOutsideBuildHeight(pos) - // else { for (BlockPos blockpos1 = pos.above(); blockpos1.getY() < 256; blockpos1 = blockpos1.above()) { if (level.isOutsideBuildHeight(blockpos1.getY())) { continue; @@ -69,7 +71,6 @@ private boolean canBlockSeeSky(Level world, BlockPos pos) { } } return true; - // } } @Override diff --git a/src/main/java/com/lothrazar/cyclic/block/terrasoil/TileTerraPreta.java b/src/main/java/com/lothrazar/cyclic/block/terrasoil/TileTerraPreta.java index 7084d2cc8..3bc097478 100644 --- a/src/main/java/com/lothrazar/cyclic/block/terrasoil/TileTerraPreta.java +++ b/src/main/java/com/lothrazar/cyclic/block/terrasoil/TileTerraPreta.java @@ -16,8 +16,9 @@ public class TileTerraPreta extends TileBlockEntityCyclic { public static IntValue TIMER_FULL; - public static final int HEIGHT = 16; + public static IntValue HEIGHT; public static DoubleValue CHANCE; + // public static final double ODDS_DEFAULT = 0.5; public TileTerraPreta(BlockPos pos, BlockState state) { super(TileRegistry.TERRA_PRETA.get(), pos, state); @@ -38,7 +39,7 @@ public void tick() { return; } timer = TIMER_FULL.get(); - for (int h = 0; h < HEIGHT; h++) { + for (int h = 0; h < HEIGHT.get(); h++) { BlockPos current = this.getBlockPos().above(h); grow(level, current, CHANCE.get()); } diff --git a/src/main/java/com/lothrazar/cyclic/block/uncrafter/ScreenUncraft.java b/src/main/java/com/lothrazar/cyclic/block/uncrafter/ScreenUncraft.java index 17a5e8ab8..5a3ba6ce9 100644 --- a/src/main/java/com/lothrazar/cyclic/block/uncrafter/ScreenUncraft.java +++ b/src/main/java/com/lothrazar/cyclic/block/uncrafter/ScreenUncraft.java @@ -55,24 +55,6 @@ protected void renderLabels(GuiGraphics ms, int mouseX, int mouseY) { ModCyclic.MODID + ".gui.uncrafter." + menu.tile.getStatus().name().toLowerCase()); int center = (this.getXSize() - this.font.width(name)) / 2; drawString(ms, name, center + 37, 24); - //======= - // UncraftStatusEnum status = container.tile.getStatus(); - // if (status != UncraftStatusEnum.EMPTY && status != UncraftStatusEnum.MATCH) { - // minecraft.getTextureManager().bindTexture(TextureRegistry.WIDGETS); - // blit(ms, 125, 15, 228, 452, 24, 24, 512, 512); - // } - // } - // - // @Override - // protected void renderHoveredTooltip(MatrixStack matrixStack, int x, int y) { - // super.renderHoveredTooltip(matrixStack, x, y); - // if (this.isPointInRegion(125, 15, 24, 24, x, y)) { - // UncraftStatusEnum status = container.tile.getStatus(); - // if (status != UncraftStatusEnum.EMPTY && status != UncraftStatusEnum.MATCH) { - // TranslationTextComponent comp = new TranslationTextComponent(ModCyclic.MODID + ".gui.uncrafter." + container.tile.getStatus().name().toLowerCase()); - // GuiUtils.drawHoveringText(matrixStack, Arrays.asList(comp), x, y, this.width, this.height, 0xFFFFFF, font); - // } - //>>>>>>> 54f4445a2d7902cf4ef454efe328c9667ca5b652 } } diff --git a/src/main/java/com/lothrazar/cyclic/block/user/TileUser.java b/src/main/java/com/lothrazar/cyclic/block/user/TileUser.java index e911e7909..828ab8942 100644 --- a/src/main/java/com/lothrazar/cyclic/block/user/TileUser.java +++ b/src/main/java/com/lothrazar/cyclic/block/user/TileUser.java @@ -128,17 +128,16 @@ public void tick() { catch (Exception e) { ModCyclic.LOGGER.error("User action item error", e); } - tryDumpFakePlayerInvo(fakePlayer, this.outputSlots, false); + final boolean dropItemsOnGround = false; + tryDumpFakePlayerInvo(fakePlayer, this.outputSlots, dropItemsOnGround); } private void depositOutputMainhand() { var usedItem = fakePlayer.get().getItemInHand(InteractionHand.MAIN_HAND); for (int slotId = 0; slotId < outputSlots.getSlots(); slotId++) { if (!usedItem.isEmpty()) { - // usedItem = outputSlots.insertItem(slotId, usedItem.copy(), false); if (outputSlots.insertItem(slotId, usedItem.copy(), true).isEmpty()) { usedItem = outputSlots.insertItem(slotId, usedItem.copy(), false); - // userSlots.setStackInSlot(0, usedItem); TileBlockEntityCyclic.tryEquipItem(usedItem, fakePlayer, InteractionHand.MAIN_HAND); } } diff --git a/src/main/java/com/lothrazar/cyclic/block/wireless/energy/TileWirelessEnergy.java b/src/main/java/com/lothrazar/cyclic/block/wireless/energy/TileWirelessEnergy.java index 761581daf..881dbd435 100644 --- a/src/main/java/com/lothrazar/cyclic/block/wireless/energy/TileWirelessEnergy.java +++ b/src/main/java/com/lothrazar/cyclic/block/wireless/energy/TileWirelessEnergy.java @@ -3,6 +3,7 @@ import java.util.HashSet; import java.util.Set; import com.lothrazar.cyclic.block.TileBlockEntityCyclic; +import com.lothrazar.cyclic.config.ConfigRegistry; import com.lothrazar.cyclic.data.PreviewOutlineType; import com.lothrazar.cyclic.item.datacard.LocationGpsCard; import com.lothrazar.cyclic.registry.BlockRegistry; @@ -115,17 +116,19 @@ public void tick() { Set used = new HashSet<>(); for (int slot = 0; slot < gpsSlots.getSlots(); slot++) { BlockPosDim loc = getTargetInSlot(slot); - if (used.contains(loc)) { + if (loc == null || used.contains(loc)) { continue; } - if (loc != null && LevelWorldUtil.dimensionIsEqual(loc, level)) { - if (moveEnergy(loc.getSide(), loc.getPos(), transferRate)) { - used.add(loc); - moved = true; - } + if (LevelWorldUtil.dimensionIsEqual(loc, level)) { + // assume position is in the same level/dimension/world + moved = moveEnergy(loc.getSide(), loc.getPos(), transferRate); } + else if (ConfigRegistry.TRANSFER_NODES_DIMENSIONAL.get()) { + //allows config to disable this cross dimension feature for modpack balance purposes + moved = moveEnergyDimensional(loc, transferRate); + } + this.setLitProperty(moved); } - this.setLitProperty(moved); } BlockPosDim getTargetInSlot(int s) { diff --git a/src/main/java/com/lothrazar/cyclic/block/wireless/fluid/TileWirelessFluid.java b/src/main/java/com/lothrazar/cyclic/block/wireless/fluid/TileWirelessFluid.java index a0c3eebe3..f590d1617 100644 --- a/src/main/java/com/lothrazar/cyclic/block/wireless/fluid/TileWirelessFluid.java +++ b/src/main/java/com/lothrazar/cyclic/block/wireless/fluid/TileWirelessFluid.java @@ -2,6 +2,7 @@ import com.lothrazar.cyclic.block.TileBlockEntityCyclic; import com.lothrazar.cyclic.capabilities.block.FluidTankBase; +import com.lothrazar.cyclic.config.ConfigRegistry; import com.lothrazar.cyclic.data.PreviewOutlineType; import com.lothrazar.cyclic.item.datacard.LocationGpsCard; import com.lothrazar.cyclic.registry.BlockRegistry; @@ -130,8 +131,13 @@ public void tick() { boolean moved = false; //run the transfer. one slot only BlockPosDim loc = getTargetInSlot(0); - if (loc != null && LevelWorldUtil.dimensionIsEqual(loc, level)) { - this.moveFluids(loc.getSide(), loc.getPos(), this.transferRate, tank); + if (loc != null) { + if (LevelWorldUtil.dimensionIsEqual(loc, level)) { + this.moveFluids(loc.getSide(), loc.getPos(), this.transferRate, tank); + } + else if (ConfigRegistry.TRANSFER_NODES_DIMENSIONAL.get()) { + this.moveFluidsDimensional(loc, this.transferRate, tank); + } } this.setLitProperty(moved); } diff --git a/src/main/java/com/lothrazar/cyclic/block/wireless/item/TileWirelessItem.java b/src/main/java/com/lothrazar/cyclic/block/wireless/item/TileWirelessItem.java index 6442074c2..5feb94d07 100644 --- a/src/main/java/com/lothrazar/cyclic/block/wireless/item/TileWirelessItem.java +++ b/src/main/java/com/lothrazar/cyclic/block/wireless/item/TileWirelessItem.java @@ -1,6 +1,7 @@ package com.lothrazar.cyclic.block.wireless.item; import com.lothrazar.cyclic.block.TileBlockEntityCyclic; +import com.lothrazar.cyclic.config.ConfigRegistry; import com.lothrazar.cyclic.data.PreviewOutlineType; import com.lothrazar.cyclic.item.datacard.LocationGpsCard; import com.lothrazar.cyclic.registry.BlockRegistry; @@ -114,8 +115,13 @@ public void tick() { boolean moved = false; //run the transfer. one slot only BlockPosDim loc = getTargetInSlot(); - if (loc != null && LevelWorldUtil.dimensionIsEqual(loc, level)) { - moved = moveItems(Direction.UP, loc.getPos(), this.transferRate, this.inventory, 0); + if (loc != null) { + if (LevelWorldUtil.dimensionIsEqual(loc, level)) { + moved = moveItems(loc.getSide(), loc.getPos(), this.transferRate, this.inventory, 0); + } + else if (ConfigRegistry.TRANSFER_NODES_DIMENSIONAL.get()) { + moved = moveItemsDimensional(loc, this.transferRate, this.inventory, 0); + } } this.setLitProperty(moved); } diff --git a/src/main/java/com/lothrazar/cyclic/block/wireless/redstone/TileWirelessTransmit.java b/src/main/java/com/lothrazar/cyclic/block/wireless/redstone/TileWirelessTransmit.java index 893b96262..9fc943098 100644 --- a/src/main/java/com/lothrazar/cyclic/block/wireless/redstone/TileWirelessTransmit.java +++ b/src/main/java/com/lothrazar/cyclic/block/wireless/redstone/TileWirelessTransmit.java @@ -97,14 +97,17 @@ private void toggleTarget(BlockPosDim dimPos) { if (serverLevel.getBlockEntity(targetPos) instanceof TileWirelessRec receiver) { //am I powered? if (isPowered) { + ModCyclic.LOGGER.info(" POWER UP target" + dimPos); receiver.putPowerSender(this.id); } else { + ModCyclic.LOGGER.info(" turn off target" + dimPos); receiver.removePowerSender(this.id); } } if (level.isLoaded(worldPosition) && level.getBlockState(worldPosition).getBlock() == this.getBlockState().getBlock()) { level.setBlockAndUpdate(worldPosition, level.getBlockState(worldPosition).setValue(BlockStateProperties.POWERED, isPowered)); + // world.setBlockState(pos, world.getBlockState(pos).with(BlockStateProperties.POWERED, isPowered)); } } diff --git a/src/main/java/com/lothrazar/cyclic/capabilities/livingentity/LivingEntityCapProvider.java b/src/main/java/com/lothrazar/cyclic/capabilities/livingentity/LivingEntityCapProvider.java index 0c8f91c39..f4b8b1a2b 100644 --- a/src/main/java/com/lothrazar/cyclic/capabilities/livingentity/LivingEntityCapProvider.java +++ b/src/main/java/com/lothrazar/cyclic/capabilities/livingentity/LivingEntityCapProvider.java @@ -1,5 +1,7 @@ package com.lothrazar.cyclic.capabilities.livingentity; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; import net.minecraft.core.Direction; import net.minecraft.nbt.CompoundTag; import net.minecraftforge.common.capabilities.Capability; @@ -9,9 +11,6 @@ import net.minecraftforge.common.util.INBTSerializable; import net.minecraftforge.common.util.LazyOptional; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - public class LivingEntityCapProvider implements ICapabilityProvider, INBTSerializable { public static Capability CYCLIC_LIVING_ENTITY = CapabilityManager.get(new CapabilityToken<>() {}); diff --git a/src/main/java/com/lothrazar/cyclic/compat/CompatConstants.java b/src/main/java/com/lothrazar/cyclic/compat/CompatConstants.java index d2ff8fdde..34cf39f7f 100644 --- a/src/main/java/com/lothrazar/cyclic/compat/CompatConstants.java +++ b/src/main/java/com/lothrazar/cyclic/compat/CompatConstants.java @@ -6,4 +6,6 @@ public class CompatConstants { public static final String CRAFTTWEAKER = "crafttweaker"; public static final String CURIOS = "curios"; public static final String TCONSTRUCT = "tconstruct"; + public static final String RS_MODID = "repurposed_structures"; + public static final String YUSTRONG_MODID = "betterstrongholds"; } diff --git a/src/main/java/com/lothrazar/cyclic/compat/botania/BotaniaWrapper.java b/src/main/java/com/lothrazar/cyclic/compat/botania/BotaniaWrapper.java index ab2ed11cd..c1847140e 100644 --- a/src/main/java/com/lothrazar/cyclic/compat/botania/BotaniaWrapper.java +++ b/src/main/java/com/lothrazar/cyclic/compat/botania/BotaniaWrapper.java @@ -1,18 +1,23 @@ package com.lothrazar.cyclic.compat.botania; import net.minecraft.world.entity.LivingEntity; -//import vazkii.botania.api.BotaniaAPI; +import net.minecraftforge.fml.ModList; public class BotaniaWrapper { + /** + * If the botania mod is loaded, use the botania-api to check for hasSolegnoliaAround(entity); otherwise return false + * + * @param entity + * @return true if botania has found a solegnolia around the entity + */ public static boolean hasSolegnoliaAround(LivingEntity entity) { try { - // return ModList.get().isLoaded("botania") && BotaniaAPI.instance().hasSolegnoliaAround(entity); + if (ModList.get().isLoaded("botania")) { + // return vazkii.botania.api.BotaniaAPI.instance().hasSolegnoliaAround(entity); // 1.19.4 only doesnt have a port + } } - catch (Exception e) { - //ive never seen an exception here yet, just being safe - } - //either botania does not exist or an error was thrown + catch (Exception e) {} return false; } } diff --git a/src/main/java/com/lothrazar/cyclic/config/ConfigRegistry.java b/src/main/java/com/lothrazar/cyclic/config/ConfigRegistry.java index 35a63ca88..42be0c1ad 100644 --- a/src/main/java/com/lothrazar/cyclic/config/ConfigRegistry.java +++ b/src/main/java/com/lothrazar/cyclic/config/ConfigRegistry.java @@ -39,11 +39,10 @@ import com.lothrazar.cyclic.block.packager.TilePackager; import com.lothrazar.cyclic.block.peatfarm.TilePeatFarm; import com.lothrazar.cyclic.block.shapebuilder.TileStructure; -import com.lothrazar.cyclic.block.soundmuff.SoundmufflerBlock; -import com.lothrazar.cyclic.block.soundrecord.BlockSoundRecorder; import com.lothrazar.cyclic.block.spawntriggers.BlockAltarNoTraders; import com.lothrazar.cyclic.block.spawntriggers.CandlePeaceBlock; import com.lothrazar.cyclic.block.sprinkler.TileSprinkler; +import com.lothrazar.cyclic.block.terraglass.TileTerraGlass; import com.lothrazar.cyclic.block.terrasoil.TileTerraPreta; import com.lothrazar.cyclic.block.tp.BlockTeleport; import com.lothrazar.cyclic.block.uncrafter.TileUncraft; @@ -126,6 +125,7 @@ public void setupClient() { private static ConfigValue> BEHEADING_SKINS; private static ConfigValue> MBALL_IGNORE_LIST; private static ConfigValue> DISARM_IGNORE_LIST; + public static ConfigValue> GLOOM_IGNORE_LIST; private static final String WALL = "####################################################################################"; public static IntValue CHARM_LUCK; public static DoubleValue CHARM_SPEED; @@ -133,6 +133,9 @@ public void setupClient() { public static BooleanValue OVERRIDE_TRANSPORTER_SINGLETON; public static BooleanValue GENERATE_FLOWERS; public static BooleanValue CYAN_PODZOL_LEGACY; + public static BooleanValue TRANSFER_NODES_DIMENSIONAL; + public static IntValue SOUND_RADIUS; + public static IntValue RECORDER_RADIUS; static { buildDefaults(); initConfig(); @@ -268,8 +271,11 @@ private static void initConfig() { AutoSmeltEnchant.CFG = CFG.comment("Set false to stop enchantment from working").define(AutoSmeltEnchant.ID + ".enabled", true); BeekeeperEnchant.CFG = CFG.comment("Set false to stop enchantment from working").define(BeekeeperEnchant.ID + ".enabled", true); BeheadingEnchant.CFG = CFG.comment("Set false to stop enchantment from working").define(BeheadingEnchant.ID + ".enabled", true); - BEHEADING_SKINS = CFG.comment("Beheading enchant add player skin head drop, add any mob id and any skin").defineList(BeheadingEnchant.ID + ".EntityMHF", BEHEADING, - it -> it instanceof String); + GLOOM_IGNORE_LIST = CFG.comment("Set list of effects for Gloom enchant (cyclic:curse) to ignore and not use these") + .defineList(GloomCurseEnchant.ID + ".ignored", Arrays.asList("minecraft:bad_omen", "minecraft:nausea", "botania:clear"), + it -> it instanceof String); + BEHEADING_SKINS = CFG.comment("Beheading enchant add player skin head drop, add any mob id and any skin") + .defineList(BeheadingEnchant.ID + ".EntityMHF", BEHEADING, it -> it instanceof String); BeheadingEnchant.PERCDROP = CFG.comment("Base perecentage chance to drop a head on kill").defineInRange(BeheadingEnchant.ID + ".percent", 20, 1, 99); BeheadingEnchant.PERCPERLEVEL = CFG.comment("Percentage increase per level of enchant. Formula [percent + (level - 1) * per_level] ").defineInRange(BeheadingEnchant.ID + ".per_level", 25, 1, 99); GloomCurseEnchant.CFG = CFG.comment("(Gloom) Set false to stop enchantment from working").define(GloomCurseEnchant.ID + ".enabled", true); @@ -318,7 +324,7 @@ private static void initConfig() { CFG.comment(WALL, " Logging related configs", WALL) .push("logging"); CyclicLogger.LOGINFO = CFG.comment("Unblock info logs; very spammy; can be useful for testing certain issues").define("info", false); - CFG.pop(); //logging + CFG.pop(); //logging CFG.comment(WALL, " Item specific configs", WALL).push("items"); // CFG.comment(WALL, " scythe_brush settings. note radius is halved while player is sneaking", WALL).push("scythe_brush"); @@ -404,11 +410,13 @@ private static void initConfig() { HeartToxicItem.HEARTXPMINUS = CFG.comment("Experience given when eating a poisoned heart").defineInRange("experience", 500, 0, 99999); HeartItem.MAX = CFG.comment("Maximum number of hearts that can be attained (including initial 10)").defineInRange("maximum", 100, 1, 200); CFG.pop(); //heart - CFG.pop(); //items + CFG.pop(); //items CFG.comment(WALL, " Block specific configs", WALL).push("blocks"); //////////////////////////////////////////////////////////////////////////////////// blocks - //buffer size for cables - SoundmufflerBlock.RADIUS = CFG.comment("Radius to find and muffle sounds. ") - .defineInRange("soundproofing.radius", 6, 1, 128); + TRANSFER_NODES_DIMENSIONAL = CFG.comment(" Allows the dimensional Transfer Nodes to cross dimensions " + + "(no chunk loading is done, you have to do that on your own); " + + "This affects blocks cyclic:wireless_energy, cyclic:wireless_item, cyclic:wireless_fluid, cyclic:wireless_transmitter; " + + "If you change it to false it will only work if the target is in the same dimension.") + .define("wireless_transfer_dimensional", true); TileAntiBeacon.HARMFUL_POTIONS = CFG.comment("If true, then all potions marked as harmful/negative will be used in addition to the 'anti_beacon.potion_list' for cures and immunities (used by both sponge and artemisbeacon).") .define("harmful_potions", true); TileAntiBeacon.RADIUS = CFG.comment("Radius to protect players and entities from potion effects being applied (used by both sponge and artemisbeacon). ") @@ -475,25 +483,33 @@ private static void initConfig() { TileDisenchant.FLUIDCOST = CFG.comment("Cost of (or payment for if negative) per enchanted book generated").defineInRange("fluid_cost", 100, -1000, 16000); TileDisenchant.POWERCONF = CFG.comment("Power per use disenchanter").defineInRange("energy_cost", 2500, 0, 64000); CFG.pop(); - CFG.push("terra_preta"); - TileTerraPreta.TIMER_FULL = CFG.comment("Growth interval in ticks (100 would be every 5 seconds). Also affects terra glass").defineInRange("growth_interval", 100, 1, 64000); - TileTerraPreta.CHANCE = CFG.comment("Chance that the crop will grow after the interval").defineInRange("growth_chance", 0.5, 0, 1); - CFG.pop(); CFG.push("anvil_void"); TileAnvilVoid.FLUIDPAY = CFG.comment("Payment per void action, if not zero").defineInRange("fluid_cost", 25, 0, 16000); CFG.pop(); CFG.push("sound"); - BlockSoundRecorder.RADIUS = CFG.comment("Sound Recorder - how far out does it listen to record sounds").defineInRange("radius", 8, 1, 64); + RECORDER_RADIUS = CFG.comment("Sound Recorder - how far out does it listen to record sounds").defineInRange("radius", 8, 1, 64); CFG.pop(); - CFG.push("ender_shelf"); + CFG.comment("Ender shelf settings").push("ender_shelf"); EnderShelfItemHandler.BOOKS_PER_ROW = CFG.comment("Each shelf has five rows. Set the number of books stored per row here").defineInRange("books_per_row", 256, 1, 1024); EnderShelfHelper.MAX_DIST = CFG.comment("Controller Max distance to search (using manhattan distance)").defineInRange("controller_distance", 64, 1, 256); CFG.pop(); // ender_shelf*6 + CFG.comment("soundproofing settings").push("soundproofing"); //soundproofing + SOUND_RADIUS = CFG.comment("Radius of sound proofing (distance from each block that it will listen)").defineInRange("radius", 6, 1, 16); + CFG.pop(); //soundproofing CFG.comment("Sprinkler settings").push("sprinkler"); TileSprinkler.RADIUS = CFG.comment("Radius").defineInRange("radius", 4, 1, 32); TileSprinkler.WATERCOST = CFG.comment("Water consumption").defineInRange("water", 5, 0, 1000); TileSprinkler.TIMER_FULL = CFG.comment("Tick rate. 20 will fire one block per second").defineInRange("ticks", 20, 1, 20); CFG.pop(); // sprinkler + CFG.push("terra_preta"); + TileTerraPreta.TIMER_FULL = CFG.comment("Growth interval in ticks (100 would be every 5 seconds). ").defineInRange("growth_interval", 100, 1, 64000); + TileTerraPreta.CHANCE = CFG.comment("Chance that the crop will grow after the interval").defineInRange("growth_chance", 0.5, 0, 1); + TileTerraPreta.HEIGHT = CFG.comment("growth height above the soil").defineInRange("height", 8, 2, 32); + CFG.pop(); // terra_preta + CFG.comment("terra_glass settings").push("terra_glass"); + TileTerraGlass.TIMER_FULL = CFG.comment("ticks between growth cycles").defineInRange("timer", 100, 1, 10000); + TileTerraGlass.HEIGHT = CFG.comment("growth height below the glass").defineInRange("height", 8, 0, 32); + CFG.pop(); // terra_preta CFG.comment("Ender Anchor settings").push("eye_teleport"); TileEyeTp.RANGE = CFG.comment("Maximum distance to activate").defineInRange("range", 128, 2, 256); TileEyeTp.HUNGER = CFG.comment("Hunger cost on teleport").defineInRange("hunger", 1, 0, 20); @@ -584,6 +600,11 @@ public static List getDisarmIgnoreList() { return (List) DISARM_IGNORE_LIST.get(); } + @SuppressWarnings("unchecked") + public static List getGloomIgnoreList() { + return (List) GLOOM_IGNORE_LIST.get(); + } + public static Map getMappedBeheading() { Map mappedBeheading = new HashMap(); for (String s : BEHEADING_SKINS.get()) { diff --git a/src/main/java/com/lothrazar/cyclic/data/DataTags.java b/src/main/java/com/lothrazar/cyclic/data/DataTags.java index c65374780..4d4175577 100644 --- a/src/main/java/com/lothrazar/cyclic/data/DataTags.java +++ b/src/main/java/com/lothrazar/cyclic/data/DataTags.java @@ -35,6 +35,7 @@ public class DataTags { public static final TagKey IMUSHROOMS = ItemTags.create(new ResourceLocation("forge:mushrooms")); public static final TagKey IVINES = ItemTags.create(new ResourceLocation("forge:vines")); public static final TagKey ICACTUS = ItemTags.create(new ResourceLocation("forge:cactus")); + public static final TagKey EXCAVATE_IGNORED = BlockTags.create(new ResourceLocation("cyclic:ignored/excavate")); public static void setup() { // do not delete:! this makes the mod get classloaded so the wrapper tags correctly get added to the registry early, before recipe testing diff --git a/src/main/java/com/lothrazar/cyclic/enchant/ExcavationEnchant.java b/src/main/java/com/lothrazar/cyclic/enchant/ExcavationEnchant.java index 12bd1a258..f94b1cae4 100644 --- a/src/main/java/com/lothrazar/cyclic/enchant/ExcavationEnchant.java +++ b/src/main/java/com/lothrazar/cyclic/enchant/ExcavationEnchant.java @@ -28,6 +28,8 @@ import java.util.HashSet; import java.util.List; import java.util.Set; +import com.lothrazar.cyclic.ModCyclic; +import com.lothrazar.cyclic.data.DataTags; import com.lothrazar.cyclic.registry.EnchantRegistry; import com.lothrazar.library.enchant.EnchantmentFlib; import com.lothrazar.library.util.ItemStackUtil; @@ -47,6 +49,7 @@ import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; import net.minecraftforge.common.ForgeConfigSpec.BooleanValue; +import net.minecraftforge.common.ForgeHooks; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.Tags; import net.minecraftforge.event.ForgeEventFactory; @@ -58,6 +61,7 @@ public class ExcavationEnchant extends EnchantmentFlib { public static final String ID = "excavate"; public static BooleanValue CFG; + public static boolean effectiveToolRequired = true; // non-config lets hardcode this actually public ExcavationEnchant(Rarity rarityIn, EnchantmentCategory typeIn, EquipmentSlot... slots) { super(rarityIn, typeIn, slots); @@ -127,7 +131,14 @@ public void onBreakEvent(BreakEvent event) { if (level <= 0) { return; } - //if (ForgeHooks.canHarvestBlock(eventState, player, world, pos)) { + if (effectiveToolRequired && !ForgeHooks.isCorrectToolForDrops(eventState, player)) { + ModCyclic.LOGGER.info("excavate trigger cancelled; tool not effective"); + return; + } + if (eventState.is(DataTags.EXCAVATE_IGNORED)) { + ModCyclic.LOGGER.info("excavate trigger cancelled; see blocktag " + DataTags.EXCAVATE_IGNORED.toString()); + return; + } if (ForgeEventFactory.doPlayerHarvestCheck(player, eventState, true)) { int harvested = this.harvestSurrounding((Level) world, player, pos, block, 1, level, player.swingingArm); if (harvested > 0) { diff --git a/src/main/java/com/lothrazar/cyclic/enchant/GloomCurseEnchant.java b/src/main/java/com/lothrazar/cyclic/enchant/GloomCurseEnchant.java index 1a3eb27a4..108aff096 100644 --- a/src/main/java/com/lothrazar/cyclic/enchant/GloomCurseEnchant.java +++ b/src/main/java/com/lothrazar/cyclic/enchant/GloomCurseEnchant.java @@ -2,9 +2,13 @@ import java.util.Collections; import java.util.List; +import com.lothrazar.cyclic.ModCyclic; +import com.lothrazar.cyclic.config.ConfigRegistry; import com.lothrazar.library.enchant.EnchantmentFlib; import com.lothrazar.library.util.EnchantUtil; import com.lothrazar.library.util.FakePlayerUtil; +import com.lothrazar.library.util.StringParseUtil; +import net.minecraft.resources.ResourceLocation; import net.minecraft.world.effect.MobEffect; import net.minecraft.world.effect.MobEffectInstance; import net.minecraft.world.entity.Entity; @@ -15,6 +19,7 @@ import net.minecraft.world.item.enchantment.EnchantmentCategory; import net.minecraftforge.common.ForgeConfigSpec.BooleanValue; import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.registries.ForgeRegistries; public class GloomCurseEnchant extends EnchantmentFlib { @@ -92,6 +97,11 @@ public void doPostHurt(LivingEntity user, Entity attacker, int level) { continue; //should be impossible, but i had a random NPE crash log } + ResourceLocation effectKey = ForgeRegistries.MOB_EFFECTS.getKey(effect); + if (StringParseUtil.isInList(ConfigRegistry.getGloomIgnoreList(), effectKey)) { + ModCyclic.LOGGER.info("Gloom(curse) effect cannot apply " + effectKey); + continue; + } if (appliedEffects < MIN_EFFECTS || BASE_APPLY_CHANCE > user.level().random.nextDouble()) { //the OR means, if we are under minimum, always go thru diff --git a/src/main/java/com/lothrazar/cyclic/enchant/GrowthEnchant.java b/src/main/java/com/lothrazar/cyclic/enchant/GrowthEnchant.java index c68a49d0f..9f04a6efc 100644 --- a/src/main/java/com/lothrazar/cyclic/enchant/GrowthEnchant.java +++ b/src/main/java/com/lothrazar/cyclic/enchant/GrowthEnchant.java @@ -25,11 +25,12 @@ import java.util.Collections; import java.util.List; -import com.lothrazar.cyclic.util.HarvestUtil; +import com.lothrazar.cyclic.util.GrowthUtil; import com.lothrazar.library.enchant.EnchantmentFlib; import com.lothrazar.library.util.ItemStackUtil; import com.lothrazar.library.util.ShapeUtil; import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; import net.minecraft.world.InteractionHand; import net.minecraft.world.entity.EquipmentSlot; import net.minecraft.world.entity.LivingEntity; @@ -37,9 +38,6 @@ import net.minecraft.world.item.HoeItem; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.enchantment.EnchantmentCategory; -import net.minecraft.world.level.block.CropBlock; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.properties.IntegerProperty; import net.minecraftforge.common.ForgeConfigSpec.BooleanValue; import net.minecraftforge.common.ForgeConfigSpec.IntValue; import net.minecraftforge.common.MinecraftForge; @@ -48,7 +46,8 @@ public class GrowthEnchant extends EnchantmentFlib { - public static final double ODDS_ROTATE = 0.04; + public static final int HEIGHT = 2; + public static final double ODDS = 0.04; public static final String ID = "growth"; public static BooleanValue CFG; public static IntValue RADIUSFACTOR; @@ -107,39 +106,17 @@ public void onEntityUpdate(LivingTickEvent event) { } //Ticking int level = getCurrentLevelTool(entity.getItemInHand(InteractionHand.MAIN_HAND)); - if (level > 0 && !entity.level().isClientSide) { - if (entity.level().random.nextDouble() > ODDS_ROTATE / level) { - return; //slow the dice down - } + if (level > 0 && entity.level() instanceof ServerLevel sw) { final int growthLimit = level * 2 + (entity.level().isRaining() ? 4 : 1); //faster when raining too int grown = 0; List shape = ShapeUtil.squareHorizontalFull(entity.blockPosition().below(), level + RADIUSFACTOR.get()); - shape = ShapeUtil.repeatShapeByHeight(shape, 2); + shape = ShapeUtil.repeatShapeByHeight(shape, HEIGHT); Collections.shuffle(shape); for (int i = 0; i < shape.size(); i++) { if (grown >= growthLimit) { break; } - //do one - BlockPos pos = shape.get(i); - BlockState target = entity.level().getBlockState(pos); - if (target.getBlock() instanceof CropBlock igrowable) { // IGrowable gone, dont use BonemealableBlock - igrowable.growCrops(entity.level(), pos, target); - grown++; // allow mods to override growCrops() for custom behavior - } - else { //still use same old age logic as always unchanged - IntegerProperty propAge = HarvestUtil.getAgeProp(target); - if (propAge == null) { - continue; - } - int maxAge = Collections.max(propAge.getPossibleValues()); - Integer currentAge = target.getValue(propAge); - if (currentAge < maxAge) { - if (entity.level().setBlockAndUpdate(pos, target.setValue(propAge, currentAge + 1))) { - grown++; - } - } - } + GrowthUtil.tryGrow(sw, shape.get(i), ODDS * 10); } if (grown > 0) { ItemStackUtil.damageItem(entity, entity.getItemInHand(InteractionHand.MAIN_HAND)); diff --git a/src/main/java/com/lothrazar/cyclic/event/EventRender.java b/src/main/java/com/lothrazar/cyclic/event/EventRender.java index 3641904d6..677392751 100644 --- a/src/main/java/com/lothrazar/cyclic/event/EventRender.java +++ b/src/main/java/com/lothrazar/cyclic/event/EventRender.java @@ -53,7 +53,6 @@ public class EventRender { @SubscribeEvent - // public void overlay(RenderGameOverlayEvent.Post event) { public static void onCustomizeDebugText(CustomizeGuiOverlayEvent.DebugText event) { //Build scepter feature : render selected blockstate in cross hair Player player = Minecraft.getInstance().player; @@ -79,10 +78,6 @@ public static void onCustomizeDebugText(CustomizeGuiOverlayEvent.DebugText event } int height = mc.getWindow().getGuiScaledHeight(); CyclicFile datFile = PlayerDataEvents.getOrCreate(player); - // if (datFile.flyTicks > 0) { - // int sec = datFile.flyTicks / 20; - // drawString(event.getPoseStack(), "flight " + sec, 10, height - 30); - // } if (datFile.spectatorTicks > 0) { int sec = datFile.spectatorTicks / 20; RenderUtil.drawString(event.getGuiGraphics(), "noClip " + sec, 10, height - 10); diff --git a/src/main/java/com/lothrazar/cyclic/event/PlayerAbilityEvents.java b/src/main/java/com/lothrazar/cyclic/event/PlayerAbilityEvents.java index 1d2f2c73d..94f67faf0 100644 --- a/src/main/java/com/lothrazar/cyclic/event/PlayerAbilityEvents.java +++ b/src/main/java/com/lothrazar/cyclic/event/PlayerAbilityEvents.java @@ -15,7 +15,6 @@ public void onEntityUpdate(LivingTickEvent event) { if (event.getEntity() instanceof Player player) { FireballItem.tickHoldingFireball(player); CyclicFile datFile = PlayerDataEvents.getOrCreate(player); - // tickFlying(player, datFile); tickSpec(player, datFile); } } @@ -33,19 +32,4 @@ else if (datFile.spectatorTicks <= DISABLE_OFFSET) { } datFile.spectatorTicks--; } - // private void tickFlying(Player player, CyclicFile datFile) { - // if (datFile.flyTicks <= 0) { - // datFile.flyTicks = 0; - // return; - // } - // if (datFile.flyTicks > DISABLE_OFFSET) { - // player.getAbilities().mayfly = true; - // } - // else if (datFile.flyTicks <= DISABLE_OFFSET) { - // player.getAbilities().mayfly = false; - // player.getAbilities().flying = false; - // player.fallDistance = 0.0F; - // } - // datFile.flyTicks--; - // } } diff --git a/src/main/java/com/lothrazar/cyclic/item/crafting/CraftingBagContainer.java b/src/main/java/com/lothrazar/cyclic/item/crafting/CraftingBagContainer.java index dbdd69902..9d8f76883 100644 --- a/src/main/java/com/lothrazar/cyclic/item/crafting/CraftingBagContainer.java +++ b/src/main/java/com/lothrazar/cyclic/item/crafting/CraftingBagContainer.java @@ -30,7 +30,7 @@ public class CraftingBagContainer extends ContainerBase implements IContainerCra private final ResultContainer craftResult = new ResultContainer(); // public int slot = -1; - public ItemStack bag; + public ItemStack bag = ItemStack.EMPTY; public CraftingBagContainer(int id, Inventory playerInventory, Player player, int slot) { super(MenuTypeRegistry.CRAFTING_BAG.get(), id); @@ -43,9 +43,8 @@ public CraftingBagContainer(int id, Inventory playerInventory, Player player, in this.addSlot(new ResultSlot(playerInventory.player, this.craftMatrix, this.craftResult, 0, 124, 35)); if (slot > -1) { this.bag = playerInventory.getItem(slot); - ModCyclic.LOGGER.info("bag " + bag); } - if (bag.isEmpty()) { + if (bag == null || bag.isEmpty()) { this.bag = super.findBag(ItemRegistry.CRAFTING_BAG.get()); } //grid diff --git a/src/main/java/com/lothrazar/cyclic/item/equipment/GlowingHelmetItem.java b/src/main/java/com/lothrazar/cyclic/item/equipment/GlowingHelmetItem.java index 1781bc770..1df40b93b 100644 --- a/src/main/java/com/lothrazar/cyclic/item/equipment/GlowingHelmetItem.java +++ b/src/main/java/com/lothrazar/cyclic/item/equipment/GlowingHelmetItem.java @@ -98,9 +98,8 @@ private static boolean isOnStatic(ItemStack held) { //from ItemEvents- curios slot public static void onEntityUpdate(LivingTickEvent event) { //reduce check to only once per second instead of per tick - if (event.getEntity().level().getGameTime() % 20 == 0 && - event.getEntity() != null) { //some of the items need an off switch - Player player = (Player) event.getEntity(); + if (event.getEntity().level().getGameTime() % Const.TICKS_PER_SEC == 0 && + event.getEntity() instanceof Player player) { //some of the items need an off switch checkIfHelmOff(player); // get helm ItemStack helm = CharmUtil.getCurio(player, ItemRegistry.GLOWING_HELMET.get()); diff --git a/src/main/java/com/lothrazar/cyclic/item/food/EdibleSpecItem.java b/src/main/java/com/lothrazar/cyclic/item/food/EdibleSpecItem.java index 84fa30b61..fbfec187f 100644 --- a/src/main/java/com/lothrazar/cyclic/item/food/EdibleSpecItem.java +++ b/src/main/java/com/lothrazar/cyclic/item/food/EdibleSpecItem.java @@ -17,7 +17,7 @@ public class EdibleSpecItem extends ItemBaseCyclic { public static IntValue TICKS; public EdibleSpecItem(Properties properties) { - super(properties.rarity(Rarity.EPIC).food(new FoodProperties.Builder().nutrition(3).saturationMod(0).alwaysEat().build())); + super(properties.rarity(Rarity.EPIC).food(new FoodProperties.Builder().nutrition(1).saturationMod(0).alwaysEat().build())); } @Override diff --git a/src/main/java/com/lothrazar/cyclic/item/lunchbox/ItemLunchbox.java b/src/main/java/com/lothrazar/cyclic/item/lunchbox/ItemLunchbox.java index 50fff7134..1bf897742 100644 --- a/src/main/java/com/lothrazar/cyclic/item/lunchbox/ItemLunchbox.java +++ b/src/main/java/com/lothrazar/cyclic/item/lunchbox/ItemLunchbox.java @@ -46,6 +46,7 @@ public class ItemLunchbox extends ItemBaseCyclic { + private static final String HOLDING = "holding"; public static final int SLOTS = 7; public ItemLunchbox(Properties prop) { @@ -171,11 +172,11 @@ public ICapabilityProvider initCapabilities(ItemStack stack, CompoundTag nbt) { } public static void setHoldingEdible(ItemStack box, boolean edible) { - box.getOrCreateTag().putBoolean("holding", edible); + box.getOrCreateTag().putBoolean(HOLDING, edible); } public static int getColour(ItemStack stack) { - if (stack.hasTag() && stack.getTag().getBoolean("holding")) { + if (stack.hasTag() && stack.getTag().getBoolean(HOLDING)) { // green? return 0x00AAAAFF; return 0x000000FF; // 0xFFFF0011; } diff --git a/src/main/java/com/lothrazar/cyclic/registry/TileRegistry.java b/src/main/java/com/lothrazar/cyclic/registry/TileRegistry.java index e071bc0d9..ef382048b 100644 --- a/src/main/java/com/lothrazar/cyclic/registry/TileRegistry.java +++ b/src/main/java/com/lothrazar/cyclic/registry/TileRegistry.java @@ -103,7 +103,7 @@ public class TileRegistry { public static final RegistryObject> ROTATOR = TILES.register("rotator", () -> BlockEntityType.Builder.of(TileRotator::new, BlockRegistry.ROTATOR.get()).build(null)); public static final RegistryObject> DETECTORMOON = TILES.register("detector_moon", () -> BlockEntityType.Builder.of(TileMoon::new, BlockRegistry.DETECTORMOON.get()).build(null)); public static final RegistryObject> DETECTORWEATHER = TILES.register("detector_weather", () -> BlockEntityType.Builder.of(TileWeather::new, BlockRegistry.DETECTORWEATHER.get()).build(null)); - public static final RegistryObject> TERRAGLASS = TILES.register("terra_glass", () -> BlockEntityType.Builder.of(TileTerraGlass::new, BlockRegistry.TERRAGLASS.get()).build(null)); + public static final RegistryObject> TERRA_GLASS = TILES.register("terra_glass", () -> BlockEntityType.Builder.of(TileTerraGlass::new, BlockRegistry.TERRAGLASS.get()).build(null)); public static final RegistryObject> SPRINKLER = TILES.register("sprinkler", () -> BlockEntityType.Builder.of(TileSprinkler::new, BlockRegistry.SPRINKLER.get()).build(null)); public static final RegistryObject> ENDER_ITEM_SHELF = TILES.register("ender_item_shelf", () -> BlockEntityType.Builder.of(TileItemShelf::new, BlockRegistry.ENDER_ITEM_SHELF.get()).build(null)); public static final RegistryObject> WIRELESS_ENERGY = TILES.register("wireless_energy", () -> BlockEntityType.Builder.of(TileWirelessEnergy::new, BlockRegistry.WIRELESS_ENERGY.get()).build(null)); diff --git a/src/main/java/com/lothrazar/cyclic/util/GrowthUtil.java b/src/main/java/com/lothrazar/cyclic/util/GrowthUtil.java new file mode 100644 index 000000000..3b58ad36d --- /dev/null +++ b/src/main/java/com/lothrazar/cyclic/util/GrowthUtil.java @@ -0,0 +1,71 @@ +package com.lothrazar.cyclic.util; + +import com.lothrazar.cyclic.ModCyclic; +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.tags.BlockTags; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.BonemealableBlock; +import net.minecraft.world.level.block.state.BlockState; + +public class GrowthUtil { + + public static boolean isValidGrow(Level world, BlockPos current) { + if (world.isEmptyBlock(current)) { // isAir + return false; + } + BlockState bState = world.getBlockState(current); + if (!bState.is(BlockTags.CROPS) && !bState.is(BlockTags.SAPLINGS)) { + ModCyclic.LOGGER.info("terra-grow can only grow minecraft:crops | minecraft:saplings : " + bState.getBlock()); + return false; + } + if (bState.getBlock() instanceof BonemealableBlock crop) { + // BonemealableBlock crop = ((BonemealableBlock) bState.getBlock()); + // if (!crop.isValidBonemealTarget(world, current, bState, world.isClientSide)) { // canCrow + // ModCyclic.LOGGER.info("terra-grow crop cannot grow right now " + bState.getBlock()); + // return false; //cant grow, or cant bonemeal. no + // } + if (!crop.isValidBonemealTarget(world, current, bState, world.isClientSide)) {//canUseBonemeal // canGrow + ModCyclic.LOGGER.info("terra-grow canUseBonemeal is false " + bState.getBlock()); + return false; //cant grow, or cant bonemeal. no + } + } + return true; + } + + /** + * grow if valid + */ + public static boolean tryGrow(ServerLevel world, BlockPos current, double d) { + if (!isValidGrow(world, current)) { + return false; + } + if (d >= 1 || world.random.nextDouble() < d) { + BlockState bState = world.getBlockState(current); + Block block = bState.getBlock(); + if (world instanceof ServerLevel) { + try { + grow(world, current, bState, block); + } + catch (Exception e) { + return false; + } + } + } + return true; + } + + @SuppressWarnings("deprecation") + private static void grow(ServerLevel world, BlockPos current, BlockState bState, Block block) { + if (bState.getBlock() instanceof BonemealableBlock crop) { + crop.performBonemeal(world, world.random, current, bState); // .grow() + } + else { // saplings, etc + block.randomTick(bState, world, current, world.random); + block.randomTick(bState, world, current, world.random); + block.randomTick(bState, world, current, world.random); + } + ModCyclic.LOGGER.info("terra-grow Successful growth" + block); + } +} diff --git a/src/main/resources/assets/cyclic/lang/en_us.json b/src/main/resources/assets/cyclic/lang/en_us.json index bb2f24cbd..fc5e81854 100644 --- a/src/main/resources/assets/cyclic/lang/en_us.json +++ b/src/main/resources/assets/cyclic/lang/en_us.json @@ -1360,7 +1360,6 @@ "potion.butter.oops": "Butterfingers! Dropped something when you moved.", - "effect.cyclic.flight": "Flight", "effect.cyclic.flight.description": "Players can fly using this effect", "item.minecraft.potion.effect.cyclic_flight": "Potion of Flight", @@ -1368,7 +1367,9 @@ "item.minecraft.lingering_potion.effect.cyclic_flight": "Lingering Potion of Flight", "item.minecraft.tipped_arrow.effect.cyclic_flight": "Arrow of Flight", - + "item.cyclic.tile_transporter_empty.guide": "Right click on any machine or container with the Sack of Holding to pick it up. Right click on any block with a filled Sack of Holding to place the machine again.", + + "effect.cyclic.butter": "Butterfingers", "effect.cyclic.butter.description": "Chance to drop items while moving or attacking", "item.minecraft.potion.effect.cyclic_butter": "Potion of Butterfingers", diff --git a/src/main/resources/assets/cyclic/models/block/my_water_candle_lit.json b/src/main/resources/assets/cyclic/models/block/my_water_candle_lit.json index dcb8500ed..24b3d614f 100644 --- a/src/main/resources/assets/cyclic/models/block/my_water_candle_lit.json +++ b/src/main/resources/assets/cyclic/models/block/my_water_candle_lit.json @@ -4,9 +4,9 @@ "textures": { "holder": "cyclic:block/machine/water_candle_holder", "2": "cyclic:block/machine/water_candle", - "centerwater": "cyclic:block/water_fake", + "centerwater": "cyclic:block/water_fake", "sides": "cyclic:block/machine/water_candle_sides", - "flame": "cyclic:block/machine/gold" + "flame": "cyclic:block/machine/gold" }, "elements": [ { diff --git a/src/main/resources/data/cyclic/recipes/randomize_scepter.json b/src/main/resources/data/cyclic/recipes/randomize_scepter.json index 1680baac2..6b131236e 100644 --- a/src/main/resources/data/cyclic/recipes/randomize_scepter.json +++ b/src/main/resources/data/cyclic/recipes/randomize_scepter.json @@ -10,7 +10,7 @@ "tag": "forge:dyes/purple" }, "i": { - "item": "minecraft:iron_ingot" + "tag": "forge:ingots/iron" }, "g": { "item": "minecraft:redstone" diff --git a/src/main/resources/data/cyclic/recipes/solidifier/solidifier_apple.json b/src/main/resources/data/cyclic/recipes/solidifier/solidifier_apple.json index 14b17e807..b08c5419d 100644 --- a/src/main/resources/data/cyclic/recipes/solidifier/solidifier_apple.json +++ b/src/main/resources/data/cyclic/recipes/solidifier/solidifier_apple.json @@ -17,7 +17,7 @@ }, "mix": { "tag": "forge:honey", - "count": 300 + "count": 3000 }, "result": { "item": "cyclic:apple_honey", diff --git a/src/main/resources/data/cyclic/recipes/solidifier/solidifier_apple0.json b/src/main/resources/data/cyclic/recipes/solidifier/solidifier_apple0.json index 7ea2df9de..77b11d6b2 100644 --- a/src/main/resources/data/cyclic/recipes/solidifier/solidifier_apple0.json +++ b/src/main/resources/data/cyclic/recipes/solidifier/solidifier_apple0.json @@ -7,7 +7,7 @@ ], "mix": { "tag": "forge:honey", - "count": 100 + "count": 1000 }, "energy": { "rfpertick": 100, diff --git a/src/main/resources/data/cyclic/tags/blocks/ignored/excavate.json b/src/main/resources/data/cyclic/tags/blocks/ignored/excavate.json new file mode 100644 index 000000000..cf52e968c --- /dev/null +++ b/src/main/resources/data/cyclic/tags/blocks/ignored/excavate.json @@ -0,0 +1,9 @@ +{ + "replace": false, + "values": [ + "#minecraft:shulker_boxes", + {"required":false, "id": "cyclic:crate"}, + {"required":false, "id": "minecraft:chest"}, + {"required":false, "id": "minecraft:command_block"} + ] +} \ No newline at end of file diff --git a/update.json b/update.json index 9332774c1..7c426d5dc 100644 --- a/update.json +++ b/update.json @@ -2,12 +2,13 @@ "homepage": "https://www.curseforge.com/minecraft/mc-mods/cyclic", "promos": { - "1.16.5-latest": "1.5.21", + "1.16.5-latest": "1.5.22", "1.18.2-latest": "1.7.17", "1.19.2-latest":"1.8.2", "1.19.3-latest":"1.9.0", "1.19.4-latest":"1.10.3", - "1.20.1-latest":"1.12.4" + "1.20-latest":"1.12.1" + }, "1.16.5": { "0.6.1": "Ported ", @@ -74,8 +75,24 @@ ,"1.5.9":"Fix Battery energy tooltip not updating when charged in an item slot. Added charging slot to Battery. Fix sleeping mat bug when used in nether. Fix Fluid cables visual disconnection when placing. " ,"1.5.10":"Machines that use fluid ingredients now accept fluid tags such as 'forge:experience' in place of fluid ID; updated some existing recipes on Solidifier and Evap Generator to match (old recipe JSONs still all compatible/valid). Fixed battery energy item stack capability provider. Refreshed texture of Air charm. Vision helmet compat with curios head slot. Revert GPS card fixes to v1.5.6. One recipe added to cyclic:generator_fluid for tag forge:biomass. Default config value updated for disable_pickup on the Sack of Holding. Add compat for Beheading enchant with the 7 Tinkers Construct mob heads (config heads are still checked last. no changes if tinkers not installed). " ,"1.5.11":"Fix a bugged interaction with Settings data card and Filter data card #1970 . Torch Charm now tries to avoid placing on non-solid blocks such as top side of a bottom Slab where the torch breaks right away. " - ,"1.5.12":"PR #1976 by metalshark :Item, Energy, and Fluid Cables now have Increased performance (compile time optimisations, reduction in cyclomatic complexity and removal of redundant checks) " + ,"1.5.13":"Added support for using the left hand on Item User. #1994 by 'metalshark' Fixes issue #1992. " + ,"1.5.14":"Fix #2016 regarding settings data card. Fix Crash when trying to push Cyclic item cables with create piston. Merge pull request #2013 from metalshark : Add caching of packager recipes and move static methods out of main class for scaling. Merge pull request #2011 from metalshark : Invalidate capabilities when declaring them " + ,"1.5.15":"Fluids cyclic:honey, xpjuice, and biomass are now swim-able. Fix harvesting Battery and Tank. Fix scythe of foraging not harvesting some 2-tall flower bushes. Fix cannot shift-click from Packager. Added client text config 'FluidContents'. Reusable Ender Eye now works with YUNGS better strongholds (structure ID 'betterstrongholds:stronghold'). Fix Item Transfer Node missing loot table. Fix ender shelf event conflict with supplementaries:book_pile. Empty Ender Shelf now drops item stack with no datatag. Hoppers can now insert into Composter. Fix wooden hopper sometimes not picking up items on top of it. Fluid Cable and Fluid Hopper can now extract water from a full Water Cauldron. Cyan Flower can now go into Compost. Fix harvest scythe desync on servers. Fix #2057 doorbell on leaf blocks. fix #2054 dodge concurrent exceptions when present so isabesnt is overkill. Fix #2056 remove event blocking bonemeal and podzol. Fix #2041 Inaccessible Enchantments, update enchant rarity levels to match mc1.18.2+ settings. Tunnel added to Shape Builder #1911. Fix #2061 Block Reach enchant by using Attribute Modifiers (mod compatibility). " + ,"1.5.16":" Fix Workbench deletes items inside when mined #2121" + ,"1.5.17":" Fix Workbench deletes items inside when mined #2121. Fix Fluid cable crashing game #2118 fluid pipe server crash #2090 using ConcurrentHashMap for smp issues (ConcurrentModificationException)." + ,"1.5.18":"Added 'Always On / Requires Redstone' button to the Redstone Clock so it can be controlled (feature ported from mc 1.12.2 & 1.18.2)" + ,"1.5.19":"Backports from mc1.18.2: right-click the Crafting Stick anywhere in your inventory screen, even while not holding it, to open it. Fix logs about 'unused frames'. Fixed logs about ' Unknown recipe category: cyclic:'. Fix Combustion Generator consumes Empty Bucket #2146. Fix #2171 Rich Soil acting translucent and blocksounds. #2138 /cyclic commands can run in functions and command blocks" + ,"1.5.20":"#2102 wooden and golden hopper deposit logic fixed, now matches 1.18.2+ versions. #2085 Hopper reach area & pickup logic now uses vanilla-hopper area size. JEED compatibility added for some potion effects. Port Fishing Net and Mending Fishingrods compatibility from 1.12.2 #2067. Ender Apple now sends a message if nothing is found (void/flatworlds/etc). Growth enchant now skips IGrowable blocks that return false for 'canGrow();'. Many new config options added for: growth enchant, beheading enchant, battery, sprinkler, experience_pylon, fisher, scythes, and others in cyclic.toml" + ,"1.5.21":"#1933 Sack of Holding chest placement override added, with new config to revert back to legacy behavior if desired (overrideChestSingle). #2168 fix bug where ender shelf sometimes would not save contents when mined after exiting reloading world when client data desyncs. Added a percentage config and ignorelist config for cyclic:disarm enchantment (disarmPercentPerLevel, disarmIngoredMobs), resolves it dropping your copied weapon from alexsmobs:mimicube #2249. Fix #1878 layered and/or logic for multiple wireless transmitters on the same node " + ,"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. New config '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). 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] zenscript support for generator_fluid and generator_item; #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+ " + + }, @@ -116,8 +133,9 @@ ,"1.7.14":"Fix cyclic:auto_smelt enchant #2148 (NOTE: also check cyclic.toml and make sure enabled = true under auto_smelt header ). Fix Solar Generator #2154 #2155 . Ore prospector item has new config prospector.height . Prospector now tells player the count of ores detected; Fix #2159 laser beam rendering. Fix #2152, and chorus flight is now compatible with flight potion. Add feature #1913 Wireless redstone transmitter can now attempt to reach across dimensions (example nether to overworld, only if chunk is already loaded by something else). #2134 Add cyclic:gem_obsidian recipe that consumes Chorus Fruit, for consistency with 1.16.5 versions . Add inventory screen to Clay Battery and Solar Generator. Fix potion names. Fix #2132 wither rose duplicate crusher recipes. Add more default values to uncrafter ignore_list and ignore_recipe recipe ids (this means for newly generated default config files, the uncrafter will let you reverse dyes to other dyes but not dyes to flowers). Added 3 new to solidifier that use biomass fluid (moss_block, tallgrass). " ,"1.7.15":"Life Leech no longer refills hunger (#2241). Merged Typo: double 'consume' (#2275)@Pifanjr. Update Simplified Chinese Transaction (#2277)@UraraChiya. " ,"1.7.16":"Fix #2243 User output buffer (milk and other tranforming outputs from entity interactions). fix #2236 recipe conflict for moss block in solidifier_moss_block.json. fix #2247 Charm Talisman Missing lava protection. Fix #2259: crates and other heavy blocks that keep their contents now drop motionless to avoid bouncing away for small base situations. #2261 Smooth glass can be reverse-smelted back into plain glass. Fix items that use RF not charging items on servers #2274 #2169. fix #2272 #2260 typos. Fix #2268 material generator recipe. update candle models from #2182. Fix Smooth Glass looks incorrect underwater #2263. Fix Tempered dark glass does not cull against itself #2262 " - - + ,"1.7.17":"This update ports some features that had previously been exlusive to the mc 1.16.5-1.15.12 thru 1.16.5-1.15.21; all are listed below. New configs: [cyclic.enchantment.disarm] now has 'ignoredMobs' and 'percentPerLevel', [cyclic.items.tile_transporter] now has 'overrideChestSingle', read on or see cyclic.yml for more details. PR #1976 by metalshark :Item, Energy, and Fluid Cables now have Increased performance (compile time optimisations, reduction in cyclomatic complexity and removal of redundant checks). PR #1994 by 'metalshark' Fixes issue #1992. Merge pull request #2013 from metalshark : Add caching of packager recipes and move static methods out of main class for scaling. Merge pull request #2011 from metalshark : Invalidate capabilities when declaring them. #1933 Sack of Holding chest placement override added, with new config to revert back to legacy behavior if desired (overrideChestSingle). #2168 fix bug where ender shelf sometimes would not save contents when mined after exiting reloading world when client data desyncs. Added a percentage config and ignorelist config for cyclic:disarm enchantment (disarmPercentPerLevel, disarmIngoredMobs), resolves it dropping your copied weapon from alexsmobs:mimicube #2249. Fix #1878 layered and/or logic for multiple wireless transmitters on the same node. Now all git branches can be merged from mc-1.16.5 downstream to mc-1.20.1 and future updates as well. " + ,"1.7.18":"Re-added crafttweaker support. Re-added botania-api Solegnolia support. Growth enchantment now uses the same logic as Sprinkler & Terra Soil (only minecraft:crops or minecraft::saplings can grow, respect IGrowable::canUseBonemeal). New gloom ignored config Gloom enchant (cyclic:curse) to ignore and not use these effects #2217 #2325. New config '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). New config [cyclic.blocks.soundproofing] radius = 6 to control the area. New config under [cyclic.blocks] wireless_transfer_dimensional = true allowing transfer nodes to connect across dimensions #1913. 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 some recipe changes to match mc1.20.1+ (port of 1.16.5-1.5.23) " + }, @@ -139,6 +157,7 @@ ,"1.8.2":"(This update ports some features that had previously been exlusive to the mc 1.16.5-1.15.12 thru 1.16.5-1.15.21; all are listed below). New configs: [cyclic.enchantment.disarm] now has 'ignoredMobs' and 'percentPerLevel', [cyclic.items.tile_transporter] now has 'overrideChestSingle', read on or see cyclic.yml for more details. PR #1976 by metalshark :Item, Energy, and Fluid Cables now have Increased performance (compile time optimisations, reduction in cyclomatic complexity and removal of redundant checks). PR #1994 by 'metalshark' Fixes issue #1992. Merge pull request #2013 from metalshark : Add caching of packager recipes and move static methods out of main class for scaling. Merge pull request #2011 from metalshark : Invalidate capabilities when declaring them. #1933 Sack of Holding chest placement override added, with new config to revert back to legacy behavior if desired (overrideChestSingle). #2168 fix bug where ender shelf sometimes would not save contents when mined after exiting reloading world when client data desyncs. Added a percentage config and ignorelist config for cyclic:disarm enchantment (disarmPercentPerLevel, disarmIngoredMobs), resolves it dropping your copied weapon from alexsmobs:mimicube #2249. Fix #1878 layered and/or logic for multiple wireless transmitters on the same node. Now all git branches can be merged from mc-1.16.5 downstream to mc-1.20.1 and future updates as well. " + ,"1.8.3":"Re-added crafttweaker support. Re-added botania-api Solegnolia support. Growth enchantment now uses the same logic as Sprinkler & Terra Soil (only minecraft:crops or minecraft::saplings can grow, respect IGrowable::canUseBonemeal). New gloom ignored config Gloom enchant (cyclic:curse) to ignore and not use these effects #2217 #2325. New config '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). New config [cyclic.blocks.soundproofing] radius = 6 to control the area. New config under [cyclic.blocks] wireless_transfer_dimensional = true allowing transfer nodes to connect across dimensions #1913. 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 some recipe changes to match mc1.20.1+ (port of 1.16.5-1.5.23) " }, @@ -162,5 +181,7 @@ ,"1.20.5":"Merge pull request #2334 from TelepathicGrunt/trunk/1.20 Optimize anti beacon to not deadlock worldgen or lag entities" ,"1.20.6":"#2332 Patch doorbell crash. Patch InvocationTargetException: null errors coming from IHasClickToggle" ,"1.20.7":"Change curio render_toggle. #2356. Wooden Hopper is mineable with axes. Fixed Block Breaker attempting to break liquid source blocks. " + ,"1.10.3":"Re-added crafttweaker support. Re-added botania-api Solegnolia support. Growth enchantment now uses the same logic as Sprinkler & Terra Soil (only minecraft:crops or minecraft::saplings can grow, respect IGrowable::canUseBonemeal). New gloom ignored config Gloom enchant (cyclic:curse) to ignore and not use these effects #2217 #2325. New config '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). New config [cyclic.blocks.soundproofing] radius = 6 to control the area. New config under [cyclic.blocks] wireless_transfer_dimensional = true allowing transfer nodes to connect across dimensions #1913. 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 some recipe changes to match mc1.20.1+ (port of 1.16.5-1.5.23) " + } }