@hytopia.com/examples 1.0.12 → 1.0.14

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 (68) hide show
  1. package/frontiers-rpg-game/assets/icons/items/leather-boots.png +0 -0
  2. package/frontiers-rpg-game/assets/icons/items/leather-bracers.png +0 -0
  3. package/frontiers-rpg-game/assets/icons/items/leather-helmet.png +0 -0
  4. package/frontiers-rpg-game/assets/icons/items/leather-leggings.png +0 -0
  5. package/frontiers-rpg-game/assets/icons/items/leather-vest.png +0 -0
  6. package/frontiers-rpg-game/assets/icons/items/spiked-club.png +0 -0
  7. package/frontiers-rpg-game/assets/icons/skills/crafting.png +0 -0
  8. package/frontiers-rpg-game/assets/models/weapons/.optimized/mace/baseColor.png +0 -0
  9. package/frontiers-rpg-game/assets/models/weapons/.optimized/mace/mace-named-nodes.bin +0 -0
  10. package/frontiers-rpg-game/assets/models/weapons/.optimized/mace/mace-named-nodes.gltf +653 -0
  11. package/frontiers-rpg-game/assets/models/weapons/.optimized/mace/mace.bin +0 -0
  12. package/frontiers-rpg-game/assets/models/weapons/.optimized/mace/mace.gltf +135 -0
  13. package/frontiers-rpg-game/assets/models/weapons/.optimized/mace/mace.gltf.md5 +1 -0
  14. package/frontiers-rpg-game/assets/models/weapons/.optimized/spiked-club/baseColor.png +0 -0
  15. package/frontiers-rpg-game/assets/models/weapons/.optimized/spiked-club/spiked-club-named-nodes.bin +0 -0
  16. package/frontiers-rpg-game/assets/models/weapons/.optimized/spiked-club/spiked-club-named-nodes.gltf +840 -0
  17. package/frontiers-rpg-game/assets/models/weapons/.optimized/spiked-club/spiked-club.bin +0 -0
  18. package/frontiers-rpg-game/assets/models/weapons/.optimized/spiked-club/spiked-club.gltf +141 -0
  19. package/frontiers-rpg-game/assets/models/weapons/.optimized/spiked-club/spiked-club.gltf.md5 +1 -0
  20. package/frontiers-rpg-game/assets/models/weapons/mace.gltf +1 -0
  21. package/frontiers-rpg-game/assets/ui/build.js +2 -0
  22. package/frontiers-rpg-game/assets/ui/index.html +1328 -64
  23. package/frontiers-rpg-game/assets/ui/menus/crafting.html +976 -0
  24. package/frontiers-rpg-game/assets/ui/menus/quests.html +70 -2
  25. package/frontiers-rpg-game/assets/ui/shared/item-stats.html +224 -0
  26. package/frontiers-rpg-game/assets/ui/shared/item-tooltips.html +72 -81
  27. package/frontiers-rpg-game/dev/persistence/player-player-1.json +120 -11
  28. package/frontiers-rpg-game/src/GamePlayer.ts +53 -0
  29. package/frontiers-rpg-game/src/GamePlayerEntity.ts +9 -2
  30. package/frontiers-rpg-game/src/config.ts +7 -0
  31. package/frontiers-rpg-game/src/entities/BaseCraftingEntity.ts +115 -0
  32. package/frontiers-rpg-game/src/entities/enemies/RatkinBruteEntity.ts +2 -0
  33. package/frontiers-rpg-game/src/entities/enemies/RatkinRangerEntity.ts +2 -0
  34. package/frontiers-rpg-game/src/entities/enemies/RatkinSpellcasterEntity.ts +2 -0
  35. package/frontiers-rpg-game/src/entities/enemies/RatkinWarriorEntity.ts +2 -0
  36. package/frontiers-rpg-game/src/entities/enemies/TaintedRatkinBruteEntity.ts +2 -0
  37. package/frontiers-rpg-game/src/entities/enemies/TaintedRatkinRangerEntity.ts +2 -1
  38. package/frontiers-rpg-game/src/entities/enemies/TaintedRatkinSpellcasterEntity.ts +2 -0
  39. package/frontiers-rpg-game/src/entities/enemies/TaintedRatkinWarriorEntity.ts +2 -0
  40. package/frontiers-rpg-game/src/entities/forageables/DecayingPileEntity.ts +2 -2
  41. package/frontiers-rpg-game/src/entities/forageables/RottenLogEntity.ts +2 -2
  42. package/frontiers-rpg-game/src/items/BaseWeaponItem.ts +2 -2
  43. package/frontiers-rpg-game/src/items/ItemClasses.ts +14 -2
  44. package/frontiers-rpg-game/src/items/materials/RawHideItem.ts +10 -0
  45. package/frontiers-rpg-game/src/items/weapons/DullSwordItem.ts +5 -4
  46. package/frontiers-rpg-game/src/items/weapons/IronDaggerItem.ts +1 -1
  47. package/frontiers-rpg-game/src/items/weapons/IronLongSwordItem.ts +5 -4
  48. package/frontiers-rpg-game/src/items/weapons/SpikedClubItem.ts +26 -0
  49. package/frontiers-rpg-game/src/items/weapons/TrainingSwordItem.ts +5 -4
  50. package/frontiers-rpg-game/src/items/wearables/LeatherBootsItem.ts +14 -0
  51. package/frontiers-rpg-game/src/items/wearables/LeatherBracersItem.ts +14 -0
  52. package/frontiers-rpg-game/src/items/wearables/LeatherHelmetItem.ts +14 -0
  53. package/frontiers-rpg-game/src/items/wearables/LeatherLeggingsItem.ts +14 -0
  54. package/frontiers-rpg-game/src/items/wearables/LeatherVestItem.ts +14 -0
  55. package/frontiers-rpg-game/src/quests/BaseQuest.ts +1 -2
  56. package/frontiers-rpg-game/src/quests/QuestClasses.ts +2 -0
  57. package/frontiers-rpg-game/src/quests/side/FungalForagingQuest.ts +1 -23
  58. package/frontiers-rpg-game/src/quests/side/HammersAndCraftingQuest.ts +139 -0
  59. package/frontiers-rpg-game/src/regions/stalkhaven/StalkhavenRegion.ts +35 -22
  60. package/frontiers-rpg-game/src/regions/stalkhaven/npcs/BlacksmithArdenEntity.ts +114 -0
  61. package/frontiers-rpg-game/src/systems/QuestLog.ts +2 -5
  62. package/package.json +1 -1
  63. package/frontiers-rpg-game/dev/persistence/player-player-2.json +0 -31
  64. package/frontiers-rpg-game/dev/persistence/player-player-3.json +0 -25
  65. package/frontiers-rpg-game/dev/persistence/player-player-4.json +0 -31
  66. package/frontiers-rpg-game/src/items/materials/MonsterHideItem.ts +0 -10
  67. /package/frontiers-rpg-game/assets/icons/items/{monster-hide.png → raw-hide.png} +0 -0
  68. /package/frontiers-rpg-game/assets/models/weapons/{club.gltf → spiked-club.gltf} +0 -0
@@ -0,0 +1,14 @@
1
+ import BaseWearableItem, { WearableSlot } from '../BaseWearableItem';
2
+
3
+ export default class LeatherBootsItem extends BaseWearableItem {
4
+ static readonly id = 'leather_boots';
5
+ static readonly name = 'Leather Boots';
6
+ static readonly iconImageUri = 'icons/items/leather-boots.png';
7
+ static readonly description = `A sturdy pair of boots made from thick leather.`;
8
+ static readonly buyPrice = 350;
9
+ static readonly sellPrice = 35;
10
+
11
+ static readonly damageReduction = 2;
12
+
13
+ static readonly slot: WearableSlot = 'boots';
14
+ }
@@ -0,0 +1,14 @@
1
+ import BaseWearableItem, { WearableSlot } from '../BaseWearableItem';
2
+
3
+ export default class LeatherBracersItem extends BaseWearableItem {
4
+ static readonly id = 'leather_bracers';
5
+ static readonly name = 'Leather Bracers';
6
+ static readonly iconImageUri = 'icons/items/leather-bracers.png';
7
+ static readonly description = `A pair of supportive bracers made from thick leather.`;
8
+ static readonly buyPrice = 300;
9
+ static readonly sellPrice = 30;
10
+
11
+ static readonly damageReduction = 2;
12
+
13
+ static readonly slot: WearableSlot = 'gloves';
14
+ }
@@ -0,0 +1,14 @@
1
+ import BaseWearableItem, { WearableSlot } from '../BaseWearableItem';
2
+
3
+ export default class LeatherHelmetItem extends BaseWearableItem {
4
+ static readonly id = 'leather_helmet';
5
+ static readonly name = 'Leather Helmet';
6
+ static readonly iconImageUri = 'icons/items/leather-helmet.png';
7
+ static readonly description = `A protective helmet made from thick leather.`;
8
+ static readonly buyPrice = 350;
9
+ static readonly sellPrice = 35;
10
+
11
+ static readonly damageReduction = 2;
12
+
13
+ static readonly slot: WearableSlot = 'helmet';
14
+ }
@@ -0,0 +1,14 @@
1
+ import BaseWearableItem, { WearableSlot } from '../BaseWearableItem';
2
+
3
+ export default class LeatherLeggingsItem extends BaseWearableItem {
4
+ static readonly id = 'leather_leggings';
5
+ static readonly name = 'Leather Leggings';
6
+ static readonly iconImageUri = 'icons/items/leather-leggings.png';
7
+ static readonly description = `A comfortable pair of leggings made from thick leather.`;
8
+ static readonly buyPrice = 500;
9
+ static readonly sellPrice = 50;
10
+
11
+ static readonly damageReduction = 3;
12
+
13
+ static readonly slot: WearableSlot = 'leggings';
14
+ }
@@ -0,0 +1,14 @@
1
+ import BaseWearableItem, { WearableSlot } from '../BaseWearableItem';
2
+
3
+ export default class LeatherVestItem extends BaseWearableItem {
4
+ static readonly id = 'leather_vest';
5
+ static readonly name = 'Leather Vest';
6
+ static readonly iconImageUri = 'icons/items/leather-vest.png';
7
+ static readonly description = `A tough multi-layer vest made from thick leather.`;
8
+ static readonly buyPrice = 700;
9
+ static readonly sellPrice = 70;
10
+
11
+ static readonly damageReduction = 4;
12
+
13
+ static readonly slot: WearableSlot = 'armor';
14
+ }
@@ -67,8 +67,7 @@ export default abstract class BaseQuest {
67
67
  }
68
68
 
69
69
  for (const itemReward of this.reward.items) {
70
- const item = itemReward.itemClass.create({ quantity: itemReward.quantity });
71
- gamePlayer.hotbar.addItem(item) || gamePlayer.backpack.addItem(item);
70
+ gamePlayer.addHeldItem(itemReward.itemClass, itemReward.quantity);
72
71
  }
73
72
  }
74
73
 
@@ -10,6 +10,7 @@ import BlightedHarvestQuest from './main/BlightedHarvestQuest';
10
10
  // Side Quests, Alphabetical
11
11
  import DipDuckDodgeQuest from './side/DipDuckDodgeQuest';
12
12
  import FungalForagingQuest from './side/FungalForagingQuest';
13
+ import HammersAndCraftingQuest from './side/HammersAndCraftingQuest';
13
14
 
14
15
  export default [
15
16
  // Main, Alphabetical
@@ -24,4 +25,5 @@ export default [
24
25
  // Side, Alphabetical
25
26
  DipDuckDodgeQuest,
26
27
  FungalForagingQuest,
28
+ HammersAndCraftingQuest,
27
29
  ];
@@ -107,32 +107,10 @@ export default class FungalForagingQuest extends BaseQuest {
107
107
  ],
108
108
  },
109
109
  onSelect: (interactor: GamePlayerEntity) => {
110
- const totalBackpackMushrooms = interactor.gamePlayer.backpack.getItemQuantityByClass(CommonMushroomItem);
111
- const totalHotbarMushrooms = interactor.gamePlayer.hotbar.getItemQuantityByClass(CommonMushroomItem);
112
-
113
- if (totalHotbarMushrooms + totalBackpackMushrooms < 25) {
110
+ if (!interactor.gamePlayer.removeHeldItem(CommonMushroomItem, 25)) {
114
111
  return interactor.showNotification(`Merchant Finn is looking for 25 Common Mushrooms - seems you're a bit short!`, 'error');
115
112
  }
116
113
 
117
- // Remove 25 mushrooms from backpack and hotbar
118
- let remaining = 25;
119
-
120
- // Remove from backpack first
121
- for (const item of interactor.gamePlayer.backpack.getItemsByClass(CommonMushroomItem)) {
122
- if (remaining <= 0) break;
123
- const toRemove = Math.min(item.quantity, remaining);
124
- interactor.gamePlayer.backpack.adjustItemQuantityByReference(item, -toRemove);
125
- remaining -= toRemove;
126
- }
127
-
128
- // Remove from hotbar if needed
129
- for (const item of interactor.gamePlayer.hotbar.getItemsByClass(CommonMushroomItem)) {
130
- if (remaining <= 0) break;
131
- const toRemove = Math.min(item.quantity, remaining);
132
- interactor.gamePlayer.hotbar.adjustItemQuantityByReference(item, -toRemove);
133
- remaining -= toRemove;
134
- }
135
-
136
114
  interactor.gamePlayer.questLog.adjustObjectiveProgress(this.id, 'give-mushrooms', 1);
137
115
  interactor.gamePlayer.questLog.completeQuest(this.id);
138
116
  }
@@ -0,0 +1,139 @@
1
+ import BaseQuest, { QuestObjective, QuestNpcDialogueInteraction } from '../BaseQuest';
2
+ import { SkillId } from '../../config';
3
+ import type GamePlayer from '../../GamePlayer';
4
+ import type GamePlayerEntity from '../../GamePlayerEntity';
5
+
6
+ import { BaseCraftingEntityPlayerEvent } from '../../entities/BaseCraftingEntity';
7
+ import { BaseItemPlayerEvent } from '../../items/BaseItem';
8
+ import type { BaseCraftingEntityPlayerEventPayloads } from '../../entities/BaseCraftingEntity';
9
+ import type { BaseItemPlayerEventPayloads } from '../../items/BaseItem';
10
+
11
+ import BlacksmithArdenEntity from '../../regions/stalkhaven/npcs/BlacksmithArdenEntity';
12
+ import ExploringStalkhavenQuest from '../main/ExploringStalkhavenQuest';
13
+ import RawHideItem from '../../items/materials/RawHideItem';
14
+
15
+ export default class HammersAndCraftingQuest extends BaseQuest {
16
+ static readonly id = 'hammers-and-crafting';
17
+ static readonly name = 'Hammers and Crafting';
18
+ static readonly description = `Blacksmith Arden wants to introduce you to crafting. Bring him some materials and craft your first item.`;
19
+
20
+ static readonly reward = {
21
+ items: [
22
+ { itemClass: RawHideItem, quantity: 10 },
23
+ ],
24
+ skillExperience: [
25
+ { skillId: SkillId.CRAFTING, amount: 300 },
26
+ ],
27
+ }
28
+
29
+ static readonly objectives: QuestObjective[] = [
30
+ {
31
+ id: 'gather-materials',
32
+ name: 'Gather Materials',
33
+ description: 'Gather 15 Raw Hides by slaying Ratkin or foraging in Chitter Forest.',
34
+ target: 15,
35
+ },
36
+ {
37
+ id: 'craft-item',
38
+ name: 'Craft an Item',
39
+ description: 'Craft your first item after gathering materials. Blacksmith Arden in Stalkhaven can help you craft!',
40
+ target: 1,
41
+ },
42
+ {
43
+ id: 'talk-to-arden',
44
+ name: 'Speak with Blacksmith Arden',
45
+ description: 'Speak with Blacksmith Arden after gathering materials and crafting an item.',
46
+ target: 1,
47
+ }
48
+ ];
49
+
50
+ static readonly dialogueInteractions: QuestNpcDialogueInteraction[] = [
51
+ // Start Quest
52
+ {
53
+ npcClass: BlacksmithArdenEntity,
54
+ dialogueOption: {
55
+ text: `Who are you?`,
56
+ nextDialogue: {
57
+ text: `Ahh, me? The name's Arden. I'm just a humble blacksmith making weapons and armor for the 7th regiment here in Stalkhaven. I can help you make some if you'd like?`,
58
+ options: [
59
+ {
60
+ text: `Please teach me how to craft!`,
61
+ nextDialogue: {
62
+ text: `Absolutely, first you'll need to gather some materials. Raw Hide is the easiest to work with. Go slay those Ratkin beasts or forage in Chitter Forest to find some. 15 Raw Hides should do. I'll wait here.`,
63
+ options: [
64
+ {
65
+ text: `That sounds great, I'll go get some Raw Hide.`,
66
+ dismiss: true,
67
+ pureExit: true,
68
+ }
69
+ ],
70
+ },
71
+ onSelect: (interactor: GamePlayerEntity) => {
72
+ interactor.gamePlayer.questLog.startQuest(this);
73
+ }
74
+ },
75
+ {
76
+ text: `Maybe later, thanks.`,
77
+ dismiss: true,
78
+ pureExit: true,
79
+ }
80
+ ],
81
+ },
82
+ },
83
+ enabledForInteractor: (interactor: GamePlayerEntity) => {
84
+ return interactor.gamePlayer.questLog.isQuestCompleted(ExploringStalkhavenQuest.id) &&
85
+ !interactor.gamePlayer.questLog.hasQuest(this.id);
86
+ }
87
+ },
88
+
89
+ // Complete Quest
90
+ {
91
+ npcClass: BlacksmithArdenEntity,
92
+ dialogueOption: {
93
+ text: `I've crafted my first item, that was fun!`,
94
+ nextDialogue: {
95
+ text: `Great work! You can come back to me anytime and I can help you craft more items. Improve your crafting skills and we'll be able to craft even better weapons and armor.`,
96
+ options: [
97
+ {
98
+ text: `Thanks for the help!`,
99
+ dismiss: true,
100
+ pureExit: true,
101
+ }
102
+ ],
103
+ },
104
+ onSelect: (interactor: GamePlayerEntity) => {
105
+ interactor.gamePlayer.questLog.adjustObjectiveProgress(this.id, 'talk-to-arden', 1);
106
+ interactor.gamePlayer.questLog.completeQuest(this.id);
107
+ }
108
+ },
109
+ enabledForInteractor: (interactor: GamePlayerEntity) => {
110
+ return interactor.gamePlayer.questLog.isQuestActive(this.id) &&
111
+ interactor.gamePlayer.questLog.isQuestObjectiveCompleted(this.id, 'gather-materials') &&
112
+ interactor.gamePlayer.questLog.isQuestObjectiveCompleted(this.id, 'craft-item');
113
+ }
114
+ }
115
+ ];
116
+
117
+ public static setupForPlayer(gamePlayer: GamePlayer): () => void {
118
+ // Add event listeners
119
+ const itemPickupListener = (payload: BaseItemPlayerEventPayloads[BaseItemPlayerEvent.PICKED_UP]) => {
120
+ if (payload.item.id === RawHideItem.id) {
121
+ gamePlayer.questLog.adjustObjectiveProgress(this.id, 'gather-materials', payload.item.quantity);
122
+ }
123
+ };
124
+
125
+ const craftListener = (payload: BaseCraftingEntityPlayerEventPayloads[BaseCraftingEntityPlayerEvent.CRAFT_ITEM]) => {
126
+ gamePlayer.questLog.adjustObjectiveProgress(this.id, 'craft-item', 1);
127
+ };
128
+
129
+ gamePlayer.eventRouter.on(BaseItemPlayerEvent.PICKED_UP, itemPickupListener);
130
+ gamePlayer.eventRouter.on(BaseCraftingEntityPlayerEvent.CRAFT_ITEM, craftListener);
131
+
132
+ const cleanup = () => {
133
+ gamePlayer.eventRouter.off(BaseItemPlayerEvent.PICKED_UP, itemPickupListener);
134
+ gamePlayer.eventRouter.off(BaseCraftingEntityPlayerEvent.CRAFT_ITEM, craftListener);
135
+ };
136
+
137
+ return cleanup;
138
+ }
139
+ }
@@ -1,11 +1,15 @@
1
1
  import { Quaternion } from 'hytopia';
2
2
  import GameRegion from '../../GameRegion';
3
+ import Spawner from '../../systems/Spawner';
3
4
  import PortalEntity from '../../entities/PortalEntity';
5
+ import type { WanderOptions } from '../../entities/BaseEntity';
4
6
 
7
+ // NPCs
5
8
  import CapfolkVillagerEntity from '../../entities/npcs/CapfolkVillagerEntity';
6
9
  import CaptainSpornEntity from './npcs/CaptainSpornEntity';
7
10
  import CommanderMarkEntity from './npcs/CommanderMarkEntity';
8
11
  import BankerJohnEntity from './npcs/BankerJohnEntity';
12
+ import BlacksmithArdenEntity from './npcs/BlacksmithArdenEntity';
9
13
  import HealerMycelisEntity from './npcs/HealerMycelisEntity';
10
14
  import MerchantFinnEntity from './npcs/MerchantFinnEntity';
11
15
 
@@ -27,40 +31,49 @@ export default class StalkhavenRegion extends GameRegion {
27
31
  super.setup();
28
32
 
29
33
  this._setupNPCs();
34
+ this._setupNPCSpawners();
30
35
  this._setupPortals();
31
36
  }
32
37
 
33
38
  private _setupNPCs(): void {
34
39
  (new BankerJohnEntity({ facingAngle: 90 })).spawn(this.world, { x: 12, y: 3, z: 41 });
40
+ (new BlacksmithArdenEntity({ facingAngle: 250 })).spawn(this.world, { x: -25, y: 3, z: -13 });
35
41
  (new CaptainSpornEntity({ facingAngle: 315 })).spawn(this.world, { x: -2, y: 3, z: 43 });
36
42
  (new CommanderMarkEntity({ facingAngle: 180 })).spawn(this.world, { x: 3, y: 3, z: 12 });
37
43
  (new HealerMycelisEntity({ facingAngle: 180 })).spawn(this.world, { x: -13.5, y: 3, z: -30 });
38
44
  (new MerchantFinnEntity({ facingAngle: 90 })).spawn(this.world, { x: 13, y: 3, z: 26.5 });
45
+ }
39
46
 
40
- // Wandering Villagers
41
- const villagerStartPositions = [
42
- { x: -6, y: 3, z: 13 }, // town center
43
- { x: 14, y: 3, z: 4 }, // town center
44
- { x: -2, y: 3, z: -15 }, // town center
45
- { x: 23, y: 3, z: 41 }, // well
46
- { x: 26, y: 3, z: -22 }, // market
47
- { x: 15, y: 3, z: -30 }, // market
48
- ];
47
+ private _setupNPCSpawners(): void {
48
+ const wanderOptions: WanderOptions = {
49
+ idleMinMs: 5000,
50
+ idleMaxMs: 15000,
51
+ maxWanderRadius: 12,
52
+ moveOptions: {
53
+ moveCompletesWhenStuck: true,
54
+ moveStoppingDistance: 1,
55
+ }
56
+ }
49
57
 
50
- for (const position of villagerStartPositions) {
51
- const villager = new CapfolkVillagerEntity({ facingAngle: Math.random() * 360 });
52
- villager.spawn(this.world, position);
53
- villager.wander(villager.moveSpeed, {
54
- idleMinMs: 5000,
55
- idleMaxMs: 15000,
56
- maxWanderRadius: 12,
57
- moveOptions: {
58
- moveCompletesWhenStuck: true,
59
- moveStoppingDistance: 1,
58
+ const capfolkVillagerSpawner = new Spawner({
59
+ groundCheckDistance: 10,
60
+ maxSpawns: 10,
61
+ spawnables: [
62
+ { entityConstructor: CapfolkVillagerEntity, weight: 1, wanders: true, wanderOptions },
63
+ ],
64
+ spawnRegions: [
65
+ {
66
+ min: { x: -24, y: 2, z: -29 },
67
+ max: { x: 29, y: 12, z: 38 },
68
+ weight: 1,
60
69
  }
61
- });
62
- }
63
- }
70
+ ],
71
+ spawnIntervalMs: 60000,
72
+ world: this.world,
73
+ });
74
+
75
+ capfolkVillagerSpawner.start(true);
76
+ }
64
77
 
65
78
  private _setupPortals(): void {
66
79
  const chitterForestPortal = new PortalEntity({
@@ -0,0 +1,114 @@
1
+ import BaseCraftingEntity, { BaseCraftingEntityOptions } from '../../../entities/BaseCraftingEntity';
2
+
3
+ import GoldItem from '../../../items/general/GoldItem';
4
+ import LeatherBootsItem from '../../../items/wearables/LeatherBootsItem';
5
+ import LeatherBracersItem from '../../../items/wearables/LeatherBracersItem';
6
+ import LeatherHelmetItem from '../../../items/wearables/LeatherHelmetItem';
7
+ import LeatherLeggingsItem from '../../../items/wearables/LeatherLeggingsItem';
8
+ import LeatherVestItem from '../../../items/wearables/LeatherVestItem';
9
+ import RatkinBonesItem from '../../../items/materials/RatkinBonesItem';
10
+ import RatkinToothItem from '../../../items/materials/RatkinToothItem';
11
+ import RawHideItem from '../../../items/materials/RawHideItem';
12
+ import SpikedClubItem from '../../../items/weapons/SpikedClubItem';
13
+
14
+ export default class BlacksmithArdenEntity extends BaseCraftingEntity {
15
+ public constructor(options?: Partial<BaseCraftingEntityOptions>) {
16
+ super({
17
+ craftingRecipes: [
18
+ {
19
+ craftedItemClass: LeatherHelmetItem,
20
+ requirements: [
21
+ {
22
+ itemClass: RawHideItem,
23
+ quantity: 20,
24
+ },
25
+ {
26
+ itemClass: GoldItem,
27
+ quantity: 250,
28
+ },
29
+ ],
30
+ },
31
+ {
32
+ craftedItemClass: LeatherVestItem,
33
+ requirements: [
34
+ {
35
+ itemClass: RawHideItem,
36
+ quantity: 35,
37
+ },
38
+ {
39
+ itemClass: GoldItem,
40
+ quantity: 300,
41
+ },
42
+ ],
43
+ },
44
+ {
45
+ craftedItemClass: LeatherBracersItem,
46
+ requirements: [
47
+ {
48
+ itemClass: RawHideItem,
49
+ quantity: 15,
50
+ },
51
+ {
52
+ itemClass: GoldItem,
53
+ quantity: 200,
54
+ },
55
+ ],
56
+ },
57
+ {
58
+ craftedItemClass: LeatherLeggingsItem,
59
+ requirements: [
60
+ {
61
+ itemClass: RawHideItem,
62
+ quantity: 25,
63
+ },
64
+ {
65
+ itemClass: GoldItem,
66
+ quantity: 250,
67
+ },
68
+ ],
69
+ },
70
+ {
71
+ craftedItemClass: LeatherBootsItem,
72
+ requirements: [
73
+ {
74
+ itemClass: RawHideItem,
75
+ quantity: 15,
76
+ },
77
+ {
78
+ itemClass: GoldItem,
79
+ quantity: 200,
80
+ },
81
+ ],
82
+ },
83
+ {
84
+ craftedItemClass: SpikedClubItem,
85
+ requirements: [
86
+ {
87
+ itemClass: RatkinBonesItem,
88
+ quantity: 30,
89
+ },
90
+ {
91
+ itemClass: RatkinToothItem,
92
+ quantity: 25,
93
+ },
94
+ {
95
+ itemClass: RawHideItem,
96
+ quantity: 5,
97
+ },
98
+ {
99
+ itemClass: GoldItem,
100
+ quantity: 400,
101
+ },
102
+ ],
103
+ },
104
+ ],
105
+ dialogueAvatarImageUri: 'avatars/blacksmith.png',
106
+ dialogueTitle: 'Apprentice Blacksmith',
107
+ idleAnimations: [ 'idle' ],
108
+ modelUri: 'models/npcs/blacksmith.gltf',
109
+ modelScale: 0.75,
110
+ name: 'Blacksmith Arden',
111
+ ...options,
112
+ })
113
+ }
114
+ }
@@ -3,6 +3,7 @@ import type BaseQuest from '../quests/BaseQuest';
3
3
  import type GamePlayer from '../GamePlayer';
4
4
  import type BaseEntity from '../entities/BaseEntity';
5
5
  import type { PlayerQuestState } from '../quests/BaseQuest';
6
+ import { ItemUIDataHelper } from '../items/ItemUIDataHelper';
6
7
 
7
8
  export type SerializedQuestLogData = {
8
9
  quests: PlayerQuestState[];
@@ -181,11 +182,7 @@ export default class QuestLog {
181
182
  description: questClass.description,
182
183
  objectives: questClass.objectives,
183
184
  reward: {
184
- items: questClass.reward.items?.map(item => ({
185
- name: item.itemClass.name,
186
- iconImageUri: item.itemClass.iconImageUri,
187
- quantity: item.quantity,
188
- })),
185
+ items: questClass.reward.items?.map(item => ItemUIDataHelper.getUIData(item.itemClass, { quantity: item.quantity })),
189
186
  skillExperience: questClass.reward.skillExperience,
190
187
  },
191
188
  state: questState
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hytopia.com/examples",
3
- "version": "1.0.12",
3
+ "version": "1.0.14",
4
4
  "description": "",
5
5
  "license": "ISC",
6
6
  "author": "",
@@ -1,31 +0,0 @@
1
- {
2
- "health": 100,
3
- "currentRegionId": "stalkhaven",
4
- "currentRegionSpawnFacingAngle": 90,
5
- "currentRegionSpawnPoint": {
6
- "x": 32,
7
- "y": 2,
8
- "z": 1
9
- },
10
- "skillExperience": [],
11
- "backpack": {
12
- "items": []
13
- },
14
- "hotbar": {
15
- "items": [
16
- {
17
- "position": 0,
18
- "itemId": "toy_sword"
19
- }
20
- ]
21
- },
22
- "questLog": {
23
- "quests": []
24
- },
25
- "storage": {
26
- "items": []
27
- },
28
- "wearables": {
29
- "items": []
30
- }
31
- }
@@ -1,25 +0,0 @@
1
- {
2
- "health": 100,
3
- "currentRegionId": "stalkhaven-port",
4
- "skillExperience": [],
5
- "backpack": {
6
- "items": []
7
- },
8
- "hotbar": {
9
- "items": [
10
- {
11
- "position": 0,
12
- "itemId": "toy_sword"
13
- }
14
- ]
15
- },
16
- "questLog": {
17
- "quests": []
18
- },
19
- "storage": {
20
- "items": []
21
- },
22
- "wearables": {
23
- "items": []
24
- }
25
- }
@@ -1,31 +0,0 @@
1
- {
2
- "health": 100,
3
- "currentRegionId": "stalkhaven-port",
4
- "currentRegionSpawnFacingAngle": 180,
5
- "currentRegionSpawnPoint": {
6
- "x": -6,
7
- "y": 8,
8
- "z": -28
9
- },
10
- "skillExperience": [],
11
- "backpack": {
12
- "items": []
13
- },
14
- "hotbar": {
15
- "items": [
16
- {
17
- "position": 0,
18
- "itemId": "toy_sword"
19
- }
20
- ]
21
- },
22
- "questLog": {
23
- "quests": []
24
- },
25
- "storage": {
26
- "items": []
27
- },
28
- "wearables": {
29
- "items": []
30
- }
31
- }
@@ -1,10 +0,0 @@
1
- import BaseItem from '../BaseItem';
2
-
3
- export default class MonsterHideItem extends BaseItem {
4
- static readonly id = 'monster_hide';
5
- static readonly name = 'Monster Hide';
6
- static readonly iconImageUri = 'icons/items/monster-hide.png';
7
- static readonly description = 'Thick hide from a Frontier beast. Tough and weathered.';
8
- static readonly stackable = true;
9
- static readonly sellPrice = 15;
10
- }