Skip to content

Commit f8ba63f

Browse files
committed
Suggested Fixes: Cleanup + Tidy
1 parent 589ff64 commit f8ba63f

6 files changed

Lines changed: 108 additions & 55 deletions

File tree

src/main/java/com/robertx22/mine_and_slash/database/data/exile_effects/ExileEffect.java

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import com.robertx22.mine_and_slash.database.data.value_calc.LeveledValue;
1414
import com.robertx22.mine_and_slash.database.registry.ExileDB;
1515
import com.robertx22.mine_and_slash.database.registry.ExileRegistryTypes;
16+
import com.robertx22.mine_and_slash.event_hooks.my_events.EffectUtils;
1617
import com.robertx22.mine_and_slash.mmorpg.DebugHud;
1718
import com.robertx22.mine_and_slash.mmorpg.SlashRef;
1819
import com.robertx22.mine_and_slash.saveclasses.ExactStatData;
@@ -279,29 +280,31 @@ public void onRemove(LivingEntity target) {
279280
}
280281

281282
if (!target.level().isClientSide && data.onExpireEffectDurationTicks != null && !data.onExpireEffectDurationTicks.isEmpty()) {
283+
boolean anyApplied = false;
282284
for (var entry : data.onExpireEffectDurationTicks.entrySet()) {
283285
String effId = entry.getKey();
284286
int durTicks = Math.max(1, entry.getValue());
285287
if (ctx.onExpireApplied != null && ctx.onExpireApplied.contains(effId)) {
286288
continue;
287289
}
288290
var extraEff = ExileDB.ExileEffects().get(effId);
289-
if (extraEff != null) {
290-
var unitT = com.robertx22.mine_and_slash.uncommon.datasaving.Load.Unit(target);
291-
var storeT = unitT.getStatusEffectsData();
292-
var instT = storeT.getOrCreate(extraEff);
293-
instT.stacks = Math.max(instT.stacks, 1);
294-
instT.ticks_left = Math.max(instT.ticks_left, durTicks);
291+
if (extraEff == null) {
292+
continue;
293+
}
294+
var instT = EffectUtils.applyEffect(target, extraEff, durTicks, 1, false);
295+
if (instT != null) {
295296
instT.is_infinite = false;
296297
instT.caster_uuid = caster.getStringUUID();
297-
try { extraEff.onApply(target); } catch (Exception ignored) {}
298-
unitT.equipmentCache.STATUS.setDirty();
299-
unitT.sync.setDirty();
300298
if (DebugHud.ON_EXPIRE && target instanceof ServerPlayer spx) {
301299
DebugHud.send(spx, "expire_extra_" + effId, "[EFFECT][EXPIRE] Extra-applied " + effId + " tl=" + instT.ticks_left, 400);
302300
}
301+
anyApplied = true;
303302
}
304303
}
304+
if (anyApplied) {
305+
var unitT = Load.Unit(target);
306+
unitT.sync.setDirty();
307+
}
305308
}
306309
}
307310
}

src/main/java/com/robertx22/mine_and_slash/event_hooks/my_events/EffectUtils.java

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import com.robertx22.mine_and_slash.database.registry.ExileDB;
77
import com.robertx22.mine_and_slash.uncommon.datasaving.Load;
88
import net.minecraft.server.level.ServerPlayer;
9+
import net.minecraft.world.entity.LivingEntity;
910

1011
/**
1112
* Utility for applying short-TTL "state" effects (e.g., leeching_state) to players.
@@ -28,14 +29,22 @@ private EffectUtils() {}
2829
public static ExileEffectInstanceData applyState(ServerPlayer sp, EffectCtx ctx, int durationTicks, int stacks) {
2930
final ExileEffect effect = resolveEffect(ctx);
3031
if (effect == null) return null;
31-
32-
return applyEffect(sp, effect, durationTicks, stacks);
32+
return applyEffect((LivingEntity) sp, effect, durationTicks, stacks);
3333
}
3434

3535
public static ExileEffectInstanceData applyEffect(ServerPlayer sp, ExileEffect effect, int durationTicks, int stacks) {
36-
if (effect == null) return null;
36+
return applyEffect((LivingEntity) sp, effect, durationTicks, stacks, true);
37+
}
38+
39+
public static ExileEffectInstanceData applyEffect(LivingEntity entity, ExileEffect effect, int durationTicks, int stacks) {
40+
return applyEffect(entity, effect, durationTicks, stacks, true);
41+
}
42+
43+
public static ExileEffectInstanceData applyEffect(LivingEntity entity, ExileEffect effect, int durationTicks, int stacks, boolean markDirty) {
44+
if (effect == null || entity == null) return null;
45+
if (durationTicks <= 0 || stacks <= 0) return null;
3746

38-
var unit = Load.Unit(sp);
47+
var unit = Load.Unit(entity);
3948
var store = unit.getStatusEffectsData();
4049
var inst = store.getOrCreate(effect);
4150

@@ -44,8 +53,13 @@ public static ExileEffectInstanceData applyEffect(ServerPlayer sp, ExileEffect e
4453
inst.stacks = Math.max(inst.stacks, capped);
4554
inst.ticks_left = Math.max(inst.ticks_left, durationTicks);
4655

47-
effect.onApply(sp);
48-
unit.sync.setDirty();
56+
try { effect.onApply(entity); } catch (Exception ignored) {}
57+
if (markDirty) {
58+
unit.equipmentCache.STATUS.setDirty();
59+
if (entity instanceof ServerPlayer) {
60+
unit.sync.setDirty();
61+
}
62+
}
4963
return inst;
5064
}
5165

src/main/java/com/robertx22/mine_and_slash/event_hooks/ontick/OnServerTick.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ public static void onEndTick(ServerPlayer player) {
133133
long now = player.level().getGameTime();
134134
var unit = Load.Unit(player);
135135
if (unit != null) {
136-
for (var rt : com.robertx22.mine_and_slash.saveclasses.unit.ResourceType.values()) {
136+
for (var rt : ResourceType.values()) {
137137
for (var key : unit.getSpendRuntime().getActiveKeys(rt)) {
138138
var spec = unit.getSpendRuntime().getSpec(key);
139139
if (!spec.showUi()) continue;
@@ -152,8 +152,7 @@ public static void onEndTick(ServerPlayer player) {
152152
float newVal = unit.getResourceTracker().decayKeyProgress(key, rt, decayPerSecond);
153153
int cint = (int) newVal;
154154
if (unit.getSpendRuntime().progressIntChanged(key, cint)) {
155-
com.robertx22.library_of_exile.main.Packets.sendToClient(player,
156-
new ThresholdUiPacket(key, rt.id, newVal > 0f, newVal));
155+
Packets.sendToClient(player, new ThresholdUiPacket(key, rt.id, newVal > 0f, newVal));
157156
}
158157
if (newVal <= 0f) {
159158
unit.getSpendRuntime().removeActive(rt, key);

src/main/java/com/robertx22/mine_and_slash/mechanics/thresholds/SpendThresholdManager.java

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33
import com.robertx22.mine_and_slash.capability.entity.EntityData;
44
import com.robertx22.mine_and_slash.event_hooks.my_events.OnResourceLost;
55
import com.robertx22.mine_and_slash.vanilla_mc.packets.ThresholdUiPacket;
6+
import com.robertx22.library_of_exile.main.Packets;
67
import com.robertx22.mine_and_slash.saveclasses.unit.ResourceType;
78
import net.minecraft.server.level.ServerPlayer;
9+
import net.minecraft.network.chat.Component;
810

911
public final class SpendThresholdManager {
1012
private SpendThresholdManager() {}
@@ -26,7 +28,7 @@ public static void processSpend(ServerPlayer sp, EntityData unit, ResourceType t
2628
var specs = SpendThresholdRegistry.resolveFor(unit, type);
2729
if (specs.isEmpty()) {
2830
if (debug) {
29-
sp.sendSystemMessage(net.minecraft.network.chat.Component.literal(
31+
sp.sendSystemMessage(Component.literal(
3032
"[SPEND] +" + String.format(java.util.Locale.US, "%.1f", loss) +
3133
" " + type.id + " (no specs)"
3234
));
@@ -43,7 +45,7 @@ public static void processSpend(ServerPlayer sp, EntityData unit, ResourceType t
4345
}
4446
if (debug) {
4547
long rem = unit.getSpendRuntime().cooldownRemainingTicks(key, now);
46-
sp.sendSystemMessage(net.minecraft.network.chat.Component.literal(
48+
sp.sendSystemMessage(Component.literal(
4749
"[SPEND:" + spec.key() + "] locked by cooldown (" + rem + "t ~ " + fmtSec((float) rem) + "s)"
4850
));
4951
}
@@ -55,10 +57,10 @@ public static void processSpend(ServerPlayer sp, EntityData unit, ResourceType t
5557
tracker.clearKey(type, key);
5658
}
5759
if (debug) {
58-
sp.sendSystemMessage(net.minecraft.network.chat.Component.literal("[SPEND:" + spec.key() + "] locked"));
60+
sp.sendSystemMessage(Component.literal("[SPEND:" + spec.key() + "] locked"));
5961
}
6062
if (spec.showUi()) {
61-
com.robertx22.library_of_exile.main.Packets.sendToClient(sp, new ThresholdUiPacket(key, type.id, false, 0));
63+
Packets.sendToClient(sp, new ThresholdUiPacket(key, type.id, false, 0));
6264
}
6365
continue;
6466
}
@@ -80,7 +82,7 @@ public static void processSpend(ServerPlayer sp, EntityData unit, ResourceType t
8082
}
8183
if (debug) dbg(sp, "[SPEND:" + spec.key() + "] " + type.id + " ×" + procs + " (thr=" + fmt(threshold) + ")");
8284
if (spec.showUi()) {
83-
com.robertx22.library_of_exile.main.Packets.sendToClient(sp, new ThresholdUiPacket(key, type.id, false, 0));
85+
Packets.sendToClient(sp, new ThresholdUiPacket(key, type.id, false, 0));
8486
}
8587
unit.getSpendRuntime().removeActive(type, key);
8688
} else {
@@ -92,7 +94,7 @@ public static void processSpend(ServerPlayer sp, EntityData unit, ResourceType t
9294
int cint = (int) cur;
9395
if (unit.getSpendRuntime().progressIntChanged(key, cint)) {
9496
boolean show = cur > 0f;
95-
com.robertx22.library_of_exile.main.Packets.sendToClient(sp, new ThresholdUiPacket(key, type.id, show, cur));
97+
Packets.sendToClient(sp, new ThresholdUiPacket(key, type.id, show, cur));
9698
}
9799
}
98100
if (cur <= 0f) {
@@ -105,7 +107,7 @@ public static void processSpend(ServerPlayer sp, EntityData unit, ResourceType t
105107
// --- helpers ---
106108
private static void dbg(ServerPlayer sp, String msg) {
107109
if (!OnResourceLost.DEBUG_ENABLED) return;
108-
sp.sendSystemMessage(net.minecraft.network.chat.Component.literal(msg));
110+
sp.sendSystemMessage(Component.literal(msg));
109111
}
110112
private static String fmt(float v) { return String.format(java.util.Locale.US, "%.1f", v); }
111113
private static String fmtSec(float s) { return String.format(java.util.Locale.US, "%.1f", s); }

src/main/java/com/robertx22/mine_and_slash/mechanics/thresholds/SpendThresholdRuntime.java

Lines changed: 65 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -9,58 +9,73 @@
99

1010
public class SpendThresholdRuntime {
1111

12-
private final Map<String, Long> cooldownUntil = new HashMap<>();
13-
14-
private final Map<String, Long> lastActivityTick = new HashMap<>();
15-
16-
private final Map<String, Long> lastDecayTick = new HashMap<>();
12+
private static final class KeyState {
13+
long cooldownUntil;
14+
long lastActivityTick;
15+
long lastDecayTick;
16+
int lastProgressIntSent = Integer.MIN_VALUE;
17+
SpendThresholdSpec spec;
18+
}
1719

18-
private final Map<String, Integer> lastProgressIntSent = new HashMap<>();
20+
private final Map<String, KeyState> states = new HashMap<>();
1921

2022
private final java.util.EnumMap<ResourceType, Set<String>> activeByResource = new java.util.EnumMap<>(ResourceType.class);
21-
private final Map<String, SpendThresholdSpec> specByKey = new HashMap<>();
23+
private final java.util.EnumMap<ResourceType, Set<String>> activeByResourceReadOnly = new java.util.EnumMap<>(ResourceType.class);
2224

2325
public void startCooldown(String key, long now, int cooldownTicks) {
2426
if (cooldownTicks <= 0) return;
25-
cooldownUntil.put(key, now + cooldownTicks);
27+
if (key == null || key.isEmpty()) return;
28+
KeyState ks = states.computeIfAbsent(key, __ -> new KeyState());
29+
ks.cooldownUntil = now + cooldownTicks;
2630
}
2731

2832
public boolean isCoolingDown(String key, long now) {
29-
Long until = cooldownUntil.get(key);
30-
return until != null && now < until;
33+
if (key == null || key.isEmpty()) return false;
34+
KeyState ks = states.get(key);
35+
return ks != null && now < ks.cooldownUntil;
3136
}
3237

3338
public int cooldownRemainingTicks(String key, long now) {
34-
Long until = cooldownUntil.get(key);
35-
if (until == null) return 0;
39+
if (key == null || key.isEmpty()) return 0;
40+
KeyState ks = states.get(key);
41+
long until = (ks == null) ? 0L : ks.cooldownUntil;
3642
long rem = until - now;
3743
return (int) Math.max(0, rem);
3844
}
3945

4046
// === Activity/Decay tracking ===
4147
public void markActivity(String key, long now) {
4248
if (key == null || key.isEmpty()) return;
43-
lastActivityTick.put(key, now);
44-
lastDecayTick.remove(key);
49+
KeyState ks = states.computeIfAbsent(key, __ -> new KeyState());
50+
ks.lastActivityTick = now;
51+
ks.lastDecayTick = 0L;
4552
}
4653

4754
public long getLastActivity(String key) {
48-
return lastActivityTick.getOrDefault(key, 0L);
55+
if (key == null || key.isEmpty()) return 0L;
56+
KeyState ks = states.get(key);
57+
return ks == null ? 0L : ks.lastActivityTick;
4958
}
5059

5160
public long getLastDecay(String key) {
52-
return lastDecayTick.getOrDefault(key, 0L);
61+
if (key == null || key.isEmpty()) return 0L;
62+
KeyState ks = states.get(key);
63+
return ks == null ? 0L : ks.lastDecayTick;
5364
}
5465

5566
public void markDecay(String key, long now) {
5667
if (key == null || key.isEmpty()) return;
57-
lastDecayTick.put(key, now);
68+
KeyState ks = states.computeIfAbsent(key, __ -> new KeyState());
69+
ks.lastDecayTick = now;
5870
}
5971

6072
public boolean progressIntChanged(String key, int intProgress) {
61-
Integer prev = lastProgressIntSent.get(key);
62-
if (prev == null || prev.intValue() != intProgress) {
63-
lastProgressIntSent.put(key, intProgress);
73+
if (key == null || key.isEmpty()) return false;
74+
KeyState ks = states.get(key);
75+
int prev = (ks == null) ? Integer.MIN_VALUE : ks.lastProgressIntSent;
76+
if (prev != intProgress) {
77+
if (ks == null) ks = states.computeIfAbsent(key, __ -> new KeyState());
78+
ks.lastProgressIntSent = intProgress;
6479
return true;
6580
}
6681
return false;
@@ -69,29 +84,50 @@ public boolean progressIntChanged(String key, int intProgress) {
6984
// === Active key index ===
7085
public void markActive(ResourceType rt, String key, SpendThresholdSpec spec) {
7186
if (rt == null || key == null || key.isEmpty() || spec == null) return;
72-
activeByResource.computeIfAbsent(rt, __ -> new HashSet<>()).add(key);
73-
specByKey.put(key, spec);
87+
Set<String> set = activeByResource.get(rt);
88+
if (set == null) {
89+
set = new HashSet<>();
90+
activeByResource.put(rt, set);
91+
activeByResourceReadOnly.put(rt, java.util.Collections.unmodifiableSet(set));
92+
}
93+
set.add(key);
94+
KeyState ks = states.computeIfAbsent(key, __ -> new KeyState());
95+
ks.spec = spec;
7496
}
7597

7698
public void removeActive(ResourceType rt, String key) {
7799
if (rt == null || key == null || key.isEmpty()) return;
78100
var set = activeByResource.get(rt);
79101
if (set != null) {
80102
set.remove(key);
81-
if (set.isEmpty()) activeByResource.remove(rt);
103+
if (set.isEmpty()) {
104+
activeByResource.remove(rt);
105+
activeByResourceReadOnly.remove(rt);
106+
}
107+
}
108+
KeyState ks = states.get(key);
109+
if (ks != null) {
110+
ks.spec = null;
111+
ks.lastActivityTick = 0L;
112+
ks.lastDecayTick = 0L;
113+
ks.lastProgressIntSent = Integer.MIN_VALUE;
82114
}
83-
specByKey.remove(key);
84-
lastActivityTick.remove(key);
85-
lastDecayTick.remove(key);
86-
lastProgressIntSent.remove(key);
87115
}
88116

89117
public Set<String> getActiveKeys(ResourceType rt) {
90118
var s = activeByResource.get(rt);
91-
return s == null ? java.util.Set.of() : java.util.Set.copyOf(s);
119+
if (s == null || s.isEmpty()) return java.util.Set.of();
120+
var view = activeByResourceReadOnly.get(rt);
121+
if (view == null) {
122+
view = java.util.Collections.unmodifiableSet(s);
123+
activeByResourceReadOnly.put(rt, view);
124+
}
125+
return view;
92126
}
93127

94128
public SpendThresholdSpec getSpec(String key) {
95-
return specByKey.get(key);
129+
if (key == null || key.isEmpty()) return null;
130+
KeyState ks = states.get(key);
131+
return ks == null ? null : ks.spec;
96132
}
97133
}

src/main/java/com/robertx22/mine_and_slash/mechanics/thresholds/SpendThresholdSpec.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ public abstract class SpendThresholdSpec {
1515
private final float perLevelFactor;
1616
private final String key;
1717

18-
// gating/cooldown controls
1918
private final Set<String> lockWhileEffectIds;
2019
private final int cooldownTicks;
2120
private final boolean lockWhileCooldown; // Used to lock the threshold while the cooldown is active. **RECOMMENDED FOR DEBUGGING ONLY**

0 commit comments

Comments
 (0)