Jump to content

Recommended Posts

Posted

As the title says i need all classes of my mod,
because i want to output them firstly on the console (for debugging),
and secondly for a custom registration of recipes.

I looked at the code from forge for the AutomaticEventSubscriber registration and understand it only partially.
I also have this code that gives me a ModFileScanData:

ModList.get().getModFileById(Nero.MOD_ID).getFile().getScanResult()

ModFileScanData has the getClasses method, which unfortunately gives me an unusable class,
because I don't get any classes or anything back from a ClassData

is there a way to get all classes of my mod?

Posted
1 hour ago, diesieben07 said:

This is a terrible idea. What do recipes have to do with getting all classes?

I have a custom recipe system, I use annotations to register the recipe methods faster and easier,
which currently only works in classes that extend my recipe helper.
I would like to extend this to all classes that have an annotation similar to the event registration of forge.


I also need the classes for a config system in which I add an annotation to a fields and these are automatically added to my config,
the implementaion is not perfect/finished but here is a small example:
 

	@ConfigValue(valueName = "example", comment = "This is an example")
	public static int example;

 

Posted
16 hours ago, diesieben07 said:

This is a valid use case, but it does not require you to "list all classes of the mod".
Use ModFileScanData#getAnnotations to find things annotated with your annotation, then process them however you like.

with which method do I get the object which has the annotation

Posted
7 minutes ago, diesieben07 said:

AnnotationData#getAnnotationType: The class of the annotation.

AnnotationData#getTargetType: The type of element that was annotated (e.g. field, method, class)

AnnotationData#getClassType: The class of the element that was annotated (for fields and methods this is the containing class)

AnnotationData#getMemberName: The name of the element that was annotated (for fields and methods this is the name, for classes it is the class name).

If I look at the AnnotationData and the methods you have listed, I cannot find a usable method
since I can't do anything with the target/class type, the name of the target doesn't help with fields and methods either.

what does the map contain, the AnnotationData#getAnnotationData returns

Posted
On 6/7/2021 at 9:20 PM, diesieben07 said:

This is a valid use case, but it does not require you to "list all classes of the mod".
Use ModFileScanData#getAnnotations to find things annotated with your annotation, then process them however you like.

I have now created a custom config system which also works,
but I get an error that is actually not possible:
log part:

[11:43:37] [modloading-worker-1/WARN] [ne.lu.ne.Nero/]: Can't define Config Value coalXpMin
java.lang.IllegalArgumentException: Can not set net.minecraftforge.common.ForgeConfigSpec$ConfigValue field net.luis.nero.api.block.ModOreBlock.coalXpMin to net.minecraftforge.common.ForgeConfigSpec$ConfigValue

 

complete log:
log.log

this is the config class
this is the config value class

 

Posted (edited)
2 hours ago, diesieben07 said:

You have to use the correct ClassLoader when loading the classes, look at what AutomaticEventSubscriber does.

okay AutomaticEventSubscriber uses the ClassLoader of the mod main class,
but I didn't use a ClassLoader in my code, so where do I have to set/use the ClassLoader?

Edited by Luis_ST
Posted
44 minutes ago, diesieben07 said:

You have to do it the same way AutomaticEventSubscriber does.

huh? AutomaticEventSubscriber uses the ClassLoader to register the event to the EventBus,
but I don't have to register anything

Posted
1 hour ago, diesieben07 said:

No, it uses the class loader when looking up the class by name. You also look up the class by name, but you do not specify the class loader.

okay makes sense, but can i get the ClassLoader of my main mod class?
can i do something like that:
 

Nero.class.getClassLoader()

 

Posted
1 hour ago, diesieben07 said:

I can't reproduce this, the game starts up fine when I cloned your repo.

yes the game starts, the config is also created,
but the try-catch block still catches an exception for each ConfigValue,

I also get a NullPointerException when I use the values that I set via reflection in the code (xp drop of my custom ores)

Posted
2 hours ago, diesieben07 said:

The first parameter to Field#set is the instance holding the field. You're giving it the ConfigValue every time, but ConfigValue is not the class holding the field.

so i need the class of the ConfigValue there?
and ConfigValue.class doesn't work

Posted
1 hour ago, diesieben07 said:

No. Here configField is a field in configClass. So if you call field.set you need to pass in an instance of configClass (so that the field knows on which instance to set the field...) or null for static fields. Read the documentation for Field#set if you do not understand this.

I understood how the method works my problem is that I don't have an instance of ConfigValue,
I can't create a temporary new one and if I need the instance from the class in which the ConfigValue is located that I want to add to the config,
the automatic addition is "for the bucket".

the other possibility would be to set the fields with the ConfigValues to static, but i dont want to do that.

Posted
9 minutes ago, diesieben07 said:

Why do you not want the fields to be static?

damn i mean final, thanks this fixed the problem
and is this important, or is this just debbing:
 

Null comment for config option Nero Common Config, this is invalid and may be disallowed in the future.

 

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.