mirror of
https://github.com/Xiao-MoMi/Custom-Fishing.git
synced 2025-12-27 10:59:13 +00:00
events and actions
This commit is contained in:
@@ -26,6 +26,7 @@ import net.momirealms.customfishing.adventure.AdventureManagerImpl;
|
||||
import net.momirealms.customfishing.api.CustomFishingPlugin;
|
||||
import net.momirealms.customfishing.api.manager.CommandManager;
|
||||
import net.momirealms.customfishing.command.sub.CompetitionCommand;
|
||||
import net.momirealms.customfishing.command.sub.DebugCommand;
|
||||
import net.momirealms.customfishing.command.sub.FishingBagCommand;
|
||||
import net.momirealms.customfishing.command.sub.ItemCommand;
|
||||
import net.momirealms.customfishing.setting.Locale;
|
||||
@@ -47,7 +48,8 @@ public class CommandManagerImpl implements CommandManager {
|
||||
.withSubcommands(
|
||||
getReloadCommand(),
|
||||
CompetitionCommand.INSTANCE.getCompetitionCommand(),
|
||||
ItemCommand.INSTANCE.getItemCommand()
|
||||
ItemCommand.INSTANCE.getItemCommand(),
|
||||
DebugCommand.INSTANCE.getDebugCommand()
|
||||
)
|
||||
.register();
|
||||
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
package net.momirealms.customfishing.command.sub;
|
||||
|
||||
import dev.jorel.commandapi.CommandAPICommand;
|
||||
import dev.jorel.commandapi.IStringTooltip;
|
||||
import dev.jorel.commandapi.StringTooltip;
|
||||
import dev.jorel.commandapi.arguments.ArgumentSuggestions;
|
||||
import dev.jorel.commandapi.arguments.BooleanArgument;
|
||||
import net.momirealms.biomeapi.BiomeAPI;
|
||||
import net.momirealms.customfishing.adventure.AdventureManagerImpl;
|
||||
import net.momirealms.customfishing.api.CustomFishingPlugin;
|
||||
import net.momirealms.customfishing.api.integration.SeasonInterface;
|
||||
import net.momirealms.customfishing.api.manager.AdventureManager;
|
||||
import net.momirealms.customfishing.api.mechanic.condition.FishingPreparation;
|
||||
import net.momirealms.customfishing.api.mechanic.effect.Effect;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class DebugCommand {
|
||||
|
||||
public static DebugCommand INSTANCE = new DebugCommand();
|
||||
|
||||
public CommandAPICommand getDebugCommand() {
|
||||
return new CommandAPICommand("debug")
|
||||
.withSubcommands(
|
||||
getLootChanceCommand(),
|
||||
getBiomeCommand(),
|
||||
getSeasonCommand()
|
||||
);
|
||||
}
|
||||
|
||||
public CommandAPICommand getBiomeCommand() {
|
||||
return new CommandAPICommand("biome")
|
||||
.executesPlayer((player, arg) -> {
|
||||
AdventureManagerImpl.getInstance().sendMessage(player, BiomeAPI.getBiome(player.getLocation()));
|
||||
});
|
||||
}
|
||||
|
||||
public CommandAPICommand getSeasonCommand() {
|
||||
return new CommandAPICommand("season")
|
||||
.executesPlayer((player, arg) -> {
|
||||
SeasonInterface seasonInterface = CustomFishingPlugin.get().getIntegrationManager().getSeasonInterface();
|
||||
if (seasonInterface == null) {
|
||||
AdventureManagerImpl.getInstance().sendMessageWithPrefix(player, "NO SEASON PLUGIN");
|
||||
return;
|
||||
}
|
||||
AdventureManagerImpl.getInstance().sendMessage(player, seasonInterface.getSeason(player.getLocation().getWorld()));
|
||||
});
|
||||
}
|
||||
|
||||
public CommandAPICommand getLootChanceCommand() {
|
||||
return new CommandAPICommand("loot-chance")
|
||||
.withArguments(new BooleanArgument("lava fishing").replaceSuggestions(ArgumentSuggestions.stringsWithTooltips(info ->
|
||||
new IStringTooltip[] {
|
||||
StringTooltip.ofString("true", "loots in lava"),
|
||||
StringTooltip.ofString("false", "loots in water")
|
||||
})))
|
||||
.executesPlayer((player, arg) -> {
|
||||
Effect initialEffect = CustomFishingPlugin.get().getEffectManager().getInitialEffect();
|
||||
FishingPreparation fishingPreparation = new FishingPreparation(player, CustomFishingPlugin.get());
|
||||
boolean inLava = (boolean) arg.getOrDefault("lava fishing", false);
|
||||
fishingPreparation.insertArg("{lava}", String.valueOf(inLava));
|
||||
fishingPreparation.mergeEffect(initialEffect);
|
||||
//TODO apply totems
|
||||
|
||||
var map = CustomFishingPlugin.get().getFishingManager().getPossibleLootKeysWithWeight(initialEffect, fishingPreparation);
|
||||
List<LootWithWeight> loots = new ArrayList<>();
|
||||
double sum = 0;
|
||||
for (Map.Entry<String, Double> entry : map.entrySet()) {
|
||||
double weight = entry.getValue();
|
||||
String loot = entry.getKey();
|
||||
if (weight <= 0) continue;
|
||||
loots.add(new LootWithWeight(loot, weight));
|
||||
sum += weight;
|
||||
}
|
||||
LootWithWeight[] lootArray = loots.toArray(new LootWithWeight[0]);
|
||||
quickSort(lootArray, 0,lootArray.length - 1);
|
||||
AdventureManager adventureManager = AdventureManagerImpl.getInstance();
|
||||
adventureManager.sendMessage(player, "<red>---------- results ---------");
|
||||
for (LootWithWeight loot : lootArray) {
|
||||
adventureManager.sendMessage(player, "<hover:show_text:'<blue>GET'><click:run_command:/cfishing items loot get "+ loot.key() + ">" +loot.key() + "</click></hover>: <gold>" + String.format("%.2f", loot.weight()*100/sum) + "% <gray>(" + String.format("%.2f", loot.weight()) + ")");
|
||||
}
|
||||
adventureManager.sendMessage(player, "<red>----------- end -----------");
|
||||
});
|
||||
}
|
||||
|
||||
public record LootWithWeight(String key, double weight) {
|
||||
}
|
||||
|
||||
public static void quickSort(LootWithWeight[] loot, int low, int high) {
|
||||
if (low < high) {
|
||||
int pi = partition(loot, low, high);
|
||||
quickSort(loot, low, pi - 1);
|
||||
quickSort(loot, pi + 1, high);
|
||||
}
|
||||
}
|
||||
|
||||
public static int partition(LootWithWeight[] loot, int low, int high) {
|
||||
double pivot = loot[high].weight();
|
||||
int i = low - 1;
|
||||
for (int j = low; j <= high - 1; j++) {
|
||||
if (loot[j].weight() > pivot) {
|
||||
i++;
|
||||
swap(loot, i, j);
|
||||
}
|
||||
}
|
||||
swap(loot, i + 1, high);
|
||||
return i + 1;
|
||||
}
|
||||
|
||||
public static void swap(LootWithWeight[] loot, int i, int j) {
|
||||
LootWithWeight temp = loot[i];
|
||||
loot[i] = loot[j];
|
||||
loot[j] = temp;
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,10 @@ import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
@@ -32,7 +36,7 @@ import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class PlaceholderManagerImpl implements PlaceholderManager {
|
||||
public class PlaceholderManagerImpl implements PlaceholderManager, Listener {
|
||||
|
||||
private static PlaceholderManagerImpl instance;
|
||||
private final CustomFishingPlugin plugin;
|
||||
@@ -59,18 +63,25 @@ public class PlaceholderManagerImpl implements PlaceholderManager {
|
||||
public void load() {
|
||||
if (competitionPapi != null) competitionPapi.load();
|
||||
if (statisticsPapi != null) statisticsPapi.load();
|
||||
Bukkit.getPluginManager().registerEvents(this, plugin);
|
||||
loadCustomPlaceholders();
|
||||
}
|
||||
|
||||
public void unload() {
|
||||
if (competitionPapi != null) competitionPapi.unload();
|
||||
if (statisticsPapi != null) statisticsPapi.unload();
|
||||
HandlerList.unregisterAll(this);
|
||||
}
|
||||
|
||||
public void disable() {
|
||||
this.customPlaceholderMap.clear();
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onQuit(PlayerQuitEvent event) {
|
||||
cachedPlaceholders.remove(event.getPlayer().getUniqueId());
|
||||
}
|
||||
|
||||
public void loadCustomPlaceholders() {
|
||||
YamlConfiguration config = plugin.getConfig("config.yml");
|
||||
ConfigurationSection section = config.getConfigurationSection("other-settings.placeholder-register");
|
||||
|
||||
@@ -23,16 +23,21 @@ import net.momirealms.customfishing.adventure.AdventureManagerImpl;
|
||||
import net.momirealms.customfishing.api.CustomFishingPlugin;
|
||||
import net.momirealms.customfishing.api.common.Pair;
|
||||
import net.momirealms.customfishing.api.manager.ActionManager;
|
||||
import net.momirealms.customfishing.api.mechanic.GlobalSettings;
|
||||
import net.momirealms.customfishing.api.mechanic.action.Action;
|
||||
import net.momirealms.customfishing.api.mechanic.action.ActionExpansion;
|
||||
import net.momirealms.customfishing.api.mechanic.action.ActionFactory;
|
||||
import net.momirealms.customfishing.api.mechanic.action.ActionTrigger;
|
||||
import net.momirealms.customfishing.api.mechanic.requirement.Requirement;
|
||||
import net.momirealms.customfishing.api.util.LogUtils;
|
||||
import net.momirealms.customfishing.compatibility.papi.PlaceholderManagerImpl;
|
||||
import net.momirealms.customfishing.util.ArmorStandUtils;
|
||||
import net.momirealms.customfishing.util.ClassUtils;
|
||||
import net.momirealms.customfishing.util.ConfigUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.entity.ExperienceOrb;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
@@ -73,20 +78,30 @@ public class ActionManagerImpl implements ActionManager {
|
||||
this.registerDelayedAction();
|
||||
this.registerConditionalAction();
|
||||
this.registerPriorityAction();
|
||||
this.registerLevelAction();
|
||||
this.registerHologramAction();
|
||||
this.registerFakeItemAction();
|
||||
}
|
||||
|
||||
public void load() {
|
||||
this.loadExpansions();
|
||||
this.loadGlobalEventActions();
|
||||
}
|
||||
|
||||
public void unload() {
|
||||
|
||||
GlobalSettings.unload();
|
||||
}
|
||||
|
||||
public void disable() {
|
||||
unload();
|
||||
this.actionBuilderMap.clear();
|
||||
}
|
||||
|
||||
private void loadGlobalEventActions() {
|
||||
YamlConfiguration config = plugin.getConfig("config.yml");
|
||||
GlobalSettings.load(config.getConfigurationSection("mechanics.global-events"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean registerAction(String type, ActionFactory actionFactory) {
|
||||
if (this.actionBuilderMap.containsKey(type)) return false;
|
||||
@@ -104,6 +119,21 @@ public class ActionManagerImpl implements ActionManager {
|
||||
return getActionBuilder(section.getString("type")).build(section.get("value"), section.getDouble("chance", 1d));
|
||||
}
|
||||
|
||||
@Override
|
||||
public HashMap<ActionTrigger, Action[]> getActionMap(ConfigurationSection section) {
|
||||
HashMap<ActionTrigger, Action[]> actionMap = new HashMap<>();
|
||||
if (section == null) return actionMap;
|
||||
for (Map.Entry<String, Object> entry : section.getValues(false).entrySet()) {
|
||||
if (entry.getValue() instanceof ConfigurationSection innerSection) {
|
||||
actionMap.put(
|
||||
ActionTrigger.valueOf(entry.getKey().toUpperCase(Locale.ENGLISH)),
|
||||
getActions(innerSection)
|
||||
);
|
||||
}
|
||||
}
|
||||
return actionMap;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Action[] getActions(ConfigurationSection section) {
|
||||
@@ -247,6 +277,62 @@ public class ActionManagerImpl implements ActionManager {
|
||||
});
|
||||
}
|
||||
|
||||
private void registerHologramAction() {
|
||||
registerAction("hologram", (args, chance) -> {
|
||||
if (args instanceof ConfigurationSection section) {
|
||||
String text = section.getString("text", "");
|
||||
int duration = section.getInt("duration", 20);
|
||||
boolean position = section.getString("position", "hook").equals("hook");
|
||||
double x = section.getDouble("x");
|
||||
double y = section.getDouble("y");
|
||||
double z = section.getDouble("z");
|
||||
return condition -> {
|
||||
if (Math.random() > chance) return;
|
||||
Player player = condition.getPlayer();
|
||||
Location location = position ? condition.getLocation() : player.getLocation();
|
||||
ArmorStandUtils.sendHologram(
|
||||
condition.getPlayer(),
|
||||
location.clone().add(x, y, z),
|
||||
AdventureManagerImpl.getInstance().getComponentFromMiniMessage(
|
||||
PlaceholderManagerImpl.getInstance().parse(player, text, condition.getArgs())
|
||||
),
|
||||
duration
|
||||
);
|
||||
};
|
||||
} else {
|
||||
LogUtils.warn("Illegal value format found at action: hologram");
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void registerFakeItemAction() {
|
||||
registerAction("fake-item", (args, chance) -> {
|
||||
if (args instanceof ConfigurationSection section) {
|
||||
String[] itemSplit = section.getString("item", "").split(":", 2);
|
||||
int duration = section.getInt("duration", 20);
|
||||
boolean position = section.getString("position", "hook").equals("hook");
|
||||
double x = section.getDouble("x");
|
||||
double y = section.getDouble("y");
|
||||
double z = section.getDouble("z");
|
||||
return condition -> {
|
||||
if (Math.random() > chance) return;
|
||||
Player player = condition.getPlayer();
|
||||
Location location = position ? condition.getLocation() : player.getLocation();
|
||||
ArmorStandUtils.sendFakeItem(
|
||||
condition.getPlayer(),
|
||||
location.clone().add(x, y, z),
|
||||
plugin.getItemManager().build(player, itemSplit[0], itemSplit[1], condition.getArgs()),
|
||||
duration
|
||||
);
|
||||
};
|
||||
} else {
|
||||
LogUtils.warn("Illegal value format found at action: hologram");
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void registerChainAction() {
|
||||
registerAction("chain", (args, chance) -> {
|
||||
List<Action> actions = new ArrayList<>();
|
||||
@@ -357,6 +443,17 @@ public class ActionManagerImpl implements ActionManager {
|
||||
});
|
||||
}
|
||||
|
||||
private void registerLevelAction() {
|
||||
registerAction("level", (args, chance) -> {
|
||||
int level = (int) args;
|
||||
return condition -> {
|
||||
if (Math.random() > chance) return;
|
||||
Player player = condition.getPlayer();
|
||||
player.setLevel(Math.max(0, player.getLevel() + level));
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
@SuppressWarnings("all")
|
||||
private void registerSoundAction() {
|
||||
registerAction("sound", (args, chance) -> {
|
||||
@@ -452,6 +549,7 @@ public class ActionManagerImpl implements ActionManager {
|
||||
});
|
||||
}
|
||||
|
||||
@SuppressWarnings("ResultOfMethodCallIgnored")
|
||||
private void loadExpansions() {
|
||||
File expansionFolder = new File(plugin.getDataFolder(), EXPANSION_FOLDER);
|
||||
if (!expansionFolder.exists())
|
||||
|
||||
@@ -82,9 +82,10 @@ public class Competition implements FishingCompetition {
|
||||
this.actionBarManager.load();
|
||||
}
|
||||
|
||||
|
||||
Action[] actions = config.getStartActions();
|
||||
if (actions != null) {
|
||||
Condition condition = new Condition();
|
||||
Condition condition = new Condition(null, null, new HashMap<>());
|
||||
for (Action action : actions) {
|
||||
action.trigger(condition);
|
||||
}
|
||||
@@ -171,7 +172,7 @@ public class Competition implements FishingCompetition {
|
||||
// do end actions
|
||||
Action[] actions = config.getEndActions();
|
||||
if (actions != null) {
|
||||
Condition condition = new Condition(new HashMap<>(publicPlaceholders));
|
||||
Condition condition = new Condition(null, null, new HashMap<>(publicPlaceholders));
|
||||
for (Action action : actions) {
|
||||
action.trigger(condition);
|
||||
}
|
||||
|
||||
@@ -108,6 +108,7 @@ public class EffectManagerImpl implements EffectManager {
|
||||
.key(key)
|
||||
.requirements(plugin.getRequirementManager().getRequirements(section.getConfigurationSection("requirements"), true))
|
||||
.effect(getEffectFromSection(section.getConfigurationSection("effects")))
|
||||
.actionMap(plugin.getActionManager().getActionMap(section.getConfigurationSection("events")))
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
@@ -26,13 +26,13 @@ import net.momirealms.customfishing.api.event.LavaFishingEvent;
|
||||
import net.momirealms.customfishing.api.event.RodCastEvent;
|
||||
import net.momirealms.customfishing.api.manager.FishingManager;
|
||||
import net.momirealms.customfishing.api.manager.RequirementManager;
|
||||
import net.momirealms.customfishing.api.mechanic.GlobalSettings;
|
||||
import net.momirealms.customfishing.api.mechanic.TempFishingState;
|
||||
import net.momirealms.customfishing.api.mechanic.action.Action;
|
||||
import net.momirealms.customfishing.api.mechanic.action.ActionTrigger;
|
||||
import net.momirealms.customfishing.api.mechanic.competition.FishingCompetition;
|
||||
import net.momirealms.customfishing.api.mechanic.condition.Condition;
|
||||
import net.momirealms.customfishing.api.mechanic.condition.FishingPreparation;
|
||||
import net.momirealms.customfishing.api.mechanic.effect.Effect;
|
||||
import net.momirealms.customfishing.api.mechanic.effect.EffectCarrier;
|
||||
import net.momirealms.customfishing.api.mechanic.game.GameConfig;
|
||||
import net.momirealms.customfishing.api.mechanic.game.GameInstance;
|
||||
import net.momirealms.customfishing.api.mechanic.game.GameSettings;
|
||||
@@ -41,7 +41,6 @@ import net.momirealms.customfishing.api.mechanic.loot.Loot;
|
||||
import net.momirealms.customfishing.api.mechanic.loot.Modifier;
|
||||
import net.momirealms.customfishing.api.util.LogUtils;
|
||||
import net.momirealms.customfishing.api.util.WeightUtils;
|
||||
import net.momirealms.customfishing.mechanic.loot.LootManagerImpl;
|
||||
import net.momirealms.customfishing.mechanic.requirement.RequirementManagerImpl;
|
||||
import net.momirealms.customfishing.setting.Config;
|
||||
import org.bukkit.Bukkit;
|
||||
@@ -56,12 +55,10 @@ import org.bukkit.event.inventory.InventoryPickupItemEvent;
|
||||
import org.bukkit.event.player.*;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class FishingManagerImpl implements Listener, FishingManager {
|
||||
@@ -202,6 +199,19 @@ public class FishingManagerImpl implements Listener, FishingManager {
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onConsumeItem(PlayerItemConsumeEvent event) {
|
||||
if (event.isCancelled()) return;
|
||||
ItemStack itemStack = event.getItem();
|
||||
String id = plugin.getItemManager().getAnyItemID(itemStack);
|
||||
Loot loot = plugin.getLootManager().getLoot(id);
|
||||
if (loot != null) {
|
||||
Condition condition = new Condition(event.getPlayer());
|
||||
GlobalSettings.triggerLootActions(ActionTrigger.CONSUME, condition);
|
||||
loot.triggerActions(ActionTrigger.CONSUME, condition);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeHook(UUID uuid) {
|
||||
FishHook hook = hookCacheMap.remove(uuid);
|
||||
@@ -248,16 +258,11 @@ public class FishingManagerImpl implements Listener, FishingManager {
|
||||
fishingPreparation.mergeEffect(initialEffect);
|
||||
|
||||
// Apply enchants
|
||||
for (String enchant : plugin.getIntegrationManager().getEnchantments(fishingPreparation.getRodItemStack())) {
|
||||
EffectCarrier enchantEffect = plugin.getEffectManager().getEffect("enchant", enchant);
|
||||
if (enchantEffect != null && enchantEffect.isConditionMet(fishingPreparation)) {
|
||||
initialEffect.merge(enchantEffect.getEffect());
|
||||
}
|
||||
}
|
||||
|
||||
//TODO Apply totem effects
|
||||
|
||||
// Call custom event
|
||||
RodCastEvent rodCastEvent = new RodCastEvent(event, initialEffect);
|
||||
RodCastEvent rodCastEvent = new RodCastEvent(event, fishingPreparation, initialEffect);
|
||||
Bukkit.getPluginManager().callEvent(rodCastEvent);
|
||||
if (rodCastEvent.isCancelled()) {
|
||||
return;
|
||||
@@ -271,15 +276,15 @@ public class FishingManagerImpl implements Listener, FishingManager {
|
||||
// Reduce amount & Send animation
|
||||
var baitItem = fishingPreparation.getBaitItemStack();
|
||||
if (baitItem != null) {
|
||||
if (Config.enableBaitAnimation) {
|
||||
ItemStack cloned = baitItem.clone();
|
||||
cloned.setAmount(1);
|
||||
new BaitAnimationTask(plugin, player, fishHook, cloned);
|
||||
}
|
||||
ItemStack cloned = baitItem.clone();
|
||||
cloned.setAmount(1);
|
||||
new BaitAnimationTask(plugin, player, fishHook, cloned);
|
||||
baitItem.setAmount(baitItem.getAmount() - 1);
|
||||
}
|
||||
// Arrange hook check task
|
||||
this.hookCheckMap.put(player.getUniqueId(), new HookCheckTimerTask(this, fishHook, fishingPreparation, initialEffect));
|
||||
// trigger actions
|
||||
fishingPreparation.triggerActions(ActionTrigger.CAST);
|
||||
}
|
||||
|
||||
private void onCaughtEntity(PlayerFishEvent event) {
|
||||
@@ -343,6 +348,8 @@ public class FishingManagerImpl implements Listener, FishingManager {
|
||||
// put vanilla loot in map
|
||||
this.vanillaLootMap.put(uuid, item.getItemStack());
|
||||
}
|
||||
loot.triggerActions(ActionTrigger.HOOK, temp.getPreparation());
|
||||
temp.getPreparation().triggerActions(ActionTrigger.HOOK);
|
||||
if (!loot.disableGame()) {
|
||||
// start the game if the loot has a game
|
||||
event.setCancelled(true);
|
||||
@@ -379,12 +386,12 @@ public class FishingManagerImpl implements Listener, FishingManager {
|
||||
if (temp != null) {
|
||||
var loot = temp.getLoot();
|
||||
|
||||
Action[] actions = loot.getActions(ActionTrigger.HOOK);
|
||||
if (actions != null)
|
||||
for (Action action : actions)
|
||||
action.trigger(temp.getPreparation());
|
||||
loot.triggerActions(ActionTrigger.BITE, temp.getPreparation());
|
||||
temp.getPreparation().triggerActions(ActionTrigger.BITE);
|
||||
|
||||
if (loot.instanceGame() && !loot.disableGame()) {
|
||||
loot.triggerActions(ActionTrigger.HOOK, temp.getPreparation());
|
||||
temp.getPreparation().triggerActions(ActionTrigger.HOOK);
|
||||
startFishingGame(player, loot, temp.getEffect());
|
||||
}
|
||||
}
|
||||
@@ -414,9 +421,12 @@ public class FishingManagerImpl implements Listener, FishingManager {
|
||||
|
||||
var temp = this.tempFishingStateMap.get(uuid);
|
||||
if (temp != null ) {
|
||||
if (!temp.getLoot().disableGame()) {
|
||||
Loot loot = temp.getLoot();
|
||||
loot.triggerActions(ActionTrigger.HOOK, temp.getPreparation());
|
||||
temp.getPreparation().triggerActions(ActionTrigger.HOOK);
|
||||
if (!loot.disableGame()) {
|
||||
event.setCancelled(true);
|
||||
startFishingGame(player, temp.getLoot(), temp.getEffect());
|
||||
startFishingGame(player, loot, temp.getEffect());
|
||||
} else {
|
||||
success(temp, event.getHook());
|
||||
}
|
||||
@@ -454,7 +464,15 @@ public class FishingManagerImpl implements Listener, FishingManager {
|
||||
|
||||
gamingPlayer.cancel();
|
||||
gamingPlayerMap.remove(uuid);
|
||||
plugin.getScheduler().runTaskSync(fishHook::remove, fishHook.getLocation());
|
||||
plugin.getScheduler().runTaskSync(() -> {
|
||||
fishHook.remove();
|
||||
ItemStack rod = tempFishingState.getPreparation().getRodItemStack();
|
||||
PlayerItemDamageEvent damageEvent = new PlayerItemDamageEvent(player, rod, 1);
|
||||
Bukkit.getPluginManager().callEvent(damageEvent);
|
||||
if (damageEvent.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
}, fishHook.getLocation());
|
||||
}
|
||||
|
||||
public void fail(TempFishingState state, FishHook hook) {
|
||||
@@ -482,15 +500,10 @@ public class FishingManagerImpl implements Listener, FishingManager {
|
||||
return;
|
||||
}
|
||||
|
||||
Action[] globalActions = LootManagerImpl.GlobalSetting.globalLootProperties.getActions(ActionTrigger.FAILURE);
|
||||
if (globalActions != null)
|
||||
for (Action action : globalActions)
|
||||
action.trigger(fishingPreparation);
|
||||
GlobalSettings.triggerLootActions(ActionTrigger.FAILURE, fishingPreparation);
|
||||
loot.triggerActions(ActionTrigger.FAILURE, fishingPreparation);
|
||||
fishingPreparation.triggerActions(ActionTrigger.FAILURE);
|
||||
|
||||
Action[] actions = loot.getActions(ActionTrigger.FAILURE);
|
||||
if (actions != null)
|
||||
for (Action action : actions)
|
||||
action.trigger(fishingPreparation);
|
||||
}, hook.getLocation());
|
||||
}
|
||||
|
||||
@@ -579,28 +592,35 @@ public class FishingManagerImpl implements Listener, FishingManager {
|
||||
fishingPreparation.insertArg("{score}","-1");
|
||||
}
|
||||
|
||||
Action[] globalActions = LootManagerImpl.GlobalSetting.globalLootProperties.getActions(ActionTrigger.SUCCESS);
|
||||
if (globalActions != null)
|
||||
for (Action action : globalActions)
|
||||
action.trigger(fishingPreparation);
|
||||
|
||||
Action[] actions = loot.getActions(ActionTrigger.SUCCESS);
|
||||
if (actions != null)
|
||||
for (Action action : actions)
|
||||
action.trigger(fishingPreparation);
|
||||
// events and actions
|
||||
GlobalSettings.triggerLootActions(ActionTrigger.SUCCESS, fishingPreparation);
|
||||
loot.triggerActions(ActionTrigger.SUCCESS, fishingPreparation);
|
||||
fishingPreparation.triggerActions(ActionTrigger.SUCCESS);
|
||||
|
||||
player.setStatistic(
|
||||
Statistic.FISH_CAUGHT,
|
||||
player.getStatistic(Statistic.FISH_CAUGHT) + 1
|
||||
);
|
||||
|
||||
if (!loot.disableStats())
|
||||
Optional.ofNullable(
|
||||
plugin.getStatisticsManager()
|
||||
.getStatistics(player.getUniqueId())
|
||||
).ifPresent(it -> it.addLootAmount(loot, fishingPreparation, 1));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Loot getNextLoot(Effect initialEffect, FishingPreparation fishingPreparation) {
|
||||
HashMap<String, Double> lootWithWeight = plugin.getRequirementManager().getLootWithWeight(fishingPreparation);
|
||||
@Override
|
||||
public Collection<String> getPossibleLootKeys (FishingPreparation fishingPreparation) {
|
||||
return plugin.getRequirementManager().getLootWithWeight(fishingPreparation).keySet();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Map<String, Double> getPossibleLootKeysWithWeight(Effect initialEffect, FishingPreparation fishingPreparation) {
|
||||
Map<String, Double> lootWithWeight = plugin.getRequirementManager().getLootWithWeight(fishingPreparation);
|
||||
if (lootWithWeight.size() == 0) {
|
||||
LogUtils.warn(String.format("No Loot found at %s for Player %s!", fishingPreparation.getPlayer().getLocation(), fishingPreparation.getPlayer().getName()));
|
||||
return null;
|
||||
return new HashMap<>();
|
||||
}
|
||||
|
||||
Player player = fishingPreparation.getPlayer();
|
||||
@@ -608,8 +628,13 @@ public class FishingManagerImpl implements Listener, FishingManager {
|
||||
double previous = lootWithWeight.getOrDefault(pair.left(), 0d);
|
||||
lootWithWeight.put(pair.left(), pair.right().modify(player, previous));
|
||||
}
|
||||
return lootWithWeight;
|
||||
}
|
||||
|
||||
String key = WeightUtils.getRandom(lootWithWeight);
|
||||
@Override
|
||||
@Nullable
|
||||
public Loot getNextLoot(Effect initialEffect, FishingPreparation fishingPreparation) {
|
||||
String key = WeightUtils.getRandom(getPossibleLootKeysWithWeight(initialEffect, fishingPreparation));
|
||||
Loot loot = plugin.getLootManager().getLoot(key);
|
||||
if (loot == null) {
|
||||
LogUtils.warn(String.format("Loot %s doesn't exist!", key));
|
||||
|
||||
@@ -21,14 +21,15 @@ import net.kyori.adventure.key.Key;
|
||||
import net.kyori.adventure.sound.Sound;
|
||||
import net.momirealms.customfishing.adventure.AdventureManagerImpl;
|
||||
import net.momirealms.customfishing.api.CustomFishingPlugin;
|
||||
import net.momirealms.customfishing.api.event.FishHookLandEvent;
|
||||
import net.momirealms.customfishing.api.event.LavaFishingEvent;
|
||||
import net.momirealms.customfishing.api.mechanic.TempFishingState;
|
||||
import net.momirealms.customfishing.api.mechanic.action.ActionTrigger;
|
||||
import net.momirealms.customfishing.api.mechanic.condition.FishingPreparation;
|
||||
import net.momirealms.customfishing.api.mechanic.effect.Effect;
|
||||
import net.momirealms.customfishing.api.mechanic.loot.Loot;
|
||||
import net.momirealms.customfishing.api.scheduler.CancellableTask;
|
||||
import net.momirealms.customfishing.setting.Config;
|
||||
import net.momirealms.customfishing.util.ArmorStandUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
@@ -59,6 +60,7 @@ public class HookCheckTimerTask implements Runnable {
|
||||
private boolean reserve;
|
||||
private int jumpTimer;
|
||||
private Entity hookedEntity;
|
||||
private Loot loot;
|
||||
|
||||
public HookCheckTimerTask(
|
||||
FishingManagerImpl manager,
|
||||
@@ -94,14 +96,11 @@ public class HookCheckTimerTask implements Runnable {
|
||||
return;
|
||||
}
|
||||
if (firstTime) {
|
||||
this.fishingPreparation.insertArg("in-lava", "true");
|
||||
if (Config.enableSplashAnimation)
|
||||
ArmorStandUtils.sendAnimationToPlayer(
|
||||
fishingPreparation.getPlayer(),
|
||||
fishHook.getLocation(),
|
||||
CustomFishingPlugin.get().getItemManager().build(null, "util", Config.lavaSplashItem),
|
||||
Config.splashAnimationTime
|
||||
);
|
||||
this.fishingPreparation.setLocation(fishHook.getLocation());
|
||||
this.fishingPreparation.insertArg("{lava}", "true");
|
||||
this.fishingPreparation.triggerActions(ActionTrigger.LAND);
|
||||
FishHookLandEvent event = new FishHookLandEvent(fishingPreparation.getPlayer(), FishHookLandEvent.Target.LAVA);
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
firstTime = false;
|
||||
this.setTempState();
|
||||
}
|
||||
@@ -127,16 +126,13 @@ public class HookCheckTimerTask implements Runnable {
|
||||
return;
|
||||
}
|
||||
if (fishHook.isInWater()) {
|
||||
this.fishingPreparation.setLocation(fishHook.getLocation());
|
||||
this.fishingPreparation.insertArg("{lava}", "false");
|
||||
this.fishingPreparation.triggerActions(ActionTrigger.LAND);
|
||||
FishHookLandEvent event = new FishHookLandEvent(fishingPreparation.getPlayer(), FishHookLandEvent.Target.WATER);
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
// if the hook is in water
|
||||
// then cancel the task
|
||||
this.fishingPreparation.insertArg("in-lava", "false");
|
||||
if (Config.enableSplashAnimation)
|
||||
ArmorStandUtils.sendAnimationToPlayer(
|
||||
fishingPreparation.getPlayer(),
|
||||
fishHook.getLocation(),
|
||||
CustomFishingPlugin.get().getItemManager().build(null, "util", Config.waterSplashItem),
|
||||
Config.splashAnimationTime
|
||||
);
|
||||
this.destroy();
|
||||
this.setTempState();
|
||||
return;
|
||||
@@ -161,6 +157,7 @@ public class HookCheckTimerTask implements Runnable {
|
||||
Loot nextLoot = manager.getNextLoot(initialEffect, fishingPreparation);
|
||||
if (nextLoot == null)
|
||||
return;
|
||||
this.loot = nextLoot;
|
||||
fishingPreparation.insertArg("{nick}", nextLoot.getNick());
|
||||
fishingPreparation.insertArg("{loot}", nextLoot.getID());
|
||||
CustomFishingPlugin.get().getScheduler().runTaskAsync(() -> manager.setTempFishingState(fishingPreparation.getPlayer(), new TempFishingState(
|
||||
@@ -198,6 +195,9 @@ public class HookCheckTimerTask implements Runnable {
|
||||
return;
|
||||
}
|
||||
|
||||
this.loot.triggerActions(ActionTrigger.BITE, fishingPreparation);
|
||||
this.fishingPreparation.triggerActions(ActionTrigger.BITE);
|
||||
|
||||
this.fishHooked = true;
|
||||
this.removeTempEntity();
|
||||
|
||||
|
||||
@@ -104,6 +104,7 @@ public class GameManagerImpl implements GameManager {
|
||||
@Override
|
||||
@Nullable
|
||||
public GameConfig getGameConfig(String key) {
|
||||
if (key == null) return null;
|
||||
return gameConfigMap.get(key);
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,6 @@ package net.momirealms.customfishing.mechanic.loot;
|
||||
import net.momirealms.customfishing.api.CustomFishingPlugin;
|
||||
import net.momirealms.customfishing.api.manager.LootManager;
|
||||
import net.momirealms.customfishing.api.mechanic.action.Action;
|
||||
import net.momirealms.customfishing.api.mechanic.action.ActionTrigger;
|
||||
import net.momirealms.customfishing.api.mechanic.loot.CFLoot;
|
||||
import net.momirealms.customfishing.api.mechanic.loot.Loot;
|
||||
import net.momirealms.customfishing.api.mechanic.loot.LootType;
|
||||
@@ -40,16 +39,6 @@ public class LootManagerImpl implements LootManager {
|
||||
private final HashMap<String, Loot> lootMap;
|
||||
private final HashMap<String, List<String>> lootGroupMap;
|
||||
|
||||
public static class GlobalSetting {
|
||||
public static CFLoot globalLootProperties;
|
||||
public static boolean disableStats;
|
||||
public static boolean disableGames;
|
||||
public static boolean instantGame;
|
||||
public static boolean showInFinder;
|
||||
public static String gameGroup;
|
||||
public static String[] lootGroup;
|
||||
}
|
||||
|
||||
public LootManagerImpl(CustomFishingPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
this.lootMap = new HashMap<>();
|
||||
@@ -57,7 +46,6 @@ public class LootManagerImpl implements LootManager {
|
||||
}
|
||||
|
||||
public void load() {
|
||||
this.loadGlobalLootProperties();
|
||||
this.loadLootsFromPluginFolder();
|
||||
}
|
||||
|
||||
@@ -95,11 +83,6 @@ public class LootManagerImpl implements LootManager {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Loot getGlobalLootProperties() {
|
||||
return GlobalSetting.globalLootProperties;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public List<String> getLootGroup(String key) {
|
||||
@@ -112,21 +95,6 @@ public class LootManagerImpl implements LootManager {
|
||||
return lootMap.get(key);
|
||||
}
|
||||
|
||||
private void loadGlobalLootProperties() {
|
||||
YamlConfiguration config = plugin.getConfig("config.yml");
|
||||
GlobalSetting.globalLootProperties = getSingleSectionItem(
|
||||
Objects.requireNonNull(config.getConfigurationSection("mechanics.global-loot-properties")),
|
||||
"GLOBAL",
|
||||
"global"
|
||||
);
|
||||
GlobalSetting.disableStats = GlobalSetting.globalLootProperties.disableStats();
|
||||
GlobalSetting.disableGames = GlobalSetting.globalLootProperties.disableGame();
|
||||
GlobalSetting.instantGame = GlobalSetting.globalLootProperties.instanceGame();
|
||||
GlobalSetting.showInFinder = GlobalSetting.globalLootProperties.showInFinder();
|
||||
GlobalSetting.lootGroup = GlobalSetting.globalLootProperties.getLootGroup();
|
||||
GlobalSetting.gameGroup = GlobalSetting.globalLootProperties.getGameConfigKey();
|
||||
}
|
||||
|
||||
private void loadSingleFile(File file, String namespace) {
|
||||
YamlConfiguration yaml = YamlConfiguration.loadConfiguration(file);
|
||||
for (Map.Entry<String, Object> entry : yaml.getValues(false).entrySet()) {
|
||||
@@ -154,33 +122,18 @@ public class LootManagerImpl implements LootManager {
|
||||
|
||||
private CFLoot getSingleSectionItem(ConfigurationSection section, String namespace, String key) {
|
||||
return new CFLoot.Builder(key, LootType.valueOf(namespace.toUpperCase(Locale.ENGLISH)))
|
||||
.disableStats(section.getBoolean("disable-stat", GlobalSetting.disableStats))
|
||||
.disableGames(section.getBoolean("disable-game", GlobalSetting.disableGames))
|
||||
.instantGame(section.getBoolean("instant-game", GlobalSetting.instantGame))
|
||||
.showInFinder(section.getBoolean("show-in-fishfinder", GlobalSetting.showInFinder))
|
||||
.gameConfig(section.getString("game-group", GlobalSetting.gameGroup))
|
||||
.lootGroup(ConfigUtils.stringListArgs(Optional.ofNullable(section.get("loot-group")).orElse(GlobalSetting.lootGroup)).toArray(new String[0]))
|
||||
.disableStats(section.getBoolean("disable-stat", false))
|
||||
.disableGames(section.getBoolean("disable-game", false))
|
||||
.instantGame(section.getBoolean("instant-game", false))
|
||||
.showInFinder(section.getBoolean("show-in-fishfinder", true))
|
||||
.gameConfig(section.getString("game-group"))
|
||||
.lootGroup(ConfigUtils.stringListArgs(section.get("loot-group")).toArray(new String[0]))
|
||||
.nick(section.getString("nick", section.getString("display.name", key)))
|
||||
.addActions(getActionMap(section.getConfigurationSection("events")))
|
||||
.addActions(plugin.getActionManager().getActionMap(section.getConfigurationSection("events")))
|
||||
.addTimesActions(getTimesActionMap(section.getConfigurationSection("events.success-times")))
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
private HashMap<ActionTrigger, Action[]> getActionMap(ConfigurationSection section) {
|
||||
HashMap<ActionTrigger, Action[]> actionMap = new HashMap<>();
|
||||
if (section == null) return actionMap;
|
||||
for (Map.Entry<String, Object> entry : section.getValues(false).entrySet()) {
|
||||
if (entry.getValue() instanceof ConfigurationSection innerSection) {
|
||||
actionMap.put(
|
||||
ActionTrigger.valueOf(entry.getKey().toUpperCase(Locale.ENGLISH)),
|
||||
plugin.getActionManager().getActions(innerSection)
|
||||
);
|
||||
}
|
||||
}
|
||||
return actionMap;
|
||||
}
|
||||
|
||||
private HashMap<Integer, Action[]> getTimesActionMap(ConfigurationSection section) {
|
||||
HashMap<Integer, Action[]> actionMap = new HashMap<>();
|
||||
if (section == null) return actionMap;
|
||||
|
||||
@@ -117,6 +117,8 @@ public class RequirementManagerImpl implements RequirementManager {
|
||||
this.registerCompareRequirement();
|
||||
this.registerAndRequirement();
|
||||
this.registerOrRequirement();
|
||||
this.registerLevelRequirement();
|
||||
this.registerRandomRequirement();
|
||||
}
|
||||
|
||||
public ConditionalLoots getConditionalLoots(ConfigurationSection section) {
|
||||
@@ -302,7 +304,7 @@ public class RequirementManagerImpl implements RequirementManager {
|
||||
registerRequirement("in-lava", (args, actions, advanced) -> {
|
||||
boolean inLava = (boolean) args;
|
||||
return condition -> {
|
||||
String current = condition.getArgs().get("in-lava");
|
||||
String current = condition.getArgs().get("{lava}");
|
||||
if (current.equals(String.valueOf(inLava)))
|
||||
return true;
|
||||
if (advanced) triggerActions(actions, condition);
|
||||
@@ -311,6 +313,31 @@ public class RequirementManagerImpl implements RequirementManager {
|
||||
});
|
||||
}
|
||||
|
||||
private void registerLevelRequirement() {
|
||||
registerRequirement("level", (args, actions, advanced) -> {
|
||||
int level = (int) args;
|
||||
return condition -> {
|
||||
int current = condition.getPlayer().getLevel();
|
||||
if (current >= level)
|
||||
return true;
|
||||
if (advanced) triggerActions(actions, condition);
|
||||
return false;
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
private void registerRandomRequirement() {
|
||||
registerRequirement("random", (args, actions, advanced) -> {
|
||||
double random = ConfigUtils.getDoubleValue(args);
|
||||
return condition -> {
|
||||
if (Math.random() < random)
|
||||
return true;
|
||||
if (advanced) triggerActions(actions, condition);
|
||||
return false;
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
private void registerBiomeRequirement() {
|
||||
registerRequirement("biome", (args, actions, advanced) -> {
|
||||
HashSet<String> biomes = new HashSet<>(ConfigUtils.stringListArgs(args));
|
||||
|
||||
@@ -68,13 +68,6 @@ public class Config {
|
||||
public static String bagTitle;
|
||||
public static List<Material> bagWhiteListItems;
|
||||
|
||||
// Animation
|
||||
public static boolean enableBaitAnimation;
|
||||
public static boolean enableSplashAnimation;
|
||||
public static int splashAnimationTime;
|
||||
public static String lavaSplashItem;
|
||||
public static String waterSplashItem;
|
||||
|
||||
// Lava fishing
|
||||
public static int lavaMinTime;
|
||||
public static int lavaMaxTime;
|
||||
@@ -88,9 +81,10 @@ public class Config {
|
||||
public static boolean redisRanking;
|
||||
public static int placeholderLimit;
|
||||
|
||||
//
|
||||
// Data save interval
|
||||
public static int dataSaveInterval;
|
||||
|
||||
// Legacy color code support
|
||||
public static boolean legacyColorSupport;
|
||||
|
||||
public static void load() {
|
||||
@@ -108,7 +102,7 @@ public class Config {
|
||||
.builder()
|
||||
.setVersioning(new BasicVersioning("config-version"))
|
||||
.addIgnoredRoute(configVersion, "mechanics.mechanic-requirements", '.')
|
||||
.addIgnoredRoute(configVersion, "mechanics.global-loot-properties", '.')
|
||||
.addIgnoredRoute(configVersion, "mechanics.global-events", '.')
|
||||
.build()
|
||||
);
|
||||
loadSettings(CustomFishingPlugin.getInstance().getConfig("config.yml"));
|
||||
@@ -139,12 +133,6 @@ public class Config {
|
||||
lavaMinTime = config.getInt("mechanics.lava-fishing.min-wait-time", 100);
|
||||
lavaMaxTime = config.getInt("mechanics.lava-fishing.max-wait-time", 600);
|
||||
|
||||
enableSplashAnimation = config.getBoolean("mechanics.animation.splash.enable", true);
|
||||
enableBaitAnimation = config.getBoolean("mechanics.animation.bait.enable", true);
|
||||
waterSplashItem = config.getString("mechanics.animation.splash.water");
|
||||
lavaSplashItem = config.getString("mechanics.animation.splash.lava");
|
||||
splashAnimationTime = config.getInt("mechanics.animation.splash.duration");
|
||||
|
||||
vanillaMechanicIfNoLoot = config.getBoolean("mechanics.vanilla-mechanic-if-no-loot.enable", false);
|
||||
noLootActions = CustomFishingPlugin.get().getActionManager().getActions(config.getConfigurationSection("mechanics.vanilla-mechanic-if-no-loot.actions"));
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.events.PacketContainer;
|
||||
import com.comphenix.protocol.wrappers.*;
|
||||
import com.google.common.collect.Lists;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
||||
import net.momirealms.customfishing.CustomFishingPluginImpl;
|
||||
import net.momirealms.customfishing.api.CustomFishingPlugin;
|
||||
@@ -73,14 +73,14 @@ public class ArmorStandUtils {
|
||||
metaPacket.getDataValueCollectionModifier().write(0, wrappedDataValueList);
|
||||
}
|
||||
|
||||
public static PacketContainer getMetaPacket(int id, String text) {
|
||||
public static PacketContainer getMetaPacket(int id, Component component) {
|
||||
PacketContainer metaPacket = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA);
|
||||
metaPacket.getIntegers().write(0, id);
|
||||
if (CustomFishingPlugin.get().getVersionManager().isVersionNewerThan1_19_R2()) {
|
||||
WrappedDataWatcher wrappedDataWatcher = createDataWatcher(text);
|
||||
WrappedDataWatcher wrappedDataWatcher = createDataWatcher(component);
|
||||
setValueList(metaPacket, wrappedDataWatcher);
|
||||
} else {
|
||||
metaPacket.getWatchableCollectionModifier().write(0, createDataWatcher(text).getWatchableObjects());
|
||||
metaPacket.getWatchableCollectionModifier().write(0, createDataWatcher(component).getWatchableObjects());
|
||||
}
|
||||
return metaPacket;
|
||||
}
|
||||
@@ -95,11 +95,11 @@ public class ArmorStandUtils {
|
||||
return wrappedDataWatcher;
|
||||
}
|
||||
|
||||
public static WrappedDataWatcher createDataWatcher(String text) {
|
||||
public static WrappedDataWatcher createDataWatcher(Component component) {
|
||||
WrappedDataWatcher wrappedDataWatcher = new WrappedDataWatcher();
|
||||
WrappedDataWatcher.Serializer serializer1 = WrappedDataWatcher.Registry.get(Boolean.class);
|
||||
WrappedDataWatcher.Serializer serializer2 = WrappedDataWatcher.Registry.get(Byte.class);
|
||||
wrappedDataWatcher.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(2, WrappedDataWatcher.Registry.getChatComponentSerializer(true)), Optional.of(WrappedChatComponent.fromJson(GsonComponentSerializer.gson().serialize(MiniMessage.miniMessage().deserialize(text))).getHandle()));
|
||||
wrappedDataWatcher.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(2, WrappedDataWatcher.Registry.getChatComponentSerializer(true)), Optional.of(WrappedChatComponent.fromJson(GsonComponentSerializer.gson().serialize(component)).getHandle()));
|
||||
wrappedDataWatcher.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(3, serializer1), true);
|
||||
wrappedDataWatcher.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(15, serializer2), (byte) 0x01);
|
||||
byte flag = 0x20;
|
||||
@@ -116,11 +116,18 @@ public class ArmorStandUtils {
|
||||
return equipPacket;
|
||||
}
|
||||
|
||||
public static void sendAnimationToPlayer(Player player, Location location, ItemStack itemStack, int time) {
|
||||
public static void sendFakeItem(Player player, Location location, ItemStack itemStack, int time) {
|
||||
int id = new Random().nextInt(Integer.MAX_VALUE);
|
||||
CustomFishingPluginImpl.getProtocolManager().sendServerPacket(player, getSpawnPacket(id, location.clone().subtract(0,1,0)));
|
||||
CustomFishingPluginImpl.getProtocolManager().sendServerPacket(player, getMetaPacket(id));
|
||||
CustomFishingPluginImpl.getProtocolManager().sendServerPacket(player, getEquipPacket(id, itemStack));
|
||||
CustomFishingPlugin.get().getScheduler().runTaskAsyncLater(() -> CustomFishingPluginImpl.getProtocolManager().sendServerPacket(player, getDestroyPacket(id)), time * 50L, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
public static void sendHologram(Player player, Location location, Component component, int time) {
|
||||
int id = new Random().nextInt(Integer.MAX_VALUE);
|
||||
CustomFishingPluginImpl.getProtocolManager().sendServerPacket(player, getSpawnPacket(id, location.clone().subtract(0,1,0)));
|
||||
CustomFishingPluginImpl.getProtocolManager().sendServerPacket(player, getMetaPacket(id, component));
|
||||
CustomFishingPlugin.get().getScheduler().runTaskAsyncLater(() -> CustomFishingPluginImpl.getProtocolManager().sendServerPacket(player, getDestroyPacket(id)), time * 50L, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
}
|
||||
@@ -21,14 +21,10 @@ mechanics:
|
||||
value:
|
||||
- blacklist_world
|
||||
|
||||
# Global loot properties
|
||||
global-loot-properties:
|
||||
show-in-fishfinder: true
|
||||
disable-stat: false
|
||||
disable-game: false
|
||||
instant-game: false
|
||||
prevent-grabbing: false
|
||||
events:
|
||||
# global event settings
|
||||
global-events:
|
||||
bait: {}
|
||||
loot:
|
||||
success:
|
||||
title_action:
|
||||
type: random-title
|
||||
@@ -60,7 +56,37 @@ mechanics:
|
||||
stay: 30
|
||||
fade-out: 10
|
||||
chance: 1.0
|
||||
|
||||
rod:
|
||||
land:
|
||||
priority_action:
|
||||
type: priority
|
||||
value:
|
||||
priority_1:
|
||||
conditions:
|
||||
in-lava: true
|
||||
actions:
|
||||
fake_item_action:
|
||||
type: fake-item
|
||||
value:
|
||||
duration: 35
|
||||
position: hook
|
||||
item: util:lava_effect
|
||||
y: 0
|
||||
x: 0
|
||||
z: 0
|
||||
priority_2:
|
||||
conditions:
|
||||
in-lava: false
|
||||
actions:
|
||||
fake_item_action:
|
||||
type: fake-item
|
||||
value:
|
||||
duration: 35
|
||||
position: hook
|
||||
item: util:water_effect
|
||||
y: 0
|
||||
x: 0
|
||||
z: 0
|
||||
# Fishing bag is where players can store their baits, utils and rods (Fish optional)
|
||||
fishing-bag:
|
||||
# Enable
|
||||
@@ -79,16 +105,6 @@ mechanics:
|
||||
min-wait-time: 100
|
||||
max-wait-time: 600
|
||||
|
||||
# Animation settings
|
||||
animation:
|
||||
splash:
|
||||
enable: true
|
||||
water: water_effect
|
||||
lava: lava_effect
|
||||
duration: 25
|
||||
bait:
|
||||
enable: true
|
||||
|
||||
# Competition settings
|
||||
competition:
|
||||
# Use redis for cross server data synchronization
|
||||
|
||||
@@ -11,7 +11,7 @@ rubbish:
|
||||
disable-game: true
|
||||
instant-game: false
|
||||
prevent-grabbing: false
|
||||
action:
|
||||
events:
|
||||
success:
|
||||
mending:
|
||||
type: mending
|
||||
@@ -27,7 +27,7 @@ tuna_fish:
|
||||
- <gray>Tuna is a kind of healthy food.
|
||||
- '<white>size: {size}cm'
|
||||
custom-model-data: 50001
|
||||
action:
|
||||
events:
|
||||
success:
|
||||
action_mending:
|
||||
type: mending
|
||||
@@ -47,7 +47,7 @@ tuna_fish_silver_star:
|
||||
- <gray>Tuna is a kind of healthy food.
|
||||
- '<white>size: {size}cm'
|
||||
custom-model-data: 50002
|
||||
action:
|
||||
events:
|
||||
success:
|
||||
action_mending:
|
||||
type: mending
|
||||
@@ -67,7 +67,7 @@ tuna_fish_golden_star:
|
||||
- <gray>Tuna is a kind of healthy food.
|
||||
- '<white>size: {size}cm'
|
||||
custom-model-data: 50003
|
||||
action:
|
||||
events:
|
||||
success:
|
||||
action_mending:
|
||||
type: mending
|
||||
@@ -90,7 +90,7 @@ pike_fish:
|
||||
- <gray>water and inland freshwater lakes
|
||||
- '<white>size: {size}cm'
|
||||
custom-model-data: 50004
|
||||
action:
|
||||
events:
|
||||
success:
|
||||
action_mending:
|
||||
type: mending
|
||||
@@ -113,7 +113,7 @@ pike_fish_silver_star:
|
||||
- <gray>water and inland freshwater lakes
|
||||
- '<white>size: {size}cm'
|
||||
custom-model-data: 50005
|
||||
action:
|
||||
events:
|
||||
success:
|
||||
action_mending:
|
||||
type: mending
|
||||
@@ -136,7 +136,7 @@ pike_fish_golden_star:
|
||||
- <gray>water and inland freshwater lakes
|
||||
- '<white>size: {size}cm'
|
||||
custom-model-data: 50006
|
||||
action:
|
||||
events:
|
||||
success:
|
||||
action_mending:
|
||||
type: mending
|
||||
@@ -158,7 +158,7 @@ gold_fish:
|
||||
price:
|
||||
base: 70
|
||||
custom-model-data: 50007
|
||||
action:
|
||||
events:
|
||||
success:
|
||||
action_mending:
|
||||
type: mending
|
||||
@@ -177,7 +177,7 @@ gold_fish_silver_star:
|
||||
price:
|
||||
base: 80
|
||||
custom-model-data: 50008
|
||||
action:
|
||||
events:
|
||||
success:
|
||||
action_mending:
|
||||
type: mending
|
||||
@@ -196,7 +196,7 @@ gold_fish_golden_star:
|
||||
price:
|
||||
base: 100
|
||||
custom-model-data: 50009
|
||||
action:
|
||||
events:
|
||||
success:
|
||||
action_mending:
|
||||
type: mending
|
||||
@@ -212,7 +212,7 @@ perch_fish:
|
||||
- <gray>foraging at dusk and early morning
|
||||
- '<white>size: {size}cm'
|
||||
custom-model-data: 50010
|
||||
action:
|
||||
events:
|
||||
success:
|
||||
action_mending:
|
||||
type: mending
|
||||
@@ -233,7 +233,7 @@ perch_fish_silver_star:
|
||||
- <gray>foraging at dusk and early morning
|
||||
- '<white>size: {size}cm'
|
||||
custom-model-data: 50011
|
||||
action:
|
||||
events:
|
||||
success:
|
||||
action_mending:
|
||||
type: mending
|
||||
@@ -254,7 +254,7 @@ perch_fish_golden_star:
|
||||
- <gray>foraging at dusk and early morning
|
||||
- '<white>size: {size}cm'
|
||||
custom-model-data: 50012
|
||||
action:
|
||||
events:
|
||||
success:
|
||||
action_mending:
|
||||
type: mending
|
||||
@@ -275,7 +275,7 @@ mullet_fish:
|
||||
- <gray>to treat spleen and stomach weakness
|
||||
- '<white>size: {size}cm'
|
||||
custom-model-data: 50013
|
||||
action:
|
||||
events:
|
||||
success:
|
||||
action_mending:
|
||||
type: mending
|
||||
@@ -296,7 +296,7 @@ mullet_fish_silver_star:
|
||||
- <gray>to treat spleen and stomach weakness
|
||||
- '<white>size: {size}cm'
|
||||
custom-model-data: 50014
|
||||
action:
|
||||
events:
|
||||
success:
|
||||
action_mending:
|
||||
type: mending
|
||||
@@ -317,7 +317,7 @@ mullet_fish_golden_star:
|
||||
- <gray>to treat spleen and stomach weakness
|
||||
- '<white>size: {size}cm'
|
||||
custom-model-data: 50015
|
||||
action:
|
||||
events:
|
||||
success:
|
||||
action_mending:
|
||||
type: mending
|
||||
@@ -338,7 +338,7 @@ sardine_fish:
|
||||
- <gray>Therefore, sardine are also called "smart food"
|
||||
- '<white>size: {size}cm'
|
||||
custom-model-data: 50016
|
||||
action:
|
||||
events:
|
||||
success:
|
||||
action_mending:
|
||||
type: mending
|
||||
@@ -358,7 +358,7 @@ sardine_fish_silver_star:
|
||||
- <gray>Therefore, sardine are also called "smart food"
|
||||
- '<white>size: {size}cm'
|
||||
custom-model-data: 50017
|
||||
action:
|
||||
events:
|
||||
success:
|
||||
action_mending:
|
||||
type: mending
|
||||
@@ -378,7 +378,7 @@ sardine_fish_golden_star:
|
||||
- <gray>Therefore, sardine are also called "smart food"
|
||||
- '<white>size: {size}cm'
|
||||
custom-model-data: 50018
|
||||
action:
|
||||
events:
|
||||
success:
|
||||
action_mending:
|
||||
type: mending
|
||||
@@ -398,7 +398,7 @@ carp_fish:
|
||||
- <gray>One of the most common edible fish
|
||||
- '<white>size: {size}cm'
|
||||
custom-model-data: 50019
|
||||
action:
|
||||
events:
|
||||
success:
|
||||
action_mending:
|
||||
type: mending
|
||||
@@ -417,7 +417,7 @@ carp_fish_silver_star:
|
||||
- <gray>One of the most common edible fish
|
||||
- '<white>size: {size}cm'
|
||||
custom-model-data: 50020
|
||||
action:
|
||||
events:
|
||||
success:
|
||||
action_mending:
|
||||
type: mending
|
||||
@@ -436,7 +436,7 @@ carp_fish_golden_star:
|
||||
- <gray>One of the most common edible fish
|
||||
- '<white>size: {size}cm'
|
||||
custom-model-data: 50021
|
||||
action:
|
||||
events:
|
||||
success:
|
||||
action_mending:
|
||||
type: mending
|
||||
@@ -456,7 +456,7 @@ cat_fish:
|
||||
- <gray>sharp jaw teeth, short intestine and stomach
|
||||
- '<white>size: {size}cm'
|
||||
custom-model-data: 50022
|
||||
action:
|
||||
events:
|
||||
success:
|
||||
action_mending:
|
||||
type: mending
|
||||
@@ -476,7 +476,7 @@ cat_fish_silver_star:
|
||||
- <gray>sharp jaw teeth, short intestine and stomach
|
||||
- '<white>size: {size}cm'
|
||||
custom-model-data: 50023
|
||||
action:
|
||||
events:
|
||||
success:
|
||||
action_mending:
|
||||
type: mending
|
||||
@@ -496,7 +496,7 @@ cat_fish_golden_star:
|
||||
- <gray>sharp jaw teeth, short intestine and stomach
|
||||
- '<white>size: {size}cm'
|
||||
custom-model-data: 50024
|
||||
action:
|
||||
events:
|
||||
success:
|
||||
action_mending:
|
||||
type: mending
|
||||
@@ -517,7 +517,7 @@ octopus:
|
||||
- <gray>People often use pots to catch octopus
|
||||
- '<white>size: {size}cm'
|
||||
custom-model-data: 50025
|
||||
action:
|
||||
events:
|
||||
success:
|
||||
action_mending:
|
||||
type: mending
|
||||
@@ -537,7 +537,7 @@ octopus_silver_star:
|
||||
- <gray>People often use pots to catch octopus
|
||||
- '<white>size: {size}cm'
|
||||
custom-model-data: 50026
|
||||
action:
|
||||
events:
|
||||
success:
|
||||
action_mending:
|
||||
type: mending
|
||||
@@ -557,7 +557,7 @@ octopus_golden_star:
|
||||
- <gray>People often use pots to catch octopus
|
||||
- '<white>size: {size}cm'
|
||||
custom-model-data: 50027
|
||||
action:
|
||||
events:
|
||||
success:
|
||||
action_mending:
|
||||
type: mending
|
||||
@@ -577,7 +577,7 @@ sunfish:
|
||||
- <gray>It only has one huge head
|
||||
- '<white>size: {size}cm'
|
||||
custom-model-data: 50028
|
||||
action:
|
||||
events:
|
||||
success:
|
||||
action_mending:
|
||||
type: mending
|
||||
@@ -596,7 +596,7 @@ sunfish_silver_star:
|
||||
- <gray>It only has one huge head
|
||||
- '<white>size: {size}cm'
|
||||
custom-model-data: 50029
|
||||
action:
|
||||
events:
|
||||
success:
|
||||
action_mending:
|
||||
type: mending
|
||||
@@ -615,7 +615,7 @@ sunfish_golden_star:
|
||||
- <gray>It only has one huge head
|
||||
- '<white>size: {size}cm'
|
||||
custom-model-data: 50030
|
||||
action:
|
||||
events:
|
||||
success:
|
||||
action_mending:
|
||||
type: mending
|
||||
@@ -635,7 +635,7 @@ red_snapper_fish:
|
||||
- <gray>with a male as the "head of the family"
|
||||
- '<white>size: {size}cm'
|
||||
custom-model-data: 50031
|
||||
action:
|
||||
events:
|
||||
success:
|
||||
action_mending:
|
||||
type: mending
|
||||
@@ -656,7 +656,7 @@ red_snapper_fish_silver_star:
|
||||
- <gray>with a male as the "head of the family"
|
||||
- '<white>size: {size}cm'
|
||||
custom-model-data: 50032
|
||||
action:
|
||||
events:
|
||||
success:
|
||||
action_mending:
|
||||
type: mending
|
||||
@@ -677,7 +677,7 @@ red_snapper_fish_golden_star:
|
||||
- <gray>with a male as the "head of the family"
|
||||
- '<white>size: {size}cm'
|
||||
custom-model-data: 50033
|
||||
action:
|
||||
events:
|
||||
success:
|
||||
action_mending:
|
||||
type: mending
|
||||
@@ -697,7 +697,7 @@ salmon_void_fish:
|
||||
lore:
|
||||
- <gray>A fish from the hell
|
||||
custom-model-data: 50034
|
||||
action:
|
||||
events:
|
||||
success:
|
||||
action_mending:
|
||||
type: mending
|
||||
@@ -714,7 +714,7 @@ salmon_void_fish_silver_star:
|
||||
lore:
|
||||
- <gray>A fish from the hell
|
||||
custom-model-data: 50035
|
||||
action:
|
||||
events:
|
||||
success:
|
||||
action_mending:
|
||||
type: mending
|
||||
@@ -732,7 +732,7 @@ salmon_void_fish_golden_star:
|
||||
- <gray>A fish from the hell
|
||||
group: gold
|
||||
custom-model-data: 50036
|
||||
action:
|
||||
events:
|
||||
success:
|
||||
action_mending:
|
||||
type: mending
|
||||
@@ -751,7 +751,7 @@ woodskip_fish:
|
||||
- <gray>live in pools deep in the forest
|
||||
- '<white>size: {size}cm'
|
||||
custom-model-data: 50037
|
||||
action:
|
||||
events:
|
||||
success:
|
||||
action_mending:
|
||||
type: mending
|
||||
@@ -771,7 +771,7 @@ woodskip_fish_silver_star:
|
||||
- <gray>live in pools deep in the forest
|
||||
- '<white>size: {size}cm'
|
||||
custom-model-data: 50038
|
||||
action:
|
||||
events:
|
||||
success:
|
||||
action_mending:
|
||||
type: mending
|
||||
@@ -791,7 +791,7 @@ woodskip_fish_golden_star:
|
||||
- <gray>live in pools deep in the forest
|
||||
- '<white>size: {size}cm'
|
||||
custom-model-data: 50039
|
||||
action:
|
||||
events:
|
||||
success:
|
||||
action_mending:
|
||||
type: mending
|
||||
@@ -812,7 +812,7 @@ sturgeon_fish:
|
||||
- <gray>population. Females can live up to 150 years
|
||||
- '<white>size: {size}cm'
|
||||
custom-model-data: 50040
|
||||
action:
|
||||
events:
|
||||
success:
|
||||
action_mending:
|
||||
type: mending
|
||||
@@ -832,7 +832,7 @@ sturgeon_fish_silver_star:
|
||||
- <gray>population. Females can live up to 150 years
|
||||
- '<white>size: {size}cm'
|
||||
custom-model-data: 50041
|
||||
action:
|
||||
events:
|
||||
success:
|
||||
action_mending:
|
||||
type: mending
|
||||
@@ -852,7 +852,7 @@ sturgeon_fish_golden_star:
|
||||
- <gray>population. Females can live up to 150 years
|
||||
- '<white>size: {size}cm'
|
||||
custom-model-data: 50042
|
||||
action:
|
||||
events:
|
||||
success:
|
||||
action_mending:
|
||||
type: mending
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
######################################
|
||||
rainbow_1:
|
||||
game-type: accurate_click
|
||||
title: '<#B22222>RED!'
|
||||
title: '<#fd4036>RED!'
|
||||
subtitle:
|
||||
font: 'customfishing:default'
|
||||
bar: '뀋'
|
||||
@@ -24,7 +24,7 @@ rainbow_1:
|
||||
7: 0
|
||||
rainbow_2:
|
||||
game-type: accurate_click
|
||||
title: '<#FFA500>ORANGE!'
|
||||
title: '<#ffa449>ORANGE!'
|
||||
subtitle:
|
||||
font: 'customfishing:default'
|
||||
bar: '뀋'
|
||||
@@ -43,7 +43,7 @@ rainbow_2:
|
||||
7: 0
|
||||
rainbow_3:
|
||||
game-type: accurate_click
|
||||
title: '<#FFFF00>YELLOW!'
|
||||
title: '<#ffca4c>YELLOW!'
|
||||
subtitle:
|
||||
font: 'customfishing:default'
|
||||
bar: '뀋'
|
||||
@@ -62,7 +62,7 @@ rainbow_3:
|
||||
7: 0
|
||||
rainbow_4:
|
||||
game-type: accurate_click
|
||||
title: '<GREEN>GREEN!'
|
||||
title: '<#34f250>GREEN!'
|
||||
subtitle:
|
||||
font: 'customfishing:default'
|
||||
bar: '뀋'
|
||||
@@ -81,7 +81,7 @@ rainbow_4:
|
||||
7: 0
|
||||
rainbow_5:
|
||||
game-type: accurate_click
|
||||
title: '<#00FFFF>AQUA!'
|
||||
title: '<#34f2d5>AQUA!'
|
||||
subtitle:
|
||||
font: 'customfishing:default'
|
||||
bar: '뀋'
|
||||
@@ -100,7 +100,7 @@ rainbow_5:
|
||||
7: 0
|
||||
rainbow_6:
|
||||
game-type: accurate_click
|
||||
title: '<#1E90FF>BLUE!'
|
||||
title: '<#34f2d5>BLUE!'
|
||||
subtitle:
|
||||
font: 'customfishing:default'
|
||||
bar: '뀋'
|
||||
@@ -119,7 +119,7 @@ rainbow_6:
|
||||
7: 0
|
||||
rainbow_7:
|
||||
game-type: accurate_click
|
||||
title: '<#9400D3>PURPLE!'
|
||||
title: '<#c96cff>PURPLE!'
|
||||
subtitle:
|
||||
font: 'customfishing:default'
|
||||
bar: '뀋'
|
||||
@@ -583,10 +583,4 @@ tension_game:
|
||||
- '<font:customfishing:icons>뀖</font>'
|
||||
- '<font:customfishing:icons>뀗</font>'
|
||||
- '<font:customfishing:icons>뀘</font>'
|
||||
- '<font:customfishing:icons>뀙</font>'
|
||||
|
||||
######################################
|
||||
# Burst #
|
||||
# When the fish is hooked, you need #
|
||||
# to click quickly in limited time #
|
||||
######################################
|
||||
- '<font:customfishing:icons>뀙</font>'
|
||||
@@ -1,3 +1,9 @@
|
||||
# Vanilla fishing rod properties
|
||||
FISHING_ROD:
|
||||
tag: false
|
||||
material: fishing_rod
|
||||
|
||||
# Custom rods
|
||||
wooden_rod:
|
||||
material: fishing_rod
|
||||
display:
|
||||
|
||||
Reference in New Issue
Block a user