LocalPropSet.cs 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. using System;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. namespace DunGen
  5. {
  6. public enum LocalPropSetCountMode
  7. {
  8. Random,
  9. DepthBased,
  10. DepthMultiply,
  11. }
  12. public delegate int GetPropCountDelegate(LocalPropSet propSet, RandomStream randomStream, Tile tile);
  13. [AddComponentMenu("DunGen/Random Props/Local Prop Set")]
  14. public class LocalPropSet : RandomProp
  15. {
  16. private static readonly Dictionary<LocalPropSetCountMode, GetPropCountDelegate> GetCountMethods = new Dictionary<LocalPropSetCountMode, GetPropCountDelegate>();
  17. [AcceptGameObjectTypes(GameObjectFilter.Scene)]
  18. public GameObjectChanceTable Props = new GameObjectChanceTable();
  19. public IntRange PropCount = new IntRange(1, 1);
  20. public LocalPropSetCountMode CountMode;
  21. public AnimationCurve CountDepthCurve = AnimationCurve.Linear(0, 0, 1, 1);
  22. public override void Process(RandomStream randomStream, Tile tile, ref List<GameObject> spawnedObjects)
  23. {
  24. var propTable = Props.Clone();
  25. if (!GetCountMethods.TryGetValue(CountMode, out var getCountDelegate))
  26. throw new NotImplementedException("LocalPropSet count mode \"" + CountMode + "\" is not yet implemented");
  27. int count = getCountDelegate(this, randomStream, tile);
  28. var toKeep = new List<GameObject>(count);
  29. for (int i = 0; i < count; i++)
  30. {
  31. // allowNullSelection is true so that we can treat empty entries as "no prop"
  32. var chosenEntry = propTable.GetRandom(randomStream,
  33. tile.Placement.IsOnMainPath,
  34. tile.Placement.NormalizedDepth,
  35. previouslyChosen: null,
  36. allowImmediateRepeats: true,
  37. removeFromTable: true,
  38. allowNullSelection: true);
  39. if (chosenEntry != null && chosenEntry.Value != null)
  40. toKeep.Add(chosenEntry.Value);
  41. }
  42. foreach (var prop in Props.Weights)
  43. {
  44. if (prop.Value == null)
  45. continue;
  46. bool isActive = toKeep.Contains(prop.Value);
  47. prop.Value.SetActive(isActive);
  48. }
  49. }
  50. #region GetCount Methods
  51. static LocalPropSet()
  52. {
  53. GetCountMethods[LocalPropSetCountMode.Random] = GetCountRandom;
  54. GetCountMethods[LocalPropSetCountMode.DepthBased] = GetCountDepthBased;
  55. GetCountMethods[LocalPropSetCountMode.DepthMultiply] = GetCountDepthMultiply;
  56. }
  57. private static int GetCountRandom(LocalPropSet propSet, RandomStream randomStream, Tile tile)
  58. {
  59. int count = propSet.PropCount.GetRandom(randomStream);
  60. count = Mathf.Clamp(count, 0, propSet.Props.Weights.Count);
  61. return count;
  62. }
  63. private static int GetCountDepthBased(LocalPropSet propSet, RandomStream randomStream, Tile tile)
  64. {
  65. float curveValue = Mathf.Clamp(propSet.CountDepthCurve.Evaluate(tile.Placement.NormalizedPathDepth), 0, 1);
  66. int count = Mathf.RoundToInt(Mathf.Lerp(propSet.PropCount.Min, propSet.PropCount.Max, curveValue));
  67. return count;
  68. }
  69. private static int GetCountDepthMultiply(LocalPropSet propSet, RandomStream randomStream, Tile tile)
  70. {
  71. float curveValue = Mathf.Clamp(propSet.CountDepthCurve.Evaluate(tile.Placement.NormalizedPathDepth), 0, 1);
  72. int count = GetCountRandom(propSet, randomStream, tile);
  73. count = Mathf.RoundToInt(count * curveValue);
  74. return count;
  75. }
  76. #endregion
  77. }
  78. }