Partially implement furnace blocks
This commit is contained in:
parent
6bfa813d54
commit
11489e7f95
15
TrueCraft.API/Logic/IBurnableItem.cs
Normal file
15
TrueCraft.API/Logic/IBurnableItem.cs
Normal file
@ -0,0 +1,15 @@
|
||||
using System;
|
||||
|
||||
namespace TrueCraft.API.Logic
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes an item that can be burnt as fuel in a furnace.
|
||||
/// </summary>
|
||||
public interface IBurnableItem
|
||||
{
|
||||
/// <summary>
|
||||
/// The duration of time this item can act as fuel.
|
||||
/// </summary>
|
||||
TimeSpan BurnTime { get; }
|
||||
}
|
||||
}
|
15
TrueCraft.API/Logic/ISmeltableItem.cs
Normal file
15
TrueCraft.API/Logic/ISmeltableItem.cs
Normal file
@ -0,0 +1,15 @@
|
||||
using System;
|
||||
|
||||
namespace TrueCraft.API.Logic
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes an item that can be smelted in a furnace to produce a new item.
|
||||
/// </summary>
|
||||
public interface ISmeltableItem
|
||||
{
|
||||
/// <summary>
|
||||
/// The item this becomes when smelted.
|
||||
/// </summary>
|
||||
ItemStack SmeltingOutput { get; }
|
||||
}
|
||||
}
|
@ -122,6 +122,8 @@
|
||||
<Compile Include="Physics\IPhysicsEngine.cs" />
|
||||
<Compile Include="Physics\IPhysicsEntity.cs" />
|
||||
<Compile Include="Physics\IAABBEntity.cs" />
|
||||
<Compile Include="Logic\ISmeltableItem.cs" />
|
||||
<Compile Include="Logic\IBurnableItem.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<ItemGroup />
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using TrueCraft.API.Networking;
|
||||
|
||||
namespace TrueCraft.API.Windows
|
||||
{
|
||||
@ -6,6 +7,7 @@ namespace TrueCraft.API.Windows
|
||||
{
|
||||
event EventHandler<WindowChangeEventArgs> WindowChange;
|
||||
|
||||
IRemoteClient Client { get; set; }
|
||||
IWindowArea[] WindowAreas { get; }
|
||||
sbyte ID { get; set; }
|
||||
string Name { get; }
|
||||
|
@ -3,6 +3,13 @@ using TrueCraft.API.Logic;
|
||||
using TrueCraft.API;
|
||||
using TrueCraft.API.Networking;
|
||||
using TrueCraft.API.World;
|
||||
using TrueCraft.Core.Windows;
|
||||
using TrueCraft.API.Windows;
|
||||
using System.Collections.Generic;
|
||||
using fNbt;
|
||||
using TrueCraft.API.Server;
|
||||
using TrueCraft.Core.Networking.Packets;
|
||||
using TrueCraft.Core.Entities;
|
||||
|
||||
namespace TrueCraft.Core.Logic.Blocks
|
||||
{
|
||||
@ -20,6 +27,123 @@ namespace TrueCraft.Core.Logic.Blocks
|
||||
|
||||
public override string DisplayName { get { return "Furnace"; } }
|
||||
|
||||
protected override ItemStack[] GetDrop(BlockDescriptor descriptor, ItemStack item)
|
||||
{
|
||||
return new ItemStack[] { new ItemStack(BlockID) };
|
||||
}
|
||||
|
||||
public override void BlockMined(BlockDescriptor descriptor, BlockFace face, IWorld world, IRemoteClient user)
|
||||
{
|
||||
var entity = world.GetTileEntity(descriptor.Coordinates);
|
||||
if (entity != null)
|
||||
{
|
||||
foreach (var item in (NbtList)entity["Items"])
|
||||
{
|
||||
var manager = user.Server.GetEntityManagerForWorld(world);
|
||||
var slot = ItemStack.FromNbt((NbtCompound)item);
|
||||
manager.SpawnEntity(new ItemEntity(descriptor.Coordinates + new Vector3(0.5), slot));
|
||||
}
|
||||
world.SetTileEntity(descriptor.Coordinates, null);
|
||||
}
|
||||
base.BlockMined(descriptor, face, world, user);
|
||||
}
|
||||
|
||||
public override bool BlockRightClicked(BlockDescriptor descriptor, BlockFace face, IWorld world, IRemoteClient user)
|
||||
{
|
||||
var window = new FurnaceWindow(user.Server.Scheduler, descriptor.Coordinates,
|
||||
user.Server.ItemRepository, (InventoryWindow)user.Inventory);
|
||||
|
||||
var entity = world.GetTileEntity(descriptor.Coordinates);
|
||||
if (entity != null)
|
||||
{
|
||||
int i = 0;
|
||||
foreach (var item in (NbtList)entity["Items"])
|
||||
{
|
||||
var slot = ItemStack.FromNbt((NbtCompound)item);
|
||||
window[i++] = slot;
|
||||
}
|
||||
}
|
||||
|
||||
user.OpenWindow(window);
|
||||
|
||||
if (entity != null)
|
||||
{
|
||||
var burnTime = entity["BurnTime"].ShortValue;
|
||||
var burnTotal = entity["BurnTotal"].ShortValue;
|
||||
var cookTime = entity["CookTime"].ShortValue;
|
||||
var burnProgress = (short)(((double)burnTime / burnTotal) * 250);
|
||||
if (burnTime == 0)
|
||||
burnProgress = 0;
|
||||
if (cookTime != 0)
|
||||
window.Client.QueuePacket(new UpdateProgressPacket(window.ID,
|
||||
UpdateProgressPacket.ProgressTarget.ItemCompletion, cookTime));
|
||||
if (burnProgress != 0)
|
||||
window.Client.QueuePacket(new UpdateProgressPacket(window.ID,
|
||||
UpdateProgressPacket.ProgressTarget.AvailableHeat, burnProgress));
|
||||
}
|
||||
|
||||
window.WindowChange += (sender, e) => FurnaceWindowChanged(sender, e, world);
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool Handling = false;
|
||||
|
||||
private NbtCompound CreateTileEntity()
|
||||
{
|
||||
return new NbtCompound(new NbtTag[]
|
||||
{
|
||||
new NbtShort("BurnTime", 0),
|
||||
new NbtShort("BurnTotal", 0),
|
||||
new NbtShort("CookTime", 20),
|
||||
new NbtList("Items", new[]
|
||||
{
|
||||
ItemStack.EmptyStack.ToNbt(),
|
||||
ItemStack.EmptyStack.ToNbt(),
|
||||
ItemStack.EmptyStack.ToNbt()
|
||||
}, NbtTagType.Compound)
|
||||
});
|
||||
}
|
||||
|
||||
protected void FurnaceWindowChanged(object sender, WindowChangeEventArgs e, IWorld world)
|
||||
{
|
||||
if (Handling)
|
||||
return;
|
||||
var window = sender as FurnaceWindow;
|
||||
var index = e.SlotIndex;
|
||||
if (index >= FurnaceWindow.MainIndex)
|
||||
return;
|
||||
|
||||
Handling = true;
|
||||
window[index] = e.Value;
|
||||
|
||||
var entity = world.GetTileEntity(window.Coordinates);
|
||||
if (entity == null)
|
||||
entity = CreateTileEntity();
|
||||
|
||||
entity["Items"] = new NbtList("Items", new NbtTag[]
|
||||
{
|
||||
window[0].ToNbt(), window[1].ToNbt(), window[2].ToNbt()
|
||||
}, NbtTagType.Compound);
|
||||
|
||||
world.SetTileEntity(window.Coordinates, entity);
|
||||
|
||||
UpdateFurnaceState(window.EventScheduler, world, entity, window.ItemRepository, window.Coordinates, window, TimeSpan.Zero);
|
||||
|
||||
Handling = false;
|
||||
}
|
||||
|
||||
private void UpdateFurnaceState(IEventScheduler scheduler, IWorld world, NbtCompound tileEntity,
|
||||
IItemRepository itemRepository, Coordinates3D coords, FurnaceWindow window, TimeSpan elapsed)
|
||||
{
|
||||
if (world.GetBlockID(coords) != FurnaceBlock.BlockID && world.GetBlockID(coords) != LitFurnaceBlock.BlockID)
|
||||
{
|
||||
if (window != null && !window.IsDisposed)
|
||||
window.Dispose();
|
||||
return;
|
||||
}
|
||||
// TODO
|
||||
}
|
||||
|
||||
public override Tuple<int, int> GetTextureMap(byte metadata)
|
||||
{
|
||||
return new Tuple<int, int>(13, 2);
|
||||
|
@ -1,10 +1,11 @@
|
||||
using System;
|
||||
using TrueCraft.API.Logic;
|
||||
using TrueCraft.API;
|
||||
using TrueCraft.Core.Logic.Items;
|
||||
|
||||
namespace TrueCraft.Core.Logic.Blocks
|
||||
{
|
||||
public class IronOreBlock : BlockProvider
|
||||
public class IronOreBlock : BlockProvider, ISmeltableItem
|
||||
{
|
||||
public static readonly byte BlockID = 0x0F;
|
||||
|
||||
@ -38,5 +39,7 @@ namespace TrueCraft.Core.Logic.Blocks
|
||||
return ToolType.Pickaxe;
|
||||
}
|
||||
}
|
||||
|
||||
public ItemStack SmeltingOutput { get { return new ItemStack(IronIngotItem.ItemID); } }
|
||||
}
|
||||
}
|
@ -3,7 +3,7 @@ using TrueCraft.API.Logic;
|
||||
|
||||
namespace TrueCraft.Core.Logic.Items
|
||||
{
|
||||
public class CoalItem : ItemProvider
|
||||
public class CoalItem : ItemProvider, IBurnableItem
|
||||
{
|
||||
public static readonly short ItemID = 0x107;
|
||||
|
||||
@ -15,5 +15,7 @@ namespace TrueCraft.Core.Logic.Items
|
||||
}
|
||||
|
||||
public override string DisplayName { get { return "Coal"; } }
|
||||
|
||||
public TimeSpan BurnTime { get { return TimeSpan.FromSeconds(80); } }
|
||||
}
|
||||
}
|
@ -16,6 +16,13 @@ namespace TrueCraft.Core.Networking.Packets
|
||||
|
||||
public byte ID { get { return 0x69; } }
|
||||
|
||||
public UpdateProgressPacket(sbyte windowID, ProgressTarget target, short value)
|
||||
{
|
||||
WindowID = windowID;
|
||||
Target = target;
|
||||
Value = value;
|
||||
}
|
||||
|
||||
public sbyte WindowID;
|
||||
public ProgressTarget Target;
|
||||
/// <summary>
|
||||
|
@ -352,6 +352,7 @@
|
||||
<Compile Include="AI\WanderState.cs" />
|
||||
<Compile Include="Physics\PhysicsEngine.cs" />
|
||||
<Compile Include="Entities\WolfEntity.cs" />
|
||||
<Compile Include="Windows\FurnaceWindow.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<ItemGroup>
|
||||
|
144
TrueCraft.Core/Windows/FurnaceWindow.cs
Normal file
144
TrueCraft.Core/Windows/FurnaceWindow.cs
Normal file
@ -0,0 +1,144 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using TrueCraft.API.Windows;
|
||||
using TrueCraft.API.Logic;
|
||||
using TrueCraft.API;
|
||||
using TrueCraft.API.Server;
|
||||
|
||||
namespace TrueCraft.Core.Windows
|
||||
{
|
||||
public class FurnaceWindow : Window
|
||||
{
|
||||
public IItemRepository ItemRepository { get; set; }
|
||||
public IEventScheduler EventScheduler { get; set; }
|
||||
public Coordinates3D Coordinates { get; set; }
|
||||
|
||||
public FurnaceWindow(IEventScheduler scheduler, Coordinates3D coordinates,
|
||||
IItemRepository itemRepository, InventoryWindow inventory)
|
||||
{
|
||||
ItemRepository = itemRepository;
|
||||
EventScheduler = scheduler;
|
||||
Coordinates = coordinates;
|
||||
|
||||
WindowAreas = new[]
|
||||
{
|
||||
new WindowArea(IngredientIndex, 1, 1, 1),
|
||||
new WindowArea(FuelIndex, 1, 1, 1),
|
||||
new WindowArea(OutputIndex, 1, 1, 1),
|
||||
new WindowArea(MainIndex, 27, 9, 3),
|
||||
new WindowArea(HotbarIndex, 9, 9, 1)
|
||||
};
|
||||
inventory.MainInventory.CopyTo(MainInventory);
|
||||
inventory.Hotbar.CopyTo(Hotbar);
|
||||
foreach (var area in WindowAreas)
|
||||
area.WindowChange += (s, e) => OnWindowChange(new WindowChangeEventArgs(
|
||||
(s as WindowArea).StartIndex + e.SlotIndex, e.Value));
|
||||
Copying = false;
|
||||
inventory.WindowChange += (sender, e) =>
|
||||
{
|
||||
if (Copying) return;
|
||||
if ((e.SlotIndex >= InventoryWindow.MainIndex && e.SlotIndex < InventoryWindow.MainIndex + inventory.MainInventory.Length)
|
||||
|| (e.SlotIndex >= InventoryWindow.HotbarIndex && e.SlotIndex < InventoryWindow.HotbarIndex + inventory.Hotbar.Length))
|
||||
{
|
||||
inventory.MainInventory.CopyTo(MainInventory);
|
||||
inventory.Hotbar.CopyTo(Hotbar);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private bool Copying { get; set; }
|
||||
|
||||
public const int IngredientIndex = 0;
|
||||
public const int FuelIndex = 1;
|
||||
public const int OutputIndex = 2;
|
||||
public const int MainIndex = 3;
|
||||
public const int HotbarIndex = 30;
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return "Furnace";
|
||||
}
|
||||
}
|
||||
|
||||
public override sbyte Type
|
||||
{
|
||||
get
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
public override IWindowArea[] WindowAreas { get; protected set; }
|
||||
|
||||
public IWindowArea Ingredient
|
||||
{
|
||||
get { return WindowAreas[0]; }
|
||||
}
|
||||
|
||||
public IWindowArea Fuel
|
||||
{
|
||||
get { return WindowAreas[1]; }
|
||||
}
|
||||
|
||||
public IWindowArea Output
|
||||
{
|
||||
get { return WindowAreas[2]; }
|
||||
}
|
||||
|
||||
public IWindowArea MainInventory
|
||||
{
|
||||
get { return WindowAreas[3]; }
|
||||
}
|
||||
|
||||
public IWindowArea Hotbar
|
||||
{
|
||||
get { return WindowAreas[4]; }
|
||||
}
|
||||
|
||||
public override ItemStack[] GetSlots()
|
||||
{
|
||||
var relevantAreas = new[] { Ingredient, Fuel, Output };
|
||||
int length = relevantAreas.Sum(area => area.Length);
|
||||
var slots = new ItemStack[length];
|
||||
foreach (var windowArea in relevantAreas)
|
||||
Array.Copy(windowArea.Items, 0, slots, windowArea.StartIndex, windowArea.Length);
|
||||
return slots;
|
||||
}
|
||||
|
||||
public override void CopyToInventory(IWindow inventoryWindow)
|
||||
{
|
||||
var window = (InventoryWindow)inventoryWindow;
|
||||
Copying = true;
|
||||
MainInventory.CopyTo(window.MainInventory);
|
||||
Hotbar.CopyTo(window.Hotbar);
|
||||
Copying = false;
|
||||
}
|
||||
|
||||
protected override IWindowArea GetLinkedArea(int index, ItemStack slot)
|
||||
{
|
||||
if (index < MainIndex)
|
||||
return MainInventory;
|
||||
return Hotbar;
|
||||
}
|
||||
|
||||
public override bool PickUpStack(ItemStack slot)
|
||||
{
|
||||
var area = MainInventory;
|
||||
foreach (var item in Hotbar.Items)
|
||||
{
|
||||
if (item.Empty || (slot.ID == item.ID && slot.Metadata == item.Metadata))
|
||||
//&& item.Count + slot.Count < Item.GetMaximumStackSize(new ItemDescriptor(item.Id, item.Metadata)))) // TODO
|
||||
{
|
||||
area = Hotbar;
|
||||
break;
|
||||
}
|
||||
}
|
||||
int index = area.MoveOrMergeItem(-1, slot, null);
|
||||
return index != -1;
|
||||
}
|
||||
}
|
||||
}
|
@ -4,15 +4,20 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using TrueCraft.API.Windows;
|
||||
using TrueCraft.API;
|
||||
using TrueCraft.API.Networking;
|
||||
|
||||
namespace TrueCraft.Core.Windows
|
||||
{
|
||||
public abstract class Window : IWindow, IDisposable
|
||||
public abstract class Window : IWindow, IDisposable, IEventSubject
|
||||
{
|
||||
public abstract IWindowArea[] WindowAreas { get; protected set; }
|
||||
|
||||
public event EventHandler<WindowChangeEventArgs> WindowChange;
|
||||
|
||||
public bool IsDisposed { get; private set; }
|
||||
|
||||
public IRemoteClient Client { get; set; }
|
||||
|
||||
public virtual void MoveToAlternateArea(int index)
|
||||
{
|
||||
int fromIndex = GetAreaIndex(index);
|
||||
@ -142,6 +147,8 @@ namespace TrueCraft.Core.Windows
|
||||
WindowChange(this, e);
|
||||
}
|
||||
|
||||
public event EventHandler Disposed;
|
||||
|
||||
public virtual void Dispose()
|
||||
{
|
||||
for (int i = 0; i < WindowAreas.Length; i++)
|
||||
@ -149,6 +156,10 @@ namespace TrueCraft.Core.Windows
|
||||
WindowAreas[i].Dispose();
|
||||
}
|
||||
WindowChange = null;
|
||||
if (Disposed != null)
|
||||
Disposed(this, null);
|
||||
Client = null;
|
||||
IsDisposed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -208,6 +208,7 @@ namespace TrueCraft
|
||||
public void OpenWindow(IWindow window)
|
||||
{
|
||||
CurrentWindow = window;
|
||||
window.Client = this;
|
||||
window.ID = NextWindowID++;
|
||||
if (NextWindowID < 0) NextWindowID = 1;
|
||||
QueuePacket(new OpenWindowPacket(window.ID, window.Type, window.Name, (sbyte)window.MinecraftWasWrittenByFuckingIdiotsLength));
|
||||
|
Reference in New Issue
Block a user