@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.
- package/frontiers-rpg-game/assets/icons/items/leather-boots.png +0 -0
- package/frontiers-rpg-game/assets/icons/items/leather-bracers.png +0 -0
- package/frontiers-rpg-game/assets/icons/items/leather-helmet.png +0 -0
- package/frontiers-rpg-game/assets/icons/items/leather-leggings.png +0 -0
- package/frontiers-rpg-game/assets/icons/items/leather-vest.png +0 -0
- package/frontiers-rpg-game/assets/icons/items/spiked-club.png +0 -0
- package/frontiers-rpg-game/assets/icons/skills/crafting.png +0 -0
- package/frontiers-rpg-game/assets/models/weapons/.optimized/mace/baseColor.png +0 -0
- package/frontiers-rpg-game/assets/models/weapons/.optimized/mace/mace-named-nodes.bin +0 -0
- package/frontiers-rpg-game/assets/models/weapons/.optimized/mace/mace-named-nodes.gltf +653 -0
- package/frontiers-rpg-game/assets/models/weapons/.optimized/mace/mace.bin +0 -0
- package/frontiers-rpg-game/assets/models/weapons/.optimized/mace/mace.gltf +135 -0
- package/frontiers-rpg-game/assets/models/weapons/.optimized/mace/mace.gltf.md5 +1 -0
- package/frontiers-rpg-game/assets/models/weapons/.optimized/spiked-club/baseColor.png +0 -0
- package/frontiers-rpg-game/assets/models/weapons/.optimized/spiked-club/spiked-club-named-nodes.bin +0 -0
- package/frontiers-rpg-game/assets/models/weapons/.optimized/spiked-club/spiked-club-named-nodes.gltf +840 -0
- package/frontiers-rpg-game/assets/models/weapons/.optimized/spiked-club/spiked-club.bin +0 -0
- package/frontiers-rpg-game/assets/models/weapons/.optimized/spiked-club/spiked-club.gltf +141 -0
- package/frontiers-rpg-game/assets/models/weapons/.optimized/spiked-club/spiked-club.gltf.md5 +1 -0
- package/frontiers-rpg-game/assets/models/weapons/mace.gltf +1 -0
- package/frontiers-rpg-game/assets/ui/build.js +2 -0
- package/frontiers-rpg-game/assets/ui/index.html +1328 -64
- package/frontiers-rpg-game/assets/ui/menus/crafting.html +976 -0
- package/frontiers-rpg-game/assets/ui/menus/quests.html +70 -2
- package/frontiers-rpg-game/assets/ui/shared/item-stats.html +224 -0
- package/frontiers-rpg-game/assets/ui/shared/item-tooltips.html +72 -81
- package/frontiers-rpg-game/dev/persistence/player-player-1.json +120 -11
- package/frontiers-rpg-game/src/GamePlayer.ts +53 -0
- package/frontiers-rpg-game/src/GamePlayerEntity.ts +9 -2
- package/frontiers-rpg-game/src/config.ts +7 -0
- package/frontiers-rpg-game/src/entities/BaseCraftingEntity.ts +115 -0
- package/frontiers-rpg-game/src/entities/enemies/RatkinBruteEntity.ts +2 -0
- package/frontiers-rpg-game/src/entities/enemies/RatkinRangerEntity.ts +2 -0
- package/frontiers-rpg-game/src/entities/enemies/RatkinSpellcasterEntity.ts +2 -0
- package/frontiers-rpg-game/src/entities/enemies/RatkinWarriorEntity.ts +2 -0
- package/frontiers-rpg-game/src/entities/enemies/TaintedRatkinBruteEntity.ts +2 -0
- package/frontiers-rpg-game/src/entities/enemies/TaintedRatkinRangerEntity.ts +2 -1
- package/frontiers-rpg-game/src/entities/enemies/TaintedRatkinSpellcasterEntity.ts +2 -0
- package/frontiers-rpg-game/src/entities/enemies/TaintedRatkinWarriorEntity.ts +2 -0
- package/frontiers-rpg-game/src/entities/forageables/DecayingPileEntity.ts +2 -2
- package/frontiers-rpg-game/src/entities/forageables/RottenLogEntity.ts +2 -2
- package/frontiers-rpg-game/src/items/BaseWeaponItem.ts +2 -2
- package/frontiers-rpg-game/src/items/ItemClasses.ts +14 -2
- package/frontiers-rpg-game/src/items/materials/RawHideItem.ts +10 -0
- package/frontiers-rpg-game/src/items/weapons/DullSwordItem.ts +5 -4
- package/frontiers-rpg-game/src/items/weapons/IronDaggerItem.ts +1 -1
- package/frontiers-rpg-game/src/items/weapons/IronLongSwordItem.ts +5 -4
- package/frontiers-rpg-game/src/items/weapons/SpikedClubItem.ts +26 -0
- package/frontiers-rpg-game/src/items/weapons/TrainingSwordItem.ts +5 -4
- package/frontiers-rpg-game/src/items/wearables/LeatherBootsItem.ts +14 -0
- package/frontiers-rpg-game/src/items/wearables/LeatherBracersItem.ts +14 -0
- package/frontiers-rpg-game/src/items/wearables/LeatherHelmetItem.ts +14 -0
- package/frontiers-rpg-game/src/items/wearables/LeatherLeggingsItem.ts +14 -0
- package/frontiers-rpg-game/src/items/wearables/LeatherVestItem.ts +14 -0
- package/frontiers-rpg-game/src/quests/BaseQuest.ts +1 -2
- package/frontiers-rpg-game/src/quests/QuestClasses.ts +2 -0
- package/frontiers-rpg-game/src/quests/side/FungalForagingQuest.ts +1 -23
- package/frontiers-rpg-game/src/quests/side/HammersAndCraftingQuest.ts +139 -0
- package/frontiers-rpg-game/src/regions/stalkhaven/StalkhavenRegion.ts +35 -22
- package/frontiers-rpg-game/src/regions/stalkhaven/npcs/BlacksmithArdenEntity.ts +114 -0
- package/frontiers-rpg-game/src/systems/QuestLog.ts +2 -5
- package/package.json +1 -1
- package/frontiers-rpg-game/dev/persistence/player-player-2.json +0 -31
- package/frontiers-rpg-game/dev/persistence/player-player-3.json +0 -25
- package/frontiers-rpg-game/dev/persistence/player-player-4.json +0 -31
- package/frontiers-rpg-game/src/items/materials/MonsterHideItem.ts +0 -10
- /package/frontiers-rpg-game/assets/icons/items/{monster-hide.png → raw-hide.png} +0 -0
- /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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
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
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
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,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
|
-
}
|
|
File without changes
|
|
File without changes
|