@xforge-dev/forge-kit 0.24.0 → 0.24.1
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/README.md +2 -2
- package/dist/legion.d.ts +9 -18
- package/dist/legion.js +15 -40
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -133,10 +133,10 @@ the lowercased name without spaces, so a stored board never holds names.
|
|
|
133
133
|
|
|
134
134
|
v.272 removes the board. The points model sits beside it (the board stays for app versions still reading it):
|
|
135
135
|
`legionPoints` (the automatic raid's ranks, B 1 … SSS 5, as many members as the Legion rank holds), stat levels
|
|
136
|
-
(`LegionStats`, one point a level,
|
|
136
|
+
(`LegionStats`, one point a level, what a grid square was: same values, caps 15 inner and 40 outer),
|
|
137
137
|
`allocationProblem`, `statTotals`, `suggestStats`, the two highest event blocks (`appliedEventBlocks`), 10 named
|
|
138
138
|
presets (`SharedPoints`, stored under `points` in the shared row so an older board write leaves it alone) and the 5th
|
|
139
|
-
Champion slot (`championSlotsOpen`).
|
|
139
|
+
Champion slot (`championSlotsOpen`).
|
|
140
140
|
|
|
141
141
|
## Exports
|
|
142
142
|
|
package/dist/legion.d.ts
CHANGED
|
@@ -166,9 +166,9 @@ export declare function sharedBoardFrom(raw: unknown): SharedBoard | null;
|
|
|
166
166
|
export declare function crystalsFrom(raw: unknown): ArtifactCrystal[];
|
|
167
167
|
/** The Legion's 16 stats, keyed as the grid's areas were. */
|
|
168
168
|
export type LegionStatKey = GridKey;
|
|
169
|
-
/** Basic stats
|
|
169
|
+
/** Basic stats: the board's inner areas (the patch notes' order). */
|
|
170
170
|
export declare const BASIC_STATS: readonly ["str", "dex", "int", "luk", "att", "matt", "hp", "mp"];
|
|
171
|
-
/** Expanded stats
|
|
171
|
+
/** Expanded stats: the board's outer areas (the patch notes' order). */
|
|
172
172
|
export declare const EXPANDED_STATS: readonly ["critDamage", "boss", "ied", "critRate", "buffDuration", "normal", "exp", "statusResist"];
|
|
173
173
|
export type ExpandedStat = (typeof EXPANDED_STATS)[number];
|
|
174
174
|
export declare const LEGION_STATS: readonly GridKey[];
|
|
@@ -190,24 +190,15 @@ export declare const LEGION_LEVEL_RANKS: readonly LegionLevelRank[];
|
|
|
190
190
|
export declare function legionLevelRank(level: number): LegionLevelRank | null;
|
|
191
191
|
/** Members the automatic Legion Raid takes at this Legion level (Nameless I's 9 below it). */
|
|
192
192
|
export declare const raidMembers: (level: number) => number;
|
|
193
|
-
/**
|
|
194
|
-
export declare const STAT_MAX_LEVEL: Record<GridKey, number>;
|
|
195
|
-
/** The expanded stats' shared level cap by Legion level (the guide's 유니온 레벨별 확장 스탯 최대 레벨). */
|
|
196
|
-
export declare const EXPANDED_CAPS: readonly {
|
|
197
|
-
level: number;
|
|
198
|
-
cap: number;
|
|
199
|
-
}[];
|
|
200
|
-
/** The expanded stats' level cap at this Legion level: 0 below 2,000. */
|
|
201
|
-
export declare function expandedCap(legionLevel: number): number;
|
|
202
|
-
/** What one level of each stat gives. */
|
|
193
|
+
/** What one level of each stat gives: a grid square's value. */
|
|
203
194
|
export declare const STAT_PER_LEVEL: Record<GridKey, number>;
|
|
204
|
-
/**
|
|
205
|
-
export declare const
|
|
195
|
+
/** Each stat's highest level: its grid area's size. */
|
|
196
|
+
export declare const STAT_MAX_LEVEL: Record<GridKey, number>;
|
|
206
197
|
/** Stat levels, one per point: absent or 0 when nothing is spent. */
|
|
207
198
|
export type LegionStats = Partial<Record<GridKey, number>>;
|
|
208
199
|
export declare const isExpandedStat: (k: GridKey) => k is ExpandedStat;
|
|
209
|
-
/** A stat's level cap at this Legion level:
|
|
210
|
-
export declare const statCap: (k: GridKey,
|
|
200
|
+
/** A stat's level cap at this Legion level: its grid area's size at every Legion level, as the board had it. */
|
|
201
|
+
export declare const statCap: (k: GridKey, _legionLevel: number) => number;
|
|
211
202
|
/** Whether a stat is open at this Legion level. */
|
|
212
203
|
export declare const statUnlocked: (k: GridKey, legionLevel: number) => boolean;
|
|
213
204
|
/** One member as the points model reads it: `rank` null below B (no points, no effect). */
|
|
@@ -222,8 +213,8 @@ export type PointsMember = {
|
|
|
222
213
|
export declare function raidComposition<M extends PointsMember>(members: readonly M[], legionLevel: number): M[];
|
|
223
214
|
/** The two event blocks that apply: the highest values among those owned. */
|
|
224
215
|
export declare function appliedEventBlocks(owned: readonly EventBlock[]): EventBlock[];
|
|
225
|
-
/** Legion Points to spend: the
|
|
226
|
-
export declare function legionPoints(members: readonly PointsMember[], legionLevel: number
|
|
216
|
+
/** Legion Points to spend: the ranks of the members the raid counts. Event blocks add ATT, not points. */
|
|
217
|
+
export declare function legionPoints(members: readonly PointsMember[], legionLevel: number): number;
|
|
227
218
|
/** Points the stat levels spend. */
|
|
228
219
|
export declare const pointsSpent: (stats: LegionStats) => number;
|
|
229
220
|
/** What each stat gives at its level (only stats with a level). */
|
package/dist/legion.js
CHANGED
|
@@ -195,9 +195,9 @@ export function crystalsFrom(raw) {
|
|
|
195
195
|
return { level, lines };
|
|
196
196
|
});
|
|
197
197
|
}
|
|
198
|
-
/** Basic stats
|
|
198
|
+
/** Basic stats: the board's inner areas (the patch notes' order). */
|
|
199
199
|
export const BASIC_STATS = ['str', 'dex', 'int', 'luk', 'att', 'matt', 'hp', 'mp'];
|
|
200
|
-
/** Expanded stats
|
|
200
|
+
/** Expanded stats: the board's outer areas (the patch notes' order). */
|
|
201
201
|
export const EXPANDED_STATS = [
|
|
202
202
|
'critDamage', 'boss', 'ied', 'critRate', 'buffDuration', 'normal', 'exp', 'statusResist',
|
|
203
203
|
];
|
|
@@ -226,37 +226,16 @@ export function legionLevelRank(level) {
|
|
|
226
226
|
}
|
|
227
227
|
/** Members the automatic Legion Raid takes at this Legion level (Nameless I's 9 below it). */
|
|
228
228
|
export const raidMembers = (level) => (legionLevelRank(level) ?? LEGION_LEVEL_RANKS[0]).members;
|
|
229
|
-
//
|
|
230
|
-
//
|
|
231
|
-
//
|
|
232
|
-
|
|
233
|
-
/** Each stat's highest level. */
|
|
234
|
-
export const STAT_MAX_LEVEL = Object.fromEntries(GRID_KEYS.map((k) => [k, gridMax(k)]));
|
|
235
|
-
/** The expanded stats' shared level cap by Legion level (the guide's 유니온 레벨별 확장 스탯 최대 레벨). */
|
|
236
|
-
export const EXPANDED_CAPS = [
|
|
237
|
-
{ level: 2000, cap: 5 }, { level: 3000, cap: 10 }, { level: 4000, cap: 20 }, { level: 5000, cap: 30 }, { level: 6000, cap: 40 },
|
|
238
|
-
];
|
|
239
|
-
/** The expanded stats' level cap at this Legion level: 0 below 2,000. */
|
|
240
|
-
export function expandedCap(legionLevel) {
|
|
241
|
-
let cap = 0;
|
|
242
|
-
for (const c of EXPANDED_CAPS)
|
|
243
|
-
if (legionLevel >= c.level)
|
|
244
|
-
cap = c.cap;
|
|
245
|
-
return cap;
|
|
246
|
-
}
|
|
247
|
-
// ┌─ ASSUMED VALUES ────────────────────────────────────────────────────────────────────────────────────────────────┐
|
|
248
|
-
// │ Not in the v.272 notes nor any KMS source found: what a stat level gives. Each is taken as one old grid square │
|
|
249
|
-
// │ (KMS says the stats are "the same types as the old occupation effects", and the caps and 440 total match the │
|
|
250
|
-
// │ board). Nor whether event blocks give points: taken as none (the notes only say they apply automatically and │
|
|
251
|
-
// │ don't count as members). Change them here only; everything below reads them. │
|
|
252
|
-
// └─────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
|
|
253
|
-
/** What one level of each stat gives. */
|
|
229
|
+
// The rules are the board's, without the board: a stat level is what a grid square was (same value per level, the
|
|
230
|
+
// same caps: inner stats 15, outer stats 40, open from the start as every area was), and only the members the raid
|
|
231
|
+
// counts (the top members by Legion level, as the board's slots were) give points and their effects.
|
|
232
|
+
/** What one level of each stat gives: a grid square's value. */
|
|
254
233
|
export const STAT_PER_LEVEL = { ...GRID_PER_SQUARE };
|
|
255
|
-
/**
|
|
256
|
-
export const
|
|
234
|
+
/** Each stat's highest level: its grid area's size. */
|
|
235
|
+
export const STAT_MAX_LEVEL = Object.fromEntries(GRID_KEYS.map((k) => [k, gridMax(k)]));
|
|
257
236
|
export const isExpandedStat = (k) => EXPANDED_STATS.includes(k);
|
|
258
|
-
/** A stat's level cap at this Legion level:
|
|
259
|
-
export const statCap = (k,
|
|
237
|
+
/** A stat's level cap at this Legion level: its grid area's size at every Legion level, as the board had it. */
|
|
238
|
+
export const statCap = (k, _legionLevel) => STAT_MAX_LEVEL[k];
|
|
260
239
|
/** Whether a stat is open at this Legion level. */
|
|
261
240
|
export const statUnlocked = (k, legionLevel) => statCap(k, legionLevel) > 0;
|
|
262
241
|
/**
|
|
@@ -270,10 +249,9 @@ export function raidComposition(members, legionLevel) {
|
|
|
270
249
|
export function appliedEventBlocks(owned) {
|
|
271
250
|
return [...owned].sort((a, b) => b.value - a.value).slice(0, MAX_EVENT_BLOCKS);
|
|
272
251
|
}
|
|
273
|
-
/** Legion Points to spend: the
|
|
274
|
-
export function legionPoints(members, legionLevel
|
|
275
|
-
return raidComposition(members, legionLevel).reduce((t, m) => t + RANK_POINTS[m.rank], 0)
|
|
276
|
-
+ appliedEventBlocks(owned).reduce((t, b) => t + eventBlockPoints(b), 0);
|
|
252
|
+
/** Legion Points to spend: the ranks of the members the raid counts. Event blocks add ATT, not points. */
|
|
253
|
+
export function legionPoints(members, legionLevel) {
|
|
254
|
+
return raidComposition(members, legionLevel).reduce((t, m) => t + RANK_POINTS[m.rank], 0);
|
|
277
255
|
}
|
|
278
256
|
/** Points the stat levels spend. */
|
|
279
257
|
export const pointsSpent = (stats) => Object.values(stats).reduce((t, n) => t + (n ?? 0), 0);
|
|
@@ -292,11 +270,8 @@ export function allocationProblem(a) {
|
|
|
292
270
|
if (!n)
|
|
293
271
|
continue;
|
|
294
272
|
const cap = statCap(k, a.legionLevel);
|
|
295
|
-
if (n > cap)
|
|
296
|
-
|
|
297
|
-
return `${STAT_LABELS[k]} opens at Legion level ${EXPANDED_CAPS[0].level.toLocaleString('en-US')}.`;
|
|
298
|
-
return `${STAT_LABELS[k]} goes up to level ${cap}${cap < STAT_MAX_LEVEL[k] ? ' at this Legion level' : ''}.`;
|
|
299
|
-
}
|
|
273
|
+
if (n > cap)
|
|
274
|
+
return `${STAT_LABELS[k]} goes up to level ${cap}.`;
|
|
300
275
|
}
|
|
301
276
|
const spent = pointsSpent(a.stats);
|
|
302
277
|
if (spent > a.points)
|