Skip to content

Commit

Permalink
Merge pull request #376 from Jameskmonger/actor-typed-metadaata
Browse files Browse the repository at this point in the history
refactor: create strongly typed `metadata` property on `Actor` and `Player`
  • Loading branch information
SchauweM authored Sep 8, 2022
2 parents 2f30be1 + cdce42d commit e8f41bc
Show file tree
Hide file tree
Showing 18 changed files with 245 additions and 61 deletions.
6 changes: 0 additions & 6 deletions src/engine/action/pipe/button.action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,6 @@ const buttonActionPipe = (player: Player, widgetId: number, buttonId: number): R
matchingHooks = questActions;
}

if(player.metadata.buttonListener) {
if(widgetId === player.metadata.buttonListener.widgetId) {
player.metadata.buttonListener.event.next(buttonId);
}
}

if(matchingHooks.length === 0) {
player.outgoingPackets.chatboxMessage(`Unhandled button interaction: ${widgetId}:${buttonId}`);
return null;
Expand Down
12 changes: 6 additions & 6 deletions src/engine/config/shop-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,8 @@ export class Shop {
}

public open(player: Player): void {
player.metadata['lastOpenedShop'] = this;
player.metadata['shopCloseListener'] = player.interfaceState.closed.subscribe((whatClosed: WidgetClosedEvent) => {
player.metadata.lastOpenedShop = this;
player.metadata.shopCloseListener = player.interfaceState.closed.subscribe((whatClosed: WidgetClosedEvent) => {
if(whatClosed && whatClosed.widget && whatClosed.widget.widgetId === widgets.shop.widgetId) {
this.removePlayerFromShop(player);
}
Expand All @@ -121,7 +121,7 @@ export class Shop {

private updateCustomers() {
for (const player of this.customers) {
if(player.metadata['lastOpenedShop'] === this) {
if(player.metadata.lastOpenedShop === this) {
player.outgoingPackets.sendUpdateAllWidgetItems(widgets.shop, this.container);
} else {
this.removePlayerFromShop(player);
Expand All @@ -130,9 +130,9 @@ export class Shop {
}

private removePlayerFromShop(player: Player) {
if(player.metadata['lastOpenedShop'] === this) {
player.metadata['lastOpenedShop'] = undefined;
player.metadata['shopCloseListener'].unsubscribe();
if(player.metadata.lastOpenedShop === this) {
player.metadata.lastOpenedShop = undefined;
player.metadata.shopCloseListener.unsubscribe();
}
this.customers = this.customers.filter((c) => c !== player);
}
Expand Down
4 changes: 2 additions & 2 deletions src/engine/net/inbound-packets/item-on-object.packet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,12 @@ const itemOnObjectPacket = (player: Player, packet: PacketData) => {
let morphIndex = -1;
if(objectConfig.varbitId === -1) {
if(objectConfig.configId !== -1) {
const configValue = player.metadata['configs'] && player.metadata['configs'][objectConfig.configId] ? player.metadata['configs'][objectConfig.configId] : 0;
const configValue = player.metadata.configs && player.metadata.configs[objectConfig.configId] ? player.metadata.configs[objectConfig.configId] : 0;
morphIndex = configValue;

}
} else {
morphIndex = getVarbitMorphIndex(objectConfig.varbitId, player.metadata['configs']);
morphIndex = getVarbitMorphIndex(objectConfig.varbitId, player.metadata.configs);
}
if(morphIndex !== -1) {
objectConfig = filestore.configStore.objectStore.getObject(objectConfig.configChangeDest[morphIndex]);
Expand Down
6 changes: 3 additions & 3 deletions src/engine/net/inbound-packets/object-interaction.packet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,11 @@ const objectInteractionPacket = (player: Player, packet: PacketData) => {
let morphIndex = -1;
if(objectConfig.varbitId === -1) {
if(objectConfig.configId !== -1) {
morphIndex = player.metadata['configs'] && player.metadata['configs'][objectConfig.configId] ?
player.metadata['configs'][objectConfig.configId] : 0;
morphIndex = player.metadata.configs && player.metadata.configs[objectConfig.configId] ?
player.metadata.configs[objectConfig.configId] : 0;
}
} else {
morphIndex = getVarbitMorphIndex(objectConfig.varbitId, player.metadata['configs']);
morphIndex = getVarbitMorphIndex(objectConfig.varbitId, player.metadata.configs);
}
if(morphIndex !== -1) {
objectConfig = filestore.configStore.objectStore.getObject(objectConfig.configChangeDest[morphIndex]);
Expand Down
9 changes: 5 additions & 4 deletions src/engine/net/outbound-packet-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export class OutboundPacketHandler {

public sendProjectile(position: Position, offsetX: number, offsetY: number, id: number, startHeight: number, endHeight: number, speed: number, lockon: number, delay: number) {
this.updateReferencePosition(position);

const packet = new Packet(1);
packet.put(0);
packet.put(offsetY, 'byte');
Expand All @@ -85,7 +85,8 @@ export class OutboundPacketHandler {
packet.put(16);
packet.put(64);
this.queue(packet);
}
}

public updateFriendStatus(friendName: string, worldId: number): void {
const packet = new Packet(156);
packet.put(stringToLong(friendName.toLowerCase()), 'LONG');
Expand Down Expand Up @@ -278,8 +279,8 @@ export class OutboundPacketHandler {
public updateClientConfig(configId: number, value: number): void {
let packet: Packet;
const metadata = this.player.metadata;
if(!metadata['configs']) {
metadata['configs'] = []
if(!metadata.configs) {
metadata.configs = []
}
metadata.configs[configId] = value;

Expand Down
38 changes: 24 additions & 14 deletions src/engine/world/actor/actor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { Pathfinding } from './pathfinding';
import { Attack, AttackDamageType } from './player/attack';
import { Behavior } from './behaviors';
import { Effect, EffectType } from './effect';
import { ActorMetadata } from './metadata';


export type ActorType = 'player' | 'npc';
Expand All @@ -33,7 +34,16 @@ export abstract class Actor {
public readonly inventory: ItemContainer = new ItemContainer(28);
public readonly bank: ItemContainer = new ItemContainer(376);
public readonly actionPipeline = new ActionPipeline(this);
public readonly metadata: { [key: string]: any } = {};

/**
* The map of available metadata for this actor.
*
* You cannot guarantee that this will be populated with data, so you should always check for the existence of the
* metadata you are looking for before using it.
*
* @author jameskmonger
*/
public readonly metadata: Partial<ActorMetadata> = {};

/**
* @deprecated - use new action system instead
Expand Down Expand Up @@ -109,13 +119,13 @@ export abstract class Actor {
// https://oldschool.runescape.wiki/w/Combat_level#:~:text=Calculating%20combat%20level,-Simply&text=Add%20your%20Strength%20and%20Attack,have%20your%20melee%20combat%20level.&text=Multiply%20this%20by%200.325%20and,have%20your%20magic%20combat%20level
// https://oldschool.runescape.wiki/w/Damage_per_second/Melee#:~:text=1%20Step%20one%3A%20Calculate%20the%20effective%20strength%20level%3B,1.7%20Step%20seven%3A%20Calculate%20the%20melee%20damage%20output
public getAttackRoll(defender): Attack {

//the amount of damage is random from 0 to Max
//stance modifiers
const _stance_defense = 3;
const _stance_accurate = 0;
const _stance_controlled = 1;

// base level
// ToDo: calculate prayer effects
// round decimal result calulcation up
Expand All @@ -131,7 +141,7 @@ export abstract class Actor {
Effective strength level
Multiply by(Equipment Melee Strength + 64)
Add 320
Add 320
Divide by 640
Round down to nearest integer
Multiply by gear bonus
Expand Down Expand Up @@ -211,7 +221,7 @@ export abstract class Actor {
return attack;
//+ stance modifier
}
// #endregion
// #endregion

public damage(amount: number, damageType: DamageType = DamageType.DAMAGE) {
const armorReduction = 0;
Expand Down Expand Up @@ -347,7 +357,7 @@ export abstract class Actor {

public follow(target: Actor): void {
this.face(target, false, false, false);
this.metadata['following'] = target;
this.metadata.following = target;

this.moveBehind(target);
const subscription = target.walkingQueue.movementEvent.subscribe(() => {
Expand All @@ -362,7 +372,7 @@ export abstract class Actor {
).subscribe(() => {
subscription.unsubscribe();
this.face(null);
delete this.metadata['following'];
delete this.metadata.following;
});
}

Expand All @@ -376,7 +386,7 @@ export abstract class Actor {
if(distance <= 1) {
return false;
}

if(distance > 16) {
this.clearFaceActor();
this.metadata.faceActorClearedByWalking = true;
Expand All @@ -398,7 +408,7 @@ export abstract class Actor {
return;
}

this.metadata['tailing'] = target;
this.metadata.tailing = target;

this.moveTo(target);
const subscription = target.walkingQueue.movementEvent.subscribe(async () => this.moveTo(target));
Expand All @@ -409,7 +419,7 @@ export abstract class Actor {
).subscribe(() => {
subscription.unsubscribe();
this.face(null);
delete this.metadata['tailing'];
delete this.metadata.tailing;
});
}

Expand All @@ -424,8 +434,8 @@ export abstract class Actor {
this.updateFlags.facePosition = face;
} else if(face instanceof Actor) {
this.updateFlags.faceActor = face;
this.metadata['faceActor'] = face;
this.metadata['faceActorClearedByWalking'] = clearedByWalking;
this.metadata.faceActor = face;
this.metadata.faceActorClearedByWalking = clearedByWalking;

if(autoClear) {
setTimeout(() => {
Expand All @@ -441,9 +451,9 @@ export abstract class Actor {
}

public clearFaceActor(): void {
if(this.metadata['faceActor']) {
if(this.metadata.faceActor) {
this.updateFlags.faceActor = null;
this.metadata['faceActor'] = undefined;
this.metadata.faceActor = undefined;
}
}

Expand Down
56 changes: 56 additions & 0 deletions src/engine/world/actor/metadata.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { ConstructedRegion } from '../map';
import { Position } from '../position';
import { Actor } from './actor';

/**
* The definition of the metadata available on an {@link Actor}.
*
* You cannot guarantee that all of these properties will be present on an actor,
* so you should always check for their existence before using them.
*
* @author jameskmonger
*/
export type ActorMetadata = {
/**
* The custom constructed map region for this actor.
*
* TODO (jameskmonger) Should this live on Actor rather than on {@link Player}? I don't think NPCs can have a custom map.
*/
customMap: ConstructedRegion;

/**
* The player's current target position.
*
* Used within the action pipeline.
*/
walkingTo: Position;

/**
* The actor currently being `tailed` by this actor.
*
* TODO (jameskmonger) we should delete this - only used by deleted code in the old combat plugin
*/
tailing: Actor;

/**
* The actor currently being followed by this actor.
*/
following: Actor;

/**
* The actor which the local actor is facing towards.
*/
faceActor: Actor;

/**
* Whether a walk action has cleared the actor which the local actor is facing towards.
*
* TODO (jameskmonger) does this belong on this metadata?
*/
faceActorClearedByWalking: boolean;

/**
* Set to true if the actor is currently teleporting.
*/
teleporting: boolean;
};
Loading

0 comments on commit e8f41bc

Please sign in to comment.