mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-14 10:05:44 -04:00
Merge pull request #974 from UnknownShadow200/TeleportChanges
Add ExtEntityTeleport CPE
This commit is contained in:
commit
25a783dd27
@ -84,7 +84,7 @@ static void PerspectiveCamera_UpdateMouseRotation(double delta) {
|
||||
return;
|
||||
}
|
||||
|
||||
update.flags = LU_INCLUDES_YAW | LU_INCLUDES_PITCH;
|
||||
update.flags = LU_HAS_YAW | LU_HAS_PITCH;
|
||||
update.yaw = e->next.yaw + rot.X;
|
||||
update.pitch = e->next.pitch + rot.Y;
|
||||
update.pitch = Math_ClampAngle(update.pitch);
|
||||
|
@ -631,7 +631,7 @@ static void TeleportCommand_Execute(const cc_string* args, int argsCount) {
|
||||
return;
|
||||
}
|
||||
|
||||
update.flags = LU_INCLUDES_POS;
|
||||
update.flags = LU_HAS_POS;
|
||||
update.pos = v;
|
||||
e->VTABLE->SetLocation(e, &update);
|
||||
}
|
||||
|
@ -508,7 +508,7 @@ void Entity_LerpAngles(struct Entity* e, float t) {
|
||||
e->Pitch = Math_LerpAngle(prev->pitch, next->pitch, t);
|
||||
e->Yaw = Math_LerpAngle(prev->yaw, next->yaw, t);
|
||||
e->RotX = Math_LerpAngle(prev->rotX, next->rotX, t);
|
||||
e->RotY = Math_LerpAngle(prev->rotY, next->rotY, t);
|
||||
e->RotY = Math_LerpAngle(prev->rotY, next->rotY, t);
|
||||
e->RotZ = Math_LerpAngle(prev->rotZ, next->rotZ, t);
|
||||
}
|
||||
|
||||
@ -997,7 +997,7 @@ static void LocalPlayer_DoRespawn(void) {
|
||||
/* it's obvious to the player that they are being respawned */
|
||||
spawn.Y += 2.0f/16.0f;
|
||||
|
||||
update.flags = LU_INCLUDES_POS | LU_INCLUDES_YAW | LU_INCLUDES_PITCH;
|
||||
update.flags = LU_HAS_POS | LU_HAS_YAW | LU_HAS_PITCH;
|
||||
update.pos = spawn;
|
||||
update.yaw = p->SpawnYaw;
|
||||
update.pitch = p->SpawnPitch;
|
||||
@ -1107,7 +1107,7 @@ void LocalPlayer_MoveToSpawn(void) {
|
||||
struct LocalPlayer* p = &LocalPlayer_Instance;
|
||||
struct LocationUpdate update;
|
||||
|
||||
update.flags = LU_INCLUDES_POS | LU_INCLUDES_YAW | LU_INCLUDES_PITCH;
|
||||
update.flags = LU_HAS_POS | LU_HAS_YAW | LU_HAS_PITCH;
|
||||
update.pos = p->Spawn;
|
||||
update.yaw = p->SpawnYaw;
|
||||
update.pitch = p->SpawnPitch;
|
||||
|
33
src/Entity.h
33
src/Entity.h
@ -32,20 +32,27 @@ extern const char* const ShadowMode_Names[SHADOW_MODE_COUNT];
|
||||
enum EntityType { ENTITY_TYPE_NONE, ENTITY_TYPE_PLAYER };
|
||||
|
||||
/* Which fields are included/valid in a LocationUpdate */
|
||||
#define LU_INCLUDES_POS 0x01
|
||||
#define LU_INCLUDES_PITCH 0x02
|
||||
#define LU_INCLUDES_YAW 0x04
|
||||
#define LU_INCLUDES_ROTX 0x08
|
||||
#define LU_INCLUDES_ROTZ 0x10
|
||||
#define LU_HAS_POS 0x01
|
||||
#define LU_HAS_PITCH 0x02
|
||||
#define LU_HAS_YAW 0x04
|
||||
#define LU_HAS_ROTX 0x08
|
||||
#define LU_HAS_ROTZ 0x10
|
||||
|
||||
/* If set, then new position is calculated by adding current position to update->pos */
|
||||
/* If not set, then new position is just update->pos */
|
||||
#define LU_FLAG_RELATIVEPOS 0x20
|
||||
/* TODO fill this in when implemented */
|
||||
#define LU_FLAG_X 0x40
|
||||
/* If set, then linearly interpolates between current and new state */
|
||||
/* If not set, then current state is immediately updated to new state */
|
||||
#define LU_FLAG_INTERPOLATE 0x80
|
||||
/* 0-11-00000 How to move the entity when position field is included */
|
||||
#define LU_POS_MODEMASK 0x60
|
||||
|
||||
/* 0-00-00000 Entity is instantly teleported to update->pos */
|
||||
#define LU_POS_ABSOLUTE_INSTANT 0x00
|
||||
/* 0-01-00000 Entity is smoothly moved to update->pos */
|
||||
#define LU_POS_ABSOLUTE_SMOOTH 0x20
|
||||
/* 0-10-00000 Entity is smoothly moved to current position + update->pos */
|
||||
#define LU_POS_RELATIVE_SMOOTH 0x40
|
||||
/* 0-11-00000 Entity is offset/shifted by update->pos */
|
||||
#define LU_POS_RELATIVE_SHIFT 0x60
|
||||
|
||||
/* If set, then linearly interpolates between current and new angles */
|
||||
/* If not set, then current angles are immediately updated to new angles */
|
||||
#define LU_ORI_INTERPOLATE 0x80
|
||||
|
||||
/* Represents a location update for an entity. Can be a relative position, full position, and/or an orientation update. */
|
||||
struct LocationUpdate {
|
||||
|
@ -313,61 +313,94 @@ static void InterpComp_AdvanceRotY(struct InterpComp* interp, struct Entity* e)
|
||||
/*########################################################################################################################*
|
||||
*----------------------------------------------NetworkInterpolationComponent----------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
#define NetInterpState_Copy(dst, src) \
|
||||
(dst).pos = (src)->Pos;\
|
||||
#define NetInterpAngles_Copy(dst, src) \
|
||||
(dst).pitch = (src)->Pitch;\
|
||||
(dst).yaw = (src)->Yaw;\
|
||||
(dst).rotX = (src)->RotX;\
|
||||
(dst).rotZ = (src)->RotZ;
|
||||
|
||||
static void NetInterpComp_RemoveOldestState(struct NetInterpComp* interp) {
|
||||
static void NetInterpComp_RemoveOldestPosition(struct NetInterpComp* interp) {
|
||||
int i;
|
||||
for (i = 0; i < Array_Elems(interp->States); i++) {
|
||||
interp->States[i] = interp->States[i + 1];
|
||||
interp->PositionsCount--;
|
||||
|
||||
for (i = 0; i < interp->PositionsCount; i++) {
|
||||
interp->Positions[i] = interp->Positions[i + 1];
|
||||
}
|
||||
interp->StatesCount--;
|
||||
}
|
||||
|
||||
static void NetInterpComp_AddState(struct NetInterpComp* interp, struct NetInterpState state) {
|
||||
if (interp->StatesCount == Array_Elems(interp->States)) {
|
||||
NetInterpComp_RemoveOldestState(interp);
|
||||
static void NetInterpComp_AddPosition(struct NetInterpComp* interp, Vec3 pos) {
|
||||
if (interp->PositionsCount == Array_Elems(interp->Positions)) {
|
||||
NetInterpComp_RemoveOldestPosition(interp);
|
||||
}
|
||||
interp->States[interp->StatesCount] = state; interp->StatesCount++;
|
||||
interp->Positions[interp->PositionsCount++] = pos;
|
||||
}
|
||||
|
||||
static void NetInterpComp_SetPosition(struct NetInterpComp* interp, struct LocationUpdate* update, struct Entity* e, int mode) {
|
||||
Vec3 lastPos = interp->CurPos;
|
||||
Vec3* curPos = &interp->CurPos;
|
||||
Vec3 midPos;
|
||||
|
||||
if (mode == LU_POS_ABSOLUTE_INSTANT || mode == LU_POS_ABSOLUTE_SMOOTH) {
|
||||
*curPos = update->pos;
|
||||
} else {
|
||||
Vec3_AddBy(curPos, &update->pos);
|
||||
}
|
||||
|
||||
if (mode == LU_POS_ABSOLUTE_INSTANT) {
|
||||
e->prev.pos = *curPos;
|
||||
e->next.pos = *curPos;
|
||||
interp->PositionsCount = 0;
|
||||
} else {
|
||||
/* Smoother interpolation by also adding midpoint */
|
||||
Vec3_Lerp(&midPos, &lastPos, curPos, 0.5f);
|
||||
NetInterpComp_AddPosition(interp, midPos);
|
||||
NetInterpComp_AddPosition(interp, *curPos);
|
||||
}
|
||||
}
|
||||
|
||||
static void NetInterpComp_RemoveOldestAngles(struct NetInterpComp* interp) {
|
||||
int i;
|
||||
interp->AnglesCount--;
|
||||
|
||||
for (i = 0; i < interp->AnglesCount; i++) {
|
||||
interp->Angles[i] = interp->Angles[i + 1];
|
||||
}
|
||||
}
|
||||
|
||||
static void NetInterpComp_AddAngles(struct NetInterpComp* interp, struct NetInterpAngles angles) {
|
||||
if (interp->AnglesCount == Array_Elems(interp->Angles)) {
|
||||
NetInterpComp_RemoveOldestAngles(interp);
|
||||
}
|
||||
interp->Angles[interp->AnglesCount++] = angles;
|
||||
}
|
||||
|
||||
void NetInterpComp_SetLocation(struct NetInterpComp* interp, struct LocationUpdate* update, struct Entity* e) {
|
||||
struct NetInterpState last = interp->Cur;
|
||||
struct NetInterpState* cur = &interp->Cur;
|
||||
struct NetInterpState mid;
|
||||
struct NetInterpAngles last = interp->CurAngles;
|
||||
struct NetInterpAngles* cur = &interp->CurAngles;
|
||||
struct NetInterpAngles mid;
|
||||
cc_uint8 flags = update->flags;
|
||||
cc_bool interpolate = flags & LU_FLAG_INTERPOLATE;
|
||||
cc_bool interpolate = flags & LU_ORI_INTERPOLATE;
|
||||
|
||||
if (flags & LU_INCLUDES_POS) {
|
||||
if (flags & LU_FLAG_RELATIVEPOS) {
|
||||
Vec3_AddBy(&cur->Pos, &update->pos);
|
||||
} else {
|
||||
cur->Pos = update->pos;
|
||||
}
|
||||
if (flags & LU_HAS_POS) {
|
||||
NetInterpComp_SetPosition(interp, update, e, flags & LU_POS_MODEMASK);
|
||||
}
|
||||
|
||||
if (flags & LU_INCLUDES_ROTX) cur->RotX = Math_ClampAngle(update->rotX);
|
||||
if (flags & LU_INCLUDES_ROTZ) cur->RotZ = Math_ClampAngle(update->rotZ);
|
||||
if (flags & LU_INCLUDES_PITCH) cur->Pitch = Math_ClampAngle(update->pitch);
|
||||
if (flags & LU_INCLUDES_YAW) cur->Yaw = Math_ClampAngle(update->yaw);
|
||||
if (flags & LU_HAS_ROTX) cur->RotX = Math_ClampAngle(update->rotX);
|
||||
if (flags & LU_HAS_ROTZ) cur->RotZ = Math_ClampAngle(update->rotZ);
|
||||
if (flags & LU_HAS_PITCH) cur->Pitch = Math_ClampAngle(update->pitch);
|
||||
if (flags & LU_HAS_YAW) cur->Yaw = Math_ClampAngle(update->yaw);
|
||||
|
||||
if (!interpolate) {
|
||||
NetInterpState_Copy(e->prev, cur); e->prev.rotY = cur->Yaw;
|
||||
NetInterpState_Copy(e->next, cur); e->next.rotY = cur->Yaw;
|
||||
interp->RotYCount = 0; interp->StatesCount = 0;
|
||||
NetInterpAngles_Copy(e->prev, cur); e->prev.rotY = cur->Yaw;
|
||||
NetInterpAngles_Copy(e->next, cur); e->next.rotY = cur->Yaw;
|
||||
interp->RotYCount = 0; interp->AnglesCount = 0;
|
||||
} else {
|
||||
/* Smoother interpolation by also adding midpoint. */
|
||||
Vec3_Lerp(&mid.Pos, &last.Pos, &cur->Pos, 0.5f);
|
||||
/* Smoother interpolation by also adding midpoint */
|
||||
mid.RotX = Math_LerpAngle(last.RotX, cur->RotX, 0.5f);
|
||||
mid.RotZ = Math_LerpAngle(last.RotZ, cur->RotZ, 0.5f);
|
||||
mid.Pitch = Math_LerpAngle(last.Pitch, cur->Pitch, 0.5f);
|
||||
mid.Yaw = Math_LerpAngle(last.Yaw, cur->Yaw, 0.5f);
|
||||
NetInterpComp_AddState(interp, mid);
|
||||
NetInterpComp_AddState(interp, *cur);
|
||||
NetInterpComp_AddAngles(interp, mid);
|
||||
NetInterpComp_AddAngles(interp, *cur);
|
||||
|
||||
/* Body rotation lags behind head a tiny bit */
|
||||
InterpComp_AddRotY((struct InterpComp*)interp, Math_LerpAngle(last.Yaw, cur->Yaw, 0.33333333f));
|
||||
@ -380,9 +413,13 @@ void NetInterpComp_AdvanceState(struct NetInterpComp* interp, struct Entity* e)
|
||||
e->prev = e->next;
|
||||
e->Position = e->prev.pos;
|
||||
|
||||
if (interp->StatesCount > 0) {
|
||||
NetInterpState_Copy(e->next, &interp->States[0]);
|
||||
NetInterpComp_RemoveOldestState(interp);
|
||||
if (interp->PositionsCount) {
|
||||
e->next.pos = interp->Positions[0];
|
||||
NetInterpComp_RemoveOldestPosition(interp);
|
||||
}
|
||||
if (interp->AnglesCount) {
|
||||
NetInterpAngles_Copy(e->next, &interp->Angles[0]);
|
||||
NetInterpComp_RemoveOldestAngles(interp);
|
||||
}
|
||||
InterpComp_AdvanceRotY((struct InterpComp*)interp, e);
|
||||
}
|
||||
@ -391,6 +428,28 @@ void NetInterpComp_AdvanceState(struct NetInterpComp* interp, struct Entity* e)
|
||||
/*########################################################################################################################*
|
||||
*-----------------------------------------------LocalInterpolationComponent-----------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
static void LocalInterpComp_SetPosition(struct LocationUpdate* update, int mode) {
|
||||
struct Entity* e = &LocalPlayer_Instance.Base;
|
||||
float yOffset;
|
||||
|
||||
if (mode == LU_POS_ABSOLUTE_INSTANT || mode == LU_POS_ABSOLUTE_SMOOTH) {
|
||||
e->next.pos = update->pos;
|
||||
} else if (mode == LU_POS_RELATIVE_SMOOTH) {
|
||||
Vec3_AddBy(&e->next.pos, &update->pos);
|
||||
} else if (mode == LU_POS_RELATIVE_SHIFT) {
|
||||
Vec3_AddBy(&e->prev.pos, &update->pos);
|
||||
Vec3_AddBy(&e->next.pos, &update->pos);
|
||||
}
|
||||
|
||||
/* If server sets Y position exactly on ground, push up a tiny bit */
|
||||
yOffset = e->next.pos.Y - Math_Floor(e->next.pos.Y);
|
||||
if (yOffset < ENTITY_ADJUSTMENT) e->next.pos.Y += ENTITY_ADJUSTMENT;
|
||||
|
||||
if (mode == LU_POS_ABSOLUTE_INSTANT) {
|
||||
e->prev.pos = e->next.pos; e->Position = e->next.pos;
|
||||
}
|
||||
}
|
||||
|
||||
static void LocalInterpComp_Angle(float* prev, float* next, float value, cc_bool interpolate) {
|
||||
value = Math_ClampAngle(value);
|
||||
*next = value;
|
||||
@ -402,33 +461,22 @@ void LocalInterpComp_SetLocation(struct InterpComp* interp, struct LocationUpdat
|
||||
struct EntityLocation* prev = &e->prev;
|
||||
struct EntityLocation* next = &e->next;
|
||||
cc_uint8 flags = update->flags;
|
||||
cc_bool interpolate = flags & LU_FLAG_INTERPOLATE;
|
||||
cc_bool interpolate = flags & LU_ORI_INTERPOLATE;
|
||||
float yOffset;
|
||||
|
||||
if (flags & LU_INCLUDES_POS) {
|
||||
if (flags & LU_FLAG_RELATIVEPOS) {
|
||||
Vec3_AddBy(&next->pos, &update->pos);
|
||||
} else {
|
||||
next->pos = update->pos;
|
||||
}
|
||||
|
||||
/* If server sets Y position exactly on ground, push up a tiny bit */
|
||||
yOffset = next->pos.Y - Math_Floor(next->pos.Y);
|
||||
|
||||
if (yOffset < ENTITY_ADJUSTMENT) next->pos.Y += ENTITY_ADJUSTMENT;
|
||||
if (!interpolate) { prev->pos = next->pos; e->Position = next->pos; }
|
||||
if (flags & LU_HAS_POS) {
|
||||
LocalInterpComp_SetPosition(update, flags & LU_POS_MODEMASK);
|
||||
}
|
||||
|
||||
if (flags & LU_INCLUDES_PITCH) {
|
||||
if (flags & LU_HAS_PITCH) {
|
||||
LocalInterpComp_Angle(&prev->pitch, &next->pitch, update->pitch, interpolate);
|
||||
}
|
||||
if (flags & LU_INCLUDES_ROTX) {
|
||||
if (flags & LU_HAS_ROTX) {
|
||||
LocalInterpComp_Angle(&prev->rotX, &next->rotX, update->rotX, interpolate);
|
||||
}
|
||||
if (flags & LU_INCLUDES_ROTZ) {
|
||||
if (flags & LU_HAS_ROTZ) {
|
||||
LocalInterpComp_Angle(&prev->rotZ, &next->rotZ, update->rotZ, interpolate);
|
||||
}
|
||||
if (flags & LU_INCLUDES_YAW) {
|
||||
if (flags & LU_HAS_YAW) {
|
||||
LocalInterpComp_Angle(&prev->yaw, &next->yaw, update->yaw, interpolate);
|
||||
|
||||
if (!interpolate) {
|
||||
|
@ -84,16 +84,17 @@ struct InterpComp { InterpComp_Layout };
|
||||
void LocalInterpComp_SetLocation(struct InterpComp* interp, struct LocationUpdate* update);
|
||||
void LocalInterpComp_AdvanceState(struct InterpComp* interp, struct Entity* e);
|
||||
|
||||
/* Represents a network position and orientation state */
|
||||
struct NetInterpState { Vec3 Pos; float Pitch, Yaw, RotX, RotZ; };
|
||||
/* Represents a network orientation state */
|
||||
struct NetInterpAngles { float Pitch, Yaw, RotX, RotZ; };
|
||||
|
||||
/* Entity component that performs interpolation for network players */
|
||||
struct NetInterpComp {
|
||||
InterpComp_Layout
|
||||
/* Last known position and orientation sent by the server */
|
||||
struct NetInterpState Cur;
|
||||
int StatesCount;
|
||||
struct NetInterpState States[10];
|
||||
Vec3 CurPos; struct NetInterpAngles CurAngles;
|
||||
/* Interpolated position and orientation state */
|
||||
int PositionsCount, AnglesCount;
|
||||
Vec3 Positions[10]; struct NetInterpAngles Angles[10];
|
||||
};
|
||||
|
||||
void NetInterpComp_SetLocation(struct NetInterpComp* interp, struct LocationUpdate* update, struct Entity* e);
|
||||
|
@ -652,7 +652,7 @@ static cc_bool PushbackPlace(struct AABB* blockBB) {
|
||||
return false;
|
||||
}
|
||||
|
||||
update.flags = LU_INCLUDES_POS;
|
||||
update.flags = LU_HAS_POS | LU_POS_ABSOLUTE_INSTANT;
|
||||
update.pos = pos;
|
||||
p->VTABLE->SetLocation(p, &update);
|
||||
return true;
|
||||
@ -711,7 +711,7 @@ static cc_bool CheckIsFree(BlockID block) {
|
||||
/* Push player upwards when they are jumping and trying to place a block underneath them */
|
||||
nextPos.Y = pos.Y + Blocks.MaxBB[block].Y + ENTITY_ADJUSTMENT;
|
||||
|
||||
update.flags = LU_INCLUDES_POS;
|
||||
update.flags = LU_HAS_POS | LU_POS_ABSOLUTE_INSTANT;
|
||||
update.pos = nextPos;
|
||||
p->VTABLE->SetLocation(p, &update);
|
||||
return true;
|
||||
|
@ -151,7 +151,8 @@ static void AddEntity(cc_uint8* data, EntityID id, const cc_string* name, const
|
||||
Entity_SetName(e, name);
|
||||
|
||||
if (!readPosition) return;
|
||||
Classic_ReadAbsoluteLocation(data, id, 0);
|
||||
Classic_ReadAbsoluteLocation(data, id,
|
||||
LU_HAS_POS | LU_HAS_YAW | LU_HAS_PITCH | LU_POS_ABSOLUTE_INSTANT);
|
||||
if (id != ENTITIES_SELF_ID) return;
|
||||
|
||||
p->Spawn = p->Base.Position;
|
||||
@ -600,14 +601,15 @@ static void Classic_AddEntity(cc_uint8* data) {
|
||||
|
||||
static void Classic_EntityTeleport(cc_uint8* data) {
|
||||
EntityID id = *data++;
|
||||
Classic_ReadAbsoluteLocation(data, id, LU_FLAG_INTERPOLATE);
|
||||
Classic_ReadAbsoluteLocation(data, id,
|
||||
LU_HAS_POS | LU_HAS_YAW | LU_HAS_PITCH | LU_POS_ABSOLUTE_SMOOTH | LU_ORI_INTERPOLATE);
|
||||
}
|
||||
|
||||
static void Classic_RelPosAndOrientationUpdate(cc_uint8* data) {
|
||||
struct LocationUpdate update;
|
||||
EntityID id = data[0];
|
||||
|
||||
update.flags = LU_INCLUDES_POS | LU_INCLUDES_YAW | LU_INCLUDES_PITCH | LU_FLAG_RELATIVEPOS | LU_FLAG_INTERPOLATE;
|
||||
update.flags = LU_HAS_POS | LU_HAS_YAW | LU_HAS_PITCH | LU_POS_RELATIVE_SMOOTH | LU_ORI_INTERPOLATE;
|
||||
update.pos.X = (cc_int8)data[1] / 32.0f;
|
||||
update.pos.Y = (cc_int8)data[2] / 32.0f;
|
||||
update.pos.Z = (cc_int8)data[3] / 32.0f;
|
||||
@ -620,7 +622,7 @@ static void Classic_RelPositionUpdate(cc_uint8* data) {
|
||||
struct LocationUpdate update;
|
||||
EntityID id = data[0];
|
||||
|
||||
update.flags = LU_INCLUDES_POS | LU_FLAG_RELATIVEPOS | LU_FLAG_INTERPOLATE;
|
||||
update.flags = LU_HAS_POS | LU_POS_RELATIVE_SMOOTH | LU_ORI_INTERPOLATE;
|
||||
update.pos.X = (cc_int8)data[1] / 32.0f;
|
||||
update.pos.Y = (cc_int8)data[2] / 32.0f;
|
||||
update.pos.Z = (cc_int8)data[3] / 32.0f;
|
||||
@ -631,7 +633,7 @@ static void Classic_OrientationUpdate(cc_uint8* data) {
|
||||
struct LocationUpdate update;
|
||||
EntityID id = data[0];
|
||||
|
||||
update.flags = LU_INCLUDES_YAW | LU_INCLUDES_PITCH| LU_FLAG_INTERPOLATE;
|
||||
update.flags = LU_HAS_YAW | LU_HAS_PITCH | LU_ORI_INTERPOLATE;
|
||||
update.yaw = Math_Packed2Deg(data[1]);
|
||||
update.pitch = Math_Packed2Deg(data[2]);
|
||||
UpdateLocation(id, &update);
|
||||
@ -681,6 +683,7 @@ static void Classic_SetPermission(cc_uint8* data) {
|
||||
static void Classic_ReadAbsoluteLocation(cc_uint8* data, EntityID id, cc_uint8 flags) {
|
||||
struct LocationUpdate update;
|
||||
int x, y, z;
|
||||
cc_uint8 mode;
|
||||
|
||||
if (cpe_extEntityPos) {
|
||||
x = (int)Stream_GetU32_BE(&data[0]);
|
||||
@ -694,14 +697,17 @@ static void Classic_ReadAbsoluteLocation(cc_uint8* data, EntityID id, cc_uint8 f
|
||||
data += 6;
|
||||
}
|
||||
|
||||
y -= 51; /* Convert to feet position */
|
||||
/* The original classic client behaves strangely in that */
|
||||
/* Y+0 is sent back to the server for next client->server position update */
|
||||
/* Y+22 is sent back to the server for all subsequent position updates */
|
||||
/* so to simplify things, just always add 22 to Y*/
|
||||
if (id == ENTITIES_SELF_ID) y += 22;
|
||||
mode = flags & LU_POS_MODEMASK;
|
||||
if (mode == LU_POS_ABSOLUTE_SMOOTH || mode == LU_POS_ABSOLUTE_INSTANT) { /* Only perform height shifts on absolute updates */
|
||||
y -= 51; /* Convert to feet position */
|
||||
/* The original classic client behaves strangely in that */
|
||||
/* Y+0 is sent back to the server for next client->server position update */
|
||||
/* Y+22 is sent back to the server for all subsequent position updates */
|
||||
/* so to simplify things, just always add 22 to Y*/
|
||||
if (id == ENTITIES_SELF_ID) y += 22;
|
||||
}
|
||||
|
||||
update.flags = LU_INCLUDES_POS | LU_INCLUDES_PITCH | LU_INCLUDES_YAW | flags;
|
||||
update.flags = flags;
|
||||
update.pos.X = x/32.0f;
|
||||
update.pos.Y = y/32.0f;
|
||||
update.pos.Z = z/32.0f;
|
||||
@ -754,7 +760,7 @@ static const char* cpe_clientExtensions[] = {
|
||||
"EnvWeatherType", "MessageTypes", "HackControl", "PlayerClick", "FullCP437", "LongerMessages",
|
||||
"BlockDefinitions", "BlockDefinitionsExt", "BulkBlockUpdate", "TextColors", "EnvMapAspect",
|
||||
"EntityProperty", "ExtEntityPositions", "TwoWayPing", "InventoryOrder", "InstantMOTD", "FastMap", "SetHotbar",
|
||||
"SetSpawnpoint", "VelocityControl", "CustomParticles", "CustomModels", "PluginMessages",
|
||||
"SetSpawnpoint", "VelocityControl", "CustomParticles", "CustomModels", "PluginMessages", "ExtEntityTeleport",
|
||||
/* NOTE: These must be placed last for when EXTENDED_TEXTURES or EXTENDED_BLOCKS are not defined */
|
||||
"ExtendedTextures", "ExtendedBlocks"
|
||||
};
|
||||
@ -926,10 +932,11 @@ static void CPE_ExtEntry(cc_uint8* data) {
|
||||
if (version == 1) return;
|
||||
Protocol.Sizes[OPCODE_DEFINE_BLOCK_EXT] += 3;
|
||||
} else if (String_CaselessEqualsConst(&ext, "ExtEntityPositions")) {
|
||||
Protocol.Sizes[OPCODE_ENTITY_TELEPORT] += 6;
|
||||
Protocol.Sizes[OPCODE_ADD_ENTITY] += 6;
|
||||
Protocol.Sizes[OPCODE_EXT_ADD_ENTITY2] += 6;
|
||||
Protocol.Sizes[OPCODE_SET_SPAWNPOINT] += 6;
|
||||
Protocol.Sizes[OPCODE_ENTITY_TELEPORT] += 6;
|
||||
Protocol.Sizes[OPCODE_ADD_ENTITY] += 6;
|
||||
Protocol.Sizes[OPCODE_EXT_ADD_ENTITY2] += 6;
|
||||
Protocol.Sizes[OPCODE_SET_SPAWNPOINT] += 6;
|
||||
Protocol.Sizes[OPCODE_ENTITY_TELEPORT_EXT] += 6;
|
||||
cpe_extEntityPos = true;
|
||||
} else if (String_CaselessEqualsConst(&ext, "TwoWayPing")) {
|
||||
cpe_twoWayPing = true;
|
||||
@ -1281,13 +1288,13 @@ static void CPE_SetEntityProperty(cc_uint8* data) {
|
||||
|
||||
switch (type) {
|
||||
case 0:
|
||||
update.flags = LU_INCLUDES_ROTX | LU_FLAG_INTERPOLATE;
|
||||
update.flags = LU_HAS_ROTX | LU_ORI_INTERPOLATE;
|
||||
update.rotX = (float)value; break;
|
||||
case 1:
|
||||
update.flags = LU_INCLUDES_YAW | LU_FLAG_INTERPOLATE;
|
||||
update.flags = LU_HAS_YAW | LU_ORI_INTERPOLATE;
|
||||
update.yaw = (float)value; break;
|
||||
case 2:
|
||||
update.flags = LU_INCLUDES_ROTZ | LU_FLAG_INTERPOLATE;
|
||||
update.flags = LU_HAS_ROTZ | LU_ORI_INTERPOLATE;
|
||||
update.rotZ = (float)value; break;
|
||||
|
||||
case 3:
|
||||
@ -1541,6 +1548,26 @@ static void CPE_PluginMessage(cc_uint8* data) {
|
||||
Event_RaisePluginMessage(&NetEvents.PluginMessageReceived, channel, data + 1);
|
||||
}
|
||||
|
||||
static void CPE_ExtEntityTeleport(cc_uint8* data) {
|
||||
EntityID id = *data++;
|
||||
cc_uint8 packetFlags = *data++;
|
||||
cc_uint8 flags = 0;
|
||||
|
||||
/* bit 0 includes position */
|
||||
/* bits 1-2 position mode(absolute_instant / absolute_smooth / relative_smooth / relative_seamless) */
|
||||
/* bit 3 unused */
|
||||
/* bit 4 includes orientation */
|
||||
/* bit 5 interpolate ori */
|
||||
/* bit 6-7 unused */
|
||||
|
||||
if (packetFlags & 1) flags |= LU_HAS_POS;
|
||||
flags |= (packetFlags & 6) << 4; /* bit-and with 00000110 to isolate only pos mode, then left shift by 4 to match client mode offset */
|
||||
if (packetFlags & 16) flags |= LU_HAS_PITCH | LU_HAS_YAW;
|
||||
if (packetFlags & 32) flags |= LU_ORI_INTERPOLATE;
|
||||
|
||||
Classic_ReadAbsoluteLocation(data, id, flags);
|
||||
}
|
||||
|
||||
static void CPE_Reset(void) {
|
||||
cpe_serverExtensionsCount = 0; cpe_pingTicks = 0;
|
||||
cpe_sendHeldBlock = false; cpe_useMessageTypes = false;
|
||||
@ -1587,6 +1614,7 @@ static void CPE_Reset(void) {
|
||||
Net_Set(OPCODE_DEFINE_MODEL_PART, CPE_DefineModelPart, 104);
|
||||
Net_Set(OPCODE_UNDEFINE_MODEL, CPE_UndefineModel, 2);
|
||||
Net_Set(OPCODE_PLUGIN_MESSAGE, CPE_PluginMessage, 66);
|
||||
Net_Set(OPCODE_ENTITY_TELEPORT_EXT, CPE_ExtEntityTeleport, 11);
|
||||
}
|
||||
|
||||
static void CPE_Tick(void) {
|
||||
|
@ -36,7 +36,7 @@ enum OPCODE_ {
|
||||
OPCODE_SET_SPAWNPOINT, OPCODE_VELOCITY_CONTROL,
|
||||
OPCODE_DEFINE_EFFECT, OPCODE_SPAWN_EFFECT,
|
||||
OPCODE_DEFINE_MODEL, OPCODE_DEFINE_MODEL_PART, OPCODE_UNDEFINE_MODEL,
|
||||
OPCODE_PLUGIN_MESSAGE,
|
||||
OPCODE_PLUGIN_MESSAGE, OPCODE_ENTITY_TELEPORT_EXT,
|
||||
|
||||
OPCODE_COUNT
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user