Jump to content

Forge hooks for Structure loot.


fabricator77
 Share

Recommended Posts

I've looked at the Forge hooks for Dungeon loot, and would like something like it for the various other map generated loot chests. Yes there are a lot of them. Basically I want to add items from Forge mods to chests, which is easy without Forge until Bukkit is involved.

 

The idea I have is to modify StructureComponent.class so the StructurePieceTreasure[] part is removed/ignored, and a class parameter used instead to determine what set of loot to generate (eg ComponentStrongholdLibrary.class). This way when Mojang add yet another structure with chest loots in it, the API doesn't need yet more changes.

 

I don't mind doing most/all of the code changes, just want to hear what others think of the implementation. Also should I go with 1.2.5 or is it likely to be a wasted effort ?

Link to comment
Share on other sites

Dont make anything for 1.2.5 anymore. As as soon as major mods update, nobody will use 1.2.5 anymore

As for the the Structure loot, I have planned for a while to expand this to any world gen chest loot, but that is a future feature, we are currently in the 'fix bugs' stage of Forge, not the 'Add new things'

I do Forge for free, however the servers to run it arn't free, so anything is appreciated.
Patreon: http://www.patreon.com/lexmanos
Paypal: http://paypal.me/LexManos

BitCoin: 1Q8rWvUNMM2T1ZfDaFeeYQyVXtYoeT6tTn

Link to comment
Share on other sites

I've added a few lines of code to StructureComponent so it can determine its called class, eg: ComponentMineshaftCorridor.class and use that name to store each set of loot. This way any structure created gets its own unique loot set, even ones added by modders. Still need to write a data structure to store it all, then look at the pull request.

 

StructureComponent.class contains:

func_74879_a

Loot chests

 

func_74869_a

Dispensers

 

So I might at well tap into the Dispenser code, so mean people can put fire arrows in them or something.

Link to comment
Share on other sites

  • 5 weeks later...
  • 3 weeks later...

Got enchanted dungeon loot thanks to the recent changes in Forge (4.2.x)

Thanks for that LexManos!

I had to brush up on sub-classes and such to get it going but I'll put what I found here (if that's ok)

 

The override class:

 

 

package net.minecraft.src;

import net.minecraft.client.Minecraft;

import net.minecraftforge.common.DungeonHooks;

import net.minecraftforge.common.DungeonHooks.DungeonLoot;

import net.minecraft.src.EnchantmentHelper;

import net.minecraft.src.EnchantmentData;

import java.util.*;

 

public class enchantedLoot extends DungeonHooks.DungeonLoot

{

        private ItemStack itemStack;

        private int minCount = 1;

        private int maxCount = 1;

        private int minEnchantLevel = 1;

        private int maxEnchantLevel = 1;

        private int enchantChance = 0;

 

public enchantedLoot(ItemStack item, int weight, int min, int max, int ench)

{

super(weight, item, 1, 1);

this.itemStack = item;

minEnchantLevel = min;

maxEnchantLevel = max;

if (max < min)

{

maxEnchantLevel = min;

}

enchantChance = ench;

 

// Enchantable items should never be stackable

minCount = 1;

maxCount = 1;

}

 

public ItemStack generateStack(Random rand)

{

ItemStack ret = this.itemStack.copy();

 

ret.stackSize = minCount + (rand.nextInt(maxCount - minCount + 1));

if (enchantChance > 0)

{

int i = rand.nextInt(100);

if (i < enchantChance)

{

int level = minEnchantLevel + (rand.nextInt(maxEnchantLevel - minEnchantLevel + 1));

ret.stackSize = 1;

List list = EnchantmentHelper.buildEnchantmentList(rand, ret, level);

if(list != null)

{

EnchantmentData enchantmentdata;

for(Iterator iterator = list.iterator(); iterator.hasNext(); ret.addEnchantment(enchantmentdata.enchantmentobj, enchantmentdata.enchantmentLevel))

{

enchantmentdata = (EnchantmentData)iterator.next();

}

}

}

}

            return ret;

        }

}

 

 

 

Then to reference it, add a method to your code:

 

 

private void addEnchantedLoot(ItemStack item, int weight, int min, int max, int ench)

{

DungeonHooks newLoot = new DungeonHooks();

newLoot.addDungeonLoot((DungeonHooks.DungeonLoot)new enchantedLoot(item, weight, min, max, ench));

}

 

 

 

Then if you want to add, for instance, randomly enchanted bows, you could use:

addEnchantedLoot(new ItemStack(Item.bow),100, 1,30, 10);

where 100 is the weight (chance it will be in loot)

1 is the minimum enchantment level

30 is the maximum enchantment level

10 is the percent chance the item will have any enchantment

Link to comment
Share on other sites

Wow copy paste up the wazoo, please go learn some java code structure.

But ya.. Enchanting stuff or doing whatever you want is possible now.

I do Forge for free, however the servers to run it arn't free, so anything is appreciated.
Patreon: http://www.patreon.com/lexmanos
Paypal: http://paypal.me/LexManos

BitCoin: 1Q8rWvUNMM2T1ZfDaFeeYQyVXtYoeT6tTn

Link to comment
Share on other sites

  • 3 months later...

::)

Yeah yeah. Copy-paste heaven and structure sucks. It's been like 10 years since I had a college course in Java. I'll learn better coding skills if/when I get a full time job writing code.

The main reason for this reply is because with the deprication of DungeonHooks, this all changes. The only way I can think of doing the same thing now is to either add one of every possible enchantment of every possible tool/armor/weapon or to create some kind of new fake item which replaces itself with an enchanted item when created. Not even sure if that would work.

So with the current structure, is it still possible to add dungeon loot that will have a random enchantment applied when generated? If so, any hints?

Link to comment
Share on other sites

Guest
This topic is now closed to further replies.
 Share



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • I have a custom recipe that uses JSON to work properly. And everything works right except I cant seem to figure out how to find the stack count for each ingredient of my recipe.   Recipe class: public class AlloyKilnRecipe implements Recipe<SimpleContainer> { private final ResourceLocation id; private final ItemStack output; private final NonNullList<Ingredient> ingredients; public AlloyKilnRecipe(ResourceLocation id, ItemStack output, NonNullList<Ingredient> ingredients) { this.id = id; this.output = output; this.ingredients = ingredients; } @Override public boolean matches(SimpleContainer pContainer, Level pLevel) { if (pLevel.isClientSide()) return false; return (ingredients.get(0).test(pContainer.getItem(0)) && ingredients.get(1).test(pContainer.getItem(1))) || (ingredients.get(0).test(pContainer.getItem(1)) && ingredients.get(1).test(pContainer.getItem(0))); } public int getIngAmnt(int index) { ItemStack[] stacks = ingredients.get(index).getItems(); for (ItemStack stack : stacks) { return stack.getCount(); } return 0; } @Override public NonNullList<Ingredient> getIngredients() { return ingredients; } @Override public ItemStack assemble(SimpleContainer pContainer) { return output; } @Override public boolean canCraftInDimensions(int pWidth, int pHeight) { return true; } @Override public ItemStack getResultItem() { return output.copy(); } @Override public ResourceLocation getId() { return id; } @Override public RecipeSerializer<?> getSerializer() { return Serializer.INSTANCE; } @Override public RecipeType<?> getType() { return Type.INSTANCE; } public static class Type implements RecipeType<AlloyKilnRecipe> { private Type() {} public static final Type INSTANCE = new Type(); public static final String ID = "alloy_kiln_recipe"; } public static class Serializer implements RecipeSerializer<AlloyKilnRecipe> { public static final Serializer INSTANCE = new Serializer(); public static final ResourceLocation ID = new ResourceLocation(FF.MOD_ID, "alloy_kiln_recipe"); @Override public AlloyKilnRecipe fromJson(ResourceLocation pRecipeId, JsonObject pSerializedRecipe) { ItemStack output = ShapedRecipe.itemStackFromJson(GsonHelper.getAsJsonObject(pSerializedRecipe, "output")); JsonArray ingredients = GsonHelper.getAsJsonArray(pSerializedRecipe, "ingredients"); NonNullList<Ingredient> inputs = NonNullList.withSize(2, Ingredient.EMPTY); for (int i = 0; i < ingredients.size(); i++) { inputs.set(i, Ingredient.fromJson(ingredients.get(i))); } return new AlloyKilnRecipe(pRecipeId, output, inputs); } @Override public @Nullable AlloyKilnRecipe fromNetwork(ResourceLocation pRecipeId, FriendlyByteBuf pBuffer) { NonNullList<Ingredient> inputs = NonNullList.withSize(pBuffer.readInt(), Ingredient.EMPTY); for (int i = 0; i < inputs.size(); i++) { inputs.set(i, Ingredient.fromNetwork(pBuffer)); } ItemStack output = pBuffer.readItem(); return new AlloyKilnRecipe(pRecipeId, output, inputs); } @Override public void toNetwork(FriendlyByteBuf pBuffer, AlloyKilnRecipe pRecipe) { pBuffer.writeInt(pRecipe.getIngredients().size()); for (Ingredient ing : pRecipe.getIngredients()) { ing.toNetwork(pBuffer); } pBuffer.writeItemStack(pRecipe.getResultItem(), false); } } } And here is my recipe.json { "type": "forgedfactory:alloy_kiln_recipe", "ingredients": [ { "item": "minecraft:iron_ingot", "count": 3 }, { "item": "minecraft:gold_ingot" } ], "output": { "item": "minecraft:diamond", "count": 3 } } Could someone tell me what I would have to do? The getIngAmount method just returns 1 even though I have a count defined for the iron ingots.
    • forge installer version 43.1.7 for 1.19.2 won't download the jar file, only the json 
    • Stop bumping your post. This sounds like a issue with your install. Try deleting your .minecraft folder and re-installing the launcher. Beyond that it's not something we control. As we don't control the launcher.
    • Can someone help me with this
  • Topics

×
×
  • Create New...

Important Information

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