Jump to content

Recommended Posts

Posted

Hello, i'm new to modding and also this forum.

I'm also new to java, but i have a basic understanding of c++. It looks alot the same in my opinion!

I looked into several tutorials and learned alot in a short time.

I've recently started creating my own mod and it goes pretty well atm.(been busy for 3 weeks now).

I made a bunch of new stones and stairs and slabs (and yes the slabs work like they should).

 

But now i want to know how to start for making an addon for an existing mod.

I want to make an addon for Biomes O' Plenty, just because i like this mod very very much.

I just don't know where to start and how?

 

For example:

 

I want to make stairs for let's say ashstone. I know how to make stairs, but how to load in into my mod?

I hope someone can help me showing me the direction.

 

greetz

 

Posted

I don't really have time to dig into that mod's forum/whatever, but you should find it.

 

Look for either API or decompiled source.

For source - just add it and you are fine.

For API - throw it somewhere, go to Build Path -> "Libraries -> Add JARs.... Add API.jar.

Then (as any API should) you can attach source to API (find it in list and add API-src.zip/jar.

Any how-to can be found on google.

 

Add dependency to your @Mod.

@Mod(dependencies = "required-after:APIModID@[1.0.0.0,);") // adding @ defines "minimal version".

There are also other dependency keys - google them.

 

Above is how to get references to actual mod. If you want mod to just run in background - throw it into /mods/.

Note - you should never do both (add to /mods/ and libraries) - it will attempts to load twice.

 

Note: There were some changes in 1.8+ regarding running obfuscated mods - still in your case you need API/decomp src.

1.7.10 is no longer supported by forge, you are on your own.

  • 3 weeks later...
Posted

Now i can see the biome o plenty mod in the reference lib, and everything is there. I can see in all classes etc etc.

But when i start the game now i get this error:

There was a severe problem during mod loading that has caused the game to fail

cpw.mods.fml.common.LoaderException: java.lang.NoSuchMethodError: net.minecraft.client.Minecraft.func_71410_x()Lnet/minecraft/client/Minecraft;

 

in the error i see this too:

 

Caused by: java.lang.NoSuchMethodError: net.minecraft.client.Minecraft.func_71410_x()Lnet/minecraft/client/Minecraft;

at biomesoplenty.ClientProxy.<init>(ClientProxy.java:49)

Can i fix this?

Posted

I fixed it with installing code chicken core. it does the deobf while running it. Now it works fine.

How do i use now an existing block from that mod ?

For example i want to make stairs from ashStone.

I tried this:

GameRegistry.registerBlock(ashstonestairs = new Customstairs(GameData.getBlockRegistry().getObject("BiomesOPlenty:ashStone"), 0).setBlockName("ashstonestairs"),"ashstonestairs" ).setCreativeTab(TemBlocks.extrastairs);

The game starts but the block has no textures. Even when setting manually a texture with .setBlockTextureName("something") it has no texture.

I made a class for the addon, here i add all the stuff i want to add when having the mod installed.

I did a check in the class where i register all my own blocks if the mod is present and if yes then load all the "additions" for it.

if(Loader.isModLoaded("BiomesOPlenty")){
	BOPBlocksAddon.init();
	}

This works all fine, i just have no textures. So what am i doing wrong?

 

Posted

I fixed it with installing code chicken core. it does the deobf while running it. Now it works fine.

How do i use now an existing block from that mod ?

For example i want to make stairs from ashStone.

I tried this:

GameRegistry.registerBlock(ashstonestairs = new Customstairs(GameData.getBlockRegistry().getObject("BiomesOPlenty:ashStone"), 0).setBlockName("ashstonestairs"),"ashstonestairs" ).setCreativeTab(TemBlocks.extrastairs);

The game starts but the block has no textures. Even when setting manually a texture with .setBlockTextureName("something") it has no texture.

I made a class for the addon, here i add all the stuff i want to add when having the mod installed.

I did a check in the class where i register all my own blocks if the mod is present and if yes then load all the "additions" for it.

if(Loader.isModLoaded("BiomesOPlenty")){
	BOPBlocksAddon.init();
	}

This works all fine, i just have no textures. So what am i doing wrong?

 

Are you sure you have the right directory / folder and everything?

 

The texture name would be: :modid/ + name

e.g. for something mymod with a block called baddirt

setBlockTextureName(":mymod/baddirt");

 

while if you used a subfolder it would be:  :modid/ + subdirectory + name

e.g. fro something with a graphic at

src/main/resources/assets/mf1inmf2/textures/blocks/slate0.png

setBlockTextureName(":mf1inmf2/basic/slate0");

 

Note that I've yet to make stairs, so I don't know about them specifically, so if its a stairs thing that's going wrong I probably can't help -- so far I've just made basic blocks and meta-block varieties, since most of my experience in modding is world gen.

Developer of Doomlike Dungeons.

Posted

this is what i see in the console when i start up and load a world:

 

[14:43:21] [main/INFO] [GradleStart]: Extra: []

[14:43:21] [main/INFO] [GradleStart]: Running with arguments: [--userProperties, {}, --assetsDir, C:/Users/Timmy/.gradle/caches/minecraft/assets, --assetIndex, 1.7.10, --accessToken, {REDACTED}, --version, 1.7.10, --tweakClass, cpw.mods.fml.common.launcher.FMLTweaker, --tweakClass, net.minecraftforge.gradle.tweakers.CoremodTweaker]

[14:43:21] [main/INFO] [LaunchWrapper]: Loading tweak class name cpw.mods.fml.common.launcher.FMLTweaker

[14:43:21] [main/INFO] [LaunchWrapper]: Using primary tweak class name cpw.mods.fml.common.launcher.FMLTweaker

[14:43:21] [main/INFO] [LaunchWrapper]: Loading tweak class name net.minecraftforge.gradle.tweakers.CoremodTweaker

[14:43:21] [main/INFO] [LaunchWrapper]: Calling tweak class cpw.mods.fml.common.launcher.FMLTweaker

[14:43:21] [main/INFO] [FML]: Forge Mod Loader version 7.99.39.1566 for Minecraft 1.7.10 loading

[14:43:21] [main/INFO] [FML]: Java is Java HotSpot 64-Bit Server VM, version 1.8.0_73, running on Windows 7:amd64:6.1, installed at C:\Program Files\Java\jdk1.8.0_73\jre

[14:43:21] [main/INFO] [FML]: Managed to load a deobfuscated Minecraft name- we are in a deobfuscated environment. Skipping runtime deobfuscation

[14:43:21] [main/WARN] [FML]: The coremod codechicken.core.launch.CodeChickenCorePlugin does not have a MCVersion annotation, it may cause issues with this version of Minecraft

[14:43:22] [main/INFO] [LaunchWrapper]: Calling tweak class net.minecraftforge.gradle.tweakers.CoremodTweaker

[14:43:22] [main/INFO] [GradleStart]: Injecting location in coremod cpw.mods.fml.relauncher.FMLCorePlugin

[14:43:22] [main/INFO] [GradleStart]: Injecting location in coremod net.minecraftforge.classloading.FMLForgePlugin

[14:43:22] [main/INFO] [GradleStart]: Injecting location in coremod codechicken.core.asm.MCPDeobfuscationTransformer.LoadPlugin

[14:43:22] [main/INFO] [GradleStart]: Injecting location in coremod codechicken.core.launch.CodeChickenCorePlugin

[14:43:22] [main/INFO] [LaunchWrapper]: Loading tweak class name cpw.mods.fml.common.launcher.FMLInjectionAndSortingTweaker

[14:43:22] [main/INFO] [LaunchWrapper]: Loading tweak class name cpw.mods.fml.common.launcher.FMLDeobfTweaker

[14:43:22] [main/INFO] [LaunchWrapper]: Loading tweak class name net.minecraftforge.gradle.tweakers.AccessTransformerTweaker

[14:43:22] [main/INFO] [LaunchWrapper]: Calling tweak class cpw.mods.fml.common.launcher.FMLInjectionAndSortingTweaker

[14:43:22] [main/INFO] [LaunchWrapper]: Calling tweak class cpw.mods.fml.common.launcher.FMLInjectionAndSortingTweaker

[14:43:22] [main/INFO] [LaunchWrapper]: Calling tweak class cpw.mods.fml.relauncher.CoreModManager$FMLPluginWrapper

[14:43:22] [main/ERROR] [FML]: The binary patch set is missing. Either you are in a development environment, or things are not going to work!

[14:43:23] [main/ERROR] [FML]: FML appears to be missing any signature data. This is not a good thing

[14:43:23] [main/INFO] [LaunchWrapper]: Calling tweak class cpw.mods.fml.relauncher.CoreModManager$FMLPluginWrapper

[14:43:23] [main/INFO] [LaunchWrapper]: Calling tweak class cpw.mods.fml.relauncher.CoreModManager$FMLPluginWrapper

[14:43:23] [main/INFO] [LaunchWrapper]: Calling tweak class cpw.mods.fml.relauncher.CoreModManager$FMLPluginWrapper

[14:43:23] [main/INFO] [LaunchWrapper]: Calling tweak class cpw.mods.fml.common.launcher.FMLDeobfTweaker

[14:43:24] [main/INFO] [LaunchWrapper]: Calling tweak class net.minecraftforge.gradle.tweakers.AccessTransformerTweaker

[14:43:24] [main/INFO] [LaunchWrapper]: Loading tweak class name cpw.mods.fml.common.launcher.TerminalTweaker

[14:43:24] [main/INFO] [LaunchWrapper]: Calling tweak class cpw.mods.fml.common.launcher.TerminalTweaker

[14:43:24] [main/INFO] [LaunchWrapper]: Launching wrapped minecraft {net.minecraft.client.main.Main}

[14:43:25] [main/INFO]: Setting user: Player116

[14:43:27] [Client thread/INFO]: LWJGL Version: 2.9.1

[14:43:28] [Client thread/INFO] [sTDOUT]: [cpw.mods.fml.client.SplashProgress:start:188]: ---- Minecraft Crash Report ----

// Everything's going to plan. No, really, that was supposed to happen.

 

Time: 25/04/16 14:43

Description: Loading screen debug info

 

This is just a prompt for computer specs to be printed. THIS IS NOT A ERROR

 

 

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

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

 

-- System Details --

Details:

Minecraft Version: 1.7.10

Operating System: Windows 7 (amd64) version 6.1

Java Version: 1.8.0_73, Oracle Corporation

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

Memory: 821351312 bytes (783 MB) / 1037959168 bytes (989 MB) up to 1037959168 bytes (989 MB)

JVM Flags: 3 total; -Xincgc -Xmx1024M -Xms1024M

AABB Pool Size: 0 (0 bytes; 0 MB) allocated, 0 (0 bytes; 0 MB) used

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

FML:

GL info: ' Vendor: 'NVIDIA Corporation' Version: '4.5.0 NVIDIA 364.51' Renderer: 'GeForce GTX 560/PCIe/SSE2'

[14:43:28] [Client thread/INFO] [MinecraftForge]: Attempting early MinecraftForge initialization

[14:43:28] [Client thread/INFO] [FML]: MinecraftForge v10.13.4.1566 Initialized

[14:43:28] [Client thread/INFO] [FML]: Replaced 183 ore recipies

[14:43:28] [Client thread/INFO] [MinecraftForge]: Completed early MinecraftForge initialization

[14:43:28] [Client thread/INFO] [FML]: Found 0 mods from the command line. Injecting into mod discoverer

[14:43:28] [Client thread/INFO] [FML]: Searching C:\Users\Timmy\Desktop\modding tut\eclipse\mods for mods

[14:43:28] [Client thread/INFO] [FML]: Also searching C:\Users\Timmy\Desktop\modding tut\eclipse\mods\1.7.10 for mods

[14:43:34] [Client thread/INFO] [FML]: Forge Mod Loader has identified 6 mods to load

[14:43:34] [Client thread/INFO] [FML]: FML has found a non-mod file CodeChickenLib-1.7.10-1.1.3.138-dev.jar in your mods directory. It will now be injected into your classpath. This could severe stability issues, it should be removed if possible.

[14:43:35] [Client thread/INFO] [FML]: Attempting connection with missing mods [mcp, FML, Forge, CodeChickenCore, tem, BiomesOPlenty] at CLIENT

[14:43:35] [Client thread/INFO] [FML]: Attempting connection with missing mods [mcp, FML, Forge, CodeChickenCore, tem, BiomesOPlenty] at SERVER

[14:43:35] [Client thread/INFO]: Reloading ResourceManager: Default, FMLFileResourcePack:Forge Mod Loader, FMLFileResourcePack:Minecraft Forge, FMLFileResourcePack:Tim's Expansion Mod, FMLFileResourcePack:Biomes O' Plenty

[14:43:35] [Client thread/INFO] [FML]: Processing ObjectHolder annotations

[14:43:35] [Client thread/INFO] [FML]: Found 341 ObjectHolder annotations

[14:43:35] [Client thread/INFO] [FML]: Identifying ItemStackHolder annotations

[14:43:35] [Client thread/INFO] [FML]: Found 0 ItemStackHolder annotations

[14:43:35] [Client thread/INFO] [FML]: Configured a dormant chunk cache size of 0

[14:43:37] [Client thread/INFO] [biomesOPlenty]: Trail info successfully received from remote.

[14:43:37] [Client thread/INFO] [FML]: Applying holder lookups

[14:43:37] [Client thread/INFO] [FML]: Holder lookups applied

[14:43:37] [Client thread/INFO] [FML]: Injecting itemstacks

[14:43:37] [Client thread/INFO] [FML]: Itemstack injection complete

[14:43:37] [sound Library Loader/INFO] [sTDOUT]: [paulscode.sound.SoundSystemLogger:message:69]:

[14:43:37] [sound Library Loader/INFO] [sTDOUT]: [paulscode.sound.SoundSystemLogger:message:69]: Starting up SoundSystem...

[14:43:37] [Thread-9/INFO] [sTDOUT]: [paulscode.sound.SoundSystemLogger:message:69]: Initializing LWJGL OpenAL

[14:43:37] [Thread-9/INFO] [sTDOUT]: [paulscode.sound.SoundSystemLogger:message:69]:    (The LWJGL binding of OpenAL.  For more information, see http://www.lwjgl.org)

[14:43:38] [Thread-9/INFO] [sTDOUT]: [paulscode.sound.SoundSystemLogger:message:69]: OpenAL initialized.

[14:43:38] [sound Library Loader/INFO] [sTDOUT]: [paulscode.sound.SoundSystemLogger:message:69]:

[14:43:38] [sound Library Loader/INFO]: Sound engine started

[14:43:41] [Client thread/INFO]: Created: 16x16 textures/blocks-atlas

[14:43:41] [Client thread/INFO]: Created: 16x16 textures/items-atlas

[14:43:41] [Client thread/ERROR] [CodeChickenCore]: Unable to do mod description scrolling due to lack of stencil buffer

[14:43:41] [Client thread/INFO] [FML]: Injecting itemstacks

[14:43:41] [Client thread/INFO] [FML]: Itemstack injection complete

[14:43:41] [Client thread/INFO] [FML]: Forge Mod Loader has successfully loaded 6 mods

[14:43:41] [Client thread/INFO]: Reloading ResourceManager: Default, FMLFileResourcePack:Forge Mod Loader, FMLFileResourcePack:Minecraft Forge, FMLFileResourcePack:Tim's Expansion Mod, FMLFileResourcePack:Biomes O' Plenty

[14:43:42] [Client thread/INFO]: Created: 512x512 textures/blocks-atlas

[14:43:42] [Client thread/INFO]: Created: 512x256 textures/items-atlas

[14:43:42] [Client thread/INFO] [sTDOUT]: [paulscode.sound.SoundSystemLogger:message:69]:

[14:43:42] [Client thread/INFO] [sTDOUT]: [paulscode.sound.SoundSystemLogger:message:69]: SoundSystem shutting down...

[14:43:42] [Client thread/INFO] [sTDOUT]: [paulscode.sound.SoundSystemLogger:importantMessage:90]:    Author: Paul Lamb, www.paulscode.com

[14:43:42] [Client thread/INFO] [sTDOUT]: [paulscode.sound.SoundSystemLogger:message:69]:

[14:43:42] [sound Library Loader/INFO] [sTDOUT]: [paulscode.sound.SoundSystemLogger:message:69]:

[14:43:42] [sound Library Loader/INFO] [sTDOUT]: [paulscode.sound.SoundSystemLogger:message:69]: Starting up SoundSystem...

[14:43:42] [Thread-12/INFO] [sTDOUT]: [paulscode.sound.SoundSystemLogger:message:69]: Initializing LWJGL OpenAL

[14:43:42] [Thread-12/INFO] [sTDOUT]: [paulscode.sound.SoundSystemLogger:message:69]:    (The LWJGL binding of OpenAL.  For more information, see http://www.lwjgl.org)

[14:43:42] [Thread-12/INFO] [sTDOUT]: [paulscode.sound.SoundSystemLogger:message:69]: OpenAL initialized.

[14:43:43] [sound Library Loader/INFO] [sTDOUT]: [paulscode.sound.SoundSystemLogger:message:69]:

[14:43:43] [sound Library Loader/INFO]: Sound engine started

[14:44:41] [server thread/INFO]: Starting integrated minecraft server version 1.7.10

[14:44:41] [server thread/INFO]: Generating keypair

[14:44:41] [server thread/INFO] [FML]: Injecting existing block and item data into this server instance

[14:44:41] [server thread/INFO] [FML]: Applying holder lookups

[14:44:41] [server thread/INFO] [FML]: Holder lookups applied

[14:44:41] [server thread/INFO] [FML]: Loading dimension 0 (New World) (net.minecraft.server.integrated.IntegratedServer@7d7e292d)

[14:44:41] [server thread/INFO] [FML]: Loading dimension 1 (New World) (net.minecraft.server.integrated.IntegratedServer@7d7e292d)

[14:44:41] [server thread/INFO] [FML]: Loading dimension -1 (New World) (net.minecraft.server.integrated.IntegratedServer@7d7e292d)

[14:44:41] [server thread/INFO]: Preparing start region for level 0

[14:44:42] [server thread/INFO]: Changing view distance to 12, from 10

[14:44:43] [Netty Client IO #0/INFO] [FML]: Server protocol version 2

[14:44:43] [Netty IO #1/INFO] [FML]: Client protocol version 2

[14:44:43] [Netty IO #1/INFO] [FML]: Client attempting to join with 6 mods : [email protected],[email protected],[email protected],[email protected],[email protected],[email protected]

[14:44:43] [Netty IO #1/INFO] [FML]: Attempting connection with missing mods [] at CLIENT

[14:44:43] [Netty Client IO #0/INFO] [FML]: Attempting connection with missing mods [] at SERVER

[14:44:43] [server thread/INFO] [FML]: [server thread] Server side modded connection established

[14:44:43] [Client thread/INFO] [FML]: [Client thread] Client side modded connection established

[14:44:43] [server thread/INFO]: Player116[local:E:ef1dd6ca] logged in with entity id 412 at (32.679943133582384, 65.0, 266.68128256586186)

[14:44:43] [server thread/INFO]: Player116 joined the game

[14:44:48] [server thread/INFO]: Saving and pausing game...

[14:44:48] [server thread/INFO]: Saving chunks for level 'New World'/Overworld

[14:44:48] [server thread/INFO]: Saving chunks for level 'New World'/Nether

[14:44:48] [server thread/INFO]: Saving chunks for level 'New World'/The End

 

in my opinion nothing special.

As for the texture i do not apply 1, because i make stairs out of that block and that block has a texture.

At least this works for my own blocks. If i change the biome o plenty block into 1 of my own blocks or 1 of minecraft, it then works.

But just in case i tested it with supplying a texture of my own and also tested it with supplying the texture it from BOP.

It also see no error saying it has no texture. So somehow it knows the texture but does not apply it.

 

Posted

So i tried something new, based on some info i found.

public static final void init(){

	 GameRegistry.registerBlock(ashstonestairs = new Customstairs(getBlock("BiomesOPlenty:ashStone"), 0).setBlockName("ashstonestairs"),"ashstonestairs" ).setCreativeTab(TemBlocks.extrastairs);


}
public static Block getBlock(String name) {
	Block block = (Block) Block.blockRegistry.getObject(name);
	if (block == null || block == Blocks.air)
		throw new NullPointerException("Could not find any blocks named " + name);
	return block;
}

But now it gives me that error, wich is weird because the block IS there.

If i try to supply a block from minecraft or 1 of mine it works! What am i doing wrong?

Why can't it find the block, i'm very sure the name is correct. I can also find the block ingame in the bop tab.

 

EDIT:

I tried initializing it in the postinit of my proxy, because you never know and it worked...

 

package winnetrie.tem;

import winnetrie.tem.block.BOPBlocksAddon;
import winnetrie.tem.block.TemBlocks;
import winnetrie.tem.block.ColoredSlab;
import winnetrie.tem.crafting.TemRecipes;
import winnetrie.tem.item.TemItems;
import winnetrie.tem.item.TemTools;
import cpw.mods.fml.common.Loader;
import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
import cpw.mods.fml.common.registry.GameRegistry;

public class CommonProxy {
public void preInit(FMLPreInitializationEvent event) {
	TemItems.init();
	TemBlocks.init();
	TemTools.init();





    }

    public void init(FMLInitializationEvent event) {
    	TemRecipes.init();
    	GameRegistry.registerWorldGenerator(new ChalkStoneGenerator(), 1);

    }

    public void postInit(FMLPostInitializationEvent event) {
    	if(Loader.isModLoaded("BiomesOPlenty")){
		BOPBlocksAddon.init();
		}
    }



}

I have all my own block in the preinit

Why do i have to put the addon block in the postinit to let it work?

Is this because the mod has to be loaded first before you can qeue something?

It now works but if something is still not good or wrong i'll be happy to hear it.

Posted

Ah!  Now I know what's happening, though should have thought of it before.  Its about the order the mods load.  Your mod was being loaded before BoP, so the BoP resources weren't there yet.  By moving it to post init it insured that all other mods had been at least loaded (and should have gone through pre-init and init as well).  By putting it in pre-init it meant that some mods might not even have been loaded.

 

You should try defining and registering blocks in init -- technically pre-init is for things like reading in config files and setting options.  Init is for initializing your main content, like including blocks, and post init is there to allow for inter-mod compatibility, by allowing things to be done after other mods have initialized.  Register in init should work, since BoP resources should be loaded by then, but if not you can always go back to post-init.  But doing this in pre-init was not the correct place and probably cause the problem.

 

EDIT: The reason post-init might not be the best place is that it could cause problem if another mod wants to use your block -- for example, I have Doomlike Dungeons read in themes in post-init so blocks from other mods can be used -- if you're block didn't exist yet then my mod might crash if someone had added it to a theme.

Developer of Doomlike Dungeons.

Posted

Blocks and items should be registered in preInit, not init.

 

Use the

dependencies

attribute of your

@Mod

annotation (as Ernio said) to ensure your mod loads after BoP.

 

Edit: It was Ernio who originally mentioned the

dependencies

attribute, not diesieben07 as I said previously.

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

 

Use the

dependencies

attribute of your

@Mod

annotation (as diesieben07 said) to ensure your mod loads after BoP.

wouldn't that make my mod depending on BOP? If so, i don't want that.

My mod is a mod on his own, but whenever BOP is installed too you have the extra stuff

 

That is true.  If your mod really is an add-on it should have the other as a dependency, but if its not that's a problem.  I know there is a way to make a mod a "soft" dependency, that doesn't require the other but loads after it because Lycanite did that with my mod -- but I don't know how (its something I've been wanting to learn myself).  But if its not technically an add-on, if its its own mod, it really shouldn't have a hard dependency.

Developer of Doomlike Dungeons.

Posted

before:xyz means "load before xyz if it present"

required-before:xyz "load before xyz and fail if it's missing"

 

Same with after.

 

Ow,this is nice. I didn't know you can do "before" and "after" alone.

I always thought it has to be "required-after" or "required-before".

 

thank you very much!! Seems to work all fine now!

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.