9
0
mirror of https://github.com/Xiao-MoMi/Custom-Fishing.git synced 2025-12-28 11:29:15 +00:00
This commit is contained in:
XiaoMoMi
2024-01-03 06:04:44 +08:00
parent 23fc9c33bd
commit da74c91f61
22 changed files with 365 additions and 139 deletions

View File

@@ -125,7 +125,7 @@ public class ItemCommand {
int amount = (int) args.getOrDefault("amount", 1);
ItemStack item = CustomFishingPlugin.get().getItemManager().build(player, namespace, id, new Condition(player).getArgs());
if (item != null) {
int actual = ItemUtils.giveCertainAmountOfItem(player, item, amount);
int actual = ItemUtils.putLootsToBag(player, item, amount);
AdventureManagerImpl.getInstance().sendMessageWithPrefix(player, CFLocale.MSG_Get_Item.replace("{item}", id).replace("{amount}", String.valueOf(actual)));
} else {
AdventureManagerImpl.getInstance().sendMessageWithPrefix(player, CFLocale.MSG_Item_Not_Exists);
@@ -151,7 +151,7 @@ public class ItemCommand {
assert players != null;
for (Player player : players) {
ItemStack item = CustomFishingPlugin.get().getItemManager().build(player, namespace, id, new Condition(player).getArgs());
int actual = ItemUtils.giveCertainAmountOfItem(player, item, amount);
int actual = ItemUtils.putLootsToBag(player, item, amount);
AdventureManagerImpl.getInstance().sendMessageWithPrefix(sender, CFLocale.MSG_Give_Item.replace("{item}", id).replace("{amount}", String.valueOf(actual)).replace("{player}", player.getName()));
}
} else {

View File

@@ -29,7 +29,6 @@ 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.condition.Condition;
import net.momirealms.customfishing.api.mechanic.loot.Loot;
import net.momirealms.customfishing.api.mechanic.requirement.Requirement;
import net.momirealms.customfishing.api.scheduler.CancellableTask;
@@ -296,20 +295,6 @@ public class ActionManagerImpl implements ActionManager {
return actionMap;
}
/**
* Triggers a list of actions with the given condition.
* If the list of actions is not null, each action in the list is triggered.
*
* @param actions The list of actions to trigger.
* @param condition The condition associated with the actions.
*/
@Override
public void triggerActions(List<Action> actions, Condition condition) {
if (actions != null)
for (Action action : actions)
action.trigger(condition);
}
private void registerMessageAction() {
registerAction("message", (args, chance) -> {
ArrayList<String> msg = ConfigUtils.stringListArgs(args);
@@ -558,22 +543,33 @@ public class ActionManagerImpl implements ActionManager {
if (Math.random() > chance) return;
Player owner = condition.getPlayer();
Location location = position ? condition.getLocation() : owner.getLocation();
plugin.getScheduler().runTaskSync(() -> {
for (Entity player : condition.getLocation().getWorld().getNearbyEntities(condition.getLocation(), range, range, range, entity -> entity instanceof Player)) {
double distance = LocationUtils.getDistance(player.getLocation(), condition.getLocation());
if (distance <= range) {
ArmorStandUtils.sendHologram(
(Player) player,
location.clone().add(x, y, z),
AdventureManagerImpl.getInstance().getComponentFromMiniMessage(
PlaceholderManagerImpl.getInstance().parse(owner, text, condition.getArgs())
),
duration
);
}
}
}, condition.getLocation()
);
if (range > 0) {
plugin.getScheduler().runTaskSync(() -> {
for (Entity player : location.getWorld().getNearbyEntities(location, range, range, range, entity -> entity instanceof Player)) {
double distance = LocationUtils.getDistance(player.getLocation(), location);
if (distance <= range) {
ArmorStandUtils.sendHologram(
(Player) player,
location.clone().add(x, y, z),
AdventureManagerImpl.getInstance().getComponentFromMiniMessage(
PlaceholderManagerImpl.getInstance().parse(owner, text, condition.getArgs())
),
duration
);
}
}
}, location
);
} else {
ArmorStandUtils.sendHologram(
owner,
location.clone().add(x, y, z),
AdventureManagerImpl.getInstance().getComponentFromMiniMessage(
PlaceholderManagerImpl.getInstance().parse(owner, text, condition.getArgs())
),
duration
);
}
};
} else {
LogUtils.warn("Illegal value format found at action: hologram");
@@ -630,7 +626,7 @@ public class ActionManagerImpl implements ActionManager {
return condition -> {
if (Math.random() > chance) return;
Player player = condition.getPlayer();
ItemUtils.giveCertainAmountOfItem(player, Objects.requireNonNull(CustomFishingPlugin.get().getItemManager().buildAnyPluginItemByID(player, id)), amount);
ItemUtils.putLootsToBag(player, Objects.requireNonNull(CustomFishingPlugin.get().getItemManager().buildAnyPluginItemByID(player, id)), amount);
};
} else {
LogUtils.warn("Illegal value format found at action: give-item");
@@ -644,20 +640,56 @@ public class ActionManagerImpl implements ActionManager {
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");
boolean position = !section.getString("position", "player").equals("player");
String x = ConfigUtils.getString(section.get("x", "0"));
String y = ConfigUtils.getString(section.get("y", "0"));
String z = ConfigUtils.getString(section.get("z", "0"));
String yaw = ConfigUtils.getString(section.get("yaw", "0"));
int range = section.getInt("range", 0);
boolean opposite = section.getBoolean("opposite-yaw", false);
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
Player owner = condition.getPlayer();
Location location = position ? condition.getLocation() : owner.getLocation();
location = location.clone().add(
plugin.getPlaceholderManager().getExpressionValue(owner, x, condition.getArgs()),
plugin.getPlaceholderManager().getExpressionValue(owner, y, condition.getArgs()),
plugin.getPlaceholderManager().getExpressionValue(owner, z, condition.getArgs())
);
Location finalLocation = location;
ItemStack itemStack = plugin.getItemManager().build(
owner, itemSplit[0],
plugin.getPlaceholderManager().parse(owner, itemSplit[1], condition.getArgs()),
condition.getArgs()
);
if (range > 0) {
plugin.getScheduler().runTaskSync(() -> {
for (Entity player : finalLocation.getWorld().getNearbyEntities(finalLocation, range, range, range, entity -> entity instanceof Player)) {
double distance = LocationUtils.getDistance(player.getLocation(), finalLocation);
if (distance <= range) {
Location locationTemp = finalLocation.clone();
if (opposite) locationTemp.setYaw(-player.getLocation().getYaw());
else locationTemp.setYaw((float) plugin.getPlaceholderManager().getExpressionValue((Player) player, yaw, condition.getArgs()));
ArmorStandUtils.sendFakeItem(
condition.getPlayer(),
locationTemp,
itemStack,
duration
);
}
}
}, condition.getLocation()
);
} else {
if (opposite) finalLocation.setYaw(-owner.getLocation().getYaw());
else finalLocation.setYaw((float) plugin.getPlaceholderManager().getExpressionValue(owner, yaw, condition.getArgs()));
ArmorStandUtils.sendFakeItem(
condition.getPlayer(),
finalLocation,
itemStack,
duration
);
}
};
} else {
LogUtils.warn("Illegal value format found at action: fake-item");
@@ -819,7 +851,7 @@ public class ActionManagerImpl implements ActionManager {
int fadeIn = section.getInt("fade-in", 20);
int stay = section.getInt("stay", 30);
int fadeOut = section.getInt("fade-out", 10);
int range = section.getInt("range", 32);
int range = section.getInt("range", 0);
return condition -> {
if (Math.random() > chance) return;
plugin.getScheduler().runTaskSync(() -> {

View File

@@ -23,12 +23,15 @@ import net.momirealms.customfishing.api.CustomFishingPlugin;
import net.momirealms.customfishing.api.data.user.OfflineUser;
import net.momirealms.customfishing.api.manager.BagManager;
import net.momirealms.customfishing.api.manager.EffectManager;
import net.momirealms.customfishing.api.mechanic.action.Action;
import net.momirealms.customfishing.api.mechanic.bag.FishingBagHolder;
import net.momirealms.customfishing.api.util.InventoryUtils;
import net.momirealms.customfishing.compatibility.papi.PlaceholderManagerImpl;
import net.momirealms.customfishing.setting.CFConfig;
import org.bukkit.Bukkit;
import org.bukkit.Material;
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;
@@ -40,14 +43,17 @@ import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.*;
public class BagManagerImpl implements BagManager, Listener {
private final CustomFishingPlugin plugin;
private final HashMap<UUID, OfflineUser> tempEditMap;
private Action[] collectLootActions;
private Action[] bagFullActions;
private boolean bagStoreLoots;
private String bagTitle;
private List<Material> bagWhiteListItems;
public BagManagerImpl(CustomFishingPluginImpl plugin) {
this.plugin = plugin;
@@ -61,6 +67,19 @@ public class BagManagerImpl implements BagManager, Listener {
public void load() {
Bukkit.getPluginManager().registerEvents(this, plugin);
if (isEnabled()) {
YamlConfiguration config = plugin.getConfig("config.yml");
ConfigurationSection bagSection = config.getConfigurationSection("mechanics.fishing-bag");
if (bagSection != null) {
bagTitle = bagSection.getString("bag-title");
bagStoreLoots = bagSection.getBoolean("can-store-loot", false);
bagWhiteListItems = bagSection.getStringList("whitelist-items").stream().map(it -> Material.valueOf(it.toUpperCase(Locale.ENGLISH))).toList();
if (bagStoreLoots) {
collectLootActions = plugin.getActionManager().getActions(bagSection.getConfigurationSection("collect-actions"));
bagFullActions = plugin.getActionManager().getActions(bagSection.getConfigurationSection("full-actions"));
}
}
}
}
public void unload() {
@@ -92,7 +111,7 @@ public class BagManagerImpl implements BagManager, Listener {
Inventory newBag = InventoryUtils.createInventory(onlinePlayer.getHolder(), rows * 9,
AdventureManagerImpl.getInstance().getComponentFromMiniMessage(
PlaceholderManagerImpl.getInstance().parse(
player, CFConfig.bagTitle, Map.of("{player}", player.getName())
player, bagTitle, Map.of("{player}", player.getName())
)
));
onlinePlayer.getHolder().setInventory(newBag);
@@ -165,7 +184,7 @@ public class BagManagerImpl implements BagManager, Listener {
ItemStack clickedItem = event.getCurrentItem();
if (clickedItem == null || clickedItem.getType() == Material.AIR)
return;
if (CFConfig.bagWhiteListItems.contains(clickedItem.getType()))
if (bagWhiteListItems.contains(clickedItem.getType()))
return;
String id = plugin.getItemManager().getAnyPluginItemID(clickedItem);
EffectManager effectManager = plugin.getEffectManager();
@@ -176,7 +195,7 @@ public class BagManagerImpl implements BagManager, Listener {
) {
return;
}
if (CFConfig.bagStoreLoots && plugin.getLootManager().getLoot(id) != null)
if (bagStoreLoots && plugin.getLootManager().getLoot(id) != null)
return;
event.setCancelled(true);
}
@@ -196,4 +215,29 @@ public class BagManagerImpl implements BagManager, Listener {
return;
plugin.getStorageManager().saveUserData(offlineUser, true);
}
@Override
public Action[] getCollectLootActions() {
return collectLootActions;
}
@Override
public Action[] getBagFullActions() {
return bagFullActions;
}
@Override
public boolean doesBagStoreLoots() {
return bagStoreLoots;
}
@Override
public String getBagTitle() {
return bagTitle;
}
@Override
public List<Material> getBagWhiteListItems() {
return bagWhiteListItems;
}
}

View File

@@ -416,12 +416,12 @@ public class FishingManagerImpl implements Listener, FishingManager {
// put vanilla loot in map
this.vanillaLootMap.put(uuid, Pair.of(item.getItemStack(), event.getExpToDrop()));
}
loot.triggerActions(ActionTrigger.HOOK, temp.getPreparation());
temp.getPreparation().triggerActions(ActionTrigger.HOOK);
var fishingPreparation = temp.getPreparation();
loot.triggerActions(ActionTrigger.HOOK, fishingPreparation);
fishingPreparation.triggerActions(ActionTrigger.HOOK);
if (!loot.disableGame()) {
// start the game if the loot has a game
if (startFishingGame(player, temp.getPreparation(), temp.getEffect())) {
if (startFishingGame(player, fishingPreparation, temp.getEffect())) {
event.setCancelled(true);
}
} else {
@@ -455,14 +455,16 @@ public class FishingManagerImpl implements Listener, FishingManager {
TempFishingState temp = getTempFishingState(uuid);
if (temp != null) {
var loot = temp.getLoot();
var fishingPreparation = temp.getPreparation();
fishingPreparation.setLocation(event.getHook().getLocation());
loot.triggerActions(ActionTrigger.BITE, temp.getPreparation());
temp.getPreparation().triggerActions(ActionTrigger.BITE);
loot.triggerActions(ActionTrigger.BITE, fishingPreparation);
fishingPreparation.triggerActions(ActionTrigger.BITE);
if (loot.instanceGame() && !loot.disableGame()) {
loot.triggerActions(ActionTrigger.HOOK, temp.getPreparation());
temp.getPreparation().triggerActions(ActionTrigger.HOOK);
startFishingGame(player, temp.getPreparation(), temp.getEffect());
loot.triggerActions(ActionTrigger.HOOK, fishingPreparation);
fishingPreparation.triggerActions(ActionTrigger.HOOK);
startFishingGame(player, fishingPreparation, temp.getEffect());
}
}
}
@@ -641,18 +643,27 @@ public class FishingManagerImpl implements Listener, FishingManager {
if (pair != null) {
fishingPreparation.insertArg("{nick}", "<lang:item.minecraft." + pair.left().getType().toString().toLowerCase() + ">");
for (int i = 0; i < amount; i++) {
plugin.getItemManager().dropItem(hook.getLocation(), player.getLocation(), pair.left().clone());
doSuccessActions(loot, effect, fishingPreparation, player);
if (pair.right() > 0) {
player.giveExp(pair.right(), true);
AdventureManagerImpl.getInstance().sendSound(player, Sound.Source.PLAYER, Key.key("minecraft:entity.experience_orb.pickup"), 1, 1);
}
plugin.getScheduler().runTaskSyncLater(() -> {
plugin.getItemManager().dropItem(player, hook.getLocation(), player.getLocation(), pair.left().clone(), fishingPreparation);
doSuccessActions(loot, effect, fishingPreparation, player);
if (pair.right() > 0) {
player.giveExp(pair.right(), true);
AdventureManagerImpl.getInstance().sendSound(player, Sound.Source.PLAYER, Key.key("minecraft:entity.experience_orb.pickup"), 1, 1);
}
}, hook.getLocation(), (long) CFConfig.multipleLootSpawnDelay * i);
}
}
} else {
for (int i = 0; i < amount; i++) {
plugin.getItemManager().dropItem(player, hook.getLocation(), player.getLocation(), loot.getID(), fishingPreparation.getArgs());
doSuccessActions(loot, effect, fishingPreparation, player);
plugin.getScheduler().runTaskSyncLater(() -> {
ItemStack item = plugin.getItemManager().build(player, "item", loot.getID(), fishingPreparation.getArgs());
if (item == null) {
LogUtils.warn(String.format("Item %s not exists", loot.getID()));
return;
}
plugin.getItemManager().dropItem(player, hook.getLocation(), player.getLocation(), item, fishingPreparation);
doSuccessActions(loot, effect, fishingPreparation, player);
}, hook.getLocation(), (long) CFConfig.multipleLootSpawnDelay * i);
}
}
return;

View File

@@ -185,9 +185,6 @@ public class HookCheckTimerTask implements Runnable {
this.loot = nextLoot;
fishingPreparation.insertArg("{nick}", nextLoot.getNick());
fishingPreparation.insertArg("{loot}", nextLoot.getID());
fishingPreparation.insertArg("{x}", String.valueOf(fishHook.getLocation().getBlockX()));
fishingPreparation.insertArg("{y}", String.valueOf(fishHook.getLocation().getBlockY()));
fishingPreparation.insertArg("{z}", String.valueOf(fishHook.getLocation().getBlockZ()));
if (!nextLoot.disableStats()) {
fishingPreparation.insertArg("{statistics_size}", nextLoot.getStatisticKey().getSizeKey());
fishingPreparation.insertArg("{statistics_amount}", nextLoot.getStatisticKey().getAmountKey());

View File

@@ -322,7 +322,7 @@ public class HookManagerImpl implements Listener, HookManager {
if (cursor.getAmount() == 0) {
event.setCursor(previousItemStack);
} else {
ItemUtils.giveCertainAmountOfItem(player, previousItemStack, 1);
ItemUtils.putLootsToBag(player, previousItemStack, 1);
}
}

View File

@@ -24,6 +24,7 @@ import net.momirealms.customfishing.api.common.Key;
import net.momirealms.customfishing.api.common.Pair;
import net.momirealms.customfishing.api.common.Tuple;
import net.momirealms.customfishing.api.event.FishingLootSpawnEvent;
import net.momirealms.customfishing.api.manager.ActionManager;
import net.momirealms.customfishing.api.manager.ItemManager;
import net.momirealms.customfishing.api.manager.RequirementManager;
import net.momirealms.customfishing.api.mechanic.GlobalSettings;
@@ -374,7 +375,9 @@ public class ItemManagerImpl implements ItemManager, Listener {
if (temp.getType() == Material.AIR) {
return temp;
}
temp.setAmount(builder.getAmount());
int amount = builder.getAmount();
temp.setAmount(amount);
placeholders.put("{amount}", String.valueOf(amount));
NBTItem nbtItem = new NBTItem(temp);
for (ItemBuilder.ItemPropertyEditor editor : builder.getEditors()) {
editor.edit(player, nbtItem, placeholders);
@@ -423,27 +426,28 @@ public class ItemManagerImpl implements ItemManager, Listener {
return itemLibraryMap.remove(identification) != null;
}
/**
* Drops an item based on the provided loot, applying velocity from a hook location to a player location.
* This method would also trigger FishingLootSpawnEvent
*
* @param player The player for whom the item is intended.
* @param hookLocation The location where the item will initially drop.
* @param playerLocation The target location towards which the item's velocity is applied.
* @param id The loot object representing the item to be dropped.
* @param args A map of placeholders for item customization.
*/
@Override
public void dropItem(Player player, Location hookLocation, Location playerLocation, String id, Map<String, String> args) {
ItemStack item = build(player, "item", id, args);
if (item == null) {
LogUtils.warn(String.format("Item %s not exists", id));
return;
}
public void dropItem(Player player, Location hookLocation, Location playerLocation, ItemStack item, Condition condition) {
if (item.getType() == Material.AIR) {
return;
}
if (CFConfig.enableFishingBag && plugin.getBagManager().doesBagStoreLoots() && player.hasPermission("fishingbag.collectloot")) {
var bag = plugin.getBagManager().getOnlineBagInventory(player.getUniqueId());
int cannotPut = ItemUtils.putLootsToBag(bag, item, item.getAmount());
// some are put into bag
if (cannotPut != item.getAmount()) {
ActionManager.triggerActions(condition, plugin.getBagManager().getCollectLootActions());
}
// all are put
if (cannotPut == 0) {
return;
}
// bag is full
item.setAmount(cannotPut);
ActionManager.triggerActions(condition, plugin.getBagManager().getBagFullActions());
}
FishingLootSpawnEvent spawnEvent = new FishingLootSpawnEvent(player, hookLocation, item);
Bukkit.getPluginManager().callEvent(spawnEvent);
if (spawnEvent.isCancelled()) {
@@ -456,21 +460,6 @@ public class ItemManagerImpl implements ItemManager, Listener {
itemEntity.setVelocity(vector);
}
/**
* Drops an item entity at the specified location and applies velocity towards another location.
*
* @param hookLocation The location where the item will initially drop.
* @param playerLocation The target location towards which the item's velocity is applied.
* @param itemStack The item stack to be dropped as an entity.
*/
@Override
public void dropItem(Location hookLocation, Location playerLocation, ItemStack itemStack) {
Entity itemEntity = hookLocation.getWorld().dropItem(hookLocation, itemStack);
Vector vector = playerLocation.subtract(hookLocation).toVector().multiply(0.105);
vector = vector.setY((vector.getY() + 0.22) * 1.18);
itemEntity.setVelocity(vector);
}
/**
* Decreases the durability of an ItemStack by a specified amount and optionally updates its lore.
*
@@ -731,7 +720,8 @@ public class ItemManagerImpl implements ItemManager, Listener {
placeholders.put("{BASE}", String.valueOf(base));
placeholders.put("{bonus}", String.format("%.2f", bonus));
placeholders.put("{BONUS}", String.valueOf(bonus));
double price = CustomFishingPlugin.get().getMarketManager().getFishPrice(
double price;
price = CustomFishingPlugin.get().getMarketManager().getFishPrice(
player,
placeholders
);

View File

@@ -255,7 +255,7 @@ public class MarketGUI {
for (int slot : itemElement.getSlots()) {
ItemStack itemStack = inventory.getItem(slot);
if (itemStack != null && itemStack.getType() != Material.AIR) {
ItemUtils.giveCertainAmountOfItem(owner, itemStack, itemStack.getAmount());
ItemUtils.putLootsToBag(owner, itemStack, itemStack.getAmount());
inventory.setItem(slot, new ItemStack(Material.AIR));
}
}

View File

@@ -433,7 +433,12 @@ public class MarketManagerImpl implements MarketManager, Listener {
*/
@Override
public double getFishPrice(Player player, Map<String, String> vars) {
return ConfigUtils.getExpressionValue(player, formula, vars);
String temp = PlaceholderManagerImpl.getInstance().parse(player, formula, vars);
var placeholders = PlaceholderManagerImpl.getInstance().detectPlaceholders(temp);
for (String placeholder : placeholders) {
temp = temp.replace(placeholder, "0");
}
return new ExpressionBuilder(temp).build().evaluate();
}
/**

View File

@@ -215,6 +215,7 @@ public class RequirementManagerImpl implements RequirementManager {
this.registerPotionEffectRequirement();
this.registerSizeRequirement();
this.registerHasStatsRequirement();
this.registerLootTypeRequirement();
}
public HashMap<String, Double> getLootWithWeight(Condition condition) {
@@ -1075,6 +1076,33 @@ public class RequirementManagerImpl implements RequirementManager {
});
}
private void registerLootTypeRequirement() {
registerRequirement("loot-type", (args, actions, advanced) -> {
List<String> types = ConfigUtils.stringListArgs(args);
return condition -> {
String loot = condition.getArg("{loot}");
Loot lootInstance = plugin.getLootManager().getLoot(loot);
if (lootInstance != null) {
if (types.contains(lootInstance.getType().name().toLowerCase(Locale.ENGLISH))) return true;
}
if (advanced) triggerActions(actions, condition);
return false;
};
});
registerRequirement("!loot-type", (args, actions, advanced) -> {
List<String> types = ConfigUtils.stringListArgs(args);
return condition -> {
String loot = condition.getArg("{loot}");
Loot lootInstance = plugin.getLootManager().getLoot(loot);
if (lootInstance != null) {
if (!types.contains(lootInstance.getType().name().toLowerCase(Locale.ENGLISH))) return true;
}
if (advanced) triggerActions(actions, condition);
return false;
};
});
}
private void registerEnvironmentRequirement() {
registerRequirement("environment", (args, actions, advanced) -> {
List<String> environments = ConfigUtils.stringListArgs(args);

View File

@@ -73,6 +73,11 @@ public class BukkitSchedulerImpl implements SyncScheduler {
*/
@Override
public CancellableTask runTaskSyncLater(Runnable runnable, Location location, long delay) {
if (delay == 0) {
if (Bukkit.isPrimaryThread()) runnable.run();
else Bukkit.getScheduler().runTask(plugin, runnable);
return new BukkitCancellableTask(null);
}
return new BukkitCancellableTask(Bukkit.getScheduler().runTaskLater(plugin, runnable, delay));
}
@@ -89,11 +94,13 @@ public class BukkitSchedulerImpl implements SyncScheduler {
@Override
public void cancel() {
this.bukkitTask.cancel();
if (this.bukkitTask != null)
this.bukkitTask.cancel();
}
@Override
public boolean isCancelled() {
if (this.bukkitTask == null) return true;
return this.bukkitTask.isCancelled();
}
}

View File

@@ -24,6 +24,7 @@ import dev.dejvokep.boostedyaml.settings.general.GeneralSettings;
import dev.dejvokep.boostedyaml.settings.loader.LoaderSettings;
import dev.dejvokep.boostedyaml.settings.updater.UpdaterSettings;
import net.momirealms.customfishing.api.CustomFishingPlugin;
import net.momirealms.customfishing.api.mechanic.action.Action;
import net.momirealms.customfishing.api.util.LogUtils;
import net.momirealms.customfishing.api.util.OffsetUtils;
import net.momirealms.customfishing.util.ConfigUtils;
@@ -40,7 +41,7 @@ import java.util.Objects;
public class CFConfig {
// config version
public static String configVersion = "31";
public static String configVersion = "32";
// Debug mode
public static boolean debug;
// language
@@ -66,9 +67,6 @@ public class CFConfig {
// fishing bag
public static boolean enableFishingBag;
public static boolean bagStoreLoots;
public static String bagTitle;
public static List<Material> bagWhiteListItems;
// Fishing wait time
public static boolean overrideVanilla;
@@ -101,6 +99,8 @@ public class CFConfig {
public static boolean globalDisableGame;
public static boolean globalInstantGame;
public static int multipleLootSpawnDelay;
public static void load() {
try {
YamlDocument.create(
@@ -118,6 +118,8 @@ public class CFConfig {
.addIgnoredRoute(configVersion, "mechanics.mechanic-requirements", '.')
.addIgnoredRoute(configVersion, "mechanics.global-events", '.')
.addIgnoredRoute(configVersion, "mechanics.global-effects", '.')
.addIgnoredRoute(configVersion, "mechanics.fishing-bag.collect-actions", '.')
.addIgnoredRoute(configVersion, "mechanics.fishing-bag.full-actions", '.')
.addIgnoredRoute(configVersion, "other-settings.placeholder-register", '.')
.build()
);
@@ -143,9 +145,6 @@ public class CFConfig {
blockDetectOrder = config.getStringList("other-settings.block-detection-order");
enableFishingBag = config.getBoolean("mechanics.fishing-bag.enable", true);
bagTitle = config.getString("mechanics.fishing-bag.bag-title");
bagStoreLoots = config.getBoolean("mechanics.fishing-bag.can-store-loot", false);
bagWhiteListItems = config.getStringList("mechanics.fishing-bag.whitelist-items").stream().map(it -> Material.valueOf(it.toUpperCase(Locale.ENGLISH))).toList();
overrideVanilla = config.getBoolean("mechanics.fishing-wait-time.override-vanilla", false);
waterMinTime = config.getInt("mechanics.fishing-wait-time.min-wait-time", 100);
@@ -165,6 +164,8 @@ public class CFConfig {
placeholderLimit = config.getInt("mechanics.competition.placeholder-limit", 3);
serverGroup = config.getString("mechanics.competition.server-group","default");
multipleLootSpawnDelay = config.getInt("mechanics.multiple-loot-spawn-delay", 0);
dataSaveInterval = config.getInt("other-settings.data-saving-interval", 600);
logDataSaving = config.getBoolean("other-settings.log-data-saving", true);
lockData = config.getBoolean("other-settings.lock-data", true);

View File

@@ -66,7 +66,7 @@ public class OfflineUserImpl implements OfflineUser {
this.holder.setInventory(InventoryUtils.createInventory(this.holder, playerData.getBagData().size,
AdventureManagerImpl.getInstance().getComponentFromMiniMessage(
PlaceholderManagerImpl.getInstance().parse(
offlinePlayer, CFConfig.bagTitle, Map.of("{player}", Optional.ofNullable(offlinePlayer.getName()).orElse(String.valueOf(uuid)))
offlinePlayer, CustomFishingPlugin.get().getBagManager().getBagTitle(), Map.of("{player}", Optional.ofNullable(offlinePlayer.getName()).orElse(String.valueOf(uuid)))
)
)));
this.holder.setItems(InventoryUtils.getInventoryItems(playerData.getBagData().serialized));

View File

@@ -67,6 +67,7 @@ public class ArmorStandUtils {
entityPacket.getDoubles().write(0, location.getX());
entityPacket.getDoubles().write(1, location.getY());
entityPacket.getDoubles().write(2, location.getZ());
entityPacket.getBytes().write(0, (byte) ((location.getYaw() % 360) * 128 / 180));
return entityPacket;
}

View File

@@ -258,6 +258,17 @@ public class ConfigUtils {
return list;
}
public static String getString(Object o) {
if (o instanceof String s) {
return s;
} else if (o instanceof Integer i) {
return String.valueOf(i);
} else if (o instanceof Double d) {
return String.valueOf(d);
}
throw new IllegalArgumentException("Illegal string format: " + o);
}
/**
* Reads data from a YAML configuration file and creates it if it doesn't exist.
*

View File

@@ -34,6 +34,7 @@ import org.bukkit.Material;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerItemDamageEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
import org.bukkit.inventory.meta.Damageable;
@@ -341,7 +342,7 @@ public class ItemUtils {
* @param amount The amount of items to give
* @return The actual amount of items given
*/
public static int giveCertainAmountOfItem(Player player, ItemStack itemStack, int amount) {
public static int putLootsToBag(Player player, ItemStack itemStack, int amount) {
PlayerInventory inventory = player.getInventory();
ItemMeta meta = itemStack.getItemMeta();
int maxStackSize = itemStack.getMaxStackSize();
@@ -404,4 +405,59 @@ public class ItemUtils {
return actualAmount;
}
public static ItemStack removeOwner(ItemStack itemStack) {
if (itemStack == null || itemStack.getType() == Material.AIR) return itemStack;
NBTItem nbtItem = new NBTItem(itemStack);
if (nbtItem.hasTag("owner")) {
nbtItem.removeKey("owner");
return nbtItem.getItem();
}
return itemStack;
}
/**
* @return the amount of items that can't be put in the inventory
*/
public static int putLootsToBag(Inventory inventory, ItemStack itemStack, int amount) {
itemStack = removeOwner(itemStack.clone());
ItemMeta meta = itemStack.getItemMeta();
int maxStackSize = itemStack.getMaxStackSize();
for (ItemStack other : inventory.getStorageContents()) {
if (other != null) {
if (other.getType() == itemStack.getType() && other.getItemMeta().equals(meta)) {
if (other.getAmount() < maxStackSize) {
int delta = maxStackSize - other.getAmount();
if (amount > delta) {
other.setAmount(maxStackSize);
amount -= delta;
} else {
other.setAmount(amount + other.getAmount());
return 0;
}
}
}
}
}
if (amount > 0) {
for (ItemStack other : inventory.getStorageContents()) {
if (other == null) {
if (amount > maxStackSize) {
amount -= maxStackSize;
ItemStack cloned = itemStack.clone();
cloned.setAmount(maxStackSize);
inventory.addItem(cloned);
} else {
ItemStack cloned = itemStack.clone();
cloned.setAmount(amount);
inventory.addItem(cloned);
return 0;
}
}
}
}
return amount;
}
}

View File

@@ -1,6 +1,6 @@
# Developer: @Xiao-MoMi
# Wiki: https://mo-mi.gitbook.io/xiaomomi-plugins/
config-version: '31'
config-version: '32'
# Debug
debug: false
@@ -130,9 +130,6 @@ mechanics:
duration: 35
position: hook
item: util:lava_effect
y: 0
x: 0
z: 0
priority_2:
conditions:
lava-fishing: false
@@ -143,9 +140,6 @@ mechanics:
duration: 35
position: hook
item: util:water_effect
y: 0
x: 0
z: 0
# Global properties which would help you reduce duplicated lines
global-loot-property:
@@ -165,6 +159,37 @@ mechanics:
# Other whitelist-items
whitelist-items:
- fishing_rod
# Actions to do if fishing loots are automatically collected into bag
collect-actions:
sound_action:
type: sound
value:
key: "minecraft:item.armor.equip_leather"
source: 'player'
volume: 1
pitch: 1
hologram_action:
type: hologram
value:
duration: 40
text: '{nick} <#B0E0E6><b>has been stored into bag</#B0E0E6>'
position: other
y: 1
# Actions to do if the fishing bag is full
full-actions:
conditional_action:
type: conditional
value:
conditions:
condition_1:
type: cooldown
value:
key: fishing_bag_full_notice
time: 60000
actions:
message_action:
type: message
value: "<#EEE8AA>[Fishing Bag]</#EEE8AA> Your fishing bag has been full."
# Fishing wait time
# This section would take effect if you set "override-vanilla" to true
@@ -199,6 +224,9 @@ mechanics:
# Increase this value would allow you to use more placeholders like {4_player} {5_score} in sacrifice of some performance
placeholder-limit: 3
# If a player could get multiple loots from fishing, should the loots spawn at the same time or have delays for each (tick)
multiple-loot-spawn-delay: 4
# Other settings
other-settings:
# It's recommended to use MiniMessage format. If you insist on using legacy color code "&", enable the support below.
@@ -233,6 +261,8 @@ other-settings:
'{record}': '%fishingstats_size-record_{loot}%'
# Requires server expansion
'{date}': '%server_time_yyyy-MM-dd-HH:mm:ss%'
# Requires player expansion
'{yaw}': '%player_yaw%'
# CustomFishing supports using items/blocks from other plugins
# If items share the same id, they would inherit the effects

View File

@@ -27,4 +27,8 @@ softdepend:
- Zaphkiel
permissions:
fishingbag.user:
default: true
fishingbag.collectloot:
default: false
customfishing.sellfish:
default: true