Jump to content

Recommended Posts

Posted

I'm currently trying to use the animation system to move the sentry gun back and forth which I got it to animate in my inventory, but when I place it down its just a static block. All I did was just copy the code from the MinecraftForge GitHub on this but I can't figure out why this is happening.

 

Here is the code:

 

Main

@Mod(modid = Refrence.MODID, name = Refrence.MODID, version = Refrence.VERSION)
public class Main {
@SidedProxy(clientSide = Refrence.CLIENT_PROXY, serverSide = Refrence.COMMON_PROXY)
public static CommonProxy proxy;

@Instance(Refrence.MODID)
public static Main instance;

@EventHandler
public void preInit (FMLPreInitializationEvent event) {

	TFCBlocks.init();
	TFCBlocks.register();

	proxy.init();

	ClientRegistry.bindTileEntitySpecialRenderer(TileEntitySentry.class, new AnimationTESR<TileEntitySentry>() {
		@Override
		public void handleEvents(TileEntitySentry te, float time, Iterable<Event> pastEvents) {
			super.handleEvents(te, time, pastEvents);
			te.handleEvents(time, pastEvents);
		}
	});
}

@EventHandler
public void init (FMLInitializationEvent event) {
	GameRegistry.registerTileEntity(TileEntitySentry.class, Refrence.MODID + ":sentry_tile");
}
}

 

ClientProxy

public class ClientProxy extends CommonProxy {
@Override
public void init () {
	TFCBlocks.registerRenders();
}

@Override
public IAnimationStateMachine load(ResourceLocation location, ImmutableMap<String, ITimeValue> parameters) {
	return ModelLoaderRegistry.loadASM(location, parameters);
}
}

 

TFCBlocks

public class TFCBlocks {
public static Block sentry;

public static void init () {
	sentry = new BlockSentry(Material.IRON).setUnlocalizedName("sentry").setCreativeTab(tab);
}

public static void register () {
	//registerBlock(sentry);
	GameRegistry.register(sentry.setRegistryName(sentry.getUnlocalizedName().substring(5)));
	ItemBlockSentry sen = new ItemBlockSentry(sentry);
	sen.setRegistryName(sentry.getRegistryName());
	GameRegistry.register(sen);
}

public static void registerRenders () {
	registerRender(sentry);
}

public static void registerRender (Block block) {
	ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(block), 0, new ModelResourceLocation(Refrence.MODID + ":" + block.getUnlocalizedName().substring(5), "inventory"));
}
}

 

BlockSentry

public class BlockSentry extends Block implements ITileEntityProvider {
public BlockSentry(Material materialIn) {
	super(materialIn);
}

@Override
public boolean isFullCube (IBlockState state) {
	return false;
}

@Override
public boolean isOpaqueCube (IBlockState state) {
	return false;
}

@Nonnull
@Override
protected ExtendedBlockState createBlockState () {
	//return new ExtendedBlockState(this, new IProperty[] { Properties.StaticProperty }, new IUnlistedProperty[] { Properties.AnimationProperty });
	return new ExtendedBlockState(this, new IProperty[0], new IUnlistedProperty[] { Properties.AnimationProperty });
}

@Override
public boolean hasTileEntity (IBlockState state) {
	return true;
}

@Override
public TileEntity createNewTileEntity (World worldIn, int meta) {
	return new TileEntitySentry();
}
}

 

TileEntitySentry

public class TileEntitySentry extends TileEntity {
private final IAnimationStateMachine stateMachine;
private final VariableValue cycleLength = new VariableValue(4);
private final VariableValue clickTime = new VariableValue(Float.NEGATIVE_INFINITY);

public TileEntitySentry () {
	stateMachine = Main.proxy.load(new ResourceLocation(Refrence.MODID, "asms/block/sentry.json"), ImmutableMap.<String, ITimeValue>of("cycle_length", cycleLength, "click_time", clickTime));
}

public void handleEvents (float time, Iterable<Event> pastEvents) {
	for (Event event : pastEvents) {
		System.out.println("Event: " + event.event() + " " + event.offset() + " " + getPos() + " " + time);
	}
}

@Override
public boolean hasFastRenderer() {
	return true;
}

public void click (boolean sneaking) {
	if (stateMachine != null) {
		if (sneaking) {
			cycleLength.setValue(6 - cycleLength.apply(0));
		} else if (stateMachine.currentState().equals("default")) {
			float time = Animation.getWorldTime(getWorld(), Animation.getPartialTickTime());
			clickTime.setValue(time);
			stateMachine.transition("starting");
		} else if (stateMachine.currentState().equals("moving")) {
			clickTime.setValue(Animation.getWorldTime(getWorld(), Animation.getPartialTickTime()));
			stateMachine.transition("stopping");
		}
	}
}

@Override
public boolean hasCapability(Capability<?> capability, EnumFacing facing) {
	if (capability == CapabilityAnimation.ANIMATION_CAPABILITY) return true;
	return super.hasCapability(capability, facing);
}

@Override
public <T> T getCapability(Capability<T> capability, EnumFacing facing) {
	if (capability == CapabilityAnimation.ANIMATION_CAPABILITY) return CapabilityAnimation.ANIMATION_CAPABILITY.cast(stateMachine);
	return super.getCapability(capability, facing);
}
}

 

ItemBlockSentry

public class ItemBlockSentry extends ItemBlock {
public ItemBlockSentry (Block block) {
	super(block);
}

@Override
public ICapabilityProvider initCapabilities (ItemStack stack, NBTTagCompound nbt) {
	return new ItemAnimationHolder();
}
}

 

ItemAnimationHolder

public class ItemAnimationHolder implements ICapabilityProvider {
    private final VariableValue cycleLength = new VariableValue(4);

    private final IAnimationStateMachine asm = Main.proxy.load(new ResourceLocation(Refrence.MODID, "asms/block/sentry.json"), ImmutableMap.<String, ITimeValue>of("cycle_length", cycleLength));

    public boolean hasCapability (Capability<?> capability, EnumFacing facing) {
    	return capability == CapabilityAnimation.ANIMATION_CAPABILITY;
    }

public <T> T getCapability (Capability<T> capability, EnumFacing facing) {
    	if (capability == CapabilityAnimation.ANIMATION_CAPABILITY) return CapabilityAnimation.ANIMATION_CAPABILITY.cast(asm);
        return null;
}
}

 

armatures/block/sentry_gun

{
"joints": {
	"back": { "2": [1.0] },
	"gun": { "0": [1.0] },
	"barrel": { "1": [1.0] }
},
"clips": {
	"default": {
		"loop": false,
		"joint_clips": {},
		"events": {}
	},
	"moving": {
		"loop": true,
		"joint_clips": {
			"back": [{
				"variable": "axis_y",
				"type": "uniform",
				"interpolation": "nearest",
				"samples": [1]
			},
			{
				"variable": "angle",
				"type": "uniform",
				"interpolation": "linear",
				"samples": [
				0, 120, 240,
				0, 120, 240,
				0, 120, 240,
				0, 120, 240
				]
			}],
			"gun": [{
                    "variable": "axis_y",
                    "type": "uniform",
                    "interpolation": "nearest",
                    "samples": [1]
                },
                {
                    "variable": "angle",
                    "type": "uniform",
                    "interpolation": "linear",
                    "samples": [
                    0, 120, 240,
                    0, 120, 240,
                    0, 120, 240,
                    0, 120, 240
                    ]
                }],
                "barrel": [{
                    "variable": "axis_y",
                    "type": "uniform",
                    "interpolation": "nearest",
                    "samples": [1]
                },
                {
                    "variable": "angle",
                    "type": "uniform",
                    "interpolation": "linear",
                    "samples": [
                    0, 120, 240,
                    0, 120, 240,
                    0, 120, 240,
                    0, 120, 240
                    ]
                }]
		},
		"events": {
			"0.5": "boop"
		}
	}
}
}

 

asms/block/sentry

{
    "parameters": {
    	"world_to_cycle": [ "/", "#cycle_length"],
    	"round_cycle": [ "compose", [ "R", "#cycle_length" ], "#click_time" ],
    	"end_cycle": [ "-", "#round_cycle" ]
    },
    "clips": {
        "default": "tfc:block/sentry_gun@default",
        "starting": [ "trigger_positive", "#default", "#end_cycle", "!transition:moving" ],
        "moving": [ "apply", "tfc:block/sentry_gun@moving", "#world_to_cycle" ],
        "stopping": [ "trigger_positive", "#moving", "#end_cycle", "!transition:default" ]
    },
    "states": [
        "default",
        "starting",
        "moving",
        "stopping"
    ],
    "transitions": {
        "default": "starting",
        "starting": [ "moving" ],
        "moving": "stopping",
        "stopping": "default"
    },
    "start_state": "moving"
}

 

blockstate/sentry

{
"forge_marker": 1,
    "variants": {
        "normal": [{
        	"model": "tfc:sentry",
            "submodel": { "gun": { "model": "tfc:sentry_gun" } },
            "textures": { "color": "tfc:blocks/sentry_blue" }
        }],
        "inventory": [{
        	"model": "tfc:sentry",
        	"submodel": { "gun": { "model": "tfc:sentry_gun" } },
        	"textures": { "color": "tfc:blocks/sentry_blue" }
        }]
    }
}

 

Posted

You need to clean your code up.

I see you have client-only code, in your main.

ClientRegistry.bindTileEntitySpecialRenderer(TileEntitySentry.class, new AnimationTESR<TileEntitySentry>(). Hint is in the Client part of the method.

Your ClientProxy barely does anything related to rendering. Client is the only side that handles rendering. Do anything with rendering on the server-side, and oooops, crash.

You also need to do as the guide shows, and create a new Entity, for your Tile.

 

 

Also:

ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(block), 0, new ModelResourceLocation(Refrence.MODID + ":" + block.getUnlocalizedName().substring(5), "inventory"));

*Eye twitch*

In your IDE:

[*]Simply search for the interface "IForgeRegistryEntry"

[*]Read the documentation for RegistryNames

Also previously known as eAndPi.

"Pi, is there a station coming up where we can board your train of thought?" -Kronnn

Published Mods: Underworld

Handy links: Vic_'s Forge events Own WIP Tutorials.

Posted

You need to clean your code up.

I see you have client-only code, in your main.

ClientRegistry.bindTileEntitySpecialRenderer(TileEntitySentry.class, new AnimationTESR<TileEntitySentry>(). Hint is in the Client part of the method.

Your ClientProxy barely does anything related to rendering. Client is the only side that handles rendering. Do anything with rendering on the server-side, and oooops, crash.

You also need to do as the guide shows, and create a new Entity, for your Tile.

 

 

Also:

ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(block), 0, new ModelResourceLocation(Refrence.MODID + ":" + block.getUnlocalizedName().substring(5), "inventory"));

*Eye twitch*

In your IDE:

[*]Simply search for the interface "IForgeRegistryEntry"

[*]Read the documentation for RegistryNames

 

I've created an Entity for it and looked through the forge code and I don't see how the Entity connects with the Block. Here is the code I've added:

 

ModelLoader.setCustomModelResourceLocation(Item.REGISTRY.getObject(new ResourceLocation(Reference.MODID + ":" + sentry.getUnlocalizedName().substring(5))), 0, new ModelResourceLocation(Reference.MODID + ":" + sentry.getUnlocalizedName().substring(5), "inventory"));

 

ClientRegistry.bindTileEntitySpecialRenderer(TileEntitySentry.class, new AnimationTESR<TileEntitySentry>() {
		@Override
		public void handleEvents(TileEntitySentry te, float time, Iterable<Event> pastEvents) {
			super.handleEvents(te, time, pastEvents);
			te.handleEvents(time, pastEvents);
		}
	});

	EntityRegistry.registerModEntity(EntitySentry.class, "entity_sentry", 0, Main.instance, 54, 20, true);
	RenderingRegistry.registerEntityRenderingHandler(EntitySentry.class, new IRenderFactory<EntitySentry>() {
		@Override
		public Render<EntitySentry> createRenderFor(RenderManager manager) {
			ResourceLocation location = new ModelResourceLocation(new ResourceLocation(Reference.MODID, "sentry"), "entity");

			return new RenderLiving<EntitySentry>(manager, new AnimationModelBase<EntitySentry>(location, new VertexLighterSmoothAo(Minecraft.getMinecraft().getBlockColors())) {
				public void handleEvents(EntitySentry sentry, float time, Iterable<Event> pastEvents) {
					sentry.handleEvents(time, pastEvents);
				}}, 0.5F) {
				protected ResourceLocation getEntityTexture(EntitySentry entity) {
					return TextureMap.LOCATION_BLOCKS_TEXTURE;
				}
			};
		}
	});

 

public class EntitySentry extends EntityLiving {
private final IAnimationStateMachine asm;
private final VariableValue cycleLength = new VariableValue(getHealth() / 6);

public EntitySentry (World worldIn) {
	super(worldIn);

	setSize(1, 1);

	asm = Main.proxy.load(new ResourceLocation(Reference.MODID, "asms/block/sentry.json"), ImmutableMap.<String, ITimeValue>of("cycle_length", cycleLength));
}

public void handleEvents (float time, Iterable<Event> pastEvents) {}

@Override
public void onEntityUpdate() {
	super.onEntityUpdate();

	if (worldObj.isRemote && cycleLength != null) cycleLength.setValue(getHealth() / 5);
}

@Override
protected void applyEntityAttributes() {
	super.applyEntityAttributes();
	getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(60);
}

@Override
public boolean hasCapability(Capability<?> capability, EnumFacing facing) {
	if (capability == CapabilityAnimation.ANIMATION_CAPABILITY) return true;
	return super.hasCapability(capability, facing);
}

@Override
public <T> T getCapability(Capability<T> capability, EnumFacing facing) {
	if (capability == CapabilityAnimation.ANIMATION_CAPABILITY) return CapabilityAnimation.ANIMATION_CAPABILITY.cast(asm);
	return super.getCapability(capability, facing);
}
}

 

I also added this to the sentry blockstate

"entity": [{
            "model": "tfc:sentry",
            "submodel": { "gun": { "model": "tfc:sentry_gun" } }
        }]

Posted

The "connection" is made here:

ResourceLocation location = new ModelResourceLocation(new ResourceLocation(MODID, blockName), "entity");
return new RenderLiving<EntityChest>(manager, new net.minecraftforge.client.model.animation.AnimationModelBase<EntityChest>(location, new VertexLighterSmoothAo(Minecraft.getMinecraft().getBlockColors()))

 

The code -is- hard to read. It's dynamic in places, like here (blockName is, oddly enough, the name of the block the entity is supposed to be rendered as  ;) ), and then hard-coded names in other places.

 

I can't help much more atm, as I'm not too familiar with this type of rendering, though I'll probably sit down and tear the ModelAnimationDebug into their own proper damned classes, to get a better overview of it, in a few hours.

 

 

Oh, and once again:

*Eye twitch* x2

Fix that, please excuse my language, completely redundant, moronic, atrocious and gratuitous use of

modid + ":" + getUnlocalizedName().substring()

.

You have to use

setRegistryName(name)

for blocks and items. Instead of all that modid & substringing, just use "item(or block).getRegistryName()" and you are done.

getRegistryName() already returns "modid:name" for you. Just be sure to set the registryName first, then if you want the unlocalized name to mirror that, use getRegistryName().toString. Registry name is what you use for saying what is what, unlocalized name is purely to describe it in various languages.

"...Unlocalized names have NOTHING to do with unique modifiers."-Docmentation of setRegistryName().

I don't fault you for using it, I fault whatever piece of proverbial waste that keep producing tutorials that use that method.

Also previously known as eAndPi.

"Pi, is there a station coming up where we can board your train of thought?" -Kronnn

Published Mods: Underworld

Handy links: Vic_'s Forge events Own WIP Tutorials.

Posted

The "connection" is made here:

ResourceLocation location = new ModelResourceLocation(new ResourceLocation(MODID, blockName), "entity");
return new RenderLiving<EntityChest>(manager, new net.minecraftforge.client.model.animation.AnimationModelBase<EntityChest>(location, new VertexLighterSmoothAo(Minecraft.getMinecraft().getBlockColors()))

 

The code -is- hard to read. It's dynamic in places, like here (blockName is, oddly enough, the name of the block the entity is supposed to be rendered as  ;) ), and then hard-coded names in other places.

 

I can't help much more atm, as I'm not too familiar with this type of rendering, though I'll probably sit down and tear the ModelAnimationDebug into their own proper damned classes, to get a better overview of it, in a few hours.

 

 

Oh, and once again:

*Eye twitch* x2

Fix that, please excuse my language, completely redundant, moronic, atrocious and gratuitous use of

modid + ":" + getUnlocalizedName().substring()

.

You have to use

setRegistryName(name)

for blocks and items. Instead of all that modid & substringing, just use "item(or block).getRegistryName()" and you are done.

getRegistryName() already returns "modid:name" for you. Just be sure to set the registryName first, then if you want the unlocalized name to mirror that, use getRegistryName().toString. Registry name is what you use for saying what is what, unlocalized name is purely to describe it in various languages.

"...Unlocalized names have NOTHING to do with unique modifiers."-Docmentation of setRegistryName().

I don't fault you for using it, I fault whatever piece of proverbial waste that keep producing tutorials that use that method.

 

Sorry about that, I just used MrCrayFish's old tutorial around a year ago to update another mod and I just stuck with that format ever since. I'll switch as soon as I get this to work.

Posted

You won't be ABLE to get it to work without switching.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Posted

I feel like I should add, he wasn't saying that changing to registry names would fix everything, he was saying that even if everything else was perfect, it wouldn't work until you switched to registry names.  So basically, don't stop looking for answers yourself because that change didn't fix everything.

Guest
This topic is now closed to further replies.

Announcements



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • Version 1.19 - Forge 41.0.63 I want to create a wolf entity that I can ride, so far it seems to be working, but the problem is that when I get on the wolf, I can’t control it. I then discovered that the issue is that the server doesn’t detect that I’m riding the wolf, so I’m struggling with synchronization. However, it seems to not be working properly. As I understand it, the server receives the packet but doesn’t register it correctly. I’m a bit new to Java, and I’ll try to provide all the relevant code and prints *The comments and prints are translated by chatgpt since they were originally in Spanish* Thank you very much in advance No player is mounted, or the passenger is not a player. No player is mounted, or the passenger is not a player. No player is mounted, or the passenger is not a player. No player is mounted, or the passenger is not a player. No player is mounted, or the passenger is not a player. MountableWolfEntity package com.vals.valscraft.entity; import com.vals.valscraft.network.MountSyncPacket; import com.vals.valscraft.network.NetworkHandler; import net.minecraft.client.Minecraft; import net.minecraft.network.syncher.EntityDataAccessor; import net.minecraft.network.syncher.EntityDataSerializers; import net.minecraft.network.syncher.SynchedEntityData; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.Mob; import net.minecraft.world.entity.ai.attributes.AttributeSupplier; import net.minecraft.world.entity.ai.attributes.Attributes; import net.minecraft.world.entity.animal.Wolf; import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.Entity; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; import net.minecraft.world.level.Level; import net.minecraft.world.phys.Vec3; import net.minecraftforge.event.TickEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.network.PacketDistributor; public class MountableWolfEntity extends Wolf { private boolean hasSaddle; private static final EntityDataAccessor<Byte> DATA_ID_FLAGS = SynchedEntityData.defineId(MountableWolfEntity.class, EntityDataSerializers.BYTE); public MountableWolfEntity(EntityType<? extends Wolf> type, Level level) { super(type, level); this.hasSaddle = false; } @Override protected void defineSynchedData() { super.defineSynchedData(); this.entityData.define(DATA_ID_FLAGS, (byte)0); } public static AttributeSupplier.Builder createAttributes() { return Wolf.createAttributes() .add(Attributes.MAX_HEALTH, 20.0) .add(Attributes.MOVEMENT_SPEED, 0.3); } @Override public InteractionResult mobInteract(Player player, InteractionHand hand) { ItemStack itemstack = player.getItemInHand(hand); if (itemstack.getItem() == Items.SADDLE && !this.hasSaddle()) { if (!player.isCreative()) { itemstack.shrink(1); } this.setSaddle(true); return InteractionResult.SUCCESS; } else if (!level.isClientSide && this.hasSaddle()) { player.startRiding(this); MountSyncPacket packet = new MountSyncPacket(true); // 'true' means the player is mounted NetworkHandler.CHANNEL.sendToServer(packet); // Ensure the server handles the packet return InteractionResult.SUCCESS; } return InteractionResult.PASS; } @Override public void travel(Vec3 travelVector) { if (this.isVehicle() && this.getControllingPassenger() instanceof Player) { System.out.println("The wolf has a passenger."); System.out.println("The passenger is a player."); Player player = (Player) this.getControllingPassenger(); // Ensure the player is the controller this.setYRot(player.getYRot()); this.yRotO = this.getYRot(); this.setXRot(player.getXRot() * 0.5F); this.setRot(this.getYRot(), this.getXRot()); this.yBodyRot = this.getYRot(); this.yHeadRot = this.yBodyRot; float forward = player.zza; float strafe = player.xxa; if (forward <= 0.0F) { forward *= 0.25F; } this.flyingSpeed = this.getSpeed() * 0.1F; this.setSpeed((float) this.getAttributeValue(Attributes.MOVEMENT_SPEED) * 1.5F); this.setDeltaMovement(new Vec3(strafe, travelVector.y, forward).scale(this.getSpeed())); this.calculateEntityAnimation(this, false); } else { // The wolf does not have a passenger or the passenger is not a player System.out.println("No player is mounted, or the passenger is not a player."); super.travel(travelVector); } } public boolean hasSaddle() { return this.hasSaddle; } public void setSaddle(boolean hasSaddle) { this.hasSaddle = hasSaddle; } @Override protected void dropEquipment() { super.dropEquipment(); if (this.hasSaddle()) { this.spawnAtLocation(Items.SADDLE); this.setSaddle(false); } } @SubscribeEvent public static void onServerTick(TickEvent.ServerTickEvent event) { if (event.phase == TickEvent.Phase.START) { MinecraftServer server = net.minecraftforge.server.ServerLifecycleHooks.getCurrentServer(); if (server != null) { for (ServerPlayer player : server.getPlayerList().getPlayers()) { if (player.isPassenger() && player.getVehicle() instanceof MountableWolfEntity) { MountableWolfEntity wolf = (MountableWolfEntity) player.getVehicle(); System.out.println("Tick: " + player.getName().getString() + " is correctly mounted on " + wolf); } } } } } private boolean lastMountedState = false; @Override public void tick() { super.tick(); if (!this.level.isClientSide) { // Only on the server boolean isMounted = this.isVehicle() && this.getControllingPassenger() instanceof Player; // Only print if the state changed if (isMounted != lastMountedState) { if (isMounted) { Player player = (Player) this.getControllingPassenger(); // Verify the passenger is a player System.out.println("Server: Player " + player.getName().getString() + " is now mounted."); } else { System.out.println("Server: The wolf no longer has a passenger."); } lastMountedState = isMounted; } } } @Override public void addPassenger(Entity passenger) { super.addPassenger(passenger); if (passenger instanceof Player) { Player player = (Player) passenger; if (!this.level.isClientSide && player instanceof ServerPlayer) { // Send the packet to the server to indicate the player is mounted NetworkHandler.CHANNEL.send(PacketDistributor.PLAYER.with(() -> (ServerPlayer) player), new MountSyncPacket(true)); } } } @Override public void removePassenger(Entity passenger) { super.removePassenger(passenger); if (passenger instanceof Player) { Player player = (Player) passenger; if (!this.level.isClientSide && player instanceof ServerPlayer) { // Send the packet to the server to indicate the player is no longer mounted NetworkHandler.CHANNEL.send(PacketDistributor.PLAYER.with(() -> (ServerPlayer) player), new MountSyncPacket(false)); } } } @Override public boolean isControlledByLocalInstance() { Entity entity = this.getControllingPassenger(); return entity instanceof Player; } @Override public void positionRider(Entity passenger) { if (this.hasPassenger(passenger)) { double xOffset = Math.cos(Math.toRadians(this.getYRot() + 90)) * 0.4; double zOffset = Math.sin(Math.toRadians(this.getYRot() + 90)) * 0.4; passenger.setPos(this.getX() + xOffset, this.getY() + this.getPassengersRidingOffset() + passenger.getMyRidingOffset(), this.getZ() + zOffset); } } } MountSyncPacket package com.vals.valscraft.network; import com.vals.valscraft.entity.MountableWolfEntity; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Player; import net.minecraftforge.network.NetworkEvent; import java.util.function.Supplier; public class MountSyncPacket { private final boolean isMounted; public MountSyncPacket(boolean isMounted) { this.isMounted = isMounted; } public void encode(FriendlyByteBuf buffer) { buffer.writeBoolean(isMounted); } public static MountSyncPacket decode(FriendlyByteBuf buffer) { return new MountSyncPacket(buffer.readBoolean()); } public void handle(NetworkEvent.Context context) { context.enqueueWork(() -> { ServerPlayer player = context.getSender(); // Get the player from the context if (player != null) { // Verifies if the player has dismounted if (!isMounted) { Entity vehicle = player.getVehicle(); if (vehicle instanceof MountableWolfEntity wolf) { // Logic to remove the player as a passenger wolf.removePassenger(player); System.out.println("Server: Player " + player.getName().getString() + " is no longer mounted."); } } } }); context.setPacketHandled(true); // Marks the packet as handled } } networkHandler package com.vals.valscraft.network; import com.vals.valscraft.valscraft; import net.minecraft.resources.ResourceLocation; import net.minecraftforge.network.NetworkRegistry; import net.minecraftforge.network.simple.SimpleChannel; import net.minecraftforge.network.NetworkEvent; import java.util.function.Supplier; public class NetworkHandler { private static final String PROTOCOL_VERSION = "1"; public static final SimpleChannel CHANNEL = NetworkRegistry.newSimpleChannel( new ResourceLocation(valscraft.MODID, "main"), () -> PROTOCOL_VERSION, PROTOCOL_VERSION::equals, PROTOCOL_VERSION::equals ); public static void init() { int packetId = 0; // Register the mount synchronization packet CHANNEL.registerMessage( packetId++, MountSyncPacket.class, MountSyncPacket::encode, MountSyncPacket::decode, (msg, context) -> msg.handle(context.get()) // Get the context with context.get() ); } }  
    • Do you use features of inventory profiles next (ipnext) or is there a change without it?
    • Remove rubidium - you are already using embeddium, which is a fork of rubidium
  • Topics

×
×
  • Create New...

Important Information

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