-
Posts
52 -
Joined
-
Last visited
Everything posted by izofar
-
Ah, I see. Is the <T extends LivingEntity> the player, in this case? In addition, I'm not familiar with the <> Notation as used in `public <T extends LivingEntity> int damageItem(...)`. Does this just place restriction on T? How does one use the Consumer<T> input? I'm looking at ItemStack#hurtAndBreak for direction on how to use the inputs. But, I've found that breaking an item occurs outside of the damageItem call. which means that giving the player the replacement item inside of damageItem will happen before the original is broken and removed.
-
I have a ModdedArmorItem extends ArmorItem class which overrides setDamage(ItemStack stack, int damage), in which i want to check if the durability is zero, then replace the item stack with another item. Functionally, I want armor to leave an item when it breaks (to simplify, break into another armor item that resides in the same slot).
-
Is there a way to access the player owning the inventory an item stack is in? If any? Or to change the item in an itemstack? Two ways I've looked at this is to do onArmorTick(PlayerEntity player) to store the player but I don't think this would work for multiplayer (since there is only one modded armor class instantiated?). The other means I'm trying is to set the entity representation of the item stack obtained from setDamage to the entity representation of a newly instantiated itemstack of the desired replacement material. I am not optimistic about either approach.
-
Excellent, thanks. If I wanted, for example, gold armor to drop ingots upon breaking, how would I achieve this for vanilla armor? Would I have to duplicate the gold armor item instantiations (except inherited from the custom class) and register them under the minecraft:golden_*slot* resource? Or is writing a hook for the trigger a more desirable solution? In addition, where is this damage item method? I can't find it in the type hierarchy. I thought this would be a member of the item stack, not the item class.
-
This is my modded armor. Instantiated: Item moddedHelmet = new ArmorItem( ...); If I'm correct, are you about to suggest I make my own armor class that inherits from ArmorItem (or something) and override some itemDamaged method? Because now that makes sense Despite this, I do intend to do this for other armor items as well in the future
-
My intent is to hijack the event when a piece of armor's durability reaches zero, and replace the item with another once this occurs. Currently I've read there is no Forge hook for this, and that I should add a listener to the ItemDurabilityTrigger. Source: I, however, have no clue how to do this. I've found ItemDurabilityTrigger#changedDurability, which is what I want to intercept. I've tried to look at how this method is used, and I found net.minecraft.data.advancements.NetherAdvancements, which checks if warped fungus on a stick was used. I don't believe this is the condition in which I would wish to use it, though. While I understand and have been using events and listeners, is Draco18s instruction/advice a Java concept I am too noob to know, or are there Forge-specific libraries and techniques that I must use to register listeners/events and all of that?
-
While the OP may have moved on from this topic... I have been pursuing this same goal for 1.16.5 I have been searching the Vanilla Library and came across the net.minecraft.block.AbstractFireBlock#onPlace method. This is where nether portal activation occurs, and gives sample code to achieving your own. My intent was to implement a nether portal using crying obsidian, rather than obsidian. I did this by 1) cancelling the PortalSpawnEvent (which is called in net.minecraft.blocks.AbstractFireBlock#onPlace) and then 2) Copying the net.minecraft.block.PortalSize class over to my own. Then changing the AbstractBlock.IPositionPredicate FRAME instance variable to check that the block is Crying obsidian. I would have liked to not copy, but the vanilla code offers a private method isPortalFrame in one of the block classes that only returns true for obsidian. For anyone making a custom portal for a custom dimension, I would recommend making your own PortalFrame block similar to the vanilla nether portal frame class, then replacing all nether portal frame references in the PortalSize class to your new block.
-
Wow, that's an easy solution. Kudos on the shameless plug, as well, good sir :P
-
I intend to use reflection to modify the vanilla potion brewing recipes. To do this, I need the SRG name, but can currently only see the mapped name from MojMaps. When I comment out the // mappings channel: 'official', version: '1.16.5' in build.gradle, `gradlew genEclipseRuns` doesn't like it. How do I temporarily disable the mappings so that I know which SRG to use in my reflection?
-
[1.15.2] Check if it is snowing in the chunk an entity is in
izofar replied to izofar's topic in Modder Support
It seems like I'm learning, since I did think to try this, and it worked! Thank you so much, you're a champ -
[1.15.2] Check if it is snowing in the chunk an entity is in
izofar replied to izofar's topic in Modder Support
Unfortunately, I have never had to do this before. I changed the build.gradle accordingly: mappings channel: 'snapshot', version: '20200513-1.15.1' then ran ./gradlew genRunEclipse, ./gradlew eclipse and ./gradlew --refresh-dependencies with success. This didn't invalidate the references I had before and what should be the updated references still don't work am I missing a step? Edit: ExampleMod/src/main/java/com/jacobdil/dillmod/entity/ai/goal/CollideGoal.java:174: error: cannot find symbol return this.world.func_226665_a__(this.entity, this.entity.getBoundingBox().offset(blockpos)); ^ symbol: method func_226665_a__(MobEntity,AxisAlignedBB) location: variable world of type IWorldReader That looks promising, but if only my IDE would follow along! -
[1.15.2] Check if it is snowing in the chunk an entity is in
izofar replied to izofar's topic in Modder Support
Makes sense, considering I used the methods.csv of the latest snapshot to find World#func_226691_t_ in the first place -
[1.15.2] Check if it is snowing in the chunk an entity is in
izofar replied to izofar's topic in Modder Support
I'm not sure why, Eclipse is telling me net.minecraft.world.World has no method called getBiome. This is odd since the 1.15 source code I've seen have accessed it. -
[1.15.2] Check if it is snowing in the chunk an entity is in
izofar posted a topic in Modder Support
I am intercepting a LivingUpdateEvent, and have accessed event.getEntity.getWorld(), but don't know where to go from here. So far, I have found world#isRaining, but not one for snowing, so I figure I check if it is raining and if the biome is cold, but how do I find the biome? I suspect I can do this with the chunk provider, but I'm not sure, since all of the methods I've found on GitHub or past forums seems to make references to outdated fields (I even checked MCPBot to see if I could find some of these fields obfuscated, to no avail). Specifically, I can't seem to call world#getBiome Edit: As of now, I have found World#func_226691_t_ which seems to return a biome given a BlockPos. From this I have: world.func_226691_t_(player.getPosition()).getPrecipitation() == Biome.RainType.SNOW However, this seems to only check the type of precipitation, not when it is precipitating. -
My goal is to increase the litter-size when pigs breed (to make them more desirable to farm), my first thought was to use EntityJoinWorldEvent conditioned on the entity being a baby pig and then spawning some random number more. However, it didn't take long to realize that spawning pigs every time a pig is spawned won't lead to spawning pigs every time a pig is spawned won't lead to spawning pigs every time a pig is spawned won't lead to spawning pigs every time a pig is spawned won't lead to spawning pigs every time a pig is spawned won't lead to a result I desire... (mind my recursion joke). Any better way to do this? (Taking a look at the BabyEntitySpawnEvent, it seems I will run into the same issue).
-
Just to make sure I understand: To do this, I would copy the vanilla code to redefine the honey bottle item myself, then re-register it as minecraft:honey_bottle? Would this effect events like collecting honey from beehives (which returns the original minecraft:honey_bottle)?
-
In researching reflection with Forge, I came across MCPBot and Jabelar's helpful post explaining how it works. I noticed that the latest MCPBot snapshot is for 1.15.1, does this mean I can't yet use reflection the way I intend to in 1.15.2? Jabelar also cited the event of reflection working in the IDE but not the build, which leads me to have such suspicions. Such leads me to ask, because I am trying to change maxStackSize, this field was obfuscated as field_200920_a in 1.15.1 according to MCPBot. how likely is this to have changed in 1.15.2? Do they get randomly generated per every update or do they usually remain consistent? (From comparing across 1.15.1 and 1.14.4, they seem to remain the same)
-
Trying to change the maxStackSize of honey bottle to 1 (like potions/water bottles/etc.)
-
Item#maxStackSize is a private final int and I would like to use reflection to change this. For context, I have the following code: From this I get the following in latest.log: From this, I believe that there have been no static references to the Item class at the point of this code being run (my error occurs on startup). This would make sense for I am calling the StackSizeEditor.adjustStackSizes() method in a static block in one of my event handlers. My question is, if the meat of the code is correct (which, I believe to be so, because ./gradlew runClient doesn't give me this error, only running from the launcher with the file as result of ./gradlew build), then where do I make the call to the above code? On world startup? Another note: when I change SecurityException e to Exception e, I don't get a null error on startup (to be expected because the exception is handled), but the honey bottle item is still stackable (also to be expected if the reflection failed). This is why I suspect that I must call this method elsewhere in my code. I, however, am not sure where. Edit: reformatted code-block w/ comments for readability Update: I figured to move this call to the items registry method (since I figure some static reference to the Item class has happened). Sure enough, my error changed from null to NoSuchFieldException as shown in latest.log. I have indeed verified that Item#maxStackSize does exist. Once again, ./gradlew runClient works just fine and yields the desired behavior. My issue occurs on running the Minecraft launcher on my built jar (and yes, I verified that the versions of Forge being run are the same). I just came across ObfuscationHelper.setPrivateValue, so maybe I'll give that a try...
-
[1.15.2] Using Non-potion items as Potion Ingredients [Resolved]
izofar replied to izofar's topic in Modder Support
[FIXED] Silly me... ... when testing the code I last posted, I was attempting to place a stack of honey bottles instead of a single honey bottle... Otherwise, it works fine. Thank you to all who replied. -
[1.15.2] Using Non-potion items as Potion Ingredients [Resolved]
izofar replied to izofar's topic in Modder Support
I see, in switching the honey bottle to Items.IRON_INGOT, it seems to work fine. This is interesting since in net.minecraft.item.Items, I read: public static final Item field_226638_pX_ = register("honey_bottle", new HoneyBottleItem((new Item.Properties()) .containerItem(GLASS_BOTTLE) .food(Foods.field_226604_w_) .group(ItemGroup.FOOD) .maxStackSize(16))); Which appears to be the honey bottle. I will have to investigate this further, but this seemed to narrow down the issue, thank you! -
I'm not quite sure what you're trying to ask, but if you mean you are trying to install the Forge 1.15.2 client, and the .jar is opening to Internet Explorer, it sounds like you either don't have Java installed, or that you need to RightClick>Open With>Java TM
-
[1.15.2] How do I use Registries, Events, and Fluids.
izofar replied to KINØ's topic in Modder Support
Word of advice, it will take more than a week of modding/learning java to understand most of this stuff. The fluid concept you want to achieve isn't a very simple implementation. The best way to learn is through reading the source code to see how vanilla achieves things. This almost always requires some digging through packages, or reading forums to get led in the right direction. Regarding the packages you have drawn attention to, the vanilla code is made up of many interfaces and parent classes that act as blueprints, while the classes you are most likely interested in reading are WaterFluid and LavaFluid, as these seem to be the most specific. For example, in the WaterFluid class: @OnlyIn(Dist.CLIENT) public void animateTick(World worldIn, BlockPos pos, IFluidState state, Random random) { if (!state.isSource() && !state.get(FALLING)) { if (random.nextInt(64) == 0) { worldIn.playSound((double)pos.getX() + 0.5D, (double)pos.getY() + 0.5D, (double)pos.getZ() + 0.5D, SoundEvents.BLOCK_WATER_AMBIENT, SoundCategory.BLOCKS, random.nextFloat() * 0.25F + 0.75F, random.nextFloat() + 0.5F, false); } } else if (random.nextInt(10) == 0) { worldIn.addParticle(ParticleTypes.UNDERWATER, (double)pos.getX() + (double)random.nextFloat(), (double)pos.getY() + (double)random.nextFloat(), (double)pos.getZ() + (double)random.nextFloat(), 0.0D, 0.0D, 0.0D); } } You already get a sense that there are block states such as FALLING, that describes the movement/behavior of the water. Looking at how the class is set up: public abstract class WaterFluid extends FlowingFluid { public Fluid getFlowingFluid() { return Fluids.FLOWING_WATER; } public Fluid getStillFluid() { return Fluids.WATER; } public Item getFilledBucket() { return Items.WATER_BUCKET; } Any fluid you'd like to make must have these features. So, you notice that there is a class Fluids that seems to store all the types of fluids. Hence, you should look for a Forge registry that allows you register your own fluid to show up in the game. Hopefully this provides some direction, I personally haven't messed with fluids myself, but this is how I've tried to figure things out. Registries and Events I suggest checking out the net.minecraftforge.event package and poke around. An event is exactly what it sounds like. Something happens in the game. When you annotate your method with a @SubscribeEvent annotation, you signal to Forge that your method should run when something in the game happens. Which event depends on the Event parameter you give it. These events can be found in the aforementioned package. The class that contains this method (called an event handler) must be registered to the MinecraftForge.EVENT_BUS.register(...). An example of using under some condition you didn't want zombies to spawn. In otherwords, you wanted to cancel the event of a zombie spawning. You may have something like: @SubscribeEvent public static void onEntityJoinWorld(EntityJoinWorldEvent event){ if(event.getEntity() instanceof ZombieEntity && condition) event.setCanceled(true); } And behold, during the game, given that condition is true, zombie spawns will be canceled faster than Kevin Hart was for his Oscar speech. Registries are Forge's way of "injecting" your content into the game. Think of it like a list of things to be included into the game. The way you add to this list is to register an item. In your console, you may see something of the following: [19:09:01] [Server-Worker-6/DEBUG] [ne.mi.re.ForgeRegistry/REGISTRYDUMP]: Registry Name: minecraft:block Entry: 0, minecraft:air, Block{minecraft:air} Entry: 1, minecraft:stone, Block{minecraft:stone} Entry: 2, minecraft:granite, Block{minecraft:granite} Entry: 3, minecraft:polished_granite, Block{minecraft:polished_granite} Entry: 4, minecraft:diorite, Block{minecraft:diorite} Entry: 5, minecraft:polished_diorite, Block{minecraft:polished_diorite} ... Here, Forge is registering the blocks. If you don't register your items, they won't be in the game. Hope this provides some guidance. I would suggest reading the Forge Documentation EVEN THOUGH MANY OF THE SPECIFICS ARE OUTDATED (keep in mind, the dudes are doing this for free). Many of the concepts are still relevant, like Registries and Events. -
[1.15.2] Using Non-potion items as Potion Ingredients [Resolved]
izofar replied to izofar's topic in Modder Support
Thanks! This seems to be supposed to do what I want, though when I call BrewingRecipeRegistry.addRecipe( Ingredient.fromItems(Items.field_226638_pX_), //Honey Bottle Item (retrived from source) Ingredient.fromItems(Items.FERMENTED_SPIDER_EYE), PotionUtils.addPotionToItemStack(new ItemStack(Items.SPLASH_POTION), Potions.WEAKNESS) in-game, I still can't place honey bottles in the potion slot. Could this have to do with honey bottles not inheriting from minecraft.item.PotionItem? To make sure, I have indeed checked that the method containing the above code is called with the rest of the registers (And with a debug output that shows up in the console). -
Currently, I am using reflection to call Potions.addMix I want to be able to use the honey bottle as a base potion like I would water, awkward potions, etc. However, the HoneyBottleItem does not inherit from Potion. It seems that registered Potions have an item automatically generated for them, which I don't want because honey bottles already have an associated item. How can I, given a registered Potion HONEY, override it's item to be the honey bottle, so that I may use Potions.addMix(HONEY, ...)? Or, is there a better way to achieve this? Edit: While I considered a custom class that extends the necessary superclasses, the BeehiveBlock class has a native method that returns the HoneyBottleItem during the appropriate event. This would cause trouble for me for I would have to create a custom beehive class then modify world-gen. I hope there's another way.