mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-23 04:34:58 -04:00
Now some entities spawn and can be clicked on.
This commit is contained in:
parent
530e9eb09c
commit
fd454c0c01
@ -150,13 +150,14 @@
|
||||
<Compile Include="Blocks\BlockInfo.Atlas.cs" />
|
||||
<Compile Include="Blocks\DefaultSet.cs" />
|
||||
<Compile Include="Commands\SinglePlayerCommands.cs" />
|
||||
<Compile Include="Entities\AI\AI.cs" />
|
||||
<Compile Include="Entities\AI\FleeAI.cs" />
|
||||
<Compile Include="Entities\AI\HostileAI.cs" />
|
||||
<Compile Include="Entities\Components\LocalInterpComponent.cs" />
|
||||
<Compile Include="Entities\Mobs\AI\AI.cs" />
|
||||
<Compile Include="Entities\Mobs\AI\FleeAI.cs" />
|
||||
<Compile Include="Entities\Mobs\AI\HostileAI.cs" />
|
||||
<Compile Include="Entities\Components\AnimatedComponent.cs" />
|
||||
<Compile Include="Entities\Components\HacksComponent.cs" />
|
||||
<Compile Include="Entities\Components\InputComponent.cs" />
|
||||
<Compile Include="Entities\Components\InterpolatedComponent.cs" />
|
||||
<Compile Include="Entities\Components\NetInterpComponent.cs" />
|
||||
<Compile Include="Entities\Components\CollisionsComponent.cs" />
|
||||
<Compile Include="Entities\Components\NewCollisionsComponent.cs" />
|
||||
<Compile Include="Entities\Components\PhysicsComponent.cs" />
|
||||
@ -167,6 +168,7 @@
|
||||
<Compile Include="Entities\EntityList.cs" />
|
||||
<Compile Include="Entities\LocalPlayer.cs" />
|
||||
<Compile Include="Entities\LocationUpdate.cs" />
|
||||
<Compile Include="Entities\Mobs\MobEntity.cs" />
|
||||
<Compile Include="Entities\NetPlayer.cs" />
|
||||
<Compile Include="Entities\TabList.cs" />
|
||||
<Compile Include="Events\EntityEvents.cs" />
|
||||
@ -341,8 +343,9 @@
|
||||
<Folder Include="2D\Widgets\Chat" />
|
||||
<Folder Include="2D\Widgets\PlayerList" />
|
||||
<Folder Include="Blocks" />
|
||||
<Folder Include="Entities\AI" />
|
||||
<Folder Include="Entities\Mobs\AI" />
|
||||
<Folder Include="Entities\Components" />
|
||||
<Folder Include="Entities\Mobs" />
|
||||
<Folder Include="Events" />
|
||||
<Folder Include="Generator" />
|
||||
<Folder Include="Map\Lighting" />
|
||||
|
71
ClassicalSharp/Entities/Components/LocalInterpComponent.cs
Normal file
71
ClassicalSharp/Entities/Components/LocalInterpComponent.cs
Normal file
@ -0,0 +1,71 @@
|
||||
// Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
|
||||
using System;
|
||||
using ClassicalSharp.Renderers;
|
||||
using OpenTK;
|
||||
|
||||
namespace ClassicalSharp.Entities {
|
||||
|
||||
/// <summary> Entity component that performs interpolation of position and model head yaw over time. </summary>
|
||||
public sealed class LocalInterpComponent {
|
||||
|
||||
Entity entity;
|
||||
public LocalInterpComponent(Game game, Entity entity) {
|
||||
this.entity = entity;
|
||||
}
|
||||
|
||||
internal Vector3 lastPos, nextPos;
|
||||
internal float lastHeadYaw, nextHeadYaw, lastPitch, nextPitch, lastYaw, nextYaw;
|
||||
int yawStateCount;
|
||||
float[] yawStates = new float[15];
|
||||
|
||||
public void SetLocation(LocationUpdate update, bool interpolate) {
|
||||
if (update.IncludesPosition) {
|
||||
nextPos = update.RelativePosition ? nextPos + update.Pos : update.Pos;
|
||||
double blockOffset = nextPos.Y - Math.Floor(nextPos.Y);
|
||||
if (blockOffset < Entity.Adjustment)
|
||||
nextPos.Y += Entity.Adjustment;
|
||||
if (!interpolate) {
|
||||
lastPos = entity.Position = nextPos;
|
||||
}
|
||||
}
|
||||
|
||||
if (update.IncludesOrientation) {
|
||||
nextHeadYaw = update.Yaw;
|
||||
nextPitch = update.Pitch;
|
||||
if (!interpolate) {
|
||||
lastHeadYaw = entity.YawDegrees = nextHeadYaw;
|
||||
lastPitch = entity.PitchDegrees = nextPitch;
|
||||
entity.HeadYawDegrees = entity.YawDegrees;
|
||||
yawStateCount = 0;
|
||||
} else {
|
||||
for (int i = 0; i < 3; i++)
|
||||
AddYaw(Utils.LerpAngle(lastHeadYaw, nextHeadYaw, (i + 1) / 3f));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void AdvanceState() {
|
||||
lastPos = entity.Position = nextPos;
|
||||
lastHeadYaw = nextHeadYaw;
|
||||
lastYaw = nextYaw;
|
||||
lastPitch = nextPitch;
|
||||
|
||||
if (yawStateCount > 0) {
|
||||
nextYaw = yawStates[0];
|
||||
RemoveOldest(yawStates, ref yawStateCount);
|
||||
}
|
||||
}
|
||||
|
||||
void AddYaw(float state) {
|
||||
if (yawStateCount == yawStates.Length)
|
||||
RemoveOldest(yawStates, ref yawStateCount);
|
||||
yawStates[yawStateCount++] = state;
|
||||
}
|
||||
|
||||
void RemoveOldest<T>(T[] array, ref int count) {
|
||||
for (int i = 0; i < array.Length - 1; i++)
|
||||
array[i] = array[i + 1];
|
||||
count--;
|
||||
}
|
||||
}
|
||||
}
|
@ -6,10 +6,10 @@ using OpenTK;
|
||||
namespace ClassicalSharp.Entities {
|
||||
|
||||
/// <summary> Entity component that performs interpolation of position and model head yaw over time. </summary>
|
||||
public sealed class InterpolatedComponent {
|
||||
public sealed class NetInterpComponent {
|
||||
|
||||
Entity entity;
|
||||
public InterpolatedComponent(Game game, Entity entity) {
|
||||
public NetInterpComponent(Game game, Entity entity) {
|
||||
this.entity = entity;
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ namespace ClassicalSharp.Entities {
|
||||
|
||||
Vector3 lastSoundPos;
|
||||
public void Tick(bool wasOnGround) {
|
||||
Vector3 soundPos = p.nextPos;
|
||||
Vector3 soundPos = p.interp.nextPos;
|
||||
GetSound();
|
||||
if (!anyNonAir) soundPos = Utils.MaxPos();
|
||||
|
||||
@ -55,7 +55,7 @@ namespace ClassicalSharp.Entities {
|
||||
bool anyNonAir = false;
|
||||
SoundType sndType = SoundType.None;
|
||||
void GetSound() {
|
||||
Vector3 pos = p.nextPos;
|
||||
Vector3 pos = p.interp.nextPos;
|
||||
AABB bounds = p.Bounds;
|
||||
sndType = SoundType.None;
|
||||
anyNonAir = false;
|
||||
|
@ -26,12 +26,13 @@ namespace ClassicalSharp.Entities {
|
||||
get { return (float)PhysicsComponent.GetMaxHeight(physics.jumpVel); }
|
||||
}
|
||||
|
||||
internal float curWalkTime, curSwing;
|
||||
internal float curSwing;
|
||||
internal CollisionsComponent collisions;
|
||||
public HacksComponent Hacks;
|
||||
internal PhysicsComponent physics;
|
||||
internal InputComponent input;
|
||||
internal SoundComponent sound;
|
||||
internal LocalInterpComponent interp;
|
||||
|
||||
public LocalPlayer(Game game) : base(game) {
|
||||
DisplayName = game.Username;
|
||||
@ -43,6 +44,7 @@ namespace ClassicalSharp.Entities {
|
||||
physics = new PhysicsComponent(game, this);
|
||||
input = new InputComponent(game, this);
|
||||
sound = new SoundComponent(game, this);
|
||||
interp = new LocalInterpComponent(game, this);
|
||||
|
||||
physics.hacks = Hacks; input.Hacks = Hacks;
|
||||
physics.collisions = collisions;
|
||||
@ -55,9 +57,7 @@ namespace ClassicalSharp.Entities {
|
||||
&& Hacks.CanSpeed ? 1 : 0.5f;
|
||||
OldVelocity = Velocity;
|
||||
float xMoving = 0, zMoving = 0;
|
||||
lastPos = Position = nextPos;
|
||||
lastYaw = nextYaw;
|
||||
lastPitch = nextPitch;
|
||||
interp.AdvanceState();
|
||||
bool wasOnGround = onGround;
|
||||
|
||||
HandleInput(ref xMoving, ref zMoving);
|
||||
@ -65,20 +65,17 @@ namespace ClassicalSharp.Entities {
|
||||
physics.UpdateVelocityState(xMoving, zMoving);
|
||||
physics.PhysicsTick(xMoving, zMoving);
|
||||
|
||||
nextPos = Position;
|
||||
Position = lastPos;
|
||||
anim.UpdateAnimState(lastPos, nextPos, delta);
|
||||
interp.nextPos = Position; Position = interp.lastPos;
|
||||
anim.UpdateAnimState(interp.lastPos, interp.nextPos, delta);
|
||||
|
||||
CheckSkin();
|
||||
sound.Tick(wasOnGround);
|
||||
UpdateCurrentBodyYaw();
|
||||
}
|
||||
|
||||
public override void RenderModel(double deltaTime, float t) {
|
||||
anim.GetCurrentAnimState(t);
|
||||
curSwing = Utils.Lerp(anim.swingO, anim.swingN, t);
|
||||
curWalkTime = Utils.Lerp(anim.walkTimeO, anim.walkTimeN, t);
|
||||
|
||||
|
||||
if (!game.Camera.IsThirdPerson) return;
|
||||
Model.Render(this);
|
||||
}
|
||||
@ -118,65 +115,18 @@ namespace ClassicalSharp.Entities {
|
||||
}
|
||||
}
|
||||
|
||||
internal Vector3 lastPos, nextPos;
|
||||
internal float lastYaw, nextYaw, lastPitch, nextPitch;
|
||||
float newYaw, oldYaw;
|
||||
int yawStateCount;
|
||||
float[] yawStates = new float[15];
|
||||
|
||||
public override void SetLocation(LocationUpdate update, bool interpolate) {
|
||||
if (update.IncludesPosition) {
|
||||
nextPos = update.RelativePosition ? nextPos + update.Pos : update.Pos;
|
||||
double blockOffset = nextPos.Y - Math.Floor(nextPos.Y);
|
||||
if (blockOffset < Entity.Adjustment)
|
||||
nextPos.Y += Entity.Adjustment;
|
||||
if (!interpolate) {
|
||||
lastPos = Position = nextPos;
|
||||
}
|
||||
}
|
||||
if (update.IncludesOrientation) {
|
||||
nextYaw = update.Yaw;
|
||||
nextPitch = update.Pitch;
|
||||
if (!interpolate) {
|
||||
lastYaw = YawDegrees = nextYaw;
|
||||
lastPitch = PitchDegrees = nextPitch;
|
||||
HeadYawDegrees = YawDegrees;
|
||||
yawStateCount = 0;
|
||||
} else {
|
||||
for (int i = 0; i < 3; i++)
|
||||
AddYaw(Utils.LerpAngle(lastYaw, nextYaw, (i + 1) / 3f));
|
||||
}
|
||||
}
|
||||
interp.SetLocation(update, interpolate);
|
||||
}
|
||||
|
||||
/// <summary> Linearly interpolates position and rotation between the previous and next state. </summary>
|
||||
public void SetInterpPosition(float t) {
|
||||
if (!Hacks.WOMStyleHacks || !Hacks.Noclip)
|
||||
Position = Vector3.Lerp(lastPos, nextPos, t);
|
||||
Position = Vector3.Lerp(interp.lastPos, interp.nextPos, t);
|
||||
|
||||
HeadYawDegrees = Utils.LerpAngle(lastYaw, nextYaw, t);
|
||||
YawDegrees = Utils.LerpAngle(oldYaw, newYaw, t);
|
||||
PitchDegrees = Utils.LerpAngle(lastPitch, nextPitch, t);
|
||||
}
|
||||
|
||||
void AddYaw(float state) {
|
||||
if (yawStateCount == yawStates.Length)
|
||||
RemoveOldest(yawStates, ref yawStateCount);
|
||||
yawStates[yawStateCount++] = state;
|
||||
}
|
||||
|
||||
void UpdateCurrentBodyYaw() {
|
||||
oldYaw = newYaw;
|
||||
if (yawStateCount > 0) {
|
||||
newYaw = yawStates[0];
|
||||
RemoveOldest(yawStates, ref yawStateCount);
|
||||
}
|
||||
}
|
||||
|
||||
void RemoveOldest<T>(T[] array, ref int count) {
|
||||
for (int i = 0; i < array.Length - 1; i++)
|
||||
array[i] = array[i + 1];
|
||||
count--;
|
||||
HeadYawDegrees = Utils.LerpAngle(interp.lastHeadYaw, interp.nextHeadYaw, t);
|
||||
YawDegrees = Utils.LerpAngle(interp.lastYaw, interp.nextYaw, t);
|
||||
PitchDegrees = Utils.LerpAngle(interp.lastPitch, interp.nextPitch, t);
|
||||
}
|
||||
|
||||
public void Init(Game game) {
|
||||
|
@ -2,7 +2,7 @@
|
||||
using System;
|
||||
using OpenTK;
|
||||
|
||||
namespace ClassicalSharp.Entities {
|
||||
namespace ClassicalSharp.Entities.Mobs {
|
||||
|
||||
public abstract class AI {
|
||||
|
@ -2,7 +2,7 @@
|
||||
using System;
|
||||
using OpenTK;
|
||||
|
||||
namespace ClassicalSharp.Entities {
|
||||
namespace ClassicalSharp.Entities.Mobs {
|
||||
|
||||
public sealed class FleeAI : AI {
|
||||
|
@ -2,7 +2,7 @@
|
||||
using System;
|
||||
using OpenTK;
|
||||
|
||||
namespace ClassicalSharp.Entities {
|
||||
namespace ClassicalSharp.Entities.Mobs {
|
||||
|
||||
public sealed class HostileAI : AI {
|
||||
|
42
ClassicalSharp/Entities/Mobs/MobEntity.cs
Normal file
42
ClassicalSharp/Entities/Mobs/MobEntity.cs
Normal file
@ -0,0 +1,42 @@
|
||||
// Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
|
||||
using System;
|
||||
using OpenTK;
|
||||
|
||||
namespace ClassicalSharp.Entities.Mobs {
|
||||
|
||||
public class MobEntity : Entity {
|
||||
|
||||
LocalInterpComponent interp;
|
||||
public MobEntity(Game game, string model) : base(game) {
|
||||
StepSize = 0.5f;
|
||||
SetModel(model);
|
||||
interp = new LocalInterpComponent(game, this);
|
||||
}
|
||||
|
||||
public override void Despawn() { }
|
||||
public override void RenderName() { }
|
||||
|
||||
// TODO: this is just so the entities do something, remove later
|
||||
static Random rand = new Random();
|
||||
public override void Tick(double delta) {
|
||||
interp.AdvanceState();
|
||||
float inc = rand.Next(0, 10);
|
||||
LocationUpdate update = LocationUpdate.MakeOri(interp.nextHeadYaw + inc, 0);
|
||||
SetLocation(update, true);
|
||||
}
|
||||
|
||||
public override void SetLocation(LocationUpdate update, bool interpolate) {
|
||||
interp.SetLocation(update, interpolate);
|
||||
}
|
||||
|
||||
public override void RenderModel(double deltaTime, float t) {
|
||||
Position = Vector3.Lerp(interp.lastPos, interp.nextPos, t);
|
||||
HeadYawDegrees = Utils.LerpAngle(interp.lastHeadYaw, interp.nextHeadYaw, t);
|
||||
YawDegrees = Utils.LerpAngle(interp.lastYaw, interp.nextYaw, t);
|
||||
PitchDegrees = Utils.LerpAngle(interp.lastPitch, interp.nextPitch, t);
|
||||
|
||||
anim.GetCurrentAnimState(t);
|
||||
Model.Render(this);
|
||||
}
|
||||
}
|
||||
}
|
@ -6,12 +6,12 @@ namespace ClassicalSharp.Entities {
|
||||
|
||||
public sealed class NetPlayer : Player {
|
||||
|
||||
InterpolatedComponent interp;
|
||||
NetInterpComponent interp;
|
||||
public NetPlayer(string displayName, string skinName, Game game, byte id) : base(game) {
|
||||
DisplayName = displayName;
|
||||
SkinName = skinName;
|
||||
SkinIdentifier = "skin_" + id;
|
||||
interp = new InterpolatedComponent(game, this);
|
||||
interp = new NetInterpComponent(game, this);
|
||||
}
|
||||
|
||||
public override void SetLocation(LocationUpdate update, bool interpolate) {
|
||||
|
@ -84,7 +84,7 @@ namespace ClassicalSharp {
|
||||
// NOTE: We need to also test against nextPos here, because otherwise
|
||||
// we can fall through the block as collision is performed against nextPos
|
||||
AABB localBB = AABB.Make(p.Position, p.Size);
|
||||
localBB.Min.Y = Math.Min(p.nextPos.Y, localBB.Min.Y);
|
||||
localBB.Min.Y = Math.Min(p.interp.nextPos.Y, localBB.Min.Y);
|
||||
|
||||
if (p.Hacks.Noclip || !localBB.Intersects(blockBB)) return true;
|
||||
if (p.Hacks.CanPushbackBlocks && p.Hacks.PushbackPlacing && p.Hacks.Enabled)
|
||||
@ -94,7 +94,7 @@ namespace ClassicalSharp {
|
||||
if (localBB.Intersects(blockBB)) return false;
|
||||
|
||||
// Push player up if they are jumping and trying to place a block underneath them.
|
||||
Vector3 next = game.LocalPlayer.nextPos;
|
||||
Vector3 next = game.LocalPlayer.interp.nextPos;
|
||||
next.Y = pos.Y + game.BlockInfo.MaxBB[block].Y + Entity.Adjustment;
|
||||
LocationUpdate update = LocationUpdate.MakePos(next, false);
|
||||
game.LocalPlayer.SetLocation(update, false);
|
||||
|
@ -1,5 +1,8 @@
|
||||
// Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
|
||||
using System;
|
||||
using ClassicalSharp.Entities;
|
||||
using ClassicalSharp.Entities.Mobs;
|
||||
using OpenTK;
|
||||
using OpenTK.Input;
|
||||
|
||||
namespace ClassicalSharp.Mode {
|
||||
@ -40,7 +43,8 @@ namespace ClassicalSharp.Mode {
|
||||
}
|
||||
|
||||
public bool PickEntity(byte id) {
|
||||
return false;
|
||||
game.Chat.Add("PICKED ON: " + id + "," + game.Entities[id].ModelName);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -92,6 +96,17 @@ namespace ClassicalSharp.Mode {
|
||||
|
||||
public void OnNewMapLoaded(Game game) {
|
||||
game.Chat.Add("&fScore: &e" + score, MessageType.Status1);
|
||||
|
||||
string[] models = { "sheep", "pig", "skeleton", "zombie", "creeper" };
|
||||
for (int i = 0; i < 254; i++) {
|
||||
MobEntity fail = new MobEntity(game, models[rnd.Next(models.Length)]);
|
||||
float x = rnd.Next(0, game.World.Width) + 0.5f;
|
||||
float z = rnd.Next(0, game.World.Length) + 0.5f;
|
||||
|
||||
Vector3 pos = Respawn.FindSpawnPosition(game, x, z, fail.Size);
|
||||
fail.SetLocation(LocationUpdate.MakePos(pos, false), false);
|
||||
game.Entities[i] = fail;
|
||||
}
|
||||
}
|
||||
|
||||
public void Init(Game game) {
|
||||
|
@ -110,24 +110,12 @@ namespace ClassicalSharp.Singleplayer {
|
||||
this.generator = generator;
|
||||
game.Gui.SetNewScreen(new LoadingMapScreen(game, "Generating level", "Generating.."));
|
||||
generator.GenerateAsync(game, width, height, length, seed);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ResetPlayerPosition() {
|
||||
Vector3 spawn = default(Vector3);
|
||||
spawn.X = (game.World.Width / 2) + 0.5f;
|
||||
spawn.Y = game.World.Height + Entity.Adjustment;
|
||||
spawn.Z = (game.World.Length / 2) + 0.5f;
|
||||
|
||||
AABB bb = AABB.Make(spawn, game.LocalPlayer.Size);
|
||||
spawn.Y = 0;
|
||||
for (int y = game.World.Height; y >= 0; y--) {
|
||||
float highestY = Respawn.HighestFreeY(game, ref bb);
|
||||
if (highestY != float.NegativeInfinity) {
|
||||
spawn.Y = highestY; break;
|
||||
}
|
||||
bb.Min.Y -= 1; bb.Max.Y -= 1;
|
||||
}
|
||||
float x = (game.World.Width / 2) + 0.5f;
|
||||
float z = (game.World.Length / 2) + 0.5f;
|
||||
Vector3 spawn = Respawn.FindSpawnPosition(game, x, z, game.LocalPlayer.Size);
|
||||
|
||||
LocationUpdate update = LocationUpdate.MakePosAndOri(spawn, 0, 0, false);
|
||||
game.LocalPlayer.SetLocation(update, false);
|
||||
|
@ -94,14 +94,14 @@ namespace ClassicalSharp {
|
||||
static readonly float sensiFactor = 0.0002f / 3 * Utils.Rad2Deg;
|
||||
private void UpdateMouseRotation() {
|
||||
float sensitivity = sensiFactor * game.MouseSensitivity;
|
||||
float yaw = player.nextYaw + delta.X * sensitivity;
|
||||
float yaw = player.interp.nextHeadYaw + delta.X * sensitivity;
|
||||
float yAdj = game.InvertMouse ? -delta.Y * sensitivity : delta.Y * sensitivity;
|
||||
float pitch = player.nextPitch + yAdj;
|
||||
float pitch = player.interp.nextPitch + yAdj;
|
||||
LocationUpdate update = LocationUpdate.MakeOri(yaw, pitch);
|
||||
|
||||
// Need to make sure we don't cross the vertical axes, because that gets weird.
|
||||
if (update.Pitch >= 90 && update.Pitch <= 270)
|
||||
update.Pitch = player.nextPitch < 180 ? 89.9f : 270.1f;
|
||||
update.Pitch = player.interp.nextPitch < 180 ? 89.9f : 270.1f;
|
||||
game.LocalPlayer.SetLocation(update, true);
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
// Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
|
||||
using System;
|
||||
using ClassicalSharp.Entities;
|
||||
using ClassicalSharp.Physics;
|
||||
using OpenTK;
|
||||
|
||||
@ -31,5 +32,21 @@ namespace ClassicalSharp {
|
||||
}
|
||||
return spawnY;
|
||||
}
|
||||
|
||||
public static Vector3 FindSpawnPosition(Game game, float x, float z, Vector3 modelSize) {
|
||||
Vector3 spawn = new Vector3(x, 0, z);
|
||||
spawn.Y = game.World.Height + Entity.Adjustment;
|
||||
AABB bb = AABB.Make(spawn, modelSize);
|
||||
spawn.Y = 0;
|
||||
|
||||
for (int y = game.World.Height; y >= 0; y--) {
|
||||
float highestY = HighestFreeY(game, ref bb);
|
||||
if (highestY != float.NegativeInfinity) {
|
||||
spawn.Y = highestY; break;
|
||||
}
|
||||
bb.Min.Y -= 1; bb.Max.Y -= 1;
|
||||
}
|
||||
return spawn;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user