Add support for signs

This commit is contained in:
Drew DeVault 2015-05-03 16:02:47 -06:00
parent 08d2e88ab9
commit e5207c6dec
13 changed files with 197 additions and 29 deletions

View File

@ -2,6 +2,7 @@
using TrueCraft.API.World;
using TrueCraft.API.Networking;
using TrueCraft.API.Server;
using fNbt;
namespace TrueCraft.API.Logic
{
@ -23,5 +24,7 @@ namespace TrueCraft.API.Logic
void BlockMined(BlockDescriptor descriptor, BlockFace face, IWorld world, IRemoteClient user);
void BlockUpdate(BlockDescriptor descriptor, BlockDescriptor source, IMultiplayerServer server, IWorld world);
void BlockScheduledEvent(BlockDescriptor descriptor, IWorld world, object data);
void BlockLoadedFromChunk(BlockDescriptor descriptor, IWorld world);
void TileEntityLoadedForClient(BlockDescriptor descriptor, IWorld world, NbtCompound compound, IRemoteClient client);
}
}

View File

@ -1,15 +1,20 @@
using System;
using fNbt;
using System.Collections.Generic;
namespace TrueCraft.API.World
{
public interface IChunk
{
int X { get; }
int Z { get; }
Coordinates2D Coordinates { get; set; }
bool IsModified { get; set; }
int[] HeightMap { get; }
byte[] Biomes { get; }
DateTime LastAccessed { get; set; }
byte[] Blocks { get; }
Dictionary<Coordinates3D, NbtCompound> TileEntities { get; set; }
NibbleArray Metadata { get; }
NibbleArray BlockLight { get; }
NibbleArray SkyLight { get; }
@ -21,5 +26,7 @@ namespace TrueCraft.API.World
void SetMetadata(Coordinates3D coordinates, byte value);
void SetSkyLight(Coordinates3D coordinates, byte value);
void SetBlockLight(Coordinates3D coordinates, byte value);
NbtCompound GetTileEntity(Coordinates3D coordinates);
void SetTileEntity(Coordinates3D coordinates, NbtCompound value);
}
}

View File

@ -1,5 +1,6 @@
using System;
using TrueCraft.API.Logic;
using fNbt;
namespace TrueCraft.API.World
{
@ -23,12 +24,14 @@ namespace TrueCraft.API.World
byte GetBlockID(Coordinates3D coordinates);
byte GetMetadata(Coordinates3D coordinates);
byte GetSkyLight(Coordinates3D coordinates);
NbtCompound GetTileEntity(Coordinates3D coordinates);
BlockDescriptor GetBlockData(Coordinates3D coordinates);
void SetBlockData(Coordinates3D coordinates, BlockDescriptor block);
void SetBlockID(Coordinates3D coordinates, byte value);
void SetMetadata(Coordinates3D coordinates, byte value);
void SetSkyLight(Coordinates3D coordinates, byte value);
void SetBlockLight(Coordinates3D coordinates, byte value);
void SetTileEntity(Coordinates3D coordinates, NbtCompound value);
bool IsValidPosition(Coordinates3D position);
void Save();
void Save(string path);

View File

@ -8,6 +8,7 @@ using TrueCraft.API.Entities;
using TrueCraft.API.Server;
using TrueCraft.Core.Logic.Blocks;
using System.Linq;
using fNbt;
namespace TrueCraft.Core.Logic
{
@ -107,7 +108,7 @@ namespace TrueCraft.Core.Logic
};
if (overwritable.Any(b => b == old.ID))
{
world.SetBlockID(coordinates, (byte)item.ID);
world.SetBlockID(coordinates, ID);
world.SetMetadata(coordinates, (byte)item.Metadata);
BlockPlaced(world.GetBlockData(coordinates), face, world, user);
@ -122,6 +123,16 @@ namespace TrueCraft.Core.Logic
}
}
public virtual void BlockLoadedFromChunk(BlockDescriptor descriptor, IWorld world)
{
// This space intentionally left blank
}
public virtual void TileEntityLoadedForClient(BlockDescriptor descriptor, IWorld world, NbtCompound entity, IRemoteClient client)
{
// This space intentionally left blank
}
short IItemProvider.ID
{
get

View File

@ -1,27 +0,0 @@
using System;
using TrueCraft.API.Logic;
namespace TrueCraft.Core.Logic.Blocks
{
public class SignBlock : BlockProvider
{
public static readonly byte BlockID = 0x44;
public override byte ID { get { return 0x44; } }
public override double BlastResistance { get { return 5; } }
public override double Hardness { get { return 1; } }
public override byte Luminance { get { return 0; } }
public override bool Opaque { get { return false; } }
public override string DisplayName { get { return "Sign"; } }
public override Tuple<int, int> GetTextureMap(byte metadata)
{
return new Tuple<int, int>(4, 0);
}
}
}

View File

@ -0,0 +1,64 @@
using System;
using TrueCraft.API.Logic;
using TrueCraft.API;
using TrueCraft.API.World;
using TrueCraft.API.Networking;
using TrueCraft.Core.Logic.Items;
using fNbt;
using TrueCraft.Core.Networking.Packets;
namespace TrueCraft.Core.Logic.Blocks
{
public class UprightSignBlock : BlockProvider
{
public static readonly byte BlockID = 0x3F;
public override byte ID { get { return 0x3F; } }
public override double BlastResistance { get { return 5; } }
public override double Hardness { get { return 1; } }
public override byte Luminance { get { return 0; } }
public override bool Opaque { get { return true; } } // This is weird. You can stack signs on signs in Minecraft.
public override string DisplayName { get { return "Sign"; } }
public override Tuple<int, int> GetTextureMap(byte metadata)
{
return new Tuple<int, int>(4, 0);
}
public override void BlockPlaced(BlockDescriptor descriptor, BlockFace face, IWorld world, IRemoteClient user)
{
double rotation = user.Entity.Yaw + 180 % 360;
if (rotation < 0)
rotation += 360;
world.SetMetadata(descriptor.Coordinates, (byte)(rotation / 22.5));
}
protected override ItemStack[] GetDrop(BlockDescriptor descriptor)
{
return new[] { new ItemStack(SignItem.ItemID) };
}
public override void TileEntityLoadedForClient(BlockDescriptor descriptor, IWorld world, NbtCompound entity, IRemoteClient client)
{
client.QueuePacket(new UpdateSignPacket
{
X = descriptor.Coordinates.X,
Y = (short)descriptor.Coordinates.Y,
Z = descriptor.Coordinates.Z,
Text = new[]
{
entity["Text1"].StringValue,
entity["Text2"].StringValue,
entity["Text3"].StringValue,
entity["Text4"].StringValue
}
});
}
}
}

View File

@ -0,0 +1,41 @@
using System;
using TrueCraft.API.Logic;
using TrueCraft.API;
using TrueCraft.API.World;
using TrueCraft.API.Networking;
using TrueCraft.Core.Logic.Items;
namespace TrueCraft.Core.Logic.Blocks
{
public class WallSignBlock : BlockProvider
{
public static readonly byte BlockID = 0x44;
public override byte ID { get { return 0x44; } }
public override double BlastResistance { get { return 5; } }
public override double Hardness { get { return 1; } }
public override byte Luminance { get { return 0; } }
public override bool Opaque { get { return true; } } // This is weird. You can stack signs on signs in Minecraft.
public override string DisplayName { get { return "Sign"; } }
public override Tuple<int, int> GetTextureMap(byte metadata)
{
return new Tuple<int, int>(4, 0);
}
public override void BlockPlaced(BlockDescriptor descriptor, BlockFace face, IWorld world, IRemoteClient user)
{
world.SetMetadata(descriptor.Coordinates, (byte)MathHelper.DirectionByRotationFlat(user.Entity.Yaw, true));
}
protected override ItemStack[] GetDrop(BlockDescriptor descriptor)
{
return new[] { new ItemStack(SignItem.ItemID) };
}
}
}

View File

@ -2,6 +2,8 @@ using System;
using TrueCraft.API.Logic;
using TrueCraft.API;
using TrueCraft.Core.Logic.Blocks;
using TrueCraft.API.World;
using TrueCraft.API.Networking;
namespace TrueCraft.Core.Logic.Items
{
@ -43,5 +45,19 @@ namespace TrueCraft.Core.Logic.Items
return true;
}
}
public override void ItemUsedOnBlock(Coordinates3D coordinates, ItemStack item, BlockFace face, IWorld world, IRemoteClient user)
{
if (face == BlockFace.PositiveY)
{
var provider = user.Server.BlockRepository.GetBlockProvider(UprightSignBlock.BlockID);
(provider as IItemProvider).ItemUsedOnBlock(coordinates, item, face, world, user);
}
else
{
var provider = user.Server.BlockRepository.GetBlockProvider(WallSignBlock.BlockID);
(provider as IItemProvider).ItemUsedOnBlock(coordinates, item, face, world, user);
}
}
}
}

View File

@ -272,7 +272,6 @@
<Compile Include="Logic\Blocks\SandBlock.cs" />
<Compile Include="Logic\Blocks\SandstoneBlock.cs" />
<Compile Include="Logic\Blocks\SaplingBlock.cs" />
<Compile Include="Logic\Blocks\SignBlock.cs" />
<Compile Include="Logic\Blocks\SnowBlock.cs" />
<Compile Include="Logic\Blocks\SoulSandBlock.cs" />
<Compile Include="Logic\Blocks\SpongeBlock.cs" />
@ -307,6 +306,8 @@
<Compile Include="Logic\Blocks\DoorBlock.cs" />
<Compile Include="TerrainGen\StandardGenerator.cs" />
<Compile Include="Entities\FallingGravelEntity.cs" />
<Compile Include="Logic\Blocks\WallSignBlock.cs" />
<Compile Include="Logic\Blocks\UprightSignBlock.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>

View File

@ -184,6 +184,13 @@ namespace TrueCraft.Core.World
return chunk.GetBlockLight(coordinates);
}
public NbtCompound GetTileEntity(Coordinates3D coordinates)
{
IChunk chunk;
coordinates = FindBlockPosition(coordinates, out chunk);
return chunk.GetTileEntity(coordinates);
}
public BlockDescriptor GetBlockData(Coordinates3D coordinates)
{
IChunk chunk;
@ -253,6 +260,13 @@ namespace TrueCraft.Core.World
chunk.SetBlockLight(coordinates, value);
}
public void SetTileEntity(Coordinates3D coordinates, NbtCompound value)
{
IChunk chunk;
coordinates = FindBlockPosition(coordinates, out chunk);
chunk.SetTileEntity(coordinates, value);
}
public void Save()
{
lock (Regions)

View File

@ -8,6 +8,7 @@ using TrueCraft.Core;
using TrueCraft.Core.Windows;
using TrueCraft.API.Logic;
using TrueCraft.Core.Entities;
using fNbt;
namespace TrueCraft.Handlers
{
@ -277,5 +278,23 @@ namespace TrueCraft.Handlers
break;
}
}
public static void HandleUpdateSignPacket(IPacket _packet, IRemoteClient _client, IMultiplayerServer server)
{
var packet = (UpdateSignPacket)_packet;
var client = (RemoteClient)_client;
var coords = new Coordinates3D(packet.X, packet.Y, packet.Z);
if (client.Entity.Position.DistanceTo(coords) < 10) // TODO: Reach
{
client.World.SetTileEntity(coords, new NbtCompound(new[]
{
new NbtString("Text1", packet.Text[0]),
new NbtString("Text2", packet.Text[1]),
new NbtString("Text3", packet.Text[2]),
new NbtString("Text4", packet.Text[3]),
}));
client.QueuePacket(packet);
}
}
}
}

View File

@ -30,6 +30,7 @@ namespace TrueCraft.Handlers
server.RegisterPacketHandler(new PlayerActionPacket().ID, InteractionHandlers.HandlePlayerAction);
server.RegisterPacketHandler(new ClickWindowPacket().ID, InteractionHandlers.HandleClickWindowPacket);
server.RegisterPacketHandler(new CloseWindowPacket().ID, InteractionHandlers.HandleCloseWindowPacket);
server.RegisterPacketHandler(new UpdateSignPacket().ID, InteractionHandlers.HandleUpdateSignPacket);
}
internal static void HandleKeepAlive(IPacket _packet, IRemoteClient _client, IMultiplayerServer server)

View File

@ -19,6 +19,7 @@ using System.Threading;
using TrueCraft.Core.Entities;
using System.IO;
using fNbt;
using TrueCraft.API.Logic;
namespace TrueCraft
{
@ -266,6 +267,20 @@ namespace TrueCraft
QueuePacket(new ChunkPreamblePacket(chunk.Coordinates.X, chunk.Coordinates.Z));
QueuePacket(CreatePacket(chunk));
LoadedChunks.Add(position);
foreach (var kvp in chunk.TileEntities)
{
var coords = kvp.Key;
var descriptor = new BlockDescriptor
{
Coordinates = coords + new Coordinates3D(chunk.X, 0, chunk.Z),
Metadata = chunk.GetMetadata(coords),
ID = chunk.GetBlockID(coords),
BlockLight = chunk.GetBlockLight(coords),
SkyLight = chunk.GetSkyLight(coords)
};
var provider = Server.BlockRepository.GetBlockProvider(descriptor.ID);
provider.TileEntityLoadedForClient(descriptor, World, kvp.Value, this);
}
}
internal void UnloadChunk(Coordinates2D position)