Jump to content

Recommended Posts

Posted

Hello everyone. So I've been experimenting with the idea of creating a crate block, which would store a unlimited amount of just one item.  To do this, I would need a tile entity, since I need to store extra variables in the block.  However, when I run Minecraft, it gives me a null pointer exception.

 

Here's the code for the tile entity class:

 

public class CrateTileEntity extends TileEntity
{
    private ItemStack item;
    private int amount;

    /**
     * This method will return the item variable.
     */
    public ItemStack getItemStack()
    {
        return item;
    }

    /**
     * This method will return the count variable.
     */
    public int getAmount()
    {
        return amount;
    }

    /**
     * This method will be called whenever an item is added to the Crate. Items will only be added to this block through
     * a player's inventory (ItemStack is therefore used).
     *
     * Will return true only if a transaction takes place.
     */
    public boolean addItem(ItemStack stack)
    {
        //If no item is selected
        if (stack.getItem() == null)
        {
            return false;
        }

        //If item of stack is not the correct type...
        if (stack.getItem() != item.getItem())
        {
            //If item for Crate is not determined
            if (item == null)
            {
                //Set item and amount equal to that of ItemStack
                item.setItem(stack.getItem());
                amount = stack.stackSize;
                return true;
            }
            //Else, return.false
            else
            {
                return false;
            }
        }

        //if item is selected and item is of correct type, then add to Crate
        else
        {
            //Adds the size of stack
            amount += stack.stackSize;
            return true;
        }
    }

    // Loading and saving the data to NBT, so the info is not lost when the world is reloaded.

    /**
     * This method will read the information from the NBT regarding the item and amount for the Crate.
     *
     */
    @Override
    public void readFromNBT(NBTTagCompound compound)
    {
        super.readFromNBT(compound);

        //ItemStack:
        this.item = ItemStack.loadItemStackFromNBT(compound.getCompoundTag("item"));

        this.amount = compound.getInteger("amount");
    }

    /**
     * This method will write the information from the NBT regarding the item and amount for the Crate.
     *
     */
    @Override
    public void writeToNBT(NBTTagCompound compound)
    {
        super.writeToNBT(compound);
        compound.setInteger("amount", amount);

        //Item Stack:
        NBTTagCompound stack = new NBTTagCompound();
        this.item.writeToNBT(stack);
        compound.setTag("item", stack);
    }
}

 

and the code for the block class:

 

package crate;

import net.minecraft.block.Block;
import net.minecraft.block.ITileEntityProvider;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.TextComponentString;
import net.minecraft.util.text.TextFormatting;
import net.minecraft.world.World;
import net.minecraftforge.fml.common.registry.GameRegistry;

/**
* This class will create a Crate block, which will be able to store an infinite amount of a selected type of item.
* However, it can only store one item at a time.
*
* Created by Haaris Tahir-Kheli on 5/21/2016.
*/
public class CrateBlock extends Block implements ITileEntityProvider
{
    //Constructor
    protected CrateBlock()
    {
        //Set material for block (through superclass constructor)
        super(Material.wood);

        //Set unlocalized name
        this.setUnlocalizedName("crateBlock");

        //Set registry name and register
        this.setRegistryName("crateblock");

        //Set up which creative tab it can be found in
        this.setCreativeTab(CreativeTabs.tabBlock);

        //Set hardness
        this.setHardness(8.0F);

        //Set blast resistance
        this.setResistance(5.0F);

        //Set brightness
        this.setLightLevel(0.2F);

        //Set harvest level
        this.setHarvestLevel("axe", 1);

        //Set block container to true
        this.isBlockContainer = true;

    }

    /**
     * This method will establish a new tile entity that will be created and associated with this block
     */
    @Override
    public TileEntity createNewTileEntity(World worldIn, int meta)
    {
        return new CrateTileEntity();
    }

    /**
     * This method will return the tile entity of the block that was clicked
     */
    private CrateTileEntity getTileEntity(World world, BlockPos pos)
    {
        return (CrateTileEntity) world.getTileEntity(pos);
    }

    /**
     * Thie method will trigger as a clean-up for when the block is destroyed.
     */
    @Override
    public void breakBlock(World world, BlockPos pos, IBlockState state)
    {
        super.breakBlock(world, pos, state);
        world.removeTileEntity(pos);
    }

    /**
     * This method will handle the passing of block events, which are useful for synchronizing data.
     */
    @Override
    public boolean onBlockEventReceived(World worldIn, BlockPos pos, IBlockState state, int eventID, int eventParam)
    {
        super.onBlockEventReceived(worldIn, pos, state, eventID, eventParam);
        TileEntity tileentity = worldIn.getTileEntity(pos);
        return (tileentity == null) ? false : tileentity.receiveClientEvent(eventID, eventParam);
    }

    /**
     * This method will trigger whenever the block is right-clicked.
     */
    @Override
    public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand,
                                    ItemStack heldItem, EnumFacing side, float hitX, float hitY, float hitZ)
    {
        super.onBlockActivated(world, pos, state, player, hand, heldItem, side, hitX, hitY, hitZ);

        //Make sure event only takes place on client side
        if (world.isRemote)
        {
            return false;
        }

        //Check if player is holding an item
        if (player.getHeldItemMainhand() == null)
        {
            //Print message assessing crate
            player.addChatComponentMessage(new TextComponentString(TextFormatting.RED + "As you are not holding an item," +
                    " no item will be added to the crate."));
            return false;
        }

        //Create CrateTileEntity
        CrateTileEntity tileEntity = getTileEntity(world, pos);

        //Add item based on Crate tile entity
        if (tileEntity.addItem(heldItem))
        {
            //Print messages assessing crate
            player.addChatComponentMessage(new TextComponentString(TextFormatting.AQUA + "The crate holds "
                    + tileEntity.getItemStack().getItem().getUnlocalizedName() + "."));
            player.addChatComponentMessage(new TextComponentString(TextFormatting.AQUA + "It holds " + tileEntity.getAmount() + "."));
            return true;
        }
        //Else will trigger only if item is not the correct one for the crate.
        else
        {
            //Print message assessing crate
            player.addChatComponentMessage(new TextComponentString(TextFormatting.RED + "This is not a " + heldItem.getUnlocalizedName()
                    + " crate.  It is a " + tileEntity.getItemStack().getItem().getUnlocalizedName() + " crate."));
            return false;
        }
    }
}

 

And finally, the main class:

 

@Mod(modid = Main.MODID, version = Main.VERSION)
public class Main
{
    public static final String MODID = "CrateMod";
    public static final String VERSION = "1.0";

    public static void init()
    {
        GameRegistry.registerTileEntity(CrateTileEntity.class, "Crate tile entity");
    }

    @EventHandler
    public static void init(FMLInitializationEvent event)
    {
        CrateBlock block = new CrateBlock();

    }
}

Posted

Whoops, sorry, the previous post was incomplete.

 

Here's the crash report I keep getting:

 

---- Minecraft Crash Report ----

// Surprise! Haha. Well, this is awkward.

 

Time: 5/22/16 12:21 PM

Description: Ticking player

 

java.lang.NullPointerException: Ticking player

at net.minecraft.world.World.getBlockState(World.java:906)

at net.minecraft.world.World.isMaterialInBB(World.java:2383)

at net.minecraft.entity.Entity.isInLava(Entity.java:1306)

at net.minecraft.entity.Entity.onEntityUpdate(Entity.java:536)

at net.minecraft.entity.EntityLivingBase.onEntityUpdate(EntityLivingBase.java:252)

at net.minecraft.entity.Entity.onUpdate(Entity.java:427)

at net.minecraft.entity.EntityLivingBase.onUpdate(EntityLivingBase.java:2078)

at net.minecraft.entity.player.EntityPlayer.onUpdate(EntityPlayer.java:252)

at net.minecraft.entity.player.EntityPlayerMP.onUpdateEntity(EntityPlayerMP.java:339)

at net.minecraft.network.NetHandlerPlayServer.update(NetHandlerPlayServer.java:174)

at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher$1.update(NetworkDispatcher.java:196)

at net.minecraft.network.NetworkManager.processReceivedPackets(NetworkManager.java:307)

at net.minecraft.network.NetworkSystem.networkTick(NetworkSystem.java:195)

at net.minecraft.server.MinecraftServer.updateTimeLightAndEntities(MinecraftServer.java:802)

at net.minecraft.server.MinecraftServer.tick(MinecraftServer.java:683)

at net.minecraft.server.integrated.IntegratedServer.tick(IntegratedServer.java:155)

at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:532)

at java.lang.Thread.run(Thread.java:745)

 

 

A detailed walkthrough of the error, its code path and all known details is as follows:

---------------------------------------------------------------------------------------

 

-- Head --

Stacktrace:

at net.minecraft.world.World.getBlockState(World.java:906)

at net.minecraft.world.World.isMaterialInBB(World.java:2383)

at net.minecraft.entity.Entity.isInLava(Entity.java:1306)

at net.minecraft.entity.Entity.onEntityUpdate(Entity.java:536)

at net.minecraft.entity.EntityLivingBase.onEntityUpdate(EntityLivingBase.java:252)

at net.minecraft.entity.Entity.onUpdate(Entity.java:427)

at net.minecraft.entity.EntityLivingBase.onUpdate(EntityLivingBase.java:2078)

at net.minecraft.entity.player.EntityPlayer.onUpdate(EntityPlayer.java:252)

 

-- Player being ticked --

Details:

Entity Type: null (net.minecraft.entity.player.EntityPlayerMP)

Entity ID: 110

Entity Name: Player464

Entity's Exact location: 142.12, 80.00, 415.89

Entity's Block location: World: (142,80,415), Chunk: (at 14,5,15 in 8,25; contains blocks 128,0,400 to 143,255,415), Region: (0,0; contains chunks 0,0 to 31,31, blocks 0,0,0 to 511,255,511)

Entity's Momentum: 0.00, -0.08, 0.00

Entity's Passengers: []

Entity's Vehicle: ~~ERROR~~ NullPointerException: null

Stacktrace:

at net.minecraft.entity.player.EntityPlayerMP.onUpdateEntity(EntityPlayerMP.java:339)

at net.minecraft.network.NetHandlerPlayServer.update(NetHandlerPlayServer.java:174)

at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher$1.update(NetworkDispatcher.java:196)

at net.minecraft.network.NetworkManager.processReceivedPackets(NetworkManager.java:307)

 

-- Ticking connection --

Details:

Connection: net.minecraft.network.NetworkManager@2dbcb696

Stacktrace:

at net.minecraft.network.NetworkSystem.networkTick(NetworkSystem.java:195)

at net.minecraft.server.MinecraftServer.updateTimeLightAndEntities(MinecraftServer.java:802)

at net.minecraft.server.MinecraftServer.tick(MinecraftServer.java:683)

at net.minecraft.server.integrated.IntegratedServer.tick(IntegratedServer.java:155)

at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:532)

at java.lang.Thread.run(Thread.java:745)

 

-- System Details --

Details:

Minecraft Version: 1.9

Operating System: Windows 10 (amd64) version 10.0

Java Version: 1.8.0_91, Oracle Corporation

Java VM Version: Java HotSpot 64-Bit Server VM (mixed mode), Oracle Corporation

Memory: 411156400 bytes (392 MB) / 983564288 bytes (938 MB) up to 1888485376 bytes (1801 MB)

JVM Flags: 0 total;

IntCache: cache: 0, tcache: 0, allocated: 12, tallocated: 94

FML: MCP 9.23 Powered by Forge 12.16.1.1892 8 mods loaded, 8 mods active

States: 'U' = Unloaded 'L' = Loaded 'C' = Constructed 'H' = Pre-initialized 'I' = Initialized 'J' = Post-initialized 'A' = Available 'D' = Disabled 'E' = Errored

UCHIJAAAA mcp{9.19} [Minecraft Coder Pack] (minecraft.jar)

UCHIJAAAA FML{8.0.99.99} [Forge Mod Loader] (forgeSrc-1.9-12.16.1.1892.jar)

UCHIJAAAA Forge{12.16.1.1892} [Minecraft Forge] (forgeSrc-1.9-12.16.1.1892.jar)

UCHIJAAAA BlocksMods{1.0} [blocksMods] (modid-1.0.jar)

UCHIJAAAA examplemod{1.0} [Example Mod] (modid-1.0.jar)

UCHIJAAAA CommandMods{1.0} [CommandMods] (modid-1.0.jar)

UCHIJAAAA CrateMod{1.0} [CrateMod] (modid-1.0.jar)

UCHIJAAAA myMods{1.0} [myMods] (modid-1.0.jar)

Loaded coremods (and transformers):

GL info: ~~ERROR~~ RuntimeException: No OpenGL context found in the current thread.

Profiler Position: N/A (disabled)

Player Count: 1 / 8; [EntityPlayerMP['Player464'/110, l='Copy of New World', x=142.12, y=80.00, z=415.89]]

Type: Integrated Server (map_client.txt)

Is Modded: Definitely; Client brand changed to 'fml,forge'

 

I thought about using getDescriptionPacket or onDataPacket, but I tried learning them on my own, and tutorials I've been looking at are pretty out-of-date.  If anyone could help me out with understanding these methods, or point me to a good tutorial on them, I would be grateful.

Posted

Your crash report shows you are on 1.9, but this does not match up with your block class.

onBlockActivated

does not return a

boolean

in 1.9.

Uhmm, for me it does... maybe not in 1.9.4, but 1.9 it does.

Don't PM me with questions. They will be ignored! Make a thread on the appropriate board for support.

 

1.12 -> 1.13 primer by williewillus.

 

1.7.10 and older versions of Minecraft are no longer supported due to it's age! Update to the latest version for support.

 

http://www.howoldisminecraft1710.today/

Posted

So I got rid of the implementation, removed the isBlockContainer, removed the removeTileEntity, registered the tile entity in the main (and set the registration name to the MODID).  When the program runs, it now crashes with a null pointer exception when the Crate block is right-clicked.

 

Here's the updated code for the CrateBlock class:

 

http://pastebin.com/tWkDJ7yg

 

Here's the update code for the CrateTileEntity class:

 

http://pastebin.com/t8ie1G67

 

And here's the crash report:

 

---- Minecraft Crash Report ----

// I bet Cylons wouldn't have this problem.

 

Time: 5/22/16 7:05 PM

Description: Unexpected error

 

java.lang.NullPointerException: Unexpected error

at crate.CrateBlock.onBlockActivated(CrateBlock.java:128)

at net.minecraft.client.multiplayer.PlayerControllerMP.processRightClickBlock(PlayerControllerMP.java:439)

at net.minecraft.client.Minecraft.rightClickMouse(Minecraft.java:1597)

at net.minecraft.client.Minecraft.processKeyBinds(Minecraft.java:2268)

at net.minecraft.client.Minecraft.runTickKeyboard(Minecraft.java:2052)

at net.minecraft.client.Minecraft.runTick(Minecraft.java:1840)

at net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:1114)

at net.minecraft.client.Minecraft.run(Minecraft.java:401)

at net.minecraft.client.main.Main.main(Main.java:118)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

at java.lang.reflect.Method.invoke(Method.java:498)

at net.minecraft.launchwrapper.Launch.launch(Launch.java:135)

at net.minecraft.launchwrapper.Launch.main(Launch.java:28)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

at java.lang.reflect.Method.invoke(Method.java:498)

at net.minecraftforge.gradle.GradleStartCommon.launch(GradleStartCommon.java:97)

at GradleStart.main(GradleStart.java:26)

 

 

Based on the report, the error must occur because the getTileEntity(world, pos) in the CrateBlock class is returning a null.  However, I am unclear as to how to improve the code.

Posted

Override

Block#hasTileEntity(IBlockState)

, not the deprecated

Block#hasTileEntity()

.

Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future.

Posted

If your block always has a

TileEntity

, simply return

true

. If it depends on the state, use the

IBlockState

argument to determine the return value.

Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future.

Posted

It does not crash now, but the data members of the crates are not saved when the game is exited.  Any ideas on how to proceed?  I thought writing and reading from the NBT would solve the problem, but I guess not...

 

Here's the code for the CrateTileEntity:

 

http://pastebin.com/t8ie1G67

 

By the way, thank you to everyone for your help so far!

Posted

Don't save the item using its unlocalised name, use its registry name (

IForgeRegistryEntry#getRegistryName

, inherited by

Item

). This is the name used by

Item.getByNameOrId

.

 

Why not store the item as an

ItemStack

or a 1-slot

IItemHandler

?

Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future.

Posted

So I ...set the registration name to the MODID

I think you should include the MODID in the reg name, but you probably shouldn't use that as your whole name.

The debugger is a powerful and necessary tool in any IDE, so learn how to use it. You'll be able to tell us more and get better help here if you investigate your runtime problems in the debugger before posting.

Posted

So I ...set the registration name to the MODID

I think you should include the MODID in the reg name, but you probably shouldn't use that as your whole name.

The debugger is a powerful and necessary tool in any IDE, so learn how to use it. You'll be able to tell us more and get better help here if you investigate your runtime problems in the debugger before posting.

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

    • 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() ); } }  
    • Do you use features of inventory profiles next (ipnext) or is there a change without it?
  • Topics

×
×
  • Create New...

Important Information

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