├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ └── bug-report.md └── workflows │ └── maven.yml ├── .gitignore ├── LICENSE ├── README.md ├── lombok.config ├── pom.xml └── src ├── main ├── java │ └── io │ │ └── github │ │ └── mooy1 │ │ └── infinityexpansion │ │ ├── InfinityExpansion.java │ │ ├── categories │ │ ├── Groups.java │ │ └── InfinityGroup.java │ │ ├── commands │ │ ├── GiveRecipe.java │ │ ├── PrintItem.java │ │ └── SetData.java │ │ ├── items │ │ ├── Researches.java │ │ ├── SlimefunExtension.java │ │ ├── abstracts │ │ │ └── AbstractEnergyCrafter.java │ │ ├── blocks │ │ │ ├── AdvancedAnvil.java │ │ │ ├── Blocks.java │ │ │ ├── InfinityWorkbench.java │ │ │ └── StrainerBase.java │ │ ├── gear │ │ │ ├── Gear.java │ │ │ ├── InfinityArmor.java │ │ │ ├── InfinityBow.java │ │ │ ├── InfinityMatrix.java │ │ │ ├── InfinityTool.java │ │ │ └── VeinMinerRune.java │ │ ├── generators │ │ │ ├── EnergyGenerator.java │ │ │ ├── GenerationType.java │ │ │ ├── Generators.java │ │ │ └── InfinityReactor.java │ │ ├── machines │ │ │ ├── GearTransformer.java │ │ │ ├── GeoQuarry.java │ │ │ ├── GrowingMachine.java │ │ │ ├── Machines.java │ │ │ ├── MaterialGenerator.java │ │ │ ├── PoweredBedrock.java │ │ │ ├── ResourceSynthesizer.java │ │ │ ├── SingularityConstructor.java │ │ │ ├── StoneworksFactory.java │ │ │ └── VoidHarvester.java │ │ ├── materials │ │ │ ├── EnderEssence.java │ │ │ ├── Materials.java │ │ │ ├── Singularity.java │ │ │ └── Strainer.java │ │ ├── mobdata │ │ │ ├── MobData.java │ │ │ ├── MobDataCard.java │ │ │ ├── MobDataInfuser.java │ │ │ ├── MobDataTier.java │ │ │ └── MobSimulationChamber.java │ │ ├── quarries │ │ │ ├── Oscillator.java │ │ │ ├── Quarries.java │ │ │ └── Quarry.java │ │ └── storage │ │ │ ├── Storage.java │ │ │ ├── StorageCache.java │ │ │ ├── StorageForge.java │ │ │ ├── StorageSaveFix.java │ │ │ └── StorageUnit.java │ │ └── utils │ │ └── Util.java └── resources │ ├── config.yml │ └── plugin.yml └── test └── java └── io └── github └── mooy1 └── infinityexpansion └── TestInfinityExpansion.java /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | custom: ["https://www.paypal.com/paypalme/mooy1"] 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug-report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug Report 3 | about: Report a Bug or an Issue with this Plugin. 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | ## Description (Required) 11 | 12 | 13 | 14 | 15 | ## Steps to reproduce the Issue (Required) 16 | 17 | 18 | ## Expected behavior (Required) 19 | 20 | 21 | ## Server Log / Error Report 22 | 23 | 24 | 25 | ## Environment (Required) 26 | 27 | 28 | 29 | 30 | 31 | - Minecraft Version: 32 | - Slimefun Version: 33 | - Plugin Version: 34 | -------------------------------------------------------------------------------- /.github/workflows/maven.yml: -------------------------------------------------------------------------------- 1 | name: Java CI 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | pull_request: 8 | branches: 9 | - master 10 | 11 | jobs: 12 | build: 13 | 14 | name: Maven build 15 | runs-on: ubuntu-latest 16 | 17 | steps: 18 | - name: Checkout repository 19 | uses: actions/checkout@v3 20 | 21 | - name: Set up JDK 17 22 | uses: actions/setup-java@v3.4.0 23 | with: 24 | distribution: 'adopt' 25 | java-version: '17' 26 | java-package: jdk 27 | architecture: x64 28 | 29 | - name: Cache Maven packages 30 | uses: actions/cache@v3 31 | with: 32 | path: ~/.m2 33 | key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} 34 | restore-keys: ${{ runner.os }}-m2 35 | 36 | - name: Build with Maven 37 | run: mvn package --file pom.xml 38 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /bin/ 2 | /.settings/ 3 | /target/ 4 | /.idea/ 5 | *.iml 6 | .project 7 | .classpath 8 | dependency-reduced-pom.xml 9 | .DS_Store 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Infinity Expansion 2 | 3 | InfinityExpansion is an addon to the plugin Slimefun which adds a bunch of new machines and resources. 4 | It expands the endgame of Slimefun by a large margin. 5 | You can read about recent changes and additions at the bottom of the page. 6 | 7 | ## Download 8 | 9 | (Click Below) 10 | 11 | [![Build Status](https://thebusybiscuit.github.io/builds/Mooy1/InfinityExpansion/master/badge.svg)](https://thebusybiscuit.github.io/builds/Mooy1/InfinityExpansion/master) 12 | 13 | ## Requirements 14 | 15 | Minecraft Version: 1.16+ (Paper recommended) 16 | 17 | Slimefun Version: DEV 950+ (Click Below) 18 | 19 | [![Build Status](https://thebusybiscuit.github.io/builds/TheBusyBiscuit/Slimefun4/master/badge.svg)](https://thebusybiscuit.github.io/builds/TheBusyBiscuit/Slimefun4/master/) 20 | 21 | ## Bugs/Suggestions 22 | 23 | Make a new issue, pull request, or contact me on discord @Riley#5911 24 | 25 |

26 | 27 | Discord Invite 28 | 29 | 30 | Discord Invite 31 | 32 |

33 | 34 | ## Texture Pack 35 | 36 | A Texture Pack that adds texture for some items in this addon (requires Optifine): 37 | 38 | https://github.com/Mooy1/InfinityExpansion/releases/tag/v1 39 | 40 | ## Stats 41 | 42 | Some stats about the addon including current server count and player count are available here: 43 | 44 | https://bstats.org/plugin/bukkit/InfinityExpansion/8991 45 | 46 | ## Changelog 47 | ### Version 141 48 | - Fix Zombie Data Card Recipe using 1 iron ingot instead of 64. 49 | ### Version 140 50 | - Fix Powered Bedrock not taking the correct charge and getting stuck in a powered state 51 | ### Version 123 52 | - Fix Storage unit drops 53 | ### Version 122 54 | - Update to RC-28 55 | - Fix dust extractors 56 | - Small menu fixes 57 | ### Version 121 58 | - Update to RC-27 59 | #### Version 120 60 | - Won't warn about LiteXpansion nerfs if they are disabled 61 | #### Version 119 62 | - Fixed void harvester speed issue 63 | - infinity harvester will be about 6% faster 64 | - fixed display issue with rgb names on storage signs 65 | - new changelog style 66 | #### Version 118 67 | - Added Config option to enable researches, 68 | - Improved storage unit signs, 69 | - Slight nerf to mob data xp 70 | #### Version 117 71 | - Fix errors of Version 116 72 | #### Version 116 73 | - Add configuration to all quarry resources, 74 | - added copper (only with 1.17+) 75 | #### Version 115 76 | - Fixed issue with storage unit display (From PR) 77 | #### Version 114 78 | - Added cobble press and advanced smeltery, 79 | - Attempt to fix Storage Units, 80 | - Fix config stuff, 81 | - if you are on Dev 95 or lower, update to Dev 111 before this. 82 | #### Version 113 83 | - Fix future issues on startup 84 | #### Version 112 85 | - Fix for latest dev, Requires dev 925! 86 | #### Version 111 87 | - Fix auto update thing and temp fix for unit error 88 | #### Version 110 89 | - Fixed infinity cobble gen, optimized storage units 90 | #### Version 109 91 | - Fixed gold dust dupe and added quartz oscillator 92 | #### Version 108 93 | - Added infinity dust extractor, ingot former, infinity ingot former, infinity cobble gen 94 | - fixed storage withdraw overstacking 95 | #### Version 107 96 | - Fixed storage units and some recipes 97 | #### Version 106 98 | - Fixed ores generating in high tier quarries. 99 | #### Version 105 100 | - Fixed small issues with 104. 101 | #### Version 104 102 | - Added Quarry oscillators 103 | - Added witch and villager data card 104 | - fixed a bunch of bugs. 105 | #### Version 103 and below 106 | - Lots of stuff 107 | - Many Bugs 108 | - Bad code 109 | - Don't use these 110 | -------------------------------------------------------------------------------- /lombok.config: -------------------------------------------------------------------------------- 1 | # Stops lombok from looking for child configs 2 | config.stopbubbling = true 3 | 4 | # Removes getter prefixes 5 | lombok.accessors.fluent = true 6 | 7 | # Chain setters 8 | lombok.accessors.chain = true 9 | 10 | # Adds nullable annotations to generated methods when applicable 11 | lombok.addNullAnnotations = javax 12 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 4.0.0 7 | io.github.mooy1 8 | InfinityExpansion 9 | MODIFIED 10 | 11 | 12 | 1.8 13 | 1.8 14 | UTF-8 15 | 16 | 17 | 18 | 19 | spigot-repo 20 | https://hub.spigotmc.org/nexus/content/repositories/snapshots/ 21 | 22 | 23 | papermc 24 | https://repo.papermc.io/repository/maven-public/ 25 | 26 | 27 | jitpack.io 28 | https://jitpack.io 29 | 30 | 31 | 32 | 33 | 34 | org.spigotmc 35 | spigot-api 36 | 1.19-R0.1-SNAPSHOT 37 | provided 38 | 39 | 40 | 41 | com.github.Slimefun 42 | Slimefun4 43 | 934ab822a6 44 | provided 45 | 46 | 47 | 48 | org.projectlombok 49 | lombok 50 | 1.18.24 51 | provided 52 | 53 | 54 | 55 | com.google.code.findbugs 56 | jsr305 57 | 3.0.2 58 | provided 59 | 60 | 61 | 62 | io.github.mooy1 63 | InfinityLib 64 | f784252486 65 | compile 66 | 67 | 68 | 69 | org.junit.jupiter 70 | junit-jupiter 71 | 5.8.2 72 | test 73 | 74 | 75 | 76 | com.github.seeseemelk 77 | MockBukkit-v1.19 78 | 2.29.0 79 | test 80 | 81 | 82 | 83 | 84 | ${project.name} v${project.version} 85 | clean package 86 | ${basedir}/src/main/java 87 | 88 | 89 | 90 | ${basedir}/src/main/resources 91 | true 92 | 93 | 94 | ${basedir} 95 | 96 | LICENSE 97 | 98 | 99 | 100 | 101 | 102 | 103 | org.apache.maven.plugins 104 | maven-surefire-plugin 105 | 3.0.0-M7 106 | 107 | 108 | org.junit.jupiter:junit-jupiter 109 | false 110 | 111 | 112 | 113 | 114 | org.apache.maven.plugins 115 | maven-shade-plugin 116 | 3.3.0 117 | 118 | true 119 | 120 | 121 | io.github.mooy1.infinitylib 122 | io.github.mooy1.infinityexpansion.infinitylib 123 | 124 | 125 | 126 | 127 | *:* 128 | 129 | META-INF/* 130 | 131 | 132 | 133 | 134 | 135 | 136 | package 137 | 138 | shade 139 | 140 | 141 | 142 | 143 | 144 | 145 | -------------------------------------------------------------------------------- /src/main/java/io/github/mooy1/infinityexpansion/InfinityExpansion.java: -------------------------------------------------------------------------------- 1 | package io.github.mooy1.infinityexpansion; 2 | 3 | import java.io.File; 4 | import java.util.logging.Level; 5 | 6 | import org.bukkit.plugin.Plugin; 7 | import org.bukkit.plugin.PluginDescriptionFile; 8 | import org.bukkit.plugin.java.JavaPluginLoader; 9 | 10 | import io.github.mooy1.infinityexpansion.categories.Groups; 11 | import io.github.mooy1.infinityexpansion.commands.GiveRecipe; 12 | import io.github.mooy1.infinityexpansion.commands.PrintItem; 13 | import io.github.mooy1.infinityexpansion.commands.SetData; 14 | import io.github.mooy1.infinityexpansion.items.Researches; 15 | import io.github.mooy1.infinityexpansion.items.SlimefunExtension; 16 | import io.github.mooy1.infinityexpansion.items.blocks.Blocks; 17 | import io.github.mooy1.infinityexpansion.items.gear.Gear; 18 | import io.github.mooy1.infinityexpansion.items.generators.Generators; 19 | import io.github.mooy1.infinityexpansion.items.machines.Machines; 20 | import io.github.mooy1.infinityexpansion.items.materials.Materials; 21 | import io.github.mooy1.infinityexpansion.items.mobdata.MobData; 22 | import io.github.mooy1.infinityexpansion.items.quarries.Quarries; 23 | import io.github.mooy1.infinityexpansion.items.storage.Storage; 24 | import io.github.mooy1.infinityexpansion.items.storage.StorageSaveFix; 25 | import io.github.mooy1.infinitylib.common.Scheduler; 26 | import io.github.mooy1.infinitylib.core.AbstractAddon; 27 | import io.github.mooy1.infinitylib.metrics.bukkit.Metrics; 28 | import io.github.mooy1.infinitylib.metrics.charts.SimplePie; 29 | 30 | public final class InfinityExpansion extends AbstractAddon { 31 | 32 | public InfinityExpansion(JavaPluginLoader loader, PluginDescriptionFile description, File dataFolder, File file) { 33 | super(loader, description, dataFolder, file, 34 | "Mooy1", "InfinityExpansion", "master", "auto-update"); 35 | } 36 | 37 | public InfinityExpansion() { 38 | super("Mooy1", "InfinityExpansion", "master", "auto-update"); 39 | StorageSaveFix.fixStuff(getLogger()); 40 | } 41 | 42 | @Override 43 | protected void enable() { 44 | Metrics metrics = new Metrics(this, 8991); 45 | String autoUpdates = String.valueOf(autoUpdatesEnabled()); 46 | metrics.addCustomChart(new SimplePie("auto_updates", () -> autoUpdates)); 47 | 48 | Plugin lx = getServer().getPluginManager().getPlugin("LiteXpansion"); 49 | if (lx != null && lx.getConfig().getBoolean("options.nerf-other-addons")) { 50 | Scheduler.run(() -> log(Level.WARNING, 51 | "########################################################", 52 | "LiteXpansion nerfs energy generation in this addon.", 53 | "You can disable these nerfs in the LiteXpansion config.", 54 | "Under 'options:' add 'nerf-other-addons: false'", 55 | "########################################################" 56 | )); 57 | } 58 | 59 | getAddonCommand() 60 | .addSub(new GiveRecipe()) 61 | .addSub(new SetData()) 62 | .addSub(new PrintItem()); 63 | 64 | Groups.setup(this); 65 | MobData.setup(this); 66 | Materials.setup(this); 67 | Machines.setup(this); 68 | Quarries.setup(this); 69 | Gear.setup(this); 70 | Blocks.setup(this); 71 | Storage.setup(this); 72 | Generators.setup(this); 73 | SlimefunExtension.setup(this); 74 | 75 | if (getConfig().getBoolean("balance-options.enable-researches")) { 76 | Researches.setup(); 77 | } 78 | } 79 | 80 | @Override 81 | public void disable() { 82 | 83 | } 84 | 85 | } 86 | -------------------------------------------------------------------------------- /src/main/java/io/github/mooy1/infinityexpansion/categories/Groups.java: -------------------------------------------------------------------------------- 1 | package io.github.mooy1.infinityexpansion.categories; 2 | 3 | import org.bukkit.Material; 4 | 5 | import io.github.mooy1.infinityexpansion.InfinityExpansion; 6 | import io.github.mooy1.infinitylib.groups.MultiGroup; 7 | import io.github.mooy1.infinitylib.groups.SubGroup; 8 | import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup; 9 | import io.github.thebusybiscuit.slimefun4.libraries.dough.items.CustomItemStack; 10 | 11 | /** 12 | * Categories for this addon 13 | * 14 | * @author Mooy1 15 | */ 16 | public final class Groups { 17 | 18 | public static final ItemGroup INFINITY = new InfinityGroup(InfinityExpansion.createKey("infinity_recipes"), 19 | new CustomItemStack(Material.RESPAWN_ANCHOR, "&bInfinity &7Recipes"), 3); 20 | public static final ItemGroup MAIN_MATERIALS = new SubGroup("main_materials", 21 | new CustomItemStack(Material.NETHER_STAR, "&bInfinity &7Materials")); 22 | public static final ItemGroup BASIC_MACHINES = new SubGroup("basic_machines", 23 | new CustomItemStack(Material.LOOM, "&9Basic &7Machines")); 24 | public static final ItemGroup ADVANCED_MACHINES = new SubGroup("advanced_machines", 25 | new CustomItemStack(Material.BLAST_FURNACE, "&cAdvanced &7Machines")); 26 | public static final ItemGroup STORAGE = new SubGroup("storage", 27 | new CustomItemStack(Material.BEEHIVE, "&6Storage")); 28 | public static final ItemGroup MOB_SIMULATION = new SubGroup("mob_simulation", 29 | new CustomItemStack(Material.BEACON, "&bMob Simulation")); 30 | public static final ItemGroup INFINITY_MATERIALS = new SubGroup("infinity_materials", 31 | new CustomItemStack(Material.NETHERITE_BLOCK, "&bInfinity &aMaterials")); 32 | public static final ItemGroup MAIN_CATEGORY = new MultiGroup("main", 33 | new CustomItemStack(Material.NETHER_STAR, "&bInfinity &7Expansion"), 3, 34 | MAIN_MATERIALS, BASIC_MACHINES, ADVANCED_MACHINES, STORAGE, MOB_SIMULATION, INFINITY_MATERIALS, INFINITY); 35 | public static final ItemGroup INFINITY_CHEAT = new SubGroup("infinity_cheat", 36 | new CustomItemStack(Material.RESPAWN_ANCHOR, "&bInfinity &7Recipes &c- INCORRECT RECIPES")); 37 | 38 | public static void setup(InfinityExpansion inst) { 39 | INFINITY.register(inst); 40 | MAIN_CATEGORY.register(inst); 41 | MOB_SIMULATION.setCrossAddonItemGroup(true); 42 | INFINITY_CHEAT.register(inst); 43 | } 44 | 45 | } -------------------------------------------------------------------------------- /src/main/java/io/github/mooy1/infinityexpansion/commands/GiveRecipe.java: -------------------------------------------------------------------------------- 1 | package io.github.mooy1.infinityexpansion.commands; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import javax.annotation.Nonnull; 7 | 8 | import org.bukkit.ChatColor; 9 | import org.bukkit.command.CommandSender; 10 | import org.bukkit.entity.Player; 11 | import org.bukkit.inventory.ItemStack; 12 | 13 | import io.github.mooy1.infinitylib.commands.SubCommand; 14 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem; 15 | import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; 16 | import io.github.thebusybiscuit.slimefun4.core.multiblocks.MultiBlockMachine; 17 | import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; 18 | 19 | public final class GiveRecipe extends SubCommand { 20 | 21 | public GiveRecipe() { 22 | super("giverecipe", "gives all the items in a Slimefun item recipe", "infinityexpansion.giverecipe"); 23 | } 24 | 25 | @Override 26 | protected void execute(@Nonnull CommandSender sender, @Nonnull String[] args) { 27 | if (!(sender instanceof Player)) { 28 | sender.sendMessage("Only players can use this!"); 29 | return; 30 | } 31 | 32 | if (args.length != 1) { 33 | sender.sendMessage("Usage: /ie giverecipe "); 34 | return; 35 | } 36 | 37 | SlimefunItem sfItem = SlimefunItem.getById(args[0].toUpperCase()); 38 | 39 | if (sfItem == null || sfItem instanceof MultiBlockMachine || sfItem.getRecipeType() == RecipeType.GEO_MINER) { 40 | sender.sendMessage(ChatColor.RED + "Invalid Slimefun item!"); 41 | return; 42 | } 43 | 44 | sender.sendMessage(ChatColor.GREEN + "Gave recipe for " + sfItem.getItemName()); 45 | 46 | Player p = (Player) sender; 47 | 48 | List recipe = new ArrayList<>(); 49 | 50 | for (ItemStack e : sfItem.getRecipe()) { 51 | if (e != null) { 52 | recipe.add(e); 53 | } 54 | } 55 | 56 | p.getInventory().addItem(recipe.toArray(new ItemStack[0])); 57 | } 58 | 59 | @Override 60 | protected void complete(@Nonnull CommandSender sender, @Nonnull String[] args, @Nonnull List tabs) { 61 | if (args.length == 1) { 62 | for (SlimefunItem item : Slimefun.getRegistry().getEnabledSlimefunItems()) { 63 | tabs.add(item.getId()); 64 | } 65 | } 66 | } 67 | 68 | } -------------------------------------------------------------------------------- /src/main/java/io/github/mooy1/infinityexpansion/commands/PrintItem.java: -------------------------------------------------------------------------------- 1 | package io.github.mooy1.infinityexpansion.commands; 2 | 3 | import java.util.List; 4 | 5 | import javax.annotation.Nonnull; 6 | 7 | import org.bukkit.ChatColor; 8 | import org.bukkit.Material; 9 | import org.bukkit.command.CommandSender; 10 | import org.bukkit.entity.Player; 11 | import org.bukkit.inventory.ItemStack; 12 | 13 | import io.github.mooy1.infinitylib.commands.SubCommand; 14 | 15 | public final class PrintItem extends SubCommand { 16 | 17 | public PrintItem() { 18 | super("printitem", "Prints the internal data of an item for debugging purposes", "infinityexpansion.printitem"); 19 | } 20 | 21 | @Override 22 | protected void execute(@Nonnull CommandSender commandSender, @Nonnull String[] strings) { 23 | if (!(commandSender instanceof Player)) { 24 | return; 25 | } 26 | 27 | Player p = (Player) commandSender; 28 | 29 | ItemStack item = p.getInventory().getItemInMainHand(); 30 | 31 | if (item.getType() == Material.AIR) { 32 | p.sendMessage(ChatColor.RED + "You must be holding an item!"); 33 | return; 34 | } 35 | 36 | p.sendMessage(item.toString()); 37 | } 38 | 39 | @Override 40 | protected void complete(@Nonnull CommandSender commandSender, @Nonnull String[] strings, @Nonnull List list) { 41 | 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/io/github/mooy1/infinityexpansion/commands/SetData.java: -------------------------------------------------------------------------------- 1 | package io.github.mooy1.infinityexpansion.commands; 2 | 3 | import java.util.List; 4 | 5 | import javax.annotation.Nonnull; 6 | 7 | import org.bukkit.ChatColor; 8 | import org.bukkit.FluidCollisionMode; 9 | import org.bukkit.Material; 10 | import org.bukkit.block.Block; 11 | import org.bukkit.command.CommandSender; 12 | import org.bukkit.entity.Player; 13 | 14 | import io.github.mooy1.infinityexpansion.items.storage.StorageUnit; 15 | import io.github.mooy1.infinitylib.commands.SubCommand; 16 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem; 17 | import me.mrCookieSlime.Slimefun.api.BlockStorage; 18 | 19 | public final class SetData extends SubCommand { 20 | 21 | public SetData() { 22 | super("setdata", "Set slimefun block data of the block you are looking at", "infinityexpansion.setdata"); 23 | } 24 | 25 | @Override 26 | protected void execute(@Nonnull CommandSender commandSender, @Nonnull String[] strings) { 27 | if (!(commandSender instanceof Player)) { 28 | commandSender.sendMessage("Only players can use this!"); 29 | return; 30 | } 31 | 32 | if (strings.length != 2) { 33 | commandSender.sendMessage(ChatColor.RED + "You must specify a key and value to set!"); 34 | return; 35 | } 36 | 37 | Player p = (Player) commandSender; 38 | 39 | Block target = p.getTargetBlockExact(8, FluidCollisionMode.NEVER); 40 | 41 | if (target == null || target.getType() == Material.AIR) { 42 | p.sendMessage(ChatColor.RED + "You need to target a block to use this command!"); 43 | return; 44 | } 45 | 46 | String id = BlockStorage.getLocationInfo(target.getLocation(), "id"); 47 | 48 | if (id == null) { 49 | p.sendMessage(ChatColor.RED + "You need to target a slimefun block to use this command!"); 50 | return; 51 | } 52 | 53 | if (strings[0].equals("id")) { 54 | p.sendMessage(ChatColor.RED + "You cannot change the id of this block, it could cause internal issues!"); 55 | return; 56 | } 57 | 58 | if (strings[1].equals("\\remove")) { 59 | p.sendMessage(ChatColor.GREEN + "Successfully removed value of key '" + strings[0] + "' in " + id); 60 | BlockStorage.addBlockInfo(target, strings[0], null); 61 | } 62 | else { 63 | p.sendMessage(ChatColor.GREEN + "Successfully set key '" + strings[0] + "' to value '" + strings[1] + "' in " + id); 64 | BlockStorage.addBlockInfo(target, strings[0], strings[1]); 65 | } 66 | 67 | SlimefunItem unit = SlimefunItem.getById(id); 68 | if (unit instanceof StorageUnit) { 69 | ((StorageUnit) unit).reloadCache(target); 70 | } 71 | } 72 | 73 | @Override 74 | protected void complete(@Nonnull CommandSender commandSender, @Nonnull String[] strings, @Nonnull List list) { 75 | if (!(commandSender instanceof Player)) { 76 | return; 77 | } 78 | 79 | Player p = (Player) commandSender; 80 | 81 | Block target = p.getTargetBlockExact(8, FluidCollisionMode.NEVER); 82 | 83 | if (target == null || target.getType() == Material.AIR) { 84 | return; 85 | } 86 | 87 | if (strings.length == 1) { 88 | if (BlockStorage.hasBlockInfo(target)) { 89 | list.addAll(BlockStorage.getLocationInfo(target.getLocation()).getKeys()); 90 | list.remove("id"); 91 | } 92 | } 93 | else if (strings.length == 2 && !strings[1].equals("id")) { 94 | String current = BlockStorage.getLocationInfo(target.getLocation(), strings[1]); 95 | if (current != null) { 96 | list.add(current); 97 | list.add("\\remove"); 98 | } 99 | } 100 | } 101 | 102 | } 103 | -------------------------------------------------------------------------------- /src/main/java/io/github/mooy1/infinityexpansion/items/Researches.java: -------------------------------------------------------------------------------- 1 | package io.github.mooy1.infinityexpansion.items; 2 | 3 | import lombok.experimental.UtilityClass; 4 | 5 | import io.github.mooy1.infinityexpansion.InfinityExpansion; 6 | import io.github.mooy1.infinityexpansion.items.blocks.Blocks; 7 | import io.github.mooy1.infinityexpansion.items.gear.Gear; 8 | import io.github.mooy1.infinityexpansion.items.generators.Generators; 9 | import io.github.mooy1.infinityexpansion.items.machines.Machines; 10 | import io.github.mooy1.infinityexpansion.items.materials.Materials; 11 | import io.github.mooy1.infinityexpansion.items.mobdata.MobData; 12 | import io.github.mooy1.infinityexpansion.items.quarries.Quarries; 13 | import io.github.mooy1.infinityexpansion.items.storage.Storage; 14 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; 15 | import io.github.thebusybiscuit.slimefun4.api.researches.Research; 16 | 17 | @UtilityClass 18 | public final class Researches { 19 | 20 | private static final int FIRST_RESEARCH_ID = 314000000; 21 | 22 | public static void setup() { 23 | create(0, "harvesting_void", "Harvesting the Void", 35, 24 | Materials.VOID_BIT, Materials.VOID_DUST, Materials.VOID_INGOT, Machines.VOID_HARVESTER 25 | ); 26 | create(1, "infinity_gear", "Infinity Gear", 60, 27 | Gear.AXE, Gear.BLADE, Gear.BOW, Gear.PICKAXE, Gear.SHOVEL, Gear.SHIELD, 28 | Gear.CROWN, Gear.CHESTPLATE, Gear.LEGGINGS, Gear.BOOTS, Gear.INFINITY_MATRIX 29 | ); 30 | create(2, "singularities", "Creating Singularities", 35, 31 | Materials.ALUMINUM_SINGULARITY, 32 | Materials.SILVER_SINGULARITY, 33 | Materials.COPPER_SINGULARITY, 34 | Materials.LEAD_SINGULARITY, 35 | Materials.ZINC_SINGULARITY, 36 | Materials.TIN_SINGULARITY, 37 | Materials.MAGNESIUM_SINGULARITY, 38 | Materials.COAL_SINGULARITY, 39 | Materials.IRON_SINGULARITY, 40 | Materials.GOLD_SINGULARITY, 41 | Materials.DIAMOND_SINGULARITY, 42 | Materials.EMERALD_SINGULARITY, 43 | Materials.LAPIS_SINGULARITY, 44 | Materials.REDSTONE_SINGULARITY, 45 | Materials.NETHERITE_SINGULARITY, 46 | Materials.QUARTZ_SINGULARITY, 47 | Machines.SINGULARITY_CONSTRUCTOR, 48 | Machines.RESOURCE_SYNTHESIZER 49 | ); 50 | create(3, "infinity_ingot", "Creating Infinity", 40, 51 | Materials.EARTH_SINGULARITY, Materials.FORTUNE_SINGULARITY, Materials.MAGIC_SINGULARITY, 52 | Materials.METAL_SINGULARITY, Materials.INFINITE_INGOT, Blocks.INFINITY_FORGE 53 | ); 54 | create(4, "harvesting_end", "Harvesting the End", 20, 55 | Materials.ENDER_ESSENCE, Gear.ENDER_FLAME, Gear.VEIN_MINER_RUNE 56 | ); 57 | create(5, "mob_data", "Virtual Mob Farms", 30, 58 | MobData.CHAMBER, MobData.EMPTY_DATA_CARD, MobData.INFUSER, 59 | MobData.COW, MobData.SHEEP, MobData.CHICKEN 60 | ); 61 | create(6, "oscillators", "Improving Quarries", 30, 62 | Quarries.DIAMOND_OSCILLATOR, Quarries.EMERALD_OSCILLATOR, Quarries.LAPIS_OSCILLATOR, 63 | Quarries.REDSTONE_OSCILLATOR, Quarries.QUARTZ_OSCILLATOR 64 | ); 65 | create(7, "machine_materials", "Machine Materials", 20, 66 | Materials.MAGSTEEL, Materials.MAGSTEEL_PLATE, Materials.MACHINE_CIRCUIT, 67 | Materials.MACHINE_CORE, Materials.MACHINE_PLATE 68 | ); 69 | create(8, "compressed_cobble", "Compressing Cobblestone", 15, 70 | Materials.COBBLE_1, Materials.COBBLE_2, Materials.COBBLE_3, 71 | Materials.COBBLE_4, Materials.COBBLE_5, Machines.COBBLE_PRESS 72 | ); 73 | create(9, "starter_machines", "Starter Machines", 15, 74 | Machines.BASIC_COBBLE, Machines.BASIC_GROWER, 75 | Machines.BASIC_TREE, Quarries.BASIC_QUARRY 76 | ); 77 | create(10, "strainers", "Material Strainers", 10, 78 | Blocks.STRAINER_BASE, Materials.BASIC_STRAINER, 79 | Materials.ADVANCED_STRAINER, Materials.REINFORCED_STRAINER 80 | ); 81 | create(11, "starter_power", "Starter Power", 15, 82 | Generators.BASIC_PANEL, Generators.HYDRO 83 | ); 84 | create(12, "advanced_power", "Advanced Power", 35, 85 | Generators.ADVANCED_PANEL, Generators.GEOTHERMAL, Generators.REINFORCED_HYDRO, 86 | Generators.REINFORCED_GEOTHERMAL, Generators.CELESTIAL_PANEL, 87 | SlimefunExtension.ADVANCED_NETHER_STAR_REACTOR 88 | ); 89 | create(13, "advanced_machines", "Advanced Machines", 40, 90 | Machines.DUST_EXTRACTOR, Machines.EXTREME_FREEZER, Machines.GEO_QUARRY, 91 | Machines.DECOMPRESSOR, Machines.STONEWORKS_FACTORY, Machines.BASIC_OBSIDIAN, 92 | Machines.INGOT_FORMER, Blocks.ADVANCED_ANVIL, Machines.URANIUM_EXTRACTOR, 93 | Machines.GEAR_TRANSFORMER 94 | ); 95 | create(14, "upgraded_machines", "Upgraded Machines", 40, 96 | SlimefunExtension.ADVANCED_CHARGER, SlimefunExtension.ADVANCED_ENCHANTER, 97 | SlimefunExtension.ADVANCED_DISENCHANTER, SlimefunExtension.ADVANCED_SMELTERY, 98 | Machines.ADVANCED_COBBLE, Machines.ADVANCED_GROWER, Machines.ADVANCED_TREE, 99 | SlimefunExtension.ADVANCED_GEO_MINER, Quarries.ADVANCED_QUARRY 100 | ); 101 | create(15, "infinity_upgrades", "Infinity Upgrades", 80, 102 | Machines.INFINITE_VOID_HARVESTER, Machines.INFINITY_COBBLE, Machines.INFINITY_CONSTRUCTOR, 103 | Machines.INFINITY_GROWER, Machines.INFINITY_TREE, Machines.INFINITY_INGOT_FORMER, 104 | Generators.INFINITE_PANEL, Generators.INFINITY_REACTOR, Storage.INFINITY_STORAGE, 105 | SlimefunExtension.INFINITY_CAPACITOR, SlimefunExtension.INFINITY_CHARGER, 106 | SlimefunExtension.INFINITY_DISENCHANTER, SlimefunExtension.INFINITY_ENCHANTER, 107 | Quarries.INFINITY_QUARRY, Machines.INFINITY_DUST_EXTRACTOR 108 | ); 109 | create(16, "void_upgrades", "Void Upgrades", 45, 110 | Generators.VOID_PANEL, SlimefunExtension.VOID_CAPACITOR, Storage.VOID_STORAGE, 111 | Machines.POWERED_BEDROCK, Quarries.VOID_QUARRY 112 | ); 113 | create(17, "advanced_alloys", "Advanced Alloys", 30, 114 | Materials.TITANIUM, Materials.ADAMANTITE, Materials.MAGNONIUM, Materials.MYTHRIL 115 | ); 116 | create(18, "big_storage", "Big Storage", 20, 117 | Storage.STORAGE_FORGE, Storage.BASIC_STORAGE, Storage.ADVANCED_STORAGE, Storage.REINFORCED_STORAGE 118 | ); 119 | create(19, "infinity_materials", "Infinity Materials", 40, 120 | Materials.INFINITY_SINGULARITY, Materials.INFINITE_CORE, Materials.INFINITE_CIRCUIT 121 | ); 122 | create(20, "neutral_mob_data", "Neutral Mob Data", 25, 123 | MobData.SLIME, MobData.MAGMA_CUBE, MobData.BEE, MobData.VILLAGER 124 | ); 125 | create(21, "hostile_mob_data", "Hostile Mob Data", 30, 126 | MobData.ZOMBIE, MobData.SPIDER, MobData.SKELETON, 127 | MobData.CREEPER, MobData.GUARDIAN, MobData.WITCH 128 | ); 129 | create(22, "advanced_mob_data", "Advanced Mob Data", 45, 130 | MobData.WITHER_SKELETON, MobData.ENDERMEN, MobData.IRON_GOLEM, MobData.BLAZE 131 | ); 132 | create(23, "boss_mob_data", "Boss Mob Data", 60, 133 | MobData.WITHER, MobData.ENDER_DRAGON 134 | ); 135 | } 136 | 137 | private static void create(int id, String key, String name, int cost, SlimefunItemStack... items) { 138 | new Research(InfinityExpansion.createKey(key), FIRST_RESEARCH_ID + id, name, cost).addItems(items).register(); 139 | } 140 | 141 | } 142 | -------------------------------------------------------------------------------- /src/main/java/io/github/mooy1/infinityexpansion/items/abstracts/AbstractEnergyCrafter.java: -------------------------------------------------------------------------------- 1 | package io.github.mooy1.infinityexpansion.items.abstracts; 2 | 3 | import javax.annotation.Nonnull; 4 | import javax.annotation.ParametersAreNonnullByDefault; 5 | 6 | import org.bukkit.Material; 7 | import org.bukkit.block.Block; 8 | import org.bukkit.inventory.ItemStack; 9 | 10 | import io.github.mooy1.infinitylib.machines.TickingMenuBlock; 11 | import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup; 12 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; 13 | import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; 14 | import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetComponent; 15 | import io.github.thebusybiscuit.slimefun4.core.networks.energy.EnergyNetComponentType; 16 | import io.github.thebusybiscuit.slimefun4.libraries.dough.items.CustomItemStack; 17 | import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu; 18 | import me.mrCookieSlime.Slimefun.api.inventory.DirtyChestMenu; 19 | 20 | @ParametersAreNonnullByDefault 21 | public abstract class AbstractEnergyCrafter extends TickingMenuBlock implements EnergyNetComponent { 22 | 23 | protected final int energy; 24 | protected final int statusSlot; 25 | 26 | public AbstractEnergyCrafter(ItemGroup category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, int energy, int statusSlot) { 27 | super(category, item, recipeType, recipe); 28 | this.energy = energy; 29 | this.statusSlot = statusSlot; 30 | } 31 | 32 | @Override 33 | protected final void tick(Block block, BlockMenu blockMenu) { 34 | if (blockMenu.hasViewer()) { 35 | int charge = getCharge(block.getLocation()); 36 | if (charge < this.energy) { //not enough energy 37 | blockMenu.replaceExistingItem(this.statusSlot, new CustomItemStack( 38 | Material.RED_STAINED_GLASS_PANE, 39 | "&cNot enough energy!", 40 | "", 41 | "&aCharge: " + charge + "/" + this.energy + " J", 42 | "" 43 | )); 44 | } 45 | else { 46 | update(blockMenu); 47 | } 48 | } 49 | } 50 | 51 | public abstract void update(BlockMenu blockMenu); 52 | 53 | @Nonnull 54 | @Override 55 | public final EnergyNetComponentType getEnergyComponentType() { 56 | return EnergyNetComponentType.CONSUMER; 57 | } 58 | 59 | @Override 60 | public final int getCapacity() { 61 | return this.energy; 62 | } 63 | 64 | @Override 65 | protected final int[] getInputSlots(DirtyChestMenu menu, ItemStack item) { 66 | return new int[0]; 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/io/github/mooy1/infinityexpansion/items/blocks/AdvancedAnvil.java: -------------------------------------------------------------------------------- 1 | package io.github.mooy1.infinityexpansion.items.blocks; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | import java.util.Objects; 6 | 7 | import javax.annotation.Nonnull; 8 | import javax.annotation.Nullable; 9 | 10 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem; 11 | import org.bukkit.ChatColor; 12 | import org.bukkit.Location; 13 | import org.bukkit.Material; 14 | import org.bukkit.Sound; 15 | import org.bukkit.block.Block; 16 | import org.bukkit.enchantments.Enchantment; 17 | import org.bukkit.entity.Player; 18 | import org.bukkit.inventory.ItemStack; 19 | import org.bukkit.inventory.meta.EnchantmentStorageMeta; 20 | import org.bukkit.inventory.meta.ItemMeta; 21 | 22 | import com.google.common.collect.MapDifference; 23 | import com.google.common.collect.Maps; 24 | import io.github.mooy1.infinityexpansion.InfinityExpansion; 25 | import io.github.mooy1.infinityexpansion.items.abstracts.AbstractEnergyCrafter; 26 | import io.github.mooy1.infinityexpansion.utils.Util; 27 | import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup; 28 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; 29 | import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; 30 | import io.github.thebusybiscuit.slimefun4.libraries.dough.items.CustomItemStack; 31 | import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils; 32 | import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu; 33 | import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset; 34 | 35 | /** 36 | * Combines slimefun items, exceeds vanilla anvil limits 37 | * 38 | * @author Mooy1 39 | */ 40 | public final class AdvancedAnvil extends AbstractEnergyCrafter { 41 | 42 | private static final Map MAX_LEVELS = Util.getEnchants(Objects.requireNonNull( 43 | InfinityExpansion.config().getConfigurationSection("advanced-anvil-max-levels") 44 | )); 45 | private static final ItemStack ANVIL_SLOT = new CustomItemStack(Material.BLACK_STAINED_GLASS_PANE, " "); 46 | private static final int[] INPUT_SLOTS = { 47 | 10, 13 48 | }; 49 | private static final int[] OUTPUT_SLOTS = { 50 | 16 51 | }; 52 | private static final int STATUS_SLOT = 40; 53 | private static final int[] ANVIL_SLOTS = { 54 | 30, 31, 32, 39, 41, 47, 48, 49, 50, 51 55 | 56 | }; 57 | private static final int[] BACKGROUND = { 58 | 27, 28, 29, 33, 34, 35, 59 | 36, 37, 38, 42, 43, 44, 60 | 45, 46, 52, 53 61 | }; 62 | 63 | public AdvancedAnvil(ItemGroup category, SlimefunItemStack item, RecipeType type, ItemStack[] recipe, int energy) { 64 | super(category, item, type, recipe, energy, STATUS_SLOT); 65 | } 66 | 67 | @Override 68 | protected void setup(@Nonnull BlockMenuPreset blockMenuPreset) { 69 | blockMenuPreset.drawBackground(BACKGROUND); 70 | blockMenuPreset.drawBackground(ANVIL_SLOT, ANVIL_SLOTS); 71 | blockMenuPreset.drawBackground(INPUT_BORDER, new int[] { 72 | 0, 1, 2, 3, 4, 5, 73 | 9, 11, 12, 14, 74 | 18, 19, 20, 21, 22, 23 75 | }); 76 | blockMenuPreset.drawBackground(OUTPUT_BORDER, new int[] { 77 | 6, 7, 8, 78 | 15, 17, 79 | 24, 25, 26 80 | }); 81 | blockMenuPreset.addItem(STATUS_SLOT, ChestMenuUtils.getBackground(), ChestMenuUtils.getEmptyClickHandler()); 82 | } 83 | 84 | @Override 85 | protected int[] getInputSlots() { 86 | return INPUT_SLOTS; 87 | } 88 | 89 | @Override 90 | protected int[] getOutputSlots() { 91 | return OUTPUT_SLOTS; 92 | } 93 | 94 | @Override 95 | protected void onNewInstance(@Nonnull BlockMenu menu, @Nonnull Block b) { 96 | menu.addMenuClickHandler(STATUS_SLOT, (player, i, itemStack, clickAction) -> { 97 | craft(menu, b, player); 98 | return false; 99 | }); 100 | } 101 | 102 | private void craft(BlockMenu inv, Block b, Player p) { 103 | Location l = b.getLocation(); 104 | if (getCharge(l) < this.energy) { //not enough energy 105 | p.sendMessage(ChatColor.RED + "Not enough energy!", 106 | ChatColor.GREEN + "Charge: " + ChatColor.RED + getCharge(l) + ChatColor.GREEN + "/" + this.energy + " J"); 107 | return; 108 | } 109 | 110 | ItemStack item1 = inv.getItemInSlot(INPUT_SLOTS[0]); 111 | SlimefunItem sfItem1 = SlimefunItem.getByItem(inv.getItemInSlot(INPUT_SLOTS[0])); 112 | ItemStack item2 = inv.getItemInSlot(INPUT_SLOTS[1]); 113 | SlimefunItem sfItem2 = SlimefunItem.getByItem(inv.getItemInSlot(INPUT_SLOTS[1])); 114 | 115 | if (item1 == null || item2 == null || (item2.getType() != Material.ENCHANTED_BOOK && item1.getType() != item2.getType())) { 116 | p.sendMessage(ChatColor.RED + "Invalid items!"); 117 | return; 118 | } 119 | 120 | if(sfItem2 != null && !sfItem2.isDisenchantable()){ 121 | p.sendMessage(ChatColor.RED + "Slimefun item is not disenchantable!"); 122 | return; 123 | } 124 | 125 | if(sfItem1 != null && !sfItem1.isEnchantable()){ 126 | p.sendMessage(ChatColor.RED + "Slimefun item is not enchantable!"); 127 | return; 128 | } 129 | 130 | ItemStack output = getOutput(item1, item2); 131 | 132 | if (output == null) { 133 | p.sendMessage(ChatColor.RED + "No upgrades!"); 134 | return; 135 | } 136 | 137 | if (!inv.fits(output, OUTPUT_SLOTS)) { 138 | p.sendMessage(ChatColor.GOLD + "Not enough room!"); 139 | return; 140 | } 141 | 142 | p.playSound(l, Sound.BLOCK_ANVIL_USE, 1, 1); 143 | item1.setAmount(item1.getAmount() - 1); 144 | item2.setAmount(item2.getAmount() - 1); 145 | inv.pushItem(output, OUTPUT_SLOTS); 146 | removeCharge(l, this.energy); 147 | update(inv); 148 | } 149 | 150 | @Nullable 151 | private static ItemStack getOutput(@Nonnull ItemStack item1, @Nonnull ItemStack item2) { 152 | Map enchants1 = getEnchants(item1.getItemMeta()); 153 | Map enchants2 = getEnchants(item2.getItemMeta()); 154 | if (enchants1.size() == 0 && enchants2.size() == 0) { 155 | return null; 156 | } 157 | return combineEnchants(Maps.difference(enchants1, enchants2), item1, item2); 158 | } 159 | 160 | @Nonnull 161 | private static Map getEnchants(@Nonnull ItemMeta meta) { 162 | if (meta instanceof EnchantmentStorageMeta) { 163 | EnchantmentStorageMeta book = (EnchantmentStorageMeta) meta; 164 | if (book.hasStoredEnchants()) { 165 | return book.getStoredEnchants(); 166 | } 167 | } 168 | else if (meta.hasEnchants()) { 169 | return meta.getEnchants(); 170 | } 171 | 172 | return new HashMap<>(); 173 | } 174 | 175 | private static void setEnchants(@Nonnull ItemStack item, @Nonnull ItemMeta meta, @Nonnull Map enchants) { 176 | if (meta instanceof EnchantmentStorageMeta) { 177 | EnchantmentStorageMeta book = (EnchantmentStorageMeta) meta; 178 | for (Map.Entry entry : enchants.entrySet()) { 179 | book.addStoredEnchant(entry.getKey(), entry.getValue(), true); 180 | } 181 | item.setItemMeta(book); 182 | } 183 | else { 184 | for (Map.Entry entry : enchants.entrySet()) { 185 | item.addUnsafeEnchantment(entry.getKey(), entry.getValue()); 186 | } 187 | } 188 | } 189 | 190 | @Nullable 191 | private static ItemStack combineEnchants(@Nonnull MapDifference dif, @Nonnull ItemStack item1, @Nonnull ItemStack item2) { 192 | ItemStack item = item1.clone(); 193 | item.setAmount(1); 194 | ItemMeta meta = item.getItemMeta(); 195 | 196 | Map enchants = new HashMap<>(); 197 | 198 | boolean changed = false; 199 | 200 | //upgrades (same enchant and level) 201 | for (Map.Entry e : dif.entriesInCommon().entrySet()) { 202 | if (MAX_LEVELS.containsKey(e.getKey()) && e.getValue() < MAX_LEVELS.get(e.getKey())) { 203 | enchants.put(e.getKey(), e.getValue() + 1); 204 | changed = true; 205 | } 206 | } 207 | 208 | //override (same enchant different level) 209 | for (Map.Entry> e : dif.entriesDiffering().entrySet()) { 210 | if (e.getValue().rightValue() > e.getValue().leftValue()) { 211 | enchants.put(e.getKey(), e.getValue().rightValue()); 212 | changed = true; 213 | } 214 | } 215 | 216 | boolean bookOntoTool = item2.getType() == Material.ENCHANTED_BOOK && item1.getType() != Material.ENCHANTED_BOOK; 217 | 218 | //unique (different enchants from 2nd item) 219 | for (Map.Entry e : dif.entriesOnlyOnRight().entrySet()) { 220 | if (bookOntoTool) { 221 | if (!e.getKey().canEnchantItem(item)) { 222 | continue; 223 | } 224 | } 225 | enchants.put(e.getKey(), e.getValue()); 226 | changed = true; 227 | } 228 | 229 | if (changed) { 230 | setEnchants(item, meta, enchants); 231 | return item; 232 | } 233 | else { 234 | return null; 235 | } 236 | } 237 | 238 | @Override 239 | public void update(@Nonnull BlockMenu inv) { 240 | ItemStack item1 = inv.getItemInSlot(INPUT_SLOTS[0]); 241 | ItemStack item2 = inv.getItemInSlot(INPUT_SLOTS[1]); 242 | 243 | if (item1 == null || item2 == null || (item2.getType() != Material.ENCHANTED_BOOK && item1.getType() != item2.getType())) { 244 | inv.replaceExistingItem(STATUS_SLOT, new CustomItemStack(Material.BARRIER, "&cInvalid items!")); 245 | return; 246 | } 247 | 248 | ItemStack output = getOutput(item1, item2); 249 | 250 | if (output == null) { 251 | inv.replaceExistingItem(STATUS_SLOT, new CustomItemStack(Material.BARRIER, "&cNo upgrades!")); 252 | return; 253 | } 254 | 255 | inv.replaceExistingItem(STATUS_SLOT, Util.getDisplayItem(output)); 256 | 257 | } 258 | 259 | } 260 | -------------------------------------------------------------------------------- /src/main/java/io/github/mooy1/infinityexpansion/items/blocks/Blocks.java: -------------------------------------------------------------------------------- 1 | package io.github.mooy1.infinityexpansion.items.blocks; 2 | 3 | import lombok.experimental.UtilityClass; 4 | 5 | import org.bukkit.Material; 6 | import org.bukkit.inventory.ItemStack; 7 | 8 | import io.github.mooy1.infinityexpansion.InfinityExpansion; 9 | import io.github.mooy1.infinityexpansion.categories.Groups; 10 | import io.github.mooy1.infinityexpansion.items.materials.Materials; 11 | import io.github.mooy1.infinitylib.machines.MachineLore; 12 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; 13 | import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; 14 | import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; 15 | 16 | @UtilityClass 17 | public final class Blocks { 18 | 19 | public static final SlimefunItemStack STRAINER_BASE = new SlimefunItemStack( 20 | "STRAINER_BASE", 21 | Material.SANDSTONE_WALL, 22 | "&7Strainer Base" 23 | ); 24 | public static final SlimefunItemStack ADVANCED_ANVIL = new SlimefunItemStack( 25 | "ADVANCED_ANVIL", 26 | Material.SMITHING_TABLE, 27 | "&cAdvanced Anvil", 28 | "&7Combines tools and gear enchants and sometimes upgrades them", 29 | "&bWorks with Slimefun items", 30 | "", 31 | MachineLore.energy(100000) + "per use" 32 | ); 33 | public static final SlimefunItemStack INFINITY_FORGE = new SlimefunItemStack( 34 | "INFINITY_FORGE", 35 | Material.RESPAWN_ANCHOR, 36 | "&6Infinity Workbench", 37 | "&7Used to craft infinity items", 38 | "", 39 | MachineLore.energy(10000000) + "per item" 40 | ); 41 | 42 | public static void setup(InfinityExpansion plugin) { 43 | new StrainerBase(Groups.BASIC_MACHINES, STRAINER_BASE, RecipeType.ENHANCED_CRAFTING_TABLE, new ItemStack[] { 44 | new ItemStack(Material.STICK), new ItemStack(Material.STRING), new ItemStack(Material.STICK), 45 | new ItemStack(Material.STICK), new ItemStack(Material.STRING), new ItemStack(Material.STICK), 46 | Materials.MAGSTEEL, Materials.MAGSTEEL, Materials.MAGSTEEL, 47 | }, 48).register(plugin); 48 | new AdvancedAnvil(Groups.MAIN_MATERIALS, ADVANCED_ANVIL, RecipeType.ENHANCED_CRAFTING_TABLE, new ItemStack[] { 49 | Materials.MACHINE_PLATE, Materials.MACHINE_PLATE, Materials.MACHINE_PLATE, 50 | Materials.MACHINE_PLATE, new ItemStack(Material.ANVIL), Materials.MACHINE_PLATE, 51 | Materials.MACHINE_CIRCUIT, Materials.MACHINE_CORE, Materials.MACHINE_CIRCUIT 52 | }, 100000).register(plugin); 53 | new InfinityWorkbench(Groups.MAIN_MATERIALS, INFINITY_FORGE, RecipeType.ENHANCED_CRAFTING_TABLE, new ItemStack[] { 54 | Materials.VOID_INGOT, Materials.MACHINE_PLATE, Materials.VOID_INGOT, 55 | SlimefunItems.ENERGIZED_CAPACITOR, new ItemStack(Material.CRAFTING_TABLE), SlimefunItems.ENERGIZED_CAPACITOR, 56 | Materials.VOID_INGOT, Materials.MACHINE_PLATE, Materials.VOID_INGOT 57 | }, 10000000).register(plugin); 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/io/github/mooy1/infinityexpansion/items/blocks/InfinityWorkbench.java: -------------------------------------------------------------------------------- 1 | package io.github.mooy1.infinityexpansion.items.blocks; 2 | 3 | import javax.annotation.Nonnull; 4 | import javax.annotation.ParametersAreNonnullByDefault; 5 | 6 | import org.bukkit.ChatColor; 7 | import org.bukkit.Material; 8 | import org.bukkit.block.Block; 9 | import org.bukkit.entity.Player; 10 | import org.bukkit.inventory.ItemStack; 11 | 12 | import io.github.mooy1.infinityexpansion.categories.InfinityGroup; 13 | import io.github.mooy1.infinitylib.machines.MachineLayout; 14 | import io.github.mooy1.infinitylib.machines.MachineRecipeType; 15 | import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup; 16 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; 17 | import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; 18 | import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetComponent; 19 | import io.github.thebusybiscuit.slimefun4.core.networks.energy.EnergyNetComponentType; 20 | import io.github.thebusybiscuit.slimefun4.libraries.dough.items.CustomItemStack; 21 | import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils; 22 | import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu; 23 | import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset; 24 | 25 | @ParametersAreNonnullByDefault 26 | public final class InfinityWorkbench extends io.github.mooy1.infinitylib.machines.CraftingBlock implements EnergyNetComponent { 27 | 28 | public static final int[] INPUT_SLOTS = { 29 | 0, 1, 2, 3, 4, 5, 30 | 9, 10, 11, 12, 13, 14, 31 | 18, 19, 20, 21, 22, 23, 32 | 27, 28, 29, 30, 31, 32, 33 | 36, 37, 38, 39, 40, 41, 34 | 45, 46, 47, 48, 49, 50 35 | }; 36 | private static final int RECIPE_SLOT = 7; 37 | public static final MachineRecipeType TYPE = new MachineRecipeType("infinity_forge", 38 | new CustomItemStack(Blocks.INFINITY_FORGE, Blocks.INFINITY_FORGE.getDisplayName(), 39 | "", "&cUse the infinity recipes category to see the correct recipe!")); 40 | 41 | private final int energy; 42 | 43 | public InfinityWorkbench(ItemGroup category, SlimefunItemStack item, RecipeType type, ItemStack[] recipe, int energy) { 44 | super(category, item, type, recipe); 45 | addRecipesFrom(TYPE); 46 | layout(new MachineLayout() 47 | .inputSlots(INPUT_SLOTS) 48 | .outputSlots(new int[] { 43 }) 49 | .statusSlot(16) 50 | .inputBorder(new int[0]) 51 | .outputBorder(new int[] { 52 | 33, 34, 35, 53 | 42, 44, 54 | 51, 52, 53 55 | }).background(new int[] { 56 | 6, 8, 15, 17, 24, 25, 26 57 | }) 58 | ); 59 | this.energy = energy; 60 | } 61 | 62 | @Override 63 | protected void setup(BlockMenuPreset preset) { 64 | super.setup(preset); 65 | preset.addItem(RECIPE_SLOT, new CustomItemStack(Material.BOOK, "&6Recipes"), ChestMenuUtils.getEmptyClickHandler()); 66 | } 67 | 68 | @Override 69 | protected void onNewInstance(BlockMenu menu, Block b) { 70 | super.onNewInstance(menu, b); 71 | menu.addMenuClickHandler(RECIPE_SLOT, (p, slot, item, action) -> { 72 | InfinityGroup.open(p, menu); 73 | return false; 74 | }); 75 | } 76 | 77 | @Override 78 | protected void craft(Block b, BlockMenu menu, Player p) { 79 | int charge = getCharge(menu.getLocation()); 80 | if (charge < this.energy) { 81 | p.sendMessage( 82 | ChatColor.RED + "Not enough energy!", 83 | ChatColor.GREEN + "Charge: " + ChatColor.RED + charge + ChatColor.GREEN + "/" + this.energy + " J" 84 | ); 85 | } 86 | else { 87 | super.craft(b, menu, p); 88 | } 89 | } 90 | 91 | @Override 92 | protected void onSuccessfulCraft(BlockMenu menu, ItemStack toOutput) { 93 | setCharge(menu.getLocation(), 0); 94 | } 95 | 96 | @Nonnull 97 | @Override 98 | public EnergyNetComponentType getEnergyComponentType() { 99 | return EnergyNetComponentType.CONSUMER; 100 | } 101 | 102 | @Override 103 | public int getCapacity() { 104 | return this.energy; 105 | } 106 | 107 | } 108 | -------------------------------------------------------------------------------- /src/main/java/io/github/mooy1/infinityexpansion/items/blocks/StrainerBase.java: -------------------------------------------------------------------------------- 1 | package io.github.mooy1.infinityexpansion.items.blocks; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.Random; 6 | import java.util.concurrent.ThreadLocalRandom; 7 | 8 | import javax.annotation.Nonnull; 9 | import javax.annotation.ParametersAreNonnullByDefault; 10 | 11 | import org.bukkit.Material; 12 | import org.bukkit.block.Block; 13 | import org.bukkit.enchantments.Enchantment; 14 | import org.bukkit.entity.Player; 15 | import org.bukkit.inventory.ItemStack; 16 | import org.bukkit.inventory.meta.Damageable; 17 | import org.bukkit.inventory.meta.ItemMeta; 18 | 19 | import io.github.mooy1.infinityexpansion.items.materials.Materials; 20 | import io.github.mooy1.infinityexpansion.items.materials.Strainer; 21 | import io.github.mooy1.infinityexpansion.utils.Util; 22 | import io.github.mooy1.infinitylib.machines.TickingMenuBlock; 23 | import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup; 24 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; 25 | import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; 26 | import io.github.thebusybiscuit.slimefun4.core.attributes.RecipeDisplayItem; 27 | import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; 28 | import io.github.thebusybiscuit.slimefun4.libraries.dough.items.CustomItemStack; 29 | import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils; 30 | import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu; 31 | import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset; 32 | import me.mrCookieSlime.Slimefun.api.inventory.DirtyChestMenu; 33 | 34 | /** 35 | * Generates items slowly using up strainers, must be waterlogged 36 | * 37 | * @author Mooy1 38 | */ 39 | @ParametersAreNonnullByDefault 40 | public final class StrainerBase extends TickingMenuBlock implements RecipeDisplayItem { 41 | 42 | 43 | private static final ItemStack POTATO = new CustomItemStack(Material.POTATO, "&7:&6Potatofish&7:", "&eLucky"); 44 | private static final int STATUS_SLOT = 10; 45 | private static final int[] OUTPUT_SLOTS = { 46 | 13, 14, 15, 16, 47 | 22, 23, 24, 25, 48 | 31, 32, 33, 34, 49 | 40, 41, 42, 43 50 | }; 51 | private static final int[] INPUT_SLOTS = { 52 | 37 53 | }; 54 | 55 | private static final ItemStack[] OUTPUTS = { 56 | new ItemStack(Material.STICK), 57 | new ItemStack(Material.SAND), 58 | new ItemStack(Material.GRAVEL), 59 | new ItemStack(Material.QUARTZ), 60 | new ItemStack(Material.REDSTONE), 61 | new ItemStack(Material.EMERALD), 62 | new SlimefunItemStack(SlimefunItems.MAGNESIUM_DUST, 1), 63 | new SlimefunItemStack(SlimefunItems.COPPER_DUST, 1), 64 | new SlimefunItemStack(SlimefunItems.COPPER_DUST, 1), 65 | new SlimefunItemStack(SlimefunItems.SILVER_DUST, 1), 66 | new SlimefunItemStack(SlimefunItems.ALUMINUM_DUST, 1), 67 | new SlimefunItemStack(SlimefunItems.LEAD_DUST, 1), 68 | new SlimefunItemStack(SlimefunItems.IRON_DUST, 1), 69 | new SlimefunItemStack(SlimefunItems.GOLD_DUST, 1), 70 | new SlimefunItemStack(SlimefunItems.TIN_DUST, 1), 71 | new SlimefunItemStack(SlimefunItems.ZINC_DUST, 1), 72 | }; 73 | 74 | private final int time; 75 | 76 | public StrainerBase(ItemGroup category, SlimefunItemStack item, RecipeType type, ItemStack[] recipe, int time) { 77 | super(category, item, type, recipe); 78 | this.time = time; 79 | } 80 | 81 | @Override 82 | protected void setup(@Nonnull BlockMenuPreset blockMenuPreset) { 83 | blockMenuPreset.drawBackground(new int[] { 84 | 0, 1, 2, 9, 11, 18, 19, 20 85 | }); 86 | blockMenuPreset.drawBackground(INPUT_BORDER, new int[] { 87 | 27, 28, 29, 36, 38, 45, 46, 47 88 | }); 89 | blockMenuPreset.drawBackground(OUTPUT_BORDER, new int[] { 90 | 3, 4, 5, 6, 7, 8, 91 | 12, 17, 92 | 21, 26, 93 | 30, 35, 94 | 39, 44, 95 | 48, 49, 50, 51, 52, 53 96 | }); 97 | blockMenuPreset.addItem(STATUS_SLOT, ChestMenuUtils.getBackground(), ChestMenuUtils.getEmptyClickHandler()); 98 | } 99 | 100 | @Nonnull 101 | @Override 102 | public int[] getInputSlots(@Nonnull DirtyChestMenu menu, @Nonnull ItemStack item) { 103 | if (Strainer.getStrainer(item) > 0) { 104 | return INPUT_SLOTS; 105 | } 106 | else { 107 | return new int[0]; 108 | } 109 | } 110 | 111 | @Override 112 | protected int[] getInputSlots() { 113 | return INPUT_SLOTS; 114 | } 115 | 116 | @Override 117 | protected int[] getOutputSlots() { 118 | return OUTPUT_SLOTS; 119 | } 120 | 121 | @Nonnull 122 | @Override 123 | public List getDisplayRecipes() { 124 | List items = new ArrayList<>(); 125 | 126 | for (ItemStack output : OUTPUTS) { 127 | items.add(Materials.BASIC_STRAINER); 128 | items.add(output); 129 | } 130 | 131 | return items; 132 | } 133 | 134 | @Nonnull 135 | @Override 136 | public String getRecipeSectionLabel(@Nonnull Player p) { 137 | return "&7Collects:"; 138 | } 139 | 140 | @Override 141 | protected void tick(Block b, BlockMenu inv) { 142 | 143 | //check water 144 | if (!Util.isWaterLogged(b)) { 145 | return; 146 | } 147 | 148 | //check input 149 | 150 | ItemStack strainer = inv.getItemInSlot(INPUT_SLOTS[0]); 151 | int speed = Strainer.getStrainer(strainer); 152 | 153 | if (speed == 0) { 154 | 155 | if (inv.hasViewer()) { 156 | inv.replaceExistingItem(STATUS_SLOT, new CustomItemStack(Material.BARRIER, "&cInput a Strainer!")); 157 | } 158 | 159 | return; 160 | } 161 | 162 | Random random = ThreadLocalRandom.current(); 163 | 164 | //progress 165 | 166 | if (random.nextInt(this.time / speed) != 0) { 167 | 168 | if (inv.hasViewer()) { 169 | inv.replaceExistingItem(STATUS_SLOT, new CustomItemStack(Material.LIME_STAINED_GLASS_PANE, "&aCollecting...")); 170 | } 171 | 172 | return; 173 | } 174 | 175 | //fish 176 | 177 | if (random.nextInt(10000) == 0) { 178 | inv.pushItem(POTATO, OUTPUT_SLOTS); 179 | } 180 | 181 | ItemStack output = OUTPUTS[random.nextInt(OUTPUTS.length)]; 182 | 183 | //check fits 184 | 185 | if (!inv.fits(output, OUTPUT_SLOTS)) { 186 | 187 | if (inv.hasViewer()) { 188 | inv.replaceExistingItem(STATUS_SLOT, NO_ROOM_ITEM); 189 | } 190 | 191 | return; 192 | } 193 | 194 | //output 195 | 196 | inv.pushItem(output.clone(), OUTPUT_SLOTS); 197 | 198 | if (inv.hasViewer()) { 199 | inv.replaceExistingItem(STATUS_SLOT, new CustomItemStack(Material.LIME_STAINED_GLASS_PANE, "&aMaterial Collected!")); 200 | } 201 | 202 | //reduce durability 203 | 204 | if (random.nextInt(strainer.getEnchantmentLevel(Enchantment.DURABILITY) + 3 * strainer.getEnchantmentLevel(Enchantment.MENDING) + 1) == 0) { 205 | ItemMeta itemMeta = strainer.getItemMeta(); 206 | Damageable durability = (Damageable) itemMeta; 207 | 208 | int current = durability.getDamage(); 209 | 210 | if (current + 1 == Material.FISHING_ROD.getMaxDurability()) { 211 | 212 | inv.consumeItem(INPUT_SLOTS[0]); 213 | 214 | } 215 | else { //reduce 216 | 217 | ((Damageable) itemMeta).setDamage(current + 1); 218 | strainer.setItemMeta(itemMeta); 219 | inv.replaceExistingItem(INPUT_SLOTS[0], strainer); 220 | 221 | } 222 | } 223 | } 224 | 225 | } 226 | -------------------------------------------------------------------------------- /src/main/java/io/github/mooy1/infinityexpansion/items/gear/InfinityArmor.java: -------------------------------------------------------------------------------- 1 | package io.github.mooy1.infinityexpansion.items.gear; 2 | 3 | import javax.annotation.Nonnull; 4 | 5 | import org.bukkit.NamespacedKey; 6 | import org.bukkit.inventory.ItemStack; 7 | import org.bukkit.potion.PotionEffect; 8 | 9 | import io.github.mooy1.infinityexpansion.InfinityExpansion; 10 | import io.github.mooy1.infinityexpansion.categories.Groups; 11 | import io.github.mooy1.infinityexpansion.items.blocks.InfinityWorkbench; 12 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; 13 | import io.github.thebusybiscuit.slimefun4.core.attributes.NotPlaceable; 14 | import io.github.thebusybiscuit.slimefun4.core.attributes.ProtectionType; 15 | import io.github.thebusybiscuit.slimefun4.core.attributes.ProtectiveArmor; 16 | import io.github.thebusybiscuit.slimefun4.core.attributes.Soulbound; 17 | import io.github.thebusybiscuit.slimefun4.implementation.items.armor.SlimefunArmorPiece; 18 | 19 | /** 20 | * armor 21 | * 22 | * @author Mooy1 23 | */ 24 | public final class InfinityArmor extends SlimefunArmorPiece implements ProtectiveArmor, Soulbound, NotPlaceable { 25 | 26 | private static final NamespacedKey KEY = InfinityExpansion.createKey("infinity_armor"); 27 | 28 | public InfinityArmor(SlimefunItemStack item, PotionEffect[] effects, ItemStack[] recipe) { 29 | super(Groups.INFINITY_CHEAT, item, InfinityWorkbench.TYPE, recipe, effects); 30 | } 31 | 32 | @Nonnull 33 | @Override 34 | public ProtectionType[] getProtectionTypes() { 35 | return new ProtectionType[] { 36 | ProtectionType.BEES, ProtectionType.RADIATION, ProtectionType.FLYING_INTO_WALL 37 | }; 38 | } 39 | 40 | @Override 41 | public boolean isFullSetRequired() { 42 | return false; 43 | } 44 | 45 | @Nonnull 46 | @Override 47 | public NamespacedKey getArmorSetId() { 48 | return KEY; 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/io/github/mooy1/infinityexpansion/items/gear/InfinityBow.java: -------------------------------------------------------------------------------- 1 | package io.github.mooy1.infinityexpansion.items.gear; 2 | 3 | import javax.annotation.Nonnull; 4 | import javax.annotation.ParametersAreNonnullByDefault; 5 | 6 | import org.bukkit.Effect; 7 | import org.bukkit.Material; 8 | import org.bukkit.entity.Player; 9 | import org.bukkit.inventory.ItemStack; 10 | import org.bukkit.potion.PotionEffect; 11 | import org.bukkit.potion.PotionEffectType; 12 | 13 | import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion; 14 | import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup; 15 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; 16 | import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; 17 | import io.github.thebusybiscuit.slimefun4.core.attributes.NotPlaceable; 18 | import io.github.thebusybiscuit.slimefun4.core.attributes.Soulbound; 19 | import io.github.thebusybiscuit.slimefun4.core.handlers.BowShootHandler; 20 | import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; 21 | import io.github.thebusybiscuit.slimefun4.implementation.items.weapons.ExplosiveBow; 22 | 23 | public final class InfinityBow extends ExplosiveBow implements NotPlaceable, Soulbound { 24 | 25 | @ParametersAreNonnullByDefault 26 | public InfinityBow(ItemGroup itemGroup, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { 27 | super(itemGroup, item, recipe); 28 | setRecipeType(recipeType); 29 | } 30 | 31 | @Nonnull 32 | @Override 33 | public BowShootHandler onShoot() { 34 | BowShootHandler explosive = super.onShoot(); 35 | return (e, target) -> { 36 | explosive.onHit(e, target); 37 | 38 | if (target instanceof Player) { 39 | Player p = (Player) target; 40 | 41 | // Fixes #3060 - Don't apply effects if the arrow was successfully blocked. 42 | if (p.isBlocking() && e.getFinalDamage() <= 0) { 43 | return; 44 | } 45 | 46 | if (Slimefun.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_17)) { 47 | p.setFreezeTicks(60); 48 | } 49 | } 50 | 51 | target.getWorld().playEffect(target.getLocation(), Effect.STEP_SOUND, Material.ICE); 52 | target.getWorld().playEffect(target.getEyeLocation(), Effect.STEP_SOUND, Material.ICE); 53 | target.addPotionEffect(new PotionEffect(PotionEffectType.SLOW, 20 * 2, 10)); 54 | target.addPotionEffect(new PotionEffect(PotionEffectType.JUMP, 20 * 2, -10)); 55 | }; 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/io/github/mooy1/infinityexpansion/items/gear/InfinityMatrix.java: -------------------------------------------------------------------------------- 1 | package io.github.mooy1.infinityexpansion.items.gear; 2 | 3 | import java.util.Iterator; 4 | import java.util.List; 5 | 6 | import javax.annotation.Nonnull; 7 | 8 | import org.bukkit.ChatColor; 9 | import org.bukkit.entity.Player; 10 | import org.bukkit.event.Listener; 11 | import org.bukkit.inventory.ItemStack; 12 | import org.bukkit.inventory.meta.ItemMeta; 13 | 14 | import io.github.mooy1.infinitylib.common.Events; 15 | import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup; 16 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; 17 | import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; 18 | import io.github.thebusybiscuit.slimefun4.core.attributes.NotPlaceable; 19 | import io.github.thebusybiscuit.slimefun4.core.attributes.Soulbound; 20 | import io.github.thebusybiscuit.slimefun4.core.handlers.ItemUseHandler; 21 | import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem; 22 | 23 | public final class InfinityMatrix extends SimpleSlimefunItem implements Listener, Soulbound, NotPlaceable { 24 | 25 | public InfinityMatrix(ItemGroup category, SlimefunItemStack item, RecipeType type, ItemStack[] recipe) { 26 | super(category, item, type, recipe); 27 | Events.registerListener(this); 28 | } 29 | 30 | private static void disableFlight(Player p) { 31 | p.sendMessage(ChatColor.RED + "Infinity Flight Disabled!"); 32 | p.setAllowFlight(false); 33 | } 34 | 35 | private static void enableFlight(Player p) { 36 | p.sendMessage(ChatColor.GREEN + "Infinity Flight Enabled!"); 37 | p.setAllowFlight(true); 38 | } 39 | 40 | @Nonnull 41 | @Override 42 | public ItemUseHandler getItemHandler() { 43 | return e -> { 44 | ItemStack item = e.getItem(); 45 | if (!item.hasItemMeta()) { 46 | return; 47 | } 48 | ItemMeta meta = item.getItemMeta(); 49 | if (!meta.hasLore()) { 50 | return; 51 | } 52 | List lore = meta.getLore(); 53 | 54 | Player p = e.getPlayer(); 55 | 56 | Iterator iterator = lore.listIterator(); 57 | 58 | while (iterator.hasNext()) { 59 | String line = iterator.next(); 60 | 61 | if (ChatColor.stripColor(line).contains("UUID: ")) { 62 | String uuid = ChatColor.stripColor(line).substring(6); 63 | 64 | if (!p.getUniqueId().toString().equals(uuid)) { 65 | p.sendMessage(ChatColor.YELLOW + "You do not own this matrix!"); 66 | return; 67 | } 68 | 69 | if (p.isSneaking()) { //remove owner 70 | iterator.remove(); 71 | meta.setLore(lore); 72 | item.setItemMeta(meta); 73 | p.sendMessage(ChatColor.GOLD + "Ownership removed!"); 74 | disableFlight(p); 75 | 76 | } 77 | else if (p.getAllowFlight()) { 78 | disableFlight(p); 79 | } 80 | else { 81 | enableFlight(p); 82 | } 83 | 84 | return; 85 | } 86 | } 87 | 88 | lore.add(ChatColor.GREEN + "UUID: " + p.getUniqueId()); 89 | meta.setLore(lore); 90 | item.setItemMeta(meta); 91 | p.sendMessage(ChatColor.GOLD + "Ownership claimed!"); 92 | enableFlight(p); 93 | }; 94 | } 95 | 96 | } -------------------------------------------------------------------------------- /src/main/java/io/github/mooy1/infinityexpansion/items/gear/InfinityTool.java: -------------------------------------------------------------------------------- 1 | package io.github.mooy1.infinityexpansion.items.gear; 2 | 3 | import org.bukkit.inventory.ItemStack; 4 | 5 | import io.github.mooy1.infinityexpansion.categories.Groups; 6 | import io.github.mooy1.infinityexpansion.items.blocks.InfinityWorkbench; 7 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem; 8 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; 9 | import io.github.thebusybiscuit.slimefun4.core.attributes.NotPlaceable; 10 | import io.github.thebusybiscuit.slimefun4.core.attributes.Soulbound; 11 | 12 | /** 13 | * tools 14 | * 15 | * @author Mooy1 16 | */ 17 | public final class InfinityTool extends SlimefunItem implements Soulbound, NotPlaceable { 18 | 19 | public InfinityTool(SlimefunItemStack stack, ItemStack[] recipe) { 20 | super(Groups.INFINITY_CHEAT, stack, InfinityWorkbench.TYPE, recipe); 21 | } 22 | 23 | } -------------------------------------------------------------------------------- /src/main/java/io/github/mooy1/infinityexpansion/items/gear/VeinMinerRune.java: -------------------------------------------------------------------------------- 1 | package io.github.mooy1.infinityexpansion.items.gear; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collection; 5 | import java.util.Collections; 6 | import java.util.HashSet; 7 | import java.util.List; 8 | import java.util.Objects; 9 | import java.util.Optional; 10 | import java.util.Set; 11 | import java.util.concurrent.ThreadLocalRandom; 12 | 13 | import javax.annotation.Nullable; 14 | 15 | import org.bukkit.Bukkit; 16 | import org.bukkit.ChatColor; 17 | import org.bukkit.Location; 18 | import org.bukkit.Material; 19 | import org.bukkit.NamespacedKey; 20 | import org.bukkit.Sound; 21 | import org.bukkit.World; 22 | import org.bukkit.block.Block; 23 | import org.bukkit.entity.Entity; 24 | import org.bukkit.entity.ExperienceOrb; 25 | import org.bukkit.entity.Item; 26 | import org.bukkit.entity.Player; 27 | import org.bukkit.event.EventHandler; 28 | import org.bukkit.event.Listener; 29 | import org.bukkit.event.block.BlockBreakEvent; 30 | import org.bukkit.event.entity.FoodLevelChangeEvent; 31 | import org.bukkit.event.player.PlayerDropItemEvent; 32 | import org.bukkit.inventory.ItemStack; 33 | import org.bukkit.inventory.meta.Damageable; 34 | import org.bukkit.inventory.meta.ItemMeta; 35 | import org.bukkit.persistence.PersistentDataContainer; 36 | import org.bukkit.persistence.PersistentDataType; 37 | 38 | import io.github.mooy1.infinityexpansion.InfinityExpansion; 39 | import io.github.mooy1.infinitylib.common.CoolDowns; 40 | import io.github.mooy1.infinitylib.common.Events; 41 | import io.github.mooy1.infinitylib.common.Scheduler; 42 | import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup; 43 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem; 44 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; 45 | import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; 46 | import io.github.thebusybiscuit.slimefun4.core.attributes.NotPlaceable; 47 | import io.github.thebusybiscuit.slimefun4.implementation.items.magical.runes.SoulboundRune; 48 | import me.mrCookieSlime.Slimefun.api.BlockStorage; 49 | 50 | /** 51 | * A VeinMiner rune, most code from {@link SoulboundRune} 52 | * 53 | * @author Mooy1 54 | */ 55 | public final class VeinMinerRune extends SlimefunItem implements Listener, NotPlaceable { 56 | 57 | private static final String[] ALLOWED = { 58 | "_ORE", "_LOG", "_WOOD", "GILDED", "SOUL", "GRAVEL", 59 | "MAGMA", "OBSIDIAN", "DIORITE", "ANDESITE", "GRANITE", "_LEAVES", 60 | "GLASS", "DIRT", "GRASS", "DEBRIS", "GLOWSTONE" 61 | }; 62 | private static final double RANGE = 1.5; 63 | private static final int MAX = 64; 64 | private static final String LORE = ChatColor.AQUA + "Veinminer - Crouch to use"; 65 | private static final NamespacedKey key = InfinityExpansion.createKey("vein_miner"); 66 | 67 | private final CoolDowns cooldowns = new CoolDowns(1000); 68 | private Block processing; 69 | 70 | public VeinMinerRune(ItemGroup category, SlimefunItemStack item, RecipeType type, ItemStack[] recipe) { 71 | super(category, item, type, recipe); 72 | Events.registerListener(this); 73 | } 74 | 75 | @EventHandler 76 | public void onDrop(PlayerDropItemEvent e) { 77 | if (isItem(e.getItemDrop().getItemStack()) && e.getItemDrop().getItemStack().getAmount() == 1) { 78 | Scheduler.run(20, () -> activate(e.getPlayer(), e.getItemDrop())); 79 | } 80 | } 81 | 82 | private void activate(Player p, Item rune) { 83 | // Being sure the entity is still valid and not picked up or whatsoever. 84 | if (!rune.isValid()) { 85 | return; 86 | } 87 | 88 | Location l = rune.getLocation(); 89 | Collection entities = Objects.requireNonNull(l.getWorld()).getNearbyEntities(l, RANGE, RANGE, RANGE, this::findCompatibleItem); 90 | Optional optional = entities.stream().findFirst(); 91 | 92 | if (optional.isPresent()) { 93 | 94 | Item item = (Item) optional.get(); 95 | ItemStack itemStack = item.getItemStack(); 96 | 97 | if (itemStack.getAmount() == 1) { 98 | // This lightning is just an effect, it deals no damage. 99 | l.getWorld().strikeLightningEffect(l); 100 | 101 | Scheduler.run(10, () -> { 102 | // Being sure entities are still valid and not picked up or whatsoever. 103 | if (rune.isValid() && item.isValid() && rune.getItemStack().getAmount() == 1) { 104 | 105 | l.getWorld().createExplosion(l, 0); 106 | l.getWorld().playSound(l, Sound.ENTITY_GENERIC_EXPLODE, 0.3F, 1); 107 | 108 | item.remove(); 109 | rune.remove(); 110 | 111 | setVeinMiner(itemStack, true); 112 | l.getWorld().dropItemNaturally(l, itemStack); 113 | 114 | p.sendMessage(ChatColor.GREEN + "Added Vein Miner to tool!"); 115 | } 116 | else { 117 | p.sendMessage(ChatColor.RED + "Failed to add vein miner!"); 118 | } 119 | }); 120 | 121 | } 122 | else { 123 | p.sendMessage(ChatColor.RED + "Failed to add vein miner!"); 124 | } 125 | } 126 | } 127 | 128 | private boolean findCompatibleItem(Entity entity) { 129 | if (entity instanceof Item) { 130 | Item item = (Item) entity; 131 | ItemStack stack = item.getItemStack(); 132 | return stack.getAmount() == 1 133 | && stack.getItemMeta() instanceof Damageable 134 | && !isVeinMiner(stack) && !isItem(stack); 135 | } 136 | 137 | return false; 138 | } 139 | 140 | public static boolean isVeinMiner(@Nullable ItemStack item) { 141 | if (item == null || !item.hasItemMeta()) { 142 | return false; 143 | } 144 | return item.getItemMeta().getPersistentDataContainer().has(key, PersistentDataType.BYTE); 145 | } 146 | 147 | public static void setVeinMiner(@Nullable ItemStack item, boolean makeVeinMiner) { 148 | if (item == null) { 149 | return; 150 | } 151 | 152 | ItemMeta meta = item.getItemMeta(); 153 | 154 | boolean isVeinMiner = isVeinMiner(item); 155 | 156 | PersistentDataContainer container = meta.getPersistentDataContainer(); 157 | 158 | if (makeVeinMiner && !isVeinMiner) { 159 | container.set(key, PersistentDataType.BYTE, (byte) 1); 160 | List lore; 161 | if (meta.hasLore()) { 162 | lore = meta.getLore(); 163 | } 164 | else { 165 | lore = new ArrayList<>(); 166 | } 167 | lore.add(LORE); 168 | meta.setLore(lore); 169 | item.setItemMeta(meta); 170 | } 171 | 172 | if (!makeVeinMiner && isVeinMiner) { 173 | container.remove(key); 174 | if (meta.hasLore()) { 175 | List lore = meta.getLore(); 176 | lore.remove(LORE); 177 | meta.setLore(lore); 178 | item.setItemMeta(meta); 179 | } 180 | } 181 | } 182 | 183 | @EventHandler 184 | public void onBlockBreak(BlockBreakEvent e) { 185 | Block b = e.getBlock(); 186 | 187 | if (this.processing == b) { 188 | return; 189 | } 190 | 191 | Player p = e.getPlayer(); 192 | 193 | if (!p.isSneaking()) { 194 | return; 195 | } 196 | 197 | ItemStack item = p.getInventory().getItemInMainHand(); 198 | 199 | if (!isVeinMiner(item)) { 200 | return; 201 | } 202 | 203 | if (p.getFoodLevel() == 0) { 204 | p.sendMessage(ChatColor.GOLD + "You are too tired to vein-mine!"); 205 | return; 206 | } 207 | 208 | String type = b.getType().toString(); 209 | 210 | if (!isAllowed(type)) { 211 | return; 212 | } 213 | 214 | Location l = b.getLocation(); 215 | 216 | if (BlockStorage.hasBlockInfo(l)) { 217 | return; 218 | } 219 | 220 | if (!this.cooldowns.checkAndReset(p.getUniqueId())) { 221 | p.sendMessage(ChatColor.GOLD + "You must wait 1 second before using again!"); 222 | return; 223 | } 224 | 225 | Set found = new HashSet<>(); 226 | Set checked = new HashSet<>(); 227 | checked.add(l); 228 | getVein(checked, found, l, b); 229 | 230 | World w = b.getWorld(); 231 | 232 | for (Block mine : found) { 233 | this.processing = mine; 234 | BlockBreakEvent event = new BlockBreakEvent(mine, p); 235 | Bukkit.getPluginManager().callEvent(event); 236 | if (!event.isCancelled()) { 237 | if (event.isDropItems()) { 238 | for (ItemStack drop : mine.getDrops(item)) { 239 | w.dropItemNaturally(l, drop); 240 | } 241 | } 242 | mine.setType(Material.AIR); 243 | } 244 | } 245 | 246 | if (type.endsWith("ORE")) { 247 | w.spawn(b.getLocation(), ExperienceOrb.class).setExperience(found.size() * 2); 248 | } 249 | 250 | if (ThreadLocalRandom.current().nextBoolean()) { 251 | FoodLevelChangeEvent event = new FoodLevelChangeEvent(p, p.getFoodLevel() - 1); 252 | Bukkit.getPluginManager().callEvent(event); 253 | if (!event.isCancelled()) { 254 | p.setFoodLevel(event.getFoodLevel()); 255 | } 256 | } 257 | } 258 | 259 | private static boolean isAllowed(String mat) { 260 | for (String test : ALLOWED) { 261 | if (mat.contains(test)) { 262 | return true; 263 | } 264 | } 265 | return false; 266 | } 267 | 268 | private static void getVein(Set checked, Set found, Location l, Block b) { 269 | if (found.size() >= MAX) { 270 | return; 271 | } 272 | 273 | for (Location check : getAdjacentLocations(l)) { 274 | if (checked.add(check) && check.getBlock().getType() == b.getType() && !BlockStorage.hasBlockInfo(b)) { 275 | found.add(b); 276 | getVein(checked, found, check, check.getBlock()); 277 | } 278 | } 279 | } 280 | 281 | private static List getAdjacentLocations(Location l) { 282 | List list = new ArrayList<>(); 283 | list.add(l.clone().add(1, 0, 0)); 284 | list.add(l.clone().add(-1, 0, 0)); 285 | list.add(l.clone().add(0, 1, 0)); 286 | list.add(l.clone().add(0, -1, 0)); 287 | list.add(l.clone().add(0, 0, 1)); 288 | list.add(l.clone().add(0, 0, -1)); 289 | Collections.shuffle(list); 290 | return list; 291 | } 292 | 293 | } 294 | -------------------------------------------------------------------------------- /src/main/java/io/github/mooy1/infinityexpansion/items/generators/EnergyGenerator.java: -------------------------------------------------------------------------------- 1 | package io.github.mooy1.infinityexpansion.items.generators; 2 | 3 | import javax.annotation.Nonnull; 4 | import javax.annotation.ParametersAreNonnullByDefault; 5 | 6 | import org.bukkit.Location; 7 | import org.bukkit.Material; 8 | import org.bukkit.inventory.ItemStack; 9 | 10 | import io.github.mooy1.infinitylib.machines.MachineLore; 11 | import io.github.mooy1.infinitylib.machines.MenuBlock; 12 | import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup; 13 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; 14 | import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; 15 | import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetProvider; 16 | import io.github.thebusybiscuit.slimefun4.core.networks.energy.EnergyNetComponentType; 17 | import io.github.thebusybiscuit.slimefun4.libraries.dough.items.CustomItemStack; 18 | import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config; 19 | import me.mrCookieSlime.Slimefun.api.BlockStorage; 20 | import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu; 21 | import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset; 22 | import me.mrCookieSlime.Slimefun.api.inventory.DirtyChestMenu; 23 | 24 | /** 25 | * Solar panels and some other basic generators 26 | * 27 | * @author Mooy1 28 | * 29 | * Thanks to panda for some stuff to work off of 30 | */ 31 | @ParametersAreNonnullByDefault 32 | public final class EnergyGenerator extends MenuBlock implements EnergyNetProvider { 33 | 34 | private final GenerationType type; 35 | private final int generation; 36 | 37 | public EnergyGenerator(ItemGroup category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, 38 | int generation, GenerationType type) { 39 | super(category, item, recipeType, recipe); 40 | this.type = type; 41 | this.generation = generation; 42 | } 43 | 44 | @Override 45 | protected void setup(BlockMenuPreset blockMenuPreset) { 46 | blockMenuPreset.drawBackground(new int[] { 47 | 0, 1, 2, 3, 4, 5, 6, 7, 8 48 | }); 49 | } 50 | 51 | @Nonnull 52 | @Override 53 | protected int[] getInputSlots(DirtyChestMenu dirtyChestMenu, ItemStack itemStack) { 54 | return new int[0]; 55 | } 56 | 57 | @Override 58 | protected int[] getInputSlots() { 59 | return new int[0]; 60 | } 61 | 62 | @Override 63 | protected int[] getOutputSlots() { 64 | return new int[0]; 65 | } 66 | 67 | @Override 68 | public int getGeneratedOutput(Location l, Config data) { 69 | int gen = this.type.generate(l.getWorld(), l.getBlock(), this.generation); 70 | 71 | BlockMenu inv = BlockStorage.getInventory(l); 72 | if (inv != null && inv.hasViewer()) { 73 | if (gen == 0) { 74 | inv.replaceExistingItem(4, new CustomItemStack( 75 | Material.GREEN_STAINED_GLASS_PANE, 76 | "&cNot generating", 77 | "&7Stored: &6" + MachineLore.format(getCharge(l)) + " J" 78 | )); 79 | } 80 | else { 81 | inv.replaceExistingItem(4, new CustomItemStack( 82 | Material.GREEN_STAINED_GLASS_PANE, 83 | "&aGeneration", 84 | "&7Type: &6" + this.type, 85 | "&7Generating: &6" + MachineLore.formatEnergy(gen) + " J/s ", 86 | "&7Stored: &6" + MachineLore.format(getCharge(l)) + " J" 87 | )); 88 | } 89 | } 90 | 91 | return gen; 92 | } 93 | 94 | @Override 95 | public int getCapacity() { 96 | return this.generation * 100; 97 | } 98 | 99 | @Nonnull 100 | @Override 101 | public EnergyNetComponentType getEnergyComponentType() { 102 | return EnergyNetComponentType.GENERATOR; 103 | } 104 | 105 | } 106 | -------------------------------------------------------------------------------- /src/main/java/io/github/mooy1/infinityexpansion/items/generators/GenerationType.java: -------------------------------------------------------------------------------- 1 | package io.github.mooy1.infinityexpansion.items.generators; 2 | 3 | import javax.annotation.Nonnull; 4 | 5 | import lombok.AllArgsConstructor; 6 | import lombok.Getter; 7 | 8 | import org.bukkit.World; 9 | import org.bukkit.block.Block; 10 | 11 | import io.github.mooy1.infinityexpansion.utils.Util; 12 | 13 | @AllArgsConstructor 14 | public enum GenerationType { 15 | 16 | HYDROELECTRIC("Hydroelectric") { 17 | @Override 18 | protected int generate(@Nonnull World world, @Nonnull Block block, int def) { 19 | return Util.isWaterLogged(block) ? def : 0; 20 | } 21 | }, 22 | GEOTHERMAL("Geothermal") { 23 | @Override 24 | protected int generate(@Nonnull World world, @Nonnull Block block, int def) { 25 | switch (world.getEnvironment()) { 26 | case NETHER: 27 | return def * 2; 28 | case NORMAL: 29 | return def; 30 | default: 31 | return 0; 32 | } 33 | } 34 | }, 35 | SOLAR("Day") { 36 | @Override 37 | protected int generate(@Nonnull World world, @Nonnull Block block, int def) { 38 | if (world.getEnvironment() == World.Environment.NORMAL 39 | && world.getTime() < 13000 40 | && block.getLocation().add(0, 1, 0).getBlock().getLightFromSky() == 15) { 41 | return def; 42 | } 43 | return 0; 44 | } 45 | }, 46 | LUNAR("Night") { 47 | @Override 48 | protected int generate(@Nonnull World world, @Nonnull Block block, int def) { 49 | switch (world.getEnvironment()) { 50 | case NETHER: 51 | case THE_END: 52 | return def; 53 | case NORMAL: { 54 | if (world.getTime() >= 13000 55 | || block.getLocation().add(0, 1, 0).getBlock().getLightFromSky() != 15) { 56 | return def; 57 | } 58 | return 0; 59 | } 60 | default: 61 | return 0; 62 | } 63 | } 64 | }, 65 | INFINITY("Infinity") { 66 | @Override 67 | protected int generate(@Nonnull World world, @Nonnull Block block, int def) { 68 | return def; 69 | } 70 | }; 71 | 72 | @Getter 73 | private final String toString; 74 | 75 | protected abstract int generate(@Nonnull World world, @Nonnull Block block, int def); 76 | 77 | } 78 | -------------------------------------------------------------------------------- /src/main/java/io/github/mooy1/infinityexpansion/items/generators/InfinityReactor.java: -------------------------------------------------------------------------------- 1 | package io.github.mooy1.infinityexpansion.items.generators; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import javax.annotation.Nonnull; 7 | import javax.annotation.ParametersAreNonnullByDefault; 8 | 9 | import org.bukkit.ChatColor; 10 | import org.bukkit.Location; 11 | import org.bukkit.Material; 12 | import org.bukkit.block.Block; 13 | import org.bukkit.inventory.ItemStack; 14 | 15 | import io.github.mooy1.infinityexpansion.items.materials.Materials; 16 | import io.github.mooy1.infinitylib.common.StackUtils; 17 | import io.github.mooy1.infinitylib.machines.MenuBlock; 18 | import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup; 19 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; 20 | import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; 21 | import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetProvider; 22 | import io.github.thebusybiscuit.slimefun4.core.attributes.RecipeDisplayItem; 23 | import io.github.thebusybiscuit.slimefun4.libraries.dough.items.CustomItemStack; 24 | import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config; 25 | import me.mrCookieSlime.Slimefun.api.BlockStorage; 26 | import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu; 27 | import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset; 28 | import me.mrCookieSlime.Slimefun.api.inventory.DirtyChestMenu; 29 | 30 | /** 31 | * A reactor that generates huge power but costs infinity ingots and void ingots 32 | * 33 | * @author Mooy1 34 | */ 35 | @ParametersAreNonnullByDefault 36 | public final class InfinityReactor extends MenuBlock implements EnergyNetProvider, RecipeDisplayItem { 37 | 38 | private static final int INFINITY_INTERVAL = 196000; 39 | private static final int VOID_INTERVAL = 32000; 40 | private static final int[] INPUT_SLOTS = { 10, 16 }; 41 | private static final int STATUS_SLOT = 13; 42 | 43 | private final int gen; 44 | 45 | public InfinityReactor(ItemGroup category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, int gen) { 46 | super(category, item, recipeType, recipe); 47 | this.gen = gen; 48 | } 49 | 50 | @Override 51 | protected void onNewInstance(@Nonnull BlockMenu menu, @Nonnull Block b) { 52 | if (BlockStorage.getLocationInfo(b.getLocation(), "progress") == null) { 53 | BlockStorage.addBlockInfo(b, "progress", "0"); 54 | } 55 | } 56 | 57 | @Override 58 | protected void setup(@Nonnull BlockMenuPreset blockMenuPreset) { 59 | blockMenuPreset.drawBackground(new CustomItemStack(Material.WHITE_STAINED_GLASS_PANE, 60 | "&fInfinity Ingot Input"), new int[] { 61 | 0, 1, 2, 62 | 9, 11, 63 | 18, 19, 20 64 | }); 65 | blockMenuPreset.drawBackground(new int[] { 66 | 3, 4, 5, 67 | 12, 13, 14, 68 | 21, 22, 23 69 | }); 70 | blockMenuPreset.drawBackground(new CustomItemStack(Material.BLACK_STAINED_GLASS_PANE, 71 | "&8Void Ingot Input"), new int[] { 72 | 6, 7, 8, 73 | 15, 17, 74 | 24, 25, 26 75 | }); 76 | } 77 | 78 | @Nonnull 79 | @Override 80 | public int[] getInputSlots(DirtyChestMenu menu, ItemStack item) { 81 | String input = StackUtils.getId(item); 82 | if (Materials.VOID_INGOT.getItemId().equals(input)) { 83 | return new int[] { INPUT_SLOTS[1] }; 84 | } 85 | else if (Materials.INFINITE_INGOT.getItemId().equals(input)) { 86 | return new int[] { INPUT_SLOTS[0] }; 87 | } 88 | else { 89 | return new int[0]; 90 | } 91 | } 92 | 93 | @Override 94 | protected int[] getInputSlots() { 95 | return INPUT_SLOTS; 96 | } 97 | 98 | @Override 99 | protected int[] getOutputSlots() { 100 | return new int[0]; 101 | } 102 | 103 | @Override 104 | public int getGeneratedOutput(@Nonnull Location l, @Nonnull Config config) { 105 | BlockMenu inv = BlockStorage.getInventory(l); 106 | 107 | int progress = Integer.parseInt(BlockStorage.getLocationInfo(l, "progress")); 108 | ItemStack infinityInput = inv.getItemInSlot(INPUT_SLOTS[0]); 109 | ItemStack voidInput = inv.getItemInSlot(INPUT_SLOTS[1]); 110 | 111 | if (progress == 0) { //need infinity + void 112 | 113 | if (infinityInput == null || !Materials.INFINITE_INGOT.getItemId().equals(StackUtils.getId(infinityInput))) { //wrong input 114 | 115 | if (inv.hasViewer()) { 116 | inv.replaceExistingItem(STATUS_SLOT, new CustomItemStack(Material.RED_STAINED_GLASS_PANE, "&cInput more &fInfinity Ingots")); 117 | } 118 | return 0; 119 | 120 | } 121 | 122 | if (voidInput == null || !Materials.VOID_INGOT.getItemId().equals(StackUtils.getId(voidInput))) { //wrong input 123 | 124 | if (inv.hasViewer()) { 125 | inv.replaceExistingItem(STATUS_SLOT, new CustomItemStack(Material.RED_STAINED_GLASS_PANE, "&cInput more &8Void Ingots")); 126 | } 127 | return 0; 128 | 129 | } 130 | 131 | //correct input 132 | if (inv.hasViewer()) { 133 | inv.replaceExistingItem(STATUS_SLOT, new CustomItemStack(Material.LIME_STAINED_GLASS_PANE, 134 | "&aStarting Generation", 135 | "&aTime until infinity ingot needed: " + INFINITY_INTERVAL, 136 | "&aTime until void ingot needed: " + VOID_INTERVAL 137 | )); 138 | } 139 | inv.consumeItem(INPUT_SLOTS[0]); 140 | inv.consumeItem(INPUT_SLOTS[1]); 141 | BlockStorage.addBlockInfo(l, "progress", "1"); 142 | return this.gen; 143 | 144 | } 145 | 146 | if (progress >= INFINITY_INTERVAL) { //done 147 | 148 | if (inv.hasViewer()) { 149 | inv.replaceExistingItem(STATUS_SLOT, new CustomItemStack(Material.LIME_STAINED_GLASS_PANE, "&aFinished Generation")); 150 | } 151 | BlockStorage.addBlockInfo(l, "progress", "0"); 152 | return this.gen; 153 | 154 | } 155 | 156 | if (Math.floorMod(progress, VOID_INTERVAL) == 0) { //need void 157 | 158 | if (voidInput == null || !Materials.VOID_INGOT.getItemId().equals(StackUtils.getId(voidInput))) { //wrong input 159 | 160 | if (inv.hasViewer()) { 161 | inv.replaceExistingItem(STATUS_SLOT, new CustomItemStack(Material.RED_STAINED_GLASS_PANE, "&cInput more &8Void Ingots")); 162 | } 163 | return 0; 164 | 165 | } 166 | 167 | //right input 168 | if (inv.hasViewer()) { 169 | inv.replaceExistingItem(STATUS_SLOT, new CustomItemStack(Material.LIME_STAINED_GLASS_PANE, 170 | "&aGenerating...", 171 | "&aTime until infinity ingot needed: " + (INFINITY_INTERVAL - progress), 172 | "&aTime until void ingot needed: " + (VOID_INTERVAL - Math.floorMod(progress, VOID_INTERVAL)) 173 | )); 174 | } 175 | BlockStorage.addBlockInfo(l, "progress", String.valueOf(progress + 1)); 176 | inv.consumeItem(INPUT_SLOTS[1]); 177 | return this.gen; 178 | 179 | } 180 | 181 | //generate 182 | 183 | if (inv.hasViewer()) { 184 | inv.replaceExistingItem(STATUS_SLOT, new CustomItemStack(Material.LIME_STAINED_GLASS_PANE, 185 | "&aGenerating...", 186 | "&aTime until infinity ingot needed: " + (INFINITY_INTERVAL - progress), 187 | "&aTime until void ingot needed: " + (VOID_INTERVAL - Math.floorMod(progress, VOID_INTERVAL)) 188 | ) 189 | ); 190 | } 191 | BlockStorage.addBlockInfo(l, "progress", String.valueOf(progress + 1)); 192 | return this.gen; 193 | } 194 | 195 | @Override 196 | public int getCapacity() { 197 | return this.gen * 1000; 198 | } 199 | 200 | @Nonnull 201 | @Override 202 | public List getDisplayRecipes() { 203 | List items = new ArrayList<>(); 204 | 205 | ItemStack item = new CustomItemStack(Materials.INFINITE_INGOT, Materials.INFINITE_INGOT.getDisplayName(), 206 | "", ChatColor.GOLD + "Lasts for 1 day"); 207 | items.add(item); 208 | items.add(null); 209 | 210 | item = new CustomItemStack(Materials.VOID_INGOT, Materials.VOID_INGOT.getDisplayName(), 211 | ChatColor.GOLD + "Lasts for 4 hours"); 212 | items.add(item); 213 | items.add(null); 214 | 215 | return items; 216 | } 217 | 218 | } 219 | -------------------------------------------------------------------------------- /src/main/java/io/github/mooy1/infinityexpansion/items/machines/GearTransformer.java: -------------------------------------------------------------------------------- 1 | package io.github.mooy1.infinityexpansion.items.machines; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import javax.annotation.Nonnull; 7 | import javax.annotation.Nullable; 8 | import javax.annotation.ParametersAreNonnullByDefault; 9 | 10 | import org.bukkit.Material; 11 | import org.bukkit.inventory.ItemStack; 12 | 13 | import io.github.mooy1.infinityexpansion.InfinityExpansion; 14 | import io.github.mooy1.infinityexpansion.items.abstracts.AbstractEnergyCrafter; 15 | import io.github.mooy1.infinitylib.common.StackUtils; 16 | import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup; 17 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; 18 | import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; 19 | import io.github.thebusybiscuit.slimefun4.core.attributes.RecipeDisplayItem; 20 | import io.github.thebusybiscuit.slimefun4.libraries.dough.collections.Pair; 21 | import io.github.thebusybiscuit.slimefun4.libraries.dough.items.CustomItemStack; 22 | import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu; 23 | import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset; 24 | 25 | /** 26 | * Machine that changes the material of gear and tools 27 | * 28 | * @author Mooy1 29 | */ 30 | @ParametersAreNonnullByDefault 31 | public final class GearTransformer extends AbstractEnergyCrafter implements RecipeDisplayItem { 32 | 33 | private static final boolean SF = InfinityExpansion.config().getBoolean("balance-options.allow-sf-item-transform"); 34 | private static final int[] OUTPUT_SLOTS = { 40 }; 35 | private static final int[] INPUT_SLOTS = { 10, 16 }; 36 | private static final int STATUS_SLOT = 13; 37 | private static final ItemStack[] TOOL_RECIPE = { 38 | new ItemStack(Material.OAK_PLANKS, 4), 39 | new ItemStack(Material.COBBLESTONE, 4), 40 | new ItemStack(Material.IRON_INGOT, 4), 41 | new ItemStack(Material.GOLD_INGOT, 4), 42 | new ItemStack(Material.DIAMOND, 4), 43 | new ItemStack(Material.NETHERITE_INGOT, 2) 44 | }; 45 | private static final ItemStack[] ARMOR_RECIPE = { 46 | new ItemStack(Material.LEATHER, 9), 47 | new ItemStack(Material.CHAIN, 9), 48 | new ItemStack(Material.IRON_INGOT, 9), 49 | new ItemStack(Material.GOLD_INGOT, 9), 50 | new ItemStack(Material.DIAMOND, 9), 51 | new ItemStack(Material.NETHERITE_INGOT, 2) 52 | }; 53 | private static final String[] ARMOR_TYPES = { 54 | "_HELMET", 55 | "_CHESTPLATE", 56 | "_LEGGINGS", 57 | "_BOOTS" 58 | }; 59 | private static final String[] TOOL_TYPES = { 60 | "_SWORD", 61 | "_PICKAXE", 62 | "_AXE", 63 | "_SHOVEL", 64 | "_HOE" 65 | }; 66 | private static final String[] TOOL_MATERIALS = { 67 | "WOODEN", 68 | "STONE", 69 | "IRON", 70 | "GOLDEN", 71 | "DIAMOND", 72 | "NETHERITE" 73 | }; 74 | private static final String[] ARMOR_MATERIALS = { 75 | "LEATHER", 76 | "CHAINMAIL", 77 | "IRON", 78 | "GOLDEN", 79 | "DIAMOND", 80 | "NETHERITE" 81 | }; 82 | 83 | public GearTransformer(ItemGroup category, SlimefunItemStack item, RecipeType type, ItemStack[] recipe, int energy) { 84 | super(category, item, type, recipe, energy, STATUS_SLOT); 85 | } 86 | 87 | @Override 88 | protected void setup(@Nonnull BlockMenuPreset blockMenuPreset) { 89 | blockMenuPreset.drawBackground(new int[] { 90 | 3, 4, 5, 91 | 12, STATUS_SLOT, 14, 92 | 21, 22 , 23, 93 | 27, 29, 33, 35, 94 | 36, 44, 95 | 45, 46, 47, 51, 52, 53 96 | }); 97 | blockMenuPreset.drawBackground(OUTPUT_BORDER, new int[] { 98 | 28, 30, 31, 32, 34, 99 | 37, 38, 39, 41, 42, 43, 100 | 48, 49, 50 101 | }); 102 | blockMenuPreset.drawBackground(new CustomItemStack(Material.BLUE_STAINED_GLASS_PANE, "&9Tool Input"), new int[] { 103 | 0, 1, 2, 104 | 9, 11, 105 | 18, 19, 20 106 | }); 107 | blockMenuPreset.drawBackground(new CustomItemStack(Material.BLUE_STAINED_GLASS_PANE, "&9Material Input"), new int[] { 108 | 6, 7, 8, 109 | 15, 17, 110 | 24, 25, 26 111 | }); 112 | } 113 | 114 | @Override 115 | protected int[] getInputSlots() { 116 | return INPUT_SLOTS; 117 | } 118 | 119 | @Override 120 | protected int[] getOutputSlots() { 121 | return OUTPUT_SLOTS; 122 | } 123 | 124 | @Nullable 125 | private static Pair getOutput(ItemStack inputMaterial, String inputToolType) { 126 | 127 | for (String toolType : TOOL_TYPES) { 128 | if (inputToolType.equals(toolType)) { //make sure its a tool 129 | 130 | for (int i = 0 ; i < TOOL_RECIPE.length ; i++) { //compare to each recipe 131 | ItemStack recipe = TOOL_RECIPE[i]; 132 | 133 | if (inputMaterial.getType() == recipe.getType() && inputMaterial.getAmount() >= recipe.getAmount()) { 134 | 135 | return new Pair<>(Material.getMaterial(TOOL_MATERIALS[i] + toolType), recipe.getAmount()); 136 | } 137 | } 138 | 139 | break; 140 | } 141 | } 142 | 143 | for (String armorType : ARMOR_TYPES) { 144 | if (inputToolType.equals(armorType)) { //make sure its a armor 145 | 146 | for (int i = 0 ; i < ARMOR_RECIPE.length ; i++) { //compare to each recipe 147 | ItemStack recipe = ARMOR_RECIPE[i]; 148 | 149 | if (inputMaterial.getType() == recipe.getType() && inputMaterial.getAmount() >= recipe.getAmount()) { 150 | 151 | return new Pair<>(Material.getMaterial(ARMOR_MATERIALS[i] + armorType), recipe.getAmount()); 152 | } 153 | } 154 | 155 | break; 156 | } 157 | } 158 | 159 | return null; 160 | } 161 | 162 | @Nullable 163 | private static String getType(ItemStack item) { 164 | Material material = item.getType(); 165 | 166 | for (String armorType : ARMOR_TYPES) { 167 | 168 | for (String armorMaterial : ARMOR_MATERIALS) { 169 | 170 | if (material == Material.getMaterial(armorMaterial + armorType)) { 171 | return armorType; 172 | } 173 | } 174 | } 175 | 176 | for (String toolType : TOOL_TYPES) { 177 | 178 | for (String toolMaterial : TOOL_MATERIALS) { 179 | 180 | if (material == Material.getMaterial(toolMaterial + toolType)) { 181 | return toolType; 182 | } 183 | } 184 | } 185 | return null; 186 | 187 | } 188 | 189 | @Nonnull 190 | @Override 191 | public List getDisplayRecipes() { 192 | List items = new ArrayList<>(); 193 | 194 | for (int i = 0 ; i < TOOL_RECIPE.length ; i++) { 195 | items.add(TOOL_RECIPE[i]); 196 | items.add(ARMOR_RECIPE[i]); 197 | } 198 | 199 | return items; 200 | } 201 | 202 | @Override 203 | public void update(@Nonnull BlockMenu inv) { 204 | ItemStack inputItem = inv.getItemInSlot(INPUT_SLOTS[0]); 205 | 206 | if (inputItem == null) { //no input 207 | 208 | inv.replaceExistingItem(STATUS_SLOT, new CustomItemStack(Material.BLUE_STAINED_GLASS_PANE, "&9Input a tool or piece of gear")); 209 | return; 210 | 211 | } 212 | 213 | if (!SF && StackUtils.getId(inputItem) != null) { 214 | inv.replaceExistingItem(STATUS_SLOT, new CustomItemStack(Material.RED_STAINED_GLASS_PANE, "&cSlimefun items may not have their material changed!")); 215 | return; 216 | } 217 | 218 | String inputToolType = getType(inputItem); 219 | 220 | if (inputToolType == null) { //invalid input 221 | 222 | inv.replaceExistingItem(STATUS_SLOT, new CustomItemStack(Material.BARRIER, "&cNot a tool or piece of gear!")); 223 | return; 224 | 225 | } 226 | 227 | ItemStack inputMaterial = inv.getItemInSlot(INPUT_SLOTS[1]); 228 | 229 | if (inputMaterial == null) { //no material 230 | 231 | inv.replaceExistingItem(STATUS_SLOT, new CustomItemStack(Material.BLUE_STAINED_GLASS_PANE, "&9Input materials")); 232 | return; 233 | 234 | } 235 | 236 | Pair pair = getOutput(inputMaterial, inputToolType); 237 | 238 | if (pair == null) { //invalid material 239 | 240 | inv.replaceExistingItem(STATUS_SLOT, new CustomItemStack(Material.BARRIER, "&cInvalid Materials!")); 241 | return; 242 | 243 | } 244 | 245 | if (inv.getItemInSlot(OUTPUT_SLOTS[0]) != null) { //valid material, not enough room 246 | 247 | inv.replaceExistingItem(STATUS_SLOT, NO_ROOM_ITEM); 248 | return; 249 | 250 | } 251 | 252 | //output 253 | setCharge(inv.getLocation(), 0); 254 | 255 | inputItem.setType(pair.getFirstValue()); 256 | inv.pushItem(inputItem, OUTPUT_SLOTS); 257 | 258 | inv.replaceExistingItem(INPUT_SLOTS[0], null); 259 | inv.consumeItem(INPUT_SLOTS[1], pair.getSecondValue()); 260 | 261 | inv.replaceExistingItem(STATUS_SLOT, new CustomItemStack(Material.LIME_STAINED_GLASS_PANE, "&aTool Transformed!")); 262 | } 263 | 264 | } 265 | -------------------------------------------------------------------------------- /src/main/java/io/github/mooy1/infinityexpansion/items/machines/GeoQuarry.java: -------------------------------------------------------------------------------- 1 | package io.github.mooy1.infinityexpansion.items.machines; 2 | 3 | import java.util.HashMap; 4 | import java.util.LinkedList; 5 | import java.util.List; 6 | import java.util.Map; 7 | 8 | import javax.annotation.Nonnull; 9 | import javax.annotation.ParametersAreNonnullByDefault; 10 | 11 | import lombok.Setter; 12 | 13 | import org.bukkit.Material; 14 | import org.bukkit.World; 15 | import org.bukkit.block.Biome; 16 | import org.bukkit.block.Block; 17 | import org.bukkit.inventory.ItemStack; 18 | 19 | import io.github.mooy1.infinityexpansion.InfinityExpansion; 20 | import io.github.mooy1.infinitylib.machines.AbstractMachineBlock; 21 | import io.github.thebusybiscuit.slimefun4.api.geo.GEOResource; 22 | import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup; 23 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; 24 | import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; 25 | import io.github.thebusybiscuit.slimefun4.core.attributes.RecipeDisplayItem; 26 | import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; 27 | import io.github.thebusybiscuit.slimefun4.libraries.dough.collections.Pair; 28 | import io.github.thebusybiscuit.slimefun4.libraries.dough.collections.RandomizedSet; 29 | import io.github.thebusybiscuit.slimefun4.libraries.dough.items.CustomItemStack; 30 | import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu; 31 | import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset; 32 | 33 | @ParametersAreNonnullByDefault 34 | public final class GeoQuarry extends AbstractMachineBlock implements RecipeDisplayItem { 35 | 36 | private static final int STATUS = 4; 37 | private static final int[] OUTPUT_SLOTS = { 29, 30, 31, 32, 33, 38, 39, 40, 41, 42 }; 38 | 39 | private final Map, RandomizedSet> recipes = new HashMap<>(); 40 | @Setter 41 | private int ticksPerOutput; 42 | 43 | public GeoQuarry(ItemGroup category, SlimefunItemStack item, RecipeType type, ItemStack[] recipe) { 44 | super(category, item, type, recipe); 45 | } 46 | 47 | @Override 48 | protected void setup(@Nonnull BlockMenuPreset blockMenuPreset) { 49 | blockMenuPreset.drawBackground(new int[] { 50 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 26, 27, 35, 36, 44, 45, 53 51 | }); 52 | blockMenuPreset.drawBackground(OUTPUT_BORDER, new int[] { 53 | 19, 20, 21, 22, 23, 24, 25, 28, 34, 37, 43, 46, 47, 48, 49, 50, 51, 52 54 | }); 55 | } 56 | 57 | @Override 58 | protected int[] getInputSlots() { 59 | return new int[0]; 60 | } 61 | 62 | @Override 63 | protected int[] getOutputSlots() { 64 | return OUTPUT_SLOTS; 65 | } 66 | 67 | @Override 68 | public void onNewInstance(@Nonnull BlockMenu menu, @Nonnull Block b) { 69 | 70 | } 71 | 72 | @Override 73 | protected boolean process(Block b, BlockMenu inv) { 74 | if (InfinityExpansion.slimefunTickCount() % this.ticksPerOutput != 0) { 75 | if (inv.hasViewer()) { 76 | inv.replaceExistingItem(STATUS, new CustomItemStack(Material.LIME_STAINED_GLASS_PANE, "&aDrilling...")); 77 | } 78 | return true; 79 | } 80 | 81 | ItemStack output = this.recipes.computeIfAbsent(new Pair<>(b.getBiome(), b.getWorld().getEnvironment()), k -> { 82 | RandomizedSet set = new RandomizedSet<>(); 83 | for (GEOResource resource : Slimefun.getRegistry().getGEOResources().values()) { 84 | if (resource.isObtainableFromGEOMiner()) { 85 | int supply = resource.getDefaultSupply(b.getWorld().getEnvironment(), b.getBiome()); 86 | if (supply > 0) { 87 | set.add(resource.getItem(), supply); 88 | } 89 | } 90 | } 91 | return set; 92 | }).getRandom(); 93 | 94 | if (!inv.fits(output, OUTPUT_SLOTS)) { 95 | if (inv.hasViewer()) { 96 | inv.replaceExistingItem(STATUS, NO_ROOM_ITEM); 97 | } 98 | return false; 99 | } 100 | 101 | inv.pushItem(output.clone(), OUTPUT_SLOTS); 102 | if (inv.hasViewer()) { 103 | inv.replaceExistingItem(STATUS, new CustomItemStack(Material.LIME_STAINED_GLASS_PANE, "&aFound!")); 104 | } 105 | return true; 106 | } 107 | 108 | @Override 109 | protected int getStatusSlot() { 110 | return STATUS; 111 | } 112 | 113 | @Nonnull 114 | @Override 115 | public List getDisplayRecipes() { 116 | List displayRecipes = new LinkedList<>(); 117 | 118 | for (GEOResource resource : Slimefun.getRegistry().getGEOResources().values()) { 119 | if (resource.isObtainableFromGEOMiner()) { 120 | displayRecipes.add(resource.getItem()); 121 | } 122 | } 123 | 124 | return displayRecipes; 125 | } 126 | 127 | } 128 | -------------------------------------------------------------------------------- /src/main/java/io/github/mooy1/infinityexpansion/items/machines/GrowingMachine.java: -------------------------------------------------------------------------------- 1 | package io.github.mooy1.infinityexpansion.items.machines; 2 | 3 | import java.util.ArrayList; 4 | import java.util.EnumMap; 5 | import java.util.List; 6 | import java.util.Map; 7 | 8 | import javax.annotation.Nonnull; 9 | 10 | import lombok.Setter; 11 | 12 | import org.bukkit.Material; 13 | import org.bukkit.block.Block; 14 | import org.bukkit.inventory.ItemStack; 15 | 16 | import io.github.mooy1.infinityexpansion.InfinityExpansion; 17 | import io.github.mooy1.infinitylib.machines.AbstractMachineBlock; 18 | import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup; 19 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; 20 | import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; 21 | import io.github.thebusybiscuit.slimefun4.core.attributes.RecipeDisplayItem; 22 | import io.github.thebusybiscuit.slimefun4.libraries.dough.items.CustomItemStack; 23 | import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu; 24 | import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset; 25 | 26 | public final class GrowingMachine extends AbstractMachineBlock implements RecipeDisplayItem { 27 | 28 | private static final int[] OUTPUT_SLOTS = { 29 | 13, 14, 15, 16, 30 | 22, 23, 24, 25, 31 | 31, 32, 33, 34, 32 | 40, 41, 42, 43 33 | }; 34 | private static final int[] INPUT_SLOTS = { 37 }; 35 | private static final int STATUS_SLOT = 10; 36 | private static final ItemStack GROWING = new CustomItemStack(Material.LIME_STAINED_GLASS_PANE, "&aGrowing..."); 37 | private static final ItemStack INPUT_PLANT = new CustomItemStack(Material.BLUE_STAINED_GLASS_PANE, "&9Input a plant!"); 38 | 39 | @Setter 40 | private EnumMap recipes; 41 | @Setter 42 | private int ticksPerOutput; 43 | 44 | public GrowingMachine(ItemGroup category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { 45 | super(category, item, recipeType, recipe); 46 | } 47 | 48 | @Override 49 | protected boolean process(@Nonnull Block b, @Nonnull BlockMenu menu) { 50 | ItemStack input = menu.getItemInSlot(INPUT_SLOTS[0]); 51 | if (input != null && this.recipes.containsKey(input.getType())) { 52 | if (menu.hasViewer()) { 53 | menu.replaceExistingItem(STATUS_SLOT, GROWING); 54 | } 55 | if (InfinityExpansion.slimefunTickCount() % this.ticksPerOutput == 0) { 56 | ItemStack[] output = this.recipes.get(input.getType()); 57 | if (output != null) { 58 | for (ItemStack item : output) { 59 | menu.pushItem(item.clone(), OUTPUT_SLOTS); 60 | } 61 | } 62 | } 63 | return true; 64 | } 65 | else { 66 | if (menu.hasViewer()) { 67 | menu.replaceExistingItem(STATUS_SLOT, INPUT_PLANT); 68 | } 69 | return false; 70 | } 71 | } 72 | 73 | @Override 74 | protected int getStatusSlot() { 75 | return STATUS_SLOT; 76 | } 77 | 78 | @Override 79 | protected void setup(@Nonnull BlockMenuPreset blockMenuPreset) { 80 | blockMenuPreset.drawBackground(new int[] { 81 | 0, 1, 2, 9, 10, 11, 18, 19, 20 82 | }); 83 | blockMenuPreset.drawBackground(INPUT_BORDER, new int[] { 84 | 27, 28, 29, 36, 38, 45, 46, 47 85 | }); 86 | blockMenuPreset.drawBackground(OUTPUT_BORDER, new int[] { 87 | 3, 4, 5, 6, 7, 8, 88 | 12, 17, 89 | 21, 26, 90 | 30, 35, 91 | 39, 44, 92 | 48, 49, 50, 51, 52, 53 93 | }); 94 | } 95 | 96 | @Nonnull 97 | @Override 98 | public List getDisplayRecipes() { 99 | List list = new ArrayList<>(); 100 | for (Map.Entry entry : this.recipes.entrySet()) { 101 | ItemStack in = new ItemStack(entry.getKey()); 102 | for (ItemStack item : entry.getValue()) { 103 | list.add(in); 104 | list.add(item); 105 | } 106 | } 107 | return list; 108 | } 109 | 110 | @Override 111 | protected int[] getInputSlots() { 112 | return INPUT_SLOTS; 113 | } 114 | 115 | @Override 116 | protected int[] getOutputSlots() { 117 | return OUTPUT_SLOTS; 118 | } 119 | 120 | } 121 | -------------------------------------------------------------------------------- /src/main/java/io/github/mooy1/infinityexpansion/items/machines/MaterialGenerator.java: -------------------------------------------------------------------------------- 1 | package io.github.mooy1.infinityexpansion.items.machines; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import javax.annotation.Nonnull; 7 | 8 | import lombok.Setter; 9 | 10 | import org.bukkit.Material; 11 | import org.bukkit.block.Block; 12 | import org.bukkit.entity.Player; 13 | import org.bukkit.inventory.ItemStack; 14 | 15 | import io.github.mooy1.infinitylib.machines.AbstractMachineBlock; 16 | import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup; 17 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; 18 | import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; 19 | import io.github.thebusybiscuit.slimefun4.core.attributes.RecipeDisplayItem; 20 | import io.github.thebusybiscuit.slimefun4.libraries.dough.items.CustomItemStack; 21 | import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu; 22 | import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset; 23 | 24 | /** 25 | * Machines that generate materials at the cost of energy 26 | * 27 | * @author Mooy1 28 | */ 29 | public final class MaterialGenerator extends AbstractMachineBlock implements RecipeDisplayItem { 30 | 31 | private static final int[] OUTPUT_SLOTS = { 13 }; 32 | private static final int STATUS_SLOT = 4; 33 | 34 | @Setter 35 | private int speed; 36 | @Setter 37 | private Material material; 38 | 39 | public MaterialGenerator(ItemGroup category, SlimefunItemStack item, RecipeType type, ItemStack[] recipe) { 40 | super(category, item, type, recipe); 41 | } 42 | 43 | @Override 44 | protected void setup(@Nonnull BlockMenuPreset blockMenuPreset) { 45 | blockMenuPreset.drawBackground(new int[] { 46 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 47 | 9, 10, 11, 12, 14, 15, 16, 17 48 | }); 49 | } 50 | 51 | @Override 52 | protected int getStatusSlot() { 53 | return STATUS_SLOT; 54 | } 55 | 56 | @Override 57 | protected int[] getInputSlots() { 58 | return new int[0]; 59 | } 60 | 61 | @Override 62 | protected int[] getOutputSlots() { 63 | return OUTPUT_SLOTS; 64 | } 65 | 66 | @Override 67 | public void onNewInstance(@Nonnull BlockMenu menu, @Nonnull Block b) { 68 | 69 | } 70 | 71 | @Nonnull 72 | @Override 73 | public List getDisplayRecipes() { 74 | List items = new ArrayList<>(); 75 | items.add(null); 76 | items.add(new ItemStack(this.material, this.speed)); 77 | return items; 78 | } 79 | 80 | @Nonnull 81 | @Override 82 | public String getRecipeSectionLabel(@Nonnull Player p) { 83 | return "&7Generates"; 84 | } 85 | 86 | @Override 87 | protected boolean process(@Nonnull Block b, @Nonnull BlockMenu inv) { 88 | ItemStack output = new ItemStack(this.material, this.speed); 89 | 90 | if (!inv.fits(output, OUTPUT_SLOTS)) { 91 | 92 | if (inv.hasViewer()) { 93 | inv.replaceExistingItem(STATUS_SLOT, NO_ROOM_ITEM); 94 | } 95 | return false; 96 | 97 | } 98 | 99 | inv.pushItem(output, OUTPUT_SLOTS); 100 | 101 | if (inv.hasViewer()) { 102 | inv.replaceExistingItem(STATUS_SLOT, new CustomItemStack(Material.LIME_STAINED_GLASS_PANE, "&aGenerating...")); 103 | } 104 | 105 | return true; 106 | } 107 | 108 | } 109 | -------------------------------------------------------------------------------- /src/main/java/io/github/mooy1/infinityexpansion/items/machines/PoweredBedrock.java: -------------------------------------------------------------------------------- 1 | package io.github.mooy1.infinityexpansion.items.machines; 2 | 3 | import javax.annotation.Nonnull; 4 | 5 | import org.bukkit.Location; 6 | import org.bukkit.Material; 7 | import org.bukkit.block.Block; 8 | import org.bukkit.inventory.ItemStack; 9 | 10 | import io.github.mooy1.infinityexpansion.InfinityExpansion; 11 | import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup; 12 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem; 13 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; 14 | import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; 15 | import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetComponent; 16 | import io.github.thebusybiscuit.slimefun4.core.networks.energy.EnergyNetComponentType; 17 | import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config; 18 | import me.mrCookieSlime.Slimefun.Objects.handlers.BlockTicker; 19 | 20 | /** 21 | * A block that becomes bedrock when powered, for decoration of course 22 | * 23 | * @author Mooy1 24 | */ 25 | public final class PoweredBedrock extends SlimefunItem implements EnergyNetComponent { 26 | 27 | private final int energy; 28 | 29 | public PoweredBedrock(ItemGroup category, SlimefunItemStack item, RecipeType type, ItemStack[] recipe, int energy) { 30 | super(category, item, type, recipe); 31 | this.energy = energy; 32 | 33 | addItemHandler(new BlockTicker() { 34 | @Override 35 | public boolean isSynchronized() { 36 | return true; 37 | } 38 | 39 | @Override 40 | public void tick(Block b, SlimefunItem item, Config data) { 41 | if (InfinityExpansion.slimefunTickCount() % 8 == 0) { 42 | return; 43 | } 44 | Location l = b.getLocation(); 45 | if (getCharge(l) < energy) { 46 | if (b.getType() != Material.NETHERITE_BLOCK) { 47 | b.setType(Material.NETHERITE_BLOCK); 48 | return; 49 | } 50 | } 51 | else if (b.getType() != Material.BEDROCK) { 52 | b.setType(Material.BEDROCK); 53 | } 54 | removeCharge(l, energy); 55 | } 56 | }); 57 | } 58 | 59 | @Nonnull 60 | @Override 61 | public EnergyNetComponentType getEnergyComponentType() { 62 | return EnergyNetComponentType.CONSUMER; 63 | } 64 | 65 | @Override 66 | public int getCapacity() { 67 | return this.energy * 2; 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/io/github/mooy1/infinityexpansion/items/machines/ResourceSynthesizer.java: -------------------------------------------------------------------------------- 1 | package io.github.mooy1.infinityexpansion.items.machines; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import javax.annotation.Nonnull; 7 | 8 | import lombok.Setter; 9 | 10 | import org.bukkit.Material; 11 | import org.bukkit.block.Block; 12 | import org.bukkit.inventory.ItemStack; 13 | 14 | import io.github.mooy1.infinitylib.common.StackUtils; 15 | import io.github.mooy1.infinitylib.machines.AbstractMachineBlock; 16 | import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup; 17 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; 18 | import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; 19 | import io.github.thebusybiscuit.slimefun4.core.attributes.RecipeDisplayItem; 20 | import io.github.thebusybiscuit.slimefun4.libraries.dough.items.CustomItemStack; 21 | import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu; 22 | import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset; 23 | 24 | /** 25 | * Creates special resources from the combination of singularities 26 | * 27 | * @author Mooy1 28 | */ 29 | public final class ResourceSynthesizer extends AbstractMachineBlock implements RecipeDisplayItem { 30 | 31 | private static final int[] OUTPUT_SLOTS = { 32 | 40 33 | }; 34 | private static final int[] INPUT_SLOTS = { 35 | 10, 16 36 | }; 37 | private static final int STATUS_SLOT = 13; 38 | 39 | @Setter 40 | private SlimefunItemStack[] recipes; 41 | 42 | public ResourceSynthesizer(ItemGroup category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { 43 | super(category, item, recipeType, recipe); 44 | } 45 | 46 | @Override 47 | protected int getStatusSlot() { 48 | return STATUS_SLOT; 49 | } 50 | 51 | @Override 52 | protected void setup(@Nonnull BlockMenuPreset blockMenuPreset) { 53 | blockMenuPreset.drawBackground(new int[] { 54 | 3, 4, 5, 55 | 12, 13, 14, 56 | 21, 22, 23, 57 | 27, 29, 33, 35, 58 | 36, 44, 59 | 45, 46, 47, 51, 52, 53 60 | }); 61 | blockMenuPreset.drawBackground(INPUT_BORDER, new int[] { 62 | 0, 1, 2, 6, 7, 8, 63 | 9, 11, 15, 17, 64 | 18, 19, 20, 24, 25, 26 65 | }); 66 | blockMenuPreset.drawBackground(OUTPUT_BORDER, new int[] { 67 | 28, 34, 37, 38, 42, 43, 68 | 30, 31, 32, 69 | 39, 41, 70 | 48, 49, 50 71 | }); 72 | } 73 | 74 | @Override 75 | protected int[] getInputSlots() { 76 | return INPUT_SLOTS; 77 | } 78 | 79 | @Override 80 | protected int[] getOutputSlots() { 81 | return OUTPUT_SLOTS; 82 | } 83 | 84 | @Nonnull 85 | @Override 86 | public List getDisplayRecipes() { 87 | final List items = new ArrayList<>(); 88 | 89 | for (int i = 0 ; i < this.recipes.length ; i += 3) { 90 | items.add(this.recipes[i]); 91 | items.add(this.recipes[i + 2]); 92 | items.add(this.recipes[i + 1]); 93 | items.add(this.recipes[i + 2]); 94 | } 95 | 96 | return items; 97 | } 98 | 99 | @Override 100 | protected boolean process(@Nonnull Block b, @Nonnull BlockMenu inv) { 101 | 102 | ItemStack input1 = inv.getItemInSlot(INPUT_SLOTS[0]); 103 | ItemStack input2 = inv.getItemInSlot(INPUT_SLOTS[1]); 104 | 105 | if (input1 == null || input2 == null) { //no input 106 | 107 | if (inv.hasViewer()) { 108 | inv.replaceExistingItem(STATUS_SLOT, IDLE_ITEM); 109 | } 110 | return false; 111 | 112 | } 113 | 114 | String id1 = StackUtils.getId(input1); 115 | 116 | if (id1 == null) { 117 | return false; 118 | } 119 | 120 | String id2 = StackUtils.getId(input2); 121 | 122 | if (id2 == null) { 123 | return false; 124 | } 125 | 126 | ItemStack recipe = null; 127 | 128 | for (int i = 0 ; i < this.recipes.length ; i += 3) { 129 | if ((id1.equals(this.recipes[i].getItemId()) && id2.equals(this.recipes[i + 1].getItemId()) || (id2.equals(this.recipes[i].getItemId()) && id1.equals(this.recipes[i + 1].getItemId())))) { 130 | recipe = this.recipes[i + 2]; 131 | } 132 | } 133 | 134 | if (recipe == null) { //invalid recipe 135 | 136 | if (inv.hasViewer()) { 137 | inv.replaceExistingItem(STATUS_SLOT, IDLE_ITEM); 138 | } 139 | return false; 140 | 141 | } 142 | 143 | recipe = recipe.clone(); 144 | 145 | if (inv.fits(recipe, OUTPUT_SLOTS)) { //no item 146 | 147 | inv.pushItem(recipe, OUTPUT_SLOTS); 148 | inv.consumeItem(INPUT_SLOTS[0], 1); 149 | inv.consumeItem(INPUT_SLOTS[1], 1); 150 | 151 | if (inv.hasViewer()) { 152 | inv.replaceExistingItem(STATUS_SLOT, new CustomItemStack(Material.LIME_STAINED_GLASS_PANE, "&aResource Synthesized!")); 153 | } 154 | return true; 155 | 156 | } 157 | else { //not enough room 158 | 159 | if (inv.hasViewer()) { 160 | inv.replaceExistingItem(STATUS_SLOT, NO_ROOM_ITEM); 161 | } 162 | return false; 163 | 164 | } 165 | } 166 | 167 | } 168 | -------------------------------------------------------------------------------- /src/main/java/io/github/mooy1/infinityexpansion/items/machines/SingularityConstructor.java: -------------------------------------------------------------------------------- 1 | package io.github.mooy1.infinityexpansion.items.machines; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | import java.util.List; 6 | import java.util.Map; 7 | 8 | import javax.annotation.Nonnull; 9 | import javax.annotation.Nullable; 10 | 11 | import lombok.AllArgsConstructor; 12 | import lombok.Setter; 13 | 14 | import org.bukkit.Location; 15 | import org.bukkit.Material; 16 | import org.bukkit.block.Block; 17 | import org.bukkit.event.block.BlockBreakEvent; 18 | import org.bukkit.inventory.ItemStack; 19 | 20 | import io.github.mooy1.infinityexpansion.InfinityExpansion; 21 | import io.github.mooy1.infinityexpansion.utils.Util; 22 | import io.github.mooy1.infinitylib.common.StackUtils; 23 | import io.github.mooy1.infinitylib.machines.AbstractMachineBlock; 24 | import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup; 25 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; 26 | import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; 27 | import io.github.thebusybiscuit.slimefun4.core.attributes.RecipeDisplayItem; 28 | import io.github.thebusybiscuit.slimefun4.libraries.dough.collections.Pair; 29 | import io.github.thebusybiscuit.slimefun4.libraries.dough.items.CustomItemStack; 30 | import me.mrCookieSlime.Slimefun.api.BlockStorage; 31 | import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu; 32 | import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset; 33 | 34 | /** 35 | * Constructs singularities form many items 36 | * 37 | * @author Mooy1 38 | */ 39 | public final class SingularityConstructor extends AbstractMachineBlock implements RecipeDisplayItem { 40 | 41 | private static final List RECIPE_LIST = new ArrayList<>(); 42 | private static final Map> RECIPE_MAP = new HashMap<>(); 43 | public static final RecipeType TYPE = new RecipeType(InfinityExpansion.createKey("singularity_constructor"), 44 | Machines.SINGULARITY_CONSTRUCTOR, (stacks, itemStack) -> { 45 | int amt = 0; 46 | for (ItemStack item : stacks) { 47 | if (item != null) { 48 | amt += item.getAmount(); 49 | } 50 | } 51 | String id = StackUtils.getIdOrType(stacks[0]); 52 | Recipe recipe = new Recipe((SlimefunItemStack) itemStack, stacks[0], id, amt); 53 | RECIPE_LIST.add(recipe); 54 | RECIPE_MAP.put(id, new Pair<>(RECIPE_LIST.size() - 1, recipe)); 55 | }); 56 | 57 | private static final String PROGRESS = "progress"; 58 | private static final int STATUS_SLOT = 13; 59 | private static final int[] INPUT_SLOT = {10}; 60 | private static final int[] OUTPUT_SLOT = {16}; 61 | 62 | @Setter 63 | private int speed; 64 | 65 | public SingularityConstructor(ItemGroup category, SlimefunItemStack item, RecipeType type, ItemStack[] recipe) { 66 | super(category, item, type, recipe); 67 | } 68 | 69 | @Override 70 | protected void onBreak(@Nonnull BlockBreakEvent e, @Nonnull BlockMenu menu) { 71 | super.onBreak(e, menu); 72 | Location l = menu.getLocation(); 73 | int progress = Util.getIntData(PROGRESS, l); 74 | Integer progressID = getProgressID(l); 75 | 76 | if (progress > 0 && progressID != null) { 77 | 78 | Recipe triplet = RECIPE_LIST.get(progressID); 79 | 80 | if (triplet != null) { 81 | ItemStack drop = new CustomItemStack(triplet.input, 64); 82 | 83 | int stacks = progress / 64; 84 | 85 | if (stacks > 0) { 86 | for (int i = 0 ; i < stacks ; i++) { 87 | e.getBlock().getWorld().dropItemNaturally(l, drop); 88 | } 89 | } 90 | 91 | int remainder = progress % 64; 92 | 93 | if (remainder > 0) { 94 | drop.setAmount(remainder); 95 | e.getBlock().getWorld().dropItemNaturally(l, drop); 96 | } 97 | } 98 | } 99 | 100 | setProgressID(l, null); 101 | setProgress(l, 0); 102 | } 103 | 104 | @Override 105 | protected boolean process(@Nonnull Block b, @Nonnull BlockMenu menu) { 106 | ItemStack input = menu.getItemInSlot(INPUT_SLOT[0]); 107 | String inputID; 108 | if (input == null) { 109 | inputID = null; 110 | } 111 | else { 112 | inputID = StackUtils.getIdOrType(input); 113 | } 114 | 115 | // load data 116 | Integer progressID = getProgressID(b.getLocation()); 117 | int progress = Util.getIntData(PROGRESS, b.getLocation()); 118 | 119 | Recipe triplet; 120 | boolean takeCharge = false; 121 | 122 | if (progressID == null || progress == 0) { 123 | // not started 124 | if (inputID != null) { 125 | Pair pair = RECIPE_MAP.get(inputID); 126 | if (pair != null) { 127 | progress = Math.min(this.speed, input.getAmount()); 128 | input.setAmount(input.getAmount() - progress); 129 | progressID = pair.getFirstValue(); 130 | triplet = pair.getSecondValue(); 131 | takeCharge = true; 132 | } 133 | else { 134 | // invalid input 135 | triplet = null; 136 | } 137 | } 138 | else { 139 | // still haven't started 140 | triplet = null; 141 | } 142 | } 143 | else { 144 | // started 145 | triplet = RECIPE_LIST.get(progressID); 146 | if (inputID != null) { 147 | int max = Math.min(triplet.amount - progress, Math.min(this.speed, input.getAmount())); 148 | if (max > 0) { 149 | if (triplet.id.equals(inputID)) { 150 | progress += max; 151 | input.setAmount(input.getAmount() - max); 152 | takeCharge = true; 153 | } // invalid input 154 | } // already done 155 | } 156 | } 157 | 158 | // show status and output if done 159 | if (triplet != null) { 160 | if (progress >= triplet.amount && menu.fits(triplet.output, OUTPUT_SLOT)) { 161 | menu.pushItem(triplet.output.clone(), OUTPUT_SLOT); 162 | progress = 0; 163 | progressID = null; 164 | 165 | if (menu.hasViewer()) { 166 | menu.replaceExistingItem(STATUS_SLOT, new CustomItemStack( 167 | Material.LIME_STAINED_GLASS_PANE, 168 | "&aConstructing " + triplet.output.getDisplayName() + "...", 169 | "&7Complete" 170 | )); 171 | } 172 | } 173 | else if (menu.hasViewer()) { 174 | menu.replaceExistingItem(STATUS_SLOT, new CustomItemStack( 175 | Material.LIME_STAINED_GLASS_PANE, 176 | "&aConstructing " + triplet.output.getDisplayName() + "...", 177 | "&7" + progress + " / " + triplet.amount 178 | )); 179 | } 180 | } 181 | else if (menu.hasViewer()) { 182 | invalidInput(menu); 183 | } 184 | 185 | // save data 186 | setProgressID(b.getLocation(), progressID); 187 | setProgress(b.getLocation(), progress); 188 | 189 | return takeCharge; 190 | } 191 | 192 | @Override 193 | protected void setup(@Nonnull BlockMenuPreset blockMenuPreset) { 194 | blockMenuPreset.drawBackground(INPUT_BORDER, new int[] { 195 | 0, 1, 2, 196 | 9, 11, 197 | 18, 19, 20 198 | }); 199 | blockMenuPreset.drawBackground(new int[] { 200 | 3, 4, 5, 201 | 12, 13, 14, 202 | 21, 22, 23 203 | }); 204 | blockMenuPreset.drawBackground(OUTPUT_BORDER, new int[] { 205 | 6, 7, 8, 206 | 15, 17, 207 | 24, 25, 26 208 | }); 209 | } 210 | 211 | @Override 212 | protected int getStatusSlot() { 213 | return STATUS_SLOT; 214 | } 215 | 216 | @Override 217 | protected int[] getInputSlots() { 218 | return INPUT_SLOT; 219 | } 220 | 221 | @Override 222 | protected int[] getOutputSlots() { 223 | return OUTPUT_SLOT; 224 | } 225 | 226 | @Override 227 | public void onNewInstance(@Nonnull BlockMenu blockMenu, @Nonnull Block block) { 228 | invalidInput(blockMenu); 229 | } 230 | 231 | private static void invalidInput(BlockMenu menu) { 232 | menu.replaceExistingItem(STATUS_SLOT, new CustomItemStack( 233 | Material.RED_STAINED_GLASS_PANE, 234 | "&cInput a valid material to start" 235 | )); 236 | } 237 | 238 | private static void setProgress(Location l, int progress) { 239 | BlockStorage.addBlockInfo(l, "progress", String.valueOf(progress)); 240 | } 241 | 242 | private static void setProgressID(Location l, @Nullable Integer progressID) { 243 | if (progressID == null) { 244 | BlockStorage.addBlockInfo(l, "progressid", null); 245 | } 246 | else { 247 | BlockStorage.addBlockInfo(l, "progressid", String.valueOf(progressID)); 248 | } 249 | } 250 | 251 | @Nullable 252 | private static Integer getProgressID(Location l) { 253 | String id = BlockStorage.getLocationInfo(l, "progressid"); 254 | if (id == null) { 255 | return null; 256 | } 257 | else { 258 | try { 259 | return Integer.parseInt(id); 260 | } catch (NumberFormatException e) { 261 | setProgressID(l, null); 262 | return null; 263 | } 264 | } 265 | } 266 | 267 | @Nonnull 268 | @Override 269 | public List getDisplayRecipes() { 270 | final List items = new ArrayList<>(); 271 | 272 | for (Recipe recipe : RECIPE_LIST) { 273 | items.add(recipe.input); 274 | items.add(recipe.output); 275 | } 276 | 277 | return items; 278 | } 279 | 280 | @AllArgsConstructor 281 | private static final class Recipe { 282 | 283 | private final SlimefunItemStack output; 284 | private final ItemStack input; 285 | private final String id; 286 | private final int amount; 287 | 288 | } 289 | 290 | } 291 | -------------------------------------------------------------------------------- /src/main/java/io/github/mooy1/infinityexpansion/items/machines/StoneworksFactory.java: -------------------------------------------------------------------------------- 1 | package io.github.mooy1.infinityexpansion.items.machines; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import javax.annotation.Nonnull; 7 | import javax.annotation.ParametersAreNonnullByDefault; 8 | 9 | import lombok.AllArgsConstructor; 10 | 11 | import org.bukkit.Location; 12 | import org.bukkit.Material; 13 | import org.bukkit.block.Block; 14 | import org.bukkit.inventory.ItemStack; 15 | 16 | import io.github.mooy1.infinityexpansion.InfinityExpansion; 17 | import io.github.mooy1.infinitylib.machines.AbstractMachineBlock; 18 | import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup; 19 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; 20 | import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; 21 | import io.github.thebusybiscuit.slimefun4.core.attributes.NotHopperable; 22 | import io.github.thebusybiscuit.slimefun4.core.attributes.RecipeDisplayItem; 23 | import io.github.thebusybiscuit.slimefun4.libraries.dough.items.CustomItemStack; 24 | import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils; 25 | import me.mrCookieSlime.Slimefun.api.BlockStorage; 26 | import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu; 27 | import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset; 28 | import me.mrCookieSlime.Slimefun.api.inventory.DirtyChestMenu; 29 | 30 | /** 31 | * Turns cobble into stuff 32 | */ 33 | @ParametersAreNonnullByDefault 34 | public final class StoneworksFactory extends AbstractMachineBlock implements RecipeDisplayItem, NotHopperable { 35 | 36 | private static final int[] PROCESS_BORDER = { 0, 1, 2, 3, 4, 5, 18, 19, 20, 21, 22, 23 }; 37 | private static final int[] OUT_BORDER = { 6, 7, 8, 17, 24, 25, 26 }; 38 | private static final int[] OUTPUT_SLOTS = { 16 }; 39 | private static final int STATUS_SLOT = 9; 40 | private static final int[] CHOICE_SLOTS = { 11, 13, 15 }; 41 | private static final int[] PROCESS_SLOTS = { 10, 12, 14 }; 42 | private static final ItemStack COBBLE_GEN = new CustomItemStack(Material.GRAY_CONCRETE, "&8Cobblegen"); 43 | private static final ItemStack PROCESSING = new CustomItemStack(Material.LIME_STAINED_GLASS_PANE, "&aProcessing"); 44 | 45 | public StoneworksFactory(ItemGroup category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { 46 | super(category, item, recipeType, recipe); 47 | } 48 | 49 | @Override 50 | protected void setup(@Nonnull BlockMenuPreset blockMenuPreset) { 51 | blockMenuPreset.drawBackground(PROCESS_BORDER); 52 | blockMenuPreset.drawBackground(OUTPUT_BORDER, OUT_BORDER); 53 | blockMenuPreset.drawBackground(Choice.NONE.item, CHOICE_SLOTS); 54 | blockMenuPreset.addItem(STATUS_SLOT, COBBLE_GEN, ChestMenuUtils.getEmptyClickHandler()); 55 | } 56 | 57 | @Override 58 | public void onNewInstance(@Nonnull BlockMenu menu, @Nonnull Block b) { 59 | Location l = b.getLocation(); 60 | 61 | if (BlockStorage.getLocationInfo(l, "choice0") == null) { 62 | setChoice(l, 0, Choice.NONE); 63 | setChoice(l, 1, Choice.NONE); 64 | setChoice(l, 2, Choice.NONE); 65 | } 66 | 67 | for (int i = 0 ; i < CHOICE_SLOTS.length ; i++) { 68 | menu.replaceExistingItem(CHOICE_SLOTS[i], getChoice(l, i).item); 69 | } 70 | 71 | for (int i = 0 ; i < 3 ; i++) { 72 | int finalI = i; 73 | menu.addMenuClickHandler(CHOICE_SLOTS[i], (p, slot, item, action) -> { 74 | int current = getChoice(b.getLocation(), finalI).ordinal(); 75 | Choice next = action.isRightClicked() 76 | ? current > 0 77 | ? Choice.values[current - 1] 78 | : Choice.values[Choice.values.length - 1] 79 | : current < Choice.values.length - 1 80 | ? Choice.values[current + 1] 81 | : Choice.values[0]; 82 | setChoice(l, finalI, next); 83 | menu.replaceExistingItem(CHOICE_SLOTS[finalI], next.item); 84 | return false; 85 | }); 86 | } 87 | } 88 | 89 | private static void process(int i, BlockMenu inv, Location l) { 90 | int slot = PROCESS_SLOTS[i]; 91 | 92 | ItemStack item = inv.getItemInSlot(slot); 93 | 94 | if (item == null) { 95 | return; 96 | } 97 | 98 | Choice c = getChoice(l, i); 99 | int nextSlot = i < 2 ? PROCESS_SLOTS[i + 1] : OUTPUT_SLOTS[0]; 100 | 101 | if (c == Choice.NONE) { 102 | item = item.clone(); 103 | item.setAmount(1); 104 | 105 | if (inv.fits(item, nextSlot)) { 106 | inv.consumeItem(slot, 1); 107 | inv.pushItem(item, nextSlot); 108 | } 109 | return; 110 | } 111 | 112 | for (int check = 0; check < c.inputs.length; check++) { 113 | 114 | if (item.getType() == c.inputs[check]) { 115 | 116 | ItemStack output = new ItemStack(c.outputs[check]); 117 | 118 | if (inv.fits(output, nextSlot)) { 119 | inv.consumeItem(slot, 1); 120 | inv.pushItem(output, nextSlot); 121 | } 122 | 123 | break; 124 | } 125 | } 126 | } 127 | 128 | @Nonnull 129 | @Override 130 | public List getDisplayRecipes() { 131 | List items = new ArrayList<>(); 132 | for (Choice option : Choice.values) { 133 | for (int i = 0 ; i < option.inputs.length ; i++) { 134 | items.add(new ItemStack(option.inputs[i])); 135 | items.add(new ItemStack(option.outputs[i])); 136 | } 137 | } 138 | return items; 139 | } 140 | 141 | @Override 142 | protected int[] getInputSlots(DirtyChestMenu menu, ItemStack item) { 143 | return new int[0]; 144 | } 145 | 146 | @Override 147 | protected int[] getInputSlots() { 148 | return PROCESS_SLOTS; 149 | } 150 | 151 | @Override 152 | protected int[] getOutputSlots() { 153 | return OUTPUT_SLOTS; 154 | } 155 | 156 | @Nonnull 157 | private static Choice getChoice(Location l, int i) { 158 | try { 159 | return Choice.valueOf(BlockStorage.getLocationInfo(l, "choice" + i)); 160 | } catch (Exception e) { 161 | setChoice(l, i, Choice.NONE); 162 | return Choice.NONE; 163 | } 164 | } 165 | 166 | private static void setChoice(Location l, int i, Choice o) { 167 | BlockStorage.addBlockInfo(l, "choice" + i, o.toString()); 168 | } 169 | 170 | @Override 171 | protected boolean process(Block b, BlockMenu inv) { 172 | if (inv.hasViewer()) { 173 | inv.replaceExistingItem(STATUS_SLOT, PROCESSING); 174 | } 175 | int tick = InfinityExpansion.slimefunTickCount() % 4; 176 | 177 | if (tick == 3) { 178 | inv.pushItem(new ItemStack(Material.COBBLESTONE), PROCESS_SLOTS[0]); 179 | } 180 | else { 181 | process(tick, inv, b.getLocation()); 182 | } 183 | 184 | return true; 185 | } 186 | 187 | @Override 188 | protected int getStatusSlot() { 189 | return STATUS_SLOT; 190 | } 191 | 192 | @AllArgsConstructor 193 | private enum Choice { 194 | NONE(new CustomItemStack(Material.BARRIER, "&cNone", "", "&7 > Click to cycle"), 195 | new Material[0], 196 | new Material[0] 197 | ), 198 | FURNACE(new CustomItemStack(Material.FURNACE, "&8Smelting", "", "&7 > Click to cycle"), 199 | new Material[] { Material.COBBLESTONE, Material.STONE, Material.SAND, Material.STONE_BRICKS }, 200 | new Material[] { Material.STONE, Material.SMOOTH_STONE, Material.GLASS, Material.CRACKED_STONE_BRICKS } 201 | ), 202 | CRUSH(new CustomItemStack(Material.DIAMOND_PICKAXE, "&8Crushing", "", "&7 > Click to cycle"), 203 | new Material[] { Material.COBBLESTONE, Material.GRAVEL }, 204 | new Material[] { Material.GRAVEL, Material.SAND } 205 | ), 206 | COMPACT(new CustomItemStack(Material.PISTON, "&8Compacting", "", "&7 > Click to cycle"), 207 | new Material[] { Material.STONE, Material.GRANITE, Material.DIORITE, Material.ANDESITE, Material.SAND }, 208 | new Material[] { Material.STONE_BRICKS, Material.POLISHED_GRANITE, Material.POLISHED_DIORITE, Material.POLISHED_ANDESITE, Material.SANDSTONE } 209 | ), 210 | TRANSFORM(new CustomItemStack(Material.ANDESITE, "&8Transforming", "", "&7 > Click to cycle"), 211 | new Material[] { Material.COBBLESTONE, Material.ANDESITE, Material.DIORITE }, 212 | new Material[] { Material.ANDESITE, Material.DIORITE, Material.GRANITE } 213 | ); 214 | 215 | private final ItemStack item; 216 | private final Material[] inputs; 217 | private final Material[] outputs; 218 | 219 | private static final Choice[] values = values(); 220 | } 221 | 222 | } 223 | -------------------------------------------------------------------------------- /src/main/java/io/github/mooy1/infinityexpansion/items/machines/VoidHarvester.java: -------------------------------------------------------------------------------- 1 | package io.github.mooy1.infinityexpansion.items.machines; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import javax.annotation.Nonnull; 7 | 8 | import org.bukkit.Material; 9 | import org.bukkit.block.Block; 10 | import org.bukkit.entity.Player; 11 | import org.bukkit.inventory.ItemStack; 12 | 13 | import io.github.mooy1.infinityexpansion.InfinityExpansion; 14 | import io.github.mooy1.infinityexpansion.items.materials.Materials; 15 | import io.github.mooy1.infinitylib.machines.AbstractMachineBlock; 16 | import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup; 17 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; 18 | import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; 19 | import io.github.thebusybiscuit.slimefun4.core.attributes.RecipeDisplayItem; 20 | import io.github.thebusybiscuit.slimefun4.libraries.dough.items.CustomItemStack; 21 | import me.mrCookieSlime.Slimefun.api.BlockStorage; 22 | import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu; 23 | import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset; 24 | 25 | /** 26 | * harvests void bits from... the void 27 | * 28 | * @author Mooy1 29 | */ 30 | public final class VoidHarvester extends AbstractMachineBlock implements RecipeDisplayItem { 31 | 32 | public static final RecipeType TYPE = new RecipeType(InfinityExpansion.createKey("void_harvester"), Machines.VOID_HARVESTER); 33 | 34 | private static final int[] OUTPUT_SLOTS = { 13 }; 35 | private static final int TIME = 1024; 36 | 37 | private final int speed; 38 | 39 | public VoidHarvester(ItemGroup category, SlimefunItemStack item, RecipeType type, ItemStack[] recipe, int speed) { 40 | super(category, item, type, recipe); 41 | this.speed = speed; 42 | } 43 | 44 | @Override 45 | protected boolean process(@Nonnull Block b, @Nonnull BlockMenu inv) { 46 | int progress = Integer.parseInt(getProgress(b)); 47 | 48 | if (progress >= TIME) { //reached full progress 49 | 50 | ItemStack output = Materials.VOID_BIT; 51 | 52 | if (inv.fits(output, OUTPUT_SLOTS)) { 53 | 54 | inv.pushItem(output.clone(), OUTPUT_SLOTS); 55 | 56 | progress = this.speed; 57 | 58 | } 59 | else { 60 | if (inv.hasViewer()) { 61 | inv.replaceExistingItem(getStatusSlot(), NO_ROOM_ITEM); 62 | } 63 | return false; 64 | } 65 | } 66 | else { 67 | progress += this.speed; 68 | } 69 | 70 | setProgress(b, progress); 71 | if (inv.hasViewer()) { //update status 72 | inv.replaceExistingItem(getStatusSlot(), new CustomItemStack(Material.LIME_STAINED_GLASS_PANE, 73 | "&aHarvesting - " + progress * 100 / TIME + "%", 74 | "&7(" + progress + "/" + TIME + ")" 75 | )); 76 | } 77 | return true; 78 | } 79 | 80 | @Override 81 | protected int getStatusSlot() { 82 | return 4; 83 | } 84 | 85 | @Override 86 | protected void setup(BlockMenuPreset blockMenuPreset) { 87 | blockMenuPreset.drawBackground(new int[] { 88 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 89 | 9, 10, 11, 12, 14, 15, 16, 17 90 | }); 91 | } 92 | 93 | @Override 94 | protected int[] getInputSlots() { 95 | return new int[0]; 96 | } 97 | 98 | @Override 99 | protected int[] getOutputSlots() { 100 | return OUTPUT_SLOTS; 101 | } 102 | 103 | @Override 104 | public void onNewInstance(@Nonnull BlockMenu menu, @Nonnull Block b) { 105 | if (getProgress(b) == null) { 106 | setProgress(b, 0); 107 | } 108 | } 109 | 110 | private static void setProgress(Block b, int progress) { 111 | BlockStorage.addBlockInfo(b, "progress", String.valueOf(progress)); 112 | } 113 | 114 | private static String getProgress(Block b) { 115 | return BlockStorage.getLocationInfo(b.getLocation(), "progress"); 116 | } 117 | 118 | @Nonnull 119 | @Override 120 | public List getDisplayRecipes() { 121 | final List items = new ArrayList<>(); 122 | 123 | items.add(null); 124 | items.add(Materials.VOID_BIT); 125 | 126 | return items; 127 | } 128 | 129 | @Nonnull 130 | @Override 131 | public String getRecipeSectionLabel(@Nonnull Player p) { 132 | return "&7Harvests:"; 133 | } 134 | 135 | } 136 | 137 | -------------------------------------------------------------------------------- /src/main/java/io/github/mooy1/infinityexpansion/items/materials/EnderEssence.java: -------------------------------------------------------------------------------- 1 | package io.github.mooy1.infinityexpansion.items.materials; 2 | 3 | import javax.annotation.Nonnull; 4 | 5 | import org.bukkit.NamespacedKey; 6 | import org.bukkit.World; 7 | import org.bukkit.block.Biome; 8 | import org.bukkit.inventory.ItemStack; 9 | 10 | import io.github.thebusybiscuit.slimefun4.api.geo.GEOResource; 11 | import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup; 12 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem; 13 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; 14 | import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; 15 | import io.github.thebusybiscuit.slimefun4.core.attributes.NotPlaceable; 16 | 17 | /** 18 | * Ender essence geo-resource item 19 | * 20 | * @author Mooy1 21 | */ 22 | public final class EnderEssence extends SlimefunItem implements NotPlaceable, GEOResource { 23 | 24 | private final NamespacedKey key; 25 | 26 | public EnderEssence(ItemGroup category, SlimefunItemStack item, NamespacedKey key) { 27 | super(category, item, RecipeType.GEO_MINER, new ItemStack[9]); 28 | this.key = key; 29 | register(); 30 | } 31 | 32 | @Override 33 | public int getDefaultSupply(@Nonnull World.Environment environment, @Nonnull Biome biome) { 34 | if (environment == World.Environment.THE_END) { 35 | return 12; 36 | } 37 | if (biome == Biome.THE_VOID) { 38 | return 8; 39 | } 40 | if (environment == World.Environment.NETHER) { 41 | return 4; 42 | } 43 | return 0; 44 | } 45 | 46 | @Nonnull 47 | @Override 48 | public NamespacedKey getKey() { 49 | return this.key; 50 | } 51 | 52 | @Override 53 | public int getMaxDeviation() { 54 | return 4; 55 | } 56 | 57 | @Nonnull 58 | @Override 59 | public String getName() { 60 | return getItemName(); 61 | } 62 | 63 | @Override 64 | public boolean isObtainableFromGEOMiner() { 65 | return true; 66 | } 67 | 68 | } -------------------------------------------------------------------------------- /src/main/java/io/github/mooy1/infinityexpansion/items/materials/Singularity.java: -------------------------------------------------------------------------------- 1 | package io.github.mooy1.infinityexpansion.items.materials; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import javax.annotation.Nonnull; 7 | 8 | import org.bukkit.Material; 9 | import org.bukkit.inventory.ItemStack; 10 | 11 | import io.github.mooy1.infinityexpansion.InfinityExpansion; 12 | import io.github.mooy1.infinityexpansion.categories.Groups; 13 | import io.github.mooy1.infinityexpansion.items.machines.SingularityConstructor; 14 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; 15 | import io.github.thebusybiscuit.slimefun4.implementation.items.blocks.UnplaceableBlock; 16 | import io.github.thebusybiscuit.slimefun4.libraries.dough.items.CustomItemStack; 17 | 18 | /** 19 | * Singularities and there recipe displays 20 | * 21 | * @author Mooy1 22 | */ 23 | public final class Singularity extends UnplaceableBlock { 24 | 25 | private static final double COST_MULTIPLIER = 26 | InfinityExpansion.config().getDouble("balance-options.singularity-cost-multiplier", 0.1, 100); 27 | 28 | public Singularity(SlimefunItemStack item, SlimefunItemStack recipe, int amount) { 29 | super(Groups.INFINITY_MATERIALS, item, SingularityConstructor.TYPE, 30 | makeRecipe(recipe, (int) (amount * COST_MULTIPLIER))); 31 | } 32 | 33 | public Singularity(SlimefunItemStack item, Material recipe, int amount) { 34 | super(Groups.INFINITY_MATERIALS, item, SingularityConstructor.TYPE, 35 | makeRecipe(new ItemStack(recipe), (int) (amount * COST_MULTIPLIER))); 36 | } 37 | 38 | @Nonnull 39 | private static ItemStack[] makeRecipe(ItemStack item, int amount) { 40 | List recipe = new ArrayList<>(); 41 | 42 | int stacks = (int) Math.floor(amount / 64D); 43 | int extra = amount % 64; 44 | 45 | for (int i = 0 ; i < stacks ; i++) { 46 | recipe.add(new CustomItemStack(item, 64)); 47 | } 48 | 49 | recipe.add(new CustomItemStack(item, extra)); 50 | 51 | while (recipe.size() < 9) { 52 | recipe.add(null); 53 | } 54 | 55 | return recipe.toArray(new ItemStack[9]); 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/io/github/mooy1/infinityexpansion/items/materials/Strainer.java: -------------------------------------------------------------------------------- 1 | package io.github.mooy1.infinityexpansion.items.materials; 2 | 3 | import javax.annotation.Nullable; 4 | 5 | import org.bukkit.NamespacedKey; 6 | import org.bukkit.inventory.ItemStack; 7 | import org.bukkit.inventory.meta.ItemMeta; 8 | import org.bukkit.persistence.PersistentDataType; 9 | 10 | import io.github.mooy1.infinityexpansion.InfinityExpansion; 11 | import io.github.mooy1.infinityexpansion.categories.Groups; 12 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem; 13 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; 14 | import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; 15 | import io.github.thebusybiscuit.slimefun4.core.attributes.NotPlaceable; 16 | 17 | /** 18 | * Items to be used in the Strainer Base 19 | * 20 | * @author Mooy1 21 | */ 22 | public final class Strainer extends SlimefunItem implements NotPlaceable { 23 | 24 | private static final NamespacedKey KEY = InfinityExpansion.createKey("strainer_speed"); 25 | 26 | public Strainer(SlimefunItemStack item, ItemStack[] recipe, int speed) { 27 | super(Groups.BASIC_MACHINES, item, RecipeType.ENHANCED_CRAFTING_TABLE, recipe); 28 | ItemMeta meta = item.getItemMeta(); 29 | meta.getPersistentDataContainer().set(KEY, PersistentDataType.INTEGER, speed); 30 | item.setItemMeta(meta); 31 | } 32 | 33 | /** 34 | * This method gets the speed of strainer from an item 35 | * 36 | * @return speed 37 | */ 38 | public static int getStrainer(@Nullable ItemStack item) { 39 | if (item != null && item.hasItemMeta()) { 40 | return item.getItemMeta().getPersistentDataContainer().getOrDefault(Strainer.KEY, PersistentDataType.INTEGER, 0); 41 | } 42 | return 0; 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/io/github/mooy1/infinityexpansion/items/mobdata/MobDataCard.java: -------------------------------------------------------------------------------- 1 | package io.github.mooy1.infinityexpansion.items.mobdata; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | import java.util.List; 6 | import java.util.Locale; 7 | import java.util.Map; 8 | 9 | import javax.annotation.Nonnull; 10 | import javax.annotation.ParametersAreNonnullByDefault; 11 | 12 | import org.bukkit.Material; 13 | import org.bukkit.inventory.ItemStack; 14 | 15 | import io.github.mooy1.infinityexpansion.categories.Groups; 16 | import io.github.mooy1.infinitylib.machines.MachineLore; 17 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem; 18 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; 19 | import io.github.thebusybiscuit.slimefun4.core.attributes.NotPlaceable; 20 | import io.github.thebusybiscuit.slimefun4.core.attributes.RecipeDisplayItem; 21 | import io.github.thebusybiscuit.slimefun4.libraries.dough.collections.RandomizedSet; 22 | import io.github.thebusybiscuit.slimefun4.libraries.dough.items.CustomItemStack; 23 | 24 | /** 25 | * A mob data card which will be able to be used in the {@link MobSimulationChamber} 26 | */ 27 | @ParametersAreNonnullByDefault 28 | public final class MobDataCard extends SlimefunItem implements RecipeDisplayItem, NotPlaceable { 29 | 30 | static final Map CARDS = new HashMap<>(); 31 | 32 | public static SlimefunItemStack create(String name, MobDataTier tier) { 33 | return new SlimefunItemStack( 34 | name.toUpperCase(Locale.ROOT).replace(" ", "_") + "_DATA_CARD", 35 | tier.material, 36 | "&b" + name + " Data Card", 37 | "&7Place in a mob simulation chamber to activate", 38 | "", 39 | MachineLore.energyPerSecond(tier.energy) 40 | ); 41 | } 42 | 43 | public MobDataCard(String name, MobDataTier tier, ItemStack[] recipe) { 44 | super(Groups.MOB_SIMULATION, create(name, tier), MobDataInfuser.TYPE, recipe); 45 | this.tier = tier; 46 | CARDS.put(getId(), this); 47 | } 48 | 49 | public MobDataCard(SlimefunItemStack item, MobDataTier tier, ItemStack[] recipe) { 50 | super(Groups.MOB_SIMULATION, item, MobDataInfuser.TYPE, recipe); 51 | this.tier = tier; 52 | CARDS.put(getId(), this); 53 | } 54 | 55 | final RandomizedSet drops = new RandomizedSet<>(); 56 | final MobDataTier tier; 57 | 58 | public MobDataCard addDrop(ItemStack drop, float chance) { 59 | this.drops.add(drop, 1 / chance); 60 | return this; 61 | } 62 | 63 | public MobDataCard addDrop(ItemStack drop, int amount, float chance) { 64 | return addDrop(new CustomItemStack(drop, amount), chance); 65 | } 66 | 67 | public MobDataCard addDrop(Material drop, float chance) { 68 | return addDrop(new ItemStack(drop), chance); 69 | } 70 | 71 | public MobDataCard addDrop(Material drop, int amount, float chance) { 72 | return addDrop(new ItemStack(drop, amount), chance); 73 | } 74 | 75 | @Nonnull 76 | @Override 77 | public List getDisplayRecipes() { 78 | List items = new ArrayList<>(); 79 | for (ItemStack item : this.drops) { 80 | items.add(null); 81 | items.add(item); 82 | } 83 | return items; 84 | } 85 | 86 | } 87 | -------------------------------------------------------------------------------- /src/main/java/io/github/mooy1/infinityexpansion/items/mobdata/MobDataInfuser.java: -------------------------------------------------------------------------------- 1 | package io.github.mooy1.infinityexpansion.items.mobdata; 2 | 3 | import javax.annotation.Nonnull; 4 | import javax.annotation.ParametersAreNonnullByDefault; 5 | 6 | import org.bukkit.ChatColor; 7 | import org.bukkit.block.Block; 8 | import org.bukkit.entity.Player; 9 | import org.bukkit.inventory.ItemStack; 10 | 11 | import io.github.mooy1.infinitylib.machines.CraftingBlock; 12 | import io.github.mooy1.infinitylib.machines.MachineRecipeType; 13 | import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup; 14 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; 15 | import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; 16 | import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetComponent; 17 | import io.github.thebusybiscuit.slimefun4.core.networks.energy.EnergyNetComponentType; 18 | import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu; 19 | 20 | @ParametersAreNonnullByDefault 21 | public final class MobDataInfuser extends CraftingBlock implements EnergyNetComponent { 22 | 23 | static final MachineRecipeType TYPE = new MachineRecipeType("mob_data_infuser", MobData.INFUSER); 24 | 25 | private final int energy; 26 | 27 | public MobDataInfuser(ItemGroup category, SlimefunItemStack stack, RecipeType type, ItemStack[] recipe, int energy) { 28 | super(category, stack, type, recipe); 29 | addRecipesFrom(TYPE); 30 | this.energy = energy; 31 | } 32 | 33 | @Override 34 | protected void craft(Block b, BlockMenu menu, Player p) { 35 | if (getCharge(menu.getLocation()) < this.energy) { 36 | p.sendMessage(ChatColor.RED + "Not enough energy!"); 37 | } 38 | else { 39 | super.craft(b, menu, p); 40 | } 41 | } 42 | 43 | @Override 44 | protected void onSuccessfulCraft(BlockMenu menu, ItemStack toOutput) { 45 | setCharge(menu.getLocation(), 0); 46 | } 47 | 48 | @Nonnull 49 | @Override 50 | public EnergyNetComponentType getEnergyComponentType() { 51 | return EnergyNetComponentType.CONSUMER; 52 | } 53 | 54 | @Override 55 | public int getCapacity() { 56 | return this.energy; 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/io/github/mooy1/infinityexpansion/items/mobdata/MobDataTier.java: -------------------------------------------------------------------------------- 1 | package io.github.mooy1.infinityexpansion.items.mobdata; 2 | 3 | import org.bukkit.Material; 4 | 5 | public enum MobDataTier { 6 | 7 | // ex: chicken 8 | PASSIVE(1, 75, Material.IRON_CHESTPLATE), 9 | 10 | // ex: slime 11 | NEUTRAL(1, 150, Material.IRON_CHESTPLATE), 12 | 13 | // ex: zombie 14 | HOSTILE(2, 300, Material.DIAMOND_CHESTPLATE), 15 | 16 | // ex: endermen 17 | ADVANCED(4, 600, Material.DIAMOND_CHESTPLATE), 18 | 19 | // ex: wither 20 | MINI_BOSS(32, 4500, Material.NETHERITE_CHESTPLATE), 21 | 22 | // ex: ender dragon 23 | BOSS(96, 9000, Material.NETHERITE_CHESTPLATE); 24 | 25 | final int xp; 26 | final int energy; 27 | final Material material; 28 | 29 | MobDataTier(int xp, int energy, Material material) { 30 | this.xp = (int) (xp * MobSimulationChamber.XP_MULTIPLIER); 31 | this.energy = energy; 32 | this.material = material; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/io/github/mooy1/infinityexpansion/items/mobdata/MobSimulationChamber.java: -------------------------------------------------------------------------------- 1 | package io.github.mooy1.infinityexpansion.items.mobdata; 2 | 3 | import javax.annotation.Nonnull; 4 | 5 | import org.bukkit.Location; 6 | import org.bukkit.Material; 7 | import org.bukkit.Sound; 8 | import org.bukkit.block.Block; 9 | import org.bukkit.event.block.BlockBreakEvent; 10 | import org.bukkit.inventory.ItemStack; 11 | 12 | import io.github.mooy1.infinityexpansion.InfinityExpansion; 13 | import io.github.mooy1.infinityexpansion.utils.Util; 14 | import io.github.mooy1.infinitylib.common.StackUtils; 15 | import io.github.mooy1.infinitylib.machines.AbstractMachineBlock; 16 | import io.github.mooy1.infinitylib.machines.MachineLore; 17 | import io.github.mooy1.infinitylib.machines.TickingMenuBlock; 18 | import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup; 19 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; 20 | import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; 21 | import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetComponent; 22 | import io.github.thebusybiscuit.slimefun4.core.networks.energy.EnergyNetComponentType; 23 | import io.github.thebusybiscuit.slimefun4.libraries.dough.items.CustomItemStack; 24 | import me.mrCookieSlime.Slimefun.api.BlockStorage; 25 | import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu; 26 | import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset; 27 | import me.mrCookieSlime.Slimefun.api.inventory.DirtyChestMenu; 28 | 29 | public final class MobSimulationChamber extends TickingMenuBlock implements EnergyNetComponent { 30 | 31 | static final double XP_MULTIPLIER = InfinityExpansion.config().getDouble("mob-simulation-options.xp-multiplier", 0, 1000); 32 | 33 | private static final ItemStack NO_CARD = new CustomItemStack(Material.BARRIER, "&cInput a Mob Data Card!"); 34 | private static final int CARD_SLOT = 37; 35 | private static final int STATUS_SLOT = 10; 36 | private static final int[] OUTPUT_SLOTS = { 37 | 13, 14, 15, 16, 38 | 22, 23, 24, 25, 39 | 31, 32, 33, 34, 40 | 40, 41, 42, 43 41 | }; 42 | private static final int XP_SLOT = 46; 43 | 44 | private final int energy; 45 | private final int interval; 46 | 47 | public MobSimulationChamber(ItemGroup category, SlimefunItemStack item, RecipeType type, ItemStack[] recipe, int energy, int interval) { 48 | super(category, item, type, recipe); 49 | this.energy = energy; 50 | this.interval = interval; 51 | } 52 | 53 | @Override 54 | protected void onBreak(@Nonnull BlockBreakEvent e, @Nonnull BlockMenu menu) { 55 | super.onBreak(e, menu); 56 | e.getPlayer().giveExp(Util.getIntData("xp", menu.getLocation())); 57 | BlockStorage.addBlockInfo(menu.getLocation(), "xp", "0"); 58 | } 59 | 60 | @Nonnull 61 | @Override 62 | public EnergyNetComponentType getEnergyComponentType() { 63 | return EnergyNetComponentType.CONSUMER; 64 | } 65 | 66 | @Override 67 | public int getCapacity() { 68 | return this.energy + Math.max(MobDataTier.BOSS.energy, this.energy * 9); 69 | } 70 | 71 | @Override 72 | protected void setup(BlockMenuPreset blockMenuPreset) { 73 | blockMenuPreset.drawBackground(OUTPUT_BORDER, new int[] { 74 | 3, 4, 5, 6, 7, 8, 75 | 12, 17, 76 | 21, 26, 77 | 30, 35, 78 | 39, 44, 79 | 48, 49, 50, 51, 52, 53 80 | }); 81 | blockMenuPreset.drawBackground(new int[] { 82 | 0, 1, 2, 83 | 9, 11, 84 | 18, 19, 20, 85 | STATUS_SLOT, XP_SLOT 86 | }); 87 | blockMenuPreset.drawBackground(INPUT_BORDER, new int[] { 88 | 27, 28, 29, 89 | 36, 38, 90 | 45, 46, 47 91 | }); 92 | } 93 | 94 | @Nonnull 95 | @Override 96 | protected int[] getInputSlots(@Nonnull DirtyChestMenu menu, @Nonnull ItemStack item) { 97 | return new int[0]; 98 | } 99 | 100 | @Override 101 | protected int[] getInputSlots() { 102 | return new int[] { CARD_SLOT }; 103 | } 104 | 105 | @Override 106 | protected int[] getOutputSlots() { 107 | return OUTPUT_SLOTS; 108 | } 109 | 110 | @Override 111 | public void onNewInstance(@Nonnull BlockMenu menu, @Nonnull Block b) { 112 | Location l = b.getLocation(); 113 | if (BlockStorage.getLocationInfo(l, "xp") == null) { 114 | BlockStorage.addBlockInfo(l, "xp", "O"); 115 | } 116 | menu.replaceExistingItem(XP_SLOT, makeXpItem(0)); 117 | menu.addMenuClickHandler(XP_SLOT, (p, slot, item, action) -> { 118 | int xp = Util.getIntData("xp", l); 119 | if (xp > 0) { 120 | p.giveExp(xp); 121 | p.playSound(l, Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1, 1); 122 | BlockStorage.addBlockInfo(l, "xp", "O"); 123 | menu.replaceExistingItem(XP_SLOT, makeXpItem(0)); 124 | } 125 | return false; 126 | }); 127 | } 128 | 129 | private static ItemStack makeXpItem(int stored) { 130 | return new CustomItemStack(Material.LIME_STAINED_GLASS_PANE, "&aStored xp: " + stored, "", "&a> Click to claim"); 131 | } 132 | 133 | @Override 134 | protected void tick(@Nonnull Block b, @Nonnull BlockMenu inv) { 135 | ItemStack input = inv.getItemInSlot(CARD_SLOT); 136 | 137 | if (input == null) { 138 | return; 139 | } 140 | 141 | MobDataCard card = MobDataCard.CARDS.get(StackUtils.getId(input)); 142 | 143 | if (card == null) { 144 | if (inv.hasViewer()) { 145 | inv.replaceExistingItem(STATUS_SLOT, NO_CARD); 146 | } 147 | return; 148 | } 149 | 150 | int energy = card.tier.energy + this.energy; 151 | 152 | if (getCharge(b.getLocation()) < energy) { 153 | if (inv.hasViewer()) { 154 | inv.replaceExistingItem(STATUS_SLOT, AbstractMachineBlock.NO_ENERGY_ITEM); 155 | } 156 | return; 157 | } 158 | 159 | removeCharge(b.getLocation(), energy); 160 | 161 | int xp = Util.getIntData("xp", b.getLocation()); 162 | 163 | if (inv.hasViewer()) { 164 | inv.replaceExistingItem(STATUS_SLOT, new CustomItemStack(Material.LIME_STAINED_GLASS_PANE, 165 | "&aSimulating... (" + MachineLore.formatEnergy(energy) + " J/s)") 166 | ); 167 | inv.replaceExistingItem(XP_SLOT, makeXpItem(xp)); 168 | } 169 | 170 | if (InfinityExpansion.slimefunTickCount() % this.interval != 0) { 171 | return; 172 | } 173 | 174 | BlockStorage.addBlockInfo(b.getLocation(), "xp", String.valueOf(xp + card.tier.xp)); 175 | 176 | ItemStack item = card.drops.getRandom(); 177 | if (inv.fits(item, OUTPUT_SLOTS)) { 178 | inv.pushItem(item.clone(), OUTPUT_SLOTS); 179 | } 180 | else if (inv.hasViewer()) { 181 | inv.replaceExistingItem(STATUS_SLOT, NO_ROOM_ITEM); 182 | } 183 | } 184 | 185 | } 186 | -------------------------------------------------------------------------------- /src/main/java/io/github/mooy1/infinityexpansion/items/quarries/Oscillator.java: -------------------------------------------------------------------------------- 1 | package io.github.mooy1.infinityexpansion.items.quarries; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import javax.annotation.Nonnull; 7 | import javax.annotation.Nullable; 8 | 9 | import org.bukkit.Material; 10 | import org.bukkit.inventory.ItemStack; 11 | 12 | import io.github.mooy1.infinityexpansion.categories.Groups; 13 | import io.github.mooy1.infinityexpansion.items.materials.Materials; 14 | import io.github.mooy1.infinitylib.common.StackUtils; 15 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem; 16 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; 17 | import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; 18 | import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; 19 | import io.github.thebusybiscuit.slimefun4.libraries.dough.items.ItemUtils; 20 | 21 | public final class Oscillator extends SlimefunItem { 22 | 23 | private static final Map OSCILLATORS = new HashMap<>(); 24 | 25 | public final double chance; 26 | 27 | @Nullable 28 | public static Oscillator getOscillator(@Nullable ItemStack item) { 29 | if (item == null) { 30 | return null; 31 | } 32 | return OSCILLATORS.get(StackUtils.getId(item)); 33 | } 34 | 35 | @Nonnull 36 | public static SlimefunItemStack create(Material material, double chance) { 37 | return new SlimefunItemStack( 38 | "QUARRY_OSCILLATOR_" + material.name(), 39 | material, 40 | "&b" + ItemUtils.getItemName(new ItemStack(material)) + " Oscillator", 41 | "&7Place in a quarry to give it", 42 | "&7a " + (chance * 100) + "% chance of mining this material" 43 | ); 44 | } 45 | 46 | public Oscillator(SlimefunItemStack item, double chance) { 47 | super(Groups.MAIN_MATERIALS, item, RecipeType.ENHANCED_CRAFTING_TABLE, new ItemStack[] { 48 | Materials.MACHINE_PLATE, SlimefunItems.BLISTERING_INGOT_3, Materials.MACHINE_PLATE, 49 | SlimefunItems.BLISTERING_INGOT_3, new ItemStack(item.getType()), SlimefunItems.BLISTERING_INGOT_3, 50 | Materials.MACHINE_PLATE, SlimefunItems.BLISTERING_INGOT_3, Materials.MACHINE_PLATE 51 | }); 52 | OSCILLATORS.put(getId(), this); 53 | this.chance = chance; 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/io/github/mooy1/infinityexpansion/items/quarries/Quarries.java: -------------------------------------------------------------------------------- 1 | package io.github.mooy1.infinityexpansion.items.quarries; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.Objects; 6 | 7 | import lombok.experimental.UtilityClass; 8 | 9 | import org.bukkit.Material; 10 | import org.bukkit.configuration.ConfigurationSection; 11 | import org.bukkit.inventory.ItemStack; 12 | 13 | import io.github.mooy1.infinityexpansion.InfinityExpansion; 14 | import io.github.mooy1.infinityexpansion.categories.Groups; 15 | import io.github.mooy1.infinityexpansion.items.SlimefunExtension; 16 | import io.github.mooy1.infinityexpansion.items.blocks.InfinityWorkbench; 17 | import io.github.mooy1.infinityexpansion.items.gear.Gear; 18 | import io.github.mooy1.infinityexpansion.items.materials.Materials; 19 | import io.github.mooy1.infinitylib.machines.MachineLore; 20 | import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion; 21 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; 22 | import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; 23 | import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; 24 | import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; 25 | 26 | @UtilityClass 27 | public final class Quarries { 28 | 29 | public static final SlimefunItemStack BASIC_QUARRY = new SlimefunItemStack( 30 | "BASIC_QUARRY", 31 | Material.CHISELED_SANDSTONE, 32 | "&9Basic Quarry", 33 | "&7Automatically mines overworld ores", 34 | "", 35 | MachineLore.speed(1), 36 | MachineLore.energyPerSecond(300) 37 | ); 38 | public static final SlimefunItemStack ADVANCED_QUARRY = new SlimefunItemStack( 39 | "ADVANCED_QUARRY", 40 | Material.CHISELED_RED_SANDSTONE, 41 | "&cAdvanced Quarry", 42 | "&7Automatically mines overworld and nether ores", 43 | "", 44 | MachineLore.speed(2), 45 | MachineLore.energyPerSecond(900) 46 | ); 47 | public static final SlimefunItemStack VOID_QUARRY = new SlimefunItemStack( 48 | "VOID_QUARRY", 49 | Material.CHISELED_NETHER_BRICKS, 50 | "&8Void Quarry", 51 | "&7Automatically mines overworld and nether ores", 52 | "", 53 | MachineLore.speed(6), 54 | MachineLore.energyPerSecond(3600) 55 | ); 56 | public static final SlimefunItemStack INFINITY_QUARRY = new SlimefunItemStack( 57 | "INFINITY_QUARRY", 58 | Material.CHISELED_POLISHED_BLACKSTONE, 59 | "&bInfinity Quarry", 60 | "&7Automatically mines overworld and nether ores", 61 | "", 62 | MachineLore.speed(64), 63 | MachineLore.energyPerSecond(36000) 64 | ); 65 | public static final double DIAMOND_CHANCE = getOscillatorChance("diamond"); 66 | public static final double REDSTONE_CHANCE = getOscillatorChance("redstone"); 67 | public static final double LAPIS_CHANCE = getOscillatorChance("lapis"); 68 | public static final double EMERALD_CHANCE = getOscillatorChance("emerald"); 69 | public static final double QUARTZ_CHANCE = getOscillatorChance("quartz"); 70 | public static final SlimefunItemStack DIAMOND_OSCILLATOR = Oscillator.create(Material.DIAMOND, DIAMOND_CHANCE); 71 | public static final SlimefunItemStack REDSTONE_OSCILLATOR = Oscillator.create(Material.REDSTONE, REDSTONE_CHANCE); 72 | public static final SlimefunItemStack LAPIS_OSCILLATOR = Oscillator.create(Material.LAPIS_LAZULI, LAPIS_CHANCE); 73 | public static final SlimefunItemStack QUARTZ_OSCILLATOR = Oscillator.create(Material.QUARTZ, QUARTZ_CHANCE); 74 | public static final SlimefunItemStack EMERALD_OSCILLATOR = Oscillator.create(Material.EMERALD, EMERALD_CHANCE); 75 | 76 | private static double getOscillatorChance(String type) { 77 | return InfinityExpansion.config().getDouble("quarry-options.oscillators." + type, 0, 1); 78 | } 79 | 80 | public static void setup(InfinityExpansion plugin) { 81 | ConfigurationSection section = plugin.getConfig().getConfigurationSection("quarry-options.resources"); 82 | Objects.requireNonNull(section); 83 | List outputs = new ArrayList<>(); 84 | 85 | boolean coal = section.getBoolean("coal"); 86 | 87 | if (coal) { 88 | outputs.add(Material.COAL); 89 | outputs.add(Material.COAL); 90 | } 91 | 92 | if (section.getBoolean("iron")) { 93 | outputs.add(Material.IRON_INGOT); 94 | } 95 | 96 | if (section.getBoolean("gold")) { 97 | outputs.add(Material.GOLD_INGOT); 98 | } 99 | 100 | if (Slimefun.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_17) && section.getBoolean("copper")) { 101 | outputs.add(Material.COPPER_INGOT); 102 | outputs.add(Material.COPPER_INGOT); 103 | } 104 | 105 | if (section.getBoolean("redstone")) { 106 | new Oscillator(REDSTONE_OSCILLATOR, REDSTONE_CHANCE).register(plugin); 107 | outputs.add(Material.REDSTONE); 108 | } 109 | 110 | if (section.getBoolean("lapis")) { 111 | new Oscillator(LAPIS_OSCILLATOR, LAPIS_CHANCE).register(plugin); 112 | outputs.add(Material.LAPIS_LAZULI); 113 | } 114 | 115 | if (section.getBoolean("emerald")) { 116 | new Oscillator(EMERALD_OSCILLATOR, EMERALD_CHANCE).register(plugin); 117 | outputs.add(Material.EMERALD); 118 | } 119 | 120 | if (section.getBoolean("diamond")) { 121 | new Oscillator(DIAMOND_OSCILLATOR, DIAMOND_CHANCE).register(plugin); 122 | outputs.add(Material.DIAMOND); 123 | } 124 | 125 | new Quarry(Groups.ADVANCED_MACHINES, BASIC_QUARRY, RecipeType.ENHANCED_CRAFTING_TABLE, new ItemStack[] { 126 | Materials.MAGSTEEL_PLATE, SlimefunItems.CARBONADO_EDGED_CAPACITOR, Materials.MAGSTEEL_PLATE, 127 | new ItemStack(Material.IRON_PICKAXE), SlimefunItems.GEO_MINER, new ItemStack(Material.IRON_PICKAXE), 128 | Materials.MACHINE_CIRCUIT, Materials.MACHINE_CORE, Materials.MACHINE_CIRCUIT 129 | }, 1, 6, outputs.toArray(new Material[0])).energyPerTick(300).register(plugin); 130 | 131 | if (section.getBoolean("quartz")) { 132 | new Oscillator(QUARTZ_OSCILLATOR, QUARTZ_CHANCE).register(plugin); 133 | 134 | outputs.add(Material.QUARTZ); 135 | } 136 | 137 | if (section.getBoolean("netherite")) { 138 | outputs.add(Material.NETHERITE_INGOT); 139 | } 140 | 141 | if (section.getBoolean("netherrack")) { 142 | outputs.add(Material.NETHERRACK); 143 | outputs.add(Material.NETHERRACK); 144 | } 145 | 146 | new Quarry(Groups.ADVANCED_MACHINES, ADVANCED_QUARRY, RecipeType.ENHANCED_CRAFTING_TABLE, new ItemStack[] { 147 | Materials.MACHINE_PLATE, SlimefunItems.ENERGIZED_CAPACITOR, Materials.MACHINE_PLATE, 148 | new ItemStack(Material.DIAMOND_PICKAXE), BASIC_QUARRY, new ItemStack(Material.DIAMOND_PICKAXE), 149 | Materials.MACHINE_CIRCUIT, Materials.MACHINE_CORE, Materials.MACHINE_CIRCUIT 150 | }, 2, 4, outputs.toArray(new Material[0])).energyPerTick(900).register(plugin); 151 | 152 | if (coal) { 153 | outputs.add(Material.COAL); 154 | } 155 | 156 | new Quarry(Groups.ADVANCED_MACHINES, VOID_QUARRY, RecipeType.ENHANCED_CRAFTING_TABLE, new ItemStack[] { 157 | Materials.VOID_INGOT, SlimefunExtension.VOID_CAPACITOR, Materials.VOID_INGOT, 158 | new ItemStack(Material.NETHERITE_PICKAXE), ADVANCED_QUARRY, new ItemStack(Material.NETHERITE_PICKAXE), 159 | Materials.MACHINE_CIRCUIT, Materials.MACHINE_CORE, Materials.MACHINE_CIRCUIT 160 | }, 6, 2, outputs.toArray(new Material[0])).energyPerTick(3600).register(plugin); 161 | 162 | if (coal) { 163 | outputs.add(Material.COAL); 164 | } 165 | 166 | new Quarry(Groups.INFINITY_CHEAT, INFINITY_QUARRY, InfinityWorkbench.TYPE, new ItemStack[] { 167 | null, Materials.MACHINE_PLATE, Materials.MACHINE_PLATE, Materials.MACHINE_PLATE, Materials.MACHINE_PLATE, null, 168 | Materials.MACHINE_PLATE, Gear.PICKAXE, Materials.INFINITE_CIRCUIT, Materials.INFINITE_CIRCUIT, Gear.PICKAXE, Materials.MACHINE_PLATE, 169 | Materials.MACHINE_PLATE, VOID_QUARRY, Materials.INFINITE_CORE, Materials.INFINITE_CORE, VOID_QUARRY, Materials.MACHINE_PLATE, 170 | Materials.VOID_INGOT, null, Materials.INFINITE_INGOT, Materials.INFINITE_INGOT, null, Materials.VOID_INGOT, 171 | Materials.VOID_INGOT, null, Materials.INFINITE_INGOT, Materials.INFINITE_INGOT, null, Materials.VOID_INGOT, 172 | Materials.VOID_INGOT, null, Materials.INFINITE_INGOT, Materials.INFINITE_INGOT, null, Materials.VOID_INGOT 173 | }, 64, 1, outputs.toArray(new Material[0])).energyPerTick(36000).register(plugin); 174 | } 175 | 176 | } 177 | -------------------------------------------------------------------------------- /src/main/java/io/github/mooy1/infinityexpansion/items/quarries/Quarry.java: -------------------------------------------------------------------------------- 1 | package io.github.mooy1.infinityexpansion.items.quarries; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.concurrent.ThreadLocalRandom; 6 | 7 | import javax.annotation.Nonnull; 8 | import javax.annotation.ParametersAreNonnullByDefault; 9 | 10 | import org.bukkit.Material; 11 | import org.bukkit.World; 12 | import org.bukkit.block.Block; 13 | import org.bukkit.entity.Player; 14 | import org.bukkit.inventory.ItemStack; 15 | 16 | import io.github.mooy1.infinityexpansion.InfinityExpansion; 17 | import io.github.mooy1.infinitylib.machines.AbstractMachineBlock; 18 | import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup; 19 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; 20 | import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; 21 | import io.github.thebusybiscuit.slimefun4.core.attributes.RecipeDisplayItem; 22 | import io.github.thebusybiscuit.slimefun4.libraries.dough.items.CustomItemStack; 23 | import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils; 24 | import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu; 25 | import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset; 26 | import me.mrCookieSlime.Slimefun.api.inventory.DirtyChestMenu; 27 | 28 | /** 29 | * Mines stuff 30 | * 31 | * @author Mooy1 32 | */ 33 | @ParametersAreNonnullByDefault 34 | public final class Quarry extends AbstractMachineBlock implements RecipeDisplayItem { 35 | 36 | private static final boolean ALLOW_NETHER_IN_OVERWORLD = 37 | InfinityExpansion.config().getBoolean("quarry-options.output-nether-materials-in-overworld"); 38 | private static final int INTERVAL = 39 | InfinityExpansion.config().getInt("quarry-options.ticks-per-output", 1, 100); 40 | private static final ItemStack MINING = new CustomItemStack(Material.LIME_STAINED_GLASS_PANE, "&aMining..."); 41 | private static final ItemStack OSCILLATOR_INFO = new CustomItemStack( 42 | Material.CYAN_STAINED_GLASS_PANE, 43 | "&bOscillator Slot", 44 | "&7Place a quarry oscillator to", 45 | "&7boost certain material's rates!" 46 | ); 47 | private static final int[] OUTPUT_SLOTS = { 48 | 9, 10, 11, 12, 13, 14, 15, 16, 17, 49 | 18, 19, 20, 21, 22, 23, 24, 25, 26, 50 | 27, 28, 29, 30, 31, 32, 33, 34, 35, 51 | 36, 37, 38, 39, 40, 41, 42, 43, 44 52 | }; 53 | private static final int OSCILLATOR_SLOT = 49; 54 | private static final int STATUS_SLOT = 4; 55 | 56 | private final int speed; 57 | private final int chance; 58 | private final Material[] outputs; 59 | 60 | public Quarry(ItemGroup category, SlimefunItemStack item, RecipeType type, ItemStack[] recipe, 61 | int speed, int chance, Material... outputs) { 62 | super(category, item, type, recipe); 63 | 64 | this.speed = speed; 65 | this.chance = chance; 66 | this.outputs = outputs; 67 | } 68 | 69 | @Override 70 | protected void setup(@Nonnull BlockMenuPreset blockMenuPreset) { 71 | blockMenuPreset.drawBackground(new int[] { 72 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 45, 46, 47, 51, 52, 53 73 | }); 74 | blockMenuPreset.addItem(48, OSCILLATOR_INFO, ChestMenuUtils.getEmptyClickHandler()); 75 | blockMenuPreset.addItem(50, OSCILLATOR_INFO, ChestMenuUtils.getEmptyClickHandler()); 76 | } 77 | 78 | @Override 79 | protected int[] getInputSlots(DirtyChestMenu menu, ItemStack item) { 80 | return new int[0]; 81 | } 82 | 83 | @Override 84 | protected int[] getInputSlots() { 85 | return new int[] { OSCILLATOR_SLOT }; 86 | } 87 | 88 | @Override 89 | protected int[] getOutputSlots() { 90 | return OUTPUT_SLOTS; 91 | } 92 | 93 | @Override 94 | public void onNewInstance(@Nonnull BlockMenu menu, @Nonnull Block b) { 95 | 96 | } 97 | 98 | @Override 99 | protected boolean process(Block b, BlockMenu inv) { 100 | if (inv.hasViewer()) { 101 | inv.replaceExistingItem(STATUS_SLOT, MINING); 102 | } 103 | 104 | if (InfinityExpansion.slimefunTickCount() % INTERVAL != 0) { 105 | return true; 106 | } 107 | 108 | ItemStack outputItem; 109 | 110 | if (ThreadLocalRandom.current().nextInt(this.chance) == 0) { 111 | Oscillator oscillator = Oscillator.getOscillator(inv.getItemInSlot(OSCILLATOR_SLOT)); 112 | if (oscillator == null || ThreadLocalRandom.current().nextDouble() >= oscillator.chance) { 113 | Material outputType = this.outputs[ThreadLocalRandom.current().nextInt(this.outputs.length)]; 114 | if (!ALLOW_NETHER_IN_OVERWORLD && b.getWorld().getEnvironment() != World.Environment.NETHER && 115 | (outputType == Material.QUARTZ || outputType == Material.NETHERITE_INGOT || outputType == Material.NETHERRACK) 116 | ) { 117 | outputItem = new ItemStack(Material.COBBLESTONE, this.speed); 118 | } 119 | else { 120 | outputItem = new ItemStack(outputType, this.speed); 121 | } 122 | } 123 | else { 124 | outputItem = new ItemStack(oscillator.getItem().getType(), this.speed); 125 | } 126 | } 127 | else { 128 | outputItem = new ItemStack(Material.COBBLESTONE, this.speed); 129 | } 130 | 131 | inv.pushItem(outputItem, OUTPUT_SLOTS); 132 | return true; 133 | } 134 | 135 | @Override 136 | protected int getStatusSlot() { 137 | return STATUS_SLOT; 138 | } 139 | 140 | @Nonnull 141 | @Override 142 | public List getDisplayRecipes() { 143 | List items = new ArrayList<>(); 144 | 145 | items.add(new ItemStack(Material.COBBLESTONE, this.speed)); 146 | for (Material mat : this.outputs) { 147 | items.add(new ItemStack(mat, this.speed)); 148 | } 149 | 150 | return items; 151 | } 152 | 153 | @Nonnull 154 | @Override 155 | public String getRecipeSectionLabel(@Nonnull Player p) { 156 | return "&7Mines:"; 157 | } 158 | 159 | } 160 | -------------------------------------------------------------------------------- /src/main/java/io/github/mooy1/infinityexpansion/items/storage/Storage.java: -------------------------------------------------------------------------------- 1 | package io.github.mooy1.infinityexpansion.items.storage; 2 | 3 | import lombok.experimental.UtilityClass; 4 | 5 | import org.bukkit.Material; 6 | import org.bukkit.inventory.ItemStack; 7 | 8 | import io.github.mooy1.infinityexpansion.InfinityExpansion; 9 | import io.github.mooy1.infinityexpansion.categories.Groups; 10 | import io.github.mooy1.infinityexpansion.items.materials.Materials; 11 | import io.github.mooy1.infinitylib.machines.MachineLore; 12 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; 13 | import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; 14 | 15 | @UtilityClass 16 | public final class Storage { 17 | 18 | public static final SlimefunItemStack STORAGE_FORGE = new SlimefunItemStack( 19 | "STORAGE_FORGE", 20 | Material.BEEHIVE, 21 | "&6Storage Forge", 22 | "&7Upgrades the tier of Storage Units", 23 | "&7Retains stored items" 24 | ); 25 | 26 | private static final int BASIC_AMOUNT = 6400; 27 | private static final int ADVANCED_AMOUNT = 25600; 28 | private static final int REINFORCED_AMOUNT = 102400; 29 | private static final int VOID_AMOUNT = 409600; 30 | private static final int INFINITY_AMOUNT = 1_600_000_000; 31 | 32 | public static final SlimefunItemStack BASIC_STORAGE = new SlimefunItemStack( 33 | "BASIC_STORAGE", 34 | Material.OAK_WOOD, 35 | "&9Basic &8Storage Unit", 36 | "&6Capacity: &e" + MachineLore.format(BASIC_AMOUNT) + " &eitems" 37 | ); 38 | public static final SlimefunItemStack ADVANCED_STORAGE = new SlimefunItemStack( 39 | "ADVANCED_STORAGE", 40 | Material.DARK_OAK_WOOD, 41 | "&cAdvanced &8Storage Unit", 42 | "&6Capacity: &e" + MachineLore.format(ADVANCED_AMOUNT) + " &eitems" 43 | ); 44 | public static final SlimefunItemStack REINFORCED_STORAGE = new SlimefunItemStack( 45 | "REINFORCED_STORAGE", 46 | Material.ACACIA_WOOD, 47 | "&fReinforced &8Storage Unit", 48 | "&6Capacity: &e" + MachineLore.format(REINFORCED_AMOUNT) + " &eitems" 49 | ); 50 | public static final SlimefunItemStack VOID_STORAGE = new SlimefunItemStack( 51 | "VOID_STORAGE", 52 | Material.CRIMSON_HYPHAE, 53 | "&8Void &8Storage Unit", 54 | "&6Capacity: &e" + MachineLore.format(VOID_AMOUNT) + " &eitems" 55 | ); 56 | public static final SlimefunItemStack INFINITY_STORAGE = new SlimefunItemStack( 57 | "INFINITY_STORAGE", 58 | Material.WARPED_HYPHAE, 59 | "&bInfinity &8Storage Unit", 60 | "&6Capacity: &e" + MachineLore.format(INFINITY_AMOUNT) + " &eitems" 61 | ); 62 | 63 | public static void setup(InfinityExpansion plugin) { 64 | new StorageForge(Groups.STORAGE, STORAGE_FORGE, RecipeType.ENHANCED_CRAFTING_TABLE, new ItemStack[] { 65 | Materials.MAGSTEEL, new ItemStack(Material.ANVIL), Materials.MAGSTEEL, 66 | Materials.MAGSTEEL, new ItemStack(Material.CRAFTING_TABLE), Materials.MAGSTEEL, 67 | Materials.MAGSTEEL, new ItemStack(Material.BARREL), Materials.MAGSTEEL, 68 | }).register(plugin); 69 | new StorageUnit(BASIC_STORAGE, BASIC_AMOUNT, new ItemStack[] { 70 | new ItemStack(Material.OAK_LOG), Materials.MAGSTEEL, new ItemStack(Material.OAK_LOG), 71 | new ItemStack(Material.OAK_LOG), new ItemStack(Material.BARREL), new ItemStack(Material.OAK_LOG), 72 | new ItemStack(Material.OAK_LOG), Materials.MAGSTEEL, new ItemStack(Material.OAK_LOG) 73 | }).register(plugin); 74 | new StorageUnit(ADVANCED_STORAGE, ADVANCED_AMOUNT, new ItemStack[] { 75 | Materials.MAGSTEEL, Materials.MACHINE_CIRCUIT, Materials.MAGSTEEL, 76 | Materials.MAGSTEEL, BASIC_STORAGE, Materials.MAGSTEEL, 77 | Materials.MAGSTEEL, Materials.MACHINE_CIRCUIT, Materials.MAGSTEEL 78 | }).register(plugin); 79 | new StorageUnit(REINFORCED_STORAGE, REINFORCED_AMOUNT, new ItemStack[] { 80 | Materials.MAGSTEEL_PLATE, Materials.MACHINE_CIRCUIT, Materials.MAGSTEEL_PLATE, 81 | Materials.MAGSTEEL_PLATE, ADVANCED_STORAGE, Materials.MAGSTEEL_PLATE, 82 | Materials.MAGSTEEL_PLATE, Materials.MACHINE_PLATE, Materials.MAGSTEEL_PLATE 83 | }).register(plugin); 84 | new StorageUnit(VOID_STORAGE, VOID_AMOUNT, new ItemStack[] { 85 | Materials.VOID_INGOT, Materials.MACHINE_PLATE, Materials.VOID_INGOT, 86 | Materials.MAGNONIUM, REINFORCED_STORAGE, Materials.MAGNONIUM, 87 | Materials.VOID_INGOT, Materials.MACHINE_CORE, Materials.VOID_INGOT 88 | }).register(plugin); 89 | new StorageUnit(INFINITY_STORAGE, INFINITY_AMOUNT, new ItemStack[] { 90 | Materials.INFINITE_INGOT, Materials.VOID_INGOT, Materials.INFINITE_INGOT, 91 | Materials.INFINITE_INGOT, VOID_STORAGE, Materials.INFINITE_INGOT, 92 | Materials.INFINITE_INGOT, Materials.VOID_INGOT, Materials.INFINITE_INGOT 93 | }).register(plugin); 94 | } 95 | 96 | } 97 | -------------------------------------------------------------------------------- /src/main/java/io/github/mooy1/infinityexpansion/items/storage/StorageForge.java: -------------------------------------------------------------------------------- 1 | package io.github.mooy1.infinityexpansion.items.storage; 2 | 3 | import javax.annotation.ParametersAreNonnullByDefault; 4 | 5 | import org.bukkit.inventory.ItemStack; 6 | 7 | import io.github.mooy1.infinitylib.machines.CraftingBlock; 8 | import io.github.mooy1.infinitylib.machines.MachineRecipeType; 9 | import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup; 10 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; 11 | import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; 12 | import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu; 13 | 14 | /** 15 | * A crafting machine for upgrading storage units and retaining the stored items 16 | * 17 | * @author Mooy1 18 | */ 19 | @ParametersAreNonnullByDefault 20 | public final class StorageForge extends CraftingBlock { 21 | 22 | public static final MachineRecipeType TYPE = new MachineRecipeType("storage_forge", Storage.STORAGE_FORGE); 23 | 24 | public StorageForge(ItemGroup category, SlimefunItemStack stack, RecipeType type, ItemStack[] recipe) { 25 | super(category, stack, type, recipe); 26 | addRecipesFrom(TYPE); 27 | } 28 | 29 | @Override 30 | protected void onSuccessfulCraft(BlockMenu menu, ItemStack toOutput) { 31 | StorageUnit.transferToStack(menu.getItemInSlot(layout.inputSlots()[4]), toOutput); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/io/github/mooy1/infinityexpansion/items/storage/StorageSaveFix.java: -------------------------------------------------------------------------------- 1 | package io.github.mooy1.infinityexpansion.items.storage; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | import java.nio.file.Files; 6 | import java.util.HashMap; 7 | import java.util.Iterator; 8 | import java.util.List; 9 | import java.util.Map; 10 | import java.util.logging.Level; 11 | import java.util.logging.Logger; 12 | 13 | import lombok.experimental.UtilityClass; 14 | 15 | import io.github.thebusybiscuit.slimefun4.libraries.dough.common.CommonPatterns; 16 | 17 | @UtilityClass 18 | public final class StorageSaveFix { 19 | 20 | public static void fixStuff(Logger logger) { 21 | long time = System.nanoTime(); 22 | 23 | File folder = new File("data-storage/Slimefun/stored-blocks/"); 24 | if (!folder.exists()) { 25 | return; 26 | } 27 | 28 | int fixed = 0; 29 | String[] ids = new String[] { 30 | "INFINITY_STORAGE", 31 | "VOID_STORAGE", 32 | "REINFORCED_STORAGE", 33 | "ADVANCED_STORAGE", 34 | "BASIC_STORAGE" 35 | }; 36 | 37 | for (File world : folder.listFiles()) { 38 | String name = world.getName(); 39 | int locationBeginIndex = name.length() + 1; 40 | Map locations = new HashMap<>(); 41 | 42 | for (String id : ids) { 43 | File storages = new File(world, id + ".sfb"); 44 | 45 | if (!storages.exists()) { 46 | continue; 47 | } 48 | 49 | List lines; 50 | boolean changed = false; 51 | 52 | try { 53 | lines = Files.readAllLines(storages.toPath()); 54 | } catch (IOException e) { 55 | e.printStackTrace(); 56 | continue; 57 | } 58 | 59 | Iterator iterator = lines.listIterator(); 60 | while (iterator.hasNext()) { 61 | String line = iterator.next(); 62 | String location = line.substring(locationBeginIndex, line.indexOf(':')); 63 | String correct = locations.get(location); 64 | 65 | if (correct == null) { 66 | locations.put(location, id); 67 | } else { 68 | iterator.remove(); 69 | changed = true; 70 | if (fixed++ < 25) { 71 | String[] cords = CommonPatterns.SEMICOLON.split(location); 72 | logger.log(Level.INFO, "Fixed bugged " + correct + " in " 73 | + name + " @ " 74 | + cords[0] + ", " 75 | + cords[1] + ", " 76 | + cords[2]); 77 | } 78 | } 79 | } 80 | 81 | if (changed) try { 82 | Files.write(storages.toPath(), lines); 83 | } catch (IOException e) { 84 | e.printStackTrace(); 85 | } 86 | } 87 | } 88 | 89 | time = System.nanoTime() - time; 90 | if (fixed > 0) { 91 | logger.log(Level.INFO, "Fixed " + fixed + " bugged storage(s) in " + (time / 1000000) + " ms"); 92 | } 93 | } 94 | 95 | } 96 | -------------------------------------------------------------------------------- /src/main/java/io/github/mooy1/infinityexpansion/items/storage/StorageUnit.java: -------------------------------------------------------------------------------- 1 | package io.github.mooy1.infinityexpansion.items.storage; 2 | 3 | import java.util.Collection; 4 | import java.util.Collections; 5 | import java.util.HashMap; 6 | import java.util.List; 7 | import java.util.Map; 8 | 9 | import javax.annotation.Nonnull; 10 | import javax.annotation.Nullable; 11 | import javax.annotation.ParametersAreNonnullByDefault; 12 | 13 | import org.bukkit.ChatColor; 14 | import org.bukkit.Location; 15 | import org.bukkit.Material; 16 | import org.bukkit.NamespacedKey; 17 | import org.bukkit.block.Block; 18 | import org.bukkit.event.block.BlockBreakEvent; 19 | import org.bukkit.event.block.BlockPlaceEvent; 20 | import org.bukkit.inventory.ItemStack; 21 | import org.bukkit.inventory.meta.ItemMeta; 22 | import org.bukkit.persistence.PersistentDataContainer; 23 | import org.bukkit.persistence.PersistentDataType; 24 | 25 | import io.github.mooy1.infinityexpansion.InfinityExpansion; 26 | import io.github.mooy1.infinityexpansion.categories.Groups; 27 | import io.github.mooy1.infinitylib.common.PersistentType; 28 | import io.github.mooy1.infinitylib.common.Scheduler; 29 | import io.github.mooy1.infinitylib.machines.MenuBlock; 30 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem; 31 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; 32 | import io.github.thebusybiscuit.slimefun4.core.attributes.DistinctiveItem; 33 | import io.github.thebusybiscuit.slimefun4.core.handlers.BlockBreakHandler; 34 | import io.github.thebusybiscuit.slimefun4.libraries.dough.collections.Pair; 35 | import io.github.thebusybiscuit.slimefun4.libraries.dough.items.CustomItemStack; 36 | import io.github.thebusybiscuit.slimefun4.libraries.dough.items.ItemUtils; 37 | import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils; 38 | import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config; 39 | import me.mrCookieSlime.Slimefun.Objects.handlers.BlockTicker; 40 | import me.mrCookieSlime.Slimefun.api.BlockStorage; 41 | import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu; 42 | import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset; 43 | import me.mrCookieSlime.Slimefun.api.inventory.DirtyChestMenu; 44 | 45 | /** 46 | * A block that stored large amounts of 1 item 47 | * 48 | * @author Mooy1 49 | * 50 | * Thanks to FluffyBear for stuff to learn from 51 | */ 52 | @ParametersAreNonnullByDefault 53 | public final class StorageUnit extends MenuBlock implements DistinctiveItem { 54 | 55 | /* Namespaced keys */ 56 | static final NamespacedKey EMPTY_KEY = InfinityExpansion.createKey("empty"); // key for empty item 57 | static final NamespacedKey DISPLAY_KEY = InfinityExpansion.createKey("display"); // key for display item 58 | private static final NamespacedKey ITEM_KEY = InfinityExpansion.createKey("item"); // item key for item pdc 59 | private static final NamespacedKey AMOUNT_KEY = InfinityExpansion.createKey("stored"); // amount key for item pdc 60 | 61 | /* Menu slots */ 62 | static final int INPUT_SLOT = 10; 63 | static final int DISPLAY_SLOT = 13; 64 | static final int STATUS_SLOT = 4; 65 | static final int OUTPUT_SLOT = 16; 66 | static final int INTERACT_SLOT = 22; 67 | 68 | /* Menu items */ 69 | private static final ItemStack INTERACTION_ITEM = new CustomItemStack(Material.LIME_STAINED_GLASS_PANE, 70 | "&aQuick Actions", 71 | "&bLeft Click: &7Withdraw 1 item", 72 | "&bRight Click: &7Withdraw 1 stack", 73 | "&bShift Left Click: &7Deposit inventory", 74 | "&bShift Right Click: &7Withdraw inventory" 75 | ); 76 | private static final ItemStack LOADING_ITEM = new CustomItemStack(Material.CYAN_STAINED_GLASS_PANE, 77 | "&bStatus", 78 | "&7Loading..." 79 | ); 80 | 81 | /* Instance constants */ 82 | private final Map caches = new HashMap<>(); 83 | final int max; 84 | 85 | public StorageUnit(SlimefunItemStack item, int max, ItemStack[] recipe) { 86 | super(Groups.STORAGE, item, StorageForge.TYPE, recipe); 87 | this.max = max; 88 | 89 | addItemHandler(new BlockTicker() { 90 | 91 | @Override 92 | public boolean isSynchronized() { 93 | return true; 94 | } 95 | 96 | @Override 97 | public void tick(Block b, SlimefunItem item, Config data) { 98 | StorageCache cache = StorageUnit.this.caches.get(b.getLocation()); 99 | if (cache != null) { 100 | cache.tick(b); 101 | } 102 | } 103 | 104 | }, new BlockBreakHandler(false, false) { 105 | 106 | @Override 107 | public void onPlayerBreak(BlockBreakEvent e, ItemStack item, List drops) { 108 | BlockMenu menu = BlockStorage.getInventory(e.getBlock()); 109 | StorageCache cache = StorageUnit.this.caches.remove(menu.getLocation()); 110 | if (cache != null && !cache.isEmpty()) { 111 | cache.destroy(e, drops); 112 | } 113 | else { 114 | drops.add(getItem().clone()); 115 | } 116 | menu.dropItems(menu.getLocation(), INPUT_SLOT, OUTPUT_SLOT); 117 | } 118 | 119 | }); 120 | } 121 | 122 | @Override 123 | protected void onNewInstance(@Nonnull BlockMenu menu, @Nonnull Block b) { 124 | if (BlockStorage.getInventory(b) == menu) { 125 | this.caches.put(b.getLocation(), new StorageCache(this, menu)); 126 | } 127 | } 128 | 129 | @Nonnull 130 | @Override 131 | public Collection getDrops() { 132 | return Collections.emptyList(); 133 | } 134 | 135 | @Override 136 | protected void onPlace(@Nonnull BlockPlaceEvent e, @Nonnull Block b) { 137 | Pair data = loadFromStack(e.getItemInHand()); 138 | if (data != null) { 139 | Scheduler.run(() -> { 140 | StorageCache cache = this.caches.get(b.getLocation()); 141 | cache.load(data.getFirstValue(), data.getFirstValue().getItemMeta()); 142 | cache.amount(data.getSecondValue()); 143 | }); 144 | } 145 | } 146 | 147 | @Override 148 | protected void setup(@Nonnull BlockMenuPreset blockMenuPreset) { 149 | blockMenuPreset.drawBackground(INPUT_BORDER, new int[] { 150 | 0, 1, 2, 9, 11, 18, 19, 20 151 | }); 152 | blockMenuPreset.drawBackground(BACKGROUND_ITEM, new int[] { 153 | 3, 5, 12, 14, 21, 23 154 | }); 155 | blockMenuPreset.drawBackground(OUTPUT_BORDER, new int[] { 156 | 6, 7, 8, 15, 17, 24, 25, 26 157 | }); 158 | blockMenuPreset.addMenuClickHandler(DISPLAY_SLOT, ChestMenuUtils.getEmptyClickHandler()); 159 | blockMenuPreset.addItem(INTERACT_SLOT, INTERACTION_ITEM); 160 | blockMenuPreset.addItem(STATUS_SLOT, LOADING_ITEM); 161 | } 162 | 163 | @Nonnull 164 | @Override 165 | protected int[] getInputSlots(DirtyChestMenu dirtyChestMenu, ItemStack itemStack) { 166 | StorageCache cache = this.caches.get(((BlockMenu) dirtyChestMenu).getLocation()); 167 | if (cache != null && (cache.isEmpty() || cache.matches(itemStack))) { 168 | cache.input(); 169 | return new int[] { INPUT_SLOT }; 170 | } 171 | else { 172 | return new int[0]; 173 | } 174 | } 175 | 176 | @Override 177 | protected int[] getInputSlots() { 178 | return new int[] { INPUT_SLOT }; 179 | } 180 | 181 | @Override 182 | protected int[] getOutputSlots() { 183 | return new int[] { OUTPUT_SLOT }; 184 | } 185 | 186 | public void reloadCache(Block b) { 187 | this.caches.get(b.getLocation()).reloadData(); 188 | } 189 | 190 | @Nullable 191 | public StorageCache getCache(Location location) { 192 | return this.caches.get(location); 193 | } 194 | 195 | static void transferToStack(@Nonnull ItemStack source, @Nonnull ItemStack target) { 196 | Pair data = loadFromStack(source); 197 | if (data != null) { 198 | target.setItemMeta(saveToStack(target.getItemMeta(), data.getFirstValue(), 199 | ItemUtils.getItemName(data.getFirstValue()), data.getSecondValue())); 200 | } 201 | } 202 | 203 | static ItemMeta saveToStack(ItemMeta meta, ItemStack displayItem, String displayName, int amount) { 204 | if (meta.hasLore()) { 205 | List lore = meta.getLore(); 206 | lore.add(ChatColor.GOLD + "Stored: " + displayName + ChatColor.YELLOW + " x " + amount); 207 | meta.setLore(lore); 208 | } 209 | meta.getPersistentDataContainer().set(ITEM_KEY, PersistentType.ITEM_STACK_OLD, displayItem); 210 | meta.getPersistentDataContainer().set(AMOUNT_KEY, PersistentDataType.INTEGER, amount); 211 | return meta; 212 | } 213 | 214 | @Nullable 215 | private static Pair loadFromStack(ItemStack source) { 216 | if (source.hasItemMeta()) { 217 | PersistentDataContainer con = source.getItemMeta().getPersistentDataContainer(); 218 | Integer amount = con.get(AMOUNT_KEY, PersistentDataType.INTEGER); 219 | if (amount != null) { 220 | ItemStack item = con.get(ITEM_KEY, PersistentType.ITEM_STACK_OLD); 221 | if (item != null) { 222 | return new Pair<>(item, amount); 223 | } 224 | } 225 | } 226 | return null; 227 | } 228 | 229 | @Override 230 | public boolean canStack(@Nonnull ItemMeta sfItemMeta, @Nonnull ItemMeta itemMeta) { 231 | return sfItemMeta.getPersistentDataContainer().equals(itemMeta.getPersistentDataContainer()); 232 | } 233 | } 234 | -------------------------------------------------------------------------------- /src/main/java/io/github/mooy1/infinityexpansion/utils/Util.java: -------------------------------------------------------------------------------- 1 | package io.github.mooy1.infinityexpansion.utils; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | import java.util.List; 6 | import java.util.Map; 7 | import java.util.logging.Level; 8 | 9 | import javax.annotation.Nonnull; 10 | import javax.annotation.Nullable; 11 | 12 | import lombok.experimental.UtilityClass; 13 | 14 | import org.bukkit.ChatColor; 15 | import org.bukkit.Location; 16 | import org.bukkit.block.Block; 17 | import org.bukkit.block.data.BlockData; 18 | import org.bukkit.block.data.Waterlogged; 19 | import org.bukkit.configuration.ConfigurationSection; 20 | import org.bukkit.enchantments.Enchantment; 21 | import org.bukkit.inventory.ItemStack; 22 | import org.bukkit.inventory.meta.ItemMeta; 23 | 24 | import io.github.mooy1.infinityexpansion.InfinityExpansion; 25 | import me.mrCookieSlime.Slimefun.api.BlockStorage; 26 | 27 | @UtilityClass 28 | public final class Util { 29 | 30 | @Nonnull 31 | public static ItemStack getDisplayItem(@Nonnull ItemStack output) { 32 | ItemMeta meta = output.getItemMeta(); 33 | List lore; 34 | if (meta.hasLore()) { 35 | lore = meta.getLore(); 36 | } 37 | else { 38 | lore = new ArrayList<>(); 39 | } 40 | lore.add(""); 41 | lore.add(ChatColor.GREEN + "-------------------"); 42 | lore.add(ChatColor.GREEN + "\u21E8 Click to craft"); 43 | lore.add(ChatColor.GREEN + "-------------------"); 44 | output.setItemMeta(meta); 45 | return output; 46 | } 47 | 48 | @Nonnull 49 | public static Map getEnchants(@Nonnull ConfigurationSection section) { 50 | Map enchants = new HashMap<>(); 51 | for (String path : section.getKeys(false)) { 52 | Enchantment e = enchantmentByPath(path); 53 | if (e != null) { 54 | int level = section.getInt(path); 55 | if (level > 0 && level <= Short.MAX_VALUE) { 56 | enchants.put(e, level); 57 | } 58 | else if (level != 0) { 59 | section.set(path, 0); 60 | InfinityExpansion.log(Level.WARNING, 61 | "Enchantment level " + level 62 | + " is out of bounds for " + e.getKey() 63 | + ", resetting to default!" 64 | ); 65 | } 66 | } 67 | } 68 | return enchants; 69 | } 70 | 71 | @Nullable 72 | private static Enchantment enchantmentByPath(@Nonnull String path) { 73 | switch (path) { 74 | case "sharpness": 75 | return Enchantment.DAMAGE_ALL; 76 | case "smite": 77 | return Enchantment.DAMAGE_UNDEAD; 78 | case "bane-of-arthropods": 79 | return Enchantment.DAMAGE_ARTHROPODS; 80 | case "efficiency": 81 | return Enchantment.DIG_SPEED; 82 | case "protection": 83 | return Enchantment.PROTECTION_ENVIRONMENTAL; 84 | case "fire-aspect": 85 | return Enchantment.FIRE_ASPECT; 86 | case "fortune": 87 | return Enchantment.LOOT_BONUS_BLOCKS; 88 | case "looting": 89 | return Enchantment.LOOT_BONUS_MOBS; 90 | case "silk-touch": 91 | return Enchantment.SILK_TOUCH; 92 | case "thorns": 93 | return Enchantment.THORNS; 94 | case "aqua-affinity": 95 | return Enchantment.WATER_WORKER; 96 | case "power": 97 | return Enchantment.ARROW_DAMAGE; 98 | case "flame": 99 | return Enchantment.ARROW_FIRE; 100 | case "infinity": 101 | return Enchantment.ARROW_INFINITE; 102 | case "punch": 103 | return Enchantment.ARROW_KNOCKBACK; 104 | case "feather-falling": 105 | return Enchantment.PROTECTION_FALL; 106 | case "unbreaking": 107 | return Enchantment.DURABILITY; 108 | default: 109 | return null; 110 | } 111 | } 112 | 113 | public static boolean isWaterLogged(@Nonnull Block b) { 114 | if (InfinityExpansion.slimefunTickCount() % 63 == 0) { 115 | BlockData blockData = b.getBlockData(); 116 | 117 | if (blockData instanceof Waterlogged) { 118 | Waterlogged waterLogged = (Waterlogged) blockData; 119 | if (waterLogged.isWaterlogged()) { 120 | BlockStorage.addBlockInfo(b.getLocation(), "water_logged", "true"); 121 | return true; 122 | } 123 | else { 124 | BlockStorage.addBlockInfo(b.getLocation(), "water_logged", "false"); 125 | return false; 126 | } 127 | } 128 | else { 129 | return false; 130 | } 131 | 132 | } 133 | else { 134 | return "true".equals(BlockStorage.getLocationInfo(b.getLocation(), "water_logged")); 135 | } 136 | } 137 | 138 | public static int getIntData(String key, Location block) { 139 | String val = BlockStorage.getLocationInfo(block, key); 140 | if (val == null) { 141 | BlockStorage.addBlockInfo(block, key, "0"); 142 | return 0; 143 | } 144 | try { 145 | return Integer.parseInt(val); 146 | } catch (NumberFormatException x) { 147 | BlockStorage.addBlockInfo(block, key, "0"); 148 | return 0; 149 | } 150 | } 151 | 152 | } 153 | -------------------------------------------------------------------------------- /src/main/resources/config.yml: -------------------------------------------------------------------------------- 1 | 2 | # You should enable this to get bug fixes and receive support asap! 3 | auto-update: true 4 | 5 | balance-options: 6 | 7 | # Increases or decreases the cost of infinity singularities 8 | singularity-cost-multiplier: 1.0 9 | 10 | # Will allow the gear transformer to change slimefun gear's material. Diamond tools can already be upgraded to netherite, 11 | # but some addon developers do not want there gear to be transformable so change this at your own risk. 12 | allow-sf-item-transform: false 13 | 14 | # Enables/Disables Researches which requires players to spend xp to unlock items 15 | enable-researches: false 16 | 17 | mob-simulation-options: 18 | 19 | # The number of slimefun ticks it takes to output xp and drops. 1 slimefun tick = .5 seconds by default 20 | ticks-per-output: 20 21 | 22 | # Multiplies amount of xp gained from mob simulation 23 | xp-multiplier: 1.0 24 | 25 | quarry-options: 26 | 27 | # The chance (0 to 1) of an oscillator activating each time a material would be produced 28 | oscillators: 29 | lapis: .5 30 | diamond: .5 31 | redstone: .5 32 | quartz: .5 33 | emerald: .5 34 | 35 | # The number of slimefun ticks it takes to mine 1 block. 1 slimefun ticks = .6 seconds by default 36 | ticks-per-output: 10 37 | 38 | # Allow quarries to mine quartz, netherite, netherrack in any world 39 | output-nether-materials-in-overworld: false 40 | 41 | # Enable/Disable resources from being produced 42 | resources: 43 | 44 | coal: true 45 | iron: true 46 | gold: true 47 | lapis: true 48 | 49 | # Vanilla Copper (1.17+) 50 | copper: true 51 | quartz: true 52 | diamond: true 53 | emerald: true 54 | redstone: true 55 | netherite: true 56 | netherrack: true 57 | 58 | # These are the maximum level of enchants that can be obtained by combining 2 of the same enchant of the same level. 59 | advanced-anvil-max-levels: 60 | sharpness: 9 61 | bane-of-arthropods: 9 62 | smite: 9 63 | protection: 10 64 | fortune: 6 65 | efficiency: 7 66 | fire-aspect: 6 67 | power: 7 68 | thorns: 13 69 | looting: 6 70 | unbreaking: 13 71 | 72 | # levels of infinity gear. this will not affect existing items. adding more enchants wont have any effect, only change levels. 73 | # protection caps out at 20 levels across all 4 pieces of gear. So 10+10+10+10 is still the same as 5+5+5+5. 74 | infinity-enchant-levels: 75 | blade: 76 | unbreakable: true 77 | sharpness: 20 78 | looting: 10 79 | fire-aspect: 10 80 | pickaxe: 81 | unbreakable: true 82 | efficiency: 40 83 | fortune: 20 84 | shovel: 85 | unbreakable: true 86 | efficiency: 40 87 | silk-touch: 10 88 | axe: 89 | unbreakable: true 90 | efficiency: 40 91 | sharpness: 20 92 | fire-aspect: 10 93 | looting: 0 94 | silk-touch: 0 95 | bow: 96 | unbreakable: true 97 | power: 10 98 | flame: 10 99 | infinity: 10 100 | punch: 0 101 | crown: 102 | unbreakable: true 103 | protection: 20 104 | aqua-affinity: 10 105 | chestplate: 106 | unbreakable: true 107 | protection: 20 108 | thorns: 10 109 | leggings: 110 | unbreakable: true 111 | protection: 20 112 | thorns: 10 113 | boots: 114 | unbreakable: true 115 | protection: 20 116 | feather-falling: 0 117 | thorns: 0 118 | shield: 119 | unbreakable: true 120 | protection: 20 121 | thorns: 10 -------------------------------------------------------------------------------- /src/main/resources/plugin.yml: -------------------------------------------------------------------------------- 1 | name: InfinityExpansion 2 | author: Mooy1 3 | description: more slimefun content 4 | main: io.github.mooy1.infinityexpansion.InfinityExpansion 5 | website: https://github.com/Mooy1/InfinityExpansion 6 | depend: [Slimefun] 7 | softdepend: [LiteXpansion] 8 | version: ${project.version} 9 | api-version: 1.16 10 | 11 | commands: 12 | infinityexpansion: 13 | description: Use /infinityexpansion help for a list of commands 14 | usage: /infinityexpansion 15 | aliases: [ie, ix, infinity] 16 | 17 | permissions: 18 | infinityexpansion.setdata: 19 | description: Access to /infinityexpansion setdata 20 | default: op 21 | infinityexpansion.printitem: 22 | description: Access to /infinityexpansion printitem 23 | default: op 24 | infinityexpansion.giverecipe: 25 | description: Access to /infinityexpansion giverecipe 26 | default: op 27 | 28 | -------------------------------------------------------------------------------- /src/test/java/io/github/mooy1/infinityexpansion/TestInfinityExpansion.java: -------------------------------------------------------------------------------- 1 | package io.github.mooy1.infinityexpansion; 2 | 3 | import org.junit.jupiter.api.AfterAll; 4 | import org.junit.jupiter.api.BeforeAll; 5 | import org.junit.jupiter.api.Test; 6 | 7 | import be.seeseemelk.mockbukkit.MockBukkit; 8 | import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; 9 | 10 | class TestInfinityExpansion { 11 | 12 | @BeforeAll 13 | public static void load() { 14 | MockBukkit.mock(); 15 | MockBukkit.load(Slimefun.class); 16 | } 17 | 18 | @AfterAll 19 | public static void unload() { 20 | MockBukkit.unmock(); 21 | } 22 | 23 | @Test 24 | void testLoad() { 25 | MockBukkit.load(InfinityExpansion.class); 26 | } 27 | 28 | } 29 | --------------------------------------------------------------------------------