Skip to content

Commit 6bf3fbd

Browse files
committed
Random bug fix.
1 parent bb5b39c commit 6bf3fbd

File tree

13 files changed

+194
-101
lines changed

13 files changed

+194
-101
lines changed

src/api/java/io/izzel/mesmerize/api/DefaultStats.java

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -22,36 +22,36 @@ public final class DefaultStats {
2222
public static final Stats<List<NumberValue<Double>>> PVP_DAMAGE = rangeRelativeStats("pvp_damage");
2323
public static final Stats<List<NumberValue<Double>>> PVE_DAMAGE = rangeRelativeStats("pve_damage");
2424
public static final Stats<List<NumberValue<Double>>> RANGE_DAMAGE = rangeRelativeStats("range_damage");
25-
public static final Stats<StatsNumber<Double>> REAL_DAMAGE = singleRelativeStats("real_damage");
25+
public static final Stats<StatsNumber<Double>> REAL_DAMAGE = singleRelativeStats("real_damage", true);
2626
public static final Stats<List<NumberValue<Double>>> DEFENSE = rangeRelativeStats("defense");
2727
public static final Stats<List<NumberValue<Double>>> PVP_DEFENSE = rangeRelativeStats("pvp_defense");
2828
public static final Stats<List<NumberValue<Double>>> PVE_DEFENSE = rangeRelativeStats("pve_defense");
2929
public static final Stats<List<NumberValue<Double>>> RANGE_DEFENSE = rangeRelativeStats("range_defense");
30-
public static final Stats<StatsNumber<Double>> CRIT_DAMAGE = singleRelativeStats("crit_damage");
31-
public static final Stats<StatsNumber<Double>> CRIT_CHANCE = singleRelativeStats("crit_chance");
32-
public static final Stats<StatsNumber<Double>> THORNS = singleRelativeStats("thorns");
33-
public static final Stats<StatsNumber<Double>> MELEE_THORNS = singleRelativeStats("melee_thorns");
34-
public static final Stats<StatsNumber<Double>> RANGE_THORNS = singleRelativeStats("range_thorns");
35-
public static final Stats<StatsNumber<Double>> THORNS_CHANCE = singleRelativeStats("thorns_chance");
36-
public static final Stats<StatsNumber<Double>> LIFESTEAL = singleRelativeStats("lifesteal");
37-
public static final Stats<StatsNumber<Double>> LIFESTEAL_CHANCE = singleRelativeStats("lifesteal_chance");
38-
public static final Stats<StatsNumber<Double>> HEALTH = singleRelativeStats("health");
30+
public static final Stats<StatsNumber<Double>> CRIT_DAMAGE = singleRelativeStats("crit_damage", true);
31+
public static final Stats<StatsNumber<Double>> CRIT_CHANCE = singleRelativeStats("crit_chance", false);
32+
public static final Stats<StatsNumber<Double>> THORNS = singleRelativeStats("thorns", true);
33+
public static final Stats<StatsNumber<Double>> MELEE_THORNS = singleRelativeStats("melee_thorns", true);
34+
public static final Stats<StatsNumber<Double>> RANGE_THORNS = singleRelativeStats("range_thorns", true);
35+
public static final Stats<StatsNumber<Double>> THORNS_CHANCE = singleRelativeStats("thorns_chance", false);
36+
public static final Stats<StatsNumber<Double>> LIFESTEAL = singleRelativeStats("lifesteal", true);
37+
public static final Stats<StatsNumber<Double>> LIFESTEAL_CHANCE = singleRelativeStats("lifesteal_chance", false);
38+
public static final Stats<StatsNumber<Double>> HEALTH = singleRelativeStats("health", true);
3939
public static final Stats<List<NumberValue<Double>>> REGENERATION = rangeRelativeStats("regeneration");
4040
public static final Stats<StatsNumber<Integer>> COMBAT_EXP_BONUS = absoluteInt("combat_exp_bonus");
4141
public static final Stats<StatsNumber<Integer>> OTHER_EXP_BONUS = absoluteInt("other_exp_bonus");
4242
public static final Stats<UUID> SOULBIND =
4343
Stats.builder().key(key("soulbind")).supplying(UUIDValue::new).displaying(UUIDValue.displayName("soulbind")).build();
4444
public static final Stats<Void> AUTO_BIND =
4545
Stats.builder().key(key("auto_bind")).supplying(MarkerValue::new).build();
46-
public static final Stats<StatsNumber<Double>> MOVE_SPEED = singleRelativeStats("move_speed");
47-
public static final Stats<StatsNumber<Double>> FLY_SPEED = singleRelativeStats("fly_speed");
48-
public static final Stats<StatsNumber<Double>> ATTACK_SPEED = singleRelativeStats("attack_speed");
49-
public static final Stats<StatsNumber<Double>> ATTACK_RANGE = singleRelativeStats("attack_range");
50-
public static final Stats<StatsNumber<Double>> DODGE = singleRelativeStats("dodge");
51-
public static final Stats<StatsNumber<Double>> ACCURACY = singleRelativeStats("accuracy");
46+
public static final Stats<StatsNumber<Double>> MOVE_SPEED = singleRelativeStats("move_speed", true);
47+
public static final Stats<StatsNumber<Double>> FLY_SPEED = singleRelativeStats("fly_speed", true);
48+
public static final Stats<StatsNumber<Double>> ATTACK_SPEED = singleRelativeStats("attack_speed", true);
49+
public static final Stats<StatsNumber<Double>> ATTACK_RANGE = singleRelativeStats("attack_range", true);
50+
public static final Stats<StatsNumber<Double>> DODGE = singleRelativeStats("dodge", false);
51+
public static final Stats<StatsNumber<Double>> ACCURACY = singleRelativeStats("accuracy", false);
5252
public static final Stats<Map<String, StatsValue<?>>> PERMISSION = PermissionValue.STATS;
53-
public static final Stats<StatsNumber<Double>> TRACING = singleRelativeStats("tracing");
54-
public static final Stats<StatsNumber<Double>> ACCELERATE = singleRelativeStats("accelerate");
53+
public static final Stats<StatsNumber<Double>> TRACING = singleRelativeStats("tracing", true);
54+
public static final Stats<StatsNumber<Double>> ACCELERATE = singleRelativeStats("accelerate", true);
5555
public static final Stats<List<StatsSetValue>> STATS_SET =
5656
Stats.builder().key(key("stats_set"))
5757
.supplying(MultiValue.builder().supplying(StatsSetValue::new).allowSingleNonListValue().buildSupplier())
@@ -73,10 +73,12 @@ private static Stats<StatsNumber<Integer>> absoluteInt(String key) {
7373
.build();
7474
}
7575

76-
private static Stats<StatsNumber<Double>> singleRelativeStats(String key) {
76+
private static Stats<StatsNumber<Double>> singleRelativeStats(String key, boolean absolute) {
77+
NumberValue.NumberValueBuilder<Double> builder = NumberValue.builder().valueType(double.class).allowRelative();
78+
if (absolute) builder.allowDecimal();
7779
return Stats.builder().key(key(key))
7880
.supplying(
79-
NumberValue.builder().valueType(double.class).allowRelative().buildSupplier()
81+
builder.buildSupplier()
8082
)
8183
.merging(NumberValue.defaultMerger())
8284
.displaying(NumberValue.defaultDisplay("stats." + key))

src/api/java/io/izzel/mesmerize/api/data/NumberValue.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,14 +68,14 @@ public void accept(ValueVisitor visitor, VisitMode mode) {
6868
private void acceptByType(ValueVisitor visitor) {
6969
Number absolutePart = number.getAbsolutePart();
7070
Class<?> valueType = number.getValueType();
71-
if (valueType == int.class) {
71+
if (valueType == double.class) {
72+
visitor.visitDouble(absolutePart.doubleValue());
73+
} else if (valueType == int.class) {
7274
visitor.visitInt(absolutePart.intValue());
7375
} else if (valueType == long.class) {
7476
visitor.visitLong(absolutePart.longValue());
75-
} else if (valueType == float.class) {
76-
visitor.visitFloat(absolutePart.floatValue());
7777
} else {
78-
visitor.visitLong(absolutePart.longValue());
78+
visitor.visitFloat(absolutePart.floatValue());
7979
}
8080
}
8181

@@ -189,7 +189,7 @@ public static <T extends Number> BiFunction<NumberValue<T>, NumberValue<T>, Numb
189189

190190
public static class NumberValueBuilder<T extends Number> {
191191

192-
private boolean allowRelative, allowDecimal, allowCoerce = true;
192+
private boolean allowRelative = false, allowDecimal = false, allowCoerce = true;
193193
private Class<T> valueType;
194194

195195
@Contract("_ -> this")

src/api/java/io/izzel/mesmerize/api/data/StatsNumber.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ private static <T extends Number> StatsNumber<T> merge(StatsNumber<T> a, StatsNu
179179
} else {
180180
abs = (T) absMerger.apply(a.absolutePart, b.absolutePart);
181181
}
182-
double rel = (a.relativePart + 100D) * (b.relativePart + 100D) - 100D;
182+
double rel = (a.relativePart + 100D) * (b.relativePart + 100D) - 10000D;
183183
return new StatsNumber<>(a.valueType, abs, rel, ImmutableList.<StatsNumber<T>>builder().addAll(a.operations).addAll(b.operations).build());
184184
}
185185
}

src/api/java/io/izzel/mesmerize/api/service/StatsService.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import org.bukkit.entity.Entity;
1010
import org.bukkit.persistence.PersistentDataContainer;
1111
import org.bukkit.persistence.PersistentDataHolder;
12+
import org.jetbrains.annotations.Contract;
1213
import org.jetbrains.annotations.NotNull;
1314

1415
import java.util.Objects;
@@ -25,7 +26,9 @@ public interface StatsService {
2526

2627
StatsSet cachedSetFor(@NotNull Entity entity);
2728

28-
void refreshCache(@NotNull Entity entity);
29+
@SuppressWarnings("UnusedReturnValue")
30+
@Contract("_, false -> null; _, true -> !null")
31+
StatsSet refreshCache(@NotNull Entity entity, boolean immediate);
2932

3033
default StatsHolder newStatsHolder(@NotNull PersistentDataHolder holder) {
3134
return newStatsHolder(holder.getPersistentDataContainer());

src/main/java/io/izzel/mesmerize/impl/Mesmerize.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
import io.izzel.mesmerize.api.service.StatsService;
55
import io.izzel.mesmerize.impl.config.LocalRepository;
66
import io.izzel.mesmerize.impl.config.spec.ConfigSpec;
7+
import io.izzel.mesmerize.impl.event.AttributeListener;
78
import io.izzel.mesmerize.impl.event.CombatListener;
89
import io.izzel.mesmerize.impl.event.EntityStatsCacheListener;
9-
import io.izzel.mesmerize.impl.event.AttributeListener;
1010
import io.izzel.mesmerize.impl.event.ProjectileListener;
1111
import io.izzel.mesmerize.impl.service.SimpleStatsService;
1212
import io.izzel.mesmerize.impl.util.Updater;
@@ -18,7 +18,6 @@
1818
import org.bstats.bukkit.Metrics;
1919
import org.bukkit.Bukkit;
2020
import org.bukkit.plugin.ServicePriority;
21-
import org.bukkit.plugin.java.JavaPlugin;
2221
import org.yaml.snakeyaml.Yaml;
2322
import org.yaml.snakeyaml.constructor.CustomClassLoaderConstructor;
2423

@@ -76,6 +75,6 @@ public void reloadMesmerizeData() {
7675
}
7776

7877
public static Mesmerize instance() {
79-
return JavaPlugin.getPlugin(Mesmerize.class);
78+
return ((Mesmerize) getPlugin());
8079
}
8180
}

src/main/java/io/izzel/mesmerize/impl/command/MesmerizeCommand.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ public void onCommand(CommandSender sender, Command command, String s, String[]
6464
statsSet.accept(writer, VisitMode.DATA);
6565
itemInMainHand.setItemMeta(itemMeta);
6666
player.getInventory().setItemInMainHand(itemInMainHand);
67+
StatsService.instance().refreshCache(player, true);
6768
TLocale.sendTo(player, "command.attach", args[0]);
6869
} else {
6970
TLocale.sendTo(player, "command.item_not_present");

src/main/java/io/izzel/mesmerize/impl/config/spec/GeneralSpec.java

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,9 @@ public class GeneralSpec {
44

55
private boolean debug = false;
66
private boolean updateCheck = true;
7-
private long attributeApplyInterval = 20L;
87
private double defaultAttackRange = 5.0D;
98
private double defaultHitChance = 1.0D;
10-
private double defaultHealth = 20.0D;
9+
private boolean enableSpeedControl = true;
1110
private double defaultAttackSpeed = 4.0D;
1211
private double defaultMoveSpeed = 0.1D;
1312
private double defaultFlySpeed = 0.2D;
@@ -28,14 +27,6 @@ public void setUpdateCheck(boolean updateCheck) {
2827
this.updateCheck = updateCheck;
2928
}
3029

31-
public long attributeApplyInterval() {
32-
return attributeApplyInterval;
33-
}
34-
35-
public void setAttributeApplyInterval(long attributeApplyInterval) {
36-
this.attributeApplyInterval = attributeApplyInterval;
37-
}
38-
3930
public double defaultAttackRange() {
4031
return defaultAttackRange;
4132
}
@@ -52,12 +43,12 @@ public void setDefaultHitChance(double defaultHitChance) {
5243
this.defaultHitChance = defaultHitChance;
5344
}
5445

55-
public double defaultHealth() {
56-
return defaultHealth;
46+
public boolean enableSpeedControl() {
47+
return enableSpeedControl;
5748
}
5849

59-
public void setDefaultHealth(double defaultHealth) {
60-
this.defaultHealth = defaultHealth;
50+
public void setEnableSpeedControl(boolean enableSpeedControl) {
51+
this.enableSpeedControl = enableSpeedControl;
6152
}
6253

6354
public double defaultAttackSpeed() {

src/main/java/io/izzel/mesmerize/impl/config/spec/HealthSpec.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ public class HealthSpec {
88

99
private double heathScale = 20.0D;
1010

11+
private double defaultHealth = 20.0D;
12+
1113
private double minimalHealth = 1.0D;
1214

1315
private double maximumHealth = Integer.MAX_VALUE;
@@ -38,6 +40,14 @@ public void setHeathScale(double heathScale) {
3840
this.heathScale = heathScale;
3941
}
4042

43+
public double defaultHealth() {
44+
return defaultHealth;
45+
}
46+
47+
public void setDefaultHealth(double defaultHealth) {
48+
this.defaultHealth = defaultHealth;
49+
}
50+
4151
public double minimalHealth() {
4252
return minimalHealth;
4353
}

src/main/java/io/izzel/mesmerize/impl/event/AttributeListener.java

Lines changed: 67 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@
33
import io.izzel.mesmerize.api.DefaultStats;
44
import io.izzel.mesmerize.api.data.NumberValue;
55
import io.izzel.mesmerize.api.data.RangeNumberValue;
6-
import io.izzel.mesmerize.api.data.StatsNumber;
76
import io.izzel.mesmerize.api.event.StatsRefreshEvent;
87
import io.izzel.mesmerize.api.visitor.util.StatsSet;
98
import io.izzel.mesmerize.impl.Mesmerize;
109
import io.izzel.mesmerize.impl.config.spec.ConfigSpec;
10+
import io.izzel.mesmerize.impl.config.spec.GeneralSpec;
11+
import io.izzel.mesmerize.impl.config.spec.HealthSpec;
12+
import io.izzel.mesmerize.impl.util.Util;
1113
import org.bukkit.Bukkit;
1214
import org.bukkit.attribute.Attribute;
1315
import org.bukkit.attribute.AttributeInstance;
@@ -16,6 +18,7 @@
1618
import org.bukkit.entity.Player;
1719
import org.bukkit.event.EventHandler;
1820
import org.bukkit.event.Listener;
21+
import org.bukkit.event.player.PlayerJoinEvent;
1922

2023
import java.util.List;
2124
import java.util.Optional;
@@ -27,40 +30,83 @@ public class AttributeListener implements Listener {
2730

2831
public AttributeListener() {
2932
Bukkit.getScheduler().runTaskTimer(Mesmerize.instance(), () -> {
33+
if (!ConfigSpec.spec().health().enableHealthControl()) {
34+
return;
35+
}
3036
for (Player player : Bukkit.getOnlinePlayers()) {
3137
Optional<List<NumberValue<Double>>> regen = DefaultStats.REGENERATION.tryApply(StatsSet.of(player), null);
3238
regen.ifPresent(list -> {
39+
//noinspection ConstantConditions
40+
double maxHealth = player.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue();
3341
double heal = RangeNumberValue.applyAsDouble(0, list, random);
34-
player.setHealth(player.getHealth() + heal);
42+
player.setHealth(Util.clamp(player.getHealth() + heal, 0, maxHealth));
3543
});
3644
}
37-
}, 0, ConfigSpec.spec().general().attributeApplyInterval());
45+
}, 0, ConfigSpec.spec().health().regenerationTicks());
46+
}
47+
48+
@EventHandler
49+
public void onJoin(PlayerJoinEvent event) {
50+
HealthSpec health = ConfigSpec.spec().health();
51+
if (health.enableHealthControl()) {
52+
if (health.healthScaled()) {
53+
event.getPlayer().setHealthScaled(true);
54+
event.getPlayer().setHealthScale(health.heathScale());
55+
} else {
56+
event.getPlayer().setHealthScaled(false);
57+
}
58+
}
3859
}
3960

4061
@EventHandler
4162
public void onRefresh(StatsRefreshEvent event) {
4263
Entity entity = event.getEntity();
4364
if (entity instanceof LivingEntity) {
65+
LivingEntity livingEntity = (LivingEntity) entity;
4466
StatsSet statsSet = event.getStatsSet();
45-
AttributeInstance attribute = ((LivingEntity) entity).getAttribute(Attribute.GENERIC_MAX_HEALTH);
46-
if (attribute != null) {
47-
Optional<StatsNumber<Double>> health = DefaultStats.HEALTH.tryApply(statsSet, event);
48-
health.ifPresent(number -> attribute.setBaseValue(number.applyDouble(ConfigSpec.spec().general().defaultHealth())));
49-
}
50-
AttributeInstance attackSpeedAttr = ((LivingEntity) entity).getAttribute(Attribute.GENERIC_ATTACK_SPEED);
51-
if (attackSpeedAttr != null) {
52-
Optional<StatsNumber<Double>> attackSpeed = DefaultStats.ATTACK_SPEED.tryApply(statsSet, event);
53-
attackSpeed.ifPresent(number -> attackSpeedAttr.setBaseValue(number.applyDouble(ConfigSpec.spec().general().defaultAttackSpeed())));
54-
}
55-
AttributeInstance moveSpeedAttr = ((LivingEntity) entity).getAttribute(Attribute.GENERIC_MOVEMENT_SPEED);
56-
if (moveSpeedAttr != null) {
57-
Optional<StatsNumber<Double>> moveSpeed = DefaultStats.MOVE_SPEED.tryApply(statsSet, event);
58-
moveSpeed.ifPresent(number -> moveSpeedAttr.setBaseValue(number.applyDouble(ConfigSpec.spec().general().defaultMoveSpeed())));
67+
68+
if (ConfigSpec.spec().health().enableHealthControl()) {
69+
AttributeInstance attribute = livingEntity.getAttribute(Attribute.GENERIC_MAX_HEALTH);
70+
if (attribute != null) {
71+
HealthSpec healthSpec = ConfigSpec.spec().health();
72+
attribute.setBaseValue(DefaultStats.HEALTH.tryApply(statsSet, event).map(number -> {
73+
double value = number.applyDouble(healthSpec.defaultHealth());
74+
return Util.clamp(value, healthSpec.minimalHealth(), healthSpec.maximumHealth());
75+
}).orElse(healthSpec.defaultHealth()));
76+
}
5977
}
60-
AttributeInstance flySpeedAttr = ((LivingEntity) entity).getAttribute(Attribute.GENERIC_FLYING_SPEED);
61-
if (flySpeedAttr != null) {
62-
Optional<StatsNumber<Double>> flySpeed = DefaultStats.FLY_SPEED.tryApply(statsSet, event);
63-
flySpeed.ifPresent(number -> flySpeedAttr.setBaseValue(number.applyDouble(ConfigSpec.spec().general().defaultFlySpeed())));
78+
79+
GeneralSpec generalSpec = ConfigSpec.spec().general();
80+
if (generalSpec.enableSpeedControl()) {
81+
AttributeInstance attackSpeedAttr = livingEntity.getAttribute(Attribute.GENERIC_ATTACK_SPEED);
82+
if (attackSpeedAttr != null) {
83+
attackSpeedAttr.setBaseValue(DefaultStats.ATTACK_SPEED.tryApply(statsSet, event)
84+
.map(number -> number.applyDouble(generalSpec.defaultAttackSpeed()))
85+
.orElse(generalSpec.defaultAttackSpeed()));
86+
}
87+
88+
double moveSpeed = DefaultStats.MOVE_SPEED.tryApply(statsSet, event).map(number -> {
89+
double value = number.applyDouble(generalSpec.defaultMoveSpeed());
90+
return Util.clamp(value, -1, 1);
91+
}).orElse(generalSpec.defaultMoveSpeed());
92+
double flySpeed = DefaultStats.FLY_SPEED.tryApply(statsSet, event).map(number -> {
93+
double value = number.applyDouble(generalSpec.defaultFlySpeed());
94+
return Util.clamp(value, -1, 1);
95+
}).orElse(generalSpec.defaultFlySpeed());
96+
if (entity instanceof Player) {
97+
Player player = (Player) entity;
98+
player.setWalkSpeed((float) moveSpeed);
99+
player.setFlySpeed((float) flySpeed);
100+
} else {
101+
AttributeInstance moveSpeedAttr = ((LivingEntity) entity).getAttribute(Attribute.GENERIC_MOVEMENT_SPEED);
102+
if (moveSpeedAttr != null) {
103+
moveSpeedAttr.setBaseValue(moveSpeed);
104+
}
105+
AttributeInstance flySpeedAttr = ((LivingEntity) entity).getAttribute(Attribute.GENERIC_FLYING_SPEED);
106+
if (flySpeedAttr != null) {
107+
flySpeedAttr.setBaseValue(flySpeed);
108+
}
109+
}
64110
}
65111
}
66112
}

0 commit comments

Comments
 (0)