コード例 #1
0
class CareerStoryProgressionParameters(HasTunableSingletonFactory,
                                       AutoFactoryInit):
    FACTORY_TUNABLES = {
        'joining':
        OptionalTunable(
            description=
            '\n            If enabled, Sims will be able to join this career via Story\n            Progression.\n            ',
            tunable=TunableMultiplier.TunableFactory(
                description=
                '\n                The weight of a particular Sim joining this career versus all\n                other eligible Sims doing the same. A weight of zero prevents\n                the Sim from joining the career.\n                '
            )),
        'retiring':
        OptionalTunable(
            description=
            "\n            If enabled, Sims will be able to retire from this career via Story\n            Progression. This does not override the 'can_quit' flag on the\n            career tuning.\n            \n            Story Progression will attempt to have Sims retire before having\n            Sims quit.\n            ",
            tunable=TunableMultiplier.TunableFactory(
                description=
                '\n                The weight of a particular Sim retiring from this career versus\n                all other eligible Sims doing the same. A weight of zero\n                prevents the Sim from retiring from the career.\n                '
            )),
        'quitting':
        OptionalTunable(
            description=
            "\n            If enabled, Sims will be able to quit this career via Story\n            Progression. This does not override the 'can_quit' flag on the\n            career tuning.\n            ",
            tunable=TunableMultiplier.TunableFactory(
                description=
                '\n                The weight of a particular Sim quitting this career versus all\n                other eligible Sims doing the same. A weight of zero prevents\n                the Sim from quitting the career.\n                '
            ))
    }
コード例 #2
0
class _TextInputLengthFixed(HasTunableSingletonFactory, AutoFactoryInit):
    FACTORY_TUNABLES = {
        'min_length':
        OptionalTunable(
            description=
            "\n             If enabled, specify the minimum length of input text the player has\n             to enter before he/she can hit the 'OK' button.\n             ",
            tunable=TunableTuple(
                length=TunableRange(
                    description=
                    '\n                     Minimum amount of characters the user must enter in to the\n                     text box before he/she can click on the OK button.\n                     ',
                    tunable_type=int,
                    minimum=1,
                    default=1),
                tooltip=OptionalTunable(
                    description=
                    '\n                     If enabled, allows specification of a tooltip to display if\n                     the user has entered text length less than min_length.\n                     ',
                    tunable=TunableLocalizedStringFactory()))),
        'max_length':
        Tunable(
            description=
            '\n             Max amount of characters the user can enter into the text box.\n             ',
            tunable_type=int,
            default=20)
    }

    def build_msg(self, dialog, msg, *additional_tokens):
        msg.max_length = self.max_length
        if self.min_length is not None:
            msg.min_length = self.min_length.length
            if self.min_length.tooltip is not None:
                msg.input_too_short_tooltip = dialog._build_localized_string_msg(
                    self.min_length.tooltip, *additional_tokens)
コード例 #3
0
 def __init__(self, **kwargs):
     super().__init__(
         gender=TunableEnumEntry(
             description=
             "\n                The Sim's gender.\n                ",
             tunable_type=sim_info_types.Gender,
             needs_tuning=True,
             default=None),
         age_variant=TunableVariant(
             description=
             "\n                The sim's age for creation. Can be a literal age or random\n                between two ages.\n                ",
             literal=LiteralAge.TunableFactory(),
             random=RandomAge.TunableFactory(),
             needs_tuning=True),
         resource_key=OptionalTunable(
             description=
             '\n                If enabled, the Sim will be created using a saved SimInfo file.\n                ',
             tunable=TunableResourceKey(
                 description=
                 '\n                    The SimInfo file to use.\n                    ',
                 default=None,
                 resource_types=(sims4.resources.Types.SIMINFO, ))),
         full_name=OptionalTunable(
             description=
             "\n                If specified, then the Sim's name will be determined by this\n                localized string. Their first, last and full name will all be\n                set to this.\n                ",
             tunable=TunableLocalizedString()),
         tunable_tag_set=TunableReference(
             description=
             '\n                The set of tags that this template uses for CAS creation.\n                ',
             manager=services.get_instance_manager(
                 sims4.resources.Types.TAG_SET)),
         **kwargs)
コード例 #4
0
class ObjectRoutingBehaviorActionDestroyObjects(ObjectRoutingBehaviorAction):
    FACTORY_TUNABLES = {
        'animation_success':
        OptionalTunable(
            description=
            '\n            If enabled, the animation to play if there are objects to destroy.\n            ',
            tunable=_ObjectRoutingActionAnimation.TunableFactory()),
        'animation_failure':
        OptionalTunable(
            description=
            '\n            If enabled, the animation to play if there are no objects to destroy.\n            ',
            tunable=_ObjectRoutingActionAnimation.TunableFactory()),
        'loot_success':
        TunableList(
            description=
            '\n            For each destroyed object, apply this loot between the routing\n            object (Actor) and the destroyed object (Object).\n            ',
            tunable=LootActions.TunableReference()),
        'object_selection_method':
        TunableVariant(tags=_DestroyObjectSelectionRuleTags.TunableFactory(),
                       target_object=_DestroyObjectSelectionRuleTargetObject.
                       TunableFactory(),
                       default='tags')
    }

    def run_action_gen(self, timeline, obj, target):
        objects = self.object_selection_method.get_objects(obj, target)
        if not objects:
            if self.animation_failure is not None:
                result = yield from self.animation_failure(
                    timeline, obj, target)
                return result
                yield
            return True
            yield

        def _callback(_):
            for o in objects:
                resolver = DoubleObjectResolver(obj, o)
                for loot_action in self.loot_success:
                    loot_action.apply_to_resolver(resolver)
                o.remove_from_client(fade_duration=obj.FADE_DURATION)
                o.destroy(
                    source=self,
                    cause=
                    'Object being destroyed by ObjectRoutingBehaviorActionDestroyObjects'
                )

        if self.animation_success is not None:
            result = yield from self.animation_success(timeline,
                                                       obj,
                                                       target,
                                                       callback=_callback)
            if not result:
                return result
                yield
        else:
            _callback(timeline)
        return True
        yield
コード例 #5
0
    class _OutfitChangeForReason(OutfitChangeBase):
        FACTORY_TUNABLES = {
            'on_entry':
            OptionalTunable(
                description=
                '\n                When enabled, define the change reason to apply on posture\n                entry.\n                ',
                tunable=TunableEnumEntry(tunable_type=OutfitChangeReason,
                                         default=OutfitChangeReason.Invalid)),
            'on_exit':
            OptionalTunable(
                description=
                '\n                When enabled, define the change reason to apply on posture\n                exit.\n                ',
                tunable=TunableEnumEntry(tunable_type=OutfitChangeReason,
                                         default=OutfitChangeReason.Invalid))
        }

        def _get_outfit_resolver_and_sim_info(self,
                                              interaction,
                                              sim_info=DEFAULT):
            if sim_info is DEFAULT:
                return (None, interaction.sim.sim_info)
            return (SingleSimResolver(sim_info), sim_info)

        def has_entry_change(self, interaction, **kwargs):
            return self.on_entry is not None

        def has_exit_change(self, interaction, **kwargs):
            return self.on_exit is not None

        def get_on_entry_change(self, interaction, sim_info=DEFAULT, **kwargs):
            (resolver, sim_info) = self._get_outfit_resolver_and_sim_info(
                interaction, sim_info=sim_info)
            return sim_info.get_outfit_change(interaction,
                                              self.on_entry,
                                              resolver=resolver,
                                              **kwargs)

        def get_on_exit_change(self, interaction, sim_info=DEFAULT, **kwargs):
            (resolver, sim_info) = self._get_outfit_resolver_and_sim_info(
                interaction, sim_info=sim_info)
            return sim_info.get_outfit_change(interaction,
                                              self.on_exit,
                                              resolver=resolver,
                                              **kwargs)

        def get_on_entry_outfit(self, interaction, sim_info=DEFAULT):
            if self.on_entry is not None:
                (resolver, sim_info) = self._get_outfit_resolver_and_sim_info(
                    interaction, sim_info=sim_info)
                return sim_info.get_outfit_for_clothing_change(
                    interaction, self.on_entry, resolver=resolver)

        def get_on_exit_outfit(self, interaction, sim_info=DEFAULT):
            if self.on_exit is not None:
                (resolver, sim_info) = self._get_outfit_resolver_and_sim_info(
                    interaction, sim_info=sim_info)
                return sim_info.get_outfit_for_clothing_change(
                    interaction, self.on_exit, resolver=resolver)
コード例 #6
0
class MultiPickerInteraction(PickerSuperInteraction):
    INSTANCE_TUNABLES = {
        'picker_dialog':
        UiMultiPicker.TunableFactory(
            description=
            '\n           Tuning for the ui multi picker. \n           ',
            tuning_group=GroupNames.PICKERTUNING),
        'continuation':
        OptionalTunable(
            description=
            '\n            If enabled, you can tune a continuation to be pushed.\n            Do not use PickedObjects or PickedSims as we are not setting those\n            directly.\n            ',
            tunable=TunableContinuation(
                description=
                '\n                If specified, a continuation to push.\n                '
            ),
            tuning_group=GroupNames.PICKERTUNING),
        'success_notification':
        OptionalTunable(
            description=
            '\n            When enabled this dialog will be displayed when the multi picker\n            is accepted and has changes new information.\n            ',
            tunable=UiDialogNotification.TunableFactory(
                description=
                '\n                The notification that is displayed when a multi picker interaction\n                is accepted with new information.\n                '
            ),
            tuning_group=GroupNames.PICKERTUNING)
    }

    def _run_interaction_gen(self, timeline):
        self._show_picker_dialog(self.sim,
                                 target_sim=self.sim,
                                 target=self.target)
        return True
        yield

    @flexmethod
    def picker_rows_gen(cls, inst, target, context, **kwargs):
        return ()

    def on_choice_selected(self, choice_tag, **kwargs):
        if choice_tag:
            self._handle_successful_editing()

    def on_multi_choice_selected(self, choice_tags, **kwargs):
        if choice_tags:
            self._handle_successful_editing()

    def _push_continuation(self):
        if self.continuation is not None:
            self.push_tunable_continuation(self.continuation)

    def _handle_successful_editing(self):
        self._push_continuation()
        if self.success_notification is not None:
            resolver = self.get_resolver()
            dialog = self.success_notification(self.sim, resolver)
            dialog.show_dialog()
コード例 #7
0
ファイル: basic.py プロジェクト: NeonOcean/Environment
class _FlexibleLengthContent(_BasicContent):
	FACTORY_TUNABLES = {
		'progressive_stat_change': OptionalTunable(description = '\n            Statistic changes tuned to change a certain amount over the course\n            of an interaction.\n            ', tunable = TunableProgressiveStatisticChangeElement()),
		'periodic_stat_change': OptionalTunable(description = '\n            Statistic changes tuned to occur every specified interval.\n            ', tunable = PeriodicStatisticChangeElement.TunableFactory()),
		'statistic_reduction_by_category': OptionalTunable(description = '\n            Increase the decay of some commodities over time.\n            Useful for removing a category of buffs from a Sim.', tunable = TunableStatisticDecayByCategory()),
		'conditional_actions': TunableList(description = '\n            A list of conditional actions for this interaction. Conditional\n            actions are behavior, such as giving loot and canceling interaction,\n            that trigger based upon a condition or list of conditions, e.g. \n            time or a commodity hitting a set number.\n            \n            Example behavior that can be accomplished with this:\n            - Guarantee a Sim will play with a doll for 30 minutes.\n            - Stop the interaction when the object breaks.\n            ', tunable = TunableExitConditionSnippet(pack_safe = True)),
		'start_autonomous_inertial': Tunable(bool, True, needs_tuning = True,
											 description = '\n            Inertial interactions will run only for as long autonomy fails to\n            find another interaction that outscores it. As soon as a higher-\n            scoring interaction is found, the inertial interaction is canceled\n            and the other interaction runs.\n            \n            The opposite of inertial is guaranteed. A guaranteed interaction\n            will never be displaced by autonomy, even if there are higher\n            scoring interactions available to the Sim.\n\n            This option controls which mode the interaction starts in if\n            autonomy starts it. If started guaranteed, this interaction can be\n            set back to inertial with a conditional action.\n            \n            Please use this with care. If an interaction starts guaranteed but\n            nothing ever sets the interaction back to inertial or otherwise end\n            the interaction, this interaction will never end without direct\n            user intervention.\n            '),
		'start_user_directed_inertial': Tunable(bool, False, needs_tuning = True,
												description = '\n            Inertial interactions will run only for as long autonomy fails to\n            find another interaction that outscores it. As soon as a higher-\n            scoring interaction is found, the inertial interaction is canceled\n            and the other interaction runs.\n            \n            The opposite of inertial is guaranteed. A guaranteed interaction\n            will never be displaced by autonomy, even if there are higher\n            scoring interactions available to the Sim.\n\n            This option controls which mode the interaction starts in if the\n            user starts it. If started guaranteed, this interaction can be\n            set back to inertial with a conditional action.\n            \n            Please use this with care. If an interaction starts guaranteed but\n            nothing ever sets the interaction back to inertial or otherwise end\n            the interaction, this interaction will never end without direct\n            user intervention.\n            ')
	}
コード例 #8
0
class BusinessSettingTest(HasTunableSingletonFactory, AutoFactoryInit,
                          test_base.BaseTest):
    FACTORY_TUNABLES = {
        'quality_setting':
        OptionalTunable(
            description=
            '\n            A test to see if the current business has certain settings set by the owner.\n            ',
            tunable=TunableWhiteBlackList(
                description=
                '\n                Use of this white/black list will check whether or not the \n                current on-lot business is set to certain quality settings.\n                ',
                tunable=TunableEnumEntry(
                    description=
                    '\n                    Business Quality Type from business settings.\n                    ',
                    tunable_type=BusinessQualityType,
                    default=BusinessQualityType.INVALID,
                    invalid_enums=(BusinessQualityType.INVALID, ))),
            disabled_name='ignore',
            enabled_name='test'),
        'star_rating':
        OptionalTunable(
            description=
            '\n            A test to see if the current business is within a star rating range.\n            ',
            tunable=TunableInterval(
                description=
                "\n                If the business's star rating is within this range, this test passes.\n                ",
                tunable_type=float,
                default_lower=0,
                default_upper=5,
                minimum=0),
            disabled_name='ignore',
            enabled_name='test')
    }

    def get_expected_args(self):
        return {}

    def __call__(self):
        business_manager = services.business_service(
        ).get_business_manager_for_zone()
        if business_manager is None:
            return TestResult(False, 'Not currently on a business lot.')
        if self.quality_setting is not None and not self.quality_setting.test_item(
                business_manager.quality_setting):
            return TestResult(
                False, 'Business is set to {}'.format(
                    business_manager.quality_setting))
        if self.star_rating is not None:
            business_star_rating = business_manager.get_star_rating()
            if business_star_rating not in self.star_rating:
                return TestResult(
                    False,
                    'Business star rating is {}'.format(business_star_rating))
        return TestResult.TRUE
コード例 #9
0
class SituationMeterData(HasTunableSingletonFactory, AutoFactoryInit):
    FACTORY_TUNABLES = {
        '_meter_id':
        Tunable(
            description=
            '\n            Meter ID used by UI to differentiate meters from each other\n            (when multiple meters exist in a situation).\n            \n            This will typically be assigned by a GPE in code as opposed to tuned.\n            ',
            tunable_type=bool,
            default=True),
        '_threshold_data':
        TunableList(
            description=
            '\n            List of thresholds for this meter.\n            ',
            tunable=TunableTuple(
                color=TunableColorSnippet(
                    description=
                    '\n                    Color of meter at this specified threshold.\n                    \n                    Note: alpha value is not used.\n                    '
                ),
                threshold_value=Tunable(
                    description=
                    '\n                    Value at or above which this threshold exists. \n                    ',
                    tunable_type=int,
                    default=0))),
        '_display_text':
        OptionalTunable(
            description=
            '\n            Optional meter display text.\n            ',
            tunable=TunableLocalizedString()),
        '_tooltip':
        OptionalTunable(
            description='\n            Optional tooltip text.\n            ',
            tunable=TunableLocalizedString())
    }

    def build_data_message(self, msg):
        msg.meter_id = self._meter_id
        display_text = self._display_text
        if display_text is not None:
            msg.meter_text = display_text
        tooltip = self._tooltip
        if tooltip is not None:
            msg.meter_tooltip = tooltip
        self._build_meter_threshold_data(msg.thresholds)

    def _build_meter_threshold_data(self, msg):
        for threshold in self._threshold_data:
            with ProtocolBufferRollback(msg) as threshold_msg:
                threshold_msg.color = threshold.color
                threshold_msg.threshold = threshold.threshold_value

    def create_meter(self, situation):
        return SituationMeter(situation, self._meter_id)
コード例 #10
0
class HouseholdMilestone(Milestone,
                         metaclass=HashedTunedInstanceMetaclass,
                         manager=services.get_instance_manager(
                             sims4.resources.Types.HOUSEHOLD_MILESTONE)):
    INSTANCE_TUNABLES = {
        'notification':
        OptionalTunable(
            description=
            '\n            If enabled then we will display a notification when this milestone\n            is completed.\n            ',
            tunable=UiDialogNotification.TunableFactory(
                description=
                '\n                This text will display in a notification pop up when completed.\n                '
            ))
    }

    @classmethod
    def handle_event(cls, sim_info, event, resolver):
        if sim_info is None:
            return
        if sim_info.household is None:
            logger.error(
                "Household doesn't exist for milestone {} and SimInfo {}",
                cls,
                sim_info,
                owner='camilogarcia')
            return
        household_milestone_tracker = sim_info.household.household_milestone_tracker
        if household_milestone_tracker is None:
            return
        household_milestone_tracker.handle_event(cls, event, resolver)

    @classmethod
    def register_callbacks(cls):
        tests = [objective.objective_test for objective in cls.objectives]
        services.get_event_manager().register_tests(cls, tests)
コード例 #11
0
 def __init__(self,
              target_default=ParticipantType.Object,
              locked_args={},
              carry_target_default=ParticipantType.Object,
              **kwargs):
     super().__init__(
         TunableTuple(
             affordance=TunableReference(
                 services.affordance_manager(),
                 description=
                 'The affordance to push as a continuation on the actor for this SI.'
             ),
             si_affordance_override=TunableReference(
                 services.affordance_manager(),
                 description=
                 "When the tuned affordance is a mixer for a different SI, use this to specify the mixer's appropriate SI. This is useful for pushing socials."
             ),
             actor=TunableEnumEntry(
                 ParticipantType,
                 ParticipantType.Actor,
                 description='The Sim on which the affordance is pushed.'),
             target=TunableEnumEntry(
                 ParticipantType,
                 target_default,
                 description='The participant the affordance will target.'),
             carry_target=OptionalTunable(
                 TunableEnumEntry(
                     ParticipantType,
                     carry_target_default,
                     description=
                     'The participant the affordance will set as a carry target.'
                 )),
             locked_args=locked_args), **kwargs)
コード例 #12
0
    class _PropShareKeyParameter(HasTunableSingletonFactory, AutoFactoryInit):
        FACTORY_TUNABLES = {
            'actor_name':
            OptionalTunable(
                description=
                "\n                The actor for which this parameter's value is to be used.\n                ",
                tunable=Tunable(
                    description=
                    '\n                    The actor name.\n                    ',
                    tunable_type=str,
                    default='x'),
                enabled_name='Specified',
                disabled_name='Global'),
            'parameter_name':
            Tunable(
                description=
                '\n                The parameter whose value is to be used.\n                ',
                tunable_type=str,
                default=None)
        }

        def get_resolved_key(self, asm):
            for (key, param_value) in itertools.chain.from_iterable(
                    d.items() for d in asm.get_all_parameters()):
                if not isinstance(key, str):
                    if key[1] != self.actor_name:
                        continue
                    key = key[0]
                if key != self.parameter_name:
                    continue
                return param_value
コード例 #13
0
class _ArrivingState(CommonInteractionCompletedSituationState, AnchoredAutonomySituationStateMixin):
    FACTORY_TUNABLES = {'arrival_timeout': OptionalTunable(description="\n            Optional tunable for how long to wait before progressing to the\n            Do Stuff state. This is basically here for if you don't care\n            if they do the arriving behavior all of the time.\n            ", tunable=TunableSimMinute(description='\n                The length of time before moving onto the Do Stuff state.\n                ', default=60))}

    def __init__(self, arrival_timeout, **kwargs):
        super().__init__(**kwargs)
        self._arrival_timeout = arrival_timeout
        self._arrived_sims = []

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

    def _on_interaction_of_interest_complete(self, **kwargs):
        self._arrived_sims.clear()
        self.owner._change_state(self.owner.do_stuff_situation_state())

    def _additional_tests(self, sim_info, event, resolver):
        if not self.owner.sim_of_interest(sim_info):
            return False
        if not resolver.interaction.is_finishing_naturally:
            return False
        else:
            self._arrived_sims.append(sim_info)
            if not self.owner.all_sims_of_interest_arrived(self._arrived_sims):
                return False
        return True

    def timer_expired(self):
        self.owner._change_state(self.owner.do_stuff_situation_state())

    def should_anchor_new_arrival(self):
        return True
コード例 #14
0
class GoToSpecificLotTravelInteraction(TravelInteraction):
    __qualname__ = 'GoToSpecificLotTravelInteraction'
    INSTANCE_TUNABLES = {
        'destination_lot':
        OptionalTunable(
            description=
            "\n            If enabled, tune a specific lot description to be the destination\n            of the interaction.  Otherwise, the interaction will assume the\n            destination lot is the Sim's home lot.\n            ",
            tunable=TunableLotDescription(
                description=
                '\n                The lot description of the destination lot.\n                '
            ))
    }

    def __init__(self, aop, context, **kwargs):
        if self.destination_lot is None:
            zone_id = context.sim.household.home_zone_id
        else:
            lot_id = get_lot_id_from_instance_id(self.destination_lot)
            zone_id = services.get_persistence_service(
            ).resolve_lot_id_into_zone_id(lot_id, ignore_neighborhood_id=True)
        super().__init__(aop,
                         context,
                         from_zone_id=context.sim.zone_id,
                         to_zone_id=zone_id,
                         on_complete_callback=None,
                         on_complete_context=None,
                         **kwargs)

    def _run_interaction_gen(self, timeline):
        travel_info = InteractionOps_pb2.TravelSimsToZone()
        travel_info.zone_id = self.to_zone_id
        travel_info.sim_ids.append(self.sim.id)
        distributor.system.Distributor.instance().add_event(
            Consts_pb2.MSG_TRAVEL_SIMS_TO_ZONE, travel_info)
        services.game_clock_service().set_clock_speed(ClockSpeedMode.PAUSED)
コード例 #15
0
class PackSpecificTuning:
    VENUE_PACK_TUNING = TunableMapping(
        description=
        "\n        Venue tuning that is needed by UI when that venue's pack is not installed.\n        ",
        key_name='venue_id',
        key_type=TunableReference(
            description=
            '\n            Reference to the venue that this data represents\n            ',
            manager=services.get_instance_manager(sims4.resources.Types.VENUE),
            pack_safe=True),
        value_name='data',
        value_type=TunableTuple(
            description=
            "\n            Venue data that is shown in the UI when this venue's pack is not installed.\n            ",
            gallery_download_venue=OptionalTunable(
                description=
                '\n                If tuned, the tuned venue tuning will be substituted if this\n                venue is downloaded from the gallery by a player who is not\n                entitled to it. The default behavior is to substitute the\n                generic venue. This tuned venue will also determine download\n                compatibility (for instance, only residential venues can be \n                downloaded to owned residential venues).\n                ',
                tunable=TunableReference(manager=services.get_instance_manager(
                    sims4.resources.Types.VENUE))),
            venue_name=TunableLocalizedStringFactory(
                description=
                '\n                Name that will be displayed for the venue when the pack containing \n                that venue is not installed\n                '
            ),
            venue_flags=TunableEnumFlags(
                description=
                '\n                Venue flags used to mark a venue with specific properties.\n                ',
                enum_type=VenueFlags,
                allow_no_flags=True,
                default=VenueFlags.NONE),
            export_class_name='VenueDataTuple'),
        tuple_name='VenuePackTuning',
        export_modes=ExportModes.All,
        verify_tunable_callback=verify_venue_tuning)
コード例 #16
0
class _BroadcasterEffectTested(_BroadcasterEffect):
    FACTORY_TUNABLES = {
        'tests':
        TunableTestSet(
            description=
            '\n            Tests that must pass in order for the broadcaster effect to be\n            applied.\n            '
        ),
        'excluded_participants':
        OptionalTunable(
            description=
            '\n            If enabled, these participants will be excluded from this broadcaster effect.\n            ',
            tunable=TunableEnumFlags(
                description=
                '\n                A set of Participants that will be excluded from having this effect\n                applied to them. If the broadcaster comes from an interaction,\n                these participants will come from that interaction.\n                ',
                enum_type=ParticipantType,
                default=ParticipantType.Actor | ParticipantType.TargetSim))
    }

    def _should_apply_broadcaster_effect(self, broadcaster, affected_object):
        if broadcaster.interaction is not None and self.excluded_participants is not None:
            participants = broadcaster.interaction.get_participants(
                self.excluded_participants)
            if affected_object in participants:
                return False
            if affected_object.sim_info is not None and affected_object.sim_info in participants:
                return False
        resolver = broadcaster.get_resolver(affected_object)
        if not self.tests.run_tests(resolver):
            return False
        return super()._should_apply_broadcaster_effect(
            broadcaster, affected_object)
コード例 #17
0
    class _DirectionalGoalMixin:
        FACTORY_TUNABLES = {
            'limit_direction':
            OptionalTunable(
                TunableTuple(description='\n                ',
                             direction=TunableOperator(
                                 tunable_type=InequalityOperator,
                                 default=Operator.LESS_OR_EQUAL),
                             tooltip=event_testing.test_base.BaseTest.
                             FACTORY_TUNABLES['tooltip']))
        }

        def get_threshold_value(self, stat):
            return self.get_goal_value()

        def get_additional_tests_gen(self, subject):
            yield from super().get_additional_tests_gen(subject)
            if self.limit_direction is not None:
                threshold = sims4.math.Threshold(
                    self.get_threshold_value(), self.limit_direction.direction)
                test = StatThresholdTest(tooltip=self.limit_direction.tooltip,
                                         who=subject,
                                         stat=self.stat,
                                         threshold=threshold)
                yield test
コード例 #18
0
ファイル: primitive.py プロジェクト: NeonOcean/Environment
 def __init__(self, **kwargs):
     super().__init__(
         audio=TunableResourceKey(
             description=
             '\n                The sound to play.\n                ',
             default=None,
             resource_types=(sims4.resources.Types.PROPX, )),
         joint_name_hash=OptionalTunable(
             description=
             "\n                Specify if the audio is attached to a slot and, if so, which\n                slot. Otherwise the audio will be attached to the object's \n                origin.\n                ",
             tunable=TunableStringHash32(
                 description=
                 '\n                    The name of the slot this audio is attached to.\n                    '
             )),
         play_on_active_sim_only=Tunable(
             description=
             '\n                If enabled, and audio target is Sim, the audio will only be \n                played on selected Sim. Otherwise it will be played regardless \n                Sim is selected or not.\n                \n                If audio target is Object, always set this to False. Otherwise\n                the audio will never be played.\n                \n                ex. This will be useful for Earbuds where we want to hear the\n                music only when the Sim is selected.\n                ',
             tunable_type=bool,
             default=False),
         immediate_audio=Tunable(
             description=
             '\n                If checked, this audio will be triggered immediately, nothing\n                will block.\n                \n                ex. Earbuds audio will be played immediately while \n                the Sim is routing or animating.\n                ',
             tunable_type=bool,
             default=False),
         **kwargs)
コード例 #19
0
class SlotObjectsFromInventory(XevtTriggeredElement, HasTunableFactory,
                               AutoFactoryInit):
    FACTORY_TUNABLES = {
        'description':
        '\n            Transfer particpant objects into the target object available slots\n            of the tuned slot type. \n            ',
        'slot_strategy':
        SlotStrategyVariant(
            description=
            '\n            The slot strategy we want to use to place objects from the transfer\n            source into slots on the target.\n            '
        ),
        'slot_failure_notification':
        OptionalTunable(
            description=
            '\n            If enabled, we will show a notification to the player when this\n            element runs and no objects are successfully slotted.\n            ',
            tunable=TunableUiDialogNotificationSnippet(
                description=
                '\n                Notification to show if we fail to slot any objects.\n                '
            ))
    }

    def _do_behavior(self):
        slot_strategy = self.slot_strategy(self.interaction.get_resolver())
        if not slot_strategy.slot_objects(
        ) and self.slot_failure_notification is not None:
            dialog = self.slot_failure_notification(
                self.interaction.sim, resolver=self.interaction.get_resolver())
            dialog.show_dialog()
        return True
コード例 #20
0
    class _ByParticipantType(HasTunableSingletonFactory, AutoFactoryInit):
        FACTORY_TUNABLES = {'course': OptionalTunable(description='\n                If enabled, the target Sim must be the professor of the\n                specified course. If not enabled the professor can be professor\n                of any course.\n                ', tunable=TunableTuple(description='\n                    A pair of participant type and student to use for your checks.\n                    Since you need some reference as to whos class and what\n                    university we have to specify the student.\n                    ', course_participant=TunableEnumEntry(description='\n                        The participant type to find the course specification in.\n                        ', tunable_type=ParticipantType, default=ParticipantType.PickedItemId), student=TunableEnumEntry(description='\n                        The participant type to find the student in.\n                        ', tunable_type=ParticipantTypeActorTargetSim, default=ParticipantTypeActorTargetSim.Actor)))}

        def get_expected_args(self):
            if self.course is not None:
                return {'course': self.course.course_participant, 'students': self.course.student}
            return {}

        def __call__(self, targets, students, course, tooltip):
            for target in targets:
                if course:
                    career_manager = services.get_instance_manager(sims4.resources.Types.CAREER)
                    career = career_manager.get(course[0])
                    if career is None:
                        return TestResult(False, "Didn't choose a valid career slot to look for the course in.", tooltip=tooltip)
                    for student in students:
                        degree_tracker = student.degree_tracker
                        if degree_tracker is None:
                            return TestResult(False, '{} does not have a degree tracker.', student, tooltip=tooltip)
                        course_data = degree_tracker.get_course_data(career.guid64)
                        if course_data is None:
                            return TestResult(False, "Career Slot being checked against isn't actually an active slot for an enrolled course.", tooltip=tooltip)
                        student_university = degree_tracker.get_university()
                        professor_trait = course_data.professor_assignment_trait[student_university]
                        if not target.has_trait(professor_trait):
                            return TestResult(False, '{} is not the professor for {} in slot {}', target, course_data, career, tooltip=tooltip)
                    else:
                        traits = target.trait_tracker.get_traits_of_type(TraitType.PROFESSOR)
                        if not traits:
                            return TestResult(False, "{} doesn't have any PROFESSOR type traits.", target, tooltip=tooltip)
                else:
                    traits = target.trait_tracker.get_traits_of_type(TraitType.PROFESSOR)
                    if not traits:
                        return TestResult(False, "{} doesn't have any PROFESSOR type traits.", target, tooltip=tooltip)
            return TestResult.TRUE
コード例 #21
0
class UniversityHousingConfigurationTest(HasTunableSingletonFactory, AutoFactoryInit, event_testing.test_base.BaseTest):
    FACTORY_TUNABLES = {'university': OptionalTunable(description='\n            Checks for a specific university requirement.\n            ', tunable=TunablePackSafeReference(description='\n                Which university to check for.\n                ', manager=services.get_instance_manager(Types.UNIVERSITY)))}

    def get_expected_args(self):
        return {}

    @cached_test
    def __call__(self, tooltip=None):
        zone_id = services.current_zone_id()
        if zone_id is None:
            return TestResult(False, 'No current ZoneId found', tooltip=tooltip)
        persistence_service = services.get_persistence_service()
        zone_data = persistence_service.get_zone_proto_buff(zone_id)
        if zone_data is None:
            return TestResult(False, 'No zone data found for ZoneID:{}', zone_id, tooltip=tooltip)
        if not zone_data.HasField('university_housing_configuration') or zone_data.university_housing_configuration is None:
            return TestResult(False, 'No university housing configuration data found', tooltip=tooltip)
        config_data = zone_data.university_housing_configuration
        if self.university is not None:
            if not config_data.HasField('university_id'):
                return TestResult(False, 'No university university id found in configuration data', tooltip=tooltip)
            university_id = config_data.university_id
            if self.university.guid64 != university_id:
                return TestResult(False, "University id:{} doesn't match the venue configuration's university id:{}", self.university.guid64, university_id, tooltip=tooltip)
            return TestResult.TRUE
        return TestResult(False, 'No requirements tuned on test', tooltip=tooltip)
コード例 #22
0
class PlayVisualEffectMixin:
    FACTORY_TUNABLES = {
        'vfx':
        PlayEffect.TunableFactory(
            description='\n            The effect to play.\n            '),
        'vfx_target':
        OptionalTunable(
            description=
            '\n            If enabled, the visual effect is set to target a specific joint on\n            another object or Sim.\n            ',
            tunable=TunableTuple(
                participant=TunableEnumEntry(
                    description=
                    '\n                    The participant this visual effect targets.\n                    ',
                    tunable_type=ParticipantTypeSingle,
                    default=ParticipantTypeSingle.TargetSim),
                joint_name=TunableStringHash32(
                    description=
                    '\n                    The name of the slot this effect is targeted to.\n                    ',
                    default='_FX_')))
    }

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

    def _start_vfx(self, participant, target_participant):
        vfx_params = {}
        if target_participant is not None:
            vfx_params['target_actor_id'] = target_participant.id
            vfx_params['target_joint_name_hash'] = self.vfx_target.joint_name
        running_vfx = self.vfx(participant, **vfx_params)
        self.vfx_lifetime.start_visual_effect(running_vfx)
        return running_vfx
コード例 #23
0
class TestableDisplayName(HasTunableSingletonFactory, AutoFactoryInit):
    __qualname__ = 'TestableDisplayName'

    @staticmethod
    def _verify_tunable_callback(instance_class, tunable_name, source, value):
        for (index, override_data) in enumerate(value.overrides):
            while not override_data.new_display_name:
                logger.error(
                    'name override not set for display name override in {} at index:{}',
                    instance_class, index)

    FACTORY_TUNABLES = {
        'overrides':
        TunableList(
            description=
            '\n            Potential name overrides for this interaction. The first test in\n            this list which passes will be the new display name show to the\n            player. If none pass the tuned display_name will be used.\n            ',
            tunable=TunableTuple(
                description=
                '\n                A tuple of a test and the name that would be chosen if the test\n                passes.\n                ',
                test=event_testing.tests.TunableTestSet(
                    description=
                    '\n                    The test to run to see if the display_name should be\n                    overridden.\n                    '
                ),
                new_display_name=TunableLocalizedStringFactory(
                    description=
                    '\n                    The localized name of this interaction. it takes two tokens,\n                    the actor (0) and target object (1) of the interaction.\n                    '
                ),
                new_pie_menu_icon=TunableResourceKey(
                    description=
                    '\n                    If this display name overrides the default display name,\n                    this will be the icon that is shown. If this is not tuned\n                    then the default pie menu icon for this interaction will be\n                    used.\n                    ',
                    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(
                    )),
                new_pie_menu_category=TunableReference(
                    description=
                    '\n                    Pie menu category to put interaction under.\n                    ',
                    manager=services.get_instance_manager(
                        sims4.resources.Types.PIE_MENU_CATEGORY)))),
        'verify_tunable_callback':
        _verify_tunable_callback
    }

    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):
        resolver = interaction.get_resolver(target=target, context=context)
        for override in self.overrides:
            result = override.test.run_tests(resolver)
            while result:
                return (override, result)
        return (None, TestResult.NONE)
コード例 #24
0
class ProceduralControlWheel(ProceduralControlBase, TerrainAlignmentMixin):
    FACTORY_TUNABLES = {
        'reference_joint':
        TunableStringHash32(
            description=
            '\n            The joint we use to determine where the wheel is on the bike.\n            '
        ),
        'control_joint':
        TunableStringHash32(
            description=
            "\n            The joint that is controlled and rotates with the actor's velocity.\n            "
        ),
        'bump_sound':
        OptionalTunable(
            description=
            "\n            If enabled, this is the name of the sound to play when the control\n            hits a 'bump' in the terrain.\n            ",
            tunable=Tunable(
                description=
                '\n                The name of the sound to play when the control hits a bump in\n                the terrain. We use a string here instead of a hash so that we\n                can modify the sound name based on the terrain and other\n                factors from locomotion.\n                ',
                tunable_type=str,
                default=''))
    }

    def build_control_msg(self, msg):
        super().build_control_msg(msg)
        self.build_terrain_alignment_msg(msg)
        msg.control_type = ProceduralControlType.WHEEL
        msg.joint_name_hash = self.control_joint
        msg.reference_joint_name_hash = self.reference_joint
        if self.bump_sound:
            msg.bump_sound_name = self.bump_sound
コード例 #25
0
class PushInteractionOnAllGreetedSimsInteraction(
        interactions.base.super_interaction.SuperInteraction):
    __qualname__ = 'PushInteractionOnAllGreetedSimsInteraction'
    INSTANCE_TUNABLES = {
        '_pushed_interaction_tunables':
        TunableTuple(
            affordance_to_push=sims4.tuning.tunable.TunableReference(
                description=
                '\n                Affordance to push on all sims in the household and all greeted\n                sims.\n                ',
                manager=services.affordance_manager()),
            push_on_actor=sims4.tuning.tunable.Tunable(
                description=
                '\n               Whether Afforance To Push should be pushed on the actor.\n               ',
                tunable_type=bool,
                default=False),
            target_override_for_pushed_affordance=OptionalTunable(
                TunableEnumEntry(
                    description=
                    '\n                ParticipantType for the target to be set on the pushed\n                affordance.\n                ',
                    tunable_type=ParticipantType,
                    default=ParticipantType.Actor))),
        '_required_appropriateness_tags':
        TunableSet(
            description=
            '\n            A list of tags that a Sim must have to be eligible for this\n            interaction.\n            ',
            tunable=TunableEnumEntry(tunable_type=tag.Tag,
                                     default=tag.Tag.INVALID))
    }

    @classmethod
    def _test(cls, target, context, **interaction_parameters):
        sim = next(cls._target_sim_gen(context.sim), None)
        if sim is None:
            return event_testing.results.TestResult(False,
                                                    'No valid sims to call.')
        return super()._test(target, context, **interaction_parameters)

    def _run_interaction_gen(self, timeline):
        if self._pushed_interaction_tunables.target_override_for_pushed_affordance is not None:
            new_target = self.get_participant(
                self._pushed_interaction_tunables.
                target_override_for_pushed_affordance)
        else:
            new_target = self.target
        for target_sim in self._target_sim_gen(self.sim):
            target_context = self.context.clone_for_sim(target_sim)
            target_sim.push_super_affordance(
                self._pushed_interaction_tunables.affordance_to_push,
                new_target, target_context)
        return event_testing.results.ExecuteResult.NONE

    @classmethod
    def _target_sim_gen(cls, sim):
        for target_sim in services.sim_info_manager(
        ).instanced_sims_on_active_lot_gen():
            while target_sim.Buffs.is_appropriate(
                    cls._required_appropriateness_tags):
                if not cls._pushed_interaction_tunables.push_on_actor and target_sim is sim:
                    pass
                yield target_sim
コード例 #26
0
class StoreSimElement(XevtTriggeredElement, HasTunableFactory,
                      AutoFactoryInit):
    FACTORY_TUNABLES = {
        'description':
        '\n            An element that retrieves an interaction participant and attaches\n            its information to another interaction participant using a dynamic\n            StoredSimInfoComponent.\n            ',
        'source_participant':
        OptionalTunable(
            description=
            '\n            Specify what participant to store on the destination participant.\n            ',
            tunable=TunableEnumEntry(
                description=
                '\n                The participant of this interaction whose Sim Info is retrieved\n                to be stored as a component.\n                ',
                tunable_type=ParticipantType,
                default=ParticipantType.PickedObject),
            enabled_name='specific_participant',
            disabled_name='no_participant'),
        'destination_participant':
        TunableEnumEntry(
            description=
            '\n            The participant of this interaction to which a\n            StoredSimInfoComponent is added, with the Sim Info of\n            source_participant.\n            ',
            tunable_type=ParticipantType,
            default=ParticipantType.Object)
    }

    def _do_behavior(self):
        source = self.interaction.get_participant(
            participant_type=self.source_participant
        ) if self.source_participant is not None else None
        destination = self.interaction.get_participant(
            participant_type=self.destination_participant)
        if destination.has_component(types.STORED_SIM_INFO_COMPONENT):
            destination.remove_component(types.STORED_SIM_INFO_COMPONENT)
        if source is not None:
            destination.add_dynamic_component(types.STORED_SIM_INFO_COMPONENT,
                                              sim_id=source.id)
コード例 #27
0
class RenameImmediateInteraction(ImmediateSuperInteraction):
    __qualname__ = 'RenameImmediateInteraction'
    TEXT_INPUT_NEW_NAME = 'new_name'
    TEXT_INPUT_NEW_DESCRIPTION = 'new_description'
    INSTANCE_TUNABLES = {'display_name_rename': OptionalTunable(TunableLocalizedStringFactory(description="If set, this localized string will be used as the interaction's display name if the object has been previously renamed.")), 'rename_dialog': TunableVariant(description='\n            The rename dialog to show when running this interaction.\n            ', ok_dialog=UiDialogTextInputOk.TunableFactory(text_inputs=(TEXT_INPUT_NEW_NAME, TEXT_INPUT_NEW_DESCRIPTION)), ok_cancel_dialog=UiDialogTextInputOkCancel.TunableFactory(text_inputs=(TEXT_INPUT_NEW_NAME, TEXT_INPUT_NEW_DESCRIPTION)))}

    @flexmethod
    def _get_name(cls, inst, target=DEFAULT, context=DEFAULT, **kwargs):
        inst_or_cls = inst if inst is not None else cls
        target = inst.target if inst is not None else target
        if inst_or_cls.display_name_rename is not None and target.has_custom_name():
            display_name = inst_or_cls.display_name_rename
        else:
            display_name = inst_or_cls.display_name
        return inst_or_cls.create_localized_string(display_name, target=target, context=context, **kwargs)

    def _run_interaction_gen(self, timeline):
        target_name_component = self.target.name_component

        def on_response(dialog):
            if not dialog.accepted:
                return
            name = dialog.text_input_responses.get(self.TEXT_INPUT_NEW_NAME)
            description = dialog.text_input_responses.get(self.TEXT_INPUT_NEW_DESCRIPTION)
            target = self.target
            if target is not None:
                if name is not None:
                    target.set_custom_name(name)
                if description is not None:
                    target.set_custom_description(description)
                self._update_ui_metadata(target)
            sequence = self._build_outcome_sequence()
            services.time_service().sim_timeline.schedule(element_utils.build_element(sequence))

        text_input_overrides = {}
        (template_name, template_description) = target_name_component.get_template_name_and_description()
        if target_name_component.allow_name:
            text_input_overrides[self.TEXT_INPUT_NEW_NAME] = None
            if self.target.has_custom_name():
                text_input_overrides[self.TEXT_INPUT_NEW_NAME] = lambda *_, **__: LocalizationHelperTuning.get_object_name(self.target)
            elif template_name is not None:
                text_input_overrides[self.TEXT_INPUT_NEW_NAME] = template_name
        if target_name_component.allow_description:
            text_input_overrides[self.TEXT_INPUT_NEW_DESCRIPTION] = None
            if self.target.has_custom_description():
                text_input_overrides[self.TEXT_INPUT_NEW_DESCRIPTION] = lambda *_, **__: LocalizationHelperTuning.get_object_description(self.target)
            elif template_description is not None:
                text_input_overrides[self.TEXT_INPUT_NEW_DESCRIPTION] = template_description
        dialog = self.rename_dialog(self.sim, self.get_resolver())
        dialog.show_dialog(on_response=on_response, text_input_overrides=text_input_overrides)
        return True

    def build_outcome(self):
        pass

    def _update_ui_metadata(self, updated_object):
        updated_object.update_ui_metadata()
        current_inventory = updated_object.get_inventory()
        if current_inventory is not None:
            current_inventory.push_inventory_item_update_msg(updated_object)
コード例 #28
0
class _BroadcasterEffectTestedOneShot(_BroadcasterEffectTested):
    FACTORY_TUNABLES = {
        'affected_object_cap':
        OptionalTunable(
            description=
            '\n            If enabled, specify the maximum number of objects that can\n            be affected by this particular effect, per broadcaster. This\n            is a soft- cap, since the data does not persist across\n            multiple broadcaster requests nor save games.\n            ',
            tunable=TunableRange(
                description=
                '\n                The maximum number of objects that can be affected by\n                this broadcaster.\n                ',
                tunable_type=int,
                minimum=1,
                default=1))
    }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self._object_counter = weakref.WeakKeyDictionary()

    def _should_apply_broadcaster_effect(self, broadcaster, affected_object):
        result = super()._should_apply_broadcaster_effect(
            broadcaster, affected_object)
        if not result:
            return result
        if self.affected_object_cap is not None:
            if broadcaster not in self._object_counter:
                self._object_counter[broadcaster] = 0
            if self._object_counter[broadcaster] >= self.affected_object_cap:
                return False
            self._object_counter[broadcaster] += 1
        return result
コード例 #29
0
class _PortalRoutingSurfaceSpecified(HasTunableSingletonFactory,
                                     AutoFactoryInit):
    FACTORY_TUNABLES = {
        'surface_type':
        TunableEnumEntry(
            description=
            '\n            The surface type on which to create the portal.\n            ',
            tunable_type=SurfaceType,
            default=SurfaceType.SURFACETYPE_WORLD,
            invalid_enums=(SurfaceType.SURFACETYPE_UNKNOWN, )),
        'level_override':
        OptionalTunable(
            description=
            '\n            If enabled, allows this surface to have a level override.\n            ',
            tunable=TunableRange(
                description=
                '\n                The level to force this routing surface. This is useful for\n                picking out oceans since they are routing surface type POOL but\n                always on level 0.\n                ',
                tunable_type=int,
                default=0,
                minimum=-3,
                maximum=5))
    }

    def __call__(self, obj):
        routing_surface = obj.routing_surface
        level = routing_surface.secondary_id
        if self.level_override is not None:
            level = self.level_override
        return SurfaceIdentifier(routing_surface.primary_id, level,
                                 self.surface_type)
コード例 #30
0
ファイル: item_consume.py プロジェクト: NeonOcean/Environment
class ItemCost(ItemCostBase, AutoFactoryInit, HasTunableSingletonFactory):
    UNAVAILABLE_TOOLTIP_HEADER = TunableLocalizedStringFactory(
        description=
        '\n        A string to be used as a header for a bulleted list of items that the\n        Sim is missing in order to run this interaction.\n        '
    )
    AVAILABLE_TOOLTIP_HEADER = TunableLocalizedStringFactory(
        description=
        '\n        A string to be used as a header for a bulleted list of items that the\n        Sim will consume in order to run this interaction.\n        '
    )
    FACTORY_TUNABLES = {
        'ingredients':
        TunableList(
            description=
            '\n            List of tuples of Objects and Quantity, which will indicate\n            the cost of items for this interaction to run\n            ',
            tunable=TunableTuple(
                description=
                '\n                Pair of Object and Quantity needed for this interaction\n                ',
                ingredient=TunableReference(
                    description=
                    '\n                    Object reference of the type of game object needed.\n                    ',
                    manager=services.definition_manager()),
                quantity=TunableRange(
                    description=
                    '\n                    Quantity of objects needed\n                    ',
                    tunable_type=int,
                    default=1,
                    minimum=1),
                missing_ingredient_additional_text=OptionalTunable(
                    description=
                    '\n                    If set, this text is inserted on a new line following a missing ingredient.\n                    ',
                    tunable=TunableLocalizedString(
                        default=None,
                        description='The string key of the text description'
                    ))))
    }