mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-17 11:35:08 -04:00
Mostly port entity components to C.
This commit is contained in:
parent
468e958e36
commit
bfe4bc05e0
@ -82,7 +82,7 @@ namespace ClassicalSharp {
|
|||||||
public int ToArgb() { return A << 24 | R << 16 | G << 8 | B; }
|
public int ToArgb() { return A << 24 | R << 16 | G << 8 | B; }
|
||||||
|
|
||||||
public static FastColour Argb(int c) {
|
public static FastColour Argb(int c) {
|
||||||
FastColour col = default(FastColour);
|
FastColour col;
|
||||||
col.A = (byte)(c >> 24);
|
col.A = (byte)(c >> 24);
|
||||||
col.R = (byte)(c >> 16);
|
col.R = (byte)(c >> 16);
|
||||||
col.G = (byte)(c >> 8);
|
col.G = (byte)(c >> 8);
|
||||||
@ -102,7 +102,7 @@ namespace ClassicalSharp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static FastColour Unpack(int c) {
|
public static FastColour Unpack(int c) {
|
||||||
FastColour col = default(FastColour);
|
FastColour col;
|
||||||
col.A = (byte)(c >> 24);
|
col.A = (byte)(c >> 24);
|
||||||
col.G = (byte)(c >> 8);
|
col.G = (byte)(c >> 8);
|
||||||
#if USE_DX
|
#if USE_DX
|
||||||
|
@ -144,7 +144,6 @@
|
|||||||
<Compile Include="Entities\Mobs\AI.cs" />
|
<Compile Include="Entities\Mobs\AI.cs" />
|
||||||
<Compile Include="Entities\Components\AnimatedComponent.cs" />
|
<Compile Include="Entities\Components\AnimatedComponent.cs" />
|
||||||
<Compile Include="Entities\Components\HacksComponent.cs" />
|
<Compile Include="Entities\Components\HacksComponent.cs" />
|
||||||
<Compile Include="Entities\Components\InputComponent.cs" />
|
|
||||||
<Compile Include="Entities\Components\CollisionsComponent.cs" />
|
<Compile Include="Entities\Components\CollisionsComponent.cs" />
|
||||||
<Compile Include="Entities\Components\NewCollisionsComponent.cs" />
|
<Compile Include="Entities\Components\NewCollisionsComponent.cs" />
|
||||||
<Compile Include="Entities\Components\PhysicsComponent.cs" />
|
<Compile Include="Entities\Components\PhysicsComponent.cs" />
|
||||||
|
@ -117,7 +117,7 @@ namespace ClassicalSharp.Entities {
|
|||||||
|
|
||||||
// TODO: the Tilt code was designed for 60 ticks/second, fix it up for 20 ticks/second
|
// TODO: the Tilt code was designed for 60 ticks/second, fix it up for 20 ticks/second
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
AnimatedComponent.DoTilt(ref velTiltStrengthN, p.Hacks.Noclip || p.Hacks.Flying);
|
AnimatedComponent.DoTilt(ref velTiltStrengthN, p.Hacks.Floating);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,7 +111,7 @@ namespace ClassicalSharp.Entities {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ClipXMin(ref AABB blockBB, ref AABB entityBB, bool wasOn, ref AABB finalBB, ref AABB extentBB, ref Vector3 size) {
|
void ClipXMin(ref AABB blockBB, ref AABB entityBB, bool wasOn, ref AABB finalBB, ref AABB extentBB, ref Vector3 size) {
|
||||||
if (!wasOn || !DidSlide(blockBB, ref size, ref finalBB, ref entityBB, ref extentBB)) {
|
if (!wasOn || !DidSlide(ref blockBB, ref size, ref finalBB, ref entityBB, ref extentBB)) {
|
||||||
entity.Position.X = blockBB.Min.X - size.X / 2 - Adjustment;
|
entity.Position.X = blockBB.Min.X - size.X / 2 - Adjustment;
|
||||||
ClipX(ref size, ref entityBB, ref extentBB);
|
ClipX(ref size, ref entityBB, ref extentBB);
|
||||||
hitXMin = true;
|
hitXMin = true;
|
||||||
@ -119,7 +119,7 @@ namespace ClassicalSharp.Entities {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ClipXMax(ref AABB blockBB, ref AABB entityBB, bool wasOn, ref AABB finalBB, ref AABB extentBB, ref Vector3 size) {
|
void ClipXMax(ref AABB blockBB, ref AABB entityBB, bool wasOn, ref AABB finalBB, ref AABB extentBB, ref Vector3 size) {
|
||||||
if (!wasOn || !DidSlide(blockBB, ref size, ref finalBB, ref entityBB, ref extentBB)) {
|
if (!wasOn || !DidSlide(ref blockBB, ref size, ref finalBB, ref entityBB, ref extentBB)) {
|
||||||
entity.Position.X = blockBB.Max.X + size.X / 2 + Adjustment;
|
entity.Position.X = blockBB.Max.X + size.X / 2 + Adjustment;
|
||||||
ClipX(ref size, ref entityBB, ref extentBB);
|
ClipX(ref size, ref entityBB, ref extentBB);
|
||||||
hitXMax = true;
|
hitXMax = true;
|
||||||
@ -127,7 +127,7 @@ namespace ClassicalSharp.Entities {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ClipZMax(ref AABB blockBB, ref AABB entityBB, bool wasOn, ref AABB finalBB, ref AABB extentBB, ref Vector3 size) {
|
void ClipZMax(ref AABB blockBB, ref AABB entityBB, bool wasOn, ref AABB finalBB, ref AABB extentBB, ref Vector3 size) {
|
||||||
if (!wasOn || !DidSlide(blockBB, ref size, ref finalBB, ref entityBB, ref extentBB)) {
|
if (!wasOn || !DidSlide(ref blockBB, ref size, ref finalBB, ref entityBB, ref extentBB)) {
|
||||||
entity.Position.Z = blockBB.Max.Z + size.Z / 2 + Adjustment;
|
entity.Position.Z = blockBB.Max.Z + size.Z / 2 + Adjustment;
|
||||||
ClipZ(ref size, ref entityBB, ref extentBB);
|
ClipZ(ref size, ref entityBB, ref extentBB);
|
||||||
hitZMax = true;
|
hitZMax = true;
|
||||||
@ -135,7 +135,7 @@ namespace ClassicalSharp.Entities {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ClipZMin(ref AABB blockBB, ref AABB entityBB, bool wasOn, ref AABB finalBB, ref AABB extentBB, ref Vector3 size) {
|
void ClipZMin(ref AABB blockBB, ref AABB entityBB, bool wasOn, ref AABB finalBB, ref AABB extentBB, ref Vector3 size) {
|
||||||
if (!wasOn || !DidSlide(blockBB, ref size, ref finalBB, ref entityBB, ref extentBB)) {
|
if (!wasOn || !DidSlide(ref blockBB, ref size, ref finalBB, ref entityBB, ref extentBB)) {
|
||||||
entity.Position.Z = blockBB.Min.Z - size.Z / 2 - Adjustment;
|
entity.Position.Z = blockBB.Min.Z - size.Z / 2 - Adjustment;
|
||||||
ClipZ(ref size, ref entityBB, ref extentBB);
|
ClipZ(ref size, ref entityBB, ref extentBB);
|
||||||
hitZMin = true;
|
hitZMin = true;
|
||||||
@ -155,26 +155,24 @@ namespace ClassicalSharp.Entities {
|
|||||||
hitYMax = true;
|
hitYMax = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DidSlide(AABB blockBB, ref Vector3 size, ref AABB finalBB, ref AABB entityBB, ref AABB extentBB) {
|
bool DidSlide(ref AABB blockBB, ref Vector3 size, ref AABB finalBB, ref AABB entityBB, ref AABB extentBB) {
|
||||||
float yDist = blockBB.Max.Y - entityBB.Min.Y;
|
float yDist = blockBB.Max.Y - entityBB.Min.Y;
|
||||||
if (yDist > 0 && yDist <= entity.StepSize + 0.01f) {
|
if (yDist > 0 && yDist <= entity.StepSize + 0.01f) {
|
||||||
float blockXMin = blockBB.Min.X, blockZMin = blockBB.Min.Z;
|
float blockBB_MinX = Math.Max(blockBB.Min.X, blockBB.Max.X - size.X / 2);
|
||||||
blockBB.Min.X = Math.Max(blockBB.Min.X, blockBB.Max.X - size.X / 2);
|
float blockBB_MaxX = Math.Min(blockBB.Max.X, blockBB.Min.X + size.X / 2);
|
||||||
blockBB.Max.X = Math.Min(blockBB.Max.X, blockXMin + size.X / 2);
|
float blockBB_MinZ = Math.Max(blockBB.Min.Z, blockBB.Max.Z - size.Z / 2);
|
||||||
blockBB.Min.Z = Math.Max(blockBB.Min.Z, blockBB.Max.Z - size.Z / 2);
|
float blockBB_MaxZ = Math.Min(blockBB.Max.Z, blockBB.Min.Z + size.Z / 2);
|
||||||
blockBB.Max.Z = Math.Min(blockBB.Max.Z, blockZMin + size.Z / 2);
|
|
||||||
|
|
||||||
AABB adjBB;
|
AABB adjBB;
|
||||||
adjBB.Min.X = Math.Min(finalBB.Min.X, blockBB.Min.X + Adjustment);
|
adjBB.Min.X = Math.Min(finalBB.Min.X, blockBB_MinX + Adjustment);
|
||||||
adjBB.Max.X = Math.Max(finalBB.Max.X, blockBB.Max.X - Adjustment);
|
adjBB.Max.X = Math.Max(finalBB.Max.X, blockBB_MaxX - Adjustment);
|
||||||
adjBB.Min.Y = blockBB.Max.Y + Adjustment;
|
adjBB.Min.Y = blockBB.Max.Y + Adjustment;
|
||||||
adjBB.Max.Y = adjBB.Min.Y + size.Y;
|
adjBB.Max.Y = adjBB.Min.Y + size.Y;
|
||||||
adjBB.Min.Z = Math.Min(finalBB.Min.Z, blockBB.Min.Z + Adjustment);
|
adjBB.Min.Z = Math.Min(finalBB.Min.Z, blockBB_MinZ + Adjustment);
|
||||||
adjBB.Max.Z = Math.Max(finalBB.Max.Z, blockBB.Max.Z - Adjustment);
|
adjBB.Max.Z = Math.Max(finalBB.Max.Z, blockBB_MaxZ - Adjustment);
|
||||||
|
|
||||||
if (!CanSlideThrough(ref adjBB)) return false;
|
if (!CanSlideThrough(ref adjBB)) return false;
|
||||||
|
entity.Position.Y = adjBB.Min.Y;
|
||||||
entity.Position.Y = blockBB.Max.Y + Adjustment;
|
|
||||||
entity.onGround = true;
|
entity.onGround = true;
|
||||||
ClipY(ref size, ref entityBB, ref extentBB);
|
ClipY(ref size, ref entityBB, ref extentBB);
|
||||||
return true;
|
return true;
|
||||||
@ -187,13 +185,15 @@ namespace ClassicalSharp.Entities {
|
|||||||
Vector3I bbMax = Vector3I.Floor(adjFinalBB.Max);
|
Vector3I bbMax = Vector3I.Floor(adjFinalBB.Max);
|
||||||
AABB blockBB;
|
AABB blockBB;
|
||||||
|
|
||||||
|
Vector3 pos;
|
||||||
for (int y = bbMin.Y; y <= bbMax.Y; y++)
|
for (int y = bbMin.Y; y <= bbMax.Y; y++)
|
||||||
for (int z = bbMin.Z; z <= bbMax.Z; z++)
|
for (int z = bbMin.Z; z <= bbMax.Z; z++)
|
||||||
for (int x = bbMin.X; x <= bbMax.X; x++)
|
for (int x = bbMin.X; x <= bbMax.X; x++)
|
||||||
{
|
{
|
||||||
|
pos.X = x; pos.Y = y; pos.Z = z;
|
||||||
BlockID block = game.World.GetPhysicsBlock(x, y, z);
|
BlockID block = game.World.GetPhysicsBlock(x, y, z);
|
||||||
blockBB.Min = new Vector3(x, y, z) + BlockInfo.MinBB[block];
|
blockBB.Min = pos + BlockInfo.MinBB[block];
|
||||||
blockBB.Max = new Vector3(x, y, z) + BlockInfo.MaxBB[block];
|
blockBB.Max = pos + BlockInfo.MaxBB[block];
|
||||||
|
|
||||||
if (!blockBB.Intersects(adjFinalBB)) continue;
|
if (!blockBB.Intersects(adjFinalBB)) continue;
|
||||||
if (BlockInfo.Collide[block] == CollideType.Solid) return false;
|
if (BlockInfo.Collide[block] == CollideType.Solid) return false;
|
||||||
|
@ -51,7 +51,7 @@ namespace ClassicalSharp.Entities {
|
|||||||
public bool Noclip, Flying, FlyingUp, FlyingDown, Speeding, HalfSpeeding;
|
public bool Noclip, Flying, FlyingUp, FlyingDown, Speeding, HalfSpeeding;
|
||||||
|
|
||||||
public bool CanJumpHigher { get { return Enabled && CanAnyHacks && CanSpeed; } }
|
public bool CanJumpHigher { get { return Enabled && CanAnyHacks && CanSpeed; } }
|
||||||
public bool Floating { get { return Noclip || Flying; } }
|
public bool Floating; // true if Noclip or Flying
|
||||||
public string HacksFlags;
|
public string HacksFlags;
|
||||||
|
|
||||||
string GetFlagValue(string flag) {
|
string GetFlagValue(string flag) {
|
||||||
|
@ -1,93 +0,0 @@
|
|||||||
// Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
|
|
||||||
using System;
|
|
||||||
using ClassicalSharp.Physics;
|
|
||||||
using OpenTK;
|
|
||||||
using OpenTK.Input;
|
|
||||||
using BlockID = System.UInt16;
|
|
||||||
|
|
||||||
namespace ClassicalSharp.Entities {
|
|
||||||
|
|
||||||
/// <summary> Entity component that performs input handling. </summary>
|
|
||||||
public sealed class InputComponent {
|
|
||||||
|
|
||||||
Entity entity;
|
|
||||||
Game game;
|
|
||||||
public HacksComponent Hacks;
|
|
||||||
public PhysicsComponent physics;
|
|
||||||
|
|
||||||
public InputComponent(Game game, Entity entity) {
|
|
||||||
this.game = game;
|
|
||||||
this.entity = entity;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal bool Handles(Key key) {
|
|
||||||
LocalPlayer p = (LocalPlayer)entity;
|
|
||||||
KeyMap keys = game.Input.Keys;
|
|
||||||
|
|
||||||
if (key == keys[KeyBind.Respawn] && Hacks.CanRespawn) {
|
|
||||||
DoRespawn();
|
|
||||||
} else if (key == keys[KeyBind.SetSpawn] && Hacks.CanRespawn) {
|
|
||||||
p.Spawn = entity.Position;
|
|
||||||
p.Spawn.X = Utils.Floor(p.Spawn.X) + 0.5f;
|
|
||||||
p.Spawn.Z = Utils.Floor(p.Spawn.Z) + 0.5f;
|
|
||||||
p.SpawnRotY = entity.RotY;
|
|
||||||
p.SpawnHeadX = entity.HeadX;
|
|
||||||
DoRespawn();
|
|
||||||
} else if (key == keys[KeyBind.Fly] && Hacks.CanFly && Hacks.Enabled) {
|
|
||||||
Hacks.Flying = !Hacks.Flying;
|
|
||||||
} else if (key == keys[KeyBind.NoClip] && Hacks.CanNoclip && Hacks.Enabled && !Hacks.WOMStyleHacks) {
|
|
||||||
if (Hacks.Noclip) entity.Velocity.Y = 0;
|
|
||||||
Hacks.Noclip = !Hacks.Noclip;
|
|
||||||
} else if (key == keys[KeyBind.Jump] && !entity.onGround && !(Hacks.Flying || Hacks.Noclip)) {
|
|
||||||
int maxJumps = Hacks.CanDoubleJump && Hacks.WOMStyleHacks ? 2 : 0;
|
|
||||||
maxJumps = Math.Max(maxJumps, Hacks.MaxJumps - 1);
|
|
||||||
|
|
||||||
if (physics.multiJumps < maxJumps) {
|
|
||||||
physics.DoNormalJump();
|
|
||||||
physics.multiJumps++;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DoRespawn() {
|
|
||||||
if (!game.World.HasBlocks) return;
|
|
||||||
LocalPlayer p = (LocalPlayer)entity;
|
|
||||||
Vector3 spawn = p.Spawn;
|
|
||||||
if (game.World.IsValidPos(Vector3I.Floor(spawn)))
|
|
||||||
FindHighestFree(ref spawn);
|
|
||||||
|
|
||||||
spawn.Y += 2/16f;
|
|
||||||
LocationUpdate update = LocationUpdate.MakePosAndOri(spawn, p.SpawnRotY, p.SpawnHeadX, false);
|
|
||||||
entity.SetLocation(update, false);
|
|
||||||
entity.Velocity = Vector3.Zero;
|
|
||||||
|
|
||||||
// Update onGround, otherwise if 'respawn' then 'space' is pressed, you still jump into the air if onGround was true before
|
|
||||||
AABB bb = entity.Bounds;
|
|
||||||
bb.Min.Y -= 0.01f; bb.Max.Y = bb.Min.Y;
|
|
||||||
entity.onGround = entity.TouchesAny(bb, touchesAnySolid);
|
|
||||||
}
|
|
||||||
|
|
||||||
static Predicate<BlockID> touchesAnySolid = IsSolidCollide;
|
|
||||||
static bool IsSolidCollide(BlockID b) { return BlockInfo.Collide[b] == CollideType.Solid; }
|
|
||||||
|
|
||||||
void FindHighestFree(ref Vector3 spawn) {
|
|
||||||
AABB bb = AABB.Make(spawn, entity.Size);
|
|
||||||
|
|
||||||
Vector3I P = Vector3I.Floor(spawn);
|
|
||||||
// Spawn player at highest valid position.
|
|
||||||
for (int y = P.Y; y <= game.World.Height; y++) {
|
|
||||||
float spawnY = Respawn.HighestFreeY(game, ref bb);
|
|
||||||
if (spawnY == float.NegativeInfinity) {
|
|
||||||
BlockID block = game.World.GetPhysicsBlock(P.X, y, P.Z);
|
|
||||||
float height = BlockInfo.Collide[block] == CollideType.Solid ? BlockInfo.MaxBB[block].Y : 0;
|
|
||||||
spawn.Y = y + height + Entity.Adjustment;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
bb.Min.Y += 1; bb.Max.Y += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -7,7 +7,7 @@ using BlockID = System.UInt16;
|
|||||||
|
|
||||||
namespace ClassicalSharp.Entities {
|
namespace ClassicalSharp.Entities {
|
||||||
|
|
||||||
/// <summary> Entity component that performs collision detection. </summary>
|
/// <summary> Entity component that performs collisions. </summary>
|
||||||
public sealed class PhysicsComponent {
|
public sealed class PhysicsComponent {
|
||||||
|
|
||||||
bool useLiquidGravity = false; // used by BlockDefinitions.
|
bool useLiquidGravity = false; // used by BlockDefinitions.
|
||||||
@ -63,11 +63,12 @@ namespace ClassicalSharp.Entities {
|
|||||||
if (hacks.Speeding && hacks.CanSpeed) entity.Velocity.Y += 0.04f;
|
if (hacks.Speeding && hacks.CanSpeed) entity.Velocity.Y += 0.04f;
|
||||||
if (hacks.HalfSpeeding && hacks.CanSpeed) entity.Velocity.Y += 0.02f;
|
if (hacks.HalfSpeeding && hacks.CanSpeed) entity.Velocity.Y += 0.02f;
|
||||||
} else if (pastJumpPoint) {
|
} else if (pastJumpPoint) {
|
||||||
// either A) jump bob in water B) climb up solid on side
|
// either A) climb up solid on side B) jump bob in water
|
||||||
if (collisions.HorizontalCollision)
|
if (collisions.HorizontalCollision) {
|
||||||
entity.Velocity.Y += touchLava ? 0.30f : 0.13f;
|
entity.Velocity.Y += touchLava ? 0.30f : 0.13f;
|
||||||
else if (canLiquidJump)
|
} else if (canLiquidJump) {
|
||||||
entity.Velocity.Y += touchLava ? 0.20f : 0.10f;
|
entity.Velocity.Y += touchLava ? 0.20f : 0.10f;
|
||||||
|
}
|
||||||
canLiquidJump = false;
|
canLiquidJump = false;
|
||||||
}
|
}
|
||||||
} else if (useLiquidGravity) {
|
} else if (useLiquidGravity) {
|
||||||
@ -152,17 +153,14 @@ namespace ClassicalSharp.Entities {
|
|||||||
|
|
||||||
bool OnIce(Entity entity) {
|
bool OnIce(Entity entity) {
|
||||||
Vector3 under = entity.Position; under.Y -= 0.01f;
|
Vector3 under = entity.Position; under.Y -= 0.01f;
|
||||||
if (BlockInfo.ExtendedCollide[GetBlock(under)] == CollideType.Ice) return true;
|
BlockID blockUnder = game.World.SafeGetBlock(Vector3I.Floor(under));
|
||||||
|
if (BlockInfo.ExtendedCollide[blockUnder] == CollideType.Ice) return true;
|
||||||
|
|
||||||
AABB bounds = entity.Bounds;
|
AABB bounds = entity.Bounds;
|
||||||
bounds.Min.Y -= 0.01f; bounds.Max.Y = bounds.Min.Y;
|
bounds.Min.Y -= 0.01f; bounds.Max.Y = bounds.Min.Y;
|
||||||
return entity.TouchesAny(bounds, touchesSlipperyIce);
|
return entity.TouchesAny(bounds, touchesSlipperyIce);
|
||||||
}
|
}
|
||||||
|
|
||||||
BlockID GetBlock(Vector3 coords) {
|
|
||||||
return game.World.SafeGetBlock(Vector3I.Floor(coords));
|
|
||||||
}
|
|
||||||
|
|
||||||
static Predicate<BlockID> touchesSlipperyIce = IsSlipperyIce;
|
static Predicate<BlockID> touchesSlipperyIce = IsSlipperyIce;
|
||||||
static bool IsSlipperyIce(BlockID b) { return BlockInfo.ExtendedCollide[b] == CollideType.SlipperyIce; }
|
static bool IsSlipperyIce(BlockID b) { return BlockInfo.ExtendedCollide[b] == CollideType.SlipperyIce; }
|
||||||
|
|
||||||
@ -227,7 +225,7 @@ namespace ClassicalSharp.Entities {
|
|||||||
Vector3I max = Vector3I.Floor(bounds.Max);
|
Vector3I max = Vector3I.Floor(bounds.Max);
|
||||||
float modifier = inf;
|
float modifier = inf;
|
||||||
|
|
||||||
AABB blockBB = default(AABB);
|
AABB blockBB;
|
||||||
min.X = min.X < 0 ? 0 : min.X; max.X = max.X > game.World.MaxX ? game.World.MaxX : max.X;
|
min.X = min.X < 0 ? 0 : min.X; max.X = max.X > game.World.MaxX ? game.World.MaxX : max.X;
|
||||||
min.Y = min.Y < 0 ? 0 : min.Y; max.Y = max.Y > game.World.MaxY ? game.World.MaxY : max.Y;
|
min.Y = min.Y < 0 ? 0 : min.Y; max.Y = max.Y > game.World.MaxY ? game.World.MaxY : max.Y;
|
||||||
min.Z = min.Z < 0 ? 0 : min.Z; max.Z = max.Z > game.World.MaxZ ? game.World.MaxZ : max.Z;
|
min.Z = min.Z < 0 ? 0 : min.Z; max.Z = max.Z > game.World.MaxZ ? game.World.MaxZ : max.Z;
|
||||||
@ -237,7 +235,7 @@ namespace ClassicalSharp.Entities {
|
|||||||
for (int x = min.X; x <= max.X; x++)
|
for (int x = min.X; x <= max.X; x++)
|
||||||
{
|
{
|
||||||
BlockID block = game.World.GetBlock(x, y, z);
|
BlockID block = game.World.GetBlock(x, y, z);
|
||||||
if (block == 0) continue;
|
if (block == Block.Air) continue;
|
||||||
byte collide = BlockInfo.Collide[block];
|
byte collide = BlockInfo.Collide[block];
|
||||||
if (collide == CollideType.Solid && !checkSolid) continue;
|
if (collide == CollideType.Solid && !checkSolid) continue;
|
||||||
|
|
||||||
|
@ -170,7 +170,7 @@ namespace ClassicalSharp.Entities {
|
|||||||
Vector3I min = Vector3I.Floor(bounds.Min);
|
Vector3I min = Vector3I.Floor(bounds.Min);
|
||||||
Vector3I max = Vector3I.Floor(bounds.Max);
|
Vector3I max = Vector3I.Floor(bounds.Max);
|
||||||
|
|
||||||
AABB blockBB = default(AABB);
|
AABB blockBB;
|
||||||
Vector3 v;
|
Vector3 v;
|
||||||
min.X = min.X < 0 ? 0 : min.X; max.X = max.X > game.World.MaxX ? game.World.MaxX : max.X;
|
min.X = min.X < 0 ? 0 : min.X; max.X = max.X > game.World.MaxX ? game.World.MaxX : max.X;
|
||||||
min.Y = min.Y < 0 ? 0 : min.Y; max.Y = max.Y > game.World.MaxY ? game.World.MaxY : max.Y;
|
min.Y = min.Y < 0 ? 0 : min.Y; max.Y = max.Y > game.World.MaxY ? game.World.MaxY : max.Y;
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
// Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
|
// Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
|
||||||
using System;
|
using System;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
|
using ClassicalSharp.Physics;
|
||||||
using ClassicalSharp.Renderers;
|
using ClassicalSharp.Renderers;
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
using OpenTK.Input;
|
using OpenTK.Input;
|
||||||
|
using BlockID = System.UInt16;
|
||||||
|
|
||||||
namespace ClassicalSharp.Entities {
|
namespace ClassicalSharp.Entities {
|
||||||
|
|
||||||
@ -27,7 +29,6 @@ namespace ClassicalSharp.Entities {
|
|||||||
internal CollisionsComponent collisions;
|
internal CollisionsComponent collisions;
|
||||||
public HacksComponent Hacks;
|
public HacksComponent Hacks;
|
||||||
internal PhysicsComponent physics;
|
internal PhysicsComponent physics;
|
||||||
internal InputComponent input;
|
|
||||||
internal SoundComponent sound;
|
internal SoundComponent sound;
|
||||||
internal LocalInterpComponent interp;
|
internal LocalInterpComponent interp;
|
||||||
internal TiltComponent tilt;
|
internal TiltComponent tilt;
|
||||||
@ -39,31 +40,28 @@ namespace ClassicalSharp.Entities {
|
|||||||
collisions = new CollisionsComponent(game, this);
|
collisions = new CollisionsComponent(game, this);
|
||||||
Hacks = new HacksComponent(game);
|
Hacks = new HacksComponent(game);
|
||||||
physics = new PhysicsComponent(game, this);
|
physics = new PhysicsComponent(game, this);
|
||||||
input = new InputComponent(game, this);
|
|
||||||
sound = new SoundComponent(game, this);
|
sound = new SoundComponent(game, this);
|
||||||
interp = new LocalInterpComponent(game, this);
|
interp = new LocalInterpComponent(game, this);
|
||||||
tilt = new TiltComponent(game);
|
tilt = new TiltComponent(game);
|
||||||
|
physics.hacks = Hacks; physics.collisions = collisions;
|
||||||
physics.hacks = Hacks; input.Hacks = Hacks;
|
|
||||||
physics.collisions = collisions;
|
|
||||||
input.physics = physics;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Tick(double delta) {
|
public override void Tick(double delta) {
|
||||||
if (!game.World.HasBlocks) return;
|
if (!game.World.HasBlocks) return;
|
||||||
StepSize = Hacks.FullBlockStep && Hacks.Enabled && Hacks.CanAnyHacks
|
StepSize = Hacks.FullBlockStep && Hacks.Enabled && Hacks.CanAnyHacks && Hacks.CanSpeed ? 1 : 0.5f;
|
||||||
&& Hacks.CanSpeed ? 1 : 0.5f;
|
|
||||||
OldVelocity = Velocity;
|
OldVelocity = Velocity;
|
||||||
float xMoving = 0, zMoving = 0;
|
float xMoving = 0, zMoving = 0;
|
||||||
interp.AdvanceState();
|
interp.AdvanceState();
|
||||||
bool wasOnGround = onGround;
|
bool wasOnGround = onGround;
|
||||||
|
|
||||||
HandleInput(ref xMoving, ref zMoving);
|
HandleInput(ref xMoving, ref zMoving);
|
||||||
|
Hacks.Floating = Hacks.Noclip || Hacks.Flying;
|
||||||
if (!Hacks.Floating && Hacks.CanBePushed) physics.DoEntityPush();
|
if (!Hacks.Floating && Hacks.CanBePushed) physics.DoEntityPush();
|
||||||
|
|
||||||
// Immediate stop in noclip mode
|
// Immediate stop in noclip mode
|
||||||
if (!Hacks.NoclipSlide && (Hacks.Noclip && xMoving == 0 && zMoving == 0))
|
if (!Hacks.NoclipSlide && (Hacks.Noclip && xMoving == 0 && zMoving == 0)) {
|
||||||
Velocity = Vector3.Zero;
|
Velocity = Vector3.Zero;
|
||||||
|
}
|
||||||
physics.UpdateVelocityState();
|
physics.UpdateVelocityState();
|
||||||
physics.PhysicsTick(GetHeadingVelocity(zMoving, xMoving));
|
physics.PhysicsTick(GetHeadingVelocity(zMoving, xMoving));
|
||||||
|
|
||||||
@ -161,5 +159,70 @@ namespace ClassicalSharp.Entities {
|
|||||||
physics.serverJumpVel = 0.42f;
|
physics.serverJumpVel = 0.42f;
|
||||||
Health = 20;
|
Health = 20;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static Predicate<BlockID> touchesAnySolid = IsSolidCollide;
|
||||||
|
static bool IsSolidCollide(BlockID b) { return BlockInfo.Collide[b] == CollideType.Solid; }
|
||||||
|
void DoRespawn() {
|
||||||
|
if (!game.World.HasBlocks) return;
|
||||||
|
Vector3 spawn = Spawn;
|
||||||
|
Vector3I P = Vector3I.Floor(spawn);
|
||||||
|
AABB bb;
|
||||||
|
|
||||||
|
// Spawn player at highest valid position
|
||||||
|
if (game.World.IsValidPos(P)) {
|
||||||
|
bb = AABB.Make(spawn, Size);
|
||||||
|
for (int y = P.Y; y <= game.World.Height; y++) {
|
||||||
|
float spawnY = Respawn.HighestFreeY(game, ref bb);
|
||||||
|
if (spawnY == float.NegativeInfinity) {
|
||||||
|
BlockID block = game.World.GetPhysicsBlock(P.X, y, P.Z);
|
||||||
|
float height = BlockInfo.Collide[block] == CollideType.Solid ? BlockInfo.MaxBB[block].Y : 0;
|
||||||
|
spawn.Y = y + height + Entity.Adjustment;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
bb.Min.Y += 1; bb.Max.Y += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
spawn.Y += 2/16f;
|
||||||
|
LocationUpdate update = LocationUpdate.MakePosAndOri(spawn, SpawnRotY, SpawnHeadX, false);
|
||||||
|
SetLocation(update, false);
|
||||||
|
Velocity = Vector3.Zero;
|
||||||
|
|
||||||
|
// Update onGround, otherwise if 'respawn' then 'space' is pressed, you still jump into the air if onGround was true before
|
||||||
|
bb = Bounds;
|
||||||
|
bb.Min.Y -= 0.01f; bb.Max.Y = bb.Min.Y;
|
||||||
|
onGround = TouchesAny(bb, touchesAnySolid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool HandlesKey(Key key) {
|
||||||
|
KeyMap keys = game.Input.Keys;
|
||||||
|
if (key == keys[KeyBind.Respawn] && Hacks.CanRespawn) {
|
||||||
|
DoRespawn();
|
||||||
|
} else if (key == keys[KeyBind.SetSpawn] && Hacks.CanRespawn) {
|
||||||
|
Spawn = Position;
|
||||||
|
Spawn.X = Utils.Floor(Spawn.X) + 0.5f;
|
||||||
|
Spawn.Z = Utils.Floor(Spawn.Z) + 0.5f;
|
||||||
|
SpawnRotY = RotY;
|
||||||
|
SpawnHeadX = HeadX;
|
||||||
|
DoRespawn();
|
||||||
|
} else if (key == keys[KeyBind.Fly] && Hacks.CanFly && Hacks.Enabled) {
|
||||||
|
Hacks.Flying = !Hacks.Flying;
|
||||||
|
} else if (key == keys[KeyBind.NoClip] && Hacks.CanNoclip && Hacks.Enabled && !Hacks.WOMStyleHacks) {
|
||||||
|
if (Hacks.Noclip) Velocity.Y = 0;
|
||||||
|
Hacks.Noclip = !Hacks.Noclip;
|
||||||
|
} else if (key == keys[KeyBind.Jump] && !onGround && !(Hacks.Flying || Hacks.Noclip)) {
|
||||||
|
int maxJumps = Hacks.CanDoubleJump && Hacks.WOMStyleHacks ? 2 : 0;
|
||||||
|
maxJumps = Math.Max(maxJumps, Hacks.MaxJumps - 1);
|
||||||
|
|
||||||
|
if (physics.multiJumps < maxJumps) {
|
||||||
|
physics.DoNormalJump();
|
||||||
|
physics.multiJumps++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -160,7 +160,7 @@ namespace ClassicalSharp {
|
|||||||
} else if (key == Keys[KeyBind.Screenshot]) {
|
} else if (key == Keys[KeyBind.Screenshot]) {
|
||||||
game.screenshotRequested = true;
|
game.screenshotRequested = true;
|
||||||
} else if (!game.Gui.ActiveScreen.HandlesKeyDown(key)) {
|
} else if (!game.Gui.ActiveScreen.HandlesKeyDown(key)) {
|
||||||
if (!HandleBuiltinKey(key) && !game.LocalPlayer.input.Handles(key))
|
if (!HandleBuiltinKey(key) && !game.LocalPlayer.HandlesKey(key))
|
||||||
HandleHotkey(key);
|
HandleHotkey(key);
|
||||||
}
|
}
|
||||||
lastKey = key;
|
lastKey = key;
|
||||||
|
@ -160,8 +160,11 @@ namespace ClassicalSharp.Renderers {
|
|||||||
// TODO: rewrite this to avoid raising the event? want to avoid recreating vbos too many times often
|
// TODO: rewrite this to avoid raising the event? want to avoid recreating vbos too many times often
|
||||||
if (fogDensity != 0) {
|
if (fogDensity != 0) {
|
||||||
// Exp fog mode: f = e^(-density*coord)
|
// Exp fog mode: f = e^(-density*coord)
|
||||||
// Solve for f = 0.05 to figure out coord (good approx for fog end)
|
// Solve coord for f = 0.05 (good approx for fog end)
|
||||||
float dist = (float)Math.Log(0.05) / -fogDensity;
|
// i.e. log(0.05) = -density * coord
|
||||||
|
|
||||||
|
const double log005 = -2.99573227355399;
|
||||||
|
double dist = log005 / -fogDensity;
|
||||||
game.SetViewDistance((int)dist, false);
|
game.SetViewDistance((int)dist, false);
|
||||||
} else {
|
} else {
|
||||||
game.SetViewDistance(game.UserViewDistance, false);
|
game.SetViewDistance(game.UserViewDistance, false);
|
||||||
@ -233,7 +236,9 @@ namespace ClassicalSharp.Renderers {
|
|||||||
// 0.99=z/end --> z=end*0.99
|
// 0.99=z/end --> z=end*0.99
|
||||||
// therefore
|
// therefore
|
||||||
// d = -ln(0.01)/(end*0.99)
|
// d = -ln(0.01)/(end*0.99)
|
||||||
double density = -Math.Log(0.01) / (game.ViewDistance * 0.99);
|
|
||||||
|
const double log001 = -4.60517018598809;
|
||||||
|
double density = -log001 / (game.ViewDistance * 0.99);
|
||||||
gfx.SetFogDensity((float)density);
|
gfx.SetFogDensity((float)density);
|
||||||
} else {
|
} else {
|
||||||
gfx.SetFogMode(Fog.Linear);
|
gfx.SetFogMode(Fog.Linear);
|
||||||
|
@ -16,7 +16,7 @@ namespace ClassicalSharp {
|
|||||||
int minZ = Utils.Floor(bb.Min.Z), maxZ = Utils.Floor(bb.Max.Z);
|
int minZ = Utils.Floor(bb.Min.Z), maxZ = Utils.Floor(bb.Max.Z);
|
||||||
|
|
||||||
float spawnY = float.NegativeInfinity;
|
float spawnY = float.NegativeInfinity;
|
||||||
AABB blockBB = default(AABB);
|
AABB blockBB;
|
||||||
|
|
||||||
for (int y = minY; y <= maxY; y++)
|
for (int y = minY; y <= maxY; y++)
|
||||||
for (int z = minZ; z <= maxZ; z++)
|
for (int z = minZ; z <= maxZ; z++)
|
||||||
|
@ -74,8 +74,6 @@ namespace OpenTK {
|
|||||||
|
|
||||||
public static readonly Vector3 One = new Vector3(1, 1, 1);
|
public static readonly Vector3 One = new Vector3(1, 1, 1);
|
||||||
|
|
||||||
public static readonly int SizeInBytes = 3 * sizeof( float );
|
|
||||||
|
|
||||||
public static void Add(ref Vector3 a, ref Vector3 b, out Vector3 result) {
|
public static void Add(ref Vector3 a, ref Vector3 b, out Vector3 result) {
|
||||||
result = new Vector3(a.X + b.X, a.Y + b.Y, a.Z + b.Z);
|
result = new Vector3(a.X + b.X, a.Y + b.Y, a.Z + b.Z);
|
||||||
}
|
}
|
||||||
|
@ -30,8 +30,8 @@ void LavaAnimation_Tick(UInt32* ptr, Int32 size) {
|
|||||||
for (y = 0; y < size; y++) {
|
for (y = 0; y < size; y++) {
|
||||||
for (x = 0; x < size; x++) {
|
for (x = 0; x < size; x++) {
|
||||||
/* Calculate the colour at this coordinate in the heatmap */
|
/* Calculate the colour at this coordinate in the heatmap */
|
||||||
Int32 xx = x + (Int32)(1.2f * Math_Sin(y * 22.5f * MATH_DEG2RAD));
|
Int32 xx = x + (Int32)(1.2f * Math_SinF(y * 22.5f * MATH_DEG2RAD));
|
||||||
Int32 yy = y + (Int32)(1.2f * Math_Sin(x * 22.5f * MATH_DEG2RAD));
|
Int32 yy = y + (Int32)(1.2f * Math_SinF(x * 22.5f * MATH_DEG2RAD));
|
||||||
Real32 lSoupHeat =
|
Real32 lSoupHeat =
|
||||||
L_soupHeat[((yy - 1) & mask) << shift | ((xx - 1) & mask)] +
|
L_soupHeat[((yy - 1) & mask) << shift | ((xx - 1) & mask)] +
|
||||||
L_soupHeat[((yy - 1) & mask) << shift | (xx & mask)] +
|
L_soupHeat[((yy - 1) & mask) << shift | (xx & mask)] +
|
||||||
|
@ -487,7 +487,7 @@ BlockID AutoRotate_RotateBlock(BlockID block) {
|
|||||||
|
|
||||||
Vector3 translated, offset;
|
Vector3 translated, offset;
|
||||||
Vector3I_ToVector3(&translated, &Game_SelectedPos.TranslatedPos);
|
Vector3I_ToVector3(&translated, &Game_SelectedPos.TranslatedPos);
|
||||||
Vector3_Subtract(&offset, &Game_SelectedPos.Intersect, &translated);
|
Vector3_Sub(&offset, &Game_SelectedPos.Intersect, &translated);
|
||||||
|
|
||||||
if (AR_EQ2(dir, 'n', 'w') || AR_EQ2(dir, 'n', 'e') || AR_EQ2(dir, 's', 'w') || AR_EQ2(dir, 's', 'e')) {
|
if (AR_EQ2(dir, 'n', 'w') || AR_EQ2(dir, 'n', 'e') || AR_EQ2(dir, 's', 'w') || AR_EQ2(dir, 's', 'e')) {
|
||||||
return AutoRotate_RotateCorner(block, &baseName, offset);
|
return AutoRotate_RotateCorner(block, &baseName, offset);
|
||||||
|
@ -148,8 +148,8 @@ Vector3 FirstPersonCamera_GetCameraPos(Real32 t) {
|
|||||||
camPos.Y += Camera_BobbingVer;
|
camPos.Y += Camera_BobbingVer;
|
||||||
|
|
||||||
Real32 headY = (p->HeadY * MATH_DEG2RAD);
|
Real32 headY = (p->HeadY * MATH_DEG2RAD);
|
||||||
camPos.X += Camera_BobbingHor * Math_Cos(headY);
|
camPos.X += Camera_BobbingHor * Math_CosF(headY);
|
||||||
camPos.Z += Camera_BobbingHor * Math_Sin(headY);
|
camPos.Z += Camera_BobbingHor * Math_SinF(headY);
|
||||||
return camPos;
|
return camPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,6 +138,7 @@
|
|||||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||||
<AdditionalOptions>
|
<AdditionalOptions>
|
||||||
</AdditionalOptions>
|
</AdditionalOptions>
|
||||||
|
<EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Windows</SubSystem>
|
<SubSystem>Windows</SubSystem>
|
||||||
@ -166,6 +167,7 @@
|
|||||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||||
<AdditionalOptions>
|
<AdditionalOptions>
|
||||||
</AdditionalOptions>
|
</AdditionalOptions>
|
||||||
|
<EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Windows</SubSystem>
|
<SubSystem>Windows</SubSystem>
|
||||||
|
@ -16,12 +16,13 @@
|
|||||||
#include "AsyncDownloader.h"
|
#include "AsyncDownloader.h"
|
||||||
#include "ErrorHandler.h"
|
#include "ErrorHandler.h"
|
||||||
#include "IModel.h"
|
#include "IModel.h"
|
||||||
|
#include "Input.h"
|
||||||
|
|
||||||
const UInt8* NameMode_Names[NAME_MODE_COUNT] = { "None", "Hovered", "All", "AllHovered", "AllUnscaled" };
|
const UInt8* NameMode_Names[NAME_MODE_COUNT] = { "None", "Hovered", "All", "AllHovered", "AllUnscaled" };
|
||||||
const UInt8* ShadowMode_Names[SHADOW_MODE_COUNT] = { "None", "SnapToBlock", "Circle", "CircleAll" };
|
const UInt8* ShadowMode_Names[SHADOW_MODE_COUNT] = { "None", "SnapToBlock", "Circle", "CircleAll" };
|
||||||
|
|
||||||
Real32 LocationUpdate_Clamp(Real32 degrees) {
|
Real32 LocationUpdate_Clamp(Real32 degrees) {
|
||||||
degrees = Math_Mod(degrees, 360.0f);
|
degrees = Math_ModF(degrees, 360.0f);
|
||||||
if (degrees < 0) degrees += 360.0f;
|
if (degrees < 0) degrees += 360.0f;
|
||||||
return degrees;
|
return degrees;
|
||||||
}
|
}
|
||||||
@ -154,33 +155,29 @@ void Entity_SetModel(Entity* entity, STRING_PURE String* model) {
|
|||||||
void Entity_UpdateModelBounds(Entity* entity) {
|
void Entity_UpdateModelBounds(Entity* entity) {
|
||||||
IModel* model = entity->Model;
|
IModel* model = entity->Model;
|
||||||
Vector3 baseSize = model->GetCollisionSize();
|
Vector3 baseSize = model->GetCollisionSize();
|
||||||
Vector3_Multiply3(&entity->Size, &baseSize, &entity->ModelScale);
|
Vector3_Mul3(&entity->Size, &baseSize, &entity->ModelScale);
|
||||||
|
|
||||||
AABB* bb = &entity->ModelAABB;
|
AABB* bb = &entity->ModelAABB;
|
||||||
model->GetPickingBounds(bb);
|
model->GetPickingBounds(bb);
|
||||||
Vector3_Multiply3(&bb->Min, &bb->Min, &entity->ModelScale);
|
Vector3_Mul3By(&bb->Min, &entity->ModelScale);
|
||||||
Vector3_Multiply3(&bb->Max, &bb->Max, &entity->ModelScale);
|
Vector3_Mul3By(&bb->Max, &entity->ModelScale);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Entity_TouchesAny(AABB* bounds, bool (*touches_condition)(BlockID block__)) {
|
bool Entity_TouchesAny(AABB* bounds, bool (*touches_condition)(BlockID block__)) {
|
||||||
Vector3I bbMin, bbMax;
|
Vector3I bbMin, bbMax;
|
||||||
Vector3I_Floor(&bbMin, &bounds->Min);
|
Vector3I_Floor(&bbMin, &bounds->Min);
|
||||||
Vector3I_Floor(&bbMax, &bounds->Max);
|
Vector3I_Floor(&bbMax, &bounds->Max);
|
||||||
AABB blockBB;
|
|
||||||
Vector3 v;
|
|
||||||
|
|
||||||
bbMin.X = max(bbMin.X, 0); bbMax.X = min(bbMax.X, World_MaxX);
|
bbMin.X = max(bbMin.X, 0); bbMax.X = min(bbMax.X, World_MaxX);
|
||||||
bbMin.Y = max(bbMin.Y, 0); bbMax.Y = min(bbMax.Y, World_MaxY);
|
bbMin.Y = max(bbMin.Y, 0); bbMax.Y = min(bbMax.Y, World_MaxY);
|
||||||
bbMin.Z = max(bbMin.Z, 0); bbMax.Z = min(bbMax.Z, World_MaxZ);
|
bbMin.Z = max(bbMin.Z, 0); bbMax.Z = min(bbMax.Z, World_MaxZ);
|
||||||
|
|
||||||
|
AABB blockBB;
|
||||||
|
Vector3 v;
|
||||||
Int32 x, y, z;
|
Int32 x, y, z;
|
||||||
for (y = bbMin.Y; y <= bbMax.Y; y++) {
|
for (y = bbMin.Y; y <= bbMax.Y; y++) { v.Y = (Real32)y;
|
||||||
v.Y = (Real32)y;
|
for (z = bbMin.Z; z <= bbMax.Z; z++) { v.Z = (Real32)z;
|
||||||
for (z = bbMin.Z; z <= bbMax.Z; z++) {
|
for (x = bbMin.X; x <= bbMax.X; x++) { v.X = (Real32)x;
|
||||||
v.Z = (Real32)z;
|
|
||||||
for (x = bbMin.X; x <= bbMax.X; x++) {
|
|
||||||
v.X = (Real32)x;
|
|
||||||
|
|
||||||
BlockID block = World_GetBlock(x, y, z);
|
BlockID block = World_GetBlock(x, y, z);
|
||||||
Vector3_Add(&blockBB.Min, &v, &Block_MinBB[block]);
|
Vector3_Add(&blockBB.Min, &v, &Block_MinBB[block]);
|
||||||
Vector3_Add(&blockBB.Max, &v, &Block_MaxBB[block]);
|
Vector3_Add(&blockBB.Max, &v, &Block_MaxBB[block]);
|
||||||
@ -728,3 +725,84 @@ void Player_Init(Player* player) {
|
|||||||
entity->VTABLE->ContextRecreated = Player_ContextRecreated;
|
entity->VTABLE->ContextRecreated = Player_ContextRecreated;
|
||||||
entity->VTABLE->Despawn = Player_Despawn;
|
entity->VTABLE->Despawn = Player_Despawn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Real32 LocalPlayer_JumpHeight(void) {
|
||||||
|
LocalPlayer* p = &LocalPlayer_Instance;
|
||||||
|
return (Real32)PhysicsComp_GetMaxHeight(p->Physics.JumpVel);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocalPlayer_CheckHacksConsistency(void) {
|
||||||
|
LocalPlayer* p = &LocalPlayer_Instance;
|
||||||
|
HacksComp_CheckConsistency(&p->Hacks);
|
||||||
|
if (!HacksComp_CanJumpHigher(&p->Hacks)) {
|
||||||
|
p->Physics.JumpVel = p->Physics.ServerJumpVel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LocalPlayer_IsSolidCollide(BlockID b) { return Block_Collide[b] == COLLIDE_SOLID; }
|
||||||
|
void LocalPlayer_DoRespawn(void) {
|
||||||
|
if (World_Blocks == NULL) return;
|
||||||
|
LocalPlayer* p = &LocalPlayer_Instance;
|
||||||
|
Vector3 spawn = p->Spawn;
|
||||||
|
Vector3I P; Vector3I_Floor(&P, &spawn);
|
||||||
|
AABB bb;
|
||||||
|
|
||||||
|
/* Spawn player at highest valid position */
|
||||||
|
if (World_IsValidPos_3I(P)) {
|
||||||
|
AAABB_Make(&bb, &spawn, &p->Base.Size);
|
||||||
|
Int32 y;
|
||||||
|
for (y = P.Y; y <= World_Height; y++) {
|
||||||
|
Real32 spawnY = Respawn_HighestFreeY(&bb);
|
||||||
|
if (spawnY == RESPAWN_NOT_FOUND) {
|
||||||
|
BlockID block = World_GetPhysicsBlock(P.X, y, P.Z);
|
||||||
|
Real32 height = Block_Collide[block] == COLLIDE_SOLID ? Block_MaxBB[block].Y : 0.0f;
|
||||||
|
spawn.Y = y + height + ENTITY_ADJUSTMENT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
bb.Min.Y += 1.0f; bb.Max.Y += 1.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
spawn.Y += 2.0f / 16.0f;
|
||||||
|
LocationUpdate update; LocationUpdate_MakePosAndOri(&update, spawn, p->SpawnRotY, p->SpawnHeadX, false);
|
||||||
|
p->Base.VTABLE->SetLocation(&p->Base, &update, false);
|
||||||
|
Vector3 zero = Vector3_Zero; p->Base.Velocity = zero;
|
||||||
|
|
||||||
|
/* Update onGround, otherwise if 'respawn' then 'space' is pressed, you still jump into the air if onGround was true before */
|
||||||
|
Entity_GetBounds(&p->Base, &bb);
|
||||||
|
bb.Min.Y -= 0.01f; bb.Max.Y = bb.Min.Y;
|
||||||
|
p->Base.OnGround = Entity_TouchesAny(&bb, LocalPlayer_IsSolidCollide);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LocalPlayer_HandlesKey(Int32 key) {
|
||||||
|
LocalPlayer* p = &LocalPlayer_Instance;
|
||||||
|
HacksComp* hacks = &p->Hacks;
|
||||||
|
PhysicsComp* physics = &p->Physics;
|
||||||
|
|
||||||
|
if (key == KeyBind_Get(KeyBind_Respawn) && hacks->CanRespawn) {
|
||||||
|
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();
|
||||||
|
} 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) {
|
||||||
|
if (hacks->Noclip) p->Base.Velocity.Y = 0;
|
||||||
|
hacks->Noclip = !hacks->Noclip;
|
||||||
|
} else if (key == KeyBind_Get(KeyBind_Jump) && !p->Base.OnGround && !(hacks->Flying || hacks->Noclip)) {
|
||||||
|
Int32 maxJumps = hacks->CanDoubleJump && hacks->WOMStyleHacks ? 2 : 0;
|
||||||
|
maxJumps = max(maxJumps, hacks->MaxJumps - 1);
|
||||||
|
|
||||||
|
if (physics->MultiJumps < maxJumps) {
|
||||||
|
PhysicsComp_DoNormalJump(physics);
|
||||||
|
physics->MultiJumps++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
@ -52,15 +52,16 @@ void LocationUpdate_MakeOri(LocationUpdate* update, Real32 rotY, Real32 headX);
|
|||||||
void LocationUpdate_MakePos(LocationUpdate* update, Vector3 pos, bool rel);
|
void LocationUpdate_MakePos(LocationUpdate* update, Vector3 pos, bool rel);
|
||||||
void LocationUpdate_MakePosAndOri(LocationUpdate* update, Vector3 pos, Real32 rotY, Real32 headX, bool rel);
|
void LocationUpdate_MakePosAndOri(LocationUpdate* update, Vector3 pos, Real32 rotY, Real32 headX, bool rel);
|
||||||
|
|
||||||
|
typedef struct Entity_ Entity;
|
||||||
typedef struct EntityVTABLE_ {
|
typedef struct EntityVTABLE_ {
|
||||||
void (*Tick)(struct Entity_* entity, ScheduledTask* task);
|
void (*Tick)(Entity* entity, ScheduledTask* task);
|
||||||
void (*SetLocation)(struct Entity_* entity, LocationUpdate* update, bool interpolate);
|
void (*SetLocation)(Entity* entity, LocationUpdate* update, bool interpolate);
|
||||||
void (*RenderModel)(struct Entity_* entity, Real64 deltaTime, Real32 t);
|
void (*RenderModel)(Entity* entity, Real64 deltaTime, Real32 t);
|
||||||
void (*RenderName)(struct Entity_* entity);
|
void (*RenderName)(Entity* entity);
|
||||||
void (*ContextLost)(struct Entity_* entity);
|
void (*ContextLost)(Entity* entity);
|
||||||
void (*ContextRecreated)(struct Entity_* entity);
|
void (*ContextRecreated)(Entity* entity);
|
||||||
void (*Despawn)(struct Entity_* entity);
|
void (*Despawn)(Entity* entity);
|
||||||
PackedCol (*GetCol)(struct Entity_* entity);
|
PackedCol (*GetCol)(Entity* entity);
|
||||||
} EntityVTABLE;
|
} EntityVTABLE;
|
||||||
|
|
||||||
/* Contains a model, along with position, velocity, and rotation. May also contain other fields and properties. */
|
/* Contains a model, along with position, velocity, and rotation. May also contain other fields and properties. */
|
||||||
@ -149,10 +150,13 @@ typedef struct LocalPlayer_ {
|
|||||||
HacksComp Hacks;
|
HacksComp Hacks;
|
||||||
TiltComp Tilt;
|
TiltComp Tilt;
|
||||||
InterpComp Interp;
|
InterpComp Interp;
|
||||||
|
CollisionsComp Collisions;
|
||||||
|
PhysicsComp Physics;
|
||||||
} LocalPlayer;
|
} LocalPlayer;
|
||||||
|
|
||||||
LocalPlayer LocalPlayer_Instance;
|
LocalPlayer LocalPlayer_Instance;
|
||||||
void LocalPlayer_Init(void);
|
void LocalPlayer_Init(void);
|
||||||
Real32 LocalPlayer_JumpHeight(void);
|
Real32 LocalPlayer_JumpHeight(void);
|
||||||
void LocalPlayer_ChecksHackConsistency();
|
void LocalPlayer_CheckHacksConsistency(void);
|
||||||
|
bool LocalPlayer_HandlesKey(Int32 key);
|
||||||
#endif
|
#endif
|
@ -1,4 +1,4 @@
|
|||||||
#include "EntityComponents.h"
|
#include "EntityComponents.h"
|
||||||
#include "ExtMath.h"
|
#include "ExtMath.h"
|
||||||
#include "World.h"
|
#include "World.h"
|
||||||
#include "Block.h"
|
#include "Block.h"
|
||||||
@ -36,9 +36,9 @@ void AnimatedComp_DoTilt(Real32* tilt, bool reduce) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void AnimatedComp_PerpendicularAnim(AnimatedComp* anim, Real32 flapSpeed, Real32 idleXRot, Real32 idleZRot, bool left) {
|
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 verAngle = 0.5f + 0.5f * Math_SinF(anim->WalkTime * flapSpeed);
|
||||||
Real32 zRot = -idleZRot - verAngle * anim->Swing * ANIM_MAX_ANGLE;
|
Real32 zRot = -idleZRot - verAngle * anim->Swing * ANIM_MAX_ANGLE;
|
||||||
Real32 horAngle = Math_Cos(anim->WalkTime) * anim->Swing * ANIM_ARM_MAX * 1.5f;
|
Real32 horAngle = Math_CosF(anim->WalkTime) * anim->Swing * ANIM_ARM_MAX * 1.5f;
|
||||||
Real32 xRot = idleXRot + horAngle;
|
Real32 xRot = idleXRot + horAngle;
|
||||||
|
|
||||||
if (left) {
|
if (left) {
|
||||||
@ -64,7 +64,7 @@ void AnimatedComp_Update(AnimatedComp* anim, Vector3 oldPos, Vector3 newPos, Rea
|
|||||||
anim->SwingO = anim->SwingN;
|
anim->SwingO = anim->SwingN;
|
||||||
Real32 dx = newPos.X - oldPos.X;
|
Real32 dx = newPos.X - oldPos.X;
|
||||||
Real32 dz = newPos.Z - oldPos.Z;
|
Real32 dz = newPos.Z - oldPos.Z;
|
||||||
Real32 distance = Math_Sqrt(dx * dx + dz * dz);
|
Real32 distance = Math_SqrtF(dx * dx + dz * dz);
|
||||||
|
|
||||||
if (distance > 0.05f) {
|
if (distance > 0.05f) {
|
||||||
Real32 walkDelta = distance * 2 * (Real32)(20 * delta);
|
Real32 walkDelta = distance * 2 * (Real32)(20 * delta);
|
||||||
@ -90,20 +90,20 @@ void AnimatedComp_GetCurrent(AnimatedComp* anim, Real32 t, bool calcHumanAnims)
|
|||||||
anim->BobStrength = Math_Lerp(anim->BobStrengthO, anim->BobStrengthN, t);
|
anim->BobStrength = Math_Lerp(anim->BobStrengthO, anim->BobStrengthN, t);
|
||||||
|
|
||||||
Real32 idleTime = (Real32)Game_Accumulator;
|
Real32 idleTime = (Real32)Game_Accumulator;
|
||||||
Real32 idleXRot = Math_Sin(idleTime * ANIM_IDLE_XPERIOD) * ANIM_IDLE_MAX;
|
Real32 idleXRot = Math_SinF(idleTime * ANIM_IDLE_XPERIOD) * ANIM_IDLE_MAX;
|
||||||
Real32 idleZRot = ANIM_IDLE_MAX + Math_Cos(idleTime * ANIM_IDLE_ZPERIOD) * ANIM_IDLE_MAX;
|
Real32 idleZRot = ANIM_IDLE_MAX + Math_CosF(idleTime * ANIM_IDLE_ZPERIOD) * ANIM_IDLE_MAX;
|
||||||
|
|
||||||
anim->LeftArmX = (Math_Cos(anim->WalkTime) * anim->Swing * ANIM_ARM_MAX) - idleXRot;
|
anim->LeftArmX = (Math_CosF(anim->WalkTime) * anim->Swing * ANIM_ARM_MAX) - idleXRot;
|
||||||
anim->LeftArmZ = -idleZRot;
|
anim->LeftArmZ = -idleZRot;
|
||||||
anim->LeftLegX = -(Math_Cos(anim->WalkTime) * anim->Swing * ANIM_LEG_MAX);
|
anim->LeftLegX = -(Math_CosF(anim->WalkTime) * anim->Swing * ANIM_LEG_MAX);
|
||||||
anim->LeftLegZ = 0;
|
anim->LeftLegZ = 0;
|
||||||
|
|
||||||
anim->RightLegX = -anim->LeftLegX; anim->RightLegZ = -anim->LeftLegZ;
|
anim->RightLegX = -anim->LeftLegX; anim->RightLegZ = -anim->LeftLegZ;
|
||||||
anim->RightArmX = -anim->LeftArmX; anim->RightArmZ = -anim->LeftArmZ;
|
anim->RightArmX = -anim->LeftArmX; anim->RightArmZ = -anim->LeftArmZ;
|
||||||
|
|
||||||
anim->BobbingHor = Math_Cos(anim->WalkTime) * anim->Swing * (2.5f / 16.0f);
|
anim->BobbingHor = Math_CosF(anim->WalkTime) * anim->Swing * (2.5f / 16.0f);
|
||||||
anim->BobbingVer = Math_AbsF(Math_Sin(anim->WalkTime)) * anim->Swing * (2.5f / 16.0f);
|
anim->BobbingVer = Math_AbsF(Math_SinF(anim->WalkTime)) * anim->Swing * (2.5f / 16.0f);
|
||||||
anim->BobbingModel = Math_AbsF(Math_Cos(anim->WalkTime)) * anim->Swing * (4.0f / 16.0f);
|
anim->BobbingModel = Math_AbsF(Math_CosF(anim->WalkTime)) * anim->Swing * (4.0f / 16.0f);
|
||||||
|
|
||||||
if (calcHumanAnims && !Game_SimpleArmsAnim) {
|
if (calcHumanAnims && !Game_SimpleArmsAnim) {
|
||||||
AnimatedComp_CalcHumanAnim(anim, idleXRot, idleZRot);
|
AnimatedComp_CalcHumanAnim(anim, idleXRot, idleZRot);
|
||||||
@ -126,7 +126,7 @@ void TiltComp_Update(TiltComp* anim, Real64 delta) {
|
|||||||
/* TODO: the Tilt code was designed for 60 ticks/second, fix it up for 20 ticks/second */
|
/* TODO: the Tilt code was designed for 60 ticks/second, fix it up for 20 ticks/second */
|
||||||
Int32 i;
|
Int32 i;
|
||||||
for (i = 0; i < 3; i++) {
|
for (i = 0; i < 3; i++) {
|
||||||
AnimatedComp_DoTilt(&anim->VelTiltStrengthN, p->Hacks.Noclip || p->Hacks.Flying);
|
AnimatedComp_DoTilt(&anim->VelTiltStrengthN, p->Hacks.Floating);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,8 +135,8 @@ void TiltComp_GetCurrent(TiltComp* anim, Real32 t) {
|
|||||||
anim->VelTiltStrength = Math_Lerp(anim->VelTiltStrengthO, anim->VelTiltStrengthN, t);
|
anim->VelTiltStrength = Math_Lerp(anim->VelTiltStrengthO, anim->VelTiltStrengthN, t);
|
||||||
|
|
||||||
AnimatedComp* pAnim = &p->Base.Anim;
|
AnimatedComp* pAnim = &p->Base.Anim;
|
||||||
anim->TiltX = Math_Cos(pAnim->WalkTime) * pAnim->Swing * (0.15f * MATH_DEG2RAD);
|
anim->TiltX = Math_CosF(pAnim->WalkTime) * pAnim->Swing * (0.15f * MATH_DEG2RAD);
|
||||||
anim->TiltY = Math_Sin(pAnim->WalkTime) * pAnim->Swing * (0.15f * MATH_DEG2RAD);
|
anim->TiltY = Math_SinF(pAnim->WalkTime) * pAnim->Swing * (0.15f * MATH_DEG2RAD);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -665,29 +665,126 @@ void ShadowComponent_Draw(Entity* entity) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
typedef struct CollisionsComponent_ {
|
/*########################################################################################################################*
|
||||||
Entity* Entity;
|
*---------------------------------------------------CollisionsComponent---------------------------------------------------*
|
||||||
bool HitXMin, HitYMin, HitZMin, HitXMax, HitYMax, HitZMax, WasOn;
|
*#########################################################################################################################*/
|
||||||
} CollisionsComponent;
|
|
||||||
|
|
||||||
/* Whether a collision occurred with any horizontal sides of any blocks */
|
/* Whether a collision occurred with any horizontal sides of any blocks */
|
||||||
bool Collisions_HitHorizontal(CollisionsComponent* comp) {
|
bool Collisions_HitHorizontal(CollisionsComp* comp) {
|
||||||
return comp->HitXMin || comp->HitXMax || comp->HitZMin || comp->HitZMax;
|
return comp->HitXMin || comp->HitXMax || comp->HitZMin || comp->HitZMax;
|
||||||
}
|
}
|
||||||
|
#define COLLISIONS_ADJ 0.001f
|
||||||
|
|
||||||
|
void Collisions_ClipX(Entity* entity, Vector3* size, AABB* entityBB, AABB* extentBB) {
|
||||||
/* TODO: test for corner cases, and refactor this */
|
entity->Velocity.X = 0.0f;
|
||||||
void Collisions_MoveAndWallSlide(CollisionsComponent* comp) {
|
entityBB->Min.X = entity->Position.X - size->X / 2; extentBB->Min.X = entityBB->Min.X;
|
||||||
Vector3 zero = Vector3_Zero;
|
entityBB->Max.X = entity->Position.X + size->X / 2; extentBB->Max.X = entityBB->Max.X;
|
||||||
Entity* entity = comp->Entity;
|
|
||||||
if (Vector3_Equals(&entity->Velocity, &zero)) return;
|
|
||||||
|
|
||||||
AABB entityBB, entityExtentBB;
|
|
||||||
UInt32 count = Searcher_FindReachableBlocks(entity, &entityBB, &entityExtentBB);
|
|
||||||
CollideWithReachableBlocks(comp, count, &entityBB, &entityExtentBB);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Collisions_CollideWithReachableBlocks(CollisionsComponent* comp, UInt32 count, AABB* entityBB, AABB* extentBB) {
|
void Collisions_ClipY(Entity* entity, Vector3* size, AABB* entityBB, AABB* extentBB) {
|
||||||
|
entity->Velocity.Y = 0.0f;
|
||||||
|
entityBB->Min.Y = entity->Position.Y; extentBB->Min.Y = entityBB->Min.Y;
|
||||||
|
entityBB->Max.Y = entity->Position.Y + size->Y; extentBB->Max.Y = entityBB->Max.Y;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Collisions_ClipZ(Entity* entity, Vector3* size, AABB* entityBB, AABB* extentBB) {
|
||||||
|
entity->Velocity.Z = 0.0f;
|
||||||
|
entityBB->Min.Z = entity->Position.Z - size->Z / 2; extentBB->Min.Z = entityBB->Min.Z;
|
||||||
|
entityBB->Max.Z = entity->Position.Z + size->Z / 2; extentBB->Max.Z = entityBB->Max.Z;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Collisions_CanSlideThrough(AABB* adjFinalBB) {
|
||||||
|
Vector3I bbMin; Vector3I_Floor(&bbMin, &adjFinalBB->Min);
|
||||||
|
Vector3I bbMax; Vector3I_Floor(&bbMax, &adjFinalBB->Max);
|
||||||
|
|
||||||
|
AABB blockBB;
|
||||||
|
Vector3 v;
|
||||||
|
Int32 x, y, z;
|
||||||
|
for (y = bbMin.Y; y <= bbMax.Y; y++) { v.Y = (Real32)y;
|
||||||
|
for (z = bbMin.Z; z <= bbMax.Z; z++) { v.Z = (Real32)z;
|
||||||
|
for (x = bbMin.X; x <= bbMax.X; x++) { v.X = (Real32)x;
|
||||||
|
BlockID block = World_GetPhysicsBlock(x, y, z);
|
||||||
|
Vector3_Add(&blockBB.Min, &v, &Block_MinBB[block]);
|
||||||
|
Vector3_Add(&blockBB.Max, &v, &Block_MaxBB[block]);
|
||||||
|
|
||||||
|
if (!AABB_Intersects(&blockBB, adjFinalBB)) continue;
|
||||||
|
if (Block_Collide[block] == COLLIDE_SOLID) return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Collisions_DidSlide(CollisionsComp* comp, AABB* blockBB, Vector3* size, AABB* finalBB, AABB* entityBB, AABB* extentBB) {
|
||||||
|
Real32 yDist = blockBB->Max.Y - entityBB->Min.Y;
|
||||||
|
if (yDist > 0.0f && yDist <= comp->Entity->StepSize + 0.01f) {
|
||||||
|
Real32 blockBB_MinX = max(blockBB->Min.X, blockBB->Max.X - size->X / 2);
|
||||||
|
Real32 blockBB_MaxX = min(blockBB->Max.X, blockBB->Min.X + size->X / 2);
|
||||||
|
Real32 blockBB_MinZ = max(blockBB->Min.Z, blockBB->Max.Z - size->Z / 2);
|
||||||
|
Real32 blockBB_MaxZ = min(blockBB->Max.Z, blockBB->Min.Z + size->Z / 2);
|
||||||
|
|
||||||
|
AABB adjBB;
|
||||||
|
adjBB.Min.X = min(finalBB->Min.X, blockBB_MinX + COLLISIONS_ADJ);
|
||||||
|
adjBB.Max.X = max(finalBB->Max.X, blockBB_MaxX - COLLISIONS_ADJ);
|
||||||
|
adjBB.Min.Y = blockBB->Max.Y + COLLISIONS_ADJ;
|
||||||
|
adjBB.Max.Y = adjBB.Min.Y + size->Y;
|
||||||
|
adjBB.Min.Z = min(finalBB->Min.Z, blockBB_MinZ + COLLISIONS_ADJ);
|
||||||
|
adjBB.Max.Z = max(finalBB->Max.Z, blockBB_MaxZ - COLLISIONS_ADJ);
|
||||||
|
|
||||||
|
if (!Collisions_CanSlideThrough(&adjBB)) return false;
|
||||||
|
comp->Entity->Position.Y = adjBB.Min.Y;
|
||||||
|
comp->Entity->OnGround = true;
|
||||||
|
Collisions_ClipY(comp->Entity, size, entityBB, extentBB);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Collisions_ClipXMin(CollisionsComp* comp, AABB* blockBB, AABB* entityBB, bool wasOn, AABB* finalBB, AABB* extentBB, Vector3* size) {
|
||||||
|
if (!wasOn || !Collisions_DidSlide(comp, blockBB, size, finalBB, entityBB, extentBB)) {
|
||||||
|
comp->Entity->Position.X = blockBB->Min.X - size->X / 2 - COLLISIONS_ADJ;
|
||||||
|
Collisions_ClipX(comp->Entity, size, entityBB, extentBB);
|
||||||
|
comp->HitXMin = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Collisions_ClipXMax(CollisionsComp* comp, AABB* blockBB, AABB* entityBB, bool wasOn, AABB* finalBB, AABB* extentBB, Vector3* size) {
|
||||||
|
if (!wasOn || !Collisions_DidSlide(comp, blockBB, size, finalBB, entityBB, extentBB)) {
|
||||||
|
comp->Entity->Position.X = blockBB->Max.X + size->X / 2 + COLLISIONS_ADJ;
|
||||||
|
Collisions_ClipX(comp->Entity, size, entityBB, extentBB);
|
||||||
|
comp->HitXMax = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Collisions_ClipZMax(CollisionsComp* comp, AABB* blockBB, AABB* entityBB, bool wasOn, AABB* finalBB, AABB* extentBB, Vector3* size) {
|
||||||
|
if (!wasOn || !Collisions_DidSlide(comp, blockBB, size, finalBB, entityBB, extentBB)) {
|
||||||
|
comp->Entity->Position.Z = blockBB->Max.Z + size->Z / 2 + COLLISIONS_ADJ;
|
||||||
|
Collisions_ClipZ(comp->Entity, size, entityBB, extentBB);
|
||||||
|
comp->HitZMax = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Collisions_ClipZMin(CollisionsComp* comp, AABB* blockBB, AABB* entityBB, bool wasOn, AABB* finalBB, AABB* extentBB, Vector3* size) {
|
||||||
|
if (!wasOn || !Collisions_DidSlide(comp, blockBB, size, finalBB, entityBB, extentBB)) {
|
||||||
|
comp->Entity->Position.Z = blockBB->Min.Z - size->Z / 2 - COLLISIONS_ADJ;
|
||||||
|
Collisions_ClipZ(comp->Entity, size, entityBB, extentBB);
|
||||||
|
comp->HitZMin = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Collisions_ClipYMin(CollisionsComp* comp, AABB* blockBB, AABB* entityBB, AABB* extentBB, Vector3* size) {
|
||||||
|
comp->Entity->Position.Y = blockBB->Min.Y - size->Y - COLLISIONS_ADJ;
|
||||||
|
Collisions_ClipY(comp->Entity, size, entityBB, extentBB);
|
||||||
|
comp->HitYMin = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Collisions_ClipYMax(CollisionsComp* comp, AABB* blockBB, AABB* entityBB, AABB* extentBB, Vector3* size) {
|
||||||
|
comp->Entity->Position.Y = blockBB->Max.Y + COLLISIONS_ADJ;
|
||||||
|
comp->Entity->OnGround = true;
|
||||||
|
Collisions_ClipY(comp->Entity, size, entityBB, extentBB);
|
||||||
|
comp->HitYMax = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Collisions_CollideWithReachableBlocks(CollisionsComp* comp, UInt32 count, AABB* entityBB, AABB* extentBB) {
|
||||||
Entity* entity = comp->Entity;
|
Entity* entity = comp->Entity;
|
||||||
/* Reset collision detection states */
|
/* Reset collision detection states */
|
||||||
bool wasOn = entity->OnGround;
|
bool wasOn = entity->OnGround;
|
||||||
@ -712,7 +809,8 @@ void Collisions_CollideWithReachableBlocks(CollisionsComponent* comp, UInt32 cou
|
|||||||
Real32 tx, ty, tz;
|
Real32 tx, ty, tz;
|
||||||
Searcher_CalcTime(&entity->Velocity, entityBB, &blockBB, &tx, &ty, &tz);
|
Searcher_CalcTime(&entity->Velocity, entityBB, &blockBB, &tx, &ty, &tz);
|
||||||
if (tx > 1.0f || ty > 1.0f || tz > 1.0f) {
|
if (tx > 1.0f || ty > 1.0f || tz > 1.0f) {
|
||||||
Utils.LogDebug("t > 1 in physics calculation.. this shouldn't have happened.");
|
String warn = String_FromConst("t > 1 in physics calculation.. this shouldn't have happened.");
|
||||||
|
Platform_Log(&warn);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Calculate the location of the entity when it collides with this block */
|
/* Calculate the location of the entity when it collides with this block */
|
||||||
@ -722,148 +820,364 @@ void Collisions_CollideWithReachableBlocks(CollisionsComponent* comp, UInt32 cou
|
|||||||
Vector3_Add(&finalBB.Min, &entityBB->Min, &v);
|
Vector3_Add(&finalBB.Min, &entityBB->Min, &v);
|
||||||
Vector3_Add(&finalBB.Min, &entityBB->Max, &v);
|
Vector3_Add(&finalBB.Min, &entityBB->Max, &v);
|
||||||
|
|
||||||
// if we have hit the bottom of a block, we need to change the axis we test first.
|
/* if we have hit the bottom of a block, we need to change the axis we test first */
|
||||||
if (!hitYMin) {
|
if (!comp->HitYMin) {
|
||||||
if (finalBB.Min.Y + Adjustment >= blockBB.Max.Y) {
|
if (finalBB.Min.Y + COLLISIONS_ADJ >= blockBB.Max.Y) {
|
||||||
ClipYMax(&blockBB, entityBB, extentBB, size);
|
Collisions_ClipYMax(comp, &blockBB, entityBB, extentBB, &size);
|
||||||
} else if (finalBB.Max.Y - Adjustment <= blockBB.Min.Y) {
|
} else if (finalBB.Max.Y - COLLISIONS_ADJ <= blockBB.Min.Y) {
|
||||||
ClipYMin(&blockBB, entityBB, extentBB, size);
|
Collisions_ClipYMin(comp, &blockBB, entityBB, extentBB, &size);
|
||||||
} else if (finalBB.Min.X + Adjustment >= blockBB.Max.X) {
|
} else if (finalBB.Min.X + COLLISIONS_ADJ >= blockBB.Max.X) {
|
||||||
ClipXMax(&blockBB, entityBB, wasOn, finalBB, extentBB, size);
|
Collisions_ClipXMax(comp, &blockBB, entityBB, wasOn, &finalBB, extentBB, &size);
|
||||||
} else if (finalBB.Max.X - Adjustment <= blockBB.Min.X) {
|
} else if (finalBB.Max.X - COLLISIONS_ADJ <= blockBB.Min.X) {
|
||||||
ClipXMin(&blockBB, entityBB, wasOn, finalBB, extentBB, size);
|
Collisions_ClipXMin(comp, &blockBB, entityBB, wasOn, &finalBB, extentBB, &size);
|
||||||
} else if (finalBB.Min.Z + Adjustment >= blockBB.Max.Z) {
|
} else if (finalBB.Min.Z + COLLISIONS_ADJ >= blockBB.Max.Z) {
|
||||||
ClipZMax(&blockBB, entityBB, wasOn, finalBB, extentBB, size);
|
Collisions_ClipZMax(comp, &blockBB, entityBB, wasOn, &finalBB, extentBB, &size);
|
||||||
} else if (finalBB.Max.Z - Adjustment <= blockBB.Min.Z) {
|
} else if (finalBB.Max.Z - COLLISIONS_ADJ <= blockBB.Min.Z) {
|
||||||
ClipZMin(&blockBB, entityBB, wasOn, finalBB, extentBB, size);
|
Collisions_ClipZMin(comp, &blockBB, entityBB, wasOn, &finalBB, extentBB, &size);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if flying or falling, test the horizontal axes first.
|
/* if flying or falling, test the horizontal axes first */
|
||||||
if (finalBB.Min.X + Adjustment >= blockBB.Max.X) {
|
if (finalBB.Min.X + COLLISIONS_ADJ >= blockBB.Max.X) {
|
||||||
ClipXMax(&blockBB, entityBB, wasOn, finalBB, extentBB, size);
|
Collisions_ClipXMax(comp, &blockBB, entityBB, wasOn, &finalBB, extentBB, &size);
|
||||||
} else if (finalBB.Max.X - Adjustment <= blockBB.Min.X) {
|
} else if (finalBB.Max.X - COLLISIONS_ADJ <= blockBB.Min.X) {
|
||||||
ClipXMin(&blockBB, entityBB, wasOn, finalBB, extentBB, size);
|
Collisions_ClipXMin(comp, &blockBB, entityBB, wasOn, &finalBB, extentBB, &size);
|
||||||
} else if (finalBB.Min.Z + Adjustment >= blockBB.Max.Z) {
|
} else if (finalBB.Min.Z + COLLISIONS_ADJ >= blockBB.Max.Z) {
|
||||||
ClipZMax(&blockBB, entityBB, wasOn, finalBB, extentBB, size);
|
Collisions_ClipZMax(comp, &blockBB, entityBB, wasOn, &finalBB, extentBB, &size);
|
||||||
} else if (finalBB.Max.Z - Adjustment <= blockBB.Min.Z) {
|
} else if (finalBB.Max.Z - COLLISIONS_ADJ <= blockBB.Min.Z) {
|
||||||
ClipZMin(&blockBB, entityBB, wasOn, finalBB, extentBB, size);
|
Collisions_ClipZMin(comp, &blockBB, entityBB, wasOn, &finalBB, extentBB, &size);
|
||||||
} else if (finalBB.Min.Y + Adjustment >= blockBB.Max.Y) {
|
} else if (finalBB.Min.Y + COLLISIONS_ADJ >= blockBB.Max.Y) {
|
||||||
ClipYMax(&blockBB, entityBB, extentBB, size);
|
Collisions_ClipYMax(comp, &blockBB, entityBB, extentBB, &size);
|
||||||
} else if (finalBB.Max.Y - Adjustment <= blockBB.Min.Y) {
|
} else if (finalBB.Max.Y - COLLISIONS_ADJ <= blockBB.Min.Y) {
|
||||||
ClipYMin(&blockBB, entityBB, extentBB, size);
|
Collisions_ClipYMin(comp, &blockBB, entityBB, extentBB, &size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Collisions_ClipXMin(AABB* blockBB, AABB* entityBB, bool wasOn, AABB* finalBB, AABB* extentBB, Vector3* size) {
|
/* TODO: test for corner cases, and refactor this */
|
||||||
if (!wasOn || !DidSlide(blockBB, size, finalBB, entityBB, extentBB)) {
|
void Collisions_MoveAndWallSlide(CollisionsComp* comp) {
|
||||||
entity.Position.X = blockBB.Min.X - size.X / 2 - Adjustment;
|
Vector3 zero = Vector3_Zero;
|
||||||
ClipX(size, entityBB, extentBB);
|
Entity* entity = comp->Entity;
|
||||||
hitXMin = true;
|
if (Vector3_Equals(&entity->Velocity, &zero)) return;
|
||||||
|
|
||||||
|
AABB entityBB, entityExtentBB;
|
||||||
|
UInt32 count = Searcher_FindReachableBlocks(entity, &entityBB, &entityExtentBB);
|
||||||
|
Collisions_CollideWithReachableBlocks(comp, count, &entityBB, &entityExtentBB);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*########################################################################################################################*
|
||||||
|
*----------------------------------------------------PhysicsComponent-----------------------------------------------------*
|
||||||
|
*#########################################################################################################################*/
|
||||||
|
void PhysicsComp_Init(PhysicsComp* comp, Entity* entity) {
|
||||||
|
Platform_MemSet(comp, 0, sizeof(PhysicsComp));
|
||||||
|
comp->CanLiquidJump = true;
|
||||||
|
comp->Entity = entity;
|
||||||
|
comp->JumpVel = 0.42f;
|
||||||
|
comp->UserJumpVel = 0.42f;
|
||||||
|
comp->ServerJumpVel = 0.42f;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PhysicsComp_TouchesLiquid(BlockID block) { return Block_Collide[block] == COLLIDE_LIQUID; }
|
||||||
|
void PhysicsComp_UpdateVelocityState(PhysicsComp* comp) {
|
||||||
|
Entity* entity = comp->Entity;
|
||||||
|
HacksComp* hacks = comp->Hacks;
|
||||||
|
|
||||||
|
if (hacks->Floating) {
|
||||||
|
entity->Velocity.Y = 0.0f; /* eliminate the effect of gravity */
|
||||||
|
Int32 dir = (hacks->FlyingUp || comp->Jumping) ? 1 : (hacks->FlyingDown ? -1 : 0);
|
||||||
|
|
||||||
|
entity->Velocity.Y += 0.12f * dir;
|
||||||
|
if (hacks->Speeding && hacks->CanSpeed) entity->Velocity.Y += 0.12f * dir;
|
||||||
|
if (hacks->HalfSpeeding && hacks->CanSpeed) entity->Velocity.Y += 0.06f * dir;
|
||||||
|
} else if (comp->Jumping && Entity_TouchesAnyRope(entity) && entity->Velocity.Y > 0.02f) {
|
||||||
|
entity->Velocity.Y = 0.02f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!comp->Jumping) {
|
||||||
|
comp->CanLiquidJump = false; return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool touchWater = Entity_TouchesAnyWater(entity);
|
||||||
|
bool touchLava = Entity_TouchesAnyLava(entity);
|
||||||
|
if (touchWater || touchLava) {
|
||||||
|
AABB bounds; Entity_GetBounds(entity, &bounds);
|
||||||
|
Int32 feetY = Math_Floor(bounds.Min.Y), bodyY = feetY + 1;
|
||||||
|
Int32 headY = Math_Floor(bounds.Max.Y);
|
||||||
|
if (bodyY > headY) bodyY = headY;
|
||||||
|
|
||||||
|
bounds.Max.Y = bounds.Min.Y = feetY;
|
||||||
|
bool liquidFeet = Entity_TouchesAny(&bounds, PhysicsComp_TouchesLiquid);
|
||||||
|
bounds.Min.Y = min(bodyY, headY);
|
||||||
|
bounds.Max.Y = max(bodyY, headY);
|
||||||
|
bool liquidRest = Entity_TouchesAny(&bounds, PhysicsComp_TouchesLiquid);
|
||||||
|
|
||||||
|
bool pastJumpPoint = liquidFeet && !liquidRest && (Math_ModF(entity->Position.Y, 1.0f) >= 0.4f);
|
||||||
|
if (!pastJumpPoint) {
|
||||||
|
comp->CanLiquidJump = true;
|
||||||
|
entity->Velocity.Y += 0.04f;
|
||||||
|
if (hacks->Speeding && hacks->CanSpeed) entity->Velocity.Y += 0.04f;
|
||||||
|
if (hacks->HalfSpeeding && hacks->CanSpeed) entity->Velocity.Y += 0.02f;
|
||||||
|
} else if (pastJumpPoint) {
|
||||||
|
/* either A) climb up solid on side B) jump bob in water */
|
||||||
|
if (Collisions_HitHorizontal(comp->Collisions)) {
|
||||||
|
entity->Velocity.Y += touchLava ? 0.30f : 0.13f;
|
||||||
|
} else if (comp->CanLiquidJump) {
|
||||||
|
entity->Velocity.Y += touchLava ? 0.20f : 0.10f;
|
||||||
|
}
|
||||||
|
comp->CanLiquidJump = false;
|
||||||
|
}
|
||||||
|
} else if (comp->UseLiquidGravity) {
|
||||||
|
entity->Velocity.Y += 0.04f;
|
||||||
|
if (hacks->Speeding && hacks->CanSpeed) entity->Velocity.Y += 0.04f;
|
||||||
|
if (hacks->HalfSpeeding && hacks->CanSpeed) entity->Velocity.Y += 0.02f;
|
||||||
|
comp->CanLiquidJump = false;
|
||||||
|
} else if (Entity_TouchesAnyRope(entity)) {
|
||||||
|
entity->Velocity.Y += (hacks->Speeding && hacks->CanSpeed) ? 0.15f : 0.10f;
|
||||||
|
comp->CanLiquidJump = false;
|
||||||
|
} else if (entity->OnGround) {
|
||||||
|
PhysicsComp_DoNormalJump(comp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Collisions_ClipXMax(AABB* blockBB, AABB* entityBB, bool wasOn, AABB* finalBB, AABB* extentBB, Vector3* size) {
|
void PhysicsComp_DoNormalJump(PhysicsComp* comp) {
|
||||||
if (!wasOn || !DidSlide(blockBB, size, finalBB, entityBB, extentBB)) {
|
Entity* entity = comp->Entity;
|
||||||
entity.Position.X = blockBB.Max.X + size.X / 2 + Adjustment;
|
HacksComp* hacks = comp->Hacks;
|
||||||
ClipX(size, entityBB, extentBB);
|
if (comp->JumpVel == 0.0f || hacks->MaxJumps == 0) return;
|
||||||
hitXMax = true;
|
|
||||||
|
entity->Velocity.Y = comp->JumpVel;
|
||||||
|
if (hacks->Speeding && hacks->CanSpeed) entity->Velocity.Y += comp->JumpVel;
|
||||||
|
if (hacks->HalfSpeeding && hacks->CanSpeed) entity->Velocity.Y += comp->JumpVel / 2;
|
||||||
|
comp->CanLiquidJump = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PhysicsComp_TouchesSlipperyIce(BlockID b) { return Block_ExtendedCollide[b] == COLLIDE_SLIPPERY_ICE; }
|
||||||
|
bool PhysicsComp_OnIce(Entity* entity) {
|
||||||
|
Vector3 under = entity->Position; under.Y -= 0.01f;
|
||||||
|
Vector3I underCoords; Vector3I_Floor(&underCoords, &under);
|
||||||
|
BlockID blockUnder = World_SafeGetBlock_3I(underCoords);
|
||||||
|
if (Block_ExtendedCollide[blockUnder] == COLLIDE_ICE) return true;
|
||||||
|
|
||||||
|
AABB bounds; Entity_GetBounds(entity, &bounds);
|
||||||
|
bounds.Min.Y -= 0.01f; bounds.Max.Y = bounds.Min.Y;
|
||||||
|
return Entity_TouchesAny(&bounds, PhysicsComp_TouchesSlipperyIce);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PhysicsComp_MoveHor(PhysicsComp* comp, Vector3 vel, Real32 factor) {
|
||||||
|
Real32 dist = Math_SqrtF(vel.X * vel.X + vel.Z * vel.Z);
|
||||||
|
if (dist < 0.00001f) return;
|
||||||
|
if (dist < 1.0f) dist = 1.0f;
|
||||||
|
|
||||||
|
/* entity.Velocity += vel * (factor / dist) */
|
||||||
|
Entity* entity = comp->Entity;
|
||||||
|
Vector3_Mul1By(&vel, factor / dist);
|
||||||
|
Vector3_AddBy(&entity->Velocity, &vel);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PhysicsComp_Move(PhysicsComp* comp, Vector3 drag, Real32 gravity, Real32 yMul) {
|
||||||
|
Entity* entity = comp->Entity;
|
||||||
|
entity->Velocity.Y *= yMul;
|
||||||
|
if (!comp->Hacks->Noclip) {
|
||||||
|
Collisions_MoveAndWallSlide(comp->Collisions);
|
||||||
}
|
}
|
||||||
|
Vector3_AddBy(&entity->Position, &entity->Velocity);
|
||||||
|
|
||||||
|
entity->Velocity.Y /= yMul;
|
||||||
|
Vector3_Mul3By(&entity->Velocity, &drag);
|
||||||
|
entity->Velocity.Y -= gravity;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Collisions_ClipZMax(AABB* blockBB, AABB* entityBB, bool wasOn, AABB* finalBB, AABB* extentBB, Vector3* size) {
|
void PhysicsComp_MoveFlying(PhysicsComp* comp, Vector3 vel, Real32 factor, Vector3 drag, Real32 gravity, Real32 yMul) {
|
||||||
if (!wasOn || !DidSlide(blockBB, size, finalBB, entityBB, extentBB)) {
|
Entity* entity = comp->Entity;
|
||||||
entity.Position.Z = blockBB.Max.Z + size.Z / 2 + Adjustment;
|
HacksComp* hacks = comp->Hacks;
|
||||||
ClipZ(size, entityBB, extentBB);
|
|
||||||
hitZMax = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Collisions_ClipZMin(AABB* blockBB, AABB* entityBB, bool wasOn, AABB* finalBB, AABB* extentBB, Vector3* size) {
|
PhysicsComp_MoveHor(comp, vel, factor);
|
||||||
if (!wasOn || !DidSlide(blockBB, size, finalBB, entityBB, extentBB)) {
|
Real32 yVel = Math_SqrtF(entity->Velocity.X * entity->Velocity.X + entity->Velocity.Z * entity->Velocity.Z);
|
||||||
entity.Position.Z = blockBB.Min.Z - size.Z / 2 - Adjustment;
|
/* make horizontal speed the same as vertical speed */
|
||||||
ClipZ(size, entityBB, extentBB);
|
if ((vel.X != 0.0f || vel.Z != 0.0f) && yVel > 0.001f) {
|
||||||
hitZMin = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Collisions_ClipYMin(AABB* blockBB, AABB* entityBB, AABB* extentBB, Vector3* size) {
|
|
||||||
entity.Position.Y = blockBB.Min.Y - size.Y - Adjustment;
|
|
||||||
ClipY(size, entityBB, ref extentBB);
|
|
||||||
hitYMin = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Collisions_ClipYMax(AABB* blockBB, AABB* entityBB, AABB* extentBB, Vector3* size) {
|
|
||||||
entity.Position.Y = blockBB.Max.Y + Adjustment;
|
|
||||||
entity.onGround = true;
|
|
||||||
ClipY(size, entityBB, ref extentBB);
|
|
||||||
hitYMax = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Collisions_DidSlide(AABB blockBB, Vector3* size, AABB* finalBB, AABB* entityBB, AABB* extentBB) {
|
|
||||||
Real32 yDist = blockBB.Max.Y - entityBB.Min.Y;
|
|
||||||
if (yDist > 0 && yDist <= entity.StepSize + 0.01f) {
|
|
||||||
float blockXMin = blockBB.Min.X, blockZMin = blockBB.Min.Z;
|
|
||||||
blockBB.Min.X = Math.Max(blockBB.Min.X, blockBB.Max.X - size.X / 2);
|
|
||||||
blockBB.Max.X = Math.Min(blockBB.Max.X, blockXMin + size.X / 2);
|
|
||||||
blockBB.Min.Z = Math.Max(blockBB.Min.Z, blockBB.Max.Z - size.Z / 2);
|
|
||||||
blockBB.Max.Z = Math.Min(blockBB.Max.Z, blockZMin + size.Z / 2);
|
|
||||||
|
|
||||||
AABB adjBB;
|
|
||||||
adjBB.Min.X = min(finalBB->Min.X, blockBB.Min.X + Adjustment);
|
|
||||||
adjBB.Max.X = max(finalBB->Max.X, blockBB.Max.X - Adjustment);
|
|
||||||
adjBB.Min.Y = blockBB.Max.Y + Adjustment;
|
|
||||||
adjBB.Max.Y = adjBB.Min.Y + size->Y;
|
|
||||||
adjBB.Min.Z = min(finalBB->Min.Z, blockBB.Min.Z + Adjustment);
|
|
||||||
adjBB.Max.Z = max(finalBB->Max.Z, blockBB.Max.Z - Adjustment);
|
|
||||||
|
|
||||||
if (!Collisions_CanSlideThrough(&adjBB)) return false;
|
|
||||||
|
|
||||||
entity.Position.Y = blockBB.Max.Y + Adjustment;
|
|
||||||
entity.onGround = true;
|
|
||||||
ClipY(size, entityBB, extentBB);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Collisions_CanSlideThrough(AABB* adjFinalBB) {
|
|
||||||
Vector3I bbMin; Vector3I_Floor(&bbMin, &adjFinalBB->Min);
|
|
||||||
Vector3I bbMax; Vector3I_Floor(&bbMax, &adjFinalBB->Max);
|
|
||||||
AABB blockBB;
|
|
||||||
Int32 x, y, z;
|
|
||||||
|
|
||||||
for (y = bbMin.Y; y <= bbMax.Y; y++) {
|
|
||||||
for (z = bbMin.Z; z <= bbMax.Z; z++) {
|
|
||||||
for (x = bbMin.X; x <= bbMax.X; x++) {
|
|
||||||
BlockID block = World_GetPhysicsBlock(x, y, z);
|
|
||||||
blockBB.Min = new Vector3(x, y, z) + Block_MinBB[block];
|
|
||||||
blockBB.Max = new Vector3(x, y, z) + Block_MaxBB[block];
|
|
||||||
|
|
||||||
if (!AABB_Intersects(&blockBB, adjFinalBB)) continue;
|
|
||||||
if (Block_Collide[block] == COLLIDE_SOLID) return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Collisions_ClipX(Entity* entity, Vector3* size, AABB* entityBB, AABB* extentBB) {
|
|
||||||
entity->Velocity.X = 0.0f;
|
|
||||||
entityBB->Min.X = entity->Position.X - size->X / 2; extentBB->Min.X = entityBB->Min.X;
|
|
||||||
entityBB->Max.X = entity->Position.X + size->X / 2; extentBB->Max.X = entityBB->Max.X;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Collisions_ClipY(Entity* entity, Vector3* size, AABB* entityBB, AABB* extentBB) {
|
|
||||||
entity->Velocity.Y = 0.0f;
|
entity->Velocity.Y = 0.0f;
|
||||||
entityBB->Min.Y = entity->Position.Y; extentBB->Min.Y = entityBB->Min.Y;
|
yMul = 1.0f;
|
||||||
entityBB->Max.Y = entity->Position.Y + size->Y; extentBB->Max.Y = entityBB->Max.Y;
|
if (hacks->FlyingUp || comp->Jumping) entity->Velocity.Y += yVel;
|
||||||
|
if (hacks->FlyingDown) entity->Velocity.Y -= yVel;
|
||||||
|
}
|
||||||
|
PhysicsComp_Move(comp, drag, gravity, yMul);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Collisions_ClipZ(Entity* entity, Vector3* size, AABB* entityBB, AABB* extentBB) {
|
void PhysicsComp_MoveNormal(PhysicsComp* comp, Vector3 vel, Real32 factor, Vector3 drag, Real32 gravity, Real32 yMul) {
|
||||||
entity->Velocity.Z = 0.0f;
|
PhysicsComp_MoveHor(comp, vel, factor);
|
||||||
entityBB->Min.Z = entity->Position.Z - size->Z / 2; extentBB->Min.Z = entityBB->Min.Z;
|
PhysicsComp_Move(comp, drag, gravity, yMul);
|
||||||
entityBB->Max.Z = entity->Position.Z + size->Z / 2; extentBB->Max.Z = entityBB->Max.Z;
|
}
|
||||||
|
|
||||||
|
Real32 PhysicsComp_LowestModifier(PhysicsComp* comp, AABB* bounds, bool checkSolid) {
|
||||||
|
Vector3I bbMin, bbMax;
|
||||||
|
Vector3I_Floor(&bbMin, &bounds->Min);
|
||||||
|
Vector3I_Floor(&bbMax, &bounds->Max);
|
||||||
|
Real32 modifier = MATH_POS_INF;
|
||||||
|
|
||||||
|
bbMin.X = max(bbMin.X, 0); bbMax.X = min(bbMax.X, World_MaxX);
|
||||||
|
bbMin.Y = max(bbMin.Y, 0); bbMax.Y = min(bbMax.Y, World_MaxY);
|
||||||
|
bbMin.Z = max(bbMin.Z, 0); bbMax.Z = min(bbMax.Z, World_MaxZ);
|
||||||
|
|
||||||
|
AABB blockBB;
|
||||||
|
Vector3 v;
|
||||||
|
Int32 x, y, z;
|
||||||
|
for (y = bbMin.Y; y <= bbMax.Y; y++) { v.Y = (Real32)y;
|
||||||
|
for (z = bbMin.Z; z <= bbMax.Z; z++) { v.Z = (Real32)z;
|
||||||
|
for (x = bbMin.X; x <= bbMax.X; x++) { v.X = (Real32)x;
|
||||||
|
BlockID block = World_GetBlock(x, y, z);
|
||||||
|
if (block == BLOCK_AIR) continue;
|
||||||
|
UInt8 collide = Block_Collide[block];
|
||||||
|
if (collide == COLLIDE_SOLID && !checkSolid) continue;
|
||||||
|
|
||||||
|
Vector3_Add(&blockBB.Min, &v, &Block_MinBB[block]);
|
||||||
|
Vector3_Add(&blockBB.Max, &v, &Block_MaxBB[block]);
|
||||||
|
if (!AABB_Intersects(&blockBB, bounds)) continue;
|
||||||
|
|
||||||
|
modifier = min(modifier, Block_SpeedMultiplier[block]);
|
||||||
|
if (Block_ExtendedCollide[block] == COLLIDE_LIQUID) {
|
||||||
|
comp->UseLiquidGravity = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return modifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
Real32 PhysicsComp_GetSpeed(HacksComp* hacks, Real32 speedMul) {
|
||||||
|
Real32 factor = hacks->Floating ? speedMul : 1.0f, speed = factor;
|
||||||
|
if (hacks->Speeding && hacks->CanSpeed) speed += factor * hacks->SpeedMultiplier;
|
||||||
|
if (hacks->HalfSpeeding && hacks->CanSpeed) speed += factor * hacks->SpeedMultiplier / 2;
|
||||||
|
return hacks->CanSpeed ? speed : min(speed, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
Real32 PhysicsComp_GetBaseSpeed(PhysicsComp* comp) {
|
||||||
|
AABB bounds; Entity_GetBounds(comp->Entity, &bounds);
|
||||||
|
comp->UseLiquidGravity = false;
|
||||||
|
Real32 baseModifier = PhysicsComp_LowestModifier(comp, &bounds, false);
|
||||||
|
bounds.Min.Y -= 0.5f / 16.0f; /* also check block standing on */
|
||||||
|
Real32 solidModifier = PhysicsComp_LowestModifier(comp, &bounds, true);
|
||||||
|
|
||||||
|
if (baseModifier == MATH_POS_INF && solidModifier == MATH_POS_INF) return 1.0f;
|
||||||
|
return baseModifier == MATH_POS_INF ? solidModifier : baseModifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define LIQUID_GRAVITY 0.02f
|
||||||
|
#define ROPE_GRAVITY 0.034f
|
||||||
|
void PhysicsComp_PhysicsTick(PhysicsComp* comp, Vector3 vel) {
|
||||||
|
Entity* entity = comp->Entity;
|
||||||
|
HacksComp* hacks = comp->Hacks;
|
||||||
|
|
||||||
|
if (hacks->Noclip) entity->OnGround = false;
|
||||||
|
Real32 baseSpeed = PhysicsComp_GetBaseSpeed(comp);
|
||||||
|
Real32 verSpeed = baseSpeed * (PhysicsComp_GetSpeed(hacks, 8.0f) / 5.0f);
|
||||||
|
Real32 horSpeed = baseSpeed * PhysicsComp_GetSpeed(hacks, 8.0f / 5.0f) * hacks->BaseHorSpeed;
|
||||||
|
/* previously horSpeed used to be multiplied by factor of 0.02 in last case */
|
||||||
|
/* it's now multiplied by 0.1, so need to divide by 5 so user speed modifier comes out same */
|
||||||
|
|
||||||
|
/* TODO: this is a temp fix to avoid crashing for high horizontal speed */
|
||||||
|
if (horSpeed > 75.0f) horSpeed = 75.0f;
|
||||||
|
/* vertical speed never goes below: base speed * 1.0 */
|
||||||
|
if (verSpeed < baseSpeed) verSpeed = baseSpeed;
|
||||||
|
|
||||||
|
bool womSpeedBoost = hacks->CanDoubleJump && hacks->WOMStyleHacks;
|
||||||
|
if (!hacks->Floating && womSpeedBoost) {
|
||||||
|
if (comp->MultiJumps == 1) { horSpeed *= 46.5f; verSpeed *= 7.5f; }
|
||||||
|
else if (comp->MultiJumps > 1) { horSpeed *= 93.0f; verSpeed *= 10.0f; }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Entity_TouchesAnyWater(entity) && !hacks->Floating) {
|
||||||
|
Vector3 waterDrag = VECTOR3_CONST(0.8f, 0.8f, 0.8f);
|
||||||
|
PhysicsComp_MoveNormal(comp, vel, 0.02f * horSpeed, waterDrag, LIQUID_GRAVITY, verSpeed);
|
||||||
|
} else if (Entity_TouchesAnyLava(entity) && !hacks->Floating) {
|
||||||
|
Vector3 lavaDrag = VECTOR3_CONST(0.5f, 0.5f, 0.5f);
|
||||||
|
PhysicsComp_MoveNormal(comp, vel, 0.02f * horSpeed, lavaDrag, LIQUID_GRAVITY, verSpeed);
|
||||||
|
} else if (Entity_TouchesAnyRope(entity) && !hacks->Floating) {
|
||||||
|
Vector3 ropeDrag = VECTOR3_CONST(0.5f, 0.85f, 0.5f);
|
||||||
|
PhysicsComp_MoveNormal(comp, vel, 0.02f * 1.7f, ropeDrag, ROPE_GRAVITY, verSpeed);
|
||||||
|
} else {
|
||||||
|
Real32 factor = hacks->Floating || entity->OnGround ? 0.1f : 0.02f;
|
||||||
|
Real32 gravity = comp->UseLiquidGravity ? LIQUID_GRAVITY : entity->Model->Gravity;
|
||||||
|
|
||||||
|
if (hacks->Floating) {
|
||||||
|
PhysicsComp_MoveFlying(comp, vel, factor * horSpeed, entity->Model->Drag, gravity, verSpeed);
|
||||||
|
} else {
|
||||||
|
PhysicsComp_MoveNormal(comp, vel, factor * horSpeed, entity->Model->Drag, gravity, verSpeed);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PhysicsComp_OnIce(entity) && !hacks->Floating) {
|
||||||
|
/* limit components to +-0.25f by rescaling vector to [-0.25, 0.25] */
|
||||||
|
if (Math_AbsF(entity->Velocity.X) > 0.25f || Math_AbsF(entity->Velocity.Z) > 0.25f) {
|
||||||
|
Real32 xScale = Math_AbsF(0.25f / entity->Velocity.X);
|
||||||
|
Real32 zScale = Math_AbsF(0.25f / entity->Velocity.Z);
|
||||||
|
|
||||||
|
Real32 scale = min(xScale, zScale);
|
||||||
|
entity->Velocity.X *= scale;
|
||||||
|
entity->Velocity.Z *= scale;
|
||||||
|
}
|
||||||
|
} else if (entity->OnGround || hacks->Flying) {
|
||||||
|
Vector3_Mul3By(&entity->Velocity, &entity->Model->GroundFriction); /* air drag or ground friction */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entity->OnGround) comp->MultiJumps = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Real64 PhysicsComp_YPosAt(Int32 t, Real32 u) {
|
||||||
|
/* v(t, u) = (4 + u) * (0.98^t) - 4, where u = initial velocity */
|
||||||
|
/* x(t, u) = Σv(t, u) from 0 to t (since we work in discrete timesteps) */
|
||||||
|
/* plugging into Wolfram Alpha gives 1 equation as */
|
||||||
|
/* (0.98^t) * (-49u - 196) - 4t + 50u + 196 */
|
||||||
|
Real64 a = Math_Exp(-0.0202027 * t); /* ~0.98^t */
|
||||||
|
return a * (-49 * u - 196) - 4 * t + 50 * u + 196;
|
||||||
|
}
|
||||||
|
|
||||||
|
Real64 PhysicsComp_GetMaxHeight(Real32 u) {
|
||||||
|
/* equation below comes from solving diff(x(t, u))= 0 */
|
||||||
|
/* We only work in discrete timesteps, so test both rounded up and down */
|
||||||
|
Real64 t = 49.49831645 * Math_Log(0.247483075 * u + 0.9899323);
|
||||||
|
Real64 value_floor = PhysicsComp_YPosAt((Int32)t, u);
|
||||||
|
Real64 value_ceil = PhysicsComp_YPosAt((Int32)t + 1, u);
|
||||||
|
return max(value_floor, value_ceil);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Calculates the jump velocity required such that when a client presses
|
||||||
|
the jump binding they will be able to jump up to the given height. */
|
||||||
|
void PhysicsComp_CalculateJumpVelocity(PhysicsComp* comp, bool userVel, Real32 jumpHeight) {
|
||||||
|
comp->JumpVel = 0.0f;
|
||||||
|
if (jumpHeight == 0.0f) return;
|
||||||
|
|
||||||
|
if (jumpHeight >= 256.0f) comp->JumpVel = 10.0f;
|
||||||
|
if (jumpHeight >= 512.0f) comp->JumpVel = 16.5f;
|
||||||
|
if (jumpHeight >= 768.0f) comp->JumpVel = 22.5f;
|
||||||
|
|
||||||
|
while (PhysicsComp_GetMaxHeight(comp->JumpVel) <= jumpHeight) { comp->JumpVel += 0.001f; }
|
||||||
|
if (userVel) comp->UserJumpVel = comp->JumpVel;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PhysicsComp_DoEntityPush(Entity* entity) {
|
||||||
|
Int32 id;
|
||||||
|
Vector3 dir; dir.Y = 0.0f;
|
||||||
|
|
||||||
|
for (id = 0; id < ENTITIES_MAX_COUNT; id++) {
|
||||||
|
Entity* other = Entities_List[id];
|
||||||
|
if (other == NULL || other == entity) continue;
|
||||||
|
if (!other->Model->Pushes) continue;
|
||||||
|
|
||||||
|
bool yIntersects =
|
||||||
|
entity->Position.Y <= (other->Position.Y + other->Size.Y) &&
|
||||||
|
other->Position.Y <= (entity->Position.Y + entity->Size.Y);
|
||||||
|
if (!yIntersects) continue;
|
||||||
|
|
||||||
|
dir.X = other->Position.X - entity->Position.X;
|
||||||
|
dir.Z = other->Position.Z - entity->Position.Z;
|
||||||
|
Real32 dist = dir.X * dir.X + dir.Z * dir.Z;
|
||||||
|
if (dist < 0.002f || dist > 1.0f) continue; /* TODO: range needs to be lower? */
|
||||||
|
|
||||||
|
Vector3_Normalize(&dir, &dir);
|
||||||
|
Real32 pushStrength = (1 - dist) / 32.0f; /* TODO: should be 24/25 */
|
||||||
|
/* entity.Velocity -= dir * pushStrength */
|
||||||
|
Vector3_Mul1By(&dir, pushStrength);
|
||||||
|
Vector3_SubBy(&entity->Velocity, &dir);
|
||||||
|
}
|
||||||
}
|
}
|
@ -9,7 +9,7 @@
|
|||||||
typedef struct Entity_ Entity;
|
typedef struct Entity_ Entity;
|
||||||
typedef struct LocationUpdate_ LocationUpdate;
|
typedef struct LocationUpdate_ LocationUpdate;
|
||||||
|
|
||||||
/* Entity component that performs model animation depending on movement speed and time. */
|
/* Entity component that performs model animation depending on movement speed and time */
|
||||||
typedef struct AnimatedComp_ {
|
typedef struct AnimatedComp_ {
|
||||||
Real32 BobbingHor, BobbingVer, BobbingModel;
|
Real32 BobbingHor, BobbingVer, BobbingModel;
|
||||||
Real32 WalkTime, Swing, BobStrength;
|
Real32 WalkTime, Swing, BobStrength;
|
||||||
@ -23,7 +23,7 @@ void AnimatedComp_Init(AnimatedComp* anim);
|
|||||||
void AnimatedComp_Update(AnimatedComp* anim, Vector3 oldPos, Vector3 newPos, Real64 delta, bool onGround);
|
void AnimatedComp_Update(AnimatedComp* anim, Vector3 oldPos, Vector3 newPos, Real64 delta, bool onGround);
|
||||||
void AnimatedComp_GetCurrent(AnimatedComp* anim, Real32 t, bool calcHumanAnims);
|
void AnimatedComp_GetCurrent(AnimatedComp* anim, Real32 t, bool calcHumanAnims);
|
||||||
|
|
||||||
/* Entity component that performs tilt animation depending on movement speed and time. */
|
/* Entity component that performs tilt animation depending on movement speed and time */
|
||||||
typedef struct TiltComp_ {
|
typedef struct TiltComp_ {
|
||||||
Real32 TiltX, TiltY, VelTiltStrength;
|
Real32 TiltX, TiltY, VelTiltStrength;
|
||||||
Real32 VelTiltStrengthO, VelTiltStrengthN;
|
Real32 VelTiltStrengthO, VelTiltStrengthN;
|
||||||
@ -33,33 +33,34 @@ void TiltComp_Init(TiltComp* anim);
|
|||||||
void TiltComp_Update(TiltComp* anim, Real64 delta);
|
void TiltComp_Update(TiltComp* anim, Real64 delta);
|
||||||
void TiltComp_GetCurrent(TiltComp* anim, Real32 t);
|
void TiltComp_GetCurrent(TiltComp* anim, Real32 t);
|
||||||
|
|
||||||
/* Entity component that performs management of hack states. */
|
/* Entity component that performs management of hack states */
|
||||||
typedef struct HacksComponent_ {
|
typedef struct HacksComponent_ {
|
||||||
UInt8 UserType;
|
UInt8 UserType;
|
||||||
/* Speed player move at, relative to normal speed, when the 'speeding' key binding is held down. */
|
/* Speed player move at, relative to normal speed, when the 'speeding' key binding is held down */
|
||||||
Real32 SpeedMultiplier;
|
Real32 SpeedMultiplier;
|
||||||
/* Whether blocks that the player places that intersect themselves, should cause the player to
|
/* 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. */
|
be pushed back in the opposite direction of the placed block */
|
||||||
bool PushbackPlacing;
|
bool PushbackPlacing;
|
||||||
/* Whether the player should be able to step up whole blocks, instead of just slabs. */
|
/* Whether the player should be able to step up whole blocks, instead of just slabs */
|
||||||
bool FullBlockStep;
|
bool FullBlockStep;
|
||||||
/* Whether the player has allowed hacks usage as an option. Note 'can use X' set by the server override this. */
|
/* Whether the player has allowed hacks usage as an option. Note 'can use X' set by the server override this */
|
||||||
bool Enabled;
|
bool Enabled;
|
||||||
|
|
||||||
bool CanAnyHacks, CanUseThirdPersonCamera, CanSpeed, CanFly;
|
bool CanAnyHacks, CanUseThirdPersonCamera, CanSpeed, CanFly;
|
||||||
bool CanRespawn, CanNoclip, CanPushbackBlocks,CanSeeAllNames;
|
bool CanRespawn, CanNoclip, CanPushbackBlocks,CanSeeAllNames;
|
||||||
bool CanDoubleJump, CanBePushed;
|
bool CanDoubleJump, CanBePushed;
|
||||||
/* Maximum speed the entity can move at horizontally when CanSpeed is false. */
|
/* Maximum speed the entity can move at horizontally when CanSpeed is false */
|
||||||
Real32 BaseHorSpeed;
|
Real32 BaseHorSpeed;
|
||||||
/* Max amount of jumps the player can perform. */
|
/* Max amount of jumps the player can perform */
|
||||||
Int32 MaxJumps;
|
Int32 MaxJumps;
|
||||||
|
|
||||||
/* Whether the player should slide after letting go of movement buttons in noclip. */
|
/* Whether the player should slide after letting go of movement buttons in noclip */
|
||||||
bool NoclipSlide;
|
bool NoclipSlide;
|
||||||
/* Whether the player has allowed the usage of fast double jumping abilities. */
|
/* Whether the player has allowed the usage of fast double jumping abilities */
|
||||||
bool WOMStyleHacks;
|
bool WOMStyleHacks;
|
||||||
|
|
||||||
bool Noclip, Flying,FlyingUp, FlyingDown, Speeding, HalfSpeeding;
|
bool Noclip, Flying, FlyingUp, FlyingDown, Speeding, HalfSpeeding;
|
||||||
|
bool Floating; /* true if NoClip or Flying */
|
||||||
UInt8 HacksFlagsBuffer[String_BufferSize(128)];
|
UInt8 HacksFlagsBuffer[String_BufferSize(128)];
|
||||||
String HacksFlags;
|
String HacksFlags;
|
||||||
} HacksComp;
|
} HacksComp;
|
||||||
@ -71,13 +72,13 @@ void HacksComp_SetUserType(HacksComp* hacks, UInt8 value, bool setBlockPerms);
|
|||||||
void HacksComp_CheckConsistency(HacksComp* hacks);
|
void HacksComp_CheckConsistency(HacksComp* hacks);
|
||||||
void HacksComp_UpdateState(HacksComp* hacks);
|
void HacksComp_UpdateState(HacksComp* hacks);
|
||||||
|
|
||||||
/* Represents a position and orientation state. */
|
/* Represents a position and orientation state */
|
||||||
typedef struct InterpState_ {
|
typedef struct InterpState_ {
|
||||||
Vector3 Pos;
|
Vector3 Pos;
|
||||||
Real32 HeadX, HeadY, RotX, RotZ;
|
Real32 HeadX, HeadY, RotX, RotZ;
|
||||||
} InterpState;
|
} InterpState;
|
||||||
|
|
||||||
/* Base entity component that performs interpolation of position and orientation. */
|
/* Base entity component that performs interpolation of position and orientation */
|
||||||
typedef struct InterpComp_ {
|
typedef struct InterpComp_ {
|
||||||
InterpState Prev, Next;
|
InterpState Prev, Next;
|
||||||
Real32 PrevRotY, NextRotY;
|
Real32 PrevRotY, NextRotY;
|
||||||
@ -91,10 +92,10 @@ void InterpComp_LerpAngles(InterpComp* interp, Entity* entity, Real32 t);
|
|||||||
void LocalInterpComp_SetLocation(InterpComp* interp, LocationUpdate* update, bool interpolate);
|
void LocalInterpComp_SetLocation(InterpComp* interp, LocationUpdate* update, bool interpolate);
|
||||||
void LocalInterpComp_AdvanceState(InterpComp* interp);
|
void LocalInterpComp_AdvanceState(InterpComp* interp);
|
||||||
|
|
||||||
/* Entity component that performs interpolation for network players. */
|
/* Entity component that performs interpolation for network players */
|
||||||
typedef struct NetInterpComp_ {
|
typedef struct NetInterpComp_ {
|
||||||
InterpComp Base;
|
InterpComp Base;
|
||||||
/* Last known position and orientation sent by the server. */
|
/* Last known position and orientation sent by the server */
|
||||||
InterpState Cur;
|
InterpState Cur;
|
||||||
Int32 StatesCount;
|
Int32 StatesCount;
|
||||||
InterpState States[10];
|
InterpState States[10];
|
||||||
@ -103,10 +104,37 @@ typedef struct NetInterpComp_ {
|
|||||||
void NetInterpComp_SetLocation(NetInterpComp* interp, LocationUpdate* update, bool interpolate);
|
void NetInterpComp_SetLocation(NetInterpComp* interp, LocationUpdate* update, bool interpolate);
|
||||||
void NetInterpComp_AdvanceState(NetInterpComp* interp);
|
void NetInterpComp_AdvanceState(NetInterpComp* interp);
|
||||||
|
|
||||||
/* Entity component that draws square and circle shadows beneath entities. */
|
/* Entity component that draws square and circle shadows beneath entities */
|
||||||
|
|
||||||
bool ShadowComponent_BoundShadowTex;
|
bool ShadowComponent_BoundShadowTex;
|
||||||
GfxResourceID ShadowComponent_ShadowTex;
|
GfxResourceID ShadowComponent_ShadowTex;
|
||||||
void ShadowComponent_Draw(Entity* entity);
|
void ShadowComponent_Draw(Entity* entity);
|
||||||
|
|
||||||
|
/* Entity component that performs collision detection */
|
||||||
|
typedef struct CollisionsComp_ {
|
||||||
|
Entity* Entity;
|
||||||
|
bool HitXMin, HitYMin, HitZMin, HitXMax, HitYMax, HitZMax, WasOn;
|
||||||
|
} CollisionsComp;
|
||||||
|
bool Collisions_HitHorizontal(CollisionsComp* comp);
|
||||||
|
void Collisions_MoveAndWallSlide(CollisionsComp* comp);
|
||||||
|
|
||||||
|
/* Entity component that performs collisions */
|
||||||
|
typedef struct PhysicsComp_ {
|
||||||
|
bool UseLiquidGravity; /* used by BlockDefinitions */
|
||||||
|
bool CanLiquidJump, Jumping;
|
||||||
|
Int32 MultiJumps;
|
||||||
|
Entity* Entity;
|
||||||
|
|
||||||
|
Real32 JumpVel, UserJumpVel, ServerJumpVel;
|
||||||
|
HacksComp* Hacks;
|
||||||
|
CollisionsComp* Collisions;
|
||||||
|
} PhysicsComp;
|
||||||
|
|
||||||
|
void PhysicsComp_Init(PhysicsComp* comp, Entity* entity);
|
||||||
|
void PhysicsComp_UpdateVelocityState(PhysicsComp* comp);
|
||||||
|
void PhysicsComp_DoNormalJump(PhysicsComp* comp);
|
||||||
|
void PhysicsComp_PhysicsTick(PhysicsComp* comp, Vector3 vel);
|
||||||
|
void PhysicsComp_CalculateJumpVelocity(PhysicsComp* comp, bool userVel, Real32 jumpHeight);
|
||||||
|
Real64 PhysicsComp_GetMaxHeight(Real32 u);
|
||||||
|
void PhysicsComp_DoEntityPush(Entity* entity);
|
||||||
#endif
|
#endif
|
@ -18,11 +18,11 @@ GfxResourceID env_cloudsVb, env_skyVb, env_cloudsTex;
|
|||||||
Int32 env_cloudVertices, env_skyVertices;
|
Int32 env_cloudVertices, env_skyVertices;
|
||||||
|
|
||||||
Real32 EnvRenderer_BlendFactor(Real32 x) {
|
Real32 EnvRenderer_BlendFactor(Real32 x) {
|
||||||
/* return -0.05 + 0.22 * (Math_LogE(x) * 0.25f); */
|
/* return -0.05 + 0.22 * (Math_Log(x) * 0.25f); */
|
||||||
Real32 blend = -0.13f + 0.28f * (Math_LogE(x) * 0.25f);
|
Real64 blend = -0.13 + 0.28 * (Math_Log(x) * 0.25);
|
||||||
if (blend < 0.0f) blend = 0.0f;
|
if (blend < 0.0) blend = 0.0;
|
||||||
if (blend > 1.0f) blend = 1.0f;
|
if (blend > 1.0) blend = 1.0;
|
||||||
return blend;
|
return (Real32)blend;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EnvRenderer_BlockOn(Real32* fogDensity, PackedCol* fogCol) {
|
void EnvRenderer_BlockOn(Real32* fogDensity, PackedCol* fogCol) {
|
||||||
@ -59,8 +59,11 @@ void EnvRenderer_RenderMinimal(Real64 deltaTime) {
|
|||||||
/* TODO: rewrite this to avoid raising the event? want to avoid recreating vbos too many times often */
|
/* TODO: rewrite this to avoid raising the event? want to avoid recreating vbos too many times often */
|
||||||
if (fogDensity != 0.0f) {
|
if (fogDensity != 0.0f) {
|
||||||
/* Exp fog mode: f = e^(-density*coord) */
|
/* Exp fog mode: f = e^(-density*coord) */
|
||||||
/* Solve for f = 0.05 to figure out coord (good approx for fog end) */
|
/* Solve coord for f = 0.05 (good approx for fog end) */
|
||||||
Real32 dist = (Real32)Math_LogE(0.05f) / -fogDensity;
|
/* i.e. log(0.05) = -density * coord */
|
||||||
|
|
||||||
|
#define LOG_005 -2.99573227355399
|
||||||
|
Real64 dist = LOG_005 / -fogDensity;
|
||||||
Game_SetViewDistance((Int32)dist, false);
|
Game_SetViewDistance((Int32)dist, false);
|
||||||
} else {
|
} else {
|
||||||
Game_SetViewDistance(Game_UserViewDistance, false);
|
Game_SetViewDistance(Game_UserViewDistance, false);
|
||||||
@ -129,8 +132,10 @@ void EnvRenderer_UpdateFog(void) {
|
|||||||
0.99=z/end --> z=end*0.99
|
0.99=z/end --> z=end*0.99
|
||||||
therefore
|
therefore
|
||||||
d = -ln(0.01)/(end*0.99) */
|
d = -ln(0.01)/(end*0.99) */
|
||||||
Real32 density = -Math_LogE(0.01f) / (Game_ViewDistance * 0.99f);
|
|
||||||
Gfx_SetFogDensity(density);
|
#define LOG_001 -4.60517018598809
|
||||||
|
Real64 density = -(LOG_001) / (Game_ViewDistance * 0.99);
|
||||||
|
Gfx_SetFogDensity((Real32)density);
|
||||||
} else {
|
} else {
|
||||||
Gfx_SetFogMode(FOG_LINEAR);
|
Gfx_SetFogMode(FOG_LINEAR);
|
||||||
Gfx_SetFogEnd(Game_ViewDistance);
|
Gfx_SetFogEnd(Game_ViewDistance);
|
||||||
|
@ -1,5 +1,21 @@
|
|||||||
#include "ExtMath.h"
|
#include "ExtMath.h"
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
/* TODO: Replace with own functions that don't rely on stdlib */
|
||||||
|
|
||||||
|
Real32 Math_AbsF(Real32 x) { return fabsf(x); }
|
||||||
|
Real32 Math_SinF(Real32 x) { return sinf(x); }
|
||||||
|
Real32 Math_CosF(Real32 x) { return cosf(x); }
|
||||||
|
Real32 Math_TanF(Real32 x) { return tanf(x); }
|
||||||
|
Real32 Math_SqrtF(Real32 x) { return sqrtf(x); }
|
||||||
|
Real32 Math_ModF(Real32 x, Real32 y) { return fmodf(x, y); }
|
||||||
|
|
||||||
|
Real64 Math_Log(Real64 x) { return log(x); }
|
||||||
|
Real64 Math_Exp(Real64 x) { return exp(x); }
|
||||||
|
Real64 Math_Asin(Real64 x) { return asin(x); }
|
||||||
|
Real64 Math_Atan2(Real64 y, Real64 x) { return atan2(y, x); }
|
||||||
|
|
||||||
|
Int32 Math_AbsI(Int32 x) { return abs(x); }
|
||||||
Int32 Math_Floor(Real32 value) {
|
Int32 Math_Floor(Real32 value) {
|
||||||
Int32 valueI = (Int32)value;
|
Int32 valueI = (Int32)value;
|
||||||
return valueI > value ? valueI - 1 : valueI;
|
return valueI > value ? valueI - 1 : valueI;
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
#ifndef CC_MATH_H
|
#ifndef CC_MATH_H
|
||||||
#define CC_MATH_H
|
#define CC_MATH_H
|
||||||
#include <math.h>
|
|
||||||
#include "Typedefs.h"
|
#include "Typedefs.h"
|
||||||
/* Simple math functions and constants.
|
/* Simple math functions and constants.
|
||||||
Copyright 2017 ClassicalSharp | Licensed under BSD-3
|
Copyright 2017 ClassicalSharp | Licensed under BSD-3
|
||||||
@ -15,21 +14,19 @@
|
|||||||
#define Math_Deg2Packed(x) ((UInt8)((x) * 256.0f / 360.0f))
|
#define Math_Deg2Packed(x) ((UInt8)((x) * 256.0f / 360.0f))
|
||||||
#define Math_Packed2Deg(x) ((x) * 360.0f / 256.0f)
|
#define Math_Packed2Deg(x) ((x) * 360.0f / 256.0f)
|
||||||
|
|
||||||
#define Math_AbsF(x) fabsf(x)
|
Real32 Math_AbsF(Real32 x);
|
||||||
#define Math_AbsI(x) abs(x)
|
Real32 Math_SinF(Real32 x);
|
||||||
|
Real32 Math_CosF(Real32 x);
|
||||||
|
Real32 Math_TanF(Real32 x);
|
||||||
|
Real32 Math_SqrtF(Real32 x);
|
||||||
|
Real32 Math_ModF(Real32 x, Real32 y);
|
||||||
|
|
||||||
#define Math_LogE(x) logf(x)
|
Real64 Math_Log(Real64 x);
|
||||||
#define Math_PowE(x) expf(x)
|
Real64 Math_Exp(Real64 x);
|
||||||
|
Real64 Math_Asin(Real64 x);
|
||||||
#define Math_Sin(x) sinf(x)
|
Real64 Math_Atan2(Real64 y, Real64 x);
|
||||||
#define Math_Cos(x) cosf(x)
|
|
||||||
#define Math_Tan(x) tanf(x)
|
|
||||||
#define Math_Asin(x) asinf(x)
|
|
||||||
#define Math_Atan2(y, x) atan2f(y, x)
|
|
||||||
|
|
||||||
#define Math_Sqrt(x) sqrtf(x)
|
|
||||||
#define Math_Mod(x, y) fmodf(x, y)
|
|
||||||
|
|
||||||
|
Int32 Math_AbsI(Int32 x);
|
||||||
Int32 Math_Floor(Real32 value);
|
Int32 Math_Floor(Real32 value);
|
||||||
Int32 Math_Ceil(Real32 value);
|
Int32 Math_Ceil(Real32 value);
|
||||||
Int32 Math_Log2(Int32 value);
|
Int32 Math_Log2(Int32 value);
|
||||||
|
@ -103,16 +103,16 @@ void HeldBlockRenderer_ProjectionChanged(void* obj) {
|
|||||||
*/
|
*/
|
||||||
void HeldBlockRenderer_DigAnimation(void) {
|
void HeldBlockRenderer_DigAnimation(void) {
|
||||||
Real32 t = held_time / held_period;
|
Real32 t = held_time / held_period;
|
||||||
Real32 sinHalfCircle = Math_Sin(t * MATH_PI);
|
Real32 sinHalfCircle = Math_SinF(t * MATH_PI);
|
||||||
Real32 sqrtLerpPI = Math_Sqrt(t) * MATH_PI;
|
Real32 sqrtLerpPI = Math_SqrtF(t) * MATH_PI;
|
||||||
|
|
||||||
held_entity.Position.X -= Math_Sin(sqrtLerpPI) * 0.4f;
|
held_entity.Position.X -= Math_SinF(sqrtLerpPI) * 0.4f;
|
||||||
held_entity.Position.Y += Math_Sin((sqrtLerpPI * 2)) * 0.2f;
|
held_entity.Position.Y += Math_SinF((sqrtLerpPI * 2)) * 0.2f;
|
||||||
held_entity.Position.Z -= sinHalfCircle * 0.2f;
|
held_entity.Position.Z -= sinHalfCircle * 0.2f;
|
||||||
|
|
||||||
Real32 sinHalfCircleWeird = Math_Sin(t * t * MATH_PI);
|
Real32 sinHalfCircleWeird = Math_SinF(t * t * MATH_PI);
|
||||||
held_entity.RotY -= Math_Sin(sqrtLerpPI) * 80.0f;
|
held_entity.RotY -= Math_SinF(sqrtLerpPI) * 80.0f;
|
||||||
held_entity.HeadY -= Math_Sin(sqrtLerpPI) * 80.0f;
|
held_entity.HeadY -= Math_SinF(sqrtLerpPI) * 80.0f;
|
||||||
held_entity.RotX += sinHalfCircleWeird * 20.0f;
|
held_entity.RotX += sinHalfCircleWeird * 20.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,7 +172,7 @@ void HeldBlockRenderer_DoAnimation(Real64 delta, Real32 lastSwingY) {
|
|||||||
|
|
||||||
if (held_swinging || !held_breaking) {
|
if (held_swinging || !held_breaking) {
|
||||||
Real32 t = held_time / held_period;
|
Real32 t = held_time / held_period;
|
||||||
held_swingY = -0.4f * Math_Sin(t * MATH_PI);
|
held_swingY = -0.4f * Math_SinF(t * MATH_PI);
|
||||||
held_entity.Position.Y += held_swingY;
|
held_entity.Position.Y += held_swingY;
|
||||||
|
|
||||||
if (held_swinging) {
|
if (held_swinging) {
|
||||||
|
@ -118,8 +118,8 @@ void IModel_SetupState(IModel* model, Entity* entity) {
|
|||||||
IModel_Cols[5] = IModel_Cols[4];
|
IModel_Cols[5] = IModel_Cols[4];
|
||||||
|
|
||||||
Real32 yawDelta = entity->HeadY - entity->RotY;
|
Real32 yawDelta = entity->HeadY - entity->RotY;
|
||||||
IModel_cosHead = Math_Cos(yawDelta * MATH_DEG2RAD);
|
IModel_cosHead = Math_CosF(yawDelta * MATH_DEG2RAD);
|
||||||
IModel_sinHead = Math_Sin(yawDelta * MATH_DEG2RAD);
|
IModel_sinHead = Math_SinF(yawDelta * MATH_DEG2RAD);
|
||||||
}
|
}
|
||||||
|
|
||||||
void IModel_UpdateVB(void) {
|
void IModel_UpdateVB(void) {
|
||||||
@ -158,9 +158,9 @@ void IModel_DrawPart(ModelPart part) {
|
|||||||
|
|
||||||
void IModel_DrawRotate(Real32 angleX, Real32 angleY, Real32 angleZ, ModelPart part, bool head) {
|
void IModel_DrawRotate(Real32 angleX, Real32 angleY, Real32 angleZ, ModelPart part, bool head) {
|
||||||
IModel* model = IModel_ActiveModel;
|
IModel* model = IModel_ActiveModel;
|
||||||
Real32 cosX = Math_Cos(-angleX), sinX = Math_Sin(-angleX);
|
Real32 cosX = Math_CosF(-angleX), sinX = Math_SinF(-angleX);
|
||||||
Real32 cosY = Math_Cos(-angleY), sinY = Math_Sin(-angleY);
|
Real32 cosY = Math_CosF(-angleY), sinY = Math_SinF(-angleY);
|
||||||
Real32 cosZ = Math_Cos(-angleZ), sinZ = Math_Sin(-angleZ);
|
Real32 cosZ = Math_CosF(-angleZ), sinZ = Math_SinF(-angleZ);
|
||||||
Real32 x = part.RotX, y = part.RotY, z = part.RotZ;
|
Real32 x = part.RotX, y = part.RotY, z = part.RotZ;
|
||||||
|
|
||||||
ModelVertex* src = &model->vertices[part.Offset];
|
ModelVertex* src = &model->vertices[part.Offset];
|
||||||
|
@ -386,7 +386,7 @@ void InputHandler_KeyDown(void* obj, Int32 key) {
|
|||||||
Game_ScreenshotRequested = true;
|
Game_ScreenshotRequested = true;
|
||||||
} else if (active->VTABLE->HandlesKeyDown(active, key)) {
|
} else if (active->VTABLE->HandlesKeyDown(active, key)) {
|
||||||
} else if (InputHandler_HandleCoreKey(key)) {
|
} else if (InputHandler_HandleCoreKey(key)) {
|
||||||
} else if (LocalPlayer_Instance.Input.Handles(key)) {
|
} else if (LocalPlayer_HandlesKey(key)) {
|
||||||
} else {
|
} else {
|
||||||
UInt8 textBuffer[String_BufferSize(STRING_SIZE)];
|
UInt8 textBuffer[String_BufferSize(STRING_SIZE)];
|
||||||
String text = String_InitAndClearArray(textBuffer);
|
String text = String_InitAndClearArray(textBuffer);
|
||||||
|
@ -44,10 +44,10 @@ void IsometricDrawer_InitCache(void) {
|
|||||||
Matrix_RotateX(&rotX, -30.0f * MATH_DEG2RAD);
|
Matrix_RotateX(&rotX, -30.0f * MATH_DEG2RAD);
|
||||||
Matrix_Mul(&iso_transform, &rotY, &rotX);
|
Matrix_Mul(&iso_transform, &rotY, &rotX);
|
||||||
|
|
||||||
iso_cosX = Math_Cos(30.0f * MATH_DEG2RAD);
|
iso_cosX = Math_CosF(30.0f * MATH_DEG2RAD);
|
||||||
iso_sinX = Math_Sin(30.0f * MATH_DEG2RAD);
|
iso_sinX = Math_SinF(30.0f * MATH_DEG2RAD);
|
||||||
iso_cosY = Math_Cos(-45.0f * MATH_DEG2RAD);
|
iso_cosY = Math_CosF(-45.0f * MATH_DEG2RAD);
|
||||||
iso_sinY = Math_Sin(-45.0f * MATH_DEG2RAD);
|
iso_sinY = Math_SinF(-45.0f * MATH_DEG2RAD);
|
||||||
}
|
}
|
||||||
|
|
||||||
void IsometricDrawer_Flush(void) {
|
void IsometricDrawer_Flush(void) {
|
||||||
|
@ -216,9 +216,9 @@ void NotchyGen_CarveCaves(void) {
|
|||||||
Real32 caveRadius = Random_Float(&rnd) * Random_Float(&rnd);
|
Real32 caveRadius = Random_Float(&rnd) * Random_Float(&rnd);
|
||||||
|
|
||||||
for (j = 0; j < caveLen; j++) {
|
for (j = 0; j < caveLen; j++) {
|
||||||
caveX += Math_Sin(theta) * Math_Cos(phi);
|
caveX += Math_SinF(theta) * Math_CosF(phi);
|
||||||
caveZ += Math_Cos(theta) * Math_Cos(phi);
|
caveZ += Math_CosF(theta) * Math_CosF(phi);
|
||||||
caveY += Math_Sin(phi);
|
caveY += Math_SinF(phi);
|
||||||
|
|
||||||
theta = theta + deltaTheta * 0.2f;
|
theta = theta + deltaTheta * 0.2f;
|
||||||
deltaTheta = deltaTheta * 0.9f + Random_Float(&rnd) - Random_Float(&rnd);
|
deltaTheta = deltaTheta * 0.9f + Random_Float(&rnd) - Random_Float(&rnd);
|
||||||
@ -232,7 +232,7 @@ void NotchyGen_CarveCaves(void) {
|
|||||||
|
|
||||||
Real32 radius = (Gen_Height - cenY) / (Real32)Gen_Height;
|
Real32 radius = (Gen_Height - cenY) / (Real32)Gen_Height;
|
||||||
radius = 1.2f + (radius * 3.5f + 1.0f) * caveRadius;
|
radius = 1.2f + (radius * 3.5f + 1.0f) * caveRadius;
|
||||||
radius = radius * Math_Sin(j * MATH_PI / caveLen);
|
radius = radius * Math_SinF(j * MATH_PI / caveLen);
|
||||||
NotchyGen_FillOblateSpheroid(cenX, cenY, cenZ, radius, BLOCK_AIR);
|
NotchyGen_FillOblateSpheroid(cenX, cenY, cenZ, radius, BLOCK_AIR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -254,16 +254,16 @@ void NotchyGen_CarveOreVeins(Real32 abundance, const UInt8* state, BlockID block
|
|||||||
Real32 phi = Random_Float(&rnd) * 2.0f * MATH_PI, deltaPhi = 0.0f;
|
Real32 phi = Random_Float(&rnd) * 2.0f * MATH_PI, deltaPhi = 0.0f;
|
||||||
|
|
||||||
for (j = 0; j < veinLen; j++) {
|
for (j = 0; j < veinLen; j++) {
|
||||||
veinX += Math_Sin(theta) * Math_Cos(phi);
|
veinX += Math_SinF(theta) * Math_CosF(phi);
|
||||||
veinZ += Math_Cos(theta) * Math_Cos(phi);
|
veinZ += Math_CosF(theta) * Math_CosF(phi);
|
||||||
veinY += Math_Sin(phi);
|
veinY += Math_SinF(phi);
|
||||||
|
|
||||||
theta = deltaTheta * 0.2f;
|
theta = deltaTheta * 0.2f;
|
||||||
deltaTheta = deltaTheta * 0.9f + Random_Float(&rnd) - Random_Float(&rnd);
|
deltaTheta = deltaTheta * 0.9f + Random_Float(&rnd) - Random_Float(&rnd);
|
||||||
phi = phi * 0.5f + deltaPhi * 0.25f;
|
phi = phi * 0.5f + deltaPhi * 0.25f;
|
||||||
deltaPhi = deltaPhi * 0.9f + Random_Float(&rnd) - Random_Float(&rnd);
|
deltaPhi = deltaPhi * 0.9f + Random_Float(&rnd) - Random_Float(&rnd);
|
||||||
|
|
||||||
Real32 radius = abundance * Math_Sin(j * MATH_PI / veinLen) + 1.0f;
|
Real32 radius = abundance * Math_SinF(j * MATH_PI / veinLen) + 1.0f;
|
||||||
NotchyGen_FillOblateSpheroid((Int32)veinX, (Int32)veinY, (Int32)veinZ, radius, block);
|
NotchyGen_FillOblateSpheroid((Int32)veinX, (Int32)veinY, (Int32)veinZ, radius, block);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2611,9 +2611,13 @@ void HacksSettingsScreen_SetClipping(STRING_PURE String* v) {
|
|||||||
|
|
||||||
void HacksSettingsScreen_GetJump(STRING_TRANSIENT String* v) { String_AppendReal32(v, LocalPlayer_JumpHeight(), 3); }
|
void HacksSettingsScreen_GetJump(STRING_TRANSIENT String* v) { String_AppendReal32(v, LocalPlayer_JumpHeight(), 3); }
|
||||||
void HacksSettingsScreen_SetJump(STRING_PURE String* v) {
|
void HacksSettingsScreen_SetJump(STRING_PURE String* v) {
|
||||||
LocalPlayer_Instance.physics.CalculateJumpVelocity(true, Menu_Real32(v));
|
PhysicsComp* physics = &LocalPlayer_Instance.Physics;
|
||||||
Real32 jumpVel = LocalPlayer_Instance.physics.jumpVel;
|
PhysicsComp_CalculateJumpVelocity(physics, true, Menu_Real32(v));
|
||||||
Options_Set(OPT_JUMP_VELOCITY, jumpVel.ToString());
|
|
||||||
|
UInt8 strBuffer[String_BufferSize(STRING_SIZE)];
|
||||||
|
String str = String_InitAndClearArray(strBuffer);
|
||||||
|
String_AppendReal32(&str, physics->JumpVel, 8);
|
||||||
|
Options_Set(OPT_JUMP_VELOCITY, &str);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HacksSettingsScreen_GetWOMHacks(STRING_TRANSIENT String* v) { Menu_GetBool(v, LocalPlayer_Instance.Hacks.WOMStyleHacks); }
|
void HacksSettingsScreen_GetWOMHacks(STRING_TRANSIENT String* v) { Menu_GetBool(v, LocalPlayer_Instance.Hacks.WOMStyleHacks); }
|
||||||
|
@ -572,9 +572,9 @@ void SpiderModel_DrawModel(Entity* entity) {
|
|||||||
IModel_DrawPart(Spider_Link);
|
IModel_DrawPart(Spider_Link);
|
||||||
IModel_DrawPart(Spider_End);
|
IModel_DrawPart(Spider_End);
|
||||||
|
|
||||||
Real32 rotX = Math_Sin(entity->Anim.WalkTime) * entity->Anim.Swing * MATH_PI;
|
Real32 rotX = Math_SinF(entity->Anim.WalkTime) * entity->Anim.Swing * MATH_PI;
|
||||||
Real32 rotZ = Math_Cos(entity->Anim.WalkTime * 2) * entity->Anim.Swing * MATH_PI / 16.0f;
|
Real32 rotZ = Math_CosF(entity->Anim.WalkTime * 2) * entity->Anim.Swing * MATH_PI / 16.0f;
|
||||||
Real32 rotY = Math_Sin(entity->Anim.WalkTime * 2) * entity->Anim.Swing * MATH_PI / 32.0f;
|
Real32 rotY = Math_SinF(entity->Anim.WalkTime * 2) * entity->Anim.Swing * MATH_PI / 32.0f;
|
||||||
IModel_Rotation = ROTATE_ORDER_XZY;
|
IModel_Rotation = ROTATE_ORDER_XZY;
|
||||||
|
|
||||||
IModel_DrawRotate(rotX, quarterPi + rotY, eighthPi + rotZ, Spider_LeftLeg, false);
|
IModel_DrawRotate(rotX, quarterPi + rotY, eighthPi + rotZ, Spider_LeftLeg, false);
|
||||||
@ -1120,10 +1120,10 @@ Real32 BlockModel_GetEyeY(Entity* entity) {
|
|||||||
|
|
||||||
Vector3 BlockModel_GetCollisionSize(void) {
|
Vector3 BlockModel_GetCollisionSize(void) {
|
||||||
Vector3 size;
|
Vector3 size;
|
||||||
Vector3_Subtract(&size, &BlockModel_maxBB, &BlockModel_minBB);
|
Vector3_Sub(&size, &BlockModel_maxBB, &BlockModel_minBB);
|
||||||
/* to fit slightly inside */
|
/* to fit slightly inside */
|
||||||
Vector3 sizeShrink = Vector3_Create1(0.75f / 16.0f);
|
Vector3 sizeShrink = VECTOR3_CONST1(0.75f / 16.0f);
|
||||||
Vector3_Subtract(&size, &size, &sizeShrink);
|
Vector3_SubBy(&size, &sizeShrink);
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,7 +105,7 @@ bool Particle_PhysicsTick(Particle* p, Real32 gravity, bool throughLiquids, Real
|
|||||||
p->Velocity.Y -= gravity * (Real32)delta;
|
p->Velocity.Y -= gravity * (Real32)delta;
|
||||||
Int32 startY = Math_Floor(p->NextPos.Y);
|
Int32 startY = Math_Floor(p->NextPos.Y);
|
||||||
Vector3 velocity;
|
Vector3 velocity;
|
||||||
Vector3_Multiply1(&velocity, &p->Velocity, (Real32)delta * 3.0f);
|
Vector3_Mul1(&velocity, &p->Velocity, (Real32)delta * 3.0f);
|
||||||
Vector3_Add(&p->NextPos, &p->NextPos, &velocity);
|
Vector3_Add(&p->NextPos, &p->NextPos, &velocity);
|
||||||
Int32 endY = Math_Floor(p->NextPos.Y);
|
Int32 endY = Math_Floor(p->NextPos.Y);
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ bool Intersection_RayIntersectsRotatedBox(Vector3 origin, Vector3 dir, Entity* t
|
|||||||
* /
|
* /
|
||||||
/
|
/
|
||||||
*/
|
*/
|
||||||
Vector3 delta; Vector3_Subtract(&delta, &origin, &target->Position); /* delta = origin - target.Position */
|
Vector3 delta; Vector3_Sub(&delta, &origin, &target->Position); /* delta = origin - target.Position */
|
||||||
delta = Intersection_InverseRotate(delta, target); /* delta = UndoRotation(delta) */
|
delta = Intersection_InverseRotate(delta, target); /* delta = UndoRotation(delta) */
|
||||||
Vector3_Add(&origin, &delta, &target->Position); /* origin = delta + target.Position */
|
Vector3_Add(&origin, &delta, &target->Position); /* origin = delta + target.Position */
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ void PickedPosRenderer_ZQuad(Real32 z, Real32 x1, Real32 y1, Real32 x2, Real32 y
|
|||||||
void PickedPosRenderer_UpdateState(PickedPos* selected) {
|
void PickedPosRenderer_UpdateState(PickedPos* selected) {
|
||||||
pickedPos_ptr = pickedPos_vertices;
|
pickedPos_ptr = pickedPos_vertices;
|
||||||
Vector3 delta;
|
Vector3 delta;
|
||||||
Vector3_Subtract(&delta, &Game_CurrentCameraPos, &selected->Min);
|
Vector3_Sub(&delta, &Game_CurrentCameraPos, &selected->Min);
|
||||||
Real32 dist = Vector3_LengthSquared(&delta);
|
Real32 dist = Vector3_LengthSquared(&delta);
|
||||||
|
|
||||||
Real32 offset = 0.01f;
|
Real32 offset = 0.01f;
|
||||||
|
@ -185,7 +185,7 @@ bool Picking_ClipBlock(PickedPos* pos) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Vector3 scaledDir, intersect;
|
Vector3 scaledDir, intersect;
|
||||||
Vector3_Multiply1(&scaledDir, &tracer.Dir, t0); /* scaledDir = dir * t0 */
|
Vector3_Mul1(&scaledDir, &tracer.Dir, t0); /* scaledDir = dir * t0 */
|
||||||
Vector3_Add(&intersect, &tracer.Origin, &scaledDir); /* intersect = origin + scaledDir */
|
Vector3_Add(&intersect, &tracer.Origin, &scaledDir); /* intersect = origin + scaledDir */
|
||||||
/* Only pick the block if the block is precisely within reach distance. */
|
/* Only pick the block if the block is precisely within reach distance. */
|
||||||
Real32 lenSq = Vector3_LengthSquared(&scaledDir);
|
Real32 lenSq = Vector3_LengthSquared(&scaledDir);
|
||||||
@ -210,7 +210,7 @@ bool Picking_ClipCamera(PickedPos* pos) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Vector3 intersect;
|
Vector3 intersect;
|
||||||
Vector3_Multiply1(&intersect, &tracer.Dir, t0); /* intersect = dir * t0 */
|
Vector3_Mul1(&intersect, &tracer.Dir, t0); /* intersect = dir * t0 */
|
||||||
Vector3_Add(&intersect, &tracer.Origin, &intersect); /* intersect = origin + dir * t0 */
|
Vector3_Add(&intersect, &tracer.Origin, &intersect); /* intersect = origin + dir * t0 */
|
||||||
PickedPos_SetAsValid(pos, &tracer, intersect);
|
PickedPos_SetAsValid(pos, &tracer, intersect);
|
||||||
|
|
||||||
@ -236,7 +236,7 @@ void Picking_ClipCameraPos(Vector3 origin, Vector3 dir, Real32 reach, PickedPos*
|
|||||||
bool noClip = !Game_CameraClipping || LocalPlayer_Instance.Hacks.Noclip;
|
bool noClip = !Game_CameraClipping || LocalPlayer_Instance.Hacks.Noclip;
|
||||||
if (noClip || !Picking_RayTrace(origin, dir, reach, pos, Picking_ClipCamera)) {
|
if (noClip || !Picking_RayTrace(origin, dir, reach, pos, Picking_ClipCamera)) {
|
||||||
PickedPos_SetAsInvalid(pos);
|
PickedPos_SetAsInvalid(pos);
|
||||||
Vector3_Multiply1(&pos->Intersect, &tracer.Dir, reach); /* intersect = dir * reach */
|
Vector3_Mul1(&pos->Intersect, &tracer.Dir, reach); /* intersect = dir * reach */
|
||||||
Vector3_Add(&pos->Intersect, &tracer.Origin, &pos->Intersect); /* intersect = origin + dir * reach */
|
Vector3_Add(&pos->Intersect, &tracer.Origin, &pos->Intersect); /* intersect = origin + dir * reach */
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -18,11 +18,6 @@ Vector3I Vector3I_Create3(Int32 x, Int32 y, Int32 z) {
|
|||||||
Vector3I v; v.X = x; v.Y = y; v.Z = z; return v;
|
Vector3I v; v.X = x; v.Y = y; v.Z = z; return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
Real32 Vector3_Length(Vector3* v) {
|
|
||||||
Real32 lenSquared = v->X * v->X + v->Y * v->Y + v->Z * v->Z;
|
|
||||||
return Math_Sqrt(lenSquared);
|
|
||||||
}
|
|
||||||
|
|
||||||
Real32 Vector3_LengthSquared(Vector3* v) {
|
Real32 Vector3_LengthSquared(Vector3* v) {
|
||||||
return v->X * v->X + v->Y * v->Y + v->Z * v->Z;
|
return v->X * v->X + v->Y * v->Y + v->Z * v->Z;
|
||||||
}
|
}
|
||||||
@ -35,15 +30,15 @@ void Vector3_Add1(Vector3* result, Vector3* a, Real32 b) {
|
|||||||
result->X = a->X + b; result->Y = a->Y + b; result->Z = a->Z + b;
|
result->X = a->X + b; result->Y = a->Y + b; result->Z = a->Z + b;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Vector3_Subtract(Vector3* result, Vector3* a, Vector3* b) {
|
void Vector3_Sub(Vector3* result, Vector3* a, Vector3* b) {
|
||||||
result->X = a->X - b->X; result->Y = a->Y - b->Y; result->Z = a->Z - b->Z;
|
result->X = a->X - b->X; result->Y = a->Y - b->Y; result->Z = a->Z - b->Z;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Vector3_Multiply1(Vector3* result, Vector3* a, Real32 scale) {
|
void Vector3_Mul1(Vector3* result, Vector3* a, Real32 scale) {
|
||||||
result->X = a->X * scale; result->Y = a->Y * scale; result->Z = a->Z * scale;
|
result->X = a->X * scale; result->Y = a->Y * scale; result->Z = a->Z * scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Vector3_Multiply3(Vector3* result, Vector3* a, Vector3* scale) {
|
void Vector3_Mul3(Vector3* result, Vector3* a, Vector3* scale) {
|
||||||
result->X = a->X * scale->X; result->Y = a->Y * scale->Y; result->Z = a->Z * scale->Z;
|
result->X = a->X * scale->X; result->Y = a->Y * scale->Y; result->Z = a->Z * scale->Z;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,7 +65,8 @@ void Vector3_Cross(Vector3* result, Vector3* a, Vector3* b) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Vector3_Normalize(Vector3* result, Vector3* a) {
|
void Vector3_Normalize(Vector3* result, Vector3* a) {
|
||||||
Real32 scale = 1.0f / Vector3_Length(a);
|
Real32 lenSquared = a->X * a->X + a->Y * a->Y + a->Z * a->Z;
|
||||||
|
Real32 scale = 1.0f / Math_SqrtF(lenSquared);
|
||||||
result->X = a->X * scale;
|
result->X = a->X * scale;
|
||||||
result->Y = a->Y * scale;
|
result->Y = a->Y * scale;
|
||||||
result->Z = a->Z * scale;
|
result->Z = a->Z * scale;
|
||||||
@ -103,22 +99,22 @@ void Vector3_TransformZ(Vector3* result, Real32 z, Matrix* mat) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Vector3 Vector3_RotateX(Vector3 v, Real32 angle) {
|
Vector3 Vector3_RotateX(Vector3 v, Real32 angle) {
|
||||||
Real32 cosA = Math_Cos(angle), sinA = Math_Sin(angle);
|
Real32 cosA = Math_CosF(angle), sinA = Math_SinF(angle);
|
||||||
return Vector3_Create3(v.X, cosA * v.Y + sinA * v.Z, -sinA * v.Y + cosA * v.Z);
|
return Vector3_Create3(v.X, cosA * v.Y + sinA * v.Z, -sinA * v.Y + cosA * v.Z);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3 Vector3_RotateY(Vector3 v, Real32 angle) {
|
Vector3 Vector3_RotateY(Vector3 v, Real32 angle) {
|
||||||
Real32 cosA = Math_Cos(angle), sinA = Math_Sin(angle);
|
Real32 cosA = Math_CosF(angle), sinA = Math_SinF(angle);
|
||||||
return Vector3_Create3(cosA * v.X - sinA * v.Z, v.Y, sinA * v.X + cosA * v.Z);
|
return Vector3_Create3(cosA * v.X - sinA * v.Z, v.Y, sinA * v.X + cosA * v.Z);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3 Vector3_RotateY3(Real32 x, Real32 y, Real32 z, Real32 angle) {
|
Vector3 Vector3_RotateY3(Real32 x, Real32 y, Real32 z, Real32 angle) {
|
||||||
Real32 cosA = Math_Cos(angle), sinA = Math_Sin(angle);
|
Real32 cosA = Math_CosF(angle), sinA = Math_SinF(angle);
|
||||||
return Vector3_Create3(cosA * x - sinA * z, y, sinA * x + cosA * z);
|
return Vector3_Create3(cosA * x - sinA * z, y, sinA * x + cosA * z);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3 Vector3_RotateZ(Vector3 v, Real32 angle) {
|
Vector3 Vector3_RotateZ(Vector3 v, Real32 angle) {
|
||||||
Real32 cosA = Math_Cos(angle), sinA = Math_Sin(angle);
|
Real32 cosA = Math_CosF(angle), sinA = Math_SinF(angle);
|
||||||
return Vector3_Create3(cosA * v.X + sinA * v.Y, -sinA * v.X + cosA * v.Y, v.Z);
|
return Vector3_Create3(cosA * v.X + sinA * v.Y, -sinA * v.X + cosA * v.Y, v.Z);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,15 +146,15 @@ void Vector3I_Max(Vector3I* result, Vector3I* a, Vector3I* b) {
|
|||||||
|
|
||||||
|
|
||||||
Vector3 Vector3_GetDirVector(Real32 yawRad, Real32 pitchRad) {
|
Vector3 Vector3_GetDirVector(Real32 yawRad, Real32 pitchRad) {
|
||||||
Real32 x = -Math_Cos(pitchRad) * -Math_Sin(yawRad);
|
Real32 x = -Math_CosF(pitchRad) * -Math_SinF(yawRad);
|
||||||
Real32 y = -Math_Sin(pitchRad);
|
Real32 y = -Math_SinF(pitchRad);
|
||||||
Real32 z = -Math_Cos(pitchRad) * Math_Cos(yawRad);
|
Real32 z = -Math_CosF(pitchRad) * Math_CosF(yawRad);
|
||||||
return Vector3_Create3(x, y, z);
|
return Vector3_Create3(x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Vector3_GetHeading(Vector3 dir, Real32* yaw, Real32* pitch) {
|
void Vector3_GetHeading(Vector3 dir, Real32* yaw, Real32* pitch) {
|
||||||
*pitch = Math_Asin(-dir.Y);
|
*pitch = (Real32)Math_Asin(-dir.Y);
|
||||||
*yaw = Math_Atan2(dir.X, -dir.Z);
|
*yaw = (Real32)Math_Atan2(dir.X, -dir.Z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -172,21 +168,21 @@ Matrix Matrix_Identity = {
|
|||||||
/* Transposed, source https://open.gl/transformations */
|
/* Transposed, source https://open.gl/transformations */
|
||||||
|
|
||||||
void Matrix_RotateX(Matrix* result, Real32 angle) {
|
void Matrix_RotateX(Matrix* result, Real32 angle) {
|
||||||
Real32 cosA = Math_Cos(angle), sinA = Math_Sin(angle);
|
Real32 cosA = Math_CosF(angle), sinA = Math_SinF(angle);
|
||||||
*result = Matrix_Identity;
|
*result = Matrix_Identity;
|
||||||
result->Row1.Y = cosA; result->Row1.Z = sinA;
|
result->Row1.Y = cosA; result->Row1.Z = sinA;
|
||||||
result->Row2.Y = -sinA; result->Row2.Z = cosA;
|
result->Row2.Y = -sinA; result->Row2.Z = cosA;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Matrix_RotateY(Matrix* result, Real32 angle) {
|
void Matrix_RotateY(Matrix* result, Real32 angle) {
|
||||||
Real32 cosA = Math_Cos(angle), sinA = Math_Sin(angle);
|
Real32 cosA = Math_CosF(angle), sinA = Math_SinF(angle);
|
||||||
*result = Matrix_Identity;
|
*result = Matrix_Identity;
|
||||||
result->Row1.X = cosA; result->Row1.Z = -sinA;
|
result->Row1.X = cosA; result->Row1.Z = -sinA;
|
||||||
result->Row2.X = sinA; result->Row2.Z = cosA;
|
result->Row2.X = sinA; result->Row2.Z = cosA;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Matrix_RotateZ(Matrix* result, Real32 angle) {
|
void Matrix_RotateZ(Matrix* result, Real32 angle) {
|
||||||
Real32 cosA = Math_Cos(angle), sinA = Math_Sin(angle);
|
Real32 cosA = Math_CosF(angle), sinA = Math_SinF(angle);
|
||||||
*result = Matrix_Identity;
|
*result = Matrix_Identity;
|
||||||
result->Row1.X = cosA; result->Row1.Y = sinA;
|
result->Row1.X = cosA; result->Row1.Y = sinA;
|
||||||
result->Row2.X = -sinA; result->Row2.Y = cosA;
|
result->Row2.X = -sinA; result->Row2.Y = cosA;
|
||||||
@ -254,7 +250,7 @@ void Matrix_OrthographicOffCenter(Matrix* result, Real32 left, Real32 right, Rea
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Matrix_PerspectiveFieldOfView(Matrix* result, Real32 fovy, Real32 aspect, Real32 zNear, Real32 zFar) {
|
void Matrix_PerspectiveFieldOfView(Matrix* result, Real32 fovy, Real32 aspect, Real32 zNear, Real32 zFar) {
|
||||||
Real32 c = zNear * Math_Tan(0.5f * fovy);
|
Real32 c = zNear * Math_TanF(0.5 * fovy);
|
||||||
Matrix_PerspectiveOffCenter(result, -c * aspect, c * aspect, -c, c, zNear, zFar);
|
Matrix_PerspectiveOffCenter(result, -c * aspect, c * aspect, -c, c, zNear, zFar);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -275,7 +271,7 @@ void Matrix_PerspectiveOffCenter(Matrix* result, Real32 left, Real32 right, Real
|
|||||||
void Matrix_LookAt(Matrix* result, Vector3 eye, Vector3 target, Vector3 up) {
|
void Matrix_LookAt(Matrix* result, Vector3 eye, Vector3 target, Vector3 up) {
|
||||||
/* Transposed, source https://msdn.microsoft.com/en-us/library/windows/desktop/bb281711(v=vs.85).aspx */
|
/* Transposed, source https://msdn.microsoft.com/en-us/library/windows/desktop/bb281711(v=vs.85).aspx */
|
||||||
Vector3 x, y, z;
|
Vector3 x, y, z;
|
||||||
Vector3_Subtract(&z, &eye, &target); Vector3_Normalize(&z, &z);
|
Vector3_Sub(&z, &eye, &target); Vector3_Normalize(&z, &z);
|
||||||
Vector3_Cross(&x, &up, &z); Vector3_Normalize(&x, &x);
|
Vector3_Cross(&x, &up, &z); Vector3_Normalize(&x, &x);
|
||||||
Vector3_Cross(&y, &z, &x); Vector3_Normalize(&y, &y);
|
Vector3_Cross(&y, &z, &x); Vector3_Normalize(&y, &y);
|
||||||
|
|
||||||
@ -298,7 +294,7 @@ frustum40, frustum41, frustum42, frustum43;
|
|||||||
|
|
||||||
void FrustumCulling_Normalise(Real32* plane0, Real32* plane1, Real32* plane2, Real32* plane3) {
|
void FrustumCulling_Normalise(Real32* plane0, Real32* plane1, Real32* plane2, Real32* plane3) {
|
||||||
Real32 val1 = *plane0, val2 = *plane1, val3 = *plane2;
|
Real32 val1 = *plane0, val2 = *plane1, val3 = *plane2;
|
||||||
Real32 t = Math_Sqrt(val1 * val1 + val2 * val2 + val3 * val3);
|
Real32 t = Math_SqrtF(val1 * val1 + val2 * val2 + val3 * val3);
|
||||||
*plane0 /= t; *plane1 /= t; *plane2 /= t; *plane3 /= t;
|
*plane0 /= t; *plane1 /= t; *plane2 /= t; *plane3 /= t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,10 +17,9 @@ Vector3 Vector3_Create1(Real32 value);
|
|||||||
Vector3 Vector3_Create3(Real32 x, Real32 y, Real32 z);
|
Vector3 Vector3_Create3(Real32 x, Real32 y, Real32 z);
|
||||||
Vector3I Vector3I_Create1(Int32 value);
|
Vector3I Vector3I_Create1(Int32 value);
|
||||||
Vector3I Vector3I_Create3(Int32 x, Int32 y, Int32 z);
|
Vector3I Vector3I_Create3(Int32 x, Int32 y, Int32 z);
|
||||||
|
|
||||||
Real32 Vector3_Length(Vector3* v);
|
|
||||||
Real32 Vector3_LengthSquared(Vector3* v);
|
Real32 Vector3_LengthSquared(Vector3* v);
|
||||||
|
|
||||||
|
#define VECTOR3_CONST1(val) { val, val, val };
|
||||||
#define VECTOR3_CONST(x, y, z) { x, y, z };
|
#define VECTOR3_CONST(x, y, z) { x, y, z };
|
||||||
#define Vector3_UnitX VECTOR3_CONST(1.0f, 0.0f, 0.0f)
|
#define Vector3_UnitX VECTOR3_CONST(1.0f, 0.0f, 0.0f)
|
||||||
#define Vector3_UnitY VECTOR3_CONST(0.0f, 1.0f, 0.0f)
|
#define Vector3_UnitY VECTOR3_CONST(0.0f, 1.0f, 0.0f)
|
||||||
@ -30,11 +29,16 @@ Real32 Vector3_LengthSquared(Vector3* v);
|
|||||||
|
|
||||||
void Vector3_Add(Vector3* result, Vector3* a, Vector3* b);
|
void Vector3_Add(Vector3* result, Vector3* a, Vector3* b);
|
||||||
void Vector3_Add1(Vector3* result, Vector3* a, Real32 b);
|
void Vector3_Add1(Vector3* result, Vector3* a, Real32 b);
|
||||||
void Vector3_Subtract(Vector3* result, Vector3* a, Vector3* b);
|
void Vector3_Sub(Vector3* result, Vector3* a, Vector3* b);
|
||||||
void Vector3_Multiply1(Vector3* result, Vector3* a, Real32 scale);
|
void Vector3_Mul1(Vector3* result, Vector3* a, Real32 scale);
|
||||||
void Vector3_Multiply3(Vector3* result, Vector3* a, Vector3* scale);
|
void Vector3_Mul3(Vector3* result, Vector3* a, Vector3* scale);
|
||||||
void Vector3_Negate(Vector3* result, Vector3* a);
|
void Vector3_Negate(Vector3* result, Vector3* a);
|
||||||
|
|
||||||
|
#define Vector3_AddBy(dst, value) Vector3_Add(dst, dst, value)
|
||||||
|
#define Vector3_SubBy(dst, value) Vector3_Sub(dst, dst, value)
|
||||||
|
#define Vector3_Mul1By(dst, value) Vector3_Mul1(dst, dst, value)
|
||||||
|
#define Vector3_Mul3By(dst, value) Vector3_Mul3(dst, dst, value)
|
||||||
|
|
||||||
void Vector3_Lerp(Vector3* result, Vector3* a, Vector3* b, Real32 blend);
|
void Vector3_Lerp(Vector3* result, Vector3* a, Vector3* b, Real32 blend);
|
||||||
Real32 Vector3_Dot(Vector3* left, Vector3* right);
|
Real32 Vector3_Dot(Vector3* left, Vector3* right);
|
||||||
void Vector3_Cross(Vector3* result, Vector3* a, Vector3* b);
|
void Vector3_Cross(Vector3* result, Vector3* a, Vector3* b);
|
||||||
|
@ -735,8 +735,8 @@ void TableWidget_Recreate(GuiElement* elem) {
|
|||||||
void TableWidget_Reposition(GuiElement* elem) {
|
void TableWidget_Reposition(GuiElement* elem) {
|
||||||
TableWidget* widget = (TableWidget*)elem;
|
TableWidget* widget = (TableWidget*)elem;
|
||||||
Real32 scale = Game_GetInventoryScale();
|
Real32 scale = Game_GetInventoryScale();
|
||||||
widget->BlockSize = (Int32)(50 * Math_Sqrt(scale));
|
widget->BlockSize = (Int32)(50 * Math_SqrtF(scale));
|
||||||
widget->SelBlockExpand = 25.0f * Math_Sqrt(scale);
|
widget->SelBlockExpand = 25.0f * Math_SqrtF(scale);
|
||||||
TableWidget_UpdatePos(widget);
|
TableWidget_UpdatePos(widget);
|
||||||
TableWidget_UpdateScrollbarPos(widget);
|
TableWidget_UpdateScrollbarPos(widget);
|
||||||
}
|
}
|
||||||
|
@ -208,13 +208,12 @@ void WorldEnv_SetShadowCol(PackedCol col) {
|
|||||||
Event_RaiseInt32(&WorldEvents_EnvVarChanged, ENV_VAR_SHADOW_COL);
|
Event_RaiseInt32(&WorldEvents_EnvVarChanged, ENV_VAR_SHADOW_COL);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define Respawn_NotFound -10000.0f
|
|
||||||
Real32 Respawn_HighestFreeY(AABB* bb) {
|
Real32 Respawn_HighestFreeY(AABB* bb) {
|
||||||
Int32 minX = Math_Floor(bb->Min.X), maxX = Math_Floor(bb->Max.X);
|
Int32 minX = Math_Floor(bb->Min.X), maxX = Math_Floor(bb->Max.X);
|
||||||
Int32 minY = Math_Floor(bb->Min.Y), maxY = Math_Floor(bb->Max.Y);
|
Int32 minY = Math_Floor(bb->Min.Y), maxY = Math_Floor(bb->Max.Y);
|
||||||
Int32 minZ = Math_Floor(bb->Min.Z), maxZ = Math_Floor(bb->Max.Z);
|
Int32 minZ = Math_Floor(bb->Min.Z), maxZ = Math_Floor(bb->Max.Z);
|
||||||
|
|
||||||
Real32 spawnY = Respawn_NotFound;
|
Real32 spawnY = RESPAWN_NOT_FOUND;
|
||||||
AABB blockBB;
|
AABB blockBB;
|
||||||
Int32 x, y, z;
|
Int32 x, y, z;
|
||||||
Vector3 pos;
|
Vector3 pos;
|
||||||
@ -248,7 +247,7 @@ Vector3 Respawn_FindSpawnPosition(Real32 x, Real32 z, Vector3 modelSize) {
|
|||||||
Int32 y;
|
Int32 y;
|
||||||
for (y = World_Height; y >= 0; y--) {
|
for (y = World_Height; y >= 0; y--) {
|
||||||
Real32 highestY = Respawn_HighestFreeY(&bb);
|
Real32 highestY = Respawn_HighestFreeY(&bb);
|
||||||
if (highestY != Respawn_NotFound) {
|
if (highestY != RESPAWN_NOT_FOUND) {
|
||||||
spawn.Y = highestY; break;
|
spawn.Y = highestY; break;
|
||||||
}
|
}
|
||||||
bb.Min.Y -= 1.0f; bb.Max.Y -= 1.0f;
|
bb.Min.Y -= 1.0f; bb.Max.Y -= 1.0f;
|
||||||
|
@ -87,9 +87,10 @@ void WorldEnv_SetCloudsCol(PackedCol col);
|
|||||||
void WorldEnv_SetSunCol(PackedCol col);
|
void WorldEnv_SetSunCol(PackedCol col);
|
||||||
void WorldEnv_SetShadowCol(PackedCol col);
|
void WorldEnv_SetShadowCol(PackedCol col);
|
||||||
|
|
||||||
/* Finds the highest free Y coordinate in the given bounding box.*/
|
#define RESPAWN_NOT_FOUND -100000.0f
|
||||||
|
/* Finds the highest free Y coordinate in the given bounding box */
|
||||||
Real32 Respawn_HighestFreeY(AABB* bb);
|
Real32 Respawn_HighestFreeY(AABB* bb);
|
||||||
/* Finds a suitable spawn position for the entity, by iterating
|
/* Finds a suitable spawn position for the entity, by iterating
|
||||||
downwards from top of the world until the ground is found. */
|
downwards from top of the world until the ground is found */
|
||||||
Vector3 Respawn_FindSpawnPosition(Real32 x, Real32 z, Vector3 modelSize);
|
Vector3 Respawn_FindSpawnPosition(Real32 x, Real32 z, Vector3 modelSize);
|
||||||
#endif
|
#endif
|
Loading…
x
Reference in New Issue
Block a user