9
0
mirror of https://github.com/Xiao-MoMi/Custom-Fishing.git synced 2025-12-28 11:29:15 +00:00

checkpoint - 18

This commit is contained in:
XiaoMoMi
2024-07-01 01:34:19 +08:00
parent 53a6dc20bb
commit 4eb4ff901a
48 changed files with 775 additions and 154 deletions

View File

@@ -4,6 +4,10 @@ plugins {
id("io.github.goooler.shadow") version "8.1.7"
}
repositories {
maven("https://repo.xenondevs.xyz/releases") // invui
}
dependencies {
// platform
compileOnly("dev.folia:folia-api:${rootProject.properties["paper_version"]}-R0.1-SNAPSHOT")

Binary file not shown.

View File

@@ -14,6 +14,7 @@ import net.momirealms.customfishing.bukkit.config.BukkitConfigManager;
import net.momirealms.customfishing.bukkit.effect.BukkitEffectManager;
import net.momirealms.customfishing.bukkit.entity.BukkitEntityManager;
import net.momirealms.customfishing.bukkit.event.BukkitEventManager;
import net.momirealms.customfishing.bukkit.fishing.BukkitFishingManager;
import net.momirealms.customfishing.bukkit.gui.ChatCatcherManager;
import net.momirealms.customfishing.bukkit.hook.BukkitHookManager;
import net.momirealms.customfishing.bukkit.integration.BukkitIntegrationManager;
@@ -59,7 +60,6 @@ public class BukkitCustomFishingPluginImpl extends BukkitCustomFishingPlugin {
this.classPathAppender = new ReflectionClassPathAppender(this);
this.logger = new JavaPluginLogger(getBoostrap().getLogger());
this.dependencyManager = new DependencyManagerImpl(this);
this.debugger = (s) -> {};
}
@Override
@@ -104,6 +104,7 @@ public class BukkitCustomFishingPluginImpl extends BukkitCustomFishingPlugin {
this.statisticsManager = new BukkitStatisticsManager(this);
this.effectManager = new BukkitEffectManager(this);
this.hookManager = new BukkitHookManager(this);
this.fishingManager = new BukkitFishingManager(this);
this.bagManager = new BukkitBagManager(this);
this.totemManager = new BukkitTotemManager(this);
this.translationManager = new TranslationManager(this);
@@ -138,7 +139,7 @@ public class BukkitCustomFishingPluginImpl extends BukkitCustomFishingPlugin {
this.placeholderManager.reload();
this.configManager.reload();
// after ConfigManager
this.debugger = ConfigManager.debug() ? logger::info : (s) -> {};
this.debugger = ConfigManager.debug() ? (s) -> logger.info("[DEBUG] " + s) : (s) -> {};
this.actionManager.reload();
this.requirementManager.reload();
@@ -149,6 +150,7 @@ public class BukkitCustomFishingPluginImpl extends BukkitCustomFishingPlugin {
this.statisticsManager.reload();
this.bagManager.reload();
this.storageManager.reload();
this.fishingManager.reload();
this.itemManager.load();
this.eventManager.load();

View File

@@ -21,6 +21,8 @@ import net.momirealms.customfishing.common.util.ClassUtils;
import net.momirealms.customfishing.common.util.ListUtils;
import net.momirealms.customfishing.common.util.Pair;
import net.momirealms.customfishing.common.util.RandomUtils;
import net.momirealms.sparrow.heart.SparrowHeart;
import net.momirealms.sparrow.heart.feature.armorstand.FakeArmorStand;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
@@ -51,7 +53,6 @@ public class BukkitActionManager implements ActionManager<Player> {
public BukkitActionManager(BukkitCustomFishingPlugin plugin) {
this.plugin = plugin;
this.registerBuiltInActions();
}
@Override
@@ -89,6 +90,7 @@ public class BukkitActionManager implements ActionManager<Player> {
@Override
public Action<Player> parseAction(Section section) {
if (section == null) return EmptyAction.INSTANCE;
ActionFactory<Player> factory = getActionFactory(section.getString("type"));
if (factory == null) {
plugin.getPluginLogger().warn("Action type: " + section.getString("type") + " doesn't exist.");
@@ -100,15 +102,16 @@ public class BukkitActionManager implements ActionManager<Player> {
@NotNull
@Override
@SuppressWarnings("unchecked")
public Action<Player>[] parseActions(@NotNull Section section) {
public Action<Player>[] parseActions(Section section) {
ArrayList<Action<Player>> actionList = new ArrayList<>();
for (Map.Entry<String, Object> entry : section.getStringRouteMappedValues(false).entrySet()) {
if (entry.getValue() instanceof Section innerSection) {
Action<Player> action = parseAction(innerSection);
if (action != null)
actionList.add(action);
if (section != null)
for (Map.Entry<String, Object> entry : section.getStringRouteMappedValues(false).entrySet()) {
if (entry.getValue() instanceof Section innerSection) {
Action<Player> action = parseAction(innerSection);
if (action != null)
actionList.add(action);
}
}
}
return actionList.toArray(new Action[0]);
}
@@ -136,6 +139,7 @@ public class BukkitActionManager implements ActionManager<Player> {
this.registerFishFindAction();
this.registerPluginExpAction();
this.registerSoundAction();
this.registerHologramAction();
this.registerTitleAction();
}
@@ -390,7 +394,7 @@ public class BukkitActionManager implements ActionManager<Player> {
itemStack.setAmount(Math.max(0, itemStack.getAmount() + amount));
};
} else {
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at item-amount action which should be Section");
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at item-amount action which is expected to be `Section`");
return EmptyAction.INSTANCE;
}
});
@@ -409,7 +413,7 @@ public class BukkitActionManager implements ActionManager<Player> {
// }
};
} else {
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at durability action which should be Section");
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at durability action which is expected to be `Section`");
return EmptyAction.INSTANCE;
}
});
@@ -432,7 +436,7 @@ public class BukkitActionManager implements ActionManager<Player> {
}
};
} else {
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at give-item action which should be Section");
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at give-item action which is expected to be `Section`");
return EmptyAction.INSTANCE;
}
});
@@ -543,7 +547,7 @@ public class BukkitActionManager implements ActionManager<Player> {
}
};
} else {
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at conditional action which should be Section");
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at conditional action which is expected to be `Section`");
return EmptyAction.INSTANCE;
}
});
@@ -575,7 +579,7 @@ public class BukkitActionManager implements ActionManager<Player> {
}
};
} else {
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at priority action which should be Section");
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at priority action which is expected to be `Section`");
return EmptyAction.INSTANCE;
}
});
@@ -611,7 +615,7 @@ public class BukkitActionManager implements ActionManager<Player> {
context.getHolder().addPotionEffect(potionEffect);
};
} else {
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at potion-effect action which should be Section");
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at potion-effect action which is expected to be `Section`");
return EmptyAction.INSTANCE;
}
});
@@ -632,7 +636,7 @@ public class BukkitActionManager implements ActionManager<Player> {
AdventureHelper.playSound(audience, sound);
};
} else {
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at sound action which should be Section");
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at sound action which is expected to be `Section`");
return EmptyAction.INSTANCE;
}
});
@@ -652,7 +656,7 @@ public class BukkitActionManager implements ActionManager<Player> {
}, () -> plugin.getPluginLogger().warn("Plugin (" + pluginName + "'s) level is not compatible. Please double check if it's a problem caused by pronunciation."));
};
} else {
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at plugin-exp action which should be Section");
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at plugin-exp action which is expected to be `Section`");
return EmptyAction.INSTANCE;
}
});
@@ -677,7 +681,7 @@ public class BukkitActionManager implements ActionManager<Player> {
);
};
} else {
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at title action which should be Section");
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at title action which is expected to be `Section`");
return EmptyAction.INSTANCE;
}
});
@@ -703,7 +707,7 @@ public class BukkitActionManager implements ActionManager<Player> {
);
};
} else {
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at random-title action which should be Section");
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at random-title action which is expected to be `Section`");
return EmptyAction.INSTANCE;
}
});
@@ -735,12 +739,61 @@ public class BukkitActionManager implements ActionManager<Player> {
);
};
} else {
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at title-nearby action which should be Section");
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at title-nearby action which is expected to be `Section`");
return EmptyAction.INSTANCE;
}
});
}
private void registerHologramAction() {
registerAction("hologram", ((args, chance) -> {
if (args instanceof Section section) {
TextValue<Player> text = TextValue.auto(section.getString("text", ""));
MathValue<Player> duration = MathValue.auto(section.get("duration", 20));
boolean position = section.getString("position", "other").equals("other");
MathValue<Player> x = MathValue.auto(section.get("x", 0));
MathValue<Player> y = MathValue.auto(section.get("y", 0));
MathValue<Player> z = MathValue.auto(section.get("z", 0));
int range = section.getInt("range", 16);
return context -> {
if (Math.random() > chance) return;
Player owner = context.getHolder();
Location location = position ? requireNonNull(context.arg(ContextKeys.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);
armorStand.small(true);
armorStand.name(AdventureHelper.miniMessageToJson(text.render(context)));
ArrayList<Player> viewers = new ArrayList<>();
if (range > 0) {
for (Entity player : location.getWorld().getNearbyEntities(location, range, range, range, entity -> entity instanceof Player)) {
double distance = LocationUtils.getDistance(player.getLocation(), location);
if (distance <= range) {
viewers.add((Player) player);
}
}
} else {
viewers.add(owner);
}
for (Player player : viewers) {
armorStand.spawn(player);
}
plugin.getScheduler().asyncLater(() -> {
for (Player player : viewers) {
if (player.isOnline() && player.isValid()) {
armorStand.destroy(player);
}
}
}, (long) (duration.evaluate(context) * 50), TimeUnit.MILLISECONDS);
};
} else {
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at hologram action which is expected to be `Section`");
return EmptyAction.INSTANCE;
}
}));
}
private void registerFishFindAction() {
registerAction("fish-finder", (args, chance) -> {
return context -> {

View File

@@ -20,6 +20,7 @@ package net.momirealms.customfishing.bukkit.block;
import dev.dejvokep.boostedyaml.block.implementation.Section;
import net.momirealms.customfishing.api.BukkitCustomFishingPlugin;
import net.momirealms.customfishing.api.integration.BlockProvider;
import net.momirealms.customfishing.api.integration.ExternalProvider;
import net.momirealms.customfishing.api.mechanic.block.*;
import net.momirealms.customfishing.api.mechanic.config.ConfigManager;
import net.momirealms.customfishing.api.mechanic.context.Context;
@@ -92,6 +93,11 @@ public class BukkitBlockManager implements BlockManager, Listener {
public void load() {
Bukkit.getPluginManager().registerEvents(this, plugin.getBoostrap());
this.resetBlockDetectionOrder();
for (BlockProvider provider : blockProviders.values()) {
plugin.debug("Registered BlockProvider: " + provider.identifier());
}
plugin.debug("Loaded " + blocks.size() + " blocks");
plugin.debug("Block order: " + Arrays.toString(Arrays.stream(blockDetectArray).map(ExternalProvider::identifier).toList().toArray(new String[0])));
}
@Override

View File

@@ -67,6 +67,7 @@ public class BukkitCompetitionManager implements CompetitionManager {
1,
TimeUnit.SECONDS
);
plugin.debug("Loaded " + commandConfigMap.size() + " competitions");
}
public void unload() {

View File

@@ -383,7 +383,8 @@ public class BukkitConfigManager extends ConfigManager {
}
}
private List<Pair<String, BiFunction<Context<Player>, Double, Double>>> parseWeightOperation(List<String> ops) {
@Override
public List<Pair<String, BiFunction<Context<Player>, Double, Double>>> parseWeightOperation(List<String> ops) {
List<Pair<String, BiFunction<Context<Player>, Double, Double>>> result = new ArrayList<>();
for (String op : ops) {
String[] split = op.split(":", 2);
@@ -392,7 +393,8 @@ public class BukkitConfigManager extends ConfigManager {
return result;
}
private List<Pair<String, BiFunction<Context<Player>, Double, Double>>> parseGroupWeightOperation(List<String> gops) {
@Override
public List<Pair<String, BiFunction<Context<Player>, Double, Double>>> parseGroupWeightOperation(List<String> gops) {
List<Pair<String, BiFunction<Context<Player>, Double, Double>>> result = new ArrayList<>();
for (String gop : gops) {
String[] split = gop.split(":", 2);

View File

@@ -41,7 +41,7 @@ public class BukkitEffectManager implements EffectManager {
@Override
public void load() {
plugin.debug("Loaded " + effectModifiers.size() + " effects");
}
@Override

View File

@@ -59,6 +59,14 @@ public class BukkitEntityManager implements EntityManager {
});
}
@Override
public void load() {
for (EntityProvider provider : entityProviders.values()) {
plugin.debug("Registered EntityProvider: " + provider.identifier());
}
plugin.debug("Loaded " + entities.size() + " entities");
}
@Override
public void unload() {
this.entities.clear();

View File

@@ -4,43 +4,61 @@ import net.momirealms.customfishing.api.BukkitCustomFishingPlugin;
import net.momirealms.customfishing.api.event.RodCastEvent;
import net.momirealms.customfishing.api.mechanic.config.ConfigManager;
import net.momirealms.customfishing.api.mechanic.context.Context;
import net.momirealms.customfishing.api.mechanic.effect.Effect;
import net.momirealms.customfishing.api.mechanic.fishing.FishingGears;
import net.momirealms.customfishing.api.mechanic.fishing.CustomFishingHook;
import net.momirealms.customfishing.api.mechanic.fishing.FishingGears;
import net.momirealms.customfishing.api.mechanic.fishing.FishingManager;
import net.momirealms.customfishing.api.mechanic.fishing.hook.VanillaMechanic;
import net.momirealms.customfishing.api.mechanic.requirement.RequirementManager;
import net.momirealms.customfishing.bukkit.util.EventUtils;
import net.momirealms.customfishing.common.helper.VersionHelper;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Entity;
import org.bukkit.entity.FishHook;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerFishEvent;
import org.bukkit.event.player.PlayerItemHeldEvent;
import org.bukkit.event.player.PlayerSwapHandItemsEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.persistence.PersistentDataType;
import java.util.Objects;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
public class BukkitFishingManager implements FishingManager, Listener {
private BukkitCustomFishingPlugin plugin;
private final ConcurrentHashMap<UUID, FishHook> castHooks = new ConcurrentHashMap<>();
private final ConcurrentHashMap<UUID, FishingGears> gears = new ConcurrentHashMap<>();
private final ConcurrentHashMap<UUID, CustomFishingHook> tasks = new ConcurrentHashMap<>();
private final BukkitCustomFishingPlugin plugin;
private final ConcurrentHashMap<UUID, CustomFishingHook> castHooks = new ConcurrentHashMap<>();
public BukkitFishingManager(BukkitCustomFishingPlugin plugin) {
this.plugin = plugin;
}
@Override
public Optional<FishHook> getFishHook(Player player) {
return Optional.ofNullable(castHooks.get(player.getUniqueId()));
public void unload() {
HandlerList.unregisterAll(this);
}
@Override
public Optional<FishHook> getFishHook(UUID player) {
public void load() {
Bukkit.getPluginManager().registerEvents(this, plugin.getBoostrap());
}
@Override
public Optional<CustomFishingHook> getFishHook(Player player) {
return getFishHook(player.getUniqueId());
}
@Override
public Optional<CustomFishingHook> getFishHook(UUID player) {
return Optional.ofNullable(castHooks.get(player));
}
@@ -105,46 +123,87 @@ public class BukkitFishingManager implements FishingManager, Listener {
private void selectState(PlayerFishEvent event) {
switch (event.getState()) {
case FISHING -> onCastRod(event);
// case REEL_IN -> onReelIn(event);
// case CAUGHT_ENTITY -> onCaughtEntity(event);
// case CAUGHT_FISH -> onCaughtFish(event);
// case BITE -> onBite(event);
// case IN_GROUND -> onInGround(event);
case REEL_IN -> onReelIn(event);
case CAUGHT_ENTITY -> onCaughtEntity(event);
case CAUGHT_FISH -> onCaughtFish(event);
case BITE -> onBite(event);
case IN_GROUND -> onInGround(event);
}
}
private void onCaughtEntity(PlayerFishEvent event) {
final Player player = event.getPlayer();
getFishHook(player).ifPresent(hook -> {
Entity entity = event.getCaught();
if (entity != null && entity.getPersistentDataContainer().get(
Objects.requireNonNull(NamespacedKey.fromString("temp-entity", plugin.getBoostrap())),
PersistentDataType.STRING
) != null) {
}
});
}
private void onReelIn(PlayerFishEvent event) {
Player player = event.getPlayer();
getFishHook(player).ifPresent(hook -> {
hook.onReelIn();
});
}
private void onBite(PlayerFishEvent event) {
Player player = event.getPlayer();
getFishHook(player).ifPresent(hook -> {
hook.onBite();
});
}
private void onCaughtFish(PlayerFishEvent event) {
Player player = event.getPlayer();
getFishHook(player).ifPresent(hook -> {
hook.onReelIn();
});
}
private void onCastRod(PlayerFishEvent event) {
FishHook hook = event.getHook();
Player player = event.getPlayer();
Context<Player> context = Context.player(player);
FishingGears gears = new FishingGears(context);
this.gears.put(player.getUniqueId(), gears);
if (!RequirementManager.isSatisfied(context, ConfigManager.mechanicRequirements())) {
this.destroy(player.getUniqueId());
event.setCancelled(true);
return;
}
RodCastEvent rodCastEvent = new RodCastEvent(event, gears);
Bukkit.getPluginManager().callEvent(rodCastEvent);
if (rodCastEvent.isCancelled()) {
if (EventUtils.fireAndCheckCancel(new RodCastEvent(event, gears))) {
return;
}
plugin.debug(context.toString());
gears.cast();
this.castHooks.put(player.getUniqueId(), hook);
CustomFishingHook customHook = new CustomFishingHook(hook, gears, context);
this.castHooks.put(player.getUniqueId(), customHook);
}
private void onInGround(PlayerFishEvent event) {
if (VersionHelper.isVersionNewerThan1_20_5()) return;
final Player player = event.getPlayer();
if (player.getGameMode() != GameMode.CREATIVE) {
ItemStack itemStack = player.getInventory().getItemInMainHand();
if (itemStack.getType() != Material.FISHING_ROD) itemStack = player.getInventory().getItemInOffHand();
if (itemStack.getType() == Material.FISHING_ROD) {
plugin.getItemManager().decreaseDurability(itemStack, 5, true);
}
}
}
@Override
public void destroy(UUID uuid) {
this.getFishHook(uuid).ifPresent(hook -> {
hook.remove();
hook.destroy();
this.castHooks.remove(uuid);
});
this.gears.remove(uuid);
CustomFishingHook task = this.tasks.remove(uuid);
if (task != null) {
task.cancel();
}
}
}

View File

@@ -34,6 +34,7 @@ public class BukkitHookManager implements HookManager, Listener {
@Override
public void load() {
Bukkit.getPluginManager().registerEvents(this, plugin.getBoostrap());
plugin.debug("Loaded " + hooks.size() + " hooks");
}
@Override

View File

@@ -3,6 +3,7 @@ package net.momirealms.customfishing.bukkit.item;
import net.momirealms.customfishing.api.BukkitCustomFishingPlugin;
import net.momirealms.customfishing.api.event.FishingLootPreSpawnEvent;
import net.momirealms.customfishing.api.event.FishingLootSpawnEvent;
import net.momirealms.customfishing.api.integration.ExternalProvider;
import net.momirealms.customfishing.api.integration.ItemProvider;
import net.momirealms.customfishing.api.mechanic.config.ConfigManager;
import net.momirealms.customfishing.api.mechanic.context.Context;
@@ -10,6 +11,7 @@ import net.momirealms.customfishing.api.mechanic.context.ContextKeys;
import net.momirealms.customfishing.api.mechanic.item.CustomFishingItem;
import net.momirealms.customfishing.api.mechanic.item.ItemManager;
import net.momirealms.customfishing.api.mechanic.item.MechanicType;
import net.momirealms.customfishing.bukkit.integration.item.CustomFishingItemProvider;
import net.momirealms.customfishing.bukkit.util.ItemUtils;
import net.momirealms.customfishing.bukkit.util.LocationUtils;
import net.momirealms.customfishing.common.item.Item;
@@ -67,6 +69,7 @@ public class BukkitItemManager implements ItemManager, Listener {
return "vanilla";
}
});
this.registerItemProvider(new CustomFishingItemProvider());
}
@Override
@@ -79,6 +82,11 @@ public class BukkitItemManager implements ItemManager, Listener {
public void load() {
Bukkit.getPluginManager().registerEvents(this, plugin.getBoostrap());
this.resetItemDetectionOrder();
for (ItemProvider provider : itemProviders.values()) {
plugin.debug("Registered ItemProvider: " + provider.identifier());
}
plugin.debug("Loaded " + items.size() + " items");
plugin.debug("Item order: " + Arrays.toString(Arrays.stream(itemDetectArray).map(ExternalProvider::identifier).toList().toArray(new String[0])));
}
@Override
@@ -220,7 +228,7 @@ public class BukkitItemManager implements ItemManager, Listener {
}
@Override
public void decreaseDurability(ItemStack itemStack) {
public void decreaseDurability(ItemStack itemStack, int amount, boolean incorrectUsage) {
}

View File

@@ -93,21 +93,38 @@ public class ComponentItemFactory extends BukkitItemFactory {
@Override
protected boolean unbreakable(RtagItem item) {
return false;
return item.isUnbreakable();
}
@Override
protected void unbreakable(RtagItem item, boolean unbreakable) {
item.setUnbreakable(unbreakable);
}
@Override
protected Optional<Boolean> glint(RtagItem item) {
return Optional.empty();
return Optional.ofNullable((Boolean) item.getComponent(ComponentKeys.ENCHANTMENT_GLINT_OVERRIDE));
}
@Override
protected void glint(RtagItem item, Boolean glint) {
item.setComponent(ComponentKeys.ENCHANTMENT_GLINT_OVERRIDE, glint);
}
@Override
protected Optional<Integer> damage(RtagItem item) {
if (!item.hasComponent(ComponentKeys.DAMAGE)) return Optional.empty();
return Optional.ofNullable(
(Integer) ComponentType.encodeJava(
ComponentKeys.DAMAGE,
item.getComponent(ComponentKeys.DAMAGE)
).orElse(null)
);
}
@Override
protected void damage(RtagItem item, Integer damage) {
if (damage == null) damage = 0;
item.setComponent(ComponentKeys.DAMAGE, damage);
}
}

View File

@@ -70,21 +70,32 @@ public class UniversalItemFactory extends BukkitItemFactory {
@Override
protected boolean unbreakable(RtagItem item) {
return false;
return item.isUnbreakable();
}
@Override
protected void unbreakable(RtagItem item, boolean unbreakable) {
item.setUnbreakable(unbreakable);
}
@Override
protected Optional<Boolean> glint(RtagItem item) {
return Optional.empty();
return Optional.of(false);
}
@Override
protected void glint(RtagItem item, Boolean glint) {
throw new UnsupportedOperationException("This feature is only available on 1.20.5+");
}
}
@Override
protected Optional<Integer> damage(RtagItem item) {
if (!item.hasTag("Damage")) return Optional.empty();
return Optional.of(item.get("Damage"));
}
@Override
protected void damage(RtagItem item, Integer damage) {
item.set(damage, "Damage");
}
}

View File

@@ -1,24 +1,30 @@
package net.momirealms.customfishing.bukkit.loot;
import dev.dejvokep.boostedyaml.YamlDocument;
import dev.dejvokep.boostedyaml.block.implementation.Section;
import net.momirealms.customfishing.api.BukkitCustomFishingPlugin;
import net.momirealms.customfishing.api.mechanic.context.Context;
import net.momirealms.customfishing.api.mechanic.effect.Effect;
import net.momirealms.customfishing.api.mechanic.loot.Loot;
import net.momirealms.customfishing.api.mechanic.loot.LootManager;
import net.momirealms.customfishing.api.mechanic.requirement.ConditionalElement;
import net.momirealms.customfishing.api.mechanic.requirement.RequirementManager;
import net.momirealms.customfishing.common.util.Pair;
import net.momirealms.customfishing.common.util.WeightUtils;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Optional;
import java.io.File;
import java.util.*;
import java.util.function.BiFunction;
public class BukkitLootManager implements LootManager {
private final BukkitCustomFishingPlugin plugin;
private final HashMap<String, Loot> lootMap = new HashMap<>();
private final HashMap<String, List<String>> groupMembersMap = new HashMap<>();
private final LinkedHashMap<String, ConditionalElement<List<Pair<String, BiFunction<Context<Player>, Double, Double>>>, Player>> lootConditions = new LinkedHashMap<>();
public BukkitLootManager(BukkitCustomFishingPlugin plugin) {
this.plugin = plugin;
@@ -28,11 +34,48 @@ public class BukkitLootManager implements LootManager {
public void unload() {
this.lootMap.clear();
this.groupMembersMap.clear();
this.lootConditions.clear();
}
@Override
public void load() {
plugin.debug("Loaded " + lootMap.size() + " loots");
for (Map.Entry<String, List<String>> entry : groupMembersMap.entrySet()) {
plugin.debug("Group: {" + entry.getKey() + "} Members: " + entry.getValue());
}
File file = new File(plugin.getDataFolder(), "loot-conditions.yml");
if (!file.exists()) {
plugin.getBoostrap().saveResource("loot-conditions.yml", false);
}
YamlDocument lootConditionsConfig = plugin.getConfigManager().loadData(file);
for (Map.Entry<String, Object> entry : lootConditionsConfig.getStringRouteMappedValues(false).entrySet()) {
if (entry.getValue() instanceof Section section) {
lootConditions.put(entry.getKey(), parseLootConditions(section));
}
}
}
private ConditionalElement<List<Pair<String, BiFunction<Context<Player>, Double, Double>>>, Player> parseLootConditions(Section section) {
Section subSection = section.getSection("sub-groups");
if (subSection == null) {
return new ConditionalElement<>(
plugin.getConfigManager().parseWeightOperation(section.getStringList("list")),
Map.of(),
plugin.getRequirementManager().parseRequirements(section.getSection("conditions"), false)
);
} else {
HashMap<String, ConditionalElement<List<Pair<String, BiFunction<Context<Player>, Double, Double>>>, Player>> subElements = new HashMap<>();
for (Map.Entry<String, Object> entry : subSection.getStringRouteMappedValues(false).entrySet()) {
if (entry.getValue() instanceof Section innerSection) {
subElements.put(entry.getKey(), parseLootConditions(innerSection));
}
}
return new ConditionalElement<>(
plugin.getConfigManager().parseWeightOperation(section.getStringList("list")),
subElements,
plugin.getRequirementManager().parseRequirements(section.getSection("conditions"), false)
);
}
}
@Override
@@ -73,6 +116,33 @@ public class BukkitLootManager implements LootManager {
@Nullable
@Override
public Loot getNextLoot(Effect effect, Context<Player> context) {
return null;
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));
}
String lootID = WeightUtils.getRandom(lootWeightMap);
return getLoot(lootID).orElseThrow(() -> new RuntimeException("Could not find loot " + lootID));
}
private void modifyWeightMap(Map<String, Double> weightMap, Context<Player> context, ConditionalElement<List<Pair<String, BiFunction<Context<Player>, Double, Double>>>, Player> conditionalElement) {
if (conditionalElement == null) return;
if (RequirementManager.isSatisfied(context, conditionalElement.getRequirements())) {
for (Pair<String, BiFunction<Context<Player>, Double, Double>> modifierPair : conditionalElement.getElement()) {
double previous = weightMap.getOrDefault(modifierPair.left(), 0d);
weightMap.put(modifierPair.left(), modifierPair.right().apply(context, previous));
}
for (ConditionalElement<List<Pair<String, BiFunction<Context<Player>, Double, Double>>>, Player> sub : conditionalElement.getSubElements().values()) {
modifyWeightMap(weightMap, context, sub);
}
}
}
}

View File

@@ -26,6 +26,7 @@ import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.jetbrains.annotations.NotNull;
@@ -85,16 +86,17 @@ public class BukkitRequirementManager implements RequirementManager<Player> {
@NotNull
@Override
@SuppressWarnings("unchecked")
public Requirement<Player>[] parseRequirements(@NotNull Section section, boolean runActions) {
public Requirement<Player>[] parseRequirements(Section section, boolean runActions) {
List<Requirement<Player>> requirements = new ArrayList<>();
for (Map.Entry<String, Object> entry : section.getStringRouteMappedValues(false).entrySet()) {
String typeOrName = entry.getKey();
if (hasRequirement(typeOrName)) {
requirements.add(parseRequirement(typeOrName, entry.getValue()));
} else {
requirements.add(parseRequirement(section.getSection(typeOrName), runActions));
if (section != null)
for (Map.Entry<String, Object> entry : section.getStringRouteMappedValues(false).entrySet()) {
String typeOrName = entry.getKey();
if (hasRequirement(typeOrName)) {
requirements.add(parseRequirement(typeOrName, entry.getValue()));
} else {
requirements.add(parseRequirement(section.getSection(typeOrName), runActions));
}
}
}
return requirements.toArray(new Requirement[0]);
}
@@ -164,6 +166,7 @@ public class BukkitRequirementManager implements RequirementManager<Player> {
this.registerInBagRequirement();
this.registerCompetitionRequirement();
this.registerPluginLevelRequirement();
this.registerItemInHandRequirement();
}
private void registerCompetitionRequirement() {
@@ -191,7 +194,7 @@ public class BukkitRequirementManager implements RequirementManager<Player> {
return false;
};
} else {
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at competition requirement which should be Section");
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at competition requirement which is expected be `Section`");
return EmptyRequirement.INSTANCE;
}
});
@@ -209,6 +212,28 @@ public class BukkitRequirementManager implements RequirementManager<Player> {
});
}
private void registerItemInHandRequirement() {
registerRequirement("item-in-hand", (args, actions, advanced) -> {
if (args instanceof Section section) {
boolean mainOrOff = section.getString("hand","main").equalsIgnoreCase("main");
int amount = section.getInt("amount", 1);
List<String> items = ListUtils.toList(section.get("item"));
return context -> {
ItemStack itemStack = mainOrOff ?
context.getHolder().getInventory().getItemInMainHand()
: context.getHolder().getInventory().getItemInOffHand();
String id = plugin.getItemManager().getItemID(itemStack);
if (items.contains(id) && itemStack.getAmount() >= amount) return true;
if (advanced) ActionManager.trigger(context, actions);
return false;
};
} else {
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at item-in-hand requirement which is expected be `Section`");
return EmptyRequirement.INSTANCE;
}
});
}
private void registerPluginLevelRequirement() {
registerRequirement("plugin-level", (args, actions, advanced) -> {
if (args instanceof Section section) {
@@ -227,7 +252,7 @@ public class BukkitRequirementManager implements RequirementManager<Player> {
return false;
};
} else {
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at plugin-level requirement which should be Section");
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at plugin-level requirement which is expected be `Section`");
return EmptyRequirement.INSTANCE;
}
});
@@ -283,7 +308,7 @@ public class BukkitRequirementManager implements RequirementManager<Player> {
return false;
};
} else {
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at || requirement which should be Section");
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at || requirement which is expected be `Section`");
return EmptyRequirement.INSTANCE;
}
});
@@ -304,7 +329,7 @@ public class BukkitRequirementManager implements RequirementManager<Player> {
return false;
};
} else {
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at && requirement which should be Section");
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at && requirement which is expected be `Section`");
return EmptyRequirement.INSTANCE;
}
});
@@ -335,11 +360,19 @@ public class BukkitRequirementManager implements RequirementManager<Player> {
}
private void registerInLavaRequirement() {
// Deprecated requirement type
registerRequirement("lava-fishing", (args, actions, advanced) -> {
boolean inLava = (boolean) args;
if (!inLava) {
throw new IllegalArgumentException("");
// in water
return context -> {
boolean in_water = Optional.ofNullable(context.arg(ContextKeys.SURROUNDING)).orElse("").equals(EffectProperties.WATER_FISHING.key());
if (in_water) return true;
if (advanced) ActionManager.trigger(context, actions);
return false;
};
}
// in lava
return context -> {
boolean in_lava = Optional.ofNullable(context.arg(ContextKeys.SURROUNDING)).orElse("").equals(EffectProperties.LAVA_FISHING.key());
if (in_lava) return true;
@@ -768,7 +801,7 @@ public class BukkitRequirementManager implements RequirementManager<Player> {
return false;
};
} else {
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at cooldown requirement which should be Section");
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at cooldown requirement which is expected be `Section`");
return EmptyRequirement.INSTANCE;
}
});
@@ -839,7 +872,7 @@ public class BukkitRequirementManager implements RequirementManager<Player> {
return false;
};
} else {
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at < requirement which should be Section");
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at < requirement which is expected be `Section`");
return EmptyRequirement.INSTANCE;
}
});
@@ -853,7 +886,7 @@ public class BukkitRequirementManager implements RequirementManager<Player> {
return false;
};
} else {
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at <= requirement which should be Section");
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at <= requirement which is expected be `Section`");
return EmptyRequirement.INSTANCE;
}
});
@@ -867,7 +900,7 @@ public class BukkitRequirementManager implements RequirementManager<Player> {
return false;
};
} else {
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at != requirement which should be Section");
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at != requirement which is expected be `Section`");
return EmptyRequirement.INSTANCE;
}
});
@@ -881,7 +914,7 @@ public class BukkitRequirementManager implements RequirementManager<Player> {
return false;
};
} else {
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at == requirement which should be Section");
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at == requirement which is expected be `Section`");
return EmptyRequirement.INSTANCE;
}
});
@@ -895,7 +928,7 @@ public class BukkitRequirementManager implements RequirementManager<Player> {
return false;
};
} else {
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at >= requirement which should be Section");
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at >= requirement which is expected be `Section`");
return EmptyRequirement.INSTANCE;
}
});
@@ -909,7 +942,7 @@ public class BukkitRequirementManager implements RequirementManager<Player> {
return false;
};
} else {
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at > requirement which should be Section");
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at > requirement which is expected be `Section`");
return EmptyRequirement.INSTANCE;
}
});
@@ -923,7 +956,7 @@ public class BukkitRequirementManager implements RequirementManager<Player> {
return false;
};
} else {
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at regex requirement which should be Section");
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at regex requirement which is expected be `Section`");
return EmptyRequirement.INSTANCE;
}
});
@@ -937,7 +970,7 @@ public class BukkitRequirementManager implements RequirementManager<Player> {
return false;
};
} else {
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at startsWith requirement which should be Section");
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at startsWith requirement which is expected be `Section`");
return EmptyRequirement.INSTANCE;
}
});
@@ -951,7 +984,7 @@ public class BukkitRequirementManager implements RequirementManager<Player> {
return false;
};
} else {
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at !startsWith requirement which should be Section");
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at !startsWith requirement which is expected be `Section`");
return EmptyRequirement.INSTANCE;
}
});
@@ -965,7 +998,7 @@ public class BukkitRequirementManager implements RequirementManager<Player> {
return false;
};
} else {
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at endsWith requirement which should be Section");
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at endsWith requirement which is expected be `Section`");
return EmptyRequirement.INSTANCE;
}
});
@@ -979,7 +1012,7 @@ public class BukkitRequirementManager implements RequirementManager<Player> {
return false;
};
} else {
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at !endsWith requirement which should be Section");
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at !endsWith requirement which is expected be `Section`");
return EmptyRequirement.INSTANCE;
}
});
@@ -993,7 +1026,7 @@ public class BukkitRequirementManager implements RequirementManager<Player> {
return false;
};
} else {
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at contains requirement which should be Section");
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at contains requirement which is expected be `Section`");
return EmptyRequirement.INSTANCE;
}
});
@@ -1007,7 +1040,7 @@ public class BukkitRequirementManager implements RequirementManager<Player> {
return false;
};
} else {
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at !contains requirement which should be Section");
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at !contains requirement which is expected be `Section`");
return EmptyRequirement.INSTANCE;
}
});
@@ -1021,7 +1054,7 @@ public class BukkitRequirementManager implements RequirementManager<Player> {
return false;
};
} else {
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at in-list requirement which should be Section");
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at in-list requirement which is expected be `Section`");
return EmptyRequirement.INSTANCE;
}
});
@@ -1035,7 +1068,7 @@ public class BukkitRequirementManager implements RequirementManager<Player> {
return false;
};
} else {
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at !in-list requirement which should be Section");
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at !in-list requirement which is expected be `Section`");
return EmptyRequirement.INSTANCE;
}
});
@@ -1049,7 +1082,7 @@ public class BukkitRequirementManager implements RequirementManager<Player> {
return false;
};
} else {
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at equals requirement which should be Section");
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at equals requirement which is expected be `Section`");
return EmptyRequirement.INSTANCE;
}
});
@@ -1063,7 +1096,7 @@ public class BukkitRequirementManager implements RequirementManager<Player> {
return false;
};
} else {
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at !equals requirement which should be Section");
plugin.getPluginLogger().warn("Invalid value type: " + args.getClass().getSimpleName() + " found at !equals requirement which is expected be `Section`");
return EmptyRequirement.INSTANCE;
}
});

View File

@@ -37,6 +37,9 @@ public class BukkitStatisticsManager implements StatisticsManager {
@Override
public void load() {
this.loadCategoriesFromPluginFolder();
for (Map.Entry<String, List<String>> entry : categoryMap.entrySet()) {
plugin.debug("Category: {" + entry.getKey() + "} Members: " + entry.getValue());
}
}
@Override

View File

@@ -79,6 +79,7 @@ public class BukkitTotemManager implements TotemManager, Listener {
activatedTotems.remove(simpleLocation);
}
}, 1, 1, TimeUnit.SECONDS);
plugin.debug("Loaded " + id2Totem.size() + " totems");
}
@Override

View File

@@ -0,0 +1,36 @@
/*
* 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.util;
import org.bukkit.Bukkit;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
public class EventUtils {
public static void fireAndForget(Event event) {
Bukkit.getPluginManager().callEvent(event);
}
public static boolean fireAndCheckCancel(Event event) {
if (!(event instanceof Cancellable cancellable))
throw new IllegalArgumentException("Only cancellable events are allowed here");
Bukkit.getPluginManager().callEvent(event);
return cancellable.isCancelled();
}
}

View File

@@ -350,6 +350,12 @@ mechanics:
# Lava fishing settings
# To modify vanilla fishing time, you should edit paper-world-defaults.yml where there's a section called fishing-time-range
lava-fishing:
enable: true
# ticks
min-wait-time: 100
max-wait-time: 600
void-fishing:
enable: true
# ticks
min-wait-time: 100
max-wait-time: 600