Skip to content

Commit 364ab32

Browse files
Merge pull request #181 from rune-js/feature/actor-following
Implementing a new follow action to make one actor follow another
2 parents 628c4de + 6ec7083 commit 364ab32

File tree

7 files changed

+67
-58
lines changed

7 files changed

+67
-58
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { ActionType } from '../plugin';
2+
import { world } from '../../game-server';
3+
import { followActor } from '../../world/actor/player/action/follow-action';
4+
5+
module.exports = {
6+
type: ActionType.COMMAND,
7+
commands: 'follow',
8+
action: details => followActor(details.player, world.npcList[0])
9+
};
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { ActionType } from '../plugin';
2+
import { followActor } from '../../world/actor/player/action/follow-action';
3+
4+
module.exports = {
5+
type: ActionType.PLAYER_ACTION,
6+
options: 'follow',
7+
action: details => followActor(details.player, details.otherPlayer)
8+
};

src/plugins/player/follow-player-plugin.ts

Lines changed: 0 additions & 53 deletions
This file was deleted.

src/world/actor/actor.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import { Position } from '@server/world/position';
88
import { DirectionData, directionFromIndex } from '@server/world/direction';
99
import { CombatAction } from '@server/world/actor/player/action/combat-action';
1010
import { Pathfinding } from '@server/world/actor/pathfinding';
11+
import { Subject } from 'rxjs';
12+
import { ActionCancelType } from '@server/world/actor/player/action/action';
1113

1214
/**
1315
* Handles an actor within the game world.
@@ -30,6 +32,8 @@ export abstract class Actor {
3032
private _combatActions: CombatAction[];
3133
public pathfinding: Pathfinding;
3234
public lastMovementPosition: Position;
35+
public readonly actionsCancelled: Subject<ActionCancelType>;
36+
public readonly movementEvent: Subject<Position>;
3337

3438
protected constructor() {
3539
this.updateFlags = new UpdateFlags();
@@ -43,6 +47,8 @@ export abstract class Actor {
4347
this._busy = false;
4448
this._combatActions = [];
4549
this.pathfinding = new Pathfinding(this);
50+
this.actionsCancelled = new Subject<ActionCancelType>();
51+
this.movementEvent = new Subject<Position>();
4652
}
4753

4854
public damage(amount: number, damageType: DamageType = DamageType.DAMAGE): void {
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { Actor } from '@server/world/actor/actor';
2+
3+
4+
export const walkToActor = async (actor: Actor, target: Actor): Promise<boolean> => {
5+
const distance = Math.floor(target.position.distanceBetween(actor.position));
6+
if(distance > 16) {
7+
actor.clearFaceActor();
8+
actor.metadata.faceActorClearedByWalking = true;
9+
throw new Error(`Distance too great!`);
10+
}
11+
12+
let ignoreDestination = true;
13+
let desiredPosition = target.position;
14+
if(target.lastMovementPosition) {
15+
desiredPosition = target.lastMovementPosition;
16+
ignoreDestination = false;
17+
}
18+
19+
await actor.pathfinding.walkTo(desiredPosition, {
20+
pathingSearchRadius: distance + 2,
21+
ignoreDestination
22+
});
23+
24+
return Promise.resolve(true);
25+
};
26+
27+
export const followActor = (follower: Actor, following: Actor): void => {
28+
follower.face(following, false, false, false);
29+
30+
walkToActor(follower, following);
31+
32+
const subscription = following.movementEvent.subscribe(() => {
33+
walkToActor(follower, following);
34+
});
35+
const actionCancelled = follower.actionsCancelled.subscribe(type => {
36+
if(type !== 'pathing-movement') {
37+
subscription.unsubscribe();
38+
actionCancelled.unsubscribe();
39+
follower.face(null);
40+
}
41+
});
42+
};

src/world/actor/player/player.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -101,9 +101,7 @@ export class Player extends Actor {
101101
public readonly dialogueInteractionEvent: Subject<number>;
102102
public readonly numericInputEvent: Subject<number>;
103103
private _walkingTo: Position;
104-
public readonly movementEvent: Subject<Position>;
105104
private _nearbyChunks: Chunk[];
106-
public readonly actionsCancelled: Subject<ActionCancelType>;
107105
private quadtreeKey: QuadtreeKey = null;
108106
public savedMetadata: { [key: string]: any } = {};
109107
public sessionMetadata: { [key: string]: any } = {};
@@ -131,9 +129,7 @@ export class Player extends Actor {
131129
this._equipment = new ItemContainer(14);
132130
this.dialogueInteractionEvent = new Subject<number>();
133131
this.numericInputEvent = new Subject<number>();
134-
this.movementEvent = new Subject<Position>();
135132
this._nearbyChunks = [];
136-
this.actionsCancelled = new Subject<ActionCancelType>();
137133

138134
this.loadSaveData();
139135
}

src/world/actor/walking-queue.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,8 +208,9 @@ export class WalkingQueue {
208208

209209
const newChunk = world.chunkManager.getChunkForWorldPosition(this.actor.position);
210210

211+
this.actor.movementEvent.next(this.actor.position);
212+
211213
if(this.actor instanceof Player) {
212-
this.actor.movementEvent.next(this.actor.position);
213214
const mapDiffX = this.actor.position.x - (lastMapRegionUpdatePosition.chunkX * 8);
214215
const mapDiffY = this.actor.position.y - (lastMapRegionUpdatePosition.chunkY * 8);
215216
if(mapDiffX < 16 || mapDiffX > 87 || mapDiffY < 16 || mapDiffY > 87) {

0 commit comments

Comments
 (0)