@@ -28,6 +28,9 @@ public class RuptureTask extends CancellableRunnable {
2828 private int damageTickTracker ;
2929 private int animationTick ;
3030 private final double pureTickDamage ;
31+ // failsafe to ensure Rupture always exits and does not run forever
32+ private int totalTicks = 0 ;
33+ private final int totalTickCeiling ;
3134
3235 /**
3336 * Constructor for the RuptureTask class.
@@ -41,7 +44,7 @@ public RuptureTask(@NotNull McMMOPlayer ruptureSource, @NotNull LivingEntity tar
4144 this .ruptureSource = ruptureSource ;
4245 this .targetEntity = targetEntity ;
4346 this .expireTick = mcMMO .p .getAdvancedConfig ().getRuptureDurationSeconds (targetEntity instanceof Player ) * 20 ;
44-
47+ this . totalTickCeiling = Math . min ( this . expireTick , 200 );
4548 this .ruptureTick = 0 ;
4649 this .damageTickTracker = 0 ;
4750 this .animationTick = ANIMATION_TICK_INTERVAL ; //Play an animation right away
@@ -68,6 +71,14 @@ public RuptureTask(@NotNull McMMOPlayer ruptureSource, @NotNull LivingEntity tar
6871
6972 @ Override
7073 public void run () {
74+ // always increment the fail-safe
75+ totalTicks ++;
76+
77+ if (totalTicks >= totalTickCeiling ) {
78+ this .cancel ();
79+ return ;
80+ }
81+
7182 //Check validity
7283 if (targetEntity .isValid ()) {
7384 ruptureTick += 1 ; //Advance rupture tick by 1.
@@ -78,7 +89,6 @@ public void run() {
7889 if (ruptureTick < expireTick ) {
7990 //Is it time to damage?
8091 if (damageTickTracker >= DAMAGE_TICK_INTERVAL ) {
81-
8292 damageTickTracker = 0 ; //Reset timer
8393 if (applyRupture ()) return ;
8494
@@ -92,8 +102,8 @@ public void run() {
92102 endRupture ();
93103 }
94104 } else {
95- targetEntity .removeMetadata (MetadataConstants .METADATA_KEY_RUPTURE , mcMMO .p );
96105 this .cancel (); //Task no longer needed
106+ targetEntity .removeMetadata (MetadataConstants .METADATA_KEY_RUPTURE , mcMMO .p );
97107 }
98108 }
99109
@@ -152,7 +162,7 @@ public void refreshRupture() {
152162 ruptureTick = 0 ;
153163 }
154164
155- public void endRupture () {
165+ private void endRupture () {
156166 targetEntity .removeMetadata (MetadataConstants .METADATA_KEY_RUPTURE , mcMMO .p );
157167 this .cancel (); //Task no longer needed
158168 }
@@ -171,6 +181,20 @@ private double calculateAdjustedTickDamage() {
171181 return tickDamage ;
172182 }
173183
184+ @ Override
185+ public final boolean equals (Object o ) {
186+ if (!(o instanceof RuptureTask that )) return false ;
187+
188+ return ruptureSource .equals (that .ruptureSource ) && targetEntity .equals (that .targetEntity );
189+ }
190+
191+ @ Override
192+ public int hashCode () {
193+ int result = ruptureSource .hashCode ();
194+ result = 31 * result + targetEntity .hashCode ();
195+ return result ;
196+ }
197+
174198 @ Override
175199 public String toString () {
176200 return "RuptureTask{" +
@@ -179,25 +203,10 @@ public String toString() {
179203 ", expireTick=" + expireTick +
180204 ", ruptureTick=" + ruptureTick +
181205 ", damageTickTracker=" + damageTickTracker +
206+ ", animationTick=" + animationTick +
182207 ", pureTickDamage=" + pureTickDamage +
208+ ", totalTicks=" + totalTicks +
209+ ", totalTickCeiling=" + totalTickCeiling +
183210 '}' ;
184211 }
185-
186- @ Override
187- public boolean equals (Object o ) {
188- if (this == o ) return true ;
189- if (o == null || getClass () != o .getClass ()) return false ;
190- RuptureTask that = (RuptureTask ) o ;
191- return expireTick == that .expireTick
192- && ruptureTick == that .ruptureTick
193- && damageTickTracker == that .damageTickTracker
194- && Double .compare (that .pureTickDamage , pureTickDamage ) == 0
195- && Objects .equal (ruptureSource , that .ruptureSource ) && Objects .equal (targetEntity , that .targetEntity );
196- }
197-
198- @ Override
199- public int hashCode () {
200- return Objects .hashCode (ruptureSource , targetEntity , expireTick ,
201- ruptureTick , damageTickTracker , pureTickDamage );
202- }
203212}
0 commit comments