OVERVIEW -------- Apparel are things that can be worn on a Person's body, including permanently attached body parts. Pants, shirts, underwear, jewelry, wigs, real hair, genitalia, tattoos. APPAREL TYPES ------------- FIXME Do we actually need to define this, and make multiple types worn exclusive? Or was it just left over old notes in the old doc? COVERAGE -------- An article of apparel occupies zero or more ApparelSlots: scalp - top of head. Hair, wigs, hats. ears eyes nose mouth chin - beards, facial hair neck shoulders breasts cleavage upperBack tummy lowerBack upperHip - low-rise clothing won't cover this. So we can model whale-tails, etc. groin ass thighs knees calves ankles feet toes upper arms elbows lower arms wrists hands fingers ... as well as zero or more ApparelLayers: bodypart (cock, breasts, hair, beard, body hair, etc) onbodypart (cages, earrings, necklaces, rings, wigs, etc) underwear (panties, bra) overunderwear (pantyhose, stockings, leggings, tank tops and t-shirts) clothing (pants, button-up or loose shirts, skirts, shoes) overclothing (belts, plate carriers, etc) outerwear (coats, hats, gloves) strapped (backpacks, sachels, rifle slings) For each (layer,location), an article of apparel defines an amount of Coverage for that (layer,location): "none" No coverage at all at location. Generally used for non-default apparel states (ie pulling up a skirt). "partial" Coverage exists on the location, but lower layers can be seen through it (spaghetti straps, whale tails). "full" The location is fully covered and lower layers cannot be seen (unless they "print through"). ... as well as one or more properties: A normal standard article of apparel fully hides whatever is on lower layers, and other things can be worn on layers above it. "thin" the article will not print through a tight layer above it. However, any non-thin things beneath it will still print. "tight" non-thin apparel on lower layer prints through (ie panty-lines through leggings, bra under tight t-shirt). things should continue to print up through tight layers. "sheer" The item is see-through, and will list what can be seen beneath it.. "bulky" clothing cannot be worn on layers above it (ie a backpack, wings as a body part, etc) These statistics allow several articles of apparel to be worn in combination in such a way that outside observers will be able to notice articles that are partially concealed by other articles worn on higher layers. Some use-cases (as would appear in an inventory list to an outside observer): a tight blue t-shirt (showing the lines of a bra) - non-thin bra worn underneath a tight shirt an off-shoulder crop top (showing the straps of a pink bra) - crop top doesn't cover shoulders an unzipped leather jacket - "unzipped" state changes front coverage to partial. a pair of red satin panties (showing the bulge of a small cock and balls) - tight panties a pair of low-waisted cutoff jean shorts (showing the whale-tail of a pink thong). FIXME - a gaff, concealing a cock and balls, with clothing over it. -- this is a tough one. Somehow it needs to make the c&b "thin" (and be thin itself) so that none of it prints through clothing. This means interaction between c&b and gaff. A chest binding would work like this, too. DEFINING APPAREL ---------------- It is easiest to use one of the built-in Apparel subclasses when you define specific articles of apparel. However you may define custom apparel types if you wish, either directly in persistence defaults or by subclassing another article of Apparel (recommended). To define custom apparel types, use the setCoverage() member function of your apparel object. Subclasses may use this in their constructor. COVERAGE STATES --------------- An article of apparel can have several coverage states defined on it. The default ("DEFAULT", or null) is the one that is usually used. However, it is possible to define alternate coverage states. These alternate states are *overlaid* on the default state when they are selected. For example, to define panties with an extra state that can be selected when they are pulled aside to reveal the groin, you might use: panties.setCoverage( null, ApparelLayer.UNDERWEAR, ApparelSlot.GROIN ); this.setCoverage( null, ApparelLayer.UNDERWEAR, ApparelSlot.ASS ); this.setCoverage( "PULLED_ASIDE", ApparelLayer.UNDERWEAR, ApparelSlot.GROIN, ApparelCoverage.NONE ); THIN, TIGHT, AND SHEER APPAREL ------------------------------ When a non-thin item is worn on a layer below a tight item will "print through" the tight item as so: a tight blue t-shirt (showing the lines of a bra) a pair of red satin panties (showing the bulge of a small cock and balls) In these cases, the object that is "printing through" will show its genericName instead of its name, since the details of the object are obscured. By default, the description "showing the lines of " is used. You can change this (as in the second example) by setting the outlineDesc property on the object that is printing through: strapon.outlineDesc = "showing the bulge of"; A sheer garment cam be seen through. "A sheer negligee (through which you can see a black lace bra and a pair of black lace panties)" FIXME: This is complicated when cock/clit and balls/pussy are separate Transformable objects. It would be better if we made a composite genitals object for this purpose or something. Breasts are a special case. Unless a chest wrap is explicitly worn, they will always be apparent through clothing (unless *possibly* they are small breasts and something bulky is worn over them, but that's kind of a stretch). I think we need to just subsume breast size description into the overall character description (outside of the worn clothing list), and then have special case items that hide or augment them (chest wrap, padding, breastforms, etc). These special case items can provide an overall bonus or penalty to some kind of femininity score that is used to determine if the character looks male, female, or andro. Some of these objects (ie beard) should prevent the femininity score from going below male, etc. FIXME Define these rules better. PARTIALLY COVERED LOWER LAYERS ------------------------------ Sometimes we want to print an alternate description when only part of a lower layer is visible. Imagine for example, a bra worn below an off-shoulder top. It would be more evocative for the inventory description to print: an off-shoulder crop top (revealing the straps of a pink bra) rather than simply: an off-shoulder crop top (partially covering a pink bra) We can do this by setting a partialCoveragePrefix. When we do this, the partially covering description is changed to the given prefix when *only* the listed ApparelSlots are visible. FIXME: Give the implementation of the above example. BODY PARTS AND PASSIVE DESCRIPTION ---------------------------------- Body parts like hair and genitals are implemented as apparel, so that they can print through and peek out from beneath other clothing items too. Normally we wouldn't want inventory descriptions to print body parts. "You are wearing: Your cock" would be pretty weird! In these cases, we set the passiveDescription property on these body part objects to true. When this is done, they are not mentioned as main inventory item descriptions, and are only mentioned when they are obscured but still detectable through other clothing. WEARING MULTIPLE ARTICLES OF APPAREL ------------------------------------ Whenever you try to wear something that occupies a layer,location that already has something worn on it (even if that location has a coverage of "none" due to an alternate clothing state being selected or somesuch -- the DEFAULT state is used for this, always), the currently worn item will be auto-removed. This can be canceled or short-circuited using the pre- and post- Add and Remove functions (see GeneralInventory for usage). FIXME check this and make sure that's where it's documented. SAVING MULTIPLE ARTICLES OF APPAREL AS A COMPLETE OUTFIT -------------------------------------------------------- We'll save user-defined outfits by name to the Person's wornapparel object. The Wardrobe UI will list them in a category by themselves. It will check against the Wardrobe object(s) opposite the wornapparel, red-mark any entries for which not all items are available in the opposite wardrobe(s), and grey out entries for which none of the items are available. In implementation, these outfits will just be a list of object ids (ideally ordered from lowest layer to highest), and they'll be applied to the Person's wornapparel as if each was worn manually by the player. This will allow for example, cursed panties that won't allow the protagonist to wear their regular underwear, but everything else will wear as normal. INVENTORY ACTIONS ON APPAREL ---------------------------- FIXME The following paragraph is generic item stuff and should be documented in the appropriate place instead of here. All objects can define "actions". An "action" is a pair of functions, canAction() and doAction(). canAction will return the very short name of an action or manipulation (capitalized) that can pe performed on the object ("use", "eat", "pull aside", etc), or ""/null if that action is unavailable for some reason (can only be taken if the item is being worn, or anything else the implementor desired). doAction will be called when the action is performed (the link clicked). Items carried in inventory will show these actions in the inventory UI list (alongside take/drop if available) as well as their detail popup. Apparel will define similar actions that are available specifically when that apparel is being worn. FIXME FIXME FIXME FIXME FIXME FIXME We need some general-purpose functions to decide whether or not an action is lewd (cannot generally be performed in public), and we need to track the current location for the purposes of determining whether or not it is private. FIXME We'll also need some general-purpose functions to determine: - If any obviously feminine clothing is showing. - If any obviously masculine clothing is showing. - If anything vaguely feminine is showing. - If anything vaguely masculine/butch is showing. - If anything slutty is showing. - If anything lewd is showing. - Whether the person looks male, female, or andro. FIXME on that note, we need to define a general inventory screen that disables wear/remove/take/drop, and shows a Person's wornapparel on one side and generalinventory on the other, just for the purposes of manipulating objects during play. FIXME How to separate vaguely feminine (a pink heart tshirt) and obviously feminine (minidress) clothing? A flag on unisex clothing? Class hierarchy Unisex->VaguelyFem->Feminine? Maybe a femininity value on clothing regardless of Male/Female subclass, and if the total value of what is showing gets too high it moves from vague to obvious. Like you might get away with wearing skinny low-rider jeans *or* a pink heart tshirt, but not both at once. Yeah, and then having an obviously feminine subclass of clothing showing will cap the minimum value of that fem-showing score to a value above vague. APPAREL AND CHARACTER STATS --------------------------- A Person should have some statistics: Femininity/Masculinity (and andro in between) whether others see the character as male or female maybe gate off clothing choices and/or actions. Sluttiness/Perversion/Corruption, maybe vs wholesomeness/cuteness or something. how others treat the character also maybe gate off clothing choices and/or actions. So a person has these stats. Actions might require certain stats to take, and then would change those stats. Clothing would modify a stat while worn, but then the stat would trend towards that modified value? A greater distance between modified and unmodified values would make the stat change faster, but it would slow down the closer it got until it stopped at some percentage below the modified stat. the base stat changes would be each night or something? but what if they were ultrafemme all day and then defemmed at bedtime? we need to track it somehow... we need some sort of built in game timebase to do that. RANDOM NOTES ------------ WornApparel: implements producing a description of an item within it, including the parenthesized status (concealed by, printing through, showing outline of). getWornDesc( item ), where item is an object contained within the WornApparel. getWornDescList() will produce an array of all the items in the WornApparel, with the parenthesized status. toString() will produce a commaList of the above.