1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5.  
  6. namespace Zeritor
  7. {
  8.     public class Behaviour
  9.     {
  10.         protected Item owner;
  11.  
  12.         public Behaviour()
  13.         {
  14.             // base class, does nothing.
  15.         }
  16.  
  17.         public void Attach(Item item)
  18.         {
  19.             owner = item;
  20.         }
  21.     }
  22.  
  23.     public class Harvestable : Behaviour
  24.     {
  25.         public Harvestable()
  26.         {
  27.             // This is just a base class so it doesn't do anything?
  28.         }
  29.  
  30.         public virtual void Harvest()
  31.         {
  32.            // maybe log that the class was not set correctly
  33.         }
  34.     }
  35.  
  36.     public class HarvestReplace : Harvestable
  37.     {
  38.         ItemRecipe replaceWith;
  39.  
  40.         public HarvestReplace(ItemRecipe replaceWith)
  41.         {
  42.              this.replaceWith = replaceWith;
  43.         }
  44.  
  45.         public override void Harvest()
  46.         {
  47.             owner.World.Remove(owner);
  48.  
  49.             // You'll probably need to extend this logic so the Harvestable can update his replaceWith recipe
  50.             // to take the Harvestable's position.
  51.             owner.World.AddItem(replaceWith);
  52.         }
  53.     }
  54.  
  55.     public class World
  56.     {
  57.         List<Item> worldItems = new List<Item>();
  58.         List<Item> addList = new List<Item>();
  59.         List<Item> removeList = new List<Item>();
  60.  
  61.         public void Remove( Item removeMe )
  62.         {
  63.             // Remove me (probably put me on a delete list to remove next frame and set a flag on my ass
  64.             // so no one goes using me)
  65.  
  66.             removeList.Add(removeMe);
  67.         }
  68.  
  69.         public Item AddItem( ItemRecipe recipe )
  70.         {
  71.             Item retVal = new Item(this, recipe);
  72.             addList.Add(retVal);
  73.             return retVal;
  74.         }
  75.  
  76.         public void Update()
  77.         {
  78.             // Add from addList
  79.             worldItems.AddRange(addList);
  80.             addList.Clear();
  81.  
  82.             // Purge from removeList
  83.             // There's a linq version of this that is rad, but I won't
  84.             // Obfuscate here
  85.             foreach (var item in removeList)
  86.             {
  87.                 worldItems.Remove(item);
  88.                 // Do item cleanup
  89.             }
  90.  
  91.             removeList.Clear();
  92.  
  93.             foreach (var item in worldItems)
  94.             {
  95.                 // Do a generic update.
  96.             }
  97.         }
  98.  
  99.         // This is for illustrative purposes to see how you'd get to the Harvestable behavior from an arbitrary item
  100.         public void CrazyAssTempFunctionToHarvestAllHarvestables()
  101.         {
  102.             foreach (var item in worldItems)
  103.             {
  104.                 Harvestable har = item.GetBehavior<Harvestable>();
  105.                 if (har != null)
  106.                 {
  107.                     har.Harvest();
  108.                 }
  109.             }
  110.         }
  111.     }
  112.  
  113.     public abstract class ItemRecipe
  114.     {
  115.         abstract public List<Behaviour> CreateBehaviors();
  116.     }
  117.  
  118.     public class Item
  119.     {
  120.         World world;
  121.         Dictionary<Type, Behaviour> behaviours = new Dictionary<Type, Behaviour>();
  122.  
  123.         public World World
  124.         {
  125.             get
  126.             {
  127.                 return world;
  128.             }
  129.         }
  130.  
  131.         public Item(World parent, ItemRecipe recipe)
  132.         {
  133.             // Get all the basics
  134.             world = parent;
  135.             List<Behaviour> initBehaviours = recipe.CreateBehaviors();
  136.  
  137.             foreach (var beh in initBehaviours)
  138.             {
  139.                 beh.Attach(this);
  140.                 // Get this behavior's type that is immediately inherited from Behavior
  141.                 // ie, we want to browse for behaviours like Harvestable,
  142.                 // NOT SPECIFIC BEHAVIOURS LIKE HARVESTABLE REPLACE
  143.                 Type installType = beh.GetType();
  144.                 Type baseType = installType.BaseType;
  145.                 while (baseType != typeof(Behaviour))
  146.                 {
  147.                     installType = baseType;
  148.                     baseType = installType.BaseType;
  149.                 }
  150.  
  151.                 behaviours[installType] = beh;
  152.             }      
  153.         }
  154.  
  155.         public T GetBehavior<T>() where T : class
  156.         {
  157.             Behaviour returnVal = null;
  158.             if (behaviours.TryGetValue(typeof(T), out returnVal))
  159.             {
  160.                 return returnVal as T;
  161.             }
  162.  
  163.             return null;
  164.         }
  165.     }
  166.  
  167.     public class WoodRecipe : ItemRecipe
  168.     {
  169.         override public List<Behaviour> CreateBehaviors()
  170.         {
  171.             // Fill this out with whatever behaviors wood is supposed to have
  172.             return new List<Behaviour>();
  173.         }
  174.     }
  175.  
  176.     public class TreeRecipe : ItemRecipe
  177.     {
  178.         override public List<Behaviour> CreateBehaviors()
  179.         {
  180.             List<Behaviour> retVal = new List<Behaviour>();
  181.             retVal.Add(new HarvestReplace(new WoodRecipe()));
  182.  
  183.             return retVal;
  184.         }
  185.     }
  186.  
  187.     class Program
  188.     {
  189.         static void Main(string[] args)
  190.         {
  191.  
  192.             World myWorld = new World();
  193.             myWorld.AddItem(new TreeRecipe());
  194.  
  195.             while (true)
  196.             {
  197.                 myWorld.Update();
  198.                 myWorld.CrazyAssTempFunctionToHarvestAllHarvestables();
  199.             }
  200.         }
  201.     }
  202. }