Tavi007
Members-
Posts
145 -
Joined
-
Last visited
Everything posted by Tavi007
-
How to get the sum of all enchantment levels equipped
Tavi007 replied to squidlex's topic in Modder Support
To loop over the armor inventory use LivingEntity#getArmorInventoryList() and then iterate through it. Then use EnchantmentHelper#getEnchantments(stack) to get the enchantment data from an itemstack in form of Map<Enchantment, Integer>. -
Hello! I'm modifying the damage calculation by subscribing to LivingHurtEvent and scaling the damage value. This works fine, but now I also want to change the rendering a bit. My current LivingHurtEvent looks like this (I removed some unnecessary stuff) @SubscribeEvent public static void elementifyLivingHurtEvent(LivingHurtEvent event) { // compute new damage value .... // heals the target, if damage is lower than 0. This can happen with my modification if(damageAmount <= 0) { target.heal(-damageAmount); event.setCanceled(true); //does this even do something? damageAmount = 0; } event.setAmount(damageAmount); } 1. I want to change the red texture (an OverlayTexture?) to a green one, if the targets is healed. But I don't really know, where I should start with this task. I couldn't even find the code, that applies the red texture. So which Event do I need to hook in, so I can change this texture? Is it RenderLivingEvent? I also would like to read the vanilla code. I'm assuming, that the red overlayTexture is applied as long as hurttime>0, and that I might need to work around this with capabilities. 2. I also would like to reduce the screen shake (or at least disable it, when no damage has been dealt). Here I got the same question as 1. As you can see, I'm not really experienced with all the render stuff. It's my first time working with it. 3. Not really a question about rendering, but I didn't want to create a new thread for a single problem. I would also like to prevent the hurt-sound from firing, if no damage has been dealt and instead play another sound. Again I have no idea, where I would have to start looking in the vanilla code or which event I should use. So yeah, I'm quite clueless and I hope you can help me out. Here is my repository, if you need more informations: https://github.com/Tavi007/ElementalCombat
-
Okay then. If I encounter some problems, that I can't fix myself, I'll come asking again.
-
So, I should implement a capability, that extends ItemStackHandler (so it can store other ItemStacks), which then gets attached to the any of my IMateriaTool ItemStacks? Then I can fill the capability as I want in my EquippingStation. You might notice, that I'm a little bit confused ^^' Well I can implement that part, but would that really solve my problem with my EquippingStation inventory behaving so weirdly?
-
Done. Here the link again to my repository https://github.com/Tavi007/Materia
-
Because I'm too dumb to read your post, lol. Please take a look at my new code: package Tavi007.Materia.inventory; import java.util.ArrayList; import Tavi007.Materia.inventory.container.EquippingStationContainer; import Tavi007.Materia.items.IMateriaTool; import Tavi007.Materia.util.MateriaToolUtil; import net.minecraft.item.ItemStack; import net.minecraftforge.items.ItemStackHandler; public class EquippingStationItemHandler extends ItemStackHandler { private final EquippingStationContainer container; public EquippingStationItemHandler(EquippingStationContainer container) { super(9); this.container = container; } @Override public void onContentsChanged(int slot) { if(slot>=0 && slot < 8) { // BaseMateria ItemStack stack = getStackInSlot(slot); if (stack.isEmpty()) { // Materia got removed IMateriaTool tool = (IMateriaTool) getMateriaToolStack().getItem(); //the tool MateriaToolUtil.setMateriaStack(tool, ItemStack.EMPTY, slot); } else { // Materia got inserted IMateriaTool tool = (IMateriaTool) getMateriaToolStack().getItem(); //the tool MateriaToolUtil.setMateriaStack(tool, stack, slot); } } else if(slot == 8) { // IMateriaTool ItemStack stack = getStackInSlot(slot); if (stack.isEmpty()) { // IMateriaTool got removed for(int i=0; i<8; i++) { stacks.set(i, ItemStack.EMPTY); } } else { // IMateriaTool got inserted IMateriaTool tool = (IMateriaTool) stack.getItem(); ArrayList<ItemStack> topStacks = MateriaToolUtil.getMateriaStacks(tool.getTopSlots()); for(int i=0; i<topStacks.size(); i++) { stacks.set(i, topStacks.get(i)); } ArrayList<ItemStack> botStacks = MateriaToolUtil.getMateriaStacks(tool.getBotSlots()); for(int i=0; i<botStacks.size(); i++) { stacks.set(i+4, botStacks.get(i)); } } } else { // Should not have happened } } @Override public int getSlotLimit(int slot) { return 1; } @Override public boolean isItemValid(int slot, ItemStack stack) { return container.inventorySlots.get(slot).isItemValid(stack); } public boolean isMateriaSlotEnabled(int slotIndex) { ItemStack itemstack = container.getMateriaToolStack(); if(itemstack.isEmpty()) { return false; } IMateriaTool tool = (IMateriaTool) itemstack.getItem(); int noSlots; if(slotIndex<4) { noSlots = MateriaToolUtil.getNumberOfSlots(tool.getTopSlots()); if(slotIndex<noSlots) { return true; } } else { noSlots = MateriaToolUtil.getNumberOfSlots(tool.getBotSlots()); if(slotIndex-4<noSlots) { return true; } } return false; } public ItemStack getMateriaToolStack() { return stacks.get(8); } } I removed my own implementation of insertItem and extractItem and instead added my own code to onContentsChanged. Sadly a few new problems arise. First of, if I click with an item on a slot, that already has an itemstack, then the itemstack, that I'm holding (the one near the cursor) changes correctly. But the stack in the slot stays the same. Even more so, the stack in the slot is a weird ghost stack, that disappears after I insert the holded stack into the player inventory. I also noticed that shift-left click slots in my inventory to extract an item, never triggers the onContentsChanged function. That is kinda bad for me, because I would like to apply the same logic as the normal item extraction.
-
Thanks, I finally figured most of it out. The slots now get enabled as they should and also shift-left clicking works as intended. Extracting itemstacks from my inventory using a simple mousclick is slightly broken however. After clicking i can move the itemstack, but i have some weird ghost stack left in the slot, that disappears after I place the stack back into an inventory. So something is definitely wrong in my extractItem function, but I don't know what. (link)
-
Yeah, that was the error. I changed my code, so this won't happen anymore. Thanks!
-
Hello, I wanted try my mod in a server enviroment, but it crashed on startup. Here is the crash log: -- Head -- Thread: main Stacktrace: at net.minecraftforge.fml.loading.RuntimeDistCleaner.processClassWithFlags(RuntimeDistCleaner.java:71) ~[forge-1.16.4-35.1.4.jar:35.1] {} -- MOD elementalcombat -- Details: Mod File: elementalcombat-forge-1.16.4-1.0.jar Failure message: Elemental Combat (elementalcombat) encountered an error during the common_setup event phase java.lang.RuntimeException: Attempted to load class net/minecraft/client/entity/player/ClientPlayerEntity for invalid dist DEDICATED_SERVER Mod Version: 1.0 Mod Issue URL: NOT PROVIDED Exception message: java.lang.RuntimeException: Attempted to load class net/minecraft/client/entity/player/ClientPlayerEntity for invalid dist DEDICATED_SERVER Stacktrace: at net.minecraftforge.fml.loading.RuntimeDistCleaner.processClassWithFlags(RuntimeDistCleaner.java:71) ~[forge-1.16.4-35.1.4.jar:35.1] {} at cpw.mods.modlauncher.LaunchPluginHandler.offerClassNodeToPlugins(LaunchPluginHandler.java:85) ~[modlauncher-8.0.6.jar:?] {} at cpw.mods.modlauncher.ClassTransformer.transform(ClassTransformer.java:119) ~[modlauncher-8.0.6.jar:?] {} at cpw.mods.modlauncher.TransformingClassLoader$DelegatedClassLoader.findClass(TransformingClassLoader.java:265) ~[modlauncher-8.0.6.jar:?] {} at cpw.mods.modlauncher.TransformingClassLoader.loadClass(TransformingClassLoader.java:136) ~[modlauncher-8.0.6.jar:?] {re:classloading} at cpw.mods.modlauncher.TransformingClassLoader.loadClass(TransformingClassLoader.java:98) ~[modlauncher-8.0.6.jar:?] {re:classloading} at java.lang.ClassLoader.loadClass(Unknown Source) ~[?:1.8.0_271] {} at java.lang.invoke.MethodHandleNatives.resolve(Native Method) ~[?:1.8.0_271] {} at java.lang.invoke.MemberName$Factory.resolve(Unknown Source) ~[?:1.8.0_271] {} at java.lang.invoke.MemberName$Factory.resolveOrFail(Unknown Source) ~[?:1.8.0_271] {} at java.lang.invoke.MethodHandles$Lookup.resolveOrFail(Unknown Source) ~[?:1.8.0_271] {} at java.lang.invoke.MethodHandles$Lookup.linkMethodHandleConstant(Unknown Source) ~[?:1.8.0_271] {} at java.lang.invoke.MethodHandleNatives.linkMethodHandleConstant(Unknown Source) ~[?:1.8.0_271] {} at Tavi007.ElementalCombat.StartupCommon.onCommonSetup(StartupCommon.java:29) ~[elementalcombat:1.16.4-1.0] {re:classloading} at net.minecraftforge.eventbus.ASMEventHandler_2_StartupCommon_onCommonSetup_FMLCommonSetupEvent.invoke(.dynamic) ~[?:?] {} at net.minecraftforge.eventbus.ASMEventHandler.invoke(ASMEventHandler.java:85) ~[eventbus-3.0.5-service.jar:?] {} at net.minecraftforge.eventbus.EventBus.post(EventBus.java:297) ~[eventbus-3.0.5-service.jar:?] {} at net.minecraftforge.fml.javafmlmod.FMLModContainer.acceptEvent(FMLModContainer.java:120) ~[forge:35.1] {re:classloading} at net.minecraftforge.fml.ModContainer.lambda$buildTransitionHandler$4(ModContainer.java:121) ~[forge:?] {re:classloading} at java.util.concurrent.CompletableFuture$AsyncRun.run(Unknown Source) ~[?:1.8.0_271] {} at java.util.concurrent.CompletableFuture$AsyncRun.exec(Unknown Source) ~[?:1.8.0_271] {} at java.util.concurrent.ForkJoinTask.doExec(Unknown Source) ~[?:1.8.0_271] {} at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(Unknown Source) ~[?:1.8.0_271] {} at java.util.concurrent.ForkJoinPool.runWorker(Unknown Source) ~[?:1.8.0_271] {} at java.util.concurrent.ForkJoinWorkerThread.run(Unknown Source) ~[?:1.8.0_271] {} and here is the failing file: package Tavi007.ElementalCombat; import Tavi007.ElementalCombat.capabilities.defense.DefenseDataCapability; import Tavi007.ElementalCombat.network.EntityMessage; import Tavi007.ElementalCombat.network.ItemMessage; import Tavi007.ElementalCombat.network.PackageHandlerOnClient; import Tavi007.ElementalCombat.network.PackageHandlerOnServer; import java.util.Optional; import Tavi007.ElementalCombat.capabilities.attack.AttackDataCapability; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; import net.minecraftforge.fml.network.NetworkDirection; import net.minecraftforge.fml.network.NetworkRegistry; public class StartupCommon { private static final byte ENTITYDATA_MESSAGE_TO_CLIENT_ID = 1; private static final byte ITEMDATA_MESSAGE_TO_CLIENT_ID = 2; public static final String MESSAGE_PROTOCOL_VERSION = "1.0"; @SubscribeEvent public static void onCommonSetup(FMLCommonSetupEvent event){ //capabilities AttackDataCapability.register(); DefenseDataCapability.register(); //networking ElementalCombat.simpleChannel = NetworkRegistry.newSimpleChannel(ElementalCombat.simpleChannelRL, () -> MESSAGE_PROTOCOL_VERSION, PackageHandlerOnClient::isThisProtocolAcceptedByClient, PackageHandlerOnServer::isThisProtocolAcceptedByServer); ElementalCombat.simpleChannel.registerMessage(ENTITYDATA_MESSAGE_TO_CLIENT_ID, EntityMessage.class, EntityMessage::encode, EntityMessage::decode, PackageHandlerOnClient::onMessageReceived, Optional.of(NetworkDirection.PLAY_TO_CLIENT)); ElementalCombat.simpleChannel.registerMessage(ITEMDATA_MESSAGE_TO_CLIENT_ID, ItemMessage.class, ItemMessage::encode, ItemMessage::decode, PackageHandlerOnClient::onMessageReceived, Optional.of(NetworkDirection.PLAY_TO_CLIENT)); ElementalCombat.LOGGER.info("setup method registered."); } } Line 29 is the one right below the comment '//networking'. I don't understand, why the game tries to load ClientPlayerEntity here. Also this part was actually working in previous version of my mod (see here: https://github.com/Tavi007/ElementalCombat/blob/master/src/main/java/Tavi007/ElementalCombat/StartupCommon.java), tho this was for minecraft 1.16.3.
-
Since the inventory is called the same way as a the GUI of a workbench, it would actually not matter in my case. I will stick to the ItemHandler however, because I might change my mind on the former and that would make switching easier.
-
I know about your github. It is one of my references. What is the difference between the IITemHandler and an IIventory? And when am I supposed to use which?
-
I will try my best to implement your suggestion. Few question before I start diving in. 1: Slot#isEnabled ist client only. How can this prevent the server side container to not put stacks into certain slots? (for example via shift clicking) 2: Where can I find some classes/tutorials that implements IItemHandler in combination with a container?
-
Hey folks, I've been trying to implement a GUI , which should add and remove (or enables/disables) slots depending of an itemstack in a dedicated slot. Let me explain with using some images: the bottom slots are the player inventory. At the top, we have a slot for a tool, which implement IMateriaTool (for my own tool classes). Right next to it are the slots for Materia. And the last block is for displaying some information (the screen class will display some text here, so it is uninterresting for the container). On opening the GUI, the player inventory should be filled correctly, but all the slots at the top are empty. At this point, it should not be possible to add Materia in any of the Materia slots. Either because the slots don't exist yet or because they are disabled. When I put an IMateriaTool into the right slot, I want the right amount of materia slots added/enabled and I also want to fill some of them with the right items. The number of slots and the corresponding itemstack all depend on the tool and said data can be retrieved from it Now I should be able to modify the data from the tool by adding/removing Materia. When I remove the tool from his slot, I want to be back in the state from the first picture. This means, that the slots for the Materia need to be cleaned and removed/disabled again. I hope this explanation was clear enough. In case of confusion, please ask. Now to my question: How can implement this? For the last week I've been trying to figure something out by myself, but everytime I get a little bit confused and suddendly I have an IndexOutOfBounds error. For starters I have slots specifically for MateriaTools and Materia: https://github.com/Tavi007/Materia/blob/master/src/main/java/Tavi007/Materia/inventory/container/MateriaContainerSlot.java https://github.com/Tavi007/Materia/blob/master/src/main/java/Tavi007/Materia/inventory/container/MateriaToolContainerSlot.java Then I also have a container and an inventory, which is supposed to handle the items at the top (so the tool and the materia) https://github.com/Tavi007/Materia/blob/master/src/main/java/Tavi007/Materia/inventory/container/EquippingStationContainer.java https://github.com/Tavi007/Materia/blob/master/src/main/java/Tavi007/Materia/inventory/EquippingStationInventory.java keep in mind, that the current state of my master branch was me trying to figure it out on my own. So stuff might be handled stupidly. I also tried my best be reading some code of different tutorial mods, but none of them could help with my confusion so far. So I really hope you guys can help me. PS: For those, who think, that this kinda system seems familiar: I'm trying to implement the Materia system from Final Fantasy VII in Minecraft
-
[1.16.4] Costum screen doesn't display background image
Tavi007 replied to Tavi007's topic in Modder Support
Yup, that was the missing piece. Thank you! -
Hello! I tried to implement my first GUI, which functionality is similar to the vanilla crafting table. I got almost everything working: I got a block, a container and a screen all registered and the container also opens, when i right-click on my new block. However the screen is missing the background image and has a wrong title/name at the top. This lets me believe, that my error lies within the resource location or my assets, but I'm sure I named everything correctly. So please take a look and help me out. Thank you in advance Here is my github: https://github.com/Tavi007/Materia (you can find the screen registration in the client.init package)
-
[1.16] syncronising itemstack capabilities for any item
Tavi007 replied to Tavi007's topic in Modder Support
Bump. I really hope someone knows more about this stuf. This is basically the last hurdle for my mod and I would really like to have a proper release in this year. -
[1.16] syncronising itemstack capabilities for any item
Tavi007 replied to Tavi007's topic in Modder Support
Hey, so tried to implement what you said and I got it mostly working, but there is one last bug remaining. When I open the play inventory, the itemstacks won't get updated immediately. I have to move the itemstack at least once for it to update. Any other container is working as intended tho. If I open a chest, every itemstack has the right information directly. Any idea what the reason might be? Could it have to do something with the curios mod, which I'm using while developing? Some links of my github: https://github.com/Tavi007/ElementalCombat/tree/master/src/main/java/Tavi007/ElementalCombat/capabilities https://github.com/Tavi007/ElementalCombat/tree/master/src/main/java/Tavi007/ElementalCombat/network -
[1.16] syncronising itemstack capabilities for any item
Tavi007 replied to Tavi007's topic in Modder Support
Thank you so much for such an in depth answer! I think, I should be able to modify your code now (cause I really only have 2 capabilities, so my system doesn't have to be as flexible as yours) -
[1.16] syncronising itemstack capabilities for any item
Tavi007 replied to Tavi007's topic in Modder Support
Sooo... -
[1.16] syncronising itemstack capabilities for any item
Tavi007 replied to Tavi007's topic in Modder Support
It's just for displaying the data as tooltip. Also the data doesn't change that often, so it wouldn't need to be syncronized continously. -
[1.16] syncronising itemstack capabilities for any item
Tavi007 replied to Tavi007's topic in Modder Support
Well that sucks. I found this thread which seems to have a work around with a container listener (hence why I mentioned it in the op). Do you know more on this topic? Cause I don't fully understand it yet. -
[1.16] syncronising itemstack capabilities for any item
Tavi007 replied to Tavi007's topic in Modder Support
Since I attach my capability to every item, how could I synchronize it for lets say the vanilla iron sword? -
[1.16] syncronising itemstack capabilities for any item
Tavi007 replied to Tavi007's topic in Modder Support
Bump. To rephrase my question: How can I syncronize itemstack capabilities without using Item#getShareTag/readShareTag? Are there some vanilla classes/ example mods, that implemented container listener, so I can check them out? -
[1.16] syncronising itemstack capabilities for any item
Tavi007 replied to Tavi007's topic in Modder Support
Just tested this part again and now the itemstack won't sync up. I swear they did before... -
Hello! I have an Itemstack capability on client and server side and I want the client one syncronised with the server. Overriding Item#getShareTag and Item#readShareTag is not possible, because the capability is attached to every itemstack. With the help of google I found 2 answers to my question, however I'm struggling with implementation. The first solution I found was to send packaged through a simpleChannel. I know the basics of this method, because I succesfully implemented this type of networking for my entity capability. My problem is, that I don't know, when I would have to send the message. You can look at my code on this branch here for more details: https://github.com/Tavi007/ElementalCombat/tree/ItemSync-via-packets/src/main/java/Tavi007/ElementalCombat (check out the network package). For the entity one I knew the events, that were relevant, so I knew, when stuff would change. For Itemstack I do not know this yet. The second solution was to implement a containerListener, just like Choonsters did in his TestMod3. In an attempt to understand the code I copied his code, did some changes and somehow got it working. To be frank, I still don't fully understand his code, but it did sync up the capability. What's weird is, that I never specified to just sync up my capability nor did I define a message for it. I'm afraid, that this will cause issues with other mods down the line. (Also I don't like the fact, that I don't know, what my code is doing). You can look up the code for this attempt on this branch: https://github.com/Tavi007/ElementalCombat/tree/ItemSync-via-Listener/src/main/java/Tavi007/ElementalCombat (check out the capability and network package). Can someone please elaborate how this type of networking usually works?