@malib/gear 1.1.0 → 1.2.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/dist/index.mjs CHANGED
@@ -154,6 +154,8 @@ let GearType = /* @__PURE__ */ function(GearType) {
154
154
  GearType[GearType["breathShooter"] = 1214] = "breathShooter";
155
155
  /** 장검 */
156
156
  GearType[GearType["longSword2"] = 1215] = "longSword2";
157
+ /** 카르타 */
158
+ GearType[GearType["carta"] = 1216] = "carta";
157
159
  /** 소울 슈터 */
158
160
  GearType[GearType["soulShooter"] = 122] = "soulShooter";
159
161
  /** 데스페라도 */
@@ -318,6 +320,8 @@ let GearType = /* @__PURE__ */ function(GearType) {
318
320
  GearType[GearType["machineTransistors"] = 165] = "machineTransistors";
319
321
  /** 모래시계 */
320
322
  GearType[GearType["hourGlass"] = 17237] = "hourGlass";
323
+ /** 마법깃펜 */
324
+ GearType[GearType["magicQuill"] = 1726] = "magicQuill";
321
325
  /** 드래곤 모자 */
322
326
  GearType[GearType["dragonMask"] = 194] = "dragonMask";
323
327
  /** 드래곤 펜던트 */
@@ -392,6 +396,7 @@ let ErrorMessage = /* @__PURE__ */ function(ErrorMessage) {
392
396
  ErrorMessage["Migrate_InvalidGearData"] = "입력 데이터가 유효하지 않습니다.";
393
397
  ErrorMessage["Migrate_UnknownDataVersion"] = "입력 데이터의 버전이 잘못되었습니다.";
394
398
  ErrorMessage["Migrate_DataVersionTooNew"] = "입력 데이터의 버전이 지원하는 버전보다 최신입니다.";
399
+ ErrorMessage["Migrate_RequiresIcon"] = "입력 데이터에 icon 속성이 필요합니다.";
395
400
  ErrorMessage["Migrate_DataPropertyWillBeOverwritten"] = "입력 데이터의 속성이 덮어쓰여집니다. 제거하고 다시 실행해 주세요.";
396
401
  return ErrorMessage;
397
402
  }({});
@@ -505,7 +510,8 @@ function isSubWeapon(type) {
505
510
  if (isShield(type)) return true;
506
511
  switch (type) {
507
512
  case GearType.katara:
508
- case GearType.hourGlass: return true;
513
+ case GearType.hourGlass:
514
+ case GearType.magicQuill: return true;
509
515
  default:
510
516
  if (Math.floor(type / 1e3) === 135) return true;
511
517
  return false;
@@ -1306,10 +1312,10 @@ function _getArmorSpellTrace(gear, type, rate) {
1306
1312
  break;
1307
1313
  }
1308
1314
  }
1309
- if (gear.scrollUpgradeCount === 3) if (gear.req.beginner()) {
1315
+ if (gear.scrollUpgradeCount === 3) if (gear.req.job.beginner()) {
1310
1316
  option.attackPower = 1;
1311
1317
  option.magicPower = 1;
1312
- } else if (gear.req.magician()) option.magicPower = 1;
1318
+ } else if (gear.req.job.magician()) option.magicPower = 1;
1313
1319
  else option.attackPower = 1;
1314
1320
  return {
1315
1321
  name: _createScrollName(rate, _getTypeName(type)),
@@ -1772,7 +1778,7 @@ function _weaponStarforce(gear) {
1772
1778
  const optionTypes = _getJobOptionTypes(gear);
1773
1779
  for (const type of statTypes) if (optionTypes.has(type)) _getStarforceOption(gear)[type] += stat;
1774
1780
  else if (gear.star > 15 && (gear.baseOption[type] > 0 || gear.upgradeOption[type] > 0)) _getStarforceOption(gear)[type] += stat;
1775
- const isMagic = gear.req.magician() || gear.upgradeOption.magicPower > 0;
1781
+ const isMagic = gear.req.job.magician() || gear.upgradeOption.magicPower > 0;
1776
1782
  if (gear.star > 15) {
1777
1783
  _getStarforceOption(gear).attackPower += power;
1778
1784
  if (isMagic) _getStarforceOption(gear).magicPower += power;
@@ -1798,10 +1804,10 @@ function _otherStarforce(gear) {
1798
1804
  _getStarforceOption(gear).magicPower += power;
1799
1805
  if (gear.type === GearType.glove && gear.req.level >= 130) {
1800
1806
  const bonusPower = starforceGloveBonusPower[gear.star];
1801
- if (gear.req.beginner()) {
1807
+ if (gear.req.job.beginner()) {
1802
1808
  _getStarforceOption(gear).attackPower += bonusPower;
1803
1809
  _getStarforceOption(gear).magicPower += bonusPower;
1804
- } else if (gear.req.magician()) _getStarforceOption(gear).magicPower += bonusPower;
1810
+ } else if (gear.req.job.magician()) _getStarforceOption(gear).magicPower += bonusPower;
1805
1811
  else _getStarforceOption(gear).attackPower += bonusPower;
1806
1812
  }
1807
1813
  if (gear.type !== GearType.machineHeart && !isSubWeapon(gear.type)) {
@@ -1819,13 +1825,13 @@ function _otherStarforce(gear) {
1819
1825
  }
1820
1826
  }
1821
1827
  function _getJobOptionTypes(gear) {
1822
- if (gear.req.beginner()) return new Set(statTypes);
1828
+ if (gear.req.job.beginner()) return new Set(statTypes);
1823
1829
  const stats = [];
1824
- if (gear.req.warrior()) stats.push("str", "dex");
1825
- if (gear.req.magician()) stats.push("int", "luk");
1826
- if (gear.req.bowman()) stats.push("dex", "str");
1827
- if (gear.req.thief()) stats.push("luk", "dex");
1828
- if (gear.req.pirate()) stats.push("str", "dex");
1830
+ if (gear.req.job.warrior()) stats.push("str", "dex");
1831
+ if (gear.req.job.magician()) stats.push("int", "luk");
1832
+ if (gear.req.job.bowman()) stats.push("dex", "str");
1833
+ if (gear.req.job.thief()) stats.push("luk", "dex");
1834
+ if (gear.req.job.pirate()) stats.push("str", "dex");
1829
1835
  return new Set(stats);
1830
1836
  }
1831
1837
  function _getValue(data, gear) {
@@ -3484,22 +3490,11 @@ const migrators = {
3484
3490
  1: migrateV1ToV2,
3485
3491
  2: migrateV2ToV3
3486
3492
  };
3487
- /**
3488
- * 입력 장비 정보를 목표 버전으로 마이그레이션합니다.
3489
- * 이 함수가 성공한 이후에는 입력 장비 정보 객체를 사용할 수 없습니다.
3490
- *
3491
- * @param data 마이그레이션할 장비 정보.
3492
- * @param version 목표 버전.
3493
- * @returns 목표 버전으로 마이그레이션된 장비 정보.
3494
- *
3495
- * @throws {@link TypeError}
3496
- * 입력 데이터가 유효하지 않은 경우.
3497
- * 입력 데이터의 버전이 잘못되었거나 지원하는 버전보다 최신인 경우.
3498
- */
3499
3493
  function migrate(data, version = 3) {
3500
- let currentVersion = getVersion(data);
3501
- if (currentVersion === void 0) throw new TypeError(ErrorMessage.Migrate_InvalidGearData);
3502
- if (currentVersion > version) throw new TypeError(ErrorMessage.Migrate_DataVersionTooNew);
3494
+ const dataVersion = getVersion(data);
3495
+ if (dataVersion === void 0) throw new TypeError(ErrorMessage.Migrate_InvalidGearData);
3496
+ if (dataVersion > version) throw new TypeError(ErrorMessage.Migrate_DataVersionTooNew);
3497
+ let currentVersion = dataVersion;
3503
3498
  while (currentVersion < version) {
3504
3499
  if (!(currentVersion in migrators)) throw new TypeError(ErrorMessage.Migrate_UnknownDataVersion);
3505
3500
  data = migrators[currentVersion](data);
@@ -3509,22 +3504,32 @@ function migrate(data, version = 3) {
3509
3504
  }
3510
3505
  function migrateV1ToV2(data) {
3511
3506
  if ("id" in data && data.id !== void 0 || "version" in data && data.version !== void 0) throw new TypeError(ErrorMessage.Migrate_DataPropertyWillBeOverwritten);
3512
- if (!("meta" in data && typeof data.meta === "object" && data.meta !== null && "id" in data.meta && typeof data.meta.id === "number")) throw new TypeError("Assert: id should exist");
3513
- const { meta, ...rest } = data;
3507
+ const { meta, icon, ...rest } = data;
3514
3508
  return {
3515
3509
  ...rest,
3516
3510
  id: meta.id,
3517
- version: 2
3511
+ version: 2,
3512
+ icon: icon ?? "(null)"
3518
3513
  };
3519
3514
  }
3520
3515
  function migrateV2ToV3(data) {
3521
- if ("req" in data && data.req !== void 0 && typeof data.req === "object" && data.req !== null && "class" in data.req && data.req.class !== void 0) {
3522
- if (typeof data.req.class !== "number") throw new TypeError(ErrorMessage.Migrate_InvalidGearData);
3523
- data.req.specJobs = [data.req.class];
3524
- delete data.req.class;
3525
- }
3526
- data.version = 3;
3527
- return data;
3516
+ const { req, ...rest } = data;
3517
+ const { level, levelIncrease, job, class: classCode, gender } = req;
3518
+ let reqJob = void 0;
3519
+ if (job || classCode) reqJob = {
3520
+ class: job,
3521
+ jobs: classCode ? [classCode] : void 0
3522
+ };
3523
+ const newReq = {};
3524
+ if (level !== void 0) newReq.level = level;
3525
+ if (levelIncrease !== void 0) newReq.levelIncrease = levelIncrease;
3526
+ if (reqJob !== void 0) newReq.job = reqJob;
3527
+ if (gender !== void 0) newReq.gender = gender;
3528
+ return {
3529
+ ...rest,
3530
+ version: 3,
3531
+ req: newReq
3532
+ };
3528
3533
  }
3529
3534
  //#endregion
3530
3535
  //#region src/lib/GearAttribute.ts
@@ -3694,64 +3699,95 @@ var GearReq = class {
3694
3699
  return this.data.levelIncrease ?? 0;
3695
3700
  }
3696
3701
  /**
3697
- * 착용 가능 직업 분류 마스크 (전사, 마법사, 궁수, 도적, 해적)
3702
+ * 착용 가능 직업
3698
3703
  */
3699
3704
  get job() {
3700
- return this.data.job ?? 0;
3705
+ return new GearReqJob(this.data.job ?? {});
3706
+ }
3707
+ /**
3708
+ * 착용 가능 성별
3709
+ */
3710
+ get gender() {
3711
+ return this.data.gender;
3712
+ }
3713
+ };
3714
+ /**
3715
+ * 장비 착용 제한 직업
3716
+ */
3717
+ var GearReqJob = class {
3718
+ /**
3719
+ * 장비 착용 제한 직업 정보
3720
+ */
3721
+ data;
3722
+ /**
3723
+ * 장비 착용 제한 직업 정보를 참조하는 장비 착용 제한 직업 인스턴스를 생성합니다.
3724
+ */
3725
+ constructor(data) {
3726
+ this.data = data;
3727
+ }
3728
+ /**
3729
+ * 착용 가능 전직 계열 비트마스크 (전사, 마법사, 궁수, 도적, 해적)
3730
+ */
3731
+ get class() {
3732
+ return this.data.class ?? 0;
3701
3733
  }
3702
3734
  /**
3703
3735
  * 착용 가능 직업 코드 목록
3736
+ *
3737
+ * 차수 무관한 직업 코드 목록입니다.
3704
3738
  */
3705
- get specJobs() {
3706
- return this.data.specJobs ?? [];
3739
+ get jobs() {
3740
+ return this.data.jobs ?? [];
3707
3741
  }
3708
3742
  /**
3709
- * 착용 가능 성별
3743
+ * 착용 가능 세부 직업 코드 목록
3744
+ *
3745
+ * 차수를 고려한 직업 코드 목록입니다.
3710
3746
  */
3711
- get gender() {
3712
- return this.data.gender;
3747
+ get fullJobs() {
3748
+ return this.data.fullJobs ?? [];
3713
3749
  }
3714
3750
  /**
3715
3751
  * 초보자 착용 가능 여부를 계산합니다.
3716
3752
  * @returns 착용할 수 있을 경우 `true`; 아닐 경우 `false`.
3717
3753
  */
3718
3754
  beginner() {
3719
- return this.job <= 0;
3755
+ return this.class <= 0;
3720
3756
  }
3721
3757
  /**
3722
3758
  * 전사 착용 가능 여부를 계산합니다.
3723
3759
  * @returns 착용할 수 있을 경우 `true`; 아닐 경우 `false`.
3724
3760
  */
3725
3761
  warrior() {
3726
- return this.job === 0 || (this.job & 1) != 0;
3762
+ return this.class === 0 || (this.class & 1) != 0;
3727
3763
  }
3728
3764
  /**
3729
3765
  * 마법사 착용 가능 여부를 계산합니다.
3730
3766
  * @returns 착용할 수 있을 경우 `true`; 아닐 경우 `false`.
3731
3767
  */
3732
3768
  magician() {
3733
- return this.job === 0 || (this.job & 2) != 0;
3769
+ return this.class === 0 || (this.class & 2) != 0;
3734
3770
  }
3735
3771
  /**
3736
3772
  * 궁수 착용 가능 여부를 계산합니다.
3737
3773
  * @returns 착용할 수 있을 경우 `true`; 아닐 경우 `false`.
3738
3774
  */
3739
3775
  bowman() {
3740
- return this.job === 0 || (this.job & 4) != 0;
3776
+ return this.class === 0 || (this.class & 4) != 0;
3741
3777
  }
3742
3778
  /**
3743
3779
  * 도적 착용 가능 여부를 계산합니다.
3744
3780
  * @returns 착용할 수 있을 경우 `true`; 아닐 경우 `false`.
3745
3781
  */
3746
3782
  thief() {
3747
- return this.job === 0 || (this.job & 8) != 0;
3783
+ return this.class === 0 || (this.class & 8) != 0;
3748
3784
  }
3749
3785
  /**
3750
3786
  * 해적 착용 가능 여부를 계산합니다.
3751
3787
  * @returns 착용할 수 있을 경우 `true`; 아닐 경우 `false`.
3752
3788
  */
3753
3789
  pirate() {
3754
- return this.job === 0 || (this.job & 16) != 0;
3790
+ return this.class === 0 || (this.class & 16) != 0;
3755
3791
  }
3756
3792
  };
3757
3793
  //#endregion
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@malib/gear",
3
- "version": "1.1.0",
3
+ "version": "1.2.1",
4
4
  "description": "MapleStory gear logic simulator",
5
5
  "repository": {
6
6
  "type": "git",
@@ -14,9 +14,11 @@
14
14
  "main": "dist/index.mjs",
15
15
  "types": "dist/index.d.mts",
16
16
  "devDependencies": {
17
+ "@malib/gearV1": "npm:@malib/gear@1.0.0-next.10",
18
+ "@malib/gearV2": "npm:@malib/gear@1.0.0-next.15",
17
19
  "tsdown": "^0.21.0",
18
20
  "typescript": "^5.9.3",
19
- "vitest": "^3.2.4",
21
+ "vitest": "^4.0.18",
20
22
  "@repo/typescript-config": "0.0.0"
21
23
  },
22
24
  "scripts": {