|
1 |
| -import { itemOnObjectActionHandler } from '@engine/world/action/item-on-object.action'; |
| 1 | +import { itemOnObjectActionHandler, ItemOnObjectActionHook } from '@engine/world/action/item-on-object.action'; |
2 | 2 | import { widgets } from '@engine/config';
|
3 | 3 | 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'; |
5 | 5 | import { itemIds } from '@engine/world/config/item-ids';
|
6 | 6 | 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'; |
9 | 11 | import { Player } from '@engine/world/actor/player/player';
|
10 | 12 | import { findItem } from '@engine/config';
|
| 13 | +import { TaskExecutor } from '@engine/world/action'; |
11 | 14 |
|
12 | 15 | const mapWidgetItemsToFlatArray = (input) => {
|
13 | 16 | const result = [];
|
@@ -35,75 +38,84 @@ const findSmithableByItemId = (itemId) : Smithable => {
|
35 | 38 | });
|
36 | 39 | };
|
37 | 40 |
|
38 |
| -const smithItem: itemInteractionActionHandler = (details) => { |
39 |
| - const { player, option, itemDetails } = details; |
| 41 | +const canActivate = (task: TaskExecutor<ItemInteractionAction>): boolean => { |
| 42 | + const { actor, player, actionData, session } = task.getDetails(); |
40 | 43 |
|
41 |
| - const smithable = findSmithableByItemId(itemDetails.gameId); |
| 44 | + const itemId = actionData.itemId; |
| 45 | + |
| 46 | + const smithable = findSmithableByItemId(itemId); |
42 | 47 |
|
43 | 48 |
|
44 | 49 | // In case the smithable doesn't exist.
|
45 | 50 | if (!smithable) {
|
46 |
| - return; |
| 51 | + return false; |
47 | 52 | }
|
48 | 53 |
|
49 | 54 | // Check if the player has the level required.
|
50 | 55 | if (smithable.level > player.skills.getLevel(Skill.SMITHING)) {
|
51 | 56 | const item = findItem(smithable.item.itemId);
|
52 | 57 | player.sendMessage(`You have to be at least level ${smithable.level} to smith ${item.name}s.`, true);
|
53 |
| - return; |
| 58 | + return false; |
54 | 59 | }
|
55 | 60 |
|
56 | 61 | const amountInInventory = player.inventory.findAll(smithable.ingredient.itemId).length;
|
| 62 | + // @todo: Forging: Make a check for sufficient bars in the inventory. |
57 | 63 |
|
58 |
| - // Close the forging interface. |
59 |
| - player.interfaceState.closeAllSlots(); |
| 64 | + if (!hasIngredients(player, smithable)) { |
| 65 | + player.interfaceState.closeAllSlots(); |
| 66 | + const bar = findItem(smithable.ingredient.itemId); |
| 67 | + player.sendMessage(`You don't have enough ${bar.name}s.`, true); |
| 68 | + return false; |
| 69 | + } |
60 | 70 |
|
61 |
| - const loop = loopingEvent({ player: details.player }); |
62 |
| - let elapsedTicks = 0; |
63 |
| - let wantedAmount = 0; |
64 |
| - let forgedAmount = 0; |
| 71 | + return true; |
| 72 | +}; |
| 73 | + |
| 74 | +let wantedAmount = 0; |
| 75 | +let forgedAmount = 0; |
| 76 | + |
| 77 | +const activate = (task: TaskExecutor<ItemInteractionAction>, taskIteration: number): boolean => { |
| 78 | + const { player, actionData } = task.getDetails(); |
| 79 | + |
| 80 | + const itemId = actionData.itemId; |
| 81 | + |
| 82 | + const smithable = findSmithableByItemId(itemId); |
65 | 83 |
|
66 | 84 | // How many? Quick and dirty.
|
67 |
| - switch (option) { |
| 85 | + switch (actionData.option) { |
68 | 86 | case 'make' : wantedAmount = 1; break;
|
69 | 87 | case 'make-5' : wantedAmount = 5; break;
|
70 | 88 | case 'make-10' : wantedAmount = 10; break;
|
71 | 89 | }
|
72 | 90 |
|
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 |
| - } |
| 91 | + player.interfaceState.closeAllSlots(); |
| 92 | + player.playAnimation(898); |
78 | 93 |
|
79 |
| - loop.event.subscribe(() => { |
80 |
| - if (!hasIngredients(details.player, smithable) || wantedAmount === forgedAmount) { |
81 |
| - loop.cancel(); |
82 |
| - return; |
| 94 | + if(taskIteration % 4 === 0 && taskIteration != 0) { |
| 95 | + if (!hasIngredients(player, smithable) || wantedAmount === forgedAmount) { |
| 96 | + return false; |
83 | 97 | }
|
84 | 98 |
|
85 |
| - if (elapsedTicks % 5 === 0) { |
86 |
| - player.playAnimation(898); |
87 |
| - |
88 |
| - // Remove ingredients |
89 |
| - for (let i=0; i<smithable.ingredient.amount; i++) { |
90 |
| - player.inventory.removeFirst(smithable.ingredient.itemId); |
91 |
| - details.player.outgoingPackets.sendUpdateAllWidgetItems(widgets.inventory, details.player.inventory); |
92 |
| - } |
| 99 | + // Remove ingredients |
| 100 | + for (let i=0; i<smithable.ingredient.amount; i++) { |
| 101 | + player.inventory.removeFirst(smithable.ingredient.itemId); |
| 102 | + player.outgoingPackets.sendUpdateAllWidgetItems(widgets.inventory, player.inventory); |
| 103 | + } |
93 | 104 |
|
94 |
| - // Add item to inventory |
95 |
| - for (let i=0; i<smithable.item.amount; i++) { |
96 |
| - player.inventory.add(smithable.item.itemId); |
97 |
| - } |
| 105 | + // Add item to inventory |
| 106 | + for (let i=0; i<smithable.item.amount; i++) { |
| 107 | + player.inventory.add(smithable.item.itemId); |
| 108 | + } |
98 | 109 |
|
99 |
| - // Give the experience |
100 |
| - player.skills.addExp(Skill.SMITHING, smithable.experience); |
| 110 | + // Give the experience |
| 111 | + player.skills.addExp(Skill.SMITHING, smithable.experience); |
101 | 112 |
|
102 |
| - forgedAmount++; |
103 |
| - } |
| 113 | + forgedAmount++; |
| 114 | + } |
| 115 | +}; |
104 | 116 |
|
105 |
| - elapsedTicks++; |
106 |
| - }); |
| 117 | +const onComplete = (task: TaskExecutor<ItemInteractionAction>): void => { |
| 118 | + task.actor.stopAnimation(); |
107 | 119 | };
|
108 | 120 |
|
109 | 121 | const hasIngredients = (player: Player, smithable: Smithable) => {
|
@@ -143,17 +155,28 @@ const openForgingInterface: itemOnObjectActionHandler = (details) => {
|
143 | 155 | });
|
144 | 156 | };
|
145 | 157 |
|
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 |
| -]; |
| 158 | +export default { |
| 159 | + pluginId: 'rs:forging', |
| 160 | + hooks: [ |
| 161 | + { |
| 162 | + type: 'item_on_object', |
| 163 | + itemIds: [...bars.keys()], |
| 164 | + objectIds: anvilIds, |
| 165 | + walkTo: true, |
| 166 | + cancelOtherActions: true, |
| 167 | + handler: openForgingInterface |
| 168 | + } as ItemOnObjectActionHook, |
| 169 | + { |
| 170 | + type: 'item_interaction', |
| 171 | + itemIds: [...mapWidgetItemsToFlatArray(smithables)], |
| 172 | + options: ['make', 'make-5', 'make-10'], |
| 173 | + cancelOtherActions: true, |
| 174 | + task: { |
| 175 | + canActivate, |
| 176 | + activate, |
| 177 | + onComplete, |
| 178 | + interval: 1 |
| 179 | + } |
| 180 | + } as ItemInteractionActionHook |
| 181 | + ] |
| 182 | +}; |
0 commit comments