1
1

Liquid.ts 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. /// <reference path="../Thing.ts" />
  2. /// <reference path="../../../Elements/Classes/Say/OneOf.ts" />
  3. /// <reference path="../Rulebook.ts" />
  4. /// <reference path="../Rule.ts" />
  5. interface LiquidOptions extends ThingOptions {
  6. taste? : OneOf;
  7. }
  8. interface LiquidContainer {
  9. liquidContents : Array<Liquid>;
  10. }
  11. interface LiquidMixture {
  12. quantities : Map<any, number>;
  13. result : Liquid;
  14. quantityMultiplier? : number;
  15. firstPriority : number;
  16. priority : number;
  17. }
  18. class Liquid extends Thing {
  19. public taste : OneOf;
  20. public constructor (options? : LiquidOptions) {
  21. super(options);
  22. options = options == undefined ? {} : options;
  23. if (options.taste != undefined) {
  24. this.taste = options.taste;
  25. } else {
  26. this.taste = new OneOf(
  27. OneOf.ROTATING_RANDOM,
  28. "It goes easily through your throat with no particular taste.",
  29. "You taste nothing as it softly slides through your tongue."
  30. );
  31. }
  32. }
  33. /**
  34. * This rulebook will return a LiquidMixture
  35. * @type {Rulebook<LiquidContainer>}
  36. */
  37. public static rulebookMixing = new Rulebook<LiquidContainer>("Mixing the liquid contents of something"); // noun = LiquidContainer
  38. public static mixtures : Array<LiquidMixture> = [];
  39. public static sortedMixtures = false;
  40. public static async mix (container : LiquidContainer) {
  41. let result = await Liquid.rulebookMixing.execute({noun : container});
  42. // Did we find a liquid?
  43. if (result != undefined) {
  44. let finalQuantity = result.quantityMultiplier != undefined ?
  45. (result.quantityMultiplier * container.liquidContents.length)
  46. :
  47. (container.liquidContents.length);
  48. container.liquidContents = new Array(finalQuantity);
  49. for (let i = 0; i < finalQuantity; i++) {
  50. container.liquidContents[i] = result.result;
  51. }
  52. }
  53. }
  54. public static getMixtures () {
  55. if (Liquid.sortedMixtures) {
  56. return Liquid.mixtures;
  57. }
  58. Liquid.mixtures.sort((a, b) => {
  59. if (b.firstPriority < a.firstPriority) return -1;
  60. if (a.firstPriority < b.firstPriority) return 1;
  61. if (b.priority < a.priority) return -1;
  62. if (a.priority < b.priority) return 1;
  63. return 0;
  64. });
  65. Liquid.sortedMixtures = true;
  66. return Liquid.mixtures;
  67. }
  68. public static addMixture(mixture : LiquidMixture) {
  69. Liquid.mixtures.push(mixture);
  70. Liquid.sortedMixtures = false;
  71. }
  72. public static ruleDefaultMixing = Liquid.rulebookMixing.createAndAddRule({
  73. name : "Mixing through Mixtures",
  74. code : runner => {
  75. if (runner.noun.liquidContents.length == 0) {
  76. return;
  77. }
  78. let mixture : LiquidMixture;
  79. for (let i = 0; i < Liquid.mixtures.length; i++) {
  80. mixture = Liquid.mixtures[i];
  81. let proportions = [];
  82. let mixtureIterator = mixture.quantities.entries();
  83. for (let mixtureLiquid = mixtureIterator.next(); !mixtureLiquid.done; mixtureLiquid = mixtureIterator.next()) {
  84. let mixtureType = mixtureLiquid.value[0];
  85. let mixtureQuantity = mixtureLiquid.value[1];
  86. let matchedQuantity = 0;
  87. runner.noun.liquidContents.forEach((liquidType) => {
  88. try {
  89. if (liquidType == mixtureType ||
  90. (typeof mixtureType == "function" &&
  91. (liquidType instanceof mixtureType || mixtureType(liquidType))
  92. )
  93. ) {
  94. matchedQuantity++;
  95. }
  96. // mixtureType is not always callable
  97. } catch (e) {}
  98. });
  99. proportions.push(matchedQuantity / mixtureQuantity);
  100. }
  101. // If this is a valid mix, then every part of the recipe is represented proportionally
  102. if (proportions.every(function(element, index, array) {
  103. return element === array[0];
  104. })) {
  105. return mixture;
  106. }
  107. }
  108. }
  109. });
  110. }
  111. // class Semen extends Liquid {}
  112. // class OrcSemen extends Semen {}
  113. // class MinotaurSemen extends Semen {}
  114. // class PowerfulDrink extends Liquid {}
  115. //
  116. // let powerfulDrinkQuantities = new Map();
  117. // powerfulDrinkQuantities.set(OrcSemen, 2);
  118. // powerfulDrinkQuantities.set(MinotaurSemen, 1);
  119. // Liquid.addMixture({
  120. // firstPriority : Rule.PRIORITY_HIGHEST,
  121. // priority : Rule.PRIORITY_MEDIUM,
  122. // quantityMultiplier : 0.5,
  123. // result : new PowerfulDrink("Powerful Drink"),
  124. // quantities : powerfulDrinkQuantities
  125. // });
  126. // let recipient = new Recipient("Cup");
  127. // recipient.liquidContents.push(new OrcSemen("Semen of the Chief"));
  128. // recipient.liquidContents.push(new OrcSemen("Semen of the Chief"));
  129. // recipient.liquidContents.push(new OrcSemen("Semen of the Chief"));
  130. // recipient.liquidContents.push(new OrcSemen("Semen of the Chief"));
  131. // recipient.liquidContents.push(new MinotaurSemen("Semen of Harold"));
  132. // recipient.liquidContents.push(new MinotaurSemen("Semen of Harold"));
  133. //
  134. // {
  135. // Settings.setDebug(false);
  136. // let t1 = performance.now();
  137. // let t0 = performance.now();
  138. // Liquid.mix(recipient);
  139. // t1 = performance.now();
  140. // console.log(t1 - t0);
  141. // }