mc-beta-server/server/entities/Player.ts

95 lines
3.0 KiB
TypeScript
Raw Normal View History

2023-04-09 04:19:10 +01:00
import { Chunk } from "../Chunk";
import { MPClient } from "../MPClient";
2023-04-08 20:52:47 +01:00
import { MinecraftServer } from "../MinecraftServer";
import { World } from "../World";
2023-04-09 04:19:10 +01:00
import { PacketMapChunk } from "../packets/MapChunk";
import { EntityLiving } from "./EntityLiving";
import { PacketPreChunk } from "../packets/PreChunk";
2023-04-13 23:52:13 +01:00
import { PacketUpdateHealth } from "../packets/UpdateHealth";
2023-04-08 20:52:47 +01:00
2023-09-04 23:42:38 +01:00
const CHUNK_LOAD_RANGE = 5;
2023-04-09 04:19:10 +01:00
export class Player extends EntityLiving {
2023-04-08 20:52:47 +01:00
public username:string;
private server:MinecraftServer;
2023-04-09 04:19:10 +01:00
private firstUpdate:boolean;
public loadedChunks:Array<number>;
public justUnloaded:Array<number>;
public mpClient?:MPClient;
2023-04-08 20:52:47 +01:00
2023-04-13 23:52:13 +01:00
private lastHealth:number;
2023-04-08 20:52:47 +01:00
public constructor(server:MinecraftServer, world:World, username:string) {
super(world);
this.server = server;
2023-04-09 04:19:10 +01:00
this.firstUpdate = true;
this.loadedChunks = new Array<number>();
this.justUnloaded = new Array<number>();
2023-04-08 20:52:47 +01:00
this.username = username;
this.x = 8;
this.y = 64;
this.z = 8;
2023-04-13 23:52:13 +01:00
this.lastHealth = this.health;
2023-04-08 20:52:47 +01:00
}
2023-04-09 04:19:10 +01:00
2023-09-04 23:42:38 +01:00
public forceUpdatePlayerChunks() {
this.firstUpdate = true;
}
2023-04-11 07:47:56 +01:00
private async updatePlayerChunks() {
2023-04-09 04:19:10 +01:00
const bitX = this.x >> 4;
const bitZ = this.z >> 4;
if (bitX != this.lastX >> 4 || bitZ != this.lastZ >> 4 || this.firstUpdate) {
if (this.firstUpdate) {
this.firstUpdate = false;
2023-04-13 23:52:13 +01:00
// TODO: Make this based on the player's initial coords
2023-04-09 04:19:10 +01:00
this.mpClient?.send(new PacketPreChunk(0, 0, true).writeData());
2023-04-11 07:47:56 +01:00
const chunk = await this.world.getChunkSafe(0, 0);
const chunkData = await (new PacketMapChunk(0, 0, 0, 15, 127, 15, chunk).writeData());
this.mpClient?.send(chunkData);
2023-04-09 04:19:10 +01:00
}
// Load or keep any chunks we need
const currentLoads = [];
2023-09-04 23:42:38 +01:00
for (let x = bitX - CHUNK_LOAD_RANGE; x < bitX + CHUNK_LOAD_RANGE; x++) {
for (let z = bitZ - CHUNK_LOAD_RANGE; z < bitZ + CHUNK_LOAD_RANGE; z++) {
2023-04-09 04:19:10 +01:00
const coordPair = Chunk.CreateCoordPair(x, z);
if (!this.loadedChunks.includes(coordPair)) {
2023-04-11 07:47:56 +01:00
const chunk = await this.world.getChunkSafe(x, z);
2023-04-09 04:19:10 +01:00
this.mpClient?.send(new PacketPreChunk(x, z, true).writeData());
this.loadedChunks.push(coordPair);
chunk.playersInChunk.set(this.entityId, this);
2023-04-11 07:47:56 +01:00
const chunkData = await (new PacketMapChunk(x, 0, z, 15, 127, 15, chunk).writeData());
this.mpClient?.send(chunkData);
2023-04-09 04:19:10 +01:00
}
currentLoads.push(coordPair);
}
}
// Mark any unaccounted chunks for unload
2023-04-09 04:47:23 +01:00
for (const coordPair of this.loadedChunks) {
2023-05-02 08:50:49 +01:00
if (!currentLoads.includes(coordPair) && this.world.chunkExists(coordPair)) {
2023-04-09 04:19:10 +01:00
this.justUnloaded.push(coordPair);
const chunkToUnload = this.world.getChunkByCoordPair(coordPair);
this.mpClient?.send(new PacketPreChunk(chunkToUnload.x, chunkToUnload.z, false).writeData());
}
}
// Overwrite loaded chunks
this.loadedChunks = currentLoads;
}
2023-04-11 07:47:56 +01:00
}
public onTick() {
this.updatePlayerChunks();
2023-04-09 04:19:10 +01:00
2023-04-13 23:52:13 +01:00
if (this.health != this.lastHealth) {
this.lastHealth = this.health;
this.mpClient?.send(new PacketUpdateHealth(this.health).writeData());
}
2023-04-09 04:19:10 +01:00
super.onTick();
}
2023-04-08 20:52:47 +01:00
}