def _TriggerAnnouncement (self, announcementMethodName: str, preemptive: bool, *announcementArgs, **announcementKwargs) -> None: for announcer in Director.GetAllAnnouncers(): # type: typing.Type[Director.Announcer] readReportLockIdentifier = None # type: typing.Optional[str] readReportLockReference = None # type: typing.Any if self.LimitErrors: readReportLockIdentifier = __name__ + ":" + str(Python.GetLineNumber()) # type: str readReportLockReference = announcer try: if not announcer.Enabled: continue if not announcer.Host.IsLoaded() and not announcer.Reliable: continue if preemptive != announcer.Preemptive: continue announcementMethod = getattr(announcer, announcementMethodName) # type: typing.Callable except Exception: from NeonOcean.S4.Main import Debug Debug.Log("Failed to read the announcer at '" + Types.GetFullName(announcer) + "' when triggering the announcement '" + announcementMethodName + "'.", announcer.Host.Namespace, Debug.LogLevels.Exception, group = announcer.Host.Namespace, owner = __name__, lockIdentifier = readReportLockIdentifier, lockReference = readReportLockReference) return else: if readReportLockIdentifier is not None: from NeonOcean.S4.Main import Debug Debug.Unlock(readReportLockIdentifier, readReportLockReference) callReportLockIdentifier = None # type: typing.Optional[str] callReportLockReference = None # type: typing.Any if self.LimitErrors: callReportLockIdentifier = __name__ + ":" + str(Python.GetLineNumber()) # type: str callReportLockReference = announcer try: if self.AnnouncementCallWrapper is None: announcementMethod(*announcementArgs, **announcementKwargs) else: self.AnnouncementCallWrapper(announcementMethod, *announcementArgs, **announcementKwargs) except Exception: from NeonOcean.S4.Main import Debug Debug.Log("Failed to trigger the announcement '" + announcementMethodName + "' for '" + Types.GetFullName(announcer) + "'.", announcer.Host.Namespace, Debug.LogLevels.Exception, group = announcer.Host.Namespace, owner = __name__, lockIdentifier = callReportLockIdentifier, lockReference = callReportLockReference) return else: if callReportLockIdentifier is not None: from NeonOcean.S4.Main import Debug Debug.Unlock(callReportLockIdentifier, callReportLockReference)
def _SimulateInternal(self, simulation: ReproductionShared.Simulation, ticks: int, reproductiveTimeMultiplier: float) -> None: simulatingMinutes = ReproductionShared.TicksToReproductiveMinutes( ticks, reproductiveTimeMultiplier) # type: float quickMode = Settings.QuickMode.Get() # type: bool if not self.Fertilized: decaying = False # type: bool if self.Age < self.TimeRemaining <= (self.Age + simulatingMinutes): decaying = True if decaying: #TODO set age first? if self.DecayedCallback is None: Debug.Log( "Missing callback to be triggered on ovum decay.", This.Mod.Namespace, Debug.LogLevels.Warning, group=This.Mod.Namespace, owner=__name__, lockIdentifier=__name__ + ":" + str(Python.GetLineNumber())) else: self.DecayedCallback(self) else: if quickMode: implanting = True # type: bool self.Age = self.ImplantationTime else: implanting = False # type: bool if self.Age < self.TimeUntilImplantation <= ( self.Age + simulatingMinutes): implanting = True if implanting: if self.AttemptImplantationCallback is None: Debug.Log( "Missing callback to be triggered on ovum implantation attempt.", This.Mod.Namespace, Debug.LogLevels.Warning, group=This.Mod.Namespace, owner=__name__, lockIdentifier=__name__ + ":" + str(Python.GetLineNumber())) else: self.AttemptImplantationCallback(self) self.Age += simulatingMinutes
def GetPregnancyProgress(self) -> float: """ Get the amount the active pregnancy has progressed toward completion. This will be a number from 0 to 1. """ if not self.IsPregnant: return 0 gamePregnancyTracker = self.TrackingSystem.SimInfo.pregnancy_tracker pregnancyCommodityType = gamePregnancyTracker.PREGNANCY_COMMODITY_MAP.get( self.TrackingSystem.SimInfo.species ) # type: typing.Type[commodity.Commodity] pregnancyCommodityTracker = self.TrackingSystem.SimInfo.get_tracker( pregnancyCommodityType) # type: commodity_tracker.CommodityTracker pregnancyCommodity = pregnancyCommodityTracker.get_statistic( pregnancyCommodityType, add=True) # type: commodity.Commodity pregnancyProgress = pregnancyCommodity.get_value( ) / pregnancyCommodity.max_value # type: float if pregnancyProgress < 0 or pregnancyProgress > 1: Debug.Log( "Calculated the pregnancy progress (%s) as being less than 0 or greater than 1.\n%s" % (pregnancyProgress, self.DebugInformation), This.Mod.Namespace, Debug.LogLevels.Exception, group=This.Mod.Namespace, owner=__name__, lockIdentifier=__name__ + ":" + str(Python.GetLineNumber())) pregnancyProgress = min(max(pregnancyProgress, 0), 1) return pregnancyProgress
def _WickedWhimsUpdateSexSettingsToGeneralSaveDataPatch( originalCallable: typing.Callable, *args, **kwargs) -> bool: try: # noinspection PyUnresolvedReferences from wickedwhims.sex import sex_settings as WickedWhimsSexSettings if WickedWhimsSexSettings.get_sex_setting( WickedWhimsSexSettings.SexSetting.PREGNANCY_MODE ) != WickedWhimsSexSettings.PregnancyModeSetting.SIMPLE: # noinspection PyProtectedMember WickedWhimsSexSettings._sex_settings_data[ WickedWhimsSexSettings.SexSetting. PREGNANCY_MODE] = WickedWhimsSexSettings.PregnancyModeSetting.SIMPLE if WickedWhimsSexSettings.get_sex_setting( WickedWhimsSexSettings.SexSetting.BIRTH_CONTROL_PILLS_AUTO_USE ) != 0: # noinspection PyProtectedMember WickedWhimsSexSettings._sex_settings_data[ WickedWhimsSexSettings.SexSetting. BIRTH_CONTROL_PILLS_AUTO_USE] = 0 return originalCallable(*args, **kwargs) except: Debug.Log( "Failed to handle WickedWhim's update sex settings to general save data function.", This.Mod.Namespace, Debug.LogLevels.Exception, group=This.Mod.Namespace, owner=__name__, lockIdentifier=__name__ + ":" + str(Python.GetLineNumber())) return originalCallable(*args, **kwargs)
def _WickedWhimsTakeBirthControlPillPatch(originalCallable: typing.Callable, turbo_sim: typing.Any, no_inventory: bool = False, *args, **kwargs) -> bool: try: Debug.Log("Here Pill", This.Mod.Namespace, Debug.LogLevels.Warning) # TODO REMOVE targetSimInfo = turbo_sim.get_sim_info( ) # type: typing.Optional[sim_info.SimInfo] if targetSimInfo is None: return False if no_inventory: SafetyBirthControlPills.TakePill(targetSimInfo, None, requiresPill=False, removePill=False) except: Debug.Log( "Failed to handle WickedWhim's take birth control pill function.", This.Mod.Namespace, Debug.LogLevels.Exception, group=This.Mod.Namespace, owner=__name__, lockIdentifier=__name__ + ":" + str(Python.GetLineNumber())) return originalCallable(turbo_sim, no_inventory=no_inventory, *args, **kwargs)
def _PregnancyCommodityWatcher( statisticTracker: base_statistic_tracker.BaseStatisticTracker, statisticType: typing.Type[base_statistic.BaseStatistic], oldValue: float, newValue: float) -> None: try: if oldValue != newValue: # We only care about statistic modifier changes here, when those change the old value will always equal the new value. return if not isinstance(statisticTracker.owner, sim_info.SimInfo): return if not statisticTracker.owner.is_pregnant: return if statisticType is not GamePregnancyTracker.PregnancyTracker.PREGNANCY_COMMODITY_MAP.get( sim_info_types.Species.HUMAN, None): return statistic = statisticTracker.get_statistic( statisticType, add=True) # type: base_statistic.BaseStatistic _ApplySettingsPregnancyStatistic(statistic) except: Debug.Log("Failed to handle statistic change.", This.Mod.Namespace, Debug.LogLevels.Exception, group=This.Mod.Namespace, owner=__name__, lockIdentifier=__name__ + ":" + str(Python.GetLineNumber()))
def VerifySystems( reproductiveSystems: typing.Optional[typing.Iterable[ ReproductionShared.ReproductiveSystem]] = None ) -> None: """ Verify that all specified reproductive systems should exist and that their values are valid. :param reproductiveSystems: All reproductive systems that need to be verified. If this is None the function will go through all registered reproductive systems. :type reproductiveSystems: typing.Iterable[ReproductionShared.ReproductiveSystem] | None """ if reproductiveSystems is None: reproductiveSystems = GetAllSystems(automaticallyUpdate=False) for reproductiveSystem in reproductiveSystems: # type: ReproductionShared.ReproductiveSystem reportLockIdentifier = __name__ + ":" + str( Python.GetLineNumber()) # type: str reportLockReference = reproductiveSystem try: if not reproductiveSystem.ShouldExist: UnregisterReproductiveSystem(reproductiveSystem) continue reproductiveSystem.Verify() except: Debug.Log("Failed to verify a reproductive system.\n" + reproductiveSystem.DebugInformation, This.Mod.Namespace, Debug.LogLevels.Exception, group=This.Mod.Namespace, owner=__name__, lockIdentifier=reportLockIdentifier, lockReference=reportLockReference) else: Debug.Unlock(reportLockIdentifier, reportLockReference)
def NotifyPregnancyEnded(self) -> None: """ Notify this reproductive system that a pregnancy has ended. If we are not monitoring the pregnancy, or we detect the sim is still pregnant, nothing will happen. """ if self.IsPregnant: return if not self.MonitoringPregnancy: return self.MonitoringPregnancy = False eventArguments = CycleEvents.PregnancyEndedArguments() for pregnancyEndedCallback in self.PregnancyEndedEvent: try: pregnancyEndedCallback(self, eventArguments) except: Debug.Log("Failed to call pregnancy ended callback '" + Types.GetFullName(pregnancyEndedCallback) + "'.\n" + self.TrackingSystem.DebugInformation, This.Mod.Namespace, Debug.LogLevels.Exception, group=This.Mod.Namespace, owner=__name__, lockIdentifier=__name__ + ":" + str(Python.GetLineNumber()), lockReference=pregnancyEndedCallback) self.ResetPregnancyVisualsIfAppropriate()
def GetSimSimsSectionBranchKey(targetSimInfo: sim_info.SimInfo) -> str: """ Get the branch that the target sim has data on in the sims section. If this sim has no saved data, then we will return the sim's id as a string. This takes into consideration if the sim has changed their sim id since the last save. """ if not isinstance(targetSimInfo, sim_info.SimInfo): raise Exceptions.IncorrectTypeException(targetSimInfo, "targetSimInfo", (sim_info.SimInfo, )) currentSimID = targetSimInfo.id try: lastSimID = LastSimID.GetLastSimID(targetSimInfo) except: Debug.Log( "Could not retrieve the last sim id for a sim with the current id of '%s'." % currentSimID, This.Mod.Namespace, Debug.LogLevels.Warning, group=This.Mod.Namespace, owner=__name__, lockIdentifier=__name__ + ":" + str(Python.GetLineNumber()), lockThreshold=5) lastSimID = None currentSimIDString = str(currentSimID) # type: str lastSimIDString = str(lastSimID) # type: str if lastSimID is None or lastSimID == 0: return currentSimIDString if lastSimID != currentSimID: Debug.Log( "Found a sim that seems to have changed their sim id. Current ID: %s Last ID: %s" % (currentSimID, lastSimID), This.Mod.Namespace, Debug.LogLevels.Warning, group=This.Mod.Namespace, owner=__name__, lockIdentifier=__name__ + ":" + str(Python.GetLineNumber()), lockThreshold=5) if not GetSimsSection().BranchExists(lastSimIDString): return currentSimIDString else: return lastSimIDString
def SelectBuffRarity(self) -> typing.Optional[BuffsShared.BuffRarity]: """ Randomly select a buff rarity based on the current state of the effect and the system. This will return None if no buff rarity was selected. """ buffRarity = self.GetBuffRarity( ) # type: typing.Optional[Probability.Probability] if buffRarity is None: Debug.Log( "Could not get a valid buff rarity probability object, the buff rarity base value was probably never set.", This.Mod.Namespace, Debug.LogLevels.Exception, group=This.Mod.Namespace, owner=__name__, lockIdentifier=__name__ + ":" + str(Python.GetLineNumber())) return None if not buffRarity.HasOptions: Debug.Log( "Retrieved a buff rarity probability object had no options to pick from.", This.Mod.Namespace, Debug.LogLevels.Exception, group=This.Mod.Namespace, owner=__name__, lockIdentifier=__name__ + ":" + str(Python.GetLineNumber())) return None rarityChoiceSeed = self.Seed + 470760185 # type: int rarityChoiceString = self.GetBuffRarity().ChooseOption( rarityChoiceSeed).Identifier # type: str try: if rarityChoiceString == "Abstain": return None else: return BuffsShared.BuffRarity[rarityChoiceString] except: Debug.Log("Failed to parse rarity option identifier '%s'" % rarityChoiceString, This.Mod.Namespace, Debug.LogLevels.Exception, group=This.Mod.Namespace, owner=__name__, lockIdentifier=__name__ + ":" + str(Python.GetLineNumber())) return None
def _ApplyBellyModifierValue(self, applyingModifierValue: float) -> None: hasFeminineFrameTrait = self._HasFeminineFrameTrait() # type: bool hasMasculineFrameTrait = self._HasMasculineFrameTrait() # type: bool if hasFeminineFrameTrait or (not hasFeminineFrameTrait and not hasMasculineFrameTrait and self.TrackingSystem.SimInfo.gender == sim_info_types.Gender.FEMALE): appropriatePositiveModifierKey = References.FemaleBellyPositiveModifierKey # type: int appropriateNegativeModifierKey = References.FemaleBellyNegativeModifierKey # type: int elif hasMasculineFrameTrait or (not hasFeminineFrameTrait and not hasMasculineFrameTrait and self.TrackingSystem.SimInfo.gender == sim_info_types.Gender.MALE): appropriatePositiveModifierKey = References.MaleBellyPositiveModifierKey # type: int appropriateNegativeModifierKey = References.MaleBellyNegativeModifierKey # type: int else: Debug.Log( "Could not determine the frame type or gender of a system's sim.\n" + self.DebugInformation, This.Mod.Namespace, Debug.LogLevels.Error, group=This.Mod.Namespace, owner=__name__, lockIdentifier=__name__ + ":" + str(Python.GetLineNumber())) return simAttributes = PersistenceBlobs_pb2.BlobSimFacialCustomizationData( ) # type: typing.Any # noinspection PyPropertyAccess simAttributes.ParseFromString( self.TrackingSystem.SimInfo.facial_attributes) if applyingModifierValue > 0: targetModifierKey = appropriatePositiveModifierKey # type: int inappropriateModifierKey = appropriateNegativeModifierKey # type: int targetModifierValue = applyingModifierValue # type: float else: targetModifierKey = appropriateNegativeModifierKey inappropriateModifierKey = appropriatePositiveModifierKey # type: int targetModifierValue = applyingModifierValue * -1 # type: float for bodyModifier in simAttributes.body_modifiers: if bodyModifier.key == targetModifierKey: bodyModifier.amount = targetModifierValue bodyModifierIndex = 0 while bodyModifierIndex < len(simAttributes.body_modifiers): bodyModifier = simAttributes.body_modifiers[bodyModifierIndex] if bodyModifier.key == inappropriateModifierKey: del simAttributes.body_modifiers[bodyModifierIndex] continue bodyModifierIndex += 1 self.TrackingSystem.SimInfo.facial_attributes = simAttributes.SerializeToString( )
def __call__(self, affordance: typing.Type[_DotAppInteraction], actors: typing.Tuple[sim_info.SimInfo, ...]): if affordance is None: return results.TestResult(False) if not issubclass(affordance, _DotAppInteraction): return results.TestResult(False) if len(actors) == 0: Debug.Log( "Dot app state test recived an empty actors parameter.", This.Mod.Namespace, Debug.LogLevels.Warning, group=This.Mod.Namespace, owner=__name__, lockIdentifier=__name__ + ":" + str(Python.GetLineNumber())) return results.TestResult(False) targetSimInfo = actors[0] # type: sim_info.SimInfo dotInformation = Dot.GetDotInformation( targetSimInfo) # type: typing.Optional[Dot.DotInformation] if dotInformation is None: Debug.Log( "Missing dot information for a sim with the id '%s'." % targetSimInfo.id, This.Mod.Namespace, Debug.LogLevels.Warning, group=This.Mod.Namespace, owner=__name__, lockIdentifier=__name__ + ":" + str(Python.GetLineNumber()), lockReference=targetSimInfo) return results.TestResult(False) if affordance.RequiredDotEnabledState is None: return results.TestResult(True) else: return results.TestResult(dotInformation.Enabled == affordance.RequiredDotEnabledState)
def GetUpdateTicks( maximumTick: int, reproductiveSystems: typing.Optional[typing.Iterable[ ReproductionShared.ReproductiveSystem]] = None ) -> typing.Dict[int, typing.List[ReproductionShared.ReproductiveSystem]]: """ Get a dictionary of ticks paired with lists of reproductive systems that should update on them. :param maximumTick: Planned updates beyond this tick will be ignored. :type maximumTick: int :param reproductiveSystems: The reproductive systems to get an update tick for. If this is None the function will go through all registered reproductive systems. :type reproductiveSystems: typing.Iterable[ReproductionShared.ReproductiveSystem] | None """ if reproductiveSystems is None: reproductiveSystems = GetAllSystems() updateTicks = dict( ) # type: typing.Dict[int, typing.List[ReproductionShared.ReproductiveSystem]] for reproductiveSystem in reproductiveSystems: # type: ReproductionShared.ReproductiveSystem reportLockIdentifier = __name__ + ":" + str( Python.GetLineNumber()) # type: str reportLockReference = reproductiveSystem try: planUpdateArguments = reproductiveSystem.PlanUpdate() plannedTick = planUpdateArguments.RequestedTick if plannedTick is None or plannedTick >= maximumTick: plannedTick = maximumTick plannedTickSystems = updateTicks.get( plannedTick, None ) # type: typing.Optional[typing.List[ReproductionShared.ReproductiveSystem]] if plannedTickSystems is None: plannedTickSystems = list() updateTicks[plannedTick] = plannedTickSystems plannedTickSystems.append(reproductiveSystem) except: Debug.Log("Failed to plan the update of a reproductive system\n." + reproductiveSystem.DebugInformation, This.Mod.Namespace, Debug.LogLevels.Exception, group=This.Mod.Namespace, owner=__name__, lockIdentifier=reportLockIdentifier, lockReference=reportLockReference) else: Debug.Unlock(reportLockIdentifier, reportLockReference) return updateTicks
def _GetPregnancyStatisticOwner( pregnancyStatistic: base_statistic.BaseStatistic ) -> typing.Optional[sim_info.SimInfo]: pregnancyStatisticTracker = pregnancyStatistic.tracker # type: typing.Optional[base_statistic_tracker.BaseStatisticTracker] if pregnancyStatisticTracker is None: Debug.Log("Found a pregnancy statistic with no tracker.", This.Mod.Namespace, Debug.LogLevels.Warning, group=This.Mod.Namespace, owner=__name__, lockIdentifier=__name__ + ":" + str(Python.GetLineNumber()), lockThreshold=5) return None pregnancyStatisticOwner = pregnancyStatisticTracker.owner # type: typing.Optional[script_object.ScriptObject] if pregnancyStatisticOwner is None: Debug.Log("Found a pregnancy statistic with a tracker but no owner.", This.Mod.Namespace, Debug.LogLevels.Warning, group=This.Mod.Namespace, owner=__name__, lockIdentifier=__name__ + ":" + str(Python.GetLineNumber()), lockThreshold=5) return if not isinstance(pregnancyStatisticOwner, sim_info.SimInfo): Debug.Log( "Found a pregnancy statistic that has an object other than a sim as its owner.", This.Mod.Namespace, Debug.LogLevels.Warning, group=This.Mod.Namespace, owner=__name__, lockIdentifier=__name__ + ":" + str(Python.GetLineNumber()), lockThreshold=5) return return pregnancyStatisticOwner
def DetermineAllObjectTypes(cls) -> None: operationStartTime = time.time() # type: float cls._objectsByType = dict( ) # type: typing.Dict[str, typing.Set[typing.Type[script_object.ScriptObject]]] # noinspection PyProtectedMember objectManager = services.get_instance_manager( resources.Types.OBJECT ) # type: definition_manager.DefinitionManager objectDefinitions = objectManager.loaded_definitions for typeIdentifier, typeDeterminer in cls._typeDeterminers.items( ): # type: str, typing.Callable matchingObjects = set( ) # type: typing.Set[typing.Type[script_object.ScriptObject]] for objectDefinition in objectDefinitions: # type: typing.Any, definition.Definition matchingType = False # type: bool try: matchingType = typeDeterminer(objectDefinition) except: Debug.Log( "Type determiner failed to determine if an object definition matches the type identifier '" + typeIdentifier + "'.\nObject Definition ID:" + str(objectDefinition.id), cls.Host.Namespace, Debug.LogLevels.Exception, group=cls.Host.Namespace, owner=__name__, lockIdentifier=__name__ + ":" + str(Python.GetLineNumber()), lockReference=typeDeterminer) if matchingType: matchingObjects.add(objectDefinition.cls) cls._objectsByType[typeIdentifier] = matchingObjects operationTime = time.time() - operationStartTime cls._objectTypesDetermined = True Debug.Log( "Finished organizing all objects by type in %s seconds with %s type determiners and %s object definitions existing." % (operationTime, len(cls._typeDeterminers), len(objectDefinitions)), cls.Host.Namespace, Debug.LogLevels.Info, group=cls.Host.Namespace, owner=__name__)
def _LocalizationStringHashPatch(originalCallable: typing.Callable, self) -> int: try: return id(self) except: Debug.Log( "Failed to handle the game's '__hash__' method in a 'LocalizationString' object.", This.Mod.Namespace, Debug.LogLevels.Exception, group=This.Mod.Namespace, owner=__name__, lockIdentifier=__name__ + ":" + str(Python.GetLineNumber()), lockThreshold=2) return originalCallable(self)
def _WickedWhimsTakeBirthControlPillInteractionTestPatch( originalCallable: typing.Callable, *args, **kwargs) -> typing.Union[bool, results.TestResult]: try: return results.TestResult(False) except: Debug.Log( "Failed to handle WickedWhim's take birth control pill interaction test method.", This.Mod.Namespace, Debug.LogLevels.Exception, group=This.Mod.Namespace, owner=__name__, lockIdentifier=__name__ + ":" + str(Python.GetLineNumber())) return originalCallable(*args, **kwargs)
def _WickedWhimsDisallowBirthControlPillsAutoUseInteractionTestPatch( originalCallable: typing.Callable, *args, **kwargs) -> typing.Union[bool, results.TestResult]: try: return results.TestResult(False, tooltip=DisabledBecauseCycleInstalledToolTip. GetCallableLocalizationString()) except: Debug.Log( "Failed to handle WickedWhim's disallow birth control pills auto use interaction test method.", This.Mod.Namespace, Debug.LogLevels.Exception, group=This.Mod.Namespace, owner=__name__, lockIdentifier=__name__ + ":" + str(Python.GetLineNumber())) return originalCallable(*args, **kwargs)
def _WickedWhimsTryImpregnateSimPatch(originalCallable: typing.Callable, self, sim_actor_id, turbo_sim, *args, **kwargs) -> bool: try: Debug.Log("Here Impreg", This.Mod.Namespace, Debug.LogLevels.Warning) # TODO REMOVE # noinspection PyUnresolvedReferences from turbolib2.wrappers.sim import sim as TurboSimWrapper # noinspection PyUnresolvedReferences from wickedwhims.sex.pregnancy.birth_control import birth_control_handler inseminatedSimInfo = turbo_sim.get_sim_info( ) # type: typing.Optional[sim_info.SimInfo] if inseminatedSimInfo is None: return False for sourceSimID, spermArriving in self._get_possible_partners( sim_actor_id, turbo_sim): # type: int, bool if not spermArriving: return False sourceSimInfo = services.sim_info_manager().get( sourceSimID) # type: typing.Optional[sim_info.SimInfo] if sourceSimInfo is None: continue sourceSimWickedWhimsWrapper = TurboSimWrapper.TurboSim( sourceSimInfo) if birth_control_handler.is_sim_on_birth_control( sourceSimWickedWhimsWrapper ): # This should only really be testing if they are using condoms since we effectively disabled birth control pills continue Insemination.AutoInseminate(inseminatedSimInfo, sourceSimInfo) except: Debug.Log("Failed to handle WickedWhim's try impregnate sim method.", This.Mod.Namespace, Debug.LogLevels.Exception, group=This.Mod.Namespace, owner=__name__, lockIdentifier=__name__ + ":" + str(Python.GetLineNumber())) return originalCallable(self, sim_actor_id, turbo_sim, *args, **kwargs)
def _HasMasculineFrameTrait(self) -> bool: masculineFrameTrait = services.get_instance_manager( resources.Types.TRAIT).get(References.MasculineFrameTraitID) if masculineFrameTrait is not None: return self.TrackingSystem.SimInfo.has_trait(masculineFrameTrait) else: Debug.Log( "Could not find the masculine frame trait.\nTrait ID: %s" % References.MasculineFrameTraitID, This.Mod.Namespace, Debug.LogLevels.Error, group=This.Mod.Namespace, owner=__name__, lockIdentifier=__name__ + ":" + str(Python.GetLineNumber()), lockThreshold=1) return False
def _NotifyHandlerRemoved( self, removedHandler: HandlersBase.HandlerBase) -> None: eventArguments = CycleEvents.HandlerRemovedArguments( removedHandler) # type: CycleEvents.HandlerRemovedArguments for handlerRemovedCallback in self.HandlerRemovedEvent: try: handlerRemovedCallback(self, eventArguments) except: Debug.Log("Failed to call handler removed callback '" + Types.GetFullName(handlerRemovedCallback) + "'.\n" + self.TrackingSystem.DebugInformation, This.Mod.Namespace, Debug.LogLevels.Exception, group=This.Mod.Namespace, owner=__name__, lockIdentifier=__name__ + ":" + str(Python.GetLineNumber()), lockReference=handlerRemovedCallback)
def GetOvumReleaseAmount(self) -> int: ovumReleaseAmountString = self.OvumReleaseAmountProbability.ChooseOption( seed=self.Seed + self.OvumReleaseAmountSeed).Identifier # type: str try: ovumReleaseAmount = int(ovumReleaseAmountString) # type: int except ValueError: Debug.Log("Failed to parse %s to a valid ovum count (an int)." % ovumReleaseAmountString, This.Mod.Namespace, Debug.LogLevels.Error, group=This.Mod.Namespace, owner=__name__, lockIdentifier=__name__ + ":" + str(Python.GetLineNumber())) ovumReleaseAmount = 1 return ovumReleaseAmount
def _GetCurrentBellyModifierValue(self) -> float: hasFeminineFrameTrait = self._HasFeminineFrameTrait() # type: bool hasMasculineFrameTrait = self._HasMasculineFrameTrait() # type: bool if hasFeminineFrameTrait or (not hasFeminineFrameTrait and not hasMasculineFrameTrait and self.TrackingSystem.SimInfo.gender == sim_info_types.Gender.FEMALE): appropriatePositiveModifierKey = References.FemaleBellyPositiveModifierKey # type: int appropriateNegativeModifierKey = References.FemaleBellyNegativeModifierKey # type: int elif hasMasculineFrameTrait or (not hasFeminineFrameTrait and not hasMasculineFrameTrait and self.TrackingSystem.SimInfo.gender == sim_info_types.Gender.MALE): appropriatePositiveModifierKey = References.MaleBellyPositiveModifierKey # type: int appropriateNegativeModifierKey = References.MaleBellyNegativeModifierKey # type: int else: Debug.Log( "Could not determine the frame type or gender of a system's sim.\n" + self.DebugInformation, This.Mod.Namespace, Debug.LogLevels.Error, group=This.Mod.Namespace, owner=__name__, lockIdentifier=__name__ + ":" + str(Python.GetLineNumber())) return 0 simAttributes = PersistenceBlobs_pb2.BlobSimFacialCustomizationData( ) # type: typing.Any # noinspection PyPropertyAccess simAttributes.ParseFromString( self.TrackingSystem.SimInfo.facial_attributes) for bodyModifier in simAttributes.body_modifiers: if bodyModifier.key == appropriatePositiveModifierKey: return bodyModifier.amount elif bodyModifier.key == appropriateNegativeModifierKey: return bodyModifier.amount * -1 return 0
def SimulateSystems( ticks: int, reproductiveSystems: typing.Optional[typing.Iterable[ ReproductionShared.ReproductiveSystem]] = None ) -> None: """ Simulate this many ticks in the specified reproductive systems. All out of date reproductive systems will be updated before simulating. :param ticks: The number of ticks to simulate. :type ticks: int :param reproductiveSystems: All reproductive systems that need to be simulated. If this is None the function will go through all registered reproductive systems. :type reproductiveSystems: typing.Iterable[ReproductionShared.ReproductiveSystem] | None """ if not isinstance(ticks, int): raise Exceptions.IncorrectTypeException(ticks, "ticks", (int, )) if reproductiveSystems is None: reproductiveSystems = GetAllSystems() for reproductiveSystem in reproductiveSystems: # type: ReproductionShared.ReproductiveSystem reportLockIdentifier = __name__ + ":" + str( Python.GetLineNumber()) # type: str reportLockReference = reproductiveSystem try: reproductiveSystem.Simulate(ticks) except: Debug.Log("Failed to simulate a reproductive system\n." + reproductiveSystem.DebugInformation, This.Mod.Namespace, Debug.LogLevels.Exception, group=This.Mod.Namespace, owner=__name__, lockIdentifier=reportLockIdentifier, lockReference=reportLockReference) else: Debug.Unlock(reportLockIdentifier, reportLockReference)
def GetCurrentLanguageHandler() -> typing.Optional[LanguageHandlerBase]: """ Get the game's current language's handler. This will raise an exception if the client manager does not yet exist. This will return none if the current language is not supported. """ if game_services.service_manager is None or game_services.service_manager.client_manager is None: raise Exception( "Cannot retrieve the current language as the client manager does not yet exist." ) firstClient = game_services.service_manager.client_manager.get_first_client( ) # type: client.Client if firstClient is None: raise Exception( "Tried to get the current language, but we cannot retrieve it right now." ) gameLocal = services.get_locale() # type: str gameLocalLower = gameLocal.lower() try: for languageHandler in _registeredLanguageHandlers: # type: LanguageHandlerBase if languageHandler.GameIdentifier.lower() == gameLocalLower: return languageHandler except KeyError: Debug.Log("Current language is unsupported '%s'." % gameLocal, This.Mod.Namespace, Debug.LogLevels.Warning, group=This.Mod.Namespace, owner=__name__, lockIdentifier=__name__ + ":" + str(Python.GetLineNumber()), lockThreshold=1) return None return None
def _GetPregnancyRate() -> float: reproductiveTimeMultiplier = Settings.PregnancySpeed.Get() # type: float pregnancyGuide = CycleGuides.HumanPregnancyGuide.Guide # type: CycleGuides.PregnancyGuide pregnancyTime = pregnancyGuide.PregnancyTime # type: float pregnancyGameTime = ReproductionShared.ReproductiveMinutesToGameMinutes( pregnancyTime, reproductiveTimeMultiplier) # type: float if pregnancyGameTime != 0: pregnancyRate = 100 / pregnancyGameTime # type: float else: Debug.Log( "Calculated a pregnancy game time to be 0 minutes, this is probably not intentional.", This.Mod.Namespace, Debug.LogLevels.Warning, group=This.Mod.Namespace, owner=__name__, lockIdentifier=__name__ + ":" + str(Python.GetLineNumber()), lockThreshold=1) pregnancyRate = 0 return pregnancyRate
def _CreateTokensPatch(originalCallable: typing.Callable, tokens_msg, *tokens) -> None: try: # noinspection PyProtectedMember localizationString = tokens_msg._message if localizationString.hash == 0: # TODO log tokens applied before hash? return trueStringValues = _trueLocalizationStringValues.get( localizationString, None) # type: typing.Optional[typing.Tuple[int, tuple]] if trueStringValues is not None: trueStringHash = trueStringValues[0] # type: int trueStringTokens = trueStringValues[1] + tokens # type: tuple hasTrueValues = True # type: bool else: trueStringHash = localizationString.hash # type: int trueStringTokens = tokens # type: tuple hasTrueValues = False # type: bool localizationStringText = GenderedLanguage.GetGenderedLocalizationStringText( trueStringHash) # type: typing.Optional[str] def createTrueValueCleaner( deletingLocalizationString: Localization_pb2.LocalizedString, cleanerTimer: Timer.Timer) -> typing.Callable: def trueValueCleaner() -> None: _trueLocalizationStringValues.pop(deletingLocalizationString, None) try: _trueLocalizationStringValueDeletionTimers.remove( cleanerTimer) except ValueError: pass return trueValueCleaner if localizationStringText is not None: correctedSTBLText = GenderedLanguage.CorrectGenderedSTBLText( trueStringHash, localizationStringText, trueStringTokens) if correctedSTBLText is not None: localizationString.hash = 2462885516 # The 'raw text' string. "{0.String}" while len(tokens_msg) != 0: tokens_msg.remove(tokens_msg[0]) rawTextToken = Localization_pb2.LocalizedStringToken( ) # type: Localization_pb2.LocalizedStringToken # noinspection PyUnresolvedReferences rawTextToken.type = Localization_pb2.LocalizedStringToken.RAW_TEXT rawTextToken.raw_text = correctedSTBLText tokens_msg.append(rawTextToken) _trueLocalizationStringValues[ localizationString] = trueStringHash, trueStringTokens if not hasTrueValues: trueValueDeletionTimer = Timer.Timer( _trueLocalizationStringValueDeletionInterval, lambda *args, **kwargs: None) trueValueDeletionTimer.Callback = createTrueValueCleaner( localizationString, trueValueDeletionTimer) trueValueDeletionTimer.start() _trueLocalizationStringValueDeletionTimers.append( trueValueDeletionTimer) return else: _trueLocalizationStringValues[ localizationString] = trueStringHash, trueStringTokens if not hasTrueValues: trueValueDeletionTimer = Timer.Timer( _trueLocalizationStringValueDeletionInterval, lambda *args, **kwargs: None) trueValueDeletionTimer.Callback = createTrueValueCleaner( localizationString, trueValueDeletionTimer) trueValueDeletionTimer.start() _trueLocalizationStringValueDeletionTimers.append( trueValueDeletionTimer) except: Debug.Log("Failed to handle the game's 'create tokens' function.", This.Mod.Namespace, Debug.LogLevels.Exception, group=This.Mod.Namespace, owner=__name__, lockIdentifier=__name__ + ":" + str(Python.GetLineNumber()), lockThreshold=2) return originalCallable(tokens_msg, *tokens)
def _SimulateInternal (self, simulation: ReproductionShared.Simulation, ticks: int, reproductiveTimeMultiplier: typing.Union[float, int]) -> None: ageTicks = ReproductionShared.ReproductiveMinutesToTicks(self.Age, reproductiveTimeMultiplier) # type: typing.Union[float, int] decayTick = ReproductionShared.ReproductiveMinutesToTicks(self.Lifetime, reproductiveTimeMultiplier) # type: typing.Union[float, int] decaying = False # type: bool decayed = False # type: bool if ageTicks < decayTick <= (ageTicks + ticks): decaying = True if decayTick <= (ageTicks + ticks): decayed = True if not decayed: decayingAmount = self.DecayingTicks(ticks, reproductiveTimeMultiplier) # type: int else: decayingAmount = self.SpermCount # type: int self.Age = ReproductionShared.TicksToReproductiveMinutes(ageTicks + ticks, reproductiveTimeMultiplier) self.SpermCount -= decayingAmount if decaying: if self.DecayedCallback is None: Debug.Log("Missing callback to be triggered on sperm decay.", This.Mod.Namespace, Debug.LogLevels.Warning, group = This.Mod.Namespace, owner = __name__, lockIdentifier = __name__ + ":" + str(Python.GetLineNumber())) else: self.DecayedCallback(self)
def DecayingTicks (self, ticks: int, reproductiveTimeMultiplier: typing.Union[float, int]) -> int: """ Get the amount of sperm cells that will decay within this many ticks. """ if not isinstance(ticks, (int,)): raise Exceptions.IncorrectTypeException(ticks, "ticks", (int,)) if not isinstance(reproductiveTimeMultiplier, (float, int)): raise Exceptions.IncorrectTypeException(reproductiveTimeMultiplier, "reproductiveTimeMultiplier", (float, int)) if ticks < 0: raise ValueError("The parameter 'ticks' cannot be less than 0.") if reproductiveTimeMultiplier <= 0: raise ValueError("The parameter 'reproductiveTimeMultiplier' cannot be less than or equal to 0.") if self.SpermCount == 0: return 0 if ticks == 0: return 0 currentAgeTicks = ReproductionShared.ReproductiveMinutesToTicks(self.Age, reproductiveTimeMultiplier) # type: int currentAge = ReproductionShared.TicksToReproductiveMinutes(currentAgeTicks, reproductiveTimeMultiplier) # type: typing.Union[float, int] # This is slightly faster than getting using the GetClosestPreciseReproductiveMinute function. nextAgeTicks = currentAgeTicks + ticks # type: typing.Union[float, int] nextAge = ReproductionShared.TicksToReproductiveMinutes(nextAgeTicks, reproductiveTimeMultiplier) # type: typing.Union[float, int] lifeTimeTick = ReproductionShared.ReproductiveMinutesToTicks(self.Lifetime, reproductiveTimeMultiplier) if nextAgeTicks >= lifeTimeTick: return self.SpermCount currentPercentageRemaining = 1.0 - self.LifetimeDistribution.CumulativeDistribution(currentAge) # type: typing.Union[float, int] nextPercentageRemaining = 1.0 - self.LifetimeDistribution.CumulativeDistribution(nextAge) # type: typing.Union[float, int] percentageRemainingChange = currentPercentageRemaining - nextPercentageRemaining # type: typing.Union[float, int] originalSpermCount = int(self.SpermCount / currentPercentageRemaining) # type: int decayingSpermCount = int(originalSpermCount * percentageRemainingChange) # type: int if decayingSpermCount < 0: Debug.Log("Calculated a decaying sperm count of less than zero (%s)." % decayingSpermCount, This.Mod.Namespace, Debug.LogLevels.Warning, group = This.Mod.Namespace, owner = __name__, lockIdentifier = __name__ + ":" + str(Python.GetLineNumber())) return int(originalSpermCount * percentageRemainingChange)
def Decaying (self, reproductiveMinutes: typing.Union[float, int]) -> int: """ Get the amount of sperm cells that will decay within this many reproductive minutes. This may return a slightly incorrect value if the age or the input are between two game tick. """ if not isinstance(reproductiveMinutes, (float, int)): raise Exceptions.IncorrectTypeException(reproductiveMinutes, "reproductiveMinutes", (float, int)) if reproductiveMinutes < 0: raise ValueError("The parameter 'reproductiveMinutes' cannot be less than 0.") if self.SpermCount == 0: return 0 if reproductiveMinutes == 0: return 0 currentAge = self.Age # type: float nextAge = self.Age + reproductiveMinutes # type: float if nextAge >= self.Lifetime: return self.SpermCount currentPercentageRemaining = 1.0 - self.LifetimeDistribution.CumulativeDistribution(currentAge) # type: typing.Union[float, int] nextPercentageRemaining = 1.0 - self.LifetimeDistribution.CumulativeDistribution(nextAge) # type: typing.Union[float, int] percentageRemainingChange = nextPercentageRemaining - currentPercentageRemaining # type: typing.Union[float, int] originalSpermCount = int(self.SpermCount / currentPercentageRemaining) # type: int decayingSpermCount = int(originalSpermCount * percentageRemainingChange) # type: int if decayingSpermCount < 0: Debug.Log("Calculated a decaying sperm count of less than zero (%s)." % decayingSpermCount, This.Mod.Namespace, Debug.LogLevels.Warning, group = This.Mod.Namespace, owner = __name__, lockIdentifier = __name__ + ":" + str(Python.GetLineNumber())) return int(originalSpermCount * percentageRemainingChange)