Skip to content

Commit cfdbfc6

Browse files
author
src
authored
Merge branch 'develop' into development
2 parents 59d739b + cba2a78 commit cfdbfc6

File tree

1 file changed

+107
-55
lines changed

1 file changed

+107
-55
lines changed
Lines changed: 107 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,27 @@
1-
import { itemOnObjectActionHandler } from '@engine/world/action/item-on-object.action';
1+
import { itemOnObjectActionHandler, ItemOnObjectActionHook } from '@engine/world/action/item-on-object.action';
22
import { widgets } from '@engine/config';
33
import { Skill } from '@engine/world/actor/skills';
4-
import { bars, smithables, widgetItems } from '@plugins/skills/smithing/forging-constants';
4+
import { anvilIds, bars, smithables, widgetItems } from '@plugins/skills/smithing/forging-constants';
55
import { itemIds } from '@engine/world/config/item-ids';
66
import { Smithable } from '@plugins/skills/smithing/forging-types';
7-
import { itemInteractionActionHandler } from '@engine/world/action/item-interaction.action';
8-
import { loopingEvent } from '@engine/game-server';
7+
import {
8+
ItemInteractionAction,
9+
ItemInteractionActionHook
10+
} from '@engine/world/action/item-interaction.action';
911
import { Player } from '@engine/world/actor/player/player';
1012
import { findItem } from '@engine/config';
13+
import { TaskExecutor } from '@engine/world/action';
14+
import { Position } from '@engine/world/position';
15+
16+
/**
17+
* The amount of items the player wants to forge.
18+
*/
19+
let wantedAmount = 0;
20+
21+
/**
22+
* The amount of items already forged.
23+
*/
24+
let forgedAmount = 0;
1125

1226
const mapWidgetItemsToFlatArray = (input) => {
1327
const result = [];
@@ -29,91 +43,118 @@ const mapToFlatArray = (input) => {
2943
return results;
3044
};
3145

46+
/**
47+
* Lookup a smithable from just an item id.
48+
* @param itemId
49+
*/
3250
const findSmithableByItemId = (itemId) : Smithable => {
3351
return mapToFlatArray(smithables).find((smithable) => {
3452
return smithable.item.itemId === itemId;
3553
});
3654
};
3755

38-
const smithItem: itemInteractionActionHandler = (details) => {
39-
const { player, option, itemDetails } = details;
40-
41-
const smithable = findSmithableByItemId(itemDetails.gameId);
42-
56+
/**
57+
* Check if the player is able to perform the action.
58+
* @param task
59+
*/
60+
const canActivate = (task: TaskExecutor<ItemInteractionAction>): boolean => {
61+
const { actor, player, actionData } = task.getDetails();
62+
const itemId = actionData.itemId;
63+
const smithable = findSmithableByItemId(itemId);
4364

4465
// In case the smithable doesn't exist.
4566
if (!smithable) {
46-
return;
67+
return false;
4768
}
4869

4970
// Check if the player has the level required.
5071
if (smithable.level > player.skills.getLevel(Skill.SMITHING)) {
5172
const item = findItem(smithable.item.itemId);
5273
player.sendMessage(`You have to be at least level ${smithable.level} to smith ${item.name}s.`, true);
53-
return;
74+
return false;
5475
}
5576

56-
const amountInInventory = player.inventory.findAll(smithable.ingredient.itemId).length;
77+
// Check if the player has sufficient materials.
78+
if (!hasMaterials(player, smithable)) {
79+
const bar = findItem(smithable.ingredient.itemId);
80+
player.sendMessage(`You don't have enough ${bar.name}s.`, true);
81+
return false;
82+
}
5783

58-
// Close the forging interface.
5984
player.interfaceState.closeAllSlots();
6085

61-
const loop = loopingEvent({ player: details.player });
62-
let elapsedTicks = 0;
63-
let wantedAmount = 0;
64-
let forgedAmount = 0;
86+
return true;
87+
};
88+
89+
/**
90+
* The actual forging loop.
91+
* @param task
92+
* @param taskIteration
93+
*/
94+
const activate = (task: TaskExecutor<ItemInteractionAction>, taskIteration: number): boolean => {
95+
const { player, actionData } = task.getDetails();
96+
const itemId = actionData.itemId;
97+
const smithable = findSmithableByItemId(itemId);
6598

6699
// How many? Quick and dirty.
67-
switch (option) {
100+
switch (actionData.option) {
68101
case 'make' : wantedAmount = 1; break;
69102
case 'make-5' : wantedAmount = 5; break;
70103
case 'make-10' : wantedAmount = 10; break;
71104
}
72105

73-
if (!hasIngredients(details.player, smithable)) {
74-
player.interfaceState.closeAllSlots();
75-
const bar = findItem(smithable.ingredient.itemId);
76-
player.sendMessage(`You don't have enough ${bar.name}s.`, true);
77-
}
78-
79-
loop.event.subscribe(() => {
80-
if (!hasIngredients(details.player, smithable) || wantedAmount === forgedAmount) {
81-
loop.cancel();
82-
return;
83-
}
84-
85-
if (elapsedTicks % 5 === 0) {
86-
player.playAnimation(898);
106+
for(let m=0; m<wantedAmount; m++) {
107+
player.playAnimation(898);
108+
if(taskIteration % 4 === 0) {
109+
if (!hasMaterials(player, smithable) || wantedAmount === forgedAmount) {
110+
return false;
111+
}
87112

88113
// Remove ingredients
89114
for (let i=0; i<smithable.ingredient.amount; i++) {
90115
player.inventory.removeFirst(smithable.ingredient.itemId);
91-
details.player.outgoingPackets.sendUpdateAllWidgetItems(widgets.inventory, details.player.inventory);
92116
}
93117

94118
// Add item to inventory
95-
for (let i=0; i<smithable.item.amount; i++) {
96-
player.inventory.add(smithable.item.itemId);
97-
}
119+
player.inventory.add({
120+
itemId: smithable.item.itemId, amount: smithable.item.amount
121+
});
98122

99-
// Give the experience
123+
player.outgoingPackets.sendUpdateAllWidgetItems(widgets.inventory, player.inventory);
100124
player.skills.addExp(Skill.SMITHING, smithable.experience);
101125

102126
forgedAmount++;
127+
return true;
103128
}
129+
}
104130

105-
elapsedTicks++;
106-
});
131+
// Reset the properties, and strap in for the next batch.
132+
if (forgedAmount === wantedAmount) {
133+
forgedAmount = 0;
134+
wantedAmount = 0;
135+
return false;
136+
}
107137
};
108138

109-
const hasIngredients = (player: Player, smithable: Smithable) => {
139+
/**
140+
* Checks if the player has enough materials
141+
* @param player
142+
* @param smithable
143+
*/
144+
const hasMaterials = (player: Player, smithable: Smithable) => {
110145
return smithable.ingredient.amount <= player.inventory.findAll(smithable.ingredient.itemId).length;
111146
};
112147

148+
/**
149+
* Opens the forging interface, and loads the items.
150+
* @param details
151+
*/
113152
const openForgingInterface: itemOnObjectActionHandler = (details) => {
114-
const { player, item } = details;
153+
const { player, item, object } = details;
115154
const amountInInventory = player.inventory.findAll(item).length;
116155

156+
player.face(new Position(object.x, object.y));
157+
117158
// The player does not have a hammer.
118159
if (!player.inventory.has(itemIds.hammer)) {
119160
player.sendMessage(`You need a hammer to work the metal with.`, true);
@@ -143,17 +184,28 @@ const openForgingInterface: itemOnObjectActionHandler = (details) => {
143184
});
144185
};
145186

146-
export default [
147-
{
148-
type: 'item_on_object',
149-
itemIds: [...bars.keys()],
150-
objectIds: [2783],
151-
options: ['use'],
152-
action: openForgingInterface
153-
},
154-
{
155-
type: 'item_action',
156-
itemIds: [...mapWidgetItemsToFlatArray(widgetItems)],
157-
action: smithItem
158-
}
159-
];
187+
export default {
188+
pluginId: 'rs:forging',
189+
hooks: [
190+
{
191+
type: 'item_on_object',
192+
itemIds: [...bars.keys()],
193+
objectIds: anvilIds,
194+
walkTo: true,
195+
196+
cancelOtherActions: true,
197+
handler: openForgingInterface
198+
} as ItemOnObjectActionHook,
199+
{
200+
type: 'item_interaction',
201+
itemIds: [...mapWidgetItemsToFlatArray(smithables)],
202+
options: ['make', 'make-5', 'make-10'],
203+
cancelOtherActions: true,
204+
task: {
205+
canActivate,
206+
activate,
207+
interval: 1
208+
}
209+
} as ItemInteractionActionHook
210+
]
211+
};

0 commit comments

Comments
 (0)