Skip to main content
Updated for naming consistency between the code and text body. (code used `class DropBundle` but text kept referring to `CompositeItem`). I felt that `DropBundle` was a more intuitive name than `CompositeItem`, so chose to standardize to that one.
Source Link

You are on the right track. That is where I would start. All of your components share the identifier and quantity. It makes sense to add chance property and use composite pattern.

public class Droppable
{
    public string Name { get; private set; }
    public uint QTY { get; private set; }
    public float Chance { get; private set; }

    public Droppable(string name, float chance, uint qty)
    {
      this.Name = name;
      this.QTY = qty;
      this.Chance = chance;
    }

    public virtual bool ShouldDrop()
    {
    // random drop check
    }
}

You can then create your loot table extending Droppable component.

public class DropBundle extends Droppable
{
    public bool CollectAll { get; private set; }
    private List<Droppable> _items;

    public DropBundle(string name, float chance, uint qty, bool collectAll, List<Droppable> items): base(name, chance, qty)
    {
        CollectAll = collectAll
        _items = items;
    }

    public override bool ShouldDrop()
    {
    // random drop check and if yeas run should drop check for other items
    }
}

You also need your item class that would also extend Droppable

public class DropItem extends Droppable
{

   public override bool ShouldDrop()
   {
      // random drop check
   }
}

Notice CompositeItemDropBundle holds references to other Droppable components. That means you can then next them as much as you want, eg.:

  • 5% of finding 10 gold coin (DropItem)
  • 10% of finding a coin (CompositeItemDropBundle) wich can be either gold (20%) or silver (80%)
  • 20% of finding a chest (CompositeItemDropBundle) that can have 10% chance of finding a coin (CompositeItemDropBundle) which can be either gold, silver or copper, etc.

All of those scenerios are then possible without changing dependency tree too much. The only thing you have to remember is obviously implement randomisation and keep in mind that sum of chances of nested droppables should be 1 (100%) for simplicity sake.

Another great advantage of using composite pattern is ability to later on use that implementation for data you can dynamically read from static XML (or JSON) file.

You are on the right track. That is where I would start. All of your components share the identifier and quantity. It makes sense to add chance property and use composite pattern.

public class Droppable
{
    public string Name { get; private set; }
    public uint QTY { get; private set; }
    public float Chance { get; private set; }

    public Droppable(string name, float chance, uint qty)
    {
      this.Name = name;
      this.QTY = qty;
      this.Chance = chance;
    }

    public virtual bool ShouldDrop()
    {
    // random drop check
    }
}

You can then create your loot table extending Droppable component.

public class DropBundle extends Droppable
{
    public bool CollectAll { get; private set; }
    private List<Droppable> _items;

    public DropBundle(string name, float chance, uint qty, bool collectAll, List<Droppable> items): base(name, chance, qty)
    {
        CollectAll = collectAll
        _items = items;
    }

    public override bool ShouldDrop()
    {
    // random drop check and if yeas run should drop check for other items
    }
}

You also need your item class that would also extend Droppable

public class DropItem extends Droppable
{

   public override bool ShouldDrop()
   {
      // random drop check
   }
}

Notice CompositeItem holds references to other Droppable components. That means you can then next them as much as you want, eg.:

  • 5% of finding 10 gold coin (DropItem)
  • 10% of finding a coin (CompositeItem) wich can be either gold (20%) or silver (80%)
  • 20% of finding a chest (CompositeItem) that can have 10% chance of finding a coin (CompositeItem) which can be either gold, silver or copper, etc.

All of those scenerios are then possible without changing dependency tree too much. The only thing you have to remember is obviously implement randomisation and keep in mind that sum of chances of nested droppables should be 1 (100%) for simplicity sake.

Another great advantage of using composite pattern is ability to later on use that implementation for data you can dynamically read from static XML (or JSON) file.

You are on the right track. That is where I would start. All of your components share the identifier and quantity. It makes sense to add chance property and use composite pattern.

public class Droppable
{
    public string Name { get; private set; }
    public uint QTY { get; private set; }
    public float Chance { get; private set; }

    public Droppable(string name, float chance, uint qty)
    {
      this.Name = name;
      this.QTY = qty;
      this.Chance = chance;
    }

    public virtual bool ShouldDrop()
    {
    // random drop check
    }
}

You can then create your loot table extending Droppable component.

public class DropBundle extends Droppable
{
    public bool CollectAll { get; private set; }
    private List<Droppable> _items;

    public DropBundle(string name, float chance, uint qty, bool collectAll, List<Droppable> items): base(name, chance, qty)
    {
        CollectAll = collectAll
        _items = items;
    }

    public override bool ShouldDrop()
    {
    // random drop check and if yeas run should drop check for other items
    }
}

You also need your item class that would also extend Droppable

public class DropItem extends Droppable
{

   public override bool ShouldDrop()
   {
      // random drop check
   }
}

Notice DropBundle holds references to other Droppable components. That means you can then next them as much as you want, eg.:

  • 5% of finding 10 gold coin (DropItem)
  • 10% of finding a coin (DropBundle) wich can be either gold (20%) or silver (80%)
  • 20% of finding a chest (DropBundle) that can have 10% chance of finding a coin (DropBundle) which can be either gold, silver or copper, etc.

All of those scenerios are then possible without changing dependency tree too much. The only thing you have to remember is obviously implement randomisation and keep in mind that sum of chances of nested droppables should be 1 (100%) for simplicity sake.

Another great advantage of using composite pattern is ability to later on use that implementation for data you can dynamically read from static XML (or JSON) file.

Source Link

You are on the right track. That is where I would start. All of your components share the identifier and quantity. It makes sense to add chance property and use composite pattern.

public class Droppable
{
    public string Name { get; private set; }
    public uint QTY { get; private set; }
    public float Chance { get; private set; }

    public Droppable(string name, float chance, uint qty)
    {
      this.Name = name;
      this.QTY = qty;
      this.Chance = chance;
    }

    public virtual bool ShouldDrop()
    {
    // random drop check
    }
}

You can then create your loot table extending Droppable component.

public class DropBundle extends Droppable
{
    public bool CollectAll { get; private set; }
    private List<Droppable> _items;

    public DropBundle(string name, float chance, uint qty, bool collectAll, List<Droppable> items): base(name, chance, qty)
    {
        CollectAll = collectAll
        _items = items;
    }

    public override bool ShouldDrop()
    {
    // random drop check and if yeas run should drop check for other items
    }
}

You also need your item class that would also extend Droppable

public class DropItem extends Droppable
{

   public override bool ShouldDrop()
   {
      // random drop check
   }
}

Notice CompositeItem holds references to other Droppable components. That means you can then next them as much as you want, eg.:

  • 5% of finding 10 gold coin (DropItem)
  • 10% of finding a coin (CompositeItem) wich can be either gold (20%) or silver (80%)
  • 20% of finding a chest (CompositeItem) that can have 10% chance of finding a coin (CompositeItem) which can be either gold, silver or copper, etc.

All of those scenerios are then possible without changing dependency tree too much. The only thing you have to remember is obviously implement randomisation and keep in mind that sum of chances of nested droppables should be 1 (100%) for simplicity sake.

Another great advantage of using composite pattern is ability to later on use that implementation for data you can dynamically read from static XML (or JSON) file.