

Ipsissimus418
Members-
Content count
11 -
Joined
-
Last visited
Community Reputation
0 NeutralAbout Ipsissimus418
-
Rank
Tree Puncher
-
[SOLVED][1.12.2] onLivingDeath Event Multiple Calls For Ender Dragon
Ipsissimus418 replied to Ipsissimus418's topic in Modder Support
I've started to cache the last few entity.getCachedUniqueIdString and then used that to compare incoming event, then dropping the event if I've already seen that id. This seems to filter out the multiple Dragon ones without having any obvious impact on other entity deaths. -
[SOLVED][1.12.2] onLivingDeath Event Multiple Calls For Ender Dragon
Ipsissimus418 replied to Ipsissimus418's topic in Modder Support
That actually fits in with a piece of code in EntityDragon attackDragonFrom if health <= 0.0F && !currentphase.isStationary setHealth(1.0F) setPhase(DYING) That seems to tick the Dragon back up by 1 health if you attack it while it is dying, but still moving. It would therefore be allowed to reach the onDeath multiple times as the health > 0.0F. If that is the case, I might try caching the last EntityID in my event handler to try and filter out the duplicate Dragon ones. It wont be 100% successful, but it should cut them down a bit. -
[SOLVED][1.12.2] onLivingDeath Event Multiple Calls For Ender Dragon
Ipsissimus418 posted a topic in Modder Support
In my mod I use the onLivingDeath event to decide if a user has killed enough of a specific mob for something to occur. I recently had an issue raised on GitHub where the user said that they could keep hitting the Dragon with arrows while it was dying and they could register multiple deaths. I've added some debug to my event handler and sure enough, if I was quick enough with a bow I could get multiple events raised until a point in the EnderDragon death sequence eg. public class HandlerLivingDeathEvent { @SubscribeEvent public void onLivingDeathEvent(LivingDeathEvent event) { LogHelper.info("onLivingDeathEvent: " + event.getSource() + "/" + event.getEntity() + "/" + event.getEntity().isDead); new Exception().printStackTrace(); Gave the output [12:26:23] [Server thread/INFO]: Woot: onLivingDeathEvent: net.minecraft.util.EntityDamageSourceIndirect@70bea580/EntityDragon['Ender Dragon'/277010, l='Mob Test', x=7.20, y=84.56, z=-28.32]/false [12:26:23] [main/INFO]: Woot: onLivingDeathEvent: net.minecraft.util.DamageSource@369d50fa/EntityDragon['Ender Dragon'/277010, l='MpServer', x=7.50, y=84.50, z=-29.54]/false [12:26:24] [Server thread/INFO]: Woot: onLivingDeathEvent: net.minecraft.util.EntityDamageSourceIndirect@764bce76/EntityDragon['Ender Dragon'/277010, l='Mob Test', x=7.99, y=80.26, z=-24.57]/false [12:26:25] [Server thread/INFO]: Woot: onLivingDeathEvent: net.minecraft.util.EntityDamageSourceIndirect@4a8c7eaa/EntityDragon['Ender Dragon'/277010, l='Mob Test', x=9.94, y=68.92, z=-15.77]/false So I managed three server events for onLivingDeath and one client event. On another run I managed to get six server events and one client event. I'm only summoning one EnderDragon so it can only be for the one mob. Dumping the stack for the server event showed the same path for each event [12:29:54] [Server thread/INFO]: [ipsis.woot.event.HandlerLivingDeathEvent:onLivingDeathEvent:21]: at ipsis.woot.event.HandlerLivingDeathEvent.onLivingDeathEvent(HandlerLivingDeathEvent.java:21) [12:29:54] [Server thread/INFO]: [ipsis.woot.event.HandlerLivingDeathEvent:onLivingDeathEvent:21]: at net.minecraftforge.fml.common.eventhandler.ASMEventHandler_188_HandlerLivingDeathEvent_onLivingDeathEvent_LivingDeathEvent.invoke(.dynamic) [12:29:54] [Server thread/INFO]: [ipsis.woot.event.HandlerLivingDeathEvent:onLivingDeathEvent:21]: at net.minecraftforge.fml.common.eventhandler.ASMEventHandler.invoke(ASMEventHandler.java:90) [12:29:54] [Server thread/INFO]: [ipsis.woot.event.HandlerLivingDeathEvent:onLivingDeathEvent:21]: at net.minecraftforge.fml.common.eventhandler.EventBus.post(EventBus.java:179) [12:29:54] [Server thread/INFO]: [ipsis.woot.event.HandlerLivingDeathEvent:onLivingDeathEvent:21]: at net.minecraftforge.common.ForgeHooks.onLivingDeath(ForgeHooks.java:600) [12:29:54] [Server thread/INFO]: [ipsis.woot.event.HandlerLivingDeathEvent:onLivingDeathEvent:21]: at net.minecraft.entity.EntityLivingBase.onDeath(EntityLivingBase.java:1282) [12:29:54] [Server thread/INFO]: [ipsis.woot.event.HandlerLivingDeathEvent:onLivingDeathEvent:21]: at net.minecraft.entity.EntityLivingBase.attackEntityFrom(EntityLivingBase.java:1127) [12:29:54] [Server thread/INFO]: [ipsis.woot.event.HandlerLivingDeathEvent:onLivingDeathEvent:21]: at net.minecraft.entity.boss.EntityDragon.attackDragonFrom(EntityDragon.java:643) [12:29:54] [Server thread/INFO]: [ipsis.woot.event.HandlerLivingDeathEvent:onLivingDeathEvent:21]: at net.minecraft.entity.boss.EntityDragon.attackEntityFromPart(EntityDragon.java:601) [12:29:54] [Server thread/INFO]: [ipsis.woot.event.HandlerLivingDeathEvent:onLivingDeathEvent:21]: at net.minecraft.entity.MultiPartEntityPart.attackEntityFrom(MultiPartEntityPart.java:51) [12:29:54] [Server thread/INFO]: [ipsis.woot.event.HandlerLivingDeathEvent:onLivingDeathEvent:21]: at net.minecraft.entity.projectile.EntityArrow.onHit(EntityArrow.java:391) [12:29:54] [Server thread/INFO]: [ipsis.woot.event.HandlerLivingDeathEvent:onLivingDeathEvent:21]: at net.minecraft.entity.projectile.EntityArrow.onUpdate(EntityArrow.java:286) [12:29:54] [Server thread/INFO]: [ipsis.woot.event.HandlerLivingDeathEvent:onLivingDeathEvent:21]: at net.minecraft.entity.projectile.EntityTippedArrow.onUpdate(EntityTippedArrow.java:110) [12:29:54] [Server thread/INFO]: [ipsis.woot.event.HandlerLivingDeathEvent:onLivingDeathEvent:21]: at net.minecraft.world.World.updateEntityWithOptionalForce(World.java:2168) [12:29:54] [Server thread/INFO]: [ipsis.woot.event.HandlerLivingDeathEvent:onLivingDeathEvent:21]: at net.minecraft.world.WorldServer.updateEntityWithOptionalForce(WorldServer.java:871) [12:29:54] [Server thread/INFO]: [ipsis.woot.event.HandlerLivingDeathEvent:onLivingDeathEvent:21]: at net.minecraft.world.World.updateEntity(World.java:2127) [12:29:54] [Server thread/INFO]: [ipsis.woot.event.HandlerLivingDeathEvent:onLivingDeathEvent:21]: at net.minecraft.world.World.updateEntities(World.java:1928) [12:29:54] [Server thread/INFO]: [ipsis.woot.event.HandlerLivingDeathEvent:onLivingDeathEvent:21]: at net.minecraft.world.WorldServer.updateEntities(WorldServer.java:643) This is using Forge 1.12.2-14.23.3.2655. I have a few mods in my dev environment for testing, but nothing is jumping out as having any impact on the Dragon death sequence. Looking at the methods in the stack trace I'm not seeing any obvious path that allows this. attackEntityFromPart(dragonPart, source, damage) damage = modify damage if neede attackDragonFrom(source, damage) attackEntityFrom(source, damage) raise onLivingAttack event if health <= 0.0F return damageEntity if health <= 0.0F onDeath raise onLivingDeath event So am I just using the wrong event to register the death occurring in my code, or is this a known "quirk" of the Dragon death and the fact that it is a multi-part mob? -
[1.12.2] [SOLVED] Multiblock chunk load
Ipsissimus418 replied to Ipsissimus418's topic in Modder Support
So TileEntity::validate did the trick. First try it got called on both the server and the client - which created a very impressive stack overflow. Limiting that to the server - which is where I needed to do it - allowed me to walk to the master. One initial concern was the algorithm I use to walk to the master was travelling over other TEs in the same chunk which had not yet had their validate methods called yet. However as I only use their position to determine the path and never try to access them, I don't think that is an issue. I'm now horribly embarrassed for investigating every other method in block and TE and completely overlooking the "validate" one. Thanks diesieben07 -
I currently have a working multiblock with a mixture of ticking and non-ticking TEs. The main block (heart/master) is a ticking TE with a public method interruptStructure which basically tells it to do a scan of the multiblock. All the other blocks are non-ticking TEs which when block.onBlockAdded is called, find the nearest reachable heart and call master.interruptStructure. They do something similar for when the block/te is invalidated. So I've got a way to say hello-block.onBlockAdded and goodbye-te.invalidate This seems to work nicely until someone builds the multiblock over a chunk boundary The problems occurs when the player moves away from the multiblock and returns. When the first chunk loads and it contains the heart, then the heart does an initial scan and fails since some of the multiblock is in the unloaded chunk. The player moves further forward, the next chunk loads and then the rest of the multiblock is loaded, but cannot say hello because there is no block.onBlockAdded for a chunk load. My solution - which I don't like - is to make them all tickable, then on the first tick of the non-heart blocks, find the master and poke it. All subsequent ticks for that TE are then no-ops. But of course I've just registered possibly 60 new ticking TEs per multiblock - which doesn't seem right. So does anyone have any suggestions of a way to fix this that doesn't involve making them all ITickable? Possible alternative: Keep track of which chunks have heart TEs and then when a neighbouring chunk loads, use that list to force the heart to rescan. Thanks Ipsis
-
[1.12.2][SOLVED] Json recipe enchanted book ingredient
Ipsissimus418 replied to Ipsissimus418's topic in Modder Support
I'm going to stick with the enchantment name solution, rather than trying a NBTPredicate solution. I'll mark this as solved and update the title to something more appropriate. Mainly so nobody thinks that the solution shows partial NBT matching. -
[1.12.2][SOLVED] Json recipe enchanted book ingredient
Ipsissimus418 replied to Ipsissimus418's topic in Modder Support
That was me using vanilla enchantments and thinking it would always work Thanks, I'll swap over to using the registry name instead. Github commit -
[1.12.2][SOLVED] Json recipe enchanted book ingredient
Ipsissimus418 replied to Ipsissimus418's topic in Modder Support
So I gave Choonster's pointers a go and I think I have something working. I added a new factory with my new type that allowed me to specify an enchant id and enchant level. The factory then parsed those json entries and applies them as the enchantment to the itemstack so it shows up in the recipe tooltips. The factory then created a new IngredientEnchantedBook object with the itemstack, enchantment id and enchantment level. The IngredientEnchantedBook apply method then uses EnchantmentHelper to pull the enchantments off the input stack and looks for the stored enchantment id and level in that map. The recipes were then updated to do the following: { "type": "woot:enchanted_book", "item": "minecraft:enchanted_book", "enchant_id", 16, "enchant_lvl": 1 } This moves away from matching the NBT tags for now, but does mean that as long as a valid enchantment is present it will match. I am a little concerned with this method processing all the enchantments on the itemstack to do this match, as it seems a lot of processing compared to a quicker(?) partial-nbt match. Below is a link to the commit with the factory and EnchantmentHelper version for future reference. Github commit I'll investigate the NBTPredicate method next. -
[1.12.2][SOLVED] Json recipe enchanted book ingredient
Ipsissimus418 posted a topic in Modder Support
I've had a bug report raised to me where my crafting recipes using enchanted books were not matching anymore. The issue came down to me testing with cheated in or enchantment table books and the user creating them with the anvil. The anvil added an extra nbt tag "RepairCost" that caused the book to no longer match in the recipe. So I'm guessing that the ingredient type "minecraft:item_nbt" has to match exactly and have no other nbt tags present. Does anyone have any pointers as to how to handle this situation of extra, unwanted nbt tags being present on the item that item_nbt matches against? I've looked at IIngredientFactory but I'm not sure that is going to help me. Thanks Ipsis This is what I'm using to match against. { "type": "minecraft:item_nbt", "item": "minecraft:enchanted_book", "nbt": "{ StoredEnchantments: [ { id: 21s, lvl: 1s } ] }" } The user showed a screenshot with the nbt as {RepairCost:1,StoredEnchantments:[{lvl:2s,id:48s}]} -
[1.12][SOLVED] Json recipe with enchanted book ingredient
Ipsissimus418 replied to Ipsissimus418's topic in Modder Support
So I think I've solved this, because my upgrade to Forge 14.23.1.2554 didn't fully refresh the dev environment. Now that I'm definitely running with the latest forge, it looks like my recipe issues are not happening anymore and I've getting unique items. So I'll pass on my apologies for wasting peoples time. (No matter how much you check, you always miss the obvious!) -
[1.12][SOLVED] Json recipe with enchanted book ingredient
Ipsissimus418 posted a topic in Modder Support
I had upgraded my mod to use the json recipes as part of the 1.12.X port and I believe they were working find when I first tested them. I used to use a custom recipe handler in the pre-1.12 versions. However I've recently retested due to a bug report (StoredEnchandments needing to use shorts in the nbt) and seem to be getting the same output item for all the recipes that have the all the same ingredients, apart from a different enchanted book. These recipes all use vanilla enchanted books as an ingredient. JEI shows the correct output for the input ingredients, but the vanilla crafting table gives the wrong output. I've updated to using Forge 14.23.1.2554 with no difference. eg. rate 1 upgrade (metadata 0) - factory base + t1 upgrade core + power I enchanted book -> output is decapitate I (metadata 12) looting 1 upgrade (metadata 3) - factory base + t1 upgrade core + looting I enchanted book -> output is decapitate I (metadata 12) https://github.com/Ipsis/Woot/tree/1_12/src/main/resources/assets/woot/recipes https://github.com/Ipsis/Woot/blob/1_12/src/main/resources/assets/woot/recipes/upgrade_looting_i.json https://github.com/Ipsis/Woot/blob/1_12/src/main/resources/assets/woot/recipes/upgrade_rate_i.json https://github.com/Ipsis/Woot/blob/1_12/src/main/resources/assets/woot/recipes/upgrade_decapitate_i.json All the recipes with enchanted books output the same item but with different metadata. "result": { "item": "woot:upgrade", "data": 3 }, This is the format of ingredient I was using successfully(?) before, probably during 1.12 development rather than 1.12.1 or 1.12.2. { "type": "minecraft:item_nbt", "item": "minecraft:enchanted_book", "nbt": { "StoredEnchantments": [ { "id": 21, "lvl": 1 } ] } } I've also tried using the vanilla string nbt version of this with the same results. { "type": "minecraft:item_nbt", "item": "minecraft:enchanted_book", "nbt": "{ StoredEnchantments: [ { id: 32s, lvl: 1s } ] }" }