More fun
This commit is contained in:
parent
a1fb6755c7
commit
fc9df09ee1
2 changed files with 2012 additions and 252 deletions
|
|
@ -60,6 +60,10 @@ const npcTuning = {
|
|||
spreadBase: 60,
|
||||
spreadPerDistance: 0.08,
|
||||
spreadAggressionFalloff: 1.3,
|
||||
|
||||
// Per-second chance to hop while grounded and on the move, so bots use the
|
||||
// leap verb too instead of being grounded targets.
|
||||
leapChancePerSecond: 0.35,
|
||||
};
|
||||
|
||||
export class NPC extends PlayerBase {
|
||||
|
|
@ -141,6 +145,16 @@ export class NPC extends PlayerBase {
|
|||
const movement = this.decideMovement(this.nearObjects);
|
||||
this.character.handleMovementAction(new MoveActionCommand(movement));
|
||||
|
||||
if (
|
||||
!this.isComingBack &&
|
||||
this.character.groundPlanet &&
|
||||
vec2.length(movement) > 0 &&
|
||||
Random.getRandom() <
|
||||
npcTuning.leapChancePerSecond * this.aggression * deltaTimeInSeconds
|
||||
) {
|
||||
this.character.leap();
|
||||
}
|
||||
|
||||
if (
|
||||
(this.timeSinceLastShoot += deltaTimeInSeconds) > npcTuning.shootIntervalSeconds
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@ import {
|
|||
PropertyUpdatesForObjects,
|
||||
PropertyUpdatesForObject,
|
||||
PrimaryActionCommand,
|
||||
LeapActionCommand,
|
||||
InputAcknowledgement,
|
||||
} from 'shared';
|
||||
import { Socket } from 'socket.io';
|
||||
import { BoundingBox } from '../physics/bounding-boxes/bounding-box';
|
||||
|
|
@ -37,14 +39,27 @@ export class Player extends PlayerBase {
|
|||
private timeUntilRespawn = 0;
|
||||
private timeSinceLastMessage = 0;
|
||||
private objectsPreviouslyInViewArea: Array<GameObject> = [];
|
||||
private lastInputClientTimeMs = 0;
|
||||
private lastLeapClientTimeMs = 0;
|
||||
|
||||
protected commandExecutors: CommandExecutors = {
|
||||
[SetAspectRatioActionCommand.type]: (v: SetAspectRatioActionCommand) =>
|
||||
(this.aspectRatio = v.aspectRatio),
|
||||
[MoveActionCommand.type]: (c: MoveActionCommand) =>
|
||||
this.character?.handleMovementAction(c),
|
||||
[MoveActionCommand.type]: (c: MoveActionCommand) => {
|
||||
// Remember how far into this client's input timeline we've consumed, to
|
||||
// echo back for client-side prediction reconciliation.
|
||||
this.lastInputClientTimeMs = c.clientTimeMs;
|
||||
this.character?.handleMovementAction(c);
|
||||
},
|
||||
[PrimaryActionCommand.type]: (c: PrimaryActionCommand) =>
|
||||
this.character?.shootTowards(c.position, c.charge),
|
||||
[LeapActionCommand.type]: (c: LeapActionCommand) => {
|
||||
// Record receipt (whether or not leap() accepts it): either way its effect
|
||||
// on bodyVelocity is now reflected in the streamed launch momentum, so the
|
||||
// predictor must stop replaying this leap.
|
||||
this.lastLeapClientTimeMs = c.clientTimeMs;
|
||||
this.character?.leap();
|
||||
},
|
||||
};
|
||||
|
||||
constructor(
|
||||
|
|
@ -100,6 +115,13 @@ export class Player extends PlayerBase {
|
|||
new Set(this.objectContainer.findIntersecting(bb).map((o) => o.gameObject)),
|
||||
);
|
||||
|
||||
// The owning character must always be in its own snapshot, regardless of the
|
||||
// view-area query, so the client predictor never loses its authoritative
|
||||
// anchor (the body can ride a fast spinner to the very edge of the box).
|
||||
if (this.character && !objectsInViewArea.includes(this.character)) {
|
||||
objectsInViewArea.push(this.character);
|
||||
}
|
||||
|
||||
const newlyIntersecting = objectsInViewArea.filter(
|
||||
(o) => !this.objectsPreviouslyInViewArea.includes(o),
|
||||
);
|
||||
|
|
@ -130,6 +152,19 @@ export class Player extends PlayerBase {
|
|||
performance.now() / 1000,
|
||||
),
|
||||
);
|
||||
|
||||
// Tell the client how much of its own input is reflected in the snapshot it
|
||||
// just received, so its predictor can replay the rest. Only while alive —
|
||||
// a dead player isn't predicting.
|
||||
if (this.character) {
|
||||
this.queueCommandSend(
|
||||
new InputAcknowledgement(
|
||||
this.lastInputClientTimeMs,
|
||||
this.character.launchMomentum,
|
||||
this.lastLeapClientTimeMs,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private getOtherPlayers(): Array<OtherPlayerDirection> {
|
||||
|
|
|
|||
Loading…
Reference in a new issue