私はゲームのプレーヤーインベントリシステムに取り組んでいます。
どの種類のアイテムが許可されているかを表すList<Loot>コレクションを持つ構造体スロットがあります。抽象クラスLootは、ルート可能なすべてのアイテムによってサブクラス化されます。つまり、Slot構造体の有効なContent値になります。
スロットには、 Lootのどのサブクラスに含めることができるかについて制限があることを表現したいと思います。たとえば、スロットが弾薬コンテナを表す場合、 「矢筒」や「ショットポーチ」(ラインのどこかでコンテナをサブクラス化する)などの弾薬コンテナである戦利品サブクラスのみを保持するようにします。
戦利品クラス
public abstract class Loot : GameEntity, ILootable
{
public int MaxUnitsPerStack { get; set; }
public int MaxUnitsCarriable { get; set; }
public int MaxUnitsOwnable { get; set; }
public void Stack() { }
public void Split() { }
public void Scrap() { }
}
コンテナクラス
public abstract class Container : Loot
{
public List<Slot> Slots { get; set; }
public Container(int slots)
{
this.Slots = new List<Slot>(slots);
}
}
スロット構造
public struct Slot
{
public Loot Content;
public int Count;
public List<Loot> ExclusiveLootTypes;
public Slot(Loot[] exclusiveLootTypes)
{
this.Content = null;
this.Count = 0;
List<Loot> newList;
if (exclusiveLootTypes.Count() > 0)
{
newList = new List<Loot>(exclusiveLootTypes.Count());
foreach (Loot l in exclusiveLootTypes)
{
newList.Add(l);
}
}
else { newList = new List<Loot>(); }
this.ExclusiveLootTypes = newList;
}
}
PlayerInventory
public struct PlayerInventory
{
static Dictionary<Slot, string> Slots;
static void Main()
{
Slots = new Dictionary<Slot, string>();
/* Add a bunch of slots */
Slots.Add(new Slot(/* I don't know the
syntax for this:
Quiver, Backpack */), "Backpack"); // Container
}
}
PlayerInventoryクラスのMainメソッドのSlotコンストラクター呼び出しでLootサブクラスの引数を指定する方法がわかりません。
これが明確であることを願っています。前もって感謝します。
編集
私は、David SielerのアプローチといくつかのReflectionを使用して、これを解決することができました(つまり、コンパイルすることができました)。
スロット構造
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
public struct Slot
{
private Loot _content;
private int _count;
public List ExclusiveLootTypes;
public Loot Content
{
get { return _content; }
private set
{
if ((ExclusiveLootTypes.Contains(value.GetType())) && (value.GetType().IsSubclassOf(Type.GetType("Loot"))))
{
_content = value;
}
}
}
public int Count
{
get { return _count; }
set { _count = value; }
}
public Slot(params Type[] exclusiveLootTypes)
{
this._content = null;
this._count = 0;
List newList;
if (exclusiveLootTypes.Count() > 0)
{
newList = new List(exclusiveLootTypes.Count());
foreach (Type l in exclusiveLootTypes)
{
newList.Add(l);
}
}
else { newList = new List(); }
this.ExclusiveLootTypes = newList;
}
}
スロットコンストラクターへのPlayerInventory呼び出し
Slots.Add(new Slot(typeof(Backpack)));
議論してくれた皆さん、ありがとうございました。