Jump to content

FireController1847

Members
  • Posts

    290
  • Joined

  • Last visited

Everything posted by FireController1847

  1. Aye, that's a massive downfall and something that, imho, should have been a higher priority before releasing the 1.14+ rewrite. Anyways, thanks for the help, I'll try out JitPack!
  2. What I mean is, how do I add a mod to the runClient's "mods" folder and load it to test with it, say, for compatibility. My mod is incompatible with another mod, and I need to test some things, however when I try and launch the game with the mod in the mods folder (for the client in the run folder), it crashes (which I think is because it's trying to parse the JAR file for the mod I included). How do I use a temporary dependency mod for testing?
  3. I'm going to be honest with you, I have no idea what I was thinking. I've been running "gradlew jar" not "gradlew build". It works great now, thanks!
  4. I am currently developing a mod using Minecraft Forge 31.2.0 for Minecraft 1.15.2, with the mappings of snapshot-20200518-1.15.1. I am using IntelliJ as my environment. When I launch my mod using the IntelliJRuns, it works great. Everything works fine with no issues at all. So, I run the "jar" gradle task and get my jar out of it. This is where things go awry. I install the same version of Forge onto vanilla MC using the vanilla launcher, and it fails to load. This is a crash report submitted by one of my users: https://pastebin.com/eckCHVvF . I get the same crash report when getting it. Something along the lines of .maxStackSize is not a method when making a new item, but that doesn't make sense because it is a method (though for those who want to see my code, here's my item class that it's erroring on: https://hastebin.com/rilexoduro.java ). So, I'm at a complete loss. I have no idea why it would be crashing like this. It builds and runs fine in my development environment, but when I generate the JAR for some reason it crashes in a production environment. I've tried completely rebuilding my gradle cache, resetting my IntelliJ, and straight up deleting everything and re-starting from my GitHub repository ( https://gitlab.com/FireController1847/levelhearts/ ) all to no avail. So, I come here. Does this ring a bell for anyone? Is anyone else getting this error? Does somebody have any idea as to what might be happening? Because I'm clueless.
  5. By doing a little bit more digging, now that I'm not really tired today haha, I found that the PlayerRespawn event (when the player dies) actually also calls the PlayerClone event, helping me discover there was an option in PlayerEvent.Clone called "isWasDeath." By using this event, I was able to determine if the player died, and re-apply my health modifier appropriately, which allowed me to set the playerNew's health to the same as the playerOld's health, thereby keeping their health across dimension change. Here's my fixed code: @SubscribeEvent public static void onPlayerClone(PlayerEvent.Clone event) { debug("PlayerClone{Event}"); // Fetch & Copy Capability PlayerEntity playerOld = event.getOriginal(); PlayerEntity playerNew = event.getPlayer(); IMoreHealth capOld = MoreHealth.getFromPlayer(playerOld); IMoreHealth capNew = MoreHealth.getFromPlayer(playerNew); capNew.copy(capOld); // Copy Health on Dimension Change if (!event.isWasDeath()) { debug("PlayerClone{Event}: Cloning from dimension change, re-applying health modifier."); LevelHearts.applyHealthModifier(playerNew, capNew.getTrueModifier()); playerNew.setHealth(playerOld.getHealth()); } } @SubscribeEvent public static void onPlayerRespawn(PlayerRespawnEvent event) { // Ensure server-side only if (event.getPlayer().getEntityWorld().isRemote) { return; } debug("PlayerRespawn{Event}"); // Fetch Capability PlayerEntity player = event.getPlayer(); IMoreHealth cap = MoreHealth.getFromPlayer(player); // Handle "The End" if (event.isEndConquered()) { debug("PlayerRespawn{Event}: Coming from end, syncing!"); MoreHealth.updateClient((ServerPlayerEntity) player, cap); return; } // ... other stuff }
  6. Here's a video showing the bug, in case my wording confused anyone: https://www.youtube.com/watch?v=HJhUjRIHsSM
  7. I have not been able to fix this issue, so bumping this to see if anyone has any idea
  8. I have a mod that applies a health modifier and uses a capability to keep track of it. My problem is, when I'm coming back from the end, the player's health kind of "resets" back to 20. For example, let's say I've entered the end with 30 hearts, applied by my capability. I defeat the ender dragon, and then I come back. Suddenly, I still appear to have all 30 hearts, but I only have 10 of them with health left (so it's like I took imaginary damage). Leaving and re-joining the world does not work, and I've tried both to sync the client to the server and the server to the client, but none of my efforts have worked. Currently, I've set up my onChangedDimension event like so: @SubscribeEvent public static void onPlayerChangedDimension(PlayerChangedDimensionEvent event) { // Ensure server-side only if (event.getPlayer().getEntityWorld().isRemote) { return; } debug("PlayerChangedDimension{Event}"); // Fetch Capability PlayerEntity player = event.getPlayer(); IMoreHealth cap = MoreHealth.getFromPlayer(player); // Re-add health modifier LevelHearts.applyHealthModifier(player, cap.getTrueModifier()); // Synchronize cap.synchronise(player); } cap.synchronize will send a packet from the client to the server. This works great for coming from and going to the nether, as well as going to the end. But oh no, coming back FROM the end has to be different, and indeed it instead calls the PlayerRespawn event. Currently, my respawn event looks like this: @SubscribeEvent public static void onPlayerRespawn(PlayerRespawnEvent event) { // Ensure server-side only if (event.getPlayer().getEntityWorld().isRemote) { return; } debug("PlayerRespawn{Event}"); // Fetch Capability PlayerEntity player = event.getPlayer(); IMoreHealth cap = MoreHealth.getFromPlayer(player); // Handle "The End" if (event.isEndConquered()) { debug("PlayerRespawn{Event}: Coming from end, syncing!"); // ??? What do I put here? ??? return; } // Handle Hardcore Mode if (Config.enableHardcore.get()) { debug("PlayerRespawn{Event}: Hardcore mode enabled, removing health."); cap.setModifier(MoreHealth.getDefaultModifier()); cap.setRampPosition((short) 0); cap.setHeartContainers((byte) 0); MoreHealth.updateClient((ServerPlayerEntity) player, cap); } // Handle force lose xp on death if (Config.loseXpOnDeath.get()) { player.addExperienceLevel(-player.experienceLevel - 1); } // Re-add health modifier and fill health LevelHearts.applyHealthModifier(player, cap.getTrueModifier()); player.setHealth(player.getMaxHealth()); } When the player enters the end, and inside the end, let's say they have 40 hearts. When they come back, the player appears to still have those forty hearts, but the health has reset back to 20. I have absolutely no idea why, and it means that I cannot do what I do on a dimension change to just update the client / update the server (for other situations). So... what do I do to have the player keep their health when coming back from the end?
  9. Currently, I have an event that attaches to the RenderGameOverlayEvent.Pre. What I want to do is move the armor bar to be above the food, instead of above the health. I check if the element type is armor, and then cancel the event and run my custom code. In previous versions of my mod, I figured the only way to do this was to copy Mojang's code for drawing the armor bar in IngameGui#renderPlayerStats, however I fear that if I do this I am violating some copyright. Is there a way to move the armor bar without copying the Mojang code? Here's the code I used for previous versions of the mod, and below is the code I currently have: @SubscribeEvent public void onRenderGameOverlay(RenderGameOverlayEvent.Pre event) { if (Config.customHud.get()) { } } private void redrawArmor() { // What to put here? }
  10. So in reality, what's happening is the attribute is lost on the client-side but not on the server side, which allows it to recover itself without having to re-initiate it?
  11. It worked! Awesome, thank you! I don't suppose you'd be willing to help me understand what this piece of code does? I kind of get that it's making a packet for the attribute, but what is this "sendToTrackingAndSelf" method?
  12. Awesome, thanks. I'll try that next chance I get and report back here
  13. I'm currently working on a mod that allows a player to have more than their maximum amount of health. I've got the health modifier down, but what I don't understand is what happens when the player changes dimension. It appears that the modifier goes away. This would be fine, except... well, this is best explained with an example: Let's say I have 20 hearts. If I'm at full health, then go through a nether portal, my modifier is re-applied and I get the appropriate amount of 20 hearts back. However, my health is down to 10. My question is, how do I remember and persist the player's health as they go from one world to another? My code is currently available here, and below is a code snippet of my changed dimension event: @SubscribeEvent public static void onPlayerChangedDimension(PlayerChangedDimensionEvent event) { debug("PlayerChangedDimension{Event}"); // Fetch Capability PlayerEntity player = event.getPlayer(); IMoreHealth cap = MoreHealth.getFromPlayer(player); // Re-add health modifier LevelHearts.applyHealthModifier(player, cap.getTrueModifier()); }
  14. For anyone looking at this in future reference, I figured it out. There's a Gradle task that you need to run that will generate all of the test files that are needed to, well, test. This is not stated in the documentation. Once you've done that you can find example test mods in the "test-java" source package.
  15. Bump. I'm curious if anyone else knows how to solve this.
  16. I've gotten so far as to fork the repository, run the `setup` and `eclipse` tasks, and import the project into Eclipse (and I can run it). I've made my contribution, but I can't seem to figure out how to test it. The tutorial on the docs websites does not include anything for setting up the test mods on Eclipse, only IntelliJ. Does anyone know how to do it? Sorry if this is the wrong forum for this, I didn't know of any other spots.
  17. Oh right! I had completely forgotten about there being two different event busses. Yes! It works now! Thank you everyone who helped me out with this! I really, really, really appreciate it! Thank you for being understanding with me through being an idiot sometimes as well haha. A lot of good topics were covered here so I really hope this thread will also help some other people using capabilities! As some example code, here's the gist showing all of what I've done to get this capability registered and working. Again, thank you so so much! https://gist.github.com/FireController1847/c7a50144f45806a996d13efcff468d1b
  18. I've updated the following gist with my latest modifications to the code. https://gist.github.com/FireController1847/c7a50144f45806a996d13efcff468d1b
  19. Sorry about the abrupt leave. I think the cause of the error is down to the LazyOptional.of method. I'm not sure if getInstance() is returning null upon creation, but the error makes no sense... Does anyone have an idea?
  20. That didn't make a difference, unfortunately. I think the error is lying in line 15. I need to go be back in a bit.
  21. Okay, sorry about that last error report. I was just dumb and couldn't read. Here's one that might be more worthy of some help... MoreHeathProvider package com.firecontroller1847.levelhearts.capabilities; import net.minecraft.nbt.INBT; import net.minecraft.util.Direction; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.capabilities.CapabilityInject; import net.minecraftforge.common.capabilities.ICapabilitySerializable; import net.minecraftforge.common.util.LazyOptional; public class MoreHealthProvider implements ICapabilitySerializable<INBT> { @CapabilityInject(IMoreHealth.class) public static Capability<IMoreHealth> MORE_HEALTH_CAPABILITY; private LazyOptional<IMoreHealth> instance = LazyOptional.of(MORE_HEALTH_CAPABILITY::getDefaultInstance); @Override public <T> LazyOptional<T> getCapability(Capability<T> cap, Direction side) { return cap == MORE_HEALTH_CAPABILITY ? instance.cast() : LazyOptional.empty(); } @Override public INBT serializeNBT() { // @formatter:off return MORE_HEALTH_CAPABILITY.getStorage().writeNBT(MORE_HEALTH_CAPABILITY, this.instance.orElseThrow(() -> new IllegalArgumentException("LazyOptional must not be empty!")), null); // @formatter:on } @Override public void deserializeNBT(INBT nbt) { // @formatter:off MORE_HEALTH_CAPABILITY.getStorage().readNBT(MORE_HEALTH_CAPABILITY, this.instance.orElseThrow(() -> new IllegalArgumentException("LazyOptional must not be empty!")), null, nbt); // @formatter:on } } The Erroring Event (on addCapability) @SubscribeEvent public static void onAttachCapabilities(AttachCapabilitiesEvent<Entity> event) { if (event.getObject() instanceof PlayerEntity) { event.addCapability(new ResourceLocation(LevelHearts.MOD_ID, "morehealth"), new MoreHealthProvider()); } } java.lang.NullPointerException at com.firecontroller1847.levelhearts.capabilities.MoreHealthProvider.<init>(MoreHealthProvider.java:15) at com.firecontroller1847.levelhearts.LevelHearts.onAttachCapabilities(LevelHearts.java:43) at net.minecraftforge.eventbus.ASMEventHandler_2_LevelHearts_onAttachCapabilities_AttachCapabilitiesEvent.invoke(.dynamic) at net.minecraftforge.eventbus.ASMEventHandler.invoke(ASMEventHandler.java:80) at net.minecraftforge.eventbus.EventBus.post(EventBus.java:258) at net.minecraftforge.event.ForgeEventFactory.gatherCapabilities(ForgeEventFactory.java:560) at net.minecraftforge.event.ForgeEventFactory.gatherCapabilities(ForgeEventFactory.java:554) at net.minecraftforge.common.capabilities.CapabilityProvider.gatherCapabilities(CapabilityProvider.java:48) at net.minecraftforge.common.capabilities.CapabilityProvider.gatherCapabilities(CapabilityProvider.java:44) at net.minecraft.entity.Entity.<init>(Entity.java:222) at net.minecraft.entity.LivingEntity.<init>(LivingEntity.java:192) at net.minecraft.entity.player.PlayerEntity.<init>(PlayerEntity.java:162) at net.minecraft.entity.player.ServerPlayerEntity.<init>(ServerPlayerEntity.java:163) at net.minecraft.server.management.PlayerList.createPlayerForUser(PlayerList.java:390) at net.minecraft.network.login.ServerLoginNetHandler.tryAcceptPlayer(ServerLoginNetHandler.java:119) at net.minecraft.network.login.ServerLoginNetHandler.tick(ServerLoginNetHandler.java:63) at net.minecraft.network.NetworkManager.tick(NetworkManager.java:241) at net.minecraft.network.NetworkSystem.tick(NetworkSystem.java:148) at net.minecraft.server.MinecraftServer.updateTimeLightAndEntities(MinecraftServer.java:882) at net.minecraft.server.MinecraftServer.tick(MinecraftServer.java:800) at net.minecraft.server.integrated.IntegratedServer.tick(IntegratedServer.java:118) at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:646) at java.lang.Thread.run(Unknown Source)
  22. Arrg! So close! I got one more error and this time it's with my ResourceLocation... public static final String NBT_ID = "levelHearts"; public static final String MOD_ID = "levelhearts"; @SubscribeEvent public static void onAttachCapabilities(AttachCapabilitiesEvent<Entity> event) { if (event.getObject() instanceof PlayerEntity) { event.addCapability(new ResourceLocation(LevelHearts.MOD_ID, LevelHearts.NBT_ID), new MoreHealthProvider()); } } net.minecraft.util.ResourceLocationException: Non [a-z0-9/._-] character in path of location: levelhearts:levelHearts at net.minecraft.util.ResourceLocation.<init>(ResourceLocation.java:30) ~[forge-1.14.4-28.0.95_mapped_snapshot_20190907-1.14.3-recomp.jar:?] {} at net.minecraft.util.ResourceLocation.<init>(ResourceLocation.java:39) ~[forge-1.14.4-28.0.95_mapped_snapshot_20190907-1.14.3-recomp.jar:?] {} at com.firecontroller1847.levelhearts.LevelHearts.onAttachCapabilities(LevelHearts.java:44) ~[main/:?] {} at net.minecraftforge.eventbus.ASMEventHandler_0_LevelHearts_onAttachCapabilities_AttachCapabilitiesEvent.invoke(.dynamic) ~[?:?] {} at net.minecraftforge.eventbus.ASMEventHandler.invoke(ASMEventHandler.java:80) ~[eventbus-1.0.0-service.jar:?] {} at net.minecraftforge.eventbus.EventBus.post(EventBus.java:258) ~[eventbus-1.0.0-service.jar:?] {} at net.minecraftforge.event.ForgeEventFactory.gatherCapabilities(ForgeEventFactory.java:560) ~[?:?] {} at net.minecraftforge.event.ForgeEventFactory.gatherCapabilities(ForgeEventFactory.java:554) ~[?:?] {} at net.minecraftforge.common.capabilities.CapabilityProvider.gatherCapabilities(CapabilityProvider.java:48) ~[?:?] {} at net.minecraftforge.common.capabilities.CapabilityProvider.gatherCapabilities(CapabilityProvider.java:44) ~[?:?] {} at net.minecraft.entity.Entity.<init>(Entity.java:222) ~[?:?] {pl:accesstransformer:B} at net.minecraft.entity.LivingEntity.<init>(LivingEntity.java:192) ~[?:?] {} at net.minecraft.entity.player.PlayerEntity.<init>(PlayerEntity.java:162) ~[?:?] {pl:accesstransformer:B} at net.minecraft.entity.player.ServerPlayerEntity.<init>(ServerPlayerEntity.java:163) ~[?:?] {pl:accesstransformer:B} at net.minecraft.server.management.PlayerList.createPlayerForUser(PlayerList.java:390) ~[?:?] {} at net.minecraft.network.login.ServerLoginNetHandler.tryAcceptPlayer(ServerLoginNetHandler.java:119) ~[?:?] {} at net.minecraft.network.login.ServerLoginNetHandler.tick(ServerLoginNetHandler.java:63) ~[?:?] {} at net.minecraft.network.NetworkManager.tick(NetworkManager.java:241) ~[?:?] {} at net.minecraft.network.NetworkSystem.tick(NetworkSystem.java:148) ~[?:?] {} at net.minecraft.server.MinecraftServer.updateTimeLightAndEntities(MinecraftServer.java:882) ~[?:?] {pl:accesstransformer:B} at net.minecraft.server.MinecraftServer.tick(MinecraftServer.java:800) ~[?:?] {pl:accesstransformer:B} at net.minecraft.server.integrated.IntegratedServer.tick(IntegratedServer.java:118) ~[?:?] {pl:runtimedistcleaner:A} at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:646) ~[?:?] {pl:accesstransformer:B} at java.lang.Thread.run(Unknown Source) ~[?:1.8.0_221] {} EDIT: Nevermind, I'm just dumb and missed the fact the error says no capital letters.
  23. Okay, I think I've got it. Hopefully this looks right... https://gist.github.com/FireController1847/c7a50144f45806a996d13efcff468d1b EDIT: So I got this crash report, and I have no idea how to fix it. java.lang.NullPointerException: null at net.minecraftforge.common.capabilities.CapabilityManager.register(CapabilityManager.java:79) ~[?:?] at com.firecontroller1847.levelhearts.LevelHearts.<init>(LevelHearts.java:32) ~[?:?] at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[?:1.8.0_221] at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source) ~[?:1.8.0_221] at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source) ~[?:1.8.0_221] at java.lang.reflect.Constructor.newInstance(Unknown Source) ~[?:1.8.0_221] at java.lang.Class.newInstance(Unknown Source) ~[?:1.8.0_221] at net.minecraftforge.fml.javafmlmod.FMLModContainer.constructMod(FMLModContainer.java:131) ~[?:28.0] at java.util.function.Consumer.lambda$andThen$0(Unknown Source) ~[?:1.8.0_221] at java.util.function.Consumer.lambda$andThen$0(Unknown Source) ~[?:1.8.0_221] at net.minecraftforge.fml.ModContainer.transitionState(ModContainer.java:112) ~[?:?] at net.minecraftforge.fml.ModList.lambda$null$10(ModList.java:133) ~[?:?] at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(Unknown Source) ~[?:1.8.0_221] at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(Unknown Source) ~[?:1.8.0_221] at java.util.stream.AbstractPipeline.copyInto(Unknown Source) ~[?:1.8.0_221] at java.util.stream.ForEachOps$ForEachTask.compute(Unknown Source) ~[?:1.8.0_221] at java.util.concurrent.CountedCompleter.exec(Unknown Source) ~[?:1.8.0_221] at java.util.concurrent.ForkJoinTask.doExec(Unknown Source) ~[?:1.8.0_221] at java.util.concurrent.ForkJoinTask.doInvoke(Unknown Source) ~[?:1.8.0_221] at java.util.concurrent.ForkJoinTask.invoke(Unknown Source) ~[?:1.8.0_221] at java.util.stream.ForEachOps$ForEachOp.evaluateParallel(Unknown Source) ~[?:1.8.0_221] at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateParallel(Unknown Source) ~[?:1.8.0_221] at java.util.stream.AbstractPipeline.evaluate(Unknown Source) ~[?:1.8.0_221] at java.util.stream.ReferencePipeline.forEach(Unknown Source) ~[?:1.8.0_221] at java.util.stream.ReferencePipeline$Head.forEach(Unknown Source) ~[?:1.8.0_221] at net.minecraftforge.fml.ModList.lambda$dispatchParallelEvent$11(ModList.java:133) ~[?:?] at java.util.concurrent.ForkJoinTask$AdaptedRunnableAction.exec(Unknown Source) [?:1.8.0_221] at java.util.concurrent.ForkJoinTask.doExec(Unknown Source) [?:1.8.0_221] at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(Unknown Source) [?:1.8.0_221] at java.util.concurrent.ForkJoinPool.runWorker(Unknown Source) [?:1.8.0_221] at java.util.concurrent.ForkJoinWorkerThread.run(Unknown Source) [?:1.8.0_221]
  24. Okay, I am now to the point where I got stuck before. When calling the serializeNBT and deserializeNBT functions, I need to call the IStorage instance from my capability. What I don't understand is how I am supposed to provide the instance if it is a LazyOptional... package com.firecontroller1847.levelhearts.capabilities; import net.minecraft.nbt.INBT; import net.minecraft.util.Direction; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.capabilities.CapabilityInject; import net.minecraftforge.common.capabilities.ICapabilitySerializable; import net.minecraftforge.common.util.LazyOptional; public class MoreHealthProvider implements ICapabilitySerializable<INBT> { @CapabilityInject(IMoreHealth.class) public static Capability<IMoreHealth> MORE_HEALTH_CAPABILITY; private LazyOptional<IMoreHealth> instance = LazyOptional.of(MORE_HEALTH_CAPABILITY::getDefaultInstance); @Override public <T> LazyOptional<T> getCapability(Capability<T> cap, Direction side) { return cap == MORE_HEALTH_CAPABILITY ? instance.cast() : LazyOptional.empty(); } @Override public INBT serializeNBT() { // using this.instance errors, expects IMoreHealth not Lazy Optional return MORE_HEALTH_CAPABILITY.getStorage().writeNBT(MORE_HEALTH_CAPABILITY, this.instance, null); } @Override public void deserializeNBT(INBT nbt) { // using this.instance errors, expects IMoreHealth not Lazy Optional MORE_HEALTH_CAPABILITY.getStorage().readNBT(MORE_HEALTH_CAPABILITY, this.instance, null, nbt); } } If I were to use LazyOptional.orElse, would I do something like this? @Override public INBT serializeNBT() { // using this.instance errors, expects IMoreHealth not Lazy Optional return MORE_HEALTH_CAPABILITY.getStorage().writeNBT(MORE_HEALTH_CAPABILITY, this.instance.orElse(MORE_HEALTH_CAPABILITY.getDefaultInstance()), null); } If I do, then what's the point of doing the LazyOptional.of with the getDefaultInstance method in the first place? EDIT: I read this comment on another thread, and it's starting to make more sense. So, in this situation, if the instance is null then it's an error condition, right? Or is it not...? Is it allowed to be null here? I'd assume not since the IStorage requires it...
  25. Okay, I swear that didn't show up when I tried it before. Alright, I think I understand it enough to get a prototype working, I'll probably be back at some point to ask more questions haha. Thanks for everyone's help!
×
×
  • Create New...

Important Information

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