-
Notifications
You must be signed in to change notification settings - Fork 7
NEW API + EVENT HOOKS (While_Leeching + Resource Tracker/Thresholds) #29
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: 1.20-Forge
Are you sure you want to change the base?
Changes from 4 commits
ff6fb59
bf52165
7336969
62bcd68
2559965
211c0ff
6ec6525
c0a0476
5aece79
1fdcb7f
f06bf30
e83314d
0ee8eb6
c364377
26310f1
5976286
308fd77
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -71,6 +71,8 @@ public class ModEffects implements ExileRegistryInit { | |||||
| public static EffectCtx BLIND = new EffectCtx("blind", "Blind", Elements.Shadow, EffectType.negative); | ||||||
| public static EffectCtx STUN = new EffectCtx("stun", "Stun", Elements.Physical, EffectType.negative); | ||||||
| public static EffectCtx GALE_FORCE = new EffectCtx("gale_force", "Gale Force", Elements.Physical, EffectType.beneficial); | ||||||
| public static EffectCtx WRATH_OF_THE_JUGGERNAUT = new EffectCtx("wrath_of_the_juggernaut", "Wrath of the Juggernaut", Elements.Physical, EffectType.beneficial); | ||||||
| public static EffectCtx BURNOUT = new EffectCtx("burnout", "Burnout", Elements.Physical, EffectType.negative); | ||||||
|
|
||||||
| // these could be used for map affixes | ||||||
| public static EffectCtx SLOW = new EffectCtx("slow", "Lethargy", Elements.Physical, EffectType.negative); | ||||||
|
|
@@ -105,8 +107,7 @@ public static List<EffectCtx> getCurses() { | |||||
|
|
||||||
| // ---------- Helper ---------- | ||||||
| private static EffectCtx state(String id, String name, Elements elem) { | ||||||
| // EffectCtx constructor already adds itself to ModEffects.ALL in this file's pattern | ||||||
| return new EffectCtx(id, name, elem, EffectType.beneficial); | ||||||
| return new EffectCtx(id, name, (elem != null ? elem : Elements.Physical), EffectType.beneficial); | ||||||
| } | ||||||
|
|
||||||
| // Pretty names for resources (UI text) | ||||||
|
|
@@ -119,13 +120,6 @@ private static EffectCtx state(String id, String name, Elements elem) { | |||||
| ); | ||||||
|
|
||||||
| // Suggested elements per resource (only used for coloring/category) | ||||||
| private static final Map<ResourceType, Elements> RES_ELEM = Map.of( | ||||||
| ResourceType.health, Elements.Physical, | ||||||
| ResourceType.mana, Elements.Cold, | ||||||
| ResourceType.energy, Elements.Nature, | ||||||
| ResourceType.magic_shield, Elements.Shadow, | ||||||
| ResourceType.blood, Elements.Fire | ||||||
| ); | ||||||
|
|
||||||
| // ---------- Generic flags ---------- | ||||||
| public static final EffectCtx LEECHING_STATE = state( | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In next PR after you move thresholds generation into |
||||||
|
|
@@ -141,14 +135,13 @@ private static EffectCtx state(String id, String name, Elements elem) { | |||||
|
|
||||||
| static { | ||||||
| for (var rt : RES_NAME.keySet()) { | ||||||
| var elem = RES_ELEM.get(rt); | ||||||
| var nice = RES_NAME.get(rt); | ||||||
|
|
||||||
| LEECHING_STATE_BY_RES.put( | ||||||
| rt, state("leeching_" + rt.id + "_state", "Leeching " + nice, elem) | ||||||
| rt, state("leeching_" + rt.id + "_state", "Leeching " + nice, null) | ||||||
|
||||||
| rt, state("leeching_" + rt.id + "_state", "Leeching " + nice, null) | |
| rt, statePhysical("leeching_" + rt.id + "_state", "Leeching " + nice) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, same thing here. I can't remove null. It causes errors because of how EffectCtx is setup.
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| rt, state("regen_" + rt.id + "_state", "Regenerating " + nice, null) | |
| rt, statePhysical("regen_" + rt.id + "_state", "Regenerating " + nice) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why statePhysical?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also changing it to:
REGEN_STATE_BY_RES.put(
rt, statePhysical("regen_" + rt.id + "_state", "Regenerating " + nice)
);
causes errors. Only rt, state("regen_" + rt.id + "_state", "Regenerating " + nice, null) is accepted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because that null you had before meant Elements.Physical in your state method little higher here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because that
nullyou had before meantElements.Physicalin yourstatemethod little higher here
Sure, but I can not change it to anything else other than using physical or another element. If you want me to change it to rt, state("regen_" + rt.id + "_state", "Regenerating " + nice, Elements.Physical) I can do that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, but I can not change it to anything else other than using physical. If you want me to change it to
rt, state("regen_" + rt.id + "_state", "Regenerating " + nice, Elements.Physical)I can do that.
Yea, either this or what I suggested before
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, but I can not change it to anything else other than using physical. If you want me to change it to
rt, state("regen_" + rt.id + "_state", "Regenerating " + nice, Elements.Physical)I can do that.Yea, either this or what I suggested before
I can't do what you suggested before because of how EffectCtx is defined. I will have to use a specific element from now on. Which I assume I can just default everything to phys if I have to.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,58 +9,77 @@ | |
|
|
||
| public class DataDrivenSpendThresholdSpec extends SpendThresholdSpec { | ||
|
|
||
| public enum ThresholdMode { X_PER_LEVEL, FLAT, PCT_OF_MAX } | ||
| public enum ThresholdMode { FLAT, PERCENT_OF_MAX } | ||
|
|
||
| private final ThresholdMode mode; | ||
| private final float value; | ||
| private final boolean multiplyByLevel; | ||
| @Nullable private final ResourceType pctMaxOf; | ||
| @Nullable private final ResourceType percentMaxOf; | ||
| private final boolean showUi; | ||
|
|
||
| public DataDrivenSpendThresholdSpec( | ||
| String key, | ||
| ResourceType resource, | ||
| ThresholdMode mode, | ||
| float value, | ||
| boolean multiplyByLevel, | ||
| @Nullable ResourceType pctMaxOf, | ||
| @Nullable ResourceType percentMaxOf, | ||
| Set<String> lockWhileEffectIds, | ||
| int cooldownTicks, | ||
| boolean lockWhileCooldown, | ||
| boolean dropProgressWhileLocked, | ||
| boolean resetProgressOnProc | ||
| boolean resetProgressOnProc, | ||
| boolean showUi | ||
| ) { | ||
| super(resource, /*perLevelFactor (unused)*/ 0f, key, | ||
| lockWhileEffectIds, cooldownTicks, lockWhileCooldown, dropProgressWhileLocked, resetProgressOnProc); | ||
| super(resource, 0f, key, | ||
| lockWhileEffectIds, cooldownTicks, lockWhileCooldown, dropProgressWhileLocked, resetProgressOnProc, showUi); | ||
| this.mode = mode; | ||
| this.value = value; | ||
| this.multiplyByLevel = multiplyByLevel; | ||
| this.pctMaxOf = pctMaxOf; | ||
| this.percentMaxOf = percentMaxOf; | ||
| this.showUi = showUi; | ||
| } | ||
|
|
||
| // Backward-compatible ctor (defaults showUi=false) | ||
| public DataDrivenSpendThresholdSpec( | ||
| String key, | ||
| ResourceType resource, | ||
| ThresholdMode mode, | ||
| float value, | ||
| boolean multiplyByLevel, | ||
| @Nullable ResourceType percentMaxOf, | ||
| Set<String> lockWhileEffectIds, | ||
| int cooldownTicks, | ||
| boolean lockWhileCooldown, | ||
| boolean dropProgressWhileLocked, | ||
| boolean resetProgressOnProc | ||
| ) { | ||
| this(key, resource, mode, value, multiplyByLevel, percentMaxOf, lockWhileEffectIds, cooldownTicks, lockWhileCooldown, dropProgressWhileLocked, resetProgressOnProc, false); | ||
| } | ||
|
|
||
| @Override | ||
| public float thresholdFor(EntityData unit) { | ||
| float base; | ||
| switch (mode) { | ||
| case X_PER_LEVEL: | ||
| base = value * Math.max(1, unit.getLevel()); | ||
| break; | ||
| case FLAT: | ||
| base = value * (multiplyByLevel ? Math.max(1, unit.getLevel()) : 1f); | ||
| break; | ||
| case PCT_OF_MAX: | ||
| ResourceType rt = (pctMaxOf != null) ? pctMaxOf : resource(); | ||
| float max = unit.getResources().getMax(unit.getEntity(), rt); | ||
| case PERCENT_OF_MAX -> { | ||
| // default to this spec's resource if percentOf is null | ||
| ResourceType tgt = (percentMaxOf != null) ? percentMaxOf : resource(); | ||
| float max = unit.getResources().getMax(unit.getEntity(), tgt); | ||
| base = (value / 100f) * max; | ||
| if (multiplyByLevel) base *= Math.max(1, unit.getLevel()); | ||
| break; | ||
| default: | ||
| base = 0f; | ||
| } | ||
| case FLAT -> base = value; | ||
| default -> base = value; | ||
| } | ||
| if (multiplyByLevel) base *= Math.max(1, unit.getLevel()); | ||
| return Math.max(0f, base); | ||
| } | ||
|
|
||
| @Override | ||
| public void onProc(ServerPlayer sp, int procs) { | ||
| // No default action here; datapack loader wires actions. | ||
| } | ||
|
|
||
| public boolean showUi() { return showUi; } | ||
|
|
||
| // Perk lock is handled by callers (anonymous subclass) when needed. | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this comment needed here?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, this will be implemented later. It is placeholder for now. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure, just make sure next time no placeholders are added. |
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,7 +6,6 @@ | |
| import com.robertx22.mine_and_slash.saveclasses.unit.ResourceType; | ||
| import net.minecraft.server.level.ServerPlayer; | ||
|
|
||
| import javax.annotation.Nullable; | ||
| import java.util.Collections; | ||
| import java.util.HashSet; | ||
| import java.util.Set; | ||
|
|
@@ -22,15 +21,11 @@ public abstract class SpendThresholdSpec { | |
| private final boolean lockWhileCooldown; // treat cooldown as a lock | ||
| private final boolean dropProgressWhileLocked; | ||
| private final boolean resetProgressOnProc; | ||
| private final boolean showUi; // whether to render progress HUD for this spec | ||
|
|
||
| // registry ordering (lower runs first) | ||
| private int priority = 0; | ||
|
|
||
| // Legacy/simple ctor | ||
| public SpendThresholdSpec(ResourceType resource, float perLevelFactor, String key) { | ||
| this(resource, perLevelFactor, key, Collections.emptySet(), 0, false, true, true); | ||
| } | ||
|
|
||
| // Full ctor used by data-driven impl | ||
| public SpendThresholdSpec(ResourceType resource, | ||
| float perLevelFactor, | ||
|
|
@@ -39,7 +34,8 @@ public SpendThresholdSpec(ResourceType resource, | |
| int cooldownTicks, | ||
| boolean lockWhileCooldown, | ||
| boolean dropProgressWhileLocked, | ||
| boolean resetProgressOnProc) { | ||
| boolean resetProgressOnProc, | ||
| boolean showUi) { | ||
| this.resource = resource; | ||
| this.perLevelFactor = perLevelFactor; | ||
| this.key = key; | ||
|
|
@@ -48,6 +44,19 @@ public SpendThresholdSpec(ResourceType resource, | |
| this.lockWhileCooldown = lockWhileCooldown; | ||
| this.dropProgressWhileLocked = dropProgressWhileLocked; | ||
| this.resetProgressOnProc = resetProgressOnProc; | ||
| this.showUi = showUi; | ||
| } | ||
|
|
||
| // Backward-compatible ctor (defaults showUi=false) | ||
| public SpendThresholdSpec(ResourceType resource, | ||
| float perLevelFactor, | ||
| String key, | ||
| Set<String> lockWhileEffectIds, | ||
| int cooldownTicks, | ||
| boolean lockWhileCooldown, | ||
| boolean dropProgressWhileLocked, | ||
| boolean resetProgressOnProc) { | ||
| this(resource, perLevelFactor, key, lockWhileEffectIds, cooldownTicks, lockWhileCooldown, dropProgressWhileLocked, resetProgressOnProc, false); | ||
| } | ||
|
|
||
| // ===== accessors ===== | ||
|
|
@@ -59,6 +68,7 @@ public SpendThresholdSpec(ResourceType resource, | |
| public boolean resetOnProc() { return resetProgressOnProc; } | ||
| public int cooldownTicks() { return cooldownTicks; } | ||
| public int priority() { return priority; } | ||
| public boolean showUi() { return showUi; } | ||
|
|
||
| // fluent config (for code-defined specs) | ||
|
||
| public SpendThresholdSpec withCooldownSeconds(int seconds) { | ||
Dubledice marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
@@ -88,9 +98,18 @@ public SpendThresholdSpec withPriority(int p) { | |
|
|
||
| private SpendThresholdSpec newWrapper(Set<String> lockIds, int cooldown, boolean lockCD, boolean dropLocked, boolean resetOnProc) { | ||
| // create a shallow “copy” retaining dynamic behavior (onProc/thresholdFor come from subclass) | ||
| return new SpendThresholdSpec(this.resource, this.perLevelFactor, this.key, lockIds, cooldown, lockCD, dropLocked, resetOnProc) { | ||
| return new SpendThresholdSpec(this.resource, this.perLevelFactor, this.key, lockIds, cooldown, lockCD, dropLocked, resetOnProc, this.showUi) { | ||
| @Override public float thresholdFor(EntityData unit) { return SpendThresholdSpec.this.thresholdFor(unit); } | ||
| @Override public void onProc(ServerPlayer sp, int procs) { SpendThresholdSpec.this.onProc(sp, procs); } | ||
| @Override public boolean isLockedFor(EntityData unit) { return SpendThresholdSpec.this.isLockedFor(unit); } | ||
| }.withPriority(this.priority); | ||
| } | ||
|
|
||
| public SpendThresholdSpec withShowUi(boolean on) { | ||
| return new SpendThresholdSpec(this.resource, this.perLevelFactor, this.key, this.lockWhileEffectIds, this.cooldownTicks, this.lockWhileCooldown, this.dropProgressWhileLocked, this.resetProgressOnProc, on) { | ||
| @Override public float thresholdFor(EntityData unit) { return SpendThresholdSpec.this.thresholdFor(unit); } | ||
| @Override public void onProc(ServerPlayer sp, int procs) { SpendThresholdSpec.this.onProc(sp, procs); } | ||
| @Override public boolean isLockedFor(EntityData unit) { return SpendThresholdSpec.this.isLockedFor(unit); } | ||
| }.withPriority(this.priority); | ||
| } | ||
|
|
||
|
|
@@ -104,12 +123,16 @@ public boolean isEffectLocked(EntityData unit) { | |
| if (lockWhileEffectIds.isEmpty()) return false; | ||
| var store = unit.getStatusEffectsData(); | ||
| for (String id : lockWhileEffectIds) { | ||
| ExileEffect fx = ExileDB.ExileEffects().get(id); | ||
| if (fx != null && store.has(fx)) return true; | ||
| ExileEffect effect = ExileDB.ExileEffects().get(id); | ||
| if (effect != null && store.has(effect)) return true; | ||
| } | ||
| return false; | ||
| } | ||
|
|
||
| public boolean isLockedFor(EntityData unit) { | ||
| return isEffectLocked(unit); | ||
| } | ||
|
|
||
| /** Start cooldown (no-op if cooldownTicks == 0). */ | ||
| public void startCooldown(EntityData unit, long now) { | ||
| if (cooldownTicks > 0) { | ||
|
|
@@ -122,7 +145,7 @@ public void startCooldown(EntityData unit, long now) { | |
|
|
||
| // time helpers | ||
| public static int secondsToTicks(int seconds) { | ||
| return (seconds <= 0) ? 0 : Math.max(1, seconds * 20); | ||
| return (seconds <= 0) ? 0 : seconds * 20; | ||
| } | ||
| public static float ticksToSeconds(int ticks) { return ticks / 20f; } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This has to be done as method overload