This commit is contained in:
UnknownShadow200 2017-02-25 18:44:27 +11:00
parent 810b2e8a9a
commit 06ba0208bc
12 changed files with 146 additions and 63 deletions

View File

@ -19,6 +19,7 @@ namespace ClassicalSharp.Gui.Widgets {
}
}
/// <summary> Ensures that the input conforms to a hex colour code. </summary>
public sealed class HexColourValidator : MenuInputValidator {
public HexColourValidator() {
@ -39,7 +40,8 @@ namespace ClassicalSharp.Gui.Widgets {
return FastColour.TryParse(s, out col);
}
}
/// <summary> Ensures that the input conforms to a whole number integer. </summary>
public class IntegerValidator : MenuInputValidator {
int min, max;
@ -59,7 +61,7 @@ namespace ClassicalSharp.Gui.Widgets {
public override bool IsValidString(string s) {
int value;
if (s.Length == 1 && s[0] == '-') return true;
if (s.Length == 1 && s[0] == '-') return true; // input is just a minus sign
return Int32.TryParse(s, out value);
}

View File

@ -11,7 +11,8 @@ namespace ClassicalSharp {
/// <summary> Enumeration of all blocks in Minecraft Classic, including CPE ones. </summary>
public static class Block {
#pragma warning disable 1591
public const BlockID Air = 0;
public const BlockID Stone = 1;
public const BlockID Grass = 2;
@ -79,17 +80,24 @@ namespace ClassicalSharp {
public const BlockID Pillar = 63;
public const BlockID Crate = 64;
public const BlockID StoneBrick = 65;
#pragma warning restore 1591
public const string Names = "Air Stone Grass Dirt Cobblestone Wood Sapling Bedrock Water StillWater Lava" +
internal const string Names = "Air Stone Grass Dirt Cobblestone Wood Sapling Bedrock Water StillWater Lava" +
" StillLava Sand Gravel GoldOre IronOre CoalOre Log Leaves Sponge Glass Red Orange Yellow Lime Green" +
" Teal Aqua Cyan Blue Indigo Violet Magenta Pink Black Gray White Dandelion Rose BrownMushroom RedMushroom" +
" Gold Iron DoubleSlab Slab Brick TNT Bookshelf MossyRocks Obsidian CobblestoneSlab Rope Sandstone" +
" Snow Fire LightPink ForestGreen Brown DeepBlue Turquoise Ice CeramicTile Magma Pillar Crate StoneBrick";
/// <summary> Max block ID used in original classic. </summary>
public const BlockID MaxOriginalBlock = Block.Obsidian;
/// <summary> Number of blocks in original classic. </summary>
public const int OriginalCount = MaxOriginalBlock + 1;
/// <summary> Max block ID used in original classic plus CPE blocks. </summary>
public const BlockID MaxCpeBlock = Block.StoneBrick;
/// <summary> Number of blocks in original classic plus CPE blocks. </summary>
public const int CpeCount = MaxCpeBlock + 1;
#if USE16_BIT

View File

@ -16,40 +16,62 @@ namespace ClassicalSharp {
None, Wood, Gravel, Grass, Stone,
Metal, Glass, Cloth, Sand, Snow,
}
/// <summary> Describes how a block is rendered in the world. </summary>
public static class DrawType {
/// <summary> Completely covers blocks behind (e.g. dirt). </summary>
public const byte Opaque = 0;
/// <summary> Blocks behind show (e.g. glass). Pixels are either fully visible or invisible. </summary>
public const byte Transparent = 1;
public const byte TransparentThick = 2; // e.g. leaves render all neighbours
/// <summary> Same as Transparent, but all neighbour faces show. (e.g. leaves) </summary>
public const byte TransparentThick = 2;
/// <summary> Blocks behind show (e.g. water). Pixels blend with other blocks behind. </summary>
public const byte Translucent = 3;
/// <summary> Does not show (e.g. air). Can still be collided with. </summary>
public const byte Gas = 4;
/// <summary> Block renders as an X sprite (e.g. sapling). Pixels are either fully visible or invisible. </summary>
public const byte Sprite = 5;
}
/// <summary> Describes the interaction a block has with a player when they collide with it. </summary>
public enum CollideType : byte {
WalkThrough, // i.e. gas or sprite
SwimThrough, // i.e. liquid
Solid, // i.e. solid
/// <summary> No interaction when player collides. (typically gas or sprite blocks) </summary>
WalkThrough,
/// <summary> 'swimming'/'bobbing' interaction when player collides. (typically liquid blocks) </summary>
SwimThrough,
/// <summary> Block completely stops the player when they are moving. (typically most blocks) </summary>
Solid,
}
/// <summary> Stores various properties about the blocks in Minecraft Classic. </summary>
public partial class BlockInfo {
/// <summary> Gets whether the given block id is a liquid. (water and lava) </summary>
/// <summary> Gets whether the given block is a liquid. (water and lava) </summary>
public bool IsLiquid(BlockID block) { return block >= Block.Water && block <= Block.StillLava; }
/// <summary> Gets whether the given block blocks sunlight. </summary>
/// <summary> Gets whether the given block stops sunlight. </summary>
public bool[] BlocksLight = new bool[Block.Count];
/// <summary> Gets whether the given block should draw all it faces with a full white colour component. </summary>
/// <summary> Gets whether the given block should draw all its faces in a full white colour. </summary>
public bool[] FullBright = new bool[Block.Count];
/// <summary> Gets the name of the given block, or 'Invalid' if the block is not defined. </summary>
public string[] Name = new string[Block.Count];
/// <summary> Gets the custom fog colour that should be used when the player is standing within this block.
/// Note that this is only used for exponential fog mode. </summary>
public FastColour[] FogColour = new FastColour[Block.Count];
/// <summary> Gets the fog density for the given block. </summary>
/// <remarks> A value of 0 means this block does not apply fog. </remarks>
public float[] FogDensity = new float[Block.Count];
public CollideType[] Collide = new CollideType[Block.Count];
@ -58,8 +80,11 @@ namespace ClassicalSharp {
public byte[] LightOffset = new byte[Block.Count];
/// <summary> Gets the DrawType for the given block. </summary>
public byte[] Draw = new byte[Block.Count];
/// <summary> Gets whether the given block has an opaque draw type and is also a full tile block. </summary>
/// <remarks> Full tile block means Min of (0, 0, 0) and max of (1, 1, 1). </remarks>
public bool[] FullOpaque = new bool[Block.Count];
public uint[] DefinedCustomBlocks = new uint[Block.Count >> 5];
@ -67,9 +92,12 @@ namespace ClassicalSharp {
public SoundType[] DigSounds = new SoundType[Block.Count];
public SoundType[] StepSounds = new SoundType[Block.Count];
/// <summary> Gets whether the given block has a tinting colour applied to it when rendered. </summary>
/// <remarks> The tinting colour used is the block's fog colour. </remarks>
public bool[] Tinted = new bool[Block.Count];
/// <summary> Recalculates the initial properties and culling states for all blocks. </summary>
public void Reset(Game game) {
Init();
// TODO: Make this part of TerrainAtlas2D maybe?
@ -77,6 +105,7 @@ namespace ClassicalSharp {
RecalculateSpriteBB(fastBmp);
}
/// <summary> Calculates the initial properties and culling states for all blocks. </summary>
public void Init() {
for (int i = 0; i < DefinedCustomBlocks.Length; i++)
DefinedCustomBlocks[i] = 0;
@ -85,23 +114,18 @@ namespace ClassicalSharp {
UpdateCulling();
}
public void SetDefaultBlockPerms(InventoryPermissions place,
InventoryPermissions delete) {
/// <summary> Initialises the default blocks the player is allowed to place and delete. </summary>
public void SetDefaultPerms(InventoryPermissions place, InventoryPermissions delete) {
for (int block = Block.Stone; block <= Block.MaxDefinedBlock; block++) {
place[block] = true;
delete[block] = true;
}
place[Block.Lava] = false;
place[Block.Water] = false;
place[Block.StillLava] = false;
place[Block.StillWater] = false;
place[Block.Bedrock] = false;
delete[Block.Bedrock] = false;
delete[Block.Lava] = false;
delete[Block.Water] = false;
delete[Block.StillWater] = false;
delete[Block.StillLava] = false;
place[Block.Lava] = false; delete[Block.Lava] = false;
place[Block.Water] = false; delete[Block.Water] = false;
place[Block.StillLava] = false; delete[Block.StillLava] = false;
place[Block.StillWater] = false; delete[Block.StillWater] = false;
place[Block.Bedrock] = false; delete[Block.Bedrock] = false;
}
public void SetBlockDraw(BlockID id, byte draw) {
@ -109,10 +133,11 @@ namespace ClassicalSharp {
draw = DrawType.Transparent;
Draw[id] = draw;
FullOpaque[id] = draw == DrawType.Opaque
FullOpaque[id] = draw == DrawType.Opaque
&& MinBB[id] == Vector3.Zero && MaxBB[id] == Vector3.One;
}
/// <summary> Resets the properties for the given block to their defaults. </summary>
public void ResetBlockProps(BlockID id) {
BlocksLight[id] = DefaultSet.BlocksLight(id);
FullBright[id] = DefaultSet.FullBright(id);
@ -136,12 +161,12 @@ namespace ClassicalSharp {
}
SetBlockDraw(id, Draw[id]);
CalcRenderBounds(id);
CalcRenderBounds(id);
LightOffset[id] = CalcLightOffset(id);
if (id >= Block.CpeCount) {
#if USE16_BIT
// give some random texture ids
SetTex((id * 10 + (id % 7) + 20) % 80, Side.Top, id);
SetTex((id * 8 + (id & 5) + 5 ) % 80, Side.Bottom, id);
SetSide((id * 4 + (id / 4) + 4 ) % 80, id);
@ -157,6 +182,7 @@ namespace ClassicalSharp {
}
}
/// <summary> Finds the ID of the block whose name caselessly matches the input, -1 otherwise. </summary>
public int FindID(string name) {
for (int i = 0; i < Block.Count; i++) {
if (Utils.CaselessEquals(Name[i], name)) return i;
@ -164,6 +190,7 @@ namespace ClassicalSharp {
return -1;
}
static StringBuffer buffer = new StringBuffer(64);
static string DefaultName(BlockID block) {
#if USE16_BIT

View File

@ -1,7 +1,6 @@
// Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
using System;
using ClassicalSharp.Entities;
using ClassicalSharp.GraphicsAPI;
using ClassicalSharp.Physics;
using OpenTK;
@ -10,7 +9,8 @@ namespace ClassicalSharp.Model {
public class CreeperModel : IModel {
public CreeperModel(Game window) : base(window) { }
/// <inheritdoc/>
public override void CreateParts() {
vertices = new ModelVertex[boxVertices * 6];
Head = BuildBox(MakeBoxBounds(-4, 18, -4, 4, 26, 4)
@ -33,18 +33,23 @@ namespace ClassicalSharp.Model {
.RotOrigin(0, 6, 2));
}
/// <inheritdoc/>
public override float NameYOffset { get { return 1.7f; } }
/// <inheritdoc/>
public override float GetEyeY(Entity entity) { return 22/16f; }
/// <inheritdoc/>
public override Vector3 CollisionSize {
get { return new Vector3(8/16f, 26/16f, 8/16f); }
}
/// <inheritdoc/>
public override AABB PickingBounds {
get { return new AABB(-4/16f, 0, -6/16f, 4/16f, 26/16f, 6/16f); }
}
/// <inheritdoc/>
protected override void DrawModel(Entity p) {
game.Graphics.BindTexture(GetTexture(p.MobTextureId));
DrawRotate(-p.HeadXRadians, 0, 0, Head, true);

View File

@ -26,7 +26,8 @@ namespace ClassicalSharp.Model {
/// <remarks> e.g. for players when their legs are at the peak of their swing,
/// the whole model will be moved slightly down. </remarks>
public bool Bobbing = true;
/// <summary> Whether this entity requires downloading of a skin texture. </summary>
public bool UsesSkin = true;
/// <summary> Vertical offset from the model's feet/base that the name texture should be drawn at. </summary>
@ -85,7 +86,8 @@ namespace ClassicalSharp.Model {
return Math.Min(Math.Abs(dist), Math.Min(dMin, dMax));
}
/// <summary> Renders the model based on the given entity's position and orientation. </summary>
/// <summary> Sets up the state for, then renders an entity model,
/// based on the given entity's position and orientation. </summary>
public void Render(Entity p) {
index = 0;
pos = p.Position;
@ -113,8 +115,10 @@ namespace ClassicalSharp.Model {
game.Graphics.PopMatrix();
}
/// <summary> Performs the actual rendering of an entity model. </summary>
protected abstract void DrawModel(Entity p);
/// <summary> Sends the updated vertex data to the GPU. </summary>
protected void UpdateVB() {
ModelCache cache = game.ModelCache;
game.Graphics.UpdateDynamicIndexedVb(
@ -122,6 +126,7 @@ namespace ClassicalSharp.Model {
index = 0;
}
/// <summary> Disposes of any native resources tied to this entity model. </summary>
public virtual void Dispose() { }
protected int col;

View File

@ -1,7 +1,6 @@
// Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
using System;
using ClassicalSharp.Entities;
using ClassicalSharp.GraphicsAPI;
using ClassicalSharp.Physics;
using OpenTK;
@ -10,7 +9,8 @@ namespace ClassicalSharp.Model {
public class PigModel : IModel {
public PigModel(Game window) : base(window) { }
/// <inheritdoc/>
public override void CreateParts() {
vertices = new ModelVertex[boxVertices * 6];
Head = BuildBox(MakeBoxBounds(-4, 8, -14, 4, 16, -6)
@ -32,18 +32,23 @@ namespace ClassicalSharp.Model {
.RotOrigin(0, 6, 7));
}
/// <inheritdoc/>
public override float NameYOffset { get { return 1.075f; } }
/// <inheritdoc/>
public override float GetEyeY(Entity entity) { return 12/16f; }
/// <inheritdoc/>
public override Vector3 CollisionSize {
get { return new Vector3(14/16f, 14/16f, 14/16f); }
}
/// <inheritdoc/>
public override AABB PickingBounds {
get { return new AABB(-5/16f, 0, -14/16f, 5/16f, 16/16f, 9/16f); }
}
/// <inheritdoc/>
protected override void DrawModel(Entity p) {
game.Graphics.BindTexture(GetTexture(p.MobTextureId));
DrawRotate(-p.HeadXRadians, 0, 0, Head, true);

View File

@ -3,7 +3,6 @@ using System;
using ClassicalSharp.Entities;
using ClassicalSharp.GraphicsAPI;
using ClassicalSharp.Physics;
using ClassicalSharp.Renderers;
using OpenTK;
namespace ClassicalSharp.Model {
@ -17,6 +16,7 @@ namespace ClassicalSharp.Model {
furIndex = game.ModelCache.GetTextureIndex("sheep_fur.png");
}
/// <inheritdoc/>
public override void CreateParts() {
vertices = new ModelVertex[boxVertices * 6 * 2];
MakeBaseModel();
@ -41,8 +41,7 @@ namespace ClassicalSharp.Model {
RightLegBack = BuildBox(MakeBoxBounds(1, 0, 5, 5, 12, 9)
.TexOrigin(0, 16)
.RotOrigin(0, 12, 7));
}
}
void MakeFurModel() {
FurHead = BuildBox(MakeBoxBounds(-3, -3, -3, 3, 3, 3)
@ -65,18 +64,24 @@ namespace ClassicalSharp.Model {
.RotOrigin(0, 12, 7));
}
public override float NameYOffset { get { return Fur ? 1.48125f: 1.075f; } }
/// <inheritdoc/>
public override float NameYOffset { get { return Fur ? 1.48125f: 1.075f; } }
/// <inheritdoc/>
public override float GetEyeY(Entity entity) { return 20/16f; }
/// <inheritdoc/>
public override Vector3 CollisionSize {
get { return new Vector3(10/16f, 20/16f, 10/16f); }
}
/// <inheritdoc/>
public override AABB PickingBounds {
get { return new AABB(-6/16f, 0, -13/16f, 6/16f, 23/16f, 10/16f); }
}
/// <inheritdoc/>
protected override void DrawModel(Entity p) {
IGraphicsApi gfx = game.Graphics;
gfx.BindTexture(GetTexture(p.MobTextureId));

View File

@ -1,7 +1,6 @@
// Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
using System;
using ClassicalSharp.Entities;
using ClassicalSharp.GraphicsAPI;
using ClassicalSharp.Physics;
using OpenTK;
@ -10,7 +9,8 @@ namespace ClassicalSharp.Model {
public class SpiderModel : IModel {
public SpiderModel(Game window) : base(window) { }
/// <inheritdoc/>
public override void CreateParts() {
vertices = new ModelVertex[boxVertices * 5];
Head = BuildBox(MakeBoxBounds(-4, 4, -11, 4, 12, -3)
@ -27,21 +27,27 @@ namespace ClassicalSharp.Model {
.TexOrigin(18, 0)
.RotOrigin(3, 8, 0));
}
/// <inheritdoc/>
public override float NameYOffset { get { return 1.0125f; } }
/// <inheritdoc/>
public override float GetEyeY(Entity entity) { return 8/16f; }
/// <inheritdoc/>
public override Vector3 CollisionSize {
get { return new Vector3(15/16f, 12/16f, 15/16f); }
}
/// <inheritdoc/>
public override AABB PickingBounds {
get { return new AABB(-5/16f, 0, -11/16f, 5/16f, 12/16f, 15/16f); }
}
const float quarterPi = (float)(Math.PI / 4);
const float eighthPi = (float)(Math.PI / 8);
/// <inheritdoc/>
protected override void DrawModel(Entity p) {
game.Graphics.BindTexture(GetTexture(p.MobTextureId));
DrawRotate(-p.HeadXRadians, 0, 0, Head, true);

View File

@ -84,7 +84,7 @@ namespace ClassicalSharp {
Animations = AddComponent(new Animations());
Inventory = AddComponent(new Inventory());
BlockInfo.SetDefaultBlockPerms(Inventory.CanPlace, Inventory.CanDelete);
BlockInfo.SetDefaultPerms(Inventory.CanPlace, Inventory.CanDelete);
World = new World(this);
LocalPlayer = AddComponent(new LocalPlayer(this));
Entities[EntityList.SelfID] = LocalPlayer;

View File

@ -137,7 +137,7 @@ namespace ClassicalSharp {
Inventory inv = game.Inventory;
bool hotbar = AltDown || ControlDown || ShiftDown;
if ((!hotbar && game.Camera.DoZoom(e.DeltaPrecise)) || DoFovZoom(e.DeltaPrecise) || !inv.CanChangeHeldBlock)
if ((!hotbar && game.Camera.Zoom(e.DeltaPrecise)) || DoFovZoom(e.DeltaPrecise) || !inv.CanChangeHeldBlock)
return;
ScrollHotbar(e.DeltaPrecise);
}

View File

@ -4,21 +4,27 @@ using OpenTK.Input;
namespace ClassicalSharp {
/// <summary> Enumeration of all custom key bindings. </summary>
public enum KeyBind {
#pragma warning disable 1591
Forward, Back, Left, Right, Jump, Respawn, SetSpawn, Chat,
Inventory, ToggleFog, SendChat, PauseOrExit, PlayerList,
Speed, NoClip, Fly, FlyUp, FlyDown, ExtInput, HideFps,
Screenshot, Fullscreen, ThirdPerson, HideGui, AxisLines,
ZoomScrolling, HalfSpeed, MouseLeft, MouseMiddle, MouseRight, Autorotate,
#pragma warning restore 1591
}
/// <summary> Maps a key binding to its actual key on the keyboard. </summary>
public class KeyMap {
/// <summary> Gets the actual key on the keyboard that maps to the given key binding. </summary>
public Key this[KeyBind key] {
get { return keys[(int)key]; }
set { keys[(int)key] = value; SaveKeyBindings(); }
}
/// <summary> Gets the default key on the keyboard that maps to the given key binding. </summary>
public Key GetDefault(KeyBind key) {
return defaultKeys[(int)key];
}
@ -46,6 +52,7 @@ namespace ClassicalSharp {
LoadKeyBindings();
}
void LoadKeyBindings() {
string[] names = KeyBind.GetNames(typeof(KeyBind));
for (int i = 0; i < names.Length; i++) {

View File

@ -12,8 +12,10 @@ namespace ClassicalSharp {
protected internal Matrix4 tiltM;
internal float bobbingVer, bobbingHor;
/// <summary> Calculates the projection matrix for this camera. </summary>
public abstract Matrix4 GetProjection();
/// <summary> Calculates the world/view matrix for this camera. </summary>
public abstract Matrix4 GetView();
/// <summary> Calculates the location of the camera's position in the world. </summary>
@ -23,18 +25,29 @@ namespace ClassicalSharp {
public abstract Vector2 GetCameraOrientation();
/// <summary> Whether this camera is using a third person perspective. </summary>
/// <remarks> This causes the local player to be renderered if true. </remarks>
public abstract bool IsThirdPerson { get; }
/// <remarks> Causes the player's own entity model to be renderered if true. </remarks>
public abstract bool IsThirdPerson { get; }
public virtual bool DoZoom(float deltaPrecise) { return false; }
/// <summary> Attempts to zoom the camera's position closer to or further from its origin point. </summary>
/// <returns> true if this camera handled zooming </returns>
/// <example> Third person cameras override this method to zoom in or out, and hence return true.
/// The first person camera does not perform zomming, so returns false. </example>
public virtual bool Zoom(float amount) { return false; }
/// <summary> Called every frame for the camera to update its state. </summary>
/// <example> The perspective cameras gets delta between mouse cursor's current position and the centre of the window,
/// then uses this to adjust the player's horizontal and vertical rotation. </example>
public abstract void UpdateMouse();
/// <summary> Called after the camera has regrabbed the mouse from 2D input handling. </summary>
/// <example> The perspective cameras set the mouse cursor to the centre of the window. </example>
public abstract void RegrabMouse();
/// <summary> Calculates the picked block based on the camera's current position. </summary>
/// <summary> Calculates the picked block based on the camera's current state. </summary>
public virtual void GetPickedBlock(PickedPos pos) { }
/// <summary> Adjusts the head X rotation of the player to avoid looking straight up or down. </summary>
/// <remarks> Looking straight up or down (parallel to camera up vector) can otherwise cause rendering issues. </remarks>
protected float AdjustHeadX(float value) {
if (value >= 90.0f && value <= 90.1f) return 90.1f * Utils.Deg2Rad;
if (value >= 89.9f && value <= 90.0f) return 89.9f * Utils.Deg2Rad;
@ -137,8 +150,8 @@ namespace ClassicalSharp {
bool forward;
float dist = 3;
public override bool DoZoom(float deltaPrecise) {
dist = Math.Max(dist - deltaPrecise, 2);
public override bool Zoom(float amount) {
dist = Math.Max(dist - amount, 2);
return true;
}
@ -153,7 +166,7 @@ namespace ClassicalSharp {
public override Vector2 GetCameraOrientation() {
if (!forward)
return new Vector2(player.HeadYRadians, player.HeadXRadians);
return new Vector2(player.HeadYRadians + (float)Math.PI, -player.HeadXRadians);
return new Vector2(player.HeadYRadians + (float)Math.PI, -player.HeadXRadians);
}
public override Vector3 GetCameraPos(float t) {