mirror of
https://github.com/Xiao-MoMi/Custom-Fishing.git
synced 2026-01-04 15:41:35 +00:00
checkpoint - 30
This commit is contained in:
@@ -25,6 +25,9 @@ import net.kyori.adventure.text.Component;
|
||||
import net.momirealms.customfishing.api.BukkitCustomFishingPlugin;
|
||||
import net.momirealms.customfishing.api.mechanic.action.*;
|
||||
import net.momirealms.customfishing.api.mechanic.context.ContextKeys;
|
||||
import net.momirealms.customfishing.api.mechanic.effect.Effect;
|
||||
import net.momirealms.customfishing.api.mechanic.fishing.CustomFishingHook;
|
||||
import net.momirealms.customfishing.api.mechanic.fishing.FishingGears;
|
||||
import net.momirealms.customfishing.api.mechanic.misc.placeholder.BukkitPlaceholderManager;
|
||||
import net.momirealms.customfishing.api.mechanic.misc.value.MathValue;
|
||||
import net.momirealms.customfishing.api.mechanic.misc.value.TextValue;
|
||||
@@ -783,7 +786,7 @@ public class BukkitActionManager implements ActionManager<Player> {
|
||||
return context -> {
|
||||
if (Math.random() > chance) return;
|
||||
Player owner = context.getHolder();
|
||||
Location location = position ? requireNonNull(context.arg(ContextKeys.HOOK_LOCATION)).clone() : owner.getLocation().clone();
|
||||
Location location = position ? requireNonNull(context.arg(ContextKeys.OTHER_LOCATION)).clone() : owner.getLocation().clone();
|
||||
location.add(x.evaluate(context), y.evaluate(context) - 1, z.evaluate(context));
|
||||
if (opposite) location.setYaw(-owner.getLocation().getYaw());
|
||||
else location.setYaw((float) yaw.evaluate(context));
|
||||
@@ -832,7 +835,7 @@ public class BukkitActionManager implements ActionManager<Player> {
|
||||
return context -> {
|
||||
if (Math.random() > chance) return;
|
||||
Player owner = context.getHolder();
|
||||
Location location = position ? requireNonNull(context.arg(ContextKeys.HOOK_LOCATION)).clone() : owner.getLocation().clone();
|
||||
Location location = position ? requireNonNull(context.arg(ContextKeys.OTHER_LOCATION)).clone() : owner.getLocation().clone();
|
||||
location.add(x.evaluate(context), y.evaluate(context), z.evaluate(context));
|
||||
FakeArmorStand armorStand = SparrowHeart.getInstance().createFakeArmorStand(location);
|
||||
armorStand.invisible(true);
|
||||
@@ -874,16 +877,27 @@ public class BukkitActionManager implements ActionManager<Player> {
|
||||
if (Math.random() > chance) return;
|
||||
String previous = context.arg(ContextKeys.SURROUNDING);
|
||||
context.arg(ContextKeys.SURROUNDING, surrounding);
|
||||
Collection<String> loots = plugin.getLootManager().getWeightedLoots(context).keySet();
|
||||
Collection<String> loots = plugin.getLootManager().getWeightedLoots(Effect.newInstance(), context).keySet();
|
||||
StringJoiner stringJoiner = new StringJoiner(TranslationManager.miniMessageTranslation(MessageConstants.COMMAND_FISH_FINDER_SPLIT_CHAR.build().key()));
|
||||
for (String loot : loots) {
|
||||
stringJoiner.add(loot);
|
||||
plugin.getLootManager().getLoot(loot).ifPresent(lootIns -> {
|
||||
System.out.println("loot: " + loot + " : " + lootIns.showInFinder());
|
||||
if (lootIns.showInFinder()) {
|
||||
if (!lootIns.nick().equals("UNDEFINED")) {
|
||||
stringJoiner.add(lootIns.nick());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
if (previous == null) {
|
||||
context.remove(ContextKeys.SURROUNDING);
|
||||
} else {
|
||||
context.arg(ContextKeys.SURROUNDING, previous);
|
||||
}
|
||||
context.arg(ContextKeys.SURROUNDING, previous);
|
||||
if (loots.isEmpty()) {
|
||||
plugin.getSenderFactory().wrap(context.getHolder()).sendMessage(TranslationManager.render(MessageConstants.COMMAND_FISH_FINDER_NO_LOOT.build()));
|
||||
} else {
|
||||
plugin.getSenderFactory().wrap(context.getHolder()).sendMessage(TranslationManager.render(MessageConstants.COMMAND_FISH_FINDER_POSSIBLE_LOOTS.arguments(Component.text(stringJoiner.toString())).build()));
|
||||
plugin.getSenderFactory().wrap(context.getHolder()).sendMessage(TranslationManager.render(MessageConstants.COMMAND_FISH_FINDER_POSSIBLE_LOOTS.arguments(AdventureHelper.miniMessage(stringJoiner.toString())).build()));
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
@@ -59,6 +59,11 @@ public class BukkitBagManager implements BagManager, Listener {
|
||||
private Action<Player>[] collectLootActions;
|
||||
private Action<Player>[] bagFullActions;
|
||||
private boolean bagStoreLoots;
|
||||
private boolean bagStoreRods;
|
||||
private boolean bagStoreBaits;
|
||||
private boolean bagStoreHooks;
|
||||
private boolean bagStoreUtils;
|
||||
private final HashSet<MechanicType> storedTypes = new HashSet<>();
|
||||
private boolean enable;
|
||||
private String bagTitle;
|
||||
private List<Material> bagWhiteListItems = new ArrayList<>();
|
||||
@@ -78,6 +83,7 @@ public class BukkitBagManager implements BagManager, Listener {
|
||||
@Override
|
||||
public void unload() {
|
||||
HandlerList.unregisterAll(this);
|
||||
storedTypes.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -137,10 +143,20 @@ public class BukkitBagManager implements BagManager, Listener {
|
||||
enable = config.getBoolean("enable", true);
|
||||
bagTitle = config.getString("bag-title", "");
|
||||
bagStoreLoots = config.getBoolean("can-store-loot", false);
|
||||
bagStoreRods = config.getBoolean("can-store-rod", true);
|
||||
bagStoreBaits = config.getBoolean("can-store-bait", true);
|
||||
bagStoreHooks = config.getBoolean("can-store-hook", true);
|
||||
bagStoreUtils = config.getBoolean("can-store-util", true);
|
||||
bagWhiteListItems = config.getStringList("whitelist-items").stream().map(it -> Material.valueOf(it.toUpperCase(Locale.ENGLISH))).toList();
|
||||
collectLootActions = plugin.getActionManager().parseActions(config.getSection("collect-actions"));
|
||||
bagFullActions = plugin.getActionManager().parseActions(config.getSection("full-actions"));
|
||||
collectRequirements = plugin.getRequirementManager().parseRequirements(config.getSection("collect-requirements"), false);
|
||||
|
||||
if (bagStoreLoots) storedTypes.add(MechanicType.LOOT);
|
||||
if (bagStoreRods) storedTypes.add(MechanicType.ROD);
|
||||
if (bagStoreBaits) storedTypes.add(MechanicType.BAIT);
|
||||
if (bagStoreHooks) storedTypes.add(MechanicType.HOOK);
|
||||
if (bagStoreUtils) storedTypes.add(MechanicType.UTIL);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -205,15 +221,16 @@ public class BukkitBagManager implements BagManager, Listener {
|
||||
if (movedItem == null || movedItem.getType() == Material.AIR || bagWhiteListItems.contains(movedItem.getType()))
|
||||
return;
|
||||
String id = plugin.getItemManager().getItemID(movedItem);
|
||||
MechanicType type = MechanicType.getTypeByID(id);
|
||||
List<MechanicType> type = MechanicType.getTypeByID(id);
|
||||
if (type == null) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
if (type == MechanicType.LOOT && bagStoreLoots)
|
||||
return;
|
||||
if (type == MechanicType.BAIT || type == MechanicType.ROD || type == MechanicType.UTIL || type == MechanicType.HOOK)
|
||||
return;
|
||||
for (MechanicType mechanicType : type) {
|
||||
if (storedTypes.contains(mechanicType)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
|
||||
@@ -227,7 +227,7 @@ public class BukkitBlockManager implements BlockManager, Listener {
|
||||
} else {
|
||||
blockData = blockProviders.get("vanilla").blockData(context, blockID, config.dataModifier());
|
||||
}
|
||||
Location hookLocation = requireNonNull(context.arg(ContextKeys.HOOK_LOCATION));
|
||||
Location hookLocation = requireNonNull(context.arg(ContextKeys.OTHER_LOCATION));
|
||||
Location playerLocation = requireNonNull(context.getHolder()).getLocation();
|
||||
FallingBlock fallingBlock = hookLocation.getWorld().spawn(hookLocation, FallingBlock.class, (fb -> fb.setBlockData(blockData)));
|
||||
fallingBlock.getPersistentDataContainer().set(
|
||||
|
||||
@@ -39,6 +39,7 @@ public class BukkitCommandManager extends AbstractCommandManager<CommandSender>
|
||||
new SellFishCommand(this),
|
||||
new GetItemCommand(this),
|
||||
new GiveItemCommand(this),
|
||||
new ImportItemCommand(this),
|
||||
new EndCompetitionCommand(this),
|
||||
new StopCompetitionCommand(this),
|
||||
new StartCompetitionCommand(this),
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (C) <2022> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customfishing.bukkit.command.feature;
|
||||
|
||||
import dev.dejvokep.boostedyaml.YamlDocument;
|
||||
import dev.dejvokep.boostedyaml.block.implementation.Section;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.momirealms.customfishing.api.BukkitCustomFishingPlugin;
|
||||
import net.momirealms.customfishing.bukkit.command.BukkitCommandFeature;
|
||||
import net.momirealms.customfishing.bukkit.util.ItemStackUtils;
|
||||
import net.momirealms.customfishing.common.command.CustomFishingCommandManager;
|
||||
import net.momirealms.customfishing.common.locale.MessageConstants;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.incendo.cloud.Command;
|
||||
import org.incendo.cloud.CommandManager;
|
||||
import org.incendo.cloud.parser.standard.StringParser;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
@SuppressWarnings("DuplicatedCode")
|
||||
public class ImportItemCommand extends BukkitCommandFeature<CommandSender> {
|
||||
|
||||
public ImportItemCommand(CustomFishingCommandManager<CommandSender> commandManager) {
|
||||
super(commandManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Command.Builder<? extends CommandSender> assembleCommand(CommandManager<CommandSender> manager, Command.Builder<CommandSender> builder) {
|
||||
return builder
|
||||
.senderType(Player.class)
|
||||
.required("id", StringParser.stringParser())
|
||||
.flag(manager.flagBuilder("silent").withAliases("s").build())
|
||||
.handler(context -> {
|
||||
Player player = context.sender();
|
||||
ItemStack itemStack = player.getInventory().getItemInMainHand();
|
||||
String id = context.get("id");
|
||||
if (itemStack.getType() == Material.AIR) {
|
||||
handleFeedback(context, MessageConstants.COMMAND_ITEM_IMPORT_FAILURE_NO_ITEM);
|
||||
return;
|
||||
}
|
||||
File saved = new File(BukkitCustomFishingPlugin.getInstance().getDataFolder(), "imported_items.yml");
|
||||
if (!saved.exists()) {
|
||||
try {
|
||||
saved.createNewFile();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
YamlDocument document = BukkitCustomFishingPlugin.getInstance().getConfigManager().loadData(saved);
|
||||
Map<String, Object> map = ItemStackUtils.itemStackToMap(itemStack);
|
||||
document.set(id, map);
|
||||
try {
|
||||
document.save(saved);
|
||||
handleFeedback(context, MessageConstants.COMMAND_ITEM_IMPORT_SUCCESS, Component.text(id));
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFeatureID() {
|
||||
return "import_item";
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
package net.momirealms.customfishing.bukkit.config;
|
||||
|
||||
import com.saicone.rtag.RtagItem;
|
||||
import dev.dejvokep.boostedyaml.YamlDocument;
|
||||
import dev.dejvokep.boostedyaml.block.implementation.Section;
|
||||
import dev.dejvokep.boostedyaml.dvs.versioning.BasicVersioning;
|
||||
@@ -35,6 +36,7 @@ import net.momirealms.customfishing.api.mechanic.effect.Effect;
|
||||
import net.momirealms.customfishing.api.mechanic.effect.EffectProperties;
|
||||
import net.momirealms.customfishing.api.mechanic.event.EventManager;
|
||||
import net.momirealms.customfishing.api.mechanic.item.MechanicType;
|
||||
import net.momirealms.customfishing.api.mechanic.item.tag.TagEditor;
|
||||
import net.momirealms.customfishing.api.mechanic.loot.Loot;
|
||||
import net.momirealms.customfishing.api.mechanic.misc.value.MathValue;
|
||||
import net.momirealms.customfishing.api.mechanic.misc.value.TextValue;
|
||||
@@ -52,8 +54,10 @@ import net.momirealms.customfishing.api.mechanic.totem.block.type.TypeCondition;
|
||||
import net.momirealms.customfishing.api.util.OffsetUtils;
|
||||
import net.momirealms.customfishing.bukkit.totem.particle.DustParticleSetting;
|
||||
import net.momirealms.customfishing.bukkit.totem.particle.ParticleSetting;
|
||||
import net.momirealms.customfishing.bukkit.util.ItemStackUtils;
|
||||
import net.momirealms.customfishing.common.dependency.DependencyProperties;
|
||||
import net.momirealms.customfishing.common.helper.AdventureHelper;
|
||||
import net.momirealms.customfishing.common.item.AbstractItem;
|
||||
import net.momirealms.customfishing.common.item.Item;
|
||||
import net.momirealms.customfishing.common.util.*;
|
||||
import org.bukkit.*;
|
||||
@@ -65,7 +69,9 @@ import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.*;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.BiFunction;
|
||||
@@ -94,9 +100,9 @@ public class BukkitConfigManager extends ConfigManager {
|
||||
@Override
|
||||
public void load() {
|
||||
String configVersion = DependencyProperties.getDependencyVersion("config");
|
||||
try {
|
||||
try (InputStream inputStream = new FileInputStream(resolveConfig("config.yml").toFile())) {
|
||||
MAIN_CONFIG = YamlDocument.create(
|
||||
resolveConfig("config.yml").toFile(),
|
||||
inputStream,
|
||||
plugin.getResourceStream("config.yml"),
|
||||
GeneralSettings.builder()
|
||||
.setRouteSeparator('.')
|
||||
@@ -287,26 +293,6 @@ public class BukkitConfigManager extends ConfigManager {
|
||||
}
|
||||
|
||||
private void registerBuiltInItemProperties() {
|
||||
Function<Object, BiConsumer<Item<ItemStack>, Context<Player>>> f2 = arg -> {
|
||||
Section section = (Section) arg;
|
||||
boolean stored = Objects.equals(section.getNameAsString(), "stored-random-enchantments");
|
||||
List<Tuple<Double, String, Short>> enchantments = getPossibleEnchantments(section);
|
||||
return (item, context) -> {
|
||||
HashSet<String> ids = new HashSet<>();
|
||||
for (Tuple<Double, String, Short> pair : enchantments) {
|
||||
if (Math.random() < pair.left() && !ids.contains(pair.mid())) {
|
||||
if (stored) {
|
||||
item.addStoredEnchantment(Key.fromString(pair.mid()), pair.right());
|
||||
} else {
|
||||
item.addEnchantment(Key.fromString(pair.mid()), pair.right());
|
||||
}
|
||||
ids.add(pair.mid());
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
this.registerItemParser(f2, 4850, "random-stored-enchantments");
|
||||
this.registerItemParser(f2, 4750, "random-enchantments");
|
||||
Function<Object, BiConsumer<Item<ItemStack>, Context<Player>>> f1 = arg -> {
|
||||
Section section = (Section) arg;
|
||||
boolean stored = Objects.equals(section.getNameAsString(), "stored-enchantment-pool");
|
||||
@@ -365,6 +351,26 @@ public class BukkitConfigManager extends ConfigManager {
|
||||
};
|
||||
this.registerItemParser(f1, 4800, "stored-enchantment-pool");
|
||||
this.registerItemParser(f1, 4700, "enchantment-pool");
|
||||
Function<Object, BiConsumer<Item<ItemStack>, Context<Player>>> f2 = arg -> {
|
||||
Section section = (Section) arg;
|
||||
boolean stored = Objects.equals(section.getNameAsString(), "stored-random-enchantments");
|
||||
List<Tuple<Double, String, Short>> enchantments = getPossibleEnchantments(section);
|
||||
return (item, context) -> {
|
||||
HashSet<String> ids = new HashSet<>();
|
||||
for (Tuple<Double, String, Short> pair : enchantments) {
|
||||
if (Math.random() < pair.left() && !ids.contains(pair.mid())) {
|
||||
if (stored) {
|
||||
item.addStoredEnchantment(Key.fromString(pair.mid()), pair.right());
|
||||
} else {
|
||||
item.addEnchantment(Key.fromString(pair.mid()), pair.right());
|
||||
}
|
||||
ids.add(pair.mid());
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
this.registerItemParser(f2, 4850, "random-stored-enchantments");
|
||||
this.registerItemParser(f2, 4750, "random-enchantments");
|
||||
this.registerItemParser(arg -> {
|
||||
Section section = (Section) arg;
|
||||
Map<Key, Short> map = getEnchantments(section);
|
||||
@@ -432,6 +438,16 @@ public class BukkitConfigManager extends ConfigManager {
|
||||
context.arg(ContextKeys.PRICE_FORMATTED, String.format("%.2f", price));
|
||||
};
|
||||
}, 1_500, "price");
|
||||
this.registerItemParser(arg -> {
|
||||
Section section = (Section) arg;
|
||||
ArrayList<TagEditor> editors = new ArrayList<>();
|
||||
ItemStackUtils.sectionToEditor(section, editors);
|
||||
return (item, context) -> {
|
||||
for (TagEditor editor : editors) {
|
||||
editor.apply(((AbstractItem<RtagItem, ItemStack>) item).getRTagItem(), context);
|
||||
}
|
||||
};
|
||||
}, 1_750, "nbt");
|
||||
}
|
||||
|
||||
private void registerBuiltInEffectModifierParser() {
|
||||
|
||||
@@ -104,7 +104,7 @@ public class BukkitEntityManager implements EntityManager {
|
||||
public Entity summonEntityLoot(Context<Player> context) {
|
||||
String id = context.arg(ContextKeys.ID);
|
||||
EntityConfig config = requireNonNull(entities.get(id), "Entity " + id + " not found");
|
||||
Location hookLocation = requireNonNull(context.arg(ContextKeys.HOOK_LOCATION));
|
||||
Location hookLocation = requireNonNull(context.arg(ContextKeys.OTHER_LOCATION));
|
||||
Location playerLocation = requireNonNull(context.getHolder().getLocation());
|
||||
String entityID = config.entityID();
|
||||
Entity entity;
|
||||
|
||||
@@ -20,11 +20,14 @@ package net.momirealms.customfishing.bukkit.event;
|
||||
import net.momirealms.customfishing.api.BukkitCustomFishingPlugin;
|
||||
import net.momirealms.customfishing.api.mechanic.action.ActionTrigger;
|
||||
import net.momirealms.customfishing.api.mechanic.context.Context;
|
||||
import net.momirealms.customfishing.api.mechanic.context.ContextKeys;
|
||||
import net.momirealms.customfishing.api.mechanic.event.EventCarrier;
|
||||
import net.momirealms.customfishing.api.mechanic.event.EventManager;
|
||||
import net.momirealms.customfishing.api.mechanic.item.MechanicType;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
@@ -78,14 +81,15 @@ public class BukkitEventManager implements EventManager, Listener {
|
||||
if (itemStack.getType() == Material.AIR || itemStack.getAmount() == 0)
|
||||
return;
|
||||
String id = this.plugin.getItemManager().getItemID(itemStack);
|
||||
Optional.ofNullable(this.carriers.get(id)).ifPresent(carrier -> {
|
||||
carrier.trigger(Context.player(event.getPlayer()), ActionTrigger.INTERACT);
|
||||
});
|
||||
Context<Player> context = Context.player(event.getPlayer());
|
||||
Block clicked = event.getClickedBlock();
|
||||
context.arg(ContextKeys.OTHER_LOCATION, clicked == null ? event.getPlayer().getLocation() : clicked.getLocation());
|
||||
trigger(context, id, MechanicType.UTIL, ActionTrigger.INTERACT);
|
||||
}
|
||||
|
||||
@EventHandler (ignoreCancelled = true)
|
||||
public void onConsumeItem(PlayerItemConsumeEvent event) {
|
||||
Optional.ofNullable(carriers.get(plugin.getItemManager().getItemID(event.getItem())))
|
||||
.ifPresent(carrier -> carrier.trigger(Context.player(event.getPlayer()), ActionTrigger.CONSUME));
|
||||
Context<Player> context = Context.player(event.getPlayer());
|
||||
trigger(context, plugin.getItemManager().getItemID(event.getItem()), MechanicType.LOOT, ActionTrigger.CONSUME);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,18 +159,6 @@ public class BukkitItemManager implements ItemManager, Listener {
|
||||
return (String) factory.wrap(itemStack).getTag("CustomFishing", "id").orElse(null);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public MechanicType getItemType(@NotNull ItemStack itemStack) {
|
||||
return MechanicType.getTypeByID(getCustomFishingItemID(itemStack));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public MechanicType getItemType(@NotNull String id) {
|
||||
return MechanicType.getTypeByID(id);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public org.bukkit.entity.Item dropItemLoot(@NotNull Context<Player> context, ItemStack rod, FishHook hook) {
|
||||
@@ -188,7 +176,7 @@ public class BukkitItemManager implements ItemManager, Listener {
|
||||
|
||||
Player player = context.getHolder();
|
||||
Location playerLocation = player.getLocation();
|
||||
Location hookLocation = requireNonNull(context.arg(ContextKeys.HOOK_LOCATION));
|
||||
Location hookLocation = requireNonNull(context.arg(ContextKeys.OTHER_LOCATION));
|
||||
|
||||
double d0 = playerLocation.getX() - hookLocation.getX();
|
||||
double d1 = playerLocation.getY() - hookLocation.getY();
|
||||
|
||||
@@ -129,8 +129,21 @@ public class BukkitLootManager implements LootManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public HashMap<String, Double> getWeightedLoots(Context<Player> context) {
|
||||
return null;
|
||||
public HashMap<String, Double> getWeightedLoots(Effect effect, Context<Player> context) {
|
||||
HashMap<String, Double> lootWeightMap = new HashMap<>();
|
||||
for (ConditionalElement<List<Pair<String, BiFunction<Context<Player>, Double, Double>>>, Player> conditionalElement : lootConditions.values()) {
|
||||
modifyWeightMap(lootWeightMap, context, conditionalElement);
|
||||
}
|
||||
for (Pair<String, BiFunction<Context<Player>, Double, Double>> pair : effect.weightOperations()) {
|
||||
double previous = lootWeightMap.getOrDefault(pair.left(), 0d);
|
||||
if (previous > 0)
|
||||
lootWeightMap.put(pair.left(), pair.right().apply(context, previous));
|
||||
}
|
||||
for (Pair<String, BiFunction<Context<Player>, Double, Double>> pair : effect.weightOperationsIgnored()) {
|
||||
double previous = lootWeightMap.getOrDefault(pair.left(), 0d);
|
||||
lootWeightMap.put(pair.left(), pair.right().apply(context, previous));
|
||||
}
|
||||
return lootWeightMap;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -665,7 +665,7 @@ public class BukkitRequirementManager implements RequirementManager<Player> {
|
||||
registerRequirement("ice-fishing", (args, actions, runActions) -> {
|
||||
boolean iceFishing = (boolean) args;
|
||||
return context -> {
|
||||
Location location = requireNonNull(context.arg(ContextKeys.HOOK_LOCATION));
|
||||
Location location = requireNonNull(context.arg(ContextKeys.OTHER_LOCATION));
|
||||
int water = 0, ice = 0;
|
||||
for (int i = -2; i <= 2; i++)
|
||||
for (int j = -1; j <= 2; j++)
|
||||
@@ -727,7 +727,7 @@ public class BukkitRequirementManager implements RequirementManager<Player> {
|
||||
registerRequirement("biome", (args, actions, runActions) -> {
|
||||
HashSet<String> biomes = new HashSet<>(ListUtils.toList(args));
|
||||
return context -> {
|
||||
Location location = requireNonNull(Optional.ofNullable(context.arg(ContextKeys.HOOK_LOCATION)).orElse(context.arg(ContextKeys.LOCATION)));
|
||||
Location location = requireNonNull(Optional.ofNullable(context.arg(ContextKeys.OTHER_LOCATION)).orElse(context.arg(ContextKeys.LOCATION)));
|
||||
String currentBiome = SparrowHeart.getInstance().getBiomeResourceLocation(location);
|
||||
if (biomes.contains(currentBiome))
|
||||
return true;
|
||||
@@ -738,7 +738,7 @@ public class BukkitRequirementManager implements RequirementManager<Player> {
|
||||
registerRequirement("!biome", (args, actions, runActions) -> {
|
||||
HashSet<String> biomes = new HashSet<>(ListUtils.toList(args));
|
||||
return context -> {
|
||||
Location location = requireNonNull(Optional.ofNullable(context.arg(ContextKeys.HOOK_LOCATION)).orElse(context.arg(ContextKeys.LOCATION)));
|
||||
Location location = requireNonNull(Optional.ofNullable(context.arg(ContextKeys.OTHER_LOCATION)).orElse(context.arg(ContextKeys.LOCATION)));
|
||||
String currentBiome = SparrowHeart.getInstance().getBiomeResourceLocation(location);
|
||||
if (!biomes.contains(currentBiome))
|
||||
return true;
|
||||
|
||||
@@ -17,10 +17,17 @@
|
||||
|
||||
package net.momirealms.customfishing.bukkit.util;
|
||||
|
||||
import com.saicone.rtag.RtagMirror;
|
||||
import com.saicone.rtag.item.ItemObject;
|
||||
import com.saicone.rtag.tag.TagCompound;
|
||||
import com.saicone.rtag.item.ItemTagStream;
|
||||
import dev.dejvokep.boostedyaml.block.implementation.Section;
|
||||
import net.momirealms.customfishing.api.mechanic.item.tag.TagEditor;
|
||||
import net.momirealms.customfishing.api.mechanic.item.tag.TagListType;
|
||||
import net.momirealms.customfishing.api.mechanic.item.tag.TagValueType;
|
||||
import net.momirealms.customfishing.api.mechanic.misc.value.MathValue;
|
||||
import net.momirealms.customfishing.api.mechanic.misc.value.TextValue;
|
||||
import net.momirealms.customfishing.common.util.ArrayUtils;
|
||||
import net.momirealms.customfishing.common.util.Pair;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.util.io.BukkitObjectInputStream;
|
||||
import org.bukkit.util.io.BukkitObjectOutputStream;
|
||||
@@ -29,7 +36,7 @@ import org.yaml.snakeyaml.external.biz.base64Coder.Base64Coder;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
public class ItemStackUtils {
|
||||
|
||||
@@ -69,24 +76,208 @@ public class ItemStackUtils {
|
||||
}
|
||||
}
|
||||
|
||||
public static Map<String, Object> toReadableMap(ItemStack item) {
|
||||
return toMap(item);
|
||||
public static Map<String, Object> itemStackToMap(ItemStack itemStack) {
|
||||
Map<String, Object> map = ItemTagStream.INSTANCE.toMap(itemStack);
|
||||
map.remove("rtagDataVersion");
|
||||
map.remove("count");
|
||||
map.remove("id");
|
||||
map.put("material", itemStack.getType().name().toLowerCase(Locale.ENGLISH));
|
||||
map.put("amount", itemStack.getAmount());
|
||||
Object tag = map.remove("tags");
|
||||
if (tag != null) {
|
||||
map.put("nbt", tag);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
private static Map<String, Object> toMap(ItemStack object) {
|
||||
return TagCompound.getValue(RtagMirror.INSTANCE, toCompound(object));
|
||||
}
|
||||
|
||||
private static Object toCompound(ItemStack object) {
|
||||
if (object == null) {
|
||||
return null;
|
||||
} else {
|
||||
Object compound = extract(object);
|
||||
return TagCompound.isTagCompound(compound) ? compound : null;
|
||||
// TODO Improve the map parser and refactor this method to make it more readable
|
||||
public static void sectionToEditor(Section section, List<TagEditor> tagEditors, String... route) {
|
||||
for (Map.Entry<String, Object> entry : section.getStringRouteMappedValues(false).entrySet()) {
|
||||
Object value = entry.getValue();
|
||||
String key = entry.getKey();
|
||||
String[] currentRoute = ArrayUtils.appendElementToArray(route, key);
|
||||
if (value instanceof Section inner) {
|
||||
sectionToEditor(inner, tagEditors, currentRoute);
|
||||
} else if (value instanceof List<?> list) {
|
||||
TagListType type = getListType(list);
|
||||
if (type == TagListType.TAG) {
|
||||
// List<TagMap> maps = new ArrayList<>();
|
||||
// for (Object o : list) {
|
||||
// Map<String, Object> map = (Map<String, Object>) o;
|
||||
//
|
||||
// }
|
||||
tagEditors.add(((item, context) -> {
|
||||
// List<Map<String, Object>> parsed = maps.stream().map(render -> render.apply(context)).toList();
|
||||
item.set(list, (Object[]) currentRoute);
|
||||
}));
|
||||
} else {
|
||||
Object first = list.get(0);
|
||||
if (first instanceof String str) {
|
||||
Pair<TagValueType, String> pair = toTypeAndData(str);
|
||||
switch (pair.left()) {
|
||||
case INT -> {
|
||||
List<MathValue<Player>> values = new ArrayList<>();
|
||||
for (Object o : list) {
|
||||
values.add(MathValue.auto(toTypeAndData((String) o).right()));
|
||||
}
|
||||
tagEditors.add(((item, context) -> {
|
||||
List<Integer> integers = values.stream().map(unparsed -> (int) unparsed.evaluate(context)).toList();
|
||||
item.set(integers, (Object[]) currentRoute);
|
||||
}));
|
||||
}
|
||||
case BYTE -> {
|
||||
List<MathValue<Player>> values = new ArrayList<>();
|
||||
for (Object o : list) {
|
||||
values.add(MathValue.auto(toTypeAndData((String) o).right()));
|
||||
}
|
||||
tagEditors.add(((item, context) -> {
|
||||
List<Byte> bytes = values.stream().map(unparsed -> (byte) unparsed.evaluate(context)).toList();
|
||||
item.set(bytes, (Object[]) currentRoute);
|
||||
}));
|
||||
}
|
||||
case LONG -> {
|
||||
List<MathValue<Player>> values = new ArrayList<>();
|
||||
for (Object o : list) {
|
||||
values.add(MathValue.auto(toTypeAndData((String) o).right()));
|
||||
}
|
||||
tagEditors.add(((item, context) -> {
|
||||
List<Long> longs = values.stream().map(unparsed -> (long) unparsed.evaluate(context)).toList();
|
||||
item.set(longs, (Object[]) currentRoute);
|
||||
}));
|
||||
}
|
||||
case FLOAT -> {
|
||||
List<MathValue<Player>> values = new ArrayList<>();
|
||||
for (Object o : list) {
|
||||
values.add(MathValue.auto(toTypeAndData((String) o).right()));
|
||||
}
|
||||
tagEditors.add(((item, context) -> {
|
||||
List<Float> floats = values.stream().map(unparsed -> (float) unparsed.evaluate(context)).toList();
|
||||
item.set(floats, (Object[]) currentRoute);
|
||||
}));
|
||||
}
|
||||
case DOUBLE -> {
|
||||
List<MathValue<Player>> values = new ArrayList<>();
|
||||
for (Object o : list) {
|
||||
values.add(MathValue.auto(toTypeAndData((String) o).right()));
|
||||
}
|
||||
tagEditors.add(((item, context) -> {
|
||||
List<Double> doubles = values.stream().map(unparsed -> (double) unparsed.evaluate(context)).toList();
|
||||
item.set(doubles, (Object[]) currentRoute);
|
||||
}));
|
||||
}
|
||||
case STRING -> {
|
||||
List<TextValue<Player>> values = new ArrayList<>();
|
||||
for (Object o : list) {
|
||||
values.add(TextValue.auto(toTypeAndData((String) o).right()));
|
||||
}
|
||||
tagEditors.add(((item, context) -> {
|
||||
List<String> texts = values.stream().map(unparsed -> unparsed.render(context)).toList();
|
||||
item.set(texts, (Object[]) currentRoute);
|
||||
}));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
tagEditors.add(((item, context) -> {
|
||||
item.set(list, (Object[]) currentRoute);
|
||||
}));
|
||||
}
|
||||
}
|
||||
} else if (value instanceof String str) {
|
||||
Pair<TagValueType, String> pair = toTypeAndData(str);
|
||||
switch (pair.left()) {
|
||||
case INT -> {
|
||||
MathValue<Player> mathValue = MathValue.auto(pair.right());
|
||||
tagEditors.add(((item, context) -> {
|
||||
item.set((int) mathValue.evaluate(context), (Object[]) currentRoute);
|
||||
}));
|
||||
}
|
||||
case BYTE -> {
|
||||
MathValue<Player> mathValue = MathValue.auto(pair.right());
|
||||
tagEditors.add(((item, context) -> {
|
||||
item.set((byte) mathValue.evaluate(context), (Object[]) currentRoute);
|
||||
}));
|
||||
}
|
||||
case LONG -> {
|
||||
MathValue<Player> mathValue = MathValue.auto(pair.right());
|
||||
tagEditors.add(((item, context) -> {
|
||||
item.set((long) mathValue.evaluate(context), (Object[]) currentRoute);
|
||||
}));
|
||||
}
|
||||
case SHORT -> {
|
||||
MathValue<Player> mathValue = MathValue.auto(pair.right());
|
||||
tagEditors.add(((item, context) -> {
|
||||
item.set((short) mathValue.evaluate(context), (Object[]) currentRoute);
|
||||
}));
|
||||
}
|
||||
case DOUBLE -> {
|
||||
MathValue<Player> mathValue = MathValue.auto(pair.right());
|
||||
tagEditors.add(((item, context) -> {
|
||||
item.set((double) mathValue.evaluate(context), (Object[]) currentRoute);
|
||||
}));
|
||||
}
|
||||
case FLOAT -> {
|
||||
MathValue<Player> mathValue = MathValue.auto(pair.right());
|
||||
tagEditors.add(((item, context) -> {
|
||||
item.set((float) mathValue.evaluate(context), (Object[]) currentRoute);
|
||||
}));
|
||||
}
|
||||
case STRING -> {
|
||||
TextValue<Player> textValue = TextValue.auto(pair.right());
|
||||
tagEditors.add(((item, context) -> {
|
||||
item.set(textValue.render(context), (Object[]) currentRoute);
|
||||
}));
|
||||
}
|
||||
case INTARRAY -> {
|
||||
String[] split = splitValue(str);
|
||||
int[] array = Arrays.stream(split).mapToInt(Integer::parseInt).toArray();
|
||||
tagEditors.add(((item, context) -> {
|
||||
item.set(array, (Object[]) currentRoute);
|
||||
}));
|
||||
}
|
||||
case BYTEARRAY -> {
|
||||
String[] split = splitValue(str);
|
||||
byte[] bytes = new byte[split.length];
|
||||
for (int i = 0; i < split.length; i++){
|
||||
bytes[i] = Byte.parseByte(split[i]);
|
||||
}
|
||||
tagEditors.add(((item, context) -> {
|
||||
item.set(bytes, (Object[]) currentRoute);
|
||||
}));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
tagEditors.add(((item, context) -> {
|
||||
item.set(value, (Object[]) currentRoute);
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Object extract(ItemStack object) {
|
||||
return ItemObject.save(ItemObject.asNMSCopy(object));
|
||||
private static TagListType getListType(List<?> list) {
|
||||
Object o = list.get(0);
|
||||
if (o instanceof Map<?, ?> map) {
|
||||
return TagListType.TAG;
|
||||
} else {
|
||||
return TagListType.VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
public static Pair<TagValueType, String> toTypeAndData(String str) {
|
||||
String[] parts = str.split("\\s+", 2);
|
||||
if (parts.length == 1) {
|
||||
return Pair.of(TagValueType.STRING, parts[0]);
|
||||
}
|
||||
if (parts.length != 2) {
|
||||
throw new IllegalArgumentException("Invalid value format: " + str);
|
||||
}
|
||||
TagValueType type = TagValueType.valueOf(parts[0].substring(1, parts[0].length() - 1).toUpperCase(Locale.ENGLISH));
|
||||
String data = parts[1];
|
||||
return Pair.of(type, data);
|
||||
}
|
||||
|
||||
private static String[] splitValue(String value) {
|
||||
return value.substring(value.indexOf('[') + 1, value.lastIndexOf(']'))
|
||||
.replaceAll("\\s", "")
|
||||
.split(",");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,8 +159,12 @@ mechanics:
|
||||
# Other whitelist-items
|
||||
whitelist-items:
|
||||
- fishing_rod
|
||||
# Can fishing bag store fishing loots?
|
||||
# Decide the items that can be stored in bag
|
||||
can-store-loot: false
|
||||
can-store-rod: true
|
||||
can-store-bait: true
|
||||
can-store-hook: true
|
||||
can-store-util: true
|
||||
# Requirements for automatically collecting
|
||||
collect-requirements:
|
||||
permission: fishingbag.collectloot
|
||||
|
||||
@@ -42,6 +42,8 @@ command.reload.success: "<white>Reloaded. Took <green><arg:0></green> ms.</white
|
||||
command.item.failure.not_exist: "<red>Item [<arg:0>] not exists.</red>"
|
||||
command.item.give.success: "<white>Successfully given <arg:0> <arg:1>x <arg:2>.</white>"
|
||||
command.item.get.success: "<white>Successfully got <arg:0>x <arg:1>.</white>"
|
||||
command.item.import.failure.no_item: "<red>You can't import air</red>"
|
||||
command.item.import.success: "<white>Item [<arg:0>] has been saved to /plugins/CustomFishing/imported_items.yml</white>"
|
||||
command.fish_finder.possible_loots: "<white>Possible loots here: <arg:0></white>"
|
||||
command.fish_finder.no_loot: "<white>No loot found here</white>"
|
||||
command.fish_finder.split_char: ", "
|
||||
|
||||
Reference in New Issue
Block a user