-
Notifications
You must be signed in to change notification settings - Fork 83
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
item on npc, and abusing sheep #111
Changes from 1 commit
350f80f
a888ef2
b3bc14d
dc203e6
8da020a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
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'; | ||
import { World } from '@server/world/world'; | ||
import { npcAction } from '@server/world/actor/player/action/npc-action'; | ||
import { itemOnNpcAction } from '@server/world/actor/player/action/item-on-npc-action'; | ||
|
||
export const itemOnNpcPacket: incomingPacket = (player: Player, packetId: number, packetSize: number, packet: RsBuffer): void => { | ||
const npcIndex = packet.readNegativeOffsetShortBE(); | ||
const itemId = packet.readNegativeOffsetShortBE(); | ||
const itemSlot = packet.readNegativeOffsetShortLE(); | ||
const itemWidgetId = packet.readShortBE(); | ||
const itemContainerId = packet.readShortBE(); | ||
|
||
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}`); | ||
} | ||
|
||
|
||
if (npcIndex < 0 || npcIndex > World.MAX_NPCS - 1) { | ||
return; | ||
} | ||
|
||
const npc = world.npcList[npcIndex]; | ||
if (!npc) { | ||
return; | ||
} | ||
|
||
const position = npc.position; | ||
const distance = Math.floor(position.distanceBetween(player.position)); | ||
|
||
// Too far away | ||
if (distance > 16) { | ||
return; | ||
} | ||
|
||
itemOnNpcAction(player, npc, position, usedItem, itemWidgetId, itemContainerId); | ||
|
||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
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 { itemOnNpcAction } from '@server/world/actor/player/action/item-on-npc-action'; | ||
|
||
|
||
export const action: itemOnNpcAction = (details) => { | ||
details.player.busy = true; | ||
details.player.playAnimation(893); | ||
details.player.outgoingPackets.playSound(761, 5); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add to |
||
|
||
setTimeout(() => { | ||
if (Math.random() >= 0.66) { | ||
details.player.outgoingPackets.chatboxMessage('The sheep manages to get away from you!'); | ||
// TODO: sheep says baa!, makes baa sound and goes backwards about 5 tiles | ||
} else { | ||
details.player.outgoingPackets.chatboxMessage('You get some wool.'); | ||
details.player.giveItem(1737); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add to |
||
// TODO: sheep says baa!, makes baa sound and gets replaces with skinned sheep | ||
|
||
} | ||
details.player.busy = false; | ||
}, World.TICK_LENGTH); | ||
|
||
}; | ||
|
||
export default new RunePlugin({ | ||
type: ActionType.ITEM_ON_NPC_ACTION, | ||
npcsIds: [43], | ||
itemIds: [1735, 5603], | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add to |
||
walkTo: true, | ||
action | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
import { Player } from '@server/world/actor/player/player'; | ||
import { Position } from '@server/world/position'; | ||
import { walkToAction } from '@server/world/actor/player/action/action'; | ||
import { pluginFilter } from '@server/plugins/plugin-loader'; | ||
import { logger } from '@runejs/logger/dist/logger'; | ||
import { ActionPlugin } from '@server/plugins/plugin'; | ||
import { Item } from '@server/world/items/item'; | ||
import { Npc } from '@server/world/actor/npc/npc'; | ||
|
||
/** | ||
* The definition for an item on npc action function. | ||
*/ | ||
export type itemOnNpcAction = (details: ItemOnNpcActionDetails) => void; | ||
|
||
/** | ||
* Details about an npc being interacted with. and the item being used. | ||
*/ | ||
export interface ItemOnNpcActionDetails { | ||
player: Player; | ||
npc: Npc; | ||
position: Position; | ||
item: Item; | ||
itemWidgetId: number; | ||
itemContainerId: number; | ||
} | ||
|
||
/** | ||
* Defines an item on npc interaction plugin. | ||
* A list of npc ids that apply to the plugin, the items that can be performed on, | ||
* and whether or not the player must first walk to the npc. | ||
*/ | ||
export interface ItemOnNpcActionPlugin extends ActionPlugin { | ||
npcsIds: number | number[]; | ||
itemIds: number | number[]; | ||
walkTo: boolean; | ||
action: itemOnNpcAction; | ||
} | ||
|
||
/** | ||
* A directory of all item on npc interaction plugins. | ||
*/ | ||
let itemOnNpcInteractions: ItemOnNpcActionPlugin[] = []; | ||
|
||
/** | ||
* Sets the list of item on npc interaction plugins. | ||
* @param plugins The plugin list. | ||
*/ | ||
export const setItemOnNpcPlugins = (plugins: ActionPlugin[]): void => { | ||
itemOnNpcInteractions = plugins as ItemOnNpcActionPlugin[]; | ||
}; | ||
|
||
// @TODO priority and cancelling other (lower priority) actions | ||
export const itemOnNpcAction = (player: Player, npc: Npc, | ||
position: Position, item: Item, itemWidgetId: number, itemContainerId: number): void => { | ||
if (player.busy) { | ||
return; | ||
} | ||
|
||
// Find all item on npc action plugins that reference this landscape object | ||
let interactionPlugins = itemOnNpcInteractions.filter(plugin => pluginFilter(plugin.npcsIds, npc.id)); | ||
|
||
// Find all item on npc action plugins that reference this item | ||
if (interactionPlugins.length !== 0) { | ||
interactionPlugins = interactionPlugins.filter(plugin => pluginFilter(plugin.itemIds, item.itemId)); | ||
} | ||
|
||
if (interactionPlugins.length === 0) { | ||
player.outgoingPackets.chatboxMessage(`Unhandled item on npc interaction: ${item.itemId} on ${npc.name} ` + | ||
`(id-${npc.id}) @ ${position.x},${position.y},${position.level}`); | ||
return; | ||
} | ||
|
||
player.actionsCancelled.next(); | ||
|
||
// Separate out walk-to actions from immediate actions | ||
const walkToPlugins = interactionPlugins.filter(plugin => plugin.walkTo); | ||
const immediatePlugins = interactionPlugins.filter(plugin => !plugin.walkTo); | ||
|
||
// Make sure we walk to the npc before running any of the walk-to plugins | ||
if (walkToPlugins.length !== 0) { | ||
walkToAction(player, position) | ||
.then(() => { | ||
player.face(position); | ||
|
||
walkToPlugins.forEach(plugin => | ||
plugin.action({ | ||
player, | ||
npc, | ||
position, | ||
item, | ||
itemWidgetId, | ||
itemContainerId | ||
})); | ||
}) | ||
.catch(() => logger.warn(`Unable to complete walk-to action.`)); | ||
} | ||
|
||
// Immediately run any non-walk-to plugins | ||
if (immediatePlugins.length !== 0) { | ||
immediatePlugins.forEach(plugin => | ||
plugin.action({ | ||
player, | ||
npc, | ||
position, | ||
item, | ||
itemWidgetId, | ||
itemContainerId | ||
})); | ||
} | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add to
animation-ids.ts