Jump to content

MWR

Members
  • Posts

    44
  • Joined

  • Last visited

Posts posted by MWR

  1. I'm not sure if there is a more elegant way to hold a list of potential ingredients, but this works:

    public class EmblemRecipe extends CustomRecipe {
    
    	ArrayList<Item> ingredients = new ArrayList<>(Arrays.asList(Items.GUNPOWDER, Items.BONE, Items.REDSTONE));
    	String[] emblems = {"Creeper", "Skeleton", "Redstone"};
    	
    	public EmblemRecipe(ResourceLocation id) {
    		super(id);
    	}
    
    	@Override
    	public boolean matches(CraftingContainer inv, Level level) {
    		ItemStack chestplate = ItemStack.EMPTY;
    		ItemStack ingredient = ItemStack.EMPTY;
    		
    		for(int i = 0; i < inv.getContainerSize(); ++i) {
    			ItemStack itemstack = inv.getItem(i);
    			if (chestplate.isEmpty() && itemstack.getItem() instanceof ArmorItem && ((ArmorItem)itemstack.getItem()).getSlot() == EquipmentSlot.CHEST) {
    				chestplate = itemstack;
    			}
    			
    			if (ingredient.isEmpty() && ingredients.contains(itemstack.getItem())) {
    				ingredient = itemstack;
    			}
    		}
    		
    		return !chestplate.isEmpty() && !ingredient.isEmpty();
    	}
    
    	@Override
    	public ItemStack assemble(CraftingContainer inv) {
    		ItemStack chestplate = null;
    		CompoundTag compoundtag = null;
    		String emblem = null;
    		for(int i = 0; i < inv.getContainerSize(); ++i ) {
    			ItemStack itemstack = inv.getItem(i);
    			if (itemstack.getItem() instanceof ArmorItem) {
    				chestplate = itemstack.copy();
    				compoundtag = chestplate.getOrCreateTagElement("emblem");
    			}
    			if (ingredients.contains(itemstack.getItem())) {
    				emblem = emblems[ingredients.indexOf(itemstack.getItem())];
    			}
    		}
    		compoundtag.putString("Emblem", emblem);
    		chestplate.setTag(compoundtag);
    		return chestplate;
    	}
    
    	@Override
    	public boolean canCraftInDimensions(int width, int height) {
    		return width * height >= 2;
    	}
    
    	@Override
    	public ItemStack getResultItem() {
    		return ItemStack.EMPTY;
    	}
    
    	@Override
    	public RecipeSerializer<?> getSerializer() {
    		return ModRecipeSerializer.EMBLEM_RECIPE.get();
    	}
    
    	@Override
    	public RecipeType<?> getType() {
    		return RecipeType.CRAFTING;
    	}
    
    }

    Now my struggle is rendering the armor. I can't find where vanilla armor is rendered, and when I do, would I need to extend that class and make my own renderer for armor?

  2. On 5/30/2022 at 8:25 AM, MFMods said:

    make a class EmblemRecipe that extends SpecialRecipe. in method "matches" confirm that the player provided a chestplate (maybe you'll allow adding things in steps?) and things you accept. in "assemble" method you make a recipe result - vanilla chestplate with nbt or your own item with nbt, that's up to you.

    use SimpleRecipeSerializer as a recipe serializer. register it in RegistryEvent.Register<IRecipeSerializer<?>> event.

    make a json file like this:
    {
      "type": "your_mod_id:recipe_name"
    }
    where recipe_name is name you give to the serializer. basically this is the recipe class:

    public class YourRecipe extends SpecialRecipe
    {
    	public static IRecipeSerializer<YourRecipe> StupidSerializer = (IRecipeSerializer<YourRecipe>) (new SimpleRecipeSerializer<YourRecipe>(YourRecipe::new).setRegistryName(YourMod.MODID, "recipe_name"));
    
    
    	public YourRecipe(ResourceLocation resourceLocation)
    	{
    		super(resourceLocation);
    	}
    
    
    
    	@Override
    	public boolean matches(CraftingInventory inventory, World world)
    	{
    		return true if items are acceptable;
    	}
    
    
    
    	@Override
    	public ItemStack assemble(CraftingInventory inventory)
    	{
    		return nice new itemstack with nbt;
    	}
    
    
    
    	@Override
    	public IRecipeSerializer<?> getSerializer()
    	{
    		return StupidSerializer;
    	}
    }

     

    Would I have to make a JSON for every combination, or is there a way to have generic ingredients and results?

  3. 13 hours ago, MFMods said:

    yes, you can use tags (nbt tags within the item, not the new "item tags").

    you need a custom recipe that takes a chestplate and some items and returns a chestplate with some data in nbt tags. and you need to render your stuff when you render your armor item.

    Ok, so I came up with this:

    {
      "type": "minecraft:crafting_shapeless",
      "ingredients": [
        {
          "item": "minecraft:diamond_chestplate"
        },
        {
          "item": "minecraft:gunpowder"
        }
      ],
      "result": {
        "item": "minecraft:diamond_chestplate",
        "nbt": "{Emblem:Creeper}"
      }
    }
    13 hours ago, MFMods said:

    if you are going to use the crafting table (you don't have to, it can be your own block), in assemble method of the recipe call startingChestPlate.copy() to get the itemstack to return. then, result.getOrCreateTag() returns the root tag. it's best to make a CompoundTag for your mod, fill it using putString calls and then append your compound tag under the root using the put method.

    Where would this assemble method go? Would I need to make an ArmorItem class of some sort? The custom recipe added this tag without needing code, so do I just need to figure out how to render it based on this NBT tag?

    Would I need to override the vanilla ArmorItem, or make a new one? If possible, I don't want to change vanilla chestplates, in case it somehow breaks functionality with other mods.

     

  4. I have this idea where you can add emblems to your chestplate to distinguish yourself. What I am wondering is whether or not I need to register every variant. It can get quite overwhelming to need to register 4 chestplates for every symbol, and they wouldn’t be treated as the vanilla chestplate. Would I be able to avoid this through tags or some other way?

  5. I've been trying to update my mod to 1.18, but when I run this command: 

    gradlew genEclipseRuns --refresh-dependencies

    It fails to build with this error:

    Execution failed for task ':downloadMcpConfig'.
    > Input property 'artifact' with value 'de.oceanlabs.mcp:mcp_config:1.18-20211130.085255@zip' cannot be serialized.

    I tried deleting the build folder, but nothing changed. How can I resolve this? Thanks in advance.

  6. I've been trying to update my mod from 1.16.5 to 1.17.1, but it is not functioning correctly. When I activate my custom honey sticky piston, it essentially turns into an entity. I can walk through it, and it can be destroyed with TNT. I went as far as rewriting all the code, which isn't very difficult since it's mostly copy-and-paste, but nothing has changed. Is this a Block Entity issue, or something else? Thanks in advance.

  7. 2 hours ago, MFMods said:

    there is a "dependencies" section in build gradle. did you update that? if not, download MDK for the new version, compare two build.gradle files and update old one.

    I already have, and I've learned that the mod works in 1.16.5, but the version of Minecraft I run within Eclipse is not working. It keeps trying to run 1.16.4. I ran the genEclipseRuns task in the command line, which said it downloaded forge 1.16.5, but Eclipse still refers to the old version. I tried refreshing both the Gradle and entire project, but nothing worked.

  8. 3 hours ago, Luis_ST said:

    post mods.toml

    modLoader="javafml"
    loaderVersion="[36,)"
    license="MIT"
    [[mods]]
    modId="honeystickypistonmod"
    version="${file.jarVersion}"
    displayName="Honey Sticky Piston Mod"
    logoFile="examplemod.png"
    credits="Thanks to Cy4 and their community for teaching me how to mod and samjviana for some helpful code!"
    authors="MWR_"
    description='''
    A new sticky piston that you can craft with honey!
    '''
    [[dependencies.myfirstmod]]
        modId="forge"
        mandatory=true
        versionRange="[36,)"
        ordering="NONE"
        side="BOTH"
    [[dependencies.myfirstmod]]
        modId="minecraft"
        mandatory=true
        versionRange="[1.16.5,1.17)"
        ordering="NONE"
        side="BOTH"

    Actually I think I know the problem. It isn't the mod itself but the referenced libraries. Even with refreshing, it still keeps the jar files for 1.16.4, so when I load the client, it runs 1.16.4 and not 1.16.5. If I build the mod and play it through the Minecraft launcher on Forge 1.16.5, it works fine.

    If that's the issue, then how do I refresh those libraries?

  9. I have been trying to update my mod from 1.16.4 to 1.16.5, so I updated the Gradle and mods.toml file to match with 1.16.5. Even when refreshing, I boot up the dev client and get the error "Mod File in-development needs language provider javafml:36 or above to load." How can I update javafml? Or am I updating the mod incorrectly?

  10. 9 hours ago, Luis_ST said:

    show your code

    Piston Block:

    public class HoneyStickyPistonBlock extends PistonBlock {
       private final boolean isSticky;
       
       public HoneyStickyPistonBlock(boolean sticky, Properties properties) {
          super(sticky, properties);
          this.setDefaultState(this.stateContainer.getBaseState().with(FACING, Direction.NORTH).with(EXTENDED, Boolean.valueOf(false)));
          this.isSticky = sticky;
    	}
    
       @Override //Nothing edited, put in for checkformove()
       public void onBlockPlacedBy(World worldIn, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack) {
          if (!worldIn.isRemote) {
             this.checkForMove(worldIn, pos, state);
          }
    
       }
       
       @Override //Nothing edited, put in for checkformove()
       public void neighborChanged(BlockState state, World worldIn, BlockPos pos, Block blockIn, BlockPos fromPos, boolean isMoving) {
          if (!worldIn.isRemote) {
             this.checkForMove(worldIn, pos, state);
          }
    
       }
       
       @Override //Nothing edited, put in for checkformove()
       public void onBlockAdded(BlockState state, World worldIn, BlockPos pos, BlockState oldState, boolean isMoving) {
          if (!oldState.isIn(state.getBlock())) {
             if (!worldIn.isRemote && worldIn.getTileEntity(pos) == null) {
                this.checkForMove(worldIn, pos, state);
             }
    
          }
       }
    
       @Override //Nothing edited, may not be necessary
       public BlockState getStateForPlacement(BlockItemUseContext context) {
          return this.getDefaultState().with(FACING, context.getNearestLookingDirection().getOpposite()).with(EXTENDED, Boolean.valueOf(false));
       }
       
       private void checkForMove(World worldIn, BlockPos pos, BlockState state) {
          Direction direction = state.get(FACING);
          boolean flag = this.shouldBeExtended(worldIn, pos, direction);
          if (flag && !state.get(EXTENDED)) {
             if ((new PistonBlockStructureHelper(worldIn, pos, direction, true)).canMove()) {
                worldIn.addBlockEvent(pos, this, 0, direction.getIndex());
             }
          } else if (!flag && state.get(EXTENDED)) {
             BlockPos blockpos = pos.offset(direction, 2);
             BlockState blockstate = worldIn.getBlockState(blockpos);
             int i = 1;
             if (blockstate.isIn(Blocks.MOVING_PISTON) && blockstate.get(FACING) == direction) {
                TileEntity tileentity = worldIn.getTileEntity(blockpos);
                if (tileentity instanceof HoneyStickyPistonTileEntity) {
                   HoneyStickyPistonTileEntity pistontileentity = (HoneyStickyPistonTileEntity)tileentity;
                   if (pistontileentity.isExtending() && (pistontileentity.getProgress(0.0F) < 0.5F || worldIn.getGameTime() == pistontileentity.getLastTicked() || ((ServerWorld)worldIn).isInsideTick())) {
                      i = 2;
                   }
                }
             }
    
             worldIn.addBlockEvent(pos, this, i, direction.getIndex());
          }
    
       }
    
       private boolean shouldBeExtended(World worldIn, BlockPos pos, Direction facing) {
          for(Direction direction : Direction.values()) {
             if (direction != facing && worldIn.isSidePowered(pos.offset(direction), direction)) {
                return true;
             }
          }
    
          if (worldIn.isSidePowered(pos, Direction.DOWN)) {
             return true;
          } else {
             BlockPos blockpos = pos.up();
    
             for(Direction direction1 : Direction.values()) {
                if (direction1 != Direction.DOWN && worldIn.isSidePowered(blockpos.offset(direction1), direction1)) {
                   return true;
                }
             }
    
             return false;
          }
       }
    
       @Override @Deprecated
       public boolean eventReceived(BlockState state, World worldIn, BlockPos pos, int id, int param) {
          Direction direction = state.get(FACING);
          if (!worldIn.isRemote) {
             boolean flag = this.shouldBeExtended(worldIn, pos, direction);
             if (flag && (id == 1 || id == 2)) {
                worldIn.setBlockState(pos, state.with(EXTENDED, Boolean.valueOf(true)), 2);
                return false;
             }
    
             if (!flag && id == 0) {
                return false;
             }
          }
    
          if (id == 0) {
             if (net.minecraftforge.event.ForgeEventFactory.onPistonMovePre(worldIn, pos, direction, true)) return false;
             if (!this.doMove(worldIn, pos, direction, true)) {
                return false;
             }
    
             worldIn.setBlockState(pos, state.with(EXTENDED, Boolean.valueOf(true)), 67);
             worldIn.playSound((PlayerEntity)null, pos, SoundEvents.BLOCK_PISTON_EXTEND, SoundCategory.BLOCKS, 0.5F, worldIn.rand.nextFloat() * 0.25F + 0.6F);
          } else if (id == 1 || id == 2) {
             if (net.minecraftforge.event.ForgeEventFactory.onPistonMovePre(worldIn, pos, direction, false)) return false;
             TileEntity tileentity1 = worldIn.getTileEntity(pos.offset(direction));
             if (tileentity1 instanceof HoneyStickyPistonTileEntity) {
                ((HoneyStickyPistonTileEntity)tileentity1).clearPistonTileEntity();
             }
    
             BlockState blockstate = Blocks.MOVING_PISTON.getDefaultState().with(MovingPistonBlock.FACING, direction).with(MovingPistonBlock.TYPE, PistonType.STICKY);
             worldIn.setBlockState(pos, blockstate, 20);
             worldIn.setTileEntity(pos, new HoneyStickyPistonTileEntity(this.getDefaultState().with(FACING, Direction.byIndex(param & 7)), direction, false, true));
             worldIn.func_230547_a_(pos, blockstate.getBlock());
             blockstate.updateNeighbours(worldIn, pos, 2);
             if (this.isSticky) {
                BlockPos blockpos = pos.add(direction.getXOffset() * 2, direction.getYOffset() * 2, direction.getZOffset() * 2);
                BlockState blockstate1 = worldIn.getBlockState(blockpos);
                boolean flag1 = false;
                if (blockstate1.isIn(Blocks.MOVING_PISTON)) {
                   TileEntity tileentity = worldIn.getTileEntity(blockpos);
                   if (tileentity instanceof HoneyStickyPistonTileEntity) {
                      HoneyStickyPistonTileEntity pistontileentity = (HoneyStickyPistonTileEntity)tileentity;
                      if (pistontileentity.getFacing() == direction && pistontileentity.isExtending()) {
                         pistontileentity.clearPistonTileEntity();
                         flag1 = true;
                      }
                   }
                }
    
                if (!flag1) {
                   if (id != 1 || blockstate1.isAir() || !canPush(blockstate1, worldIn, blockpos, direction.getOpposite(), false, direction) || blockstate1.getPushReaction() != PushReaction.NORMAL && !blockstate1.isIn(BlockInit.HONEY_STICKY_PISTON.get())) {
                      worldIn.removeBlock(pos.offset(direction), false);
                   } else {
                      this.doMove(worldIn, pos, direction, false);
                   }
                }
             } else {
                worldIn.removeBlock(pos.offset(direction), false);
             }
    
             worldIn.playSound((PlayerEntity)null, pos, SoundEvents.BLOCK_PISTON_CONTRACT, SoundCategory.BLOCKS, 0.5F, worldIn.rand.nextFloat() * 0.15F + 0.6F);
    	      }
    
          net.minecraftforge.event.ForgeEventFactory.onPistonMovePost(worldIn, pos, direction, (id == 0));
          return true;
       }
       //Static method weirdness? might need to remove because it's not polymorphic
       public static boolean canPush(BlockState blockStateIn, World worldIn, BlockPos pos, Direction facing, boolean destroyBlocks, Direction direction) {
    	      if (pos.getY() >= 0 && pos.getY() <= worldIn.getHeight() - 1 && worldIn.getWorldBorder().contains(pos)) {
    	         if (blockStateIn.isAir()) {
    	            return true;
    	         } else if (!blockStateIn.isIn(Blocks.OBSIDIAN) && !blockStateIn.isIn(Blocks.CRYING_OBSIDIAN) && !blockStateIn.isIn(Blocks.RESPAWN_ANCHOR)) {
    	            if (facing == Direction.DOWN && pos.getY() == 0) {
    	               return false;
    	            } else if (facing == Direction.UP && pos.getY() == worldIn.getHeight() - 1) {
    	               return false;
    	            } else {
    	               if (!blockStateIn.isIn(Blocks.PISTON) && !blockStateIn.isIn(Blocks.STICKY_PISTON) && !blockStateIn.isIn(BlockInit.HONEY_STICKY_PISTON.get())) {
    	                  if (blockStateIn.getBlockHardness(worldIn, pos) == -1.0F) {
    	                     return false;
    	                  }
    
    	                  switch(blockStateIn.getPushReaction()) {
    	                  case BLOCK:
    	                     return false;
    	                  case DESTROY:
    	                     return destroyBlocks;
    	                  case PUSH_ONLY:
    	                     return facing == direction;
    	                  }
    	               } else if (blockStateIn.get(EXTENDED)) {
    	                  return false;
    	               }
    
    	               return !blockStateIn.hasTileEntity();
    	            }
    	         } else {
    	            return false;
    	         }
    	      } else {
    	         return false;
    	      }
    	   }
       
       private boolean doMove(World worldIn, BlockPos pos, Direction directionIn, boolean extending) {
          BlockPos blockpos = pos.offset(directionIn);
          if (!extending && worldIn.getBlockState(blockpos).isIn(BlockInit.HONEY_STICKY_PISTON_HEAD.get())) {
             worldIn.setBlockState(blockpos, Blocks.AIR.getDefaultState(), 20);
          }
    
          PistonBlockStructureHelper pistonblockstructurehelper = new PistonBlockStructureHelper(worldIn, pos, directionIn, extending);
          if (!pistonblockstructurehelper.canMove()) {
             return false;
          } else {
             Map<BlockPos, BlockState> map = Maps.newHashMap();
             List<BlockPos> list = pistonblockstructurehelper.getBlocksToMove();
             List<BlockState> list1 = Lists.newArrayList();
    
             for(int i = 0; i < list.size(); ++i) {
                BlockPos blockpos1 = list.get(i);
                BlockState blockstate = worldIn.getBlockState(blockpos1);
                list1.add(blockstate);
                map.put(blockpos1, blockstate);
             }
    
             List<BlockPos> list2 = pistonblockstructurehelper.getBlocksToDestroy();
             BlockState[] ablockstate = new BlockState[list.size() + list2.size()];
             Direction direction = extending ? directionIn : directionIn.getOpposite();
             int j = 0;
    
             for(int k = list2.size() - 1; k >= 0; --k) {
                BlockPos blockpos2 = list2.get(k);
                BlockState blockstate1 = worldIn.getBlockState(blockpos2);
                TileEntity tileentity = blockstate1.hasTileEntity() ? worldIn.getTileEntity(blockpos2) : null;
                spawnDrops(blockstate1, worldIn, blockpos2, tileentity);
                worldIn.setBlockState(blockpos2, Blocks.AIR.getDefaultState(), 18);
                ablockstate[j++] = blockstate1;
             }
    
             for(int l = list.size() - 1; l >= 0; --l) {
                BlockPos blockpos3 = list.get(l);
                BlockState blockstate5 = worldIn.getBlockState(blockpos3);
                blockpos3 = blockpos3.offset(direction);
                map.remove(blockpos3);
                worldIn.setBlockState(blockpos3, Blocks.MOVING_PISTON.getDefaultState().with(FACING, directionIn), 68);
                worldIn.setTileEntity(blockpos3, new HoneyStickyPistonTileEntity(list1.get(l), directionIn, extending, false));
                ablockstate[j++] = blockstate5;
             }
    
             if (extending) {
                PistonType pistontype = PistonType.STICKY;
                BlockState blockstate4 = BlockInit.HONEY_STICKY_PISTON_HEAD.get().getDefaultState().with(HoneyStickyPistonHeadBlock.FACING, directionIn).with(HoneyStickyPistonHeadBlock.TYPE, pistontype);
                BlockState blockstate6 = Blocks.MOVING_PISTON.getDefaultState().with(MovingPistonBlock.FACING, directionIn).with(MovingPistonBlock.TYPE, PistonType.STICKY);
                map.remove(blockpos);
                worldIn.setBlockState(blockpos, blockstate6, 68);
                worldIn.setTileEntity(blockpos, new HoneyStickyPistonTileEntity(blockstate4, directionIn, true, true));
             }
    
             BlockState blockstate3 = Blocks.AIR.getDefaultState();
    
             for(BlockPos blockpos4 : map.keySet()) {
                worldIn.setBlockState(blockpos4, blockstate3, 82);
             }
    
             for(Entry<BlockPos, BlockState> entry : map.entrySet()) {
                BlockPos blockpos5 = entry.getKey();
                BlockState blockstate2 = entry.getValue();
                blockstate2.updateDiagonalNeighbors(worldIn, blockpos5, 2);
                blockstate3.updateNeighbours(worldIn, blockpos5, 2);
                blockstate3.updateDiagonalNeighbors(worldIn, blockpos5, 2);
             }
    
             j = 0;
    
             for(int i1 = list2.size() - 1; i1 >= 0; --i1) {
                BlockState blockstate7 = ablockstate[j++];
                BlockPos blockpos6 = list2.get(i1);
                blockstate7.updateDiagonalNeighbors(worldIn, blockpos6, 2);
                worldIn.notifyNeighborsOfStateChange(blockpos6, blockstate7.getBlock());
             }
    
             for(int j1 = list.size() - 1; j1 >= 0; --j1) {
                worldIn.notifyNeighborsOfStateChange(list.get(j1), ablockstate[j++].getBlock());
             }
    
             if (extending) {
                worldIn.notifyNeighborsOfStateChange(blockpos, BlockInit.HONEY_STICKY_PISTON_HEAD.get());
             }
    
             return true;
          }
       }
       
       @Override
       public PushReaction getPushReaction(BlockState state) {
          return PushReaction.NORMAL;
       }
    }

    Piston Head Block:

    public class HoneyStickyPistonHeadBlock extends PistonHeadBlock{
       private static final VoxelShape[] EXTENDED_SHAPES = getShapesForExtension(true);
       private static final VoxelShape[] UNEXTENDED_SHAPES = getShapesForExtension(false);
    
       private static VoxelShape[] getShapesForExtension(boolean extended) {
          return Arrays.stream(Direction.values()).map((direction) -> {
             return getShapeForDirection(direction, extended);
          }).toArray((id) -> {
             return new VoxelShape[id];
          });
       }
    
       private static VoxelShape getShapeForDirection(Direction direction, boolean shortArm) {
          switch(direction) {
          case DOWN:
          default:
             return VoxelShapes.or(PISTON_EXTENSION_DOWN_AABB, shortArm ? SHORT_DOWN_ARM_AABB : DOWN_ARM_AABB);
          case UP:
             return VoxelShapes.or(PISTON_EXTENSION_UP_AABB, shortArm ? SHORT_UP_ARM_AABB : UP_ARM_AABB);
          case NORTH:
             return VoxelShapes.or(PISTON_EXTENSION_NORTH_AABB, shortArm ? SHORT_NORTH_ARM_AABB : NORTH_ARM_AABB);
          case SOUTH:
             return VoxelShapes.or(PISTON_EXTENSION_SOUTH_AABB, shortArm ? SHORT_SOUTH_ARM_AABB : SOUTH_ARM_AABB);
          case WEST:
             return VoxelShapes.or(PISTON_EXTENSION_WEST_AABB, shortArm ? SHORT_WEST_ARM_AABB : WEST_ARM_AABB);
          case EAST:
             return VoxelShapes.or(PISTON_EXTENSION_EAST_AABB, shortArm ? SHORT_EAST_ARM_AABB : EAST_ARM_AABB);
          }
       }
    
       public HoneyStickyPistonHeadBlock(AbstractBlock.Properties properties) {
          super(properties);
          this.setDefaultState(this.stateContainer.getBaseState().with(FACING, Direction.NORTH).with(TYPE, PistonType.STICKY).with(SHORT, Boolean.valueOf(false)));
    
       }
       @Override //Nothing changed, may not be necessary
       public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) {
          return (state.get(SHORT) ? EXTENDED_SHAPES : UNEXTENDED_SHAPES)[state.get(FACING).ordinal()];
       }
       
       private boolean isExtended(BlockState baseState, BlockState extendedState) { 
          return extendedState.isIn(BlockInit.HONEY_STICKY_PISTON.get()) && extendedState.get(HoneyStickyPistonBlock.EXTENDED) && extendedState.get(FACING) == baseState.get(FACING);
       }
    
       @Override //Nothing changed, may not be necessary
       public void onBlockHarvested(World worldIn, BlockPos pos, BlockState state, PlayerEntity player) {
          if (!worldIn.isRemote && player.abilities.isCreativeMode) {
             BlockPos blockpos = pos.offset(state.get(FACING).getOpposite());
             if (this.isExtended(state, worldIn.getBlockState(blockpos))) {
                worldIn.destroyBlock(blockpos, false);
             }
          }
    
          super.onBlockHarvested(worldIn, pos, state, player);
       }
    
       @Override  //Nothing changed, may not be necessary
       public boolean isValidPosition(BlockState state, IWorldReader worldIn, BlockPos pos) {
          BlockState blockstate = worldIn.getBlockState(pos.offset(state.get(FACING).getOpposite()));
          return this.isExtended(state, blockstate) || blockstate.isIn(Blocks.MOVING_PISTON) && blockstate.get(FACING) == state.get(FACING);
       }
       
       @Override
       public ItemStack getItem(IBlockReader worldIn, BlockPos pos, BlockState state) {
          return new ItemStack(BlockInit.HONEY_STICKY_PISTON.get());
       }
    
    
    }

     

  11. 18 hours ago, Luis_ST said:

    Do you have a PistonHeadBlock?

    You need to override Block#canSticky (not sure if this is the correct method name)

    Yes, I have a PistonHeadBlock. I made the piston able to be pushed by overriding AbstractBlock#getPushReaction(BlockState state), but the modded piston still cannot push vanilla pistons.

  12. I created a new sticky piston made with honey, and after figuring out how to render it properly, I encountered another issue. It cannot be pushed, and the modded piston isn't sticky when pushing vanilla pistons. Where and how can I fix this? Thanks in advance.

  13. On 9/6/2020 at 10:53 PM, samjviana said:

    So, after a lot of searching and testing with some piston related code, i was able to fix the problem by creating an custom PistonTileEntity and an PistonTileEntityRenderer. 😪

    Now i'm stuck in another problem. But i'll open another topic about it later.

    How did you figure out the texture changing? I looked at your code and I can't seem to replicate your solution.

  14. 3 minutes ago, diesieben07 said:

    You'll need a custom PistonHeadBlock and override its validity checks. It has checks that the base fits, etc.

    Also update to 1.16.5.

    Would it be correct to create something like HoneyPistonHeadBlock, extend PistonHeadBlock, and override the relevant methods?

  15. I recently started modding, and I've been trying to create a new type of sticky piston that is made of honey. It has the same functionality, but it has a different recipe and texture.

    First I just registered the block like this:

    public static final RegistryObject<Block> HONEY_STICKY_PISTON = BLOCKS
    			.register("honey_sticky_piston", () -> new PistonBlock(true, AbstractBlock.Properties.from(Blocks.STICKY_PISTON)));
    //The boolean determines whether or not the piston is sticky.

    When I try to use the piston it-game, it functions perfectly. I can extend and retract it, and it sticks to blocks. However, the piston head breaks once extended. I looked through the mess of code that is the piston block, and I can't figure out how to make this work without modifying vanilla code, which I don't know how to do yet. I think the problem is that it only checks to see if it is Blocks.PISTON or Blocks.STICKY_PISTON, which doesn't allow me to make a new, fully-working piston. Is there anything I can do without having to change vanilla code?

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.