Jump to content
Search In
  • More options...
Find results that contain...
Find results in...

[SOLVED] [1.17.1] How to/Fluids not working


Majd123mc
 Share

Recommended Posts

Solved:
 

Quote

As advised by Luis_ST, I subclassed LiquidBlock to fix all the missing references to LiquidBlock.supplier.

I *finally* found a reference for what my OilFluid class should look like, and it turns out I just had to change this:

super(new ForgeFlowingFluid.Properties(
				Source::new,
				Flowing::new,
				FluidAttributes.builder(
								new ResourceLocation(MiniTech.MODID, "block/oil_still"),
								new ResourceLocation(MiniTech.MODID, "block/oil_flow")
						).overlay(new ResourceLocation(MiniTech.MODID, "block/oil_overlay"))
						.translationKey("block." + MiniTech.MODID + ".oil")
						.color(0xffffff)));

to this:

super(new ForgeFlowingFluid.Properties(
				ModFluids.OIL,
				ModFluids.FLOWING_OIL,
				FluidAttributes.builder(
								new ResourceLocation(MiniTech.MODID, "block/oil_still"),
								new ResourceLocation(MiniTech.MODID, "block/oil_flow")
						).overlay(new ResourceLocation(MiniTech.MODID, "block/oil_overlay"))
						.translationKey("block." + MiniTech.MODID + ".oil")
						.color(0xffffff))
				.block(ModBlocks.OIL)
				.bucket(ModItems.OIL_BUCKET));

 



Hello all.

I am trying to implement oil into my mod (I know I know, unoriginal). But I just can't seem to get it to work.

(System/Minecraft information: Java 17, forge: 1.17.1-37.0.95, mappings: official)

I am using DeferredRegisters.

In the current configuration, the bucket doesn't do anything most of the time, the block doesn't appear and doesn't flow.

I am extending "ForgeFlowingFluid".

It seems in LiquidBlock there are two constructors, one deprecated taking in a Fluid, the other takes in a supplier/RegistryObject<Fluid>.

Because I am using DeferredRegisters, I have to use the second one, because blocks are registered before fluids.

But it seems that in the code, most of it relies on the LiquidBlock.fluid field, which never gets set in the second constructor. I tried hacking in a solution with a "Fixed" version of LiquidBlock:

public class FixedLiquidBlock extends LiquidBlock {
	private static final List<FixedLiquidBlock> liquidBlocksNeedingFixing = new ArrayList<>();

	// Check if the supplier is a registry object. If it is, and the value is not null, set the value of the fluid field, else mark it so that it gets set later.
	public FixedLiquidBlock(Supplier<? extends FlowingFluid> supplier, Properties properties) {
		super(supplier, properties);
		try {
			if (supplier instanceof RegistryObject registryObject && registryObject.get() != null) {
				try {
					Class<?> class_ = LiquidBlock.class;

					Field fluidField = ObfuscationReflectionHelper.findField(class_, "fluid");
					fluidField.setAccessible(true);
					fluidField.set(this, supplier.get());
				} catch (Exception e) {
					throw new RuntimeException(e);
				}
			}
		} catch (NullPointerException ignored) {}

		liquidBlocksNeedingFixing.add(this);
	}

	@Mod.EventBusSubscriber(bus=Mod.EventBusSubscriber.Bus.MOD)
	private static class FixedLiquidBlockEvents {
		@SubscribeEvent(priority = EventPriority.LOWEST) // Force the event to be called last
		// After registration of fluids is finished, set the fluids field.
		public static void onFluidsRegister(RegistryEvent<Fluid> fluidRegistryEvent) {
			for (FixedLiquidBlock fixedLiquidBlock : liquidBlocksNeedingFixing) {
				try {
					Class<?> class_ = LiquidBlock.class;

					Field fluidField = ObfuscationReflectionHelper.findField(class_, "fluid");
					fluidField.setAccessible(true);
					fluidField.set(fixedLiquidBlock, fixedLiquidBlock.getFluid());
				} catch (Exception e) {
					throw new RuntimeException(e);
				}
			}
		}
	}
}

But clearly what I'm doing is stupid because it still doesn't work. I even tried without my hacky solution, and it still didn't work!

Am I doing something wrong? Should I be extending something else? What else should I do?
 

Code for fluid, OilFluid.java:
 

public abstract class OilFluid extends ForgeFlowingFluid {

	protected OilFluid() {
		super(new ForgeFlowingFluid.Properties(
				Source::new,
				Flowing::new,
				FluidAttributes.builder(
								new ResourceLocation(MiniTech.MODID, "block/oil_still"),
								new ResourceLocation(MiniTech.MODID, "block/oil_flow")
						).overlay(new ResourceLocation(MiniTech.MODID, "block/oil_overlay"))
						.translationKey("block." + MiniTech.MODID + ".oil")
						.color(0xffffff)));
	}



	public static class Flowing extends OilFluid {
		public Flowing()
		{
			registerDefaultState(getStateDefinition().any().setValue(LEVEL, 7));
		}

		@Override
		protected void createFluidStateDefinition(StateDefinition.Builder<Fluid, FluidState> p_76476_) {
			super.createFluidStateDefinition(p_76476_);
			p_76476_.add(LEVEL);
		}

		@Override
		public int getAmount(FluidState p_76480_) {
			return p_76480_.getValue(LEVEL);
		}

		@Override
		public boolean isSource(FluidState p_76478_) {
			return false;
		}
	}

	public static class Source extends OilFluid {

		@Override
		public int getAmount(FluidState p_76485_) {
			return 8;
		}

		@Override
		public boolean isSource(FluidState p_76483_) {
			return true;
		}
	}
}

Code for ModBlocks.java:
 

public class ModBlocks {
    private static final DeferredRegister<Block> BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, MiniTech.MODID);

    public static final RegistryObject<RefineryFurnaceBlock> REFINERY_FURNACE = BLOCKS.register("refinery_furnace", () -> new RefineryFurnaceBlock(BlockBehaviour.Properties.of(Material.STONE).requiresCorrectToolForDrops().strength(3.5F).lightLevel(litBlockEmission(13))));
    // Fluids
    public static final RegistryObject<LiquidBlock> OIL = BLOCKS.register("oil", () -> new FixedLiquidBlock(ModFluids.OIL, BlockBehaviour.Properties.of(Material.WATER).noCollission().strength(100.0F).noDrops()));

    public static void register(IEventBus eventBus) {
        BLOCKS.register(eventBus);
    }

    private static ToIntFunction<BlockState> litBlockEmission(int lightLevel) {
        return (blockState) -> {
            return blockState.getValue(BlockStateProperties.LIT) ? lightLevel : 0;
        };
    }
}

 

Edited by Majd123mc
Solved
Link to comment
Share on other sites

3 hours ago, Majd123mc said:

Am I doing something wrong? Should I be extending something else? What else should I do?

you should not use refelection to set the Field, overwrite all methods that use the vanilla 'fluid' Field,
and copy the code of vanilla and replace the vanilla Field with LiquidBlock#getFluid

The methods you need to overwrite:

  • LiquidBlock#isPathfindable
  • LiquidBlock#skipRendering
  • LiquidBlock#onPlace
  • LiquidBlock#updateShape
  • LiquidBlock#neighborChanged
  • LiquidBlock#shouldSpreadLiquid (AT required)
  • LiquidBlock#pickupBlock
  • LiquidBlock#getPickupSound
Edited by Luis_ST
  • Thanks 1
Link to comment
Share on other sites

The bucket item should be pretty straight forward and is handled in a general purpose registry file. I basically just copied the vanilla water bucket registry, and changed to what I needed. The fluid block and registry however gave me some headache. You prolly want to adapt to changes in 1.17+, but most of the code should be working out of the box.

Fluid block:

 
	public class BlockCrudeOil extends FlowingFluidBlock {
	    public BlockCrudeOil(Object object, Properties props) {
        super(() -> (FlowingFluid) RegisterFluid.OIL_FLUID.get(), props
                        .doesNotBlockMovement()
                        .hardnessAndResistance(100f)
                        .noDrops()
                    );
    }
    
    @Override
    public boolean canHarvestBlock(BlockState state, IBlockReader world, BlockPos pos, PlayerEntity player)
    {
        return false;
    }
    
    @Override
    public int getFlammability(BlockState state, IBlockReader world, BlockPos pos, Direction face)
    {
        return 300;
    }
    
    @Override
    public boolean isFlammable(BlockState state, IBlockReader world, BlockPos pos, Direction face)
    {
        return true;
    }
    
    public int getFireSpreadSpeed(BlockState state, IBlockReader world, BlockPos pos, Direction face)
    {
        return 100;
    }
    
    public boolean canDisplace(FluidState fluidState, IBlockReader blockReader, BlockPos pos, Fluid fluid, Direction direction) 
    {
        return true;
    }    
    
}

Fluid registry:

 
	public class RegisterFluid{
    
    public static final ResourceLocation OIL_STILL_RL = new ResourceLocation("fluid/oil_still");
    public static final ResourceLocation OIL_FLOWING_RL = new ResourceLocation("fluid/oil_flow");
    public static final ResourceLocation OIL_OVERLAY_RL = new ResourceLocation("fluid/oil_overlay");
    
    public static final Material MATOIL = (new Material.Builder(MaterialColor.TNT)).doesNotBlockMovement().notSolid().replaceable().liquid().build();
	    public static final DeferredRegister<Fluid> FLUIDS
            = DeferredRegister.create(ForgeRegistries.FLUIDS, MatLibMain.MODID);   
	    public static final RegistryObject<FlowingFluid> OIL_FLUID
            = FLUIDS.register("oil_fluid", () -> new ForgeFlowingFluid.Source(RegisterFluid.OIL_PROPERTIES));
	    public static final RegistryObject<FlowingFluid> OIL_FLOWING
            = FLUIDS.register("oil_flowing", () -> new ForgeFlowingFluid.Flowing(RegisterFluid.OIL_PROPERTIES));
	    public static final ForgeFlowingFluid.Properties OIL_PROPERTIES = new ForgeFlowingFluid.Properties(
            () -> OIL_FLUID.get(), () -> OIL_FLOWING.get(), FluidAttributes.builder(OIL_STILL_RL, OIL_FLOWING_RL)
            .density(800).temperature(300).viscosity(10000).sound(SoundEvents.ITEM_HONEY_BOTTLE_DRINK).overlay(OIL_OVERLAY_RL)
            .color(0xff000000)).slopeFindDistance(2).levelDecreasePerBlock(2).tickRate(45).explosionResistance(100f)
            .block(() -> RegisterFluid.OIL_BLOCK.get()).bucket(() -> RegisterMain.BUCKETOIL.get());
    
    public static class Source extends ForgeFlowingFluid.Source {
        public Source() {
            super(OIL_PROPERTIES);
        }
	        public int getTickDelay(IWorldReader world) {
            return 20;
        }  
	    }    
    
    public static final RegistryObject<FlowingFluidBlock> OIL_BLOCK = RegisterMain.BLOCKS.register("crudeoil",
            () -> new BlockCrudeOil(null, AbstractBlock.Properties.create(RegisterFluid.MATOIL)));//null was = () -> new FlowingFluidBlock(() -> MatLibFluidOil.OIL_FLUID.get(),     
	    public static void register(IEventBus eventBus) {
        FLUIDS.register(eventBus);
    } 
    
} 
	

 

Edited by Cratthorax
  • Thanks 1
Link to comment
Share on other sites

Thanks for the help everybody! I tried this and although the block did register, the fluid just appears as a flat plane you can only see if you break the block under it.

I tried debugging it as much as I could but alas I couldn't solve it

Here is the code for my "fixed" liquidblock as suggested by Luis_ST:

package com.hotmail.majdroaydi.minitech.blocks;

import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.FluidTags;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.LiquidBlock;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.FlowingFluid;
import net.minecraft.world.level.pathfinder.PathComputationType;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.Shapes;
import net.minecraft.world.phys.shapes.VoxelShape;

import java.util.Optional;
import java.util.function.Supplier;

public class ForgeLiquidBlock extends LiquidBlock {
	public ForgeLiquidBlock(Supplier<? extends FlowingFluid> supplier, Properties properties) {
		super(supplier, properties);
	}

	@Override
	public VoxelShape getCollisionShape(BlockState p_54760_, BlockGetter p_54761_, BlockPos p_54762_, CollisionContext p_54763_) {
		return p_54763_.isAbove(STABLE_SHAPE, p_54762_, true) && p_54760_.getValue(LEVEL) == 0 && p_54763_.canStandOnFluid(p_54761_.getFluidState(p_54762_.above()), getFluid()) ? STABLE_SHAPE : Shapes.empty();
	}

	@Override
	public boolean isPathfindable(BlockState p_54704_, BlockGetter p_54705_, BlockPos p_54706_, PathComputationType p_54707_) {
		return !getFluid().is(FluidTags.LAVA);
	}

	@Override
	public boolean skipRendering(BlockState p_54716_, BlockState p_54717_, Direction p_54718_) {
		return p_54717_.getFluidState().getType().isSame(getFluid());
	}

	@Override
	public void onPlace(BlockState p_54754_, Level p_54755_, BlockPos p_54756_, BlockState p_54757_, boolean p_54758_) {
		if (this.shouldSpreadLiquid(p_54755_, p_54756_, p_54754_)) {
			p_54755_.getLiquidTicks().scheduleTick(p_54756_, p_54754_.getFluidState().getType(), getFluid().getTickDelay(p_54755_));
		}

	}

	@Override
	public BlockState updateShape(BlockState p_54723_, Direction p_54724_, BlockState p_54725_, LevelAccessor p_54726_, BlockPos p_54727_, BlockPos p_54728_) {
		if (p_54723_.getFluidState().isSource() || p_54725_.getFluidState().isSource()) {
			p_54726_.getLiquidTicks().scheduleTick(p_54727_, p_54723_.getFluidState().getType(), getFluid().getTickDelay(p_54726_));
		}

		//return super.updateShape(p_54723_, p_54724_, p_54725_, p_54726_, p_54727_, p_54728_);
		return p_54723_; // Calling super.updateShape will just call LiquidBlock's updateShape, not what we are looking for! Thankfully, Block.updateShape, simply enough, just returns the first parameter.
	}

	@Override
	public void neighborChanged(BlockState p_54709_, Level p_54710_, BlockPos p_54711_, Block p_54712_, BlockPos p_54713_, boolean p_54714_) {
		if (this.shouldSpreadLiquid(p_54710_, p_54711_, p_54709_)) {
			p_54710_.getLiquidTicks().scheduleTick(p_54711_, p_54709_.getFluidState().getType(), getFluid().getTickDelay(p_54710_));
		}

	}

	private boolean shouldSpreadLiquid(Level p_54697_, BlockPos p_54698_, BlockState p_54699_) {
		if (getFluid().is(FluidTags.LAVA)) {
			boolean flag = p_54697_.getBlockState(p_54698_.below()).is(Blocks.SOUL_SOIL);

			for(Direction direction : POSSIBLE_FLOW_DIRECTIONS) {
				BlockPos blockpos = p_54698_.relative(direction.getOpposite());
				if (p_54697_.getFluidState(blockpos).is(FluidTags.WATER)) {
					Block block = p_54697_.getFluidState(p_54698_).isSource() ? Blocks.OBSIDIAN : Blocks.COBBLESTONE;
					p_54697_.setBlockAndUpdate(p_54698_, net.minecraftforge.event.ForgeEventFactory.fireFluidPlaceBlockEvent(p_54697_, p_54698_, p_54698_, block.defaultBlockState()));
					this.fizz(p_54697_, p_54698_);
					return false;
				}

				if (flag && p_54697_.getBlockState(blockpos).is(Blocks.BLUE_ICE)) {
					p_54697_.setBlockAndUpdate(p_54698_, net.minecraftforge.event.ForgeEventFactory.fireFluidPlaceBlockEvent(p_54697_, p_54698_, p_54698_, Blocks.BASALT.defaultBlockState()));
					this.fizz(p_54697_, p_54698_);
					return false;
				}
			}
		}

		return true;
	}

	private void fizz(LevelAccessor p_54701_, BlockPos p_54702_) {
		p_54701_.levelEvent(1501, p_54702_, 0);
	}

	@Override
	public ItemStack pickupBlock(LevelAccessor p_153772_, BlockPos p_153773_, BlockState p_153774_) {
		if (p_153774_.getValue(LEVEL) == 0) {
			p_153772_.setBlock(p_153773_, Blocks.AIR.defaultBlockState(), 11);
			return new ItemStack(getFluid().getBucket());
		} else {
			return ItemStack.EMPTY;
		}
	}

	@Override
	public Optional<SoundEvent> getPickupSound() {
		return getFluid().getPickupSound();
	}
}

The code for my OilFluid can be found above.

Link to comment
Share on other sites

Thank you everybody, I have figured out the cause. I was accidentally passing in the constructor for the Fluids instead of the RegistryObject.

I changed:

super(new ForgeFlowingFluid.Properties(
				OilFluid.Source::new,
				OilFluid.Flowing::new,

to:

super(new ForgeFlowingFluid.Properties(
				ModFluids.OIL,
				ModFluids.FLOWING_OIL,

And now the fluid actually works! But it doesn't spread though, I think I'd be able to figured it out from now. Thanks a lot Luis_ST and Cratthorax!

Link to comment
Share on other sites

Yeah, the whole registry process can be quite confusing and daunting for how MC is working nowadays, but once you get the grasp of it, it actually saves a whole lot of effort, and quantity of code. I'd spend 3 days+ to actually figure I had to apply the getter(.get())[<-- is this even named getter?], to any of the .class references, because stupid Eclipse refused to de-obfuscate the source of problems. It was just making stupid a** auto fix suggestions, that didn't help at all. Google found the answer quite often though.

And don't even get me started when I was trying to implement the Oil to world generation. I was literally tearing my hair out for days.

But don't give up. We're not the only ones dealing with the reinvention of MC code wheel. I mean I get it. There's always room for improvements. But a wheel is just a wheel, right?

Edited by Cratthorax
  • Thanks 1
Link to comment
Share on other sites

  • Majd123mc changed the title to [CLOSED] [1.17.1] How to/Fluids not working
  • Majd123mc changed the title to [SOLVED] [1.17.1] How to/Fluids not working
  • 1 month later...
36 minutes ago, LuisAduana said:

Can you share how your classes looks like? I have a problem. I can set on the ground the LiquidBlock but it "breaks" instantly.

Did you create your own LiquidBlock and did you replace all vanilla fluid Field with the getter for the Forge Field?

If yes show your code (fo this in your town thread)

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share



  • Recently Browsing

    No registered users viewing this page.

  • Posts

    • Launcher screenshot: https://tinypic.host/i/YL1x  Launcher Log: https://pastebin.com/WLFuyCMY  I'm not really sure which log would be considered the complete log so these are just all of the logs I have Launcher cef log: https://pastebin.com/xQ3ZeeKd  Debug Log: https://pastebin.com/BSeKG56y  And this one is under "latest": https://pastebin.com/ABSYWX3N 
    • I am trying to create a custom horse, but I am getting an error in bakeLayer.     ModEntityRenderer @Mod.EventBusSubscriber( modid = TutorialMod.MOD_ID, value = {Dist.CLIENT}, bus = Mod.EventBusSubscriber.Bus.MOD ) @OnlyIn(Dist.CLIENT) public class ModEntityRenderers{ private static final Set<ModelLayerLocation> ALL_MODELS = Sets.newHashSet(); public static ModelLayerLocation TUTORIAL_PIG_LAYER = new ModelLayerLocation(new ResourceLocation(TutorialMod.MOD_ID, "tutorial_pig"), "tutorial_pig"); public static ModelLayerLocation TUTORIAL_HORSE_LAYER = new ModelLayerLocation(new ResourceLocation(TutorialMod.MOD_ID, "tutorial_horse"), "tutorial_horse"); public static final ModelLayerLocation HORSEE = register("tutorial_horse"); private static ModelLayerLocation register(String p_171294_) { return register(p_171294_, "main"); } private static ModelLayerLocation register(String p_171296_, String p_171297_) { ModelLayerLocation modellayerlocation = createLocation(p_171296_, p_171297_); if (!ALL_MODELS.add(modellayerlocation)) { throw new IllegalStateException("Duplicate registration for " + modellayerlocation); } else { return modellayerlocation; } } private static ModelLayerLocation createLocation(String p_171301_, String p_171302_) { return new ModelLayerLocation(new ResourceLocation("minecraft", p_171301_), p_171302_); } public static void init() { } //registry list @SubscribeEvent public static void registerEntityRenders(EntityRenderersEvent.RegisterRenderers event) { event.registerEntityRenderer(ModEntityType.TUTORIAL_PIG, TutorialPigRenderer::new); event.registerEntityRenderer(ModEntityType.TUTORIAL_HORSE, TutorialHorseRenderer::new); } //renderer list @SubscribeEvent public static void registerLayerDefinition(EntityRenderersEvent.RegisterLayerDefinitions event) { LayerDefinition ModlayerTutorialHorse = LayerDefinition.create(TutorialHorseModel.createBodyMesh(CubeDeformation.NONE), 64, 64); ImmutableMap.Builder<ModelLayerLocation, LayerDefinition> builder = ImmutableMap.builder(); event.registerLayerDefinition(TUTORIAL_PIG_LAYER, TutorialPigModel::createBodyLayer); // event.registerLayerDefinition(TUTORIAL_HORSE_LAYER, TutorialHorseModel::createMesh); builder.put(HORSEE, ModlayerTutorialHorse); } }   Model @OnlyIn(Dist.CLIENT) public class TutorialHorseModel<T extends AbstractHorse> extends AgeableListModel<T> { private static final float DEG_125 = 2.1816616F; private static final float DEG_60 = ((float)Math.PI / 3F); private static final float DEG_45 = ((float)Math.PI / 4F); private static final float DEG_30 = ((float)Math.PI / 6F); private static final float DEG_15 = 0.2617994F; protected static final String HEAD_PARTS = "head_parts"; private static final String LEFT_HIND_BABY_LEG = "left_hind_baby_leg"; private static final String RIGHT_HIND_BABY_LEG = "right_hind_baby_leg"; private static final String LEFT_FRONT_BABY_LEG = "left_front_baby_leg"; private static final String RIGHT_FRONT_BABY_LEG = "right_front_baby_leg"; private static final String SADDLE = "saddle"; private static final String LEFT_SADDLE_MOUTH = "left_saddle_mouth"; private static final String LEFT_SADDLE_LINE = "left_saddle_line"; private static final String RIGHT_SADDLE_MOUTH = "right_saddle_mouth"; private static final String RIGHT_SADDLE_LINE = "right_saddle_line"; private static final String HEAD_SADDLE = "head_saddle"; private static final String MOUTH_SADDLE_WRAP = "mouth_saddle_wrap"; protected final ModelPart body; protected final ModelPart headParts; private final ModelPart rightHindLeg; private final ModelPart leftHindLeg; private final ModelPart rightFrontLeg; private final ModelPart leftFrontLeg; private final ModelPart rightHindBabyLeg; private final ModelPart leftHindBabyLeg; private final ModelPart rightFrontBabyLeg; private final ModelPart leftFrontBabyLeg; private final ModelPart tail; private final ModelPart[] saddleParts; private final ModelPart[] ridingParts; public TutorialHorseModel(ModelPart p_170668_) { super(true, 16.2F, 1.36F, 2.7272F, 2.0F, 20.0F); this.body = p_170668_.getChild("body"); this.headParts = p_170668_.getChild("head_parts"); this.rightHindLeg = p_170668_.getChild("right_hind_leg"); this.leftHindLeg = p_170668_.getChild("left_hind_leg"); this.rightFrontLeg = p_170668_.getChild("right_front_leg"); this.leftFrontLeg = p_170668_.getChild("left_front_leg"); this.rightHindBabyLeg = p_170668_.getChild("right_hind_baby_leg"); this.leftHindBabyLeg = p_170668_.getChild("left_hind_baby_leg"); this.rightFrontBabyLeg = p_170668_.getChild("right_front_baby_leg"); this.leftFrontBabyLeg = p_170668_.getChild("left_front_baby_leg"); this.tail = this.body.getChild("tail"); ModelPart modelpart = this.body.getChild("saddle"); ModelPart modelpart1 = this.headParts.getChild("left_saddle_mouth"); ModelPart modelpart2 = this.headParts.getChild("right_saddle_mouth"); ModelPart modelpart3 = this.headParts.getChild("left_saddle_line"); ModelPart modelpart4 = this.headParts.getChild("right_saddle_line"); ModelPart modelpart5 = this.headParts.getChild("head_saddle"); ModelPart modelpart6 = this.headParts.getChild("mouth_saddle_wrap"); this.saddleParts = new ModelPart[]{modelpart, modelpart1, modelpart2, modelpart5, modelpart6}; this.ridingParts = new ModelPart[]{modelpart3, modelpart4}; } public static MeshDefinition createBodyMesh(CubeDeformation p_170670_) { MeshDefinition meshdefinition = new MeshDefinition(); PartDefinition partdefinition = meshdefinition.getRoot(); PartDefinition partdefinition1 = partdefinition.addOrReplaceChild("body", CubeListBuilder.create().texOffs(0, 32).addBox(-5.0F, -8.0F, -17.0F, 10.0F, 10.0F, 22.0F, new CubeDeformation(0.05F)), PartPose.offset(0.0F, 11.0F, 5.0F)); PartDefinition partdefinition2 = partdefinition.addOrReplaceChild("head_parts", CubeListBuilder.create().texOffs(0, 35).addBox(-2.05F, -6.0F, -2.0F, 4.0F, 12.0F, 7.0F), PartPose.offsetAndRotation(0.0F, 4.0F, -12.0F, ((float)Math.PI / 6F), 0.0F, 0.0F)); PartDefinition partdefinition3 = partdefinition2.addOrReplaceChild("head", CubeListBuilder.create().texOffs(0, 13).addBox(-3.0F, -11.0F, -2.0F, 6.0F, 5.0F, 7.0F, p_170670_), PartPose.ZERO); partdefinition2.addOrReplaceChild("mane", CubeListBuilder.create().texOffs(56, 36).addBox(-1.0F, -11.0F, 5.01F, 2.0F, 16.0F, 2.0F, p_170670_), PartPose.ZERO); partdefinition2.addOrReplaceChild("upper_mouth", CubeListBuilder.create().texOffs(0, 25).addBox(-2.0F, -11.0F, -7.0F, 4.0F, 5.0F, 5.0F, p_170670_), PartPose.ZERO); partdefinition.addOrReplaceChild("left_hind_leg", CubeListBuilder.create().texOffs(48, 21).mirror().addBox(-3.0F, -1.01F, -1.0F, 4.0F, 11.0F, 4.0F, p_170670_), PartPose.offset(4.0F, 14.0F, 7.0F)); partdefinition.addOrReplaceChild("right_hind_leg", CubeListBuilder.create().texOffs(48, 21).addBox(-1.0F, -1.01F, -1.0F, 4.0F, 11.0F, 4.0F, p_170670_), PartPose.offset(-4.0F, 14.0F, 7.0F)); partdefinition.addOrReplaceChild("left_front_leg", CubeListBuilder.create().texOffs(48, 21).mirror().addBox(-3.0F, -1.01F, -1.9F, 4.0F, 11.0F, 4.0F, p_170670_), PartPose.offset(4.0F, 14.0F, -12.0F)); partdefinition.addOrReplaceChild("right_front_leg", CubeListBuilder.create().texOffs(48, 21).addBox(-1.0F, -1.01F, -1.9F, 4.0F, 11.0F, 4.0F, p_170670_), PartPose.offset(-4.0F, 14.0F, -12.0F)); CubeDeformation cubedeformation = p_170670_.extend(0.0F, 5.5F, 0.0F); partdefinition.addOrReplaceChild("left_hind_baby_leg", CubeListBuilder.create().texOffs(48, 21).mirror().addBox(-3.0F, -1.01F, -1.0F, 4.0F, 11.0F, 4.0F, cubedeformation), PartPose.offset(4.0F, 14.0F, 7.0F)); partdefinition.addOrReplaceChild("right_hind_baby_leg", CubeListBuilder.create().texOffs(48, 21).addBox(-1.0F, -1.01F, -1.0F, 4.0F, 11.0F, 4.0F, cubedeformation), PartPose.offset(-4.0F, 14.0F, 7.0F)); partdefinition.addOrReplaceChild("left_front_baby_leg", CubeListBuilder.create().texOffs(48, 21).mirror().addBox(-3.0F, -1.01F, -1.9F, 4.0F, 11.0F, 4.0F, cubedeformation), PartPose.offset(4.0F, 14.0F, -12.0F)); partdefinition.addOrReplaceChild("right_front_baby_leg", CubeListBuilder.create().texOffs(48, 21).addBox(-1.0F, -1.01F, -1.9F, 4.0F, 11.0F, 4.0F, cubedeformation), PartPose.offset(-4.0F, 14.0F, -12.0F)); partdefinition1.addOrReplaceChild("tail", CubeListBuilder.create().texOffs(42, 36).addBox(-1.5F, 0.0F, 0.0F, 3.0F, 14.0F, 4.0F, p_170670_), PartPose.offsetAndRotation(0.0F, -5.0F, 2.0F, ((float)Math.PI / 6F), 0.0F, 0.0F)); partdefinition1.addOrReplaceChild("saddle", CubeListBuilder.create().texOffs(26, 0).addBox(-5.0F, -8.0F, -9.0F, 10.0F, 9.0F, 9.0F, new CubeDeformation(0.5F)), PartPose.ZERO); partdefinition2.addOrReplaceChild("left_saddle_mouth", CubeListBuilder.create().texOffs(29, 5).addBox(2.0F, -9.0F, -6.0F, 1.0F, 2.0F, 2.0F, p_170670_), PartPose.ZERO); partdefinition2.addOrReplaceChild("right_saddle_mouth", CubeListBuilder.create().texOffs(29, 5).addBox(-3.0F, -9.0F, -6.0F, 1.0F, 2.0F, 2.0F, p_170670_), PartPose.ZERO); partdefinition2.addOrReplaceChild("left_saddle_line", CubeListBuilder.create().texOffs(32, 2).addBox(3.1F, -6.0F, -8.0F, 0.0F, 3.0F, 16.0F, p_170670_), PartPose.rotation((-(float)Math.PI / 6F), 0.0F, 0.0F)); partdefinition2.addOrReplaceChild("right_saddle_line", CubeListBuilder.create().texOffs(32, 2).addBox(-3.1F, -6.0F, -8.0F, 0.0F, 3.0F, 16.0F, p_170670_), PartPose.rotation((-(float)Math.PI / 6F), 0.0F, 0.0F)); partdefinition2.addOrReplaceChild("head_saddle", CubeListBuilder.create().texOffs(1, 1).addBox(-3.0F, -11.0F, -1.9F, 6.0F, 5.0F, 6.0F, new CubeDeformation(0.2F)), PartPose.ZERO); partdefinition2.addOrReplaceChild("mouth_saddle_wrap", CubeListBuilder.create().texOffs(19, 0).addBox(-2.0F, -11.0F, -4.0F, 4.0F, 5.0F, 2.0F, new CubeDeformation(0.2F)), PartPose.ZERO); partdefinition3.addOrReplaceChild("left_ear", CubeListBuilder.create().texOffs(19, 16).addBox(0.55F, -13.0F, 4.0F, 2.0F, 3.0F, 1.0F, new CubeDeformation(-0.001F)), PartPose.ZERO); partdefinition3.addOrReplaceChild("right_ear", CubeListBuilder.create().texOffs(19, 16).addBox(-2.55F, -13.0F, 4.0F, 2.0F, 3.0F, 1.0F, new CubeDeformation(-0.001F)), PartPose.ZERO); return meshdefinition; } public void setupAnim(T p_102785_, float p_102786_, float p_102787_, float p_102788_, float p_102789_, float p_102790_) { boolean flag = p_102785_.isSaddled(); boolean flag1 = p_102785_.isVehicle(); for(ModelPart modelpart : this.saddleParts) { modelpart.visible = flag; } for(ModelPart modelpart1 : this.ridingParts) { modelpart1.visible = flag1 && flag; } this.body.y = 11.0F; } public Iterable<ModelPart> headParts() { return ImmutableList.of(this.headParts); } protected Iterable<ModelPart> bodyParts() { return ImmutableList.of(this.body, this.rightHindLeg, this.leftHindLeg, this.rightFrontLeg, this.leftFrontLeg, this.rightHindBabyLeg, this.leftHindBabyLeg, this.rightFrontBabyLeg, this.leftFrontBabyLeg); } public void prepareMobModel(T p_102780_, float p_102781_, float p_102782_, float p_102783_) { super.prepareMobModel(p_102780_, p_102781_, p_102782_, p_102783_); float f = Mth.rotlerp(p_102780_.yBodyRotO, p_102780_.yBodyRot, p_102783_); float f1 = Mth.rotlerp(p_102780_.yHeadRotO, p_102780_.yHeadRot, p_102783_); float f2 = Mth.lerp(p_102783_, p_102780_.xRotO, p_102780_.getXRot()); float f3 = f1 - f; float f4 = f2 * ((float)Math.PI / 180F); if (f3 > 20.0F) { f3 = 20.0F; } if (f3 < -20.0F) { f3 = -20.0F; } if (p_102782_ > 0.2F) { f4 += Mth.cos(p_102781_ * 0.4F) * 0.15F * p_102782_; } float f5 = p_102780_.getEatAnim(p_102783_); float f6 = p_102780_.getStandAnim(p_102783_); float f7 = 1.0F - f6; float f8 = p_102780_.getMouthAnim(p_102783_); boolean flag = p_102780_.tailCounter != 0; float f9 = (float)p_102780_.tickCount + p_102783_; this.headParts.y = 4.0F; this.headParts.z = -12.0F; this.body.xRot = 0.0F; this.headParts.xRot = ((float)Math.PI / 6F) + f4; this.headParts.yRot = f3 * ((float)Math.PI / 180F); float f10 = p_102780_.isInWater() ? 0.2F : 1.0F; float f11 = Mth.cos(f10 * p_102781_ * 0.6662F + (float)Math.PI); float f12 = f11 * 0.8F * p_102782_; float f13 = (1.0F - Math.max(f6, f5)) * (((float)Math.PI / 6F) + f4 + f8 * Mth.sin(f9) * 0.05F); this.headParts.xRot = f6 * (0.2617994F + f4) + f5 * (2.1816616F + Mth.sin(f9) * 0.05F) + f13; this.headParts.yRot = f6 * f3 * ((float)Math.PI / 180F) + (1.0F - Math.max(f6, f5)) * this.headParts.yRot; this.headParts.y = f6 * -4.0F + f5 * 11.0F + (1.0F - Math.max(f6, f5)) * this.headParts.y; this.headParts.z = f6 * -4.0F + f5 * -12.0F + (1.0F - Math.max(f6, f5)) * this.headParts.z; this.body.xRot = f6 * (-(float)Math.PI / 4F) + f7 * this.body.xRot; float f14 = 0.2617994F * f6; float f15 = Mth.cos(f9 * 0.6F + (float)Math.PI); this.leftFrontLeg.y = 2.0F * f6 + 14.0F * f7; this.leftFrontLeg.z = -6.0F * f6 - 10.0F * f7; this.rightFrontLeg.y = this.leftFrontLeg.y; this.rightFrontLeg.z = this.leftFrontLeg.z; float f16 = ((-(float)Math.PI / 3F) + f15) * f6 + f12 * f7; float f17 = ((-(float)Math.PI / 3F) - f15) * f6 - f12 * f7; this.leftHindLeg.xRot = f14 - f11 * 0.5F * p_102782_ * f7; this.rightHindLeg.xRot = f14 + f11 * 0.5F * p_102782_ * f7; this.leftFrontLeg.xRot = f16; this.rightFrontLeg.xRot = f17; this.tail.xRot = ((float)Math.PI / 6F) + p_102782_ * 0.75F; this.tail.y = -5.0F + p_102782_; this.tail.z = 2.0F + p_102782_ * 2.0F; if (flag) { this.tail.yRot = Mth.cos(f9 * 0.7F); } else { this.tail.yRot = 0.0F; } this.rightHindBabyLeg.y = this.rightHindLeg.y; this.rightHindBabyLeg.z = this.rightHindLeg.z; this.rightHindBabyLeg.xRot = this.rightHindLeg.xRot; this.leftHindBabyLeg.y = this.leftHindLeg.y; this.leftHindBabyLeg.z = this.leftHindLeg.z; this.leftHindBabyLeg.xRot = this.leftHindLeg.xRot; this.rightFrontBabyLeg.y = this.rightFrontLeg.y; this.rightFrontBabyLeg.z = this.rightFrontLeg.z; this.rightFrontBabyLeg.xRot = this.rightFrontLeg.xRot; this.leftFrontBabyLeg.y = this.leftFrontLeg.y; this.leftFrontBabyLeg.z = this.leftFrontLeg.z; this.leftFrontBabyLeg.xRot = this.leftFrontLeg.xRot; boolean flag1 = p_102780_.isBaby(); this.rightHindLeg.visible = !flag1; this.leftHindLeg.visible = !flag1; this.rightFrontLeg.visible = !flag1; this.leftFrontLeg.visible = !flag1; this.rightHindBabyLeg.visible = flag1; this.leftHindBabyLeg.visible = flag1; this.rightFrontBabyLeg.visible = flag1; this.leftFrontBabyLeg.visible = flag1; this.body.y = flag1 ? 10.8F : 0.0F; } }   Renderer @OnlyIn(Dist.CLIENT) public final class TutorialHorseRenderer extends ModAbstractHorseRenderer<TutorialHorse, TutorialHorseModel<TutorialHorse>> { private static final Map<Variant, ResourceLocation> LOCATION_BY_VARIANT = Util.make(Maps.newEnumMap(Variant.class), (p_114874_) -> { p_114874_.put(Variant.WHITE, new ResourceLocation("textures/entity/horse/horse_white.png")); p_114874_.put(Variant.CREAMY, new ResourceLocation("textures/entity/horse/horse_creamy.png")); p_114874_.put(Variant.CHESTNUT, new ResourceLocation("textures/entity/horse/horse_chestnut.png")); p_114874_.put(Variant.BROWN, new ResourceLocation("textures/entity/horse/horse_brown.png")); p_114874_.put(Variant.BLACK, new ResourceLocation("textures/entity/horse/horse_black.png")); p_114874_.put(Variant.GRAY, new ResourceLocation("textures/entity/horse/horse_gray.png")); p_114874_.put(Variant.DARKBROWN, new ResourceLocation("textures/entity/horse/horse_darkbrown.png")); }); public TutorialHorseRenderer(EntityRendererProvider.Context p_174167_) { super(p_174167_, new TutorialHorseModel<>(p_174167_.bakeLayer(ModEntityRenderers.HORSEE)), 1.1F); //this.addLayer(new HorseMarkingLayer(this)); //this.addLayer(new HorseArmorLayer(this, p_174167_.getModelSet())); } public ResourceLocation getTextureLocation(TutorialHorse p_114872_) { return LOCATION_BY_VARIANT.get(p_114872_.getVariant()); } } I'm trying to make the code equivalent to Vanilla, but I think I'm wrong. Please help me
    • Also please show the registration of the MenuType.
    • Same as before, NetworkHooks.openGui.
  • Topics

  • Who's Online (See full list)

×
×
  • Create New...

Important Information

By using this site, you agree to our Privacy Policy.