9
0
mirror of https://github.com/Xiao-MoMi/Custom-Fishing.git synced 2025-12-28 19:39:06 +00:00

2.0-backup-4

This commit is contained in:
XiaoMoMi
2023-09-03 23:22:51 +08:00
parent b73dd6cf51
commit 3f79d9c621
17 changed files with 390 additions and 183 deletions

View File

@@ -34,17 +34,23 @@ public class CommandManagerImpl implements CommandManager {
)
.register();
if (CustomFishingPlugin.get().getBagManager().isBagEnabled()) {
new CommandAPICommand("sellfish")
.withPermission("customfishing.sellfish")
.executesPlayer((player, args) -> {
plugin.getMarketManager().openMarketGUI(player);
})
.register();
if (plugin.getBagManager().isBagEnabled()) {
FishingBagCommand.INSTANCE.getBagCommand().register();
}
}
private CommandAPICommand getReloadCommand() {
return new CommandAPICommand("reload")
.withPermission("customfishing.command.reload")
.executes((sender, args) -> {
long time = System.currentTimeMillis();
CustomFishingPlugin.get().reload();
plugin.reload();
AdventureManagerImpl.getInstance().sendMessageWithPrefix(sender, Locale.MSG_Reload.replace("{time}", String.valueOf(System.currentTimeMillis()-time)));
});
}

View File

@@ -313,6 +313,7 @@ public class ActionManagerImpl implements ActionManager {
condition.getPlayer().addPotionEffect(potionEffect);
};
}
LogUtils.warn("Illegal value format found at action: potion-effect");
return null;
});
}
@@ -332,6 +333,7 @@ public class ActionManagerImpl implements ActionManager {
AdventureManagerImpl.getInstance().sendSound(condition.getPlayer(), sound);
};
}
LogUtils.warn("Illegal value format found at action: sound");
return null;
});
}

View File

@@ -223,17 +223,15 @@ public class BlockManagerImpl implements BlockManager, Listener {
} else {
blockData = blockLibraryMap.get("vanilla").getBlockData(player, blockID, config.getDataModifier());
}
plugin.getScheduler().runTaskSync(() -> {
FallingBlock fallingBlock = hookLocation.getWorld().spawnFallingBlock(hookLocation, blockData);
fallingBlock.getPersistentDataContainer().set(
Objects.requireNonNull(NamespacedKey.fromString("block", CustomFishingPlugin.get())),
PersistentDataType.STRING,
loot.getID() + ";" + player.getName()
);
Vector vector = playerLocation.subtract(hookLocation).toVector().multiply((config.getHorizontalVector()) - 1);
vector = vector.setY((vector.getY() + 0.2) * config.getVerticalVector());
fallingBlock.setVelocity(vector);
}, hookLocation);
FallingBlock fallingBlock = hookLocation.getWorld().spawnFallingBlock(hookLocation, blockData);
fallingBlock.getPersistentDataContainer().set(
Objects.requireNonNull(NamespacedKey.fromString("block", CustomFishingPlugin.get())),
PersistentDataType.STRING,
loot.getID() + ";" + player.getName()
);
Vector vector = playerLocation.subtract(hookLocation).toVector().multiply((config.getHorizontalVector()) - 1);
vector = vector.setY((vector.getY() + 0.2) * config.getVerticalVector());
fallingBlock.setVelocity(vector);
}
private void registerDirectional() {

View File

@@ -2,7 +2,6 @@ package net.momirealms.customfishing.mechanic.fishing;
import com.destroystokyo.paper.event.player.PlayerJumpEvent;
import de.tr7zw.changeme.nbtapi.NBTItem;
import io.papermc.paper.event.player.AsyncChatEvent;
import net.momirealms.customfishing.CustomFishingPluginImpl;
import net.momirealms.customfishing.api.common.Pair;
import net.momirealms.customfishing.api.event.LavaFishingEvent;
@@ -434,7 +433,7 @@ public class FishingManagerImpl implements Listener, FishingManager {
if (bonus != null)
tempFishingState.getEffect().merge(bonus);
if (gamingPlayer.isSucceeded())
if (gamingPlayer.isSuccessful())
success(tempFishingState, fishHook);
else
fail(tempFishingState);
@@ -472,10 +471,6 @@ public class FishingManagerImpl implements Listener, FishingManager {
var fishingPreparation = state.getPreparation();
var player = fishingPreparation.getPlayer();
int amount = (int) effect.getMultipleLootChance();
amount += Math.random() < (effect.getMultipleLootChance() - amount) ? 2 : 1;
fishingPreparation.insertArg("{amount}", String.valueOf(amount));
fishingPreparation.insertArg("{score}", String.format("%.2f", loot.getScore() * effect.getScoreMultiplier()));
fishingPreparation.insertArg("{size-multiplier}", String.format("%.2f", effect.getSizeMultiplier()));
fishingPreparation.insertArg("{x}", String.valueOf(hook.getLocation().getBlockX()));
@@ -483,35 +478,39 @@ public class FishingManagerImpl implements Listener, FishingManager {
fishingPreparation.insertArg("{z}", String.valueOf(hook.getLocation().getBlockZ()));
fishingPreparation.insertArg("{loot}", loot.getID());
fishingPreparation.insertArg("{nick}", loot.getNick());
fishingPreparation.insertArg("{score}", String.format("%.2f", loot.getScore()));
switch (loot.getType()) {
case LOOT -> {
// build the items for multiple times instead of using setAmount() to make sure that each item is unique
if (loot.getID().equals("vanilla")) {
ItemStack itemStack = vanillaLootMap.remove(player.getUniqueId());
if (itemStack != null) {
fishingPreparation.insertArg("{loot}", "<lang:item.minecraft." + itemStack.getType().toString().toLowerCase() + ">");
plugin.getScheduler().runTaskSync(() -> {
switch (loot.getType()) {
case LOOT -> {
int amount = (int) effect.getMultipleLootChance();
amount += Math.random() < (effect.getMultipleLootChance() - amount) ? 2 : 1;
fishingPreparation.insertArg("{amount}", String.valueOf(amount));
// build the items for multiple times instead of using setAmount() to make sure that each item is unique
if (loot.getID().equals("vanilla")) {
ItemStack itemStack = vanillaLootMap.remove(player.getUniqueId());
if (itemStack != null) {
fishingPreparation.insertArg("{loot}", "<lang:item.minecraft." + itemStack.getType().toString().toLowerCase() + ">");
for (int i = 0; i < amount; i++) {
plugin.getItemManager().dropItem(hook.getLocation(), player.getLocation(), itemStack.clone());
doSuccessActions(loot, fishingPreparation, player);
}
}
} else {
for (int i = 0; i < amount; i++) {
plugin.getItemManager().dropItem(hook.getLocation(), player.getLocation(), itemStack.clone());
doActions(loot, fishingPreparation, player);
plugin.getItemManager().dropItem(player, hook.getLocation(), player.getLocation(), loot, fishingPreparation.getArgs());
doSuccessActions(loot, fishingPreparation, player);
}
}
} else {
for (int i = 0; i < amount; i++) {
plugin.getItemManager().dropItem(player, hook.getLocation(), player.getLocation(), loot, fishingPreparation.getArgs());
doActions(loot, fishingPreparation, player);
}
return;
}
return;
case MOB -> plugin.getMobManager().summonMob(hook.getLocation(), player.getLocation(), loot);
case BLOCK -> plugin.getBlockManager().summonBlock(player, hook.getLocation(), player.getLocation(), loot);
}
case MOB -> plugin.getMobManager().summonMob(hook.getLocation(), player.getLocation(), loot);
case BLOCK -> plugin.getBlockManager().summonBlock(player, hook.getLocation(), player.getLocation(), loot);
}
doActions(loot, fishingPreparation, player);
doSuccessActions(loot, fishingPreparation, player);
}, hook.getLocation());
}
private void doActions(Loot loot, FishingPreparation fishingPreparation, Player player) {
private void doSuccessActions(Loot loot, FishingPreparation fishingPreparation, Player player) {
Action[] globalActions = LootManagerImpl.globalLootProperties.getActions(ActionTrigger.SUCCESS);
if (globalActions != null)
for (Action action : globalActions)
@@ -565,7 +564,12 @@ public class FishingManagerImpl implements Listener, FishingManager {
@Override
public void startFishingGame(Player player, GameSettings settings, Game game) {
this.gamingPlayerMap.put(player.getUniqueId(), game.start(player, settings, this));
Optional<FishHook> hook = getHook(player.getUniqueId());
if (hook.isPresent()) {
this.gamingPlayerMap.put(player.getUniqueId(), game.start(player, hook.get(), settings));
} else {
LogUtils.warn("It seems that player " + player.getName() + " is not fishing. Fishing game failed to start.");
}
}
@Override

View File

@@ -165,7 +165,7 @@ public class GameManagerImpl implements GameManager {
var barImage = section.getString("subtitle.bar");
var pointerImage = section.getString("subtitle.pointer");
return (player, settings, manager) -> new AbstractGamingPlayer(player, settings, manager) {
return (player, fishHook, settings) -> new AbstractGamingPlayer(player, fishHook, settings) {
private int progress;
private boolean face;
@@ -205,7 +205,7 @@ public class GameManagerImpl implements GameManager {
}
@Override
public boolean isSucceeded() {
public boolean isSuccessful() {
int last = progress / widthPerSection;
return (Math.random() < successRate[last]);
}
@@ -234,7 +234,7 @@ public class GameManagerImpl implements GameManager {
var barImage = section.getString("subtitle.bar");
var tip = section.getString("tip");
return (player, settings, manager) -> new AbstractGamingPlayer(player, settings, manager) {
return (player, fishHook, settings) -> new AbstractGamingPlayer(player, fishHook, settings) {
private double hold_time;
private double judgement_position;
private double fish_position;
@@ -278,8 +278,8 @@ public class GameManagerImpl implements GameManager {
hold_time -= punishment * 33;
}
if (hold_time >= time_requirement) {
succeeded = true;
manager.processGameResult(this);
setGameResult(true);
endGame();
return;
}
hold_time = Math.max(0, Math.min(hold_time, time_requirement));
@@ -376,7 +376,7 @@ public class GameManagerImpl implements GameManager {
var barImage = section.getString("subtitle.bar");
var tip = section.getString("tip");
return (player, settings, manager) -> new AbstractGamingPlayer(player, settings, manager) {
return (player, fishHook, settings) -> new AbstractGamingPlayer(player, fishHook, settings) {
private int fish_position = fishStartPosition;
private double strain;
@@ -401,13 +401,13 @@ public class GameManagerImpl implements GameManager {
if (player.isSneaking()) pull();
else loosen();
if (fish_position < successPosition - fishIconWidth - 1) {
super.succeeded = true;
manager.processGameResult(this);
setGameResult(true);
endGame();
return;
}
if (fish_position + fishIconWidth > barEffectiveWidth || strain >= ultimateTension) {
super.succeeded = false;
manager.processGameResult(this);
setGameResult(false);
endGame();
return;
}
showUI();

View File

@@ -266,12 +266,10 @@ public class ItemManagerImpl implements ItemManager {
@Override
public void dropItem(Location hookLocation, Location playerLocation, ItemStack itemStack) {
plugin.getScheduler().runTaskSync(() -> {
Entity itemEntity = hookLocation.getWorld().dropItem(hookLocation, itemStack);
Vector vector = playerLocation.subtract(hookLocation).toVector().multiply(0.105);
vector = vector.setY((vector.getY() + 0.2) * 1.18);
itemEntity.setVelocity(vector);
}, hookLocation);
Entity itemEntity = hookLocation.getWorld().dropItem(hookLocation, itemStack);
Vector vector = playerLocation.subtract(hookLocation).toVector().multiply(0.105);
vector = vector.setY((vector.getY() + 0.2) * 1.18);
itemEntity.setVelocity(vector);
}
@NotNull
@@ -291,7 +289,7 @@ public class ItemManagerImpl implements ItemManager {
return Pair.of(Float.parseFloat(split[0]), Float.parseFloat(split[1]));
}
public static class CFBuilder implements ItemBuilder, BuildableItem {
public static class CFBuilder implements ItemBuilder {
private final String library;
private final String id;
@@ -438,6 +436,7 @@ public class ItemManagerImpl implements ItemManager {
@Override
public ItemBuilder price(float base, float bonus) {
if (base == 0 && bonus == 0) return this;
editors.put("price", (player, nbtItem, placeholders) -> {
if (base != 0) {
placeholders.put("{base}", String.format("%.2f", base));
@@ -463,7 +462,7 @@ public class ItemManagerImpl implements ItemManager {
editors.put("size", (player, nbtItem, placeholders) -> {
NBTCompound cfCompound = nbtItem.getOrCreateCompound("CustomFishing");
float random = size.left() + ThreadLocalRandom.current().nextFloat(size.right() - size.left());
float bonus = Float.parseFloat(placeholders.getOrDefault("size-multiplier", "1.0"));
float bonus = Float.parseFloat(placeholders.getOrDefault("{size-multiplier}", "1.0"));
random *= bonus;
cfCompound.setFloat("size", random);
placeholders.put("{size}", String.format("%.2f", random));

View File

@@ -1,6 +1,7 @@
package net.momirealms.customfishing.mechanic.market;
import net.momirealms.customfishing.adventure.AdventureManagerImpl;
import net.momirealms.customfishing.api.data.EarningData;
import net.momirealms.customfishing.api.mechanic.market.MarketGUIHolder;
import net.momirealms.customfishing.api.util.InventoryUtils;
import net.momirealms.customfishing.api.util.LogUtils;
@@ -20,10 +21,12 @@ public class MarketGUI {
private final Inventory inventory;
private final MarketManagerImpl manager;
private final Player owner;
private final EarningData earningData;
public MarketGUI(MarketManagerImpl manager, Player player) {
public MarketGUI(MarketManagerImpl manager, Player player, EarningData earningData) {
this.manager = manager;
this.owner = player;
this.earningData = earningData;
this.itemsCharMap = new HashMap<>();
this.itemsSlotMap = new HashMap<>();
var holder = new MarketGUIHolder();
@@ -45,8 +48,10 @@ public class MarketGUI {
for (int index = 0; index < 9; index++) {
char symbol = content.charAt(index);
MarketGUIElement element = itemsCharMap.get(symbol);
element.addSlot(index + line * 9);
itemsSlotMap.put(index + line * 9, element);
if (element != null) {
element.addSlot(index + line * 9);
itemsSlotMap.put(index + line * 9, element);
}
}
line++;
}
@@ -82,35 +87,48 @@ public class MarketGUI {
return itemsCharMap.get(slot);
}
public void refresh() {
public MarketGUI refresh() {
double totalWorth = getTotalWorth();
MarketDynamicGUIElement functionElement = (MarketDynamicGUIElement) getElement(manager.getFunctionSlot());
if (functionElement == null) {
return this;
}
if (totalWorth <= 0) {
addElement(new MarketDynamicGUIElement(
manager.getFunctionSlot(),
functionElement.setItemStack(
manager.getFunctionIconDenyBuilder().build(owner,
Map.of("{worth}", String.format("%.2f", totalWorth)
,"{player}", owner.getName())
Map.of("{money}", String.format("%.2f", totalWorth)
,"{player}", owner.getName()
,"{rest}", String.format("%.2f", manager.getEarningLimit() - earningData.earnings))
)
));
);
} else if (manager.getEarningLimit() != -1 && (manager.getEarningLimit() - earningData.earnings < totalWorth)) {
functionElement.setItemStack(
manager.getFunctionIconLimitBuilder().build(owner,
Map.of("{money}", String.format("%.2f", totalWorth)
,"{player}", owner.getName()
,"{rest}", String.format("%.2f", manager.getEarningLimit() - earningData.earnings))
)
);
} else {
addElement(new MarketDynamicGUIElement(
manager.getFunctionSlot(),
functionElement.setItemStack(
manager.getFunctionIconAllowBuilder().build(owner,
Map.of("{worth}", String.format("%.2f", totalWorth)
,"{player}", owner.getName())
Map.of("{money}", String.format("%.2f", totalWorth)
,"{player}", owner.getName()
,"{rest}", String.format("%.2f", manager.getEarningLimit() - earningData.earnings))
)
));
);
}
for (Map.Entry<Integer, MarketGUIElement> entry : itemsSlotMap.entrySet()) {
if (entry.getValue() instanceof MarketDynamicGUIElement dynamicGUIElement) {
this.inventory.setItem(entry.getKey(), dynamicGUIElement.getItemStack().clone());
}
}
return this;
}
public double getTotalWorth() {
double money = 0d;
MarketGUIElement itemElement = getElement(manager.getItemSlot());
MarketGUIElement itemElement = getElement(manager.getItemSlot());;
if (itemElement == null) {
LogUtils.warn("No item slot available. Please check if GUI layout contains the item slot symbol.");
return money;
@@ -137,4 +155,36 @@ public class MarketGUI {
}
}
}
public int getEmptyItemSlot() {
MarketGUIElement itemElement = getElement(manager.getItemSlot());
if (itemElement == null) {
return -1;
}
for (int slot : itemElement.getSlots()) {
ItemStack itemStack = inventory.getItem(slot);
if (itemStack == null || itemStack.getType() == Material.AIR) {
return slot;
}
}
return -1;
}
public void returnItems() {
MarketGUIElement itemElement = getElement(manager.getItemSlot());
if (itemElement == null) {
return;
}
for (int slot : itemElement.getSlots()) {
ItemStack itemStack = inventory.getItem(slot);
if (itemStack != null && itemStack.getType() != Material.AIR) {
owner.getInventory().addItem(itemStack);
inventory.setItem(slot, new ItemStack(Material.AIR));
}
}
}
public EarningData getEarningData() {
return earningData;
}
}

View File

@@ -1,12 +1,17 @@
package net.momirealms.customfishing.mechanic.market;
import com.willfp.eco.core.map.MutableListMap;
import de.tr7zw.changeme.nbtapi.NBTItem;
import net.momirealms.customfishing.api.CustomFishingPlugin;
import net.momirealms.customfishing.api.data.EarningData;
import net.momirealms.customfishing.api.data.InventoryData;
import net.momirealms.customfishing.api.data.user.OnlineUser;
import net.momirealms.customfishing.api.manager.MarketManager;
import net.momirealms.customfishing.api.mechanic.action.Action;
import net.momirealms.customfishing.api.mechanic.condition.Condition;
import net.momirealms.customfishing.api.mechanic.item.BuildableItem;
import net.momirealms.customfishing.api.mechanic.item.ItemBuilder;
import net.momirealms.customfishing.api.mechanic.market.MarketGUIHolder;
import net.momirealms.customfishing.api.util.LogUtils;
import net.momirealms.customfishing.util.ConfigUtils;
import net.objecthunter.exp4j.Expression;
import net.objecthunter.exp4j.ExpressionBuilder;
@@ -14,12 +19,12 @@ import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.*;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
@@ -34,13 +39,18 @@ public class MarketManagerImpl implements MarketManager, Listener {
private String[] layout;
private String title;
private String formula;
private final HashMap<Character, ItemBuilder> decorativeIcons;
private final HashMap<Character, BuildableItem> decorativeIcons;
private char itemSlot;
private char functionSlot;
private BuildableItem functionIconAllowBuilder;
private BuildableItem functionIconDenyBuilder;
private BuildableItem functionIconLimitBuilder;
private Action[] denyActions;
private Action[] allowActions;
private Action[] limitActions;
private double earningLimit;
private ConcurrentHashMap<UUID, MarketGUI> marketGUIMap;
private boolean allowItemWithNoPrice;
private final ConcurrentHashMap<UUID, MarketGUI> marketGUIMap;
public MarketManagerImpl(CustomFishingPlugin plugin) {
this.plugin = plugin;
@@ -54,7 +64,6 @@ public class MarketManagerImpl implements MarketManager, Listener {
Bukkit.getPluginManager().registerEvents(this, plugin);
}
public void unload() {
HandlerList.unregisterAll(this);
this.priceMap.clear();
@@ -70,6 +79,17 @@ public class MarketManagerImpl implements MarketManager, Listener {
this.layout = config.getStringList("layout").toArray(new String[0]);
this.title = config.getString("title", "market.title");
this.formula = config.getString("price-formula", "{base} + {bonus} * {size}");
this.itemSlot = config.getString("item-slot.symbol", "I").charAt(0);
this.functionSlot = config.getString("functional-icons.symbol", "B").charAt(0);
this.functionIconAllowBuilder = plugin.getItemManager().getItemBuilder(config.getConfigurationSection("functional-icons.allow-icon"), "gui", "allow");
this.functionIconDenyBuilder = plugin.getItemManager().getItemBuilder(config.getConfigurationSection("functional-icons.deny-icon"), "gui", "deny");
this.functionIconLimitBuilder = plugin.getItemManager().getItemBuilder(config.getConfigurationSection("functional-icons.limit-icon"), "gui", "limit");
this.allowActions = plugin.getActionManager().getActions(config.getConfigurationSection("functional-icons.allow-icon.action"));
this.denyActions = plugin.getActionManager().getActions(config.getConfigurationSection("functional-icons.deny-icon.action"));
this.limitActions = plugin.getActionManager().getActions(config.getConfigurationSection("functional-icons.limit-icon.action"));
this.earningLimit = config.getBoolean("limitation.enable", true) ? config.getDouble("limitation.earnings", 100) : -1;
this.allowItemWithNoPrice = config.getBoolean("item-slot.allow-items-with-no-price", true);
ConfigurationSection priceSection = config.getConfigurationSection("item-price");
if (priceSection != null) {
for (Map.Entry<String, Object> entry : priceSection.getValues(false).entrySet()) {
@@ -88,9 +108,70 @@ public class MarketManagerImpl implements MarketManager, Listener {
}
}
@Override
public void openMarketGUI(Player player) {
MarketGUI gui = new MarketGUI(this, player);
OnlineUser user = plugin.getStorageManager().getOnlineUser(player.getUniqueId());
if (user == null) {
LogUtils.warn("Player " + player.getName() + "'s market data is not loaded yet.");
return;
}
MarketGUI gui = new MarketGUI(this, player, user.getEarningData());
gui.addElement(new MarketGUIElement(getItemSlot(), new ItemStack(Material.AIR)));
gui.addElement(new MarketDynamicGUIElement(getFunctionSlot(), new ItemStack(Material.AIR)));
for (Map.Entry<Character, BuildableItem> entry : decorativeIcons.entrySet()) {
gui.addElement(new MarketGUIElement(entry.getKey(), entry.getValue().build(player)));
}
gui.build().refresh().show(player);
marketGUIMap.put(player.getUniqueId(), gui);
}
@EventHandler
public void onCloseInv(InventoryCloseEvent event) {
if (!(event.getPlayer() instanceof Player player))
return;
if (!(event.getInventory().getHolder() instanceof MarketGUIHolder))
return;
MarketGUI gui = marketGUIMap.remove(player.getUniqueId());
if (gui != null)
gui.returnItems();
}
@EventHandler
public void onQuit(PlayerQuitEvent event) {
MarketGUI gui = marketGUIMap.remove(event.getPlayer().getUniqueId());
if (gui != null)
gui.returnItems();
}
@EventHandler
public void onDragInv(InventoryDragEvent event) {
if (event.isCancelled())
return;
Inventory inventory = event.getInventory();
if (!(inventory.getHolder() instanceof MarketGUIHolder holder))
return;
Player player = (Player) event.getWhoClicked();
MarketGUI gui = marketGUIMap.get(player.getUniqueId());
if (gui == null) {
event.setCancelled(true);
player.closeInventory();
return;
}
MarketGUIElement element = gui.getElement(itemSlot);
if (element == null) {
event.setCancelled(true);
return;
}
List<Integer> slots = element.getSlots();
for (int dragSlot : event.getRawSlots()) {
if (!slots.contains(dragSlot)) {
event.setCancelled(true);
return;
}
}
}
@EventHandler
@@ -100,62 +181,91 @@ public class MarketManagerImpl implements MarketManager, Listener {
Inventory clickedInv = event.getClickedInventory();
if (clickedInv == null)
return;
HumanEntity human = event.getWhoClicked();
if (!(clickedInv.getHolder() instanceof MarketGUIHolder holder))
Player player = (Player) event.getWhoClicked();
if (!(event.getInventory().getHolder() instanceof MarketGUIHolder holder))
return;
MarketGUI gui = marketGUIMap.get(human.getUniqueId());
MarketGUI gui = marketGUIMap.get(player.getUniqueId());
if (gui == null) {
event.setCancelled(true);
human.closeInventory();
player.closeInventory();
return;
}
int slot = event.getSlot();
MarketGUIElement element = gui.getElement(slot);
if (element == null) {
event.setCancelled(true);
return;
}
if (clickedInv != player.getInventory()) {
EarningData data = gui.getEarningData();
if (data.date != getDate()) {
data.date = getDate();
data.earnings = 0;
}
if (element.getSymbol() == itemSlot) {
plugin.getScheduler().runTaskSyncLater(gui::refresh, human.getLocation(), 50, TimeUnit.MILLISECONDS);
return;
}
int slot = event.getSlot();
MarketGUIElement element = gui.getElement(slot);
if (element == null) {
event.setCancelled(true);
return;
}
if (element.getSymbol() == functionSlot) {
event.setCancelled(true);
double worth = gui.getTotalWorth();
if (worth > 0) {
double remainingToEarn = getRemainingMoneyToEarn(human.getUniqueId());
if (remainingToEarn < worth) {
if (element.getSymbol() != itemSlot) {
event.setCancelled(true);
}
if (element.getSymbol() == functionSlot) {
double worth = gui.getTotalWorth();
Condition condition = new Condition(player, new HashMap<>(Map.of(
"{money}", String.format("%.2f", worth)
,"{rest}", String.format("%.2f", (earningLimit - data.earnings))
)));
if (worth > 0) {
if (earningLimit != -1 && (earningLimit - data.earnings) < worth) {
// can't earn more money
if (limitActions != null) {
for (Action action : limitActions) {
action.trigger(condition);
}
}
} else {
// clear items
gui.clearWorthyItems();
data.earnings += worth;
condition.insertArg("{rest}", String.format("%.2f", (earningLimit - data.earnings)));
if (allowActions != null) {
for (Action action : allowActions) {
action.trigger(condition);
}
}
}
} else {
gui.clearWorthyItems();
this.setRemainMoneyToEarn(human.getUniqueId(), remainingToEarn + worth);
// nothing to sell
if (denyActions != null) {
for (Action action : denyActions) {
action.trigger(condition);
}
}
}
}
} else {
ItemStack current = event.getCurrentItem();
if (!allowItemWithNoPrice) {
double price = getItemPrice(current);
if (price <= 0) {
event.setCancelled(true);
return;
}
}
if ((event.getClick() == ClickType.SHIFT_LEFT || event.getClick() == ClickType.SHIFT_RIGHT)
&& (current != null && current.getType() != Material.AIR)) {
event.setCancelled(true);
int slot = gui.getEmptyItemSlot();
if (slot != -1) {
gui.getInventory().setItem(slot, current.clone());
current.setAmount(0);
}
}
plugin.getScheduler().runTaskSyncLater(gui::refresh, human.getLocation(), 50, TimeUnit.MILLISECONDS);
return;
}
event.setCancelled(true);
}
public double getRemainingMoneyToEarn(UUID uuid) {
OnlineUser user = plugin.getStorageManager().getOnlineUser(uuid);
if (user == null) {
return -1;
}
return earningLimit - user.getEarningData().earnings;
}
public void setRemainMoneyToEarn(UUID uuid, double remaining) {
OnlineUser user = plugin.getStorageManager().getOnlineUser(uuid);
if (user == null) {
return;
}
user.getEarningData().earnings = remaining;
plugin.getScheduler().runTaskSyncLater(gui::refresh, player.getLocation(), 50, TimeUnit.MILLISECONDS);
}
@Override
@@ -171,13 +281,13 @@ public class MarketManagerImpl implements MarketManager, Listener {
NBTItem nbtItem = new NBTItem(itemStack);
Double price = nbtItem.getDouble("Price");
if (price != null && price != 0) {
return price;
return price * itemStack.getAmount();
}
String itemID = itemStack.getType().name();
if (nbtItem.hasTag("CustomModelData")) {
itemID = itemID + ":" + nbtItem.getInteger("CustomModelData");
}
return priceMap.getOrDefault(itemID, 0d);
return priceMap.getOrDefault(itemID, 0d) * itemStack.getAmount();
}
@Override
@@ -212,6 +322,14 @@ public class MarketManagerImpl implements MarketManager, Listener {
return title;
}
public double getEarningLimit() {
return earningLimit;
}
public BuildableItem getFunctionIconLimitBuilder() {
return functionIconLimitBuilder;
}
public BuildableItem getFunctionIconAllowBuilder() {
return functionIconAllowBuilder;
}

View File

@@ -125,20 +125,18 @@ public class MobManagerImpl implements MobManager {
return;
}
String mobID = config.getMobID();
plugin.getScheduler().runTaskSync(() -> {
Entity entity;
if (mobID.contains(":")) {
String[] split = mobID.split(":", 2);
String identification = split[0];
String id = split[1];
MobLibrary library = mobLibraryMap.get(identification);
entity = library.spawn(hookLocation, id, config.getPropertyMap());
} else {
entity = mobLibraryMap.get("vanilla").spawn(hookLocation, mobID, config.getPropertyMap());
}
Vector vector = playerLocation.subtract(hookLocation).toVector().multiply((config.getHorizontalVector()) - 1);
vector = vector.setY((vector.getY() + 0.2) * config.getVerticalVector());
entity.setVelocity(vector);
}, hookLocation);
Entity entity;
if (mobID.contains(":")) {
String[] split = mobID.split(":", 2);
String identification = split[0];
String id = split[1];
MobLibrary library = mobLibraryMap.get(identification);
entity = library.spawn(hookLocation, id, config.getPropertyMap());
} else {
entity = mobLibraryMap.get("vanilla").spawn(hookLocation, mobID, config.getPropertyMap());
}
Vector vector = playerLocation.subtract(hookLocation).toVector().multiply((config.getHorizontalVector()) - 1);
vector = vector.setY((vector.getY() + 0.2) * config.getVerticalVector());
entity.setVelocity(vector);
}
}

View File

@@ -1,6 +1,10 @@
# Container title
title: '<gradient:#A52A2A:#800000:#A52A2A>Fish Market</gradient>'
limitation:
enable: true
earnings: 10000
# Market menu layout
layout:
- 'AAAAAAAAA'
@@ -25,22 +29,29 @@ item-price:
# Slots to put items in
item-slot:
symbol: 'I'
allow-items-with-no-price: true
# Functional icon
functional-icons:
symbol: 'B'
sell-icon:
allow-icon:
material: IRON_BLOCK
display:
name: '<#00CED1><b>● <!b>Ship the fish'
lore:
- '<font:uniform><gradient:#E6E6FA:#48D1CC:#E6E6FA>You will get <green>{money}$</green> by selling the fish</gradient></font>'
- '<dark_gray>You can earn {rest}'
action:
sound_action:
type: sound
value:
key: 'minecraft:block.amethyst_block.place'
source: 'player'
volume: 1
pitch: 1
message_action:
type: message
value: 'You earned {money}$ by selling the fish! You can still get {remains}$ from market today'
value: 'You earned {money}$ by selling the fish! You can still get {rest}$ from market today'
command_action:
type: command
value: 'money give {player} {money}'
@@ -53,6 +64,25 @@ functional-icons:
action:
sound_action:
type: sound
value:
key: 'minecraft:entity.villager.no'
source: 'player'
volume: 1
pitch: 1
limit-icon:
material: REDSTONE_BLOCK
display:
name: '<red><b>● <!b>Denied trade'
lore:
- '<font:uniform><gradient:#E6E6FA:red:#E6E6FA>The worth of items exceeds the money that can be earned for the rest of today!</gradient></font>'
action:
sound_action:
type: sound
value:
key: 'minecraft:block.anvil.land'
source: 'player'
volume: 1
pitch: 1
# Decorative icons
decorative-icons: