/// interface BodypartValueResult { value : number; weight : number; } class Bodypart extends Thing { public static WEIGHT_LOWEST = 1; public static WEIGHT_LOW = 3; public static WEIGHT_MEDIUM = 5; public static WEIGHT_HIGH = 7; public static WEIGHT_HIGHEST = 9; public static SLUTTINESS_LOWEST_SAINTLY = 0; public static SLUTTINESS_LOW_PRUDE = 25; public static SLUTTINESS_MEDIUM_AVERAGE = 50; public static SLUTTINESS_HIGH_SLUT = 75; public static SLUTTINESS_HIGHEST_WHORE = 100; public static GENDER_LOWEST_MANLIEST = 0; public static GENDER_LOW_MANLY = 25; public static GENDER_MEDIUM_ANDROGYNE = 50; public static GENDER_HIGH_FEMININE = 75; public static GENDER_HIGHEST_FEMININEST = 100; // The higher this number, the more the bodypart will be worth for health. // For instance, HEAD should be worth more than FINGERNAIL. public sorenessWeight : number = 1; // 0 to 10 // says how fucked up the bodypart is public soreness : number = 0; // How much soreness is healed every turn public sorenessPerTurn : number = 0.05; // Last turn soreness got updated public lastSorenessUpdate : number = 0; public constructor (options? : ThingOptions) { super(options); this.addGetAlterations((bp : Bodypart) => { return { Soreness : bp.soreness, GenderValue : bp.genderValue, Sluttiness : bp.getSluttiness() } }); this.addSetAlterations((bp : Bodypart, changes) => { this.soreness = changes.Soreness; this.genderValue = changes.GenderValue; this.sluttiness = changes.Sluttiness; }); } public changeSoreness (soreness : number) { this.soreness += soreness; if (this.soreness < 0) { this.soreness = 0; } } public regenerate() { this.changeSoreness(- this.sorenessPerTurn); } public getSoreness () { return this.soreness; } public getWeightedSoreness() { return this.getSoreness() * this.sorenessWeight; } public getSorenessWeight () { return this.sorenessWeight; } // These are the slots the bodypart is visible on // Should use Humanoid.SLOT_* ! public slots : Array = []; public visibleSlots : Array = []; // GenderValue is how masculine/feminine this bodypart is. // At 0 = the most masculine possible, at 100 = the most feminine eveter // 50 would be completely androgynous public genderValue : number = Bodypart.GENDER_MEDIUM_ANDROGYNE; // Like with health, the weight makes this bodypart matter more for deciding gender. // Gender presentation is not about prettiness, so, for instance, having huge breasts will // strongly push you to the "is a woman" side, even if you're manly as fuck everywhere else. // If you're too manly everywhere else, though, you'll probably end up closer on the spectrum to male // or at least androgynous, which might result in not passing. public genderWeight : number = 1; /** * Sluttiness goes from 0 to 100. * A bodypart's sluttiness is dependent on it being seen. * @type {number} */ public sluttiness : number = 10; public sluttinessWeight : number = Bodypart.WEIGHT_LOWEST; public getGenderWeight () { if (this.slots.length == 0) { return 0; } return this.genderWeight * (this.visibleSlots.length / this.slots.length); } public getGenderValue () { return this.genderValue; } public getWeightedGenderValue () { return this.getGenderValue() * this.getGenderWeight(); } public getSluttiness() { return this.sluttiness; } public getSluttinessWeight () { if (this.slots.length == 0) { return 0; } return this.sluttinessWeight * (this.visibleSlots.length / this.slots.length); } public getWeightedSluttinessValue () { return this.getSluttiness() * this.getSluttinessWeight(); } public updateVisibility () { this.visibleSlots = this.slots.slice(0); let parent = Thing.PartRelation.getLeft(this); if (parent != undefined) { let clothing = >Thing.WearRelation.getRight(parent); for (let i = 0; i < clothing.length; i++) { let covering = clothing[i].getCoveringSlots(); for (let k = 0; k < covering.length; k++) { let idx = this.visibleSlots.indexOf(covering[k]); if (idx >= 0) { this.visibleSlots.splice(idx, 1); } } if (this.visibleSlots.length == 0) break; } } } public isUncovered () { this.updateVisibility(); return this.visibleSlots.length == this.slots.length && this.slots.length > 0; } public updateStatus () { this.updateVisibility(); } public static getSoreness (thing : Thing) { let bodyparts = Thing.PartRelation.getRightType(thing, Bodypart); let soreness = 0; bodyparts.forEach((bodypart : Bodypart) => { soreness += bodypart.getWeightedSoreness(); }); return soreness; } public static getGenderValueOn (thing : Thing) : BodypartValueResult { let weight = 0; let value = 0; let bodyparts = Thing.PartRelation.getRightType(thing, Bodypart); bodyparts.forEach((bodypart : Bodypart) => { weight += bodypart.getGenderWeight(); value += bodypart.getWeightedGenderValue(); }); return { weight : weight, value : value }; } public static getSluttinessValueOn (thing : Thing) : BodypartValueResult { let weight = 0; let value = 0; let bodyparts = Thing.PartRelation.getRightType(thing, Bodypart); bodyparts.forEach((bodypart : Bodypart) => { weight += bodypart.getSluttinessWeight(); value += bodypart.getWeightedSluttinessValue(); }); return { weight : weight, value : value }; } /** * Changes the bodypart so that it matches the desired genderValue. * This needs to be implemented in all classes inheriting from Bodypart, as not all bodyparts have a simple "genderValue" to assign. * @param {number} genderValue */ public arrangeGenderValue (genderValue : number) { this.genderValue = genderValue; ( this.getPartOne()).invalidateCaches(); } /** * Attempts to increase Femininity by 5 * amount. Will read Current Gender Value and try to reassign it. * @param {number} amount */ public increaseFemininity (amount : number) { let currentGV = this.getGenderValue(); this.arrangeGenderValue(currentGV + (5 * amount)); } /** * Attempts to increase Masculinity by 5 * amount. Will read Current Gender Value and try to reassign it. * @param {number} amount */ public increaseMasculinity (amount : number) { let currentGV = this.getGenderValue(); this.arrangeGenderValue(currentGV - (5 * amount)); } }