using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Zeritor
{
public class Behaviour
{
protected Item owner;
public Behaviour()
{
// base class, does nothing.
}
public void Attach(Item item)
{
owner = item;
}
}
public class Harvestable : Behaviour
{
public Harvestable()
{
// This is just a base class so it doesn't do anything?
}
public virtual void Harvest()
{
// maybe log that the class was not set correctly
}
}
public class HarvestReplace : Harvestable
{
ItemRecipe replaceWith;
public HarvestReplace(ItemRecipe replaceWith)
{
this.replaceWith = replaceWith;
}
public override void Harvest()
{
owner.World.Remove(owner);
// You'll probably need to extend this logic so the Harvestable can update his replaceWith recipe
// to take the Harvestable's position.
owner.World.AddItem(replaceWith);
}
}
public class World
{
List<Item> worldItems = new List<Item>();
List<Item> addList = new List<Item>();
List<Item> removeList = new List<Item>();
public void Remove( Item removeMe )
{
// Remove me (probably put me on a delete list to remove next frame and set a flag on my ass
// so no one goes using me)
removeList.Add(removeMe);
}
public Item AddItem( ItemRecipe recipe )
{
Item retVal = new Item(this, recipe);
addList.Add(retVal);
return retVal;
}
public void Update()
{
// Add from addList
worldItems.AddRange(addList);
addList.Clear();
// Purge from removeList
// There's a linq version of this that is rad, but I won't
// Obfuscate here
foreach (var item in removeList)
{
worldItems.Remove(item);
// Do item cleanup
}
removeList.Clear();
foreach (var item in worldItems)
{
// Do a generic update.
}
}
// This is for illustrative purposes to see how you'd get to the Harvestable behavior from an arbitrary item
public void CrazyAssTempFunctionToHarvestAllHarvestables()
{
foreach (var item in worldItems)
{
Harvestable har = item.GetBehavior<Harvestable>();
if (har != null)
{
har.Harvest();
}
}
}
}
public abstract class ItemRecipe
{
abstract public List<Behaviour> CreateBehaviors();
}
public class Item
{
World world;
Dictionary<Type, Behaviour> behaviours = new Dictionary<Type, Behaviour>();
public World World
{
get
{
return world;
}
}
public Item(World parent, ItemRecipe recipe)
{
// Get all the basics
world = parent;
List<Behaviour> initBehaviours = recipe.CreateBehaviors();
foreach (var beh in initBehaviours)
{
beh.Attach(this);
// Get this behavior's type that is immediately inherited from Behavior
// ie, we want to browse for behaviours like Harvestable,
// NOT SPECIFIC BEHAVIOURS LIKE HARVESTABLE REPLACE
Type installType = beh.GetType();
Type baseType = installType.BaseType;
while (baseType != typeof(Behaviour))
{
installType = baseType;
baseType = installType.BaseType;
}
behaviours[installType] = beh;
}
}
public T GetBehavior<T>() where T : class
{
Behaviour returnVal = null;
if (behaviours.TryGetValue(typeof(T), out returnVal))
{
return returnVal as T;
}
return null;
}
}
public class WoodRecipe : ItemRecipe
{
override public List<Behaviour> CreateBehaviors()
{
// Fill this out with whatever behaviors wood is supposed to have
return new List<Behaviour>();
}
}
public class TreeRecipe : ItemRecipe
{
override public List<Behaviour> CreateBehaviors()
{
List<Behaviour> retVal = new List<Behaviour>();
retVal.Add(new HarvestReplace(new WoodRecipe()));
return retVal;
}
}
class Program
{
static void Main(string[] args)
{
World myWorld = new World();
myWorld.AddItem(new TreeRecipe());
while (true)
{
myWorld.Update();
myWorld.CrazyAssTempFunctionToHarvestAllHarvestables();
}
}
}
}