diff --git a/1.14/gradle.properties b/1.14/gradle.properties index c4daaf7..8062f0a 100644 --- a/1.14/gradle.properties +++ b/1.14/gradle.properties @@ -5,4 +5,4 @@ version_minecraft=1.14.4 version_forge_minecraft=1.14.4-28.1.90 version_fml_mappings=20190719-1.14.3 version_jei=1.14.4:6.0.0.10 -version_engineersdecor=1.0.16-b5 +version_engineersdecor=1.0.16-b6 diff --git a/1.14/meta/update.json b/1.14/meta/update.json index 7f53562..87f9469 100644 --- a/1.14/meta/update.json +++ b/1.14/meta/update.json @@ -1,6 +1,7 @@ { "homepage": "https://www.curseforge.com/minecraft/mc-mods/engineers-decor/", "1.14.4": { + "1.0.16-b6": "[A] Made slab slice left-click pickup optional (default enabled).\n[A] Added config option for device drops in creative mode (addresses #67),\n[F] Fixed Panzer Glass Block submerged display (issue #68, thx WenXin20).", "1.0.16-b5": "[F] Fixed recipe condition bug (issue #65, thx Nachtflame for the report, and gigaherz & killjoy for the help).", "1.0.16-b4": "[U] Updated to Forge 1.14.4-28.1.90/20190719-1.14.3.\n[M] Increased slag brick recipe yield to 8.\n[M] Parent specs in model files adapted.", "1.0.16-b3": "[A] Config options (opt-outs and tweaks) added.\n[M] Increased clinker brick recipe yield to 8 for the builders needs.", @@ -35,6 +36,6 @@ }, "promos": { "1.14.4-recommended": "", - "1.14.4-latest": "1.0.16-b5" + "1.14.4-latest": "1.0.16-b6" } } \ No newline at end of file diff --git a/1.14/readme.md b/1.14/readme.md index 85790eb..5e1f1f6 100644 --- a/1.14/readme.md +++ b/1.14/readme.md @@ -11,6 +11,10 @@ Mod sources for Minecraft version 1.14.4. ## Version history + - v1.0.16-b6 [A] Made slab slice left-click pickup optional (default enabled). + [A] Added config option for device drops in creative mode (addresses #67), + [F] Fixed Panzer Glass Block submerged display (issue #68, thx WenXin20). + - v1.0.16-b5 [F] Fixed recipe condition bug (issue #65, thx Nachtflame for the report, and gigaherz & killjoy for the help). diff --git a/1.14/src/main/java/wile/engineersdecor/ModContent.java b/1.14/src/main/java/wile/engineersdecor/ModContent.java index 37b8590..2eea7c8 100644 --- a/1.14/src/main/java/wile/engineersdecor/ModContent.java +++ b/1.14/src/main/java/wile/engineersdecor/ModContent.java @@ -186,8 +186,8 @@ public class ModContent // ------------------------------------------------------------------------------------------------------------------- public static final BlockDecorGlassBlock PANZERGLASS_BLOCK = (BlockDecorGlassBlock)(new BlockDecorGlassBlock( - BlockDecor.CFG_DEFAULT, - Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(5f, 2000f).sound(SoundType.METAL) + BlockDecor.CFG_TRANSLUCENT, + Block.Properties.create(Material.GLASS, MaterialColor.AIR).hardnessAndResistance(5f, 2000f).sound(SoundType.METAL) )).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "panzerglass_block")); public static final BlockDecorSlab PANZERGLASS_SLAB = (BlockDecorSlab)(new BlockDecorSlab( diff --git a/1.14/src/main/java/wile/engineersdecor/blocks/BlockDecor.java b/1.14/src/main/java/wile/engineersdecor/blocks/BlockDecor.java index 6a315d4..9aa37bb 100644 --- a/1.14/src/main/java/wile/engineersdecor/blocks/BlockDecor.java +++ b/1.14/src/main/java/wile/engineersdecor/blocks/BlockDecor.java @@ -41,6 +41,8 @@ import net.minecraft.util.*; import net.minecraft.util.text.ITextComponent; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; +import wile.engineersdecor.detail.ModConfig; + import javax.annotation.Nullable; import java.util.Collections; import java.util.List; @@ -127,11 +129,13 @@ public class BlockDecor extends Block implements IDecorBlock } } - public static boolean dropBlock(BlockState state, World world, BlockPos pos, boolean explosion) + public static boolean dropBlock(BlockState state, World world, BlockPos pos, @Nullable PlayerEntity player) { if(!(state.getBlock() instanceof IDecorBlock)) { world.removeBlock(pos, false); return true; } if(!world.isRemote()) { - ((IDecorBlock)state.getBlock()).dropList(state, world, pos, explosion).forEach(stack->world.addEntity(new ItemEntity(world, pos.getX()+0.5, pos.getY()+0.5, pos.getZ()+0.5, stack))); + if((ModConfig.with_creative_mode_device_drops) || (player==null) || (!player.isCreative())) { + ((IDecorBlock)state.getBlock()).dropList(state, world, pos, player==null).forEach(stack->world.addEntity(new ItemEntity(world, pos.getX()+0.5, pos.getY()+0.5, pos.getZ()+0.5, stack))); + } } if(state.getBlock().hasTileEntity(state)) world.removeTileEntity(pos); world.removeBlock(pos, false); @@ -140,11 +144,11 @@ public class BlockDecor extends Block implements IDecorBlock @Override public boolean removedByPlayer(BlockState state, World world, BlockPos pos, PlayerEntity player, boolean willHarvest, IFluidState fluid) - { return hasDynamicDropList() ? dropBlock(state, world, pos, false) : super.removedByPlayer(state, world,pos , player, willHarvest, fluid); } + { return hasDynamicDropList() ? dropBlock(state, world, pos, player) : super.removedByPlayer(state, world,pos , player, willHarvest, fluid); } @Override public void onExplosionDestroy(World world, BlockPos pos, Explosion explosion) - { if(hasDynamicDropList()) dropBlock(world.getBlockState(pos), world, pos, true); } + { if(hasDynamicDropList()) dropBlock(world.getBlockState(pos), world, pos, null); } @Override @SuppressWarnings("deprecation") diff --git a/1.14/src/main/java/wile/engineersdecor/blocks/BlockDecorGlassBlock.java b/1.14/src/main/java/wile/engineersdecor/blocks/BlockDecorGlassBlock.java index e2a82b6..7d0d0d7 100644 --- a/1.14/src/main/java/wile/engineersdecor/blocks/BlockDecorGlassBlock.java +++ b/1.14/src/main/java/wile/engineersdecor/blocks/BlockDecorGlassBlock.java @@ -10,60 +10,39 @@ package wile.engineersdecor.blocks; import wile.engineersdecor.detail.ModAuxiliaries; -import net.minecraft.block.Block; -import net.minecraft.block.material.PushReaction; -import net.minecraft.block.BlockState; -import net.minecraft.client.util.ITooltipFlag; -import net.minecraft.entity.EntityType; -import net.minecraft.item.ItemStack; -import net.minecraft.util.BlockRenderLayer; -import net.minecraft.util.Direction; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.text.ITextComponent; import net.minecraft.world.IBlockReader; +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.StainedGlassBlock; +import net.minecraft.item.DyeColor; +import net.minecraft.item.ItemStack; +import net.minecraft.util.Direction; +import net.minecraft.util.text.ITextComponent; +import net.minecraft.client.util.ITooltipFlag; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; import javax.annotation.Nullable; import java.util.List; -public class BlockDecorGlassBlock extends BlockDecor +public class BlockDecorGlassBlock extends StainedGlassBlock { public BlockDecorGlassBlock(long config, Block.Properties properties) - { super(config, properties); } + { super(DyeColor.BLACK, properties); } @Override @OnlyIn(Dist.CLIENT) public void addInformation(ItemStack stack, @Nullable IBlockReader world, List tooltip, ITooltipFlag flag) { ModAuxiliaries.Tooltip.addInformation(stack, world, tooltip, flag, true); } - @Override - @OnlyIn(Dist.CLIENT) - public BlockRenderLayer getRenderLayer() - { return BlockRenderLayer.TRANSLUCENT; } - @Override @OnlyIn(Dist.CLIENT) @SuppressWarnings("deprecation") public boolean isSideInvisible(BlockState state, BlockState adjacentBlockState, Direction side) { return (adjacentBlockState.getBlock()==this) ? true : super.isSideInvisible(state, adjacentBlockState, side); } - @Override - public boolean propagatesSkylightDown(BlockState state, IBlockReader reader, BlockPos pos) - { return true; } - @Override public boolean canSpawnInBlock() { return false; } - @Override - @SuppressWarnings("deprecation") - public boolean canEntitySpawn(BlockState state, IBlockReader world, BlockPos pos, EntityType entityType) - { return false; } - - @Override - @SuppressWarnings("deprecation") - public PushReaction getPushReaction(BlockState state) - { return PushReaction.NORMAL; } - } diff --git a/1.14/src/main/java/wile/engineersdecor/blocks/BlockDecorHalfSlab.java b/1.14/src/main/java/wile/engineersdecor/blocks/BlockDecorHalfSlab.java index 60d6612..78f2b11 100644 --- a/1.14/src/main/java/wile/engineersdecor/blocks/BlockDecorHalfSlab.java +++ b/1.14/src/main/java/wile/engineersdecor/blocks/BlockDecorHalfSlab.java @@ -32,6 +32,8 @@ import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; +import wile.engineersdecor.detail.ModConfig; + import javax.annotation.Nullable; import java.util.ArrayList; import java.util.Collections; @@ -74,9 +76,7 @@ public class BlockDecorHalfSlab extends BlockDecor implements IWaterLoggable public void addInformation(ItemStack stack, @Nullable IBlockReader world, List tooltip, ITooltipFlag flag) { if(!ModAuxiliaries.Tooltip.addInformation(stack, world, tooltip, flag, true)) return; - // if(!ModConfig.optout.without_direct_slab_pickup) { - ModAuxiliaries.Tooltip.addInformation("engineersdecor.tooltip.slabpickup", "engineersdecor.tooltip.slabpickup", tooltip, flag, true); - // } + if(!ModConfig.without_direct_slab_pickup) ModAuxiliaries.Tooltip.addInformation("engineersdecor.tooltip.slabpickup", "engineersdecor.tooltip.slabpickup", tooltip, flag, true); } @Override @@ -162,7 +162,7 @@ public class BlockDecorHalfSlab extends BlockDecor implements IWaterLoggable @SuppressWarnings("deprecation") public void onBlockClicked(BlockState state, World world, BlockPos pos, PlayerEntity player) { - if((world.isRemote) ) return; // || (ModConfig.optout.without_direct_slab_pickup) + if((world.isRemote) || (ModConfig.without_direct_slab_pickup)) return; final ItemStack stack = player.getHeldItemMainhand(); if(stack.isEmpty() || (Block.getBlockFromItem(stack.getItem()) != this)) return; if(stack.getCount() >= stack.getMaxStackSize()) return; diff --git a/1.14/src/main/java/wile/engineersdecor/blocks/BlockDecorMilker.java b/1.14/src/main/java/wile/engineersdecor/blocks/BlockDecorMilker.java index 216d5a5..22d33fe 100644 --- a/1.14/src/main/java/wile/engineersdecor/blocks/BlockDecorMilker.java +++ b/1.14/src/main/java/wile/engineersdecor/blocks/BlockDecorMilker.java @@ -8,11 +8,13 @@ */ package wile.engineersdecor.blocks; +import net.minecraft.entity.ai.goal.Goal; import wile.engineersdecor.ModContent; import wile.engineersdecor.ModEngineersDecor; import wile.engineersdecor.detail.ExtItems; import wile.engineersdecor.detail.ItemHandling; import net.minecraft.world.World; +import net.minecraft.world.IWorldReader; import net.minecraft.world.IBlockReader; import net.minecraft.block.Block; import net.minecraft.block.BlockState; @@ -301,7 +303,7 @@ public class BlockDecorMilker extends BlockDecorDirectedHorizontal private void log(String s) { - // System.out.println("Milker|" + s); + //System.out.println("Milker|" + s); } // may be enabled with config, for dev was println private static ItemStack milk_filled_container_item(ItemStack stack) @@ -329,19 +331,25 @@ public class BlockDecorMilker extends BlockDecorDirectedHorizontal private void release_cow(CowEntity cow) { - if(cow!=null) { + log("RELEASE"); + if(cow != null) { cow.setNoAI(false); - cow.goalSelector.getRunningGoals().forEach(PrioritizedGoal::resetTask); + cow.targetSelector.getRunningGoals().filter(g->(g.getGoal()) instanceof MoveToMilkingMachineGoal).forEach(cow.goalSelector::removeGoal); + cow.goalSelector.getRunningGoals().filter(g->(g.getGoal()) instanceof MoveToMilkingMachineGoal).forEach(cow.goalSelector::removeGoal); } tracked_cow_ = null; state_ = MilkingState.IDLE; tick_timer_ = TICK_INTERVAL; } + private boolean is_coming(CowEntity cow) + { return (cow != null) && (cow.goalSelector.getRunningGoals().anyMatch(g->(g.getGoal()) instanceof MoveToMilkingMachineGoal)); } + private boolean milking_process() { if((tracked_cow_ == null) && (fluid_level() >= MAX_MILKING_TANK_LEVEL)) return false; // nothing to do final Direction facing = world.getBlockState(getPos()).get(HORIZONTAL_FACING).getOpposite(); + final BlockPos target_pos = getPos().offset(facing); CowEntity cow = null; { AxisAlignedBB aabb = new AxisAlignedBB(pos.offset(facing, 3)).grow(4, 2, 4); @@ -354,139 +362,156 @@ public class BlockDecorMilker extends BlockDecorDirectedHorizontal cow = cows.get(world.rand.nextInt(cows.size()-1)); // pick one } } - if((state_ != MilkingState.IDLE) && ((state_timeout_ -= PROCESSING_TICK_INTERVAL) <= 0)) { log("Cow motion timeout"); cow = null; } + if((state_ != MilkingState.IDLE) && ((state_timeout_ -= PROCESSING_TICK_INTERVAL) <= 0)) { release_cow(cow); log("Cow motion timeout"); cow = null; } if((cow == null) || (!cow.isAlive())) { release_cow(cow); cow = null; } if(tracked_cow_ == null) state_ = MilkingState.IDLE; if(cow == null) { log("Init: No cow"); return false; } // retry next cycle - tick_timer_ = PROCESSING_TICK_INTERVAL; - state_timer_ -= PROCESSING_TICK_INTERVAL; + //tick_timer_ = PROCESSING_TICK_INTERVAL; - if(cow.getNavigator().noPath()) { - BlockPos p = getPos().offset(facing,2); - cow.getNavigator().tryMoveToXYZ(p.getX()+0.5, p.getY()+0.5, p.getZ()+0.5, 1); - } - if(state_timer_ > 0) return false; - switch(state_) { // Let's do this the old school FSA sequencing way ... - case IDLE: { - final List blocking_entities = world.getEntitiesWithinAABB(LivingEntity.class, new AxisAlignedBB(pos.offset(facing)).grow(0.5, 0.5, 0.5)); - if(blocking_entities.size() > 0) { - tick_timer_ = TICK_INTERVAL; - log("Idle: Position blocked"); - if(blocking_entities.get(0) instanceof CowEntity) { - CowEntity blocker = (CowEntity)blocking_entities.get(0); - BlockPos p = getPos().offset(facing,2); - log("Idle: Shove off"); - blocker.setNoAI(false); - blocker.goalSelector.getRunningGoals().forEach(PrioritizedGoal::resetTask); - blocker.getNavigator().tryMoveToXYZ(p.getX()+0.5, p.getY()+0.5, p.getZ()+0.5, 1); - } - return false; - } - if(cow.getLeashed() || cow.isChild() || cow.isInLove() || (!cow.onGround) || cow.isBeingRidden() || cow.isSprinting()) return false; - tracked_cow_ = cow.getUniqueID(); - state_ = MilkingState.PICKED; - state_timeout_ = 200; - tracked_cow_original_position_ = cow.getPosition(); - log("Idle: Picked cow " + tracked_cow_); - return false; - } - case PICKED: { - BlockPos p = getPos().offset(facing).offset(facing.rotateY()); + if(is_coming(cow)) { + log("coming ... "); + } else { + if(!target_pos.withinDistance(cow.getPosition(), 0.5)) { + log("come ... "); cow.getNavigator().clearPath(); - if(!cow.getNavigator().tryMoveToXYZ(p.getX(), p.getY(), p.getZ(),1.0)) { - log("Picked: No path"); - cow.goalSelector.getRunningGoals().forEach(PrioritizedGoal::resetTask); - tracked_cow_ = null; - tick_timer_ = TICK_INTERVAL; + cow.goalSelector.getRunningGoals().forEach(PrioritizedGoal::resetTask); + Goal goal = new MoveToMilkingMachineGoal(cow, target_pos); + cow.goalSelector.addGoal(2, goal); + cow.targetSelector.addGoal(2, goal); + } else { + log("in pos ... "); + cow.moveToBlockPosAndAngles(target_pos, facing.getHorizontalAngle(), 0); + } + } + + { + if(cow!=null) return false; + + state_timer_ -= PROCESSING_TICK_INTERVAL; + if(state_timer_ > 0) return false; + switch(state_) { // Let's do this the old school FSA sequencing way ... + case IDLE: { + final List blocking_entities = world.getEntitiesWithinAABB(LivingEntity.class, new AxisAlignedBB(pos.offset(facing)).grow(0.5, 0.5, 0.5)); + if(blocking_entities.size() > 0) { + tick_timer_ = TICK_INTERVAL; + log("Idle: Position blocked"); + if(blocking_entities.get(0) instanceof CowEntity) { + CowEntity blocker = (CowEntity)blocking_entities.get(0); + BlockPos p = getPos().offset(facing,2); + log("Idle: Shove off"); + blocker.setNoAI(false); + blocker.goalSelector.getRunningGoals().forEach(PrioritizedGoal::resetTask); + blocker.getNavigator().tryMoveToXYZ(p.getX()+0.5, p.getY()+0.5, p.getZ()+0.5, 1); + } + return false; + } + if(cow.getLeashed() || cow.isChild() || cow.isInLove() || (!cow.onGround) || cow.isBeingRidden() || cow.isSprinting()) return false; + tracked_cow_ = cow.getUniqueID(); + state_ = MilkingState.PICKED; + state_timeout_ = 200; + tracked_cow_original_position_ = cow.getPosition(); + log("Idle: Picked cow " + tracked_cow_); return false; } - state_ = MilkingState.COMING; - state_timeout_ = 300; // 15s should be enough - log("Picked: coming to " +p); - return false; - } - case COMING: { - BlockPos p = getPos().offset(facing).offset(facing.rotateY()); - if(cow.getPosition().distanceSq(p) > 1) { - if(cow.getNavigator().getTargetPos().equals(p) && (!cow.getNavigator().noPath())) return false; + case PICKED: { + BlockPos p = getPos().offset(facing).offset(facing.rotateY()); + cow.getNavigator().clearPath(); if(!cow.getNavigator().tryMoveToXYZ(p.getX(), p.getY(), p.getZ(),1.0)) { - log("Coming: lost path"); + log("Picked: No path"); cow.goalSelector.getRunningGoals().forEach(PrioritizedGoal::resetTask); tracked_cow_ = null; tick_timer_ = TICK_INTERVAL; return false; - } else { - log("Coming: Re-init path"); - state_timeout_ -= 100; } - } else { - BlockPos next_p = getPos().offset(facing); - if(!cow.getNavigator().tryMoveToXYZ(next_p.getX(), next_p.getY(), next_p.getZ(), 1.0)) { - log("Coming: No path"); - tracked_cow_ = null; - cow.goalSelector.getRunningGoals().forEach(PrioritizedGoal::resetTask); - tick_timer_ = TICK_INTERVAL; - return false; - } - log("Coming: position reached"); - state_ = MilkingState.POSITIONING; - state_timeout_ = 100; // 5s - } - return false; - } - case POSITIONING: { - BlockPos p = getPos().offset(facing); - if(p.distanceSq(cow.posX, cow.posY, cow.posZ, true) > 0.45) { - if(cow.getNavigator().getTargetPos().equals(p) && (!cow.getNavigator().noPath())) return false; - if(!cow.getNavigator().tryMoveToXYZ(p.getX(), p.getY(), p.getZ(), 1.0)) { - log("Positioning: lost path"); - tick_timer_ = TICK_INTERVAL; - cow.goalSelector.getRunningGoals().forEach(PrioritizedGoal::resetTask); - } else { - log("Positioning: Re-init path"); - state_timeout_ -= 25; - } - tracked_cow_ = null; + state_ = MilkingState.COMING; + state_timeout_ = 300; // 15s should be enough + log("Picked: coming to " +p); return false; } - cow.setNoAI(true); - cow.move(MoverType.SELF, new Vec3d(p.getX()+0.5-cow.posX, 0,p.getZ()+0.5-cow.posZ)); - world.playSound(null, pos, SoundEvents.ENTITY_COW_MILK, SoundCategory.BLOCKS, 0.5f, 1f); - state_timeout_ = 600; - state_ = MilkingState.MILKING; - state_timer_ = 30; - log("Positioning: start milking"); - return false; - } - case MILKING: { - tank_level_ = MathHelper.clamp(tank_level_+BUCKET_SIZE, 0, TANK_CAPACITY); - state_timeout_ = 600; - state_ = MilkingState.LEAVING; - state_timer_ = 20; - cow.setNoAI(false); - cow.getNavigator().clearPath(); - log("Milking: done, leave"); - return true; - } - case LEAVING: { - BlockPos p = (tracked_cow_original_position_ != null) ? (tracked_cow_original_position_) : getPos().offset(facing,2).offset(facing.rotateYCCW()); - if(!cow.getNavigator().tryMoveToXYZ(p.getX(), p.getY(), p.getZ(), 1.0)) cow.getNavigator().clearPath(); - state_timeout_ = 600; - state_timer_ = 500; - tick_timer_ = TICK_INTERVAL; - state_ = MilkingState.WAITING; - log("Leaving: process done"); - return true; - } - case WAITING: { - tick_timer_ = TICK_INTERVAL; - log("Waiting: ..."); - return true; // wait for the timeout to kick in until starting with the next. - } - default: { - tracked_cow_ = null; + case COMING: { + BlockPos p = getPos().offset(facing).offset(facing.rotateY()); + if(cow.getPosition().distanceSq(p) > 1) { + if(cow.getNavigator().getTargetPos().equals(p) && (!cow.getNavigator().noPath())) return false; + if(!cow.getNavigator().tryMoveToXYZ(p.getX(), p.getY(), p.getZ(),1.0)) { + log("Coming: lost path"); + cow.goalSelector.getRunningGoals().forEach(PrioritizedGoal::resetTask); + tracked_cow_ = null; + tick_timer_ = TICK_INTERVAL; + return false; + } else { + log("Coming: Re-init path"); + state_timeout_ -= 100; + } + } else { + BlockPos next_p = getPos().offset(facing); + if(!cow.getNavigator().tryMoveToXYZ(next_p.getX(), next_p.getY(), next_p.getZ(), 1.0)) { + log("Coming: No path"); + tracked_cow_ = null; + cow.goalSelector.getRunningGoals().forEach(PrioritizedGoal::resetTask); + tick_timer_ = TICK_INTERVAL; + return false; + } + log("Coming: position reached"); + state_ = MilkingState.POSITIONING; + state_timeout_ = 100; // 5s + } + return false; + } + case POSITIONING: { + BlockPos p = getPos().offset(facing); + if(p.distanceSq(cow.posX, cow.posY, cow.posZ, true) > 0.45) { + if(cow.getNavigator().getTargetPos().equals(p) && (!cow.getNavigator().noPath())) return false; + if(!cow.getNavigator().tryMoveToXYZ(p.getX(), p.getY(), p.getZ(), 1.0)) { + log("Positioning: lost path"); + tick_timer_ = TICK_INTERVAL; + cow.goalSelector.getRunningGoals().forEach(PrioritizedGoal::resetTask); + } else { + log("Positioning: Re-init path"); + state_timeout_ -= 25; + } + tracked_cow_ = null; + return false; + } + cow.setNoAI(true); + cow.move(MoverType.SELF, new Vec3d(p.getX()+0.5-cow.posX, 0,p.getZ()+0.5-cow.posZ)); + world.playSound(null, pos, SoundEvents.ENTITY_COW_MILK, SoundCategory.BLOCKS, 0.5f, 1f); + state_timeout_ = 600; + state_ = MilkingState.MILKING; + state_timer_ = 30; + log("Positioning: start milking"); + return false; + } + case MILKING: { + tank_level_ = MathHelper.clamp(tank_level_+BUCKET_SIZE, 0, TANK_CAPACITY); + state_timeout_ = 600; + state_ = MilkingState.LEAVING; + state_timer_ = 20; + cow.setNoAI(false); + cow.getNavigator().clearPath(); + log("Milking: done, leave"); + return true; + } + case LEAVING: { + BlockPos p = (tracked_cow_original_position_ != null) ? (tracked_cow_original_position_) : getPos().offset(facing,2).offset(facing.rotateYCCW()); + if(!cow.getNavigator().tryMoveToXYZ(p.getX(), p.getY(), p.getZ(), 1.0)) cow.getNavigator().clearPath(); + state_timeout_ = 600; + state_timer_ = 500; + tick_timer_ = TICK_INTERVAL; + state_ = MilkingState.WAITING; + log("Leaving: process done"); + return true; + } + case WAITING: { + tick_timer_ = TICK_INTERVAL; + log("Waiting: ..."); + return true; // wait for the timeout to kick in until starting with the next. + } + default: { + tracked_cow_ = null; + } } } + return (tracked_cow_ != null); } @@ -534,4 +559,65 @@ public class BlockDecorMilker extends BlockDecorDirectedHorizontal } } + public static class MoveToMilkingMachineGoal extends net.minecraft.entity.ai.goal.MoveToBlockGoal + { + + public MoveToMilkingMachineGoal(CowEntity creature, BlockPos pos) + { + super(creature, 1.0, 20, 4); + destinationBlock = pos; + runDelay = 0; + timeoutCounter = 0; + } + + private void abort() + { + creature.targetSelector.getRunningGoals().filter(g->(g.getGoal()) instanceof MoveToMilkingMachineGoal).forEach(creature.goalSelector::removeGoal); + creature.goalSelector.getRunningGoals().filter(g->(g.getGoal()) instanceof MoveToMilkingMachineGoal).forEach(creature.goalSelector::removeGoal); + } + + @Override + public double getTargetDistanceSq() + { return 0.8; } + + @Override + public boolean shouldMove() + { return (timeoutCounter & 0x3) == 0; } + + @Override + public boolean shouldExecute() { + if(--runDelay > 0) return false; + runDelay = 4; + return true; + } + + @Override + public void tick() + { + if(!destinationBlock.withinDistance(creature.getPositionVec(), getTargetDistanceSq())) { + ++timeoutCounter; + if(shouldMove()) { + if(!creature.getNavigator().tryMoveToXYZ(destinationBlock.getX()+0.5, destinationBlock.getY(), destinationBlock.getZ()+0.5, this.movementSpeed)) { + System.out.println("TRYMOVE FAILED"); + abort(); + } + } + } else { + System.out.println("IN POSITION"); + abort(); + } + } + + @Override + protected boolean shouldMoveTo(IWorldReader world, BlockPos pos) + { + for(int i=0; i<4; ++i) { + if(world.getBlockState(pos.offset(Direction.byHorizontalIndex(i))).getBlock() instanceof BlockDecorMilker) return true; + } + System.out.println("NO MOVE TO"); + abort(); + return false; + } + } + } diff --git a/1.14/src/main/java/wile/engineersdecor/blocks/BlockDecorSlab.java b/1.14/src/main/java/wile/engineersdecor/blocks/BlockDecorSlab.java index 3d15529..2f0bb4d 100644 --- a/1.14/src/main/java/wile/engineersdecor/blocks/BlockDecorSlab.java +++ b/1.14/src/main/java/wile/engineersdecor/blocks/BlockDecorSlab.java @@ -28,13 +28,15 @@ import net.minecraft.world.IBlockReader; import net.minecraft.util.math.shapes.VoxelShape; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; +import wile.engineersdecor.detail.ModConfig; + import javax.annotation.Nullable; import java.util.ArrayList; import java.util.Collections; import java.util.List; -public class BlockDecorSlab extends BlockDecor +public class BlockDecorSlab extends BlockDecor implements IWaterLoggable { public static final IntegerProperty PARTS = IntegerProperty.create("parts", 0, 2); public static final IntegerProperty TEXTURE_VARIANT = IntegerProperty.create("tvariant", 0, 3); @@ -63,11 +65,15 @@ public class BlockDecorSlab extends BlockDecor public void addInformation(ItemStack stack, @Nullable IBlockReader world, List tooltip, ITooltipFlag flag) { if(!ModAuxiliaries.Tooltip.addInformation(stack, world, tooltip, flag, true)) return; - // if(!ModConfig.optout.without_direct_slab_pickup) { - ModAuxiliaries.Tooltip.addInformation("engineersdecor.tooltip.slabpickup", "engineersdecor.tooltip.slabpickup", tooltip, flag, true); - // } + if(!ModConfig.without_direct_slab_pickup) ModAuxiliaries.Tooltip.addInformation("engineersdecor.tooltip.slabpickup", "engineersdecor.tooltip.slabpickup", tooltip, flag, true); } + @Override + @OnlyIn(Dist.CLIENT) + @SuppressWarnings("deprecation") + public boolean isSideInvisible(BlockState state, BlockState adjacentBlockState, Direction side) + { return (adjacentBlockState==state) ? true : super.isSideInvisible(state, adjacentBlockState, side); } + @Override public boolean canSpawnInBlock() { return false; } @@ -144,7 +150,7 @@ public class BlockDecorSlab extends BlockDecor @SuppressWarnings("deprecation") public void onBlockClicked(BlockState state, World world, BlockPos pos, PlayerEntity player) { - if((world.isRemote)) return; // || (ModConfig.optout.without_direct_slab_pickup) + if((world.isRemote) || (ModConfig.without_direct_slab_pickup)) return; final ItemStack stack = player.getHeldItemMainhand(); if(stack.isEmpty() || (Block.getBlockFromItem(stack.getItem()) != this)) return; if(stack.getCount() >= stack.getMaxStackSize()) return; diff --git a/1.14/src/main/java/wile/engineersdecor/detail/ModConfig.java b/1.14/src/main/java/wile/engineersdecor/detail/ModConfig.java index 1c94320..4748dd5 100644 --- a/1.14/src/main/java/wile/engineersdecor/detail/ModConfig.java +++ b/1.14/src/main/java/wile/engineersdecor/detail/ModConfig.java @@ -127,7 +127,7 @@ public class ModConfig public final ForgeConfigSpec.BooleanValue without_ladder_speed_boost; public final ForgeConfigSpec.BooleanValue without_crafting_table_history; public final ForgeConfigSpec.BooleanValue without_direct_slab_pickup; - + public final ForgeConfigSpec.BooleanValue with_creative_mode_device_drops; // Misc public final ForgeConfigSpec.BooleanValue with_experimental; public final ForgeConfigSpec.BooleanValue without_recipes; @@ -309,11 +309,6 @@ public class ModConfig .translation(ModEngineersDecor.MODID + ".config.without_halfslabs") .comment("Disable stackable 1/8 block slices.") .define("without_halfslabs", false); - without_direct_slab_pickup = builder - .translation(ModEngineersDecor.MODID + ".config.without_direct_slab_pickup") - .comment("Disable directly picking up layers from slabs and slab " + - " slices by left clicking while looking up/down.") - .define("without_direct_slab_pickup", false); without_poles = builder .translation(ModEngineersDecor.MODID + ".config.without_poles") .comment("Disable poles of any material.") @@ -336,6 +331,16 @@ public class ModConfig .translation(ModEngineersDecor.MODID + ".config.with_experimental") .comment("Enables experimental features. Use at own risk.") .define("with_experimental", false); + without_direct_slab_pickup = builder + .translation(ModEngineersDecor.MODID + ".config.without_direct_slab_pickup") + .comment("Disable directly picking up layers from slabs and slab " + + " slices by left clicking while looking up/down.") + .define("without_direct_slab_pickup", false); + with_creative_mode_device_drops = builder + .translation(ModEngineersDecor.MODID + ".config.with_creative_mode_device_drops") + .comment("Enable that devices are dropped as item also in creative mode, allowing " + + " to relocate them with contents and settings.") + .define("with_creative_mode_device_drops", false); builder.pop(); } // --- TWEAKS ------------------------------------------------------------- @@ -574,6 +579,8 @@ public class ModConfig private static final CompoundNBT server_config_ = new CompoundNBT(); public static boolean without_crafting_table = false; public static boolean immersiveengineering_installed = false; + public static boolean without_direct_slab_pickup = false; + public static boolean with_creative_mode_device_drops = false; private static boolean with_experimental_features_ = false; private static boolean without_recipes_ = false; @@ -596,6 +603,7 @@ public class ModConfig immersiveengineering_installed = ModAuxiliaries.isModLoaded("immersiveengineering"); with_experimental_features_ = COMMON.with_experimental.get(); without_recipes_ = COMMON.without_recipes.get(); + without_direct_slab_pickup = COMMON.without_direct_slab_pickup.get(); if(with_experimental_features_) { ModEngineersDecor.logger().info("Config: EXPERIMENTAL FEATURES ENABLED."); } diff --git a/meta/update.json b/meta/update.json index 85c0d4d..4d78128 100644 --- a/meta/update.json +++ b/meta/update.json @@ -4,7 +4,7 @@ "1.12.2-recommended": "1.0.15", "1.12.2-latest": "1.0.16-b3", "1.14.4-recommended": "", - "1.14.4-latest": "1.0.16-b5" + "1.14.4-latest": "1.0.16-b6" }, "1.12.2": { "1.0.16-b3": "[M] Increased slag brick recipe yield to 8.\n[A] Small Block Placer can plant Cocoa.\n[F] Fixed Small Block Placer seed detection issue (issue #64, thx Federsavo).\n[F] Fixed incorrectly enabled alternative recipes for fluid accumulator and check valve when IE is installed.\n[M] Slightly nerfed the Small Solar Panel default peak power output (does not affect existing configurations).", @@ -74,6 +74,7 @@ "1.0.0-b1": "[A] Initial structure.\n[A] Added clinker bricks and clinker brick stairs.\n[A] Added slag bricks and slag brick stairs.\n[A] Added metal rung ladder.\n[A] Added staggered metal steps ladder.\n[A] Added treated wood ladder.\n[A] Added treated wood pole.\n[A] Added treated wood table." }, "1.14.4": { + "1.0.16-b6": "[A] Made slab slice left-click pickup optional (default enabled).\n[A] Added config option for device drops in creative mode (addresses #67),\n[F] Fixed Panzer Glass Block submerged display (issue #68, thx WenXin20).", "1.0.16-b5": "[F] Fixed recipe condition bug (issue #65, thx Nachtflame for the report, and gigaherz & killjoy for the help).", "1.0.16-b4": "[U] Updated to Forge 1.14.4-28.1.90/20190719-1.14.3.\n[M] Increased slag brick recipe yield to 8.\n[M] Parent specs in model files adapted.", "1.0.16-b3": "[A] Config options (opt-outs and tweaks) added.\n[M] Increased clinker brick recipe yield to 8 for the builders needs.",