Jump to content

Recommended Posts

Posted (edited)

I'm trying to add Tough as Nails support for my mod. Basically I want players to keep their thirst level when they die. How should I do this, for hunger I used getOriginal but how should I get Original's thirst level? I already have the deobfuscated jar file in libs folder and I can access the classes but my problem is how do I get thirst level before death.

Edited by Terrails
Posted

Try to look at the mod how they implemented the functionality and how they handle the thirst.

Then look at the getOriginal method and make your own how it is realised. Put both together

in the end.

 

Posted (edited)

I just made an PlayerEvent class and did this in it:

Spoiler

public class KHPlayerEvent extends LivingEvent
{
    private final KHEntityPlayer entity;
    public KHPlayerEvent(KHEntityPlayer player)
    {
        super(player);
        entity = player;
    }

    public KHEntityPlayer getKHEntityPlayer()
    {
        return this.entity;
    }

    public static class KHClone extends KHPlayerEvent
    {
        private final KHEntityPlayer original;
        private final boolean wasDeath;

        public KHClone(KHEntityPlayer _new, KHEntityPlayer oldPlayer, boolean wasDeath)
        {
            super(_new);
            this.original = oldPlayer;
            this.wasDeath = wasDeath;
        }

        public KHEntityPlayer getKHOriginal()
        {
            return original;
        }

        public boolean isKHWasDeath()
        {
            return wasDeath;
        }
    }
}

 

This is my EntityPlayer

Spoiler

public abstract class KHEntityPlayer extends EntityPlayer {

    protected ThirstHandler thirstHandler = new ThirstHandler();

    public KHEntityPlayer(World worldIn, GameProfile gameProfileIn, ThirstHandler thirstHandler) {
        super(worldIn, gameProfileIn);
        this.thirstHandler = thirstHandler;
    }

    public void cloneKHPlayer(KHEntityPlayer oldPlayer, boolean respawnFromEnd)
    {

        if (respawnFromEnd)
        {
            this.thirstHandler = oldPlayer.thirstHandler;
        }

        this.getDataManager().set(PLAYER_MODEL_FLAG, oldPlayer.getDataManager().get(PLAYER_MODEL_FLAG));

        NBTTagCompound old = oldPlayer.getEntityData();
        if (old.hasKey(PERSISTED_NBT_TAG))
        {
            getEntityData().setTag(PERSISTED_NBT_TAG, old.getCompoundTag(PERSISTED_NBT_TAG));
        }
        ForgeEventFactory.onPlayerClone(this, oldPlayer, !respawnFromEnd);

    }
    public ThirstHandler getThirstStats()
    {
        return this.thirstHandler;
    }

}

 

and my event (I registered it in CommonProxy)

Spoiler

    @SubscribeEvent
    public void keepThirst(KHPlayerEvent.KHClone player) {

        ThirstHandler thirstHandler = new ThirstHandler();

        if (ConfigHandler.thirst && Loader.isModLoaded(ToughAsNails.MOD_ID) && player.isKHWasDeath()) {
            if (player.getKHEntityPlayer().getThirstStats().getThirst() <= ConfigHandler.thirstAmount && ConfigHandler.amountThirst) {

                player.getKHEntityPlayer().getThirstStats().setThirst(ConfigHandler.thirstAmount);
                player.getKHEntityPlayer().getThirstStats().setHydration(player.getKHOriginal().getThirstStats().getHydration());

            } else if (ConfigHandler.thirst && Loader.isModLoaded(ToughAsNails.MOD_ID)) {

                player.getKHEntityPlayer().getThirstStats().setThirst(player.getKHOriginal().getThirstStats().getThirst());
                player.getKHEntityPlayer().getThirstStats().setHydration(player.getKHOriginal().getThirstStats().getHydration());
            }
        }
    }
}

 

But it doesn't want to work, I think its something in my EntityPlayer but I'm not sure

Edited by Terrails
Posted (edited)

If I have Tough as Nails installed it should when a player die's set players thirst like the one before his death. And yes it doesn't do anything it just resets the thirst to max when I die.

Edited by Terrails
Posted

I was such an idiot.... it was so simple... this is all I needed to do:

    @SubscribeEvent
    public void onClonePlayer(PlayerEvent.Clone player){
    final IThirst oldThirst = getThirst(player.getOriginal());
    final IThirst newThirst = getThirst(player.getEntityPlayer());

        if(oldThirst.getThirst() <= ConfigHandler.thirstAmount && ConfigHandler.amountThirst && Loader.isModLoaded("toughasnails")){
            newThirst.setThirst(ConfigHandler.thirstAmount);
            newThirst.setHydration(oldThirst.getHydration());
        }
        else if(ConfigHandler.thirst && Loader.isModLoaded("toughasnails")) {
            newThirst.setThirst(oldThirst.getThirst());
            newThirst.setHydration(oldThirst.getHydration());
        }
    }

    @Nullable
    public static IThirst getThirst(final EntityLivingBase entity) {
        return entity.getCapability(TANCapabilities.THIRST, null);
    }

I just needed getThirst method from which I get THIRST capability and in my Clone method I just getThirst from original and the entityplayer. Of course I needed to register the event. I used this for tough as nails hydration too.

Posted (edited)

I have another problem.... Is there a way to put this into an IF statement so my mod can load without ToughAsNails?

    @Nullable
    public static IThirst getThirst(final EntityLivingBase entity) {
        return entity.getCapability(TANCapabilities.THIRST, null);
    }

 

Edited by Terrails
Posted (edited)

You could put @Optional.Method("modid") above both of those methods to let Forge remove them in case ToughAsNails is not loaded.

Edited by XFactHD
Posted (edited)

Thanks! Everything works perfectly.

Only problem is if I die sometimes my thirst is full, Its a visual bug is there a way to fix this?

If I relog or drink water the bug fixes itself, or if I lose thirst

Edited by Terrails
Posted

That looks like a client-server sync issue. You will need to find some way of sending the data to the client. You might want to take a look at how ToughAsNails does that.

Posted
24 minutes ago, Terrails said:

How can I do that without creating a special class for that? (Not making my own ThirstHandler)

 

No, you do not need to make a custom ThirstHandler. From what I can tell, PlayerEvent.Clone only fires on the server-side. That means that when you set your thirst level, you are only setting it on the server-side. In order for you to see the changes visually, you need to update the client-side as well. You can do that via a packet, which you can send to the client after you update the player's thirst level. You can read about networking here.

Posted (edited)

I somehow made my game to throw an connection terminated error when I try to join my world.

In my PlayerEvent.Clone it worked fine but sometimes when I login into the world my thirst would have that glitch again, so I wanted to put it into EntityJoinWorldEvent and than it started giving me that error.

Event Class (I have a lot of isModLoaded because I want to my mod to work with 1.9-1.11 and ToughAsNails changed their modid to lowercase in 1.11 and I think I can't add 2 modid's into @Optional.Method("modid")):

Spoiler

public class TANEvent {

    @SubscribeEvent
    public void onClonePlayer(PlayerEvent.Clone player) {
        final IThirst oldThirst = getThirst(player.getOriginal());
        final IThirst newThirst = getThirst(player.getEntityPlayer());

        if (oldThirst.getThirst() <= ConfigHandler.thirstAmount && ConfigHandler.thirstBoolean && Loader.isModLoaded("toughasnails") && player.isWasDeath()) {
            newThirst.setThirst(ConfigHandler.thirstAmount);
            newThirst.setHydration(oldThirst.getHydration());
        } else if (oldThirst.getThirst() <= ConfigHandler.thirstAmount && ConfigHandler.thirstBoolean && Loader.isModLoaded("ToughAsNails") && player.isWasDeath()) {
            newThirst.setThirst(ConfigHandler.thirstAmount);
            newThirst.setHydration(oldThirst.getHydration());
        } else if (ConfigHandler.thirst && Loader.isModLoaded("toughasnails") && player.isWasDeath()) {
            newThirst.setThirst(oldThirst.getThirst());
            newThirst.setHydration(oldThirst.getHydration());
        } else if (ConfigHandler.thirst && Loader.isModLoaded("ToughAsNails") && player.isWasDeath()) {
            newThirst.setThirst(oldThirst.getThirst());
            newThirst.setHydration(oldThirst.getHydration());
        }
     //   MainClass.instance.sendToAll(new ThirstMessage(newThirst.getThirst(), newThirst.getHydration()));
    }

    @SubscribeEvent
    public void onJoin(EntityJoinWorldEvent event)
    {
        if(Loader.isModLoaded("ToughAsNails")) {
            ThirstHandler thirst = new ThirstHandler();
            MainClass.instance.sendToAll(new ThirstMessage(thirst.getThirst(), thirst.getHydration()));
        } else if(Loader.isModLoaded("toughasnails")){
            ThirstHandler thirst = new ThirstHandler();
            MainClass.instance.sendToAll(new ThirstMessage(thirst.getThirst(), thirst.getHydration()));
        }
    }

    @Nullable
    public static IThirst getThirst(final EntityLivingBase entity) {
        return entity.getCapability(TANCapabilities.THIRST, null);
    }


}

 

ThirstMessage and ThirstMessageHandler:

Spoiler

public class ThirstMessage implements IMessage {

    private String text;
    private int thirst;
    private float hydration;

    public ThirstMessage() {}

    public ThirstMessage(int thirst, float hydration)
    {
        this.thirst = thirst;
        this.hydration = hydration;
    }

    @Override
    public void fromBytes(ByteBuf buf) {
        thirst = buf.readInt();
        hydration = buf.readFloat();
    }

    @Override
    public void toBytes(ByteBuf buf) {
        buf.writeInt(thirst);
        buf.writeFloat(hydration);
    }

    public static class ThirstMessageHandler implements IMessageHandler<ThirstMessage, IMessage>{

        @Override
        public IMessage onMessage(ThirstMessage message, MessageContext ctx) {
            IThreadListener mainThread = (WorldServer) ctx.getServerHandler().playerEntity.getEntityWorld();
            mainThread.addScheduledTask(new Runnable() {
                @Override
                public void run() {
                    ThirstHandler thirst = new ThirstHandler();
                    thirst.setThirst(message.thirst);
                    thirst.setHydration(message.hydration);
                }
            });
            return null;
        }

    }
}

 

Error: http://pastebin.com/YudBAdz5

 

Edited by Terrails
Posted

I tried couple of things and I still can't do anything:

Message:

Spoiler

public class ThirstMessage implements IMessage, IMessageHandler<ThirstMessage, IMessage> {

    public int thirst;

    public ThirstMessage() {}

    public ThirstMessage(int thirst){
        this.thirst = thirst;
    }

    @Override
    public void fromBytes(ByteBuf buf)
    {
        thirst = buf.readInt();
    }

    @Override
    public void toBytes(ByteBuf buf)
    {
        buf.writeInt(thirst);
    }

    @Override
    public IMessage onMessage(ThirstMessage message, MessageContext ctx) {
        IThreadListener mainThread =  Minecraft.getMinecraft();
        EntityPlayer player = Minecraft.getMinecraft().player;
        ThirstHandler thirstStats = (ThirstHandler)player.getCapability(TANCapabilities.THIRST, null);
        mainThread.addScheduledTask(new Runnable() {
            @Override
            public void run() {
                thirstStats.setThirst(message.thirst);
            }
        });
        return null;
    }
}

 

Event

Spoiler


    @Nullable
    public static IThirst getThirst(final EntityLivingBase entity) {
        return entity.getCapability(TANCapabilities.THIRST, null);
    }

    @SubscribeEvent
    public void onClonePlayer(PlayerEvent.Clone player) {
        final IThirst oldThirst = getThirst(player.getOriginal());
        EntityPlayer entityPlayer = player.getEntityPlayer();
        ThirstHandler thirstStats = (ThirstHandler)entityPlayer.getCapability(TANCapabilities.THIRST, null);
        if (oldThirst.getThirst() <= ConfigHandler.thirstAmount && ConfigHandler.thirstBoolean && Loader.isModLoaded("toughasnails") && player.isWasDeath()) {
            thirstStats.setThirst(ConfigHandler.thirstAmount);
            thirstStats.setHydration(oldThirst.getHydration());
            MainClass.network.sendToAll(new ThirstMessage(thirstStats.getThirst()));

        } else if (oldThirst.getThirst() <= ConfigHandler.thirstAmount && ConfigHandler.thirstBoolean && Loader.isModLoaded("ToughAsNails") && player.isWasDeath()) {
            thirstStats.setThirst(ConfigHandler.thirstAmount);
            thirstStats.setHydration(oldThirst.getHydration());
            MainClass.network.sendToAll(new ThirstMessage(thirstStats.getThirst()));

        } else if (ConfigHandler.thirst && Loader.isModLoaded("toughasnails") && player.isWasDeath()) {
            thirstStats.setThirst(oldThirst.getThirst());
            thirstStats.setHydration(oldThirst.getHydration());
            MainClass.network.sendToAll(new ThirstMessage(thirstStats.getThirst()));

        } else if (ConfigHandler.thirst && Loader.isModLoaded("ToughAsNails") && player.isWasDeath()) {
            thirstStats.setThirst(oldThirst.getThirst());
            thirstStats.setHydration(oldThirst.getHydration());
            MainClass.network.sendToAll(new ThirstMessage(thirstStats.getThirst()));
        }

    }

 

 

Posted

I did all of that and its still happening:

    @SubscribeEvent
    public void respawn(net.minecraftforge.fml.common.gameevent.PlayerEvent.PlayerRespawnEvent event)
    {
        EntityPlayer entityPlayer = event.player;
        ThirstHandler thirstStats = (ThirstHandler)entityPlayer.getCapability(TANCapabilities.THIRST, null);
        MainClass.network.sendTo(new ThirstMessage(thirstStats.getThirst()), (EntityPlayerMP) event.player);
    }

 

Posted (edited)

I kinda figured it out. If I die with this Message and this kind of PlayerRespawnEvent my visual thirst gets set to 0

Message(pretty much the same one as tough as nails uses):

Spoiler

public class PacketMessageThirst implements IMessage, IMessageHandler<PacketMessageThirst, IMessage> {

        public String identifier;
        public NBTTagCompound data;

    public PacketMessageThirst() {}

    public PacketMessageThirst(Capability<?> capability, NBTTagCompound data)
        {
            if (data == null) throw new IllegalArgumentException("Data cannot be null!");

            this.identifier = capability.getName();
            this.data = data;
        }

        @Override
        public void fromBytes(ByteBuf buf)
        {
            this.identifier = ByteBufUtils.readUTF8String(buf);
            this.data = ByteBufUtils.readTag(buf);
        }

        @Override
        public void toBytes(ByteBuf buf)
        {
            ByteBufUtils.writeUTF8String(buf, this.identifier);
            ByteBufUtils.writeTag(buf, this.data);
        }

        @Override
        public IMessage onMessage(PacketMessageThirst message, MessageContext ctx)
        {
            EntityPlayerSP player = Minecraft.getMinecraft().player;

            if (player != null)
            {
                Capability<IPlayerStat> capability = (Capability<IPlayerStat>) PlayerStatRegistry.getCapability(message.identifier);
                StatHandlerBase stat = (StatHandlerBase)player.getCapability(capability, null);

                capability.getStorage().readNBT(capability, stat, null, message.data);
            }

            return null;
        }
    }

 

Event (class needs to extend their ThirstHandler):

Spoiler

    @SubscribeEvent
    public void respawn(net.minecraftforge.fml.common.gameevent.PlayerEvent.PlayerRespawnEvent event)
    {
        NBTTagCompound data = (NBTTagCompound) TANCapabilities.THIRST.getStorage().writeNBT(TANCapabilities.THIRST, this, null);
        new PacketMessageThirst(TANCapabilities.THIRST, data);
    }

 

What should I do further... I'm getting really confused by these packet's.

Edited by Terrails

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
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
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.

Announcements



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • So me and a couple of friends are playing with a shitpost mod pack and one of the mods in the pack is corail tombstone and for some reason there is a problem with it, where on death to fire the player will get kicked out of the server and the tombstone will not spawn basically deleting an entire inventory, it doesn't matter what type of fire it is, whether it's from vanilla fire/lava, or from modded fire like ice&fire/lycanites and it's common enough to where everyone on the server has experienced at least once or twice and it doesn't give any crash log. a solution to this would be much appreciated thank you!
    • It is 1.12.2 - I have no idea if there is a 1.12 pack
    • Okay, but does the modpack works with 1.12 or just with 1.12.2, because I need the Forge client specifically for Minecraft 1.12, not 1.12.2
    • 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() ); } }  
  • Topics

×
×
  • Create New...

Important Information

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