Search in sources :

Example 11 with OrificeModifier

use of com.lilithsthrone.game.character.body.valueEnums.OrificeModifier in project liliths-throne-public by Innoxia.

the class Body method getDescription.

/**
 * @param owner
 * @param playerKnowledgeOfThroat
 * @param playerKnowledgeOfBreasts
 * @param playerKnowledgeOfGroin
 * @return
 */
public String getDescription(GameCharacter owner) {
    StringBuilder sb = new StringBuilder();
    // Describe race:
    if (owner.isPlayer()) {
        sb.append("<p>" + "You are [pc.name], <span style='color:" + getGender().getColour().toWebHexString() + ";'>[pc.a_gender]</span> [pc.raceStage] [pc.race]. " + owner.getAppearsAsGenderDescription() + " Standing at full height, you measure [pc.heightFeetInches] ([pc.heightCm]cm).");
    } else {
        if (owner.getPlayerKnowsAreas().contains(CoverableArea.PENIS) && owner.getPlayerKnowsAreas().contains(CoverableArea.VAGINA)) {
            sb.append("<p>" + "[npc.Name] is <span style='color:" + getGender().getColour().toWebHexString() + ";'>[npc.a_gender]</span> [npc.raceStage] [npc.race]. " + owner.getAppearsAsGenderDescription() + " Standing at full height, [npc.she] measures [npc.heightFeetInches] ([npc.heightCm]cm).");
        } else {
            if (Main.game.getPlayer().hasTrait(Perk.OBSERVANT, true)) {
                sb.append("<p>" + "Thanks to your observant perk, you can detect that [npc.name] is <span style='color:" + getGender().getColour().toWebHexString() + ";'>[npc.a_gender]</span> [npc.raceStage] [npc.race]. " + owner.getAppearsAsGenderDescription() + " Standing at full height, [npc.she] measures [npc.heightFeetInches] ([npc.heightCm]cm).");
            } else {
                sb.append("<p>" + "[npc.Name] is a [npc.raceStage] [npc.race]. " + owner.getAppearsAsGenderDescription() + " Standing at full height, [npc.she] measures [npc.heightFeetInches] ([npc.heightCm]cm).");
            }
        }
    }
    sb.append("</p>");
    switch(this.getBodyMaterial()) {
        case FIRE:
            if (owner.isPlayer()) {
                sb.append("<p>" + "Your entire body, save for a small obsidian sphere in the place where your heart should be, is made out of <b style='color:" + this.getBodyMaterial().getColour().toWebHexString() + ";'>fire and smoke</b>!" + "</p>");
            } else {
                sb.append("<p>" + "[npc.Name]'s entire body, save for a small obsidian sphere in the place where [npc.her] heart should be, is made out of <b style='color:" + this.getBodyMaterial().getColour().toWebHexString() + ";'>fire and smoke</b>!" + "</p>");
            }
            break;
        case FLESH:
            break;
        case ICE:
            if (owner.isPlayer()) {
                sb.append("<p>" + "Your entire body, save for a small obsidian sphere in the place where your heart should be, is made out of <b style='color:" + this.getBodyMaterial().getColour().toWebHexString() + ";'>ice</b>!" + "</p>");
            } else {
                sb.append("<p>" + "[npc.Name]'s entire body, save for a small obsidian sphere in the place where [npc.her] heart should be, is made out of <b style='color:" + this.getBodyMaterial().getColour().toWebHexString() + ";'>ice</b>!" + "</p>");
            }
            break;
        case RUBBER:
            if (owner.isPlayer()) {
                sb.append("<p>" + "Your entire body, save for a small obsidian sphere in the place where your heart should be, is made out of <b style='color:" + this.getBodyMaterial().getColour().toWebHexString() + ";'>rubber</b>!" + "</p>");
            } else {
                sb.append("<p>" + "[npc.Name]'s entire body, save for a small obsidian sphere in the place where [npc.her] heart should be, is made out of <b style='color:" + this.getBodyMaterial().getColour().toWebHexString() + ";'>rubber</b>!" + "</p>");
            }
            break;
        case SLIME:
            if (owner.isPlayer()) {
                sb.append("<p>" + "Your entire body, save for a small, glowing sphere in the place where your heart should be, is made out of [pc.skinFullDescription(true)]!" + "</p>");
            } else {
                sb.append("<p>" + "[npc.Name]'s entire body, save for a small, glowing sphere in the place where [npc.her] heart should be, is made out of [npc.skinFullDescription(true)]!" + "</p>");
            }
            break;
    }
    // Femininity:
    if (owner.isPlayer()) {
        sb.append("<p>" + "You have ");
    } else {
        sb.append("<p>" + "[npc.She] has ");
    }
    if (Femininity.valueOf(femininity) == Femininity.MASCULINE_STRONG) {
        sb.append(UtilText.returnStringAtRandom("a <span style='color:" + Colour.MASCULINE_PLUS.toWebHexString() + ";'>very masculine</span>", "an <span style='color:" + Colour.MASCULINE_PLUS.toWebHexString() + ";'>extremely handsome</span>"));
    } else if (Femininity.valueOf(femininity) == Femininity.MASCULINE) {
        sb.append(UtilText.returnStringAtRandom("a <span style='color:" + Colour.MASCULINE.toWebHexString() + ";'>masculine</span>", "a <span style='color:" + Colour.MASCULINE.toWebHexString() + ";'>handsome</span>"));
    } else if (Femininity.valueOf(femininity) == Femininity.ANDROGYNOUS) {
        sb.append("an <span style='color:" + Colour.ANDROGYNOUS.toWebHexString() + ";'>androgynous</span>");
    } else if (Femininity.valueOf(femininity) == Femininity.FEMININE) {
        sb.append(UtilText.returnStringAtRandom("a <span style='color:" + Colour.FEMININE.toWebHexString() + ";'>pretty</span>", "a <span style='color:" + Colour.FEMININE.toWebHexString() + ";'>feminine</span>", "a <span style='color:" + Colour.FEMININE.toWebHexString() + ";'>cute</span>"));
    } else {
        sb.append(UtilText.returnStringAtRandom("a <span style='color:" + Colour.FEMININE_PLUS.toWebHexString() + ";'>very feminine</span>", "a <span style='color:" + Colour.FEMININE_PLUS.toWebHexString() + ";'>beautiful</span>", "a <span style='color:" + Colour.FEMININE_PLUS.toWebHexString() + ";'>gorgeous</span>"));
    }
    // Face and eyes:
    switch(face.getType()) {
        case HUMAN:
            sb.append(" face.");
            break;
        case ANGEL:
            sb.append(", perfectly proportioned face.");
            break;
        case DEMON_COMMON:
            sb.append(", perfectly proportioned face.");
            break;
        case IMP:
            sb.append(", impish face.");
            break;
        case DOG_MORPH:
            sb.append(", anthropomorphic dog-like face, complete with a canine muzzle.");
            break;
        case LYCAN:
            sb.append(", anthropomorphic wolf-like face, complete with a lupine muzzle.");
            break;
        case CAT_MORPH:
            sb.append(", anthropomorphic cat-like face, with a cute little feline muzzle.");
            break;
        case ALLIGATOR_MORPH:
            sb.append(", anthropomorphic alligator-like face, with a long flat muzzle.");
            break;
        case COW_MORPH:
            sb.append(", anthropomorphic cow-like face, with a cute little bovine muzzle.");
            break;
        case SQUIRREL_MORPH:
            sb.append(", anthropomorphic squirrel-like face, with a cute little muzzle.");
            break;
        case HORSE_MORPH:
            sb.append(", anthropomorphic horse-like face, with a long, equine muzzle.");
            break;
        case REINDEER_MORPH:
            sb.append(", anthropomorphic reindeer-like face, with a long, reindeer-like muzzle.");
            break;
        case HARPY:
            sb.append(", anthropomorphic bird-like face, complete with beak.");
            break;
    }
    if (owner.getBlusher().getPrimaryColour() != Colour.COVERING_NONE) {
        if (owner.isPlayer()) {
            sb.append(" You are wearing " + owner.getBlusher().getColourDescriptor(owner, true, false) + " blusher.");
        } else {
            sb.append(" [npc.She] is wearing " + owner.getBlusher().getColourDescriptor(owner, true, false) + " blusher.");
        }
    }
    if (owner.isPlayer() && hair.getRawLengthValue() == 0) {
        sb.append(" You are completely bald.");
    } else if (!owner.isPlayer() && hair.getRawLengthValue() == 0) {
        sb.append(" [npc.She] is completely bald.");
    } else {
        if (owner.isPlayer()) {
            sb.append(" You have [pc.hairLength], [pc.hairColour(true)]");
        } else {
            sb.append(" [npc.She] has [npc.hairLength], [npc.hairColour(true)]");
        }
        switch(hair.getType()) {
            case HUMAN:
                sb.append(" hair");
                break;
            case DEMON_COMMON:
                sb.append(", silken hair");
                break;
            case IMP:
                sb.append(", silken hair");
                break;
            case ANGEL:
                sb.append(", silken hair");
                break;
            case DOG_MORPH:
                sb.append(", fur-like hair");
                break;
            case LYCAN:
                sb.append(", fur-like hair");
                break;
            case CAT_MORPH:
                sb.append(", fur-like hair");
                break;
            case COW_MORPH:
                sb.append(", fur-like hair");
                break;
            case ALLIGATOR_MORPH:
                sb.append(", coarse hair");
                break;
            case SQUIRREL_MORPH:
                sb.append(", fur-like hair");
                break;
            case HORSE_MORPH:
                sb.append(", horse-like hair");
                break;
            case REINDEER_MORPH:
                sb.append(", reindeer-like hair");
                break;
            case HARPY:
                sb.append(" feathers in place of hair");
                break;
        }
        switch(hair.getStyle()) {
            case BRAIDED:
                sb.append(", which " + (hair.getType().isDefaultPlural() ? "have" : "has") + " been woven into a long braid.");
                break;
            case CURLY:
                sb.append(", which " + (hair.getType().isDefaultPlural() ? "have" : "has") + " been curled and left loose.");
                break;
            case LOOSE:
                sb.append(", which " + (hair.getType().isDefaultPlural() ? "are" : "is") + " left loose and unstyled.");
                break;
            case NONE:
                sb.append(", which " + (hair.getType().isDefaultPlural() ? "are" : "is") + " unstyled.");
                break;
            case PONYTAIL:
                sb.append(", which " + (hair.getType().isDefaultPlural() ? "have" : "has") + " been styled into a ponytail.");
                break;
            case STRAIGHT:
                sb.append(", which " + (hair.getType().isDefaultPlural() ? "have" : "has") + " been straightened and left loose.");
                break;
            case TWIN_TAILS:
                sb.append(", which " + (hair.getType().isDefaultPlural() ? "have" : "has") + " been styled into twin tails.");
                break;
            case WAVY:
                sb.append(", which " + (hair.getType().isDefaultPlural() ? "have" : "has") + " been styled into waves and left loose.");
                break;
            case MOHAWK:
                sb.append(", which " + (hair.getType().isDefaultPlural() ? "have" : "has") + " been styled into a mohawk.");
                break;
            case AFRO:
                sb.append(", which " + (hair.getType().isDefaultPlural() ? "have" : "has") + " been styled into an afro.");
                break;
            case SIDECUT:
                sb.append(", which " + (hair.getType().isDefaultPlural() ? "have" : "has") + " been styled into a sidecut.");
                break;
            case BOB_CUT:
                sb.append(", which " + (hair.getType().isDefaultPlural() ? "have" : "has") + " been styled into a bob cut.");
                break;
            case PIXIE:
                sb.append(", which " + (hair.getType().isDefaultPlural() ? "have" : "has") + " been styled into a pixie-cut.");
                break;
            case SLICKED_BACK:
                sb.append(", which " + (hair.getType().isDefaultPlural() ? "have" : "has") + " been slicked back.");
                break;
            case MESSY:
                sb.append(", which " + (hair.getType().isDefaultPlural() ? "are" : "is") + " unstyled and very messy.");
                break;
            case HIME_CUT:
                sb.append(", which " + (hair.getType().isDefaultPlural() ? "have" : "has") + " been straightened and styled into a hime cut.");
                break;
            case CHONMAGE:
                sb.append(", which " + (hair.getType().isDefaultPlural() ? "have" : "has") + " been straightened, oiled and styled into a chonmage topknot.");
                break;
            case TOPKNOT:
                sb.append(", which " + (hair.getType().isDefaultPlural() ? "have" : "has") + " been styled into a topknot.");
                break;
            case DREADLOCKS:
                sb.append(", which " + (hair.getType().isDefaultPlural() ? "have" : "has") + " been styled into dreadlocks.");
                break;
            case BIRD_CAGE:
                sb.append(", which " + (hair.getType().isDefaultPlural() ? "have" : "has") + " been styled into an elaborate bird cage" + UtilText.returnStringAtRandom(".", ", birds not included."));
                break;
            case TWIN_BRAIDS:
                sb.append(", which " + (hair.getType().isDefaultPlural() ? "have" : "has") + " been woven into long twin braids.");
                break;
            case DRILLS:
                sb.append(", which " + (hair.getType().isDefaultPlural() ? "have" : "has") + " been styled into drills.");
                break;
            case LOW_PONYTAIL:
                sb.append(", which " + (hair.getType().isDefaultPlural() ? "have" : "has") + " been styled into a low ponytail.");
                break;
            case CROWN_BRAID:
                sb.append(", which " + (hair.getType().isDefaultPlural() ? "have" : "has") + " been woven into a " + UtilText.returnStringAtRandom("crown of braids.", "braided crown."));
                break;
        }
    }
    switch(horn.getType()) {
        case NONE:
            sb.append("");
            break;
        case CURLED:
            if (owner.isPlayer()) {
                sb.append(" " + Util.capitaliseSentence(horn.getDeterminer(owner)) + " " + horn.getHornLength().getDescriptor() + ", [pc.hornColour(true)], circular-curling horns protrude from the upper sides of your forehead.");
            } else {
                sb.append(" " + Util.capitaliseSentence(horn.getDeterminer(owner)) + " " + horn.getHornLength().getDescriptor() + ", [npc.hornColour(true)], circular-curling horns protrude from the upper sides of [npc.her] forehead.");
            }
            break;
        case CURVED:
        case BOVINE_CURVED:
            if (owner.isPlayer()) {
                sb.append(" " + Util.capitaliseSentence(horn.getDeterminer(owner)) + " " + horn.getHornLength().getDescriptor() + ", [pc.hornColour(true)], curved horns protrude from the upper sides of your forehead.");
            } else {
                sb.append(" " + Util.capitaliseSentence(horn.getDeterminer(owner)) + " " + horn.getHornLength().getDescriptor() + ", [npc.hornColour(true)], curved horns protrude from the upper sides of [npc.her] forehead.");
            }
            break;
        case REINDEER_RACK:
            if (owner.isPlayer()) {
                sb.append(" " + Util.capitaliseSentence(horn.getDeterminer(owner)) + " " + horn.getHornLength().getDescriptor() + ", [pc.hornColour(true)], multi-branched antlers protrude from the upper sides of your forehead.");
            } else {
                sb.append(" " + Util.capitaliseSentence(horn.getDeterminer(owner)) + " " + horn.getHornLength().getDescriptor() + ", [npc.hornColour(true)], multi-branched antlers protrude from the upper sides of [npc.her] forehead.");
            }
            break;
        case SPIRAL:
            if (owner.isPlayer()) {
                sb.append(" " + Util.capitaliseSentence(horn.getDeterminer(owner)) + " " + horn.getHornLength().getDescriptor() + ", [pc.hornColour(true)], spiralling horns protrude from the upper sides of your forehead.");
            } else {
                sb.append(" " + Util.capitaliseSentence(horn.getDeterminer(owner)) + " " + horn.getHornLength().getDescriptor() + ", [npc.hornColour(true)], spiralling horns protrude from the upper sides of [npc.her] forehead.");
            }
            break;
        case STRAIGHT:
        case BOVINE_STRAIGHT:
            if (owner.isPlayer()) {
                sb.append(" " + Util.capitaliseSentence(horn.getDeterminer(owner)) + " " + horn.getHornLength().getDescriptor() + ", [pc.hornColour(true)], straight horns protrude from the upper sides of your forehead.");
            } else {
                sb.append(" " + Util.capitaliseSentence(horn.getDeterminer(owner)) + " " + horn.getHornLength().getDescriptor() + ", [npc.hornColour(true)], straight horns protrude from the upper sides of [npc.her] forehead.");
            }
            break;
        case SWEPT_BACK:
            if (owner.isPlayer()) {
                sb.append(" " + Util.capitaliseSentence(horn.getDeterminer(owner)) + " " + horn.getHornLength().getDescriptor() + ", [pc.hornColour(true)], swept-back horns protrude from the upper sides of your forehead.");
            } else {
                sb.append(" " + Util.capitaliseSentence(horn.getDeterminer(owner)) + " " + horn.getHornLength().getDescriptor() + ", [npc.hornColour(true)], swept-back horns protrude from the upper sides of [npc.her] forehead.");
            }
            break;
    }
    switch(antenna.getType()) {
        case NONE:
            sb.append("");
            break;
        default:
            if (owner.isPlayer())
                sb.append(" [pc.A_antennae+] protrude from your upper forehead.");
            else
                sb.append(" [npc.A_antennae+] protrude from [npc.her] upper forehead.");
    }
    if (face.isPiercedNose()) {
        if (owner.isPlayer()) {
            sb.append(" Your [pc.nose] has been pierced.");
        } else {
            sb.append(" [npc.Her] [npc.nose] has been pierced.");
        }
    }
    if (owner.isPlayer()) {
        sb.append(" You have [pc.eyePairs] ");
    } else {
        sb.append(" [npc.She] has [npc.eyePairs] ");
    }
    switch(eye.getType()) {
        case ANGEL:
            sb.append(" angelic eyes");
            break;
        case CAT_MORPH:
            sb.append(" cat-like eyes");
            break;
        case COW_MORPH:
            sb.append(" cow-like eyes");
            break;
        case DEMON_COMMON:
            sb.append(" demonic eyes");
            break;
        case IMP:
            sb.append(" impish eyes");
            break;
        case DOG_MORPH:
            sb.append(" dog-like eyes");
            break;
        case ALLIGATOR_MORPH:
            sb.append(" reptilian eyes");
            break;
        case HARPY:
            sb.append(" bird-like eyes");
            break;
        case HORSE_MORPH:
            sb.append(" horse-like eyes");
            break;
        case REINDEER_MORPH:
            sb.append(" reindeer-like eyes");
            break;
        case HUMAN:
            sb.append(" normal, human eyes");
            break;
        case LYCAN:
            sb.append(" wolf-like eyes");
            break;
        case SQUIRREL_MORPH:
            sb.append(" squirrel-like eyes");
            break;
    }
    if (owner.isPlayer()) {
        if (owner.getCovering(owner.getEyeType().getBodyCoveringType(owner)).getPattern() == CoveringPattern.EYE_IRISES_HETEROCHROMATIC) {
            sb.append(", with [pc.irisShape], heterochromatic [pc.irisPrimaryColour(true)]-and-[pc.irisSecondaryColour(true)] irises ");
        } else {
            sb.append(", with [pc.irisShape], [pc.irisPrimaryColour(true)] irises ");
        }
        if (owner.getCovering(BodyCoveringType.EYE_PUPILS).getPattern() == CoveringPattern.EYE_PUPILS_HETEROCHROMATIC) {
            sb.append("and [pc.pupilShape], heterochromatic [pc.pupilPrimaryColour(true)]-and-[pc.pupilSecondaryColour(true)] pupils.");
        } else {
            sb.append("and [pc.pupilShape], [pc.pupilPrimaryColour(true)] pupils.");
        }
    } else {
        if (owner.getCovering(owner.getEyeType().getBodyCoveringType(owner)).getPattern() == CoveringPattern.EYE_IRISES_HETEROCHROMATIC) {
            sb.append(", with [npc.irisShape], heterochromatic [npc.irisPrimaryColour(true)]-and-[npc.irisSecondaryColour(true)] irises, ");
        } else {
            sb.append(", with [npc.irisShape], [npc.irisPrimaryColour(true)] irises ");
        }
        if (owner.getCovering(BodyCoveringType.EYE_PUPILS).getPattern() == CoveringPattern.EYE_PUPILS_HETEROCHROMATIC) {
            sb.append("and [npc.pupilShape], heterochromatic [npc.pupilPrimaryColour(true)]-and-[npc.pupilSecondaryColour(true)] pupils.");
        } else {
            sb.append("and [npc.pupilShape], [npc.pupilPrimaryColour(true)] pupils.");
        }
    }
    // Eye makeup:
    if (owner.getEyeLiner().getPrimaryColour() != Colour.COVERING_NONE) {
        if (owner.isPlayer()) {
            sb.append(" Around your [pc.eyes], you've got a layer of " + owner.getEyeLiner().getColourDescriptor(owner, true, false) + " eye liner.");
        } else {
            sb.append(" Around [npc.her] [npc.eyes], [npc.she]'s got a layer of " + owner.getEyeLiner().getColourDescriptor(owner, true, false) + " eye liner.");
        }
    }
    if (owner.getEyeShadow().getPrimaryColour() != Colour.COVERING_NONE) {
        if (owner.isPlayer()) {
            sb.append(" You're wearing a tasteful amount of " + owner.getEyeShadow().getFullDescription(owner, true) + ".");
        } else {
            sb.append(" [npc.She]'s wearing a tasteful amount of " + owner.getEyeShadow().getFullDescription(owner, true) + ".");
        }
    }
    // Ear:
    switch(ear.getType()) {
        case ANGEL:
            if (owner.isPlayer())
                sb.append(" You have a pair of perfectly-formed angelic ears, which are " + getCoveredInDescriptor(owner) + " [pc.earFullDescription(true)]" + (ear.isPierced() ? ", and which have been pierced" : "") + ".");
            else
                sb.append(" [npc.She] has a pair of perfectly-formed angelic ears, which are " + getCoveredInDescriptor(owner) + " [npc.earFullDescription(true)]" + (ear.isPierced() ? ", and which have been pierced" : "") + ".");
            break;
        case HUMAN:
            if (owner.isPlayer())
                sb.append(" You have a pair of normal, human ears, which are " + getCoveredInDescriptor(owner) + " [pc.earFullDescription(true)]" + (ear.isPierced() ? ", and which have been pierced" : "") + ".");
            else
                sb.append(" [npc.She] has a pair of normal, human ears, which are " + getCoveredInDescriptor(owner) + " [npc.earFullDescription(true)]" + (ear.isPierced() ? ", and which have been pierced" : "") + ".");
            break;
        case DEMON_COMMON:
            if (owner.isPlayer())
                sb.append(" You have a pair of pointed, demonic ears, which are " + getCoveredInDescriptor(owner) + " [pc.earFullDescription(true)]" + (ear.isPierced() ? ", and which have been pierced" : "") + ".");
            else
                sb.append(" [npc.She] has a pair of pointed, demonic ears, which are " + getCoveredInDescriptor(owner) + " [npc.earFullDescription(true)]" + (ear.isPierced() ? ", and which have been pierced" : "") + ".");
            break;
        case IMP:
            if (owner.isPlayer())
                sb.append(" You have a pair of pointed, impish ears, which are " + getCoveredInDescriptor(owner) + " [pc.earFullDescription(true)]" + (ear.isPierced() ? ", and which have been pierced" : "") + ".");
            else
                sb.append(" [npc.She] has a pair of pointed, impish ears, which are " + getCoveredInDescriptor(owner) + " [npc.earFullDescription(true)]" + (ear.isPierced() ? ", and which have been pierced" : "") + ".");
            break;
        case DOG_MORPH:
            if (owner.isPlayer())
                sb.append(" You have a pair of floppy, " + (ear.isPierced() ? "pierced, " : "") + "dog-like ears, which are positioned high up on your head and are are " + getCoveredInDescriptor(owner) + " [pc.earFullDescription(true)].");
            else
                sb.append(" [npc.She] has a pair of floppy, " + (ear.isPierced() ? "pierced, " : "") + "dog-like ears, which are positioned high up on [npc.her] head and are " + getCoveredInDescriptor(owner) + " [npc.earFullDescription(true)].");
            break;
        case DOG_MORPH_POINTED:
            if (owner.isPlayer())
                sb.append(" You have a pair of pointed, " + (ear.isPierced() ? "pierced, " : "") + "dog-like ears, which are positioned high up on your head and are are " + getCoveredInDescriptor(owner) + " [pc.earFullDescription(true)].");
            else
                sb.append(" [npc.She] has a pair of pointed, " + (ear.isPierced() ? "pierced, " : "") + "dog-like ears, which are positioned high up on [npc.her] head and are " + getCoveredInDescriptor(owner) + " [npc.earFullDescription(true)].");
            break;
        case LYCAN:
            if (owner.isPlayer())
                sb.append(" You have a pair of " + (ear.isPierced() ? "pierced, " : "") + "upright, wolf-like ears, which are positioned high up on your head and are are " + getCoveredInDescriptor(owner) + " [pc.earFullDescription(true)].");
            else
                sb.append(" [npc.She] has a pair of " + (ear.isPierced() ? "pierced, " : "") + "upright, wolf-like ears, which are positioned high up on [npc.her] head and are " + getCoveredInDescriptor(owner) + " [npc.earFullDescription(true)].");
            break;
        case CAT_MORPH:
            if (owner.isPlayer())
                sb.append(" You have a pair of " + (ear.isPierced() ? "pierced, " : "") + "upright, cat-like ears, which are positioned high up on your head and are are " + getCoveredInDescriptor(owner) + " [pc.earFullDescription(true)].");
            else
                sb.append(" [npc.She] has a pair of " + (ear.isPierced() ? "pierced, " : "") + "upright, cat-like ears, which are positioned high up on [npc.her] head and are " + getCoveredInDescriptor(owner) + " [npc.earFullDescription(true)].");
            break;
        case COW_MORPH:
            if (owner.isPlayer())
                sb.append(" You have a pair of oval-shaped, cow-like ears, which are " + getCoveredInDescriptor(owner) + " [pc.earFullDescription(true)]" + (ear.isPierced() ? ", and which have been pierced" : "") + ".");
            else
                sb.append(" [npc.She] has a pair of oval-shaped, cow-like ears, which are " + getCoveredInDescriptor(owner) + " [npc.earFullDescription(true)]" + (ear.isPierced() ? ", and which have been pierced" : "") + ".");
            break;
        case ALLIGATOR_MORPH:
            if (owner.isPlayer())
                sb.append(" Your ears are an internal part of your head, and are covered by a fan of <span style='color:[pc.earColourHex];'>[pc.earColour] scales</span>." + (ear.isPierced() ? " They have been cleverly pierced so as to allow you to wear ear-specific jewellery." : ""));
            else
                sb.append(" [npc.Her] ears are an internal part of [npc.her] head, and are covered by a fan of <span style='color:[npc.earColourHex];'>[npc.earColour] scales</span>." + (ear.isPierced() ? " They have been cleverly pierced so as to allow [npc.herHim] to wear ear-specific jewellery." : ""));
            break;
        case SQUIRREL_MORPH:
            if (owner.isPlayer())
                sb.append(" You have a pair of " + (ear.isPierced() ? "pierced, " : "") + "rounded, squirrel-like ears, which are positioned high up on your head and are are " + getCoveredInDescriptor(owner) + " [pc.earFullDescription(true)].");
            else
                sb.append(" [npc.She] has a pair of " + (ear.isPierced() ? "pierced, " : "") + "rounded, squirrel-like ears, which are positioned high up on [npc.her] head and are " + getCoveredInDescriptor(owner) + " [npc.earFullDescription(true)].");
            break;
        case HORSE_MORPH:
            if (owner.isPlayer())
                sb.append(" You have a pair of " + (ear.isPierced() ? "pierced, " : "") + "upright, horse-like ears, which are positioned high up on your head and are are " + getCoveredInDescriptor(owner) + " [pc.earFullDescription(true)].");
            else
                sb.append(" [npc.She] has a pair of " + (ear.isPierced() ? "pierced, " : "") + "upright, horse-like ears, which are positioned high up on [npc.her] head and are " + getCoveredInDescriptor(owner) + " [npc.earFullDescription(true)].");
            break;
        case REINDEER_MORPH:
            if (owner.isPlayer())
                sb.append(" You have a pair of oval-shaped, reindeer-like ears, which are " + getCoveredInDescriptor(owner) + " [pc.earFullDescription(true)]" + (ear.isPierced() ? ", and which have been pierced" : "") + ".");
            else
                sb.append(" [npc.She] has a pair of oval-shaped, reindeer-like ears, which are " + getCoveredInDescriptor(owner) + " [npc.earFullDescription(true)]" + (ear.isPierced() ? ", and which have been pierced" : "") + ".");
            break;
        case HARPY:
            if (owner.isPlayer())
                sb.append(" Your ears are an internal part of your head, and are covered by a fan of <span style='color:[pc.earColourHex];'>[pc.earColour] feathers</span>." + (ear.isPierced() ? " They have been cleverly pierced so as to allow you to wear ear-specific jewellery." : ""));
            else
                sb.append(" [npc.Her] ears are an internal part of [npc.her] head, and are covered by a fan of <span style='color:[npc.earColourHex];'>[npc.earColour] feathers</span>." + (ear.isPierced() ? " They have been cleverly pierced so as to allow [npc.herHim] to wear ear-specific jewellery." : ""));
            break;
    }
    sb.append("</p>" + "<p>");
    if (Main.game.isFacialHairEnabled()) {
        if (owner.isPlayer()) {
            if (owner.getFacialHairType().getType() == BodyCoveringType.BODY_HAIR_SCALES_ALLIGATOR) {
                switch(owner.getFacialHair()) {
                    case ZERO_NONE:
                        if (!owner.isFeminine()) {
                            sb.append(" You don't have any trace of rough, stubbly " + owner.getFacialHairType().getName(owner) + " growing on your [pc.face].");
                        }
                        break;
                    case ONE_STUBBLE:
                        sb.append(" You have a stubbly patch of rough " + owner.getFacialHairType().getFullDescription(owner, true) + " growing on your [pc.face].");
                        break;
                    case TWO_MANICURED:
                        sb.append(" You have a small amount of rough " + owner.getFacialHairType().getFullDescription(owner, true) + " growing on your [pc.face], which resembles a beard.");
                        break;
                    case THREE_TRIMMED:
                        sb.append(" You have a rough patch of " + owner.getFacialHairType().getFullDescription(owner, true) + " growing on your [pc.face], which resembles a beard.");
                        break;
                    case FOUR_NATURAL:
                        sb.append(" You have a natural-looking rough patch of " + owner.getFacialHairType().getFullDescription(owner, true) + " growing on your [pc.face], which resembles a beard.");
                        break;
                    case FIVE_UNKEMPT:
                        sb.append(" You have an unkempt, rough patch of " + owner.getFacialHairType().getFullDescription(owner, true) + " growing on your [pc.face], which resembles a beard.");
                        break;
                    case SIX_BUSHY:
                        sb.append(" You have a thick, rough patch of " + owner.getFacialHairType().getFullDescription(owner, true) + " growing on your [pc.face], which resembles a beard.");
                        break;
                    case SEVEN_WILD:
                        sb.append(" You have a wild, rough patch of " + owner.getFacialHairType().getFullDescription(owner, true) + " growing on your [pc.face], which resembles a beard.");
                        break;
                }
            } else {
                switch(owner.getFacialHair()) {
                    case ZERO_NONE:
                        if (!owner.isFeminine()) {
                            sb.append(" You don't have any trace of facial " + owner.getFacialHairType().getName(owner) + ".");
                        }
                        break;
                    case ONE_STUBBLE:
                        sb.append(" You have a stubbly patch of " + owner.getFacialHairType().getFullDescription(owner, true) + " growing on your [pc.face].");
                        break;
                    case TWO_MANICURED:
                        sb.append(" You have a small amount of " + owner.getFacialHairType().getFullDescription(owner, true) + " growing on your [pc.face].");
                        break;
                    case THREE_TRIMMED:
                        sb.append(" You have a well-trimmed beard of " + owner.getFacialHairType().getFullDescription(owner, true) + " growing on your [pc.face].");
                        break;
                    case FOUR_NATURAL:
                        sb.append(" You have a natural-looking beard of " + owner.getFacialHairType().getFullDescription(owner, true) + " growing on your [pc.face].");
                        break;
                    case FIVE_UNKEMPT:
                        sb.append(" You have an unkempt, bushy beard of " + owner.getFacialHairType().getFullDescription(owner, true) + " growing on your [pc.face].");
                        break;
                    case SIX_BUSHY:
                        sb.append(" You have a thick, bushy beard of " + owner.getFacialHairType().getFullDescription(owner, true) + " growing on your [pc.face].");
                        break;
                    case SEVEN_WILD:
                        sb.append(" You have a wild, bushy beard of " + owner.getFacialHairType().getFullDescription(owner, true) + " growing on your [pc.face].");
                        break;
                }
            }
        } else {
            if (owner.getFacialHairType().getType() == BodyCoveringType.BODY_HAIR_SCALES_ALLIGATOR) {
                switch(owner.getFacialHair()) {
                    case ZERO_NONE:
                        if (!owner.isFeminine()) {
                            sb.append(" [npc.She] doesn't have any trace of rough, stubbly " + owner.getFacialHairType().getName(owner) + ".");
                        }
                        break;
                    case ONE_STUBBLE:
                        sb.append(" [npc.She] has a stubbly patch of " + owner.getFacialHairType().getFullDescription(owner, true) + " growing on [npc.her] [npc.face].");
                        break;
                    case TWO_MANICURED:
                        sb.append(" [npc.She] has a small, rough patch of " + owner.getFacialHairType().getFullDescription(owner, true) + " growing on [npc.her] [npc.face], which resembles a beard.");
                        break;
                    case THREE_TRIMMED:
                        sb.append(" [npc.She] has a rough patch of " + owner.getFacialHairType().getFullDescription(owner, true) + " growing on [npc.her] [npc.face], which resembles a beard.");
                        break;
                    case FOUR_NATURAL:
                        sb.append(" [npc.She] has a natural-looking rough patch of " + owner.getFacialHairType().getFullDescription(owner, true) + " growing on [npc.her] [npc.face], which resembles a beard.");
                        break;
                    case FIVE_UNKEMPT:
                        sb.append(" [npc.She] has a unkempt, rough patch of " + owner.getFacialHairType().getFullDescription(owner, true) + " growing on [npc.her] [npc.face], which resembles a beard.");
                        break;
                    case SIX_BUSHY:
                        sb.append(" [npc.She] has a thick, rough patch of " + owner.getFacialHairType().getFullDescription(owner, true) + " growing on [npc.her] [npc.face], which resembles a beard.");
                        break;
                    case SEVEN_WILD:
                        sb.append(" [npc.She] has a wild, rough patch of " + owner.getFacialHairType().getFullDescription(owner, true) + " growing on [npc.her] [npc.face], which resembles a beard.");
                        break;
                }
            } else {
                switch(owner.getFacialHair()) {
                    case ZERO_NONE:
                        if (!owner.isFeminine()) {
                            sb.append(" [npc.She] doesn't have any trace of facial " + owner.getFacialHairType().getName(owner) + ".");
                        }
                        break;
                    case ONE_STUBBLE:
                        sb.append(" [npc.She] has a stubbly patch of " + owner.getFacialHairType().getFullDescription(owner, true) + " growing on [npc.her] [npc.face].");
                        break;
                    case TWO_MANICURED:
                        sb.append(" [npc.She] has a small amount of " + owner.getFacialHairType().getFullDescription(owner, true) + " growing on [npc.her] [npc.face].");
                        break;
                    case THREE_TRIMMED:
                        sb.append(" [npc.She] has a well-trimmed beard of " + owner.getFacialHairType().getFullDescription(owner, true) + " growing on [npc.her] [npc.face].");
                        break;
                    case FOUR_NATURAL:
                        sb.append(" [npc.She] has a natural-looking beard of " + owner.getFacialHairType().getFullDescription(owner, true) + " growing on [npc.her] [npc.face].");
                        break;
                    case FIVE_UNKEMPT:
                        sb.append(" [npc.She] has a unkempt, bushy beard of " + owner.getFacialHairType().getFullDescription(owner, true) + " growing on [npc.her] [npc.face].");
                        break;
                    case SIX_BUSHY:
                        sb.append(" [npc.She] has a thick, bushy beard of " + owner.getFacialHairType().getFullDescription(owner, true) + " growing on [npc.her] [npc.face].");
                        break;
                    case SEVEN_WILD:
                        sb.append(" [npc.She] has a wild, bushy beard of " + owner.getFacialHairType().getFullDescription(owner, true) + " growing on [npc.her] [npc.face].");
                        break;
                }
            }
        }
    }
    // Mouth & lips:
    if (owner.isPlayer()) {
        sb.append(" You have [pc.lipSize], [pc.mouthColourPrimary(true)] [pc.lips]");
        if (owner.getLipstick().getPrimaryColour() != Colour.COVERING_NONE) {
            sb.append((owner.isPiercedLip() ? ", which have been pierced, and" : ", which") + " are currently " + getCoveredInDescriptor(owner) + " " + owner.getLipstick().getFullDescription(owner, true) + ".");
        } else {
            sb.append((owner.isPiercedLip() ? ", which have been pierced." : "."));
        }
        sb.append(" Your throat is [pc.mouthColourSecondary(true)] in colour.");
    } else {
        sb.append(" [npc.She] has [npc.lipSize], [npc.mouthColourPrimary(true)] [pc.lips]");
        if (owner.getLipstick().getPrimaryColour() != Colour.COVERING_NONE) {
            sb.append((owner.isPiercedLip() ? ", which have been pierced, and" : ", which") + " are currently " + getCoveredInDescriptor(owner) + " " + owner.getLipstick().getFullDescription(owner, true) + ".");
        } else {
            sb.append((owner.isPiercedLip() ? ", which have been pierced." : "."));
        }
        sb.append(" [npc.Her] throat is [npc.mouthColourSecondary(true)] in colour.");
    }
    // Throat modifiers:
    for (OrificeModifier om : OrificeModifier.values()) {
        if (owner.hasFaceOrificeModifier(om)) {
            if (owner.isPlayer()) {
                switch(om) {
                    case PUFFY:
                        sb.append(" Your [pc.lips] have swollen up to be far puffier than what would be considered normal.");
                        break;
                    case MUSCLE_CONTROL:
                        sb.append(" You have a series of internal muscles lining the inside of your throat, allowing you to expertly squeeze and grip down on any intruding object.");
                        break;
                    case RIBBED:
                        sb.append(" The inside of your throat is lined with sensitive, fleshy ribs, which grant you extra pleasure when stimulated.");
                        break;
                    case TENTACLED:
                        sb.append(" Your throat is filled with tiny little tentacles, which wriggle and squirm with a mind of their own.");
                        break;
                }
            } else {
                switch(om) {
                    case PUFFY:
                        sb.append(" [npc.Her] [npc.lips] have swollen up to be far puffier than what would be considered normal.");
                        break;
                    case MUSCLE_CONTROL:
                        sb.append(" [npc.She] has a series of internal muscles lining the inside of [npc.her] throat, allowing [npc.herHim] to expertly squeeze and grip down on any intruding object.");
                        break;
                    case RIBBED:
                        sb.append(" The inside of [npc.her] throat is lined with sensitive, fleshy ribs, which grant [npc.herHim] extra pleasure when stimulated.");
                        break;
                    case TENTACLED:
                        sb.append(" [npc.Her] throat is filled with tiny little tentacles, which wriggle and squirm with a mind of their own.");
                        break;
                }
            }
        }
    }
    // Tongue & blowjob:
    if (owner.isPlayer()) {
        sb.append(" Your mouth holds [pc.a_tongueLength], [pc.tongueColour(true)] [pc.tongue]" + (face.getTongue().isPierced() ? ", which has been pierced." : "."));
    } else {
        sb.append(" [npc.Her] mouth holds [npc.a_tongueLength], [npc.tongueColour(true)] [npc.tongue]" + (face.getTongue().isPierced() ? ", which has been pierced." : "."));
    }
    for (TongueModifier tm : TongueModifier.values()) {
        if (owner.hasTongueModifier(tm)) {
            if (owner.isPlayer()) {
                switch(tm) {
                    case RIBBED:
                        sb.append(" It's lined with hard, fleshy ribs, which are sure to grant extra pleasure to any orifice that they penetrate.");
                        break;
                    case TENTACLED:
                        sb.append(" A series of little tentacles coat its surface, which wriggle and squirm with a mind of their own.");
                        break;
                    case BIFURCATED:
                        sb.append(" Near the tip, it's split in two, leaving your tongue bifurcated, like a snake.");
                        break;
                }
            } else {
                switch(tm) {
                    case RIBBED:
                        sb.append(" It's lined with hard, fleshy ribs, which are sure to grant extra pleasure to any orifice that they penetrate.");
                        break;
                    case TENTACLED:
                        sb.append(" A series of little tentacles coat its surface, which wriggle and squirm with a mind of their own.");
                        break;
                    case BIFURCATED:
                        sb.append(" Near the tip, it's split in two, leaving [npc.her] tongue bifurcated, like a snake.");
                        break;
                }
            }
        }
    }
    if (owner.isPlayer()) {
        if (face.getMouth().getOrificeMouth().isVirgin()) {
            sb.append(" <span style='color:" + Colour.GENERIC_SEX.toWebHexString() + ";'>You've never given head before, so you don't know what you could fit down your throat.</span>");
        } else {
            switch(face.getMouth().getOrificeMouth().getCapacity().getMaximumSizeComfortableWithLube()) {
                // case NEGATIVE_UTILITY_VALUE:
                case ZERO_MICROSCOPIC:
                    sb.append(" [style.colourSex(You're terrible at giving head)], and struggle to fit the tip of even a tiny cock into your mouth without gagging.");
                    break;
                case ONE_TINY:
                    sb.append(" [style.colourSex(You're really bad at giving head)], and struggle to fit even a tiny cocks into your mouth without gagging.");
                    // sb.append(" You find anything larger than "+face.getRawCapacityValue()+" inches to be uncomfortable.");
                    break;
                case TWO_AVERAGE:
                    sb.append(" [style.colourSex(You're not great at giving head)], and anything larger than an average-sized human cock will cause you to gag.");
                    // sb.append(" You find anything larger than "+face.getRawCapacityValue()+" inches to be uncomfortable.");
                    break;
                case THREE_LARGE:
                    sb.append(" [style.colourSex(You're somewhat competent at giving head)], and can suppress your gag reflex enough to comfortably suck large cocks.");
                    // sb.append(" You find anything larger than "+face.getRawCapacityValue()+" inches to be uncomfortable.");
                    break;
                case FOUR_HUGE:
                    sb.append(" [style.colourSex(You're pretty good at giving head)], and can comfortably suck huge cocks without gagging.");
                    // sb.append(" You find anything larger than "+face.getRawCapacityValue()+" inches to be uncomfortable.");
                    break;
                case FIVE_ENORMOUS:
                    sb.append(" [style.colourSex(You're somewhat of an expert at giving head)], and can suck enormous cocks without too much difficulty.");
                    // sb.append(" You find anything larger than "+face.getRawCapacityValue()+" inches to be uncomfortable.");
                    break;
                case SIX_GIGANTIC:
                    sb.append(" [style.colourSex(You're amazing at giving head)], and can comfortably suck all but the most absurdly-sized of cocks with ease.");
                    // sb.append(" You find anything larger than "+face.getRawCapacityValue()+" inches to be uncomfortable.");
                    break;
                case SEVEN_STALLION:
                    sb.append(" [style.colourSex(You are)]" + " [style.colourLegendary(legendary)]" + " [style.colourSex(at giving head)]; it's almost as though your throat was purposefully designed to fit phallic objects of any size or shape.");
                    break;
                default:
                    break;
            }
            for (PenetrationType pt : PenetrationType.values()) {
                if (Main.game.getPlayer().getVirginityLoss(new SexType(SexParticipantType.CATCHER, pt, OrificeType.MOUTH)) != null && !Main.game.getPlayer().getVirginityLoss(new SexType(SexParticipantType.CATCHER, pt, OrificeType.MOUTH)).isEmpty()) {
                    sb.append(" <span style='color:" + Colour.GENERIC_ARCANE.toWebHexString() + ";'>The first time you performed oral sex was to " + Main.game.getPlayer().getVirginityLoss(new SexType(SexParticipantType.CATCHER, pt, OrificeType.MOUTH)) + ".</span>");
                    break;
                }
            }
        }
    } else {
        if (owner.getPlayerKnowsAreas().contains(CoverableArea.MOUTH)) {
            if (face.getMouth().getOrificeMouth().isVirgin()) {
                sb.append(" <span style='color:" + Colour.GENERIC_SEX.toWebHexString() + ";'>[npc.She]'s never given head before.</span>");
            } else {
                switch(face.getMouth().getOrificeMouth().getCapacity().getMaximumSizeComfortableWithLube()) {
                    // case NEGATIVE_UTILITY_VALUE:
                    case ZERO_MICROSCOPIC:
                        sb.append(" <span style='color:" + Colour.GENERIC_SEX.toWebHexString() + ";'>[npc.She]'s terrible at giving head</span>, and struggles to fit the tip of even the smallest of cocks into [npc.her] mouth without gagging.");
                        break;
                    case ONE_TINY:
                        sb.append(" <span style='color:" + Colour.GENERIC_SEX.toWebHexString() + ";'>[npc.She]'s really bad at giving head</span>, and struggles to fit even tiny cocks into [npc.her] mouth without gagging.");
                        // sb.append(" [npc.She] finds anything larger than "+face.getRawCapacityValue()+" inches to be uncomfortable.");
                        break;
                    case TWO_AVERAGE:
                        sb.append(" <span style='color:" + Colour.GENERIC_SEX.toWebHexString() + ";'>[npc.She]'s not great at giving head</span>, and anything larger than an average-sized human cock will cause [npc.her] to gag.");
                        // sb.append(" [npc.She] finds anything larger than "+face.getRawCapacityValue()+" inches to be uncomfortable.");
                        break;
                    case THREE_LARGE:
                        sb.append(" <span style='color:" + Colour.GENERIC_SEX.toWebHexString() + ";'>[npc.She]'s somewhat competent at giving head</span>, and can suppress [npc.her] gag reflex enough to comfortably suck large cocks.");
                        // sb.append(" [npc.She] finds anything larger than "+face.getRawCapacityValue()+" inches to be uncomfortable.");
                        break;
                    case FOUR_HUGE:
                        sb.append(" <span style='color:" + Colour.GENERIC_SEX.toWebHexString() + ";'>[npc.She]'s pretty good at giving head</span>, and can comfortably suck huge cocks without gagging.");
                        // sb.append(" [npc.She] finds anything larger than "+face.getRawCapacityValue()+" inches to be uncomfortable.");
                        break;
                    case FIVE_ENORMOUS:
                        sb.append(" <span style='color:" + Colour.GENERIC_SEX.toWebHexString() + ";'>[npc.She]'s somewhat of an expert at giving head</span>, and can suck enormous cocks without too much difficulty.");
                        // sb.append(" [npc.She] finds anything larger than "+face.getRawCapacityValue()+" inches to be uncomfortable.");
                        break;
                    case SIX_GIGANTIC:
                        sb.append(" <span style='color:" + Colour.GENERIC_SEX.toWebHexString() + ";'>[npc.She]'s amazing at giving head</span>, and can comfortably suck all but the most absurdly-sized of cocks with ease.");
                        // sb.append(" [npc.She] finds anything larger than "+face.getRawCapacityValue()+" inches to be uncomfortable.");
                        break;
                    case SEVEN_STALLION:
                        sb.append(" <span style='color:" + Colour.GENERIC_SEX.toWebHexString() + ";'>[npc.She] is</span>" + " <span style='color:" + Colour.GENERIC_EXCELLENT.toWebHexString() + ";'>legendary</span>" + " <span style='color:" + Colour.GENERIC_SEX.toWebHexString() + ";'>at giving head</span>;" + " it's almost as though [npc.her] throat was purposefully designed to fit phallic objects of any size or shape.");
                        break;
                    default:
                        break;
                }
            }
        } else {
            sb.append(" <span style='color:" + Colour.GENERIC_SEX.toWebHexString() + ";'>You don't know [npc.herHim] well enough to know how competent [npc.she] is at performing oral sex.</span>");
        }
    }
    sb.append("</p>");
    // Describe body:
    sb.append("<p>");
    if (owner.isPlayer()) {
        sb.append("Your torso has");
    } else {
        sb.append("[npc.Her] torso has");
    }
    if (femininity <= Femininity.MASCULINE_STRONG.getMaximumFemininity()) {
        sb.append(UtilText.returnStringAtRandom(" an <span style='color:" + Colour.MASCULINE_PLUS.toWebHexString() + ";'>extremely masculine</span> appearance", " a <span style='color:" + Colour.MASCULINE_PLUS.toWebHexString() + ";'>very masculine</span> appearance"));
    } else if (femininity <= Femininity.MASCULINE.getMaximumFemininity()) {
        sb.append(UtilText.returnStringAtRandom(" a <span style='color:" + Colour.MASCULINE.toWebHexString() + ";'>masculine</span> appearance", " a <span style='color:" + Colour.MASCULINE.toWebHexString() + ";'>boyish</span> appearance"));
    } else if (femininity <= Femininity.ANDROGYNOUS.getMaximumFemininity()) {
        sb.append(UtilText.returnStringAtRandom(" a very <span style='color:" + Colour.ANDROGYNOUS.toWebHexString() + ";'>androgynous</span> appearance"));
    } else if (femininity <= Femininity.FEMININE.getMaximumFemininity()) {
        sb.append(UtilText.returnStringAtRandom(" a <span style='color:" + Colour.FEMININE.toWebHexString() + ";'>feminine</span> appearance", " a <span style='color:" + Colour.FEMININE.toWebHexString() + ";'>pretty</span> appearance"));
    } else {
        sb.append(UtilText.returnStringAtRandom(" an <span style='color:" + Colour.FEMININE_PLUS.toWebHexString() + ";'>extremely feminine</span> appearance", " a <span style='color:" + Colour.FEMININE_PLUS.toWebHexString() + ";'>gorgeous</span> appearance", " a <span style='color:" + Colour.FEMININE_PLUS.toWebHexString() + ";'>jaw-droppingly beautiful</span> appearance"));
    }
    if (owner.isPlayer()) {
        sb.append(", and is " + getCoveredInDescriptor(owner) + " [pc.skinFullDescription(true)].");
    } else {
        sb.append(", and is " + getCoveredInDescriptor(owner) + " [npc.skinFullDescription(true)].");
    }
    if (owner.isPlayer()) {
        sb.append(" You have <span style='color:" + owner.getBodySize().getColour().toWebHexString() + ";'>[pc.a_bodySize]</span>, " + "<span style='color:" + owner.getMuscle().getColour().toWebHexString() + ";'>[pc.muscle]</span>" + " body, which gives you <span style='color:" + owner.getBodyShape().toWebHexStringColour() + ";'>[pc.a_bodyShape]</span> body shape.");
    } else {
        sb.append(" [npc.She] has <span style='color:" + BodySize.valueOf(getBodySize()).getColour().toWebHexString() + ";'>" + BodySize.valueOf(getBodySize()).getName(true) + "</span>, " + "<span style='color:" + Muscle.valueOf(getMuscle()).getColour().toWebHexString() + ";'>" + Muscle.valueOf(getMuscle()).getName(false) + "</span>" + " body, giving [npc.herHim] <span style='color:" + owner.getBodyShape().toWebHexStringColour() + ";'>[npc.a_bodyShape]</span> body shape.");
    }
    // Pregnancy:
    if (owner.hasStatusEffect(StatusEffect.PREGNANT_1)) {
        if (owner.isPlayer())
            sb.append(" Your belly is slightly swollen, and it's clear to anyone who takes a closer look that <span style='color:" + Colour.GENERIC_ARCANE.toWebHexString() + ";'>you're pregnant</span>.");
        else
            sb.append(" [npc.Her] belly is slightly swollen, and it's clear to anyone who takes a closer look that <span style='color:" + Colour.GENERIC_ARCANE.toWebHexString() + ";'>[npc.she]'s pregnant</span>.");
    } else if (owner.hasStatusEffect(StatusEffect.PREGNANT_2)) {
        if (owner.isPlayer())
            sb.append(" Your belly is heavily swollen, and it's clear to anyone who glances your way that <span style='color:" + Colour.GENERIC_ARCANE.toWebHexString() + ";'>you're pregnant</span>.");
        else
            sb.append(" [npc.Her] belly is heavily swollen, and it's clear to anyone who glances [npc.her] way that <span style='color:" + Colour.GENERIC_ARCANE.toWebHexString() + ";'>[npc.she]'s pregnant</span>.");
    } else if (owner.hasStatusEffect(StatusEffect.PREGNANT_3)) {
        if (owner.isPlayer())
            sb.append(" Your belly is massively swollen, and it's completely obvious to anyone who glances your way that" + " <span style='color:" + Colour.GENERIC_ARCANE.toWebHexString() + ";'>you're expecting to give birth very soon</span>.");
        else
            sb.append(" [npc.Her] belly is massively swollen, and it's completely obvious to anyone who glances [npc.her] way that" + " <span style='color:" + Colour.GENERIC_ARCANE.toWebHexString() + ";'>[npc.she]'s expecting to give birth very soon</span>.");
    }
    sb.append("</p>");
    // Breasts:
    sb.append("<p>");
    Breast viewedBreast = breast;
    if (Main.game.getPlayer().hasIngestedPsychoactiveFluidType(FluidTypeBase.MILK)) {
        viewedBreast = new Breast(breast.getType(), breast.getShape(), (int) (breast.getRawSizeValue() * (1.75f)), (int) ((breast.getRawMilkStorageValue() + 100) * (2.25f)), breast.getRows(), breast.getNipples().getNippleSizeValue(), breast.getNipples().getNippleShape(), breast.getNipples().getAreolaeSizeValue(), breast.getNippleCountPerBreast(), breast.getNipples().getOrificeNipples().getRawCapacityValue(), breast.getNipples().getOrificeNipples().getElasticity().getValue(), breast.getNipples().getOrificeNipples().getPlasticity().getValue(), breast.getNipples().getOrificeNipples().isVirgin());
        sb.append(" <i style='color:" + Colour.PSYCHOACTIVE.toWebHexString() + ";'>The psychoactive milk you recently ingested is causing your view of " + (owner.isPlayer() ? "your" : "[npc.name]'s") + " breasts to be distorted!</i>");
    }
    if (owner.isPlayer()) {
        if (viewedBreast.getRawSizeValue() > 0) {
            sb.append(" You have " + Util.intToString(viewedBreast.getRows()) + " pair" + (viewedBreast.getRows() == 1 ? "" : "s") + " of " + viewedBreast.getSize().getDescriptor() + " [pc.breasts]");
            if (viewedBreast.getRows() == 1) {
                if (viewedBreast.getSize().isTrainingBraSize()) {
                    sb.append(", which fit comfortably into a training bra.");
                } else {
                    sb.append(", which fit comfortably into " + UtilText.generateSingularDeterminer(viewedBreast.getSize().getCupSizeName()) + " " + viewedBreast.getSize().getCupSizeName() + "-cup bra.");
                }
            } else if (viewedBreast.getRows() == 2) {
                if (viewedBreast.getSize().isTrainingBraSize()) {
                    sb.append(", with your top pair fitting comfortably into a training bra, and the pair below being slightly smaller.");
                } else {
                    sb.append(", with your top pair fitting comfortably into " + UtilText.generateSingularDeterminer(viewedBreast.getSize().getCupSizeName()) + " " + viewedBreast.getSize().getCupSizeName() + "-cup bra, and the pair below being slightly smaller.");
                }
            } else if (viewedBreast.getRows() > 2) {
                if (viewedBreast.getSize().isTrainingBraSize()) {
                    sb.append(", with your top pair fitting comfortably into a training bra, and the pairs below each being slightly smaller than the ones above.");
                } else {
                    sb.append(", with your top pair fitting comfortably into " + UtilText.generateSingularDeterminer(viewedBreast.getSize().getCupSizeName()) + " " + viewedBreast.getSize().getCupSizeName() + "-cup bra, and the pairs below each being slightly smaller than the ones above.");
                }
            }
        } else {
            sb.append(" You have a completely flat chest");
            if (viewedBreast.getRows() == 1) {
                sb.append(", with a single pair of pecs.");
            } else {
                sb.append(", with " + Util.intToString(viewedBreast.getRows()) + " pairs of pecs.");
            }
        }
    } else {
        if (viewedBreast.getRawSizeValue() > 0) {
            sb.append(" [npc.She] has " + Util.intToString(viewedBreast.getRows()) + " pair" + (viewedBreast.getRows() == 1 ? "" : "s") + " of " + viewedBreast.getSize().getDescriptor() + " [npc.breasts]");
            if (viewedBreast.getRows() == 1) {
                if (viewedBreast.getSize().isTrainingBraSize()) {
                    sb.append(", which fit comfortably into a training bra.");
                } else {
                    sb.append(", which fit comfortably into " + UtilText.generateSingularDeterminer(viewedBreast.getSize().getCupSizeName()) + " " + viewedBreast.getSize().getCupSizeName() + "-cup bra.");
                }
            } else if (viewedBreast.getRows() == 2) {
                if (viewedBreast.getSize().isTrainingBraSize()) {
                    sb.append(", with [npc.her] top pair fitting comfortably into a training bra, and the pair below being slightly smaller.");
                } else {
                    sb.append(", with [npc.her] top pair fitting comfortably into " + UtilText.generateSingularDeterminer(viewedBreast.getSize().getCupSizeName()) + " " + viewedBreast.getSize().getCupSizeName() + "-cup bra, and the pair below being slightly smaller.");
                }
            } else if (viewedBreast.getRows() > 2) {
                if (viewedBreast.getSize().isTrainingBraSize()) {
                    sb.append(", with [npc.her] top pair fitting comfortably into a training bra, and the pairs below each being slightly smaller than the ones above.");
                } else {
                    sb.append(", with [npc.her] top pair fitting comfortably into " + UtilText.generateSingularDeterminer(viewedBreast.getSize().getCupSizeName()) + " " + viewedBreast.getSize().getCupSizeName() + "-cup bra, and the pairs below each being slightly smaller than the ones above.");
                }
            }
        } else {
            sb.append(" [npc.She] has a completely flat chest");
            if (viewedBreast.getRows() == 1) {
                sb.append(", with a single pair of pecs.");
            } else {
                sb.append(", with " + Util.intToString(viewedBreast.getRows()) + " pairs of pecs.");
            }
        }
    }
    // Nipples & piercings
    sb.append(" " + getBreastDescription(owner, viewedBreast));
    sb.append("</p>");
    // Arms and legs:
    sb.append("<p>");
    // Arms:
    String armDeterminer = "a pair of";
    if (arm.getArmRows() == 3) {
        armDeterminer = "three pairs of";
    } else if (arm.getArmRows() == 2) {
        armDeterminer = "two pairs of";
    }
    switch(arm.getType()) {
        case HUMAN:
            if (owner.isPlayer())
                sb.append("You have " + armDeterminer + " normal human arms and hands, which are " + getCoveredInDescriptor(owner) + " [pc.armFullDescription(true)].");
            else
                sb.append("[npc.She] has " + armDeterminer + " normal human arms and hands, which are " + getCoveredInDescriptor(owner) + " [npc.armFullDescription(true)].");
            break;
        case ANGEL:
            if (owner.isPlayer())
                sb.append("You have " + armDeterminer + " human-like arms and hands, which are " + getCoveredInDescriptor(owner) + " [pc.armFullDescription(true)].");
            else
                sb.append("[npc.She] has " + armDeterminer + " human-like arms and hands, which are " + getCoveredInDescriptor(owner) + " [npc.armFullDescription(true)].");
            break;
        case DEMON_COMMON:
            if (owner.isPlayer())
                sb.append("You have " + armDeterminer + " slender, human-looking arms and hands, which are " + getCoveredInDescriptor(owner) + " [pc.armFullDescription(true)].");
            else
                sb.append("[npc.She] has " + armDeterminer + " slender human-looking arms and hands, which are " + getCoveredInDescriptor(owner) + " [npc.armFullDescription(true)].");
            break;
        case DOG_MORPH:
            if (owner.isPlayer())
                sb.append("You have " + armDeterminer + " arms, which are " + getCoveredInDescriptor(owner) + " [pc.armFullDescription(true)]." + " Your hands are formed into anthropomorphic, dog-like hands, complete with little blunt claws and leathery pads.");
            else
                sb.append("[npc.She] has " + armDeterminer + " arms, which are " + getCoveredInDescriptor(owner) + " [npc.armFullDescription(true)]." + " [npc.Her] hands are formed into anthropomorphic, dog-like hands, complete with little blunt claws and leathery pads.");
            break;
        case ALLIGATOR_MORPH:
            if (owner.isPlayer())
                sb.append("You have " + armDeterminer + " arms, which are " + getCoveredInDescriptor(owner) + " [pc.armFullDescription(true)]." + " Your hands are formed into anthropomorphic, alligator-like hands, complete with little claws.");
            else
                sb.append("[npc.She] has " + armDeterminer + " arms, which are " + getCoveredInDescriptor(owner) + " [npc.armFullDescription(true)]." + " [npc.Her] hands are formed into anthropomorphic, alligator-like hands, complete with little claws.");
            break;
        case LYCAN:
            if (owner.isPlayer())
                sb.append("You have " + armDeterminer + " arms, which are " + getCoveredInDescriptor(owner) + " [pc.armFullDescription(true)]." + " Your hands are formed into anthropomorphic, wolf-like hands, complete with sharp claws and tough leathery pads.");
            else
                sb.append("[npc.She] has " + armDeterminer + " arms, which are " + getCoveredInDescriptor(owner) + " [npc.armFullDescription(true)]." + " [npc.Her] hands are formed into anthropomorphic, wolf-like hands, complete with sharp claws and tough leathery pads.");
            break;
        case CAT_MORPH:
            if (owner.isPlayer())
                sb.append("You have " + armDeterminer + " arms, which are " + getCoveredInDescriptor(owner) + " [pc.armFullDescription(true)]." + " Your hands are formed into anthropomorphic, cat-like hands, complete with retractable claws and pink pads.");
            else
                sb.append("[npc.She] has " + armDeterminer + " arms, which are " + getCoveredInDescriptor(owner) + " [npc.armFullDescription(true)]." + " [npc.Her] hands are formed into anthropomorphic, cat-like hands, complete with retractable claws and pink pads.");
            break;
        case COW_MORPH:
            if (owner.isPlayer())
                sb.append("You have " + armDeterminer + " arms, which are " + getCoveredInDescriptor(owner) + " [pc.armFullDescription(true)]." + " Your hands, while human in shape, have tough little hoof-like nails.");
            else
                sb.append("[npc.She] has " + armDeterminer + " arms, which are " + getCoveredInDescriptor(owner) + " [npc.armFullDescription(true)]." + " [npc.Her] hands, while human in shape, have tough little hoof-like nails.");
            break;
        case SQUIRREL_MORPH:
            if (owner.isPlayer())
                sb.append("You have " + armDeterminer + " arms, which are " + getCoveredInDescriptor(owner) + " [pc.armFullDescription(true)]." + " Your hands are formed into anthropomorphic, squirrel-like hands, complete with claws.");
            else
                sb.append("[npc.She] has " + armDeterminer + " arms, which are " + getCoveredInDescriptor(owner) + " [npc.armFullDescription(true)]." + " [npc.Her] hands are formed into anthropomorphic, squirrel-like hands, complete with claws.");
            break;
        case HORSE_MORPH:
            if (owner.isPlayer())
                sb.append("You have " + armDeterminer + " arms, which are " + getCoveredInDescriptor(owner) + " [pc.armFullDescription(true)]." + " Your hands, while human in shape, have tough little hoof-like nails.");
            else
                sb.append("[npc.She] has " + armDeterminer + " arms, which are " + getCoveredInDescriptor(owner) + " [npc.armFullDescription(true)]." + " [npc.Her] hands, while human in shape, have tough little hoof-like nails.");
            break;
        case REINDEER_MORPH:
            if (owner.isPlayer())
                sb.append("You have " + armDeterminer + " arms, which are " + getCoveredInDescriptor(owner) + " [pc.armFullDescription(true)]." + " Your hands, while human in shape, have tough little hoof-like nails.");
            else
                sb.append("[npc.She] has " + armDeterminer + " arms, which are " + getCoveredInDescriptor(owner) + " [npc.armFullDescription(true)]." + " [npc.Her] hands, while human in shape, have tough little hoof-like nails.");
            break;
        case HARPY:
            if (owner.isPlayer())
                sb.append("Your arms have transformed into " + armDeterminer + " huge wings, and are " + getCoveredInDescriptor(owner) + " beautiful [pc.armFullDescription(true)]." + " Where your hands should be, you have two feathered forefingers and a thumb, each of which ends in a little blunt claw." + " Although slightly less dexterous than a human hand, you're still able to use your remaining digits to form a hand-like grip.");
            else
                sb.append("In place of arms and hands, [npc.she] has " + armDeterminer + " huge wings, which are " + getCoveredInDescriptor(owner) + " beautiful [npc.armFullDescription(true)]." + " Where [npc.her] hands should be, [npc.she] has two feathered forefingers and a thumb, each of which ends in a little blunt claw." + " Although slightly less dexterous than a human hand, [npc.she]'s still able to use [npc.her] digits to form a hand-like grip.");
            break;
        default:
            break;
    }
    if (owner.isPlayer()) {
        if (owner.getHandNailPolish().getPrimaryColour() != Colour.COVERING_NONE) {
            if (owner.getArmType() == ArmType.HARPY) {
                sb.append(" The little claw on your thumb has been painted in " + owner.getCovering(BodyCoveringType.MAKEUP_NAIL_POLISH_HANDS).getFullDescription(owner, true) + ".");
            } else {
                sb.append(" Your fingernails have been painted in " + owner.getCovering(BodyCoveringType.MAKEUP_NAIL_POLISH_HANDS).getFullDescription(owner, true) + ".");
            }
        }
    } else {
        if (owner.getHandNailPolish().getPrimaryColour() != Colour.COVERING_NONE) {
            if (owner.getArmType() == ArmType.HARPY) {
                sb.append(" The little claw on [npc.her] thumb has been painted in " + owner.getCovering(BodyCoveringType.MAKEUP_NAIL_POLISH_HANDS).getFullDescription(owner, true) + ".");
            } else {
                sb.append(" [npc.Her] fingernails have been painted in " + owner.getCovering(BodyCoveringType.MAKEUP_NAIL_POLISH_HANDS).getFullDescription(owner, true) + ".");
            }
        }
    }
    if (Main.game.isBodyHairEnabled()) {
        if (owner.isPlayer()) {
            if (owner.getUnderarmHairType().getType() == BodyCoveringType.BODY_HAIR_SCALES_ALLIGATOR) {
                switch(owner.getUnderarmHair()) {
                    case ZERO_NONE:
                        sb.append(" There's no trace of any rough " + owner.getUnderarmHairType().getName(owner) + " in your armpits.");
                        break;
                    case ONE_STUBBLE:
                        sb.append(" You have a small, rough patch of " + owner.getUnderarmHairType().getFullDescription(owner, true) + " in each of your armpits.");
                        break;
                    case TWO_MANICURED:
                        sb.append(" You have a rough patch of " + owner.getUnderarmHairType().getFullDescription(owner, true) + " in each of your armpits.");
                        break;
                    case THREE_TRIMMED:
                        sb.append(" You have a rough patch of " + owner.getUnderarmHairType().getFullDescription(owner, true) + " in each of your armpits.");
                        break;
                    case FOUR_NATURAL:
                        sb.append(" You have a natural amount of rough " + owner.getUnderarmHairType().getFullDescription(owner, true) + " in each of your armpits.");
                        break;
                    case FIVE_UNKEMPT:
                        sb.append(" You have an unkempt mass of rough " + owner.getUnderarmHairType().getFullDescription(owner, true) + " in each of your armpits.");
                        break;
                    case SIX_BUSHY:
                        sb.append(" You have a thick, rough mass of " + owner.getUnderarmHairType().getFullDescription(owner, true) + " in each of your armpits.");
                        break;
                    case SEVEN_WILD:
                        sb.append(" You have a wild, rough mass of " + owner.getUnderarmHairType().getFullDescription(owner, true) + " in each of your armpits.");
                        break;
                }
            } else {
                switch(owner.getUnderarmHair()) {
                    case ZERO_NONE:
                        sb.append(" There is no trace of any " + owner.getUnderarmHairType().getName(owner) + " in your armpits.");
                        break;
                    case ONE_STUBBLE:
                        sb.append(" You have a stubbly patch of " + owner.getUnderarmHairType().getFullDescription(owner, true) + " in each of your armpits.");
                        break;
                    case TWO_MANICURED:
                        sb.append(" You have a well-manicured patch of " + owner.getUnderarmHairType().getFullDescription(owner, true) + " in each of your armpits.");
                        break;
                    case THREE_TRIMMED:
                        sb.append(" You have a trimmed patch of " + owner.getUnderarmHairType().getFullDescription(owner, true) + " in each of your armpits.");
                        break;
                    case FOUR_NATURAL:
                        sb.append(" You have a natural amount of " + owner.getUnderarmHairType().getFullDescription(owner, true) + " in each of your armpits.");
                        break;
                    case FIVE_UNKEMPT:
                        sb.append(" You have an unkempt mass of " + owner.getUnderarmHairType().getFullDescription(owner, true) + " in each of your armpits.");
                        break;
                    case SIX_BUSHY:
                        sb.append(" You have a thick, bushy mass of " + owner.getUnderarmHairType().getFullDescription(owner, true) + " in each of your armpits.");
                        break;
                    case SEVEN_WILD:
                        sb.append(" You have a wild, bushy mass of " + owner.getUnderarmHairType().getFullDescription(owner, true) + " in each of your armpits.");
                        break;
                }
            }
        } else {
            if (owner.getUnderarmHairType().getType() == BodyCoveringType.BODY_HAIR_SCALES_ALLIGATOR) {
                switch(owner.getUnderarmHair()) {
                    case ZERO_NONE:
                        sb.append(" There is no trace of any rough " + owner.getUnderarmHairType().getName(owner) + " in [npc.her] armpits.");
                        break;
                    case ONE_STUBBLE:
                        sb.append(" [npc.She] has a rough patch of " + owner.getUnderarmHairType().getFullDescription(owner, true) + " in each of [npc.her] armpits.");
                        break;
                    case TWO_MANICURED:
                        sb.append(" [npc.She] has a rough patch of " + owner.getUnderarmHairType().getFullDescription(owner, true) + " in each of [npc.her] armpits.");
                        break;
                    case THREE_TRIMMED:
                        sb.append(" [npc.She] has a rough patch of " + owner.getUnderarmHairType().getFullDescription(owner, true) + " in each of [npc.her] armpits.");
                        break;
                    case FOUR_NATURAL:
                        sb.append(" [npc.She] has a natural amount of rough " + owner.getUnderarmHairType().getFullDescription(owner, true) + " in each of [npc.her] armpits.");
                        break;
                    case FIVE_UNKEMPT:
                        sb.append(" [npc.She] has a unkempt mass of rough " + owner.getUnderarmHairType().getFullDescription(owner, true) + " in each of [npc.her] armpits.");
                        break;
                    case SIX_BUSHY:
                        sb.append(" [npc.She] has a thick, rough mass of " + owner.getUnderarmHairType().getFullDescription(owner, true) + " in each of [npc.her] armpits.");
                        break;
                    case SEVEN_WILD:
                        sb.append(" [npc.She] has a wild, rough mass of " + owner.getUnderarmHairType().getFullDescription(owner, true) + " in each of [npc.her] armpits.");
                        break;
                }
            } else {
                switch(owner.getUnderarmHair()) {
                    case ZERO_NONE:
                        sb.append(" There is no trace of any " + owner.getUnderarmHairType().getName(owner) + " in [npc.her] armpits.");
                        break;
                    case ONE_STUBBLE:
                        sb.append(" [npc.She] has a stubbly patch of " + owner.getUnderarmHairType().getFullDescription(owner, true) + " in each of [npc.her] armpits.");
                        break;
                    case TWO_MANICURED:
                        sb.append(" [npc.She] has a well-manicured patch of " + owner.getUnderarmHairType().getFullDescription(owner, true) + " in each of [npc.her] armpits.");
                        break;
                    case THREE_TRIMMED:
                        sb.append(" [npc.She] has a trimmed patch of " + owner.getUnderarmHairType().getFullDescription(owner, true) + " in each of [npc.her] armpits.");
                        break;
                    case FOUR_NATURAL:
                        sb.append(" [npc.She] has a natural amount of " + owner.getUnderarmHairType().getFullDescription(owner, true) + " in each of [npc.her] armpits.");
                        break;
                    case FIVE_UNKEMPT:
                        sb.append(" [npc.She] has a unkempt mass of " + owner.getUnderarmHairType().getFullDescription(owner, true) + " in each of [npc.her] armpits.");
                        break;
                    case SIX_BUSHY:
                        sb.append(" [npc.She] has a thick, bushy mass of " + owner.getUnderarmHairType().getFullDescription(owner, true) + " in each of [npc.her] armpits.");
                        break;
                    case SEVEN_WILD:
                        sb.append(" [npc.She] has a wild, bushy mass of " + owner.getUnderarmHairType().getFullDescription(owner, true) + " in each of [npc.her] armpits.");
                        break;
                }
            }
        }
    }
    sb.append("</br>");
    // Legs:
    switch(leg.getType()) {
        case HUMAN:
            if (owner.isPlayer())
                sb.append("You have a pair of human legs and feet, which are " + getCoveredInDescriptor(owner) + " [pc.legFullDescription(true)].");
            else
                sb.append("[npc.Her] legs and feet are human, and are " + getCoveredInDescriptor(owner) + " [npc.legFullDescription(true)].");
            break;
        case ANGEL:
            if (owner.isPlayer())
                sb.append("Your legs and feet are human in shape, but are " + getCoveredInDescriptor(owner) + " [pc.legFullDescription(true)].");
            else
                sb.append("[npc.Her] legs and feet are human in shape, but are " + getCoveredInDescriptor(owner) + " [npc.legFullDescription(true)].");
            break;
        case DEMON_COMMON:
            if (owner.isPlayer())
                sb.append("Your legs and feet are human in shape, but are " + getCoveredInDescriptor(owner) + " [pc.legFullDescription(true)].");
            else
                sb.append("[npc.Her] legs and feet are human in shape, but are " + getCoveredInDescriptor(owner) + " [npc.legFullDescription(true)].");
            break;
        case DOG_MORPH:
            if (owner.isPlayer())
                sb.append("Your legs are " + getCoveredInDescriptor(owner) + " [pc.legFullDescription(true)]," + " and your feet are formed into anthropomorphic dog-like paws, complete with little blunt claws and leathery pads.");
            else
                sb.append("[npc.Her] legs are " + getCoveredInDescriptor(owner) + " [npc.legFullDescription(true)]," + " and [npc.her] feet are formed into anthropomorphic dog-like paws, complete with little blunt claws and leathery pads.");
            break;
        case LYCAN:
            if (owner.isPlayer())
                sb.append("Your legs are " + getCoveredInDescriptor(owner) + " [pc.legFullDescription(true)]," + " and your feet are formed into anthropomorphic wolf-like paws, complete with sharp claws and tough leathery pads.");
            else
                sb.append("[npc.Her] legs are " + getCoveredInDescriptor(owner) + " [npc.legFullDescription(true)]," + " and [npc.her] feet are formed into anthropomorphic wolf-like paws, complete with sharp claws and tough leathery pads.");
            break;
        case ALLIGATOR_MORPH:
            if (owner.isPlayer())
                sb.append("Your legs are " + getCoveredInDescriptor(owner) + " [pc.legFullDescription(true)]," + " and your feet are formed into anthropomorphic alligator-like feet, complete with sharp claws.");
            else
                sb.append("[npc.Her] legs are " + getCoveredInDescriptor(owner) + " [npc.legFullDescription(true)]," + " and [npc.her] feet are formed into anthropomorphic alligator-like feet, complete with sharp claws.");
            break;
        case CAT_MORPH:
            if (owner.isPlayer())
                sb.append("Your legs are " + getCoveredInDescriptor(owner) + " [pc.legFullDescription(true)]," + " and your feet are formed into anthropomorphic cat-like paws, complete with retractable claws and pink pads.");
            else
                sb.append("[npc.Her] legs are " + getCoveredInDescriptor(owner) + " [npc.legFullDescription(true)]," + " and [npc.her] feet are formed into anthropomorphic cat-like paws, complete with retractable claws and pink pads.");
            break;
        case SQUIRREL_MORPH:
            if (owner.isPlayer())
                sb.append("Your legs are " + getCoveredInDescriptor(owner) + " [pc.legFullDescription(true)]," + " and your feet are formed into anthropomorphic squirrel-like paws, complete with claws and pink pads.");
            else
                sb.append("[npc.Her] legs are " + getCoveredInDescriptor(owner) + " [npc.legFullDescription(true)]," + " and [npc.her] feet are formed into anthropomorphic squirrel-like paws, complete with claws and pink pads.");
            break;
        case HORSE_MORPH:
            if (owner.isPlayer())
                sb.append("Your legs are " + getCoveredInDescriptor(owner) + " [pc.legFullDescription(true)]," + " and your feet are formed into anthropomorphic horse-like hooves.");
            else
                sb.append("[npc.Her] legs are " + getCoveredInDescriptor(owner) + " [npc.legFullDescription(true)]," + " and [npc.her] feet are formed into anthropomorphic horse-like hooves.");
            break;
        case REINDEER_MORPH:
            if (owner.isPlayer())
                sb.append("Your legs are " + getCoveredInDescriptor(owner) + " <span style='color:[pc.legColourHex];'>[pc.legColour] [pc.legSkin]</span>," + " and your feet are formed into anthropomorphic reindeer-like hooves.");
            else
                sb.append("[npc.Her] legs are " + getCoveredInDescriptor(owner) + " <span style='color:[npc.legColourHex];'>[npc.legColour] [npc.legSkin]</span>," + " and [npc.her] feet are formed into anthropomorphic reindeer-like hooves.");
            break;
        case COW_MORPH:
            if (owner.isPlayer())
                sb.append("Your legs are " + getCoveredInDescriptor(owner) + " [pc.legFullDescription(true)]," + " and your feet are formed into anthropomorphic cow-like hooves.");
            else
                sb.append("[npc.Her] legs are " + getCoveredInDescriptor(owner) + " [npc.legFullDescription(true)]," + " and [npc.her] feet are formed into anthropomorphic cow-like hooves.");
            break;
        case HARPY:
            if (owner.isPlayer())
                sb.append("Your upper thighs are " + getCoveredInDescriptor(owner) + " [pc.legFullDescription(true)], which transition into leathery bird-like skin just above your knee." + " While your legs still retain a human-like shape, your feet have transformed into bird-like talons.");
            else
                sb.append("[npc.Her] upper thighs are " + getCoveredInDescriptor(owner) + " [npc.legFullDescription(true)], which transition into leathery bird-like skin just above [npc.her] knee." + " While [npc.her] legs still retain a human-like shape, [npc.her] feet have transformed into bird-like talons.");
            break;
        default:
            break;
    }
    if (owner.isPlayer()) {
        if (owner.getFootNailPolish().getPrimaryColour() != Colour.COVERING_NONE) {
            if (owner.getLegType() == LegType.HARPY) {
                sb.append(" The claws on your talons have been painted in " + owner.getCovering(BodyCoveringType.MAKEUP_NAIL_POLISH_FEET).getFullDescription(owner, true) + ".");
            } else if (owner.getLegType() == LegType.HORSE_MORPH) {
                sb.append(" Your hooves have been painted in " + owner.getCovering(BodyCoveringType.MAKEUP_NAIL_POLISH_FEET).getFullDescription(owner, true) + ".");
            } else if (owner.getLegType() == LegType.COW_MORPH) {
                sb.append(" Your hooves have been painted in " + owner.getCovering(BodyCoveringType.MAKEUP_NAIL_POLISH_FEET).getFullDescription(owner, true) + ".");
            } else {
                sb.append(" Your toenails have been painted in " + owner.getCovering(BodyCoveringType.MAKEUP_NAIL_POLISH_FEET).getFullDescription(owner, true) + ".");
            }
        }
    } else {
        if (owner.getFootNailPolish().getPrimaryColour() != Colour.COVERING_NONE) {
            if (owner.getLegType() == LegType.HARPY) {
                sb.append(" The claws on [npc.her] talons have been painted in " + owner.getCovering(BodyCoveringType.MAKEUP_NAIL_POLISH_FEET).getFullDescription(owner, true) + ".");
            } else if (owner.getLegType() == LegType.HORSE_MORPH) {
                sb.append(" [npc.Her] hooves have been painted in " + owner.getCovering(BodyCoveringType.MAKEUP_NAIL_POLISH_FEET).getFullDescription(owner, true) + ".");
            } else if (owner.getLegType() == LegType.COW_MORPH) {
                sb.append(" [npc.Her] hooves have been painted in " + owner.getCovering(BodyCoveringType.MAKEUP_NAIL_POLISH_FEET).getFullDescription(owner, true) + ".");
            } else {
                sb.append(" [npc.Her] toenails have been painted in " + owner.getCovering(BodyCoveringType.MAKEUP_NAIL_POLISH_FEET).getFullDescription(owner, true) + ".");
            }
        }
    }
    sb.append("</br>");
    if (owner.isPlayer()) {
        sb.append(" All of your limbs ");
    } else {
        sb.append(" All of [npc.her] limbs ");
    }
    if (femininity <= Femininity.MASCULINE_STRONG.getMaximumFemininity()) {
        sb.append(UtilText.returnStringAtRandom("<span style='color:" + Colour.MASCULINE_PLUS.toWebHexString() + ";'>have a very masculine shape to them</span>."));
    } else if (femininity <= Femininity.MASCULINE.getMaximumFemininity()) {
        sb.append(UtilText.returnStringAtRandom("<span style='color:" + Colour.MASCULINE.toWebHexString() + ";'>have a masculine shape to them</span>."));
    } else if (femininity <= Femininity.ANDROGYNOUS.getMaximumFemininity()) {
        sb.append("<span style='color:" + Colour.ANDROGYNOUS.toWebHexString() + ";'>look quite androgynous, and could easily belong to either a male or female</span>.");
    } else if (femininity <= Femininity.FEMININE.getMaximumFemininity()) {
        sb.append(UtilText.returnStringAtRandom("<span style='color:" + Colour.FEMININE.toWebHexString() + ";'>are slender and feminine-looking</span>."));
    } else {
        sb.append(UtilText.returnStringAtRandom("<span style='color:" + Colour.FEMININE_PLUS.toWebHexString() + ";'>have an extremely feminine shape to them</span>."));
    }
    sb.append("</p>");
    // Tail, wings & ass:
    if (wing.getType() != WingType.NONE || tail.getType() != TailType.NONE) {
        sb.append("<p>");
        // Wing:
        switch(wing.getType()) {
            case DEMON_COMMON:
                if (owner.isPlayer()) {
                    sb.append("Growing from your shoulder-blades, you have a pair of [pc.wingSize] bat-like wings.");
                } else {
                    sb.append("Growing from [npc.her] shoulder-blades, [npc.she] has a pair of [npc.wingSize] bat-like wings.");
                }
                break;
            case ANGEL:
                if (owner.isPlayer()) {
                    sb.append("Growing from your shoulder-blades, you have [pc.a_wingSize] pair of white feathered wings.");
                } else {
                    sb.append("Growing from [npc.her] shoulder-blades, [npc.she] has [pc.a_wingSize] pair of white feathered wings.");
                }
                break;
            default:
                break;
        }
        if (wing.getType().allowsFlight()) {
            if (wing.getSizeValue() >= WingSize.TWO_AVERAGE.getValue()) {
                if (owner.isPlayer()) {
                    sb.append(" They are large enough that they can be used to allow you to fly.");
                } else {
                    sb.append(" They are large enough that they can be used to allow [npc.her] to fly.");
                }
            } else {
                if (owner.isPlayer()) {
                    sb.append(" They aren't large enough to allow you to fly.");
                } else {
                    sb.append(" They aren't large enough to allow [npc.her] to fly.");
                }
            }
        } else if (wing.getType() != WingType.NONE) {
            sb.append(" They are entirely incapable of flight.");
        }
        if (tail.getType() != TailType.NONE) {
            if (owner.isPlayer()) {
                sb.append(" Growing out from just above your ass, you have ");
            } else {
                sb.append(" Growing out from just above [npc.her] ass, [npc.she] has ");
            }
        }
        if (owner.getTailCount() == 1) {
            switch(owner.getTailType()) {
                case CAT_MORPH:
                    if (owner.isPlayer()) {
                        sb.append("a furry, [pc.tailColour(true)] cat-like tail, which you can control well enough to grant you significantly improved balance.");
                    } else {
                        sb.append("a furry, [npc.tailColour(true)] cat-like tail, which [npc.she] can control well enough to grant [npc.herHim] significantly improved balance.");
                    }
                    break;
                case DEMON_COMMON:
                    if (owner.isPlayer()) {
                        sb.append("a spaded, [pc.tailColour(true)] demonic tail, over which you have complete control, and you can easily use it to grip and hold objects.");
                    } else {
                        sb.append("a spaded, [npc.tailColour(true)] demonic tail, over which [npc.she] has complete control, and [npc.she] can easily use it to grip and hold objects.");
                    }
                    break;
                case IMP:
                    if (owner.isPlayer()) {
                        sb.append("a spaded, [pc.tailColour(true)] impish tail, over which you have complete control, and you can easily use it to grip and hold objects.");
                    } else {
                        sb.append("a spaded, [npc.tailColour(true)] impish tail, over which [npc.she] has complete control, and [npc.she] can easily use it to grip and hold objects.");
                    }
                    break;
                case DOG_MORPH:
                    if (owner.isPlayer()) {
                        sb.append("a furry, [pc.tailColour(true)] dog-like tail, which wags uncontrollably when you get excited.");
                    } else {
                        sb.append("a furry, [npc.tailColour(true)] dog-like tail, which wags uncontrollably when [npc.she] gets excited.");
                    }
                    break;
                case DOG_MORPH_STUBBY:
                    if (owner.isPlayer()) {
                        sb.append("a stubby, [pc.tailColour(true)] dog-like tail, which wags uncontrollably when you get excited.");
                    } else {
                        sb.append("a stubby, [npc.tailColour(true)] dog-like tail, which wags uncontrollably when [npc.she] gets excited.");
                    }
                    break;
                case ALLIGATOR_MORPH:
                    if (owner.isPlayer()) {
                        sb.append("a long, [pc.tailColour(true)] alligator-like tail, which you can swipe from side to side with considerable force.");
                    } else {
                        sb.append("a long, [npc.tailColour(true)] alligator-like tail, which [npc.she] can swipe from side to side with considerable force.");
                    }
                    break;
                case HARPY:
                    if (owner.isPlayer()) {
                        sb.append("a plume of beautiful, [pc.tailColour(true)] tail-feathers, which you can rapidly move up and down to help you keep your balance and to control your path when in flight.");
                    } else {
                        sb.append("a plume of beautiful, [npc.tailColour(true)] tail-feathers, which [npc.she] can rapidly move up and down to help [npc.herHim] keep [npc.her] balance and to control [npc.her] path when in flight.");
                    }
                    break;
                case HORSE_MORPH:
                    if (owner.isPlayer()) {
                        sb.append("a long, [pc.tailColour(true)] horse-like tail, which you can swipe from side to side, but other than that, you don't have much control over it.");
                    } else {
                        sb.append("a long, [npc.tailColour(true)] horse-like tail, which [npc.she] can swipe from side to side, but other than that, [npc.she] doesn't have much control over it.");
                    }
                    break;
                case REINDEER_MORPH:
                    if (owner.isPlayer()) {
                        sb.append("a short, [pc.tailColour(true)] reindeer-like tail.");
                    } else {
                        sb.append("a short, [npc.tailColour(true)] reindeer-like tail.");
                    }
                    break;
                case COW_MORPH:
                    if (owner.isPlayer()) {
                        sb.append("a long, [pc.tailColour(true)] cow-like tail, which you can swipe from side to side, but other than that, you don't have much control over it.");
                    } else {
                        sb.append("a long, [npc.tailColour(true)] cow-like tail, which [npc.she] can swipe from side to side, but other than that, [npc.she] doesn't have much control over it.");
                    }
                    break;
                case LYCAN:
                    if (owner.isPlayer()) {
                        sb.append("a furry, [pc.tailColour(true)] wolf-like tail.");
                    } else {
                        sb.append("a furry, [npc.tailColour(true)] wolf-like tail.");
                    }
                    break;
                case SQUIRREL_MORPH:
                    if (owner.isPlayer()) {
                        sb.append("a fluffy, [pc.tailColour(true)] squirrel-like tail, which you can control well enough to grant you significantly improved balance.");
                    } else {
                        sb.append("a fluffy, [npc.tailColour(true)] squirrel-like tail, which [npc.she] can control well enough to grant [npc.herHim] significantly improved balance.");
                    }
                    break;
                case NONE:
                    break;
            }
        } else {
            sb.append(Util.intToString(owner.getTailCount()) + " ");
            switch(owner.getTailType()) {
                case CAT_MORPH:
                    if (owner.isPlayer()) {
                        sb.append("furry, [pc.tailColour(true)] cat-like tails, which you can control well enough to grant you significantly improved balance.");
                    } else {
                        sb.append("furry, [npc.tailColour(true)] cat-like tails, which [npc.she] can control well enough to grant [npc.herHim] significantly improved balance.");
                    }
                    break;
                case DEMON_COMMON:
                    if (owner.isPlayer()) {
                        sb.append("spaded, [pc.tailColour(true)] demonic tails, over which you have complete control, and you can easily use them to grip and hold objects.");
                    } else {
                        sb.append("spaded, [npc.tailColour(true)] demonic tails, over which [npc.she] has complete control, and [npc.she] can easily use them to grip and hold objects.");
                    }
                    break;
                case IMP:
                    if (owner.isPlayer()) {
                        sb.append("spaded, [pc.tailColour(true)] impish tails, over which you have complete control, and you can easily use them to grip and hold objects.");
                    } else {
                        sb.append("spaded, [npc.tailColour(true)] impish tails, over which [npc.she] has complete control, and [npc.she] can easily use them to grip and hold objects.");
                    }
                    break;
                case DOG_MORPH:
                    if (owner.isPlayer()) {
                        sb.append("furry, [pc.tailColour(true)] dog-like tails, which wag uncontrollably when you get excited.");
                    } else {
                        sb.append("furry, [npc.tailColour(true)] dog-like tails, which wag uncontrollably when [npc.she] gets excited.");
                    }
                    break;
                case DOG_MORPH_STUBBY:
                    if (owner.isPlayer()) {
                        sb.append("stubby, [pc.tailColour(true)] dog-like tails, which wag uncontrollably when you get excited.");
                    } else {
                        sb.append("stubby, [npc.tailColour(true)] dog-like tails, which wag uncontrollably when [npc.she] gets excited.");
                    }
                    break;
                case ALLIGATOR_MORPH:
                    if (owner.isPlayer()) {
                        sb.append("long, [pc.tailColour(true)] alligator-like tails, which you can swipe from side to side with considerable force.");
                    } else {
                        sb.append("long, [npc.tailColour(true)] alligator-like tails, which [npc.she] can swipe from side to side with considerable force.");
                    }
                    break;
                case HARPY:
                    if (owner.isPlayer()) {
                        sb.append("plumes of beautiful, [pc.tailColour(true)] tail-feathers, which you can rapidly move up and down to help you keep your balance and to control your path when in flight.");
                    } else {
                        sb.append("plumes of beautiful, [npc.tailColour(true)] tail-feathers, which [npc.she] can rapidly move up and down to help [npc.herHim] keep [npc.her] balance and to control [npc.her] path when in flight.");
                    }
                    break;
                case HORSE_MORPH:
                    if (owner.isPlayer()) {
                        sb.append("long, [pc.tailColour(true)] horse-like tails, which you can swipe from side to side, but other than that, you don't have much control over them.");
                    } else {
                        sb.append("long, [npc.tailColour(true)] horse-like tails, which [npc.she] can swipe from side to side, but other than that, [npc.she] doesn't have much control over them.");
                    }
                    break;
                case REINDEER_MORPH:
                    if (owner.isPlayer()) {
                        sb.append("short, [pc.tailColour(true)] reindeer-like tails.");
                    } else {
                        sb.append("short, [npc.tailColour(true)] reindeer-like tails.");
                    }
                    break;
                case COW_MORPH:
                    if (owner.isPlayer()) {
                        sb.append("long, [pc.tailColour(true)] cow-like tails, which you can swipe from side to side, but other than that, you don't have much control over them.");
                    } else {
                        sb.append("long, [npc.tailColour(true)] cow-like tails, which [npc.she] can swipe from side to side, but other than that, [npc.she] doesn't have much control over them.");
                    }
                    break;
                case LYCAN:
                    if (owner.isPlayer()) {
                        sb.append("furry, [pc.tailColour(true)] wolf-like tails.");
                    } else {
                        sb.append("furry, [npc.tailColour(true)] wolf-like tails.");
                    }
                    break;
                case SQUIRREL_MORPH:
                    if (owner.isPlayer()) {
                        sb.append("fluffy, [pc.tailColour(true)] squirrel-like tails, which you can control well enough to grant you significantly improved balance.");
                    } else {
                        sb.append("fluffy, [npc.tailColour(true)] squirrel-like tails, which [npc.she] can control well enough to grant [npc.herHim] significantly improved balance.");
                    }
                    break;
                case NONE:
                    break;
            }
        }
        sb.append("</p>");
    }
    sb.append("<p>");
    // Ass & hips:
    if (owner.isPlayer()) {
        sb.append("Your [pc.hips+] and [pc.assSize] [pc.ass] are " + getCoveredInDescriptor(owner) + " [pc.assFullDescription(true)].");
    } else {
        sb.append("[npc.Her] [npc.hips+] and [npc.assSize] [npc.ass] are " + getCoveredInDescriptor(owner) + " [npc.assFullDescription(true)].");
    }
    if (owner.getPlayerKnowsAreas().contains(CoverableArea.ANUS)) {
        sb.append(" " + getAssDescription(owner));
        sb.append("</p>");
    } else {
        sb.append(" <span style='color:" + Colour.GENERIC_SEX.toWebHexString() + ";'>You haven't seen [npc.her] naked ass before, so you don't know what [npc.her] asshole looks like.</span>");
        sb.append("</p>");
    }
    // TODO pubic hair
    if (owner.getPlayerKnowsAreas().contains(CoverableArea.VAGINA) && owner.getPlayerKnowsAreas().contains(CoverableArea.PENIS)) {
        // Vagina, virgin/capacity, wetness:
        if (vagina.getType() == VaginaType.NONE && penis.getType() == PenisType.NONE) {
            sb.append("<p>" + getMoundDescription(owner) + "</p>");
        }
    }
    if (owner.getPlayerKnowsAreas().contains(CoverableArea.PENIS)) {
        // Penises, cum production, testicle size, capacity:
        if (penis.getType() != PenisType.NONE) {
            sb.append("<p>" + getPenisDescription(owner) + "</p>");
        }
    } else {
        sb.append(" <p>" + "<span style='color:" + Colour.GENERIC_SEX.toWebHexString() + ";'>You haven't seen [npc.her] naked groin before, so you don't know what [npc.her] cock looks like, or even if [npc.she] has one.</span>" + "</p>");
    }
    if (owner.getPlayerKnowsAreas().contains(CoverableArea.VAGINA)) {
        // Vagina, virgin/capacity, wetness:
        if (vagina.getType() != VaginaType.NONE) {
            sb.append("<p>" + getVaginaDescription(owner) + "</p>");
        }
    } else {
        sb.append(" <p>" + "<span style='color:" + Colour.GENERIC_SEX.toWebHexString() + ";'>You haven't seen [npc.her] naked groin before, so you don't know what [npc.her] pussy looks like, or even if [npc.she] has one.</span>" + "</p>");
    }
    if (!owner.isPlayer()) {
        sb.append(getSexDetails(owner));
        sb.append(getPregnancyDetails(owner));
    }
    return UtilText.parse(owner, sb.toString());
}
Also used : SexType(com.lilithsthrone.game.sex.SexType) TongueModifier(com.lilithsthrone.game.character.body.valueEnums.TongueModifier) PenetrationType(com.lilithsthrone.game.sex.PenetrationType) OrificeModifier(com.lilithsthrone.game.character.body.valueEnums.OrificeModifier)

Example 12 with OrificeModifier

use of com.lilithsthrone.game.character.body.valueEnums.OrificeModifier in project liliths-throne-public by Innoxia.

the class Mouth method getDescriptor.

@Override
public String getDescriptor(GameCharacter owner) {
    List<String> descriptorList = new ArrayList<>();
    for (OrificeModifier om : orificeMouth.getOrificeModifiers()) {
        descriptorList.add(om.getName());
    }
    descriptorList.add(type.getDescriptor(owner));
    return UtilText.returnStringAtRandom(descriptorList.toArray(new String[] {}));
}
Also used : ArrayList(java.util.ArrayList) OrificeModifier(com.lilithsthrone.game.character.body.valueEnums.OrificeModifier)

Example 13 with OrificeModifier

use of com.lilithsthrone.game.character.body.valueEnums.OrificeModifier in project liliths-throne-public by Innoxia.

the class Nipples method getDescriptor.

@Override
public String getDescriptor(GameCharacter owner) {
    List<String> descriptorList = new ArrayList<>();
    for (OrificeModifier om : orificeNipples.getOrificeModifiers()) {
        descriptorList.add(om.getName());
    }
    if (owner.isBreastFuckableNipplePenetration()) {
        switch(owner.getBreastMilkStorage().getAssociatedWetness()) {
            case ONE_SLIGHTLY_MOIST:
            case TWO_MOIST:
            case THREE_WET:
            case FOUR_SLIMY:
            case FIVE_SLOPPY:
            case SIX_SOPPING_WET:
            case SEVEN_DROOLING:
                descriptorList.add(owner.getBreastMilkStorage().getAssociatedWetness().getDescriptor());
                break;
            default:
                break;
        }
    }
    if (Main.game.isInSex()) {
        if (!Sex.getWetOrificeTypes(owner).get(OrificeType.NIPPLE).isEmpty()) {
            descriptorList.add("wet");
        }
    }
    descriptorList.add(type.getDescriptor(owner));
    if (orificeNipples.getCapacity() != Capacity.ZERO_IMPENETRABLE) {
        descriptorList.add(orificeNipples.getCapacity().getDescriptor());
    }
    return UtilText.returnStringAtRandom(descriptorList.toArray(new String[] {}));
}
Also used : ArrayList(java.util.ArrayList) OrificeModifier(com.lilithsthrone.game.character.body.valueEnums.OrificeModifier)

Example 14 with OrificeModifier

use of com.lilithsthrone.game.character.body.valueEnums.OrificeModifier in project liliths-throne-public by Innoxia.

the class Vagina method setType.

public String setType(GameCharacter owner, VaginaType type, boolean overridePregnancyPrevention) {
    if (type == owner.getVaginaType()) {
        if (owner.isPlayer()) {
            if (type == VaginaType.NONE) {
                return "<p style='text-align:center;'>[style.colourDisabled(You already lack a vagina, so nothing happens...)]</p>";
            } else {
                return "<p style='text-align:center;'>[style.colourDisabled(You already have [pc.a_vaginaRace]'s pussy, so nothing happens...)]</p>";
            }
        } else {
            if (type == VaginaType.NONE) {
                return UtilText.parse(owner, "<p style='text-align:center;'>[style.colourDisabled([npc.Name] already lacks a vagina, so nothing happens...)]</p>");
            } else {
                return UtilText.parse(owner, "<p style='text-align:center;'>[style.colourDisabled([npc.Name] already has [npc.a_vaginaRace] pussy, so nothing happens...)]</p>");
            }
        }
    }
    UtilText.transformationContentSB.setLength(0);
    // Cannot transform if pregnant:
    if (!overridePregnancyPrevention && (owner.isPregnant() || owner.hasStatusEffect(StatusEffect.PREGNANT_0))) {
        if (owner.isPlayer()) {
            UtilText.transformationContentSB.append("<p>" + "You feel your [pc.pussy+] start to grow hot and sensitive, and you let out a lewd moan as a wave of tingling excitement washes through your lower abdomen." + " Much to your surprise, the feeling fades away almost as quickly as it came, and you realise that " + (owner.hasStatusEffect(StatusEffect.PREGNANT_0) ? "<b>the possibility of being pregnant has prevented your vagina from transforming</b>!" : "<b>your ongoing pregnancy has prevented your vagina from transforming</b>!") + "</br>" + "Your pussy remains [style.boldTfSex(unchanged)]." + "</p>");
        } else {
            UtilText.transformationContentSB.append(UtilText.parse(owner, "<p>" + "[npc.Name] lets out a lewd moan as [npc.she] feels [npc.her] [npc.pussy+] starting to grow hot and sensitive," + " and as a wave of tingling excitement washes through [npc.her] lower abdomen, [npc.her] moan turns into a desperate gasp." + " Much to [npc.her] surprise, the feeling fades away almost as quickly as it came, and with a sigh, [npc.she] realises that " + (owner.hasStatusEffect(StatusEffect.PREGNANT_0) ? "<b>the possibility of being pregnant has prevented [npc.her] vagina from transforming</b>!" : "<b>[npc.her] ongoing pregnancy has prevented [npc.her] vagina from transforming</b>!") + "</br>" + "[npc.Name]'s pussy remains [style.boldTfSex(unchanged)]." + "</p>"));
        }
        return UtilText.transformationContentSB.toString() + "<p>" + owner.postTransformationCalculation() + "</p>";
    }
    // If have no vagina:
    if (owner.getVaginaType() == VaginaType.NONE) {
        if (owner.isPlayer()) {
            UtilText.transformationContentSB.append("<p>" + "You feel a strange heat spreading through your groin, and you let out an involuntary moan as you feel the [pc.skin] between your [pc.legs] starting to cave inwards." + " Within moments, a deep furrow has formed " + (owner.getPenisType() == PenisType.NONE ? "in the middle of your groin," : "beneath your cock,") + " and you start panting and squirming as the strange feeling shows no sign of stopping there." + " A sudden, penetrating sensation tears through your groin, and while it isn't painful, you still cry out in shock as the groove between your legs splits and forms into a new, virgin pussy." + " As the feeling finally starts to fade away, your new clit and labia finish forming, and a trickle of girl-cum leaks out from your excited slit." + "</p>" + "<p>" + "Just as you start thinking that the transformation is over, a warm, tingling feeling shoots up into your lower abdomen," + " and you can't help but let out a desperate squeal as you feel a full female reproductive system rapidly growing inside of you." + " As your transformation finally comes to an end, you're left panting and covered in sweat, and you feel that your new cunt is already soaking wet from arousal." + "</br>" + "You now have a [style.boldTfSex(vagina)]!" + "</p>");
            if (owner.hasFetish(Fetish.FETISH_PURE_VIRGIN)) {
                UtilText.transformationContentSB.append("<p style='text-align:center;'>" + "[style.boldExcellent(Pure Virgin)]" + "</p>" + "<p>" + "You can't remember the last time you felt so good." + " As your new pussy finishes growing, you realise that you're now technically a virgin once more." + " After all, this pussy has never been penetrated before!" + "</p>" + "<p style='text-align:center;'>" + "[pc.thought(I-I'm a virgin?!" + "</br>" + "Yes! I'm a virgin!)]" + "</p>" + "<p>" + "The elation you feel at discovering that you're a virgin again is unlike anything you've ever felt before." + " Tears start to well up in your eyes as you find yourself overcome with joy." + "</p>" + "<p>" + "You are invincible." + " You can overcome any obstacle that's placed in your way." + " You are..." + "</p>" + "<p style='text-align:center;'>" + "[style.boldExcellent(A Pure Virgin!)]" + "</p>");
            }
        } else {
            UtilText.transformationContentSB.append(UtilText.parse(owner, "<p>" + "[npc.Name] blushes as [npc.she] feels a strange heat spreading through [npc.her] groin," + " and can't help but let out an involuntary moan as [npc.she] feels the [npc.skin] between [npc.her] [npc.legs] starting to cave inwards." + " Within moments, a deep furrow has formed " + (owner.getPenisType() == PenisType.NONE ? "in the middle of [npc.her] groin," : "beneath [npc.her] cock,") + " and [npc.she] starts panting and squirming as the strange feeling shows no sign of stopping there." + " A sudden, penetrating sensation tears through [npc.her] groin, and while it isn't painful, [npc.she] still cries out in shock as the groove between [npc.her] legs splits and forms into a new, virgin pussy." + " As the feeling finally starts to fade away, [npc.her] new clit and labia finish forming, and a trickle of girl-cum leaks out from [npc.her] excited slit." + "</p>" + "<p>" + "Just as [npc.she] starts to think that the transformation is over, a warm, tingling feeling shoots up into [npc.her] lower abdomen," + " and [npc.she] can't help but let out a desperate squeal as [npc.she] feels a full female reproductive system rapidly growing inside of [npc.herHim]." + " As [npc.her] transformation finally comes to an end, [npc.she]'s left panting and covered in sweat, and [npc.she] lets out a lewd moan as [npc.she] feels that [npc.her] new cunt is already soaking wet from arousal." + "</br>" + "[npc.Name] now has a [style.boldTfSex(vagina)]!" + "</p>"));
        }
        this.type = VaginaType.HUMAN;
        if (type == VaginaType.HUMAN) {
            return UtilText.transformationContentSB.toString() + "<p>" + owner.postTransformationCalculation() + "</p>";
        } else {
            return UtilText.transformationContentSB.toString() + owner.setVaginaType(type);
        }
    } else {
        if (owner.isPlayer()) {
            UtilText.transformationContentSB.append("<p>" + "A strange heat suddenly washes through your pussy, and you cry out as it starts to transform.");
        } else {
            UtilText.transformationContentSB.append(UtilText.parse(owner, "<p>" + "[npc.Name] suddenly blushes and squeezes [npc.her] thighs together as [npc.she] feels [npc.her] pussy starting to transform."));
        }
    }
    this.type = type;
    switch(type) {
        case NONE:
            if (owner.isPlayer()) {
                UtilText.transformationContentSB.append(" You feel your pussy suddenly tighten and squeeze shut, and you let out a cry as a strange pressure fills your lower abdomen." + " Thankfully, it doesn't last long, and when the discomfort subsides, you gasp as you suddenly realise that your cunt has vanished, along with all of your female reproductive organs." + "</br>" + "You have [style.boldSex(lost your vagina)]." + "</p>");
            } else {
                UtilText.transformationContentSB.append(UtilText.parse(owner, " [npc.She] moans and squirms about as [npc.she] feels [npc.her] pussy suddenly tighten and squeeze shut, and with a desperate cry, a strange pressure washes through [npc.her] lower abdomen." + " Thankfully for [npc.herHim], the feeling fades almost as quickly as it came, and when the discomfort subsides, [npc.she] gasps as [npc.she] suddenly realises that [npc.her] cunt has vanished," + " along with all of [npc.her] female reproductive organs." + "</br>" + "[npc.Name] has [style.boldSex(lost [npc.her] vagina)]." + "</p>"));
            }
            if (owner.isPlayer() && owner.hasFetish(Fetish.FETISH_PURE_VIRGIN)) {
                if (!owner.isVaginaVirgin()) {
                    UtilText.transformationContentSB.append("<p style='text-align:center;'>" + "[style.boldGood(Unbroken Virgin)]" + "</p>" + "<p>" + "As the reality of losing your worthless fuck-hole finally sinks in, you start to think of yourself as something more than just a cheap whore." + " After all, if you don't have a pussy, it's technically not possible for you to have lost your virginity!" + "</p>" + "<p style='text-align:center;'>" + "[pc.thought(I-I'm no longer just a worthless fuck-toy..." + "</br>" + "It's not possible for me to have lost my virginity if I don't have a vagina!)]" + "</p>" + "<p>" + "With a deep sigh, you realise that you no longer have to worry about being a broken-in slut." + " Despite the fact that you can now finally see yourself as a real person again, not having a pussy is making you feel a little restless." + "</p>" + "<p style='text-align:center;'>" + "[pc.thought(I need to find a way to get a new pussy!" + "</br>" + "Then I'll be a pure virgin again!)]" + "</p>" + "<p style='text-align:center;'>" + "<b>You are</b> [style.boldGood(no longer a)] [style.boldTerrible(Broken Virgin)]<b>!</b>" + "</p>");
                } else {
                    UtilText.transformationContentSB.append("<p style='text-align:center;'>" + "[style.boldBad(Pure Virgin?)]" + "</p>" + "<p>" + "As the reality of losing your vagina finally sinks in, you start to feel a rising panic in the back of your mind." + " After all, if you don't have a pussy, you can't call yourself a pure virgin!" + "</p>" + "<p style='text-align:center;'>" + "[pc.thought(~Aah!~ I need to get my pussy back!)]" + "</p>" + "<p style='text-align:center;'>" + "<b>Until you get your vagina back, you are</b> [style.boldBad(no longer a)] [style.boldExcellent(Pure Virgin)]<b>!</b>" + "</p>");
                }
            }
            owner.setVaginaVirgin(true);
            owner.setPiercedVagina(false);
            break;
        case HUMAN:
            if (owner.isPlayer()) {
                UtilText.transformationContentSB.append(" You let out a squeal of excitement as a wave of pleasure runs up from your groin, and you feel your slit shifting and contracting with a mind of its own." + " Within moments, the feeling fades away, and you discover that your pussy has shaped itself into a regular human vagina." + " As you let out a little sigh, a warm, tingling feeling spreads up through your lower abdomen, and you realise that your internal reproductive organs have also transformed into those of a human." + "</br>" + "You now have a [style.boldHuman(human vagina)], with [pc.pussyColourPrimary(true)] labia and [pc.pussyColourSecondary(true)] internal walls." + "</p>");
            } else {
                UtilText.transformationContentSB.append(UtilText.parse(owner, " [npc.She] lets out a squeal of excitement as a wave of pleasure runs up through [npc.her] groin, and as [npc.she] feels [npc.her] slit shifting and contracting with a mind of its own," + " [npc.she] desperately clamps [npc.her] [npc.legs] shut." + " Within moments, the feeling starts to fade away, and with a little cry of surprise, [npc.she] discovers that [npc.her] pussy has shaped itself into a regular human vagina." + " A warm, tingling feeling spreads up through [npc.her] lower abdomen, and as the transformation comes to an end, [npc.she] realises that [npc.her] internal reproductive organs have also transformed into those of a human." + "</br>" + "[npc.Name] now has a [style.boldHuman(human vagina)], with [npc.pussyColourPrimary(true)] labia and [npc.pussyColourSecondary(true)] internal walls." + "</p>"));
            }
            break;
        case DEMON_COMMON:
            if (owner.isPlayer()) {
                UtilText.transformationContentSB.append(" You let out a squeal of excitement as a wave of pleasure runs up from your groin, and you feel your slit shifting and contracting with a mind of its own." + " A strange, bubbling sensation starts running down deep into your cunt, and you let out a lewd moan as you feel rows of little wriggling tentacles grow out to line your inner vaginal walls." + " Gasping for breath, you feel a new set of muscles forming within your pussy, and with an experimental squeeze, you discover that you have an incredible amount of control over your pussy's new additions." + " With one last shiver of pleasure, your pussy reshapes its exterior into the most perfect-looking vagina you've ever seen." + "</p>" + "<p>" + "Just as you think that the transformation has come to an end, your pussy's new tentacles and muscles involuntarily clench down," + " and a desperate squeal escapes from between your [pc.lips+] as a warm, tingling feeling spreads up through your lower abdomen." + " Images of fat demonic cocks slamming deep into your new pussy flash before your eyes, and your squeal turns into a satisfied moan as you imagine them pumping their tainted seed deep into your demonic womb." + " Just as quickly as they came, the images fade from your mind, and as one last wave of tingling pleasure washes through your body, you feel your female reproductive organs finishing their transformation." + "</br>" + "You now have a [style.boldDemon(demonic vagina)], with [pc.pussyColourPrimary(true)] labia and [pc.pussyColourSecondary(true)] internal walls." + "</p>");
            } else {
                UtilText.transformationContentSB.append(UtilText.parse(owner, " [npc.She] lets out a squeal of excitement as a wave of pleasure runs up through [npc.her] groin, and as [npc.she] feels [npc.her] slit shifting and contracting with a mind of its own," + " [npc.she] desperately clamps [npc.her] [npc.legs] shut." + " A strange, bubbling sensation starts running down deep into [npc.her] cunt, and [npc.she] lets out a lewd moan as [npc.she] feels rows of little wriggling tentacles grow out to line [npc.her] inner vaginal walls." + " Gasping for breath, [npc.she] feels a new set of muscles forming within [npc.her] pussy, and with an experimental squeeze," + " [npc.she] discovers that [npc.she] has an incredible amount of control over [npc.her] pussy's new additions." + " With one last shiver of pleasure, [npc.her] pussy reshapes its exterior into an absolutely perfect-looking vagina." + "</p>" + "<p>" + "Just as [npc.she] starts think that the transformation has come to an end, [npc.her] pussy's new tentacles and muscles involuntarily clench down," + " and a desperate squeal escapes from between [npc.her] [npc.lips+] as a warm, tingling feeling spreads up through [npc.her] lower abdomen." + " Images of fat demonic cocks slamming deep into [npc.her] new pussy flash before [npc.her] eyes," + " and [npc.her] squeal turns into a satisfied moan as [npc.she] imagines them pumping their tainted seed deep into [npc.her] demonic womb." + " Just as quickly as they came, the images fade from [npc.her] mind, and as one last wave of tingling pleasure washes through [npc.her] body," + " [npc.she] feels [npc.her] female reproductive organs finishing their transformation." + "</br>" + "[npc.Name] now has a [style.boldDemon(demonic vagina)], with [npc.pussyColourPrimary(true)] labia and [npc.pussyColourSecondary(true)] internal walls." + "</p>"));
            }
            break;
        case IMP:
            if (owner.isPlayer()) {
                UtilText.transformationContentSB.append(" You let out a squeal of excitement as a wave of pleasure runs up from your groin, and you feel your slit shifting and contracting with a mind of its own." + " A strange, bubbling sensation starts running down deep into your cunt, and you let out a lewd moan as you feel rows of little wriggling tentacles grow out to line your inner vaginal walls." + " Gasping for breath, you feel a new set of muscles forming within your pussy, and with an experimental squeeze, you discover that you have an incredible amount of control over your pussy's new additions." + " With one last shiver of pleasure, your pussy reshapes its exterior into the most perfect-looking vagina you've ever seen." + "</p>" + "<p>" + "Just as you think that the transformation has come to an end, your pussy's new tentacles and muscles involuntarily clench down," + " and a desperate squeal escapes from between your [pc.lips+] as a warm, tingling feeling spreads up through your lower abdomen." + " Images of fat impish cocks slamming deep into your new pussy flash before your eyes, and your squeal turns into a satisfied moan as you imagine them pumping their tainted seed deep into your impish womb." + " Just as quickly as they came, the images fade from your mind, and as one last wave of tingling pleasure washes through your body, you feel your female reproductive organs finishing their transformation." + "</br>" + "You now have an [style.boldImp(impish vagina)], with [pc.pussyColourPrimary(true)] labia and [pc.pussyColourSecondary(true)] internal walls." + "</p>");
            } else {
                UtilText.transformationContentSB.append(UtilText.parse(owner, " [npc.She] lets out a squeal of excitement as a wave of pleasure runs up through [npc.her] groin, and as [npc.she] feels [npc.her] slit shifting and contracting with a mind of its own," + " [npc.she] desperately clamps [npc.her] [npc.legs] shut." + " A strange, bubbling sensation starts running down deep into [npc.her] cunt, and [npc.she] lets out a lewd moan as [npc.she] feels rows of little wriggling tentacles grow out to line [npc.her] inner vaginal walls." + " Gasping for breath, [npc.she] feels a new set of muscles forming within [npc.her] pussy, and with an experimental squeeze," + " [npc.she] discovers that [npc.she] has an incredible amount of control over [npc.her] pussy's new additions." + " With one last shiver of pleasure, [npc.her] pussy reshapes its exterior into an absolutely perfect-looking vagina." + "</p>" + "<p>" + "Just as [npc.she] starts think that the transformation has come to an end, [npc.her] pussy's new tentacles and muscles involuntarily clench down," + " and a desperate squeal escapes from between [npc.her] [npc.lips+] as a warm, tingling feeling spreads up through [npc.her] lower abdomen." + " Images of fat impish cocks slamming deep into [npc.her] new pussy flash before [npc.her] eyes," + " and [npc.her] squeal turns into a satisfied moan as [npc.she] imagines them pumping their tainted seed deep into [npc.her] impish womb." + " Just as quickly as they came, the images fade from [npc.her] mind, and as one last wave of tingling pleasure washes through [npc.her] body," + " [npc.she] feels [npc.her] female reproductive organs finishing their transformation." + "</br>" + "[npc.Name] now has an [style.boldImp(impish vagina)], with [npc.pussyColourPrimary(true)] labia and [npc.pussyColourSecondary(true)] internal walls." + "</p>"));
            }
            break;
        case DOG_MORPH:
            if (owner.isPlayer()) {
                UtilText.transformationContentSB.append(" You let out a squeal of excitement as a wave of pleasure runs up from your groin, and you feel your slit shifting and contracting with a mind of its own." + " Within moments, the feeling fades away, and you discover that your pussy has shaped itself into a that of a dog-morph." + " Although it looks like a normal human pussy, a short layer of soft " + owner.getCovering(type.getBodyCoveringType(owner)).getColourDescriptor(owner, false, false) + " fur has grown around it, giving your feminine sex a rather animalistic appearance." + "</p>" + "<p>" + "Just as you think that the transformation has come to an end, your pussy involuntarily clenches down," + " and a desperate squeal escapes from between your [pc.lips+] as a warm, tingling feeling spreads up through your lower abdomen." + " Images of knotted dog-like cocks slamming deep into your new pussy flash before your eyes, and your squeal turns into a satisfied moan as you imagine them pumping their potent seed deep into your canine womb." + " Just as quickly as they came, the images fade from your mind, and as one last wave of tingling pleasure washes through your body, you feel your female reproductive organs finishing their transformation." + "</br>" + "You now have a [style.boldDogMorph(canine vagina)], with [pc.pussyColourPrimary(true)] labia and [pc.pussyColourSecondary(true)] internal walls." + "</p>");
            } else {
                UtilText.transformationContentSB.append(UtilText.parse(owner, " [npc.She] lets out a squeal of excitement as a wave of pleasure runs up through [npc.her] groin, and as [npc.she] feels [npc.her] slit shifting and contracting with a mind of its own," + " [npc.she] desperately clamps [npc.her] [npc.legs] shut." + " Within moments, the feeling fades away, and [npc.she] discovers that [npc.her] pussy has shaped itself into a that of a dog-morph." + " Although it looks like a normal human pussy, a short layer of soft " + owner.getCovering(type.getBodyCoveringType(owner)).getColourDescriptor(owner, false, false) + " fur has grown around it, giving [npc.her] feminine sex a rather animalistic appearance." + "</p>" + "<p>" + "Just as [npc.she] starts think that the transformation has come to an end, [npc.her] pussy involuntarily clenches down," + " and a desperate squeal escapes from between [npc.her] [npc.lips+] as a warm, tingling feeling spreads up through [npc.her] lower abdomen." + " Images of knotted dog-like cocks slamming deep into [npc.her] new pussy flash before [npc.her] eyes," + " and [npc.her] squeal turns into a satisfied moan as [npc.she] imagines them pumping their potent seed deep into [npc.her] canine womb." + " Just as quickly as they came, the images fade from [npc.her] mind, and as one last wave of tingling pleasure washes through [npc.her] body," + " [npc.she] feels [npc.her] female reproductive organs finishing their transformation." + "</br>" + "[npc.Name] now has a [style.boldDogMorph(canine vagina)], with [npc.pussyColourPrimary(true)] labia and [npc.pussyColourSecondary(true)] internal walls." + "</p>"));
            }
            break;
        case WOLF_MORPH:
            if (owner.isPlayer()) {
                UtilText.transformationContentSB.append(" You let out a squeal of excitement as a wave of pleasure runs up from your groin, and you feel your slit shifting and contracting with a mind of its own." + " Within moments, the feeling fades away, and you discover that your pussy has shaped itself into a that of a wolf-morph." + " Although it looks like a normal human pussy, a short layer of soft " + owner.getCovering(type.getBodyCoveringType(owner)).getColourDescriptor(owner, false, false) + " fur has grown around it, giving your feminine sex a rather animalistic appearance." + "</p>" + "<p>" + "Just as you think that the transformation has come to an end, your pussy involuntarily clenches down," + " and a desperate squeal escapes from between your [pc.lips+] as a warm, tingling feeling spreads up through your lower abdomen." + " Images of knotted wolf-like cocks slamming deep into your new pussy flash before your eyes, and your squeal turns into a satisfied moan as you imagine them pumping their potent seed deep into your lupine womb." + " Just as quickly as they came, the images fade from your mind, and as one last wave of tingling pleasure washes through your body, you feel your female reproductive organs finishing their transformation." + "</br>" + "You now have a [style.boldWolfMorph(lupine vagina)], with [pc.pussyColourPrimary(true)] labia and [pc.pussyColourSecondary(true)] internal walls." + "</p>");
            } else {
                UtilText.transformationContentSB.append(UtilText.parse(owner, " [npc.She] lets out a squeal of excitement as a wave of pleasure runs up through [npc.her] groin, and as [npc.she] feels [npc.her] slit shifting and contracting with a mind of its own," + " [npc.she] desperately clamps [npc.her] [npc.legs] shut." + " Within moments, the feeling fades away, and [npc.she] discovers that [npc.her] pussy has shaped itself into a that of a wolf-morph." + " Although it looks like a normal human pussy, a short layer of soft " + owner.getCovering(type.getBodyCoveringType(owner)).getColourDescriptor(owner, false, false) + " fur has grown around it, giving [npc.her] feminine sex a rather animalistic appearance." + "</p>" + "<p>" + "Just as [npc.she] starts think that the transformation has come to an end, [npc.her] pussy involuntarily clenches down," + " and a desperate squeal escapes from between [npc.her] [npc.lips+] as a warm, tingling feeling spreads up through [npc.her] lower abdomen." + " Images of knotted wolf-like cocks slamming deep into [npc.her] new pussy flash before [npc.her] eyes," + " and [npc.her] squeal turns into a satisfied moan as [npc.she] imagines them pumping their potent seed deep into [npc.her] lupine womb." + " Just as quickly as they came, the images fade from [npc.her] mind, and as one last wave of tingling pleasure washes through [npc.her] body," + " [npc.she] feels [npc.her] female reproductive organs finishing their transformation." + "</br>" + "[npc.Name] now has a [style.boldWolfMorph(lupine vagina)], with [npc.pussyColourPrimary(true)] labia and [npc.pussyColourSecondary(true)] internal walls." + "</p>"));
            }
            break;
        case CAT_MORPH:
            if (owner.isPlayer()) {
                UtilText.transformationContentSB.append(" You let out a squeal of excitement as a wave of pleasure runs up from your groin, and you feel your slit shifting and contracting with a mind of its own." + " Within moments, the feeling fades away, and you discover that your pussy has shaped itself into a that of a cat-morph." + " Although it looks like a normal human pussy, a short layer of soft " + owner.getCovering(type.getBodyCoveringType(owner)).getColourDescriptor(owner, false, false) + " fur has grown around it, giving your feminine sex a rather animalistic appearance." + "</p>" + "<p>" + "Just as you think that the transformation has come to an end, your pussy involuntarily clenches down," + " and a desperate squeal escapes from between your [pc.lips+] as a warm, tingling feeling spreads up through your lower abdomen." + " Images of barbed cat-like cocks slamming deep into your new pussy flash before your eyes, and your squeal turns into a satisfied moan as you imagine them pumping their potent seed deep into your feline womb." + " Just as quickly as they came, the images fade from your mind, and as one last wave of tingling pleasure washes through your body, you feel your female reproductive organs finishing their transformation." + "</br>" + "You now have a [style.boldCatMorph(feline vagina)], with [pc.pussyColourPrimary(true)] labia and [pc.pussyColourSecondary(true)] internal walls." + "</p>");
            } else {
                UtilText.transformationContentSB.append(UtilText.parse(owner, " [npc.She] lets out a squeal of excitement as a wave of pleasure runs up through [npc.her] groin, and as [npc.she] feels [npc.her] slit shifting and contracting with a mind of its own," + " [npc.she] desperately clamps [npc.her] [npc.legs] shut." + " Within moments, the feeling fades away, and [npc.she] discovers that [npc.her] pussy has shaped itself into a that of a cat-morph." + " Although it looks like a normal human pussy, a short layer of soft " + owner.getCovering(type.getBodyCoveringType(owner)).getColourDescriptor(owner, false, false) + " fur has grown around it, giving [npc.her] feminine sex a rather animalistic appearance." + "</p>" + "<p>" + "Just as [npc.she] starts think that the transformation has come to an end, [npc.her] pussy involuntarily clenches down," + " and a desperate squeal escapes from between [npc.her] [npc.lips+] as a warm, tingling feeling spreads up through [npc.her] lower abdomen." + " Images of barbed cat-like cocks slamming deep into [npc.her] new pussy flash before [npc.her] eyes," + " and [npc.her] squeal turns into a satisfied moan as [npc.she] imagines them pumping their potent seed deep into [npc.her] feline womb." + " Just as quickly as they came, the images fade from [npc.her] mind, and as one last wave of tingling pleasure washes through [npc.her] body," + " [npc.she] feels [npc.her] female reproductive organs finishing their transformation." + "</br>" + "[npc.Name] now has a [style.boldCatMorph(feline vagina)], with [npc.pussyColourPrimary(true)] labia and [npc.pussyColourSecondary(true)] internal walls." + "</p>"));
            }
            break;
        case SQUIRREL_MORPH:
            if (owner.isPlayer()) {
                UtilText.transformationContentSB.append(" You let out a squeal of excitement as a wave of pleasure runs up from your groin, and you feel your slit shifting and contracting with a mind of its own." + " Within moments, the feeling fades away, and you discover that your pussy has shaped itself into a that of a squirrel-morph." + " Although it looks like a normal human pussy, a short layer of soft " + owner.getCovering(type.getBodyCoveringType(owner)).getColourDescriptor(owner, false, false) + " fur has grown around it, giving your feminine sex a rather animalistic appearance." + "</p>" + "<p>" + "Just as you think that the transformation has come to an end, your pussy involuntarily clenches down," + " and a desperate squeal escapes from between your [pc.lips+] as a warm, tingling feeling spreads up through your lower abdomen." + " Images of squirrel-like cocks slamming deep into your new pussy flash before your eyes, and your squeal turns into a satisfied moan as you imagine them pumping their potent seed deep into your rodent womb." + " Just as quickly as they came, the images fade from your mind, and as one last wave of tingling pleasure washes through your body, you feel your female reproductive organs finishing their transformation." + "</br>" + "You now have a [style.boldSquirrelMorph(squirrel-morph's vagina)], with [pc.pussyColourPrimary(true)] labia and [pc.pussyColourSecondary(true)] internal walls." + "</p>");
            } else {
                UtilText.transformationContentSB.append(UtilText.parse(owner, " [npc.She] lets out a squeal of excitement as a wave of pleasure runs up through [npc.her] groin, and as [npc.she] feels [npc.her] slit shifting and contracting with a mind of its own," + " [npc.she] desperately clamps [npc.her] [npc.legs] shut." + " Within moments, the feeling fades away, and [npc.she] discovers that [npc.her] pussy has shaped itself into a that of a squirrel-morph." + " Although it looks like a normal human pussy, a short layer of soft " + owner.getCovering(type.getBodyCoveringType(owner)).getColourDescriptor(owner, false, false) + " fur has grown around it, giving [npc.her] feminine sex a rather animalistic appearance." + "</p>" + "<p>" + "Just as [npc.she] starts think that the transformation has come to an end, [npc.her] pussy involuntarily clenches down," + " and a desperate squeal escapes from between [npc.her] [npc.lips+] as a warm, tingling feeling spreads up through [npc.her] lower abdomen." + " Images of squirrel-like cocks slamming deep into [npc.her] new pussy flash before [npc.her] eyes," + " and [npc.her] squeal turns into a satisfied moan as [npc.she] imagines them pumping their potent seed deep into [npc.her] rodent womb." + " Just as quickly as they came, the images fade from [npc.her] mind, and as one last wave of tingling pleasure washes through [npc.her] body," + " [npc.she] feels [npc.her] female reproductive organs finishing their transformation." + "</br>" + "[npc.Name] now has a [style.boldSquirrelMorph(squirrel-morph's vagina)], with [npc.pussyColourPrimary(true)] labia and [npc.pussyColourSecondary(true)] internal walls." + "</p>"));
            }
            break;
        case HORSE_MORPH:
            if (owner.isPlayer()) {
                UtilText.transformationContentSB.append(" You let out a squeal of excitement as a wave of pleasure runs up from your groin, and you feel your slit shifting and contracting with a mind of its own." + " Your pussy lips puff up as your cunt reshapes itself into an animalistic, horse-like vagina." + "</p>" + "<p>" + "Just as you think that the transformation has come to an end, your pussy involuntarily clenches down," + " and a desperate squeal escapes from between your [pc.lips+] as a warm, tingling feeling spreads up through your lower abdomen." + " Images of huge, flared horse-cocks slamming deep into your new pussy flash before your eyes, and your squeal turns into a satisfied moan as you imagine them pumping their hot seed deep into your equine womb." + " Just as quickly as they came, the images fade from your mind, and as one last wave of tingling pleasure washes through your body, you feel your female reproductive organs finishing their transformation." + "</br>" + "You now have an [style.boldHorseMorph(equine vagina)], with [pc.pussyColourPrimary(true)] labia and [pc.pussyColourSecondary(true)] internal walls." + "</p>");
            } else {
                UtilText.transformationContentSB.append(UtilText.parse(owner, " [npc.She] lets out a squeal of excitement as a wave of pleasure runs up through [npc.her] groin, and as [npc.she] feels [npc.her] slit shifting and contracting with a mind of its own," + " [npc.she] desperately clamps [npc.her] [npc.legs] shut." + " [npc.Her] pussy lips puff up, and [npc.she] starts moaning and squirming as [npc.her] cunt reshapes itself into a horse-like vagina, giving [npc.her] feminine sex a very animalistic appearance." + "</p>" + "<p>" + "Just as [npc.she] starts think that the transformation has come to an end, [npc.her] pussy involuntarily clenches down," + " and a desperate squeal escapes from between [npc.her] [npc.lips+] as a warm, tingling feeling spreads up through [npc.her] lower abdomen." + " Images of huge, flared horse-cocks slamming deep into [npc.her] new pussy flash before [npc.her] eyes," + " and [npc.her] squeal turns into a satisfied moan as [npc.she] imagines them pumping their potent seed deep into [npc.her] equine womb." + " Just as quickly as they came, the images fade from [npc.her] mind, and as one last wave of tingling pleasure washes through [npc.her] body," + " [npc.she] feels [npc.her] female reproductive organs finishing their transformation." + "</br>" + "[npc.Name] now has an [style.boldHorseMorph(equine vagina)], with [npc.pussyColourPrimary(true)] labia and [npc.pussyColourSecondary(true)] internal walls." + "</p>"));
            }
            break;
        case REINDEER_MORPH:
            if (owner.isPlayer()) {
                UtilText.transformationContentSB.append(" You let out a squeal of excitement as a wave of pleasure runs up from your groin, and you feel your pussy shifting and contracting with a mind of its own." + " Your [pc.labia] puff up as your cunt reshapes itself into an animalistic, reindeer-like vagina." + "</p>" + "<p>" + "Just as you think that the transformation has come to an end, your pussy involuntarily clenches down," + " and a desperate squeal escapes from between your [pc.lips+] as a warm, tingling feeling spreads up through your lower abdomen." + " Images of huge, flared reindeer-cocks slamming deep into your new pussy flash before your eyes, and your squeal turns into a satisfied moan as you imagine them pumping their hot seed deep into your rangiferine womb." + " Just as quickly as they came, the images fade from your mind, and as one last wave of tingling pleasure washes through your body, you feel your female reproductive organs finishing their transformation." + "</br>" + "You now have a [style.boldReindeerMorph(rangiferine vagina)], with [pc.pussyColourPrimary(true)] labia and [pc.pussyColourSecondary(true)] internal walls." + "</p>");
            } else {
                UtilText.transformationContentSB.append(UtilText.parse(owner, " [npc.She] lets out a squeal of excitement as a wave of pleasure runs up through [npc.her] groin, and as [npc.she] feels [npc.her] pussy shifting and contracting with a mind of its own," + " [npc.she] desperately clamps [npc.her] [npc.legs] shut." + " [npc.Her] [npc.labia] puff up, and [npc.she] starts moaning and squirming as [npc.her] cunt reshapes itself into a reindeer-like vagina, giving [npc.her] feminine sex a very animalistic appearance." + "</p>" + "<p>" + "Just as [npc.she] starts think that the transformation has come to an end, [npc.her] pussy involuntarily clenches down," + " and a desperate squeal escapes from between [npc.her] [npc.lips+] as a warm, tingling feeling spreads up through [npc.her] lower abdomen." + " Images of huge, flared reindeer-cocks slamming deep into [npc.her] new pussy flash before [npc.her] eyes," + " and [npc.her] squeal turns into a satisfied moan as [npc.she] imagines them pumping their potent seed deep into [npc.her] rangiferine womb." + " Just as quickly as they came, the images fade from [npc.her] mind, and as one last wave of tingling pleasure washes through [npc.her] body," + " [npc.she] feels [npc.her] female reproductive organs finishing their transformation." + "</br>" + "[npc.Name] now has a [style.boldReindeerMorph(rangiferine vagina)], with [npc.pussyColourPrimary(true)] labia and [npc.pussyColourSecondary(true)] internal walls." + "</p>"));
            }
            break;
        case COW_MORPH:
            if (owner.isPlayer()) {
                UtilText.transformationContentSB.append(" You let out a squeal of excitement as a wave of pleasure runs up from your groin, and you feel your slit shifting and contracting with a mind of its own." + " Your pussy lips puff up as your cunt reshapes itself into an animalistic, cow-like vagina." + "</p>" + "<p>" + "Just as you think that the transformation has come to an end, your pussy involuntarily clenches down," + " and a desperate squeal escapes from between your [pc.lips+] as a warm, tingling feeling spreads up through your lower abdomen." + " Images of huge, flared bull-cocks slamming deep into your new pussy flash before your eyes, and your squeal turns into a satisfied moan as you imagine them pumping their hot seed deep into your bovine womb." + " Just as quickly as they came, the images fade from your mind, and as one last wave of tingling pleasure washes through your body, you feel your female reproductive organs finishing their transformation." + "</br>" + "You now have an [style.boldCowMorph(bovine vagina)], with [pc.pussyColourPrimary(true)] labia and [pc.pussyColourSecondary(true)] internal walls." + "</p>");
            } else {
                UtilText.transformationContentSB.append(UtilText.parse(owner, " [npc.She] lets out a squeal of excitement as a wave of pleasure runs up through [npc.her] groin, and as [npc.she] feels [npc.her] slit shifting and contracting with a mind of its own," + " [npc.she] desperately clamps [npc.her] [npc.legs] shut." + " [npc.Her] pussy lips puff up and darken to a deep black, and [npc.she] starts moaning and squirming as [npc.her] cunt reshapes itself into a cow-like vagina, giving [npc.her] feminine sex a very animalistic appearance." + "</p>" + "<p>" + "Just as [npc.she] starts think that the transformation has come to an end, [npc.her] pussy involuntarily clenches down," + " and a desperate squeal escapes from between [npc.her] [npc.lips+] as a warm, tingling feeling spreads up through [npc.her] lower abdomen." + " Images of huge, flared bull-cocks slamming deep into [npc.her] new pussy flash before [npc.her] eyes," + " and [npc.her] squeal turns into a satisfied moan as [npc.she] imagines them pumping their potent seed deep into [npc.her] bovine womb." + " Just as quickly as they came, the images fade from [npc.her] mind, and as one last wave of tingling pleasure washes through [npc.her] body," + " [npc.she] feels [npc.her] female reproductive organs finishing their transformation." + "</br>" + "[npc.Name] now has an [style.boldCowMorph(bovine vagina)], with [npc.pussyColourPrimary(true)] labia and [npc.pussyColourSecondary(true)] internal walls." + "</p>"));
            }
            break;
        case ALLIGATOR_MORPH:
            if (owner.isPlayer()) {
                UtilText.transformationContentSB.append(" You let out a squeal of excitement as a wave of pleasure runs up from your groin, and you feel your slit shifting and contracting with a mind of its own." + " Within moments, the feeling fades away, and you discover that your pussy has transformed into that of an alligator-morph's." + " Although the shape and structure remains similar to a normal human's pussy, a short layer of soft " + owner.getCovering(type.getBodyCoveringType(owner)).getColourDescriptor(owner, false, false) + " scales have grown around it, giving your feminine sex a rather reptilian appearance." + "</p>" + "<p>" + "Just as you think that the transformation has come to an end, your pussy involuntarily clenches down," + " and a desperate squeal escapes from between your [pc.lips+] as a warm, tingling feeling spreads up through your lower abdomen." + " Images of spreading your legs before huge, throbbing alligator cocks flash before your eyes," + " and your squeal turns into a satisfied moan as you imagine them thrusting deep inside of you before squirting their hot seed deep into your hungry reptilian cunt." + " Just as quickly as they came, the images fade from your mind, and as one last wave of tingling pleasure washes through your body, you feel your female reproductive organs finishing their transformation." + "</br>" + "You now have an [style.boldGatorMorph(alligator-morph's vagina)], with [pc.pussyColourPrimary(true)] labia and [pc.pussyColourSecondary(true)] internal walls." + "</p>");
            } else {
                UtilText.transformationContentSB.append(UtilText.parse(owner, " [npc.She] lets out a squeal of excitement as a wave of pleasure runs up through [npc.her] groin, and as [npc.she] feels [npc.her] slit shifting and contracting with a mind of its own," + " [npc.she] desperately clamps [npc.her] [npc.legs] shut." + " Within moments, the feeling fades away, and [npc.she] discovers that [npc.her] pussy has transformed into that of an alligator-morph's." + " Although the shape and structure remains similar to a normal human's pussy, a short layer of soft " + owner.getCovering(type.getBodyCoveringType(owner)).getColourDescriptor(owner, false, false) + " scales have grown around it, giving [npc.her] feminine sex a rather reptilian appearance." + "</p>" + "<p>" + "Just as [npc.she] starts think that the transformation has come to an end, [npc.her] pussy involuntarily clenches down," + " and a desperate squeal escapes from between [npc.her] [npc.lips+] as a warm, tingling feeling spreads up through [npc.her] lower abdomen." + " Images of spreading [npc.her] legs before huge, throbbing alligator cocks flash before [npc.her] eyes," + " and [npc.her] squeal turns into a satisfied moan as [npc.she] imagines them thrusting deep inside of [npc.herHim] before squirting their hot seed deep into [npc.her] hungry reptilian cunt." + " Just as quickly as they came, the images fade from [npc.her] mind, and as one last wave of tingling pleasure washes through [npc.her] body," + " [npc.she] feels [npc.her] female reproductive organs finishing their transformation." + "</br>" + "[npc.Name] now has an [style.boldGatorMorph(alligator-morph's vagina)], with [npc.pussyColourPrimary(true)] labia and [npc.pussyColourSecondary(true)] internal walls." + "</p>"));
            }
            break;
        case HARPY:
            if (owner.isPlayer()) {
                UtilText.transformationContentSB.append(" You let out a squeal of excitement as a wave of pleasure runs up from your groin, and you feel your slit shifting and contracting with a mind of its own." + " Within moments, the feeling fades away, and you discover that your pussy has shaped itself into a that of a harpy." + " Although it looks like a normal human pussy, a short layer of soft " + owner.getCovering(type.getBodyCoveringType(owner)).getColourDescriptor(owner, false, false) + " feathers have grown around it, giving your feminine sex a rather avian appearance." + "</p>" + "<p>" + "Just as you think that the transformation has come to an end, your pussy involuntarily clenches down," + " and a desperate squeal escapes from between your [pc.lips+] as a warm, tingling feeling spreads up through your lower abdomen." + " Images of slamming your pussy down on cute little harpy cocks flash before your eyes, and your squeal turns into a satisfied moan as you imagine them squirting their hot seed deep into your hungry avian cunt." + " Just as quickly as they came, the images fade from your mind, and as one last wave of tingling pleasure washes through your body, you feel your female reproductive organs finishing their transformation." + "</br>" + "You now have an [style.boldHarpy(avian vagina)], with [pc.pussyColourPrimary(true)] labia and [pc.pussyColourSecondary(true)] internal walls." + "</p>");
            } else {
                UtilText.transformationContentSB.append(UtilText.parse(owner, " [npc.She] lets out a squeal of excitement as a wave of pleasure runs up through [npc.her] groin, and as [npc.she] feels [npc.her] slit shifting and contracting with a mind of its own," + " [npc.she] desperately clamps [npc.her] [npc.legs] shut." + " Within moments, the feeling fades away, and [npc.she] discovers that [npc.her] pussy has shaped itself into a that of a harpy." + " Although it looks like a normal human pussy, a short layer of soft " + owner.getCovering(type.getBodyCoveringType(owner)).getColourDescriptor(owner, false, false) + " feathers have grown around it, giving [npc.her] feminine sex a rather avian appearance." + "</p>" + "<p>" + "Just as [npc.she] starts think that the transformation has come to an end, [npc.her] pussy involuntarily clenches down," + " and a desperate squeal escapes from between [npc.her] [npc.lips+] as a warm, tingling feeling spreads up through [npc.her] lower abdomen." + " Images of slamming [npc.her] pussy down on cute little harpy cocks flash before [npc.her] eyes," + " and [npc.her] squeal turns into a satisfied moan as [npc.she] imagines them squirting their hot seed deep into [npc.her] hungry avian cunt." + " Just as quickly as they came, the images fade from [npc.her] mind, and as one last wave of tingling pleasure washes through [npc.her] body," + " [npc.she] feels [npc.her] female reproductive organs finishing their transformation." + "</br>" + "[npc.Name] now has an [style.boldHarpy(avian vagina)], with [npc.pussyColourPrimary(true)] labia and [npc.pussyColourSecondary(true)] internal walls." + "</p>"));
            }
            break;
        case // TODO
        ANGEL:
            break;
    }
    orificeVagina.getOrificeModifiers().clear();
    for (OrificeModifier om : type.getDefaultRacialOrificeModifiers()) {
        orificeVagina.addOrificeModifier(owner, om);
    }
    if (owner.isPlayer()) {
        UtilText.transformationContentSB.append("<p>" + "Any old modifiers that your pussy might have had have [style.boldShrink(transformed away)]!");
    } else {
        UtilText.transformationContentSB.append("<p>" + "Any old modifiers that [npc.her] pussy might have had have [style.boldShrink(transformed away)]!");
    }
    if (orificeVagina.getOrificeModifiers().isEmpty()) {
        UtilText.transformationContentSB.append("</p>");
    } else {
        if (owner.isPlayer()) {
            UtilText.transformationContentSB.append("</br>" + "Instead, your new pussy is:");
        } else {
            UtilText.transformationContentSB.append("</br>" + "Instead, [npc.her] new pussy is:");
        }
        for (OrificeModifier om : orificeVagina.getOrificeModifiers()) {
            UtilText.transformationContentSB.append("</br>[style.boldGrow(" + Util.capitaliseSentence(om.getName()) + ")]");
        }
        UtilText.transformationContentSB.append("</p>");
    }
    return UtilText.transformationContentSB.toString() + "<p>" + owner.postTransformationCalculation() + "</p>";
}
Also used : OrificeModifier(com.lilithsthrone.game.character.body.valueEnums.OrificeModifier)

Aggregations

OrificeModifier (com.lilithsthrone.game.character.body.valueEnums.OrificeModifier)14 PenetrationType (com.lilithsthrone.game.sex.PenetrationType)6 SexType (com.lilithsthrone.game.sex.SexType)6 ArrayList (java.util.ArrayList)6 PenisModifier (com.lilithsthrone.game.character.body.valueEnums.PenisModifier)5 TongueModifier (com.lilithsthrone.game.character.body.valueEnums.TongueModifier)5 BodyCoveringType (com.lilithsthrone.game.character.body.types.BodyCoveringType)4 FluidModifier (com.lilithsthrone.game.character.body.valueEnums.FluidModifier)4 Covering (com.lilithsthrone.game.character.body.Covering)2 BodyHair (com.lilithsthrone.game.character.body.valueEnums.BodyHair)2 BreastShape (com.lilithsthrone.game.character.body.valueEnums.BreastShape)2 CoveringModifier (com.lilithsthrone.game.character.body.valueEnums.CoveringModifier)2 NPC (com.lilithsthrone.game.character.npc.NPC)2 Subspecies (com.lilithsthrone.game.character.race.Subspecies)2 OrificeType (com.lilithsthrone.game.sex.OrificeType)2 HashMap (java.util.HashMap)2 EnchantmentEventListener (com.lilithsthrone.controller.eventListeners.EnchantmentEventListener)1 InventorySelectedItemEventListener (com.lilithsthrone.controller.eventListeners.InventorySelectedItemEventListener)1 InventoryTooltipEventListener (com.lilithsthrone.controller.eventListeners.InventoryTooltipEventListener)1 SetContentEventListener (com.lilithsthrone.controller.eventListeners.SetContentEventListener)1