aaaaaaaaaa

This commit is contained in:
Evert Prants 2023-12-11 21:27:34 +02:00
parent 53181efb97
commit 58a4fde43c
Signed by: evert
GPG Key ID: 1688DA83D222D0B5
5 changed files with 66 additions and 66 deletions

View File

@ -65,7 +65,7 @@ export class EventsGateway
await this.world.initializePlayer(player); await this.world.initializePlayer(player);
} }
if (this.players.handlePlayerPacket(data, player)) return false; if (this.world.handlePlayerPacket(data, player)) return false;
return false; return false;
} }

View File

@ -1,4 +1,4 @@
import { Quaternion, Vector3 } from 'three'; import { Matrix4, Quaternion, Vector3 } from 'three';
import type Rapier from '@dimforge/rapier3d-compat'; import type Rapier from '@dimforge/rapier3d-compat';
import { PhysicsTicking } from 'src/physics'; import { PhysicsTicking } from 'src/physics';
import { GameObject } from './game-object'; import { GameObject } from './game-object';
@ -21,8 +21,6 @@ export class Humanoid extends GameObject implements PhysicsTicking {
private _appliedGravity = new Vector3(0, 0, 0); private _appliedGravity = new Vector3(0, 0, 0);
private _grounded = true; private _grounded = true;
private _lookAt = new Vector3(0, 0, 1); private _lookAt = new Vector3(0, 0, 1);
private _lookAtTarget = new Vector3(0, 0, 1);
private _currentLookAt = new Vector3(0, 0, 1);
private _animState = 0; private _animState = 0;
protected collider?: Rapier.Collider; protected collider?: Rapier.Collider;
@ -109,7 +107,7 @@ export class Humanoid extends GameObject implements PhysicsTicking {
} }
setLook(vector: Vector3) { setLook(vector: Vector3) {
this._lookAtTarget.copy(vector); this._lookAt.lerp(vector, 0.15);
} }
jump() { jump() {
@ -146,13 +144,17 @@ export class Humanoid extends GameObject implements PhysicsTicking {
this._velocity.clone().add(this._appliedGravity).multiplyScalar(dt), this._velocity.clone().add(this._appliedGravity).multiplyScalar(dt),
); );
// Apply look vector // Apply look direction to the physics engine
this._currentLookAt.copy(this.parent!.position); const sink = new Vector3();
this._lookAt.lerp(this._lookAtTarget, 0.15); const rotQuat = new Quaternion();
this._currentLookAt.add(this._lookAt); new Matrix4()
this.parent?.lookAt(this._currentLookAt); .lookAt(
this.parent!.position,
this.applyRotation(this.parent!.quaternion); this.parent!.position.clone().sub(this._lookAt),
new Vector3(0, 1, 0),
)
.decompose(sink, rotQuat, sink);
this.rigidBody?.setRotation(rotQuat, false);
} }
die() { die() {
@ -184,10 +186,6 @@ export class Humanoid extends GameObject implements PhysicsTicking {
this._grounded = grounded; this._grounded = grounded;
} }
private applyRotation(quat: Quaternion) {
this.rigidBody?.setRotation(quat, false);
}
dispose(): void { dispose(): void {
if (this.collider && !this.rigidBody) { if (this.collider && !this.rigidBody) {
this.physicsWorldRef?.removeCollider(this.collider, false); this.physicsWorldRef?.removeCollider(this.collider, false);

View File

@ -5,7 +5,6 @@ import { PlayerAuthService } from './player-auth.service';
import { Packet } from 'src/net/packet'; import { Packet } from 'src/net/packet';
import { getRandomName } from 'src/utils/random'; import { getRandomName } from 'src/utils/random';
import { PacketType } from 'src/types/packet-type.enum'; import { PacketType } from 'src/types/packet-type.enum';
import { Vector3 } from 'three';
@Injectable() @Injectable()
export class PlayerStoreService { export class PlayerStoreService {
@ -78,34 +77,4 @@ export class PlayerStoreService {
.toBuffer(); .toBuffer();
}); });
} }
public handlePlayerPacket(packet: Packet, player: Player) {
if (packet.packet === PacketType.PLAYER_MOVEMENT) {
const playerId = packet.read(String);
const velocity = packet.read<Vector3>('vec3');
const lookAt = packet.read<Vector3>('vec3');
const jump = packet.read<boolean>('bool');
this.broadcastExcept(
new Packet(PacketType.PLAYER_MOVEMENT)
.write(playerId, String)
.write(velocity, 'vec3')
.write(lookAt, 'vec3')
.write(jump, 'bool')
.toBuffer(),
[player.id],
);
if (player.controller) {
player.controller.setVelocity(velocity);
if (!(velocity.x === 0 && velocity.y === 0 && velocity.z === 0)) {
player.controller.setLook(lookAt);
}
if (jump) player.controller.jump();
return true;
}
}
return false;
}
} }

View File

@ -9,6 +9,7 @@ import { PhysicsTicking } from 'src/physics';
const PHYSICS_STEPPING = 1000 / 60; const PHYSICS_STEPPING = 1000 / 60;
const PHYSICS_STEPPING_S = 1 / 60; const PHYSICS_STEPPING_S = 1 / 60;
const UPDATE_STEPPING = 1000 / 500;
@Injectable() @Injectable()
export class PhysicsService { export class PhysicsService {
@ -18,6 +19,7 @@ export class PhysicsService {
private running = false; private running = false;
private sceneInitialized = false; private sceneInitialized = false;
private updateTicker: ReturnType<typeof setInterval>;
private physicsTicker: ReturnType<typeof setInterval>; private physicsTicker: ReturnType<typeof setInterval>;
private trackedObjects: PhysicsTicking[] = []; private trackedObjects: PhysicsTicking[] = [];
private tickCallback?: () => void; private tickCallback?: () => void;
@ -29,6 +31,11 @@ export class PhysicsService {
for (const object of this.trackedObjects) object.tick(PHYSICS_STEPPING_S); for (const object of this.trackedObjects) object.tick(PHYSICS_STEPPING_S);
this.tickCallback?.(); this.tickCallback?.();
}, PHYSICS_STEPPING); }, PHYSICS_STEPPING);
this.updateTicker = setInterval(
() => this.tickCallback?.(),
UPDATE_STEPPING,
);
} }
async start(world: World, cb?: () => void) { async start(world: World, cb?: () => void) {
@ -45,6 +52,7 @@ export class PhysicsService {
stop() { stop() {
this.running = false; this.running = false;
clearInterval(this.physicsTicker); clearInterval(this.physicsTicker);
clearInterval(this.updateTicker);
} }
getObjectPackets() { getObjectPackets() {

View File

@ -5,7 +5,7 @@ import { HttpService } from '@nestjs/axios';
import { WorldFile } from 'src/types/world-file'; import { WorldFile } from 'src/types/world-file';
import { Environment, World, instancableGameObjects } from 'src/game'; import { Environment, World, instancableGameObjects } from 'src/game';
import { SerializedObject } from 'src/types/serialized'; import { SerializedObject } from 'src/types/serialized';
import { Object3D } from 'three'; import { Object3D, Vector3 } from 'three';
import { lastValueFrom } from 'rxjs'; import { lastValueFrom } from 'rxjs';
import { Packet } from 'src/net/packet'; import { Packet } from 'src/net/packet';
import { PacketType } from 'src/types/packet-type.enum'; import { PacketType } from 'src/types/packet-type.enum';
@ -19,7 +19,6 @@ export class WorldService implements OnModuleInit {
private logger = new Logger(WorldService.name); private logger = new Logger(WorldService.name);
private world = new World(); private world = new World();
private environment = new Environment(); private environment = new Environment();
private broadcastTick = 0;
constructor( constructor(
private readonly players: PlayerStoreService, private readonly players: PlayerStoreService,
@ -28,24 +27,17 @@ export class WorldService implements OnModuleInit {
private readonly http: HttpService, private readonly http: HttpService,
) {} ) {}
onModuleInit() { async onModuleInit() {
this.logger.log('Loading world file from environment'); this.logger.log('Loading world file from environment');
this.loadWorld() try {
.then(() => { await this.loadWorld();
this.logger.log('World file loaded!'); this.logger.log('World file loaded!');
this.physics.start(this.world, () => { this.physics.start(this.world, () => this.broadcastWorldState());
this.broadcastWorldState(); } catch (err) {
if (this.broadcastTick >= 0.5) {
this.broadcastTick = 0;
return;
}
this.broadcastTick += 0.016;
});
})
.catch((err) => {
this.logger.error('Failed to load world:', err.stack); this.logger.error('Failed to load world:', err.stack);
process.exit(1); process.exit(1);
}); }
} }
async loadWorld() { async loadWorld() {
@ -207,6 +199,39 @@ export class WorldService implements OnModuleInit {
this.logger.log(`PLAYER ${player.name} (${player.id}) has left the game.`); this.logger.log(`PLAYER ${player.name} (${player.id}) has left the game.`);
} }
public handlePlayerPacket(packet: Packet, player: Player) {
if (packet.packet === PacketType.PLAYER_MOVEMENT) {
const playerId = packet.read(String);
// drop bogus packet
if (playerId !== player.id) return false;
const velocity = packet.read<Vector3>('vec3');
const lookAt = packet.read<Vector3>('vec3');
const jump = packet.read<boolean>('bool');
// this.players.broadcastExcept(
// new Packet(PacketType.PLAYER_MOVEMENT)
// .write(playerId, String)
// .write(velocity, 'vec3')
// .write(lookAt, 'vec3')
// .write(jump, 'bool')
// .toBuffer(),
// [player.id],
// );
if (player.controller) {
player.controller.setVelocity(velocity);
if (!(velocity.x === 0 && velocity.y === 0 && velocity.z === 0)) {
// console.log('lookat', lookAt);
player.controller.setLook(lookAt);
}
if (jump) player.controller.jump();
}
return true;
}
return false;
}
private recursiveCreate(entry: SerializedObject, setParent?: Object3D) { private recursiveCreate(entry: SerializedObject, setParent?: Object3D) {
const parent = setParent || this.world; const parent = setParent || this.world;
const newObject = this.createObject(entry.objectType, parent, true); const newObject = this.createObject(entry.objectType, parent, true);