9
0
mirror of https://github.com/Xiao-MoMi/Custom-Fishing.git synced 2026-01-04 15:41:35 +00:00

improved default config

This commit is contained in:
XiaoMoMi
2023-09-09 22:52:38 +08:00
parent 7f9cc4f2c0
commit f3f89480ac
33 changed files with 1052 additions and 335 deletions

View File

@@ -11,7 +11,7 @@ import net.momirealms.customfishing.api.CustomFishingPlugin;
import net.momirealms.customfishing.api.integration.SeasonInterface;
import net.momirealms.customfishing.api.manager.AdventureManager;
import net.momirealms.customfishing.api.mechanic.condition.FishingPreparation;
import net.momirealms.customfishing.api.mechanic.effect.Effect;
import net.momirealms.customfishing.api.mechanic.effect.FishingEffect;
import java.util.ArrayList;
import java.util.List;
@@ -57,7 +57,7 @@ public class DebugCommand {
StringTooltip.ofString("false", "loots in water")
})))
.executesPlayer((player, arg) -> {
Effect initialEffect = CustomFishingPlugin.get().getEffectManager().getInitialEffect();
FishingEffect initialEffect = CustomFishingPlugin.get().getEffectManager().getInitialEffect();
FishingPreparation fishingPreparation = new FishingPreparation(player, CustomFishingPlugin.get());
boolean inLava = (boolean) arg.getOrDefault("lava fishing", false);
fishingPreparation.insertArg("{lava}", String.valueOf(inLava));
@@ -79,7 +79,7 @@ public class DebugCommand {
AdventureManager adventureManager = AdventureManagerImpl.getInstance();
adventureManager.sendMessage(player, "<red>---------- results ---------");
for (LootWithWeight loot : lootArray) {
adventureManager.sendMessage(player, "<hover:show_text:'<blue>GET'><click:run_command:/cfishing items loot get "+ loot.key() + ">" +loot.key() + "</click></hover>: <gold>" + String.format("%.2f", loot.weight()*100/sum) + "% <gray>(" + String.format("%.2f", loot.weight()) + ")");
adventureManager.sendMessage(player, loot.key() + ": <gold>" + String.format("%.2f", loot.weight()*100/sum) + "% <gray>(" + String.format("%.2f", loot.weight()) + ")");
}
adventureManager.sendMessage(player, "<red>----------- end -----------");
});

View File

@@ -23,8 +23,10 @@ import net.momirealms.customfishing.api.common.Pair;
import net.momirealms.customfishing.api.manager.EffectManager;
import net.momirealms.customfishing.api.mechanic.effect.Effect;
import net.momirealms.customfishing.api.mechanic.effect.EffectCarrier;
import net.momirealms.customfishing.api.mechanic.effect.EffectModifier;
import net.momirealms.customfishing.api.mechanic.effect.FishingEffect;
import net.momirealms.customfishing.api.mechanic.loot.Modifier;
import net.momirealms.customfishing.api.mechanic.loot.WeightModifier;
import net.momirealms.customfishing.api.mechanic.requirement.Requirement;
import net.momirealms.customfishing.api.util.LogUtils;
import net.momirealms.customfishing.util.ConfigUtils;
import org.apache.commons.lang3.StringUtils;
@@ -46,6 +48,10 @@ public class EffectManagerImpl implements EffectManager {
this.effectMap = new HashMap<>();
}
public void disable() {
this.effectMap.clear();
}
@Override
public boolean registerEffectItem(Key key, EffectCarrier effect) {
if (effectMap.containsKey(key)) return false;
@@ -107,7 +113,7 @@ public class EffectManagerImpl implements EffectManager {
return new EffectCarrier.Builder()
.key(key)
.requirements(plugin.getRequirementManager().getRequirements(section.getConfigurationSection("requirements"), true))
.effect(getEffectFromSection(section.getConfigurationSection("effects")))
.effect(getEffectModifiers(section.getConfigurationSection("effects")))
.actionMap(plugin.getActionManager().getActionMap(section.getConfigurationSection("events")))
.build();
}
@@ -115,8 +121,10 @@ public class EffectManagerImpl implements EffectManager {
public Effect getEffectFromSection(ConfigurationSection section) {
if (section == null) return getInitialEffect();
return new FishingEffect.Builder()
.lootWeightModifier(ConfigUtils.getModifiers(section.getStringList("weight-single")))
.lootWeightModifier(getGroupModifiers(section.getStringList("weight-group")))
.addWeightModifier(ConfigUtils.getModifiers(section.getStringList("weight-single")))
.addWeightModifier(getGroupModifiers(section.getStringList("weight-group")))
.addWeightModifierIgnored(ConfigUtils.getModifiers(section.getStringList("weight-single-ignore-condition")))
.addWeightModifierIgnored(getGroupModifiers(section.getStringList("weight-group-ignore-condition")))
.timeModifier(section.getDouble("hook-time", 1))
.difficultyModifier(section.getDouble("difficulty", 0))
.multipleLootChance(section.getDouble("multiple-loot", 0))
@@ -138,16 +146,12 @@ public class EffectManagerImpl implements EffectManager {
}
@Override
public Effect getInitialEffect() {
public FishingEffect getInitialEffect() {
return new FishingEffect.Builder().build();
}
public void disable() {
this.effectMap.clear();
}
private List<Pair<String, Modifier>> getGroupModifiers(List<String> modList) {
List<Pair<String, Modifier>> result = new ArrayList<>();
private List<Pair<String, WeightModifier>> getGroupModifiers(List<String> modList) {
List<Pair<String, WeightModifier>> result = new ArrayList<>();
for (String group : modList) {
String[] split = group.split(":",2);
String key = split[0];
@@ -162,4 +166,104 @@ public class EffectManagerImpl implements EffectManager {
}
return result;
}
public EffectModifier[] getEffectModifiers(ConfigurationSection section) {
if (section == null) return new EffectModifier[0];
ArrayList<EffectModifier> modifiers = new ArrayList<>();
for (Map.Entry<String, Object> entry: section.getValues(false).entrySet()) {
if (entry.getValue() instanceof ConfigurationSection inner) {
EffectModifier effectModifier = getEffectModifier(inner);
if (effectModifier != null)
modifiers.add(effectModifier);
}
}
return modifiers.toArray(new EffectModifier[0]);
}
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"));
return ((effect, condition) -> {
effect.addWeightModifier(modList);
});
}
case "weight-mod-ignore-conditions" -> {
var modList = ConfigUtils.getModifiers(section.getStringList("value"));
return ((effect, condition) -> {
effect.addWeightModifierIgnored(modList);
});
}
case "group-mod" -> {
var modList = getGroupModifiers(section.getStringList("value"));
return ((effect, condition) -> {
effect.addWeightModifier(modList);
});
}
case "group-mod-ignore-conditions" -> {
var modList = getGroupModifiers(section.getStringList("value"));
return ((effect, condition) -> {
effect.addWeightModifierIgnored(modList);
});
}
case "hook-time" -> {
double time = section.getDouble("value");
return ((effect, condition) -> {
effect.setHookTimeModifier(effect.getHookTimeModifier() + time - 1);
});
}
case "difficulty" -> {
double difficulty = section.getDouble("value");
return ((effect, condition) -> {
effect.setDifficultyModifier(effect.getDifficultyModifier() + difficulty);
});
}
case "multiple-loot" -> {
double multiple = section.getDouble("value");
return ((effect, condition) -> {
effect.setMultipleLootChance(effect.getMultipleLootChance() + multiple);
});
}
case "score-bonus" -> {
double multiple = section.getDouble("value");
return ((effect, condition) -> {
effect.setScoreMultiplier(effect.getScoreMultiplier() + multiple - 1);
});
}
case "size-bonus" -> {
double multiple = section.getDouble("value");
return ((effect, condition) -> {
effect.setSizeMultiplier(effect.getSizeMultiplier() + multiple - 1);
});
}
case "game-time" -> {
double time = section.getDouble("value");
return ((effect, condition) -> {
effect.setGameTimeModifier(effect.getGameTimeModifier() + time);
});
}
case "lava-fishing" -> {
return ((effect, condition) -> effect.setLavaFishing(true));
}
case "conditional" -> {
Requirement[] requirements = plugin.getRequirementManager().getRequirements(section.getConfigurationSection("conditions"), false);
EffectModifier[] modifiers = getEffectModifiers(section.getConfigurationSection("effects"));
return ((effect, condition) -> {
for (Requirement requirement : requirements)
if (!requirement.isConditionMet(condition))
return;
for (EffectModifier modifier : modifiers) {
modifier.modify(effect, condition);
}
});
}
default -> {
LogUtils.warn("Effect " + type + " doesn't exist.");
return null;
}
}
}
}

View File

@@ -33,12 +33,13 @@ import net.momirealms.customfishing.api.mechanic.competition.FishingCompetition;
import net.momirealms.customfishing.api.mechanic.condition.Condition;
import net.momirealms.customfishing.api.mechanic.condition.FishingPreparation;
import net.momirealms.customfishing.api.mechanic.effect.Effect;
import net.momirealms.customfishing.api.mechanic.effect.FishingEffect;
import net.momirealms.customfishing.api.mechanic.game.GameConfig;
import net.momirealms.customfishing.api.mechanic.game.GameInstance;
import net.momirealms.customfishing.api.mechanic.game.GameSettings;
import net.momirealms.customfishing.api.mechanic.game.GamingPlayer;
import net.momirealms.customfishing.api.mechanic.loot.Loot;
import net.momirealms.customfishing.api.mechanic.loot.Modifier;
import net.momirealms.customfishing.api.mechanic.loot.WeightModifier;
import net.momirealms.customfishing.api.util.LogUtils;
import net.momirealms.customfishing.api.util.WeightUtils;
import net.momirealms.customfishing.mechanic.requirement.RequirementManagerImpl;
@@ -254,7 +255,7 @@ public class FishingManagerImpl implements Listener, FishingManager {
return;
}
// Merge rod/bait/util effects
Effect initialEffect = plugin.getEffectManager().getInitialEffect();
FishingEffect initialEffect = plugin.getEffectManager().getInitialEffect();
fishingPreparation.mergeEffect(initialEffect);
// Apply enchants
@@ -271,8 +272,8 @@ public class FishingManagerImpl implements Listener, FishingManager {
// Store fishhook entity and apply the effects
final FishHook fishHook = event.getHook();
this.hookCacheMap.put(player.getUniqueId(), fishHook);
fishHook.setMaxWaitTime((int) (fishHook.getMaxWaitTime() * initialEffect.getTimeModifier()));
fishHook.setMinWaitTime((int) (fishHook.getMinWaitTime() * initialEffect.getTimeModifier()));
fishHook.setMaxWaitTime((int) (fishHook.getMaxWaitTime() * initialEffect.getHookTimeModifier()));
fishHook.setMinWaitTime((int) (fishHook.getMinWaitTime() * initialEffect.getHookTimeModifier()));
// Reduce amount & Send animation
var baitItem = fishingPreparation.getBaitItemStack();
if (baitItem != null) {
@@ -512,11 +513,7 @@ public class FishingManagerImpl implements Listener, FishingManager {
var effect = state.getEffect();
var fishingPreparation = state.getPreparation();
var player = fishingPreparation.getPlayer();
fishingPreparation.insertArg("{size-multiplier}", String.format("%.2f", effect.getSizeMultiplier()));
fishingPreparation.insertArg("{x}", String.valueOf(hook.getLocation().getBlockX()));
fishingPreparation.insertArg("{y}", String.valueOf(hook.getLocation().getBlockY()));
fishingPreparation.insertArg("{z}", String.valueOf(hook.getLocation().getBlockZ()));
plugin.getScheduler().runTaskSync(() -> {
@@ -618,13 +615,14 @@ public class FishingManagerImpl implements Listener, FishingManager {
@Override
public Map<String, Double> getPossibleLootKeysWithWeight(Effect initialEffect, FishingPreparation fishingPreparation) {
Map<String, Double> lootWithWeight = plugin.getRequirementManager().getLootWithWeight(fishingPreparation);
if (lootWithWeight.size() == 0) {
LogUtils.warn(String.format("No Loot found at %s for Player %s!", fishingPreparation.getPlayer().getLocation(), fishingPreparation.getPlayer().getName()));
return new HashMap<>();
}
Player player = fishingPreparation.getPlayer();
for (Pair<String, Modifier> pair : initialEffect.getLootWeightModifier()) {
for (Pair<String, WeightModifier> pair : initialEffect.getWeightModifier()) {
Double previous = lootWithWeight.get(pair.left());
if (previous != null)
lootWithWeight.put(pair.left(), pair.right().modify(player, previous));
}
for (Pair<String, WeightModifier> pair : initialEffect.getWeightModifierIgnored()) {
double previous = lootWithWeight.getOrDefault(pair.left(), 0d);
lootWithWeight.put(pair.left(), pair.right().modify(player, previous));
}

View File

@@ -176,7 +176,7 @@ public class HookCheckTimerTask implements Runnable {
// get random time
int random = ThreadLocalRandom.current().nextInt(Config.lavaMinTime, Config.lavaMaxTime);
random -= lureLevel * 100;
random *= initialEffect.getTimeModifier();
random *= initialEffect.getHookTimeModifier();
random = Math.max(Config.lavaMinTime, random);
// lava effect task (Three seconds in advance)

View File

@@ -22,6 +22,7 @@ import net.momirealms.customfishing.adventure.AdventureManagerImpl;
import net.momirealms.customfishing.api.CustomFishingPlugin;
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.manager.ItemManager;
import net.momirealms.customfishing.api.mechanic.item.BuildableItem;
import net.momirealms.customfishing.api.mechanic.item.ItemBuilder;
@@ -228,10 +229,12 @@ public class ItemManagerImpl implements ItemManager {
.itemFlag(section.getStringList("item-flags").stream().map(flag -> ItemFlag.valueOf(flag.toUpperCase())).toList())
.enchantment(getEnchantmentPair(section.getConfigurationSection("enchantments")), false)
.enchantment(getEnchantmentPair(section.getConfigurationSection("stored-enchantments")), true)
.randomEnchantments(getEnchantmentTuple(section.getConfigurationSection("random-enchantments")), false)
.randomEnchantments(getEnchantmentTuple(section.getConfigurationSection("random-stored-enchantments")), true)
.tag(section.getBoolean("tag", true), type, id)
.randomDamage(section.getBoolean("random-durability", false))
.unbreakable(section.getBoolean("unbreakable", false))
.preventGrabbing(section.getBoolean("prevent-grabbing", false))
.preventGrabbing(section.getBoolean("prevent-grabbing", true))
.head(section.getString("head64"))
.name(section.getString("display.name"))
.lore(section.getStringList("display.lore"));
@@ -295,7 +298,26 @@ public class ItemManagerImpl implements ItemManager {
List<Pair<String, Short>> list = new ArrayList<>();
if (section == null) return list;
for (Map.Entry<String, Object> entry : section.getValues(false).entrySet()) {
list.add(Pair.of(entry.getKey(), (short) entry.getValue()));
if (entry.getValue() instanceof Integer integer) {
list.add(Pair.of(entry.getKey(), Short.valueOf(String.valueOf(integer))));
}
}
return list;
}
@NotNull
private List<Tuple<Double, String, Short>> getEnchantmentTuple(ConfigurationSection section) {
List<Tuple<Double, String, Short>> list = new ArrayList<>();
if (section == null) return list;
for (Map.Entry<String, Object> entry : section.getValues(false).entrySet()) {
if (entry.getValue() instanceof ConfigurationSection inner) {
Tuple<Double, String, Short> tuple = Tuple.of(
inner.getDouble("chance"),
inner.getString("enchant"),
Short.valueOf(String.valueOf(inner.getInt("level")))
);
list.add(tuple);
}
}
return list;
}
@@ -439,6 +461,24 @@ public class ItemManagerImpl implements ItemManager {
return this;
}
@Override
public ItemBuilder randomEnchantments(List<Tuple<Double, String, Short>> enchantments, boolean store) {
if (enchantments.size() == 0) return this;
editors.put("random-enchantment", (player, nbtItem, placeholders) -> {
NBTCompoundList list = nbtItem.getCompoundList(store ? "StoredEnchantments" : "Enchantments");
HashSet<String> ids = new HashSet<>();
for (Tuple<Double, String, Short> pair : enchantments) {
if (Math.random() < pair.getLeft() && !ids.contains(pair.getMid())) {
NBTCompound nbtCompound = list.addCompound();
nbtCompound.setString("id", pair.getMid());
nbtCompound.setShort("lvl", pair.getRight());
ids.add(pair.getMid());
}
}
});
return this;
}
@Override
public ItemBuilder maxDurability(int max) {
if (max == 0) return this;
@@ -528,6 +568,8 @@ public class ItemManagerImpl implements ItemManager {
int dur = ThreadLocalRandom.current().nextInt(i);
cfCompound.setInteger("cur_dur", dur);
nbtItem.setInteger("Damage", (int) (nbtItem.getItem().getType().getMaxDurability() * ((double) dur / i)));
} else {
nbtItem.setInteger("Damage", ThreadLocalRandom.current().nextInt(nbtItem.getItem().getType().getMaxDurability()));
}
} else {
nbtItem.setInteger("Damage", ThreadLocalRandom.current().nextInt(nbtItem.getItem().getType().getMaxDurability()));

View File

@@ -126,8 +126,8 @@ public class LootManagerImpl implements LootManager {
.disableGames(section.getBoolean("disable-game", false))
.instantGame(section.getBoolean("instant-game", false))
.showInFinder(section.getBoolean("show-in-fishfinder", true))
.gameConfig(section.getString("game-group"))
.lootGroup(ConfigUtils.stringListArgs(section.get("loot-group")).toArray(new String[0]))
.gameConfig(section.getString("game"))
.lootGroup(ConfigUtils.stringListArgs(section.get("group")).toArray(new String[0]))
.nick(section.getString("nick", section.getString("display.name", key)))
.addActions(plugin.getActionManager().getActionMap(section.getConfigurationSection("events")))
.addTimesActions(getTimesActionMap(section.getConfigurationSection("events.success-times")))

View File

@@ -1,41 +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.requirement;
import net.momirealms.customfishing.api.mechanic.action.Action;
import net.momirealms.customfishing.api.mechanic.condition.Condition;
import net.momirealms.customfishing.api.mechanic.requirement.Requirement;
import java.util.List;
public abstract class AbstractRequirement implements Requirement {
private final List<Action> actions;
public AbstractRequirement(List<Action> actions) {
this.actions = actions;
}
protected void triggerActions(Condition condition) {
if (actions != null) {
for (Action action : actions) {
action.trigger(condition);
}
}
}
}

View File

@@ -19,7 +19,7 @@ package net.momirealms.customfishing.mechanic.requirement;
import net.momirealms.customfishing.api.common.Pair;
import net.momirealms.customfishing.api.mechanic.condition.Condition;
import net.momirealms.customfishing.api.mechanic.loot.Modifier;
import net.momirealms.customfishing.api.mechanic.loot.WeightModifier;
import net.momirealms.customfishing.api.mechanic.requirement.Requirement;
import org.bukkit.entity.Player;
@@ -28,13 +28,13 @@ import java.util.List;
public class ConditionalLoots {
private final List<Pair<String, Modifier>> modifierList;
private final List<Pair<String, WeightModifier>> modifierList;
private final HashMap<String, ConditionalLoots> subLoots;
private final Requirement[] requirements;
public ConditionalLoots(
Requirement[] requirements,
List<Pair<String, Modifier>> modifierList,
List<Pair<String, WeightModifier>> modifierList,
HashMap<String, ConditionalLoots> subLoots
) {
this.modifierList = modifierList;
@@ -43,7 +43,7 @@ public class ConditionalLoots {
}
synchronized public void combine(Player player, HashMap<String, Double> weightMap) {
for (Pair<String, Modifier> modifierPair : this.modifierList) {
for (Pair<String, WeightModifier> modifierPair : this.modifierList) {
double previous = weightMap.getOrDefault(modifierPair.left(), 0d);
weightMap.put(modifierPair.left(), modifierPair.right().modify(player, previous));
}

View File

@@ -187,6 +187,7 @@ public class RequirementManagerImpl implements RequirementManager {
@NotNull
@Override
public Requirement getRequirement(ConfigurationSection section, boolean advanced) {
if (section == null) return EmptyRequirement.instance;
List<Action> actionList = null;
if (advanced) {
actionList = new ArrayList<>();
@@ -301,7 +302,7 @@ public class RequirementManagerImpl implements RequirementManager {
}
private void registerInLavaRequirement() {
registerRequirement("in-lava", (args, actions, advanced) -> {
registerRequirement("lava-fishing", (args, actions, advanced) -> {
boolean inLava = (boolean) args;
return condition -> {
String current = condition.getArgs().get("{lava}");
@@ -693,7 +694,7 @@ public class RequirementManagerImpl implements RequirementManager {
registerRequirement("rod", (args, actions, advanced) -> {
List<String> rods = ConfigUtils.stringListArgs(args);
return condition -> {
String id = condition.getArg("rod");
String id = condition.getArg("{rod}");
if (rods.contains(id)) return true;
if (advanced) triggerActions(actions, condition);
return false;
@@ -702,7 +703,7 @@ public class RequirementManagerImpl implements RequirementManager {
registerRequirement("!rod", (args, actions, advanced) -> {
List<String> rods = ConfigUtils.stringListArgs(args);
return condition -> {
String id = condition.getArg("rod");
String id = condition.getArg("{rod}");
if (!rods.contains(id)) return true;
if (advanced) triggerActions(actions, condition);
return false;
@@ -714,7 +715,7 @@ public class RequirementManagerImpl implements RequirementManager {
registerRequirement("bait", (args, actions, advanced) -> {
List<String> baits = ConfigUtils.stringListArgs(args);
return condition -> {
String id = condition.getArg("bait");
String id = condition.getArg("{bait}");
if (baits.contains(id)) return true;
if (advanced) triggerActions(actions, condition);
return false;
@@ -723,7 +724,7 @@ public class RequirementManagerImpl implements RequirementManager {
registerRequirement("!bait", (args, actions, advanced) -> {
List<String> baits = ConfigUtils.stringListArgs(args);
return condition -> {
String id = condition.getArg("bait");
String id = condition.getArg("{bait}");
if (!baits.contains(id)) return true;
if (advanced) triggerActions(actions, condition);
return false;
@@ -761,6 +762,7 @@ public class RequirementManagerImpl implements RequirementManager {
action.trigger(condition);
}
@SuppressWarnings("ResultOfMethodCallIgnored")
private void loadExpansions() {
File expansionFolder = new File(plugin.getDataFolder(), EXPANSION_FOLDER);
if (!expansionFolder.exists())

View File

@@ -18,7 +18,7 @@
package net.momirealms.customfishing.util;
import net.momirealms.customfishing.api.common.Pair;
import net.momirealms.customfishing.api.mechanic.loot.Modifier;
import net.momirealms.customfishing.api.mechanic.loot.WeightModifier;
import net.momirealms.customfishing.api.util.LogUtils;
import net.momirealms.customfishing.compatibility.papi.PlaceholderManagerImpl;
import net.objecthunter.exp4j.Expression;
@@ -70,8 +70,8 @@ public class ConfigUtils {
return 0;
}
public static List<Pair<String, Modifier>> getModifiers(List<String> modList) {
List<Pair<String, Modifier>> result = new ArrayList<>(modList.size());
public static List<Pair<String, WeightModifier>> getModifiers(List<String> modList) {
List<Pair<String, WeightModifier>> result = new ArrayList<>(modList.size());
for (String member : modList) {
String[] split = member.split(":",2);
String key = split[0];
@@ -99,7 +99,7 @@ public class ConfigUtils {
return YamlConfiguration.loadConfiguration(file);
}
public static Modifier getModifier(String text) {
public static WeightModifier getModifier(String text) {
if (text.length() == 0) {
throw new IllegalArgumentException("Weight format is invalid.");
}