mirror of
https://github.com/Xiao-MoMi/Custom-Fishing.git
synced 2025-12-31 04:46:36 +00:00
code clean up
This commit is contained in:
@@ -1,15 +0,0 @@
|
||||
package net.momirealms.customfishing.gui;
|
||||
|
||||
public class EditConditionGUI {
|
||||
|
||||
private String[] guiLayout = new String[] {
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" "
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
@@ -498,13 +498,13 @@ public class ActionManagerImpl implements ActionManager {
|
||||
|
||||
private void registerMendingAction() {
|
||||
registerAction("mending", (args, chance) -> {
|
||||
int xp = (int) args;
|
||||
var value = ConfigUtils.getValue(args);
|
||||
return condition -> {
|
||||
if (Math.random() > chance) return;
|
||||
if (CustomFishingPlugin.get().getVersionManager().isSpigot()) {
|
||||
condition.getPlayer().getLocation().getWorld().spawn(condition.getPlayer().getLocation(), ExperienceOrb.class, e -> e.setExperience(xp));
|
||||
condition.getPlayer().getLocation().getWorld().spawn(condition.getPlayer().getLocation(), ExperienceOrb.class, e -> e.setExperience((int) value.get(condition.getPlayer())));
|
||||
} else {
|
||||
condition.getPlayer().giveExp(xp, true);
|
||||
condition.getPlayer().giveExp((int) value.get(condition.getPlayer()), true);
|
||||
AdventureManagerImpl.getInstance().sendSound(condition.getPlayer(), Sound.Source.PLAYER, Key.key("minecraft:entity.experience_orb.pickup"), 1, 1);
|
||||
}
|
||||
};
|
||||
@@ -513,29 +513,30 @@ public class ActionManagerImpl implements ActionManager {
|
||||
|
||||
private void registerFoodAction() {
|
||||
registerAction("food", (args, chance) -> {
|
||||
int food = (int) (ConfigUtils.getDoubleValue(args) * 2);
|
||||
var value = ConfigUtils.getValue(args);
|
||||
return condition -> {
|
||||
if (Math.random() > chance) return;
|
||||
Player player = condition.getPlayer();
|
||||
player.setFoodLevel(player.getFoodLevel() + food);
|
||||
player.setFoodLevel((int) (player.getFoodLevel() + value.get(player)));
|
||||
};
|
||||
});
|
||||
registerAction("saturation", (args, chance) -> {
|
||||
double saturation = ConfigUtils.getDoubleValue(args);
|
||||
var value = ConfigUtils.getValue(args);
|
||||
return condition -> {
|
||||
if (Math.random() > chance) return;
|
||||
Player player = condition.getPlayer();
|
||||
player.setSaturation((float) (player.getSaturation() + saturation));
|
||||
player.setSaturation((float) (player.getSaturation() + value.get(player)));
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
private void registerExpAction() {
|
||||
registerAction("exp", (args, chance) -> {
|
||||
int xp = (int) args;
|
||||
var value = ConfigUtils.getValue(args);
|
||||
return condition -> {
|
||||
if (Math.random() > chance) return;
|
||||
condition.getPlayer().giveExp(xp);
|
||||
condition.getPlayer().giveExp((int) value.get(condition.getPlayer()));
|
||||
AdventureManagerImpl.getInstance().sendSound(condition.getPlayer(), Sound.Source.PLAYER, Key.key("minecraft:entity.experience_orb.pickup"), 1, 1);
|
||||
};
|
||||
});
|
||||
}
|
||||
@@ -683,17 +684,17 @@ public class ActionManagerImpl implements ActionManager {
|
||||
|
||||
private void registerMoneyAction() {
|
||||
registerAction("give-money", (args, chance) -> {
|
||||
double money = ConfigUtils.getDoubleValue(args);
|
||||
var value = ConfigUtils.getValue(args);
|
||||
return condition -> {
|
||||
if (Math.random() > chance) return;
|
||||
VaultHook.getEconomy().depositPlayer(condition.getPlayer(), money);
|
||||
VaultHook.getEconomy().depositPlayer(condition.getPlayer(), value.get(condition.getPlayer()));
|
||||
};
|
||||
});
|
||||
registerAction("take-money", (args, chance) -> {
|
||||
double money = ConfigUtils.getDoubleValue(args);
|
||||
var value = ConfigUtils.getValue(args);
|
||||
return condition -> {
|
||||
if (Math.random() > chance) return;
|
||||
VaultHook.getEconomy().withdrawPlayer(condition.getPlayer(), money);
|
||||
VaultHook.getEconomy().withdrawPlayer(condition.getPlayer(), value.get(condition.getPlayer()));
|
||||
};
|
||||
});
|
||||
}
|
||||
@@ -830,11 +831,11 @@ public class ActionManagerImpl implements ActionManager {
|
||||
|
||||
private void registerLevelAction() {
|
||||
registerAction("level", (args, chance) -> {
|
||||
int level = (int) args;
|
||||
var value = ConfigUtils.getValue(args);
|
||||
return condition -> {
|
||||
if (Math.random() > chance) return;
|
||||
Player player = condition.getPlayer();
|
||||
player.setLevel(Math.max(0, player.getLevel() + level));
|
||||
player.setLevel((int) Math.max(0, player.getLevel() + value.get(condition.getPlayer())));
|
||||
};
|
||||
});
|
||||
}
|
||||
@@ -923,12 +924,12 @@ public class ActionManagerImpl implements ActionManager {
|
||||
registerAction("plugin-exp", (args, chance) -> {
|
||||
if (args instanceof ConfigurationSection section) {
|
||||
String pluginName = section.getString("plugin");
|
||||
double exp = section.getDouble("exp", 1);
|
||||
var value = ConfigUtils.getValue(section.get("exp"));
|
||||
String target = section.getString("target");
|
||||
return condition -> {
|
||||
if (Math.random() > chance) return;
|
||||
Optional.ofNullable(plugin.getIntegrationManager().getLevelPlugin(pluginName)).ifPresentOrElse(it -> {
|
||||
it.addXp(condition.getPlayer(), target, exp);
|
||||
it.addXp(condition.getPlayer(), target, value.get(condition.getPlayer()));
|
||||
}, () -> LogUtils.warn("Plugin (" + pluginName + "'s) level is not compatible. Please double check if it's a problem caused by pronunciation."));
|
||||
};
|
||||
} else {
|
||||
|
||||
@@ -245,7 +245,6 @@ public class EffectManagerImpl implements EffectManager {
|
||||
public EffectModifier getEffectModifier(ConfigurationSection section) {
|
||||
String type = section.getString("type");
|
||||
if (type == null) return null;
|
||||
|
||||
switch (type) {
|
||||
case "weight-mod" -> {
|
||||
var modList = ConfigUtils.getModifiers(section.getStringList("value"));
|
||||
@@ -272,39 +271,39 @@ public class EffectManagerImpl implements EffectManager {
|
||||
});
|
||||
}
|
||||
case "hook-time" -> {
|
||||
double time = section.getDouble("value");
|
||||
var value = ConfigUtils.getValue(section.get("value"));
|
||||
return ((effect, condition) -> {
|
||||
effect.setHookTimeModifier(effect.getHookTimeModifier() + time - 1);
|
||||
effect.setHookTimeModifier(effect.getHookTimeModifier() + value.get(condition.getPlayer()) - 1);
|
||||
});
|
||||
}
|
||||
case "difficulty" -> {
|
||||
double difficulty = section.getDouble("value");
|
||||
var value = ConfigUtils.getValue(section.get("value"));
|
||||
return ((effect, condition) -> {
|
||||
effect.setDifficultyModifier(effect.getDifficultyModifier() + difficulty);
|
||||
effect.setDifficultyModifier(effect.getDifficultyModifier() + value.get(condition.getPlayer()));
|
||||
});
|
||||
}
|
||||
case "multiple-loot" -> {
|
||||
double multiple = section.getDouble("value");
|
||||
var value = ConfigUtils.getValue(section.get("value"));
|
||||
return ((effect, condition) -> {
|
||||
effect.setMultipleLootChance(effect.getMultipleLootChance() + multiple);
|
||||
effect.setMultipleLootChance(effect.getMultipleLootChance() + value.get(condition.getPlayer()));
|
||||
});
|
||||
}
|
||||
case "score-bonus" -> {
|
||||
double multiple = section.getDouble("value");
|
||||
var value = ConfigUtils.getValue(section.get("value"));
|
||||
return ((effect, condition) -> {
|
||||
effect.setScoreMultiplier(effect.getScoreMultiplier() + multiple - 1);
|
||||
effect.setScoreMultiplier(effect.getScoreMultiplier() + value.get(condition.getPlayer()) - 1);
|
||||
});
|
||||
}
|
||||
case "size-bonus" -> {
|
||||
double multiple = section.getDouble("value");
|
||||
var value = ConfigUtils.getValue(section.get("value"));
|
||||
return ((effect, condition) -> {
|
||||
effect.setSizeMultiplier(effect.getSizeMultiplier() + multiple - 1);
|
||||
effect.setSizeMultiplier(effect.getSizeMultiplier() + value.get(condition.getPlayer()) - 1);
|
||||
});
|
||||
}
|
||||
case "game-time" -> {
|
||||
double time = section.getDouble("value");
|
||||
var value = ConfigUtils.getValue(section.get("value"));
|
||||
return ((effect, condition) -> {
|
||||
effect.setGameTimeModifier(effect.getGameTimeModifier() + time);
|
||||
effect.setGameTimeModifier(effect.getGameTimeModifier() + value.get(condition.getPlayer()));
|
||||
});
|
||||
}
|
||||
case "lava-fishing" -> {
|
||||
|
||||
@@ -20,7 +20,10 @@ package net.momirealms.customfishing.mechanic.fishing;
|
||||
import com.destroystokyo.paper.event.player.PlayerJumpEvent;
|
||||
import de.tr7zw.changeme.nbtapi.NBTCompound;
|
||||
import de.tr7zw.changeme.nbtapi.NBTItem;
|
||||
import net.kyori.adventure.key.Key;
|
||||
import net.kyori.adventure.sound.Sound;
|
||||
import net.momirealms.customfishing.CustomFishingPluginImpl;
|
||||
import net.momirealms.customfishing.adventure.AdventureManagerImpl;
|
||||
import net.momirealms.customfishing.api.common.Pair;
|
||||
import net.momirealms.customfishing.api.event.FishingResultEvent;
|
||||
import net.momirealms.customfishing.api.event.LavaFishingEvent;
|
||||
@@ -72,7 +75,7 @@ public class FishingManagerImpl implements Listener, FishingManager {
|
||||
private final ConcurrentHashMap<UUID, HookCheckTimerTask> hookCheckMap;
|
||||
private final ConcurrentHashMap<UUID, TempFishingState> tempFishingStateMap;
|
||||
private final ConcurrentHashMap<UUID, GamingPlayer> gamingPlayerMap;
|
||||
private final ConcurrentHashMap<UUID, ItemStack> vanillaLootMap;
|
||||
private final ConcurrentHashMap<UUID, Pair<ItemStack, Integer>> vanillaLootMap;
|
||||
|
||||
public FishingManagerImpl(CustomFishingPluginImpl plugin) {
|
||||
this.plugin = plugin;
|
||||
@@ -394,7 +397,7 @@ public class FishingManagerImpl implements Listener, FishingManager {
|
||||
var loot = temp.getLoot();
|
||||
if (loot.getID().equals("vanilla")) {
|
||||
// put vanilla loot in map
|
||||
this.vanillaLootMap.put(uuid, item.getItemStack());
|
||||
this.vanillaLootMap.put(uuid, Pair.of(item.getItemStack(), event.getExpToDrop()));
|
||||
}
|
||||
loot.triggerActions(ActionTrigger.HOOK, temp.getPreparation());
|
||||
temp.getPreparation().triggerActions(ActionTrigger.HOOK);
|
||||
@@ -552,10 +555,10 @@ public class FishingManagerImpl implements Listener, FishingManager {
|
||||
var fishingPreparation = state.getPreparation();
|
||||
|
||||
if (loot.getID().equals("vanilla")) {
|
||||
ItemStack itemStack = this.vanillaLootMap.remove(fishingPreparation.getPlayer().getUniqueId());
|
||||
if (itemStack != null) {
|
||||
fishingPreparation.insertArg("{nick}", "<lang:item.minecraft." + itemStack.getType().toString().toLowerCase() + ">");
|
||||
fishingPreparation.insertArg("{loot}", itemStack.getType().toString());
|
||||
Pair<ItemStack, Integer> pair = this.vanillaLootMap.remove(fishingPreparation.getPlayer().getUniqueId());
|
||||
if (pair != null) {
|
||||
fishingPreparation.insertArg("{nick}", "<lang:item.minecraft." + pair.left().getType().toString().toLowerCase() + ">");
|
||||
fishingPreparation.insertArg("{loot}", pair.left().getType().toString());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -618,12 +621,16 @@ public class FishingManagerImpl implements Listener, FishingManager {
|
||||
|
||||
// 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("{nick}", "<lang:item.minecraft." + itemStack.getType().toString().toLowerCase() + ">");
|
||||
Pair<ItemStack, Integer> pair = vanillaLootMap.remove(player.getUniqueId());
|
||||
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(), itemStack.clone());
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -15,27 +15,23 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customfishing.mechanic.totem.block.type;
|
||||
package net.momirealms.customfishing.mechanic.misc.value;
|
||||
|
||||
import org.bukkit.block.Block;
|
||||
import net.momirealms.customfishing.util.ConfigUtils;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class StartWithType implements TypeCondition, Serializable {
|
||||
public class ExpressionValue implements Value {
|
||||
|
||||
private final String start;
|
||||
private final String expression;
|
||||
|
||||
public StartWithType(String start) {
|
||||
this.start = start;
|
||||
public ExpressionValue(String expression) {
|
||||
this.expression = expression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMet(Block type) {
|
||||
return type.getType().name().startsWith(start);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRawText() {
|
||||
return start + "*";
|
||||
public double get(Player player) {
|
||||
return ConfigUtils.getExpressionValue(player, expression, new HashMap<>(0));
|
||||
}
|
||||
}
|
||||
@@ -15,27 +15,20 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customfishing.mechanic.totem.block.type;
|
||||
package net.momirealms.customfishing.mechanic.misc.value;
|
||||
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.io.Serializable;
|
||||
public class PlainValue implements Value{
|
||||
|
||||
public class EndWithType implements TypeCondition, Serializable {
|
||||
private final double value;
|
||||
|
||||
private final String end;
|
||||
|
||||
public EndWithType(String end) {
|
||||
this.end = end;
|
||||
public PlainValue(double value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMet(Block type) {
|
||||
return type.getType().name().endsWith(end);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRawText() {
|
||||
return "*" + end;
|
||||
public double get(Player player) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
@@ -15,23 +15,11 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customfishing.mechanic.totem.block.type;
|
||||
package net.momirealms.customfishing.mechanic.misc.value;
|
||||
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public interface TypeCondition {
|
||||
public interface Value {
|
||||
|
||||
boolean isMet(Block block);
|
||||
|
||||
String getRawText();
|
||||
|
||||
static TypeCondition getTypeCondition(String raw) {
|
||||
if (raw.startsWith("*")) {
|
||||
return new EndWithType(raw.substring(1));
|
||||
} else if (raw.endsWith("*")) {
|
||||
return new StartWithType(raw.substring(0, raw.length() -1));
|
||||
} else {
|
||||
return new EqualType(raw);
|
||||
}
|
||||
}
|
||||
double get(Player player);
|
||||
}
|
||||
@@ -1,109 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) <2022> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customfishing.mechanic.totem;
|
||||
|
||||
import net.momirealms.customfishing.api.mechanic.requirement.Requirement;
|
||||
import net.momirealms.customfishing.mechanic.totem.block.TotemBlock;
|
||||
import net.momirealms.customfishing.mechanic.totem.particle.ParticleSetting;
|
||||
import org.bukkit.Location;
|
||||
|
||||
public class TotemConfig {
|
||||
|
||||
private String key;
|
||||
private TotemModel[] totemModels;
|
||||
private ParticleSetting[] particleSettings;
|
||||
private Requirement[] requirements;
|
||||
private double radius;
|
||||
private int duration;
|
||||
|
||||
public TotemModel[] getTotemModels() {
|
||||
return totemModels;
|
||||
}
|
||||
|
||||
public Requirement[] getRequirements() {
|
||||
return requirements;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public boolean isRightPattern(Location location) {
|
||||
for (TotemModel totemModel : totemModels) {
|
||||
if (totemModel.isPatternSatisfied(location)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public ParticleSetting[] getParticleSettings() {
|
||||
return particleSettings;
|
||||
}
|
||||
|
||||
public double getRadius() {
|
||||
return radius;
|
||||
}
|
||||
|
||||
public int getDuration() {
|
||||
return duration;
|
||||
}
|
||||
|
||||
public TotemBlock[] getTotemCore() {
|
||||
return totemModels[0].getTotemCore();
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
|
||||
private final TotemConfig config;
|
||||
|
||||
public Builder(String key) {
|
||||
this.config = new TotemConfig();
|
||||
this.config.key = key;
|
||||
}
|
||||
|
||||
public Builder setTotemModels(TotemModel[] totemModels) {
|
||||
config.totemModels = totemModels;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setParticleSettings(ParticleSetting[] particleSettings) {
|
||||
config.particleSettings = particleSettings;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setRequirements(Requirement[] requirements) {
|
||||
config.requirements = requirements;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setRadius(double radius) {
|
||||
config.radius = radius;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setDuration(int duration) {
|
||||
config.duration = duration;
|
||||
return this;
|
||||
}
|
||||
|
||||
public TotemConfig build() {
|
||||
return config;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,204 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) <2022> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customfishing.mechanic.totem;
|
||||
|
||||
import net.momirealms.customfishing.mechanic.totem.block.TotemBlock;
|
||||
import org.apache.commons.lang3.SerializationUtils;
|
||||
import org.bukkit.Axis;
|
||||
import org.bukkit.Location;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.StringJoiner;
|
||||
|
||||
public class TotemModel implements Serializable {
|
||||
|
||||
private int coreX;
|
||||
private final int coreY;
|
||||
private int coreZ;
|
||||
private TotemBlock[][][][] model;
|
||||
|
||||
public TotemModel(int coreX, int coreY, int coreZ, TotemBlock[][][][] model) {
|
||||
this.coreX = coreX;
|
||||
this.coreY = coreY;
|
||||
this.coreZ = coreZ;
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
public TotemBlock[] getTotemCore() {
|
||||
return model[coreY][coreZ][coreX];
|
||||
}
|
||||
|
||||
public int getCoreX() {
|
||||
return coreX;
|
||||
}
|
||||
|
||||
public int getCoreY() {
|
||||
return coreY;
|
||||
}
|
||||
|
||||
public int getCoreZ() {
|
||||
return coreZ;
|
||||
}
|
||||
|
||||
public TotemBlock[][][][] getModel() {
|
||||
return model;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
for (int h = 0; h < model.length; h++) {
|
||||
stringBuilder.append("layer: ").append(h + 1).append("\n");
|
||||
TotemBlock[][][] totemBlocks1 = model[h];
|
||||
for (TotemBlock[][] totemBlocks2 : totemBlocks1) {
|
||||
for (TotemBlock[] totemBlocks3 : totemBlocks2) {
|
||||
StringJoiner stringJoiner = new StringJoiner("||");
|
||||
for (TotemBlock totemBlock : totemBlocks3) {
|
||||
stringJoiner.add(totemBlock.toString());
|
||||
}
|
||||
stringBuilder.append(stringJoiner).append("\t");
|
||||
}
|
||||
stringBuilder.append("\n");
|
||||
}
|
||||
}
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TotemModel clone() {
|
||||
return SerializationUtils.clone(this);
|
||||
}
|
||||
|
||||
public TotemModel rotate90() {
|
||||
int tempX = this.coreX;
|
||||
this.coreX = this.coreZ;
|
||||
this.coreZ = this.model[0][0].length - 1 - tempX;
|
||||
this.model = rotate90(model);
|
||||
for (TotemBlock[][][] totemBlocks1 : model) {
|
||||
for (TotemBlock[][] totemBlocks2 : totemBlocks1) {
|
||||
for (TotemBlock[] totemBlocks3 : totemBlocks2) {
|
||||
for (TotemBlock totemBlock : totemBlocks3) {
|
||||
totemBlock.rotate90();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public TotemModel mirrorHorizontally() {
|
||||
mirrorHorizontally(model);
|
||||
this.coreZ = model[0].length - this.coreZ - 1;
|
||||
for (TotemBlock[][][] totemBlocks1 : model) {
|
||||
for (TotemBlock[][] totemBlocks2 : totemBlocks1) {
|
||||
for (TotemBlock[] totemBlocks3 : totemBlocks2) {
|
||||
for (TotemBlock totemBlock : totemBlocks3) {
|
||||
totemBlock.mirror(Axis.X);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public TotemModel mirrorVertically() {
|
||||
mirrorVertically(model);
|
||||
this.coreX = model[0][0].length - this.coreX - 1;
|
||||
|
||||
for (TotemBlock[][][] totemBlocks1 : model) {
|
||||
for (TotemBlock[][] totemBlocks2 : totemBlocks1) {
|
||||
for (TotemBlock[] totemBlocks3 : totemBlocks2) {
|
||||
for (TotemBlock totemBlock : totemBlocks3) {
|
||||
totemBlock.mirror(Axis.Z);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isPatternSatisfied(Location location) {
|
||||
Location startLoc = location.clone().subtract(0, coreY, 0);
|
||||
|
||||
int height = model.length;
|
||||
int width = model[0].length;
|
||||
int length = model[0][0].length;
|
||||
|
||||
for (int y = 0; y < height; y++) {
|
||||
Location loc = startLoc.clone().add(-coreX, y, -coreZ);
|
||||
for (int z = 0; z < width; z++) {
|
||||
outer:
|
||||
for (int x = 0; x < length; x++) {
|
||||
for (TotemBlock totemBlock : model[y][z][x]) {
|
||||
if (totemBlock.isRightBlock(loc.clone().add(x, 0, z).getBlock())) {
|
||||
continue outer;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static TotemBlock[][][][] rotate90(TotemBlock[][][][] matrix) {
|
||||
int height = matrix.length;
|
||||
int rows = matrix[0].length;
|
||||
int cols = matrix[0][0].length;
|
||||
TotemBlock[][][][] rotated = new TotemBlock[height][cols][rows][];
|
||||
for (int h = 0; h < height; h++) {
|
||||
for (int r = 0; r < rows; r++) {
|
||||
for (int c = 0; c < cols; c++) {
|
||||
rotated[h][c][rows - 1 - r] = matrix[h][r][c];
|
||||
}
|
||||
}
|
||||
}
|
||||
return rotated;
|
||||
}
|
||||
|
||||
private static void mirrorHorizontally(TotemBlock[][][][] matrix) {
|
||||
int height = matrix.length;
|
||||
int rows = matrix[0].length;
|
||||
int cols = matrix[0][0].length;
|
||||
|
||||
for (int h = 0; h < height; h++) {
|
||||
for (int i = 0; i < rows / 2; i++) {
|
||||
for (int j = 0; j < cols; j++) {
|
||||
TotemBlock[] temp = matrix[h][i][j];
|
||||
matrix[h][i][j] = matrix[h][rows - i - 1][j];
|
||||
matrix[h][rows - i - 1][j] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void mirrorVertically(TotemBlock[][][][] matrix) {
|
||||
int height = matrix.length;
|
||||
int rows = matrix[0].length;
|
||||
int cols = matrix[0][0].length;
|
||||
for (int h = 0; h < height; h++) {
|
||||
for (int i = 0; i < rows; i++) {
|
||||
for (int j = 0; j < cols / 2; j++) {
|
||||
TotemBlock[] temp = matrix[h][i][j];
|
||||
matrix[h][i][j] = matrix[h][i][cols - j - 1];
|
||||
matrix[h][i][cols - j - 1] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) <2022> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customfishing.mechanic.totem.block;
|
||||
|
||||
import net.momirealms.customfishing.mechanic.totem.block.property.TotemBlockProperty;
|
||||
import net.momirealms.customfishing.mechanic.totem.block.type.TypeCondition;
|
||||
import org.bukkit.Axis;
|
||||
import org.bukkit.block.Block;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.StringJoiner;
|
||||
|
||||
public class TotemBlock implements Serializable {
|
||||
|
||||
private final TypeCondition typeCondition;
|
||||
private final TotemBlockProperty[] properties;
|
||||
|
||||
public TotemBlock(TypeCondition typeCondition, TotemBlockProperty[] properties) {
|
||||
this.typeCondition = typeCondition;
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
public TypeCondition getTypeCondition() {
|
||||
return typeCondition;
|
||||
}
|
||||
|
||||
public TotemBlockProperty[] getProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
||||
public boolean isRightBlock(Block block) {
|
||||
if (!typeCondition.isMet(block)) {
|
||||
return false;
|
||||
}
|
||||
for (TotemBlockProperty property : properties) {
|
||||
if (!property.isPropertyMet(block)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void rotate90() {
|
||||
for (TotemBlockProperty property : properties) {
|
||||
property.rotate90();
|
||||
}
|
||||
}
|
||||
|
||||
public void mirror(Axis axis) {
|
||||
for (TotemBlockProperty property : properties) {
|
||||
property.mirror(axis);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the raw text of the totem block.
|
||||
* @return The raw text of the totem block.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
StringJoiner stringJoiner = new StringJoiner(";");
|
||||
for (TotemBlockProperty property : properties) {
|
||||
stringJoiner.add(property.getRawText());
|
||||
}
|
||||
return typeCondition.getRawText() + "{" + stringJoiner + "}";
|
||||
}
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) <2022> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customfishing.mechanic.totem.block.property;
|
||||
|
||||
import org.bukkit.Axis;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.data.Orientable;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Locale;
|
||||
|
||||
public class AxisImpl implements TotemBlockProperty, Serializable {
|
||||
|
||||
private Axis axis;
|
||||
|
||||
public AxisImpl(Axis axis) {
|
||||
this.axis = axis;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TotemBlockProperty mirror(Axis axis) {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rotates the block axis 90 degrees. (X -> Z, Z -> X)
|
||||
* @return The rotated block axis.
|
||||
*/
|
||||
@Override
|
||||
public TotemBlockProperty rotate90() {
|
||||
if (this.axis == Axis.X) {
|
||||
axis = Axis.Z;
|
||||
} else if (this.axis == Axis.Z) {
|
||||
axis = Axis.X;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the block has the property.
|
||||
* @param block The block to check.
|
||||
* @return True if the block has the property.
|
||||
*/
|
||||
@Override
|
||||
public boolean isPropertyMet(Block block) {
|
||||
if (block.getBlockData() instanceof Orientable orientable) {
|
||||
return orientable.getAxis().equals(this.axis);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRawText() {
|
||||
return "axis=" + axis.name().toLowerCase(Locale.ENGLISH);
|
||||
}
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) <2022> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customfishing.mechanic.totem.block.property;
|
||||
|
||||
import org.bukkit.Axis;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.data.Directional;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Locale;
|
||||
|
||||
public class FaceImpl implements TotemBlockProperty, Serializable {
|
||||
|
||||
private BlockFace blockFace;
|
||||
|
||||
public FaceImpl(BlockFace blockFace) {
|
||||
this.blockFace = blockFace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mirrors the block face if the axis is X or Z.
|
||||
* @param axis The axis to mirror.
|
||||
* @return The mirrored block face.
|
||||
*/
|
||||
@Override
|
||||
public TotemBlockProperty mirror(Axis axis) {
|
||||
if (axis == Axis.X) {
|
||||
if (blockFace == BlockFace.SOUTH || blockFace == BlockFace.NORTH) {
|
||||
return new FaceImpl(blockFace.getOppositeFace());
|
||||
} else {
|
||||
return this;
|
||||
}
|
||||
} else if (axis == Axis.Z) {
|
||||
if (blockFace == BlockFace.EAST || blockFace == BlockFace.WEST) {
|
||||
return new FaceImpl(blockFace.getOppositeFace());
|
||||
} else {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TotemBlockProperty rotate90() {
|
||||
switch (blockFace) {
|
||||
case UP, DOWN -> {
|
||||
return this;
|
||||
}
|
||||
case EAST -> blockFace = BlockFace.SOUTH;
|
||||
case SOUTH -> blockFace = BlockFace.WEST;
|
||||
case WEST -> blockFace = BlockFace.NORTH;
|
||||
case NORTH -> blockFace = BlockFace.EAST;
|
||||
default -> throw new IllegalArgumentException("Unsupported block facing: " + blockFace);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPropertyMet(Block block) {
|
||||
if (block.getBlockData() instanceof Directional directional) {
|
||||
return directional.getFacing().equals(this.blockFace);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRawText() {
|
||||
return "face=" + blockFace.name().toLowerCase(Locale.ENGLISH);
|
||||
}
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) <2022> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customfishing.mechanic.totem.block.property;
|
||||
|
||||
import org.bukkit.Axis;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.data.Bisected;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Locale;
|
||||
|
||||
public class HalfImpl implements TotemBlockProperty, Serializable {
|
||||
private final Bisected.Half half;
|
||||
|
||||
public HalfImpl(Bisected.Half half) {
|
||||
this.half = half;
|
||||
}
|
||||
|
||||
/**
|
||||
* half is not affected by mirroring.
|
||||
* @param axis The axis to mirror.
|
||||
* @return this
|
||||
*/
|
||||
@Override
|
||||
public TotemBlockProperty mirror(Axis axis) {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* half is not affected by rotation.
|
||||
* @return this
|
||||
*/
|
||||
@Override
|
||||
public TotemBlockProperty rotate90() {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the block's half is the same as the half of this property.
|
||||
* @param block The block to check.
|
||||
* @return true if the block's half is the same as the half of this property.
|
||||
*/
|
||||
@Override
|
||||
public boolean isPropertyMet(Block block) {
|
||||
if (block.getBlockData() instanceof Bisected bisected) {
|
||||
return bisected.getHalf().equals(this.half);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the raw text of the half property.
|
||||
* @return The raw text of the half property.
|
||||
*/
|
||||
@Override
|
||||
public String getRawText() {
|
||||
return "half=" + half.name().toLowerCase(Locale.ENGLISH);
|
||||
}
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) <2022> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customfishing.mechanic.totem.block.property;
|
||||
|
||||
import org.bukkit.Axis;
|
||||
import org.bukkit.block.Block;
|
||||
|
||||
public interface TotemBlockProperty {
|
||||
|
||||
/**
|
||||
* Mirrors the block face if the axis is X or Z.
|
||||
* @param axis The axis to mirror.
|
||||
* @return The mirrored block face.
|
||||
*/
|
||||
TotemBlockProperty mirror(Axis axis);
|
||||
|
||||
/**
|
||||
* Rotates the block face 90 degrees.
|
||||
* @return The rotated block face.
|
||||
*/
|
||||
TotemBlockProperty rotate90();
|
||||
|
||||
/**
|
||||
* Checks if the block has the property.
|
||||
* @param block The block to check.
|
||||
* @return True if the block has the property.
|
||||
*/
|
||||
boolean isPropertyMet(Block block);
|
||||
|
||||
/**
|
||||
* Gets the raw text of the property.
|
||||
* @return The raw text of the property.
|
||||
*/
|
||||
String getRawText();
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) <2022> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customfishing.mechanic.totem.block.type;
|
||||
|
||||
import net.momirealms.customfishing.api.CustomFishingPlugin;
|
||||
import org.bukkit.block.Block;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class EqualType implements TypeCondition, Serializable {
|
||||
|
||||
private final String type;
|
||||
|
||||
public EqualType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMet(Block type) {
|
||||
return this.type.equals(CustomFishingPlugin.get().getBlockManager().getAnyPluginBlockID(type));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRawText() {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
@@ -22,10 +22,14 @@ import net.momirealms.customfishing.api.common.Tuple;
|
||||
import net.momirealms.customfishing.api.mechanic.loot.WeightModifier;
|
||||
import net.momirealms.customfishing.api.util.LogUtils;
|
||||
import net.momirealms.customfishing.compatibility.papi.PlaceholderManagerImpl;
|
||||
import net.momirealms.customfishing.mechanic.misc.value.ExpressionValue;
|
||||
import net.momirealms.customfishing.mechanic.misc.value.PlainValue;
|
||||
import net.momirealms.customfishing.mechanic.misc.value.Value;
|
||||
import net.objecthunter.exp4j.Expression;
|
||||
import net.objecthunter.exp4j.ExpressionBuilder;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -102,6 +106,38 @@ public class ConfigUtils {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an object into an integer value.
|
||||
*
|
||||
* @param arg The input object
|
||||
* @return An integer value
|
||||
*/
|
||||
public static int getIntegerValue(Object arg) {
|
||||
if (arg instanceof Integer i) {
|
||||
return i;
|
||||
} else if (arg instanceof Double d) {
|
||||
return d.intValue();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an object into a "value".
|
||||
*
|
||||
* @param arg int / double / expression
|
||||
* @return Value
|
||||
*/
|
||||
public static Value getValue(Object arg) {
|
||||
if (arg instanceof Integer i) {
|
||||
return new PlainValue(i);
|
||||
} else if (arg instanceof Double d) {
|
||||
return new PlainValue(d);
|
||||
} else if (arg instanceof String s) {
|
||||
return new ExpressionValue(s);
|
||||
}
|
||||
throw new IllegalArgumentException("Illegal value type");
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a string representing a size range and returns a pair of floats.
|
||||
*
|
||||
@@ -249,19 +285,24 @@ public class ConfigUtils {
|
||||
}
|
||||
case '=' -> {
|
||||
String formula = text.substring(1);
|
||||
boolean hasPapi = PlaceholderManagerImpl.getInstance().hasPapi();
|
||||
return (player, weight) -> {
|
||||
String temp = formula;
|
||||
if (hasPapi)
|
||||
temp = PlaceholderManagerImpl.getInstance().parseCacheablePlaceholders(player, formula);
|
||||
Expression expression = new ExpressionBuilder(temp)
|
||||
.variables("0")
|
||||
.build()
|
||||
.setVariable("0", weight);
|
||||
return expression.evaluate();
|
||||
};
|
||||
return (player, weight) -> getExpressionValue(player, formula, Map.of("0", weight));
|
||||
}
|
||||
default -> throw new IllegalArgumentException("Invalid weight: " + text);
|
||||
}
|
||||
}
|
||||
|
||||
public static double getExpressionValue(Player player, String formula, Map<String, Double> vars) {
|
||||
boolean hasPapi = PlaceholderManagerImpl.getInstance().hasPapi();
|
||||
if (hasPapi)
|
||||
formula = PlaceholderManagerImpl.getInstance().parseCacheablePlaceholders(player, formula);
|
||||
ExpressionBuilder expressionBuilder = new ExpressionBuilder(formula);
|
||||
for (Map.Entry<String, Double> entry : vars.entrySet()) {
|
||||
expressionBuilder.variables(entry.getKey());
|
||||
}
|
||||
Expression expression = expressionBuilder.build();
|
||||
for (Map.Entry<String, Double> entry : vars.entrySet()) {
|
||||
expression.setVariable(entry.getKey(), entry.getValue());
|
||||
}
|
||||
return expression.evaluate();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user