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 worldItems = new List(); List addList = new List(); List removeList = new List(); 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(); if (har != null) { har.Harvest(); } } } } public abstract class ItemRecipe { abstract public List CreateBehaviors(); } public class Item { World world; Dictionary behaviours = new Dictionary(); public World World { get { return world; } } public Item(World parent, ItemRecipe recipe) { // Get all the basics world = parent; List 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() 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 CreateBehaviors() { // Fill this out with whatever behaviors wood is supposed to have return new List(); } } public class TreeRecipe : ItemRecipe { override public List CreateBehaviors() { List retVal = new List(); 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(); } } } }