9
0
mirror of https://github.com/Xiao-MoMi/Custom-Fishing.git synced 2025-12-21 07:59:23 +00:00

additional operations for loot

This commit is contained in:
XiaoMoMi
2025-01-03 19:18:16 +08:00
parent 1fd3617fe5
commit 03d481e476
17 changed files with 382 additions and 88 deletions

View File

@@ -37,6 +37,7 @@ import net.momirealms.customfishing.api.mechanic.entity.EntityConfig;
import net.momirealms.customfishing.api.mechanic.event.EventCarrier; import net.momirealms.customfishing.api.mechanic.event.EventCarrier;
import net.momirealms.customfishing.api.mechanic.hook.HookConfig; import net.momirealms.customfishing.api.mechanic.hook.HookConfig;
import net.momirealms.customfishing.api.mechanic.loot.Loot; import net.momirealms.customfishing.api.mechanic.loot.Loot;
import net.momirealms.customfishing.api.mechanic.loot.operation.WeightOperation;
import net.momirealms.customfishing.api.mechanic.requirement.Requirement; import net.momirealms.customfishing.api.mechanic.requirement.Requirement;
import net.momirealms.customfishing.api.mechanic.totem.TotemConfig; import net.momirealms.customfishing.api.mechanic.totem.TotemConfig;
import net.momirealms.customfishing.common.config.ConfigLoader; import net.momirealms.customfishing.common.config.ConfigLoader;
@@ -59,7 +60,6 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Function; import java.util.function.Function;
@@ -471,9 +471,9 @@ public abstract class ConfigManager implements ConfigLoader, Reloadable {
return lootFormatFunctions; return lootFormatFunctions;
} }
public abstract List<Pair<String, BiFunction<Context<Player>, Double, Double>>> parseWeightOperation(List<String> ops); public abstract List<Pair<String, WeightOperation>> parseWeightOperation(List<String> ops, Function<String, Boolean> validator);
public abstract List<Pair<String, BiFunction<Context<Player>, Double, Double>>> parseGroupWeightOperation(List<String> gops); public abstract List<Pair<String, WeightOperation>> parseGroupWeightOperation(List<String> gops);
@Deprecated @Deprecated
public Map<String, Node<ConfigParserFunction>> getDefaultFormatFunctions() { public Map<String, Node<ConfigParserFunction>> getDefaultFormatFunctions() {

View File

@@ -76,6 +76,7 @@ public class ContextKeys<T> {
public static final ContextKeys<Integer> AMOUNT = of("amount", Integer.class); public static final ContextKeys<Integer> AMOUNT = of("amount", Integer.class);
public static final ContextKeys<Integer> TOTAL_AMOUNT = of("total_amount", Integer.class); public static final ContextKeys<Integer> TOTAL_AMOUNT = of("total_amount", Integer.class);
public static final ContextKeys<Double> WEIGHT = of("0", Double.class); public static final ContextKeys<Double> WEIGHT = of("0", Double.class);
public static final ContextKeys<Double> TOTAL_WEIGHT = of("1", Double.class);
public static final ContextKeys<String> TIME_LEFT = of("time_left", String.class); public static final ContextKeys<String> TIME_LEFT = of("time_left", String.class);
public static final ContextKeys<String> PROGRESS = of("progress", String.class); public static final ContextKeys<String> PROGRESS = of("progress", String.class);
public static final ContextKeys<Float> RECORD = of("record", Float.class); public static final ContextKeys<Float> RECORD = of("record", Float.class);

View File

@@ -17,13 +17,11 @@
package net.momirealms.customfishing.api.mechanic.effect; package net.momirealms.customfishing.api.mechanic.effect;
import net.momirealms.customfishing.api.mechanic.context.Context; import net.momirealms.customfishing.api.mechanic.loot.operation.WeightOperation;
import net.momirealms.customfishing.common.util.Pair; import net.momirealms.customfishing.common.util.Pair;
import org.bukkit.entity.Player;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.function.BiFunction;
/** /**
* Represents an effect applied in the fishing. * Represents an effect applied in the fishing.
@@ -234,7 +232,7 @@ public interface Effect {
* *
* @return the list of weight operations * @return the list of weight operations
*/ */
List<Pair<String, BiFunction<Context<Player>, Double, Double>>> weightOperations(); List<Pair<String, WeightOperation>> weightOperations();
/** /**
* Adds the list of weight operations. * Adds the list of weight operations.
@@ -242,14 +240,14 @@ public interface Effect {
* @param weightOperations the list of weight operations to add * @param weightOperations the list of weight operations to add
* @return the effect instance * @return the effect instance
*/ */
Effect weightOperations(List<Pair<String, BiFunction<Context<Player>, Double, Double>>> weightOperations); Effect weightOperations(List<Pair<String, WeightOperation>> weightOperations);
/** /**
* Gets the list of weight operations that are conditions ignored. * Gets the list of weight operations that are conditions ignored.
* *
* @return the list of weight operations that are conditions ignored * @return the list of weight operations that are conditions ignored
*/ */
List<Pair<String, BiFunction<Context<Player>, Double, Double>>> weightOperationsIgnored(); List<Pair<String, WeightOperation>> weightOperationsIgnored();
/** /**
* Adds the list of weight operations that are conditions ignored. * Adds the list of weight operations that are conditions ignored.
@@ -257,7 +255,7 @@ public interface Effect {
* @param weightOperations the list of weight operations that are conditions ignored * @param weightOperations the list of weight operations that are conditions ignored
* @return the effect instance * @return the effect instance
*/ */
Effect weightOperationsIgnored(List<Pair<String, BiFunction<Context<Player>, Double, Double>>> weightOperations); Effect weightOperationsIgnored(List<Pair<String, WeightOperation>> weightOperations);
/** /**
* Combines this effect with another effect. * Combines this effect with another effect.

View File

@@ -1,14 +1,12 @@
package net.momirealms.customfishing.api.mechanic.effect; package net.momirealms.customfishing.api.mechanic.effect;
import net.momirealms.customfishing.api.mechanic.context.Context; import net.momirealms.customfishing.api.mechanic.loot.operation.WeightOperation;
import net.momirealms.customfishing.common.util.Pair; import net.momirealms.customfishing.common.util.Pair;
import org.bukkit.entity.Player;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.function.BiFunction;
public class EffectImpl implements Effect { public class EffectImpl implements Effect {
@@ -24,8 +22,8 @@ public class EffectImpl implements Effect {
private double waitTimeMultiplier = 1; private double waitTimeMultiplier = 1;
private double difficultyAdder = 0; private double difficultyAdder = 0;
private double difficultyMultiplier = 1; private double difficultyMultiplier = 1;
private final List<Pair<String, BiFunction<Context<Player>, Double, Double>>> weightOperations = new ArrayList<>(); private final List<Pair<String, WeightOperation>> weightOperations = new ArrayList<>();
private final List<Pair<String, BiFunction<Context<Player>, Double, Double>>> weightOperationsIgnored = new ArrayList<>(); private final List<Pair<String, WeightOperation>> weightOperationsIgnored = new ArrayList<>();
@Override @Override
public Map<EffectProperties<?>, Object> properties() { public Map<EffectProperties<?>, Object> properties() {
@@ -172,23 +170,23 @@ public class EffectImpl implements Effect {
} }
@Override @Override
public List<Pair<String, BiFunction<Context<Player>, Double, Double>>> weightOperations() { public List<Pair<String, WeightOperation>> weightOperations() {
return weightOperations; return weightOperations;
} }
@Override @Override
public Effect weightOperations(List<Pair<String, BiFunction<Context<Player>, Double, Double>>> weightOperations) { public Effect weightOperations(List<Pair<String, WeightOperation>> weightOperations) {
this.weightOperations.addAll(weightOperations); this.weightOperations.addAll(weightOperations);
return this; return this;
} }
@Override @Override
public List<Pair<String, BiFunction<Context<Player>, Double, Double>>> weightOperationsIgnored() { public List<Pair<String, WeightOperation>> weightOperationsIgnored() {
return weightOperationsIgnored; return weightOperationsIgnored;
} }
@Override @Override
public Effect weightOperationsIgnored(List<Pair<String, BiFunction<Context<Player>, Double, Double>>> weightOperations) { public Effect weightOperationsIgnored(List<Pair<String, WeightOperation>> weightOperations) {
this.weightOperationsIgnored.addAll(weightOperations); this.weightOperationsIgnored.addAll(weightOperations);
return this; return this;
} }

View File

@@ -0,0 +1,38 @@
/*
* Copyright (C) <2024> <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.api.mechanic.loot.operation;
import net.momirealms.customfishing.api.mechanic.context.Context;
import net.momirealms.customfishing.api.mechanic.misc.value.MathValue;
import org.bukkit.entity.Player;
import java.util.Map;
public class AddWeightOperation implements WeightOperation {
private final MathValue<Player> arg;
public AddWeightOperation(MathValue<Player> arg) {
this.arg = arg;
}
@Override
public Double apply(Context<Player> context, Double weight, Map<String, Double> weights) {
return weight + arg.evaluate(context);
}
}

View File

@@ -0,0 +1,64 @@
/*
* Copyright (C) <2024> <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.api.mechanic.loot.operation;
import net.momirealms.customfishing.api.mechanic.context.Context;
import net.momirealms.customfishing.api.mechanic.context.ContextKeys;
import net.momirealms.customfishing.api.mechanic.misc.value.MathValue;
import org.bukkit.entity.Player;
import java.util.Collection;
import java.util.List;
import java.util.Map;
public class CustomWeightOperation implements WeightOperation {
private final MathValue<Player> arg;
private final boolean hasTotalWeight;
private final List<String> otherWeights;
public CustomWeightOperation(MathValue<Player> arg, boolean hasTotalWeight, List<String> otherWeights) {
this.arg = arg;
this.hasTotalWeight = hasTotalWeight;
this.otherWeights = otherWeights;
}
@Override
public Double apply(Context<Player> context, Double weight, Map<String, Double> weights) {
context.arg(ContextKeys.WEIGHT, weight);
if (hasTotalWeight) {
context.arg(ContextKeys.TOTAL_WEIGHT, getValidTotalWeight(weights.values()));
}
if (!otherWeights.isEmpty()) {
for (String otherWeight : otherWeights) {
context.arg(ContextKeys.of("loot_" + otherWeight, Double.class), weights.get(otherWeight));
}
}
return arg.evaluate(context);
}
private double getValidTotalWeight(Collection<Double> weights) {
double totalWeight = 0;
for (Double weight : weights) {
if (weight > 0) {
totalWeight += weight;
}
}
return totalWeight;
}
}

View File

@@ -0,0 +1,38 @@
/*
* Copyright (C) <2024> <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.api.mechanic.loot.operation;
import net.momirealms.customfishing.api.mechanic.context.Context;
import net.momirealms.customfishing.api.mechanic.misc.value.MathValue;
import org.bukkit.entity.Player;
import java.util.Map;
public class DivideWeightOperation implements WeightOperation {
private final MathValue<Player> arg;
public DivideWeightOperation(MathValue<Player> arg) {
this.arg = arg;
}
@Override
public Double apply(Context<Player> context, Double weight, Map<String, Double> weights) {
return weight / arg.evaluate(context);
}
}

View File

@@ -0,0 +1,38 @@
/*
* Copyright (C) <2024> <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.api.mechanic.loot.operation;
import net.momirealms.customfishing.api.mechanic.context.Context;
import net.momirealms.customfishing.api.mechanic.misc.value.MathValue;
import org.bukkit.entity.Player;
import java.util.Map;
public class ModuloWeightOperation implements WeightOperation {
private final MathValue<Player> arg;
public ModuloWeightOperation(MathValue<Player> arg) {
this.arg = arg;
}
@Override
public Double apply(Context<Player> context, Double weight, Map<String, Double> weights) {
return weight % arg.evaluate(context);
}
}

View File

@@ -0,0 +1,38 @@
/*
* Copyright (C) <2024> <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.api.mechanic.loot.operation;
import net.momirealms.customfishing.api.mechanic.context.Context;
import net.momirealms.customfishing.api.mechanic.misc.value.MathValue;
import org.bukkit.entity.Player;
import java.util.Map;
public class MultiplyWeightOperation implements WeightOperation {
private final MathValue<Player> arg;
public MultiplyWeightOperation(MathValue<Player> arg) {
this.arg = arg;
}
@Override
public Double apply(Context<Player> context, Double weight, Map<String, Double> weights) {
return weight * arg.evaluate(context);
}
}

View File

@@ -0,0 +1,38 @@
/*
* Copyright (C) <2024> <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.api.mechanic.loot.operation;
import net.momirealms.customfishing.api.mechanic.context.Context;
import net.momirealms.customfishing.api.mechanic.misc.value.MathValue;
import org.bukkit.entity.Player;
import java.util.Map;
public class ReduceWeightOperation implements WeightOperation {
private final MathValue<Player> arg;
public ReduceWeightOperation(MathValue<Player> arg) {
this.arg = arg;
}
@Override
public Double apply(Context<Player> context, Double weight, Map<String, Double> weights) {
return weight - arg.evaluate(context);
}
}

View File

@@ -0,0 +1,28 @@
/*
* Copyright (C) <2024> <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.api.mechanic.loot.operation;
import net.momirealms.customfishing.api.mechanic.context.Context;
import net.momirealms.customfishing.common.util.TriFunction;
import org.bukkit.entity.Player;
import java.util.Map;
@FunctionalInterface
public interface WeightOperation extends TriFunction<Context<Player>, Double, Map<String, Double>, Double> {
}

View File

@@ -184,7 +184,7 @@ public class BukkitCustomFishingPluginImpl extends BukkitCustomFishingPlugin {
this.actionManager.reload(); this.actionManager.reload();
this.requirementManager.reload(); this.requirementManager.reload();
this.gameManager.reload(); this.gameManager.unload();
// before ConfigManager // before ConfigManager
this.placeholderManager.reload(); this.placeholderManager.reload();
@@ -205,6 +205,7 @@ public class BukkitCustomFishingPluginImpl extends BukkitCustomFishingPlugin {
this.eventManager.load(); this.eventManager.load();
this.entityManager.load(); this.entityManager.load();
this.lootManager.load(); this.lootManager.load();
this.gameManager.load();
this.blockManager.load(); this.blockManager.load();
this.effectManager.load(); this.effectManager.load();
this.hookManager.load(); this.hookManager.load();

View File

@@ -48,6 +48,8 @@ import net.momirealms.customfishing.api.mechanic.effect.EffectProperties;
import net.momirealms.customfishing.api.mechanic.event.EventManager; import net.momirealms.customfishing.api.mechanic.event.EventManager;
import net.momirealms.customfishing.api.mechanic.item.ItemEditor; import net.momirealms.customfishing.api.mechanic.item.ItemEditor;
import net.momirealms.customfishing.api.mechanic.loot.Loot; import net.momirealms.customfishing.api.mechanic.loot.Loot;
import net.momirealms.customfishing.api.mechanic.loot.operation.*;
import net.momirealms.customfishing.api.mechanic.misc.placeholder.BukkitPlaceholderManager;
import net.momirealms.customfishing.api.mechanic.misc.value.MathValue; import net.momirealms.customfishing.api.mechanic.misc.value.MathValue;
import net.momirealms.customfishing.api.mechanic.misc.value.TextValue; import net.momirealms.customfishing.api.mechanic.misc.value.TextValue;
import net.momirealms.customfishing.api.mechanic.requirement.Requirement; import net.momirealms.customfishing.api.mechanic.requirement.Requirement;
@@ -90,18 +92,20 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.*; import java.util.*;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Function; import java.util.function.Function;
public class BukkitConfigManager extends ConfigManager { public class BukkitConfigManager extends ConfigManager {
private static YamlDocument MAIN_CONFIG; private static YamlDocument MAIN_CONFIG;
private static Particle dustParticle; private static Particle dustParticle;
public static YamlDocument getMainConfig() { public static YamlDocument getMainConfig() {
return MAIN_CONFIG; return MAIN_CONFIG;
} }
private Function<String, Boolean> lootValidator = (id) -> {
return plugin.getLootManager().getLoot(id).isPresent();
};
public BukkitConfigManager(BukkitCustomFishingPlugin plugin) { public BukkitConfigManager(BukkitCustomFishingPlugin plugin) {
super(plugin); super(plugin);
this.registerBuiltInItemProperties(); this.registerBuiltInItemProperties();
@@ -627,7 +631,7 @@ public class BukkitConfigManager extends ConfigManager {
})); }));
} }
case "weight-mod" -> { case "weight-mod" -> {
var op = parseWeightOperation(section.getStringList("value")); var op = parseWeightOperation(section.getStringList("value"), lootValidator);
return (((effect, context, phase) -> { return (((effect, context, phase) -> {
if (phase == 1) { if (phase == 1) {
effect.weightOperations(op); effect.weightOperations(op);
@@ -636,7 +640,7 @@ public class BukkitConfigManager extends ConfigManager {
})); }));
} }
case "weight-mod-ignore-conditions" -> { case "weight-mod-ignore-conditions" -> {
var op = parseWeightOperation(section.getStringList("value")); var op = parseWeightOperation(section.getStringList("value"), lootValidator);
return (((effect, context, phase) -> { return (((effect, context, phase) -> {
if (phase == 1) { if (phase == 1) {
effect.weightOperationsIgnored(op); effect.weightOperationsIgnored(op);
@@ -782,63 +786,73 @@ public class BukkitConfigManager extends ConfigManager {
} }
} }
private BiFunction<Context<Player>, Double, Double> parseWeightOperation(String op) { private WeightOperation parseWeightOperation(String op) {
switch (op.charAt(0)) { switch (op.charAt(0)) {
case '/' -> { case '/' -> {
MathValue<Player> arg = MathValue.auto(op.substring(1)); MathValue<Player> arg = MathValue.auto(op.substring(1));
return (context, weight) -> weight / arg.evaluate(context); return new DivideWeightOperation(arg);
} }
case '*' -> { case '*' -> {
MathValue<Player> arg = MathValue.auto(op.substring(1)); MathValue<Player> arg = MathValue.auto(op.substring(1));
return (context, weight) -> weight * arg.evaluate(context); return new MultiplyWeightOperation(arg);
} }
case '-' -> { case '-' -> {
MathValue<Player> arg = MathValue.auto(op.substring(1)); MathValue<Player> arg = MathValue.auto(op.substring(1));
return (context, weight) -> weight - arg.evaluate(context); return new ReduceWeightOperation(arg);
} }
case '%' -> { case '%' -> {
MathValue<Player> arg = MathValue.auto(op.substring(1)); MathValue<Player> arg = MathValue.auto(op.substring(1));
return (context, weight) -> weight % arg.evaluate(context); return new ModuloWeightOperation(arg);
} }
case '+' -> { case '+' -> {
MathValue<Player> arg = MathValue.auto(op.substring(1)); MathValue<Player> arg = MathValue.auto(op.substring(1));
return (context, weight) -> weight + arg.evaluate(context); return new AddWeightOperation(arg);
} }
case '=' -> { case '=' -> {
MathValue<Player> arg = MathValue.auto(op.substring(1)); String expression = op.substring(1);
return (context, weight) -> { MathValue<Player> arg = MathValue.auto(expression);
context.arg(ContextKeys.WEIGHT, weight); List<String> placeholders = BukkitPlaceholderManager.getInstance().resolvePlaceholders(expression);
return arg.evaluate(context); List<String> otherWeights = new ArrayList<>();
}; for (String placeholder : placeholders) {
if (placeholder.startsWith("{loot_")) {
otherWeights.add(placeholder.substring("{loot_".length(), placeholder.length() - 1));
}
}
return new CustomWeightOperation(arg, expression.contains("{1}"), otherWeights);
} }
default -> throw new IllegalArgumentException("Invalid weight operation: " + op); default -> throw new IllegalArgumentException("Invalid weight operation: " + op);
} }
} }
@Override @Override
public List<Pair<String, BiFunction<Context<Player>, Double, Double>>> parseWeightOperation(List<String> ops) { public List<Pair<String, WeightOperation>> parseWeightOperation(List<String> ops, Function<String, Boolean> validator) {
List<Pair<String, BiFunction<Context<Player>, Double, Double>>> result = new ArrayList<>(); List<Pair<String, WeightOperation>> result = new ArrayList<>();
for (String op : ops) { for (String op : ops) {
String[] split = op.split(":", 2); String[] split = op.split(":", 2);
if (split.length < 2) { if (split.length < 2) {
plugin.getPluginLogger().warn("Illegal weight operation: " + op); plugin.getPluginLogger().warn("Illegal weight operation: " + op);
continue; continue;
} }
result.add(Pair.of(split[0], parseWeightOperation(split[1]))); String id = split[0];
if (!validator.apply(id)) {
plugin.getPluginLogger().warn("Illegal weight operation: " + op + ". Id " + id + " is not valid");
continue;
}
result.add(Pair.of(id, parseWeightOperation(split[1])));
} }
return result; return result;
} }
@Override @Override
public List<Pair<String, BiFunction<Context<Player>, Double, Double>>> parseGroupWeightOperation(List<String> gops) { public List<Pair<String, WeightOperation>> parseGroupWeightOperation(List<String> gops) {
List<Pair<String, BiFunction<Context<Player>, Double, Double>>> result = new ArrayList<>(); List<Pair<String, WeightOperation>> result = new ArrayList<>();
for (String gop : gops) { for (String gop : gops) {
String[] split = gop.split(":", 2); String[] split = gop.split(":", 2);
if (split.length < 2) { if (split.length < 2) {
plugin.getPluginLogger().warn("Illegal weight operation: " + gop); plugin.getPluginLogger().warn("Illegal weight operation: " + gop);
continue; continue;
} }
BiFunction<Context<Player>, Double, Double> operation = parseWeightOperation(split[1]); WeightOperation operation = parseWeightOperation(split[1]);
for (String member : plugin.getLootManager().getGroupMembers(split[0])) { for (String member : plugin.getLootManager().getGroupMembers(split[0])) {
result.add(Pair.of(member, operation)); result.add(Pair.of(member, operation));
} }

View File

@@ -27,6 +27,7 @@ import net.momirealms.customfishing.api.mechanic.context.ContextKeys;
import net.momirealms.customfishing.api.mechanic.effect.Effect; import net.momirealms.customfishing.api.mechanic.effect.Effect;
import net.momirealms.customfishing.api.mechanic.fishing.CustomFishingHook; import net.momirealms.customfishing.api.mechanic.fishing.CustomFishingHook;
import net.momirealms.customfishing.api.mechanic.game.*; import net.momirealms.customfishing.api.mechanic.game.*;
import net.momirealms.customfishing.api.mechanic.loot.operation.WeightOperation;
import net.momirealms.customfishing.api.mechanic.misc.value.MathValue; import net.momirealms.customfishing.api.mechanic.misc.value.MathValue;
import net.momirealms.customfishing.api.mechanic.misc.value.TextValue; import net.momirealms.customfishing.api.mechanic.misc.value.TextValue;
import net.momirealms.customfishing.api.mechanic.requirement.ConditionalElement; import net.momirealms.customfishing.api.mechanic.requirement.ConditionalElement;
@@ -52,7 +53,7 @@ public class BukkitGameManager implements GameManager {
private final BukkitCustomFishingPlugin plugin; private final BukkitCustomFishingPlugin plugin;
private final Map<String, GameFactory> gameFactoryMap = new HashMap<>(); private final Map<String, GameFactory> gameFactoryMap = new HashMap<>();
private final Map<String, Game> gameMap = new HashMap<>(); private final Map<String, Game> gameMap = new HashMap<>();
private final LinkedHashMap<String, ConditionalElement<List<Pair<String, BiFunction<Context<Player>, Double, Double>>>, Player>> gameConditions = new LinkedHashMap<>(); private final LinkedHashMap<String, ConditionalElement<List<Pair<String, WeightOperation>>, Player>> gameConditions = new LinkedHashMap<>();
private static final String EXPANSION_FOLDER = "expansions/minigame"; private static final String EXPANSION_FOLDER = "expansions/minigame";
public BukkitGameManager(BukkitCustomFishingPlugin plugin) { public BukkitGameManager(BukkitCustomFishingPlugin plugin) {
@@ -87,23 +88,23 @@ public class BukkitGameManager implements GameManager {
this.gameMap.clear(); this.gameMap.clear();
} }
private ConditionalElement<List<Pair<String, BiFunction<Context<Player>, Double, Double>>>, Player> parseGameConditions(Section section) { private ConditionalElement<List<Pair<String, WeightOperation>>, Player> parseGameConditions(Section section) {
Section subSection = section.getSection("sub-groups"); Section subSection = section.getSection("sub-groups");
if (subSection == null) { if (subSection == null) {
return new ConditionalElement<>( return new ConditionalElement<>(
plugin.getConfigManager().parseWeightOperation(section.getStringList("list")), plugin.getConfigManager().parseWeightOperation(section.getStringList("list"), (id) -> getGame(id).isPresent()),
Map.of(), Map.of(),
plugin.getRequirementManager().parseRequirements(section.getSection("conditions"), false) plugin.getRequirementManager().parseRequirements(section.getSection("conditions"), false)
); );
} else { } else {
HashMap<String, ConditionalElement<List<Pair<String, BiFunction<Context<Player>, Double, Double>>>, Player>> subElements = new HashMap<>(); HashMap<String, ConditionalElement<List<Pair<String, WeightOperation>>, Player>> subElements = new HashMap<>();
for (Map.Entry<String, Object> entry : subSection.getStringRouteMappedValues(false).entrySet()) { for (Map.Entry<String, Object> entry : subSection.getStringRouteMappedValues(false).entrySet()) {
if (entry.getValue() instanceof Section innerSection) { if (entry.getValue() instanceof Section innerSection) {
subElements.put(entry.getKey(), parseGameConditions(innerSection)); subElements.put(entry.getKey(), parseGameConditions(innerSection));
} }
} }
return new ConditionalElement<>( return new ConditionalElement<>(
plugin.getConfigManager().parseWeightOperation(section.getStringList("list")), plugin.getConfigManager().parseWeightOperation(section.getStringList("list"), (id) -> getGame(id).isPresent()),
subElements, subElements,
plugin.getRequirementManager().parseRequirements(section.getSection("conditions"), false) plugin.getRequirementManager().parseRequirements(section.getSection("conditions"), false)
); );
@@ -143,24 +144,24 @@ public class BukkitGameManager implements GameManager {
@Nullable @Nullable
@Override @Override
public Game getNextGame(Effect effect, Context<Player> context) { public Game getNextGame(Effect effect, Context<Player> context) {
HashMap<String, Double> lootWeightMap = new HashMap<>(); HashMap<String, Double> gameWeightMap = new HashMap<>();
for (ConditionalElement<List<Pair<String, BiFunction<Context<Player>, Double, Double>>>, Player> conditionalElement : gameConditions.values()) { for (ConditionalElement<List<Pair<String, WeightOperation>>, Player> conditionalElement : gameConditions.values()) {
modifyWeightMap(lootWeightMap, context, conditionalElement); modifyWeightMap(gameWeightMap, context, conditionalElement);
} }
String gameID = WeightUtils.getRandom(lootWeightMap); String gameID = WeightUtils.getRandom(gameWeightMap);
return Optional.ofNullable(gameID) return Optional.ofNullable(gameID)
.map(id -> getGame(gameID).orElseThrow(() -> new RuntimeException("Could not find game " + gameID))) .map(id -> getGame(gameID).orElseThrow(() -> new RuntimeException("Could not find game " + gameID)))
.orElse(null); .orElse(null);
} }
private void modifyWeightMap(Map<String, Double> weightMap, Context<Player> context, ConditionalElement<List<Pair<String, BiFunction<Context<Player>, Double, Double>>>, Player> conditionalElement) { private void modifyWeightMap(Map<String, Double> weightMap, Context<Player> context, ConditionalElement<List<Pair<String, WeightOperation>>, Player> conditionalElement) {
if (conditionalElement == null) return; if (conditionalElement == null) return;
if (RequirementManager.isSatisfied(context, conditionalElement.getRequirements())) { if (RequirementManager.isSatisfied(context, conditionalElement.getRequirements())) {
for (Pair<String, BiFunction<Context<Player>, Double, Double>> modifierPair : conditionalElement.getElement()) { for (Pair<String, WeightOperation> modifierPair : conditionalElement.getElement()) {
double previous = weightMap.getOrDefault(modifierPair.left(), 0d); double previous = weightMap.getOrDefault(modifierPair.left(), 0d);
weightMap.put(modifierPair.left(), modifierPair.right().apply(context, previous)); weightMap.put(modifierPair.left(), modifierPair.right().apply(context, previous, weightMap));
} }
for (ConditionalElement<List<Pair<String, BiFunction<Context<Player>, Double, Double>>>, Player> sub : conditionalElement.getSubElements().values()) { for (ConditionalElement<List<Pair<String, WeightOperation>>, Player> sub : conditionalElement.getSubElements().values()) {
modifyWeightMap(weightMap, context, sub); modifyWeightMap(weightMap, context, sub);
} }
} }

View File

@@ -39,7 +39,6 @@ import net.momirealms.customfishing.bukkit.integration.region.WorldGuardRegion;
import net.momirealms.customfishing.bukkit.integration.season.AdvancedSeasonsProvider; import net.momirealms.customfishing.bukkit.integration.season.AdvancedSeasonsProvider;
import net.momirealms.customfishing.bukkit.integration.season.CustomCropsSeasonProvider; import net.momirealms.customfishing.bukkit.integration.season.CustomCropsSeasonProvider;
import net.momirealms.customfishing.bukkit.integration.season.RealisticSeasonsProvider; import net.momirealms.customfishing.bukkit.integration.season.RealisticSeasonsProvider;
import net.momirealms.customfishing.bukkit.integration.shop.ShopGUICFItemProvider;
import net.momirealms.customfishing.bukkit.integration.shop.ShopGUIHook; import net.momirealms.customfishing.bukkit.integration.shop.ShopGUIHook;
import net.momirealms.customfishing.bukkit.item.BukkitItemManager; import net.momirealms.customfishing.bukkit.item.BukkitItemManager;
import net.momirealms.customfishing.common.util.Pair; import net.momirealms.customfishing.common.util.Pair;

View File

@@ -24,6 +24,7 @@ import net.momirealms.customfishing.api.mechanic.context.Context;
import net.momirealms.customfishing.api.mechanic.effect.Effect; import net.momirealms.customfishing.api.mechanic.effect.Effect;
import net.momirealms.customfishing.api.mechanic.loot.Loot; import net.momirealms.customfishing.api.mechanic.loot.Loot;
import net.momirealms.customfishing.api.mechanic.loot.LootManager; import net.momirealms.customfishing.api.mechanic.loot.LootManager;
import net.momirealms.customfishing.api.mechanic.loot.operation.WeightOperation;
import net.momirealms.customfishing.api.mechanic.requirement.ConditionalElement; import net.momirealms.customfishing.api.mechanic.requirement.ConditionalElement;
import net.momirealms.customfishing.api.mechanic.requirement.RequirementManager; import net.momirealms.customfishing.api.mechanic.requirement.RequirementManager;
import net.momirealms.customfishing.common.util.Pair; import net.momirealms.customfishing.common.util.Pair;
@@ -34,7 +35,6 @@ import org.jetbrains.annotations.Nullable;
import java.io.File; import java.io.File;
import java.util.*; import java.util.*;
import java.util.function.BiFunction;
@SuppressWarnings("DuplicatedCode") @SuppressWarnings("DuplicatedCode")
public class BukkitLootManager implements LootManager { public class BukkitLootManager implements LootManager {
@@ -42,7 +42,7 @@ public class BukkitLootManager implements LootManager {
private final BukkitCustomFishingPlugin plugin; private final BukkitCustomFishingPlugin plugin;
private final HashMap<String, Loot> lootMap = new HashMap<>(); private final HashMap<String, Loot> lootMap = new HashMap<>();
private final HashMap<String, List<String>> groupMembersMap = new HashMap<>(); private final HashMap<String, List<String>> groupMembersMap = new HashMap<>();
private final LinkedHashMap<String, ConditionalElement<List<Pair<String, BiFunction<Context<Player>, Double, Double>>>, Player>> lootConditions = new LinkedHashMap<>(); private final LinkedHashMap<String, ConditionalElement<List<Pair<String, WeightOperation>>, Player>> lootConditions = new LinkedHashMap<>();
public BukkitLootManager(BukkitCustomFishingPlugin plugin) { public BukkitLootManager(BukkitCustomFishingPlugin plugin) {
this.plugin = plugin; this.plugin = plugin;
@@ -73,23 +73,23 @@ public class BukkitLootManager implements LootManager {
} }
} }
private ConditionalElement<List<Pair<String, BiFunction<Context<Player>, Double, Double>>>, Player> parseLootConditions(Section section) { private ConditionalElement<List<Pair<String, WeightOperation>>, Player> parseLootConditions(Section section) {
Section subSection = section.getSection("sub-groups"); Section subSection = section.getSection("sub-groups");
if (subSection == null) { if (subSection == null) {
return new ConditionalElement<>( return new ConditionalElement<>(
plugin.getConfigManager().parseWeightOperation(section.getStringList("list")), plugin.getConfigManager().parseWeightOperation(section.getStringList("list"), (id) -> getLoot(id).isPresent()),
Map.of(), Map.of(),
plugin.getRequirementManager().parseRequirements(section.getSection("conditions"), false) plugin.getRequirementManager().parseRequirements(section.getSection("conditions"), false)
); );
} else { } else {
HashMap<String, ConditionalElement<List<Pair<String, BiFunction<Context<Player>, Double, Double>>>, Player>> subElements = new HashMap<>(); HashMap<String, ConditionalElement<List<Pair<String, WeightOperation>>, Player>> subElements = new HashMap<>();
for (Map.Entry<String, Object> entry : subSection.getStringRouteMappedValues(false).entrySet()) { for (Map.Entry<String, Object> entry : subSection.getStringRouteMappedValues(false).entrySet()) {
if (entry.getValue() instanceof Section innerSection) { if (entry.getValue() instanceof Section innerSection) {
subElements.put(entry.getKey(), parseLootConditions(innerSection)); subElements.put(entry.getKey(), parseLootConditions(innerSection));
} }
} }
return new ConditionalElement<>( return new ConditionalElement<>(
plugin.getConfigManager().parseWeightOperation(section.getStringList("list")), plugin.getConfigManager().parseWeightOperation(section.getStringList("list"), (id) -> getLoot(id).isPresent()),
subElements, subElements,
plugin.getRequirementManager().parseRequirements(section.getSection("conditions"), false) plugin.getRequirementManager().parseRequirements(section.getSection("conditions"), false)
); );
@@ -136,18 +136,18 @@ public class BukkitLootManager implements LootManager {
@Override @Override
public HashMap<String, Double> getWeightedLoots(Effect effect, Context<Player> context) { public HashMap<String, Double> getWeightedLoots(Effect effect, Context<Player> context) {
HashMap<String, Double> lootWeightMap = new HashMap<>(); HashMap<String, Double> lootWeightMap = new HashMap<>();
for (ConditionalElement<List<Pair<String, BiFunction<Context<Player>, Double, Double>>>, Player> conditionalElement : lootConditions.values()) { for (ConditionalElement<List<Pair<String, WeightOperation>>, Player> conditionalElement : lootConditions.values()) {
modifyWeightMap(lootWeightMap, context, conditionalElement); modifyWeightMap(lootWeightMap, context, conditionalElement);
} }
for (Pair<String, BiFunction<Context<Player>, Double, Double>> pair : effect.weightOperations()) { for (Pair<String, WeightOperation> pair : effect.weightOperations()) {
Double previous = lootWeightMap.get(pair.left()); Double previous = lootWeightMap.get(pair.left());
if (previous != null) { if (previous != null) {
lootWeightMap.put(pair.left(), pair.right().apply(context, previous)); lootWeightMap.put(pair.left(), pair.right().apply(context, previous, lootWeightMap));
} }
} }
for (Pair<String, BiFunction<Context<Player>, Double, Double>> pair : effect.weightOperationsIgnored()) { for (Pair<String, WeightOperation> pair : effect.weightOperationsIgnored()) {
double previous = lootWeightMap.getOrDefault(pair.left(), 0d); double previous = lootWeightMap.getOrDefault(pair.left(), 0d);
lootWeightMap.put(pair.left(), pair.right().apply(context, previous)); lootWeightMap.put(pair.left(), pair.right().apply(context, previous, lootWeightMap));
} }
return lootWeightMap; return lootWeightMap;
} }
@@ -155,36 +155,36 @@ public class BukkitLootManager implements LootManager {
@Nullable @Nullable
@Override @Override
public Loot getNextLoot(Effect effect, Context<Player> context) { public Loot getNextLoot(Effect effect, Context<Player> context) {
HashMap<String, Double> lootWeightMap = new HashMap<>(); HashMap<String, Double> weightMap = new HashMap<>();
for (ConditionalElement<List<Pair<String, BiFunction<Context<Player>, Double, Double>>>, Player> conditionalElement : lootConditions.values()) { for (ConditionalElement<List<Pair<String, WeightOperation>>, Player> conditionalElement : lootConditions.values()) {
modifyWeightMap(lootWeightMap, context, conditionalElement); modifyWeightMap(weightMap, context, conditionalElement);
} }
for (Pair<String, BiFunction<Context<Player>, Double, Double>> pair : effect.weightOperations()) { for (Pair<String, WeightOperation> pair : effect.weightOperations()) {
Double previous = lootWeightMap.get(pair.left()); Double previous = weightMap.get(pair.left());
if (previous != null) { if (previous != null) {
lootWeightMap.put(pair.left(), pair.right().apply(context, previous)); weightMap.put(pair.left(), pair.right().apply(context, previous, weightMap));
} }
} }
for (Pair<String, BiFunction<Context<Player>, Double, Double>> pair : effect.weightOperationsIgnored()) { for (Pair<String, WeightOperation> pair : effect.weightOperationsIgnored()) {
double previous = lootWeightMap.getOrDefault(pair.left(), 0d); double previous = weightMap.getOrDefault(pair.left(), 0d);
lootWeightMap.put(pair.left(), pair.right().apply(context, previous)); weightMap.put(pair.left(), pair.right().apply(context, previous, weightMap));
} }
plugin.debug(lootWeightMap); plugin.debug(weightMap::toString);
String lootID = WeightUtils.getRandom(lootWeightMap); String lootID = WeightUtils.getRandom(weightMap);
return Optional.ofNullable(lootID) return Optional.ofNullable(lootID)
.map(id -> getLoot(lootID).orElseThrow(() -> new NullPointerException("Could not find loot " + lootID))) .map(id -> getLoot(lootID).orElseThrow(() -> new NullPointerException("Could not find loot " + lootID)))
.orElse(null); .orElse(null);
} }
private void modifyWeightMap(Map<String, Double> weightMap, Context<Player> context, ConditionalElement<List<Pair<String, BiFunction<Context<Player>, Double, Double>>>, Player> conditionalElement) { private void modifyWeightMap(Map<String, Double> weightMap, Context<Player> context, ConditionalElement<List<Pair<String, WeightOperation>>, Player> conditionalElement) {
if (conditionalElement == null) return; if (conditionalElement == null) return;
if (RequirementManager.isSatisfied(context, conditionalElement.getRequirements())) { if (RequirementManager.isSatisfied(context, conditionalElement.getRequirements())) {
for (Pair<String, BiFunction<Context<Player>, Double, Double>> modifierPair : conditionalElement.getElement()) { for (Pair<String, WeightOperation> modifierPair : conditionalElement.getElement()) {
double previous = weightMap.getOrDefault(modifierPair.left(), 0d); double previous = weightMap.getOrDefault(modifierPair.left(), 0d);
weightMap.put(modifierPair.left(), modifierPair.right().apply(context, previous)); weightMap.put(modifierPair.left(), modifierPair.right().apply(context, previous, weightMap));
} }
for (ConditionalElement<List<Pair<String, BiFunction<Context<Player>, Double, Double>>>, Player> sub : conditionalElement.getSubElements().values()) { for (ConditionalElement<List<Pair<String, WeightOperation>>, Player> sub : conditionalElement.getSubElements().values()) {
modifyWeightMap(weightMap, context, sub); modifyWeightMap(weightMap, context, sub);
} }
} }

View File

@@ -1,6 +1,6 @@
# Project settings # Project settings
# Rule: [major update].[feature update].[bug fix] # Rule: [major update].[feature update].[bug fix]
project_version=2.2.36 project_version=2.3.0
config_version=38 config_version=38
project_group=net.momirealms project_group=net.momirealms
@@ -46,9 +46,9 @@ guava_version=33.3.1-jre
lz4_version=1.8.0 lz4_version=1.8.0
# Proxy settings # Proxy settings
#systemProp.socks.proxyHost=127.0.0.1 systemProp.socks.proxyHost=127.0.0.1
#systemProp.socks.proxyPort=7890 systemProp.socks.proxyPort=7890
#systemProp.http.proxyHost=127.0.0.1 systemProp.http.proxyHost=127.0.0.1
#systemProp.http.proxyPort=7890 systemProp.http.proxyPort=7890
#systemProp.https.proxyHost=127.0.0.1 systemProp.https.proxyHost=127.0.0.1
#systemProp.https.proxyPort=7890 systemProp.https.proxyPort=7890