Jump to content

Recommended Posts

Posted

If you're following my example, the COLOR property is stored in the metadata and as such is already set when Block#getActualState is called. The FACING property is stored in the TileEntity and is the only property that needs to be set in your override of Block#getActualState.

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.

  • Replies 64
  • Created
  • Last Reply

Top Posters In This Topic

Posted
5 hours ago, Choonster said:

and is the only property that needs to be set in your override of Block#getActualState.

That's exactly what I thought. I'm assuming my problem is elsewhere then? I wasn't sure if maybe it's in onBlockPlaced or something.

Posted
40 minutes ago, Siqhter said:

That's exactly what I thought. I'm assuming my problem is elsewhere then? I wasn't sure if maybe it's in onBlockPlaced or something.

 

What exactly is your current issue? Please post your latest code (or a link to your repository). If it's a model issue, please post your blockstates/model files and your debug.log.

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

(Note that you can do it the other way too: store the facing in the metadata and the color in the TE).

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
On 12/22/2018 at 11:55 PM, Choonster said:

 

What exactly is your current issue?

On placing the block, it should be 1 of 16 different dye colors. Also the items in the creative menu should each be their own dye color.

 

It's not a model issue, because they render when placed, just not with the correct color (they only render in white, which is the first color in the blockstates colors variants). Also the blocks work fine when applied with dyes (the blocks change to their respective color), so it's probably something in a method that I'm not adding. Below are my Block and TileEntity classes, as well as the blockstate file.

Spoiler

public class BlockCounter extends BlockColored {

    public static final IProperty<EnumFacing> FACING = PropertyDirection.create("facing");

    public static final AxisAlignedBB RED_COUNTER_AABB = new AxisAlignedBB(0.0D, 0.0D, 0.0D, 1.0D, 1.0D, 1.0D);

    public BlockCounter(final Material material) {
        super(Material.CLAY);
        setCreativeTab(CreativeTabs.DECORATIONS);
        this.setDefaultState(this.blockState.getBaseState().withProperty(FACING, EnumFacing.NORTH));
    }

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

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

    @Override
    public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos) {
        return RED_COUNTER_AABB;
    }

    @Override
    protected BlockStateContainer createBlockState()
    {
        return new BlockStateContainer(this, COLOR, FACING);
    }

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

    @Nullable
    @Override
    public TileEntity createTileEntity(World world, IBlockState state) {
        return new TileEntityCounter();
    }

    @Nullable
    public TileEntityCounter getTileEntity(final IBlockAccess world, final BlockPos pos) {
        return (TileEntityCounter) world.getTileEntity(pos);
    }

    public EnumFacing getFacing(final IBlockAccess world, final BlockPos pos) {
        final TileEntityCounter tileEntity = getTileEntity(world, pos);
        return tileEntity != null ? tileEntity.getFacing() : EnumFacing.NORTH;
    }

    public void setFacing(final IBlockAccess world, final BlockPos pos, final EnumFacing facing) {
        final TileEntityCounter tileEntity = getTileEntity(world, pos);
        if (tileEntity != null) {
            tileEntity.setFacing(facing);
        }
    }

    @Override
    public void onBlockPlacedBy(final World worldIn, final BlockPos pos, final IBlockState state, final EntityLivingBase placer, final ItemStack stack) {
        setFacing(worldIn, pos, EnumFacing.getDirectionFromEntityLiving(pos, placer).getOpposite());
    }

    @Override
    public IBlockState getActualState(final IBlockState state, final IBlockAccess worldIn, final BlockPos pos) {
        return state.withProperty(FACING, getFacing(worldIn, pos));
    }

    @Override
    public void getSubBlocks(CreativeTabs item, NonNullList<ItemStack> items) {
        for (int i = 0; i < EnumDyeColor.values().length; i++) {
            items.add(new ItemStack(this, 1, i));
        }
    }

    @Override
    public boolean onBlockActivated(final World worldIn, final BlockPos pos, final IBlockState state, final EntityPlayer playerIn, final EnumHand hand, final EnumFacing side, final float hitX, final float hitY, final float hitZ)
    {
        final ItemStack heldItem = playerIn.getHeldItem(hand);

        if (!heldItem.isEmpty()) {
            final Optional<EnumDyeColor> dyeColour = DyeUtils.colorFromStack(heldItem);
            if (dyeColour.isPresent()) {
                final boolean success = recolorBlock(worldIn, pos, side, dyeColour.get());
                if (success && !playerIn.isCreative()) {
                    heldItem.shrink(1);
                }
                return true;
            }
        }
        return false;
       }
    }
Spoiler

public class TileEntityCounter extends TileEntity {

    private EnumFacing facing = EnumFacing.NORTH;

    public EnumFacing getFacing() {
        return facing;
    }

    public void setFacing(final EnumFacing facing) {
        this.facing = facing;
        markDirty();
    }

    @Override
    public void readFromNBT(final NBTTagCompound compound) {
        super.readFromNBT(compound);
        facing = EnumFacing.getFront(compound.getInteger("facing"));
    }

    @Override
    public NBTTagCompound writeToNBT(final NBTTagCompound compound) {
        super.writeToNBT(compound);
        compound.setInteger("facing", facing.getIndex());
        return compound;
    }

    private void notifyBlockUpdate() {
        final IBlockState state = getWorld().getBlockState(getPos());
        getWorld().notifyBlockUpdate(getPos(), state, state, 3);
    }

    @Override
    public void markDirty() {
        super.markDirty();
        notifyBlockUpdate();
    }

    @Override
    public NBTTagCompound getUpdateTag() {
        return writeToNBT(new NBTTagCompound());
    }

    @Nullable
    @Override
    public SPacketUpdateTileEntity getUpdatePacket() {
        return new SPacketUpdateTileEntity(getPos(), 0, getUpdateTag());
    }

    @Override
    public void onDataPacket(final NetworkManager net, final SPacketUpdateTileEntity pkt) {
        readFromNBT(pkt.getNbtCompound());
        notifyBlockUpdate();
    }

    @Override
    public boolean shouldRefresh(final World world, final BlockPos pos, final IBlockState oldState, final IBlockState newSate) {
        return oldState.getBlock() != newSate.getBlock();
    }
}
Spoiler

{
  "forge_marker": 1,
  "defaults": {
    "model": "testmod:counter"
  },
  "variants": {
    "facing": {
      "down": {
        "x": 90
      },
      "up": {
        "x": 270
      },
      "north": {
        "y": 270
      },
      "south": {
        "y": 90
      },
      "east": {
        "y": 0
      },
      "west": {
        "y": 180
      }
    },
    "color": {
      "white": {
        "textures": {
          "top": "blocks/hardened_clay_stained_white"
        }
      },
      "orange": {
        "textures": {
          "top": "blocks/hardened_clay_stained_orange"
        }
      },
      "magenta": {
        "textures": {
          "top": "blocks/hardened_clay_stained_magenta"
        }
      },
      "light_blue": {
        "textures": {
          "top": "blocks/hardened_clay_stained_light_blue"
        }
      },
      "yellow": {
        "textures": {
          "top": "blocks/hardened_clay_stained_yellow"
        }
      },
      "lime": {
        "textures": {
          "top": "blocks/hardened_clay_stained_lime"
        }
      },
      "pink": {
        "textures": {
          "top": "blocks/hardened_clay_stained_pink"
        }
      },
      "gray": {
        "textures": {
          "top": "blocks/hardened_clay_stained_gray"
        }
      },
      "silver": {
        "textures": {
          "top": "blocks/hardened_clay_stained_silver"
        }
      },
      "cyan": {
        "textures": {
          "top": "blocks/hardened_clay_stained_cyan"
        }
      },
      "purple": {
        "textures": {
          "top": "blocks/hardened_clay_stained_purple"
        }
      },
      "blue": {
        "textures": {
          "top": "blocks/hardened_clay_stained_blue"
        }
      },
      "brown": {
        "textures": {
          "top": "blocks/hardened_clay_stained_brown"
        }
      },
      "green": {
        "textures": {
          "top": "blocks/hardened_clay_stained_green"
        }
      },
      "red": {
        "textures": {
          "top": "blocks/hardened_clay_stained_red"
        }
      },
      "black": {
        "textures": {
          "top": "blocks/hardened_clay_stained_black"
        }
      }
    }
  }
}

 

Posted
3 minutes ago, Siqhter said:

On placing the block, it should be 1 of 16 different dye colors. Also the items in the creative menu should each be their own dye color.

 

It's not a model issue, because they render when placed, just not with the correct color (they only render in white, which is the first color in the blockstates colors variants). Also the blocks work fine when applied with dyes (the blocks change to their respective color), so it's probably something in a method that I'm not adding. Below are my Block and TileEntity classes, as well as the blockstate file.

 

This sounds like an issue with the ItemBlock and/or the model registration for the ItemBlock. Please post the code where you instantiate and register the ItemBlock and the code where you register the models for the ItemBlock(or create a repository so that we can see all of your code).

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
1 minute ago, Choonster said:

(or create a repository so that we can see all of your code).

Yeah sorry I've been meaning to do that. Something got messed up with an old mod's repository and I've been trying to fix it. Anyway this is how I register the block and itemblock, but I feel like that would only be an issue with it registering the texture in the inventory. And I should add, it does register the counter model block fine (on placed, and in the inventory), just not the subitems I create with the getSubItems method in my BlockCounter.java. So I'm pretty sure they're registered correctly.

 

BlockInit.java

Spoiler

public static final List<Block> BLOCKS = new ArrayList<Block>();


static Block COUNTER;

public static void init()
{
    COUNTER = new BlockCounter(Material.ROCK).setUnlocalizedName("counter").setRegistryName("counter");

    registerBlock(COUNTER);
}

public static void registerBlock(Block block)
{
    registerBlock(block, new ItemBlock(block));
}

public static void registerBlock(Block block, ItemBlock itemBlock)
{
    BLOCKS.add(block);
    itemBlock.setRegistryName(block.getRegistryName());
    ItemInit.ITEMS.add(itemBlock);
}

RegistryHandler.java

Spoiler

@SubscribeEvent
public static void onBlockRegister(RegistryEvent.Register<Block> event) {
    BlockInit.init();
    event.getRegistry().registerAll(BlockInit.BLOCKS.toArray(new Block[0]));
}

 

Posted

ItemBlock itself isn't suitable for blocks with variants, you need to use a subclass that overrides Item#getMetadata(int) to convert the item metadata to block metadata and calls Item#setHasSubtypes to mark the item as having variants/subtypes. ItemCloth does these and also overrides Item#getTranslationKey(ItemStack) to add the stack's colour as a suffix to the translation key (unlocalised name) so that each colour can have its own translation.

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
20 minutes ago, Choonster said:

ItemBlock itself isn't suitable for blocks with variants

Ah, I didn't realize that. So I would need a separate class that sets hasSubtypes to true, overrides getMetadata, and a getUnlocalizedName method? Pretty much everything in the ItemCloth class?

Posted
9 minutes ago, Siqhter said:

Ah, I didn't realize that. So I would need a separate class that sets hasSubtypes to true, overrides getMetadata, and a getUnlocalizedName method? Pretty much everything in the ItemCloth class?

 

Yes, or just use ItemCloth.

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

Got that working. I feel stupid, I had created a class that I planned to use for any block with subtypes, just forgot to register it in the BlockInit class as a new ItemBlock. It was the same type as ItemCloth that you just told me about. The textures in the inventory are still not registering, should I do the same with with a getSubItems subclass? I'm not sure how similar it is toSubBlocks. Thanks.

Posted

Nevermind I actually just got that working as well. I created a SubItems interface with a ResourceLocation method, and registered items that are instances of SubItems in my RegistrationHandler under Items. Thanks for your help on this.

Posted (edited)

Sorry I do have one other question. Using harvestBlock how would I get it to drop the correct color block? Right now it just drops nothing.

Edited by Siqhter
Posted (edited)

What does the code look like right now?

nvm...

Edited by Animus_Surge

Forge 1.8.9 and below are not supported in the forums anymore. Please upgrade to a later version.

 

My experimental mod: new GitHub page to be created... (Add your favorite TCGs in MC! [WIP])

 

When asking for assistance with modding or making mods, paste the log (located in .minecraft/logs folder for mod users or in the console for mod makers).

Posted
7 minutes ago, diesieben07 said:

Override getDrops instead

Well I just did this and it works fine. What is the reason for not overriding harvestBlock? 

drops.add(new ItemStack(this, 1, this.getMetaFromState(state)));
Posted
2 minutes ago, diesieben07 said:

If you override harvestBlock and hard-code your drops there, nobody can figure out what your block drops.

Ok, that makes sense, thanks.

Posted

You could also have a different block for each colour, the way shulker boxes do

About Me

Spoiler

My Discord - Cadiboo#8887

My WebsiteCadiboo.github.io

My ModsCadiboo.github.io/projects

My TutorialsCadiboo.github.io/tutorials

Versions below 1.14.4 are no longer supported on this forum. Use the latest version to receive support.

When asking support remember to include all relevant log files (logs are found in .minecraft/logs/), code if applicable and screenshots if possible.

Only download mods from trusted sites like CurseForge (minecraft.curseforge.com). A list of bad sites can be found here, with more information available at stopmodreposts.org

Edit your own signature at www.minecraftforge.net/forum/settings/signature/ (Make sure to check its compatibility with the Dark Theme)

Posted
1 hour ago, Cadiboo said:

You could also have a different block for each colour, the way shulker boxes do

You mean like a separate model/blockstate file instead of subtypes?

Posted

Well I have heard a couple people on this post say something about switching facing and color properties so that I can store color in the TE. Right now color is in the metadata, but if I instead put it in the TE, than how exactly would I call it in the block class instead of using getMetaFromState and getStateFromMeta?

Posted (edited)

You would use the block pos you would get to get the tile entity at that pos, check if it’s yours & get the data from it.

However, with the ID limit expansion in 1.13 I would just use seperate blocks (not seperate classes) for each colour the way shulker boxes do it (with an enum). Meta is great for facing, but you shouldnt be using a TE for something like this as you can avoid all the overhead of it by just using multiple blocks

Edited by Cadiboo

About Me

Spoiler

My Discord - Cadiboo#8887

My WebsiteCadiboo.github.io

My ModsCadiboo.github.io/projects

My TutorialsCadiboo.github.io/tutorials

Versions below 1.14.4 are no longer supported on this forum. Use the latest version to receive support.

When asking support remember to include all relevant log files (logs are found in .minecraft/logs/), code if applicable and screenshots if possible.

Only download mods from trusted sites like CurseForge (minecraft.curseforge.com). A list of bad sites can be found here, with more information available at stopmodreposts.org

Edit your own signature at www.minecraftforge.net/forum/settings/signature/ (Make sure to check its compatibility with the Dark Theme)

Posted (edited)
7 minutes ago, Cadiboo said:

You would use the block pos you would get to get the tile entity at that pos, check if it’s yours & get the data from it.

Would this go in getActualState?

Edited by Siqhter
Posted

Yes

About Me

Spoiler

My Discord - Cadiboo#8887

My WebsiteCadiboo.github.io

My ModsCadiboo.github.io/projects

My TutorialsCadiboo.github.io/tutorials

Versions below 1.14.4 are no longer supported on this forum. Use the latest version to receive support.

When asking support remember to include all relevant log files (logs are found in .minecraft/logs/), code if applicable and screenshots if possible.

Only download mods from trusted sites like CurseForge (minecraft.curseforge.com). A list of bad sites can be found here, with more information available at stopmodreposts.org

Edit your own signature at www.minecraftforge.net/forum/settings/signature/ (Make sure to check its compatibility with the Dark Theme)

Posted

Ok, thanks. And just to check I defined my color in the TE as

Spoiler

private EnumDyeColor color = EnumDyeColor.RED;

 

It doesn't need to be an integer or is this alright?

 

Posted
11 hours ago, Cadiboo said:

However, with the ID limit expansion in 1.13 I would just use seperate blocks (not seperate classes) for each colour the way shulker boxes do it (with an enum). Meta is great for facing, but you shouldnt be using a TE for something like this as you can avoid all the overhead of it by just using multiple blocks

Ok, I will look into it. For now I am curious, just because I'm trying to switch color and facing so I store color in the TE. (I will end up changing it to what has been recommended). But in getActualState I'm trying to call the TE and get the data from it, but I'm not quite sure how.

@Override
public IBlockState getActualState(IBlockState state, IBlockAccess worldIn, BlockPos pos) {
    super.getActualState(state, worldIn, pos);
    TileEntityCounter tileEntity = (TileEntityCounter) worldIn.getTileEntity(pos);
    EnumDyeColor color = tileEntity.getColor();

    return state.withProperty(COLOR, color);
}
Posted

Quick update, sorry but I'm still stuck on this. My tileentity for color is:

Spoiler

private EnumDyeColor color = EnumDyeColor.RED;

@Override
public void readFromNBT(NBTTagCompound compound) {
    super.readFromNBT(compound);
    this.color = EnumDyeColor.byMetadata(compound.getInteger("color"));
}

@Override
public NBTTagCompound writeToNBT(NBTTagCompound compound) {
    super.writeToNBT(compound);
    compound.setInteger("color", this.color.getMetadata());
    return compound;
}

and getActualState:

Spoiler

@Override
public IBlockState getActualState(IBlockState state, IBlockAccess worldIn, BlockPos pos) {
    super.getActualState(state, worldIn, pos);
    TileEntityCounter tileEntity = (TileEntityCounter) worldIn.getTileEntity(pos);
    EnumDyeColor color = tileEntity.getColor();

    return state.withProperty(COLOR, color);
}

but this only returns RED, obviously, but I don't understand how to get the data from the block.

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

    • 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.