code:
init 4 python:
    def recolor_company_wardrobe_requirement():
        return company_wardrobe_loaded

    def recolor_company_wardrobe_initialization(self):
        ceo_office.add_action(self)
        return

    recolor_company_wardrobe_action = ActionMod("Rebuild Company Wardrobe", recolor_company_wardrobe_requirement, "recolor_company_wardrobe", initialization = recolor_company_wardrobe_initialization,
        menu_tooltip = "Adds a collection of over- and underwear for your company to your outfit manager.", category = "Wardrobe")

label recolor_company_wardrobe():
    "This will create a new set of company uniforms with the colour of your choice."
    "If you still have your original set this will make the list long and slightly unresponsive."
    "Would you like to delete all existing business uniforms first?"
    menu:
        "Yes":
            "WARNING: This is not reversable, all existing uniforms will be cleared from the business."
            menu:
                "Proceed":
                    $ mc.business.business_uniforms = []
                "Nevermind":
                    pass
        "No":
            pass
    call append_company_wardrobe() from _call_append_company_wardrobe
    return

license: unknown


code:
init 3 python:
    def use_tan_bed_requirement():
        if not time_of_day == 0 and not time_of_day == 4:
            if mc.business.funds > 25:
                return True
            return "You need $25"
        return "Salon not open"

    def tan_bed_initialization(self):
        mall_salon.add_action(self)
        return

    tan_action = ActionMod("Schedule a tan {image=gui/heart/Time_Advance.png}", use_tan_bed_requirement, "tan_label", initialization = tan_bed_initialization,
        menu_tooltip = "Have a person get a tan.", category="Mall")

    bath_robe_bottom = Clothing("Bathrobe bottom", 2, True, False, "Bath_Robe_Bot", False, False, 0, is_extension = True, display_name = "robe bottom",
        can_be_half_off = True, half_off_regions = [pelvis_region, upper_leg_region, lower_leg_region], half_off_ignore_regions = [lower_arm_region, stomach_region], half_off_gives_access = True, half_off_reveals = True)
    bath_robe = Clothing("Bathrobe", 2, True, True, "Bath_Robe", True, False, 1, has_extension = bath_robe_bottom, supported_patterns = {"Flowers":"Pattern_1"}, display_name = "robe",
        can_be_half_off = True, half_off_regions = [breast_region], half_off_ignore_regions = [upper_arm_region], half_off_gives_access = True, half_off_reveals = True,
        constrain_regions = [torso_region, upper_arm_region, lower_arm_region, stomach_region, skirt_region])

    towel_bottom = Clothing("Towel bottom", 2, True, False, "Towel_Bot", False, False, 0, is_extension = True, display_name = "towel bottom",
        can_be_half_off = True, half_off_regions = [pelvis_region, upper_leg_region], half_off_gives_access = True, half_off_reveals = True)
    towel = Clothing("Towel", 2, True, True, "Towel", True, False, 1, has_extension = towel_bottom, display_name = "towel",
        can_be_half_off = True, half_off_regions = [torso_region], half_off_ignore_regions = [stomach_region], half_off_gives_access = True, half_off_reveals = True,
        constrain_regions = [torso_region, stomach_region, skirt_region])

label tan_label():
    call screen main_choice_display(build_menu_items([get_sorted_people_list(known_people_in_the_game(), "Tan appointment", "Back")]))
    $ person_choice = _return
    if person_choice != "Back":
        "You send a message to [person_choice.fname] about the appointment."
        "After some time you get a response..."
        call tan_response(person_choice) from _call_tan_response
        $ del person_choice
    return

label tan_response(the_person):
    $ scene_manager = Scene()
    $ scene_manager.add_actor(the_person)
    if the_person.personality.personality_type_prefix == "bimbo":
        $ scene_manager.update_actor(the_person, emotion = "happy")
        the_person "Oh, [the_person.mc_title], like, I love tanning."
    elif the_person.love > 30:
        $ scene_manager.update_actor(the_person, emotion = "happy")
        the_person "Thanks for the attention, [the_person.mc_title]."
    elif the_person.obedience < 80 or the_person.happiness < 100:
        $ scene_manager.update_actor(the_person, emotion = "sad")
        the_person "I'm not in the mood for a spa day right now."
        $ the_person.change_obedience(-2)
        $ the_person.change_happiness(-2)
        $ scene_manager.clear_scene()
        return
    elif the_person.happiness > 120 or the_person.obedience > 120:
        the_person "Yes, [the_person.mc_title]. I am on my way."
    else:
        the_person "Sounds good, I'll be right there [the_person.mc_title]."
    call use_tan_bed(the_person) from _call_use_tan_bed
    $ mc.business.change_funds(-25)
    call advance_time from _call_advance_time_tan
    $ scene_manager.clear_scene()
    return

label use_tan_bed(the_person):
    $ scene_manager = Scene()
    $ scene_manager.add_actor(the_person)
    "Once she gets there you show her around the salon a bit."
    mc.name "And here is the tanning bed, I think it would do you a world of good."
    if the_person in mc.business.employee_list:
        the_person "Oh yes, you know the office could have bigger windows. Everyone there is so pale after working all week."
    else: # more unique people
        the_person "Oh yes, I don't spend nearly as much time outside as I'd like."
    mc.name "Great, now we just need to decide what you wear in there."
    if the_person.sluttiness > 80: #opinion showing
        the_person "I should probably just get naked."
        mc.name "I don't know, sometimes tan lines look good."
    else:
        the_person "Oh, right, it is kind of public here."
    the_person "What do you think I should do?"
    $ the_bra = the_person.outfit.get_bra()
    $ the_panties = the_person.outfit.get_panties()
    $ tan_style = normal_tan
    menu:
        "Tan in your underwear":
            mc.name "Whatever underwear you have on is fine, most people won't ever see your tan lines."
            if not the_panties:
                if not the_bra:
                    the_person "But, I'm not wearing any underwear."
                    mc.name "Then I guess you'll have to get naked."
                else:
                    the_person "But, I'm not wearing panties."
                    mc.name "Then you better take your bra off, it would be pretty weird to only have tan lines on the top."
                    $ the_bra = None
            else: # has panties
                if not the_bra:
                    the_person "But, I'm not wearing a bra."
                    mc.name "That's fine, plenty of people tan topless."
        "Tan topless" if the_person.sluttiness > 40:
            mc.name "You should go topless, that way you don't have to be as careful about what you wear in the future."
            if the_bra:
                if the_bra.has_extension:
                    $ the_panties = None
                $ the_bra = None
            if not the_panties:
                the_person "Ok, but I'm not wearing panties right now."
                mc.name "Then I guess you won't have any tan lines."
        "Tan naked" if the_person.sluttiness > 60:
            mc.name "You should get naked, if you are going to tan you might as well do it properly."
            $ the_bra = None
            $ the_panties = None
    the_person "Ok, if you think that's best."
    if the_bra is None:
        if the_panties is None:
            $ tan_style = None
        else:
            $ tan_style = slutty_tan
    elif the_bra.has_extension:
        $ tan_style = one_piece_tan
    elif the_bra.slut_value > 3:
        $ tan_style = sexy_tan
    $ the_person.tan_style = tan_style
    call strip_with_taboos(the_person, the_bra = the_bra, the_panties = the_panties) from _call_strip_with_taboos_tan
    if done_stripping:
        the_person "Thanks, [the_person.mc_title]. I guess I better go get started."
        # pose/tease
        $ scene_manager.update_actor(the_person, position = "walking_away")
        "You watch her go, enjoying the view. Then sit down to wait."
    "After some time passes you see [the_person.title] coming out in a robe."
    $ towel_outfit = Outfit("Towel")
    if renpy.random.randint(0,1) == 1:
        $ upper = bath_robe.get_copy()
        if hasattr(upper, "supported_patterns") and upper.supported_patterns and renpy.random.randint(1, 100) > 50:
            $ upper.pattern = upper.supported_patterns[renpy.random.choice(list(upper.supported_patterns.keys()))]
            $ upper.colour_pattern = WardrobeBuilder.get_color(the_person, upper.colour)
        $ towel_outfit.add_dress(upper)
    else:
        $ towel_outfit.add_dress(towel.get_copy())
    if the_bra:
        $ towel_outfit.add_upper(the_bra.get_copy())
    if the_panties:
        $ towel_outfit.add_lower(the_panties.get_copy())
    $ the_person.apply_outfit(towel_outfit)
    $ scene_manager.update_actor(the_person)
    mc.name "How did it go?"
    the_person "Pretty good."
    if done_stripping:
        the_person "Do you want to see?"
        mc.name "Absolutely."
        $ generalised_strip_description(the_person, the_person.outfit.get_underwear_strip_list(visible_enough = True))
        the_person "What do you think?"
        mc.name "You look amazing, this was a great idea."
    else:
        mc.name "Can I see?"
        the_person "Maybe if you keep doing nice thing for me you'll get to see eventually."
        mc.name "I'll have to keep working on that."
        $ the_person.change_slut(5)
    $ the_person.change_happiness(5)
    "You pay for the tanning session and head your separate ways."
    $ scene_manager.clear_scene()
    return

label strip_with_taboos(the_person, the_bra = None, the_panties = None):
    $ taboo = 5
    if the_person.has_taboo("bare_pussy"):
        $ taboo -= 1
        if not the_person.wearing_panties:
            $ taboo -= 3
    if the_person.has_taboo("bare_tits"):
        $ taboo -= 2
        if not the_person.wearing_bra:
            $ taboo -= 2
    if the_person.has_taboo("underwear_nudity"):
        $ taboo -= 4
    $ done_stripping = True
    if taboo > 1: # underwear
        $ generalised_strip_description(the_person, the_person.outfit.get_underwear_strip_list())
        if taboo > 3: #topless
            if taboo > 4: # everything
                if not the_panties: # everything
                    $ generalised_strip_description(the_person, the_person.outfit.get_full_strip_list())
            elif not the_panties:
                $ done_stripping = False
            if not the_bra: # topless
                $ generalised_strip_description(the_person, the_person.outfit.get_tit_strip_list())
        elif not the_bra:
            $ done_stripping = False
    else:
        $ done_stripping = False
    if done_stripping: #she went as far as we asked
        "With her brief strip show finished [the_person.title] looks at you with a smile."
        mc.name "Wow, [the_person.title], you look incredible."
    else: # not ready to strip in front of us
        if taboo < 2:
            "[the_person.title] shifts on her feet nervously."
            the_person "Um, I need to get ready, but I don't think I can do it with you here."
        elif taboo < 4:
            "Once she is in her underwear, she hesitates, and looks at you shyly."
            the_person "I don't think I can go any further with you watching me."
        else:
            "Although she stripped off her top with no trouble, she seems to be hesitating with her panties."
            the_person "I don't think I can take these off with you watching me."
        mc.name "Of course, let me give you some privacy."
    $ scene_manager.clear_scene()
    return done_stripping


code:
init -1:
    default persistent.time_capsule = []
    default persistent.lactation_serum = []

init 3 python:
    def hidden_trait_list():
        hidden_trait_list = []
        for trait in [x for x in SerumTraitMod._instances]:
            hidden_trait_list.append(trait)
        if "nora_reward_instant_trance" in globals():
            hidden_trait_list.append(nora_reward_instant_trance)
        if "nora_reward_hucow_trait" in globals():
            hidden_trait_list.append(nora_reward_hucow_trait)
        if "nora_reward_genius_trait" in globals():
            hidden_trait_list.append(nora_reward_genius_trait)
        if "nora_reward_high_slut_trait" in globals():
            hidden_trait_list.append(nora_reward_high_slut_trait)
        if "nora_reward_high_obedience_trait" in globals():
            hidden_trait_list.append(nora_reward_high_obedience_trait)
        if "nora_reward_low_love_trait" in globals():
            hidden_trait_list.append(nora_reward_low_love_trait)
        if "nora_reward_high_love_trait" in globals():
            hidden_trait_list.append(nora_reward_high_love_trait)
        if "nora_reward_nora_trait" in globals():
            hidden_trait_list.append(nora_reward_nora_trait)
        if "nora_reward_aunt_trait" in globals():
            hidden_trait_list.append(nora_reward_aunt_trait)
        if "nora_reward_cousin_trait" in globals():
            hidden_trait_list.append(nora_reward_cousin_trait)
        if "nora_reward_sister_trait" in globals():
            hidden_trait_list.append(nora_reward_sister_trait)
        if "nora_reward_mother_trait" in globals():
            hidden_trait_list.append(nora_reward_mother_trait)
        if "arousal_serum_trait" in globals():
            hidden_trait_list.append(arousal_serum_trait)
        if "body_monitor_serum_trait" in globals():
            hidden_trait_list.append(body_monitor_serum_trait)
        if "anti_bimbo_serum_trait" in globals():
            hidden_trait_list.append(anti_bimbo_serum_trait)
        if "energy_drink_serum_trait" in globals():
            hidden_trait_list.append(energy_drink_serum_trait)
        if "essential_oil_trait" in globals():
            hidden_trait_list.append(essential_oil_trait)
        if "fetish_basic_serum" in globals():
            hidden_trait_list.append(fetish_basic_serum)
        if "fetish_exhibition_serum" in globals():
            hidden_trait_list.append(fetish_exhibition_serum)
        if "fetish_anal_serum" in globals():
            hidden_trait_list.append(fetish_anal_serum)
        if "fetish_cum_serum" in globals():
            hidden_trait_list.append(fetish_cum_serum)
        if "fetish_breeding_serum" in globals():
            hidden_trait_list.append(fetish_breeding_serum)
        if "massive_pregnancy_decelerator_serum_trait" in globals():
            hidden_trait_list.append(massive_pregnancy_decelerator_serum_trait)
        if "nocturnal_emission_actuator_serum_trait" in globals():
            hidden_trait_list.append(nocturnal_emission_actuator_serum_trait)
        return hidden_trait_list

    def find_hidden_trait(name):
        for trait in [x for x in hidden_trait_list()]:
            if trait.name == name:
                return trait
        return False

    def create_time_serum(serum):
        time_capsule = []
        lactation_serum = []
        for trait in serum.traits:
            time_capsule.append(trait.name)
            if isinstance(trait.on_apply, functools.partial):
                if isinstance(trait.on_apply.args[0], SerumDesign):
                    lactation_serum = create_time_serum(trait.on_apply.args[0])[0]
        return [time_capsule, lactation_serum]

    def get_time_serum():
        temp_list = []
        list2 = []
        list2 = hidden_trait_list()
        temp_list = persistent.time_capsule
        time_serum = SerumDesign()
        time_serum.name = "Time Serum"
        if temp_list:
            for y in temp_list:
                for x in list_of_traits:
                    if x.name == y:
                        time_serum.add_trait(x)
        if temp_list and list2:
            for y in temp_list:
                for x in list2:
                    if x.name == y:
                        time_serum.add_trait(x)
        if persistent.lactation_serum:
            lactation_serum = get_lactation_serum()
            new_trait = SerumTrait(*breast_milk_serum_production.given_args, **breast_milk_serum_production.given_kwargs)
            time_serum.add_trait(new_trait)
            time_serum.traits[len(time_serum.traits)-1].on_apply = partial(breast_milk_serum_production_on_apply, lactation_serum)
            time_serum.traits[len(time_serum.traits)-1].on_remove = partial(breast_milk_serum_production_on_remove, lactation_serum)
        time_serum.attention_modifier = -4
        return time_serum

    def get_lactation_serum():
        temp_list = []
        list2 = []
        list2 = hidden_trait_list()
        temp_list = persistent.lactation_serum
        lactation_serum = SerumDesign()
        lactation_serum.name = "Lactation Serum"
        if temp_list:
            for y in temp_list:
                for x in list_of_traits:
                    if x.name == y:
                        lactation_serum.add_trait(x)
        if temp_list and list2:
            for y in temp_list:
                for x in list2:
                    if x.name == y:
                        lactation_serum.add_trait(x)
        return lactation_serum

init 16 python: # hijack
    def attic_search_event_requirement():
        if mc.is_home:
            if time_of_day == 0:
                if not mc.business.event_triggers_dict.get("time_capsule_discovered", False):
                    return True
        return False

    attic_search_event_action = ActionMod("Search the attic", attic_search_event_requirement, "activate_attic_search",
        menu_tooltip = "Discover something weird in your attic.", category = "Home", is_crisis = True, is_morning_crisis = True, priority = 100)

    def attic_search_requirement():
        return mc.business.event_triggers_dict.get("time_capsule_discovered", False)

    add_label_hijack("mom_found_serums", "activate_attic_mod_core")

init 12 python:
    def super_serum():
        time_serum = []
        time_serum.append(futuristic_serum_prod.name)
        time_serum.append(mind_control_agent.name)
        mpa = next((x for x in list_of_traits if x == massive_pregnancy_accelerator), None)
        if mpa:
            time_serum.append(mpa.name)
        sgs = next((x for x in list_of_traits if x == self_generating_serum), None)
        if sgs:
            time_serum.append(sgs.name)
        time_serum.append(low_volatility_reagents.name)
        time_serum.append(rolling_orgasm.name)
        time_serum.append(slutty_caffeine_trait.name)
        time_serum.append(happiness_tick.name)
        time_serum.append(improved_duration_trait.name)
        time_serum.append(focus_enhancement.name)
        time_serum.append(int_enhancement.name)
        time_serum.append(cha_enhancement.name)
        time_serum.append("Behaviour Adjustment")
        time_serum.append(nora_reward_aunt_trait.name)
        time_serum.append(nora_reward_genius_trait.name)
        time_serum.append(nora_reward_instant_trance.name)
        time_serum.append("Dopamine Therapy")
        time_serum.append("Body Monitoring Nanobots")
        time_serum.append("Sexual Proclivity Nanobots")
        time_serum.append("Social Sexual Proclivity Nanobots")
        time_serum.append("Energy Drink")
        time_serum.append("Skin Sensitivity")
        time_serum.append("Teasing Nightfall")
        if "arousal_serum_trait" in globals():
            time_serum.append(arousal_serum_trait.name)
        setattr(persistent, "time_capsule", time_serum)
        mc.business.event_triggers_dict["time_capsule"] = 100
        mc.business.event_triggers_dict["time_capsule_locked"] = False
        return

label activate_attic_mod_core(stack):
    $ mc.business.add_mandatory_crisis(attic_search_event_action)
    python:
        # continue on the hijack stack if needed
        execute_hijack_call(stack)
    return

label activate_attic_search():
    python:
        attic_search_action = Action("Search the attic", attic_search_requirement, "attic_search_label", menu_tooltip = "Look for more serums in the attic")
        bedroom.add_action(attic_search_action)
        mc.business.event_triggers_dict["time_capsule_discovered"] = True
    "Suddenly you are struck by a thought."
    "[mom.possessive_title!c] already found a box of serums you hid in the attic last year, but maybe she missed some."
    "With that thought to drive you, you go up the stairs to the attic and see that it is full of boxes."
    "After some searching you find a weird metal case labelled TIME CAPSULE, but oddly the date emblazoned on the side is today."
    "It also seems to be bolted to the floor, a bit like a safe."
    if not persistent.time_capsule:
        "Does that mean that it has been up here for years and is meant to be opened? It feels empty."
    else:
        $ mc.business.event_triggers_dict["time_capsule"] = 100
        "Does that mean that it has been up here for years and is meant to be opened? It feels heavy."
    "Before you are able to investigate further, you hear your alarm going off downstairs."
    "You better get the day started, but if you want to check this out again, you should be able to do so from your bedroom."
    return

label attic_search_label():
    "You go up the stairs to the attic and quickly make your way to the odd time capsule."
    $ count = mc.business.event_triggers_dict.get("time_capsule", 0)
    if mc.business.event_triggers_dict.get("time_capsule_locked", False):
        "You mess with the outside of the case for a bit but as easy as it was to open before you can't seem to find a way to open it now."
    menu:
        "Open the case" if not mc.business.event_triggers_dict.get("time_capsule_locked", False):
            if not mc.business.event_triggers_dict.get("time_capsule_opened", False):
                $ mc.business.event_triggers_dict["time_capsule_opened"] = True
                if count < 1:
                    "You were right, the case is empty. However, as you look at it you notice something about the way it is designed."
                    "Trusting your instincts you reach into your pocket you pull out a serum vial."
                    "Sure enough it is a perfect fit. The entire case is lined with slots that would securely hold the exact vials that your serums get produced to fill."
                else:
                    "You were right, the case is packed full. To your great surprise the contents are incredibly familiar."
                    "Trusting your instincts you reach into your pocket you pull out a serum vial."
                    "Sure enough it is identical. The entire case is stocked with the exact vials that your serums get produced to fill."
                    "Oddly the colour is a bit different than any of the serums you currently produce."
            else:
                if count < 1:
                    "The case is still empty, you don't really know what else you expected."
                else:
                    "The case is still full, you don't really know what else you expected."
            menu:
                "Fill the case" if mc.inventory.total_serum_count > 0 and count < 1:
                    call screen serum_inventory_select_ui(mc.inventory)
                    if isinstance(_return, SerumDesign):
                        $ serum = _return
                        "You select a vial of [serum.name] and snap it into place in the case."
                        "Suddenly it makes a hissing noise and starts to close slowly."
                        "You certainly won't be able to fill the case but you could probably retrieve the one you put in if you want."
                        menu:
                            "Retrieve the vial":
                                "You stick your hand in and pull the vial out, as soon as you do it stops closing."
                                "It seems like there is more than meets the eye to this case, but before messing with it more you decide to wait a bit."
                            "Let it close":
                                $ mc.inventory.change_serum(serum,-1)
                                $ [time_serum, lactation_serum] = create_time_serum(serum)
                                $ mc.business.event_triggers_dict["time_capsule_locked"] = True
                                $ mc.business.event_triggers_dict["time_capsule"] = 100
                                python:
                                    setattr(persistent, "time_capsule", time_serum)
                                    setattr(persistent, "lactation_serum", lactation_serum)
                                "You watch as the case closes the rest of the way and then listen as what sounds like a dozen locks spin into place. The case is surely secure for now."
                                "You wonder how you ever got it open in the first place..."
                    else:
                        "You change your mind for now."
                "Empty the case" if count > 0:
                    $ mc.inventory.change_serum(get_time_serum(), 99)
                    "You spend some time pulling vials from the case but as you are setting the second to last vial in your bag the case starts to make a hissing noise and begins closing."
                    menu:
                        "Grab the last one":
                            $ mc.inventory.change_serum(get_time_serum(), 1)
                            $ mc.business.event_triggers_dict["time_capsule"] = 0
                            "You quickly grab at the last vial, but as soon as you pick it up the case stops moving."
                            "It sits there almost like it is waiting for you to put something inside."
                        "Let it close":
                            $ mc.business.event_triggers_dict["time_capsule_locked"] = True
                            "You watch as the case closes the rest of the way and then listen as what sounds like a dozen locks spin into place. The case is surely secure for now."
                            "You wonder how you ever got it open in the first place..."
                "Leave it alone":
                    pass
        "Leave it alone":
            pass
    "You head back down the stairs and return to your room."
    return


code:
# idea by quiboune
# original trait by Vavilon
# modified by Kaden
init -1 python:
    def impreg_on_day(person, the_serum, add_to_log):
        if (renpy.random.randint(0,100) < 50) and (person.fertility_percent < 100):
            person.fertility_percent += 1
            if add_to_log:
                mc.log_event((person.title or "???") + ": +1 Permanent Fertility", "float_text_red")
        if renpy.random.randint(0,100) < person.event_triggers_dict.get("serum_induced_lactation", 5):
            person.lactation_sources += 1
            person.event_triggers_dict["serum_induced_lactation"] = 0
        else:
            person.event_triggers_dict["serum_induced_lactation"] = person.event_triggers_dict.get("serum_induced_lactation", 5)+5
        return

    def add_quiboune_breeding_serum():
        impreg_serum_trait = SerumTraitMod(name = "Breeding Cow",
                desc = "Increases fertility and lactation of recipients as they sleep.",
                positive_slug = "50% chance of +1% Permanent Fertility overnight. Rare chance of increased lactation.",
                negative_slug = "",
                research_added = 500,
                base_side_effect_chance = 0,
                on_day = impreg_on_day,
                tier = 2,
                start_researched =  False,
                research_needed = 1600,
                clarity_cost = 1500,
                mental_aspect = 0, physical_aspect = 4, sexual_aspect = 2, medical_aspect = 2, flaws_aspect = 0, attention = 3,
                start_enabled = False
            )

# any label that starts with serum_mod is added to the serum mod list
label serum_mod_quiboune_breeding_trait(stack):
    python:
        add_quiboune_breeding_serum()
        execute_hijack_call(stack)
    return


code:
# idea and original design by electricat
# modified by Kaden
init -1 python:
    def detox_accelerator_trait_on_apply(person, the_serum, add_to_log):
        person._serum_tolerance += 1
        for serum in person.serum_effects:
            serum.duration -=2
        return

    def detox_accelerator_trait_on_remove(person, the_serum, add_to_log):
        person._serum_tolerance -= 1
        return

    def add_detox_accelerator_serum():
        detox_accelerator_trait = SerumTraitMod(name = "Pharmakokinetic Accelerator",
                desc = "Temporarily increases serum tolerance by speeding up the rate at which active serums are disposed of by the body.",
                positive_slug = "+1 serum tolerance",
                negative_slug = "-2 serum duration to all active serums",
                research_added = 20,
                base_side_effect_chance = 0,
                on_apply = detox_accelerator_trait_on_apply,
                on_remove = detox_accelerator_trait_on_remove,
                requires = [weight_loss],
                tier = 2,
                start_researched =  False,
                research_needed = 800,
                clarity_cost = 750,
                mental_aspect = 0, physical_aspect = 3, sexual_aspect = 0, medical_aspect = 5, flaws_aspect = -1, attention = 0,
                start_enabled = False
            )

# any label that starts with serum_mod is added to the serum mod list
label serum_mod_detox_accelerator_serum_trait(stack):
    python:
        add_detox_accelerator_serum()
        execute_hijack_call(stack)
    return


code:
init -1 python:
    def personality_change_on_apply(goal_personality, the_person, the_serum, add_to_log):
        the_person.change_personality(goal_personality)
        return

    def personality_menu():
        temp_list = []
        for x in list_of_personalities:
            if isinstance(x.personality_type_prefix, str):
                temp_string = str.capitalize(x.personality_type_prefix) + " Personality"
                temp_list.append([temp_string, x])
        return temp_list

init 1 python:
    personality_trait = SerumTraitBlueprint(
        unlock_label = "personality_unlock_label",
        name = "Personality Change",
        desc = "Instantly alters the core of the subject's personality.",
        positive_slug = "Changes Personality",
        negative_slug = "",
        research_added = 600,
        base_side_effect_chance = 100,
        tier = 3,
        research_needed = 3000,
        clarity_cost = 3300,
        mental_aspect = 10, physical_aspect = 0, sexual_aspect = 0, medical_aspect = 0, flaws_aspect = 0, attention = 3)

init 16 python:
    add_label_hijack("instantiate_serum_trait_blueprints", "instantiate_instant_personality_blueprint")
    add_label_hijack("after_load", "instantiate_instant_personality_blueprint")

label instantiate_instant_personality_blueprint(stack): # Called from instantiate_serum_traits.
    python:
        if not personality_trait in list_of_traits:
            list_of_traits.append(personality_trait)
        if not bimbo_personality in list_of_personalities:
            list_of_personalities.extend((
                bimbo_personality,
                alpha_personality,
                cougar_personality
            ))
        if 'daddy_girl_personality' in globals():
            list_of_personalities.extend((daddy_girl_personality))
        if 'breeding_stock' in globals():
            list_of_personalities.extend((breeding_stock))
        execute_hijack_call(stack)
    return

label personality_unlock_label(new_trait):
    python:
        return_personality = menu(personality_menu())
        temp_text = str.capitalize(return_personality.personality_type_prefix) + " Personality"
        new_trait.on_apply = partial(personality_change_on_apply, return_personality) #Generates a partially filled function
        new_trait.desc += " "+temp_text+" is the target personality."
        new_trait.name += ": "+temp_text
        del return_personality
        del temp_text
    return


code:
init python:
    def get_impotence_person():
        potential_people = []
        for a_person in mc.location.people:
            if not a_person.title is None:
                if a_person.event_triggers_dict.get("impotence_tracker", 0) >= 10:
                    if not a_person.has_role(girlfriend_role) and not a_person.has_role(harem_role):
                        potential_people.append(a_person)
        return get_random_from_list(potential_people)

    def impotence_requirement():
        if time_of_day > 0 and time_of_day < 4:
            return not get_impotence_person() is None
        return False

    def impotence_serum_function_on_day(person, the_serum, add_to_log):
        if not person.has_role(girlfriend_role) and not person.has_role(harem_role):
            if person.energy > 60:
                temp_number = person.effective_sluttiness() + person.opinion.bareback_sex*10
                if person.relationship == "Girlfriend":
                    temp_number +=10
                elif person.relationship == "Fiancée":
                    temp_number +=20
                elif person.relationship == "Married":
                    temp_number -=10
                if person.personality in [wild_personality, alpha_personality, cougar_personality]:
                    temp_number +=10
                if renpy.random.randint(0,200) < temp_number:
                    person.change_stats(arousal = 30, happiness = -5)
                    person.event_triggers_dict.update({"impotence_tracker" : person.event_triggers_dict.get("impotence_tracker", 0) + temp_number/10})
                    impotence_crisis = Action("Friend SO relationship worsen", impotence_requirement, "impotence_label")
                    crisis_list.append([impotence_crisis, 10])
        return

    def add_impotence_serum():
        impotence_serum_trait = SerumTraitMod(name = "Impotence Secretions",
            desc = "Forces a person to secrete chemicals that cause impotence in potential mates (after inoculating yourself).",
            positive_slug = "Potential for unsatisfying overnight exertions. Impact on relationships and arousal.",
            negative_slug = "",
            research_added = 20,
            base_side_effect_chance = 30,
            on_day = impotence_serum_function_on_day,
            tier = 2,
            start_researched =  False,
            research_needed = 800,
            clarity_cost = 1000,
            mental_aspect = 0, sexual_aspect = 2, physical_aspect = 1, flaws_aspect = 1, attention = 1,
            start_enabled = False
            )

label serum_mod_impotence_serum_trait(stack):
    python:
        add_impotence_serum()
        execute_hijack_call(stack)
    return

label impotence_label():
    $ scene_manager = Scene()
    $ the_person = get_impotence_person()
    if the_person is None or not the_person.title or the_person.mc_title == "Stranger":
        return #Something's changed and there is no longer a valid person
    $ so_title = SO_relationship_to_title(the_person.relationship)
    $ scene_manager.add_actor(the_person)
    if not the_person.event_triggers_dict.get("impotence_chat", False):
        if renpy.random.randint(0,(100-the_person.love)/2) > the_person.event_triggers_dict.get("impotence_tracker", 0):
            "[the_person.title] walks towards you as if she's going to say something, but turns away at the last moment."
            $ scene_manager.update_actor(the_person, position = "walking_away")
            "She looked flushed at first and maybe embarrassed as she walked away. She must not feel comfortable talking to you yet."
            "You wonder if the serum you gave her is having an effect."
        else:
            $ the_person.event_triggers_dict["impotence_chat"] = True
            the_person "Hey [the_person.mc_title], it's good to see you. I have a delicate question I was hoping you could answer."
            mc.name "Of course, how can I help?"
            if len(mc.location.people) > 1:
                "[the_person.title] takes a look around and then steps a bit closer to you, lowering her voice to nearly a whisper."
            the_person "This is a bit embarrassing, can you keep it to yourself?"
            mc.name "Of course."
            the_person "You know [the_person.SO_name], my [so_title]? The last time we were together he had a bit of trouble performing."
            if not the_person.has_taboo("vaginal_sex") or not the_person.has_taboo("anal_sex"):
                the_person "You've never had that problem with me, but you know... does it ever happen to you?"
            else:
                the_person "I know this is super personal, but... does that ever happen for you?"
            menu:
                "Reassure her":
                    mc.name "I've never run into that myself, but it does happen to people."
                    mc.name "Sometimes if a guy drinks too much he can have trouble getting it up."
                    $ the_person.change_love(2)
                    $ the_person.event_triggers_dict["impotence_tracker"] -= 5
                    the_person "Well, that's the thing. He got it up but then once we started getting busy he... went soft."
                    mc.name "Two pump chump?"
                    if the_person.wants_creampie:
                        the_person "No, worse than that. He didn't cum, his condom was empty."
                    else:
                        the_person "No, worse than that. When he pulled out there wasn't any cum."
                    mc.name "Maybe it was just an off night, the next time might be better."
                    the_person "Yeah... I guess. Well, thanks for listening [the_person.mc_title]."
                "Add to her doubts":
                    mc.name "Sorry, that is a problem I've never had."
                    mc.name "If we're being honest, I'm a little surprised that anyone could fail to get it up with someone as hot as you."
                    $ the_person.change_slut(2)
                    $ the_person.event_triggers_dict["impotence_tracker"] += 5
                    the_person "Well, that's the thing. He got it up but then once we started getting busy he... went soft."
                    mc.name "Two pump chump?"
                    if the_person.wants_creampie:
                        the_person "No, worse than that. He didn't cum, his condom was empty."
                    else:
                        the_person "No, worse than that. When he pulled out there wasn't any cum."
                    mc.name "Wow, I understand why you're concerned. Could he be seeing someone else?"
                    the_person "I don't think so... I guess maybe I need to watch him more. Well, thanks for listening [the_person.mc_title]."
            if the_person.love > 40:
                mc.name "No problem. You know, if he left you unsatisfied I could help out..."
                if not the_person.has_taboo("vaginal_sex") or not the_person.has_taboo("anal_sex") or not the_person.has_taboo("licking_pussy") or not the_person.has_taboo("touching_vagina"):
                    if the_person.opinion.cheating_on_men < 0:
                        the_person "Seriously? I'm still with my [so_title]... but I really do need some help."
                    else:
                        the_person "I was hoping you would suggest something like that."
                    if len(mc.location.people) > 1:
                        the_person "Let's go somewhere a bit more private."
                if the_person.outfit.can_half_off_to_vagina():
                    $ generalised_strip_description(the_person, the_person.outfit.get_half_off_to_vagina_list(), position = "stand3", half_off_instead = True)
                else:
                    $ generalised_strip_description(the_person, the_person.outfit.get_full_strip_list(), position = "stand3")
                if not the_person.has_taboo("vaginal_sex") and the_person.arousal_perc > 30:
                    call fuck_person(the_person, start_position = standing_doggy, private = True, start_object = make_wall(), skip_intro = False, skip_condom = False) from _call_fuck_person_i1
                elif not the_person.has_taboo("anal_sex") and the_person.arousal_perc > 20:
                    call fuck_person(the_person, start_position = anal_standing, private = True, start_object = make_floor(), skip_intro = False, skip_condom = False) from _call_fuck_person_i2
                elif not the_person.has_taboo("licking_pussy") and the_person.arousal_perc > 10:
                    call fuck_person(the_person, start_position = standing_cunnilingus, private = True, start_object = make_floor(), skip_intro = False, skip_condom = False) from _call_fuck_person_i3
                elif not the_person.has_taboo("touching_vagina"):
                    call fuck_person(the_person, start_position = standing_finger, private = True, start_object = make_floor(), skip_intro = False, skip_condom = False) from _call_fuck_person_i4
                else:
                    "[the_person.possessive_title!c] starts and gives you a searching look as if trying to decide how serious you are."
                    if the_person.opinion.cheating_on_men < 0:
                        the_person "Seriously? I'm still with my [so_title], I can't believe you would even suggest that."
                    else:
                        the_person "That's sort of sweet but also sort of weird. I'll keep you in mind if things don't improve."
            else:
                mc.name "No problem, I hope things get better for you and I'm here if you need to talk."
            the_person "I guess I'll see you around."
            $ scene_manager.update_actor(the_person, position = "walking_away")
            "As she walks away you take a moment to appreciate the view."
            "It seems like your serum is having an effect, but it hasn't pushed her hard enough to make any life altering decisions yet."
    # add a loop because different relationships should take more to end
    else:
        $ the_person.change_happiness(-20)
        the_person "Hey [the_person.mc_title], it's good to see you."
        if len(mc.location.people) > 1:
            "[the_person.title] takes a look around and then steps a bit closer to you, lowering her voice to nearly a whisper."
        the_person "Do you remember when I told you about [the_person.SO_name]'s little problem?"
        mc.name "I do, have things gotten any better?"
        the_person "No, unfortunately he wasn't even able to get it up the last time tried."
        the_person "I've been so frustrated, and he keeps swearing that there isn't another woman, but..."
        the_person "We fought and things got pretty ugly. We decided to split up."
        $ the_person.relationship = "Single"
        $ the_person.SO_name = None
        $ the_person.change_stats(happiness = -10)
        mc.name "I'm sorry to hear that, [the_person.title], just take it easy and take your time to process it."
        the_person "Thanks, it's appreciated."
        if the_person.has_role(affair_role):
            the_person "I know it's kind of sudden, but... since I'm single now we don't need to keep hiding what we have."
            $ the_person.remove_role(affair_role)
            menu:
                "Start dating her":
                    mc.name "I'm so happy to hear that! I would love to start dating you for real."
                    the_person "Thank god, I was a bit worried about being totally alone."
                    $ scene_manager.update_actor(the_person, position = "kissing", emotion = "happy")
                    "She wraps you in her arms and plants a firm kiss on your lips. It looks like you have a new girlfriend."
                    $ the_person.add_role(girlfriend_role)
                    $ the_person.change_stats(love = 5, happiness = 20)
                "Keep things casual":
                    mc.name "I don't know... what we have has been fun, but I wasn't really looking for something serious."
                    the_person "Right... of course... no pressure, I know this is really sudden."
                    $ scene_manager.update_actor(the_person, position = "kissing", emotion = "sad")
                    "She steps closer to wrap you in a hug and plants a tentative kiss on your cheek."
                    $ the_person.change_stats(love = -2, happiness = -5)
        the_person "I guess I'll see you around."
        $ scene_manager.update_actor(the_person, position = "walking_away")
        "As she walks away you take a moment to appreciate the view."
        "Although it took some time it seems like your serum trait is working to end relationships."
    $ scene_manager.clear_scene()
    return


code:
# idea by Starbuck
# design by Kaden
init python:
    def nocturnal_emission_actuator_serum_function_on_turn(person, the_serum, add_to_log):
        if time_of_day == 4:
            if the_serum.duration - the_serum.duration_counter == 1:
                if person.arousal_perc < 30:
                    person.change_arousal((30 - person.arousal_perc),add_to_log = False)
            elif the_serum.duration - the_serum.duration_counter == 2:
                if person.arousal_perc < 60:
                    person.change_arousal((60 - person.arousal_perc),add_to_log = False)
        return

    def nocturnal_emission_actuator_serum_function_on_day(person, the_serum, add_to_log):
        if person.arousal_perc < 90:
            person.change_arousal((90 - person.arousal_perc),add_to_log = False)
        return

    def add_nocturnal_emission_actuator_serum():
        nocturnal_emission_actuator_serum_trait = SerumTraitMod(name = "Teasing Nightfall",
            desc = "No effect during the day. If a person is affected by it when going to bed, causes numerous lewd dreams.",
            positive_slug = "+90 Arousal overnight",
            negative_slug = "",
            research_added = 20,
            base_side_effect_chance = 30,
            on_turn = nocturnal_emission_actuator_serum_function_on_turn,
            on_day = nocturnal_emission_actuator_serum_function_on_day,
            tier = 2,
            start_researched =  False,
            research_needed = 800,
            clarity_cost = 1000,
            mental_aspect = 2, sexual_aspect = 2, flaws_aspect = 1, attention = 1,
            start_enabled = False
            )

label serum_mod_nocturnal_emission_actuator_serum_trait(stack):
    python:
        add_nocturnal_emission_actuator_serum()
        execute_hijack_call(stack)
    return


code:
init -1 python:
    def personality_change_on_turn(goal_personality, the_person, the_serum, add_to_log):
        if the_person.personality in list_of_personalities:
            if renpy.random.randint(0,200) < the_person.suggestibility:
                if not goal_personality in list_of_personalities and the_person.personality == wild_personality:
                    goal_personality = wild_personality
                else:
                    the_person.personality = goal_personality
                if goal_personality == introvert_personality:
                    if the_person.personality == reserved_personality:
                        the_person.personality = introvert_personality
                    elif the_person.personality == relaxed_personality:
                        the_person.personality = reserved_personality
                    elif the_person.personality == wild_personality:
                        the_person.personality = relaxed_personality
                elif goal_personality == reserved_personality:
                    if the_person.personality == introvert_personality:
                        the_person.personality = reserved_personality
                    elif the_person.personality == relaxed_personality:
                        the_person.personality = reserved_personality
                    elif the_person.personality == wild_personality:
                        the_person.personality = relaxed_personality
                elif goal_personality == relaxed_personality:
                    if the_person.personality == introvert_personality:
                        the_person.personality = reserved_personality
                    elif the_person.personality == reserved_personality:
                        the_person.personality = relaxed_personality
                    elif the_person.personality == wild_personality:
                        the_person.personality = relaxed_personality
                elif goal_personality == wild_personality:
                    if the_person.personality == introvert_personality:
                        the_person.personality = reserved_personality
                    elif the_person.personality == reserved_personality:
                        the_person.personality = relaxed_personality
                    elif the_person.personality == relaxed_personality:
                        the_person.personality = wild_personality
        else:
            mc.log_event(the_person.name + " can not change personalities", "float_text_grey")
        return

init 1 python:
    personality_change_trait = SerumTraitBlueprint(
        unlock_label = "personality_change_unlock_label",
        name = "Personality Alterations",
        desc = "Modifies the core of the subject's personality. Suggestion based chance of changing each turn.",
        positive_slug = "Shifts Personality Towards Set Target",
        negative_slug = "",
        research_added = 400,
        base_side_effect_chance = 80,
        tier = 3,
        research_needed = 2000,
        clarity_cost = 2200,
        mental_aspect = 8, physical_aspect = 0, sexual_aspect = 0, medical_aspect = 0, flaws_aspect = 0, attention = 3)

init 16 python:
    add_label_hijack("instantiate_serum_trait_blueprints", "instantiate_personality_blueprint")
    add_label_hijack("after_load", "instantiate_personality_blueprint")

label instantiate_personality_blueprint(stack): # Called from instantiate_serum_traits.
    python:
        if not personality_change_trait in list_of_traits:
            list_of_traits.append(personality_change_trait)
        execute_hijack_call(stack)
    return

label personality_change_unlock_label(new_trait):
    menu:
        "Introvert":
            $ return_personality = introvert_personality
            $ temp_text = "Introvert"
        "Reserved":
            $ return_personality = reserved_personality
            $ temp_text = "Reserved"
        "Relaxed":
            $ return_personality = relaxed_personality
            $ temp_text = "Relaxed"
        "Wild":
            $ return_personality = wild_personality
            $ temp_text = "Wild"
        "Alpha":
            $ return_personality = alpha_personality
            $ temp_text = "Alpha"
        "Cougar":
            $ return_personality = cougar_personality
            $ temp_text = "Cougar"
        # "Breeding Stock":
        #     $ return_personality = breeding_stock
        #     $ temp_text = "Breeding Stock"
        # "Daddy's Girl":
        #     $ return_personality = daddy_girl
        #     $ temp_text = "Daddy's Girl"
    python:
        new_trait.on_turn = partial(personality_change_on_turn, return_personality) #Generates a partially filled function
        new_trait.desc += " "+temp_text+" is the target personality."
        new_trait.name += ": "+temp_text
        del return_personality
        del temp_text
    return


code:
init -1 python:
    def pubes_change_on_day(goal_pubes, the_person, the_serum, add_to_log):
        if the_person.pubes_style != goal_pubes:
            if renpy.random.randint(0,100) < the_person.suggestibility:
                if goal_pubes == default_pubes:
                    if the_person.pubes_style == trimmed_pubes:
                        the_person.pubes_style = default_pubes
                    else:
                        goal_pubes = trimmed_pubes
                if goal_pubes == trimmed_pubes:
                    if the_person.pubes_style == diamond_pubes or default_pubes:
                        the_person.pubes_style = trimmed_pubes
                    else:
                        goal_pubes = diamond_pubes
                if goal_pubes == diamond_pubes:
                    if the_person.pubes_style == trimmed_pubes or landing_strip_pubes:
                        the_person.pubes_style = diamond_pubes
                    elif the_person.pubes_style == default_pubes:
                        the_person.pubes_style = trimmed_pubes
                    else:
                        goal_pubes = landing_strip_pubes
                if goal_pubes == landing_strip_pubes:
                    if the_person.pubes_style == diamond_pubes or shaved_pubes:
                        the_person.pubes_style = landing_strip_pubes
                    elif the_person.pubes_style == trimmed_pubes:
                        the_person.pubes_style = diamond_pubes
                    else:
                        the_person.pubes_style = trimmed_pubes
                if goal_pubes == shaved_pubes:
                    if the_person.pubes_style == landing_strip_pubes:
                        the_person.pubes_style = shaved_pubes
                    elif the_person.pubes_style == diamond_pubes:
                        the_person.pubes_style = landing_strip_pubes
                    elif the_person.pubes_style == trimmed_pubes:
                        the_person.pubes_style = diamond_pubes
                    elif the_person.pubes_style == default_pubes:
                        the_person.pubes_style = trimmed_pubes
        return

init 1 python:
    pubes_change_trait = SerumTraitBlueprint(
        unlock_label = "pubes_change_unlock_label",
        name = "Pube Alterations",
        desc = "Modifies the desire for body hair. Suggestion based chance of changing each night. ",
        positive_slug = "Shifts Pubes Towards Set Target",
        negative_slug = "",
        research_added = 80,
        base_side_effect_chance = 20,
        tier = 2,
        research_needed = 400,
        clarity_cost = 300,
        mental_aspect = 2, physical_aspect = 2, sexual_aspect = 0, medical_aspect = 1, flaws_aspect = 0, attention = 3)

init 16 python:
    add_label_hijack("instantiate_serum_trait_blueprints", "instantiate_pubes_blueprint")
    add_label_hijack("after_load", "instantiate_pubes_blueprint")

label instantiate_pubes_blueprint(stack): # Called from instantiate_serum_traits.
    python:
        if not pubes_change_trait in list_of_traits:
            list_of_traits.append(pubes_change_trait)
        execute_hijack_call(stack)
    return

label pubes_change_unlock_label(new_trait):
    menu:
        "Shaved":
            $ return_pubes = shaved_pubes
            $ temp_text = "Shaved"
        "Landing Strip":
            $ return_pubes = landing_strip_pubes
            $ temp_text = "Landing Strip"
        "Diamond":
            $ return_pubes = diamond_pubes
            $ temp_text = "Diamond"
        "Trimmed":
            $ return_pubes = trimmed_pubes
            $ temp_text = "Trimmed"
        "Natural":
            $ return_pubes = default_pubes
            $ temp_text = "Natural"
    python:
        new_trait.on_day = partial(pubes_change_on_day, return_pubes) #Generates a partially filled function
        new_trait.desc += " "+temp_text+ " is the target style."
        new_trait.name += ": "+temp_text
        del return_pubes
        del temp_text
    return


code:
init python:
    def add_side_effect_traits():
        temp_number = 1
        for trait in list_of_side_effects:
            temp_name = "side_effect_trait_"+str(temp_number)
            temp_name = SerumTraitMod(name = trait.name ,desc = trait.desc, positive_slug = trait.positive_slug, negative_slug = trait.negative_slug,
                research_added = 50, slots_added = trait.slots, production_added = 50, duration_added = trait.duration, base_side_effect_chance = 5, clarity_added = 50,
                on_apply = trait.on_apply, on_remove = trait.on_remove, on_turn = trait.on_turn, on_day = trait.on_day,
                requires = trait.requires, tier = 1, start_researched = False, research_needed = 50, exclude_tags = trait.exclude_tags, is_side_effect = False,
                clarity_cost = 50, start_unlocked = False, start_enabled = False,
                mental_aspect = trait.mental_aspect, physical_aspect = trait.physical_aspect, sexual_aspect = trait.sexual_aspect, medical_aspect = trait.medical_aspect, flaws_aspect = 0, attention = trait.attention)
            temp_number +=1
        return

label serum_mod_side_effect_traits(stack):
    python:
        add_side_effect_traits()
        execute_hijack_call(stack)
    return


code:
init -1 python:
    def skin_change_on_apply(new_skin, the_person, the_serum, add_to_log):
        return the_person.match_skin(new_skin)

init 1 python:
    skin_change_trait = SerumTraitBlueprint(
        unlock_label = "skin_change_unlock_label",
        name = "Skin Pigmentation",
        desc = "Triggers instant changes in the way the body produces melanin causing skin tone to shift to the desired pigment.",
        positive_slug = "Alters skin tone",
        negative_slug = "",
        research_added = 80,
        base_side_effect_chance = 20,
        tier = 2,
        research_needed = 400,
        clarity_cost = 300,
        mental_aspect = 0, physical_aspect = 2, sexual_aspect = 0, medical_aspect = 1, flaws_aspect = 0, attention = 3)

init 16 python:
    add_label_hijack("instantiate_serum_trait_blueprints", "instantiate_pigment_blueprint")
    add_label_hijack("after_load", "instantiate_pigment_blueprint")

label instantiate_pigment_blueprint(stack): # Called from instantiate_serum_traits.
    python:
        if not skin_change_trait in list_of_traits:
            list_of_traits.append(skin_change_trait)
        execute_hijack_call(stack)
    return

label skin_change_unlock_label(new_trait):
    menu:
        "White":
            $ return_pigment ='white'
            $ temp_text = "White"
        "Tan":
            $ return_pigment = 'tan'
            $ temp_text = "Tan"
        "Black":
            $ return_pigment = 'black'
            $ temp_text = "Black"
    python:
        new_trait.on_apply = partial(skin_change_on_apply, return_pigment) #Generates a partially filled function
        new_trait.desc += " "+temp_text+ " is the target pigment."
        new_trait.name += ": "+temp_text
        del return_pigment
        del temp_text
    return


code:
# idea by quiboune
# original trait by Vavilon
# modified by Kaden
init -1 python:
    def slavery_on_turn(person, the_serum, add_to_log):
        if (person.obedience < 300) and (person.love > -100):
            change_amount = builtins.min(100+person.love, 2, 300-person.obedience)
            person.change_stats(obedience = change_amount, love = -change_amount)
        return

    def add_quiboune_obedience_serum():
        slavery_serum_trait = SerumTraitMod(name = "No Love, Serve",
                desc = "Exchanges Love for Obedience.",
                positive_slug = "+2 Obedience/Turn",
                negative_slug = "-2 Love/Turn",
                research_added = 250,
                base_side_effect_chance = 0,
                on_turn = slavery_on_turn,
                tier = 2,
                start_researched =  False,
                research_needed = 800,
                clarity_cost = 1000,
                mental_aspect = 6, physical_aspect = 0, sexual_aspect = 0, medical_aspect = 2, flaws_aspect = 0, attention = 2,
                start_enabled = False
            )

# any label that starts with serum_mod is added to the serum mod list
label serum_mod_quiboune_obedience_trait(stack):
    python:
        add_quiboune_obedience_serum()
        execute_hijack_call(stack)
    return


code:
init -1 python:
    def wear_pajamas(self, sluttiness = None):
        if sluttiness is None:
            sluttiness = self.sluttiness
        pajamas = get_pajama_outfit(self, sluttiness = sluttiness)
        self.apply_outfit(pajamas)
        return

    def get_pajama_outfit(person, sluttiness = None):
        if sluttiness is None:
            sluttiness = person.sluttiness
        [main_colour, second_colour, third_colour] = random_colours(person, 3)
        main_colour[3] *= 1.0-(sluttiness/400.0)
        second_colour[3] *= 1.0-(sluttiness/300.0)
        pajamas = Outfit("Pajams")
        bottom_list = []
        bottom_list.append(cotton_panties.get_copy())
        bottom_list.append(cute_panties.get_copy())
        if person.opinion.showing_her_ass > 0:
            bottom_list.append(thong.get_copy())
        bottom = get_random_from_list(bottom_list)
        bottom.colour = third_colour
        if hasattr(bottom, "supported_patterns") and bottom.supported_patterns and renpy.random.randint(1, 100) > 50:
            bottom.pattern = bottom.supported_patterns[renpy.random.choice(list(bottom.supported_patterns.keys()))]
            bottom.colour_pattern = WardrobeBuilder.get_color(person, bottom.colour)
        if sluttiness + person.opinion.not_wearing_underwear*5 < 45:
            pajamas.add_lower(bottom)
        elif sluttiness + person.opinion.not_wearing_anything*5 < 85:
            pajamas.add_lower(bottom)

        if sluttiness < 20 + Person.rank_tits(person.tits)*5 - person.opinion.not_wearing_underwear*5:
            pajamas.add_upper(sports_bra.get_copy(), third_colour)
        covered = False
        lower = None
        if sluttiness < 15 + person.opinion.pants*5:
            lower = leggings.get_copy()
            covered = True
        else:
            if sluttiness < 35 + person.opinion.pants*5:
                lower = booty_shorts.get_copy()
                covered = True
            if renpy.random.randint(1, 100) > 70 - sluttiness/5:
                socks = high_socks.get_copy()
                socks.colour = second_colour
                if hasattr(socks, "supported_patterns") and socks.supported_patterns and renpy.random.randint(1, 100) > 50:
                    socks.pattern = socks.supported_patterns[renpy.random.choice(list(socks.supported_patterns.keys()))]
                    socks.colour_pattern = WardrobeBuilder.get_color(person, socks.colour)
                pajamas.add_feet(socks)
        if lower:
            lower.colour = second_colour
            if hasattr(lower, "supported_patterns") and lower.supported_patterns and renpy.random.randint(1, 100) > 50:
                lower.pattern = lower.supported_patterns[renpy.random.choice(list(lower.supported_patterns.keys()))]
                lower.colour_pattern = WardrobeBuilder.get_color(person, lower.colour)
            pajamas.add_lower(lower)
        upper_list = []
        if covered:
            upper_list.append(long_tshirt.get_copy())
            if sluttiness > 10 - person.opinion.skimpy_outfits*5:
                upper_list.append(wrapped_blouse.get_copy())
                upper_list.append(long_sweater.get_copy())
            if sluttiness > 15 - person.opinion.skimpy_outfits*5:
                upper_list.append(sleeveless_top.get_copy())
                upper_list.append(camisole.get_copy())
                upper_list.append(tshirt.get_copy())
            if sluttiness > 20 - person.opinion.skimpy_outfits*5:
                upper_list.append(tanktop.get_copy())
                upper_list.append(sports_bra.get_copy())
        else:
            if sluttiness >= 25 - person.opinion.skimpy_outfits*5 and sluttiness < 45:
                upper_list.append(sweater_dress.get_copy())
                upper_list.append(long_tshirt.get_copy())
                upper_list.append(wrapped_blouse.get_copy())
            if sluttiness > 35 - person.opinion.skimpy_outfits*5 and sluttiness < 65:
                upper_list.append(long_sweater.get_copy())
                upper_list.append(sleeveless_top.get_copy())
            if sluttiness > 45 - person.opinion.skimpy_outfits*5 and sluttiness < 85:
                upper_list.append(camisole.get_copy())
                upper_list.append(tshirt.get_copy())
                upper_list.append(nightgown_dress.get_copy())
            if sluttiness > 55 - person.opinion.skimpy_outfits*5:
                upper_list.append(tanktop.get_copy())
                upper_list.append(sports_bra.get_copy())
                upper_list.append(teddy.get_copy())
        if sluttiness + person.opinion.not_wearing_anything*5 < 85:
            upper = get_random_from_list(upper_list)
            if upper:
                upper.colour = main_colour
                if hasattr(upper, "supported_patterns") and upper.supported_patterns and renpy.random.randint(1, 100) > 50:
                    upper.pattern = upper.supported_patterns[renpy.random.choice(list(upper.supported_patterns.keys()))]
                    upper.colour_pattern = WardrobeBuilder.get_color(person, upper.colour)
                pajamas.add_upper(upper)
                pajamas.add_dress(upper)
        return pajamas

init 0 python:
    def run_move_enhanced(org_func):
        def run_move_enhanced_wrapper(person):
            # run original function
            org_func(person)
            # run extension code
            if time_of_day > 3:
                if person.location == person.home:
                    wear_pajamas(person)
                if not aunt.event_triggers_dict.get("invited_for_drinks", False):
                    if aunt.location == hall:
                        wear_pajamas(aunt)
                    if cousin.location == lily_bedroom:
                        wear_pajamas(cousin)
            if person.location.name == "beach":
                person.apply_outfit(get_beach_outfit(person))
            return
        return run_move_enhanced_wrapper

    Person.run_move = run_move_enhanced(Person.run_move)

label pajama_test():
    call screen main_choice_display(build_menu_items([get_sorted_people_list(known_people_in_the_game(), "Pajama Test", "Back")]))
    $ person_choice = _return
    if person_choice != "Back":
        $ number = 1
        while number < 100:
            $ wear_pajamas(person_choice, sluttiness = number)
            $ person_choice.draw_person(emotion = "happy")
            $ outfit_slut = person_choice.outfit.outfit_slut_score
            "Current sluttiness = [number]. Outfit sluttiness = [outfit_slut]."
            $ number += 1
        $ del person_choice
    return


code:
init -1 python:
    def traits_by_attention(attention = 0, flaws = 0, serum = []):
        temp_list = []
        exclude_tags = build_exclude_tags(serum)
        for trait in list_of_traits:
            if trait.unlocked and trait.researched and trait.attention <= attention:
                if trait.flaws_aspect <= flaws:
                    if not trait.exclude_tags in exclude_tags:
                        if not trait in serum:
                            if not isinstance(trait, SerumTraitBlueprint):
                                if isinstance(trait, SerumTrait):
                                    temp_list.append(trait)
        return temp_list

    def unlocked_traits():
        temp_list = []
        for trait in list_of_traits:
            if trait.unlocked:
                if not trait.researched:
                    temp_list.append(trait)
        return temp_list

    def max_mental(temp_list):
        aspect = 0
        mental_list = []
        for trait in temp_list:
            if trait.mental_aspect > aspect:
                aspect = trait.mental_aspect
                mental_list = [trait]
            elif trait.mental_aspect == aspect:
                mental_list.append(trait)
        if mental_list:
            return mental_list
        return None

    def max_physical(temp_list):
        aspect = 0
        physical_list = []
        for trait in temp_list:
            if trait.physical_aspect > aspect:
                aspect = trait.physical_aspect
                physical_list = [trait]
            elif trait.physical_aspect == aspect:
                physical_list.append(trait)
        if physical_list:
            return physical_list
        return None

    def max_sexual(temp_list):
        aspect = 0
        sexual_list = []
        for trait in temp_list:
            if trait.sexual_aspect > aspect:
                aspect = trait.sexual_aspect
                sexual_list = [trait]
            elif trait.sexual_aspect == aspect:
                sexual_list.append(trait)
        if sexual_list:
            return sexual_list
        return None

    def max_medical(temp_list):
        aspect = 0
        medical_list = []
        for trait in temp_list:
            if trait.medical_aspect > aspect:
                aspect = trait.medical_aspect
                medical_list = [trait]
            elif trait.medical_aspect == aspect:
                medical_list.append(trait)
        if medical_list:
            return medical_list
        return None

    def suf_mental(temp_list, aspect):
        mental_list = []
        for trait in temp_list:
            if trait.mental_aspect >= aspect:
                mental_list.append(trait)
        if mental_list:
            return mental_list
        return max_mental(temp_list)

    def suf_physical(temp_list, aspect):
        physical_list = []
        for trait in temp_list:
            if trait.physical_aspect >= aspect:
                physical_list.append(trait)
        if physical_list:
            return physical_list
        return max_physical(temp_list)

    def suf_sexual(temp_list, aspect):
        sexual_list = []
        for trait in temp_list:
            if trait.sexual_aspect >= aspect:
                sexual_list.append(trait)
        if sexual_list:
            return sexual_list
        return max_sexual(temp_list)

    def suf_medical(temp_list, aspect):
        medical_list = []
        for trait in temp_list:
            if trait.medical_aspect >= aspect:
                medical_list.append(trait)
        if medical_list:
            return medical_list
        return max_medical(temp_list)

    def max_total_aspect(temp_list):
        max_total = 0
        max_list = []
        for trait in temp_list:
            x = trait.mental_aspect + trait.physical_aspect + trait.sexual_aspect + trait.medical_aspect
            if x > max_total:
                max_total = x
                max_list = [trait]
            else:
                max_list.append(trait)
        return max_list

    #new function to check max price at current market if max_list is > 1

    def build_exclude_tags(temp_list):
        exclude_tags = []
        for trait in temp_list:
            if trait.exclude_tags:
                exclude_tags.append(trait.exclude_tags)
        return exclude_tags

    def total_flaws(temp_list):
        x = 0
        for trait in temp_list:
            x += trait.flaws_aspect
        return x

    def serum_for_contract(contract, max_path = True, suf_path = True):
        max_complete = False
        suf_complete = False
        effective_attention = contract.attention
        if attention_floor_increase_1_policy.is_active:
            effective_attention += 1
        if attention_floor_increase_2_policy.is_active:
            effective_attention += 1
        max_serum = []
        suf_serum = []
        while max_path or suf_path:
            aspect_list = [[contract.mental_aspect, "mental"], [contract.physical_aspect, "physical"], [contract.sexual_aspect, "sexual"], [contract.medical_aspect, "medical"]]
            max_sorted_list = sorted(aspect_list.copy())
            suf_sorted_list = sorted(aspect_list.copy())
            flaw_allowance = contract.flaws_aspect
            if effective_attention >= 2 and futuristic_serum_prod.researched:
                slots = 7
                max_serum.append(futuristic_serum_prod)
                suf_serum.append(futuristic_serum_prod)
            elif effective_attention >= 1 and advanced_serum_prod.researched:
                slots = 5
                max_serum.append(advanced_serum_prod)
                suf_serum.append(advanced_serum_prod)
            elif improved_serum_prod.researched:
                slots = 3
                max_serum.append(improved_serum_prod)
                suf_serum.append(improved_serum_prod)
            else:
                slots = 2
                max_serum.append(primitive_serum_prod)
                suf_serum.append(primitive_serum_prod)
            temp_flaw = 0
            trait = max_serum[0]
            # renpy.say(None, trait.name)
            aspect_list[0][0] -= trait.mental_aspect
            aspect_list[1][0] -= trait.physical_aspect
            aspect_list[2][0] -= trait.sexual_aspect
            aspect_list[3][0] -= trait.medical_aspect
            if max_path:
                max_path = False
                while slots > 0:
                    temp_flaw = 0
                    while temp_flaw <= flaw_allowance and slots > 0:
                        pruned_traits = traits_by_attention(attention = effective_attention, flaws = flaw_allowance, serum = max_serum)
                        if len(pruned_traits) < slots:
                            slots = len(pruned_traits) -1
                        aspect = max_sorted_list[0][1]
                        if aspect == "mental":
                            traits = max_mental(pruned_traits)
                        elif aspect == "physical":
                            traits = max_physical(pruned_traits)
                        elif aspect == "sexual":
                            traits = max_sexual(pruned_traits)
                        elif aspect == "medical":
                            traits = max_medical(pruned_traits)
                        if traits:
                            trait = get_random_from_list(max_total_aspect(traits))
                            if trait.name == "High Capacity Design":
                                slots += 2
                            # renpy.say(None, "max " + trait.name)
                            max_serum.append(trait)
                            aspect_list[0][0] -= trait.mental_aspect
                            aspect_list[1][0] -= trait.physical_aspect
                            aspect_list[2][0] -= trait.sexual_aspect
                            aspect_list[3][0] -= trait.medical_aspect
                            flaw_allowance -= trait.flaws_aspect
                            temp_flaw = 0
                            slots -= 1
                        else:
                            temp_flaw += 1
                        max_sorted_list = sorted(aspect_list.copy())
                        x = 3
                        while x > -1:
                            if max_sorted_list[x][0] < 1:
                                max_sorted_list.pop(x)
                            x -=1
                        if not max_sorted_list:
                            max_complete = True
                            max_sorted_list = [[1, "mental"], [1, "physical"], [1, "sexual"], [1, "medical"]]
            elif suf_path:
                suf_path = False
                while slots > 0:
                    temp_flaw = 0
                    while temp_flaw <= flaw_allowance and slots > 0:
                        pruned_traits = traits_by_attention(attention = effective_attention, flaws = flaw_allowance, serum = suf_serum)
                        if len(pruned_traits) < slots:
                            # renpy.say(None, "short pruned list")
                            slots = len(pruned_traits) -1
                        aspect = suf_sorted_list[0][1]
                        target = suf_sorted_list[0][0]
                        if aspect == "mental":
                            traits = suf_mental(pruned_traits, target)
                        elif aspect == "physical":
                            traits = suf_physical(pruned_traits, target)
                        elif aspect == "sexual":
                            traits = suf_sexual(pruned_traits, target)
                        elif aspect == "medical":
                            traits = suf_medical(pruned_traits, target)
                        if traits:
                            trait = get_random_from_list(max_total_aspect(traits))
                            if trait.name == "High Capacity Design":
                                slots += 2
                            # renpy.say(None, "suf " + trait.name)
                            suf_serum.append(trait)
                            aspect_list[0][0] -= trait.mental_aspect
                            aspect_list[1][0] -= trait.physical_aspect
                            aspect_list[2][0] -= trait.sexual_aspect
                            aspect_list[3][0] -= trait.medical_aspect
                            flaw_allowance -= trait.flaws_aspect
                            temp_flaw = 0
                            slots -= 1
                        else:
                            # renpy.say(None, "suf flaw +1")
                            temp_flaw += 1
                        suf_sorted_list = sorted(aspect_list.copy())
                        x = 3
                        while x > -1:
                            # renpy.say(None, "popping suf " + str(x))
                            if suf_sorted_list[x][0] < 1:
                                suf_sorted_list.pop(x)
                            x -=1
                        if not suf_sorted_list:
                            suf_complete = True
                            suf_sorted_list = [[1, "mental"], [1, "physical"], [1, "sexual"], [1, "medical"]]
        if max_complete or suf_complete:
            if max_complete:
                if suf_complete:
                    if len(suf_serum) > len(max_serum):
                        serum = suf_serum
                    else:
                        serum = max_serum
                else:
                    serum = max_serum
            else:
                serum = suf_serum
            return serum, None
        elif len(max_serum) >= len(suf_serum):
            return max_serum, max_sorted_list
        return suf_serum, suf_sorted_list

init 3 python:
    def serum_builder_requirement():
        if mc.business.is_open_for_business:
            if mc.business.active_contracts or mc.business.offered_contracts:
                return True
            return "Wait for contracts to be offered"
        return "Wait for business to be open"

    def serum_builder_initialization(self):
        m_division.add_action(self)
        return

    def contract_menu(temp_list):
        contract_list = []
        for x in temp_list:
            contract_list.append([x.name, x])
        contract_list.append(["Back", "Back"])
        return contract_list

    def missing_aspect_text(sorted_list):
        x = len(sorted_list) - 1
        y = len(sorted_list) - 1
        while x >= 0:
            number = sorted_list[x][0]
            if number <= 0:
                y -= 1
            x -= 1
        text = ""
        x = len(sorted_list) - 1
        while x >= 0:
            number = sorted_list[x][0]
            if number > 0:
                number = str(sorted_list[x][0])
                label = sorted_list[x][1]
                text = text + number + " more " + label + " aspect"
                if y >= 1:
                    text = text + ", "
                if y == 1:
                    text = text + "and "
                y -= 1
            x -= 1
        return text

    serum_builder_action = ActionMod("Build a serum", serum_builder_requirement, "serum_builder_label", initialization = serum_builder_initialization,
        menu_tooltip = "Build a serum for a contract.", category = "Business Action")

init 4 python:
    def market_demand_requirement():
        if mc.business.is_open_for_business:
            if mc.business.market_team:
                if mc.is_at_office:
                    if lowest_demand():
                        return True
        return False

    def lowest_demand():
        temp_serum = None
        x = 1.00
        for line in mc.business.production_lines:
            if line.selected_design and line.selected_design.market_demand < x:
                x = line.selected_design.market_demand
                temp_serum = line.selected_design
        if x < 0.50:
            return temp_serum
        return None

    def clear_production_line(the_serum):
        for line in mc.business.production_lines:
            if line.selected_design == the_serum:
                line.clear_product()
        return

    market_demand_action = ActionMod("Market Demand", market_demand_requirement, "market_demand_label",
        menu_tooltip = "Get informed that market demand for serums in production is too low.",
        category = "Business Crisis", is_crisis = True, priority = 10)

label serum_builder_label():
    $ active = len(mc.business.active_contracts)
    $ offered = len(mc.business.offered_contracts)
    "You currently have [active] active contracts and [offered] offered contracts."
    menu:
        "Active" if active > 0:
            $ contract_list = contract_menu(mc.business.active_contracts)
        "Offered" if offered > 0:
            $ contract_list = contract_menu(mc.business.offered_contracts)
        "Back":
            return
    $ contract = menu(contract_list)
    if not contract == "Back":
        $ serum_design, sorted_list = serum_for_contract(contract)
        if sorted_list:
            "A serum could not be built for this contract. The closest design will still display."
            $ temp_text = missing_aspect_text(sorted_list)
            "To fulfil this contract you need traits with [temp_text]."
            if sorted_list[0][1] == "mental":
                $ traits = max_mental(unlocked_traits())
            elif sorted_list[0][1] == "physical":
                $ traits = max_physical(unlocked_traits())
            elif sorted_list[0][1] == "sexual":
                $ traits = max_sexual(unlocked_traits())
            elif sorted_list[0][1] == "medical":
                $ traits = max_medical(unlocked_traits())
            if traits:
                $ trait = get_random_from_list(max_total_aspect(traits))
                "You might want to start by researching [trait.name]."
            else:
                "You might need to advance to your next research tier to find one."
        if serum_design:
            call serum_design_action_description(SerumDesign.clone_serum(contract.name, serum_design)) from _call_serum_design_description_builder
        else:
            "Unable to build a serum for this contract."
    return

label market_demand_label():
    $ scene_manager = Scene()
    if mc.business.company_model:
        $ the_person = mc.business.company_model
    else:
        $ the_person = get_random_from_list(mc.business.market_team)
    $ contract = None
    $ the_serum = lowest_demand()
    if not the_serum or not the_person:
        "MARKET DEMAND FAILED"
        return
    if mc.location == m_division:
        "As you work [the_person.possessive_title] approaches you, it looks like she has something to tell you."
    else:
        "As you work you get a text from [the_person.possessive_title] in marketing. It looks like she wants you to come see her."
        $ mc.change_location(m_division)
        "When you get there you quickly move over to [the_person.title]."
    $ scene_manager.add_actor(the_person, emotion = "sad")
    mc.name "Yes? How can I help you?"
    the_person "I've noticed a bit of a problem. Our customers just don't seem to be interested in buying [the_serum.name] anymore."
    $ temp_number = round(the_serum.market_demand * 100)
    the_person "Its market demand is down to [temp_number]%% and production just keeps sending us more."
    $ x = len(mc.business.active_contracts)-1
    while x > -1 and not contract:
        if mc.business.active_contracts[x]:
            $ test_contract = mc.business.active_contracts[x]
            if lowest_demand() in get_designs_that_satisfy_contract(test_contract):
                $ contract = mc.business.active_contracts[x]
        $ x-=1
    $ x = len(mc.business.offered_contracts)-1
    while x > -1 and not contract:
        if mc.business.offered_contracts[x]:
            $ test_contract = mc.business.offered_contracts[x]
            if lowest_demand() in get_designs_that_satisfy_contract(test_contract):
                $ contract = mc.business.offered_contracts[x]
        $ x-=1
    if contract:
        the_person "I suppose we could keep making them for contracts like the [contract.name] one, but our general customers don't want it."
    menu:
        "Thank her":
            mc.name "I understand. I'll talk to production about refocusing on something that will be easier to sell."
            $ scene_manager.update_actor(the_person, emotion = "happy")
        "Get upset":
            mc.name "Are you questioning me?"
            the_person "What?"
            mc.name "This is my business, and if I want the production department to make a serum they will make it."
            the_person "I know.. but..."
            if office_punishment.is_active:
                menu:
                    "Spank her now" if corporal_punishment.is_active:
                        mc.name "No buts... well actually..."
                        mc.name "Get over here, there is one butt that seems like it needs some attention."
                        if not strict_enforcement.is_active:
                            call punishment_spank(the_person, Infraction.bureaucratic_mistake_factory()) from _call_punishment_spank_serum
                        else:
                            call punishment_strip_and_spank(the_person, Infraction.bureaucratic_mistake_factory()) from _call_punishment_spank_serum2
                    "Punish her for insubordination later":
                        mc.name "No buts, I'm in charge you just work here. I think I'm going to have to write you up for insubordination."
                        the_person "But..."
                        "Seeing your glare [the_person.possessive_title] trails off."
                        the_person "Yes [the_person.mc_title]. Whatever you need to do."
                        if the_person.obedience < 150:
                            $ the_person.change_stats(obedience = 3, happiness = -5, love = -1)
                        else:
                            $ the_person.change_stats(obedience = 2)
                        $ the_person.add_infraction(Infraction.bureaucratic_mistake_factory())
                    "Let it go":
                        mc.name "But nothing. Get back to work."
            else:
                mc.name "But nothing. Get back to work."
    $ clear_scene
    "Would you like to visit the production department now?"
    menu:
        "Go now":
            $ clear_production_line(the_serum)
            $ mc.change_location(p_division)
            if mc.business.production_team:
                $ the_person = get_random_from_list(mc.business.production_team)
                # $ scene_manager.add_actor(the_person, emotion = "happy")
                # talk to someone
            call production_select_action_description() from _call_production_select_action_description_market
        "Deal with it later":
            "You decide to just get back to work, but make a note to investigate more later."
    $ clear_scene
    return