@rpg-engine/long-bow 0.8.197 → 0.8.198

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.
@@ -15,7 +15,7 @@ import { camelCase, debounce } from 'lodash-es';
15
15
  import { observer } from 'mobx-react-lite';
16
16
  import { AiFillFilter, AiOutlineFilter, AiFillCaretRight } from 'react-icons/ai';
17
17
  import { HexColorPicker } from 'react-colorful';
18
- import { Clock } from 'pixelarticons/react/Clock';
18
+ import { DateTime } from 'pixelarticons/react/DateTime';
19
19
  import { Settings2 } from 'pixelarticons/react/Settings2';
20
20
  import { ShoppingBag } from 'pixelarticons/react/ShoppingBag';
21
21
  import { ShoppingCart } from 'pixelarticons/react/ShoppingCart';
@@ -27,10 +27,9 @@ import { Search } from 'pixelarticons/react/Search';
27
27
  import { Delete } from 'pixelarticons/react/Delete';
28
28
  import 'rpgui/rpgui.css';
29
29
  import 'rpgui/rpgui.min.js';
30
- import { Coins } from 'pixelarticons/react/Coins';
31
- import { Box } from 'pixelarticons/react/Box';
32
30
  import { Crown } from 'pixelarticons/react/Crown';
33
31
  import { Gift } from 'pixelarticons/react/Gift';
32
+ import { Package } from 'pixelarticons/react/Package';
34
33
  import capitalize from 'lodash-es/capitalize';
35
34
 
36
35
  function _arrayLikeToArray(r, a) {
@@ -631,7 +630,9 @@ var ButtonContainer = /*#__PURE__*/styled.button.withConfig({
631
630
  })(["height:45px;font-size:", ";"], uiFonts.size.small);
632
631
 
633
632
  var NO_IMAGE_SPRITE_KEY = 'others/no-image.png';
633
+ var atlasSpriteAliases = /*#__PURE__*/new Map([['mysticstaff', 'staffs/mystic-lightning-staff.png'], ['silverarrow', 'ranged-weapons/silvermoon-arrow.png']]);
634
634
  var atlasBaseNameLookupCache = /*#__PURE__*/new WeakMap();
635
+ var atlasNormalizedNameLookupCache = /*#__PURE__*/new WeakMap();
635
636
  var getBaseName = function getBaseName(spriteKey) {
636
637
  var normalizedKey = spriteKey.trim();
637
638
  if (!normalizedKey) {
@@ -643,6 +644,13 @@ var getBaseName = function getBaseName(spriteKey) {
643
644
  }
644
645
  return fileName.replace(/\.png$/, '');
645
646
  };
647
+ var normalizeBaseName = function normalizeBaseName(spriteKey) {
648
+ var baseName = getBaseName(spriteKey);
649
+ if (!baseName) {
650
+ return null;
651
+ }
652
+ return baseName.replace(/([a-z0-9])([A-Z])/g, '$1-$2').replace(/[^a-zA-Z0-9]+/g, '').toLowerCase();
653
+ };
646
654
  var getAtlasBaseNameLookup = function getAtlasBaseNameLookup(atlasJSON) {
647
655
  var _atlasJSON$frames;
648
656
  if (!atlasJSON || typeof atlasJSON !== 'object') {
@@ -663,8 +671,28 @@ var getAtlasBaseNameLookup = function getAtlasBaseNameLookup(atlasJSON) {
663
671
  atlasBaseNameLookupCache.set(atlasJSON, lookup);
664
672
  return lookup;
665
673
  };
674
+ var getAtlasNormalizedNameLookup = function getAtlasNormalizedNameLookup(atlasJSON) {
675
+ var _atlasJSON$frames2;
676
+ if (!atlasJSON || typeof atlasJSON !== 'object') {
677
+ return new Map();
678
+ }
679
+ var cachedLookup = atlasNormalizedNameLookupCache.get(atlasJSON);
680
+ if (cachedLookup) {
681
+ return cachedLookup;
682
+ }
683
+ var frames = (_atlasJSON$frames2 = atlasJSON == null ? void 0 : atlasJSON.frames) != null ? _atlasJSON$frames2 : {};
684
+ var lookup = new Map();
685
+ Object.keys(frames).forEach(function (frameKey) {
686
+ var normalizedBaseName = normalizeBaseName(frameKey);
687
+ if (normalizedBaseName && !lookup.has(normalizedBaseName)) {
688
+ lookup.set(normalizedBaseName, frameKey);
689
+ }
690
+ });
691
+ atlasNormalizedNameLookupCache.set(atlasJSON, lookup);
692
+ return lookup;
693
+ };
666
694
  var resolveAtlasSpriteKey = function resolveAtlasSpriteKey(atlasJSON, spriteKey) {
667
- var _getAtlasBaseNameLook;
695
+ var _getAtlasNormalizedNa;
668
696
  if (!spriteKey) {
669
697
  return null;
670
698
  }
@@ -687,7 +715,19 @@ var resolveAtlasSpriteKey = function resolveAtlasSpriteKey(atlasJSON, spriteKey)
687
715
  if (!baseName) {
688
716
  return null;
689
717
  }
690
- return (_getAtlasBaseNameLook = getAtlasBaseNameLookup(atlasJSON).get(baseName)) != null ? _getAtlasBaseNameLook : null;
718
+ var directBaseMatch = getAtlasBaseNameLookup(atlasJSON).get(baseName);
719
+ if (directBaseMatch) {
720
+ return directBaseMatch;
721
+ }
722
+ var normalizedBaseName = normalizeBaseName(normalizedKey);
723
+ if (!normalizedBaseName) {
724
+ return null;
725
+ }
726
+ var aliasedSpriteKey = atlasSpriteAliases.get(normalizedBaseName);
727
+ if (aliasedSpriteKey && frames[aliasedSpriteKey]) {
728
+ return aliasedSpriteKey;
729
+ }
730
+ return (_getAtlasNormalizedNa = getAtlasNormalizedNameLookup(atlasJSON).get(normalizedBaseName)) != null ? _getAtlasNormalizedNa : null;
691
731
  };
692
732
 
693
733
  var toUppercaseHexColor = function toUppercaseHexColor(color) {
@@ -45126,7 +45166,9 @@ var GroupedRowContainer = function GroupedRowContainer(_ref) {
45126
45166
  var mainRow = _ref.mainRow,
45127
45167
  subRows = _ref.subRows,
45128
45168
  _ref$badgeLabel = _ref.badgeLabel,
45129
- badgeLabel = _ref$badgeLabel === void 0 ? 'offers' : _ref$badgeLabel;
45169
+ badgeLabel = _ref$badgeLabel === void 0 ? 'offers' : _ref$badgeLabel,
45170
+ _ref$metaRightInset = _ref.metaRightInset,
45171
+ metaRightInset = _ref$metaRightInset === void 0 ? 120 : _ref$metaRightInset;
45130
45172
  var _useState = useState(false),
45131
45173
  expanded = _useState[0],
45132
45174
  setExpanded = _useState[1];
@@ -45139,7 +45181,9 @@ var GroupedRowContainer = function GroupedRowContainer(_ref) {
45139
45181
  return !e;
45140
45182
  });
45141
45183
  } : undefined
45142
- }, mainRow, hasMultiple && React.createElement(GroupMeta, null, React.createElement(OfferBadge, null, totalCount, " ", badgeLabel), React.createElement(Chevron, {
45184
+ }, mainRow, hasMultiple && React.createElement(GroupMeta, {
45185
+ "$rightInset": metaRightInset
45186
+ }, React.createElement(OfferBadge, null, totalCount, " ", badgeLabel), React.createElement(Chevron, {
45143
45187
  "$expanded": expanded
45144
45188
  }, "\u25B8"))), expanded && React.createElement(SubRows, null, subRows));
45145
45189
  };
@@ -45157,7 +45201,10 @@ var GroupHeader = /*#__PURE__*/styled.div.withConfig({
45157
45201
  var GroupMeta = /*#__PURE__*/styled.div.withConfig({
45158
45202
  displayName: "GroupedRowContainer__GroupMeta",
45159
45203
  componentId: "sc-12q03tq-2"
45160
- })(["position:absolute;right:100px;top:50%;transform:translateY(-50%);display:flex;align-items:center;gap:6px;pointer-events:none;"]);
45204
+ })(["position:absolute;right:", ";top:50%;transform:translateY(-50%);display:flex;align-items:center;gap:4px;padding-left:10px;background:linear-gradient(to left,rgba(25,23,23,0.85),rgba(25,23,23,0));pointer-events:none;z-index:1;"], function (_ref3) {
45205
+ var $rightInset = _ref3.$rightInset;
45206
+ return $rightInset + "px";
45207
+ });
45161
45208
  var OfferBadge = /*#__PURE__*/styled.span.withConfig({
45162
45209
  displayName: "GroupedRowContainer__OfferBadge",
45163
45210
  componentId: "sc-12q03tq-3"
@@ -45165,8 +45212,8 @@ var OfferBadge = /*#__PURE__*/styled.span.withConfig({
45165
45212
  var Chevron = /*#__PURE__*/styled.span.withConfig({
45166
45213
  displayName: "GroupedRowContainer__Chevron",
45167
45214
  componentId: "sc-12q03tq-4"
45168
- })(["display:inline-block;font-size:0.7rem;color:rgba(255,255,255,0.4);transition:transform 0.2s ease;transform:rotate(", ");"], function (_ref3) {
45169
- var $expanded = _ref3.$expanded;
45215
+ })(["display:inline-block;font-size:0.7rem;color:rgba(255,255,255,0.4);transition:transform 0.2s ease;transform:rotate(", ");"], function (_ref4) {
45216
+ var $expanded = _ref4.$expanded;
45170
45217
  return $expanded ? '90deg' : '0deg';
45171
45218
  });
45172
45219
  var SubRows = /*#__PURE__*/styled.div.withConfig({
@@ -45491,7 +45538,8 @@ var GroupedBuyOrderRow = function GroupedBuyOrderRow(_ref2) {
45491
45538
  return React.createElement(GroupedRowContainer, {
45492
45539
  mainRow: makeRow(bestOrder),
45493
45540
  subRows: otherOrders.map(makeRow),
45494
- badgeLabel: "requests"
45541
+ badgeLabel: "requests",
45542
+ metaRightInset: 156
45495
45543
  });
45496
45544
  };
45497
45545
  // ── Styled components matching MarketplaceRows layout ──
@@ -45957,7 +46005,7 @@ var MarketplaceRows = function MarketplaceRows(_ref) {
45957
46005
  spriteKey: "others/definya-coin.png",
45958
46006
  imgScale: 1
45959
46007
  }))), React.createElement(DCPrice, null, formatDCAmount(dcEquivalentPrice)))))), React.createElement(ActionSection$1, null, React.createElement(CTAButton, {
45960
- icon: onMarketPlaceItemBuy ? React.createElement(Coins, {
46008
+ icon: onMarketPlaceItemBuy ? React.createElement(Wallet, {
45961
46009
  width: 18,
45962
46010
  height: 18
45963
46011
  }) : React.createElement(Delete, {
@@ -46009,7 +46057,8 @@ var GroupedMarketplaceRow = function GroupedMarketplaceRow(_ref2) {
46009
46057
  return React.createElement(GroupedRowContainer, {
46010
46058
  mainRow: makeRow(bestListing),
46011
46059
  subRows: otherListings.map(makeRow),
46012
- badgeLabel: "offers"
46060
+ badgeLabel: "offers",
46061
+ metaRightInset: 132
46013
46062
  });
46014
46063
  };
46015
46064
  var ItemSection$1 = /*#__PURE__*/styled.div.withConfig({
@@ -46550,7 +46599,7 @@ var WrapperContainer$1 = /*#__PURE__*/styled.div.withConfig({
46550
46599
  var ItemComponentScrollWrapper$1 = /*#__PURE__*/styled.div.withConfig({
46551
46600
  displayName: "BuyPanel__ItemComponentScrollWrapper",
46552
46601
  componentId: "sc-1si8t7i-7"
46553
- })(["overflow-y:scroll;overflow-x:hidden;height:390px;width:95%;margin:1rem auto 0 auto;background:rgba(0,0,0,0.2);border:1px solid rgba(255,255,255,0.05);border-radius:4px;@media (max-width:950px){height:250px;}"]);
46602
+ })(["display:flex;flex-direction:column;overflow-y:auto;overflow-x:hidden;max-height:390px;min-height:120px;width:95%;margin:1rem auto 0 auto;background:rgba(0,0,0,0.2);border:1px solid rgba(255,255,255,0.05);border-radius:4px;@media (max-width:950px){max-height:250px;}"]);
46554
46603
  var MarketSection = /*#__PURE__*/styled.div.withConfig({
46555
46604
  displayName: "BuyPanel__MarketSection",
46556
46605
  componentId: "sc-1si8t7i-8"
@@ -46974,7 +47023,7 @@ var ManagmentPanel = function ManagmentPanel(_ref) {
46974
47023
  })), React.createElement(BalanceAmount$1, {
46975
47024
  "$disabled": false
46976
47025
  }, dcBalance), React.createElement(BalanceCurrencyLabel, null, "DC")), React.createElement(SmallCTAButton, {
46977
- icon: React.createElement(Coins, {
47026
+ icon: React.createElement(Wallet, {
46978
47027
  width: 18,
46979
47028
  height: 18
46980
47029
  }),
@@ -48189,7 +48238,7 @@ var Marketplace = function Marketplace(props) {
48189
48238
  }, {
48190
48239
  id: 'history',
48191
48240
  label: 'History',
48192
- icon: React.createElement(Clock, {
48241
+ icon: React.createElement(DateTime, {
48193
48242
  width: 18,
48194
48243
  height: 18
48195
48244
  })
@@ -48368,7 +48417,7 @@ var CharacterMarketplaceRows = function CharacterMarketplaceRows(_ref) {
48368
48417
  spriteKey: "others/definya-coin.png",
48369
48418
  imgScale: 1
48370
48419
  })), React.createElement(DCPrice$2, null, formatDCAmount(price))), isBeingBought && React.createElement(PendingBadge$1, null, "Sale Pending"))), React.createElement(ActionSection$2, null, React.createElement(CTAButton, {
48371
- icon: onCharacterBuy ? React.createElement(Coins, {
48420
+ icon: onCharacterBuy ? React.createElement(Wallet, {
48372
48421
  width: 18,
48373
48422
  height: 18
48374
48423
  }) : undefined,
@@ -49832,146 +49881,150 @@ var COMBAT_COLOR = '#C5283D';
49832
49881
  var CRAFTING_COLOR = '#597DCE';
49833
49882
  var ATTRIBUTE_COLOR = '#6833A3';
49834
49883
  var LEVEL_COLOR = '#0E79B2';
49884
+ // Keep this copy aligned with ../rpg-api:
49885
+ // SkillIncrease.ts, BattleDamageCalculator.ts, BattleEvent.ts,
49886
+ // ResourceRequirementConstants.ts, PlantHarvest.ts,
49887
+ // ItemCraftableQueue.ts, ItemMinLevelCalculator.ts, NPCExperience.ts.
49835
49888
  var SKILL_INFO_DATA = {
49836
49889
  first: {
49837
49890
  name: 'Fist',
49838
49891
  color: COMBAT_COLOR,
49839
- description: 'Governs your effectiveness when fighting unarmed or with punch-type weapons. Your level directly scales unarmed attack damage and attack speed.',
49840
- howToTrain: 'Deal damage to enemies while fighting with no weapon equipped or while wearing leather gloves.',
49841
- notes: 'No equipment is required to train this skill useful for new players. Berserker class receives a strong affinity bonus.'
49892
+ description: 'Used for unarmed attacks. Higher Fist improves your chance to hit and the damage you deal while fighting empty-handed.',
49893
+ howToTrain: 'Land non-spell hits with no weapon equipped.',
49894
+ notes: 'Some gloves require Fist, but you train it by fighting unarmed. Berserkers learn it especially well.'
49842
49895
  },
49843
49896
  club: {
49844
49897
  name: 'Club',
49845
49898
  color: COMBAT_COLOR,
49846
- description: 'Determines your proficiency with mace-type weapons such as clubs and hammers. Higher level increases damage dealt and reduces attack interval.',
49847
- howToTrain: 'Deal damage to enemies while wielding any mace-type weapon.',
49848
- notes: 'Mace weapons deal more consistent damage than swords but have slower attack speed. Useful against heavily armored enemies.'
49899
+ description: 'Used for maces and clubs. Higher Club improves your chance to hit and the damage you deal with those weapons.',
49900
+ howToTrain: 'Land non-spell hits with a mace or club weapon equipped.',
49901
+ notes: 'Some mace-type weapons require Club to equip. Warriors and Berserkers learn it faster than most classes.'
49849
49902
  },
49850
49903
  sword: {
49851
49904
  name: 'Sword',
49852
49905
  color: COMBAT_COLOR,
49853
- description: 'Governs your mastery of one-handed and two-handed swords. Level scales both the damage bonus and effective swing speed of sword attacks.',
49854
- howToTrain: 'Deal damage to enemies while wielding any sword-type weapon.',
49855
- notes: 'Swords are the most balanced combat skill — moderate damage, moderate speed. Knight class has an affinity bonus to sword progression.'
49906
+ description: 'Used for swords. Higher Sword improves your chance to hit and the damage you deal with sword attacks.',
49907
+ howToTrain: 'Land non-spell hits with a sword equipped.',
49908
+ notes: 'Some swords require Sword to equip. Warriors and Berserkers are the natural Sword classes.'
49856
49909
  },
49857
49910
  axe: {
49858
49911
  name: 'Axe',
49859
49912
  color: COMBAT_COLOR,
49860
- description: 'Controls your skill with axe-type weapons. High axe level gives the biggest per-hit damage increase of any melee weapon type.',
49861
- howToTrain: 'Deal damage to enemies while wielding any axe-type weapon.',
49862
- notes: 'Axes have the highest damage ceiling of melee weapons but the slowest base attack speed. Best for burst damage on single targets.'
49913
+ description: 'Used for axes. Higher Axe improves your chance to hit and the damage you deal with axe attacks.',
49914
+ howToTrain: 'Land non-spell hits with an axe equipped.',
49915
+ notes: 'Some axes require Axe to equip. Berserkers are the natural Axe class, with Warriors close behind.'
49863
49916
  },
49864
49917
  distance: {
49865
49918
  name: 'Distance',
49866
49919
  color: COMBAT_COLOR,
49867
- description: 'Measures your accuracy and damage with ranged weapons such as bows, crossbows, and spears. Level reduces miss chance and increases projectile damage.',
49868
- howToTrain: 'Deal damage to enemies using any ranged weapon.',
49869
- notes: 'Allows attacking from a safe range. Archer class receives a notable affinity bonus. Vigor level affects the delay between ranged shots.'
49920
+ description: 'Used for ranged weapons and spears. Higher Distance improves your accuracy and damage, especially for Hunters.',
49921
+ howToTrain: 'Land non-spell hits with a ranged weapon or spear.',
49922
+ notes: 'Some ranged weapons and abilities also require Distance. Hunters rely on it the most for bows and spears.'
49870
49923
  },
49871
49924
  shielding: {
49872
49925
  name: 'Shielding',
49873
49926
  color: COMBAT_COLOR,
49874
- description: 'Represents your skill at blocking with shields. Higher level increases the percentage of incoming damage blocked per successful shield block and lowers block failure chance.',
49875
- howToTrain: 'Receive attacks from enemies while a shield is equipped in your off-hand slot.',
49876
- notes: 'Purely defensive trains only when you are being hit, not when you attack. Any shield enables training. Paladin and Knight classes have affinity bonuses.'
49927
+ description: 'Used when reducing incoming damage with a shield. With a shield equipped, Shielding boosts your defense and lets the shield absorb part of each hit.',
49928
+ howToTrain: 'Take hits or blocks while a shield is equipped.',
49929
+ notes: 'Shielding gains use a hard cooldown, so extra hits do not spam progress. Warriors benefit from it the most, with Berserkers also training it well.'
49877
49930
  },
49878
49931
  dagger: {
49879
49932
  name: 'Dagger',
49880
49933
  color: COMBAT_COLOR,
49881
- description: 'Governs your technique with daggers and short blades. Daggers are fast but deal less per-hit damage; high level compensates with additional attack speed and critical hit probability.',
49882
- howToTrain: 'Deal damage to enemies while wielding any dagger-type weapon.',
49883
- notes: 'Daggers have the fastest attack speed of any melee weapon type. Rogue class has a strong affinity bonus to dagger progression.'
49934
+ description: 'Used for daggers. Higher Dagger improves your chance to hit and the damage you deal with dagger attacks.',
49935
+ howToTrain: 'Land non-spell hits with a dagger equipped.',
49936
+ notes: 'Some daggers require Dagger to equip. Rogues are the main Dagger class, and Hunters also train it well.'
49884
49937
  },
49885
49938
  fishing: {
49886
49939
  name: 'Fishing',
49887
49940
  color: CRAFTING_COLOR,
49888
- description: 'Determines your success rate and yield when fishing. Higher levels unlock catches of rarer fish species and reduce waiting time between bites.',
49889
- howToTrain: 'Use a fishing rod near any water body with a fish resource. Each successful catch grants Skill Points.',
49890
- notes: 'A fishing rod must be equipped. Caught fish can be cooked with the Cooking skill. Druid class has a 10% bonus.'
49941
+ description: 'Governs fishing rewards and access to higher-tier catches. Higher Fishing lets you catch better fish and shell rewards.',
49942
+ howToTrain: 'Successfully fish reward items such as fish or shell resources.',
49943
+ notes: 'Higher-tier catches also depend on the rod you are using.'
49891
49944
  },
49892
49945
  farming: {
49893
49946
  name: 'Farming',
49894
49947
  color: CRAFTING_COLOR,
49895
- description: 'Controls your efficiency when cultivating crops. Level affects harvest quantity, double-harvest chance, and which rare crop varieties you can grow.',
49896
- howToTrain: 'Plant seeds in farming spots using a watering can, then harvest mature crops. Each harvest grants Skill Points.',
49897
- notes: 'Requires seeds (purchasable from farming NPCs) and a watering can. Crops must be watered at least once before harvest. Druid class has a 20% affinity bonus.'
49948
+ description: 'Governs plant harvesting. Higher Farming increases crop yield and improves harvest rarity when plants are collected.',
49949
+ howToTrain: 'Plant and harvest crops. Harvesting plants grants Farming SP.',
49950
+ notes: 'Some seeds require Farming before you can plant them.'
49898
49951
  },
49899
49952
  mining: {
49900
49953
  name: 'Mining',
49901
49954
  color: CRAFTING_COLOR,
49902
- description: 'Governs your ability to extract ore and stone from rock nodes. Level determines which ore types you can mine and how many resources you yield per swing.',
49903
- howToTrain: 'Mine rock or ore nodes with a pickaxe. Each successful resource extraction grants Skill Points.',
49904
- notes: 'A pickaxe must be equipped. Higher mining levels unlock rarer ores found in deeper zones. Dwarf race has a 20% bonus.'
49955
+ description: 'Governs mining rewards and unlocks higher-tier ore, stone, and gem drops.',
49956
+ howToTrain: 'Mine resource nodes and successfully receive mining rewards.',
49957
+ notes: 'Better mining rewards depend on both your Mining level and your pickaxe.'
49905
49958
  },
49906
49959
  lumberjacking: {
49907
49960
  name: 'Lumberjacking',
49908
49961
  color: CRAFTING_COLOR,
49909
- description: 'Controls your skill at chopping trees for wood. Level determines which tree types you can cut and the number of logs obtained per swing.',
49910
- howToTrain: 'Chop tree resource nodes with an axe equipped. Each log obtained grants Skill Points.',
49911
- notes: 'Any axe-type weapon doubles as a lumberjacking tool there is no separate lumberjacking tool. Rarer wood types require higher skill and appear in higher-level zones.'
49962
+ description: 'Governs woodcutting rewards and unlocks higher-tier wood drops.',
49963
+ howToTrain: 'Chop resource nodes and successfully receive wood rewards.',
49964
+ notes: 'Better wood tiers depend on both your Lumberjacking level and the tool you are using.'
49912
49965
  },
49913
49966
  blacksmithing: {
49914
49967
  name: 'Blacksmithing',
49915
49968
  color: CRAFTING_COLOR,
49916
- description: 'Determines your ability to craft metal equipment such as weapons and armor at forge stations. Higher level unlocks stronger recipes and improves crafted item quality.',
49917
- howToTrain: "Craft metal items at a blacksmith's forge using ingots and other materials. Each successful craft grants Skill Points.",
49918
- notes: 'Requires materials obtained from mining. Blacksmithing produces tradeable equipment items. Higher level recipes require rare ingots. Rogue class has a 10% bonus.'
49969
+ description: 'Governs blacksmithing recipes and ingot processing. Higher Blacksmithing improves craft success and unlocks stronger smithing recipes.',
49970
+ howToTrain: 'Successfully smelt bars or craft gear with Blacksmithing recipes.',
49971
+ notes: 'You only gain SP from successful crafts.'
49919
49972
  },
49920
49973
  cooking: {
49921
49974
  name: 'Cooking',
49922
49975
  color: CRAFTING_COLOR,
49923
- description: 'Governs your ability to prepare food from raw ingredients. Cooked food restores HP or provides temporary stat buffs. Higher level produces more potent food.',
49924
- howToTrain: 'Cook raw food items at a cooking station or campfire. Each successful cook grants Skill Points.',
49925
- notes: 'Raw ingredients come from fishing, farming, and monster drops. Cooked meals restore more HP than potions at equivalent cost and can provide additional buffs.'
49976
+ description: 'Governs cooking recipes. Higher Cooking improves craft success and unlocks recipes with higher cooking requirements.',
49977
+ howToTrain: 'Successfully cook food with Cooking recipes.',
49978
+ notes: 'You only gain SP from successful crafts.'
49926
49979
  },
49927
49980
  alchemy: {
49928
49981
  name: 'Alchemy',
49929
49982
  color: CRAFTING_COLOR,
49930
- description: 'Controls your skill at brewing potions and elixirs. Higher levels unlock stronger potion recipes, reduce failure chance, and increase the potency of brewed potions.',
49931
- howToTrain: 'Brew potions at an alchemy station using herbs, reagents, and vials. Each successful brew grants Skill Points.',
49932
- notes: 'Herb reagents are gathered from nature nodes across the world. High-level alchemy produces Greater and Superior potions that substantially outperform shop-bought equivalents. Druid has a 20% bonus.'
49983
+ description: 'Governs alchemy recipes. Higher Alchemy improves craft success and unlocks recipes with higher alchemy requirements.',
49984
+ howToTrain: 'Successfully brew potions or craft reagents with Alchemy recipes.',
49985
+ notes: 'You only gain SP from successful crafts.'
49933
49986
  },
49934
49987
  magic: {
49935
49988
  name: 'Magic',
49936
49989
  color: ATTRIBUTE_COLOR,
49937
- description: 'Governs the power and efficiency of spells and magic-type weapons. Higher Magic level increases spell damage, spell range, and reduces mana consumption.',
49938
- howToTrain: 'Deal damage to enemies using spells from your spellbook, or fight while wielding a magic staff or wand.',
49939
- notes: 'Magic starts at level 0 and is one of the slower attributes to train since it requires active spell use. Sorcerer and Mage classes receive strong affinity bonuses. Also increases maximum mana.'
49990
+ description: 'Used for spell power, rune scaling, staff or magic-weapon attacks, gear used by mage classes, and some carry-weight calculations.',
49991
+ howToTrain: 'Cast spells or land non-spell hits with magic or staff weapons.',
49992
+ notes: 'Sorcerers and Druids are the mage classes, and both lean on Magic and staves. They also use Magic instead of Strength for max carry weight.'
49940
49993
  },
49941
49994
  magicResistance: {
49942
49995
  name: 'Magic Resistance',
49943
49996
  color: ATTRIBUTE_COLOR,
49944
- description: 'Reduces the damage taken from incoming magical attacks and spells. Each level of magic resistance reduces a percentage of spell damage received.',
49945
- howToTrain: 'Receive magic damage from enemies (spells, magical attacks, staff hits aimed at you).',
49946
- notes: 'Purely defensive trains only when you are the target of magical attacks. Cannot be trained offensively. Essential for characters that frequently face casters or magic creatures.'
49997
+ description: 'Used when reducing incoming magic damage. Higher Magic Resistance improves your defense against spells and other magical attacks.',
49998
+ howToTrain: 'Take damage from spells, magic weapons, runes, or other magical attacks.',
49999
+ notes: 'This only trains on incoming magic damage, not on casting. Sorcerers and Druids improve it faster than other classes.'
49947
50000
  },
49948
50001
  strength: {
49949
50002
  name: 'Strength',
49950
50003
  color: ATTRIBUTE_COLOR,
49951
- description: 'Directly increases melee attack damage for all physical weapon types. Also increases how much weight your character can carry.',
49952
- howToTrain: 'Deal melee damage to enemies using any physical weapon or unarmed combat.',
49953
- notes: 'Applies to all physical weapon types regardless of which combat skill you use. Warrior and Berserker classes gain Strength faster due to class affinity.'
50004
+ description: 'Used for physical damage, carry weight for non-mages, item requirements, and many strength-scaling abilities.',
50005
+ howToTrain: 'Land non-spell hits with physical weapons or while fighting unarmed.',
50006
+ notes: 'When you attack with magic or staff weapons, Strength is not trained. Warriors and Berserkers get the most out of it.'
49954
50007
  },
49955
50008
  resistance: {
49956
50009
  name: 'Resistance',
49957
50010
  color: ATTRIBUTE_COLOR,
49958
- description: 'Reduces incoming physical damage from melee and ranged attacks. Higher resistance provides a percentage reduction to the physical damage you receive per hit.',
49959
- howToTrain: 'Receive physical damage from enemies (melee hits, arrows, projectiles).',
49960
- notes: 'Passive defense trains only when you take physical damage. Tank-oriented classes (Paladin, Knight) receive faster resistance growth. Stacks with Shielding for substantial physical damage reduction.'
50011
+ description: 'Used in physical defense and damage reduction. Higher Resistance lowers the damage you take from non-magic attacks.',
50012
+ howToTrain: 'Take non-magic damage from melee, ranged, or other physical attacks.',
50013
+ notes: 'Shield users stack Resistance with Shielding for better mitigation. Warriors are strongest here, with Berserkers and Druids also holding up well.'
49961
50014
  },
49962
50015
  dexterity: {
49963
50016
  name: 'Dexterity',
49964
50017
  color: ATTRIBUTE_COLOR,
49965
- description: 'Increases your attack speed (reduces attack interval) and improves your chance to dodge incoming attacks. Also slightly improves accuracy with ranged weapons.',
49966
- howToTrain: 'Deal physical damage to enemies or successfully dodge incoming attacks.',
49967
- notes: 'Attack speed compounds with damage more attacks per second means proportionally more total damage. One of the most impactful combat attributes. Archer and Rogue classes have strong dexterity affinity.'
50018
+ description: 'Dexterity affects accuracy and blocking, and Hunters also rely on it heavily for ranged damage. Some Rogue and Hunter abilities scale from it.',
50019
+ howToTrain: 'Make incoming attacks miss you. Each miss grants Dexterity SP.',
50020
+ notes: 'Some accessories require Dexterity. Hunters and Rogues lean on it the most.'
49968
50021
  },
49969
50022
  level: {
49970
50023
  name: 'Character Level',
49971
50024
  color: LEVEL_COLOR,
49972
- description: 'Your overall character level, derived from total Experience Points (XP) accumulated. It summarizes your overall progress and may unlock access to certain areas or content.',
49973
- howToTrain: 'XP is gained by killing monsters, completing quests, and reaching skill level milestones. Unlike skill SP, all XP accumulates into a single shared pool that determines your character level.',
49974
- notes: 'Uses a cubic progression formula (level³ × 3 XP per level), so higher levels require exponentially more XP. Character level itself does not directly affect combat — individual skill levels handle that.'
50025
+ description: 'Your overall character level. It affects attack, defense, damage, movement speed, health, mana, spell unlocks, and other progression systems.',
50026
+ howToTrain: 'Gain XP from defeated enemies and other experience rewards.',
50027
+ notes: 'Level-ups refresh derived stats such as max health and max mana and can unlock new spells.'
49975
50028
  }
49976
50029
  };
49977
50030
 
@@ -73483,7 +73536,7 @@ var Store = function Store(_ref) {
73483
73536
  items: {
73484
73537
  id: 'items',
73485
73538
  title: 'Items',
73486
- icon: React.createElement(Box, {
73539
+ icon: React.createElement(Package, {
73487
73540
  width: 18,
73488
73541
  height: 18
73489
73542
  }),