Port LocalPlayer and NetPlayer to C.

This commit is contained in:
UnknownShadow200 2018-04-20 08:16:30 +10:00
parent bfe4bc05e0
commit af2a363def
21 changed files with 359 additions and 151 deletions

View File

@ -46,6 +46,11 @@ namespace ClassicalSharp.Entities {
physics.hacks = Hacks; physics.collisions = collisions;
}
public override void SetLocation(LocationUpdate update, bool interpolate) {
interp.SetLocation(update, interpolate);
}
public override void Tick(double delta) {
if (!game.World.HasBlocks) return;
StepSize = Hacks.FullBlockStep && Hacks.Enabled && Hacks.CanAnyHacks && Hacks.CanSpeed ? 1 : 0.5f;
@ -62,8 +67,10 @@ namespace ClassicalSharp.Entities {
if (!Hacks.NoclipSlide && (Hacks.Noclip && xMoving == 0 && zMoving == 0)) {
Velocity = Vector3.Zero;
}
physics.UpdateVelocityState();
physics.PhysicsTick(GetHeadingVelocity(zMoving, xMoving));
Vector3 headingVelocity = Utils.RotateY(xMoving, 0, zMoving, HeadYRadians);
physics.PhysicsTick(headingVelocity);
interp.next.Pos = Position; Position = interp.prev.Pos;
anim.UpdateAnimState(interp.prev.Pos, interp.next.Pos, delta);
@ -72,11 +79,6 @@ namespace ClassicalSharp.Entities {
CheckSkin();
sound.Tick(wasOnGround);
}
Vector3 GetHeadingVelocity(float xMoving, float zMoving) {
return Utils.RotateY(xMoving, 0, zMoving, HeadYRadians);
}
public override void RenderModel(double deltaTime, float t) {
anim.GetCurrentAnimState(t);
@ -90,15 +92,32 @@ namespace ClassicalSharp.Entities {
if (!game.Camera.IsThirdPerson) return;
DrawName();
}
/// <summary> Disables any hacks if their respective CanHackX value is set to false. </summary>
public void CheckHacksConsistency() {
Hacks.CheckHacksConsistency();
if (!Hacks.CanJumpHigher) {
physics.jumpVel = physics.serverJumpVel;
}
}
/// <summary> Linearly interpolates position and rotation between the previous and next state. </summary>
public void SetInterpPosition(float t) {
if (!(Hacks.WOMStyleHacks && Hacks.Noclip)) {
Position = Vector3.Lerp(interp.prev.Pos, interp.next.Pos, t);
}
interp.LerpAngles(t);
}
void HandleInput(ref float xMoving, ref float zMoving) {
if (game.Gui.ActiveScreen.HandlesAllInput) {
physics.jumping = Hacks.Speeding = Hacks.FlyingUp = Hacks.FlyingDown = false;
} else {
if (game.IsKeyDown(KeyBind.Forward)) xMoving -= 0.98f;
if (game.IsKeyDown(KeyBind.Back)) xMoving += 0.98f;
if (game.IsKeyDown(KeyBind.Left)) zMoving -= 0.98f;
if (game.IsKeyDown(KeyBind.Right)) zMoving += 0.98f;
if (game.IsKeyDown(KeyBind.Forward)) zMoving -= 0.98f;
if (game.IsKeyDown(KeyBind.Back)) zMoving += 0.98f;
if (game.IsKeyDown(KeyBind.Left)) xMoving -= 0.98f;
if (game.IsKeyDown(KeyBind.Right)) xMoving += 0.98f;
physics.jumping = game.IsKeyDown(KeyBind.Jump);
Hacks.Speeding = Hacks.Enabled && game.IsKeyDown(KeyBind.Speed);
@ -112,25 +131,7 @@ namespace ClassicalSharp.Entities {
}
}
}
/// <summary> Disables any hacks if their respective CanHackX value is set to false. </summary>
public void CheckHacksConsistency() {
Hacks.CheckHacksConsistency();
if (!Hacks.CanJumpHigher) {
physics.jumpVel = physics.serverJumpVel;
}
}
public override void SetLocation(LocationUpdate update, bool interpolate) {
interp.SetLocation(update, interpolate);
}
/// <summary> Linearly interpolates position and rotation between the previous and next state. </summary>
public void SetInterpPosition(float t) {
if (!Hacks.WOMStyleHacks || !Hacks.Noclip)
Position = Vector3.Lerp(interp.prev.Pos, interp.next.Pos, t);
interp.LerpAngles(t);
}
public void Init(Game game) {
Hacks.Enabled = !game.PureClassic && Options.GetBool(OptionsKey.HacksOn, true);
@ -143,8 +144,7 @@ namespace ClassicalSharp.Entities {
Hacks.WOMStyleHacks = Options.GetBool(OptionsKey.WOMStyleHacks, false);
Hacks.FullBlockStep = Options.GetBool(OptionsKey.FullBlockStep, false);
physics.userJumpVel = Options.GetFloat(OptionsKey.JumpVelocity, 0.0f, 52.0f, 0.42f);
physics.jumpVel = physics.userJumpVel;
physics.jumpVel = physics.userJumpVel;
}
public void Ready(Game game) { }

View File

@ -20,10 +20,10 @@ namespace ClassicalSharp.Generator {
public override string GeneratorName { get { return "Vanilla classic"; } }
public override BlockRaw[] Generate() {
blocks = new BlockRaw[Width * Height * Length];
rnd = new JavaRandom(Seed);
oneY = Width * Length;
waterLevel = Height / 2;
blocks = new BlockRaw[Width * Height * Length];
rnd = new JavaRandom(Seed);
minHeight = Height;
CreateHeightmap();

View File

@ -57,7 +57,7 @@ void AxisLinesRenderer_Render(Real64 delta) {
P.X + axisLines_size, P.Z + axisLines_length,
P.Y);
if (Camera_ActiveCamera->IsThirdPerson) {
if (Camera_Active->IsThirdPerson) {
PackedCol green = PACKEDCOL_GREEN;
SelectionBox_VerQuad(&ptr, green,
P.X - axisLines_size, P.Y, P.Z + axisLines_size,

View File

@ -253,7 +253,7 @@ void Camera_Init(void) {
ThirdPersonCamera_Init(&Camera_Cameras[1]);
ForwardThirdPersonCamera_Init(&Camera_Cameras[2]);
Camera_ActiveCamera = &Camera_Cameras[0];
Camera_Active = &Camera_Cameras[0];
Camera_ActiveIndex = 0;
}
@ -266,6 +266,6 @@ void Camera_CycleActive(void) {
LocalPlayer* player = &LocalPlayer_Instance;
if (!player->Hacks.CanUseThirdPersonCamera || !player->Hacks.Enabled) { i = 0; }
Camera_ActiveCamera = &Camera_Cameras[i];
Camera_Active = &Camera_Cameras[i];
Game_UpdateProjection();
}

View File

@ -41,7 +41,7 @@ typedef struct Camera_ {
NOTE: looking straight up or down (parallel to camera up vector) can otherwise cause rendering issues. */
Real32 Camera_AdjustHeadX(Real32 degrees);
Camera* Camera_ActiveCamera;
Camera* Camera_Active;
void Camera_Init(void);
void Camera_CycleActive(void);
#endif

View File

@ -17,10 +17,14 @@
#include "ErrorHandler.h"
#include "IModel.h"
#include "Input.h"
#include "Gui.h"
const UInt8* NameMode_Names[NAME_MODE_COUNT] = { "None", "Hovered", "All", "AllHovered", "AllUnscaled" };
const UInt8* ShadowMode_Names[SHADOW_MODE_COUNT] = { "None", "SnapToBlock", "Circle", "CircleAll" };
/*########################################################################################################################*
*-----------------------------------------------------LocationUpdate------------------------------------------------------*
*#########################################################################################################################*/
Real32 LocationUpdate_Clamp(Real32 degrees) {
degrees = Math_ModF(degrees, 360.0f);
if (degrees < 0) degrees += 360.0f;
@ -56,7 +60,10 @@ void LocationUpdate_MakePosAndOri(LocationUpdate* update, Vector3 pos, Real32 ro
}
EntityVTABLE entityDefaultVTABLE;
/*########################################################################################################################*
*---------------------------------------------------------Entity----------------------------------------------------------*
*#########################################################################################################################*/
EntityVTABLE entity_VTABLE;
PackedCol Entity_DefaultGetCol(Entity* entity) {
Vector3 eyePos = Entity_GetEyePosition(entity);
Vector3I P; Vector3I_Floor(&P, &eyePos);
@ -65,15 +72,14 @@ PackedCol Entity_DefaultGetCol(Entity* entity) {
void Entity_NullFunc(Entity* entity) {}
void Entity_Init(Entity* entity) {
Platform_MemSet(entity, 0, sizeof(Entity));
entity->ModelScale = Vector3_Create1(1.0f);
entity->uScale = 1.0f;
entity->vScale = 1.0f;
entityDefaultVTABLE.ContextLost = Entity_NullFunc;
entityDefaultVTABLE.ContextRecreated = Entity_NullFunc;
entityDefaultVTABLE.GetCol = Entity_DefaultGetCol;
entity->VTABLE = &entityDefaultVTABLE;
entity->VTABLE = &entity_VTABLE;
entity->VTABLE->ContextLost = Entity_NullFunc;
entity->VTABLE->ContextRecreated = Entity_NullFunc;
entity->VTABLE->GetCol = Entity_DefaultGetCol;
}
Vector3 Entity_GetEyePosition(Entity* entity) {
@ -214,12 +220,15 @@ bool Entity_TouchesAnyWater(Entity* entity) {
}
EntityID closestId;
/*########################################################################################################################*
*--------------------------------------------------------Entities---------------------------------------------------------*
*#########################################################################################################################*/
EntityID entities_closestId;
void Entities_Tick(ScheduledTask* task) {
UInt32 i;
for (i = 0; i < ENTITIES_MAX_COUNT; i++) {
if (Entities_List[i] == NULL) continue;
Entities_List[i]->VTABLE->Tick(Entities_List[i], task);
Entities_List[i]->VTABLE->Tick(Entities_List[i], task->Interval);
}
}
@ -239,7 +248,7 @@ void Entities_RenderModels(Real64 delta, Real32 t) {
void Entities_RenderNames(Real64 delta) {
if (Entities_NameMode == NAME_MODE_NONE) return;
LocalPlayer* p = &LocalPlayer_Instance;
closestId = Entities_GetCloset(&p->Base);
entities_closestId = Entities_GetCloset(&p->Base);
if (!p->Hacks.CanSeeAllNames || Entities_NameMode != NAME_MODE_ALL) return;
Gfx_SetTexturing(true);
@ -250,7 +259,7 @@ void Entities_RenderNames(Real64 delta) {
UInt32 i;
for (i = 0; i < ENTITIES_MAX_COUNT; i++) {
if (Entities_List[i] == NULL) continue;
if (i != closestId || i == ENTITIES_SELF_ID) {
if (i != entities_closestId || i == ENTITIES_SELF_ID) {
Entities_List[i]->VTABLE->RenderName(Entities_List[i]);
}
}
@ -275,7 +284,7 @@ void Entities_RenderHoveredNames(Real64 delta) {
UInt32 i;
for (i = 0; i < ENTITIES_MAX_COUNT; i++) {
if (Entities_List[i] == NULL) continue;
if ((i == closestId || allNames) && i != ENTITIES_SELF_ID) {
if ((i == entities_closestId || allNames) && i != ENTITIES_SELF_ID) {
Entities_List[i]->VTABLE->RenderName(Entities_List[i]);
}
}
@ -394,6 +403,10 @@ void Entities_DrawShadows(void) {
Gfx_SetTexturing(false);
}
/*########################################################################################################################*
*--------------------------------------------------------TabList----------------------------------------------------------*
*#########################################################################################################################*/
bool TabList_Valid(EntityID id) {
return TabList_PlayerNames[id] > 0 || TabList_ListNames[id] > 0 || TabList_GroupNames[id] > 0;
}
@ -439,6 +452,9 @@ IGameComponent TabList_MakeComponent(void) {
}
/*########################################################################################################################*
*---------------------------------------------------------Player----------------------------------------------------------*
*#########################################################################################################################*/
#define PLAYER_NAME_EMPTY_TEX -30000
void Player_MakeNameTexture(Player* player) {
FontDesc font;
@ -708,10 +724,15 @@ void Player_ContextRecreated(Entity* entity) {
Player_UpdateName(player);
}
EntityVTABLE playerDefaultVTABLE;
void Player_SetName(Player* player, STRING_PURE String* displayName, STRING_PURE String* skinName) {
String dstDisplayName = String_FromEmptyArray(player->DisplayNameRaw);
String_AppendString(&dstDisplayName, displayName);
String dstSkinName = String_FromEmptyArray(player->SkinNameRaw);
String_AppendString(&dstSkinName, skinName);
}
EntityVTABLE player_VTABLE;
void Player_Init(Player* player) {
/* TODO should we just remove the memset from entity_Init and player_init?? */
Platform_MemSet(player + sizeof(Entity), 0, sizeof(Player) - sizeof(Entity));
Entity* entity = &player->Base;
Entity_Init(entity);
entity->StepSize = 0.5f;
@ -719,13 +740,17 @@ void Player_Init(Player* player) {
String model = String_FromConst("humanoid");
Entity_SetModel(entity, &model);
playerDefaultVTABLE = *entity->VTABLE;
entity->VTABLE = &playerDefaultVTABLE;
player_VTABLE = *entity->VTABLE;
entity->VTABLE = &player_VTABLE;
entity->VTABLE->ContextLost = Player_ContextLost;
entity->VTABLE->ContextRecreated = Player_ContextRecreated;
entity->VTABLE->Despawn = Player_Despawn;
}
/*########################################################################################################################*
*------------------------------------------------------LocalPlayer--------------------------------------------------------*
*#########################################################################################################################*/
Real32 LocalPlayer_JumpHeight(void) {
LocalPlayer* p = &LocalPlayer_Instance;
return (Real32)PhysicsComp_GetMaxHeight(p->Physics.JumpVel);
@ -739,6 +764,150 @@ void LocalPlayer_CheckHacksConsistency(void) {
}
}
void LocalPlayer_SetInterpPosition(Real32 t) {
LocalPlayer* p = &LocalPlayer_Instance;
if (!(p->Hacks.WOMStyleHacks && p->Hacks.Noclip)) {
Vector3_Lerp(&p->Base.Position, &p->Interp.Prev.Pos, &p->Interp.Next.Pos, t);
}
InterpComp_LerpAngles((InterpComp*)(&p->Interp), &p->Base, t);
}
void LocalPlayer_HandleInput(Real32* xMoving, Real32* zMoving) {
LocalPlayer* p = &LocalPlayer_Instance;
HacksComp* hacks = &p->Hacks;
if (Gui_GetActiveScreen()->HandlesAllInput) {
p->Physics.Jumping = false; hacks->Speeding = false;
hacks->FlyingUp = false; hacks->FlyingDown = false;
} else {
if (KeyBind_IsPressed(KeyBind_Forward)) *zMoving -= 0.98f;
if (KeyBind_IsPressed(KeyBind_Back)) *zMoving += 0.98f;
if (KeyBind_IsPressed(KeyBind_Left)) *xMoving -= 0.98f;
if (KeyBind_IsPressed(KeyBind_Right)) *xMoving += 0.98f;
p->Physics.Jumping = KeyBind_IsPressed(KeyBind_Jump);
hacks->Speeding = hacks->Enabled && KeyBind_IsPressed(KeyBind_Speed);
hacks->HalfSpeeding = hacks->Enabled && KeyBind_IsPressed(KeyBind_HalfSpeed);
hacks->FlyingUp = KeyBind_IsPressed(KeyBind_FlyUp);
hacks->FlyingDown = KeyBind_IsPressed(KeyBind_FlyDown);
if (hacks->WOMStyleHacks && hacks->Enabled && hacks->CanNoclip) {
if (hacks->Noclip) { Vector3 zero = Vector3_Zero; p->Base.Velocity = zero; }
hacks->Noclip = KeyBind_IsPressed(KeyBind_NoClip);
}
}
}
void LocalPlayer_SetLocation(Entity* entity, LocationUpdate* update, bool interpolate) {
LocalPlayer* p = (LocalPlayer*)entity;
LocalInterpComp_SetLocation(&p->Interp, update, interpolate);
}
void LocalPlayer_Tick(Entity* entity, Real64 delta) {
if (World_Blocks == NULL) return;
LocalPlayer* p = (LocalPlayer*)entity;
HacksComp* hacks = &p->Hacks;
entity->StepSize = hacks->FullBlockStep && hacks->Enabled && hacks->CanAnyHacks && hacks->CanSpeed ? 1.0f : 0.5f;
entity->OldVelocity = entity->Velocity;
Real32 xMoving = 0.0f, zMoving = 0.0f;
LocalInterpComp_AdvanceState(&p->Interp);
bool wasOnGround = entity->OnGround;
LocalPlayer_HandleInput(&xMoving, &zMoving);
hacks->Floating = hacks->Noclip || hacks->Flying;
if (!hacks->Floating && hacks->CanBePushed) PhysicsComp_DoEntityPush(entity);
/* Immediate stop in noclip mode */
if (!hacks->NoclipSlide && (hacks->Noclip && xMoving == 0.0f && zMoving == 0.0f)) {
Vector3 zero = Vector3_Zero; entity->Velocity = zero;
}
PhysicsComp_UpdateVelocityState(&p->Physics);
Vector3 headingVelocity = Vector3_RotateY3(xMoving, 0, zMoving, entity->HeadY * MATH_DEG2RAD);
PhysicsComp_PhysicsTick(&p->Physics, headingVelocity);
p->Interp.Next.Pos = entity->Position; entity->Position = p->Interp.Prev.Pos;
AnimatedComp_Update(entity, p->Interp.Prev.Pos, p->Interp.Next.Pos, delta);
TiltComp_Update(&p->Tilt, delta);
Player_CheckSkin((Player*)p);
/* TODO: sound */
/* sound.Tick(wasOnGround); */
}
void LocalPlayer_RenderModel(Entity* entity, Real64 deltaTime, Real32 t) {
LocalPlayer* p = (LocalPlayer*)entity;
AnimatedComp_GetCurrent(entity, t);
TiltComp_GetCurrent(&p->Tilt, t);
if (!Camera_Active->IsThirdPerson) return;
IModel_Render(entity->Model, entity);
}
void LocalPlayer_RenderName(Entity* entity) {
if (!Camera_Active->IsThirdPerson) return;
Player_DrawName((Player*)entity);
}
void LocalPlayer_Init_(void) {
LocalPlayer* p = &LocalPlayer_Instance;
HacksComp* hacks = &p->Hacks;
hacks->Enabled = !Game_PureClassic && Options_GetBool(OPT_HACKS_ENABLED, true);
/* p->Base.Health = 20; TODO: survival mode stuff */
if (Game_ClassicMode) return;
hacks->SpeedMultiplier = Options_GetFloat(OPT_SPEED_FACTOR, 0.1f, 50.0f, 10.0f);
hacks->PushbackPlacing = Options_GetBool(OPT_PUSHBACK_PLACING, false);
hacks->NoclipSlide = Options_GetBool(OPT_NOCLIP_SLIDE, false);
hacks->WOMStyleHacks = Options_GetBool(OPT_WOM_STYLE_HACKS, false);
hacks->FullBlockStep = Options_GetBool(OPT_FULL_BLOCK_STEP, false);
p->Physics.UserJumpVel = Options_GetFloat(OPT_JUMP_VELOCITY, 0.0f, 52.0f, 0.42f);
p->Physics.JumpVel = p->Physics.UserJumpVel;
}
void LocalPlayer_Reset(void) {
LocalPlayer* p = &LocalPlayer_Instance;
p->ReachDistance = 5.0f;
Vector3 zero = Vector3_Zero; p->Base.Velocity = zero;
p->Physics.JumpVel = 0.42f;
p->Physics.ServerJumpVel = 0.42f;
/* p->Base.Health = 20; TODO: survival mode stuff */
}
IGameComponent LocalPlayer_MakeComponent(void) {
IGameComponent comp = IGameComponent_MakeEmpty();
comp.Init = LocalPlayer_Init_;
comp.Ready = LocalPlayer_Reset;
return comp;
}
EntityVTABLE localplayer_VTABLE;
void LocalPlayer_Init(void) {
LocalPlayer* p = &LocalPlayer_Instance;
Platform_MemSet(p, 0, sizeof(LocalPlayer));
Player_Init((Player*)p);
Player_SetName((Player*)p, &Game_Username, &Game_Username);
HacksComp_Init(&p->Hacks);
PhysicsComp_Init(&p->Physics, &p->Base);
TiltComp_Init(&p->Tilt);
p->ReachDistance = 5.0f;
p->Physics.Hacks = &p->Hacks;
p->Physics.Collisions = &p->Collisions;
Entity* entity = &p->Base;
localplayer_VTABLE = *entity->VTABLE;
entity->VTABLE = &localplayer_VTABLE;
entity->VTABLE->SetLocation = LocalPlayer_SetLocation;
entity->VTABLE->Tick = LocalPlayer_Tick;
entity->VTABLE->RenderModel = LocalPlayer_RenderModel;
entity->VTABLE->RenderName = LocalPlayer_RenderName;
}
bool LocalPlayer_IsSolidCollide(BlockID b) { return Block_Collide[b] == COLLIDE_SOLID; }
void LocalPlayer_DoRespawn(void) {
if (World_Blocks == NULL) return;
@ -749,7 +918,7 @@ void LocalPlayer_DoRespawn(void) {
/* Spawn player at highest valid position */
if (World_IsValidPos_3I(P)) {
AAABB_Make(&bb, &spawn, &p->Base.Size);
AABB_Make(&bb, &spawn, &p->Base.Size);
Int32 y;
for (y = P.Y; y <= World_Height; y++) {
Real32 spawnY = Respawn_HighestFreeY(&bb);
@ -780,14 +949,14 @@ bool LocalPlayer_HandlesKey(Int32 key) {
PhysicsComp* physics = &p->Physics;
if (key == KeyBind_Get(KeyBind_Respawn) && hacks->CanRespawn) {
DoRespawn();
LocalPlayer_DoRespawn();
} else if (key == KeyBind_Get(KeyBind_SetSpawn) && hacks->CanRespawn) {
p->Spawn = p->Base.Position;
p->Spawn.X = Math_Floor(p->Spawn.X) + 0.5f;
p->Spawn.Z = Math_Floor(p->Spawn.Z) + 0.5f;
p->SpawnRotY = p->Base.RotY;
p->SpawnHeadX = p->Base.HeadX;
DoRespawn();
LocalPlayer_DoRespawn();
} else if (key == KeyBind_Get(KeyBind_Fly) && hacks->CanFly && hacks->Enabled) {
hacks->Flying = !hacks->Flying;
} else if (key == KeyBind_Get(KeyBind_NoClip) && hacks->CanNoclip && hacks->Enabled && !hacks->WOMStyleHacks) {
@ -805,4 +974,55 @@ bool LocalPlayer_HandlesKey(Int32 key) {
return false;
}
return true;
}
/*########################################################################################################################*
*-------------------------------------------------------NetPlayer---------------------------------------------------------*
*#########################################################################################################################*/
void NetPlayer_SetLocation(Entity* entity, LocationUpdate* update, bool interpolate) {
NetPlayer* p = (NetPlayer*)entity;
NetInterpComp_SetLocation(&p->Interp, update, interpolate);
}
void NetPlayer_Tick(Entity* entity, Real64 delta) {
NetPlayer* p = (NetPlayer*)entity;
Player_CheckSkin((Player*)p);
NetInterpComp_AdvanceState(&p->Interp);
AnimatedComp_Update(entity, p->Interp.Prev.Pos, p->Interp.Next.Pos, delta);
}
void NetPlayer_RenderModel(Entity* entity, Real64 deltaTime, Real32 t) {
NetPlayer* p = (NetPlayer*)entity;
Vector3_Lerp(&entity->Position, &p->Interp.Prev.Pos, &p->Interp.Next.Pos, t);
InterpComp_LerpAngles((InterpComp*)(&p->Interp), entity, t);
AnimatedComp_GetCurrent(entity, t);
p->ShouldRender = IModel_ShouldRender(entity);
if (p->ShouldRender) IModel_Render(entity->Model, entity);
}
void NetPlayer_RenderName(Entity* entity) {
NetPlayer* p = (NetPlayer*)entity;
if (!p->ShouldRender) return;
Real32 dist = IModel_RenderDistance(entity);
Int32 threshold = Entities_NameMode == NAME_MODE_ALL_UNSCALED ? 8192 * 8192 : 32 * 32;
if (dist <= (Real32)threshold) Player_DrawName((Player*)p);
}
EntityVTABLE netplayer_VTABLE;
void NetPlayer_Init(NetPlayer* player, STRING_PURE String* displayName, STRING_PURE String* skinName) {
Platform_MemSet(player, 0, sizeof(NetPlayer));
Player_Init((Player*)player);
Player_SetName((Player*)player, displayName, skinName);
Entity* entity = &player->Base;
netplayer_VTABLE = *entity->VTABLE;
entity->VTABLE = &netplayer_VTABLE;
entity->VTABLE->SetLocation = NetPlayer_SetLocation;
entity->VTABLE->Tick = NetPlayer_Tick;
entity->VTABLE->RenderModel = NetPlayer_RenderModel;
entity->VTABLE->RenderName = NetPlayer_RenderName;
}

View File

@ -54,7 +54,7 @@ void LocationUpdate_MakePosAndOri(LocationUpdate* update, Vector3 pos, Real32 ro
typedef struct Entity_ Entity;
typedef struct EntityVTABLE_ {
void (*Tick)(Entity* entity, ScheduledTask* task);
void (*Tick)(Entity* entity, Real64 delta);
void (*SetLocation)(Entity* entity, LocationUpdate* update, bool interpolate);
void (*RenderModel)(Entity* entity, Real64 deltaTime, Real32 t);
void (*RenderName)(Entity* entity);
@ -140,7 +140,7 @@ typedef struct NetPlayer_ {
NetInterpComp Interp;
bool ShouldRender;
} NetPlayer;
void NetPlayer_Init(NetPlayer* player);
void NetPlayer_Init(NetPlayer* player, STRING_PURE String* displayName, STRING_PURE String* skinName);
/* Represents the user/player's own entity. */
typedef struct LocalPlayer_ {
@ -155,8 +155,10 @@ typedef struct LocalPlayer_ {
} LocalPlayer;
LocalPlayer LocalPlayer_Instance;
IGameComponent LocalPlayer_MakeComponent(void);
void LocalPlayer_Init(void);
Real32 LocalPlayer_JumpHeight(void);
void LocalPlayer_CheckHacksConsistency(void);
void LocalPlayer_SetInterpPosition(Real32 t);
bool LocalPlayer_HandlesKey(Int32 key);
#endif

View File

@ -59,7 +59,8 @@ void AnimatedComp_Init(AnimatedComp* anim) {
anim->BobStrength = 1.0f; anim->BobStrengthO = 1.0f; anim->BobStrengthN = 1.0f;
}
void AnimatedComp_Update(AnimatedComp* anim, Vector3 oldPos, Vector3 newPos, Real64 delta, bool onGround) {
void AnimatedComp_Update(Entity* entity, Vector3 oldPos, Vector3 newPos, Real64 delta) {
AnimatedComp* anim = &entity->Anim;
anim->WalkTimeO = anim->WalkTimeN;
anim->SwingO = anim->SwingN;
Real32 dx = newPos.X - oldPos.X;
@ -79,12 +80,12 @@ void AnimatedComp_Update(AnimatedComp* anim, Vector3 oldPos, Vector3 newPos, Rea
anim->BobStrengthO = anim->BobStrengthN;
Int32 i;
for (i = 0; i < 3; i++) {
AnimatedComp_DoTilt(&anim->BobStrengthN, !Game_ViewBobbing || !onGround);
AnimatedComp_DoTilt(&anim->BobStrengthN, !Game_ViewBobbing || !entity->OnGround);
}
}
void AnimatedComp_GetCurrent(AnimatedComp* anim, Real32 t, bool calcHumanAnims) {
void AnimatedComp_GetCurrent(Entity* entity, Real32 t) {
AnimatedComp* anim = &entity->Anim;
anim->Swing = Math_Lerp(anim->SwingO, anim->SwingN, t);
anim->WalkTime = Math_Lerp(anim->WalkTimeO, anim->WalkTimeN, t);
anim->BobStrength = Math_Lerp(anim->BobStrengthO, anim->BobStrengthN, t);
@ -105,7 +106,7 @@ void AnimatedComp_GetCurrent(AnimatedComp* anim, Real32 t, bool calcHumanAnims)
anim->BobbingVer = Math_AbsF(Math_SinF(anim->WalkTime)) * anim->Swing * (2.5f / 16.0f);
anim->BobbingModel = Math_AbsF(Math_CosF(anim->WalkTime)) * anim->Swing * (4.0f / 16.0f);
if (calcHumanAnims && !Game_SimpleArmsAnim) {
if (entity->Model->CalcHumanAnims && !Game_SimpleArmsAnim) {
AnimatedComp_CalcHumanAnim(anim, idleXRot, idleZRot);
}
}
@ -373,9 +374,9 @@ void NetInterpComp_SetLocation(NetInterpComp* interp, LocationUpdate* update, bo
cur->HeadY = NetInterpComp_Next(update->RotY, cur->HeadY);
if (!interpolate) {
interp->Base.Prev = *cur; interp->Base.PrevRotY = cur->HeadY;
interp->Base.Next = *cur; interp->Base.NextRotY = cur->HeadY;
interp->Base.RotYCount = 0; interp->StatesCount = 0;
interp->Prev = *cur; interp->PrevRotY = cur->HeadY;
interp->Next = *cur; interp->NextRotY = cur->HeadY;
interp->RotYCount = 0; interp->StatesCount = 0;
} else {
/* Smoother interpolation by also adding midpoint. */
InterpState mid;
@ -388,19 +389,19 @@ void NetInterpComp_SetLocation(NetInterpComp* interp, LocationUpdate* update, bo
NetInterpComp_AddState(interp, *cur);
/* Head rotation lags behind body a tiny bit */
InterpComp_AddRotY(&interp->Base, Math_LerpAngle(last.HeadY, cur->HeadY, 0.33333333f));
InterpComp_AddRotY(&interp->Base, Math_LerpAngle(last.HeadY, cur->HeadY, 0.66666667f));
InterpComp_AddRotY(&interp->Base, Math_LerpAngle(last.HeadY, cur->HeadY, 1.00000000f));
InterpComp_AddRotY((InterpComp*)interp, Math_LerpAngle(last.HeadY, cur->HeadY, 0.33333333f));
InterpComp_AddRotY((InterpComp*)interp, Math_LerpAngle(last.HeadY, cur->HeadY, 0.66666667f));
InterpComp_AddRotY((InterpComp*)interp, Math_LerpAngle(last.HeadY, cur->HeadY, 1.00000000f));
}
}
void NetInterpComp_AdvanceState(NetInterpComp* interp) {
interp->Base.Prev = interp->Base.Next;
interp->Prev = interp->Next;
if (interp->StatesCount > 0) {
interp->Base.Next = interp->States[0];
interp->Next = interp->States[0];
NetInterpComp_RemoveOldestState(interp);
}
InterpComp_AdvanceRotY(&interp->Base);
InterpComp_AdvanceRotY((InterpComp*)interp);
}

View File

@ -20,8 +20,8 @@ typedef struct AnimatedComp_ {
} AnimatedComp;
void AnimatedComp_Init(AnimatedComp* anim);
void AnimatedComp_Update(AnimatedComp* anim, Vector3 oldPos, Vector3 newPos, Real64 delta, bool onGround);
void AnimatedComp_GetCurrent(AnimatedComp* anim, Real32 t, bool calcHumanAnims);
void AnimatedComp_Update(Entity* entity, Vector3 oldPos, Vector3 newPos, Real64 delta);
void AnimatedComp_GetCurrent(Entity* entity, Real32 t);
/* Entity component that performs tilt animation depending on movement speed and time */
typedef struct TiltComp_ {
@ -73,19 +73,14 @@ void HacksComp_CheckConsistency(HacksComp* hacks);
void HacksComp_UpdateState(HacksComp* hacks);
/* Represents a position and orientation state */
typedef struct InterpState_ {
Vector3 Pos;
Real32 HeadX, HeadY, RotX, RotZ;
} InterpState;
typedef struct InterpState_ { Vector3 Pos; Real32 HeadX, HeadY, RotX, RotZ; } InterpState;
#define InterpComp_Layout \
InterpState Prev, Next; Real32 PrevRotY, NextRotY; \
Int32 RotYCount; Real32 RotYStates[15];
/* Base entity component that performs interpolation of position and orientation */
typedef struct InterpComp_ {
InterpState Prev, Next;
Real32 PrevRotY, NextRotY;
Int32 RotYCount;
Real32 RotYStates[15];
} InterpComp;
typedef struct InterpComp_ { InterpComp_Layout } InterpComp;
void InterpComp_LerpAngles(InterpComp* interp, Entity* entity, Real32 t);
@ -94,7 +89,7 @@ void LocalInterpComp_AdvanceState(InterpComp* interp);
/* Entity component that performs interpolation for network players */
typedef struct NetInterpComp_ {
InterpComp Base;
InterpComp_Layout
/* Last known position and orientation sent by the server */
InterpState Cur;
Int32 StatesCount;

View File

@ -95,7 +95,7 @@ bool Game_ChangeTerrainAtlas(Bitmap* atlas) {
void Game_UpdateProjection(void) {
Game_DefaultFov = Options_GetInt(OPT_FIELD_OF_VIEW, 1, 150, 70);
Camera_ActiveCamera->GetProjection(&Gfx_Projection);
Camera_Active->GetProjection(&Gfx_Projection);
Gfx_SetMatrixMode(MATRIX_TYPE_PROJECTION);
Gfx_LoadMatrix(&Gfx_Projection);

View File

@ -144,7 +144,7 @@ void Gui_SetScreen(Screen* screen, bool freeOld) {
if (screen == NULL) {
Window_SetCursorVisible(false);
if (Window_GetFocused()) { Camera_ActiveCamera->RegrabMouse(); }
if (Window_GetFocused()) { Camera_Active->RegrabMouse(); }
} else if (Gui_Active == NULL) {
Window_SetCursorVisible(true);
}

View File

@ -208,7 +208,7 @@ void HeldBlockRenderer_Render(Real64 delta) {
HeldBlockRenderer_ResetHeldState();
HeldBlockRenderer_DoAnimation(delta, lastSwingY);
HeldBlockRenderer_SetBaseOffset();
if (!Camera_ActiveCamera->IsThirdPerson) HeldBlockRenderer_RenderModel();
if (!Camera_Active->IsThirdPerson) HeldBlockRenderer_RenderModel();
Gfx_View = view;
Gfx_SetMatrixMode(MATRIX_TYPE_PROJECTION);

View File

@ -329,7 +329,7 @@ void InputHandler_MouseWheel(void* obj, Real32 delta) {
if (active->VTABLE->HandlesMouseScroll(active, delta)) return;
bool hotbar = Key_IsAltPressed() || Key_IsControlPressed() || Key_IsShiftPressed();
if (!hotbar && Camera_ActiveCamera->Zoom(delta)) return;
if (!hotbar && Camera_Active->Zoom(delta)) return;
if (InputHandler_DoFovZoom(delta) || !Inventory_CanChangeHeldBlock) return;
Gui.hudScreen.hotbar.HandlesMouseScroll(delta);

View File

@ -7,7 +7,7 @@
#include "Platform.h"
#include "Random.h"
#include "TreeGen.h"
#include "Vectors.h"
void FlatgrassGen_MapSet(Int32 yStart, Int32 yEnd, BlockID block) {
yStart = max(yStart, 0); yEnd = max(yEnd, 0);
@ -28,16 +28,18 @@ void FlatgrassGen_MapSet(Int32 yStart, Int32 yEnd, BlockID block) {
}
void FlatgrassGen_Generate(void) {
Gen_Blocks = Platform_MemAlloc(Gen_Width * Gen_Height * Gen_Length * sizeof(BlockID));
if (Gen_Blocks == NULL)
ErrorHandler_Fail("FlatgrassGen - failed to allocate Blocks array");
Gen_CurrentProgress = 0.0f;
Gen_CurrentState = "";
String dirtStr = String_FromConst("Setting dirt blocks");
Gen_CurrentState = dirtStr;
Gen_Blocks = Platform_MemAlloc(Gen_Width * Gen_Height * Gen_Length * sizeof(BlockID));
if (Gen_Blocks == NULL) {
ErrorHandler_Fail("FlatgrassGen - failed to allocate Blocks array");
}
Gen_CurrentState = "Setting dirt blocks";
FlatgrassGen_MapSet(0, Gen_Height / 2 - 2, BLOCK_DIRT);
String grassStr = String_FromConst("Setting grass blocks");
Gen_CurrentState = grassStr;
Gen_CurrentState = "Setting grass blocks";
FlatgrassGen_MapSet(Gen_Height / 2 - 1, Gen_Height / 2 - 1, BLOCK_GRASS);
}
@ -114,8 +116,7 @@ void NotchyGen_CreateHeightmap(void) {
OctaveNoise_Init(&n3, &rnd, 6);
Int32 index = 0;
String state = String_FromConst("Building heightmap");
Gen_CurrentState = state;
Gen_CurrentState = "Building heightmap";
Int32 x, z;
for (z = 0; z < Gen_Length; z++) {
@ -167,8 +168,7 @@ Int32 NotchyGen_CreateStrataFast(void) {
void NotchyGen_CreateStrata(void) {
OctaveNoise n;
OctaveNoise_Init(&n, &rnd, 8);
String state = String_FromConst("Creating strata");
Gen_CurrentState = state;
Gen_CurrentState = "Creating strata";
Int32 hMapIndex = 0, maxY = Gen_Height - 1, mapIndex = 0;
/* Try to bulk fill bottom of the map if possible */
Int32 minSTONEY = NotchyGen_CreateStrataFast();
@ -200,8 +200,7 @@ void NotchyGen_CreateStrata(void) {
void NotchyGen_CarveCaves(void) {
Int32 cavesCount = volume / 8192;
String state = String_FromConst("Carving caves");
Gen_CurrentState = state;
Gen_CurrentState = "Carving caves";
Int32 i, j;
for (i = 0; i < cavesCount; i++) {
@ -240,7 +239,7 @@ void NotchyGen_CarveCaves(void) {
void NotchyGen_CarveOreVeins(Real32 abundance, const UInt8* state, BlockID block) {
Int32 numVeins = (Int32)(volume * abundance / 16384);
Gen_CurrentState = String_FromReadonly(state);
Gen_CurrentState = state;
Int32 i, j;
for (i = 0; i < numVeins; i++) {
@ -273,8 +272,7 @@ void NotchyGen_FloodFillWaterBorders(void) {
Int32 waterY = waterLevel - 1;
Int32 index1 = Gen_Pack(0, waterY, 0);
Int32 index2 = Gen_Pack(0, waterY, Gen_Length - 1);
String state = String_FromConst("Flooding edge water");
Gen_CurrentState = state;
Gen_CurrentState = "Flooding edge water";
Int32 x, z;
for (x = 0; x < Gen_Width; x++) {
@ -296,8 +294,7 @@ void NotchyGen_FloodFillWaterBorders(void) {
void NotchyGen_FloodFillWater(void) {
Int32 numSources = Gen_Width * Gen_Length / 800;
String state = String_FromConst("Flooding water");
Gen_CurrentState = state;
Gen_CurrentState = "Flooding water";
Int32 i;
for (i = 0; i < numSources; i++) {
@ -311,8 +308,7 @@ void NotchyGen_FloodFillWater(void) {
void NotchyGen_FloodFillLava(void) {
Int32 numSources = Gen_Width * Gen_Length / 20000;
String state = String_FromConst("Flooding lava");
Gen_CurrentState = state;
Gen_CurrentState = "Flooding lava";
Int32 i;
for (i = 0; i < numSources; i++) {
@ -328,8 +324,7 @@ void NotchyGen_CreateSurfaceLayer(void) {
OctaveNoise n1, n2;
OctaveNoise_Init(&n1, &rnd, 8);
OctaveNoise_Init(&n2, &rnd, 8);
String state = String_FromConst("Creating surface");
Gen_CurrentState = state;
Gen_CurrentState = "Creating surface";
/* TODO: update heightmap */
Int32 hMapIndex = 0;
@ -355,8 +350,7 @@ void NotchyGen_CreateSurfaceLayer(void) {
void NotchyGen_PlantFlowers(void) {
Int32 numPatches = Gen_Width * Gen_Length / 3000;
String state = String_FromConst("Planting flowers");
Gen_CurrentState = state;
Gen_CurrentState = "Planting flowers";
Int32 i, j, k;
for (i = 0; i < numPatches; i++) {
@ -384,8 +378,7 @@ void NotchyGen_PlantFlowers(void) {
void NotchyGen_PlantMushrooms(void) {
Int32 numPatches = volume / 2000;
String state = String_FromConst("Planting mushrooms");
Gen_CurrentState = state;
Gen_CurrentState = "Planting mushrooms";
Int32 i, j, k;
for (i = 0; i < numPatches; i++) {
@ -417,8 +410,7 @@ void NotchyGen_PlantMushrooms(void) {
void NotchyGen_PlantTrees(void) {
Int32 numPatches = Gen_Width * Gen_Length / 4000;
String state = String_FromConst("Planting trees");
Gen_CurrentState = state;
Gen_CurrentState = "Planting trees";
Tree_Width = Gen_Width; Tree_Height = Gen_Height; Tree_Length = Gen_Length;
Tree_Blocks = Gen_Blocks;
@ -461,22 +453,24 @@ void NotchyGen_PlantTrees(void) {
}
void NotchyGen_Generate(void) {
Heightmap = Platform_MemAlloc(Gen_Width * Gen_Length * sizeof(Int16));
if (Heightmap == NULL)
ErrorHandler_Fail("NotchyGen - Failed to allocate Heightmap array");
Gen_Blocks = Platform_MemAlloc(Gen_Width * Gen_Height * Gen_Length * sizeof(BlockID));
if (Gen_Blocks == NULL)
ErrorHandler_Fail("NotchyGen - Failed to allocate Blocks array");
oneY = Gen_Width * Gen_Length;
volume = Gen_Width * Gen_Length * Gen_Height;
waterLevel = Gen_Height / 2;
Random_Init(&rnd, Gen_Seed);
minHeight = Gen_Height;
Gen_CurrentProgress = 0.0f;
String state = String_FromConst("");
Gen_CurrentState = state;
Gen_CurrentState = "";
Heightmap = Platform_MemAlloc(Gen_Width * Gen_Length * sizeof(Int16));
if (Heightmap == NULL) {
ErrorHandler_Fail("NotchyGen - Failed to allocate Heightmap array");
}
Gen_Blocks = Platform_MemAlloc(Gen_Width * Gen_Height * Gen_Length * sizeof(BlockID));
if (Gen_Blocks == NULL) {
ErrorHandler_Fail("NotchyGen - Failed to allocate Blocks array");
}
Random_Init(&rnd, Gen_Seed);
volume = Gen_Width * Gen_Length * Gen_Height;
oneY = Gen_Width * Gen_Length;
waterLevel = Gen_Height / 2;
minHeight = Gen_Height;
NotchyGen_CreateHeightmap();
NotchyGen_CreateStrata();

View File

@ -7,9 +7,9 @@
Copyright 2014 - 2017 ClassicalSharp | Licensed under BSD-3
*/
Real32 Gen_CurrentProgress;
String Gen_CurrentState;
bool Gen_Done;
volatile Real32 Gen_CurrentProgress;
volatile const UInt8* Gen_CurrentState;
volatile bool Gen_Done;
Int32 Gen_Width, Gen_Height, Gen_Length;
Int32 Gen_MaxX, Gen_MaxY, Gen_MaxZ;
Int32 Gen_Seed;

View File

@ -1,6 +1,5 @@
#ifndef CC_IMPROVED_NOISE_H
#define CC_IMPROVED_NOISE_H
#include "Typedefs.h"
#include "Random.h"
/* Implements perlin noise generation.
Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3

View File

@ -59,8 +59,7 @@ typedef struct LoadingScreen_ {
typedef struct GeneratingMapScreen_ {
LoadingScreen Base;
String LastState;
UInt8 LastStateBuffer[String_BufferSize(STRING_SIZE)];
const UInt8* LastState;
} GeneratingMapScreen;
#define CHATSCREEN_MAX_STATUS 5
@ -636,15 +635,12 @@ void GeneratingScreen_Render(GuiElement* elem, Real64 delta) {
LoadingScreen_Render(elem, delta);
if (Gen_Done) { ServerConnection_EndGeneration(); return; }
String state = Gen_CurrentState;
const volatile UInt8* state = Gen_CurrentState;
screen->Base.Progress = Gen_CurrentProgress;
if (String_Equals(&state, &screen->LastState)) return;
String_Clear(&screen->LastState);
String_AppendString(&screen->LastState, &state);
if (state == screen->LastState) return;
String message = String_InitAndClearArray(screen->Base.MessageBuffer);
String_AppendString(&message, &screen->LastState);
String_AppendConst(&message, state);
LoadingScreen_SetMessage(&screen->Base);
}
@ -655,7 +651,7 @@ Screen* GeneratingScreen_MakeInstance(void) {
LoadingScreen_Make(&screen->Base, &GeneratingMapScreen_VTABLE, &title, &message);
screen->Base.VTABLE->Render = GeneratingScreen_Render;
screen->LastState = String_InitAndClearArray(screen->LastStateBuffer);
screen->LastState = NULL;
return (Screen*)screen;
}
@ -875,7 +871,7 @@ bool ChatScreen_HandlesKeyDown(GuiElement* elem, Key key) {
if (key == KeyBind_Get(KeyBind_SendChat) || key == Key_KeypadEnter || key == KeyBind_Get(KeyBind_PauseOrExit)) {
ChatScreen_SetHandlesAllInput(screen, false);
Game_SetCursorVisible(false);
Camera_ActiveCamera->RegrabMouse();
Camera_Active->RegrabMouse();
Key_KeyRepeat = false;
if (key == KeyBind_Get(KeyBind_PauseOrExit)) {

View File

@ -72,7 +72,7 @@ void ServerConnection_EndGeneration(void) {
LocationUpdate update; LocationUpdate_MakePosAndOri(&update, p->Spawn, 0.0f, 0.0f, false);
p->Base.VTABLE->SetLocation(&p->Base, &update, false);
Game_CurrentCameraPos = Camera_ActiveCamera->GetCameraPos(0.0f);
Game_CurrentCameraPos = Camera_Active->GetCameraPos(0.0f);
Event_RaiseVoid(&WorldEvents_MapLoaded);
}
}

View File

@ -49,7 +49,7 @@ void SkyboxRenderer_Render(Real64 deltaTime) {
Matrix_MulBy(&m, &rotX);
/* Rotate around camera */
Vector2 rotation = Camera_ActiveCamera->GetCameraOrientation();
Vector2 rotation = Camera_Active->GetCameraOrientation();
Matrix_RotateY(&rotY, rotation.Y); /* Camera yaw */
Matrix_MulBy(&m, &rotY);
Matrix_RotateX(&rotX, rotation.X); /* Camera pitch */

View File

@ -1,6 +1,7 @@
#include "TreeGen.h"
#include "BlockID.h"
#include "ExtMath.h"
#include "Vectors.h"
bool TreeGen_CanGrow(Int32 treeX, Int32 treeY, Int32 treeZ, Int32 treeHeight) {
/* check tree base */

View File

@ -1,13 +1,13 @@
#ifndef CC_TREE_GEN_H
#define CC_TREE_GEN_H
#include "Random.h"
#include "Vectors.h"
/* Implements original classic vanilla map generation
Based on: https://github.com/UnknownShadow200/ClassicalSharp/wiki/Minecraft-Classic-map-generation-algorithm
Thanks to Jerralish for originally reverse engineering classic's algorithm, then preparing a high level overview of the algorithm.
I believe this process adheres to clean room reverse engineering.
Copyright 2014 - 2017 ClassicalSharp | Licensed under BSD-3
*/
typedef struct Vector3I_ Vector3I;
/* Dimensions of the map trees are generated on. */
Int32 Tree_Width, Tree_Height, Tree_Length;