Exemplo n.º 1
0
class EmergencyFrequency(HasTunableSingletonFactory, AutoFactoryInit):
    FACTORY_TUNABLES = {
        'max_emergency_situations_per_shift':
        TunableRange(
            description=
            '\n            The maximum number of times during a shift that an emergency\n            situation can be created/started.\n            ',
            tunable_type=int,
            default=1,
            minimum=0),
        'inital_lockout_in_sim_minutes':
        TunableSimMinute(
            description=
            '\n            The time, in Sim minutes, that pass at the beginning of a shift\n            before the first check for creating/starting an emergency happens.\n            ',
            default=60),
        'cool_down_in_sim_minutes':
        TunableSimMinute(
            description=
            '\n            How often a check for whether or not to create/start an emergency\n            happens.\n            ',
            default=60),
        'percent_chance_of_emergency':
        TunablePercent(
            description=
            '\n            The percentage chance that on any given check an emergency is to\n            to be created/started.\n            ',
            default=30),
        'weighted_situations':
        TunableList(
            description=
            '\n            A weighted list of situations to be used as emergencies. When a\n            check passes to create/start an emergency, this is the list\n            of emergency situations that will be chosen from.\n            ',
            tunable=TunableTuple(situation=Situation.TunableReference(),
                                 weight=Tunable(tunable_type=int, default=1)))
    }
Exemplo n.º 2
0
 def __init__(self, default_lower=40, default_upper=60, **kwargs):
     super().__init__(
         start_delay=TunableSimMinute(
             description=
             '\n                    Delay in sim minutes before change starts.  Used if new weather is more\n                    severe than existing weather.\n                    ',
             default=1,
             minimum=0),
         start_rate=Tunable100ConvertRange(
             description=
             '\n                    Rate at which ramp up occurs.  Used if new weather is more\n                    severe than existing weather.\n                    ',
             default=3.3,
             minimum=0),
         end_delay=TunableSimMinute(
             description=
             '\n                    Delay in sim minutes before element ends.  Used if existing weather is more\n                    severe than new weather.\n                    ',
             default=1,
             minimum=0),
         end_rate=Tunable100ConvertRange(
             description=
             '\n                    Rate at which ramp doown occurs.  Used if existing weather is more\n                    severe than new weather.\n                    ',
             default=3.3,
             minimum=0),
         range=TunableInterval(
             description=
             '\n                    Range.\n                    ',
             tunable_type=Tunable100ConvertRange,
             minimum=0,
             maximum=100,
             default_lower=default_lower,
             default_upper=default_upper),
         **kwargs)
Exemplo n.º 3
0
class PeriodicLootOperation(HasTunableFactory, AutoFactoryInit):
    FACTORY_TUNABLES = {
        'periodic_loots':
        TunableList(
            description=
            '\n            A list of periodic loots to apply.\n            ',
            tunable=TunableTuple(
                initial_delay=TunableSimMinute(
                    description=
                    '\n                    Delay before the first loot.\n                    ',
                    default=15,
                    minimum=0),
                frequency_interval=TunableSimMinute(
                    description=
                    '\n                    The time between loot applications. \n                    ',
                    default=15,
                    minimum=5),
                loots_to_apply=TunableList(
                    description=
                    '\n                    The loots to apply\n                    ',
                    unique_entries=True,
                    tunable=TunableReference(
                        description=
                        '\n                        The loot to apply.\n                        ',
                        manager=services.get_instance_manager(Types.ACTION),
                        pack_safe=True))))
    }

    def __init__(self, owner, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self._owner = owner
        self._alarm_handles = []

    def start(self, *_, **__):
        for periodic_loot_data in self.periodic_loots:
            alarm_handle = alarms.add_alarm(
                self._owner,
                clock.interval_in_sim_minutes(
                    periodic_loot_data.initial_delay),
                lambda _, loots=periodic_loot_data.loots_to_apply: self.
                _apply_loots(loots),
                repeating=True,
                repeating_time_span=clock.interval_in_sim_minutes(
                    periodic_loot_data.frequency_interval))
            self._alarm_handles.append(alarm_handle)

    def stop(self, *_, **__):
        while self._alarm_handles:
            alarm_handle = self._alarm_handles.pop()
            alarms.cancel_alarm(alarm_handle)

    def _apply_loots(self, loots):
        resolver = SingleSimResolver(
            self._owner.sim_info
        ) if self._owner.is_sim else SingleActorAndObjectResolver(
            None, self._owner, self)
        for loot in loots:
            loot.apply_to_resolver(resolver)
class _TemporaryCloneState(CommonSituationState):
    FACTORY_TUNABLES = {
        'time_out':
        TunableSimMinute(
            description=
            '\n            How long the clone will last before disappearing.\n            ',
            default=60,
            minimum=15),
        'locked_args': {
            'allow_join_situation': True
        }
    }

    def on_activate(self, reader=None):
        super().on_activate(reader=reader)
        self._test_event_register(TestEvent.HouseholdChanged)

    def handle_event(self, sim_info, event, _resolver):
        if event != TestEvent.HouseholdChanged:
            return
        if not self.owner.is_sim_info_in_situation(sim_info):
            return
        if not sim_info.household.hidden:
            self.owner._self_destruct()

    def timer_expired(self):
        self._change_state(self.owner.leave_state())
Exemplo n.º 5
0
class _LeaveCafeState(CommonInteractionCompletedSituationState):
    FACTORY_TUNABLES = {
        'timeout':
        TunableSimMinute(
            description=
            '\n            The length of time before ending the situation.\n            ',
            default=60)
    }

    def __init__(self, timeout, **kwargs):
        super().__init__(**kwargs)
        self._timeout = timeout

    def on_activate(self, reader=None):
        super().on_activate(reader)
        if self._timeout is not None:
            self._create_or_load_alarm(LEAVE_TIMEOUT,
                                       self._timeout,
                                       lambda _: self.timer_expired(),
                                       should_persist=True,
                                       reader=reader)

    def _on_interaction_of_interest_complete(self, **kwargs):
        self.owner._self_destruct()

    def _additional_tests(self, sim_info, event, resolver):
        if not self.owner.sim_of_interest(sim_info):
            return False
        elif not resolver.interaction.is_finishing:
            return False
        return True

    def timer_expired(self):
        self.owner._self_destruct()
Exemplo n.º 6
0
class WaitToInfectSituationState(CommonInteractionCompletedSituationState):
    FACTORY_TUNABLES = {
        'timeout':
        TunableSimMinute(
            description=
            '\n            The amount of time to wait in this situation state before it\n            times out and we send the sims home.\n            ',
            default=10,
            minimum=1)
    }

    def __init__(self, timeout, **kwargs):
        super().__init__(**kwargs)
        self._timeout = timeout

    def on_activate(self, reader=None):
        super().on_activate(reader)
        self._create_or_load_alarm(WAIT_TO_BE_LET_IN_TIMEOUT,
                                   self._timeout,
                                   lambda _: self.timer_expired(),
                                   should_persist=True,
                                   reader=reader)

    def timer_expired(self):
        self.owner._self_destruct()

    def _on_interaction_of_interest_complete(self, **kwargs):
        self._change_state(self.owner.infect_state())
Exemplo n.º 7
0
class WeatherSetSeasonLootOp(BaseLootOperation):
    FACTORY_TUNABLES = {
        'season':
        TunableEnumEntry(
            description='\n            The target season.\n            ',
            tunable_type=SeasonType,
            default=SeasonType.WINTER),
        'interpolation_time':
        TunableSimMinute(
            description=
            '\n            The time over which the interpolation to the new season should\n            occur.\n            ',
            default=20)
    }

    def __init__(self, *args, season, interpolation_time, **kwargs):
        super().__init__(*args, **kwargs)
        self.season = season
        self.interpolation_time = interpolation_time

    def _apply_to_subject_and_target(self, subject, target, resolver):
        season_service = services.season_service()
        if season_service is not None:
            season_service.reset_region_season_params()
            season_service.set_season(self.season,
                                      SeasonSetSource.LOOT,
                                      interp_time=self.interpolation_time)
class RelationshipBitLock(metaclass=HashedTunedInstanceMetaclass,
                          manager=services.get_instance_manager(
                              sims4.resources.Types.RELATIONSHIP_LOCK)):
    INSTANCE_TUNABLES = {
        'group_id':
        TunableEnumEntry(
            description=
            '\n            The group that this lock applies to.  No two locks can belong to\n            the same group.\n            ',
            tunable_type=RelationshipBitType,
            default=RelationshipBitType.Invalid,
            invalid_enums=(RelationshipBitType.Invalid,
                           RelationshipBitType.NoGroup)),
        'timeout':
        TunableSimMinute(
            description=
            '\n            The amount of time in Sim minutes that this Relationship Bit Lock\n            will be locked before potentially allowing a Relationship Bit\n            Change.\n            ',
            default=360,
            minimum=1),
        'relock_percentage':
        TunablePercent(
            description=
            '\n            The percent chance that we will just relock this Relationship Bit\n            Lock and prevent a change when one attempts to occur.  If we are\n            relocked then we will not change the bit.\n            ',
            default=0)
    }
    relationship_bit_cache = None

    @classmethod
    def get_lock_type_for_group_id(cls, group_id):
        return cls.relationship_bit_cache.get(group_id, None)

    def __init__(self):
        self._locked_time = DATE_AND_TIME_ZERO

    @property
    def end_time(self):
        return self._locked_time + clock.interval_in_sim_minutes(self.timeout)

    def lock(self):
        self._locked_time = services.time_service().sim_now

    def unlock(self):
        self._locked_time = DATE_AND_TIME_ZERO

    def try_and_aquire_lock_permission(self):
        if self._locked_time == DATE_AND_TIME_ZERO:
            return True
        now = services.time_service().sim_now
        if now < self.end_time:
            return False
        elif sims4.random.random_chance(self.relock_percentage * 100):
            self.lock()
            return False
        return True

    def save(self, msg):
        msg.relationship_bit_lock_type = self.guid64
        msg.locked_time = self._locked_time.absolute_ticks()

    def load(self, msg):
        self._locked_time = DateAndTime(msg.locked_time)
Exemplo n.º 9
0
 def __init__(self, **kwargs):
     super().__init__(
         job_list=TunableMapping(
             description='A list of roles associated with the situation.',
             key_type=TunableReference(services.situation_job_manager(),
                                       description='Job reference'),
             value_type=TunableReference(
                 services.get_instance_manager(
                     sims4.resources.Types.ROLE_STATE),
                 description='Role the job will perform'),
             key_name='job',
             value_name='role'),
         exit_conditions=TunableList(
             TunableTuple(conditions=TunableList(
                 TunableSituationCondition(
                     description=
                     'A condition for a situation or single phase.'),
                 description=
                 'A list of conditions that all must be satisfied for the group to be considered satisfied.'
             )),
             description=
             'A list of condition groups of which if any are satisfied, the group is satisfied.'
         ),
         duration=TunableSimMinute(
             description=
             '\n                                                    How long the phase will last in sim minutes.\n                                                    0 means forever, which should be used on the last phase of the situation.\n                                                    ',
             default=60),
         **kwargs)
Exemplo n.º 10
0
class ManageCustomersState(CommonSituationState):
    FACTORY_TUNABLES = {
        'time_between_customer_checks':
        TunableSimMinute(
            description=
            '\n            Time in Sim minutes between situation checks to see if we need to add\n            more Sims to be customers.\n            ',
            default=10)
    }

    def __init__(self, *args, time_between_customer_checks=None, **kwargs):
        super().__init__(*args, **kwargs)
        self.time_between_customer_checks = time_between_customer_checks

    def on_activate(self, reader=None):
        super().on_activate(reader)
        self.number_of_situations = self.owner.number_of_expected_customers.random_int(
        )
        self._create_or_load_alarm(SITUATION_ALARM,
                                   self.time_between_customer_checks,
                                   lambda _: self._check_customers(),
                                   repeating=True,
                                   should_persist=False,
                                   reader=reader)

    def _check_customers(self):
        customer_situations = self.owner.get_customer_situations()
        if len(customer_situations) < self.number_of_situations:
            num_to_create = self.number_of_situations - len(
                customer_situations)
            for _ in range(num_to_create):
                self.owner.create_customer_situation()
Exemplo n.º 11
0
class CommonSituationState(SituationState, HasTunableFactory):
    FACTORY_TUNABLES = {
        'job_and_role_changes':
        TunableMapping(
            description=
            '\n                A mapping between situation jobs and role states that defines\n                what role states we want to switch to for sims on which jobs\n                when this situation state is entered.\n                ',
            key_type=TunableReference(
                description=
                "\n                    A reference to a SituationJob that we will use to change\n                    sim's role state.\n                    ",
                manager=services.situation_job_manager()),
            key_name='Situation Job',
            value_type=TunableReference(
                description=
                '\n                    The role state that we will switch sims of the linked job\n                    into.\n                    ',
                manager=services.get_instance_manager(
                    sims4.resources.Types.ROLE_STATE)),
            value_name='Role State'),
        'allow_join_situation':
        Tunable(
            description=
            '\n                Whether the situation is allowed to join at this state.\n                ',
            tunable_type=bool,
            default=True),
        'time_out':
        OptionalTunable(
            description=
            '\n                How long this state will last before time expired. Please talk to the GPE who implemented the specific\n                situation to see what the state will do on time expired.\n                ',
            tunable=TunableSimMinute(default=15, minimum=1))
    }

    def __init__(self, job_and_role_changes, allow_join_situation, time_out):
        super().__init__()
        self._job_and_role_changes = job_and_role_changes
        self._allow_join_situation = allow_join_situation
        self._time_out = time_out
        self._time_out_string = '' if self._time_out is None else '{}_TIMEOUT'.format(
            self.__class__.__name__)

    def on_activate(self, reader=None):
        super().on_activate(reader)
        self._set_job_role_state()
        if self._time_out is not None:
            self._create_or_load_alarm(self._time_out_string,
                                       self._time_out,
                                       lambda _: self.timer_expired(),
                                       should_persist=True)

    def _set_job_role_state(self):
        for (job, role_state) in self._job_and_role_changes.items():
            self.owner._set_job_role_state(job, role_state)

    def get_all_job_and_role_states(self):
        return self._job_and_role_changes.items()

    def allow_join_situation(self):
        return self._allow_join_situation

    def timer_expired(self):
        pass
Exemplo n.º 12
0
class TravelTuning:
    ENTER_LOT_AFFORDANCE = TunableReference(services.affordance_manager(), description='SI to push when sim enters the lot.')
    EXIT_LOT_AFFORDANCE = TunableReference(services.affordance_manager(), description='SI to push when sim is exiting the lot.')
    NPC_WAIT_TIME = TunableSimMinute(15, description='Delay in sim minutes before pushing the ENTER_LOT_AFFORDANCE on a NPC at the spawn point if they have not moved.')
    TRAVEL_AVAILABILITY_SIM_FILTER = TunableSimFilter.TunableReference(description='Sim Filter to show what Sims the player can travel with to send to Game Entry.')
    TRAVEL_SUCCESS_AUDIO_STING = TunablePlayAudio(description='\n        The sound to play when we finish loading in after the player has traveled.\n        ')
    NEW_GAME_AUDIO_STING = TunablePlayAudio(description='\n        The sound to play when we finish loading in from a new game, resume, or\n        household move in.\n        ')
    GO_HOME_INTERACTION = TunableReference(description='\n        The interaction to push a Sim to go home.\n        ', manager=services.get_instance_manager(sims4.resources.Types.INTERACTION))
Exemplo n.º 13
0
class PersistenceTuning:
    __qualname__ = 'PersistenceTuning'
    SAVE_GAME_COOLDOWN = TunableRealSecond(0, minimum=0, description='Cooldown on the save game button to prevent users from saving too often.')
    MAX_LOT_SIMULATE_ELAPSED_TIME = TunableSimMinute(description='\n        When we load a lot that was saved in the past and world time has\n        elapsed, this is the max amount of time the lot will pretend time will\n        elapse. EX: lot was saved at 8:00am sunday. The player goes to another\n        lot at that point and plays until 8:00am Tuesday. If max simulated time\n        is set to 1440 mins (24 hours), the lot will load and realize more than\n        24 hours have passed between sunday and tuesday, so the lot will start\n        off at time 8:00am Tuesday - 24 hours = 8:00am Monday. And then the lot\n        will progress for 24 hours forwards to Tuesday.\n        ', default=1440, minimum=0)
    MINUTES_STAY_ON_LOT_BEFORE_GO_HOME = TunableInterval(description="\n        For all sims, when the sim is saved NOT on their home lot, we use this\n        interval to determine how many minutes they'll stay on that lot before\n        they go home. \n\n        Then, if we load up the non-home lot past this amount of time, that sim\n        will no longer be on that lot because that sim will have gone home.\n        \n        If the we load up on the sim's home lot -- if less than this amount of\n        time has passed, we set an alarm so that the sim will spawn into their\n        home lot at the saved time. If equal or more than this amount of time\n        has passed, that sim will be spawned in at zone load.\n        \n        The amount of time is a range. When loading, we'll randomly pick between\n        the upper and lower limit of the range.\n        ", tunable_type=TunableSimMinute, default_lower=180, default_upper=240, minimum=0)
    SAVE_FAILED_REASONS = TunableTuple(description='\n        Localized strings to display when the user cannot save.\n        ', generic=TunableLocalizedString(description='\n            Generic message for why game cannot be saved at the moment\n            '), on_cooldown=TunableLocalizedString(description='\n            The message to show when save game failed due to save being on cooldown\n            '), exception_occurred=TunableLocalizedStringFactory(description='\n            The message to show when save game failed due to an exception occuring during save\n            '))
    LOAD_ERROR_REQUEST_RESTART = ui.ui_dialog.UiDialogOk.TunableFactory(description='\n        The dialog that will be triggered when exception occurred during load of zone and ask user to restart game.\n        ')
    LOAD_ERROR = ui.ui_dialog.UiDialogOk.TunableFactory(description='\n        The dialog that will be triggered when exception occurred during load of zone.\n        ')
Exemplo n.º 14
0
class RandomDisplayName(HasTunableSingletonFactory, AutoFactoryInit):
    __qualname__ = 'RandomDisplayName'
    FACTORY_TUNABLES = {
        'overrides':
        TunableList(
            description=
            '\n            A list of random strings and icons to select randomly.\n            ',
            tunable=TunableTuple(
                new_display_name=TunableLocalizedStringFactory(),
                new_pie_menu_icon=TunableResourceKey(
                    default=None,
                    resource_types=sims4.resources.CompoundTypes.IMAGE),
                new_display_tooltip=OptionalTunable(
                    description=
                    '\n                    Tooltip to show on this pie menu option.\n                    ',
                    tunable=sims4.localization.TunableLocalizedStringFactory(
                    )),
                locked_args={'new_pie_menu_category': None})),
        'timeout':
        TunableSimMinute(
            description=
            '\n            The time it will take for a new string to be generated given the\n            same set of data.\n            ',
            minimum=0,
            default=10)
    }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self._key_map = {}

    def get_display_names_gen(self):
        for override in self.overrides:
            yield override.new_display_name

    def get_display_name_and_result(self,
                                    interaction,
                                    target=DEFAULT,
                                    context=DEFAULT):
        context = interaction.context if context is DEFAULT else context
        target = interaction.target if target is DEFAULT else target
        key = (context.sim.id, 0 if target is None else target.id,
               interaction.affordance)
        random_names = getattr(context, 'random_names', dict())
        result = random_names.get(key)
        if result is not None:
            return (result, TestResult.NONE)
        now = services.time_service().sim_now
        result_and_timestamp = self._key_map.get(key)
        if result_and_timestamp is not None:
            time_delta = now - result_and_timestamp[1]
            if self.timeout > time_delta.in_minutes():
                self._key_map[key] = (result_and_timestamp[0], now)
                return (result_and_timestamp[0], TestResult.NONE)
        result = random.choice(self.overrides)
        random_names[key] = result
        setattr(context, 'random_names', random_names)
        self._key_map[key] = (result, now)
        return (result, TestResult.NONE)
Exemplo n.º 15
0
class AgingTuning:
    AGING_DATA = TunableMapping(description='\n        On a per-species level, define all age-related data.\n        ', key_type=TunableEnumEntry(description='\n            The species this aging data applies to.\n            ', tunable_type=Species, default=Species.HUMAN, invalid_enums=(Species.INVALID,), binary_type=EnumBinaryExportType.EnumUint32), value_type=AgingData.TunableFactory(), tuple_name='AgingDataMapping')
    AGING_SAVE_LOCK_TOOLTIP = TunableLocalizedStringFactory(description='\n        The tooltip to show in situations where save-lock during Age Up is\n        necessary, i.e. when babies or non-NPC Sims age up.\n        \n        This tooltip is provided one token: the Sim that is aging up.\n        ')
    AGE_SPEED_SETTING_MULTIPLIER = TunableMapping(description='\n        A mapping between age speeds and the multiplier that those speeds\n        correspond to.\n        ', key_type=TunableEnumEntry(description='\n            The age speed that will be mapped to its multiplier.\n            ', tunable_type=AgeSpeeds, default=AgeSpeeds.NORMAL), value_type=Tunable(description="\n            The multiplier by which to adjust the lifespan based on user age\n            speed settings. Setting this to 2 for 'Slow' speed will double the\n            Sim's age play time in that setting.\n            ", tunable_type=float, default=1))
    AGE_PROGRESS_UPDATE_TIME = Tunable(description='\n        The update rate, in Sim Days, of age progression in the UI.\n        ', tunable_type=float, default=0.2)
    AGE_SUPPRESSION_ALARM_TIME = TunableSimMinute(description='\n        Amount of time in sim seconds to suppress aging.\n        ', default=5, minimum=1)

    @classmethod
    def get_aging_data(cls, species):
        return cls.AGING_DATA[species]
Exemplo n.º 16
0
    class FixedTime(HasTunableSingletonFactory, AutoFactoryInit):
        FACTORY_TUNABLES = {
            'completion_time':
            TunableSimMinute(
                description=
                '\n                Number of Sim minutes it should take the specified goal\n                commodity to reach the goal value in the worst case, that is, if\n                the stat is as far from the goal value as possible.\n                ',
                default=None)
        }

        def get_maximum_running_time(self, interaction):
            return self.completion_time
Exemplo n.º 17
0
    class _EmployeeSituationState(HasTunableFactory, AutoFactoryInit,
                                  SituationState):
        FACTORY_TUNABLES = {
            'role_state':
            RoleState.TunableReference(
                description=
                '\n                The role state that is active on the employee for the duration\n                of this state.\n                '
            ),
            'timeout_min':
            TunableSimMinute(
                description=
                '\n                The minimum amount of time, in Sim minutes, the employee will be\n                in this state before moving on to a new state.\n                ',
                default=10),
            'timeout_max':
            TunableSimMinute(
                description=
                '\n                The maximum amount of time, in Sim minutes, the employee will be\n                in this state before moving on to a new state.\n                ',
                default=30),
            'push_interaction':
            TunableInteractionOfInterest(
                description=
                '\n                If an interaction of this type is run by the employee, this\n                state will activate.\n                '
            )
        }

        def __init__(self, *args, state_name=None, **kwargs):
            super().__init__(*args, **kwargs)
            self.state_name = state_name

        def on_activate(self, reader=None):
            super().on_activate(reader)
            self.owner._set_job_role_state(self.owner.employee_job,
                                           self.role_state)
            timeout = random.randint(self.timeout_min, self.timeout_max)
            self._create_or_load_alarm(self.state_name,
                                       timeout,
                                       self._timeout_expired,
                                       reader=reader)

        def _timeout_expired(self, *_, **__):
            self._change_state(self.owner._choose_next_state())
Exemplo n.º 18
0
class _ExerciseState(CommonSituationState):
    FACTORY_TUNABLES = {
        'exercise_timeout':
        OptionalTunable(
            description=
            '\n            Optional tunable for when to end the exercise state. If this is\n            enabled then the exercise state will end and will take shower\n            afterwards. If this is disabled the situation will just stay in the\n            exercise state forever.\n            ',
            tunable=TunableTuple(
                min_time=TunableSimMinute(
                    description=
                    '\n                    The length of time to wait before advancing to the\n                    take shower state.\n                    ',
                    default=60),
                max_time=TunableSimMinute(
                    description=
                    '\n                    The maximum time a visitor will spend on exercise state.\n                    ',
                    default=60)))
    }

    def __init__(self, exercise_timeout, **kwargs):
        super().__init__(**kwargs)
        self._exercise_timeout = exercise_timeout

    def on_activate(self, reader=None):
        super().on_activate(reader)
        if self._exercise_timeout is not None:
            duration = random.uniform(self._exercise_timeout.min_time,
                                      self._exercise_timeout.max_time)
            self._create_or_load_alarm(EXERCISE_TIMEOUT,
                                       duration,
                                       lambda _: self.timer_expired(),
                                       should_persist=True,
                                       reader=reader)

    def _get_remaining_time_for_gsi(self):
        return self._get_remaining_alarm_time(EXERCISE_TIMEOUT)

    def timer_expired(self):
        self.owner._change_state(self.owner.take_shower_state())
Exemplo n.º 19
0
class SituationJobChurn(HasTunableSingletonFactory, AutoFactoryInit):
    __qualname__ = 'SituationJobChurn'
    FACTORY_TUNABLES = {
        'min_duration':
        TunableSimMinute(
            description=
            '\n                Minimum amount of time a sim in this job will stay before they\n                might be churned out.\n                ',
            default=60),
        'auto_populate_by_time_of_day':
        TunableMapping(
            description=
            "\n                Each entry in the map has two columns.\n                The first column is the hour of the day (0-24) \n                that this entry begins to control the number of sims in the job.\n                The second column is the minimum and maximum desired number\n                of sims.\n                The entry with starting hour that is closest to, but before\n                the current hour will be chosen.\n                \n                Given this tuning: \n                    beginning_hour        desired_population\n                    6                     1-3\n                    10                    3-5\n                    14                    5-7\n                    20                    7-9\n                    \n                if the hour is 11, beginning_hour will be 10 and desired is 3-5.\n                if the hour is 19, beginning_hour will be 14 and desired is 5-7.\n                if the hour is 23, beginning_hour will be 20 and desired is 7-9.\n                if the hour is 2, beginning_hour will be 20 and desired is 7-9. (uses 20 tuning because it is not 6 yet)\n                \n                The entries will be automatically sorted by time on load, so you\n                don't have to put them in order (but that would be nutty)\n                ",
            key_type=Tunable(tunable_type=int, default=0),
            value_type=TunableInterval(tunable_type=int,
                                       default_lower=0,
                                       default_upper=0),
            key_name='beginning_hour',
            value_name='desired_population'),
        'chance_to_add_or_remove_sim':
        TunableRange(
            description=
            '\n                Periodically the churn system will re-evaluate the number of sims\n                currently in the job. If the number of sims is above or below\n                the range it will add/remove one sim as appropriate. \n                If the number of sims is within the tuned\n                range it will roll the dice to determine what it should do:\n                    nothing\n                    add a sim\n                    remove a sim\n                    \n                The chance tuned here (1-100) is the chance that it will do\n                something (add/remove), as opposed to nothing. \n                \n                When it is going to do something, the determination of \n                whether to add or remove is roughly 50/50 with additional\n                checks to stay within the range of desired sims and respect the\n                min duration.\n                ',
            tunable_type=int,
            default=20,
            minimum=0,
            maximum=100)
    }

    def get_auto_populate_interval(self, time_of_day=None):
        if not self.auto_populate_by_time_of_day:
            return AutoPopulateInterval(min=0, max=0)
        if time_of_day is None:
            time_of_day = services.time_service().sim_now
        auto_populate = []
        for (beginning_hour,
             interval) in self.auto_populate_by_time_of_day.items():
            auto_populate.append((beginning_hour, interval))
        auto_populate.sort(key=lambda entry: entry[0])
        hour_of_day = time_of_day.hour()
        entry = auto_populate[-1]
        interval = AutoPopulateInterval(min=entry[1].lower_bound,
                                        max=entry[1].upper_bound)
        for entry in auto_populate:
            if entry[0] <= hour_of_day:
                interval = AutoPopulateInterval(min=entry[1].lower_bound,
                                                max=entry[1].upper_bound)
            else:
                break
        return interval
Exemplo n.º 20
0
class _WeatherParamData(HasTunableFactory, AutoFactoryInit):
    FACTORY_TUNABLES = {
        'interpolation_time':
        TunableSimMinute(
            description=
            '\n            The time in sim minutes over which to transition to the new value,\n            if this occurs during simulation.\n            ',
            minimum=0.0,
            default=15.0),
        'new_value':
        Tunable(
            description=
            '\n            The value that we will set this parameter to.\n            ',
            tunable_type=float,
            default=1.0)
    }
Exemplo n.º 21
0
class TimeoutLiability(Liability, HasTunableFactory):
    LIABILITY_TOKEN = 'TimeoutLiability'
    FACTORY_TUNABLES = {
        'description':
        'Establish a timeout for this affordance. If it has not run when the timeout hits, cancel and push timeout_affordance, if set.',
        'timeout':
        TunableSimMinute(
            4,
            minimum=0,
            description=
            'The time, in Sim minutes, after which the interaction is canceled and time_toute affordance is pushed, if set.'
        ),
        'timeout_affordance':
        TunableReference(
            services.affordance_manager(),
            allow_none=True,
            description=
            'The affordance to push when the timeout expires. Can be unset, in which case the interaction will just be canceled.'
        )
    }

    def __init__(self, interaction, *, timeout, timeout_affordance, **kwargs):
        super().__init__(**kwargs)

        def on_alarm(*_, **__):
            if interaction.running:
                return
            if interaction.transition is not None and interaction.transition.running:
                return
            if timeout_affordance is not None:
                context = interaction.context.clone_for_continuation(
                    interaction)
                interaction.sim.push_super_affordance(timeout_affordance,
                                                      interaction.target,
                                                      context)
            interaction.cancel(
                FinishingType.LIABILITY,
                cancel_reason_msg='Timeout after {} sim minutes.'.format(
                    timeout))

        time_span = clock.interval_in_sim_minutes(timeout)
        self._handle = alarms.add_alarm(self, time_span, on_alarm)

    def release(self):
        alarms.cancel_alarm(self._handle)

    def should_transfer(self, continuation):
        return False
Exemplo n.º 22
0
class _OrderAndWaitForCoffeeState(CommonSituationState):
    FACTORY_TUNABLES = {
        'interaction_of_interest':
        TunableInteractionOfInterest(
            description=
            '\n             The interaction that needs to run to \n             '
        ),
        'order_coffee_timeout':
        OptionalTunable(
            description=
            "\n            Optional tunable for how long to wait before progressing to the\n            next state. This is basically here if you don't care if they order\n            coffee all of the time.\n            ",
            tunable=TunableSimMinute(
                description=
                '\n                The length of time before moving onto the next state.\n                ',
                default=60))
    }

    def __init__(self, interaction_of_interest, order_coffee_timeout,
                 **kwargs):
        super().__init__(**kwargs)
        self._interaction_of_interest = interaction_of_interest
        self._order_coffee_timeout = order_coffee_timeout

    def on_activate(self, reader=None):
        super().on_activate(reader)
        for custom_key in self._interaction_of_interest.custom_keys_gen():
            self._test_event_register(TestEvent.InteractionStart, custom_key)
        if self._order_coffee_timeout is not None:
            self._create_or_load_alarm(ORDER_COFFEE_TIMEOUT,
                                       self._order_coffee_timeout,
                                       lambda _: self.timer_expired(),
                                       should_persist=True,
                                       reader=reader)

    def handle_event(self, sim_info, event, resolver):
        if event != TestEvent.InteractionStart:
            return
        if not resolver(self._interaction_of_interest):
            return
        if not self.owner.sim_of_interest(sim_info):
            return
        self.owner._change_state(self.owner.get_post_coffee_state())

    def timer_expired(self):
        self.owner._change_state(self.owner.get_post_coffee_state())
class NarrativeEnvironmentOverride(HasTunableSingletonFactory,
                                   AutoFactoryInit):
    FACTORY_TUNABLES = {
        'supported_regions':
        OptionalTunable(
            description=
            '\n            If set, this override is only applicable in the specified regions.\n            ',
            tunable=RegionTest.TunableFactory(locked_args={
                'tooltip': None,
                'subject': None
            })),
        'weather_forecast_override':
        WeatherSetOverrideForecastLootOp.TunableFactory(
            description=
            "\n            If Seasons pack is installed, this forecast is used to override \n            the affected region's weather.\n            "
        ),
        'narrative_environment_params':
        TunableMapping(
            description=
            '\n            The various parameters to set when the narrative is enabled.\n            ',
            key_type=TunableEnumEntry(
                description=
                '\n                The parameter that we wish to change.\n                ',
                tunable_type=NarrativeEnvironmentParams,
                default=None),
            value_type=TunableTuple(
                interpolation_time=TunableSimMinute(
                    description=
                    '\n                    The time over which to transition to the new value,\n                    if this occurs during simulation.\n                    ',
                    minimum=0.0,
                    default=15.0),
                value=Tunable(
                    description=
                    '\n                    The value that we will set this parameter to.\n                    ',
                    tunable_type=float,
                    default=1.0)))
    }

    def should_apply(self):
        if self.supported_regions is not None:
            return self.supported_regions()
        return True
Exemplo n.º 24
0
 def __init__(self, description='A material state.', **kwargs):
     super().__init__(
         state_name=TunableStringOrDefault(
             'materialStateName',
             description='The name of the material state.'),
         opacity=TunableRange(
             float,
             1,
             0,
             1,
             description=
             'Opacity of the material from ( 0.0 == transparent ) to ( 1.0 == opaque ). Not yet supported on the client.'
         ),
         transition=TunableSimMinute(
             0,
             description=
             'Time to take when transitioning in sim minutes. Not yet supported on the client.'
         ),
         description=description,
         **kwargs)
Exemplo n.º 25
0
class HideWhimsLiability(Liability, HasTunableFactory, AutoFactoryInit):
    LIABILITY_TOKEN = 'HideWhimsLiability'
    FACTORY_TUNABLES = {
        '_reset_time':
        OptionalTunable(
            description=
            '\n            If enabled, when this liability is released, all non-locked whims\n            will be reset if this liability exists for longer than this time.\n            ',
            tunable=TunableSimMinute(
                description=
                '\n                The amount of time that needs to pass on liability release that\n                the whims will be reset as well as unhidden.\n                ',
                default=1,
                minimum=1))
    }

    def __init__(self, interaction, **kwargs):
        super().__init__(**kwargs)
        self._starting_time_stamp = None
        self._sim_info = interaction.sim.sim_info

    def on_run(self):
        if self._starting_time_stamp is not None:
            return
        if self._sim_info.whim_tracker is None:
            return
        self._starting_time_stamp = services.time_service().sim_now
        self._sim_info.whim_tracker.hide_whims()

    def release(self):
        if self._starting_time_stamp is None:
            return
        if self._sim_info.whim_tracker is None:
            return
        should_reset = False
        if self._reset_time is not None:
            current_time = services.time_service().sim_now
            elapsed_time = current_time - self._starting_time_stamp
            should_reset = elapsed_time > create_time_span(
                minutes=self._reset_time)
        self._sim_info.whim_tracker.show_whims(reset=should_reset)
class TimedFestivalState(BaseFestivalState):
    FACTORY_TUNABLES = {
        '_duration':
        TunableSimMinute(
            description=
            '\n            The length of time that this state will run before moving into the\n            next state.\n            ',
            minimum=1,
            default=60)
    }
    TIMEOUT_ALARM_KEY = 'state_timeout_alarm'

    def _get_next_state(self):
        raise NotImplementedError

    def _change_state(self):
        next_state = self._get_next_state()
        if next_state is not None:
            self._owner.change_state(next_state)
        else:
            self._owner.self_destruct()

    def _on_timeout_expired_callback(self, _):
        self._change_state()

    def on_state_activated(self, reader=None, preroll_time_override=None):
        super().on_state_activated(reader=reader,
                                   preroll_time_override=preroll_time_override)
        alarm_time = -preroll_time_override.in_minutes(
        ) if preroll_time_override is not None else self._duration
        self.schedule_alarm(self.TIMEOUT_ALARM_KEY,
                            alarm_time,
                            self._on_timeout_expired_callback,
                            reader=reader)

    def _get_fake_preroll_time(self):
        return create_time_span(minutes=self._duration)

    def _preroll_end_of_state(self):
        self._change_state()
Exemplo n.º 27
0
class _OrderCoffeeState(CommonInteractionCompletedSituationState):
    FACTORY_TUNABLES = {
        'order_coffee_timeout':
        OptionalTunable(
            description=
            "\n            Optional tunable for how long to wait before progressing to the\n            next state. This is basically here if you don't care if they order\n            coffee all of the time.\n            ",
            tunable=TunableSimMinute(
                description=
                '\n                The length of time before moving onto the next state.\n                ',
                default=60))
    }

    def __init__(self, order_coffee_timeout, **kwargs):
        super().__init__(**kwargs)
        self._order_coffee_timeout = order_coffee_timeout

    def on_activate(self, reader=None):
        super().on_activate(reader)
        if self._order_coffee_timeout is not None:
            self._create_or_load_alarm(ORDER_COFFEE_TIMEOUT,
                                       self._order_coffee_timeout,
                                       lambda _: self.timer_expired(),
                                       should_persist=True,
                                       reader=reader)

    def _on_interaction_of_interest_complete(self, **kwargs):
        self.owner._change_state(self.owner.get_post_coffee_state())

    def _additional_tests(self, sim_info, event, resolver):
        if not self.owner.sim_of_interest(sim_info):
            return False
        elif not resolver.interaction.is_finishing:
            return False
        return True

    def timer_expired(self):
        self.owner._change_state(self.owner.get_post_coffee_state())
class TimeElapsedZoneTest(HasTunableSingletonFactory, AutoFactoryInit,
                          event_testing.test_base.BaseTest):
    FACTORY_TUNABLES = {
        'minutes_passed':
        TunableSimMinute(
            description=
            '\n            This test will pass when the minutes passed is greater than the\n            number minutes since last loading into zone.\n            ',
            default=720,
            minimum=1)
    }

    def get_expected_args(self):
        return {}

    @event_testing.test_events.cached_test
    def __call__(self):
        elapsed_time = services.current_zone().time_elapsed_since_last_save(
        ).in_minutes()
        if elapsed_time <= self.minutes_passed:
            return event_testing.results.TestResult(
                False,
                'TimeElapsedZoneTest: elapsed time ({}) since last save at this zone is not greater than {}',
                elapsed_time, self.minutes_passed)
        return event_testing.results.TestResult.TRUE
Exemplo n.º 29
0
class _PartyTimeState(CommonSituationState):
    FACTORY_TUNABLES = {
        'timeout':
        TunableSimMinute(
            description=
            '\n                The amount of time to wait until the party switches to phase 2\n                winding down.\n                ',
            default=10,
            minimum=1)
    }

    def __init__(self, timeout, **kwargs):
        super().__init__(**kwargs)
        self._timeout = timeout

    def on_activate(self, reader=None):
        super().on_activate(reader)
        self._create_or_load_alarm(PARTY_TIME_PHASE_TIMEOUT,
                                   self._timeout,
                                   lambda _: self.timer_expired(),
                                   should_persist=True,
                                   reader=reader)

    def timer_expired(self):
        self._change_state(self.owner.wind_down_state())
Exemplo n.º 30
0
class SatisfactionPointPeriodicGainModifier(HasTunableSingletonFactory,
                                            AutoFactoryInit,
                                            BaseGameEffectModifier):
    FACTORY_TUNABLES = {
        'score_rate':
        TunableRate(
            description=
            '\n            The rate at which Sims gain Satisfaction Points.\n            ',
            rate_description=RateDescriptions.PER_SIM_MINUTE,
            tunable_type=int,
            default=1),
        'score_interval':
        TunableSimMinute(
            description=
            '\n            How often satisfaction points are awarded. Since awarding points has\n            a UI treatment, this affects visible feedback to the player.\n            ',
            default=8)
    }

    def __init__(self, **kwargs):
        super().__init__(GameEffectType.WHIM_MODIFIER, **kwargs)

    def apply_modifier(self, sim_info):
        score = int(self.score_interval * self.score_rate)

        def _on_award_satisfaction_points(_):
            sim_info.add_whim_bucks(score, SetWhimBucks.WHIM)

        alarm_handle = alarms.add_alarm(
            self,
            create_time_span(minutes=self.score_interval),
            _on_award_satisfaction_points,
            repeating=True)
        return alarm_handle

    def remove_modifier(self, sim_info, handle):
        alarms.cancel_alarm(handle)