Пример #1
0
class OwnableComponent(Component, HasTunableFactory, component_name=types.OWNABLE_COMPONENT, persistence_key=protocols.PersistenceMaster.PersistableData.OwnableComponent):
    DEFAULT_OWNABLE_COMPONENT_AFFORDANCES = TunableList(TunableReference(manager=services.get_instance_manager(sims4.resources.Types.INTERACTION)), description='Affordances that all ownable component owners have.')

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

    def update_sim_ownership(self, new_sim_id):
        self._sim_owner_id = new_sim_id

    @componentmethod_with_fallback(lambda : None)
    def get_sim_owner_id(self):
        return self._sim_owner_id

    def save(self, persistence_master_message):
        if self._sim_owner_id is None:
            return
        persistable_data = protocols.PersistenceMaster.PersistableData()
        persistable_data.type = protocols.PersistenceMaster.PersistableData.OwnableComponent
        ownable_component_data = persistable_data.Extensions[protocols.PersistableOwnableComponent.persistable_data]
        if self._sim_owner_id is not None:
            ownable_component_data.sim_owner_id = self._sim_owner_id
        persistence_master_message.data.extend([persistable_data])

    def _owning_sim_in_owning_household(self, sim_id):
        owner_household_id = self.owner.get_household_owner_id()
        if sim_id is None or owner_household_id is None:
            return False
        household = services.household_manager().get(owner_household_id)
        if household is None:
            return False
        return household.sim_in_household(sim_id)

    def _on_households_loaded_verify(self):
        if not self._owning_sim_in_owning_household(self._sim_owner_id):
            self._sim_owner_id = None
        else:
            self.owner.update_object_tooltip()

    def load(self, persistable_data):
        ownable_component_data = persistable_data.Extensions[protocols.PersistableOwnableComponent.persistable_data]
        if ownable_component_data.HasField('sim_owner_id'):
            self._sim_owner_id = ownable_component_data.sim_owner_id
            services.current_zone().register_callback(zone_types.ZoneState.HOUSEHOLDS_AND_SIM_INFOS_LOADED, self._on_households_loaded_verify)

    def component_super_affordances_gen(self, **kwargs):
        for affordance in self.DEFAULT_OWNABLE_COMPONENT_AFFORDANCES:
            yield affordance
Пример #2
0
class LoanTunables:
    DEBT_STATISTIC = TunableReference(description='\n        The statistic used to track the amount of debt this Sim has incurred.\n        ', manager=services.get_instance_manager(sims4.resources.Types.STATISTIC), class_restrictions=('Statistic',))
    DEATH_DEBT_COLLECTION_NOTIFICATION = TunableUiDialogNotificationSnippet(description='\n        The notification shown when a Sim that has unpaid debt dies.\n        ')
    POVERTY_LOOT = TunablePackSafeReference(description='\n        A loot action applied to all other members of the household if a Sim\n        with unpaid dies, and the debt amount is greater than or equal to\n        the household funds.\n        ', manager=services.get_instance_manager(sims4.resources.Types.ACTION), class_restrictions=('LootActions',))
    INTEREST_MAP = TunableMapping(description='\n        Mapping between loan type and the interest rate for that type.\n        ', key_type=TunableEnumEntry(description='\n            The type of loan taken.\n            ', tunable_type=LoanType, default=LoanType.INVALID, invalid_enums=(LoanType.INVALID,)), value_type=TunablePercent(description='\n            The interest rate for the corresponding loan type.\n            ', default=10), tuple_name='InterestMappingTuple', export_modes=ExportModes.All)

    @staticmethod
    def get_loan_amount(amount, loan_type):
        interest_rate = LoanTunables.INTEREST_MAP.get(loan_type, 0)
        amount += amount*interest_rate
        return int(amount)

    @staticmethod
    def add_debt(sim_info, amount):
        if amount == 0:
            return
        sim_info_debt_stat = sim_info.statistic_tracker.get_statistic(LoanTunables.DEBT_STATISTIC, add=True)
        sim_info_debt_stat.add_value(amount)
        LoanTunables.send_loan_op(sim_info, -amount)

    @staticmethod
    def send_loan_op(sim_info, amount):
        msg = Sims_pb2.SetLoan()
        msg.amount = amount
        op = GenericProtocolBufferOp(Operation.SET_LOAN, msg)
        Distributor.instance().add_op(sim_info, op)

    @staticmethod
    def on_death(sim_info):
        debt_stat = sim_info.statistic_tracker.get_statistic(LoanTunables.DEBT_STATISTIC)
        if debt_stat is None:
            return
        debt_amount = debt_stat.get_value()
        if debt_amount == 0:
            return
        resolver = SingleSimResolver(sim_info)
        dialog = LoanTunables.DEATH_DEBT_COLLECTION_NOTIFICATION(sim_info, resolver=resolver)
        dialog.show_dialog()
        household_funds = sim_info.household.funds.money
        if LoanTunables.POVERTY_LOOT is not None:
            if debt_amount >= household_funds:
                for hh_sim_info in sim_info.household.sim_info_gen():
                    if sim_info is hh_sim_info:
                        continue
                    resolver = DoubleSimResolver(hh_sim_info, sim_info)
                    LoanTunables.POVERTY_LOOT.apply_to_resolver(resolver)
        amount_to_remove = min(debt_amount, household_funds)
        sim_info.household.funds.try_remove_amount(amount_to_remove, Consts_pb2.TELEMETRY_LOANS_SIM_DEATH)
Пример #3
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
Пример #4
0
 def __init__(self, *args, **kwargs):
     super().__init__(
         statistic=TunableReference(
             description=
             '\n                The statistic to be changed on the object.\n                ',
             manager=services.get_instance_manager(
                 sims4.resources.Types.STATISTIC)),
         amount=TunableVariant(
             constant=ConstantAmount(),
             statistic_based=StatisticBased(),
             description=
             '\n                The amount to modify the statistic by.\n                '
         ),
         description=
         '\n                Modify the statistic value of an object.\n                '
     )
Пример #5
0
class _TestRecipeByDefinition(HasTunableSingletonFactory, AutoFactoryInit):
    FACTORY_TUNABLES = {
        'valid_recipes':
        TunableSet(description=
                   '\n            The set of recipes allowed.\n            ',
                   tunable=TunableReference(
                       manager=services.get_instance_manager(Types.RECIPE),
                       class_restrictions=('Recipe', )),
                   minlength=1)
    }

    def test_recipe(self, recipe):
        if recipe not in self.valid_recipes:
            return TestResult(
                False, f'{recipe} not in valid recipes {self.valid_recipes}')
        return TestResult.TRUE
Пример #6
0
class BroadcasterEffectLoot(_BroadcasterEffectTestedOneShot):
    FACTORY_TUNABLES = {
        'loot_list':
        TunableList(description=
                    '\n            A list of loot operations.\n            ',
                    tunable=TunableReference(
                        manager=services.get_instance_manager(
                            sims4.resources.Types.ACTION),
                        class_restrictions=('LootActions', ),
                        pack_safe=True))
    }

    def _apply_broadcaster_effect(self, broadcaster, affected_object):
        resolver = broadcaster.get_resolver(affected_object)
        for loot_action in self.loot_list:
            loot_action.apply_to_resolver(resolver)
Пример #7
0
class StandSuperInteraction(SuperInteraction):
    STAND_POSTURE_TYPE = TunableReference(
        services.posture_manager(),
        description='The Posture Type for the Stand posture.')

    @classmethod
    def _is_linked_to(cls, super_affordance):
        return cls is not super_affordance

    def get_cancel_replacement_aops_contexts_postures(
            self, can_transfer_ownership=True, carry_cancel_override=None):
        if self.target is None and self.sim.posture.posture_type == self.STAND_POSTURE_TYPE:
            return []
        return super().get_cancel_replacement_aops_contexts_postures(
            can_transfer_ownership=can_transfer_ownership,
            carry_cancel_override=carry_cancel_override)
 def __init__(self, asm_source=None):
     if asm_source is not None:
         source_query = SourceQueries.ASMActorObject
     else:
         source_query = None
     super().__init__(actor_name=Tunable(str,
                                         None,
                                         source_location=asm_source,
                                         source_query=source_query),
                      parent_name=Tunable(str,
                                          'surface',
                                          source_location=asm_source,
                                          source_query=source_query),
                      slot_type=TunableReference(
                          services.get_instance_manager(
                              sims4.resources.Types.SLOT_TYPE)))
Пример #9
0
class GameElementJoin(ParentElement, HasTunableFactory, AutoFactoryInit):
    FACTORY_TUNABLES = {
        'game_type':
        GameRules.TunableReference(
            description=
            '\n            The game to create or join.\n            '),
        'game_affordances':
        TunableList(
            description=
            '\n            Any affordance in this list, when pushed as a continuation of this\n            interaction, will preserve the game, as if the Sim never left it.\n            ',
            tunable=TunableReference(
                description=
                '\n                An affordance that, when pushed as a continuation of this\n                interaction, preserves the game.\n                ',
                manager=services.get_instance_manager(
                    sims4.resources.Types.INTERACTION),
                class_restrictions='SuperInteraction')),
        'ensure_setup':
        Tunable(
            description=
            '\n            If checked, ensure that the game is properly set up on join.\n            ',
            tunable_type=bool,
            default=False)
    }

    def __init__(self, interaction, *args, sequence=(), **kwargs):
        super().__init__(*args, **kwargs)
        self.interaction = interaction
        self.sequence = sequence

    @classmethod
    def on_affordance_loaded_callback(cls,
                                      affordance,
                                      game_join_element,
                                      object_tuning_id=DEFAULT):
        affordance.add_additional_basic_liability(
            lambda *args, **kwargs: GameTransitionLiability(
                *args, game_type=game_join_element.game_type, **kwargs))

    def _begin_game(self, _):
        self.interaction.add_liability(
            _GameElementJoinLiability.LIABILITY_TOKEN,
            _GameElementJoinLiability(self))
        return True

    def _run(self, timeline):
        child_element = build_element((self._begin_game, self.sequence))
        return timeline.run_child(child_element)
 def __init__(self,
              target_default=ParticipantType.Object,
              carry_target_default=ParticipantType.Object,
              locked_args=None,
              class_restrictions=(),
              **kwargs):
     super().__init__(tunable=TunableTuple(
         description=
         '\n                Tunables related to a specific affordance we are providing,\n                with the ability to override specifics about targets,\n                restrictions, and dependencies.\n                ',
         affordance=TunableReference(
             description=
             '\n                    An affordance we make available. Pay attention to who this\n                    affordance is provided on. See the provided affordances\n                    description for more info.\n                    ',
             manager=services.get_instance_manager(
                 sims4.resources.Types.INTERACTION),
             class_restrictions=class_restrictions,
             pack_safe=True),
         target=TunableEnumEntry(
             description=
             '\n                    The participant the affordance will target. See the\n                    provided affordances description for more info.\n                    ',
             tunable_type=ParticipantType,
             default=target_default),
         carry_target=TunableEnumEntry(
             description=
             '\n                    The participant the affordance will set as a carry target.\n                    ',
             tunable_type=ParticipantType,
             default=carry_target_default),
         allow_self=Tunable(
             description=
             '\n                    If set, the Sim running the providing interaction is\n                    allowed to also run the provided interaction.\n                    ',
             tunable_type=bool,
             default=False),
         is_linked=Tunable(
             description=
             '\n                    When set to True if the original affordance is canceled,\n                    the provided affordance will be as well. \n                    \n                    If set to False then canceling the original affordance \n                    will not affect the provided affordance.\n                    ',
             tunable_type=bool,
             default=True),
         unlink_if_running=Tunable(
             description=
             '\n                    If checked, the provided interaction is not canceled if the\n                    interaction it depends on is canceled after the provided\n                    interaction has already started transitioning.\n                    \n                    This is useful if it is expected for the provided\n                    interaction to cancel the providing one (but we want to\n                    preserve the linked cancelation behavior in the queue.)\n                    \n                    e.g.: Sit on Toddler Bed provides Tuck In. Tuck In\n                    transitions the toddler from Sit to Relax (canceling Sit).\n                    We want the Tuck In to complete once the transition has\n                    started.\n                    ',
             tunable_type=bool,
             default=False),
         object_filter=TunableObjectFilterVariant(
             description=
             '\n                    Define the type of objects this affordance is provided on.\n                    '
         ),
         locked_args=locked_args if locked_args is not None else {}),
                      **kwargs)
Пример #11
0
class _loot_only(_dialog_and_loot):
    FACTORY_TUNABLES = {
        'on_drama_node_run_loot':
        TunableList(
            description=
            '\n            A list of loot operations to apply when the drama node runs.\n            ',
            tunable=TunableReference(manager=services.get_instance_manager(
                sims4.resources.Types.ACTION),
                                     class_restrictions=('LootActions',
                                                         'RandomWeightedLoot'),
                                     pack_safe=True))
    }

    def on_node_run(self, drama_node):
        resolver = drama_node._get_resolver()
        for loot_action in self.on_drama_node_run_loot:
            loot_action.apply_to_resolver(resolver)
class NPCHostedSituationEntry(ScheduleEntry):
    __qualname__ = 'NPCHostedSituationEntry'
    FACTORY_TUNABLES = {'possible_situations': TunableList(TunableTuple(situation=TunableReference(description='\n                        The situation that will attempted to be run by the NPC.\n                        ', manager=services.get_instance_manager(sims4.resources.Types.SITUATION)), weight=Tunable(description='\n                        The weight that this situation will be chosen.\n                        ', tunable_type=float, default=1.0)))}

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self._possible_situations = []
        for possible_situation in self.possible_situations:
            if possible_situation.situation.NPC_hosted_situation_player_job is None:
                logger.error('Situation: {} tuned in schedule entry without NPC_hosted_situation_player_job tuned.', possible_situation.situation)
            if possible_situation.situation.NPC_hosted_situation_player_job not in possible_situation.situation.get_tuned_jobs():
                logger.error('NPC_hosted_situation_player_job: {} tuned in Situation: {} that is not a possible job for that situation.', possible_situation.situation.NPC_hosted_situation_player_job, possible_situation.situation)
            self._possible_situations.append((possible_situation.weight, possible_situation.situation))
        self.duration = 0

    def select_situation(self):
        return sims4.random.weighted_random_item(self._possible_situations)
Пример #13
0
class ScheduleDramaNodeLoot(BaseLootOperation):
    FACTORY_TUNABLES = {
        'drama_node':
        TunableReference(
            description=
            '\n            The drama node to schedule.\n            ',
            manager=services.get_instance_manager(
                sims4.resources.Types.DRAMA_NODE))
    }

    def __init__(self, drama_node, **kwargs):
        super().__init__(**kwargs)
        self._drama_node = drama_node

    def _apply_to_subject_and_target(self, subject, target, resolver):
        services.drama_scheduler_service().schedule_node(
            self._drama_node, resolver)
Пример #14
0
class RestaurantCourseItemCountTest(HasTunableSingletonFactory,
                                    AutoFactoryInit, test_base.BaseTest):
    FACTORY_TUNABLES = {
        'course':
        TunableEnumWithFilter(
            description=
            '\n            The course to check for this test.\n            ',
            tunable_type=Tag,
            filter_prefixes=['recipe_course'],
            default=Tag.INVALID,
            invalid_enums=(Tag.INVALID, ),
            pack_safe=True),
        'threshold':
        TunableThreshold(
            description=
            '\n            The number of items that should available in this course.\n            '
        ),
        'blacklist_recipes':
        TunableList(
            description=
            '\n            The items from the course to not include in this test.\n            ',
            tunable=TunableReference(manager=services.recipe_manager(),
                                     class_restrictions=('Recipe', ),
                                     pack_safe=True))
    }

    def get_expected_args(self):
        return {}

    def __call__(self):
        zone_director = get_restaurant_zone_director()
        if zone_director is None:
            return TestResult(
                False,
                'Want to test restaurant course item count but not in a restaurant.',
                tooltip=self.tooltip)
        item_count = len([
            recipe for recipe in zone_director.get_menu_for_course(self.course)
            if recipe not in self.blacklist_recipes
        ])
        if not self.threshold.compare(item_count):
            return TestResult(False,
                              'Only {} items in {}'.format(
                                  item_count, self.course),
                              tooltip=self.tooltip)
        return TestResult.TRUE
Пример #15
0
 def __init__(self, **kwargs):
     super().__init__(
         collection_id=TunableEnumEntry(
             description=
             '\n                            Unique Id for this collectible, cannot be re-used.\n                            ',
             tunable_type=CollectionIdentifier,
             default=CollectionIdentifier.Unindentified,
             export_modes=ExportModes.All),
         collection_name=TunableLocalizedString(
             description=
             '\n                            Localization String For the name of the \n                            collection.  This will be read on the collection\n                            UI to separate each item group.\n                            ',
             export_modes=ExportModes.All),
         completed_award=TunableReference(
             description=
             '\n                            Object award when the collection is completed.  \n                            This is an object that will be awarded to the Sim\n                            when all the items inside a collection have been \n                            discovered.\n                            ',
             manager=services.definition_manager(),
             export_modes=ExportModes.All),
         completed_award_money=TunableRange(
             description=
             '\n                            Money award when the collection is completed.  \n                            ',
             tunable_type=int,
             default=100,
             minimum=0,
             export_modes=ExportModes.All),
         completed_award_notification=UiDialogNotification.TunableFactory(
             description=
             '\n                            Notification that will be shown when the collection\n                            is completed and the completed_award is given.\n                            '
         ),
         object_list=TunableList(
             description=
             '\n                            List of object that belong to a collectible group.\n                            ',
             tunable=CollectibleTuple.TunableFactory(),
             export_modes=ExportModes.All),
         screen_slam=OptionalTunable(
             description=
             '\n                             Screen slam to show when the collection is\n                             completed and the completed_award is given.\n                             Localization Tokens: Collection Name = {0.String}\n                             ',
             tunable=ui.screen_slam.TunableScreenSlamSnippet()),
         first_collected_notification=OptionalTunable(
             description=
             '\n                            If enabled a notification will be displayed when\n                            the first item of this collection has been found.\n                            ',
             tunable=UiDialogNotification.TunableFactory(
                 description=
                 '\n                                Notification that will be shown the first item of\n                                this collection has been found.\n                                '
             ),
             disabled_name='No_notification',
             enabled_name='Display_notification'))
Пример #16
0
class HoldObject(HoldObjectBase):
    INSTANCE_TUNABLES = {
        '_carry_posture_type':
        TunableReference(
            services.posture_manager(),
            description='The carry posture type for this version of HoldObject.'
        )
    }

    @classmethod
    def get_provided_posture_change(cls, aop):
        return postures.posture_specs.PostureOperation.PickUpObject(
            cls._carry_posture_type, aop.target)

    @classproperty
    def provided_posture_type(cls):
        return cls._carry_posture_type
Пример #17
0
class TrackCommodity(HasTunableFactory, AutoFactoryInit):
    FACTORY_TUNABLES = {
        'commodity_to_track':
        TunableReference(
            description=
            '\n            The commodity that we want to track on the Sim.\n            ',
            manager=services.get_instance_manager(
                sims4.resources.Types.STATISTIC),
            class_restrictions=('Commodity', )),
        'threshold':
        TunableThreshold(
            description=
            '\n            The threshold that we are trying to reach.\n            '
        )
    }

    def __init__(self, event_data_tracker, milestone, objective, **kwargs):
        super().__init__(**kwargs)
        self._event_data_tracker = event_data_tracker
        self._owning_milestone = milestone
        self._owning_objective = objective
        self._commodity_tracker_handle = None

    def on_threshold_reached(self, stat_type):
        self._event_data_tracker.tracker_complete(self._owning_milestone,
                                                  self._owning_objective)

    def setup(self):
        sim_info = self._event_data_tracker.owner_sim_info
        if sim_info is None:
            return False
        if self._commodity_tracker_handle is not None:
            self._commodity_tracker_handle = sim_info.commodity_tracker.create_and_add_listener(
                self.commodity_to_track, self.threshold,
                self.on_threshold_reached)
        return True

    def clear(self):
        if self._commodity_tracker_handle is not None:
            sim_info = self._event_data_tracker.owner_sim_info
            sim_info.commodity_tracker.remove_listener(
                self._commodity_tracker_handle)
        self._commodity_tracker_handle = None
        self._event_data_tracker = None
        self._owning_milestone = None
        self._owning_objective = None
class CustomStatesSituationReplaceSituation(HasTunableSingletonFactory,
                                            AutoFactoryInit):
    FACTORY_TUNABLES = {
        'new_situation':
        TunableReference(
            description=
            '\n            The new situation to be created.\n            \n            This situation will be created using the default guest list (predefined if the situation has one else an\n            empty one) and non-user facing.  If we want either Sims transferred between this situation and the next one\n            or the following situation to be user facing GPE would just need to add new tuning within this factory to\n            add the logic.\n            ',
            manager=services.get_instance_manager(Types.SITUATION))
    }

    def __call__(self, situation_state):
        situation_state.owner._self_destruct()
        guest_list = self.new_situation.get_predefined_guest_list()
        if guest_list is None:
            guest_list = SituationGuestList(invite_only=True)
        services.get_zone_situation_manager().create_situation(
            self.new_situation, guest_list=guest_list, user_facing=False)
Пример #19
0
class _StagingContentBase(HasTunableSingletonFactory, AutoFactoryInit):
	staging = True

	@TunableFactory.factory_option
	def animation_callback (callback = DEFAULT):
		return {
			'animation_ref': OptionalTunable(TunableAnimationReference(description = ' \n                A non-looping animation reference.\n                ', callback = callback, allow_none = True, reload_dependent = True))
		}

	FACTORY_TUNABLES = {
		'content_set': lambda: ContentSetWithOverrides.TunableFactory(),
		'push_affordance_on_run': OptionalTunable(TunableTuple(actor = TunableEnumEntry(description = '\n                        The participant of this interaction that is going to have\n                        the specified affordance pushed upon them.\n                        ', tunable_type = ParticipantType, default = ParticipantType.Actor), target = OptionalTunable(description = "\n                        If enabled, specify a participant to be used as the\n                        interaction's target.\n                        ", tunable = TunableEnumEntry(description = "\n                            The participant to be used as the interaction's\n                            target.\n                            ", tunable_type = ParticipantType, default = ParticipantType.Object), enabled_by_default = True),
															   carry_target = OptionalTunable(description = "\n                        If enabled, specify a participant to be used as the\n                        interaction's carry target.\n                        If disabled carry_target will be set to None.\n                        ", tunable = TunableEnumEntry(description = "\n                            The participant to be used as the interaction's\n                            carry target.\n                            ", tunable_type = ParticipantType, default = ParticipantType.Object), disabled_name = 'No_carry_target'),
															   affordance = TunableReference(description = '\n                        When this interaction is run, the tuned affordance will be\n                        pushed if possible. \n                        \n                        e.g: when Stereo dance is run, we also push the listen to\n                        music interaction\n                        ', manager = services.get_instance_manager(sims4.resources.Types.INTERACTION)), link_cancelling_to_affordance = Tunable(description = '\n                        If True, when the above tuned affordance is cancelled, This\n                        interaction will cancel too. \n                        \n                        e.g.: When sim is dancing and listening to music, if the\n                        listen to music interaction is cancelled, the dance will\n                        cancel too.\n                        ', tunable_type = bool, default = True))),
		'post_stage_autonomy_commodities': TunableList(description = '\n                An ordered list of parameterized autonomy requests to run when\n                this interaction has staged.\n                ', tunable = TunableParameterizedAutonomy()),
		'only_use_mixers_from_SI': Tunable(description = '\n                If checked then sub-action autonomy will only use mixers from\n                this SI.\n                ', tunable_type = bool, default = False)
	}
Пример #20
0
    class _ModelFromDefinition(AutoFactoryInit, HasTunableSingletonFactory):

        @staticmethod
        def _verify_tunable_callback(instance_class, tunable_name, source, value):
            if value.apply_definition:
                original_definition = services.definition_manager().find_first_definition_by_cls(instance_class)
                if original_definition is not None:
                    (result, error) = original_definition.is_similar(value.definition, ignore_rig_footprint=True)
                    if not result:
                        logger.error("<{}>'s client state model swap requires a definition change {} which is incompatible with its own definition {}.\n {}", instance_class.__name__, value.definition, original_definition, error, owner='cjiang')

        FACTORY_TUNABLES = {'definition': TunableReference(description="\n                The model's definition. \n                ", manager=services.definition_manager()), 'apply_definition': Tunable(description='\n                If set, the definition is also swapped. Otherwise, only the\n                model is swapped.\n                ', tunable_type=bool, default=False), 'verify_tunable_callback': _verify_tunable_callback}

        def get_model(self):
            if self.apply_definition:
                return self.definition
            return self.definition.get_model(index=0)
 def __init__(
         self,
         description='Join a game as part of this interaction, and leave it when the interaction finishes.',
         **kwargs):
     super().__init__(
         game=TunableReference(
             description=
             '\n                A reference to the game created when this interaction is run.\n                ',
             manager=services.get_instance_manager(
                 sims4.resources.Types.GAME_RULESET)),
         ensure_setup=Tunable(
             description=
             '\n                Tunable that, when checked, will make sure the game gets setup.\n                ',
             tunable_type=bool,
             default=False),
         description=description,
         **kwargs)
class ApplyLootToHiddenInventoryItemsLoot(BaseLootOperation):
    FACTORY_TUNABLES = {
        'loot_list':
        TunableList(description=
                    '\n            A list of loot operations.\n            ',
                    tunable=TunableReference(
                        manager=services.get_instance_manager(
                            sims4.resources.Types.ACTION),
                        class_restrictions=('LootActions', ),
                        pack_safe=True)),
        'object_tests':
        TunableTestSet(
            description=
            '\n           Tests that will run on each object, if passes loot_actions will be run\n           with that object as Object participant.\n           '
        )
    }

    @classmethod
    def _verify_tuning_callback(cls):
        if not cls.object_tests:
            logger.error('No object tests tuned for {}', cls)

    def __init__(self, *args, loot_list, object_tests, **kwargs):
        super().__init__(*args, **kwargs)
        self.loot_list = loot_list
        self.object_tests = object_tests

    def _apply_to_subject_and_target(self, subject, target, resolver):
        source_inventory = None
        if subject.is_sim:
            sim = subject.get_sim_instance()
            if sim is not None:
                source_inventory = sim.inventory_component.hidden_storage
        else:
            source_inventory = subject.inventory_component.hidden_storage
        if source_inventory is None:
            return
        for obj in list(source_inventory):
            obj_resolver = SingleActorAndObjectResolver(subject,
                                                        obj,
                                                        source=self)
            if not self.object_tests.run_tests(obj_resolver):
                continue
            for loot_action in self.loot_list:
                loot_action.apply_to_resolver(obj_resolver)
class TestBasedScoreThresholdTest(event_testing.test_base.BaseTest):
    __qualname__ = 'TestBasedScoreThresholdTest'
    FACTORY_TUNABLES = {
        'description':
        'Gate availability by a statistic on the actor or target.',
        'who':
        TunableEnumEntry(ParticipantType,
                         ParticipantType.Actor,
                         description='Who or what to apply this test to.'),
        'test_based_score':
        TunableReference(services.test_based_score_manager(),
                         description='The specific cumulative test.'),
        'threshold':
        TunableThreshold(
            description=
            "The threshold to control availability based on the statistic's value"
        )
    }

    def __init__(self, who, test_based_score, threshold, **kwargs):
        super().__init__(safe_to_skip=True, **kwargs)
        self.who = who
        self.test_based_score = test_based_score
        self.threshold = threshold

    def get_expected_args(self):
        return {'resolver': RESOLVER_PARTICIPANT}

    def __call__(self, resolver=None):
        score = self.test_based_score.get_score(resolver)
        if not self.threshold.compare(score):
            operator_symbol = Operator.from_function(
                self.threshold.comparison).symbol
            return TestResult(
                False,
                'Failed {}. Current Score: {}. Operator: {}. Threshold: {}',
                self.test_based_score.__name__,
                score,
                operator_symbol,
                self.threshold,
                tooltip=self.tooltip)
        return TestResult.TRUE

    def tuning_is_valid(self):
        return self.test_based_score is not None
Пример #24
0
 def __init__(self, description='An affordance filter.', **kwargs):
     AffordanceReference = TunableReference(
         services.get_instance_manager(sims4.resources.Types.INTERACTION))
     super().__init__(default_inclusion=TunableVariant(
         include_all=TunableTuple(
             include_all_by_default=Tunable(bool, True, description=''),
             include_affordances=TunableList(
                 AffordanceReference,
                 display_name='Filter Exception Items'),
             exclude_affordances=TunableList(
                 AffordanceReference, display_name='Blacklist Items'),
             include_lists=TunableList(
                 TunableAffordanceListReference(),
                 display_name='Filter Exception Lists'),
             exclude_lists=TunableList(TunableAffordanceListReference(),
                                       display_name='Blacklist Lists'),
             locked_args={'include_all_by_default': True},
             description=
             '\n                        This will create compatibility with all interactions by default,\n                        except those that are blacklisted, from which you can define\n                        exceptions.'
         ),
         exclude_all=TunableTuple(
             include_all_by_default=Tunable(bool, False,
                                            description=''),
             include_affordances=TunableList(
                 AffordanceReference,
                 display_name='Whitelist Items'),
             exclude_affordances=TunableList(
                 AffordanceReference,
                 display_name='Filter Exception Items'),
             include_lists=TunableList(TunableAffordanceListReference(),
                                       display_name='Whitelist Lists'),
             exclude_lists=TunableList(
                 TunableAffordanceListReference(),
                 display_name='Filter Exception Lists'),
             locked_args={'include_all_by_default': False},
             description=
             '\n                        This will create incompatibility with all interactions by\n                        default, except those that are whitelisted, from which you\n                        can define exceptions.'
         ),
         default='include_all',
         description=
         '\n                    This defines the default compatibility with other interactions.'
     ),
                      description=description,
                      needs_tuning=True,
                      **kwargs)
Пример #25
0
 def __init__(self, *args, **kwargs):
     super().__init__(
         *args,
         bg_image=TunableIcon(
             description=
             '\n                Image resource to display as UI phone panel background.\n                '
         ),
         icon=TunableIcon(
             description=
             '\n                Icon to display for phone color selector swatch.\n                '
         ),
         phone_trait=TunableReference(
             description=
             '\n                Trait associated with cell phone color.\n                ',
             allow_none=True,
             manager=services.get_instance_manager(
                 sims4.resources.Types.TRAIT)),
         **kwargs)
Пример #26
0
class TunableRewardTrait(TunableRewardBase):
    __qualname__ = 'TunableRewardTrait'
    FACTORY_TUNABLES = {'trait': TunableReference(description='\n            Give a trait as a reward\n            ', manager=services.get_instance_manager(sims4.resources.Types.TRAIT))}

    def __init__(self, *args, trait, **kwargs):
        super().__init__(*args, **kwargs)
        self._trait = trait

    def open_reward(self, sim_info, is_household):
        if is_household:
            household = sim_info.household
            for sim in household.sim_info_gen():
                sim.trait_tracker.add_trait(self._trait)
        else:
            sim_info.trait_tracker.add_trait(self._trait)

    def valid_reward(self, sim_info):
        return not sim_info.trait_tracker.is_conflicting(self._trait) and (not sim_info.trait_tracker.has_trait(self._trait) and self._trait.test_sim_info(sim_info))
Пример #27
0
class PutObjectInMail(XevtTriggeredElement, HasTunableFactory,
                      AutoFactoryInit):
    FACTORY_TUNABLES = {
        'description':
        '\n            Create an object of the specified type and place it in the hidden\n            inventory of the active lot so that it will be delivered along with\n            the mail.\n            ',
        'object_to_be_mailed':
        TunableReference(
            description=
            '\n            A reference to the type of object which will be sent to the hidden\n            inventory to be mailed.\n            ',
            manager=services.definition_manager(),
            pack_safe=True)
    }

    def _do_behavior(self):
        lot = services.active_lot()
        if lot is None:
            return
        lot.create_object_in_hidden_inventory(self.object_to_be_mailed.id)
Пример #28
0
class SicknessTuning:
    SICKNESS_BUFFS_PLAYER_FACED = TunableList(
        description=
        "\n        List of buffs that define if a sim is sick from what the player can \n        see.  The way sickness work, a sim might be sick but it may not be \n        visible to the player, so on this list we should only tune the buff's\n        that would make the sim sick on the players perspective.\n        i.e. buffs that would make a child sim take a day of school.\n        ",
        tunable=TunableReference(manager=services.buff_manager(),
                                 pack_safe=True))
    LOOT_ACTIONS_ON_CHILD_CAREER_AUTO_SICK = TunableList(
        description=
        '\n        Loot actions to test and apply on the event its time to go to work \n        and the child sim is sick.\n        i.e. notification...  \n        ',
        tunable=LootActions.TunableReference(pack_safe=True))

    @classmethod
    def is_child_sim_sick(cls, sim_info):
        if not sim_info.is_child:
            return False
        return any(
            sim_info.has_buff(buff_type)
            for buff_type in SicknessTuning.SICKNESS_BUFFS_PLAYER_FACED)
Пример #29
0
class RetailTuning:
    ADVERTISING_COMMODITY_MAP = TunableMapping(
        description=
        '\n        The mapping between advertising enum and the advertising data for\n        that type.\n        ',
        key_name='advertising_enum',
        key_type=TunableEnumEntry(
            description='\n            The Advertising Type .\n            ',
            tunable_type=BusinessAdvertisingType,
            default=BusinessAdvertisingType.INVALID,
            invalid_enums=(BusinessAdvertisingType.INVALID, )),
        value_name='advertising_commodity',
        value_type=TunableReference(
            description=
            '\n            The commodity that will be added to the lot when this\n            advertising type is chosen. This commodity is applied via\n            the Advertising Interaction. This makes it easier for design\n            to tune differences in how each business handles\n            advertising. i.e. Retail allows advertising on multiple\n            channels at the same time while restaurants only allow one\n            advertisement at a time.\n            ',
            manager=services.get_instance_manager(
                sims4.resources.Types.STATISTIC),
            class_restrictions=('Commodity', ),
            pack_safe=True))
class OpenMicPlayerControllerSituation(SituationComplexCommon):
    INSTANCE_TUNABLES = {
        'situation_state':
        PlayerSituationState.TunableFactory(locked_args={
            'time_out': None,
            'allow_join_situation': True
        }),
        'player_job':
        TunableReference(
            description=
            '\n            The job for the player Sim.\n            ',
            manager=services.get_instance_manager(
                sims4.resources.Types.SITUATION_JOB))
    }
    REMOVE_INSTANCE_TUNABLES = Situation.NON_USER_FACING_REMOVE_INSTANCE_TUNABLES

    @classmethod
    def _states(cls):
        return (SituationStateData(1,
                                   PlayerSituationState,
                                   factory=cls.situation_state), )

    @classmethod
    def _get_tuned_job_and_default_role_state_tuples(cls):
        return list(
            cls.situation_state._tuned_values.job_and_role_changes.items())

    @classmethod
    def default_job(cls):
        pass

    @classproperty
    def situation_serialization_option(cls):
        return SituationSerializationOption.DONT

    def start_situation(self):
        super().start_situation()
        self._change_state(self.situation_state())

    def _issue_requests(self):
        request = SelectableSimRequestFactory(self, _RequestUserData(),
                                              self.player_job,
                                              self.exclusivity)
        self.manager.bouncer.submit_request(request)