Skip to content

Commit

Permalink
multiblockcraft criterion, some optimizations
Browse files Browse the repository at this point in the history
  • Loading branch information
char3210 committed Dec 6, 2023
1 parent b99cc74 commit 12e75d6
Show file tree
Hide file tree
Showing 20 changed files with 204 additions and 50 deletions.
33 changes: 18 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,40 +107,43 @@ The name is what appears in the gui for progress. (Supports color codes with `&`
The type is the type of criterion. By default, these are the default criterion types:
- `consume`
- for eating items
- has an item parameter `item`, which is the item to consume
- note that this only works for vanilla consumption, NOT exotic garden fruits for example, use `interact` for that
- has an item parameter `item`, item to consume
- has an integer parameter `amount`, the number of items to consume
- `interact`
- for right-clicking items
- has an item parameter `item`, which is the item to be right-clicked
- has an item parameter `item`, the item to be right-clicked
- has an integer parameter `amount`, the number of times to interact
- `inventory`
- for having an item in an inventory
- has an item parameter `item`, the item to have in the inventory
- has an integer parameter `amount`, which is the number of items you need to complete the criterion
- has an integer parameter `amount`, the number of items you need to complete the criterion
- `multiblock`
- for interacting with a slimefun multiblock
- has a string parameter `multiblock`, which is the slimefun item id of the multiblock
- has a string parameter `multiblock`, the slimefun item id of the multiblock
- `place`
- for placing blocks
- has an item parameter `item`, which is the item to place down
- has an integer parameter `amount`, which is the number of items to place
- note that there is no protection against players repeatedly breaking and replacing the block, so for most items setting the `amount` to 1 would be appropriate
- has an item parameter `item`, the item to place down
- has an integer parameter `amount`, the number of items to place
- note that there is no protection against players repeatedly breaking and replacing the same block, so for most items setting the `amount` to 1 would be appropriate
- `break`
- like `place` but for breaking blocks, same parameters
- `research`
- for completing a research
- has a string parameter `research`, which is the namespaced key of the research
- namespaced keys have the format "plugin:key", so for slimefun researches, it is "slimefun:research"
- ex: "slimefun:ender_talismans"
- has a string parameter `research`, the namespaced key of the research
- namespaced keys have the format "plugin:key", so for slimefun researches, it is "slimefun:research", e.g. "slimefun:ender_talismans"
- `mobkill`
- for killing a type of mob
- int parameter 'amount', the number of mobs to kill
- has a string parameter `entity` which is the mob to kill
- entity types are generally lowercase, separated by underscores (ex. `stray`, `cave_spider`, `glow_squid`, etc.)
- has an integer parameter `amount`, the number of mobs to kill
- has a string parameter `entity`, the mob to kill
- entity types are generally lowercase, separated by underscores (ex. `stray`, `cave_spider`, `glow_squid`, etc.)
- `search`
- for searching for a string in the slimefun guide
- string parameter `search` which is the exact string to search for
- string parameter `search`, the exact string to search for in the guide
- `multiblockcraft`
- for crafting an item in a multiblock
- has an item parameter `item`, the item to craft
- has an integer parameter `amount`, the number of times to craft it (not how many items are to be crafted)

#### rewards

Expand All @@ -164,7 +167,7 @@ see [api.md](https://github.com/qwertyuioplkjhgfd/SlimefunAdvancements/blob/main
## TODO:
- ~~criteria system~~
- ~~inventory criteria~~
- craft criteria (soon, see [Slimefun/Slimefun4#3439](https://github.com/Slimefun/Slimefun4/pull/3439))
- ~~craft criteria (soon, see [Slimefun/Slimefun4#3439](https://github.com/Slimefun/Slimefun4/pull/3439))~~
- ~~interact criteria~~
- ~~place criteria~~
- ~~research criteria~~
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@
<dependency>
<groupId>com.github.Slimefun</groupId>
<artifactId>Slimefun4</artifactId>
<version>RC-30</version>
<version>b646e15974</version>
<scope>provided</scope>
<exclusions>
<exclusion>
Expand Down
18 changes: 17 additions & 1 deletion src/main/java/me/char321/sfadvancements/SFAdvancements.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package me.char321.sfadvancements;

import io.github.bakedlibs.dough.config.Config;
import io.github.bakedlibs.dough.updater.BlobBuildUpdater;
import io.github.thebusybiscuit.slimefun4.api.SlimefunAddon;
import io.github.thebusybiscuit.slimefun4.libraries.dough.config.Config;
import me.char321.sfadvancements.api.AdvancementBuilder;
import me.char321.sfadvancements.api.AdvancementGroup;
import me.char321.sfadvancements.api.criteria.CriteriaTypes;
Expand Down Expand Up @@ -45,6 +45,7 @@ public final class SFAdvancements extends JavaPlugin implements SlimefunAddon {
private YamlConfiguration groupConfig;

private boolean testing = false;
private boolean multiBlockCraftEvent = false;

public SFAdvancements() {

Expand All @@ -61,6 +62,8 @@ public void onEnable() {

config = new Config(this);

detectCapabilities();

autoUpdate();

getCommand("sfadvancements").setExecutor(new SFACommand(this));
Expand Down Expand Up @@ -108,6 +111,15 @@ public void onDisable() {
}
}

private void detectCapabilities() {
try {
Class.forName("io.github.thebusybiscuit.slimefun4.api.events.MultiBlockCraftEvent");
multiBlockCraftEvent = true;
} catch (ClassNotFoundException e) {
multiBlockCraftEvent = false;
}
}

private void autoUpdate() {
if (config.getBoolean("auto-update") && !getDescription().getVersion().contains("MODIFIED")) {
info("Checking for updates...");
Expand Down Expand Up @@ -207,6 +219,10 @@ public boolean isTesting() {
return testing;
}

public boolean isMultiBlockCraftEvent() {
return multiBlockCraftEvent;
}

public static Logger logger() {
return instance.getLogger();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public static void loadDefaultCriteria() {
putType("none", Criterion::loadFromConfig);
putType("search", SearchCriterion::loadFromConfig);
putType("break", BlockBreakCriterion::loadFromConfig);
putType("multiblockcraft", MultiBlockCraftCriterion::loadFromConfig);
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package me.char321.sfadvancements.api.criteria;

import me.char321.sfadvancements.SFAdvancements;
import me.char321.sfadvancements.util.ConfigUtils;
import org.bukkit.ChatColor;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.inventory.ItemStack;

public class MultiBlockCraftCriterion extends Criterion {
private final ItemStack item;

public static MultiBlockCraftCriterion loadFromConfig(ConfigurationSection config) {
String id = config.getName();

if (!SFAdvancements.instance().isMultiBlockCraftEvent()) {
SFAdvancements.warn("Multiblock craft events are not available on this version of Slimefun! for criterion " + id);
return null;
}

int amount = config.getInt("amount");
if (amount == 0) {
amount = 1;
}

String name = config.getString("name");
if(name == null) {
name = id;
}

name = ChatColor.translateAlternateColorCodes('&', name);

ItemStack item = ConfigUtils.getItem(config, "item");
if (item == null) {
SFAdvancements.warn("unknown item for multiblock craft criterion " + id);
return null;
}

return new MultiBlockCraftCriterion(id, amount, name, item);
}

/**
*
* @param id
* @param count
* @param name
* @param item the output item of the multiblock craft
*/
public MultiBlockCraftCriterion(String id, int count, String name, ItemStack item) {
super(id, count, name);
this.item = item;
}

public ItemStack getItem() {
return item;
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package me.char321.sfadvancements.core;

import io.github.bakedlibs.dough.items.CustomItemStack;
import io.github.thebusybiscuit.slimefun4.api.items.groups.FlexItemGroup;
import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile;
import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideMode;
import io.github.thebusybiscuit.slimefun4.libraries.dough.items.CustomItemStack;
import me.char321.sfadvancements.SFAdvancements;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package me.char321.sfadvancements.core.command;

import io.github.bakedlibs.dough.items.ItemUtils;
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem;
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
import io.github.thebusybiscuit.slimefun4.libraries.dough.items.ItemUtils;
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
import me.char321.sfadvancements.SFAdvancements;
import org.bukkit.ChatColor;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ public void onBlockBreak(BlockBreakEvent e) {

@Override
public void register(Criterion criterion) {
if (!(getCriterionClass().isInstance(criterion))) {
throw new IllegalArgumentException("criterion must be an " + getCriterionClass().getName());
}

BlockBreakCriterion criterion1 = (BlockBreakCriterion) criterion;
criteria.computeIfAbsent(criterion1.getItem().getType(), k -> new ArrayList<>()).add(criterion1);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,13 @@ public void onConsume(PlayerItemConsumeEvent e) {

@Override
public void register(Criterion criterion) {
if (!(criterion instanceof ConsumeCriterion)) {
throw new IllegalArgumentException("criterion must be an ConsumeCriterion");
if (!(getCriterionClass().isInstance(criterion))) {
throw new IllegalArgumentException("criterion must be an " + getCriterionClass().getName());
}

ConsumeCriterion criterion1 = (ConsumeCriterion) criterion;
Material m = criterion1.getItem().getType();
criteria.computeIfAbsent(m, k -> new HashSet<>());
criteria.get(m).add(criterion1);
criteria.computeIfAbsent(m, k -> new HashSet<>()).add(criterion1);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package me.char321.sfadvancements.core.criteria.completer;

import me.char321.sfadvancements.SFAdvancements;

public class DefaultCompleters {

private DefaultCompleters() {
Expand All @@ -16,5 +18,9 @@ public static void registerDefaultCompleters() {
new MobKillCriterionCompleter().register();
new SearchCriterionCompleter().register();
new BlockBreakCriterionCompleter().register();

if (SFAdvancements.instance().isMultiBlockCraftEvent()) {
new MultiBlockCraftCriterionCompleter().register();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,13 @@ public void onInteract(PlayerRightClickEvent e) {

@Override
public void register(Criterion criterion) {
if (!(criterion instanceof InteractCriterion)) {
throw new IllegalArgumentException("criterion must be an interactcriterion");
if (!(getCriterionClass().isInstance(criterion))) {
throw new IllegalArgumentException("criterion must be an " + getCriterionClass().getName());
}

InteractCriterion criterion1 = (InteractCriterion) criterion;
Material m = criterion1.getItem().getType();
criteria.computeIfAbsent(m, k -> new HashSet<>());
criteria.get(m).add(criterion1);
criteria.computeIfAbsent(m, k -> new HashSet<>()).add(criterion1);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,13 @@ public void onInventory1(Player p) {

@Override
public void register(Criterion criterion) {
if (!(criterion instanceof InventoryCriterion)) {
throw new IllegalArgumentException("criterion must be an interactcriterion");
if (!(getCriterionClass().isInstance(criterion))) {
throw new IllegalArgumentException("criterion must be an " + getCriterionClass().getName());
}

InventoryCriterion criterion1 = (InventoryCriterion) criterion;
Material m = criterion1.getItem().getType();
criteria.computeIfAbsent(m, k -> new HashSet<>());
criteria.get(m).add(criterion1);
criteria.computeIfAbsent(m, k -> new HashSet<>()).add(criterion1);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,10 @@ public void onDeath(EntityDeathEvent e) {

@Override
public void register(Criterion criterion) {
if (!(criterion instanceof MobKillCriterion)) {
throw new IllegalArgumentException("criterion must be a MobKillCriterion");
if (!(getCriterionClass().isInstance(criterion))) {
throw new IllegalArgumentException("criterion must be an " + getCriterionClass().getName());
}

MobKillCriterion criterion1 = (MobKillCriterion) criterion;
criteria.computeIfAbsent(criterion1.getEntity(), k -> new ArrayList<>()).add(criterion1);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package me.char321.sfadvancements.core.criteria.completer;

import io.github.thebusybiscuit.slimefun4.api.events.MultiBlockCraftEvent;
import io.github.thebusybiscuit.slimefun4.api.events.ResearchUnlockEvent;
import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile;
import io.github.thebusybiscuit.slimefun4.api.researches.Research;
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
import me.char321.sfadvancements.SFAdvancements;
import me.char321.sfadvancements.api.criteria.Criterion;
import me.char321.sfadvancements.api.criteria.MultiBlockCraftCriterion;
import me.char321.sfadvancements.api.criteria.ResearchCriterion;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.inventory.ItemStack;

import java.util.*;

public class MultiBlockCraftCriterionCompleter implements CriterionCompleter, Listener {
private final Map<Material, Set<MultiBlockCraftCriterion>> criteria = new EnumMap<>(Material.class);

public MultiBlockCraftCriterionCompleter() {
Bukkit.getPluginManager().registerEvents(this, SFAdvancements.instance());
}

@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onMultiBlockCraft(MultiBlockCraftEvent e) {
performCriteria(e.getPlayer(), e.getOutput());
}

private void performCriteria(Player player, ItemStack output) {
Set<MultiBlockCraftCriterion> allcriteria = criteria.get(output.getType());
if (allcriteria == null) {
return;
}

for (MultiBlockCraftCriterion criterion : allcriteria) {
if (SlimefunUtils.isItemSimilar(output, criterion.getItem(), false, false)) {
criterion.perform(player);
}
}
}

@Override
public void register(Criterion criterion) {
if (!(getCriterionClass().isInstance(criterion))) {
throw new IllegalArgumentException("criterion must be an " + getCriterionClass().getName());
}

MultiBlockCraftCriterion criterion1 = ((MultiBlockCraftCriterion) criterion);
Material material = criterion1.getItem().getType();
criteria.computeIfAbsent(material, k -> new HashSet<>()).add(criterion1);
}

@Override
public Class<? extends Criterion> getCriterionClass() {
return MultiBlockCraftCriterion.class;
}

@Override
public void reload() {
criteria.clear();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,13 @@ public void onMultiBlock(MultiBlockInteractEvent e) {

@Override
public void register(Criterion criterion) {
if (!(criterion instanceof MultiBlockCriterion)) {
throw new IllegalArgumentException("criterion must be an multiblockcriterion");
if (!(getCriterionClass().isInstance(criterion))) {
throw new IllegalArgumentException("criterion must be a " + getCriterionClass().getName());
}

MultiBlockCriterion criterion1 = (MultiBlockCriterion) criterion;
String machine = criterion1.getMachineId();
criteria.computeIfAbsent(machine, k -> new HashSet<>());
criteria.get(machine).add(criterion1);
criteria.computeIfAbsent(machine, k -> new HashSet<>()).add(criterion1);
}

@Override
Expand Down
Loading

0 comments on commit 12e75d6

Please sign in to comment.