コード例 #1
0
    def on_remove(self, apply_loot_on_remove: bool = True) -> None:
        returnValue = super().on_remove(
            apply_loot_on_remove=apply_loot_on_remove)

        ownerSimInfo = self._owner  # type: sim_info.SimInfo
        ownerSimSystem = Reproduction.GetSimSystem(
            ownerSimInfo
        )  # type: typing.Optional[ReproductionShared.ReproductiveSystem]

        if ownerSimSystem is None:
            return

        ownerEffectTracker = ownerSimSystem.GetTracker(
            UniversalShared.EffectTrackerIdentifier)  # type: typing.Any

        if ownerEffectTracker is None:
            return

        ownerMenstrualEffect = ownerEffectTracker.GetEffect(
            EffectsShared.MenstrualEffectTypeIdentifier)

        if ownerMenstrualEffect is None:
            return

        ownerMenstrualEffect.NotifyBuffRemoved(self)

        return returnValue
コード例 #2
0
        def __call__(self, actors: typing.Tuple[sim_info.SimInfo, ...]):
            if len(actors) == 0:
                Debug.Log(
                    "Took pill recently test received an empty actors parameter.",
                    This.Mod.Namespace,
                    Debug.LogLevels.Warning,
                    group=This.Mod.Namespace,
                    owner=__name__)
                return results.TestResult(False)

            targetActor = actors[0]  # type: sim_info.SimInfo

            targetSystem = Reproduction.GetSimSystem(
                targetActor)  # type: ReproductionShared.ReproductiveSystem

            if targetSystem is None:
                return results.TestResult(False)

            targetCycleTracker = targetSystem.GetTracker(
                FemalesShared.CycleTrackerIdentifier)

            if targetCycleTracker is None:
                return results.TestResult(False)

            return results.TestResult(True)
コード例 #3
0
    def on_add(self, from_load=False, apply_buff_loot=True) -> None:
        returnValue = super().on_add(from_load=from_load,
                                     apply_buff_loot=apply_buff_loot)

        ownerSimInfo = self._owner  # type: sim_info.SimInfo
        ownerSimSystem = Reproduction.GetSimSystem(
            ownerSimInfo
        )  # type: typing.Optional[ReproductionShared.ReproductiveSystem]

        if ownerSimSystem is None:
            return

        ownerEffectTracker = ownerSimSystem.GetTracker(
            UniversalShared.EffectTrackerIdentifier)  # type: typing.Any

        if ownerEffectTracker is None:
            return

        ownerMenstrualEffect = ownerEffectTracker.GetEffect(
            EffectsShared.MenstrualEffectTypeIdentifier)

        if ownerMenstrualEffect is None:
            return

        ownerMenstrualEffect.NotifyBuffAdded(self, fromLoad=from_load)

        return returnValue
コード例 #4
0
def _OnSimAddCallback (simInfo: sim_info.SimInfo) -> None:
	if not This.Mod.IsLoaded():
		return

	try:
		if Reproduction.SimHasSystem(simInfo):
			Debug.Log("Went to create a reproductive system for a sim being added, but one already exists.", This.Mod.Namespace, Debug.LogLevels.Warning, group = This.Mod.Namespace, owner = __name__)
			return

		simSystem = Reproduction.InitiateReproductiveSystem(simInfo)
		simsSection = Saving.GetSimsSection()  # type: SectionBranched.SectionBranched

		if Saving.GetSimsSection().SavingObject.Loaded:
			simSystem.Load(simsSection)
	except:
		Debug.Log("Reproduction on sim add callback failed.", This.Mod.Namespace, Debug.LogLevels.Exception, group = This.Mod.Namespace, owner = __name__)
コード例 #5
0
ファイル: Debug.py プロジェクト: NeonOcean/S4.Cycle
def ShowReproductiveInfoNotifications(targetSimInfo: sim_info.SimInfo) -> None:
    if not isinstance(targetSimInfo, sim_info.SimInfo):
        raise Exceptions.IncorrectTypeException(targetSimInfo, "targetSimInfo",
                                                (sim_info.SimInfo, ))

    targetSimSystem = Reproduction.GetSimSystem(
        targetSimInfo
    )  # type: typing.Optional[ReproductionShared.ReproductiveSystem]

    if targetSimSystem is None:
        return

    notificationText = targetSimSystem.GetDebugNotificationString()

    notificationArguments = {
        "title":
        Language.MakeLocalizationStringCallable(
            Language.CreateLocalizationString("")),
        "text":
        Language.MakeLocalizationStringCallable(
            Language.CreateLocalizationString(notificationText)),
    }

    Notifications.ShowNotification(queue=False, **notificationArguments)

    Debug.Log(
        "Collected and reported debug info from a sim's reproductive system by request.\n\n%s"
        % notificationText,
        This.Mod.Namespace,
        Debug.LogLevels.Info,
        group=This.Mod.Namespace,
        owner=__name__)
コード例 #6
0
def _OnSimRemoveCallback (simInfo: sim_info.SimInfo) -> None:
	if not This.Mod.IsLoaded():
		return

	try:
		Reproduction.RemoveSimSystem(simInfo)
	except:
		Debug.Log("Reproduction on sim remove callback failed.", This.Mod.Namespace, Debug.LogLevels.Exception, group = This.Mod.Namespace, owner = __name__)
コード例 #7
0
def TakePill(targetSimInfo: sim_info.SimInfo,
             pillsObject: typing.Optional[script_object.ScriptObject],
             requiresPill: bool = True,
             removePill: bool = True,
             showGeneralFeedback: bool = True) -> bool:
    if not isinstance(targetSimInfo, sim_info.SimInfo):
        raise Exceptions.IncorrectTypeException(targetSimInfo, "targetSimInfo",
                                                (sim_info.SimInfo, ))

    if not isinstance(pillsObject,
                      script_object.ScriptObject) and pillsObject is not None:
        raise Exceptions.IncorrectTypeException(
            pillsObject, "pillsObject", (script_object.ScriptObject, None))

    if not isinstance(requiresPill, bool):
        raise Exceptions.IncorrectTypeException(requiresPill, "requiresPill",
                                                (bool, ))

    if not isinstance(removePill, bool):
        raise Exceptions.IncorrectTypeException(removePill, "removePill",
                                                (bool, ))

    if pillsObject is None and (requiresPill or removePill):
        raise ValueError(
            "The 'pillsObject' parameter cannot be none if the requires pill or remove pill parameters are true."
        )

    if not isinstance(showGeneralFeedback, bool):
        raise Exceptions.IncorrectTypeException(showGeneralFeedback,
                                                "showGeneralFeedback",
                                                (bool, ))

    targetSystem = Reproduction.GetSimSystem(
        targetSimInfo
    )  # type: typing.Optional[ReproductionShared.ReproductiveSystem]

    if targetSystem is None:
        return False

    effectTracker = targetSystem.GetTracker(
        UniversalShared.EffectTrackerIdentifier
    )  # type: typing.Optional[EffectTracker.EffectTracker]

    if effectTracker is None:
        return False

    emergencyContraceptivePillEffect = effectTracker.GetEffect(
        EffectsShared.EmergencyContraceptivePillEffectTypeIdentifier
    )  # type: typing.Optional[EffectsEmergencyContraceptivePill.EmergencyContraceptivePillEffect]

    if emergencyContraceptivePillEffect is None:
        return False

    emergencyContraceptivePillEffect.NotifyOfTakenPill()

    if removePill:
        pillsObject.destroy()
コード例 #8
0
    def ZoneSave(cls,
                 zoneReference: zone.Zone,
                 saveSlotData: typing.Optional[typing.Any] = None) -> None:
        for reproductiveSystem in Reproduction.GetAllSystems():
            systemPregnancyTracker = reproductiveSystem.GetTracker(
                FemalesShared.PregnancyTrackerIdentifier
            )  # type: typing.Optional[PregnancyTracker.PregnancyTracker]

            if systemPregnancyTracker is not None:
                systemPregnancyTracker.SetPregnancyVisualsIfAppropriate()
コード例 #9
0
def _ClearPregnancy(self: pregnancy_tracker.PregnancyTracker, *args,
                    **kwargs) -> None:
    targetSimSystem = Reproduction.GetSimSystem(
        self._sim_info
    )  # type: typing.Optional[ReproductionShared.ReproductiveSystem]
    pregnancyTracker = targetSimSystem.GetTracker(
        FemalesShared.PregnancyTrackerIdentifier
    )  # type: typing.Optional[PregnancyTracker.PregnancyTracker]

    if pregnancyTracker is None:
        return

    pregnancyTracker.NotifyPregnancyEnded()
コード例 #10
0
def _SettingsOnUpdateCallback(
        owner, eventArguments: SettingsBase.UpdateEventArguments) -> None:
    if eventArguments.Changed(Settings.PregnancySpeed.Key):
        for simReproductiveSystem in Reproduction.GetAllSystems(
                automaticallyUpdate=False):
            pregnancyTracker = simReproductiveSystem.GetTracker(
                FemalesShared.PregnancyTrackerIdentifier
            )  # type: typing.Optional[PregnancyTracker.PregnancyTracker]

            if pregnancyTracker is None:
                continue

            simReproductiveSystem.Update()
コード例 #11
0
def _StandardUpdateCallback (alarmHandle: alarms.AlarmHandle) -> None:
	if not This.Mod.IsLoaded():
		return

	reportLockIdentifier = __name__ + ":UpdateCallback"  # type: str

	try:
		Reproduction.UpdateSystems()  # TODO log the time taken?

		updateTicks = Reproduction.GetUpdateTicks(_standardUpdateInterval)  # type: typing.Dict[int, typing.List[ReproductionShared.ReproductiveSystem]]

		for plannedTick, plannedSystems in updateTicks.items():  # type: int, typing.List[ReproductionShared.ReproductiveSystem]
			if plannedTick >= _standardUpdateInterval:
				continue

			alarmTimeSpan = date_and_time.TimeSpan(plannedTick)
			plannedUpdateAlarm = alarms.add_alarm(sys.modules[__name__], alarmTimeSpan, _CreatePlannedUpdateCallback(plannedSystems))

			_plannedUpdateAlarms.append(plannedUpdateAlarm)
	except:
		Debug.Log("Reproduction standard update callback failed.", This.Mod.Namespace, Debug.LogLevels.Exception, group = This.Mod.Namespace, owner = __name__, lockIdentifier = reportLockIdentifier)
	else:
		Debug.Unlock(reportLockIdentifier)
コード例 #12
0
ファイル: Debug.py プロジェクト: NeonOcean/S4.Cycle
def _FixDotCycle(targetSimHandler: argument_helpers.RequiredTargetParam,
                 _connection=None) -> None:
    try:
        if game_services.service_manager is None:
            return

        targetSimInfo = targetSimHandler.get_target(
            services.sim_info_manager())

        if not isinstance(targetSimInfo, sim_info.SimInfo):
            raise ValueError(
                "Failed to get the target sim, %s is not a valid sim id." %
                targetSimHandler.target_id)

        targetDotInformation = Dot.GetDotInformation(
            targetSimInfo)  # type: typing.Optional[Dot.DotInformation]

        if targetDotInformation is None:
            return

        targetSystem = Reproduction.GetSimSystem(
            targetSimInfo
        )  # type: typing.Optional[ReproductionShared.ReproductiveSystem]

        if targetSystem is None:
            return

        targetCycleTracker = targetSystem.GetTracker(
            FemalesShared.CycleTrackerIdentifier
        )  # type: typing.Optional[CycleTracker.CycleTracker]

        if targetCycleTracker is None:
            return

        if targetCycleTracker.CurrentCycle is not None:
            targetDotInformation.TimeSinceCycleStart = targetCycleTracker.CurrentCycle.Age
        else:
            if targetCycleTracker.TimeSinceLastCycle is not None:
                targetDotInformation.TimeSinceCycleStart = targetCycleTracker.TimeSinceLastCycle
    except Exception as e:
        Debug.Log("Failed to fix a sim's dot cycle.",
                  This.Mod.Namespace,
                  Debug.LogLevels.Exception,
                  group=This.Mod.Namespace,
                  owner=__name__,
                  exception=e)
        raise e
コード例 #13
0
	def _plannedUpdateCallback (alarmHandle: alarms.AlarmHandle) -> None:
		if not This.Mod.IsLoaded():
			return

		reportLockIdentifier = __name__ + ":UpdateCallback"  # type: str

		try:
			Reproduction.UpdateSystems(plannedSystems)  # TODO log the time taken?
		except:
			Debug.Log("Reproduction planned update callback failed.", This.Mod.Namespace, Debug.LogLevels.Exception, group = This.Mod.Namespace, owner = __name__, lockIdentifier = reportLockIdentifier)
		else:
			Debug.Unlock(reportLockIdentifier)

		try:
			_plannedUpdateAlarms.remove(alarmHandle)
		except ValueError:
			pass
コード例 #14
0
def ShowTestResultNotification(targetSimInfo: sim_info.SimInfo) -> None:
    if not isinstance(targetSimInfo, sim_info.SimInfo):
        raise Exceptions.IncorrectTypeException(targetSimInfo, "targetSimInfo",
                                                (sim_info.SimInfo, ))

    targetSimSystem = Reproduction.GetSimSystem(
        targetSimInfo)  # type: ReproductionShared.ReproductiveSystem

    if targetSimSystem is None:
        ShowNegativeTestResultNotification(targetSimInfo)
        return

    targetPregnancyTracker = targetSimSystem.GetTracker(
        FemalesShared.PregnancyTrackerIdentifier
    )  # type: typing.Optional[PregnancyTracker.PregnancyTracker]

    if targetPregnancyTracker.GeneratePregnancyTestResults():
        ShowPositiveTestResultNotification(targetSimInfo)
    else:
        ShowNegativeTestResultNotification(targetSimInfo)
コード例 #15
0
ファイル: Dot.py プロジェクト: NeonOcean/S4.Cycle
        def __call__(self, actors: typing.Tuple[sim_info.SimInfo, ...]):
            if len(actors) == 0:
                Debug.Log(
                    "Has cycle tracker test recived an empty actors parameter.",
                    This.Mod.Namespace,
                    Debug.LogLevels.Warning,
                    group=This.Mod.Namespace,
                    owner=__name__)
                return results.TestResult(False)

            targetSimInfo = actors[0]  # type: sim_info.SimInfo

            targetSimSystem = Reproduction.GetSimSystem(
                targetSimInfo
            )  # type: typing.Optional[ReproductionShared.ReproductiveSystem]

            if targetSimSystem is None:
                return results.TestResult(False)

            return results.TestResult(
                targetSimSystem.HasTracker(
                    FemalesShared.CycleTrackerIdentifier))
コード例 #16
0
ファイル: Menstruation.py プロジェクト: NeonOcean/S4.Cycle
	def IsHidden(cls, simID: str) -> bool:
		"""
		Get whether or not this setting should be visible to the user.
		"""

		if not isinstance(simID, str):
			raise Exceptions.IncorrectTypeException(simID, "simID", (str,))

		try:
			simIDNumber = int(simID)  # type: int
		except ValueError:
			return True

		if game_services.service_manager is None:
			return True

		simInfoManager = services.sim_info_manager()  # type: typing.Optional[sim_info_manager.SimInfoManager]

		if simInfoManager is None:
			return True

		simInfo = simInfoManager.get(simIDNumber)  # type: typing.Optional[sim_info.SimInfo]

		if simInfo is None:
			return True

		if simInfo.species != sim_info_types.Species.HUMAN:
			return True

		simSystem = Reproduction.GetSimSystem(simInfo)  # type: typing.Optional[ReproductionShared.ReproductiveSystem]

		if simSystem is None:
			return True

		if not simSystem.HasTracker(FemalesShared.CycleTrackerIdentifier):
			return True

		return False
コード例 #17
0
def _ClearOva(targetSimHandler: argument_helpers.RequiredTargetParam,
              clearFertilized: bool = True,
              _connection=None) -> None:
    try:
        if game_services.service_manager is None:
            return

        targetSimInfo = targetSimHandler.get_target(
            services.sim_info_manager())

        if not isinstance(targetSimInfo, sim_info.SimInfo):
            raise ValueError(
                "Failed to get the target sim, %s is not a valid sim id." %
                targetSimHandler.target_id)

        targetSimSystem = Reproduction.GetSimSystem(
            targetSimInfo
        )  # type: typing.Optional[ReproductionShared.ReproductiveSystem]

        if targetSimSystem is None:
            return

        targetSimOvumTracker = targetSimSystem.GetTracker(
            FemalesShared.OvumTrackerIdentifier)  # type: typing.Any

        if targetSimOvumTracker is None:
            return

        targetSimOvumTracker.ClearAllOva(clearFertilized=clearFertilized)
    except Exception as e:
        Debug.Log("Failed to clear sperm from a sim.",
                  This.Mod.Namespace,
                  Debug.LogLevels.Exception,
                  group=This.Mod.Namespace,
                  owner=__name__,
                  exception=e)
        raise e
コード例 #18
0
def _SimsSectionLoadCallback (simsSection: SectionBranched.SectionBranched) -> bool:
	return Reproduction.LoadAllSystems(simsSection = simsSection)
コード例 #19
0
ファイル: Debug.py プロジェクト: NeonOcean/S4.Cycle
def _ShowSetPregnancyProgressDialog(
        targetSimHandler: argument_helpers.RequiredTargetParam,
        _connection=None) -> None:
    try:
        if game_services.service_manager is None:
            return

        targetSimInfo = targetSimHandler.get_target(
            services.sim_info_manager())

        if not isinstance(targetSimInfo, sim_info.SimInfo):
            raise ValueError(
                "Failed to get the target sim, %s is not a valid sim id." %
                targetSimHandler.target_id)

        targetSimSystem = Reproduction.GetSimSystem(
            targetSimInfo
        )  # type: typing.Optional[ReproductionShared.ReproductiveSystem]

        if targetSimSystem is None:
            return

        targetSimPregnancyTracker = targetSimSystem.GetTracker(
            FemalesShared.PregnancyTrackerIdentifier
        )  # type: typing.Optional[PregnancyTracker.PregnancyTracker]

        currentProgress = round(
            targetSimPregnancyTracker.GetPregnancyProgress(), 3)  # type: float

        def dialogCallback(
                dialogReference: ui_dialog_generic.UiDialogTextInputOkCancel):
            if dialogReference.response == ui_dialog.ButtonType.DIALOG_RESPONSE_OK:
                nextProgressString = dialogReference.text_input_responses[
                    "Input"]  # type: str

                try:
                    nextProgress = float(nextProgressString)  # type: float
                except:
                    return

                if currentProgress != nextProgress:
                    targetSimPregnancyTracker.SetPregnancyProgress(
                        nextProgress)

        textInputKey = "Input"  # type: str

        textInputLockedArguments = {
            "sort_order": 0,
        }

        textInput = ui_text_input.UiTextInput.TunableFactory(
            locked_args=textInputLockedArguments
        ).default  # type: ui_text_input.UiTextInput
        textInputInitialValue = Language.MakeLocalizationStringCallable(
            Language.CreateLocalizationString(str(currentProgress)))

        textInput.initial_value = textInputInitialValue

        textInputs = collections.make_immutable_slots_class([textInputKey])
        textInputs = textInputs({textInputKey: textInput})

        dialogArguments = {
            "title":
            SetPregnancyProgressDialogTitle.GetCallableLocalizationString(),
            "text":
            SetPregnancyProgressDialogText.GetCallableLocalizationString(),
            "text_ok":
            SetPregnancyProgressDialogOkButton.GetCallableLocalizationString(),
            "text_cancel":
            SetPregnancyProgressDialogCancelButton.
            GetCallableLocalizationString(),
            "text_inputs":
            textInputs
        }

        Dialogs.ShowOkCancelInputDialog(callback=dialogCallback,
                                        queue=False,
                                        **dialogArguments)
    except Exception as e:
        Debug.Log(
            "Failed to show the set pregnancy progress dialog for a sim.",
            This.Mod.Namespace,
            Debug.LogLevels.Exception,
            group=This.Mod.Namespace,
            owner=__name__,
            exception=e)
        raise e
コード例 #20
0
def _SimsSectionSaveCallback (simsSection: SectionBranched.SectionBranched) -> bool:
	return Reproduction.SaveAllSystems(simsSection = simsSection)
コード例 #21
0
def _SimsSectionResetCallback (simsSection: SectionBranched.SectionBranched) -> bool:
	return Reproduction.ResetSystems()
コード例 #22
0
ファイル: Insemination.py プロジェクト: NeonOcean/S4.Cycle
def AutoInseminate(
        inseminatedSimInfo: sim_info.SimInfo,
        sourceSimInfo: sim_info.SimInfo,
        tryingForBaby: bool = True,
        generateGenericSperm: bool = False,
        woohooSafetyMethods: typing.Optional[typing.List[
            WoohooSafety.WoohooSafetyMethod]] = None,
        arrivingSpermPercentage: typing.Optional[float] = None) -> None:
    """
	A simple function to add sperm to a sim.
	:param inseminatedSimInfo: The sim who is being inseminated.
	:type inseminatedSimInfo: sim_info.SimInfo
	:param sourceSimInfo: The sim who is providing the sperm.
	:type sourceSimInfo: sim_info.SimInfo
	:param tryingForBaby: Whether or not the sims are trying for a baby. Sims trying to a baby will not use any devices to prevent pregnancy, such as condoms.
	:type tryingForBaby: bool
	:param generateGenericSperm: Whether or not we should generate a generic sperm object if the source sim does not have a sperm production tracker.
	:type generateGenericSperm: bool
	:param woohooSafetyMethods: Allows for the woohoo safety methods that would normally be used by the two sims to be overridden.
	:type woohooSafetyMethods: typing.Optional[typing.List[Safety.WoohooSafetyMethod]]
	:param arrivingSpermPercentage: Allows for the sperm arrival percentage to be overridden. Other than the arriving sperm percentage, which will be
	overridden, we will act as though the appropriate woohoo safety methods have been used. This must be between 0 and 1.
	:type arrivingSpermPercentage: typing.Optional[float]
	"""

    if not isinstance(inseminatedSimInfo, sim_info.SimInfo):
        raise Exceptions.IncorrectTypeException(inseminatedSimInfo,
                                                "inseminatedSimInfo",
                                                (sim_info.SimInfo, ))

    if not isinstance(sourceSimInfo, sim_info.SimInfo):
        raise Exceptions.IncorrectTypeException(sourceSimInfo, "sourceSimInfo",
                                                (sim_info.SimInfo, ))

    if not isinstance(tryingForBaby, bool):
        raise Exceptions.IncorrectTypeException(tryingForBaby, "tryingForBaby",
                                                (bool, ))

    if not isinstance(generateGenericSperm, bool):
        raise Exceptions.IncorrectTypeException(generateGenericSperm,
                                                "generateGenericSperm",
                                                (bool, ))

    if not isinstance(woohooSafetyMethods,
                      list) and woohooSafetyMethods is not None:
        raise Exceptions.IncorrectTypeException(woohooSafetyMethods,
                                                "woohooSafetyMethods",
                                                (list, None))

    if woohooSafetyMethods is not None:
        for woohooSafetyMethodIndex in range(
                len(woohooSafetyMethods)):  # type: int
            woohooSafetyMethod = woohooSafetyMethods[
                woohooSafetyMethodIndex]  # type: WoohooSafety.WoohooSafetyMethod

            if not isinstance(woohooSafetyMethod,
                              WoohooSafety.WoohooSafetyMethod):
                raise Exceptions.IncorrectTypeException(
                    woohooSafetyMethod,
                    "woohooSafetyMethod[%s]" % woohooSafetyMethodIndex,
                    (WoohooSafety.WoohooSafetyMethod, ))

    if not isinstance(arrivingSpermPercentage,
                      float) and arrivingSpermPercentage is not None:
        raise Exceptions.IncorrectTypeException(arrivingSpermPercentage,
                                                "arrivingSpermPercentage",
                                                (float, None))

    if arrivingSpermPercentage is not None:
        if not (0 < arrivingSpermPercentage < 1):
            raise ValueError(
                "The parameter 'arrivingSpermPercentage' must be greater than or equal to 0 and less than or equal to 1."
            )

    inseminatedSystem = Reproduction.GetSimSystem(
        inseminatedSimInfo
    )  # type: typing.Union[ReproductionShared.ReproductiveSystem, None]

    if inseminatedSystem is None or not inseminatedSystem.HasTracker(
            FemalesShared.SpermTrackerIdentifier):
        return

    sourceSystem = Reproduction.GetSimSystem(
        sourceSimInfo
    )  # type: typing.Union[ReproductionShared.ReproductiveSystem, None]

    if sourceSystem is None or not sourceSystem.HasTracker(
            MalesShared.SpermProductionTrackerIdentifier):
        if not generateGenericSperm:
            return

        inseminatedSpermGuide = CycleGuides.SpermGuide.GetGuide(
            inseminatedSystem.GuideGroup)  # type: CycleGuides.SpermGuide
        inseminatedSpermTracker = inseminatedSystem.GetTracker(
            FemalesShared.SpermTrackerIdentifier)

        releasingSperm = Sperm.GenerateGenericSperm(
            source=sourceSimInfo,
            spermGuide=inseminatedSpermGuide)  # type: Sperm.Sperm
    else:
        inseminatedSpermTracker = inseminatedSystem.GetTracker(
            FemalesShared.SpermTrackerIdentifier)
        sourceSpermProductionTracker = sourceSystem.GetTracker(
            MalesShared.SpermProductionTrackerIdentifier)

        releasingSperm = sourceSpermProductionTracker.GenerateSperm(
        )  # type: Sperm.Sperm

    if not tryingForBaby:
        if woohooSafetyMethods is None:
            woohooSafetyMethods = set(
            )  # type: typing.Set[WoohooSafety.WoohooSafetyMethod]

            woohooSafetyMethods.update(
                WoohooSafety.GetUsingWoohooSafetyMethods(inseminatedSimInfo))
            woohooSafetyMethods.update(
                WoohooSafety.GetUsingWoohooSafetyMethods(sourceSimInfo))

            woohooSafetyMethods = list(
                woohooSafetyMethods
            )  # type: typing.List[WoohooSafety.WoohooSafetyMethod]

        methodPerformanceSelections = WoohooSafety.MethodPerformanceSelectionSet(
            woohooSafetyMethods)

        if arrivingSpermPercentage is None:
            arrivingSpermPercentage = methodPerformanceSelections.GenerateSpermArrivingPercentage(
            )

        arrivingSpermCount = int(releasingSperm.SpermCount *
                                 arrivingSpermPercentage)  # type: int

        if arrivingSpermCount != 0:
            releasingSperm.SpermCount = arrivingSpermCount
            inseminatedSpermTracker.ReleaseSperm(releasingSperm)

        methodPerformanceSelections.HandlePostUse(inseminatedSimInfo,
                                                  sourceSimInfo)
    else:
        inseminatedSpermTracker.ReleaseSperm(releasingSperm)