From 3f9641b86136c5d744c44662d76bd20bdb92c62d Mon Sep 17 00:00:00 2001 From: koolkrafter5 Date: Sat, 18 Jan 2025 02:04:42 -0500 Subject: [PATCH] Make meteor reagents completely configurable and add some new options to their functionality. (#63) Co-authored-by: Martin Robertz --- .../AlchemicalWizardry.java | 4 +- .../client/nei/NEIMeteorRecipeHandler.java | 27 ++- .../entity/projectile/EntityMeteor.java | 47 ++-- .../rituals/RitualEffectSummonMeteor.java | 19 +- .../common/summoning/meteor/Meteor.java | 15 +- .../summoning/meteor/MeteorParadigm.java | 176 ++++++++------ .../meteor/MeteorParadigmComponent.java | 31 ++- .../summoning/meteor/MeteorReagent.java | 16 ++ .../meteor/MeteorReagentRegistry.java | 221 ++++++++++++++++++ .../summoning/meteor/MeteorRegistry.java | 12 +- .../common/tweaker/FallingTower.java | 3 +- .../assets/alchemicalwizardry/lang/en_US.lang | 1 + 12 files changed, 436 insertions(+), 136 deletions(-) create mode 100644 src/main/java/WayofTime/alchemicalWizardry/common/summoning/meteor/MeteorReagent.java create mode 100644 src/main/java/WayofTime/alchemicalWizardry/common/summoning/meteor/MeteorReagentRegistry.java diff --git a/src/main/java/WayofTime/alchemicalWizardry/AlchemicalWizardry.java b/src/main/java/WayofTime/alchemicalWizardry/AlchemicalWizardry.java index 6015dcb78..430e5ef3b 100644 --- a/src/main/java/WayofTime/alchemicalWizardry/AlchemicalWizardry.java +++ b/src/main/java/WayofTime/alchemicalWizardry/AlchemicalWizardry.java @@ -251,6 +251,7 @@ import WayofTime.alchemicalWizardry.common.spell.simple.SpellWindGust; import WayofTime.alchemicalWizardry.common.summoning.SummoningHelperAW; import WayofTime.alchemicalWizardry.common.summoning.meteor.Meteor; +import WayofTime.alchemicalWizardry.common.summoning.meteor.MeteorReagentRegistry; import WayofTime.alchemicalWizardry.common.tileEntity.TEAlchemicCalcinator; import WayofTime.alchemicalWizardry.common.tileEntity.TEAltar; import WayofTime.alchemicalWizardry.common.tileEntity.TEBellJar; @@ -3321,6 +3322,7 @@ public void postInit(FMLPostInitializationEvent event) { DemonVillageLootRegistry.init(); Meteor.loadConfig(); + MeteorReagentRegistry.loadConfig(); this.initCompressionHandlers(); } @@ -4504,7 +4506,7 @@ public String[] getGeneratedStrings(String itemName) { return strings; } - @Mod.EventHandler + @EventHandler public void initCommands(FMLServerStartingEvent event) { event.registerServerCommand(new CommandBloodMagic()); } diff --git a/src/main/java/WayofTime/alchemicalWizardry/client/nei/NEIMeteorRecipeHandler.java b/src/main/java/WayofTime/alchemicalWizardry/client/nei/NEIMeteorRecipeHandler.java index 536f16029..caacb45a4 100644 --- a/src/main/java/WayofTime/alchemicalWizardry/client/nei/NEIMeteorRecipeHandler.java +++ b/src/main/java/WayofTime/alchemicalWizardry/client/nei/NEIMeteorRecipeHandler.java @@ -16,6 +16,9 @@ import org.lwjgl.opengl.GL11; +import com.google.common.base.Joiner; + +import WayofTime.alchemicalWizardry.api.alchemy.energy.Reagent; import WayofTime.alchemicalWizardry.common.summoning.meteor.MeteorParadigm; import WayofTime.alchemicalWizardry.common.summoning.meteor.MeteorParadigmComponent; import WayofTime.alchemicalWizardry.common.summoning.meteor.MeteorRegistry; @@ -31,7 +34,6 @@ public class CachedMeteorRecipe extends CachedRecipe { private final List input = new ArrayList<>(); private final List outputs = new ArrayList<>(); - private final List filler = new ArrayList<>(); private final int cost; private final int radius; private Point focus; @@ -50,7 +52,7 @@ public CachedMeteorRecipe(MeteorParadigm meteor, ItemStack focusStack) { float componentRatio = 1 - fillerRatio; for (MeteorParadigmComponent component : sortedComponents) { - ItemStack stack = component.getValidBlockParadigm(); + ItemStack stack = component.getBlock(); int xPos = 3 + 18 * col; int yPos = 37 + 18 * row; @@ -58,6 +60,9 @@ public CachedMeteorRecipe(MeteorParadigm meteor, ItemStack focusStack) { float chance = component.getWeight() / totalComponentWeight * componentRatio; tooltips.add(I18n.format("nei.recipe.meteor.chance", getFormattedChance(chance))); tooltips.add(I18n.format("nei.recipe.meteor.amount", getEstimatedAmount(chance, meteor.radius))); + if (!component.getRequiredReagents().isEmpty()) { + tooltips.add(I18n.format("nei.recipe.meteor.reagent", getReagentStrings(component))); + } this.outputs.add(new TooltipStack(stack, xPos, yPos, tooltips)); col++; @@ -82,7 +87,7 @@ public CachedMeteorRecipe(MeteorParadigm meteor, ItemStack focusStack) { float totalFillerWeight = meteor.getTotalListWeight(meteor.fillerList); for (MeteorParadigmComponent filler : sortedFiller) { - ItemStack stack = filler.getValidBlockParadigm(); + ItemStack stack = filler.getBlock(); int xPos = 3 + 18 * col; int yPos = 37 + 18 * row; @@ -91,6 +96,9 @@ public CachedMeteorRecipe(MeteorParadigm meteor, ItemStack focusStack) { tooltips.add(I18n.format("nei.recipe.meteor.chance", getFormattedChance(chance))); tooltips.add(I18n.format("nei.recipe.meteor.amount", getEstimatedAmount(chance, meteor.radius))); tooltips.add(I18n.format("nei.recipe.meteor.filler")); + if (!filler.getRequiredReagents().isEmpty()) { + tooltips.add(I18n.format("nei.recipe.meteor.reagent", getReagentStrings(filler))); + } this.outputs.add(new TooltipStack(stack, xPos, yPos, tooltips)); col++; @@ -109,6 +117,15 @@ public CachedMeteorRecipe(MeteorParadigm meteor, ItemStack focusStack) { this.cost = meteor.cost; } + private String getReagentStrings(MeteorParadigmComponent component) { + ArrayList reagents = component.getRequiredReagents(); + ArrayList reagentNames = new ArrayList<>(); + for (Reagent r : reagents) { + reagentNames.add(r.name); + } + return Joiner.on(", ").join(reagentNames); + } + @Override public List getIngredients() { return this.input; @@ -152,10 +169,10 @@ public void loadCraftingRecipes(String outputId, Object... results) { @Override public void loadCraftingRecipes(ItemStack result) { for (MeteorParadigm meteor : getSortedMeteors()) { - if (meteor.componentList.stream().anyMatch(m -> matchItem(result, m.getValidBlockParadigm()))) { + if (meteor.componentList.stream().anyMatch(m -> matchItem(result, m.getBlock()))) { arecipes.add(new CachedMeteorRecipe(meteor, result)); } - if (meteor.fillerList.stream().anyMatch(m -> matchItem(result, m.getValidBlockParadigm()))) { + if (meteor.fillerList.stream().anyMatch(m -> matchItem(result, m.getBlock()))) { arecipes.add(new CachedMeteorRecipe(meteor, result)); } } diff --git a/src/main/java/WayofTime/alchemicalWizardry/common/entity/projectile/EntityMeteor.java b/src/main/java/WayofTime/alchemicalWizardry/common/entity/projectile/EntityMeteor.java index 72c9759d4..27948564c 100644 --- a/src/main/java/WayofTime/alchemicalWizardry/common/entity/projectile/EntityMeteor.java +++ b/src/main/java/WayofTime/alchemicalWizardry/common/entity/projectile/EntityMeteor.java @@ -1,22 +1,22 @@ package WayofTime.alchemicalWizardry.common.entity.projectile; +import java.util.ArrayList; + import net.minecraft.entity.Entity; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.DamageSource; import net.minecraft.util.MovingObjectPosition; import net.minecraft.world.World; +import WayofTime.alchemicalWizardry.api.alchemy.energy.Reagent; +import WayofTime.alchemicalWizardry.api.alchemy.energy.ReagentRegistry; import WayofTime.alchemicalWizardry.common.summoning.meteor.MeteorRegistry; public class EntityMeteor extends EnergyBlastProjectile { private int meteorID; - public boolean hasTerrae; - public boolean hasOrbisTerrae; - public boolean hasCrystallos; - public boolean hasIncendium; - public boolean hasTennebrae; + public ArrayList reagentList = new ArrayList<>(); public EntityMeteor(World par1World) { super(par1World); @@ -33,11 +33,11 @@ public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { super.writeEntityToNBT(par1NBTTagCompound); par1NBTTagCompound.setInteger("meteorID", meteorID); - par1NBTTagCompound.setBoolean("hasTerrae", hasTerrae); - par1NBTTagCompound.setBoolean("hasOrbisTerrae", hasOrbisTerrae); - par1NBTTagCompound.setBoolean("hasCrystallos", hasCrystallos); - par1NBTTagCompound.setBoolean("hasIncendium", hasIncendium); - par1NBTTagCompound.setBoolean("hasTennebrae", hasTennebrae); + + for (Reagent r : reagentList) { + par1NBTTagCompound.setBoolean("reagent." + r.name, true); + } + } @Override @@ -45,11 +45,11 @@ public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { super.readEntityFromNBT(par1NBTTagCompound); meteorID = par1NBTTagCompound.getInteger("meteorID"); - hasTerrae = par1NBTTagCompound.getBoolean("hasTerrae"); - hasOrbisTerrae = par1NBTTagCompound.getBoolean("hasOrbisTerrae"); - hasIncendium = par1NBTTagCompound.getBoolean("hasIncendium"); - hasCrystallos = par1NBTTagCompound.getBoolean("hasCrystallos"); - hasTennebrae = par1NBTTagCompound.getBoolean("hasTennebrae"); + for (Reagent r : ReagentRegistry.reagentList.values()) { + if (par1NBTTagCompound.getBoolean("reagent." + r.name)) { + reagentList.add(r); + } + } } @Override @@ -66,13 +66,7 @@ public void onImpact(MovingObjectPosition mop) { if (mop.typeOfHit == MovingObjectPosition.MovingObjectType.ENTITY && mop.entityHit != null) { this.onImpact(mop.entityHit); } else if (mop.typeOfHit == MovingObjectPosition.MovingObjectType.BLOCK) { - MeteorRegistry.createMeteorImpact( - worldObj, - mop.blockX, - mop.blockY, - mop.blockZ, - this.meteorID, - new boolean[] { hasTerrae, hasOrbisTerrae, hasCrystallos, hasIncendium, hasTennebrae }); + MeteorRegistry.createMeteorImpact(worldObj, mop.blockX, mop.blockY, mop.blockZ, this.meteorID, reagentList); } this.setDead(); @@ -80,13 +74,8 @@ public void onImpact(MovingObjectPosition mop) { @Override public void onImpact(Entity mop) { - MeteorRegistry.createMeteorImpact( - worldObj, - (int) this.posX, - (int) this.posY, - (int) this.posZ, - meteorID, - new boolean[] { hasTerrae, hasOrbisTerrae, hasCrystallos, hasIncendium, hasTennebrae }); + MeteorRegistry + .createMeteorImpact(worldObj, (int) this.posX, (int) this.posY, (int) this.posZ, meteorID, reagentList); this.setDead(); } diff --git a/src/main/java/WayofTime/alchemicalWizardry/common/rituals/RitualEffectSummonMeteor.java b/src/main/java/WayofTime/alchemicalWizardry/common/rituals/RitualEffectSummonMeteor.java index 2d5138b97..ba888b3a6 100644 --- a/src/main/java/WayofTime/alchemicalWizardry/common/rituals/RitualEffectSummonMeteor.java +++ b/src/main/java/WayofTime/alchemicalWizardry/common/rituals/RitualEffectSummonMeteor.java @@ -11,6 +11,7 @@ import net.minecraft.world.World; import WayofTime.alchemicalWizardry.AlchemicalWizardry; +import WayofTime.alchemicalWizardry.api.alchemy.energy.Reagent; import WayofTime.alchemicalWizardry.api.alchemy.energy.ReagentRegistry; import WayofTime.alchemicalWizardry.api.rituals.IMasterRitualStone; import WayofTime.alchemicalWizardry.api.rituals.RitualComponent; @@ -56,20 +57,10 @@ public void performEffect(IMasterRitualStone ritualStone) { EntityMeteor meteor = new EntityMeteor(world, x + 0.5f, 257, z + 0.5f, meteorID); meteor.motionY = -1.0f; - if (this.canDrainReagent(ritualStone, ReagentRegistry.terraeReagent, 1000, true)) { - meteor.hasTerrae = true; - } - if (this.canDrainReagent(ritualStone, ReagentRegistry.orbisTerraeReagent, 1000, true)) { - meteor.hasOrbisTerrae = true; - } - if (this.canDrainReagent(ritualStone, ReagentRegistry.crystallosReagent, 1000, true)) { - meteor.hasCrystallos = true; - } - if (this.canDrainReagent(ritualStone, ReagentRegistry.incendiumReagent, 1000, true)) { - meteor.hasIncendium = true; - } - if (this.canDrainReagent(ritualStone, ReagentRegistry.tenebraeReagent, 1000, true)) { - meteor.hasTennebrae = true; + for (Reagent r : ReagentRegistry.reagentList.values()) { + if (this.canDrainReagent(ritualStone, r, 1000, true)) { + meteor.reagentList.add(r); + } } entityItem.setDead(); diff --git a/src/main/java/WayofTime/alchemicalWizardry/common/summoning/meteor/Meteor.java b/src/main/java/WayofTime/alchemicalWizardry/common/summoning/meteor/Meteor.java index e251acf85..6f298e0e2 100644 --- a/src/main/java/WayofTime/alchemicalWizardry/common/summoning/meteor/Meteor.java +++ b/src/main/java/WayofTime/alchemicalWizardry/common/summoning/meteor/Meteor.java @@ -16,12 +16,12 @@ public class Meteor { - private String[] ores; - private int radius; - private int cost; - private String focusModId; - private String focusName; - private int focusMeta; + public String[] ores; + public int radius; + public int cost; + public String focusModId; + public String focusName; + public int focusMeta; private String[] filler; private int fillerChance; @@ -32,6 +32,9 @@ public static void loadConfig() { if (files != null) { try { for (File f : files) { + if (f.isDirectory()) { + continue; + } BufferedReader br = new BufferedReader(new FileReader(f)); Meteor m = gson.fromJson(br, Meteor.class); MeteorRegistry.registerMeteorParadigm( diff --git a/src/main/java/WayofTime/alchemicalWizardry/common/summoning/meteor/MeteorParadigm.java b/src/main/java/WayofTime/alchemicalWizardry/common/summoning/meteor/MeteorParadigm.java index d837f2791..dbe9178a3 100644 --- a/src/main/java/WayofTime/alchemicalWizardry/common/summoning/meteor/MeteorParadigm.java +++ b/src/main/java/WayofTime/alchemicalWizardry/common/summoning/meteor/MeteorParadigm.java @@ -1,12 +1,13 @@ package WayofTime.alchemicalWizardry.common.summoning.meteor; +import static WayofTime.alchemicalWizardry.common.summoning.meteor.MeteorReagentRegistry.getFillerList; + import java.util.ArrayList; import java.util.List; import java.util.Random; import java.util.regex.Matcher; import java.util.regex.Pattern; -import net.minecraft.init.Blocks; import net.minecraft.item.ItemBlock; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; @@ -14,6 +15,8 @@ import net.minecraftforge.oredict.OreDictionary; import WayofTime.alchemicalWizardry.AlchemicalWizardry; +import WayofTime.alchemicalWizardry.api.alchemy.energy.Reagent; +import WayofTime.alchemicalWizardry.api.alchemy.energy.ReagentRegistry; import cpw.mods.fml.common.Optional; import cpw.mods.fml.common.registry.GameRegistry; import gregtech.common.blocks.TileEntityOres; @@ -29,10 +32,6 @@ public class MeteorParadigm { public static Random rand = new Random(); - public MeteorParadigm(ItemStack focusStack, int radius, int cost) { - new MeteorParadigm(focusStack, radius, cost, 0); - } - public MeteorParadigm(ItemStack focusStack, int radius, int cost, int fillerChance) { this.focusStack = focusStack; this.radius = radius; @@ -40,10 +39,10 @@ public MeteorParadigm(ItemStack focusStack, int radius, int cost, int fillerChan this.fillerChance = fillerChance; } - // modId:itemName:meta:weight - private static final Pattern itemNamePattern = Pattern.compile("(.*):(.*):(\\d+):(\\d+)"); - // OREDICT:oreDictName:weight - private static final Pattern oredictPattern = Pattern.compile("OREDICT:(.*):(\\d+)"); + // modId:itemName:meta:weight(:reagent1, reagent2, ... optional) + private static final Pattern itemNamePattern = Pattern.compile("(.*):(.*):(\\d+):(\\d+)(:.*)?"); + // OREDICT:oreDictName:weight(:reagent1, reagent2, ... optional) + private static final Pattern oredictPattern = Pattern.compile("OREDICT:(.*):(\\d+)(:.*)?"); public static List parseStringArray(String[] blockArray) { List addList = new ArrayList<>(); @@ -57,49 +56,60 @@ public static List parseStringArray(String[] blockArray String itemName = matcher.group(2); int meta = Integer.parseInt(matcher.group(3)); int weight = Integer.parseInt(matcher.group(4)); + String reagent = matcher.group(5); + + ArrayList reagentList = getReagents(reagent, blockName); ItemStack stack = GameRegistry.findItemStack(modID, itemName, 1); if (stack != null && stack.getItem() instanceof ItemBlock) { stack.setItemDamage(meta); - addList.add(new MeteorParadigmComponent(stack, weight)); + addList.add(new MeteorParadigmComponent(stack, weight, reagentList)); success = true; } } else if ((matcher = oredictPattern.matcher(blockName)).matches()) { String oreDict = matcher.group(1); int weight = Integer.parseInt(matcher.group(2)); + String reagent = matcher.group(3); - List list = OreDictionary.getOres(oreDict); - for (ItemStack stack : list) { - if (stack != null && stack.getItem() instanceof ItemBlock) { - addList.add(new MeteorParadigmComponent(stack, weight)); - success = true; - break; - } - } - - } else { - // Legacy config - String oreDict = blockName; - int weight = Integer.parseInt(blockArray[++i]); + ArrayList reagentList = getReagents(reagent, blockName); List list = OreDictionary.getOres(oreDict); for (ItemStack stack : list) { if (stack != null && stack.getItem() instanceof ItemBlock) { - addList.add(new MeteorParadigmComponent(stack, weight)); + addList.add(new MeteorParadigmComponent(stack, weight, reagentList)); success = true; break; } } + } if (!success) { - AlchemicalWizardry.logger.warn("Unable to add Meteor Paradigm \"" + blockName + "\""); + AlchemicalWizardry.logger.warn("Unable to add Meteor Paradigm \"{}\"", blockName); + AlchemicalWizardry.logger.warn( + "Valid formats are \"modId:itemName:meta:weight(:reagent1, reagent2, ... optional)\" and \"OREDICT:oreDictName:weight(:reagent1, reagent2, ... optional)\"."); } } return addList; } + private static ArrayList getReagents(String reagent, String blockName) { + ArrayList reagentList = new ArrayList<>(); + if (reagent != null) { + String[] reagents = reagent.substring(1).split(", ?"); + for (String str : reagents) { + Reagent r = ReagentRegistry.getReagentForKey(str); + if (r == null) { + AlchemicalWizardry.logger.warn("Unable to add reagent \"{}\" for {}.", str, blockName); + continue; + } + reagentList.add(r); + } + } + return reagentList; + } + public int getTotalListWeight(List blockList) { int totalWeight = 0; for (MeteorParadigmComponent mpc : blockList) { @@ -108,62 +118,24 @@ public int getTotalListWeight(List blockList) { return totalWeight; } - public void createMeteorImpact(World world, int x, int y, int z, boolean[] flags) { - boolean hasTerrae = false; - boolean hasOrbisTerrae = false; - boolean hasCrystallos = false; - boolean hasIncendium = false; - boolean hasTennebrae = false; - - if (flags != null && flags.length >= 5) { - hasTerrae = flags[0]; - hasOrbisTerrae = flags[1]; - hasCrystallos = flags[2]; - hasIncendium = flags[3]; - hasTennebrae = flags[4]; - } + public void createMeteorImpact(World world, int x, int y, int z, List reagents) { + int radius = getNewRadius(this.radius, reagents); + int fillerChance = getNewFillerChance(this.fillerChance, reagents); - int newRadius = radius; - int fillerChance = this.fillerChance; - if (hasOrbisTerrae) { - newRadius += 2; - fillerChance *= 1.12; - } else if (hasTerrae) { - newRadius += 1; - fillerChance *= 1.06; - } - if (fillerChance > 100) { - fillerChance = 100; + if (MeteorReagentRegistry.doExplosions(reagents)) { + world.createExplosion(null, x, y, z, radius * 4, MeteorReagentRegistry.doMeteorsDestroyBlocks(reagents)); } - world.createExplosion(null, x, y, z, newRadius * 4, AlchemicalWizardry.doMeteorsDestroyBlocks); - - List fillerList; - - if (hasCrystallos || hasIncendium || hasTennebrae) { - fillerList = new ArrayList<>(); - if (hasCrystallos) { - fillerList.add(new MeteorParadigmComponent(new ItemStack(Blocks.ice), 180)); // 180 = 2^2 * 3^2 * 5 - } - if (hasIncendium) { - fillerList.add(new MeteorParadigmComponent(new ItemStack(Blocks.netherrack), 60)); - fillerList.add(new MeteorParadigmComponent(new ItemStack(Blocks.soul_sand), 60)); - fillerList.add(new MeteorParadigmComponent(new ItemStack(Blocks.glowstone), 60)); - } - if (hasTennebrae) { - fillerList.add(new MeteorParadigmComponent(new ItemStack(Blocks.obsidian), 180)); - } - } else { - fillerList = this.fillerList; - } + List componentList = removeBlocksMissingRequiredReagents(this.componentList, reagents); + List fillerList = getNewFillerList(this.fillerList, reagents); int totalComponentWeight = getTotalListWeight(componentList); int totalFillerWeight = getTotalListWeight(fillerList); - for (int i = -newRadius; i <= newRadius; i++) { - for (int j = -newRadius; j <= newRadius; j++) { - for (int k = -newRadius; k <= newRadius; k++) { - if (i * i + j * j + k * k >= (newRadius + 0.50f) * (newRadius + 0.50f)) { + for (int i = -radius; i <= radius; i++) { + for (int j = -radius; j <= radius; j++) { + for (int k = -radius; k <= radius; k++) { + if (i * i + j * j + k * k >= (radius + 0.50f) * (radius + 0.50f)) { continue; } @@ -181,6 +153,60 @@ public void createMeteorImpact(World world, int x, int y, int z, boolean[] flags } } + private int getNewRadius(int radius, List reagents) { + radius += MeteorReagentRegistry.getLargestRadiusIncrease(reagents); + radius += MeteorReagentRegistry.getLargestRadiusDecrease(reagents); + return Math.max(radius, 1); + } + + private int getNewFillerChance(int fillerChance, List reagents) { + // Don't add filler to meteors with none + if (fillerChance <= 0) { + return 0; + } + + int increase = MeteorReagentRegistry.getLargestFillerChanceIncrease(reagents); + int decrease = MeteorReagentRegistry.getLargestFillerChanceDecrease(reagents); + // Avoid division by zero + if (decrease == -100) { + return 0; + } + + fillerChance += MeteorReagentRegistry.getLargestRawFillerChanceIncrease(reagents); + fillerChance += MeteorReagentRegistry.getLargestRawFillerChanceDecrease(reagents); + if (increase > 0) { + fillerChance = (fillerChance + increase) * 100 / (100 + increase); + } else if (decrease < 0) { + fillerChance = (fillerChance + decrease) * 100 / (100 + decrease); + } + return Math.max(0, Math.min(fillerChance, 100)); + } + + private List getNewFillerList(List fillerList, + List reagents) { + List reagentFillers = getFillerList(reagents); + reagentFillers = removeBlocksMissingRequiredReagents(reagentFillers, reagents); + if (!reagentFillers.isEmpty()) { + return reagentFillers; + } + List newFillers = removeBlocksMissingRequiredReagents(fillerList, reagents); + if (newFillers.isEmpty()) { // Use the default if every filler requires a reagent + newFillers.add(MeteorRegistry.getDefaultMeteorParadigmComponent()); + } + return newFillers; + } + + private List removeBlocksMissingRequiredReagents(List blockList, + List reagents) { + ArrayList newList = new ArrayList<>(); + for (MeteorParadigmComponent mpc : blockList) { + if (mpc.checkForReagent(reagents)) { + newList.add(mpc); + } + } + return newList; + } + private void setMeteorBlock(int x, int y, int z, World world, List blockList, int totalListWeight) { int randNum = world.rand.nextInt(totalListWeight); @@ -188,7 +214,7 @@ private void setMeteorBlock(int x, int y, int z, World world, List reagent = new ArrayList<>(); public MeteorParadigmComponent(ItemStack stack, int weight) { + this(stack, weight, new ArrayList<>()); + } + + public MeteorParadigmComponent(ItemStack stack, int weight, ArrayList reagent) { this.itemStack = stack; this.weight = weight; + this.reagent = reagent; } public int getWeight() { return this.weight; } - public ItemStack getValidBlockParadigm() { + public ItemStack getBlock() { return itemStack; } + + public ArrayList getRequiredReagents() { + return reagent; + } + + public boolean checkForReagent(List reagentList) { + if (reagent.isEmpty()) { + return true; + } + for (Reagent r1 : reagentList) { + for (Reagent r2 : reagent) { + if (r1.equals(r2)) { + return true; + } + } + } + return false; + } } diff --git a/src/main/java/WayofTime/alchemicalWizardry/common/summoning/meteor/MeteorReagent.java b/src/main/java/WayofTime/alchemicalWizardry/common/summoning/meteor/MeteorReagent.java new file mode 100644 index 000000000..f1547ad98 --- /dev/null +++ b/src/main/java/WayofTime/alchemicalWizardry/common/summoning/meteor/MeteorReagent.java @@ -0,0 +1,16 @@ +package WayofTime.alchemicalWizardry.common.summoning.meteor; + +import java.util.ArrayList; +import java.util.List; + +public class MeteorReagent { + + public boolean disableExplosions = false; + public boolean invertExplosionBlockDamage = false; + public int radiusChange = 0; + public int fillerChanceChange = 0; + public int rawFillerChanceChange = 0; + public String[] filler = {}; + public List parsedFiller = new ArrayList<>(); + +} diff --git a/src/main/java/WayofTime/alchemicalWizardry/common/summoning/meteor/MeteorReagentRegistry.java b/src/main/java/WayofTime/alchemicalWizardry/common/summoning/meteor/MeteorReagentRegistry.java new file mode 100644 index 000000000..41d97f5fc --- /dev/null +++ b/src/main/java/WayofTime/alchemicalWizardry/common/summoning/meteor/MeteorReagentRegistry.java @@ -0,0 +1,221 @@ +package WayofTime.alchemicalWizardry.common.summoning.meteor; + +import static WayofTime.alchemicalWizardry.api.alchemy.energy.ReagentRegistry.reagentList; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonSyntaxException; + +import WayofTime.alchemicalWizardry.AlchemicalWizardry; +import WayofTime.alchemicalWizardry.api.alchemy.energy.Reagent; +import WayofTime.alchemicalWizardry.api.alchemy.energy.ReagentRegistry; + +public class MeteorReagentRegistry { + + public static Map reagents = new HashMap<>(); + + public static void loadConfig() { + Gson gson = new GsonBuilder().setPrettyPrinting().create(); + File file = new File("config/BloodMagic/meteors/reagents/"); + if (!file.isDirectory()) { + MeteorReagentRegistry.generateDefaultConfig(); + } + File[] files = file.listFiles(); + if (files != null) { + try { + for (String reagent : reagentList.keySet()) { + File f = new File("config/BloodMagic/meteors/reagents/" + reagent + ".json"); + if (!f.isFile()) { + continue; + } + BufferedReader br = new BufferedReader(new FileReader(f)); + MeteorReagent r = gson.fromJson(br, MeteorReagent.class); + if (r == null) { + continue; + } + if (r.filler.length > 0) { + r.parsedFiller = MeteorParadigm.parseStringArray(r.filler); + } + reagents.put(ReagentRegistry.getReagentForKey(reagent), r); + } + } catch (FileNotFoundException | JsonSyntaxException e) { + e.printStackTrace(); + } + } + } + + // Returns the one largest radius increase (positive config). + public static int getLargestRadiusIncrease(List reagentList) { + int increase = 0; + for (Reagent r : reagentList) { + if (!reagents.containsKey(r)) { + continue; + } + int change = reagents.get(r).radiusChange; + if (change > increase) { + increase = change; + } + } + return increase; + } + + // Returns the one largest radius decrease (negative config). + public static int getLargestRadiusDecrease(List reagentList) { + int decrease = 0; + for (Reagent r : reagentList) { + if (!reagents.containsKey(r)) { + continue; + } + int change = reagents.get(r).radiusChange; + if (change < decrease) { + decrease = change; + } + } + return decrease; + } + + // Returns the one largest filler chance increase (positive config). + public static int getLargestFillerChanceIncrease(List reagentList) { + int increase = 0; + for (Reagent r : reagentList) { + if (!reagents.containsKey(r)) { + continue; + } + int change = reagents.get(r).fillerChanceChange; + if (change > increase) { + increase = change; + } + } + return increase; + } + + // Returns the one largest filler chance decrease (negative config). + public static int getLargestFillerChanceDecrease(List reagentList) { + int decrease = 0; + for (Reagent r : reagentList) { + if (!reagents.containsKey(r)) { + continue; + } + int change = reagents.get(r).fillerChanceChange; + if (change < decrease) { + decrease = change; + } + } + return decrease; + } + + // Returns the one largest raw filler chance increase (positive config). + public static int getLargestRawFillerChanceIncrease(List reagentList) { + int increase = 0; + for (Reagent r : reagentList) { + if (!reagents.containsKey(r)) { + continue; + } + int change = reagents.get(r).rawFillerChanceChange; + if (change > increase) { + increase = change; + } + } + return increase; + } + + // Returns the one largest raw filler chance decrease (negative config). + public static int getLargestRawFillerChanceDecrease(List reagentList) { + int decrease = 0; + for (Reagent r : reagentList) { + if (!reagents.containsKey(r)) { + continue; + } + int change = reagents.get(r).rawFillerChanceChange; + if (change < decrease) { + decrease = change; + } + } + return decrease; + } + + // Returns a list of the blocks that the given reagents will use to replace filler. + public static List getFillerList(List reagentList) { + List fillerList = new ArrayList<>(); + for (Reagent r : reagentList) { + if (!reagents.containsKey(r)) { + continue; + } + List filler = reagents.get(r).parsedFiller; + if (filler != null && !filler.isEmpty()) { + fillerList.addAll(filler); + } + } + return fillerList; + } + + // Returns false if any of the given reagents disable explosions, otherwise true + public static boolean doExplosions(List reagentList) { + for (Reagent r : reagentList) { + if (!reagents.containsKey(r)) { + continue; + } + if (reagents.get(r).disableExplosions) { + return false; + } + } + return true; + } + + /** + * Returns the value of the config AlchemicalWizardry.doMeteorsDestroyBlocks if no reagent inverts explosion block + * damage Returns the inverse of the value of AlchemicalWizardry.doMeteorsDestroyBlocks if any reagent inverts + * explosion block damage + */ + public static boolean doMeteorsDestroyBlocks(List reagentList) { + for (Reagent r : reagentList) { + if (!reagents.containsKey(r)) { + continue; + } + if (reagents.get(r).invertExplosionBlockDamage) { + return !AlchemicalWizardry.doMeteorsDestroyBlocks; + } + } + return AlchemicalWizardry.doMeteorsDestroyBlocks; + } + + public static void generateDefaultConfig() { + Map lineMap = new HashMap<>(); + lineMap.put("terrae", new String[] { "{", " \"radiusChange\": 1,", " \"fillerChanceChange\": 10", "}", }); + lineMap.put( + "orbisTerrae", + new String[] { "{", " \"radiusChange\": 2,", " \"fillerChanceChange\": 20", "}", }); + lineMap.put("tenebrae", new String[] { "{", " \"filler\": [\"minecraft:obsidian:0:180\"]", "}", }); + lineMap.put( + "incendium", + new String[] { "{", " \"filler\": [", " \"minecraft:netherrack:0:60\",", + " \"minecraft:glowstone:0:60\",", " \"minecraft:soul_sand:0:60\"", " ]", "}", }); + lineMap.put("crystallos", new String[] { "{", " \"filler\": [\"minecraft:ice:0:180\"]", "}", }); + try { + Files.createDirectories(Paths.get("config/BloodMagic/meteors/reagents/")); + String[] reagents = { "terrae", "orbisTerrae", "tenebrae", "incendium", "crystallos" }; + for (String reagent : reagents) { + Path path = Paths.get("config/BloodMagic/meteors/reagents/" + reagent + ".json"); + Files.createFile(path); + Files.write(path, Arrays.asList(lineMap.get(reagent)), StandardOpenOption.WRITE); + } + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/src/main/java/WayofTime/alchemicalWizardry/common/summoning/meteor/MeteorRegistry.java b/src/main/java/WayofTime/alchemicalWizardry/common/summoning/meteor/MeteorRegistry.java index fc63bc4fc..1bfb36482 100644 --- a/src/main/java/WayofTime/alchemicalWizardry/common/summoning/meteor/MeteorRegistry.java +++ b/src/main/java/WayofTime/alchemicalWizardry/common/summoning/meteor/MeteorRegistry.java @@ -8,6 +8,8 @@ import net.minecraft.world.World; import net.minecraftforge.oredict.OreDictionary; +import WayofTime.alchemicalWizardry.api.alchemy.energy.Reagent; + public class MeteorRegistry { public static List paradigmList = new ArrayList<>(); @@ -28,15 +30,19 @@ public static void registerMeteorParadigm(ItemStack stack, String[] componentLis if (fillerList != null && fillerList.length > 0) { meteor.fillerList = MeteorParadigm.parseStringArray(fillerList); } else { - meteor.fillerList.add(new MeteorParadigmComponent(new ItemStack(Blocks.stone), 1)); + meteor.fillerList.add(getDefaultMeteorParadigmComponent()); } paradigmList.add(meteor); } } - public static void createMeteorImpact(World world, int x, int y, int z, int paradigmID, boolean[] flags) { + public static MeteorParadigmComponent getDefaultMeteorParadigmComponent() { + return new MeteorParadigmComponent(new ItemStack(Blocks.stone), 1); + } + + public static void createMeteorImpact(World world, int x, int y, int z, int paradigmID, List reagents) { if (paradigmID < paradigmList.size()) { - paradigmList.get(paradigmID).createMeteorImpact(world, x, y, z, flags); + paradigmList.get(paradigmID).createMeteorImpact(world, x, y, z, reagents); } } diff --git a/src/main/java/WayofTime/alchemicalWizardry/common/tweaker/FallingTower.java b/src/main/java/WayofTime/alchemicalWizardry/common/tweaker/FallingTower.java index 677d5c8cc..2c2ddcd15 100644 --- a/src/main/java/WayofTime/alchemicalWizardry/common/tweaker/FallingTower.java +++ b/src/main/java/WayofTime/alchemicalWizardry/common/tweaker/FallingTower.java @@ -68,12 +68,11 @@ public Add(ItemStack stack, int radius, int cost, String[] components) { } public Add(ItemStack stack, int radius, int cost, String[] components, String[] filler, int fillerChance) { - paradigm = new MeteorParadigm(stack, radius, cost); + paradigm = new MeteorParadigm(stack, radius, cost, fillerChance); paradigm.componentList = MeteorParadigm.parseStringArray(components); if (filler != null) { paradigm.fillerList = MeteorParadigm.parseStringArray(filler); } - paradigm.fillerChance = fillerChance; } @Override diff --git a/src/main/resources/assets/alchemicalwizardry/lang/en_US.lang b/src/main/resources/assets/alchemicalwizardry/lang/en_US.lang index 82a48674e..8b31777fd 100644 --- a/src/main/resources/assets/alchemicalwizardry/lang/en_US.lang +++ b/src/main/resources/assets/alchemicalwizardry/lang/en_US.lang @@ -280,6 +280,7 @@ nei.recipe.meteor.radius=Radius: %s nei.recipe.meteor.chance=Chance: %s%% nei.recipe.meteor.amount=Estimated amount: %s nei.recipe.meteor.filler=§7Filler block +nei.recipe.meteor.reagent=§nRequired reagent§r: %s #Rituals ritual.AW001Water.name=Ritual of the Full Spring