Jump to content

MWR

Members
  • Posts

    44
  • Joined

  • Last visited

Everything posted by MWR

  1. Do I need to make my own model if I just want change the texture?
  2. 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?
  3. Would I have to make a JSON for every combination, or is there a way to have generic ingredients and results?
  4. 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}" } } 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.
  5. 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?
  6. Thank you for the video, but I found the issue. I had to update the Gradle from 7.2 to 7.3 in gradle/wrapper/gradle-wrapper.properties.
  7. 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.
  8. 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.
  9. 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.
  10. 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?
  11. I did, but it still won’t update, even after refreshing the Gradle and entire project.
  12. 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?
  13. 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()); } }
  14. Down Below
  15. 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.
  16. 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.
  17. How did you figure out the texture changing? I looked at your code and I can't seem to replicate your solution.
  18. Would it be correct to create something like HoneyPistonHeadBlock, extend PistonHeadBlock, and override the relevant methods?
  19. 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.