mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-17 19:45:23 -04:00
More work on porting EntityList to C, split up Entity.c into Entity.c and EntityComponent.c
This commit is contained in:
parent
3bed91af85
commit
db7d148a44
@ -72,8 +72,9 @@ namespace ClassicalSharp.Entities {
|
||||
|
||||
for (int i = 0; i < List.Length; i++) {
|
||||
if (List[i] == null) continue;
|
||||
if (i != closestId || i == SelfID)
|
||||
if (i != closestId || i == SelfID) {
|
||||
List[i].RenderName();
|
||||
}
|
||||
}
|
||||
|
||||
gfx.Texturing = false;
|
||||
@ -92,8 +93,9 @@ namespace ClassicalSharp.Entities {
|
||||
&& game.LocalPlayer.Hacks.CanSeeAllNames;
|
||||
for (int i = 0; i < List.Length; i++) {
|
||||
bool hover = (i == closestId || allNames) && i != SelfID;
|
||||
if (List[i] != null && hover)
|
||||
if (List[i] != null && hover) {
|
||||
List[i].RenderName();
|
||||
}
|
||||
}
|
||||
|
||||
gfx.Texturing = false;
|
||||
@ -176,21 +178,18 @@ namespace ClassicalSharp.Entities {
|
||||
|
||||
gfx.SetBatchFormat(VertexFormat.P3fT2fC4b);
|
||||
ShadowComponent.Draw(game, List[SelfID]);
|
||||
if (ShadowMode == EntityShadow.CircleAll)
|
||||
DrawOtherShadows();
|
||||
if (ShadowMode == EntityShadow.CircleAll) {
|
||||
for (int i = 0; i < SelfID; i++) {
|
||||
if (List[i] == null) continue;
|
||||
Player p = List[i] as Player;
|
||||
if (p != null) ShadowComponent.Draw(game, p);
|
||||
}
|
||||
}
|
||||
|
||||
gfx.AlphaArgBlend = false;
|
||||
gfx.DepthWrite = true;
|
||||
gfx.AlphaBlending = false;
|
||||
gfx.Texturing = false;
|
||||
}
|
||||
|
||||
void DrawOtherShadows() {
|
||||
for (int i = 0; i < SelfID; i++) {
|
||||
if (List[i] == null) continue;
|
||||
Player p = List[i] as Player;
|
||||
if (p != null) ShadowComponent.Draw(game, p);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -195,6 +195,7 @@
|
||||
<ClInclude Include="Drawer.h" />
|
||||
<ClInclude Include="Drawer2D.h" />
|
||||
<ClInclude Include="Entity.h" />
|
||||
<ClInclude Include="EntityComponents.h" />
|
||||
<ClInclude Include="EnvRenderer.h" />
|
||||
<ClInclude Include="ErrorHandler.h" />
|
||||
<ClInclude Include="Event.h" />
|
||||
@ -270,6 +271,7 @@
|
||||
<ClCompile Include="DisplayDevice.c" />
|
||||
<ClCompile Include="Drawer.c" />
|
||||
<ClCompile Include="Drawer2D.c" />
|
||||
<ClCompile Include="EntityComponents.c" />
|
||||
<ClCompile Include="EnvRenderer.c" />
|
||||
<ClCompile Include="Event.c" />
|
||||
<ClCompile Include="ExtMath.c" />
|
||||
|
@ -378,6 +378,9 @@
|
||||
<ClInclude Include="Hotkeys.h">
|
||||
<Filter>Header Files\Game</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="EntityComponents.h">
|
||||
<Filter>Header Files\Entities</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Noise.c">
|
||||
@ -587,5 +590,8 @@
|
||||
<ClCompile Include="Hotkeys.c">
|
||||
<Filter>Source Files\Game</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="EntityComponents.c">
|
||||
<Filter>Source Files\Entities</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -352,7 +352,7 @@ void Gfx_SetFogEnd(Real32 value) {
|
||||
}
|
||||
|
||||
D3DFOGMODE d3d9_fogTableMode = D3DFOG_NONE;
|
||||
void Gfx_SetFogMode(Fog fogMode) {
|
||||
void Gfx_SetFogMode(Int32 fogMode) {
|
||||
D3DFOGMODE mode = d3d9_modes[fogMode];
|
||||
if (mode == d3d9_fogTableMode) return;
|
||||
|
||||
@ -376,7 +376,7 @@ void Gfx_SetAlphaTest(bool enabled) {
|
||||
|
||||
D3DCMPFUNC d3d9_alphaTestFunc = 0;
|
||||
Int32 d3d9_alphaTestRef = 0;
|
||||
void Gfx_SetAlphaTestFunc(CompareFunc compareFunc, Real32 refValue) {
|
||||
void Gfx_SetAlphaTestFunc(Int32 compareFunc, Real32 refValue) {
|
||||
d3d9_alphaTestFunc = d3d9_compareFuncs[compareFunc];
|
||||
D3D9_SetRenderState(d3d9_alphaTestFunc, D3DRS_ALPHAFUNC, "D3D9_SetAlphaTest_Func");
|
||||
d3d9_alphaTestRef = (Int32)(refValue * 255);
|
||||
@ -393,7 +393,7 @@ void Gfx_SetAlphaBlending(bool enabled) {
|
||||
|
||||
D3DBLEND d3d9_srcBlendFunc = 0;
|
||||
D3DBLEND d3d9_dstBlendFunc = 0;
|
||||
void Gfx_SetAlphaBlendFunc(BlendFunc srcBlendFunc, BlendFunc dstBlendFunc) {
|
||||
void Gfx_SetAlphaBlendFunc(Int32 srcBlendFunc, Int32 dstBlendFunc) {
|
||||
d3d9_srcBlendFunc = d3d9_blendFuncs[srcBlendFunc];
|
||||
D3D9_SetRenderState(d3d9_srcBlendFunc, D3DRS_SRCBLEND, "D3D9_SetAlphaBlendFunc_Src");
|
||||
d3d9_dstBlendFunc = d3d9_blendFuncs[dstBlendFunc];
|
||||
@ -425,7 +425,7 @@ void Gfx_SetDepthTest(bool enabled) {
|
||||
}
|
||||
|
||||
D3DCMPFUNC d3d9_depthTestFunc = 0;
|
||||
void Gfx_SetDepthTestFunc(CompareFunc compareFunc) {
|
||||
void Gfx_SetDepthTestFunc(Int32 compareFunc) {
|
||||
d3d9_depthTestFunc = d3d9_compareFuncs[compareFunc];
|
||||
D3D9_SetRenderState(d3d9_alphaTestFunc, D3DRS_ZFUNC, "D3D9_SetDepthTestFunc");
|
||||
}
|
||||
@ -442,7 +442,7 @@ void Gfx_SetDepthWrite(bool enabled) {
|
||||
}
|
||||
|
||||
|
||||
GfxResourceID Gfx_CreateDynamicVb(VertexFormat vertexFormat, Int32 maxVertices) {
|
||||
GfxResourceID Gfx_CreateDynamicVb(Int32 vertexFormat, Int32 maxVertices) {
|
||||
Int32 size = maxVertices * Gfx_strideSizes[vertexFormat];
|
||||
IDirect3DVertexBuffer9* vbuffer;
|
||||
ReturnCode hresult = IDirect3DDevice9_CreateVertexBuffer(device, size, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY,
|
||||
@ -462,7 +462,7 @@ void D3D9_SetVbData(IDirect3DVertexBuffer9* buffer, void* data, Int32 size, cons
|
||||
ErrorHandler_CheckOrFail(hresult, unlockMsg);
|
||||
}
|
||||
|
||||
GfxResourceID Gfx_CreateVb(void* vertices, VertexFormat vertexFormat, Int32 count) {
|
||||
GfxResourceID Gfx_CreateVb(void* vertices, Int32 vertexFormat, Int32 count) {
|
||||
Int32 size = count * Gfx_strideSizes[vertexFormat];
|
||||
IDirect3DVertexBuffer9* vbuffer;
|
||||
ReturnCode hresult = IDirect3DDevice9_CreateVertexBuffer(device, size, D3DUSAGE_WRITEONLY,
|
||||
@ -510,8 +510,8 @@ void Gfx_BindIb(GfxResourceID ib) {
|
||||
void Gfx_DeleteVb(GfxResourceID* vb) { D3D9_FreeResource(vb); }
|
||||
void Gfx_DeleteIb(GfxResourceID* ib) { D3D9_FreeResource(ib); }
|
||||
|
||||
VertexFormat d3d9_batchFormat = -1;
|
||||
void Gfx_SetBatchFormat(VertexFormat format) {
|
||||
Int32 d3d9_batchFormat = -1;
|
||||
void Gfx_SetBatchFormat(Int32 format) {
|
||||
if (format == d3d9_batchFormat) return;
|
||||
d3d9_batchFormat = format;
|
||||
|
||||
@ -553,7 +553,7 @@ void Gfx_DrawIndexedVb_TrisT2fC4b(Int32 verticesCount, Int32 startVertex) {
|
||||
}
|
||||
|
||||
|
||||
void Gfx_SetMatrixMode(MatrixType matrixType) {
|
||||
void Gfx_SetMatrixMode(Int32 matrixType) {
|
||||
if (matrixType == MATRIX_TYPE_PROJECTION) {
|
||||
curStack = &projStack;
|
||||
} else if (matrixType == MATRIX_TYPE_MODELVIEW) {
|
||||
|
@ -9,6 +9,8 @@
|
||||
#include "Platform.h"
|
||||
#include "Funcs.h"
|
||||
#include "ModelCache.h"
|
||||
#include "GraphicsAPI.h"
|
||||
#include "Intersection.h"
|
||||
|
||||
Real32 LocationUpdate_Clamp(Real32 degrees) {
|
||||
degrees = Math_Mod(degrees, 360.0f);
|
||||
@ -195,604 +197,176 @@ bool Entity_TouchesAnyWater(Entity* entity) {
|
||||
}
|
||||
|
||||
|
||||
#define ANIM_MAX_ANGLE (110 * MATH_DEG2RAD)
|
||||
#define ANIM_ARM_MAX (60.0f * MATH_DEG2RAD)
|
||||
#define ANIM_LEG_MAX (80.0f * MATH_DEG2RAD)
|
||||
#define ANIM_IDLE_MAX (3.0f * MATH_DEG2RAD)
|
||||
#define ANIM_IDLE_XPERIOD (2.0f * MATH_PI / 5.0f)
|
||||
#define ANIM_IDLE_ZPERIOD (2.0f * MATH_PI / 3.5f)
|
||||
|
||||
void AnimatedComp_DoTilt(Real32* tilt, bool reduce) {
|
||||
if (reduce) {
|
||||
(*tilt) *= 0.84f;
|
||||
} else {
|
||||
(*tilt) += 0.1f;
|
||||
}
|
||||
Math_Clamp(*tilt, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
void AnimatedComp_PerpendicularAnim(AnimatedComp* anim, Real32 flapSpeed, Real32 idleXRot, Real32 idleZRot, bool left) {
|
||||
Real32 verAngle = 0.5f + 0.5f * Math_Sin(anim->WalkTime * flapSpeed);
|
||||
Real32 zRot = -idleZRot - verAngle * anim->Swing * ANIM_MAX_ANGLE;
|
||||
Real32 horAngle = Math_Cos(anim->WalkTime) * anim->Swing * ANIM_ARM_MAX * 1.5f;
|
||||
Real32 xRot = idleXRot + horAngle;
|
||||
|
||||
if (left) {
|
||||
anim->LeftArmX = xRot; anim->LeftArmZ = zRot;
|
||||
} else {
|
||||
anim->RightArmX = xRot; anim->RightArmZ = zRot;
|
||||
EntityID 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]->Tick(Entities_List[i], task);
|
||||
}
|
||||
}
|
||||
|
||||
void AnimatedComp_CalcHumanAnim(AnimatedComp* anim, Real32 idleXRot, Real32 idleZRot) {
|
||||
AnimatedComp_PerpendicularAnim(anim, 0.23f, idleXRot, idleZRot, true);
|
||||
AnimatedComp_PerpendicularAnim(anim, 0.28f, idleXRot, idleZRot, false);
|
||||
anim->RightArmX = -anim->RightArmX; anim->RightArmZ = -anim->RightArmZ;
|
||||
}
|
||||
|
||||
void AnimatedComp_Init(AnimatedComp* anim) {
|
||||
anim->BobbingHor = 0.0f; anim->BobbingVer = 0.0f; anim->BobbingModel = 0.0f;
|
||||
anim->WalkTime = 0.0f; anim->Swing = 0.0f; anim->BobStrength = 1.0f;
|
||||
anim->WalkTimeO = 0.0f; anim->SwingO = 0.0f; anim->BobStrengthO = 1.0f;
|
||||
anim->WalkTimeN = 0.0f; anim->SwingN = 0.0f; anim->BobStrengthN = 1.0f;
|
||||
|
||||
anim->LeftLegX = 0.0f; anim->LeftLegZ = 0.0f; anim->RightLegX = 0.0f; anim->RightLegZ = 0.0f;
|
||||
anim->LeftArmX = 0.0f; anim->LeftArmZ = 0.0f; anim->RightArmX = 0.0f; anim->RightArmZ = 0.0f;
|
||||
}
|
||||
|
||||
void AnimatedComp_Update(AnimatedComp* anim, Vector3 oldPos, Vector3 newPos, Real64 delta, bool onGround) {
|
||||
anim->WalkTimeO = anim->WalkTimeN;
|
||||
anim->SwingO = anim->SwingN;
|
||||
Real32 dx = newPos.X - oldPos.X;
|
||||
Real32 dz = newPos.Z - oldPos.Z;
|
||||
Real32 distance = Math_Sqrt(dx * dx + dz * dz);
|
||||
|
||||
if (distance > 0.05f) {
|
||||
Real32 walkDelta = distance * 2 * (Real32)(20 * delta);
|
||||
anim->WalkTimeN += walkDelta;
|
||||
anim->SwingN += (Real32)delta * 3;
|
||||
} else {
|
||||
anim->SwingN -= (Real32)delta * 3;
|
||||
}
|
||||
Math_Clamp(anim->SwingN, 0.0f, 1.0f);
|
||||
|
||||
/* TODO: the Tilt code was designed for 60 ticks/second, fix it up for 20 ticks/second */
|
||||
anim->BobStrengthO = anim->BobStrengthN;
|
||||
Int32 i;
|
||||
for (i = 0; i < 3; i++) {
|
||||
AnimatedComp_DoTilt(&anim->BobStrengthN, !Game_ViewBobbing || !onGround);
|
||||
void Entities_RenderModels(Real64 delta, Real32 t) {
|
||||
Gfx_SetTexturing(true);
|
||||
Gfx_SetAlphaTest(true);
|
||||
UInt32 i;
|
||||
for (i = 0; i < ENTITIES_MAX_COUNT; i++) {
|
||||
if (Entities_List[i] == NULL) continue;
|
||||
Entities_List[i]->RenderModel(Entities_List[i], delta, t);
|
||||
}
|
||||
Gfx_SetTexturing(false);
|
||||
Gfx_SetAlphaTest(false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void AnimatedComp_GetCurrent(AnimatedComp* anim, Real32 t, bool calcHumanAnims) {
|
||||
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);
|
||||
|
||||
Real32 idleTime = (Real32)Game_Accumulator;
|
||||
Real32 idleXRot = Math_Sin(idleTime * ANIM_IDLE_XPERIOD) * ANIM_IDLE_MAX;
|
||||
Real32 idleZRot = ANIM_IDLE_MAX + Math_Cos(idleTime * ANIM_IDLE_ZPERIOD) * ANIM_IDLE_MAX;
|
||||
|
||||
anim->LeftArmX = (Math_Cos(anim->WalkTime) * anim->Swing * ANIM_ARM_MAX) - idleXRot;
|
||||
anim->LeftArmZ = -idleZRot;
|
||||
anim->LeftLegX = -(Math_Cos(anim->WalkTime) * anim->Swing * ANIM_LEG_MAX);
|
||||
anim->LeftLegZ = 0;
|
||||
|
||||
anim->RightLegX = -anim->LeftLegX; anim->RightLegZ = -anim->LeftLegZ;
|
||||
anim->RightArmX = -anim->LeftArmX; anim->RightArmZ = -anim->LeftArmZ;
|
||||
|
||||
anim->BobbingHor = Math_Cos(anim->WalkTime) * anim->Swing * (2.5f / 16.0f);
|
||||
anim->BobbingVer = Math_AbsF(Math_Sin(anim->WalkTime)) * anim->Swing * (2.5f / 16.0f);
|
||||
anim->BobbingModel = Math_AbsF(Math_Cos(anim->WalkTime)) * anim->Swing * (4.0f / 16.0f);
|
||||
|
||||
if (calcHumanAnims && !Game_SimpleArmsAnim) {
|
||||
AnimatedComp_CalcHumanAnim(anim, idleXRot, idleZRot);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void TiltComp_Init(TiltComp* anim) {
|
||||
anim->TiltX = 0.0f; anim->TiltY = 0.0f; anim->VelTiltStrength = 1.0f;
|
||||
anim->VelTiltStrengthO = 1.0f; anim->VelTiltStrengthN = 1.0f;
|
||||
}
|
||||
|
||||
void TiltComp_Update(TiltComp* anim, Real64 delta) {
|
||||
anim->VelTiltStrengthO = anim->VelTiltStrengthN;
|
||||
void Entities_RenderNames(Real64 delta) {
|
||||
LocalPlayer* p = &LocalPlayer_Instance;
|
||||
closestId = Entities_GetCloset(&p->Base.Base);
|
||||
if (!p->Hacks.CanSeeAllNames || Entities_NameMode != NAME_MODE_ALL) return;
|
||||
|
||||
/* TODO: the Tilt code was designed for 60 ticks/second, fix it up for 20 ticks/second */
|
||||
Int32 i;
|
||||
for (i = 0; i < 3; i++) {
|
||||
AnimatedComp_DoTilt(&anim->VelTiltStrengthN, p->Hacks.Noclip || p->Hacks.Flying);
|
||||
Gfx_SetTexturing(true);
|
||||
Gfx_SetAlphaTest(true);
|
||||
bool hadFog = Gfx_GetFog();
|
||||
if (hadFog) Gfx_SetFog(false);
|
||||
|
||||
UInt32 i;
|
||||
for (i = 0; i < ENTITIES_MAX_COUNT; i++) {
|
||||
if (Entities_List[i] == NULL) continue;
|
||||
if (i != closestId || i == ENTITIES_SELF_ID) {
|
||||
Entities_List[i]->RenderName(Entities_List[i]);
|
||||
}
|
||||
}
|
||||
|
||||
Gfx_SetTexturing(false);
|
||||
Gfx_SetAlphaTest(false);
|
||||
if (hadFog) Gfx_SetFog(true);
|
||||
}
|
||||
|
||||
void TiltComp_GetCurrent(TiltComp* anim, Real32 t) {
|
||||
void Entities_RenderHoveredNames(Real64 delta) {
|
||||
LocalPlayer* p = &LocalPlayer_Instance;
|
||||
anim->VelTiltStrength = Math_Lerp(anim->VelTiltStrengthO, anim->VelTiltStrengthN, t);
|
||||
bool allNames = !(Entities_NameMode == NAME_MODE_HOVERED || Entities_NameMode == NAME_MODE_ALL)
|
||||
&& p->Hacks.CanSeeAllNames;
|
||||
|
||||
AnimatedComp* pAnim = &p->Base.Base.Anim;
|
||||
anim->TiltX = Math_Cos(pAnim->WalkTime) * pAnim->Swing * (0.15f * MATH_DEG2RAD);
|
||||
anim->TiltY = Math_Sin(pAnim->WalkTime) * pAnim->Swing * (0.15f * MATH_DEG2RAD);
|
||||
}
|
||||
Gfx_SetTexturing(true);
|
||||
Gfx_SetAlphaTest(true);
|
||||
Gfx_SetDepthTest(false);
|
||||
bool hadFog = Gfx_GetFog();
|
||||
if (hadFog) Gfx_SetFog(false);
|
||||
|
||||
|
||||
void HacksComp_SetAll(HacksComp* hacks, bool allowed) {
|
||||
hacks->CanAnyHacks = allowed; hacks->CanFly = allowed;
|
||||
hacks->CanNoclip = allowed; hacks->CanRespawn = allowed;
|
||||
hacks->CanSpeed = allowed; hacks->CanPushbackBlocks = allowed;
|
||||
hacks->CanUseThirdPersonCamera = allowed;
|
||||
}
|
||||
|
||||
void HacksComp_Init(HacksComp* hacks) {
|
||||
Platform_MemSet(hacks, 0, sizeof(HacksComp));
|
||||
HacksComp_SetAll(hacks, true);
|
||||
hacks->SpeedMultiplier = 10.0f;
|
||||
hacks->Enabled = true;
|
||||
hacks->CanSeeAllNames = true;
|
||||
hacks->CanDoubleJump = true;
|
||||
hacks->BaseHorSpeed = 1.0f;
|
||||
hacks->MaxJumps = 1;
|
||||
hacks->NoclipSlide = true;
|
||||
hacks->CanBePushed = true;
|
||||
hacks->HacksFlags = String_InitAndClear(&hacks->HacksFlagsBuffer[0], 128);
|
||||
}
|
||||
|
||||
bool HacksComp_CanJumpHigher(HacksComp* hacks) {
|
||||
return hacks->Enabled && hacks->CanAnyHacks && hacks->CanSpeed;
|
||||
}
|
||||
|
||||
bool HacksComp_Floating(HacksComp* hacks) {
|
||||
return hacks->Noclip || hacks->Flying;
|
||||
}
|
||||
|
||||
String HacksComp_GetFlagValue(String* flag, HacksComp* hacks) {
|
||||
String* joined = &hacks->HacksFlags;
|
||||
Int32 start = String_IndexOfString(joined, flag);
|
||||
if (start < 0) return String_MakeNull();
|
||||
start += flag->length;
|
||||
|
||||
Int32 end = String_IndexOf(joined, ' ', start);
|
||||
if (end < 0) end = joined->length;
|
||||
|
||||
return String_UNSAFE_Substring(joined, start, end - start);
|
||||
}
|
||||
|
||||
void HacksComp_ParseHorizontalSpeed(HacksComp* hacks) {
|
||||
String horSpeedFlag = String_FromConst("horspeed=");
|
||||
String speedStr = HacksComp_GetFlagValue(&horSpeedFlag, hacks);
|
||||
if (speedStr.length == 0) return;
|
||||
|
||||
Real32 speed = 0.0f;
|
||||
if (!Convert_TryParseReal32(&speedStr, &speed) || speed <= 0.0f) return;
|
||||
hacks->BaseHorSpeed = speed;
|
||||
}
|
||||
|
||||
void HacksComp_ParseMultiSpeed(HacksComp* hacks) {
|
||||
String jumpsFlag = String_FromConst("jumps=");
|
||||
String jumpsStr = HacksComp_GetFlagValue(&jumpsFlag, hacks);
|
||||
if (jumpsStr.length == 0) return;
|
||||
|
||||
Int32 jumps = 0;
|
||||
if (!Convert_TryParseInt32(&jumpsStr, &jumps) || jumps < 0) return;
|
||||
hacks->MaxJumps = jumps;
|
||||
}
|
||||
|
||||
void HacksComp_ParseFlag(HacksComp* hacks, const UInt8* incFlag, const UInt8* excFlag, bool* target) {
|
||||
String include = String_FromReadonly(incFlag);
|
||||
String exclude = String_FromReadonly(excFlag);
|
||||
String* joined = &hacks->HacksFlags;
|
||||
|
||||
if (String_ContainsString(joined, &include)) {
|
||||
*target = true;
|
||||
} else if (String_ContainsString(joined, &exclude)) {
|
||||
*target = false;
|
||||
}
|
||||
}
|
||||
|
||||
void HacksComp_ParseAllFlag(HacksComp* hacks, const UInt8* incFlag, const UInt8* excFlag) {
|
||||
String include = String_FromReadonly(incFlag);
|
||||
String exclude = String_FromReadonly(excFlag);
|
||||
String* joined = &hacks->HacksFlags;
|
||||
|
||||
if (String_ContainsString(joined, &include)) {
|
||||
HacksComp_SetAll(hacks, true);
|
||||
} else if (String_ContainsString(joined, &exclude)) {
|
||||
HacksComp_SetAll(hacks, false);
|
||||
}
|
||||
}
|
||||
|
||||
void HacksComp_SetUserType(HacksComp* hacks, UInt8 value) {
|
||||
bool isOp = value >= 100 && value <= 127;
|
||||
hacks->UserType = value;
|
||||
hacks->CanSeeAllNames = isOp;
|
||||
|
||||
Block_CanPlace[BLOCK_BEDROCK] = isOp;
|
||||
Block_CanDelete[BLOCK_BEDROCK] = isOp;
|
||||
Block_CanPlace[BLOCK_WATER] = isOp;
|
||||
Block_CanPlace[BLOCK_STILL_WATER] = isOp;
|
||||
Block_CanPlace[BLOCK_LAVA] = isOp;
|
||||
Block_CanPlace[BLOCK_STILL_LAVA] = isOp;
|
||||
}
|
||||
|
||||
void HacksComp_CheckConsistency(HacksComp* hacks) {
|
||||
if (!hacks->CanFly || !hacks->Enabled) {
|
||||
hacks->Flying = false; hacks->FlyingDown = false; hacks->FlyingUp = false;
|
||||
}
|
||||
if (!hacks->CanNoclip || !hacks->Enabled) {
|
||||
hacks->Noclip = false;
|
||||
}
|
||||
if (!hacks->CanSpeed || !hacks->Enabled) {
|
||||
hacks->Speeding = false; hacks->HalfSpeeding = false;
|
||||
}
|
||||
|
||||
hacks->CanDoubleJump = hacks->CanAnyHacks && hacks->Enabled && hacks->CanSpeed;
|
||||
hacks->CanSeeAllNames = hacks->CanAnyHacks && hacks->CanSeeAllNames;
|
||||
|
||||
if (!hacks->CanUseThirdPersonCamera || !hacks->Enabled) {
|
||||
Camera_CycleActive();
|
||||
}
|
||||
}
|
||||
|
||||
void HacksComp_UpdateState(HacksComp* hacks) {
|
||||
HacksComp_SetAll(hacks, true);
|
||||
if (hacks->HacksFlags.length == 0) return;
|
||||
|
||||
hacks->BaseHorSpeed = 1;
|
||||
hacks->MaxJumps = 1;
|
||||
hacks->CanBePushed = true;
|
||||
|
||||
/* By default (this is also the case with WoM), we can use hacks. */
|
||||
String excHacks = String_FromConst("-hax");
|
||||
if (String_ContainsString(&hacks->HacksFlags, &excHacks)) {
|
||||
HacksComp_SetAll(hacks, false);
|
||||
}
|
||||
|
||||
HacksComp_ParseFlag(hacks, "+fly", "-fly", &hacks->CanFly);
|
||||
HacksComp_ParseFlag(hacks, "+noclip", "-noclip", &hacks->CanNoclip);
|
||||
HacksComp_ParseFlag(hacks, "+speed", "-speed", &hacks->CanSpeed);
|
||||
HacksComp_ParseFlag(hacks, "+respawn", "-respawn", &hacks->CanRespawn);
|
||||
HacksComp_ParseFlag(hacks, "+push", "-push", &hacks->CanBePushed);
|
||||
|
||||
if (hacks->UserType == 0x64) {
|
||||
HacksComp_ParseAllFlag(hacks, "+ophax", "-ophax");
|
||||
}
|
||||
HacksComp_ParseHorizontalSpeed(hacks);
|
||||
HacksComp_ParseMultiSpeed(hacks);
|
||||
|
||||
HacksComp_CheckConsistency(hacks);
|
||||
Event_RaiseVoid(&UserEvents_HackPermissionsChanged);
|
||||
}
|
||||
|
||||
|
||||
void InterpComp_RemoveOldestRotY(InterpComp* interp) {
|
||||
Int32 i;
|
||||
for (i = 0; i < Array_NumElements(interp->RotYStates); i++) {
|
||||
interp->RotYStates[i] = interp->RotYStates[i + 1];
|
||||
}
|
||||
interp->RotYCount--;
|
||||
}
|
||||
|
||||
void InterpComp_AddRotY(InterpComp* interp, Real32 state) {
|
||||
if (interp->RotYCount == Array_NumElements(interp->RotYStates)) {
|
||||
InterpComp_RemoveOldestRotY(interp);
|
||||
}
|
||||
interp->RotYStates[interp->RotYCount] = state; interp->RotYCount++;
|
||||
}
|
||||
|
||||
void InterpComp_AdvanceRotY(InterpComp* interp) {
|
||||
interp->PrevRotY = interp->NextRotY;
|
||||
if (interp->RotYCount == 0) return;
|
||||
|
||||
interp->NextRotY = interp->RotYStates[0];
|
||||
InterpComp_RemoveOldestRotY(interp);
|
||||
}
|
||||
|
||||
void InterpComp_LerpAngles(InterpComp* interp, Entity* entity, Real32 t) {
|
||||
InterpState* prev = &interp->Prev;
|
||||
InterpState* next = &interp->Next;
|
||||
entity->HeadX = Math_LerpAngle(prev->HeadX, next->HeadX, t);
|
||||
entity->HeadY = Math_LerpAngle(prev->HeadY, next->HeadY, t);
|
||||
entity->RotX = Math_LerpAngle(prev->RotX, next->RotX, t);
|
||||
entity->RotY = Math_LerpAngle(interp->PrevRotY, interp->NextRotY, t);
|
||||
entity->RotZ = Math_LerpAngle(prev->RotZ, next->RotZ, t);
|
||||
}
|
||||
|
||||
void InterpComp_SetPos(InterpState* state, LocationUpdate* update) {
|
||||
if (update->RelativePosition) {
|
||||
Vector3_Add(&state->Pos, &state->Pos, &update->Pos);
|
||||
} else {
|
||||
state->Pos = update->Pos;
|
||||
}
|
||||
}
|
||||
|
||||
Real32 NetInterpComp_Next(Real32 next, Real32 cur) {
|
||||
if (next == LOCATIONUPDATE_EXCLUDED) return cur;
|
||||
return next;
|
||||
}
|
||||
|
||||
void NetInterpComp_RemoveOldestState(NetInterpComp* interp) {
|
||||
Int32 i;
|
||||
for (i = 0; i < Array_NumElements(interp->States); i++) {
|
||||
interp->States[i] = interp->States[i + 1];
|
||||
}
|
||||
interp->StatesCount--;
|
||||
}
|
||||
|
||||
void NetInterpComp_AddState(NetInterpComp* interp, InterpState state) {
|
||||
if (interp->StatesCount == Array_NumElements(interp->States)) {
|
||||
NetInterpComp_RemoveOldestState(interp);
|
||||
}
|
||||
interp->States[interp->StatesCount] = state; interp->StatesCount++;
|
||||
}
|
||||
|
||||
void NetInterpComp_SetLocation(NetInterpComp* interp, LocationUpdate* update, bool interpolate) {
|
||||
InterpState last = interp->Cur;
|
||||
InterpState* cur = &interp->Cur;
|
||||
if (update->IncludesPosition) {
|
||||
InterpComp_SetPos(cur, update);
|
||||
}
|
||||
|
||||
cur->RotX = NetInterpComp_Next(update->RotX, cur->RotX);
|
||||
cur->RotZ = NetInterpComp_Next(update->RotZ, cur->RotZ);
|
||||
cur->HeadX = NetInterpComp_Next(update->HeadX, cur->HeadX);
|
||||
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;
|
||||
} else {
|
||||
/* Smoother interpolation by also adding midpoint. */
|
||||
InterpState mid;
|
||||
Vector3_Lerp(&mid.Pos, &last.Pos, &cur->Pos, 0.5f);
|
||||
mid.RotX = Math_LerpAngle(last.RotX, cur->RotX, 0.5f);
|
||||
mid.RotZ = Math_LerpAngle(last.RotZ, cur->RotZ, 0.5f);
|
||||
mid.HeadX = Math_LerpAngle(last.HeadX, cur->HeadX, 0.5f);
|
||||
mid.HeadY = Math_LerpAngle(last.HeadY, cur->HeadY, 0.5f);
|
||||
NetInterpComp_AddState(interp, mid);
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
void NetInterpComp_AdvanceState(NetInterpComp* interp) {
|
||||
interp->Base.Prev = interp->Base.Next;
|
||||
if (interp->StatesCount > 0) {
|
||||
interp->Base.Next = interp->States[0];
|
||||
NetInterpComp_RemoveOldestState(interp);
|
||||
}
|
||||
InterpComp_AdvanceRotY(&interp->Base);
|
||||
}
|
||||
|
||||
Real32 LocalInterpComp_Next(Real32 next, Real32 cur, Real32* last, bool interpolate) {
|
||||
if (next == LOCATIONUPDATE_EXCLUDED) return cur;
|
||||
if (!interpolate) *last = next;
|
||||
return next;
|
||||
}
|
||||
|
||||
void LocalInterpComp_SetLocation(InterpComp* interp, LocationUpdate* update, bool interpolate) {
|
||||
Entity* entity = &LocalPlayer_Instance.Base.Base;
|
||||
InterpState* prev = &interp->Prev;
|
||||
InterpState* next = &interp->Next;
|
||||
|
||||
if (update->IncludesPosition) {
|
||||
InterpComp_SetPos(next, update);
|
||||
Real32 blockOffset = next->Pos.Y - Math_Floor(next->Pos.Y);
|
||||
if (blockOffset < ENTITY_ADJUSTMENT) {
|
||||
next->Pos.Y += ENTITY_ADJUSTMENT;
|
||||
}
|
||||
if (!interpolate) {
|
||||
prev->Pos = next->Pos;
|
||||
entity->Position = next->Pos;
|
||||
UInt32 i;
|
||||
for (i = 0; i < ENTITIES_MAX_COUNT; i++) {
|
||||
if (Entities_List[i] == NULL) continue;
|
||||
if ((i == closestId || allNames) && i != ENTITIES_SELF_ID) {
|
||||
Entities_List[i]->RenderName(Entities_List[i]);
|
||||
}
|
||||
}
|
||||
|
||||
next->RotX = LocalInterpComp_Next(update->RotX, next->RotX, &prev->RotX, interpolate);
|
||||
next->RotZ = LocalInterpComp_Next(update->RotZ, next->RotZ, &prev->RotZ, interpolate);
|
||||
next->HeadX = LocalInterpComp_Next(update->HeadX, next->HeadX, &prev->HeadX, interpolate);
|
||||
next->HeadY = LocalInterpComp_Next(update->RotY, next->HeadY, &prev->HeadY, interpolate);
|
||||
|
||||
if (update->RotY != LOCATIONUPDATE_EXCLUDED) {
|
||||
if (!interpolate) {
|
||||
interp->NextRotY = update->RotY;
|
||||
entity->RotY = update->RotY;
|
||||
interp->RotYCount = 0;
|
||||
} else {
|
||||
/* Body Y rotation lags slightly behind */
|
||||
InterpComp_AddRotY(interp, Math_LerpAngle(prev->HeadY, next->HeadY, 0.33333333f));
|
||||
InterpComp_AddRotY(interp, Math_LerpAngle(prev->HeadY, next->HeadY, 0.66666667f));
|
||||
InterpComp_AddRotY(interp, Math_LerpAngle(prev->HeadY, next->HeadY, 1.00000000f));
|
||||
|
||||
interp->NextRotY = interp->RotYStates[0];
|
||||
}
|
||||
}
|
||||
|
||||
InterpComp_LerpAngles(interp, entity, 0.0f);
|
||||
Gfx_SetTexturing(false);
|
||||
Gfx_SetAlphaTest(false);
|
||||
Gfx_SetDepthTest(true);
|
||||
if (hadFog) Gfx_SetFog(true);
|
||||
}
|
||||
|
||||
void LocalInterpComp_AdvanceState(InterpComp* interp) {
|
||||
Entity* entity = &LocalPlayer_Instance.Base.Base;
|
||||
interp->Prev = interp->Next;
|
||||
entity->Position = interp->Next.Pos;
|
||||
InterpComp_AdvanceRotY(interp);
|
||||
void Entities_ContextLost(void) {
|
||||
UInt32 i;
|
||||
for (i = 0; i < ENTITIES_MAX_COUNT; i++) {
|
||||
if (Entities_List[i] == NULL) continue;
|
||||
Entities_List[i]->ContextLost(Entities_List[i]);
|
||||
}
|
||||
}
|
||||
|
||||
enum NameMode { Hovered, All, AllHovered, AllUnscaled }
|
||||
void Entities_ContextRecreated(void) {
|
||||
UInt32 i;
|
||||
for (i = 0; i < ENTITIES_MAX_COUNT; i++) {
|
||||
if (Entities_List[i] == NULL) continue;
|
||||
Entities_List[i]->ContextRecreated(Entities_List[i]);
|
||||
}
|
||||
}
|
||||
|
||||
enum EntityShadow { None, SnapToBlock, Circle, CircleAll, }
|
||||
void Entities_ChatFontChanged(void) {
|
||||
UInt32 i;
|
||||
for (i = 0; i < ENTITIES_MAX_COUNT; i++) {
|
||||
if (Entities_List[i] == NULL) continue;
|
||||
Player p = List[i] as Player;
|
||||
if (p != null) p.UpdateName();
|
||||
}
|
||||
}
|
||||
|
||||
const int MaxCount = 256;
|
||||
const byte SelfID = 255;
|
||||
void Entities_Init(void) {
|
||||
Event_RegisterVoid(&GfxEvents_ContextLost, Entities_ContextLost);
|
||||
Event_RegisterVoid(&GfxEvents_ContextRecreated, Entities_ContextRecreated);
|
||||
Event_RegisterVoid(&ChatEvents_FontChanged, Entities_ChatFontChanged);
|
||||
|
||||
public Entity[] List = new Entity[MaxCount];
|
||||
public EntityShadow ShadowMode = EntityShadow.None;
|
||||
byte closestId;
|
||||
NameMode NamesMode = NameMode.Hovered;
|
||||
Entities_NameMode = Options_GetEnum(OptionsKey.NamesMode, NameMode.Hovered);
|
||||
if (Game_ClassicMode) Entities_NameMode = NAME_MODE_HOVERED;
|
||||
Entities_ShadowMode = Options_GetEnum(OptionsKey.EntityShadow, EntityShadow.None);
|
||||
if (Game_ClassicMode) Entities_ShadowMode = SHADOW_MODE_NONE;
|
||||
}
|
||||
|
||||
void Entities_Init(void) {
|
||||
game.Graphics.ContextLost += ContextLost;
|
||||
game.Graphics.ContextRecreated += ContextRecreated;
|
||||
game.Events.ChatFontChanged += ChatFontChanged;
|
||||
|
||||
NamesMode = Options.GetEnum(OptionsKey.NamesMode, NameMode.Hovered);
|
||||
if (game.ClassicMode) NamesMode = NameMode.Hovered;
|
||||
ShadowMode = Options.GetEnum(OptionsKey.EntityShadow, EntityShadow.None);
|
||||
if (game.ClassicMode) ShadowMode = EntityShadow.None;
|
||||
void Entities_Free(void) {
|
||||
UInt32 i;
|
||||
for (i = 0; i < ENTITIES_MAX_COUNT; i++) {
|
||||
if (Entities_List[i] == NULL) continue;
|
||||
Entities_Remove((EntityID)i);
|
||||
}
|
||||
|
||||
void Entities_Tick(ScheduledTask* task) {
|
||||
for (int i = 0; i < List.Length; i++) {
|
||||
if (List[i] == null) continue;
|
||||
List[i].Tick(task.Interval);
|
||||
Event_UnregisterVoid(&GfxEvents_ContextLost, Entities_ContextLost);
|
||||
Event_UnregisterVoid(&GfxEvents_ContextRecreated, Entities_ContextRecreated);
|
||||
Event_UnregisterVoid(&ChatEvents_FontChanged, Entities_ChatFontChanged);
|
||||
|
||||
if (ShadowComponent.shadowTex > 0) {
|
||||
game.Graphics.DeleteTexture(ref ShadowComponent.shadowTex);
|
||||
}
|
||||
}
|
||||
|
||||
void Entities_Remove(EntityID id) {
|
||||
Event_RaiseEntityID(&EntityEvents_Removed, id);
|
||||
Entities_List[id]->Despawn(Entities_List[id]);
|
||||
Entities_List[id] = NULL;
|
||||
}
|
||||
|
||||
EntityID Entities_GetCloset(Entity* src) {
|
||||
Vector3 eyePos = Entity_GetEyePosition(src);
|
||||
Vector3 dir = Vector3_GetDirVector(src->HeadY * MATH_DEG2RAD, src->HeadX * MATH_DEG2RAD);
|
||||
float closestDist = float.PositiveInfinity;
|
||||
EntityID targetId = ENTITIES_SELF_ID;
|
||||
|
||||
UInt32 i;
|
||||
for (i = 0; i < ENTITIES_SELF_ID; i++) { /* -1 because we don't want to pick against local player */
|
||||
Entity* entity = Entities_List[i];
|
||||
if (entity == NULL) continue;
|
||||
|
||||
Real32 t0, t1;
|
||||
if (Intersection_RayIntersectsRotatedBox(eyePos, dir, entity, &t0, &t1) && t0 < closestDist) {
|
||||
closestDist = t0;
|
||||
targetId = (EntityID)i;
|
||||
}
|
||||
}
|
||||
return targetId;
|
||||
}
|
||||
|
||||
void Entities_RenderModels(Real64 delta, Real32 t) {
|
||||
gfx.Texturing = true;
|
||||
gfx.AlphaTest = true;
|
||||
for (int i = 0; i < List.Length; i++) {
|
||||
if (List[i] == null) continue;
|
||||
List[i].RenderModel(delta, t);
|
||||
}
|
||||
gfx.Texturing = false;
|
||||
gfx.AlphaTest = false;
|
||||
}
|
||||
bool hadFog;
|
||||
void Entities_DrawShadows(void) {
|
||||
if (Entities_ShadowMode == SHADOW_MODE_NONE) return;
|
||||
ShadowComponent.boundShadowTex = false;
|
||||
|
||||
void Entities_RenderNames(Real64 delta) {
|
||||
closestId = GetClosetPlayer(game.LocalPlayer);
|
||||
if (!game.LocalPlayer.Hacks.CanSeeAllNames || NamesMode != NameMode.All) return;
|
||||
Gfx_SetAlphaArgBlend(true);
|
||||
Gfx_SetDepthWrite(false);
|
||||
Gfx_SetAlphaBlending(true);
|
||||
Gfx_SetTexturing(true);
|
||||
|
||||
gfx.Texturing = true;
|
||||
gfx.AlphaTest = true;
|
||||
hadFog = gfx.Fog;
|
||||
if (hadFog) gfx.Fog = false;
|
||||
|
||||
for (int i = 0; i < List.Length; i++) {
|
||||
if (List[i] == null) continue;
|
||||
if (i != closestId || i == SelfID)
|
||||
List[i].RenderName();
|
||||
}
|
||||
|
||||
gfx.Texturing = false;
|
||||
gfx.AlphaTest = false;
|
||||
if (hadFog) gfx.Fog = true;
|
||||
}
|
||||
|
||||
void Entities_RenderHoveredNames(Real64 delta) {
|
||||
gfx.Texturing = true;
|
||||
gfx.AlphaTest = true;
|
||||
gfx.DepthTest = false;
|
||||
hadFog = gfx.Fog;
|
||||
if (hadFog) gfx.Fog = false;
|
||||
|
||||
bool allNames = !(NamesMode == NameMode.Hovered || NamesMode == NameMode.All)
|
||||
&& game.LocalPlayer.Hacks.CanSeeAllNames;
|
||||
for (int i = 0; i < List.Length; i++) {
|
||||
bool hover = (i == closestId || allNames) && i != SelfID;
|
||||
if (List[i] != null && hover)
|
||||
List[i].RenderName();
|
||||
}
|
||||
|
||||
gfx.Texturing = false;
|
||||
gfx.AlphaTest = false;
|
||||
gfx.DepthTest = true;
|
||||
if (hadFog) gfx.Fog = true;
|
||||
}
|
||||
|
||||
void Entities_ContextLost(void) {
|
||||
for (int i = 0; i < List.Length; i++) {
|
||||
if (List[i] == null) continue;
|
||||
List[i].ContextLost();
|
||||
}
|
||||
}
|
||||
|
||||
void Entities_ContextRecreated(void) {
|
||||
for (int i = 0; i < List.Length; i++) {
|
||||
if (List[i] == null) continue;
|
||||
List[i].ContextRecreated();
|
||||
}
|
||||
}
|
||||
|
||||
void Entities_ChatFontChanged(void) {
|
||||
for (int i = 0; i < List.Length; i++) {
|
||||
if (List[i] == null) continue;
|
||||
Gfx_SetBatchFormat(VERTEX_FORMAT_P3FT2FC4B);
|
||||
ShadowComponent.Draw(Entities_List[ENTITIES_SELF_ID]);
|
||||
if (Entities_ShadowMode == SHADOW_MODE_CIRCLE_ALL) {
|
||||
UInt32 i;
|
||||
for (i = 0; i < ENTITIES_MAX_COUNT; i++) {
|
||||
if (Entities_List[i] == NULL) continue;
|
||||
Player p = List[i] as Player;
|
||||
if (p != null) p.UpdateName();
|
||||
if (p != null) ShadowComponent.Draw(p);
|
||||
}
|
||||
}
|
||||
|
||||
void Entities_Remove(EntityID id) {
|
||||
game.EntityEvents.RaiseRemoved(id);
|
||||
List[id].Despawn();
|
||||
List[id] = null;
|
||||
}
|
||||
|
||||
void Entities_Free(void) {
|
||||
for (int i = 0; i < List.Length; i++) {
|
||||
if (List[i] == null) continue;
|
||||
RemoveEntity((byte)i);
|
||||
}
|
||||
|
||||
game.Graphics.ContextLost -= ContextLost;
|
||||
game.Graphics.ContextRecreated -= ContextRecreated;
|
||||
game.Events.ChatFontChanged -= ChatFontChanged;
|
||||
|
||||
if (ShadowComponent.shadowTex > 0) {
|
||||
game.Graphics.DeleteTexture(ref ShadowComponent.shadowTex);
|
||||
}
|
||||
}
|
||||
|
||||
EntityID Entities_GetClosetPlayer(Player* src) {
|
||||
Vector3 eyePos = src.EyePosition;
|
||||
Vector3 dir = Utils.GetDirVector(src.HeadYRadians, src.HeadXRadians);
|
||||
float closestDist = float.PositiveInfinity;
|
||||
byte targetId = SelfID;
|
||||
|
||||
for (int i = 0; i < List.Length - 1; i++) { // -1 because we don't want to pick against local player
|
||||
Entity p = List[i];
|
||||
if (p == null) continue;
|
||||
|
||||
float t0, t1;
|
||||
if (Intersection.RayIntersectsRotatedBox(eyePos, dir, p, out t0, out t1) && t0 < closestDist) {
|
||||
closestDist = t0;
|
||||
targetId = (byte)i;
|
||||
}
|
||||
}
|
||||
return targetId;
|
||||
}
|
||||
|
||||
void Entities_DrawShadows(void) {
|
||||
if (ShadowMode == EntityShadow.None) return;
|
||||
ShadowComponent.boundShadowTex = false;
|
||||
IGraphicsApi gfx = game.Graphics;
|
||||
|
||||
gfx.AlphaArgBlend = true;
|
||||
gfx.DepthWrite = false;
|
||||
gfx.AlphaBlending = true;
|
||||
gfx.Texturing = true;
|
||||
|
||||
gfx.SetBatchFormat(VertexFormat.P3fT2fC4b);
|
||||
ShadowComponent.Draw(game, List[SelfID]);
|
||||
if (ShadowMode == EntityShadow.CircleAll)
|
||||
DrawOtherShadows();
|
||||
|
||||
gfx.AlphaArgBlend = false;
|
||||
gfx.DepthWrite = true;
|
||||
gfx.AlphaBlending = false;
|
||||
gfx.Texturing = false;
|
||||
}
|
||||
|
||||
void Entities_DrawOtherShadows(void) {
|
||||
for (int i = 0; i < SelfID; i++) {
|
||||
if (List[i] == null) continue;
|
||||
Player p = List[i] as Player;
|
||||
if (p != null) ShadowComponent.Draw(game, p);
|
||||
}
|
||||
}
|
||||
Gfx_SetAlphaArgBlend(false);
|
||||
Gfx_SetDepthWrite(true);
|
||||
Gfx_SetAlphaBlending(false);
|
||||
Gfx_SetTexturing(false);
|
||||
}
|
@ -1,12 +1,14 @@
|
||||
#ifndef CC_ENTITY_H
|
||||
#define CC_ENTITY_H
|
||||
#include "EntityComponents.h"
|
||||
#include "IModel.h"
|
||||
#include "Typedefs.h"
|
||||
#include "Vectors.h"
|
||||
#include "AABB.h"
|
||||
#include "GraphicsEnums.h"
|
||||
#include "Matrix.h"
|
||||
/* Represents an in-game entity. Also contains various components for entities.
|
||||
#include "GameStructs.h"
|
||||
/* Represents an in-game entity.
|
||||
Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
|
||||
*/
|
||||
typedef struct IModel_ IModel; /* Forward declaration */
|
||||
@ -18,6 +20,21 @@ typedef struct IModel_ IModel; /* Forward declaration */
|
||||
/* Maxmimum number of characters in a model name. */
|
||||
#define ENTITY_MAX_MODEL_LENGTH 10
|
||||
|
||||
#define ENTITIES_MAX_COUNT 256
|
||||
#define ENTITIES_SELF_ID 255
|
||||
|
||||
UInt32 Entities_NameMode;
|
||||
#define NAME_MODE_HOVERED 0
|
||||
#define NAME_MODE_ALL 1
|
||||
#define NAME_MODE_ALL_HOVERED 2
|
||||
#define NAME_MODE_ALL_UNSCALED 3
|
||||
|
||||
UInt32 Entities_ShadowMode;
|
||||
#define SHADOW_MODE_NONE 0
|
||||
#define SHADOW_MODE_SNAP_TO_BLOCK 1
|
||||
#define SHADOW_MODE_CIRCLE 2
|
||||
#define SHADOW_MODE_CIRCLE_ALL 3
|
||||
|
||||
typedef bool (*TouchesAny_Condition)(BlockID block);
|
||||
|
||||
/* Represents a location update for an entity. Can be a relative position, full position, and/or an orientation update. */
|
||||
@ -39,22 +56,6 @@ void LocationUpdate_MakeOri(LocationUpdate* update, Real32 rotY, Real32 headX);
|
||||
void LocationUpdate_MakePos(LocationUpdate* update, Vector3 pos, bool rel);
|
||||
void LocationUpdate_MakePosAndOri(LocationUpdate* update, Vector3 pos, Real32 rotY, Real32 headX, bool rel);
|
||||
|
||||
|
||||
/* Entity component that performs model animation depending on movement speed and time. */
|
||||
typedef struct AnimatedComp_ {
|
||||
Real32 BobbingHor, BobbingVer, BobbingModel;
|
||||
Real32 WalkTime, Swing, BobStrength;
|
||||
Real32 WalkTimeO, WalkTimeN, SwingO, SwingN, BobStrengthO, BobStrengthN;
|
||||
|
||||
Real32 LeftLegX, LeftLegZ, RightLegX, RightLegZ;
|
||||
Real32 LeftArmX, LeftArmZ, RightArmX, RightArmZ;
|
||||
} 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);
|
||||
|
||||
|
||||
/* Contains a model, along with position, velocity, and rotation. May also contain other fields and properties. */
|
||||
typedef struct Entity_ {
|
||||
Vector3 Position;
|
||||
@ -77,7 +78,13 @@ typedef struct Entity_ {
|
||||
bool NoShade;
|
||||
|
||||
/* TODO: SHOULD THESE BE A SEPARATE VTABLE STRUCT? (only need 1 shared pointer that way) */
|
||||
void (*Tick)(struct Entity_* entity, ScheduledTask* task);
|
||||
void (*SetLocation)(struct Entity_* entity, LocationUpdate* update, bool interpolate);
|
||||
void (*RenderModel)(struct Entity_* entity, Real64 deltaTime, Real32 t);
|
||||
void (*RenderName)(struct Entity_* entity);
|
||||
void (*ContextLost)(struct Entity_* entity);
|
||||
void (*ContextRecreated)(struct Entity_* entity);
|
||||
void (*Despawn)(struct Entity_* entity);
|
||||
PackedCol (*GetCol)(struct Entity_* entity);
|
||||
} Entity;
|
||||
|
||||
@ -93,85 +100,14 @@ bool Entity_TouchesAnyRope(Entity* entity);
|
||||
bool Entity_TouchesAnyLava(Entity* entity);
|
||||
bool Entity_TouchesAnyWater(Entity* entity);
|
||||
|
||||
|
||||
/* Entity component that performs tilt animation depending on movement speed and time. */
|
||||
typedef struct TiltComp_ {
|
||||
Real32 TiltX, TiltY, VelTiltStrength;
|
||||
Real32 VelTiltStrengthO, VelTiltStrengthN;
|
||||
} TiltComp;
|
||||
|
||||
void TiltComp_Init(TiltComp* anim);
|
||||
void TiltComp_Update(TiltComp* anim, Real64 delta);
|
||||
void TiltComp_GetCurrent(TiltComp* anim, Real32 t);
|
||||
|
||||
/* Entity component that performs management of hack states. */
|
||||
typedef struct HacksComponent_ {
|
||||
UInt8 UserType;
|
||||
/* Speed player move at, relative to normal speed, when the 'speeding' key binding is held down. */
|
||||
Real32 SpeedMultiplier;
|
||||
/* Whether blocks that the player places that intersect themselves, should cause the player to
|
||||
be pushed back in the opposite direction of the placed block. */
|
||||
bool PushbackPlacing;
|
||||
/* Whether the player should be able to step up whole blocks, instead of just slabs. */
|
||||
bool FullBlockStep;
|
||||
/* Whether the player has allowed hacks usage as an option. Note 'can use X' set by the server override this. */
|
||||
bool Enabled;
|
||||
|
||||
bool CanAnyHacks, CanUseThirdPersonCamera, CanSpeed, CanFly;
|
||||
bool CanRespawn, CanNoclip, CanPushbackBlocks,CanSeeAllNames;
|
||||
bool CanDoubleJump, CanBePushed;
|
||||
/* Maximum speed the entity can move at horizontally when CanSpeed is false. */
|
||||
Real32 BaseHorSpeed;
|
||||
/* Max amount of jumps the player can perform. */
|
||||
Int32 MaxJumps;
|
||||
|
||||
/* Whether the player should slide after letting go of movement buttons in noclip. */
|
||||
bool NoclipSlide;
|
||||
/* Whether the player has allowed the usage of fast double jumping abilities. */
|
||||
bool WOMStyleHacks;
|
||||
|
||||
bool Noclip, Flying,FlyingUp, FlyingDown, Speeding, HalfSpeeding;
|
||||
UInt8 HacksFlagsBuffer[String_BufferSize(128)];
|
||||
String HacksFlags;
|
||||
} HacksComp;
|
||||
|
||||
void HacksComp_Init(HacksComp* hacks);
|
||||
bool HacksComp_CanJumpHigher(HacksComp* hacks);
|
||||
bool HacksComp_Floating(HacksComp* hacks);
|
||||
void HacksComp_SetUserType(HacksComp* hacks, UInt8 value);
|
||||
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;
|
||||
|
||||
/* 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;
|
||||
|
||||
void InterpComp_LerpAngles(InterpComp* interp, Entity* entity, Real32 t);
|
||||
|
||||
void LocalInterpComp_SetLocation(InterpComp* interp, LocationUpdate* update, bool interpolate);
|
||||
void LocalInterpComp_AdvanceState(InterpComp* interp);
|
||||
|
||||
/* Entity component that performs interpolation for network players. */
|
||||
typedef struct NetInterpComp_ {
|
||||
InterpComp Base;
|
||||
/* Last known position and orientation sent by the server. */
|
||||
InterpState Cur;
|
||||
Int32 StatesCount;
|
||||
InterpState States[10];
|
||||
} NetInterpComp;
|
||||
|
||||
void NetInterpComp_SetLocation(NetInterpComp* interp, LocationUpdate* update, bool interpolate);
|
||||
void NetInterpComp_AdvanceState(NetInterpComp* interp);
|
||||
Entity* Entities_List[ENTITIES_MAX_COUNT];
|
||||
void Entities_Tick(ScheduledTask* task);
|
||||
void Entities_RenderModels(Real64 delta, Real32 t);
|
||||
void Entities_RenderNames(Real64 delta);
|
||||
void Entities_RenderHoveredNames(Real64 delta);
|
||||
void Entities_Init(void);
|
||||
void Entities_Free(void);
|
||||
void Entities_Remove(EntityID id);
|
||||
EntityID Entities_GetCloset(Entity* src);
|
||||
void Entities_DrawShadows(void);
|
||||
#endif
|
438
src/Client/EntityComponents.c
Normal file
438
src/Client/EntityComponents.c
Normal file
@ -0,0 +1,438 @@
|
||||
#include "EntityComponents.h"
|
||||
#include "ExtMath.h"
|
||||
#include "World.h"
|
||||
#include "Block.h"
|
||||
#include "Event.h"
|
||||
#include "Game.h"
|
||||
#include "Player.h"
|
||||
#include "Platform.h"
|
||||
#include "Camera.h"
|
||||
#include "Funcs.h"
|
||||
|
||||
#define ANIM_MAX_ANGLE (110 * MATH_DEG2RAD)
|
||||
#define ANIM_ARM_MAX (60.0f * MATH_DEG2RAD)
|
||||
#define ANIM_LEG_MAX (80.0f * MATH_DEG2RAD)
|
||||
#define ANIM_IDLE_MAX (3.0f * MATH_DEG2RAD)
|
||||
#define ANIM_IDLE_XPERIOD (2.0f * MATH_PI / 5.0f)
|
||||
#define ANIM_IDLE_ZPERIOD (2.0f * MATH_PI / 3.5f)
|
||||
|
||||
void AnimatedComp_DoTilt(Real32* tilt, bool reduce) {
|
||||
if (reduce) {
|
||||
(*tilt) *= 0.84f;
|
||||
} else {
|
||||
(*tilt) += 0.1f;
|
||||
}
|
||||
Math_Clamp(*tilt, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
void AnimatedComp_PerpendicularAnim(AnimatedComp* anim, Real32 flapSpeed, Real32 idleXRot, Real32 idleZRot, bool left) {
|
||||
Real32 verAngle = 0.5f + 0.5f * Math_Sin(anim->WalkTime * flapSpeed);
|
||||
Real32 zRot = -idleZRot - verAngle * anim->Swing * ANIM_MAX_ANGLE;
|
||||
Real32 horAngle = Math_Cos(anim->WalkTime) * anim->Swing * ANIM_ARM_MAX * 1.5f;
|
||||
Real32 xRot = idleXRot + horAngle;
|
||||
|
||||
if (left) {
|
||||
anim->LeftArmX = xRot; anim->LeftArmZ = zRot;
|
||||
} else {
|
||||
anim->RightArmX = xRot; anim->RightArmZ = zRot;
|
||||
}
|
||||
}
|
||||
|
||||
void AnimatedComp_CalcHumanAnim(AnimatedComp* anim, Real32 idleXRot, Real32 idleZRot) {
|
||||
AnimatedComp_PerpendicularAnim(anim, 0.23f, idleXRot, idleZRot, true);
|
||||
AnimatedComp_PerpendicularAnim(anim, 0.28f, idleXRot, idleZRot, false);
|
||||
anim->RightArmX = -anim->RightArmX; anim->RightArmZ = -anim->RightArmZ;
|
||||
}
|
||||
|
||||
void AnimatedComp_Init(AnimatedComp* anim) {
|
||||
anim->BobbingHor = 0.0f; anim->BobbingVer = 0.0f; anim->BobbingModel = 0.0f;
|
||||
anim->WalkTime = 0.0f; anim->Swing = 0.0f; anim->BobStrength = 1.0f;
|
||||
anim->WalkTimeO = 0.0f; anim->SwingO = 0.0f; anim->BobStrengthO = 1.0f;
|
||||
anim->WalkTimeN = 0.0f; anim->SwingN = 0.0f; anim->BobStrengthN = 1.0f;
|
||||
|
||||
anim->LeftLegX = 0.0f; anim->LeftLegZ = 0.0f; anim->RightLegX = 0.0f; anim->RightLegZ = 0.0f;
|
||||
anim->LeftArmX = 0.0f; anim->LeftArmZ = 0.0f; anim->RightArmX = 0.0f; anim->RightArmZ = 0.0f;
|
||||
}
|
||||
|
||||
void AnimatedComp_Update(AnimatedComp* anim, Vector3 oldPos, Vector3 newPos, Real64 delta, bool onGround) {
|
||||
anim->WalkTimeO = anim->WalkTimeN;
|
||||
anim->SwingO = anim->SwingN;
|
||||
Real32 dx = newPos.X - oldPos.X;
|
||||
Real32 dz = newPos.Z - oldPos.Z;
|
||||
Real32 distance = Math_Sqrt(dx * dx + dz * dz);
|
||||
|
||||
if (distance > 0.05f) {
|
||||
Real32 walkDelta = distance * 2 * (Real32)(20 * delta);
|
||||
anim->WalkTimeN += walkDelta;
|
||||
anim->SwingN += (Real32)delta * 3;
|
||||
} else {
|
||||
anim->SwingN -= (Real32)delta * 3;
|
||||
}
|
||||
Math_Clamp(anim->SwingN, 0.0f, 1.0f);
|
||||
|
||||
/* TODO: the Tilt code was designed for 60 ticks/second, fix it up for 20 ticks/second */
|
||||
anim->BobStrengthO = anim->BobStrengthN;
|
||||
Int32 i;
|
||||
for (i = 0; i < 3; i++) {
|
||||
AnimatedComp_DoTilt(&anim->BobStrengthN, !Game_ViewBobbing || !onGround);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void AnimatedComp_GetCurrent(AnimatedComp* anim, Real32 t, bool calcHumanAnims) {
|
||||
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);
|
||||
|
||||
Real32 idleTime = (Real32)Game_Accumulator;
|
||||
Real32 idleXRot = Math_Sin(idleTime * ANIM_IDLE_XPERIOD) * ANIM_IDLE_MAX;
|
||||
Real32 idleZRot = ANIM_IDLE_MAX + Math_Cos(idleTime * ANIM_IDLE_ZPERIOD) * ANIM_IDLE_MAX;
|
||||
|
||||
anim->LeftArmX = (Math_Cos(anim->WalkTime) * anim->Swing * ANIM_ARM_MAX) - idleXRot;
|
||||
anim->LeftArmZ = -idleZRot;
|
||||
anim->LeftLegX = -(Math_Cos(anim->WalkTime) * anim->Swing * ANIM_LEG_MAX);
|
||||
anim->LeftLegZ = 0;
|
||||
|
||||
anim->RightLegX = -anim->LeftLegX; anim->RightLegZ = -anim->LeftLegZ;
|
||||
anim->RightArmX = -anim->LeftArmX; anim->RightArmZ = -anim->LeftArmZ;
|
||||
|
||||
anim->BobbingHor = Math_Cos(anim->WalkTime) * anim->Swing * (2.5f / 16.0f);
|
||||
anim->BobbingVer = Math_AbsF(Math_Sin(anim->WalkTime)) * anim->Swing * (2.5f / 16.0f);
|
||||
anim->BobbingModel = Math_AbsF(Math_Cos(anim->WalkTime)) * anim->Swing * (4.0f / 16.0f);
|
||||
|
||||
if (calcHumanAnims && !Game_SimpleArmsAnim) {
|
||||
AnimatedComp_CalcHumanAnim(anim, idleXRot, idleZRot);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void TiltComp_Init(TiltComp* anim) {
|
||||
anim->TiltX = 0.0f; anim->TiltY = 0.0f; anim->VelTiltStrength = 1.0f;
|
||||
anim->VelTiltStrengthO = 1.0f; anim->VelTiltStrengthN = 1.0f;
|
||||
}
|
||||
|
||||
void TiltComp_Update(TiltComp* anim, Real64 delta) {
|
||||
anim->VelTiltStrengthO = anim->VelTiltStrengthN;
|
||||
LocalPlayer* p = &LocalPlayer_Instance;
|
||||
|
||||
/* TODO: the Tilt code was designed for 60 ticks/second, fix it up for 20 ticks/second */
|
||||
Int32 i;
|
||||
for (i = 0; i < 3; i++) {
|
||||
AnimatedComp_DoTilt(&anim->VelTiltStrengthN, p->Hacks.Noclip || p->Hacks.Flying);
|
||||
}
|
||||
}
|
||||
|
||||
void TiltComp_GetCurrent(TiltComp* anim, Real32 t) {
|
||||
LocalPlayer* p = &LocalPlayer_Instance;
|
||||
anim->VelTiltStrength = Math_Lerp(anim->VelTiltStrengthO, anim->VelTiltStrengthN, t);
|
||||
|
||||
AnimatedComp* pAnim = &p->Base.Base.Anim;
|
||||
anim->TiltX = Math_Cos(pAnim->WalkTime) * pAnim->Swing * (0.15f * MATH_DEG2RAD);
|
||||
anim->TiltY = Math_Sin(pAnim->WalkTime) * pAnim->Swing * (0.15f * MATH_DEG2RAD);
|
||||
}
|
||||
|
||||
|
||||
void HacksComp_SetAll(HacksComp* hacks, bool allowed) {
|
||||
hacks->CanAnyHacks = allowed; hacks->CanFly = allowed;
|
||||
hacks->CanNoclip = allowed; hacks->CanRespawn = allowed;
|
||||
hacks->CanSpeed = allowed; hacks->CanPushbackBlocks = allowed;
|
||||
hacks->CanUseThirdPersonCamera = allowed;
|
||||
}
|
||||
|
||||
void HacksComp_Init(HacksComp* hacks) {
|
||||
Platform_MemSet(hacks, 0, sizeof(HacksComp));
|
||||
HacksComp_SetAll(hacks, true);
|
||||
hacks->SpeedMultiplier = 10.0f;
|
||||
hacks->Enabled = true;
|
||||
hacks->CanSeeAllNames = true;
|
||||
hacks->CanDoubleJump = true;
|
||||
hacks->BaseHorSpeed = 1.0f;
|
||||
hacks->MaxJumps = 1;
|
||||
hacks->NoclipSlide = true;
|
||||
hacks->CanBePushed = true;
|
||||
hacks->HacksFlags = String_InitAndClear(&hacks->HacksFlagsBuffer[0], 128);
|
||||
}
|
||||
|
||||
bool HacksComp_CanJumpHigher(HacksComp* hacks) {
|
||||
return hacks->Enabled && hacks->CanAnyHacks && hacks->CanSpeed;
|
||||
}
|
||||
|
||||
bool HacksComp_Floating(HacksComp* hacks) {
|
||||
return hacks->Noclip || hacks->Flying;
|
||||
}
|
||||
|
||||
String HacksComp_GetFlagValue(String* flag, HacksComp* hacks) {
|
||||
String* joined = &hacks->HacksFlags;
|
||||
Int32 start = String_IndexOfString(joined, flag);
|
||||
if (start < 0) return String_MakeNull();
|
||||
start += flag->length;
|
||||
|
||||
Int32 end = String_IndexOf(joined, ' ', start);
|
||||
if (end < 0) end = joined->length;
|
||||
|
||||
return String_UNSAFE_Substring(joined, start, end - start);
|
||||
}
|
||||
|
||||
void HacksComp_ParseHorizontalSpeed(HacksComp* hacks) {
|
||||
String horSpeedFlag = String_FromConst("horspeed=");
|
||||
String speedStr = HacksComp_GetFlagValue(&horSpeedFlag, hacks);
|
||||
if (speedStr.length == 0) return;
|
||||
|
||||
Real32 speed = 0.0f;
|
||||
if (!Convert_TryParseReal32(&speedStr, &speed) || speed <= 0.0f) return;
|
||||
hacks->BaseHorSpeed = speed;
|
||||
}
|
||||
|
||||
void HacksComp_ParseMultiSpeed(HacksComp* hacks) {
|
||||
String jumpsFlag = String_FromConst("jumps=");
|
||||
String jumpsStr = HacksComp_GetFlagValue(&jumpsFlag, hacks);
|
||||
if (jumpsStr.length == 0) return;
|
||||
|
||||
Int32 jumps = 0;
|
||||
if (!Convert_TryParseInt32(&jumpsStr, &jumps) || jumps < 0) return;
|
||||
hacks->MaxJumps = jumps;
|
||||
}
|
||||
|
||||
void HacksComp_ParseFlag(HacksComp* hacks, const UInt8* incFlag, const UInt8* excFlag, bool* target) {
|
||||
String include = String_FromReadonly(incFlag);
|
||||
String exclude = String_FromReadonly(excFlag);
|
||||
String* joined = &hacks->HacksFlags;
|
||||
|
||||
if (String_ContainsString(joined, &include)) {
|
||||
*target = true;
|
||||
} else if (String_ContainsString(joined, &exclude)) {
|
||||
*target = false;
|
||||
}
|
||||
}
|
||||
|
||||
void HacksComp_ParseAllFlag(HacksComp* hacks, const UInt8* incFlag, const UInt8* excFlag) {
|
||||
String include = String_FromReadonly(incFlag);
|
||||
String exclude = String_FromReadonly(excFlag);
|
||||
String* joined = &hacks->HacksFlags;
|
||||
|
||||
if (String_ContainsString(joined, &include)) {
|
||||
HacksComp_SetAll(hacks, true);
|
||||
} else if (String_ContainsString(joined, &exclude)) {
|
||||
HacksComp_SetAll(hacks, false);
|
||||
}
|
||||
}
|
||||
|
||||
void HacksComp_SetUserType(HacksComp* hacks, UInt8 value) {
|
||||
bool isOp = value >= 100 && value <= 127;
|
||||
hacks->UserType = value;
|
||||
hacks->CanSeeAllNames = isOp;
|
||||
|
||||
Block_CanPlace[BLOCK_BEDROCK] = isOp;
|
||||
Block_CanDelete[BLOCK_BEDROCK] = isOp;
|
||||
Block_CanPlace[BLOCK_WATER] = isOp;
|
||||
Block_CanPlace[BLOCK_STILL_WATER] = isOp;
|
||||
Block_CanPlace[BLOCK_LAVA] = isOp;
|
||||
Block_CanPlace[BLOCK_STILL_LAVA] = isOp;
|
||||
}
|
||||
|
||||
void HacksComp_CheckConsistency(HacksComp* hacks) {
|
||||
if (!hacks->CanFly || !hacks->Enabled) {
|
||||
hacks->Flying = false; hacks->FlyingDown = false; hacks->FlyingUp = false;
|
||||
}
|
||||
if (!hacks->CanNoclip || !hacks->Enabled) {
|
||||
hacks->Noclip = false;
|
||||
}
|
||||
if (!hacks->CanSpeed || !hacks->Enabled) {
|
||||
hacks->Speeding = false; hacks->HalfSpeeding = false;
|
||||
}
|
||||
|
||||
hacks->CanDoubleJump = hacks->CanAnyHacks && hacks->Enabled && hacks->CanSpeed;
|
||||
hacks->CanSeeAllNames = hacks->CanAnyHacks && hacks->CanSeeAllNames;
|
||||
|
||||
if (!hacks->CanUseThirdPersonCamera || !hacks->Enabled) {
|
||||
Camera_CycleActive();
|
||||
}
|
||||
}
|
||||
|
||||
void HacksComp_UpdateState(HacksComp* hacks) {
|
||||
HacksComp_SetAll(hacks, true);
|
||||
if (hacks->HacksFlags.length == 0) return;
|
||||
|
||||
hacks->BaseHorSpeed = 1;
|
||||
hacks->MaxJumps = 1;
|
||||
hacks->CanBePushed = true;
|
||||
|
||||
/* By default (this is also the case with WoM), we can use hacks. */
|
||||
String excHacks = String_FromConst("-hax");
|
||||
if (String_ContainsString(&hacks->HacksFlags, &excHacks)) {
|
||||
HacksComp_SetAll(hacks, false);
|
||||
}
|
||||
|
||||
HacksComp_ParseFlag(hacks, "+fly", "-fly", &hacks->CanFly);
|
||||
HacksComp_ParseFlag(hacks, "+noclip", "-noclip", &hacks->CanNoclip);
|
||||
HacksComp_ParseFlag(hacks, "+speed", "-speed", &hacks->CanSpeed);
|
||||
HacksComp_ParseFlag(hacks, "+respawn", "-respawn", &hacks->CanRespawn);
|
||||
HacksComp_ParseFlag(hacks, "+push", "-push", &hacks->CanBePushed);
|
||||
|
||||
if (hacks->UserType == 0x64) {
|
||||
HacksComp_ParseAllFlag(hacks, "+ophax", "-ophax");
|
||||
}
|
||||
HacksComp_ParseHorizontalSpeed(hacks);
|
||||
HacksComp_ParseMultiSpeed(hacks);
|
||||
|
||||
HacksComp_CheckConsistency(hacks);
|
||||
Event_RaiseVoid(&UserEvents_HackPermissionsChanged);
|
||||
}
|
||||
|
||||
|
||||
void InterpComp_RemoveOldestRotY(InterpComp* interp) {
|
||||
Int32 i;
|
||||
for (i = 0; i < Array_NumElements(interp->RotYStates); i++) {
|
||||
interp->RotYStates[i] = interp->RotYStates[i + 1];
|
||||
}
|
||||
interp->RotYCount--;
|
||||
}
|
||||
|
||||
void InterpComp_AddRotY(InterpComp* interp, Real32 state) {
|
||||
if (interp->RotYCount == Array_NumElements(interp->RotYStates)) {
|
||||
InterpComp_RemoveOldestRotY(interp);
|
||||
}
|
||||
interp->RotYStates[interp->RotYCount] = state; interp->RotYCount++;
|
||||
}
|
||||
|
||||
void InterpComp_AdvanceRotY(InterpComp* interp) {
|
||||
interp->PrevRotY = interp->NextRotY;
|
||||
if (interp->RotYCount == 0) return;
|
||||
|
||||
interp->NextRotY = interp->RotYStates[0];
|
||||
InterpComp_RemoveOldestRotY(interp);
|
||||
}
|
||||
|
||||
void InterpComp_LerpAngles(InterpComp* interp, Entity* entity, Real32 t) {
|
||||
InterpState* prev = &interp->Prev;
|
||||
InterpState* next = &interp->Next;
|
||||
entity->HeadX = Math_LerpAngle(prev->HeadX, next->HeadX, t);
|
||||
entity->HeadY = Math_LerpAngle(prev->HeadY, next->HeadY, t);
|
||||
entity->RotX = Math_LerpAngle(prev->RotX, next->RotX, t);
|
||||
entity->RotY = Math_LerpAngle(interp->PrevRotY, interp->NextRotY, t);
|
||||
entity->RotZ = Math_LerpAngle(prev->RotZ, next->RotZ, t);
|
||||
}
|
||||
|
||||
void InterpComp_SetPos(InterpState* state, LocationUpdate* update) {
|
||||
if (update->RelativePosition) {
|
||||
Vector3_Add(&state->Pos, &state->Pos, &update->Pos);
|
||||
} else {
|
||||
state->Pos = update->Pos;
|
||||
}
|
||||
}
|
||||
|
||||
Real32 NetInterpComp_Next(Real32 next, Real32 cur) {
|
||||
if (next == LOCATIONUPDATE_EXCLUDED) return cur;
|
||||
return next;
|
||||
}
|
||||
|
||||
void NetInterpComp_RemoveOldestState(NetInterpComp* interp) {
|
||||
Int32 i;
|
||||
for (i = 0; i < Array_NumElements(interp->States); i++) {
|
||||
interp->States[i] = interp->States[i + 1];
|
||||
}
|
||||
interp->StatesCount--;
|
||||
}
|
||||
|
||||
void NetInterpComp_AddState(NetInterpComp* interp, InterpState state) {
|
||||
if (interp->StatesCount == Array_NumElements(interp->States)) {
|
||||
NetInterpComp_RemoveOldestState(interp);
|
||||
}
|
||||
interp->States[interp->StatesCount] = state; interp->StatesCount++;
|
||||
}
|
||||
|
||||
void NetInterpComp_SetLocation(NetInterpComp* interp, LocationUpdate* update, bool interpolate) {
|
||||
InterpState last = interp->Cur;
|
||||
InterpState* cur = &interp->Cur;
|
||||
if (update->IncludesPosition) {
|
||||
InterpComp_SetPos(cur, update);
|
||||
}
|
||||
|
||||
cur->RotX = NetInterpComp_Next(update->RotX, cur->RotX);
|
||||
cur->RotZ = NetInterpComp_Next(update->RotZ, cur->RotZ);
|
||||
cur->HeadX = NetInterpComp_Next(update->HeadX, cur->HeadX);
|
||||
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;
|
||||
} else {
|
||||
/* Smoother interpolation by also adding midpoint. */
|
||||
InterpState mid;
|
||||
Vector3_Lerp(&mid.Pos, &last.Pos, &cur->Pos, 0.5f);
|
||||
mid.RotX = Math_LerpAngle(last.RotX, cur->RotX, 0.5f);
|
||||
mid.RotZ = Math_LerpAngle(last.RotZ, cur->RotZ, 0.5f);
|
||||
mid.HeadX = Math_LerpAngle(last.HeadX, cur->HeadX, 0.5f);
|
||||
mid.HeadY = Math_LerpAngle(last.HeadY, cur->HeadY, 0.5f);
|
||||
NetInterpComp_AddState(interp, mid);
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
void NetInterpComp_AdvanceState(NetInterpComp* interp) {
|
||||
interp->Base.Prev = interp->Base.Next;
|
||||
if (interp->StatesCount > 0) {
|
||||
interp->Base.Next = interp->States[0];
|
||||
NetInterpComp_RemoveOldestState(interp);
|
||||
}
|
||||
InterpComp_AdvanceRotY(&interp->Base);
|
||||
}
|
||||
|
||||
Real32 LocalInterpComp_Next(Real32 next, Real32 cur, Real32* last, bool interpolate) {
|
||||
if (next == LOCATIONUPDATE_EXCLUDED) return cur;
|
||||
if (!interpolate) *last = next;
|
||||
return next;
|
||||
}
|
||||
|
||||
void LocalInterpComp_SetLocation(InterpComp* interp, LocationUpdate* update, bool interpolate) {
|
||||
Entity* entity = &LocalPlayer_Instance.Base.Base;
|
||||
InterpState* prev = &interp->Prev;
|
||||
InterpState* next = &interp->Next;
|
||||
|
||||
if (update->IncludesPosition) {
|
||||
InterpComp_SetPos(next, update);
|
||||
Real32 blockOffset = next->Pos.Y - Math_Floor(next->Pos.Y);
|
||||
if (blockOffset < ENTITY_ADJUSTMENT) {
|
||||
next->Pos.Y += ENTITY_ADJUSTMENT;
|
||||
}
|
||||
if (!interpolate) {
|
||||
prev->Pos = next->Pos;
|
||||
entity->Position = next->Pos;
|
||||
}
|
||||
}
|
||||
|
||||
next->RotX = LocalInterpComp_Next(update->RotX, next->RotX, &prev->RotX, interpolate);
|
||||
next->RotZ = LocalInterpComp_Next(update->RotZ, next->RotZ, &prev->RotZ, interpolate);
|
||||
next->HeadX = LocalInterpComp_Next(update->HeadX, next->HeadX, &prev->HeadX, interpolate);
|
||||
next->HeadY = LocalInterpComp_Next(update->RotY, next->HeadY, &prev->HeadY, interpolate);
|
||||
|
||||
if (update->RotY != LOCATIONUPDATE_EXCLUDED) {
|
||||
if (!interpolate) {
|
||||
interp->NextRotY = update->RotY;
|
||||
entity->RotY = update->RotY;
|
||||
interp->RotYCount = 0;
|
||||
} else {
|
||||
/* Body Y rotation lags slightly behind */
|
||||
InterpComp_AddRotY(interp, Math_LerpAngle(prev->HeadY, next->HeadY, 0.33333333f));
|
||||
InterpComp_AddRotY(interp, Math_LerpAngle(prev->HeadY, next->HeadY, 0.66666667f));
|
||||
InterpComp_AddRotY(interp, Math_LerpAngle(prev->HeadY, next->HeadY, 1.00000000f));
|
||||
|
||||
interp->NextRotY = interp->RotYStates[0];
|
||||
}
|
||||
}
|
||||
|
||||
InterpComp_LerpAngles(interp, entity, 0.0f);
|
||||
}
|
||||
|
||||
void LocalInterpComp_AdvanceState(InterpComp* interp) {
|
||||
Entity* entity = &LocalPlayer_Instance.Base.Base;
|
||||
interp->Prev = interp->Next;
|
||||
entity->Position = interp->Next.Pos;
|
||||
InterpComp_AdvanceRotY(interp);
|
||||
}
|
107
src/Client/EntityComponents.h
Normal file
107
src/Client/EntityComponents.h
Normal file
@ -0,0 +1,107 @@
|
||||
#ifndef CC_ENTITY_COMPONENTS_H
|
||||
#define CC_ENTITY_COMPONENTS_H
|
||||
#include "Typedefs.h"
|
||||
#include "Vectors.h"
|
||||
#include "String.h"
|
||||
/* Various components for entities.
|
||||
Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
|
||||
*/
|
||||
|
||||
typedef struct Entity_ Entity;
|
||||
typedef struct LocationUpdate_ LocationUpdate;
|
||||
|
||||
/* Entity component that performs model animation depending on movement speed and time. */
|
||||
typedef struct AnimatedComp_ {
|
||||
Real32 BobbingHor, BobbingVer, BobbingModel;
|
||||
Real32 WalkTime, Swing, BobStrength;
|
||||
Real32 WalkTimeO, WalkTimeN, SwingO, SwingN, BobStrengthO, BobStrengthN;
|
||||
|
||||
Real32 LeftLegX, LeftLegZ, RightLegX, RightLegZ;
|
||||
Real32 LeftArmX, LeftArmZ, RightArmX, RightArmZ;
|
||||
} 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);
|
||||
|
||||
/* Entity component that performs tilt animation depending on movement speed and time. */
|
||||
typedef struct TiltComp_ {
|
||||
Real32 TiltX, TiltY, VelTiltStrength;
|
||||
Real32 VelTiltStrengthO, VelTiltStrengthN;
|
||||
} TiltComp;
|
||||
|
||||
void TiltComp_Init(TiltComp* anim);
|
||||
void TiltComp_Update(TiltComp* anim, Real64 delta);
|
||||
void TiltComp_GetCurrent(TiltComp* anim, Real32 t);
|
||||
|
||||
/* Entity component that performs management of hack states. */
|
||||
typedef struct HacksComponent_ {
|
||||
UInt8 UserType;
|
||||
/* Speed player move at, relative to normal speed, when the 'speeding' key binding is held down. */
|
||||
Real32 SpeedMultiplier;
|
||||
/* Whether blocks that the player places that intersect themselves, should cause the player to
|
||||
be pushed back in the opposite direction of the placed block. */
|
||||
bool PushbackPlacing;
|
||||
/* Whether the player should be able to step up whole blocks, instead of just slabs. */
|
||||
bool FullBlockStep;
|
||||
/* Whether the player has allowed hacks usage as an option. Note 'can use X' set by the server override this. */
|
||||
bool Enabled;
|
||||
|
||||
bool CanAnyHacks, CanUseThirdPersonCamera, CanSpeed, CanFly;
|
||||
bool CanRespawn, CanNoclip, CanPushbackBlocks,CanSeeAllNames;
|
||||
bool CanDoubleJump, CanBePushed;
|
||||
/* Maximum speed the entity can move at horizontally when CanSpeed is false. */
|
||||
Real32 BaseHorSpeed;
|
||||
/* Max amount of jumps the player can perform. */
|
||||
Int32 MaxJumps;
|
||||
|
||||
/* Whether the player should slide after letting go of movement buttons in noclip. */
|
||||
bool NoclipSlide;
|
||||
/* Whether the player has allowed the usage of fast double jumping abilities. */
|
||||
bool WOMStyleHacks;
|
||||
|
||||
bool Noclip, Flying,FlyingUp, FlyingDown, Speeding, HalfSpeeding;
|
||||
UInt8 HacksFlagsBuffer[String_BufferSize(128)];
|
||||
String HacksFlags;
|
||||
} HacksComp;
|
||||
|
||||
void HacksComp_Init(HacksComp* hacks);
|
||||
bool HacksComp_CanJumpHigher(HacksComp* hacks);
|
||||
bool HacksComp_Floating(HacksComp* hacks);
|
||||
void HacksComp_SetUserType(HacksComp* hacks, UInt8 value);
|
||||
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;
|
||||
|
||||
/* 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;
|
||||
|
||||
void InterpComp_LerpAngles(InterpComp* interp, Entity* entity, Real32 t);
|
||||
|
||||
void LocalInterpComp_SetLocation(InterpComp* interp, LocationUpdate* update, bool interpolate);
|
||||
void LocalInterpComp_AdvanceState(InterpComp* interp);
|
||||
|
||||
/* Entity component that performs interpolation for network players. */
|
||||
typedef struct NetInterpComp_ {
|
||||
InterpComp Base;
|
||||
/* Last known position and orientation sent by the server. */
|
||||
InterpState Cur;
|
||||
Int32 StatesCount;
|
||||
InterpState States[10];
|
||||
} NetInterpComp;
|
||||
|
||||
void NetInterpComp_SetLocation(NetInterpComp* interp, LocationUpdate* update, bool interpolate);
|
||||
void NetInterpComp_AdvanceState(NetInterpComp* interp);
|
||||
#endif
|
@ -104,6 +104,8 @@ Event_Real32 WorldEvents_MapLoading; /* Portion of world is decompressed/gener
|
||||
Event_Void WorldEvents_MapLoaded; /* New world has finished loading, player can now interact with it. */
|
||||
Event_Int32 WorldEvents_EnvVarChanged; /* World environment variable changed by player/CPE/WoM config. */
|
||||
|
||||
Event_Void ChatEvents_FontChanged; /* User changes whether system chat font used, and when the bitmapped font texture changes. */
|
||||
|
||||
/* Environment variable identifiers*/
|
||||
typedef Int32 EnvVar;
|
||||
#define EnvVar_EdgeBlock 0
|
||||
|
@ -14,9 +14,7 @@
|
||||
*/
|
||||
#define ICOUNT(verticesCount) (((verticesCount) >> 2) * 6)
|
||||
|
||||
/* Initalises this graphics API. */
|
||||
void Gfx_Init(void);
|
||||
/* Frees memory allocated by this graphics API. */
|
||||
void Gfx_Free(void);
|
||||
|
||||
/* Maximum supported length of a dimension (width and height) of a 2D texture. */
|
||||
@ -30,9 +28,7 @@ bool Gfx_Mipmaps;
|
||||
/* Whether the backend supports setting the number of custom mipmaps levels. */
|
||||
bool Gfx_CustomMipmapsLevels;
|
||||
|
||||
/* Maximum number of vertices that can be indexed. */
|
||||
#define GFX_MAX_INDICES (65536 / 4 * 6)
|
||||
/* Maximum number of vertices that can be indexed. */
|
||||
#define GFX_MAX_VERTICES 65536
|
||||
|
||||
/* Callback invoked when the current context is lost, and is repeatedly invoked until the context can be retrieved. */
|
||||
@ -44,78 +40,51 @@ GfxResourceID Gfx_CreateTexture(Bitmap* bmp, bool managedPool, bool mipmaps);
|
||||
/* Updates the sub-rectangle (x, y) -> (x + part.Width, y + part.Height)
|
||||
of the native texture associated with the given ID, with the pixels encapsulated in the 'part' instance. */
|
||||
void Gfx_UpdateTexturePart(GfxResourceID texId, Int32 x, Int32 y, Bitmap* part, bool mipmaps);
|
||||
/* Binds the given texture id so that it can be used for rasterization. */
|
||||
void Gfx_BindTexture(GfxResourceID texId);
|
||||
/* Frees all native resources held for the given texture id. */
|
||||
void Gfx_DeleteTexture(GfxResourceID* texId);
|
||||
/* Sets whether texturing is applied when rasterizing primitives. */
|
||||
void Gfx_SetTexturing(bool enabled);
|
||||
/* Enables mipmapping for subsequent texture drawing. */
|
||||
void Gfx_EnableMipmaps(void);
|
||||
/* Disbles mipmapping for subsequent texture drawing. */
|
||||
void Gfx_DisableMipmaps(void);
|
||||
|
||||
/* Gets whether fog is currently enabled. */
|
||||
bool Gfx_GetFog(void);
|
||||
/* Sets whether fog is currently enabled. */
|
||||
void Gfx_SetFog(bool enabled);
|
||||
/* Sets the fog colour that is blended with final primitive colours. */
|
||||
void Gfx_SetFogColour(PackedCol col);
|
||||
/* Sets the density of exp and exp^2 fog */
|
||||
void Gfx_SetFogDensity(Real32 value);
|
||||
/* Sets the start radius of fog for linear fog. */
|
||||
void Gfx_SetFogStart(Real32 value);
|
||||
/* Sets the end radius of fog for for linear fog. */
|
||||
void Gfx_SetFogEnd(Real32 value);
|
||||
/* Sets the current fog mode. (linear, exp, or exp^2) */
|
||||
void Gfx_SetFogMode(Fog fogMode);
|
||||
void Gfx_SetFogMode(Int32 fogMode);
|
||||
|
||||
/* Whether back facing primitives should be culled by the 3D graphics api. */
|
||||
void Gfx_SetFaceCulling(bool enabled);
|
||||
/* Sets hether alpha testing is currently enabled. */
|
||||
void Gfx_SetAlphaTest(bool enabled);
|
||||
/* Sets the alpha test compare function that is used when alpha testing is enabled. */
|
||||
void Gfx_SetAlphaTestFunc(CompareFunc compareFunc, Real32 refValue);
|
||||
/* Whether alpha blending is currently enabled. */
|
||||
void Gfx_SetAlphaTestFunc(Int32 compareFunc, Real32 refValue);
|
||||
void Gfx_SetAlphaBlending(bool enabled);
|
||||
/* Sets the alpha blend function that is used when alpha blending is enabled. */
|
||||
void Gfx_SetAlphaBlendFunc(BlendFunc srcBlendFunc, BlendFunc dstBlendFunc);
|
||||
void Gfx_SetAlphaBlendFunc(Int32 srcBlendFunc, Int32 dstBlendFunc);
|
||||
/* Whether blending between the alpha components of the texture and colour are performed. */
|
||||
void Gfx_SetAlphaArgBlend(bool enabled);
|
||||
|
||||
/* Clears the underlying back and/or front buffer. */
|
||||
void Gfx_Clear(void);
|
||||
/* Sets the colour the screen is cleared to when Clear() is called. */
|
||||
void Gfx_ClearColour(PackedCol col);
|
||||
/* Whether depth testing is currently enabled. */
|
||||
void Gfx_SetDepthTest(bool enabled);
|
||||
/* Sets the depth test compare function that is used when depth testing is enabled. */
|
||||
void Gfx_SetDepthTestFunc(CompareFunc compareFunc);
|
||||
/* Whether writing to the colour buffer is enabled. */
|
||||
void Gfx_SetDepthTestFunc(Int32 compareFunc);
|
||||
void Gfx_SetColourWrite(bool enabled);
|
||||
/* Whether writing to the depth buffer is enabled. */
|
||||
void Gfx_SetDepthWrite(bool enabled);
|
||||
|
||||
/* Creates a vertex buffer that can have its data dynamically updated. */
|
||||
GfxResourceID Gfx_CreateDynamicVb(VertexFormat vertexFormat, Int32 maxVertices);
|
||||
GfxResourceID Gfx_CreateDynamicVb(Int32 vertexFormat, Int32 maxVertices);
|
||||
/* Creates a static vertex buffer that has its data set at creation,
|
||||
but the vertex buffer's data cannot be updated after creation.*/
|
||||
GfxResourceID Gfx_CreateVb(void* vertices, VertexFormat vertexFormat, Int32 count);
|
||||
GfxResourceID Gfx_CreateVb(void* vertices, Int32 vertexFormat, Int32 count);
|
||||
/* Creates a static index buffer that has its data set at creation,
|
||||
but the index buffer's data cannot be updated after creation. */
|
||||
GfxResourceID Gfx_CreateIb(void* indices, Int32 indicesCount);
|
||||
/* Sets the currently active vertex buffer to the given id. */
|
||||
void Gfx_BindVb(GfxResourceID vb);
|
||||
/* Sets the currently active index buffer to the given id. */
|
||||
void Gfx_BindIb(GfxResourceID ib);
|
||||
/* Frees all native resources held for the vertex buffer associated with the given id. */
|
||||
void Gfx_DeleteVb(GfxResourceID* vb);
|
||||
/* Frees all native resources held for the index buffer associated with the given id. */
|
||||
void Gfx_DeleteIb(GfxResourceID* ib);
|
||||
|
||||
/* Informs the graphics API that the format of the vertex data used in subsequent
|
||||
draw calls will be in the given format. */
|
||||
void Gfx_SetBatchFormat(VertexFormat vertexFormat);
|
||||
void Gfx_SetBatchFormat(Int32 vertexFormat);
|
||||
/* Binds and updates the data of the current dynamic vertex buffer's data.
|
||||
This method also replaces the dynamic vertex buffer's data first with the given vertices before drawing. */
|
||||
void Gfx_SetDynamicVbData(GfxResourceID vb, void* vertices, Int32 vCount);
|
||||
@ -129,42 +98,25 @@ void Gfx_DrawVb_IndexedTris(Int32 verticesCount);
|
||||
void Gfx_DrawIndexedVb_TrisT2fC4b(Int32 verticesCount, Int32 startVertex);
|
||||
static Int32 Gfx_strideSizes[2] = { 16, 24 };
|
||||
|
||||
/* Sets the matrix type that load/push/pop operations should be applied to. */
|
||||
void Gfx_SetMatrixMode(MatrixType matrixType);
|
||||
/* Sets the current matrix to the given matrix.*/
|
||||
void Gfx_SetMatrixMode(Int32 matrixType);
|
||||
void Gfx_LoadMatrix(Matrix* matrix);
|
||||
/* Sets the current matrix to the identity matrix. */
|
||||
void Gfx_LoadIdentityMatrix(void);
|
||||
/* Multiplies the current matrix by the given matrix, then
|
||||
sets the current matrix to the result of the multiplication. */
|
||||
void Gfx_MultiplyMatrix(Matrix* matrix);
|
||||
/* Gets the top matrix the current matrix stack and pushes it to the stack. */
|
||||
void Gfx_PushMatrix(void);
|
||||
/* Removes the top matrix from the current matrix stack, then
|
||||
sets the current matrix to the new top matrix of the stack. */
|
||||
void Gfx_PopMatrix(void);
|
||||
/* Loads an orthographic projection matrix for the given height.*/
|
||||
void Gfx_LoadOrthoMatrix(Real32 width, Real32 height);
|
||||
|
||||
/*Outputs a .png screenshot of the backbuffer to the specified file. */
|
||||
/* Outputs a .png screenshot of the backbuffer to the specified file. */
|
||||
void Gfx_TakeScreenshot(STRING_PURE String* output, Int32 width, Int32 height);
|
||||
/* Adds a warning to game's chat if this graphics API has problems with the current user's GPU.
|
||||
Returns boolean of whether legacy rendering mode is needed. */
|
||||
bool Gfx_WarnIfNecessary(void);
|
||||
/* Informs the graphic api to update its state in preparation for a new frame. */
|
||||
void Gfx_BeginFrame(void);
|
||||
/* Informs the graphic api to update its state in preparation for the end of a frame,
|
||||
and to prepare that frame for display on the monitor. */
|
||||
void Gfx_EndFrame(void);
|
||||
/* Sets whether the graphics api should tie frame rendering to the refresh rate of the monitor. */
|
||||
void Gfx_SetVSync(bool value);
|
||||
/* Raised when the dimensions of the game's window have changed. */
|
||||
void Gfx_OnWindowResize(void);
|
||||
/* Makes an array of strings of information about the graphics API. */
|
||||
void Gfx_MakeApiInfo(void);
|
||||
|
||||
#define Gfx_ApiInfo_Count 32
|
||||
/* Array of strings for information about the graphics API.
|
||||
Max of Gfx_ApiInfo_Count strings, check if string is included by checking length > 0*/
|
||||
#define Gfx_ApiInfo_Count 8
|
||||
String Gfx_ApiInfo[Gfx_ApiInfo_Count];
|
||||
#endif
|
@ -2,12 +2,10 @@
|
||||
#define CC_GFXENUMS_H
|
||||
|
||||
/* Vertex data format types*/
|
||||
typedef Int32 VertexFormat;
|
||||
#define VERTEX_FORMAT_P3FC4B 0
|
||||
#define VERTEX_FORMAT_P3FT2FC4B 1
|
||||
|
||||
/* 3D graphics pixel comparison functions */
|
||||
typedef Int32 CompareFunc;
|
||||
#define COMPARE_FUNC_ALWAYS 0
|
||||
#define COMPARE_FUNC_NOTEQUAL 1
|
||||
#define COMPARE_FUNC_NEVER 2
|
||||
@ -18,7 +16,6 @@ typedef Int32 CompareFunc;
|
||||
#define COMPARE_FUNC_GREATER 7
|
||||
|
||||
/* 3D graphics pixel blending functions */
|
||||
typedef Int32 BlendFunc;
|
||||
#define BLEND_FUNC_ZERO 0
|
||||
#define BLEND_FUNC_ONE 1
|
||||
#define BLEND_FUNC_SRC_ALPHA 2
|
||||
@ -27,13 +24,11 @@ typedef Int32 BlendFunc;
|
||||
#define BLEND_FUNC_INV_DST_ALPHA 5
|
||||
|
||||
/* 3D graphics pixel fog blending functions */
|
||||
typedef Int32 Fog;
|
||||
#define FOG_LINEAR 0
|
||||
#define FOG_EXP 1
|
||||
#define FOG_EXP2 2
|
||||
|
||||
/* 3D graphics matrix types */
|
||||
typedef Int32 MatrixType;
|
||||
#define MATRIX_TYPE_PROJECTION 0
|
||||
#define MATRIX_TYPE_MODELVIEW 1
|
||||
#define MATRIX_TYPE_TEXTURE 2
|
||||
|
@ -58,8 +58,6 @@ typedef struct Screen_ {
|
||||
bool RenderHUDOver;
|
||||
/* Called when the game window is resized. */
|
||||
void (*OnResize)(struct Screen_* screen);
|
||||
void (*OnContextLost)(struct Screen_* screen);
|
||||
void (*OnContextRecreated)(struct Screen_* screen);
|
||||
} Screen;
|
||||
void Screen_Reset(Screen* screen);
|
||||
|
||||
|
@ -136,7 +136,7 @@ void Hotkeys_Init(void) {
|
||||
if (hotkey == Key_Unknown || strText.length == 0 || !Convert_TryParseUInt8(&strFlags, &flags)
|
||||
|| !Convert_TryParseBool(&strMoreInput, &moreInput)) { continue; }
|
||||
|
||||
Hotkeys_AddHotkey(hotkey, flags, &strText, moreInput);
|
||||
Hotkeys_Add(hotkey, flags, &strText, moreInput);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,6 @@
|
||||
|
||||
/* Calculates the intersection points of a ray and a rotated bounding box. */
|
||||
bool Intersection_RayIntersectsRotatedBox(Vector3 origin, Vector3 dir, Entity* target, Real32* tMin, Real32* tMax);
|
||||
|
||||
/* Calculates the intersection points of a ray and a bounding box.
|
||||
Source: http://www.cs.utah.edu/~awilliam/box/box.pdf */
|
||||
bool Intersection_RayIntersectsBox(Vector3 origin, Vector3 dir, Vector3 min, Vector3 max, Real32* t0, Real32* t1);
|
||||
|
@ -196,8 +196,8 @@ void Gfx_SetFogEnd(Real32 value) {
|
||||
gl_lastFogEnd = value;
|
||||
}
|
||||
|
||||
Fog gl_lastFogMode = -1;
|
||||
void Gfx_SetFogMode(Fog mode) {
|
||||
Int32 gl_lastFogMode = -1;
|
||||
void Gfx_SetFogMode(Int32 mode) {
|
||||
if (mode == gl_lastFogMode) return;
|
||||
glFogi(GL_FOG_MODE, gl_fogModes[mode]);
|
||||
gl_lastFogMode = mode;
|
||||
@ -206,12 +206,12 @@ void Gfx_SetFogMode(Fog mode) {
|
||||
|
||||
void Gfx_SetFaceCulling(bool enabled) { GL_TOGGLE(GL_CULL_FACE); }
|
||||
void Gfx_SetAlphaTest(bool enabled) { GL_TOGGLE(GL_ALPHA_TEST); }
|
||||
void Gfx_SetAlphaTestFunc(CompareFunc func, Real32 value) {
|
||||
void Gfx_SetAlphaTestFunc(Int32 func, Real32 value) {
|
||||
glAlphaFunc(gl_compare[func], value);
|
||||
}
|
||||
|
||||
void Gfx_SetAlphaBlending(bool enabled) { GL_TOGGLE(GL_BLEND); }
|
||||
void Gfx_SetAlphaBlendFunc(BlendFunc srcFunc, BlendFunc dstFunc) {
|
||||
void Gfx_SetAlphaBlendFunc(Int32 srcFunc, Int32 dstFunc) {
|
||||
glBlendFunc(gl_blend[srcFunc], gl_blend[dstFunc]);
|
||||
}
|
||||
void Gfx_SetAlphaArgBlend(bool enabled) { }
|
||||
@ -237,7 +237,7 @@ void Gfx_SetDepthWrite(bool enabled) {
|
||||
}
|
||||
|
||||
void Gfx_SetDepthTest(bool enabled) { GL_TOGGLE(GL_DEPTH_TEST); }
|
||||
void Gfx_SetDepthTestFunc(CompareFunc compareFunc) {
|
||||
void Gfx_SetDepthTestFunc(Int32 compareFunc) {
|
||||
glDepthFunc(gl_compare[compareFunc]);
|
||||
}
|
||||
|
||||
@ -249,7 +249,7 @@ GfxResourceID GL_GenAndBind(GLenum target) {
|
||||
return id;
|
||||
}
|
||||
|
||||
GfxResourceID Gfx_CreateDynamicVb(VertexFormat vertexFormat, Int32 maxVertices) {
|
||||
GfxResourceID Gfx_CreateDynamicVb(Int32 vertexFormat, Int32 maxVertices) {
|
||||
if (gl_lists) return gl_DYNAMICLISTID;
|
||||
Int32 id = GL_GenAndBind(GL_ARRAY_BUFFER);
|
||||
UInt32 sizeInBytes = maxVertices * Gfx_strideSizes[vertexFormat];
|
||||
@ -258,7 +258,7 @@ GfxResourceID Gfx_CreateDynamicVb(VertexFormat vertexFormat, Int32 maxVertices)
|
||||
}
|
||||
|
||||
#define gl_MAXINDICES ICOUNT(65536)
|
||||
GfxResourceID Gfx_CreateVb(void* vertices, VertexFormat vertexFormat, Int32 count) {
|
||||
GfxResourceID Gfx_CreateVb(void* vertices, Int32 vertexFormat, Int32 count) {
|
||||
if (gl_lists) {
|
||||
Int32 list = glGenLists(1);
|
||||
glNewList(list, GL_COMPILE);
|
||||
@ -328,7 +328,7 @@ typedef void (*GL_SetupVBRangeFunc)(Int32 startVertex);
|
||||
GL_SetupVBFunc gl_setupVBFunc;
|
||||
GL_SetupVBRangeFunc gl_setupVBRangeFunc;
|
||||
Int32 gl_batchStride;
|
||||
VertexFormat gl_batchFormat = -1;
|
||||
Int32 gl_batchFormat = -1;
|
||||
|
||||
void GL_SetupVbPos3fCol4b(void) {
|
||||
glVertexPointer(3, GL_FLOAT, VertexP3fC4b_Size, (void*)0);
|
||||
@ -354,7 +354,7 @@ void GL_SetupVbPos3fTex2fCol4b_Range(Int32 startVertex) {
|
||||
glTexCoordPointer(2, GL_FLOAT, VertexP3fT2fC4b_Size, (void*)(offset + 16));
|
||||
}
|
||||
|
||||
void Gfx_SetBatchFormat(VertexFormat vertexFormat) {
|
||||
void Gfx_SetBatchFormat(Int32 vertexFormat) {
|
||||
if (vertexFormat == gl_batchFormat) return;
|
||||
|
||||
if (gl_batchFormat == VERTEX_FORMAT_P3FT2FC4B) {
|
||||
@ -480,8 +480,8 @@ void Gfx_DrawIndexedVb_TrisT2fC4b(Int32 verticesCount, Int32 startVertex) {
|
||||
}
|
||||
|
||||
|
||||
MatrixType gl_lastMatrixType = 0;
|
||||
void Gfx_SetMatrixMode(MatrixType matrixType) {
|
||||
Int32 gl_lastMatrixType = 0;
|
||||
void Gfx_SetMatrixMode(Int32 matrixType) {
|
||||
if (matrixType == gl_lastMatrixType) return;
|
||||
glMatrixMode(gl_matrixModes[matrixType]);
|
||||
gl_lastMatrixType = matrixType;
|
||||
|
@ -102,8 +102,8 @@ Int32 Options_Insert(STRING_PURE String* key, STRING_PURE String* value) {
|
||||
}
|
||||
}
|
||||
|
||||
StringsBuffer_Add(&Options_Keys, &key);
|
||||
StringsBuffer_Add(&Options_Values, &value);
|
||||
StringsBuffer_Add(&Options_Keys, key);
|
||||
StringsBuffer_Add(&Options_Values, value);
|
||||
return Options_Keys.Count;
|
||||
}
|
||||
|
||||
|
@ -129,7 +129,7 @@ void InventoryScreen_Init(GuiElement* elem) {
|
||||
TableWidget_Create(&screen->Table);
|
||||
screen->Table.Font = screen->Font;
|
||||
screen->Table.ElementsPerRow = Game_PureClassic ? 9 : 10;
|
||||
elem->Init(&elem);
|
||||
elem->Init(elem);
|
||||
|
||||
Key_KeyRepeat = true;
|
||||
Event_RegisterVoid(&BlockEvents_PermissionsChanged, InventoryScreen_OnBlockChanged);
|
||||
@ -154,7 +154,7 @@ void InventoryScreen_Free(GuiElement* elem) {
|
||||
InventoryScreen* screen = (InventoryScreen*)elem;
|
||||
Platform_FreeFont(&screen->Font);
|
||||
elem = &screen->Table.Base.Base;
|
||||
elem->Free(&elem);
|
||||
elem->Free(elem);
|
||||
|
||||
Key_KeyRepeat = false;
|
||||
Event_UnregisterVoid(&BlockEvents_PermissionsChanged, InventoryScreen_OnBlockChanged);
|
||||
@ -166,9 +166,10 @@ void InventoryScreen_Free(GuiElement* elem) {
|
||||
bool InventoryScreen_HandlesKeyDown(GuiElement* elem, Key key) {
|
||||
InventoryScreen* screen = (InventoryScreen*)elem;
|
||||
TableWidget* table = &screen->Table;
|
||||
GuiElement* elem = &screen->Table.Base.Base;
|
||||
elem = &screen->Table.Base.Base;
|
||||
|
||||
if (key == KeyBind_Get(KeyBind_PauseOrExit)) {
|
||||
gGui_SetNewScreen(NULL);
|
||||
Gui_SetNewScreen(NULL);
|
||||
} else if (key == KeyBind_Get(KeyBind_Inventory) && screen->ReleasedInv) {
|
||||
Gui_SetNewScreen(NULL);
|
||||
} else if (key == Key_Enter && table->SelectedIndex != -1) {
|
||||
@ -192,7 +193,7 @@ bool InventoryScreen_HandlesKeyUp(GuiElement* elem, Key key) {
|
||||
bool InventoryScreen_HandlesMouseDown(GuiElement* elem, Int32 x, Int32 y, MouseButton btn) {
|
||||
InventoryScreen* screen = (InventoryScreen*)elem;
|
||||
TableWidget* table = &screen->Table;
|
||||
GuiElement* elem = &screen->Table.Base.Base;
|
||||
elem = &screen->Table.Base.Base;
|
||||
if (table->Scroll.DraggingMouse || game.Gui.hudScreen.hotbar.HandlesMouseDown(x, y, btn))
|
||||
return true;
|
||||
|
||||
@ -225,7 +226,7 @@ bool InventoryScreen_HandlesMouseScroll(GuiElement* elem, Real32 delta) {
|
||||
return elem->HandlesMouseScroll(elem, delta);
|
||||
}
|
||||
|
||||
Screen* InventoryScreen_GetInstance(void) {
|
||||
Screen* InventoryScreen_MakeInstance(void) {
|
||||
InventoryScreen* screen = &InventoryScreen_Instance;
|
||||
Platform_MemSet(&screen, 0, sizeof(InventoryScreen));
|
||||
Screen_Reset(&screen->Base);
|
||||
@ -237,13 +238,10 @@ Screen* InventoryScreen_GetInstance(void) {
|
||||
screen->Base.Base.HandlesMouseMove = InventoryScreen_HandlesMouseMove;
|
||||
screen->Base.Base.HandlesMouseScroll = InventoryScreen_HandlesMouseScroll;
|
||||
|
||||
screen->Base.OnContextLost = InventoryScreen_ContextLost;
|
||||
screen->Base.OnContextRecreated = InventoryScreen_ContextRecreated;
|
||||
screen->Base.OnResize = InventoryScreen_OnResize;
|
||||
screen->Base.Base.Init = InventoryScreen_Init;
|
||||
screen->Base.Base.Render = InventoryScreen_Render;
|
||||
screen->Base.Base.Free = InventoryScreen_Free;
|
||||
|
||||
return &screen->Base;
|
||||
}
|
||||
extern Screen* InventoryScreen_Unsafe_RawPointer = &InventoryScreen_Instance.Base;
|
||||
extern Screen* InventoryScreen_UNSAFE_RawPointer = &InventoryScreen_Instance.Base;
|
||||
|
@ -16,8 +16,8 @@ typedef struct ClickableScreen_ {
|
||||
} ClickableScreen;
|
||||
void ClickableScreen_Create(ClickableScreen* screen);
|
||||
|
||||
Screen* InventoryScreen_GetInstance(void);
|
||||
Screen* InventoryScreen_MakeInstance(void);
|
||||
|
||||
/* Raw pointer to inventory screen. DO NOT USE THIS. Use InventoryScreen_GetInstance() */
|
||||
extern Screen* InventoryScreen_Unsafe_RawPointer;
|
||||
/* Raw pointer to inventory screen. DO NOT USE THIS. Use InventoryScreen_MakeInstance() */
|
||||
extern Screen* InventoryScreen_UNSAFE_RawPointer;
|
||||
#endif
|
@ -440,7 +440,7 @@ bool HotbarWidget_HandlesMouseDown(GuiElement* elem, Int32 x, Int32 y, MouseButt
|
||||
Widget* w = (Widget*)elem;
|
||||
if (btn != MouseButton_Left || !Gui_Contains(w->X, w->Y, w->Width, w->Height, x, y)) return false;
|
||||
Screen* screen = Gui_GetActiveScreen();
|
||||
if (screen != InventoryScreen_Unsafe_RawPointer) return false;
|
||||
if (screen != InventoryScreen_UNSAFE_RawPointer) return false;
|
||||
|
||||
HotbarWidget* widget = (HotbarWidget*)elem;
|
||||
Int32 width = (Int32)(widget->ElemSize * widget->BorderSize);
|
||||
|
Loading…
x
Reference in New Issue
Block a user