-
Posts
167 -
Joined
-
Last visited
Everything posted by Turtledove
-
How do I use Capabilities for this (1.15.2)
Turtledove replied to TheSnufe's topic in Modder Support
This tutorial from 1.12.2 is as easy as anyone could possibly explain it, it hasn't changed much til now except some slight changes here and there for you to figure out, it's pretty straightforward (https://www.planetminecraft.com/blog/forge-tutorial-capability-system/). Obviously instead of mana you'd just replace it with whatever else you're doing. All a capability is in essence is the ability to serialize/deserialize standard data types to an entity. When the player dies the game creates a new instance of a PlayerEntity object so your data won't automatically "transfer" over to that new object unless as you say, you copy the data over in an event hook. After you have this set up, if you want to access the data you store in player capabilities you create a class with a static get function that retrieves it.- 1 reply
-
- 1
-
-
What do the other parameters in setBlock do?
Turtledove replied to Turtledove's topic in Modder Support
I know what it was, I wrote getWorld() as a wrapper method for classes that implement IWorld, but I guess I missed that that method isn't listed as a function in the interface. 0 IQ moment. -
What do the other parameters in setBlock do?
Turtledove replied to Turtledove's topic in Modder Support
...Again, there is literally no function that takes in just two parameters. But anyways thanks for that, I'll look into the flags, never realized it was a thing when blocks are placed. -
What do the other parameters in setBlock do?
Turtledove replied to Turtledove's topic in Modder Support
well technically a quaternion IS a vector with just an exra real valued number -
What do the other parameters in setBlock do?
Turtledove replied to Turtledove's topic in Modder Support
There were several notable changes I noticed refactoring my code from 16.3 to 16.5, not just the above, but also the fact that rotations on the renderer now take quaternions as inputs rather than just a vector representing the rotations. -
What do the other parameters in setBlock do?
Turtledove replied to Turtledove's topic in Modder Support
...except it clearly did, here's the snippet from 1.16.3, take a look for yourself if you didn't know: and now in 1.16.5: -
I'm updating my mod from 1.16.3 to 1.16.5, and I noticed that the setBlockState method has been replaced with setBlock, but it has two additional integer parameters apart from the standard blockstate and block position arguments. Looking at the implementation of the method didn't help because all the variable names are obfuscated. Anyone have any idea?
-
Say I have a class called PlayerStatHandler that subscribes to the event bus, and in that class I have a member called: int monsterKillCount On the logical server, let's then say I set the value of monsterKillCount in an event hook method, an event that is called when a monster is killed. When there are multiple players, do each of them get their own instance of PlayerStatHandler's members, or is there just one for the entire logical server?
-
Server->Client packets aren't working [1.16.3]
Turtledove replied to Turtledove's topic in Modder Support
Solved it myself: when handle() is called it's (in the context of server->client) called on the logical client, ctx.getSender() is going to return null. So just use Minecraft.instance.player. -
The following is my packet registry. The Client->Server packets work just fine, it's just the Server->Client ones where the context sender is null. so I'm certain I'm just missing something stupid: public final class PacketRegistry { /** * The ID for the next packet registration. */ private static final String PROTOCOL_VERSION = Integer.toString(1); private byte nextPacketID = 0; /** * The internal network wrapper. */ private static final SimpleChannel wrapper = NetworkRegistry.ChannelBuilder .named(new ResourceLocation(Withernauts.MODID, "main_channel")) .clientAcceptedVersions(PROTOCOL_VERSION::equals) .serverAcceptedVersions(PROTOCOL_VERSION::equals) .networkProtocolVersion(() -> PROTOCOL_VERSION) .simpleChannel(); public void registerPackets() { //register packets going to the client registerServerToClient(MotionPlayerPacket.class, MotionPlayerPacket::encode, MotionPlayerPacket::decode, MotionPlayerPacket::handle); registerServerToClient(PlayerLoadingPacket.class, PlayerLoadingPacket::encode, PlayerLoadingPacket::decode, PlayerLoadingPacket::handle); //register packets going to the server registerClientToServer(CrouchSyncPacket.class, CrouchSyncPacket::encode, CrouchSyncPacket::decode, CrouchSyncPacket::handle); registerClientToServer(RunSyncPacket.class, RunSyncPacket::encode, RunSyncPacket::decode, RunSyncPacket::handle); registerClientToServer(AttackSyncPacket.class, AttackSyncPacket::encode, AttackSyncPacket::decode, AttackSyncPacket::handle); registerClientToServer(CombatActionPacket.class, CombatActionPacket::encode, CombatActionPacket::decode, CombatActionPacket::handle); registerClientToServer(ManaSyncPacket.class, ManaSyncPacket::encode, ManaSyncPacket::decode, ManaSyncPacket::handle); registerClientToServer(StaminaSyncPacket.class, StaminaSyncPacket::encode, StaminaSyncPacket::decode, StaminaSyncPacket::handle); } @SuppressWarnings({"unchecked", "rawtypes"}) protected <MESSAGE> void registerServerToClient(Class<MESSAGE> type, BiConsumer<MESSAGE, PacketBuffer> encoder, Function<PacketBuffer, MESSAGE> decoder, BiConsumer<MESSAGE, Supplier<NetworkEvent.Context>> consumer) { this.wrapper.registerMessage(nextPacketID++, type, encoder, decoder, consumer, Optional.of(NetworkDirection.PLAY_TO_CLIENT)); } @SuppressWarnings({"unchecked", "rawtypes"}) protected <MESSAGE> void registerClientToServer(Class<MESSAGE> type, BiConsumer<MESSAGE, PacketBuffer> encoder, Function<PacketBuffer, MESSAGE> decoder, BiConsumer<MESSAGE, Supplier<NetworkEvent.Context>> consumer) { this.wrapper.registerMessage(nextPacketID++, type, encoder, decoder, consumer, Optional.of(NetworkDirection.PLAY_TO_SERVER)); } /** * Sends the given packet to every client. * * @param message the packet to send. */ public<MESSAGE> void sendToAll(MESSAGE message) { this.wrapper.send(PacketDistributor.ALL.noArg(), message); } /** * Sends the given packet to the given player. * * @param message the packet to send. * @param player the player to send the packet to. */ public<MESSAGE> void sendTo(MESSAGE message, ServerPlayerEntity player) { if (player.connection != null) this.wrapper.sendTo(message, player.connection.getNetworkManager(), NetworkDirection.PLAY_TO_CLIENT); } /** * Sends the given packet to all players around the given target point. * * @param message the packet to send. * @param point the target point. */ public<MESSAGE> void sendToAllAround(MESSAGE message, PacketDistributor.TargetPoint point) { this.wrapper.send(PacketDistributor.NEAR.with(()->point), message); } /** * Sends the given packet to the server. * * @param message the packet to send. */ public<MESSAGE> void sendToServer(MESSAGE message) { this.wrapper.sendToServer(message); } public<MESSAGE> void sendToAllTracking(MESSAGE message, Entity entity) { this.wrapper.send(PacketDistributor.TRACKING_ENTITY.with(() -> entity), message); } } This class is called in the FMLCommonSetupEvent event hook within my main file. This is a Server->Client packet that isn't working: public class PlayerLoadingPacket { private final int currentMana, maxMana, currentStamina, maxStamina; private final boolean staminaPunish; public PlayerLoadingPacket(int cMana, int mMana, int cStamina, int mStamina, boolean sPunish) { currentMana = cMana; maxMana = mMana; currentStamina = cStamina; maxStamina = mStamina; staminaPunish = sPunish; } public static void encode(PlayerLoadingPacket pkt, PacketBuffer buf) { buf.writeInt(pkt.currentMana); buf.writeInt(pkt.maxMana); buf.writeInt(pkt.currentStamina); buf.writeInt(pkt.maxStamina); buf.writeBoolean(pkt.staminaPunish); } public static PlayerLoadingPacket decode(PacketBuffer buf) { int cM = buf.readInt(); int mM = buf.readInt(); int cS = buf.readInt(); int mS = buf.readInt(); boolean sS = buf.readBoolean(); return new PlayerLoadingPacket(cM, mM, cS, mS, sS); } public static void handle(PlayerLoadingPacket message, Supplier<NetworkEvent.Context> context) { NetworkEvent.Context ctx = context.get(); ctx.enqueueWork(()-> { if (ctx.getSender()!= null) { EntityPlayer entityPlayer = new EntityPlayer(ctx.getSender()); entityPlayer.getPlayerCapability().setMana(message.currentMana); entityPlayer.getPlayerCapability().setMaxMana(message.maxMana); entityPlayer.getPlayerCapability().setStamina(message.currentStamina); entityPlayer.getPlayerCapability().setMaxStamina(message.maxStamina); entityPlayer.getPlayerCapability().setStaminaPunished(message.staminaPunish); System.out.print("MANA: "); System.out.print(entityPlayer.getPlayerCapability().getCurrentMana()); System.out.printf("%n"); } } ); ctx.setPacketHandled(true); } }
-
After you have your crop block, then look into how the lilypad item works.
-
I just reimported my gradle project and now it works.
-
So in a codebase that was working perfectly fine just last month, I come back to this crash I just can't seem to figure out why it's happening: Description: Initializing game java.lang.NoClassDefFoundError: net/jodah/typetools/TypeResolver at net.minecraftforge.eventbus.EventBus.getEventClass(EventBus.java:217) ~[eventbus-3.0.3-service.jar:?] {} at net.minecraftforge.eventbus.EventBus.checkNotGeneric(EventBus.java:162) ~[eventbus-3.0.3-service.jar:?] {} at net.minecraftforge.eventbus.EventBus.addListener(EventBus.java:173) ~[eventbus-3.0.3-service.jar:?] {} at net.minecraftforge.fml.network.NetworkInstance.addListener(NetworkInstance.java:65) ~[forge-1.16.3-34.1.0_mapped_snapshot_20200514-1.16-recomp.jar:?] {re:classloading} at net.minecraftforge.fml.network.simple.SimpleChannel.<init>(SimpleChannel.java:57) ~[forge-1.16.3-34.1.0_mapped_snapshot_20200514-1.16-recomp.jar:?] {re:classloading} at net.minecraftforge.fml.network.simple.SimpleChannel.<init>(SimpleChannel.java:50) ~[forge-1.16.3-34.1.0_mapped_snapshot_20200514-1.16-recomp.jar:?] {re:classloading} at net.minecraftforge.fml.network.NetworkRegistry$ChannelBuilder.simpleChannel(NetworkRegistry.java:409) ~[forge-1.16.3-34.1.0_mapped_snapshot_20200514-1.16-recomp.jar:?] {re:classloading} at net.minecraftforge.fml.network.NetworkInitialization.getHandshakeChannel(NetworkInitialization.java:38) ~[forge-1.16.3-34.1.0_mapped_snapshot_20200514-1.16-recomp.jar:?] {re:classloading} at net.minecraftforge.fml.network.FMLNetworkConstants.<clinit>(FMLNetworkConstants.java:48) ~[forge-1.16.3-34.1.0_mapped_snapshot_20200514-1.16-recomp.jar:?] {re:classloading} at net.minecraftforge.fml.ModLoader.<init>(ModLoader.java:128) ~[forge-1.16.3-34.1.0_mapped_snapshot_20200514-1.16-recomp.jar:?] {re:classloading} at net.minecraftforge.fml.ModLoader.get(ModLoader.java:153) ~[forge-1.16.3-34.1.0_mapped_snapshot_20200514-1.16-recomp.jar:?] {re:classloading} at net.minecraftforge.fml.client.ClientModLoader.lambda$begin$1(ClientModLoader.java:103) ~[forge-1.16.3-34.1.0_mapped_snapshot_20200514-1.16-recomp.jar:?] {re:classloading,pl:runtimedistcleaner:A} at net.minecraftforge.fml.client.ClientModLoader.lambda$createRunnableWithCatch$4(ClientModLoader.java:123) ~[forge-1.16.3-34.1.0_mapped_snapshot_20200514-1.16-recomp.jar:?] {re:classloading,pl:runtimedistcleaner:A} at net.minecraftforge.fml.client.ClientModLoader.begin(ClientModLoader.java:103) ~[forge-1.16.3-34.1.0_mapped_snapshot_20200514-1.16-recomp.jar:?] {re:classloading,pl:runtimedistcleaner:A} at net.minecraft.client.Minecraft.<init>(Minecraft.java:429) ~[forge-1.16.3-34.1.0_mapped_snapshot_20200514-1.16-recomp.jar:?] {re:classloading,pl:accesstransformer:B,pl:runtimedistcleaner:A} at net.minecraft.client.main.Main.main(Main.java:149) ~[forge-1.16.3-34.1.0_mapped_snapshot_20200514-1.16-recomp.jar:?] {re:classloading,pl:runtimedistcleaner:A} at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_241] {} at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_241] {} at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_241] {} at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_241] {} at net.minecraftforge.userdev.FMLUserdevClientLaunchProvider.lambda$launchService$0(FMLUserdevClientLaunchProvider.java:52) ~[forge-1.16.3-34.1.0_mapped_snapshot_20200514-1.16-recomp.jar:?] {} at cpw.mods.modlauncher.LaunchServiceHandlerDecorator.launch(LaunchServiceHandlerDecorator.java:37) [modlauncher-7.0.1.jar:?] {} at cpw.mods.modlauncher.LaunchServiceHandler.launch(LaunchServiceHandler.java:54) [modlauncher-7.0.1.jar:?] {} at cpw.mods.modlauncher.LaunchServiceHandler.launch(LaunchServiceHandler.java:72) [modlauncher-7.0.1.jar:?] {} at cpw.mods.modlauncher.Launcher.run(Launcher.java:81) [modlauncher-7.0.1.jar:?] {} at cpw.mods.modlauncher.Launcher.main(Launcher.java:65) [modlauncher-7.0.1.jar:?] {} at net.minecraftforge.userdev.LaunchTesting.main(LaunchTesting.java:105) [forge-1.16.3-34.1.0_mapped_snapshot_20200514-1.16-recomp.jar:?] {} Caused by: java.lang.ClassNotFoundException: net.jodah.typetools.TypeResolver at java.net.URLClassLoader.findClass(URLClassLoader.java:382) ~[?:1.8.0_241] {} at java.lang.ClassLoader.loadClass(ClassLoader.java:418) ~[?:1.8.0_241] {} at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:355) ~[?:1.8.0_241] {} at java.lang.ClassLoader.loadClass(ClassLoader.java:351) ~[?:1.8.0_241] {} ... 27 more A detailed walkthrough of the error, its code path and all known details is as follows: --------------------------------------------------------------------------------------- -- Head -- Thread: Render thread Stacktrace: at net.minecraftforge.eventbus.EventBus.getEventClass(EventBus.java:217) ~[eventbus-3.0.3-service.jar:?] {} at net.minecraftforge.eventbus.EventBus.checkNotGeneric(EventBus.java:162) ~[eventbus-3.0.3-service.jar:?] {} at net.minecraftforge.eventbus.EventBus.addListener(EventBus.java:173) ~[eventbus-3.0.3-service.jar:?] {} at net.minecraftforge.fml.network.NetworkInstance.addListener(NetworkInstance.java:65) ~[?:?] {re:classloading} at net.minecraftforge.fml.network.simple.SimpleChannel.<init>(SimpleChannel.java:57) ~[?:?] {re:classloading} at net.minecraftforge.fml.network.simple.SimpleChannel.<init>(SimpleChannel.java:50) ~[?:?] {re:classloading} at net.minecraftforge.fml.network.NetworkRegistry$ChannelBuilder.simpleChannel(NetworkRegistry.java:409) ~[?:?] {re:classloading} at net.minecraftforge.fml.network.NetworkInitialization.getHandshakeChannel(NetworkInitialization.java:38) ~[?:?] {re:classloading} at net.minecraftforge.fml.network.FMLNetworkConstants.<clinit>(FMLNetworkConstants.java:48) ~[?:?] {re:classloading} at net.minecraftforge.fml.ModLoader.<init>(ModLoader.java:128) ~[?:?] {re:classloading} at net.minecraftforge.fml.ModLoader.get(ModLoader.java:153) ~[?:?] {re:classloading} at net.minecraftforge.fml.client.ClientModLoader.lambda$begin$1(ClientModLoader.java:103) ~[?:?] {re:classloading,pl:runtimedistcleaner:A} at net.minecraftforge.fml.client.ClientModLoader.lambda$createRunnableWithCatch$4(ClientModLoader.java:123) ~[?:?] {re:classloading,pl:runtimedistcleaner:A} at net.minecraftforge.fml.client.ClientModLoader.begin(ClientModLoader.java:103) ~[?:?] {re:classloading,pl:runtimedistcleaner:A} at net.minecraft.client.Minecraft.<init>(Minecraft.java:429) ~[?:?] {re:classloading,pl:accesstransformer:B,pl:runtimedistcleaner:A} -- Initialization -- Details: Stacktrace: at net.minecraft.client.main.Main.main(Main.java:149) ~[forge-1.16.3-34.1.0_mapped_snapshot_20200514-1.16-recomp.jar:?] {re:classloading,pl:runtimedistcleaner:A} at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_241] {} at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_241] {} at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_241] {} at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_241] {} at net.minecraftforge.userdev.FMLUserdevClientLaunchProvider.lambda$launchService$0(FMLUserdevClientLaunchProvider.java:52) ~[forge-1.16.3-34.1.0_mapped_snapshot_20200514-1.16-recomp.jar:?] {} at cpw.mods.modlauncher.LaunchServiceHandlerDecorator.launch(LaunchServiceHandlerDecorator.java:37) [modlauncher-7.0.1.jar:?] {} at cpw.mods.modlauncher.LaunchServiceHandler.launch(LaunchServiceHandler.java:54) [modlauncher-7.0.1.jar:?] {} at cpw.mods.modlauncher.LaunchServiceHandler.launch(LaunchServiceHandler.java:72) [modlauncher-7.0.1.jar:?] {} at cpw.mods.modlauncher.Launcher.run(Launcher.java:81) [modlauncher-7.0.1.jar:?] {} at cpw.mods.modlauncher.Launcher.main(Launcher.java:65) [modlauncher-7.0.1.jar:?] {} at net.minecraftforge.userdev.LaunchTesting.main(LaunchTesting.java:105) [forge-1.16.3-34.1.0_mapped_snapshot_20200514-1.16-recomp.jar:?] {} Anyone have an idea what it might be?
-
Setting entity rendering brightness [1.16.3]
Turtledove replied to Turtledove's topic in Modder Support
Yeah looks like that's about right. But now the problem is that I need every face of the entity's model to be lit up the same, but gl11 calls like GL11.glEnable(GL11.GL_MAX_LIGHTS) or even GL11.GLDisable(GL11.GL_LIGHTING) doesn't work. -
I'm trying to make my entity's model be bright at a fixed light value. In 1.12.2 I was able to override getBrightnessForRender(), but this method is no longer there in 1.16.3. I've looked through the EntityRenderer class and couldn't find anything there either. Anyone know how I could achieve this? Btw getBrightness has nothing to do with how the entity is rendered, I checked.
-
Ugly conditionals, as in: switch key: case 'blah': return BlahEntity object case 'foo': return FooEntity object case 'bar': return BarEntity object . . . case 'blah': return BlahEntity object Where I'd need to add to this whenever I add new relevant Entities. This is what I'm avoiding. This part works just fine, we pass null to field.get() in this case because the members it's looking for are static. It correctly retreives the EntityTypes, the problem is that I don't know how to get an Entity object out of it.
-
So I need to create a lookup table of several of my custom entities, via the EntityType members of my entity registry. The entities are successfully registered; public static final EntityType<DemonFangEntity> DEMON_FANG = registerEntity(EntityType.Builder.create(DemonFangEntity::new, EntityClassification.MISC).size(0.7F, 0.7F), "demon_fang"); and when I need an entity to spawn I simply call the following method where I try to return an entity via a string key. In this case, I'd need this to return a DemonFangEntity object (it extends WithernautsMagicEntity): public WithernautsMagicEntity getMagicEntity(World worldIn, String key) { try { for (Field f : EntityRegistry.class.getDeclaredFields()) { Object obj = f.get(null); if (obj instanceof EntityType) { EntityType type = (EntityType)obj; Entity entity = type.create(worldIn); if (entity instanceof WithernautsMagicEntity) { WithernautsMagicEntity magicEntity = (WithernautsMagicEntity)entity; if (magicEntity.getKey().equals(key)) return magicEntity; } } } throw new IllegalArgumentException(); } catch (IllegalAccessException e) { throw new RuntimeException(e); } } However, this method currently throws an exception because Entity entity = type.create(worldIn) returns null. What's a way I could correctly return an object of EntityType's template type? Or is this just not possible without reflection? Sidenote: I'm trying to do it this way because I don't want to create a giant conditional statement since it would not scale well at all with my project's scope.
-
So I've got an AI class where previously in 1.12.2, the mutex bits were set to 7 (incompatible with other vanilla AIs). I'm attempting to update this to 1.16.3, but I see that the mutex bits are replaced by an enumset of flags, which are: MOVE, JUMP, LOOK, and TARGET. If I want equivalent behavior where the AI shouldn't execute when vanilla AIs are executing, how do I set the flags?
-
Question about MatrixStacks - 1.16.3 [SOLVED]
Turtledove replied to Turtledove's topic in Modder Support
Solved my own problem, I ended up using a parser rather than the ScriptEngine, which I should've done from the beginning. -
I am currently creating dozens (potentially 100+) different animations for the player's hand in first person view, and to make it easier on myself I have a system that lets me parse .json files for expressions, in a form like this: { "transform":[ {"translation":["__i * 0.56 - __swing_ratio * 1.75 + 0.9","-0.38", "-0.52"]}, {"rotation":["0.0","90.0","0.0"]}, {"rotation":["0.0","0.0","-90.0"]}, {"rotation":["-25.0 + 25.0 * Math.cos(__swing_ratio * __swing_ratio * Math.PI)","0.0","0.0"]} ] } these get read into a list of an HandTransformation class where type is the type of transformation. public class HandTransformation { public String type; public String[] transformation = new String[3]; } At runtime, this method is called which evaluates the expression in the .json via a JS ScriptEngine, and does the appropriate transformations to the MatrixStacks object from the RenderHand event: matrixStack.clear(); matrixStack.push(); for (ItemTransformation itemTransformation:action.getTransformations()) { String type = itemTransformation.type; Vector3f transform = getVector(itemTransformation, side, swingRatio, equippedRatio); if (type.equals("translation")) { matrixStack.translate(transform.getX(), transform.getY(), transform.getZ()); } else if (type.equals("rotation")) { matrixStack.rotate(Vector3f.XP.rotationDegrees(transform.getX())); matrixStack.rotate(Vector3f.YP.rotationDegrees(transform.getY())); matrixStack.rotate(Vector3f.ZP.rotationDegrees(transform.getZ())); } } Minecraft.getInstance().getFirstPersonRenderer().renderItemSide(Minecraft.getInstance().player, itemStack, rightHanded ? ItemCameraTransforms.TransformType.FIRST_PERSON_RIGHT_HAND : ItemCameraTransforms.TransformType.FIRST_PERSON_LEFT_HAND, !rightHanded, matrixStack, buffer,light); matrixStack.pop(); private Vector3f getVector(ItemTransformation itemTransformation, float side, float swingRatio, float equippedRatio) { String[] transformation = itemTransformation.transformation; String sideString = Float.toString(side); String swingRatioString = Float.toString(swingRatio); String equppedRatioString = Float.toString(equippedRatio); Vector3f transforms = new Vector3f(); for (int i = 0; i < 3; i++) { String expression = transformation[i]; expression.replaceAll("__i", sideString); expression.replaceAll("__swing_ratio", swingRatioString); expression.replaceAll("__equip_ratio", equppedRatioString); float result = evaluateScript(expression); switch(i) { case 0: transforms.setX(result); break; case 1: transforms.setY(result); break; default: transforms.setZ(result); } } return transforms; } public float evaluateScript(String expression) { float result = 0.0f; ScriptEngineManager factory = new ScriptEngineManager(); ScriptEngine engine = factory.getEngineByName("JavaScript"); try { Object obj = engine.eval(expression); result = Float.parseFloat(obj.toString()); } catch(ScriptException e) { e.printStackTrace(); } return result; } This all works, but as expected it cripples the framerate whenever it runs due to ScriptEngine. So, the next best thing is to apply the transformations to my own MatrixStacks object at initialization, for when I need them during gameplay. Can I simply create my own MatrixStacks object at initialization (outside of the render event call) and not use the one provided by the event call? Or does it work more like the old GLStateManager and just wouldn't work? Or better yet, is there an equally robust alternative to the JS script engine for evaluating mathematical expressions at runtime?
-
I think I got it, in some ways it's cleaner than how it was done in 1.12.2 since we don't need to go through an interface. public final class PacketRegistry { /** * The ID for the next packet registration. */ private static final String PROTOCOL_VERSION = Integer.toString(1); private byte nextPacketID = 0; /** * The internal network wrapper. */ private static final SimpleChannel wrapper = NetworkRegistry.ChannelBuilder .named(new ResourceLocation(Withernauts.MODID, "main_channel")) .clientAcceptedVersions(PROTOCOL_VERSION::equals) .serverAcceptedVersions(PROTOCOL_VERSION::equals) .networkProtocolVersion(() -> PROTOCOL_VERSION) .simpleChannel(); public void registerPackets() { //register packets going to the client //register packets going to the server } @SuppressWarnings({"unchecked", "rawtypes"}) protected <MESSAGE> void registerServerToClient(Class<MESSAGE> type, BiConsumer<MESSAGE, PacketBuffer> encoder, Function<PacketBuffer, MESSAGE> decoder, BiConsumer<MESSAGE, Supplier<NetworkEvent.Context>> consumer) { this.wrapper.registerMessage(nextPacketID++, type, encoder, decoder, consumer, Optional.of(NetworkDirection.PLAY_TO_CLIENT)); } @SuppressWarnings({"unchecked", "rawtypes"}) protected <MESSAGE> void registerClientToServer(Class<MESSAGE> type, BiConsumer<MESSAGE, PacketBuffer> encoder, Function<PacketBuffer, MESSAGE> decoder, BiConsumer<MESSAGE, Supplier<NetworkEvent.Context>> consumer) { this.wrapper.registerMessage(nextPacketID++, type, encoder, decoder, consumer, Optional.of(NetworkDirection.PLAY_TO_SERVER)); } /** * Sends the given packet to every client. * * @param message the packet to send. */ public<MESSAGE> void sendToAll(MESSAGE message) { this.wrapper.send(PacketDistributor.ALL.noArg(), message); } /** * Sends the given packet to the given player. * * @param message the packet to send. * @param player the player to send the packet to. */ public<MESSAGE> void sendTo(MESSAGE message, ServerPlayerEntity player) { if (player.connection != null) this.wrapper.sendTo(message, player.connection.getNetworkManager(), NetworkDirection.PLAY_TO_CLIENT); } /** * Sends the given packet to all players around the given target point. * * @param message the packet to send. * @param point the target point. */ public<MESSAGE> void sendToAllAround(MESSAGE message, PacketDistributor.TargetPoint point) { this.wrapper.send(PacketDistributor.NEAR.with(()->point), message); } /** * Sends the given packet to the server. * * @param message the packet to send. */ public<MESSAGE> void sendToServer(MESSAGE message) { this.wrapper.sendToServer(message); } public<MESSAGE> void sendToAllTracking(MESSAGE message, Entity entity) { this.wrapper.send(PacketDistributor.TRACKING_ENTITY.with(() -> entity), message); } }
-
I'm attempting to update my packet system from 1.12.2 -> 1.16.3, and I've found that a ton appears to have changed, I've looked through the 1.13/1.14 primer and overall I'm still not sure what to do here. This was my packethandler class in 1.12 public final class PacketHandler { /** * The ID for the next packet registration. */ private byte nextPacketID = 0; /** * The internal network wrapper. */ private SimpleNetworkWrapper wrapper; /** * The channelid. */ private String channelid; /** * Instantiates a new packet handler with the given channelid and reserves * the channel. * * @param channelid the channelid. This is mostly the modid. */ public PacketHandler(String channelid) { this.wrapper = NetworkRegistry.INSTANCE.newSimpleChannel(channelid); this.channelid = channelid; } public void registerPackets() { registerPacket(PlayerSyncCapability.class, new PlayerSyncCapability.Handler(), Side.SERVER); } /** * Register an IMessage packet with it's corresponding message handler. * * @param packetClass the packet's class that should be registered. * @param messageHandler the message handler for this packet type. * @param target The side to which this packet can be sent. * @return <code>true</code>, if successful */ @SuppressWarnings({"unchecked", "rawtypes"}) public boolean registerPacket(Class<? extends IMessage> packetClass, MessageHandler messageHandler, Side target) { if (this.nextPacketID == -1) throw new IllegalStateException("Too many packets registered for channel " + this.channelid); this.wrapper.registerMessage(messageHandler, packetClass, this.nextPacketID, target); Log.debug("Registered packet class %s with handler class %s for the channel %s. Send direction: to %s. The discriminator is %s.", packetClass.getSimpleName(), messageHandler.getClass().getSimpleName(), this.channelid, target.name().toLowerCase(), this.nextPacketID); this.nextPacketID++; return true; } /** * Sends the given packet to every client. * * @param message the packet to send. */ public void sendToAll(IMessage message) { this.wrapper.sendToAll(message); } /** * Sends the given packet to the given player. * * @param message the packet to send. * @param player the player to send the packet to. */ public void sendTo(IMessage message, EntityPlayerMP player) { if (player.connection != null) this.wrapper.sendTo(message, player); } /** * Sends the given packet to all players around the given target point. * * @param message the packet to send. * @param point the target point. */ public void sendToAllAround(IMessage message, NetworkRegistry.TargetPoint point) { this.wrapper.sendToAllAround(message, point); } /** * Sends the given packet to all players within the radius around the given coordinates. * * @param message the packet to send. * @param dimension the dimension. * @param x the x coordinate. * @param y the y coordinate. * @param z the z coordinate. * @param range the radius. */ public void sendToAllAround(IMessage message, int dimension, double x, double y, double z, double range) { this.sendToAllAround(message, new NetworkRegistry.TargetPoint(dimension, x, y, z, range)); } /** * Sends the given packet to all players within the radius around the given entity. * * @param message the packet to send. * @param entity the entity. * @param range the radius. */ public void sendToAllAround(IMessage message, Entity entity, double range) { this.sendToAllAround(message, entity.dimension, entity.posX, entity.posY, entity.posZ, range); } /** * Sends the given packet to the server. * * @param message the packet to send. */ public void sendToServer(IMessage message) { this.wrapper.sendToServer(message); } public void sendToAllTracking(IMessage message, Entity entity) { this.wrapper.sendToAllTracking(message, entity); } } Couple things that threw me for a loop I'm hoping for some clarification on: 1) IMessage is no longer a thing. So can I no longer do something like my registerpacket implementation anymore? Or is it going to have to be in the form of INSTANCE.registerMessage(nextID(),SendBlockData.class,SendBlockData::encode,SendBlockData::new,SendBlockData::handle); 2) Logical sides aren't specified when registering the packets. Is there no longer any distinction between packets meant on the client vs server? 3) SimpleChannel doesn't have sendToAll alongside a few other convenient methods. Thanks!
-
I'm updating a gigantic mod of mine to the latest version, I have just a few questions to start: 1. To my understanding the preInit and and initialization events were removed. As an example, in 1.12 I registered my entities' renderer in the preinitialization event, where would this go in 1.16? 2. I use GLStateManager calls throughout the mod to make changes to UI, first person item rendering, and the like. But is there a new way of doing this? 3. Did entity AI/pathfinding change in any significant way?
-
For testing purposes, I've cloned my mods repo on github and successfully got it to run the game on a separate, fresh machine, but for some reason it's missing the minecraft library files that comes with Forge mdk installs. The build.gradle is obviously the same as the version I pushed to git, and the library fils are all there on that machine. What do I need to do?