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
13 changes: 13 additions & 0 deletions src/net/rs-buffer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,12 @@ export class RsBuffer {
this.writeUnsignedByte(value >> 8);
}

public writeMediumME(value: number): void {
this.writeUnsignedByte(value >> 8);
this.writeUnsignedByte(value >> 16);
this.writeUnsignedByte(value);
}

public writeIntLE(value: number): void {
this.buffer.writeInt32LE(value, this.writerIndex);
this.writerIndex += 4;
Expand All @@ -273,6 +279,13 @@ export class RsBuffer {
this.writerIndex += 4;
}

public writeIntME1(value: number): void {
this.writeUnsignedByte((value >> 8) & 0xff);
this.writeUnsignedByte(value & 0xff);
this.writeUnsignedByte((value >> 24) & 0xff);
this.writeUnsignedByte((value >> 16) & 0xff);
}

public writeLongBE(value: bigint): void {
this.buffer.writeBigInt64BE(value, this.writerIndex);
this.writerIndex += 8;
Expand Down
3 changes: 3 additions & 0 deletions src/world/mob/mob.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { ItemContainer } from '../items/item-container';
import { UpdateFlags } from './update-flags';
import { Npc } from './npc/npc';
import { Entity } from '../entity';
import { Skills } from '@server/world/mob/skills';

/**
* Handles a mobile entity within the game world.
Expand All @@ -16,6 +17,7 @@ export abstract class Mob extends Entity {
private _runDirection: number;
private _faceDirection: number;
private readonly _inventory: ItemContainer;
public readonly skills: Skills;

protected constructor() {
super();
Expand All @@ -25,6 +27,7 @@ export abstract class Mob extends Entity {
this._runDirection = -1;
this._faceDirection = -1;
this._inventory = new ItemContainer(28);
this.skills = new Skills(this);
}

public initiateRandomMovement(): void {
Expand Down
24 changes: 21 additions & 3 deletions src/world/mob/player/action/dialogue/dialogue-action.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Player } from '@server/world/mob/player/player';
import { gameCache } from '@server/game-server';
import { Npc } from '@server/world/mob/npc/npc';
import { skillDetails } from '@server/world/mob/skills';

const interfaceIds = {
PLAYER: [ 968, 973, 979, 986 ],
Expand All @@ -11,7 +12,8 @@ const interfaceIds = {
const lineConstraints = {
PLAYER: [ 1, 4 ],
NPC: [ 1, 4 ],
OPTIONS: [ 2, 5 ]
OPTIONS: [ 2, 5 ],
LEVEL_UP: [ 2, 2 ]
};

export enum DialogueEmote {
Expand Down Expand Up @@ -47,13 +49,14 @@ export enum DialogueEmote {
ANGRY_4 = 617
}

export type DialogueType = 'PLAYER' | 'NPC' | 'OPTIONS';
export type DialogueType = 'PLAYER' | 'NPC' | 'OPTIONS' | 'LEVEL_UP';

export interface DialogueOptions {
type: DialogueType;
npc?: number;
emote?: DialogueEmote;
title?: string;
skillId?: number;
lines: string[];
}

Expand Down Expand Up @@ -85,14 +88,29 @@ export class DialogueAction {
throw 'NPC not supplied.';
}

if(options.type === 'LEVEL_UP' && options.skillId === undefined) {
throw 'Skill ID not supplied.';
}

this._action = null;

let interfaceIndex = options.lines.length - 1;
if(options.type === 'OPTIONS') {
interfaceIndex--;
}

const interfaceId = interfaceIds[options.type][interfaceIndex];
let interfaceId = -1;

if(options.type === 'LEVEL_UP') {
interfaceId = skillDetails.map(skill => skill.advancementInterfaceId === undefined ? -1 : skill.advancementInterfaceId)[options.skillId];
} else {
interfaceId = interfaceIds[options.type][interfaceIndex];
}

if(interfaceId === undefined || interfaceId === null || interfaceId === -1) {
return Promise.resolve(this);
}

let textOffset = 1;

if(options.type === 'PLAYER' || options.type === 'NPC') {
Expand Down
43 changes: 43 additions & 0 deletions src/world/mob/player/action/input-command-action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { logger } from '@runejs/logger/dist/logger';
import { injectPlugins, world } from '@server/game-server';
import { interfaceIds } from '../game-interface';
import { npcAction } from '@server/world/mob/player/action/npc-action';
import { Skill } from '@server/world/mob/skills';

type commandHandler = (player: Player, args?: string[]) => void;

Expand Down Expand Up @@ -118,6 +119,48 @@ const commands: { [key: string]: commandHandler } = {
injectPlugins()
.then(() => player.packetSender.chatboxMessage('Plugins reloaded.'))
.catch(() => player.packetSender.chatboxMessage('Error reloading plugins.'));
},

exptest: player => {
player.skills.addExp(Skill.WOODCUTTING, 420);
},

song: (player, args) => {
if(args.length !== 1) {
throw `song songId`;
}

const songId: number = parseInt(args[0]);

if(isNaN(songId)) {
throw `song songId`;
}

player.packetSender.playSong(songId);
},

quicksong: (player, args) => {
if(args.length !== 1 && args.length !== 2) {
throw `quicksong songId [previousSongId?]`;
}

const songId: number = parseInt(args[0]);

if(isNaN(songId)) {
throw `quicksong songId [previousSongId?]`;
}

let previousSongId: number = 76;

if(args.length === 2) {
previousSongId = parseInt(args[1]);

if(isNaN(previousSongId)) {
throw `quicksong songId [previousSongId?]`;
}
}

player.packetSender.playQuickSong(songId, previousSongId);
}

};
Expand Down
15 changes: 15 additions & 0 deletions src/world/mob/player/packet/packet-sender.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,21 @@ export class PacketSender {
this.socket = player.socket;
}

public playSong(songId: number): void {
const packet = new Packet(220);
packet.writeOffsetShortLE(songId);

this.send(packet);
}

public playQuickSong(songId: number, previousSongId: number): void {
const packet = new Packet(249);
packet.writeShortLE(songId);
packet.writeMediumME(previousSongId);

this.send(packet);
}

public playSound(soundId: number, volume: number, delay: number = 0): void {
const packet = new Packet(26);
packet.writeShortBE(soundId);
Expand Down
3 changes: 3 additions & 0 deletions src/world/mob/player/player-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { writeFileSync, readFileSync, existsSync } from 'fs';
import { join } from 'path';
import { logger } from '@runejs/logger/dist/logger';
import { Player } from './player';
import { SkillValue } from '@server/world/mob/skills';

export interface Appearance {
gender: number;
Expand Down Expand Up @@ -43,6 +44,7 @@ export interface PlayerSave {
appearance: Appearance;
inventory: Item[];
equipment: Item[];
skills: SkillValue[];
settings: PlayerSettings;
}

Expand Down Expand Up @@ -93,6 +95,7 @@ export function savePlayerData(player: Player): boolean {
appearance: player.appearance,
inventory: player.inventory.items,
equipment: player.equipment.items,
skills: player.skills.values,
settings: player.settings
};

Expand Down
7 changes: 5 additions & 2 deletions src/world/mob/player/player.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Isaac } from '@server/net/isaac';
import { PlayerUpdateTask } from './updating/player-update-task';
import { Mob } from '../mob';
import { Position } from '@server/world/position';
import { Skill, skills } from '../skills/skill';
import { Skill, skillDetails } from '../skills';
import { world } from '@server/game-server';
import { logger } from '@runejs/logger';
import {
Expand Down Expand Up @@ -101,6 +101,9 @@ export class Player extends Mob {
if(playerSave.equipment && playerSave.equipment.length !== 0) {
this.equipment.setAll(playerSave.equipment);
}
if(playerSave.skills && playerSave.skills.length !== 0) {
this.skills.values = playerSave.skills;
}
this._appearance = playerSave.appearance;
this._settings = playerSave.settings;
this._rights = playerSave.rights || Rights.USER;
Expand Down Expand Up @@ -143,7 +146,7 @@ export class Player extends Mob {
}
});

skills.forEach((skill: Skill, index: number) => this.packetSender.sendSkill(index, 1, 0));
this.skills.values.forEach((skill, index) => this.packetSender.sendSkill(index, skill.level, skill.exp));

this.packetSender.sendUpdateAllInterfaceItems(interfaceIds.inventory, this.inventory);
this.packetSender.sendUpdateAllInterfaceItems(interfaceIds.equipment, this.equipment);
Expand Down
10 changes: 10 additions & 0 deletions src/world/mob/player/updating/player-update-task.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@ export class PlayerUpdateTask extends Task<void> {
if(updateFlags.chatMessages.length !== 0 && !currentPlayer) {
mask |= 0x40;
}
if(updateFlags.graphics) {
mask |= 0x200;
}

if(mask >= 0xff) {
mask |= 0x20;
Expand All @@ -118,11 +121,18 @@ export class PlayerUpdateTask extends Task<void> {
updateMaskData.writeOffsetByte(message.data.readInt8(i));
}
}

if(updateFlags.facePosition || forceUpdate) {
const position = updateFlags.facePosition ? updateFlags.facePosition : player.position.fromDirection(player.faceDirection);
updateMaskData.writeShortBE(position.x * 2 + 1);
updateMaskData.writeShortBE(position.y * 2 + 1);
}

if(updateFlags.graphics) {
updateMaskData.writeOffsetShortBE(updateFlags.graphics.id);
updateMaskData.writeIntME1(updateFlags.graphics.height << 16 | updateFlags.graphics.delay & 0xffff);
}

if(updateFlags.appearanceUpdateRequired || forceUpdate) {
const equipment = player.equipment;
const appearanceData: RsBuffer = RsBuffer.create();
Expand Down
Loading