///
///
///
///
interface LiquidOptions extends ThingOptions {
taste? : OneOf;
}
interface LiquidContainer {
liquidContents : Array;
}
interface LiquidMixture {
quantities : Map;
result : Liquid;
quantityMultiplier? : number;
firstPriority : number;
priority : number;
}
class Liquid extends Thing {
public taste : OneOf;
public constructor (options? : LiquidOptions) {
super(options);
options = options == undefined ? {} : options;
if (options.taste != undefined) {
this.taste = options.taste;
} else {
this.taste = new OneOf(
OneOf.ROTATING_RANDOM,
"It goes easily through your throat with no particular taste.",
"You taste nothing as it softly slides through your tongue."
);
}
}
/**
* This rulebook will return a LiquidMixture
* @type {Rulebook}
*/
public static rulebookMixing = new Rulebook("Mixing the liquid contents of something"); // noun = LiquidContainer
public static mixtures : Array = [];
public static sortedMixtures = false;
public static async mix (container : LiquidContainer) {
let result = await Liquid.rulebookMixing.execute({noun : container});
// Did we find a liquid?
if (result != undefined) {
let finalQuantity = result.quantityMultiplier != undefined ?
(result.quantityMultiplier * container.liquidContents.length)
:
(container.liquidContents.length);
container.liquidContents = new Array(finalQuantity);
for (let i = 0; i < finalQuantity; i++) {
container.liquidContents[i] = result.result;
}
}
}
public static getMixtures () {
if (Liquid.sortedMixtures) {
return Liquid.mixtures;
}
Liquid.mixtures.sort((a, b) => {
if (b.firstPriority < a.firstPriority) return -1;
if (a.firstPriority < b.firstPriority) return 1;
if (b.priority < a.priority) return -1;
if (a.priority < b.priority) return 1;
return 0;
});
Liquid.sortedMixtures = true;
return Liquid.mixtures;
}
public static addMixture(mixture : LiquidMixture) {
Liquid.mixtures.push(mixture);
Liquid.sortedMixtures = false;
}
public static ruleDefaultMixing = Liquid.rulebookMixing.createAndAddRule({
name : "Mixing through Mixtures",
code : runner => {
if (runner.noun.liquidContents.length == 0) {
return;
}
let mixture : LiquidMixture;
for (let i = 0; i < Liquid.mixtures.length; i++) {
mixture = Liquid.mixtures[i];
let proportions = [];
let mixtureIterator = mixture.quantities.entries();
for (let mixtureLiquid = mixtureIterator.next(); !mixtureLiquid.done; mixtureLiquid = mixtureIterator.next()) {
let mixtureType = mixtureLiquid.value[0];
let mixtureQuantity = mixtureLiquid.value[1];
let matchedQuantity = 0;
runner.noun.liquidContents.forEach((liquidType) => {
try {
if (liquidType == mixtureType ||
(typeof mixtureType == "function" &&
(liquidType instanceof mixtureType || mixtureType(liquidType))
)
) {
matchedQuantity++;
}
// mixtureType is not always callable
} catch (e) {}
});
proportions.push(matchedQuantity / mixtureQuantity);
}
// If this is a valid mix, then every part of the recipe is represented proportionally
if (proportions.every(function(element, index, array) {
return element === array[0];
})) {
return mixture;
}
}
}
});
}
// class Semen extends Liquid {}
// class OrcSemen extends Semen {}
// class MinotaurSemen extends Semen {}
// class PowerfulDrink extends Liquid {}
//
// let powerfulDrinkQuantities = new Map();
// powerfulDrinkQuantities.set(OrcSemen, 2);
// powerfulDrinkQuantities.set(MinotaurSemen, 1);
// Liquid.addMixture({
// firstPriority : Rule.PRIORITY_HIGHEST,
// priority : Rule.PRIORITY_MEDIUM,
// quantityMultiplier : 0.5,
// result : new PowerfulDrink("Powerful Drink"),
// quantities : powerfulDrinkQuantities
// });
// let recipient = new Recipient("Cup");
// recipient.liquidContents.push(new OrcSemen("Semen of the Chief"));
// recipient.liquidContents.push(new OrcSemen("Semen of the Chief"));
// recipient.liquidContents.push(new OrcSemen("Semen of the Chief"));
// recipient.liquidContents.push(new OrcSemen("Semen of the Chief"));
// recipient.liquidContents.push(new MinotaurSemen("Semen of Harold"));
// recipient.liquidContents.push(new MinotaurSemen("Semen of Harold"));
//
// {
// Settings.setDebug(false);
// let t1 = performance.now();
// let t0 = performance.now();
// Liquid.mix(recipient);
// t1 = performance.now();
// console.log(t1 - t0);
// }