@gamebob/axon-surge 0.13.0 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/dist/axon-surge.js +883 -670
  2. package/dist/config/GameConfig.d.ts +11 -0
  3. package/dist/config/GameConfig.d.ts.map +1 -1
  4. package/dist/core/GameEngine.d.ts +8 -1
  5. package/dist/core/GameEngine.d.ts.map +1 -1
  6. package/dist/entities/EnemyEntity.d.ts +4 -2
  7. package/dist/entities/EnemyEntity.d.ts.map +1 -1
  8. package/dist/entities/ExperienceOrb.d.ts +14 -0
  9. package/dist/entities/ExperienceOrb.d.ts.map +1 -0
  10. package/dist/i18n/locales.d.ts +8 -0
  11. package/dist/i18n/locales.d.ts.map +1 -1
  12. package/dist/physics/PhysicsEngine.d.ts.map +1 -1
  13. package/dist/physics/handlers/ChainReactionHelper.d.ts.map +1 -1
  14. package/dist/physics/handlers/ShieldCollisionHandler.d.ts +2 -1
  15. package/dist/physics/handlers/ShieldCollisionHandler.d.ts.map +1 -1
  16. package/dist/physics/handlers/ThrownCollisionHandler.d.ts +2 -1
  17. package/dist/physics/handlers/ThrownCollisionHandler.d.ts.map +1 -1
  18. package/dist/physics/handlers/VortexPhysicsHandler.d.ts.map +1 -1
  19. package/dist/powerups/PowerUpRegistry.d.ts.map +1 -1
  20. package/dist/powerups/PowerUpTypes.d.ts +1 -1
  21. package/dist/powerups/PowerUpTypes.d.ts.map +1 -1
  22. package/dist/render/CanvasRenderer.d.ts +4 -2
  23. package/dist/render/CanvasRenderer.d.ts.map +1 -1
  24. package/dist/strategies/FragmentClusterStrategy.d.ts.map +1 -1
  25. package/dist/strategies/HeavyShieldStrategy.d.ts.map +1 -1
  26. package/dist/strategies/PiercingCellStrategy.d.ts.map +1 -1
  27. package/dist/strategies/ToxicSporeStrategy.d.ts.map +1 -1
  28. package/dist/ui/ProgressBar.d.ts +3 -2
  29. package/dist/ui/ProgressBar.d.ts.map +1 -1
  30. package/package.json +1 -1
@@ -1,4 +1,4 @@
1
- class V {
1
+ class F {
2
2
  listeners = /* @__PURE__ */ new Map();
3
3
  on(t, e) {
4
4
  return this.listeners.has(t) || this.listeners.set(t, /* @__PURE__ */ new Set()), this.listeners.get(t).add(e), () => this.off(t, e);
@@ -36,7 +36,7 @@ class W {
36
36
  this.lastTime = t, this.updateCallback(e), this.renderCallback(), this.animationFrameId = requestAnimationFrame(this.tick);
37
37
  }
38
38
  }
39
- const k = {
39
+ const U = {
40
40
  core: {
41
41
  maxIntegrity: 3,
42
42
  invulnerabilityDuration: 1.5,
@@ -63,7 +63,11 @@ const k = {
63
63
  shield: {
64
64
  blastSpeed: 1600,
65
65
  hitboxRange: 280,
66
- isFanBlast: !1
66
+ protectionArc: Math.PI * 0.25,
67
+ isFanBlast: !1,
68
+ fanBlastInterval: 0.5,
69
+ fanBlastAngle: Math.PI / 4,
70
+ hasFanBlastUpgrade: !1
67
71
  },
68
72
  cluster: {
69
73
  fragmentCount: 6,
@@ -73,13 +77,19 @@ const k = {
73
77
  terminalAoERadius: 0,
74
78
  hasHoming: !1,
75
79
  homingTargets: 1
80
+ },
81
+ magnet: {
82
+ pickupRadius: 0,
83
+ psionicRadius: 70,
84
+ corePickupRadius: 120,
85
+ absorptionSpeed: 680
76
86
  }
77
87
  };
78
88
  class E {
79
89
  static instance;
80
90
  config;
81
91
  constructor() {
82
- this.config = JSON.parse(JSON.stringify(k));
92
+ this.config = JSON.parse(JSON.stringify(U));
83
93
  }
84
94
  static getInstance() {
85
95
  return E.instance || (E.instance = new E()), E.instance;
@@ -100,10 +110,10 @@ class E {
100
110
  this.config.core.maxIntegrity += t;
101
111
  }
102
112
  resetToDefault() {
103
- this.config = JSON.parse(JSON.stringify(k));
113
+ this.config = JSON.parse(JSON.stringify(U));
104
114
  }
105
115
  }
106
- class F {
116
+ class Y {
107
117
  position;
108
118
  radius;
109
119
  integrity;
@@ -123,8 +133,8 @@ class F {
123
133
  this.powerUpCount++, this.collectedPowerUpColors.push(t);
124
134
  const i = t.replace("#", "");
125
135
  if (i.length === 6) {
126
- const s = parseInt(i.substring(0, 2), 16), a = parseInt(i.substring(2, 4), 16), c = parseInt(i.substring(4, 6), 16);
127
- this.customColor.r = Math.round(this.customColor.r * (1 - e) + s * e), this.customColor.g = Math.round(this.customColor.g * (1 - e) + a * e), this.customColor.b = Math.round(this.customColor.b * (1 - e) + c * e);
136
+ const s = parseInt(i.substring(0, 2), 16), a = parseInt(i.substring(2, 4), 16), l = parseInt(i.substring(4, 6), 16);
137
+ this.customColor.r = Math.round(this.customColor.r * (1 - e) + s * e), this.customColor.g = Math.round(this.customColor.g * (1 - e) + a * e), this.customColor.b = Math.round(this.customColor.b * (1 - e) + l * e);
128
138
  }
129
139
  }
130
140
  getHitboxRadius() {
@@ -177,7 +187,9 @@ class w {
177
187
  maxSpeed = 200;
178
188
  isStationaryShield = !1;
179
189
  shieldAngle = 0;
190
+ launchDelay = 0;
180
191
  remainingHomingKills = 0;
192
+ experienceDropPending = !1;
181
193
  isDying = !1;
182
194
  deathType = "none";
183
195
  deathTimer = 0;
@@ -189,11 +201,11 @@ class w {
189
201
  getHitRadius() {
190
202
  return this.radius * (1 + this.hitRadiusPadding);
191
203
  }
192
- triggerDissolveDeath() {
193
- this.isDying || (this.isDying = !0, this.deathType = "dissolve", this.deathTimer = 0, this.maxDeathTimer = 0.45, this.velocity = { x: 0, y: 0 });
204
+ triggerDissolveDeath(t = !1) {
205
+ t && (this.experienceDropPending = !0), !this.isDying && (this.isDying = !0, this.deathType = "dissolve", this.deathTimer = 0, this.maxDeathTimer = 0.45, this.velocity = { x: 0, y: 0 });
194
206
  }
195
- triggerSliceDeath(t) {
196
- this.isDying || (this.isDying = !0, this.deathType = "sliced", this.deathTimer = 0, this.maxDeathTimer = 0.35, this.sliceAngle = t, this.velocity = { x: 0, y: 0 });
207
+ triggerSliceDeath(t, e = !1) {
208
+ e && (this.experienceDropPending = !0), !this.isDying && (this.isDying = !0, this.deathType = "sliced", this.deathTimer = 0, this.maxDeathTimer = 0.35, this.sliceAngle = t, this.velocity = { x: 0, y: 0 });
197
209
  }
198
210
  update(t) {
199
211
  if (this.active) {
@@ -201,7 +213,7 @@ class w {
201
213
  this.deathTimer += t, this.deathTimer >= this.maxDeathTimer && (this.active = !1, this.isDying = !1);
202
214
  return;
203
215
  }
204
- if (!(this.isGrabbed || this.isStationaryShield)) {
216
+ if (!(this.launchDelay > 0 && (this.launchDelay = Math.max(0, this.launchDelay - t), this.launchDelay > 0)) && !(this.isGrabbed || this.isStationaryShield)) {
205
217
  if (!this.isThrown && this.maxSpeed > 0) {
206
218
  const e = Math.hypot(this.velocity.x, this.velocity.y);
207
219
  if (e > this.maxSpeed) {
@@ -214,7 +226,7 @@ class w {
214
226
  }
215
227
  }
216
228
  reset() {
217
- this.active = !1, this.isGrabbed = !1, this.isThrown = !1, this.wasManipulated = !1, this.isDying = !1, this.deathType = "none", this.deathTimer = 0, this.sliceAngle = 0, this.isStationaryShield = !1, this.shieldAngle = 0, this.position = { x: 0, y: 0 }, this.velocity = { x: 0, y: 0 }, this.rotation = 0, this.strategy = null, this.maxSpeed = 200;
229
+ this.active = !1, this.isGrabbed = !1, this.isThrown = !1, this.wasManipulated = !1, this.isDying = !1, this.deathType = "none", this.deathTimer = 0, this.sliceAngle = 0, this.isStationaryShield = !1, this.shieldAngle = 0, this.launchDelay = 0, this.experienceDropPending = !1, this.position = { x: 0, y: 0 }, this.velocity = { x: 0, y: 0 }, this.rotation = 0, this.strategy = null, this.maxSpeed = 200;
218
230
  }
219
231
  }
220
232
  class G {
@@ -234,7 +246,7 @@ class G {
234
246
  this.active && !this.isGrabbed && !this.isHovered && (this.orbitAngle += t * 0.25, this.position.x = e.x + Math.cos(this.orbitAngle) * this.orbitDistance, this.position.y = e.y + Math.sin(this.orbitAngle) * this.orbitDistance);
235
247
  }
236
248
  }
237
- class Y {
249
+ class Z {
238
250
  pointerPosition = { x: 0, y: 0 };
239
251
  isPointerDown = !1;
240
252
  grabbedEnemy = null;
@@ -246,16 +258,16 @@ class Y {
246
258
  this.canvas = t, this.bindEvents();
247
259
  }
248
260
  updatePointerPos(t, e) {
249
- const i = this.canvas.getBoundingClientRect(), s = i.width > 0 ? this.canvas.width / i.width : 1, a = i.height > 0 ? this.canvas.height / i.height : 1, c = performance.now() / 1e3;
261
+ const i = this.canvas.getBoundingClientRect(), s = i.width > 0 ? this.canvas.width / i.width : 1, a = i.height > 0 ? this.canvas.height / i.height : 1, l = performance.now() / 1e3;
250
262
  this.pointerPosition = {
251
263
  x: (t - i.left) * s,
252
264
  y: (e - i.top) * a
253
265
  }, this.pointerHistory.push({
254
266
  x: this.pointerPosition.x,
255
267
  y: this.pointerPosition.y,
256
- time: c
268
+ time: l
257
269
  });
258
- const n = c - 0.08;
270
+ const n = l - 0.08;
259
271
  this.pointerHistory = this.pointerHistory.filter((o) => o.time >= n), this.grabbedEnemy && (this.grabbedEnemy.position = { ...this.pointerPosition });
260
272
  }
261
273
  bindEvents() {
@@ -295,9 +307,9 @@ class Y {
295
307
  if (this.grabbedEnemy) return this.grabbedEnemy;
296
308
  const i = e ? 50 : 20;
297
309
  for (const s of t) {
298
- if (!s.active || s.isGrabbed || s.isThrown || s.wasManipulated) continue;
299
- const a = this.pointerPosition.x - s.position.x, c = this.pointerPosition.y - s.position.y;
300
- if (Math.hypot(a, c) <= s.getHitRadius() + i)
310
+ if (!s.active || s.isGrabbed || s.isThrown || s.wasManipulated || s.launchDelay > 0) continue;
311
+ const a = this.pointerPosition.x - s.position.x, l = this.pointerPosition.y - s.position.y;
312
+ if (Math.hypot(a, l) <= s.getHitRadius() + i)
301
313
  return s.isGrabbed = !0, this.grabbedEnemy = s, this.dragStart = { ...this.pointerPosition }, this.pointerHistory = [], s;
302
314
  }
303
315
  return null;
@@ -307,8 +319,8 @@ class Y {
307
319
  const i = e ? 50 : 20;
308
320
  for (const s of t) {
309
321
  if (!s.active || s.isGrabbed) continue;
310
- const a = this.pointerPosition.x - s.position.x, c = this.pointerPosition.y - s.position.y;
311
- if (Math.hypot(a, c) <= s.radius * 1.5 + i)
322
+ const a = this.pointerPosition.x - s.position.x, l = this.pointerPosition.y - s.position.y;
323
+ if (Math.hypot(a, l) <= s.radius * 1.5 + i)
312
324
  return s.isGrabbed = !0, this.grabbedOrb = s, s;
313
325
  }
314
326
  return null;
@@ -318,22 +330,22 @@ class Y {
318
330
  const t = this.grabbedEnemy;
319
331
  t.isGrabbed = !1, t.isThrown = !0, t.wasManipulated = !0;
320
332
  const i = performance.now() / 1e3 - 0.08, s = this.pointerHistory.filter((o) => o.time >= i);
321
- let a = 0, c = 0;
333
+ let a = 0, l = 0;
322
334
  if (s.length >= 2) {
323
- const o = s[0], r = s[s.length - 1], l = Math.max(0.01, r.time - o.time);
324
- a = (r.x - o.x) / l, c = (r.y - o.y) / l;
335
+ const o = s[0], r = s[s.length - 1], c = Math.max(0.01, r.time - o.time);
336
+ a = (r.x - o.x) / c, l = (r.y - o.y) / c;
325
337
  }
326
- const n = Math.hypot(a, c);
338
+ const n = Math.hypot(a, l);
327
339
  if (n > 30) {
328
- const r = Math.min(n * 1.15, 2500), l = Math.atan2(c, a);
340
+ const r = Math.min(n * 1.15, 2500), c = Math.atan2(l, a);
329
341
  t.velocity = {
330
- x: Math.cos(l) * r,
331
- y: Math.sin(l) * r
342
+ x: Math.cos(c) * r,
343
+ y: Math.sin(c) * r
332
344
  };
333
345
  } else if (this.dragStart) {
334
- const o = t.position.x - this.dragStart.x, r = t.position.y - this.dragStart.y, l = Math.hypot(o, r);
335
- if (l > 5) {
336
- const h = Math.atan2(r, o), u = Math.min(l * 4, 600);
346
+ const o = t.position.x - this.dragStart.x, r = t.position.y - this.dragStart.y, c = Math.hypot(o, r);
347
+ if (c > 5) {
348
+ const h = Math.atan2(r, o), u = Math.min(c * 4, 600);
337
349
  t.velocity = {
338
350
  x: Math.cos(h) * u,
339
351
  y: Math.sin(h) * u
@@ -356,7 +368,7 @@ class Y {
356
368
  this.grabbedEnemy = null, this.grabbedOrb = null, this.dragStart = null, this.pointerHistory = [], this.isPointerDown = !1;
357
369
  }
358
370
  }
359
- class Z {
371
+ class z {
360
372
  cellSize;
361
373
  grid = /* @__PURE__ */ new Map();
362
374
  constructor(t = 100) {
@@ -367,17 +379,17 @@ class Z {
367
379
  }
368
380
  insert(t) {
369
381
  const e = Math.floor((t.position.x - t.radius) / this.cellSize), i = Math.floor((t.position.x + t.radius) / this.cellSize), s = Math.floor((t.position.y - t.radius) / this.cellSize), a = Math.floor((t.position.y + t.radius) / this.cellSize);
370
- for (let c = e; c <= i; c++)
382
+ for (let l = e; l <= i; l++)
371
383
  for (let n = s; n <= a; n++) {
372
- const o = `${c}:${n}`;
384
+ const o = `${l}:${n}`;
373
385
  this.grid.has(o) || this.grid.set(o, /* @__PURE__ */ new Set()), this.grid.get(o).add(t);
374
386
  }
375
387
  }
376
388
  getNearby(t, e) {
377
- const i = /* @__PURE__ */ new Set(), s = Math.floor((t.x - e) / this.cellSize), a = Math.floor((t.x + e) / this.cellSize), c = Math.floor((t.y - e) / this.cellSize), n = Math.floor((t.y + e) / this.cellSize);
389
+ const i = /* @__PURE__ */ new Set(), s = Math.floor((t.x - e) / this.cellSize), a = Math.floor((t.x + e) / this.cellSize), l = Math.floor((t.y - e) / this.cellSize), n = Math.floor((t.y + e) / this.cellSize);
378
390
  for (let o = s; o <= a; o++)
379
- for (let r = c; r <= n; r++) {
380
- const l = `${o}:${r}`, h = this.grid.get(l);
391
+ for (let r = l; r <= n; r++) {
392
+ const c = `${o}:${r}`, h = this.grid.get(c);
381
393
  h && h.forEach((u) => i.add(u));
382
394
  }
383
395
  return i;
@@ -447,7 +459,7 @@ const O = {
447
459
  tutorialStep2Text: "PASO 2: LÁNZALO CON IMPULSO HACIA EL OBJETIVO",
448
460
  tutorialDragWarning: "¡LA MEJOR ESTRATEGIA ES LANZARLOS! LÁNZALO CON IMPULSO",
449
461
  levelUpChoose: "¡NIVEL {level}! ELIGE UN MODIFICADOR",
450
- rerollButton: "🎲 REROLL (1 DISPONIBLE)",
462
+ rerollButton: "🎲 REROLL ({count} DISPONIBLE)",
451
463
  pu_spore_radius_title: "EXPANSIÓN ÁCIDA",
452
464
  pu_spore_radius_desc: "+12% Radio Ácido",
453
465
  pu_spore_duration_title: "LONGEVIDAD ÁCIDA",
@@ -472,12 +484,20 @@ const O = {
472
484
  pu_piercer_homing_target_desc: "+1 Objetivo para el Corte Buscador",
473
485
  pu_shield_fan_title: "TRIPLE RAGAZO ARC",
474
486
  pu_shield_fan_desc: "Dispara 3 rayos en abanico",
487
+ pu_shield_fan_upgrade_title: "CADENCIA DEL ABANICO",
488
+ pu_shield_fan_upgrade_desc: "+0.35s entre rayos y +15° de apertura",
489
+ pu_shield_arc_title: "ARCO PROTECTOR",
490
+ pu_shield_arc_desc: "+30° de arco de protección",
475
491
  pu_vampirism_unlock_title: "BIO-VAMPIRISMO",
476
492
  pu_vampirism_unlock_desc: "Las bajas reparan vidas dañadas",
477
493
  pu_vampirism_boost_title: "IMPULSO VAMPÍRICO",
478
494
  pu_vampirism_boost_desc: "+0.3% Curación por baja",
479
495
  pu_core_ring_title: "SOBRECARGA DE NÚCLEO",
480
496
  pu_core_ring_desc: "+1 Anillo de Vida",
497
+ pu_magnet_radius_title: "CAMPO MAGNÉTICO",
498
+ pu_magnet_radius_desc: "+60 Radio de recogida de experiencia",
499
+ pu_magnet_strength_title: "ATRACCIÓN MAGNÉTICA",
500
+ pu_magnet_strength_desc: "+25% Velocidad de absorción de experiencia",
481
501
  pu_offscreen_radar_title: "RADAR PSÍONICO",
482
502
  pu_offscreen_radar_desc: "Detecta enemigos fuera de pantalla"
483
503
  },
@@ -504,7 +524,7 @@ const O = {
504
524
  tutorialStep2Text: "STEP 2: FLICK TOWARD TARGET WITH SWIPE SPEED",
505
525
  tutorialDragWarning: "THE BEST STRATEGY IS TO FLICK THEM! THROW WITH SWIPE SPEED",
506
526
  levelUpChoose: "LEVEL {level}! CHOOSE MODIFIER",
507
- rerollButton: "🎲 REROLL (1 AVAILABLE)",
527
+ rerollButton: "🎲 REROLL ({count} AVAILABLE)",
508
528
  pu_spore_radius_title: "ACID EXPANSION",
509
529
  pu_spore_radius_desc: "+12% Acid Radius",
510
530
  pu_spore_duration_title: "ACID LINGER",
@@ -529,12 +549,20 @@ const O = {
529
549
  pu_piercer_homing_target_desc: "+1 Target for Seeker Slice",
530
550
  pu_shield_fan_title: "TRIPLE ARC BLAST",
531
551
  pu_shield_fan_desc: "Fires 3 fan beams",
552
+ pu_shield_fan_upgrade_title: "FAN OVERDRIVE",
553
+ pu_shield_fan_upgrade_desc: "+0.35s between beams and +15° spread",
554
+ pu_shield_arc_title: "PROTECTIVE ARC",
555
+ pu_shield_arc_desc: "+30° shield protection arc",
532
556
  pu_vampirism_unlock_title: "BIO-VAMPIRISM",
533
557
  pu_vampirism_unlock_desc: "Kills repair damaged core rings",
534
558
  pu_vampirism_boost_title: "VAMPIRIC SURGE",
535
559
  pu_vampirism_boost_desc: "+0.3% Heal per kill",
536
560
  pu_core_ring_title: "NUCLEUS OVERCHARGE",
537
561
  pu_core_ring_desc: "+1 Life Ring",
562
+ pu_magnet_radius_title: "MAGNETIC FIELD",
563
+ pu_magnet_radius_desc: "+60 Experience pickup range",
564
+ pu_magnet_strength_title: "MAGNETIC PULL",
565
+ pu_magnet_strength_desc: "+25% Experience absorption speed",
538
566
  pu_offscreen_radar_title: "PSIONIC RADAR",
539
567
  pu_offscreen_radar_desc: "Detect off-screen enemies"
540
568
  },
@@ -561,7 +589,7 @@ const O = {
561
589
  tutorialStep2Text: "ETAPE 2: LANCEZ AVEC VITESSE VERS LA CIBLE",
562
590
  tutorialDragWarning: "LA MEILLEURE STRATEGIE EST DE LES LANCER !",
563
591
  levelUpChoose: "NIVEAU {level} ! CHOISISSEZ UN MODIFICATEUR",
564
- rerollButton: "🎲 RELANCER (1 DISPONIBLE)",
592
+ rerollButton: "🎲 RELANCER ({count} DISPONIBLE)",
565
593
  pu_spore_radius_title: "EXPANSION ACIDE",
566
594
  pu_spore_radius_desc: "+30% Rayon d'acide",
567
595
  pu_spore_duration_title: "LONGEVITE ACIDE",
@@ -616,7 +644,7 @@ const O = {
616
644
  tutorialStep2Text: "SCHRITT 2: SCHLEUDERE MIT SCHWUNG AUF DAS ZIEL",
617
645
  tutorialDragWarning: "DIE BESTE STRATEGIE IST ES SIE ZU SCHLEUDERN!",
618
646
  levelUpChoose: "LEVEL {level}! MODIFIKATOR WÄHLEN",
619
- rerollButton: "🎲 NEU WÜRFELN (1 VERFÜGBAR)",
647
+ rerollButton: "🎲 NEU WÜRFELN ({count} VERFÜGBAR)",
620
648
  pu_spore_radius_title: "SÄURE-EXPANSION",
621
649
  pu_spore_radius_desc: "+30% Säureradius",
622
650
  pu_spore_duration_title: "SÄURE-DAUER",
@@ -671,7 +699,7 @@ const O = {
671
699
  tutorialStep2Text: "PASSO 2: LANCIA CON VELOCITA VERSO IL BERSAGLIO",
672
700
  tutorialDragWarning: "LA STRATEGIA MIGLIORE E LANCIARLI!",
673
701
  levelUpChoose: "LIVELLO {level}! SCEGLI UN MODIFICATORE",
674
- rerollButton: "🎲 RILANCIA (1 DISPONIBILE)",
702
+ rerollButton: "🎲 RILANCIA ({count} DISPONIBILE)",
675
703
  pu_spore_radius_title: "ESPANSIONE ACIDA",
676
704
  pu_spore_radius_desc: "+30% Raggio Acido",
677
705
  pu_spore_duration_title: "DURATA ACIDA",
@@ -726,7 +754,7 @@ const O = {
726
754
  tutorialStep2Text: "PASSO 2: LANCE COM IMPULSO EM DIRECAO AO ALVO",
727
755
  tutorialDragWarning: "A MELHOR ESTRATEGIA E LANCA-LOS!",
728
756
  levelUpChoose: "NÍVEL {level}! ESCOLHA UM MODIFICADOR",
729
- rerollButton: "🎲 REROLAR (1 DISPONÍVEL)",
757
+ rerollButton: "🎲 REROLAR ({count} DISPONÍVEL)",
730
758
  pu_spore_radius_title: "EXPANSÃO ÁCIDA",
731
759
  pu_spore_radius_desc: "+30% Raio Ácido",
732
760
  pu_spore_duration_title: "LONGEVIDADE ÁCIDA",
@@ -781,7 +809,7 @@ const O = {
781
809
  tutorialStep2Text: "STAP 2: GOOI MET SNELHEID NAAR HET DOEL",
782
810
  tutorialDragWarning: "DE BESTE STRATEGIE IS OM ZE TE GOOIEN!",
783
811
  levelUpChoose: "NIVEAU {level}! KIES EEN MODIFICATOR",
784
- rerollButton: "🎲 HERROL (1 BESCHIKBAAR)",
812
+ rerollButton: "🎲 HERROL ({count} BESCHIKBAAR)",
785
813
  pu_spore_radius_title: "ZURE EXPANSIE",
786
814
  pu_spore_radius_desc: "+30% Zuurstraal",
787
815
  pu_spore_duration_title: "ZURE DUUR",
@@ -836,7 +864,7 @@ const O = {
836
864
  tutorialStep2Text: "STEG 2: KASTA MED HASTIGHET MOT MÅLET",
837
865
  tutorialDragWarning: "DEN BÄSTA STRATEGIN ÄR ATT KASTA DEM!",
838
866
  levelUpChoose: "NIVÅ {level}! VÄLJ MODIFIERARE",
839
- rerollButton: "🎲 SLÅ OM (1 TILLGÄNGLIG)",
867
+ rerollButton: "🎲 SLÅ OM ({count} TILLGÄNGLIG)",
840
868
  pu_spore_radius_title: "SYRA-EXPANSION",
841
869
  pu_spore_radius_desc: "+30% Syraradie",
842
870
  pu_spore_duration_title: "SYRA-VARAKTIGHET",
@@ -891,7 +919,7 @@ const O = {
891
919
  tutorialStep2Text: "KROK 2: RZUĆ Z PRĘDKOŚCIĄ W STRONĘ CELU",
892
920
  tutorialDragWarning: "NAJLEPSZA STRATEGIA TO RZUCANIE NIMI!",
893
921
  levelUpChoose: "POZIOM {level}! WYBIERZ MODYFIKATOR",
894
- rerollButton: "🎲 PRZEROSZADA (1 DOSTĘPNA)",
922
+ rerollButton: "🎲 PRZEROSZADA ({count} DOSTĘPNA)",
895
923
  pu_spore_radius_title: "EKSPANSJA KWASOWA",
896
924
  pu_spore_radius_desc: "+30% Promień kwasu",
897
925
  pu_spore_duration_title: "TRWAŁOŚĆ KWASOWA",
@@ -946,7 +974,7 @@ const O = {
946
974
  tutorialStep2Text: "LANGKAH 2: LEMPAR DENGAN KECEPATAN KE TARGET",
947
975
  tutorialDragWarning: "STRATEGI TERBAIK ADALAH MELEMPAR MEREKA!",
948
976
  levelUpChoose: "TINGKAT {level}! PILIH MODIFIKASI",
949
- rerollButton: "🎲 ACAK ULANG (1 TERSEDIA)",
977
+ rerollButton: "🎲 ACAK ULANG ({count} TERSEDIA)",
950
978
  pu_spore_radius_title: "EKSPANSI ASAM",
951
979
  pu_spore_radius_desc: "+30% Radius Asam",
952
980
  pu_spore_duration_title: "DURASI ASAM",
@@ -1001,7 +1029,7 @@ const O = {
1001
1029
  tutorialStep2Text: "ADIM 2: HEDEFE HIZLA FIRLATIN",
1002
1030
  tutorialDragWarning: "EN İYİ STRATEJİ ONLARI FIRLATMAKTIR!",
1003
1031
  levelUpChoose: "SEVİYE {level}! GÜÇLENDİRME SEÇ",
1004
- rerollButton: "🎲 YENİDEN ZAR AT (1 HAKK)",
1032
+ rerollButton: "🎲 YENİDEN ZAR AT ({count} HAKK)",
1005
1033
  pu_spore_radius_title: "ASİT GENİŞLEMESİ",
1006
1034
  pu_spore_radius_desc: "+30% Asit Yarıçapı",
1007
1035
  pu_spore_duration_title: "ASİT SÜRESİ",
@@ -1056,7 +1084,7 @@ const O = {
1056
1084
  tutorialStep2Text: "ШАГ 2: БРОСАЙТЕ С ИМПУЛЬСОМ В ЦЕЛЬ",
1057
1085
  tutorialDragWarning: "ЛУЧШАЯ СТРАТЕГИЯ - БРОСАТЬ ИХ С ИМПУЛЬСОМ!",
1058
1086
  levelUpChoose: "УРОВЕНЬ {level}! ВЫБЕРИТЕ МОДИФИКАТОР",
1059
- rerollButton: "🎲 ПЕРЕБРОСИТЬ (1 ДОСТУПЕН)",
1087
+ rerollButton: "🎲 ПЕРЕБРОСИТЬ ({count} ДОСТУПЕН)",
1060
1088
  pu_spore_radius_title: "КИСЛОТНОЕ РАСШИРЕНИЕ",
1061
1089
  pu_spore_radius_desc: "+30% Радиус кислоты",
1062
1090
  pu_spore_duration_title: "КИСЛОТНАЯ ДЛИТЕЛЬНОСТЬ",
@@ -1111,7 +1139,7 @@ const O = {
1111
1139
  tutorialStep2Text: "ステップ2: ターゲットに向けて勢いよくフリック",
1112
1140
  tutorialDragWarning: "最高の戦略は勢いよく投げることです!",
1113
1141
  levelUpChoose: "レベル {level}! 強化を選択",
1114
- rerollButton: "🎲 リロール (残り1回)",
1142
+ rerollButton: "🎲 リロール (残り{count}回)",
1115
1143
  pu_spore_radius_title: "アシッド拡大",
1116
1144
  pu_spore_radius_desc: "+30% アシッド範囲",
1117
1145
  pu_spore_duration_title: "アシッド持続",
@@ -1166,7 +1194,7 @@ const O = {
1166
1194
  tutorialStep2Text: "2단계: 표적을 향해 빠르게 튕기세요",
1167
1195
  tutorialDragWarning: "최선의 전략은 적을 튕겨 던지는 것입니다!",
1168
1196
  levelUpChoose: "레벨 {level}! 강화 선택",
1169
- rerollButton: "🎲 리롤 (1회 가능)",
1197
+ rerollButton: "🎲 리롤 ({count}회 가능)",
1170
1198
  pu_spore_radius_title: "산성 확장",
1171
1199
  pu_spore_radius_desc: "+30% 산성 범주",
1172
1200
  pu_spore_duration_title: "산성 지속",
@@ -1221,7 +1249,7 @@ const O = {
1221
1249
  tutorialStep2Text: "步骤 2: 朝目标快速挥动抛投",
1222
1250
  tutorialDragWarning: "最佳策略是快速挥动抛投!",
1223
1251
  levelUpChoose: "等级 {level}! 选择强化",
1224
- rerollButton: "🎲 重刷 (剩余1次)",
1252
+ rerollButton: "🎲 重刷 (剩余{count}次)",
1225
1253
  pu_spore_radius_title: "酸液扩张",
1226
1254
  pu_spore_radius_desc: "+30% 酸液范围",
1227
1255
  pu_spore_duration_title: "酸液持久",
@@ -1253,7 +1281,7 @@ const O = {
1253
1281
  pu_core_ring_title: "核心过载",
1254
1282
  pu_core_ring_desc: "+1 生命环"
1255
1283
  }
1256
- }, K = [
1284
+ }, V = [
1257
1285
  "es",
1258
1286
  "en",
1259
1287
  "fr",
@@ -1270,29 +1298,29 @@ const O = {
1270
1298
  "ko",
1271
1299
  "zh"
1272
1300
  ];
1273
- function P(y) {
1274
- return K.includes(y);
1301
+ function N(A) {
1302
+ return V.includes(A);
1275
1303
  }
1276
- const U = "axon_surge_language";
1277
- class z {
1304
+ const H = "axon_surge_language";
1305
+ class $ {
1278
1306
  currentLanguage;
1279
1307
  constructor(t) {
1280
1308
  this.currentLanguage = this.detectLanguage(t);
1281
1309
  }
1282
1310
  detectLanguage(t) {
1283
1311
  try {
1284
- const e = localStorage.getItem(U);
1285
- if (e && P(e))
1312
+ const e = localStorage.getItem(H);
1313
+ if (e && N(e))
1286
1314
  return e;
1287
1315
  } catch {
1288
1316
  }
1289
- if (t && P(t))
1317
+ if (t && N(t))
1290
1318
  return t;
1291
1319
  try {
1292
1320
  const e = (document.documentElement.lang || document.body?.getAttribute("lang") || document.documentElement.getAttribute("data-lang") || "").toLowerCase();
1293
1321
  if (e) {
1294
1322
  const i = e.split("-")[0];
1295
- if (i && P(i))
1323
+ if (i && N(i))
1296
1324
  return i;
1297
1325
  }
1298
1326
  } catch {
@@ -1301,7 +1329,7 @@ class z {
1301
1329
  const e = (navigator.language || navigator.languages && navigator.languages[0] || "").toLowerCase();
1302
1330
  if (e) {
1303
1331
  const i = e.split("-")[0];
1304
- if (i && P(i))
1332
+ if (i && N(i))
1305
1333
  return i;
1306
1334
  }
1307
1335
  } catch {
@@ -1312,7 +1340,7 @@ class z {
1312
1340
  if (O[t]) {
1313
1341
  this.currentLanguage = t;
1314
1342
  try {
1315
- localStorage.setItem(U, t);
1343
+ localStorage.setItem(H, t);
1316
1344
  } catch {
1317
1345
  }
1318
1346
  }
@@ -1322,32 +1350,32 @@ class z {
1322
1350
  }
1323
1351
  translate(t, e) {
1324
1352
  let s = (O[this.currentLanguage] || O.en)[t] || O.en[t] || String(t);
1325
- return e && Object.entries(e).forEach(([a, c]) => {
1326
- s = s.replace(`{${a}}`, String(c));
1353
+ return e && Object.entries(e).forEach(([a, l]) => {
1354
+ s = s.replace(`{${a}}`, String(l));
1327
1355
  }), s;
1328
1356
  }
1329
1357
  }
1330
- class $ {
1358
+ class X {
1331
1359
  static update(t, e, i) {
1332
1360
  const s = E.getInstance().getConfig();
1333
1361
  for (let a = t.length - 1; a >= 0; a--) {
1334
- const c = t[a];
1335
- if (c) {
1336
- c.duration += i;
1362
+ const l = t[a];
1363
+ if (l) {
1364
+ l.duration += i;
1337
1365
  for (const n of e) {
1338
- if (!n.active || n.isGrabbed || n.isDying || n.isStationaryShield || n.isThrown && n.type === "piercer") continue;
1339
- const o = c.position.x - n.position.x, r = c.position.y - n.position.y, l = Math.hypot(o, r);
1340
- if (l > 2 && l <= c.radius) {
1341
- const h = Math.pow(1 - l / c.radius, 0.7), u = c.pullForce * h, p = Math.atan2(r, o);
1342
- n.velocity.x += Math.cos(p) * u * i, n.velocity.y += Math.sin(p) * u * i, n.position.x += Math.cos(p) * u * i * 0.8, n.position.y += Math.sin(p) * u * i * 0.8;
1366
+ if (!n.active || n.isGrabbed || n.isDying || n.isStationaryShield || n.launchDelay > 0 || n.isThrown && n.type === "piercer") continue;
1367
+ const o = l.position.x - n.position.x, r = l.position.y - n.position.y, c = o * o + r * r, h = Math.sqrt(c);
1368
+ if (h > 2 && c <= l.radius * l.radius) {
1369
+ const u = Math.pow(1 - h / l.radius, 0.7), d = l.pullForce * u, _ = Math.atan2(r, o);
1370
+ n.velocity.x += Math.cos(_) * d * i, n.velocity.y += Math.sin(_) * d * i, n.position.x += Math.cos(_) * d * i * 0.8, n.position.y += Math.sin(_) * d * i * 0.8;
1343
1371
  }
1344
1372
  }
1345
- if (c.duration >= c.maxDuration) {
1373
+ if (l.duration >= l.maxDuration) {
1346
1374
  if (s.gravityVortex.hasImplosionLaunch)
1347
1375
  for (const n of e) {
1348
1376
  if (!n.active || n.isDying) continue;
1349
- const o = n.position.x - c.position.x, r = n.position.y - c.position.y;
1350
- if (Math.hypot(o, r) <= c.radius) {
1377
+ const o = n.position.x - l.position.x, r = n.position.y - l.position.y;
1378
+ if (o * o + r * r <= l.radius * l.radius) {
1351
1379
  const h = Math.atan2(r, o), u = 1200;
1352
1380
  n.isThrown = !0, n.wasManipulated = !0, n.velocity = {
1353
1381
  x: Math.cos(h) * u,
@@ -1361,32 +1389,32 @@ class $ {
1361
1389
  }
1362
1390
  }
1363
1391
  }
1364
- class X {
1365
- static update(t, e, i, s, a, c, n, o, r, l) {
1392
+ class j {
1393
+ static update(t, e, i, s, a, l, n, o, r, c) {
1366
1394
  for (const h of e) {
1367
- if (!h.active || h.isGrabbed || h.isDying) continue;
1368
- const u = t.position.x - h.position.x, p = t.position.y - h.position.y;
1369
- if (Math.hypot(u, p) <= t.getHitboxRadius() + h.radius) {
1395
+ if (!h.active || h.isGrabbed || h.isDying || h.launchDelay > 0) continue;
1396
+ const u = t.position.x - h.position.x, d = t.position.y - h.position.y;
1397
+ if (Math.hypot(u, d) <= t.getHitboxRadius() + h.radius) {
1370
1398
  if (h.active = !1, t.takeDamage()) {
1371
1399
  n.emit("onCoreDamaged", { currentIntegrity: t.integrity }), i.push({
1372
1400
  id: Math.random().toString(),
1373
1401
  position: { ...t.position },
1374
1402
  radius: 20,
1375
- maxRadius: Math.max(r, l) * 1.3,
1403
+ maxRadius: Math.max(r, c) * 1.3,
1376
1404
  color: "#00f0ff",
1377
1405
  alpha: 1,
1378
1406
  lifetime: 0,
1379
1407
  maxLifetime: 0.8
1380
- }), c.triggerScreenShake({ x: u, y: p }, 25), c.triggerHitstop(0.15), c.triggerFlash(0.6);
1381
- for (const d of e)
1382
- if (d.active && !d.isGrabbed) {
1383
- d.triggerDissolveDeath();
1384
- for (let m = 0; m < 8; m++) {
1385
- const x = Math.random() * Math.PI * 2, A = 100 + Math.random() * 200;
1408
+ }), l.triggerScreenShake({ x: u, y: d }, 25), l.triggerHitstop(0.15), l.triggerFlash(0.6);
1409
+ for (const p of e)
1410
+ if (p.active && !p.isGrabbed && p.launchDelay <= 0) {
1411
+ p.triggerDissolveDeath();
1412
+ for (let g = 0; g < 8; g++) {
1413
+ const m = Math.random() * Math.PI * 2, y = 100 + Math.random() * 200;
1386
1414
  s.push({
1387
1415
  id: Math.random().toString(),
1388
- position: { ...d.position },
1389
- velocity: { x: Math.cos(x) * A, y: Math.sin(x) * A },
1416
+ position: { ...p.position },
1417
+ velocity: { x: Math.cos(m) * y, y: Math.sin(m) * y },
1390
1418
  color: "#00f0ff",
1391
1419
  radius: 3 + Math.random() * 3,
1392
1420
  alpha: 1,
@@ -1412,10 +1440,10 @@ class X {
1412
1440
  }
1413
1441
  }
1414
1442
  }
1415
- class j {
1443
+ class q {
1416
1444
  execute(t) {
1417
- const { thrownEnemy: e, targetEnemy: i, shockwaves: s, particles: a, floatingTexts: c } = t;
1418
- i.active = !1, s.push({
1445
+ const { thrownEnemy: e, targetEnemy: i, shockwaves: s, particles: a, floatingTexts: l } = t;
1446
+ i.experienceDropPending = !0, i.active = !1, s.push({
1419
1447
  id: Math.random().toString(),
1420
1448
  position: { ...i.position },
1421
1449
  radius: 10,
@@ -1438,7 +1466,7 @@ class j {
1438
1466
  maxLifetime: 0.5
1439
1467
  });
1440
1468
  }
1441
- c.push({
1469
+ l.push({
1442
1470
  id: Math.random().toString(),
1443
1471
  text: "PIERCING SLICE",
1444
1472
  position: { ...i.position },
@@ -1451,9 +1479,9 @@ class j {
1451
1479
  });
1452
1480
  }
1453
1481
  }
1454
- class q {
1482
+ class Q {
1455
1483
  execute(t) {
1456
- const { thrownEnemy: e, pools: i, shockwaves: s, particles: a, floatingTexts: c, eventBus: n } = t, o = e.position, r = E.getInstance().getConfig();
1484
+ const { thrownEnemy: e, pools: i, shockwaves: s, particles: a, floatingTexts: l, eventBus: n } = t, o = e.position, r = E.getInstance().getConfig();
1457
1485
  i.push({
1458
1486
  id: Math.random().toString(),
1459
1487
  position: { ...o },
@@ -1471,7 +1499,7 @@ class q {
1471
1499
  lifetime: 0,
1472
1500
  maxLifetime: 0.6
1473
1501
  });
1474
- for (let l = 0; l < 45; l++) {
1502
+ for (let c = 0; c < 45; c++) {
1475
1503
  const h = Math.random() * Math.PI * 2, u = 120 + Math.random() * 260;
1476
1504
  a.push({
1477
1505
  id: Math.random().toString(),
@@ -1484,7 +1512,7 @@ class q {
1484
1512
  maxLifetime: 0.9
1485
1513
  });
1486
1514
  }
1487
- c.push({
1515
+ l.push({
1488
1516
  id: Math.random().toString(),
1489
1517
  text: "MASSIVE SPORE NEBULA",
1490
1518
  position: { ...o },
@@ -1494,13 +1522,13 @@ class q {
1494
1522
  lifetime: 0,
1495
1523
  maxLifetime: 1.2,
1496
1524
  size: 26
1497
- }), e.active = !1, n.emit("onPoolCreated", { position: o });
1525
+ }), e.experienceDropPending = !0, e.active = !1, n.emit("onPoolCreated", { position: o });
1498
1526
  }
1499
1527
  }
1500
- class Q {
1528
+ class tt {
1501
1529
  execute(t) {
1502
- const { thrownEnemy: e, targetEnemy: i, allEnemies: s, shockwaves: a, particles: c, floatingTexts: n } = t, o = i.position;
1503
- e.active = !1, i.active = !1, a.push({
1530
+ const { thrownEnemy: e, targetEnemy: i, allEnemies: s, shockwaves: a, particles: l, floatingTexts: n } = t, o = i.position;
1531
+ e.experienceDropPending = !0, i.experienceDropPending = !0, e.active = !1, i.active = !1, a.push({
1504
1532
  id: Math.random().toString(),
1505
1533
  position: { ...o },
1506
1534
  radius: 15,
@@ -1510,37 +1538,37 @@ class Q {
1510
1538
  lifetime: 0,
1511
1539
  maxLifetime: 0.6
1512
1540
  });
1513
- const r = E.getInstance().getConfig(), l = r.cluster.fragmentCount, h = r.cluster.hasHoming;
1514
- for (let u = 0; u < l; u++) {
1515
- const p = u * Math.PI * 2 / l, _ = 800 + Math.random() * 300, g = {
1516
- x: o.x + Math.cos(p) * 45,
1517
- y: o.y + Math.sin(p) * 45
1541
+ const r = E.getInstance().getConfig(), c = r.cluster.fragmentCount, h = r.cluster.hasHoming;
1542
+ for (let u = 0; u < c; u++) {
1543
+ const d = u * Math.PI * 2 / c, _ = 800 + Math.random() * 300, f = {
1544
+ x: o.x + Math.cos(d) * 45,
1545
+ y: o.y + Math.sin(d) * 45
1518
1546
  };
1519
- let d = p;
1547
+ let p = d;
1520
1548
  if (h) {
1521
- let x = null, A = 1 / 0;
1549
+ let m = null, y = 1 / 0;
1522
1550
  for (const b of s) {
1523
1551
  if (b === e || b === i || !b.active || b.isGrabbed || b.isDying) continue;
1524
- const I = Math.hypot(b.position.x - g.x, b.position.y - g.y);
1525
- I < A && (A = I, x = b);
1552
+ const I = Math.hypot(b.position.x - f.x, b.position.y - f.y);
1553
+ I < y && (y = I, m = b);
1526
1554
  }
1527
- x && (d = Math.atan2(x.position.y - g.y, x.position.x - g.x));
1555
+ m && (p = Math.atan2(m.position.y - f.y, m.position.x - f.x));
1528
1556
  }
1529
- const m = M.createEnemy("micro", g, {
1530
- x: g.x + Math.cos(d) * 500,
1531
- y: g.y + Math.sin(d) * 500
1557
+ const g = M.createEnemy("micro", f, {
1558
+ x: f.x + Math.cos(p) * 500,
1559
+ y: f.y + Math.sin(p) * 500
1532
1560
  });
1533
- m.isThrown = !0, m.wasManipulated = !0, m.velocity = {
1534
- x: Math.cos(d) * _,
1535
- y: Math.sin(d) * _
1536
- }, s.push(m);
1561
+ g.isThrown = !0, g.wasManipulated = !0, g.velocity = {
1562
+ x: Math.cos(p) * _,
1563
+ y: Math.sin(p) * _
1564
+ }, s.push(g);
1537
1565
  }
1538
1566
  for (let u = 0; u < 35; u++) {
1539
- const p = Math.random() * Math.PI * 2, _ = 200 + Math.random() * 300;
1540
- c.push({
1567
+ const d = Math.random() * Math.PI * 2, _ = 200 + Math.random() * 300;
1568
+ l.push({
1541
1569
  id: Math.random().toString(),
1542
1570
  position: { ...o },
1543
- velocity: { x: Math.cos(p) * _, y: Math.sin(p) * _ },
1571
+ velocity: { x: Math.cos(d) * _, y: Math.sin(d) * _ },
1544
1572
  color: "#ffd700",
1545
1573
  radius: 4 + Math.random() * 4,
1546
1574
  alpha: 1,
@@ -1561,51 +1589,49 @@ class Q {
1561
1589
  });
1562
1590
  }
1563
1591
  }
1564
- class tt {
1592
+ class et {
1565
1593
  execute(t) {
1566
- const { thrownEnemy: e, targetEnemy: i, vortices: s, shockwaves: a } = t, c = E.getInstance().getConfig(), n = {
1594
+ const { thrownEnemy: e, targetEnemy: i, vortices: s, shockwaves: a } = t, l = E.getInstance().getConfig(), n = {
1567
1595
  x: (e.position.x + i.position.x) / 2,
1568
1596
  y: (e.position.y + i.position.y) / 2
1569
1597
  };
1570
1598
  s.push({
1571
1599
  id: Math.random().toString(),
1572
1600
  position: n,
1573
- radius: Math.round(c.gravityVortex.baseRadius * 2.2),
1601
+ radius: Math.round(l.gravityVortex.baseRadius * 2.2),
1574
1602
  duration: 0,
1575
- maxDuration: c.gravityVortex.baseDuration * 1.5,
1576
- pullForce: c.gravityVortex.basePullForce * 1.6
1603
+ maxDuration: l.gravityVortex.baseDuration * 1.5,
1604
+ pullForce: l.gravityVortex.basePullForce * 1.6
1577
1605
  }), a.push({
1578
1606
  id: Math.random().toString(),
1579
1607
  position: n,
1580
1608
  radius: 20,
1581
- maxRadius: Math.round(c.gravityVortex.baseRadius * 2.2),
1609
+ maxRadius: Math.round(l.gravityVortex.baseRadius * 2.2),
1582
1610
  color: "#9d4edd",
1583
1611
  alpha: 1,
1584
1612
  lifetime: 0,
1585
1613
  maxLifetime: 0.65
1586
- }), e.triggerDissolveDeath(), i.triggerDissolveDeath();
1614
+ }), e.triggerDissolveDeath(!0), i.triggerDissolveDeath(!0);
1587
1615
  }
1588
1616
  }
1589
- class et {
1617
+ class it {
1590
1618
  execute(t) {
1591
- const { thrownEnemy: e, targetEnemy: i, allEnemies: s, shockwaves: a, particles: c, floatingTexts: n } = t, o = i.position.x - e.position.x, r = i.position.y - e.position.y, l = Math.atan2(r, o), h = E.getInstance().getConfig().shield, u = h.blastSpeed || 1400;
1592
- if (e.isStationaryShield = !1, e.isThrown = !0, e.wasManipulated = !0, e.rotation = l, e.velocity = {
1593
- x: Math.cos(l) * u,
1594
- y: Math.sin(l) * u
1595
- }, h.isFanBlast) {
1596
- const p = [-Math.PI / 4, Math.PI / 4];
1597
- for (const _ of p) {
1598
- const g = l + _, d = M.createEnemy("heavy", {
1599
- x: e.position.x + Math.cos(g) * 30,
1600
- y: e.position.y + Math.sin(g) * 30
1601
- }, { x: 0, y: 0 });
1602
- d.isStationaryShield = !1, d.isThrown = !0, d.wasManipulated = !0, d.shieldAngle = g, d.rotation = g, d.velocity = {
1603
- x: Math.cos(g) * u,
1604
- y: Math.sin(g) * u
1605
- }, s.push(d);
1606
- }
1619
+ const { thrownEnemy: e, targetEnemy: i, allEnemies: s, shockwaves: a, particles: l, floatingTexts: n } = t, o = i.position.x - e.position.x, r = i.position.y - e.position.y, c = Math.atan2(r, o), h = E.getInstance().getConfig().shield, u = h.blastSpeed || 1400, d = h.isFanBlast ? [0, -h.fanBlastAngle, h.fanBlastAngle] : [0];
1620
+ for (const [_, f] of d.entries()) {
1621
+ const p = c + f, g = _ === 0 ? e : M.createEnemy(
1622
+ "heavy",
1623
+ {
1624
+ x: e.position.x + Math.cos(p) * 30,
1625
+ y: e.position.y + Math.sin(p) * 30
1626
+ },
1627
+ { x: 0, y: 0 }
1628
+ );
1629
+ g.isStationaryShield = !1, g.isThrown = !0, g.wasManipulated = !0, g.shieldAngle = p, g.rotation = p, g.launchDelay = h.isFanBlast ? _ * h.fanBlastInterval : 0, g.velocity = {
1630
+ x: Math.cos(p) * u,
1631
+ y: Math.sin(p) * u
1632
+ }, g !== e && s.push(g);
1607
1633
  }
1608
- i.active = !1, i.triggerDissolveDeath(), n.push({
1634
+ i.active = !1, i.triggerDissolveDeath(!0), n.push({
1609
1635
  id: Math.random().toString(),
1610
1636
  text: "ARC BLAST!",
1611
1637
  position: { ...e.position },
@@ -1616,12 +1642,12 @@ class et {
1616
1642
  maxLifetime: 0.9,
1617
1643
  size: 24
1618
1644
  });
1619
- for (let p = 0; p < 50; p++) {
1620
- const _ = (Math.random() - 0.5) * 1.5, g = l + _, d = 300 + Math.random() * 500;
1621
- c.push({
1645
+ for (let _ = 0; _ < 50; _++) {
1646
+ const f = (Math.random() - 0.5) * 1.5, p = c + f, g = 300 + Math.random() * 500;
1647
+ l.push({
1622
1648
  id: Math.random().toString(),
1623
1649
  position: { ...e.position },
1624
- velocity: { x: Math.cos(g) * d, y: Math.sin(g) * d },
1650
+ velocity: { x: Math.cos(p) * g, y: Math.sin(p) * g },
1625
1651
  color: "#00f5ff",
1626
1652
  radius: 4 + Math.random() * 6,
1627
1653
  alpha: 1,
@@ -1649,19 +1675,19 @@ class M {
1649
1675
  }
1650
1676
  static configureEnemy(t, e, i, s) {
1651
1677
  t.type = e, t.position = { ...i }, t.active = !0, t.isGrabbed = !1, t.isThrown = !1;
1652
- const a = s.x - i.x, c = s.y - i.y, n = Math.atan2(c, a);
1653
- let o = 70, r = 100, l = 20, h = "#ff2a5f", u = null;
1654
- e === "piercer" ? (o = 95, r = 140, l = 18, h = "#ff2a5f", u = new j()) : e === "spore" ? (o = 65, r = 90, l = 24, h = "#39ff14", u = new q()) : e === "cluster" ? (o = 50, r = 75, l = 26, h = "#ffd700", u = new Q()) : e === "parasite" ? (o = 80, r = 110, l = 22, h = "#9d4edd", u = new tt()) : e === "heavy" ? (o = 35, r = 50, l = 34, h = "#00f5ff", u = new et(), t.rotation = Math.random() * Math.PI * 2) : e === "micro" && (o = 130, r = 160, l = 12, h = "#ffd700"), t.radius = l, t.color = h, t.strategy = u, t.maxSpeed = r, t.velocity = {
1678
+ const a = s.x - i.x, l = s.y - i.y, n = Math.atan2(l, a);
1679
+ let o = 70, r = 100, c = 20, h = "#ff2a5f", u = null;
1680
+ e === "piercer" ? (o = 95, r = 140, c = 18, h = "#ff2a5f", u = new q()) : e === "spore" ? (o = 65, r = 90, c = 24, h = "#39ff14", u = new Q()) : e === "cluster" ? (o = 50, r = 75, c = 26, h = "#ffd700", u = new tt()) : e === "parasite" ? (o = 80, r = 110, c = 22, h = "#9d4edd", u = new et()) : e === "heavy" ? (o = 35, r = 50, c = 34, h = "#00f5ff", u = new it(), t.rotation = Math.random() * Math.PI * 2) : e === "micro" && (o = 130, r = 160, c = 12, h = "#ffd700"), t.radius = c, t.color = h, t.strategy = u, t.maxSpeed = r, t.velocity = {
1655
1681
  x: Math.cos(n) * o,
1656
1682
  y: Math.sin(n) * o
1657
1683
  };
1658
1684
  }
1659
1685
  }
1660
- class T {
1661
- static killEnemy(t, e, i, s, a, c) {
1686
+ class L {
1687
+ static killEnemy(t, e, i, s, a, l) {
1662
1688
  if (!t.active || t.isDying) return;
1663
1689
  const n = E.getInstance().getConfig();
1664
- if (a.push({
1690
+ if (t.experienceDropPending = !0, a.push({
1665
1691
  id: Math.random().toString(),
1666
1692
  position: { ...t.position },
1667
1693
  radius: 10,
@@ -1671,7 +1697,7 @@ class T {
1671
1697
  lifetime: 0,
1672
1698
  maxLifetime: 0.5
1673
1699
  }), t.type === "spore")
1674
- t.triggerDissolveDeath(), i.push({
1700
+ t.triggerDissolveDeath(!0), i.push({
1675
1701
  id: Math.random().toString(),
1676
1702
  position: { ...t.position },
1677
1703
  radius: n.toxicPool.baseRadius,
@@ -1680,52 +1706,52 @@ class T {
1680
1706
  damage: n.toxicPool.damage
1681
1707
  });
1682
1708
  else if (t.type === "cluster") {
1683
- t.triggerDissolveDeath();
1709
+ t.triggerDissolveDeath(!0);
1684
1710
  const o = n.cluster.fragmentCount, r = n.cluster.hasHoming;
1685
- for (let l = 0; l < o; l++) {
1686
- const h = l * Math.PI * 2 / o, u = 750 + Math.random() * 250, p = {
1711
+ for (let c = 0; c < o; c++) {
1712
+ const h = c * Math.PI * 2 / o, u = 750 + Math.random() * 250, d = {
1687
1713
  x: t.position.x + Math.cos(h) * 40,
1688
1714
  y: t.position.y + Math.sin(h) * 40
1689
1715
  };
1690
1716
  let _ = h;
1691
1717
  if (r) {
1692
- let d = null, m = 1 / 0;
1693
- for (const x of c) {
1694
- if (x === t || !x.active || x.isGrabbed || x.isDying) continue;
1695
- const A = Math.hypot(x.position.x - p.x, x.position.y - p.y);
1696
- A < m && (m = A, d = x);
1718
+ let p = null, g = 1 / 0;
1719
+ for (const m of l) {
1720
+ if (m === t || !m.active || m.isGrabbed || m.isDying) continue;
1721
+ const y = Math.hypot(m.position.x - d.x, m.position.y - d.y);
1722
+ y < g && (g = y, p = m);
1697
1723
  }
1698
- d && (_ = Math.atan2(d.position.y - p.y, d.position.x - p.x));
1724
+ p && (_ = Math.atan2(p.position.y - d.y, p.position.x - d.x));
1699
1725
  }
1700
- const g = M.createEnemy("micro", p, {
1701
- x: p.x + Math.cos(_) * 500,
1702
- y: p.y + Math.sin(_) * 500
1726
+ const f = M.createEnemy("micro", d, {
1727
+ x: d.x + Math.cos(_) * 500,
1728
+ y: d.y + Math.sin(_) * 500
1703
1729
  });
1704
- g.isThrown = !0, g.wasManipulated = !0, g.velocity = {
1730
+ f.isThrown = !0, f.wasManipulated = !0, f.velocity = {
1705
1731
  x: Math.cos(_) * u,
1706
1732
  y: Math.sin(_) * u
1707
- }, c.push(g);
1733
+ }, l.push(f);
1708
1734
  }
1709
- } else t.type === "parasite" ? (t.triggerDissolveDeath(), s.push({
1735
+ } else t.type === "parasite" ? (t.triggerDissolveDeath(!0), s.push({
1710
1736
  id: Math.random().toString(),
1711
1737
  position: { ...t.position },
1712
1738
  radius: n.gravityVortex.baseRadius,
1713
1739
  duration: 0,
1714
1740
  maxDuration: n.gravityVortex.baseDuration,
1715
1741
  pullForce: n.gravityVortex.basePullForce
1716
- })) : t.type === "piercer" ? t.triggerSliceDeath(e) : t.triggerDissolveDeath();
1742
+ })) : t.type === "piercer" ? t.triggerSliceDeath(e, !0) : t.triggerDissolveDeath(!0);
1717
1743
  }
1718
1744
  }
1719
- class it {
1720
- static update(t, e, i, s, a, c, n, o, r, l, h, u, p) {
1721
- let _ = !1;
1722
- for (const g of t)
1723
- if (!(!g.active || !g.isThrown || g.isDying)) {
1724
- if (_ = !0, g.position.x < -120 || g.position.x > l + 120 || g.position.y < -120 || g.position.y > h + 120) {
1725
- if (g.type === "heavy") {
1745
+ class st {
1746
+ static update(t, e, i, s, a, l, n, o, r, c, h, u, d, _) {
1747
+ let f = !1;
1748
+ for (const p of t)
1749
+ if (!(!p.active || !p.isThrown || p.isDying || p.launchDelay > 0)) {
1750
+ if (f = !0, p.position.x < -120 || p.position.x > c + 120 || p.position.y < -120 || p.position.y > h + 120) {
1751
+ if (p.type === "heavy") {
1726
1752
  s.push({
1727
1753
  id: Math.random().toString(),
1728
- position: { ...g.position },
1754
+ position: { ...p.position },
1729
1755
  radius: 20,
1730
1756
  maxRadius: 350,
1731
1757
  color: "#00f5ff",
@@ -1733,12 +1759,12 @@ class it {
1733
1759
  lifetime: 0,
1734
1760
  maxLifetime: 0.6
1735
1761
  });
1736
- for (let d = 0; d < 40; d++) {
1737
- const m = Math.random() * Math.PI * 2, x = 250 + Math.random() * 450;
1762
+ for (let g = 0; g < 40; g++) {
1763
+ const m = Math.random() * Math.PI * 2, y = 250 + Math.random() * 450;
1738
1764
  a.push({
1739
1765
  id: Math.random().toString(),
1740
- position: { ...g.position },
1741
- velocity: { x: Math.cos(m) * x, y: Math.sin(m) * x },
1766
+ position: { ...p.position },
1767
+ velocity: { x: Math.cos(m) * y, y: Math.sin(m) * y },
1742
1768
  color: "#00f5ff",
1743
1769
  radius: 4 + Math.random() * 5,
1744
1770
  alpha: 1,
@@ -1746,13 +1772,13 @@ class it {
1746
1772
  maxLifetime: 0.6
1747
1773
  });
1748
1774
  }
1749
- } else if (g.type === "piercer") {
1750
- const d = E.getInstance().getConfig().piercer;
1751
- if (d.terminalAoERadius > 0) {
1752
- const m = d.terminalAoERadius;
1775
+ } else if (p.type === "piercer") {
1776
+ const g = E.getInstance().getConfig().piercer;
1777
+ if (g.terminalAoERadius > 0) {
1778
+ const m = g.terminalAoERadius;
1753
1779
  s.push({
1754
1780
  id: Math.random().toString(),
1755
- position: { ...g.position },
1781
+ position: { ...p.position },
1756
1782
  radius: 20,
1757
1783
  maxRadius: m,
1758
1784
  color: "#ff2a5f",
@@ -1760,30 +1786,30 @@ class it {
1760
1786
  lifetime: 0,
1761
1787
  maxLifetime: 0.6
1762
1788
  });
1763
- for (const x of t) {
1764
- if (!x.active || x.isGrabbed || x.isDying) continue;
1765
- const A = x.position.x - g.position.x, b = x.position.y - g.position.y;
1766
- Math.hypot(A, b) <= m && T.killEnemy(x, Math.atan2(b, A), e, i, s, t);
1789
+ for (const y of d.getNearby(p.position, m)) {
1790
+ if (!y.active || y.isGrabbed || y.isDying) continue;
1791
+ const b = y.position.x - p.position.x, I = y.position.y - p.position.y;
1792
+ b * b + I * I <= m * m && L.killEnemy(y, Math.atan2(I, b), e, i, s, t);
1767
1793
  }
1768
1794
  }
1769
1795
  }
1770
- g.active = !1, g.isThrown = !1;
1796
+ p.active = !1, p.isThrown = !1;
1771
1797
  continue;
1772
1798
  }
1773
- for (const d of t) {
1774
- if (d === g || !d.active || d.isGrabbed || d.isDying) continue;
1775
- const m = d.position.x - g.position.x, x = d.position.y - g.position.y;
1776
- if (Math.hypot(m, x) <= g.getHitRadius() + d.getHitRadius()) {
1777
- u.pos = { x: g.position.x, y: g.position.y };
1778
- const b = Math.atan2(g.velocity.y, g.velocity.x);
1779
- if (g.type === "heavy") {
1780
- u.kills++, T.killEnemy(d, g.rotation, e, i, s, t), n.triggerHitstop(0.04), n.triggerScreenShake({ x: m, y: x }, 8);
1781
- for (let I = 0; I < 8; I++) {
1782
- const S = g.rotation + (Math.random() - 0.5), f = 200 + Math.random() * 350;
1799
+ for (const g of d.getNearby(p.position, p.getHitRadius() + 80)) {
1800
+ if (g === p || !g.active || g.isGrabbed || g.isDying || g.launchDelay > 0) continue;
1801
+ const m = g.position.x - p.position.x, y = g.position.y - p.position.y, b = p.getHitRadius() + g.getHitRadius();
1802
+ if (m * m + y * y <= b * b) {
1803
+ u.pos = { x: p.position.x, y: p.position.y };
1804
+ const I = Math.atan2(p.velocity.y, p.velocity.x);
1805
+ if (p.type === "heavy") {
1806
+ u.kills++, L.killEnemy(g, p.rotation, e, i, s, t), n.triggerHitstop(0.04), n.triggerScreenShake({ x: m, y }, 8);
1807
+ for (let S = 0; S < 8; S++) {
1808
+ const v = p.rotation + (Math.random() - 0.5), x = 200 + Math.random() * 350;
1783
1809
  a.push({
1784
1810
  id: Math.random().toString(),
1785
- position: { ...d.position },
1786
- velocity: { x: Math.cos(S) * f, y: Math.sin(S) * f },
1811
+ position: { ...g.position },
1812
+ velocity: { x: Math.cos(v) * x, y: Math.sin(v) * x },
1787
1813
  color: "#00f5ff",
1788
1814
  radius: 3 + Math.random() * 4,
1789
1815
  alpha: 1,
@@ -1791,11 +1817,11 @@ class it {
1791
1817
  maxLifetime: 0.4
1792
1818
  });
1793
1819
  }
1794
- p && p();
1795
- } else if (g.type === "piercer") {
1796
- u.kills++, T.killEnemy(d, b, e, i, s, t), n.triggerHitstop(0.05), n.triggerScreenShake({ x: m, y: x }, 7), s.push({
1820
+ _ && _();
1821
+ } else if (p.type === "piercer") {
1822
+ u.kills++, L.killEnemy(g, I, e, i, s, t), n.triggerHitstop(0.05), n.triggerScreenShake({ x: m, y }, 7), s.push({
1797
1823
  id: Math.random().toString(),
1798
- position: { ...d.position },
1824
+ position: { ...g.position },
1799
1825
  radius: 10,
1800
1826
  maxRadius: 180,
1801
1827
  color: "#ff2a5f",
@@ -1803,12 +1829,12 @@ class it {
1803
1829
  lifetime: 0,
1804
1830
  maxLifetime: 0.45
1805
1831
  });
1806
- for (let I = 0; I < 16; I++) {
1807
- const S = Math.random() * Math.PI * 2, f = 150 + Math.random() * 300;
1832
+ for (let S = 0; S < 16; S++) {
1833
+ const v = Math.random() * Math.PI * 2, x = 150 + Math.random() * 300;
1808
1834
  a.push({
1809
1835
  id: Math.random().toString(),
1810
- position: { ...d.position },
1811
- velocity: { x: Math.cos(S) * f, y: Math.sin(S) * f },
1836
+ position: { ...g.position },
1837
+ velocity: { x: Math.cos(v) * x, y: Math.sin(v) * x },
1812
1838
  color: "#ff2a5f",
1813
1839
  radius: 3 + Math.random() * 3,
1814
1840
  alpha: 1,
@@ -1816,106 +1842,106 @@ class it {
1816
1842
  maxLifetime: 0.4
1817
1843
  });
1818
1844
  }
1819
- if (g.remainingHomingKills > 0) {
1820
- g.remainingHomingKills--;
1821
- let I = null, S = 1 / 0;
1822
- for (const f of t) {
1823
- if (f === g || f === d || !f.active || f.isGrabbed || f.isDying) continue;
1824
- const v = f.position.x - g.position.x, L = f.position.y - g.position.y, D = Math.hypot(v, L);
1825
- D < S && (S = D, I = f);
1845
+ if (p.remainingHomingKills > 0) {
1846
+ p.remainingHomingKills--;
1847
+ let S = null, v = 1 / 0;
1848
+ for (const x of t) {
1849
+ if (x === p || x === g || !x.active || x.isGrabbed || x.isDying) continue;
1850
+ const T = x.position.x - p.position.x, R = x.position.y - p.position.y, k = Math.hypot(T, R);
1851
+ k < v && (v = k, S = x);
1826
1852
  }
1827
- if (I) {
1828
- const f = Math.atan2(I.position.y - g.position.y, I.position.x - g.position.x), v = Math.hypot(g.velocity.x, g.velocity.y) || 1200;
1829
- g.rotation = f, g.velocity = {
1830
- x: Math.cos(f) * v,
1831
- y: Math.sin(f) * v
1853
+ if (S) {
1854
+ const x = Math.atan2(S.position.y - p.position.y, S.position.x - p.position.x), T = Math.hypot(p.velocity.x, p.velocity.y) || 1200;
1855
+ p.rotation = x, p.velocity = {
1856
+ x: Math.cos(x) * T,
1857
+ y: Math.sin(x) * T
1832
1858
  };
1833
1859
  }
1834
1860
  }
1835
- p && p();
1861
+ _ && _();
1836
1862
  } else {
1837
- const I = g.type === d.type, S = I ? 360 : 250;
1863
+ const S = p.type === g.type, v = S ? 360 : 250;
1838
1864
  s.push({
1839
1865
  id: Math.random().toString(),
1840
1866
  position: { ...u.pos },
1841
1867
  radius: 15,
1842
- maxRadius: S,
1843
- color: g.color,
1868
+ maxRadius: v,
1869
+ color: p.color,
1844
1870
  alpha: 1,
1845
1871
  lifetime: 0,
1846
1872
  maxLifetime: 0.55
1847
1873
  });
1848
- for (let f = 0; f < 45; f++) {
1849
- const v = Math.random() * Math.PI * 2, L = 200 + Math.random() * 450;
1874
+ for (let x = 0; x < 45; x++) {
1875
+ const T = Math.random() * Math.PI * 2, R = 200 + Math.random() * 450;
1850
1876
  a.push({
1851
1877
  id: Math.random().toString(),
1852
1878
  position: { ...u.pos },
1853
- velocity: { x: Math.cos(v) * L, y: Math.sin(v) * L },
1854
- color: g.color,
1879
+ velocity: { x: Math.cos(T) * R, y: Math.sin(T) * R },
1880
+ color: p.color,
1855
1881
  radius: 4 + Math.random() * 6,
1856
1882
  alpha: 1,
1857
1883
  lifetime: 0,
1858
1884
  maxLifetime: 0.7
1859
1885
  });
1860
1886
  }
1861
- if (g.strategy) {
1862
- g.strategy.execute({
1863
- thrownEnemy: g,
1864
- targetEnemy: d,
1887
+ if (p.strategy) {
1888
+ p.strategy.execute({
1889
+ thrownEnemy: p,
1890
+ targetEnemy: g,
1865
1891
  allEnemies: t,
1866
1892
  pools: e,
1867
1893
  vortices: i,
1868
1894
  shockwaves: s,
1869
1895
  particles: a,
1870
- floatingTexts: c,
1896
+ floatingTexts: l,
1871
1897
  eventBus: o,
1872
- width: l,
1898
+ width: c,
1873
1899
  height: h
1874
- }), u.kills += 2, p && p();
1900
+ }), u.kills += 2, _ && _();
1875
1901
  break;
1876
1902
  }
1877
- if (I) {
1878
- u.kills += 2, n.triggerHitstop(0.14), n.triggerFlash(0.5), n.triggerScreenShake({ x: m, y: x }, 16), c.push({
1903
+ if (S) {
1904
+ u.kills += 2, n.triggerHitstop(0.14), n.triggerFlash(0.5), n.triggerScreenShake({ x: m, y }, 16), l.push({
1879
1905
  id: Math.random().toString(),
1880
1906
  text: "COLOR SYNERGY!",
1881
1907
  position: { ...u.pos },
1882
1908
  velocity: { x: 0, y: -80 },
1883
- color: g.color,
1909
+ color: p.color,
1884
1910
  alpha: 1,
1885
1911
  lifetime: 0,
1886
1912
  maxLifetime: 1.2,
1887
1913
  size: 26
1888
1914
  });
1889
- const f = E.getInstance().getConfig();
1890
- g.type === "spore" ? e.push({
1915
+ const x = E.getInstance().getConfig();
1916
+ p.type === "spore" ? e.push({
1891
1917
  id: Math.random().toString(),
1892
1918
  position: { ...u.pos },
1893
- radius: Math.round(f.toxicPool.baseRadius * 2),
1919
+ radius: Math.round(x.toxicPool.baseRadius * 2),
1894
1920
  duration: 0,
1895
- maxDuration: f.toxicPool.synergyDuration,
1896
- damage: f.toxicPool.damage * 2
1897
- }) : g.type === "parasite" && i.push({
1921
+ maxDuration: x.toxicPool.synergyDuration,
1922
+ damage: x.toxicPool.damage * 2
1923
+ }) : p.type === "parasite" && i.push({
1898
1924
  id: Math.random().toString(),
1899
1925
  position: { ...u.pos },
1900
- radius: Math.round(f.gravityVortex.baseRadius * 1.8),
1926
+ radius: Math.round(x.gravityVortex.baseRadius * 1.8),
1901
1927
  duration: 0,
1902
- maxDuration: f.gravityVortex.synergyDuration,
1903
- pullForce: f.gravityVortex.synergyPullForce
1904
- }), T.killEnemy(g, b, e, i, s, t), T.killEnemy(d, b, e, i, s, t);
1928
+ maxDuration: x.gravityVortex.synergyDuration,
1929
+ pullForce: x.gravityVortex.synergyPullForce
1930
+ }), L.killEnemy(p, I, e, i, s, t), L.killEnemy(g, I, e, i, s, t);
1905
1931
  } else
1906
- u.kills += 2, n.triggerHitstop(0.08), n.triggerFlash(0.35), n.triggerScreenShake({ x: m, y: x }, 10), T.killEnemy(g, b, e, i, s, t), T.killEnemy(d, b, e, i, s, t);
1907
- for (const f of t) {
1908
- if (f === g || f === d || !f.active || f.isGrabbed || f.isDying) continue;
1909
- const v = f.position.x - u.pos.x, L = f.position.y - u.pos.y;
1910
- Math.hypot(v, L) <= S && f.type !== "micro" && (T.killEnemy(f, b, e, i, s, t), u.kills++);
1932
+ u.kills += 2, n.triggerHitstop(0.08), n.triggerFlash(0.35), n.triggerScreenShake({ x: m, y }, 10), L.killEnemy(p, I, e, i, s, t), L.killEnemy(g, I, e, i, s, t);
1933
+ for (const x of t) {
1934
+ if (x === p || x === g || !x.active || x.isGrabbed || x.isDying) continue;
1935
+ const T = x.position.x - u.pos.x, R = x.position.y - u.pos.y;
1936
+ Math.hypot(T, R) <= v && x.type !== "micro" && (L.killEnemy(x, I, e, i, s, t), u.kills++);
1911
1937
  }
1912
- p && p();
1938
+ _ && _();
1913
1939
  break;
1914
1940
  }
1915
1941
  }
1916
1942
  }
1917
1943
  }
1918
- r.value = u.kills, !_ && u.kills > 0 && (u.kills >= 2 && u.pos && c.push({
1944
+ r.value = u.kills, !f && u.kills > 0 && (u.kills >= 2 && u.pos && l.push({
1919
1945
  id: Math.random().toString(),
1920
1946
  text: `MULTIKILL x${u.kills}!`,
1921
1947
  position: { ...u.pos },
@@ -1928,155 +1954,167 @@ class it {
1928
1954
  }), o.emit("onComboUpdated", { combo: r.value }), u.kills = 0, u.pos = null);
1929
1955
  }
1930
1956
  }
1931
- class st {
1932
- static update(t, e, i, s, a, c, n, o) {
1957
+ class at {
1958
+ static update(t, e, i, s, a, l, n, o) {
1933
1959
  for (let r = t.length - 1; r >= 0; r--) {
1934
- const l = t[r];
1935
- if (l) {
1936
- l.duration += c;
1960
+ const c = t[r];
1961
+ if (c) {
1962
+ c.duration += l;
1937
1963
  for (const h of e) {
1938
- if (!h.active || h.isGrabbed || h.isDying || h.isThrown && h.type === "piercer") continue;
1939
- const u = h.position.x - l.position.x, p = h.position.y - l.position.y;
1940
- Math.hypot(u, p) <= l.radius && (T.killEnemy(h, 0, t, i, s, e), n.kills++, o && o());
1964
+ if (!h.active || h.isGrabbed || h.isDying || h.launchDelay > 0 || h.isThrown && h.type === "piercer") continue;
1965
+ const u = h.position.x - c.position.x, d = h.position.y - c.position.y;
1966
+ u * u + d * d <= c.radius * c.radius && (L.killEnemy(h, 0, t, i, s, e), n.kills++, o && o());
1941
1967
  }
1942
- l.duration >= l.maxDuration && t.splice(r, 1);
1968
+ c.duration >= c.maxDuration && t.splice(r, 1);
1943
1969
  }
1944
1970
  }
1945
1971
  }
1946
1972
  }
1947
- class at {
1948
- static update(t, e, i, s, a, c, n, o, r, l, h, u) {
1949
- for (const p of t)
1950
- if (!(!p.active || !p.isStationaryShield || p.isDying))
1951
- for (const _ of t) {
1952
- if (_ === p || !_.active || _.isGrabbed || _.isDying) continue;
1953
- const g = _.position.x - p.position.x, d = _.position.y - p.position.y;
1954
- if (Math.hypot(g, d) <= p.getHitRadius() + _.getHitRadius()) {
1955
- p.isStationaryShield = !1, p.strategy && p.strategy.execute({
1956
- thrownEnemy: p,
1957
- targetEnemy: _,
1973
+ class ot {
1974
+ static update(t, e, i, s, a, l, n, o, r, c, h, u, d) {
1975
+ const _ = E.getInstance().getConfig().shield.protectionArc;
1976
+ for (const f of t)
1977
+ if (!(!f.active || !f.isStationaryShield || f.isDying))
1978
+ for (const p of u.getNearby(f.position, f.getHitRadius() + 80)) {
1979
+ if (p === f || !p.active || p.isGrabbed || p.isDying || p.launchDelay > 0) continue;
1980
+ const g = p.position.x - f.position.x, m = p.position.y - f.position.y;
1981
+ let y = Math.atan2(m, g) - f.rotation;
1982
+ for (; y < -Math.PI; ) y += Math.PI * 2;
1983
+ for (; y > Math.PI; ) y -= Math.PI * 2;
1984
+ if (Math.abs(y) > _ / 2) continue;
1985
+ const b = f.getHitRadius() + p.getHitRadius();
1986
+ if (g * g + m * m <= b * b) {
1987
+ f.isStationaryShield = !1, f.strategy && f.strategy.execute({
1988
+ thrownEnemy: f,
1989
+ targetEnemy: p,
1958
1990
  allEnemies: t,
1959
1991
  pools: e,
1960
1992
  vortices: i,
1961
1993
  shockwaves: s,
1962
1994
  particles: a,
1963
- floatingTexts: c,
1995
+ floatingTexts: l,
1964
1996
  eventBus: o,
1965
- width: l,
1997
+ width: c,
1966
1998
  height: h
1967
- }), r.kills += 2, n.triggerHitstop(0.12), n.triggerScreenShake({ x: g, y: d }, 18), u && u();
1999
+ }), r.kills += 2, n.triggerHitstop(0.12), n.triggerScreenShake({ x: g, y: m }, 18), d && d();
1968
2000
  break;
1969
2001
  }
1970
2002
  }
1971
2003
  }
1972
2004
  }
1973
- class ot {
2005
+ class nt {
1974
2006
  spatialHash;
1975
2007
  eventBus;
1976
2008
  i18n;
1977
2009
  throwState = { kills: 0, pos: null };
1978
2010
  constructor(t, e) {
1979
- this.spatialHash = new Z(100), this.eventBus = t, this.i18n = e;
1980
- }
1981
- update(t, e, i, s, a, c, n, o, r, l, h, u, p, _) {
1982
- this.spatialHash.clear();
1983
- const g = E.getInstance().getConfig().piercer;
1984
- for (const d of i)
1985
- if (d.active && !d.isDying) {
1986
- if (d.isThrown && d.type === "piercer" && g.hasHoming && d.remainingHomingKills > 0) {
1987
- let m = null, x = 1 / 0;
1988
- for (const A of i) {
1989
- if (A === d || !A.active || A.isGrabbed || A.isDying) continue;
1990
- const b = A.position.x - d.position.x, I = A.position.y - d.position.y, S = Math.hypot(b, I);
1991
- S < x && (x = S, m = A);
2011
+ this.spatialHash = new z(100), this.eventBus = t, this.i18n = e;
2012
+ }
2013
+ update(t, e, i, s, a, l, n, o, r, c, h, u, d, _) {
2014
+ const f = E.getInstance().getConfig().piercer;
2015
+ for (const g of i)
2016
+ if (g.active && !g.isDying) {
2017
+ if (g.isThrown && g.type === "piercer" && f.hasHoming && g.remainingHomingKills > 0) {
2018
+ let m = null, y = 1 / 0;
2019
+ for (const b of i) {
2020
+ if (b === g || !b.active || b.isGrabbed || b.isDying) continue;
2021
+ const I = b.position.x - g.position.x, S = b.position.y - g.position.y, v = I * I + S * S;
2022
+ v < y && (y = v, m = b);
1992
2023
  }
1993
2024
  if (m) {
1994
- const A = Math.atan2(m.position.y - d.position.y, m.position.x - d.position.x), b = Math.max(Math.hypot(d.velocity.x, d.velocity.y), 1e3), I = 25 * t, S = Math.atan2(d.velocity.y, d.velocity.x);
1995
- let f = A - S;
1996
- for (; f < -Math.PI; ) f += Math.PI * 2;
1997
- for (; f > Math.PI; ) f -= Math.PI * 2;
1998
- const v = S + Math.sign(f) * Math.min(Math.abs(f), I);
1999
- d.rotation = v, d.velocity = {
2000
- x: Math.cos(v) * b,
2001
- y: Math.sin(v) * b
2025
+ const b = Math.atan2(m.position.y - g.position.y, m.position.x - g.position.x), I = Math.max(Math.hypot(g.velocity.x, g.velocity.y), 1e3), S = 25 * t, v = Math.atan2(g.velocity.y, g.velocity.x);
2026
+ let x = b - v;
2027
+ for (; x < -Math.PI; ) x += Math.PI * 2;
2028
+ for (; x > Math.PI; ) x -= Math.PI * 2;
2029
+ const T = v + Math.sign(x) * Math.min(Math.abs(x), S);
2030
+ g.rotation = T, g.velocity = {
2031
+ x: Math.cos(T) * I,
2032
+ y: Math.sin(T) * I
2002
2033
  };
2003
2034
  }
2004
2035
  }
2005
- if (d.isStationaryShield) {
2006
- let m = null, x = 1 / 0;
2007
- for (const A of i) {
2008
- if (A === d || !A.active || A.isGrabbed || A.isDying || A.isStationaryShield) continue;
2009
- const b = A.position.x - d.position.x, I = A.position.y - d.position.y, S = Math.hypot(b, I);
2010
- S < x && (x = S, m = A);
2036
+ if (g.isStationaryShield) {
2037
+ let m = null, y = 1 / 0;
2038
+ for (const b of i) {
2039
+ if (b === g || !b.active || b.isGrabbed || b.isDying || b.isStationaryShield) continue;
2040
+ const I = b.position.x - g.position.x, S = b.position.y - g.position.y, v = I * I + S * S;
2041
+ v < y && (y = v, m = b);
2011
2042
  }
2012
2043
  if (m) {
2013
- let b = Math.atan2(m.position.y - d.position.y, m.position.x - d.position.x) - d.rotation;
2014
- for (; b < -Math.PI; ) b += Math.PI * 2;
2015
- for (; b > Math.PI; ) b -= Math.PI * 2;
2016
- const I = 5 * t;
2017
- d.rotation += Math.sign(b) * Math.min(Math.abs(b), I);
2044
+ let I = Math.atan2(m.position.y - g.position.y, m.position.x - g.position.x) - g.rotation;
2045
+ for (; I < -Math.PI; ) I += Math.PI * 2;
2046
+ for (; I > Math.PI; ) I -= Math.PI * 2;
2047
+ const S = 5 * t;
2048
+ g.rotation += Math.sign(I) * Math.min(Math.abs(I), S);
2018
2049
  }
2019
2050
  }
2020
- d.update(t), this.spatialHash.insert(d);
2021
- } else d.active && d.isDying && d.update(t);
2022
- for (let d = c.length - 1; d >= 0; d--) {
2023
- const m = c[d];
2051
+ g.update(t);
2052
+ } else g.active && g.isDying && g.update(t);
2053
+ for (let g = l.length - 1; g >= 0; g--) {
2054
+ const m = l[g];
2024
2055
  if (!m) continue;
2025
2056
  m.lifetime += t;
2026
- const x = m.lifetime / m.maxLifetime;
2027
- m.radius = m.maxRadius * x, m.alpha = Math.max(0, 1 - x), m.lifetime >= m.maxLifetime && c.splice(d, 1);
2057
+ const y = m.lifetime / m.maxLifetime;
2058
+ m.radius = m.maxRadius * y, m.alpha = Math.max(0, 1 - y), m.lifetime >= m.maxLifetime && l.splice(g, 1);
2028
2059
  }
2029
- $.update(a, i, t), X.update(
2060
+ X.update(a, i, t), this.spatialHash.clear();
2061
+ for (const g of i)
2062
+ g.active && !g.isDying && g.launchDelay <= 0 && this.spatialHash.insert(g);
2063
+ j.update(
2030
2064
  e,
2031
2065
  i,
2032
- c,
2066
+ l,
2033
2067
  n,
2034
2068
  o,
2035
2069
  r,
2036
2070
  this.eventBus,
2037
2071
  h,
2038
2072
  u,
2039
- p
2040
- ), it.update(
2073
+ d
2074
+ ), st.update(
2041
2075
  i,
2042
2076
  s,
2043
2077
  a,
2044
- c,
2078
+ l,
2045
2079
  n,
2046
2080
  o,
2047
2081
  r,
2048
2082
  this.eventBus,
2049
- l,
2083
+ c,
2050
2084
  u,
2051
- p,
2085
+ d,
2052
2086
  this.throwState,
2087
+ this.spatialHash,
2053
2088
  _
2054
- ), st.update(
2089
+ ), at.update(
2055
2090
  s,
2056
2091
  i,
2057
2092
  a,
2058
- c,
2093
+ l,
2059
2094
  n,
2060
2095
  t,
2061
2096
  this.throwState,
2062
2097
  _
2063
- ), at.update(
2098
+ ), ot.update(
2064
2099
  i,
2065
2100
  s,
2066
2101
  a,
2067
- c,
2102
+ l,
2068
2103
  n,
2069
2104
  o,
2070
2105
  r,
2071
2106
  this.eventBus,
2072
2107
  this.throwState,
2073
2108
  u,
2074
- p,
2109
+ d,
2110
+ this.spatialHash,
2075
2111
  _
2076
2112
  );
2113
+ const p = 32;
2114
+ l.length > p && l.splice(0, l.length - p);
2077
2115
  }
2078
2116
  }
2079
- class nt {
2117
+ class rt {
2080
2118
  pool = [];
2081
2119
  constructor(t = 500) {
2082
2120
  for (let e = 0; e < t; e++) {
@@ -2096,7 +2134,7 @@ class nt {
2096
2134
  t.reset();
2097
2135
  }
2098
2136
  }
2099
- class R {
2137
+ class C {
2100
2138
  static getOffscreenPosition(t, e) {
2101
2139
  const i = Math.floor(Math.random() * 4), s = 70;
2102
2140
  return i === 0 ? { x: Math.random() * t, y: -s } : i === 1 ? { x: t + s, y: Math.random() * e } : i === 2 ? { x: Math.random() * t, y: e + s } : { x: -s, y: Math.random() * e };
@@ -2104,11 +2142,11 @@ class R {
2104
2142
  static spawnCircleOfDeath(t, e, i, s) {
2105
2143
  const a = [], n = Math.max(i, s) * 0.55 + 80;
2106
2144
  for (let o = 0; o < 18; o++) {
2107
- const r = o * Math.PI * 2 / 18, l = {
2145
+ const r = o * Math.PI * 2 / 18, c = {
2108
2146
  x: e.x + Math.cos(r) * n,
2109
2147
  y: e.y + Math.sin(r) * n
2110
- }, h = t.get(), u = ["piercer", "spore", "cluster", "parasite"], p = u[o % u.length];
2111
- M.configureEnemy(h, p, l, e), h.velocity = {
2148
+ }, h = t.get(), u = ["piercer", "spore", "cluster", "parasite"], d = u[o % u.length];
2149
+ M.configureEnemy(h, d, c, e), h.velocity = {
2112
2150
  x: Math.cos(r + Math.PI) * 55,
2113
2151
  y: Math.sin(r + Math.PI) * 55
2114
2152
  }, a.push(h);
@@ -2120,15 +2158,15 @@ class R {
2120
2158
  let o = { x: -60, y: -60 };
2121
2159
  n === 0 ? o = { x: Math.random() * e, y: -80 } : n === 1 ? o = { x: e + 80, y: Math.random() * i } : n === 2 ? o = { x: Math.random() * e, y: i + 80 } : o = { x: -80, y: Math.random() * i };
2122
2160
  for (let r = 0; r < 14; r++) {
2123
- const l = {
2161
+ const c = {
2124
2162
  x: (Math.random() - 0.5) * 60,
2125
2163
  y: (Math.random() - 0.5) * 60
2126
- }, h = { x: o.x + l.x, y: o.y + l.y }, u = t.get();
2164
+ }, h = { x: o.x + c.x, y: o.y + c.y }, u = t.get();
2127
2165
  M.configureEnemy(u, "spore", h, s);
2128
- const p = s.x - h.x, _ = s.y - h.y, g = Math.atan2(_, p);
2166
+ const d = s.x - h.x, _ = s.y - h.y, f = Math.atan2(_, d);
2129
2167
  u.velocity = {
2130
- x: Math.cos(g) * (50 + Math.random() * 20),
2131
- y: Math.sin(g) * (50 + Math.random() * 20)
2168
+ x: Math.cos(f) * (50 + Math.random() * 20),
2169
+ y: Math.sin(f) * (50 + Math.random() * 20)
2132
2170
  }, a.push(u);
2133
2171
  }
2134
2172
  return a;
@@ -2139,17 +2177,17 @@ class R {
2139
2177
  const r = {
2140
2178
  x: -60 - o * 40,
2141
2179
  y: n + Math.sin(o * 0.45) * 70
2142
- }, l = t.get();
2143
- M.configureEnemy(l, "cluster", r, s), l.velocity = { x: 75, y: Math.cos(o * 0.45) * 30 }, a.push(l);
2180
+ }, c = t.get();
2181
+ M.configureEnemy(c, "cluster", r, s), c.velocity = { x: 75, y: Math.cos(o * 0.45) * 30 }, a.push(c);
2144
2182
  }
2145
2183
  return a;
2146
2184
  }
2147
2185
  static spawnDoubleSpiral(t, e, i, s) {
2148
2186
  const a = [];
2149
2187
  for (let n = 0; n < 14; n++) {
2150
- const o = n / 14, r = o * Math.PI * 4, l = 120 + o * 450, h = {
2151
- x: e + Math.cos(r) * l,
2152
- y: -60 + Math.sin(r) * l
2188
+ const o = n / 14, r = o * Math.PI * 4, c = 120 + o * 450, h = {
2189
+ x: e + Math.cos(r) * c,
2190
+ y: -60 + Math.sin(r) * c
2153
2191
  }, u = t.get();
2154
2192
  M.configureEnemy(u, "parasite", h, s), a.push(u);
2155
2193
  }
@@ -2158,11 +2196,11 @@ class R {
2158
2196
  static spawnMarchingWall(t, e, i, s) {
2159
2197
  const a = [], n = Math.random() > 0.5;
2160
2198
  for (let o = 0; o < 12; o++) {
2161
- const r = o / 11 * i, l = {
2199
+ const r = o / 11 * i, c = {
2162
2200
  x: n ? -60 : e + 60,
2163
2201
  y: r
2164
2202
  }, h = t.get();
2165
- M.configureEnemy(h, "piercer", l, s), h.velocity = {
2203
+ M.configureEnemy(h, "piercer", c, s), h.velocity = {
2166
2204
  x: n ? 70 : -70,
2167
2205
  y: 0
2168
2206
  }, a.push(h);
@@ -2174,13 +2212,13 @@ class R {
2174
2212
  for (let n = 0; n < 10; n++) {
2175
2213
  const o = { x: -50 - n * 35, y: -50 - n * 35 }, r = t.get();
2176
2214
  M.configureEnemy(r, "spore", o, s), a.push(r);
2177
- const l = { x: e + 50 + n * 35, y: i + 50 + n * 35 }, h = t.get();
2178
- M.configureEnemy(h, "cluster", l, s), a.push(h);
2215
+ const c = { x: e + 50 + n * 35, y: i + 50 + n * 35 }, h = t.get();
2216
+ M.configureEnemy(h, "cluster", c, s), a.push(h);
2179
2217
  }
2180
2218
  return a;
2181
2219
  }
2182
2220
  }
2183
- class rt {
2221
+ class lt {
2184
2222
  wave = 1;
2185
2223
  pool;
2186
2224
  spawnTimer = 0;
@@ -2188,63 +2226,103 @@ class rt {
2188
2226
  patternCooldown = 0;
2189
2227
  initialGracePeriod = 6;
2190
2228
  constructor() {
2191
- this.pool = new nt(500);
2229
+ this.pool = new rt(500);
2192
2230
  }
2193
2231
  reset() {
2194
2232
  this.wave = 1, this.spawnTimer = 0, this.waveTimer = 0, this.patternCooldown = 0;
2195
2233
  }
2196
2234
  update(t, e, i, s, a) {
2197
2235
  this.waveTimer += t, this.spawnTimer += t, this.patternCooldown += t, this.applyFlockingBehaviors(e, t, a);
2198
- const c = e.filter((r) => r.active).length, n = Math.max(0.9, 2.2 - (this.wave - 1) * 0.18);
2199
- if (this.waveTimer > this.initialGracePeriod && this.patternCooldown > Math.max(12 - this.wave, 6) && c < 35) {
2236
+ const l = e.filter((r) => r.active).length, n = Math.max(0.9, 2.2 - (this.wave - 1) * 0.18);
2237
+ if (this.waveTimer > this.initialGracePeriod && this.patternCooldown > Math.max(12 - this.wave, 6) && l < 35) {
2200
2238
  this.patternCooldown = 0;
2201
2239
  const r = this.spawnPatternFormation(i, s, a);
2202
- for (const l of r)
2203
- e.push(l);
2240
+ for (const c of r)
2241
+ e.push(c);
2204
2242
  }
2205
2243
  const o = Math.min(18 + this.wave * 4, 80);
2206
- return this.spawnTimer >= n && c < o ? (this.spawnTimer = 0, this.spawnSingleEnemy(i, s, a)) : null;
2244
+ return this.spawnTimer >= n && l < o ? (this.spawnTimer = 0, this.spawnSingleEnemy(i, s, a)) : null;
2207
2245
  }
2208
2246
  spawnSingleEnemy(t, e, i) {
2209
- const s = R.getOffscreenPosition(t, e), a = Math.random();
2210
- let c = "piercer";
2211
- a > 0.75 ? c = "heavy" : a > 0.55 ? c = "parasite" : a > 0.35 ? c = "cluster" : a > 0.15 && (c = "spore");
2247
+ const s = C.getOffscreenPosition(t, e), a = Math.random();
2248
+ let l = "piercer";
2249
+ a > 0.75 ? l = "heavy" : a > 0.55 ? l = "parasite" : a > 0.35 ? l = "cluster" : a > 0.15 && (l = "spore");
2212
2250
  const n = this.pool.get();
2213
- return M.configureEnemy(n, c, s, i), n;
2251
+ return M.configureEnemy(n, l, s, i), n;
2214
2252
  }
2215
2253
  spawnPatternFormation(t, e, i) {
2216
2254
  const s = Math.random();
2217
- return s < 0.25 ? R.spawnCircleOfDeath(this.pool, i, t, e) : s < 0.5 ? R.spawnDenseCluster(this.pool, t, e, i) : s < 0.75 ? R.spawnSineSnake(this.pool, t, e, i) : R.spawnMarchingWall(this.pool, t, e, i);
2255
+ return s < 0.25 ? C.spawnCircleOfDeath(this.pool, i, t, e) : s < 0.5 ? C.spawnDenseCluster(this.pool, t, e, i) : s < 0.75 ? C.spawnSineSnake(this.pool, t, e, i) : C.spawnMarchingWall(this.pool, t, e, i);
2218
2256
  }
2219
2257
  applyFlockingBehaviors(t, e, i) {
2220
2258
  for (let a = 0; a < t.length; a++) {
2221
- const c = t[a];
2222
- if (!c.active || c.isGrabbed || c.isThrown || c.isDying) continue;
2259
+ const l = t[a];
2260
+ if (!l.active || l.isGrabbed || l.isThrown || l.isDying) continue;
2223
2261
  let n = 0, o = 0, r = 0;
2224
- for (let p = 0; p < t.length; p++) {
2225
- if (a === p) continue;
2226
- const _ = t[p];
2262
+ for (let d = 0; d < t.length; d++) {
2263
+ if (a === d) continue;
2264
+ const _ = t[d];
2227
2265
  if (!_.active || _.isGrabbed || _.isDying) continue;
2228
- const g = c.position.x - _.position.x, d = c.position.y - _.position.y, m = Math.hypot(g, d);
2229
- m > 0 && m < 70 && (n += g / m, o += d / m, r++);
2266
+ const f = l.position.x - _.position.x, p = l.position.y - _.position.y, g = Math.hypot(f, p);
2267
+ g > 0 && g < 70 && (n += f / g, o += p / g, r++);
2230
2268
  }
2231
- r > 0 && (n /= r, o /= r, c.velocity.x += n * 60 * e, c.velocity.y += o * 60 * e);
2232
- const l = i.x - c.position.x, h = i.y - c.position.y, u = Math.hypot(l, h);
2269
+ r > 0 && (n /= r, o /= r, l.velocity.x += n * 60 * e, l.velocity.y += o * 60 * e);
2270
+ const c = i.x - l.position.x, h = i.y - l.position.y, u = Math.hypot(c, h);
2233
2271
  if (u > 0) {
2234
- const p = 80 + Math.min(this.wave * 4, 40);
2235
- c.velocity.x += l / u * p * e, c.velocity.y += h / u * p * e;
2272
+ const d = 80 + Math.min(this.wave * 4, 40);
2273
+ l.velocity.x += c / u * d * e, l.velocity.y += h / u * d * e;
2274
+ }
2275
+ if (l.maxSpeed > 0) {
2276
+ const d = Math.hypot(l.velocity.x, l.velocity.y);
2277
+ if (d > l.maxSpeed) {
2278
+ const _ = l.maxSpeed / d;
2279
+ l.velocity.x *= _, l.velocity.y *= _;
2280
+ }
2236
2281
  }
2237
- if (c.maxSpeed > 0) {
2238
- const p = Math.hypot(c.velocity.x, c.velocity.y);
2239
- if (p > c.maxSpeed) {
2240
- const _ = c.maxSpeed / p;
2241
- c.velocity.x *= _, c.velocity.y *= _;
2282
+ }
2283
+ }
2284
+ }
2285
+ class ct {
2286
+ id;
2287
+ position;
2288
+ velocity;
2289
+ value;
2290
+ radius = 5;
2291
+ active = !0;
2292
+ isAbsorbing = !1;
2293
+ constructor(t, e = 1) {
2294
+ this.id = `xp_${Date.now()}_${Math.random()}`, this.position = { ...t }, this.value = e;
2295
+ const i = Math.random() * Math.PI * 2, s = 25 + Math.random() * 45;
2296
+ this.velocity = {
2297
+ x: Math.cos(i) * s,
2298
+ y: Math.sin(i) * s
2299
+ };
2300
+ }
2301
+ beginAbsorption() {
2302
+ this.active && (this.isAbsorbing = !0);
2303
+ }
2304
+ update(t, e, i, s) {
2305
+ if (this.active) {
2306
+ if (this.isAbsorbing) {
2307
+ const a = e.x - this.position.x, l = e.y - this.position.y, n = Math.hypot(a, l);
2308
+ if (n <= i + this.radius) {
2309
+ this.position = { ...e }, this.active = !1;
2310
+ return;
2242
2311
  }
2312
+ const o = Math.min(s + n * 0.7, 1600);
2313
+ this.velocity = {
2314
+ x: a / n * o,
2315
+ y: l / n * o
2316
+ };
2317
+ } else {
2318
+ const a = Math.pow(0.04, t);
2319
+ this.velocity.x *= a, this.velocity.y *= a;
2243
2320
  }
2321
+ this.position.x += this.velocity.x * t, this.position.y += this.velocity.y * t;
2244
2322
  }
2245
2323
  }
2246
2324
  }
2247
- const C = {
2325
+ const P = {
2248
2326
  bioluminescent: {
2249
2327
  bgInner: "#081220",
2250
2328
  bgMid: "#050b16",
@@ -2311,22 +2389,22 @@ const C = {
2311
2389
  vortexCore: "#274760",
2312
2390
  vortexMid: "#577c9e"
2313
2391
  }
2314
- }, N = "axon_surge_theme";
2315
- class lt {
2392
+ }, D = "axon_surge_theme";
2393
+ class ht {
2316
2394
  currentTheme = "dark";
2317
2395
  isExplicit = !1;
2318
2396
  targetElement;
2319
2397
  constructor(t, e) {
2320
2398
  e !== void 0 && (this.targetElement = e);
2321
2399
  try {
2322
- const i = localStorage.getItem(N);
2323
- if (i && C[i]) {
2400
+ const i = localStorage.getItem(D);
2401
+ if (i && P[i]) {
2324
2402
  this.currentTheme = i, this.isExplicit = !0, this.applyThemeToDOM();
2325
2403
  return;
2326
2404
  }
2327
2405
  } catch {
2328
2406
  }
2329
- if (t && C[t]) {
2407
+ if (t && P[t]) {
2330
2408
  this.currentTheme = t, this.isExplicit = !0, this.applyThemeToDOM();
2331
2409
  return;
2332
2410
  }
@@ -2336,10 +2414,10 @@ class lt {
2336
2414
  this.targetElement = t, this.isExplicit ? this.applyThemeToDOM() : this.currentTheme = this.detectParentOrSystemTheme();
2337
2415
  }
2338
2416
  setTheme(t) {
2339
- if (C[t]) {
2417
+ if (P[t]) {
2340
2418
  this.currentTheme = t, this.isExplicit = !0, this.applyThemeToDOM();
2341
2419
  try {
2342
- localStorage.setItem(N, t);
2420
+ localStorage.setItem(D, t);
2343
2421
  } catch {
2344
2422
  }
2345
2423
  }
@@ -2347,7 +2425,7 @@ class lt {
2347
2425
  clearExplicitTheme() {
2348
2426
  this.isExplicit = !1;
2349
2427
  try {
2350
- localStorage.removeItem(N);
2428
+ localStorage.removeItem(D);
2351
2429
  } catch {
2352
2430
  }
2353
2431
  this.removeThemeClasses(), this.currentTheme = this.detectParentOrSystemTheme();
@@ -2356,7 +2434,7 @@ class lt {
2356
2434
  return this.isExplicit || (this.currentTheme = this.detectParentOrSystemTheme()), this.currentTheme;
2357
2435
  }
2358
2436
  getPalette() {
2359
- return C[this.getTheme()] || C.dark;
2437
+ return P[this.getTheme()] || P.dark;
2360
2438
  }
2361
2439
  detectParentOrSystemTheme() {
2362
2440
  try {
@@ -2394,83 +2472,83 @@ class lt {
2394
2472
  this.targetElement.classList.add(t);
2395
2473
  }
2396
2474
  }
2397
- class ct {
2475
+ class ut {
2398
2476
  maxDistance = 800;
2399
2477
  maxThickness = 18;
2400
2478
  minThickness = 5;
2401
2479
  maxLength = 110;
2402
2480
  minLength = 50;
2403
2481
  render(t, e, i, s, a) {
2404
- for (const c of e) {
2405
- if (!c.active || c.isGrabbed || c.isDying) continue;
2406
- const n = c.position.x, o = c.position.y;
2482
+ for (const l of e) {
2483
+ if (!l.active || l.isGrabbed || l.isDying) continue;
2484
+ const n = l.position.x, o = l.position.y;
2407
2485
  if (n >= 0 && n <= i && o >= 0 && o <= s) continue;
2408
- const r = Math.min(i, Math.max(0, n)), l = Math.min(s, Math.max(0, o)), h = Math.hypot(n - r, o - l);
2486
+ const r = Math.min(i, Math.max(0, n)), c = Math.min(s, Math.max(0, o)), h = Math.hypot(n - r, o - c);
2409
2487
  if (h <= 0 || h > this.maxDistance) continue;
2410
- const u = Math.min(1, Math.max(0, h / this.maxDistance)), p = this.minThickness + (this.maxThickness - this.minThickness) * (1 - u), _ = this.minLength + (this.maxLength - this.minLength) * (1 - u), g = 0.55 + (1 - u) * 0.35;
2411
- if (t.save(), t.globalAlpha = g, t.shadowColor = c.color, t.shadowBlur = 14, t.strokeStyle = c.color, t.lineWidth = p, t.lineCap = "round", t.beginPath(), r === 0 || r === i) {
2412
- const d = Math.max(0, l - _ / 2), m = Math.min(s, l + _ / 2);
2413
- t.moveTo(r, d), t.lineTo(r, m);
2488
+ const u = Math.min(1, Math.max(0, h / this.maxDistance)), d = this.minThickness + (this.maxThickness - this.minThickness) * (1 - u), _ = this.minLength + (this.maxLength - this.minLength) * (1 - u), f = 0.55 + (1 - u) * 0.35;
2489
+ if (t.save(), t.globalAlpha = f, t.shadowColor = l.color, t.shadowBlur = 14, t.strokeStyle = l.color, t.lineWidth = d, t.lineCap = "round", t.beginPath(), r === 0 || r === i) {
2490
+ const p = Math.max(0, c - _ / 2), g = Math.min(s, c + _ / 2);
2491
+ t.moveTo(r, p), t.lineTo(r, g);
2414
2492
  } else {
2415
- const d = Math.max(0, r - _ / 2), m = Math.min(i, r + _ / 2);
2416
- t.moveTo(d, l), t.lineTo(m, l);
2493
+ const p = Math.max(0, r - _ / 2), g = Math.min(i, r + _ / 2);
2494
+ t.moveTo(p, c), t.lineTo(g, c);
2417
2495
  }
2418
- t.stroke(), t.strokeStyle = a.effectHighlight, t.lineWidth = Math.max(1.8, p * 0.28), t.globalAlpha = g * 0.9, t.stroke(), t.restore();
2496
+ t.stroke(), t.strokeStyle = a.effectHighlight, t.lineWidth = Math.max(1.8, d * 0.28), t.globalAlpha = f * 0.9, t.stroke(), t.restore();
2419
2497
  }
2420
2498
  }
2421
2499
  }
2422
- class ht {
2423
- render(t, e, i, s, a, c, n = !1) {
2424
- const o = Math.max(1, a), r = Math.min(1, (o - 1) / 8), l = this.wrapHue(190 + (o - 1) * 34 + Math.sin(s * 0.1) * 5), h = this.wrapHue(l + 42), u = this.wrapHue(l + 150), p = e / 2, _ = i / 2, g = Math.max(e, i) * 0.82, d = t.createRadialGradient(p, _, 20, p, _, g);
2425
- n ? (d.addColorStop(0, `hsl(${l}, 42%, 91%)`), d.addColorStop(0.42, `hsl(${h}, 42%, 86%)`), d.addColorStop(0.78, `hsl(${u}, 38%, 81%)`), d.addColorStop(1, c.bgOuter)) : (d.addColorStop(0, `hsl(${l}, 42%, 11%)`), d.addColorStop(0.42, `hsl(${h}, 48%, 8%)`), d.addColorStop(0.78, `hsl(${u}, 42%, 5%)`), d.addColorStop(1, `hsl(${u}, 48%, 2.5%)`)), t.fillStyle = d, t.fillRect(0, 0, e, i);
2426
- const m = Math.min(e, i) * 0.055;
2500
+ class pt {
2501
+ render(t, e, i, s, a, l, n = !1) {
2502
+ const o = Math.max(1, a), r = Math.min(1, (o - 1) / 8), c = this.wrapHue(190 + (o - 1) * 34 + Math.sin(s * 0.1) * 5), h = this.wrapHue(c + 42), u = this.wrapHue(c + 150), d = e / 2, _ = i / 2, f = Math.max(e, i) * 0.82, p = t.createRadialGradient(d, _, 20, d, _, f);
2503
+ n ? (p.addColorStop(0, `hsl(${c}, 42%, 91%)`), p.addColorStop(0.42, `hsl(${h}, 42%, 86%)`), p.addColorStop(0.78, `hsl(${u}, 38%, 81%)`), p.addColorStop(1, l.bgOuter)) : (p.addColorStop(0, `hsl(${c}, 42%, 11%)`), p.addColorStop(0.42, `hsl(${h}, 48%, 8%)`), p.addColorStop(0.78, `hsl(${u}, 42%, 5%)`), p.addColorStop(1, `hsl(${u}, 48%, 2.5%)`)), t.fillStyle = p, t.fillRect(0, 0, e, i);
2504
+ const g = Math.min(e, i) * 0.055;
2427
2505
  this.drawNebula(
2428
2506
  t,
2429
- e * 0.22 + Math.sin(s * 0.18) * m,
2430
- i * 0.28 + Math.cos(s * 0.15) * m,
2507
+ e * 0.22 + Math.sin(s * 0.18) * g,
2508
+ i * 0.28 + Math.cos(s * 0.15) * g,
2431
2509
  Math.max(e, i) * 0.42,
2432
- l,
2510
+ c,
2433
2511
  n ? 0.27 : 0.23,
2434
2512
  n
2435
2513
  ), this.drawNebula(
2436
2514
  t,
2437
- e * 0.8 + Math.cos(s * 0.14) * m,
2438
- i * 0.7 + Math.sin(s * 0.17) * m,
2515
+ e * 0.8 + Math.cos(s * 0.14) * g,
2516
+ i * 0.7 + Math.sin(s * 0.17) * g,
2439
2517
  Math.max(e, i) * 0.48,
2440
2518
  h,
2441
2519
  n ? 0.23 : 0.2,
2442
2520
  n
2443
2521
  ), this.drawNebula(
2444
2522
  t,
2445
- e * 0.86 + Math.sin(s * 0.11) * m * 0.7,
2446
- i * 0.16 + Math.cos(s * 0.13) * m * 0.7,
2523
+ e * 0.86 + Math.sin(s * 0.11) * g * 0.7,
2524
+ i * 0.16 + Math.cos(s * 0.13) * g * 0.7,
2447
2525
  Math.max(e, i) * 0.3,
2448
2526
  u,
2449
2527
  n ? 0.17 : 0.14,
2450
2528
  n
2451
- ), this.drawSoftFlows(t, e, i, s, l, r, n), this.drawParticleField(t, e, i, s, l, h, o, n);
2452
- const x = t.createRadialGradient(p, _, Math.min(e, i) * 0.28, p, _, g);
2453
- x.addColorStop(0, "rgba(0, 0, 0, 0)"), x.addColorStop(1, n ? "rgba(40, 60, 90, 0.09)" : "rgba(0, 0, 0, 0.2)"), t.fillStyle = x, t.fillRect(0, 0, e, i);
2529
+ ), this.drawSoftFlows(t, e, i, s, c, r, n), this.drawParticleField(t, e, i, s, c, h, o, n);
2530
+ const m = t.createRadialGradient(d, _, Math.min(e, i) * 0.28, d, _, f);
2531
+ m.addColorStop(0, "rgba(0, 0, 0, 0)"), m.addColorStop(1, n ? "rgba(40, 60, 90, 0.09)" : "rgba(0, 0, 0, 0.2)"), t.fillStyle = m, t.fillRect(0, 0, e, i);
2454
2532
  }
2455
- drawNebula(t, e, i, s, a, c, n) {
2533
+ drawNebula(t, e, i, s, a, l, n) {
2456
2534
  const o = t.createRadialGradient(e, i, 0, e, i, s), r = n ? 52 : 60;
2457
- o.addColorStop(0, `hsla(${a}, ${n ? 88 : 80}%, ${r}%, ${c})`), o.addColorStop(0.38, `hsla(${a}, ${n ? 82 : 75}%, ${r - (n ? 7 : 12)}%, ${c * 0.5})`), o.addColorStop(1, "rgba(0, 0, 0, 0)"), t.fillStyle = o, t.beginPath(), t.arc(e, i, s, 0, Math.PI * 2), t.fill();
2535
+ o.addColorStop(0, `hsla(${a}, ${n ? 88 : 80}%, ${r}%, ${l})`), o.addColorStop(0.38, `hsla(${a}, ${n ? 82 : 75}%, ${r - (n ? 7 : 12)}%, ${l * 0.5})`), o.addColorStop(1, "rgba(0, 0, 0, 0)"), t.fillStyle = o, t.beginPath(), t.arc(e, i, s, 0, Math.PI * 2), t.fill();
2458
2536
  }
2459
- drawSoftFlows(t, e, i, s, a, c, n) {
2537
+ drawSoftFlows(t, e, i, s, a, l, n) {
2460
2538
  t.save();
2461
2539
  const o = Math.min(e, i), r = o * 0.035;
2462
2540
  t.globalAlpha = n ? 0.15 : 0.12, t.lineWidth = Math.max(1.3, o * 17e-4), t.lineCap = "round", t.shadowBlur = o * 0.02, t.shadowColor = `hsla(${a}, 85%, ${n ? 52 : 62}%, 0.28)`;
2463
- for (let l = 0; l < 3; l++) {
2464
- const h = (l - 1) * o * 0.075 + Math.sin(s * 0.06 + l) * r, u = l * 28 + c * 18;
2465
- t.strokeStyle = `hsla(${this.wrapHue(a + u)}, ${n ? 78 : 74}%, ${n ? 47 : 62}%, ${0.52 - l * 0.08})`, t.beginPath(), t.moveTo(-o * 0.12, i * 0.2 + h), t.bezierCurveTo(e * 0.2, i * 0.02 + h, e * 0.47, i * 0.2 - h, e * 0.73, i * 0.07 + h), t.bezierCurveTo(e * 0.94, -o * 0.02 + h, e * 1.04, i * 0.16 + h, e * 1.1, i * 0.36 + h), t.stroke(), t.beginPath(), t.moveTo(-o * 0.1, i * 0.8 - h), t.bezierCurveTo(e * 0.2, i * 0.98 - h, e * 0.48, i * 0.8 + h, e * 0.75, i * 0.93 - h), t.bezierCurveTo(e * 0.94, i * 1.02 - h, e * 1.04, i * 0.84 - h, e * 1.1, i * 0.65 - h), t.stroke();
2541
+ for (let c = 0; c < 3; c++) {
2542
+ const h = (c - 1) * o * 0.075 + Math.sin(s * 0.06 + c) * r, u = c * 28 + l * 18;
2543
+ t.strokeStyle = `hsla(${this.wrapHue(a + u)}, ${n ? 78 : 74}%, ${n ? 47 : 62}%, ${0.52 - c * 0.08})`, t.beginPath(), t.moveTo(-o * 0.12, i * 0.2 + h), t.bezierCurveTo(e * 0.2, i * 0.02 + h, e * 0.47, i * 0.2 - h, e * 0.73, i * 0.07 + h), t.bezierCurveTo(e * 0.94, -o * 0.02 + h, e * 1.04, i * 0.16 + h, e * 1.1, i * 0.36 + h), t.stroke(), t.beginPath(), t.moveTo(-o * 0.1, i * 0.8 - h), t.bezierCurveTo(e * 0.2, i * 0.98 - h, e * 0.48, i * 0.8 + h, e * 0.75, i * 0.93 - h), t.bezierCurveTo(e * 0.94, i * 1.02 - h, e * 1.04, i * 0.84 - h, e * 1.1, i * 0.65 - h), t.stroke();
2466
2544
  }
2467
2545
  t.restore();
2468
2546
  }
2469
- drawParticleField(t, e, i, s, a, c, n, o) {
2470
- const r = 44 + Math.min(24, n * 2), l = e / 2, h = i / 2, u = Math.min(e, i) * 0.17;
2471
- for (let p = 0; p < r; p++) {
2472
- const _ = p + n * 17, g = this.unitNoise(_ * 1.7) * e, d = this.unitNoise(_ * 2.9 + 13) * i, m = Math.hypot(g - l, d - h), x = Math.min(1, Math.max(0, (m - u) / (Math.min(e, i) * 0.28))), A = 0.7 + Math.sin(s * (0.6 + p % 4 * 0.08) + _) * 0.3, b = (o ? 0.34 : 0.3) * x * A, I = 0.65 + p % 3 * 0.45;
2473
- t.fillStyle = `hsla(${p % 3 === 0 ? c : a}, ${o ? 82 : 78}%, ${o ? 40 : 70}%, ${b})`, t.beginPath(), t.arc(g, d, I, 0, Math.PI * 2), t.fill();
2547
+ drawParticleField(t, e, i, s, a, l, n, o) {
2548
+ const r = 44 + Math.min(24, n * 2), c = e / 2, h = i / 2, u = Math.min(e, i) * 0.17;
2549
+ for (let d = 0; d < r; d++) {
2550
+ const _ = d + n * 17, f = this.unitNoise(_ * 1.7) * e, p = this.unitNoise(_ * 2.9 + 13) * i, g = Math.hypot(f - c, p - h), m = Math.min(1, Math.max(0, (g - u) / (Math.min(e, i) * 0.28))), y = 0.7 + Math.sin(s * (0.6 + d % 4 * 0.08) + _) * 0.3, b = (o ? 0.34 : 0.3) * m * y, I = 0.65 + d % 3 * 0.45;
2551
+ t.fillStyle = `hsla(${d % 3 === 0 ? l : a}, ${o ? 82 : 78}%, ${o ? 40 : 70}%, ${b})`, t.beginPath(), t.arc(f, p, I, 0, Math.PI * 2), t.fill();
2474
2552
  }
2475
2553
  }
2476
2554
  unitNoise(t) {
@@ -2480,32 +2558,32 @@ class ht {
2480
2558
  return (t % 360 + 360) % 360;
2481
2559
  }
2482
2560
  }
2483
- class ut {
2561
+ class dt {
2484
2562
  render(t, e, i) {
2485
2563
  if (!e.isActive) return;
2486
2564
  const s = e.getLauncher(), a = e.getTarget();
2487
2565
  if (!s || !a || !s.active || !a.active) return;
2488
- const c = e.getStep();
2489
- if (t.save(), c === 1) {
2566
+ const l = e.getStep();
2567
+ if (t.save(), l === 1) {
2490
2568
  const n = Math.sin(i * 6) * 10, o = s.position.x, r = s.position.y - 65 + n;
2491
2569
  t.shadowColor = "#00f0ff", t.shadowBlur = 20, t.fillStyle = "#00f0ff", t.beginPath(), t.moveTo(o, r + 20), t.lineTo(o - 16, r - 12), t.lineTo(o - 6, r - 12), t.lineTo(o - 6, r - 32), t.lineTo(o + 6, r - 32), t.lineTo(o + 6, r - 12), t.lineTo(o + 16, r - 12), t.closePath(), t.fill();
2492
- const l = s.radius * (1.6 + Math.sin(i * 8) * 0.3);
2493
- t.strokeStyle = "rgba(0, 240, 255, 0.8)", t.lineWidth = 3, t.beginPath(), t.arc(s.position.x, s.position.y, l, 0, Math.PI * 2), t.stroke();
2494
- } else if (c === 2) {
2570
+ const c = s.radius * (1.6 + Math.sin(i * 8) * 0.3);
2571
+ t.strokeStyle = "rgba(0, 240, 255, 0.8)", t.lineWidth = 3, t.beginPath(), t.arc(s.position.x, s.position.y, c, 0, Math.PI * 2), t.stroke();
2572
+ } else if (l === 2) {
2495
2573
  const n = a.position.x - s.position.x, o = a.position.y - s.position.y;
2496
2574
  if (Math.hypot(n, o) > 10) {
2497
- const l = Math.atan2(o, n);
2575
+ const c = Math.atan2(o, n);
2498
2576
  t.shadowColor = "#ff00dd", t.shadowBlur = 22, t.strokeStyle = "#ff00dd", t.lineWidth = 4, t.setLineDash([12, 8]), t.beginPath(), t.moveTo(s.position.x, s.position.y), t.lineTo(a.position.x, a.position.y), t.stroke(), t.setLineDash([]);
2499
- const h = a.position.x - Math.cos(l) * (a.radius + 10), u = a.position.y - Math.sin(l) * (a.radius + 10);
2500
- t.fillStyle = "#ff00dd", t.beginPath(), t.moveTo(h, u), t.lineTo(h - Math.cos(l - 0.4) * 24, u - Math.sin(l - 0.4) * 24), t.lineTo(h - Math.cos(l + 0.4) * 24, u - Math.sin(l + 0.4) * 24), t.closePath(), t.fill();
2501
- const p = a.radius * (1.8 + Math.cos(i * 10) * 0.3);
2502
- t.strokeStyle = "rgba(255, 0, 221, 0.9)", t.lineWidth = 3.5, t.beginPath(), t.arc(a.position.x, a.position.y, p, 0, Math.PI * 2), t.stroke();
2577
+ const h = a.position.x - Math.cos(c) * (a.radius + 10), u = a.position.y - Math.sin(c) * (a.radius + 10);
2578
+ t.fillStyle = "#ff00dd", t.beginPath(), t.moveTo(h, u), t.lineTo(h - Math.cos(c - 0.4) * 24, u - Math.sin(c - 0.4) * 24), t.lineTo(h - Math.cos(c + 0.4) * 24, u - Math.sin(c + 0.4) * 24), t.closePath(), t.fill();
2579
+ const d = a.radius * (1.8 + Math.cos(i * 10) * 0.3);
2580
+ t.strokeStyle = "rgba(255, 0, 221, 0.9)", t.lineWidth = 3.5, t.beginPath(), t.arc(a.position.x, a.position.y, d, 0, Math.PI * 2), t.stroke();
2503
2581
  }
2504
2582
  }
2505
2583
  t.restore();
2506
2584
  }
2507
2585
  }
2508
- class pt {
2586
+ class gt {
2509
2587
  canvas;
2510
2588
  ctx;
2511
2589
  themeManager;
@@ -2513,42 +2591,52 @@ class pt {
2513
2591
  bgRenderer;
2514
2592
  tutorialArrowRenderer;
2515
2593
  constructor(t, e) {
2516
- this.canvas = t, this.ctx = t.getContext("2d"), this.themeManager = e, this.indicatorRenderer = new ct(), this.bgRenderer = new ht(), this.tutorialArrowRenderer = new ut();
2594
+ this.canvas = t, this.ctx = t.getContext("2d"), this.themeManager = e, this.indicatorRenderer = new ut(), this.bgRenderer = new pt(), this.tutorialArrowRenderer = new dt();
2517
2595
  }
2518
- render(t, e, i, s, a, c, n, o, r, l, h = 1, u) {
2596
+ render(t, e, i, s, a, l, n, o, r, c, h, u = 1, d) {
2519
2597
  if (!this.ctx) return;
2520
- const p = this.themeManager.getPalette(), { width: _, height: g } = this.canvas, d = o.getShakeOffset();
2521
- this.ctx.save(), this.ctx.translate(d.x, d.y), this.bgRenderer.render(
2598
+ const _ = this.themeManager.getPalette(), { width: f, height: p } = this.canvas, g = r.getShakeOffset();
2599
+ this.ctx.save(), this.ctx.translate(g.x, g.y), this.bgRenderer.render(
2522
2600
  this.ctx,
2523
- _,
2524
- g,
2525
- t.pulsePhase,
2526
- h,
2601
+ f,
2527
2602
  p,
2603
+ t.pulsePhase,
2604
+ u,
2605
+ _,
2528
2606
  this.themeManager.getTheme() === "light"
2529
- ), this.drawToxicPools(i, t.pulsePhase), this.drawGravityVortices(s, t.pulsePhase), this.drawShockwaves(a), this.drawCoreFilaments(t, p), this.drawParticles(c), E.getInstance().getConfig().core.hasOffscreenIndicators && this.indicatorRenderer.render(this.ctx, e, _, g, p), this.drawOrganicEnemies(e, t.pulsePhase, p), u && this.tutorialArrowRenderer.render(this.ctx, u, t.pulsePhase), r ? this.drawPsionicTendril(t.position, r.position, p) : t && this.drawHoverTendril(t.position, l, e, p), this.drawOrganicConsciousnessCore(t, p), this.drawFloatingTexts(n), o.flashAlpha > 0 && (this.ctx.fillStyle = `rgba(255, 255, 255, ${o.flashAlpha})`, this.ctx.fillRect(0, 0, _, g)), this.ctx.restore();
2607
+ ), this.drawExperienceOrbs(i, t.position, t.pulsePhase, _), this.drawToxicPools(s, t.pulsePhase), this.drawGravityVortices(a, t.pulsePhase), this.drawShockwaves(l), this.drawCoreFilaments(t, _), this.drawParticles(n), E.getInstance().getConfig().core.hasOffscreenIndicators && this.indicatorRenderer.render(this.ctx, e, f, p, _), this.drawOrganicEnemies(e, t.pulsePhase, _), d && this.tutorialArrowRenderer.render(this.ctx, d, t.pulsePhase), c ? this.drawPsionicTendril(t.position, c.position, _) : t && this.drawHoverTendril(t.position, h, e, _), this.drawOrganicConsciousnessCore(t, _), this.drawFloatingTexts(o), r.flashAlpha > 0 && (this.ctx.fillStyle = `rgba(255, 255, 255, ${r.flashAlpha})`, this.ctx.fillRect(0, 0, f, p)), this.ctx.restore();
2608
+ }
2609
+ drawExperienceOrbs(t, e, i, s) {
2610
+ if (this.ctx)
2611
+ for (const a of t) {
2612
+ if (!a.active) continue;
2613
+ const l = a.radius + Math.sin(i * 7 + a.position.x * 0.01) * 0.8, { x: n, y: o } = a.position;
2614
+ this.ctx.save(), this.ctx.shadowColor = s.corePrimary, this.ctx.shadowBlur = a.isAbsorbing ? 18 : 10, a.isAbsorbing && (this.ctx.globalAlpha = 0.35, this.ctx.strokeStyle = s.tendrilCyan, this.ctx.lineWidth = 1, this.ctx.setLineDash([4, 7]), this.ctx.beginPath(), this.ctx.moveTo(n, o), this.ctx.lineTo(e.x, e.y), this.ctx.stroke(), this.ctx.setLineDash([]), this.ctx.globalAlpha = 1);
2615
+ const r = this.ctx.createRadialGradient(n - 1, o - 1, 1, n, o, l * 1.6);
2616
+ r.addColorStop(0, s.effectHighlight), r.addColorStop(0.4, s.corePrimary), r.addColorStop(1, "rgba(0, 0, 0, 0)"), this.ctx.fillStyle = r, this.ctx.beginPath(), this.ctx.arc(n, o, l * 1.6, 0, Math.PI * 2), this.ctx.fill(), this.ctx.fillStyle = s.effectHighlight, this.ctx.beginPath(), this.ctx.arc(n, o, l * 0.65, 0, Math.PI * 2), this.ctx.fill(), this.ctx.strokeStyle = s.tendrilCyan, this.ctx.lineWidth = 1, this.ctx.beginPath(), this.ctx.arc(n, o, l + 3, -i * 2, -i * 2 + Math.PI * 1.4), this.ctx.stroke(), this.ctx.restore();
2617
+ }
2530
2618
  }
2531
2619
  drawToxicPools(t, e) {
2532
2620
  if (this.ctx)
2533
2621
  for (const i of t) {
2534
- const s = i.duration / i.maxDuration, a = Math.min(0.7, (1 - s) * 0.7), { x: c, y: n } = i.position;
2622
+ const s = i.duration / i.maxDuration, a = Math.min(0.7, (1 - s) * 0.7), { x: l, y: n } = i.position;
2535
2623
  this.ctx.save();
2536
- const o = this.ctx.createRadialGradient(c, n, 10, c, n, i.radius * 1.2);
2624
+ const o = this.ctx.createRadialGradient(l, n, 10, l, n, i.radius * 1.2);
2537
2625
  o.addColorStop(0, `rgba(57, 255, 20, ${a * 0.9})`), o.addColorStop(0.4, `rgba(16, 185, 129, ${a * 0.65})`), o.addColorStop(0.8, `rgba(5, 80, 45, ${a * 0.35})`), o.addColorStop(1, "rgba(2, 35, 15, 0)"), this.ctx.fillStyle = o, this.ctx.shadowColor = "#39ff14", this.ctx.shadowBlur = 30, this.ctx.beginPath();
2538
2626
  const r = 70;
2539
- for (let l = 0; l <= r; l++) {
2540
- const h = l * Math.PI * 2 / r, u = Math.sin(h * 5 + e * 3) * 14, p = Math.cos(h * 3 - e * 2) * 9, _ = i.radius + u + p, g = c + Math.cos(h) * _, d = n + Math.sin(h) * _;
2541
- l === 0 ? this.ctx.moveTo(g, d) : this.ctx.lineTo(g, d);
2627
+ for (let c = 0; c <= r; c++) {
2628
+ const h = c * Math.PI * 2 / r, u = Math.sin(h * 5 + e * 3) * 14, d = Math.cos(h * 3 - e * 2) * 9, _ = i.radius + u + d, f = l + Math.cos(h) * _, p = n + Math.sin(h) * _;
2629
+ c === 0 ? this.ctx.moveTo(f, p) : this.ctx.lineTo(f, p);
2542
2630
  }
2543
2631
  this.ctx.closePath(), this.ctx.fill(), this.ctx.strokeStyle = `rgba(57, 255, 20, ${a * 0.8})`, this.ctx.lineWidth = 2.5, this.ctx.beginPath();
2544
- for (let l = 0; l <= r; l++) {
2545
- const h = l * Math.PI * 2 / r, u = Math.sin(h * 6 + e * 4) * 8, p = i.radius * 0.75 + u, _ = c + Math.cos(h) * p, g = n + Math.sin(h) * p;
2546
- l === 0 ? this.ctx.moveTo(_, g) : this.ctx.lineTo(_, g);
2632
+ for (let c = 0; c <= r; c++) {
2633
+ const h = c * Math.PI * 2 / r, u = Math.sin(h * 6 + e * 4) * 8, d = i.radius * 0.75 + u, _ = l + Math.cos(h) * d, f = n + Math.sin(h) * d;
2634
+ c === 0 ? this.ctx.moveTo(_, f) : this.ctx.lineTo(_, f);
2547
2635
  }
2548
2636
  this.ctx.closePath(), this.ctx.stroke();
2549
- for (let l = 0; l < 6; l++) {
2550
- const h = l * Math.PI * 0.33 + e * 1.5, u = i.radius * 0.5 * (0.3 + Math.sin(e * 2 + l) * 0.3), p = c + Math.cos(h) * u, _ = n + Math.sin(h) * u, g = 3 + Math.sin(e * 3 + l) * 2;
2551
- this.ctx.fillStyle = `rgba(255, 255, 255, ${a * 0.8})`, this.ctx.beginPath(), this.ctx.arc(p, _, Math.max(1, g), 0, Math.PI * 2), this.ctx.fill();
2637
+ for (let c = 0; c < 6; c++) {
2638
+ const h = c * Math.PI * 0.33 + e * 1.5, u = i.radius * 0.5 * (0.3 + Math.sin(e * 2 + c) * 0.3), d = l + Math.cos(h) * u, _ = n + Math.sin(h) * u, f = 3 + Math.sin(e * 3 + c) * 2;
2639
+ this.ctx.fillStyle = `rgba(255, 255, 255, ${a * 0.8})`, this.ctx.beginPath(), this.ctx.arc(d, _, Math.max(1, f), 0, Math.PI * 2), this.ctx.fill();
2552
2640
  }
2553
2641
  this.ctx.restore();
2554
2642
  }
@@ -2556,8 +2644,9 @@ class pt {
2556
2644
  drawShockwaves(t) {
2557
2645
  if (!this.ctx) return;
2558
2646
  const e = this.themeManager.getTheme() === "light";
2647
+ this.ctx.save();
2559
2648
  for (const i of t) {
2560
- this.ctx.save(), this.ctx.globalAlpha = i.alpha;
2649
+ this.ctx.globalAlpha = i.alpha;
2561
2650
  const s = this.ctx.createRadialGradient(
2562
2651
  i.position.x,
2563
2652
  i.position.y,
@@ -2566,19 +2655,20 @@ class pt {
2566
2655
  i.position.y,
2567
2656
  i.radius
2568
2657
  );
2569
- s.addColorStop(0, e ? "rgba(255, 255, 255, 0.72)" : "rgba(255, 255, 255, 0.4)"), s.addColorStop(0.7, i.color), s.addColorStop(1, "rgba(0, 0, 0, 0)"), this.ctx.fillStyle = s, this.ctx.beginPath(), this.ctx.arc(i.position.x, i.position.y, i.radius, 0, Math.PI * 2), this.ctx.fill(), this.ctx.strokeStyle = e ? i.color : "#ffffff", this.ctx.lineWidth = 4, this.ctx.shadowColor = i.color, this.ctx.shadowBlur = 24, this.ctx.beginPath(), this.ctx.arc(i.position.x, i.position.y, i.radius, 0, Math.PI * 2), this.ctx.stroke(), this.ctx.restore();
2658
+ s.addColorStop(0, e ? "rgba(255, 255, 255, 0.72)" : "rgba(255, 255, 255, 0.4)"), s.addColorStop(0.7, i.color), s.addColorStop(1, "rgba(0, 0, 0, 0)"), this.ctx.fillStyle = s, this.ctx.beginPath(), this.ctx.arc(i.position.x, i.position.y, i.radius, 0, Math.PI * 2), this.ctx.fill(), this.ctx.strokeStyle = e ? i.color : "#ffffff", this.ctx.lineWidth = 4, this.ctx.shadowColor = i.color, this.ctx.shadowBlur = 24, this.ctx.beginPath(), this.ctx.arc(i.position.x, i.position.y, i.radius, 0, Math.PI * 2), this.ctx.stroke();
2570
2659
  }
2660
+ this.ctx.restore();
2571
2661
  }
2572
2662
  drawGravityVortices(t, e) {
2573
2663
  if (!this.ctx) return;
2574
2664
  const i = this.themeManager.getPalette();
2575
2665
  for (const s of t) {
2576
- const a = Math.min(0.85, (1 - s.duration / s.maxDuration) * 0.85), c = s.radius * (1 - s.duration / s.maxDuration * 0.1), { x: n, y: o } = s.position;
2666
+ const a = Math.min(0.85, (1 - s.duration / s.maxDuration) * 0.85), l = s.radius * (1 - s.duration / s.maxDuration * 0.1), { x: n, y: o } = s.position;
2577
2667
  this.ctx.save();
2578
2668
  const r = this.ctx.createRadialGradient(n, o, 0, n, o, 60);
2579
2669
  r.addColorStop(0, this.colorWithAlpha(i.vortexCore, a)), r.addColorStop(0.7, this.colorWithAlpha(i.vortexMid, a)), r.addColorStop(1, `rgba(157, 78, 221, ${a * 0.5})`), this.ctx.fillStyle = r, this.ctx.beginPath(), this.ctx.arc(n, o, 60, 0, Math.PI * 2), this.ctx.fill(), this.ctx.strokeStyle = i.parasiteColor, this.ctx.lineWidth = 5, this.ctx.shadowColor = i.parasiteColor, this.ctx.shadowBlur = 32;
2580
- for (let l = 1; l <= 5; l++) {
2581
- const h = c * l / 5, u = e * l * 2.2;
2670
+ for (let c = 1; c <= 5; c++) {
2671
+ const h = l * c / 5, u = e * c * 2.2;
2582
2672
  this.ctx.beginPath(), this.ctx.arc(n, o, h, u, u + Math.PI * 1.5), this.ctx.stroke();
2583
2673
  }
2584
2674
  this.ctx.restore();
@@ -2588,10 +2678,10 @@ class pt {
2588
2678
  if (!this.ctx) return;
2589
2679
  const a = this.ctx.createRadialGradient(t / 2, e / 2, 40, t / 2, e / 2, Math.max(t, e));
2590
2680
  a.addColorStop(0, s.bgInner), a.addColorStop(0.5, s.bgMid), a.addColorStop(1, s.bgOuter), this.ctx.fillStyle = a, this.ctx.fillRect(0, 0, t, e);
2591
- const c = t * 0.35 + Math.sin(i * 0.3) * 60, n = e * 0.45 + Math.cos(i * 0.25) * 50, o = this.ctx.createRadialGradient(c, n, 20, c, n, 380);
2592
- o.addColorStop(0, s.nebulaCyan), o.addColorStop(1, "rgba(0, 0, 0, 0)"), this.ctx.fillStyle = o, this.ctx.beginPath(), this.ctx.arc(c, n, 380, 0, Math.PI * 2), this.ctx.fill();
2593
- const r = t * 0.68 + Math.cos(i * 0.35) * 50, l = e * 0.55 + Math.sin(i * 0.3) * 45, h = this.ctx.createRadialGradient(r, l, 20, r, l, 420);
2594
- h.addColorStop(0, s.nebulaMagenta), h.addColorStop(1, "rgba(0, 0, 0, 0)"), this.ctx.fillStyle = h, this.ctx.beginPath(), this.ctx.arc(r, l, 420, 0, Math.PI * 2), this.ctx.fill();
2681
+ const l = t * 0.35 + Math.sin(i * 0.3) * 60, n = e * 0.45 + Math.cos(i * 0.25) * 50, o = this.ctx.createRadialGradient(l, n, 20, l, n, 380);
2682
+ o.addColorStop(0, s.nebulaCyan), o.addColorStop(1, "rgba(0, 0, 0, 0)"), this.ctx.fillStyle = o, this.ctx.beginPath(), this.ctx.arc(l, n, 380, 0, Math.PI * 2), this.ctx.fill();
2683
+ const r = t * 0.68 + Math.cos(i * 0.35) * 50, c = e * 0.55 + Math.sin(i * 0.3) * 45, h = this.ctx.createRadialGradient(r, c, 20, r, c, 420);
2684
+ h.addColorStop(0, s.nebulaMagenta), h.addColorStop(1, "rgba(0, 0, 0, 0)"), this.ctx.fillStyle = h, this.ctx.beginPath(), this.ctx.arc(r, c, 420, 0, Math.PI * 2), this.ctx.fill();
2595
2685
  }
2596
2686
  drawCoreFilaments(t, e) {
2597
2687
  if (!this.ctx) return;
@@ -2600,8 +2690,8 @@ class pt {
2600
2690
  for (let s = 0; s < i; s++) {
2601
2691
  const a = t.collectedPowerUpColors[s] || e.nebulaCyan;
2602
2692
  this.ctx.strokeStyle = a;
2603
- const c = s * Math.PI * 2 / i + t.pulsePhase * 0.12, n = 85 + Math.sin(t.pulsePhase * 1.5 + s) * 25, o = t.position.x + Math.cos(c) * n, r = t.position.y + Math.sin(c) * n, l = t.position.x + Math.cos(c + 0.4) * 48, h = t.position.y + Math.sin(c + 0.4) * 48;
2604
- this.ctx.beginPath(), this.ctx.moveTo(t.position.x, t.position.y), this.ctx.quadraticCurveTo(l, h, o, r), this.ctx.stroke(), this.ctx.fillStyle = a, this.ctx.beginPath(), this.ctx.arc(o, r, 3.5, 0, Math.PI * 2), this.ctx.fill();
2693
+ const l = s * Math.PI * 2 / i + t.pulsePhase * 0.12, n = 85 + Math.sin(t.pulsePhase * 1.5 + s) * 25, o = t.position.x + Math.cos(l) * n, r = t.position.y + Math.sin(l) * n, c = t.position.x + Math.cos(l + 0.4) * 48, h = t.position.y + Math.sin(l + 0.4) * 48;
2694
+ this.ctx.beginPath(), this.ctx.moveTo(t.position.x, t.position.y), this.ctx.quadraticCurveTo(c, h, o, r), this.ctx.stroke(), this.ctx.fillStyle = a, this.ctx.beginPath(), this.ctx.arc(o, r, 3.5, 0, Math.PI * 2), this.ctx.fill();
2605
2695
  }
2606
2696
  }
2607
2697
  drawOrganicConsciousnessCore(t, e) {
@@ -2613,41 +2703,41 @@ class pt {
2613
2703
  }
2614
2704
  const a = t.getColorHex();
2615
2705
  for (let r = 0; r < t.integrity; r++) {
2616
- const l = t.radius + 16 + r * 12;
2706
+ const c = t.radius + 16 + r * 12;
2617
2707
  this.ctx.strokeStyle = a, this.ctx.lineWidth = 2.2, this.ctx.shadowColor = a, this.ctx.shadowBlur = 12, this.ctx.beginPath();
2618
2708
  const h = 60;
2619
2709
  for (let u = 0; u <= h; u++) {
2620
- const p = u * Math.PI * 2 / h, _ = l + Math.sin(p * 4 + t.pulsePhase * 2 + r) * 3, g = i + Math.cos(p) * _, d = s + Math.sin(p) * _;
2621
- u === 0 ? this.ctx.moveTo(g, d) : this.ctx.lineTo(g, d);
2710
+ const d = u * Math.PI * 2 / h, _ = c + Math.sin(d * 4 + t.pulsePhase * 2 + r) * 3, f = i + Math.cos(d) * _, p = s + Math.sin(d) * _;
2711
+ u === 0 ? this.ctx.moveTo(f, p) : this.ctx.lineTo(f, p);
2622
2712
  }
2623
2713
  this.ctx.closePath(), this.ctx.stroke();
2624
2714
  }
2625
2715
  if (t.repairProgress > 0) {
2626
- const r = t.integrity, l = t.radius + 16 + r * 12;
2716
+ const r = t.integrity, c = t.radius + 16 + r * 12;
2627
2717
  this.ctx.save(), this.ctx.globalAlpha = Math.max(0.15, t.repairProgress), this.ctx.strokeStyle = a, this.ctx.lineWidth = 2, this.ctx.shadowColor = a, this.ctx.shadowBlur = 8, this.ctx.setLineDash([6, 4]), this.ctx.beginPath();
2628
2718
  const h = 60;
2629
2719
  for (let u = 0; u <= h; u++) {
2630
- const p = u * Math.PI * 2 / h, _ = l + Math.sin(p * 4 + t.pulsePhase * 2 + r) * 3, g = i + Math.cos(p) * _, d = s + Math.sin(p) * _;
2631
- u === 0 ? this.ctx.moveTo(g, d) : this.ctx.lineTo(g, d);
2720
+ const d = u * Math.PI * 2 / h, _ = c + Math.sin(d * 4 + t.pulsePhase * 2 + r) * 3, f = i + Math.cos(d) * _, p = s + Math.sin(d) * _;
2721
+ u === 0 ? this.ctx.moveTo(f, p) : this.ctx.lineTo(f, p);
2632
2722
  }
2633
2723
  this.ctx.closePath(), this.ctx.stroke(), this.ctx.restore();
2634
2724
  }
2635
- const c = this.ctx.createRadialGradient(i, s, 5, i, s, t.radius * 2.2);
2636
- c.addColorStop(0, a), c.addColorStop(0.5, e.nebulaMagenta), c.addColorStop(1, "rgba(0, 0, 0, 0)"), this.ctx.fillStyle = c, this.ctx.beginPath(), this.ctx.arc(i, s, t.radius * 2.2, 0, Math.PI * 2), this.ctx.fill(), this.ctx.save(), this.ctx.translate(i, s), this.ctx.strokeStyle = a, this.ctx.lineWidth = 3, this.ctx.fillStyle = a, this.ctx.shadowColor = a, this.ctx.shadowBlur = 20, this.ctx.beginPath();
2725
+ const l = this.ctx.createRadialGradient(i, s, 5, i, s, t.radius * 2.2);
2726
+ l.addColorStop(0, a), l.addColorStop(0.5, e.nebulaMagenta), l.addColorStop(1, "rgba(0, 0, 0, 0)"), this.ctx.fillStyle = l, this.ctx.beginPath(), this.ctx.arc(i, s, t.radius * 2.2, 0, Math.PI * 2), this.ctx.fill(), this.ctx.save(), this.ctx.translate(i, s), this.ctx.strokeStyle = a, this.ctx.lineWidth = 3, this.ctx.fillStyle = a, this.ctx.shadowColor = a, this.ctx.shadowBlur = 20, this.ctx.beginPath();
2637
2727
  const n = 80;
2638
2728
  for (let r = 0; r <= n; r++) {
2639
- const l = r * Math.PI * 2 / n, h = t.getMembraneRadius(l), u = Math.cos(l) * h, p = Math.sin(l) * h;
2640
- r === 0 ? this.ctx.moveTo(u, p) : this.ctx.lineTo(u, p);
2729
+ const c = r * Math.PI * 2 / n, h = t.getMembraneRadius(c), u = Math.cos(c) * h, d = Math.sin(c) * h;
2730
+ r === 0 ? this.ctx.moveTo(u, d) : this.ctx.lineTo(u, d);
2641
2731
  }
2642
2732
  this.ctx.closePath(), this.ctx.fill(), this.ctx.stroke();
2643
2733
  const o = t.powerUpCount;
2644
2734
  if (o > 0) {
2645
2735
  this.ctx.strokeStyle = e.effectHighlight, this.ctx.lineWidth = 1.8, this.ctx.shadowColor = a, this.ctx.shadowBlur = 10;
2646
2736
  for (let r = 0; r < o; r++) {
2647
- const l = r * Math.PI * 2 / o + t.pulsePhase * 0.4, h = t.radius * (0.45 + Math.sin(t.pulsePhase * 2 + r) * 0.15);
2737
+ const c = r * Math.PI * 2 / o + t.pulsePhase * 0.4, h = t.radius * (0.45 + Math.sin(t.pulsePhase * 2 + r) * 0.15);
2648
2738
  this.ctx.beginPath(), this.ctx.moveTo(0, 0);
2649
- const u = Math.cos(l + Math.sin(t.pulsePhase + r) * 0.4) * (h * 0.6), p = Math.sin(l + Math.cos(t.pulsePhase + r) * 0.4) * (h * 0.6), _ = Math.cos(l) * h, g = Math.sin(l) * h;
2650
- this.ctx.quadraticCurveTo(u, p, _, g), this.ctx.stroke(), this.ctx.fillStyle = a, this.ctx.beginPath(), this.ctx.arc(_, g, 2.5, 0, Math.PI * 2), this.ctx.fill();
2739
+ const u = Math.cos(c + Math.sin(t.pulsePhase + r) * 0.4) * (h * 0.6), d = Math.sin(c + Math.cos(t.pulsePhase + r) * 0.4) * (h * 0.6), _ = Math.cos(c) * h, f = Math.sin(c) * h;
2740
+ this.ctx.quadraticCurveTo(u, d, _, f), this.ctx.stroke(), this.ctx.fillStyle = a, this.ctx.beginPath(), this.ctx.arc(_, f, 2.5, 0, Math.PI * 2), this.ctx.fill();
2651
2741
  }
2652
2742
  }
2653
2743
  this.ctx.fillStyle = e.effectHighlight, this.ctx.beginPath(), this.ctx.arc(0, 0, t.radius * 0.3, 0, Math.PI * 2), this.ctx.fill(), this.ctx.restore(), this.ctx.restore();
@@ -2657,11 +2747,11 @@ class pt {
2657
2747
  this.ctx.save();
2658
2748
  const s = e.x - t.x, a = e.y - t.y;
2659
2749
  this.ctx.strokeStyle = i.tendrilMagenta, this.ctx.lineWidth = 9, this.ctx.shadowColor = i.tendrilMagenta, this.ctx.shadowBlur = 20, this.ctx.beginPath(), this.ctx.moveTo(t.x, t.y);
2660
- const c = (t.x + e.x) / 2 + Math.sin(Date.now() * 0.02) * 16, n = (t.y + e.y) / 2 + Math.cos(Date.now() * 0.02) * 16;
2661
- this.ctx.quadraticCurveTo(c, n, e.x, e.y), this.ctx.stroke(), this.ctx.strokeStyle = i.tendrilCyan, this.ctx.lineWidth = 3.5, this.ctx.shadowColor = i.tendrilCyan, this.ctx.shadowBlur = 12, this.ctx.beginPath(), this.ctx.moveTo(t.x, t.y), this.ctx.lineTo(e.x, e.y), this.ctx.stroke();
2750
+ const l = (t.x + e.x) / 2 + Math.sin(Date.now() * 0.02) * 16, n = (t.y + e.y) / 2 + Math.cos(Date.now() * 0.02) * 16;
2751
+ this.ctx.quadraticCurveTo(l, n, e.x, e.y), this.ctx.stroke(), this.ctx.strokeStyle = i.tendrilCyan, this.ctx.lineWidth = 3.5, this.ctx.shadowColor = i.tendrilCyan, this.ctx.shadowBlur = 12, this.ctx.beginPath(), this.ctx.moveTo(t.x, t.y), this.ctx.lineTo(e.x, e.y), this.ctx.stroke();
2662
2752
  for (let o = 0; o < 6; o++) {
2663
- const r = Math.random(), l = t.x + s * r + (Math.random() - 0.5) * 24, h = t.y + a * r + (Math.random() - 0.5) * 24;
2664
- this.ctx.fillStyle = i.effectHighlight, this.ctx.beginPath(), this.ctx.arc(l, h, 2.5 + Math.random() * 2.5, 0, Math.PI * 2), this.ctx.fill();
2753
+ const r = Math.random(), c = t.x + s * r + (Math.random() - 0.5) * 24, h = t.y + a * r + (Math.random() - 0.5) * 24;
2754
+ this.ctx.fillStyle = i.effectHighlight, this.ctx.beginPath(), this.ctx.arc(c, h, 2.5 + Math.random() * 2.5, 0, Math.PI * 2), this.ctx.fill();
2665
2755
  }
2666
2756
  this.ctx.restore();
2667
2757
  }
@@ -2669,8 +2759,8 @@ class pt {
2669
2759
  if (this.ctx)
2670
2760
  for (const a of i) {
2671
2761
  if (!a.active || a.isGrabbed || a.isThrown || a.wasManipulated || a.isDying) continue;
2672
- const c = e.x - a.position.x, n = e.y - a.position.y;
2673
- if (Math.hypot(c, n) <= a.getHitRadius()) {
2762
+ const l = e.x - a.position.x, n = e.y - a.position.y;
2763
+ if (Math.hypot(l, n) <= a.getHitRadius()) {
2674
2764
  this.ctx.strokeStyle = s.tendrilMagenta, this.ctx.lineWidth = 2.5, this.ctx.beginPath(), this.ctx.moveTo(t.x, t.y), this.ctx.lineTo(a.position.x, a.position.y), this.ctx.stroke();
2675
2765
  break;
2676
2766
  }
@@ -2682,8 +2772,8 @@ class pt {
2682
2772
  if (!s.active) continue;
2683
2773
  let a = s.color;
2684
2774
  s.type === "piercer" ? a = i.piercerColor : s.type === "spore" ? a = i.sporeColor : s.type === "cluster" ? a = i.clusterColor : s.type === "parasite" ? a = i.parasiteColor : s.type === "micro" && (a = i.microColor);
2685
- const { x: c, y: n } = s.position;
2686
- if (this.ctx.save(), this.ctx.translate(c, n), s.wasManipulated && !s.isDying) {
2775
+ const { x: l, y: n } = s.position;
2776
+ if (this.ctx.save(), this.ctx.translate(l, n), s.wasManipulated && !s.isDying) {
2687
2777
  const o = s.radius * 1.5 + Math.sin(e * 6) * 4;
2688
2778
  this.ctx.strokeStyle = i.tendrilMagenta, this.ctx.lineWidth = 2.5, this.ctx.shadowColor = i.tendrilMagenta, this.ctx.shadowBlur = 18, this.ctx.beginPath(), this.ctx.arc(0, 0, o, 0, Math.PI * 2), this.ctx.stroke();
2689
2779
  const r = s.radius * 1.8 + Math.cos(e * 8) * 3;
@@ -2692,17 +2782,17 @@ class pt {
2692
2782
  if (s.isDying) {
2693
2783
  const o = s.deathTimer / s.maxDeathTimer, r = Math.max(0, 1 - o);
2694
2784
  if (this.ctx.globalAlpha = r, s.deathType === "dissolve") {
2695
- const l = s.radius * (1 - o * 0.7);
2696
- this.ctx.fillStyle = i.sporeColor, this.ctx.shadowColor = i.sporeColor, this.ctx.shadowBlur = 20, this.ctx.beginPath(), this.ctx.arc(0, 0, l, 0, Math.PI * 2), this.ctx.fill();
2785
+ const c = s.radius * (1 - o * 0.7);
2786
+ this.ctx.fillStyle = i.sporeColor, this.ctx.shadowColor = i.sporeColor, this.ctx.shadowBlur = 20, this.ctx.beginPath(), this.ctx.arc(0, 0, c, 0, Math.PI * 2), this.ctx.fill();
2697
2787
  for (let h = 0; h < 4; h++) {
2698
- const u = h * Math.PI * 0.5 + o * 4, p = l * 0.8 * o;
2699
- this.ctx.fillStyle = i.effectHighlight, this.ctx.beginPath(), this.ctx.arc(Math.cos(u) * p, Math.sin(u) * p, 3, 0, Math.PI * 2), this.ctx.fill();
2788
+ const u = h * Math.PI * 0.5 + o * 4, d = c * 0.8 * o;
2789
+ this.ctx.fillStyle = i.effectHighlight, this.ctx.beginPath(), this.ctx.arc(Math.cos(u) * d, Math.sin(u) * d, 3, 0, Math.PI * 2), this.ctx.fill();
2700
2790
  }
2701
2791
  this.ctx.restore();
2702
2792
  continue;
2703
2793
  } else if (s.deathType === "sliced") {
2704
- const l = o * 24, h = s.sliceAngle + Math.PI / 2, u = Math.cos(h) * l, p = Math.sin(h) * l;
2705
- this.ctx.shadowColor = "#ff2a5f", this.ctx.shadowBlur = 22, this.ctx.fillStyle = a, this.ctx.save(), this.ctx.translate(u, p), this.ctx.beginPath(), this.ctx.arc(0, 0, s.radius * 0.8, 0, Math.PI), this.ctx.fill(), this.ctx.restore(), this.ctx.save(), this.ctx.translate(-u, -p), this.ctx.beginPath(), this.ctx.arc(0, 0, s.radius * 0.8, Math.PI, Math.PI * 2), this.ctx.fill(), this.ctx.restore(), this.ctx.restore();
2794
+ const c = o * 24, h = s.sliceAngle + Math.PI / 2, u = Math.cos(h) * c, d = Math.sin(h) * c;
2795
+ this.ctx.shadowColor = "#ff2a5f", this.ctx.shadowBlur = 22, this.ctx.fillStyle = a, this.ctx.save(), this.ctx.translate(u, d), this.ctx.beginPath(), this.ctx.arc(0, 0, s.radius * 0.8, 0, Math.PI), this.ctx.fill(), this.ctx.restore(), this.ctx.save(), this.ctx.translate(-u, -d), this.ctx.beginPath(), this.ctx.arc(0, 0, s.radius * 0.8, Math.PI, Math.PI * 2), this.ctx.fill(), this.ctx.restore(), this.ctx.restore();
2706
2796
  continue;
2707
2797
  }
2708
2798
  }
@@ -2710,16 +2800,16 @@ class pt {
2710
2800
  this.ctx.rotate(s.rotation), this.ctx.beginPath();
2711
2801
  const o = 12;
2712
2802
  for (let r = 0; r <= o; r++) {
2713
- const l = r * Math.PI * 2 / o, h = s.radius * 1.6 + Math.sin(l * 3 + e * 4) * 3, u = s.radius * 0.6 + Math.cos(l * 2 + e * 3) * 2, p = Math.cos(l) * h, _ = Math.sin(l) * u;
2714
- r === 0 ? this.ctx.moveTo(p, _) : this.ctx.lineTo(p, _);
2803
+ const c = r * Math.PI * 2 / o, h = s.radius * 1.6 + Math.sin(c * 3 + e * 4) * 3, u = s.radius * 0.6 + Math.cos(c * 2 + e * 3) * 2, d = Math.cos(c) * h, _ = Math.sin(c) * u;
2804
+ r === 0 ? this.ctx.moveTo(d, _) : this.ctx.lineTo(d, _);
2715
2805
  }
2716
2806
  this.ctx.closePath(), this.ctx.fill(), this.ctx.fillStyle = i.effectHighlight, this.ctx.beginPath(), this.ctx.arc(4, 0, 4, 0, Math.PI * 2), this.ctx.fill();
2717
2807
  } else if (s.type === "spore") {
2718
2808
  this.ctx.beginPath();
2719
2809
  const o = 8;
2720
2810
  for (let r = 0; r < o; r++) {
2721
- const l = r * Math.PI * 2 / o, h = s.radius + Math.sin(l * 4 + e * 3 + s.position.x) * 4, u = Math.cos(l) * h, p = Math.sin(l) * h;
2722
- r === 0 ? this.ctx.moveTo(u, p) : this.ctx.lineTo(u, p);
2811
+ const c = r * Math.PI * 2 / o, h = s.radius + Math.sin(c * 4 + e * 3 + s.position.x) * 4, u = Math.cos(c) * h, d = Math.sin(c) * h;
2812
+ r === 0 ? this.ctx.moveTo(u, d) : this.ctx.lineTo(u, d);
2723
2813
  }
2724
2814
  this.ctx.closePath(), this.ctx.fill(), this.ctx.fillStyle = i.effectHighlight, this.ctx.beginPath(), this.ctx.arc(-4, -4, 5, 0, Math.PI * 2), this.ctx.arc(5, 3, 4, 0, Math.PI * 2), this.ctx.fill();
2725
2815
  } else if (s.type === "cluster") {
@@ -2730,19 +2820,19 @@ class pt {
2730
2820
  this.ctx.beginPath();
2731
2821
  const o = 14;
2732
2822
  for (let r = 0; r <= o; r++) {
2733
- const l = r * Math.PI * 2 / o, h = s.radius + Math.sin(l * 5 - e * 5) * 3, u = Math.cos(l) * h, p = Math.sin(l) * h;
2734
- r === 0 ? this.ctx.moveTo(u, p) : this.ctx.lineTo(u, p);
2823
+ const c = r * Math.PI * 2 / o, h = s.radius + Math.sin(c * 5 - e * 5) * 3, u = Math.cos(c) * h, d = Math.sin(c) * h;
2824
+ r === 0 ? this.ctx.moveTo(u, d) : this.ctx.lineTo(u, d);
2735
2825
  }
2736
2826
  this.ctx.closePath(), this.ctx.fill(), this.ctx.fillStyle = i.bgOuter, this.ctx.beginPath(), this.ctx.arc(0, 0, s.radius * 0.45, 0, Math.PI * 2), this.ctx.fill();
2737
2827
  } else if (s.type === "heavy") {
2738
2828
  this.ctx.rotate(s.rotation);
2739
- const o = Math.PI * 0.75, r = s.radius * 1.35, l = s.radius * 0.75;
2829
+ const o = E.getInstance().getConfig().shield.protectionArc, r = s.radius * 1.35, c = s.radius * 0.75;
2740
2830
  this.ctx.beginPath(), this.ctx.arc(0, 0, r, -o / 2, o / 2, !1);
2741
- const h = Math.cos(o / 2) * l, u = Math.sin(o / 2) * l;
2742
- this.ctx.lineTo(h, u), this.ctx.arc(0, 0, l, o / 2, -o / 2, !0), this.ctx.closePath(), this.ctx.fillStyle = s.isStationaryShield ? i.corePrimary : a, this.ctx.shadowColor = i.corePrimary, this.ctx.shadowBlur = s.isStationaryShield ? 28 : 16, this.ctx.fill(), this.ctx.strokeStyle = i.effectHighlight, this.ctx.lineWidth = 3, this.ctx.beginPath(), this.ctx.arc(0, 0, r + Math.sin(e * 4) * 2, -o / 2 + 0.1, o / 2 - 0.1), this.ctx.stroke();
2743
- for (let p = -2; p <= 2; p++) {
2744
- const _ = p * o / 6, g = Math.cos(_) * (l + 6), d = Math.sin(_) * (l + 6);
2745
- this.ctx.fillStyle = i.effectHighlight, this.ctx.beginPath(), this.ctx.arc(g, d, 3, 0, Math.PI * 2), this.ctx.fill();
2831
+ const h = Math.cos(o / 2) * c, u = Math.sin(o / 2) * c;
2832
+ this.ctx.lineTo(h, u), this.ctx.arc(0, 0, c, o / 2, -o / 2, !0), this.ctx.closePath(), this.ctx.fillStyle = s.isStationaryShield ? i.corePrimary : a, this.ctx.shadowColor = i.corePrimary, this.ctx.shadowBlur = s.isStationaryShield ? 28 : 16, this.ctx.fill(), this.ctx.strokeStyle = i.effectHighlight, this.ctx.lineWidth = 3, this.ctx.beginPath(), this.ctx.arc(0, 0, r + Math.sin(e * 4) * 2, -o / 2 + 0.1, o / 2 - 0.1), this.ctx.stroke();
2833
+ for (let d = -2; d <= 2; d++) {
2834
+ const _ = d * o / 6, f = Math.cos(_) * (c + 6), p = Math.sin(_) * (c + 6);
2835
+ this.ctx.fillStyle = i.effectHighlight, this.ctx.beginPath(), this.ctx.arc(f, p, 3, 0, Math.PI * 2), this.ctx.fill();
2746
2836
  }
2747
2837
  } else
2748
2838
  this.ctx.beginPath(), this.ctx.arc(0, 0, s.radius, 0, Math.PI * 2), this.ctx.fill();
@@ -2750,45 +2840,48 @@ class pt {
2750
2840
  }
2751
2841
  }
2752
2842
  drawParticles(t) {
2753
- if (this.ctx)
2843
+ if (this.ctx) {
2844
+ this.ctx.save();
2754
2845
  for (const e of t)
2755
- this.ctx.save(), this.ctx.globalAlpha = e.alpha, this.ctx.fillStyle = e.color, this.ctx.beginPath(), this.ctx.arc(e.position.x, e.position.y, e.radius, 0, Math.PI * 2), this.ctx.fill(), this.ctx.restore();
2846
+ this.ctx.globalAlpha = e.alpha, this.ctx.fillStyle = e.color, this.ctx.beginPath(), this.ctx.arc(e.position.x, e.position.y, e.radius, 0, Math.PI * 2), this.ctx.fill();
2847
+ this.ctx.restore();
2848
+ }
2756
2849
  }
2757
2850
  drawFloatingTexts(t) {
2758
2851
  if (this.ctx)
2759
2852
  for (const e of t)
2760
2853
  this.ctx.save(), this.ctx.globalAlpha = e.alpha, this.ctx.fillStyle = e.color, this.ctx.font = `900 ${e.size}px Orbitron, sans-serif`, this.ctx.textAlign = "center", this.ctx.shadowColor = e.color, this.ctx.shadowBlur = 12, this.ctx.fillText(e.text, e.position.x, e.position.y), this.ctx.restore();
2761
2854
  }
2762
- drawOrbitingModifierOrbs(t, e, i, s = !0) {
2855
+ drawOrbitingModifierOrbs(t, e, i, s = !0, a = 1) {
2763
2856
  if (!this.ctx) return;
2764
- const a = this.themeManager.getPalette(), c = this.themeManager.getTheme() === "light";
2765
- for (const n of t) {
2766
- if (!n.active) continue;
2767
- const { x: o, y: r } = n.position, l = n.definition.color, h = n.definition.rarity, u = h === "legendary" ? "#ff00ff" : h === "epic" ? "#ffd700" : h === "rare" ? "#9d4edd" : "#00f5ff", p = n.radius + Math.sin(e * 6 + n.orbitAngle) * 3;
2768
- if (this.ctx.save(), this.ctx.shadowColor = u, this.ctx.shadowBlur = n.isGrabbed ? 36 : h === "legendary" ? 28 : 16, h === "legendary" || h === "epic") {
2769
- const d = p + 12, m = this.ctx.createRadialGradient(o, r, p, o, r, d);
2770
- m.addColorStop(0, u), m.addColorStop(1, "rgba(0, 0, 0, 0)"), this.ctx.fillStyle = m, this.ctx.beginPath(), this.ctx.arc(o, r, d, 0, Math.PI * 2), this.ctx.fill();
2857
+ const l = this.themeManager.getPalette(), n = this.themeManager.getTheme() === "light";
2858
+ for (const o of t) {
2859
+ if (!o.active) continue;
2860
+ const { x: r, y: c } = o.position, h = o.definition.color, u = o.definition.rarity, d = u === "legendary" ? "#ff00ff" : u === "epic" ? "#ffd700" : u === "rare" ? "#9d4edd" : "#00f5ff", _ = o.radius + Math.sin(e * 6 + o.orbitAngle) * 3;
2861
+ if (this.ctx.save(), this.ctx.shadowColor = d, this.ctx.shadowBlur = o.isGrabbed ? 36 : u === "legendary" ? 28 : 16, u === "legendary" || u === "epic") {
2862
+ const g = _ + 12, m = this.ctx.createRadialGradient(r, c, _, r, c, g);
2863
+ m.addColorStop(0, d), m.addColorStop(1, "rgba(0, 0, 0, 0)"), this.ctx.fillStyle = m, this.ctx.beginPath(), this.ctx.arc(r, c, g, 0, Math.PI * 2), this.ctx.fill();
2771
2864
  }
2772
- const _ = this.ctx.createRadialGradient(o, r, 2, o, r, p * 1.4);
2773
- _.addColorStop(0, a.effectHighlight), _.addColorStop(0.4, l), _.addColorStop(1, c ? "rgba(23, 50, 77, 0.24)" : "rgba(0, 0, 0, 0.5)"), this.ctx.fillStyle = _, this.ctx.beginPath(), this.ctx.arc(o, r, p, 0, Math.PI * 2), this.ctx.fill(), this.ctx.strokeStyle = u, this.ctx.lineWidth = h === "legendary" ? 3.5 : 2.5, this.ctx.beginPath(), this.ctx.arc(o, r, p + 4, e * 3, e * 3 + Math.PI * 1.2), this.ctx.stroke(), (h === "legendary" || h === "epic") && (this.ctx.strokeStyle = c ? u : a.effectHighlight, this.ctx.lineWidth = 1.5, this.ctx.beginPath(), this.ctx.arc(o, r, p + 8, -e * 2, -e * 2 + Math.PI * 0.9), this.ctx.stroke()), this.ctx.font = "900 14px Orbitron, sans-serif", this.ctx.textAlign = "center", this.ctx.textBaseline = "middle", this.ctx.fillStyle = a.effectInk, this.ctx.shadowColor = a.effectShadow, this.ctx.shadowBlur = 6, this.ctx.fillText(n.definition.badge, o, r);
2774
- const g = i ? i.translate(n.definition.titleKey) : n.definition.badge;
2775
- this.ctx.textBaseline = "alphabetic", this.ctx.font = "900 16px Orbitron, sans-serif", this.ctx.fillStyle = a.effectInk, this.ctx.shadowColor = u, this.ctx.shadowBlur = 14, this.ctx.fillText(g, o, r - p - 14), this.ctx.restore();
2865
+ const f = this.ctx.createRadialGradient(r, c, 2, r, c, _ * 1.4);
2866
+ f.addColorStop(0, l.effectHighlight), f.addColorStop(0.4, h), f.addColorStop(1, n ? "rgba(23, 50, 77, 0.24)" : "rgba(0, 0, 0, 0.5)"), this.ctx.fillStyle = f, this.ctx.beginPath(), this.ctx.arc(r, c, _, 0, Math.PI * 2), this.ctx.fill(), this.ctx.strokeStyle = d, this.ctx.lineWidth = u === "legendary" ? 3.5 : 2.5, this.ctx.beginPath(), this.ctx.arc(r, c, _ + 4, e * 3, e * 3 + Math.PI * 1.2), this.ctx.stroke(), (u === "legendary" || u === "epic") && (this.ctx.strokeStyle = n ? d : l.effectHighlight, this.ctx.lineWidth = 1.5, this.ctx.beginPath(), this.ctx.arc(r, c, _ + 8, -e * 2, -e * 2 + Math.PI * 0.9), this.ctx.stroke()), this.ctx.font = "900 14px Orbitron, sans-serif", this.ctx.textAlign = "center", this.ctx.textBaseline = "middle", this.ctx.fillStyle = l.effectInk, this.ctx.shadowColor = l.effectShadow, this.ctx.shadowBlur = 6, this.ctx.fillText(o.definition.badge, r, c);
2867
+ const p = i ? i.translate(o.definition.titleKey) : o.definition.badge;
2868
+ this.ctx.textBaseline = "alphabetic", this.ctx.font = "900 16px Orbitron, sans-serif", this.ctx.fillStyle = l.effectInk, this.ctx.shadowColor = d, this.ctx.shadowBlur = 14, this.ctx.fillText(p, r, c - _ - 14), this.ctx.restore();
2776
2869
  }
2777
2870
  if (i && s) {
2778
- const n = this.canvas.width / 2, o = this.canvas.height / 2 + 210, r = i.translate("rerollButton");
2779
- this.ctx.save(), this.ctx.font = "900 14px Orbitron, sans-serif", this.ctx.textAlign = "center", this.ctx.textBaseline = "middle", this.ctx.fillStyle = a.effectPanel, this.ctx.strokeStyle = a.tendrilCyan, this.ctx.lineWidth = 2, this.ctx.shadowColor = a.tendrilCyan, this.ctx.shadowBlur = 12;
2780
- const u = this.ctx.measureText(r).width + 20 * 2, p = 38;
2781
- this.ctx.beginPath(), this.ctx.roundRect(n - u / 2, o - p / 2, u, p, 8), this.ctx.fill(), this.ctx.stroke(), this.ctx.fillStyle = a.effectInk, this.ctx.shadowColor = a.effectShadow, this.ctx.shadowBlur = 4, this.ctx.fillText(r, n, o), this.ctx.restore();
2871
+ const o = this.canvas.width / 2, r = this.canvas.height / 2 + 210, c = i.translate("rerollButton", { count: a });
2872
+ this.ctx.save(), this.ctx.font = "900 14px Orbitron, sans-serif", this.ctx.textAlign = "center", this.ctx.textBaseline = "middle", this.ctx.fillStyle = l.effectPanel, this.ctx.strokeStyle = l.tendrilCyan, this.ctx.lineWidth = 2, this.ctx.shadowColor = l.tendrilCyan, this.ctx.shadowBlur = 12;
2873
+ const d = this.ctx.measureText(c).width + 20 * 2, _ = 38;
2874
+ this.ctx.beginPath(), this.ctx.roundRect(o - d / 2, r - _ / 2, d, _, 8), this.ctx.fill(), this.ctx.stroke(), this.ctx.fillStyle = l.effectInk, this.ctx.shadowColor = l.effectShadow, this.ctx.shadowBlur = 4, this.ctx.fillText(c, o, r), this.ctx.restore();
2782
2875
  }
2783
2876
  }
2784
2877
  colorWithAlpha(t, e) {
2785
2878
  const i = t.replace("#", "");
2786
2879
  if (i.length !== 6) return t;
2787
- const s = Number.parseInt(i.slice(0, 2), 16), a = Number.parseInt(i.slice(2, 4), 16), c = Number.parseInt(i.slice(4, 6), 16);
2788
- return `rgba(${s}, ${a}, ${c}, ${e})`;
2880
+ const s = Number.parseInt(i.slice(0, 2), 16), a = Number.parseInt(i.slice(2, 4), 16), l = Number.parseInt(i.slice(4, 6), 16);
2881
+ return `rgba(${s}, ${a}, ${l}, ${e})`;
2789
2882
  }
2790
2883
  }
2791
- class dt {
2884
+ class _t {
2792
2885
  container;
2793
2886
  i18n;
2794
2887
  waveLabelElement;
@@ -2820,7 +2913,7 @@ class dt {
2820
2913
  this.container.style.display = "none";
2821
2914
  }
2822
2915
  }
2823
- class gt {
2916
+ class ft {
2824
2917
  container;
2825
2918
  i18n;
2826
2919
  onStartCallback;
@@ -2846,7 +2939,7 @@ class gt {
2846
2939
  this.container.style.display = "none";
2847
2940
  }
2848
2941
  }
2849
- class _t {
2942
+ class mt {
2850
2943
  modal;
2851
2944
  card;
2852
2945
  i18n;
@@ -2855,8 +2948,8 @@ class _t {
2855
2948
  onLanguageChangedCallback;
2856
2949
  onCloseCallback;
2857
2950
  hapticsEnabled = !0;
2858
- constructor(t, e, i, s, a, c) {
2859
- this.i18n = e, this.themeManager = i, this.platform = s, this.onLanguageChangedCallback = a, this.onCloseCallback = c;
2951
+ constructor(t, e, i, s, a, l) {
2952
+ this.i18n = e, this.themeManager = i, this.platform = s, this.onLanguageChangedCallback = a, this.onCloseCallback = l;
2860
2953
  const n = localStorage.getItem("axon_surge_haptics");
2861
2954
  n !== null && (this.hapticsEnabled = n === "true"), this.modal = document.createElement("dialog"), this.modal.className = "axon-settings-modal", this.card = document.createElement("div"), this.card.className = "axon-settings-card", this.modal.appendChild(this.card), t.appendChild(this.modal), this.modal.addEventListener("close", () => {
2862
2955
  this.onCloseCallback && this.onCloseCallback();
@@ -2874,7 +2967,7 @@ class _t {
2874
2967
  s.className = "axon-select-wrapper";
2875
2968
  const a = document.createElement("select");
2876
2969
  a.className = "axon-select";
2877
- const c = {
2970
+ const l = {
2878
2971
  es: "ESPAÑOL (ES)",
2879
2972
  en: "ENGLISH (EN)",
2880
2973
  fr: "FRANÇAIS (FR)",
@@ -2891,13 +2984,13 @@ class _t {
2891
2984
  ko: "한국어 (KO)",
2892
2985
  zh: "中文 (ZH)"
2893
2986
  };
2894
- for (const f of K) {
2895
- const v = document.createElement("option");
2896
- v.value = f, v.textContent = c[f], this.i18n.getLanguage() === f && (v.selected = !0), a.appendChild(v);
2987
+ for (const v of V) {
2988
+ const x = document.createElement("option");
2989
+ x.value = v, x.textContent = l[v], this.i18n.getLanguage() === v && (x.selected = !0), a.appendChild(x);
2897
2990
  }
2898
2991
  a.addEventListener("change", () => {
2899
- const f = a.value;
2900
- this.i18n.setLanguage(f), this.onLanguageChangedCallback && this.onLanguageChangedCallback(f), this.renderContent();
2992
+ const v = a.value;
2993
+ this.i18n.setLanguage(v), this.onLanguageChangedCallback && this.onLanguageChangedCallback(v), this.renderContent();
2901
2994
  });
2902
2995
  const n = document.createElement("span");
2903
2996
  n.className = "axon-select-arrow", n.textContent = "▼", s.appendChild(a), s.appendChild(n), e.appendChild(i), e.appendChild(s);
@@ -2905,60 +2998,60 @@ class _t {
2905
2998
  o.className = "axon-setting-row";
2906
2999
  const r = document.createElement("span");
2907
3000
  r.textContent = this.i18n.translate("themeLabel");
2908
- const l = document.createElement("div");
2909
- l.className = "axon-toggle-group";
3001
+ const c = document.createElement("div");
3002
+ c.className = "axon-toggle-group";
2910
3003
  const h = [
2911
3004
  { id: "bioluminescent", label: "BIO" },
2912
3005
  { id: "dark", label: "DARK" },
2913
3006
  { id: "light", label: "LIGHT" }
2914
3007
  ];
2915
- for (const f of h) {
2916
- const v = document.createElement("button");
2917
- v.type = "button", v.className = `axon-toggle-btn ${this.themeManager.getTheme() === f.id ? "active" : ""}`, v.textContent = f.label, v.addEventListener("click", () => {
2918
- this.themeManager.setTheme(f.id), this.renderContent();
2919
- }), l.appendChild(v);
3008
+ for (const v of h) {
3009
+ const x = document.createElement("button");
3010
+ x.type = "button", x.className = `axon-toggle-btn ${this.themeManager.getTheme() === v.id ? "active" : ""}`, x.textContent = v.label, x.addEventListener("click", () => {
3011
+ this.themeManager.setTheme(v.id), this.renderContent();
3012
+ }), c.appendChild(x);
2920
3013
  }
2921
- o.appendChild(r), o.appendChild(l);
3014
+ o.appendChild(r), o.appendChild(c);
2922
3015
  const u = document.createElement("div");
2923
3016
  u.className = "axon-setting-row";
2924
- const p = document.createElement("span");
2925
- p.textContent = this.i18n.translate("hapticsLabel");
3017
+ const d = document.createElement("span");
3018
+ d.textContent = this.i18n.translate("hapticsLabel");
2926
3019
  const _ = document.createElement("div");
2927
3020
  _.className = "axon-toggle-group";
2928
- const g = [
3021
+ const f = [
2929
3022
  { enabled: !0, label: this.i18n.translate("hapticsOn") },
2930
3023
  { enabled: !1, label: this.i18n.translate("hapticsOff") }
2931
3024
  ];
2932
- for (const f of g) {
2933
- const v = document.createElement("button");
2934
- v.type = "button", v.className = `axon-toggle-btn ${this.hapticsEnabled === f.enabled ? "active" : ""}`, v.textContent = f.label, v.addEventListener("click", () => {
2935
- this.hapticsEnabled = f.enabled, localStorage.setItem("axon_surge_haptics", String(f.enabled)), this.hapticsEnabled && this.platform.haptics.selectionChanged(), this.renderContent();
2936
- }), _.appendChild(v);
2937
- }
2938
- u.appendChild(p), u.appendChild(_);
2939
- const d = document.createElement("div");
2940
- d.className = "axon-setting-row";
2941
- const m = document.createElement("span");
2942
- m.textContent = this.i18n.translate("tutorialSettingLabel");
2943
- const x = document.createElement("div");
2944
- x.className = "axon-toggle-group";
2945
- const A = localStorage.getItem("axon_surge_show_tutorial") !== "false", b = [
3025
+ for (const v of f) {
3026
+ const x = document.createElement("button");
3027
+ x.type = "button", x.className = `axon-toggle-btn ${this.hapticsEnabled === v.enabled ? "active" : ""}`, x.textContent = v.label, x.addEventListener("click", () => {
3028
+ this.hapticsEnabled = v.enabled, localStorage.setItem("axon_surge_haptics", String(v.enabled)), this.hapticsEnabled && this.platform.haptics.selectionChanged(), this.renderContent();
3029
+ }), _.appendChild(x);
3030
+ }
3031
+ u.appendChild(d), u.appendChild(_);
3032
+ const p = document.createElement("div");
3033
+ p.className = "axon-setting-row";
3034
+ const g = document.createElement("span");
3035
+ g.textContent = this.i18n.translate("tutorialSettingLabel");
3036
+ const m = document.createElement("div");
3037
+ m.className = "axon-toggle-group";
3038
+ const y = localStorage.getItem("axon_surge_show_tutorial") !== "false", b = [
2946
3039
  { enabled: !0, label: this.i18n.translate("hapticsOn") },
2947
3040
  { enabled: !1, label: this.i18n.translate("hapticsOff") }
2948
3041
  ];
2949
- for (const f of b) {
2950
- const v = document.createElement("button");
2951
- v.type = "button", v.className = `axon-toggle-btn ${A === f.enabled ? "active" : ""}`, v.textContent = f.label, v.addEventListener("click", () => {
2952
- localStorage.setItem("axon_surge_show_tutorial", String(f.enabled)), this.renderContent();
2953
- }), x.appendChild(v);
3042
+ for (const v of b) {
3043
+ const x = document.createElement("button");
3044
+ x.type = "button", x.className = `axon-toggle-btn ${y === v.enabled ? "active" : ""}`, x.textContent = v.label, x.addEventListener("click", () => {
3045
+ localStorage.setItem("axon_surge_show_tutorial", String(v.enabled)), this.renderContent();
3046
+ }), m.appendChild(x);
2954
3047
  }
2955
- d.appendChild(m), d.appendChild(x);
3048
+ p.appendChild(g), p.appendChild(m);
2956
3049
  const I = document.createElement("div");
2957
3050
  I.className = "axon-settings-credits", I.textContent = this.i18n.translate("creditsJam");
2958
3051
  const S = document.createElement("button");
2959
3052
  S.type = "button", S.className = "axon-start-button", S.style.padding = "12px 36px", S.style.fontSize = "14px", S.textContent = this.i18n.translate("closeButton"), S.addEventListener("click", () => {
2960
3053
  this.modal.close();
2961
- }), this.card.appendChild(t), this.card.appendChild(e), this.card.appendChild(o), this.card.appendChild(u), this.card.appendChild(d), this.card.appendChild(I), this.card.appendChild(S);
3054
+ }), this.card.appendChild(t), this.card.appendChild(e), this.card.appendChild(o), this.card.appendChild(u), this.card.appendChild(p), this.card.appendChild(I), this.card.appendChild(S);
2962
3055
  }
2963
3056
  isHapticsEnabled() {
2964
3057
  return this.hapticsEnabled;
@@ -2970,8 +3063,8 @@ class _t {
2970
3063
  this.modal.close();
2971
3064
  }
2972
3065
  }
2973
- const H = "axon_surge_show_tutorial";
2974
- class mt {
3066
+ const B = "axon_surge_show_tutorial";
3067
+ class xt {
2975
3068
  isActive = !1;
2976
3069
  showWarning = !1;
2977
3070
  dummyLauncher = null;
@@ -2980,14 +3073,14 @@ class mt {
2980
3073
  initialTargetPos = { x: 0, y: 0 };
2981
3074
  isTutorialEnabled() {
2982
3075
  try {
2983
- return localStorage.getItem(H) !== "false";
3076
+ return localStorage.getItem(B) !== "false";
2984
3077
  } catch {
2985
3078
  return !0;
2986
3079
  }
2987
3080
  }
2988
3081
  setTutorialEnabled(t) {
2989
3082
  try {
2990
- localStorage.setItem(H, String(t));
3083
+ localStorage.setItem(B, String(t));
2991
3084
  } catch {
2992
3085
  }
2993
3086
  }
@@ -3015,14 +3108,14 @@ class mt {
3015
3108
  this.initialLauncherPos
3016
3109
  ), this.dummyTarget.velocity = { x: 0, y: 0 }, i.push(this.dummyLauncher), i.push(this.dummyTarget);
3017
3110
  }
3018
- update(t, e, i, s, a, c) {
3111
+ update(t, e, i, s, a, l) {
3019
3112
  if (!this.isActive || !this.dummyLauncher || !this.dummyTarget) return;
3020
3113
  const n = this.dummyLauncher, o = this.dummyTarget;
3021
3114
  e.includes(n) || e.push(n), e.includes(o) || e.push(o);
3022
- const r = o.position.x - n.position.x, l = o.position.y - n.position.y, h = Math.hypot(r, l);
3115
+ const r = o.position.x - n.position.x, c = o.position.y - n.position.y, h = Math.hypot(r, c);
3023
3116
  if (n.isGrabbed) {
3024
3117
  if (this.showWarning = !1, h <= n.radius + o.radius + 60) {
3025
- c && c(), n.isGrabbed = !1, this.showWarning = !0, this.resetDummies(n, o);
3118
+ l && l(), n.isGrabbed = !1, this.showWarning = !0, this.resetDummies(n, o);
3026
3119
  return;
3027
3120
  }
3028
3121
  return;
@@ -3030,14 +3123,14 @@ class mt {
3030
3123
  if (n.wasManipulated) {
3031
3124
  const u = Math.hypot(n.velocity.x, n.velocity.y);
3032
3125
  if (!n.isThrown || u < 70) {
3033
- c && c(), this.showWarning = !0, this.resetDummies(n, o);
3126
+ l && l(), this.showWarning = !0, this.resetDummies(n, o);
3034
3127
  return;
3035
3128
  }
3036
3129
  if (h <= n.getHitRadius() + o.getHitRadius()) {
3037
- n.triggerDissolveDeath(), o.triggerDissolveDeath(), this.showWarning = !1, this.isActive = !1, a();
3130
+ n.triggerDissolveDeath(!0), o.triggerDissolveDeath(!0), this.showWarning = !1, this.isActive = !1, a();
3038
3131
  return;
3039
3132
  }
3040
- (n.position.x < -60 || n.position.x > i + 60 || n.position.y < -60 || n.position.y > s + 60 || u < 40) && (c && c(), this.showWarning = !0, this.resetDummies(n, o));
3133
+ (n.position.x < -60 || n.position.x > i + 60 || n.position.y < -60 || n.position.y > s + 60 || u < 40) && (l && l(), this.showWarning = !0, this.resetDummies(n, o));
3041
3134
  }
3042
3135
  }
3043
3136
  resetDummies(t, e) {
@@ -3047,7 +3140,7 @@ class mt {
3047
3140
  this.isActive = !1, this.showWarning = !1;
3048
3141
  }
3049
3142
  }
3050
- class ft {
3143
+ class yt {
3051
3144
  container;
3052
3145
  i18n;
3053
3146
  tutorialManager;
@@ -3083,9 +3176,9 @@ class ft {
3083
3176
  this.container.style.display = "none";
3084
3177
  }
3085
3178
  }
3086
- class xt {
3179
+ class Et {
3087
3180
  fillElement;
3088
- killsCount = 0;
3181
+ experienceCount = 0;
3089
3182
  currentLevel = 1;
3090
3183
  onLevelUpCallback;
3091
3184
  constructor(t, e) {
@@ -3093,19 +3186,25 @@ class xt {
3093
3186
  const i = document.createElement("div");
3094
3187
  i.className = "axon-hud-level-track", this.fillElement = document.createElement("div"), this.fillElement.className = "axon-hud-level-fill", i.appendChild(this.fillElement), t.appendChild(i);
3095
3188
  }
3096
- getKillsRequiredForLevel(t) {
3189
+ getExperienceRequiredForLevel(t) {
3097
3190
  return t === 1 ? 3 : t === 2 ? 6 : t === 3 ? 10 : 10 + (t - 3) * 6;
3098
3191
  }
3192
+ addExperience(t = 1) {
3193
+ this.experienceCount += Math.max(0, t);
3194
+ let e = this.getExperienceRequiredForLevel(this.currentLevel);
3195
+ for (; this.experienceCount >= e; )
3196
+ this.experienceCount -= e, this.currentLevel++, this.onLevelUpCallback && this.onLevelUpCallback(this.currentLevel), e = this.getExperienceRequiredForLevel(this.currentLevel);
3197
+ const i = Math.min(100, this.experienceCount / e * 100);
3198
+ this.fillElement.style.width = `${i}%`;
3199
+ }
3099
3200
  addKill() {
3100
- this.killsCount++;
3101
- const t = this.getKillsRequiredForLevel(this.currentLevel), e = Math.min(100, this.killsCount / t * 100);
3102
- this.fillElement.style.width = `${e}%`, this.killsCount >= t && (this.currentLevel++, this.killsCount = 0, this.fillElement.style.width = "0%", this.onLevelUpCallback && this.onLevelUpCallback(this.currentLevel));
3201
+ this.addExperience(1);
3103
3202
  }
3104
3203
  getLevel() {
3105
3204
  return this.currentLevel;
3106
3205
  }
3107
3206
  reset() {
3108
- this.killsCount = 0, this.currentLevel = 1, this.fillElement.style.width = "0%";
3207
+ this.experienceCount = 0, this.currentLevel = 1, this.fillElement.style.width = "0%";
3109
3208
  }
3110
3209
  show() {
3111
3210
  this.fillElement && this.fillElement.parentElement && (this.fillElement.parentElement.style.display = "block");
@@ -3114,7 +3213,7 @@ class xt {
3114
3213
  this.fillElement && this.fillElement.parentElement && (this.fillElement.parentElement.style.display = "none");
3115
3214
  }
3116
3215
  }
3117
- class B {
3216
+ class K {
3118
3217
  static powerUps = [
3119
3218
  {
3120
3219
  id: "spore_radius",
@@ -3254,6 +3353,46 @@ class B {
3254
3353
  });
3255
3354
  }
3256
3355
  },
3356
+ {
3357
+ id: "shield_fan_upgrade",
3358
+ titleKey: "pu_shield_fan_upgrade_title",
3359
+ descKey: "pu_shield_fan_upgrade_desc",
3360
+ badge: "+0.35s / +15°",
3361
+ category: "power",
3362
+ rarity: "epic",
3363
+ rarityWeight: 15,
3364
+ color: "#00f5ff",
3365
+ apply: () => {
3366
+ const t = E.getInstance(), e = t.getConfig().shield;
3367
+ t.updateConfig({
3368
+ shield: {
3369
+ ...e,
3370
+ fanBlastInterval: e.fanBlastInterval + 0.35,
3371
+ fanBlastAngle: e.fanBlastAngle + Math.PI / 12,
3372
+ hasFanBlastUpgrade: !0
3373
+ }
3374
+ });
3375
+ }
3376
+ },
3377
+ {
3378
+ id: "shield_arc",
3379
+ titleKey: "pu_shield_arc_title",
3380
+ descKey: "pu_shield_arc_desc",
3381
+ badge: "+30° ARC",
3382
+ category: "defense",
3383
+ rarity: "common",
3384
+ rarityWeight: 35,
3385
+ color: "#00f5ff",
3386
+ apply: () => {
3387
+ const t = E.getInstance(), e = t.getConfig().shield;
3388
+ t.updateConfig({
3389
+ shield: {
3390
+ ...e,
3391
+ protectionArc: Math.min(Math.PI * 1.5, e.protectionArc + Math.PI / 6)
3392
+ }
3393
+ });
3394
+ }
3395
+ },
3257
3396
  {
3258
3397
  id: "cluster_extra",
3259
3398
  titleKey: "pu_cluster_extra_title",
@@ -3418,13 +3557,51 @@ class B {
3418
3557
  apply: (t) => {
3419
3558
  E.getInstance().addCoreRing(1), t && t.addMaxRing(1);
3420
3559
  }
3560
+ },
3561
+ {
3562
+ id: "magnet_radius",
3563
+ titleKey: "pu_magnet_radius_title",
3564
+ descKey: "pu_magnet_radius_desc",
3565
+ badge: "+60 MAGNET",
3566
+ category: "magnet",
3567
+ rarity: "common",
3568
+ rarityWeight: 35,
3569
+ color: "#00f5ff",
3570
+ apply: () => {
3571
+ const t = E.getInstance(), e = t.getConfig().magnet;
3572
+ t.updateConfig({
3573
+ magnet: {
3574
+ ...e,
3575
+ pickupRadius: e.pickupRadius + 60
3576
+ }
3577
+ });
3578
+ }
3579
+ },
3580
+ {
3581
+ id: "magnet_strength",
3582
+ titleKey: "pu_magnet_strength_title",
3583
+ descKey: "pu_magnet_strength_desc",
3584
+ badge: "+25% PULL",
3585
+ category: "magnet",
3586
+ rarity: "rare",
3587
+ rarityWeight: 25,
3588
+ color: "#00f5ff",
3589
+ apply: () => {
3590
+ const t = E.getInstance(), e = t.getConfig().magnet;
3591
+ t.updateConfig({
3592
+ magnet: {
3593
+ ...e,
3594
+ absorptionSpeed: Math.round(e.absorptionSpeed * 1.25)
3595
+ }
3596
+ });
3597
+ }
3421
3598
  }
3422
3599
  ];
3423
3600
  static getRandomOptions(t = 3) {
3424
- const e = E.getInstance().getConfig(), i = this.powerUps.filter((a) => !(a.id === "vampirism_unlock" && e.core.vampirismHealProgressRate > 0 || a.id === "vampirism_boost" && e.core.vampirismHealProgressRate <= 0 || a.id === "piercer_homing" && e.piercer.hasHoming || a.id === "piercer_homing_target" && !e.piercer.hasHoming || a.id === "vortex_pocket" && e.gravityVortex.hasImplosionLaunch || a.id === "shield_fan" && e.shield.isFanBlast || a.id === "cluster_homing" && e.cluster.hasHoming || a.id === "offscreen_radar" && e.core.hasOffscreenIndicators)), s = [];
3601
+ const e = E.getInstance().getConfig(), i = this.powerUps.filter((a) => !(a.id === "vampirism_unlock" && e.core.vampirismHealProgressRate > 0 || a.id === "vampirism_boost" && e.core.vampirismHealProgressRate <= 0 || a.id === "piercer_homing" && e.piercer.hasHoming || a.id === "piercer_homing_target" && !e.piercer.hasHoming || a.id === "vortex_pocket" && e.gravityVortex.hasImplosionLaunch || a.id === "shield_fan" && e.shield.isFanBlast || a.id === "shield_fan_upgrade" && (!e.shield.isFanBlast || e.shield.hasFanBlastUpgrade) || a.id === "cluster_homing" && e.cluster.hasHoming || a.id === "offscreen_radar" && e.core.hasOffscreenIndicators)), s = [];
3425
3602
  for (let a = 0; a < t && i.length > 0; a++) {
3426
- const c = i.reduce((o, r) => o + r.rarityWeight, 0);
3427
- let n = Math.random() * c;
3603
+ const l = i.reduce((o, r) => o + r.rarityWeight, 0);
3604
+ let n = Math.random() * l;
3428
3605
  for (let o = 0; o < i.length; o++) {
3429
3606
  const r = i[o];
3430
3607
  if (n -= r.rarityWeight, n <= 0) {
@@ -3439,7 +3616,7 @@ class B {
3439
3616
  this.powerUps.push(t);
3440
3617
  }
3441
3618
  }
3442
- class yt {
3619
+ class At {
3443
3620
  haptics = {
3444
3621
  impact: async (t) => {
3445
3622
  if ("vibrate" in navigator) {
@@ -3479,7 +3656,7 @@ class yt {
3479
3656
  }
3480
3657
  };
3481
3658
  }
3482
- class Et {
3659
+ class bt {
3483
3660
  container;
3484
3661
  canvas;
3485
3662
  i18n;
@@ -3506,15 +3683,18 @@ class Et {
3506
3683
  shockwaves = [];
3507
3684
  particles = [];
3508
3685
  floatingTexts = [];
3686
+ experienceOrbs = [];
3509
3687
  orbitingOrbs = [];
3510
3688
  isLevelUpActive = !1;
3511
- hasRerolledThisLevel = !1;
3689
+ pendingLevelUps = [];
3690
+ debugRerollsEnabled = typeof window < "u" && window.location.hostname === "localhost" && new URLSearchParams(window.location.search).has("debug");
3691
+ rerollsRemaining = 1;
3512
3692
  score = { value: 0 };
3513
3693
  combo = { value: 0 };
3514
3694
  isRunning = !1;
3515
3695
  isPaused = !1;
3516
3696
  constructor(t) {
3517
- this.container = t.root, this.container.classList.add("axon-game-root"), this.i18n = new z(t.language), this.themeManager = new lt(t.theme, this.container), this.platform = t.platform || new yt(), this.canvas = document.createElement("canvas"), this.canvas.className = "axon-canvas", this.container.appendChild(this.canvas), this.resizeCanvas(), window.addEventListener("resize", () => this.resizeCanvas()), this.eventBus = new V(), this.core = new F(this.canvas.width / 2, this.canvas.height / 2), this.inputManager = new Y(this.canvas), this.physicsEngine = new ot(this.eventBus, this.i18n), this.waveDirector = new rt(), this.renderer = new pt(this.canvas, this.themeManager), this.juice = new J(), this.settingsModal = new _t(
3697
+ this.container = t.root, this.container.classList.add("axon-game-root"), this.i18n = new $(t.language), this.themeManager = new ht(t.theme, this.container), this.platform = t.platform || new At(), this.canvas = document.createElement("canvas"), this.canvas.className = "axon-canvas", this.container.appendChild(this.canvas), this.resizeCanvas(), window.addEventListener("resize", () => this.resizeCanvas()), this.eventBus = new F(), this.core = new Y(this.canvas.width / 2, this.canvas.height / 2), this.inputManager = new Z(this.canvas), this.physicsEngine = new nt(this.eventBus, this.i18n), this.waveDirector = new lt(), this.renderer = new gt(this.canvas, this.themeManager), this.juice = new J(), this.settingsModal = new mt(
3518
3698
  this.container,
3519
3699
  this.i18n,
3520
3700
  this.themeManager,
@@ -3523,11 +3703,11 @@ class Et {
3523
3703
  () => {
3524
3704
  this.isPaused = !1;
3525
3705
  }
3526
- ), this.interactiveTutorial = new mt(), this.tutorialOverlay = new ft(this.container, this.i18n, this.interactiveTutorial), this.hud = new dt(this.container, this.i18n, () => {
3706
+ ), this.interactiveTutorial = new xt(), this.tutorialOverlay = new yt(this.container, this.i18n, this.interactiveTutorial), this.hud = new _t(this.container, this.i18n, () => {
3527
3707
  this.isPaused = !0, this.settingsModal.show();
3528
- }), this.hud.show(), this.progressBar = new xt(this.hud.progressSlot, (e) => {
3708
+ }), this.hud.show(), this.progressBar = new Et(this.hud.progressSlot, (e) => {
3529
3709
  this.waveDirector.wave = e, this.triggerLevelUp(e);
3530
- }), this.startMenu = new gt(this.container, this.i18n, () => this.startGame()), this.initAmbientArena(), this.gameLoop = new W(
3710
+ }), this.startMenu = new ft(this.container, this.i18n, () => this.startGame()), this.initAmbientArena(), this.gameLoop = new W(
3531
3711
  (e) => this.update(e),
3532
3712
  () => this.render()
3533
3713
  ), this.setupEvents(), this.gameLoop.start();
@@ -3551,12 +3731,12 @@ class Et {
3551
3731
  this.ambientEnemies = [];
3552
3732
  const t = ["piercer", "spore", "cluster", "parasite"];
3553
3733
  for (let e = 0; e < 16; e++) {
3554
- const i = t[e % t.length], s = e * Math.PI * 2 / 16, a = 180 + Math.random() * 220, c = {
3734
+ const i = t[e % t.length], s = e * Math.PI * 2 / 16, a = 180 + Math.random() * 220, l = {
3555
3735
  x: this.canvas.width / 2 + Math.cos(s) * a,
3556
3736
  y: this.canvas.height / 2 + Math.sin(s) * a
3557
- }, n = M.createEnemy(i, c, {
3558
- x: c.x + Math.sin(s) * 100,
3559
- y: c.y - Math.cos(s) * 100
3737
+ }, n = M.createEnemy(i, l, {
3738
+ x: l.x + Math.sin(s) * 100,
3739
+ y: l.y - Math.cos(s) * 100
3560
3740
  });
3561
3741
  this.ambientEnemies.push(n);
3562
3742
  }
@@ -3569,13 +3749,13 @@ class Et {
3569
3749
  this.eventBus.on("onCoreDamaged", () => {
3570
3750
  this.settingsModal.isHapticsEnabled() && this.platform.haptics.notification("error");
3571
3751
  }), this.eventBus.on("onGameOver", () => {
3572
- this.isRunning = !1, this.tutorialOverlay.hide(), this.progressBar.hide(), this.initAmbientArena(), this.startMenu.show();
3752
+ this.isRunning = !1, this.experienceOrbs = [], this.pendingLevelUps = [], this.tutorialOverlay.hide(), this.progressBar.hide(), this.initAmbientArena(), this.startMenu.show();
3573
3753
  });
3574
3754
  const t = (i = !1) => {
3575
- if (!this.isRunning || this.isPaused) return;
3755
+ if (!this.isRunning || this.isPaused || this.isLevelUpActive) return;
3576
3756
  this.inputManager.tryGrab(this.enemies, i) && this.settingsModal.isHapticsEnabled() && this.platform.haptics.impact("light");
3577
3757
  }, e = () => {
3578
- if (!this.isRunning || this.isPaused) return;
3758
+ if (!this.isRunning || this.isPaused || this.isLevelUpActive) return;
3579
3759
  this.inputManager.releaseAndThrow() && this.settingsModal.isHapticsEnabled() && this.platform.haptics.impact("medium");
3580
3760
  };
3581
3761
  this.canvas.addEventListener("mousedown", (i) => {
@@ -3585,7 +3765,7 @@ class Et {
3585
3765
  }), this.canvas.addEventListener("touchstart", () => t(!0), { passive: !0 }), this.canvas.addEventListener("touchend", e, { passive: !0 }), this.canvas.addEventListener("touchcancel", e, { passive: !0 });
3586
3766
  }
3587
3767
  startGame() {
3588
- E.getInstance().resetToDefault(), this.score.value = 0, this.combo.value = 0, this.enemies = [], this.ambientEnemies = [], this.pools = [], this.vortices = [], this.shockwaves = [], this.particles = [], this.floatingTexts = [], this.orbitingOrbs = [], this.isLevelUpActive = !1, this.hasRerolledThisLevel = !1, this.core.reset(this.canvas.width / 2, this.canvas.height / 2), this.waveDirector.reset(), this.inputManager.reset(), this.hud.show(), this.hud.update(1, 0), this.progressBar.reset(), this.progressBar.show(), this.isPaused = !1, this.isRunning = !0, this.interactiveTutorial.isTutorialEnabled() ? (this.interactiveTutorial.start(this.canvas.width, this.canvas.height, this.enemies), this.tutorialOverlay.show()) : (this.interactiveTutorial.isActive = !1, this.tutorialOverlay.hide());
3768
+ E.getInstance().resetToDefault(), this.score.value = 0, this.combo.value = 0, this.enemies = [], this.ambientEnemies = [], this.pools = [], this.vortices = [], this.shockwaves = [], this.particles = [], this.floatingTexts = [], this.experienceOrbs = [], this.orbitingOrbs = [], this.isLevelUpActive = !1, this.pendingLevelUps = [], this.rerollsRemaining = this.getRerollLimit(), this.core.reset(this.canvas.width / 2, this.canvas.height / 2), this.waveDirector.reset(), this.inputManager.reset(), this.hud.show(), this.hud.update(1, 0), this.progressBar.reset(), this.progressBar.show(), this.isPaused = !1, this.isRunning = !0, this.interactiveTutorial.isTutorialEnabled() ? (this.interactiveTutorial.start(this.canvas.width, this.canvas.height, this.enemies), this.tutorialOverlay.show()) : (this.interactiveTutorial.isActive = !1, this.tutorialOverlay.hide());
3589
3769
  }
3590
3770
  update(t) {
3591
3771
  if (this.core.update(t), !this.isRunning || this.isPaused) {
@@ -3619,21 +3799,21 @@ class Et {
3619
3799
  const e = this.inputManager.grabbedOrb;
3620
3800
  !this.inputManager.isPointerDown && e && (e.isGrabbed = !1, this.inputManager.grabbedOrb = null);
3621
3801
  const i = this.inputManager.pointerPosition;
3622
- if (this.inputManager.isPointerDown && !this.inputManager.grabbedOrb && !this.hasRerolledThisLevel) {
3802
+ if (this.inputManager.isPointerDown && !this.inputManager.grabbedOrb && this.rerollsRemaining > 0) {
3623
3803
  const s = this.canvas.width / 2, a = this.canvas.height / 2 + 210;
3624
3804
  Math.hypot(i.x - s, i.y - a) <= 80 && (this.triggerReroll(), this.inputManager.isPointerDown = !1);
3625
3805
  }
3626
3806
  for (const s of this.orbitingOrbs) {
3627
- const a = i.x - s.position.x, c = i.y - s.position.y;
3628
- if (s.isHovered = Math.hypot(a, c) <= s.radius * 1.5, s === e && this.inputManager.isPointerDown) {
3807
+ const a = i.x - s.position.x, l = i.y - s.position.y;
3808
+ if (s.isHovered = Math.hypot(a, l) <= s.radius * 1.5, s === e && this.inputManager.isPointerDown) {
3629
3809
  s.position = { ...this.inputManager.pointerPosition };
3630
3810
  const n = this.core.position.x - s.position.x, o = this.core.position.y - s.position.y;
3631
3811
  if (Math.hypot(n, o) <= this.core.radius + s.radius) {
3632
3812
  s.definition.apply(this.core), this.core.absorbPowerUpColor(s.definition.color, 0.4), this.juice.triggerFlash(0.8), this.juice.triggerScreenShake({ x: n, y: o }, 24);
3633
- const l = this.i18n.translate(s.definition.titleKey);
3813
+ const c = this.i18n.translate(s.definition.titleKey);
3634
3814
  this.floatingTexts.push({
3635
3815
  id: Math.random().toString(),
3636
- text: `+ ${l}`,
3816
+ text: `+ ${c}`,
3637
3817
  position: { ...this.core.position },
3638
3818
  velocity: { x: 0, y: -80 },
3639
3819
  color: s.definition.color,
@@ -3643,11 +3823,11 @@ class Et {
3643
3823
  size: 26
3644
3824
  });
3645
3825
  for (let h = 0; h < 45; h++) {
3646
- const u = Math.random() * Math.PI * 2, p = 200 + Math.random() * 400;
3826
+ const u = Math.random() * Math.PI * 2, d = 200 + Math.random() * 400;
3647
3827
  this.particles.push({
3648
3828
  id: Math.random().toString(),
3649
3829
  position: { ...this.core.position },
3650
- velocity: { x: Math.cos(u) * p, y: Math.sin(u) * p },
3830
+ velocity: { x: Math.cos(u) * d, y: Math.sin(u) * d },
3651
3831
  color: s.definition.color,
3652
3832
  radius: 4 + Math.random() * 5,
3653
3833
  alpha: 1,
@@ -3655,13 +3835,13 @@ class Et {
3655
3835
  maxLifetime: 0.7
3656
3836
  });
3657
3837
  }
3658
- this.inputManager.forceRelease(), this.orbitingOrbs = [], this.isLevelUpActive = !1;
3838
+ this.inputManager.forceRelease(), this.orbitingOrbs = [], this.presentNextLevelUp();
3659
3839
  }
3660
3840
  } else
3661
3841
  s.update(t, this.core.position);
3662
3842
  }
3663
3843
  }
3664
- this.juice.hitstopTime <= 0 && this.physicsEngine.update(
3844
+ !this.isLevelUpActive && this.juice.hitstopTime <= 0 && this.physicsEngine.update(
3665
3845
  t,
3666
3846
  this.core,
3667
3847
  this.enemies,
@@ -3676,7 +3856,7 @@ class Et {
3676
3856
  this.canvas.width,
3677
3857
  this.canvas.height,
3678
3858
  () => {
3679
- this.progressBar.addKill(), this.core.addKillRepair() && (this.juice.triggerFlash(0.4), this.floatingTexts.push({
3859
+ this.core.addKillRepair() && (this.juice.triggerFlash(0.4), this.floatingTexts.push({
3680
3860
  id: Math.random().toString(),
3681
3861
  text: "RING RESTORED!",
3682
3862
  position: { ...this.core.position },
@@ -3688,37 +3868,18 @@ class Et {
3688
3868
  size: 22
3689
3869
  }));
3690
3870
  }
3691
- ), this.hud.update(this.progressBar.getLevel(), this.combo.value), this.juice.update(t, this.floatingTexts, this.particles), this.enemies = this.enemies.filter((e) => e.active);
3871
+ ), this.spawnExperienceDrops(), this.isLevelUpActive || this.updateExperienceOrbs(t), this.hud.update(this.progressBar.getLevel(), this.combo.value), this.juice.update(t, this.floatingTexts, this.particles), this.enemies = this.enemies.filter((e) => e.active);
3692
3872
  }
3693
3873
  triggerLevelUp(t) {
3694
- this.isLevelUpActive = !0;
3695
- for (const i of this.enemies)
3696
- if (i.active) {
3697
- i.triggerDissolveDeath();
3698
- for (let s = 0; s < 6; s++) {
3699
- const a = Math.random() * Math.PI * 2, c = 100 + Math.random() * 200;
3700
- this.particles.push({
3701
- id: Math.random().toString(),
3702
- position: { ...i.position },
3703
- velocity: { x: Math.cos(a) * c, y: Math.sin(a) * c },
3704
- color: "#00f0ff",
3705
- radius: 3 + Math.random() * 3,
3706
- alpha: 1,
3707
- lifetime: 0,
3708
- maxLifetime: 0.5
3709
- });
3710
- }
3711
- }
3712
- this.shockwaves.push({
3713
- id: Math.random().toString(),
3714
- position: { ...this.core.position },
3715
- radius: 20,
3716
- maxRadius: Math.max(this.canvas.width, this.canvas.height) * 1.4,
3717
- color: "#00f0ff",
3718
- alpha: 1,
3719
- lifetime: 0,
3720
- maxLifetime: 0.8
3721
- }), this.juice.triggerFlash(0.6), this.juice.triggerScreenShake({ x: 0, y: 1 }, 20), this.floatingTexts.push({
3874
+ this.pendingLevelUps.push(t), this.isLevelUpActive || this.presentNextLevelUp();
3875
+ }
3876
+ presentNextLevelUp() {
3877
+ const t = this.pendingLevelUps.shift();
3878
+ if (t === void 0) {
3879
+ this.isLevelUpActive = !1;
3880
+ return;
3881
+ }
3882
+ this.isLevelUpActive = !0, this.inputManager.forceRelease(), this.juice.triggerFlash(0.3), this.juice.triggerScreenShake({ x: 0, y: 1 }, 8), this.floatingTexts.push({
3722
3883
  id: Math.random().toString(),
3723
3884
  text: this.i18n.translate("levelUpChoose", { level: t }),
3724
3885
  position: { ...this.core.position },
@@ -3729,16 +3890,58 @@ class Et {
3729
3890
  maxLifetime: 2,
3730
3891
  size: 30
3731
3892
  });
3732
- const e = B.getRandomOptions(3);
3893
+ for (let i = 0; i < 18; i++) {
3894
+ const s = Math.random() * Math.PI * 2, a = 80 + Math.random() * 160;
3895
+ this.particles.push({
3896
+ id: Math.random().toString(),
3897
+ position: { ...this.core.position },
3898
+ velocity: { x: Math.cos(s) * a, y: Math.sin(s) * a },
3899
+ color: "#00f0ff",
3900
+ radius: 2 + Math.random() * 3,
3901
+ alpha: 1,
3902
+ lifetime: 0,
3903
+ maxLifetime: 0.7
3904
+ });
3905
+ }
3906
+ const e = K.getRandomOptions(3);
3733
3907
  this.orbitingOrbs = e.map((i, s) => {
3734
3908
  const a = s * Math.PI * 2 / e.length;
3735
3909
  return new G(`orb_${Date.now()}_${s}`, i, a);
3736
- }), this.hasRerolledThisLevel = !1;
3910
+ }), this.rerollsRemaining = this.getRerollLimit();
3911
+ }
3912
+ spawnExperienceDrops() {
3913
+ for (const t of this.enemies)
3914
+ t.experienceDropPending && (t.experienceDropPending = !1, this.experienceOrbs.push(new ct(t.position)));
3915
+ }
3916
+ updateExperienceOrbs(t) {
3917
+ const e = E.getInstance().getConfig().magnet;
3918
+ for (const i of this.experienceOrbs)
3919
+ if (i.active) {
3920
+ if (i.isAbsorbing || Math.hypot(
3921
+ this.core.position.x - i.position.x,
3922
+ this.core.position.y - i.position.y
3923
+ ) <= this.core.getHitboxRadius() + e.corePickupRadius && i.beginAbsorption(), !i.isAbsorbing) {
3924
+ const s = this.inputManager.pointerPosition.x - i.position.x, a = this.inputManager.pointerPosition.y - i.position.y, l = e.psionicRadius + e.pickupRadius + i.radius;
3925
+ Math.hypot(s, a) <= l && i.beginAbsorption();
3926
+ }
3927
+ i.update(t, this.core.position, this.core.getHitboxRadius(), e.absorptionSpeed), i.active || (this.progressBar.addExperience(i.value), this.juice.triggerFlash(0.12), this.floatingTexts.push({
3928
+ id: Math.random().toString(),
3929
+ text: `+${i.value} XP`,
3930
+ position: { ...this.core.position },
3931
+ velocity: { x: 0, y: -55 },
3932
+ color: "#fbbf24",
3933
+ alpha: 1,
3934
+ lifetime: 0,
3935
+ maxLifetime: 0.8,
3936
+ size: 18
3937
+ }));
3938
+ }
3939
+ this.experienceOrbs = this.experienceOrbs.filter((i) => i.active);
3737
3940
  }
3738
3941
  triggerReroll() {
3739
- if (this.hasRerolledThisLevel) return;
3740
- this.hasRerolledThisLevel = !0, this.juice.triggerFlash(0.4);
3741
- const t = B.getRandomOptions(3);
3942
+ if (this.rerollsRemaining <= 0) return;
3943
+ this.rerollsRemaining -= 1, this.juice.triggerFlash(0.4);
3944
+ const t = K.getRandomOptions(3);
3742
3945
  this.orbitingOrbs = t.map((e, i) => {
3743
3946
  const s = i * Math.PI * 2 / t.length;
3744
3947
  return new G(`orb_${Date.now()}_${i}`, e, s);
@@ -3749,6 +3952,7 @@ class Et {
3749
3952
  this.renderer.render(
3750
3953
  this.core,
3751
3954
  t,
3955
+ this.experienceOrbs,
3752
3956
  this.pools,
3753
3957
  this.vortices,
3754
3958
  this.shockwaves,
@@ -3759,20 +3963,29 @@ class Et {
3759
3963
  this.inputManager.pointerPosition,
3760
3964
  this.progressBar.getLevel(),
3761
3965
  this.interactiveTutorial.isActive ? this.interactiveTutorial : void 0
3762
- ), this.isLevelUpActive && this.orbitingOrbs.length > 0 && this.renderer.drawOrbitingModifierOrbs(this.orbitingOrbs, this.core.pulsePhase, this.i18n, !this.hasRerolledThisLevel);
3966
+ ), this.isLevelUpActive && this.orbitingOrbs.length > 0 && this.renderer.drawOrbitingModifierOrbs(
3967
+ this.orbitingOrbs,
3968
+ this.core.pulsePhase,
3969
+ this.i18n,
3970
+ this.rerollsRemaining > 0,
3971
+ this.rerollsRemaining
3972
+ );
3973
+ }
3974
+ getRerollLimit() {
3975
+ return this.debugRerollsEnabled ? 99 : 1;
3763
3976
  }
3764
3977
  destroy() {
3765
3978
  this.gameLoop.stop(), this.canvas.remove();
3766
3979
  }
3767
3980
  }
3768
- function At(y) {
3769
- return new Et(y);
3981
+ function vt(A) {
3982
+ return new bt(A);
3770
3983
  }
3771
3984
  export {
3772
- yt as BrowserPlatform,
3773
- Et as GameEngine,
3774
- K as LANGUAGES,
3775
- lt as ThemeManager,
3776
- At as createAxonSurge,
3777
- P as isLanguage
3985
+ At as BrowserPlatform,
3986
+ bt as GameEngine,
3987
+ V as LANGUAGES,
3988
+ ht as ThemeManager,
3989
+ vt as createAxonSurge,
3990
+ N as isLanguage
3778
3991
  };