Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/game-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { setCommandPlugins } from '@server/world/actor/player/action/input-comma
import { setWidgetPlugins } from '@server/world/actor/player/action/widget-action';
import { setItemPlugins } from '@server/world/actor/player/action/item-action';
import { setWorldItemPlugins } from '@server/world/actor/player/action/world-item-action';
import { setItemOnObjectPlugins } from '@server/world/actor/player/action/item-on-object-action';

export let serverConfig: ServerConfig;
export let gameCache377: EarlyFormatGameCache;
Expand All @@ -40,6 +41,7 @@ export async function injectPlugins(): Promise<void> {
setButtonPlugins(actionTypes[ActionType.BUTTON]);
setNpcPlugins(actionTypes[ActionType.NPC_ACTION]);
setObjectPlugins(actionTypes[ActionType.OBJECT_ACTION]);
setItemOnObjectPlugins(actionTypes[ActionType.ITEM_ON_OBJECT_ACTION]);
setItemOnItemPlugins(actionTypes[ActionType.ITEM_ON_ITEM]);
setItemPlugins(actionTypes[ActionType.ITEM_ACTION]);
setWorldItemPlugins(actionTypes[ActionType.WORLD_ITEM_ACTION]);
Expand Down
2 changes: 2 additions & 0 deletions src/net/incoming-packet-directory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { itemOnItemPacket } from '@server/net/incoming-packets/item-on-item-pack
import { widgetsClosedPacket } from '@server/net/incoming-packets/widgets-closed-packet';
import { pickupItemPacket } from '@server/net/incoming-packets/pickup-item-packet';
import { itemInteractionPacket } from '@server/net/incoming-packets/item-interaction-packet';
import { itemOnObjectPacket } from '@server/net/incoming-packets/item-on-object-packet';

const ignore = [ 234, 160, 58 /* camera move */ ];

Expand Down Expand Up @@ -47,6 +48,7 @@ const packets: { [key: number]: incomingPacket } = {

63: npcInteractionPacket,
116: npcInteractionPacket,
24: itemOnObjectPacket,

30: objectInteractionPacket,
164: objectInteractionPacket,
Expand Down
63 changes: 63 additions & 0 deletions src/net/incoming-packets/item-on-object-packet.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { incomingPacket } from '../incoming-packet';
import { Player } from '../../world/actor/player/player';
import { RsBuffer } from '@server/net/rs-buffer';
import { widgets } from '@server/world/config/widget';
import { logger } from '@runejs/logger/dist/logger';
import { itemOnItemAction } from '@server/world/actor/player/action/item-on-item-action';
import { Position } from '@server/world/position';
import { gameCache, world } from '@server/game-server';
import { objectAction } from '@server/world/actor/player/action/object-action';
import { itemOnObjectAction } from '@server/world/actor/player/action/item-on-object-action';

export const itemOnObjectPacket: incomingPacket = (player: Player, packetId: number, packetSize: number, packet: RsBuffer): void => {
const objectY = packet.readNegativeOffsetShortLE();
const itemId = packet.readNegativeOffsetShortBE();
const objectId = packet.readUnsignedShortLE();
const itemSlot = packet.readNegativeOffsetShortLE();
const itemWidgetId = packet.readShortLE();
const itemContainerId = packet.readShortLE();
const objectX = packet.readNegativeOffsetShortLE();

let usedItem;
if (itemWidgetId === widgets.inventory.widgetId && itemContainerId === widgets.inventory.containerId) {
if (itemSlot < 0 || itemSlot > 27) {
return;
}

usedItem = player.inventory.items[itemSlot];
if (!usedItem) {
return;
}

if (usedItem.itemId !== itemId) {
return;
}
} else {
logger.warn(`Unhandled item on object case using widget ${itemWidgetId}:${itemContainerId}`);
}
const level = player.position.level;

const objectPosition = new Position(objectX, objectY, level);
const objectChunk = world.chunkManager.getChunkForWorldPosition(objectPosition);
let cacheOriginal: boolean = true;

let landscapeObject = objectChunk.getCacheObject(objectId, objectPosition);
if (!landscapeObject) {
landscapeObject = objectChunk.getAddedObject(objectId, objectPosition);
cacheOriginal = false;

if (!landscapeObject) {
return;
}
}

if (objectChunk.getRemovedObject(objectId, objectPosition)) {
return;
}

const landscapeObjectDefinition = gameCache.landscapeObjectDefinitions.get(objectId);


itemOnObjectAction(player, landscapeObject, landscapeObjectDefinition, objectPosition, usedItem, itemWidgetId, itemContainerId, cacheOriginal);

};
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,22 @@ export const action: itemAction = (details) => {

inventory.remove(itemSlot);
player.outgoingPackets.playSound(soundIds.emptyBucket, 5);
player.giveItem(itemIds.bucket);
switch (itemId) {
case itemIds.jugOfWater:
player.giveItem(itemIds.jug);
break;
default:
player.giveItem(itemIds.bucket);
break;
}
player.outgoingPackets.sendUpdateAllWidgetItems(widgets.inventory, inventory);
};

export default new RunePlugin({
type: ActionType.ITEM_ACTION,
widgets: widgets.inventory,
options: 'empty',
itemIds: [itemIds.bucketOfMilk, itemIds.bucketOfWater],
itemIds: [itemIds.bucketOfMilk, itemIds.bucketOfWater, itemIds.jugOfWater],
action,
cancelOtherActions: false
});
43 changes: 43 additions & 0 deletions src/plugins/items/buckets/fill-container-plugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { itemOnObjectAction } from '@server/world/actor/player/action/item-on-object-action';
import { gameCache } from '@server/game-server';
import { itemIds } from '@server/world/config/item-ids';
import { animationIds } from '@server/world/config/animation-ids';
import { soundIds } from '@server/world/config/sound-ids';
import { ActionType, RunePlugin } from '@server/plugins/plugin';

const FountainIds: number[] = [879];
const SinkIds: number[] = [14878, 873];
const WellIds: number[] = [878];
export const action: itemOnObjectAction = (details) => {
const {player, objectDefinition, item} = details;
const itemDef = gameCache.itemDefinitions.get(item.itemId);
if (item.itemId !== itemIds.bucket && WellIds.indexOf(objectDefinition.id) > -1) {
player.outgoingPackets.chatboxMessage(`If I drop my ${itemDef.name.toLowerCase()} down there, I don't think I'm likely to get it back.`);
return;
}

player.playAnimation(animationIds.fillContainerWithWater);
player.outgoingPackets.playSound(soundIds.fillContainerWithWater, 7);
player.removeFirstItem(item.itemId);
switch (item.itemId) {
case itemIds.bucket:
player.giveItem(itemIds.bucketOfWater);
break;
case itemIds.jug:
player.giveItem(itemIds.jugOfWater);
break;


}

player.outgoingPackets.chatboxMessage(`You fill the ${itemDef.name.toLowerCase()} from the ${objectDefinition.name.toLowerCase()}.`);

};

export default new RunePlugin({
type: ActionType.ITEM_ON_OBJECT_ACTION,
objectIds: [...FountainIds, ...WellIds, ...SinkIds],
itemIds: [itemIds.bucket, itemIds.jug],
walkTo: true,
action
});
30 changes: 30 additions & 0 deletions src/plugins/items/pots/empty-pot-plugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { getItemFromContainer, itemAction } from '@server/world/actor/player/action/item-action';
import { widgets } from '@server/world/config/widget';
import { soundIds } from '@server/world/config/sound-ids';
import { ActionType, RunePlugin } from '@server/plugins/plugin';
import { itemIds } from '@server/world/config/item-ids';

export const action: itemAction = (details) => {
const {player, itemId, itemSlot} = details;

const inventory = player.inventory;
const item = getItemFromContainer(itemId, itemSlot, inventory);

if (!item) {
// The specified item was not found in the specified slot.
return;
}

inventory.remove(itemSlot);
player.outgoingPackets.playSound(soundIds.potContentModified, 5);
player.giveItem(itemIds.pot);
};

export default new RunePlugin({
type: ActionType.ITEM_ACTION,
widgets: widgets.inventory,
options: 'empty',
itemIds: [itemIds.potOfFlour],
action,
cancelOtherActions: false
});
27 changes: 19 additions & 8 deletions src/plugins/objects/cows/cow-plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export const action: objectAction = (details) => {
player.outgoingPackets.playSound(soundIds.milkCow, 7);
player.removeFirstItem(itemIds.bucket);
player.giveItem(itemIds.bucketOfMilk);
player.outgoingPackets.chatboxMessage(`You ${option} the ${objectDefinition.name} and receive some milk.`);
player.outgoingPackets.chatboxMessage(`You milk the ${objectDefinition.name} and receive some milk.`);
} else {
dialogueAction(player)
.then(d => d.npc(npcIds.gillieGroats, DialogueEmote.LAUGH_1, [`Tee hee! You've never milked a cow before, have you?`]))
Expand All @@ -33,10 +33,21 @@ export const action: objectAction = (details) => {
}
};

export default new RunePlugin({
type: ActionType.OBJECT_ACTION,
objectIds: objectIds.milkableCow,
options: 'milk',
walkTo: true,
action
});
export default new RunePlugin(
[
{
type: ActionType.OBJECT_ACTION,
objectIds: objectIds.milkableCow,
options: 'milk',
walkTo: true,
action
},
{
type: ActionType.ITEM_ON_OBJECT_ACTION,
objectIds: objectIds.milkableCow,
itemIds: itemIds.bucket,
options: 'milk',
walkTo: true,
action
}
]);
49 changes: 49 additions & 0 deletions src/plugins/objects/mill/flour-bin-plugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { World } from '@server/world/world';
import { ActionType, RunePlugin } from '@server/plugins/plugin';
import { itemIds } from '@server/world/config/item-ids';
import { itemOnObjectAction } from '@server/world/actor/player/action/item-on-object-action';
import { objectAction } from '@server/world/actor/player/action/object-action';
import { gameCache } from '@server/game-server';
import { animationIds } from '@server/world/config/animation-ids';
import { soundIds } from '@server/world/config/sound-ids';
import { dialogueAction, DialogueEmote } from '@server/world/actor/player/action/dialogue-action';
import { npcIds } from '@server/world/config/npc-ids';


export const action: objectAction = (details) => {
const {player, objectDefinition} = details;

if (!details.player.metadata['flour']) {
player.outgoingPackets.chatboxMessage(`The ${objectDefinition.name.toLowerCase()} is already empty. You need to place wheat in the hopper upstairs `);
player.outgoingPackets.chatboxMessage(`first.`);
return;
}
const emptyBucketItem = gameCache.itemDefinitions.get(itemIds.pot);

if (player.hasItemInInventory(itemIds.pot)) {
player.outgoingPackets.playSound(soundIds.potContentModified, 7);
player.removeFirstItem(itemIds.pot);
player.giveItem(itemIds.potOfFlour);
details.player.metadata['flour'] -= 1;
} else {
player.outgoingPackets.chatboxMessage(`You need a pot to hold the flour in.`);
}
};

export default new RunePlugin([
{
type: ActionType.ITEM_ON_OBJECT_ACTION,
objectIds: [1782],
itemIds: [itemIds.pot],
options: ['empty'],
walkTo: true,
action
},
{
type: ActionType.OBJECT_ACTION,
objectIds: [1782],
options: ['empty'],
walkTo: true,
action
}
]);
32 changes: 23 additions & 9 deletions src/plugins/objects/mill/hopper-controls-plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,27 @@ import { world } from '@server/game-server';
import { Position } from '@server/world/position';
import { LandscapeObject } from '@runejs/cache-parser';
import { ActionType, RunePlugin } from '@server/plugins/plugin';
import { logger } from '@runejs/logger/dist/logger';


export const action: objectAction = (details) => {
if (details.player.metadata['busy']) {
return;
}

if ((details.player.metadata['flour'] && details.player.metadata['flour'] === 30) ||
(details.player.metadata['flour'] && details.player.metadata['grain'] &&
details.player.metadata['flour'] + details.player.metadata['grain'] >= 30)) {
details.player.outgoingPackets.chatboxMessage(`There is currently too much flour in the flour bin.`);
return;
}
details.player.metadata['busy'] = true;
details.player.playAnimation(832);
details.player.playAnimation(3571);
details.player.outgoingPackets.playSound(2400, 5);
const newHopper = {
objectId: 2722,
x: details.object.x,
y: details.object.y,
level: details.object.level,
type: details.object.type,
rotation: details.object.rotation
};
world.chunkManager.addTemporaryLandscapeObject(newHopper, details.position, 1);


setTimeout(() => {
if (details.player.metadata['grain'] && details.player.metadata['grain'] >= 1) {
Expand All @@ -29,8 +35,10 @@ export const action: objectAction = (details) => {
details.player.metadata['flour'] += details.player.metadata['grain'];
details.player.metadata['grain'] = 0;
const flourBinPos = new Position(3166, 3306);
const fullFlourBin: LandscapeObject = {objectId: 1782, x: 3166, y:3306, rotation: 0, level: 0, type: 10};
const fullFlourBin: LandscapeObject = {objectId: 1782, x: 3166, y: 3306, rotation: 0, level: 0, type: 10};
world.chunkManager.addLandscapeObject(fullFlourBin, flourBinPos);


} else {
details.player.outgoingPackets.chatboxMessage(`You operate the hopper. Nothing interesting happens.`);
}
Expand All @@ -39,4 +47,10 @@ export const action: objectAction = (details) => {

};

export default new RunePlugin({ type: ActionType.OBJECT_ACTION, objectIds: [2718], options: ['operate'], walkTo: true, action });
export default new RunePlugin({
type: ActionType.OBJECT_ACTION,
objectIds: [2718],
options: ['operate'],
walkTo: true,
action
});
33 changes: 33 additions & 0 deletions src/plugins/objects/mill/hopper-plugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { World } from '@server/world/world';
import { ActionType, RunePlugin } from '@server/plugins/plugin';
import { itemIds } from '@server/world/config/item-ids';
import { itemOnObjectAction } from '@server/world/actor/player/action/item-on-object-action';


export const action: itemOnObjectAction = (details) => {

if ((details.player.metadata['grain'] && details.player.metadata['grain'] === 1)) {
details.player.outgoingPackets.chatboxMessage(`There is already grain in the hopper.`);
return;
}
details.player.metadata['busy'] = true;
details.player.playAnimation(3572);
details.player.outgoingPackets.playSound(2576, 5);

setTimeout(() => {
details.player.removeFirstItem(itemIds.grain);
details.player.outgoingPackets.chatboxMessage(`You put the grain in the hopper. You should now pull the lever nearby to operate`);
details.player.outgoingPackets.chatboxMessage(`the hopper.`);
details.player.metadata['grain'] = 1;
details.player.metadata['busy'] = false;
}, World.TICK_LENGTH);

};

export default new RunePlugin({
type: ActionType.ITEM_ON_OBJECT_ACTION,
objectIds: [2714],
itemIds: [itemIds.grain],
walkTo: true,
action
});
1 change: 1 addition & 0 deletions src/plugins/objects/pickables/pickables-plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export const action: objectAction = (details) => {
const pickedItem = gameCache.itemDefinitions.get(itemId);
setTimeout(() => {
details.player.outgoingPackets.chatboxMessage(`You ${details.option} the ${details.objectDefinition.name.toLowerCase()} and receive ${prefix} ${pickedItem.name.toLowerCase()}.`);
details.player.outgoingPackets.playSound(2581, 7);
if (details.objectDefinition.name !== 'Flax' || Math.floor(Math.random() * 10) === 1) {
world.chunkManager.removeLandscapeObjectTemporarily(details.object, details.position, 30);
}
Expand Down
Loading