2023-04-09 04:19:10 +01:00
|
|
|
import { World } from "../World";
|
2023-08-20 01:17:27 +01:00
|
|
|
import { Block } from "../blocks/Block";
|
|
|
|
import { PacketAnimation } from "../packets/Animation";
|
2023-04-10 14:42:14 +01:00
|
|
|
import { PacketEntityLook } from "../packets/EntityLook";
|
|
|
|
import { PacketEntityLookRelativeMove } from "../packets/EntityLookRelativeMove";
|
|
|
|
import { PacketEntityRelativeMove } from "../packets/EntityRelativeMove";
|
2023-08-20 01:17:27 +01:00
|
|
|
import { PacketEntityStatus } from "../packets/EntityStatus";
|
2023-04-10 14:42:14 +01:00
|
|
|
import { PacketEntityTeleport } from "../packets/EntityTeleport";
|
2023-04-09 04:19:10 +01:00
|
|
|
import { Entity } from "./Entity";
|
2023-08-20 01:17:27 +01:00
|
|
|
import { IEntity } from "./IEntity";
|
2023-04-09 04:19:10 +01:00
|
|
|
|
|
|
|
export class EntityLiving extends Entity {
|
|
|
|
public yaw:number;
|
2023-04-10 14:42:14 +01:00
|
|
|
public lastYaw:number;
|
2023-04-09 04:19:10 +01:00
|
|
|
public pitch:number;
|
2023-04-10 14:42:14 +01:00
|
|
|
public lastPitch:number;
|
2023-04-09 04:47:23 +01:00
|
|
|
public onGround:boolean;
|
2023-04-13 23:52:13 +01:00
|
|
|
public fallDistance:number;
|
2023-08-20 01:17:27 +01:00
|
|
|
public timeInWater:number;
|
|
|
|
public headHeight:number;
|
2023-04-09 04:19:10 +01:00
|
|
|
|
2023-04-10 14:42:14 +01:00
|
|
|
public absX:number;
|
|
|
|
public absY:number;
|
|
|
|
public absZ:number;
|
|
|
|
public absYaw:number;
|
|
|
|
public absPitch:number;
|
|
|
|
public lastAbsX:number;
|
|
|
|
public lastAbsY:number;
|
|
|
|
public lastAbsZ:number;
|
|
|
|
public lastAbsYaw:number;
|
|
|
|
public lastAbsPitch:number;
|
|
|
|
|
2023-04-09 04:19:10 +01:00
|
|
|
public constructor(world:World) {
|
|
|
|
super(world);
|
|
|
|
|
2023-08-20 01:17:27 +01:00
|
|
|
this.fallDistance = this.yaw = this.lastYaw = this.pitch = this.lastPitch = this.absX = this.absY = this.absZ = this.absYaw = this.absPitch = this.lastAbsX = this.lastAbsY = this.lastAbsZ = this.lastAbsYaw = this.lastAbsPitch = this.timeInWater = 0;
|
2023-04-13 23:52:13 +01:00
|
|
|
this.onGround = true;
|
2023-08-20 01:17:27 +01:00
|
|
|
this.headHeight = 1.62;
|
|
|
|
}
|
|
|
|
|
|
|
|
damageFrom(damage:number, entity?:IEntity) {
|
|
|
|
if (this.health <= 0) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
super.damageFrom(damage, entity);
|
|
|
|
// Send Damage Animation packet
|
|
|
|
this.sendToAllNearby(new PacketEntityStatus(this.entityId, 2).writeData());
|
|
|
|
}
|
|
|
|
|
|
|
|
isInWater() {
|
2023-08-20 02:10:49 +01:00
|
|
|
return this.world.getChunkBlockId(this.chunk, this.x, this.y + this.headHeight, this.z) === Block.waterStill.blockId;
|
2023-04-09 04:19:10 +01:00
|
|
|
}
|
|
|
|
|
2023-04-10 14:42:14 +01:00
|
|
|
private constrainRot(rot:number) {
|
|
|
|
return Math.min(Math.max(rot, -128), 127);
|
|
|
|
}
|
|
|
|
|
|
|
|
private sendPositionUpdate() {
|
|
|
|
this.absX = Math.floor(this.x * 32);
|
|
|
|
this.absY = Math.floor(this.y * 32);
|
|
|
|
this.absZ = Math.floor(this.z * 32);
|
|
|
|
// This is suuuuuper jank
|
|
|
|
this.absYaw = this.constrainRot(Math.floor(((this.yaw - 180 >= 0 ? this.yaw - 180 : (this.yaw - 180) % 360 + 360) % 360 / 360) * 256) - 128);
|
|
|
|
this.absPitch = this.constrainRot(Math.floor((this.pitch % 360 * 256) / 360));
|
|
|
|
const diffX = this.absX - this.lastAbsX;
|
|
|
|
const diffY = this.absY - this.lastAbsY;
|
|
|
|
const diffZ = this.absZ - this.lastAbsZ;
|
|
|
|
const diffYaw = this.absYaw - this.lastAbsYaw;
|
|
|
|
const diffPitch = this.absPitch - this.lastAbsPitch;
|
|
|
|
|
2023-04-10 21:52:30 +01:00
|
|
|
const doRelativeMove = Math.abs(diffX) >= 4 || Math.abs(diffY) >= 4 || Math.abs(diffZ) >= 4;
|
|
|
|
const doLook = Math.abs(diffYaw) >= 4 || Math.abs(diffPitch) >= 4;
|
2023-04-10 14:42:14 +01:00
|
|
|
if (Math.abs(diffX) > 128 || Math.abs(diffY) > 128 || Math.abs(diffZ) > 128) {
|
|
|
|
this.world.sendToNearbyClients(this, new PacketEntityTeleport(this.entityId, this.absX, this.absY, this.absZ, this.absYaw, this.absPitch).writeData());
|
|
|
|
} else if (doRelativeMove && doLook) {
|
|
|
|
this.world.sendToNearbyClients(this, new PacketEntityLookRelativeMove(this.entityId, diffX, diffY, diffZ, this.absYaw, this.absPitch).writeData());
|
|
|
|
} else if (doRelativeMove) {
|
|
|
|
this.world.sendToNearbyClients(this, new PacketEntityRelativeMove(this.entityId, diffX, diffY, diffZ).writeData());
|
|
|
|
} else if (doLook) {
|
|
|
|
this.world.sendToNearbyClients(this, new PacketEntityLook(this.entityId, this.absYaw, this.absPitch).writeData());
|
|
|
|
}
|
|
|
|
|
|
|
|
if (doRelativeMove) {
|
|
|
|
this.lastAbsX = this.absX;
|
|
|
|
this.lastAbsY = this.absY;
|
|
|
|
this.lastAbsZ = this.absZ;
|
|
|
|
}
|
|
|
|
if (doLook) {
|
|
|
|
this.lastAbsYaw = this.absYaw;
|
|
|
|
this.lastAbsPitch = this.absPitch;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-04-09 04:19:10 +01:00
|
|
|
onTick() {
|
|
|
|
super.onTick();
|
2023-04-10 14:42:14 +01:00
|
|
|
this.sendPositionUpdate();
|
2023-04-13 23:52:13 +01:00
|
|
|
|
|
|
|
if (!this.onGround) {
|
|
|
|
this.fallDistance
|
|
|
|
}
|
|
|
|
|
2023-08-20 01:17:27 +01:00
|
|
|
// Drowning
|
|
|
|
if (this.isInWater()) {
|
|
|
|
if (this.timeInWater == Number.MIN_SAFE_INTEGER) {
|
|
|
|
this.timeInWater = 320;
|
|
|
|
}
|
|
|
|
if (this.timeInWater <= 0 && this.timeInWater % 20 === 0) {
|
|
|
|
this.damageFrom(1);
|
|
|
|
}
|
|
|
|
this.timeInWater--;
|
|
|
|
} else {
|
|
|
|
this.timeInWater = Number.MIN_SAFE_INTEGER;
|
|
|
|
}
|
|
|
|
|
2023-04-10 14:42:14 +01:00
|
|
|
this.lastYaw = this.yaw;
|
2023-06-26 09:53:45 +01:00
|
|
|
this.lastPitch = this.pitch;
|
2023-04-09 04:19:10 +01:00
|
|
|
}
|
|
|
|
}
|