Jump to content

Recommended Posts

Posted (edited)

(man,  this forum's recaptcha thing hates me - I must've spent like five minutes trying to get it to work)

 

So, I've been working on my mod, following Shadowfact's, Jabelar's, and McJty's tutorials. I'm at the point where I'm making entities, and it "works", but the texture isn't appearing. I've copied  McJty's tutorial almost word-for-word, it still isn't there. My mob looks like a weird white rectangle (see attachment)

 

All my code is available here

Hope someone can help!

2017-09-09_17.13.16.png

Edited by Fijal
added version of minecraft
Posted

When I do it like this it gives me the error "initModels cannot be resolved or is not a field"

@Override
public void preInit(FMLPreInitializationEvent e) 
{
	super(ModEntities.initModels);
}

 

Sorry if I'm missing something obvious, I'm still kind of new to this.

 

Also, I'm not sure if I should start a individual post for both of these questions, but I have two more. No. 1 is how do I render .OBJ models? Spoiler for no. 2 because it has some code

Spoiler

So, I have for separate tabs Items, Blocks, Tools, and Misc. I made a separate modId for each tab, because there was only tab when I used the same modId.


// main modId + modId for creative tab 1
public static final String modId = "wofmc";
// modId for creative tab no. 2
public static final String modId1 = "wofmc1";
// modId for creative tab no. 3
public static final String modId2 = "wofmc2";
// modId for creative tab no. 4
public static final String modId3 = "wofmc3";

 

An example of the tab class:


public class WoFMCTabBlocks extends CreativeTabs 
{
	public WoFMCTabBlocks() 
	{
		super(WoFMC.modId1);
	}

	@Override
	public ItemStack getTabIconItem() 
	{
		return new ItemStack(ModBlocks.oreCopper);
	}
}

Surely there's a more effective way to do this?

 

Posted
5 minutes ago, Fijal said:

When I do it like this it gives me the error "initModels cannot be resolved or is not a field"


@Override
public void preInit(FMLPreInitializationEvent e) 
{
	super(ModEntities.initModels);
}

 

Sorry if I'm missing something obvious, I'm still kind of new to this.

 

When you call the super method, you do it by passing the parameter through. Since your ClientProxy extends CommonProxy, iyou want to run the CommonProxy preInit() as well to make sure the actual entity is registered on the client. Like this

 

ModEntities.initModels();

super(e);

 

ISo you're passing the event to the common proxy method.

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Posted

When I do

@Override 	
public void preInit(FMLPreInitializationEvent e) 	
{ 		
	super(e); 
	ModEntities.initModels(); 
}

It gives me the error "Constructor call must be the first statement in a constructor"

I'm doing this in my common proxy class.

Posted
1 hour ago, Fijal said:

When I do


@Override 	
public void preInit(FMLPreInitializationEvent e) 	
{ 		
	super(e); 
	ModEntities.initModels(); 
}

It gives me the error "Constructor call must be the first statement in a constructor"

I'm doing this in my common proxy class.

Do you know Java?

You don't call super in the super class, you call it in the subclass. i.e. the client proxy.

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
8 hours ago, Draco18s said:

Do you know Java?

You don't call super in the super class, you call it in the subclass. i.e. the client proxy.

I haven't taken any courses or anything, but I know some.

9 hours ago, jabelar said:

 

When you call the super method, you do it by passing the parameter through. Since your ClientProxy extends CommonProxy, iyou want to run the CommonProxy preInit() as well to make sure the actual entity is registered on the client. Like this

[...]

ISo you're passing the event to the common proxy method.

I just misread this to mean I should place it in the common proxy.

 

8 hours ago, jabelar said:

Sorry it should actually be 

 

super.preInit(e)

 

You need to call the super method, not the super constructor. Also, you're right it is probably better to call it before the initModels().

So now my client proxy looks like this,

Spoiler

public class ClientProxy extends CommonProxy
{
	@Override
	public void registerItemRenderer(Item item, int meta, String id) 
	{
		ModelLoader.setCustomModelResourceLocation(item, meta, new ModelResourceLocation(WoFMC.modId + ":" + id, "inventory"));
	}	
	
	@Override 	
	public void preInit(FMLPreInitializationEvent e) 	
	{
		super.preInit(e);
		ModEntities.initModels(); 	
	}
}

 

and my common proxy is the same.  There aren't any errors, but it's still a white cube thing.

Posted

Show your ModEntities class.

 

Also, your common proxy should not be the same. For two reasons: 1, you can't call super from the base class, 2, you shouldn't be registering models in it.

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

Here's my ModEntities class

public static void init() 
    {
        // Every entity in our mod has an ID (local to this mod)
        int id = 1;
        EntityRegistry.registerModEntity(new ResourceLocation(WoFMC.modId, "weirdzombie"), EntityWeirdZombie.class, "WeirdZombie", id++, WoFMC.instance, 64, 3, true, 0x996600, 0x00ff00);

        //EntityRegistry.registerModEntity(new ResourceLocation(WoFMC.modId, "weirdzombie"), EntityWeirdZombie.class, "WeirdZombie", id++, WoFMC.instance, 64, 3, true, 0xa699f4, 0xe2defb);

        // Spawn Location
        EntityRegistry.addSpawn(EntityWeirdZombie.class, 100, 100, 100, EnumCreatureType.MONSTER, Biomes.PLAINS, Biomes.ICE_PLAINS, Biomes.DESERT, Biomes.DESERT_HILLS, Biomes.MUTATED_DESERT);

        // Loot Table
        LootTableList.register(EntityWeirdZombie.LOOT);
    }

    @SideOnly(Side.CLIENT)
	public static void initModels() 
    {
        RenderingRegistry.registerEntityRenderingHandler(EntityWeirdZombie.class, RenderWeirdZombie.FACTORY);
    }

 

Also, I meant "the same" as in I hadn't changed anything, not ClientProxy and CommonProxy are identical

Posted

I think the tutorial I used uses CommonProxy as the server proxy.

In the tutorial the code in the main class is

@SidedProxy(serverSide = "com.modname.proxy.CommonProxy", clientSide = "com.modname.proxy.ClientProxy")

Would it make more sense to rename it ServerProxy then? And if so, why do so many tutorials have you make a CommonProxy class?

 

What should I be calling? The only thing in ClientProxy that relates to my entities is

@Override 	
	public void preInit(FMLPreInitializationEvent e) 	
	{
		super.preInit(e);
		ModEntities.initModels(); 	
	}

but that's just loading something in the ModEntities class, I don't see anything to call.

 

Sorry for my obvious ignorance, as you can tell I'm very new to this.

Posted (edited)

So, I renamed CommonProxy.class to ServerProxy.class, made a new CommonProxy.class and moved all the stuff in the new ServerProxy.class to CommonProxy.class (which now that I think about it was a waste of time.) and it works now!

 

I'm not sure what did it, but thank you all for the help you gave me!

(also, thanks for not giving up on me because I don't know tons of Java)

 

Now, to figure out how to load .obj models...

Edit: Is it possible to move the spawn egg from the vanilla tab to my own custom one?

Edited by Fijal
Posted (edited)
31 minutes ago, Fijal said:

Edit: Is it possible to move the spawn egg from the vanilla tab to my own custom one?

If you want to move all spawn eggs then you can just call the public method  Items.SPAWN_EGG.setCreativeTab(your custom tab here). 

 

However, I assume that you just want to do that only for spawn eggs for your custom entities. There might be an easy way to do it but as far as I can tell the EntityRegistry spawn eggs all use the vanilla instance, so I've always done it by making my own custom spawn egg that extends the vanilla ItemMonsterPlacer. I haven't done that in recent versions but "in the old days" there was a time that you had to make custom spawn eggs for your custom entities before they added the hooks. I still have some tutorial information posted at http://jabelarminecraft.blogspot.com/p/minecraft-forge-1721710-creating-custom.html

 

The code was posted for version 1.7.10 so you might need to do a bit of updating but I think the overall concept should still work.

Edited by jabelar

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Posted
1 hour ago, Fijal said:

So, I renamed CommonProxy.class to ServerProxy.class, made a new CommonProxy.class and moved all the stuff in the new ServerProxy.class to CommonProxy.class (which now that I think about it was a waste of time.) and it works now!

Move everything in CommonProxy.class to your main mod class. Then retype the CommonProxy to an interface.

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 (edited)
1 hour ago, Draco18s said:

Move everything in CommonProxy.class to your main mod class. Then retype the CommonProxy to an interface.

Got it. Originally I made it as an interface, like you said, but it gave me a bunch of errors, so I changed it to a .class. I shall fix that.

 

2 hours ago, jabelar said:

If you want to move all spawn eggs then you can just call the public method  Items.SPAWN_EGG.setCreativeTab(your custom tab here). 

 

However, I assume that you just want to do that only for spawn eggs for your custom entities. There might be an easy way to do it but as far as I can tell the EntityRegistry spawn eggs all use the vanilla instance, so I've always done it by making my own custom spawn egg that extends the vanilla ItemMonsterPlacer. I haven't done that in recent versions but "in the old days" there was a time that you had to make custom spawn eggs for your custom entities before they added the hooks. I still have some tutorial information posted at http://jabelarminecraft.blogspot.com/p/minecraft-forge-1721710-creating-custom.html

 

The code was posted for version 1.7.10 so you might need to do a bit of updating but I think the overall concept should still work.

I'll look into that! Thanks

Edited by Fijal
Posted
1 hour ago, Draco18s said:

Move everything in CommonProxy.class to your main mod class. Then retype the CommonProxy to an interface.

I did this and now it's throwing me a bunch of errors. Here's what I did:

  • Moved the contents of CommonProxy.class to Main.class
  • In my CommonProxy.class I changed class to interface
  • Then I changed Client and Server Proxy to implement instead of extend
  • After I saved everything, A few errors popped up. I'm listing them in a spoiler so they save space
Spoiler

proxy.preInit(event); proxy.init(event); and proxy.postInit(event); all throw the error their respective versions of "The method postInit(FMLInitializationEvent) is undefined for the type CommonProxy". Do I need to call these in my main class? The solution suggested by Eclipse is "Create method init(FMLInitializationEvent) in type CommonProxy" If I do that the error goes away, however in ClientProxy,
 


public void preInit(FMLPreInitializationEvent e)
    {

    }

 gives me the error "The method preInit(FMLPreInitializationEvent) of type ClientProxy must override or implement a supertype method". Which is to be expected, since I don't have it there anymore. If I add it to CommonProxy.interface it errors as "Abstract methods do not specify a body". Again, to be expected I suppose.

 

There are quite a few more errors, but I'm not going to list them here unless you want me too.

 

All of that stems from the fact CommonProxy is now a interface, I think. Are you sure it should be an interface? One of the tutorials (MrCrayfish's) made it as one, but none of the others I've seen have.

 

Posted (edited)

What I've ended up doing was create the CommonProxy as an interface.

public interface CommonProxy
{
    void preInit();
    void init();
    void postInit();

    void registerItemRender(Item item, int meta, String id);
}

 

I then proceed to put the client logic into the ClientProxy.

public class ClientProxy implements CommonProxy
{
    @Override
    public void preInit()
    {
    }

    @Override
    public void init()
    {
    }

    @Override
    public void postInit()
    {
    }

    @Override
    public void registerItemRender(Item item, int meta, String id)
    {
        ModelLoader.setCustomModelResourceLocation(
                item,
                meta,
                new ModelResourceLocation(Reference.PREFIX + id, "inventory")
        );
    }
}

 

And then, finally, server stuff!

public class ServerProxy implements CommonProxy
{
    @Override
    public void preInit()
    {
    }

    @Override
    public void init()
    {
    }

    @Override
    public void postInit()
    {
    }

    @Override
    public void registerItemRender(Item item, int meta, String id)
    {
    }
}

 

Granted, Draco and jabelar know a lot more than me, but this is my current setup. Not much different then just a ClientProxy and ServerProxy.

 

Though, I probably should be implementing the FMLInitializationEvent thingies....

Edited by Splashsky
Posted

I still go by the ClientProxy extends CommonProxy setup myself. <_<

 

Mind, that came in handy when I built my EasyRegistry (they act as a common and client proxy, with the common actually containing a large portion of code, but code that makes no sense to be anywhere else).

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 (edited)
16 minutes ago, Splashsky said:

Granted, Draco and jabelar know a lot more than me, but this is my current setup. Not much different then just a ClientProxy and ServerProxy.

 

Though, I probably should be implementing the FMLInitializationEvent thingies....

Yeah, I'm 100% sure they know more than me

 

Well, it works for me! I tried to add the FMLInitializationEvent things, but it gave some errors.

 

Edit: Hmm I can't find how to quote someone when editing a post. So, this is directed at Draco. If CommonProxy is an interface don't you have to implement it instead of extend?

 

Edited by Fijal
Posted
55 minutes ago, Fijal said:

Edit: Hmm I can't find how to quote someone when editing a post. So, this is directed at Draco. If CommonProxy is an interface don't you have to implement it instead of extend?

Yes.

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

Which is what I thought. But if you believe ClientProxy should extend, not implement CommonProxy, why'd you direct me to make CommonProxy an interface?

 

Eh, I suppose it doesn't matter.

Posted
46 minutes ago, Fijal said:

Which is what I thought. But if you believe ClientProxy should extend, not implement CommonProxy, why'd you direct me to make CommonProxy an interface?

FFS. They are two different ways of doing the same thing. You either make a common proxy (which is used server side) and extend it for the client proxy, or you make the common proxy an interface which the server and client proxy implement.

 

I never said "I believe ClientProxy should extend" I said I still do it this way, even though it is bad.

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
38 minutes ago, Fijal said:

Which is what I thought. But if you believe ClientProxy should extend, not implement CommonProxy, why'd you direct me to make CommonProxy an interface?

 

Eh, I suppose it doesn't matter.

In coding there are many ways to achieve the same thing, and some of it is just preference and some of it is situational. Regarding preference, as diesieben07 mentioned earlier there is some argument remaining about the best way to do this and the terminology but most people have found a way that works for them and stuck with it.

 

In the end, the main point is that the proxy annotation allows you to point to a class that is loaded differently depending on which logical side is running. It is particularly useful for code that has the name but you want to operate differently on each side, because if there is code that is only run on one side you can just annotate it directly (that is why you also see methods, fields and classes with sided annotation sprinkled through other classes). The FML Lifecycle events (a.k.a. pre-init, init, post-init, etc.) are commonly ones that you collect in the proxy although some people find cases where they have other custom methods they want to run differently on each side and so also collect those there.

 

From there you can do many things so long as you collect all your sided code accordingly and respect the regular rules of Java inheritance. 

 

If it works, it is valid. Whether it is the best way depends on philosophy and situation. 

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Posted
57 minutes ago, Draco18s said:

I never said "I believe ClientProxy should extend" I said I still do it this way, even though it is bad.

ohhhh so you did. My bad, sorry!

 

@jabelar ah, got it. That makes sense

Posted

This into your common proxy pre init.

        int id = 1;
        EntityRegistry.registerModEntity(EntityWeirdZombie.class, "WeirdZombie", id++, TheWizardMod.instance, 64, 3, true, 0x996600, 0xff00ff);
        // We want our mob to spawn in Plains and ice plains biomes. If you don't add this then it will not spawn automatically
        // but you can of course still make it spawn manually
        EntityRegistry.addSpawn(EntityWeirdZombie.class, 100, 3, 5, EnumCreatureType.MONSTER, Biomes.PLAINS, Biomes.ICE_PLAINS);

 

And this into your client pre init

      RenderingRegistry.registerEntityRenderingHandler(EntityWeirdZombie.class, RenderWeirdZombie.FACTORY);

 

Don't forget, that the zombie will only spawn in plains and icy biomes then, if you don't extend it.

And change the instance to yours.

 

I followed the same tutorials like you, i think. 9_9

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() ); } }  
  • Topics

×
×
  • Create New...

Important Information

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