@umang-boss/claudemon 2.1.3 → 2.2.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.
- package/dist/award-xp.mjs +129 -58
- package/dist/award-xp.mjs.map +3 -3
- package/dist/server.mjs +492 -99
- package/dist/server.mjs.map +2 -2
- package/package.json +1 -1
- package/src/engine/encounter-pool.ts +51 -6
- package/src/engine/encounters.ts +122 -128
- package/src/gamification/legendary-quests.ts +515 -91
- package/src/hooks/award-xp.ts +3 -5
package/dist/server.mjs
CHANGED
|
@@ -17573,6 +17573,24 @@ function isBaseStage(pokemonId) {
|
|
|
17573
17573
|
return !EVOLVED_IDS.has(pokemonId);
|
|
17574
17574
|
}
|
|
17575
17575
|
var WILD_RARITIES = /* @__PURE__ */ new Set(["common", "uncommon", "rare"]);
|
|
17576
|
+
function buildAllPool() {
|
|
17577
|
+
const common = [];
|
|
17578
|
+
const uncommon = [];
|
|
17579
|
+
const rare = [];
|
|
17580
|
+
for (const pokemon of POKEDEX) {
|
|
17581
|
+
if (!isBaseStage(pokemon.id)) continue;
|
|
17582
|
+
if (!WILD_RARITIES.has(pokemon.rarity)) continue;
|
|
17583
|
+
const rarity = pokemon.rarity;
|
|
17584
|
+
if (rarity === "common") common.push(pokemon.id);
|
|
17585
|
+
else if (rarity === "uncommon") uncommon.push(pokemon.id);
|
|
17586
|
+
else rare.push(pokemon.id);
|
|
17587
|
+
}
|
|
17588
|
+
return {
|
|
17589
|
+
common: Object.freeze(common),
|
|
17590
|
+
uncommon: Object.freeze(uncommon),
|
|
17591
|
+
rare: Object.freeze(rare)
|
|
17592
|
+
};
|
|
17593
|
+
}
|
|
17576
17594
|
function buildTypePools() {
|
|
17577
17595
|
const pools = /* @__PURE__ */ new Map();
|
|
17578
17596
|
for (const pokemon of POKEDEX) {
|
|
@@ -17600,6 +17618,7 @@ function buildTypePools() {
|
|
|
17600
17618
|
return frozen;
|
|
17601
17619
|
}
|
|
17602
17620
|
var TYPE_POOLS = buildTypePools();
|
|
17621
|
+
var ALL_WILD_POOL = buildAllPool();
|
|
17603
17622
|
|
|
17604
17623
|
// src/engine/encounters.ts
|
|
17605
17624
|
function seededRandom(seed) {
|
|
@@ -18578,27 +18597,29 @@ function registerAchievementsTool(server) {
|
|
|
18578
18597
|
|
|
18579
18598
|
// src/gamification/legendary-quests.ts
|
|
18580
18599
|
var LEGENDARY_QUESTS = [
|
|
18600
|
+
// ═══════════════════════════════════════════════════════════
|
|
18601
|
+
// GEN 1 — Kanto Legends
|
|
18602
|
+
// ═══════════════════════════════════════════════════════════
|
|
18581
18603
|
// ── Articuno (#144) — "The Ice Bird of Endurance" ────────
|
|
18582
18604
|
{
|
|
18583
18605
|
pokemonId: 144,
|
|
18584
18606
|
name: "The Ice Bird of Endurance",
|
|
18585
18607
|
steps: [
|
|
18586
18608
|
{
|
|
18587
|
-
description: "Code for
|
|
18588
|
-
condition: { type: "streak", minDays:
|
|
18609
|
+
description: "Code for 14 days (weekends off OK)",
|
|
18610
|
+
condition: { type: "streak", minDays: 14 }
|
|
18589
18611
|
},
|
|
18590
18612
|
{
|
|
18591
18613
|
description: "Catch 3 Water or Ice type Pokemon",
|
|
18592
|
-
// Approximated as pokedex gate; real type-check in getQuestProgress.
|
|
18593
18614
|
condition: { type: "pokedex", minCaught: 3 }
|
|
18594
18615
|
},
|
|
18595
18616
|
{
|
|
18596
|
-
description: "Code for
|
|
18597
|
-
condition: { type: "streak", minDays:
|
|
18617
|
+
description: "Code for 30 days (weekends off OK)",
|
|
18618
|
+
condition: { type: "streak", minDays: 30 }
|
|
18598
18619
|
},
|
|
18599
18620
|
{
|
|
18600
|
-
description: "Reach level
|
|
18601
|
-
condition: { type: "level", minLevel:
|
|
18621
|
+
description: "Reach level 30 on your active Pokemon",
|
|
18622
|
+
condition: { type: "level", minLevel: 30 }
|
|
18602
18623
|
}
|
|
18603
18624
|
]
|
|
18604
18625
|
},
|
|
@@ -18608,20 +18629,20 @@ var LEGENDARY_QUESTS = [
|
|
|
18608
18629
|
name: "The Thunder of Testing",
|
|
18609
18630
|
steps: [
|
|
18610
18631
|
{
|
|
18611
|
-
description: "Pass
|
|
18612
|
-
condition: { type: "counter", counter: "tests_passed", threshold:
|
|
18632
|
+
description: "Pass 50 tests",
|
|
18633
|
+
condition: { type: "counter", counter: "tests_passed", threshold: 50 }
|
|
18613
18634
|
},
|
|
18614
18635
|
{
|
|
18615
|
-
description: "Write
|
|
18616
|
-
condition: { type: "counter", counter: "tests_written", threshold:
|
|
18636
|
+
description: "Write 20 test files",
|
|
18637
|
+
condition: { type: "counter", counter: "tests_written", threshold: 20 }
|
|
18617
18638
|
},
|
|
18618
18639
|
{
|
|
18619
|
-
description: "Pass
|
|
18620
|
-
condition: { type: "counter", counter: "tests_passed", threshold:
|
|
18640
|
+
description: "Pass 200 tests",
|
|
18641
|
+
condition: { type: "counter", counter: "tests_passed", threshold: 200 }
|
|
18621
18642
|
},
|
|
18622
18643
|
{
|
|
18623
|
-
description: "Pass
|
|
18624
|
-
condition: { type: "counter", counter: "tests_passed", threshold:
|
|
18644
|
+
description: "Pass 500 tests lifetime",
|
|
18645
|
+
condition: { type: "counter", counter: "tests_passed", threshold: 500 }
|
|
18625
18646
|
}
|
|
18626
18647
|
]
|
|
18627
18648
|
},
|
|
@@ -18631,20 +18652,20 @@ var LEGENDARY_QUESTS = [
|
|
|
18631
18652
|
name: "The Flame of Debugging",
|
|
18632
18653
|
steps: [
|
|
18633
18654
|
{
|
|
18634
|
-
description: "Fix
|
|
18635
|
-
condition: { type: "counter", counter: "bugs_fixed", threshold:
|
|
18655
|
+
description: "Fix 25 bugs",
|
|
18656
|
+
condition: { type: "counter", counter: "bugs_fixed", threshold: 25 }
|
|
18636
18657
|
},
|
|
18637
18658
|
{
|
|
18638
18659
|
description: "Earn the Blaze Badge",
|
|
18639
18660
|
condition: { type: "badge", badge: "blaze" }
|
|
18640
18661
|
},
|
|
18641
18662
|
{
|
|
18642
|
-
description: "Fix
|
|
18643
|
-
condition: { type: "counter", counter: "bugs_fixed", threshold:
|
|
18663
|
+
description: "Fix 100 bugs",
|
|
18664
|
+
condition: { type: "counter", counter: "bugs_fixed", threshold: 100 }
|
|
18644
18665
|
},
|
|
18645
18666
|
{
|
|
18646
|
-
description: "Fix
|
|
18647
|
-
condition: { type: "counter", counter: "bugs_fixed", threshold:
|
|
18667
|
+
description: "Fix 250 bugs lifetime",
|
|
18668
|
+
condition: { type: "counter", counter: "bugs_fixed", threshold: 250 }
|
|
18648
18669
|
}
|
|
18649
18670
|
]
|
|
18650
18671
|
},
|
|
@@ -18654,20 +18675,20 @@ var LEGENDARY_QUESTS = [
|
|
|
18654
18675
|
name: "The Ultimate Creation",
|
|
18655
18676
|
steps: [
|
|
18656
18677
|
{
|
|
18657
|
-
description: "Catch
|
|
18658
|
-
condition: { type: "pokedex", minCaught:
|
|
18678
|
+
description: "Catch 30 unique Pokemon",
|
|
18679
|
+
condition: { type: "pokedex", minCaught: 30 }
|
|
18659
18680
|
},
|
|
18660
18681
|
{
|
|
18661
|
-
description: "Reach level
|
|
18662
|
-
condition: { type: "level", minLevel:
|
|
18682
|
+
description: "Reach level 40 on any Pokemon",
|
|
18683
|
+
condition: { type: "level", minLevel: 40 }
|
|
18663
18684
|
},
|
|
18664
18685
|
{
|
|
18665
|
-
description: "Catch
|
|
18666
|
-
condition: { type: "pokedex", minCaught:
|
|
18686
|
+
description: "Catch 75 unique Pokemon",
|
|
18687
|
+
condition: { type: "pokedex", minCaught: 75 }
|
|
18667
18688
|
},
|
|
18668
18689
|
{
|
|
18669
|
-
description: "Catch
|
|
18670
|
-
condition: { type: "pokedex", minCaught:
|
|
18690
|
+
description: "Catch 120 unique Pokemon",
|
|
18691
|
+
condition: { type: "pokedex", minCaught: 120 }
|
|
18671
18692
|
}
|
|
18672
18693
|
]
|
|
18673
18694
|
},
|
|
@@ -18677,86 +18698,449 @@ var LEGENDARY_QUESTS = [
|
|
|
18677
18698
|
name: "The Myth",
|
|
18678
18699
|
steps: [
|
|
18679
18700
|
{
|
|
18680
|
-
description: "Code for
|
|
18681
|
-
condition: { type: "streak", minDays:
|
|
18701
|
+
description: "Code for 60 days (weekends off OK)",
|
|
18702
|
+
condition: { type: "streak", minDays: 60 }
|
|
18682
18703
|
},
|
|
18683
18704
|
{
|
|
18684
18705
|
description: "Catch all 3 legendary birds (Articuno, Zapdos, Moltres)",
|
|
18685
|
-
|
|
18686
|
-
// Real check in getQuestProgress verifies specific IDs.
|
|
18687
|
-
condition: { type: "pokedex", minCaught: 148 }
|
|
18706
|
+
condition: { type: "pokedex", minCaught: 50 }
|
|
18688
18707
|
},
|
|
18689
18708
|
{
|
|
18690
18709
|
description: "Catch Mewtwo",
|
|
18691
|
-
|
|
18692
|
-
|
|
18693
|
-
|
|
18710
|
+
condition: { type: "pokedex", minCaught: 60 }
|
|
18711
|
+
},
|
|
18712
|
+
{
|
|
18713
|
+
description: "Code for 180 days (weekends off OK)",
|
|
18714
|
+
condition: { type: "streak", minDays: 180 }
|
|
18715
|
+
}
|
|
18716
|
+
]
|
|
18717
|
+
},
|
|
18718
|
+
// ═══════════════════════════════════════════════════════════
|
|
18719
|
+
// GEN 2 — Johto Legends
|
|
18720
|
+
// ═══════════════════════════════════════════════════════════
|
|
18721
|
+
// ── Lugia (#249) — "The Guardian of the Deep" ───────────
|
|
18722
|
+
{
|
|
18723
|
+
pokemonId: 249,
|
|
18724
|
+
name: "The Guardian of the Deep",
|
|
18725
|
+
steps: [
|
|
18726
|
+
{
|
|
18727
|
+
description: "Pass 100 tests",
|
|
18728
|
+
condition: { type: "counter", counter: "tests_passed", threshold: 100 }
|
|
18729
|
+
},
|
|
18730
|
+
{
|
|
18731
|
+
description: "Build successfully 50 times",
|
|
18732
|
+
condition: { type: "counter", counter: "builds_succeeded", threshold: 50 }
|
|
18733
|
+
},
|
|
18734
|
+
{
|
|
18735
|
+
description: "Catch 40 unique Pokemon",
|
|
18736
|
+
condition: { type: "pokedex", minCaught: 40 }
|
|
18737
|
+
},
|
|
18738
|
+
{
|
|
18739
|
+
description: "Code for 45 days (weekends off OK)",
|
|
18740
|
+
condition: { type: "streak", minDays: 45 }
|
|
18741
|
+
}
|
|
18742
|
+
]
|
|
18743
|
+
},
|
|
18744
|
+
// ── Ho-Oh (#250) — "The Rainbow Phoenix" ────────────────
|
|
18745
|
+
{
|
|
18746
|
+
pokemonId: 250,
|
|
18747
|
+
name: "The Rainbow Phoenix",
|
|
18748
|
+
steps: [
|
|
18749
|
+
{
|
|
18750
|
+
description: "Catch Pokemon of 10 different types",
|
|
18751
|
+
condition: { type: "pokedex", minCaught: 20 }
|
|
18752
|
+
},
|
|
18753
|
+
{
|
|
18754
|
+
description: "Make 100 commits",
|
|
18755
|
+
condition: { type: "counter", counter: "commits", threshold: 100 }
|
|
18756
|
+
},
|
|
18757
|
+
{
|
|
18758
|
+
description: "Reach level 35 on any Pokemon",
|
|
18759
|
+
condition: { type: "level", minLevel: 35 }
|
|
18760
|
+
},
|
|
18761
|
+
{
|
|
18762
|
+
description: "Code for 60 days (weekends off OK)",
|
|
18763
|
+
condition: { type: "streak", minDays: 60 }
|
|
18764
|
+
}
|
|
18765
|
+
]
|
|
18766
|
+
},
|
|
18767
|
+
// ═══════════════════════════════════════════════════════════
|
|
18768
|
+
// GEN 3 — Hoenn Legends
|
|
18769
|
+
// ═══════════════════════════════════════════════════════════
|
|
18770
|
+
// ── Kyogre (#382) — "The Ocean Architect" ───────────────
|
|
18771
|
+
{
|
|
18772
|
+
pokemonId: 382,
|
|
18773
|
+
name: "The Ocean Architect",
|
|
18774
|
+
steps: [
|
|
18775
|
+
{
|
|
18776
|
+
description: "Create 50 files",
|
|
18777
|
+
condition: { type: "counter", counter: "files_created", threshold: 50 }
|
|
18778
|
+
},
|
|
18779
|
+
{
|
|
18780
|
+
description: "Pass 150 tests",
|
|
18781
|
+
condition: { type: "counter", counter: "tests_passed", threshold: 150 }
|
|
18782
|
+
},
|
|
18783
|
+
{
|
|
18784
|
+
description: "Earn the Flow Badge",
|
|
18785
|
+
condition: { type: "badge", badge: "flow" }
|
|
18786
|
+
},
|
|
18787
|
+
{
|
|
18788
|
+
description: "Catch 50 unique Pokemon",
|
|
18789
|
+
condition: { type: "pokedex", minCaught: 50 }
|
|
18790
|
+
}
|
|
18791
|
+
]
|
|
18792
|
+
},
|
|
18793
|
+
// ── Groudon (#383) — "The Continent Builder" ────────────
|
|
18794
|
+
{
|
|
18795
|
+
pokemonId: 383,
|
|
18796
|
+
name: "The Continent Builder",
|
|
18797
|
+
steps: [
|
|
18798
|
+
{
|
|
18799
|
+
description: "Edit 200 files",
|
|
18800
|
+
condition: { type: "counter", counter: "files_edited", threshold: 200 }
|
|
18801
|
+
},
|
|
18802
|
+
{
|
|
18803
|
+
description: "Build successfully 75 times",
|
|
18804
|
+
condition: { type: "counter", counter: "builds_succeeded", threshold: 75 }
|
|
18805
|
+
},
|
|
18806
|
+
{
|
|
18807
|
+
description: "Fix 75 bugs",
|
|
18808
|
+
condition: { type: "counter", counter: "bugs_fixed", threshold: 75 }
|
|
18809
|
+
},
|
|
18810
|
+
{
|
|
18811
|
+
description: "Code for 45 days (weekends off OK)",
|
|
18812
|
+
condition: { type: "streak", minDays: 45 }
|
|
18813
|
+
}
|
|
18814
|
+
]
|
|
18815
|
+
},
|
|
18816
|
+
// ── Rayquaza (#384) — "The Sky Sovereign" ───────────────
|
|
18817
|
+
{
|
|
18818
|
+
pokemonId: 384,
|
|
18819
|
+
name: "The Sky Sovereign",
|
|
18820
|
+
steps: [
|
|
18821
|
+
{
|
|
18822
|
+
description: "Catch both Kyogre and Groudon",
|
|
18823
|
+
condition: { type: "pokedex", minCaught: 60 }
|
|
18824
|
+
},
|
|
18825
|
+
{
|
|
18826
|
+
description: "Make 200 commits",
|
|
18827
|
+
condition: { type: "counter", counter: "commits", threshold: 200 }
|
|
18828
|
+
},
|
|
18829
|
+
{
|
|
18830
|
+
description: "Reach level 45 on any Pokemon",
|
|
18831
|
+
condition: { type: "level", minLevel: 45 }
|
|
18832
|
+
},
|
|
18833
|
+
{
|
|
18834
|
+
description: "Code for 90 days (weekends off OK)",
|
|
18835
|
+
condition: { type: "streak", minDays: 90 }
|
|
18836
|
+
}
|
|
18837
|
+
]
|
|
18838
|
+
},
|
|
18839
|
+
// ═══════════════════════════════════════════════════════════
|
|
18840
|
+
// GEN 4 — Sinnoh Legends
|
|
18841
|
+
// ═══════════════════════════════════════════════════════════
|
|
18842
|
+
// ── Dialga (#483) — "The Temporal Coder" ────────────────
|
|
18843
|
+
{
|
|
18844
|
+
pokemonId: 483,
|
|
18845
|
+
name: "The Temporal Coder",
|
|
18846
|
+
steps: [
|
|
18847
|
+
{
|
|
18848
|
+
description: "Code for 30 days (weekends off OK)",
|
|
18849
|
+
condition: { type: "streak", minDays: 30 }
|
|
18850
|
+
},
|
|
18851
|
+
{
|
|
18852
|
+
description: "Make 150 commits",
|
|
18853
|
+
condition: { type: "counter", counter: "commits", threshold: 150 }
|
|
18854
|
+
},
|
|
18855
|
+
{
|
|
18856
|
+
description: "Catch 60 unique Pokemon",
|
|
18857
|
+
condition: { type: "pokedex", minCaught: 60 }
|
|
18858
|
+
},
|
|
18859
|
+
{
|
|
18860
|
+
description: "Earn the Spark Badge",
|
|
18861
|
+
condition: { type: "badge", badge: "spark" }
|
|
18862
|
+
}
|
|
18863
|
+
]
|
|
18864
|
+
},
|
|
18865
|
+
// ── Palkia (#484) — "The Spatial Engineer" ──────────────
|
|
18866
|
+
{
|
|
18867
|
+
pokemonId: 484,
|
|
18868
|
+
name: "The Spatial Engineer",
|
|
18869
|
+
steps: [
|
|
18870
|
+
{
|
|
18871
|
+
description: "Create 75 files",
|
|
18872
|
+
condition: { type: "counter", counter: "files_created", threshold: 75 }
|
|
18873
|
+
},
|
|
18874
|
+
{
|
|
18875
|
+
description: "Edit 300 files",
|
|
18876
|
+
condition: { type: "counter", counter: "files_edited", threshold: 300 }
|
|
18877
|
+
},
|
|
18878
|
+
{
|
|
18879
|
+
description: "Pass 300 tests",
|
|
18880
|
+
condition: { type: "counter", counter: "tests_passed", threshold: 300 }
|
|
18881
|
+
},
|
|
18882
|
+
{
|
|
18883
|
+
description: "Code for 60 days (weekends off OK)",
|
|
18884
|
+
condition: { type: "streak", minDays: 60 }
|
|
18885
|
+
}
|
|
18886
|
+
]
|
|
18887
|
+
},
|
|
18888
|
+
// ── Giratina (#487) — "The Shadow Refactorer" ───────────
|
|
18889
|
+
{
|
|
18890
|
+
pokemonId: 487,
|
|
18891
|
+
name: "The Shadow Refactorer",
|
|
18892
|
+
steps: [
|
|
18893
|
+
{
|
|
18894
|
+
description: "Catch both Dialga and Palkia",
|
|
18895
|
+
condition: { type: "pokedex", minCaught: 70 }
|
|
18896
|
+
},
|
|
18897
|
+
{
|
|
18898
|
+
description: "Fix 150 bugs",
|
|
18899
|
+
condition: { type: "counter", counter: "bugs_fixed", threshold: 150 }
|
|
18900
|
+
},
|
|
18901
|
+
{
|
|
18902
|
+
description: "Perform 50 lint fixes",
|
|
18903
|
+
condition: { type: "counter", counter: "lint_fixes", threshold: 50 }
|
|
18904
|
+
},
|
|
18905
|
+
{
|
|
18906
|
+
description: "Code for 90 days (weekends off OK)",
|
|
18907
|
+
condition: { type: "streak", minDays: 90 }
|
|
18908
|
+
}
|
|
18909
|
+
]
|
|
18910
|
+
},
|
|
18911
|
+
// ═══════════════════════════════════════════════════════════
|
|
18912
|
+
// GEN 5 — Unova Legends
|
|
18913
|
+
// ═══════════════════════════════════════════════════════════
|
|
18914
|
+
// ── Reshiram (#643) — "The Flame of Truth" ──────────────
|
|
18915
|
+
{
|
|
18916
|
+
pokemonId: 643,
|
|
18917
|
+
name: "The Flame of Truth",
|
|
18918
|
+
steps: [
|
|
18919
|
+
{
|
|
18920
|
+
description: "Write 30 test files",
|
|
18921
|
+
condition: { type: "counter", counter: "tests_written", threshold: 30 }
|
|
18922
|
+
},
|
|
18923
|
+
{
|
|
18924
|
+
description: "Pass 250 tests",
|
|
18925
|
+
condition: { type: "counter", counter: "tests_passed", threshold: 250 }
|
|
18926
|
+
},
|
|
18927
|
+
{
|
|
18928
|
+
description: "Reach level 40 on any Pokemon",
|
|
18929
|
+
condition: { type: "level", minLevel: 40 }
|
|
18930
|
+
},
|
|
18931
|
+
{
|
|
18932
|
+
description: "Code for 60 days (weekends off OK)",
|
|
18933
|
+
condition: { type: "streak", minDays: 60 }
|
|
18934
|
+
}
|
|
18935
|
+
]
|
|
18936
|
+
},
|
|
18937
|
+
// ── Zekrom (#644) — "The Bolt of Ideals" ────────────────
|
|
18938
|
+
{
|
|
18939
|
+
pokemonId: 644,
|
|
18940
|
+
name: "The Bolt of Ideals",
|
|
18941
|
+
steps: [
|
|
18942
|
+
{
|
|
18943
|
+
description: "Make 200 commits",
|
|
18944
|
+
condition: { type: "counter", counter: "commits", threshold: 200 }
|
|
18945
|
+
},
|
|
18946
|
+
{
|
|
18947
|
+
description: "Build successfully 100 times",
|
|
18948
|
+
condition: { type: "counter", counter: "builds_succeeded", threshold: 100 }
|
|
18949
|
+
},
|
|
18950
|
+
{
|
|
18951
|
+
description: "Catch 80 unique Pokemon",
|
|
18952
|
+
condition: { type: "pokedex", minCaught: 80 }
|
|
18953
|
+
},
|
|
18954
|
+
{
|
|
18955
|
+
description: "Code for 60 days (weekends off OK)",
|
|
18956
|
+
condition: { type: "streak", minDays: 60 }
|
|
18957
|
+
}
|
|
18958
|
+
]
|
|
18959
|
+
},
|
|
18960
|
+
// ── Kyurem (#646) — "The Frozen Merger" ─────────────────
|
|
18961
|
+
{
|
|
18962
|
+
pokemonId: 646,
|
|
18963
|
+
name: "The Frozen Merger",
|
|
18964
|
+
steps: [
|
|
18965
|
+
{
|
|
18966
|
+
description: "Catch both Reshiram and Zekrom",
|
|
18967
|
+
condition: { type: "pokedex", minCaught: 90 }
|
|
18968
|
+
},
|
|
18969
|
+
{
|
|
18970
|
+
description: "Earn the Lunar Badge",
|
|
18971
|
+
condition: { type: "badge", badge: "lunar" }
|
|
18972
|
+
},
|
|
18973
|
+
{
|
|
18974
|
+
description: "Reach level 50 on any Pokemon",
|
|
18975
|
+
condition: { type: "level", minLevel: 50 }
|
|
18976
|
+
},
|
|
18977
|
+
{
|
|
18978
|
+
description: "Code for 120 days (weekends off OK)",
|
|
18979
|
+
condition: { type: "streak", minDays: 120 }
|
|
18980
|
+
}
|
|
18981
|
+
]
|
|
18982
|
+
},
|
|
18983
|
+
// ═══════════════════════════════════════════════════════════
|
|
18984
|
+
// GEN 6 — Kalos Legends
|
|
18985
|
+
// ═══════════════════════════════════════════════════════════
|
|
18986
|
+
// ── Xerneas (#716) — "The Tree of Life" ─────────────────
|
|
18987
|
+
{
|
|
18988
|
+
pokemonId: 716,
|
|
18989
|
+
name: "The Tree of Life",
|
|
18990
|
+
steps: [
|
|
18991
|
+
{
|
|
18992
|
+
description: "Create 100 files",
|
|
18993
|
+
condition: { type: "counter", counter: "files_created", threshold: 100 }
|
|
18694
18994
|
},
|
|
18695
18995
|
{
|
|
18696
|
-
description: "
|
|
18697
|
-
condition: { type: "
|
|
18996
|
+
description: "Earn the Growth Badge",
|
|
18997
|
+
condition: { type: "badge", badge: "growth" }
|
|
18998
|
+
},
|
|
18999
|
+
{
|
|
19000
|
+
description: "Catch 70 unique Pokemon",
|
|
19001
|
+
condition: { type: "pokedex", minCaught: 70 }
|
|
19002
|
+
},
|
|
19003
|
+
{
|
|
19004
|
+
description: "Code for 75 days (weekends off OK)",
|
|
19005
|
+
condition: { type: "streak", minDays: 75 }
|
|
19006
|
+
}
|
|
19007
|
+
]
|
|
19008
|
+
},
|
|
19009
|
+
// ── Yveltal (#717) — "The Destruction Debugger" ─────────
|
|
19010
|
+
{
|
|
19011
|
+
pokemonId: 717,
|
|
19012
|
+
name: "The Destruction Debugger",
|
|
19013
|
+
steps: [
|
|
19014
|
+
{
|
|
19015
|
+
description: "Fix 100 bugs",
|
|
19016
|
+
condition: { type: "counter", counter: "bugs_fixed", threshold: 100 }
|
|
19017
|
+
},
|
|
19018
|
+
{
|
|
19019
|
+
description: "Pass 400 tests",
|
|
19020
|
+
condition: { type: "counter", counter: "tests_passed", threshold: 400 }
|
|
19021
|
+
},
|
|
19022
|
+
{
|
|
19023
|
+
description: "Make 250 commits",
|
|
19024
|
+
condition: { type: "counter", counter: "commits", threshold: 250 }
|
|
19025
|
+
},
|
|
19026
|
+
{
|
|
19027
|
+
description: "Code for 75 days (weekends off OK)",
|
|
19028
|
+
condition: { type: "streak", minDays: 75 }
|
|
19029
|
+
}
|
|
19030
|
+
]
|
|
19031
|
+
},
|
|
19032
|
+
// ═══════════════════════════════════════════════════════════
|
|
19033
|
+
// GEN 7 — Alola Legends
|
|
19034
|
+
// ═══════════════════════════════════════════════════════════
|
|
19035
|
+
// ── Solgaleo (#791) — "The Sunlit Deployer" ─────────────
|
|
19036
|
+
{
|
|
19037
|
+
pokemonId: 791,
|
|
19038
|
+
name: "The Sunlit Deployer",
|
|
19039
|
+
steps: [
|
|
19040
|
+
{
|
|
19041
|
+
description: "Build successfully 100 times",
|
|
19042
|
+
condition: { type: "counter", counter: "builds_succeeded", threshold: 100 }
|
|
19043
|
+
},
|
|
19044
|
+
{
|
|
19045
|
+
description: "Make 300 commits",
|
|
19046
|
+
condition: { type: "counter", counter: "commits", threshold: 300 }
|
|
19047
|
+
},
|
|
19048
|
+
{
|
|
19049
|
+
description: "Catch 100 unique Pokemon",
|
|
19050
|
+
condition: { type: "pokedex", minCaught: 100 }
|
|
19051
|
+
},
|
|
19052
|
+
{
|
|
19053
|
+
description: "Code for 90 days (weekends off OK)",
|
|
19054
|
+
condition: { type: "streak", minDays: 90 }
|
|
19055
|
+
}
|
|
19056
|
+
]
|
|
19057
|
+
},
|
|
19058
|
+
// ── Lunala (#792) — "The Moonlit Reviewer" ──────────────
|
|
19059
|
+
{
|
|
19060
|
+
pokemonId: 792,
|
|
19061
|
+
name: "The Moonlit Reviewer",
|
|
19062
|
+
steps: [
|
|
19063
|
+
{
|
|
19064
|
+
description: "Perform 1000 searches",
|
|
19065
|
+
condition: { type: "counter", counter: "searches", threshold: 1e3 }
|
|
19066
|
+
},
|
|
19067
|
+
{
|
|
19068
|
+
description: "Write 50 test files",
|
|
19069
|
+
condition: { type: "counter", counter: "tests_written", threshold: 50 }
|
|
19070
|
+
},
|
|
19071
|
+
{
|
|
19072
|
+
description: "Reach level 50 on any Pokemon",
|
|
19073
|
+
condition: { type: "level", minLevel: 50 }
|
|
19074
|
+
},
|
|
19075
|
+
{
|
|
19076
|
+
description: "Code for 90 days (weekends off OK)",
|
|
19077
|
+
condition: { type: "streak", minDays: 90 }
|
|
19078
|
+
}
|
|
19079
|
+
]
|
|
19080
|
+
},
|
|
19081
|
+
// ═══════════════════════════════════════════════════════════
|
|
19082
|
+
// GEN 8 — Galar Legends
|
|
19083
|
+
// ═══════════════════════════════════════════════════════════
|
|
19084
|
+
// ── Zacian (#888) — "The Crowned Shipper" ───────────────
|
|
19085
|
+
{
|
|
19086
|
+
pokemonId: 888,
|
|
19087
|
+
name: "The Crowned Shipper",
|
|
19088
|
+
steps: [
|
|
19089
|
+
{
|
|
19090
|
+
description: "Make 250 commits",
|
|
19091
|
+
condition: { type: "counter", counter: "commits", threshold: 250 }
|
|
19092
|
+
},
|
|
19093
|
+
{
|
|
19094
|
+
description: "Build successfully 150 times",
|
|
19095
|
+
condition: { type: "counter", counter: "builds_succeeded", threshold: 150 }
|
|
19096
|
+
},
|
|
19097
|
+
{
|
|
19098
|
+
description: "Catch 120 unique Pokemon",
|
|
19099
|
+
condition: { type: "pokedex", minCaught: 120 }
|
|
19100
|
+
},
|
|
19101
|
+
{
|
|
19102
|
+
description: "Code for 120 days (weekends off OK)",
|
|
19103
|
+
condition: { type: "streak", minDays: 120 }
|
|
19104
|
+
}
|
|
19105
|
+
]
|
|
19106
|
+
},
|
|
19107
|
+
// ── Zamazenta (#889) — "The Shield of Stability" ────────
|
|
19108
|
+
{
|
|
19109
|
+
pokemonId: 889,
|
|
19110
|
+
name: "The Shield of Stability",
|
|
19111
|
+
steps: [
|
|
19112
|
+
{
|
|
19113
|
+
description: "Pass 500 tests",
|
|
19114
|
+
condition: { type: "counter", counter: "tests_passed", threshold: 500 }
|
|
19115
|
+
},
|
|
19116
|
+
{
|
|
19117
|
+
description: "Fix 200 bugs",
|
|
19118
|
+
condition: { type: "counter", counter: "bugs_fixed", threshold: 200 }
|
|
19119
|
+
},
|
|
19120
|
+
{
|
|
19121
|
+
description: "Edit 500 files",
|
|
19122
|
+
condition: { type: "counter", counter: "files_edited", threshold: 500 }
|
|
19123
|
+
},
|
|
19124
|
+
{
|
|
19125
|
+
description: "Code for 120 days (weekends off OK)",
|
|
19126
|
+
condition: { type: "streak", minDays: 120 }
|
|
18698
19127
|
}
|
|
18699
19128
|
]
|
|
18700
19129
|
}
|
|
18701
19130
|
];
|
|
18702
|
-
|
|
18703
|
-
|
|
18704
|
-
|
|
18705
|
-
|
|
18706
|
-
|
|
18707
|
-
// Squirtle line
|
|
18708
|
-
54,
|
|
18709
|
-
55,
|
|
18710
|
-
// Psyduck, Golduck
|
|
18711
|
-
60,
|
|
18712
|
-
61,
|
|
18713
|
-
62,
|
|
18714
|
-
// Poliwag line
|
|
18715
|
-
72,
|
|
18716
|
-
73,
|
|
18717
|
-
// Tentacool, Tentacruel
|
|
18718
|
-
79,
|
|
18719
|
-
80,
|
|
18720
|
-
// Slowpoke, Slowbro
|
|
18721
|
-
86,
|
|
18722
|
-
87,
|
|
18723
|
-
// Seel, Dewgong (also Ice)
|
|
18724
|
-
90,
|
|
18725
|
-
91,
|
|
18726
|
-
// Shellder, Cloyster (also Ice)
|
|
18727
|
-
98,
|
|
18728
|
-
99,
|
|
18729
|
-
// Krabby, Kingler
|
|
18730
|
-
116,
|
|
18731
|
-
117,
|
|
18732
|
-
// Horsea, Seadra
|
|
18733
|
-
118,
|
|
18734
|
-
119,
|
|
18735
|
-
// Goldeen, Seaking
|
|
18736
|
-
120,
|
|
18737
|
-
121,
|
|
18738
|
-
// Staryu, Starmie
|
|
18739
|
-
129,
|
|
18740
|
-
130,
|
|
18741
|
-
// Magikarp, Gyarados
|
|
18742
|
-
131,
|
|
18743
|
-
// Lapras (Water/Ice)
|
|
18744
|
-
134,
|
|
18745
|
-
// Vaporeon
|
|
18746
|
-
138,
|
|
18747
|
-
139,
|
|
18748
|
-
// Omanyte, Omastar
|
|
18749
|
-
140,
|
|
18750
|
-
141,
|
|
18751
|
-
// Kabuto, Kabutops
|
|
18752
|
-
// Ice types (not already listed)
|
|
18753
|
-
124,
|
|
18754
|
-
// Jynx (Ice/Psychic)
|
|
18755
|
-
144
|
|
18756
|
-
// Articuno (Ice/Flying)
|
|
18757
|
-
]);
|
|
19131
|
+
function isWaterOrIceType(pokemonId) {
|
|
19132
|
+
const pokemon = POKEMON_BY_ID.get(pokemonId);
|
|
19133
|
+
if (!pokemon) return false;
|
|
19134
|
+
return pokemon.types.some((t) => t === "Water" || t === "Ice");
|
|
19135
|
+
}
|
|
18758
19136
|
var LEGENDARY_BIRD_IDS = [144, 145, 146];
|
|
18759
19137
|
var MEWTWO_ID = 150;
|
|
19138
|
+
var KYOGRE_ID = 382;
|
|
19139
|
+
var GROUDON_ID = 383;
|
|
19140
|
+
var DIALGA_ID = 483;
|
|
19141
|
+
var PALKIA_ID = 484;
|
|
19142
|
+
var RESHIRAM_ID = 643;
|
|
19143
|
+
var ZEKROM_ID = 644;
|
|
18760
19144
|
function getQuestProgress(state) {
|
|
18761
19145
|
return LEGENDARY_QUESTS.map((quest) => {
|
|
18762
19146
|
let stepsCompleted = 0;
|
|
@@ -18776,7 +19160,7 @@ function getQuestProgress(state) {
|
|
|
18776
19160
|
}
|
|
18777
19161
|
function isStepComplete(questPokemonId, stepDescription, condition, state) {
|
|
18778
19162
|
if (questPokemonId === 144 && stepDescription.includes("Water or Ice")) {
|
|
18779
|
-
return
|
|
19163
|
+
return countCaughtByType(state, isWaterOrIceType) >= 3;
|
|
18780
19164
|
}
|
|
18781
19165
|
if (questPokemonId === 151 && stepDescription.includes("legendary birds")) {
|
|
18782
19166
|
return LEGENDARY_BIRD_IDS.every((id) => isPokemonCaught(state, id));
|
|
@@ -18784,16 +19168,25 @@ function isStepComplete(questPokemonId, stepDescription, condition, state) {
|
|
|
18784
19168
|
if (questPokemonId === 151 && stepDescription.includes("Mewtwo")) {
|
|
18785
19169
|
return isPokemonCaught(state, MEWTWO_ID);
|
|
18786
19170
|
}
|
|
19171
|
+
if (questPokemonId === 384 && stepDescription.includes("Kyogre and Groudon")) {
|
|
19172
|
+
return isPokemonCaught(state, KYOGRE_ID) && isPokemonCaught(state, GROUDON_ID);
|
|
19173
|
+
}
|
|
19174
|
+
if (questPokemonId === 487 && stepDescription.includes("Dialga and Palkia")) {
|
|
19175
|
+
return isPokemonCaught(state, DIALGA_ID) && isPokemonCaught(state, PALKIA_ID);
|
|
19176
|
+
}
|
|
19177
|
+
if (questPokemonId === 646 && stepDescription.includes("Reshiram and Zekrom")) {
|
|
19178
|
+
return isPokemonCaught(state, RESHIRAM_ID) && isPokemonCaught(state, ZEKROM_ID);
|
|
19179
|
+
}
|
|
18787
19180
|
return isConditionMet(condition, state);
|
|
18788
19181
|
}
|
|
18789
19182
|
function isPokemonCaught(state, pokemonId) {
|
|
18790
19183
|
const entry = state.pokedex.entries[pokemonId];
|
|
18791
19184
|
return entry !== void 0 && entry.caught;
|
|
18792
19185
|
}
|
|
18793
|
-
function
|
|
19186
|
+
function countCaughtByType(state, typePredicate) {
|
|
18794
19187
|
let count = 0;
|
|
18795
|
-
for (const
|
|
18796
|
-
if (
|
|
19188
|
+
for (const [idStr, entry] of Object.entries(state.pokedex.entries)) {
|
|
19189
|
+
if (entry.caught && typePredicate(Number(idStr))) {
|
|
18797
19190
|
count++;
|
|
18798
19191
|
}
|
|
18799
19192
|
}
|